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 */
28#include <drm/drmP.h>
29#include <drm/i915_drm.h>
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)
67#define OCMD_BUF_TYPE_MASK	(0x1<<5)
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 {
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];
168};
169
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	struct drm_i915_gem_request *last_flip_req;
186	void (*flip_tail)(struct intel_overlay *);
187};
188
189static struct overlay_registers __iomem *
190intel_overlay_map_regs(struct intel_overlay *overlay)
191{
192	struct drm_i915_private *dev_priv = overlay->dev->dev_private;
193	struct overlay_registers __iomem *regs;
194
195	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
196		regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr;
197	else
198		regs = io_mapping_map_wc(dev_priv->gtt.mappable,
199					 i915_gem_obj_ggtt_offset(overlay->reg_bo));
200
201	return regs;
202}
203
204static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
205				     struct overlay_registers __iomem *regs)
206{
207	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
208		io_mapping_unmap(regs);
209}
210
211static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
212					 void (*tail)(struct intel_overlay *))
213{
214	struct drm_device *dev = overlay->dev;
215	struct drm_i915_private *dev_priv = dev->dev_private;
216	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
217	int ret;
218
219	BUG_ON(overlay->last_flip_req);
220	i915_gem_request_assign(&overlay->last_flip_req,
221					     ring->outstanding_lazy_request);
222	ret = i915_add_request(ring);
223	if (ret)
224		return ret;
225
226	overlay->flip_tail = tail;
227	ret = i915_wait_request(overlay->last_flip_req);
228	if (ret)
229		return ret;
230	i915_gem_retire_requests(dev);
231
232	i915_gem_request_assign(&overlay->last_flip_req, NULL);
233	return 0;
234}
235
236/* overlay needs to be disable in OCMD reg */
237static int intel_overlay_on(struct intel_overlay *overlay)
238{
239	struct drm_device *dev = overlay->dev;
240	struct drm_i915_private *dev_priv = dev->dev_private;
241	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
242	int ret;
243
244	BUG_ON(overlay->active);
245	overlay->active = 1;
246
247	WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
248
249	ret = intel_ring_begin(ring, 4);
250	if (ret)
251		return ret;
252
253	intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
254	intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
255	intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
256	intel_ring_emit(ring, MI_NOOP);
257	intel_ring_advance(ring);
258
259	return intel_overlay_do_wait_request(overlay, NULL);
260}
261
262/* overlay needs to be enabled in OCMD reg */
263static int intel_overlay_continue(struct intel_overlay *overlay,
264				  bool load_polyphase_filter)
265{
266	struct drm_device *dev = overlay->dev;
267	struct drm_i915_private *dev_priv = dev->dev_private;
268	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
269	u32 flip_addr = overlay->flip_addr;
270	u32 tmp;
271	int ret;
272
273	BUG_ON(!overlay->active);
274
275	if (load_polyphase_filter)
276		flip_addr |= OFC_UPDATE;
277
278	/* check for underruns */
279	tmp = I915_READ(DOVSTA);
280	if (tmp & (1 << 17))
281		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
282
283	ret = intel_ring_begin(ring, 2);
284	if (ret)
285		return ret;
286
287	intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
288	intel_ring_emit(ring, flip_addr);
289	intel_ring_advance(ring);
290
291	WARN_ON(overlay->last_flip_req);
292	i915_gem_request_assign(&overlay->last_flip_req,
293					     ring->outstanding_lazy_request);
294	return i915_add_request(ring);
295}
296
297static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
298{
299	struct drm_i915_gem_object *obj = overlay->old_vid_bo;
300
301	i915_gem_object_ggtt_unpin(obj);
302	drm_gem_object_unreference(&obj->base);
303
304	overlay->old_vid_bo = NULL;
305}
306
307static void intel_overlay_off_tail(struct intel_overlay *overlay)
308{
309	struct drm_i915_gem_object *obj = overlay->vid_bo;
310
311	/* never have the overlay hw on without showing a frame */
312	BUG_ON(!overlay->vid_bo);
313
314	i915_gem_object_ggtt_unpin(obj);
315	drm_gem_object_unreference(&obj->base);
316	overlay->vid_bo = NULL;
317
318	overlay->crtc->overlay = NULL;
319	overlay->crtc = NULL;
320	overlay->active = 0;
321}
322
323/* overlay needs to be disabled in OCMD reg */
324static int intel_overlay_off(struct intel_overlay *overlay)
325{
326	struct drm_device *dev = overlay->dev;
327	struct drm_i915_private *dev_priv = dev->dev_private;
328	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
329	u32 flip_addr = overlay->flip_addr;
330	int ret;
331
332	BUG_ON(!overlay->active);
333
334	/* According to intel docs the overlay hw may hang (when switching
335	 * off) without loading the filter coeffs. It is however unclear whether
336	 * this applies to the disabling of the overlay or to the switching off
337	 * of the hw. Do it in both cases */
338	flip_addr |= OFC_UPDATE;
339
340	ret = intel_ring_begin(ring, 6);
341	if (ret)
342		return ret;
343
344	/* wait for overlay to go idle */
345	intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
346	intel_ring_emit(ring, flip_addr);
347	intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
348	/* turn overlay off */
349	if (IS_I830(dev)) {
350		/* Workaround: Don't disable the overlay fully, since otherwise
351		 * it dies on the next OVERLAY_ON cmd. */
352		intel_ring_emit(ring, MI_NOOP);
353		intel_ring_emit(ring, MI_NOOP);
354		intel_ring_emit(ring, MI_NOOP);
355	} else {
356		intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
357		intel_ring_emit(ring, flip_addr);
358		intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
359	}
360	intel_ring_advance(ring);
361
362	return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
363}
364
365/* recover from an interruption due to a signal
366 * We have to be careful not to repeat work forever an make forward progess. */
367static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
368{
369	int ret;
370
371	if (overlay->last_flip_req == NULL)
372		return 0;
373
374	ret = i915_wait_request(overlay->last_flip_req);
375	if (ret)
376		return ret;
377	i915_gem_retire_requests(overlay->dev);
378
379	if (overlay->flip_tail)
380		overlay->flip_tail(overlay);
381
382	i915_gem_request_assign(&overlay->last_flip_req, NULL);
383	return 0;
384}
385
386/* Wait for pending overlay flip and release old frame.
387 * Needs to be called before the overlay register are changed
388 * via intel_overlay_(un)map_regs
389 */
390static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
391{
392	struct drm_device *dev = overlay->dev;
393	struct drm_i915_private *dev_priv = dev->dev_private;
394	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
395	int ret;
396
397	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
398
399	/* Only wait if there is actually an old frame to release to
400	 * guarantee forward progress.
401	 */
402	if (!overlay->old_vid_bo)
403		return 0;
404
405	if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
406		/* synchronous slowpath */
407		ret = intel_ring_begin(ring, 2);
408		if (ret)
409			return ret;
410
411		intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
412		intel_ring_emit(ring, MI_NOOP);
413		intel_ring_advance(ring);
414
415		ret = intel_overlay_do_wait_request(overlay,
416						    intel_overlay_release_old_vid_tail);
417		if (ret)
418			return ret;
419	}
420
421	intel_overlay_release_old_vid_tail(overlay);
422
423
424	i915_gem_track_fb(overlay->old_vid_bo, NULL,
425			  INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
426	return 0;
427}
428
429void intel_overlay_reset(struct drm_i915_private *dev_priv)
430{
431	struct intel_overlay *overlay = dev_priv->overlay;
432
433	if (!overlay)
434		return;
435
436	intel_overlay_release_old_vid(overlay);
437
438	overlay->last_flip_req = NULL;
439	overlay->old_xscale = 0;
440	overlay->old_yscale = 0;
441	overlay->crtc = NULL;
442	overlay->active = false;
443}
444
445struct put_image_params {
446	int format;
447	short dst_x;
448	short dst_y;
449	short dst_w;
450	short dst_h;
451	short src_w;
452	short src_scan_h;
453	short src_scan_w;
454	short src_h;
455	short stride_Y;
456	short stride_UV;
457	int offset_Y;
458	int offset_U;
459	int offset_V;
460};
461
462static int packed_depth_bytes(u32 format)
463{
464	switch (format & I915_OVERLAY_DEPTH_MASK) {
465	case I915_OVERLAY_YUV422:
466		return 4;
467	case I915_OVERLAY_YUV411:
468		/* return 6; not implemented */
469	default:
470		return -EINVAL;
471	}
472}
473
474static int packed_width_bytes(u32 format, short width)
475{
476	switch (format & I915_OVERLAY_DEPTH_MASK) {
477	case I915_OVERLAY_YUV422:
478		return width << 1;
479	default:
480		return -EINVAL;
481	}
482}
483
484static int uv_hsubsampling(u32 format)
485{
486	switch (format & I915_OVERLAY_DEPTH_MASK) {
487	case I915_OVERLAY_YUV422:
488	case I915_OVERLAY_YUV420:
489		return 2;
490	case I915_OVERLAY_YUV411:
491	case I915_OVERLAY_YUV410:
492		return 4;
493	default:
494		return -EINVAL;
495	}
496}
497
498static int uv_vsubsampling(u32 format)
499{
500	switch (format & I915_OVERLAY_DEPTH_MASK) {
501	case I915_OVERLAY_YUV420:
502	case I915_OVERLAY_YUV410:
503		return 2;
504	case I915_OVERLAY_YUV422:
505	case I915_OVERLAY_YUV411:
506		return 1;
507	default:
508		return -EINVAL;
509	}
510}
511
512static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
513{
514	u32 mask, shift, ret;
515	if (IS_GEN2(dev)) {
516		mask = 0x1f;
517		shift = 5;
518	} else {
519		mask = 0x3f;
520		shift = 6;
521	}
522	ret = ((offset + width + mask) >> shift) - (offset >> shift);
523	if (!IS_GEN2(dev))
524		ret <<= 1;
525	ret -= 1;
526	return ret << 2;
527}
528
529static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
530	0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
531	0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
532	0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
533	0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
534	0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
535	0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
536	0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
537	0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
538	0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
539	0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
540	0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
541	0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
542	0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
543	0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
544	0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
545	0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
546	0xb000, 0x3000, 0x0800, 0x3000, 0xb000
547};
548
549static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
550	0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
551	0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
552	0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
553	0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
554	0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
555	0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
556	0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
557	0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
558	0x3000, 0x0800, 0x3000
559};
560
561static void update_polyphase_filter(struct overlay_registers __iomem *regs)
562{
563	memcpy_toio(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
564	memcpy_toio(regs->UV_HCOEFS, uv_static_hcoeffs,
565		    sizeof(uv_static_hcoeffs));
566}
567
568static bool update_scaling_factors(struct intel_overlay *overlay,
569				   struct overlay_registers __iomem *regs,
570				   struct put_image_params *params)
571{
572	/* fixed point with a 12 bit shift */
573	u32 xscale, yscale, xscale_UV, yscale_UV;
574#define FP_SHIFT 12
575#define FRACT_MASK 0xfff
576	bool scale_changed = false;
577	int uv_hscale = uv_hsubsampling(params->format);
578	int uv_vscale = uv_vsubsampling(params->format);
579
580	if (params->dst_w > 1)
581		xscale = ((params->src_scan_w - 1) << FP_SHIFT)
582			/(params->dst_w);
583	else
584		xscale = 1 << FP_SHIFT;
585
586	if (params->dst_h > 1)
587		yscale = ((params->src_scan_h - 1) << FP_SHIFT)
588			/(params->dst_h);
589	else
590		yscale = 1 << FP_SHIFT;
591
592	/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
593	xscale_UV = xscale/uv_hscale;
594	yscale_UV = yscale/uv_vscale;
595	/* make the Y scale to UV scale ratio an exact multiply */
596	xscale = xscale_UV * uv_hscale;
597	yscale = yscale_UV * uv_vscale;
598	/*} else {
599	  xscale_UV = 0;
600	  yscale_UV = 0;
601	  }*/
602
603	if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
604		scale_changed = true;
605	overlay->old_xscale = xscale;
606	overlay->old_yscale = yscale;
607
608	iowrite32(((yscale & FRACT_MASK) << 20) |
609		  ((xscale >> FP_SHIFT)  << 16) |
610		  ((xscale & FRACT_MASK) << 3),
611		 &regs->YRGBSCALE);
612
613	iowrite32(((yscale_UV & FRACT_MASK) << 20) |
614		  ((xscale_UV >> FP_SHIFT)  << 16) |
615		  ((xscale_UV & FRACT_MASK) << 3),
616		 &regs->UVSCALE);
617
618	iowrite32((((yscale    >> FP_SHIFT) << 16) |
619		   ((yscale_UV >> FP_SHIFT) << 0)),
620		 &regs->UVSCALEV);
621
622	if (scale_changed)
623		update_polyphase_filter(regs);
624
625	return scale_changed;
626}
627
628static void update_colorkey(struct intel_overlay *overlay,
629			    struct overlay_registers __iomem *regs)
630{
631	u32 key = overlay->color_key;
632
633	switch (overlay->crtc->base.primary->fb->bits_per_pixel) {
634	case 8:
635		iowrite32(0, &regs->DCLRKV);
636		iowrite32(CLK_RGB8I_MASK | DST_KEY_ENABLE, &regs->DCLRKM);
637		break;
638
639	case 16:
640		if (overlay->crtc->base.primary->fb->depth == 15) {
641			iowrite32(RGB15_TO_COLORKEY(key), &regs->DCLRKV);
642			iowrite32(CLK_RGB15_MASK | DST_KEY_ENABLE,
643				  &regs->DCLRKM);
644		} else {
645			iowrite32(RGB16_TO_COLORKEY(key), &regs->DCLRKV);
646			iowrite32(CLK_RGB16_MASK | DST_KEY_ENABLE,
647				  &regs->DCLRKM);
648		}
649		break;
650
651	case 24:
652	case 32:
653		iowrite32(key, &regs->DCLRKV);
654		iowrite32(CLK_RGB24_MASK | DST_KEY_ENABLE, &regs->DCLRKM);
655		break;
656	}
657}
658
659static u32 overlay_cmd_reg(struct put_image_params *params)
660{
661	u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
662
663	if (params->format & I915_OVERLAY_YUV_PLANAR) {
664		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
665		case I915_OVERLAY_YUV422:
666			cmd |= OCMD_YUV_422_PLANAR;
667			break;
668		case I915_OVERLAY_YUV420:
669			cmd |= OCMD_YUV_420_PLANAR;
670			break;
671		case I915_OVERLAY_YUV411:
672		case I915_OVERLAY_YUV410:
673			cmd |= OCMD_YUV_410_PLANAR;
674			break;
675		}
676	} else { /* YUV packed */
677		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
678		case I915_OVERLAY_YUV422:
679			cmd |= OCMD_YUV_422_PACKED;
680			break;
681		case I915_OVERLAY_YUV411:
682			cmd |= OCMD_YUV_411_PACKED;
683			break;
684		}
685
686		switch (params->format & I915_OVERLAY_SWAP_MASK) {
687		case I915_OVERLAY_NO_SWAP:
688			break;
689		case I915_OVERLAY_UV_SWAP:
690			cmd |= OCMD_UV_SWAP;
691			break;
692		case I915_OVERLAY_Y_SWAP:
693			cmd |= OCMD_Y_SWAP;
694			break;
695		case I915_OVERLAY_Y_AND_UV_SWAP:
696			cmd |= OCMD_Y_AND_UV_SWAP;
697			break;
698		}
699	}
700
701	return cmd;
702}
703
704static int intel_overlay_do_put_image(struct intel_overlay *overlay,
705				      struct drm_i915_gem_object *new_bo,
706				      struct put_image_params *params)
707{
708	int ret, tmp_width;
709	struct overlay_registers __iomem *regs;
710	bool scale_changed = false;
711	struct drm_device *dev = overlay->dev;
712	u32 swidth, swidthsw, sheight, ostride;
713	enum pipe pipe = overlay->crtc->pipe;
714
715	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
716	BUG_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
717	BUG_ON(!overlay);
718
719	ret = intel_overlay_release_old_vid(overlay);
720	if (ret != 0)
721		return ret;
722
723	ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL,
724						   &i915_ggtt_view_normal);
725	if (ret != 0)
726		return ret;
727
728	ret = i915_gem_object_put_fence(new_bo);
729	if (ret)
730		goto out_unpin;
731
732	if (!overlay->active) {
733		u32 oconfig;
734		regs = intel_overlay_map_regs(overlay);
735		if (!regs) {
736			ret = -ENOMEM;
737			goto out_unpin;
738		}
739		oconfig = OCONF_CC_OUT_8BIT;
740		if (IS_GEN4(overlay->dev))
741			oconfig |= OCONF_CSC_MODE_BT709;
742		oconfig |= pipe == 0 ?
743			OCONF_PIPE_A : OCONF_PIPE_B;
744		iowrite32(oconfig, &regs->OCONFIG);
745		intel_overlay_unmap_regs(overlay, regs);
746
747		ret = intel_overlay_on(overlay);
748		if (ret != 0)
749			goto out_unpin;
750	}
751
752	regs = intel_overlay_map_regs(overlay);
753	if (!regs) {
754		ret = -ENOMEM;
755		goto out_unpin;
756	}
757
758	iowrite32((params->dst_y << 16) | params->dst_x, &regs->DWINPOS);
759	iowrite32((params->dst_h << 16) | params->dst_w, &regs->DWINSZ);
760
761	if (params->format & I915_OVERLAY_YUV_PACKED)
762		tmp_width = packed_width_bytes(params->format, params->src_w);
763	else
764		tmp_width = params->src_w;
765
766	swidth = params->src_w;
767	swidthsw = calc_swidthsw(overlay->dev, params->offset_Y, tmp_width);
768	sheight = params->src_h;
769	iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_Y, &regs->OBUF_0Y);
770	ostride = params->stride_Y;
771
772	if (params->format & I915_OVERLAY_YUV_PLANAR) {
773		int uv_hscale = uv_hsubsampling(params->format);
774		int uv_vscale = uv_vsubsampling(params->format);
775		u32 tmp_U, tmp_V;
776		swidth |= (params->src_w/uv_hscale) << 16;
777		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
778				      params->src_w/uv_hscale);
779		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
780				      params->src_w/uv_hscale);
781		swidthsw |= max_t(u32, tmp_U, tmp_V) << 16;
782		sheight |= (params->src_h/uv_vscale) << 16;
783		iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_U, &regs->OBUF_0U);
784		iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_V, &regs->OBUF_0V);
785		ostride |= params->stride_UV << 16;
786	}
787
788	iowrite32(swidth, &regs->SWIDTH);
789	iowrite32(swidthsw, &regs->SWIDTHSW);
790	iowrite32(sheight, &regs->SHEIGHT);
791	iowrite32(ostride, &regs->OSTRIDE);
792
793	scale_changed = update_scaling_factors(overlay, regs, params);
794
795	update_colorkey(overlay, regs);
796
797	iowrite32(overlay_cmd_reg(params), &regs->OCMD);
798
799	intel_overlay_unmap_regs(overlay, regs);
800
801	ret = intel_overlay_continue(overlay, scale_changed);
802	if (ret)
803		goto out_unpin;
804
805	i915_gem_track_fb(overlay->vid_bo, new_bo,
806			  INTEL_FRONTBUFFER_OVERLAY(pipe));
807
808	overlay->old_vid_bo = overlay->vid_bo;
809	overlay->vid_bo = new_bo;
810
811	intel_frontbuffer_flip(dev,
812			       INTEL_FRONTBUFFER_OVERLAY(pipe));
813
814	return 0;
815
816out_unpin:
817	i915_gem_object_ggtt_unpin(new_bo);
818	return ret;
819}
820
821int intel_overlay_switch_off(struct intel_overlay *overlay)
822{
823	struct overlay_registers __iomem *regs;
824	struct drm_device *dev = overlay->dev;
825	int ret;
826
827	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
828	BUG_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
829
830	ret = intel_overlay_recover_from_interrupt(overlay);
831	if (ret != 0)
832		return ret;
833
834	if (!overlay->active)
835		return 0;
836
837	ret = intel_overlay_release_old_vid(overlay);
838	if (ret != 0)
839		return ret;
840
841	regs = intel_overlay_map_regs(overlay);
842	iowrite32(0, &regs->OCMD);
843	intel_overlay_unmap_regs(overlay, regs);
844
845	ret = intel_overlay_off(overlay);
846	if (ret != 0)
847		return ret;
848
849	intel_overlay_off_tail(overlay);
850	return 0;
851}
852
853static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
854					  struct intel_crtc *crtc)
855{
856	if (!crtc->active)
857		return -EINVAL;
858
859	/* can't use the overlay with double wide pipe */
860	if (crtc->config->double_wide)
861		return -EINVAL;
862
863	return 0;
864}
865
866static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
867{
868	struct drm_device *dev = overlay->dev;
869	struct drm_i915_private *dev_priv = dev->dev_private;
870	u32 pfit_control = I915_READ(PFIT_CONTROL);
871	u32 ratio;
872
873	/* XXX: This is not the same logic as in the xorg driver, but more in
874	 * line with the intel documentation for the i965
875	 */
876	if (INTEL_INFO(dev)->gen >= 4) {
877		/* on i965 use the PGM reg to read out the autoscaler values */
878		ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
879	} else {
880		if (pfit_control & VERT_AUTO_SCALE)
881			ratio = I915_READ(PFIT_AUTO_RATIOS);
882		else
883			ratio = I915_READ(PFIT_PGM_RATIOS);
884		ratio >>= PFIT_VERT_SCALE_SHIFT;
885	}
886
887	overlay->pfit_vscale_ratio = ratio;
888}
889
890static int check_overlay_dst(struct intel_overlay *overlay,
891			     struct drm_intel_overlay_put_image *rec)
892{
893	struct drm_display_mode *mode = &overlay->crtc->base.mode;
894
895	if (rec->dst_x < mode->hdisplay &&
896	    rec->dst_x + rec->dst_width <= mode->hdisplay &&
897	    rec->dst_y < mode->vdisplay &&
898	    rec->dst_y + rec->dst_height <= mode->vdisplay)
899		return 0;
900	else
901		return -EINVAL;
902}
903
904static int check_overlay_scaling(struct put_image_params *rec)
905{
906	u32 tmp;
907
908	/* downscaling limit is 8.0 */
909	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
910	if (tmp > 7)
911		return -EINVAL;
912	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
913	if (tmp > 7)
914		return -EINVAL;
915
916	return 0;
917}
918
919static int check_overlay_src(struct drm_device *dev,
920			     struct drm_intel_overlay_put_image *rec,
921			     struct drm_i915_gem_object *new_bo)
922{
923	int uv_hscale = uv_hsubsampling(rec->flags);
924	int uv_vscale = uv_vsubsampling(rec->flags);
925	u32 stride_mask;
926	int depth;
927	u32 tmp;
928
929	/* check src dimensions */
930	if (IS_845G(dev) || IS_I830(dev)) {
931		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
932		    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
933			return -EINVAL;
934	} else {
935		if (rec->src_height > IMAGE_MAX_HEIGHT ||
936		    rec->src_width  > IMAGE_MAX_WIDTH)
937			return -EINVAL;
938	}
939
940	/* better safe than sorry, use 4 as the maximal subsampling ratio */
941	if (rec->src_height < N_VERT_Y_TAPS*4 ||
942	    rec->src_width  < N_HORIZ_Y_TAPS*4)
943		return -EINVAL;
944
945	/* check alignment constraints */
946	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
947	case I915_OVERLAY_RGB:
948		/* not implemented */
949		return -EINVAL;
950
951	case I915_OVERLAY_YUV_PACKED:
952		if (uv_vscale != 1)
953			return -EINVAL;
954
955		depth = packed_depth_bytes(rec->flags);
956		if (depth < 0)
957			return depth;
958
959		/* ignore UV planes */
960		rec->stride_UV = 0;
961		rec->offset_U = 0;
962		rec->offset_V = 0;
963		/* check pixel alignment */
964		if (rec->offset_Y % depth)
965			return -EINVAL;
966		break;
967
968	case I915_OVERLAY_YUV_PLANAR:
969		if (uv_vscale < 0 || uv_hscale < 0)
970			return -EINVAL;
971		/* no offset restrictions for planar formats */
972		break;
973
974	default:
975		return -EINVAL;
976	}
977
978	if (rec->src_width % uv_hscale)
979		return -EINVAL;
980
981	/* stride checking */
982	if (IS_I830(dev) || IS_845G(dev))
983		stride_mask = 255;
984	else
985		stride_mask = 63;
986
987	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
988		return -EINVAL;
989	if (IS_GEN4(dev) && rec->stride_Y < 512)
990		return -EINVAL;
991
992	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
993		4096 : 8192;
994	if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
995		return -EINVAL;
996
997	/* check buffer dimensions */
998	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
999	case I915_OVERLAY_RGB:
1000	case I915_OVERLAY_YUV_PACKED:
1001		/* always 4 Y values per depth pixels */
1002		if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1003			return -EINVAL;
1004
1005		tmp = rec->stride_Y*rec->src_height;
1006		if (rec->offset_Y + tmp > new_bo->base.size)
1007			return -EINVAL;
1008		break;
1009
1010	case I915_OVERLAY_YUV_PLANAR:
1011		if (rec->src_width > rec->stride_Y)
1012			return -EINVAL;
1013		if (rec->src_width/uv_hscale > rec->stride_UV)
1014			return -EINVAL;
1015
1016		tmp = rec->stride_Y * rec->src_height;
1017		if (rec->offset_Y + tmp > new_bo->base.size)
1018			return -EINVAL;
1019
1020		tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1021		if (rec->offset_U + tmp > new_bo->base.size ||
1022		    rec->offset_V + tmp > new_bo->base.size)
1023			return -EINVAL;
1024		break;
1025	}
1026
1027	return 0;
1028}
1029
1030/**
1031 * Return the pipe currently connected to the panel fitter,
1032 * or -1 if the panel fitter is not present or not in use
1033 */
1034static int intel_panel_fitter_pipe(struct drm_device *dev)
1035{
1036	struct drm_i915_private *dev_priv = dev->dev_private;
1037	u32  pfit_control;
1038
1039	/* i830 doesn't have a panel fitter */
1040	if (INTEL_INFO(dev)->gen <= 3 && (IS_I830(dev) || !IS_MOBILE(dev)))
1041		return -1;
1042
1043	pfit_control = I915_READ(PFIT_CONTROL);
1044
1045	/* See if the panel fitter is in use */
1046	if ((pfit_control & PFIT_ENABLE) == 0)
1047		return -1;
1048
1049	/* 965 can place panel fitter on either pipe */
1050	if (IS_GEN4(dev))
1051		return (pfit_control >> 29) & 0x3;
1052
1053	/* older chips can only use pipe 1 */
1054	return 1;
1055}
1056
1057int intel_overlay_put_image(struct drm_device *dev, void *data,
1058			    struct drm_file *file_priv)
1059{
1060	struct drm_intel_overlay_put_image *put_image_rec = data;
1061	struct drm_i915_private *dev_priv = dev->dev_private;
1062	struct intel_overlay *overlay;
1063	struct drm_crtc *drmmode_crtc;
1064	struct intel_crtc *crtc;
1065	struct drm_i915_gem_object *new_bo;
1066	struct put_image_params *params;
1067	int ret;
1068
1069	overlay = dev_priv->overlay;
1070	if (!overlay) {
1071		DRM_DEBUG("userspace bug: no overlay\n");
1072		return -ENODEV;
1073	}
1074
1075	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
1076		drm_modeset_lock_all(dev);
1077		mutex_lock(&dev->struct_mutex);
1078
1079		ret = intel_overlay_switch_off(overlay);
1080
1081		mutex_unlock(&dev->struct_mutex);
1082		drm_modeset_unlock_all(dev);
1083
1084		return ret;
1085	}
1086
1087	params = kmalloc(sizeof(*params), GFP_KERNEL);
1088	if (!params)
1089		return -ENOMEM;
1090
1091	drmmode_crtc = drm_crtc_find(dev, put_image_rec->crtc_id);
1092	if (!drmmode_crtc) {
1093		ret = -ENOENT;
1094		goto out_free;
1095	}
1096	crtc = to_intel_crtc(drmmode_crtc);
1097
1098	new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
1099						   put_image_rec->bo_handle));
1100	if (&new_bo->base == NULL) {
1101		ret = -ENOENT;
1102		goto out_free;
1103	}
1104
1105	drm_modeset_lock_all(dev);
1106	mutex_lock(&dev->struct_mutex);
1107
1108	if (new_bo->tiling_mode) {
1109		DRM_DEBUG_KMS("buffer used for overlay image can not be tiled\n");
1110		ret = -EINVAL;
1111		goto out_unlock;
1112	}
1113
1114	ret = intel_overlay_recover_from_interrupt(overlay);
1115	if (ret != 0)
1116		goto out_unlock;
1117
1118	if (overlay->crtc != crtc) {
1119		struct drm_display_mode *mode = &crtc->base.mode;
1120		ret = intel_overlay_switch_off(overlay);
1121		if (ret != 0)
1122			goto out_unlock;
1123
1124		ret = check_overlay_possible_on_crtc(overlay, crtc);
1125		if (ret != 0)
1126			goto out_unlock;
1127
1128		overlay->crtc = crtc;
1129		crtc->overlay = overlay;
1130
1131		/* line too wide, i.e. one-line-mode */
1132		if (mode->hdisplay > 1024 &&
1133		    intel_panel_fitter_pipe(dev) == crtc->pipe) {
1134			overlay->pfit_active = 1;
1135			update_pfit_vscale_ratio(overlay);
1136		} else
1137			overlay->pfit_active = 0;
1138	}
1139
1140	ret = check_overlay_dst(overlay, put_image_rec);
1141	if (ret != 0)
1142		goto out_unlock;
1143
1144	if (overlay->pfit_active) {
1145		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1146				 overlay->pfit_vscale_ratio);
1147		/* shifting right rounds downwards, so add 1 */
1148		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1149				 overlay->pfit_vscale_ratio) + 1;
1150	} else {
1151		params->dst_y = put_image_rec->dst_y;
1152		params->dst_h = put_image_rec->dst_height;
1153	}
1154	params->dst_x = put_image_rec->dst_x;
1155	params->dst_w = put_image_rec->dst_width;
1156
1157	params->src_w = put_image_rec->src_width;
1158	params->src_h = put_image_rec->src_height;
1159	params->src_scan_w = put_image_rec->src_scan_width;
1160	params->src_scan_h = put_image_rec->src_scan_height;
1161	if (params->src_scan_h > params->src_h ||
1162	    params->src_scan_w > params->src_w) {
1163		ret = -EINVAL;
1164		goto out_unlock;
1165	}
1166
1167	ret = check_overlay_src(dev, put_image_rec, new_bo);
1168	if (ret != 0)
1169		goto out_unlock;
1170	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
1171	params->stride_Y = put_image_rec->stride_Y;
1172	params->stride_UV = put_image_rec->stride_UV;
1173	params->offset_Y = put_image_rec->offset_Y;
1174	params->offset_U = put_image_rec->offset_U;
1175	params->offset_V = put_image_rec->offset_V;
1176
1177	/* Check scaling after src size to prevent a divide-by-zero. */
1178	ret = check_overlay_scaling(params);
1179	if (ret != 0)
1180		goto out_unlock;
1181
1182	ret = intel_overlay_do_put_image(overlay, new_bo, params);
1183	if (ret != 0)
1184		goto out_unlock;
1185
1186	mutex_unlock(&dev->struct_mutex);
1187	drm_modeset_unlock_all(dev);
1188
1189	kfree(params);
1190
1191	return 0;
1192
1193out_unlock:
1194	mutex_unlock(&dev->struct_mutex);
1195	drm_modeset_unlock_all(dev);
1196	drm_gem_object_unreference_unlocked(&new_bo->base);
1197out_free:
1198	kfree(params);
1199
1200	return ret;
1201}
1202
1203static void update_reg_attrs(struct intel_overlay *overlay,
1204			     struct overlay_registers __iomem *regs)
1205{
1206	iowrite32((overlay->contrast << 18) | (overlay->brightness & 0xff),
1207		  &regs->OCLRC0);
1208	iowrite32(overlay->saturation, &regs->OCLRC1);
1209}
1210
1211static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1212{
1213	int i;
1214
1215	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1216		return false;
1217
1218	for (i = 0; i < 3; i++) {
1219		if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1220			return false;
1221	}
1222
1223	return true;
1224}
1225
1226static bool check_gamma5_errata(u32 gamma5)
1227{
1228	int i;
1229
1230	for (i = 0; i < 3; i++) {
1231		if (((gamma5 >> i*8) & 0xff) == 0x80)
1232			return false;
1233	}
1234
1235	return true;
1236}
1237
1238static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1239{
1240	if (!check_gamma_bounds(0, attrs->gamma0) ||
1241	    !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1242	    !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1243	    !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1244	    !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1245	    !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1246	    !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
1247		return -EINVAL;
1248
1249	if (!check_gamma5_errata(attrs->gamma5))
1250		return -EINVAL;
1251
1252	return 0;
1253}
1254
1255int intel_overlay_attrs(struct drm_device *dev, void *data,
1256			struct drm_file *file_priv)
1257{
1258	struct drm_intel_overlay_attrs *attrs = data;
1259	struct drm_i915_private *dev_priv = dev->dev_private;
1260	struct intel_overlay *overlay;
1261	struct overlay_registers __iomem *regs;
1262	int ret;
1263
1264	overlay = dev_priv->overlay;
1265	if (!overlay) {
1266		DRM_DEBUG("userspace bug: no overlay\n");
1267		return -ENODEV;
1268	}
1269
1270	drm_modeset_lock_all(dev);
1271	mutex_lock(&dev->struct_mutex);
1272
1273	ret = -EINVAL;
1274	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
1275		attrs->color_key  = overlay->color_key;
1276		attrs->brightness = overlay->brightness;
1277		attrs->contrast   = overlay->contrast;
1278		attrs->saturation = overlay->saturation;
1279
1280		if (!IS_GEN2(dev)) {
1281			attrs->gamma0 = I915_READ(OGAMC0);
1282			attrs->gamma1 = I915_READ(OGAMC1);
1283			attrs->gamma2 = I915_READ(OGAMC2);
1284			attrs->gamma3 = I915_READ(OGAMC3);
1285			attrs->gamma4 = I915_READ(OGAMC4);
1286			attrs->gamma5 = I915_READ(OGAMC5);
1287		}
1288	} else {
1289		if (attrs->brightness < -128 || attrs->brightness > 127)
1290			goto out_unlock;
1291		if (attrs->contrast > 255)
1292			goto out_unlock;
1293		if (attrs->saturation > 1023)
1294			goto out_unlock;
1295
1296		overlay->color_key  = attrs->color_key;
1297		overlay->brightness = attrs->brightness;
1298		overlay->contrast   = attrs->contrast;
1299		overlay->saturation = attrs->saturation;
1300
1301		regs = intel_overlay_map_regs(overlay);
1302		if (!regs) {
1303			ret = -ENOMEM;
1304			goto out_unlock;
1305		}
1306
1307		update_reg_attrs(overlay, regs);
1308
1309		intel_overlay_unmap_regs(overlay, regs);
1310
1311		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
1312			if (IS_GEN2(dev))
1313				goto out_unlock;
1314
1315			if (overlay->active) {
1316				ret = -EBUSY;
1317				goto out_unlock;
1318			}
1319
1320			ret = check_gamma(attrs);
1321			if (ret)
1322				goto out_unlock;
1323
1324			I915_WRITE(OGAMC0, attrs->gamma0);
1325			I915_WRITE(OGAMC1, attrs->gamma1);
1326			I915_WRITE(OGAMC2, attrs->gamma2);
1327			I915_WRITE(OGAMC3, attrs->gamma3);
1328			I915_WRITE(OGAMC4, attrs->gamma4);
1329			I915_WRITE(OGAMC5, attrs->gamma5);
1330		}
1331	}
1332
1333	ret = 0;
1334out_unlock:
1335	mutex_unlock(&dev->struct_mutex);
1336	drm_modeset_unlock_all(dev);
1337
1338	return ret;
1339}
1340
1341void intel_setup_overlay(struct drm_device *dev)
1342{
1343	struct drm_i915_private *dev_priv = dev->dev_private;
1344	struct intel_overlay *overlay;
1345	struct drm_i915_gem_object *reg_bo;
1346	struct overlay_registers __iomem *regs;
1347	int ret;
1348
1349	if (!HAS_OVERLAY(dev))
1350		return;
1351
1352	overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
1353	if (!overlay)
1354		return;
1355
1356	mutex_lock(&dev->struct_mutex);
1357	if (WARN_ON(dev_priv->overlay))
1358		goto out_free;
1359
1360	overlay->dev = dev;
1361
1362	reg_bo = NULL;
1363	if (!OVERLAY_NEEDS_PHYSICAL(dev))
1364		reg_bo = i915_gem_object_create_stolen(dev, PAGE_SIZE);
1365	if (reg_bo == NULL)
1366		reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
1367	if (reg_bo == NULL)
1368		goto out_free;
1369	overlay->reg_bo = reg_bo;
1370
1371	if (OVERLAY_NEEDS_PHYSICAL(dev)) {
1372		ret = i915_gem_object_attach_phys(reg_bo, PAGE_SIZE);
1373		if (ret) {
1374			DRM_ERROR("failed to attach phys overlay regs\n");
1375			goto out_free_bo;
1376		}
1377		overlay->flip_addr = reg_bo->phys_handle->busaddr;
1378	} else {
1379		ret = i915_gem_obj_ggtt_pin(reg_bo, PAGE_SIZE, PIN_MAPPABLE);
1380		if (ret) {
1381			DRM_ERROR("failed to pin overlay register bo\n");
1382			goto out_free_bo;
1383		}
1384		overlay->flip_addr = i915_gem_obj_ggtt_offset(reg_bo);
1385
1386		ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1387		if (ret) {
1388			DRM_ERROR("failed to move overlay register bo into the GTT\n");
1389			goto out_unpin_bo;
1390		}
1391	}
1392
1393	/* init all values */
1394	overlay->color_key = 0x0101fe;
1395	overlay->brightness = -19;
1396	overlay->contrast = 75;
1397	overlay->saturation = 146;
1398
1399	regs = intel_overlay_map_regs(overlay);
1400	if (!regs)
1401		goto out_unpin_bo;
1402
1403	memset_io(regs, 0, sizeof(struct overlay_registers));
1404	update_polyphase_filter(regs);
1405	update_reg_attrs(overlay, regs);
1406
1407	intel_overlay_unmap_regs(overlay, regs);
1408
1409	dev_priv->overlay = overlay;
1410	mutex_unlock(&dev->struct_mutex);
1411	DRM_INFO("initialized overlay support\n");
1412	return;
1413
1414out_unpin_bo:
1415	if (!OVERLAY_NEEDS_PHYSICAL(dev))
1416		i915_gem_object_ggtt_unpin(reg_bo);
1417out_free_bo:
1418	drm_gem_object_unreference(&reg_bo->base);
1419out_free:
1420	mutex_unlock(&dev->struct_mutex);
1421	kfree(overlay);
1422	return;
1423}
1424
1425void intel_cleanup_overlay(struct drm_device *dev)
1426{
1427	struct drm_i915_private *dev_priv = dev->dev_private;
1428
1429	if (!dev_priv->overlay)
1430		return;
1431
1432	/* The bo's should be free'd by the generic code already.
1433	 * Furthermore modesetting teardown happens beforehand so the
1434	 * hardware should be off already */
1435	BUG_ON(dev_priv->overlay->active);
1436
1437	drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
1438	kfree(dev_priv->overlay);
1439}
1440
1441struct intel_overlay_error_state {
1442	struct overlay_registers regs;
1443	unsigned long base;
1444	u32 dovsta;
1445	u32 isr;
1446};
1447
1448static struct overlay_registers __iomem *
1449intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
1450{
1451	struct drm_i915_private *dev_priv = overlay->dev->dev_private;
1452	struct overlay_registers __iomem *regs;
1453
1454	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1455		/* Cast to make sparse happy, but it's wc memory anyway, so
1456		 * equivalent to the wc io mapping on X86. */
1457		regs = (struct overlay_registers __iomem *)
1458			overlay->reg_bo->phys_handle->vaddr;
1459	else
1460		regs = io_mapping_map_atomic_wc(dev_priv->gtt.mappable,
1461						i915_gem_obj_ggtt_offset(overlay->reg_bo));
1462
1463	return regs;
1464}
1465
1466static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
1467					struct overlay_registers __iomem *regs)
1468{
1469	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1470		io_mapping_unmap_atomic(regs);
1471}
1472
1473
1474struct intel_overlay_error_state *
1475intel_overlay_capture_error_state(struct drm_device *dev)
1476{
1477	struct drm_i915_private *dev_priv = dev->dev_private;
1478	struct intel_overlay *overlay = dev_priv->overlay;
1479	struct intel_overlay_error_state *error;
1480	struct overlay_registers __iomem *regs;
1481
1482	if (!overlay || !overlay->active)
1483		return NULL;
1484
1485	error = kmalloc(sizeof(*error), GFP_ATOMIC);
1486	if (error == NULL)
1487		return NULL;
1488
1489	error->dovsta = I915_READ(DOVSTA);
1490	error->isr = I915_READ(ISR);
1491	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1492		error->base = (__force long)overlay->reg_bo->phys_handle->vaddr;
1493	else
1494		error->base = i915_gem_obj_ggtt_offset(overlay->reg_bo);
1495
1496	regs = intel_overlay_map_regs_atomic(overlay);
1497	if (!regs)
1498		goto err;
1499
1500	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
1501	intel_overlay_unmap_regs_atomic(overlay, regs);
1502
1503	return error;
1504
1505err:
1506	kfree(error);
1507	return NULL;
1508}
1509
1510void
1511intel_overlay_print_error_state(struct drm_i915_error_state_buf *m,
1512				struct intel_overlay_error_state *error)
1513{
1514	i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1515			  error->dovsta, error->isr);
1516	i915_error_printf(m, "  Register file at 0x%08lx:\n",
1517			  error->base);
1518
1519#define P(x) i915_error_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
1520	P(OBUF_0Y);
1521	P(OBUF_1Y);
1522	P(OBUF_0U);
1523	P(OBUF_0V);
1524	P(OBUF_1U);
1525	P(OBUF_1V);
1526	P(OSTRIDE);
1527	P(YRGB_VPH);
1528	P(UV_VPH);
1529	P(HORZ_PH);
1530	P(INIT_PHS);
1531	P(DWINPOS);
1532	P(DWINSZ);
1533	P(SWIDTH);
1534	P(SWIDTHSW);
1535	P(SHEIGHT);
1536	P(YRGBSCALE);
1537	P(UVSCALE);
1538	P(OCLRC0);
1539	P(OCLRC1);
1540	P(DCLRKV);
1541	P(DCLRKM);
1542	P(SCLRKVH);
1543	P(SCLRKVL);
1544	P(SCLRKEN);
1545	P(OCONFIG);
1546	P(OCMD);
1547	P(OSTART_0Y);
1548	P(OSTART_1Y);
1549	P(OSTART_0U);
1550	P(OSTART_0V);
1551	P(OSTART_1U);
1552	P(OSTART_1V);
1553	P(OTILEOFF_0Y);
1554	P(OTILEOFF_1Y);
1555	P(OTILEOFF_0U);
1556	P(OTILEOFF_0V);
1557	P(OTILEOFF_1U);
1558	P(OTILEOFF_1V);
1559	P(FASTHSCALE);
1560	P(UVSCALEV);
1561#undef P
1562}
1563