提交 d719cef3 编写于 作者: A Alex Deucher

drm/radeon: update rlc programming sequence on SI

This is required for certain power management features.
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
上级 8ba10463
......@@ -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)
......@@ -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);
......@@ -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;
......
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册