[PATCH v3 1/3] drm/connector: Add generic underscan properties

Brian Starkey Brian.Starkey at arm.com
Thu Nov 22 17:36:58 UTC 2018


Hi Boris,

Just because I happened to read the docs in here, one typo below:

On Thu, Nov 22, 2018 at 12:23:29PM +0100, Boris Brezillon wrote:
>We have 3 drivers defining the "underscan", "underscan hborder" and
>"underscan vborder" properties (radeon, amd and nouveau) and we are
>about to add the same kind of thing in VC4.
>
>Define generic underscan props and add new fields to the drm_connector
>state so that the property parsing logic can be shared by all DRM
>drivers.
>
>A driver can now attach underscan properties to its connector through
>the drm_connector_attach_underscan_properties() helper, and can
>check/apply the underscan setup based on the
>drm_connector_state->underscan fields.
>
>Signed-off-by: Boris Brezillon <boris.brezillon at bootlin.com>
>---
>Changes in v3:
>- None
>
>Changes in v2:
>- Add a new section in the connector props doc to describe underscan
>  props
>- Fix description of auto mode (auto means apply underscan for HDMI
>  monitors only)
>- Fix description of vborder/hborder:
>    right_border = left_border = hborder
>    top_border = bottom_border = vborder
>  not
>    right_border = left_border = hborder / 2
>    top_border = bottom_border = vborder / 2
>- Rename drm_underscan into drm_underscan_state
>---
> drivers/gpu/drm/drm_atomic_uapi.c |  12 +++
> drivers/gpu/drm/drm_connector.c   | 127 ++++++++++++++++++++++++++++++
> include/drm/drm_connector.h       |  80 +++++++++++++++++++
> 3 files changed, 219 insertions(+)
>
>diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
>index d5b7f315098c..39db6e31c565 100644
>--- a/drivers/gpu/drm/drm_atomic_uapi.c
>+++ b/drivers/gpu/drm/drm_atomic_uapi.c
>@@ -740,6 +740,12 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
>
> 		return set_out_fence_for_connector(state->state, connector,
> 						   fence_ptr);
>+	} else if (property == connector->underscan_mode_property) {
>+		state->underscan.mode = val;
>+	} else if (property == connector->underscan_hborder_property) {
>+		state->underscan.hborder = val;
>+	} else if (property == connector->underscan_vborder_property) {
>+		state->underscan.vborder = val;
> 	} else if (connector->funcs->atomic_set_property) {
> 		return connector->funcs->atomic_set_property(connector,
> 				state, property, val);
>@@ -799,6 +805,12 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
> 		*val = state->scaling_mode;
> 	} else if (property == connector->content_protection_property) {
> 		*val = state->content_protection;
>+	} else if (property == connector->underscan_mode_property) {
>+		*val = state->underscan.mode;
>+	} else if (property == connector->underscan_hborder_property) {
>+		*val = state->underscan.hborder;
>+	} else if (property == connector->underscan_vborder_property) {
>+		*val = state->underscan.vborder;
> 	} else if (property == config->writeback_fb_id_property) {
> 		/* Writeback framebuffer is one-shot, write and forget */
> 		*val = 0;
>diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>index c555e17ab8d7..170317248da6 100644
>--- a/drivers/gpu/drm/drm_connector.c
>+++ b/drivers/gpu/drm/drm_connector.c
>@@ -971,6 +971,38 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
>  *	can also expose this property to external outputs, in which case they
>  *	must support "None", which should be the default (since external screens
>  *	have a built-in scaler).
>+ *
>+ * Connectors for non-analog outputs may also have standardized underscan
>+ * properties (drivers can set this up by calling
>+ * drm_connector_attach_content_protection_property() on initialization):

Should be drm_connector_attach_underscan_properties()

Cheers,
-Brian

>+ *
>+ * underscan:
>+ *	This properties defines whether underscan is activated or not, and when
>+ *	it is activated, how the horizontal and vertical borders are calculated:
>+ *
>+ *	off:
>+ *		Underscan is disabled. The output image shouldn't be scaled to
>+ *		take screen borders into account.
>+ *	on:
>+ *		Underscan is activated and horizontal and vertical borders are
>+ *		specified through the "underscan hborder" and
>+ *		"underscan vborder" properties.
>+ *	auto:
>+ *		Underscan is activated only for HDMI monitors.
>+ *
>+ * underscan hborder:
>+ *	Horizontal border expressed in pixels. The border is symmetric, which
>+ *	means you'll have a border of 'hborder' pixels on the left and on the
>+ *	same border on the right.
>+ *	When this value is 0 and underscan is "on" or "auto", the driver will
>+ *	pick a default value (the default value is driver dependent).
>+ *
>+ * underscan vborder:
>+ *	Vertical border expressed in pixels. The border is symmetric, which
>+ *	means you'll have a border of 'vborder' pixels on the top and the same
>+ *	border on the bottom.
>+ *	When this value is 0 and underscan is "on" or "auto", the driver will
>+ *	pick a default value (the default value is driver dependent).
>  */
>
> int drm_connector_create_standard_properties(struct drm_device *dev)
>@@ -1241,6 +1273,101 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> }
> EXPORT_SYMBOL(drm_mode_create_tv_properties);
>
>+static const struct drm_prop_enum_list drm_underscan_mode_enum_list[] = {
>+	{ DRM_UNDERSCAN_OFF, "off" },
>+	{ DRM_UNDERSCAN_ON, "on" },
>+	{ DRM_UNDERSCAN_AUTO, "auto" },
>+};
>+
>+/**
>+ * drm_connector_attach_underscan_properties - attach atomic underscan
>+ *					       properties
>+ * @connector: connector to attach underscan mode properties on.
>+ * @mode_mask: bitmask of %DRM_UNDERSCAN_XX modes encoding the supported
>+ *	       underscan modes.
>+ * @max_hborder: maximum size of the horizontal border expressed in pixels.
>+ *		 Should be > 0.
>+ * @max_vborder: maximum size of the vertical border expressed in pixels.
>+ *		 Should be > 0.
>+ *
>+ * This is used to add support for underscan to atomic drivers.
>+ * The underscan config will be set to &drm_connector_state.underscan
>+ * and can be used from &drm_connector_helper_funcs->atomic_check for
>+ * validation.
>+ *
>+ * Returns:
>+ * Zero on success, negative errno on failure.
>+ */
>+int drm_connector_attach_underscan_properties(struct drm_connector *connector,
>+					      u32 mode_mask, u64 max_hborder,
>+					      u64 max_vborder)
>+{
>+	unsigned int i, nmodes = ARRAY_SIZE(drm_underscan_mode_enum_list);
>+	struct drm_device *dev = connector->dev;
>+	struct drm_property *prop;
>+
>+	if (!max_hborder || !max_vborder)
>+		return -EINVAL;
>+
>+	if (!hweight32(mode_mask) || (mode_mask & ~GENMASK(nmodes - 1, 0)))
>+		return -EINVAL;
>+
>+	prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, "underscan",
>+				   hweight32(mode_mask));
>+	if (!prop)
>+		return -ENOMEM;
>+
>+	for (i = 0; i < ARRAY_SIZE(drm_underscan_mode_enum_list); i++) {
>+		const struct drm_prop_enum_list *entry;
>+		int ret;
>+
>+		if (!(BIT(i) & mode_mask))
>+			continue;
>+
>+		entry = &drm_underscan_mode_enum_list[i];
>+		ret = drm_property_add_enum(prop, entry->type, entry->name);
>+		if (ret)
>+			goto err_free_mode_prop;
>+	}
>+
>+	connector->underscan_mode_property = prop;
>+
>+	prop = drm_property_create_range(dev, 0, "underscan hborder", 0,
>+					 max_hborder);
>+	if (!prop)
>+		goto err_free_mode_prop;
>+
>+	connector->underscan_hborder_property = prop;
>+
>+	prop = drm_property_create_range(dev, 0, "underscan vborder", 0,
>+					 max_vborder);
>+	if (!prop)
>+		goto err_free_hborder_prop;
>+
>+	connector->underscan_vborder_property = prop;
>+
>+	drm_object_attach_property(&connector->base,
>+				   connector->underscan_mode_property,
>+				   DRM_UNDERSCAN_OFF);
>+	drm_object_attach_property(&connector->base,
>+				   connector->underscan_hborder_property, 0);
>+	drm_object_attach_property(&connector->base,
>+				   connector->underscan_vborder_property, 0);
>+
>+	return 0;
>+
>+err_free_hborder_prop:
>+	drm_property_destroy(dev, connector->underscan_hborder_property);
>+	connector->underscan_hborder_property = NULL;
>+
>+err_free_mode_prop:
>+	drm_property_destroy(dev, connector->underscan_mode_property);
>+	connector->underscan_mode_property = NULL;
>+
>+	return -ENOMEM;
>+}
>+EXPORT_SYMBOL(drm_connector_attach_underscan_properties);
>+
> /**
>  * drm_mode_create_scaling_mode_property - create scaling mode property
>  * @dev: DRM device
>diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>index 5b3cf909fd5e..14d423dc7a14 100644
>--- a/include/drm/drm_connector.h
>+++ b/include/drm/drm_connector.h
>@@ -377,6 +377,53 @@ struct drm_tv_connector_state {
> 	unsigned int hue;
> };
>
>+/**
>+ * enum drm_underscan_mode - Underscan mode
>+ *
>+ * This enum is used to track the underscan mode.
>+ *
>+ * @DRM_UNDERSCAN_OFF: No underscan applied, the output image will be unchanged
>+ * @DRM_UNDERSCAN_ON: Underscan is enabled, and horizontal/vertical border size
>+ *		      are specified through the &struct_drm_underscan->hborder
>+ *		      and &struct_drm_underscan->vborder fields.
>+ * @DRM_UNDERSCAN_AUTO: Underscan is enabled and &struct_drm_underscan->hborder
>+ *			and &struct_drm_underscan->vborder are guessed by the
>+ *			driver.
>+ */
>+enum drm_underscan_mode {
>+	DRM_UNDERSCAN_OFF,
>+	DRM_UNDERSCAN_ON,
>+	DRM_UNDERSCAN_AUTO,
>+};
>+
>+/**
>+ * struct drm_underscan_state - Underscan properties attached to a connector
>+ *				state
>+ *
>+ * This can be used to tell the CRTC how the image should be scaled/placed in
>+ * order to cover fit in the display connected through this connector. Most of
>+ * the time used to address situations where the display borders are hidden.
>+ * Can also be used to compensate overscan done on the display side.
>+ */
>+struct drm_underscan_state {
>+	/**
>+	 * @mode: Underscan mode.
>+	 */
>+	enum drm_underscan_mode mode;
>+
>+	/**
>+	 * @hborder: Horizontal border. This values encodes both the left and
>+	 * right borders: left_border = right_border = hborder / 2.
>+	 */
>+	unsigned int hborder;
>+
>+	/**
>+	 * @vborder: Vertical border. This values encodes both the top and
>+	 * bottom borders: top_border = bottom_border = vborder / 2.
>+	 */
>+	unsigned int vborder;
>+};
>+
> /**
>  * struct drm_connector_state - mutable connector state
>  */
>@@ -461,6 +508,13 @@ struct drm_connector_state {
> 	 * drm_writeback_signal_completion()
> 	 */
> 	struct drm_writeback_job *writeback_job;
>+
>+	/**
>+	 * @underscan: Underscan information. Most commonly used to adjust
>+	 * image when the display has borders covering part of the image of
>+	 * when it's doing overscan on its own.
>+	 */
>+	struct drm_underscan_state underscan;
> };
>
> /**
>@@ -924,6 +978,29 @@ struct drm_connector {
> 	 */
> 	struct drm_property_blob *path_blob_ptr;
>
>+	/**
>+	 * @underscan_mode_property: Optional connector underscan mode. Used by
>+	 * the driver to scale the output image and compensate an overscan done
>+	 * on the display side.
>+	 */
>+	struct drm_property *underscan_mode_property;
>+
>+	/**
>+	 * @underscan_hborder_property: Optional connector underscan horizontal
>+	 * border (expressed in pixels). Used by the driver to adjust the
>+	 * output image position and compensate an overscan done on the display
>+	 * side.
>+	 */
>+	struct drm_property *underscan_hborder_property;
>+
>+	/**
>+	 * @underscan_hborder_property: Optional connector underscan vertical
>+	 * border (expressed in pixels). Used by the driver to adjust the
>+	 * output image position and compensate an overscan done on the display
>+	 * side.
>+	 */
>+	struct drm_property *underscan_vborder_property;
>+
> #define DRM_CONNECTOR_POLL_HPD (1 << 0)
> #define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
> #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
>@@ -1180,6 +1257,9 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev);
> int drm_mode_create_tv_properties(struct drm_device *dev,
> 				  unsigned int num_modes,
> 				  const char * const modes[]);
>+int drm_connector_attach_underscan_properties(struct drm_connector *connector,
>+					      u32 mode_mask, u64 max_hborder,
>+					      u64 max_vborder);
> int drm_mode_create_scaling_mode_property(struct drm_device *dev);
> int drm_connector_attach_content_type_property(struct drm_connector *dev);
> int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
>-- 
>2.17.1
>
>_______________________________________________
>dri-devel mailing list
>dri-devel at lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list