[PATCH v2 4/5] drm/modes: Parse overscan properties

Noralf Trønnes noralf at tronnes.org
Tue Apr 16 14:52:20 UTC 2019



Den 11.04.2019 15.22, skrev Maxime Ripard:
> Properly configuring the overscan properties might be needed for the
> initial setup of the framebuffer for display that still have overscan.
> Let's allow for more properties on the kernel command line to setup each
> margin.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard at bootlin.com>
> ---
>  drivers/gpu/drm/drm_fb_helper.c | 47 ++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/drm_modes.c     | 44 ++++++++++++++++++++++++++++++++-
>  include/drm/drm_connector.h     |  1 +-
>  3 files changed, 92 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index 8781897559b2..4e403fe1f451 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -2567,6 +2567,51 @@ static void drm_setup_crtc_rotation(struct drm_fb_helper *fb_helper,
>  	fb_helper->sw_rotations |= DRM_MODE_ROTATE_0;
>  }
>  
> +static void drm_setup_connector_margins(struct drm_connector *connector)
> +{
> +	struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
> +	struct drm_modeset_acquire_ctx ctx;
> +	struct drm_atomic_state *state;
> +	struct drm_device *dev = connector->dev;
> +	int ret;
> +
> +	if (!drm_drv_uses_atomic_modeset(dev))
> +		return;
> +
> +	drm_modeset_acquire_init(&ctx, 0);
> +
> +	state = drm_atomic_state_alloc(dev);
> +	state->acquire_ctx = &ctx;
> +
> +retry:
> +	drm_atomic_set_property(state, &connector->base,
> +				dev->mode_config.tv_left_margin_property,
> +				cmdline->overscan_left);
> +
> +	drm_atomic_set_property(state, &connector->base,
> +				dev->mode_config.tv_right_margin_property,
> +				cmdline->overscan_right);
> +
> +	drm_atomic_set_property(state, &connector->base,
> +				dev->mode_config.tv_top_margin_property,
> +				cmdline->overscan_top);
> +
> +	drm_atomic_set_property(state, &connector->base,
> +				dev->mode_config.tv_bottom_margin_property,
> +				cmdline->overscan_bottom);
> +
> +	ret = drm_atomic_commit(state);
> +	if (ret == -EDEADLK) {
> +		drm_atomic_state_clear(state);
> +		drm_modeset_backoff(&ctx);
> +		goto retry;
> +	}
> +
> +	drm_atomic_state_put(state);
> +	drm_modeset_drop_locks(&ctx);
> +	drm_modeset_acquire_fini(&ctx);
> +}
> +

Should we set these property values in drm_connector_init()?
I assume that DRM userspace would want to use these values as well.

Noralf.

>  static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
>  			    u32 width, u32 height)
>  {
> @@ -2680,6 +2725,8 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
>  		struct drm_connector *connector =
>  					fb_helper->connector_info[i]->connector;
>  
> +		drm_setup_connector_margins(connector);
> +
>  		/* use first connected connector for the physical dimensions */
>  		if (connector->status == connector_status_connected) {
>  			info->var.width = connector->display_info.width_mm;
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index ac8d70b92b62..493ba3ccde70 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1586,6 +1586,50 @@ static int drm_mode_parse_cmdline_options(char *str, size_t len,
>  		} else if (!strncmp(option, "reflect_y", delim - option)) {
>  			rotation |= DRM_MODE_REFLECT_Y;
>  			sep = delim;
> +		} else if (!strncmp(option, "overscan_right", delim - option)) {
> +			const char *value = delim + 1;
> +			unsigned int margin;
> +
> +			margin = simple_strtol(value, &sep, 10);
> +
> +			/* Make sure we have parsed something */
> +			if (sep == value)
> +				return -EINVAL;
> +
> +			mode->overscan_right = margin;
> +		} else if (!strncmp(option, "overscan_left", delim - option)) {
> +			const char *value = delim + 1;
> +			unsigned int margin;
> +
> +			margin = simple_strtol(value, &sep, 10);
> +
> +			/* Make sure we have parsed something */
> +			if (sep == value)
> +				return -EINVAL;
> +
> +			mode->overscan_left = margin;
> +		} else if (!strncmp(option, "overscan_top", delim - option)) {
> +			const char *value = delim + 1;
> +			unsigned int margin;
> +
> +			margin = simple_strtol(value, &sep, 10);
> +
> +			/* Make sure we have parsed something */
> +			if (sep == value)
> +				return -EINVAL;
> +
> +			mode->overscan_top = margin;
> +		} else if (!strncmp(option, "overscan_bottom", delim - option)) {
> +			const char *value = delim + 1;
> +			unsigned int margin;
> +
> +			margin = simple_strtol(value, &sep, 10);
> +
> +			/* Make sure we have parsed something */
> +			if (sep == value)
> +				return -EINVAL;
> +
> +			mode->overscan_bottom = margin;
>  		} else {
>  			return -EINVAL;
>  		}
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index dfe7f2304b35..44d9885dd401 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -903,6 +903,7 @@ struct drm_cmdline_mode {
>  	int xres, yres;
>  	int bpp;
>  	int refresh;
> +	int overscan_right, overscan_top, overscan_left, overscan_bottom;
>  	bool rb;
>  	bool interlace;
>  	bool cvt;
> 


More information about the dri-devel mailing list