* [PATCH v2 0/2] Refactor MST DSC Determination Policy
@ 2024-11-01 21:24 Fangzhi Zuo
2024-11-01 21:24 ` [PATCH v2 1/2] drm/display/dsc: Refactor DRM " Fangzhi Zuo
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Fangzhi Zuo @ 2024-11-01 21:24 UTC (permalink / raw)
To: dri-devel, amd-gfx, intel-gfx, lyude, jani.nikula, imre.deak,
simona, wayne.lin
Cc: harry.wentland, rodrigo.siqueira, Fangzhi Zuo
The patch series is to refactor existing dsc determination policy for
dsc decompression and dsc passthrough given a mst output port.
Original routine was written based on different peer device types
which is not accurate and shows difficulty when expanding support of
products that do not fully comply with DP specs.
To make the routine more accurate and generic, the series includes below changes:
1. Refactor MST DSC determination policy solely based on
topology connection status and dsc dpcd capability info.
2. Dependency changes required for each vendor due to interface change.
Fangzhi Zuo (2):
drm/display/dsc: Refactor DRM MST DSC Determination Policy
drm/display/dsc: MST DSC Interface Change
.../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 2 +-
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 20 +-
.../display/amdgpu_dm/amdgpu_dm_mst_types.c | 30 +-
drivers/gpu/drm/display/drm_dp_mst_topology.c | 258 ++++++++----------
drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +-
include/drm/display/drm_dp_mst_helper.h | 9 +-
7 files changed, 145 insertions(+), 179 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] drm/display/dsc: Refactor DRM MST DSC Determination Policy
2024-11-01 21:24 [PATCH v2 0/2] Refactor MST DSC Determination Policy Fangzhi Zuo
@ 2024-11-01 21:24 ` Fangzhi Zuo
2024-11-01 21:24 ` [PATCH v2 2/2] drm/display/dsc: MST DSC Interface Change Fangzhi Zuo
2024-11-04 12:17 ` ✗ Fi.CI.BUILD: failure for Refactor MST DSC Determination Policy Patchwork
2 siblings, 0 replies; 4+ messages in thread
From: Fangzhi Zuo @ 2024-11-01 21:24 UTC (permalink / raw)
To: dri-devel, amd-gfx, intel-gfx, lyude, jani.nikula, imre.deak,
simona, wayne.lin
Cc: harry.wentland, rodrigo.siqueira, Fangzhi Zuo
[why]
How we determine the dsc_aux used for dsc decompression in
drm_dp_mst_dsc_aux_for_port() today has defects:
1. The method how we determine a connected peer device is virtual or not
in drm_dp_mst_is_virtual_dpcd() is not always correct. There are DP1.4 products
in the market which don't fully comply with DP spec to enumerate virtual peer device.
That leads to existing logic defects. For example:
- Some 1.4 mst hubs with hdmi output port don't enumerate virtual dpcd/peer device.
When probing the hub, its topology is constructed with a branch device only, with
peer device type set as DP-to-Legacy converter for its HDMI output port.
Under this condition, drm_dp_mst_is_virtual_dpcd() will still determine it's connected
with a virtual peer device with virtual dpcd. And results in the section for
analyzing DP-to-DP peer device case of drm_dp_mst_dsc_aux_for_port(). That's logically
incorrect.
2. Existing routine is designed based on analyzing different connected peer device types, such
as dp-dp, dp-hdmi peer device, and virtual sink. Such categorization is redundant and unnecessary.
The key info of determining where to do dsc decompression relies on the dsc capability from dpcd
only. No matter the mst branch device enumerates virtual dpcd or not, if it's supporting dsc, it
must declare it's dsc capability at somewhere within its responded topology.
Therefore, we would like to refactor the logic how we determine the dsc aux.
[how]
1. dsc_aux should be determined by the topology connection status and dpcd capability info only.
In this way, dsc aux could be determined in a more generic way,
instead of enumerating and analyzing on different connected peer device types.
2. Synaptics quirk DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD analyzing is no longer needed
as long as we determine dsc aux generically by dpcd info.
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/display/drm_dp_mst_topology.c | 238 ++++++++----------
include/drm/display/drm_dp_mst_helper.h | 3 +
2 files changed, 104 insertions(+), 137 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index ac90118b9e7a..a4551c17a07f 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -2258,6 +2258,8 @@ void drm_dp_mst_connector_early_unregister(struct drm_connector *connector,
drm_dbg_kms(port->mgr->dev, "unregistering %s remote bus for %s\n",
port->aux.name, connector->kdev->kobj.name);
drm_dp_aux_unregister_devnode(&port->aux);
+ port->dsc_aux = NULL;
+ port->passthrough_aux = NULL;
}
EXPORT_SYMBOL(drm_dp_mst_connector_early_unregister);
@@ -5994,57 +5996,6 @@ static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_mst_port *port)
i2c_del_adapter(&port->aux.ddc);
}
-/**
- * drm_dp_mst_is_virtual_dpcd() - Is the given port a virtual DP Peer Device
- * @port: The port to check
- *
- * A single physical MST hub object can be represented in the topology
- * by multiple branches, with virtual ports between those branches.
- *
- * As of DP1.4, An MST hub with internal (virtual) ports must expose
- * certain DPCD registers over those ports. See sections 2.6.1.1.1
- * and 2.6.1.1.2 of Display Port specification v1.4 for details.
- *
- * May acquire mgr->lock
- *
- * Returns:
- * true if the port is a virtual DP peer device, false otherwise
- */
-static bool drm_dp_mst_is_virtual_dpcd(struct drm_dp_mst_port *port)
-{
- struct drm_dp_mst_port *downstream_port;
-
- if (!port || port->dpcd_rev < DP_DPCD_REV_14)
- return false;
-
- /* Virtual DP Sink (Internal Display Panel) */
- if (drm_dp_mst_port_is_logical(port))
- return true;
-
- /* DP-to-HDMI Protocol Converter */
- if (port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV &&
- !port->mcs &&
- port->ldps)
- return true;
-
- /* DP-to-DP */
- mutex_lock(&port->mgr->lock);
- if (port->pdt == DP_PEER_DEVICE_MST_BRANCHING &&
- port->mstb &&
- port->mstb->num_ports == 2) {
- list_for_each_entry(downstream_port, &port->mstb->ports, next) {
- if (downstream_port->pdt == DP_PEER_DEVICE_SST_SINK &&
- !downstream_port->input) {
- mutex_unlock(&port->mgr->lock);
- return true;
- }
- }
- }
- mutex_unlock(&port->mgr->lock);
-
- return false;
-}
-
/**
* drm_dp_mst_aux_for_parent() - Get the AUX device for an MST port's parent
* @port: MST port whose parent's AUX device is returned
@@ -6079,115 +6030,128 @@ EXPORT_SYMBOL(drm_dp_mst_aux_for_parent);
*/
struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
{
- struct drm_dp_mst_port *immediate_upstream_port;
- struct drm_dp_aux *immediate_upstream_aux;
- struct drm_dp_mst_port *fec_port;
- struct drm_dp_desc desc = {};
+ struct drm_dp_mst_topology_mgr *mgr = port->mgr;
+ struct drm_dp_mst_port *immediate_upstream_port = NULL;
+ struct drm_dp_mst_port *fec_port = NULL;
+ struct drm_dp_mst_port *dsc_port = NULL;
+ struct drm_dp_aux *upstream_aux;
+ bool end_has_dpcd = (port->dpcd_rev > 0);
+ u8 endpoint_dsc = 0;
u8 upstream_dsc;
- u8 endpoint_fec;
- u8 endpoint_dsc;
+ u8 fec_cap;
if (!port)
return NULL;
+ port->dsc_aux = NULL;
+ port->passthrough_aux = NULL;
+
+ /* Policy start */
+ if (!drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
+ drm_err(mgr->dev,
+ "MST_DSC Can't determine dsc aux for port %p which is not connected to end device\n",
+ port);
+ return NULL;
+ }
+
if (port->parent->port_parent)
immediate_upstream_port = port->parent->port_parent;
- else
- immediate_upstream_port = NULL;
-
- fec_port = immediate_upstream_port;
- while (fec_port) {
- /*
- * Each physical link (i.e. not a virtual port) between the
- * output and the primary device must support FEC
- */
- if (!drm_dp_mst_is_virtual_dpcd(fec_port) &&
- !fec_port->fec_capable)
- return NULL;
- fec_port = fec_port->parent->port_parent;
+ if (end_has_dpcd) {
+ drm_info(mgr->dev, "MST_DSC check port %p for dsc decompression capability\n", port);
+ if (drm_dp_dpcd_read(&port->aux, DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1) {
+ drm_err(mgr->dev, "MST_DSC Can't retrieve dsc caps from endpoint port\n");
+ goto out_dsc_fail;
+ }
}
- /* DP-to-DP peer device */
- if (drm_dp_mst_is_virtual_dpcd(immediate_upstream_port)) {
- if (drm_dp_dpcd_read(&port->aux,
- DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1)
- return NULL;
- if (drm_dp_dpcd_read(&port->aux,
- DP_FEC_CAPABILITY, &endpoint_fec, 1) != 1)
- return NULL;
- if (drm_dp_dpcd_read(&immediate_upstream_port->aux,
- DP_DSC_SUPPORT, &upstream_dsc, 1) != 1)
- return NULL;
-
- /* Enpoint decompression with DP-to-DP peer device */
- if ((endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) &&
- (endpoint_fec & DP_FEC_CAPABLE) &&
- (upstream_dsc & DP_DSC_PASSTHROUGH_IS_SUPPORTED)) {
- port->passthrough_aux = &immediate_upstream_port->aux;
- return &port->aux;
- }
+ if (immediate_upstream_port) {
+ upstream_aux = &immediate_upstream_port->aux;
+ drm_info(mgr->dev, "MST_DSC check immediate_upstream_port %p for dsc passthrough capability\n",
+ immediate_upstream_port);
+ } else {
+ upstream_aux = mgr->aux;
+ drm_info(mgr->dev, "MST_DSC check root aux for dsc passthrough capability\n");
+ }
- /* Virtual DPCD decompression with DP-to-DP peer device */
- return &immediate_upstream_port->aux;
+ if (drm_dp_dpcd_read(upstream_aux, DP_DSC_SUPPORT, &upstream_dsc, 1) != 1) {
+ drm_err(mgr->dev, "MST_DSC Can't retrieve dsc caps from upstream port\n");
+ goto out_dsc_fail;
}
- /* Virtual DPCD decompression with DP-to-HDMI or Virtual DP Sink */
- if (drm_dp_mst_is_virtual_dpcd(port))
- return &port->aux;
+ /* Consider passthrough as the first option for dsc_aux/passthrough_aux */
+ if (endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED &&
+ upstream_dsc & DP_DSC_PASSTHROUGH_IS_SUPPORTED) {
+ dsc_port = port;
+ port->dsc_aux = &port->aux;
+ port->passthrough_aux = upstream_aux;
+ drm_info(mgr->dev, "MST_DSC dsc passthrough to endpoint\n");
+ }
- /*
- * Synaptics quirk
- * Applies to ports for which:
- * - Physical aux has Synaptics OUI
- * - DPv1.4 or higher
- * - Port is on primary branch device
- * - Not a VGA adapter (DP_DWN_STRM_PORT_TYPE_ANALOG)
- */
- if (immediate_upstream_port)
- immediate_upstream_aux = &immediate_upstream_port->aux;
- else
- immediate_upstream_aux = port->mgr->aux;
+ if (!dsc_port) {
+ if (!immediate_upstream_port) {
+ /* Topology with 1 mstb only */
+ if (upstream_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED)
+ port->dsc_aux = mgr->aux;
- if (drm_dp_read_desc(immediate_upstream_aux, &desc, true))
- return NULL;
+ if (!port->dsc_aux) {
+ drm_err(mgr->dev, "MST_DSC dsc decompression not support at root branch\n");
+ goto out_dsc_fail;
+ }
- if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) {
- u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
+ drm_info(mgr->dev, "MST_DSC topology with 1 mstb only, dsc decompression at root branch\n");
+ } else {
+ /* Topology with multiple mstbs */
+ dsc_port = immediate_upstream_port;
+ endpoint_dsc = upstream_dsc;
+
+ if (endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED)
+ port->dsc_aux = &dsc_port->aux;
+ else {
+ drm_err(mgr->dev,
+ "MST_DSC dsc decompression not support at immediate_upstream_port %p\n",
+ dsc_port);
+ goto out_dsc_fail;
+ }
- if (drm_dp_dpcd_read(immediate_upstream_aux,
- DP_DSC_SUPPORT, &upstream_dsc, 1) != 1)
- return NULL;
+ drm_info(mgr->dev, "MST_DSC topology with multiple mstbs, dsc decompression at immediate_upstream_port %p\n",
+ dsc_port);
+ }
+ }
- if (!(upstream_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED))
- return NULL;
+ /* Check the virtual channel from source till dsc port link support FEC */
+ fec_port = dsc_port;
+ while (fec_port) {
+ /*
+ * Each link between the output and the source
+ * must support FEC. Note that virtual dpcd fec is identical
+ * to the fec capability of it's MST BU's DPRx
+ */
+ if (!fec_port->fec_capable) {
+ /* read fec cap one more time in case fec not capable return from enum path result */
+ if ((drm_dp_dpcd_read(&fec_port->aux, DP_FEC_CAPABILITY, &fec_cap, 1) != 1) ||
+ !(fec_cap & DP_FEC_CAPABLE)) {
+ drm_err(mgr->dev, "MST_DSC Failed to retrieve fec caps at port %p\n", fec_port);
+ goto out_dsc_fail;
+ }
+ fec_port->fec_capable = true;
+ }
- if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0)
- return NULL;
+ fec_port = fec_port->parent->port_parent;
+ }
- if (dpcd_ext[DP_DPCD_REV] >= DP_DPCD_REV_14 &&
- ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) &&
- ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK)
- != DP_DWN_STRM_PORT_TYPE_ANALOG)))
- return immediate_upstream_aux;
+ /* Ensure fec between source and the connected DPRx */
+ if ((drm_dp_dpcd_read(mgr->aux, DP_FEC_CAPABILITY, &fec_cap, 1) != 1) ||
+ !(fec_cap & DP_FEC_CAPABLE)) {
+ drm_err(mgr->dev, "MST_DSC fec not supported between source and the connected DPRx\n");
+ goto out_dsc_fail;
}
- /*
- * The check below verifies if the MST sink
- * connected to the GPU is capable of DSC -
- * therefore the endpoint needs to be
- * both DSC and FEC capable.
- */
- if (drm_dp_dpcd_read(&port->aux,
- DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1)
- return NULL;
- if (drm_dp_dpcd_read(&port->aux,
- DP_FEC_CAPABILITY, &endpoint_fec, 1) != 1)
- return NULL;
- if ((endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) &&
- (endpoint_fec & DP_FEC_CAPABLE))
- return &port->aux;
+ return port->dsc_aux;
+out_dsc_fail:
+ port->dsc_aux = NULL;
+ port->passthrough_aux = NULL;
return NULL;
}
EXPORT_SYMBOL(drm_dp_mst_dsc_aux_for_port);
diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
index f6a1cbb0f600..672e8f6b5655 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -80,6 +80,8 @@ struct drm_dp_mst_branch;
* @next: link to next port on this branch device
* @aux: i2c aux transport to talk to device connected to this port, protected
* by &drm_dp_mst_topology_mgr.base.lock.
+ * @dsc_aux: aux to which DSC decompression request should be sent,
+ * only set if DSC decompression is possible.
* @passthrough_aux: parent aux to which DSC pass-through requests should be
* sent, only set if DSC pass-through is possible.
* @parent: branch device parent of this port
@@ -135,6 +137,7 @@ struct drm_dp_mst_port {
*/
struct drm_dp_mst_branch *mstb;
struct drm_dp_aux aux; /* i2c bus for this port? */
+ struct drm_dp_aux *dsc_aux;
struct drm_dp_aux *passthrough_aux;
struct drm_dp_mst_branch *parent;
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] drm/display/dsc: MST DSC Interface Change
2024-11-01 21:24 [PATCH v2 0/2] Refactor MST DSC Determination Policy Fangzhi Zuo
2024-11-01 21:24 ` [PATCH v2 1/2] drm/display/dsc: Refactor DRM " Fangzhi Zuo
@ 2024-11-01 21:24 ` Fangzhi Zuo
2024-11-04 12:17 ` ✗ Fi.CI.BUILD: failure for Refactor MST DSC Determination Policy Patchwork
2 siblings, 0 replies; 4+ messages in thread
From: Fangzhi Zuo @ 2024-11-01 21:24 UTC (permalink / raw)
To: dri-devel, amd-gfx, intel-gfx, lyude, jani.nikula, imre.deak,
simona, wayne.lin
Cc: harry.wentland, rodrigo.siqueira, Fangzhi Zuo
[why]
Starting from dp2 where dsc passthrough is introduced, it is required to identify
the dsc passthrough aux, apart from dsc decompression aux. Existing drm_dp_mst_port function
that returns dsc_aux alone is not sufficient.
[how]
1. Interface change in drm_dp_mst_dsc_aux_for_port, and dependency changes for each vendor.
2. Rename passthrough_aux with dsc_passthrough_aux to align with the name of dsc_aux.
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 2 +-
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 20 +++++------
.../display/amdgpu_dm/amdgpu_dm_mst_types.c | 30 ++++++++--------
drivers/gpu/drm/display/drm_dp_mst_topology.c | 34 +++++++++----------
drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +-
include/drm/display/drm_dp_mst_helper.h | 6 ++--
7 files changed, 48 insertions(+), 49 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index db56b0aa5454..0da703f4ccac 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -1370,7 +1370,7 @@ static int dp_dsc_fec_support_show(struct seq_file *m, void *data)
* enable DSC on the sink device or on MST branch
* its connected to.
*/
- if (aconnector->dsc_aux) {
+ if (aconnector->mst_output_port->dsc_aux) {
is_fec_supported = true;
is_dsc_supported = true;
}
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 069e0195e50a..2e5e490f9027 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
@@ -810,20 +810,20 @@ bool dm_helpers_dp_write_dsc_enable(
uint8_t ret = 0;
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
- if (!aconnector->dsc_aux)
+ if (!aconnector->mst_output_port->dsc_aux)
return false;
// apply w/a to synaptics
if (needs_dsc_aux_workaround(aconnector->dc_link) &&
(aconnector->mst_downstream_port_present.byte & 0x7) != 0x3)
return write_dsc_enable_synaptics_non_virtual_dpcd_mst(
- aconnector->dsc_aux, stream, enable_dsc);
+ aconnector->mst_output_port->dsc_aux, stream, enable_dsc);
port = aconnector->mst_output_port;
if (enable) {
- if (port->passthrough_aux) {
- ret = drm_dp_dpcd_write(port->passthrough_aux,
+ if (port->dsc_passthrough_aux) {
+ ret = drm_dp_dpcd_write(port->dsc_passthrough_aux,
DP_DSC_ENABLE,
&enable_passthrough, 1);
drm_dbg_dp(dev,
@@ -831,24 +831,24 @@ bool dm_helpers_dp_write_dsc_enable(
ret);
}
- ret = drm_dp_dpcd_write(aconnector->dsc_aux,
+ ret = drm_dp_dpcd_write(aconnector->mst_output_port->dsc_aux,
DP_DSC_ENABLE, &enable_dsc, 1);
drm_dbg_dp(dev,
"MST_DSC Sent DSC decoding enable to %s port, ret = %u\n",
- (port->passthrough_aux) ? "remote RX" :
+ (port->dsc_passthrough_aux) ? "remote RX" :
"virtual dpcd",
ret);
} else {
- ret = drm_dp_dpcd_write(aconnector->dsc_aux,
+ ret = drm_dp_dpcd_write(aconnector->mst_output_port->dsc_aux,
DP_DSC_ENABLE, &enable_dsc, 1);
drm_dbg_dp(dev,
"MST_DSC Sent DSC decoding disable to %s port, ret = %u\n",
- (port->passthrough_aux) ? "remote RX" :
+ (port->dsc_passthrough_aux) ? "remote RX" :
"virtual dpcd",
ret);
- if (port->passthrough_aux) {
- ret = drm_dp_dpcd_write(port->passthrough_aux,
+ if (port->dsc_passthrough_aux) {
+ ret = drm_dp_dpcd_write(port->dsc_passthrough_aux,
DP_DSC_ENABLE,
&enable_passthrough, 1);
drm_dbg_dp(dev,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index a08e8a0b696c..5d2653e1a5f6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -183,8 +183,8 @@ amdgpu_dm_mst_connector_early_unregister(struct drm_connector *connector)
dc_sink_release(dc_sink);
aconnector->dc_sink = NULL;
aconnector->edid = NULL;
- aconnector->dsc_aux = NULL;
- port->passthrough_aux = NULL;
+ aconnector->mst_output_port->dsc_aux = NULL;
+ aconnector->mst_output_port->dsc_passthrough_aux = NULL;
}
aconnector->mst_status = MST_STATUS_DEFAULT;
@@ -237,7 +237,7 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
u8 dsc_branch_dec_caps_raw[3] = { 0 }; // DSC branch decoder caps 0xA0 ~ 0xA2
u8 *dsc_branch_dec_caps = NULL;
- aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port);
+ drm_dp_mst_dsc_aux_for_port(port);
/*
* drm_dp_mst_dsc_aux_for_port() will return NULL for certain configs
@@ -250,19 +250,19 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
*/
if (!aconnector->dsc_aux && !port->parent->port_parent &&
needs_dsc_aux_workaround(aconnector->dc_link))
- aconnector->dsc_aux = &aconnector->mst_root->dm_dp_aux.aux;
+ aconnector->mst_output_port->dsc_aux = &aconnector->mst_root->dm_dp_aux.aux;
/* synaptics cascaded MST hub case */
if (is_synaptics_cascaded_panamera(aconnector->dc_link, port))
- aconnector->dsc_aux = port->mgr->aux;
+ aconnector->mst_output_port->dsc_aux = port->mgr->aux;
- if (!aconnector->dsc_aux)
+ if (!aconnector->mst_output_port->dsc_aux)
return false;
- if (drm_dp_dpcd_read(aconnector->dsc_aux, DP_DSC_SUPPORT, dsc_caps, 16) < 0)
+ if (drm_dp_dpcd_read(aconnector->mst_output_port->dsc_aux, DP_DSC_SUPPORT, dsc_caps, 16) < 0)
return false;
- if (drm_dp_dpcd_read(aconnector->dsc_aux,
+ if (drm_dp_dpcd_read(aconnector->mst_output_port->dsc_aux,
DP_DSC_BRANCH_OVERALL_THROUGHPUT_0, dsc_branch_dec_caps_raw, 3) == 3)
dsc_branch_dec_caps = dsc_branch_dec_caps_raw;
@@ -279,10 +279,10 @@ static bool retrieve_downstream_port_device(struct amdgpu_dm_connector *aconnect
{
union dp_downstream_port_present ds_port_present;
- if (!aconnector->dsc_aux)
+ if (!aconnector->mst_output_port->dsc_aux)
return false;
- if (drm_dp_dpcd_read(aconnector->dsc_aux, DP_DOWNSTREAMPORT_PRESENT, &ds_port_present, 1) < 0) {
+ if (drm_dp_dpcd_read(aconnector->mst_output_port->dsc_aux, DP_DOWNSTREAMPORT_PRESENT, &ds_port_present, 1) < 0) {
DRM_INFO("Failed to read downstream_port_present 0x05 from DFP of branch device\n");
return false;
}
@@ -501,8 +501,8 @@ dm_dp_mst_detect(struct drm_connector *connector,
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
aconnector->edid = NULL;
- aconnector->dsc_aux = NULL;
- port->passthrough_aux = NULL;
+ aconnector->mst_output_port->dsc_aux = NULL;
+ aconnector->mst_output_port->dsc_passthrough_aux = NULL;
amdgpu_dm_set_mst_status(&aconnector->mst_status,
MST_REMOTE_EDID | MST_ALLOCATE_NEW_PAYLOAD | MST_CLEAR_ALLOCATED_PAYLOAD,
@@ -1302,7 +1302,7 @@ static bool is_dsc_need_re_compute(
continue;
aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context;
- if (!aconnector || !aconnector->dsc_aux)
+ if (!aconnector || !aconnector->mst_output_port->dsc_aux)
continue;
stream_on_link[new_stream_on_link_num] = aconnector;
@@ -1787,13 +1787,13 @@ enum dc_status dm_dp_mst_is_port_support_mode(
}
/*DSC necessary case*/
- if (!aconnector->dsc_aux)
+ if (!aconnector->mst_output_port->dsc_aux)
return DC_FAIL_BANDWIDTH_VALIDATE;
if (is_dsc_common_config_possible(stream, &bw_range)) {
/*capable of dsc passthough. dsc bitstream along the entire path*/
- if (aconnector->mst_output_port->passthrough_aux) {
+ if (aconnector->mst_output_port->dsc_passthrough_aux) {
if (bw_range.min_kbps > end_to_end_bw_in_kbps) {
DRM_DEBUG_DRIVER("MST_DSC dsc passthrough and decode at endpoint"
"Max dsc compression bw can't fit into end-to-end bw\n");
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index a4551c17a07f..483b623961e7 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -2259,7 +2259,7 @@ void drm_dp_mst_connector_early_unregister(struct drm_connector *connector,
port->aux.name, connector->kdev->kobj.name);
drm_dp_aux_unregister_devnode(&port->aux);
port->dsc_aux = NULL;
- port->passthrough_aux = NULL;
+ port->dsc_passthrough_aux = NULL;
}
EXPORT_SYMBOL(drm_dp_mst_connector_early_unregister);
@@ -5447,7 +5447,8 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm
if (!crtc)
continue;
- if (!drm_dp_mst_dsc_aux_for_port(pos->port))
+ drm_dp_mst_dsc_aux_for_port(pos->port);
+ if (!pos->port->dsc_aux)
continue;
crtc_state = drm_atomic_get_crtc_state(mst_state->base.state, crtc);
@@ -6019,16 +6020,13 @@ EXPORT_SYMBOL(drm_dp_mst_aux_for_parent);
* Depending on the situation, DSC may be enabled via the endpoint aux,
* the immediately upstream aux, or the connector's physical aux.
*
- * This is both the correct aux to read DSC_CAPABILITY and the
- * correct aux to write DSC_ENABLED.
- *
- * This operation can be expensive (up to four aux reads), so
- * the caller should cache the return.
- *
* Returns:
- * NULL if DSC cannot be enabled on this port, otherwise the aux device
+ * port->dsc_aux - point for dsc decompression
+ * null if dsc decompression point not found
+ * port->dsc_passthrough_aux - point for dsc passthrough
+ * null no dsc passthrough support found
*/
-struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
+void drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
{
struct drm_dp_mst_topology_mgr *mgr = port->mgr;
struct drm_dp_mst_port *immediate_upstream_port = NULL;
@@ -6041,17 +6039,17 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
u8 fec_cap;
if (!port)
- return NULL;
+ return;
port->dsc_aux = NULL;
- port->passthrough_aux = NULL;
+ port->dsc_passthrough_aux = NULL;
/* Policy start */
if (!drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
drm_err(mgr->dev,
"MST_DSC Can't determine dsc aux for port %p which is not connected to end device\n",
port);
- return NULL;
+ return;
}
if (port->parent->port_parent)
@@ -6079,12 +6077,12 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
goto out_dsc_fail;
}
- /* Consider passthrough as the first option for dsc_aux/passthrough_aux */
+ /* Consider passthrough as the first option for dsc_aux/dsc_passthrough_aux */
if (endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED &&
upstream_dsc & DP_DSC_PASSTHROUGH_IS_SUPPORTED) {
dsc_port = port;
port->dsc_aux = &port->aux;
- port->passthrough_aux = upstream_aux;
+ port->dsc_passthrough_aux = upstream_aux;
drm_info(mgr->dev, "MST_DSC dsc passthrough to endpoint\n");
}
@@ -6147,11 +6145,11 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
goto out_dsc_fail;
}
- return port->dsc_aux;
+ return;
out_dsc_fail:
port->dsc_aux = NULL;
- port->passthrough_aux = NULL;
- return NULL;
+ port->dsc_passthrough_aux = NULL;
+ return;
}
EXPORT_SYMBOL(drm_dp_mst_dsc_aux_for_port);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 90fa73575feb..4520456a6680 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3228,7 +3228,7 @@ intel_dp_sink_set_dsc_passthrough(const struct intel_connector *connector,
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct drm_dp_aux *aux = connector->port ?
- connector->port->passthrough_aux : NULL;
+ connector->port->dsc_passthrough_aux : NULL;
if (!aux)
return;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 15541932b809..73cb1c673525 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -1699,7 +1699,8 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
intel_dp_init_modeset_retry_work(intel_connector);
- intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port);
+ drm_dp_mst_dsc_aux_for_port(port);
+ intel_connector->dp.dsc_decompression_aux = port->dsc_aux;
intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector);
intel_connector->dp.dsc_hblank_expansion_quirk =
detect_dsc_hblank_expansion_quirk(intel_connector);
diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
index 672e8f6b5655..630ecf872e68 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -82,7 +82,7 @@ struct drm_dp_mst_branch;
* by &drm_dp_mst_topology_mgr.base.lock.
* @dsc_aux: aux to which DSC decompression request should be sent,
* only set if DSC decompression is possible.
- * @passthrough_aux: parent aux to which DSC pass-through requests should be
+ * @dsc_passthrough_aux: parent aux to which DSC pass-through requests should be
* sent, only set if DSC pass-through is possible.
* @parent: branch device parent of this port
* @connector: DRM connector this port is connected to. Protected by
@@ -138,7 +138,7 @@ struct drm_dp_mst_port {
struct drm_dp_mst_branch *mstb;
struct drm_dp_aux aux; /* i2c bus for this port? */
struct drm_dp_aux *dsc_aux;
- struct drm_dp_aux *passthrough_aux;
+ struct drm_dp_aux *dsc_passthrough_aux;
struct drm_dp_mst_branch *parent;
struct drm_connector *connector;
@@ -959,7 +959,7 @@ bool drm_dp_mst_port_is_logical(struct drm_dp_mst_port *port)
}
struct drm_dp_aux *drm_dp_mst_aux_for_parent(struct drm_dp_mst_port *port);
-struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port);
+void drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port);
static inline struct drm_dp_mst_topology_state *
to_drm_dp_mst_topology_state(struct drm_private_state *state)
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* ✗ Fi.CI.BUILD: failure for Refactor MST DSC Determination Policy
2024-11-01 21:24 [PATCH v2 0/2] Refactor MST DSC Determination Policy Fangzhi Zuo
2024-11-01 21:24 ` [PATCH v2 1/2] drm/display/dsc: Refactor DRM " Fangzhi Zuo
2024-11-01 21:24 ` [PATCH v2 2/2] drm/display/dsc: MST DSC Interface Change Fangzhi Zuo
@ 2024-11-04 12:17 ` Patchwork
2 siblings, 0 replies; 4+ messages in thread
From: Patchwork @ 2024-11-04 12:17 UTC (permalink / raw)
To: Fangzhi Zuo; +Cc: intel-gfx
== Series Details ==
Series: Refactor MST DSC Determination Policy
URL : https://patchwork.freedesktop.org/series/140832/
State : failure
== Summary ==
Error: patch https://patchwork.freedesktop.org/api/1.0/series/140832/revisions/1/mbox/ not applied
Applying: drm/display/dsc: Refactor DRM MST DSC Determination Policy
Applying: drm/display/dsc: MST DSC Interface Change
Using index info to reconstruct a base tree...
M drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
M drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
M drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
M drivers/gpu/drm/i915/display/intel_dp.c
M drivers/gpu/drm/i915/display/intel_dp_mst.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/display/intel_dp_mst.c
Auto-merging drivers/gpu/drm/i915/display/intel_dp.c
Auto-merging drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
CONFLICT (content): Merge conflict in drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
Auto-merging drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
Auto-merging drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0002 drm/display/dsc: MST DSC Interface Change
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Build failed, no error log produced
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-11-04 12:17 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-01 21:24 [PATCH v2 0/2] Refactor MST DSC Determination Policy Fangzhi Zuo
2024-11-01 21:24 ` [PATCH v2 1/2] drm/display/dsc: Refactor DRM " Fangzhi Zuo
2024-11-01 21:24 ` [PATCH v2 2/2] drm/display/dsc: MST DSC Interface Change Fangzhi Zuo
2024-11-04 12:17 ` ✗ Fi.CI.BUILD: failure for Refactor MST DSC Determination Policy Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox