All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mario Kleiner <mario.kleiner.de@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: Jani Nikula <jani.nikula@intel.com>,
	Daniel Vetter <daniel.vetter@ffwll.ch>
Subject: [PATCH 3/5] drm/dp: Add helper to find bpc of a connected DP sink.
Date: Wed,  6 Jul 2016 12:05:46 +0200	[thread overview]
Message-ID: <1467799548-13229-4-git-send-email-mario.kleiner.de@gmail.com> (raw)
In-Reply-To: <1467799548-13229-1-git-send-email-mario.kleiner.de@gmail.com>

drm_dp_sink_bpc() is meant as a fallback to be used by
kms drivers if a DP sink doesn't provide supported color
depth bpc via EDID.

It parses dpcd registers and optionally downstream port
registers read by the driver from DP AUX and passed to
the function to find out what the bpc of the connected
sink likely is.

For a DP sink without downstream ports it assumes it is a
native DP display sink and applies the 6 bpc / 18 bpp
fallback as required by the DP spec.

For a DP sink with downstream ports, e.g., a DP -> legacy
converter it makes the following assignment:

If the converter is DP->DVI or DP->HDMI, it assumes 8 bpc
depth. If the converter is DP->VGA it assumes at least
8 bpc, but tries to get a more accurate value (8, 10, 12
or 16 bpc) if the converter exposes this info.

Tested with MiniDP->DP adapter, MiniDP->HDMI adapter,
MiniDP->single-link DVI adapter, MiniDP->dual-link DVI
active adapter, and a Apple MiniDP->VGA active adapter.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 90 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h     |  6 +++
 2 files changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 091053e..2cf0289 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -160,6 +160,96 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw)
 }
 EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate);
 
+/**
+ * drm_dp_sink_bpc - Parse dpcd to derive bpc of a DP sink.
+ *
+ * @dpcd: dpcd registers, starting at offset 0
+ * @downstream_ports: downstream port info registers, starting at
+ * offset DP_DOWNSTREAM_PORT_0
+ * @index: Index of the downstream port to query
+ *
+ * Derive color depth bpc of the connected DP sink. This is meant as
+ * a fallback for getting the sink bpc if the DP sink doesn't provide
+ * a useable bpc via EDID. It returns 6 bpc for a native DP sink
+ * without any downstream ports, as the spec mandates to assume 6 bpc
+ * if the true bpc of a native DP sink can't be found out from EDID.
+ *
+ * If the sink has multiple downstream ports then @index selects the
+ * downstream port to query, otherwise the first and only one is
+ * queried.
+ *
+ * The function can return 0 to signal that it can't derive bpc from the
+ * given information.
+ */
+int drm_dp_sink_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+		    const u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS],
+		    unsigned int index)
+{
+	uint8_t type;
+	bool detail = false;
+	int bpc = 0;
+
+	/*
+	 * If there isn't any downstream port then this is a native DP sink.
+	 * The standard requires to fall back to 6 bpc / 18 bpp for native DP
+	 * sinks which don't provide bit depth via EDID.
+	 */
+	if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT))
+		return 6;
+
+	/* Basic type of downstream ports? */
+	type = dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK;
+
+	/*
+	 * Lacking other info, 8 bpc is a reasonable start for analog out.
+	 * E.g., Apple MiniDP->VGA adaptors don't provide more info than
+	 * that. Despite having DP_DPCD_REV == 0x11, their downstream_ports
+	 * descriptor is empty - all zeros. DVI and HDMI also support at least
+	 * 8 bpc, so a TMDS port type also implies 8 bpc.
+	 */
+	if (type == DP_DWN_STRM_PORT_TYPE_ANALOG ||
+	    type == DP_DWN_STRM_PORT_TYPE_TMDS)
+		bpc = 8;
+
+	if (dpcd[DP_DPCD_REV] < 0x11)
+		return bpc;
+
+	/* Rev 1.1+. More specific info available per downstream port. */
+
+	/* Detailed info of 4 Bytes per downstream port available? */
+	if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) {
+		index *= 4;
+		detail = true;
+	}
+
+	type = downstream_ports[index] & DP_DS_PORT_TYPE_MASK;
+
+	/* VGA, DVI and HDMI support at least 8 bpc */
+	if (type == DP_DS_PORT_TYPE_VGA || type == DP_DS_PORT_TYPE_DVI ||
+	    type == DP_DS_PORT_TYPE_HDMI)
+		bpc = 8;
+
+	/* As of DP interop v1.1a only VGA defines additional detail */
+	if (detail && (type == DP_DS_PORT_TYPE_VGA)) {
+		/* VGA with detail provides bpc info */
+		switch (downstream_ports[index + 2] &
+			DP_DS_VGA_MAX_BPC_MASK) {
+		    default:
+		    case DP_DS_VGA_8BPC:
+			return 8;
+		    case DP_DS_VGA_10BPC:
+			return 10;
+		    case DP_DS_VGA_12BPC:
+			return 12;
+		    case DP_DS_VGA_16BPC:
+			return 16;
+		}
+	}
+
+	return bpc;
+}
+EXPORT_SYMBOL(drm_dp_sink_bpc);
+
 #define AUX_RETRY_INTERVAL 500 /* us */
 
 /**
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 4d85cf2..0737cd0 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -203,6 +203,8 @@
  * DP interop v1.1a only VGA defines additional detail.
  */
 
+#define DP_MAX_DOWNSTREAM_PORTS		    0x10
+
 /* offset 0 */
 #define DP_DOWNSTREAM_PORT_0		    0x80
 # define DP_DS_PORT_TYPE_MASK		    (7 << 0)
@@ -630,6 +632,10 @@ void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
 u8 drm_dp_link_rate_to_bw_code(int link_rate);
 int drm_dp_bw_code_to_link_rate(u8 link_bw);
 
+int drm_dp_sink_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+		    const u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS],
+		    unsigned int index);
+
 struct edp_sdp_header {
 	u8 HB0; /* Secondary Data Packet ID */
 	u8 HB1; /* Secondary Data Packet Type */
-- 
2.7.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2016-07-06 10:06 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-06 10:05 EDID/DP fixes for proper bpc detection of displays Mario Kleiner
2016-07-06 10:05 ` [PATCH 1/5] drm/edid: Add 6 bpc quirk for display AEO model 0 Mario Kleiner
2016-07-06 10:05   ` Mario Kleiner
2016-07-06 10:05 ` [PATCH 2/5] drm/i915/dp: Revert "drm/i915/dp: fall back to 18 bpp when sink capability is unknown" Mario Kleiner
2016-07-06 10:05   ` Mario Kleiner
2016-07-06 10:05 ` Mario Kleiner [this message]
2016-07-06 10:05 ` [PATCH 4/5] drm/intel/dp: Try harder to get bpc of a DP sink if EDID doesn't tell Mario Kleiner
2016-08-03  3:07   ` Dave Airlie
2016-08-03  6:09     ` Daniel Vetter
2016-08-03 12:03       ` Mario Kleiner
2016-08-07 16:10         ` Mario Kleiner
2016-07-06 10:05 ` [PATCH 5/5] drm/edid: Set 8 bpc color depth for displays with "DFP 1.x compliant TMDS" Mario Kleiner
2016-07-30 15:08 ` Fwd: EDID/DP fixes for proper bpc detection of displays Mario Kleiner
2016-08-02 13:16   ` Daniel Vetter

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=1467799548-13229-4-git-send-email-mario.kleiner.de@gmail.com \
    --to=mario.kleiner.de@gmail.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jani.nikula@intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.