summaryrefslogtreecommitdiff
path: root/drivers/char/drm/radeon_cp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/radeon_cp.c')
-rw-r--r--drivers/char/drm/radeon_cp.c166
1 files changed, 111 insertions, 55 deletions
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 24fca8ec137..5dc799ab86b 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -816,6 +816,46 @@ static const u32 R300_cp_microcode[][2] = {
{0000000000, 0000000000},
};
+static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+ RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff));
+ ret = RADEON_READ(R520_MC_IND_DATA);
+ RADEON_WRITE(R520_MC_IND_INDEX, 0);
+ return ret;
+}
+
+u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
+{
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
+ else
+ return RADEON_READ(RADEON_MC_FB_LOCATION);
+}
+
+static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
+{
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
+ else
+ RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
+}
+
+static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
+{
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
+ else
+ RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
+}
+
static int RADEON_READ_PLL(struct drm_device * dev, int addr)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -824,7 +864,7 @@ static int RADEON_READ_PLL(struct drm_device * dev, int addr)
return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
}
-static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
+static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
{
RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
return RADEON_READ(RADEON_PCIE_DATA);
@@ -1074,41 +1114,43 @@ static int radeon_do_engine_reset(struct drm_device * dev)
radeon_do_pixcache_flush(dev_priv);
- clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
- mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
-
- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
- RADEON_FORCEON_MCLKA |
- RADEON_FORCEON_MCLKB |
- RADEON_FORCEON_YCLKA |
- RADEON_FORCEON_YCLKB |
- RADEON_FORCEON_MC |
- RADEON_FORCEON_AIC));
-
- rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
-
- RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
- RADEON_SOFT_RESET_CP |
- RADEON_SOFT_RESET_HI |
- RADEON_SOFT_RESET_SE |
- RADEON_SOFT_RESET_RE |
- RADEON_SOFT_RESET_PP |
- RADEON_SOFT_RESET_E2 |
- RADEON_SOFT_RESET_RB));
- RADEON_READ(RADEON_RBBM_SOFT_RESET);
- RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
- ~(RADEON_SOFT_RESET_CP |
- RADEON_SOFT_RESET_HI |
- RADEON_SOFT_RESET_SE |
- RADEON_SOFT_RESET_RE |
- RADEON_SOFT_RESET_PP |
- RADEON_SOFT_RESET_E2 |
- RADEON_SOFT_RESET_RB)));
- RADEON_READ(RADEON_RBBM_SOFT_RESET);
-
- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
- RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
- RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) {
+ clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
+ mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
+
+ RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
+ RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_MCLKB |
+ RADEON_FORCEON_YCLKA |
+ RADEON_FORCEON_YCLKB |
+ RADEON_FORCEON_MC |
+ RADEON_FORCEON_AIC));
+
+ rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
+
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
+ RADEON_SOFT_RESET_CP |
+ RADEON_SOFT_RESET_HI |
+ RADEON_SOFT_RESET_SE |
+ RADEON_SOFT_RESET_RE |
+ RADEON_SOFT_RESET_PP |
+ RADEON_SOFT_RESET_E2 |
+ RADEON_SOFT_RESET_RB));
+ RADEON_READ(RADEON_RBBM_SOFT_RESET);
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
+ ~(RADEON_SOFT_RESET_CP |
+ RADEON_SOFT_RESET_HI |
+ RADEON_SOFT_RESET_SE |
+ RADEON_SOFT_RESET_RE |
+ RADEON_SOFT_RESET_PP |
+ RADEON_SOFT_RESET_E2 |
+ RADEON_SOFT_RESET_RB)));
+ RADEON_READ(RADEON_RBBM_SOFT_RESET);
+
+ RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
+ RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
+ }
/* Reset the CP ring */
radeon_do_cp_reset(dev_priv);
@@ -1127,21 +1169,21 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
{
u32 ring_start, cur_read_ptr;
u32 tmp;
-
+
/* Initialize the memory controller. With new memory map, the fb location
* is not changed, it should have been properly initialized already. Part
* of the problem is that the code below is bogus, assuming the GART is
* always appended to the fb which is not necessarily the case
*/
if (!dev_priv->new_memmap)
- RADEON_WRITE(RADEON_MC_FB_LOCATION,
+ radeon_write_fb_location(dev_priv,
((dev_priv->gart_vm_start - 1) & 0xffff0000)
| (dev_priv->fb_location >> 16));
#if __OS_HAS_AGP
if (dev_priv->flags & RADEON_IS_AGP) {
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
- RADEON_WRITE(RADEON_MC_AGP_LOCATION,
+ radeon_write_agp_location(dev_priv,
(((dev_priv->gart_vm_start - 1 +
dev_priv->gart_size) & 0xffff0000) |
(dev_priv->gart_vm_start >> 16)));
@@ -1190,9 +1232,15 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
/* Set ring buffer size */
#ifdef __BIG_ENDIAN
RADEON_WRITE(RADEON_CP_RB_CNTL,
- dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT);
+ RADEON_BUF_SWAP_32BIT |
+ (dev_priv->ring.fetch_size_l2ow << 18) |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
#else
- RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw);
+ RADEON_WRITE(RADEON_CP_RB_CNTL,
+ (dev_priv->ring.fetch_size_l2ow << 18) |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
#endif
/* Start with assuming that writeback doesn't work */
@@ -1299,7 +1347,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
dev_priv->gart_size = 32*1024*1024;
- RADEON_WRITE(RADEON_MC_AGP_LOCATION,
+ radeon_write_agp_location(dev_priv,
(((dev_priv->gart_vm_start - 1 +
dev_priv->gart_size) & 0xffff0000) |
(dev_priv->gart_vm_start >> 16)));
@@ -1333,7 +1381,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
dev_priv->gart_vm_start +
dev_priv->gart_size - 1);
- RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */
+ radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
RADEON_PCIE_TX_GART_EN);
@@ -1358,7 +1406,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
return;
}
- tmp = RADEON_READ(RADEON_AIC_CNTL);
+ tmp = RADEON_READ(RADEON_AIC_CNTL);
if (on) {
RADEON_WRITE(RADEON_AIC_CNTL,
@@ -1376,7 +1424,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
/* Turn off AGP aperture -- is this required for PCI GART?
*/
- RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */
+ radeon_write_agp_location(dev_priv, 0xffffffc0);
RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */
} else {
RADEON_WRITE(RADEON_AIC_CNTL,
@@ -1581,10 +1629,9 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
dev->agp_buffer_map->handle);
}
- dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION)
- & 0xffff) << 16;
- dev_priv->fb_size =
- ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000)
+ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16;
+ dev_priv->fb_size =
+ ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000)
- dev_priv->fb_location;
dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
@@ -1630,7 +1677,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
((base + dev_priv->gart_size) & 0xfffffffful) < base)
base = dev_priv->fb_location
- dev_priv->gart_size;
- }
+ }
dev_priv->gart_vm_start = base & 0xffc00000u;
if (dev_priv->gart_vm_start != base)
DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
@@ -1663,6 +1710,11 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
dev_priv->ring.size = init->ring_size;
dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
+ dev_priv->ring.rptr_update = /* init->rptr_update */ 4096;
+ dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8);
+
+ dev_priv->ring.fetch_size = /* init->fetch_size */ 32;
+ dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16);
dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
@@ -1830,7 +1882,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (init->func == RADEON_INIT_R300_CP)
- r300_init_reg_flags();
+ r300_init_reg_flags(dev);
switch (init->func) {
case RADEON_INIT_CP:
@@ -1852,12 +1904,12 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (dev_priv->cp_running) {
- DRM_DEBUG("%s while CP running\n", __FUNCTION__);
+ DRM_DEBUG("while CP running\n");
return 0;
}
if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) {
- DRM_DEBUG("%s called with bogus CP mode (%d)\n",
- __FUNCTION__, dev_priv->cp_mode);
+ DRM_DEBUG("called with bogus CP mode (%d)\n",
+ dev_priv->cp_mode);
return 0;
}
@@ -1962,7 +2014,7 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_DEBUG("%s called before init done\n", __FUNCTION__);
+ DRM_DEBUG("called before init done\n");
return -EINVAL;
}
@@ -2239,6 +2291,10 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
case CHIP_R350:
case CHIP_R420:
case CHIP_RV410:
+ case CHIP_RV515:
+ case CHIP_R520:
+ case CHIP_RV570:
+ case CHIP_R580:
dev_priv->flags |= RADEON_HAS_HIERZ;
break;
default: