[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