drm/amdgpu: add sdma clock gating support for Fiji.
authorEric Huang <JinHuiEric.Huang@amd.com>
Wed, 11 Nov 2015 16:49:11 +0000 (11:49 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 21 Dec 2015 21:42:36 +0000 (16:42 -0500)
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com>
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c

index c741c09..ad54c46 100644 (file)
@@ -1429,9 +1429,114 @@ static int sdma_v3_0_process_illegal_inst_irq(struct amdgpu_device *adev,
        return 0;
 }
 
+static void fiji_update_sdma_medium_grain_clock_gating(
+               struct amdgpu_device *adev,
+               bool enable)
+{
+       uint32_t temp, data;
+
+       if (enable) {
+               temp = data = RREG32(mmSDMA0_CLK_CTRL);
+               data &= ~(SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK);
+               if (data != temp)
+                       WREG32(mmSDMA0_CLK_CTRL, data);
+
+               temp = data = RREG32(mmSDMA1_CLK_CTRL);
+               data &= ~(SDMA1_CLK_CTRL__SOFT_OVERRIDE7_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE6_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE5_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE4_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE3_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE2_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE1_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE0_MASK);
+
+               if (data != temp)
+                       WREG32(mmSDMA1_CLK_CTRL, data);
+       } else {
+               temp = data = RREG32(mmSDMA0_CLK_CTRL);
+               data |= SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK |
+                               SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK;
+
+               if (data != temp)
+                       WREG32(mmSDMA0_CLK_CTRL, data);
+
+               temp = data = RREG32(mmSDMA1_CLK_CTRL);
+               data |= SDMA1_CLK_CTRL__SOFT_OVERRIDE7_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE6_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE5_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE4_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE3_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE2_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE1_MASK |
+                               SDMA1_CLK_CTRL__SOFT_OVERRIDE0_MASK;
+
+               if (data != temp)
+                       WREG32(mmSDMA1_CLK_CTRL, data);
+       }
+}
+
+static void fiji_update_sdma_medium_grain_light_sleep(
+               struct amdgpu_device *adev,
+               bool enable)
+{
+       uint32_t temp, data;
+
+       if (enable) {
+               temp = data = RREG32(mmSDMA0_POWER_CNTL);
+               data |= SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
+
+               if (temp != data)
+                       WREG32(mmSDMA0_POWER_CNTL, data);
+
+               temp = data = RREG32(mmSDMA1_POWER_CNTL);
+               data |= SDMA1_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
+
+               if (temp != data)
+                       WREG32(mmSDMA1_POWER_CNTL, data);
+       } else {
+               temp = data = RREG32(mmSDMA0_POWER_CNTL);
+               data &= ~SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
+
+               if (temp != data)
+                       WREG32(mmSDMA0_POWER_CNTL, data);
+
+               temp = data = RREG32(mmSDMA1_POWER_CNTL);
+               data &= ~SDMA1_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
+
+               if (temp != data)
+                       WREG32(mmSDMA1_POWER_CNTL, data);
+       }
+}
+
 static int sdma_v3_0_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       switch (adev->asic_type) {
+       case CHIP_FIJI:
+               fiji_update_sdma_medium_grain_clock_gating(adev,
+                               state == AMD_CG_STATE_GATE ? true : false);
+               fiji_update_sdma_medium_grain_light_sleep(adev,
+                               state == AMD_CG_STATE_GATE ? true : false);
+               break;
+       default:
+               break;
+       }
        return 0;
 }