diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 128 |
1 files changed, 94 insertions, 34 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bf564a638dca..be5a73b6805a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3215,28 +3215,38 @@ i9xx_plane_max_stride(struct intel_plane *plane, | |||
3215 | } | 3215 | } |
3216 | } | 3216 | } |
3217 | 3217 | ||
3218 | static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state) | ||
3219 | { | ||
3220 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); | ||
3221 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | ||
3222 | u32 dspcntr = 0; | ||
3223 | |||
3224 | dspcntr |= DISPPLANE_GAMMA_ENABLE; | ||
3225 | |||
3226 | if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) | ||
3227 | dspcntr |= DISPPLANE_PIPE_CSC_ENABLE; | ||
3228 | |||
3229 | if (INTEL_GEN(dev_priv) < 5) | ||
3230 | dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe); | ||
3231 | |||
3232 | return dspcntr; | ||
3233 | } | ||
3234 | |||
3218 | static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, | 3235 | static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, |
3219 | const struct intel_plane_state *plane_state) | 3236 | const struct intel_plane_state *plane_state) |
3220 | { | 3237 | { |
3221 | struct drm_i915_private *dev_priv = | 3238 | struct drm_i915_private *dev_priv = |
3222 | to_i915(plane_state->base.plane->dev); | 3239 | to_i915(plane_state->base.plane->dev); |
3223 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); | ||
3224 | const struct drm_framebuffer *fb = plane_state->base.fb; | 3240 | const struct drm_framebuffer *fb = plane_state->base.fb; |
3225 | unsigned int rotation = plane_state->base.rotation; | 3241 | unsigned int rotation = plane_state->base.rotation; |
3226 | u32 dspcntr; | 3242 | u32 dspcntr; |
3227 | 3243 | ||
3228 | dspcntr = DISPLAY_PLANE_ENABLE | DISPPLANE_GAMMA_ENABLE; | 3244 | dspcntr = DISPLAY_PLANE_ENABLE; |
3229 | 3245 | ||
3230 | if (IS_G4X(dev_priv) || IS_GEN(dev_priv, 5) || | 3246 | if (IS_G4X(dev_priv) || IS_GEN(dev_priv, 5) || |
3231 | IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv)) | 3247 | IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv)) |
3232 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | 3248 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; |
3233 | 3249 | ||
3234 | if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) | ||
3235 | dspcntr |= DISPPLANE_PIPE_CSC_ENABLE; | ||
3236 | |||
3237 | if (INTEL_GEN(dev_priv) < 5) | ||
3238 | dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe); | ||
3239 | |||
3240 | switch (fb->format->format) { | 3250 | switch (fb->format->format) { |
3241 | case DRM_FORMAT_C8: | 3251 | case DRM_FORMAT_C8: |
3242 | dspcntr |= DISPPLANE_8BPP; | 3252 | dspcntr |= DISPPLANE_8BPP; |
@@ -3364,11 +3374,13 @@ static void i9xx_update_plane(struct intel_plane *plane, | |||
3364 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); | 3374 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
3365 | enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; | 3375 | enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; |
3366 | u32 linear_offset; | 3376 | u32 linear_offset; |
3367 | u32 dspcntr = plane_state->ctl; | ||
3368 | int x = plane_state->color_plane[0].x; | 3377 | int x = plane_state->color_plane[0].x; |
3369 | int y = plane_state->color_plane[0].y; | 3378 | int y = plane_state->color_plane[0].y; |
3370 | unsigned long irqflags; | 3379 | unsigned long irqflags; |
3371 | u32 dspaddr_offset; | 3380 | u32 dspaddr_offset; |
3381 | u32 dspcntr; | ||
3382 | |||
3383 | dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state); | ||
3372 | 3384 | ||
3373 | linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); | 3385 | linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); |
3374 | 3386 | ||
@@ -3428,10 +3440,23 @@ static void i9xx_disable_plane(struct intel_plane *plane, | |||
3428 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); | 3440 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
3429 | enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; | 3441 | enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; |
3430 | unsigned long irqflags; | 3442 | unsigned long irqflags; |
3443 | u32 dspcntr; | ||
3444 | |||
3445 | /* | ||
3446 | * DSPCNTR pipe gamma enable on g4x+ and pipe csc | ||
3447 | * enable on ilk+ affect the pipe bottom color as | ||
3448 | * well, so we must configure them even if the plane | ||
3449 | * is disabled. | ||
3450 | * | ||
3451 | * On pre-g4x there is no way to gamma correct the | ||
3452 | * pipe bottom color but we'll keep on doing this | ||
3453 | * anyway. | ||
3454 | */ | ||
3455 | dspcntr = i9xx_plane_ctl_crtc(crtc_state); | ||
3431 | 3456 | ||
3432 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); | 3457 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
3433 | 3458 | ||
3434 | I915_WRITE_FW(DSPCNTR(i9xx_plane), 0); | 3459 | I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr); |
3435 | if (INTEL_GEN(dev_priv) >= 4) | 3460 | if (INTEL_GEN(dev_priv) >= 4) |
3436 | I915_WRITE_FW(DSPSURF(i9xx_plane), 0); | 3461 | I915_WRITE_FW(DSPSURF(i9xx_plane), 0); |
3437 | else | 3462 | else |
@@ -3668,6 +3693,20 @@ static u32 cnl_plane_ctl_flip(unsigned int reflect) | |||
3668 | return 0; | 3693 | return 0; |
3669 | } | 3694 | } |
3670 | 3695 | ||
3696 | u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state) | ||
3697 | { | ||
3698 | struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); | ||
3699 | u32 plane_ctl = 0; | ||
3700 | |||
3701 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) | ||
3702 | return plane_ctl; | ||
3703 | |||
3704 | plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE; | ||
3705 | plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE; | ||
3706 | |||
3707 | return plane_ctl; | ||
3708 | } | ||
3709 | |||
3671 | u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, | 3710 | u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, |
3672 | const struct intel_plane_state *plane_state) | 3711 | const struct intel_plane_state *plane_state) |
3673 | { | 3712 | { |
@@ -3682,10 +3721,7 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, | |||
3682 | 3721 | ||
3683 | if (INTEL_GEN(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) { | 3722 | if (INTEL_GEN(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) { |
3684 | plane_ctl |= skl_plane_ctl_alpha(plane_state); | 3723 | plane_ctl |= skl_plane_ctl_alpha(plane_state); |
3685 | plane_ctl |= | 3724 | plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; |
3686 | PLANE_CTL_PIPE_GAMMA_ENABLE | | ||
3687 | PLANE_CTL_PIPE_CSC_ENABLE | | ||
3688 | PLANE_CTL_PLANE_GAMMA_DISABLE; | ||
3689 | 3725 | ||
3690 | if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) | 3726 | if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) |
3691 | plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709; | 3727 | plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709; |
@@ -3710,19 +3746,27 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, | |||
3710 | return plane_ctl; | 3746 | return plane_ctl; |
3711 | } | 3747 | } |
3712 | 3748 | ||
3749 | u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state) | ||
3750 | { | ||
3751 | struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); | ||
3752 | u32 plane_color_ctl = 0; | ||
3753 | |||
3754 | if (INTEL_GEN(dev_priv) >= 11) | ||
3755 | return plane_color_ctl; | ||
3756 | |||
3757 | plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE; | ||
3758 | plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE; | ||
3759 | |||
3760 | return plane_color_ctl; | ||
3761 | } | ||
3762 | |||
3713 | u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, | 3763 | u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, |
3714 | const struct intel_plane_state *plane_state) | 3764 | const struct intel_plane_state *plane_state) |
3715 | { | 3765 | { |
3716 | struct drm_i915_private *dev_priv = | ||
3717 | to_i915(plane_state->base.plane->dev); | ||
3718 | const struct drm_framebuffer *fb = plane_state->base.fb; | 3766 | const struct drm_framebuffer *fb = plane_state->base.fb; |
3719 | struct intel_plane *plane = to_intel_plane(plane_state->base.plane); | 3767 | struct intel_plane *plane = to_intel_plane(plane_state->base.plane); |
3720 | u32 plane_color_ctl = 0; | 3768 | u32 plane_color_ctl = 0; |
3721 | 3769 | ||
3722 | if (INTEL_GEN(dev_priv) < 11) { | ||
3723 | plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE; | ||
3724 | plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE; | ||
3725 | } | ||
3726 | plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; | 3770 | plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; |
3727 | plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state); | 3771 | plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state); |
3728 | 3772 | ||
@@ -9945,11 +9989,15 @@ i845_cursor_max_stride(struct intel_plane *plane, | |||
9945 | return 2048; | 9989 | return 2048; |
9946 | } | 9990 | } |
9947 | 9991 | ||
9992 | static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state) | ||
9993 | { | ||
9994 | return CURSOR_GAMMA_ENABLE; | ||
9995 | } | ||
9996 | |||
9948 | static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state, | 9997 | static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state, |
9949 | const struct intel_plane_state *plane_state) | 9998 | const struct intel_plane_state *plane_state) |
9950 | { | 9999 | { |
9951 | return CURSOR_ENABLE | | 10000 | return CURSOR_ENABLE | |
9952 | CURSOR_GAMMA_ENABLE | | ||
9953 | CURSOR_FORMAT_ARGB | | 10001 | CURSOR_FORMAT_ARGB | |
9954 | CURSOR_STRIDE(plane_state->color_plane[0].stride); | 10002 | CURSOR_STRIDE(plane_state->color_plane[0].stride); |
9955 | } | 10003 | } |
@@ -10019,7 +10067,9 @@ static void i845_update_cursor(struct intel_plane *plane, | |||
10019 | unsigned int width = plane_state->base.crtc_w; | 10067 | unsigned int width = plane_state->base.crtc_w; |
10020 | unsigned int height = plane_state->base.crtc_h; | 10068 | unsigned int height = plane_state->base.crtc_h; |
10021 | 10069 | ||
10022 | cntl = plane_state->ctl; | 10070 | cntl = plane_state->ctl | |
10071 | i845_cursor_ctl_crtc(crtc_state); | ||
10072 | |||
10023 | size = (height << 12) | width; | 10073 | size = (height << 12) | width; |
10024 | 10074 | ||
10025 | base = intel_cursor_base(plane_state); | 10075 | base = intel_cursor_base(plane_state); |
@@ -10086,27 +10136,36 @@ i9xx_cursor_max_stride(struct intel_plane *plane, | |||
10086 | return plane->base.dev->mode_config.cursor_width * 4; | 10136 | return plane->base.dev->mode_config.cursor_width * 4; |
10087 | } | 10137 | } |
10088 | 10138 | ||
10089 | static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state, | 10139 | static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state) |
10090 | const struct intel_plane_state *plane_state) | ||
10091 | { | 10140 | { |
10092 | struct drm_i915_private *dev_priv = | ||
10093 | to_i915(plane_state->base.plane->dev); | ||
10094 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); | 10141 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
10142 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | ||
10095 | u32 cntl = 0; | 10143 | u32 cntl = 0; |
10096 | 10144 | ||
10097 | if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv)) | 10145 | if (INTEL_GEN(dev_priv) >= 11) |
10098 | cntl |= MCURSOR_TRICKLE_FEED_DISABLE; | 10146 | return cntl; |
10099 | 10147 | ||
10100 | if (INTEL_GEN(dev_priv) <= 10) { | 10148 | cntl |= MCURSOR_GAMMA_ENABLE; |
10101 | cntl |= MCURSOR_GAMMA_ENABLE; | ||
10102 | 10149 | ||
10103 | if (HAS_DDI(dev_priv)) | 10150 | if (HAS_DDI(dev_priv)) |
10104 | cntl |= MCURSOR_PIPE_CSC_ENABLE; | 10151 | cntl |= MCURSOR_PIPE_CSC_ENABLE; |
10105 | } | ||
10106 | 10152 | ||
10107 | if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv)) | 10153 | if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv)) |
10108 | cntl |= MCURSOR_PIPE_SELECT(crtc->pipe); | 10154 | cntl |= MCURSOR_PIPE_SELECT(crtc->pipe); |
10109 | 10155 | ||
10156 | return cntl; | ||
10157 | } | ||
10158 | |||
10159 | static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state, | ||
10160 | const struct intel_plane_state *plane_state) | ||
10161 | { | ||
10162 | struct drm_i915_private *dev_priv = | ||
10163 | to_i915(plane_state->base.plane->dev); | ||
10164 | u32 cntl = 0; | ||
10165 | |||
10166 | if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv)) | ||
10167 | cntl |= MCURSOR_TRICKLE_FEED_DISABLE; | ||
10168 | |||
10110 | switch (plane_state->base.crtc_w) { | 10169 | switch (plane_state->base.crtc_w) { |
10111 | case 64: | 10170 | case 64: |
10112 | cntl |= MCURSOR_MODE_64_ARGB_AX; | 10171 | cntl |= MCURSOR_MODE_64_ARGB_AX; |
@@ -10231,7 +10290,8 @@ static void i9xx_update_cursor(struct intel_plane *plane, | |||
10231 | unsigned long irqflags; | 10290 | unsigned long irqflags; |
10232 | 10291 | ||
10233 | if (plane_state && plane_state->base.visible) { | 10292 | if (plane_state && plane_state->base.visible) { |
10234 | cntl = plane_state->ctl; | 10293 | cntl = plane_state->ctl | |
10294 | i9xx_cursor_ctl_crtc(crtc_state); | ||
10235 | 10295 | ||
10236 | if (plane_state->base.crtc_h != plane_state->base.crtc_w) | 10296 | if (plane_state->base.crtc_h != plane_state->base.crtc_w) |
10237 | fbc_ctl = CUR_FBC_CTL_EN | (plane_state->base.crtc_h - 1); | 10297 | fbc_ctl = CUR_FBC_CTL_EN | (plane_state->base.crtc_h - 1); |