From: Jerry Zuo <[email protected]> The Apple Studio Display exposes a 2x1 tiled panel over two SST DP links. The primary tile advertises the full 5120x2880 mode (with DSC on the bandwidth-sufficient link) while the secondary carries a per-tile 2560x2880 timing on a link without sufficient bandwidth. Report the non-primary tile connector as disconnected during detect so compositors only see the primary DP link and configure a single 5K mode instead of driving both tiled streams independently.
Drive the behaviour from an EDID quirk: add a disable_second_tile panel patch that apply_edid_quirks() sets for the affected Apple Studio Display panel IDs (0xAE3A, 0xAE42, 0xAE46), and have detect() hide the secondary tile when the sink carries that quirk. Reviewed-by: Mario Limonciello <[email protected]> Reviewed-by: Sun peng Li <[email protected]> Signed-off-by: Jerry Zuo <[email protected]> Signed-off-by: Wayne Lin <[email protected]> --- .../display/amdgpu_dm/amdgpu_dm_connector.c | 36 +++++++++++++++++++ .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 11 ++++++ drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + 3 files changed, 48 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c index da6ec75bb0f9..c30e341c0f37 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c @@ -1605,6 +1605,39 @@ amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force) } EXPORT_IF_KUNIT(amdgpu_dm_connector_poll); +/* + * Apple Studio Display exposes two SST DP links for a 2x1 tiled panel. + * The primary tile advertises the full 5120x2880 mode (with DSC on the + * bandwidth-sufficient link) while the secondary carries a per-tile + * 2560x2880 timing on a insufficient bandwidth link. Hide the secondary + * connector from userspace so compositors configure a single 5K stream + * on the primary link only. + */ +static bool amdgpu_dm_hide_secondary_tile_from_userspace(struct drm_connector *connector) +{ + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); + + if (!aconnector->dc_sink) + return false; + + if (!aconnector->dc_sink->edid_caps.panel_patch.disable_second_tile) + return false; + + drm_edid_connector_update(connector, aconnector->drm_edid); + + if (!connector->has_tile) + return false; + + if (!connector->tile_h_loc && !connector->tile_v_loc) + return false; + + drm_dbg_kms(connector->dev, + "[CONNECTOR:%d:%s] hiding secondary Apple Studio Display tile from userspace\n", + connector->base.id, connector->name); + + return true; +} + /** * amdgpu_dm_connector_detect() - Detect whether a DRM connector is connected to a display * @@ -1648,6 +1681,9 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force) (!aconnector->dc_sink || aconnector->dc_sink->edid_caps.analog)) return amdgpu_dm_connector_poll(aconnector, force); + if (amdgpu_dm_hide_secondary_tile_from_userspace(connector)) + return connector_status_disconnected; + return (aconnector->dc_sink ? connector_status_connected : connector_status_disconnected); } 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 c172bb76bcda..42f5673acb4d 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 @@ -136,6 +136,17 @@ STATIC_IFN_KUNIT void apply_edid_quirks(struct dc_link *link, struct edid *edid, drm_dbg_driver(dev, "Skip PHY SSC reduction on panel id %X\n", panel_id); link->wa_flags.skip_phy_ssc_reduction = true; break; + /* + * Workaround for Apple Studio Display which exposes a 2x1 tiled panel + * over two SST DP links. Hide the secondary tile from userspace so + * compositors drive a single 5K stream on the primary link only. + */ + case drm_edid_encode_panel_id('A', 'P', 'P', 0xAE3A): + case drm_edid_encode_panel_id('A', 'P', 'P', 0xAE42): + case drm_edid_encode_panel_id('A', 'P', 'P', 0xAE46): + drm_dbg_driver(dev, "Hiding secondary tile on panel id %X\n", panel_id); + edid_caps->panel_patch.disable_second_tile = true; + break; default: return; } diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index fccf9cb359f0..3edeb94fba23 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -188,6 +188,7 @@ struct dc_panel_patch { unsigned int skip_audio_sab_check; unsigned int mst_start_top_delay; unsigned int remove_sink_ext_caps; + bool disable_second_tile; unsigned int disable_colorimetry; uint8_t blankstream_before_otg_off; bool oled_optimize_display_on; -- 2.43.0
