drm/amdgpu: replace DRM prefix with PCI device info for GFX RAS
[linux-2.6-block.git] / drivers / gpu / drm / amd / amdgpu / gfx_v9_0.c
index 1081fa3d4b0f44ba389442a251b6fa0ded555b86..54c9e255633940baa58c91c11993977cca84c9bf 100644 (file)
 
 #include "gfx_v9_4.h"
 
+#include "asic_reg/pwr/pwr_10_0_offset.h"
+#include "asic_reg/pwr/pwr_10_0_sh_mask.h"
+
 #define GFX9_NUM_GFX_RINGS     1
 #define GFX9_MEC_HPD_SIZE 4096
 #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
 #define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L
 
-#define mmPWR_MISC_CNTL_STATUS                                 0x0183
-#define mmPWR_MISC_CNTL_STATUS_BASE_IDX                                0
-#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT       0x0
-#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT         0x1
-#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK         0x00000001L
-#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK           0x00000006L
-
 #define mmGCEA_PROBE_MAP                        0x070c
 #define mmGCEA_PROBE_MAP_BASE_IDX               0
 
@@ -697,6 +693,11 @@ static const struct soc15_reg_golden golden_settings_gc_9_4_1_arct[] =
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_FIFO_SIZES, 0xffffffff, 0x00000f00),
 };
 
+static const struct soc15_reg_rlcg rlcg_access_gc_9_0[] = {
+       {SOC15_REG_ENTRY(GC, 0, mmGRBM_GFX_INDEX)},
+       {SOC15_REG_ENTRY(GC, 0, mmSQ_IND_INDEX)},
+};
+
 static const u32 GFX_RLC_SRM_INDEX_CNTL_ADDR_OFFSETS[] =
 {
        mmRLC_SRM_INDEX_CNTL_ADDR_0 - mmRLC_SRM_INDEX_CNTL_ADDR_0,
@@ -721,6 +722,59 @@ static const u32 GFX_RLC_SRM_INDEX_CNTL_DATA_OFFSETS[] =
        mmRLC_SRM_INDEX_CNTL_DATA_7 - mmRLC_SRM_INDEX_CNTL_DATA_0,
 };
 
+void gfx_v9_0_rlcg_wreg(struct amdgpu_device *adev, u32 offset, u32 v)
+{
+       static void *scratch_reg0;
+       static void *scratch_reg1;
+       static void *scratch_reg2;
+       static void *scratch_reg3;
+       static void *spare_int;
+       static uint32_t grbm_cntl;
+       static uint32_t grbm_idx;
+
+       scratch_reg0 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG0)*4;
+       scratch_reg1 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG1)*4;
+       scratch_reg2 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG2)*4;
+       scratch_reg3 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG3)*4;
+       spare_int = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + mmRLC_SPARE_INT)*4;
+
+       grbm_cntl = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + mmGRBM_GFX_CNTL;
+       grbm_idx = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + mmGRBM_GFX_INDEX;
+
+       if (amdgpu_sriov_runtime(adev)) {
+               pr_err("shouldn't call rlcg write register during runtime\n");
+               return;
+       }
+
+       if (offset == grbm_cntl || offset == grbm_idx) {
+               if (offset  == grbm_cntl)
+                       writel(v, scratch_reg2);
+               else if (offset == grbm_idx)
+                       writel(v, scratch_reg3);
+
+               writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
+       } else {
+               uint32_t i = 0;
+               uint32_t retries = 50000;
+
+               writel(v, scratch_reg0);
+               writel(offset | 0x80000000, scratch_reg1);
+               writel(1, spare_int);
+               for (i = 0; i < retries; i++) {
+                       u32 tmp;
+
+                       tmp = readl(scratch_reg1);
+                       if (!(tmp & 0x80000000))
+                               break;
+
+                       udelay(10);
+               }
+               if (i >= retries)
+                       pr_err("timeout: rlcg program reg:0x%05x failed !\n", offset);
+       }
+
+}
+
 #define VEGA10_GB_ADDR_CONFIG_GOLDEN 0x2a114042
 #define VEGA12_GB_ADDR_CONFIG_GOLDEN 0x24104041
 #define RAVEN_GB_ADDR_CONFIG_GOLDEN 0x24000042
@@ -1024,7 +1078,8 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
        gpu_addr = adev->wb.gpu_addr + (index * 4);
        adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD);
        memset(&ib, 0, sizeof(ib));
-       r = amdgpu_ib_get(adev, NULL, 16, &ib);
+       r = amdgpu_ib_get(adev, NULL, 16,
+                                       AMDGPU_IB_POOL_DIRECT, &ib);
        if (r)
                goto err1;
 
@@ -1159,6 +1214,8 @@ static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev)
                        adev->gfx.mec_fw_write_wait = true;
                break;
        default:
+               adev->gfx.me_fw_write_wait = true;
+               adev->gfx.mec_fw_write_wait = true;
                break;
        }
 }
@@ -1888,7 +1945,7 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev)
                return r;
        }
 
-       memset(hpd, 0, adev->gfx.mec.hpd_eop_obj->tbo.mem.size);
+       memset(hpd, 0, mec_hpd_size);
 
        amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
        amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
@@ -1921,7 +1978,7 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev)
 
 static uint32_t wave_read_ind(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t address)
 {
-       WREG32_SOC15(GC, 0, mmSQ_IND_INDEX,
+       WREG32_SOC15_RLC(GC, 0, mmSQ_IND_INDEX,
                (wave << SQ_IND_INDEX__WAVE_ID__SHIFT) |
                (simd << SQ_IND_INDEX__SIMD_ID__SHIFT) |
                (address << SQ_IND_INDEX__INDEX__SHIFT) |
@@ -1933,7 +1990,7 @@ static void wave_read_regs(struct amdgpu_device *adev, uint32_t simd,
                           uint32_t wave, uint32_t thread,
                           uint32_t regno, uint32_t num, uint32_t *out)
 {
-       WREG32_SOC15(GC, 0, mmSQ_IND_INDEX,
+       WREG32_SOC15_RLC(GC, 0, mmSQ_IND_INDEX,
                (wave << SQ_IND_INDEX__WAVE_ID__SHIFT) |
                (simd << SQ_IND_INDEX__SIMD_ID__SHIFT) |
                (regno << SQ_IND_INDEX__INDEX__SHIFT) |
@@ -2135,6 +2192,7 @@ static int gfx_v9_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
        int r;
        unsigned irq_type;
        struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id];
+       unsigned int hw_prio;
 
        ring = &adev->gfx.compute_ring[ring_id];
 
@@ -2153,10 +2211,11 @@ static int gfx_v9_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
        irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
                + ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec)
                + ring->pipe;
-
+       hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue) ?
+                       AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_GFX_PIPE_PRIO_NORMAL;
        /* type-2 packets are deprecated on MEC, use type-3 instead */
        r = amdgpu_ring_init(adev, ring, 1024,
-                            &adev->gfx.eop_irq, irq_type);
+                            &adev->gfx.eop_irq, irq_type, hw_prio);
        if (r)
                return r;
 
@@ -2250,7 +2309,9 @@ static int gfx_v9_0_sw_init(void *handle)
                ring->use_doorbell = true;
                ring->doorbell_index = adev->doorbell_index.gfx_ring0 << 1;
                r = amdgpu_ring_init(adev, ring, 1024,
-                                    &adev->gfx.eop_irq, AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP);
+                                    &adev->gfx.eop_irq,
+                                    AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
+                                    AMDGPU_RING_PRIO_DEFAULT);
                if (r)
                        return r;
        }
@@ -3040,16 +3101,11 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev)
 
 static void gfx_v9_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
 {
-       int i;
        u32 tmp = RREG32_SOC15(GC, 0, mmCP_ME_CNTL);
 
        tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_HALT, enable ? 0 : 1);
        tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, enable ? 0 : 1);
        tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, enable ? 0 : 1);
-       if (!enable) {
-               for (i = 0; i < adev->gfx.num_gfx_rings; i++)
-                       adev->gfx.gfx_ring[i].sched.ready = false;
-       }
        WREG32_SOC15_RLC(GC, 0, mmCP_ME_CNTL, tmp);
        udelay(50);
 }
@@ -3245,15 +3301,11 @@ static int gfx_v9_0_cp_gfx_resume(struct amdgpu_device *adev)
 
 static void gfx_v9_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
 {
-       int i;
-
        if (enable) {
                WREG32_SOC15_RLC(GC, 0, mmCP_MEC_CNTL, 0);
        } else {
                WREG32_SOC15_RLC(GC, 0, mmCP_MEC_CNTL,
                        (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK));
-               for (i = 0; i < adev->gfx.num_compute_rings; i++)
-                       adev->gfx.compute_ring[i].sched.ready = false;
                adev->gfx.kiq.ring.sched.ready = false;
        }
        udelay(50);
@@ -3323,11 +3375,8 @@ static void gfx_v9_0_mqd_set_priority(struct amdgpu_ring *ring, struct v9_mqd *m
        if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
                if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue)) {
                        mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
-                       ring->has_high_prio = true;
                        mqd->cp_hqd_queue_priority =
                                AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
-               } else {
-                       ring->has_high_prio = false;
                }
        }
 }
@@ -4128,6 +4177,101 @@ static const u32 sgpr_init_compute_shader[] =
        0xbe800080, 0xbf810000,
 };
 
+static const u32 vgpr_init_compute_shader_arcturus[] = {
+       0xd3d94000, 0x18000080, 0xd3d94001, 0x18000080, 0xd3d94002, 0x18000080,
+       0xd3d94003, 0x18000080, 0xd3d94004, 0x18000080, 0xd3d94005, 0x18000080,
+       0xd3d94006, 0x18000080, 0xd3d94007, 0x18000080, 0xd3d94008, 0x18000080,
+       0xd3d94009, 0x18000080, 0xd3d9400a, 0x18000080, 0xd3d9400b, 0x18000080,
+       0xd3d9400c, 0x18000080, 0xd3d9400d, 0x18000080, 0xd3d9400e, 0x18000080,
+       0xd3d9400f, 0x18000080, 0xd3d94010, 0x18000080, 0xd3d94011, 0x18000080,
+       0xd3d94012, 0x18000080, 0xd3d94013, 0x18000080, 0xd3d94014, 0x18000080,
+       0xd3d94015, 0x18000080, 0xd3d94016, 0x18000080, 0xd3d94017, 0x18000080,
+       0xd3d94018, 0x18000080, 0xd3d94019, 0x18000080, 0xd3d9401a, 0x18000080,
+       0xd3d9401b, 0x18000080, 0xd3d9401c, 0x18000080, 0xd3d9401d, 0x18000080,
+       0xd3d9401e, 0x18000080, 0xd3d9401f, 0x18000080, 0xd3d94020, 0x18000080,
+       0xd3d94021, 0x18000080, 0xd3d94022, 0x18000080, 0xd3d94023, 0x18000080,
+       0xd3d94024, 0x18000080, 0xd3d94025, 0x18000080, 0xd3d94026, 0x18000080,
+       0xd3d94027, 0x18000080, 0xd3d94028, 0x18000080, 0xd3d94029, 0x18000080,
+       0xd3d9402a, 0x18000080, 0xd3d9402b, 0x18000080, 0xd3d9402c, 0x18000080,
+       0xd3d9402d, 0x18000080, 0xd3d9402e, 0x18000080, 0xd3d9402f, 0x18000080,
+       0xd3d94030, 0x18000080, 0xd3d94031, 0x18000080, 0xd3d94032, 0x18000080,
+       0xd3d94033, 0x18000080, 0xd3d94034, 0x18000080, 0xd3d94035, 0x18000080,
+       0xd3d94036, 0x18000080, 0xd3d94037, 0x18000080, 0xd3d94038, 0x18000080,
+       0xd3d94039, 0x18000080, 0xd3d9403a, 0x18000080, 0xd3d9403b, 0x18000080,
+       0xd3d9403c, 0x18000080, 0xd3d9403d, 0x18000080, 0xd3d9403e, 0x18000080,
+       0xd3d9403f, 0x18000080, 0xd3d94040, 0x18000080, 0xd3d94041, 0x18000080,
+       0xd3d94042, 0x18000080, 0xd3d94043, 0x18000080, 0xd3d94044, 0x18000080,
+       0xd3d94045, 0x18000080, 0xd3d94046, 0x18000080, 0xd3d94047, 0x18000080,
+       0xd3d94048, 0x18000080, 0xd3d94049, 0x18000080, 0xd3d9404a, 0x18000080,
+       0xd3d9404b, 0x18000080, 0xd3d9404c, 0x18000080, 0xd3d9404d, 0x18000080,
+       0xd3d9404e, 0x18000080, 0xd3d9404f, 0x18000080, 0xd3d94050, 0x18000080,
+       0xd3d94051, 0x18000080, 0xd3d94052, 0x18000080, 0xd3d94053, 0x18000080,
+       0xd3d94054, 0x18000080, 0xd3d94055, 0x18000080, 0xd3d94056, 0x18000080,
+       0xd3d94057, 0x18000080, 0xd3d94058, 0x18000080, 0xd3d94059, 0x18000080,
+       0xd3d9405a, 0x18000080, 0xd3d9405b, 0x18000080, 0xd3d9405c, 0x18000080,
+       0xd3d9405d, 0x18000080, 0xd3d9405e, 0x18000080, 0xd3d9405f, 0x18000080,
+       0xd3d94060, 0x18000080, 0xd3d94061, 0x18000080, 0xd3d94062, 0x18000080,
+       0xd3d94063, 0x18000080, 0xd3d94064, 0x18000080, 0xd3d94065, 0x18000080,
+       0xd3d94066, 0x18000080, 0xd3d94067, 0x18000080, 0xd3d94068, 0x18000080,
+       0xd3d94069, 0x18000080, 0xd3d9406a, 0x18000080, 0xd3d9406b, 0x18000080,
+       0xd3d9406c, 0x18000080, 0xd3d9406d, 0x18000080, 0xd3d9406e, 0x18000080,
+       0xd3d9406f, 0x18000080, 0xd3d94070, 0x18000080, 0xd3d94071, 0x18000080,
+       0xd3d94072, 0x18000080, 0xd3d94073, 0x18000080, 0xd3d94074, 0x18000080,
+       0xd3d94075, 0x18000080, 0xd3d94076, 0x18000080, 0xd3d94077, 0x18000080,
+       0xd3d94078, 0x18000080, 0xd3d94079, 0x18000080, 0xd3d9407a, 0x18000080,
+       0xd3d9407b, 0x18000080, 0xd3d9407c, 0x18000080, 0xd3d9407d, 0x18000080,
+       0xd3d9407e, 0x18000080, 0xd3d9407f, 0x18000080, 0xd3d94080, 0x18000080,
+       0xd3d94081, 0x18000080, 0xd3d94082, 0x18000080, 0xd3d94083, 0x18000080,
+       0xd3d94084, 0x18000080, 0xd3d94085, 0x18000080, 0xd3d94086, 0x18000080,
+       0xd3d94087, 0x18000080, 0xd3d94088, 0x18000080, 0xd3d94089, 0x18000080,
+       0xd3d9408a, 0x18000080, 0xd3d9408b, 0x18000080, 0xd3d9408c, 0x18000080,
+       0xd3d9408d, 0x18000080, 0xd3d9408e, 0x18000080, 0xd3d9408f, 0x18000080,
+       0xd3d94090, 0x18000080, 0xd3d94091, 0x18000080, 0xd3d94092, 0x18000080,
+       0xd3d94093, 0x18000080, 0xd3d94094, 0x18000080, 0xd3d94095, 0x18000080,
+       0xd3d94096, 0x18000080, 0xd3d94097, 0x18000080, 0xd3d94098, 0x18000080,
+       0xd3d94099, 0x18000080, 0xd3d9409a, 0x18000080, 0xd3d9409b, 0x18000080,
+       0xd3d9409c, 0x18000080, 0xd3d9409d, 0x18000080, 0xd3d9409e, 0x18000080,
+       0xd3d9409f, 0x18000080, 0xd3d940a0, 0x18000080, 0xd3d940a1, 0x18000080,
+       0xd3d940a2, 0x18000080, 0xd3d940a3, 0x18000080, 0xd3d940a4, 0x18000080,
+       0xd3d940a5, 0x18000080, 0xd3d940a6, 0x18000080, 0xd3d940a7, 0x18000080,
+       0xd3d940a8, 0x18000080, 0xd3d940a9, 0x18000080, 0xd3d940aa, 0x18000080,
+       0xd3d940ab, 0x18000080, 0xd3d940ac, 0x18000080, 0xd3d940ad, 0x18000080,
+       0xd3d940ae, 0x18000080, 0xd3d940af, 0x18000080, 0xd3d940b0, 0x18000080,
+       0xd3d940b1, 0x18000080, 0xd3d940b2, 0x18000080, 0xd3d940b3, 0x18000080,
+       0xd3d940b4, 0x18000080, 0xd3d940b5, 0x18000080, 0xd3d940b6, 0x18000080,
+       0xd3d940b7, 0x18000080, 0xd3d940b8, 0x18000080, 0xd3d940b9, 0x18000080,
+       0xd3d940ba, 0x18000080, 0xd3d940bb, 0x18000080, 0xd3d940bc, 0x18000080,
+       0xd3d940bd, 0x18000080, 0xd3d940be, 0x18000080, 0xd3d940bf, 0x18000080,
+       0xd3d940c0, 0x18000080, 0xd3d940c1, 0x18000080, 0xd3d940c2, 0x18000080,
+       0xd3d940c3, 0x18000080, 0xd3d940c4, 0x18000080, 0xd3d940c5, 0x18000080,
+       0xd3d940c6, 0x18000080, 0xd3d940c7, 0x18000080, 0xd3d940c8, 0x18000080,
+       0xd3d940c9, 0x18000080, 0xd3d940ca, 0x18000080, 0xd3d940cb, 0x18000080,
+       0xd3d940cc, 0x18000080, 0xd3d940cd, 0x18000080, 0xd3d940ce, 0x18000080,
+       0xd3d940cf, 0x18000080, 0xd3d940d0, 0x18000080, 0xd3d940d1, 0x18000080,
+       0xd3d940d2, 0x18000080, 0xd3d940d3, 0x18000080, 0xd3d940d4, 0x18000080,
+       0xd3d940d5, 0x18000080, 0xd3d940d6, 0x18000080, 0xd3d940d7, 0x18000080,
+       0xd3d940d8, 0x18000080, 0xd3d940d9, 0x18000080, 0xd3d940da, 0x18000080,
+       0xd3d940db, 0x18000080, 0xd3d940dc, 0x18000080, 0xd3d940dd, 0x18000080,
+       0xd3d940de, 0x18000080, 0xd3d940df, 0x18000080, 0xd3d940e0, 0x18000080,
+       0xd3d940e1, 0x18000080, 0xd3d940e2, 0x18000080, 0xd3d940e3, 0x18000080,
+       0xd3d940e4, 0x18000080, 0xd3d940e5, 0x18000080, 0xd3d940e6, 0x18000080,
+       0xd3d940e7, 0x18000080, 0xd3d940e8, 0x18000080, 0xd3d940e9, 0x18000080,
+       0xd3d940ea, 0x18000080, 0xd3d940eb, 0x18000080, 0xd3d940ec, 0x18000080,
+       0xd3d940ed, 0x18000080, 0xd3d940ee, 0x18000080, 0xd3d940ef, 0x18000080,
+       0xd3d940f0, 0x18000080, 0xd3d940f1, 0x18000080, 0xd3d940f2, 0x18000080,
+       0xd3d940f3, 0x18000080, 0xd3d940f4, 0x18000080, 0xd3d940f5, 0x18000080,
+       0xd3d940f6, 0x18000080, 0xd3d940f7, 0x18000080, 0xd3d940f8, 0x18000080,
+       0xd3d940f9, 0x18000080, 0xd3d940fa, 0x18000080, 0xd3d940fb, 0x18000080,
+       0xd3d940fc, 0x18000080, 0xd3d940fd, 0x18000080, 0xd3d940fe, 0x18000080,
+       0xd3d940ff, 0x18000080, 0xb07c0000, 0xbe8a00ff, 0x000000f8, 0xbf11080a,
+       0x7e000280, 0x7e020280, 0x7e040280, 0x7e060280, 0x7e080280, 0x7e0a0280,
+       0x7e0c0280, 0x7e0e0280, 0x808a880a, 0xbe80320a, 0xbf84fff5, 0xbf9c0000,
+       0xd28c0001, 0x0001007f, 0xd28d0001, 0x0002027e, 0x10020288, 0xb88b0904,
+       0xb78b4000, 0xd1196a01, 0x00001701, 0xbe8a0087, 0xbefc00c1, 0xd89c4000,
+       0x00020201, 0xd89cc080, 0x00040401, 0x320202ff, 0x00000800, 0x808a810a,
+       0xbf84fff8, 0xbf810000,
+};
+
 /* When below register arrays changed, please update gpr_reg_size,
   and sec_ded_counter_reg_size in function gfx_v9_0_do_edc_gpr_workarounds,
   to cover all gfx9 ASICs */
@@ -4148,6 +4292,23 @@ static const struct soc15_reg_entry vgpr_init_regs[] = {
    { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE7), 0xffffffff },
 };
 
+static const struct soc15_reg_entry vgpr_init_regs_arcturus[] = {
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_RESOURCE_LIMITS), 0x0000000 },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_NUM_THREAD_X), 0x40 },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_NUM_THREAD_Y), 4 },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_NUM_THREAD_Z), 1 },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_PGM_RSRC1), 0xbf },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_PGM_RSRC2), 0x400000 },  /* 64KB LDS */
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE0), 0xffffffff },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE1), 0xffffffff },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE2), 0xffffffff },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE3), 0xffffffff },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE4), 0xffffffff },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE5), 0xffffffff },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE6), 0xffffffff },
+   { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE7), 0xffffffff },
+};
+
 static const struct soc15_reg_entry sgpr1_init_regs[] = {
    { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_RESOURCE_LIMITS), 0x0000000 },
    { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_NUM_THREAD_X), 0x40 },
@@ -4278,7 +4439,10 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
                                                adev->gfx.config.max_cu_per_sh *
                                                adev->gfx.config.max_sh_per_se;
        int sgpr_work_group_size = 5;
-       int gpr_reg_size = compute_dim_x / 16 + 6;
+       int gpr_reg_size = adev->gfx.config.max_shader_engines + 6;
+       int vgpr_init_shader_size;
+       const u32 *vgpr_init_shader_ptr;
+       const struct soc15_reg_entry *vgpr_init_regs_ptr;
 
        /* only support when RAS is enabled */
        if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
@@ -4288,6 +4452,16 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
        if (!ring->sched.ready)
                return 0;
 
+       if (adev->asic_type == CHIP_ARCTURUS) {
+               vgpr_init_shader_ptr = vgpr_init_compute_shader_arcturus;
+               vgpr_init_shader_size = sizeof(vgpr_init_compute_shader_arcturus);
+               vgpr_init_regs_ptr = vgpr_init_regs_arcturus;
+       } else {
+               vgpr_init_shader_ptr = vgpr_init_compute_shader;
+               vgpr_init_shader_size = sizeof(vgpr_init_compute_shader);
+               vgpr_init_regs_ptr = vgpr_init_regs;
+       }
+
        total_size =
                (gpr_reg_size * 3 + 4 + 5 + 2) * 4; /* VGPRS */
        total_size +=
@@ -4296,21 +4470,22 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
                (gpr_reg_size * 3 + 4 + 5 + 2) * 4; /* SGPRS2 */
        total_size = ALIGN(total_size, 256);
        vgpr_offset = total_size;
-       total_size += ALIGN(sizeof(vgpr_init_compute_shader), 256);
+       total_size += ALIGN(vgpr_init_shader_size, 256);
        sgpr_offset = total_size;
        total_size += sizeof(sgpr_init_compute_shader);
 
        /* allocate an indirect buffer to put the commands in */
        memset(&ib, 0, sizeof(ib));
-       r = amdgpu_ib_get(adev, NULL, total_size, &ib);
+       r = amdgpu_ib_get(adev, NULL, total_size,
+                                       AMDGPU_IB_POOL_DIRECT, &ib);
        if (r) {
                DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
                return r;
        }
 
        /* load the compute shaders */
-       for (i = 0; i < ARRAY_SIZE(vgpr_init_compute_shader); i++)
-               ib.ptr[i + (vgpr_offset / 4)] = vgpr_init_compute_shader[i];
+       for (i = 0; i < vgpr_init_shader_size/sizeof(u32); i++)
+               ib.ptr[i + (vgpr_offset / 4)] = vgpr_init_shader_ptr[i];
 
        for (i = 0; i < ARRAY_SIZE(sgpr_init_compute_shader); i++)
                ib.ptr[i + (sgpr_offset / 4)] = sgpr_init_compute_shader[i];
@@ -4322,9 +4497,9 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
        /* write the register state for the compute dispatch */
        for (i = 0; i < gpr_reg_size; i++) {
                ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1);
-               ib.ptr[ib.length_dw++] = SOC15_REG_ENTRY_OFFSET(vgpr_init_regs[i])
+               ib.ptr[ib.length_dw++] = SOC15_REG_ENTRY_OFFSET(vgpr_init_regs_ptr[i])
                                                                - PACKET3_SET_SH_REG_START;
-               ib.ptr[ib.length_dw++] = vgpr_init_regs[i].reg_value;
+               ib.ptr[ib.length_dw++] = vgpr_init_regs_ptr[i].reg_value;
        }
        /* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */
        gpu_addr = (ib.gpu_addr + (u64)vgpr_offset) >> 8;
@@ -4336,7 +4511,7 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
 
        /* write dispatch packet */
        ib.ptr[ib.length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3);
-       ib.ptr[ib.length_dw++] = compute_dim_x; /* x */
+       ib.ptr[ib.length_dw++] = compute_dim_x * 2; /* x */
        ib.ptr[ib.length_dw++] = 1; /* y */
        ib.ptr[ib.length_dw++] = 1; /* z */
        ib.ptr[ib.length_dw++] =
@@ -4783,6 +4958,35 @@ static void gfx_v9_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid)
        WREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL, data);
 }
 
+static bool gfx_v9_0_check_rlcg_range(struct amdgpu_device *adev,
+                                       uint32_t offset,
+                                       struct soc15_reg_rlcg *entries, int arr_size)
+{
+       int i;
+       uint32_t reg;
+
+       if (!entries)
+               return false;
+
+       for (i = 0; i < arr_size; i++) {
+               const struct soc15_reg_rlcg *entry;
+
+               entry = &entries[i];
+               reg = adev->reg_offset[entry->hwip][entry->instance][entry->segment] + entry->reg;
+               if (offset == reg)
+                       return true;
+       }
+
+       return false;
+}
+
+static bool gfx_v9_0_is_rlcg_access_range(struct amdgpu_device *adev, u32 offset)
+{
+       return gfx_v9_0_check_rlcg_range(adev, offset,
+                                       (void *)rlcg_access_gc_9_0,
+                                       ARRAY_SIZE(rlcg_access_gc_9_0));
+}
+
 static const struct amdgpu_rlc_funcs gfx_v9_0_rlc_funcs = {
        .is_rlc_enabled = gfx_v9_0_is_rlc_enabled,
        .set_safe_mode = gfx_v9_0_set_safe_mode,
@@ -4795,7 +4999,9 @@ static const struct amdgpu_rlc_funcs gfx_v9_0_rlc_funcs = {
        .stop = gfx_v9_0_rlc_stop,
        .reset = gfx_v9_0_rlc_reset,
        .start = gfx_v9_0_rlc_start,
-       .update_spm_vmid = gfx_v9_0_update_spm_vmid
+       .update_spm_vmid = gfx_v9_0_update_spm_vmid,
+       .rlcg_wreg = gfx_v9_0_rlcg_wreg,
+       .is_rlcg_access_range = gfx_v9_0_is_rlcg_access_range,
 };
 
 static int gfx_v9_0_set_powergating_state(void *handle,
@@ -6190,15 +6396,15 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
 
                sec_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, SEC_COUNT);
                if (sec_count) {
-                       DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
-                                vml2_mems[i], sec_count);
+                       dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+                               "SEC %d\n", i, vml2_mems[i], sec_count);
                        err_data->ce_count += sec_count;
                }
 
                ded_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, DED_COUNT);
                if (ded_count) {
-                       DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
-                                vml2_mems[i], ded_count);
+                       dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+                               "DED %d\n", i, vml2_mems[i], ded_count);
                        err_data->ue_count += ded_count;
                }
        }
