summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2024-06-27 17:27:48 +0200
committerThomas Zimmermann <tzimmermann@suse.de>2024-07-03 09:38:13 +0200
commitfd63bf978b7b0f106c72b6392436f4223b16ab85 (patch)
treea88fff20246dc8b6e9ce064c5c2f02b3f96a2837 /drivers
parent7b8a74bc42016173ddb4872d113f132c8ca59fc1 (diff)
downloadlinux-fd63bf978b7b0f106c72b6392436f4223b16ab85.tar.gz
linux-fd63bf978b7b0f106c72b6392436f4223b16ab85.tar.bz2
linux-fd63bf978b7b0f106c72b6392436f4223b16ab85.zip
drm/ast: Move mode-setting code into mode_set_nofb CRTC helper
Do all mode setting in ast_crtc_helper_mode_set_nofb(), which always runs after disabling the CRTC and before programming the planes. Removes implicit synchronization between the CRTC's atomic disable, enable and the vertical retrace. Display-mode updates require HW cursors to be disabled. The HW cursor only picks up changes at vertical retrace periods. So the CRTC's atomic_disable helper waited for the retrace to delay any following mode-setting operations, which then happened in atomic_enable. See [1] for a description of the problem. With the CRTC helper callback mode_set_nofb, we can now synchronize and reprogram in the same place. As it always runs before the plane update, the plane code can be reordered with the CRTC's later atomic_enable et al. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/series/79914/ # 1 Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240627153638.8765-4-tzimmermann@suse.de
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c52
1 files changed, 28 insertions, 24 deletions
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 421fcdad40e4..e8312b3472ed 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -1131,6 +1131,33 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode
return status;
}
+static void ast_crtc_helper_mode_set_nofb(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct ast_device *ast = to_ast_device(dev);
+ struct drm_crtc_state *crtc_state = crtc->state;
+ struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
+ struct ast_vbios_mode_info *vbios_mode_info =
+ &ast_crtc_state->vbios_mode_info;
+ struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+
+ /*
+ * Ensure that no scanout takes place before reprogramming mode
+ * and format registers.
+ *
+ * TODO: Get vblank interrupts working and remove this line.
+ */
+ ast_wait_for_vretrace(ast);
+
+ ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
+ ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
+ ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
+ ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
+ ast_set_crtthd_reg(ast);
+ ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
+}
+
static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
@@ -1207,30 +1234,12 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
{
- struct drm_device *dev = crtc->dev;
- struct ast_device *ast = to_ast_device(dev);
- struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
- struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
- struct ast_vbios_mode_info *vbios_mode_info =
- &ast_crtc_state->vbios_mode_info;
- struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
-
- ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
- ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
- ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
- ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
- ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
- ast_set_crtthd_reg(ast);
- ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
-
ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
}
static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
{
struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
- struct drm_device *dev = crtc->dev;
- struct ast_device *ast = to_ast_device(dev);
ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
@@ -1245,16 +1254,11 @@ static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_ato
* simple pageflips on the planes.
*/
drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
-
- /*
- * Ensure that no scanout takes place before reprogramming mode
- * and format registers.
- */
- ast_wait_for_vretrace(ast);
}
static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
.mode_valid = ast_crtc_helper_mode_valid,
+ .mode_set_nofb = ast_crtc_helper_mode_set_nofb,
.atomic_check = ast_crtc_helper_atomic_check,
.atomic_flush = ast_crtc_helper_atomic_flush,
.atomic_enable = ast_crtc_helper_atomic_enable,