dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel@ffwll.ch>
To: Thierry Reding <thierry.reding@gmail.com>
Cc: Xinliang Liu <z.liuxinliang@hisilicon.com>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	Seung-Woo Kim <sw0312.kim@samsung.com>,
	dri-devel@lists.freedesktop.org,
	Kyungmin Park <kyungmin.park@samsung.com>,
	Chen Feng <puck.chen@hisilicon.com>
Subject: Re: [PATCH 1/4] drm/fb-helper: Support deferred setup
Date: Fri, 3 Jun 2016 20:33:46 +0200	[thread overview]
Message-ID: <20160603183346.GZ7231@phenom.ffwll.local> (raw)
In-Reply-To: <20160603161119.30528-1-thierry.reding@gmail.com>

On Fri, Jun 03, 2016 at 06:11:16PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> FB helper code falls back to a 1024x768 mode if no outputs are connected
> or don't report back any modes upon initialization. This can be annoying
> because outputs that are added to FB helper later on can't be used with
> FB helper if they don't support a matching mode.
> 
> The fallback is in place because VGA connectors can happen to report an
> unknown connection status even when they are in fact connected.
> 
> Some drivers have custom solutions in place to defer FB helper setup
> until at least one output is connected. But the logic behind these
> solutions is always the same and there is nothing driver-specific about
> it, so a better alterative is to fix the FB helper core and add support
> for all drivers automatically.
> 
> This patch adds support for deferred FB helper setup. It checks all the
> connectors for their connection status, and if all of them report to be
> disconnected marks the FB helper as needing deferred setup. Whet setup
> is deferred, the FB helper core will automatically retry setup after a
> hotplug event, and it will keep trying until it succeeds.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/gpu/drm/drm_fb_helper.c | 36 ++++++++++++++++++++++++++++++++++++
>  include/drm/drm_fb_helper.h     | 21 +++++++++++++++++++++
>  2 files changed, 57 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index 7c2eb75db60f..4f334f9cab28 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -442,6 +442,9 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
>  	if (!drm_fbdev_emulation)
>  		return -ENODEV;
>  
> +	if (fb_helper->deferred_setup)
> +		return 0;
> +
>  	drm_modeset_lock_all(dev);
>  	ret = restore_fbdev_mode(fb_helper);
>  
> @@ -1398,6 +1401,23 @@ unlock:
>  }
>  EXPORT_SYMBOL(drm_fb_helper_pan_display);
>  
> +static bool drm_fb_helper_maybe_connected(struct drm_fb_helper *helper)
> +{
> +	bool connected = false;
> +	unsigned int i;
> +
> +	for (i = 0; i < helper->connector_count; i++) {
> +		struct drm_fb_helper_connector *fb = helper->connector_info[i];
> +
> +		if (fb->connector->status != connector_status_disconnected) {
> +			connected = true;
> +			break;
> +		}
> +	}
> +
> +	return connected;
> +}
> +
>  /*
>   * Allocates the backing storage and sets up the fbdev info structure through
>   * the ->fb_probe callback and then registers the fbdev and sets up the panic
> @@ -1499,6 +1519,17 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
>  			sizes.fb_height = min_t(u32, desired_mode->vdisplay + y, sizes.fb_height);
>  	}
>  
> +	/*
> +	 * If everything's disconnected, there's no use in attempting to set
> +	 * up fbdev.
> +	 */
> +	if (!drm_fb_helper_maybe_connected(fb_helper)) {
> +		DRM_INFO("No outputs connected, deferring setup\n");
> +		fb_helper->preferred_bpp = preferred_bpp;
> +		fb_helper->deferred_setup = true;
> +		return 0;
> +	}
> +
>  	if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
>  		/* hmm everyone went away - assume VGA cable just fell out
>  		   and will come back later. */
> @@ -1539,6 +1570,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
>  
>  	list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
>  
> +	fb_helper->deferred_setup = false;
>  	return 0;
>  }
>  
> @@ -2237,6 +2269,10 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
>  	if (!drm_fbdev_emulation)
>  		return 0;
>  
> +	if (fb_helper->deferred_setup)
> +		return drm_fb_helper_initial_config(fb_helper,
> +						    fb_helper->preferred_bpp);

Logic looks all nice, but we need more locking. Extending our abuse of
dev->mode_config.mutex for fb_helper internals won't work since
initial_config already takes some locks at various times, we need a real
fb_helper->mutex now. We want that anyway, to be able to push a bunch of
the modeset locking out of the fbdev code, or at least down a lot.

To make it work we need to make it a top-level lock, surrounding all kms
locks I think. And minimally it needs to wrapt hotplug_event, restore_mode
and the single_add/remove_connector functions.
-Daniel

> +
>  	mutex_lock(&fb_helper->dev->mode_config.mutex);
>  	if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) {
>  		fb_helper->delayed_hotplug = true;
> diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
> index 5b4aa35026a3..25446690b2c1 100644
> --- a/include/drm/drm_fb_helper.h
> +++ b/include/drm/drm_fb_helper.h
> @@ -214,6 +214,27 @@ struct drm_fb_helper {
>  	bool delayed_hotplug;
>  
>  	/**
> +	 * @deferred_setup:
> +	 *
> +	 * If no outputs are connected (disconnected or unknown) the FB helper
> +	 * code will defer setup until at least one of the outputs shows up.
> +	 * This field keeps track of the status so that setup can be retried
> +	 * at every hotplug event until it succeeds eventually.
> +	 */
> +	bool deferred_setup;
> +
> +	/**
> +	 * @preferred_bpp:
> +	 *
> +	 * Temporary storage for the driver's preferred BPP setting passed to
> +	 * FB helper initialization. This needs to be tracked so that deferred
> +	 * FB helper setup can pass this on.
> +	 *
> +	 * See also: @deferred_setup
> +	 */
> +	int preferred_bpp;
> +
> +	/**
>  	 * @atomic:
>  	 *
>  	 * Use atomic updates for restore_fbdev_mode(), etc.  This defaults to
> -- 
> 2.8.3
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2016-06-03 18:33 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-03 16:11 [PATCH 1/4] drm/fb-helper: Support deferred setup Thierry Reding
2016-06-03 16:11 ` [PATCH 2/4] drm/atmel-hlcdc: Remove custom FB helper " Thierry Reding
2016-06-03 16:11 ` [PATCH 3/4] drm/exynos: " Thierry Reding
2016-06-03 16:11 ` [PATCH 4/4] drm/hisilicon: " Thierry Reding
2016-06-03 18:40   ` Daniel Vetter
2016-06-03 18:33 ` Daniel Vetter [this message]
2016-06-04 10:46 ` [PATCH 1/4] drm/fb-helper: Support " Lukas Wunner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160603183346.GZ7231@phenom.ffwll.local \
    --to=daniel@ffwll.ch \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kyungmin.park@samsung.com \
    --cc=puck.chen@hisilicon.com \
    --cc=sw0312.kim@samsung.com \
    --cc=thierry.reding@gmail.com \
    --cc=z.liuxinliang@hisilicon.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox