[09/15] drm/dp_mst: Add new quirk for Synaptics MST hubs
diff mbox series

Message ID 6b11214d7aaa5bff6ba60846a1569b6f2ac25b0b.1568833906.git.mikita.lipski@amd.com
State New
Headers show
Series
  • DSC MST support for AMDGPU
Related show

Commit Message

Lipski, Mikita Sept. 18, 2019, 8:26 p.m. UTC
From: David Francis <David.Francis@amd.com>

Synaptics DP1.4 hubs (BRANCH_ID 0x90CC24) do not
support virtual DPCD registers, but do support DSC.
The DSC caps can be read from the physical aux,
like in SST DSC. These hubs have many different
DEVICE_IDs.  Add a new quirk to detect this case.

Change-Id: I9d332f273dfca0cfbced111e62f5a06c5c312893
Cc: Lyude Paul <lyude@redhat.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Signed-off-by: David Francis <David.Francis@amd.com>
---
 drivers/gpu/drm/drm_dp_helper.c       |  4 +++-
 drivers/gpu/drm/drm_dp_mst_topology.c | 27 +++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h           |  7 +++++++
 3 files changed, 37 insertions(+), 1 deletion(-)

Comments

Lyude Paul Sept. 19, 2019, 11:44 p.m. UTC | #1
Great work!

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Wed, 2019-09-18 at 16:26 -0400, mikita.lipski@amd.com wrote:
> From: David Francis <David.Francis@amd.com>
> 
> Synaptics DP1.4 hubs (BRANCH_ID 0x90CC24) do not
> support virtual DPCD registers, but do support DSC.
> The DSC caps can be read from the physical aux,
> like in SST DSC. These hubs have many different
> DEVICE_IDs.  Add a new quirk to detect this case.
> 
> Change-Id: I9d332f273dfca0cfbced111e62f5a06c5c312893
> Cc: Lyude Paul <lyude@redhat.com>
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Harry Wentland <harry.wentland@amd.com>
> Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
> Signed-off-by: David Francis <David.Francis@amd.com>
> ---
>  drivers/gpu/drm/drm_dp_helper.c       |  4 +++-
>  drivers/gpu/drm/drm_dp_mst_topology.c | 27 +++++++++++++++++++++++++++
>  include/drm/drm_dp_helper.h           |  7 +++++++
>  3 files changed, 37 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_helper.c
> b/drivers/gpu/drm/drm_dp_helper.c
> index 0cbf10727bd6..c3e1da78e442 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -1288,7 +1288,9 @@ static const struct dpcd_quirk dpcd_quirk_list[] = {
>  	/* LG LP140WF6-SPM1 eDP panel */
>  	{ OUI(0x00, 0x22, 0xb9), DEVICE_ID('s', 'i', 'v', 'a', 'r', 'T'),
> false, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
>  	/* Apple panels need some additional handling to support PSR */
> -	{ OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false,
> BIT(DP_DPCD_QUIRK_NO_PSR) }
> +	{ OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false,
> BIT(DP_DPCD_QUIRK_NO_PSR) },
> +	/* Synaptics DP1.4 MST hubs can support DSC without virtual DPCD */
> +	{ OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true,
> BIT(DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) },
>  };
>  
>  #undef OUI
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index dd2ca065cc92..4e493d8af288 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -4219,6 +4219,7 @@ 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_mst_port *fec_port;
> +	struct drm_dp_desc desc = { 0 };
>  
>  	if (!port)
>  		return NULL;
> @@ -4271,6 +4272,32 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct
> drm_dp_mst_port *port)
>  	if (drm_dp_mst_is_virtual_dpcd(port))
>  		return &port->aux;
>  
> +	/*
> +	 * 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 (!drm_dp_read_desc(port->mgr->aux, &desc, true))
> +		return NULL;
> +
> +	if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) &&
> +	    port->mgr->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14 &&
> +	    port->parent == port->mgr->mst_primary) {
> +		u8 downstreamport;
> +
> +		if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
> +				     &downstreamport, 1) < 0)
> +			return NULL;
> +
> +		if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
> +		   ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
> +		     != DP_DWN_STRM_PORT_TYPE_ANALOG))
> +			return port->mgr->aux;
> +	}
> +
>  	return NULL;
>  }
>  EXPORT_SYMBOL(drm_dp_mst_dsc_aux_for_port);
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 6ae1a6765f63..919ad940bfb1 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1414,6 +1414,13 @@ enum drm_dp_quirk {
>  	 * driver still need to implement proper handling for such device.
>  	 */
>  	DP_DPCD_QUIRK_NO_PSR,
> +	/**
> +	 * @DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD:
> +	 *
> +	 * The device supports MST DSC despite not supporting Virtual DPCD.
> +	 * The DSC caps can be read from the physical aux instead.
> +	 */
> +	DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD,
>  };
>  
>  /**

Patch
diff mbox series

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 0cbf10727bd6..c3e1da78e442 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1288,7 +1288,9 @@  static const struct dpcd_quirk dpcd_quirk_list[] = {
 	/* LG LP140WF6-SPM1 eDP panel */
 	{ OUI(0x00, 0x22, 0xb9), DEVICE_ID('s', 'i', 'v', 'a', 'r', 'T'), false, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
 	/* Apple panels need some additional handling to support PSR */
-	{ OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_NO_PSR) }
+	{ OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_NO_PSR) },
+	/* Synaptics DP1.4 MST hubs can support DSC without virtual DPCD */
+	{ OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) },
 };
 
 #undef OUI
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index dd2ca065cc92..4e493d8af288 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -4219,6 +4219,7 @@  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_mst_port *fec_port;
+	struct drm_dp_desc desc = { 0 };
 
 	if (!port)
 		return NULL;
@@ -4271,6 +4272,32 @@  struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
 	if (drm_dp_mst_is_virtual_dpcd(port))
 		return &port->aux;
 
+	/*
+	 * 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 (!drm_dp_read_desc(port->mgr->aux, &desc, true))
+		return NULL;
+
+	if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) &&
+	    port->mgr->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14 &&
+	    port->parent == port->mgr->mst_primary) {
+		u8 downstreamport;
+
+		if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
+				     &downstreamport, 1) < 0)
+			return NULL;
+
+		if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
+		   ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
+		     != DP_DWN_STRM_PORT_TYPE_ANALOG))
+			return port->mgr->aux;
+	}
+
 	return NULL;
 }
 EXPORT_SYMBOL(drm_dp_mst_dsc_aux_for_port);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 6ae1a6765f63..919ad940bfb1 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1414,6 +1414,13 @@  enum drm_dp_quirk {
 	 * driver still need to implement proper handling for such device.
 	 */
 	DP_DPCD_QUIRK_NO_PSR,
+	/**
+	 * @DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD:
+	 *
+	 * The device supports MST DSC despite not supporting Virtual DPCD.
+	 * The DSC caps can be read from the physical aux instead.
+	 */
+	DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD,
 };
 
 /**