diff options
author | Thomas Zimmermann <tzimmermann@suse.de> | 2019-12-02 12:15:57 +0100 |
---|---|---|
committer | Thomas Zimmermann <tzimmermann@suse.de> | 2019-12-10 14:28:43 +0100 |
commit | 3339fdf5742f7182d7a17fb48e2d7463f6a79580 (patch) | |
tree | 57464d78d495179866a9bbb5b627a61067a37c2e | |
parent | e7d70cd4948e543739e9859d2b4ab30448067d32 (diff) |
drm/ast: Store primary-plane format in struct ast_crtc_state
Reading the primary plane's framebuffer from the CRTC's atomic_flush()
function is fragile as the plane state or framebuffer can be NULL.
Instead, we let the plane's atomic_check() store the framebuffer format
in the CRTC state. The CRTC always receives the framebuffer format that
is currently programmed, or NULL if no mode has been set yet.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191202111557.15176-8-tzimmermann@suse.de
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 26 |
2 files changed, 20 insertions, 9 deletions
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 72883b5aefa7..f5d8780776ae 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -284,6 +284,9 @@ struct ast_vbios_mode_info { struct ast_crtc_state { struct drm_crtc_state base; + /* Last known format of primary plane */ + const struct drm_format_info *format; + struct ast_vbios_mode_info vbios_mode_info; }; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index a27724832845..cde1cae073ec 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -535,6 +535,7 @@ static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct drm_crtc_state *crtc_state; + struct ast_crtc_state *ast_crtc_state; int ret; if (!state->crtc) @@ -549,6 +550,13 @@ static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane, if (ret) return ret; + if (!state->visible) + return 0; + + ast_crtc_state = to_ast_crtc_state(crtc_state); + + ast_crtc_state->format = state->fb->format; + return 0; } @@ -783,8 +791,8 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { struct ast_private *ast = crtc->dev->dev_private; - struct drm_plane_state *plane_state; struct ast_crtc_state *ast_state; + const struct drm_format_info *format; bool succ; if (ast->chip == AST1180) { @@ -793,12 +801,12 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, } ast_state = to_ast_crtc_state(state); - plane_state = crtc->primary->state; - if (!plane_state || !plane_state->fb) + format = ast_state->format; + if (!format) return 0; - succ = ast_get_vbios_mode_info(plane_state->fb->format, &state->mode, + succ = ast_get_vbios_mode_info(format, &state->mode, &state->adjusted_mode, &ast_state->vbios_mode_info); if (!succ) @@ -820,7 +828,6 @@ static void ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct ast_private *ast = dev->dev_private; - const struct drm_framebuffer *fb = crtc->primary->state->fb; struct ast_crtc_state *ast_state; const struct drm_format_info *format; struct ast_vbios_mode_info *vbios_mode_info; @@ -828,12 +835,12 @@ static void ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, crtc->state->no_vblank = true; - if (!fb) - return; - ast_state = to_ast_crtc_state(crtc->state); - format = fb->format; + format = ast_state->format; + if (!format) + return; + vbios_mode_info = &ast_state->vbios_mode_info; ast_set_color_reg(ast, format); @@ -896,6 +903,7 @@ ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc) ast_state = to_ast_crtc_state(crtc->state); + new_ast_state->format = ast_state->format; memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info, sizeof(new_ast_state->vbios_mode_info)); |