Commit 2ef8d0f7 authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/dp: Add helpers for DFP YCbCr 4:2:0 handling



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: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200904115354.25336-18-ville.syrjala@linux.intel.com


Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent bc7ca6a6
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -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
+8 −0
Original line number Diff line number Diff line
@@ -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]);