diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-02-15 16:49:59 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-06-27 19:16:29 -0400 |
commit | d719cef316d6377a7d6b5df495de118afb3a9fc2 (patch) | |
tree | 9b513e9940dd7c1b315ce54aae395d21bbbdd726 /drivers/gpu/drm/radeon | |
parent | 8ba104637b5901cdc52fb0455cefcc73dc4b10e4 (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.c | 82 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 17 |
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 | ||
4421 | static 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 | |||
4447 | static 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 | |||
4421 | static void si_rlc_stop(struct radeon_device *rdev) | 4464 | static 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 | ||
4426 | static void si_rlc_start(struct radeon_device *rdev) | 4473 | static 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 | |||
4482 | static 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 | |||
4493 | static 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 | ||
4431 | static int si_rlc_resume(struct radeon_device *rdev) | 4510 | static 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 |