Take a reference to existing modes, rather than duplicating them to create new ones. Signed-off-by: Daniel Stone <daniels@xxxxxxxxxxxxx> --- drivers/gpu/drm/drm_atomic_helper.c | 49 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index bc7b629..f5ee83c 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -260,7 +260,12 @@ mode_fixup(struct drm_atomic_state *state) if (!crtc_state || !crtc_state->mode_changed) continue; - drm_mode_copy(&crtc_state->adjusted_mode, crtc_state->mode); + if (crtc_state->mode) + drm_mode_copy(&crtc_state->adjusted_mode, + crtc_state->mode); + else + memset(&crtc_state->adjusted_mode, 0, + sizeof(crtc_state->adjusted_mode)); } for (i = 0; i < state->num_connector; i++) { @@ -699,14 +704,12 @@ set_routing_links(struct drm_device *dev, struct drm_atomic_state *old_state) if (!crtc) continue; - if (crtc->state->mode) { - if (crtc->mode) - drm_mode_destroy(dev, crtc->mode); - crtc->mode = drm_mode_duplicate(dev, crtc->state->mode); - } else if (crtc->mode) { + if (crtc->mode) drm_mode_destroy(dev, crtc->mode); - crtc->mode = NULL; - } + crtc->mode = crtc->state->mode; + if (crtc->mode) + drm_mode_reference(crtc->mode); + crtc->enabled = crtc->state->enable; crtc->x = crtc->primary->state->src_x >> 16; crtc->y = crtc->primary->state->src_y >> 16; @@ -731,8 +734,9 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) funcs = crtc->helper_private; if (crtc->state->enable && funcs->mode_set_nofb) { - DRM_DEBUG_ATOMIC("modeset on [CRTC:%d]\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("modeset on [CRTC:%d] [MODE:%d]\n", + crtc->base.id, + crtc->state->mode ? crtc->state->mode->base.id : 0); funcs->mode_set_nofb(crtc); } @@ -1652,7 +1656,9 @@ retry: crtc_state->active = true; if (crtc_state->mode) drm_mode_destroy(crtc->dev, crtc_state->mode); - crtc_state->mode = drm_mode_duplicate(crtc->dev, set->mode); + crtc_state->mode = set->mode; + if (crtc_state->mode) + drm_mode_reference(crtc_state->mode); ret = drm_atomic_set_crtc_for_plane(primary_state, crtc); if (ret != 0) @@ -1660,12 +1666,12 @@ retry: drm_atomic_set_fb_for_plane(primary_state, set->fb); primary_state->crtc_x = 0; primary_state->crtc_y = 0; - primary_state->crtc_h = set->mode->vdisplay; - primary_state->crtc_w = set->mode->hdisplay; + primary_state->crtc_h = set->mode ? set->mode->vdisplay : 0; + primary_state->crtc_w = set->mode ? set->mode->hdisplay : 0; primary_state->src_x = set->x << 16; primary_state->src_y = set->y << 16; - primary_state->src_h = set->mode->vdisplay << 16; - primary_state->src_w = set->mode->hdisplay << 16; + primary_state->src_h = set->mode ? set->mode->vdisplay << 16 : 0; + primary_state->src_w = set->mode ? set->mode->hdisplay << 16 : 0; commit: ret = update_output_state(state, set); @@ -2105,15 +2111,8 @@ drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc) state->planes_changed = false; state->event = NULL; - if (crtc->state->mode) { - state->mode = - drm_mode_duplicate(crtc->dev, - crtc->state->mode); - if (!state->mode) { - kfree(state); - state = NULL; - } - } + if (state->mode) + drm_mode_reference(state->mode); return state; } @@ -2130,7 +2129,7 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state); void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state) { - kfree(state->mode); + drm_mode_destroy(crtc->dev, state->mode); kfree(state); } EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); -- 2.3.2 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel