@@ -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)
@@ -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 = &rdev->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)
@@ -162,6 +162,25 @@
#define HDP_MISC_CNTL 0x2F4C
#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0)
+#define IH_RB_CNTL 0x3e00
+# 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_NONE 0
+# 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)
+
#define CC_SYS_RB_BACKEND_DISABLE 0x3F88
#define GC_USER_SYS_RB_BACKEND_DISABLE 0x3F8C
#define CGTS_SYS_TCC_DISABLE 0x3F90
@@ -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) {
- WREG32(RADEON_CP_CSQ_CNTL, 0);
- }
- tmp = RREG32(RADEON_CP_RB_CNTL);
- if (tmp) {
- WREG32(RADEON_CP_RB_CNTL, 0);
- }
- tmp = RREG32(RADEON_SCRATCH_UMSK);
- if (tmp) {
- WREG32(RADEON_SCRATCH_UMSK, 0);
- }
+ /* 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, RADEON_RB_NO_UPDATE);
+ WREG32(RADEON_GEN_INT_CNTL, 0);
}
int r100_init(struct radeon_device *rdev)
@@ -249,7 +249,7 @@ int r520_init(struct radeon_device *rdev)
/* Initialize surface registers */
radeon_surface_init(rdev);
/* restore some register to sane defaults */
- r100_restore_sanity(rdev);
+ rs600_restore_sanity(rdev);
/* TODO: disable VGA need to use VGA request */
/* BIOS*/
if (!radeon_get_bios(rdev)) {
@@ -2556,6 +2556,20 @@ int r600_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 r600_restore_sanity(struct radeon_device *rdev)
+{
+ /* stop possible GPU activities */
+ WREG32(IH_RB_CNTL, 0);
+ WREG32(IH_CNTL, 0);
+ WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
+ WREG32(SCRATCH_UMSK, 0);
+ WREG32(CP_RB_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
@@ -2566,6 +2580,8 @@ int r600_init(struct radeon_device *rdev)
{
int r;
+ /* restore some register to sane defaults */
+ r600_restore_sanity(rdev);
if (r600_debugfs_mc_info_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for mc !\n");
}
@@ -215,6 +215,7 @@ extern int rs600_init(struct radeon_device *rdev);
extern void rs600_fini(struct radeon_device *rdev);
extern int rs600_suspend(struct radeon_device *rdev);
extern int rs600_resume(struct radeon_device *rdev);
+void rs600_restore_sanity(struct radeon_device *rdev);
int rs600_irq_set(struct radeon_device *rdev);
int rs600_irq_process(struct radeon_device *rdev);
void rs600_irq_disable(struct radeon_device *rdev);
@@ -388,6 +389,7 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
void r700_cp_stop(struct radeon_device *rdev);
void r700_cp_fini(struct radeon_device *rdev);
+void rv770_restore_sanity(struct radeon_device *rdev);
/*
* evergreen
@@ -935,6 +935,24 @@ void rs600_fini(struct radeon_device *rdev)
rdev->bios = NULL;
}
+
+/*
+ * Due to how kexec works, it can leave the hw fully initialised when it
+ * boots the new kernel.
+ */
+void rs600_restore_sanity(struct radeon_device *rdev)
+{
+ /* stop possible GPU activities */
+ WREG32(R_000740_CP_CSQ_CNTL, 0);
+ WREG32(R_000744_CP_CSQ_MODE, 0);
+ WREG32(R_000770_SCRATCH_UMSK, 0);
+ WREG32(R_000704_CP_RB_CNTL, S_000704_RB_NO_UPDATE(1));
+ WREG32(R_000040_GEN_INT_CNTL, 0);
+ WREG32(R_006540_DxMODE_INT_MASK, 0);
+ WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, 0);
+ WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, 0);
+}
+
int rs600_init(struct radeon_device *rdev)
{
int r;
@@ -946,7 +964,7 @@ int rs600_init(struct radeon_device *rdev)
/* Initialize surface registers */
radeon_surface_init(rdev);
/* restore some register to sane defaults */
- r100_restore_sanity(rdev);
+ rs600_restore_sanity(rdev);
/* BIOS */
if (!radeon_get_bios(rdev)) {
if (ASIC_IS_AVIVO(rdev))
@@ -668,4 +668,25 @@
#define PM_ASSERT_RESET (1 << 20)
#define PM_PWRDN_PPLL (1 << 24)
+#define R_000704_CP_RB_CNTL 0x000704
+#define S_000704_RB_NO_UPDATE(x) (((x) & 0x1) << 27)
+#define R_000740_CP_CSQ_CNTL 0x000740
+#define S_000740_CSQ_CNT_PRIMARY(x) (((x) & 0xFF) << 0)
+#define G_000740_CSQ_CNT_PRIMARY(x) (((x) >> 0) & 0xFF)
+#define C_000740_CSQ_CNT_PRIMARY 0xFFFFFF00
+#define S_000740_CSQ_CNT_INDIRECT(x) (((x) & 0xFF) << 8)
+#define G_000740_CSQ_CNT_INDIRECT(x) (((x) >> 8) & 0xFF)
+#define C_000740_CSQ_CNT_INDIRECT 0xFFFF00FF
+#define S_000740_CSQ_MODE(x) (((x) & 0xF) << 28)
+#define G_000740_CSQ_MODE(x) (((x) >> 28) & 0xF)
+#define C_000740_CSQ_MODE 0x0FFFFFFF
+#define R_000744_CP_CSQ_MODE 0x000744
+#define R_000770_SCRATCH_UMSK 0x000770
+#define S_000770_SCRATCH_UMSK(x) (((x) & 0x3F) << 0)
+#define G_000770_SCRATCH_UMSK(x) (((x) >> 0) & 0x3F)
+#define C_000770_SCRATCH_UMSK 0xFFFFFFC0
+#define S_000770_SCRATCH_SWAP(x) (((x) & 0x3) << 16)
+#define G_000770_SCRATCH_SWAP(x) (((x) >> 16) & 0x3)
+#define C_000770_SCRATCH_SWAP 0xFFFCFFFF
+
#endif
@@ -718,7 +718,7 @@ int rs690_init(struct radeon_device *rdev)
/* Initialize surface registers */
radeon_surface_init(rdev);
/* restore some register to sane defaults */
- r100_restore_sanity(rdev);
+ rs600_restore_sanity(rdev);
/* TODO: disable VGA need to use VGA request */
/* BIOS*/
if (!radeon_get_bios(rdev)) {
@@ -488,7 +488,7 @@ int rv515_init(struct radeon_device *rdev)
radeon_surface_init(rdev);
/* TODO: disable VGA need to use VGA request */
/* restore some register to sane defaults */
- r100_restore_sanity(rdev);
+ rs600_restore_sanity(rdev);
/* BIOS*/
if (!radeon_get_bios(rdev)) {
if (ASIC_IS_AVIVO(rdev))
@@ -1167,6 +1167,20 @@ int rv770_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.
+ */
+void rv770_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_RB_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
@@ -1177,6 +1191,8 @@ int rv770_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)
@@ -38,6 +38,26 @@
#define R7XX_MAX_PIPES 8
#define R7XX_MAX_PIPES_MASK 0xff
+
+#define IH_RB_CNTL 0x3e00
+# 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_NONE 0
+# 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)
+
/* Registers */
#define CB_COLOR0_BASE 0x28040
#define CB_COLOR1_BASE 0x28044