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.rip...@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; > _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel