[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