On Mon, May 5, 2025 at 6:24 PM Sasha Levin <sas...@kernel.org> wrote:
>
> From: Alexandre Demers <alexandre.f.dem...@gmail.com>
>
> [ Upstream commit ab23db6d08efdda5d13d01a66c593d0e57f8917f ]
>
> DCE6 was missing soft reset, but it was easily identifiable under radeon.
> This should be it, pretty much as it is done under DCE8 and DCE10.
>
> Signed-off-by: Alexandre Demers <alexandre.f.dem...@gmail.com>
> Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
> Signed-off-by: Sasha Levin <sas...@kernel.org>

This is not stable material.

Alex

> ---
>  drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 53 ++++++++++++++++++++++++++-
>  1 file changed, 51 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c 
> b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> index 915804a6a1d7d..ed5e06b677df1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> @@ -370,13 +370,41 @@ static u32 dce_v6_0_hpd_get_gpio_reg(struct 
> amdgpu_device *adev)
>         return mmDC_GPIO_HPD_A;
>  }
>
> +static bool dce_v6_0_is_display_hung(struct amdgpu_device *adev)
> +{
> +       u32 crtc_hung = 0;
> +       u32 crtc_status[6];
> +       u32 i, j, tmp;
> +
> +       for (i = 0; i < adev->mode_info.num_crtc; i++) {
> +               if (RREG32(mmCRTC_CONTROL + crtc_offsets[i]) & 
> CRTC_CONTROL__CRTC_MASTER_EN_MASK) {
> +                       crtc_status[i] = RREG32(mmCRTC_STATUS_HV_COUNT + 
> crtc_offsets[i]);
> +                       crtc_hung |= (1 << i);
> +               }
> +       }
> +
> +       for (j = 0; j < 10; j++) {
> +               for (i = 0; i < adev->mode_info.num_crtc; i++) {
> +                       if (crtc_hung & (1 << i)) {
> +                               tmp = RREG32(mmCRTC_STATUS_HV_COUNT + 
> crtc_offsets[i]);
> +                               if (tmp != crtc_status[i])
> +                                       crtc_hung &= ~(1 << i);
> +                       }
> +               }
> +               if (crtc_hung == 0)
> +                       return false;
> +               udelay(100);
> +       }
> +
> +       return true;
> +}
> +
>  static void dce_v6_0_set_vga_render_state(struct amdgpu_device *adev,
>                                           bool render)
>  {
>         if (!render)
>                 WREG32(mmVGA_RENDER_CONTROL,
>                         RREG32(mmVGA_RENDER_CONTROL) & VGA_VSTATUS_CNTL);
> -
>  }
>
>  static int dce_v6_0_get_num_crtc(struct amdgpu_device *adev)
> @@ -2872,7 +2900,28 @@ static bool dce_v6_0_is_idle(void *handle)
>
>  static int dce_v6_0_soft_reset(struct amdgpu_ip_block *ip_block)
>  {
> -       DRM_INFO("xxxx: dce_v6_0_soft_reset --- no impl!!\n");
> +       u32 srbm_soft_reset = 0, tmp;
> +       struct amdgpu_device *adev = ip_block->adev;
> +
> +       if (dce_v6_0_is_display_hung(adev))
> +               srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK;
> +
> +       if (srbm_soft_reset) {
> +               tmp = RREG32(mmSRBM_SOFT_RESET);
> +               tmp |= srbm_soft_reset;
> +               dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
> +               WREG32(mmSRBM_SOFT_RESET, tmp);
> +               tmp = RREG32(mmSRBM_SOFT_RESET);
> +
> +               udelay(50);
> +
> +               tmp &= ~srbm_soft_reset;
> +               WREG32(mmSRBM_SOFT_RESET, tmp);
> +               tmp = RREG32(mmSRBM_SOFT_RESET);
> +
> +               /* Wait a little for things to settle down */
> +               udelay(50);
> +       }
>         return 0;
>  }
>
> --
> 2.39.5
>

Reply via email to