Linux Audio

Check our new training course

Loading...
v3.1
   1/*
   2 * Copyright © 2009
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 * SOFTWARE.
  22 *
  23 * Authors:
  24 *    Daniel Vetter <daniel@ffwll.ch>
  25 *
  26 * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
  27 */
  28
  29#include <linux/seq_file.h>
  30#include "drmP.h"
  31#include "drm.h"
  32#include "i915_drm.h"
  33#include "i915_drv.h"
  34#include "i915_reg.h"
  35#include "intel_drv.h"
 
  36
  37/* Limits for overlay size. According to intel doc, the real limits are:
  38 * Y width: 4095, UV width (planar): 2047, Y height: 2047,
  39 * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
  40 * the mininum of both.  */
  41#define IMAGE_MAX_WIDTH		2048
  42#define IMAGE_MAX_HEIGHT	2046 /* 2 * 1023 */
  43/* on 830 and 845 these large limits result in the card hanging */
  44#define IMAGE_MAX_WIDTH_LEGACY	1024
  45#define IMAGE_MAX_HEIGHT_LEGACY	1088
  46
  47/* overlay register definitions */
  48/* OCMD register */
  49#define OCMD_TILED_SURFACE	(0x1<<19)
  50#define OCMD_MIRROR_MASK	(0x3<<17)
  51#define OCMD_MIRROR_MODE	(0x3<<17)
  52#define OCMD_MIRROR_HORIZONTAL	(0x1<<17)
  53#define OCMD_MIRROR_VERTICAL	(0x2<<17)
  54#define OCMD_MIRROR_BOTH	(0x3<<17)
  55#define OCMD_BYTEORDER_MASK	(0x3<<14) /* zero for YUYV or FOURCC YUY2 */
  56#define OCMD_UV_SWAP		(0x1<<14) /* YVYU */
  57#define OCMD_Y_SWAP		(0x2<<14) /* UYVY or FOURCC UYVY */
  58#define OCMD_Y_AND_UV_SWAP	(0x3<<14) /* VYUY */
  59#define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
  60#define OCMD_RGB_888		(0x1<<10) /* not in i965 Intel docs */
  61#define OCMD_RGB_555		(0x2<<10) /* not in i965 Intel docs */
  62#define OCMD_RGB_565		(0x3<<10) /* not in i965 Intel docs */
  63#define OCMD_YUV_422_PACKED	(0x8<<10)
  64#define OCMD_YUV_411_PACKED	(0x9<<10) /* not in i965 Intel docs */
  65#define OCMD_YUV_420_PLANAR	(0xc<<10)
  66#define OCMD_YUV_422_PLANAR	(0xd<<10)
  67#define OCMD_YUV_410_PLANAR	(0xe<<10) /* also 411 */
  68#define OCMD_TVSYNCFLIP_PARITY	(0x1<<9)
  69#define OCMD_TVSYNCFLIP_ENABLE	(0x1<<7)
  70#define OCMD_BUF_TYPE_MASK	(0x1<<5)
  71#define OCMD_BUF_TYPE_FRAME	(0x0<<5)
  72#define OCMD_BUF_TYPE_FIELD	(0x1<<5)
  73#define OCMD_TEST_MODE		(0x1<<4)
  74#define OCMD_BUFFER_SELECT	(0x3<<2)
  75#define OCMD_BUFFER0		(0x0<<2)
  76#define OCMD_BUFFER1		(0x1<<2)
  77#define OCMD_FIELD_SELECT	(0x1<<2)
  78#define OCMD_FIELD0		(0x0<<1)
  79#define OCMD_FIELD1		(0x1<<1)
  80#define OCMD_ENABLE		(0x1<<0)
  81
  82/* OCONFIG register */
  83#define OCONF_PIPE_MASK		(0x1<<18)
  84#define OCONF_PIPE_A		(0x0<<18)
  85#define OCONF_PIPE_B		(0x1<<18)
  86#define OCONF_GAMMA2_ENABLE	(0x1<<16)
  87#define OCONF_CSC_MODE_BT601	(0x0<<5)
  88#define OCONF_CSC_MODE_BT709	(0x1<<5)
  89#define OCONF_CSC_BYPASS	(0x1<<4)
  90#define OCONF_CC_OUT_8BIT	(0x1<<3)
  91#define OCONF_TEST_MODE		(0x1<<2)
  92#define OCONF_THREE_LINE_BUFFER	(0x1<<0)
  93#define OCONF_TWO_LINE_BUFFER	(0x0<<0)
  94
  95/* DCLRKM (dst-key) register */
  96#define DST_KEY_ENABLE		(0x1<<31)
  97#define CLK_RGB24_MASK		0x0
  98#define CLK_RGB16_MASK		0x070307
  99#define CLK_RGB15_MASK		0x070707
 100#define CLK_RGB8I_MASK		0xffffff
 101
 102#define RGB16_TO_COLORKEY(c) \
 103	(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
 104#define RGB15_TO_COLORKEY(c) \
 105	(((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
 106
 107/* overlay flip addr flag */
 108#define OFC_UPDATE		0x1
 109
 110/* polyphase filter coefficients */
 111#define N_HORIZ_Y_TAPS          5
 112#define N_VERT_Y_TAPS           3
 113#define N_HORIZ_UV_TAPS         3
 114#define N_VERT_UV_TAPS          3
 115#define N_PHASES                17
 116#define MAX_TAPS                5
 117
 118/* memory bufferd overlay registers */
 119struct overlay_registers {
 120    u32 OBUF_0Y;
 121    u32 OBUF_1Y;
 122    u32 OBUF_0U;
 123    u32 OBUF_0V;
 124    u32 OBUF_1U;
 125    u32 OBUF_1V;
 126    u32 OSTRIDE;
 127    u32 YRGB_VPH;
 128    u32 UV_VPH;
 129    u32 HORZ_PH;
 130    u32 INIT_PHS;
 131    u32 DWINPOS;
 132    u32 DWINSZ;
 133    u32 SWIDTH;
 134    u32 SWIDTHSW;
 135    u32 SHEIGHT;
 136    u32 YRGBSCALE;
 137    u32 UVSCALE;
 138    u32 OCLRC0;
 139    u32 OCLRC1;
 140    u32 DCLRKV;
 141    u32 DCLRKM;
 142    u32 SCLRKVH;
 143    u32 SCLRKVL;
 144    u32 SCLRKEN;
 145    u32 OCONFIG;
 146    u32 OCMD;
 147    u32 RESERVED1; /* 0x6C */
 148    u32 OSTART_0Y;
 149    u32 OSTART_1Y;
 150    u32 OSTART_0U;
 151    u32 OSTART_0V;
 152    u32 OSTART_1U;
 153    u32 OSTART_1V;
 154    u32 OTILEOFF_0Y;
 155    u32 OTILEOFF_1Y;
 156    u32 OTILEOFF_0U;
 157    u32 OTILEOFF_0V;
 158    u32 OTILEOFF_1U;
 159    u32 OTILEOFF_1V;
 160    u32 FASTHSCALE; /* 0xA0 */
 161    u32 UVSCALEV; /* 0xA4 */
 162    u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
 163    u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
 164    u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
 165    u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
 166    u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
 167    u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
 168    u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
 169    u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
 170    u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
 171};
 172
 173struct intel_overlay {
 174	struct drm_device *dev;
 175	struct intel_crtc *crtc;
 176	struct drm_i915_gem_object *vid_bo;
 177	struct drm_i915_gem_object *old_vid_bo;
 178	int active;
 179	int pfit_active;
 180	u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
 181	u32 color_key;
 
 182	u32 brightness, contrast, saturation;
 183	u32 old_xscale, old_yscale;
 184	/* register access */
 185	u32 flip_addr;
 186	struct drm_i915_gem_object *reg_bo;
 187	/* flip handling */
 188	uint32_t last_flip_req;
 189	void (*flip_tail)(struct intel_overlay *);
 190};
 191
 192static struct overlay_registers *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 193intel_overlay_map_regs(struct intel_overlay *overlay)
 194{
 195        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 196	struct overlay_registers *regs;
 197
 198	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
 199		regs = overlay->reg_bo->phys_obj->handle->vaddr;
 200	else
 201		regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping,
 202					 overlay->reg_bo->gtt_offset);
 
 203
 204	return regs;
 205}
 206
 207static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
 208				     struct overlay_registers *regs)
 209{
 210	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
 211		io_mapping_unmap(regs);
 212}
 213
 
 
 
 
 
 
 
 
 
 
 
 
 214static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
 215					 struct drm_i915_gem_request *request,
 216					 void (*tail)(struct intel_overlay *))
 217{
 218	struct drm_device *dev = overlay->dev;
 219	drm_i915_private_t *dev_priv = dev->dev_private;
 220	int ret;
 
 221
 222	BUG_ON(overlay->last_flip_req);
 223	ret = i915_add_request(LP_RING(dev_priv), NULL, request);
 224	if (ret) {
 225	    kfree(request);
 226	    return ret;
 227	}
 228	overlay->last_flip_req = request->seqno;
 229	overlay->flip_tail = tail;
 230	ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req);
 231	if (ret)
 232		return ret;
 233
 234	overlay->last_flip_req = 0;
 235	return 0;
 236}
 237
 238/* Workaround for i830 bug where pipe a must be enable to change control regs */
 239static int
 240i830_activate_pipe_a(struct drm_device *dev)
 241{
 242	drm_i915_private_t *dev_priv = dev->dev_private;
 243	struct intel_crtc *crtc;
 244	struct drm_crtc_helper_funcs *crtc_funcs;
 245	struct drm_display_mode vesa_640x480 = {
 246		DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
 247			 752, 800, 0, 480, 489, 492, 525, 0,
 248			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
 249	}, *mode;
 250
 251	crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]);
 252	if (crtc->dpms_mode == DRM_MODE_DPMS_ON)
 253		return 0;
 254
 255	/* most i8xx have pipe a forced on, so don't trust dpms mode */
 256	if (I915_READ(_PIPEACONF) & PIPECONF_ENABLE)
 257		return 0;
 258
 259	crtc_funcs = crtc->base.helper_private;
 260	if (crtc_funcs->dpms == NULL)
 261		return 0;
 262
 263	DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n");
 264
 265	mode = drm_mode_duplicate(dev, &vesa_640x480);
 266	drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
 267	if(!drm_crtc_helper_set_mode(&crtc->base, mode,
 268				       crtc->base.x, crtc->base.y,
 269				       crtc->base.fb))
 270		return 0;
 271
 272	crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON);
 273	return 1;
 274}
 275
 276static void
 277i830_deactivate_pipe_a(struct drm_device *dev)
 278{
 279	drm_i915_private_t *dev_priv = dev->dev_private;
 280	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
 281	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 282
 283	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
 284}
 285
 286/* overlay needs to be disable in OCMD reg */
 287static int intel_overlay_on(struct intel_overlay *overlay)
 288{
 289	struct drm_device *dev = overlay->dev;
 290	struct drm_i915_private *dev_priv = dev->dev_private;
 291	struct drm_i915_gem_request *request;
 292	int pipe_a_quirk = 0;
 293	int ret;
 294
 295	BUG_ON(overlay->active);
 296	overlay->active = 1;
 297
 298	if (IS_I830(dev)) {
 299		pipe_a_quirk = i830_activate_pipe_a(dev);
 300		if (pipe_a_quirk < 0)
 301			return pipe_a_quirk;
 302	}
 303
 304	request = kzalloc(sizeof(*request), GFP_KERNEL);
 305	if (request == NULL) {
 306		ret = -ENOMEM;
 307		goto out;
 308	}
 309
 310	ret = BEGIN_LP_RING(4);
 311	if (ret) {
 312		kfree(request);
 313		goto out;
 314	}
 315
 316	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
 317	OUT_RING(overlay->flip_addr | OFC_UPDATE);
 318	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 319	OUT_RING(MI_NOOP);
 320	ADVANCE_LP_RING();
 321
 322	ret = intel_overlay_do_wait_request(overlay, request, NULL);
 323out:
 324	if (pipe_a_quirk)
 325		i830_deactivate_pipe_a(dev);
 326
 327	return ret;
 328}
 329
 330/* overlay needs to be enabled in OCMD reg */
 331static int intel_overlay_continue(struct intel_overlay *overlay,
 
 332				  bool load_polyphase_filter)
 333{
 334	struct drm_device *dev = overlay->dev;
 335        drm_i915_private_t *dev_priv = dev->dev_private;
 336	struct drm_i915_gem_request *request;
 337	u32 flip_addr = overlay->flip_addr;
 338	u32 tmp;
 339	int ret;
 340
 341	BUG_ON(!overlay->active);
 342
 343	request = kzalloc(sizeof(*request), GFP_KERNEL);
 344	if (request == NULL)
 345		return -ENOMEM;
 346
 347	if (load_polyphase_filter)
 348		flip_addr |= OFC_UPDATE;
 349
 350	/* check for underruns */
 351	tmp = I915_READ(DOVSTA);
 352	if (tmp & (1 << 17))
 353		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
 354
 355	ret = BEGIN_LP_RING(2);
 356	if (ret) {
 357		kfree(request);
 358		return ret;
 359	}
 360	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
 361	OUT_RING(flip_addr);
 362        ADVANCE_LP_RING();
 363
 364	ret = i915_add_request(LP_RING(dev_priv), NULL, request);
 365	if (ret) {
 366		kfree(request);
 367		return ret;
 368	}
 369
 370	overlay->last_flip_req = request->seqno;
 
 
 
 
 
 
 
 371	return 0;
 372}
 373
 374static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
 375{
 376	struct drm_i915_gem_object *obj = overlay->old_vid_bo;
 377
 378	i915_gem_object_unpin(obj);
 379	drm_gem_object_unreference(&obj->base);
 
 380
 381	overlay->old_vid_bo = NULL;
 
 
 
 
 382}
 383
 384static void intel_overlay_off_tail(struct intel_overlay *overlay)
 
 385{
 386	struct drm_i915_gem_object *obj = overlay->vid_bo;
 
 387
 388	/* never have the overlay hw on without showing a frame */
 389	BUG_ON(!overlay->vid_bo);
 390
 391	i915_gem_object_unpin(obj);
 392	drm_gem_object_unreference(&obj->base);
 393	overlay->vid_bo = NULL;
 
 
 
 
 
 394
 395	overlay->crtc->overlay = NULL;
 396	overlay->crtc = NULL;
 397	overlay->active = 0;
 
 
 
 398}
 399
 400/* overlay needs to be disabled in OCMD reg */
 401static int intel_overlay_off(struct intel_overlay *overlay)
 402{
 403	struct drm_device *dev = overlay->dev;
 404	struct drm_i915_private *dev_priv = dev->dev_private;
 405	u32 flip_addr = overlay->flip_addr;
 406	struct drm_i915_gem_request *request;
 407	int ret;
 408
 409	BUG_ON(!overlay->active);
 410
 411	request = kzalloc(sizeof(*request), GFP_KERNEL);
 412	if (request == NULL)
 413		return -ENOMEM;
 414
 415	/* According to intel docs the overlay hw may hang (when switching
 416	 * off) without loading the filter coeffs. It is however unclear whether
 417	 * this applies to the disabling of the overlay or to the switching off
 418	 * of the hw. Do it in both cases */
 419	flip_addr |= OFC_UPDATE;
 420
 421	ret = BEGIN_LP_RING(6);
 422	if (ret) {
 423		kfree(request);
 424		return ret;
 
 
 
 
 425	}
 
 426	/* wait for overlay to go idle */
 427	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
 428	OUT_RING(flip_addr);
 429	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 
 430	/* turn overlay off */
 431	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
 432	OUT_RING(flip_addr);
 433	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 434	ADVANCE_LP_RING();
 
 
 
 435
 436	return intel_overlay_do_wait_request(overlay, request,
 437					     intel_overlay_off_tail);
 438}
 439
 440/* recover from an interruption due to a signal
 441 * We have to be careful not to repeat work forever an make forward progess. */
 442static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
 443{
 444	struct drm_device *dev = overlay->dev;
 445	drm_i915_private_t *dev_priv = dev->dev_private;
 446	int ret;
 447
 448	if (overlay->last_flip_req == 0)
 449		return 0;
 450
 451	ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req);
 452	if (ret)
 453		return ret;
 454
 455	if (overlay->flip_tail)
 456		overlay->flip_tail(overlay);
 457
 458	overlay->last_flip_req = 0;
 459	return 0;
 460}
 461
 462/* Wait for pending overlay flip and release old frame.
 463 * Needs to be called before the overlay register are changed
 464 * via intel_overlay_(un)map_regs
 465 */
 466static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
 467{
 468	struct drm_device *dev = overlay->dev;
 469	drm_i915_private_t *dev_priv = dev->dev_private;
 470	int ret;
 471
 
 
 472	/* Only wait if there is actually an old frame to release to
 473	 * guarantee forward progress.
 474	 */
 475	if (!overlay->old_vid_bo)
 476		return 0;
 477
 478	if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
 479		struct drm_i915_gem_request *request;
 480
 481		/* synchronous slowpath */
 482		request = kzalloc(sizeof(*request), GFP_KERNEL);
 483		if (request == NULL)
 484			return -ENOMEM;
 485
 486		ret = BEGIN_LP_RING(2);
 487		if (ret) {
 488			kfree(request);
 489			return ret;
 
 
 
 
 490		}
 491
 492		OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 493		OUT_RING(MI_NOOP);
 494		ADVANCE_LP_RING();
 495
 496		ret = intel_overlay_do_wait_request(overlay, request,
 497						    intel_overlay_release_old_vid_tail);
 498		if (ret)
 499			return ret;
 500	}
 
 501
 502	intel_overlay_release_old_vid_tail(overlay);
 503	return 0;
 504}
 505
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 506struct put_image_params {
 507	int format;
 508	short dst_x;
 509	short dst_y;
 510	short dst_w;
 511	short dst_h;
 512	short src_w;
 513	short src_scan_h;
 514	short src_scan_w;
 515	short src_h;
 516	short stride_Y;
 517	short stride_UV;
 518	int offset_Y;
 519	int offset_U;
 520	int offset_V;
 521};
 522
 523static int packed_depth_bytes(u32 format)
 524{
 525	switch (format & I915_OVERLAY_DEPTH_MASK) {
 526	case I915_OVERLAY_YUV422:
 527		return 4;
 528	case I915_OVERLAY_YUV411:
 529		/* return 6; not implemented */
 530	default:
 531		return -EINVAL;
 532	}
 533}
 534
 535static int packed_width_bytes(u32 format, short width)
 536{
 537	switch (format & I915_OVERLAY_DEPTH_MASK) {
 538	case I915_OVERLAY_YUV422:
 539		return width << 1;
 540	default:
 541		return -EINVAL;
 542	}
 543}
 544
 545static int uv_hsubsampling(u32 format)
 546{
 547	switch (format & I915_OVERLAY_DEPTH_MASK) {
 548	case I915_OVERLAY_YUV422:
 549	case I915_OVERLAY_YUV420:
 550		return 2;
 551	case I915_OVERLAY_YUV411:
 552	case I915_OVERLAY_YUV410:
 553		return 4;
 554	default:
 555		return -EINVAL;
 556	}
 557}
 558
 559static int uv_vsubsampling(u32 format)
 560{
 561	switch (format & I915_OVERLAY_DEPTH_MASK) {
 562	case I915_OVERLAY_YUV420:
 563	case I915_OVERLAY_YUV410:
 564		return 2;
 565	case I915_OVERLAY_YUV422:
 566	case I915_OVERLAY_YUV411:
 567		return 1;
 568	default:
 569		return -EINVAL;
 570	}
 571}
 572
 573static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
 574{
 575	u32 mask, shift, ret;
 576	if (IS_GEN2(dev)) {
 577		mask = 0x1f;
 578		shift = 5;
 579	} else {
 580		mask = 0x3f;
 581		shift = 6;
 582	}
 583	ret = ((offset + width + mask) >> shift) - (offset >> shift);
 584	if (!IS_GEN2(dev))
 585		ret <<= 1;
 586	ret -=1;
 587	return ret << 2;
 588}
 589
 590static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
 591	0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
 592	0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
 593	0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
 594	0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
 595	0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
 596	0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
 597	0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
 598	0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
 599	0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
 600	0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
 601	0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
 602	0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
 603	0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
 604	0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
 605	0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
 606	0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
 607	0xb000, 0x3000, 0x0800, 0x3000, 0xb000
 608};
 609
 610static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
 611	0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
 612	0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
 613	0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
 614	0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
 615	0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
 616	0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
 617	0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
 618	0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
 619	0x3000, 0x0800, 0x3000
 
 
 
 
 
 
 
 
 620};
 621
 622static void update_polyphase_filter(struct overlay_registers *regs)
 623{
 624	memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
 625	memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
 
 626}
 627
 628static bool update_scaling_factors(struct intel_overlay *overlay,
 629				   struct overlay_registers *regs,
 630				   struct put_image_params *params)
 631{
 632	/* fixed point with a 12 bit shift */
 633	u32 xscale, yscale, xscale_UV, yscale_UV;
 634#define FP_SHIFT 12
 635#define FRACT_MASK 0xfff
 636	bool scale_changed = false;
 637	int uv_hscale = uv_hsubsampling(params->format);
 638	int uv_vscale = uv_vsubsampling(params->format);
 639
 640	if (params->dst_w > 1)
 641		xscale = ((params->src_scan_w - 1) << FP_SHIFT)
 642			/(params->dst_w);
 643	else
 644		xscale = 1 << FP_SHIFT;
 645
 646	if (params->dst_h > 1)
 647		yscale = ((params->src_scan_h - 1) << FP_SHIFT)
 648			/(params->dst_h);
 649	else
 650		yscale = 1 << FP_SHIFT;
 651
 652	/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
 653	xscale_UV = xscale/uv_hscale;
 654	yscale_UV = yscale/uv_vscale;
 655	/* make the Y scale to UV scale ratio an exact multiply */
 656	xscale = xscale_UV * uv_hscale;
 657	yscale = yscale_UV * uv_vscale;
 658	/*} else {
 659	  xscale_UV = 0;
 660	  yscale_UV = 0;
 661	  }*/
 662
 663	if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
 664		scale_changed = true;
 665	overlay->old_xscale = xscale;
 666	overlay->old_yscale = yscale;
 667
 668	regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) |
 669			   ((xscale >> FP_SHIFT)  << 16) |
 670			   ((xscale & FRACT_MASK) << 3));
 671
 672	regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) |
 673			 ((xscale_UV >> FP_SHIFT)  << 16) |
 674			 ((xscale_UV & FRACT_MASK) << 3));
 675
 676	regs->UVSCALEV = ((((yscale    >> FP_SHIFT) << 16) |
 677			   ((yscale_UV >> FP_SHIFT) << 0)));
 
 
 
 678
 679	if (scale_changed)
 680		update_polyphase_filter(regs);
 681
 682	return scale_changed;
 683}
 684
 685static void update_colorkey(struct intel_overlay *overlay,
 686			    struct overlay_registers *regs)
 687{
 
 
 688	u32 key = overlay->color_key;
 
 
 689
 690	switch (overlay->crtc->base.fb->bits_per_pixel) {
 691	case 8:
 692		regs->DCLRKV = 0;
 693		regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
 694		break;
 695
 696	case 16:
 697		if (overlay->crtc->base.fb->depth == 15) {
 698			regs->DCLRKV = RGB15_TO_COLORKEY(key);
 699			regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
 700		} else {
 701			regs->DCLRKV = RGB16_TO_COLORKEY(key);
 702			regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
 703		}
 704		break;
 705
 706	case 24:
 707	case 32:
 708		regs->DCLRKV = key;
 709		regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
 
 
 
 
 
 
 
 
 
 
 
 710		break;
 711	}
 
 
 
 712}
 713
 714static u32 overlay_cmd_reg(struct put_image_params *params)
 715{
 716	u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
 717
 718	if (params->format & I915_OVERLAY_YUV_PLANAR) {
 719		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
 720		case I915_OVERLAY_YUV422:
 721			cmd |= OCMD_YUV_422_PLANAR;
 722			break;
 723		case I915_OVERLAY_YUV420:
 724			cmd |= OCMD_YUV_420_PLANAR;
 725			break;
 726		case I915_OVERLAY_YUV411:
 727		case I915_OVERLAY_YUV410:
 728			cmd |= OCMD_YUV_410_PLANAR;
 729			break;
 730		}
 731	} else { /* YUV packed */
 732		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
 733		case I915_OVERLAY_YUV422:
 734			cmd |= OCMD_YUV_422_PACKED;
 735			break;
 736		case I915_OVERLAY_YUV411:
 737			cmd |= OCMD_YUV_411_PACKED;
 738			break;
 739		}
 740
 741		switch (params->format & I915_OVERLAY_SWAP_MASK) {
 742		case I915_OVERLAY_NO_SWAP:
 743			break;
 744		case I915_OVERLAY_UV_SWAP:
 745			cmd |= OCMD_UV_SWAP;
 746			break;
 747		case I915_OVERLAY_Y_SWAP:
 748			cmd |= OCMD_Y_SWAP;
 749			break;
 750		case I915_OVERLAY_Y_AND_UV_SWAP:
 751			cmd |= OCMD_Y_AND_UV_SWAP;
 752			break;
 753		}
 754	}
 755
 756	return cmd;
 757}
 758
 759static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 760				      struct drm_i915_gem_object *new_bo,
 761				      struct put_image_params *params)
 762{
 763	int ret, tmp_width;
 764	struct overlay_registers *regs;
 765	bool scale_changed = false;
 766	struct drm_device *dev = overlay->dev;
 
 
 
 767
 768	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 769	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 770	BUG_ON(!overlay);
 771
 772	ret = intel_overlay_release_old_vid(overlay);
 773	if (ret != 0)
 774		return ret;
 775
 776	ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL);
 777	if (ret != 0)
 778		return ret;
 779
 780	ret = i915_gem_object_put_fence(new_bo);
 
 
 
 
 
 
 
 781	if (ret)
 782		goto out_unpin;
 783
 784	if (!overlay->active) {
 
 785		regs = intel_overlay_map_regs(overlay);
 786		if (!regs) {
 787			ret = -ENOMEM;
 788			goto out_unpin;
 789		}
 790		regs->OCONFIG = OCONF_CC_OUT_8BIT;
 791		if (IS_GEN4(overlay->dev))
 792			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
 793		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
 794			OCONF_PIPE_A : OCONF_PIPE_B;
 
 795		intel_overlay_unmap_regs(overlay, regs);
 796
 797		ret = intel_overlay_on(overlay);
 798		if (ret != 0)
 799			goto out_unpin;
 800	}
 801
 802	regs = intel_overlay_map_regs(overlay);
 803	if (!regs) {
 804		ret = -ENOMEM;
 805		goto out_unpin;
 806	}
 807
 808	regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
 809	regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
 810
 811	if (params->format & I915_OVERLAY_YUV_PACKED)
 812		tmp_width = packed_width_bytes(params->format, params->src_w);
 813	else
 814		tmp_width = params->src_w;
 815
 816	regs->SWIDTH = params->src_w;
 817	regs->SWIDTHSW = calc_swidthsw(overlay->dev,
 818				       params->offset_Y, tmp_width);
 819	regs->SHEIGHT = params->src_h;
 820	regs->OBUF_0Y = new_bo->gtt_offset + params-> offset_Y;
 821	regs->OSTRIDE = params->stride_Y;
 822
 823	if (params->format & I915_OVERLAY_YUV_PLANAR) {
 824		int uv_hscale = uv_hsubsampling(params->format);
 825		int uv_vscale = uv_vsubsampling(params->format);
 826		u32 tmp_U, tmp_V;
 827		regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
 828		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
 829				      params->src_w/uv_hscale);
 830		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
 831				      params->src_w/uv_hscale);
 832		regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
 833		regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
 834		regs->OBUF_0U = new_bo->gtt_offset + params->offset_U;
 835		regs->OBUF_0V = new_bo->gtt_offset + params->offset_V;
 836		regs->OSTRIDE |= params->stride_UV << 16;
 
 
 837	}
 838
 
 
 
 
 
 839	scale_changed = update_scaling_factors(overlay, regs, params);
 840
 841	update_colorkey(overlay, regs);
 842
 843	regs->OCMD = overlay_cmd_reg(params);
 844
 845	intel_overlay_unmap_regs(overlay, regs);
 846
 847	ret = intel_overlay_continue(overlay, scale_changed);
 848	if (ret)
 849		goto out_unpin;
 850
 851	overlay->old_vid_bo = overlay->vid_bo;
 852	overlay->vid_bo = new_bo;
 853
 854	return 0;
 855
 856out_unpin:
 857	i915_gem_object_unpin(new_bo);
 
 
 
 858	return ret;
 859}
 860
 861int intel_overlay_switch_off(struct intel_overlay *overlay)
 862{
 863	struct overlay_registers *regs;
 864	struct drm_device *dev = overlay->dev;
 865	int ret;
 866
 867	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 868	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 869
 870	ret = intel_overlay_recover_from_interrupt(overlay);
 871	if (ret != 0)
 872		return ret;
 873
 874	if (!overlay->active)
 875		return 0;
 876
 877	ret = intel_overlay_release_old_vid(overlay);
 878	if (ret != 0)
 879		return ret;
 880
 881	regs = intel_overlay_map_regs(overlay);
 882	regs->OCMD = 0;
 883	intel_overlay_unmap_regs(overlay, regs);
 884
 885	ret = intel_overlay_off(overlay);
 886	if (ret != 0)
 887		return ret;
 888
 889	intel_overlay_off_tail(overlay);
 890	return 0;
 891}
 892
 893static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
 894					  struct intel_crtc *crtc)
 895{
 896	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 897
 898	if (!crtc->active)
 899		return -EINVAL;
 900
 901	/* can't use the overlay with double wide pipe */
 902	if (INTEL_INFO(overlay->dev)->gen < 4 &&
 903	    (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE)
 904		return -EINVAL;
 905
 906	return 0;
 907}
 908
 909static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
 910{
 911	struct drm_device *dev = overlay->dev;
 912	drm_i915_private_t *dev_priv = dev->dev_private;
 913	u32 pfit_control = I915_READ(PFIT_CONTROL);
 914	u32 ratio;
 915
 916	/* XXX: This is not the same logic as in the xorg driver, but more in
 917	 * line with the intel documentation for the i965
 918	 */
 919	if (INTEL_INFO(dev)->gen >= 4) {
 920	       	/* on i965 use the PGM reg to read out the autoscaler values */
 921		ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
 922	} else {
 923		if (pfit_control & VERT_AUTO_SCALE)
 924			ratio = I915_READ(PFIT_AUTO_RATIOS);
 925		else
 926			ratio = I915_READ(PFIT_PGM_RATIOS);
 927		ratio >>= PFIT_VERT_SCALE_SHIFT;
 928	}
 929
 930	overlay->pfit_vscale_ratio = ratio;
 931}
 932
 933static int check_overlay_dst(struct intel_overlay *overlay,
 934			     struct drm_intel_overlay_put_image *rec)
 935{
 936	struct drm_display_mode *mode = &overlay->crtc->base.mode;
 
 937
 938	if (rec->dst_x < mode->crtc_hdisplay &&
 939	    rec->dst_x + rec->dst_width <= mode->crtc_hdisplay &&
 940	    rec->dst_y < mode->crtc_vdisplay &&
 941	    rec->dst_y + rec->dst_height <= mode->crtc_vdisplay)
 942		return 0;
 943	else
 944		return -EINVAL;
 945}
 946
 947static int check_overlay_scaling(struct put_image_params *rec)
 948{
 949	u32 tmp;
 950
 951	/* downscaling limit is 8.0 */
 952	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
 953	if (tmp > 7)
 954		return -EINVAL;
 955	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
 956	if (tmp > 7)
 957		return -EINVAL;
 958
 959	return 0;
 960}
 961
 962static int check_overlay_src(struct drm_device *dev,
 963			     struct drm_intel_overlay_put_image *rec,
 964			     struct drm_i915_gem_object *new_bo)
 965{
 966	int uv_hscale = uv_hsubsampling(rec->flags);
 967	int uv_vscale = uv_vsubsampling(rec->flags);
 968	u32 stride_mask;
 969	int depth;
 970	u32 tmp;
 971
 972	/* check src dimensions */
 973	if (IS_845G(dev) || IS_I830(dev)) {
 974		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
 975		    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
 976			return -EINVAL;
 977	} else {
 978		if (rec->src_height > IMAGE_MAX_HEIGHT ||
 979		    rec->src_width  > IMAGE_MAX_WIDTH)
 980			return -EINVAL;
 981	}
 982
 983	/* better safe than sorry, use 4 as the maximal subsampling ratio */
 984	if (rec->src_height < N_VERT_Y_TAPS*4 ||
 985	    rec->src_width  < N_HORIZ_Y_TAPS*4)
 986		return -EINVAL;
 987
 988	/* check alignment constraints */
 989	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
 990	case I915_OVERLAY_RGB:
 991		/* not implemented */
 992		return -EINVAL;
 993
 994	case I915_OVERLAY_YUV_PACKED:
 995		if (uv_vscale != 1)
 996			return -EINVAL;
 997
 998		depth = packed_depth_bytes(rec->flags);
 999		if (depth < 0)
1000			return depth;
1001
1002		/* ignore UV planes */
1003		rec->stride_UV = 0;
1004		rec->offset_U = 0;
1005		rec->offset_V = 0;
1006		/* check pixel alignment */
1007		if (rec->offset_Y % depth)
1008			return -EINVAL;
1009		break;
1010
1011	case I915_OVERLAY_YUV_PLANAR:
1012		if (uv_vscale < 0 || uv_hscale < 0)
1013			return -EINVAL;
1014		/* no offset restrictions for planar formats */
1015		break;
1016
1017	default:
1018		return -EINVAL;
1019	}
1020
1021	if (rec->src_width % uv_hscale)
1022		return -EINVAL;
1023
1024	/* stride checking */
1025	if (IS_I830(dev) || IS_845G(dev))
1026		stride_mask = 255;
1027	else
1028		stride_mask = 63;
1029
1030	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
1031		return -EINVAL;
1032	if (IS_GEN4(dev) && rec->stride_Y < 512)
1033		return -EINVAL;
1034
1035	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
1036		4096 : 8192;
1037	if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
1038		return -EINVAL;
1039
1040	/* check buffer dimensions */
1041	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1042	case I915_OVERLAY_RGB:
1043	case I915_OVERLAY_YUV_PACKED:
1044		/* always 4 Y values per depth pixels */
1045		if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1046			return -EINVAL;
1047
1048		tmp = rec->stride_Y*rec->src_height;
1049		if (rec->offset_Y + tmp > new_bo->base.size)
1050			return -EINVAL;
1051		break;
1052
1053	case I915_OVERLAY_YUV_PLANAR:
1054		if (rec->src_width > rec->stride_Y)
1055			return -EINVAL;
1056		if (rec->src_width/uv_hscale > rec->stride_UV)
1057			return -EINVAL;
1058
1059		tmp = rec->stride_Y * rec->src_height;
1060		if (rec->offset_Y + tmp > new_bo->base.size)
1061			return -EINVAL;
1062
1063		tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1064		if (rec->offset_U + tmp > new_bo->base.size ||
1065		    rec->offset_V + tmp > new_bo->base.size)
1066			return -EINVAL;
1067		break;
1068	}
1069
1070	return 0;
1071}
1072
1073/**
1074 * Return the pipe currently connected to the panel fitter,
1075 * or -1 if the panel fitter is not present or not in use
1076 */
1077static int intel_panel_fitter_pipe(struct drm_device *dev)
1078{
1079	struct drm_i915_private *dev_priv = dev->dev_private;
1080	u32  pfit_control;
1081
1082	/* i830 doesn't have a panel fitter */
1083	if (IS_I830(dev))
1084		return -1;
1085
1086	pfit_control = I915_READ(PFIT_CONTROL);
1087
1088	/* See if the panel fitter is in use */
1089	if ((pfit_control & PFIT_ENABLE) == 0)
1090		return -1;
1091
1092	/* 965 can place panel fitter on either pipe */
1093	if (IS_GEN4(dev))
1094		return (pfit_control >> 29) & 0x3;
1095
1096	/* older chips can only use pipe 1 */
1097	return 1;
1098}
1099
1100int intel_overlay_put_image(struct drm_device *dev, void *data,
1101                            struct drm_file *file_priv)
1102{
1103	struct drm_intel_overlay_put_image *put_image_rec = data;
1104	drm_i915_private_t *dev_priv = dev->dev_private;
1105	struct intel_overlay *overlay;
1106	struct drm_mode_object *drmmode_obj;
1107	struct intel_crtc *crtc;
1108	struct drm_i915_gem_object *new_bo;
1109	struct put_image_params *params;
1110	int ret;
1111
1112	if (!dev_priv) {
1113		DRM_ERROR("called with no initialization\n");
1114		return -EINVAL;
1115	}
1116
1117	overlay = dev_priv->overlay;
1118	if (!overlay) {
1119		DRM_DEBUG("userspace bug: no overlay\n");
1120		return -ENODEV;
1121	}
1122
1123	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
1124		mutex_lock(&dev->mode_config.mutex);
1125		mutex_lock(&dev->struct_mutex);
1126
1127		ret = intel_overlay_switch_off(overlay);
1128
1129		mutex_unlock(&dev->struct_mutex);
1130		mutex_unlock(&dev->mode_config.mutex);
1131
1132		return ret;
1133	}
1134
1135	params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
1136	if (!params)
1137		return -ENOMEM;
1138
1139	drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
1140					   DRM_MODE_OBJECT_CRTC);
1141	if (!drmmode_obj) {
1142		ret = -ENOENT;
1143		goto out_free;
1144	}
1145	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
1146
1147	new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
1148						   put_image_rec->bo_handle));
1149	if (&new_bo->base == NULL) {
1150		ret = -ENOENT;
1151		goto out_free;
1152	}
1153
1154	mutex_lock(&dev->mode_config.mutex);
1155	mutex_lock(&dev->struct_mutex);
1156
1157	if (new_bo->tiling_mode) {
1158		DRM_ERROR("buffer used for overlay image can not be tiled\n");
1159		ret = -EINVAL;
1160		goto out_unlock;
1161	}
1162
1163	ret = intel_overlay_recover_from_interrupt(overlay);
1164	if (ret != 0)
1165		goto out_unlock;
1166
1167	if (overlay->crtc != crtc) {
1168		struct drm_display_mode *mode = &crtc->base.mode;
1169		ret = intel_overlay_switch_off(overlay);
1170		if (ret != 0)
1171			goto out_unlock;
1172
1173		ret = check_overlay_possible_on_crtc(overlay, crtc);
1174		if (ret != 0)
1175			goto out_unlock;
1176
1177		overlay->crtc = crtc;
1178		crtc->overlay = overlay;
1179
1180		/* line too wide, i.e. one-line-mode */
1181		if (mode->hdisplay > 1024 &&
1182		    intel_panel_fitter_pipe(dev) == crtc->pipe) {
1183			overlay->pfit_active = 1;
1184			update_pfit_vscale_ratio(overlay);
1185		} else
1186			overlay->pfit_active = 0;
1187	}
1188
1189	ret = check_overlay_dst(overlay, put_image_rec);
1190	if (ret != 0)
1191		goto out_unlock;
1192
1193	if (overlay->pfit_active) {
1194		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1195				 overlay->pfit_vscale_ratio);
1196		/* shifting right rounds downwards, so add 1 */
1197		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1198				 overlay->pfit_vscale_ratio) + 1;
1199	} else {
1200		params->dst_y = put_image_rec->dst_y;
1201		params->dst_h = put_image_rec->dst_height;
1202	}
1203	params->dst_x = put_image_rec->dst_x;
1204	params->dst_w = put_image_rec->dst_width;
1205
1206	params->src_w = put_image_rec->src_width;
1207	params->src_h = put_image_rec->src_height;
1208	params->src_scan_w = put_image_rec->src_scan_width;
1209	params->src_scan_h = put_image_rec->src_scan_height;
1210	if (params->src_scan_h > params->src_h ||
1211	    params->src_scan_w > params->src_w) {
1212		ret = -EINVAL;
1213		goto out_unlock;
1214	}
1215
1216	ret = check_overlay_src(dev, put_image_rec, new_bo);
1217	if (ret != 0)
1218		goto out_unlock;
1219	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
1220	params->stride_Y = put_image_rec->stride_Y;
1221	params->stride_UV = put_image_rec->stride_UV;
1222	params->offset_Y = put_image_rec->offset_Y;
1223	params->offset_U = put_image_rec->offset_U;
1224	params->offset_V = put_image_rec->offset_V;
1225
1226	/* Check scaling after src size to prevent a divide-by-zero. */
1227	ret = check_overlay_scaling(params);
1228	if (ret != 0)
1229		goto out_unlock;
1230
1231	ret = intel_overlay_do_put_image(overlay, new_bo, params);
1232	if (ret != 0)
1233		goto out_unlock;
1234
1235	mutex_unlock(&dev->struct_mutex);
1236	mutex_unlock(&dev->mode_config.mutex);
 
1237
1238	kfree(params);
1239
1240	return 0;
1241
1242out_unlock:
1243	mutex_unlock(&dev->struct_mutex);
1244	mutex_unlock(&dev->mode_config.mutex);
1245	drm_gem_object_unreference_unlocked(&new_bo->base);
1246out_free:
1247	kfree(params);
1248
1249	return ret;
1250}
1251
1252static void update_reg_attrs(struct intel_overlay *overlay,
1253			     struct overlay_registers *regs)
1254{
1255	regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
1256	regs->OCLRC1 = overlay->saturation;
 
1257}
1258
1259static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1260{
1261	int i;
1262
1263	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1264		return false;
1265
1266	for (i = 0; i < 3; i++) {
1267		if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1268			return false;
1269	}
1270
1271	return true;
1272}
1273
1274static bool check_gamma5_errata(u32 gamma5)
1275{
1276	int i;
1277
1278	for (i = 0; i < 3; i++) {
1279		if (((gamma5 >> i*8) & 0xff) == 0x80)
1280			return false;
1281	}
1282
1283	return true;
1284}
1285
1286static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1287{
1288	if (!check_gamma_bounds(0, attrs->gamma0) ||
1289	    !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1290	    !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1291	    !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1292	    !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1293	    !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1294	    !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
1295		return -EINVAL;
1296
1297	if (!check_gamma5_errata(attrs->gamma5))
1298		return -EINVAL;
1299
1300	return 0;
1301}
1302
1303int intel_overlay_attrs(struct drm_device *dev, void *data,
1304                        struct drm_file *file_priv)
1305{
1306	struct drm_intel_overlay_attrs *attrs = data;
1307        drm_i915_private_t *dev_priv = dev->dev_private;
1308	struct intel_overlay *overlay;
1309	struct overlay_registers *regs;
1310	int ret;
1311
1312	if (!dev_priv) {
1313		DRM_ERROR("called with no initialization\n");
1314		return -EINVAL;
1315	}
1316
1317	overlay = dev_priv->overlay;
1318	if (!overlay) {
1319		DRM_DEBUG("userspace bug: no overlay\n");
1320		return -ENODEV;
1321	}
1322
1323	mutex_lock(&dev->mode_config.mutex);
1324	mutex_lock(&dev->struct_mutex);
1325
1326	ret = -EINVAL;
1327	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
1328		attrs->color_key  = overlay->color_key;
1329		attrs->brightness = overlay->brightness;
1330		attrs->contrast   = overlay->contrast;
1331		attrs->saturation = overlay->saturation;
1332
1333		if (!IS_GEN2(dev)) {
1334			attrs->gamma0 = I915_READ(OGAMC0);
1335			attrs->gamma1 = I915_READ(OGAMC1);
1336			attrs->gamma2 = I915_READ(OGAMC2);
1337			attrs->gamma3 = I915_READ(OGAMC3);
1338			attrs->gamma4 = I915_READ(OGAMC4);
1339			attrs->gamma5 = I915_READ(OGAMC5);
1340		}
1341	} else {
1342		if (attrs->brightness < -128 || attrs->brightness > 127)
1343			goto out_unlock;
1344		if (attrs->contrast > 255)
1345			goto out_unlock;
1346		if (attrs->saturation > 1023)
1347			goto out_unlock;
1348
1349		overlay->color_key  = attrs->color_key;
1350		overlay->brightness = attrs->brightness;
1351		overlay->contrast   = attrs->contrast;
1352		overlay->saturation = attrs->saturation;
1353
1354		regs = intel_overlay_map_regs(overlay);
1355		if (!regs) {
1356			ret = -ENOMEM;
1357			goto out_unlock;
1358		}
1359
1360		update_reg_attrs(overlay, regs);
1361
1362		intel_overlay_unmap_regs(overlay, regs);
1363
1364		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
1365			if (IS_GEN2(dev))
1366				goto out_unlock;
1367
1368			if (overlay->active) {
1369				ret = -EBUSY;
1370				goto out_unlock;
1371			}
1372
1373			ret = check_gamma(attrs);
1374			if (ret)
1375				goto out_unlock;
1376
1377			I915_WRITE(OGAMC0, attrs->gamma0);
1378			I915_WRITE(OGAMC1, attrs->gamma1);
1379			I915_WRITE(OGAMC2, attrs->gamma2);
1380			I915_WRITE(OGAMC3, attrs->gamma3);
1381			I915_WRITE(OGAMC4, attrs->gamma4);
1382			I915_WRITE(OGAMC5, attrs->gamma5);
1383		}
1384	}
 
1385
1386	ret = 0;
1387out_unlock:
1388	mutex_unlock(&dev->struct_mutex);
1389	mutex_unlock(&dev->mode_config.mutex);
1390
1391	return ret;
1392}
1393
1394void intel_setup_overlay(struct drm_device *dev)
1395{
1396        drm_i915_private_t *dev_priv = dev->dev_private;
1397	struct intel_overlay *overlay;
1398	struct drm_i915_gem_object *reg_bo;
1399	struct overlay_registers *regs;
 
1400	int ret;
1401
1402	if (!HAS_OVERLAY(dev))
1403		return;
1404
1405	overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
1406	if (!overlay)
1407		return;
1408
1409	mutex_lock(&dev->struct_mutex);
1410	if (WARN_ON(dev_priv->overlay))
1411		goto out_free;
1412
1413	overlay->dev = dev;
1414
1415	reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
1416	if (!reg_bo)
 
 
 
 
1417		goto out_free;
1418	overlay->reg_bo = reg_bo;
1419
1420	if (OVERLAY_NEEDS_PHYSICAL(dev)) {
1421		ret = i915_gem_attach_phys_object(dev, reg_bo,
1422						  I915_GEM_PHYS_OVERLAY_REGS,
1423						  PAGE_SIZE);
1424                if (ret) {
1425                        DRM_ERROR("failed to attach phys overlay regs\n");
1426                        goto out_free_bo;
1427                }
1428		overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
1429	} else {
1430		ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true);
1431		if (ret) {
1432                        DRM_ERROR("failed to pin overlay register bo\n");
1433                        goto out_free_bo;
1434                }
1435		overlay->flip_addr = reg_bo->gtt_offset;
 
 
 
 
 
 
 
 
 
1436
1437		ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1438		if (ret) {
1439                        DRM_ERROR("failed to move overlay register bo into the GTT\n");
1440                        goto out_unpin_bo;
1441                }
1442	}
1443
1444	/* init all values */
1445	overlay->color_key = 0x0101fe;
 
