Commit f45ce933 authored by Gwan-gyeong Mun's avatar Gwan-gyeong Mun Committed by Jani Nikula

video/hdmi: Add Unpack only function for DRM infoframe

It adds an unpack only function for DRM infoframe for dynamic range and
mastering infoframe readout.
It unpacks the information data block contained in the binary buffer into
a structured frame of the HDMI Dynamic Range and Mastering (DRM)
information frame.

In contrast to hdmi_drm_infoframe_unpack() function, it does not verify
a checksum.

It can be used for unpacking a DP HDR Metadata Infoframe SDP case.
DP HDR Metadata Infoframe SDP uses the same Dynamic Range and Mastering
(DRM) information (CTA-861-G spec.) such as HDMI DRM infoframe.
But DP SDP header and payload structure are different from HDMI DRM
Infoframe. Therefore unpacking DRM infoframe for DP requires skipping of
a verifying checksum.

v9: Add clear comments to hdmi_drm_infoframe_unpack_only() and
    hdmi_drm_infoframe_unpack() (Laurent Pinchart)
Signed-off-by: default avatarGwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Reviewed-by: default avatarUma Shankar <uma.shankar@intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514060732.3378396-2-gwan-gyeong.mun@intel.com
parent 0f4013fb
...@@ -1768,20 +1768,21 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, ...@@ -1768,20 +1768,21 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
} }
/** /**
* hdmi_drm_infoframe_unpack() - unpack binary buffer to a HDMI DRM infoframe * hdmi_drm_infoframe_unpack_only() - unpack binary buffer of CTA-861-G DRM
* infoframe DataBytes to a HDMI DRM
* infoframe
* @frame: HDMI DRM infoframe * @frame: HDMI DRM infoframe
* @buffer: source buffer * @buffer: source buffer
* @size: size of buffer * @size: size of buffer
* *
* Unpacks the information contained in binary @buffer into a structured * Unpacks CTA-861-G DRM infoframe DataBytes contained in the binary @buffer
* @frame of the HDMI Dynamic Range and Mastering (DRM) information frame. * into a structured @frame of the HDMI Dynamic Range and Mastering (DRM)
* Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 * infoframe.
* specification.
* *
* Returns 0 on success or a negative error code on failure. * Returns 0 on success or a negative error code on failure.
*/ */
static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame, int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame,
const void *buffer, size_t size) const void *buffer, size_t size)
{ {
const u8 *ptr = buffer; const u8 *ptr = buffer;
const u8 *temp; const u8 *temp;
...@@ -1790,23 +1791,13 @@ static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame, ...@@ -1790,23 +1791,13 @@ static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame,
int ret; int ret;
int i; int i;
if (size < HDMI_INFOFRAME_SIZE(DRM)) if (size < HDMI_DRM_INFOFRAME_SIZE)
return -EINVAL;
if (ptr[0] != HDMI_INFOFRAME_TYPE_DRM ||
ptr[1] != 1 ||
ptr[2] != HDMI_DRM_INFOFRAME_SIZE)
return -EINVAL;
if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(DRM)) != 0)
return -EINVAL; return -EINVAL;
ret = hdmi_drm_infoframe_init(frame); ret = hdmi_drm_infoframe_init(frame);
if (ret) if (ret)
return ret; return ret;
ptr += HDMI_INFOFRAME_HEADER_SIZE;
frame->eotf = ptr[0] & 0x7; frame->eotf = ptr[0] & 0x7;
frame->metadata_type = ptr[1] & 0x7; frame->metadata_type = ptr[1] & 0x7;
...@@ -1814,7 +1805,7 @@ static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame, ...@@ -1814,7 +1805,7 @@ static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame,
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
x_lsb = *temp++; x_lsb = *temp++;
x_msb = *temp++; x_msb = *temp++;
frame->display_primaries[i].x = (x_msb << 8) | x_lsb; frame->display_primaries[i].x = (x_msb << 8) | x_lsb;
y_lsb = *temp++; y_lsb = *temp++;
y_msb = *temp++; y_msb = *temp++;
frame->display_primaries[i].y = (y_msb << 8) | y_lsb; frame->display_primaries[i].y = (y_msb << 8) | y_lsb;
...@@ -1830,6 +1821,42 @@ static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame, ...@@ -1830,6 +1821,42 @@ static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame,
return 0; return 0;
} }
EXPORT_SYMBOL(hdmi_drm_infoframe_unpack_only);
/**
* hdmi_drm_infoframe_unpack() - unpack binary buffer to a HDMI DRM infoframe
* @frame: HDMI DRM infoframe
* @buffer: source buffer
* @size: size of buffer
*
* Unpacks the CTA-861-G DRM infoframe contained in the binary @buffer into
* a structured @frame of the HDMI Dynamic Range and Mastering (DRM)
* infoframe. It also verifies the checksum as required by section 5.3.5 of
* the HDMI 1.4 specification.
*
* Returns 0 on success or a negative error code on failure.
*/
static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame,
const void *buffer, size_t size)
{
const u8 *ptr = buffer;
int ret;
if (size < HDMI_INFOFRAME_SIZE(DRM))
return -EINVAL;
if (ptr[0] != HDMI_INFOFRAME_TYPE_DRM ||
ptr[1] != 1 ||
ptr[2] != HDMI_DRM_INFOFRAME_SIZE)
return -EINVAL;
if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(DRM)) != 0)
return -EINVAL;
ret = hdmi_drm_infoframe_unpack_only(frame, ptr + HDMI_INFOFRAME_HEADER_SIZE,
size - HDMI_INFOFRAME_HEADER_SIZE);
return ret;
}
/** /**
* hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
......
...@@ -219,6 +219,8 @@ ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer, ...@@ -219,6 +219,8 @@ ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer,
ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame, ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame,
void *buffer, size_t size); void *buffer, size_t size);
int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame); int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame);
int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame,
const void *buffer, size_t size);
enum hdmi_spd_sdi { enum hdmi_spd_sdi {
HDMI_SPD_SDI_UNKNOWN, HDMI_SPD_SDI_UNKNOWN,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment