OSDN Git Service

drm/amdgpu: add basic func for RLC program reg
authorTrigger Huang <Trigger.Huang@amd.com>
Fri, 1 Mar 2019 03:56:20 +0000 (11:56 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 24 May 2019 17:20:51 +0000 (12:20 -0500)
New feature for RLC, some registers can be programmed by
RLC interface under SR-IOV VF:

WREG32_SOC15_RLC_SHADOW:
1, for GRBM_GFX_CNTL, firstly the new register value should be be
programmed to SCRATCH_REG2
1, for GRBM_GFX_INDEX, firstly the new register value should be be
programmed to SCRATCH_REG3

WREG32_RLC:
for registers supported to be programmed by RLC interface, the
following sequence should be used:
1, write the value to SCRATCH_REG0
2, write reg | 0x80000000 to SCRATCH_REG1
3, write 0x1 to RLC_SPARE_INT to notify RLC
4, polling SCRATCH_REG1 to check if finished

Signed-off-by: Trigger Huang <Trigger.Huang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/soc15_common.h

index 49c2625..c634606 100644 (file)
                        (sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT)); \
        } while (0)
 
-#endif
 
+#define WREG32_RLC(reg, value) \
+       do {                                                    \
+               if (amdgpu_virt_support_rlc_prg_reg(adev)) {    \
+                       uint32_t i = 0; \
+                       uint32_t retries = 50000;       \
+                       uint32_t r0 = adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG0;   \
+                       uint32_t r1 = adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG1;   \
+                       uint32_t spare_int = adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + mmRLC_SPARE_INT;  \
+                       WREG32(r0, value);      \
+                       WREG32(r1, (reg | 0x80000000)); \
+                       WREG32(spare_int, 0x1); \
+                       for (i = 0; i < retries; i++) { \
+                               u32 tmp = RREG32(r1);   \
+                               if (!(tmp & 0x80000000))        \
+                                       break;  \
+                               udelay(10);     \
+                       }       \
+                       if (i >= retries)       \
+                               pr_err("timeout: rlcg program reg:0x%05x failed !\n", reg);     \
+               } else {        \
+                       WREG32(reg, value); \
+               }       \
+       } while (0)
+
+#define WREG32_SOC15_RLC_SHADOW(ip, inst, reg, value) \
+       do {                                                    \
+               uint32_t target_reg = adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg;\
+               if (amdgpu_virt_support_rlc_prg_reg(adev)) {    \
+                       uint32_t r2 = adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG2;   \
+                       uint32_t r3 = adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG3;   \
+                       uint32_t grbm_cntl = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + mmGRBM_GFX_CNTL;   \
+                       uint32_t grbm_idx = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + mmGRBM_GFX_INDEX;   \
+                       if (target_reg == grbm_cntl) \
+                               WREG32(r2, value);      \
+                       else if (target_reg == grbm_idx) \
+                               WREG32(r3, value);      \
+                       WREG32(target_reg, value);      \
+               } else {        \
+                       WREG32(target_reg, value); \
+               }       \
+       } while (0)
+
+#define WREG32_SOC15_RLC(ip, inst, reg, value) \
+       do {                                                    \
+                       uint32_t target_reg = adev->reg_offset[GC_HWIP][0][reg##_BASE_IDX] + reg;\
+                       WREG32_RLC(target_reg, value); \
+       } while (0)
+
+#define WREG32_FIELD15_RLC(ip, idx, reg, field, val)   \
+    WREG32_RLC((adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg), \
+    (RREG32(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg) \
+    & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field))
+
+#define WREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset, value) \
+    WREG32_RLC(((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset), value)
 
+#endif