aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-02-15 16:49:59 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-06-27 19:16:29 -0400
commitd719cef316d6377a7d6b5df495de118afb3a9fc2 (patch)
tree9b513e9940dd7c1b315ce54aae395d21bbbdd726 /drivers/gpu/drm/radeon
parent8ba104637b5901cdc52fb0455cefcc73dc4b10e4 (diff)
drm/radeon: update rlc programming sequence on SI
This is required for certain power management features. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/si.c82
-rw-r--r--drivers/gpu/drm/radeon/sid.h17
2 files changed, 99 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 9fd0bc379f36..84ed3325a0d9 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -4418,14 +4418,93 @@ int si_rlc_init(struct radeon_device *rdev)
4418 return 0; 4418 return 0;
4419} 4419}
4420 4420
4421static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
4422 bool enable)
4423{
4424 u32 tmp = RREG32(CP_INT_CNTL_RING0);
4425 u32 mask;
4426 int i;
4427
4428 if (enable)
4429 tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
4430 else
4431 tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
4432 WREG32(CP_INT_CNTL_RING0, tmp);
4433
4434 if (!enable) {
4435 /* read a gfx register */
4436 tmp = RREG32(DB_DEPTH_INFO);
4437
4438 mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS;
4439 for (i = 0; i < rdev->usec_timeout; i++) {
4440 if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS))
4441 break;
4442 udelay(1);
4443 }
4444 }
4445}
4446
4447static void si_wait_for_rlc_serdes(struct radeon_device *rdev)
4448{
4449 int i;
4450
4451 for (i = 0; i < rdev->usec_timeout; i++) {
4452 if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0)
4453 break;
4454 udelay(1);
4455 }
4456
4457 for (i = 0; i < rdev->usec_timeout; i++) {
4458 if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0)
4459 break;
4460 udelay(1);
4461 }
4462}
4463
4421static void si_rlc_stop(struct radeon_device *rdev) 4464static void si_rlc_stop(struct radeon_device *rdev)
4422{ 4465{
4423 WREG32(RLC_CNTL, 0); 4466 WREG32(RLC_CNTL, 0);
4467
4468 si_enable_gui_idle_interrupt(rdev, false);
4469
4470 si_wait_for_rlc_serdes(rdev);
4424} 4471}
4425 4472
4426static void si_rlc_start(struct radeon_device *rdev) 4473static void si_rlc_start(struct radeon_device *rdev)
4427{ 4474{
4428 WREG32(RLC_CNTL, RLC_ENABLE); 4475 WREG32(RLC_CNTL, RLC_ENABLE);
4476
4477 si_enable_gui_idle_interrupt(rdev, true);
4478
4479 udelay(50);
4480}
4481
4482static bool si_lbpw_supported(struct radeon_device *rdev)
4483{
4484 u32 tmp;
4485
4486 /* Enable LBPW only for DDR3 */
4487 tmp = RREG32(MC_SEQ_MISC0);
4488 if ((tmp & 0xF0000000) == 0xB0000000)
4489 return true;
4490 return false;
4491}
4492
4493static void si_enable_lbpw(struct radeon_device *rdev, bool enable)
4494{
4495 u32 tmp;
4496
4497 tmp = RREG32(RLC_LB_CNTL);
4498 if (enable)
4499 tmp |= LOAD_BALANCE_ENABLE;
4500 else
4501 tmp &= ~LOAD_BALANCE_ENABLE;
4502 WREG32(RLC_LB_CNTL, tmp);
4503
4504 if (!enable) {
4505 si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
4506 WREG32(SPI_LB_CU_MASK, 0x00ff);
4507 }
4429} 4508}
4430 4509
4431static int si_rlc_resume(struct radeon_device *rdev) 4510static int si_rlc_resume(struct radeon_device *rdev)
@@ -4443,6 +4522,7 @@ static int si_rlc_resume(struct radeon_device *rdev)
4443 WREG32(RLC_LB_CNTL, 0); 4522 WREG32(RLC_LB_CNTL, 0);
4444 WREG32(RLC_LB_CNTR_MAX, 0xffffffff); 4523 WREG32(RLC_LB_CNTR_MAX, 0xffffffff);
4445 WREG32(RLC_LB_CNTR_INIT, 0); 4524 WREG32(RLC_LB_CNTR_INIT, 0);
4525 WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff);
4446 4526
4447 WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); 4527 WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
4448 WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); 4528 WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
@@ -4457,6 +4537,8 @@ static int si_rlc_resume(struct radeon_device *rdev)
4457 } 4537 }
4458 WREG32(RLC_UCODE_ADDR, 0); 4538 WREG32(RLC_UCODE_ADDR, 0);
4459 4539
4540 si_enable_lbpw(rdev, si_lbpw_supported(rdev));
4541
4460 si_rlc_start(rdev); 4542 si_rlc_start(rdev);
4461 4543
4462 return 0; 4544 return 0;
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index 5f29d81d8db2..8786b6c93c67 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -275,6 +275,8 @@
275#define MC_IO_PAD_CNTL_D0 0x29d0 275#define MC_IO_PAD_CNTL_D0 0x29d0
276#define MEM_FALL_OUT_CMD (1 << 8) 276#define MEM_FALL_OUT_CMD (1 << 8)
277 277
278#define MC_SEQ_MISC0 0x2a00
279
278#define MC_SEQ_IO_DEBUG_INDEX 0x2a44 280#define MC_SEQ_IO_DEBUG_INDEX 0x2a44
279#define MC_SEQ_IO_DEBUG_DATA 0x2a48 281#define MC_SEQ_IO_DEBUG_DATA 0x2a48
280 282
@@ -638,6 +640,8 @@
638#define TCC_DISABLE_MASK 0xFFFF0000 640#define TCC_DISABLE_MASK 0xFFFF0000
639#define TCC_DISABLE_SHIFT 16 641#define TCC_DISABLE_SHIFT 16
640 642
643#define SPI_LB_CU_MASK 0x9354
644
641#define TA_CNTL_AUX 0x9508 645#define TA_CNTL_AUX 0x9508
642 646
643#define CC_RB_BACKEND_DISABLE 0x98F4 647#define CC_RB_BACKEND_DISABLE 0x98F4
@@ -790,6 +794,7 @@
790#define RLC_RL_BASE 0xC304 794#define RLC_RL_BASE 0xC304
791#define RLC_RL_SIZE 0xC308 795#define RLC_RL_SIZE 0xC308
792#define RLC_LB_CNTL 0xC30C 796#define RLC_LB_CNTL 0xC30C
797# define LOAD_BALANCE_ENABLE (1 << 0)
793#define RLC_SAVE_AND_RESTORE_BASE 0xC310 798#define RLC_SAVE_AND_RESTORE_BASE 0xC310
794#define RLC_LB_CNTR_MAX 0xC314 799#define RLC_LB_CNTR_MAX 0xC314
795#define RLC_LB_CNTR_INIT 0xC318 800#define RLC_LB_CNTR_INIT 0xC318
@@ -804,6 +809,18 @@
804#define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 809#define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340
805#define RLC_MC_CNTL 0xC344 810#define RLC_MC_CNTL 0xC344
806#define RLC_UCODE_CNTL 0xC348 811#define RLC_UCODE_CNTL 0xC348
812#define RLC_STAT 0xC34C
813# define RLC_BUSY_STATUS (1 << 0)
814# define GFX_POWER_STATUS (1 << 1)
815# define GFX_CLOCK_STATUS (1 << 2)
816# define GFX_LS_STATUS (1 << 3)
817
818#define RLC_LB_INIT_CU_MASK 0xC41C
819
820#define RLC_SERDES_MASTER_BUSY_0 0xC464
821#define RLC_SERDES_MASTER_BUSY_1 0xC468
822
823#define DB_DEPTH_INFO 0x2803c
807 824
808#define PA_SC_RASTER_CONFIG 0x28350 825#define PA_SC_RASTER_CONFIG 0x28350
809# define RASTER_CONFIG_RB_MAP_0 0 826# define RASTER_CONFIG_RB_MAP_0 0