[PATCH] drm/amdgpu: Clear the hotplug interrupt ack bit before hpd initialization

Deucher, Alexander Alexander.Deucher at amd.com
Tue Jan 30 19:21:52 UTC 2024


[Public]

> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces at lists.freedesktop.org> On Behalf Of Qiang
> Ma
> Sent: Tuesday, January 30, 2024 4:35 AM
> To: lexander.deucher at amd.com; Koenig, Christian
> <Christian.Koenig at amd.com>; Pan, Xinhui <Xinhui.Pan at amd.com>;
> airlied at gmail.com; daniel at ffwll.ch; sunran001 at 208suo.com;
> SHANMUGAM, SRINIVASAN <SRINIVASAN.SHANMUGAM at amd.com>
> Cc: Qiang Ma <maqianga at uniontech.com>; dri-devel at lists.freedesktop.org;
> amd-gfx at lists.freedesktop.org; linux-kernel at vger.kernel.org
> Subject: [PATCH] drm/amdgpu: Clear the hotplug interrupt ack bit before hpd
> initialization
>
> Problem:
> The computer in the bios initialization process, unplug the HDMI display, wait
> until the system up, plug in the HDMI display, did not enter the hotplug
> interrupt function, the display is not bright.
>
> Fix:
> After the above problem occurs, and the hpd ack interrupt bit is 1, the
> interrupt should be cleared during hpd_init initialization so that when the
> driver is ready, it can respond to the hpd interrupt normally.
>
> Signed-off-by: Qiang Ma <maqianga at uniontech.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/dce_v10_0.c |  2 ++
> drivers/gpu/drm/amd/amdgpu/dce_v11_0.c |  2 ++
> drivers/gpu/drm/amd/amdgpu/dce_v6_0.c  | 20 +++++++++++++++++---
> drivers/gpu/drm/amd/amdgpu/dce_v8_0.c  | 20 +++++++++++++++++---
>  4 files changed, 38 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> index bb666cb7522e..11859059fd10 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
> @@ -51,6 +51,7 @@
>
>  static void dce_v10_0_set_display_funcs(struct amdgpu_device *adev);
> static void dce_v10_0_set_irq_funcs(struct amdgpu_device *adev);
> +static void dce_v10_0_hpd_int_ack(struct amdgpu_device *adev, int hpd);
>
>  static const u32 crtc_offsets[] = {
>       CRTC0_REGISTER_OFFSET,
> @@ -363,6 +364,7 @@ static void dce_v10_0_hpd_init(struct
> amdgpu_device *adev)
>
> AMDGPU_HPD_DISCONNECT_INT_DELAY_IN_MS);
>               WREG32(mmDC_HPD_TOGGLE_FILT_CNTL +
> hpd_offsets[amdgpu_connector->hpd.hpd], tmp);
>
> +             dce_v6_0_hpd_int_ack(adev, amdgpu_connector->hpd.hpd);


Should be dce_v10_0_hpd_int_ack().

>               dce_v10_0_hpd_set_polarity(adev, amdgpu_connector-
> >hpd.hpd);
>               amdgpu_irq_get(adev, &adev->hpd_irq,
>                              amdgpu_connector->hpd.hpd);
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> index 7af277f61cca..745e4fdffade 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
> @@ -51,6 +51,7 @@
>
>  static void dce_v11_0_set_display_funcs(struct amdgpu_device *adev);
> static void dce_v11_0_set_irq_funcs(struct amdgpu_device *adev);
> +static void dce_v11_0_hpd_int_ack(struct amdgpu_device *adev, int hpd);
>
>  static const u32 crtc_offsets[] =
>  {
> @@ -387,6 +388,7 @@ static void dce_v11_0_hpd_init(struct
> amdgpu_device *adev)
>
> AMDGPU_HPD_DISCONNECT_INT_DELAY_IN_MS);
>               WREG32(mmDC_HPD_TOGGLE_FILT_CNTL +
> hpd_offsets[amdgpu_connector->hpd.hpd], tmp);
>
> +             dce_v11_0_hpd_int_ack(adev, amdgpu_connector-
> >hpd.hpd);
>               dce_v11_0_hpd_set_polarity(adev, amdgpu_connector-
> >hpd.hpd);
>               amdgpu_irq_get(adev, &adev->hpd_irq, amdgpu_connector-
> >hpd.hpd);
>       }
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> index 143efc37a17f..f8e15ebf74b4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> @@ -272,6 +272,21 @@ static void dce_v6_0_hpd_set_polarity(struct
> amdgpu_device *adev,
>       WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp);  }
>
> +static void dce_v6_0_hpd_int_ack(struct amdgpu_device *adev,
> +                              int hpd)
> +{
> +     u32 tmp;
> +
> +     if (hpd >= adev->mode_info.num_hpd) {
> +             DRM_DEBUG("invalid hdp %d\n", hpd);
> +             return;
> +     }
> +
> +     tmp = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd]);
> +     tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK;
> +     WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp); }
> +
>  /**
>   * dce_v6_0_hpd_init - hpd setup callback.
>   *
> @@ -311,6 +326,7 @@ static void dce_v6_0_hpd_init(struct amdgpu_device
> *adev)
>                       continue;
>               }
>
> +             dce_v6_0_hpd_int_ack(adev, amdgpu_connector->hpd.hpd);
>               dce_v6_0_hpd_set_polarity(adev, amdgpu_connector-
> >hpd.hpd);
>               amdgpu_irq_get(adev, &adev->hpd_irq, amdgpu_connector-
> >hpd.hpd);
>       }
> @@ -3101,9 +3117,7 @@ static int dce_v6_0_hpd_irq(struct amdgpu_device
> *adev,
>       mask = interrupt_status_offsets[hpd].hpd;
>
>       if (disp_int & mask) {
> -             tmp = RREG32(mmDC_HPD1_INT_CONTROL +
> hpd_offsets[hpd]);
> -             tmp |=
> DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK;
> -             WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd],
> tmp);
> +             dce_v6_0_hpd_int_ack(adev, hpd);
>               schedule_delayed_work(&adev->hotplug_work, 0);
>               DRM_DEBUG("IH: HPD%d\n", hpd + 1);
>       }
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> index adeddfb7ff12..141e33a01686 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
> @@ -264,6 +264,21 @@ static void dce_v8_0_hpd_set_polarity(struct
> amdgpu_device *adev,
>       WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp);  }
>
> +static void dce_v8_0_hpd_int_ack(struct amdgpu_device *adev,
> +                              int hpd)
> +{
> +     u32 tmp;
> +
> +     if (hpd >= adev->mode_info.num_hpd) {
> +             DRM_DEBUG("invalid hdp %d\n", hpd);
> +             return;
> +     }
> +
> +     tmp = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd]);
> +     tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK;
> +     WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp); }
> +
>  /**
>   * dce_v8_0_hpd_init - hpd setup callback.
>   *
> @@ -303,6 +318,7 @@ static void dce_v8_0_hpd_init(struct amdgpu_device
> *adev)
>                       continue;
>               }
>
> +             dce_v6_0_hpd_int_ack(adev, amdgpu_connector->hpd.hpd);

Should be dce_v8_0_hpd_int_ack().


>               dce_v8_0_hpd_set_polarity(adev, amdgpu_connector-
> >hpd.hpd);
>               amdgpu_irq_get(adev, &adev->hpd_irq, amdgpu_connector-
> >hpd.hpd);
>       }
> @@ -3189,9 +3205,7 @@ static int dce_v8_0_hpd_irq(struct amdgpu_device
> *adev,
>       mask = interrupt_status_offsets[hpd].hpd;
>
>       if (disp_int & mask) {
> -             tmp = RREG32(mmDC_HPD1_INT_CONTROL +
> hpd_offsets[hpd]);
> -             tmp |=
> DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK;
> -             WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd],
> tmp);
> +             dce_v6_0_hpd_int_ack(adev, hpd);

Same here.

>               schedule_delayed_work(&adev->hotplug_work, 0);
>               DRM_DEBUG("IH: HPD%d\n", hpd + 1);
>       }
> --
> 2.20.1



More information about the dri-devel mailing list