intel_overlay.c revision 9bb2ff731b32c023e7a502efdc0dee46157290d5
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,
221b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson					 bool interruptible,
222b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson					 int stage)
22302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
22402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
225852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	drm_i915_private_t *dev_priv = dev->dev_private;
226b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	int ret;
22702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
228852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	overlay->last_flip_req =
2298a1a49f954734040dbc7b87e3b1221a050045e43Daniel Vetter		i915_add_request(dev, NULL, &dev_priv->render_ring);
23003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (overlay->last_flip_req == 0)
23103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return -ENOMEM;
23202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
233b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	overlay->hw_wedged = stage;
234852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	ret = i915_do_wait_request(dev,
235722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				   overlay->last_flip_req, true,
236722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				   &dev_priv->render_ring);
237b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	if (ret)
23803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return ret;
23902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
24003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	overlay->hw_wedged = 0;
24103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	overlay->last_flip_req = 0;
24202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
24302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
24402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
245b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson/* overlay needs to be disable in OCMD reg */
246b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilsonstatic int intel_overlay_on(struct intel_overlay *overlay)
247b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson{
248b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	struct drm_device *dev = overlay->dev;
249b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
250b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	BUG_ON(overlay->active);
251b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
252b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	overlay->active = 1;
253b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
254b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	BEGIN_LP_RING(4);
255b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
256b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	OUT_RING(overlay->flip_addr | OFC_UPDATE);
257b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
258b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	OUT_RING(MI_NOOP);
259b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	ADVANCE_LP_RING();
260b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
261b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	return intel_overlay_do_wait_request(overlay, true,
262b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson					     NEEDS_WAIT_FOR_FLIP);
263b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson}
264b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
26502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay needs to be enabled in OCMD reg */
26602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void intel_overlay_continue(struct intel_overlay *overlay,
267722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				   bool load_polyphase_filter)
26802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
26902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
27002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter        drm_i915_private_t *dev_priv = dev->dev_private;
27102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 flip_addr = overlay->flip_addr;
27202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 tmp;
27302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
27402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!overlay->active);
27502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
27602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (load_polyphase_filter)
27702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		flip_addr |= OFC_UPDATE;
27802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
27902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* check for underruns */
28002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	tmp = I915_READ(DOVSTA);
28102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (tmp & (1 << 17))
28202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
28302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
2844f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter	BEGIN_LP_RING(2);
28502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
28602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(flip_addr);
2875a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter        ADVANCE_LP_RING();
2885a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter
289852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	overlay->last_flip_req =
2908a1a49f954734040dbc7b87e3b1221a050045e43Daniel Vetter		i915_add_request(dev, NULL, &dev_priv->render_ring);
2915a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter}
2925a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter
2935a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetterstatic int intel_overlay_wait_flip(struct intel_overlay *overlay)
2945a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter{
2955a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter	struct drm_device *dev = overlay->dev;
296722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
2975a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter	int ret;
2985a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter	u32 tmp;
2995a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter
3005a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter	if (overlay->last_flip_req != 0) {
301722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		ret = i915_do_wait_request(dev,
302722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson					   overlay->last_flip_req, true,
303722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson					   &dev_priv->render_ring);
3045c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter		if (ret == 0) {
3055c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter			overlay->last_flip_req = 0;
3065a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter
3075c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter			tmp = I915_READ(ISR);
3085a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter
3095c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter			if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT))
3105c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter				return 0;
3115c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter		}
3125a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter	}
3135a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter
3145a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter	/* synchronous slowpath */
3155a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter	BEGIN_LP_RING(2);
316722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
317722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_NOOP);
318722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	ADVANCE_LP_RING();
31902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
320b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	return intel_overlay_do_wait_request(overlay, true, RELEASE_OLD_VID);
32102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
32202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
32302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay needs to be disabled in OCMD reg */
32402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int intel_overlay_off(struct intel_overlay *overlay)
32502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
32602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 flip_addr = overlay->flip_addr;
32702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
32802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
32902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
33002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!overlay->active);
33102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
33202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* According to intel docs the overlay hw may hang (when switching
33302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	 * off) without loading the filter coeffs. It is however unclear whether
33402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	 * this applies to the disabling of the overlay or to the switching off
33502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	 * of the hw. Do it in both cases */
33602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	flip_addr |= OFC_UPDATE;
33702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
33802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* wait for overlay to go idle */
3394f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter	BEGIN_LP_RING(4);
34002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
34102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(flip_addr);
342722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
343722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_NOOP);
344722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	ADVANCE_LP_RING();
34502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
346b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	ret = intel_overlay_do_wait_request(overlay, true,
347b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson					    SWITCH_OFF_STAGE_1);
348b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	if (ret)
34902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
35002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
35102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* turn overlay off */
3524f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter	BEGIN_LP_RING(4);
353722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
35402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	OUT_RING(flip_addr);
355722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
356722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	OUT_RING(MI_NOOP);
35702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ADVANCE_LP_RING();
35802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
359b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	return intel_overlay_do_wait_request(overlay, true,
360b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson					     SWITCH_OFF_STAGE_2);
36102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
36202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
36312ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetterstatic void intel_overlay_off_tail(struct intel_overlay *overlay)
36412ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter{
36512ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	struct drm_gem_object *obj;
36612ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter
36712ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	/* never have the overlay hw on without showing a frame */
36812ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	BUG_ON(!overlay->vid_bo);
369a8089e849a32c5b6bfd6c88dbd09c0ea4a779b71Daniel Vetter	obj = &overlay->vid_bo->base;
37012ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter
37112ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	i915_gem_object_unpin(obj);
37212ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	drm_gem_object_unreference(obj);
37312ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	overlay->vid_bo = NULL;
37412ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter
37512ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	overlay->crtc->overlay = NULL;
37612ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	overlay->crtc = NULL;
37712ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	overlay->active = 0;
37812ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter}
37912ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter
38003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter/* recover from an interruption due to a signal
38103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter * We have to be careful not to repeat work forever an make forward progess. */
38203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetterint intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
383722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson					 bool interruptible)
38403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter{
38503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	struct drm_device *dev = overlay->dev;
38603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	struct drm_gem_object *obj;
387852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	drm_i915_private_t *dev_priv = dev->dev_private;
38803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	u32 flip_addr;
38903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	int ret;
39003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
39103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (overlay->hw_wedged == HW_WEDGED)
39203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return -EIO;
39303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
394852835f343146a82a528c3b712b373661d4fa17aZou Nan hai	ret = i915_do_wait_request(dev, overlay->last_flip_req,
395722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				   interruptible, &dev_priv->render_ring);
396b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson	if (ret)
39703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return ret;
39803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
39903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	switch (overlay->hw_wedged) {
400722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case RELEASE_OLD_VID:
401722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		obj = &overlay->old_vid_bo->base;
402722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		i915_gem_object_unpin(obj);
403722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		drm_gem_object_unreference(obj);
404722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		overlay->old_vid_bo = NULL;
405722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
406b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson
407722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case SWITCH_OFF_STAGE_1:
408722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		flip_addr = overlay->flip_addr;
409722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		flip_addr |= OFC_UPDATE;
41003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
411722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		BEGIN_LP_RING(4);
412722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
413722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		OUT_RING(flip_addr);
414722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
415722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		OUT_RING(MI_NOOP);
416722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		ADVANCE_LP_RING();
417722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
418b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson		ret = intel_overlay_do_wait_request(overlay, interruptible,
419b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson						    SWITCH_OFF_STAGE_2);
420b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson		if (ret)
421722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return ret;
422722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
423722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case SWITCH_OFF_STAGE_2:
424722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		intel_overlay_off_tail(overlay);
425722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
426722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
427722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
42803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	}
42903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
43003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	overlay->hw_wedged = 0;
43103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	overlay->last_flip_req = 0;
43203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	return 0;
43303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter}
43403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
4355a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter/* Wait for pending overlay flip and release old frame.
4365a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter * Needs to be called before the overlay register are changed
4378d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson * via intel_overlay_(un)map_regs
4388d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson */
43902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int intel_overlay_release_old_vid(struct intel_overlay *overlay)
44002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
44102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
44202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_gem_object *obj;
44302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
44403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	/* only wait if there is actually an old frame to release to
44503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	 * guarantee forward progress */
44603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (!overlay->old_vid_bo)
44703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return 0;
44803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
44902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = intel_overlay_wait_flip(overlay);
45002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
45102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
45202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
453a8089e849a32c5b6bfd6c88dbd09c0ea4a779b71Daniel Vetter	obj = &overlay->old_vid_bo->base;
45402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	i915_gem_object_unpin(obj);
45502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	drm_gem_object_unreference(obj);
45602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->old_vid_bo = NULL;
45702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
45802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
45902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
46002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
46102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstruct put_image_params {
46202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int format;
46302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short dst_x;
46402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short dst_y;
46502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short dst_w;
46602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short dst_h;
46702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short src_w;
46802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short src_scan_h;
46902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short src_scan_w;
47002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short src_h;
47102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short stride_Y;
47202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	short stride_UV;
47302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int offset_Y;
47402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int offset_U;
47502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int offset_V;
47602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter};
47702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
47802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int packed_depth_bytes(u32 format)
47902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
48002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (format & I915_OVERLAY_DEPTH_MASK) {
481722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV422:
482722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 4;
483722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV411:
484722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* return 6; not implemented */
485722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
486722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
48702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
48802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
48902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
49002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int packed_width_bytes(u32 format, short width)
49102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
49202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (format & I915_OVERLAY_DEPTH_MASK) {
493722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV422:
494722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return width << 1;
495722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
496722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
49702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
49802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
49902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
50002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int uv_hsubsampling(u32 format)
50102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
50202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (format & I915_OVERLAY_DEPTH_MASK) {
503722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV422:
504722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV420:
505722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 2;
506722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV411:
507722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV410:
508722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 4;
509722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
510722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
51102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
51202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
51302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
51402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int uv_vsubsampling(u32 format)
51502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
51602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (format & I915_OVERLAY_DEPTH_MASK) {
517722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV420:
518722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV410:
519722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 2;
520722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV422:
521722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV411:
522722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return 1;
523722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
524722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
52502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
52602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
52702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
52802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
52902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
53002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 mask, shift, ret;
53102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (IS_I9XX(dev)) {
53202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mask = 0x3f;
53302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		shift = 6;
53402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else {
53502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mask = 0x1f;
53602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		shift = 5;
53702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
53802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = ((offset + width + mask) >> shift) - (offset >> shift);
53902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (IS_I9XX(dev))
54002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret <<= 1;
54102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret -=1;
54202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return ret << 2;
54302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
54402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
54502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
54602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
54702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
54802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
54902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
55002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
55102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
55202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
55302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
55402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
55502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
55602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
55702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
55802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
55902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
56002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
56102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
562722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	0xb000, 0x3000, 0x0800, 0x3000, 0xb000
563722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson};
564722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
56502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
56602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
56702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
56802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
56902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
57002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
57102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
57202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
57302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
574722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	0x3000, 0x0800, 0x3000
575722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson};
57602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
57702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_polyphase_filter(struct overlay_registers *regs)
57802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
57902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
58002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
58102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
58202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
58302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool update_scaling_factors(struct intel_overlay *overlay,
58402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				   struct overlay_registers *regs,
58502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				   struct put_image_params *params)
58602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
58702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* fixed point with a 12 bit shift */
58802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 xscale, yscale, xscale_UV, yscale_UV;
58902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define FP_SHIFT 12
59002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define FRACT_MASK 0xfff
59102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	bool scale_changed = false;
59202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int uv_hscale = uv_hsubsampling(params->format);
59302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int uv_vscale = uv_vsubsampling(params->format);
59402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
59502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->dst_w > 1)
59602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		xscale = ((params->src_scan_w - 1) << FP_SHIFT)
59702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			/(params->dst_w);
59802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	else
59902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		xscale = 1 << FP_SHIFT;
60002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
60102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->dst_h > 1)
60202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		yscale = ((params->src_scan_h - 1) << FP_SHIFT)
60302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			/(params->dst_h);
60402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	else
60502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		yscale = 1 << FP_SHIFT;
60602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
60702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
608722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	xscale_UV = xscale/uv_hscale;
609722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	yscale_UV = yscale/uv_vscale;
610722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	/* make the Y scale to UV scale ratio an exact multiply */
611722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	xscale = xscale_UV * uv_hscale;
612722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	yscale = yscale_UV * uv_vscale;
61302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/*} else {
614722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	  xscale_UV = 0;
615722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	  yscale_UV = 0;
616722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	  }*/
61702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
61802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
61902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		scale_changed = true;
62002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->old_xscale = xscale;
62102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->old_yscale = yscale;
62202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
623722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) |
624722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			   ((xscale >> FP_SHIFT)  << 16) |
625722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			   ((xscale & FRACT_MASK) << 3));
626722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
627722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) |
628722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			 ((xscale_UV >> FP_SHIFT)  << 16) |
629722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			 ((xscale_UV & FRACT_MASK) << 3));
630722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
631722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	regs->UVSCALEV = ((((yscale    >> FP_SHIFT) << 16) |
632722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			   ((yscale_UV >> FP_SHIFT) << 0)));
63302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
63402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (scale_changed)
63502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		update_polyphase_filter(regs);
63602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
63702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return scale_changed;
63802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
63902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
64002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_colorkey(struct intel_overlay *overlay,
64102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			    struct overlay_registers *regs)
64202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
64302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 key = overlay->color_key;
6446ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson
64502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (overlay->crtc->base.fb->bits_per_pixel) {
646722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case 8:
647722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		regs->DCLRKV = 0;
648722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
6496ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson		break;
6506ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson
651722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case 16:
652722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (overlay->crtc->base.fb->depth == 15) {
653722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			regs->DCLRKV = RGB15_TO_COLORKEY(key);
654722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
655722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		} else {
656722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			regs->DCLRKV = RGB16_TO_COLORKEY(key);
657722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
658722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		}
6596ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson		break;
6606ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson
661722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case 24:
662722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case 32:
663722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		regs->DCLRKV = key;
664722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
6656ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson		break;
66602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
66702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
66802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
66902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic u32 overlay_cmd_reg(struct put_image_params *params)
67002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
67102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
67202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
67302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->format & I915_OVERLAY_YUV_PLANAR) {
67402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
675722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV422:
676722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_422_PLANAR;
677722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
678722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV420:
679722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_420_PLANAR;
680722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
681722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV411:
682722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV410:
683722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_410_PLANAR;
684722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
68502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
68602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else { /* YUV packed */
68702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
688722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV422:
689722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_422_PACKED;
690722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
691722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_YUV411:
692722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_YUV_411_PACKED;
693722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
69402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
69502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
69602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		switch (params->format & I915_OVERLAY_SWAP_MASK) {
697722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_NO_SWAP:
698722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
699722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_UV_SWAP:
700722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_UV_SWAP;
701722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
702722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_Y_SWAP:
703722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_Y_SWAP;
704722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
705722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		case I915_OVERLAY_Y_AND_UV_SWAP:
706722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			cmd |= OCMD_Y_AND_UV_SWAP;
707722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			break;
70802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
70902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
71002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
71102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return cmd;
71202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
71302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
71402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_do_put_image(struct intel_overlay *overlay,
71502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			       struct drm_gem_object *new_bo,
71602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			       struct put_image_params *params)
71702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
71802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret, tmp_width;
71902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct overlay_registers *regs;
72002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	bool scale_changed = false;
72123010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter	struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo);
72202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
72302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
72402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
72502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
72602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!overlay);
72702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
72802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = intel_overlay_release_old_vid(overlay);
72902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
73002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
73102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
73202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = i915_gem_object_pin(new_bo, PAGE_SIZE);
73302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
73402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
73502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
73602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = i915_gem_object_set_to_gtt_domain(new_bo, 0);
73702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
73802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unpin;
73902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
74002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay->active) {
7418d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson		regs = intel_overlay_map_regs(overlay);
74202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (!regs) {
74302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			ret = -ENOMEM;
74402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unpin;
74502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
74602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OCONFIG = OCONF_CC_OUT_8BIT;
74702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (IS_I965GM(overlay->dev))
74802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
74902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
75002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			OCONF_PIPE_A : OCONF_PIPE_B;
7519bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson		intel_overlay_unmap_regs(overlay, regs);
75202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
75302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = intel_overlay_on(overlay);
75402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (ret != 0)
75502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unpin;
75602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
75702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
7588d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	regs = intel_overlay_map_regs(overlay);
75902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!regs) {
76002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = -ENOMEM;
76102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unpin;
76202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
76302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
76402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
76502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
76602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
76702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->format & I915_OVERLAY_YUV_PACKED)
76802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		tmp_width = packed_width_bytes(params->format, params->src_w);
76902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	else
77002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		tmp_width = params->src_w;
77102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
77202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->SWIDTH = params->src_w;
77302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->SWIDTHSW = calc_swidthsw(overlay->dev,
774722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				       params->offset_Y, tmp_width);
77502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->SHEIGHT = params->src_h;
77602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y;
77702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OSTRIDE = params->stride_Y;
77802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
77902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (params->format & I915_OVERLAY_YUV_PLANAR) {
78002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		int uv_hscale = uv_hsubsampling(params->format);
78102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		int uv_vscale = uv_vsubsampling(params->format);
78202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		u32 tmp_U, tmp_V;
78302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
78402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
785722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				      params->src_w/uv_hscale);
78602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
787722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				      params->src_w/uv_hscale);
78802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
78902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
79002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U;
79102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OBUF_0V = bo_priv->gtt_offset + params->offset_V;
79202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		regs->OSTRIDE |= params->stride_UV << 16;
79302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
79402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
79502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	scale_changed = update_scaling_factors(overlay, regs, params);
79602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
79702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	update_colorkey(overlay, regs);
79802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
79902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OCMD = overlay_cmd_reg(params);
80002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
8019bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	intel_overlay_unmap_regs(overlay, regs);
80202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
80302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	intel_overlay_continue(overlay, scale_changed);
80402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
80502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->old_vid_bo = overlay->vid_bo;
80623010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter	overlay->vid_bo = to_intel_bo(new_bo);
80702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
80802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
80902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
81002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unpin:
81102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	i915_gem_object_unpin(new_bo);
81202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return ret;
81302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
81402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
81502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_switch_off(struct intel_overlay *overlay)
81602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
81702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
81802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct overlay_registers *regs;
81902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
82002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
82102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
82202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
82302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
8249bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter	if (overlay->hw_wedged) {
8259bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter		ret = intel_overlay_recover_from_interrupt(overlay, 1);
8269bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter		if (ret != 0)
8279bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter			return ret;
8289bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter	}
8299bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter
83002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay->active)
83102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return 0;
83202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
83302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = intel_overlay_release_old_vid(overlay);
83402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
83502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
83602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
8378d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	regs = intel_overlay_map_regs(overlay);
83802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OCMD = 0;
8399bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	intel_overlay_unmap_regs(overlay, regs);
84002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
84102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = intel_overlay_off(overlay);
84203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (ret != 0)
84303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		return ret;
84403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
84512ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter	intel_overlay_off_tail(overlay);
84602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
84702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
84802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
84902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
85002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
85102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter					  struct intel_crtc *crtc)
85202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
853722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
85402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 pipeconf;
85502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF;
85602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
85702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON)
85802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
85902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
86002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	pipeconf = I915_READ(pipeconf_reg);
86102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
86202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* can't use the overlay with double wide pipe */
86302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!IS_I965G(overlay->dev) && pipeconf & PIPEACONF_DOUBLE_WIDE)
86402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
86502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
86602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
86702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
86802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
86902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_pfit_vscale_ratio(struct intel_overlay *overlay)
87002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
87102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_device *dev = overlay->dev;
872722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
87302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 pfit_control = I915_READ(PFIT_CONTROL);
874446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	u32 ratio;
87502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
87602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* XXX: This is not the same logic as in the xorg driver, but more in
877446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	 * line with the intel documentation for the i965
878446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	 */
879446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	if (!IS_I965G(dev)) {
880446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson		if (pfit_control & VERT_AUTO_SCALE)
881446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson			ratio = I915_READ(PFIT_AUTO_RATIOS);
88202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		else
883446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson			ratio = I915_READ(PFIT_PGM_RATIOS);
884446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson		ratio >>= PFIT_VERT_SCALE_SHIFT;
885446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson	} else { /* on i965 use the PGM reg to read out the autoscaler values */
886446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson		ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
88702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
88802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
88902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->pfit_vscale_ratio = ratio;
89002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
89102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
89202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_dst(struct intel_overlay *overlay,
89302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			     struct drm_intel_overlay_put_image *rec)
89402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
89502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_display_mode *mode = &overlay->crtc->base.mode;
89602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
897722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	if (rec->dst_x < mode->crtc_hdisplay &&
898722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    rec->dst_x + rec->dst_width <= mode->crtc_hdisplay &&
899722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    rec->dst_y < mode->crtc_vdisplay &&
900722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    rec->dst_y + rec->dst_height <= mode->crtc_vdisplay)
90102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return 0;
90202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	else
90302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
90402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
90502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
90602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_scaling(struct put_image_params *rec)
90702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
90802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	u32 tmp;
90902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
91002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* downscaling limit is 8.0 */
91102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
91202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (tmp > 7)
91302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
91402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
91502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (tmp > 7)
91602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
91702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
91802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
91902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
92002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
92102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_src(struct drm_device *dev,
92202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			     struct drm_intel_overlay_put_image *rec,
92302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			     struct drm_gem_object *new_bo)
92402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
92502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int uv_hscale = uv_hsubsampling(rec->flags);
92602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int uv_vscale = uv_vsubsampling(rec->flags);
9279f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson	u32 stride_mask, depth, tmp;
92802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
92902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* check src dimensions */
93002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (IS_845G(dev) || IS_I830(dev)) {
931722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
9329f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
93302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return -EINVAL;
93402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else {
935722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->src_height > IMAGE_MAX_HEIGHT ||
9369f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		    rec->src_width  > IMAGE_MAX_WIDTH)
93702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return -EINVAL;
93802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
9399f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
94002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* better safe than sorry, use 4 as the maximal subsampling ratio */
941722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	if (rec->src_height < N_VERT_Y_TAPS*4 ||
9429f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson	    rec->src_width  < N_HORIZ_Y_TAPS*4)
94302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
94402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
945a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson	/* check alignment constraints */
94602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
947722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_RGB:
948722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* not implemented */
949722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
9509f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
951722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV_PACKED:
952722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (uv_vscale != 1)
95302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return -EINVAL;
9549f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
9559f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		depth = packed_depth_bytes(rec->flags);
956722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (depth < 0)
957722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return depth;
9589f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
959722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* ignore UV planes */
960722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		rec->stride_UV = 0;
961722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		rec->offset_U = 0;
962722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		rec->offset_V = 0;
963722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* check pixel alignment */
964722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->offset_Y % depth)
965722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
966722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
9679f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
968722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV_PLANAR:
969722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (uv_vscale < 0 || uv_hscale < 0)
97002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return -EINVAL;
971722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* no offset restrictions for planar formats */
972722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
9739f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
974722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	default:
975722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		return -EINVAL;
97602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
97702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
97802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (rec->src_width % uv_hscale)
97902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
98002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
98102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* stride checking */
982a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson	if (IS_I830(dev) || IS_845G(dev))
983a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson		stride_mask = 255;
984a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson	else
985a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson		stride_mask = 63;
98602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
98702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
98802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
98902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (IS_I965G(dev) && rec->stride_Y < 512)
99002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
99102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
99202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
9939f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		4096 : 8192;
9949f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson	if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
99502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
99602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
99702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* check buffer dimensions */
99802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
999722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_RGB:
1000722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV_PACKED:
1001722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		/* always 4 Y values per depth pixels */
1002722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1003722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
1004722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
1005722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		tmp = rec->stride_Y*rec->src_height;
1006722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->offset_Y + tmp > new_bo->size)
1007722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
1008722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
1009722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
1010722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	case I915_OVERLAY_YUV_PLANAR:
1011722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->src_width > rec->stride_Y)
1012722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
1013722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->src_width/uv_hscale > rec->stride_UV)
1014722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
1015722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
10169f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		tmp = rec->stride_Y * rec->src_height;
1017722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->offset_Y + tmp > new_bo->size)
1018722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
10199f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson
10209f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson		tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1021722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (rec->offset_U + tmp > new_bo->size ||
1022722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		    rec->offset_V + tmp > new_bo->size)
1023722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson			return -EINVAL;
1024722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		break;
102502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
102602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
102702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
102802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
102902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
103002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_put_image(struct drm_device *dev, void *data,
103102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                            struct drm_file *file_priv)
103202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
103302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_intel_overlay_put_image *put_image_rec = data;
103402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	drm_i915_private_t *dev_priv = dev->dev_private;
103502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct intel_overlay *overlay;
103602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_mode_object *drmmode_obj;
103702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct intel_crtc *crtc;
103802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_gem_object *new_bo;
103902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct put_image_params *params;
104002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
104102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
104202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!dev_priv) {
104302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_ERROR("called with no initialization\n");
104402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
104502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
104602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
104702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay = dev_priv->overlay;
104802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay) {
104902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_DEBUG("userspace bug: no overlay\n");
105002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -ENODEV;
105102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
105202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
105302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
105402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mutex_lock(&dev->mode_config.mutex);
105502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mutex_lock(&dev->struct_mutex);
105602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
105702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = intel_overlay_switch_off(overlay);
105802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
105902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mutex_unlock(&dev->struct_mutex);
106002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		mutex_unlock(&dev->mode_config.mutex);
106102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
106202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return ret;
106302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
106402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
106502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
106602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!params)
106702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -ENOMEM;
106802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
106902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
1070722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson					   DRM_MODE_OBJECT_CRTC);
1071915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter	if (!drmmode_obj) {
1072915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter		ret = -ENOENT;
1073915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter		goto out_free;
1074915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter	}
107502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
107602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
107702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	new_bo = drm_gem_object_lookup(dev, file_priv,
1078722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				       put_image_rec->bo_handle);
1079915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter	if (!new_bo) {
1080915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter		ret = -ENOENT;
1081915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter		goto out_free;
1082915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter	}
108302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
108402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_lock(&dev->mode_config.mutex);
108502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_lock(&dev->struct_mutex);
108602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
108703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	if (overlay->hw_wedged) {
108803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		ret = intel_overlay_recover_from_interrupt(overlay, 1);
108903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter		if (ret != 0)
109003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter			goto out_unlock;
109103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter	}
109203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter
109302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (overlay->crtc != crtc) {
109402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		struct drm_display_mode *mode = &crtc->base.mode;
109502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = intel_overlay_switch_off(overlay);
109602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (ret != 0)
109702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
109802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
109902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = check_overlay_possible_on_crtc(overlay, crtc);
110002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (ret != 0)
110102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
110202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
110302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		overlay->crtc = crtc;
110402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		crtc->overlay = overlay;
110502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
110602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (intel_panel_fitter_pipe(dev) == crtc->pipe
110702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		    /* and line to wide, i.e. one-line-mode */
110802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		    && mode->hdisplay > 1024) {
110902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			overlay->pfit_active = 1;
111002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			update_pfit_vscale_ratio(overlay);
111102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		} else
111202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			overlay->pfit_active = 0;
111302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
111402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
111502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = check_overlay_dst(overlay, put_image_rec);
111602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
111702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
111802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
111902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (overlay->pfit_active) {
112002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1121722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				 overlay->pfit_vscale_ratio);
112202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		/* shifting right rounds downwards, so add 1 */
112302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1124722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson				 overlay->pfit_vscale_ratio) + 1;
112502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else {
112602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		params->dst_y = put_image_rec->dst_y;
112702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		params->dst_h = put_image_rec->dst_height;
112802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
112902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->dst_x = put_image_rec->dst_x;
113002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->dst_w = put_image_rec->dst_width;
113102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
113202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->src_w = put_image_rec->src_width;
113302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->src_h = put_image_rec->src_height;
113402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->src_scan_w = put_image_rec->src_scan_width;
113502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->src_scan_h = put_image_rec->src_scan_height;
1136722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	if (params->src_scan_h > params->src_h ||
1137722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    params->src_scan_w > params->src_w) {
113802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = -EINVAL;
113902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
114002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
114102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
114202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = check_overlay_src(dev, put_image_rec, new_bo);
114302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
114402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
114502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
114602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->stride_Y = put_image_rec->stride_Y;
114702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->stride_UV = put_image_rec->stride_UV;
114802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->offset_Y = put_image_rec->offset_Y;
114902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->offset_U = put_image_rec->offset_U;
115002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	params->offset_V = put_image_rec->offset_V;
115102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
115202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* Check scaling after src size to prevent a divide-by-zero. */
115302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = check_overlay_scaling(params);
115402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
115502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
115602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
115702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	ret = intel_overlay_do_put_image(overlay, new_bo, params);
115802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (ret != 0)
115902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_unlock;
116002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
116102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->struct_mutex);
116202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->mode_config.mutex);
116302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
116402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	kfree(params);
116502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
116602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
116702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
116802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unlock:
116902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->struct_mutex);
117002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->mode_config.mutex);
1171bc9025bdc4e2b591734cca17697093845007b63dLuca Barbieri	drm_gem_object_unreference_unlocked(new_bo);
1172915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenterout_free:
117302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	kfree(params);
117402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
117502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return ret;
117602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
117702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
117802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_reg_attrs(struct intel_overlay *overlay,
117902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			     struct overlay_registers *regs)
118002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
118102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
118202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	regs->OCLRC1 = overlay->saturation;
118302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
118402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
118502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool check_gamma_bounds(u32 gamma1, u32 gamma2)
118602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
118702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int i;
118802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
118902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
119002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return false;
119102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
119202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	for (i = 0; i < 3; i++) {
1193722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson		if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
119402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return false;
119502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
119602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
119702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return true;
119802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
119902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
120002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool check_gamma5_errata(u32 gamma5)
120102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
120202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int i;
120302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
120402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	for (i = 0; i < 3; i++) {
120502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (((gamma5 >> i*8) & 0xff) == 0x80)
120602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			return false;
120702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
120802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
120902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return true;
121002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
121102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
121202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_gamma(struct drm_intel_overlay_attrs *attrs)
121302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
1214722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	if (!check_gamma_bounds(0, attrs->gamma0) ||
1215722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1216722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1217722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1218722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1219722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1220722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	    !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
122102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
1222722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
122302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!check_gamma5_errata(attrs->gamma5))
122402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
1225722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson
122602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return 0;
122702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
122802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
122902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_attrs(struct drm_device *dev, void *data,
123002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                        struct drm_file *file_priv)
123102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
123202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_intel_overlay_attrs *attrs = data;
123302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter        drm_i915_private_t *dev_priv = dev->dev_private;
123402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct intel_overlay *overlay;
123502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct overlay_registers *regs;
123602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
123702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
123802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!dev_priv) {
123902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_ERROR("called with no initialization\n");
124002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -EINVAL;
124102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
124202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
124302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay = dev_priv->overlay;
124402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay) {
124502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		DRM_DEBUG("userspace bug: no overlay\n");
124602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return -ENODEV;
124702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
124802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
124902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_lock(&dev->mode_config.mutex);
125002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_lock(&dev->struct_mutex);
125102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
125260fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson	ret = -EINVAL;
125302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
125460fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		attrs->color_key  = overlay->color_key;
125502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		attrs->brightness = overlay->brightness;
125660fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		attrs->contrast   = overlay->contrast;
125702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		attrs->saturation = overlay->saturation;
125802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
125902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (IS_I9XX(dev)) {
126002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma0 = I915_READ(OGAMC0);
126102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma1 = I915_READ(OGAMC1);
126202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma2 = I915_READ(OGAMC2);
126302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma3 = I915_READ(OGAMC3);
126402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma4 = I915_READ(OGAMC4);
126502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			attrs->gamma5 = I915_READ(OGAMC5);
126602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
126702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	} else {
126860fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		if (attrs->brightness < -128 || attrs->brightness > 127)
126902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
127060fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		if (attrs->contrast > 255)
127102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
127260fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		if (attrs->saturation > 1023)
127302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
127460fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson
127560fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		overlay->color_key  = attrs->color_key;
127660fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		overlay->brightness = attrs->brightness;
127760fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		overlay->contrast   = attrs->contrast;
127860fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson		overlay->saturation = attrs->saturation;
127902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
12808d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson		regs = intel_overlay_map_regs(overlay);
128102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (!regs) {
128202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			ret = -ENOMEM;
128302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			goto out_unlock;
128402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
128502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
128602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		update_reg_attrs(overlay, regs);
128702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
12889bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson		intel_overlay_unmap_regs(overlay, regs);
128902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
129002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
129160fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson			if (!IS_I9XX(dev))
129202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				goto out_unlock;
129302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
129402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			if (overlay->active) {
129502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				ret = -EBUSY;
129602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				goto out_unlock;
129702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			}
129802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
129902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			ret = check_gamma(attrs);
130060fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson			if (ret)
130102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter				goto out_unlock;
130202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
130302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC0, attrs->gamma0);
130402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC1, attrs->gamma1);
130502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC2, attrs->gamma2);
130602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC3, attrs->gamma3);
130702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC4, attrs->gamma4);
130802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter			I915_WRITE(OGAMC5, attrs->gamma5);
130902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		}
131002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
131102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
131260fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson	ret = 0;
131302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unlock:
131402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->struct_mutex);
131502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	mutex_unlock(&dev->mode_config.mutex);
131602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
131702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return ret;
131802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
131902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
132002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vettervoid intel_setup_overlay(struct drm_device *dev)
132102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
132202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter        drm_i915_private_t *dev_priv = dev->dev_private;
132302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct intel_overlay *overlay;
132402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct drm_gem_object *reg_bo;
132502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	struct overlay_registers *regs;
132602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	int ret;
132702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
132831578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	if (!HAS_OVERLAY(dev))
132902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return;
133002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
133102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
133202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!overlay)
133302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		return;
133402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->dev = dev;
133502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
1336ac52bc56de25535a907ef07f8755f1387b89b0f5Daniel Vetter	reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
133702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!reg_bo)
133802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_free;
133923010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter	overlay->reg_bo = to_intel_bo(reg_bo);
134002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
134131578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	if (OVERLAY_NEEDS_PHYSICAL(dev)) {
134231578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson		ret = i915_gem_attach_phys_object(dev, reg_bo,
134331578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson						  I915_GEM_PHYS_OVERLAY_REGS,
1344a29301288f1840bdf9c5456da9cd7c944436edd5Chris Wilson						  PAGE_SIZE);
134531578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson                if (ret) {
134631578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson                        DRM_ERROR("failed to attach phys overlay regs\n");
134731578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson                        goto out_free_bo;
134831578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson                }
134931578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson		overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr;
135031578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	} else {
135102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
135202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		if (ret) {
135302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                        DRM_ERROR("failed to pin overlay register bo\n");
135402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                        goto out_free_bo;
135502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter                }
135602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		overlay->flip_addr = overlay->reg_bo->gtt_offset;
13570ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson
13580ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson		ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
13590ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson		if (ret) {
13600ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson                        DRM_ERROR("failed to move overlay register bo into the GTT\n");
13610ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson                        goto out_unpin_bo;
13620ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson                }
136302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	}
136402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
136502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	/* init all values */
136602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->color_key = 0x0101fe;
136702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->brightness = -19;
136802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->contrast = 75;
136902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	overlay->saturation = 146;
137002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
13718d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	regs = intel_overlay_map_regs(overlay);
137202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	if (!regs)
137302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter		goto out_free_bo;
137402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
137502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	memset(regs, 0, sizeof(struct overlay_registers));
137602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	update_polyphase_filter(regs);
137702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	update_reg_attrs(overlay, regs);
137802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
13799bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	intel_overlay_unmap_regs(overlay, regs);
138002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
138102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	dev_priv->overlay = overlay;
138202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	DRM_INFO("initialized overlay support\n");
138302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return;
138402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
13850ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilsonout_unpin_bo:
13860ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson	i915_gem_object_unpin(reg_bo);
138702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_free_bo:
138802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	drm_gem_object_unreference(reg_bo);
138902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_free:
139002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	kfree(overlay);
139102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter	return;
139202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
139302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
139402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vettervoid intel_cleanup_overlay(struct drm_device *dev)
139502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{
1396722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
139702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
139862cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	if (!dev_priv->overlay)
139962cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson		return;
140002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter
140162cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	/* The bo's should be free'd by the generic code already.
140262cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	 * Furthermore modesetting teardown happens beforehand so the
140362cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	 * hardware should be off already */
140462cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	BUG_ON(dev_priv->overlay->active);
140562cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson
140662cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
140762cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson	kfree(dev_priv->overlay);
140802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}
14096ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14106ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonstruct intel_overlay_error_state {
14116ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	struct overlay_registers regs;
14126ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	unsigned long base;
14136ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	u32 dovsta;
14146ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	u32 isr;
14156ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson};
14166ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14176ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonstruct intel_overlay_error_state *
14186ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonintel_overlay_capture_error_state(struct drm_device *dev)
14196ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson{
14206ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson        drm_i915_private_t *dev_priv = dev->dev_private;
14216ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	struct intel_overlay *overlay = dev_priv->overlay;
14226ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	struct intel_overlay_error_state *error;
14236ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	struct overlay_registers __iomem *regs;
14246ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14256ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	if (!overlay || !overlay->active)
14266ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		return NULL;
14276ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14286ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	error = kmalloc(sizeof(*error), GFP_ATOMIC);
14296ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	if (error == NULL)
14306ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		return NULL;
14316ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14326ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	error->dovsta = I915_READ(DOVSTA);
14336ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	error->isr = I915_READ(ISR);
143431578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
14356ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
143631578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson	else
143731578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson		error->base = (long) overlay->reg_bo->gtt_offset;
14386ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14398d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson	regs = intel_overlay_map_regs_atomic(overlay, KM_IRQ0);
14406ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	if (!regs)
14416ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		goto err;
14426ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14436ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
14449bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson	intel_overlay_unmap_regs_atomic(overlay, KM_IRQ0, regs);
14456ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14466ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	return error;
14476ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14486ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonerr:
14496ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	kfree(error);
14506ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	return NULL;
14516ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson}
14526ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14536ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonvoid
14546ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonintel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
14556ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson{
14566ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
14576ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		   error->dovsta, error->isr);
14586ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	seq_printf(m, "  Register file at 0x%08lx:\n",
14596ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson		   error->base);
14606ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson
14616ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson#define P(x) seq_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
14626ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_0Y);
14636ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_1Y);
14646ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_0U);
14656ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_0V);
14666ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_1U);
14676ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OBUF_1V);
14686ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTRIDE);
14696ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(YRGB_VPH);
14706ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(UV_VPH);
14716ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(HORZ_PH);
14726ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(INIT_PHS);
14736ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(DWINPOS);
14746ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(DWINSZ);
14756ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SWIDTH);
14766ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SWIDTHSW);
14776ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SHEIGHT);
14786ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(YRGBSCALE);
14796ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(UVSCALE);
14806ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OCLRC0);
14816ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OCLRC1);
14826ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(DCLRKV);
14836ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(DCLRKM);
14846ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SCLRKVH);
14856ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SCLRKVL);
14866ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(SCLRKEN);
14876ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OCONFIG);
14886ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OCMD);
14896ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_0Y);
14906ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_1Y);
14916ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_0U);
14926ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_0V);
14936ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_1U);
14946ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OSTART_1V);
14956ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_0Y);
14966ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_1Y);
14976ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_0U);
14986ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_0V);
14996ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_1U);
15006ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(OTILEOFF_1V);
15016ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(FASTHSCALE);
15026ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson	P(UVSCALEV);
15036ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson#undef P
15046ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson}
1505