[PATCH] drm: try harder to avoid regression when merging mode bits

Marc-André Lureau marcandre.lureau at gmail.com
Thu Mar 6 07:20:28 PST 2014


patch looks ok, and ugly, works for me:

Tested-by: Marc-André Lureau <marcandre.lureau at redhat.com>

Can we get this patch in Fedora asap?

thanks

On Tue, Jan 14, 2014 at 4:33 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> For QXL hw we really want the bits to be replaced as we change
> the preferred mode on the fly, and the same goes for virgl when
> I get to it, however the original fix for this seems to have caused
> a wierd regression on Intel G33 that in a stunning display of failure
> at opposition to his normal self, Daniel failed to diagnose.
>
> So we are left doing this, ugly ugly ugly ugly, Daniel you fixed
> that G33 yet?, ugly, ugly.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  drivers/gpu/drm/drm_crtc_helper.c   | 19 ++++++++++++++++---
>  drivers/gpu/drm/drm_modes.c         |  7 +++++--
>  drivers/gpu/drm/qxl/qxl_display.c   |  2 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |  2 +-
>  include/drm/drm_crtc.h              |  2 +-
>  include/drm/drm_crtc_helper.h       |  1 +
>  6 files changed, 25 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
> index 01361ab..ca450af 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -120,8 +120,8 @@ static void drm_mode_validate_flag(struct drm_connector *connector,
>   * RETURNS:
>   * Number of modes found on @connector.
>   */
> -int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> -                                           uint32_t maxX, uint32_t maxY)
> +static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
> +                                           uint32_t maxX, uint32_t maxY, bool merge_type_bits)
>  {
>         struct drm_device *dev = connector->dev;
>         struct drm_display_mode *mode;
> @@ -173,7 +173,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
>         if (count == 0)
>                 goto prune;
>
> -       drm_mode_connector_list_update(connector);
> +       drm_mode_connector_list_update(connector, merge_type_bits);
>
>         if (maxX && maxY)
>                 drm_mode_validate_size(dev, &connector->modes, maxX,
> @@ -213,8 +213,21 @@ prune:
>
>         return count;
>  }
> +
> +int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> +                                           uint32_t maxX, uint32_t maxY)
> +{
> +       return drm_helper_probe_single_connector_modes_merge_bits(connector, maxX, maxY, true);
> +}
>  EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
>
> +int drm_helper_probe_single_connector_modes_nomerge(struct drm_connector *connector,
> +                                                   uint32_t maxX, uint32_t maxY)
> +{
> +       return drm_helper_probe_single_connector_modes_merge_bits(connector, maxX, maxY, false);
> +}
> +EXPORT_SYMBOL(drm_helper_probe_single_connector_modes_nomerge);
> +
>  /**
>   * drm_helper_encoder_in_use - check if a given encoder is in use
>   * @encoder: encoder to check
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index 85071a1..54cd735 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1025,7 +1025,7 @@ EXPORT_SYMBOL(drm_mode_sort);
>   * list and only adds different modes. All modes unverified after this point
>   * will be removed by the prune invalid modes.
>   */
> -void drm_mode_connector_list_update(struct drm_connector *connector)
> +void drm_mode_connector_list_update(struct drm_connector *connector, bool merge_type_bits)
>  {
>         struct drm_display_mode *mode;
>         struct drm_display_mode *pmode, *pt;
> @@ -1041,7 +1041,10 @@ void drm_mode_connector_list_update(struct drm_connector *connector)
>                                 /* if equal delete the probed mode */
>                                 mode->status = pmode->status;
>                                 /* Merge type bits together */
> -                               mode->type = pmode->type;
> +                               if (merge_type_bits)
> +                                       mode->type |= pmode->type;
> +                               else
> +                                       mode->type = pmode->type;
>                                 list_del(&pmode->head);
>                                 drm_mode_destroy(connector->dev, pmode);
>                                 break;
> diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
> index 798bde2..26e7fe1 100644
> --- a/drivers/gpu/drm/qxl/qxl_display.c
> +++ b/drivers/gpu/drm/qxl/qxl_display.c
> @@ -841,7 +841,7 @@ static const struct drm_connector_funcs qxl_connector_funcs = {
>         .save = qxl_conn_save,
>         .restore = qxl_conn_restore,
>         .detect = qxl_conn_detect,
> -       .fill_modes = drm_helper_probe_single_connector_modes,
> +       .fill_modes = drm_helper_probe_single_connector_modes_nomerge,
>         .set_property = qxl_conn_set_property,
>         .destroy = qxl_conn_destroy,
>  };
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> index 019e2db..b0dcc65 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> @@ -2003,7 +2003,7 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
>         if (du->pref_mode)
>                 list_move(&du->pref_mode->head, &connector->probed_modes);
>
> -       drm_mode_connector_list_update(connector);
> +       drm_mode_connector_list_update(connector, true);
>
>         return 1;
>  }
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index f32c5cd..48a77d5 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -1002,7 +1002,7 @@ extern int drm_mode_hsync(const struct drm_display_mode *mode);
>  extern int drm_mode_vrefresh(const struct drm_display_mode *mode);
>  extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
>                                   int adjust_flags);
> -extern void drm_mode_connector_list_update(struct drm_connector *connector);
> +extern void drm_mode_connector_list_update(struct drm_connector *connector, bool merge_type_bits);
>  extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>                                                 struct edid *edid);
>  extern int drm_object_property_set_value(struct drm_mode_object *obj,
> diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
> index ef6ad3a..d1713eb 100644
> --- a/include/drm/drm_crtc_helper.h
> +++ b/include/drm/drm_crtc_helper.h
> @@ -126,6 +126,7 @@ struct drm_connector_helper_funcs {
>  };
>
>  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_nomerge(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
>  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,
> --
> 1.8.4.2
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Marc-André Lureau


More information about the dri-devel mailing list