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 */
