intel_overlay.c revision 5fe82c5ee1ba2d04183c376038c5d233a0311ec9
102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/*
202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * Copyright © 2009
302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter *
402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * Permission is hereby granted, free of charge, to any person obtaining a
502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * copy of this software and associated documentation files (the "Software"),
602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * to deal in the Software without restriction, including without limitation
702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * the rights to use, copy, modify, merge, publish, distribute, sublicense,
802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * and/or sell copies of the Software, and to permit persons to whom the
902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * Software is furnished to do so, subject to the following conditions:
1002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter *
1102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * The above copyright notice and this permission notice (including the next
1202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * paragraph) shall be included in all copies or substantial portions of the
1302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * Software.
1402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter *
1502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * SOFTWARE.
2202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter *
2302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * Authors:
2402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter *    Daniel Vetter <daniel@ffwll.ch>
2502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter *
2602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
2702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter */
28e167976ee7f5fe4b80f7e8f55e087f6c67cf9562Andrew Morton
29e167976ee7f5fe4b80f7e8f55e087f6c67cf9562Andrew Morton#include <linux/seq_file.h>
3002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "drmP.h"
3102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "drm.h"
3202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "i915_drm.h"
3302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "i915_drv.h"
3402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "i915_reg.h"
3502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "intel_drv.h"
3602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
3702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* Limits for overlay size. According to intel doc, the real limits are:
3802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * Y width: 4095, UV width (planar): 2047, Y height: 2047,
3902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
4002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * the mininum of both.  */
4102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define IMAGE_MAX_WIDTH		2048
4202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define IMAGE_MAX_HEIGHT	2046 /* 2 * 1023 */
4302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* on 830 and 845 these large limits result in the card hanging */
4402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define IMAGE_MAX_WIDTH_LEGACY	1024
4502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define IMAGE_MAX_HEIGHT_LEGACY	1088
4602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
4702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay register definitions */
4802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* OCMD register */
4902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_TILED_SURFACE	(0x1<<19)
5002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_MASK	(0x3<<17)
5102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_MODE	(0x3<<17)
5202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_HORIZONTAL	(0x1<<17)
5302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_VERTICAL	(0x2<<17)
5402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_BOTH	(0x3<<17)
5502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BYTEORDER_MASK	(0x3<<14) /* zero for YUYV or FOURCC YUY2 */
5602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_UV_SWAP		(0x1<<14) /* YVYU */
5702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_Y_SWAP		(0x2<<14) /* UYVY or FOURCC UYVY */
5802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_Y_AND_UV_SWAP	(0x3<<14) /* VYUY */
5902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
6002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_RGB_888		(0x1<<10) /* not in i965 Intel docs */
6102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_RGB_555		(0x2<<10) /* not in i965 Intel docs */
6202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_RGB_565		(0x3<<10) /* not in i965 Intel docs */
6302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_422_PACKED	(0x8<<10)
6402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_411_PACKED	(0x9<<10) /* not in i965 Intel docs */
6502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_420_PLANAR	(0xc<<10)
6602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_422_PLANAR	(0xd<<10)
6702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_410_PLANAR	(0xe<<10) /* also 411 */
6802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_TVSYNCFLIP_PARITY	(0x1<<9)
6902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_TVSYNCFLIP_ENABLE	(0x1<<7)
70d79613643b4512962b2be5262a09b6694dd96101Chris Wilson#define OCMD_BUF_TYPE_MASK	(0x1<<5)
7102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUF_TYPE_FRAME	(0x0<<5)
7202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUF_TYPE_FIELD	(0x1<<5)
7302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_TEST_MODE		(0x1<<4)
7402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUFFER_SELECT	(0x3<<2)
7502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUFFER0		(0x0<<2)
7602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUFFER1		(0x1<<2)
7702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_FIELD_SELECT	(0x1<<2)
7802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_FIELD0		(0x0<<1)
7902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_FIELD1		(0x1<<1)
8002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_ENABLE		(0x1<<0)
8102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
8202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* OCONFIG register */
8302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_PIPE_MASK		(0x1<<18)
8402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_PIPE_A		(0x0<<18)
8502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_PIPE_B		(0x1<<18)
8602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_GAMMA2_ENABLE	(0x1<<16)
8702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_CSC_MODE_BT601	(0x0<<5)
8802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_CSC_MODE_BT709	(0x1<<5)
8902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_CSC_BYPASS	(0x1<<4)
9002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_CC_OUT_8BIT	(0x1<<3)
9102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_TEST_MODE		(0x1<<2)
9202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_THREE_LINE_BUFFER	(0x1<<0)
9302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_TWO_LINE_BUFFER	(0x0<<0)
9402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
9502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* DCLRKM (dst-key) register */
9602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define DST_KEY_ENABLE		(0x1<<31)
9702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define CLK_RGB24_MASK		0x0
9802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define CLK_RGB16_MASK		0x070307
9902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define CLK_RGB15_MASK		0x070707
10002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define CLK_RGB8I_MASK		0xffffff
10102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
10202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define RGB16_TO_COLORKEY(c) \
10302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
10402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define RGB15_TO_COLORKEY(c) \
10502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	(((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
10602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
10702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay flip addr flag */
10802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OFC_UPDATE		0x1
10902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
11002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* polyphase filter coefficients */
11102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_HORIZ_Y_TAPS          5
11202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_VERT_Y_TAPS           3
11302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_HORIZ_UV_TAPS         3
11402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_VERT_UV_TAPS          3
11502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_PHASES                17
11602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define MAX_TAPS                5
11702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
11802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* memory bufferd overlay registers */
11902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstruct overlay_registers {
12002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OBUF_0Y;
12102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OBUF_1Y;
12202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OBUF_0U;
12302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OBUF_0V;
12402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OBUF_1U;
12502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OBUF_1V;
12602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OSTRIDE;
12702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 YRGB_VPH;
12802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 UV_VPH;
12902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 HORZ_PH;
13002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 INIT_PHS;
13102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 DWINPOS;
13202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 DWINSZ;
13302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 SWIDTH;
13402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 SWIDTHSW;
13502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 SHEIGHT;
13602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 YRGBSCALE;
13702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 UVSCALE;
13802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OCLRC0;
13902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OCLRC1;
14002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 DCLRKV;
14102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 DCLRKM;
14202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 SCLRKVH;
14302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 SCLRKVL;
14402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 SCLRKEN;
14502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OCONFIG;
14602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OCMD;
14702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 RESERVED1; /* 0x6C */
14802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OSTART_0Y;
14902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OSTART_1Y;
15002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OSTART_0U;
15102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OSTART_0V;
15202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OSTART_1U;
15302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OSTART_1V;
15402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OTILEOFF_0Y;
15502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OTILEOFF_1Y;
15602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OTILEOFF_0U;
15702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OTILEOFF_0V;
15802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OTILEOFF_1U;
15902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 OTILEOFF_1V;
16002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 FASTHSCALE; /* 0xA0 */
16102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 UVSCALEV; /* 0xA4 */
16202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
16302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
16402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
16502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
16602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
16702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
16802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
16902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
17002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter    u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
17102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter};
17202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
1738d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonstatic struct overlay_registers *
1748d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonintel_overlay_map_regs_atomic(struct intel_overlay *overlay,
1758d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson			      int slot)
17602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
17702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
17802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct overlay_registers *regs;
17902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
1809bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
18131578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson		regs = overlay->reg_bo->phys_obj->handle->vaddr;
1829bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	else
18302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
184fca3ec01e0b40cab82cac7745e154b01969e6219Chris Wilson						overlay->reg_bo->gtt_offset,
1858d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson						slot);
18602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
1879bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	return regs;
18802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
18902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
1908d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonstatic void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
1919bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson					    int slot,
1929bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson					    struct overlay_registers *regs)
19302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
19431578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1959bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson		io_mapping_unmap_atomic(regs, slot);
1968d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson}
1978d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson
1988d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonstatic struct overlay_registers *
1998d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonintel_overlay_map_regs(struct intel_overlay *overlay)
2008d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson{
2018d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
2028d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	struct overlay_registers *regs;
2038d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson
2049bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
2058d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson		regs = overlay->reg_bo->phys_obj->handle->vaddr;
2069bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	else
2078d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson		regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping,
2088d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson					 overlay->reg_bo->gtt_offset);
2098d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson
2109bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	return regs;
2118d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson}
2128d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson
2139bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilsonstatic void intel_overlay_unmap_regs(struct intel_overlay *overlay,
2149bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson				     struct overlay_registers *regs)
2158d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson{
2168d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
2179bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson		io_mapping_unmap(regs);
21802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
21902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
220b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilsonstatic int intel_overlay_do_wait_request(struct intel_overlay *overlay,
2218dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson					 struct drm_i915_gem_request *request,
222b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson					 bool interruptible,
223b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson					 int stage)
22402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
22502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
226852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	drm_i915_private_t *dev_priv = dev->dev_private;
227b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	int ret;
22802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
229852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	overlay->last_flip_req =
2308dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		i915_add_request(dev, NULL, request, &dev_priv->render_ring);
23103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (overlay->last_flip_req == 0)
23203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return -ENOMEM;
23302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
234b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	overlay->hw_wedged = stage;
235852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	ret = i915_do_wait_request(dev,
236722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				   overlay->last_flip_req, true,
237722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				   &dev_priv->render_ring);
238b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	if (ret)
23903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return ret;
24002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
24103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	overlay->hw_wedged = 0;
24203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	overlay->last_flip_req = 0;
24302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
24402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
24502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
246b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson/* overlay needs to be disable in OCMD reg */
247b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilsonstatic int intel_overlay_on(struct intel_overlay *overlay)
248b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson{
249b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	struct drm_device *dev = overlay->dev;
2508dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	struct drm_i915_gem_request *request;
251b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
252b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	BUG_ON(overlay->active);
253b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	overlay->active = 1;
254b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
2558dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	request = kzalloc(sizeof(*request), GFP_KERNEL);
2568dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	if (request == NULL)
2578dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		return -ENOMEM;
2588dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson
259b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	BEGIN_LP_RING(4);
260b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
261b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	OUT_RING(overlay->flip_addr | OFC_UPDATE);
262b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
263b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	OUT_RING(MI_NOOP);
264b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	ADVANCE_LP_RING();
265b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
2668dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	return intel_overlay_do_wait_request(overlay, request, true,
267b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson					     NEEDS_WAIT_FOR_FLIP);
268b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson}
269b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
27002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay needs to be enabled in OCMD reg */
2718dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilsonstatic int intel_overlay_continue(struct intel_overlay *overlay,
2728dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson				  bool load_polyphase_filter)
27302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
27402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
27502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter        drm_i915_private_t *dev_priv = dev->dev_private;
2768dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	struct drm_i915_gem_request *request;
27702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 flip_addr = overlay->flip_addr;
27802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 tmp;
27902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
28002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!overlay->active);
28102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
2828dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	request = kzalloc(sizeof(*request), GFP_KERNEL);
2838dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	if (request == NULL)
2848dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		return -ENOMEM;
2858dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson
28602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (load_polyphase_filter)
28702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		flip_addr |= OFC_UPDATE;
28802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
28902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* check for underruns */
29002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	tmp = I915_READ(DOVSTA);
29102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (tmp & (1 << 17))
29202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
29302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
2944f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter	BEGIN_LP_RING(2);
29502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
29602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(flip_addr);
2975a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter        ADVANCE_LP_RING();
2985a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter
299852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	overlay->last_flip_req =
3008dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		i915_add_request(dev, NULL, request, &dev_priv->render_ring);
3018dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	return 0;
3025a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter}
3035a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter
30402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay needs to be disabled in OCMD reg */
30502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int intel_overlay_off(struct intel_overlay *overlay)
30602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
30702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
3088dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	u32 flip_addr = overlay->flip_addr;
3098dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	struct drm_i915_gem_request *request;
31002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
31102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!overlay->active);
31202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
3138dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	request = kzalloc(sizeof(*request), GFP_KERNEL);
3148dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	if (request == NULL)
3158dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		return -ENOMEM;
3168dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson
31702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* According to intel docs the overlay hw may hang (when switching
31802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	 * off) without loading the filter coeffs. It is however unclear whether
31902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	 * this applies to the disabling of the overlay or to the switching off
32002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	 * of the hw. Do it in both cases */
32102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	flip_addr |= OFC_UPDATE;
32202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
3238dfbc3403113bcc51f0350c3471fa1abf664305fChris Wilson	BEGIN_LP_RING(6);
32402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* wait for overlay to go idle */
32502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
32602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(flip_addr);
327722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
32802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* turn overlay off */
329722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
33002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(flip_addr);
331722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
33202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ADVANCE_LP_RING();
33302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
3348dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	return intel_overlay_do_wait_request(overlay, request, true,
3358dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson					     SWITCH_OFF);
33602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
33702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
3385cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilsonstatic void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
3395cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson{
3405cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	struct drm_gem_object *obj = &overlay->old_vid_bo->base;
3415cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson
3425cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	i915_gem_object_unpin(obj);
3435cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	drm_gem_object_unreference(obj);
3445cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson
3455cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	overlay->old_vid_bo = NULL;
3465cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson}
3475cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson
34812ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetterstatic void intel_overlay_off_tail(struct intel_overlay *overlay)
34912ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter{
35012ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	struct drm_gem_object *obj;
35112ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter
35212ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	/* never have the overlay hw on without showing a frame */
35312ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	BUG_ON(!overlay->vid_bo);
354a8089e849a32c5b6bfd6c88dbd09c0ea4a779b71Daniel Vetter	obj = &overlay->vid_bo->base;
35512ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter
35612ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	i915_gem_object_unpin(obj);
35712ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	drm_gem_object_unreference(obj);
35812ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	overlay->vid_bo = NULL;
35912ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter
36012ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	overlay->crtc->overlay = NULL;
36112ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	overlay->crtc = NULL;
36212ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	overlay->active = 0;
36312ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter}
36412ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter
36503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter/* recover from an interruption due to a signal
36603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter * We have to be careful not to repeat work forever an make forward progess. */
36703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetterint intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
368722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson					 bool interruptible)
36903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter{
37003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	struct drm_device *dev = overlay->dev;
371852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	drm_i915_private_t *dev_priv = dev->dev_private;
37203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	int ret;
37303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
37403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (overlay->hw_wedged == HW_WEDGED)
37503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return -EIO;
37603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
377852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	ret = i915_do_wait_request(dev, overlay->last_flip_req,
378722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				   interruptible, &dev_priv->render_ring);
379b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	if (ret)
38003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return ret;
38103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
38203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	switch (overlay->hw_wedged) {
383722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case RELEASE_OLD_VID:
3845cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson		intel_overlay_release_old_vid_tail(overlay);
385722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
386b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
3878dfbc3403113bcc51f0350c3471fa1abf664305fChris Wilson	case SWITCH_OFF:
388722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		intel_overlay_off_tail(overlay);
389722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
3908dfbc3403113bcc51f0350c3471fa1abf664305fChris Wilson
391722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
392722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
39303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	}
39403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
39503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	overlay->hw_wedged = 0;
39603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	overlay->last_flip_req = 0;
39703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	return 0;
39803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter}
39903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
4005a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter/* Wait for pending overlay flip and release old frame.
4015a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter * Needs to be called before the overlay register are changed
4028d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson * via intel_overlay_(un)map_regs
4038d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson */
40402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int intel_overlay_release_old_vid(struct intel_overlay *overlay)
40502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
4065cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	struct drm_device *dev = overlay->dev;
4075cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
40802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
40902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
4105cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	/* Only wait if there is actually an old frame to release to
4115cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	 * guarantee forward progress.
4125cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	 */
41303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (!overlay->old_vid_bo)
41403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return 0;
41503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
4165cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
4178dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		struct drm_i915_gem_request *request;
4188dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson
4195cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson		/* synchronous slowpath */
4208dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		request = kzalloc(sizeof(*request), GFP_KERNEL);
4218dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		if (request == NULL)
4228dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson			return -ENOMEM;
4238dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson
4245cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson		BEGIN_LP_RING(2);
4255cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson		OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
4265cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson		OUT_RING(MI_NOOP);
4275cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson		ADVANCE_LP_RING();
4285cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson
4298dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		ret = intel_overlay_do_wait_request(overlay, request, true,
4305cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson						    RELEASE_OLD_VID);
4315cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson		if (ret)
4325cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson			return ret;
4335cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	}
43402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
4355cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson	intel_overlay_release_old_vid_tail(overlay);
43602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
43702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
43802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
43902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstruct put_image_params {
44002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int format;
44102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short dst_x;
44202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short dst_y;
44302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short dst_w;
44402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short dst_h;
44502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short src_w;
44602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short src_scan_h;
44702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short src_scan_w;
44802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short src_h;
44902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short stride_Y;
45002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short stride_UV;
45102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int offset_Y;
45202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int offset_U;
45302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int offset_V;
45402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter};
45502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
45602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int packed_depth_bytes(u32 format)
45702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
45802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (format & I915_OVERLAY_DEPTH_MASK) {
459722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV422:
460722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 4;
461722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV411:
462722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* return 6; not implemented */
463722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
464722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
46502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
46602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
46702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
46802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int packed_width_bytes(u32 format, short width)
46902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
47002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (format & I915_OVERLAY_DEPTH_MASK) {
471722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV422:
472722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return width << 1;
473722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
474722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
47502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
47602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
47702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
47802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int uv_hsubsampling(u32 format)
47902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
48002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (format & I915_OVERLAY_DEPTH_MASK) {
481722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV422:
482722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV420:
483722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 2;
484722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV411:
485722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV410:
486722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 4;
487722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
488722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
48902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
49002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
49102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
49202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int uv_vsubsampling(u32 format)
49302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
49402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (format & I915_OVERLAY_DEPTH_MASK) {
495722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV420:
496722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV410:
497722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 2;
498722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV422:
499722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV411:
500722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 1;
501722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
502722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
50302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
50402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
50502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
50602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
50702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
50802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 mask, shift, ret;
50902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (IS_I9XX(dev)) {
51002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mask = 0x3f;
51102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		shift = 6;
51202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else {
51302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mask = 0x1f;
51402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		shift = 5;
51502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
51602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = ((offset + width + mask) >> shift) - (offset >> shift);
51702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (IS_I9XX(dev))
51802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret <<= 1;
51902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret -=1;
52002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return ret << 2;
52102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
52202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
52302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
52402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
52502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
52602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
52702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
52802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
52902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
53002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
53102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
53202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
53302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
53402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
53502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
53602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
53702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
53802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
53902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
540722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	0xb000, 0x3000, 0x0800, 0x3000, 0xb000
541722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson};
542722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
54302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
54402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
54502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
54602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
54702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
54802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
54902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
55002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
55102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
552722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	0x3000, 0x0800, 0x3000
553722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson};
55402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
55502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_polyphase_filter(struct overlay_registers *regs)
55602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
55702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
55802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
55902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
56002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
56102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool update_scaling_factors(struct intel_overlay *overlay,
56202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				   struct overlay_registers *regs,
56302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				   struct put_image_params *params)
56402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
56502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* fixed point with a 12 bit shift */
56602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 xscale, yscale, xscale_UV, yscale_UV;
56702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define FP_SHIFT 12
56802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define FRACT_MASK 0xfff
56902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	bool scale_changed = false;
57002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int uv_hscale = uv_hsubsampling(params->format);
57102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int uv_vscale = uv_vsubsampling(params->format);
57202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
57302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->dst_w > 1)
57402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		xscale = ((params->src_scan_w - 1) << FP_SHIFT)
57502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			/(params->dst_w);
57602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	else
57702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		xscale = 1 << FP_SHIFT;
57802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
57902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->dst_h > 1)
58002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		yscale = ((params->src_scan_h - 1) << FP_SHIFT)
58102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			/(params->dst_h);
58202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	else
58302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		yscale = 1 << FP_SHIFT;
58402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
58502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
586722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	xscale_UV = xscale/uv_hscale;
587722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	yscale_UV = yscale/uv_vscale;
588722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	/* make the Y scale to UV scale ratio an exact multiply */
589722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	xscale = xscale_UV * uv_hscale;
590722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	yscale = yscale_UV * uv_vscale;
59102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/*} else {
592722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	  xscale_UV = 0;
593722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	  yscale_UV = 0;
594722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	  }*/
59502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
59602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
59702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		scale_changed = true;
59802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->old_xscale = xscale;
59902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->old_yscale = yscale;
60002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
601722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) |
602722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			   ((xscale >> FP_SHIFT)  << 16) |
603722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			   ((xscale & FRACT_MASK) << 3));
604722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
605722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) |
606722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			 ((xscale_UV >> FP_SHIFT)  << 16) |
607722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			 ((xscale_UV & FRACT_MASK) << 3));
608722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
609722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	regs->UVSCALEV = ((((yscale    >> FP_SHIFT) << 16) |
610722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			   ((yscale_UV >> FP_SHIFT) << 0)));
61102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
61202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (scale_changed)
61302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		update_polyphase_filter(regs);
61402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
61502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return scale_changed;
61602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
61702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
61802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_colorkey(struct intel_overlay *overlay,
61902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			    struct overlay_registers *regs)
62002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
62102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 key = overlay->color_key;
6226ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson
62302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (overlay->crtc->base.fb->bits_per_pixel) {
624722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case 8:
625722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		regs->DCLRKV = 0;
626722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
6276ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson		break;
6286ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson
629722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case 16:
630722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (overlay->crtc->base.fb->depth == 15) {
631722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			regs->DCLRKV = RGB15_TO_COLORKEY(key);
632722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
633722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		} else {
634722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			regs->DCLRKV = RGB16_TO_COLORKEY(key);
635722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
636722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		}
6376ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson		break;
6386ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson
639722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case 24:
640722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case 32:
641722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		regs->DCLRKV = key;
642722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
6436ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson		break;
64402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
64502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
64602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
64702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic u32 overlay_cmd_reg(struct put_image_params *params)
64802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
64902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
65002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
65102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->format & I915_OVERLAY_YUV_PLANAR) {
65202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
653722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV422:
654722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_422_PLANAR;
655722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
656722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV420:
657722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_420_PLANAR;
658722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
659722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV411:
660722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV410:
661722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_410_PLANAR;
662722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
66302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
66402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else { /* YUV packed */
66502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
666722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV422:
667722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_422_PACKED;
668722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
669722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV411:
670722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_411_PACKED;
671722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
67202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
67302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
67402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		switch (params->format & I915_OVERLAY_SWAP_MASK) {
675722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_NO_SWAP:
676722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
677722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_UV_SWAP:
678722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_UV_SWAP;
679722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
680722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_Y_SWAP:
681722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_Y_SWAP;
682722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
683722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_Y_AND_UV_SWAP:
684722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_Y_AND_UV_SWAP;
685722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
68602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
68702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
68802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
68902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return cmd;
69002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
69102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
6925fe82c5ee1ba2d04183c376038c5d233a0311ec9Chris Wilsonstatic int intel_overlay_do_put_image(struct intel_overlay *overlay,
6935fe82c5ee1ba2d04183c376038c5d233a0311ec9Chris Wilson				      struct drm_gem_object *new_bo,
6945fe82c5ee1ba2d04183c376038c5d233a0311ec9Chris Wilson				      struct put_image_params *params)
69502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
69602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret, tmp_width;
69702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct overlay_registers *regs;
69802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	bool scale_changed = false;
69923010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter	struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo);
70002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
70102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
70202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
70302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
70402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!overlay);
70502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
70602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = intel_overlay_release_old_vid(overlay);
70702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
70802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
70902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
71002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = i915_gem_object_pin(new_bo, PAGE_SIZE);
71102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
71202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
71302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
71402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = i915_gem_object_set_to_gtt_domain(new_bo, 0);
71502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
71602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unpin;
71702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
71802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay->active) {
7198d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson		regs = intel_overlay_map_regs(overlay);
72002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (!regs) {
72102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			ret = -ENOMEM;
72202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unpin;
72302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
72402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OCONFIG = OCONF_CC_OUT_8BIT;
72502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (IS_I965GM(overlay->dev))
72602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
72702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
72802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			OCONF_PIPE_A : OCONF_PIPE_B;
7299bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson		intel_overlay_unmap_regs(overlay, regs);
73002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
73102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = intel_overlay_on(overlay);
73202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (ret != 0)
73302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unpin;
73402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
73502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
7368d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	regs = intel_overlay_map_regs(overlay);
73702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!regs) {
73802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = -ENOMEM;
73902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unpin;
74002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
74102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
74202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
74302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
74402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
74502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->format & I915_OVERLAY_YUV_PACKED)
74602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		tmp_width = packed_width_bytes(params->format, params->src_w);
74702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	else
74802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		tmp_width = params->src_w;
74902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
75002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->SWIDTH = params->src_w;
75102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->SWIDTHSW = calc_swidthsw(overlay->dev,
752722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				       params->offset_Y, tmp_width);
75302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->SHEIGHT = params->src_h;
75402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y;
75502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OSTRIDE = params->stride_Y;
75602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
75702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->format & I915_OVERLAY_YUV_PLANAR) {
75802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		int uv_hscale = uv_hsubsampling(params->format);
75902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		int uv_vscale = uv_vsubsampling(params->format);
76002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		u32 tmp_U, tmp_V;
76102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
76202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
763722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				      params->src_w/uv_hscale);
76402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
765722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				      params->src_w/uv_hscale);
76602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
76702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
76802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U;
76902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OBUF_0V = bo_priv->gtt_offset + params->offset_V;
77002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OSTRIDE |= params->stride_UV << 16;
77102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
77202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
77302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	scale_changed = update_scaling_factors(overlay, regs, params);
77402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
77502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	update_colorkey(overlay, regs);
77602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
77702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OCMD = overlay_cmd_reg(params);
77802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
7799bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	intel_overlay_unmap_regs(overlay, regs);
78002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
7818dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	ret = intel_overlay_continue(overlay, scale_changed);
7828dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson	if (ret)
7838dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson		goto out_unpin;
78402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
78502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->old_vid_bo = overlay->vid_bo;
78623010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter	overlay->vid_bo = to_intel_bo(new_bo);
78702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
78802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
78902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
79002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unpin:
79102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	i915_gem_object_unpin(new_bo);
79202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return ret;
79302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
79402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
79502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_switch_off(struct intel_overlay *overlay)
79602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
79702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
79802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct overlay_registers *regs;
79902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
80002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
80102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
80202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
80302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
8049bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter	if (overlay->hw_wedged) {
8059bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter		ret = intel_overlay_recover_from_interrupt(overlay, 1);
8069bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter		if (ret != 0)
8079bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter			return ret;
8089bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter	}
8099bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter
81002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay->active)
81102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return 0;
81202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
81302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = intel_overlay_release_old_vid(overlay);
81402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
81502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
81602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
8178d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	regs = intel_overlay_map_regs(overlay);
81802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OCMD = 0;
8199bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	intel_overlay_unmap_regs(overlay, regs);
82002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
82102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = intel_overlay_off(overlay);
82203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (ret != 0)
82303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return ret;
82403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
82512ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	intel_overlay_off_tail(overlay);
82602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
82702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
82802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
82902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
83002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
83102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter					  struct intel_crtc *crtc)
83202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
833722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
83402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 pipeconf;
83502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF;
83602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
83702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON)
83802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
83902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
84002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	pipeconf = I915_READ(pipeconf_reg);
84102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
84202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* can't use the overlay with double wide pipe */
84302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!IS_I965G(overlay->dev) && pipeconf & PIPEACONF_DOUBLE_WIDE)
84402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
84502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
84602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
84702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
84802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
84902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_pfit_vscale_ratio(struct intel_overlay *overlay)
85002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
85102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
852722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
85302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 pfit_control = I915_READ(PFIT_CONTROL);
854446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	u32 ratio;
85502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
85602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* XXX: This is not the same logic as in the xorg driver, but more in
857446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	 * line with the intel documentation for the i965
858446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	 */
859446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	if (!IS_I965G(dev)) {
860446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson		if (pfit_control & VERT_AUTO_SCALE)
861446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson			ratio = I915_READ(PFIT_AUTO_RATIOS);
86202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		else
863446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson			ratio = I915_READ(PFIT_PGM_RATIOS);
864446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson		ratio >>= PFIT_VERT_SCALE_SHIFT;
865446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	} else { /* on i965 use the PGM reg to read out the autoscaler values */
866446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson		ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
86702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
86802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
86902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->pfit_vscale_ratio = ratio;
87002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
87102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
87202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_dst(struct intel_overlay *overlay,
87302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			     struct drm_intel_overlay_put_image *rec)
87402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
87502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_display_mode *mode = &overlay->crtc->base.mode;
87602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
877722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	if (rec->dst_x < mode->crtc_hdisplay &&
878722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    rec->dst_x + rec->dst_width <= mode->crtc_hdisplay &&
879722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    rec->dst_y < mode->crtc_vdisplay &&
880722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    rec->dst_y + rec->dst_height <= mode->crtc_vdisplay)
88102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return 0;
88202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	else
88302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
88402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
88502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
88602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_scaling(struct put_image_params *rec)
88702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
88802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 tmp;
88902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
89002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* downscaling limit is 8.0 */
89102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
89202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (tmp > 7)
89302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
89402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
89502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (tmp > 7)
89602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
89702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
89802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
89902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
90002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
90102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_src(struct drm_device *dev,
90202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			     struct drm_intel_overlay_put_image *rec,
90302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			     struct drm_gem_object *new_bo)
90402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
90502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int uv_hscale = uv_hsubsampling(rec->flags);
90602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int uv_vscale = uv_vsubsampling(rec->flags);
9079f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson	u32 stride_mask, depth, tmp;
90802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
90902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* check src dimensions */
91002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (IS_845G(dev) || IS_I830(dev)) {
911722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
9129f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
91302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return -EINVAL;
91402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else {
915722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->src_height > IMAGE_MAX_HEIGHT ||
9169f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		    rec->src_width  > IMAGE_MAX_WIDTH)
91702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return -EINVAL;
91802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
9199f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
92002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* better safe than sorry, use 4 as the maximal subsampling ratio */
921722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	if (rec->src_height < N_VERT_Y_TAPS*4 ||
9229f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson	    rec->src_width  < N_HORIZ_Y_TAPS*4)
92302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
92402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
925a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson	/* check alignment constraints */
92602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
927722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_RGB:
928722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* not implemented */
929722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
9309f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
931722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV_PACKED:
932722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (uv_vscale != 1)
93302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return -EINVAL;
9349f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
9359f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		depth = packed_depth_bytes(rec->flags);
936722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (depth < 0)
937722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return depth;
9389f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
939722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* ignore UV planes */
940722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		rec->stride_UV = 0;
941722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		rec->offset_U = 0;
942722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		rec->offset_V = 0;
943722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* check pixel alignment */
944722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->offset_Y % depth)
945722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
946722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
9479f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
948722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV_PLANAR:
949722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (uv_vscale < 0 || uv_hscale < 0)
95002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return -EINVAL;
951722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* no offset restrictions for planar formats */
952722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
9539f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
954722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
955722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
95602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
95702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
95802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (rec->src_width % uv_hscale)
95902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
96002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
96102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* stride checking */
962a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson	if (IS_I830(dev) || IS_845G(dev))
963a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson		stride_mask = 255;
964a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson	else
965a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson		stride_mask = 63;
96602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
96702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
96802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
96902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (IS_I965G(dev) && rec->stride_Y < 512)
97002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
97102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
97202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
9739f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		4096 : 8192;
9749f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson	if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
97502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
97602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
97702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* check buffer dimensions */
97802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
979722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_RGB:
980722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV_PACKED:
981722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* always 4 Y values per depth pixels */
982722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
983722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
984722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
985722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		tmp = rec->stride_Y*rec->src_height;
986722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->offset_Y + tmp > new_bo->size)
987722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
988722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
989722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
990722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV_PLANAR:
991722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->src_width > rec->stride_Y)
992722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
993722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->src_width/uv_hscale > rec->stride_UV)
994722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
995722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
9969f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		tmp = rec->stride_Y * rec->src_height;
997722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->offset_Y + tmp > new_bo->size)
998722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
9999f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
10009f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1001722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->offset_U + tmp > new_bo->size ||
1002722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		    rec->offset_V + tmp > new_bo->size)
1003722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
1004722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
100502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
100602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
100702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
100802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
100902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
101002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_put_image(struct drm_device *dev, void *data,
101102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                            struct drm_file *file_priv)
101202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
101302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_intel_overlay_put_image *put_image_rec = data;
101402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	drm_i915_private_t *dev_priv = dev->dev_private;
101502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct intel_overlay *overlay;
101602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_mode_object *drmmode_obj;
101702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct intel_crtc *crtc;
101802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_gem_object *new_bo;
101902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct put_image_params *params;
102002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
102102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
102202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!dev_priv) {
102302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_ERROR("called with no initialization\n");
102402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
102502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
102602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
102702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay = dev_priv->overlay;
102802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay) {
102902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_DEBUG("userspace bug: no overlay\n");
103002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -ENODEV;
103102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
103202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
103302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
103402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mutex_lock(&dev->mode_config.mutex);
103502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mutex_lock(&dev->struct_mutex);
103602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
103702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = intel_overlay_switch_off(overlay);
103802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
103902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mutex_unlock(&dev->struct_mutex);
104002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mutex_unlock(&dev->mode_config.mutex);
104102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
104202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
104302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
104402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
104502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
104602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!params)
104702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -ENOMEM;
104802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
104902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
1050722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson					   DRM_MODE_OBJECT_CRTC);
1051915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter	if (!drmmode_obj) {
1052915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter		ret = -ENOENT;
1053915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter		goto out_free;
1054915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter	}
105502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
105602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
105702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	new_bo = drm_gem_object_lookup(dev, file_priv,
1058722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				       put_image_rec->bo_handle);
1059915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter	if (!new_bo) {
1060915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter		ret = -ENOENT;
1061915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter		goto out_free;
1062915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter	}
106302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
106402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_lock(&dev->mode_config.mutex);
106502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_lock(&dev->struct_mutex);
106602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
106703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (overlay->hw_wedged) {
106803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		ret = intel_overlay_recover_from_interrupt(overlay, 1);
106903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		if (ret != 0)
107003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter			goto out_unlock;
107103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	}
107203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
107302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (overlay->crtc != crtc) {
107402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		struct drm_display_mode *mode = &crtc->base.mode;
107502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = intel_overlay_switch_off(overlay);
107602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (ret != 0)
107702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
107802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
107902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = check_overlay_possible_on_crtc(overlay, crtc);
108002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (ret != 0)
108102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
108202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
108302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		overlay->crtc = crtc;
108402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		crtc->overlay = overlay;
108502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
108602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (intel_panel_fitter_pipe(dev) == crtc->pipe
108702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		    /* and line to wide, i.e. one-line-mode */
108802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		    && mode->hdisplay > 1024) {
108902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			overlay->pfit_active = 1;
109002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			update_pfit_vscale_ratio(overlay);
109102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		} else
109202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			overlay->pfit_active = 0;
109302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
109402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
109502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = check_overlay_dst(overlay, put_image_rec);
109602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
109702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
109802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
109902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (overlay->pfit_active) {
110002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1101722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				 overlay->pfit_vscale_ratio);
110202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		/* shifting right rounds downwards, so add 1 */
110302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1104722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				 overlay->pfit_vscale_ratio) + 1;
110502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else {
110602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		params->dst_y = put_image_rec->dst_y;
110702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		params->dst_h = put_image_rec->dst_height;
110802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
110902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->dst_x = put_image_rec->dst_x;
111002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->dst_w = put_image_rec->dst_width;
111102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
111202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->src_w = put_image_rec->src_width;
111302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->src_h = put_image_rec->src_height;
111402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->src_scan_w = put_image_rec->src_scan_width;
111502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->src_scan_h = put_image_rec->src_scan_height;
1116722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	if (params->src_scan_h > params->src_h ||
1117722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    params->src_scan_w > params->src_w) {
111802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = -EINVAL;
111902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
112002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
112102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
112202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = check_overlay_src(dev, put_image_rec, new_bo);
112302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
112402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
112502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
112602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->stride_Y = put_image_rec->stride_Y;
112702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->stride_UV = put_image_rec->stride_UV;
112802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->offset_Y = put_image_rec->offset_Y;
112902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->offset_U = put_image_rec->offset_U;
113002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->offset_V = put_image_rec->offset_V;
113102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
113202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* Check scaling after src size to prevent a divide-by-zero. */
113302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = check_overlay_scaling(params);
113402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
113502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
113602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
113702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = intel_overlay_do_put_image(overlay, new_bo, params);
113802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
113902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
114002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
114102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->struct_mutex);
114202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->mode_config.mutex);
114302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
114402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	kfree(params);
114502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
114602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
114702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
114802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unlock:
114902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->struct_mutex);
115002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->mode_config.mutex);
1151bc9025bdc4e2b591734cca17697093845007b63dLuca Barbieri	drm_gem_object_unreference_unlocked(new_bo);
1152915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenterout_free:
115302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	kfree(params);
115402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
115502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return ret;
115602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
115702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
115802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_reg_attrs(struct intel_overlay *overlay,
115902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			     struct overlay_registers *regs)
116002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
116102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
116202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OCLRC1 = overlay->saturation;
116302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
116402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
116502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool check_gamma_bounds(u32 gamma1, u32 gamma2)
116602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
116702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int i;
116802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
116902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
117002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return false;
117102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
117202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	for (i = 0; i < 3; i++) {
1173722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
117402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return false;
117502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
117602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
117702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return true;
117802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
117902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
118002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool check_gamma5_errata(u32 gamma5)
118102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
118202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int i;
118302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
118402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	for (i = 0; i < 3; i++) {
118502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (((gamma5 >> i*8) & 0xff) == 0x80)
118602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return false;
118702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
118802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
118902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return true;
119002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
119102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
119202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_gamma(struct drm_intel_overlay_attrs *attrs)
119302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
1194722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	if (!check_gamma_bounds(0, attrs->gamma0) ||
1195722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1196722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1197722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1198722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1199722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1200722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
120102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
1202722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
120302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!check_gamma5_errata(attrs->gamma5))
120402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
1205722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
120602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
120702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
120802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
120902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_attrs(struct drm_device *dev, void *data,
121002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                        struct drm_file *file_priv)
121102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
121202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_intel_overlay_attrs *attrs = data;
121302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter        drm_i915_private_t *dev_priv = dev->dev_private;
121402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct intel_overlay *overlay;
121502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct overlay_registers *regs;
121602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
121702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
121802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!dev_priv) {
121902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_ERROR("called with no initialization\n");
122002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
122102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
122202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
122302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay = dev_priv->overlay;
122402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay) {
122502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_DEBUG("userspace bug: no overlay\n");
122602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -ENODEV;
122702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
122802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
122902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_lock(&dev->mode_config.mutex);
123002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_lock(&dev->struct_mutex);
123102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
123260fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson	ret = -EINVAL;
123302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
123460fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		attrs->color_key  = overlay->color_key;
123502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		attrs->brightness = overlay->brightness;
123660fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		attrs->contrast   = overlay->contrast;
123702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		attrs->saturation = overlay->saturation;
123802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
123902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (IS_I9XX(dev)) {
124002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma0 = I915_READ(OGAMC0);
124102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma1 = I915_READ(OGAMC1);
124202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma2 = I915_READ(OGAMC2);
124302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma3 = I915_READ(OGAMC3);
124402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma4 = I915_READ(OGAMC4);
124502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma5 = I915_READ(OGAMC5);
124602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
124702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else {
124860fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		if (attrs->brightness < -128 || attrs->brightness > 127)
124902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
125060fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		if (attrs->contrast > 255)
125102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
125260fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		if (attrs->saturation > 1023)
125302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
125460fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson
125560fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		overlay->color_key  = attrs->color_key;
125660fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		overlay->brightness = attrs->brightness;
125760fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		overlay->contrast   = attrs->contrast;
125860fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		overlay->saturation = attrs->saturation;
125902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
12608d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson		regs = intel_overlay_map_regs(overlay);
126102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (!regs) {
126202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			ret = -ENOMEM;
126302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
126402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
126502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
126602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		update_reg_attrs(overlay, regs);
126702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
12689bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson		intel_overlay_unmap_regs(overlay, regs);
126902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
127002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
127160fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson			if (!IS_I9XX(dev))
127202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				goto out_unlock;
127302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
127402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			if (overlay->active) {
127502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				ret = -EBUSY;
127602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				goto out_unlock;
127702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			}
127802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
127902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			ret = check_gamma(attrs);
128060fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson			if (ret)
128102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				goto out_unlock;
128202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
128302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC0, attrs->gamma0);
128402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC1, attrs->gamma1);
128502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC2, attrs->gamma2);
128602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC3, attrs->gamma3);
128702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC4, attrs->gamma4);
128802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC5, attrs->gamma5);
128902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
129002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
129102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
129260fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson	ret = 0;
129302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unlock:
129402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->struct_mutex);
129502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->mode_config.mutex);
129602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
129702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return ret;
129802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
129902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
130002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vettervoid intel_setup_overlay(struct drm_device *dev)
130102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
130202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter        drm_i915_private_t *dev_priv = dev->dev_private;
130302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct intel_overlay *overlay;
130402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_gem_object *reg_bo;
130502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct overlay_registers *regs;
130602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
130702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
130831578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	if (!HAS_OVERLAY(dev))
130902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return;
131002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
131102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
131202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay)
131302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return;
131402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->dev = dev;
131502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
1316ac52bc56de25535a907ef07f8755f1387b89b0f5Daniel Vetter	reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
131702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!reg_bo)
131802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_free;
131923010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter	overlay->reg_bo = to_intel_bo(reg_bo);
132002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
132131578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	if (OVERLAY_NEEDS_PHYSICAL(dev)) {
132231578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson		ret = i915_gem_attach_phys_object(dev, reg_bo,
132331578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson						  I915_GEM_PHYS_OVERLAY_REGS,
1324a29301288f1840bdf9c5456da9cd7c944436edd5Chris Wilson						  PAGE_SIZE);
132531578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson                if (ret) {
132631578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson                        DRM_ERROR("failed to attach phys overlay regs\n");
132731578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson                        goto out_free_bo;
132831578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson                }
132931578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson		overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr;
133031578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	} else {
133102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
133202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (ret) {
133302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                        DRM_ERROR("failed to pin overlay register bo\n");
133402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                        goto out_free_bo;
133502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                }
133602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		overlay->flip_addr = overlay->reg_bo->gtt_offset;
13370ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson
13380ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson		ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
13390ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson		if (ret) {
13400ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson                        DRM_ERROR("failed to move overlay register bo into the GTT\n");
13410ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson                        goto out_unpin_bo;
13420ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson                }
134302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
134402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
134502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* init all values */
134602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->color_key = 0x0101fe;
134702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->brightness = -19;
134802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->contrast = 75;
134902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->saturation = 146;
135002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
13518d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	regs = intel_overlay_map_regs(overlay);
135202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!regs)
135302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_free_bo;
135402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
135502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	memset(regs, 0, sizeof(struct overlay_registers));
135602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	update_polyphase_filter(regs);
135702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	update_reg_attrs(overlay, regs);
135802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
13599bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	intel_overlay_unmap_regs(overlay, regs);
136002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
136102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	dev_priv->overlay = overlay;
136202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	DRM_INFO("initialized overlay support\n");
136302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return;
136402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
13650ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilsonout_unpin_bo:
13660ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson	i915_gem_object_unpin(reg_bo);
136702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_free_bo:
136802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	drm_gem_object_unreference(reg_bo);
136902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_free:
137002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	kfree(overlay);
137102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return;
137202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
137302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
137402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vettervoid intel_cleanup_overlay(struct drm_device *dev)
137502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
1376722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
137702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
137862cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	if (!dev_priv->overlay)
137962cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson		return;
138002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
138162cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	/* The bo's should be free'd by the generic code already.
138262cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	 * Furthermore modesetting teardown happens beforehand so the
138362cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	 * hardware should be off already */
138462cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	BUG_ON(dev_priv->overlay->active);
138562cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson
138662cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
138762cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	kfree(dev_priv->overlay);
138802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
13896ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
13906ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonstruct intel_overlay_error_state {
13916ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	struct overlay_registers regs;
13926ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	unsigned long base;
13936ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	u32 dovsta;
13946ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	u32 isr;
13956ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson};
13966ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
13976ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonstruct intel_overlay_error_state *
13986ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonintel_overlay_capture_error_state(struct drm_device *dev)
13996ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson{
14006ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson        drm_i915_private_t *dev_priv = dev->dev_private;
14016ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	struct intel_overlay *overlay = dev_priv->overlay;
14026ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	struct intel_overlay_error_state *error;
14036ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	struct overlay_registers __iomem *regs;
14046ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14056ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	if (!overlay || !overlay->active)
14066ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		return NULL;
14076ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14086ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	error = kmalloc(sizeof(*error), GFP_ATOMIC);
14096ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	if (error == NULL)
14106ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		return NULL;
14116ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14126ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	error->dovsta = I915_READ(DOVSTA);
14136ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	error->isr = I915_READ(ISR);
141431578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
14156ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
141631578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	else
141731578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson		error->base = (long) overlay->reg_bo->gtt_offset;
14186ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14198d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	regs = intel_overlay_map_regs_atomic(overlay, KM_IRQ0);
14206ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	if (!regs)
14216ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		goto err;
14226ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14236ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
14249bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	intel_overlay_unmap_regs_atomic(overlay, KM_IRQ0, regs);
14256ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14266ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	return error;
14276ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14286ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonerr:
14296ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	kfree(error);
14306ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	return NULL;
14316ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson}
14326ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14336ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonvoid
14346ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonintel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
14356ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson{
14366ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
14376ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		   error->dovsta, error->isr);
14386ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	seq_printf(m, "  Register file at 0x%08lx:\n",
14396ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		   error->base);
14406ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14416ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson#define P(x) seq_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
14426ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_0Y);
14436ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_1Y);
14446ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_0U);
14456ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_0V);
14466ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_1U);
14476ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_1V);
14486ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTRIDE);
14496ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(YRGB_VPH);
14506ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(UV_VPH);
14516ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(HORZ_PH);
14526ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(INIT_PHS);
14536ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(DWINPOS);
14546ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(DWINSZ);
14556ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SWIDTH);
14566ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SWIDTHSW);
14576ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SHEIGHT);
14586ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(YRGBSCALE);
14596ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(UVSCALE);
14606ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OCLRC0);
14616ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OCLRC1);
14626ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(DCLRKV);
14636ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(DCLRKM);
14646ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SCLRKVH);
14656ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SCLRKVL);
14666ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SCLRKEN);
14676ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OCONFIG);
14686ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OCMD);
14696ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_0Y);
14706ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_1Y);
14716ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_0U);
14726ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_0V);
14736ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_1U);
14746ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_1V);
14756ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_0Y);
14766ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_1Y);
14776ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_0U);
14786ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_0V);
14796ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_1U);
14806ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_1V);
14816ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(FASTHSCALE);
14826ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(UVSCALEV);
14836ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson#undef P
14846ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson}
1485