mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-25 04:50:11 +01:00
RS600: add initial support (untested)
The RS600 gart setup is more like R6xx/R7xx than older IGP chips. If you have an RS600, please test!
This commit is contained in:
parent
fc9ea629ed
commit
112ad16178
4 changed files with 186 additions and 7 deletions
|
|
@ -233,6 +233,9 @@
|
|||
0x1002 0x7297 CHIP_RV560|RADEON_NEW_MEMMAP "ATI RV560"
|
||||
0x1002 0x7834 CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP "ATI Radeon RS350 9000/9100 IGP"
|
||||
0x1002 0x7835 CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon RS350 Mobility IGP"
|
||||
0x1002 0x793f CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP "ATI Radeon X1200"
|
||||
0x1002 0x7941 CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP "ATI Radeon X1200"
|
||||
0x1002 0x7942 CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP "ATI Radeon X1200"
|
||||
0x1002 0x791e CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART "ATI Radeon RS690 X1250 IGP"
|
||||
0x1002 0x791f CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART "ATI Radeon RS690 X1270 IGP"
|
||||
0x1002 0x796c CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART "ATI Radeon RS740 HD2100 IGP"
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ static void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga
|
|||
}
|
||||
|
||||
/* R600 has page table setup */
|
||||
static int r600_page_table_init(struct drm_device *dev)
|
||||
int r600_page_table_init(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info;
|
||||
|
|
@ -2460,7 +2460,11 @@ int r600_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
|
|||
dev_priv->gart_info.addr,
|
||||
dev_priv->pcigart_offset);
|
||||
|
||||
r600_page_table_init(dev);
|
||||
if (!r600_page_table_init(dev)) {
|
||||
DRM_ERROR("Failed to init GART table\n");
|
||||
r600_do_cleanup_cp(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
|
||||
r700_vm_init(dev);
|
||||
|
|
|
|||
|
|
@ -82,11 +82,22 @@ static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
|
||||
{
|
||||
u32 ret;
|
||||
RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) |
|
||||
RS600_MC_IND_CITF_ARB0));
|
||||
ret = RADEON_READ(RS600_MC_DATA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
|
||||
{
|
||||
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
|
||||
return RS690_READ_MCIND(dev_priv, addr);
|
||||
else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
|
||||
return RS600_READ_MCIND(dev_priv, addr);
|
||||
else
|
||||
return RS480_READ_MCIND(dev_priv, addr);
|
||||
}
|
||||
|
|
@ -102,6 +113,8 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
|
|||
else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
|
||||
return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
|
||||
else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
|
||||
return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION);
|
||||
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
|
||||
return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
|
||||
else
|
||||
|
|
@ -119,6 +132,8 @@ void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
|
|||
else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
|
||||
RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
|
||||
else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
|
||||
RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc);
|
||||
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
|
||||
R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
|
||||
else
|
||||
|
|
@ -139,6 +154,8 @@ void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
|
|||
else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
|
||||
RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
|
||||
else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
|
||||
RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc);
|
||||
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
|
||||
R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
|
||||
else
|
||||
|
|
@ -163,6 +180,9 @@ void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
|
|||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
|
||||
RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo);
|
||||
RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi);
|
||||
} else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
|
||||
RS690_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo);
|
||||
RS690_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi);
|
||||
} else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) {
|
||||
R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo);
|
||||
R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi);
|
||||
|
|
@ -452,6 +472,14 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
|
|||
RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
|
||||
RS690_cp_microcode[i][0]);
|
||||
}
|
||||
} else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
|
||||
DRM_INFO("Loading RS600 Microcode\n");
|
||||
for (i = 0; i < 256; i++) {
|
||||
RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
|
||||
RS600_cp_microcode[i][1]);
|
||||
RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
|
||||
RS600_cp_microcode[i][0]);
|
||||
}
|
||||
} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ||
|
||||
|
|
@ -886,6 +914,82 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
|
|||
}
|
||||
}
|
||||
|
||||
/* Enable or disable IGP GART on the chip */
|
||||
static void rs600_set_igpgart(drm_radeon_private_t * dev_priv, int on)
|
||||
{
|
||||
u32 temp;
|
||||
int i;
|
||||
|
||||
if (on) {
|
||||
DRM_DEBUG("programming igp gart %08X %08lX %08X\n",
|
||||
dev_priv->gart_vm_start,
|
||||
(long)dev_priv->gart_info.bus_addr,
|
||||
dev_priv->gart_size);
|
||||
|
||||
temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
|
||||
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
|
||||
RS600_EFFECTIVE_L2_QUEUE_SIZE(6)));
|
||||
|
||||
temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CLIENT0_CNTL);
|
||||
for (i = 0; i < 19; i++)
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i,
|
||||
(RS600_ENABLE_TRANSLATION_MODE_OVERRIDE |
|
||||
RS600_SYSTEM_ACCESS_MODE(0) | //???
|
||||
RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH |
|
||||
RS600_EFFECTIVE_L1_CACHE_SIZE(3) |
|
||||
RS600_EFFECTIVE_L1_QUEUE_SIZE(3)));
|
||||
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE |
|
||||
RS600_PAGE_TABLE_TYPE_FLAT));
|
||||
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
|
||||
dev_priv->gart_info.bus_addr >> 12);
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR,
|
||||
dev_priv->gart_vm_start >> 12);
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR,
|
||||
(dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
|
||||
|
||||
temp = IGP_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION);
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR,
|
||||
dev_priv->gart_vm_start >> 12);
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
(dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
|
||||
|
||||
temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT));
|
||||
|
||||
temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1);
|
||||
IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES));
|
||||
|
||||
do {
|
||||
temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
|
||||
if ((temp & (RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE)) == 0)
|
||||
break;
|
||||
DRM_UDELAY(1);
|
||||
} while(1);
|
||||
|
||||
temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp |
|
||||
RS600_INVALIDATE_ALL_L1_TLBS |
|
||||
RS600_INVALIDATE_L2_CACHE));
|
||||
|
||||
do {
|
||||
temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
|
||||
if ((temp & (RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE)) == 0)
|
||||
break;
|
||||
DRM_UDELAY(1);
|
||||
} while(1);
|
||||
|
||||
} else {
|
||||
IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0);
|
||||
temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1);
|
||||
temp &= ~RS600_ENABLE_PAGE_TABLES;
|
||||
IGP_WRITE_MCIND(RS600_MC_CNTL1, temp);
|
||||
}
|
||||
}
|
||||
|
||||
static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
|
||||
{
|
||||
u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
|
||||
|
|
@ -927,6 +1031,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
|
||||
rs600_set_igpgart(dev_priv, on);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dev_priv->flags & RADEON_IS_PCIE) {
|
||||
radeon_set_pciegart(dev_priv, on);
|
||||
return;
|
||||
|
|
@ -1275,6 +1384,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
|
|||
DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
|
||||
dev_priv->gart_info.addr,
|
||||
dev_priv->pcigart_offset);
|
||||
|
||||
} else {
|
||||
if (dev_priv->flags & RADEON_IS_IGPGART)
|
||||
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
|
||||
|
|
@ -1292,10 +1402,18 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
|
|||
}
|
||||
}
|
||||
|
||||
if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
|
||||
DRM_ERROR("failed to init PCI GART!\n");
|
||||
radeon_do_cleanup_cp(dev);
|
||||
return -ENOMEM;
|
||||
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
|
||||
if (!r600_page_table_init(dev)) {
|
||||
DRM_ERROR("failed to init PCI GART!\n");
|
||||
radeon_do_cleanup_cp(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
|
||||
DRM_ERROR("failed to init PCI GART!\n");
|
||||
radeon_do_cleanup_cp(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Turn on PCI GART */
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ enum radeon_family {
|
|||
CHIP_RV410,
|
||||
CHIP_RS400,
|
||||
CHIP_RS480,
|
||||
CHIP_RS600,
|
||||
CHIP_RS690,
|
||||
CHIP_RS740,
|
||||
CHIP_RV515,
|
||||
|
|
@ -457,6 +458,7 @@ void r600_do_cp_stop(drm_radeon_private_t * dev_priv);
|
|||
int r600_engine_reset(struct drm_device * dev);
|
||||
void r600_do_cp_reset(drm_radeon_private_t * dev_priv);
|
||||
int r600_do_cleanup_cp(struct drm_device * dev);
|
||||
int r600_page_table_init(struct drm_device *dev);
|
||||
|
||||
/* Flags for stats.boxes
|
||||
*/
|
||||
|
|
@ -593,6 +595,50 @@ int r600_do_cleanup_cp(struct drm_device * dev);
|
|||
#define RS690_MC_AGP_BASE 0x102
|
||||
#define RS690_MC_AGP_BASE_2 0x103
|
||||
|
||||
#define RS600_MC_INDEX 0x70
|
||||
# define RS600_MC_ADDR_MASK 0xff
|
||||
# define RS600_MC_IND_SEQ_RBS_0 (1 << 16)
|
||||
# define RS600_MC_IND_SEQ_RBS_1 (1 << 17)
|
||||
# define RS600_MC_IND_SEQ_RBS_2 (1 << 18)
|
||||
# define RS600_MC_IND_SEQ_RBS_3 (1 << 19)
|
||||
# define RS600_MC_IND_AIC_RBS (1 << 20)
|
||||
# define RS600_MC_IND_CITF_ARB0 (1 << 21)
|
||||
# define RS600_MC_IND_CITF_ARB1 (1 << 22)
|
||||
# define RS600_MC_IND_WR_EN (1 << 23)
|
||||
#define RS600_MC_DATA 0x74
|
||||
|
||||
#define RS600_MC_STATUS 0x0
|
||||
# define RS600_MC_IDLE (1 << 1)
|
||||
#define RS600_MC_FB_LOCATION 0x4
|
||||
#define RS600_MC_AGP_LOCATION 0x5
|
||||
#define RS600_AGP_BASE 0x6
|
||||
#define RS600_AGP_BASE_2 0x7
|
||||
#define RS600_MC_CNTL1 0x9
|
||||
# define RS600_ENABLE_PAGE_TABLES (1 << 26)
|
||||
#define RS600_MC_PT0_CNTL 0x100
|
||||
# define RS600_ENABLE_PT (1 << 0)
|
||||
# define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15)
|
||||
# define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21)
|
||||
# define RS600_INVALIDATE_ALL_L1_TLBS (1 << 28)
|
||||
# define RS600_INVALIDATE_L2_CACHE (1 << 29)
|
||||
#define RS600_MC_PT0_CONTEXT0_CNTL 0x102
|
||||
# define RS600_ENABLE_PAGE_TABLE (1 << 0)
|
||||
# define RS600_PAGE_TABLE_TYPE_FLAT (0 << 1)
|
||||
#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x112
|
||||
#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x114
|
||||
#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c
|
||||
#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x12c
|
||||
#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x13c
|
||||
#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x14c
|
||||
#define RS600_MC_PT0_CLIENT0_CNTL 0x16c
|
||||
# define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE (1 << 0)
|
||||
# define RS600_TRANSLATION_MODE_OVERRIDE (1 << 1)
|
||||
# define RS600_SYSTEM_ACCESS_MODE(x) ((x) << 8)
|
||||
# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH (0 << 10)
|
||||
# define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11)
|
||||
# define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15)
|
||||
# define RS600_INVALIDATE_L1_TLB (1 << 20)
|
||||
|
||||
#define R520_MC_IND_INDEX 0x70
|
||||
#define R520_MC_IND_WR_EN (1 << 24)
|
||||
#define R520_MC_IND_DATA 0x74
|
||||
|
|
@ -1395,12 +1441,20 @@ do { \
|
|||
RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \
|
||||
} while (0)
|
||||
|
||||
#define RS600_WRITE_MCIND( addr, val ) \
|
||||
do { \
|
||||
RADEON_WRITE(RS600_MC_INDEX, RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | ((addr) & RS600_MC_ADDR_MASK)); \
|
||||
RADEON_WRITE(RS600_MC_DATA, val); \
|
||||
} while (0)
|
||||
|
||||
#define IGP_WRITE_MCIND( addr, val ) \
|
||||
do { \
|
||||
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \
|
||||
RS690_WRITE_MCIND( addr, val ); \
|
||||
else \
|
||||
else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) \
|
||||
RS600_WRITE_MCIND( addr, val ); \
|
||||
else \
|
||||
RS480_WRITE_MCIND( addr, val ); \
|
||||
} while (0)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue