drm/amdgpu: add workaround for S3 issues on some vega10 boards
authorKen Wang <Ken.Wang@amd.com>
Tue, 4 Jul 2017 05:11:52 +0000 (13:11 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 14 Jul 2017 15:06:06 +0000 (11:06 -0400)
Certain MC registers need a delay after writing them to properly
update in the init sequence.

Signed-off-by: Ken Wang <Ken.Wang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

index 714235f507f61a126545daf2c59ae914bb761302..bbc7b19d2c1b35a223981db269935644ab057761 100644 (file)
@@ -1687,6 +1687,8 @@ struct amdgpu_device {
        bool has_hw_reset;
        u8                              reset_magic[AMDGPU_RESET_MAGIC_NUM];
 
+       /* record last mm index being written through WREG32*/
+       unsigned long last_mm_index;
 };
 
 static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev)
index 7963c54e5d032806c952c7e4311ab8f0cb034d20..8ce522b490c8fb4a305edd4be162921113f1ee65 100644 (file)
@@ -129,6 +129,10 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
 {
        trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);
 
+       if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
+               adev->last_mm_index = v;
+       }
+
        if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) {
                BUG_ON(in_interrupt());
                return amdgpu_virt_kiq_wreg(adev, reg, v);
@@ -144,6 +148,10 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
                writel(v, ((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
                spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
        }
+
+       if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
+               udelay(500);
+       }
 }
 
 u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
@@ -158,6 +166,9 @@ u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
 
 void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
 {
+       if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
+               adev->last_mm_index = v;
+       }
 
        if ((reg * 4) < adev->rio_mem_size)
                iowrite32(v, adev->rio_mem + (reg * 4));
@@ -165,6 +176,10 @@ void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
                iowrite32((reg * 4), adev->rio_mem + (mmMM_INDEX * 4));
                iowrite32(v, adev->rio_mem + (mmMM_DATA * 4));
        }
+
+       if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
+               udelay(500);
+       }
 }
 
 /**