1446	overlay->brightness = -19;
1447	overlay->contrast = 75;
1448	overlay->saturation = 146;
1449
 
 
1450	regs = intel_overlay_map_regs(overlay);
1451	if (!regs)
1452		goto out_unpin_bo;
1453
1454	memset(regs, 0, sizeof(struct overlay_registers));
1455	update_polyphase_filter(regs);
1456	update_reg_attrs(overlay, regs);
1457
1458	intel_overlay_unmap_regs(overlay, regs);
1459
1460	dev_priv->overlay = overlay;
1461	mutex_unlock(&dev->struct_mutex);
1462	DRM_INFO("initialized overlay support\n");
1463	return;
1464
1465out_unpin_bo:
1466	if (!OVERLAY_NEEDS_PHYSICAL(dev))
1467		i915_gem_object_unpin(reg_bo);
1468out_free_bo:
1469	drm_gem_object_unreference(&reg_bo->base);
1470out_free:
1471	mutex_unlock(&dev->struct_mutex);
1472	kfree(overlay);
1473	return;
1474}
1475
1476void intel_cleanup_overlay(struct drm_device *dev)
1477{
1478	drm_i915_private_t *dev_priv = dev->dev_private;
1479
1480	if (!dev_priv->overlay)
1481		return;
1482
1483	/* The bo's should be free'd by the generic code already.
1484	 * Furthermore modesetting teardown happens beforehand so the
1485	 * hardware should be off already */
1486	BUG_ON(dev_priv->overlay->active);
1487
1488	drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
1489	kfree(dev_priv->overlay);
1490}
1491
1492#ifdef CONFIG_DEBUG_FS
1493#include <linux/seq_file.h>
1494
1495struct intel_overlay_error_state {
1496	struct overlay_registers regs;
1497	unsigned long base;
1498	u32 dovsta;
1499	u32 isr;
1500};
1501
1502static struct overlay_registers *
1503intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
1504{
1505	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
1506	struct overlay_registers *regs;
1507
1508	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1509		regs = overlay->reg_bo->phys_obj->handle->vaddr;
 
 
 
1510	else
1511		regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
1512						overlay->reg_bo->gtt_offset);
1513
1514	return regs;
1515}
1516
1517static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
1518					    struct overlay_registers *regs)
1519{
1520	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1521		io_mapping_unmap_atomic(regs);
1522}
1523
1524
1525struct intel_overlay_error_state *
1526intel_overlay_capture_error_state(struct drm_device *dev)
1527{
1528        drm_i915_private_t *dev_priv = dev->dev_private;
1529	struct intel_overlay *overlay = dev_priv->overlay;
1530	struct intel_overlay_error_state *error;
1531	struct overlay_registers __iomem *regs;
1532
1533	if (!overlay || !overlay->active)
1534		return NULL;
1535
1536	error = kmalloc(sizeof(*error), GFP_ATOMIC);
1537	if (error == NULL)
1538		return NULL;
1539
1540	error->dovsta = I915_READ(DOVSTA);
1541	error->isr = I915_READ(ISR);
1542	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1543		error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
1544	else
1545		error->base = (long) overlay->reg_bo->gtt_offset;
1546
1547	regs = intel_overlay_map_regs_atomic(overlay);
1548	if (!regs)
1549		goto err;
1550
1551	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
1552	intel_overlay_unmap_regs_atomic(overlay, regs);
1553
1554	return error;
1555
1556err:
1557	kfree(error);
1558	return NULL;
1559}
1560
1561void
1562intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
 
1563{
1564	seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1565		   error->dovsta, error->isr);
1566	seq_printf(m, "  Register file at 0x%08lx:\n",
1567		   error->base);
1568
1569#define P(x) seq_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
1570	P(OBUF_0Y);
1571	P(OBUF_1Y);
1572	P(OBUF_0U);
1573	P(OBUF_0V);
1574	P(OBUF_1U);
1575	P(OBUF_1V);
1576	P(OSTRIDE);
1577	P(YRGB_VPH);
1578	P(UV_VPH);
1579	P(HORZ_PH);
1580	P(INIT_PHS);
1581	P(DWINPOS);
1582	P(DWINSZ);
1583	P(SWIDTH);
1584	P(SWIDTHSW);
1585	P(SHEIGHT);
1586	P(YRGBSCALE);
1587	P(UVSCALE);
1588	P(OCLRC0);
1589	P(OCLRC1);
1590	P(DCLRKV);
1591	P(DCLRKM);
1592	P(SCLRKVH);
1593	P(SCLRKVL);
1594	P(SCLRKEN);
1595	P(OCONFIG);
1596	P(OCMD);
1597	P(OSTART_0Y);
1598	P(OSTART_1Y);
1599	P(OSTART_0U);
1600	P(OSTART_0V);
1601	P(OSTART_1U);
1602	P(OSTART_1V);
1603	P(OTILEOFF_0Y);
1604	P(OTILEOFF_1Y);
1605	P(OTILEOFF_0U);
1606	P(OTILEOFF_0V);
1607	P(OTILEOFF_1U);
1608	P(OTILEOFF_1V);
1609	P(FASTHSCALE);
1610	P(UVSCALEV);
1611#undef P
1612}
 
