drm/amdgpu: add mmhub pg init sequence on raven
authorHawking Zhang <Hawking.Zhang@amd.com>
Mon, 19 Jun 2017 06:19:07 +0000 (14:19 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 29 Jun 2017 16:43:45 +0000 (12:43 -0400)
MMHub Powergating init sequence.

Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h

index 68172aace3ee7aa215c09438a832ab43b759e1df..3392bd48c6e461caba1289d2fa0e77a2432d7d6c 100644 (file)
@@ -695,6 +695,14 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
        else
                nbio_v6_1_hdp_flush(adev);
 
+       switch (adev->asic_type) {
+       case CHIP_RAVEN:
+               mmhub_v1_0_initialize_power_gating(adev);
+               break;
+       default:
+               break;
+       }
+
        r = gfxhub_v1_0_gart_enable(adev);
        if (r)
                return r;
index f50b5a77f45ae689e34bf170e68aeb802754c7dc..8447ce74304faf61c17782bfa10a63c3a736ac65 100644 (file)
@@ -244,6 +244,176 @@ 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);
+}
+
 int mmhub_v1_0_gart_enable(struct amdgpu_device *adev)
 {
        if (amdgpu_sriov_vf(adev)) {
index bbfacbcdc4a28a12fd60fd568d6ce6e48c697b27..025b88b9de810f0820507cf97f652a20616b66d7 100644 (file)
@@ -32,6 +32,7 @@ void mmhub_v1_0_init(struct amdgpu_device *adev);
 int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev,
                               enum amd_clockgating_state state);
 void mmhub_v1_0_get_clockgating(struct amdgpu_device *adev, u32 *flags);
+void mmhub_v1_0_initialize_power_gating(struct amdgpu_device *adev);
 
 extern const struct amd_ip_funcs mmhub_v1_0_ip_funcs;
 extern const struct amdgpu_ip_block_version mmhub_v1_0_ip_block;