temp revert rk change
[firefly-linux-kernel-4.4.55.git] / drivers / video / tegra / dc / dc.c
1 /*
2  * drivers/video/tegra/dc/dc.c
3  *
4  * Copyright (C) 2010 Google, Inc.
5  * Author: Erik Gilling <konkers@android.com>
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/err.h>
21 #include <linux/errno.h>
22 #include <linux/interrupt.h>
23 #include <linux/slab.h>
24 #include <linux/io.h>
25 #include <linux/clk.h>
26 #include <linux/mutex.h>
27 #include <linux/delay.h>
28 #include <linux/dma-mapping.h>
29 #include <linux/workqueue.h>
30 #include <linux/ktime.h>
31 #include <linux/debugfs.h>
32 #include <linux/seq_file.h>
33
34 #include <mach/clk.h>
35 #include <mach/dc.h>
36 #include <mach/fb.h>
37 #include <mach/mc.h>
38 #include <mach/nvhost.h>
39
40 #include "dc_reg.h"
41 #include "dc_priv.h"
42
43 static int no_vsync;
44
45 module_param_named(no_vsync, no_vsync, int, S_IRUGO | S_IWUSR);
46
47 struct tegra_dc *tegra_dcs[TEGRA_MAX_DC];
48
49 DEFINE_MUTEX(tegra_dc_lock);
50
51 static inline int tegra_dc_fmt_bpp(int fmt)
52 {
53         switch (fmt) {
54         case TEGRA_WIN_FMT_P1:
55                 return 1;
56
57         case TEGRA_WIN_FMT_P2:
58                 return 2;
59
60         case TEGRA_WIN_FMT_P4:
61                 return 4;
62
63         case TEGRA_WIN_FMT_P8:
64                 return 8;
65
66         case TEGRA_WIN_FMT_B4G4R4A4:
67         case TEGRA_WIN_FMT_B5G5R5A:
68         case TEGRA_WIN_FMT_B5G6R5:
69         case TEGRA_WIN_FMT_AB5G5R5:
70                 return 16;
71
72         case TEGRA_WIN_FMT_B8G8R8A8:
73         case TEGRA_WIN_FMT_R8G8B8A8:
74         case TEGRA_WIN_FMT_B6x2G6x2R6x2A8:
75         case TEGRA_WIN_FMT_R6x2G6x2B6x2A8:
76                 return 32;
77
78         /* for planar formats, size of the Y plane, 8bit */
79         case TEGRA_WIN_FMT_YCbCr420P:
80         case TEGRA_WIN_FMT_YUV420P:
81         case TEGRA_WIN_FMT_YCbCr422P:
82         case TEGRA_WIN_FMT_YUV422P:
83                 return 8;
84
85         case TEGRA_WIN_FMT_YCbCr422:
86         case TEGRA_WIN_FMT_YUV422:
87         case TEGRA_WIN_FMT_YCbCr422R:
88         case TEGRA_WIN_FMT_YUV422R:
89         case TEGRA_WIN_FMT_YCbCr422RA:
90         case TEGRA_WIN_FMT_YUV422RA:
91                 /* FIXME: need to know the bpp of these formats */
92                 return 0;
93         }
94         return 0;
95 }
96
97 static inline bool tegra_dc_is_yuv_planar(int fmt)
98 {
99         switch (fmt) {
100         case TEGRA_WIN_FMT_YUV420P:
101         case TEGRA_WIN_FMT_YCbCr420P:
102         case TEGRA_WIN_FMT_YCbCr422P:
103         case TEGRA_WIN_FMT_YUV422P:
104                 return true;
105         }
106         return false;
107 }
108
109 #define DUMP_REG(a) do {                        \
110         snprintf(buff, sizeof(buff), "%-32s\t%03x\t%08lx\n", \
111                  #a, a, tegra_dc_readl(dc, a));               \
112         print(data, buff);                                    \
113         } while (0)
114
115 static void _dump_regs(struct tegra_dc *dc, void *data,
116                        void (* print)(void *data, const char *str))
117 {
118         int i;
119         char buff[256];
120
121         tegra_dc_io_start(dc);
122         clk_enable(dc->clk);
123
124         DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0);
125         DUMP_REG(DC_CMD_DISPLAY_COMMAND);
126         DUMP_REG(DC_CMD_SIGNAL_RAISE);
127         DUMP_REG(DC_CMD_INT_STATUS);
128         DUMP_REG(DC_CMD_INT_MASK);
129         DUMP_REG(DC_CMD_INT_ENABLE);
130         DUMP_REG(DC_CMD_INT_TYPE);
131         DUMP_REG(DC_CMD_INT_POLARITY);
132         DUMP_REG(DC_CMD_SIGNAL_RAISE1);
133         DUMP_REG(DC_CMD_SIGNAL_RAISE2);
134         DUMP_REG(DC_CMD_SIGNAL_RAISE3);
135         DUMP_REG(DC_CMD_STATE_ACCESS);
136         DUMP_REG(DC_CMD_STATE_CONTROL);
137         DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
138         DUMP_REG(DC_CMD_REG_ACT_CONTROL);
139
140         DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0);
141         DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1);
142         DUMP_REG(DC_DISP_DISP_WIN_OPTIONS);
143         DUMP_REG(DC_DISP_MEM_HIGH_PRIORITY);
144         DUMP_REG(DC_DISP_MEM_HIGH_PRIORITY_TIMER);
145         DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS);
146         DUMP_REG(DC_DISP_REF_TO_SYNC);
147         DUMP_REG(DC_DISP_SYNC_WIDTH);
148         DUMP_REG(DC_DISP_BACK_PORCH);
149         DUMP_REG(DC_DISP_DISP_ACTIVE);
150         DUMP_REG(DC_DISP_FRONT_PORCH);
151         DUMP_REG(DC_DISP_H_PULSE0_CONTROL);
152         DUMP_REG(DC_DISP_H_PULSE0_POSITION_A);
153         DUMP_REG(DC_DISP_H_PULSE0_POSITION_B);
154         DUMP_REG(DC_DISP_H_PULSE0_POSITION_C);
155         DUMP_REG(DC_DISP_H_PULSE0_POSITION_D);
156         DUMP_REG(DC_DISP_H_PULSE1_CONTROL);
157         DUMP_REG(DC_DISP_H_PULSE1_POSITION_A);
158         DUMP_REG(DC_DISP_H_PULSE1_POSITION_B);
159         DUMP_REG(DC_DISP_H_PULSE1_POSITION_C);
160         DUMP_REG(DC_DISP_H_PULSE1_POSITION_D);
161         DUMP_REG(DC_DISP_H_PULSE2_CONTROL);
162         DUMP_REG(DC_DISP_H_PULSE2_POSITION_A);
163         DUMP_REG(DC_DISP_H_PULSE2_POSITION_B);
164         DUMP_REG(DC_DISP_H_PULSE2_POSITION_C);
165         DUMP_REG(DC_DISP_H_PULSE2_POSITION_D);
166         DUMP_REG(DC_DISP_V_PULSE0_CONTROL);
167         DUMP_REG(DC_DISP_V_PULSE0_POSITION_A);
168         DUMP_REG(DC_DISP_V_PULSE0_POSITION_B);
169         DUMP_REG(DC_DISP_V_PULSE0_POSITION_C);
170         DUMP_REG(DC_DISP_V_PULSE1_CONTROL);
171         DUMP_REG(DC_DISP_V_PULSE1_POSITION_A);
172         DUMP_REG(DC_DISP_V_PULSE1_POSITION_B);
173         DUMP_REG(DC_DISP_V_PULSE1_POSITION_C);
174         DUMP_REG(DC_DISP_V_PULSE2_CONTROL);
175         DUMP_REG(DC_DISP_V_PULSE2_POSITION_A);
176         DUMP_REG(DC_DISP_V_PULSE3_CONTROL);
177         DUMP_REG(DC_DISP_V_PULSE3_POSITION_A);
178         DUMP_REG(DC_DISP_M0_CONTROL);
179         DUMP_REG(DC_DISP_M1_CONTROL);
180         DUMP_REG(DC_DISP_DI_CONTROL);
181         DUMP_REG(DC_DISP_PP_CONTROL);
182         DUMP_REG(DC_DISP_PP_SELECT_A);
183         DUMP_REG(DC_DISP_PP_SELECT_B);
184         DUMP_REG(DC_DISP_PP_SELECT_C);
185         DUMP_REG(DC_DISP_PP_SELECT_D);
186         DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL);
187         DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL);
188         DUMP_REG(DC_DISP_DISP_COLOR_CONTROL);
189         DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS);
190         DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS);
191         DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS);
192         DUMP_REG(DC_DISP_LCD_SPI_OPTIONS);
193         DUMP_REG(DC_DISP_BORDER_COLOR);
194         DUMP_REG(DC_DISP_COLOR_KEY0_LOWER);
195         DUMP_REG(DC_DISP_COLOR_KEY0_UPPER);
196         DUMP_REG(DC_DISP_COLOR_KEY1_LOWER);
197         DUMP_REG(DC_DISP_COLOR_KEY1_UPPER);
198         DUMP_REG(DC_DISP_CURSOR_FOREGROUND);
199         DUMP_REG(DC_DISP_CURSOR_BACKGROUND);
200         DUMP_REG(DC_DISP_CURSOR_START_ADDR);
201         DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS);
202         DUMP_REG(DC_DISP_CURSOR_POSITION);
203         DUMP_REG(DC_DISP_CURSOR_POSITION_NS);
204         DUMP_REG(DC_DISP_INIT_SEQ_CONTROL);
205         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A);
206         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B);
207         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C);
208         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D);
209         DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL);
210         DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST);
211         DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST);
212         DUMP_REG(DC_DISP_MCCIF_DISPLAY0C_HYST);
213         DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST);
214         DUMP_REG(DC_DISP_DAC_CRT_CTRL);
215         DUMP_REG(DC_DISP_DISP_MISC_CONTROL);
216
217
218         for (i = 0; i < 3; i++) {
219                 print(data, "\n");
220                 snprintf(buff, sizeof(buff), "WINDOW %c:\n", 'A' + i);
221                 print(data, buff);
222
223                 tegra_dc_writel(dc, WINDOW_A_SELECT << i,
224                                 DC_CMD_DISPLAY_WINDOW_HEADER);
225                 DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
226                 DUMP_REG(DC_WIN_WIN_OPTIONS);
227                 DUMP_REG(DC_WIN_BYTE_SWAP);
228                 DUMP_REG(DC_WIN_BUFFER_CONTROL);
229                 DUMP_REG(DC_WIN_COLOR_DEPTH);
230                 DUMP_REG(DC_WIN_POSITION);
231                 DUMP_REG(DC_WIN_SIZE);
232                 DUMP_REG(DC_WIN_PRESCALED_SIZE);
233                 DUMP_REG(DC_WIN_H_INITIAL_DDA);
234                 DUMP_REG(DC_WIN_V_INITIAL_DDA);
235                 DUMP_REG(DC_WIN_DDA_INCREMENT);
236                 DUMP_REG(DC_WIN_LINE_STRIDE);
237                 DUMP_REG(DC_WIN_BUF_STRIDE);
238                 DUMP_REG(DC_WIN_UV_BUF_STRIDE);
239                 DUMP_REG(DC_WIN_BLEND_NOKEY);
240                 DUMP_REG(DC_WIN_BLEND_1WIN);
241                 DUMP_REG(DC_WIN_BLEND_2WIN_X);
242                 DUMP_REG(DC_WIN_BLEND_2WIN_Y);
243                 DUMP_REG(DC_WIN_BLEND_3WIN_XY);
244                 DUMP_REG(DC_WINBUF_START_ADDR);
245                 DUMP_REG(DC_WINBUF_START_ADDR_U);
246                 DUMP_REG(DC_WINBUF_START_ADDR_V);
247                 DUMP_REG(DC_WINBUF_ADDR_H_OFFSET);
248                 DUMP_REG(DC_WINBUF_ADDR_V_OFFSET);
249                 DUMP_REG(DC_WINBUF_UFLOW_STATUS);
250                 DUMP_REG(DC_WIN_CSC_YOF);
251                 DUMP_REG(DC_WIN_CSC_KYRGB);
252                 DUMP_REG(DC_WIN_CSC_KUR);
253                 DUMP_REG(DC_WIN_CSC_KVR);
254                 DUMP_REG(DC_WIN_CSC_KUG);
255                 DUMP_REG(DC_WIN_CSC_KVG);
256                 DUMP_REG(DC_WIN_CSC_KUB);
257                 DUMP_REG(DC_WIN_CSC_KVB);
258         }
259
260         clk_disable(dc->clk);
261         tegra_dc_io_end(dc);
262 }
263
264 #undef DUMP_REG
265
266 #ifdef DEBUG
267 static void dump_regs_print(void *data, const char *str)
268 {
269         struct tegra_dc *dc = data;
270         dev_dbg(&dc->ndev->dev, "%s", str);
271 }
272
273 static void dump_regs(struct tegra_dc *dc)
274 {
275         _dump_regs(dc, dc, dump_regs_print);
276 }
277 #else
278
279 static void dump_regs(struct tegra_dc *dc) {}
280
281 #endif
282
283 #ifdef CONFIG_DEBUG_FS
284
285 static void dbg_regs_print(void *data, const char *str)
286 {
287         struct seq_file *s = data;
288
289         seq_printf(s, "%s", str);
290 }
291
292 #undef DUMP_REG
293
294 static int dbg_dc_show(struct seq_file *s, void *unused)
295 {
296         struct tegra_dc *dc = s->private;
297
298         _dump_regs(dc, s, dbg_regs_print);
299
300         return 0;
301 }
302
303
304 static int dbg_dc_open(struct inode *inode, struct file *file)
305 {
306         return single_open(file, dbg_dc_show, inode->i_private);
307 }
308
309 static const struct file_operations dbg_fops = {
310         .open           = dbg_dc_open,
311         .read           = seq_read,
312         .llseek         = seq_lseek,
313         .release        = single_release,
314 };
315
316 static void tegra_dc_dbg_add(struct tegra_dc *dc)
317 {
318         char name[32];
319
320         snprintf(name, sizeof(name), "tegra_dc%d_regs", dc->ndev->id);
321         (void) debugfs_create_file(name, S_IRUGO, NULL, dc, &dbg_fops);
322 }
323 #else
324 static void tegra_dc_dbg_add(struct tegra_dc *dc) {}
325
326 #endif
327
328
329 static int tegra_dc_add(struct tegra_dc *dc, int index)
330 {
331         int ret = 0;
332
333         mutex_lock(&tegra_dc_lock);
334         if (index >= TEGRA_MAX_DC) {
335                 ret = -EINVAL;
336                 goto out;
337         }
338
339         if (tegra_dcs[index] != NULL) {
340                 ret = -EBUSY;
341                 goto out;
342         }
343
344         tegra_dcs[index] = dc;
345
346 out:
347         mutex_unlock(&tegra_dc_lock);
348
349         return ret;
350 }
351
352 struct tegra_dc *tegra_dc_get_dc(unsigned idx)
353 {
354         if (idx < TEGRA_MAX_DC)
355                 return tegra_dcs[idx];
356         else
357                 return NULL;
358 }
359 EXPORT_SYMBOL(tegra_dc_get_dc);
360
361 struct tegra_dc_win *tegra_dc_get_window(struct tegra_dc *dc, unsigned win)
362 {
363         if (win >= dc->n_windows)
364                 return NULL;
365
366         return &dc->windows[win];
367 }
368 EXPORT_SYMBOL(tegra_dc_get_window);
369
370 static int get_topmost_window(u32 *depths, unsigned long *wins)
371 {
372         int idx, best = -1;
373
374         for_each_set_bit(idx, wins, DC_N_WINDOWS) {
375                 if (best == -1 || depths[idx] < depths[best])
376                         best = idx;
377         }
378         clear_bit(best, wins);
379         return best;
380 }
381
382 static u32 blend_topwin(u32 flags)
383 {
384         if (flags & TEGRA_WIN_FLAG_BLEND_COVERAGE)
385                 return BLEND(NOKEY, ALPHA, 0xff, 0xff);
386         else if (flags & TEGRA_WIN_FLAG_BLEND_PREMULT)
387                 return BLEND(NOKEY, PREMULT, 0xff, 0xff);
388         else
389                 return BLEND(NOKEY, FIX, 0xff, 0xff);
390 }
391
392 static u32 blend_2win(int idx, unsigned long behind_mask, u32* flags, int xy)
393 {
394         int other;
395
396         for (other = 0; other < DC_N_WINDOWS; other++) {
397                 if (other != idx && (xy-- == 0))
398                         break;
399         }
400         if (BIT(other) & behind_mask)
401                 return blend_topwin(flags[idx]);
402         else if (flags[other])
403                 return BLEND(NOKEY, DEPENDANT, 0x00, 0x00);
404         else
405                 return BLEND(NOKEY, FIX, 0x00, 0x00);
406 }
407
408 static u32 blend_3win(int idx, unsigned long behind_mask, u32* flags)
409 {
410         unsigned long infront_mask;
411         int first;
412
413         infront_mask = ~(behind_mask | BIT(idx));
414         infront_mask &= (BIT(DC_N_WINDOWS) - 1);
415         first = ffs(infront_mask) - 1;
416
417         if (!infront_mask)
418                 return blend_topwin(flags[idx]);
419         else if (behind_mask && first != -1 && flags[first])
420                 return BLEND(NOKEY, DEPENDANT, 0x00, 0x00);
421         else
422                 return BLEND(NOKEY, FIX, 0x0, 0x0);
423 }
424
425 static void tegra_dc_set_blending(struct tegra_dc *dc, struct tegra_dc_blend *blend)
426 {
427         unsigned long mask = BIT(DC_N_WINDOWS) - 1;
428
429         while (mask) {
430                 int idx = get_topmost_window(blend->z, &mask);
431
432                 tegra_dc_writel(dc, WINDOW_A_SELECT << idx,
433                                 DC_CMD_DISPLAY_WINDOW_HEADER);
434                 tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff),
435                                 DC_WIN_BLEND_NOKEY);
436                 tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff),
437                                 DC_WIN_BLEND_1WIN);
438                 tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 0),
439                                 DC_WIN_BLEND_2WIN_X);
440                 tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 1),
441                                 DC_WIN_BLEND_2WIN_Y);
442                 tegra_dc_writel(dc, blend_3win(idx, mask, blend->flags),
443                                 DC_WIN_BLEND_3WIN_XY);
444         }
445 }
446
447 static void tegra_dc_set_csc(struct tegra_dc *dc)
448 {
449         tegra_dc_writel(dc, 0x00f0, DC_WIN_CSC_YOF);
450         tegra_dc_writel(dc, 0x012a, DC_WIN_CSC_KYRGB);
451         tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KUR);
452         tegra_dc_writel(dc, 0x0198, DC_WIN_CSC_KVR);
453         tegra_dc_writel(dc, 0x039b, DC_WIN_CSC_KUG);
454         tegra_dc_writel(dc, 0x032f, DC_WIN_CSC_KVG);
455         tegra_dc_writel(dc, 0x0204, DC_WIN_CSC_KUB);
456         tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KVB);
457 }
458
459 static void tegra_dc_set_scaling_filter(struct tegra_dc *dc)
460 {
461         unsigned i;
462         unsigned v0 = 128;
463         unsigned v1 = 0;
464         /* linear horizontal and vertical filters */
465         for (i = 0; i < 16; i++) {
466                 tegra_dc_writel(dc, (v1 << 16) | (v0 << 8),
467                                 DC_WIN_H_FILTER_P(i));
468
469                 tegra_dc_writel(dc, v0,
470                                 DC_WIN_V_FILTER_P(i));
471                 v0 -= 8;
472                 v1 += 8;
473         }
474 }
475
476 /* does not support updating windows on multiple dcs in one call */
477 int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
478 {
479         struct tegra_dc *dc;
480         unsigned long update_mask = GENERAL_ACT_REQ;
481         unsigned long val;
482         bool update_blend = false;
483         int i;
484
485         dc = windows[0]->dc;
486
487         mutex_lock(&dc->lock);
488
489         if (!dc->enabled) {
490                 mutex_unlock(&dc->lock);
491                 return -EFAULT;
492         }
493
494         if (no_vsync)
495                 tegra_dc_writel(dc, WRITE_MUX_ACTIVE | READ_MUX_ACTIVE, DC_CMD_STATE_ACCESS);
496         else
497                 tegra_dc_writel(dc, WRITE_MUX_ASSEMBLY | READ_MUX_ASSEMBLY, DC_CMD_STATE_ACCESS);
498
499         for (i = 0; i < n; i++) {
500                 struct tegra_dc_win *win = windows[i];
501                 unsigned h_dda;
502                 unsigned v_dda;
503                 unsigned h_offset;
504                 unsigned v_offset;
505                 bool invert_h = (win->flags & TEGRA_WIN_FLAG_INVERT_H) != 0;
506                 bool invert_v = (win->flags & TEGRA_WIN_FLAG_INVERT_V) != 0;
507                 bool yuvp = tegra_dc_is_yuv_planar(win->fmt);
508
509                 if (win->z != dc->blend.z[win->idx]) {
510                         dc->blend.z[win->idx] = win->z;
511                         update_blend = true;
512                 }
513                 if ((win->flags & TEGRA_WIN_BLEND_FLAGS_MASK) !=
514                         dc->blend.flags[win->idx]) {
515                         dc->blend.flags[win->idx] =
516                                 win->flags & TEGRA_WIN_BLEND_FLAGS_MASK;
517                         update_blend = true;
518                 }
519
520                 tegra_dc_writel(dc, WINDOW_A_SELECT << win->idx,
521                                 DC_CMD_DISPLAY_WINDOW_HEADER);
522
523                 if (!no_vsync)
524                         update_mask |= WIN_A_ACT_REQ << win->idx;
525
526                 if (!(win->flags & TEGRA_WIN_FLAG_ENABLED)) {
527                         tegra_dc_writel(dc, 0, DC_WIN_WIN_OPTIONS);
528                         continue;
529                 }
530
531                 tegra_dc_writel(dc, win->fmt, DC_WIN_COLOR_DEPTH);
532                 tegra_dc_writel(dc, 0, DC_WIN_BYTE_SWAP);
533
534                 tegra_dc_writel(dc,
535                                 V_POSITION(win->out_y) | H_POSITION(win->out_x),
536                                 DC_WIN_POSITION);
537                 tegra_dc_writel(dc,
538                                 V_SIZE(win->out_h) | H_SIZE(win->out_w),
539                                 DC_WIN_SIZE);
540                 tegra_dc_writel(dc,
541                                 V_PRESCALED_SIZE(win->h) |
542                                 H_PRESCALED_SIZE(win->w * tegra_dc_fmt_bpp(win->fmt) / 8),
543                                 DC_WIN_PRESCALED_SIZE);
544
545                 h_dda = ((win->w - 1) * 0x1000) / max_t(int, win->out_w - 1, 1);
546                 v_dda = ((win->h - 1) * 0x1000) / max_t(int, win->out_h - 1, 1);
547                 tegra_dc_writel(dc, V_DDA_INC(v_dda) | H_DDA_INC(h_dda),
548                                 DC_WIN_DDA_INCREMENT);
549                 tegra_dc_writel(dc, 0, DC_WIN_H_INITIAL_DDA);
550                 tegra_dc_writel(dc, 0, DC_WIN_V_INITIAL_DDA);
551
552                 tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
553                 tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
554                 tegra_dc_writel(dc, (unsigned long)win->phys_addr,
555                                 DC_WINBUF_START_ADDR);
556
557                 if (!yuvp) {
558                         tegra_dc_writel(dc, win->stride, DC_WIN_LINE_STRIDE);
559                 } else {
560                         tegra_dc_writel(dc,
561                                         (unsigned long)win->phys_addr +
562                                         (unsigned long)win->offset_u,
563                                         DC_WINBUF_START_ADDR_U);
564                         tegra_dc_writel(dc,
565                                         (unsigned long)win->phys_addr +
566                                         (unsigned long)win->offset_v,
567                                         DC_WINBUF_START_ADDR_V);
568                         tegra_dc_writel(dc,
569                                         LINE_STRIDE(win->stride) |
570                                         UV_LINE_STRIDE(win->stride_uv),
571                                         DC_WIN_LINE_STRIDE);
572                 }
573
574                 h_offset = win->x;
575                 if (invert_h) {
576                         h_offset += win->w - 1;
577                 }
578                 h_offset *= tegra_dc_fmt_bpp(win->fmt) / 8;
579
580                 v_offset = win->y;
581                 if (invert_v) {
582                         v_offset += win->h - 1;
583                 }
584
585                 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
586                 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
587
588                 if (win->flags & TEGRA_WIN_FLAG_TILED)
589                         tegra_dc_writel(dc,
590                                         DC_WIN_BUFFER_ADDR_MODE_TILE |
591                                         DC_WIN_BUFFER_ADDR_MODE_TILE_UV,
592                                         DC_WIN_BUFFER_ADDR_MODE);
593                 else
594                         tegra_dc_writel(dc,
595                                         DC_WIN_BUFFER_ADDR_MODE_LINEAR |
596                                         DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV,
597                                         DC_WIN_BUFFER_ADDR_MODE);
598
599                 val = WIN_ENABLE;
600                 if (yuvp)
601                         val |= CSC_ENABLE;
602                 else if (tegra_dc_fmt_bpp(win->fmt) < 24)
603                         val |= COLOR_EXPAND;
604
605                 if (win->w != win->out_w)
606                         val |= H_FILTER_ENABLE;
607                 if (win->h != win->out_h)
608                         val |= V_FILTER_ENABLE;
609
610                 if (invert_h)
611                         val |= H_DIRECTION_DECREMENT;
612                 if (invert_v)
613                         val |= V_DIRECTION_DECREMENT;
614
615                 tegra_dc_writel(dc, val, DC_WIN_WIN_OPTIONS);
616
617                 win->dirty = no_vsync ? 0 : 1;
618         }
619
620         if (update_blend) {
621                 tegra_dc_set_blending(dc, &dc->blend);
622                 for (i = 0; i < DC_N_WINDOWS; i++) {
623                         if (!no_vsync)
624                                 dc->windows[i].dirty = 1;
625                         update_mask |= WIN_A_ACT_REQ << i;
626                 }
627         }
628
629         tegra_dc_writel(dc, update_mask << 8, DC_CMD_STATE_CONTROL);
630
631         if (!no_vsync) {
632                 val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
633                 val |= FRAME_END_INT;
634                 tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
635
636                 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
637                 val |= FRAME_END_INT;
638                 tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
639         }
640
641         tegra_dc_writel(dc, update_mask, DC_CMD_STATE_CONTROL);
642         mutex_unlock(&dc->lock);
643
644         return 0;
645 }
646 EXPORT_SYMBOL(tegra_dc_update_windows);
647
648 u32 tegra_dc_get_syncpt_id(const struct tegra_dc *dc)
649 {
650         return dc->syncpt_id;
651 }
652 EXPORT_SYMBOL(tegra_dc_get_syncpt_id);
653
654 u32 tegra_dc_incr_syncpt_max(struct tegra_dc *dc)
655 {
656         u32 max;
657
658         mutex_lock(&dc->lock);
659         max = nvhost_syncpt_incr_max(&dc->ndev->host->syncpt, dc->syncpt_id, 1);
660         dc->syncpt_max = max;
661         mutex_unlock(&dc->lock);
662
663         return max;
664 }
665
666 void tegra_dc_incr_syncpt_min(struct tegra_dc *dc, u32 val)
667 {
668         mutex_lock(&dc->lock);
669         while (dc->syncpt_min < val) {
670                 dc->syncpt_min++;
671                 nvhost_syncpt_cpu_incr(&dc->ndev->host->syncpt, dc->syncpt_id);
672         }
673         mutex_unlock(&dc->lock);
674 }
675
676 static bool tegra_dc_windows_are_clean(struct tegra_dc_win *windows[],
677                                              int n)
678 {
679         int i;
680
681         for (i = 0; i < n; i++) {
682                 if (windows[i]->dirty)
683                         return false;
684         }
685
686         return true;
687 }
688
689 /* does not support syncing windows on multiple dcs in one call */
690 int tegra_dc_sync_windows(struct tegra_dc_win *windows[], int n)
691 {
692         if (n < 1 || n > DC_N_WINDOWS)
693                 return -EINVAL;
694
695         if (!windows[0]->dc->enabled)
696                 return -EFAULT;
697
698         return wait_event_interruptible_timeout(windows[0]->dc->wq,
699                                          tegra_dc_windows_are_clean(windows, n),
700                                          HZ);
701 }
702 EXPORT_SYMBOL(tegra_dc_sync_windows);
703
704 static unsigned long tegra_dc_pclk_round_rate(struct tegra_dc *dc, int pclk)
705 {
706         unsigned long rate;
707         unsigned long div;
708
709         rate = clk_get_rate(dc->clk);
710
711         div = DIV_ROUND_CLOSEST(rate * 2, pclk);
712
713         if (div < 2)
714                 return 0;
715
716         return rate * 2 / div;
717 }
718
719 void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk)
720 {
721         int pclk;
722
723         if (dc->out->type == TEGRA_DC_OUT_HDMI) {
724                 unsigned long rate;
725                 struct clk *pll_d_out0_clk =
726                         clk_get_sys(NULL, "pll_d_out0");
727                 struct clk *pll_d_clk =
728                         clk_get_sys(NULL, "pll_d");
729
730                 if (dc->mode.pclk > 70000000)
731                         rate = 594000000;
732                 else
733                         rate = 216000000;
734
735                 if (rate != clk_get_rate(pll_d_clk))
736                         clk_set_rate(pll_d_clk, rate);
737
738                 if (clk_get_parent(clk) != pll_d_out0_clk)
739                         clk_set_parent(clk, pll_d_out0_clk);
740         }
741
742         pclk = tegra_dc_pclk_round_rate(dc, dc->mode.pclk);
743         tegra_dvfs_set_rate(clk, pclk);
744
745 }
746
747 static int tegra_dc_program_mode(struct tegra_dc *dc, struct tegra_dc_mode *mode)
748 {
749         unsigned long val;
750         unsigned long rate;
751         unsigned long div;
752         unsigned long pclk;
753
754         tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS);
755         tegra_dc_writel(dc, mode->h_ref_to_sync | (mode->v_ref_to_sync << 16),
756                         DC_DISP_REF_TO_SYNC);
757         tegra_dc_writel(dc, mode->h_sync_width | (mode->v_sync_width << 16),
758                         DC_DISP_SYNC_WIDTH);
759         tegra_dc_writel(dc, mode->h_back_porch | (mode->v_back_porch << 16),
760                         DC_DISP_BACK_PORCH);
761         tegra_dc_writel(dc, mode->h_active | (mode->v_active << 16),
762                         DC_DISP_DISP_ACTIVE);
763         tegra_dc_writel(dc, mode->h_front_porch | (mode->v_front_porch << 16),
764                         DC_DISP_FRONT_PORCH);
765
766         tegra_dc_writel(dc, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL,
767                         DC_DISP_DATA_ENABLE_OPTIONS);
768
769         val = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_POLARITY1);
770         if (mode->flags & TEGRA_DC_MODE_FLAG_NEG_V_SYNC)
771                 val |= PIN1_LVS_OUTPUT;
772         else
773                 val &= ~PIN1_LVS_OUTPUT;
774
775         if (mode->flags & TEGRA_DC_MODE_FLAG_NEG_H_SYNC)
776                 val |= PIN1_LHS_OUTPUT;
777         else
778                 val &= ~PIN1_LHS_OUTPUT;
779         tegra_dc_writel(dc, val, DC_COM_PIN_OUTPUT_POLARITY1);
780
781         /* TODO: MIPI/CRT/HDMI clock cals */
782
783         val = DISP_DATA_FORMAT_DF1P1C;
784
785         if (dc->out->align == TEGRA_DC_ALIGN_MSB)
786                 val |= DISP_DATA_ALIGNMENT_MSB;
787         else
788                 val |= DISP_DATA_ALIGNMENT_LSB;
789
790         if (dc->out->order == TEGRA_DC_ORDER_RED_BLUE)
791                 val |= DISP_DATA_ORDER_RED_BLUE;
792         else
793                 val |= DISP_DATA_ORDER_BLUE_RED;
794
795         tegra_dc_writel(dc, val, DC_DISP_DISP_INTERFACE_CONTROL);
796
797         rate = clk_get_rate(dc->clk);
798
799         pclk = tegra_dc_pclk_round_rate(dc, mode->pclk);
800         if (pclk < (mode->pclk / 100 * 99) ||
801             pclk > (mode->pclk / 100 * 109)) {
802                 dev_err(&dc->ndev->dev,
803                         "can't divide %ld clock to %d -1/+9%% %ld %d %d\n",
804                         rate, mode->pclk,
805                         pclk, (mode->pclk / 100 * 99),
806                         (mode->pclk / 100 * 109));
807                 return -EINVAL;
808         }
809
810         div = (rate * 2 / pclk) - 2;
811
812         tegra_dc_writel(dc, 0x00010001,
813                         DC_DISP_SHIFT_CLOCK_OPTIONS);
814         tegra_dc_writel(dc, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(div),
815                         DC_DISP_DISP_CLOCK_CONTROL);
816
817         return 0;
818 }
819
820
821 int tegra_dc_set_mode(struct tegra_dc *dc, const struct tegra_dc_mode *mode)
822 {
823         memcpy(&dc->mode, mode, sizeof(dc->mode));
824
825         return 0;
826 }
827 EXPORT_SYMBOL(tegra_dc_set_mode);
828
829 static void tegra_dc_set_out(struct tegra_dc *dc, struct tegra_dc_out *out)
830 {
831         dc->out = out;
832
833         if (out->n_modes > 0)
834                 tegra_dc_set_mode(dc, &dc->out->modes[0]);
835
836         switch (out->type) {
837         case TEGRA_DC_OUT_RGB:
838                 dc->out_ops = &tegra_dc_rgb_ops;
839                 break;
840
841         case TEGRA_DC_OUT_HDMI:
842                 dc->out_ops = &tegra_dc_hdmi_ops;
843                 break;
844
845         default:
846                 dc->out_ops = NULL;
847                 break;
848         }
849
850         if (dc->out_ops && dc->out_ops->init)
851                 dc->out_ops->init(dc);
852
853 }
854
855 unsigned tegra_dc_get_out_height(struct tegra_dc *dc)
856 {
857         if (dc->out)
858                 return dc->out->height;
859         else
860                 return 0;
861 }
862 EXPORT_SYMBOL(tegra_dc_get_out_height);
863
864 unsigned tegra_dc_get_out_width(struct tegra_dc *dc)
865 {
866         if (dc->out)
867                 return dc->out->width;
868         else
869                 return 0;
870 }
871 EXPORT_SYMBOL(tegra_dc_get_out_width);
872
873 static irqreturn_t tegra_dc_irq(int irq, void *ptr)
874 {
875         struct tegra_dc *dc = ptr;
876         unsigned long status;
877         unsigned long val;
878         unsigned long underflow_mask;
879         int i;
880
881         status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
882         tegra_dc_writel(dc, status, DC_CMD_INT_STATUS);
883
884         if (status & FRAME_END_INT) {
885                 int completed = 0;
886                 int dirty = 0;
887
888                 val = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
889                 for (i = 0; i < DC_N_WINDOWS; i++) {
890                         if (!(val & (WIN_A_UPDATE << i))) {
891                                 dc->windows[i].dirty = 0;
892                                 completed = 1;
893                         } else {
894                                 dirty = 1;
895                         }
896                 }
897
898                 if (!dirty) {
899                         val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
900                         val &= ~FRAME_END_INT;
901                         tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
902                 }
903
904                 if (completed)
905                         wake_up(&dc->wq);
906         }
907
908
909         /*
910          * Overlays can get thier internal state corrupted during and underflow
911          * condition.  The only way to fix this state is to reset the DC.
912          * if we get 4 consecutive frames with underflows, assume we're
913          * hosed and reset.
914          */
915         underflow_mask = status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT);
916         if (underflow_mask) {
917                 val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
918                 val |= V_BLANK_INT;
919                 tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
920                 dc->underflow_mask |= underflow_mask;
921         }
922
923         if (status & V_BLANK_INT) {
924                 int i;
925
926                 for (i = 0; i< DC_N_WINDOWS; i++) {
927                         if (dc->underflow_mask & (WIN_A_UF_INT <<i)) {
928                                 dc->windows[i].underflows++;
929
930                                 if (dc->windows[i].underflows > 4)
931                                         schedule_work(&dc->reset_work);
932                         } else {
933                                 dc->windows[i].underflows = 0;
934                         }
935                 }
936
937                 if (!dc->underflow_mask) {
938                         val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
939                         val &= ~V_BLANK_INT;
940                         tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
941                 }
942
943                 dc->underflow_mask = 0;
944         }
945
946
947         return IRQ_HANDLED;
948 }
949
950 static void tegra_dc_set_color_control(struct tegra_dc *dc)
951 {
952         u32 color_control;
953
954         switch (dc->out->depth) {
955         case 3:
956                 color_control = BASE_COLOR_SIZE111;
957                 break;
958
959         case 6:
960                 color_control = BASE_COLOR_SIZE222;
961                 break;
962
963         case 8:
964                 color_control = BASE_COLOR_SIZE332;
965                 break;
966
967         case 9:
968                 color_control = BASE_COLOR_SIZE333;
969                 break;
970
971         case 12:
972                 color_control = BASE_COLOR_SIZE444;
973                 break;
974
975         case 15:
976                 color_control = BASE_COLOR_SIZE555;
977                 break;
978
979         case 16:
980                 color_control = BASE_COLOR_SIZE565;
981                 break;
982
983         case 18:
984                 color_control = BASE_COLOR_SIZE666;
985                 break;
986
987         default:
988                 color_control = BASE_COLOR_SIZE888;
989                 break;
990         }
991
992         tegra_dc_writel(dc, color_control, DC_DISP_DISP_COLOR_CONTROL);
993 }
994
995 static void tegra_dc_init(struct tegra_dc *dc)
996 {
997         u32 disp_syncpt;
998         u32 vblank_syncpt;
999         int i;
1000
1001         tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
1002         if (dc->ndev->id == 0) {
1003                 disp_syncpt = NVSYNCPT_DISP0;
1004                 vblank_syncpt = NVSYNCPT_VBLANK0;
1005
1006                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0A,
1007                                       TEGRA_MC_PRIO_MED);
1008                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0B,
1009                                       TEGRA_MC_PRIO_MED);
1010                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0C,
1011                                       TEGRA_MC_PRIO_MED);
1012                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY1B,
1013                                       TEGRA_MC_PRIO_MED);
1014                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAYHC,
1015                                       TEGRA_MC_PRIO_HIGH);
1016         } else if (dc->ndev->id == 1) {
1017                 disp_syncpt = NVSYNCPT_DISP1;
1018                 vblank_syncpt = NVSYNCPT_VBLANK1;
1019
1020                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0AB,
1021                                       TEGRA_MC_PRIO_MED);
1022                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0BB,
1023                                       TEGRA_MC_PRIO_MED);
1024                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0CB,
1025                                       TEGRA_MC_PRIO_MED);
1026                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY1BB,
1027                                       TEGRA_MC_PRIO_MED);
1028                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAYHCB,
1029                                       TEGRA_MC_PRIO_HIGH);
1030         }
1031         tegra_dc_writel(dc, 0x00000100 | vblank_syncpt, DC_CMD_CONT_SYNCPT_VSYNC);
1032         tegra_dc_writel(dc, 0x00004700, DC_CMD_INT_TYPE);
1033         tegra_dc_writel(dc, 0x0001c700, DC_CMD_INT_POLARITY);
1034         tegra_dc_writel(dc, 0x00202020, DC_DISP_MEM_HIGH_PRIORITY);
1035         tegra_dc_writel(dc, 0x00010101, DC_DISP_MEM_HIGH_PRIORITY_TIMER);
1036
1037         tegra_dc_writel(dc, (FRAME_END_INT |
1038                              V_BLANK_INT |
1039                              WIN_A_UF_INT |
1040                              WIN_B_UF_INT |
1041                              WIN_C_UF_INT), DC_CMD_INT_MASK);
1042         tegra_dc_writel(dc, (WIN_A_UF_INT |
1043                              WIN_B_UF_INT |
1044                              WIN_C_UF_INT), DC_CMD_INT_ENABLE);
1045
1046         tegra_dc_writel(dc, 0x00000000, DC_DISP_BORDER_COLOR);
1047
1048         tegra_dc_set_color_control(dc);
1049         for (i = 0; i < DC_N_WINDOWS; i++) {
1050                 tegra_dc_writel(dc, WINDOW_A_SELECT << i,
1051                                 DC_CMD_DISPLAY_WINDOW_HEADER);
1052                 tegra_dc_set_csc(dc);
1053                 tegra_dc_set_scaling_filter(dc);
1054         }
1055
1056
1057         dc->syncpt_id = disp_syncpt;
1058
1059         dc->syncpt_min = dc->syncpt_max =
1060                 nvhost_syncpt_read(&dc->ndev->host->syncpt, disp_syncpt);
1061
1062         if (dc->mode.pclk)
1063                 tegra_dc_program_mode(dc, &dc->mode);
1064 }
1065
1066 static bool _tegra_dc_enable(struct tegra_dc *dc)
1067 {
1068         if (dc->mode.pclk == 0)
1069                 return false;
1070
1071         tegra_dc_io_start(dc);
1072
1073         if (dc->out && dc->out->enable)
1074                 dc->out->enable();
1075
1076         tegra_dc_setup_clk(dc, dc->clk);
1077         clk_enable(dc->clk);
1078         clk_enable(dc->emc_clk);
1079         tegra_periph_reset_deassert(dc->clk);
1080         msleep(10);
1081
1082         enable_irq(dc->irq);
1083
1084         tegra_dc_init(dc);
1085
1086         if (dc->out_ops && dc->out_ops->enable)
1087                 dc->out_ops->enable(dc);
1088
1089         /* force a full blending update */
1090         dc->blend.z[0] = -1;
1091
1092         return true;
1093 }
1094
1095 void tegra_dc_enable(struct tegra_dc *dc)
1096 {
1097         mutex_lock(&dc->lock);
1098
1099         if (!dc->enabled)
1100                 dc->enabled = _tegra_dc_enable(dc);
1101
1102         mutex_unlock(&dc->lock);
1103 }
1104
1105 static void _tegra_dc_disable(struct tegra_dc *dc)
1106 {
1107         disable_irq(dc->irq);
1108
1109         if (dc->out_ops && dc->out_ops->disable)
1110                 dc->out_ops->disable(dc);
1111
1112         clk_disable(dc->emc_clk);
1113         clk_disable(dc->clk);
1114         tegra_dvfs_set_rate(dc->clk, 0);
1115
1116         if (dc->out && dc->out->disable)
1117                 dc->out->disable();
1118
1119         /* flush any pending syncpt waits */
1120         while (dc->syncpt_min < dc->syncpt_max) {
1121                 dc->syncpt_min++;
1122                 nvhost_syncpt_cpu_incr(&dc->ndev->host->syncpt, dc->syncpt_id);
1123         }
1124
1125         tegra_dc_io_end(dc);
1126 }
1127
1128
1129 void tegra_dc_disable(struct tegra_dc *dc)
1130 {
1131         mutex_lock(&dc->lock);
1132
1133         if (dc->enabled) {
1134                 dc->enabled = false;
1135
1136                 if (!dc->suspended)
1137                         _tegra_dc_disable(dc);
1138         }
1139
1140         mutex_unlock(&dc->lock);
1141 }
1142
1143 static void tegra_dc_reset_worker(struct work_struct *work)
1144 {
1145         struct tegra_dc *dc =
1146                 container_of(work, struct tegra_dc, reset_work);
1147
1148         dev_warn(&dc->ndev->dev, "overlay stuck in underflow state.  resetting.\n");
1149
1150         mutex_lock(&dc->lock);
1151         if (dc->enabled && !dc->suspended) {
1152                 _tegra_dc_disable(dc);
1153
1154                 /* A necessary wait. */
1155                 msleep(100);
1156                 tegra_periph_reset_assert(dc->clk);
1157
1158                 /* _tegra_dc_enable deasserts reset */
1159                 _tegra_dc_enable(dc);
1160         }
1161         mutex_unlock(&dc->lock);
1162 }
1163
1164
1165 static int tegra_dc_probe(struct nvhost_device *ndev)
1166 {
1167         struct tegra_dc *dc;
1168         struct clk *clk;
1169         struct clk *emc_clk;
1170         struct resource *res;
1171         struct resource *base_res;
1172         struct resource *fb_mem = NULL;
1173         int ret = 0;
1174         void __iomem *base;
1175         int irq;
1176         int i;
1177         unsigned long emc_clk_rate;
1178
1179         if (!ndev->dev.platform_data) {
1180                 dev_err(&ndev->dev, "no platform data\n");
1181                 return -ENOENT;
1182         }
1183
1184         dc = kzalloc(sizeof(struct tegra_dc), GFP_KERNEL);
1185         if (!dc) {
1186                 dev_err(&ndev->dev, "can't allocate memory for tegra_dc\n");
1187                 return -ENOMEM;
1188         }
1189
1190         irq = nvhost_get_irq_byname(ndev, "irq");
1191         if (irq <= 0) {
1192                 dev_err(&ndev->dev, "no irq\n");
1193                 ret = -ENOENT;
1194                 goto err_free;
1195         }
1196
1197         res = nvhost_get_resource_byname(ndev, IORESOURCE_MEM, "regs");
1198         if (!res) {
1199                 dev_err(&ndev->dev, "no mem resource\n");
1200                 ret = -ENOENT;
1201                 goto err_free;
1202         }
1203
1204         base_res = request_mem_region(res->start, resource_size(res), ndev->name);
1205         if (!base_res) {
1206                 dev_err(&ndev->dev, "request_mem_region failed\n");
1207                 ret = -EBUSY;
1208                 goto err_free;
1209         }
1210
1211         base = ioremap(res->start, resource_size(res));
1212         if (!base) {
1213                 dev_err(&ndev->dev, "registers can't be mapped\n");
1214                 ret = -EBUSY;
1215                 goto err_release_resource_reg;
1216         }
1217
1218         fb_mem = nvhost_get_resource_byname(ndev, IORESOURCE_MEM, "fbmem");
1219
1220         clk = clk_get(&ndev->dev, NULL);
1221         if (IS_ERR_OR_NULL(clk)) {
1222                 dev_err(&ndev->dev, "can't get clock\n");
1223                 ret = -ENOENT;
1224                 goto err_iounmap_reg;
1225         }
1226
1227         emc_clk = clk_get(&ndev->dev, "emc");
1228         if (IS_ERR_OR_NULL(emc_clk)) {
1229                 dev_err(&ndev->dev, "can't get emc clock\n");
1230                 ret = -ENOENT;
1231                 goto err_put_clk;
1232         }
1233
1234         dc->clk = clk;
1235         dc->emc_clk = emc_clk;
1236         dc->base_res = base_res;
1237         dc->base = base;
1238         dc->irq = irq;
1239         dc->ndev = ndev;
1240         dc->pdata = ndev->dev.platform_data;
1241
1242         /*
1243          * The emc is a shared clock, it will be set based on
1244          * the requirements for each user on the bus.
1245          */
1246         emc_clk_rate = dc->pdata->emc_clk_rate;
1247         clk_set_rate(emc_clk, emc_clk_rate ? emc_clk_rate : ULONG_MAX);
1248
1249         if (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED)
1250                 dc->enabled = true;
1251
1252         mutex_init(&dc->lock);
1253         init_waitqueue_head(&dc->wq);
1254         INIT_WORK(&dc->reset_work, tegra_dc_reset_worker);
1255
1256         dc->n_windows = DC_N_WINDOWS;
1257         for (i = 0; i < dc->n_windows; i++) {
1258                 dc->windows[i].idx = i;
1259                 dc->windows[i].dc = dc;
1260         }
1261
1262         if (request_irq(irq, tegra_dc_irq, IRQF_DISABLED,
1263                         dev_name(&ndev->dev), dc)) {
1264                 dev_err(&ndev->dev, "request_irq %d failed\n", irq);
1265                 ret = -EBUSY;
1266                 goto err_put_emc_clk;
1267         }
1268
1269         /* hack to ballence enable_irq calls in _tegra_dc_enable() */
1270         disable_irq(dc->irq);
1271
1272         ret = tegra_dc_add(dc, ndev->id);
1273         if (ret < 0) {
1274                 dev_err(&ndev->dev, "can't add dc\n");
1275                 goto err_free_irq;
1276         }
1277
1278         nvhost_set_drvdata(ndev, dc);
1279
1280         if (dc->pdata->default_out)
1281                 tegra_dc_set_out(dc, dc->pdata->default_out);
1282         else
1283                 dev_err(&ndev->dev, "No default output specified.  Leaving output disabled.\n");
1284
1285         if (dc->enabled)
1286                 _tegra_dc_enable(dc);
1287
1288         tegra_dc_dbg_add(dc);
1289
1290         dev_info(&ndev->dev, "probed\n");
1291
1292         if (dc->pdata->fb) {
1293                 if (dc->pdata->fb->bits_per_pixel == -1) {
1294                         unsigned long fmt;
1295                         tegra_dc_writel(dc,
1296                                         WINDOW_A_SELECT << dc->pdata->fb->win,
1297                                         DC_CMD_DISPLAY_WINDOW_HEADER);
1298
1299                         fmt = tegra_dc_readl(dc, DC_WIN_COLOR_DEPTH);
1300                         dc->pdata->fb->bits_per_pixel =
1301                                 tegra_dc_fmt_bpp(fmt);
1302                 }
1303
1304                 dc->fb = tegra_fb_register(ndev, dc, dc->pdata->fb, fb_mem);
1305                 if (IS_ERR_OR_NULL(dc->fb))
1306                         dc->fb = NULL;
1307         }
1308
1309         if (dc->out_ops && dc->out_ops->detect)
1310                 dc->out_ops->detect(dc);
1311
1312         return 0;
1313
1314 err_free_irq:
1315         free_irq(irq, dc);
1316 err_put_emc_clk:
1317         clk_put(emc_clk);
1318 err_put_clk:
1319         clk_put(clk);
1320 err_iounmap_reg:
1321         iounmap(base);
1322         if (fb_mem)
1323                 release_resource(fb_mem);
1324 err_release_resource_reg:
1325         release_resource(base_res);
1326 err_free:
1327         kfree(dc);
1328
1329         return ret;
1330 }
1331
1332 static int tegra_dc_remove(struct nvhost_device *ndev)
1333 {
1334         struct tegra_dc *dc = nvhost_get_drvdata(ndev);
1335
1336         if (dc->fb) {
1337                 tegra_fb_unregister(dc->fb);
1338                 if (dc->fb_mem)
1339                         release_resource(dc->fb_mem);
1340         }
1341
1342
1343         if (dc->enabled)
1344                 _tegra_dc_disable(dc);
1345
1346         free_irq(dc->irq, dc);
1347         clk_put(dc->emc_clk);
1348         clk_put(dc->clk);
1349         iounmap(dc->base);
1350         if (dc->fb_mem)
1351                 release_resource(dc->base_res);
1352         kfree(dc);
1353         return 0;
1354 }
1355
1356 #ifdef CONFIG_PM
1357 static int tegra_dc_suspend(struct nvhost_device *ndev, pm_message_t state)
1358 {
1359         struct tegra_dc *dc = nvhost_get_drvdata(ndev);
1360
1361         dev_info(&ndev->dev, "suspend\n");
1362
1363         mutex_lock(&dc->lock);
1364
1365         if (dc->out_ops && dc->out_ops->suspend)
1366                 dc->out_ops->suspend(dc);
1367
1368         if (dc->enabled) {
1369                 tegra_fb_suspend(dc->fb);
1370                 _tegra_dc_disable(dc);
1371
1372                 dc->suspended = true;
1373         }
1374         mutex_unlock(&dc->lock);
1375
1376         return 0;
1377 }
1378
1379 static int tegra_dc_resume(struct nvhost_device *ndev)
1380 {
1381         struct tegra_dc *dc = nvhost_get_drvdata(ndev);
1382
1383         dev_info(&ndev->dev, "resume\n");
1384
1385         mutex_lock(&dc->lock);
1386         dc->suspended = false;
1387
1388         if (dc->enabled)
1389                 _tegra_dc_enable(dc);
1390
1391         if (dc->out_ops && dc->out_ops->resume)
1392                 dc->out_ops->resume(dc);
1393         mutex_unlock(&dc->lock);
1394
1395         return 0;
1396 }
1397
1398 #endif
1399
1400 extern int suspend_set(const char *val, struct kernel_param *kp)
1401 {
1402         if (!strcmp(val, "dump"))
1403                 dump_regs(tegra_dcs[0]);
1404 #ifdef CONFIG_PM
1405         else if (!strcmp(val, "suspend"))
1406                 tegra_dc_suspend(tegra_dcs[0]->ndev, PMSG_SUSPEND);
1407         else if (!strcmp(val, "resume"))
1408                 tegra_dc_resume(tegra_dcs[0]->ndev);
1409 #endif
1410
1411         return 0;
1412 }
1413
1414 extern int suspend_get(char *buffer, struct kernel_param *kp)
1415 {
1416         return 0;
1417 }
1418
1419 int suspend;
1420
1421 module_param_call(suspend, suspend_set, suspend_get, &suspend, 0644);
1422
1423 struct nvhost_driver tegra_dc_driver = {
1424         .driver = {
1425                 .name = "tegradc",
1426                 .owner = THIS_MODULE,
1427         },
1428         .probe = tegra_dc_probe,
1429         .remove = tegra_dc_remove,
1430 #ifdef CONFIG_PM
1431         .suspend = tegra_dc_suspend,
1432         .resume = tegra_dc_resume,
1433 #endif
1434 };
1435
1436 static int __init tegra_dc_module_init(void)
1437 {
1438         return nvhost_driver_register(&tegra_dc_driver);
1439 }
1440
1441 static void __exit tegra_dc_module_exit(void)
1442 {
1443         nvhost_driver_unregister(&tegra_dc_driver);
1444 }
1445
1446 module_exit(tegra_dc_module_exit);
1447 module_init(tegra_dc_module_init);