From: Eric Huang Date: Fri, 12 Feb 2016 15:58:51 +0000 (-0500) Subject: drm/amd/amdgpu: add medium grain powergating support for Baffin X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=62a86fc2349b7ae318e91a55aa306a120d233a21;p=deliverable%2Flinux.git drm/amd/amdgpu: add medium grain powergating support for Baffin Reviewed-by: Alex Deucher Acked-by: Christian König Signed-off-by: Eric Huang Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 747f357875f4..ce1054d0f391 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -4393,6 +4393,9 @@ static int gfx_v8_0_hw_fini(void *handle) gfx_v8_0_rlc_stop(adev); gfx_v8_0_cp_compute_fini(adev); + amdgpu_set_powergating_state(adev, + AMD_IP_BLOCK_TYPE_GFX, AMD_PG_STATE_UNGATE); + return 0; } @@ -4821,12 +4824,104 @@ static int gfx_v8_0_late_init(void *handle) if (r) return r; + amdgpu_set_powergating_state(adev, + AMD_IP_BLOCK_TYPE_GFX, AMD_PG_STATE_GATE); + return 0; } +static void baffin_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t data, temp; + + /* Send msg to SMU via Powerplay */ + amdgpu_set_powergating_state(adev, + AMD_IP_BLOCK_TYPE_SMC, + enable ? AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE); + + if (enable) { + /* Enable static MGPG */ + temp = data = RREG32(mmRLC_PG_CNTL); + data |= RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; + + if (temp != data) + WREG32(mmRLC_PG_CNTL, data); + } else { + temp = data = RREG32(mmRLC_PG_CNTL); + data &= ~RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; + + if (temp != data) + WREG32(mmRLC_PG_CNTL, data); + } +} + +static void baffin_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t data, temp; + + if (enable) { + /* Enable dynamic MGPG */ + temp = data = RREG32(mmRLC_PG_CNTL); + data |= RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; + + if (temp != data) + WREG32(mmRLC_PG_CNTL, data); + } else { + temp = data = RREG32(mmRLC_PG_CNTL); + data &= ~RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; + + if (temp != data) + WREG32(mmRLC_PG_CNTL, data); + } +} + +static void baffin_enable_gfx_quick_mg_power_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t data, temp; + + if (enable) { + /* Enable quick PG */ + temp = data = RREG32(mmRLC_PG_CNTL); + data |= 0x100000; + + if (temp != data) + WREG32(mmRLC_PG_CNTL, data); + } else { + temp = data = RREG32(mmRLC_PG_CNTL); + data &= ~0x100000; + + if (temp != data) + WREG32(mmRLC_PG_CNTL, data); + } +} + static int gfx_v8_0_set_powergating_state(void *handle, enum amd_powergating_state state) { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (!(adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) + return 0; + + switch (adev->asic_type) { + case CHIP_BAFFIN: + if (adev->pg_flags & AMDGPU_PG_SUPPORT_GFX_SMG) + baffin_enable_gfx_static_mg_power_gating(adev, + state == AMD_PG_STATE_GATE ? true : false); + else if (adev->pg_flags & AMDGPU_PG_SUPPORT_GFX_DMG) + baffin_enable_gfx_dynamic_mg_power_gating(adev, + state == AMD_PG_STATE_GATE ? true : false); + else + baffin_enable_gfx_quick_mg_power_gating(adev, + state == AMD_PG_STATE_GATE ? true : false); + break; + default: + break; + } + return 0; }