diff options
author | Jerome Glisse <glisse@freedesktop.org> | 2008-11-05 15:59:37 +0100 |
---|---|---|
committer | Jerome Glisse <glisse@freedesktop.org> | 2008-11-05 15:59:37 +0100 |
commit | ddfb12b32e64d00d302f7fbb36fb079deec3646f (patch) | |
tree | 5caeade40ef88936a88e47060b6090aa44d38b94 /shared-core/radeon_cp.c | |
parent | 7651b4c424aa6c6ac6c47b2d07c8f65d0b9d0191 (diff) | |
parent | 68fcb7770efc20b9e27b1724e2fb5ac112a5330e (diff) |
Merge branch 'modesetting-gem' of ssh://git.freedesktop.org/git/mesa/drm into modesetting-gem
Diffstat (limited to 'shared-core/radeon_cp.c')
-rw-r--r-- | shared-core/radeon_cp.c | 121 |
1 files changed, 86 insertions, 35 deletions
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 190b1432..9a1e0e02 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -120,7 +120,7 @@ void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 * *agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT); *agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP); } else if (dev_priv->chip_family == CHIP_RV515) { - *agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_FB_LOCATION); + *agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_AGP_LOCATION); *agp_hi = 0; } else if (dev_priv->chip_family == CHIP_RS600) { *agp_lo = 0; @@ -133,7 +133,7 @@ void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 * *agp_lo = radeon_read_mc_reg(dev_priv, R520_MC_AGP_LOCATION); *agp_hi = 0; } else { - *agp_lo = RADEON_READ(RADEON_MC_FB_LOCATION); + *agp_lo = RADEON_READ(RADEON_MC_AGP_LOCATION); *agp_hi = 0; } } @@ -194,6 +194,24 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) } } +void radeon_enable_bm(struct drm_radeon_private *dev_priv) +{ + u32 tmp; + /* Turn on bus mastering */ + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + /* rs600/rs690/rs740 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { + /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + } /* PCIE cards appears to not need this */ +} void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv) { @@ -573,10 +591,15 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv) BEGIN_RING(8); /* isync can only be written through cp on r5xx write it here */ OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0)); + if (dev_priv->chip_family > CHIP_RV280) + OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | + RADEON_ISYNC_WAIT_IDLEGUI | + dev_priv->mm_enabled ? 0 : RADEON_ISYNC_CPSCRATCH_IDLEGUI); + else OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | - RADEON_ISYNC_WAIT_IDLEGUI | - RADEON_ISYNC_CPSCRATCH_IDLEGUI); + RADEON_ISYNC_WAIT_IDLEGUI); RADEON_PURGE_CACHE(); RADEON_PURGE_ZCACHE(); RADEON_WAIT_UNTIL_IDLE(); @@ -686,7 +709,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, drm_radeon_private_t * dev_priv) { 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 @@ -791,11 +813,12 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring_rptr->handle + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); + if (dev_priv->chip_family >= CHIP_R300) + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7f); + else + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x1f); - /* Turn on bus mastering */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); + radeon_enable_bm(dev_priv); dev_priv->scratch[0] = 0; RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); @@ -806,6 +829,15 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->scratch[2] = 0; RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); + dev_priv->scratch[3] = 0; + RADEON_WRITE(RADEON_LAST_SWI_REG, 0); + + dev_priv->scratch[4] = 0; + RADEON_WRITE(RADEON_SCRATCH_REG4, 0); + + dev_priv->scratch[6] = 0; + RADEON_WRITE(RADEON_SCRATCH_REG6, 0); + radeon_do_wait_for_idle(dev_priv); /* Sync everything up */ @@ -825,7 +857,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, static void radeon_test_writeback(drm_radeon_private_t * dev_priv) { - u32 tmp; + u32 tmp, scratch1_store; void *ring_read_ptr; if (dev_priv->mm.ring_read.bo) @@ -833,6 +865,7 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) else ring_read_ptr = dev_priv->ring_rptr->handle; + scratch1_store = RADEON_READ(RADEON_SCRATCH_REG1); /* Writeback doesn't seem to work everywhere, test it here and possibly * enable it if it appears to work */ @@ -858,6 +891,9 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) DRM_INFO("writeback forced off\n"); } + /* write back previous value */ + RADEON_WRITE(RADEON_SCRATCH_REG1, scratch1_store); + if (!dev_priv->writeback_works) { /* Disable writeback to avoid unnecessary bus master transfers */ RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | RADEON_RB_NO_UPDATE); @@ -2353,6 +2389,8 @@ int radeon_modeset_cp_resume(struct drm_device *dev) radeon_do_engine_reset(dev); + radeon_test_writeback(dev_priv); + radeon_do_cp_start(dev_priv); return 0; } @@ -2434,16 +2472,22 @@ int radeon_modeset_agp_init(struct drm_device *dev) ret = drm_agp_enable(dev, mode); if (ret) { - DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode); + DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); return ret; } /* workaround some hw issues */ - if (dev_priv->chip_family <= CHIP_R200) { + if (dev_priv->chip_family < CHIP_R200) { RADEON_WRITE(RADEON_AGP_CNTL, RADEON_READ(RADEON_AGP_CNTL) | 0x000e0000); } return 0; } + +void radeon_modeset_agp_destroy(struct drm_device *dev) +{ + if (dev->agp->acquired) + drm_agp_release(dev); +} #endif int radeon_modeset_cp_init(struct drm_device *dev) @@ -2457,7 +2501,7 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->writeback_works = 0; if (dev_priv->chip_family > CHIP_R600) - return; + return 0; dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT; dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; @@ -2562,15 +2606,23 @@ int radeon_static_clocks_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { - radeon_set_dynamic_clock(dev, radeon_dynclks); - } else if (radeon_is_avivo(dev_priv)) { - if (radeon_dynclks) { - radeon_atom_static_pwrmgt_setup(dev, 1); - radeon_atom_dyn_clk_setup(dev, 1); + if (radeon_dynclks != -1) { + + if (dev_priv->chip_family == CHIP_RS400 || + dev_priv->chip_family == CHIP_RS480) + radeon_dynclks = 0; + + if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { + radeon_set_dynamic_clock(dev, radeon_dynclks); + } else if (radeon_is_avivo(dev_priv)) { + if (radeon_dynclks) { + radeon_atom_static_pwrmgt_setup(dev, 1); + radeon_atom_dyn_clk_setup(dev, 1); + } } } - radeon_force_some_clocks(dev); + if (radeon_is_r300(dev_priv) || radeon_is_rv100(dev_priv)) + radeon_force_some_clocks(dev); return 0; } @@ -2617,9 +2669,16 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG("%s card detected\n", ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); - if ((dev_priv->flags & RADEON_IS_AGP) && (radeon_agpmode == -1)) { - DRM_INFO("Forcing AGP to PCI mode\n"); - dev_priv->flags &= ~RADEON_IS_AGP; + if (dev_priv->flags & RADEON_IS_AGP) { + + /* disable AGP for any chips after RV280 if not specified */ + if ((dev_priv->chip_family > CHIP_RV280) && (radeon_agpmode == 0)) + radeon_agpmode = -1; + + if (radeon_agpmode == -1) { + DRM_INFO("Forcing AGP to PCI mode\n"); + dev_priv->flags &= ~RADEON_IS_AGP; + } } @@ -2709,7 +2768,6 @@ int radeon_master_create(struct drm_device *dev, struct drm_master *master) void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) { struct drm_radeon_master_private *master_priv = master->driver_priv; - struct drm_radeon_private *dev_priv = dev->dev_private; if (!master_priv) return; @@ -2731,21 +2789,10 @@ void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) */ int radeon_driver_firstopen(struct drm_device *dev) { - int ret; - drm_local_map_t *map; drm_radeon_private_t *dev_priv = dev->dev_private; dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - radeon_gem_mm_init(dev); - - ret = drm_addmap(dev, dev_priv->fb_aper_offset, - drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, - _DRM_WRITE_COMBINING, &map); - if (ret != 0) - return ret; - return 0; } @@ -2757,6 +2804,10 @@ int radeon_driver_unload(struct drm_device *dev) drm_irq_uninstall(dev); radeon_modeset_cleanup(dev); radeon_gem_mm_fini(dev); +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) + radeon_modeset_agp_destroy(dev); +#endif } drm_bo_driver_finish(dev); |