Commit 568c634a authored by Ander Conselvan de Oliveira's avatar Ander Conselvan de Oliveira Committed by Jani Nikula

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: default avatarAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent fb9d6cf8
...@@ -86,8 +86,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, ...@@ -86,8 +86,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
static void ironlake_pch_clock_get(struct intel_crtc *crtc, static void ironlake_pch_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config); struct intel_crtc_state *pipe_config);
static int intel_set_mode(struct drm_crtc *crtc, static int intel_set_mode(struct drm_atomic_state *state);
struct drm_atomic_state *state);
static int intel_framebuffer_init(struct drm_device *dev, static int intel_framebuffer_init(struct drm_device *dev,
struct intel_framebuffer *ifb, struct intel_framebuffer *ifb,
struct drm_mode_fb_cmd2 *mode_cmd, struct drm_mode_fb_cmd2 *mode_cmd,
...@@ -10482,7 +10481,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, ...@@ -10482,7 +10481,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
drm_mode_copy(&crtc_state->base.mode, mode); 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"); DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
if (old->release_fb) if (old->release_fb)
old->release_fb->funcs->destroy(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, ...@@ -10556,7 +10555,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
if (ret) if (ret)
goto fail; goto fail;
ret = intel_set_mode(crtc, state); ret = intel_set_mode(state);
if (ret) if (ret)
goto fail; goto fail;
...@@ -12068,9 +12067,10 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state) ...@@ -12068,9 +12067,10 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
static int static int
intel_modeset_pipe_config(struct drm_crtc *crtc, intel_modeset_pipe_config(struct drm_crtc *crtc,
struct drm_atomic_state *state, struct drm_atomic_state *state)
struct intel_crtc_state *pipe_config)
{ {
struct drm_crtc_state *crtc_state;
struct intel_crtc_state *pipe_config;
struct intel_encoder *encoder; struct intel_encoder *encoder;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *connector_state; struct drm_connector_state *connector_state;
...@@ -12088,6 +12088,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, ...@@ -12088,6 +12088,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
return -EINVAL; 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. * 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) ...@@ -12800,45 +12806,35 @@ static void update_scanline_offset(struct intel_crtc *crtc)
crtc->scanline_offset = 1; crtc->scanline_offset = 1;
} }
static struct intel_crtc_state * static int
intel_modeset_compute_config(struct drm_crtc *crtc, intel_modeset_compute_config(struct drm_atomic_state *state)
struct drm_atomic_state *state)
{ {
struct intel_crtc_state *pipe_config; struct drm_crtc *crtc;
int ret = 0; struct drm_crtc_state *crtc_state;
int ret, i;
ret = drm_atomic_helper_check_modeset(state->dev, state); ret = drm_atomic_helper_check_modeset(state->dev, state);
if (ret) if (ret)
return ERR_PTR(ret); return 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;
if (!pipe_config->base.enable) for_each_crtc_in_state(state, crtc, crtc_state, i) {
return pipe_config; if (!crtc_state->enable &&
WARN_ON(crtc_state->active))
crtc_state->active = false;
ret = intel_modeset_pipe_config(crtc, state, pipe_config); if (!crtc_state->enable)
if (ret) continue;
return ERR_PTR(ret);
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); intel_dump_pipe_config(to_intel_crtc(crtc),
if (ret) to_intel_crtc_state(crtc_state),
return ERR_PTR(ret); "[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) 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) ...@@ -12977,37 +12973,27 @@ static int __intel_set_mode(struct drm_atomic_state *state)
return 0; return 0;
} }
static int intel_set_mode_with_config(struct drm_crtc *crtc, static int intel_set_mode_checked(struct drm_atomic_state *state)
struct intel_crtc_state *pipe_config)
{ {
struct drm_device *dev = state->dev;
int ret; int ret;
ret = __intel_set_mode(pipe_config->base.state); ret = __intel_set_mode(state);
if (ret == 0) if (ret == 0)
intel_modeset_check_state(crtc->dev); intel_modeset_check_state(dev);
return ret; return ret;
} }
static int intel_set_mode(struct drm_crtc *crtc, static int intel_set_mode(struct drm_atomic_state *state)
struct drm_atomic_state *state)
{ {
struct intel_crtc_state *pipe_config; int ret;
int ret = 0;
pipe_config = intel_modeset_compute_config(crtc, state);
if (IS_ERR(pipe_config)) {
ret = PTR_ERR(pipe_config);
goto out;
}
ret = intel_set_mode_with_config(crtc, pipe_config); ret = intel_modeset_compute_config(state);
if (ret) if (ret)
goto out; return ret;
out: return intel_set_mode_checked(state);
return ret;
} }
void intel_crtc_restore_mode(struct drm_crtc *crtc) void intel_crtc_restore_mode(struct drm_crtc *crtc)
...@@ -13079,7 +13065,7 @@ 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, intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
crtc->primary->fb, crtc->x, crtc->y); crtc->primary->fb, crtc->x, crtc->y);
ret = intel_set_mode(crtc, state); ret = intel_set_mode(state);
if (ret) if (ret)
drm_atomic_state_free(state); drm_atomic_state_free(state);
} }
...@@ -13229,7 +13215,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set) ...@@ -13229,7 +13215,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
{ {
struct drm_device *dev; struct drm_device *dev;
struct drm_atomic_state *state = NULL; struct drm_atomic_state *state = NULL;
struct intel_crtc_state *pipe_config;
int ret; int ret;
BUG_ON(!set); BUG_ON(!set);
...@@ -13260,16 +13245,13 @@ static int intel_crtc_set_config(struct drm_mode_set *set) ...@@ -13260,16 +13245,13 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
if (ret) if (ret)
goto out; goto out;
pipe_config = intel_modeset_compute_config(set->crtc, state); ret = intel_modeset_compute_config(state);
if (IS_ERR(pipe_config)) { if (ret)
ret = PTR_ERR(pipe_config);
goto out; goto out;
}
intel_update_pipe_size(to_intel_crtc(set->crtc)); 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) { if (ret) {
DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n", DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
set->crtc->base.id, ret); set->crtc->base.id, ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment