All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Hans Verkuil <hansverk@cisco.com>
Cc: intel-gfx@lists.freedesktop.org,
	Thierry Reding <thierry.reding@gmail.com>,
	Hans Verkuil <hans.verkuil@cisco.com>,
	dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org
Subject: Re: [PATCH 06/18] video/hdmi: Handle the MPEG Source infoframe
Date: Fri, 21 Sep 2018 16:53:14 +0300	[thread overview]
Message-ID: <20180921135314.GV5565@intel.com> (raw)
In-Reply-To: <689d116d-8ac1-a6dc-8857-cb8f9c6e389b@cisco.com>

On Fri, Sep 21, 2018 at 10:28:09AM +0200, Hans Verkuil wrote:
> On 09/20/18 20:51, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Add the code to deal with the MPEG source infoframe.
> > 
> > Blindly typed from the spec, and totally untested.
> 
> I'm not sure this patch should be added at all. The CTA-861-G spec (section 6.7)
> says that the implementation of this infoframe is not recommended due to unresolved
> issues.
> 
> I don't think I've ever seen it either.
> 
> It obviously doesn't hurt to have this code, but I prefer to wait until there
> are devices that actively set/use this infoframe.

Sure. I'm totally fine with leaving it out. Just figured I'd send it out
in case anyone has some use for it.

