From: David Francis <David.Francis-5C7GfCeVMHo@public.gmane.org>
To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Cc: David Francis <David.Francis-5C7GfCeVMHo@public.gmane.org>,
Wenjing Liu <Wenjing.Liu-5C7GfCeVMHo@public.gmane.org>,
Nikola Cornij <Nikola.Cornij-5C7GfCeVMHo@public.gmane.org>
Subject: [PATCH v2 11/14] drm/amd/display: Validate DSC caps on MST endpoints
Date: Tue, 20 Aug 2019 15:12:00 -0400 [thread overview]
Message-ID: <20190820191203.25807-12-David.Francis@amd.com> (raw)
In-Reply-To: <20190820191203.25807-1-David.Francis-5C7GfCeVMHo@public.gmane.org>
The first step in MST DSC is checking MST endpoints
to see how DSC can be enabled
Case 1: DP-to-DP peer device
if the branch immediately upstream has
- PDT = DP_PEER_DEVICE_DP_MST_BRANCHING (2)
- DPCD rev. >= DP 1.4
- Exactly one input and one output
- The output has PDT = DP_PEER_DEVICE_SST_SINK (3)
In this case, DSC could be possible either on the endpoint
or the peer device. Prefer the endpoint, which is possible if
- The endpoint has DP_DSC_DECOMPRESSION_IS_SUPPORTED bit set
- The endpoint has DP_FEC_CAPABLE bit set
- The peer device has DSC_PASSTHROUGH_CAPABILITY bit set (from DP v2.0)
Otherwise, use the peer device
Case 2: DP-to-HDMI peer device
If the output port has
- PDT = DP_PEER_DEVICE_DP_LEGACY_CONV (4)
- DPCD rev. >= DP 1.4
- LDPS = true
- MCS = false
In this case, DSC can only be attempted on the peer device
(the output port)
Case 3: Virtual DP Sink (Internal Display Panel)
If the output port has
- DPCD rev. >= DP 1.4
- port_num >= 8
In this case, DSC can only be attempted on the peer device
(the output port)
Case 4: Synaptix Workaround
If the output has
- link DPCD rev. >= DP 1.4
- link branch_dev_id = 0x90CC24 (Synaptix)
- There is exactly one branch device between the link and output
In this case, DSC can be attempted, but only using the *link*
aux device's caps. This is a quirk.
Test for these cases as modes are enumerated for an MST endpoint.
We cannot do this during link attach because the dc_sink object
will not have been created yet
If no DSC is attempted, zero the DSC caps
Cc: Wenjing Liu <Wenjing.Liu@amd.com>
Cc: Nikola Cornij <Nikola.Cornij@amd.com>
Signed-off-by: David Francis <David.Francis@amd.com>
---
.../display/amdgpu_dm/amdgpu_dm_mst_types.c | 123 +++++++++++++++++-
.../display/amdgpu_dm/amdgpu_dm_mst_types.h | 3 +
2 files changed, 125 insertions(+), 1 deletion(-)
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 16218a202b59..58571844f6d5 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
@@ -25,6 +25,7 @@
#include <linux/version.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_dp_mst_helper.h>
#include "dm_services.h"
#include "amdgpu.h"
#include "amdgpu_dm.h"
@@ -189,6 +190,120 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
.early_unregister = amdgpu_dm_mst_connector_early_unregister,
};
+bool is_virtual_dpcd(struct drm_dp_mst_port *port)
+{
+ struct drm_dp_mst_port *downstream_port;
+
+ if (!port)
+ return false;
+
+ if (port->port_num >= 8 &&
+ port->dpcd_rev >= DP_DPCD_REV_14) {
+ /* Virtual DP Sink (Internal Display Panel) */
+ return true;
+ } else if (port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV &&
+ !port->mcs &&
+ port->ldps &&
+ port->dpcd_rev >= DP_DPCD_REV_14) {
+ /* DP-to-HDMI Protocol Converter */
+ return true;
+ } else if (port->pdt == DP_PEER_DEVICE_MST_BRANCHING &&
+ port->mstb &&
+ port->dpcd_rev >= DP_DPCD_REV_14) {
+ /* DP-to-DP */
+ if (port->mstb->num_ports == 2) {
+ list_for_each_entry(downstream_port, &port->mstb->ports, next) {
+ if (!downstream_port->input &&
+ downstream_port->pdt == DP_PEER_DEVICE_SST_SINK)
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool synaptix_workaround(struct amdgpu_dm_connector *aconnector)
+{
+ struct drm_dp_mst_port *port = aconnector->port;
+ struct dc_link *link = aconnector->dc_sink->link;
+ u8 down_stream_port_data;
+
+ if (port->mgr->mst_primary == port->parent &&
+ link->dpcd_caps.branch_dev_id == 0x90CC24 &&
+ link->dpcd_caps.dpcd_rev.raw >= DP_DPCD_REV_14) {
+ drm_dp_mst_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT, &down_stream_port_data, 1);
+ if ((down_stream_port_data & 7) != 3)
+ return true;
+ }
+ return false;
+}
+
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector)
+{
+ u8 upstream_dsc_caps[16] = { 0 };
+ u8 endpoint_dsc_caps[16] = { 0 };
+ u8 endpoint_fec_caps = 0;
+ struct dc_sink *dc_sink = aconnector->dc_sink;
+ struct drm_dp_mst_port *output_port = aconnector->port;
+ struct drm_dp_mst_port *immediate_upstream_port;
+ struct drm_dp_mst_port *fec_port;
+
+ if (aconnector->port && aconnector->port->parent)
+ immediate_upstream_port = aconnector->port->parent->port_parent;
+ else
+ immediate_upstream_port = NULL;
+
+ fec_port = immediate_upstream_port;
+ while (fec_port) {
+ if (!fec_port->fec_capable)
+ return false;
+
+ fec_port = fec_port->parent->port_parent;
+ }
+
+ if (immediate_upstream_port)
+ drm_dp_mst_dpcd_read(&immediate_upstream_port->aux, DP_DSC_SUPPORT, upstream_dsc_caps, 16);
+ drm_dp_mst_dpcd_read(&output_port->aux, DP_DSC_SUPPORT, endpoint_dsc_caps, 16);
+ drm_dp_mst_dpcd_read(&output_port->aux, DP_FEC_CAPABILITY, &endpoint_fec_caps, 1);
+
+ if (is_virtual_dpcd(immediate_upstream_port)
+ && (upstream_dsc_caps[0] & 0x2) /* DSC passthrough capability */
+ && (endpoint_fec_caps & DP_FEC_CAPABLE)
+ && (endpoint_dsc_caps[0] & DP_DSC_DECOMPRESSION_IS_SUPPORTED)) {
+ /* Enpoint decompression with DP-to-DP peer device */
+ if (!dc_dsc_parse_dsc_dpcd(endpoint_dsc_caps, NULL, &dc_sink->sink_dsc_caps.dsc_dec_caps))
+ return false;
+
+ dc_sink->sink_dsc_caps.is_virtual_dpcd_dsc = false;
+ } else if (is_virtual_dpcd(immediate_upstream_port)) {
+ /* Virtual DPCD decompression with DP-to-DP peer device */
+ if (!dc_dsc_parse_dsc_dpcd(upstream_dsc_caps, NULL, &dc_sink->sink_dsc_caps.dsc_dec_caps))
+ return false;
+
+ dc_sink->sink_dsc_caps.is_virtual_dpcd_dsc = true;
+ } else if (is_virtual_dpcd(output_port)) {
+ /* Virtual DPCD decompression with DP-to-HDMI or Virtual DP Sink */
+ if (!dc_dsc_parse_dsc_dpcd(endpoint_dsc_caps, NULL, &dc_sink->sink_dsc_caps.dsc_dec_caps))
+ return false;
+
+ dc_sink->sink_dsc_caps.is_virtual_dpcd_dsc = true;
+ } else if (synaptix_workaround(aconnector)) {
+ /* Synaptix workaround */
+ aconnector = dc_sink->link->priv;
+ drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, DP_DSC_SUPPORT, upstream_dsc_caps, 16);
+ if (!dc_dsc_parse_dsc_dpcd(upstream_dsc_caps, NULL, &dc_sink->sink_dsc_caps.dsc_dec_caps))
+ return false;
+
+ dc_sink->sink_dsc_caps.is_virtual_dpcd_dsc = true;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+#endif
+
static int dm_dp_mst_get_modes(struct drm_connector *connector)
{
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
@@ -231,10 +346,16 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
/* dc_link_add_remote_sink returns a new reference */
aconnector->dc_sink = dc_sink;
- if (aconnector->dc_sink)
+ if (aconnector->dc_sink) {
amdgpu_dm_update_freesync_caps(
connector, aconnector->edid);
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+ if (!validate_dsc_caps_on_connector(aconnector))
+ memset(&aconnector->dc_sink->sink_dsc_caps,
+ 0, sizeof(aconnector->dc_sink->sink_dsc_caps));
+#endif
+ }
}
drm_connector_update_edid_property(
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
index 2da851b40042..8de3d8c30f8d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
@@ -32,4 +32,7 @@ struct amdgpu_dm_connector;
void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
struct amdgpu_dm_connector *aconnector);
+bool is_virtual_dpcd(struct drm_dp_mst_port *port);
+bool synaptix_workaround(struct amdgpu_dm_connector *aconnector);
+
#endif
--
2.17.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
next prev parent reply other threads:[~2019-08-20 19:12 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-20 19:11 [PATCH v2 00/14] Display Stream Compression (DSC) for AMD Navi David Francis
2019-08-20 19:11 ` [PATCH v2 01/14] Revert "drm/amd/display: skip dsc config for navi10 bring up" David Francis
2019-08-20 19:11 ` [PATCH v2 03/14] Revert "drm/amd/display: add global master update lock for DCN2" David Francis
2019-08-20 19:11 ` [PATCH v2 04/14] Revert "drm/amd/display: Fix underscan not using proper scaling" David Francis
2019-08-20 19:11 ` [PATCH v2 09/14] drm/dp-mst: Export symbols for dpcd read/write David Francis
[not found] ` <20190820191203.25807-10-David.Francis-5C7GfCeVMHo@public.gmane.org>
2019-08-20 21:02 ` Lyude Paul
[not found] ` <773c80494087854b72ffb85938f0ea54bd89c121.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2019-08-20 21:35 ` Li, Sun peng (Leo)
[not found] ` <20190820191203.25807-1-David.Francis-5C7GfCeVMHo@public.gmane.org>
2019-08-20 19:11 ` [PATCH v2 02/14] Revert "drm/amd/display: navi10 bring up skip dsc encoder config" David Francis
2019-08-20 19:11 ` [PATCH v2 05/14] drm/amd/display: Enable SST DSC in DM David Francis
2019-08-20 19:11 ` [PATCH v2 06/14] drm/dp-mst: Use dc and drm helpers to compute timeslots David Francis
[not found] ` <20190820191203.25807-7-David.Francis-5C7GfCeVMHo@public.gmane.org>
2019-08-20 20:43 ` Lyude Paul
[not found] ` <eccdbdb90afa28079a92b9cd959a1cb54ed952b3.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2019-08-21 12:27 ` Kazlauskas, Nicholas
[not found] ` <f63c563e-3aa5-0772-559b-6b34ef612495-5C7GfCeVMHo@public.gmane.org>
2019-08-21 18:57 ` Lyude Paul
2019-08-20 19:11 ` [PATCH v2 07/14] drm/amd/display: Initialize DSC PPS variables to 0 David Francis
2019-08-20 19:11 ` [PATCH v2 08/14] drm/dp-mst: Parse FEC capability on MST ports David Francis
[not found] ` <20190820191203.25807-9-David.Francis-5C7GfCeVMHo@public.gmane.org>
2019-08-20 20:40 ` Lyude Paul
2019-08-20 19:11 ` [PATCH v2 10/14] drm/dp-mst: Fill branch->num_ports David Francis
[not found] ` <20190820191203.25807-11-David.Francis-5C7GfCeVMHo@public.gmane.org>
2019-08-20 21:08 ` Lyude Paul
2019-08-20 19:12 ` David Francis [this message]
[not found] ` <20190820191203.25807-12-David.Francis-5C7GfCeVMHo@public.gmane.org>
2019-08-20 20:34 ` [PATCH v2 11/14] drm/amd/display: Validate DSC caps on MST endpoints Lyude Paul
2019-08-21 18:14 ` Kazlauskas, Nicholas
2019-08-20 19:12 ` [PATCH v2 12/14] drm/amd/display: Write DSC enable to MST DPCD David Francis
2019-08-20 19:12 ` [PATCH v2 13/14] drm/amd/display: MST DSC compute fair share David Francis
2019-08-20 19:12 ` [PATCH v2 14/14] drm/amd/display: Trigger modesets on MST DSC connectors David Francis
[not found] ` <20190820191203.25807-15-David.Francis-5C7GfCeVMHo@public.gmane.org>
2019-08-20 21:09 ` Lyude Paul
[not found] ` <f7272de2841c61f1297f0fce493efe5dd5317dfa.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2019-08-21 12:25 ` Kazlauskas, Nicholas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190820191203.25807-12-David.Francis@amd.com \
--to=david.francis-5c7gfcevmho@public.gmane.org \
--cc=Nikola.Cornij-5C7GfCeVMHo@public.gmane.org \
--cc=Wenjing.Liu-5C7GfCeVMHo@public.gmane.org \
--cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).