intel_overlay.c revision 23f09ce31ca68af3728ac5eed3e3efb03c5f990a
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 17323f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilsonstruct intel_overlay { 17423f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson struct drm_device *dev; 17523f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson struct intel_crtc *crtc; 17623f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson struct drm_i915_gem_object *vid_bo; 17723f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson struct drm_i915_gem_object *old_vid_bo; 17823f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson int active; 17923f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson int pfit_active; 18023f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */ 18123f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson u32 color_key; 18223f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson u32 brightness, contrast, saturation; 18323f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson u32 old_xscale, old_yscale; 18423f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson /* register access */ 18523f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson u32 flip_addr; 18623f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson struct drm_i915_gem_object *reg_bo; 18723f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson /* flip handling */ 18823f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson uint32_t last_flip_req; 18923f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson int hw_wedged; 19023f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson#define HW_WEDGED 1 19123f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson#define NEEDS_WAIT_FOR_FLIP 2 19223f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson#define RELEASE_OLD_VID 3 19323f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson#define SWITCH_OFF 4 19423f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson}; 19523f09ce31ca68af3728ac5eed3e3efb03c5f990aChris Wilson 1968d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonstatic struct overlay_registers * 1978d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonintel_overlay_map_regs_atomic(struct intel_overlay *overlay, 1988d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson int slot) 19902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 20002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = overlay->dev->dev_private; 20102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 20202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 2039bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) 20431578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson regs = overlay->reg_bo->phys_obj->handle->vaddr; 2059bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson else 20602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, 207fca3ec01e0b40cab82cac7745e154b01969e6219Chris Wilson overlay->reg_bo->gtt_offset, 2088d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson slot); 20902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 2109bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson return regs; 21102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 21202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 2138d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonstatic void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay, 2149bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson int slot, 2159bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson struct overlay_registers *regs) 21602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 21731578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev)) 2189bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson io_mapping_unmap_atomic(regs, slot); 2198d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson} 2208d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson 2218d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonstatic struct overlay_registers * 2228d74f656dd78ae1ba813389cd46197c6329696bcChris Wilsonintel_overlay_map_regs(struct intel_overlay *overlay) 2238d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson{ 2248d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson drm_i915_private_t *dev_priv = overlay->dev->dev_private; 2258d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson struct overlay_registers *regs; 2268d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson 2279bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) 2288d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson regs = overlay->reg_bo->phys_obj->handle->vaddr; 2299bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson else 2308d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping, 2318d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson overlay->reg_bo->gtt_offset); 2328d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson 2339bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson return regs; 2348d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson} 2358d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson 2369bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilsonstatic void intel_overlay_unmap_regs(struct intel_overlay *overlay, 2379bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson struct overlay_registers *regs) 2388d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson{ 2398d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev)) 2409bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson io_mapping_unmap(regs); 24102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 24202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 243b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilsonstatic int intel_overlay_do_wait_request(struct intel_overlay *overlay, 2448dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson struct drm_i915_gem_request *request, 245b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson bool interruptible, 246b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson int stage) 24702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 24802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 249852835f343146a82a528c3b712b373661d4fa17aZou Nan hai drm_i915_private_t *dev_priv = dev->dev_private; 250b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson int ret; 25102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 252852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req = 2538dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson i915_add_request(dev, NULL, request, &dev_priv->render_ring); 25403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->last_flip_req == 0) 25503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return -ENOMEM; 25602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 257b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson overlay->hw_wedged = stage; 258852835f343146a82a528c3b712b373661d4fa17aZou Nan hai ret = i915_do_wait_request(dev, 259722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson overlay->last_flip_req, true, 260722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson &dev_priv->render_ring); 261b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson if (ret) 26203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return ret; 26302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 26403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = 0; 26503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->last_flip_req = 0; 26602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 26702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 26802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 269106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson/* Workaround for i830 bug where pipe a must be enable to change control regs */ 270106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilsonstatic int 271106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilsoni830_activate_pipe_a(struct drm_device *dev) 272106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson{ 273106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson drm_i915_private_t *dev_priv = dev->dev_private; 274106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson struct intel_crtc *crtc; 275106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson struct drm_crtc_helper_funcs *crtc_funcs; 276106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson struct drm_display_mode vesa_640x480 = { 277106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, 278106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 752, 800, 0, 480, 489, 492, 525, 0, 279106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) 280106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson }, *mode; 281106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 282106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]); 283106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson if (crtc->dpms_mode == DRM_MODE_DPMS_ON) 284106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson return 0; 285106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 286106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson /* most i8xx have pipe a forced on, so don't trust dpms mode */ 287106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson if (I915_READ(PIPEACONF) & PIPEACONF_ENABLE) 288106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson return 0; 289106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 290106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson crtc_funcs = crtc->base.helper_private; 291106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson if (crtc_funcs->dpms == NULL) 292106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson return 0; 293106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 294106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n"); 295106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 296106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson mode = drm_mode_duplicate(dev, &vesa_640x480); 297106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 298106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson if(!drm_crtc_helper_set_mode(&crtc->base, mode, 299106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson crtc->base.x, crtc->base.y, 300106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson crtc->base.fb)) 301106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson return 0; 302106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 303106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON); 304106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson return 1; 305106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson} 306106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 307106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilsonstatic void 308106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilsoni830_deactivate_pipe_a(struct drm_device *dev) 309106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson{ 310106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson drm_i915_private_t *dev_priv = dev->dev_private; 311106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0]; 312106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 313106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 314106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); 315106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson} 316106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 317b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson/* overlay needs to be disable in OCMD reg */ 318b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilsonstatic int intel_overlay_on(struct intel_overlay *overlay) 319b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson{ 320b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson struct drm_device *dev = overlay->dev; 3218dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson struct drm_i915_gem_request *request; 322106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson int pipe_a_quirk = 0; 323106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson int ret; 324b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson 325b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson BUG_ON(overlay->active); 326b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson overlay->active = 1; 327b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson 328106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson if (IS_I830(dev)) { 329106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson pipe_a_quirk = i830_activate_pipe_a(dev); 330106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson if (pipe_a_quirk < 0) 331106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson return pipe_a_quirk; 332106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson } 333106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 3348dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson request = kzalloc(sizeof(*request), GFP_KERNEL); 335106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson if (request == NULL) { 336106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson ret = -ENOMEM; 337106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson goto out; 338106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson } 3398dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson 340b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson BEGIN_LP_RING(4); 341b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); 342b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson OUT_RING(overlay->flip_addr | OFC_UPDATE); 343b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 344b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson OUT_RING(MI_NOOP); 345b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson ADVANCE_LP_RING(); 346b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson 347106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson ret = intel_overlay_do_wait_request(overlay, request, true, 348106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson NEEDS_WAIT_FOR_FLIP); 349106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilsonout: 350106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson if (pipe_a_quirk) 351106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson i830_deactivate_pipe_a(dev); 352106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson 353106dadacbeeea92f61a2c32f3651ee31c1b34e31Chris Wilson return ret; 354b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson} 355b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson 35602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay needs to be enabled in OCMD reg */ 3578dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilsonstatic int intel_overlay_continue(struct intel_overlay *overlay, 3588dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson bool load_polyphase_filter) 35902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 36002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 36102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 3628dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson struct drm_i915_gem_request *request; 36302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 flip_addr = overlay->flip_addr; 36402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 tmp; 36502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 36602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!overlay->active); 36702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 3688dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson request = kzalloc(sizeof(*request), GFP_KERNEL); 3698dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson if (request == NULL) 3708dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson return -ENOMEM; 3718dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson 37202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (load_polyphase_filter) 37302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter flip_addr |= OFC_UPDATE; 37402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 37502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* check for underruns */ 37602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = I915_READ(DOVSTA); 37702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (tmp & (1 << 17)) 37802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); 37902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 3804f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter BEGIN_LP_RING(2); 38102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 38202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(flip_addr); 3835a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter ADVANCE_LP_RING(); 3845a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter 385852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req = 3868dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson i915_add_request(dev, NULL, request, &dev_priv->render_ring); 3878dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson return 0; 3885a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter} 3895a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter 39002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay needs to be disabled in OCMD reg */ 3915dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilsonstatic int intel_overlay_off(struct intel_overlay *overlay, 3925dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson bool interruptible) 39302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 39402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 3958dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson u32 flip_addr = overlay->flip_addr; 3968dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson struct drm_i915_gem_request *request; 39702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 39802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!overlay->active); 39902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 4008dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson request = kzalloc(sizeof(*request), GFP_KERNEL); 4018dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson if (request == NULL) 4028dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson return -ENOMEM; 4038dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson 40402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* According to intel docs the overlay hw may hang (when switching 40502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * off) without loading the filter coeffs. It is however unclear whether 40602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * this applies to the disabling of the overlay or to the switching off 40702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * of the hw. Do it in both cases */ 40802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter flip_addr |= OFC_UPDATE; 40902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 4108dfbc3403113bcc51f0350c3471fa1abf664305fChris Wilson BEGIN_LP_RING(6); 41102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* wait for overlay to go idle */ 41202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 41302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(flip_addr); 414722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 41502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* turn overlay off */ 416722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); 41702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(flip_addr); 418722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 41902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ADVANCE_LP_RING(); 42002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 4215dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson return intel_overlay_do_wait_request(overlay, request, interruptible, 4228dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson SWITCH_OFF); 42302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 42402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 4255cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilsonstatic void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) 4265cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson{ 4275cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson struct drm_gem_object *obj = &overlay->old_vid_bo->base; 4285cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson 4295cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson i915_gem_object_unpin(obj); 4305cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson drm_gem_object_unreference(obj); 4315cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson 4325cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson overlay->old_vid_bo = NULL; 4335cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson} 4345cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson 43512ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetterstatic void intel_overlay_off_tail(struct intel_overlay *overlay) 43612ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter{ 43712ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter struct drm_gem_object *obj; 43812ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter 43912ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter /* never have the overlay hw on without showing a frame */ 44012ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter BUG_ON(!overlay->vid_bo); 441a8089e849a32c5b6bfd6c88dbd09c0ea4a779b71Daniel Vetter obj = &overlay->vid_bo->base; 44212ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter 44312ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter i915_gem_object_unpin(obj); 44412ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter drm_gem_object_unreference(obj); 44512ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter overlay->vid_bo = NULL; 44612ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter 44712ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter overlay->crtc->overlay = NULL; 44812ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter overlay->crtc = NULL; 44912ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter overlay->active = 0; 45012ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter} 45112ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter 45203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter/* recover from an interruption due to a signal 45303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter * We have to be careful not to repeat work forever an make forward progess. */ 4545dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilsonstatic int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, 4555dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson bool interruptible) 45603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter{ 45703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter struct drm_device *dev = overlay->dev; 458852835f343146a82a528c3b712b373661d4fa17aZou Nan hai drm_i915_private_t *dev_priv = dev->dev_private; 45903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter int ret; 46003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 46103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->hw_wedged == HW_WEDGED) 46203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return -EIO; 46303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 464852835f343146a82a528c3b712b373661d4fa17aZou Nan hai ret = i915_do_wait_request(dev, overlay->last_flip_req, 465722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson interruptible, &dev_priv->render_ring); 466b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson if (ret) 46703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return ret; 46803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 46903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter switch (overlay->hw_wedged) { 470722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case RELEASE_OLD_VID: 4715cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson intel_overlay_release_old_vid_tail(overlay); 472722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 473b6c028e00445de9dfde2cd0c26521ac53965320aChris Wilson 4748dfbc3403113bcc51f0350c3471fa1abf664305fChris Wilson case SWITCH_OFF: 475722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson intel_overlay_off_tail(overlay); 476722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 4778dfbc3403113bcc51f0350c3471fa1abf664305fChris Wilson 478722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson default: 479722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP); 48003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter } 48103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 48203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = 0; 48303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->last_flip_req = 0; 48403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return 0; 48503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter} 48603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 4875a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter/* Wait for pending overlay flip and release old frame. 4885a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter * Needs to be called before the overlay register are changed 4898d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson * via intel_overlay_(un)map_regs 4908d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson */ 49102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int intel_overlay_release_old_vid(struct intel_overlay *overlay) 49202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 4935cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson struct drm_device *dev = overlay->dev; 4945cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson drm_i915_private_t *dev_priv = dev->dev_private; 49502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 49602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 4975cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson /* Only wait if there is actually an old frame to release to 4985cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson * guarantee forward progress. 4995cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson */ 50003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (!overlay->old_vid_bo) 50103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return 0; 50203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 5035cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { 5048dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson struct drm_i915_gem_request *request; 5058dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson 5065cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson /* synchronous slowpath */ 5078dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson request = kzalloc(sizeof(*request), GFP_KERNEL); 5088dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson if (request == NULL) 5098dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson return -ENOMEM; 5108dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson 5115cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson BEGIN_LP_RING(2); 5125cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 5135cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson OUT_RING(MI_NOOP); 5145cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson ADVANCE_LP_RING(); 5155cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson 5168dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson ret = intel_overlay_do_wait_request(overlay, request, true, 5175cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson RELEASE_OLD_VID); 5185cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson if (ret) 5195cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson return ret; 5205cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson } 52102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 5225cd68c9864d65e49c910c701716e4e94e09f7ce0Chris Wilson intel_overlay_release_old_vid_tail(overlay); 52302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 52402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 52502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 52602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstruct put_image_params { 52702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int format; 52802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short dst_x; 52902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short dst_y; 53002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short dst_w; 53102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short dst_h; 53202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short src_w; 53302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short src_scan_h; 53402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short src_scan_w; 53502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short src_h; 53602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short stride_Y; 53702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short stride_UV; 53802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int offset_Y; 53902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int offset_U; 54002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int offset_V; 54102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}; 54202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 54302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int packed_depth_bytes(u32 format) 54402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 54502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (format & I915_OVERLAY_DEPTH_MASK) { 546722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV422: 547722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return 4; 548722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV411: 549722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson /* return 6; not implemented */ 550722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson default: 551722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 55202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 55302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 55402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 55502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int packed_width_bytes(u32 format, short width) 55602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 55702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (format & I915_OVERLAY_DEPTH_MASK) { 558722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV422: 559722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return width << 1; 560722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson default: 561722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 56202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 56302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 56402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 56502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int uv_hsubsampling(u32 format) 56602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 56702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (format & I915_OVERLAY_DEPTH_MASK) { 568722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV422: 569722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV420: 570722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return 2; 571722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV411: 572722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV410: 573722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return 4; 574722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson default: 575722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 57602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 57702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 57802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 57902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int uv_vsubsampling(u32 format) 58002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 58102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (format & I915_OVERLAY_DEPTH_MASK) { 582722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV420: 583722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV410: 584722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return 2; 585722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV422: 586722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV411: 587722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return 1; 588722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson default: 589722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 59002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 59102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 59202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 59302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width) 59402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 59502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 mask, shift, ret; 59602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I9XX(dev)) { 59702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mask = 0x3f; 59802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter shift = 6; 59902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 60002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mask = 0x1f; 60102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter shift = 5; 60202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 60302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = ((offset + width + mask) >> shift) - (offset >> shift); 60402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I9XX(dev)) 60502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret <<= 1; 60602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret -=1; 60702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret << 2; 60802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 60902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 61002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = { 61102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0, 61202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb500, 0x19d0, 0x1880, 0xb440, 61302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0, 61402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380, 61502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320, 61602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0, 61702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260, 61802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200, 61902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0, 62002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160, 62102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120, 62202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0, 62302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0, 62402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060, 62502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040, 62602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020, 627722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 0xb000, 0x3000, 0x0800, 0x3000, 0xb000 628722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson}; 629722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 63002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = { 63102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60, 63202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40, 63302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880, 63402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00, 63502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0, 63602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0, 63702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240, 63802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0, 639722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 0x3000, 0x0800, 0x3000 640722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson}; 64102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 64202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_polyphase_filter(struct overlay_registers *regs) 64302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 64402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs)); 64502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs)); 64602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 64702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 64802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool update_scaling_factors(struct intel_overlay *overlay, 64902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs, 65002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct put_image_params *params) 65102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 65202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* fixed point with a 12 bit shift */ 65302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 xscale, yscale, xscale_UV, yscale_UV; 65402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define FP_SHIFT 12 65502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define FRACT_MASK 0xfff 65602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter bool scale_changed = false; 65702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_hscale = uv_hsubsampling(params->format); 65802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_vscale = uv_vsubsampling(params->format); 65902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 66002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->dst_w > 1) 66102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter xscale = ((params->src_scan_w - 1) << FP_SHIFT) 66202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /(params->dst_w); 66302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 66402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter xscale = 1 << FP_SHIFT; 66502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 66602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->dst_h > 1) 66702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter yscale = ((params->src_scan_h - 1) << FP_SHIFT) 66802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /(params->dst_h); 66902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 67002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter yscale = 1 << FP_SHIFT; 67102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 67202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/ 673722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson xscale_UV = xscale/uv_hscale; 674722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson yscale_UV = yscale/uv_vscale; 675722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson /* make the Y scale to UV scale ratio an exact multiply */ 676722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson xscale = xscale_UV * uv_hscale; 677722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson yscale = yscale_UV * uv_vscale; 67802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /*} else { 679722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson xscale_UV = 0; 680722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson yscale_UV = 0; 681722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson }*/ 68202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 68302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (xscale != overlay->old_xscale || yscale != overlay->old_yscale) 68402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter scale_changed = true; 68502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->old_xscale = xscale; 68602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->old_yscale = yscale; 68702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 688722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) | 689722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson ((xscale >> FP_SHIFT) << 16) | 690722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson ((xscale & FRACT_MASK) << 3)); 691722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 692722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) | 693722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson ((xscale_UV >> FP_SHIFT) << 16) | 694722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson ((xscale_UV & FRACT_MASK) << 3)); 695722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 696722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->UVSCALEV = ((((yscale >> FP_SHIFT) << 16) | 697722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson ((yscale_UV >> FP_SHIFT) << 0))); 69802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 69902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (scale_changed) 70002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_polyphase_filter(regs); 70102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 70202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return scale_changed; 70302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 70402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 70502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_colorkey(struct intel_overlay *overlay, 70602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs) 70702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 70802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 key = overlay->color_key; 7096ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson 71002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (overlay->crtc->base.fb->bits_per_pixel) { 711722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case 8: 712722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->DCLRKV = 0; 713722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE; 7146ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson break; 7156ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson 716722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case 16: 717722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (overlay->crtc->base.fb->depth == 15) { 718722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->DCLRKV = RGB15_TO_COLORKEY(key); 719722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE; 720722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson } else { 721722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->DCLRKV = RGB16_TO_COLORKEY(key); 722722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE; 723722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson } 7246ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson break; 7256ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson 726722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case 24: 727722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case 32: 728722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->DCLRKV = key; 729722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE; 7306ba3ddd9838f5e4d6ac7c6dce95648d205e11bffChris Wilson break; 73102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 73202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 73302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 73402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic u32 overlay_cmd_reg(struct put_image_params *params) 73502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 73602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0; 73702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 73802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->format & I915_OVERLAY_YUV_PLANAR) { 73902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (params->format & I915_OVERLAY_DEPTH_MASK) { 740722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV422: 741722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson cmd |= OCMD_YUV_422_PLANAR; 742722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 743722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV420: 744722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson cmd |= OCMD_YUV_420_PLANAR; 745722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 746722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV411: 747722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV410: 748722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson cmd |= OCMD_YUV_410_PLANAR; 749722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 75002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 75102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { /* YUV packed */ 75202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (params->format & I915_OVERLAY_DEPTH_MASK) { 753722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV422: 754722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson cmd |= OCMD_YUV_422_PACKED; 755722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 756722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV411: 757722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson cmd |= OCMD_YUV_411_PACKED; 758722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 75902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 76002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 76102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (params->format & I915_OVERLAY_SWAP_MASK) { 762722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_NO_SWAP: 763722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 764722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_UV_SWAP: 765722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson cmd |= OCMD_UV_SWAP; 766722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 767722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_Y_SWAP: 768722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson cmd |= OCMD_Y_SWAP; 769722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 770722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_Y_AND_UV_SWAP: 771722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson cmd |= OCMD_Y_AND_UV_SWAP; 772722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 77302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 77402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 77502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 77602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return cmd; 77702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 77802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 7795fe82c5ee1ba2d04183c376038c5d233a0311ec9Chris Wilsonstatic int intel_overlay_do_put_image(struct intel_overlay *overlay, 7805fe82c5ee1ba2d04183c376038c5d233a0311ec9Chris Wilson struct drm_gem_object *new_bo, 7815fe82c5ee1ba2d04183c376038c5d233a0311ec9Chris Wilson struct put_image_params *params) 78202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 78302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret, tmp_width; 78402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 78502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter bool scale_changed = false; 78623010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo); 78702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 78802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 78902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!mutex_is_locked(&dev->struct_mutex)); 79002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); 79102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!overlay); 79202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 79302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_release_old_vid(overlay); 79402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 79502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 79602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 79702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = i915_gem_object_pin(new_bo, PAGE_SIZE); 79802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 79902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 80002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 80102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = i915_gem_object_set_to_gtt_domain(new_bo, 0); 80202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 80302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unpin; 80402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 80502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay->active) { 8068d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson regs = intel_overlay_map_regs(overlay); 80702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!regs) { 80802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -ENOMEM; 80902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unpin; 81002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 81102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCONFIG = OCONF_CC_OUT_8BIT; 81202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I965GM(overlay->dev)) 81302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCONFIG |= OCONF_CSC_MODE_BT709; 81402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCONFIG |= overlay->crtc->pipe == 0 ? 81502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OCONF_PIPE_A : OCONF_PIPE_B; 8169bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson intel_overlay_unmap_regs(overlay, regs); 81702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 81802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_on(overlay); 81902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 82002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unpin; 82102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 82202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 8238d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson regs = intel_overlay_map_regs(overlay); 82402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!regs) { 82502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -ENOMEM; 82602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unpin; 82702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 82802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 82902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DWINPOS = (params->dst_y << 16) | params->dst_x; 83002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DWINSZ = (params->dst_h << 16) | params->dst_w; 83102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 83202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->format & I915_OVERLAY_YUV_PACKED) 83302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp_width = packed_width_bytes(params->format, params->src_w); 83402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 83502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp_width = params->src_w; 83602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 83702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SWIDTH = params->src_w; 83802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SWIDTHSW = calc_swidthsw(overlay->dev, 839722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson params->offset_Y, tmp_width); 84002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SHEIGHT = params->src_h; 84102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y; 84202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OSTRIDE = params->stride_Y; 84302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 84402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->format & I915_OVERLAY_YUV_PLANAR) { 84502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_hscale = uv_hsubsampling(params->format); 84602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_vscale = uv_vsubsampling(params->format); 84702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 tmp_U, tmp_V; 84802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SWIDTH |= (params->src_w/uv_hscale) << 16; 84902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp_U = calc_swidthsw(overlay->dev, params->offset_U, 850722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson params->src_w/uv_hscale); 85102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp_V = calc_swidthsw(overlay->dev, params->offset_V, 852722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson params->src_w/uv_hscale); 85302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16; 85402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; 85502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U; 85602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OBUF_0V = bo_priv->gtt_offset + params->offset_V; 85702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OSTRIDE |= params->stride_UV << 16; 85802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 85902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 86002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter scale_changed = update_scaling_factors(overlay, regs, params); 86102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 86202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_colorkey(overlay, regs); 86302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 86402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCMD = overlay_cmd_reg(params); 86502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 8669bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson intel_overlay_unmap_regs(overlay, regs); 86702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 8688dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson ret = intel_overlay_continue(overlay, scale_changed); 8698dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson if (ret) 8708dc5d14741dc1ee0074a14b360993a10c2c02d24Chris Wilson goto out_unpin; 87102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 87202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->old_vid_bo = overlay->vid_bo; 87323010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter overlay->vid_bo = to_intel_bo(new_bo); 87402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 87502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 87602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 87702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unpin: 87802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter i915_gem_object_unpin(new_bo); 87902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 88002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 88102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 8825dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilsonint intel_overlay_switch_off(struct intel_overlay *overlay, 8835dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson bool interruptible) 88402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 88502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 88602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 8875dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson int ret; 88802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 88902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!mutex_is_locked(&dev->struct_mutex)); 89002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); 89102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 8929bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter if (overlay->hw_wedged) { 8935dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson ret = intel_overlay_recover_from_interrupt(overlay, 8945dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson interruptible); 8959bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter if (ret != 0) 8969bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter return ret; 8979bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter } 8989bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter 89902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay->active) 90002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 90102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 90202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_release_old_vid(overlay); 90302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 90402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 90502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 9068d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson regs = intel_overlay_map_regs(overlay); 90702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCMD = 0; 9089bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson intel_overlay_unmap_regs(overlay, regs); 90902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 9105dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson ret = intel_overlay_off(overlay, interruptible); 91103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 91203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return ret; 91303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 91412ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter intel_overlay_off_tail(overlay); 91502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 91602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 91702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 91802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 91902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_possible_on_crtc(struct intel_overlay *overlay, 92002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_crtc *crtc) 92102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 922722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson drm_i915_private_t *dev_priv = overlay->dev->dev_private; 92302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 pipeconf; 92402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF; 92502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 92602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON) 92702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 92802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 92902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter pipeconf = I915_READ(pipeconf_reg); 93002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 93102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* can't use the overlay with double wide pipe */ 93202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!IS_I965G(overlay->dev) && pipeconf & PIPEACONF_DOUBLE_WIDE) 93302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 93402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 93502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 93602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 93702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 93802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_pfit_vscale_ratio(struct intel_overlay *overlay) 93902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 94002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 941722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson drm_i915_private_t *dev_priv = dev->dev_private; 94202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 pfit_control = I915_READ(PFIT_CONTROL); 943446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson u32 ratio; 94402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 94502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* XXX: This is not the same logic as in the xorg driver, but more in 946446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson * line with the intel documentation for the i965 947446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson */ 948446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson if (!IS_I965G(dev)) { 949446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson if (pfit_control & VERT_AUTO_SCALE) 950446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson ratio = I915_READ(PFIT_AUTO_RATIOS); 95102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 952446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson ratio = I915_READ(PFIT_PGM_RATIOS); 953446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson ratio >>= PFIT_VERT_SCALE_SHIFT; 954446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson } else { /* on i965 use the PGM reg to read out the autoscaler values */ 955446d2183af68c0fd2772f5ef97a033efe69904a5Chris Wilson ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965; 95602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 95702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 95802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->pfit_vscale_ratio = ratio; 95902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 96002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 96102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_dst(struct intel_overlay *overlay, 96202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_intel_overlay_put_image *rec) 96302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 96402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_display_mode *mode = &overlay->crtc->base.mode; 96502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 966722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->dst_x < mode->crtc_hdisplay && 967722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson rec->dst_x + rec->dst_width <= mode->crtc_hdisplay && 968722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson rec->dst_y < mode->crtc_vdisplay && 969722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson rec->dst_y + rec->dst_height <= mode->crtc_vdisplay) 97002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 97102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 97202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 97302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 97402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 97502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_scaling(struct put_image_params *rec) 97602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 97702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 tmp; 97802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 97902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* downscaling limit is 8.0 */ 98002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16; 98102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (tmp > 7) 98202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 98302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16; 98402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (tmp > 7) 98502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 98602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 98702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 98802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 98902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 99002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_src(struct drm_device *dev, 99102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_intel_overlay_put_image *rec, 99202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_gem_object *new_bo) 99302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 99402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_hscale = uv_hsubsampling(rec->flags); 99502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_vscale = uv_vsubsampling(rec->flags); 9969f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson u32 stride_mask, depth, tmp; 99702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 99802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* check src dimensions */ 99902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_845G(dev) || IS_I830(dev)) { 1000722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY || 10019f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson rec->src_width > IMAGE_MAX_WIDTH_LEGACY) 100202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 100302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 1004722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->src_height > IMAGE_MAX_HEIGHT || 10059f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson rec->src_width > IMAGE_MAX_WIDTH) 100602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 100702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 10089f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson 100902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* better safe than sorry, use 4 as the maximal subsampling ratio */ 1010722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->src_height < N_VERT_Y_TAPS*4 || 10119f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson rec->src_width < N_HORIZ_Y_TAPS*4) 101202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 101302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 1014a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson /* check alignment constraints */ 101502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (rec->flags & I915_OVERLAY_TYPE_MASK) { 1016722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_RGB: 1017722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson /* not implemented */ 1018722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 10199f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson 1020722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV_PACKED: 1021722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (uv_vscale != 1) 102202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 10239f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson 10249f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson depth = packed_depth_bytes(rec->flags); 1025722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (depth < 0) 1026722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return depth; 10279f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson 1028722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson /* ignore UV planes */ 1029722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson rec->stride_UV = 0; 1030722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson rec->offset_U = 0; 1031722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson rec->offset_V = 0; 1032722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson /* check pixel alignment */ 1033722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->offset_Y % depth) 1034722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 1035722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 10369f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson 1037722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV_PLANAR: 1038722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (uv_vscale < 0 || uv_hscale < 0) 103902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 1040722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson /* no offset restrictions for planar formats */ 1041722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 10429f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson 1043722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson default: 1044722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 104502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 104602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 104702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->src_width % uv_hscale) 104802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 104902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 105002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* stride checking */ 1051a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson if (IS_I830(dev) || IS_845G(dev)) 1052a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson stride_mask = 255; 1053a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson else 1054a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson stride_mask = 63; 105502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 105602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) 105702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 105802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I965G(dev) && rec->stride_Y < 512) 105902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 106002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 106102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ? 10629f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson 4096 : 8192; 10639f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson if (rec->stride_Y > tmp || rec->stride_UV > 2*1024) 106402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 106502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 106602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* check buffer dimensions */ 106702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (rec->flags & I915_OVERLAY_TYPE_MASK) { 1068722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_RGB: 1069722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV_PACKED: 1070722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson /* always 4 Y values per depth pixels */ 1071722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y) 1072722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 1073722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 1074722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson tmp = rec->stride_Y*rec->src_height; 1075722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->offset_Y + tmp > new_bo->size) 1076722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 1077722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 1078722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 1079722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson case I915_OVERLAY_YUV_PLANAR: 1080722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->src_width > rec->stride_Y) 1081722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 1082722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->src_width/uv_hscale > rec->stride_UV) 1083722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 1084722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 10859f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson tmp = rec->stride_Y * rec->src_height; 1086722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->offset_Y + tmp > new_bo->size) 1087722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 10889f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson 10899f7c3f442bb7c0d0a0ed25cc287932450a1f2babChris Wilson tmp = rec->stride_UV * (rec->src_height / uv_vscale); 1090722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (rec->offset_U + tmp > new_bo->size || 1091722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson rec->offset_V + tmp > new_bo->size) 1092722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson return -EINVAL; 1093722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson break; 109402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 109502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 109602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 109702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 109802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 109902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_put_image(struct drm_device *dev, void *data, 110002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_file *file_priv) 110102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 110202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_intel_overlay_put_image *put_image_rec = data; 110302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 110402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_overlay *overlay; 110502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_mode_object *drmmode_obj; 110602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_crtc *crtc; 110702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_gem_object *new_bo; 110802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct put_image_params *params; 110902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 111002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 111102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!dev_priv) { 111202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_ERROR("called with no initialization\n"); 111302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 111402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 111502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 111602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay = dev_priv->overlay; 111702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay) { 111802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_DEBUG("userspace bug: no overlay\n"); 111902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -ENODEV; 112002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 112102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 112202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) { 112302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->mode_config.mutex); 112402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->struct_mutex); 112502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 11265dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson ret = intel_overlay_switch_off(overlay, true); 112702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 112802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->struct_mutex); 112902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->mode_config.mutex); 113002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 113102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 113202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 113302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 113402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL); 113502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!params) 113602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -ENOMEM; 113702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 113802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id, 1139722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson DRM_MODE_OBJECT_CRTC); 1140915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter if (!drmmode_obj) { 1141915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter ret = -ENOENT; 1142915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter goto out_free; 1143915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter } 114402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); 114502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 114602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter new_bo = drm_gem_object_lookup(dev, file_priv, 1147722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson put_image_rec->bo_handle); 1148915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter if (!new_bo) { 1149915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter ret = -ENOENT; 1150915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter goto out_free; 1151915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter } 115202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 115302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->mode_config.mutex); 115402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->struct_mutex); 115502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 115603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->hw_wedged) { 115703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter ret = intel_overlay_recover_from_interrupt(overlay, 1); 115803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 115903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter goto out_unlock; 116003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter } 116103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 116202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (overlay->crtc != crtc) { 116302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_display_mode *mode = &crtc->base.mode; 11645dcdbcb06badbdf2faa698bf3198e421a1e12840Chris Wilson ret = intel_overlay_switch_off(overlay, true); 116502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 116602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 116702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 116802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_overlay_possible_on_crtc(overlay, crtc); 116902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 117002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 117102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 117202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->crtc = crtc; 117302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter crtc->overlay = overlay; 117402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 117502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (intel_panel_fitter_pipe(dev) == crtc->pipe 117602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* and line to wide, i.e. one-line-mode */ 117702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter && mode->hdisplay > 1024) { 117802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->pfit_active = 1; 117902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_pfit_vscale_ratio(overlay); 118002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else 118102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->pfit_active = 0; 118202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 118302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 118402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_overlay_dst(overlay, put_image_rec); 118502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 118602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 118702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 118802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (overlay->pfit_active) { 118902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_y = ((((u32)put_image_rec->dst_y) << 12) / 1190722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson overlay->pfit_vscale_ratio); 119102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* shifting right rounds downwards, so add 1 */ 119202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_h = ((((u32)put_image_rec->dst_height) << 12) / 1193722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson overlay->pfit_vscale_ratio) + 1; 119402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 119502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_y = put_image_rec->dst_y; 119602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_h = put_image_rec->dst_height; 119702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 119802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_x = put_image_rec->dst_x; 119902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_w = put_image_rec->dst_width; 120002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 120102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_w = put_image_rec->src_width; 120202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_h = put_image_rec->src_height; 120302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_scan_w = put_image_rec->src_scan_width; 120402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_scan_h = put_image_rec->src_scan_height; 1205722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (params->src_scan_h > params->src_h || 1206722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson params->src_scan_w > params->src_w) { 120702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -EINVAL; 120802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 120902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 121002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 121102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_overlay_src(dev, put_image_rec, new_bo); 121202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 121302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 121402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK; 121502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->stride_Y = put_image_rec->stride_Y; 121602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->stride_UV = put_image_rec->stride_UV; 121702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->offset_Y = put_image_rec->offset_Y; 121802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->offset_U = put_image_rec->offset_U; 121902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->offset_V = put_image_rec->offset_V; 122002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 122102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* Check scaling after src size to prevent a divide-by-zero. */ 122202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_overlay_scaling(params); 122302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 122402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 122502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 122602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_do_put_image(overlay, new_bo, params); 122702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 122802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 122902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 123002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->struct_mutex); 123102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->mode_config.mutex); 123202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 123302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter kfree(params); 123402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 123502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 123602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 123702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unlock: 123802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->struct_mutex); 123902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->mode_config.mutex); 1240bc9025bdc4e2b591734cca17697093845007b63dLuca Barbieri drm_gem_object_unreference_unlocked(new_bo); 1241915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenterout_free: 124202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter kfree(params); 124302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 124402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 124502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 124602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 124702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_reg_attrs(struct intel_overlay *overlay, 124802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs) 124902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 125002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff); 125102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCLRC1 = overlay->saturation; 125202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 125302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 125402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool check_gamma_bounds(u32 gamma1, u32 gamma2) 125502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 125602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int i; 125702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 125802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (gamma1 & 0xff000000 || gamma2 & 0xff000000) 125902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return false; 126002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 126102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter for (i = 0; i < 3; i++) { 1262722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff)) 126302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return false; 126402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 126502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 126602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return true; 126702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 126802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 126902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool check_gamma5_errata(u32 gamma5) 127002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 127102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int i; 127202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 127302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter for (i = 0; i < 3; i++) { 127402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (((gamma5 >> i*8) & 0xff) == 0x80) 127502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return false; 127602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 127702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 127802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return true; 127902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 128002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 128102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_gamma(struct drm_intel_overlay_attrs *attrs) 128202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 1283722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson if (!check_gamma_bounds(0, attrs->gamma0) || 1284722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson !check_gamma_bounds(attrs->gamma0, attrs->gamma1) || 1285722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson !check_gamma_bounds(attrs->gamma1, attrs->gamma2) || 1286722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson !check_gamma_bounds(attrs->gamma2, attrs->gamma3) || 1287722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson !check_gamma_bounds(attrs->gamma3, attrs->gamma4) || 1288722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson !check_gamma_bounds(attrs->gamma4, attrs->gamma5) || 1289722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson !check_gamma_bounds(attrs->gamma5, 0x00ffffff)) 129002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 1291722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 129202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!check_gamma5_errata(attrs->gamma5)) 129302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 1294722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson 129502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 129602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 129702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 129802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_attrs(struct drm_device *dev, void *data, 129902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_file *file_priv) 130002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 130102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_intel_overlay_attrs *attrs = data; 130202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 130302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_overlay *overlay; 130402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 130502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 130602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 130702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!dev_priv) { 130802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_ERROR("called with no initialization\n"); 130902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 131002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 131102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 131202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay = dev_priv->overlay; 131302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay) { 131402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_DEBUG("userspace bug: no overlay\n"); 131502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -ENODEV; 131602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 131702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 131802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->mode_config.mutex); 131902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->struct_mutex); 132002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 132160fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson ret = -EINVAL; 132202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) { 132360fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson attrs->color_key = overlay->color_key; 132402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->brightness = overlay->brightness; 132560fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson attrs->contrast = overlay->contrast; 132602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->saturation = overlay->saturation; 132702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 132802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I9XX(dev)) { 132902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma0 = I915_READ(OGAMC0); 133002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma1 = I915_READ(OGAMC1); 133102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma2 = I915_READ(OGAMC2); 133202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma3 = I915_READ(OGAMC3); 133302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma4 = I915_READ(OGAMC4); 133402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma5 = I915_READ(OGAMC5); 133502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 133602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 133760fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson if (attrs->brightness < -128 || attrs->brightness > 127) 133802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 133960fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson if (attrs->contrast > 255) 134002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 134160fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson if (attrs->saturation > 1023) 134202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 134360fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson 134460fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson overlay->color_key = attrs->color_key; 134560fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson overlay->brightness = attrs->brightness; 134660fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson overlay->contrast = attrs->contrast; 134760fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson overlay->saturation = attrs->saturation; 134802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 13498d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson regs = intel_overlay_map_regs(overlay); 135002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!regs) { 135102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -ENOMEM; 135202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 135302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 135402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 135502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_reg_attrs(overlay, regs); 135602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 13579bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson intel_overlay_unmap_regs(overlay, regs); 135802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 135902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { 136060fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson if (!IS_I9XX(dev)) 136102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 136202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 136302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (overlay->active) { 136402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -EBUSY; 136502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 136602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 136702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 136802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_gamma(attrs); 136960fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson if (ret) 137002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 137102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 137202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC0, attrs->gamma0); 137302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC1, attrs->gamma1); 137402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC2, attrs->gamma2); 137502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC3, attrs->gamma3); 137602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC4, attrs->gamma4); 137702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC5, attrs->gamma5); 137802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 137902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 138002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 138160fc332cb5ab19e5a86d696b210df65814b2ad8aChris Wilson ret = 0; 138202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unlock: 138302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->struct_mutex); 138402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->mode_config.mutex); 138502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 138602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 138702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 138802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 138902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vettervoid intel_setup_overlay(struct drm_device *dev) 139002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 139102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 139202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_overlay *overlay; 139302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_gem_object *reg_bo; 139402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 139502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 139602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 139731578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson if (!HAS_OVERLAY(dev)) 139802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return; 139902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 140002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); 140102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay) 140202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return; 140302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->dev = dev; 140402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 1405ac52bc56de25535a907ef07f8755f1387b89b0f5Daniel Vetter reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); 140602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!reg_bo) 140702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_free; 140823010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter overlay->reg_bo = to_intel_bo(reg_bo); 140902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 141031578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson if (OVERLAY_NEEDS_PHYSICAL(dev)) { 141131578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson ret = i915_gem_attach_phys_object(dev, reg_bo, 141231578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson I915_GEM_PHYS_OVERLAY_REGS, 1413a29301288f1840bdf9c5456da9cd7c944436edd5Chris Wilson PAGE_SIZE); 141431578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson if (ret) { 141531578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson DRM_ERROR("failed to attach phys overlay regs\n"); 141631578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson goto out_free_bo; 141731578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson } 141831578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; 141931578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson } else { 142002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); 142102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret) { 142202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_ERROR("failed to pin overlay register bo\n"); 142302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_free_bo; 142402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 142502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->flip_addr = overlay->reg_bo->gtt_offset; 14260ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson 14270ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); 14280ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson if (ret) { 14290ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson DRM_ERROR("failed to move overlay register bo into the GTT\n"); 14300ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson goto out_unpin_bo; 14310ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson } 143202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 143302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 143402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* init all values */ 143502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->color_key = 0x0101fe; 143602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->brightness = -19; 143702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->contrast = 75; 143802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->saturation = 146; 143902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 14408d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson regs = intel_overlay_map_regs(overlay); 144102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!regs) 144202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_free_bo; 144302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 144402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter memset(regs, 0, sizeof(struct overlay_registers)); 144502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_polyphase_filter(regs); 144602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_reg_attrs(overlay, regs); 144702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 14489bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson intel_overlay_unmap_regs(overlay, regs); 144902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 145002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter dev_priv->overlay = overlay; 145102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_INFO("initialized overlay support\n"); 145202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return; 145302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 14540ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilsonout_unpin_bo: 14550ddc1289f3ffd779779ddd3922f26ae7d0a21604Chris Wilson i915_gem_object_unpin(reg_bo); 145602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_free_bo: 145702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_gem_object_unreference(reg_bo); 145802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_free: 145902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter kfree(overlay); 146002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return; 146102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 146202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 146302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vettervoid intel_cleanup_overlay(struct drm_device *dev) 146402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 1465722506f04dae7c88193dab2fc836ff15070190f0Chris Wilson drm_i915_private_t *dev_priv = dev->dev_private; 146602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 146762cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson if (!dev_priv->overlay) 146862cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson return; 146902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 147062cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson /* The bo's should be free'd by the generic code already. 147162cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson * Furthermore modesetting teardown happens beforehand so the 147262cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson * hardware should be off already */ 147362cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson BUG_ON(dev_priv->overlay->active); 147462cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson 147562cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base); 147662cf4e6fef35b4422e206b63b7f0ac90261d4ad9Chris Wilson kfree(dev_priv->overlay); 147702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 14786ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 14796ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonstruct intel_overlay_error_state { 14806ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson struct overlay_registers regs; 14816ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson unsigned long base; 14826ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson u32 dovsta; 14836ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson u32 isr; 14846ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson}; 14856ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 14866ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonstruct intel_overlay_error_state * 14876ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonintel_overlay_capture_error_state(struct drm_device *dev) 14886ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson{ 14896ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson drm_i915_private_t *dev_priv = dev->dev_private; 14906ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson struct intel_overlay *overlay = dev_priv->overlay; 14916ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson struct intel_overlay_error_state *error; 14926ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson struct overlay_registers __iomem *regs; 14936ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 14946ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson if (!overlay || !overlay->active) 14956ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson return NULL; 14966ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 14976ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson error = kmalloc(sizeof(*error), GFP_ATOMIC); 14986ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson if (error == NULL) 14996ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson return NULL; 15006ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 15016ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson error->dovsta = I915_READ(DOVSTA); 15026ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson error->isr = I915_READ(ISR); 150331578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) 15046ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; 150531578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson else 150631578148b2c62612f9516fdcf5ebb64ab32ed12dChris Wilson error->base = (long) overlay->reg_bo->gtt_offset; 15076ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 15088d74f656dd78ae1ba813389cd46197c6329696bcChris Wilson regs = intel_overlay_map_regs_atomic(overlay, KM_IRQ0); 15096ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson if (!regs) 15106ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson goto err; 15116ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 15126ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); 15139bb2ff731b32c023e7a502efdc0dee46157290d5Chris Wilson intel_overlay_unmap_regs_atomic(overlay, KM_IRQ0, regs); 15146ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 15156ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson return error; 15166ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 15176ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonerr: 15186ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson kfree(error); 15196ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson return NULL; 15206ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson} 15216ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 15226ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonvoid 15236ef3d4278034982c13df87c4a51e0445f762d316Chris Wilsonintel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error) 15246ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson{ 15256ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", 15266ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson error->dovsta, error->isr); 15276ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson seq_printf(m, " Register file at 0x%08lx:\n", 15286ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson error->base); 15296ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson 15306ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson#define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x) 15316ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OBUF_0Y); 15326ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OBUF_1Y); 15336ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OBUF_0U); 15346ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OBUF_0V); 15356ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OBUF_1U); 15366ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OBUF_1V); 15376ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OSTRIDE); 15386ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(YRGB_VPH); 15396ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(UV_VPH); 15406ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(HORZ_PH); 15416ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(INIT_PHS); 15426ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(DWINPOS); 15436ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(DWINSZ); 15446ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(SWIDTH); 15456ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(SWIDTHSW); 15466ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(SHEIGHT); 15476ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(YRGBSCALE); 15486ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(UVSCALE); 15496ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OCLRC0); 15506ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OCLRC1); 15516ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(DCLRKV); 15526ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(DCLRKM); 15536ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(SCLRKVH); 15546ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(SCLRKVL); 15556ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(SCLRKEN); 15566ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OCONFIG); 15576ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OCMD); 15586ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OSTART_0Y); 15596ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OSTART_1Y); 15606ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OSTART_0U); 15616ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OSTART_0V); 15626ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OSTART_1U); 15636ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OSTART_1V); 15646ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OTILEOFF_0Y); 15656ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OTILEOFF_1Y); 15666ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OTILEOFF_0U); 15676ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OTILEOFF_0V); 15686ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OTILEOFF_1U); 15696ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(OTILEOFF_1V); 15706ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(FASTHSCALE); 15716ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson P(UVSCALEV); 15726ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson#undef P 15736ef3d4278034982c13df87c4a51e0445f762d316Chris Wilson} 1574