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: 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>
This commit is contained in:
Ville Syrjälä 2020-09-04 14:53:53 +03:00
parent bc7ca6a647
commit 2ef8d0f7de
2 changed files with 68 additions and 0 deletions

View 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); 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 * drm_dp_downstream_mode() - return a mode for downstream facing port
* @dpcd: DisplayPort configuration data * @dpcd: DisplayPort configuration data

View File

@ -407,6 +407,10 @@ struct drm_device;
# define DP_DS_DVI_HIGH_COLOR_DEPTH (1 << 2) # define DP_DS_DVI_HIGH_COLOR_DEPTH (1 << 2)
/* offset 3 for HDMI */ /* offset 3 for HDMI */
# define DP_DS_HDMI_FRAME_SEQ_TO_FRAME_PACK (1 << 0) # 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 #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], int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4], const u8 port_cap[4],
const struct edid *edid); 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, struct drm_display_mode *drm_dp_downstream_mode(struct drm_device *dev,
const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4]); const u8 port_cap[4]);