]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/tegra/dc.c
Merge branch 'topic/core-stuff' into topic/atomic-core
[karo-tx-linux.git] / drivers / gpu / drm / tegra / dc.c
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/iommu.h>
13 #include <linux/reset.h>
14
15 #include <soc/tegra/pmc.h>
16
17 #include "dc.h"
18 #include "drm.h"
19 #include "gem.h"
20
21 #include <drm/drm_plane_helper.h>
22
23 struct tegra_dc_soc_info {
24         bool supports_interlacing;
25         bool supports_cursor;
26         bool supports_block_linear;
27         unsigned int pitch_align;
28         bool has_powergate;
29 };
30
31 struct tegra_plane {
32         struct drm_plane base;
33         unsigned int index;
34 };
35
36 static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane)
37 {
38         return container_of(plane, struct tegra_plane, base);
39 }
40
41 static void tegra_dc_window_commit(struct tegra_dc *dc, unsigned int index)
42 {
43         u32 value = WIN_A_ACT_REQ << index;
44
45         tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL);
46         tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
47 }
48
49 static void tegra_dc_cursor_commit(struct tegra_dc *dc)
50 {
51         tegra_dc_writel(dc, CURSOR_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
52         tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL);
53 }
54
55 static void tegra_dc_commit(struct tegra_dc *dc)
56 {
57         tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
58         tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
59 }
60
61 static unsigned int tegra_dc_format(uint32_t format, uint32_t *swap)
62 {
63         /* assume no swapping of fetched data */
64         if (swap)
65                 *swap = BYTE_SWAP_NOSWAP;
66
67         switch (format) {
68         case DRM_FORMAT_XBGR8888:
69                 return WIN_COLOR_DEPTH_R8G8B8A8;
70
71         case DRM_FORMAT_XRGB8888:
72                 return WIN_COLOR_DEPTH_B8G8R8A8;
73
74         case DRM_FORMAT_RGB565:
75                 return WIN_COLOR_DEPTH_B5G6R5;
76
77         case DRM_FORMAT_UYVY:
78                 return WIN_COLOR_DEPTH_YCbCr422;
79
80         case DRM_FORMAT_YUYV:
81                 if (swap)
82                         *swap = BYTE_SWAP_SWAP2;
83
84                 return WIN_COLOR_DEPTH_YCbCr422;
85
86         case DRM_FORMAT_YUV420:
87                 return WIN_COLOR_DEPTH_YCbCr420P;
88
89         case DRM_FORMAT_YUV422:
90                 return WIN_COLOR_DEPTH_YCbCr422P;
91
92         default:
93                 break;
94         }
95
96         WARN(1, "unsupported pixel format %u, using default\n", format);
97         return WIN_COLOR_DEPTH_B8G8R8A8;
98 }
99
100 static bool tegra_dc_format_is_yuv(unsigned int format, bool *planar)
101 {
102         switch (format) {
103         case WIN_COLOR_DEPTH_YCbCr422:
104         case WIN_COLOR_DEPTH_YUV422:
105                 if (planar)
106                         *planar = false;
107
108                 return true;
109
110         case WIN_COLOR_DEPTH_YCbCr420P:
111         case WIN_COLOR_DEPTH_YUV420P:
112         case WIN_COLOR_DEPTH_YCbCr422P:
113         case WIN_COLOR_DEPTH_YUV422P:
114         case WIN_COLOR_DEPTH_YCbCr422R:
115         case WIN_COLOR_DEPTH_YUV422R:
116         case WIN_COLOR_DEPTH_YCbCr422RA:
117         case WIN_COLOR_DEPTH_YUV422RA:
118                 if (planar)
119                         *planar = true;
120
121                 return true;
122         }
123
124         return false;
125 }
126
127 static inline u32 compute_dda_inc(unsigned int in, unsigned int out, bool v,
128                                   unsigned int bpp)
129 {
130         fixed20_12 outf = dfixed_init(out);
131         fixed20_12 inf = dfixed_init(in);
132         u32 dda_inc;
133         int max;
134
135         if (v)
136                 max = 15;
137         else {
138                 switch (bpp) {
139                 case 2:
140                         max = 8;
141                         break;
142
143                 default:
144                         WARN_ON_ONCE(1);
145                         /* fallthrough */
146                 case 4:
147                         max = 4;
148                         break;
149                 }
150         }
151
152         outf.full = max_t(u32, outf.full - dfixed_const(1), dfixed_const(1));
153         inf.full -= dfixed_const(1);
154
155         dda_inc = dfixed_div(inf, outf);
156         dda_inc = min_t(u32, dda_inc, dfixed_const(max));
157
158         return dda_inc;
159 }
160
161 static inline u32 compute_initial_dda(unsigned int in)
162 {
163         fixed20_12 inf = dfixed_init(in);
164         return dfixed_frac(inf);
165 }
166
167 static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
168                                  const struct tegra_dc_window *window)
169 {
170         unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
171         unsigned long value;
172         bool yuv, planar;
173
174         /*
175          * For YUV planar modes, the number of bytes per pixel takes into
176          * account only the luma component and therefore is 1.
177          */
178         yuv = tegra_dc_format_is_yuv(window->format, &planar);
179         if (!yuv)
180                 bpp = window->bits_per_pixel / 8;
181         else
182                 bpp = planar ? 1 : 2;
183
184         value = WINDOW_A_SELECT << index;
185         tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
186
187         tegra_dc_writel(dc, window->format, DC_WIN_COLOR_DEPTH);
188         tegra_dc_writel(dc, window->swap, DC_WIN_BYTE_SWAP);
189
190         value = V_POSITION(window->dst.y) | H_POSITION(window->dst.x);
191         tegra_dc_writel(dc, value, DC_WIN_POSITION);
192
193         value = V_SIZE(window->dst.h) | H_SIZE(window->dst.w);
194         tegra_dc_writel(dc, value, DC_WIN_SIZE);
195
196         h_offset = window->src.x * bpp;
197         v_offset = window->src.y;
198         h_size = window->src.w * bpp;
199         v_size = window->src.h;
200
201         value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size);
202         tegra_dc_writel(dc, value, DC_WIN_PRESCALED_SIZE);
203
204         /*
205          * For DDA computations the number of bytes per pixel for YUV planar
206          * modes needs to take into account all Y, U and V components.
207          */
208         if (yuv && planar)
209                 bpp = 2;
210
211         h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp);
212         v_dda = compute_dda_inc(window->src.h, window->dst.h, true, bpp);
213
214         value = V_DDA_INC(v_dda) | H_DDA_INC(h_dda);
215         tegra_dc_writel(dc, value, DC_WIN_DDA_INC);
216
217         h_dda = compute_initial_dda(window->src.x);
218         v_dda = compute_initial_dda(window->src.y);
219
220         tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA);
221         tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA);
222
223         tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
224         tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
225
226         tegra_dc_writel(dc, window->base[0], DC_WINBUF_START_ADDR);
227
228         if (yuv && planar) {
229                 tegra_dc_writel(dc, window->base[1], DC_WINBUF_START_ADDR_U);
230                 tegra_dc_writel(dc, window->base[2], DC_WINBUF_START_ADDR_V);
231                 value = window->stride[1] << 16 | window->stride[0];
232                 tegra_dc_writel(dc, value, DC_WIN_LINE_STRIDE);
233         } else {
234                 tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE);
235         }
236
237         if (window->bottom_up)
238                 v_offset += window->src.h - 1;
239
240         tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
241         tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
242
243         if (dc->soc->supports_block_linear) {
244                 unsigned long height = window->tiling.value;
245
246                 switch (window->tiling.mode) {
247                 case TEGRA_BO_TILING_MODE_PITCH:
248                         value = DC_WINBUF_SURFACE_KIND_PITCH;
249                         break;
250
251                 case TEGRA_BO_TILING_MODE_TILED:
252                         value = DC_WINBUF_SURFACE_KIND_TILED;
253                         break;
254
255                 case TEGRA_BO_TILING_MODE_BLOCK:
256                         value = DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(height) |
257                                 DC_WINBUF_SURFACE_KIND_BLOCK;
258                         break;
259                 }
260
261                 tegra_dc_writel(dc, value, DC_WINBUF_SURFACE_KIND);
262         } else {
263                 switch (window->tiling.mode) {
264                 case TEGRA_BO_TILING_MODE_PITCH:
265                         value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
266                                 DC_WIN_BUFFER_ADDR_MODE_LINEAR;
267                         break;
268
269                 case TEGRA_BO_TILING_MODE_TILED:
270                         value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
271                                 DC_WIN_BUFFER_ADDR_MODE_TILE;
272                         break;
273
274                 case TEGRA_BO_TILING_MODE_BLOCK:
275                         DRM_ERROR("hardware doesn't support block linear mode\n");
276                         return -EINVAL;
277                 }
278
279                 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
280         }
281
282         value = WIN_ENABLE;
283
284         if (yuv) {
285                 /* setup default colorspace conversion coefficients */
286                 tegra_dc_writel(dc, 0x00f0, DC_WIN_CSC_YOF);
287                 tegra_dc_writel(dc, 0x012a, DC_WIN_CSC_KYRGB);
288                 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KUR);
289                 tegra_dc_writel(dc, 0x0198, DC_WIN_CSC_KVR);
290                 tegra_dc_writel(dc, 0x039b, DC_WIN_CSC_KUG);
291                 tegra_dc_writel(dc, 0x032f, DC_WIN_CSC_KVG);
292                 tegra_dc_writel(dc, 0x0204, DC_WIN_CSC_KUB);
293                 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KVB);
294
295                 value |= CSC_ENABLE;
296         } else if (window->bits_per_pixel < 24) {
297                 value |= COLOR_EXPAND;
298         }
299
300         if (window->bottom_up)
301                 value |= V_DIRECTION;
302
303         tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
304
305         /*
306          * Disable blending and assume Window A is the bottom-most window,
307          * Window C is the top-most window and Window B is in the middle.
308          */
309         tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_NOKEY);
310         tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_1WIN);
311
312         switch (index) {
313         case 0:
314                 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_X);
315                 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
316                 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
317                 break;
318
319         case 1:
320                 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
321                 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
322                 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
323                 break;
324
325         case 2:
326                 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
327                 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_Y);
328                 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_3WIN_XY);
329                 break;
330         }
331
332         tegra_dc_window_commit(dc, index);
333
334         return 0;
335 }
336
337 static int tegra_window_plane_disable(struct drm_plane *plane)
338 {
339         struct tegra_dc *dc = to_tegra_dc(plane->crtc);
340         struct tegra_plane *p = to_tegra_plane(plane);
341         u32 value;
342
343         if (!plane->crtc)
344                 return 0;
345
346         value = WINDOW_A_SELECT << p->index;
347         tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
348
349         value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
350         value &= ~WIN_ENABLE;
351         tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
352
353         tegra_dc_window_commit(dc, p->index);
354
355         return 0;
356 }
357
358 static void tegra_plane_destroy(struct drm_plane *plane)
359 {
360         struct tegra_plane *p = to_tegra_plane(plane);
361
362         drm_plane_cleanup(plane);
363         kfree(p);
364 }
365
366 static const u32 tegra_primary_plane_formats[] = {
367         DRM_FORMAT_XBGR8888,
368         DRM_FORMAT_XRGB8888,
369         DRM_FORMAT_RGB565,
370 };
371
372 static int tegra_primary_plane_update(struct drm_plane *plane,
373                                       struct drm_crtc *crtc,
374                                       struct drm_framebuffer *fb, int crtc_x,
375                                       int crtc_y, unsigned int crtc_w,
376                                       unsigned int crtc_h, uint32_t src_x,
377                                       uint32_t src_y, uint32_t src_w,
378                                       uint32_t src_h)
379 {
380         struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
381         struct tegra_plane *p = to_tegra_plane(plane);
382         struct tegra_dc *dc = to_tegra_dc(crtc);
383         struct tegra_dc_window window;
384         int err;
385
386         memset(&window, 0, sizeof(window));
387         window.src.x = src_x >> 16;
388         window.src.y = src_y >> 16;
389         window.src.w = src_w >> 16;
390         window.src.h = src_h >> 16;
391         window.dst.x = crtc_x;
392         window.dst.y = crtc_y;
393         window.dst.w = crtc_w;
394         window.dst.h = crtc_h;
395         window.format = tegra_dc_format(fb->pixel_format, &window.swap);
396         window.bits_per_pixel = fb->bits_per_pixel;
397         window.bottom_up = tegra_fb_is_bottom_up(fb);
398
399         err = tegra_fb_get_tiling(fb, &window.tiling);
400         if (err < 0)
401                 return err;
402
403         window.base[0] = bo->paddr + fb->offsets[0];
404         window.stride[0] = fb->pitches[0];
405
406         err = tegra_dc_setup_window(dc, p->index, &window);
407         if (err < 0)
408                 return err;
409
410         return 0;
411 }
412
413 static void tegra_primary_plane_destroy(struct drm_plane *plane)
414 {
415         tegra_window_plane_disable(plane);
416         tegra_plane_destroy(plane);
417 }
418
419 static const struct drm_plane_funcs tegra_primary_plane_funcs = {
420         .update_plane = tegra_primary_plane_update,
421         .disable_plane = tegra_window_plane_disable,
422         .destroy = tegra_primary_plane_destroy,
423 };
424
425 static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
426                                                        struct tegra_dc *dc)
427 {
428         struct tegra_plane *plane;
429         unsigned int num_formats;
430         const u32 *formats;
431         int err;
432
433         plane = kzalloc(sizeof(*plane), GFP_KERNEL);
434         if (!plane)
435                 return ERR_PTR(-ENOMEM);
436
437         num_formats = ARRAY_SIZE(tegra_primary_plane_formats);
438         formats = tegra_primary_plane_formats;
439
440         err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
441                                        &tegra_primary_plane_funcs, formats,
442                                        num_formats, DRM_PLANE_TYPE_PRIMARY);
443         if (err < 0) {
444                 kfree(plane);
445                 return ERR_PTR(err);
446         }
447
448         return &plane->base;
449 }
450
451 static const u32 tegra_cursor_plane_formats[] = {
452         DRM_FORMAT_RGBA8888,
453 };
454
455 static int tegra_cursor_plane_update(struct drm_plane *plane,
456                                      struct drm_crtc *crtc,
457                                      struct drm_framebuffer *fb, int crtc_x,
458                                      int crtc_y, unsigned int crtc_w,
459                                      unsigned int crtc_h, uint32_t src_x,
460                                      uint32_t src_y, uint32_t src_w,
461                                      uint32_t src_h)
462 {
463         struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
464         struct tegra_dc *dc = to_tegra_dc(crtc);
465         u32 value = CURSOR_CLIP_DISPLAY;
466
467         /* scaling not supported for cursor */
468         if ((src_w >> 16 != crtc_w) || (src_h >> 16 != crtc_h))
469                 return -EINVAL;
470
471         /* only square cursors supported */
472         if (src_w != src_h)
473                 return -EINVAL;
474
475         switch (crtc_w) {
476         case 32:
477                 value |= CURSOR_SIZE_32x32;
478                 break;
479
480         case 64:
481                 value |= CURSOR_SIZE_64x64;
482                 break;
483
484         case 128:
485                 value |= CURSOR_SIZE_128x128;
486                 break;
487
488         case 256:
489                 value |= CURSOR_SIZE_256x256;
490                 break;
491
492         default:
493                 return -EINVAL;
494         }
495
496         value |= (bo->paddr >> 10) & 0x3fffff;
497         tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR);
498
499 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
500         value = (bo->paddr >> 32) & 0x3;
501         tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR_HI);
502 #endif
503
504         /* enable cursor and set blend mode */
505         value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
506         value |= CURSOR_ENABLE;
507         tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
508
509         value = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL);
510         value &= ~CURSOR_DST_BLEND_MASK;
511         value &= ~CURSOR_SRC_BLEND_MASK;
512         value |= CURSOR_MODE_NORMAL;
513         value |= CURSOR_DST_BLEND_NEG_K1_TIMES_SRC;
514         value |= CURSOR_SRC_BLEND_K1_TIMES_SRC;
515         value |= CURSOR_ALPHA;
516         tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL);
517
518         /* position the cursor */
519         value = (crtc_y & 0x3fff) << 16 | (crtc_x & 0x3fff);
520         tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION);
521
522         /* apply changes */
523         tegra_dc_cursor_commit(dc);
524         tegra_dc_commit(dc);
525
526         return 0;
527 }
528
529 static int tegra_cursor_plane_disable(struct drm_plane *plane)
530 {
531         struct tegra_dc *dc = to_tegra_dc(plane->crtc);
532         u32 value;
533
534         if (!plane->crtc)
535                 return 0;
536
537         value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
538         value &= ~CURSOR_ENABLE;
539         tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
540
541         tegra_dc_cursor_commit(dc);
542         tegra_dc_commit(dc);
543
544         return 0;
545 }
546
547 static const struct drm_plane_funcs tegra_cursor_plane_funcs = {
548         .update_plane = tegra_cursor_plane_update,
549         .disable_plane = tegra_cursor_plane_disable,
550         .destroy = tegra_plane_destroy,
551 };
552
553 static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
554                                                       struct tegra_dc *dc)
555 {
556         struct tegra_plane *plane;
557         unsigned int num_formats;
558         const u32 *formats;
559         int err;
560
561         plane = kzalloc(sizeof(*plane), GFP_KERNEL);
562         if (!plane)
563                 return ERR_PTR(-ENOMEM);
564
565         num_formats = ARRAY_SIZE(tegra_cursor_plane_formats);
566         formats = tegra_cursor_plane_formats;
567
568         err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
569                                        &tegra_cursor_plane_funcs, formats,
570                                        num_formats, DRM_PLANE_TYPE_CURSOR);
571         if (err < 0) {
572                 kfree(plane);
573                 return ERR_PTR(err);
574         }
575
576         return &plane->base;
577 }
578
579 static int tegra_overlay_plane_update(struct drm_plane *plane,
580                                       struct drm_crtc *crtc,
581                                       struct drm_framebuffer *fb, int crtc_x,
582                                       int crtc_y, unsigned int crtc_w,
583                                       unsigned int crtc_h, uint32_t src_x,
584                                       uint32_t src_y, uint32_t src_w,
585                                       uint32_t src_h)
586 {
587         struct tegra_plane *p = to_tegra_plane(plane);
588         struct tegra_dc *dc = to_tegra_dc(crtc);
589         struct tegra_dc_window window;
590         unsigned int i;
591         int err;
592
593         memset(&window, 0, sizeof(window));
594         window.src.x = src_x >> 16;
595         window.src.y = src_y >> 16;
596         window.src.w = src_w >> 16;
597         window.src.h = src_h >> 16;
598         window.dst.x = crtc_x;
599         window.dst.y = crtc_y;
600         window.dst.w = crtc_w;
601         window.dst.h = crtc_h;
602         window.format = tegra_dc_format(fb->pixel_format, &window.swap);
603         window.bits_per_pixel = fb->bits_per_pixel;
604         window.bottom_up = tegra_fb_is_bottom_up(fb);
605
606         err = tegra_fb_get_tiling(fb, &window.tiling);
607         if (err < 0)
608                 return err;
609
610         for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
611                 struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
612
613                 window.base[i] = bo->paddr + fb->offsets[i];
614
615                 /*
616                  * Tegra doesn't support different strides for U and V planes
617                  * so we display a warning if the user tries to display a
618                  * framebuffer with such a configuration.
619                  */
620                 if (i >= 2) {
621                         if (fb->pitches[i] != window.stride[1])
622                                 DRM_ERROR("unsupported UV-plane configuration\n");
623                 } else {
624                         window.stride[i] = fb->pitches[i];
625                 }
626         }
627
628         return tegra_dc_setup_window(dc, p->index, &window);
629 }
630
631 static void tegra_overlay_plane_destroy(struct drm_plane *plane)
632 {
633         tegra_window_plane_disable(plane);
634         tegra_plane_destroy(plane);
635 }
636
637 static const struct drm_plane_funcs tegra_overlay_plane_funcs = {
638         .update_plane = tegra_overlay_plane_update,
639         .disable_plane = tegra_window_plane_disable,
640         .destroy = tegra_overlay_plane_destroy,
641 };
642
643 static const uint32_t tegra_overlay_plane_formats[] = {
644         DRM_FORMAT_XBGR8888,
645         DRM_FORMAT_XRGB8888,
646         DRM_FORMAT_RGB565,
647         DRM_FORMAT_UYVY,
648         DRM_FORMAT_YUYV,
649         DRM_FORMAT_YUV420,
650         DRM_FORMAT_YUV422,
651 };
652
653 static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
654                                                        struct tegra_dc *dc,
655                                                        unsigned int index)
656 {
657         struct tegra_plane *plane;
658         unsigned int num_formats;
659         const u32 *formats;
660         int err;
661
662         plane = kzalloc(sizeof(*plane), GFP_KERNEL);
663         if (!plane)
664                 return ERR_PTR(-ENOMEM);
665
666         plane->index = index;
667
668         num_formats = ARRAY_SIZE(tegra_overlay_plane_formats);
669         formats = tegra_overlay_plane_formats;
670
671         err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
672                                        &tegra_overlay_plane_funcs, formats,
673                                        num_formats, DRM_PLANE_TYPE_OVERLAY);
674         if (err < 0) {
675                 kfree(plane);
676                 return ERR_PTR(err);
677         }
678
679         return &plane->base;
680 }
681
682 static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
683 {
684         struct drm_plane *plane;
685         unsigned int i;
686
687         for (i = 0; i < 2; i++) {
688                 plane = tegra_dc_overlay_plane_create(drm, dc, 1 + i);
689                 if (IS_ERR(plane))
690                         return PTR_ERR(plane);
691         }
692
693         return 0;
694 }
695
696 static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
697                              struct drm_framebuffer *fb)
698 {
699         struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
700         unsigned int h_offset = 0, v_offset = 0;
701         struct tegra_bo_tiling tiling;
702         unsigned int format, swap;
703         unsigned long value;
704         int err;
705
706         err = tegra_fb_get_tiling(fb, &tiling);
707         if (err < 0)
708                 return err;
709
710         tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
711
712         value = fb->offsets[0] + y * fb->pitches[0] +
713                 x * fb->bits_per_pixel / 8;
714
715         tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR);
716         tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
717
718         format = tegra_dc_format(fb->pixel_format, &swap);
719         tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH);
720         tegra_dc_writel(dc, swap, DC_WIN_BYTE_SWAP);
721
722         if (dc->soc->supports_block_linear) {
723                 unsigned long height = tiling.value;
724
725                 switch (tiling.mode) {
726                 case TEGRA_BO_TILING_MODE_PITCH:
727                         value = DC_WINBUF_SURFACE_KIND_PITCH;
728                         break;
729
730                 case TEGRA_BO_TILING_MODE_TILED:
731                         value = DC_WINBUF_SURFACE_KIND_TILED;
732                         break;
733
734                 case TEGRA_BO_TILING_MODE_BLOCK:
735                         value = DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(height) |
736                                 DC_WINBUF_SURFACE_KIND_BLOCK;
737                         break;
738                 }
739
740                 tegra_dc_writel(dc, value, DC_WINBUF_SURFACE_KIND);
741         } else {
742                 switch (tiling.mode) {
743                 case TEGRA_BO_TILING_MODE_PITCH:
744                         value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
745                                 DC_WIN_BUFFER_ADDR_MODE_LINEAR;
746                         break;
747
748                 case TEGRA_BO_TILING_MODE_TILED:
749                         value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
750                                 DC_WIN_BUFFER_ADDR_MODE_TILE;
751                         break;
752
753                 case TEGRA_BO_TILING_MODE_BLOCK:
754                         DRM_ERROR("hardware doesn't support block linear mode\n");
755                         return -EINVAL;
756                 }
757
758                 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
759         }
760
761         /* make sure bottom-up buffers are properly displayed */
762         if (tegra_fb_is_bottom_up(fb)) {
763                 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
764                 value |= V_DIRECTION;
765                 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
766
767                 v_offset += fb->height - 1;
768         } else {
769                 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
770                 value &= ~V_DIRECTION;
771                 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
772         }
773
774         tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
775         tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
776
777         value = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
778         tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL);
779         tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
780
781         return 0;
782 }
783
784 void tegra_dc_enable_vblank(struct tegra_dc *dc)
785 {
786         unsigned long value, flags;
787
788         spin_lock_irqsave(&dc->lock, flags);
789
790         value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
791         value |= VBLANK_INT;
792         tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
793
794         spin_unlock_irqrestore(&dc->lock, flags);
795 }
796
797 void tegra_dc_disable_vblank(struct tegra_dc *dc)
798 {
799         unsigned long value, flags;
800
801         spin_lock_irqsave(&dc->lock, flags);
802
803         value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
804         value &= ~VBLANK_INT;
805         tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
806
807         spin_unlock_irqrestore(&dc->lock, flags);
808 }
809
810 static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
811 {
812         struct drm_device *drm = dc->base.dev;
813         struct drm_crtc *crtc = &dc->base;
814         unsigned long flags, base;
815         struct tegra_bo *bo;
816
817         if (!dc->event)
818                 return;
819
820         bo = tegra_fb_get_plane(crtc->primary->fb, 0);
821
822         /* check if new start address has been latched */
823         tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
824         base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
825         tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
826
827         if (base == bo->paddr + crtc->primary->fb->offsets[0]) {
828                 spin_lock_irqsave(&drm->event_lock, flags);
829                 drm_send_vblank_event(drm, dc->pipe, dc->event);
830                 drm_vblank_put(drm, dc->pipe);
831                 dc->event = NULL;
832                 spin_unlock_irqrestore(&drm->event_lock, flags);
833         }
834 }
835
836 void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
837 {
838         struct tegra_dc *dc = to_tegra_dc(crtc);
839         struct drm_device *drm = crtc->dev;
840         unsigned long flags;
841
842         spin_lock_irqsave(&drm->event_lock, flags);
843
844         if (dc->event && dc->event->base.file_priv == file) {
845                 dc->event->base.destroy(&dc->event->base);
846                 drm_vblank_put(drm, dc->pipe);
847                 dc->event = NULL;
848         }
849
850         spin_unlock_irqrestore(&drm->event_lock, flags);
851 }
852
853 static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
854                               struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
855 {
856         struct tegra_dc *dc = to_tegra_dc(crtc);
857         struct drm_device *drm = crtc->dev;
858
859         if (dc->event)
860                 return -EBUSY;
861
862         if (event) {
863                 event->pipe = dc->pipe;
864                 dc->event = event;
865                 drm_vblank_get(drm, dc->pipe);
866         }
867
868         tegra_dc_set_base(dc, 0, 0, fb);
869         crtc->primary->fb = fb;
870
871         return 0;
872 }
873
874 static void drm_crtc_clear(struct drm_crtc *crtc)
875 {
876         memset(crtc, 0, sizeof(*crtc));
877 }
878
879 static void tegra_dc_destroy(struct drm_crtc *crtc)
880 {
881         drm_crtc_cleanup(crtc);
882         drm_crtc_clear(crtc);
883 }
884
885 static const struct drm_crtc_funcs tegra_crtc_funcs = {
886         .page_flip = tegra_dc_page_flip,
887         .set_config = drm_crtc_helper_set_config,
888         .destroy = tegra_dc_destroy,
889 };
890
891 static void tegra_crtc_disable(struct drm_crtc *crtc)
892 {
893         struct tegra_dc *dc = to_tegra_dc(crtc);
894         struct drm_device *drm = crtc->dev;
895         struct drm_plane *plane;
896
897         drm_for_each_legacy_plane(plane, &drm->mode_config.plane_list) {
898                 if (plane->crtc == crtc) {
899                         tegra_window_plane_disable(plane);
900                         plane->crtc = NULL;
901
902                         if (plane->fb) {
903                                 drm_framebuffer_unreference(plane->fb);
904                                 plane->fb = NULL;
905                         }
906                 }
907         }
908
909         drm_crtc_vblank_off(crtc);
910         tegra_dc_commit(dc);
911 }
912
913 static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
914                                   const struct drm_display_mode *mode,
915                                   struct drm_display_mode *adjusted)
916 {
917         return true;
918 }
919
920 static int tegra_dc_set_timings(struct tegra_dc *dc,
921                                 struct drm_display_mode *mode)
922 {
923         unsigned int h_ref_to_sync = 1;
924         unsigned int v_ref_to_sync = 1;
925         unsigned long value;
926
927         tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS);
928
929         value = (v_ref_to_sync << 16) | h_ref_to_sync;
930         tegra_dc_writel(dc, value, DC_DISP_REF_TO_SYNC);
931
932         value = ((mode->vsync_end - mode->vsync_start) << 16) |
933                 ((mode->hsync_end - mode->hsync_start) <<  0);
934         tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH);
935
936         value = ((mode->vtotal - mode->vsync_end) << 16) |
937                 ((mode->htotal - mode->hsync_end) <<  0);
938         tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH);
939
940         value = ((mode->vsync_start - mode->vdisplay) << 16) |
941                 ((mode->hsync_start - mode->hdisplay) <<  0);
942         tegra_dc_writel(dc, value, DC_DISP_FRONT_PORCH);
943
944         value = (mode->vdisplay << 16) | mode->hdisplay;
945         tegra_dc_writel(dc, value, DC_DISP_ACTIVE);
946
947         return 0;
948 }
949
950 static int tegra_crtc_setup_clk(struct drm_crtc *crtc,
951                                 struct drm_display_mode *mode)
952 {
953         unsigned long pclk = mode->clock * 1000;
954         struct tegra_dc *dc = to_tegra_dc(crtc);
955         struct tegra_output *output = NULL;
956         struct drm_encoder *encoder;
957         unsigned int div;
958         u32 value;
959         long err;
960
961         list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list, head)
962                 if (encoder->crtc == crtc) {
963                         output = encoder_to_output(encoder);
964                         break;
965                 }
966
967         if (!output)
968                 return -ENODEV;
969
970         /*
971          * This assumes that the parent clock is pll_d_out0 or pll_d2_out
972          * respectively, each of which divides the base pll_d by 2.
973          */
974         err = tegra_output_setup_clock(output, dc->clk, pclk, &div);
975         if (err < 0) {
976                 dev_err(dc->dev, "failed to setup clock: %ld\n", err);
977                 return err;
978         }
979
980         DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk), div);
981
982         value = SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER_PCD1;
983         tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
984
985         return 0;
986 }
987
988 static int tegra_crtc_mode_set(struct drm_crtc *crtc,
989                                struct drm_display_mode *mode,
990                                struct drm_display_mode *adjusted,
991                                int x, int y, struct drm_framebuffer *old_fb)
992 {
993         struct tegra_bo *bo = tegra_fb_get_plane(crtc->primary->fb, 0);
994         struct tegra_dc *dc = to_tegra_dc(crtc);
995         struct tegra_dc_window window;
996         u32 value;
997         int err;
998
999         err = tegra_crtc_setup_clk(crtc, mode);
1000         if (err) {
1001                 dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err);
1002                 return err;
1003         }
1004
1005         /* program display mode */
1006         tegra_dc_set_timings(dc, mode);
1007
1008         /* interlacing isn't supported yet, so disable it */
1009         if (dc->soc->supports_interlacing) {
1010                 value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL);
1011                 value &= ~INTERLACE_ENABLE;
1012                 tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL);
1013         }
1014
1015         /* setup window parameters */
1016         memset(&window, 0, sizeof(window));
1017         window.src.x = 0;
1018         window.src.y = 0;
1019         window.src.w = mode->hdisplay;
1020         window.src.h = mode->vdisplay;
1021         window.dst.x = 0;
1022         window.dst.y = 0;
1023         window.dst.w = mode->hdisplay;
1024         window.dst.h = mode->vdisplay;
1025         window.format = tegra_dc_format(crtc->primary->fb->pixel_format,
1026                                         &window.swap);
1027         window.bits_per_pixel = crtc->primary->fb->bits_per_pixel;
1028         window.stride[0] = crtc->primary->fb->pitches[0];
1029         window.base[0] = bo->paddr;
1030
1031         err = tegra_dc_setup_window(dc, 0, &window);
1032         if (err < 0)
1033                 dev_err(dc->dev, "failed to enable root plane\n");
1034
1035         return 0;
1036 }
1037
1038 static int tegra_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
1039                                     struct drm_framebuffer *old_fb)
1040 {
1041         struct tegra_dc *dc = to_tegra_dc(crtc);
1042
1043         return tegra_dc_set_base(dc, x, y, crtc->primary->fb);
1044 }
1045
1046 static void tegra_crtc_prepare(struct drm_crtc *crtc)
1047 {
1048         struct tegra_dc *dc = to_tegra_dc(crtc);
1049         unsigned int syncpt;
1050         unsigned long value;
1051
1052         drm_crtc_vblank_off(crtc);
1053
1054         /* hardware initialization */
1055         reset_control_deassert(dc->rst);
1056         usleep_range(10000, 20000);
1057
1058         if (dc->pipe)
1059                 syncpt = SYNCPT_VBLANK1;
1060         else
1061                 syncpt = SYNCPT_VBLANK0;
1062
1063         /* initialize display controller */
1064         tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
1065         tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC);
1066
1067         value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT;
1068         tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
1069
1070         value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1071                 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1072         tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
1073
1074         /* initialize timer */
1075         value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
1076                 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
1077         tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY);
1078
1079         value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
1080                 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
1081         tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
1082
1083         value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
1084         tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
1085
1086         value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
1087         tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
1088 }
1089
1090 static void tegra_crtc_commit(struct drm_crtc *crtc)
1091 {
1092         struct tegra_dc *dc = to_tegra_dc(crtc);
1093
1094         drm_crtc_vblank_on(crtc);
1095         tegra_dc_commit(dc);
1096 }
1097
1098 static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
1099         .disable = tegra_crtc_disable,
1100         .mode_fixup = tegra_crtc_mode_fixup,
1101         .mode_set = tegra_crtc_mode_set,
1102         .mode_set_base = tegra_crtc_mode_set_base,
1103         .prepare = tegra_crtc_prepare,
1104         .commit = tegra_crtc_commit,
1105 };
1106
1107 static irqreturn_t tegra_dc_irq(int irq, void *data)
1108 {
1109         struct tegra_dc *dc = data;
1110         unsigned long status;
1111
1112         status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
1113         tegra_dc_writel(dc, status, DC_CMD_INT_STATUS);
1114
1115         if (status & FRAME_END_INT) {
1116                 /*
1117                 dev_dbg(dc->dev, "%s(): frame end\n", __func__);
1118                 */
1119         }
1120
1121         if (status & VBLANK_INT) {
1122                 /*
1123                 dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
1124                 */
1125                 drm_handle_vblank(dc->base.dev, dc->pipe);
1126                 tegra_dc_finish_page_flip(dc);
1127         }
1128
1129         if (status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)) {
1130                 /*
1131                 dev_dbg(dc->dev, "%s(): underflow\n", __func__);
1132                 */
1133         }
1134
1135         return IRQ_HANDLED;
1136 }
1137
1138 static int tegra_dc_show_regs(struct seq_file *s, void *data)
1139 {
1140         struct drm_info_node *node = s->private;
1141         struct tegra_dc *dc = node->info_ent->data;
1142
1143 #define DUMP_REG(name)                                          \
1144         seq_printf(s, "%-40s %#05x %08x\n", #name, name,        \
1145                    tegra_dc_readl(dc, name))
1146
1147         DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT);
1148         DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
1149         DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_ERROR);
1150         DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT);
1151         DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL);
1152         DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_ERROR);
1153         DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT);
1154         DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL);
1155         DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_ERROR);
1156         DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT);
1157         DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL);
1158         DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_ERROR);
1159         DUMP_REG(DC_CMD_CONT_SYNCPT_VSYNC);
1160         DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0);
1161         DUMP_REG(DC_CMD_DISPLAY_COMMAND);
1162         DUMP_REG(DC_CMD_SIGNAL_RAISE);
1163         DUMP_REG(DC_CMD_DISPLAY_POWER_CONTROL);
1164         DUMP_REG(DC_CMD_INT_STATUS);
1165         DUMP_REG(DC_CMD_INT_MASK);
1166         DUMP_REG(DC_CMD_INT_ENABLE);
1167         DUMP_REG(DC_CMD_INT_TYPE);
1168         DUMP_REG(DC_CMD_INT_POLARITY);
1169         DUMP_REG(DC_CMD_SIGNAL_RAISE1);
1170         DUMP_REG(DC_CMD_SIGNAL_RAISE2);
1171         DUMP_REG(DC_CMD_SIGNAL_RAISE3);
1172         DUMP_REG(DC_CMD_STATE_ACCESS);
1173         DUMP_REG(DC_CMD_STATE_CONTROL);
1174         DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
1175         DUMP_REG(DC_CMD_REG_ACT_CONTROL);
1176         DUMP_REG(DC_COM_CRC_CONTROL);
1177         DUMP_REG(DC_COM_CRC_CHECKSUM);
1178         DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(0));
1179         DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(1));
1180         DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(2));
1181         DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(3));
1182         DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(0));
1183         DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(1));
1184         DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(2));
1185         DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(3));
1186         DUMP_REG(DC_COM_PIN_OUTPUT_DATA(0));
1187         DUMP_REG(DC_COM_PIN_OUTPUT_DATA(1));
1188         DUMP_REG(DC_COM_PIN_OUTPUT_DATA(2));
1189         DUMP_REG(DC_COM_PIN_OUTPUT_DATA(3));
1190         DUMP_REG(DC_COM_PIN_INPUT_ENABLE(0));
1191         DUMP_REG(DC_COM_PIN_INPUT_ENABLE(1));
1192         DUMP_REG(DC_COM_PIN_INPUT_ENABLE(2));
1193         DUMP_REG(DC_COM_PIN_INPUT_ENABLE(3));
1194         DUMP_REG(DC_COM_PIN_INPUT_DATA(0));
1195         DUMP_REG(DC_COM_PIN_INPUT_DATA(1));
1196         DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(0));
1197         DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(1));
1198         DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(2));
1199         DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(3));
1200         DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(4));
1201         DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(5));
1202         DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(6));
1203         DUMP_REG(DC_COM_PIN_MISC_CONTROL);
1204         DUMP_REG(DC_COM_PIN_PM0_CONTROL);
1205         DUMP_REG(DC_COM_PIN_PM0_DUTY_CYCLE);
1206         DUMP_REG(DC_COM_PIN_PM1_CONTROL);
1207         DUMP_REG(DC_COM_PIN_PM1_DUTY_CYCLE);
1208         DUMP_REG(DC_COM_SPI_CONTROL);
1209         DUMP_REG(DC_COM_SPI_START_BYTE);
1210         DUMP_REG(DC_COM_HSPI_WRITE_DATA_AB);
1211         DUMP_REG(DC_COM_HSPI_WRITE_DATA_CD);
1212         DUMP_REG(DC_COM_HSPI_CS_DC);
1213         DUMP_REG(DC_COM_SCRATCH_REGISTER_A);
1214         DUMP_REG(DC_COM_SCRATCH_REGISTER_B);
1215         DUMP_REG(DC_COM_GPIO_CTRL);
1216         DUMP_REG(DC_COM_GPIO_DEBOUNCE_COUNTER);
1217         DUMP_REG(DC_COM_CRC_CHECKSUM_LATCHED);
1218         DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0);
1219         DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1);
1220         DUMP_REG(DC_DISP_DISP_WIN_OPTIONS);
1221         DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY);
1222         DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
1223         DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS);
1224         DUMP_REG(DC_DISP_REF_TO_SYNC);
1225         DUMP_REG(DC_DISP_SYNC_WIDTH);
1226         DUMP_REG(DC_DISP_BACK_PORCH);
1227         DUMP_REG(DC_DISP_ACTIVE);
1228         DUMP_REG(DC_DISP_FRONT_PORCH);
1229         DUMP_REG(DC_DISP_H_PULSE0_CONTROL);
1230         DUMP_REG(DC_DISP_H_PULSE0_POSITION_A);
1231         DUMP_REG(DC_DISP_H_PULSE0_POSITION_B);
1232         DUMP_REG(DC_DISP_H_PULSE0_POSITION_C);
1233         DUMP_REG(DC_DISP_H_PULSE0_POSITION_D);
1234         DUMP_REG(DC_DISP_H_PULSE1_CONTROL);
1235         DUMP_REG(DC_DISP_H_PULSE1_POSITION_A);
1236         DUMP_REG(DC_DISP_H_PULSE1_POSITION_B);
1237         DUMP_REG(DC_DISP_H_PULSE1_POSITION_C);
1238         DUMP_REG(DC_DISP_H_PULSE1_POSITION_D);
1239         DUMP_REG(DC_DISP_H_PULSE2_CONTROL);
1240         DUMP_REG(DC_DISP_H_PULSE2_POSITION_A);
1241         DUMP_REG(DC_DISP_H_PULSE2_POSITION_B);
1242         DUMP_REG(DC_DISP_H_PULSE2_POSITION_C);
1243         DUMP_REG(DC_DISP_H_PULSE2_POSITION_D);
1244         DUMP_REG(DC_DISP_V_PULSE0_CONTROL);
1245         DUMP_REG(DC_DISP_V_PULSE0_POSITION_A);
1246         DUMP_REG(DC_DISP_V_PULSE0_POSITION_B);
1247         DUMP_REG(DC_DISP_V_PULSE0_POSITION_C);
1248         DUMP_REG(DC_DISP_V_PULSE1_CONTROL);
1249         DUMP_REG(DC_DISP_V_PULSE1_POSITION_A);
1250         DUMP_REG(DC_DISP_V_PULSE1_POSITION_B);
1251         DUMP_REG(DC_DISP_V_PULSE1_POSITION_C);
1252         DUMP_REG(DC_DISP_V_PULSE2_CONTROL);
1253         DUMP_REG(DC_DISP_V_PULSE2_POSITION_A);
1254         DUMP_REG(DC_DISP_V_PULSE3_CONTROL);
1255         DUMP_REG(DC_DISP_V_PULSE3_POSITION_A);
1256         DUMP_REG(DC_DISP_M0_CONTROL);
1257         DUMP_REG(DC_DISP_M1_CONTROL);
1258         DUMP_REG(DC_DISP_DI_CONTROL);
1259         DUMP_REG(DC_DISP_PP_CONTROL);
1260         DUMP_REG(DC_DISP_PP_SELECT_A);
1261         DUMP_REG(DC_DISP_PP_SELECT_B);
1262         DUMP_REG(DC_DISP_PP_SELECT_C);
1263         DUMP_REG(DC_DISP_PP_SELECT_D);
1264         DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL);
1265         DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL);
1266         DUMP_REG(DC_DISP_DISP_COLOR_CONTROL);
1267         DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS);
1268         DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS);
1269         DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS);
1270         DUMP_REG(DC_DISP_LCD_SPI_OPTIONS);
1271         DUMP_REG(DC_DISP_BORDER_COLOR);
1272         DUMP_REG(DC_DISP_COLOR_KEY0_LOWER);
1273         DUMP_REG(DC_DISP_COLOR_KEY0_UPPER);
1274         DUMP_REG(DC_DISP_COLOR_KEY1_LOWER);
1275         DUMP_REG(DC_DISP_COLOR_KEY1_UPPER);
1276         DUMP_REG(DC_DISP_CURSOR_FOREGROUND);
1277         DUMP_REG(DC_DISP_CURSOR_BACKGROUND);
1278         DUMP_REG(DC_DISP_CURSOR_START_ADDR);
1279         DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS);
1280         DUMP_REG(DC_DISP_CURSOR_POSITION);
1281         DUMP_REG(DC_DISP_CURSOR_POSITION_NS);
1282         DUMP_REG(DC_DISP_INIT_SEQ_CONTROL);
1283         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A);
1284         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B);
1285         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C);
1286         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D);
1287         DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL);
1288         DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST);
1289         DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST);
1290         DUMP_REG(DC_DISP_MCCIF_DISPLAY1A_HYST);
1291         DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST);
1292         DUMP_REG(DC_DISP_DAC_CRT_CTRL);
1293         DUMP_REG(DC_DISP_DISP_MISC_CONTROL);
1294         DUMP_REG(DC_DISP_SD_CONTROL);
1295         DUMP_REG(DC_DISP_SD_CSC_COEFF);
1296         DUMP_REG(DC_DISP_SD_LUT(0));
1297         DUMP_REG(DC_DISP_SD_LUT(1));
1298         DUMP_REG(DC_DISP_SD_LUT(2));
1299         DUMP_REG(DC_DISP_SD_LUT(3));
1300         DUMP_REG(DC_DISP_SD_LUT(4));
1301         DUMP_REG(DC_DISP_SD_LUT(5));
1302         DUMP_REG(DC_DISP_SD_LUT(6));
1303         DUMP_REG(DC_DISP_SD_LUT(7));
1304         DUMP_REG(DC_DISP_SD_LUT(8));
1305         DUMP_REG(DC_DISP_SD_FLICKER_CONTROL);
1306         DUMP_REG(DC_DISP_DC_PIXEL_COUNT);
1307         DUMP_REG(DC_DISP_SD_HISTOGRAM(0));
1308         DUMP_REG(DC_DISP_SD_HISTOGRAM(1));
1309         DUMP_REG(DC_DISP_SD_HISTOGRAM(2));
1310         DUMP_REG(DC_DISP_SD_HISTOGRAM(3));
1311         DUMP_REG(DC_DISP_SD_HISTOGRAM(4));
1312         DUMP_REG(DC_DISP_SD_HISTOGRAM(5));
1313         DUMP_REG(DC_DISP_SD_HISTOGRAM(6));
1314         DUMP_REG(DC_DISP_SD_HISTOGRAM(7));
1315         DUMP_REG(DC_DISP_SD_BL_TF(0));
1316         DUMP_REG(DC_DISP_SD_BL_TF(1));
1317         DUMP_REG(DC_DISP_SD_BL_TF(2));
1318         DUMP_REG(DC_DISP_SD_BL_TF(3));
1319         DUMP_REG(DC_DISP_SD_BL_CONTROL);
1320         DUMP_REG(DC_DISP_SD_HW_K_VALUES);
1321         DUMP_REG(DC_DISP_SD_MAN_K_VALUES);
1322         DUMP_REG(DC_DISP_CURSOR_START_ADDR_HI);
1323         DUMP_REG(DC_DISP_BLEND_CURSOR_CONTROL);
1324         DUMP_REG(DC_WIN_WIN_OPTIONS);
1325         DUMP_REG(DC_WIN_BYTE_SWAP);
1326         DUMP_REG(DC_WIN_BUFFER_CONTROL);
1327         DUMP_REG(DC_WIN_COLOR_DEPTH);
1328         DUMP_REG(DC_WIN_POSITION);
1329         DUMP_REG(DC_WIN_SIZE);
1330         DUMP_REG(DC_WIN_PRESCALED_SIZE);
1331         DUMP_REG(DC_WIN_H_INITIAL_DDA);
1332         DUMP_REG(DC_WIN_V_INITIAL_DDA);
1333         DUMP_REG(DC_WIN_DDA_INC);
1334         DUMP_REG(DC_WIN_LINE_STRIDE);
1335         DUMP_REG(DC_WIN_BUF_STRIDE);
1336         DUMP_REG(DC_WIN_UV_BUF_STRIDE);
1337         DUMP_REG(DC_WIN_BUFFER_ADDR_MODE);
1338         DUMP_REG(DC_WIN_DV_CONTROL);
1339         DUMP_REG(DC_WIN_BLEND_NOKEY);
1340         DUMP_REG(DC_WIN_BLEND_1WIN);
1341         DUMP_REG(DC_WIN_BLEND_2WIN_X);
1342         DUMP_REG(DC_WIN_BLEND_2WIN_Y);
1343         DUMP_REG(DC_WIN_BLEND_3WIN_XY);
1344         DUMP_REG(DC_WIN_HP_FETCH_CONTROL);
1345         DUMP_REG(DC_WINBUF_START_ADDR);
1346         DUMP_REG(DC_WINBUF_START_ADDR_NS);
1347         DUMP_REG(DC_WINBUF_START_ADDR_U);
1348         DUMP_REG(DC_WINBUF_START_ADDR_U_NS);
1349         DUMP_REG(DC_WINBUF_START_ADDR_V);
1350         DUMP_REG(DC_WINBUF_START_ADDR_V_NS);
1351         DUMP_REG(DC_WINBUF_ADDR_H_OFFSET);
1352         DUMP_REG(DC_WINBUF_ADDR_H_OFFSET_NS);
1353         DUMP_REG(DC_WINBUF_ADDR_V_OFFSET);
1354         DUMP_REG(DC_WINBUF_ADDR_V_OFFSET_NS);
1355         DUMP_REG(DC_WINBUF_UFLOW_STATUS);
1356         DUMP_REG(DC_WINBUF_AD_UFLOW_STATUS);
1357         DUMP_REG(DC_WINBUF_BD_UFLOW_STATUS);
1358         DUMP_REG(DC_WINBUF_CD_UFLOW_STATUS);
1359
1360 #undef DUMP_REG
1361
1362         return 0;
1363 }
1364
1365 static struct drm_info_list debugfs_files[] = {
1366         { "regs", tegra_dc_show_regs, 0, NULL },
1367 };
1368
1369 static int tegra_dc_debugfs_init(struct tegra_dc *dc, struct drm_minor *minor)
1370 {
1371         unsigned int i;
1372         char *name;
1373         int err;
1374
1375         name = kasprintf(GFP_KERNEL, "dc.%d", dc->pipe);
1376         dc->debugfs = debugfs_create_dir(name, minor->debugfs_root);
1377         kfree(name);
1378
1379         if (!dc->debugfs)
1380                 return -ENOMEM;
1381
1382         dc->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
1383                                     GFP_KERNEL);
1384         if (!dc->debugfs_files) {
1385                 err = -ENOMEM;
1386                 goto remove;
1387         }
1388
1389         for (i = 0; i < ARRAY_SIZE(debugfs_files); i++)
1390                 dc->debugfs_files[i].data = dc;
1391
1392         err = drm_debugfs_create_files(dc->debugfs_files,
1393                                        ARRAY_SIZE(debugfs_files),
1394                                        dc->debugfs, minor);
1395         if (err < 0)
1396                 goto free;
1397
1398         dc->minor = minor;
1399
1400         return 0;
1401
1402 free:
1403         kfree(dc->debugfs_files);
1404         dc->debugfs_files = NULL;
1405 remove:
1406         debugfs_remove(dc->debugfs);
1407         dc->debugfs = NULL;
1408
1409         return err;
1410 }
1411
1412 static int tegra_dc_debugfs_exit(struct tegra_dc *dc)
1413 {
1414         drm_debugfs_remove_files(dc->debugfs_files, ARRAY_SIZE(debugfs_files),
1415                                  dc->minor);
1416         dc->minor = NULL;
1417
1418         kfree(dc->debugfs_files);
1419         dc->debugfs_files = NULL;
1420
1421         debugfs_remove(dc->debugfs);
1422         dc->debugfs = NULL;
1423
1424         return 0;
1425 }
1426
1427 static int tegra_dc_init(struct host1x_client *client)
1428 {
1429         struct drm_device *drm = dev_get_drvdata(client->parent);
1430         struct tegra_dc *dc = host1x_client_to_dc(client);
1431         struct tegra_drm *tegra = drm->dev_private;
1432         struct drm_plane *primary = NULL;
1433         struct drm_plane *cursor = NULL;
1434         int err;
1435
1436         if (tegra->domain) {
1437                 err = iommu_attach_device(tegra->domain, dc->dev);
1438                 if (err < 0) {
1439                         dev_err(dc->dev, "failed to attach to domain: %d\n",
1440                                 err);
1441                         return err;
1442                 }
1443
1444                 dc->domain = tegra->domain;
1445         }
1446
1447         primary = tegra_dc_primary_plane_create(drm, dc);
1448         if (IS_ERR(primary)) {
1449                 err = PTR_ERR(primary);
1450                 goto cleanup;
1451         }
1452
1453         if (dc->soc->supports_cursor) {
1454                 cursor = tegra_dc_cursor_plane_create(drm, dc);
1455                 if (IS_ERR(cursor)) {
1456                         err = PTR_ERR(cursor);
1457                         goto cleanup;
1458                 }
1459         }
1460
1461         err = drm_crtc_init_with_planes(drm, &dc->base, primary, cursor,
1462                                         &tegra_crtc_funcs);
1463         if (err < 0)
1464                 goto cleanup;
1465
1466         drm_mode_crtc_set_gamma_size(&dc->base, 256);
1467         drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
1468
1469         /*
1470          * Keep track of the minimum pitch alignment across all display
1471          * controllers.
1472          */
1473         if (dc->soc->pitch_align > tegra->pitch_align)
1474                 tegra->pitch_align = dc->soc->pitch_align;
1475
1476         err = tegra_dc_rgb_init(drm, dc);
1477         if (err < 0 && err != -ENODEV) {
1478                 dev_err(dc->dev, "failed to initialize RGB output: %d\n", err);
1479                 goto cleanup;
1480         }
1481
1482         err = tegra_dc_add_planes(drm, dc);
1483         if (err < 0)
1484                 goto cleanup;
1485
1486         if (IS_ENABLED(CONFIG_DEBUG_FS)) {
1487                 err = tegra_dc_debugfs_init(dc, drm->primary);
1488                 if (err < 0)
1489                         dev_err(dc->dev, "debugfs setup failed: %d\n", err);
1490         }
1491
1492         err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0,
1493                                dev_name(dc->dev), dc);
1494         if (err < 0) {
1495                 dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq,
1496                         err);
1497                 goto cleanup;
1498         }
1499
1500         return 0;
1501
1502 cleanup:
1503         if (cursor)
1504                 drm_plane_cleanup(cursor);
1505
1506         if (primary)
1507                 drm_plane_cleanup(primary);
1508
1509         if (tegra->domain) {
1510                 iommu_detach_device(tegra->domain, dc->dev);
1511                 dc->domain = NULL;
1512         }
1513
1514         return err;
1515 }
1516
1517 static int tegra_dc_exit(struct host1x_client *client)
1518 {
1519         struct tegra_dc *dc = host1x_client_to_dc(client);
1520         int err;
1521
1522         devm_free_irq(dc->dev, dc->irq, dc);
1523
1524         if (IS_ENABLED(CONFIG_DEBUG_FS)) {
1525                 err = tegra_dc_debugfs_exit(dc);
1526                 if (err < 0)
1527                         dev_err(dc->dev, "debugfs cleanup failed: %d\n", err);
1528         }
1529
1530         err = tegra_dc_rgb_exit(dc);
1531         if (err) {
1532                 dev_err(dc->dev, "failed to shutdown RGB output: %d\n", err);
1533                 return err;
1534         }
1535
1536         if (dc->domain) {
1537                 iommu_detach_device(dc->domain, dc->dev);
1538                 dc->domain = NULL;
1539         }
1540
1541         return 0;
1542 }
1543
1544 static const struct host1x_client_ops dc_client_ops = {
1545         .init = tegra_dc_init,
1546         .exit = tegra_dc_exit,
1547 };
1548
1549 static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
1550         .supports_interlacing = false,
1551         .supports_cursor = false,
1552         .supports_block_linear = false,
1553         .pitch_align = 8,
1554         .has_powergate = false,
1555 };
1556
1557 static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
1558         .supports_interlacing = false,
1559         .supports_cursor = false,
1560         .supports_block_linear = false,
1561         .pitch_align = 8,
1562         .has_powergate = false,
1563 };
1564
1565 static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
1566         .supports_interlacing = false,
1567         .supports_cursor = false,
1568         .supports_block_linear = false,
1569         .pitch_align = 64,
1570         .has_powergate = true,
1571 };
1572
1573 static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
1574         .supports_interlacing = true,
1575         .supports_cursor = true,
1576         .supports_block_linear = true,
1577         .pitch_align = 64,
1578         .has_powergate = true,
1579 };
1580
1581 static const struct of_device_id tegra_dc_of_match[] = {
1582         {
1583                 .compatible = "nvidia,tegra124-dc",
1584                 .data = &tegra124_dc_soc_info,
1585         }, {
1586                 .compatible = "nvidia,tegra114-dc",
1587                 .data = &tegra114_dc_soc_info,
1588         }, {
1589                 .compatible = "nvidia,tegra30-dc",
1590                 .data = &tegra30_dc_soc_info,
1591         }, {
1592                 .compatible = "nvidia,tegra20-dc",
1593                 .data = &tegra20_dc_soc_info,
1594         }, {
1595                 /* sentinel */
1596         }
1597 };
1598 MODULE_DEVICE_TABLE(of, tegra_dc_of_match);
1599
1600 static int tegra_dc_parse_dt(struct tegra_dc *dc)
1601 {
1602         struct device_node *np;
1603         u32 value = 0;
1604         int err;
1605
1606         err = of_property_read_u32(dc->dev->of_node, "nvidia,head", &value);
1607         if (err < 0) {
1608                 dev_err(dc->dev, "missing \"nvidia,head\" property\n");
1609
1610                 /*
1611                  * If the nvidia,head property isn't present, try to find the
1612                  * correct head number by looking up the position of this
1613                  * display controller's node within the device tree. Assuming
1614                  * that the nodes are ordered properly in the DTS file and
1615                  * that the translation into a flattened device tree blob
1616                  * preserves that ordering this will actually yield the right
1617                  * head number.
1618                  *
1619                  * If those assumptions don't hold, this will still work for
1620                  * cases where only a single display controller is used.
1621                  */
1622                 for_each_matching_node(np, tegra_dc_of_match) {
1623                         if (np == dc->dev->of_node)
1624                                 break;
1625
1626                         value++;
1627                 }
1628         }
1629
1630         dc->pipe = value;
1631
1632         return 0;
1633 }
1634
1635 static int tegra_dc_probe(struct platform_device *pdev)
1636 {
1637         const struct of_device_id *id;
1638         struct resource *regs;
1639         struct tegra_dc *dc;
1640         int err;
1641
1642         dc = devm_kzalloc(&pdev->dev, sizeof(*dc), GFP_KERNEL);
1643         if (!dc)
1644                 return -ENOMEM;
1645
1646         id = of_match_node(tegra_dc_of_match, pdev->dev.of_node);
1647         if (!id)
1648                 return -ENODEV;
1649
1650         spin_lock_init(&dc->lock);
1651         INIT_LIST_HEAD(&dc->list);
1652         dc->dev = &pdev->dev;
1653         dc->soc = id->data;
1654
1655         err = tegra_dc_parse_dt(dc);
1656         if (err < 0)
1657                 return err;
1658
1659         dc->clk = devm_clk_get(&pdev->dev, NULL);
1660         if (IS_ERR(dc->clk)) {
1661                 dev_err(&pdev->dev, "failed to get clock\n");
1662                 return PTR_ERR(dc->clk);
1663         }
1664
1665         dc->rst = devm_reset_control_get(&pdev->dev, "dc");
1666         if (IS_ERR(dc->rst)) {
1667                 dev_err(&pdev->dev, "failed to get reset\n");
1668                 return PTR_ERR(dc->rst);
1669         }
1670
1671         if (dc->soc->has_powergate) {
1672                 if (dc->pipe == 0)
1673                         dc->powergate = TEGRA_POWERGATE_DIS;
1674                 else
1675                         dc->powergate = TEGRA_POWERGATE_DISB;
1676
1677                 err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk,
1678                                                         dc->rst);
1679                 if (err < 0) {
1680                         dev_err(&pdev->dev, "failed to power partition: %d\n",
1681                                 err);
1682                         return err;
1683                 }
1684         } else {
1685                 err = clk_prepare_enable(dc->clk);
1686                 if (err < 0) {
1687                         dev_err(&pdev->dev, "failed to enable clock: %d\n",
1688                                 err);
1689                         return err;
1690                 }
1691
1692                 err = reset_control_deassert(dc->rst);
1693                 if (err < 0) {
1694                         dev_err(&pdev->dev, "failed to deassert reset: %d\n",
1695                                 err);
1696                         return err;
1697                 }
1698         }
1699
1700         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1701         dc->regs = devm_ioremap_resource(&pdev->dev, regs);
1702         if (IS_ERR(dc->regs))
1703                 return PTR_ERR(dc->regs);
1704
1705         dc->irq = platform_get_irq(pdev, 0);
1706         if (dc->irq < 0) {
1707                 dev_err(&pdev->dev, "failed to get IRQ\n");
1708                 return -ENXIO;
1709         }
1710
1711         INIT_LIST_HEAD(&dc->client.list);
1712         dc->client.ops = &dc_client_ops;
1713         dc->client.dev = &pdev->dev;
1714
1715         err = tegra_dc_rgb_probe(dc);
1716         if (err < 0 && err != -ENODEV) {
1717                 dev_err(&pdev->dev, "failed to probe RGB output: %d\n", err);
1718                 return err;
1719         }
1720
1721         err = host1x_client_register(&dc->client);
1722         if (err < 0) {
1723                 dev_err(&pdev->dev, "failed to register host1x client: %d\n",
1724                         err);
1725                 return err;
1726         }
1727
1728         platform_set_drvdata(pdev, dc);
1729
1730         return 0;
1731 }
1732
1733 static int tegra_dc_remove(struct platform_device *pdev)
1734 {
1735         struct tegra_dc *dc = platform_get_drvdata(pdev);
1736         int err;
1737
1738         err = host1x_client_unregister(&dc->client);
1739         if (err < 0) {
1740                 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
1741                         err);
1742                 return err;
1743         }
1744
1745         err = tegra_dc_rgb_remove(dc);
1746         if (err < 0) {
1747                 dev_err(&pdev->dev, "failed to remove RGB output: %d\n", err);
1748                 return err;
1749         }
1750
1751         reset_control_assert(dc->rst);
1752
1753         if (dc->soc->has_powergate)
1754                 tegra_powergate_power_off(dc->powergate);
1755
1756         clk_disable_unprepare(dc->clk);
1757
1758         return 0;
1759 }
1760
1761 struct platform_driver tegra_dc_driver = {
1762         .driver = {
1763                 .name = "tegra-dc",
1764                 .owner = THIS_MODULE,
1765                 .of_match_table = tegra_dc_of_match,
1766         },
1767         .probe = tegra_dc_probe,
1768         .remove = tegra_dc_remove,
1769 };