diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 52 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 71 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 3 |
3 files changed, 124 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7e77396a154e..527b664d3434 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -2949,6 +2949,7 @@ | |||
2949 | #define CURSOR_ENABLE 0x80000000 | 2949 | #define CURSOR_ENABLE 0x80000000 |
2950 | #define CURSOR_GAMMA_ENABLE 0x40000000 | 2950 | #define CURSOR_GAMMA_ENABLE 0x40000000 |
2951 | #define CURSOR_STRIDE_MASK 0x30000000 | 2951 | #define CURSOR_STRIDE_MASK 0x30000000 |
2952 | #define CURSOR_PIPE_CSC_ENABLE (1<<24) | ||
2952 | #define CURSOR_FORMAT_SHIFT 24 | 2953 | #define CURSOR_FORMAT_SHIFT 24 |
2953 | #define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT) | 2954 | #define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT) |
2954 | #define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT) | 2955 | #define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT) |
@@ -3010,6 +3011,7 @@ | |||
3010 | #define DISPPLANE_RGBA888 (0xf<<26) | 3011 | #define DISPPLANE_RGBA888 (0xf<<26) |
3011 | #define DISPPLANE_STEREO_ENABLE (1<<25) | 3012 | #define DISPPLANE_STEREO_ENABLE (1<<25) |
3012 | #define DISPPLANE_STEREO_DISABLE 0 | 3013 | #define DISPPLANE_STEREO_DISABLE 0 |
3014 | #define DISPPLANE_PIPE_CSC_ENABLE (1<<24) | ||
3013 | #define DISPPLANE_SEL_PIPE_SHIFT 24 | 3015 | #define DISPPLANE_SEL_PIPE_SHIFT 24 |
3014 | #define DISPPLANE_SEL_PIPE_MASK (3<<DISPPLANE_SEL_PIPE_SHIFT) | 3016 | #define DISPPLANE_SEL_PIPE_MASK (3<<DISPPLANE_SEL_PIPE_SHIFT) |
3015 | #define DISPPLANE_SEL_PIPE_A 0 | 3017 | #define DISPPLANE_SEL_PIPE_A 0 |
@@ -3098,6 +3100,7 @@ | |||
3098 | #define DVS_FORMAT_RGBX101010 (1<<25) | 3100 | #define DVS_FORMAT_RGBX101010 (1<<25) |
3099 | #define DVS_FORMAT_RGBX888 (2<<25) | 3101 | #define DVS_FORMAT_RGBX888 (2<<25) |
3100 | #define DVS_FORMAT_RGBX161616 (3<<25) | 3102 | #define DVS_FORMAT_RGBX161616 (3<<25) |
3103 | #define DVS_PIPE_CSC_ENABLE (1<<24) | ||
3101 | #define DVS_SOURCE_KEY (1<<22) | 3104 | #define DVS_SOURCE_KEY (1<<22) |
3102 | #define DVS_RGB_ORDER_XBGR (1<<20) | 3105 | #define DVS_RGB_ORDER_XBGR (1<<20) |
3103 | #define DVS_YUV_BYTE_ORDER_MASK (3<<16) | 3106 | #define DVS_YUV_BYTE_ORDER_MASK (3<<16) |
@@ -3165,7 +3168,7 @@ | |||
3165 | #define SPRITE_FORMAT_RGBX161616 (3<<25) | 3168 | #define SPRITE_FORMAT_RGBX161616 (3<<25) |
3166 | #define SPRITE_FORMAT_YUV444 (4<<25) | 3169 | #define SPRITE_FORMAT_YUV444 (4<<25) |
3167 | #define SPRITE_FORMAT_XR_BGR101010 (5<<25) /* Extended range */ | 3170 | #define SPRITE_FORMAT_XR_BGR101010 (5<<25) /* Extended range */ |
3168 | #define SPRITE_CSC_ENABLE (1<<24) | 3171 | #define SPRITE_PIPE_CSC_ENABLE (1<<24) |
3169 | #define SPRITE_SOURCE_KEY (1<<22) | 3172 | #define SPRITE_SOURCE_KEY (1<<22) |
3170 | #define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */ | 3173 | #define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */ |
3171 | #define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19) | 3174 | #define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19) |
@@ -4645,4 +4648,51 @@ | |||
4645 | #define WM_DBG_DISALLOW_MAXFIFO (1<<1) | 4648 | #define WM_DBG_DISALLOW_MAXFIFO (1<<1) |
4646 | #define WM_DBG_DISALLOW_SPRITE (1<<2) | 4649 | #define WM_DBG_DISALLOW_SPRITE (1<<2) |
4647 | 4650 | ||
4651 | /* pipe CSC */ | ||
4652 | #define _PIPE_A_CSC_COEFF_RY_GY 0x49010 | ||
4653 | #define _PIPE_A_CSC_COEFF_BY 0x49014 | ||
4654 | #define _PIPE_A_CSC_COEFF_RU_GU 0x49018 | ||
4655 | #define _PIPE_A_CSC_COEFF_BU 0x4901c | ||
4656 | #define _PIPE_A_CSC_COEFF_RV_GV 0x49020 | ||
4657 | #define _PIPE_A_CSC_COEFF_BV 0x49024 | ||
4658 | #define _PIPE_A_CSC_MODE 0x49028 | ||
4659 | #define _PIPE_A_CSC_PREOFF_HI 0x49030 | ||
4660 | #define _PIPE_A_CSC_PREOFF_ME 0x49034 | ||
4661 | #define _PIPE_A_CSC_PREOFF_LO 0x49038 | ||
4662 | #define _PIPE_A_CSC_POSTOFF_HI 0x49040 | ||
4663 | #define _PIPE_A_CSC_POSTOFF_ME 0x49044 | ||
4664 | #define _PIPE_A_CSC_POSTOFF_LO 0x49048 | ||
4665 | |||
4666 | #define _PIPE_B_CSC_COEFF_RY_GY 0x49110 | ||
4667 | #define _PIPE_B_CSC_COEFF_BY 0x49114 | ||
4668 | #define _PIPE_B_CSC_COEFF_RU_GU 0x49118 | ||
4669 | #define _PIPE_B_CSC_COEFF_BU 0x4911c | ||
4670 | #define _PIPE_B_CSC_COEFF_RV_GV 0x49120 | ||
4671 | #define _PIPE_B_CSC_COEFF_BV 0x49124 | ||
4672 | #define _PIPE_B_CSC_MODE 0x49128 | ||
4673 | #define _PIPE_B_CSC_PREOFF_HI 0x49130 | ||
4674 | #define _PIPE_B_CSC_PREOFF_ME 0x49134 | ||
4675 | #define _PIPE_B_CSC_PREOFF_LO 0x49138 | ||
4676 | #define _PIPE_B_CSC_POSTOFF_HI 0x49140 | ||
4677 | #define _PIPE_B_CSC_POSTOFF_ME 0x49144 | ||
4678 | #define _PIPE_B_CSC_POSTOFF_LO 0x49148 | ||
4679 | |||
4680 | #define CSC_BLACK_SCREEN_OFFSET (1 << 2) | ||
4681 | #define CSC_POSITION_BEFORE_GAMMA (1 << 1) | ||
4682 | #define CSC_MODE_YUV_TO_RGB (1 << 0) | ||
4683 | |||
4684 | #define PIPE_CSC_COEFF_RY_GY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RY_GY, _PIPE_B_CSC_COEFF_RY_GY) | ||
4685 | #define PIPE_CSC_COEFF_BY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BY, _PIPE_B_CSC_COEFF_BY) | ||
4686 | #define PIPE_CSC_COEFF_RU_GU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RU_GU, _PIPE_B_CSC_COEFF_RU_GU) | ||
4687 | #define PIPE_CSC_COEFF_BU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BU, _PIPE_B_CSC_COEFF_BU) | ||
4688 | #define PIPE_CSC_COEFF_RV_GV(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RV_GV, _PIPE_B_CSC_COEFF_RV_GV) | ||
4689 | #define PIPE_CSC_COEFF_BV(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BV, _PIPE_B_CSC_COEFF_BV) | ||
4690 | #define PIPE_CSC_MODE(pipe) _PIPE(pipe, _PIPE_A_CSC_MODE, _PIPE_B_CSC_MODE) | ||
4691 | #define PIPE_CSC_PREOFF_HI(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_HI, _PIPE_B_CSC_PREOFF_HI) | ||
4692 | #define PIPE_CSC_PREOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_ME, _PIPE_B_CSC_PREOFF_ME) | ||
4693 | #define PIPE_CSC_PREOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_LO, _PIPE_B_CSC_PREOFF_LO) | ||
4694 | #define PIPE_CSC_POSTOFF_HI(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_HI, _PIPE_B_CSC_POSTOFF_HI) | ||
4695 | #define PIPE_CSC_POSTOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME) | ||
4696 | #define PIPE_CSC_POSTOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO) | ||
4697 | |||
4648 | #endif /* _I915_REG_H_ */ | 4698 | #endif /* _I915_REG_H_ */ |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ba1d9131a5d6..6eb3882ba9bf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -5126,6 +5126,71 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc, | |||
5126 | POSTING_READ(PIPECONF(pipe)); | 5126 | POSTING_READ(PIPECONF(pipe)); |
5127 | } | 5127 | } |
5128 | 5128 | ||
5129 | /* | ||
5130 | * Set up the pipe CSC unit. | ||
5131 | * | ||
5132 | * Currently only full range RGB to limited range RGB conversion | ||
5133 | * is supported, but eventually this should handle various | ||
5134 | * RGB<->YCbCr scenarios as well. | ||
5135 | */ | ||
5136 | static void intel_set_pipe_csc(struct drm_crtc *crtc, | ||
5137 | const struct drm_display_mode *adjusted_mode) | ||
5138 | { | ||
5139 | struct drm_device *dev = crtc->dev; | ||
5140 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5141 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
5142 | int pipe = intel_crtc->pipe; | ||
5143 | uint16_t coeff = 0x7800; /* 1.0 */ | ||
5144 | |||
5145 | /* | ||
5146 | * TODO: Check what kind of values actually come out of the pipe | ||
5147 | * with these coeff/postoff values and adjust to get the best | ||
5148 | * accuracy. Perhaps we even need to take the bpc value into | ||
5149 | * consideration. | ||
5150 | */ | ||
5151 | |||
5152 | if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE) | ||
5153 | coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */ | ||
5154 | |||
5155 | /* | ||
5156 | * GY/GU and RY/RU should be the other way around according | ||
5157 | * to BSpec, but reality doesn't agree. Just set them up in | ||
5158 | * a way that results in the correct picture. | ||
5159 | */ | ||
5160 | I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff << 16); | ||
5161 | I915_WRITE(PIPE_CSC_COEFF_BY(pipe), 0); | ||
5162 | |||
5163 | I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff); | ||
5164 | I915_WRITE(PIPE_CSC_COEFF_BU(pipe), 0); | ||
5165 | |||
5166 | I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), 0); | ||
5167 | I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff << 16); | ||
5168 | |||
5169 | I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0); | ||
5170 | I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0); | ||
5171 | I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0); | ||
5172 | |||
5173 | if (INTEL_INFO(dev)->gen > 6) { | ||
5174 | uint16_t postoff = 0; | ||
5175 | |||
5176 | if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE) | ||
5177 | postoff = (16 * (1 << 13) / 255) & 0x1fff; | ||
5178 | |||
5179 | I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff); | ||
5180 | I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff); | ||
5181 | I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff); | ||
5182 | |||
5183 | I915_WRITE(PIPE_CSC_MODE(pipe), 0); | ||
5184 | } else { | ||
5185 | uint32_t mode = CSC_MODE_YUV_TO_RGB; | ||
5186 | |||
5187 | if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE) | ||
5188 | mode |= CSC_BLACK_SCREEN_OFFSET; | ||
5189 | |||
5190 | I915_WRITE(PIPE_CSC_MODE(pipe), mode); | ||
5191 | } | ||
5192 | } | ||
5193 | |||
5129 | static void haswell_set_pipeconf(struct drm_crtc *crtc, | 5194 | static void haswell_set_pipeconf(struct drm_crtc *crtc, |
5130 | struct drm_display_mode *adjusted_mode, | 5195 | struct drm_display_mode *adjusted_mode, |
5131 | bool dither) | 5196 | bool dither) |
@@ -5714,8 +5779,10 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, | |||
5714 | 5779 | ||
5715 | haswell_set_pipeconf(crtc, adjusted_mode, dither); | 5780 | haswell_set_pipeconf(crtc, adjusted_mode, dither); |
5716 | 5781 | ||
5782 | intel_set_pipe_csc(crtc, adjusted_mode); | ||
5783 | |||
5717 | /* Set up the display plane register */ | 5784 | /* Set up the display plane register */ |
5718 | I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE); | 5785 | I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE | DISPPLANE_PIPE_CSC_ENABLE); |
5719 | POSTING_READ(DSPCNTR(plane)); | 5786 | POSTING_READ(DSPCNTR(plane)); |
5720 | 5787 | ||
5721 | ret = intel_pipe_set_base(crtc, x, y, fb); | 5788 | ret = intel_pipe_set_base(crtc, x, y, fb); |
@@ -6120,6 +6187,8 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) | |||
6120 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | 6187 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); |
6121 | cntl |= CURSOR_MODE_DISABLE; | 6188 | cntl |= CURSOR_MODE_DISABLE; |
6122 | } | 6189 | } |
6190 | if (IS_HASWELL(dev)) | ||
6191 | cntl |= CURSOR_PIPE_CSC_ENABLE; | ||
6123 | I915_WRITE(CURCNTR_IVB(pipe), cntl); | 6192 | I915_WRITE(CURCNTR_IVB(pipe), cntl); |
6124 | 6193 | ||
6125 | intel_crtc->cursor_visible = visible; | 6194 | intel_crtc->cursor_visible = visible; |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 03cfd62d17e2..d086e48a831a 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -90,6 +90,9 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
90 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; | 90 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
91 | sprctl |= SPRITE_ENABLE; | 91 | sprctl |= SPRITE_ENABLE; |
92 | 92 | ||
93 | if (IS_HASWELL(dev)) | ||
94 | sprctl |= SPRITE_PIPE_CSC_ENABLE; | ||
95 | |||
93 | /* Sizes are 0 based */ | 96 | /* Sizes are 0 based */ |
94 | src_w--; | 97 | src_w--; |
95 | src_h--; | 98 | src_h--; |