drm: try harder to avoid regression when merging mode bits
Dave Airlie
maintainerPATCH 1/1 drm: try harder to avoid regression when merging mode bits
From: Dave Airlie <[email protected]>
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.
--- 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(-)
drivers/gpu/drm/drm_crtc_helper.c +16 -3
@@ -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
drivers/gpu/drm/drm_modes.c +5 -2
@@ -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 ;
drivers/gpu/drm/qxl/qxl_display.c +1 -1
@@ -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, };
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +1 -1
@@ -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 ; }
include/drm/drm_crtc.h +1 -1
@@ -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,
include/drm/drm_crtc_helper.h +1 -0
@@ -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,
Signature · 1 line
1.8.4.2
patch looks ok, and ugly, works for me:
Can we get this patch in Fedora asap?
thanks
Quoted 150 lines · Dave Airlie
From: Dave Airlie <[email protected]>
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 <[email protected]>--- 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(-)drivers/gpu/drm/drm_crtc_helper.c +16
-3@@ -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 drivers/gpu/drm/drm_modes.c +5
-2@@ -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 ;drivers/gpu/drm/qxl/qxl_display.c +1
-1@@ -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, };drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +1
-1@@ -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 ; }include/drm/drm_crtc.h +1
-1@@ -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,include/drm/drm_crtc_helper.h +1
-1@@ -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
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Marc-André Lureau