Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+45 −63
Original line number Diff line number Diff line
@@ -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 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,

	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;
		return ret;

	if (!pipe_config->base.enable &&
	    WARN_ON(pipe_config->base.active))
		pipe_config->base.active = false;
	for_each_crtc_in_state(state, crtc, crtc_state, i) {
		if (!crtc_state->enable &&
		    WARN_ON(crtc_state->active))
			crtc_state->active = false;

	if (!pipe_config->base.enable)
		return pipe_config;
		if (!crtc_state->enable)
			continue;

	ret = intel_modeset_pipe_config(crtc, state, pipe_config);
		ret = intel_modeset_pipe_config(crtc, state);
		if (ret)
		return ERR_PTR(ret);

	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, "[modeset]");
			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;

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);