[PATCH] drm/radeon/kms: Workaround RV410/R420 CP errata (V2)
From: Corbin Simpson mostawesomed...@gmail.com Long story short, this fixes sporadic hardlocks with my rv410 during times of intense 2D acceleration (Flash on Fx3). V2: Fix indentation and move errata_fini to suspend function so we don't leak scratch register over suspend/resume cycle. Signed-off-by: Corbin Simpson mostawesomed...@gmail.com Signed-off-by: Jerome Glisse jgli...@redhat.com --- drivers/gpu/drm/radeon/r420.c | 31 +++ drivers/gpu/drm/radeon/radeon.h |1 + 2 files changed, 32 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index c05a727..48ab18f 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,34 @@ static void r420_clock_resume(struct radeon_device *rdev) WREG32_PLL(R_0D_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; @@ -196,6 +225,7 @@ static int r420_startup(struct radeon_device *rdev) dev_err(rdev-dev, failled initializing CP (%d).\n, r); return r; } + r420_cp_errata_init(rdev); r = r100_wb_init(rdev); if (r) { dev_err(rdev-dev, failled initializing WB (%d).\n, r); @@ -238,6 +268,7 @@ int r420_resume(struct radeon_device *rdev) int r420_suspend(struct radeon_device *rdev) { + r420_cp_errata_fini(rdev); r100_cp_disable(rdev); r100_wb_disable(rdev); r100_irq_disable(rdev); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index cd650fd..b272065 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -798,6 +798,7 @@ struct radeon_device { struct radeon_gem gem; struct radeon_pmpm; uint32_tbios_scratch[RADEON_BIOS_NUM_SCRATCH]; +uint32_t resync_scratch; struct mutexcs_mutex; struct radeon_wbwb; struct radeon_dummy_pagedummy_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
Re: [PATCH] drm/radeon/kms: Workaround RV410/R420 CP errata (V2)
I will pop my rv410 back in and test when I get back home. Posting from a mobile, pardon my terseness. ~ C. On Jan 6, 2010 2:41 AM, Jerome Glisse jgli...@redhat.com wrote: From: Corbin Simpson mostawesomed...@gmail.com Long story short, this fixes sporadic hardlocks with my rv410 during times of intense 2D acceleration (Flash on Fx3). V2: Fix indentation and move errata_fini to suspend function so we don't leak scratch register over suspend/resume cycle. Signed-off-by: Corbin Simpson mostawesomed...@gmail.com Signed-off-by: Jerome Glisse jgli...@redhat.com --- drivers/gpu/drm/radeon/r420.c | 31 +++ drivers/gpu/drm/radeon/radeon.h |1 + 2 files changed, 32 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index c05a727..48ab18f 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,34 @@ static void r420_clock_resume(struct radeon_device *rdev) WREG32_PLL(R_0D_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; @@ -196,6 +225,7 @@ static int r420_startup(struct radeon_device *rdev) dev_err(rdev-dev, failled initializing CP (%d).\n, r); return r; } + r420_cp_errata_init(rdev); r = r100_wb_init(rdev); if (r) { dev_err(rdev-dev, failled initializing WB (%d).\n, r); @@ -238,6 +268,7 @@ int r420_resume(struct radeon_device *rdev) int r420_suspend(struct radeon_device *rdev) { + r420_cp_errata_fini(rdev); r100_cp_disable(rdev); r100_wb_disable(rdev); r100_irq_disable(rdev); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index cd650fd..b272065 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -798,6 +798,7 @@ struct radeon_device { struct radeon_gem gem; struct radeon_pmpm; uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; +uint32_t resync_scratch; struct mutexcs_mutex; struct radeon_wbwb; struct radeon_dummy_pagedummy_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
Re: [PATCH] drm/radeon/kms: Workaround RV410/R420 CP errata (V2)
On Wed, 2010-01-06 at 11:41 +0100, Jerome Glisse wrote: From: Corbin Simpson mostawesomed...@gmail.com Long story short, this fixes sporadic hardlocks with my rv410 during times of intense 2D acceleration (Flash on Fx3). V2: Fix indentation and move errata_fini to suspend function so we don't leak scratch register over suspend/resume cycle. Signed-off-by: Corbin Simpson mostawesomed...@gmail.com Signed-off-by: Jerome Glisse jgli...@redhat.com --- [...] diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index cd650fd..b272065 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -798,6 +798,7 @@ struct radeon_device { struct radeon_gem gem; struct radeon_pmpm; uint32_tbios_scratch[RADEON_BIOS_NUM_SCRATCH]; +uint32_t resync_scratch; struct mutexcs_mutex; struct radeon_wbwb; struct radeon_dummy_pagedummy_page; Indentation still looks wrong in this hunk. -- Earthling Michel Dänzer |http://www.vmware.com Libre software enthusiast | Debian, X and DRI developer -- 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