> 
> Regards,
> 
> 	Hans
> 
> > 
> > Cc: Thierry Reding <thierry.reding@gmail.com>
> > Cc: Hans Verkuil <hans.verkuil@cisco.com>
> > Cc: linux-media@vger.kernel.org
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/video/hdmi.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/hdmi.h |  27 ++++++
> >  2 files changed, 256 insertions(+)
> > 
> > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > index 9507f668a569..3d24c7746c51 100644
> > --- a/drivers/video/hdmi.c
> > +++ b/drivers/video/hdmi.c
> > @@ -706,6 +706,131 @@ hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
> >  	return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size);
> >  }
> >  
> > +/**
> > + * hdmi_mpeg_source_infoframe_init() - initialize an HDMI MPEG Source infoframe
> > + * @frame: HDMI MPEG Source infoframe
> > + *
> > + * Returns 0 on success or a negative error code on failure.
> > + */
> > +int hdmi_mpeg_source_infoframe_init(struct hdmi_mpeg_source_infoframe *frame)
> > +{
> > +	memset(frame, 0, sizeof(*frame));
> > +
> > +	frame->type = HDMI_INFOFRAME_TYPE_MPEG_SOURCE;
> > +	frame->version = 1;
> > +	frame->length = HDMI_MPEG_SOURCE_INFOFRAME_SIZE;
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_init);
> > +
> > +static int hdmi_mpeg_source_infoframe_check_only(const struct hdmi_mpeg_source_infoframe *frame)
> > +{
> > +	if (frame->type != HDMI_INFOFRAME_TYPE_MPEG_SOURCE ||
> > +	    frame->version != 1 ||
> > +	    frame->length != HDMI_MPEG_SOURCE_INFOFRAME_SIZE)
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * hdmi_mpeg_source_infoframe_check() - Check and check a HDMI MPEG Source infoframe
> > + * @frame: HDMI MPEG Source infoframe
> > + *
> > + * Validates that the infoframe is consistent and updates derived fields
> > + * (eg. length) based on other fields.
> > + *
> > + * Returns 0 on success or a negative error code on failure.
> > + */
> > +int hdmi_mpeg_source_infoframe_check(struct hdmi_mpeg_source_infoframe *frame)
> > +{
> > +	return hdmi_mpeg_source_infoframe_check_only(frame);
> > +}
> > +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_check);
> > +
> > +/**
> > + * hdmi_mpeg_source_infoframe_pack_only() - write HDMI MPEG Source infoframe to binary buffer
> > + * @frame: HDMI MPEG Source infoframe
> > + * @buffer: destination buffer
> > + * @size: size of buffer
> > + *
> > + * Packs the information contained in the @frame structure into a binary
> > + * representation that can be written into the corresponding controller
> > + * registers. Also computes the checksum as required by section 5.3.5 of
> > + * the HDMI 1.4 specification.
> > + *
> > + * Returns the number of bytes packed into the binary buffer or a negative
> > + * error code on failure.
> > + */
> > +ssize_t hdmi_mpeg_source_infoframe_pack_only(const struct hdmi_mpeg_source_infoframe *frame,
> > +					     void *buffer, size_t size)
> > +{
> > +	u8 *ptr = buffer;
> > +	size_t length;
> > +	int ret;
> > +
> > +	ret = hdmi_mpeg_source_infoframe_check_only(frame);
> > +	if (ret)
> > +		return ret;
> > +
> > +	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
> > +
> > +	if (size < length)
> > +		return -ENOSPC;
> > +
> > +	memset(buffer, 0, size);
> > +
> > +	ptr[0] = frame->type;
> > +	ptr[1] = frame->version;
> > +	ptr[2] = frame->length;
> > +	ptr[3] = 0; /* checksum */
> > +
> > +	/* start infoframe payload */
> > +	ptr += HDMI_INFOFRAME_HEADER_SIZE;
> > +
> > +	ptr[0] = frame->mpeg_bit_rate >> 0;
> > +	ptr[1] = frame->mpeg_bit_rate >> 8;
> > +	ptr[2] = frame->mpeg_bit_rate >> 16;
> > +	ptr[3] = frame->mpeg_bit_rate >> 24;
> > +	ptr[4] = (frame->field_repeat << 4) | frame->mpeg_frame;
> > +
> > +	hdmi_infoframe_set_checksum(buffer, length);
> > +
> > +	return length;
> > +}
> > +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack_only);
> > +
> > +/**
> > + * hdmi_mpeg_source_infoframe_pack() - Check and check a HDMI MPEG Source infoframe,
> > + *                                     and write it to binary buffer
> > + * @frame: HDMI MPEG Source infoframe
> > + * @buffer: destination buffer
> > + * @size: size of buffer
> > + *
> > + * Validates that the infoframe is consistent and updates derived fields
> > + * (eg. length) based on other fields, after which packs the information
> > + * contained in the @frame structure into a binary representation that
> > + * can be written into the corresponding controller registers. Also
> > + * computes the checksum as required by section 5.3.5 of the HDMI 1.4
> > + * specification.
> > + *
> > + * Returns the number of bytes packed into the binary buffer or a negative
> > + * error code on failure.
> > + */
> > +ssize_t hdmi_mpeg_source_infoframe_pack(struct hdmi_mpeg_source_infoframe *frame,
> > +					void *buffer, size_t size)
> > +{
> > +	int ret;
> > +
> > +	ret = hdmi_mpeg_source_infoframe_check(frame);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return hdmi_mpeg_source_infoframe_pack_only(frame, buffer, size);
> > +}
> > +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack);
> > +
> >  /**
> >   * hdmi_infoframe_check() - Check check a HDMI infoframe
> >   * @frame: HDMI infoframe
> > @@ -727,6 +852,8 @@ hdmi_infoframe_check(union hdmi_infoframe *frame)
> >  		return hdmi_audio_infoframe_check(&frame->audio);
> >  	case HDMI_INFOFRAME_TYPE_VENDOR:
> >  		return hdmi_vendor_any_infoframe_check(&frame->vendor);
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		return hdmi_mpeg_source_infoframe_check(&frame->mpeg_source);
> >  	default:
> >  		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> >  		return -EINVAL;
> > @@ -770,6 +897,10 @@ hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t
> >  		length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor,
> >  							     buffer, size);
> >  		break;
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		length = hdmi_mpeg_source_infoframe_pack_only(&frame->mpeg_source,
> > +							      buffer, size);
> > +		break;
> >  	default:
> >  		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> >  		length = -EINVAL;
> > @@ -816,6 +947,10 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame,
> >  		length = hdmi_vendor_any_infoframe_pack(&frame->vendor,
> >  							buffer, size);
> >  		break;
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		length = hdmi_mpeg_source_infoframe_pack(&frame->mpeg_source,
> > +							 buffer, size);
> > +		break;
> >  	default:
> >  		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> >  		length = -EINVAL;
> > @@ -838,6 +973,8 @@ static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type)
> >  		return "Source Product Description (SPD)";
> >  	case HDMI_INFOFRAME_TYPE_AUDIO:
> >  		return "Audio";
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		return "MPEG Source";
> >  	}
> >  	return "Reserved";
> >  }
> > @@ -1349,6 +1486,46 @@ hdmi_vendor_any_infoframe_log(const char *level,
> >  	}
> >  }
> >  
> > +static const char *
> > +hdmi_mpeg_frame_get_name(enum hdmi_mpeg_frame frame)
> > +{
> > +	if (frame < 0 || frame > 3)
> > +		return "invalid";
> > +
> > +	switch (frame) {
> > +	case HDMI_MPEG_FRAME_UNKNOWN:
> > +		return "Unknown";
> > +	case HDMI_MPEG_FRAME_I_PICTURE:
> > +		return "I Picture";
> > +	case HDMI_MPEG_FRAME_B_PICTURE:
> > +		return "B Picture";
> > +	case HDMI_MPEG_FRAME_P_PICTURE:
> > +		return "P Picture";
> > +	}
> > +	return "Reserved";
> > +}
> > +
> > +/**
> > + * hdmi_mpeg_source_infoframe_log() - log info of HDMI MPEG Source infoframe
> > + * @level: logging level
> > + * @dev: device
> > + * @frame: HDMI MPEG Source infoframe
> > + */
> > +static void hdmi_mpeg_source_infoframe_log(const char *level,
> > +					   struct device *dev,
> > +					   const struct hdmi_mpeg_source_infoframe *frame)
> > +{
> > +	hdmi_infoframe_log_header(level, dev,
> > +				  (const struct hdmi_any_infoframe *)frame);
> > +
> > +	hdmi_log("    MPEG bit rate: %d Hz\n",
> > +		 frame->mpeg_bit_rate);
> > +	hdmi_log("    MPEG frame: %s\n",
> > +		 hdmi_mpeg_frame_get_name(frame->mpeg_frame));
> > +	hdmi_log("    field repeat: %s\n",
> > +		 frame->field_repeat ? "Yes" : "No");
> > +}
> > +
> >  /**
> >   * hdmi_infoframe_log() - log info of HDMI infoframe
> >   * @level: logging level
> > @@ -1372,6 +1549,9 @@ void hdmi_infoframe_log(const char *level,
> >  	case HDMI_INFOFRAME_TYPE_VENDOR:
> >  		hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor);
> >  		break;
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		hdmi_mpeg_source_infoframe_log(level, dev, &frame->mpeg_source);
> > +		break;
> >  	}
> >  }
> >  EXPORT_SYMBOL(hdmi_infoframe_log);
> > @@ -1614,6 +1794,52 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
> >  	return 0;
> >  }
> >  
> > +/**
> > + * hdmi_mpeg_source_infoframe_unpack() - unpack binary buffer to a HDMI MPEG Source infoframe
> > + * @frame: HDMI MPEG Source infoframe
> > + * @buffer: source buffer
> > + * @size: size of buffer
> > + *
> > + * Unpacks the information contained in binary @buffer into a structured
> > + * @frame of the HDMI MPEG Source information frame.
> > + * 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_mpeg_source_infoframe_unpack(struct hdmi_mpeg_source_infoframe *frame,
> > +					     const void *buffer, size_t size)
> > +{
> > +	const u8 *ptr = buffer;
> > +	int ret;
> > +
> > +	if (size < HDMI_INFOFRAME_SIZE(MPEG_SOURCE))
> > +		return -EINVAL;
> > +
> > +	if (ptr[0] != HDMI_INFOFRAME_TYPE_MPEG_SOURCE ||
> > +	    ptr[1] != 1 ||
> > +	    ptr[2] != HDMI_MPEG_SOURCE_INFOFRAME_SIZE) {
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(MPEG_SOURCE)) != 0)
> > +		return -EINVAL;
> > +
> > +	ret = hdmi_mpeg_source_infoframe_init(frame);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ptr += HDMI_INFOFRAME_HEADER_SIZE;
> > +
> > +	frame->mpeg_bit_rate =
> > +		(ptr[0] << 0) | (ptr[1] << 8) |
> > +		(ptr[2] << 16) | (ptr[3] << 24);
> > +	frame->mpeg_frame = ptr[4] & 0x3;
> > +	frame->field_repeat = ptr[4] & 0x10;
> > +
> > +	return 0;
> > +}
> > +
> >  /**
> >   * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
> >   * @frame: HDMI infoframe
> > @@ -1649,6 +1875,9 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
> >  	case HDMI_INFOFRAME_TYPE_VENDOR:
> >  		ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size);
> >  		break;
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		ret = hdmi_mpeg_source_infoframe_unpack(&frame->mpeg_source, buffer, size);
> > +		break;
> >  	default:
> >  		ret = -EINVAL;
> >  		break;
> > diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
> > index 80521d9591a1..2c9322f7538d 100644
> > --- a/include/linux/hdmi.h
> > +++ b/include/linux/hdmi.h
> > @@ -47,6 +47,7 @@ enum hdmi_infoframe_type {
> >  	HDMI_INFOFRAME_TYPE_AVI = 0x82,
> >  	HDMI_INFOFRAME_TYPE_SPD = 0x83,
> >  	HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
> > +	HDMI_INFOFRAME_TYPE_MPEG_SOURCE = 0x85,
> >  };
> >  
> >  #define HDMI_IEEE_OUI 0x000c03
> > @@ -55,6 +56,7 @@ enum hdmi_infoframe_type {
> >  #define HDMI_AVI_INFOFRAME_SIZE    13
> >  #define HDMI_SPD_INFOFRAME_SIZE    25
> >  #define HDMI_AUDIO_INFOFRAME_SIZE  10
> > +#define HDMI_MPEG_SOURCE_INFOFRAME_SIZE  10
> >  
> >  #define HDMI_INFOFRAME_SIZE(type)	\
> >  	(HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE)
> > @@ -337,6 +339,29 @@ union hdmi_vendor_any_infoframe {
> >  	struct hdmi_vendor_infoframe hdmi;
> >  };
> >  
> > +enum hdmi_mpeg_frame {
> > +	HDMI_MPEG_FRAME_UNKNOWN,
> > +	HDMI_MPEG_FRAME_I_PICTURE,
> > +	HDMI_MPEG_FRAME_B_PICTURE,
> > +	HDMI_MPEG_FRAME_P_PICTURE,
> > +};
> > +
> > +struct hdmi_mpeg_source_infoframe {
> > +	enum hdmi_infoframe_type type;
> > +	unsigned char version;
> > +	unsigned char length;
> > +	unsigned int mpeg_bit_rate;
> > +	enum hdmi_mpeg_frame mpeg_frame;
> > +	bool field_repeat;
> > +};
> > +
> > +int hdmi_mpeg_source_infoframe_init(struct hdmi_mpeg_source_infoframe *frame);
> > +ssize_t hdmi_mpeg_source_infoframe_pack(struct hdmi_mpeg_source_infoframe *frame,
> > +					void *buffer, size_t size);
> > +ssize_t hdmi_mpeg_source_infoframe_pack_only(const struct hdmi_mpeg_source_infoframe *frame,
> > +					     void *buffer, size_t size);
> > +int hdmi_mpeg_source_infoframe_check(struct hdmi_mpeg_source_infoframe *frame);
> > +
> >  /**
> >   * union hdmi_infoframe - overall union of all abstract infoframe representations
> >   * @any: generic infoframe
> > @@ -344,6 +369,7 @@ union hdmi_vendor_any_infoframe {
> >   * @spd: spd infoframe
> >   * @vendor: union of all vendor infoframes
> >   * @audio: audio infoframe
> > + * @mpeg_source: mpeg source infoframe
> >   *
> >   * This is used by the generic pack function. This works since all infoframes
> >   * have the same header which also indicates which type of infoframe should be
> > @@ -355,6 +381,7 @@ union hdmi_infoframe {
> >  	struct hdmi_spd_infoframe spd;
> >  	union hdmi_vendor_any_infoframe vendor;
> >  	struct hdmi_audio_infoframe audio;
> > +	struct hdmi_mpeg_source_infoframe mpeg_source;
> >  };
> >  
> >  ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer,
> > 

-- 
Ville Syrjälä
Intel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Hans Verkuil <hansverk@cisco.com>
Cc: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org,
	Thierry Reding <thierry.reding@gmail.com>,
	Hans Verkuil <hans.verkuil@cisco.com>,
	linux-media@vger.kernel.org
Subject: Re: [PATCH 06/18] video/hdmi: Handle the MPEG Source infoframe
Date: Fri, 21 Sep 2018 16:53:14 +0300	[thread overview]
Message-ID: <20180921135314.GV5565@intel.com> (raw)
In-Reply-To: <689d116d-8ac1-a6dc-8857-cb8f9c6e389b@cisco.com>

On Fri, Sep 21, 2018 at 10:28:09AM +0200, Hans Verkuil wrote:
> On 09/20/18 20:51, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Add the code to deal with the MPEG source infoframe.
> > 
> > Blindly typed from the spec, and totally untested.
> 
> I'm not sure this patch should be added at all. The CTA-861-G spec (section 6.7)
> says that the implementation of this infoframe is not recommended due to unresolved
> issues.
> 
> I don't think I've ever seen it either.
> 
> It obviously doesn't hurt to have this code, but I prefer to wait until there
> are devices that actively set/use this infoframe.

Sure. I'm totally fine with leaving it out. Just figured I'd send it out
in case anyone has some use for it.

> 
> Regards,
> 
> 	Hans
> 
> > 
> > Cc: Thierry Reding <thierry.reding@gmail.com>
> > Cc: Hans Verkuil <hans.verkuil@cisco.com>
> > Cc: linux-media@vger.kernel.org
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/video/hdmi.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/hdmi.h |  27 ++++++
> >  2 files changed, 256 insertions(+)
> > 
> > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > index 9507f668a569..3d24c7746c51 100644
> > --- a/drivers/video/hdmi.c
> > +++ b/drivers/video/hdmi.c
> > @@ -706,6 +706,131 @@ hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
> >  	return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size);
> >  }
> >  
> > +/**
> > + * hdmi_mpeg_source_infoframe_init() - initialize an HDMI MPEG Source infoframe
> > + * @frame: HDMI MPEG Source infoframe
> > + *
> > + * Returns 0 on success or a negative error code on failure.
> > + */
> > +int hdmi_mpeg_source_infoframe_init(struct hdmi_mpeg_source_infoframe *frame)
> > +{
> > +	memset(frame, 0, sizeof(*frame));
> > +
> > +	frame->type = HDMI_INFOFRAME_TYPE_MPEG_SOURCE;
> > +	frame->version = 1;
> > +	frame->length = HDMI_MPEG_SOURCE_INFOFRAME_SIZE;
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_init);
> > +
> > +static int hdmi_mpeg_source_infoframe_check_only(const struct hdmi_mpeg_source_infoframe *frame)
> > +{
> > +	if (frame->type != HDMI_INFOFRAME_TYPE_MPEG_SOURCE ||
> > +	    frame->version != 1 ||
> > +	    frame->length != HDMI_MPEG_SOURCE_INFOFRAME_SIZE)
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * hdmi_mpeg_source_infoframe_check() - Check and check a HDMI MPEG Source infoframe
> > + * @frame: HDMI MPEG Source infoframe
> > + *
> > + * Validates that the infoframe is consistent and updates derived fields
> > + * (eg. length) based on other fields.
> > + *
> > + * Returns 0 on success or a negative error code on failure.
> > + */
> > +int hdmi_mpeg_source_infoframe_check(struct hdmi_mpeg_source_infoframe *frame)
> > +{
> > +	return hdmi_mpeg_source_infoframe_check_only(frame);
> > +}
> > +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_check);
> > +
> > +/**
> > + * hdmi_mpeg_source_infoframe_pack_only() - write HDMI MPEG Source infoframe to binary buffer
> > + * @frame: HDMI MPEG Source infoframe
> > + * @buffer: destination buffer
> > + * @size: size of buffer
> > + *
> > + * Packs the information contained in the @frame structure into a binary
> > + * representation that can be written into the corresponding controller
> > + * registers. Also computes the checksum as required by section 5.3.5 of
> > + * the HDMI 1.4 specification.
> > + *
> > + * Returns the number of bytes packed into the binary buffer or a negative
> > + * error code on failure.
> > + */
> > +ssize_t hdmi_mpeg_source_infoframe_pack_only(const struct hdmi_mpeg_source_infoframe *frame,
> > +					     void *buffer, size_t size)
> > +{
> > +	u8 *ptr = buffer;
> > +	size_t length;
> > +	int ret;
> > +
> > +	ret = hdmi_mpeg_source_infoframe_check_only(frame);
> > +	if (ret)
> > +		return ret;
> > +
> > +	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
> > +
> > +	if (size < length)
> > +		return -ENOSPC;
> > +
> > +	memset(buffer, 0, size);
> > +
> > +	ptr[0] = frame->type;
> > +	ptr[1] = frame->version;
> > +	ptr[2] = frame->length;
> > +	ptr[3] = 0; /* checksum */
> > +
> > +	/* start infoframe payload */
> > +	ptr += HDMI_INFOFRAME_HEADER_SIZE;
> > +
> > +	ptr[0] = frame->mpeg_bit_rate >> 0;
> > +	ptr[1] = frame->mpeg_bit_rate >> 8;
> > +	ptr[2] = frame->mpeg_bit_rate >> 16;
> > +	ptr[3] = frame->mpeg_bit_rate >> 24;
> > +	ptr[4] = (frame->field_repeat << 4) | frame->mpeg_frame;
> > +
> > +	hdmi_infoframe_set_checksum(buffer, length);
> > +
> > +	return length;
> > +}
> > +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack_only);
> > +
> > +/**
> > + * hdmi_mpeg_source_infoframe_pack() - Check and check a HDMI MPEG Source infoframe,
> > + *                                     and write it to binary buffer
> > + * @frame: HDMI MPEG Source infoframe
> > + * @buffer: destination buffer
> > + * @size: size of buffer
> > + *
> > + * Validates that the infoframe is consistent and updates derived fields
> > + * (eg. length) based on other fields, after which packs the information
> > + * contained in the @frame structure into a binary representation that
> > + * can be written into the corresponding controller registers. Also
> > + * computes the checksum as required by section 5.3.5 of the HDMI 1.4
> > + * specification.
> > + *
> > + * Returns the number of bytes packed into the binary buffer or a negative
> > + * error code on failure.
> > + */
> > +ssize_t hdmi_mpeg_source_infoframe_pack(struct hdmi_mpeg_source_infoframe *frame,
> > +					void *buffer, size_t size)
> > +{
> > +	int ret;
> > +
> > +	ret = hdmi_mpeg_source_infoframe_check(frame);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return hdmi_mpeg_source_infoframe_pack_only(frame, buffer, size);
> > +}
> > +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack);
> > +
> >  /**
> >   * hdmi_infoframe_check() - Check check a HDMI infoframe
> >   * @frame: HDMI infoframe
> > @@ -727,6 +852,8 @@ hdmi_infoframe_check(union hdmi_infoframe *frame)
> >  		return hdmi_audio_infoframe_check(&frame->audio);
> >  	case HDMI_INFOFRAME_TYPE_VENDOR:
> >  		return hdmi_vendor_any_infoframe_check(&frame->vendor);
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		return hdmi_mpeg_source_infoframe_check(&frame->mpeg_source);
> >  	default:
> >  		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> >  		return -EINVAL;
> > @@ -770,6 +897,10 @@ hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t
> >  		length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor,
> >  							     buffer, size);
> >  		break;
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		length = hdmi_mpeg_source_infoframe_pack_only(&frame->mpeg_source,
> > +							      buffer, size);
> > +		break;
> >  	default:
> >  		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> >  		length = -EINVAL;
> > @@ -816,6 +947,10 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame,
> >  		length = hdmi_vendor_any_infoframe_pack(&frame->vendor,
> >  							buffer, size);
> >  		break;
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		length = hdmi_mpeg_source_infoframe_pack(&frame->mpeg_source,
> > +							 buffer, size);
> > +		break;
> >  	default:
> >  		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> >  		length = -EINVAL;
> > @@ -838,6 +973,8 @@ static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type)
> >  		return "Source Product Description (SPD)";
> >  	case HDMI_INFOFRAME_TYPE_AUDIO:
> >  		return "Audio";
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		return "MPEG Source";
> >  	}
> >  	return "Reserved";
> >  }
> > @@ -1349,6 +1486,46 @@ hdmi_vendor_any_infoframe_log(const char *level,
> >  	}
> >  }
> >  
> > +static const char *
> > +hdmi_mpeg_frame_get_name(enum hdmi_mpeg_frame frame)
> > +{
> > +	if (frame < 0 || frame > 3)
> > +		return "invalid";
> > +
> > +	switch (frame) {
> > +	case HDMI_MPEG_FRAME_UNKNOWN:
> > +		return "Unknown";
> > +	case HDMI_MPEG_FRAME_I_PICTURE:
> > +		return "I Picture";
> > +	case HDMI_MPEG_FRAME_B_PICTURE:
> > +		return "B Picture";
> > +	case HDMI_MPEG_FRAME_P_PICTURE:
> > +		return "P Picture";
> > +	}
> > +	return "Reserved";
> > +}
> > +
> > +/**
> > + * hdmi_mpeg_source_infoframe_log() - log info of HDMI MPEG Source infoframe
> > + * @level: logging level
> > + * @dev: device
> > + * @frame: HDMI MPEG Source infoframe
> > + */
> > +static void hdmi_mpeg_source_infoframe_log(const char *level,
> > +					   struct device *dev,
> > +					   const struct hdmi_mpeg_source_infoframe *frame)
> > +{
> > +	hdmi_infoframe_log_header(level, dev,
> > +				  (const struct hdmi_any_infoframe *)frame);
> > +
> > +	hdmi_log("    MPEG bit rate: %d Hz\n",
> > +		 frame->mpeg_bit_rate);
> > +	hdmi_log("    MPEG frame: %s\n",
> > +		 hdmi_mpeg_frame_get_name(frame->mpeg_frame));
> > +	hdmi_log("    field repeat: %s\n",
> > +		 frame->field_repeat ? "Yes" : "No");
> > +}
> > +
> >  /**
> >   * hdmi_infoframe_log() - log info of HDMI infoframe
> >   * @level: logging level
> > @@ -1372,6 +1549,9 @@ void hdmi_infoframe_log(const char *level,
> >  	case HDMI_INFOFRAME_TYPE_VENDOR:
> >  		hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor);
> >  		break;
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		hdmi_mpeg_source_infoframe_log(level, dev, &frame->mpeg_source);
> > +		break;
> >  	}
> >  }
> >  EXPORT_SYMBOL(hdmi_infoframe_log);
> > @@ -1614,6 +1794,52 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
> >  	return 0;
> >  }
> >  
> > +/**
> > + * hdmi_mpeg_source_infoframe_unpack() - unpack binary buffer to a HDMI MPEG Source infoframe
> > + * @frame: HDMI MPEG Source infoframe
> > + * @buffer: source buffer
> > + * @size: size of buffer
> > + *
> > + * Unpacks the information contained in binary @buffer into a structured
> > + * @frame of the HDMI MPEG Source information frame.
> > + * 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_mpeg_source_infoframe_unpack(struct hdmi_mpeg_source_infoframe *frame,
> > +					     const void *buffer, size_t size)
> > +{
> > +	const u8 *ptr = buffer;
> > +	int ret;
> > +
> > +	if (size < HDMI_INFOFRAME_SIZE(MPEG_SOURCE))
> > +		return -EINVAL;
> > +
> > +	if (ptr[0] != HDMI_INFOFRAME_TYPE_MPEG_SOURCE ||
> > +	    ptr[1] != 1 ||
> > +	    ptr[2] != HDMI_MPEG_SOURCE_INFOFRAME_SIZE) {
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(MPEG_SOURCE)) != 0)
> > +		return -EINVAL;
> > +
> > +	ret = hdmi_mpeg_source_infoframe_init(frame);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ptr += HDMI_INFOFRAME_HEADER_SIZE;
> > +
> > +	frame->mpeg_bit_rate =
> > +		(ptr[0] << 0) | (ptr[1] << 8) |
> > +		(ptr[2] << 16) | (ptr[3] << 24);
> > +	frame->mpeg_frame = ptr[4] & 0x3;
> > +	frame->field_repeat = ptr[4] & 0x10;
> > +
> > +	return 0;
> > +}
> > +
> >  /**
> >   * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
> >   * @frame: HDMI infoframe
> > @@ -1649,6 +1875,9 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
> >  	case HDMI_INFOFRAME_TYPE_VENDOR:
> >  		ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size);
> >  		break;
> > +	case HDMI_INFOFRAME_TYPE_MPEG_SOURCE:
> > +		ret = hdmi_mpeg_source_infoframe_unpack(&frame->mpeg_source, buffer, size);
> > +		break;
> >  	default:
> >  		ret = -EINVAL;
> >  		break;
> > diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
> > index 80521d9591a1..2c9322f7538d 100644
> > --- a/include/linux/hdmi.h
> > +++ b/include/linux/hdmi.h
> > @@ -47,6 +47,7 @@ enum hdmi_infoframe_type {
> >  	HDMI_INFOFRAME_TYPE_AVI = 0x82,
> >  	HDMI_INFOFRAME_TYPE_SPD = 0x83,
> >  	HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
> > +	HDMI_INFOFRAME_TYPE_MPEG_SOURCE = 0x85,
> >  };
> >  
> >  #define HDMI_IEEE_OUI 0x000c03
> > @@ -55,6 +56,7 @@ enum hdmi_infoframe_type {
> >  #define HDMI_AVI_INFOFRAME_SIZE    13
> >  #define HDMI_SPD_INFOFRAME_SIZE    25
> >  #define HDMI_AUDIO_INFOFRAME_SIZE  10
> > +#define HDMI_MPEG_SOURCE_INFOFRAME_SIZE  10
> >  
> >  #define HDMI_INFOFRAME_SIZE(type)	\
> >  	(HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE)
> > @@ -337,6 +339,29 @@ union hdmi_vendor_any_infoframe {
> >  	struct hdmi_vendor_infoframe hdmi;
> >  };
> >  
> > +enum hdmi_mpeg_frame {
> > +	HDMI_MPEG_FRAME_UNKNOWN,
> > +	HDMI_MPEG_FRAME_I_PICTURE,
> > +	HDMI_MPEG_FRAME_B_PICTURE,
> > +	HDMI_MPEG_FRAME_P_PICTURE,
> > +};
> > +
> > +struct hdmi_mpeg_source_infoframe {
> > +	enum hdmi_infoframe_type type;
> > +	unsigned char version;
> > +	unsigned char length;
> > +	unsigned int mpeg_bit_rate;
> > +	enum hdmi_mpeg_frame mpeg_frame;
> > +	bool field_repeat;
> > +};
> > +
> > +int hdmi_mpeg_source_infoframe_init(struct hdmi_mpeg_source_infoframe *frame);
> > +ssize_t hdmi_mpeg_source_infoframe_pack(struct hdmi_mpeg_source_infoframe *frame,
> > +					void *buffer, size_t size);
> > +ssize_t hdmi_mpeg_source_infoframe_pack_only(const struct hdmi_mpeg_source_infoframe *frame,
> > +					     void *buffer, size_t size);
> > +int hdmi_mpeg_source_infoframe_check(struct hdmi_mpeg_source_infoframe *frame);
> > +
> >  /**
> >   * union hdmi_infoframe - overall union of all abstract infoframe representations
> >   * @any: generic infoframe
> > @@ -344,6 +369,7 @@ union hdmi_vendor_any_infoframe {
> >   * @spd: spd infoframe
> >   * @vendor: union of all vendor infoframes
> >   * @audio: audio infoframe
> > + * @mpeg_source: mpeg source infoframe
> >   *
> >   * This is used by the generic pack function. This works since all infoframes
> >   * have the same header which also indicates which type of infoframe should be
> > @@ -355,6 +381,7 @@ union hdmi_infoframe {
> >  	struct hdmi_spd_infoframe spd;
> >  	union hdmi_vendor_any_infoframe vendor;
> >  	struct hdmi_audio_infoframe audio;
> > +	struct hdmi_mpeg_source_infoframe mpeg_source;
> >  };
> >  
> >  ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer,
> > 

-- 
Ville Syrjälä
Intel

  reply	other threads:[~2018-09-21 13:53 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-20 18:51 [PATCH 00/18] drm/i915: Infoframe precompute/check Ville Syrjala
2018-09-20 18:51 ` Ville Syrjala
2018-09-20 18:51 ` [PATCH 01/18] video/hdmi: Constify 'buffer' to the unpack functions Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:03   ` Hans Verkuil
2018-09-21  8:03     ` Hans Verkuil
2018-09-20 18:51 ` [PATCH 02/18] video/hdmi: Pass buffer size to infoframe " Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:06   ` Hans Verkuil
2018-09-21  8:06     ` Hans Verkuil
2018-09-20 18:51 ` [PATCH 03/18] video/hdmi: Constify infoframe passed to the log functions Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:06   ` Hans Verkuil
2018-09-21  8:06     ` Hans Verkuil
2018-09-20 18:51 ` [PATCH 04/18] video/hdmi: Constify infoframe passed to the pack functions Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:24   ` Hans Verkuil
2018-09-21  8:24     ` Hans Verkuil
2018-09-21 14:30     ` Ville Syrjälä
2018-09-21 14:30       ` Ville Syrjälä
2018-09-21 14:33   ` [PATCH v3 " Ville Syrjala
2018-09-21 14:33     ` Ville Syrjala
2018-10-01 19:10     ` Ville Syrjälä
2018-10-01 19:10       ` Ville Syrjälä
2018-10-02  6:37       ` Hans Verkuil
2018-10-02  6:37         ` Hans Verkuil
2018-09-20 18:51 ` [PATCH 05/18] video/hdmi: Add an enum for HDMI packet types Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:41   ` Hans Verkuil
2018-09-21  8:41     ` Hans Verkuil
2018-09-21 14:01     ` Ville Syrjälä
2018-09-21 14:01       ` Ville Syrjälä
2018-09-21 14:12       ` Hans Verkuil
2018-09-21 14:12         ` Hans Verkuil
2018-09-21 15:07         ` Ville Syrjälä
2018-09-21 15:07           ` Ville Syrjälä
2018-12-20 11:27   ` Sharma, Shashank
2018-09-20 18:51 ` [PATCH 06/18] video/hdmi: Handle the MPEG Source infoframe Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:28   ` Hans Verkuil
2018-09-21  8:28     ` Hans Verkuil
2018-09-21 13:53     ` Ville Syrjälä [this message]
2018-09-21 13:53       ` Ville Syrjälä
2018-09-21 15:09   ` [PATCH v2 " Ville Syrjala
2018-09-21 15:09     ` Ville Syrjala
2018-09-20 18:51 ` [PATCH 07/18] video/hdmi: Handle the NTSC VBI infoframe Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:30   ` Hans Verkuil
2018-09-21  8:30     ` Hans Verkuil
2018-09-21 13:54     ` Ville Syrjälä
2018-09-21 13:54       ` Ville Syrjälä
2018-09-21 15:10   ` [PATCH v2 " Ville Syrjala
2018-09-21 15:10     ` Ville Syrjala
2018-09-20 18:51 ` [PATCH 08/18] drm/i915: Use memmove() for punching the hole into infoframes Ville Syrjala
2018-09-21 13:52   ` Daniel Vetter
2018-09-20 18:51 ` [PATCH 09/18] drm/i915: Pass intel_encoder to infoframe functions Ville Syrjala
2018-09-21 13:59   ` Daniel Vetter
2018-09-21 15:03     ` Ville Syrjälä
2018-09-20 18:51 ` [PATCH 10/18] drm/i915: Add the missing HDMI gamut metadata packet stuff Ville Syrjala
2018-09-21 14:15   ` [Intel-gfx] " Daniel Vetter
2018-09-20 18:51 ` [PATCH 11/18] drm/i915: Return the mask of enabled infoframes from ->inforame_enabled() Ville Syrjala
2018-09-24 15:51   ` Daniel Vetter
2018-09-24 16:36     ` [Intel-gfx] " Ville Syrjälä
2018-10-01  6:55       ` Daniel Vetter
2018-10-01 19:29         ` Ville Syrjälä
2018-09-20 18:51 ` [PATCH 12/18] drm/i915: Store mask of enabled infoframes in the crtc state Ville Syrjala
2018-09-24 15:51   ` [Intel-gfx] " Daniel Vetter
2018-09-20 18:51 ` [PATCH 13/18] drm/i915: Precompute HDMI infoframes Ville Syrjala
2018-09-24 15:58   ` Daniel Vetter
2018-09-24 16:42     ` Ville Syrjälä
2018-09-20 18:51 ` [PATCH 14/18] drm/i915: Read out " Ville Syrjala
2018-09-24 16:08   ` Daniel Vetter
2018-09-24 16:52     ` Ville Syrjälä
2018-09-20 18:51 ` [PATCH 15/18] drm/i915/sdvo: Precompute " Ville Syrjala
2018-09-20 18:51 ` [PATCH 16/18] drm/i915/sdvo: Read out " Ville Syrjala
2018-09-24 16:10   ` [Intel-gfx] " Daniel Vetter
2018-09-24 17:13     ` Ville Syrjälä
2018-10-01  6:59       ` Daniel Vetter
2018-10-01 13:35         ` Ville Syrjälä
2018-10-01 16:48           ` Daniel Vetter
2018-09-20 18:51 ` [PATCH 17/18] drm/i915: Check infoframe state in intel_pipe_config_compare() Ville Syrjala
2018-09-24 16:12   ` Daniel Vetter
2018-10-01 20:35     ` [Intel-gfx] " Ville Syrjälä
2018-10-02  8:16       ` Daniel Vetter
2018-09-20 18:51 ` [PATCH 18/18] drm/i915: Include infoframes in the crtc state dump Ville Syrjala
2018-09-24 16:14   ` [Intel-gfx] " Daniel Vetter
2018-09-20 19:02 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Infoframe precompute/check Patchwork
2018-09-20 19:12 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-09-20 19:26 ` ✓ Fi.CI.BAT: success " Patchwork
2018-09-20 22:30 ` ✓ Fi.CI.IGT: " Patchwork
2018-09-21 14:40 ` ✗ Fi.CI.BAT: failure for drm/i915: Infoframe precompute/check (rev2) Patchwork
2018-09-21 15:25 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Infoframe precompute/check (rev4) Patchwork
2018-09-21 15:35 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-09-21 15:46 ` ✓ Fi.CI.BAT: success " Patchwork
2018-09-21 17:04 ` ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180921135314.GV5565@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hans.verkuil@cisco.com \
    --cc=hansverk@cisco.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=linux-media@vger.kernel.org \
    --cc=thierry.reding@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.