[PATCH] drm/radeon: disable possible GPU writeback early

2011-12-05 Thread Jerome Glisse
Given how kexec works we need to disable any kind of GPU writeback
early in GPU initialization just in case some are still active from
previous setup.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/evergreen.c |7 ++
 drivers/gpu/drm/radeon/ni.c|9 +++
 drivers/gpu/drm/radeon/nid.h   |   19 
 drivers/gpu/drm/radeon/r100.c  |7 ++
 drivers/gpu/drm/radeon/r300.c  |7 ++
 drivers/gpu/drm/radeon/r300d.h |   21 ++
 drivers/gpu/drm/radeon/r420.c  |7 ++
 drivers/gpu/drm/radeon/r420d.h |   42 
 drivers/gpu/drm/radeon/r520.c  |   10 
 drivers/gpu/drm/radeon/r520d.h |   24 
 drivers/gpu/drm/radeon/r600.c  |7 ++
 drivers/gpu/drm/radeon/rs400.c |7 ++
 drivers/gpu/drm/radeon/rs400d.h|   21 ++
 drivers/gpu/drm/radeon/rs600.c |   10 
 drivers/gpu/drm/radeon/rs600d.h|   21 ++
 drivers/gpu/drm/radeon/rs690.c |   10 
 drivers/gpu/drm/radeon/rs690d.h|   24 
 drivers/gpu/drm/radeon/rv515.c |   10 
 drivers/gpu/drm/radeon/rv515d.h|   24 
 drivers/gpu/drm/radeon/rv770.c |7 ++
 drivers/gpu/drm/radeon/rv770d.h|   20 +
 21 files changed, 314 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 1934728..d49596b 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3249,6 +3249,13 @@ int evergreen_init(struct radeon_device *rdev)
 {
int r;

+   /* stop possible GPU activities */
+   WREG32(IH_RB_CNTL, 0);
+   WREG32(IH_CNTL, 0);
+   WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
+   WREG32(SCRATCH_UMSK, 0);
+   WREG32(CP_RB_CNTL, RB_NO_UPDATE);
+
/* This don't do much */
r = radeon_gem_init(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index c15fc8b..2a00ad1 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1577,6 +1577,15 @@ int cayman_init(struct radeon_device *rdev)
struct radeon_ring *ring = >ring[RADEON_RING_TYPE_GFX_INDEX];
int r;

+   /* stop possible GPU activities */
+   WREG32(IH_RB_CNTL, 0);
+   WREG32(IH_CNTL, 0);
+   WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
+   WREG32(SCRATCH_UMSK, 0);
+   WREG32(CP_RB0_CNTL, RB_NO_UPDATE);
+   WREG32(CP_RB1_CNTL, RB_NO_UPDATE);
+   WREG32(CP_RB2_CNTL, RB_NO_UPDATE);
+
/* This don't do much */
r = radeon_gem_init(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 4640334..3aa33c6 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -162,6 +162,25 @@
 #define HDP_MISC_CNTL  0x2F4C
 #defineHDP_FLUSH_INVALIDATE_CACHE  (1 << 0)

+#define IH_RB_CNTL0x3e00
+#   define IH_RB_ENABLE   (1 << 0)
+#   define IH_IB_SIZE(x)  ((x) << 1) /* log2 */
+#   define IH_RB_FULL_DRAIN_ENABLE(1 << 6)
+#   define IH_WPTR_WRITEBACK_ENABLE   (1 << 8)
+#   define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */
+#   define IH_WPTR_OVERFLOW_ENABLE(1 << 16)
+#   define IH_WPTR_OVERFLOW_CLEAR (1 << 31)
+#define IH_CNTL   0x3e18
+#   define ENABLE_INTR(1 << 0)
+#   define IH_MC_SWAP(x)  ((x) << 1)
+#   define IH_MC_SWAP_NONE0
+#   define IH_MC_SWAP_16BIT   1
+#   define IH_MC_SWAP_32BIT   2
+#   define IH_MC_SWAP_64BIT   3
+#   define RPTR_REARM (1 << 4)
+#   define MC_WRREQ_CREDIT(x) ((x) << 15)
+#   define MC_WR_CLEAN_CNT(x) ((x) << 20)
+
 #defineCC_SYS_RB_BACKEND_DISABLE   0x3F88
 #defineGC_USER_SYS_RB_BACKEND_DISABLE  0x3F8C
 #defineCGTS_SYS_TCC_DISABLE0x3F90
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 657040b..8a71502 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -4010,6 +4010,13 @@ int r100_init(struct radeon_device *rdev)
 {
int r;

+   /* stop possible GPU activities */
+   WREG32(RADEON_CP_CSQ_MODE, 0);
+   WREG32(RADEON_CP_CSQ_CNTL, 0);
+   WREG32(R_000770_SCRATCH_UMSK, 0);
+   WREG32(RADEON_CP_RB_CNTL, 

[PATCH] drm/radeon: disable possible GPU writeback early v2

2011-12-05 Thread Jerome Glisse
Given how kexec works we need to disable any kind of GPU writeback
early in GPU initialization just in case some are still active from
previous setup.

v2 follow previous sanity work done on earlier radeon, also write
reg uncondionaly and disable irq too.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/evergreen.c   |2 ++
 drivers/gpu/drm/radeon/ni.c  |   18 ++
 drivers/gpu/drm/radeon/nid.h |   19 +++
 drivers/gpu/drm/radeon/r100.c|   20 ++--
 drivers/gpu/drm/radeon/r520.c|2 +-
 drivers/gpu/drm/radeon/r600.c|   16 
 drivers/gpu/drm/radeon/radeon_asic.h |2 ++
 drivers/gpu/drm/radeon/rs600.c   |   20 +++-
 drivers/gpu/drm/radeon/rs600d.h  |   21 +
 drivers/gpu/drm/radeon/rs690.c   |2 +-
 drivers/gpu/drm/radeon/rv515.c   |2 +-
 drivers/gpu/drm/radeon/rv770.c   |   16 
 drivers/gpu/drm/radeon/rv770d.h  |   20 
 13 files changed, 142 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 1934728..6109579 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3249,6 +3249,8 @@ int evergreen_init(struct radeon_device *rdev)
 {
int r;

+   /* restore some register to sane defaults */
+   rv770_restore_sanity(rdev);
/* This don't do much */
r = radeon_gem_init(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index c15fc8b..f5d7054 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1566,6 +1566,22 @@ int cayman_suspend(struct radeon_device *rdev)
return 0;
 }

+/*
+ * Due to how kexec works, it can leave the hw fully initialised when it
+ * boots the new kernel.
+ */
+static void cayman_restore_sanity(struct radeon_device *rdev)
+{
+   /* stop possible GPU activities */
+   WREG32(IH_RB_CNTL, 0);
+   WREG32(IH_CNTL, 0);
+   WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
+   WREG32(SCRATCH_UMSK, 0);
+   WREG32(CP_RB0_CNTL, RB_NO_UPDATE);
+   WREG32(CP_RB1_CNTL, RB_NO_UPDATE);
+   WREG32(CP_RB2_CNTL, RB_NO_UPDATE);
+}
+
 /* Plan is to move initialization in that function and use
  * helper function so that radeon_device_init pretty much
  * do nothing more than calling asic specific function. This
@@ -1577,6 +1593,8 @@ int cayman_init(struct radeon_device *rdev)
struct radeon_ring *ring = >ring[RADEON_RING_TYPE_GFX_INDEX];
int r;

+   /* restore some register to sane defaults */
+   cayman_restore_sanity(rdev);
/* This don't do much */
r = radeon_gem_init(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 4640334..3aa33c6 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -162,6 +162,25 @@
 #define HDP_MISC_CNTL  0x2F4C
 #defineHDP_FLUSH_INVALIDATE_CACHE  (1 << 0)

+#define IH_RB_CNTL0x3e00
+#   define IH_RB_ENABLE   (1 << 0)
+#   define IH_IB_SIZE(x)  ((x) << 1) /* log2 */
+#   define IH_RB_FULL_DRAIN_ENABLE(1 << 6)
+#   define IH_WPTR_WRITEBACK_ENABLE   (1 << 8)
+#   define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */
+#   define IH_WPTR_OVERFLOW_ENABLE(1 << 16)
+#   define IH_WPTR_OVERFLOW_CLEAR (1 << 31)
+#define IH_CNTL   0x3e18
+#   define ENABLE_INTR(1 << 0)
+#   define IH_MC_SWAP(x)  ((x) << 1)
+#   define IH_MC_SWAP_NONE0
+#   define IH_MC_SWAP_16BIT   1
+#   define IH_MC_SWAP_32BIT   2
+#   define IH_MC_SWAP_64BIT   3
+#   define RPTR_REARM (1 << 4)
+#   define MC_WRREQ_CREDIT(x) ((x) << 15)
+#   define MC_WR_CLEAN_CNT(x) ((x) << 20)
+
 #defineCC_SYS_RB_BACKEND_DISABLE   0x3F88
 #defineGC_USER_SYS_RB_BACKEND_DISABLE  0x3F8C
 #defineCGTS_SYS_TCC_DISABLE0x3F90
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 657040b..d58531f 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3990,20 +3990,12 @@ void r100_fini(struct radeon_device *rdev)
  */
 void r100_restore_sanity(struct radeon_device *rdev)
 {
-   u32 tmp;
-
-   tmp = RREG32(RADEON_CP_CSQ_CNTL);
-   if (tmp) {
-   

[PATCH] drm/radeon: disable possible GPU writeback early v3

2011-12-05 Thread Jerome Glisse
Given how kexec works we need to disable any kind of GPU writeback
early in GPU initialization just in case some are still active from
previous setup. This patch is done to fix the issue described in
the lkml thread :

WARNING: at mm/slub.c:3357, kernel BUG at mm/slub.c:3413

https://lkml.org/lkml/2011/12/5/466

Thanks to Markus Trippelsdorf for testing this.

v2 follow previous sanity work done on earlier radeon, also write
reg uncondionaly and disable irq too.
v3 update change log

Signed-off-by: Jerome Glisse 
Tested-by: Markus Trippelsdorf 
---
 drivers/gpu/drm/radeon/evergreen.c   |2 ++
 drivers/gpu/drm/radeon/ni.c  |   18 ++
 drivers/gpu/drm/radeon/nid.h |   19 +++
 drivers/gpu/drm/radeon/r100.c|   20 ++--
 drivers/gpu/drm/radeon/r520.c|2 +-
 drivers/gpu/drm/radeon/r600.c|   16 
 drivers/gpu/drm/radeon/radeon_asic.h |2 ++
 drivers/gpu/drm/radeon/rs600.c   |   20 +++-
 drivers/gpu/drm/radeon/rs600d.h  |   21 +
 drivers/gpu/drm/radeon/rs690.c   |2 +-
 drivers/gpu/drm/radeon/rv515.c   |2 +-
 drivers/gpu/drm/radeon/rv770.c   |   16 
 drivers/gpu/drm/radeon/rv770d.h  |   20 
 13 files changed, 142 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 1934728..6109579 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3249,6 +3249,8 @@ int evergreen_init(struct radeon_device *rdev)
 {
int r;

+   /* restore some register to sane defaults */
+   rv770_restore_sanity(rdev);
/* This don't do much */
r = radeon_gem_init(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index c15fc8b..f5d7054 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1566,6 +1566,22 @@ int cayman_suspend(struct radeon_device *rdev)
return 0;
 }

+/*
+ * Due to how kexec works, it can leave the hw fully initialised when it
+ * boots the new kernel.
+ */
+static void cayman_restore_sanity(struct radeon_device *rdev)
+{
+   /* stop possible GPU activities */
+   WREG32(IH_RB_CNTL, 0);
+   WREG32(IH_CNTL, 0);
+   WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
+   WREG32(SCRATCH_UMSK, 0);
+   WREG32(CP_RB0_CNTL, RB_NO_UPDATE);
+   WREG32(CP_RB1_CNTL, RB_NO_UPDATE);
+   WREG32(CP_RB2_CNTL, RB_NO_UPDATE);
+}
+
 /* Plan is to move initialization in that function and use
  * helper function so that radeon_device_init pretty much
  * do nothing more than calling asic specific function. This
@@ -1577,6 +1593,8 @@ int cayman_init(struct radeon_device *rdev)
struct radeon_ring *ring = >ring[RADEON_RING_TYPE_GFX_INDEX];
int r;

+   /* restore some register to sane defaults */
+   cayman_restore_sanity(rdev);
/* This don't do much */
r = radeon_gem_init(rdev);
if (r)
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 4640334..3aa33c6 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -162,6 +162,25 @@
 #define HDP_MISC_CNTL  0x2F4C
 #defineHDP_FLUSH_INVALIDATE_CACHE  (1 << 0)

+#define IH_RB_CNTL0x3e00
+#   define IH_RB_ENABLE   (1 << 0)
+#   define IH_IB_SIZE(x)  ((x) << 1) /* log2 */
+#   define IH_RB_FULL_DRAIN_ENABLE(1 << 6)
+#   define IH_WPTR_WRITEBACK_ENABLE   (1 << 8)
+#   define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */
+#   define IH_WPTR_OVERFLOW_ENABLE(1 << 16)
+#   define IH_WPTR_OVERFLOW_CLEAR (1 << 31)
+#define IH_CNTL   0x3e18
+#   define ENABLE_INTR(1 << 0)
+#   define IH_MC_SWAP(x)  ((x) << 1)
+#   define IH_MC_SWAP_NONE0
+#   define IH_MC_SWAP_16BIT   1
+#   define IH_MC_SWAP_32BIT   2
+#   define IH_MC_SWAP_64BIT   3
+#   define RPTR_REARM (1 << 4)
+#   define MC_WRREQ_CREDIT(x) ((x) << 15)
+#   define MC_WR_CLEAN_CNT(x) ((x) << 20)
+
 #defineCC_SYS_RB_BACKEND_DISABLE   0x3F88
 #defineGC_USER_SYS_RB_BACKEND_DISABLE  0x3F8C
 #defineCGTS_SYS_TCC_DISABLE0x3F90
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 657040b..d58531f 100644
---