diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2014-03-07 11:57:49 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-03-08 05:31:41 -0500 |
commit | 1ad292b51e358c8b6e9b8966889c21f1fe705489 (patch) | |
tree | acbc6b1c2e535c012851429216e394a9471a7de1 | |
parent | 46f297fb83d4f9a6f6891964beb184664341a28b (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.c | 63 |
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 | ||
5672 | static 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 | |||
5672 | static bool i9xx_get_pipe_config(struct intel_crtc *crtc, | 5733 | static 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; |