intel_overlay.c revision a1efd14a99483a4fb9308902397ed86b69454c99
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 */ 2802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "drmP.h" 2902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "drm.h" 3002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "i915_drm.h" 3102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "i915_drv.h" 3202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "i915_reg.h" 3302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#include "intel_drv.h" 3402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 3502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* Limits for overlay size. According to intel doc, the real limits are: 3602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * Y width: 4095, UV width (planar): 2047, Y height: 2047, 3702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use 3802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * the mininum of both. */ 3902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define IMAGE_MAX_WIDTH 2048 4002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define IMAGE_MAX_HEIGHT 2046 /* 2 * 1023 */ 4102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* on 830 and 845 these large limits result in the card hanging */ 4202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define IMAGE_MAX_WIDTH_LEGACY 1024 4302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define IMAGE_MAX_HEIGHT_LEGACY 1088 4402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 4502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay register definitions */ 4602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* OCMD register */ 4702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_TILED_SURFACE (0x1<<19) 4802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_MASK (0x3<<17) 4902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_MODE (0x3<<17) 5002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_HORIZONTAL (0x1<<17) 5102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_VERTICAL (0x2<<17) 5202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_MIRROR_BOTH (0x3<<17) 5302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BYTEORDER_MASK (0x3<<14) /* zero for YUYV or FOURCC YUY2 */ 5402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_UV_SWAP (0x1<<14) /* YVYU */ 5502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_Y_SWAP (0x2<<14) /* UYVY or FOURCC UYVY */ 5602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_Y_AND_UV_SWAP (0x3<<14) /* VYUY */ 5702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_SOURCE_FORMAT_MASK (0xf<<10) 5802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_RGB_888 (0x1<<10) /* not in i965 Intel docs */ 5902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_RGB_555 (0x2<<10) /* not in i965 Intel docs */ 6002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_RGB_565 (0x3<<10) /* not in i965 Intel docs */ 6102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_422_PACKED (0x8<<10) 6202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_411_PACKED (0x9<<10) /* not in i965 Intel docs */ 6302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_420_PLANAR (0xc<<10) 6402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_422_PLANAR (0xd<<10) 6502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */ 6602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_TVSYNCFLIP_PARITY (0x1<<9) 6702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_TVSYNCFLIP_ENABLE (0x1<<7) 6802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUF_TYPE_MASK (Ox1<<5) 6902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUF_TYPE_FRAME (0x0<<5) 7002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUF_TYPE_FIELD (0x1<<5) 7102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_TEST_MODE (0x1<<4) 7202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUFFER_SELECT (0x3<<2) 7302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUFFER0 (0x0<<2) 7402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_BUFFER1 (0x1<<2) 7502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_FIELD_SELECT (0x1<<2) 7602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_FIELD0 (0x0<<1) 7702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_FIELD1 (0x1<<1) 7802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCMD_ENABLE (0x1<<0) 7902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 8002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* OCONFIG register */ 8102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_PIPE_MASK (0x1<<18) 8202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_PIPE_A (0x0<<18) 8302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_PIPE_B (0x1<<18) 8402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_GAMMA2_ENABLE (0x1<<16) 8502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_CSC_MODE_BT601 (0x0<<5) 8602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_CSC_MODE_BT709 (0x1<<5) 8702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_CSC_BYPASS (0x1<<4) 8802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_CC_OUT_8BIT (0x1<<3) 8902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_TEST_MODE (0x1<<2) 9002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_THREE_LINE_BUFFER (0x1<<0) 9102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OCONF_TWO_LINE_BUFFER (0x0<<0) 9202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 9302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* DCLRKM (dst-key) register */ 9402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define DST_KEY_ENABLE (0x1<<31) 9502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define CLK_RGB24_MASK 0x0 9602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define CLK_RGB16_MASK 0x070307 9702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define CLK_RGB15_MASK 0x070707 9802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define CLK_RGB8I_MASK 0xffffff 9902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 10002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define RGB16_TO_COLORKEY(c) \ 10102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3)) 10202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define RGB15_TO_COLORKEY(c) \ 10302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3)) 10402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 10502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay flip addr flag */ 10602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OFC_UPDATE 0x1 10702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 10802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* polyphase filter coefficients */ 10902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_HORIZ_Y_TAPS 5 11002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_VERT_Y_TAPS 3 11102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_HORIZ_UV_TAPS 3 11202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_VERT_UV_TAPS 3 11302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define N_PHASES 17 11402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define MAX_TAPS 5 11502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 11602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* memory bufferd overlay registers */ 11702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstruct overlay_registers { 11802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OBUF_0Y; 11902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OBUF_1Y; 12002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OBUF_0U; 12102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OBUF_0V; 12202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OBUF_1U; 12302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OBUF_1V; 12402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OSTRIDE; 12502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 YRGB_VPH; 12602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 UV_VPH; 12702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 HORZ_PH; 12802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 INIT_PHS; 12902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 DWINPOS; 13002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 DWINSZ; 13102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 SWIDTH; 13202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 SWIDTHSW; 13302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 SHEIGHT; 13402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 YRGBSCALE; 13502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 UVSCALE; 13602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OCLRC0; 13702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OCLRC1; 13802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 DCLRKV; 13902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 DCLRKM; 14002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 SCLRKVH; 14102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 SCLRKVL; 14202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 SCLRKEN; 14302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OCONFIG; 14402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OCMD; 14502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 RESERVED1; /* 0x6C */ 14602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OSTART_0Y; 14702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OSTART_1Y; 14802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OSTART_0U; 14902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OSTART_0V; 15002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OSTART_1U; 15102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OSTART_1V; 15202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OTILEOFF_0Y; 15302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OTILEOFF_1Y; 15402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OTILEOFF_0U; 15502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OTILEOFF_0V; 15602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OTILEOFF_1U; 15702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 OTILEOFF_1V; 15802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 FASTHSCALE; /* 0xA0 */ 15902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 UVSCALEV; /* 0xA4 */ 16002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */ 16102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */ 16202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES]; 16302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */ 16402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES]; 16502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */ 16602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES]; 16702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */ 16802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES]; 16902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}; 17002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 17102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay flip addr flag */ 17202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OFC_UPDATE 0x1 17302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 17402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define OVERLAY_NONPHYSICAL(dev) (IS_G33(dev) || IS_I965G(dev)) 175bad720ff3e8e47a04bd88d9bbc8317e7d7e049d3Eric Anholt#define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IRONLAKE(dev) && !IS_GEN6(dev)) 17602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 17702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 17802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_overlay *overlay) 17902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 18002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = overlay->dev->dev_private; 18102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 18202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 18302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* no recursive mappings */ 18402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(overlay->virt_addr); 18502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 18602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (OVERLAY_NONPHYSICAL(overlay->dev)) { 18702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, 18802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->reg_bo->gtt_offset); 18902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 19002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!regs) { 19102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_ERROR("failed to map overlay regs in GTT\n"); 19202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return NULL; 19302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 19402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else 19502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs = overlay->reg_bo->phys_obj->handle->vaddr; 19602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 19702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return overlay->virt_addr = regs; 19802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 19902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 20002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) 20102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 20202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (OVERLAY_NONPHYSICAL(overlay->dev)) 20302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter io_mapping_unmap_atomic(overlay->virt_addr); 20402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 20502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->virt_addr = NULL; 20602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 20702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return; 20802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 20902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 21002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay needs to be disable in OCMD reg */ 21102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int intel_overlay_on(struct intel_overlay *overlay) 21202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 21302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 21402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 215852835f343146a82a528c3b712b373661d4fa17aZou Nan hai drm_i915_private_t *dev_priv = dev->dev_private; 21602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 21702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(overlay->active); 21802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 21903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->active = 1; 22003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = NEEDS_WAIT_FOR_FLIP; 22103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 2224f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter BEGIN_LP_RING(4); 22302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); 22402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(overlay->flip_addr | OFC_UPDATE); 22502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 22602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_NOOP); 22702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ADVANCE_LP_RING(); 22802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 229852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req = 230852835f343146a82a528c3b712b373661d4fa17aZou Nan hai i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 23103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->last_flip_req == 0) 23203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return -ENOMEM; 23302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 234852835f343146a82a528c3b712b373661d4fa17aZou Nan hai ret = i915_do_wait_request(dev, 235852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req, 1, &dev_priv->render_ring); 23603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 23703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return ret; 23802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 23903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = 0; 24003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->last_flip_req = 0; 24102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 24202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 24302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 24402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay needs to be enabled in OCMD reg */ 24502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void intel_overlay_continue(struct intel_overlay *overlay, 24602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter bool load_polyphase_filter) 24702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 24802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 24902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 25002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 flip_addr = overlay->flip_addr; 25102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 tmp; 25202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 25302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!overlay->active); 25402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 25502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (load_polyphase_filter) 25602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter flip_addr |= OFC_UPDATE; 25702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 25802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* check for underruns */ 25902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = I915_READ(DOVSTA); 26002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (tmp & (1 << 17)) 26102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); 26202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 2634f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter BEGIN_LP_RING(2); 26402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 26502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(flip_addr); 2665a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter ADVANCE_LP_RING(); 2675a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter 268852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req = 269852835f343146a82a528c3b712b373661d4fa17aZou Nan hai i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 2705a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter} 2715a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter 2725a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetterstatic int intel_overlay_wait_flip(struct intel_overlay *overlay) 2735a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter{ 2745a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter struct drm_device *dev = overlay->dev; 2755a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 2765a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter int ret; 2775a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter u32 tmp; 2785a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter 2795a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter if (overlay->last_flip_req != 0) { 280852835f343146a82a528c3b712b373661d4fa17aZou Nan hai ret = i915_do_wait_request(dev, overlay->last_flip_req, 281852835f343146a82a528c3b712b373661d4fa17aZou Nan hai 1, &dev_priv->render_ring); 2825c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter if (ret == 0) { 2835c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter overlay->last_flip_req = 0; 2845a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter 2855c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter tmp = I915_READ(ISR); 2865a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter 2875c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT)) 2885c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter return 0; 2895c5a4359fe392b52b444134877fc4002be542b42Daniel Vetter } 2905a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter } 2915a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter 2925a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter /* synchronous slowpath */ 29303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = RELEASE_OLD_VID; 29403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 2955a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter BEGIN_LP_RING(2); 29602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 29702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_NOOP); 29802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ADVANCE_LP_RING(); 29902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 300852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req = 301852835f343146a82a528c3b712b373661d4fa17aZou Nan hai i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 30203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->last_flip_req == 0) 30303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return -ENOMEM; 30402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 305852835f343146a82a528c3b712b373661d4fa17aZou Nan hai ret = i915_do_wait_request(dev, overlay->last_flip_req, 306852835f343146a82a528c3b712b373661d4fa17aZou Nan hai 1, &dev_priv->render_ring); 30703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 30803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return ret; 30903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 31003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = 0; 31103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->last_flip_req = 0; 31203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return 0; 31302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 31402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 31502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter/* overlay needs to be disabled in OCMD reg */ 31602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int intel_overlay_off(struct intel_overlay *overlay) 31702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 31802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 flip_addr = overlay->flip_addr; 31902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 320852835f343146a82a528c3b712b373661d4fa17aZou Nan hai drm_i915_private_t *dev_priv = dev->dev_private; 32102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 32202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 32302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!overlay->active); 32402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 32502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* According to intel docs the overlay hw may hang (when switching 32602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * off) without loading the filter coeffs. It is however unclear whether 32702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * this applies to the disabling of the overlay or to the switching off 32802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * of the hw. Do it in both cases */ 32902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter flip_addr |= OFC_UPDATE; 33002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 33102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* wait for overlay to go idle */ 33203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = SWITCH_OFF_STAGE_1; 33303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 3344f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter BEGIN_LP_RING(4); 33502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 33602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(flip_addr); 33702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 33802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_NOOP); 33902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ADVANCE_LP_RING(); 34002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 341852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req = 342852835f343146a82a528c3b712b373661d4fa17aZou Nan hai i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 34303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->last_flip_req == 0) 34403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return -ENOMEM; 34503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 346852835f343146a82a528c3b712b373661d4fa17aZou Nan hai ret = i915_do_wait_request(dev, overlay->last_flip_req, 347852835f343146a82a528c3b712b373661d4fa17aZou Nan hai 1, &dev_priv->render_ring); 34803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 34902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 35002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 35102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* turn overlay off */ 35203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = SWITCH_OFF_STAGE_2; 35303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 3544f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter BEGIN_LP_RING(4); 35502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); 35602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(flip_addr); 35702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 35802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OUT_RING(MI_NOOP); 35902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ADVANCE_LP_RING(); 36002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 361852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req = 362852835f343146a82a528c3b712b373661d4fa17aZou Nan hai i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 36303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->last_flip_req == 0) 36403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return -ENOMEM; 36503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 366852835f343146a82a528c3b712b373661d4fa17aZou Nan hai ret = i915_do_wait_request(dev, overlay->last_flip_req, 367852835f343146a82a528c3b712b373661d4fa17aZou Nan hai 1, &dev_priv->render_ring); 36803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 36902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 37002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 37103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = 0; 37203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->last_flip_req = 0; 37302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 37402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 37502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 37612ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetterstatic void intel_overlay_off_tail(struct intel_overlay *overlay) 37712ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter{ 37812ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter struct drm_gem_object *obj; 37912ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter 38012ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter /* never have the overlay hw on without showing a frame */ 38112ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter BUG_ON(!overlay->vid_bo); 382a8089e849a32c5b6bfd6c88dbd09c0ea4a779b71Daniel Vetter obj = &overlay->vid_bo->base; 38312ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter 38412ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter i915_gem_object_unpin(obj); 38512ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter drm_gem_object_unreference(obj); 38612ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter overlay->vid_bo = NULL; 38712ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter 38812ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter overlay->crtc->overlay = NULL; 38912ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter overlay->crtc = NULL; 39012ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter overlay->active = 0; 39112ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter} 39212ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter 39303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter/* recover from an interruption due to a signal 39403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter * We have to be careful not to repeat work forever an make forward progess. */ 39503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetterint intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, 39603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter int interruptible) 39703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter{ 39803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter struct drm_device *dev = overlay->dev; 39903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter struct drm_gem_object *obj; 400852835f343146a82a528c3b712b373661d4fa17aZou Nan hai drm_i915_private_t *dev_priv = dev->dev_private; 40103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter u32 flip_addr; 40203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter int ret; 40303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 40403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->hw_wedged == HW_WEDGED) 40503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return -EIO; 40603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 40703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->last_flip_req == 0) { 408852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req = 409852835f343146a82a528c3b712b373661d4fa17aZou Nan hai i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 41003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->last_flip_req == 0) 41103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return -ENOMEM; 41203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter } 41303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 414852835f343146a82a528c3b712b373661d4fa17aZou Nan hai ret = i915_do_wait_request(dev, overlay->last_flip_req, 415852835f343146a82a528c3b712b373661d4fa17aZou Nan hai interruptible, &dev_priv->render_ring); 41603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 41703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return ret; 41803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 41903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter switch (overlay->hw_wedged) { 42003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter case RELEASE_OLD_VID: 421a8089e849a32c5b6bfd6c88dbd09c0ea4a779b71Daniel Vetter obj = &overlay->old_vid_bo->base; 42203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter i915_gem_object_unpin(obj); 42303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter drm_gem_object_unreference(obj); 42403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->old_vid_bo = NULL; 42503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter break; 42603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter case SWITCH_OFF_STAGE_1: 42703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter flip_addr = overlay->flip_addr; 42803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter flip_addr |= OFC_UPDATE; 42903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 43003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = SWITCH_OFF_STAGE_2; 43103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 4324f8a567c4666c73284832240db89fdadb2c50bd5Daniel Vetter BEGIN_LP_RING(4); 43303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); 43403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter OUT_RING(flip_addr); 43503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 43603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter OUT_RING(MI_NOOP); 43703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter ADVANCE_LP_RING(); 43803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 439852835f343146a82a528c3b712b373661d4fa17aZou Nan hai overlay->last_flip_req = i915_add_request(dev, NULL, 440852835f343146a82a528c3b712b373661d4fa17aZou Nan hai 0, &dev_priv->render_ring); 44103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->last_flip_req == 0) 44203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return -ENOMEM; 44303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 44403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter ret = i915_do_wait_request(dev, overlay->last_flip_req, 445852835f343146a82a528c3b712b373661d4fa17aZou Nan hai interruptible, &dev_priv->render_ring); 44603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 44703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return ret; 44803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 44903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter case SWITCH_OFF_STAGE_2: 45012ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter intel_overlay_off_tail(overlay); 45103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter break; 45203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter default: 45303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP); 45403f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter } 45503f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 45603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->hw_wedged = 0; 45703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter overlay->last_flip_req = 0; 45803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return 0; 45903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter} 46003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 4615a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter/* Wait for pending overlay flip and release old frame. 4625a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter * Needs to be called before the overlay register are changed 4635a5a0c64a99d7542c48c99d1a8bbb49e665842beDaniel Vetter * via intel_overlay_(un)map_regs_atomic */ 46402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int intel_overlay_release_old_vid(struct intel_overlay *overlay) 46502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 46602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 46702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_gem_object *obj; 46802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 46903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter /* only wait if there is actually an old frame to release to 47003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter * guarantee forward progress */ 47103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (!overlay->old_vid_bo) 47203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return 0; 47303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 47402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_wait_flip(overlay); 47502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 47602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 47702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 478a8089e849a32c5b6bfd6c88dbd09c0ea4a779b71Daniel Vetter obj = &overlay->old_vid_bo->base; 47902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter i915_gem_object_unpin(obj); 48002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_gem_object_unreference(obj); 48102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->old_vid_bo = NULL; 48202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 48302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 48402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 48502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 48602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstruct put_image_params { 48702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int format; 48802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short dst_x; 48902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short dst_y; 49002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short dst_w; 49102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short dst_h; 49202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short src_w; 49302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short src_scan_h; 49402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short src_scan_w; 49502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short src_h; 49602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short stride_Y; 49702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter short stride_UV; 49802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int offset_Y; 49902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int offset_U; 50002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int offset_V; 50102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter}; 50202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 50302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int packed_depth_bytes(u32 format) 50402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 50502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (format & I915_OVERLAY_DEPTH_MASK) { 50602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV422: 50702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 4; 50802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV411: 50902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* return 6; not implemented */ 51002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter default: 51102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 51202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 51302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 51402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 51502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int packed_width_bytes(u32 format, short width) 51602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 51702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (format & I915_OVERLAY_DEPTH_MASK) { 51802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV422: 51902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return width << 1; 52002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter default: 52102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 52202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 52302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 52402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 52502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int uv_hsubsampling(u32 format) 52602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 52702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (format & I915_OVERLAY_DEPTH_MASK) { 52802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV422: 52902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV420: 53002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 2; 53102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV411: 53202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV410: 53302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 4; 53402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter default: 53502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 53602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 53702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 53802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 53902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int uv_vsubsampling(u32 format) 54002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 54102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (format & I915_OVERLAY_DEPTH_MASK) { 54202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV420: 54302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV410: 54402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 2; 54502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV422: 54602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV411: 54702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 1; 54802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter default: 54902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 55002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 55102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 55202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 55302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width) 55402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 55502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 mask, shift, ret; 55602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I9XX(dev)) { 55702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mask = 0x3f; 55802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter shift = 6; 55902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 56002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mask = 0x1f; 56102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter shift = 5; 56202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 56302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = ((offset + width + mask) >> shift) - (offset >> shift); 56402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I9XX(dev)) 56502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret <<= 1; 56602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret -=1; 56702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret << 2; 56802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 56902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 57002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = { 57102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0, 57202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb500, 0x19d0, 0x1880, 0xb440, 57302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0, 57402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380, 57502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320, 57602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0, 57702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260, 57802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200, 57902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0, 58002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160, 58102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120, 58202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0, 58302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0, 58402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060, 58502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040, 58602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020, 58702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb000, 0x3000, 0x0800, 0x3000, 0xb000}; 58802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = { 58902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60, 59002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40, 59102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880, 59202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00, 59302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0, 59402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0, 59502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240, 59602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0, 59702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 0x3000, 0x0800, 0x3000}; 59802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 59902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_polyphase_filter(struct overlay_registers *regs) 60002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 60102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs)); 60202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs)); 60302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 60402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 60502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool update_scaling_factors(struct intel_overlay *overlay, 60602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs, 60702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct put_image_params *params) 60802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 60902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* fixed point with a 12 bit shift */ 61002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 xscale, yscale, xscale_UV, yscale_UV; 61102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define FP_SHIFT 12 61202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter#define FRACT_MASK 0xfff 61302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter bool scale_changed = false; 61402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_hscale = uv_hsubsampling(params->format); 61502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_vscale = uv_vsubsampling(params->format); 61602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 61702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->dst_w > 1) 61802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter xscale = ((params->src_scan_w - 1) << FP_SHIFT) 61902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /(params->dst_w); 62002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 62102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter xscale = 1 << FP_SHIFT; 62202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 62302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->dst_h > 1) 62402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter yscale = ((params->src_scan_h - 1) << FP_SHIFT) 62502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /(params->dst_h); 62602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 62702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter yscale = 1 << FP_SHIFT; 62802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 62902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/ 63002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter xscale_UV = xscale/uv_hscale; 63102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter yscale_UV = yscale/uv_vscale; 63202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* make the Y scale to UV scale ratio an exact multiply */ 63302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter xscale = xscale_UV * uv_hscale; 63402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter yscale = yscale_UV * uv_vscale; 63502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /*} else { 63602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter xscale_UV = 0; 63702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter yscale_UV = 0; 63802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter }*/ 63902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 64002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (xscale != overlay->old_xscale || yscale != overlay->old_yscale) 64102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter scale_changed = true; 64202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->old_xscale = xscale; 64302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->old_yscale = yscale; 64402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 64502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->YRGBSCALE = ((yscale & FRACT_MASK) << 20) 64602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter | ((xscale >> FP_SHIFT) << 16) 64702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter | ((xscale & FRACT_MASK) << 3); 64802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->UVSCALE = ((yscale_UV & FRACT_MASK) << 20) 64902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter | ((xscale_UV >> FP_SHIFT) << 16) 65002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter | ((xscale_UV & FRACT_MASK) << 3); 65102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->UVSCALEV = ((yscale >> FP_SHIFT) << 16) 65202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter | ((yscale_UV >> FP_SHIFT) << 0); 65302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 65402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (scale_changed) 65502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_polyphase_filter(regs); 65602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 65702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return scale_changed; 65802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 65902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 66002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_colorkey(struct intel_overlay *overlay, 66102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs) 66202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 66302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 key = overlay->color_key; 66402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (overlay->crtc->base.fb->bits_per_pixel) { 66502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case 8: 66602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DCLRKV = 0; 66702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE; 66802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case 16: 66902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (overlay->crtc->base.fb->depth == 15) { 67002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DCLRKV = RGB15_TO_COLORKEY(key); 67102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE; 67202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 67302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DCLRKV = RGB16_TO_COLORKEY(key); 67402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE; 67502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 67602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case 24: 67702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case 32: 67802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DCLRKV = key; 67902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE; 68002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 68102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 68202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 68302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic u32 overlay_cmd_reg(struct put_image_params *params) 68402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 68502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0; 68602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 68702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->format & I915_OVERLAY_YUV_PLANAR) { 68802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (params->format & I915_OVERLAY_DEPTH_MASK) { 68902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV422: 69002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter cmd |= OCMD_YUV_422_PLANAR; 69102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 69202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV420: 69302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter cmd |= OCMD_YUV_420_PLANAR; 69402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 69502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV411: 69602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV410: 69702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter cmd |= OCMD_YUV_410_PLANAR; 69802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 69902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 70002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { /* YUV packed */ 70102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (params->format & I915_OVERLAY_DEPTH_MASK) { 70202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV422: 70302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter cmd |= OCMD_YUV_422_PACKED; 70402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 70502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV411: 70602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter cmd |= OCMD_YUV_411_PACKED; 70702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 70802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 70902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 71002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (params->format & I915_OVERLAY_SWAP_MASK) { 71102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_NO_SWAP: 71202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 71302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_UV_SWAP: 71402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter cmd |= OCMD_UV_SWAP; 71502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 71602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_Y_SWAP: 71702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter cmd |= OCMD_Y_SWAP; 71802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 71902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_Y_AND_UV_SWAP: 72002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter cmd |= OCMD_Y_AND_UV_SWAP; 72102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 72202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 72302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 72402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 72502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return cmd; 72602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 72702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 72802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_do_put_image(struct intel_overlay *overlay, 72902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_gem_object *new_bo, 73002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct put_image_params *params) 73102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 73202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret, tmp_width; 73302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 73402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter bool scale_changed = false; 73523010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo); 73602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 73702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 73802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!mutex_is_locked(&dev->struct_mutex)); 73902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); 74002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!overlay); 74102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 74202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_release_old_vid(overlay); 74302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 74402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 74502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 74602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = i915_gem_object_pin(new_bo, PAGE_SIZE); 74702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 74802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 74902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 75002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = i915_gem_object_set_to_gtt_domain(new_bo, 0); 75102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 75202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unpin; 75302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 75402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay->active) { 75502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs = intel_overlay_map_regs_atomic(overlay); 75602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!regs) { 75702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -ENOMEM; 75802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unpin; 75902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 76002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCONFIG = OCONF_CC_OUT_8BIT; 76102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I965GM(overlay->dev)) 76202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCONFIG |= OCONF_CSC_MODE_BT709; 76302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCONFIG |= overlay->crtc->pipe == 0 ? 76402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter OCONF_PIPE_A : OCONF_PIPE_B; 76502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter intel_overlay_unmap_regs_atomic(overlay); 76602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 76702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_on(overlay); 76802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 76902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unpin; 77002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 77102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 77202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs = intel_overlay_map_regs_atomic(overlay); 77302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!regs) { 77402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -ENOMEM; 77502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unpin; 77602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 77702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 77802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DWINPOS = (params->dst_y << 16) | params->dst_x; 77902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->DWINSZ = (params->dst_h << 16) | params->dst_w; 78002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 78102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->format & I915_OVERLAY_YUV_PACKED) 78202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp_width = packed_width_bytes(params->format, params->src_w); 78302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 78402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp_width = params->src_w; 78502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 78602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SWIDTH = params->src_w; 78702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SWIDTHSW = calc_swidthsw(overlay->dev, 78802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->offset_Y, tmp_width); 78902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SHEIGHT = params->src_h; 79002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y; 79102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OSTRIDE = params->stride_Y; 79202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 79302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->format & I915_OVERLAY_YUV_PLANAR) { 79402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_hscale = uv_hsubsampling(params->format); 79502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_vscale = uv_vsubsampling(params->format); 79602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 tmp_U, tmp_V; 79702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SWIDTH |= (params->src_w/uv_hscale) << 16; 79802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp_U = calc_swidthsw(overlay->dev, params->offset_U, 79902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_w/uv_hscale); 80002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp_V = calc_swidthsw(overlay->dev, params->offset_V, 80102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_w/uv_hscale); 80202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16; 80302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; 80402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U; 80502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OBUF_0V = bo_priv->gtt_offset + params->offset_V; 80602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OSTRIDE |= params->stride_UV << 16; 80702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 80802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 80902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter scale_changed = update_scaling_factors(overlay, regs, params); 81002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 81102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_colorkey(overlay, regs); 81202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 81302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCMD = overlay_cmd_reg(params); 81402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 81502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter intel_overlay_unmap_regs_atomic(overlay); 81602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 81702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter intel_overlay_continue(overlay, scale_changed); 81802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 81902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->old_vid_bo = overlay->vid_bo; 82023010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter overlay->vid_bo = to_intel_bo(new_bo); 82102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 82202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 82302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 82402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unpin: 82502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter i915_gem_object_unpin(new_bo); 82602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 82702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 82802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 82902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_switch_off(struct intel_overlay *overlay) 83002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 83102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 83202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 83302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 83402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 83502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!mutex_is_locked(&dev->struct_mutex)); 83602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); 83702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 8389bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter if (overlay->hw_wedged) { 8399bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter ret = intel_overlay_recover_from_interrupt(overlay, 1); 8409bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter if (ret != 0) 8419bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter return ret; 8429bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter } 8439bedb9743fd906e4160468663ee6e1bbdc4412b8Daniel Vetter 84402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay->active) 84502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 84602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 84702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_release_old_vid(overlay); 84802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 84902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 85002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 85102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs = intel_overlay_map_regs_atomic(overlay); 85202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCMD = 0; 85302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter intel_overlay_unmap_regs_atomic(overlay); 85402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 85502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_off(overlay); 85603f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 85703f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter return ret; 85803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 85912ca45fea91cfbb09df828bea958b47348caee6dDaniel Vetter intel_overlay_off_tail(overlay); 86002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 86102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 86202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 86302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 86402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_possible_on_crtc(struct intel_overlay *overlay, 86502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_crtc *crtc) 86602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 86702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = overlay->dev->dev_private; 86802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 pipeconf; 86902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF; 87002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 87102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON) 87202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 87302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 87402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter pipeconf = I915_READ(pipeconf_reg); 87502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 87602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* can't use the overlay with double wide pipe */ 87702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!IS_I965G(overlay->dev) && pipeconf & PIPEACONF_DOUBLE_WIDE) 87802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 87902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 88002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 88102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 88202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 88302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_pfit_vscale_ratio(struct intel_overlay *overlay) 88402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 88502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_device *dev = overlay->dev; 88602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 88702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 ratio; 88802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 pfit_control = I915_READ(PFIT_CONTROL); 88902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 89002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* XXX: This is not the same logic as in the xorg driver, but more in 89102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * line with the intel documentation for the i965 */ 89202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!IS_I965G(dev) && (pfit_control & VERT_AUTO_SCALE)) { 89302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ratio = I915_READ(PFIT_AUTO_RATIOS) >> PFIT_VERT_SCALE_SHIFT; 89402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { /* on i965 use the PGM reg to read out the autoscaler values */ 89502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ratio = I915_READ(PFIT_PGM_RATIOS); 89602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I965G(dev)) 89702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ratio >>= PFIT_VERT_SCALE_SHIFT_965; 89802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 89902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ratio >>= PFIT_VERT_SCALE_SHIFT; 90002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 90102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 90202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->pfit_vscale_ratio = ratio; 90302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 90402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 90502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_dst(struct intel_overlay *overlay, 90602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_intel_overlay_put_image *rec) 90702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 90802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_display_mode *mode = &overlay->crtc->base.mode; 90902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 91002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if ((rec->dst_x < mode->crtc_hdisplay) 91102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter && (rec->dst_x + rec->dst_width 91202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter <= mode->crtc_hdisplay) 91302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter && (rec->dst_y < mode->crtc_vdisplay) 91402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter && (rec->dst_y + rec->dst_height 91502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter <= mode->crtc_vdisplay)) 91602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 91702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter else 91802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 91902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 92002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 92102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_scaling(struct put_image_params *rec) 92202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 92302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 tmp; 92402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 92502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* downscaling limit is 8.0 */ 92602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16; 92702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (tmp > 7) 92802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 92902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16; 93002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (tmp > 7) 93102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 93202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 93302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 93402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 93502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 93602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_overlay_src(struct drm_device *dev, 93702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_intel_overlay_put_image *rec, 93802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_gem_object *new_bo) 93902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 94002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter u32 stride_mask; 94102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int depth; 94202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_hscale = uv_hsubsampling(rec->flags); 94302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int uv_vscale = uv_vsubsampling(rec->flags); 94402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter size_t tmp; 94502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 94602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* check src dimensions */ 94702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_845G(dev) || IS_I830(dev)) { 94802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY 94902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || rec->src_width > IMAGE_MAX_WIDTH_LEGACY) 95002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 95102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 95202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->src_height > IMAGE_MAX_HEIGHT 95302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || rec->src_width > IMAGE_MAX_WIDTH) 95402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 95502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 95602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* better safe than sorry, use 4 as the maximal subsampling ratio */ 95702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->src_height < N_VERT_Y_TAPS*4 95802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || rec->src_width < N_HORIZ_Y_TAPS*4) 95902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 96002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 961a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson /* check alignment constraints */ 96202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (rec->flags & I915_OVERLAY_TYPE_MASK) { 96302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_RGB: 96402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* not implemented */ 96502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 96602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV_PACKED: 96702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter depth = packed_depth_bytes(rec->flags); 96802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (uv_vscale != 1) 96902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 97002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (depth < 0) 97102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return depth; 97202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* ignore UV planes */ 97302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter rec->stride_UV = 0; 97402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter rec->offset_U = 0; 97502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter rec->offset_V = 0; 97602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* check pixel alignment */ 97702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->offset_Y % depth) 97802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 97902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 98002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV_PLANAR: 98102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (uv_vscale < 0 || uv_hscale < 0) 98202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 98302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* no offset restrictions for planar formats */ 98402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 98502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter default: 98602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 98702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 98802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 98902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->src_width % uv_hscale) 99002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 99102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 99202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* stride checking */ 993a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson if (IS_I830(dev) || IS_845G(dev)) 994a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson stride_mask = 255; 995a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson else 996a1efd14a99483a4fb9308902397ed86b69454c99Chris Wilson stride_mask = 63; 99702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 99802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) 99902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 100002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I965G(dev) && rec->stride_Y < 512) 100102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 100202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 100302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ? 100402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 4 : 8; 100502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->stride_Y > tmp*1024 || rec->stride_UV > 2*1024) 100602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 100702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 100802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* check buffer dimensions */ 100902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter switch (rec->flags & I915_OVERLAY_TYPE_MASK) { 101002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_RGB: 101102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV_PACKED: 101202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* always 4 Y values per depth pixels */ 101302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (packed_width_bytes(rec->flags, rec->src_width) 101402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter > rec->stride_Y) 101502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 101602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 101702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = rec->stride_Y*rec->src_height; 101802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->offset_Y + tmp > new_bo->size) 101902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 102002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 102102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_OVERLAY_YUV_PLANAR: 102202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->src_width > rec->stride_Y) 102302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 102402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->src_width/uv_hscale > rec->stride_UV) 102502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 102602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 102702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = rec->stride_Y*rec->src_height; 102802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->offset_Y + tmp > new_bo->size) 102902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 103002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp = rec->stride_UV*rec->src_height; 103102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter tmp /= uv_vscale; 103202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (rec->offset_U + tmp > new_bo->size 103302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || rec->offset_V + tmp > new_bo->size) 103402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 103502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 103602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 103702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 103802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 103902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 104002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 104102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_put_image(struct drm_device *dev, void *data, 104202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_file *file_priv) 104302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 104402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_intel_overlay_put_image *put_image_rec = data; 104502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 104602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_overlay *overlay; 104702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_mode_object *drmmode_obj; 104802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_crtc *crtc; 104902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_gem_object *new_bo; 105002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct put_image_params *params; 105102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 105202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 105302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!dev_priv) { 105402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_ERROR("called with no initialization\n"); 105502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 105602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 105702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 105802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay = dev_priv->overlay; 105902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay) { 106002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_DEBUG("userspace bug: no overlay\n"); 106102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -ENODEV; 106202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 106302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 106402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) { 106502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->mode_config.mutex); 106602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->struct_mutex); 106702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 106802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_switch_off(overlay); 106902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 107002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->struct_mutex); 107102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->mode_config.mutex); 107202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 107302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 107402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 107502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 107602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL); 107702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!params) 107802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -ENOMEM; 107902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 108002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id, 108102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_MODE_OBJECT_CRTC); 1082915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter if (!drmmode_obj) { 1083915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter ret = -ENOENT; 1084915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter goto out_free; 1085915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter } 108602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); 108702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 108802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter new_bo = drm_gem_object_lookup(dev, file_priv, 108902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter put_image_rec->bo_handle); 1090915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter if (!new_bo) { 1091915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter ret = -ENOENT; 1092915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter goto out_free; 1093915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenter } 109402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 109502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->mode_config.mutex); 109602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->struct_mutex); 109702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 109803f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (overlay->hw_wedged) { 109903f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter ret = intel_overlay_recover_from_interrupt(overlay, 1); 110003f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter if (ret != 0) 110103f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter goto out_unlock; 110203f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter } 110303f77ea5972e6a2363152aec692744cac824dabaDaniel Vetter 110402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (overlay->crtc != crtc) { 110502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_display_mode *mode = &crtc->base.mode; 110602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_switch_off(overlay); 110702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 110802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 110902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 111002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_overlay_possible_on_crtc(overlay, crtc); 111102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 111202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 111302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 111402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->crtc = crtc; 111502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter crtc->overlay = overlay; 111602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 111702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (intel_panel_fitter_pipe(dev) == crtc->pipe 111802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* and line to wide, i.e. one-line-mode */ 111902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter && mode->hdisplay > 1024) { 112002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->pfit_active = 1; 112102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_pfit_vscale_ratio(overlay); 112202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else 112302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->pfit_active = 0; 112402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 112502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 112602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_overlay_dst(overlay, put_image_rec); 112702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 112802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 112902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 113002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (overlay->pfit_active) { 113102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_y = ((((u32)put_image_rec->dst_y) << 12) / 113202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->pfit_vscale_ratio); 113302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* shifting right rounds downwards, so add 1 */ 113402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_h = ((((u32)put_image_rec->dst_height) << 12) / 113502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->pfit_vscale_ratio) + 1; 113602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 113702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_y = put_image_rec->dst_y; 113802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_h = put_image_rec->dst_height; 113902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 114002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_x = put_image_rec->dst_x; 114102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->dst_w = put_image_rec->dst_width; 114202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 114302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_w = put_image_rec->src_width; 114402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_h = put_image_rec->src_height; 114502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_scan_w = put_image_rec->src_scan_width; 114602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->src_scan_h = put_image_rec->src_scan_height; 114702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (params->src_scan_h > params->src_h 114802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || params->src_scan_w > params->src_w) { 114902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -EINVAL; 115002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 115102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 115202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 115302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_overlay_src(dev, put_image_rec, new_bo); 115402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 115502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 115602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK; 115702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->stride_Y = put_image_rec->stride_Y; 115802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->stride_UV = put_image_rec->stride_UV; 115902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->offset_Y = put_image_rec->offset_Y; 116002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->offset_U = put_image_rec->offset_U; 116102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter params->offset_V = put_image_rec->offset_V; 116202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 116302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* Check scaling after src size to prevent a divide-by-zero. */ 116402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_overlay_scaling(params); 116502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 116602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 116702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 116802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = intel_overlay_do_put_image(overlay, new_bo, params); 116902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 117002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 117102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 117202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->struct_mutex); 117302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->mode_config.mutex); 117402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 117502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter kfree(params); 117602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 117702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 117802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 117902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unlock: 118002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->struct_mutex); 118102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->mode_config.mutex); 1182bc9025bdc4e2b591734cca17697093845007b63dLuca Barbieri drm_gem_object_unreference_unlocked(new_bo); 1183915a428e43acfd05e4ffeaf40549b0cf163eebe2Dan Carpenterout_free: 118402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter kfree(params); 118502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 118602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 118702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 118802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 118902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic void update_reg_attrs(struct intel_overlay *overlay, 119002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs) 119102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 119202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff); 119302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs->OCLRC1 = overlay->saturation; 119402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 119502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 119602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool check_gamma_bounds(u32 gamma1, u32 gamma2) 119702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 119802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int i; 119902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 120002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (gamma1 & 0xff000000 || gamma2 & 0xff000000) 120102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return false; 120202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 120302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter for (i = 0; i < 3; i++) { 120402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (((gamma1 >> i * 8) & 0xff) >= ((gamma2 >> i*8) & 0xff)) 120502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return false; 120602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 120702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 120802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return true; 120902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 121002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 121102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic bool check_gamma5_errata(u32 gamma5) 121202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 121302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int i; 121402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 121502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter for (i = 0; i < 3; i++) { 121602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (((gamma5 >> i*8) & 0xff) == 0x80) 121702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return false; 121802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 121902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 122002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return true; 122102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 122202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 122302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterstatic int check_gamma(struct drm_intel_overlay_attrs *attrs) 122402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 122502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!check_gamma_bounds(0, attrs->gamma0) 122602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || !check_gamma_bounds(attrs->gamma0, attrs->gamma1) 122702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || !check_gamma_bounds(attrs->gamma1, attrs->gamma2) 122802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || !check_gamma_bounds(attrs->gamma2, attrs->gamma3) 122902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || !check_gamma_bounds(attrs->gamma3, attrs->gamma4) 123002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || !check_gamma_bounds(attrs->gamma4, attrs->gamma5) 123102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter || !check_gamma_bounds(attrs->gamma5, 0x00ffffff)) 123202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 123302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!check_gamma5_errata(attrs->gamma5)) 123402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 123502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return 0; 123602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 123702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 123802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterint intel_overlay_attrs(struct drm_device *dev, void *data, 123902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_file *file_priv) 124002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 124102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_intel_overlay_attrs *attrs = data; 124202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 124302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_overlay *overlay; 124402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 124502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 124602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 124702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!dev_priv) { 124802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_ERROR("called with no initialization\n"); 124902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -EINVAL; 125002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 125102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 125202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay = dev_priv->overlay; 125302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay) { 125402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_DEBUG("userspace bug: no overlay\n"); 125502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return -ENODEV; 125602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 125702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 125802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->mode_config.mutex); 125902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_lock(&dev->struct_mutex); 126002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 126102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) { 126202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->color_key = overlay->color_key; 126302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->brightness = overlay->brightness; 126402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->contrast = overlay->contrast; 126502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->saturation = overlay->saturation; 126602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 126702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (IS_I9XX(dev)) { 126802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma0 = I915_READ(OGAMC0); 126902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma1 = I915_READ(OGAMC1); 127002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma2 = I915_READ(OGAMC2); 127102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma3 = I915_READ(OGAMC3); 127202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma4 = I915_READ(OGAMC4); 127302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter attrs->gamma5 = I915_READ(OGAMC5); 127402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 127502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = 0; 127602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 127702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->color_key = attrs->color_key; 127802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (attrs->brightness >= -128 && attrs->brightness <= 127) { 127902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->brightness = attrs->brightness; 128002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 128102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -EINVAL; 128202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 128302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 128402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (attrs->contrast <= 255) { 128502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->contrast = attrs->contrast; 128602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 128702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -EINVAL; 128802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 128902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 129002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (attrs->saturation <= 1023) { 129102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->saturation = attrs->saturation; 129202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 129302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -EINVAL; 129402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 129502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 129602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 129702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs = intel_overlay_map_regs_atomic(overlay); 129802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!regs) { 129902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -ENOMEM; 130002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 130102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 130202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 130302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_reg_attrs(overlay, regs); 130402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 130502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter intel_overlay_unmap_regs_atomic(overlay); 130602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 130702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { 130802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!IS_I9XX(dev)) { 130902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -EINVAL; 131002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 131102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 131202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 131302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (overlay->active) { 131402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = -EBUSY; 131502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 131602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 131702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 131802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = check_gamma(attrs); 131902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret != 0) 132002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_unlock; 132102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 132202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC0, attrs->gamma0); 132302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC1, attrs->gamma1); 132402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC2, attrs->gamma2); 132502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC3, attrs->gamma3); 132602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC4, attrs->gamma4); 132702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_WRITE(OGAMC5, attrs->gamma5); 132802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 132902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = 0; 133002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 133102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 133202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_unlock: 133302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->struct_mutex); 133402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter mutex_unlock(&dev->mode_config.mutex); 133502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 133602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return ret; 133702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 133802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 133902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vettervoid intel_setup_overlay(struct drm_device *dev) 134002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 134102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 134202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct intel_overlay *overlay; 134302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct drm_gem_object *reg_bo; 134402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter struct overlay_registers *regs; 134502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter int ret; 134602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 134702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!OVERLAY_EXISTS(dev)) 134802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return; 134902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 135002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); 135102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!overlay) 135202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return; 135302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->dev = dev; 135402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 1355ac52bc56de25535a907ef07f8755f1387b89b0f5Daniel Vetter reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); 135602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!reg_bo) 135702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_free; 135823010e43b353c2cdc9725cbedc7e364708039bf7Daniel Vetter overlay->reg_bo = to_intel_bo(reg_bo); 135902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 136002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (OVERLAY_NONPHYSICAL(dev)) { 136102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); 136202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret) { 136302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_ERROR("failed to pin overlay register bo\n"); 136402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_free_bo; 136502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 136602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->flip_addr = overlay->reg_bo->gtt_offset; 136702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } else { 136802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter ret = i915_gem_attach_phys_object(dev, reg_bo, 136902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter I915_GEM_PHYS_OVERLAY_REGS); 137002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (ret) { 137102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_ERROR("failed to attach phys overlay regs\n"); 137202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_free_bo; 137302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 137402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; 137502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 137602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 137702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* init all values */ 137802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->color_key = 0x0101fe; 137902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->brightness = -19; 138002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->contrast = 75; 138102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter overlay->saturation = 146; 138202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 138302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter regs = intel_overlay_map_regs_atomic(overlay); 138402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (!regs) 138502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter goto out_free_bo; 138602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 138702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter memset(regs, 0, sizeof(struct overlay_registers)); 138802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_polyphase_filter(regs); 138902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 139002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter update_reg_attrs(overlay, regs); 139102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 139202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter intel_overlay_unmap_regs_atomic(overlay); 139302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 139402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter dev_priv->overlay = overlay; 139502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter DRM_INFO("initialized overlay support\n"); 139602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return; 139702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 139802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_free_bo: 139902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_gem_object_unreference(reg_bo); 140002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetterout_free: 140102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter kfree(overlay); 140202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter return; 140302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 140402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 140502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vettervoid intel_cleanup_overlay(struct drm_device *dev) 140602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter{ 140702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter drm_i915_private_t *dev_priv = dev->dev_private; 140802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 140902e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter if (dev_priv->overlay) { 141002e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter /* The bo's should be free'd by the generic code already. 141102e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * Furthermore modesetting teardown happens beforehand so the 141202e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter * hardware should be off already */ 141302e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter BUG_ON(dev_priv->overlay->active); 141402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 141502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter kfree(dev_priv->overlay); 141602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter } 141702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter} 1418