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

Reply via email to