diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 92 |
1 files changed, 90 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dc264de4e39..65f4ff66820 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2644,6 +2644,90 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc, POSTING_READ(reg); } +static void skylake_update_primary_plane(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int x, int y) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_framebuffer *intel_fb; + struct drm_i915_gem_object *obj; + int pipe = intel_crtc->pipe; + u32 plane_ctl, stride; + + if (!intel_crtc->primary_enabled) { + I915_WRITE(PLANE_CTL(pipe, 0), 0); + I915_WRITE(PLANE_SURF(pipe, 0), 0); + POSTING_READ(PLANE_CTL(pipe, 0)); + return; + } + + plane_ctl = PLANE_CTL_ENABLE | + PLANE_CTL_PIPE_GAMMA_ENABLE | + PLANE_CTL_PIPE_CSC_ENABLE; + + switch (fb->pixel_format) { + case DRM_FORMAT_RGB565: + plane_ctl |= PLANE_CTL_FORMAT_RGB_565; + break; + case DRM_FORMAT_XRGB8888: + plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888; + break; + case DRM_FORMAT_XBGR8888: + plane_ctl |= PLANE_CTL_ORDER_RGBX; + plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888; + break; + case DRM_FORMAT_XRGB2101010: + plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010; + break; + case DRM_FORMAT_XBGR2101010: + plane_ctl |= PLANE_CTL_ORDER_RGBX; + plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010; + break; + default: + BUG(); + } + + intel_fb = to_intel_framebuffer(fb); + obj = intel_fb->obj; + + /* + * The stride is either expressed as a multiple of 64 bytes chunks for + * linear buffers or in number of tiles for tiled buffers. + */ + switch (obj->tiling_mode) { + case I915_TILING_NONE: + stride = fb->pitches[0] >> 6; + break; + case I915_TILING_X: + plane_ctl |= PLANE_CTL_TILED_X; + stride = fb->pitches[0] >> 9; + break; + default: + BUG(); + } + + plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; + + I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl); + + DRM_DEBUG_KMS("Writing base %08lX %d,%d,%d,%d pitch=%d\n", + i915_gem_obj_ggtt_offset(obj), + x, y, fb->width, fb->height, + fb->pitches[0]); + + I915_WRITE(PLANE_POS(pipe, 0), 0); + I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x); + I915_WRITE(PLANE_SIZE(pipe, 0), + (intel_crtc->config.pipe_src_h - 1) << 16 | + (intel_crtc->config.pipe_src_w - 1)); + I915_WRITE(PLANE_STRIDE(pipe, 0), stride); + I915_WRITE(PLANE_SURF(pipe, 0), i915_gem_obj_ggtt_offset(obj)); + + POSTING_READ(PLANE_SURF(pipe, 0)); +} + /* Assume fb object is pinned & idle & fenced and just update base pointers */ static int intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -12581,8 +12665,12 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.crtc_enable = haswell_crtc_enable; dev_priv->display.crtc_disable = haswell_crtc_disable; dev_priv->display.off = ironlake_crtc_off; - dev_priv->display.update_primary_plane = - ironlake_update_primary_plane; + if (INTEL_INFO(dev)->gen >= 9) + dev_priv->display.update_primary_plane = + skylake_update_primary_plane; + else + dev_priv->display.update_primary_plane = + ironlake_update_primary_plane; } else if (HAS_PCH_SPLIT(dev)) { dev_priv->display.get_pipe_config = ironlake_get_pipe_config; dev_priv->display.get_plane_config = ironlake_get_plane_config; |