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

Commit 1ad292b5 authored by Jesse Barnes's avatar Jesse Barnes Committed by Daniel Vetter
Browse files

drm/i915: get_plane_config for i9xx v13



Read out the current plane configuration at init time into a new
plane_config structure.  This allows us to track any existing
framebuffers attached to the plane and potentially re-use them in our
fbdev code for a smooth handoff.

v2: update for new pitch_for_width function (Jesse)
    comment how get_plane_config works with shared fbs (Jesse)
v3: s/ARGB/XRGB (Ville)
    use pipesrc width/height (Ville)
    fix fourcc comment (Bob)
    use drm_format_plane_cpp (Ville)
v4: use fb for tracking fb data object (Ville)
v5: fix up gen2 pitch limits (Ville)
v6: read out stride as well (Daniel)
v7: split out init ordering changes (Daniel)
    don't fetch config if !CONFIG_FB
v8: use proper height in get_plane_config (Chris)
v9: fix CONFIG_FB check for modular configs (Jani)
v10: add comment about stolen allocation stomping
v11: drop hw state readout hunk (Daniel)
v12: handle tiled BIOS fbs (Kristian)
     pull out common bits (Jesse)
v13: move fb obj alloc out to _init

Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 46f297fb
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -5669,6 +5669,67 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
	pipe_config->port_clock = clock.dot / 5;
}

static void i9xx_get_plane_config(struct intel_crtc *crtc,
				  struct intel_plane_config *plane_config)
{
	struct drm_device *dev = crtc->base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 val, base, offset;
	int pipe = crtc->pipe, plane = crtc->plane;
	int fourcc, pixel_format;
	int aligned_height;

	plane_config->fb = kzalloc(sizeof(*plane_config->fb), GFP_KERNEL);
	if (!plane_config->fb) {
		DRM_DEBUG_KMS("failed to alloc fb\n");
		return;
	}

	val = I915_READ(DSPCNTR(plane));

	if (INTEL_INFO(dev)->gen >= 4)
		if (val & DISPPLANE_TILED)
			plane_config->tiled = true;

	pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
	fourcc = intel_format_to_fourcc(pixel_format);
	plane_config->fb->base.pixel_format = fourcc;
	plane_config->fb->base.bits_per_pixel =
		drm_format_plane_cpp(fourcc, 0) * 8;

	if (INTEL_INFO(dev)->gen >= 4) {
		if (plane_config->tiled)
			offset = I915_READ(DSPTILEOFF(plane));
		else
			offset = I915_READ(DSPLINOFF(plane));
		base = I915_READ(DSPSURF(plane)) & 0xfffff000;
	} else {
		base = I915_READ(DSPADDR(plane));
	}
	plane_config->base = base;

	val = I915_READ(PIPESRC(pipe));
	plane_config->fb->base.width = ((val >> 16) & 0xfff) + 1;
	plane_config->fb->base.height = ((val >> 0) & 0xfff) + 1;

	val = I915_READ(DSPSTRIDE(pipe));
	plane_config->fb->base.pitches[0] = val & 0xffffff80;

	aligned_height = intel_align_height(dev, plane_config->fb->base.height,
					    plane_config->tiled);

	plane_config->size = ALIGN(plane_config->fb->base.pitches[0] *
				   aligned_height, PAGE_SIZE);

	DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
		      pipe, plane, plane_config->fb->base.width,
		      plane_config->fb->base.height,
		      plane_config->fb->base.bits_per_pixel, base,
		      plane_config->fb->base.pitches[0],
		      plane_config->size);

}

static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
				 struct intel_crtc_config *pipe_config)
{
@@ -10828,6 +10889,7 @@ static void intel_init_display(struct drm_device *dev)
		dev_priv->display.update_plane = ironlake_update_plane;
	} else if (IS_VALLEYVIEW(dev)) {
		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
		dev_priv->display.get_plane_config = i9xx_get_plane_config;
		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
		dev_priv->display.crtc_enable = valleyview_crtc_enable;
		dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -10835,6 +10897,7 @@ static void intel_init_display(struct drm_device *dev)
		dev_priv->display.update_plane = i9xx_update_plane;
	} else {
		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
		dev_priv->display.get_plane_config = i9xx_get_plane_config;
		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
		dev_priv->display.crtc_enable = i9xx_crtc_enable;
		dev_priv->display.crtc_disable = i9xx_crtc_disable;