diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-09-07 17:37:28 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-09-07 17:37:28 +0200 |
| commit | 5eccd39d8efa3bc8d557be50f202bbf023837eed (patch) | |
| tree | 6f1589cd863481a7dfdace2b9a692957dc94afbe /drivers/gpu | |
| parent | 8fb649f3a174efaa618928cbe0737bf78b456eed (diff) | |
| parent | 5015d0d945b3d3f2b038d2667880d5762f7d9437 (diff) | |
| download | linux-rolling-stable.tar.gz linux-rolling-stable.zip | |
Merge v7.2.4linux-rolling-stable
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 79 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 28 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/display/dc/dc_types.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_gem.c | 11 |
5 files changed, 121 insertions, 9 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 941c1a312824..9320e49e4428 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7846,6 +7846,39 @@ amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force) return status; } +/* + * 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 * @@ -7889,6 +7922,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); } @@ -9080,6 +9116,47 @@ static void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder, } } +/* + * The Apple Studio Display primary tile advertises both the full 5120x2880 + * mode and the per-tile 2560x2880 timing. As the secondary tile is hidden from + * userspace (see amdgpu_dm_hide_secondary_tile_from_userspace()), drop the + * per-tile timing from the primary connector so compositors only pick the full + * 5K mode. + */ +static void amdgpu_dm_prune_primary_tile_modes(struct drm_connector *connector) +{ + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); + struct drm_display_mode *mode, *t; + + if (!aconnector->dc_sink) + return; + + if (!aconnector->dc_sink->edid_caps.panel_patch.disable_second_tile) + return; + + if (!connector->has_tile) + return; + + /* Only prune the per-tile timing from the primary tile. */ + if (connector->tile_h_loc || connector->tile_v_loc) + return; + + list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { + if (mode->hdisplay != connector->tile_h_size || + mode->vdisplay != connector->tile_v_size) + continue; + + drm_dbg_kms(connector->dev, + "[CONNECTOR:%d:%s] pruning per-tile %dx%d timing from primary Apple Studio Display tile\n", + connector->base.id, connector->name, + mode->hdisplay, mode->vdisplay); + + list_del(&mode->head); + drm_mode_destroy(connector->dev, mode); + aconnector->num_modes--; + } +} + static void amdgpu_set_panel_orientation(struct drm_connector *connector) { struct drm_encoder *encoder; @@ -9122,6 +9199,8 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector, amdgpu_dm_connector->num_modes = drm_edid_connector_add_modes(connector); + amdgpu_dm_prune_primary_tile_modes(connector); + /* sorting the probed modes before calling function * amdgpu_dm_get_native_mode() since EDID can have * more than one preferred mode. The modes that are diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 4c164ae4a4f9..8304e8897a3e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -535,15 +535,27 @@ static bool enable_assr(void *handle, struct dc_link *link) static void update_config(void *handle, struct cp_psp_stream_config *config) { struct hdcp_workqueue *hdcp_work = handle; - struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx; - int link_index = aconnector->dc_link->link_index; - unsigned int conn_index = aconnector->base.index; - struct mod_hdcp_display *display = &hdcp_work[link_index].display; - struct mod_hdcp_link *link = &hdcp_work[link_index].link; - struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; + struct amdgpu_dm_connector *aconnector; + const struct dc *dc; + int link_index; + unsigned int conn_index; + struct mod_hdcp_display *display; + struct mod_hdcp_link *link; + struct hdcp_workqueue *hdcp_w; struct dc_sink *sink = NULL; bool link_is_hdcp14 = false; - const struct dc *dc = aconnector->dc_link->dc; + + aconnector = config->dm_stream_ctx; + if (!aconnector || !aconnector->dc_link) + return; + + link_index = aconnector->dc_link->link_index; + display = &hdcp_work[link_index].display; + link = &hdcp_work[link_index].link; + hdcp_w = &hdcp_work[link_index]; + + conn_index = aconnector->base.index; + dc = aconnector->dc_link->dc; if (config->dpms_off) { hdcp_remove_display(hdcp_work, link_index, aconnector); @@ -581,7 +593,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) link->dp.mst_enabled = config->mst_enabled; link->dp.dp2_enabled = config->dp2_enabled; link->dp.usb4_enabled = config->usb4_enabled; - if (aconnector->dc_sink->sink_signal == SIGNAL_TYPE_HDMI_FRL) + if (sink && sink->sink_signal == SIGNAL_TYPE_HDMI_FRL) link->hdmi.frl_enabled = config->frl_enabled; display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION; link->adjust.auth_delay = 2; 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 6be7f6edd0b2..41aa8f9bb152 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 @@ -134,6 +134,17 @@ static 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 4ed1efa17270..6482e275e63b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -187,6 +187,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; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 20dba02d6175..c5a24dff4b69 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -313,11 +313,20 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, rep->offset = nvbo->offset; if (vmm->vmm.object.oclass >= NVIF_CLASS_VMM_NV50 && !nouveau_cli_uvmm(cli)) { + int ret; + + ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL); + if (ret) + return ret; + vma = nouveau_vma_find(nvbo, vmm); - if (!vma) + if (!vma) { + ttm_bo_unreserve(&nvbo->bo); return -EINVAL; + } rep->offset = vma->addr; + ttm_bo_unreserve(&nvbo->bo); } else rep->offset = 0; |
