Loading drivers/gpu/drm/radeon/si.c +82 −0 Original line number Diff line number Diff line Loading @@ -4418,14 +4418,93 @@ int si_rlc_init(struct radeon_device *rdev) return 0; } static void si_enable_gui_idle_interrupt(struct radeon_device *rdev, bool enable) { u32 tmp = RREG32(CP_INT_CNTL_RING0); u32 mask; int i; if (enable) tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); else tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); WREG32(CP_INT_CNTL_RING0, tmp); if (!enable) { /* read a gfx register */ tmp = RREG32(DB_DEPTH_INFO); mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS; for (i = 0; i < rdev->usec_timeout; i++) { if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS)) break; udelay(1); } } } static void si_wait_for_rlc_serdes(struct radeon_device *rdev) { int i; for (i = 0; i < rdev->usec_timeout; i++) { if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0) break; udelay(1); } for (i = 0; i < rdev->usec_timeout; i++) { if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0) break; udelay(1); } } static void si_rlc_stop(struct radeon_device *rdev) { WREG32(RLC_CNTL, 0); si_enable_gui_idle_interrupt(rdev, false); si_wait_for_rlc_serdes(rdev); } static void si_rlc_start(struct radeon_device *rdev) { WREG32(RLC_CNTL, RLC_ENABLE); si_enable_gui_idle_interrupt(rdev, true); udelay(50); } static bool si_lbpw_supported(struct radeon_device *rdev) { u32 tmp; /* Enable LBPW only for DDR3 */ tmp = RREG32(MC_SEQ_MISC0); if ((tmp & 0xF0000000) == 0xB0000000) return true; return false; } static void si_enable_lbpw(struct radeon_device *rdev, bool enable) { u32 tmp; tmp = RREG32(RLC_LB_CNTL); if (enable) tmp |= LOAD_BALANCE_ENABLE; else tmp &= ~LOAD_BALANCE_ENABLE; WREG32(RLC_LB_CNTL, tmp); if (!enable) { si_select_se_sh(rdev, 0xffffffff, 0xffffffff); WREG32(SPI_LB_CU_MASK, 0x00ff); } } static int si_rlc_resume(struct radeon_device *rdev) Loading @@ -4443,6 +4522,7 @@ static int si_rlc_resume(struct radeon_device *rdev) WREG32(RLC_LB_CNTL, 0); WREG32(RLC_LB_CNTR_MAX, 0xffffffff); WREG32(RLC_LB_CNTR_INIT, 0); WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff); WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); Loading @@ -4457,6 +4537,8 @@ static int si_rlc_resume(struct radeon_device *rdev) } WREG32(RLC_UCODE_ADDR, 0); si_enable_lbpw(rdev, si_lbpw_supported(rdev)); si_rlc_start(rdev); return 0; Loading drivers/gpu/drm/radeon/sid.h +17 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,8 @@ #define MC_IO_PAD_CNTL_D0 0x29d0 #define MEM_FALL_OUT_CMD (1 << 8) #define MC_SEQ_MISC0 0x2a00 #define MC_SEQ_IO_DEBUG_INDEX 0x2a44 #define MC_SEQ_IO_DEBUG_DATA 0x2a48 Loading Loading @@ -638,6 +640,8 @@ #define TCC_DISABLE_MASK 0xFFFF0000 #define TCC_DISABLE_SHIFT 16 #define SPI_LB_CU_MASK 0x9354 #define TA_CNTL_AUX 0x9508 #define CC_RB_BACKEND_DISABLE 0x98F4 Loading Loading @@ -790,6 +794,7 @@ #define RLC_RL_BASE 0xC304 #define RLC_RL_SIZE 0xC308 #define RLC_LB_CNTL 0xC30C # define LOAD_BALANCE_ENABLE (1 << 0) #define RLC_SAVE_AND_RESTORE_BASE 0xC310 #define RLC_LB_CNTR_MAX 0xC314 #define RLC_LB_CNTR_INIT 0xC318 Loading @@ -804,6 +809,18 @@ #define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 #define RLC_MC_CNTL 0xC344 #define RLC_UCODE_CNTL 0xC348 #define RLC_STAT 0xC34C # define RLC_BUSY_STATUS (1 << 0) # define GFX_POWER_STATUS (1 << 1) # define GFX_CLOCK_STATUS (1 << 2) # define GFX_LS_STATUS (1 << 3) #define RLC_LB_INIT_CU_MASK 0xC41C #define RLC_SERDES_MASTER_BUSY_0 0xC464 #define RLC_SERDES_MASTER_BUSY_1 0xC468 #define DB_DEPTH_INFO 0x2803c #define PA_SC_RASTER_CONFIG 0x28350 # define RASTER_CONFIG_RB_MAP_0 0 Loading Loading
drivers/gpu/drm/radeon/si.c +82 −0 Original line number Diff line number Diff line Loading @@ -4418,14 +4418,93 @@ int si_rlc_init(struct radeon_device *rdev) return 0; } static void si_enable_gui_idle_interrupt(struct radeon_device *rdev, bool enable) { u32 tmp = RREG32(CP_INT_CNTL_RING0); u32 mask; int i; if (enable) tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); else tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); WREG32(CP_INT_CNTL_RING0, tmp); if (!enable) { /* read a gfx register */ tmp = RREG32(DB_DEPTH_INFO); mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS; for (i = 0; i < rdev->usec_timeout; i++) { if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS)) break; udelay(1); } } } static void si_wait_for_rlc_serdes(struct radeon_device *rdev) { int i; for (i = 0; i < rdev->usec_timeout; i++) { if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0) break; udelay(1); } for (i = 0; i < rdev->usec_timeout; i++) { if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0) break; udelay(1); } } static void si_rlc_stop(struct radeon_device *rdev) { WREG32(RLC_CNTL, 0); si_enable_gui_idle_interrupt(rdev, false); si_wait_for_rlc_serdes(rdev); } static void si_rlc_start(struct radeon_device *rdev) { WREG32(RLC_CNTL, RLC_ENABLE); si_enable_gui_idle_interrupt(rdev, true); udelay(50); } static bool si_lbpw_supported(struct radeon_device *rdev) { u32 tmp; /* Enable LBPW only for DDR3 */ tmp = RREG32(MC_SEQ_MISC0); if ((tmp & 0xF0000000) == 0xB0000000) return true; return false; } static void si_enable_lbpw(struct radeon_device *rdev, bool enable) { u32 tmp; tmp = RREG32(RLC_LB_CNTL); if (enable) tmp |= LOAD_BALANCE_ENABLE; else tmp &= ~LOAD_BALANCE_ENABLE; WREG32(RLC_LB_CNTL, tmp); if (!enable) { si_select_se_sh(rdev, 0xffffffff, 0xffffffff); WREG32(SPI_LB_CU_MASK, 0x00ff); } } static int si_rlc_resume(struct radeon_device *rdev) Loading @@ -4443,6 +4522,7 @@ static int si_rlc_resume(struct radeon_device *rdev) WREG32(RLC_LB_CNTL, 0); WREG32(RLC_LB_CNTR_MAX, 0xffffffff); WREG32(RLC_LB_CNTR_INIT, 0); WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff); WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); Loading @@ -4457,6 +4537,8 @@ static int si_rlc_resume(struct radeon_device *rdev) } WREG32(RLC_UCODE_ADDR, 0); si_enable_lbpw(rdev, si_lbpw_supported(rdev)); si_rlc_start(rdev); return 0; Loading
drivers/gpu/drm/radeon/sid.h +17 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,8 @@ #define MC_IO_PAD_CNTL_D0 0x29d0 #define MEM_FALL_OUT_CMD (1 << 8) #define MC_SEQ_MISC0 0x2a00 #define MC_SEQ_IO_DEBUG_INDEX 0x2a44 #define MC_SEQ_IO_DEBUG_DATA 0x2a48 Loading Loading @@ -638,6 +640,8 @@ #define TCC_DISABLE_MASK 0xFFFF0000 #define TCC_DISABLE_SHIFT 16 #define SPI_LB_CU_MASK 0x9354 #define TA_CNTL_AUX 0x9508 #define CC_RB_BACKEND_DISABLE 0x98F4 Loading Loading @@ -790,6 +794,7 @@ #define RLC_RL_BASE 0xC304 #define RLC_RL_SIZE 0xC308 #define RLC_LB_CNTL 0xC30C # define LOAD_BALANCE_ENABLE (1 << 0) #define RLC_SAVE_AND_RESTORE_BASE 0xC310 #define RLC_LB_CNTR_MAX 0xC314 #define RLC_LB_CNTR_INIT 0xC318 Loading @@ -804,6 +809,18 @@ #define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 #define RLC_MC_CNTL 0xC344 #define RLC_UCODE_CNTL 0xC348 #define RLC_STAT 0xC34C # define RLC_BUSY_STATUS (1 << 0) # define GFX_POWER_STATUS (1 << 1) # define GFX_CLOCK_STATUS (1 << 2) # define GFX_LS_STATUS (1 << 3) #define RLC_LB_INIT_CU_MASK 0xC41C #define RLC_SERDES_MASTER_BUSY_0 0xC464 #define RLC_SERDES_MASTER_BUSY_1 0xC468 #define DB_DEPTH_INFO 0x2803c #define PA_SC_RASTER_CONFIG 0x28350 # define RASTER_CONFIG_RB_MAP_0 0 Loading