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

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
...@@ -5669,6 +5669,67 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc, ...@@ -5669,6 +5669,67 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
pipe_config->port_clock = clock.dot / 5; 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, static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config) struct intel_crtc_config *pipe_config)
{ {
...@@ -10828,6 +10889,7 @@ static void intel_init_display(struct drm_device *dev) ...@@ -10828,6 +10889,7 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.update_plane = ironlake_update_plane; dev_priv->display.update_plane = ironlake_update_plane;
} else if (IS_VALLEYVIEW(dev)) { } else if (IS_VALLEYVIEW(dev)) {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config; 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_mode_set = i9xx_crtc_mode_set;
dev_priv->display.crtc_enable = valleyview_crtc_enable; dev_priv->display.crtc_enable = valleyview_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable; dev_priv->display.crtc_disable = i9xx_crtc_disable;
...@@ -10835,6 +10897,7 @@ static void intel_init_display(struct drm_device *dev) ...@@ -10835,6 +10897,7 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.update_plane = i9xx_update_plane; dev_priv->display.update_plane = i9xx_update_plane;
} else { } else {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config; 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_mode_set = i9xx_crtc_mode_set;
dev_priv->display.crtc_enable = i9xx_crtc_enable; dev_priv->display.crtc_enable = i9xx_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable; dev_priv->display.crtc_disable = i9xx_crtc_disable;
......
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