1613#endif
v4.17
   1/*
   2 * Copyright © 2009
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 * SOFTWARE.
  22 *
  23 * Authors:
  24 *    Daniel Vetter <daniel@ffwll.ch>
  25 *
  26 * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
  27 */
  28#include <drm/drmP.h>
  29#include <drm/i915_drm.h>
 
 
 
  30#include "i915_drv.h"
  31#include "i915_reg.h"
  32#include "intel_drv.h"
  33#include "intel_frontbuffer.h"
  34
  35/* Limits for overlay size. According to intel doc, the real limits are:
  36 * Y width: 4095, UV width (planar): 2047, Y height: 2047,
  37 * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
  38 * the mininum of both.  */
  39#define IMAGE_MAX_WIDTH		2048
  40#define IMAGE_MAX_HEIGHT	2046 /* 2 * 1023 */
  41/* on 830 and 845 these large limits result in the card hanging */
  42#define IMAGE_MAX_WIDTH_LEGACY	1024
  43#define IMAGE_MAX_HEIGHT_LEGACY	1088
  44
  45/* overlay register definitions */
  46/* OCMD register */
  47#define OCMD_TILED_SURFACE	(0x1<<19)
  48#define OCMD_MIRROR_MASK	(0x3<<17)
  49#define OCMD_MIRROR_MODE	(0x3<<17)
  50#define OCMD_MIRROR_HORIZONTAL	(0x1<<17)
  51#define OCMD_MIRROR_VERTICAL	(0x2<<17)
  52#define OCMD_MIRROR_BOTH	(0x3<<17)
  53#define OCMD_BYTEORDER_MASK	(0x3<<14) /* zero for YUYV or FOURCC YUY2 */
  54#define OCMD_UV_SWAP		(0x1<<14) /* YVYU */
  55#define OCMD_Y_SWAP		(0x2<<14) /* UYVY or FOURCC UYVY */
  56#define OCMD_Y_AND_UV_SWAP	(0x3<<14) /* VYUY */
  57#define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
  58#define OCMD_RGB_888		(0x1<<10) /* not in i965 Intel docs */
  59#define OCMD_RGB_555		(0x2<<10) /* not in i965 Intel docs */
  60#define OCMD_RGB_565		(0x3<<10) /* not in i965 Intel docs */
  61#define OCMD_YUV_422_PACKED	(0x8<<10)
  62#define OCMD_YUV_411_PACKED	(0x9<<10) /* not in i965 Intel docs */
  63#define OCMD_YUV_420_PLANAR	(0xc<<10)
  64#define OCMD_YUV_422_PLANAR	(0xd<<10)
  65#define OCMD_YUV_410_PLANAR	(0xe<<10) /* also 411 */
  66#define OCMD_TVSYNCFLIP_PARITY	(0x1<<9)
  67#define OCMD_TVSYNCFLIP_ENABLE	(0x1<<7)
  68#define OCMD_BUF_TYPE_MASK	(0x1<<5)
  69#define OCMD_BUF_TYPE_FRAME	(0x0<<5)
  70#define OCMD_BUF_TYPE_FIELD	(0x1<<5)
  71#define OCMD_TEST_MODE		(0x1<<4)
  72#define OCMD_BUFFER_SELECT	(0x3<<2)
  73#define OCMD_BUFFER0		(0x0<<2)
  74#define OCMD_BUFFER1		(0x1<<2)
  75#define OCMD_FIELD_SELECT	(0x1<<2)
  76#define OCMD_FIELD0		(0x0<<1)
  77#define OCMD_FIELD1		(0x1<<1)
  78#define OCMD_ENABLE		(0x1<<0)
  79
  80/* OCONFIG register */
  81#define OCONF_PIPE_MASK		(0x1<<18)
  82#define OCONF_PIPE_A		(0x0<<18)
  83#define OCONF_PIPE_B		(0x1<<18)
  84#define OCONF_GAMMA2_ENABLE	(0x1<<16)
  85#define OCONF_CSC_MODE_BT601	(0x0<<5)
  86#define OCONF_CSC_MODE_BT709	(0x1<<5)
  87#define OCONF_CSC_BYPASS	(0x1<<4)
  88#define OCONF_CC_OUT_8BIT	(0x1<<3)
  89#define OCONF_TEST_MODE		(0x1<<2)
  90#define OCONF_THREE_LINE_BUFFER	(0x1<<0)
  91#define OCONF_TWO_LINE_BUFFER	(0x0<<0)
  92
  93/* DCLRKM (dst-key) register */
  94#define DST_KEY_ENABLE		(0x1<<31)
  95#define CLK_RGB24_MASK		0x0
  96#define CLK_RGB16_MASK		0x070307
  97#define CLK_RGB15_MASK		0x070707
  98#define CLK_RGB8I_MASK		0xffffff
  99
 100#define RGB16_TO_COLORKEY(c) \
 101	(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
 102#define RGB15_TO_COLORKEY(c) \
 103	(((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
 104
 105/* overlay flip addr flag */
 106#define OFC_UPDATE		0x1
 107
 108/* polyphase filter coefficients */
 109#define N_HORIZ_Y_TAPS          5
 110#define N_VERT_Y_TAPS           3
 111#define N_HORIZ_UV_TAPS         3
 112#define N_VERT_UV_TAPS          3
 113#define N_PHASES                17
 114#define MAX_TAPS                5
 115
 116/* memory bufferd overlay registers */
 117struct overlay_registers {
 118	u32 OBUF_0Y;
 119	u32 OBUF_1Y;
 120	u32 OBUF_0U;
 121	u32 OBUF_0V;
 122	u32 OBUF_1U;
 123	u32 OBUF_1V;
 124	u32 OSTRIDE;
 125	u32 YRGB_VPH;
 126	u32 UV_VPH;
 127	u32 HORZ_PH;
 128	u32 INIT_PHS;
 129	u32 DWINPOS;
 130	u32 DWINSZ;
 131	u32 SWIDTH;
 132	u32 SWIDTHSW;
 133	u32 SHEIGHT;
 134	u32 YRGBSCALE;
 135	u32 UVSCALE;
 136	u32 OCLRC0;
 137	u32 OCLRC1;
 138	u32 DCLRKV;
 139	u32 DCLRKM;
 140	u32 SCLRKVH;
 141	u32 SCLRKVL;
 142	u32 SCLRKEN;
 143	u32 OCONFIG;
 144	u32 OCMD;
 145	u32 RESERVED1; /* 0x6C */
 146	u32 OSTART_0Y;
 147	u32 OSTART_1Y;
 148	u32 OSTART_0U;
 149	u32 OSTART_0V;
 150	u32 OSTART_1U;
 151	u32 OSTART_1V;
 152	u32 OTILEOFF_0Y;
 153	u32 OTILEOFF_1Y;
 154	u32 OTILEOFF_0U;
 155	u32 OTILEOFF_0V;
 156	u32 OTILEOFF_1U;
 157	u32 OTILEOFF_1V;
 158	u32 FASTHSCALE; /* 0xA0 */
 159	u32 UVSCALEV; /* 0xA4 */
 160	u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
 161	u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
 162	u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
 163	u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
 164	u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
 165	u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
 166	u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
 167	u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
 168	u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
 169};
 170
 171struct intel_overlay {
 172	struct drm_i915_private *i915;
 173	struct intel_crtc *crtc;
 174	struct i915_vma *vma;
 175	struct i915_vma *old_vma;
 176	bool active;
 177	bool pfit_active;
 178	u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
 179	u32 color_key:24;
 180	u32 color_key_enabled:1;
 181	u32 brightness, contrast, saturation;
 182	u32 old_xscale, old_yscale;
 183	/* register access */
 184	u32 flip_addr;
 185	struct drm_i915_gem_object *reg_bo;
 186	/* flip handling */
 187	struct i915_gem_active last_flip;
 
 188};
 189
 190static void i830_overlay_clock_gating(struct drm_i915_private *dev_priv,
 191				      bool enable)
 192{
 193	struct pci_dev *pdev = dev_priv->drm.pdev;
 194	u8 val;
 195
 196	/* WA_OVERLAY_CLKGATE:alm */
 197	if (enable)
 198		I915_WRITE(DSPCLK_GATE_D, 0);
 199	else
 200		I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
 201
 202	/* WA_DISABLE_L2CACHE_CLOCK_GATING:alm */
 203	pci_bus_read_config_byte(pdev->bus,
 204				 PCI_DEVFN(0, 0), I830_CLOCK_GATE, &val);
 205	if (enable)
 206		val &= ~I830_L2_CACHE_CLOCK_GATE_DISABLE;
 207	else
 208		val |= I830_L2_CACHE_CLOCK_GATE_DISABLE;
 209	pci_bus_write_config_byte(pdev->bus,
 210				  PCI_DEVFN(0, 0), I830_CLOCK_GATE, val);
 211}
 212
 213static struct overlay_registers __iomem *
 214intel_overlay_map_regs(struct intel_overlay *overlay)
 215{
 216	struct drm_i915_private *dev_priv = overlay->i915;
 217	struct overlay_registers __iomem *regs;
 218
 219	if (OVERLAY_NEEDS_PHYSICAL(dev_priv))
 220		regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr;
 221	else
 222		regs = io_mapping_map_wc(&dev_priv->ggtt.iomap,
 223					 overlay->flip_addr,
 224					 PAGE_SIZE);
 225
 226	return regs;
 227}
 228
 229static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
 230				     struct overlay_registers __iomem *regs)
 231{
 232	if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915))
 233		io_mapping_unmap(regs);
 234}
 235
 236static void intel_overlay_submit_request(struct intel_overlay *overlay,
 237					 struct i915_request *rq,
 238					 i915_gem_retire_fn retire)
 239{
 240	GEM_BUG_ON(i915_gem_active_peek(&overlay->last_flip,
 241					&overlay->i915->drm.struct_mutex));
 242	i915_gem_active_set_retire_fn(&overlay->last_flip, retire,
 243				      &overlay->i915->drm.struct_mutex);
 244	i915_gem_active_set(&overlay->last_flip, rq);
 245	i915_request_add(rq);
 246}
 247
 248static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
 249					 struct i915_request *rq,
 250					 i915_gem_retire_fn retire)
 251{
 252	intel_overlay_submit_request(overlay, rq, retire);
 253	return i915_gem_active_retire(&overlay->last_flip,
 254				      &overlay->i915->drm.struct_mutex);
 255}
 256
 257static struct i915_request *alloc_request(struct intel_overlay *overlay)
 258{
 259	struct drm_i915_private *dev_priv = overlay->i915;
 260	struct intel_engine_cs *engine = dev_priv->engine[RCS];
 
 
 
 
 
 
 
 261
 262	return i915_request_alloc(engine, dev_priv->kernel_context);
 
 263}
 264
 265/* overlay needs to be disable in OCMD reg */
 266static int intel_overlay_on(struct intel_overlay *overlay)
 
 267{
 268	struct drm_i915_private *dev_priv = overlay->i915;
 269	struct i915_request *rq;
 270	u32 *cs;
 
 
 
 
 
 271
 272	WARN_ON(overlay->active);
 
 
 273
 274	rq = alloc_request(overlay);
 275	if (IS_ERR(rq))
 276		return PTR_ERR(rq);
 277
 278	cs = intel_ring_begin(rq, 4);
 279	if (IS_ERR(cs)) {
 280		i915_request_add(rq);
 281		return PTR_ERR(cs);
 282	}
 283
 284	overlay->active = true;
 
 
 
 
 
 285
 286	if (IS_I830(dev_priv))
 287		i830_overlay_clock_gating(dev_priv, false);
 
 288
 289	*cs++ = MI_OVERLAY_FLIP | MI_OVERLAY_ON;
 290	*cs++ = overlay->flip_addr | OFC_UPDATE;
 291	*cs++ = MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP;
 292	*cs++ = MI_NOOP;
 293	intel_ring_advance(rq, cs);
 
 294
 295	return intel_overlay_do_wait_request(overlay, rq, NULL);
 296}
 297
 298static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
 299				       struct i915_vma *vma)
 300{
 301	enum pipe pipe = overlay->crtc->pipe;
 
 
 
 
 302
 303	WARN_ON(overlay->old_vma);
 
 304
 305	i915_gem_track_fb(overlay->vma ? overlay->vma->obj : NULL,
 306			  vma ? vma->obj : NULL,
 307			  INTEL_FRONTBUFFER_OVERLAY(pipe));
 
 
 308
 309	intel_frontbuffer_flip_prepare(overlay->i915,
 310				       INTEL_FRONTBUFFER_OVERLAY(pipe));
 
 
 
 311
 312	overlay->old_vma = overlay->vma;
 313	if (vma)
 314		overlay->vma = i915_vma_get(vma);
 315	else
 316		overlay->vma = NULL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 317}
 318
 319/* overlay needs to be enabled in OCMD reg */
 320static int intel_overlay_continue(struct intel_overlay *overlay,
 321				  struct i915_vma *vma,
 322				  bool load_polyphase_filter)
 323{
 324	struct drm_i915_private *dev_priv = overlay->i915;
 325	struct i915_request *rq;
 
 326	u32 flip_addr = overlay->flip_addr;
 327	u32 tmp, *cs;
 
 328
 329	WARN_ON(!overlay->active);
 
 
 
 
 330
 331	if (load_polyphase_filter)
 332		flip_addr |= OFC_UPDATE;
 333
 334	/* check for underruns */
 335	tmp = I915_READ(DOVSTA);
 336	if (tmp & (1 << 17))
 337		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
 338
 339	rq = alloc_request(overlay);
 340	if (IS_ERR(rq))
 341		return PTR_ERR(rq);
 342
 343	cs = intel_ring_begin(rq, 2);
 344	if (IS_ERR(cs)) {
 345		i915_request_add(rq);
 346		return PTR_ERR(cs);
 
 
 
 
 
 347	}
 348
 349	*cs++ = MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE;
 350	*cs++ = flip_addr;
 351	intel_ring_advance(rq, cs);
 352
 353	intel_overlay_flip_prepare(overlay, vma);
 354
 355	intel_overlay_submit_request(overlay, rq, NULL);
 356
 357	return 0;
 358}
 359
 360static void intel_overlay_release_old_vma(struct intel_overlay *overlay)
 361{
 362	struct i915_vma *vma;
 363
 364	vma = fetch_and_zero(&overlay->old_vma);
 365	if (WARN_ON(!vma))
 366		return;
 367
 368	intel_frontbuffer_flip_complete(overlay->i915,
 369					INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
 370
 371	i915_gem_object_unpin_from_display_plane(vma);
 372	i915_vma_put(vma);
 373}
 374
 375static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active,
 376					       struct i915_request *rq)
 377{
 378	struct intel_overlay *overlay =
 379		container_of(active, typeof(*overlay), last_flip);
 380
 381	intel_overlay_release_old_vma(overlay);
 382}
 383
 384static void intel_overlay_off_tail(struct i915_gem_active *active,
 385				   struct i915_request *rq)
 386{
 387	struct intel_overlay *overlay =
 388		container_of(active, typeof(*overlay), last_flip);
 389	struct drm_i915_private *dev_priv = overlay->i915;
 390
 391	intel_overlay_release_old_vma(overlay);
 392
 393	overlay->crtc->overlay = NULL;
 394	overlay->crtc = NULL;
 395	overlay->active = false;
 396
 397	if (IS_I830(dev_priv))
 398		i830_overlay_clock_gating(dev_priv, true);
 399}
 400
 401/* overlay needs to be disabled in OCMD reg */
 402static int intel_overlay_off(struct intel_overlay *overlay)
 403{
 404	struct i915_request *rq;
 405	u32 *cs, flip_addr = overlay->flip_addr;
 
 
 
 
 
 406
 407	WARN_ON(!overlay->active);
 
 
 408
 409	/* According to intel docs the overlay hw may hang (when switching
 410	 * off) without loading the filter coeffs. It is however unclear whether
 411	 * this applies to the disabling of the overlay or to the switching off
 412	 * of the hw. Do it in both cases */
 413	flip_addr |= OFC_UPDATE;
 414
 415	rq = alloc_request(overlay);
 416	if (IS_ERR(rq))
 417		return PTR_ERR(rq);
 418
 419	cs = intel_ring_begin(rq, 6);
 420	if (IS_ERR(cs)) {
 421		i915_request_add(rq);
 422		return PTR_ERR(cs);
 423	}
 424
 425	/* wait for overlay to go idle */
 426	*cs++ = MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE;
 427	*cs++ = flip_addr;
 428	*cs++ = MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP;
 429
 430	/* turn overlay off */
 431	*cs++ = MI_OVERLAY_FLIP | MI_OVERLAY_OFF;
 432	*cs++ = flip_addr;
 433	*cs++ = MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP;
 434
 435	intel_ring_advance(rq, cs);
 436
 437	intel_overlay_flip_prepare(overlay, NULL);
 438
 439	return intel_overlay_do_wait_request(overlay, rq,
 440					     intel_overlay_off_tail);
 441}
 442
 443/* recover from an interruption due to a signal
 444 * We have to be careful not to repeat work forever an make forward progess. */
 445static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
 446{
 447	return i915_gem_active_retire(&overlay->last_flip,
 448				      &overlay->i915->drm.struct_mutex);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 449}
 450
 451/* Wait for pending overlay flip and release old frame.
 452 * Needs to be called before the overlay register are changed
 453 * via intel_overlay_(un)map_regs
 454 */
 455static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
 456{
 457	struct drm_i915_private *dev_priv = overlay->i915;
 458	u32 *cs;
 459	int ret;
 460
 461	lockdep_assert_held(&dev_priv->drm.struct_mutex);
 462
 463	/* Only wait if there is actually an old frame to release to
 464	 * guarantee forward progress.
 465	 */
 466	if (!overlay->old_vma)
 467		return 0;
 468
 469	if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
 
 
 470		/* synchronous slowpath */
 471		struct i915_request *rq;
 
 
 472
 473		rq = alloc_request(overlay);
 474		if (IS_ERR(rq))
 475			return PTR_ERR(rq);
 476
 477		cs = intel_ring_begin(rq, 2);
 478		if (IS_ERR(cs)) {
 479			i915_request_add(rq);
 480			return PTR_ERR(cs);
 481		}
 482
 483		*cs++ = MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP;
 484		*cs++ = MI_NOOP;
 485		intel_ring_advance(rq, cs);
 486
 487		ret = intel_overlay_do_wait_request(overlay, rq,
 488						    intel_overlay_release_old_vid_tail);
 489		if (ret)
 490			return ret;
 491	} else
 492		intel_overlay_release_old_vid_tail(&overlay->last_flip, NULL);
 493
 
 494	return 0;
 495}
 496
 497void intel_overlay_reset(struct drm_i915_private *dev_priv)
 498{
 499	struct intel_overlay *overlay = dev_priv->overlay;
 500
 501	if (!overlay)
 502		return;
 503
 504	intel_overlay_release_old_vid(overlay);
 505
 506	overlay->old_xscale = 0;
 507	overlay->old_yscale = 0;
 508	overlay->crtc = NULL;
 509	overlay->active = false;
 510}
 511
 512struct put_image_params {
 513	int format;
 514	short dst_x;
 515	short dst_y;
 516	short dst_w;
 517	short dst_h;
 518	short src_w;
 519	short src_scan_h;
 520	short src_scan_w;
 521	short src_h;
 522	short stride_Y;
 523	short stride_UV;
 524	int offset_Y;
 525	int offset_U;
 526	int offset_V;
 527};
 528
 529static int packed_depth_bytes(u32 format)
 530{
 531	switch (format & I915_OVERLAY_DEPTH_MASK) {
 532	case I915_OVERLAY_YUV422:
 533		return 4;
 534	case I915_OVERLAY_YUV411:
 535		/* return 6; not implemented */
 536	default:
 537		return -EINVAL;
 538	}
 539}
 540
 541static int packed_width_bytes(u32 format, short width)
 542{
 543	switch (format & I915_OVERLAY_DEPTH_MASK) {
 544	case I915_OVERLAY_YUV422:
 545		return width << 1;
 546	default:
 547		return -EINVAL;
 548	}
 549}
 550
 551static int uv_hsubsampling(u32 format)
 552{
 553	switch (format & I915_OVERLAY_DEPTH_MASK) {
 554	case I915_OVERLAY_YUV422:
 555	case I915_OVERLAY_YUV420:
 556		return 2;
 557	case I915_OVERLAY_YUV411:
 558	case I915_OVERLAY_YUV410:
 559		return 4;
 560	default:
 561		return -EINVAL;
 562	}
 563}
 564
 565static int uv_vsubsampling(u32 format)
 566{
 567	switch (format & I915_OVERLAY_DEPTH_MASK) {
 568	case I915_OVERLAY_YUV420:
 569	case I915_OVERLAY_YUV410:
 570		return 2;
 571	case I915_OVERLAY_YUV422:
 572	case I915_OVERLAY_YUV411:
 573		return 1;
 574	default:
 575		return -EINVAL;
 576	}
 577}
 578
 579static u32 calc_swidthsw(struct drm_i915_private *dev_priv, u32 offset, u32 width)
 580{
 581	u32 sw;
 582
 583	if (IS_GEN2(dev_priv))
 584		sw = ALIGN((offset & 31) + width, 32);
 585	else
 586		sw = ALIGN((offset & 63) + width, 64);
 587
 588	if (sw == 0)
 589		return 0;
 590
 591	return (sw - 32) >> 3;
 592}
 593
 594static const u16 y_static_hcoeffs[N_PHASES][N_HORIZ_Y_TAPS] = {
 595	[ 0] = { 0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0, },
 596	[ 1] = { 0x3000, 0xb500, 0x19d0, 0x1880, 0xb440, },
 597	[ 2] = { 0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0, },
 598	[ 3] = { 0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380, },
 599	[ 4] = { 0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320, },
 600	[ 5] = { 0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0, },
 601	[ 6] = { 0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260, },
 602	[ 7] = { 0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200, },
 603	[ 8] = { 0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0, },
 604	[ 9] = { 0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160, },
 605	[10] = { 0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120, },
 606	[11] = { 0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0, },
 607	[12] = { 0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0, },
 608	[13] = { 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060, },
 609	[14] = { 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040, },
 610	[15] = { 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020, },
 611	[16] = { 0xb000, 0x3000, 0x0800, 0x3000, 0xb000, },
 
 
 612};
 613
 614static const u16 uv_static_hcoeffs[N_PHASES][N_HORIZ_UV_TAPS] = {
 615	[ 0] = { 0x3000, 0x1800, 0x1800, },
 616	[ 1] = { 0xb000, 0x18d0, 0x2e60, },
 617	[ 2] = { 0xb000, 0x1990, 0x2ce0, },
 618	[ 3] = { 0xb020, 0x1a68, 0x2b40, },
 619	[ 4] = { 0xb040, 0x1b20, 0x29e0, },
 620	[ 5] = { 0xb060, 0x1bd8, 0x2880, },
 621	[ 6] = { 0xb080, 0x1c88, 0x3e60, },
 622	[ 7] = { 0xb0a0, 0x1d28, 0x3c00, },
 623	[ 8] = { 0xb0c0, 0x1db8, 0x39e0, },
 624	[ 9] = { 0xb0e0, 0x1e40, 0x37e0, },
 625	[10] = { 0xb100, 0x1eb8, 0x3620, },
 626	[11] = { 0xb100, 0x1f18, 0x34a0, },
 627	[12] = { 0xb100, 0x1f68, 0x3360, },
 628	[13] = { 0xb0e0, 0x1fa8, 0x3240, },
 629	[14] = { 0xb0c0, 0x1fe0, 0x3140, },
 630	[15] = { 0xb060, 0x1ff0, 0x30a0, },
 631	[16] = { 0x3000, 0x0800, 0x3000, },
 632};
 633
 634static void update_polyphase_filter(struct overlay_registers __iomem *regs)
 635{
 636	memcpy_toio(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
 637	memcpy_toio(regs->UV_HCOEFS, uv_static_hcoeffs,
 638		    sizeof(uv_static_hcoeffs));
 639}
 640
 641static bool update_scaling_factors(struct intel_overlay *overlay,
 642				   struct overlay_registers __iomem *regs,
 643				   struct put_image_params *params)
 644{
 645	/* fixed point with a 12 bit shift */
 646	u32 xscale, yscale, xscale_UV, yscale_UV;
 647#define FP_SHIFT 12
 648#define FRACT_MASK 0xfff
 649	bool scale_changed = false;
 650	int uv_hscale = uv_hsubsampling(params->format);
 651	int uv_vscale = uv_vsubsampling(params->format);
 652
 653	if (params->dst_w > 1)
 654		xscale = ((params->src_scan_w - 1) << FP_SHIFT)
 655			/(params->dst_w);
 656	else
 657		xscale = 1 << FP_SHIFT;
 658
 659	if (params->dst_h > 1)
 660		yscale = ((params->src_scan_h - 1) << FP_SHIFT)
 661			/(params->dst_h);
 662	else
 663		yscale = 1 << FP_SHIFT;
 664
 665	/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
 666	xscale_UV = xscale/uv_hscale;
 667	yscale_UV = yscale/uv_vscale;
 668	/* make the Y scale to UV scale ratio an exact multiply */
 669	xscale = xscale_UV * uv_hscale;
 670	yscale = yscale_UV * uv_vscale;
 671	/*} else {
 672	  xscale_UV = 0;
 673	  yscale_UV = 0;
 674	  }*/
 675
 676	if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
 677		scale_changed = true;
 678	overlay->old_xscale = xscale;
 679	overlay->old_yscale = yscale;
 680
 681	iowrite32(((yscale & FRACT_MASK) << 20) |
 682		  ((xscale >> FP_SHIFT)  << 16) |
 683		  ((xscale & FRACT_MASK) << 3),
 684		 &regs->YRGBSCALE);
 685
 686	iowrite32(((yscale_UV & FRACT_MASK) << 20) |
 687		  ((xscale_UV >> FP_SHIFT)  << 16) |
 688		  ((xscale_UV & FRACT_MASK) << 3),
 689		 &regs->UVSCALE);
 690
 691	iowrite32((((yscale    >> FP_SHIFT) << 16) |
 692		   ((yscale_UV >> FP_SHIFT) << 0)),
 693		 &regs->UVSCALEV);
 694
 695	if (scale_changed)
 696		update_polyphase_filter(regs);
 697
 698	return scale_changed;
 699}
 700
 701static void update_colorkey(struct intel_overlay *overlay,
 702			    struct overlay_registers __iomem *regs)
 703{
 704	const struct intel_plane_state *state =
 705		to_intel_plane_state(overlay->crtc->base.primary->state);
 706	u32 key = overlay->color_key;
 707	u32 format = 0;
 708	u32 flags = 0;
 709
 710	if (overlay->color_key_enabled)
 711		flags |= DST_KEY_ENABLE;
 
 
 
 712
 713	if (state->base.visible)
 714		format = state->base.fb->format->format;
 
 
 
 
 
 
 
 715
 716	switch (format) {
 717	case DRM_FORMAT_C8:
 718		key = 0;
 719		flags |= CLK_RGB8I_MASK;
 720		break;
 721	case DRM_FORMAT_XRGB1555:
 722		key = RGB15_TO_COLORKEY(key);
 723		flags |= CLK_RGB15_MASK;
 724		break;
 725	case DRM_FORMAT_RGB565:
 726		key = RGB16_TO_COLORKEY(key);
 727		flags |= CLK_RGB16_MASK;
 728		break;
 729	default:
 730		flags |= CLK_RGB24_MASK;
 731		break;
 732	}
 733
 734	iowrite32(key, &regs->DCLRKV);
 735	iowrite32(flags, &regs->DCLRKM);
 736}
 737
 738static u32 overlay_cmd_reg(struct put_image_params *params)
 739{
 740	u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
 741
 742	if (params->format & I915_OVERLAY_YUV_PLANAR) {
 743		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
 744		case I915_OVERLAY_YUV422:
 745			cmd |= OCMD_YUV_422_PLANAR;
 746			break;
 747		case I915_OVERLAY_YUV420:
 748			cmd |= OCMD_YUV_420_PLANAR;
 749			break;
 750		case I915_OVERLAY_YUV411:
 751		case I915_OVERLAY_YUV410:
 752			cmd |= OCMD_YUV_410_PLANAR;
 753			break;
 754		}
 755	} else { /* YUV packed */
 756		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
 757		case I915_OVERLAY_YUV422:
 758			cmd |= OCMD_YUV_422_PACKED;
 759			break;
 760		case I915_OVERLAY_YUV411:
 761			cmd |= OCMD_YUV_411_PACKED;
 762			break;
 763		}
 764
 765		switch (params->format & I915_OVERLAY_SWAP_MASK) {
 766		case I915_OVERLAY_NO_SWAP:
 767			break;
 768		case I915_OVERLAY_UV_SWAP:
 769			cmd |= OCMD_UV_SWAP;
 770			break;
 771		case I915_OVERLAY_Y_SWAP:
 772			cmd |= OCMD_Y_SWAP;
 773			break;
 774		case I915_OVERLAY_Y_AND_UV_SWAP:
 775			cmd |= OCMD_Y_AND_UV_SWAP;
 776			break;
 777		}
 778	}
 779
 780	return cmd;
 781}
 782
 783static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 784				      struct drm_i915_gem_object *new_bo,
 785				      struct put_image_params *params)
 786{
 787	int ret, tmp_width;
 788	struct overlay_registers __iomem *regs;
 789	bool scale_changed = false;
 790	struct drm_i915_private *dev_priv = overlay->i915;
 791	u32 swidth, swidthsw, sheight, ostride;
 792	enum pipe pipe = overlay->crtc->pipe;
 793	struct i915_vma *vma;
 794
 795	lockdep_assert_held(&dev_priv->drm.struct_mutex);
 796	WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex));
 
 797
 798	ret = intel_overlay_release_old_vid(overlay);
 799	if (ret != 0)
 800		return ret;
 801
 802	atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
 
 
 803
 804	vma = i915_gem_object_pin_to_display_plane(new_bo,
 805						   0, NULL, PIN_MAPPABLE);
 806	if (IS_ERR(vma)) {
 807		ret = PTR_ERR(vma);
 808		goto out_pin_section;
 809	}
 810
 811	ret = i915_vma_put_fence(vma);
 812	if (ret)
 813		goto out_unpin;
 814
 815	if (!overlay->active) {
 816		u32 oconfig;
 817		regs = intel_overlay_map_regs(overlay);
 818		if (!regs) {
 819			ret = -ENOMEM;
 820			goto out_unpin;
 821		}
 822		oconfig = OCONF_CC_OUT_8BIT;
 823		if (IS_GEN4(dev_priv))
 824			oconfig |= OCONF_CSC_MODE_BT709;
 825		oconfig |= pipe == 0 ?
 826			OCONF_PIPE_A : OCONF_PIPE_B;
 827		iowrite32(oconfig, &regs->OCONFIG);
 828		intel_overlay_unmap_regs(overlay, regs);
 829
 830		ret = intel_overlay_on(overlay);
 831		if (ret != 0)
 832			goto out_unpin;
 833	}
 834
 835	regs = intel_overlay_map_regs(overlay);
 836	if (!regs) {
 837		ret = -ENOMEM;
 838		goto out_unpin;
 839	}
 840
 841	iowrite32((params->dst_y << 16) | params->dst_x, &regs->DWINPOS);
 842	iowrite32((params->dst_h << 16) | params->dst_w, &regs->DWINSZ);
 843
 844	if (params->format & I915_OVERLAY_YUV_PACKED)
 845		tmp_width = packed_width_bytes(params->format, params->src_w);
 846	else
 847		tmp_width = params->src_w;
 848
 849	swidth = params->src_w;
 850	swidthsw = calc_swidthsw(dev_priv, params->offset_Y, tmp_width);
 851	sheight = params->src_h;
 852	iowrite32(i915_ggtt_offset(vma) + params->offset_Y, &regs->OBUF_0Y);
 853	ostride = params->stride_Y;
 
 854
 855	if (params->format & I915_OVERLAY_YUV_PLANAR) {
 856		int uv_hscale = uv_hsubsampling(params->format);
 857		int uv_vscale = uv_vsubsampling(params->format);
 858		u32 tmp_U, tmp_V;
 859		swidth |= (params->src_w/uv_hscale) << 16;
 860		tmp_U = calc_swidthsw(dev_priv, params->offset_U,
 861				      params->src_w/uv_hscale);
 862		tmp_V = calc_swidthsw(dev_priv, params->offset_V,
 863				      params->src_w/uv_hscale);
 864		swidthsw |= max_t(u32, tmp_U, tmp_V) << 16;
 865		sheight |= (params->src_h/uv_vscale) << 16;
 866		iowrite32(i915_ggtt_offset(vma) + params->offset_U,
 867			  &regs->OBUF_0U);
 868		iowrite32(i915_ggtt_offset(vma) + params->offset_V,
 869			  &regs->OBUF_0V);
 870		ostride |= params->stride_UV << 16;
 871	}
 872
 873	iowrite32(swidth, &regs->SWIDTH);
 874	iowrite32(swidthsw, &regs->SWIDTHSW);
 875	iowrite32(sheight, &regs->SHEIGHT);
 876	iowrite32(ostride, &regs->OSTRIDE);
 877
 878	scale_changed = update_scaling_factors(overlay, regs, params);
 879
 880	update_colorkey(overlay, regs);
 881
 882	iowrite32(overlay_cmd_reg(params), &regs->OCMD);
 883
 884	intel_overlay_unmap_regs(overlay, regs);
 885
 886	ret = intel_overlay_continue(overlay, vma, scale_changed);
 887	if (ret)
 888		goto out_unpin;
 889
 
 
 
 890	return 0;
 891
 892out_unpin:
 893	i915_gem_object_unpin_from_display_plane(vma);
 894out_pin_section:
 895	atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
 896
 897	return ret;
 898}
 899
 900int intel_overlay_switch_off(struct intel_overlay *overlay)
 901{
 902	struct drm_i915_private *dev_priv = overlay->i915;
 903	struct overlay_registers __iomem *regs;
 904	int ret;
 905
 906	lockdep_assert_held(&dev_priv->drm.struct_mutex);
 907	WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex));
 908
 909	ret = intel_overlay_recover_from_interrupt(overlay);
 910	if (ret != 0)
 911		return ret;
 912
 913	if (!overlay->active)
 914		return 0;
 915
 916	ret = intel_overlay_release_old_vid(overlay);
 917	if (ret != 0)
 918		return ret;
 919
 920	regs = intel_overlay_map_regs(overlay);
 921	iowrite32(0, &regs->OCMD);
 922	intel_overlay_unmap_regs(overlay, regs);
 923
 924	return intel_overlay_off(overlay);
 
 
 
 
 
 925}
 926
 927static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
 928					  struct intel_crtc *crtc)
 929{
 
 
 930	if (!crtc->active)
 931		return -EINVAL;
 932
 933	/* can't use the overlay with double wide pipe */
 934	if (crtc->config->double_wide)
 
 935		return -EINVAL;
 936
 937	return 0;
 938}
 939
 940static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
 941{
 942	struct drm_i915_private *dev_priv = overlay->i915;
 
 943	u32 pfit_control = I915_READ(PFIT_CONTROL);
 944	u32 ratio;
 945
 946	/* XXX: This is not the same logic as in the xorg driver, but more in
 947	 * line with the intel documentation for the i965
 948	 */
 949	if (INTEL_GEN(dev_priv) >= 4) {
 950		/* on i965 use the PGM reg to read out the autoscaler values */
 951		ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
 952	} else {
 953		if (pfit_control & VERT_AUTO_SCALE)
 954			ratio = I915_READ(PFIT_AUTO_RATIOS);
 955		else
 956			ratio = I915_READ(PFIT_PGM_RATIOS);
 957		ratio >>= PFIT_VERT_SCALE_SHIFT;
 958	}
 959
 960	overlay->pfit_vscale_ratio = ratio;
 961}
 962
 963static int check_overlay_dst(struct intel_overlay *overlay,
 964			     struct drm_intel_overlay_put_image *rec)
 965{
 966	const struct intel_crtc_state *pipe_config =
 967		overlay->crtc->config;
 968
 969	if (rec->dst_x < pipe_config->pipe_src_w &&
 970	    rec->dst_x + rec->dst_width <= pipe_config->pipe_src_w &&
 971	    rec->dst_y < pipe_config->pipe_src_h &&
 972	    rec->dst_y + rec->dst_height <= pipe_config->pipe_src_h)
 973		return 0;
 974	else
 975		return -EINVAL;
 976}
 977
 978static int check_overlay_scaling(struct put_image_params *rec)
 979{
 980	u32 tmp;
 981
 982	/* downscaling limit is 8.0 */
 983	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
 984	if (tmp > 7)
 985		return -EINVAL;
 986	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
 987	if (tmp > 7)
 988		return -EINVAL;
 989
 990	return 0;
 991}
 992
 993static int check_overlay_src(struct drm_i915_private *dev_priv,
 994			     struct drm_intel_overlay_put_image *rec,
 995			     struct drm_i915_gem_object *new_bo)
 996{
 997	int uv_hscale = uv_hsubsampling(rec->flags);
 998	int uv_vscale = uv_vsubsampling(rec->flags);
 999	u32 stride_mask;
1000	int depth;
1001	u32 tmp;
1002
1003	/* check src dimensions */
1004	if (IS_I845G(dev_priv) || IS_I830(dev_priv)) {
1005		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
1006		    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
1007			return -EINVAL;
1008	} else {
1009		if (rec->src_height > IMAGE_MAX_HEIGHT ||
1010		    rec->src_width  > IMAGE_MAX_WIDTH)
1011			return -EINVAL;
1012	}
1013
1014	/* better safe than sorry, use 4 as the maximal subsampling ratio */
1015	if (rec->src_height < N_VERT_Y_TAPS*4 ||
1016	    rec->src_width  < N_HORIZ_Y_TAPS*4)
1017		return -EINVAL;
1018
1019	/* check alignment constraints */
1020	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1021	case I915_OVERLAY_RGB:
1022		/* not implemented */
1023		return -EINVAL;
1024
1025	case I915_OVERLAY_YUV_PACKED:
1026		if (uv_vscale != 1)
1027			return -EINVAL;
1028
1029		depth = packed_depth_bytes(rec->flags);
1030		if (depth < 0)
1031			return depth;
1032
1033		/* ignore UV planes */
1034		rec->stride_UV = 0;
1035		rec->offset_U = 0;
1036		rec->offset_V = 0;
1037		/* check pixel alignment */
1038		if (rec->offset_Y % depth)
1039			return -EINVAL;
1040		break;
1041
1042	case I915_OVERLAY_YUV_PLANAR:
1043		if (uv_vscale < 0 || uv_hscale < 0)
1044			return -EINVAL;
1045		/* no offset restrictions for planar formats */
1046		break;
1047
1048	default:
1049		return -EINVAL;
1050	}
1051
1052	if (rec->src_width % uv_hscale)
1053		return -EINVAL;
1054
1055	/* stride checking */
1056	if (IS_I830(dev_priv) || IS_I845G(dev_priv))
1057		stride_mask = 255;
1058	else
1059		stride_mask = 63;
1060
1061	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
1062		return -EINVAL;
1063	if (IS_GEN4(dev_priv) && rec->stride_Y < 512)
1064		return -EINVAL;
1065
1066	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
1067		4096 : 8192;
1068	if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
1069		return -EINVAL;
1070
1071	/* check buffer dimensions */
1072	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1073	case I915_OVERLAY_RGB:
1074	case I915_OVERLAY_YUV_PACKED:
1075		/* always 4 Y values per depth pixels */
1076		if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1077			return -EINVAL;
1078
1079		tmp = rec->stride_Y*rec->src_height;
1080		if (rec->offset_Y + tmp > new_bo->base.size)
1081			return -EINVAL;
1082		break;
1083
1084	case I915_OVERLAY_YUV_PLANAR:
1085		if (rec->src_width > rec->stride_Y)
1086			return -EINVAL;
1087		if (rec->src_width/uv_hscale > rec->stride_UV)
1088			return -EINVAL;
1089
1090		tmp = rec->stride_Y * rec->src_height;
1091		if (rec->offset_Y + tmp > new_bo->base.size)
1092			return -EINVAL;
1093
1094		tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1095		if (rec->offset_U + tmp > new_bo->base.size ||
1096		    rec->offset_V + tmp > new_bo->base.size)
1097			return -EINVAL;
1098		break;
1099	}
1100
1101	return 0;
1102}
1103
1104int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
1105				  struct drm_file *file_priv)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1106{
1107	struct drm_intel_overlay_put_image *put_image_rec = data;
1108	struct drm_i915_private *dev_priv = to_i915(dev);
1109	struct intel_overlay *overlay;
1110	struct drm_crtc *drmmode_crtc;
1111	struct intel_crtc *crtc;
1112	struct drm_i915_gem_object *new_bo;
1113	struct put_image_params *params;
1114	int ret;
1115
 
 
 
 
 
1116	overlay = dev_priv->overlay;
1117	if (!overlay) {
1118		DRM_DEBUG("userspace bug: no overlay\n");
1119		return -ENODEV;
1120	}
1121
1122	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
1123		drm_modeset_lock_all(dev);
1124		mutex_lock(&dev->struct_mutex);
1125
1126		ret = intel_overlay_switch_off(overlay);
1127
1128		mutex_unlock(&dev->struct_mutex);
1129		drm_modeset_unlock_all(dev);
1130
1131		return ret;
1132	}
1133
1134	params = kmalloc(sizeof(*params), GFP_KERNEL);
1135	if (!params)
1136		return -ENOMEM;
1137
1138	drmmode_crtc = drm_crtc_find(dev, file_priv, put_image_rec->crtc_id);
1139	if (!drmmode_crtc) {
 
1140		ret = -ENOENT;
1141		goto out_free;
1142	}
1143	crtc = to_intel_crtc(drmmode_crtc);
1144
1145	new_bo = i915_gem_object_lookup(file_priv, put_image_rec->bo_handle);
1146	if (!new_bo) {
 
1147		ret = -ENOENT;
1148		goto out_free;
1149	}
1150
1151	drm_modeset_lock_all(dev);
1152	mutex_lock(&dev->struct_mutex);
1153
1154	if (i915_gem_object_is_tiled(new_bo)) {
1155		DRM_DEBUG_KMS("buffer used for overlay image can not be tiled\n");
1156		ret = -EINVAL;
1157		goto out_unlock;
1158	}
1159
1160	ret = intel_overlay_recover_from_interrupt(overlay);
1161	if (ret != 0)
1162		goto out_unlock;
1163
1164	if (overlay->crtc != crtc) {
 
1165		ret = intel_overlay_switch_off(overlay);
1166		if (ret != 0)
1167			goto out_unlock;
1168
1169		ret = check_overlay_possible_on_crtc(overlay, crtc);
1170		if (ret != 0)
1171			goto out_unlock;
1172
1173		overlay->crtc = crtc;
1174		crtc->overlay = overlay;
1175
1176		/* line too wide, i.e. one-line-mode */
1177		if (crtc->config->pipe_src_w > 1024 &&
1178		    crtc->config->gmch_pfit.control & PFIT_ENABLE) {
1179			overlay->pfit_active = true;
1180			update_pfit_vscale_ratio(overlay);
1181		} else
1182			overlay->pfit_active = false;
1183	}
1184
1185	ret = check_overlay_dst(overlay, put_image_rec);
1186	if (ret != 0)
1187		goto out_unlock;
1188
1189	if (overlay->pfit_active) {
1190		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1191				 overlay->pfit_vscale_ratio);
1192		/* shifting right rounds downwards, so add 1 */
1193		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1194				 overlay->pfit_vscale_ratio) + 1;
1195	} else {
1196		params->dst_y = put_image_rec->dst_y;
1197		params->dst_h = put_image_rec->dst_height;
1198	}
1199	params->dst_x = put_image_rec->dst_x;
1200	params->dst_w = put_image_rec->dst_width;
1201
1202	params->src_w = put_image_rec->src_width;
1203	params->src_h = put_image_rec->src_height;
1204	params->src_scan_w = put_image_rec->src_scan_width;
1205	params->src_scan_h = put_image_rec->src_scan_height;
1206	if (params->src_scan_h > params->src_h ||
1207	    params->src_scan_w > params->src_w) {
1208		ret = -EINVAL;
1209		goto out_unlock;
1210	}
1211
1212	ret = check_overlay_src(dev_priv, put_image_rec, new_bo);
1213	if (ret != 0)
1214		goto out_unlock;
1215	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
1216	params->stride_Y = put_image_rec->stride_Y;
1217	params->stride_UV = put_image_rec->stride_UV;
1218	params->offset_Y = put_image_rec->offset_Y;
1219	params->offset_U = put_image_rec->offset_U;
1220	params->offset_V = put_image_rec->offset_V;
1221
1222	/* Check scaling after src size to prevent a divide-by-zero. */
1223	ret = check_overlay_scaling(params);
1224	if (ret != 0)
1225		goto out_unlock;
1226
1227	ret = intel_overlay_do_put_image(overlay, new_bo, params);
1228	if (ret != 0)
1229		goto out_unlock;
1230
1231	mutex_unlock(&dev->struct_mutex);
1232	drm_modeset_unlock_all(dev);
1233	i915_gem_object_put(new_bo);
1234
1235	kfree(params);
1236
1237	return 0;
1238
1239out_unlock:
1240	mutex_unlock(&dev->struct_mutex);
1241	drm_modeset_unlock_all(dev);
1242	i915_gem_object_put(new_bo);
1243out_free:
1244	kfree(params);
1245
1246	return ret;
1247}
1248
1249static void update_reg_attrs(struct intel_overlay *overlay,
1250			     struct overlay_registers __iomem *regs)
1251{
1252	iowrite32((overlay->contrast << 18) | (overlay->brightness & 0xff),
1253		  &regs->OCLRC0);
1254	iowrite32(overlay->saturation, &regs->OCLRC1);
1255}
1256
1257static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1258{
1259	int i;
1260
1261	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1262		return false;
1263
1264	for (i = 0; i < 3; i++) {
1265		if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1266			return false;
1267	}
1268
1269	return true;
1270}
1271
1272static bool check_gamma5_errata(u32 gamma5)
1273{
1274	int i;
1275
1276	for (i = 0; i < 3; i++) {
1277		if (((gamma5 >> i*8) & 0xff) == 0x80)
1278			return false;
1279	}
1280
1281	return true;
1282}
1283
1284static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1285{
1286	if (!check_gamma_bounds(0, attrs->gamma0) ||
1287	    !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1288	    !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1289	    !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1290	    !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1291	    !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1292	    !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
1293		return -EINVAL;
1294
1295	if (!check_gamma5_errata(attrs->gamma5))
1296		return -EINVAL;
1297
1298	return 0;
1299}
1300
1301int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
1302			      struct drm_file *file_priv)
1303{
1304	struct drm_intel_overlay_attrs *attrs = data;
1305	struct drm_i915_private *dev_priv = to_i915(dev);
1306	struct intel_overlay *overlay;
1307	struct overlay_registers __iomem *regs;
1308	int ret;
1309
 
 
 
 
 
1310	overlay = dev_priv->overlay;
1311	if (!overlay) {
1312		DRM_DEBUG("userspace bug: no overlay\n");
1313		return -ENODEV;
1314	}
1315
1316	drm_modeset_lock_all(dev);
1317	mutex_lock(&dev->struct_mutex);
1318
1319	ret = -EINVAL;
1320	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
1321		attrs->color_key  = overlay->color_key;
1322		attrs->brightness = overlay->brightness;
1323		attrs->contrast   = overlay->contrast;
1324		attrs->saturation = overlay->saturation;
1325
1326		if (!IS_GEN2(dev_priv)) {
1327			attrs->gamma0 = I915_READ(OGAMC0);
1328			attrs->gamma1 = I915_READ(OGAMC1);
1329			attrs->gamma2 = I915_READ(OGAMC2);
1330			attrs->gamma3 = I915_READ(OGAMC3);
1331			attrs->gamma4 = I915_READ(OGAMC4);
1332			attrs->gamma5 = I915_READ(OGAMC5);
1333		}
1334	} else {
1335		if (attrs->brightness < -128 || attrs->brightness > 127)
1336			goto out_unlock;
1337		if (attrs->contrast > 255)
1338			goto out_unlock;
1339		if (attrs->saturation > 1023)
1340			goto out_unlock;
1341
1342		overlay->color_key  = attrs->color_key;
1343		overlay->brightness = attrs->brightness;
1344		overlay->contrast   = attrs->contrast;
1345		overlay->saturation = attrs->saturation;
1346
1347		regs = intel_overlay_map_regs(overlay);
1348		if (!regs) {
1349			ret = -ENOMEM;
1350			goto out_unlock;
1351		}
1352
1353		update_reg_attrs(overlay, regs);
1354
1355		intel_overlay_unmap_regs(overlay, regs);
1356
1357		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
1358			if (IS_GEN2(dev_priv))
1359				goto out_unlock;
1360
1361			if (overlay->active) {
1362				ret = -EBUSY;
1363				goto out_unlock;
1364			}
1365
1366			ret = check_gamma(attrs);
1367			if (ret)
1368				goto out_unlock;
1369
1370			I915_WRITE(OGAMC0, attrs->gamma0);
1371			I915_WRITE(OGAMC1, attrs->gamma1);
1372			I915_WRITE(OGAMC2, attrs->gamma2);
1373			I915_WRITE(OGAMC3, attrs->gamma3);
1374			I915_WRITE(OGAMC4, attrs->gamma4);
1375			I915_WRITE(OGAMC5, attrs->gamma5);
1376		}
1377	}
1378	overlay->color_key_enabled = (attrs->flags & I915_OVERLAY_DISABLE_DEST_COLORKEY) == 0;
1379
1380	ret = 0;
1381out_unlock:
1382	mutex_unlock(&dev->struct_mutex);
1383	drm_modeset_unlock_all(dev);
1384
1385	return ret;
1386}
1387
1388void intel_setup_overlay(struct drm_i915_private *dev_priv)
1389{
 
1390	struct intel_overlay *overlay;
1391	struct drm_i915_gem_object *reg_bo;
1392	struct overlay_registers __iomem *regs;
1393	struct i915_vma *vma = NULL;
1394	int ret;
1395
1396	if (!HAS_OVERLAY(dev_priv))
1397		return;
1398
1399	overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
1400	if (!overlay)
1401		return;
1402
1403	mutex_lock(&dev_priv->drm.struct_mutex);
1404	if (WARN_ON(dev_priv->overlay))
1405		goto out_free;
1406
1407	overlay->i915 = dev_priv;
1408
1409	reg_bo = NULL;
1410	if (!OVERLAY_NEEDS_PHYSICAL(dev_priv))
1411		reg_bo = i915_gem_object_create_stolen(dev_priv, PAGE_SIZE);
1412	if (reg_bo == NULL)
1413		reg_bo = i915_gem_object_create(dev_priv, PAGE_SIZE);
1414	if (IS_ERR(reg_bo))
1415		goto out_free;
1416	overlay->reg_bo = reg_bo;
1417
1418	if (OVERLAY_NEEDS_PHYSICAL(dev_priv)) {
1419		ret = i915_gem_object_attach_phys(reg_bo, PAGE_SIZE);
 
 
 
 
 
 
 
 
 
1420		if (ret) {
1421			DRM_ERROR("failed to attach phys overlay regs\n");
1422			goto out_free_bo;
1423		}
1424		overlay->flip_addr = reg_bo->phys_handle->busaddr;
1425	} else {
1426		vma = i915_gem_object_ggtt_pin(reg_bo, NULL,
1427					       0, PAGE_SIZE, PIN_MAPPABLE);
1428		if (IS_ERR(vma)) {
1429			DRM_ERROR("failed to pin overlay register bo\n");
1430			ret = PTR_ERR(vma);
1431			goto out_free_bo;
1432		}
1433		overlay->flip_addr = i915_ggtt_offset(vma);
1434
1435		ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1436		if (ret) {
1437			DRM_ERROR("failed to move overlay register bo into the GTT\n");
1438			goto out_unpin_bo;
1439		}
1440	}
1441
1442	/* init all values */
1443	overlay->color_key = 0x0101fe;
1444	overlay->color_key_enabled = true;
1445	overlay->brightness = -19;
1446	overlay->contrast = 75;
1447	overlay->saturation = 146;
1448
1449	init_request_active(&overlay->last_flip, NULL);
1450
1451	regs = intel_overlay_map_regs(overlay);
1452	if (!regs)
1453		goto out_unpin_bo;
1454
1455	memset_io(regs, 0, sizeof(struct overlay_registers));
1456	update_polyphase_filter(regs);
1457	update_reg_attrs(overlay, regs);
1458
1459	intel_overlay_unmap_regs(overlay, regs);
1460
1461	dev_priv->overlay = overlay;
1462	mutex_unlock(&dev_priv->drm.struct_mutex);
1463	DRM_INFO("initialized overlay support\n");
1464	return;
1465
1466out_unpin_bo:
1467	if (vma)
1468		i915_vma_unpin(vma);
1469out_free_bo:
1470	i915_gem_object_put(reg_bo);
1471out_free:
1472	mutex_unlock(&dev_priv->drm.struct_mutex);
1473	kfree(overlay);
1474	return;
1475}
1476
1477void intel_cleanup_overlay(struct drm_i915_private *dev_priv)
1478{
 
 
1479	if (!dev_priv->overlay)
1480		return;
1481
1482	/* The bo's should be free'd by the generic code already.
1483	 * Furthermore modesetting teardown happens beforehand so the
1484	 * hardware should be off already */
1485	WARN_ON(dev_priv->overlay->active);
1486
1487	i915_gem_object_put(dev_priv->overlay->reg_bo);
1488	kfree(dev_priv->overlay);
1489}
1490
1491#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
 
