aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2014-03-07 11:57:49 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-03-08 05:31:41 -0500
commit1ad292b51e358c8b6e9b8966889c21f1fe705489 (patch)
treeacbc6b1c2e535c012851429216e394a9471a7de1
parent46f297fb83d4f9a6f6891964beb184664341a28b (diff)
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: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 482b8d4bd94a..447649775779 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5669,6 +5669,67 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
5669 pipe_config->port_clock = clock.dot / 5; 5669 pipe_config->port_clock = clock.dot / 5;
5670} 5670}
5671 5671
5672static void i9xx_get_plane_config(struct intel_crtc *crtc,
5673 struct intel_plane_config *plane_config)
5674{
5675 struct drm_device *dev = crtc->base.dev;
5676 struct drm_i915_private *dev_priv = dev->dev_private;
5677 u32 val, base, offset;
5678 int pipe = crtc->pipe, plane = crtc->plane;
5679 int fourcc, pixel_format;
5680 int aligned_height;
5681
5682 plane_config->fb = kzalloc(sizeof(*plane_config->fb), GFP_KERNEL);
5683 if (!plane_config->fb) {
5684 DRM_DEBUG_KMS("failed to alloc fb\n");
5685 return;
5686 }
5687
5688 val = I915_READ(DSPCNTR(plane));
5689
5690 if (INTEL_INFO(dev)->gen >= 4)
5691 if (val & DISPPLANE_TILED)
5692 plane_config->tiled = true;
5693
5694 pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
5695 fourcc = intel_format_to_fourcc(pixel_format);
5696 plane_config->fb->base.pixel_format = fourcc;
5697 plane_config->fb->base.bits_per_pixel =
5698 drm_format_plane_cpp(fourcc, 0) * 8;
5699
5700 if (INTEL_INFO(dev)->gen >= 4) {
5701 if (plane_config->tiled)
5702 offset = I915_READ(DSPTILEOFF(plane));
5703 else
5704 offset = I915_READ(DSPLINOFF(plane));
5705 base = I915_READ(DSPSURF(plane)) & 0xfffff000;
5706 } else {
5707 base = I915_READ(DSPADDR(plane));
5708 }
5709 plane_config->base = base;
5710
5711 val = I915_READ(PIPESRC(pipe));
5712 plane_config->fb->base.width = ((val >> 16) & 0xfff) + 1;
5713 plane_config->fb->base.height = ((val >> 0) & 0xfff) + 1;
5714
5715 val = I915_READ(DSPSTRIDE(pipe));
5716 plane_config->fb->base.pitches[0] = val & 0xffffff80;
5717
5718 aligned_height = intel_align_height(dev, plane_config->fb->base.height,
5719 plane_config->tiled);
5720
5721 plane_config->size = ALIGN(plane_config->fb->base.pitches[0] *
5722 aligned_height, PAGE_SIZE);
5723
5724 DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
5725 pipe, plane, plane_config->fb->base.width,
5726 plane_config->fb->base.height,
5727 plane_config->fb->base.bits_per_pixel, base,
5728 plane_config->fb->base.pitches[0],
5729 plane_config->size);
5730
5731}
5732
5672static bool i9xx_get_pipe_config(struct intel_crtc *crtc, 5733static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
5673 struct intel_crtc_config *pipe_config) 5734 struct intel_crtc_config *pipe_config)
5674{ 5735{
@@ -10828,6 +10889,7 @@ static void intel_init_display(struct drm_device *dev)
10828 dev_priv->display.update_plane = ironlake_update_plane; 10889 dev_priv->display.update_plane = ironlake_update_plane;
10829 } else if (IS_VALLEYVIEW(dev)) { 10890 } else if (IS_VALLEYVIEW(dev)) {
10830 dev_priv->display.get_pipe_config = i9xx_get_pipe_config; 10891 dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
10892 dev_priv->display.get_plane_config = i9xx_get_plane_config;
10831 dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; 10893 dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
10832 dev_priv->display.crtc_enable = valleyview_crtc_enable; 10894 dev_priv->display.crtc_enable = valleyview_crtc_enable;
10833 dev_priv->display.crtc_disable = i9xx_crtc_disable; 10895 dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -10835,6 +10897,7 @@ static void intel_init_display(struct drm_device *dev)
10835 dev_priv->display.update_plane = i9xx_update_plane; 10897 dev_priv->display.update_plane = i9xx_update_plane;
10836 } else { 10898 } else {
10837 dev_priv->display.get_pipe_config = i9xx_get_pipe_config; 10899 dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
10900 dev_priv->display.get_plane_config = i9xx_get_plane_config;
10838 dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; 10901 dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
10839 dev_priv->display.crtc_enable = i9xx_crtc_enable; 10902 dev_priv->display.crtc_enable = i9xx_crtc_enable;
10840 dev_priv->display.crtc_disable = i9xx_crtc_disable; 10903 dev_priv->display.crtc_disable = i9xx_crtc_disable;