Skip to content

Commit fd63bf9

Browse files
committed
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
1 parent 7b8a74b commit fd63bf9

File tree

1 file changed

+28
-24
lines changed

1 file changed

+28
-24
lines changed

drivers/gpu/drm/ast/ast_mode.c

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,33 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode
11311131
return status;
11321132
}
11331133

1134+
static void ast_crtc_helper_mode_set_nofb(struct drm_crtc *crtc)
1135+
{
1136+
struct drm_device *dev = crtc->dev;
1137+
struct ast_device *ast = to_ast_device(dev);
1138+
struct drm_crtc_state *crtc_state = crtc->state;
1139+
struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
1140+
struct ast_vbios_mode_info *vbios_mode_info =
1141+
&ast_crtc_state->vbios_mode_info;
1142+
struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
1143+
1144+
/*
1145+
* Ensure that no scanout takes place before reprogramming mode
1146+
* and format registers.
1147+
*
1148+
* TODO: Get vblank interrupts working and remove this line.
1149+
*/
1150+
ast_wait_for_vretrace(ast);
1151+
1152+
ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
1153+
ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
1154+
ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
1155+
ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
1156+
ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
1157+
ast_set_crtthd_reg(ast);
1158+
ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
1159+
}
1160+
11341161
static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
11351162
struct drm_atomic_state *state)
11361163
{
@@ -1207,30 +1234,12 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
12071234

12081235
static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
12091236
{
1210-
struct drm_device *dev = crtc->dev;
1211-
struct ast_device *ast = to_ast_device(dev);
1212-
struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1213-
struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
1214-
struct ast_vbios_mode_info *vbios_mode_info =
1215-
&ast_crtc_state->vbios_mode_info;
1216-
struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
1217-
1218-
ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
1219-
ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
1220-
ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
1221-
ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
1222-
ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
1223-
ast_set_crtthd_reg(ast);
1224-
ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
1225-
12261237
ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
12271238
}
12281239

12291240
static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
12301241
{
12311242
struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
1232-
struct drm_device *dev = crtc->dev;
1233-
struct ast_device *ast = to_ast_device(dev);
12341243

12351244
ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
12361245

@@ -1245,16 +1254,11 @@ static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_ato
12451254
* simple pageflips on the planes.
12461255
*/
12471256
drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
1248-
1249-
/*
1250-
* Ensure that no scanout takes place before reprogramming mode
1251-
* and format registers.
1252-
*/
1253-
ast_wait_for_vretrace(ast);
12541257
}
12551258

12561259
static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
12571260
.mode_valid = ast_crtc_helper_mode_valid,
1261+
.mode_set_nofb = ast_crtc_helper_mode_set_nofb,
12581262
.atomic_check = ast_crtc_helper_atomic_check,
12591263
.atomic_flush = ast_crtc_helper_atomic_flush,
12601264
.atomic_enable = ast_crtc_helper_atomic_enable,

0 commit comments

Comments
 (0)