[Intel-gfx] [PATCH] drm: Perform cmdline mode parsing during connector initialisation
Rodrigo Vivi
rodrigo.vivi at gmail.com
Mon Jul 14 20:47:54 CEST 2014
When getting this patch for -collector I noticed it conflicts with mgag200
and break its compilation.
On Wed, Jun 11, 2014 at 3:55 AM, Chris Wilson <chris at chris-wilson.co.uk>
wrote:
> i915.ko has a custom fbdev initialisation routine that aims to preserve
> the current mode set by the BIOS, unless overruled by the user. The
> user's wishes are determined by what, if any, mode is specified on the
> command line (via the video= parameter). However, that command line mode
> is first parsed by drm_fb_helper_initial_config() which is called after
> i915.ko's custom initial_config() as a fallback method. So in order for
> us to honour it, we need to move the cmdline parser earlier. If we
> perform the connector cmdline parsing as soon as we initialise the
> connector, that cmdline mode and forced status is then available even if
> the fbdev helper is not compiled in or never called.
>
> We also then expose the cmdline user mode in the connector mode lists.
>
> v2: Rebase after connector->name upheaval.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=73154
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Jesse Barnes <jbarnes at virtuousgeek.org>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> Reviewed-by: Jesse Barnes <jbarnes at virtuousgeek.org>
> Cc: dri-devel at lists.freedesktop.org
> ---
> drivers/gpu/drm/drm_crtc.c | 55 ++++++++++++++++++++++++++++++++
> drivers/gpu/drm/drm_fb_helper.c | 64
> ++------------------------------------
> drivers/gpu/drm/drm_modes.c | 1 +
> drivers/gpu/drm/drm_probe_helper.c | 17 ++++++++++
> include/drm/drm_crtc.h | 1 +
> include/drm/drm_fb_helper.h | 1 -
> 6 files changed, 77 insertions(+), 62 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index fe94cc10cd35..b9de156515b6 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -819,6 +819,59 @@ static void drm_mode_remove(struct drm_connector
> *connector,
> }
>
> /**
> + * drm_connector_get_cmdline_mode - reads the user's cmdline mode
> + * @connector: connector to quwery
> + * @mode: returned mode
> + *
> + * The kernel supports per-connector configration of its consoles through
> + * use of the video= parameter. This function parses that option and
> + * extracts the user's specified mode (or enable/disable status) for a
> + * particular connector. This is typically only used during the early
> fbdev
> + * setup.
> + */
> +static void drm_connector_get_cmdline_mode(struct drm_connector
> *connector)
> +{
> + struct drm_cmdline_mode *mode = &connector->cmdline_mode;
> + char *option = NULL;
> +
> + if (fb_get_options(connector->name, &option))
> + return;
> +
> + if (!drm_mode_parse_command_line_for_connector(option,
> + connector,
> + mode))
> + return;
> +
> + if (mode->force) {
> + const char *s;
> +
> + switch (mode->force) {
> + case DRM_FORCE_OFF:
> + s = "OFF";
> + break;
> + case DRM_FORCE_ON_DIGITAL:
> + s = "ON - dig";
> + break;
> + default:
> + case DRM_FORCE_ON:
> + s = "ON";
> + break;
> + }
> +
> + DRM_INFO("forcing %s connector %s\n", connector->name, s);
> + connector->force = mode->force;
> + }
> +
> + DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
> + connector->name,
> + mode->xres, mode->yres,
> + mode->refresh_specified ? mode->refresh : 60,
> + mode->rb ? " reduced blanking" : "",
> + mode->margins ? " with margins" : "",
> + mode->interlace ? " interlaced" : "");
> +}
> +
> +/**
> * drm_connector_init - Init a preallocated connector
> * @dev: DRM device
> * @connector: the connector to init
> @@ -870,6 +923,8 @@ int drm_connector_init(struct drm_device *dev,
> connector->edid_blob_ptr = NULL;
> connector->status = connector_status_unknown;
>
> + drm_connector_get_cmdline_mode(connector);
> +
> list_add_tail(&connector->head, &dev->mode_config.connector_list);
> dev->mode_config.num_connector++;
>
> diff --git a/drivers/gpu/drm/drm_fb_helper.c
> b/drivers/gpu/drm/drm_fb_helper.c
> index d5d8cea1a679..18988dc3de91 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -105,60 +105,6 @@ fail:
> }
> EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
>
> -static int drm_fb_helper_parse_command_line(struct drm_fb_helper
> *fb_helper)
> -{
> - struct drm_fb_helper_connector *fb_helper_conn;
> - int i;
> -
> - for (i = 0; i < fb_helper->connector_count; i++) {
> - struct drm_cmdline_mode *mode;
> - struct drm_connector *connector;
> - char *option = NULL;
> -
> - fb_helper_conn = fb_helper->connector_info[i];
> - connector = fb_helper_conn->connector;
> - mode = &fb_helper_conn->cmdline_mode;
> -
> - /* do something on return - turn off connector maybe */
> - if (fb_get_options(connector->name, &option))
> - continue;
> -
> - if (drm_mode_parse_command_line_for_connector(option,
> - connector,
> - mode)) {
> - if (mode->force) {
> - const char *s;
> - switch (mode->force) {
> - case DRM_FORCE_OFF:
> - s = "OFF";
> - break;
> - case DRM_FORCE_ON_DIGITAL:
> - s = "ON - dig";
> - break;
> - default:
> - case DRM_FORCE_ON:
> - s = "ON";
> - break;
> - }
> -
> - DRM_INFO("forcing %s connector %s\n",
> - connector->name, s);
> - connector->force = mode->force;
> - }
> -
> - DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@
> %dHz%s%s%s\n",
> - connector->name,
> - mode->xres, mode->yres,
> - mode->refresh_specified ?
> mode->refresh : 60,
> - mode->rb ? " reduced blanking" : "",
> - mode->margins ? " with margins" : "",
> - mode->interlace ? " interlaced" :
> "");
> - }
> -
> - }
> - return 0;
> -}
> -
> static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct
> drm_fb_helper *helper)
> {
> uint16_t *r_base, *g_base, *b_base;
> @@ -936,7 +882,7 @@ static int drm_fb_helper_single_fb_probe(struct
> drm_fb_helper *fb_helper,
> struct drm_fb_helper_connector *fb_helper_conn =
> fb_helper->connector_info[i];
> struct drm_cmdline_mode *cmdline_mode;
>
> - cmdline_mode = &fb_helper_conn->cmdline_mode;
> + cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
>
> if (cmdline_mode->bpp_specified) {
> switch (cmdline_mode->bpp) {
> @@ -1184,9 +1130,7 @@ EXPORT_SYMBOL(drm_has_preferred_mode);
>
> static bool drm_has_cmdline_mode(struct drm_fb_helper_connector
> *fb_connector)
> {
> - struct drm_cmdline_mode *cmdline_mode;
> - cmdline_mode = &fb_connector->cmdline_mode;
> - return cmdline_mode->specified;
> + return fb_connector->connector->cmdline_mode.specified;
> }
>
> struct drm_display_mode *drm_pick_cmdline_mode(struct
> drm_fb_helper_connector *fb_helper_conn,
> @@ -1196,7 +1140,7 @@ struct drm_display_mode
> *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f
> struct drm_display_mode *mode = NULL;
> bool prefer_non_interlace;
>
> - cmdline_mode = &fb_helper_conn->cmdline_mode;
> + cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
> if (cmdline_mode->specified == false)
> return mode;
>
> @@ -1581,8 +1525,6 @@ bool drm_fb_helper_initial_config(struct
> drm_fb_helper *fb_helper, int bpp_sel)
> struct drm_device *dev = fb_helper->dev;
> int count = 0;
>
> - drm_fb_helper_parse_command_line(fb_helper);
> -
> mutex_lock(&dev->mode_config.mutex);
> count = drm_fb_helper_probe_connector_modes(fb_helper,
>
> dev->mode_config.max_width,
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index bedf1894e17e..d1b7d2006529 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1259,6 +1259,7 @@ drm_mode_create_from_cmdline_mode(struct drm_device
> *dev,
> if (!mode)
> return NULL;
>
> + mode->type |= DRM_MODE_TYPE_USERDEF;
> drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
> return mode;
> }
> diff --git a/drivers/gpu/drm/drm_probe_helper.c
> b/drivers/gpu/drm/drm_probe_helper.c
> index d22676b89cbb..59f663879fd4 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -82,6 +82,22 @@ static void drm_mode_validate_flag(struct drm_connector
> *connector,
> return;
> }
>
> +static int drm_helper_probe_add_cmdline_mode(struct drm_connector
> *connector)
> +{
> + struct drm_display_mode *mode;
> +
> + if (!connector->cmdline_mode.specified)
> + return 0;
> +
> + mode = drm_mode_create_from_cmdline_mode(connector->dev,
> + &connector->cmdline_mode);
> + if (mode == NULL)
> + return 0;
> +
> + drm_mode_probed_add(connector, mode);
> + return 1;
> +}
> +
> static int drm_helper_probe_single_connector_modes_merge_bits(struct
> drm_connector *connector,
> uint32_t
> maxX, uint32_t maxY, bool merge_type_bits)
> {
> @@ -134,6 +150,7 @@ static int
> drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
>
> if (count == 0 && connector->status == connector_status_connected)
> count = drm_add_modes_noedid(connector, 1024, 768);
> + count += drm_helper_probe_add_cmdline_mode(connector);
> if (count == 0)
> goto prune;
>
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 251b75e6bf7a..abaed07a4b3b 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -532,6 +532,7 @@ struct drm_connector {
> void *helper_private;
>
> /* forced on connector */
> + struct drm_cmdline_mode cmdline_mode;
> enum drm_connector_force force;
> uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
> struct drm_encoder *encoder; /* currently active encoder */
> diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
> index 7997246d4039..28ead2b6f59b 100644
> --- a/include/drm/drm_fb_helper.h
> +++ b/include/drm/drm_fb_helper.h
> @@ -77,7 +77,6 @@ struct drm_fb_helper_funcs {
>
> struct drm_fb_helper_connector {
> struct drm_connector *connector;
> - struct drm_cmdline_mode cmdline_mode;
> };
>
> struct drm_fb_helper {
> --
> 2.0.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
--
Rodrigo Vivi
Blog: http://blog.vivi.eng.br
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20140714/13d872fd/attachment.html>
More information about the Intel-gfx
mailing list