We need a special programming sequence for updating
mmUTCL1_CGTT_CLK_CTRL golden settings.

Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 96 +++++++++++++++++++++-----
 1 file changed, 78 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index db28823891ac..24f5e928e7b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -353,32 +353,92 @@ static void gfx_v10_0_set_kiq_pm4_funcs(struct 
amdgpu_device *adev)
        adev->gfx.kiq.pmf = &gfx_v10_0_kiq_pm4_funcs;
 }
 
+/**
+ * gfx_v10_0_program_register_sequence - program an array of registers.
+ *
+ * @adev: amdgpu_device pointer
+ * @regs: pointer to the register array
+ * @array_size: size of the register array
+ *
+ * Programs an array or registers with and and or masks.
+ * This is a helper for setting golden registers.
+ */
+
+static void gfx_v10_0_program_register_sequence(struct amdgpu_device *adev,
+                                               const struct soc15_reg_golden 
*regs,
+                                               const u32 array_size)
+{
+       const struct soc15_reg_golden *entry;
+       u32 tmp, reg, gcrd = 0;
+       int i;
+
+       for (i = 0; i < array_size; ++i) {
+               entry = &regs[i];
+               reg =  
adev->reg_offset[entry->hwip][entry->instance][entry->segment] + entry->reg;
+
+               if (adev->asic_type == CHIP_NAVI10 ||
+                   adev->asic_type == CHIP_NAVI14 ||
+                   adev->asic_type == CHIP_NAVI12) {
+                       /* Navi1x has an aliasing bug between these two 
registers.
+                        * Writes to mmUTCL1_CGTT_CLK_CTRL will change both
+                        * mmUTCL1_CGTT_CLK_CTRL and mmGCRD_SA_TARGETS_DISABLE.
+                        * Reads from mmUTCL1_CGTT_CLK_CTRL will have incorrect 
data
+                        * if mmGCRD_SA_TARGETS_DISABLE is non-0. Reads and 
writes
+                        * from/to mmGCRD_SA_TARGETS_DISABLE will be correct.
+                        */
+                       if (reg == SOC15_REG_OFFSET(GC, 0, 
mmUTCL1_CGTT_CLK_CTRL)) {
+                               gcrd = RREG32_SOC15(GC, 0, 
mmGCRD_SA_TARGETS_DISABLE);
+                               WREG32_SOC15(GC, 0, mmGCRD_SA_TARGETS_DISABLE, 
0);
+                       }
+               }
+
+               if (entry->and_mask == 0xffffffff) {
+                       tmp = entry->or_mask;
+               } else {
+                       tmp = RREG32(reg);
+                       tmp &= ~(entry->and_mask);
+                       tmp |= (entry->or_mask & entry->and_mask);
+               }
+
+               WREG32(reg, tmp);
+
+               if (adev->asic_type == CHIP_NAVI10 ||
+                   adev->asic_type == CHIP_NAVI14 ||
+                   adev->asic_type == CHIP_NAVI12) {
+                       if (reg == SOC15_REG_OFFSET(GC, 0, 
mmUTCL1_CGTT_CLK_CTRL)) {
+                               WREG32_SOC15(GC, 0, mmGCRD_SA_TARGETS_DISABLE, 
gcrd);
+                       }
+               }
+       }
+
+}
+
 static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev)
 {
        switch (adev->asic_type) {
        case CHIP_NAVI10:
-               soc15_program_register_sequence(adev,
-                                               golden_settings_gc_10_1,
-                                               (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1));
-               soc15_program_register_sequence(adev,
-                                               golden_settings_gc_10_0_nv10,
-                                               (const 
u32)ARRAY_SIZE(golden_settings_gc_10_0_nv10));
+               gfx_v10_0_program_register_sequence(adev,
+                                                   golden_settings_gc_10_1,
+                                                   (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1));
+               gfx_v10_0_program_register_sequence(adev,
+                                                   
golden_settings_gc_10_0_nv10,
+                                                   (const 
u32)ARRAY_SIZE(golden_settings_gc_10_0_nv10));
                break;
        case CHIP_NAVI14:
-               soc15_program_register_sequence(adev,
-                                               golden_settings_gc_10_1_1,
-                                               (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1_1));
-               soc15_program_register_sequence(adev,
-                                               golden_settings_gc_10_1_nv14,
-                                               (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1_nv14));
+               gfx_v10_0_program_register_sequence(adev,
+                                                   golden_settings_gc_10_1_1,
+                                                   (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1_1));
+               gfx_v10_0_program_register_sequence(adev,
+                                                   
golden_settings_gc_10_1_nv14,
+                                                   (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1_nv14));
                break;
        case CHIP_NAVI12:
-               soc15_program_register_sequence(adev,
-                                               golden_settings_gc_10_1_2,
-                                               (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1_2));
-               soc15_program_register_sequence(adev,
-                                               golden_settings_gc_10_1_2_nv12,
-                                               (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1_2_nv12));
+               gfx_v10_0_program_register_sequence(adev,
+                                                   golden_settings_gc_10_1_2,
+                                                   (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1_2));
+               gfx_v10_0_program_register_sequence(adev,
+                                                   
golden_settings_gc_10_1_2_nv12,
+                                                   (const 
u32)ARRAY_SIZE(golden_settings_gc_10_1_2_nv12));
                break;
        default:
                break;
-- 
2.20.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to