From 568c634a2af62e07ed248a6e7fe9770173f9d9b2 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 1 Jun 2015 12:49:57 +0200 Subject: [PATCH] drm/i915: Support modeset across multiple pipes Compute new pipe_configs for all crtcs in the atomic state. The commit part of the mode set (__intel_set_mode()) is already enabled to support multiple pipes, the only thing missing was calculating a new pipe_config for every crtc. Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Maarten Lankhorst Reviewed-by: Matt Roper Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 108 +++++++++++---------------- 1 file changed, 45 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 52759c03c9e8..e566515e27ca 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -86,8 +86,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, static void ironlake_pch_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); -static int intel_set_mode(struct drm_crtc *crtc, - struct drm_atomic_state *state); +static int intel_set_mode(struct drm_atomic_state *state); static int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *ifb, struct drm_mode_fb_cmd2 *mode_cmd, @@ -10482,7 +10481,7 @@ retry: drm_mode_copy(&crtc_state->base.mode, mode); - if (intel_set_mode(crtc, state)) { + if (intel_set_mode(state)) { DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); if (old->release_fb) old->release_fb->funcs->destroy(old->release_fb); @@ -10556,7 +10555,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, if (ret) goto fail; - ret = intel_set_mode(crtc, state); + ret = intel_set_mode(state); if (ret) goto fail; @@ -12068,9 +12067,10 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state) static int intel_modeset_pipe_config(struct drm_crtc *crtc, - struct drm_atomic_state *state, - struct intel_crtc_state *pipe_config) + struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state; + struct intel_crtc_state *pipe_config; struct intel_encoder *encoder; struct drm_connector *connector; struct drm_connector_state *connector_state; @@ -12088,6 +12088,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, return -EINVAL; } + crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); + if (WARN_ON(!crtc_state)) + return -EINVAL; + + pipe_config = to_intel_crtc_state(crtc_state); + /* * XXX: Add all connectors to make the crtc state match the encoders. */ @@ -12800,45 +12806,35 @@ static void update_scanline_offset(struct intel_crtc *crtc) crtc->scanline_offset = 1; } -static struct intel_crtc_state * -intel_modeset_compute_config(struct drm_crtc *crtc, - struct drm_atomic_state *state) +static int +intel_modeset_compute_config(struct drm_atomic_state *state) { - struct intel_crtc_state *pipe_config; - int ret = 0; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int ret, i; ret = drm_atomic_helper_check_modeset(state->dev, state); if (ret) - return ERR_PTR(ret); - - /* - * Note this needs changes when we start tracking multiple modes - * and crtcs. At that point we'll need to compute the whole config - * (i.e. one pipe_config for each crtc) rather than just the one - * for this crtc. - */ - pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc)); - if (IS_ERR(pipe_config)) - return pipe_config; - - if (!pipe_config->base.enable && - WARN_ON(pipe_config->base.active)) - pipe_config->base.active = false; + return ret; - if (!pipe_config->base.enable) - return pipe_config; + for_each_crtc_in_state(state, crtc, crtc_state, i) { + if (!crtc_state->enable && + WARN_ON(crtc_state->active)) + crtc_state->active = false; - ret = intel_modeset_pipe_config(crtc, state, pipe_config); - if (ret) - return ERR_PTR(ret); + if (!crtc_state->enable) + continue; - intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, "[modeset]"); + ret = intel_modeset_pipe_config(crtc, state); + if (ret) + return ret; - ret = drm_atomic_helper_check_planes(state->dev, state); - if (ret) - return ERR_PTR(ret); + intel_dump_pipe_config(to_intel_crtc(crtc), + to_intel_crtc_state(crtc_state), + "[modeset]"); + } - return pipe_config; + return drm_atomic_helper_check_planes(state->dev, state); } static int __intel_set_mode_setup_plls(struct drm_atomic_state *state) @@ -12977,37 +12973,27 @@ static int __intel_set_mode(struct drm_atomic_state *state) return 0; } -static int intel_set_mode_with_config(struct drm_crtc *crtc, - struct intel_crtc_state *pipe_config) +static int intel_set_mode_checked(struct drm_atomic_state *state) { + struct drm_device *dev = state->dev; int ret; - ret = __intel_set_mode(pipe_config->base.state); - + ret = __intel_set_mode(state); if (ret == 0) - intel_modeset_check_state(crtc->dev); + intel_modeset_check_state(dev); return ret; } -static int intel_set_mode(struct drm_crtc *crtc, - struct drm_atomic_state *state) +static int intel_set_mode(struct drm_atomic_state *state) { - struct intel_crtc_state *pipe_config; - int ret = 0; - - pipe_config = intel_modeset_compute_config(crtc, state); - if (IS_ERR(pipe_config)) { - ret = PTR_ERR(pipe_config); - goto out; - } + int ret; - ret = intel_set_mode_with_config(crtc, pipe_config); + ret = intel_modeset_compute_config(state); if (ret) - goto out; + return ret; -out: - return ret; + return intel_set_mode_checked(state); } void intel_crtc_restore_mode(struct drm_crtc *crtc) @@ -13079,7 +13065,7 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc) intel_modeset_setup_plane_state(state, crtc, &crtc->mode, crtc->primary->fb, crtc->x, crtc->y); - ret = intel_set_mode(crtc, state); + ret = intel_set_mode(state); if (ret) drm_atomic_state_free(state); } @@ -13229,7 +13215,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set) { struct drm_device *dev; struct drm_atomic_state *state = NULL; - struct intel_crtc_state *pipe_config; int ret; BUG_ON(!set); @@ -13260,16 +13245,13 @@ static int intel_crtc_set_config(struct drm_mode_set *set) if (ret) goto out; - pipe_config = intel_modeset_compute_config(set->crtc, state); - if (IS_ERR(pipe_config)) { - ret = PTR_ERR(pipe_config); + ret = intel_modeset_compute_config(state); + if (ret) goto out; - } intel_update_pipe_size(to_intel_crtc(set->crtc)); - ret = intel_set_mode_with_config(set->crtc, pipe_config); - + ret = intel_set_mode_checked(state); if (ret) { DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n", set->crtc->base.id, ret); -- 2.30.2