diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index f50b5a77f45a..9804318f3488 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -244,6 +244,224 @@ static void mmhub_v1_0_program_invalidation(struct amdgpu_device *adev) } } +struct pctl_data { + uint32_t index; + uint32_t data; +}; + +const struct pctl_data pctl0_data[] = { + {0x0, 0x7a640}, + {0x9, 0x2a64a}, + {0xd, 0x2a680}, + {0x11, 0x6a684}, + {0x19, 0xea68e}, + {0x29, 0xa69e}, + {0x2b, 0x34a6c0}, + {0x61, 0x83a707}, + {0xe6, 0x8a7a4}, + {0xf0, 0x1a7b8}, + {0xf3, 0xfa7cc}, + {0x104, 0x17a7dd}, + {0x11d, 0xa7dc}, + {0x11f, 0x12a7f5}, + {0x133, 0xa808}, + {0x135, 0x12a810}, + {0x149, 0x7a82c} +}; +#define PCTL0_DATA_LEN (sizeof(pctl0_data)/sizeof(pctl0_data[0])) + +#define PCTL0_RENG_EXEC_END_PTR 0x151 +#define PCTL0_STCTRL_REG_SAVE_RANGE0_BASE 0xa640 +#define PCTL0_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa833 + +const struct pctl_data pctl1_data[] = { + {0x0, 0x39a000}, + {0x3b, 0x44a040}, + {0x81, 0x2a08d}, + {0x85, 0x6ba094}, + {0xf2, 0x18a100}, + {0x10c, 0x4a132}, + {0x112, 0xca141}, + {0x120, 0x2fa158}, + {0x151, 0x17a1d0}, + {0x16a, 0x1a1e9}, + {0x16d, 0x13a1ec}, + {0x182, 0x7a201}, + {0x18b, 0x3a20a}, + {0x190, 0x7a580}, + {0x199, 0xa590}, + {0x19b, 0x4a594}, + {0x1a1, 0x1a59c}, + {0x1a4, 0x7a82c}, + {0x1ad, 0xfa7cc}, + {0x1be, 0x17a7dd}, + {0x1d7, 0x12a810} +}; +#define PCTL1_DATA_LEN (sizeof(pctl1_data)/sizeof(pctl1_data[0])) + +#define PCTL1_RENG_EXEC_END_PTR 0x1ea +#define PCTL1_STCTRL_REG_SAVE_RANGE0_BASE 0xa000 +#define PCTL1_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa20d +#define PCTL1_STCTRL_REG_SAVE_RANGE1_BASE 0xa580 +#define PCTL1_STCTRL_REG_SAVE_RANGE1_LIMIT 0xa59d +#define PCTL1_STCTRL_REG_SAVE_RANGE2_BASE 0xa82c +#define PCTL1_STCTRL_REG_SAVE_RANGE2_LIMIT 0xa833 + +static void mmhub_v1_0_power_gating_write_save_ranges(struct amdgpu_device *adev) +{ + uint32_t tmp = 0; + + /* PCTL0_STCTRL_REGISTER_SAVE_RANGE0 */ + tmp = REG_SET_FIELD(tmp, PCTL0_STCTRL_REGISTER_SAVE_RANGE0, + STCTRL_REGISTER_SAVE_BASE, + PCTL0_STCTRL_REG_SAVE_RANGE0_BASE); + tmp = REG_SET_FIELD(tmp, PCTL0_STCTRL_REGISTER_SAVE_RANGE0, + STCTRL_REGISTER_SAVE_LIMIT, + PCTL0_STCTRL_REG_SAVE_RANGE0_LIMIT); + WREG32_SOC15(MMHUB, 0, mmPCTL0_STCTRL_REGISTER_SAVE_RANGE0, tmp); + + /* PCTL1_STCTRL_REGISTER_SAVE_RANGE0 */ + tmp = 0; + tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE0, + STCTRL_REGISTER_SAVE_BASE, + PCTL1_STCTRL_REG_SAVE_RANGE0_BASE); + tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE0, + STCTRL_REGISTER_SAVE_LIMIT, + PCTL1_STCTRL_REG_SAVE_RANGE0_LIMIT); + WREG32_SOC15(MMHUB, 0, mmPCTL1_STCTRL_REGISTER_SAVE_RANGE0, tmp); + + /* PCTL1_STCTRL_REGISTER_SAVE_RANGE1 */ + tmp = 0; + tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE1, + STCTRL_REGISTER_SAVE_BASE, + PCTL1_STCTRL_REG_SAVE_RANGE1_BASE); + tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE1, + STCTRL_REGISTER_SAVE_LIMIT, + PCTL1_STCTRL_REG_SAVE_RANGE1_LIMIT); + WREG32_SOC15(MMHUB, 0, mmPCTL1_STCTRL_REGISTER_SAVE_RANGE1, tmp); + + /* PCTL1_STCTRL_REGISTER_SAVE_RANGE2 */ + tmp = 0; + tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE2, + STCTRL_REGISTER_SAVE_BASE, + PCTL1_STCTRL_REG_SAVE_RANGE2_BASE); + tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE2, + STCTRL_REGISTER_SAVE_LIMIT, + PCTL1_STCTRL_REG_SAVE_RANGE2_LIMIT); + WREG32_SOC15(MMHUB, 0, mmPCTL1_STCTRL_REGISTER_SAVE_RANGE2, tmp); +} + +void mmhub_v1_0_initialize_power_gating(struct amdgpu_device *adev) +{ + uint32_t pctl0_misc = 0; + uint32_t pctl0_reng_execute = 0; + uint32_t pctl1_misc = 0; + uint32_t pctl1_reng_execute = 0; + int i = 0; + + if (amdgpu_sriov_vf(adev)) + return; + + pctl0_misc = RREG32_SOC15(MMHUB, 0, mmPCTL0_MISC); + pctl0_reng_execute = RREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE); + pctl1_misc = RREG32_SOC15(MMHUB, 0, mmPCTL1_MISC); + pctl1_reng_execute = RREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE); + + /* Light sleep must be disabled before writing to pctl0 registers */ + pctl0_misc &= ~PCTL0_MISC__RENG_MEM_LS_ENABLE_MASK; + WREG32_SOC15(MMHUB, 0, mmPCTL0_MISC, pctl0_misc); + + /* Write data used to access ram of register engine */ + for (i = 0; i < PCTL0_DATA_LEN; i++) { + WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_RAM_INDEX, + pctl0_data[i].index); + WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_RAM_DATA, + pctl0_data[i].data); + } + + /* Set the reng execute end ptr for pctl0 */ + pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute, + PCTL0_RENG_EXECUTE, + RENG_EXECUTE_END_PTR, + PCTL0_RENG_EXEC_END_PTR); + WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE, pctl0_reng_execute); + + /* Light sleep must be disabled before writing to pctl1 registers */ + pctl1_misc &= ~PCTL1_MISC__RENG_MEM_LS_ENABLE_MASK; + WREG32_SOC15(MMHUB, 0, mmPCTL1_MISC, pctl1_misc); + + /* Write data used to access ram of register engine */ + for (i = 0; i < PCTL1_DATA_LEN; i++) { + WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_RAM_INDEX, + pctl1_data[i].index); + WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_RAM_DATA, + pctl1_data[i].data); + } + + /* Set the reng execute end ptr for pctl1 */ + pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute, + PCTL1_RENG_EXECUTE, + RENG_EXECUTE_END_PTR, + PCTL1_RENG_EXEC_END_PTR); + WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE, pctl1_reng_execute); + + mmhub_v1_0_power_gating_write_save_ranges(adev); + + /* Re-enable light sleep */ + pctl0_misc |= PCTL0_MISC__RENG_MEM_LS_ENABLE_MASK; + WREG32_SOC15(MMHUB, 0, mmPCTL0_MISC, pctl0_misc); + pctl1_misc |= PCTL1_MISC__RENG_MEM_LS_ENABLE_MASK; + WREG32_SOC15(MMHUB, 0, mmPCTL1_MISC, pctl1_misc); +} + +void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t pctl0_reng_execute = 0; + uint32_t pctl1_reng_execute = 0; + + if (amdgpu_sriov_vf(adev)) + return; + + pctl0_reng_execute = RREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE); + pctl1_reng_execute = RREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE); + + if (enable && adev->pg_flags & AMD_PG_SUPPORT_MMHUB) { + pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute, + PCTL0_RENG_EXECUTE, + RENG_EXECUTE_ON_PWR_UP, 1); + pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute, + PCTL0_RENG_EXECUTE, + RENG_EXECUTE_ON_REG_UPDATE, 1); + WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE, pctl0_reng_execute); + + pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute, + PCTL1_RENG_EXECUTE, + RENG_EXECUTE_ON_PWR_UP, 1); + pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute, + PCTL1_RENG_EXECUTE, + RENG_EXECUTE_ON_REG_UPDATE, 1); + WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE, pctl1_reng_execute); + + } else { + pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute, + PCTL0_RENG_EXECUTE, + RENG_EXECUTE_ON_PWR_UP, 0); + pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute, + PCTL0_RENG_EXECUTE, + RENG_EXECUTE_ON_REG_UPDATE, 0); + WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE, pctl0_reng_execute); + + pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute, + PCTL1_RENG_EXECUTE, + RENG_EXECUTE_ON_PWR_UP, 0); + pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute, + PCTL1_RENG_EXECUTE, + RENG_EXECUTE_ON_REG_UPDATE, 0); + WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE, pctl1_reng_execute); + } +} + int mmhub_v1_0_gart_enable(struct amdgpu_device *adev) { if (amdgpu_sriov_vf(adev)) { |