Message ID | 20240624205951.23343-1-ian.forbes@broadcom.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/vmwgfx: Trigger a modeset when the screen moves | expand |
On 6/24/24 13:59, Ian Forbes wrote: > When multi-monitor is cycled the X,Y position of the Screen Target will > likely change but the resolution will not. We need to trigger a modeset > when this occurs in order to recreate the Screen Target with the correct > X,Y position. > > Fixes a bug where multiple displays are shown in a single scrollable > host window rather than in 2+ windows on separate host displays. > > Fixes: 426826933109 ("drm/vmwgfx: Filter modes which exceed graphics memory") > Signed-off-by: Ian Forbes <ian.forbes@broadcom.com> > --- > drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 29 +++++++++++++++++++++++++++- > 1 file changed, 28 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c > index a04e0736318da..9becd71bc93bc 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c > @@ -877,6 +877,32 @@ vmw_stdu_connector_mode_valid(struct drm_connector *connector, > return MODE_OK; > } > > +/* > + * Trigger a modeset if the X,Y position of the Screen Target changes. > + * This is needed when multi-mon is cycled. The original Screen Target will have > + * the same mode but its relative X,Y position in the topology will change. > + */ > +static int vmw_stdu_connector_atomic_check(struct drm_connector *conn, > + struct drm_atomic_state *state) > +{ > + struct drm_connector_state *conn_state; > + struct vmw_screen_target_display_unit *du; > + struct drm_crtc_state *new_crtc_state; > + > + conn_state = drm_atomic_get_connector_state(state, conn); > + du = vmw_connector_to_stdu(conn); > + > + if (!conn_state->crtc) > + return 0; > + > + new_crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); We should be checking for new_crtc_state being NULL here. > + if (du->base.gui_x != du->base.set_gui_x || > + du->base.gui_y != du->base.set_gui_y) > + new_crtc_state->mode_changed = true; > + > + return 0; > +} > + > static const struct drm_connector_funcs vmw_stdu_connector_funcs = { > .dpms = vmw_du_connector_dpms, > .detect = vmw_du_connector_detect, > @@ -891,7 +917,8 @@ static const struct drm_connector_funcs vmw_stdu_connector_funcs = { > static const struct > drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = { > .get_modes = vmw_connector_get_modes, > - .mode_valid = vmw_stdu_connector_mode_valid > + .mode_valid = vmw_stdu_connector_mode_valid, > + .atomic_check = vmw_stdu_connector_atomic_check, > }; > > Maaz Mombasawala <maaz.mombasawala@broadcom.com>
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index a04e0736318da..9becd71bc93bc 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -877,6 +877,32 @@ vmw_stdu_connector_mode_valid(struct drm_connector *connector, return MODE_OK; } +/* + * Trigger a modeset if the X,Y position of the Screen Target changes. + * This is needed when multi-mon is cycled. The original Screen Target will have + * the same mode but its relative X,Y position in the topology will change. + */ +static int vmw_stdu_connector_atomic_check(struct drm_connector *conn, + struct drm_atomic_state *state) +{ + struct drm_connector_state *conn_state; + struct vmw_screen_target_display_unit *du; + struct drm_crtc_state *new_crtc_state; + + conn_state = drm_atomic_get_connector_state(state, conn); + du = vmw_connector_to_stdu(conn); + + if (!conn_state->crtc) + return 0; + + new_crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + if (du->base.gui_x != du->base.set_gui_x || + du->base.gui_y != du->base.set_gui_y) + new_crtc_state->mode_changed = true; + + return 0; +} + static const struct drm_connector_funcs vmw_stdu_connector_funcs = { .dpms = vmw_du_connector_dpms, .detect = vmw_du_connector_detect, @@ -891,7 +917,8 @@ static const struct drm_connector_funcs vmw_stdu_connector_funcs = { static const struct drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = { .get_modes = vmw_connector_get_modes, - .mode_valid = vmw_stdu_connector_mode_valid + .mode_valid = vmw_stdu_connector_mode_valid, + .atomic_check = vmw_stdu_connector_atomic_check, };
When multi-monitor is cycled the X,Y position of the Screen Target will likely change but the resolution will not. We need to trigger a modeset when this occurs in order to recreate the Screen Target with the correct X,Y position. Fixes a bug where multiple displays are shown in a single scrollable host window rather than in 2+ windows on separate host displays. Fixes: 426826933109 ("drm/vmwgfx: Filter modes which exceed graphics memory") Signed-off-by: Ian Forbes <ian.forbes@broadcom.com> --- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 29 +++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-)