Hi Chris,

Thanks for the patch.

On Wednesday 05 June 2013 16:50:14 Chris Wilson wrote:
> The typical procedure after a hotplug event is then to enumerate all the
> new modes. In the existing code, this is achieved by performing a forced
> detection cycle over all connectors. Ideally, we should just be able to
> use the current detection status and only enumerate the modes on the
> connectors that changed. This is a step in that direction by teaching
> the hotplug path to only use the known detection status rather than
> performing a second *forced* detection on every connector. As it
> currently stands, the first thing userspace does upon receipt of a
> hotplug uevent is call DRM_IOCTL_MODE_GETCONNECTOR on each connector,
> which of course, performs another full detection cycle.
> 
> Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
> Cc: dri-devel@lists.freedesktop.org
> Cc: Jakob Bornecrantz <ja...@vmware.com>
> Cc: Inki Dae <inki....@samsung.com>
> Cc: Adam Jackson <a...@redhat.com>
> ---
>  drivers/gpu/drm/drm_crtc.c                    |    3 ++-
>  drivers/gpu/drm/drm_crtc_helper.c             |    8 ++++++--
>  drivers/gpu/drm/drm_fb_helper.c               |   14 ++++++++------
>  drivers/gpu/drm/exynos/exynos_drm_connector.c |    7 ++++---
>  drivers/gpu/drm/i2c/ch7006_drv.c              |    2 +-
>  drivers/gpu/drm/nouveau/dispnv04/tvnv17.c     |    2 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c           |    3 ++-
>  drivers/gpu/drm/vmwgfx/vmwgfx_kms.h           |    3 ++-
>  include/drm/drm_crtc.h                        |    2 +-
>  include/drm/drm_crtc_helper.h                 |    2 +-

Could you please also update Documentation/DocBook/drm.tmpl ?

>  10 files changed, 28 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index e7e9242..635276c 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1537,7 +1537,8 @@ int drm_mode_getconnector(struct drm_device *dev, void
> *data, if (out_resp->count_modes == 0) {
>               connector->funcs->fill_modes(connector,
>                                            dev->mode_config.max_width,
> -                                          dev->mode_config.max_height);
> +                                          dev->mode_config.max_height,
> +                                          true);
>       }
> 
>       /* delayed so we get modes regardless of pre-fill_modes state */
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c
> b/drivers/gpu/drm/drm_crtc_helper.c index ed1334e..7f2128c 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -96,6 +96,9 @@ static void drm_mode_validate_flag(struct drm_connector
> *connector, * @connector: connector to probe
>   * @maxX: max width for modes
>   * @maxY: max height for modes
> + * @force: whether to use the cached connector status or to force a
> + *         fresh detection cycle, for instance after a hotplug event, we
> + *         want to simply use the known status.
>   *
>   * LOCKING:
>   * Caller must hold mode config lock.
> @@ -113,7 +116,8 @@ static void drm_mode_validate_flag(struct drm_connector
> *connector, * Number of modes found on @connector.
>   */
>  int drm_helper_probe_single_connector_modes(struct drm_connector
> *connector, -                                     uint32_t maxX, uint32_t 
> maxY)
> +                                         uint32_t maxX, uint32_t maxY,
> +                                         bool force)
>  {
>       struct drm_device *dev = connector->dev;
>       struct drm_display_mode *mode;
> @@ -136,7 +140,7 @@ int drm_helper_probe_single_connector_modes(struct
> drm_connector *connector, connector->status =
> connector_status_disconnected;
>               if (connector->funcs->force)
>                       connector->funcs->force(connector);
> -     } else {
> +     } else if (force) {
>               connector->status = connector->funcs->detect(connector, true);
>       }
> 
> diff --git a/drivers/gpu/drm/drm_fb_helper.c
> b/drivers/gpu/drm/drm_fb_helper.c index b78cbe7..3e0802d 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -1087,8 +1087,8 @@ void drm_fb_helper_fill_var(struct fb_info *info,
> struct drm_fb_helper *fb_helpe EXPORT_SYMBOL(drm_fb_helper_fill_var);
> 
>  static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper
> *fb_helper, -                                        uint32_t maxX,
> -                                            uint32_t maxY)
> +                                            uint32_t maxX, uint32_t maxY,
> +                                            bool force)
>  {
>       struct drm_connector *connector;
>       int count = 0;
> @@ -1096,7 +1096,7 @@ static int drm_fb_helper_probe_connector_modes(struct
> drm_fb_helper *fb_helper,
> 
>       for (i = 0; i < fb_helper->connector_count; i++) {
>               connector = fb_helper->connector_info[i]->connector;
> -             count += connector->funcs->fill_modes(connector, maxX, maxY);
> +             count += connector->funcs->fill_modes(connector, maxX, maxY, 
> force);
>       }
> 
>       return count;
> @@ -1510,7 +1510,8 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper
> *fb_helper, int bpp_sel)
> 
>       count = drm_fb_helper_probe_connector_modes(fb_helper,
>                                                   dev->mode_config.max_width,
> -                                                 
> dev->mode_config.max_height);
> +                                                 dev->mode_config.max_height,
> +                                                 true);
>       /*
>        * we shouldn't end up with no modes here.
>        */
> @@ -1563,8 +1564,9 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper
> *fb_helper) max_height = fb_helper->fb->height;
>       bpp_sel = fb_helper->fb->bits_per_pixel;
> 
> -     count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
> -                                                 max_height);
> +     count = drm_fb_helper_probe_connector_modes(fb_helper,
> +                                                 max_width, max_height,
> +                                                 false);
>       mutex_unlock(&fb_helper->dev->mode_config.mutex);
> 
>       drm_modeset_lock_all(dev);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c
> b/drivers/gpu/drm/exynos/exynos_drm_connector.c index 8bcc13a..48ef16f
> 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
> @@ -249,7 +249,8 @@ static void exynos_drm_connector_dpms(struct
> drm_connector *connector, }
> 
>  static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
> -                             unsigned int max_width, unsigned int max_height)
> +                             unsigned int max_width, unsigned int max_height,
> +                             bool force)
>  {
>       struct exynos_drm_connector *exynos_connector =
>                                       to_exynos_connector(connector);
> @@ -267,8 +268,8 @@ static int exynos_drm_connector_fill_modes(struct
> drm_connector *connector, if (ops && ops->get_max_resol)
>               ops->get_max_resol(manager->dev, &width, &height);
> 
> -     return drm_helper_probe_single_connector_modes(connector, width,
> -                                                     height);
> +     return drm_helper_probe_single_connector_modes(connector,
> +                                                    width, height, force);
>  }
> 
>  /* get detection status of display device. */
> diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c
> b/drivers/gpu/drm/i2c/ch7006_drv.c index 51fa323..d18237d 100644
> --- a/drivers/gpu/drm/i2c/ch7006_drv.c
> +++ b/drivers/gpu/drm/i2c/ch7006_drv.c
> @@ -355,7 +355,7 @@ static int ch7006_encoder_set_property(struct
> drm_encoder *encoder, }
> 
>       if (modes_changed) {
> -             drm_helper_probe_single_connector_modes(connector, 0, 0);
> +             drm_helper_probe_single_connector_modes(connector, 0, 0, false);
> 
>               /* Disable the crtc to ensure a full modeset is
>                * performed whenever it's turned on again. */
> diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c index acef48f..535dd14 100644
> --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> @@ -759,7 +759,7 @@ static int nv17_tv_set_property(struct drm_encoder
> *encoder, }
> 
>       if (modes_changed) {
> -             drm_helper_probe_single_connector_modes(connector, 0, 0);
> +             drm_helper_probe_single_connector_modes(connector, 0, 0, false);
> 
>               /* Disable the crtc to ensure a full modeset is
>                * performed whenever it's turned on again. */
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 3e3c7ab..d9a0768 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> @@ -1924,7 +1924,8 @@ static void vmw_guess_mode_timing(struct
> drm_display_mode *mode)
> 
> 
>  int vmw_du_connector_fill_modes(struct drm_connector *connector,
> -                             uint32_t max_width, uint32_t max_height)
> +                             uint32_t max_width, uint32_t max_height,
> +                             bool force)
>  {
>       struct vmw_display_unit *du = vmw_connector_to_du(connector);
>       struct drm_device *dev = connector->dev;
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
> b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 6fa89c9..19fc306 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
> @@ -138,7 +138,8 @@ void vmw_du_connector_restore(struct drm_connector
> *connector); enum drm_connector_status
>  vmw_du_connector_detect(struct drm_connector *connector, bool force);
>  int vmw_du_connector_fill_modes(struct drm_connector *connector,
> -                             uint32_t max_width, uint32_t max_height);
> +                             uint32_t max_width, uint32_t max_height,
> +                             bool force);
>  int vmw_du_connector_set_property(struct drm_connector *connector,
>                                 struct drm_property *property,
>                                 uint64_t val);
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index adb3f9b..373e774 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -468,7 +468,7 @@ struct drm_connector_funcs {
>        */
>       enum drm_connector_status (*detect)(struct drm_connector *connector,
>                                           bool force);
> -     int (*fill_modes)(struct drm_connector *connector, uint32_t max_width,
> uint32_t max_height); +       int (*fill_modes)(struct drm_connector 
> *connector,
> uint32_t max_width, uint32_t max_height, bool force); int
> (*set_property)(struct drm_connector *connector, struct drm_property
> *property, uint64_t val);
>       void (*destroy)(struct drm_connector *connector);
> diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
> index f43d556..cce7221 100644
> --- a/include/drm/drm_crtc_helper.h
> +++ b/include/drm/drm_crtc_helper.h
> @@ -125,7 +125,7 @@ struct drm_connector_helper_funcs {
>       struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
>  };
> 
> -extern int drm_helper_probe_single_connector_modes(struct drm_connector
> *connector, uint32_t maxX, uint32_t maxY); +extern int
> drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> uint32_t maxX, uint32_t maxY, bool force); extern void
> drm_helper_disable_unused_functions(struct drm_device *dev); extern int
> drm_crtc_helper_set_config(struct drm_mode_set *set);
>  extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to