UAPI: (Scripted) Convert #include "..." to #include <path/...> in drivers/gpu/
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / gpu / drm / i915 / intel_overlay.c
CommitLineData
02e792fb
DV
1/*
2 * Copyright © 2009
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 * Daniel Vetter <daniel@ffwll.ch>
25 *
26 * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
27 */
760285e7
DH
28#include <drm/drmP.h>
29#include <drm/i915_drm.h>
02e792fb
DV
30#include "i915_drv.h"
31#include "i915_reg.h"
32#include "intel_drv.h"
33
34/* Limits for overlay size. According to intel doc, the real limits are:
35 * Y width: 4095, UV width (planar): 2047, Y height: 2047,
36 * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
37 * the mininum of both. */
38#define IMAGE_MAX_WIDTH 2048
39#define IMAGE_MAX_HEIGHT 2046 /* 2 * 1023 */
40/* on 830 and 845 these large limits result in the card hanging */
41#define IMAGE_MAX_WIDTH_LEGACY 1024
42#define IMAGE_MAX_HEIGHT_LEGACY 1088
43
44/* overlay register definitions */
45/* OCMD register */
46#define OCMD_TILED_SURFACE (0x1<<19)
47#define OCMD_MIRROR_MASK (0x3<<17)
48#define OCMD_MIRROR_MODE (0x3<<17)
49#define OCMD_MIRROR_HORIZONTAL (0x1<<17)
50#define OCMD_MIRROR_VERTICAL (0x2<<17)
51#define OCMD_MIRROR_BOTH (0x3<<17)
52#define OCMD_BYTEORDER_MASK (0x3<<14) /* zero for YUYV or FOURCC YUY2 */
53#define OCMD_UV_SWAP (0x1<<14) /* YVYU */
54#define OCMD_Y_SWAP (0x2<<14) /* UYVY or FOURCC UYVY */
55#define OCMD_Y_AND_UV_SWAP (0x3<<14) /* VYUY */
56#define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
57#define OCMD_RGB_888 (0x1<<10) /* not in i965 Intel docs */
58#define OCMD_RGB_555 (0x2<<10) /* not in i965 Intel docs */
59#define OCMD_RGB_565 (0x3<<10) /* not in i965 Intel docs */
60#define OCMD_YUV_422_PACKED (0x8<<10)
61#define OCMD_YUV_411_PACKED (0x9<<10) /* not in i965 Intel docs */
62#define OCMD_YUV_420_PLANAR (0xc<<10)
63#define OCMD_YUV_422_PLANAR (0xd<<10)
64#define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */
65#define OCMD_TVSYNCFLIP_PARITY (0x1<<9)
66#define OCMD_TVSYNCFLIP_ENABLE (0x1<<7)
d7961364 67#define OCMD_BUF_TYPE_MASK (0x1<<5)
02e792fb
DV
68#define OCMD_BUF_TYPE_FRAME (0x0<<5)
69#define OCMD_BUF_TYPE_FIELD (0x1<<5)
70#define OCMD_TEST_MODE (0x1<<4)
71#define OCMD_BUFFER_SELECT (0x3<<2)
72#define OCMD_BUFFER0 (0x0<<2)
73#define OCMD_BUFFER1 (0x1<<2)
74#define OCMD_FIELD_SELECT (0x1<<2)
75#define OCMD_FIELD0 (0x0<<1)
76#define OCMD_FIELD1 (0x1<<1)
77#define OCMD_ENABLE (0x1<<0)
78
79/* OCONFIG register */
80#define OCONF_PIPE_MASK (0x1<<18)
81#define OCONF_PIPE_A (0x0<<18)
82#define OCONF_PIPE_B (0x1<<18)
83#define OCONF_GAMMA2_ENABLE (0x1<<16)
84#define OCONF_CSC_MODE_BT601 (0x0<<5)
85#define OCONF_CSC_MODE_BT709 (0x1<<5)
86#define OCONF_CSC_BYPASS (0x1<<4)
87#define OCONF_CC_OUT_8BIT (0x1<<3)
88#define OCONF_TEST_MODE (0x1<<2)
89#define OCONF_THREE_LINE_BUFFER (0x1<<0)
90#define OCONF_TWO_LINE_BUFFER (0x0<<0)
91
92/* DCLRKM (dst-key) register */
93#define DST_KEY_ENABLE (0x1<<31)
94#define CLK_RGB24_MASK 0x0
95#define CLK_RGB16_MASK 0x070307
96#define CLK_RGB15_MASK 0x070707
97#define CLK_RGB8I_MASK 0xffffff
98
99#define RGB16_TO_COLORKEY(c) \
100 (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
101#define RGB15_TO_COLORKEY(c) \
102 (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
103
104/* overlay flip addr flag */
105#define OFC_UPDATE 0x1
106
107/* polyphase filter coefficients */
108#define N_HORIZ_Y_TAPS 5
109#define N_VERT_Y_TAPS 3
110#define N_HORIZ_UV_TAPS 3
111#define N_VERT_UV_TAPS 3
112#define N_PHASES 17
113#define MAX_TAPS 5
114
115/* memory bufferd overlay registers */
116struct overlay_registers {
0206e353
AJ
117 u32 OBUF_0Y;
118 u32 OBUF_1Y;
119 u32 OBUF_0U;
120 u32 OBUF_0V;
121 u32 OBUF_1U;
122 u32 OBUF_1V;
123 u32 OSTRIDE;
124 u32 YRGB_VPH;
125 u32 UV_VPH;
126 u32 HORZ_PH;
127 u32 INIT_PHS;
128 u32 DWINPOS;
129 u32 DWINSZ;
130 u32 SWIDTH;
131 u32 SWIDTHSW;
132 u32 SHEIGHT;
133 u32 YRGBSCALE;
134 u32 UVSCALE;
135 u32 OCLRC0;
136 u32 OCLRC1;
137 u32 DCLRKV;
138 u32 DCLRKM;
139 u32 SCLRKVH;
140 u32 SCLRKVL;
141 u32 SCLRKEN;
142 u32 OCONFIG;
143 u32 OCMD;
144 u32 RESERVED1; /* 0x6C */
145 u32 OSTART_0Y;
146 u32 OSTART_1Y;
147 u32 OSTART_0U;
148 u32 OSTART_0V;
149 u32 OSTART_1U;
150 u32 OSTART_1V;
151 u32 OTILEOFF_0Y;
152 u32 OTILEOFF_1Y;
153 u32 OTILEOFF_0U;
154 u32 OTILEOFF_0V;
155 u32 OTILEOFF_1U;
156 u32 OTILEOFF_1V;
157 u32 FASTHSCALE; /* 0xA0 */
158 u32 UVSCALEV; /* 0xA4 */
159 u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
160 u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
161 u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
162 u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
163 u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
164 u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
165 u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
166 u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
167 u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
02e792fb
DV
168};
169
23f09ce3
CW
170struct intel_overlay {
171 struct drm_device *dev;
172 struct intel_crtc *crtc;
173 struct drm_i915_gem_object *vid_bo;
174 struct drm_i915_gem_object *old_vid_bo;
175 int active;
176 int pfit_active;
177 u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
178 u32 color_key;
179 u32 brightness, contrast, saturation;
180 u32 old_xscale, old_yscale;
181 /* register access */
182 u32 flip_addr;
183 struct drm_i915_gem_object *reg_bo;
184 /* flip handling */
185 uint32_t last_flip_req;
b303cf95 186 void (*flip_tail)(struct intel_overlay *);
23f09ce3 187};
02e792fb 188
75020bc1 189static struct overlay_registers __iomem *
8d74f656 190intel_overlay_map_regs(struct intel_overlay *overlay)
02e792fb 191{
0206e353 192 drm_i915_private_t *dev_priv = overlay->dev->dev_private;
75020bc1 193 struct overlay_registers __iomem *regs;
02e792fb 194
9bb2ff73 195 if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
75020bc1 196 regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_obj->handle->vaddr;
9bb2ff73 197 else
8d74f656
CW
198 regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping,
199 overlay->reg_bo->gtt_offset);
02e792fb 200
9bb2ff73 201 return regs;
8d74f656 202}
02e792fb 203
9bb2ff73 204static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
75020bc1 205 struct overlay_registers __iomem *regs)
8d74f656
CW
206{
207 if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
9bb2ff73 208 io_mapping_unmap(regs);
02e792fb
DV
209}
210
b6c028e0 211static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
8dc5d147 212 struct drm_i915_gem_request *request,
b303cf95 213 void (*tail)(struct intel_overlay *))
02e792fb
DV
214{
215 struct drm_device *dev = overlay->dev;
852835f3 216 drm_i915_private_t *dev_priv = dev->dev_private;
6d90c952 217 struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
b6c028e0 218 int ret;
02e792fb 219
b303cf95 220 BUG_ON(overlay->last_flip_req);
6d90c952 221 ret = i915_add_request(ring, NULL, request);
3cce469c
CW
222 if (ret) {
223 kfree(request);
224 return ret;
225 }
226 overlay->last_flip_req = request->seqno;
b303cf95 227 overlay->flip_tail = tail;
199b2bc2 228 ret = i915_wait_seqno(ring, overlay->last_flip_req);
b6c028e0 229 if (ret)
03f77ea5 230 return ret;
b2da9fe5 231 i915_gem_retire_requests(dev);
02e792fb 232
03f77ea5 233 overlay->last_flip_req = 0;
02e792fb 234 return 0;
02e792fb
DV
235}
236
106dadac
CW
237/* Workaround for i830 bug where pipe a must be enable to change control regs */
238static int
239i830_activate_pipe_a(struct drm_device *dev)
02e792fb 240{
106dadac
CW
241 drm_i915_private_t *dev_priv = dev->dev_private;
242 struct intel_crtc *crtc;
243 struct drm_crtc_helper_funcs *crtc_funcs;
244 struct drm_display_mode vesa_640x480 = {
245 DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
246 752, 800, 0, 480, 489, 492, 525, 0,
247 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
248 }, *mode;
249
250 crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]);
251 if (crtc->dpms_mode == DRM_MODE_DPMS_ON)
252 return 0;
02e792fb 253
106dadac 254 /* most i8xx have pipe a forced on, so don't trust dpms mode */
9db4a9c7 255 if (I915_READ(_PIPEACONF) & PIPECONF_ENABLE)
106dadac 256 return 0;
02e792fb 257
106dadac
CW
258 crtc_funcs = crtc->base.helper_private;
259 if (crtc_funcs->dpms == NULL)
260 return 0;
261
262 DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n");
263
264 mode = drm_mode_duplicate(dev, &vesa_640x480);
f7bacf19 265
0206e353 266 if (!drm_crtc_helper_set_mode(&crtc->base, mode,
106dadac
CW
267 crtc->base.x, crtc->base.y,
268 crtc->base.fb))
269 return 0;
270
271 crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON);
272 return 1;
273}
274
275static void
276i830_deactivate_pipe_a(struct drm_device *dev)
277{
278 drm_i915_private_t *dev_priv = dev->dev_private;
279 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
280 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
281
282 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
02e792fb
DV
283}
284
285/* overlay needs to be disable in OCMD reg */
286static int intel_overlay_on(struct intel_overlay *overlay)
287{
288 struct drm_device *dev = overlay->dev;
e1f99ce6 289 struct drm_i915_private *dev_priv = dev->dev_private;
6d90c952 290 struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
8dc5d147 291 struct drm_i915_gem_request *request;
106dadac 292 int pipe_a_quirk = 0;
02e792fb 293 int ret;
02e792fb
DV
294
295 BUG_ON(overlay->active);
03f77ea5 296 overlay->active = 1;
b6c028e0 297
106dadac
CW
298 if (IS_I830(dev)) {
299 pipe_a_quirk = i830_activate_pipe_a(dev);
300 if (pipe_a_quirk < 0)
301 return pipe_a_quirk;
302 }
303
8dc5d147 304 request = kzalloc(sizeof(*request), GFP_KERNEL);
106dadac
CW
305 if (request == NULL) {
306 ret = -ENOMEM;
307 goto out;
308 }
03f77ea5 309
6d90c952 310 ret = intel_ring_begin(ring, 4);
e1f99ce6
CW
311 if (ret) {
312 kfree(request);
313 goto out;
314 }
315
6d90c952
DV
316 intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
317 intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
318 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
319 intel_ring_emit(ring, MI_NOOP);
320 intel_ring_advance(ring);
02e792fb 321
ce453d81 322 ret = intel_overlay_do_wait_request(overlay, request, NULL);
106dadac
CW
323out:
324 if (pipe_a_quirk)
325 i830_deactivate_pipe_a(dev);
02e792fb 326
106dadac 327 return ret;
02e792fb
DV
328}
329
330/* overlay needs to be enabled in OCMD reg */
8dc5d147
CW
331static int intel_overlay_continue(struct intel_overlay *overlay,
332 bool load_polyphase_filter)
02e792fb
DV
333{
334 struct drm_device *dev = overlay->dev;
0206e353 335 drm_i915_private_t *dev_priv = dev->dev_private;
6d90c952 336 struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
8dc5d147 337 struct drm_i915_gem_request *request;
02e792fb
DV
338 u32 flip_addr = overlay->flip_addr;
339 u32 tmp;
e1f99ce6 340 int ret;
02e792fb
DV
341
342 BUG_ON(!overlay->active);
343
8dc5d147
CW
344 request = kzalloc(sizeof(*request), GFP_KERNEL);
345 if (request == NULL)
346 return -ENOMEM;
347
02e792fb
DV
348 if (load_polyphase_filter)
349 flip_addr |= OFC_UPDATE;
350
351 /* check for underruns */
352 tmp = I915_READ(DOVSTA);
353 if (tmp & (1 << 17))
354 DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
355
6d90c952 356 ret = intel_ring_begin(ring, 2);
e1f99ce6
CW
357 if (ret) {
358 kfree(request);
359 return ret;
360 }
6d90c952
DV
361 intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
362 intel_ring_emit(ring, flip_addr);
363 intel_ring_advance(ring);
5a5a0c64 364
6d90c952 365 ret = i915_add_request(ring, NULL, request);
3cce469c
CW
366 if (ret) {
367 kfree(request);
368 return ret;
369 }
370
371 overlay->last_flip_req = request->seqno;
8dc5d147 372 return 0;
5a5a0c64
DV
373}
374
b303cf95 375static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
5a5a0c64 376{
05394f39 377 struct drm_i915_gem_object *obj = overlay->old_vid_bo;
5a5a0c64 378
b303cf95 379 i915_gem_object_unpin(obj);
05394f39 380 drm_gem_object_unreference(&obj->base);
5a5a0c64 381
b303cf95
CW
382 overlay->old_vid_bo = NULL;
383}
03f77ea5 384
b303cf95
CW
385static void intel_overlay_off_tail(struct intel_overlay *overlay)
386{
05394f39 387 struct drm_i915_gem_object *obj = overlay->vid_bo;
02e792fb 388
b303cf95
CW
389 /* never have the overlay hw on without showing a frame */
390 BUG_ON(!overlay->vid_bo);
02e792fb 391
b303cf95 392 i915_gem_object_unpin(obj);
05394f39 393 drm_gem_object_unreference(&obj->base);
b303cf95 394 overlay->vid_bo = NULL;
03f77ea5 395
b303cf95
CW
396 overlay->crtc->overlay = NULL;
397 overlay->crtc = NULL;
398 overlay->active = 0;
02e792fb
DV
399}
400
401/* overlay needs to be disabled in OCMD reg */
ce453d81 402static int intel_overlay_off(struct intel_overlay *overlay)
02e792fb 403{
02e792fb 404 struct drm_device *dev = overlay->dev;
e1f99ce6 405 struct drm_i915_private *dev_priv = dev->dev_private;
6d90c952 406 struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
8dc5d147
CW
407 u32 flip_addr = overlay->flip_addr;
408 struct drm_i915_gem_request *request;
e1f99ce6 409 int ret;
02e792fb
DV
410
411 BUG_ON(!overlay->active);
412
8dc5d147
CW
413 request = kzalloc(sizeof(*request), GFP_KERNEL);
414 if (request == NULL)
415 return -ENOMEM;
416
02e792fb
DV
417 /* According to intel docs the overlay hw may hang (when switching
418 * off) without loading the filter coeffs. It is however unclear whether
419 * this applies to the disabling of the overlay or to the switching off
420 * of the hw. Do it in both cases */
421 flip_addr |= OFC_UPDATE;
422
6d90c952 423 ret = intel_ring_begin(ring, 6);
e1f99ce6
CW
424 if (ret) {
425 kfree(request);
426 return ret;
427 }
02e792fb 428 /* wait for overlay to go idle */
6d90c952
DV
429 intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
430 intel_ring_emit(ring, flip_addr);
431 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
02e792fb 432 /* turn overlay off */
6d90c952
DV
433 intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
434 intel_ring_emit(ring, flip_addr);
435 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
436 intel_ring_advance(ring);
02e792fb 437
ce453d81 438 return intel_overlay_do_wait_request(overlay, request,
b303cf95 439 intel_overlay_off_tail);
12ca45fe
DV
440}
441
03f77ea5
DV
442/* recover from an interruption due to a signal
443 * We have to be careful not to repeat work forever an make forward progess. */
ce453d81 444static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
03f77ea5
DV
445{
446 struct drm_device *dev = overlay->dev;
852835f3 447 drm_i915_private_t *dev_priv = dev->dev_private;
6d90c952 448 struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
03f77ea5 449 int ret;
03f77ea5 450
b303cf95
CW
451 if (overlay->last_flip_req == 0)
452 return 0;
03f77ea5 453
199b2bc2 454 ret = i915_wait_seqno(ring, overlay->last_flip_req);
b6c028e0 455 if (ret)
03f77ea5 456 return ret;
b2da9fe5 457 i915_gem_retire_requests(dev);
03f77ea5 458
b303cf95
CW
459 if (overlay->flip_tail)
460 overlay->flip_tail(overlay);
03f77ea5 461
03f77ea5
DV
462 overlay->last_flip_req = 0;
463 return 0;
464}
465
5a5a0c64
DV
466/* Wait for pending overlay flip and release old frame.
467 * Needs to be called before the overlay register are changed
8d74f656
CW
468 * via intel_overlay_(un)map_regs
469 */
02e792fb
DV
470static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
471{
5cd68c98
CW
472 struct drm_device *dev = overlay->dev;
473 drm_i915_private_t *dev_priv = dev->dev_private;
6d90c952 474 struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
02e792fb 475 int ret;
02e792fb 476
5cd68c98
CW
477 /* Only wait if there is actually an old frame to release to
478 * guarantee forward progress.
479 */
03f77ea5
DV
480 if (!overlay->old_vid_bo)
481 return 0;
482
5cd68c98 483 if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
8dc5d147 484 struct drm_i915_gem_request *request;
02e792fb 485
5cd68c98 486 /* synchronous slowpath */
8dc5d147
CW
487 request = kzalloc(sizeof(*request), GFP_KERNEL);
488 if (request == NULL)
489 return -ENOMEM;
02e792fb 490
6d90c952 491 ret = intel_ring_begin(ring, 2);
e1f99ce6
CW
492 if (ret) {
493 kfree(request);
494 return ret;
495 }
496
6d90c952
DV
497 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
498 intel_ring_emit(ring, MI_NOOP);
499 intel_ring_advance(ring);
5cd68c98 500
ce453d81 501 ret = intel_overlay_do_wait_request(overlay, request,
b303cf95 502 intel_overlay_release_old_vid_tail);
5cd68c98
CW
503 if (ret)
504 return ret;
505 }
02e792fb 506
5cd68c98 507 intel_overlay_release_old_vid_tail(overlay);
02e792fb
DV
508 return 0;
509}
510
511struct put_image_params {
512 int format;
513 short dst_x;
514 short dst_y;
515 short dst_w;
516 short dst_h;
517 short src_w;
518 short src_scan_h;
519 short src_scan_w;
520 short src_h;
521 short stride_Y;
522 short stride_UV;
523 int offset_Y;
524 int offset_U;
525 int offset_V;
526};
527
528static int packed_depth_bytes(u32 format)
529{
530 switch (format & I915_OVERLAY_DEPTH_MASK) {
722506f0
CW
531 case I915_OVERLAY_YUV422:
532 return 4;
533 case I915_OVERLAY_YUV411:
534 /* return 6; not implemented */
535 default:
536 return -EINVAL;
02e792fb
DV
537 }
538}
539
540static int packed_width_bytes(u32 format, short width)
541{
542 switch (format & I915_OVERLAY_DEPTH_MASK) {
722506f0
CW
543 case I915_OVERLAY_YUV422:
544 return width << 1;
545 default:
546 return -EINVAL;
02e792fb
DV
547 }
548}
549
550static int uv_hsubsampling(u32 format)
551{
552 switch (format & I915_OVERLAY_DEPTH_MASK) {
722506f0
CW
553 case I915_OVERLAY_YUV422:
554 case I915_OVERLAY_YUV420:
555 return 2;
556 case I915_OVERLAY_YUV411:
557 case I915_OVERLAY_YUV410:
558 return 4;
559 default:
560 return -EINVAL;
02e792fb
DV
561 }
562}
563
564static int uv_vsubsampling(u32 format)
565{
566 switch (format & I915_OVERLAY_DEPTH_MASK) {
722506f0
CW
567 case I915_OVERLAY_YUV420:
568 case I915_OVERLAY_YUV410:
569 return 2;
570 case I915_OVERLAY_YUV422:
571 case I915_OVERLAY_YUV411:
572 return 1;
573 default:
574 return -EINVAL;
02e792fb
DV
575 }
576}
577
578static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
579{
580 u32 mask, shift, ret;
a6c45cf0 581 if (IS_GEN2(dev)) {
02e792fb
DV
582 mask = 0x1f;
583 shift = 5;
a6c45cf0
CW
584 } else {
585 mask = 0x3f;
586 shift = 6;
02e792fb
DV
587 }
588 ret = ((offset + width + mask) >> shift) - (offset >> shift);
a6c45cf0 589 if (!IS_GEN2(dev))
02e792fb 590 ret <<= 1;
0206e353 591 ret -= 1;
02e792fb
DV
592 return ret << 2;
593}
594
595static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
596 0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
597 0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
598 0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
599 0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
600 0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
601 0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
602 0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
603 0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
604 0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
605 0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
606 0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
607 0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
608 0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
609 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
610 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
611 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
722506f0
CW
612 0xb000, 0x3000, 0x0800, 0x3000, 0xb000
613};
614
02e792fb
DV
615static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
616 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
617 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
618 0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
619 0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
620 0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
621 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
622 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
623 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
722506f0
CW
624 0x3000, 0x0800, 0x3000
625};
02e792fb 626
75020bc1 627static void update_polyphase_filter(struct overlay_registers __iomem *regs)
02e792fb 628{
75020bc1
BW
629 memcpy_toio(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
630 memcpy_toio(regs->UV_HCOEFS, uv_static_hcoeffs,
631 sizeof(uv_static_hcoeffs));
02e792fb
DV
632}
633
634static bool update_scaling_factors(struct intel_overlay *overlay,
75020bc1 635 struct overlay_registers __iomem *regs,
02e792fb
DV
636 struct put_image_params *params)
637{
638 /* fixed point with a 12 bit shift */
639 u32 xscale, yscale, xscale_UV, yscale_UV;
640#define FP_SHIFT 12
641#define FRACT_MASK 0xfff
642 bool scale_changed = false;
643 int uv_hscale = uv_hsubsampling(params->format);
644 int uv_vscale = uv_vsubsampling(params->format);
645
646 if (params->dst_w > 1)
647 xscale = ((params->src_scan_w - 1) << FP_SHIFT)
648 /(params->dst_w);
649 else
650 xscale = 1 << FP_SHIFT;
651
652 if (params->dst_h > 1)
653 yscale = ((params->src_scan_h - 1) << FP_SHIFT)
654 /(params->dst_h);
655 else
656 yscale = 1 << FP_SHIFT;
657
658 /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
722506f0
CW
659 xscale_UV = xscale/uv_hscale;
660 yscale_UV = yscale/uv_vscale;
661 /* make the Y scale to UV scale ratio an exact multiply */
662 xscale = xscale_UV * uv_hscale;
663 yscale = yscale_UV * uv_vscale;
02e792fb 664 /*} else {
722506f0
CW
665 xscale_UV = 0;
666 yscale_UV = 0;
667 }*/
02e792fb
DV
668
669 if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
670 scale_changed = true;
671 overlay->old_xscale = xscale;
672 overlay->old_yscale = yscale;
673
75020bc1
BW
674 iowrite32(((yscale & FRACT_MASK) << 20) |
675 ((xscale >> FP_SHIFT) << 16) |
676 ((xscale & FRACT_MASK) << 3),
677 &regs->YRGBSCALE);
722506f0 678
75020bc1
BW
679 iowrite32(((yscale_UV & FRACT_MASK) << 20) |
680 ((xscale_UV >> FP_SHIFT) << 16) |
681 ((xscale_UV & FRACT_MASK) << 3),
682 &regs->UVSCALE);
722506f0 683
75020bc1
BW
684 iowrite32((((yscale >> FP_SHIFT) << 16) |
685 ((yscale_UV >> FP_SHIFT) << 0)),
686 &regs->UVSCALEV);
02e792fb
DV
687
688 if (scale_changed)
689 update_polyphase_filter(regs);
690
691 return scale_changed;
692}
693
694static void update_colorkey(struct intel_overlay *overlay,
75020bc1 695 struct overlay_registers __iomem *regs)
02e792fb
DV
696{
697 u32 key = overlay->color_key;
6ba3ddd9 698
02e792fb 699 switch (overlay->crtc->base.fb->bits_per_pixel) {
722506f0 700 case 8:
75020bc1
BW
701 iowrite32(0, &regs->DCLRKV);
702 iowrite32(CLK_RGB8I_MASK | DST_KEY_ENABLE, &regs->DCLRKM);
6ba3ddd9
CW
703 break;
704
722506f0
CW
705 case 16:
706 if (overlay->crtc->base.fb->depth == 15) {
75020bc1
BW
707 iowrite32(RGB15_TO_COLORKEY(key), &regs->DCLRKV);
708 iowrite32(CLK_RGB15_MASK | DST_KEY_ENABLE,
709 &regs->DCLRKM);
722506f0 710 } else {
75020bc1
BW
711 iowrite32(RGB16_TO_COLORKEY(key), &regs->DCLRKV);
712 iowrite32(CLK_RGB16_MASK | DST_KEY_ENABLE,
713 &regs->DCLRKM);
722506f0 714 }
6ba3ddd9
CW
715 break;
716
722506f0
CW
717 case 24:
718 case 32:
75020bc1
BW
719 iowrite32(key, &regs->DCLRKV);
720 iowrite32(CLK_RGB24_MASK | DST_KEY_ENABLE, &regs->DCLRKM);
6ba3ddd9 721 break;
02e792fb
DV
722 }
723}
724
725static u32 overlay_cmd_reg(struct put_image_params *params)
726{
727 u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
728
729 if (params->format & I915_OVERLAY_YUV_PLANAR) {
730 switch (params->format & I915_OVERLAY_DEPTH_MASK) {
722506f0
CW
731 case I915_OVERLAY_YUV422:
732 cmd |= OCMD_YUV_422_PLANAR;
733 break;
734 case I915_OVERLAY_YUV420:
735 cmd |= OCMD_YUV_420_PLANAR;
736 break;
737 case I915_OVERLAY_YUV411:
738 case I915_OVERLAY_YUV410:
739 cmd |= OCMD_YUV_410_PLANAR;
740 break;
02e792fb
DV
741 }
742 } else { /* YUV packed */
743 switch (params->format & I915_OVERLAY_DEPTH_MASK) {
722506f0
CW
744 case I915_OVERLAY_YUV422:
745 cmd |= OCMD_YUV_422_PACKED;
746 break;
747 case I915_OVERLAY_YUV411:
748 cmd |= OCMD_YUV_411_PACKED;
749 break;
02e792fb
DV
750 }
751
752 switch (params->format & I915_OVERLAY_SWAP_MASK) {
722506f0
CW
753 case I915_OVERLAY_NO_SWAP:
754 break;
755 case I915_OVERLAY_UV_SWAP:
756 cmd |= OCMD_UV_SWAP;
757 break;
758 case I915_OVERLAY_Y_SWAP:
759 cmd |= OCMD_Y_SWAP;
760 break;
761 case I915_OVERLAY_Y_AND_UV_SWAP:
762 cmd |= OCMD_Y_AND_UV_SWAP;
763 break;
02e792fb
DV
764 }
765 }
766
767 return cmd;
768}
769
5fe82c5e 770static int intel_overlay_do_put_image(struct intel_overlay *overlay,
05394f39 771 struct drm_i915_gem_object *new_bo,
5fe82c5e 772 struct put_image_params *params)
02e792fb
DV
773{
774 int ret, tmp_width;
75020bc1 775 struct overlay_registers __iomem *regs;
02e792fb 776 bool scale_changed = false;
02e792fb 777 struct drm_device *dev = overlay->dev;
75020bc1 778 u32 swidth, swidthsw, sheight, ostride;
02e792fb
DV
779
780 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
781 BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
782 BUG_ON(!overlay);
783
02e792fb
DV
784 ret = intel_overlay_release_old_vid(overlay);
785 if (ret != 0)
786 return ret;
787
2da3b9b9 788 ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL);
02e792fb
DV
789 if (ret != 0)
790 return ret;
791
d9e86c0e
CW
792 ret = i915_gem_object_put_fence(new_bo);
793 if (ret)
794 goto out_unpin;
795
02e792fb 796 if (!overlay->active) {
75020bc1 797 u32 oconfig;
8d74f656 798 regs = intel_overlay_map_regs(overlay);
02e792fb
DV
799 if (!regs) {
800 ret = -ENOMEM;
801 goto out_unpin;
802 }
75020bc1 803 oconfig = OCONF_CC_OUT_8BIT;
a6c45cf0 804 if (IS_GEN4(overlay->dev))
75020bc1
BW
805 oconfig |= OCONF_CSC_MODE_BT709;
806 oconfig |= overlay->crtc->pipe == 0 ?
02e792fb 807 OCONF_PIPE_A : OCONF_PIPE_B;
75020bc1 808 iowrite32(oconfig, &regs->OCONFIG);
9bb2ff73 809 intel_overlay_unmap_regs(overlay, regs);
02e792fb
DV
810
811 ret = intel_overlay_on(overlay);
812 if (ret != 0)
813 goto out_unpin;
814 }
815
8d74f656 816 regs = intel_overlay_map_regs(overlay);
02e792fb
DV
817 if (!regs) {
818 ret = -ENOMEM;
819 goto out_unpin;
820 }
821
75020bc1
BW
822 iowrite32((params->dst_y << 16) | params->dst_x, &regs->DWINPOS);
823 iowrite32((params->dst_h << 16) | params->dst_w, &regs->DWINSZ);
02e792fb
DV
824
825 if (params->format & I915_OVERLAY_YUV_PACKED)
826 tmp_width = packed_width_bytes(params->format, params->src_w);
827 else
828 tmp_width = params->src_w;
829
75020bc1
BW
830 swidth = params->src_w;
831 swidthsw = calc_swidthsw(overlay->dev, params->offset_Y, tmp_width);
832 sheight = params->src_h;
833 iowrite32(new_bo->gtt_offset + params->offset_Y, &regs->OBUF_0Y);
834 ostride = params->stride_Y;
02e792fb
DV
835
836 if (params->format & I915_OVERLAY_YUV_PLANAR) {
837 int uv_hscale = uv_hsubsampling(params->format);
838 int uv_vscale = uv_vsubsampling(params->format);
839 u32 tmp_U, tmp_V;
75020bc1 840 swidth |= (params->src_w/uv_hscale) << 16;
02e792fb 841 tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
722506f0 842 params->src_w/uv_hscale);
02e792fb 843 tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
722506f0 844 params->src_w/uv_hscale);
75020bc1
BW
845 swidthsw |= max_t(u32, tmp_U, tmp_V) << 16;
846 sheight |= (params->src_h/uv_vscale) << 16;
847 iowrite32(new_bo->gtt_offset + params->offset_U, &regs->OBUF_0U);
848 iowrite32(new_bo->gtt_offset + params->offset_V, &regs->OBUF_0V);
849 ostride |= params->stride_UV << 16;
02e792fb
DV
850 }
851
75020bc1
BW
852 iowrite32(swidth, &regs->SWIDTH);
853 iowrite32(swidthsw, &regs->SWIDTHSW);
854 iowrite32(sheight, &regs->SHEIGHT);
855 iowrite32(ostride, &regs->OSTRIDE);
856
02e792fb
DV
857 scale_changed = update_scaling_factors(overlay, regs, params);
858
859 update_colorkey(overlay, regs);
860
75020bc1 861 iowrite32(overlay_cmd_reg(params), &regs->OCMD);
02e792fb 862
9bb2ff73 863 intel_overlay_unmap_regs(overlay, regs);
02e792fb 864
8dc5d147
CW
865 ret = intel_overlay_continue(overlay, scale_changed);
866 if (ret)
867 goto out_unpin;
02e792fb
DV
868
869 overlay->old_vid_bo = overlay->vid_bo;
05394f39 870 overlay->vid_bo = new_bo;
02e792fb
DV
871
872 return 0;
873
874out_unpin:
875 i915_gem_object_unpin(new_bo);
876 return ret;
877}
878
ce453d81 879int intel_overlay_switch_off(struct intel_overlay *overlay)
02e792fb 880{
75020bc1 881 struct overlay_registers __iomem *regs;
02e792fb 882 struct drm_device *dev = overlay->dev;
5dcdbcb0 883 int ret;
02e792fb
DV
884
885 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
886 BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
887
ce453d81 888 ret = intel_overlay_recover_from_interrupt(overlay);
b303cf95
CW
889 if (ret != 0)
890 return ret;
9bedb974 891
02e792fb
DV
892 if (!overlay->active)
893 return 0;
894
02e792fb
DV
895 ret = intel_overlay_release_old_vid(overlay);
896 if (ret != 0)
897 return ret;
898
8d74f656 899 regs = intel_overlay_map_regs(overlay);
75020bc1 900 iowrite32(0, &regs->OCMD);
9bb2ff73 901 intel_overlay_unmap_regs(overlay, regs);
02e792fb 902
ce453d81 903 ret = intel_overlay_off(overlay);
03f77ea5
DV
904 if (ret != 0)
905 return ret;
906
12ca45fe 907 intel_overlay_off_tail(overlay);
02e792fb
DV
908 return 0;
909}
910
911static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
912 struct intel_crtc *crtc)
913{
722506f0 914 drm_i915_private_t *dev_priv = overlay->dev->dev_private;
02e792fb 915
f7abfe8b 916 if (!crtc->active)
02e792fb
DV
917 return -EINVAL;
918
02e792fb 919 /* can't use the overlay with double wide pipe */
a6c45cf0 920 if (INTEL_INFO(overlay->dev)->gen < 4 &&
f7abfe8b 921 (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE)
02e792fb
DV
922 return -EINVAL;
923
924 return 0;
925}
926
927static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
928{
929 struct drm_device *dev = overlay->dev;
722506f0 930 drm_i915_private_t *dev_priv = dev->dev_private;
02e792fb 931 u32 pfit_control = I915_READ(PFIT_CONTROL);
446d2183 932 u32 ratio;
02e792fb
DV
933
934 /* XXX: This is not the same logic as in the xorg driver, but more in
446d2183
CW
935 * line with the intel documentation for the i965
936 */
a6c45cf0 937 if (INTEL_INFO(dev)->gen >= 4) {
0206e353 938 /* on i965 use the PGM reg to read out the autoscaler values */
a6c45cf0
CW
939 ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
940 } else {
446d2183
CW
941 if (pfit_control & VERT_AUTO_SCALE)
942 ratio = I915_READ(PFIT_AUTO_RATIOS);
02e792fb 943 else
446d2183
CW
944 ratio = I915_READ(PFIT_PGM_RATIOS);
945 ratio >>= PFIT_VERT_SCALE_SHIFT;
02e792fb
DV
946 }
947
948 overlay->pfit_vscale_ratio = ratio;
949}
950
951static int check_overlay_dst(struct intel_overlay *overlay,
952 struct drm_intel_overlay_put_image *rec)
953{
954 struct drm_display_mode *mode = &overlay->crtc->base.mode;
955
75c13993
DV
956 if (rec->dst_x < mode->hdisplay &&
957 rec->dst_x + rec->dst_width <= mode->hdisplay &&
958 rec->dst_y < mode->vdisplay &&
959 rec->dst_y + rec->dst_height <= mode->vdisplay)
02e792fb
DV
960 return 0;
961 else
962 return -EINVAL;
963}
964
965static int check_overlay_scaling(struct put_image_params *rec)
966{
967 u32 tmp;
968
969 /* downscaling limit is 8.0 */
970 tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
971 if (tmp > 7)
972 return -EINVAL;
973 tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
974 if (tmp > 7)
975 return -EINVAL;
976
977 return 0;
978}
979
980static int check_overlay_src(struct drm_device *dev,
981 struct drm_intel_overlay_put_image *rec,
05394f39 982 struct drm_i915_gem_object *new_bo)
02e792fb 983{
02e792fb
DV
984 int uv_hscale = uv_hsubsampling(rec->flags);
985 int uv_vscale = uv_vsubsampling(rec->flags);
8f28f54a
DC
986 u32 stride_mask;
987 int depth;
988 u32 tmp;
02e792fb
DV
989
990 /* check src dimensions */
991 if (IS_845G(dev) || IS_I830(dev)) {
722506f0 992 if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
9f7c3f44 993 rec->src_width > IMAGE_MAX_WIDTH_LEGACY)
02e792fb
DV
994 return -EINVAL;
995 } else {
722506f0 996 if (rec->src_height > IMAGE_MAX_HEIGHT ||
9f7c3f44 997 rec->src_width > IMAGE_MAX_WIDTH)
02e792fb
DV
998 return -EINVAL;
999 }
9f7c3f44 1000
02e792fb 1001 /* better safe than sorry, use 4 as the maximal subsampling ratio */
722506f0 1002 if (rec->src_height < N_VERT_Y_TAPS*4 ||
9f7c3f44 1003 rec->src_width < N_HORIZ_Y_TAPS*4)
02e792fb
DV
1004 return -EINVAL;
1005
a1efd14a 1006 /* check alignment constraints */
02e792fb 1007 switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
722506f0
CW
1008 case I915_OVERLAY_RGB:
1009 /* not implemented */
1010 return -EINVAL;
9f7c3f44 1011
722506f0 1012 case I915_OVERLAY_YUV_PACKED:
722506f0 1013 if (uv_vscale != 1)
02e792fb 1014 return -EINVAL;
9f7c3f44
CW
1015
1016 depth = packed_depth_bytes(rec->flags);
722506f0
CW
1017 if (depth < 0)
1018 return depth;
9f7c3f44 1019
722506f0
CW
1020 /* ignore UV planes */
1021 rec->stride_UV = 0;
1022 rec->offset_U = 0;
1023 rec->offset_V = 0;
1024 /* check pixel alignment */
1025 if (rec->offset_Y % depth)
1026 return -EINVAL;
1027 break;
9f7c3f44 1028
722506f0
CW
1029 case I915_OVERLAY_YUV_PLANAR:
1030 if (uv_vscale < 0 || uv_hscale < 0)
02e792fb 1031 return -EINVAL;
722506f0
CW
1032 /* no offset restrictions for planar formats */
1033 break;
9f7c3f44 1034
722506f0
CW
1035 default:
1036 return -EINVAL;
02e792fb
DV
1037 }
1038
1039 if (rec->src_width % uv_hscale)
1040 return -EINVAL;
1041
1042 /* stride checking */
a1efd14a
CW
1043 if (IS_I830(dev) || IS_845G(dev))
1044 stride_mask = 255;
1045 else
1046 stride_mask = 63;
02e792fb
DV
1047
1048 if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
1049 return -EINVAL;
a6c45cf0 1050 if (IS_GEN4(dev) && rec->stride_Y < 512)
02e792fb
DV
1051 return -EINVAL;
1052
1053 tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
9f7c3f44
CW
1054 4096 : 8192;
1055 if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
02e792fb
DV
1056 return -EINVAL;
1057
1058 /* check buffer dimensions */
1059 switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
722506f0
CW
1060 case I915_OVERLAY_RGB:
1061 case I915_OVERLAY_YUV_PACKED:
1062 /* always 4 Y values per depth pixels */
1063 if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1064 return -EINVAL;
1065
1066 tmp = rec->stride_Y*rec->src_height;
05394f39 1067 if (rec->offset_Y + tmp > new_bo->base.size)
722506f0
CW
1068 return -EINVAL;
1069 break;
1070
1071 case I915_OVERLAY_YUV_PLANAR:
1072 if (rec->src_width > rec->stride_Y)
1073 return -EINVAL;
1074 if (rec->src_width/uv_hscale > rec->stride_UV)
1075 return -EINVAL;
1076
9f7c3f44 1077 tmp = rec->stride_Y * rec->src_height;
05394f39 1078 if (rec->offset_Y + tmp > new_bo->base.size)
722506f0 1079 return -EINVAL;
9f7c3f44
CW
1080
1081 tmp = rec->stride_UV * (rec->src_height / uv_vscale);
05394f39
CW
1082 if (rec->offset_U + tmp > new_bo->base.size ||
1083 rec->offset_V + tmp > new_bo->base.size)
722506f0
CW
1084 return -EINVAL;
1085 break;
02e792fb
DV
1086 }
1087
1088 return 0;
1089}
1090
e9e331a8
CW
1091/**
1092 * Return the pipe currently connected to the panel fitter,
1093 * or -1 if the panel fitter is not present or not in use
1094 */
1095static int intel_panel_fitter_pipe(struct drm_device *dev)
1096{
1097 struct drm_i915_private *dev_priv = dev->dev_private;
1098 u32 pfit_control;
1099
1100 /* i830 doesn't have a panel fitter */
1101 if (IS_I830(dev))
1102 return -1;
1103
1104 pfit_control = I915_READ(PFIT_CONTROL);
1105
1106 /* See if the panel fitter is in use */
1107 if ((pfit_control & PFIT_ENABLE) == 0)
1108 return -1;
1109
1110 /* 965 can place panel fitter on either pipe */
a6c45cf0 1111 if (IS_GEN4(dev))
e9e331a8
CW
1112 return (pfit_control >> 29) & 0x3;
1113
1114 /* older chips can only use pipe 1 */
1115 return 1;
1116}
1117
02e792fb 1118int intel_overlay_put_image(struct drm_device *dev, void *data,
0206e353 1119 struct drm_file *file_priv)
02e792fb
DV
1120{
1121 struct drm_intel_overlay_put_image *put_image_rec = data;
1122 drm_i915_private_t *dev_priv = dev->dev_private;
1123 struct intel_overlay *overlay;
1124 struct drm_mode_object *drmmode_obj;
1125 struct intel_crtc *crtc;
05394f39 1126 struct drm_i915_gem_object *new_bo;
02e792fb
DV
1127 struct put_image_params *params;
1128 int ret;
1129
1cff8f6b 1130 /* No need to check for DRIVER_MODESET - we don't set it up then. */
02e792fb
DV
1131 overlay = dev_priv->overlay;
1132 if (!overlay) {
1133 DRM_DEBUG("userspace bug: no overlay\n");
1134 return -ENODEV;
1135 }
1136
1137 if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
1138 mutex_lock(&dev->mode_config.mutex);
1139 mutex_lock(&dev->struct_mutex);
1140
ce453d81 1141 ret = intel_overlay_switch_off(overlay);
02e792fb
DV
1142
1143 mutex_unlock(&dev->struct_mutex);
1144 mutex_unlock(&dev->mode_config.mutex);
1145
1146 return ret;
1147 }
1148
1149 params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
1150 if (!params)
1151 return -ENOMEM;
1152
1153 drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
722506f0 1154 DRM_MODE_OBJECT_CRTC);
915a428e
DC
1155 if (!drmmode_obj) {
1156 ret = -ENOENT;
1157 goto out_free;
1158 }
02e792fb
DV
1159 crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
1160
05394f39
CW
1161 new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
1162 put_image_rec->bo_handle));
c8725226 1163 if (&new_bo->base == NULL) {
915a428e
DC
1164 ret = -ENOENT;
1165 goto out_free;
1166 }
02e792fb
DV
1167
1168 mutex_lock(&dev->mode_config.mutex);
1169 mutex_lock(&dev->struct_mutex);
1170
d9e86c0e
CW
1171 if (new_bo->tiling_mode) {
1172 DRM_ERROR("buffer used for overlay image can not be tiled\n");
1173 ret = -EINVAL;
1174 goto out_unlock;
1175 }
1176
ce453d81 1177 ret = intel_overlay_recover_from_interrupt(overlay);
b303cf95
CW
1178 if (ret != 0)
1179 goto out_unlock;
03f77ea5 1180
02e792fb
DV
1181 if (overlay->crtc != crtc) {
1182 struct drm_display_mode *mode = &crtc->base.mode;
ce453d81 1183 ret = intel_overlay_switch_off(overlay);
02e792fb
DV
1184 if (ret != 0)
1185 goto out_unlock;
1186
1187 ret = check_overlay_possible_on_crtc(overlay, crtc);
1188 if (ret != 0)
1189 goto out_unlock;
1190
1191 overlay->crtc = crtc;
1192 crtc->overlay = overlay;
1193
e9e331a8
CW
1194 /* line too wide, i.e. one-line-mode */
1195 if (mode->hdisplay > 1024 &&
1196 intel_panel_fitter_pipe(dev) == crtc->pipe) {
02e792fb
DV
1197 overlay->pfit_active = 1;
1198 update_pfit_vscale_ratio(overlay);
1199 } else
1200 overlay->pfit_active = 0;
1201 }
1202
1203 ret = check_overlay_dst(overlay, put_image_rec);
1204 if (ret != 0)
1205 goto out_unlock;
1206
1207 if (overlay->pfit_active) {
1208 params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
722506f0 1209 overlay->pfit_vscale_ratio);
02e792fb
DV
1210 /* shifting right rounds downwards, so add 1 */
1211 params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
722506f0 1212 overlay->pfit_vscale_ratio) + 1;
02e792fb
DV
1213 } else {
1214 params->dst_y = put_image_rec->dst_y;
1215 params->dst_h = put_image_rec->dst_height;
1216 }
1217 params->dst_x = put_image_rec->dst_x;
1218 params->dst_w = put_image_rec->dst_width;
1219
1220 params->src_w = put_image_rec->src_width;
1221 params->src_h = put_image_rec->src_height;
1222 params->src_scan_w = put_image_rec->src_scan_width;
1223 params->src_scan_h = put_image_rec->src_scan_height;
722506f0
CW
1224 if (params->src_scan_h > params->src_h ||
1225 params->src_scan_w > params->src_w) {
02e792fb
DV
1226 ret = -EINVAL;
1227 goto out_unlock;
1228 }
1229
1230 ret = check_overlay_src(dev, put_image_rec, new_bo);
1231 if (ret != 0)
1232 goto out_unlock;
1233 params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
1234 params->stride_Y = put_image_rec->stride_Y;
1235 params->stride_UV = put_image_rec->stride_UV;
1236 params->offset_Y = put_image_rec->offset_Y;
1237 params->offset_U = put_image_rec->offset_U;
1238 params->offset_V = put_image_rec->offset_V;
1239
1240 /* Check scaling after src size to prevent a divide-by-zero. */
1241 ret = check_overlay_scaling(params);
1242 if (ret != 0)
1243 goto out_unlock;
1244
1245 ret = intel_overlay_do_put_image(overlay, new_bo, params);
1246 if (ret != 0)
1247 goto out_unlock;
1248
1249 mutex_unlock(&dev->struct_mutex);
1250 mutex_unlock(&dev->mode_config.mutex);
1251
1252 kfree(params);
1253
1254 return 0;
1255
1256out_unlock:
1257 mutex_unlock(&dev->struct_mutex);
1258 mutex_unlock(&dev->mode_config.mutex);
05394f39 1259 drm_gem_object_unreference_unlocked(&new_bo->base);
915a428e 1260out_free:
02e792fb
DV
1261 kfree(params);
1262
1263 return ret;
1264}
1265
1266static void update_reg_attrs(struct intel_overlay *overlay,
75020bc1 1267 struct overlay_registers __iomem *regs)
02e792fb 1268{
75020bc1
BW
1269 iowrite32((overlay->contrast << 18) | (overlay->brightness & 0xff),
1270 &regs->OCLRC0);
1271 iowrite32(overlay->saturation, &regs->OCLRC1);
02e792fb
DV
1272}
1273
1274static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1275{
1276 int i;
1277
1278 if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1279 return false;
1280
1281 for (i = 0; i < 3; i++) {
722506f0 1282 if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
02e792fb
DV
1283 return false;
1284 }
1285
1286 return true;
1287}
1288
1289static bool check_gamma5_errata(u32 gamma5)
1290{
1291 int i;
1292
1293 for (i = 0; i < 3; i++) {
1294 if (((gamma5 >> i*8) & 0xff) == 0x80)
1295 return false;
1296 }
1297
1298 return true;
1299}
1300
1301static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1302{
722506f0
CW
1303 if (!check_gamma_bounds(0, attrs->gamma0) ||
1304 !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1305 !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1306 !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1307 !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1308 !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1309 !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
02e792fb 1310 return -EINVAL;
722506f0 1311
02e792fb
DV
1312 if (!check_gamma5_errata(attrs->gamma5))
1313 return -EINVAL;
722506f0 1314
02e792fb
DV
1315 return 0;
1316}
1317
1318int intel_overlay_attrs(struct drm_device *dev, void *data,
0206e353 1319 struct drm_file *file_priv)
02e792fb
DV
1320{
1321 struct drm_intel_overlay_attrs *attrs = data;
0206e353 1322 drm_i915_private_t *dev_priv = dev->dev_private;
02e792fb 1323 struct intel_overlay *overlay;
75020bc1 1324 struct overlay_registers __iomem *regs;
02e792fb
DV
1325 int ret;
1326
1cff8f6b 1327 /* No need to check for DRIVER_MODESET - we don't set it up then. */
02e792fb
DV
1328 overlay = dev_priv->overlay;
1329 if (!overlay) {
1330 DRM_DEBUG("userspace bug: no overlay\n");
1331 return -ENODEV;
1332 }
1333
1334 mutex_lock(&dev->mode_config.mutex);
1335 mutex_lock(&dev->struct_mutex);
1336
60fc332c 1337 ret = -EINVAL;
02e792fb 1338 if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
60fc332c 1339 attrs->color_key = overlay->color_key;
02e792fb 1340 attrs->brightness = overlay->brightness;
60fc332c 1341 attrs->contrast = overlay->contrast;
02e792fb
DV
1342 attrs->saturation = overlay->saturation;
1343
a6c45cf0 1344 if (!IS_GEN2(dev)) {
02e792fb
DV
1345 attrs->gamma0 = I915_READ(OGAMC0);
1346 attrs->gamma1 = I915_READ(OGAMC1);
1347 attrs->gamma2 = I915_READ(OGAMC2);
1348 attrs->gamma3 = I915_READ(OGAMC3);
1349 attrs->gamma4 = I915_READ(OGAMC4);
1350 attrs->gamma5 = I915_READ(OGAMC5);
1351 }
02e792fb 1352 } else {
60fc332c 1353 if (attrs->brightness < -128 || attrs->brightness > 127)
02e792fb 1354 goto out_unlock;
60fc332c 1355 if (attrs->contrast > 255)
02e792fb 1356 goto out_unlock;
60fc332c 1357 if (attrs->saturation > 1023)
02e792fb 1358 goto out_unlock;
02e792fb 1359
60fc332c
CW
1360 overlay->color_key = attrs->color_key;
1361 overlay->brightness = attrs->brightness;
1362 overlay->contrast = attrs->contrast;
1363 overlay->saturation = attrs->saturation;
02e792fb 1364
8d74f656 1365 regs = intel_overlay_map_regs(overlay);
02e792fb
DV
1366 if (!regs) {
1367 ret = -ENOMEM;
1368 goto out_unlock;
1369 }
1370
1371 update_reg_attrs(overlay, regs);
1372
9bb2ff73 1373 intel_overlay_unmap_regs(overlay, regs);
02e792fb
DV
1374
1375 if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
a6c45cf0 1376 if (IS_GEN2(dev))
02e792fb 1377 goto out_unlock;
02e792fb
DV
1378
1379 if (overlay->active) {
1380 ret = -EBUSY;
1381 goto out_unlock;
1382 }
1383
1384 ret = check_gamma(attrs);
60fc332c 1385 if (ret)
02e792fb
DV
1386 goto out_unlock;
1387
1388 I915_WRITE(OGAMC0, attrs->gamma0);
1389 I915_WRITE(OGAMC1, attrs->gamma1);
1390 I915_WRITE(OGAMC2, attrs->gamma2);
1391 I915_WRITE(OGAMC3, attrs->gamma3);
1392 I915_WRITE(OGAMC4, attrs->gamma4);
1393 I915_WRITE(OGAMC5, attrs->gamma5);
1394 }
02e792fb
DV
1395 }
1396
60fc332c 1397 ret = 0;
02e792fb
DV
1398out_unlock:
1399 mutex_unlock(&dev->struct_mutex);
1400 mutex_unlock(&dev->mode_config.mutex);
1401
1402 return ret;
1403}
1404
1405void intel_setup_overlay(struct drm_device *dev)
1406{
0206e353 1407 drm_i915_private_t *dev_priv = dev->dev_private;
02e792fb 1408 struct intel_overlay *overlay;
05394f39 1409 struct drm_i915_gem_object *reg_bo;
75020bc1 1410 struct overlay_registers __iomem *regs;
02e792fb
DV
1411 int ret;
1412
31578148 1413 if (!HAS_OVERLAY(dev))
02e792fb
DV
1414 return;
1415
1416 overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
1417 if (!overlay)
1418 return;
79d24273
CW
1419
1420 mutex_lock(&dev->struct_mutex);
1421 if (WARN_ON(dev_priv->overlay))
1422 goto out_free;
1423
02e792fb
DV
1424 overlay->dev = dev;
1425
ac52bc56 1426 reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
02e792fb
DV
1427 if (!reg_bo)
1428 goto out_free;
05394f39 1429 overlay->reg_bo = reg_bo;
02e792fb 1430
31578148 1431 if (OVERLAY_NEEDS_PHYSICAL(dev)) {
02e792fb 1432 ret = i915_gem_attach_phys_object(dev, reg_bo,
6eeefaf3 1433 I915_GEM_PHYS_OVERLAY_REGS,
a2930128 1434 PAGE_SIZE);
0206e353
AJ
1435 if (ret) {
1436 DRM_ERROR("failed to attach phys overlay regs\n");
1437 goto out_free_bo;
1438 }
05394f39 1439 overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
31578148 1440 } else {
75e9e915 1441 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true);
02e792fb 1442 if (ret) {
0206e353
AJ
1443 DRM_ERROR("failed to pin overlay register bo\n");
1444 goto out_free_bo;
1445 }
05394f39 1446 overlay->flip_addr = reg_bo->gtt_offset;
0ddc1289
CW
1447
1448 ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1449 if (ret) {
0206e353
AJ
1450 DRM_ERROR("failed to move overlay register bo into the GTT\n");
1451 goto out_unpin_bo;
1452 }
02e792fb
DV
1453 }
1454
1455 /* init all values */
1456 overlay->color_key = 0x0101fe;
1457 overlay->brightness = -19;
1458 overlay->contrast = 75;
1459 overlay->saturation = 146;
1460
8d74f656 1461 regs = intel_overlay_map_regs(overlay);
02e792fb 1462 if (!regs)
79d24273 1463 goto out_unpin_bo;
02e792fb 1464
75020bc1 1465 memset_io(regs, 0, sizeof(struct overlay_registers));
02e792fb 1466 update_polyphase_filter(regs);
02e792fb
DV
1467 update_reg_attrs(overlay, regs);
1468
9bb2ff73 1469 intel_overlay_unmap_regs(overlay, regs);
02e792fb
DV
1470
1471 dev_priv->overlay = overlay;
79d24273 1472 mutex_unlock(&dev->struct_mutex);
02e792fb
DV
1473 DRM_INFO("initialized overlay support\n");
1474 return;
1475
0ddc1289 1476out_unpin_bo:
79d24273
CW
1477 if (!OVERLAY_NEEDS_PHYSICAL(dev))
1478 i915_gem_object_unpin(reg_bo);
02e792fb 1479out_free_bo:
05394f39 1480 drm_gem_object_unreference(&reg_bo->base);
02e792fb 1481out_free:
79d24273 1482 mutex_unlock(&dev->struct_mutex);
02e792fb
DV
1483 kfree(overlay);
1484 return;
1485}
1486
1487void intel_cleanup_overlay(struct drm_device *dev)
1488{
722506f0 1489 drm_i915_private_t *dev_priv = dev->dev_private;
02e792fb 1490
62cf4e6f
CW
1491 if (!dev_priv->overlay)
1492 return;
02e792fb 1493
62cf4e6f
CW
1494 /* The bo's should be free'd by the generic code already.
1495 * Furthermore modesetting teardown happens beforehand so the
1496 * hardware should be off already */
1497 BUG_ON(dev_priv->overlay->active);
1498
1499 drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
1500 kfree(dev_priv->overlay);
02e792fb 1501}
6ef3d427 1502
3bd3c932
CW
1503#ifdef CONFIG_DEBUG_FS
1504#include <linux/seq_file.h>
1505
6ef3d427
CW
1506struct intel_overlay_error_state {
1507 struct overlay_registers regs;
1508 unsigned long base;
1509 u32 dovsta;
1510 u32 isr;
1511};
1512
75020bc1 1513static struct overlay_registers __iomem *
c48c43e4 1514intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
3bd3c932 1515{
c48c43e4 1516 drm_i915_private_t *dev_priv = overlay->dev->dev_private;
75020bc1 1517 struct overlay_registers __iomem *regs;
3bd3c932
CW
1518
1519 if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
75020bc1
BW
1520 /* Cast to make sparse happy, but it's wc memory anyway, so
1521 * equivalent to the wc io mapping on X86. */
1522 regs = (struct overlay_registers __iomem *)
1523 overlay->reg_bo->phys_obj->handle->vaddr;
3bd3c932
CW
1524 else
1525 regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
c48c43e4 1526 overlay->reg_bo->gtt_offset);
3bd3c932
CW
1527
1528 return regs;
1529}
1530
1531static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
75020bc1 1532 struct overlay_registers __iomem *regs)
3bd3c932
CW
1533{
1534 if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
c48c43e4 1535 io_mapping_unmap_atomic(regs);
3bd3c932
CW
1536}
1537
1538
6ef3d427
CW
1539struct intel_overlay_error_state *
1540intel_overlay_capture_error_state(struct drm_device *dev)
1541{
0206e353 1542 drm_i915_private_t *dev_priv = dev->dev_private;
6ef3d427
CW
1543 struct intel_overlay *overlay = dev_priv->overlay;
1544 struct intel_overlay_error_state *error;
1545 struct overlay_registers __iomem *regs;
1546
1547 if (!overlay || !overlay->active)
1548 return NULL;
1549
1550 error = kmalloc(sizeof(*error), GFP_ATOMIC);
1551 if (error == NULL)
1552 return NULL;
1553
1554 error->dovsta = I915_READ(DOVSTA);
1555 error->isr = I915_READ(ISR);
31578148 1556 if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
75020bc1 1557 error->base = (__force long)overlay->reg_bo->phys_obj->handle->vaddr;
31578148 1558 else
75020bc1 1559 error->base = overlay->reg_bo->gtt_offset;
6ef3d427
CW
1560
1561 regs = intel_overlay_map_regs_atomic(overlay);
1562 if (!regs)
1563 goto err;
1564
1565 memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
c48c43e4 1566 intel_overlay_unmap_regs_atomic(overlay, regs);
6ef3d427
CW
1567
1568 return error;
1569
1570err:
1571 kfree(error);
1572 return NULL;
1573}
1574
1575void
1576intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
1577{
1578 seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1579 error->dovsta, error->isr);
1580 seq_printf(m, " Register file at 0x%08lx:\n",
1581 error->base);
1582
1583#define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x)
1584 P(OBUF_0Y);
1585 P(OBUF_1Y);
1586 P(OBUF_0U);
1587 P(OBUF_0V);
1588 P(OBUF_1U);
1589 P(OBUF_1V);
1590 P(OSTRIDE);
1591 P(YRGB_VPH);
1592 P(UV_VPH);
1593 P(HORZ_PH);
1594 P(INIT_PHS);
1595 P(DWINPOS);
1596 P(DWINSZ);
1597 P(SWIDTH);
1598 P(SWIDTHSW);
1599 P(SHEIGHT);
1600 P(YRGBSCALE);
1601 P(UVSCALE);
1602 P(OCLRC0);
1603 P(OCLRC1);
1604 P(DCLRKV);
1605 P(DCLRKM);
1606 P(SCLRKVH);
1607 P(SCLRKVL);
1608 P(SCLRKEN);
1609 P(OCONFIG);
1610 P(OCMD);
1611 P(OSTART_0Y);
1612 P(OSTART_1Y);
1613 P(OSTART_0U);
1614 P(OSTART_0V);
1615 P(OSTART_1U);
1616 P(OSTART_1V);
1617 P(OTILEOFF_0Y);
1618 P(OTILEOFF_1Y);
1619 P(OTILEOFF_0U);
1620 P(OTILEOFF_0V);
1621 P(OTILEOFF_1U);
1622 P(OTILEOFF_1V);
1623 P(FASTHSCALE);
1624 P(UVSCALEV);
1625#undef P
1626}
3bd3c932 1627#endif