]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/dp: Add helpers for DFP YCbCr 4:2:0 handling
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 4 Sep 2020 11:53:53 +0000 (14:53 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 17 Sep 2020 15:39:01 +0000 (18:39 +0300)
Add helpers to determine whether the DFP supports
YCbCr 4:2:0 passthrough or YCbCr 4:4:4->4:2:0 conversion.

v2: Add kdocs (Lyude)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200904115354.25336-18-ville.syrjala@linux.intel.com
Reviewed-by: Lyude Paul <lyude@redhat.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/drm_dp_helper.c
include/drm/drm_dp_helper.h

index 63ac94c54e9590dbdcb35c9061675db2984d02f5..90807a6b415ca8598e83f72dd0a589c0d3cbc0b6 100644 (file)
@@ -808,6 +808,66 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 }
 EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
 
+/**
+ * drm_dp_downstream_420_passthrough() - determine downstream facing port
+ *                                       YCbCr 4:2:0 pass-through capability
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: downstream facing port capabilities
+ *
+ * Returns: whether the downstream facing port can pass through YCbCr 4:2:0
+ */
+bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+                                      const u8 port_cap[4])
+{
+       if (!drm_dp_is_branch(dpcd))
+               return false;
+
+       if (dpcd[DP_DPCD_REV] < 0x13)
+               return false;
+
+       switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+       case DP_DS_PORT_TYPE_DP:
+               return true;
+       case DP_DS_PORT_TYPE_HDMI:
+               if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+                       return false;
+
+               return port_cap[3] & DP_DS_HDMI_YCBCR420_PASS_THROUGH;
+       default:
+               return false;
+       }
+}
+EXPORT_SYMBOL(drm_dp_downstream_420_passthrough);
+
+/**
+ * drm_dp_downstream_444_to_420_conversion() - determine downstream facing port
+ *                                             YCbCr 4:4:4->4:2:0 conversion capability
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: downstream facing port capabilities
+ *
+ * Returns: whether the downstream facing port can convert YCbCr 4:4:4 to 4:2:0
+ */
+bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+                                            const u8 port_cap[4])
+{
+       if (!drm_dp_is_branch(dpcd))
+               return false;
+
+       if (dpcd[DP_DPCD_REV] < 0x13)
+               return false;
+
+       switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+       case DP_DS_PORT_TYPE_HDMI:
+               if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+                       return false;
+
+               return port_cap[3] & DP_DS_HDMI_YCBCR444_TO_420_CONV;
+       default:
+               return false;
+       }
+}
+EXPORT_SYMBOL(drm_dp_downstream_444_to_420_conversion);
+
 /**
  * drm_dp_downstream_mode() - return a mode for downstream facing port
  * @dpcd: DisplayPort configuration data
index fbba4a0f73665e4b57e11a4a82ae138ea2f66bd0..c9f2851904d0ad5bfa2dcdb22b119f11f5a0efc4 100644 (file)
@@ -407,6 +407,10 @@ struct drm_device;
 # define DP_DS_DVI_HIGH_COLOR_DEPTH        (1 << 2)
 /* offset 3 for HDMI */
 # define DP_DS_HDMI_FRAME_SEQ_TO_FRAME_PACK (1 << 0)
+# define DP_DS_HDMI_YCBCR422_PASS_THROUGH   (1 << 1)
+# define DP_DS_HDMI_YCBCR420_PASS_THROUGH   (1 << 2)
+# define DP_DS_HDMI_YCBCR444_TO_422_CONV    (1 << 3)
+# define DP_DS_HDMI_YCBCR444_TO_420_CONV    (1 << 4)
 
 #define DP_MAX_DOWNSTREAM_PORTS                    0x10
 
@@ -1663,6 +1667,10 @@ int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
                              const u8 port_cap[4],
                              const struct edid *edid);
+bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+                                      const u8 port_cap[4]);
+bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+                                            const u8 port_cap[4]);
 struct drm_display_mode *drm_dp_downstream_mode(struct drm_device *dev,
                                                const u8 dpcd[DP_RECEIVER_CAP_SIZE],
                                                const u8 port_cap[4]);