From f657c2a7310ad56e2b67f35f4c5c6106a7146b9c Mon Sep 17 00:00:00 2001
From: Yang Zhao <yang@yangman.ca>
Date: Tue, 15 Sep 2009 12:21:01 +1000
Subject: drm/radeon: Save and restore bios scratch regs during S/R

[airlied:- adapted slightly in naming]

Signed-off-by: Yang Zhao <yang@yangman.ca>
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 drivers/gpu/drm/radeon/radeon.h          |  2 ++
 drivers/gpu/drm/radeon/radeon_atombios.c | 28 ++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/radeon_device.c   |  3 +++
 drivers/gpu/drm/radeon/radeon_mode.h     |  2 ++
 4 files changed, 35 insertions(+)

(limited to 'drivers/gpu')

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index ff9e4171559a..5bfc05612ac2 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -75,6 +75,7 @@ extern int radeon_tv;
 #define RADEON_IB_POOL_SIZE		16
 #define RADEON_DEBUGFS_MAX_NUM_FILES	32
 #define RADEONFB_CONN_LIMIT		4
+#define RADEON_BIOS_NUM_SCRATCH		8
 
 enum radeon_family {
 	CHIP_R100,
@@ -783,6 +784,7 @@ struct radeon_device {
 	struct radeon_asic		*asic;
 	struct radeon_gem		gem;
 	struct radeon_pm		pm;
+	uint32_t			bios_scratch[RADEON_BIOS_NUM_SCRATCH];
 	struct mutex			cs_mutex;
 	struct radeon_wb		wb;
 	struct radeon_dummy_page	dummy_page;
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index aa756dec8959..cb5efcaf2bab 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1045,6 +1045,34 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
 
 }
 
+void radeon_save_bios_scratch_regs(struct radeon_device *rdev)
+{
+	uint32_t scratch_reg;
+	int i;
+
+	if (rdev->family >= CHIP_R600)
+		scratch_reg = R600_BIOS_0_SCRATCH;
+	else
+		scratch_reg = RADEON_BIOS_0_SCRATCH;
+
+	for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
+		rdev->bios_scratch[i] = RREG32(scratch_reg + (i * 4));
+}
+
+void radeon_restore_bios_scratch_regs(struct radeon_device *rdev)
+{
+	uint32_t scratch_reg;
+	int i;
+
+	if (rdev->family >= CHIP_R600)
+		scratch_reg = R600_BIOS_0_SCRATCH;
+	else
+		scratch_reg = RADEON_BIOS_0_SCRATCH;
+
+	for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
+		WREG32(scratch_reg + (i * 4), rdev->bios_scratch[i]);
+}
+
 void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock)
 {
 	struct drm_device *dev = encoder->dev;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index cc8e005c1b30..db5ae73d6289 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -755,6 +755,8 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
 	/* wait for gpu to finish processing current batch */
 	radeon_fence_wait_last(rdev);
 
+	radeon_save_bios_scratch_regs(rdev);
+
 	if (!rdev->new_init_path) {
 		radeon_cp_disable(rdev);
 		radeon_gart_disable(rdev);
@@ -828,6 +830,7 @@ int radeon_resume_kms(struct drm_device *dev)
 		radeon_resume(rdev);
 	}
 out:
+	radeon_restore_bios_scratch_regs(rdev);
 	fb_set_suspend(rdev->fbdev_info, 0);
 	release_console_sem();
 
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 523d6cbd4f08..dde13817dee0 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -383,6 +383,8 @@ extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock);
 extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev);
 extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock);
 extern void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev);
+extern void radeon_save_bios_scratch_regs(struct radeon_device *rdev);
+extern void radeon_restore_bios_scratch_regs(struct radeon_device *rdev);
 extern void
 radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc);
 extern void
-- 
cgit v1.2.3