diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4439-drm-amdgpu-don-t-read-registers-if-gfxoff-is-enabled.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4439-drm-amdgpu-don-t-read-registers-if-gfxoff-is-enabled.patch | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4439-drm-amdgpu-don-t-read-registers-if-gfxoff-is-enabled.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4439-drm-amdgpu-don-t-read-registers-if-gfxoff-is-enabled.patch new file mode 100644 index 00000000..1aba1752 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4439-drm-amdgpu-don-t-read-registers-if-gfxoff-is-enabled.patch @@ -0,0 +1,126 @@ +From 3aaf57ff28015d3d07f80b8c1540d75b2d20f288 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Tue, 12 Nov 2019 09:46:54 -0500 +Subject: [PATCH 4439/4736] drm/amdgpu: don't read registers if gfxoff is + enabled (v2) + +When gfxoff is enabled, accessing gfx registers via MMIO +can lead to a hang. + +v2: return cached registers properly. + +Bug: https://bugzilla.kernel.org/show_bug.cgi?id=205497 +Reviewed-by: Evan Quan <evan.quan@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/nv.c | 27 ++++++++++++++++---------- + drivers/gpu/drm/amd/amdgpu/soc15.c | 31 ++++++++++++++++++------------ + 2 files changed, 36 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c +index b33da33214eb..be761785b2a8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/nv.c ++++ b/drivers/gpu/drm/amd/amdgpu/nv.c +@@ -200,17 +200,25 @@ static uint32_t nv_read_indexed_register(struct amdgpu_device *adev, u32 se_num, + return val; + } + +-static uint32_t nv_get_register_value(struct amdgpu_device *adev, ++static int nv_get_register_value(struct amdgpu_device *adev, + bool indexed, u32 se_num, +- u32 sh_num, u32 reg_offset) ++ u32 sh_num, u32 reg_offset, ++ u32 *value) + { + if (indexed) { +- return nv_read_indexed_register(adev, se_num, sh_num, reg_offset); ++ if (adev->pm.pp_feature & PP_GFXOFF_MASK) ++ return -EINVAL; ++ *value = nv_read_indexed_register(adev, se_num, sh_num, reg_offset); + } else { +- if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) +- return adev->gfx.config.gb_addr_config; +- return RREG32(reg_offset); ++ if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) { ++ *value = adev->gfx.config.gb_addr_config; ++ } else { ++ if (adev->pm.pp_feature & PP_GFXOFF_MASK) ++ return -EINVAL; ++ *value = RREG32(reg_offset); ++ } + } ++ return 0; + } + + static int nv_read_register(struct amdgpu_device *adev, u32 se_num, +@@ -226,10 +234,9 @@ static int nv_read_register(struct amdgpu_device *adev, u32 se_num, + (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset)) + continue; + +- *value = nv_get_register_value(adev, +- nv_allowed_read_registers[i].grbm_indexed, +- se_num, sh_num, reg_offset); +- return 0; ++ return nv_get_register_value(adev, ++ nv_allowed_read_registers[i].grbm_indexed, ++ se_num, sh_num, reg_offset, value); + } + return -EINVAL; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c +index e12cdbdd9aed..836a34c10db2 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -362,19 +362,27 @@ static uint32_t soc15_read_indexed_register(struct amdgpu_device *adev, u32 se_n + return val; + } + +-static uint32_t soc15_get_register_value(struct amdgpu_device *adev, ++static int soc15_get_register_value(struct amdgpu_device *adev, + bool indexed, u32 se_num, +- u32 sh_num, u32 reg_offset) ++ u32 sh_num, u32 reg_offset, ++ u32 *value) + { + if (indexed) { +- return soc15_read_indexed_register(adev, se_num, sh_num, reg_offset); ++ if (adev->pm.pp_feature & PP_GFXOFF_MASK) ++ return -EINVAL; ++ *value = soc15_read_indexed_register(adev, se_num, sh_num, reg_offset); + } else { +- if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) +- return adev->gfx.config.gb_addr_config; +- else if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmDB_DEBUG2)) +- return adev->gfx.config.db_debug2; +- return RREG32(reg_offset); ++ if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) { ++ *value = adev->gfx.config.gb_addr_config; ++ } else if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmDB_DEBUG2)) { ++ *value = adev->gfx.config.db_debug2; ++ } else { ++ if (adev->pm.pp_feature & PP_GFXOFF_MASK) ++ return -EINVAL; ++ *value = RREG32(reg_offset); ++ } + } ++ return 0; + } + + static int soc15_read_register(struct amdgpu_device *adev, u32 se_num, +@@ -390,10 +398,9 @@ static int soc15_read_register(struct amdgpu_device *adev, u32 se_num, + + en->reg_offset)) + continue; + +- *value = soc15_get_register_value(adev, +- soc15_allowed_read_registers[i].grbm_indexed, +- se_num, sh_num, reg_offset); +- return 0; ++ return soc15_get_register_value(adev, ++ soc15_allowed_read_registers[i].grbm_indexed, ++ se_num, sh_num, reg_offset, value); + } + return -EINVAL; + } +-- +2.17.1 + |