[PATCH v5 09/17] drm: create hdmi output property

Daniel Vetter daniel at ffwll.ch
Wed Jul 5 06:31:56 UTC 2017


On Wed, Jul 05, 2017 at 11:39:30AM +0530, Sharma, Shashank wrote:
> Regards
> 
> Shashank
> 
> 
> On 7/4/2017 9:06 PM, Daniel Vetter wrote:
> > On Tue, Jul 04, 2017 at 07:41:56PM +0530, Shashank Sharma wrote:
> > > HDMI displays can support various output types, based on
> > > the color space and subsampling type. The possible
> > > outputs from a HDMI 2.0 monitor could be:
> > >   - RGB
> > >   - YCBCR 444
> > >   - YCBCR 422
> > >   - YCBCR 420
> > > 
> > > This patch adds a drm property "hdmi_output_format", using which,
> > > a user can specify its preference, for the HDMI output type. The
> > > output type enums are similar to the mentioned outputs above. To
> > > handle various subsampling of YCBCR output types, this property
> > > allows two special cases:
> > >   - DRM_HDMI_OUTPUT_YCBCR_HQ
> > >     This indicates preferred output should be YCBCR output, with highest
> > >     subsampling rate by the source/sink, which can be typically:
> > >   	- ycbcr444
> > >   	- ycbcr422
> > >   	- ycbcr420
> > >   - DRM_HDMI_OUTPUT_YCBCR_LQ
> > >     This indicates preferred output should be YCBCR output, with lowest
> > >     subsampling rate supported by source/sink, which can be:
> > >   	- ycbcr420
> > >   	- ycbcr422
> > >   	- ycbcr444
> > > 
> > > Default value of the property is set to 0 = RGB, so no changes if you
> > > dont set the property.
> > > 
> > > PS: While doing modeset for YCBCR 420 only modes, this property is
> > >      ignored, as those timings can be supported only in YCBCR 420
> > >      output mode.
> > > 
> > > V2: Added description for the new variable to address build warning
> > > V3: Rebase
> > > V4: Rebase
> > > V5: Added get_property counterpart to fix IGT BAT failures (BAT/CI)
> > >      Danvet:
> > >      - Add documentation for the new property
> > >      - Create a sub-section for HDMI properties, and add documentation for
> > >        few more HDMI propeties. Added documentation for:
> > > 	- Broadcast RGB
> > > 	- aspect ratio
> > > 
> > > Cc: Ville Syrjala <ville.syrjala at linux.intel.com>
> > > Cc: Jose Abreu <joabreu at synopsys.com>
> > > Cc: Daniel Vetter <daniel.vetter at intel.com>
> > > Signed-off-by: Shashank Sharma <shashank.sharma at intel.com>
> > Bunch more documentation nitpicks below. I'd personally also split up the
> > patch into documenting the existing props and adding the new format one.
> In fact thats what I would do now. I dont want HDMI 2.0 patch series to get
> blocked due to documentation, as with all the comments
> it seems like some work. Lets do it in this way:
>  - This patch series will add the documentation for hdmi_output_property
> - I will send a separate patch which will collectively add documentation for
> all standard HDMI properties.
> > Thanks, Daniel
> > 
> > > ---
> > >   Documentation/gpu/drm-kms.rst       | 12 +++++++
> > >   drivers/gpu/drm/drm_atomic.c        |  4 +++
> > >   drivers/gpu/drm/drm_atomic_helper.c |  4 +++
> > >   drivers/gpu/drm/drm_connector.c     | 69 ++++++++++++++++++++++++++++++++++++-
> > >   drivers/gpu/drm/drm_crtc_internal.h |  1 +
> > >   drivers/gpu/drm/drm_mode_config.c   |  4 +++
> > >   drivers/gpu/drm/i915/intel_modes.c  | 13 +++++++
> > >   include/drm/drm_connector.h         | 18 ++++++++++
> > >   include/drm/drm_mode_config.h       |  5 +++
> > >   9 files changed, 129 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
> > > index 3072841..dcdd6ff 100644
> > > --- a/Documentation/gpu/drm-kms.rst
> > > +++ b/Documentation/gpu/drm-kms.rst
> > > @@ -508,6 +508,18 @@ Standard Connector Properties
> > >   .. kernel-doc:: drivers/gpu/drm/drm_connector.c
> > >      :doc: standard connector properties
> > > +Standard HDMI Properties
> > > +-----------------------------
> > > +
> > > +.. kernel-doc:: drivers/gpu/drm/drm_connector.c
> > > +   :doc: hdmi_output_format
> > > +
> > > +.. kernel-doc:: drivers/gpu/drm/drm_connector.c
> > > +   :doc: aspect ratio property
> > I'd have just created 1 DOC: section titled "standard HDMI properties" and
> > listed all of them in 1 comment block. People often forget to add the
> > include stanza in the .rst files, having bigger comments helps with that.
> > 
> > But feel free to go either way.
> Yes, this would be easier for me too, but this means I will have to add all
> the documentation in one place, in one file, whether the respective
> property is created at that place or not. I am not sure if everyone would be
> ok with that during review. But if you think we should go ahead,
> thanks for easing this up for me :-).

It might result in a minor merge conflict, but nothing bad should happen
if we put all the docs into one section.

> > > +.. kernel-doc:: drivers/gpu/drm/i915/intel_modes.c
> > > +   :doc: Broadcast RGB property
> > Please no generic properties documented in driver code.
> Broadcast RGB property is created here, and also, while I was adding
> documentation for it, I realized its kept in dev_priv, which is specific to
> I915 driver, So its not generic too. I was not sure if that will be OK, if I
> add an Intel specific property's description in DRM layer ?

It should be generic, but oh well it isn't. Either document it in the
core, or we'll leave this to the future when the create helper gets
extracted to the core.

> > > +
> > >   Plane Composition Properties
> > >   ----------------------------
> > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > > index 09ca662..adcb89d 100644
> > > --- a/drivers/gpu/drm/drm_atomic.c
> > > +++ b/drivers/gpu/drm/drm_atomic.c
> > > @@ -1192,6 +1192,8 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
> > >   		state->picture_aspect_ratio = val;
> > >   	} else if (property == connector->scaling_mode_property) {
> > >   		state->scaling_mode = val;
> > > +	} else if (property == config->hdmi_output_property) {
> > > +		state->hdmi_output = val;
> > >   	} else if (connector->funcs->atomic_set_property) {
> > >   		return connector->funcs->atomic_set_property(connector,
> > >   				state, property, val);
> > > @@ -1272,6 +1274,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
> > >   		*val = state->picture_aspect_ratio;
> > >   	} else if (property == connector->scaling_mode_property) {
> > >   		*val = state->scaling_mode;
> > > +	} else if (property == config->hdmi_output_property) {
> > > +		*val = state->hdmi_output;
> > >   	} else if (connector->funcs->atomic_get_property) {
> > >   		return connector->funcs->atomic_get_property(connector,
> > >   				state, property, val);
> > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > > index 23e4661..2e7459f 100644
> > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > @@ -637,6 +637,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> > >   			if (old_connector_state->link_status !=
> > >   			    new_connector_state->link_status)
> > >   				new_crtc_state->connectors_changed = true;
> > > +
> > > +			if (old_connector_state->hdmi_output !=
> > > +			    new_connector_state->hdmi_output)
> > > +				new_crtc_state->connectors_changed = true;
> > >   		}
> > >   		if (funcs->atomic_check)
> > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > > index 8072e6e..8357918 100644
> > > --- a/drivers/gpu/drm/drm_connector.c
> > > +++ b/drivers/gpu/drm/drm_connector.c
> > > @@ -227,6 +227,11 @@ int drm_connector_init(struct drm_device *dev,
> > >   					      config->edid_property,
> > >   					      0);
> > > +	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
> > > +		drm_object_attach_property(&connector->base,
> > > +					   config->hdmi_output_property,
> > > +					   0);
> > > +
> > >   	drm_object_attach_property(&connector->base,
> > >   				      config->dpms_property, 0);
> > > @@ -617,6 +622,26 @@ static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> > >   };
> > >   DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> > > +static const struct drm_prop_enum_list drm_hdmi_output_enum_list[] = {
> > > +	{ DRM_HDMI_OUTPUT_DEFAULT_RGB, "output_rgb" },
> > > +	{ DRM_HDMI_OUTPUT_YCBCR444, "output_ycbcr444" },
> > > +	{ DRM_HDMI_OUTPUT_YCBCR422, "output_ycbcr422" },
> > > +	{ DRM_HDMI_OUTPUT_YCBCR420, "output_ycbcr420" },
> > > +	{ DRM_HDMI_OUTPUT_YCBCR_HQ, "output_ycbcr_high_subsampling" },
> > > +	{ DRM_HDMI_OUTPUT_YCBCR_LQ, "output_ycbcr_low_subsampling" },
> > > +	{ DRM_HDMI_OUTPUT_INVALID, "invalid_output" },
> > > +};
> > > +
> > > +/**
> > > + * drm_get_hdmi_output_name - return a string for a given hdmi output enum
> > > + * @type: enum of output type
> > > + */
> > > +const char *drm_get_hdmi_output_name(enum drm_hdmi_output_type type)
> > > +{
> > > +	return drm_hdmi_output_enum_list[type].name;
> > > +}
> > > +EXPORT_SYMBOL(drm_get_hdmi_output_name);
> > > +
> > >   /**
> > >    * drm_display_info_set_bus_formats - set the supported bus formats
> > >    * @info: display info to store bus formats in
> > > @@ -697,7 +722,36 @@ static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
> > >   	{ DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
> > >   };
> > >   DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
> > > -		 drm_tv_subconnector_enum_list)
> > > +		 drm_tv_subconnector_enum_list);
> > > +
> > > +/**
> > > + * DOC: hdmi_output_format
> > > + *
> > > + * hdmi_output_format:
> > > + *	Enum property which allows a userspace to provide its preference for a
> > > + *	HDMI output format. Standard HDMI 1.4b outputs can support RGB/YCBCR444
> > > + *	YCBCR422 output formats, whereas HDMI 2.0 outputs can additionally
> > > + *	support YCBCR420 output. Default value of the property is HDMI output
> > > + *	RGB.
> > > + *
> > > + *	A driver can attach to this property, and then handle the HDMI output
> > > + *	based on its capabilities and sink support. There are few helper
> > > + *	functions available in drm_modes.c which can help in finding the best
> > > + *	suitable output considering a sink/source/mode combination. Refer to
> > > + *	drm_modes.c:drm_display_info_hdmi_output_type()
> > > + */
> > > +int drm_connector_create_hdmi_properties(struct drm_device *dev)
> > > +{
> > > +	struct drm_property *prop;
> > > +
> > > +	prop = drm_property_create_enum(dev, 0, "hdmi_output_format",
> > > +					drm_hdmi_output_enum_list,
> > > +					ARRAY_SIZE(drm_hdmi_output_enum_list));
> > > +	if (!prop)
> > > +		return -ENOMEM;
> > > +	dev->mode_config.hdmi_output_property = prop;
> > > +	return 0;
> > > +}
> > >   /**
> > >    * DOC: standard connector properties
> > > @@ -1024,6 +1078,19 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
> > >   }
> > >   EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
> > > +
> > > +/**
> > > + * DOC: aspect ratio property
> > > + *
> > > + * aspect ratio:
> > > + *	Enum property to override the HDMI output's aspect ratio.
> > > + *	When this property is set, the aspect ratio of the frame in
> > > + *	AVI infoframes is set as per the property value. For example
> > > + *	if userspace sets the property value to DRM_MODE_PICTURE_ASPECT_4_3
> > > + *	the output aspect ratio is set to 4:3 (regardless of the PAR of mode)
> > Would be good to document all possible values. Same for the other
> > properties, plus insert a link to the function that creates the property
> > (where we have that).
> This is the part, which makes me feel that I should create this patch
> separately, as this seems like slightly bigger cleanup than
> I thought, so I dont want this to be a part of HDMI 2.0 series.

Writing good docs is hard work, but it's part of creating a new uapi :-)
But yeah you can split out the overall cleanup if you think that's easier
(it'll probably result in some fun small conflicts).

> > 
> > > + *
> > > + */
> > > +
> > >   /**
> > >    * drm_mode_create_aspect_ratio_property - create aspect ratio property
> > >    * @dev: DRM device
> > > diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
> > > index d077c54..e6c4adc 100644
> > > --- a/drivers/gpu/drm/drm_crtc_internal.h
> > > +++ b/drivers/gpu/drm/drm_crtc_internal.h
> > > @@ -140,6 +140,7 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
> > >   				    struct drm_property *property,
> > >   				    uint64_t value);
> > >   int drm_connector_create_standard_properties(struct drm_device *dev);
> > > +int drm_connector_create_hdmi_properties(struct drm_device *dev);
> > >   const char *drm_get_connector_force_name(enum drm_connector_force force);
> > >   /* IOCTL */
> > > diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> > > index d986225..3ba9262 100644
> > > --- a/drivers/gpu/drm/drm_mode_config.c
> > > +++ b/drivers/gpu/drm/drm_mode_config.c
> > > @@ -210,6 +210,10 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
> > >   	if (ret)
> > >   		return ret;
> > > +	ret = drm_connector_create_hdmi_properties(dev);
> > > +	if (ret)
> > > +		return ret;
> > We still create all the property values instead of just the ones that the
> > source hw supports. E.g. aspect ratio property is only created if needed,
> > not unconditionally on all connectors.
> > 
> > Note that users see properties through xrandr and the gui screen
> > configuration tools, adding properties that never do anything is
> > confusing, more for properties where you can select invalid values.
> If I understood this properly, you want me to create the property in I915
> layer, just before attaching it to object (similar to aspect ratio and
> others)
> something like:
> intel_attach_hdmi_output_property()
> {
>       if (!mode_config->hdmi_output_property)
>                    mode_config->hdmi_output_property = create_prop();
>         now_attach_property();
> }

