[PATCH 1/2] drm/amd/display: Add a temp w/a for a panel
Pillai, Aurabindo
Aurabindo.Pillai at amd.com
Mon Mar 3 22:15:17 UTC 2025
[AMD Official Use Only - AMD Internal Distribution Only]
Thanks Alex, I'll fix that and push.
--
Regards,
Jay
________________________________
From: Hung, Alex <Alex.Hung at amd.com>
Sent: Monday, March 3, 2025 4:48 PM
To: Pillai, Aurabindo <Aurabindo.Pillai at amd.com>; amd-gfx at lists.freedesktop.org <amd-gfx at lists.freedesktop.org>
Cc: Wentland, Harry <Harry.Wentland at amd.com>; Li, Sun peng (Leo) <Sunpeng.Li at amd.com>; Deucher, Alexander <Alexander.Deucher at amd.com>
Subject: Re: [PATCH 1/2] drm/amd/display: Add a temp w/a for a panel
This has conflicts to latest asdn and a minor spacing issue below.
The others look good to me.
Reviewed-by: Alex Hung <alex.hung at amd.com>
On 3/3/25 06:50, Aurabindo Pillai wrote:
> Implement w/a for a panel which requires 10s delay after link detect.
>
> Signed-off-by: Aurabindo Pillai <aurabindo.pillai at amd.com>
> ---
> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 ++++++++++++++++++-
> .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 10 ++++++--
> drivers/gpu/drm/amd/display/dc/dc_types.h | 1 +
> 3 files changed, 32 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 73c95c3c39f9..3a2843e3367e 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3327,6 +3327,21 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
> }
> }
>
> +static void apply_delay_after_dpcd_poweroff(struct amdgpu_device *adev, struct dc_sink *sink) {
> + struct dc_panel_patch *ppatch = NULL;
> +
> + if (!sink)
> + return;
> +
> + ppatch = &sink->edid_caps.panel_patch;
> + if (ppatch->wait_after_dpcd_poweroff_ms) {
> + msleep(ppatch->wait_after_dpcd_poweroff_ms);
> + drm_dbg_driver(adev_to_drm(adev), "%s: adding a %ds delay as w/a for panel\n",
> + __func__,
> + ppatch->wait_after_dpcd_poweroff_ms / 1000);
This doesn't look aligned to me, and maybe the two line can fit into
one. But this is just my opinions.
> + }
> +}
> +
> static int dm_resume(struct amdgpu_ip_block *ip_block)
> {
> struct amdgpu_device *adev = ip_block->adev;
> @@ -3448,6 +3463,7 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
> /* Do detection*/
> drm_connector_list_iter_begin(ddev, &iter);
> drm_for_each_connector_iter(connector, &iter) {
> + bool ret;
>
> if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> continue;
> @@ -3473,7 +3489,11 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
> } else {
> guard(mutex)(&dm->dc_lock);
> dc_exit_ips_for_hw_access(dm->dc);
> - dc_link_detect(aconnector->dc_link, DETECT_REASON_RESUMEFROMS3S4);
> + ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_RESUMEFROMS3S4);
> + if (ret) {
> + /* w/a delay for certain panels */
> + apply_delay_after_dpcd_poweroff(adev, aconnector->dc_sink);
> + }
> }
>
> if (aconnector->fake_enable && aconnector->dc_link->local_sink)
> @@ -3834,6 +3854,8 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector)
> ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
> }
> if (ret) {
> + /* w/a delay for certain panels */
> + apply_delay_after_dpcd_poweroff(adev, aconnector->dc_sink);
> amdgpu_dm_update_connector_after_detect(aconnector);
>
> drm_modeset_lock_all(dev);
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index fbd80d8545a8..253aac93e3d8 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -55,11 +55,16 @@ static u32 edid_extract_panel_id(struct edid *edid)
> (u32)EDID_PRODUCT_ID(edid);
> }
>
> -static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps)
> +static void apply_edid_quirks(struct drm_device *dev, struct edid *edid, struct dc_edid_caps *edid_caps)
> {
> uint32_t panel_id = edid_extract_panel_id(edid);
>
> switch (panel_id) {
> + /* Workaround for monitors that need a delay after detecting the link */
> + case drm_edid_encode_panel_id('G', 'B', 'T', 0x3215):
> + drm_dbg_driver(dev, "Add 10s delay for link detection for panel id %X\n", panel_id);
> + edid_caps->panel_patch.wait_after_dpcd_poweroff_ms = 10000;
> + break;
> /* Workaround for some monitors which does not work well with FAMS */
> case drm_edid_encode_panel_id('S', 'A', 'M', 0x0E5E):
> case drm_edid_encode_panel_id('S', 'A', 'M', 0x7053):
> @@ -101,6 +106,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> {
> struct amdgpu_dm_connector *aconnector = link->priv;
> struct drm_connector *connector = &aconnector->base;
> + struct drm_device *dev = connector->dev;
> struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
> struct cea_sad *sads;
> int sad_count = -1;
> @@ -130,7 +136,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
>
> edid_caps->edid_hdmi = connector->display_info.is_hdmi;
>
> - apply_edid_quirks(edid_buf, edid_caps);
> + apply_edid_quirks(dev, edid_buf, edid_caps);
>
> sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
> if (sad_count <= 0)
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
> index e60898c2df01..acd3b373a18e 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
> @@ -181,6 +181,7 @@ struct dc_panel_patch {
> uint8_t blankstream_before_otg_off;
> bool oled_optimize_display_on;
> unsigned int force_mst_blocked_discovery;
> + unsigned int wait_after_dpcd_poweroff_ms;
> };
>
> struct dc_edid_caps {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/amd-gfx/attachments/20250303/32f0a12b/attachment-0001.htm>
More information about the amd-gfx
mailing list