diff options
| author | Damien Lespiau <damien.lespiau@intel.com> | 2015-01-20 07:51:51 -0500 |
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-01-27 03:51:04 -0500 |
| commit | bc8d7dffacb15bef89e21227c42e23d3ffc77b7b (patch) | |
| tree | b22d066bff3124400a20b11f844493c6720edce1 /drivers/gpu | |
| parent | b35d63fae6a2a3a0e1949228de07f795a73f23d0 (diff) | |
drm/i915/skl: Provide a Skylake version of get_plane_config()
Universal planes have changed a bit the register organization.
v2: Rebase on top of the latest drm-intel-nightly
v3: Use PLANE_SIZE to retrieve the fb size (Tvrtko)
Don't use BUG() (Tvrtko)
v4: Use MISSING_CASE (Daniel)
Reviewed-By: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 114 |
1 files changed, 107 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bd5b9a6e3a0e..30d99017f6cc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -2337,6 +2337,32 @@ static int i9xx_format_to_fourcc(int format) | |||
| 2337 | } | 2337 | } |
| 2338 | } | 2338 | } |
| 2339 | 2339 | ||
| 2340 | static int skl_format_to_fourcc(int format, bool rgb_order, bool alpha) | ||
| 2341 | { | ||
| 2342 | switch (format) { | ||
| 2343 | case PLANE_CTL_FORMAT_RGB_565: | ||
| 2344 | return DRM_FORMAT_RGB565; | ||
| 2345 | default: | ||
| 2346 | case PLANE_CTL_FORMAT_XRGB_8888: | ||
| 2347 | if (rgb_order) { | ||
| 2348 | if (alpha) | ||
| 2349 | return DRM_FORMAT_ABGR8888; | ||
| 2350 | else | ||
| 2351 | return DRM_FORMAT_XBGR8888; | ||
| 2352 | } else { | ||
| 2353 | if (alpha) | ||
| 2354 | return DRM_FORMAT_ARGB8888; | ||
| 2355 | else | ||
| 2356 | return DRM_FORMAT_XRGB8888; | ||
| 2357 | } | ||
| 2358 | case PLANE_CTL_FORMAT_XRGB_2101010: | ||
| 2359 | if (rgb_order) | ||
| 2360 | return DRM_FORMAT_XBGR2101010; | ||
| 2361 | else | ||
| 2362 | return DRM_FORMAT_XRGB2101010; | ||
| 2363 | } | ||
| 2364 | } | ||
| 2365 | |||
| 2340 | static bool intel_alloc_plane_obj(struct intel_crtc *crtc, | 2366 | static bool intel_alloc_plane_obj(struct intel_crtc *crtc, |
| 2341 | struct intel_plane_config *plane_config) | 2367 | struct intel_plane_config *plane_config) |
| 2342 | { | 2368 | { |
| @@ -7573,6 +7599,74 @@ static void skylake_get_pfit_config(struct intel_crtc *crtc, | |||
| 7573 | } | 7599 | } |
| 7574 | } | 7600 | } |
| 7575 | 7601 | ||
| 7602 | static void skylake_get_plane_config(struct intel_crtc *crtc, | ||
| 7603 | struct intel_plane_config *plane_config) | ||
| 7604 | { | ||
| 7605 | struct drm_device *dev = crtc->base.dev; | ||
| 7606 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 7607 | u32 val, base, offset, stride_mult; | ||
| 7608 | int pipe = crtc->pipe; | ||
| 7609 | int fourcc, pixel_format; | ||
| 7610 | int aligned_height; | ||
| 7611 | struct drm_framebuffer *fb; | ||
| 7612 | |||
| 7613 | fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL); | ||
| 7614 | if (!fb) { | ||
| 7615 | DRM_DEBUG_KMS("failed to alloc fb\n"); | ||
| 7616 | return; | ||
| 7617 | } | ||
| 7618 | |||
| 7619 | val = I915_READ(PLANE_CTL(pipe, 0)); | ||
| 7620 | if (val & PLANE_CTL_TILED_MASK) | ||
| 7621 | plane_config->tiling = I915_TILING_X; | ||
| 7622 | |||
| 7623 | pixel_format = val & PLANE_CTL_FORMAT_MASK; | ||
| 7624 | fourcc = skl_format_to_fourcc(pixel_format, | ||
| 7625 | val & PLANE_CTL_ORDER_RGBX, | ||
| 7626 | val & PLANE_CTL_ALPHA_MASK); | ||
| 7627 | fb->pixel_format = fourcc; | ||
| 7628 | fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8; | ||
| 7629 | |||
| 7630 | base = I915_READ(PLANE_SURF(pipe, 0)) & 0xfffff000; | ||
| 7631 | plane_config->base = base; | ||
| 7632 | |||
| 7633 | offset = I915_READ(PLANE_OFFSET(pipe, 0)); | ||
| 7634 | |||
| 7635 | val = I915_READ(PLANE_SIZE(pipe, 0)); | ||
| 7636 | fb->height = ((val >> 16) & 0xfff) + 1; | ||
| 7637 | fb->width = ((val >> 0) & 0x1fff) + 1; | ||
| 7638 | |||
| 7639 | val = I915_READ(PLANE_STRIDE(pipe, 0)); | ||
| 7640 | switch (plane_config->tiling) { | ||
| 7641 | case I915_TILING_NONE: | ||
| 7642 | stride_mult = 64; | ||
| 7643 | break; | ||
| 7644 | case I915_TILING_X: | ||
| 7645 | stride_mult = 512; | ||
| 7646 | break; | ||
| 7647 | default: | ||
| 7648 | MISSING_CASE(plane_config->tiling); | ||
| 7649 | goto error; | ||
| 7650 | } | ||
| 7651 | fb->pitches[0] = (val & 0x3ff) * stride_mult; | ||
| 7652 | |||
| 7653 | aligned_height = intel_fb_align_height(dev, fb->height, | ||
| 7654 | plane_config->tiling); | ||
| 7655 | |||
| 7656 | plane_config->size = ALIGN(fb->pitches[0] * aligned_height, PAGE_SIZE); | ||
| 7657 | |||
| 7658 | DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", | ||
| 7659 | pipe_name(pipe), fb->width, fb->height, | ||
| 7660 | fb->bits_per_pixel, base, fb->pitches[0], | ||
| 7661 | plane_config->size); | ||
| 7662 | |||
| 7663 | crtc->base.primary->fb = fb; | ||
| 7664 | return; | ||
| 7665 | |||
| 7666 | error: | ||
| 7667 | kfree(fb); | ||
| 7668 | } | ||
| 7669 | |||
| 7576 | static void ironlake_get_pfit_config(struct intel_crtc *crtc, | 7670 | static void ironlake_get_pfit_config(struct intel_crtc *crtc, |
| 7577 | struct intel_crtc_state *pipe_config) | 7671 | struct intel_crtc_state *pipe_config) |
| 7578 | { | 7672 | { |
| @@ -12668,7 +12762,17 @@ static void intel_init_display(struct drm_device *dev) | |||
| 12668 | else | 12762 | else |
| 12669 | dev_priv->display.find_dpll = i9xx_find_best_dpll; | 12763 | dev_priv->display.find_dpll = i9xx_find_best_dpll; |
| 12670 | 12764 | ||
| 12671 | if (HAS_DDI(dev)) { | 12765 | if (INTEL_INFO(dev)->gen >= 9) { |
| 12766 | dev_priv->display.get_pipe_config = haswell_get_pipe_config; | ||
| 12767 | dev_priv->display.get_plane_config = skylake_get_plane_config; | ||
| 12768 | dev_priv->display.crtc_compute_clock = | ||
| 12769 | haswell_crtc_compute_clock; | ||
| 12770 | dev_priv->display.crtc_enable = haswell_crtc_enable; | ||
| 12771 | dev_priv->display.crtc_disable = haswell_crtc_disable; | ||
| 12772 | dev_priv->display.off = ironlake_crtc_off; | ||
| 12773 | dev_priv->display.update_primary_plane = | ||
| 12774 | skylake_update_primary_plane; | ||
| 12775 | } else if (HAS_DDI(dev)) { | ||
| 12672 | dev_priv->display.get_pipe_config = haswell_get_pipe_config; | 12776 | dev_priv->display.get_pipe_config = haswell_get_pipe_config; |
| 12673 | dev_priv->display.get_plane_config = ironlake_get_plane_config; | 12777 | dev_priv->display.get_plane_config = ironlake_get_plane_config; |
| 12674 | dev_priv->display.crtc_compute_clock = | 12778 | dev_priv->display.crtc_compute_clock = |
| @@ -12676,12 +12780,8 @@ static void intel_init_display(struct drm_device *dev) | |||
| 12676 | dev_priv->display.crtc_enable = haswell_crtc_enable; | 12780 | dev_priv->display.crtc_enable = haswell_crtc_enable; |
| 12677 | dev_priv->display.crtc_disable = haswell_crtc_disable; | 12781 | dev_priv->display.crtc_disable = haswell_crtc_disable; |
| 12678 | dev_priv->display.off = ironlake_crtc_off; | 12782 | dev_priv->display.off = ironlake_crtc_off; |
| 12679 | if (INTEL_INFO(dev)->gen >= 9) | 12783 | dev_priv->display.update_primary_plane = |
| 12680 | dev_priv->display.update_primary_plane = | 12784 | ironlake_update_primary_plane; |
| 12681 | skylake_update_primary_plane; | ||
| 12682 | else | ||
| 12683 | dev_priv->display.update_primary_plane = | ||
| 12684 | ironlake_update_primary_plane; | ||
| 12685 | } else if (HAS_PCH_SPLIT(dev)) { | 12785 | } else if (HAS_PCH_SPLIT(dev)) { |
| 12686 | dev_priv->display.get_pipe_config = ironlake_get_pipe_config; | 12786 | dev_priv->display.get_pipe_config = ironlake_get_pipe_config; |
| 12687 | dev_priv->display.get_plane_config = ironlake_get_plane_config; | 12787 | dev_priv->display.get_plane_config = ironlake_get_plane_config; |