@@ -6210,16 +6416,16 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
                sec_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT,
                                                SEC_COUNT);
                if (sec_count) {
-                       DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
-                                vml2_walker_mems[i], sec_count);
+                       dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+                               "SEC %d\n", i, vml2_walker_mems[i], sec_count);
                        err_data->ce_count += sec_count;
                }
 
                ded_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT,
                                                DED_COUNT);
                if (ded_count) {
-                       DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
-                                vml2_walker_mems[i], ded_count);
+                       dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+                               "DED %d\n", i, vml2_walker_mems[i], ded_count);
                        err_data->ue_count += ded_count;
                }
        }
@@ -6230,8 +6436,9 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
 
                sec_count = (data & 0x00006000L) >> 0xd;
                if (sec_count) {
-                       DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
-                                atc_l2_cache_2m_mems[i], sec_count);
+                       dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+                               "SEC %d\n", i, atc_l2_cache_2m_mems[i],
+                               sec_count);
                        err_data->ce_count += sec_count;
                }
        }
@@ -6242,15 +6449,17 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
 
                sec_count = (data & 0x00006000L) >> 0xd;
                if (sec_count) {
-                       DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
-                                atc_l2_cache_4k_mems[i], sec_count);
+                       dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+                               "SEC %d\n", i, atc_l2_cache_4k_mems[i],
+                               sec_count);
                        err_data->ce_count += sec_count;
                }
 
                ded_count = (data & 0x00018000L) >> 0xf;
                if (ded_count) {
-                       DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
-                                atc_l2_cache_4k_mems[i], ded_count);
+                       dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+                               "DED %d\n", i, atc_l2_cache_4k_mems[i],
+                               ded_count);
                        err_data->ue_count += ded_count;
                }
        }
@@ -6263,7 +6472,8 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
        return 0;
 }
 
-static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
+static int gfx_v9_0_ras_error_count(struct amdgpu_device *adev,
+       const struct soc15_reg_entry *reg,
        uint32_t se_id, uint32_t inst_id, uint32_t value,
        uint32_t *sec_count, uint32_t *ded_count)
 {
@@ -6280,7 +6490,8 @@ static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
                                gfx_v9_0_ras_fields[i].sec_count_mask) >>
                                gfx_v9_0_ras_fields[i].sec_count_shift;
                if (sec_cnt) {
-                       DRM_INFO("GFX SubBlock %s, Instance[%d][%d], SEC %d\n",
+                       dev_info(adev->dev, "GFX SubBlock %s, "
+                               "Instance[%d][%d], SEC %d\n",
                                gfx_v9_0_ras_fields[i].name,
                                se_id, inst_id,
                                sec_cnt);
@@ -6291,7 +6502,8 @@ static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
                                gfx_v9_0_ras_fields[i].ded_count_mask) >>
                                gfx_v9_0_ras_fields[i].ded_count_shift;
                if (ded_cnt) {
-                       DRM_INFO("GFX SubBlock %s, Instance[%d][%d], DED %d\n",
+                       dev_info(adev->dev, "GFX SubBlock %s, "
+                               "Instance[%d][%d], DED %d\n",
                                gfx_v9_0_ras_fields[i].name,
                                se_id, inst_id,
                                ded_cnt);
@@ -6306,6 +6518,9 @@ static void gfx_v9_0_reset_ras_error_count(struct amdgpu_device *adev)
 {
        int i, j, k;
 
+       if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
+               return;
+
        /* read back registers to clear the counters */
        mutex_lock(&adev->grbm_idx_mutex);
        for (i = 0; i < ARRAY_SIZE(gfx_v9_0_edc_counter_regs); i++) {
@@ -6377,9 +6592,10 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
                                reg_value =
                                        RREG32(SOC15_REG_ENTRY_OFFSET(gfx_v9_0_edc_counter_regs[i]));
                                if (reg_value)
-                                       gfx_v9_0_ras_error_count(&gfx_v9_0_edc_counter_regs[i],
-                                                       j, k, reg_value,
-                                                       &sec_count, &ded_count);
+                                       gfx_v9_0_ras_error_count(adev,
+                                               &gfx_v9_0_edc_counter_regs[i],
+                                               j, k, reg_value,
+                                               &sec_count, &ded_count);
                        }
                }
        }