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

Commit d3a40d1b authored by Ander Conselvan de Oliveira's avatar Ander Conselvan de Oliveira Committed by Daniel Vetter
Browse files

drm/i915: Add primary plane to atomic state in legacy modeset



Add the primary plane state to the legacy modeset atomic state and use
it when configuring the primary plane in __intel_set_mode(). This is a
first step towards merging the flip path in intel_crtc_set_config() and
__intel_set_mode().

v2: Set crtc to NULL if fb is NULL. (Maarten)

Signed-off-by: default avatarAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Reviewed-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 561c8bda
Loading
Loading
Loading
Loading
+71 −12
Original line number Original line Diff line number Diff line
@@ -9710,6 +9710,41 @@ mode_fits_in_fbdev(struct drm_device *dev,
#endif
#endif
}
}


static int intel_modeset_setup_plane_state(struct drm_atomic_state *state,
					   struct drm_crtc *crtc,
					   struct drm_display_mode *mode,
					   struct drm_framebuffer *fb,
					   int x, int y)
{
	struct drm_plane_state *plane_state;
	int hdisplay, vdisplay;
	int ret;

	plane_state = drm_atomic_get_plane_state(state, crtc->primary);
	if (IS_ERR(plane_state))
		return PTR_ERR(plane_state);

	if (mode)
		drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
	else
		hdisplay = vdisplay = 0;

	ret = drm_atomic_set_crtc_for_plane(plane_state, fb ? crtc : NULL);
	if (ret)
		return ret;
	drm_atomic_set_fb_for_plane(plane_state, fb);
	plane_state->crtc_x = 0;
	plane_state->crtc_y = 0;
	plane_state->crtc_w = hdisplay;
	plane_state->crtc_h = vdisplay;
	plane_state->src_x = x << 16;
	plane_state->src_y = y << 16;
	plane_state->src_w = hdisplay << 16;
	plane_state->src_h = vdisplay << 16;

	return 0;
}

bool intel_get_load_detect_pipe(struct drm_connector *connector,
bool intel_get_load_detect_pipe(struct drm_connector *connector,
				struct drm_display_mode *mode,
				struct drm_display_mode *mode,
				struct intel_load_detect_pipe *old,
				struct intel_load_detect_pipe *old,
@@ -9852,6 +9887,10 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
		goto fail;
		goto fail;
	}
	}


	ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0);
	if (ret)
		goto fail;

	if (intel_set_mode(crtc, mode, 0, 0, fb, state)) {
	if (intel_set_mode(crtc, mode, 0, 0, fb, 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)
@@ -9891,6 +9930,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
	struct drm_atomic_state *state;
	struct drm_atomic_state *state;
	struct drm_connector_state *connector_state;
	struct drm_connector_state *connector_state;
	struct intel_crtc_state *crtc_state;
	struct intel_crtc_state *crtc_state;
	int ret;


	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
		      connector->base.id, connector->name,
		      connector->base.id, connector->name,
@@ -9920,6 +9960,11 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,


		crtc_state->base.enable = false;
		crtc_state->base.enable = false;


		ret = intel_modeset_setup_plane_state(state, crtc, NULL, NULL,
						      0, 0);
		if (ret)
			goto fail;

		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
		intel_set_mode(crtc, NULL, 0, 0, NULL, state);


		drm_atomic_state_free(state);
		drm_atomic_state_free(state);
@@ -12270,6 +12315,8 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
	struct intel_crtc *intel_crtc;
	struct intel_crtc *intel_crtc;
	struct drm_crtc *crtc;
	struct drm_crtc *crtc;
	struct drm_crtc_state *crtc_state;
	struct drm_crtc_state *crtc_state;
	struct drm_plane *plane;
	struct drm_plane_state *plane_state;
	int ret = 0;
	int ret = 0;
	int i;
	int i;


@@ -12321,20 +12368,24 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,


	modeset_update_crtc_power_domains(state);
	modeset_update_crtc_power_domains(state);


	if (pipe_config->base.enable && needs_modeset(&pipe_config->base)) {
	for_each_plane_in_state(state, plane, plane_state, i) {
		struct drm_plane *primary;
		if (WARN_ON(plane != modeset_crtc->primary))
		int vdisplay, hdisplay;
			continue;

		intel_crtc = to_intel_crtc(modeset_crtc);
		primary = intel_crtc->base.primary;


		drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
		/* Primary plane is disabled in intel_crtc_disable() */
		if (!pipe_config->base.enable)
			continue;


		ret = drm_plane_helper_update(primary, &intel_crtc->base,
		ret = drm_plane_helper_update(plane, plane_state->crtc,
					      fb, 0, 0,
					      plane_state->fb,
					      hdisplay, vdisplay,
					      plane_state->crtc_x,
					      x << 16, y << 16,
					      plane_state->crtc_y,
					      hdisplay << 16, vdisplay << 16);
					      plane_state->crtc_w,
					      plane_state->crtc_h,
					      plane_state->src_x,
					      plane_state->src_y,
					      plane_state->src_w,
					      plane_state->src_h);
		WARN_ON(ret != 0);
		WARN_ON(ret != 0);
	}
	}


@@ -12460,6 +12511,9 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
		crtc_state->base.enable = intel_crtc->new_enabled;
		crtc_state->base.enable = intel_crtc->new_enabled;
	}
	}


	intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
					crtc->primary->fb, crtc->x, crtc->y);

	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
		       state);
		       state);


@@ -12834,6 +12888,11 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
	if (ret)
	if (ret)
		goto fail;
		goto fail;


	ret = intel_modeset_setup_plane_state(state, set->crtc, set->mode,
					      set->fb, set->x, set->y);
	if (ret)
		goto fail;

	/* Compute whether we need a full modeset, only an fb base update or no
	/* Compute whether we need a full modeset, only an fb base update or no
	 * change at all. In the future we might also check whether only the
	 * change at all. In the future we might also check whether only the
	 * mode changed, e.g. for LVDS where we only change the panel fitter in
	 * mode changed, e.g. for LVDS where we only change the panel fitter in