Yes.

> I was assuming that once other drivers move to HDMI 2.0, they might all need
> this for YCBCR420 outputs, so it would be ok to create it generically.
> But at the same time, this also seems like a good idea.

gen8 isn't going to magically support hdmi2.0. We shouldn't advertise it
to users either. Same holds for other drivers and other features. Having a
generic/shared function to create it is good, but automically creating
something that on many drivers/platforms does nothing is not good, that
only confuses users (and userspace programmers).

Cheers, Daniel

> 
> - Shashank
> > > +
> > >   	prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
> > >   					"type", drm_plane_type_enum_list,
> > >   					ARRAY_SIZE(drm_plane_type_enum_list));
> > > diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
> > > index 951e834..d07de45 100644
> > > --- a/drivers/gpu/drm/i915/intel_modes.c
> > > +++ b/drivers/gpu/drm/i915/intel_modes.c
> > > @@ -104,6 +104,19 @@ static const struct drm_prop_enum_list broadcast_rgb_names[] = {
> > >   	{ INTEL_BROADCAST_RGB_LIMITED, "Limited 16:235" },
> > >   };
> > > +/**
> > > + * DOC: Broadcast RGB property
> > > + *
> > > + * Broadcast RGB:
> > > + *	Enum property to indicate RGB color range of a HDMI output.
> > > + *	For limited range RGB outputs, a remapping of pixel values from 0-255
> > > + *	should be remaped to a range of 16-235. When this property is set to
> > > + *	Limited 16:235 and CTM is set, the hardware will be programmed with the
> > > + *	result of the multiplication of CTM by the limited  range matrix, to
> > > + *	ensure the pixels normaly in the range 0..1.0 are remapped to the range
> > > + *	16/255..235/255.
> > > + *
> > > + */
> > >   void
> > >   intel_attach_broadcast_rgb_property(struct drm_connector *connector)
> > >   {
> > > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > > index 4bc0882..3773600 100644
> > > --- a/include/drm/drm_connector.h
> > > +++ b/include/drm/drm_connector.h
> > > @@ -319,6 +319,17 @@ struct drm_tv_connector_state {
> > >   	unsigned int hue;
> > >   };
> > > +/* HDMI output pixel format */
> > > +enum drm_hdmi_output_type {
> > > +	DRM_HDMI_OUTPUT_DEFAULT_RGB, /* default RGB */
> > > +	DRM_HDMI_OUTPUT_YCBCR444, /* YCBCR 444 */
> > > +	DRM_HDMI_OUTPUT_YCBCR422, /* YCBCR 422 */
> > > +	DRM_HDMI_OUTPUT_YCBCR420, /* YCBCR 420 */
> > > +	DRM_HDMI_OUTPUT_YCBCR_HQ, /* Highest subsampled YUV */
> > > +	DRM_HDMI_OUTPUT_YCBCR_LQ, /* Lowest subsampled YUV */
> > > +	DRM_HDMI_OUTPUT_INVALID, /* Guess what ? */
> > > +};
> > > +
> > >   /**
> > >    * struct drm_connector_state - mutable connector state
> > >    * @connector: backpointer to the connector
> > > @@ -363,6 +374,12 @@ struct drm_connector_state {
> > >   	 * upscaling, mostly used for built-in panels.
> > >   	 */
> > >   	unsigned int scaling_mode;
> > > +
> > > +	/**
> > > +	 * @hdmi_output: Connector property to control the
> > > +	 * HDMI output mode (RGB/YCBCR444/422/420).
> > > +	 */
> > > +	enum drm_hdmi_output_type hdmi_output;
> > >   };
> > >   /**
> > > @@ -991,6 +1008,7 @@ static inline void drm_connector_unreference(struct drm_connector *connector)
> > >   const char *drm_get_connector_status_name(enum drm_connector_status status);
> > >   const char *drm_get_subpixel_order_name(enum subpixel_order order);
> > > +const char *drm_get_hdmi_output_name(enum drm_hdmi_output_type type);
> > >   const char *drm_get_dpms_name(int val);
> > >   const char *drm_get_dvi_i_subconnector_name(int val);
> > >   const char *drm_get_dvi_i_select_name(int val);
> > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > > index 4298171..1887261 100644
> > > --- a/include/drm/drm_mode_config.h
> > > +++ b/include/drm/drm_mode_config.h
> > > @@ -740,6 +740,11 @@ struct drm_mode_config {
> > >   	 * the position of the output on the host's screen.
> > >   	 */
> > >   	struct drm_property *suggested_y_property;
> > > +	/**
> > > +	 * @hdmi_output_property: output pixel format from HDMI display
> > > +	 * Default is set for RGB
> > > +	 */
> > > +	struct drm_property *hdmi_output_property;
> > >   	/* dumb ioctl parameters */
> > >   	uint32_t preferred_depth, prefer_shadow;
> > > -- 
> > > 2.7.4
> > > 
> > > _______________________________________________
> > > dri-devel mailing list
> > > dri-devel at lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the dri-devel mailing list