>From 7c1de3201bd4e965da7c1d542c46d8b2725bf42d Mon Sep 17 00:00:00 2001 From: Corbin Simpson <mostawesomed...@gmail.com> Date: Fri, 18 Dec 2009 01:00:57 -0800 Subject: [PATCH] drivers/radeon/kms: Workaround RV410/R420 CP errata.
Long story short, this fixes sporadic hardlocks with my rv410 during times of intense 2D acceleration (Flash on Fx3). Signed-off-by: Corbin Simpson <mostawesomed...@gmail.com> --- drivers/gpu/drm/radeon/r420.c | 35 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon.h | 1 + 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 5c7fe52..6f096a6 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -30,6 +30,7 @@ #include "radeon_reg.h" #include "radeon.h" #include "atom.h" +#include "r100d.h" #include "r420d.h" int r420_mc_init(struct radeon_device *rdev) @@ -165,6 +166,36 @@ static void r420_clock_resume(struct radeon_device *rdev) WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl); } +static void r420_cp_errata_init(struct radeon_device *rdev) +{ + /* RV410 and R420 can lock up if CP DMA to host memory happens while the + * 2D engine is busy. + * + * The proper workaround is to queue a RESYNC at the beginning of the CP + * init, apparently. + */ + radeon_scratch_get(rdev, &rdev->resync_scratch); + + radeon_ring_lock(rdev, 8); + radeon_ring_write(rdev, PACKET0(R300_CP_RESYNC_ADDR, 1)); + radeon_ring_write(rdev, rdev->resync_scratch); + radeon_ring_write(rdev, 0xDEADBEEF); + radeon_ring_unlock_commit(rdev); +} + +static void r420_cp_errata_fini(struct radeon_device *rdev) +{ + /* Catch the RESYNC we dispatched all the way back, at the very beginning + * of the CP init. + */ + radeon_ring_lock(rdev, 8); + radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(rdev, R300_RB3D_DC_FINISH); + radeon_ring_unlock_commit(rdev); + + radeon_scratch_free(rdev, rdev->resync_scratch); +} + static int r420_startup(struct radeon_device *rdev) { int r; @@ -194,6 +225,9 @@ static int r420_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failled initializing CP (%d).\n", r); return r; } + /* Handle CP errata. */ + r420_cp_errata_init(rdev); + r = r100_wb_init(rdev); if (r) { dev_err(rdev->dev, "failled initializing WB (%d).\n", r); @@ -247,6 +281,7 @@ int r420_suspend(struct radeon_device *rdev) void r420_fini(struct radeon_device *rdev) { + r420_cp_errata_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5ab35b8..0da50a2 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -771,6 +771,7 @@ struct radeon_device { struct radeon_gem gem; struct radeon_pm pm; uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; + uint32_t resync_scratch; struct mutex cs_mutex; struct radeon_wb wb; struct radeon_dummy_page dummy_page; -- 1.6.5.2 ------------------------------------------------------------------------------ This SF.Net email is sponsored by the Verizon Developer Community Take advantage of Verizon's best-in-class app development support A streamlined, 14 day to market process makes app distribution fast and easy Join now and get one step closer to millions of Verizon customers http://p.sf.net/sfu/verizon-dev2dev -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel