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
This commit is contained in:
parent
e7d70cd494
commit
3339fdf574
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in New Issue