Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1/*
   2 * Copyright (C) 2012 Avionic Design GmbH
   3 * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 */
   9
  10#include <linux/clk.h>
  11#include <linux/debugfs.h>
  12#include <linux/reset.h>
  13
  14#include "dc.h"
  15#include "drm.h"
  16#include "gem.h"
  17
  18struct tegra_dc_soc_info {
  19	bool supports_interlacing;
  20};
  21
  22struct tegra_plane {
  23	struct drm_plane base;
  24	unsigned int index;
  25};
  26
  27static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane)
  28{
  29	return container_of(plane, struct tegra_plane, base);
  30}
  31
  32static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
  33			      struct drm_framebuffer *fb, int crtc_x,
  34			      int crtc_y, unsigned int crtc_w,
  35			      unsigned int crtc_h, uint32_t src_x,
  36			      uint32_t src_y, uint32_t src_w, uint32_t src_h)
  37{
  38	struct tegra_plane *p = to_tegra_plane(plane);
  39	struct tegra_dc *dc = to_tegra_dc(crtc);
  40	struct tegra_dc_window window;
  41	unsigned int i;
  42
  43	memset(&window, 0, sizeof(window));
  44	window.src.x = src_x >> 16;
  45	window.src.y = src_y >> 16;
  46	window.src.w = src_w >> 16;
  47	window.src.h = src_h >> 16;
  48	window.dst.x = crtc_x;
  49	window.dst.y = crtc_y;
  50	window.dst.w = crtc_w;
  51	window.dst.h = crtc_h;
  52	window.format = tegra_dc_format(fb->pixel_format);
  53	window.bits_per_pixel = fb->bits_per_pixel;
  54	window.bottom_up = tegra_fb_is_bottom_up(fb);
  55	window.tiled = tegra_fb_is_tiled(fb);
  56
  57	for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
  58		struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
  59
  60		window.base[i] = bo->paddr + fb->offsets[i];
  61
  62		/*
  63		 * Tegra doesn't support different strides for U and V planes
  64		 * so we display a warning if the user tries to display a
  65		 * framebuffer with such a configuration.
  66		 */
  67		if (i >= 2) {
  68			if (fb->pitches[i] != window.stride[1])
  69				DRM_ERROR("unsupported UV-plane configuration\n");
  70		} else {
  71			window.stride[i] = fb->pitches[i];
  72		}
  73	}
  74
  75	return tegra_dc_setup_window(dc, p->index, &window);
  76}
  77
  78static int tegra_plane_disable(struct drm_plane *plane)
  79{
  80	struct tegra_dc *dc = to_tegra_dc(plane->crtc);
  81	struct tegra_plane *p = to_tegra_plane(plane);
  82	unsigned long value;
  83
  84	if (!plane->crtc)
  85		return 0;
  86
  87	value = WINDOW_A_SELECT << p->index;
  88	tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
  89
  90	value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
  91	value &= ~WIN_ENABLE;
  92	tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
  93
  94	tegra_dc_writel(dc, WIN_A_UPDATE << p->index, DC_CMD_STATE_CONTROL);
  95	tegra_dc_writel(dc, WIN_A_ACT_REQ << p->index, DC_CMD_STATE_CONTROL);
  96
  97	return 0;
  98}
  99
 100static void tegra_plane_destroy(struct drm_plane *plane)
 101{
 102	struct tegra_plane *p = to_tegra_plane(plane);
 103
 104	tegra_plane_disable(plane);
 105	drm_plane_cleanup(plane);
 106	kfree(p);
 107}
 108
 109static const struct drm_plane_funcs tegra_plane_funcs = {
 110	.update_plane = tegra_plane_update,
 111	.disable_plane = tegra_plane_disable,
 112	.destroy = tegra_plane_destroy,
 113};
 114
 115static const uint32_t plane_formats[] = {
 116	DRM_FORMAT_XBGR8888,
 117	DRM_FORMAT_XRGB8888,
 118	DRM_FORMAT_RGB565,
 119	DRM_FORMAT_UYVY,
 120	DRM_FORMAT_YUV420,
 121	DRM_FORMAT_YUV422,
 122};
 123
 124static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
 125{
 126	unsigned int i;
 127	int err = 0;
 128
 129	for (i = 0; i < 2; i++) {
 130		struct tegra_plane *plane;
 131
 132		plane = kzalloc(sizeof(*plane), GFP_KERNEL);
 133		if (!plane)
 134			return -ENOMEM;
 135
 136		plane->index = 1 + i;
 137
 138		err = drm_plane_init(drm, &plane->base, 1 << dc->pipe,
 139				     &tegra_plane_funcs, plane_formats,
 140				     ARRAY_SIZE(plane_formats), false);
 141		if (err < 0) {
 142			kfree(plane);
 143			return err;
 144		}
 145	}
 146
 147	return 0;
 148}
 149
 150static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
 151			     struct drm_framebuffer *fb)
 152{
 153	unsigned int format = tegra_dc_format(fb->pixel_format);
 154	struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
 155	unsigned int h_offset = 0, v_offset = 0;
 156	unsigned long value;
 157
 158	tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
 159
 160	value = fb->offsets[0] + y * fb->pitches[0] +
 161		x * fb->bits_per_pixel / 8;
 162
 163	tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR);
 164	tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
 165	tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH);
 166
 167	if (tegra_fb_is_tiled(fb)) {
 168		value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
 169			DC_WIN_BUFFER_ADDR_MODE_TILE;
 170	} else {
 171		value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
 172			DC_WIN_BUFFER_ADDR_MODE_LINEAR;
 173	}
 174
 175	tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
 176
 177	/* make sure bottom-up buffers are properly displayed */
 178	if (tegra_fb_is_bottom_up(fb)) {
 179		value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
 180		value |= INVERT_V;
 181		tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
 182
 183		v_offset += fb->height - 1;
 184	} else {
 185		value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
 186		value &= ~INVERT_V;
 187		tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
 188	}
 189
 190	tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
 191	tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
 192
 193	value = GENERAL_UPDATE | WIN_A_UPDATE;
 194	tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
 195
 196	value = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
 197	tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
 198
 199	return 0;
 200}
 201
 202void tegra_dc_enable_vblank(struct tegra_dc *dc)
 203{
 204	unsigned long value, flags;
 205
 206	spin_lock_irqsave(&dc->lock, flags);
 207
 208	value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
 209	value |= VBLANK_INT;
 210	tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
 211
 212	spin_unlock_irqrestore(&dc->lock, flags);
 213}
 214
 215void tegra_dc_disable_vblank(struct tegra_dc *dc)
 216{
 217	unsigned long value, flags;
 218
 219	spin_lock_irqsave(&dc->lock, flags);
 220
 221	value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
 222	value &= ~VBLANK_INT;
 223	tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
 224
 225	spin_unlock_irqrestore(&dc->lock, flags);
 226}
 227
 228static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
 229{
 230	struct drm_device *drm = dc->base.dev;
 231	struct drm_crtc *crtc = &dc->base;
 232	unsigned long flags, base;
 233	struct tegra_bo *bo;
 234
 235	if (!dc->event)
 236		return;
 237
 238	bo = tegra_fb_get_plane(crtc->primary->fb, 0);
 239
 240	/* check if new start address has been latched */
 241	tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
 242	base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
 243	tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
 244
 245	if (base == bo->paddr + crtc->primary->fb->offsets[0]) {
 246		spin_lock_irqsave(&drm->event_lock, flags);
 247		drm_send_vblank_event(drm, dc->pipe, dc->event);
 248		drm_vblank_put(drm, dc->pipe);
 249		dc->event = NULL;
 250		spin_unlock_irqrestore(&drm->event_lock, flags);
 251	}
 252}
 253
 254void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
 255{
 256	struct tegra_dc *dc = to_tegra_dc(crtc);
 257	struct drm_device *drm = crtc->dev;
 258	unsigned long flags;
 259
 260	spin_lock_irqsave(&drm->event_lock, flags);
 261
 262	if (dc->event && dc->event->base.file_priv == file) {
 263		dc->event->base.destroy(&dc->event->base);
 264		drm_vblank_put(drm, dc->pipe);
 265		dc->event = NULL;
 266	}
 267
 268	spin_unlock_irqrestore(&drm->event_lock, flags);
 269}
 270
 271static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 272			      struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
 273{
 274	struct tegra_dc *dc = to_tegra_dc(crtc);
 275	struct drm_device *drm = crtc->dev;
 276
 277	if (dc->event)
 278		return -EBUSY;
 279
 280	if (event) {
 281		event->pipe = dc->pipe;
 282		dc->event = event;
 283		drm_vblank_get(drm, dc->pipe);
 284	}
 285
 286	tegra_dc_set_base(dc, 0, 0, fb);
 287	crtc->primary->fb = fb;
 288
 289	return 0;
 290}
 291
 292static void drm_crtc_clear(struct drm_crtc *crtc)
 293{
 294	memset(crtc, 0, sizeof(*crtc));
 295}
 296
 297static void tegra_dc_destroy(struct drm_crtc *crtc)
 298{
 299	drm_crtc_cleanup(crtc);
 300	drm_crtc_clear(crtc);
 301}
 302
 303static const struct drm_crtc_funcs tegra_crtc_funcs = {
 304	.page_flip = tegra_dc_page_flip,
 305	.set_config = drm_crtc_helper_set_config,
 306	.destroy = tegra_dc_destroy,
 307};
 308
 309static void tegra_crtc_disable(struct drm_crtc *crtc)
 310{
 311	struct tegra_dc *dc = to_tegra_dc(crtc);
 312	struct drm_device *drm = crtc->dev;
 313	struct drm_plane *plane;
 314
 315	drm_for_each_legacy_plane(plane, &drm->mode_config.plane_list) {
 316		if (plane->crtc == crtc) {
 317			tegra_plane_disable(plane);
 318			plane->crtc = NULL;
 319
 320			if (plane->fb) {
 321				drm_framebuffer_unreference(plane->fb);
 322				plane->fb = NULL;
 323			}
 324		}
 325	}
 326
 327	drm_vblank_off(drm, dc->pipe);
 328}
 329
 330static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
 331				  const struct drm_display_mode *mode,
 332				  struct drm_display_mode *adjusted)
 333{
 334	return true;
 335}
 336
 337static inline u32 compute_dda_inc(unsigned int in, unsigned int out, bool v,
 338				  unsigned int bpp)
 339{
 340	fixed20_12 outf = dfixed_init(out);
 341	fixed20_12 inf = dfixed_init(in);
 342	u32 dda_inc;
 343	int max;
 344
 345	if (v)
 346		max = 15;
 347	else {
 348		switch (bpp) {
 349		case 2:
 350			max = 8;
 351			break;
 352
 353		default:
 354			WARN_ON_ONCE(1);
 355			/* fallthrough */
 356		case 4:
 357			max = 4;
 358			break;
 359		}
 360	}
 361
 362	outf.full = max_t(u32, outf.full - dfixed_const(1), dfixed_const(1));
 363	inf.full -= dfixed_const(1);
 364
 365	dda_inc = dfixed_div(inf, outf);
 366	dda_inc = min_t(u32, dda_inc, dfixed_const(max));
 367
 368	return dda_inc;
 369}
 370
 371static inline u32 compute_initial_dda(unsigned int in)
 372{
 373	fixed20_12 inf = dfixed_init(in);
 374	return dfixed_frac(inf);
 375}
 376
 377static int tegra_dc_set_timings(struct tegra_dc *dc,
 378				struct drm_display_mode *mode)
 379{
 380	/* TODO: For HDMI compliance, h & v ref_to_sync should be set to 1 */
 381	unsigned int h_ref_to_sync = 0;
 382	unsigned int v_ref_to_sync = 0;
 383	unsigned long value;
 384
 385	tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS);
 386
 387	value = (v_ref_to_sync << 16) | h_ref_to_sync;
 388	tegra_dc_writel(dc, value, DC_DISP_REF_TO_SYNC);
 389
 390	value = ((mode->vsync_end - mode->vsync_start) << 16) |
 391		((mode->hsync_end - mode->hsync_start) <<  0);
 392	tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH);
 393
 394	value = ((mode->vtotal - mode->vsync_end) << 16) |
 395		((mode->htotal - mode->hsync_end) <<  0);
 396	tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH);
 397
 398	value = ((mode->vsync_start - mode->vdisplay) << 16) |
 399		((mode->hsync_start - mode->hdisplay) <<  0);
 400	tegra_dc_writel(dc, value, DC_DISP_FRONT_PORCH);
 401
 402	value = (mode->vdisplay << 16) | mode->hdisplay;
 403	tegra_dc_writel(dc, value, DC_DISP_ACTIVE);
 404
 405	return 0;
 406}
 407
 408static int tegra_crtc_setup_clk(struct drm_crtc *crtc,
 409				struct drm_display_mode *mode,
 410				unsigned long *div)
 411{
 412	unsigned long pclk = mode->clock * 1000, rate;
 413	struct tegra_dc *dc = to_tegra_dc(crtc);
 414	struct tegra_output *output = NULL;
 415	struct drm_encoder *encoder;
 416	long err;
 417
 418	list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list, head)
 419		if (encoder->crtc == crtc) {
 420			output = encoder_to_output(encoder);
 421			break;
 422		}
 423
 424	if (!output)
 425		return -ENODEV;
 426
 427	/*
 428	 * This assumes that the display controller will divide its parent
 429	 * clock by 2 to generate the pixel clock.
 430	 */
 431	err = tegra_output_setup_clock(output, dc->clk, pclk * 2);
 432	if (err < 0) {
 433		dev_err(dc->dev, "failed to setup clock: %ld\n", err);
 434		return err;
 435	}
 436
 437	rate = clk_get_rate(dc->clk);
 438	*div = (rate * 2 / pclk) - 2;
 439
 440	DRM_DEBUG_KMS("rate: %lu, div: %lu\n", rate, *div);
 441
 442	return 0;
 443}
 444
 445static bool tegra_dc_format_is_yuv(unsigned int format, bool *planar)
 446{
 447	switch (format) {
 448	case WIN_COLOR_DEPTH_YCbCr422:
 449	case WIN_COLOR_DEPTH_YUV422:
 450		if (planar)
 451			*planar = false;
 452
 453		return true;
 454
 455	case WIN_COLOR_DEPTH_YCbCr420P:
 456	case WIN_COLOR_DEPTH_YUV420P:
 457	case WIN_COLOR_DEPTH_YCbCr422P:
 458	case WIN_COLOR_DEPTH_YUV422P:
 459	case WIN_COLOR_DEPTH_YCbCr422R:
 460	case WIN_COLOR_DEPTH_YUV422R:
 461	case WIN_COLOR_DEPTH_YCbCr422RA:
 462	case WIN_COLOR_DEPTH_YUV422RA:
 463		if (planar)
 464			*planar = true;
 465
 466		return true;
 467	}
 468
 469	return false;
 470}
 471
 472int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
 473			  const struct tegra_dc_window *window)
 474{
 475	unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
 476	unsigned long value;
 477	bool yuv, planar;
 478
 479	/*
 480	 * For YUV planar modes, the number of bytes per pixel takes into
 481	 * account only the luma component and therefore is 1.
 482	 */
 483	yuv = tegra_dc_format_is_yuv(window->format, &planar);
 484	if (!yuv)
 485		bpp = window->bits_per_pixel / 8;
 486	else
 487		bpp = planar ? 1 : 2;
 488
 489	value = WINDOW_A_SELECT << index;
 490	tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
 491
 492	tegra_dc_writel(dc, window->format, DC_WIN_COLOR_DEPTH);
 493	tegra_dc_writel(dc, 0, DC_WIN_BYTE_SWAP);
 494
 495	value = V_POSITION(window->dst.y) | H_POSITION(window->dst.x);
 496	tegra_dc_writel(dc, value, DC_WIN_POSITION);
 497
 498	value = V_SIZE(window->dst.h) | H_SIZE(window->dst.w);
 499	tegra_dc_writel(dc, value, DC_WIN_SIZE);
 500
 501	h_offset = window->src.x * bpp;
 502	v_offset = window->src.y;
 503	h_size = window->src.w * bpp;
 504	v_size = window->src.h;
 505
 506	value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size);
 507	tegra_dc_writel(dc, value, DC_WIN_PRESCALED_SIZE);
 508
 509	/*
 510	 * For DDA computations the number of bytes per pixel for YUV planar
 511	 * modes needs to take into account all Y, U and V components.
 512	 */
 513	if (yuv && planar)
 514		bpp = 2;
 515
 516	h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp);
 517	v_dda = compute_dda_inc(window->src.h, window->dst.h, true, bpp);
 518
 519	value = V_DDA_INC(v_dda) | H_DDA_INC(h_dda);
 520	tegra_dc_writel(dc, value, DC_WIN_DDA_INC);
 521
 522	h_dda = compute_initial_dda(window->src.x);
 523	v_dda = compute_initial_dda(window->src.y);
 524
 525	tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA);
 526	tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA);
 527
 528	tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
 529	tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
 530
 531	tegra_dc_writel(dc, window->base[0], DC_WINBUF_START_ADDR);
 532
 533	if (yuv && planar) {
 534		tegra_dc_writel(dc, window->base[1], DC_WINBUF_START_ADDR_U);
 535		tegra_dc_writel(dc, window->base[2], DC_WINBUF_START_ADDR_V);
 536		value = window->stride[1] << 16 | window->stride[0];
 537		tegra_dc_writel(dc, value, DC_WIN_LINE_STRIDE);
 538	} else {
 539		tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE);
 540	}
 541
 542	if (window->bottom_up)
 543		v_offset += window->src.h - 1;
 544
 545	tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
 546	tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
 547
 548	if (window->tiled) {
 549		value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
 550			DC_WIN_BUFFER_ADDR_MODE_TILE;
 551	} else {
 552		value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
 553			DC_WIN_BUFFER_ADDR_MODE_LINEAR;
 554	}
 555
 556	tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
 557
 558	value = WIN_ENABLE;
 559
 560	if (yuv) {
 561		/* setup default colorspace conversion coefficients */
 562		tegra_dc_writel(dc, 0x00f0, DC_WIN_CSC_YOF);
 563		tegra_dc_writel(dc, 0x012a, DC_WIN_CSC_KYRGB);
 564		tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KUR);
 565		tegra_dc_writel(dc, 0x0198, DC_WIN_CSC_KVR);
 566		tegra_dc_writel(dc, 0x039b, DC_WIN_CSC_KUG);
 567		tegra_dc_writel(dc, 0x032f, DC_WIN_CSC_KVG);
 568		tegra_dc_writel(dc, 0x0204, DC_WIN_CSC_KUB);
 569		tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KVB);
 570
 571		value |= CSC_ENABLE;
 572	} else if (window->bits_per_pixel < 24) {
 573		value |= COLOR_EXPAND;
 574	}
 575
 576	if (window->bottom_up)
 577		value |= INVERT_V;
 578
 579	tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
 580
 581	/*
 582	 * Disable blending and assume Window A is the bottom-most window,
 583	 * Window C is the top-most window and Window B is in the middle.
 584	 */
 585	tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_NOKEY);
 586	tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_1WIN);
 587
 588	switch (index) {
 589	case 0:
 590		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_X);
 591		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
 592		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
 593		break;
 594
 595	case 1:
 596		tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
 597		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
 598		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
 599		break;
 600
 601	case 2:
 602		tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
 603		tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_Y);
 604		tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_3WIN_XY);
 605		break;
 606	}
 607
 608	tegra_dc_writel(dc, WIN_A_UPDATE << index, DC_CMD_STATE_CONTROL);
 609	tegra_dc_writel(dc, WIN_A_ACT_REQ << index, DC_CMD_STATE_CONTROL);
 610
 611	return 0;
 612}
 613
 614unsigned int tegra_dc_format(uint32_t format)
 615{
 616	switch (format) {
 617	case DRM_FORMAT_XBGR8888:
 618		return WIN_COLOR_DEPTH_R8G8B8A8;
 619
 620	case DRM_FORMAT_XRGB8888:
 621		return WIN_COLOR_DEPTH_B8G8R8A8;
 622
 623	case DRM_FORMAT_RGB565:
 624		return WIN_COLOR_DEPTH_B5G6R5;
 625
 626	case DRM_FORMAT_UYVY:
 627		return WIN_COLOR_DEPTH_YCbCr422;
 628
 629	case DRM_FORMAT_YUV420:
 630		return WIN_COLOR_DEPTH_YCbCr420P;
 631
 632	case DRM_FORMAT_YUV422:
 633		return WIN_COLOR_DEPTH_YCbCr422P;
 634
 635	default:
 636		break;
 637	}
 638
 639	WARN(1, "unsupported pixel format %u, using default\n", format);
 640	return WIN_COLOR_DEPTH_B8G8R8A8;
 641}
 642
 643static int tegra_crtc_mode_set(struct drm_crtc *crtc,
 644			       struct drm_display_mode *mode,
 645			       struct drm_display_mode *adjusted,
 646			       int x, int y, struct drm_framebuffer *old_fb)
 647{
 648	struct tegra_bo *bo = tegra_fb_get_plane(crtc->primary->fb, 0);
 649	struct tegra_dc *dc = to_tegra_dc(crtc);
 650	struct tegra_dc_window window;
 651	unsigned long div, value;
 652	int err;
 653
 654	drm_vblank_pre_modeset(crtc->dev, dc->pipe);
 655
 656	err = tegra_crtc_setup_clk(crtc, mode, &div);
 657	if (err) {
 658		dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err);
 659		return err;
 660	}
 661
 662	/* program display mode */
 663	tegra_dc_set_timings(dc, mode);
 664
 665	/* interlacing isn't supported yet, so disable it */
 666	if (dc->soc->supports_interlacing) {
 667		value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL);
 668		value &= ~INTERLACE_ENABLE;
 669		tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL);
 670	}
 671
 672	value = SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER_PCD1;
 673	tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
 674
 675	/* setup window parameters */
 676	memset(&window, 0, sizeof(window));
 677	window.src.x = 0;
 678	window.src.y = 0;
 679	window.src.w = mode->hdisplay;
 680	window.src.h = mode->vdisplay;
 681	window.dst.x = 0;
 682	window.dst.y = 0;
 683	window.dst.w = mode->hdisplay;
 684	window.dst.h = mode->vdisplay;
 685	window.format = tegra_dc_format(crtc->primary->fb->pixel_format);
 686	window.bits_per_pixel = crtc->primary->fb->bits_per_pixel;
 687	window.stride[0] = crtc->primary->fb->pitches[0];
 688	window.base[0] = bo->paddr;
 689
 690	err = tegra_dc_setup_window(dc, 0, &window);
 691	if (err < 0)
 692		dev_err(dc->dev, "failed to enable root plane\n");
 693
 694	return 0;
 695}
 696
 697static int tegra_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 698				    struct drm_framebuffer *old_fb)
 699{
 700	struct tegra_dc *dc = to_tegra_dc(crtc);
 701
 702	return tegra_dc_set_base(dc, x, y, crtc->primary->fb);
 703}
 704
 705static void tegra_crtc_prepare(struct drm_crtc *crtc)
 706{
 707	struct tegra_dc *dc = to_tegra_dc(crtc);
 708	unsigned int syncpt;
 709	unsigned long value;
 710
 711	/* hardware initialization */
 712	reset_control_deassert(dc->rst);
 713	usleep_range(10000, 20000);
 714
 715	if (dc->pipe)
 716		syncpt = SYNCPT_VBLANK1;
 717	else
 718		syncpt = SYNCPT_VBLANK0;
 719
 720	/* initialize display controller */
 721	tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
 722	tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC);
 723
 724	value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT;
 725	tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
 726
 727	value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
 728		WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
 729	tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
 730
 731	value = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
 732		PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
 733	tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
 734
 735	/* initialize timer */
 736	value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
 737		WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
 738	tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY);
 739
 740	value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
 741		WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
 742	tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
 743
 744	value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
 745	tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
 746
 747	value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
 748	tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
 749}
 750
 751static void tegra_crtc_commit(struct drm_crtc *crtc)
 752{
 753	struct tegra_dc *dc = to_tegra_dc(crtc);
 754	unsigned long value;
 755
 756	value = GENERAL_UPDATE | WIN_A_UPDATE;
 757	tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
 758
 759	value = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
 760	tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
 761
 762	drm_vblank_post_modeset(crtc->dev, dc->pipe);
 763}
 764
 765static void tegra_crtc_load_lut(struct drm_crtc *crtc)
 766{
 767}
 768
 769static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
 770	.disable = tegra_crtc_disable,
 771	.mode_fixup = tegra_crtc_mode_fixup,
 772	.mode_set = tegra_crtc_mode_set,
 773	.mode_set_base = tegra_crtc_mode_set_base,
 774	.prepare = tegra_crtc_prepare,
 775	.commit = tegra_crtc_commit,
 776	.load_lut = tegra_crtc_load_lut,
 777};
 778
 779static irqreturn_t tegra_dc_irq(int irq, void *data)
 780{
 781	struct tegra_dc *dc = data;
 782	unsigned long status;
 783
 784	status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
 785	tegra_dc_writel(dc, status, DC_CMD_INT_STATUS);
 786
 787	if (status & FRAME_END_INT) {
 788		/*
 789		dev_dbg(dc->dev, "%s(): frame end\n", __func__);
 790		*/
 791	}
 792
 793	if (status & VBLANK_INT) {
 794		/*
 795		dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
 796		*/
 797		drm_handle_vblank(dc->base.dev, dc->pipe);
 798		tegra_dc_finish_page_flip(dc);
 799	}
 800
 801	if (status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)) {
 802		/*
 803		dev_dbg(dc->dev, "%s(): underflow\n", __func__);
 804		*/
 805	}
 806
 807	return IRQ_HANDLED;
 808}
 809
 810static int tegra_dc_show_regs(struct seq_file *s, void *data)
 811{
 812	struct drm_info_node *node = s->private;
 813	struct tegra_dc *dc = node->info_ent->data;
 814
 815#define DUMP_REG(name)						\
 816	seq_printf(s, "%-40s %#05x %08lx\n", #name, name,	\
 817		   tegra_dc_readl(dc, name))
 818
 819	DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT);
 820	DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
 821	DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_ERROR);
 822	DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT);
 823	DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL);
 824	DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_ERROR);
 825	DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT);
 826	DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL);
 827	DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_ERROR);
 828	DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT);
 829	DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL);
 830	DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_ERROR);
 831	DUMP_REG(DC_CMD_CONT_SYNCPT_VSYNC);
 832	DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0);
 833	DUMP_REG(DC_CMD_DISPLAY_COMMAND);
 834	DUMP_REG(DC_CMD_SIGNAL_RAISE);
 835	DUMP_REG(DC_CMD_DISPLAY_POWER_CONTROL);
 836	DUMP_REG(DC_CMD_INT_STATUS);
 837	DUMP_REG(DC_CMD_INT_MASK);
 838	DUMP_REG(DC_CMD_INT_ENABLE);
 839	DUMP_REG(DC_CMD_INT_TYPE);
 840	DUMP_REG(DC_CMD_INT_POLARITY);
 841	DUMP_REG(DC_CMD_SIGNAL_RAISE1);
 842	DUMP_REG(DC_CMD_SIGNAL_RAISE2);
 843	DUMP_REG(DC_CMD_SIGNAL_RAISE3);
 844	DUMP_REG(DC_CMD_STATE_ACCESS);
 845	DUMP_REG(DC_CMD_STATE_CONTROL);
 846	DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
 847	DUMP_REG(DC_CMD_REG_ACT_CONTROL);
 848	DUMP_REG(DC_COM_CRC_CONTROL);
 849	DUMP_REG(DC_COM_CRC_CHECKSUM);
 850	DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(0));
 851	DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(1));
 852	DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(2));
 853	DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(3));
 854	DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(0));
 855	DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(1));
 856	DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(2));
 857	DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(3));
 858	DUMP_REG(DC_COM_PIN_OUTPUT_DATA(0));
 859	DUMP_REG(DC_COM_PIN_OUTPUT_DATA(1));
 860	DUMP_REG(DC_COM_PIN_OUTPUT_DATA(2));
 861	DUMP_REG(DC_COM_PIN_OUTPUT_DATA(3));
 862	DUMP_REG(DC_COM_PIN_INPUT_ENABLE(0));
 863	DUMP_REG(DC_COM_PIN_INPUT_ENABLE(1));
 864	DUMP_REG(DC_COM_PIN_INPUT_ENABLE(2));
 865	DUMP_REG(DC_COM_PIN_INPUT_ENABLE(3));
 866	DUMP_REG(DC_COM_PIN_INPUT_DATA(0));
 867	DUMP_REG(DC_COM_PIN_INPUT_DATA(1));
 868	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(0));
 869	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(1));
 870	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(2));
 871	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(3));
 872	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(4));
 873	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(5));
 874	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(6));
 875	DUMP_REG(DC_COM_PIN_MISC_CONTROL);
 876	DUMP_REG(DC_COM_PIN_PM0_CONTROL);
 877	DUMP_REG(DC_COM_PIN_PM0_DUTY_CYCLE);
 878	DUMP_REG(DC_COM_PIN_PM1_CONTROL);
 879	DUMP_REG(DC_COM_PIN_PM1_DUTY_CYCLE);
 880	DUMP_REG(DC_COM_SPI_CONTROL);
 881	DUMP_REG(DC_COM_SPI_START_BYTE);
 882	DUMP_REG(DC_COM_HSPI_WRITE_DATA_AB);
 883	DUMP_REG(DC_COM_HSPI_WRITE_DATA_CD);
 884	DUMP_REG(DC_COM_HSPI_CS_DC);
 885	DUMP_REG(DC_COM_SCRATCH_REGISTER_A);
 886	DUMP_REG(DC_COM_SCRATCH_REGISTER_B);
 887	DUMP_REG(DC_COM_GPIO_CTRL);
 888	DUMP_REG(DC_COM_GPIO_DEBOUNCE_COUNTER);
 889	DUMP_REG(DC_COM_CRC_CHECKSUM_LATCHED);
 890	DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0);
 891	DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1);
 892	DUMP_REG(DC_DISP_DISP_WIN_OPTIONS);
 893	DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY);
 894	DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
 895	DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS);
 896	DUMP_REG(DC_DISP_REF_TO_SYNC);
 897	DUMP_REG(DC_DISP_SYNC_WIDTH);
 898	DUMP_REG(DC_DISP_BACK_PORCH);
 899	DUMP_REG(DC_DISP_ACTIVE);
 900	DUMP_REG(DC_DISP_FRONT_PORCH);
 901	DUMP_REG(DC_DISP_H_PULSE0_CONTROL);
 902	DUMP_REG(DC_DISP_H_PULSE0_POSITION_A);
 903	DUMP_REG(DC_DISP_H_PULSE0_POSITION_B);
 904	DUMP_REG(DC_DISP_H_PULSE0_POSITION_C);
 905	DUMP_REG(DC_DISP_H_PULSE0_POSITION_D);
 906	DUMP_REG(DC_DISP_H_PULSE1_CONTROL);
 907	DUMP_REG(DC_DISP_H_PULSE1_POSITION_A);
 908	DUMP_REG(DC_DISP_H_PULSE1_POSITION_B);
 909	DUMP_REG(DC_DISP_H_PULSE1_POSITION_C);
 910	DUMP_REG(DC_DISP_H_PULSE1_POSITION_D);
 911	DUMP_REG(DC_DISP_H_PULSE2_CONTROL);
 912	DUMP_REG(DC_DISP_H_PULSE2_POSITION_A);
 913	DUMP_REG(DC_DISP_H_PULSE2_POSITION_B);
 914	DUMP_REG(DC_DISP_H_PULSE2_POSITION_C);
 915	DUMP_REG(DC_DISP_H_PULSE2_POSITION_D);
 916	DUMP_REG(DC_DISP_V_PULSE0_CONTROL);
 917	DUMP_REG(DC_DISP_V_PULSE0_POSITION_A);
 918	DUMP_REG(DC_DISP_V_PULSE0_POSITION_B);
 919	DUMP_REG(DC_DISP_V_PULSE0_POSITION_C);
 920	DUMP_REG(DC_DISP_V_PULSE1_CONTROL);
 921	DUMP_REG(DC_DISP_V_PULSE1_POSITION_A);
 922	DUMP_REG(DC_DISP_V_PULSE1_POSITION_B);
 923	DUMP_REG(DC_DISP_V_PULSE1_POSITION_C);
 924	DUMP_REG(DC_DISP_V_PULSE2_CONTROL);
 925	DUMP_REG(DC_DISP_V_PULSE2_POSITION_A);
 926	DUMP_REG(DC_DISP_V_PULSE3_CONTROL);
 927	DUMP_REG(DC_DISP_V_PULSE3_POSITION_A);
 928	DUMP_REG(DC_DISP_M0_CONTROL);
 929	DUMP_REG(DC_DISP_M1_CONTROL);
 930	DUMP_REG(DC_DISP_DI_CONTROL);
 931	DUMP_REG(DC_DISP_PP_CONTROL);
 932	DUMP_REG(DC_DISP_PP_SELECT_A);
 933	DUMP_REG(DC_DISP_PP_SELECT_B);
 934	DUMP_REG(DC_DISP_PP_SELECT_C);
 935	DUMP_REG(DC_DISP_PP_SELECT_D);
 936	DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL);
 937	DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL);
 938	DUMP_REG(DC_DISP_DISP_COLOR_CONTROL);
 939	DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS);
 940	DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS);
 941	DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS);
 942	DUMP_REG(DC_DISP_LCD_SPI_OPTIONS);
 943	DUMP_REG(DC_DISP_BORDER_COLOR);
 944	DUMP_REG(DC_DISP_COLOR_KEY0_LOWER);
 945	DUMP_REG(DC_DISP_COLOR_KEY0_UPPER);
 946	DUMP_REG(DC_DISP_COLOR_KEY1_LOWER);
 947	DUMP_REG(DC_DISP_COLOR_KEY1_UPPER);
 948	DUMP_REG(DC_DISP_CURSOR_FOREGROUND);
 949	DUMP_REG(DC_DISP_CURSOR_BACKGROUND);
 950	DUMP_REG(DC_DISP_CURSOR_START_ADDR);
 951	DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS);
 952	DUMP_REG(DC_DISP_CURSOR_POSITION);
 953	DUMP_REG(DC_DISP_CURSOR_POSITION_NS);
 954	DUMP_REG(DC_DISP_INIT_SEQ_CONTROL);
 955	DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A);
 956	DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B);
 957	DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C);
 958	DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D);
 959	DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL);
 960	DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST);
 961	DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST);
 962	DUMP_REG(DC_DISP_MCCIF_DISPLAY1A_HYST);
 963	DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST);
 964	DUMP_REG(DC_DISP_DAC_CRT_CTRL);
 965	DUMP_REG(DC_DISP_DISP_MISC_CONTROL);
 966	DUMP_REG(DC_DISP_SD_CONTROL);
 967	DUMP_REG(DC_DISP_SD_CSC_COEFF);
 968	DUMP_REG(DC_DISP_SD_LUT(0));
 969	DUMP_REG(DC_DISP_SD_LUT(1));
 970	DUMP_REG(DC_DISP_SD_LUT(2));
 971	DUMP_REG(DC_DISP_SD_LUT(3));
 972	DUMP_REG(DC_DISP_SD_LUT(4));
 973	DUMP_REG(DC_DISP_SD_LUT(5));
 974	DUMP_REG(DC_DISP_SD_LUT(6));
 975	DUMP_REG(DC_DISP_SD_LUT(7));
 976	DUMP_REG(DC_DISP_SD_LUT(8));
 977	DUMP_REG(DC_DISP_SD_FLICKER_CONTROL);
 978	DUMP_REG(DC_DISP_DC_PIXEL_COUNT);
 979	DUMP_REG(DC_DISP_SD_HISTOGRAM(0));
 980	DUMP_REG(DC_DISP_SD_HISTOGRAM(1));
 981	DUMP_REG(DC_DISP_SD_HISTOGRAM(2));
 982	DUMP_REG(DC_DISP_SD_HISTOGRAM(3));
 983	DUMP_REG(DC_DISP_SD_HISTOGRAM(4));
 984	DUMP_REG(DC_DISP_SD_HISTOGRAM(5));
 985	DUMP_REG(DC_DISP_SD_HISTOGRAM(6));
 986	DUMP_REG(DC_DISP_SD_HISTOGRAM(7));
 987	DUMP_REG(DC_DISP_SD_BL_TF(0));
 988	DUMP_REG(DC_DISP_SD_BL_TF(1));
 989	DUMP_REG(DC_DISP_SD_BL_TF(2));
 990	DUMP_REG(DC_DISP_SD_BL_TF(3));
 991	DUMP_REG(DC_DISP_SD_BL_CONTROL);
 992	DUMP_REG(DC_DISP_SD_HW_K_VALUES);
 993	DUMP_REG(DC_DISP_SD_MAN_K_VALUES);
 994	DUMP_REG(DC_WIN_WIN_OPTIONS);
 995	DUMP_REG(DC_WIN_BYTE_SWAP);
 996	DUMP_REG(DC_WIN_BUFFER_CONTROL);
 997	DUMP_REG(DC_WIN_COLOR_DEPTH);
 998	DUMP_REG(DC_WIN_POSITION);
 999	DUMP_REG(DC_WIN_SIZE);
1000	DUMP_REG(DC_WIN_PRESCALED_SIZE);
1001	DUMP_REG(DC_WIN_H_INITIAL_DDA);
1002	DUMP_REG(DC_WIN_V_INITIAL_DDA);
1003	DUMP_REG(DC_WIN_DDA_INC);
1004	DUMP_REG(DC_WIN_LINE_STRIDE);
1005	DUMP_REG(DC_WIN_BUF_STRIDE);
1006	DUMP_REG(DC_WIN_UV_BUF_STRIDE);
1007	DUMP_REG(DC_WIN_BUFFER_ADDR_MODE);
1008	DUMP_REG(DC_WIN_DV_CONTROL);
1009	DUMP_REG(DC_WIN_BLEND_NOKEY);
1010	DUMP_REG(DC_WIN_BLEND_1WIN);
1011	DUMP_REG(DC_WIN_BLEND_2WIN_X);
1012	DUMP_REG(DC_WIN_BLEND_2WIN_Y);
1013	DUMP_REG(DC_WIN_BLEND_3WIN_XY);
1014	DUMP_REG(DC_WIN_HP_FETCH_CONTROL);
1015	DUMP_REG(DC_WINBUF_START_ADDR);
1016	DUMP_REG(DC_WINBUF_START_ADDR_NS);
1017	DUMP_REG(DC_WINBUF_START_ADDR_U);
1018	DUMP_REG(DC_WINBUF_START_ADDR_U_NS);
1019	DUMP_REG(DC_WINBUF_START_ADDR_V);
1020	DUMP_REG(DC_WINBUF_START_ADDR_V_NS);
1021	DUMP_REG(DC_WINBUF_ADDR_H_OFFSET);
1022	DUMP_REG(DC_WINBUF_ADDR_H_OFFSET_NS);
1023	DUMP_REG(DC_WINBUF_ADDR_V_OFFSET);
1024	DUMP_REG(DC_WINBUF_ADDR_V_OFFSET_NS);
1025	DUMP_REG(DC_WINBUF_UFLOW_STATUS);
1026	DUMP_REG(DC_WINBUF_AD_UFLOW_STATUS);
1027	DUMP_REG(DC_WINBUF_BD_UFLOW_STATUS);
1028	DUMP_REG(DC_WINBUF_CD_UFLOW_STATUS);
1029
1030#undef DUMP_REG
1031
1032	return 0;
1033}
1034
1035static struct drm_info_list debugfs_files[] = {
1036	{ "regs", tegra_dc_show_regs, 0, NULL },
1037};
1038
1039static int tegra_dc_debugfs_init(struct tegra_dc *dc, struct drm_minor *minor)
1040{
1041	unsigned int i;
1042	char *name;
1043	int err;
1044
1045	name = kasprintf(GFP_KERNEL, "dc.%d", dc->pipe);
1046	dc->debugfs = debugfs_create_dir(name, minor->debugfs_root);
1047	kfree(name);
1048
1049	if (!dc->debugfs)
1050		return -ENOMEM;
1051
1052	dc->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
1053				    GFP_KERNEL);
1054	if (!dc->debugfs_files) {
1055		err = -ENOMEM;
1056		goto remove;
1057	}
1058
1059	for (i = 0; i < ARRAY_SIZE(debugfs_files); i++)
1060		dc->debugfs_files[i].data = dc;
1061
1062	err = drm_debugfs_create_files(dc->debugfs_files,
1063				       ARRAY_SIZE(debugfs_files),
1064				       dc->debugfs, minor);
1065	if (err < 0)
1066		goto free;
1067
1068	dc->minor = minor;
1069
1070	return 0;
1071
1072free:
1073	kfree(dc->debugfs_files);
1074	dc->debugfs_files = NULL;
1075remove:
1076	debugfs_remove(dc->debugfs);
1077	dc->debugfs = NULL;
1078
1079	return err;
1080}
1081
1082static int tegra_dc_debugfs_exit(struct tegra_dc *dc)
1083{
1084	drm_debugfs_remove_files(dc->debugfs_files, ARRAY_SIZE(debugfs_files),
1085				 dc->minor);
1086	dc->minor = NULL;
1087
1088	kfree(dc->debugfs_files);
1089	dc->debugfs_files = NULL;
1090
1091	debugfs_remove(dc->debugfs);
1092	dc->debugfs = NULL;
1093
1094	return 0;
1095}
1096
1097static int tegra_dc_init(struct host1x_client *client)
1098{
1099	struct tegra_drm *tegra = dev_get_drvdata(client->parent);
1100	struct tegra_dc *dc = host1x_client_to_dc(client);
1101	int err;
1102
1103	drm_crtc_init(tegra->drm, &dc->base, &tegra_crtc_funcs);
1104	drm_mode_crtc_set_gamma_size(&dc->base, 256);
1105	drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
1106
1107	err = tegra_dc_rgb_init(tegra->drm, dc);
1108	if (err < 0 && err != -ENODEV) {
1109		dev_err(dc->dev, "failed to initialize RGB output: %d\n", err);
1110		return err;
1111	}
1112
1113	err = tegra_dc_add_planes(tegra->drm, dc);
1114	if (err < 0)
1115		return err;
1116
1117	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
1118		err = tegra_dc_debugfs_init(dc, tegra->drm->primary);
1119		if (err < 0)
1120			dev_err(dc->dev, "debugfs setup failed: %d\n", err);
1121	}
1122
1123	err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0,
1124			       dev_name(dc->dev), dc);
1125	if (err < 0) {
1126		dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq,
1127			err);
1128		return err;
1129	}
1130
1131	return 0;
1132}
1133
1134static int tegra_dc_exit(struct host1x_client *client)
1135{
1136	struct tegra_dc *dc = host1x_client_to_dc(client);
1137	int err;
1138
1139	devm_free_irq(dc->dev, dc->irq, dc);
1140
1141	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
1142		err = tegra_dc_debugfs_exit(dc);
1143		if (err < 0)
1144			dev_err(dc->dev, "debugfs cleanup failed: %d\n", err);
1145	}
1146
1147	err = tegra_dc_rgb_exit(dc);
1148	if (err) {
1149		dev_err(dc->dev, "failed to shutdown RGB output: %d\n", err);
1150		return err;
1151	}
1152
1153	return 0;
1154}
1155
1156static const struct host1x_client_ops dc_client_ops = {
1157	.init = tegra_dc_init,
1158	.exit = tegra_dc_exit,
1159};
1160
1161static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
1162	.supports_interlacing = false,
1163};
1164
1165static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
1166	.supports_interlacing = false,
1167};
1168
1169static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
1170	.supports_interlacing = true,
1171};
1172
1173static const struct of_device_id tegra_dc_of_match[] = {
1174	{
1175		.compatible = "nvidia,tegra124-dc",
1176		.data = &tegra124_dc_soc_info,
1177	}, {
1178		.compatible = "nvidia,tegra30-dc",
1179		.data = &tegra30_dc_soc_info,
1180	}, {
1181		.compatible = "nvidia,tegra20-dc",
1182		.data = &tegra20_dc_soc_info,
1183	}, {
1184		/* sentinel */
1185	}
1186};
1187
1188static int tegra_dc_parse_dt(struct tegra_dc *dc)
1189{
1190	struct device_node *np;
1191	u32 value = 0;
1192	int err;
1193
1194	err = of_property_read_u32(dc->dev->of_node, "nvidia,head", &value);
1195	if (err < 0) {
1196		dev_err(dc->dev, "missing \"nvidia,head\" property\n");
1197
1198		/*
1199		 * If the nvidia,head property isn't present, try to find the
1200		 * correct head number by looking up the position of this
1201		 * display controller's node within the device tree. Assuming
1202		 * that the nodes are ordered properly in the DTS file and
1203		 * that the translation into a flattened device tree blob
1204		 * preserves that ordering this will actually yield the right
1205		 * head number.
1206		 *
1207		 * If those assumptions don't hold, this will still work for
1208		 * cases where only a single display controller is used.
1209		 */
1210		for_each_matching_node(np, tegra_dc_of_match) {
1211			if (np == dc->dev->of_node)
1212				break;
1213
1214			value++;
1215		}
1216	}
1217
1218	dc->pipe = value;
1219
1220	return 0;
1221}
1222
1223static int tegra_dc_probe(struct platform_device *pdev)
1224{
1225	const struct of_device_id *id;
1226	struct resource *regs;
1227	struct tegra_dc *dc;
1228	int err;
1229
1230	dc = devm_kzalloc(&pdev->dev, sizeof(*dc), GFP_KERNEL);
1231	if (!dc)
1232		return -ENOMEM;
1233
1234	id = of_match_node(tegra_dc_of_match, pdev->dev.of_node);
1235	if (!id)
1236		return -ENODEV;
1237
1238	spin_lock_init(&dc->lock);
1239	INIT_LIST_HEAD(&dc->list);
1240	dc->dev = &pdev->dev;
1241	dc->soc = id->data;
1242
1243	err = tegra_dc_parse_dt(dc);
1244	if (err < 0)
1245		return err;
1246
1247	dc->clk = devm_clk_get(&pdev->dev, NULL);
1248	if (IS_ERR(dc->clk)) {
1249		dev_err(&pdev->dev, "failed to get clock\n");
1250		return PTR_ERR(dc->clk);
1251	}
1252
1253	dc->rst = devm_reset_control_get(&pdev->dev, "dc");
1254	if (IS_ERR(dc->rst)) {
1255		dev_err(&pdev->dev, "failed to get reset\n");
1256		return PTR_ERR(dc->rst);
1257	}
1258
1259	err = clk_prepare_enable(dc->clk);
1260	if (err < 0)
1261		return err;
1262
1263	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1264	dc->regs = devm_ioremap_resource(&pdev->dev, regs);
1265	if (IS_ERR(dc->regs))
1266		return PTR_ERR(dc->regs);
1267
1268	dc->irq = platform_get_irq(pdev, 0);
1269	if (dc->irq < 0) {
1270		dev_err(&pdev->dev, "failed to get IRQ\n");
1271		return -ENXIO;
1272	}
1273
1274	INIT_LIST_HEAD(&dc->client.list);
1275	dc->client.ops = &dc_client_ops;
1276	dc->client.dev = &pdev->dev;
1277
1278	err = tegra_dc_rgb_probe(dc);
1279	if (err < 0 && err != -ENODEV) {
1280		dev_err(&pdev->dev, "failed to probe RGB output: %d\n", err);
1281		return err;
1282	}
1283
1284	err = host1x_client_register(&dc->client);
1285	if (err < 0) {
1286		dev_err(&pdev->dev, "failed to register host1x client: %d\n",
1287			err);
1288		return err;
1289	}
1290
1291	platform_set_drvdata(pdev, dc);
1292
1293	return 0;
1294}
1295
1296static int tegra_dc_remove(struct platform_device *pdev)
1297{
1298	struct tegra_dc *dc = platform_get_drvdata(pdev);
1299	int err;
1300
1301	err = host1x_client_unregister(&dc->client);
1302	if (err < 0) {
1303		dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
1304			err);
1305		return err;
1306	}
1307
1308	err = tegra_dc_rgb_remove(dc);
1309	if (err < 0) {
1310		dev_err(&pdev->dev, "failed to remove RGB output: %d\n", err);
1311		return err;
1312	}
1313
1314	clk_disable_unprepare(dc->clk);
1315
1316	return 0;
1317}
1318
1319struct platform_driver tegra_dc_driver = {
1320	.driver = {
1321		.name = "tegra-dc",
1322		.owner = THIS_MODULE,
1323		.of_match_table = tegra_dc_of_match,
1324	},
1325	.probe = tegra_dc_probe,
1326	.remove = tegra_dc_remove,
1327};