1492
1493struct intel_overlay_error_state {
1494	struct overlay_registers regs;
1495	unsigned long base;
1496	u32 dovsta;
1497	u32 isr;
1498};
1499
1500static struct overlay_registers __iomem *
1501intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
1502{
1503	struct drm_i915_private *dev_priv = overlay->i915;
1504	struct overlay_registers __iomem *regs;
1505
1506	if (OVERLAY_NEEDS_PHYSICAL(dev_priv))
1507		/* Cast to make sparse happy, but it's wc memory anyway, so
1508		 * equivalent to the wc io mapping on X86. */
1509		regs = (struct overlay_registers __iomem *)
1510			overlay->reg_bo->phys_handle->vaddr;
1511	else
1512		regs = io_mapping_map_atomic_wc(&dev_priv->ggtt.iomap,
1513						overlay->flip_addr);
1514
1515	return regs;
1516}
1517
1518static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
1519					struct overlay_registers __iomem *regs)
1520{
1521	if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915))
1522		io_mapping_unmap_atomic(regs);
1523}
1524
 
1525struct intel_overlay_error_state *
1526intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
1527{
 
1528	struct intel_overlay *overlay = dev_priv->overlay;
1529	struct intel_overlay_error_state *error;
1530	struct overlay_registers __iomem *regs;
1531
1532	if (!overlay || !overlay->active)
1533		return NULL;
1534
1535	error = kmalloc(sizeof(*error), GFP_ATOMIC);
1536	if (error == NULL)
1537		return NULL;
1538
1539	error->dovsta = I915_READ(DOVSTA);
1540	error->isr = I915_READ(ISR);
1541	error->base = overlay->flip_addr;
 
 
 
1542
1543	regs = intel_overlay_map_regs_atomic(overlay);
1544	if (!regs)
1545		goto err;
1546
1547	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
1548	intel_overlay_unmap_regs_atomic(overlay, regs);
1549
1550	return error;
1551
1552err:
1553	kfree(error);
1554	return NULL;
1555}
1556
1557void
1558intel_overlay_print_error_state(struct drm_i915_error_state_buf *m,
1559				struct intel_overlay_error_state *error)
1560{
1561	i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1562			  error->dovsta, error->isr);
1563	i915_error_printf(m, "  Register file at 0x%08lx:\n",
1564			  error->base);
1565
1566#define P(x) i915_error_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
1567	P(OBUF_0Y);
1568	P(OBUF_1Y);
1569	P(OBUF_0U);
1570	P(OBUF_0V);
1571	P(OBUF_1U);
1572	P(OBUF_1V);
1573	P(OSTRIDE);
1574	P(YRGB_VPH);
1575	P(UV_VPH);
1576	P(HORZ_PH);
1577	P(INIT_PHS);
1578	P(DWINPOS);
1579	P(DWINSZ);
1580	P(SWIDTH);
1581	P(SWIDTHSW);
1582	P(SHEIGHT);
1583	P(YRGBSCALE);
1584	P(UVSCALE);
1585	P(OCLRC0);
1586	P(OCLRC1);
1587	P(DCLRKV);
1588	P(DCLRKM);
1589	P(SCLRKVH);
1590	P(SCLRKVL);
1591	P(SCLRKEN);
1592	P(OCONFIG);
1593	P(OCMD);
1594	P(OSTART_0Y);
1595	P(OSTART_1Y);
1596	P(OSTART_0U);
1597	P(OSTART_0V);
1598	P(OSTART_1U);
1599	P(OSTART_1V);
1600	P(OTILEOFF_0Y);
1601	P(OTILEOFF_1Y);
1602	P(OTILEOFF_0U);
1603	P(OTILEOFF_0V);
1604	P(OTILEOFF_1U);
1605	P(OTILEOFF_1V);
1606	P(FASTHSCALE);
1607	P(UVSCALEV);
1608#undef P
1609}
1610
1611#endif