PageRenderTime 74ms CodeModel.GetById 21ms app.highlight 41ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/gpu/drm/i915/intel_overlay.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 1617 lines | 1263 code | 251 blank | 103 comment | 197 complexity | f4e21b35c16c8036e2e9850314e19b4c MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
   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(new_bo, PAGE_SIZE, true);
 777	if (ret != 0)
 778		return ret;
 779
 780	ret = i915_gem_object_set_to_gtt_domain(new_bo, 0);
 781	if (ret != 0)
 782		goto out_unpin;
 783
 784	ret = i915_gem_object_put_fence(new_bo);
 785	if (ret)
 786		goto out_unpin;
 787
 788	if (!overlay->active) {
 789		regs = intel_overlay_map_regs(overlay);
 790		if (!regs) {
 791			ret = -ENOMEM;
 792			goto out_unpin;
 793		}
 794		regs->OCONFIG = OCONF_CC_OUT_8BIT;
 795		if (IS_GEN4(overlay->dev))
 796			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
 797		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
 798			OCONF_PIPE_A : OCONF_PIPE_B;
 799		intel_overlay_unmap_regs(overlay, regs);
 800
 801		ret = intel_overlay_on(overlay);
 802		if (ret != 0)
 803			goto out_unpin;
 804	}
 805
 806	regs = intel_overlay_map_regs(overlay);
 807	if (!regs) {
 808		ret = -ENOMEM;
 809		goto out_unpin;
 810	}
 811
 812	regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
 813	regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
 814
 815	if (params->format & I915_OVERLAY_YUV_PACKED)
 816		tmp_width = packed_width_bytes(params->format, params->src_w);
 817	else
 818		tmp_width = params->src_w;
 819
 820	regs->SWIDTH = params->src_w;
 821	regs->SWIDTHSW = calc_swidthsw(overlay->dev,
 822				       params->offset_Y, tmp_width);
 823	regs->SHEIGHT = params->src_h;
 824	regs->OBUF_0Y = new_bo->gtt_offset + params-> offset_Y;
 825	regs->OSTRIDE = params->stride_Y;
 826
 827	if (params->format & I915_OVERLAY_YUV_PLANAR) {
 828		int uv_hscale = uv_hsubsampling(params->format);
 829		int uv_vscale = uv_vsubsampling(params->format);
 830		u32 tmp_U, tmp_V;
 831		regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
 832		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
 833				      params->src_w/uv_hscale);
 834		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
 835				      params->src_w/uv_hscale);
 836		regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
 837		regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
 838		regs->OBUF_0U = new_bo->gtt_offset + params->offset_U;
 839		regs->OBUF_0V = new_bo->gtt_offset + params->offset_V;
 840		regs->OSTRIDE |= params->stride_UV << 16;
 841	}
 842
 843	scale_changed = update_scaling_factors(overlay, regs, params);
 844
 845	update_colorkey(overlay, regs);
 846
 847	regs->OCMD = overlay_cmd_reg(params);
 848
 849	intel_overlay_unmap_regs(overlay, regs);
 850
 851	ret = intel_overlay_continue(overlay, scale_changed);
 852	if (ret)
 853		goto out_unpin;
 854
 855	overlay->old_vid_bo = overlay->vid_bo;
 856	overlay->vid_bo = new_bo;
 857
 858	return 0;
 859
 860out_unpin:
 861	i915_gem_object_unpin(new_bo);
 862	return ret;
 863}
 864
 865int intel_overlay_switch_off(struct intel_overlay *overlay)
 866{
 867	struct overlay_registers *regs;
 868	struct drm_device *dev = overlay->dev;
 869	int ret;
 870
 871	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 872	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 873
 874	ret = intel_overlay_recover_from_interrupt(overlay);
 875	if (ret != 0)
 876		return ret;
 877
 878	if (!overlay->active)
 879		return 0;
 880
 881	ret = intel_overlay_release_old_vid(overlay);
 882	if (ret != 0)
 883		return ret;
 884
 885	regs = intel_overlay_map_regs(overlay);
 886	regs->OCMD = 0;
 887	intel_overlay_unmap_regs(overlay, regs);
 888
 889	ret = intel_overlay_off(overlay);
 890	if (ret != 0)
 891		return ret;
 892
 893	intel_overlay_off_tail(overlay);
 894	return 0;
 895}
 896
 897static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
 898					  struct intel_crtc *crtc)
 899{
 900	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 901
 902	if (!crtc->active)
 903		return -EINVAL;
 904
 905	/* can't use the overlay with double wide pipe */
 906	if (INTEL_INFO(overlay->dev)->gen < 4 &&
 907	    (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE)
 908		return -EINVAL;
 909
 910	return 0;
 911}
 912
 913static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
 914{
 915	struct drm_device *dev = overlay->dev;
 916	drm_i915_private_t *dev_priv = dev->dev_private;
 917	u32 pfit_control = I915_READ(PFIT_CONTROL);
 918	u32 ratio;
 919
 920	/* XXX: This is not the same logic as in the xorg driver, but more in
 921	 * line with the intel documentation for the i965
 922	 */
 923	if (INTEL_INFO(dev)->gen >= 4) {
 924	       	/* on i965 use the PGM reg to read out the autoscaler values */
 925		ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
 926	} else {
 927		if (pfit_control & VERT_AUTO_SCALE)
 928			ratio = I915_READ(PFIT_AUTO_RATIOS);
 929		else
 930			ratio = I915_READ(PFIT_PGM_RATIOS);
 931		ratio >>= PFIT_VERT_SCALE_SHIFT;
 932	}
 933
 934	overlay->pfit_vscale_ratio = ratio;
 935}
 936
 937static int check_overlay_dst(struct intel_overlay *overlay,
 938			     struct drm_intel_overlay_put_image *rec)
 939{
 940	struct drm_display_mode *mode = &overlay->crtc->base.mode;
 941
 942	if (rec->dst_x < mode->crtc_hdisplay &&
 943	    rec->dst_x + rec->dst_width <= mode->crtc_hdisplay &&
 944	    rec->dst_y < mode->crtc_vdisplay &&
 945	    rec->dst_y + rec->dst_height <= mode->crtc_vdisplay)
 946		return 0;
 947	else
 948		return -EINVAL;
 949}
 950
 951static int check_overlay_scaling(struct put_image_params *rec)
 952{
 953	u32 tmp;
 954
 955	/* downscaling limit is 8.0 */
 956	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
 957	if (tmp > 7)
 958		return -EINVAL;
 959	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
 960	if (tmp > 7)
 961		return -EINVAL;
 962
 963	return 0;
 964}
 965
 966static int check_overlay_src(struct drm_device *dev,
 967			     struct drm_intel_overlay_put_image *rec,
 968			     struct drm_i915_gem_object *new_bo)
 969{
 970	int uv_hscale = uv_hsubsampling(rec->flags);
 971	int uv_vscale = uv_vsubsampling(rec->flags);
 972	u32 stride_mask;
 973	int depth;
 974	u32 tmp;
 975
 976	/* check src dimensions */
 977	if (IS_845G(dev) || IS_I830(dev)) {
 978		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
 979		    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
 980			return -EINVAL;
 981	} else {
 982		if (rec->src_height > IMAGE_MAX_HEIGHT ||
 983		    rec->src_width  > IMAGE_MAX_WIDTH)
 984			return -EINVAL;
 985	}
 986
 987	/* better safe than sorry, use 4 as the maximal subsampling ratio */
 988	if (rec->src_height < N_VERT_Y_TAPS*4 ||
 989	    rec->src_width  < N_HORIZ_Y_TAPS*4)
 990		return -EINVAL;
 991
 992	/* check alignment constraints */
 993	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
 994	case I915_OVERLAY_RGB:
 995		/* not implemented */
 996		return -EINVAL;
 997
 998	case I915_OVERLAY_YUV_PACKED:
 999		if (uv_vscale != 1)
1000			return -EINVAL;
1001
1002		depth = packed_depth_bytes(rec->flags);
1003		if (depth < 0)
1004			return depth;
1005
1006		/* ignore UV planes */
1007		rec->stride_UV = 0;
1008		rec->offset_U = 0;
1009		rec->offset_V = 0;
1010		/* check pixel alignment */
1011		if (rec->offset_Y % depth)
1012			return -EINVAL;
1013		break;
1014
1015	case I915_OVERLAY_YUV_PLANAR:
1016		if (uv_vscale < 0 || uv_hscale < 0)
1017			return -EINVAL;
1018		/* no offset restrictions for planar formats */
1019		break;
1020
1021	default:
1022		return -EINVAL;
1023	}
1024
1025	if (rec->src_width % uv_hscale)
1026		return -EINVAL;
1027
1028	/* stride checking */
1029	if (IS_I830(dev) || IS_845G(dev))
1030		stride_mask = 255;
1031	else
1032		stride_mask = 63;
1033
1034	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
1035		return -EINVAL;
1036	if (IS_GEN4(dev) && rec->stride_Y < 512)
1037		return -EINVAL;
1038
1039	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
1040		4096 : 8192;
1041	if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
1042		return -EINVAL;
1043
1044	/* check buffer dimensions */
1045	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1046	case I915_OVERLAY_RGB:
1047	case I915_OVERLAY_YUV_PACKED:
1048		/* always 4 Y values per depth pixels */
1049		if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1050			return -EINVAL;
1051
1052		tmp = rec->stride_Y*rec->src_height;
1053		if (rec->offset_Y + tmp > new_bo->base.size)
1054			return -EINVAL;
1055		break;
1056
1057	case I915_OVERLAY_YUV_PLANAR:
1058		if (rec->src_width > rec->stride_Y)
1059			return -EINVAL;
1060		if (rec->src_width/uv_hscale > rec->stride_UV)
1061			return -EINVAL;
1062
1063		tmp = rec->stride_Y * rec->src_height;
1064		if (rec->offset_Y + tmp > new_bo->base.size)
1065			return -EINVAL;
1066
1067		tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1068		if (rec->offset_U + tmp > new_bo->base.size ||
1069		    rec->offset_V + tmp > new_bo->base.size)
1070			return -EINVAL;
1071		break;
1072	}
1073
1074	return 0;
1075}
1076
1077/**
1078 * Return the pipe currently connected to the panel fitter,
1079 * or -1 if the panel fitter is not present or not in use
1080 */
1081static int intel_panel_fitter_pipe(struct drm_device *dev)
1082{
1083	struct drm_i915_private *dev_priv = dev->dev_private;
1084	u32  pfit_control;
1085
1086	/* i830 doesn't have a panel fitter */
1087	if (IS_I830(dev))
1088		return -1;
1089
1090	pfit_control = I915_READ(PFIT_CONTROL);
1091
1092	/* See if the panel fitter is in use */
1093	if ((pfit_control & PFIT_ENABLE) == 0)
1094		return -1;
1095
1096	/* 965 can place panel fitter on either pipe */
1097	if (IS_GEN4(dev))
1098		return (pfit_control >> 29) & 0x3;
1099
1100	/* older chips can only use pipe 1 */
1101	return 1;
1102}
1103
1104int intel_overlay_put_image(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	drm_i915_private_t *dev_priv = dev->dev_private;
1109	struct intel_overlay *overlay;
1110	struct drm_mode_object *drmmode_obj;
1111	struct intel_crtc *crtc;
1112	struct drm_i915_gem_object *new_bo;
1113	struct put_image_params *params;
1114	int ret;
1115
1116	if (!dev_priv) {
1117		DRM_ERROR("called with no initialization\n");
1118		return -EINVAL;
1119	}
1120
1121	overlay = dev_priv->overlay;
1122	if (!overlay) {
1123		DRM_DEBUG("userspace bug: no overlay\n");
1124		return -ENODEV;
1125	}
1126
1127	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
1128		mutex_lock(&dev->mode_config.mutex);
1129		mutex_lock(&dev->struct_mutex);
1130
1131		ret = intel_overlay_switch_off(overlay);
1132
1133		mutex_unlock(&dev->struct_mutex);
1134		mutex_unlock(&dev->mode_config.mutex);
1135
1136		return ret;
1137	}
1138
1139	params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
1140	if (!params)
1141		return -ENOMEM;
1142
1143	drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
1144					   DRM_MODE_OBJECT_CRTC);
1145	if (!drmmode_obj) {
1146		ret = -ENOENT;
1147		goto out_free;
1148	}
1149	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
1150
1151	new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
1152						   put_image_rec->bo_handle));
1153	if (&new_bo->base == NULL) {
1154		ret = -ENOENT;
1155		goto out_free;
1156	}
1157
1158	mutex_lock(&dev->mode_config.mutex);
1159	mutex_lock(&dev->struct_mutex);
1160
1161	if (new_bo->tiling_mode) {
1162		DRM_ERROR("buffer used for overlay image can not be tiled\n");
1163		ret = -EINVAL;
1164		goto out_unlock;
1165	}
1166
1167	ret = intel_overlay_recover_from_interrupt(overlay);
1168	if (ret != 0)
1169		goto out_unlock;
1170
1171	if (overlay->crtc != crtc) {
1172		struct drm_display_mode *mode = &crtc->base.mode;
1173		ret = intel_overlay_switch_off(overlay);
1174		if (ret != 0)
1175			goto out_unlock;
1176
1177		ret = check_overlay_possible_on_crtc(overlay, crtc);
1178		if (ret != 0)
1179			goto out_unlock;
1180
1181		overlay->crtc = crtc;
1182		crtc->overlay = overlay;
1183
1184		/* line too wide, i.e. one-line-mode */
1185		if (mode->hdisplay > 1024 &&
1186		    intel_panel_fitter_pipe(dev) == crtc->pipe) {
1187			overlay->pfit_active = 1;
1188			update_pfit_vscale_ratio(overlay);
1189		} else
1190			overlay->pfit_active = 0;
1191	}
1192
1193	ret = check_overlay_dst(overlay, put_image_rec);
1194	if (ret != 0)
1195		goto out_unlock;
1196
1197	if (overlay->pfit_active) {
1198		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1199				 overlay->pfit_vscale_ratio);
1200		/* shifting right rounds downwards, so add 1 */
1201		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1202				 overlay->pfit_vscale_ratio) + 1;
1203	} else {
1204		params->dst_y = put_image_rec->dst_y;
1205		params->dst_h = put_image_rec->dst_height;
1206	}
1207	params->dst_x = put_image_rec->dst_x;
1208	params->dst_w = put_image_rec->dst_width;
1209
1210	params->src_w = put_image_rec->src_width;
1211	params->src_h = put_image_rec->src_height;
1212	params->src_scan_w = put_image_rec->src_scan_width;
1213	params->src_scan_h = put_image_rec->src_scan_height;
1214	if (params->src_scan_h > params->src_h ||
1215	    params->src_scan_w > params->src_w) {
1216		ret = -EINVAL;
1217		goto out_unlock;
1218	}
1219
1220	ret = check_overlay_src(dev, put_image_rec, new_bo);
1221	if (ret != 0)
1222		goto out_unlock;
1223	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
1224	params->stride_Y = put_image_rec->stride_Y;
1225	params->stride_UV = put_image_rec->stride_UV;
1226	params->offset_Y = put_image_rec->offset_Y;
1227	params->offset_U = put_image_rec->offset_U;
1228	params->offset_V = put_image_rec->offset_V;
1229
1230	/* Check scaling after src size to prevent a divide-by-zero. */
1231	ret = check_overlay_scaling(params);
1232	if (ret != 0)
1233		goto out_unlock;
1234
1235	ret = intel_overlay_do_put_image(overlay, new_bo, params);
1236	if (ret != 0)
1237		goto out_unlock;
1238
1239	mutex_unlock(&dev->struct_mutex);
1240	mutex_unlock(&dev->mode_config.mutex);
1241
1242	kfree(params);
1243
1244	return 0;
1245
1246out_unlock:
1247	mutex_unlock(&dev->struct_mutex);
1248	mutex_unlock(&dev->mode_config.mutex);
1249	drm_gem_object_unreference_unlocked(&new_bo->base);
1250out_free:
1251	kfree(params);
1252
1253	return ret;
1254}
1255
1256static void update_reg_attrs(struct intel_overlay *overlay,
1257			     struct overlay_registers *regs)
1258{
1259	regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
1260	regs->OCLRC1 = overlay->saturation;
1261}
1262
1263static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1264{
1265	int i;
1266
1267	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1268		return false;
1269
1270	for (i = 0; i < 3; i++) {
1271		if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1272			return false;
1273	}
1274
1275	return true;
1276}
1277
1278static bool check_gamma5_errata(u32 gamma5)
1279{
1280	int i;
1281
1282	for (i = 0; i < 3; i++) {
1283		if (((gamma5 >> i*8) & 0xff) == 0x80)
1284			return false;
1285	}
1286
1287	return true;
1288}
1289
1290static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1291{
1292	if (!check_gamma_bounds(0, attrs->gamma0) ||
1293	    !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1294	    !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1295	    !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1296	    !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1297	    !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1298	    !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
1299		return -EINVAL;
1300
1301	if (!check_gamma5_errata(attrs->gamma5))
1302		return -EINVAL;
1303
1304	return 0;
1305}
1306
1307int intel_overlay_attrs(struct drm_device *dev, void *data,
1308                        struct drm_file *file_priv)
1309{
1310	struct drm_intel_overlay_attrs *attrs = data;
1311        drm_i915_private_t *dev_priv = dev->dev_private;
1312	struct intel_overlay *overlay;
1313	struct overlay_registers *regs;
1314	int ret;
1315
1316	if (!dev_priv) {
1317		DRM_ERROR("called with no initialization\n");
1318		return -EINVAL;
1319	}
1320
1321	overlay = dev_priv->overlay;
1322	if (!overlay) {
1323		DRM_DEBUG("userspace bug: no overlay\n");
1324		return -ENODEV;
1325	}
1326
1327	mutex_lock(&dev->mode_config.mutex);
1328	mutex_lock(&dev->struct_mutex);
1329
1330	ret = -EINVAL;
1331	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
1332		attrs->color_key  = overlay->color_key;
1333		attrs->brightness = overlay->brightness;
1334		attrs->contrast   = overlay->contrast;
1335		attrs->saturation = overlay->saturation;
1336
1337		if (!IS_GEN2(dev)) {
1338			attrs->gamma0 = I915_READ(OGAMC0);
1339			attrs->gamma1 = I915_READ(OGAMC1);
1340			attrs->gamma2 = I915_READ(OGAMC2);
1341			attrs->gamma3 = I915_READ(OGAMC3);
1342			attrs->gamma4 = I915_READ(OGAMC4);
1343			attrs->gamma5 = I915_READ(OGAMC5);
1344		}
1345	} else {
1346		if (attrs->brightness < -128 || attrs->brightness > 127)
1347			goto out_unlock;
1348		if (attrs->contrast > 255)
1349			goto out_unlock;
1350		if (attrs->saturation > 1023)
1351			goto out_unlock;
1352
1353		overlay->color_key  = attrs->color_key;
1354		overlay->brightness = attrs->brightness;
1355		overlay->contrast   = attrs->contrast;
1356		overlay->saturation = attrs->saturation;
1357
1358		regs = intel_overlay_map_regs(overlay);
1359		if (!regs) {
1360			ret = -ENOMEM;
1361			goto out_unlock;
1362		}
1363
1364		update_reg_attrs(overlay, regs);
1365
1366		intel_overlay_unmap_regs(overlay, regs);
1367
1368		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
1369			if (IS_GEN2(dev))
1370				goto out_unlock;
1371
1372			if (overlay->active) {
1373				ret = -EBUSY;
1374				goto out_unlock;
1375			}
1376
1377			ret = check_gamma(attrs);
1378			if (ret)
1379				goto out_unlock;
1380
1381			I915_WRITE(OGAMC0, attrs->gamma0);
1382			I915_WRITE(OGAMC1, attrs->gamma1);
1383			I915_WRITE(OGAMC2, attrs->gamma2);
1384			I915_WRITE(OGAMC3, attrs->gamma3);
1385			I915_WRITE(OGAMC4, attrs->gamma4);
1386			I915_WRITE(OGAMC5, attrs->gamma5);
1387		}
1388	}
1389
1390	ret = 0;
1391out_unlock:
1392	mutex_unlock(&dev->struct_mutex);
1393	mutex_unlock(&dev->mode_config.mutex);
1394
1395	return ret;
1396}
1397
1398void intel_setup_overlay(struct drm_device *dev)
1399{
1400        drm_i915_private_t *dev_priv = dev->dev_private;
1401	struct intel_overlay *overlay;
1402	struct drm_i915_gem_object *reg_bo;
1403	struct overlay_registers *regs;
1404	int ret;
1405
1406	if (!HAS_OVERLAY(dev))
1407		return;
1408
1409	overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
1410	if (!overlay)
1411		return;
1412
1413	mutex_lock(&dev->struct_mutex);
1414	if (WARN_ON(dev_priv->overlay))
1415		goto out_free;
1416
1417	overlay->dev = dev;
1418
1419	reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
1420	if (!reg_bo)
1421		goto out_free;
1422	overlay->reg_bo = reg_bo;
1423
1424	if (OVERLAY_NEEDS_PHYSICAL(dev)) {
1425		ret = i915_gem_attach_phys_object(dev, reg_bo,
1426						  I915_GEM_PHYS_OVERLAY_REGS,
1427						  PAGE_SIZE);
1428                if (ret) {
1429                        DRM_ERROR("failed to attach phys overlay regs\n");
1430                        goto out_free_bo;
1431                }
1432		overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
1433	} else {
1434		ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true);
1435		if (ret) {
1436                        DRM_ERROR("failed to pin overlay register bo\n");
1437                        goto out_free_bo;
1438                }
1439		overlay->flip_addr = reg_bo->gtt_offset;
1440
1441		ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1442		if (ret) {
1443                        DRM_ERROR("failed to move overlay register bo into the GTT\n");
1444                        goto out_unpin_bo;
1445                }
1446	}
1447
1448	/* init all values */
1449	overlay->color_key = 0x0101fe;
1450	overlay->brightness = -19;
1451	overlay->contrast = 75;
1452	overlay->saturation = 146;
1453
1454	regs = intel_overlay_map_regs(overlay);
1455	if (!regs)
1456		goto out_unpin_bo;
1457
1458	memset(regs, 0, sizeof(struct overlay_registers));
1459	update_polyphase_filter(regs);
1460	update_reg_attrs(overlay, regs);
1461
1462	intel_overlay_unmap_regs(overlay, regs);
1463
1464	dev_priv->overlay = overlay;
1465	mutex_unlock(&dev->struct_mutex);
1466	DRM_INFO("initialized overlay support\n");
1467	return;
1468
1469out_unpin_bo:
1470	if (!OVERLAY_NEEDS_PHYSICAL(dev))
1471		i915_gem_object_unpin(reg_bo);
1472out_free_bo:
1473	drm_gem_object_unreference(&reg_bo->base);
1474out_free:
1475	mutex_unlock(&dev->struct_mutex);
1476	kfree(overlay);
1477	return;
1478}
1479
1480void intel_cleanup_overlay(struct drm_device *dev)
1481{
1482	drm_i915_private_t *dev_priv = dev->dev_private;
1483
1484	if (!dev_priv->overlay)
1485		return;
1486
1487	/* The bo's should be free'd by the generic code already.
1488	 * Furthermore modesetting teardown happens beforehand so the
1489	 * hardware should be off already */
1490	BUG_ON(dev_priv->overlay->active);
1491
1492	drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
1493	kfree(dev_priv->overlay);
1494}
1495
1496#ifdef CONFIG_DEBUG_FS
1497#include <linux/seq_file.h>
1498
1499struct intel_overlay_error_state {
1500	struct overlay_registers regs;
1501	unsigned long base;
1502	u32 dovsta;
1503	u32 isr;
1504};
1505
1506static struct overlay_registers *
1507intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
1508{
1509	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
1510	struct overlay_registers *regs;
1511
1512	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1513		regs = overlay->reg_bo->phys_obj->handle->vaddr;
1514	else
1515		regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
1516						overlay->reg_bo->gtt_offset);
1517
1518	return regs;
1519}
1520
1521static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
1522					    struct overlay_registers *regs)
1523{
1524	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1525		io_mapping_unmap_atomic(regs);
1526}
1527
1528
1529struct intel_overlay_error_state *
1530intel_overlay_capture_error_state(struct drm_device *dev)
1531{
1532        drm_i915_private_t *dev_priv = dev->dev_private;
1533	struct intel_overlay *overlay = dev_priv->overlay;
1534	struct intel_overlay_error_state *error;
1535	struct overlay_registers __iomem *regs;
1536
1537	if (!overlay || !overlay->active)
1538		return NULL;
1539
1540	error = kmalloc(sizeof(*error), GFP_ATOMIC);
1541	if (error == NULL)
1542		return NULL;
1543
1544	error->dovsta = I915_READ(DOVSTA);
1545	error->isr = I915_READ(ISR);
1546	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1547		error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
1548	else
1549		error->base = (long) overlay->reg_bo->gtt_offset;
1550
1551	regs = intel_overlay_map_regs_atomic(overlay);
1552	if (!regs)
1553		goto err;
1554
1555	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
1556	intel_overlay_unmap_regs_atomic(overlay, regs);
1557
1558	return error;
1559
1560err:
1561	kfree(error);
1562	return NULL;
1563}
1564
1565void
1566intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
1567{
1568	seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1569		   error->dovsta, error->isr);
1570	seq_printf(m, "  Register file at 0x%08lx:\n",
1571		   error->base);
1572
1573#define P(x) seq_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
1574	P(OBUF_0Y);
1575	P(OBUF_1Y);
1576	P(OBUF_0U);
1577	P(OBUF_0V);
1578	P(OBUF_1U);
1579	P(OBUF_1V);
1580	P(OSTRIDE);
1581	P(YRGB_VPH);
1582	P(UV_VPH);
1583	P(HORZ_PH);
1584	P(INIT_PHS);
1585	P(DWINPOS);
1586	P(DWINSZ);
1587	P(SWIDTH);
1588	P(SWIDTHSW);
1589	P(SHEIGHT);
1590	P(YRGBSCALE);
1591	P(UVSCALE);
1592	P(OCLRC0);
1593	P(OCLRC1);
1594	P(DCLRKV);
1595	P(DCLRKM);
1596	P(SCLRKVH);
1597	P(SCLRKVL);
1598	P(SCLRKEN);
1599	P(OCONFIG);
1600	P(OCMD);
1601	P(OSTART_0Y);
1602	P(OSTART_1Y);
1603	P(OSTART_0U);
1604	P(OSTART_0V);
1605	P(OSTART_1U);
1606	P(OSTART_1V);
1607	P(OTILEOFF_0Y);
1608	P(OTILEOFF_1Y);
1609	P(OTILEOFF_0U);
1610	P(OTILEOFF_0V);
1611	P(OTILEOFF_1U);
1612	P(OTILEOFF_1V);
1613	P(FASTHSCALE);
1614	P(UVSCALEV);
1615#undef P
1616}
1617#endif