541346a3bbee3b08d80b03739d0ee535bfff51fc
[linux-2.6.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 #include "overlay.h"
43
44 static int no_vsync;
45
46 module_param_named(no_vsync, no_vsync, int, S_IRUGO | S_IWUSR);
47
48 struct tegra_dc *tegra_dcs[TEGRA_MAX_DC];
49
50 DEFINE_MUTEX(tegra_dc_lock);
51 DEFINE_MUTEX(shared_lock);
52
53 static inline int tegra_dc_fmt_bpp(int fmt)
54 {
55         switch (fmt) {
56         case TEGRA_WIN_FMT_P1:
57                 return 1;
58
59         case TEGRA_WIN_FMT_P2:
60                 return 2;
61
62         case TEGRA_WIN_FMT_P4:
63                 return 4;
64
65         case TEGRA_WIN_FMT_P8:
66                 return 8;
67
68         case TEGRA_WIN_FMT_B4G4R4A4:
69         case TEGRA_WIN_FMT_B5G5R5A:
70         case TEGRA_WIN_FMT_B5G6R5:
71         case TEGRA_WIN_FMT_AB5G5R5:
72                 return 16;
73
74         case TEGRA_WIN_FMT_B8G8R8A8:
75         case TEGRA_WIN_FMT_R8G8B8A8:
76         case TEGRA_WIN_FMT_B6x2G6x2R6x2A8:
77         case TEGRA_WIN_FMT_R6x2G6x2B6x2A8:
78                 return 32;
79
80         /* for planar formats, size of the Y plane, 8bit */
81         case TEGRA_WIN_FMT_YCbCr420P:
82         case TEGRA_WIN_FMT_YUV420P:
83         case TEGRA_WIN_FMT_YCbCr422P:
84         case TEGRA_WIN_FMT_YUV422P:
85                 return 8;
86
87         case TEGRA_WIN_FMT_YCbCr422:
88         case TEGRA_WIN_FMT_YUV422:
89         case TEGRA_WIN_FMT_YCbCr422R:
90         case TEGRA_WIN_FMT_YUV422R:
91         case TEGRA_WIN_FMT_YCbCr422RA:
92         case TEGRA_WIN_FMT_YUV422RA:
93                 /* FIXME: need to know the bpp of these formats */
94                 return 0;
95         }
96         return 0;
97 }
98
99 static inline bool tegra_dc_is_yuv_planar(int fmt)
100 {
101         switch (fmt) {
102         case TEGRA_WIN_FMT_YUV420P:
103         case TEGRA_WIN_FMT_YCbCr420P:
104         case TEGRA_WIN_FMT_YCbCr422P:
105         case TEGRA_WIN_FMT_YUV422P:
106                 return true;
107         }
108         return false;
109 }
110
111 #define DUMP_REG(a) do {                        \
112         snprintf(buff, sizeof(buff), "%-32s\t%03x\t%08lx\n", \
113                  #a, a, tegra_dc_readl(dc, a));               \
114         print(data, buff);                                    \
115         } while (0)
116
117 static void _dump_regs(struct tegra_dc *dc, void *data,
118                        void (* print)(void *data, const char *str))
119 {
120         int i;
121         char buff[256];
122
123         tegra_dc_io_start(dc);
124         clk_enable(dc->clk);
125
126         DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0);
127         DUMP_REG(DC_CMD_DISPLAY_COMMAND);
128         DUMP_REG(DC_CMD_SIGNAL_RAISE);
129         DUMP_REG(DC_CMD_INT_STATUS);
130         DUMP_REG(DC_CMD_INT_MASK);
131         DUMP_REG(DC_CMD_INT_ENABLE);
132         DUMP_REG(DC_CMD_INT_TYPE);
133         DUMP_REG(DC_CMD_INT_POLARITY);
134         DUMP_REG(DC_CMD_SIGNAL_RAISE1);
135         DUMP_REG(DC_CMD_SIGNAL_RAISE2);
136         DUMP_REG(DC_CMD_SIGNAL_RAISE3);
137         DUMP_REG(DC_CMD_STATE_ACCESS);
138         DUMP_REG(DC_CMD_STATE_CONTROL);
139         DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
140         DUMP_REG(DC_CMD_REG_ACT_CONTROL);
141
142         DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0);
143         DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1);
144         DUMP_REG(DC_DISP_DISP_WIN_OPTIONS);
145         DUMP_REG(DC_DISP_MEM_HIGH_PRIORITY);
146         DUMP_REG(DC_DISP_MEM_HIGH_PRIORITY_TIMER);
147         DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS);
148         DUMP_REG(DC_DISP_REF_TO_SYNC);
149         DUMP_REG(DC_DISP_SYNC_WIDTH);
150         DUMP_REG(DC_DISP_BACK_PORCH);
151         DUMP_REG(DC_DISP_DISP_ACTIVE);
152         DUMP_REG(DC_DISP_FRONT_PORCH);
153         DUMP_REG(DC_DISP_H_PULSE0_CONTROL);
154         DUMP_REG(DC_DISP_H_PULSE0_POSITION_A);
155         DUMP_REG(DC_DISP_H_PULSE0_POSITION_B);
156         DUMP_REG(DC_DISP_H_PULSE0_POSITION_C);
157         DUMP_REG(DC_DISP_H_PULSE0_POSITION_D);
158         DUMP_REG(DC_DISP_H_PULSE1_CONTROL);
159         DUMP_REG(DC_DISP_H_PULSE1_POSITION_A);
160         DUMP_REG(DC_DISP_H_PULSE1_POSITION_B);
161         DUMP_REG(DC_DISP_H_PULSE1_POSITION_C);
162         DUMP_REG(DC_DISP_H_PULSE1_POSITION_D);
163         DUMP_REG(DC_DISP_H_PULSE2_CONTROL);
164         DUMP_REG(DC_DISP_H_PULSE2_POSITION_A);
165         DUMP_REG(DC_DISP_H_PULSE2_POSITION_B);
166         DUMP_REG(DC_DISP_H_PULSE2_POSITION_C);
167         DUMP_REG(DC_DISP_H_PULSE2_POSITION_D);
168         DUMP_REG(DC_DISP_V_PULSE0_CONTROL);
169         DUMP_REG(DC_DISP_V_PULSE0_POSITION_A);
170         DUMP_REG(DC_DISP_V_PULSE0_POSITION_B);
171         DUMP_REG(DC_DISP_V_PULSE0_POSITION_C);
172         DUMP_REG(DC_DISP_V_PULSE1_CONTROL);
173         DUMP_REG(DC_DISP_V_PULSE1_POSITION_A);
174         DUMP_REG(DC_DISP_V_PULSE1_POSITION_B);
175         DUMP_REG(DC_DISP_V_PULSE1_POSITION_C);
176         DUMP_REG(DC_DISP_V_PULSE2_CONTROL);
177         DUMP_REG(DC_DISP_V_PULSE2_POSITION_A);
178         DUMP_REG(DC_DISP_V_PULSE3_CONTROL);
179         DUMP_REG(DC_DISP_V_PULSE3_POSITION_A);
180         DUMP_REG(DC_DISP_M0_CONTROL);
181         DUMP_REG(DC_DISP_M1_CONTROL);
182         DUMP_REG(DC_DISP_DI_CONTROL);
183         DUMP_REG(DC_DISP_PP_CONTROL);
184         DUMP_REG(DC_DISP_PP_SELECT_A);
185         DUMP_REG(DC_DISP_PP_SELECT_B);
186         DUMP_REG(DC_DISP_PP_SELECT_C);
187         DUMP_REG(DC_DISP_PP_SELECT_D);
188         DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL);
189         DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL);
190         DUMP_REG(DC_DISP_DISP_COLOR_CONTROL);
191         DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS);
192         DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS);
193         DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS);
194         DUMP_REG(DC_DISP_LCD_SPI_OPTIONS);
195         DUMP_REG(DC_DISP_BORDER_COLOR);
196         DUMP_REG(DC_DISP_COLOR_KEY0_LOWER);
197         DUMP_REG(DC_DISP_COLOR_KEY0_UPPER);
198         DUMP_REG(DC_DISP_COLOR_KEY1_LOWER);
199         DUMP_REG(DC_DISP_COLOR_KEY1_UPPER);
200         DUMP_REG(DC_DISP_CURSOR_FOREGROUND);
201         DUMP_REG(DC_DISP_CURSOR_BACKGROUND);
202         DUMP_REG(DC_DISP_CURSOR_START_ADDR);
203         DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS);
204         DUMP_REG(DC_DISP_CURSOR_POSITION);
205         DUMP_REG(DC_DISP_CURSOR_POSITION_NS);
206         DUMP_REG(DC_DISP_INIT_SEQ_CONTROL);
207         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A);
208         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B);
209         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C);
210         DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D);
211         DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL);
212         DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST);
213         DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST);
214         DUMP_REG(DC_DISP_MCCIF_DISPLAY0C_HYST);
215         DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST);
216         DUMP_REG(DC_DISP_DAC_CRT_CTRL);
217         DUMP_REG(DC_DISP_DISP_MISC_CONTROL);
218
219
220         for (i = 0; i < 3; i++) {
221                 print(data, "\n");
222                 snprintf(buff, sizeof(buff), "WINDOW %c:\n", 'A' + i);
223                 print(data, buff);
224
225                 tegra_dc_writel(dc, WINDOW_A_SELECT << i,
226                                 DC_CMD_DISPLAY_WINDOW_HEADER);
227                 DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
228                 DUMP_REG(DC_WIN_WIN_OPTIONS);
229                 DUMP_REG(DC_WIN_BYTE_SWAP);
230                 DUMP_REG(DC_WIN_BUFFER_CONTROL);
231                 DUMP_REG(DC_WIN_COLOR_DEPTH);
232                 DUMP_REG(DC_WIN_POSITION);
233                 DUMP_REG(DC_WIN_SIZE);
234                 DUMP_REG(DC_WIN_PRESCALED_SIZE);
235                 DUMP_REG(DC_WIN_H_INITIAL_DDA);
236                 DUMP_REG(DC_WIN_V_INITIAL_DDA);
237                 DUMP_REG(DC_WIN_DDA_INCREMENT);
238                 DUMP_REG(DC_WIN_LINE_STRIDE);
239                 DUMP_REG(DC_WIN_BUF_STRIDE);
240                 DUMP_REG(DC_WIN_UV_BUF_STRIDE);
241                 DUMP_REG(DC_WIN_BLEND_NOKEY);
242                 DUMP_REG(DC_WIN_BLEND_1WIN);
243                 DUMP_REG(DC_WIN_BLEND_2WIN_X);
244                 DUMP_REG(DC_WIN_BLEND_2WIN_Y);
245                 DUMP_REG(DC_WIN_BLEND_3WIN_XY);
246                 DUMP_REG(DC_WINBUF_START_ADDR);
247                 DUMP_REG(DC_WINBUF_START_ADDR_U);
248                 DUMP_REG(DC_WINBUF_START_ADDR_V);
249                 DUMP_REG(DC_WINBUF_ADDR_H_OFFSET);
250                 DUMP_REG(DC_WINBUF_ADDR_V_OFFSET);
251                 DUMP_REG(DC_WINBUF_UFLOW_STATUS);
252                 DUMP_REG(DC_WIN_CSC_YOF);
253                 DUMP_REG(DC_WIN_CSC_KYRGB);
254                 DUMP_REG(DC_WIN_CSC_KUR);
255                 DUMP_REG(DC_WIN_CSC_KVR);
256                 DUMP_REG(DC_WIN_CSC_KUG);
257                 DUMP_REG(DC_WIN_CSC_KVG);
258                 DUMP_REG(DC_WIN_CSC_KUB);
259                 DUMP_REG(DC_WIN_CSC_KVB);
260         }
261
262         clk_disable(dc->clk);
263         tegra_dc_io_end(dc);
264 }
265
266 #undef DUMP_REG
267
268 #ifdef DEBUG
269 static void dump_regs_print(void *data, const char *str)
270 {
271         struct tegra_dc *dc = data;
272         dev_dbg(&dc->ndev->dev, "%s", str);
273 }
274
275 static void dump_regs(struct tegra_dc *dc)
276 {
277         _dump_regs(dc, dc, dump_regs_print);
278 }
279 #else
280
281 static void dump_regs(struct tegra_dc *dc) {}
282
283 #endif
284
285 #ifdef CONFIG_DEBUG_FS
286
287 static void dbg_regs_print(void *data, const char *str)
288 {
289         struct seq_file *s = data;
290
291         seq_printf(s, "%s", str);
292 }
293
294 #undef DUMP_REG
295
296 static int dbg_dc_show(struct seq_file *s, void *unused)
297 {
298         struct tegra_dc *dc = s->private;
299
300         _dump_regs(dc, s, dbg_regs_print);
301
302         return 0;
303 }
304
305
306 static int dbg_dc_open(struct inode *inode, struct file *file)
307 {
308         return single_open(file, dbg_dc_show, inode->i_private);
309 }
310
311 static const struct file_operations dbg_fops = {
312         .open           = dbg_dc_open,
313         .read           = seq_read,
314         .llseek         = seq_lseek,
315         .release        = single_release,
316 };
317
318 static void tegra_dc_dbg_add(struct tegra_dc *dc)
319 {
320         char name[32];
321
322         snprintf(name, sizeof(name), "tegra_dc%d_regs", dc->ndev->id);
323         (void) debugfs_create_file(name, S_IRUGO, NULL, dc, &dbg_fops);
324 }
325 #else
326 static void tegra_dc_dbg_add(struct tegra_dc *dc) {}
327
328 #endif
329
330
331 static int tegra_dc_add(struct tegra_dc *dc, int index)
332 {
333         int ret = 0;
334
335         mutex_lock(&tegra_dc_lock);
336         if (index >= TEGRA_MAX_DC) {
337                 ret = -EINVAL;
338                 goto out;
339         }
340
341         if (tegra_dcs[index] != NULL) {
342                 ret = -EBUSY;
343                 goto out;
344         }
345
346         tegra_dcs[index] = dc;
347
348 out:
349         mutex_unlock(&tegra_dc_lock);
350
351         return ret;
352 }
353
354 struct tegra_dc *tegra_dc_get_dc(unsigned idx)
355 {
356         if (idx < TEGRA_MAX_DC)
357                 return tegra_dcs[idx];
358         else
359                 return NULL;
360 }
361 EXPORT_SYMBOL(tegra_dc_get_dc);
362
363 struct tegra_dc_win *tegra_dc_get_window(struct tegra_dc *dc, unsigned win)
364 {
365         if (win >= dc->n_windows)
366                 return NULL;
367
368         return &dc->windows[win];
369 }
370 EXPORT_SYMBOL(tegra_dc_get_window);
371
372 static int get_topmost_window(u32 *depths, unsigned long *wins)
373 {
374         int idx, best = -1;
375
376         for_each_set_bit(idx, wins, DC_N_WINDOWS) {
377                 if (best == -1 || depths[idx] < depths[best])
378                         best = idx;
379         }
380         clear_bit(best, wins);
381         return best;
382 }
383
384 static u32 blend_topwin(u32 flags)
385 {
386         if (flags & TEGRA_WIN_FLAG_BLEND_COVERAGE)
387                 return BLEND(NOKEY, ALPHA, 0xff, 0xff);
388         else if (flags & TEGRA_WIN_FLAG_BLEND_PREMULT)
389                 return BLEND(NOKEY, PREMULT, 0xff, 0xff);
390         else
391                 return BLEND(NOKEY, FIX, 0xff, 0xff);
392 }
393
394 static u32 blend_2win(int idx, unsigned long behind_mask, u32* flags, int xy)
395 {
396         int other;
397
398         for (other = 0; other < DC_N_WINDOWS; other++) {
399                 if (other != idx && (xy-- == 0))
400                         break;
401         }
402         if (BIT(other) & behind_mask)
403                 return blend_topwin(flags[idx]);
404         else if (flags[other])
405                 return BLEND(NOKEY, DEPENDANT, 0x00, 0x00);
406         else
407                 return BLEND(NOKEY, FIX, 0x00, 0x00);
408 }
409
410 static u32 blend_3win(int idx, unsigned long behind_mask, u32* flags)
411 {
412         unsigned long infront_mask;
413         int first;
414
415         infront_mask = ~(behind_mask | BIT(idx));
416         infront_mask &= (BIT(DC_N_WINDOWS) - 1);
417         first = ffs(infront_mask) - 1;
418
419         if (!infront_mask)
420                 return blend_topwin(flags[idx]);
421         else if (behind_mask && first != -1 && flags[first])
422                 return BLEND(NOKEY, DEPENDANT, 0x00, 0x00);
423         else
424                 return BLEND(NOKEY, FIX, 0x0, 0x0);
425 }
426
427 static void tegra_dc_set_blending(struct tegra_dc *dc, struct tegra_dc_blend *blend)
428 {
429         unsigned long mask = BIT(DC_N_WINDOWS) - 1;
430
431         while (mask) {
432                 int idx = get_topmost_window(blend->z, &mask);
433
434                 tegra_dc_writel(dc, WINDOW_A_SELECT << idx,
435                                 DC_CMD_DISPLAY_WINDOW_HEADER);
436                 tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff),
437                                 DC_WIN_BLEND_NOKEY);
438                 tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff),
439                                 DC_WIN_BLEND_1WIN);
440                 tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 0),
441                                 DC_WIN_BLEND_2WIN_X);
442                 tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 1),
443                                 DC_WIN_BLEND_2WIN_Y);
444                 tegra_dc_writel(dc, blend_3win(idx, mask, blend->flags),
445                                 DC_WIN_BLEND_3WIN_XY);
446         }
447 }
448
449 static void tegra_dc_set_csc(struct tegra_dc *dc)
450 {
451         tegra_dc_writel(dc, 0x00f0, DC_WIN_CSC_YOF);
452         tegra_dc_writel(dc, 0x012a, DC_WIN_CSC_KYRGB);
453         tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KUR);
454         tegra_dc_writel(dc, 0x0198, DC_WIN_CSC_KVR);
455         tegra_dc_writel(dc, 0x039b, DC_WIN_CSC_KUG);
456         tegra_dc_writel(dc, 0x032f, DC_WIN_CSC_KVG);
457         tegra_dc_writel(dc, 0x0204, DC_WIN_CSC_KUB);
458         tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KVB);
459 }
460
461 static void tegra_dc_set_scaling_filter(struct tegra_dc *dc)
462 {
463         unsigned i;
464         unsigned v0 = 128;
465         unsigned v1 = 0;
466         /* linear horizontal and vertical filters */
467         for (i = 0; i < 16; i++) {
468                 tegra_dc_writel(dc, (v1 << 16) | (v0 << 8),
469                                 DC_WIN_H_FILTER_P(i));
470
471                 tegra_dc_writel(dc, v0,
472                                 DC_WIN_V_FILTER_P(i));
473                 v0 -= 8;
474                 v1 += 8;
475         }
476 }
477
478 /* does not support updating windows on multiple dcs in one call */
479 int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
480 {
481         struct tegra_dc *dc;
482         unsigned long update_mask = GENERAL_ACT_REQ;
483         unsigned long val;
484         bool update_blend = false;
485         int i;
486
487         dc = windows[0]->dc;
488
489         mutex_lock(&dc->lock);
490
491         if (!dc->enabled) {
492                 mutex_unlock(&dc->lock);
493                 return -EFAULT;
494         }
495
496         if (no_vsync)
497                 tegra_dc_writel(dc, WRITE_MUX_ACTIVE | READ_MUX_ACTIVE, DC_CMD_STATE_ACCESS);
498         else
499                 tegra_dc_writel(dc, WRITE_MUX_ASSEMBLY | READ_MUX_ASSEMBLY, DC_CMD_STATE_ACCESS);
500
501         for (i = 0; i < n; i++) {
502                 struct tegra_dc_win *win = windows[i];
503                 unsigned h_dda;
504                 unsigned v_dda;
505                 unsigned h_offset;
506                 unsigned v_offset;
507                 bool invert_h = (win->flags & TEGRA_WIN_FLAG_INVERT_H) != 0;
508                 bool invert_v = (win->flags & TEGRA_WIN_FLAG_INVERT_V) != 0;
509                 bool yuvp = tegra_dc_is_yuv_planar(win->fmt);
510
511                 if (win->z != dc->blend.z[win->idx]) {
512                         dc->blend.z[win->idx] = win->z;
513                         update_blend = true;
514                 }
515                 if ((win->flags & TEGRA_WIN_BLEND_FLAGS_MASK) !=
516                         dc->blend.flags[win->idx]) {
517                         dc->blend.flags[win->idx] =
518                                 win->flags & TEGRA_WIN_BLEND_FLAGS_MASK;
519                         update_blend = true;
520                 }
521
522                 tegra_dc_writel(dc, WINDOW_A_SELECT << win->idx,
523                                 DC_CMD_DISPLAY_WINDOW_HEADER);
524
525                 if (!no_vsync)
526                         update_mask |= WIN_A_ACT_REQ << win->idx;
527
528                 if (!(win->flags & TEGRA_WIN_FLAG_ENABLED)) {
529                         tegra_dc_writel(dc, 0, DC_WIN_WIN_OPTIONS);
530                         continue;
531                 }
532
533                 tegra_dc_writel(dc, win->fmt, DC_WIN_COLOR_DEPTH);
534                 tegra_dc_writel(dc, 0, DC_WIN_BYTE_SWAP);
535
536                 tegra_dc_writel(dc,
537                                 V_POSITION(win->out_y) | H_POSITION(win->out_x),
538                                 DC_WIN_POSITION);
539                 tegra_dc_writel(dc,
540                                 V_SIZE(win->out_h) | H_SIZE(win->out_w),
541                                 DC_WIN_SIZE);
542                 tegra_dc_writel(dc,
543                                 V_PRESCALED_SIZE(win->h) |
544                                 H_PRESCALED_SIZE(win->w * tegra_dc_fmt_bpp(win->fmt) / 8),
545                                 DC_WIN_PRESCALED_SIZE);
546
547                 h_dda = ((win->w - 1) * 0x1000) / max_t(int, win->out_w - 1, 1);
548                 v_dda = ((win->h - 1) * 0x1000) / max_t(int, win->out_h - 1, 1);
549                 tegra_dc_writel(dc, V_DDA_INC(v_dda) | H_DDA_INC(h_dda),
550                                 DC_WIN_DDA_INCREMENT);
551                 tegra_dc_writel(dc, 0, DC_WIN_H_INITIAL_DDA);
552                 tegra_dc_writel(dc, 0, DC_WIN_V_INITIAL_DDA);
553
554                 tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
555                 tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
556                 tegra_dc_writel(dc,
557                                 (unsigned long)win->phys_addr +
558                                 (unsigned long)win->offset,
559                                 DC_WINBUF_START_ADDR);
560
561                 if (!yuvp) {
562                         tegra_dc_writel(dc, win->stride, DC_WIN_LINE_STRIDE);
563                 } else {
564                         tegra_dc_writel(dc,
565                                         (unsigned long)win->phys_addr +
566                                         (unsigned long)win->offset_u,
567                                         DC_WINBUF_START_ADDR_U);
568                         tegra_dc_writel(dc,
569                                         (unsigned long)win->phys_addr +
570                                         (unsigned long)win->offset_v,
571                                         DC_WINBUF_START_ADDR_V);
572                         tegra_dc_writel(dc,
573                                         LINE_STRIDE(win->stride) |
574                                         UV_LINE_STRIDE(win->stride_uv),
575                                         DC_WIN_LINE_STRIDE);
576                 }
577
578                 h_offset = win->x;
579                 if (invert_h) {
580                         h_offset += win->w - 1;
581                 }
582                 h_offset *= tegra_dc_fmt_bpp(win->fmt) / 8;
583
584                 v_offset = win->y;
585                 if (invert_v) {
586                         v_offset += win->h - 1;
587                 }
588
589                 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
590                 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
591
592                 if (win->flags & TEGRA_WIN_FLAG_TILED)
593                         tegra_dc_writel(dc,
594                                         DC_WIN_BUFFER_ADDR_MODE_TILE |
595                                         DC_WIN_BUFFER_ADDR_MODE_TILE_UV,
596                                         DC_WIN_BUFFER_ADDR_MODE);
597                 else
598                         tegra_dc_writel(dc,
599                                         DC_WIN_BUFFER_ADDR_MODE_LINEAR |
600                                         DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV,
601                                         DC_WIN_BUFFER_ADDR_MODE);
602
603                 val = WIN_ENABLE;
604                 if (yuvp)
605                         val |= CSC_ENABLE;
606                 else if (tegra_dc_fmt_bpp(win->fmt) < 24)
607                         val |= COLOR_EXPAND;
608
609                 if (win->w != win->out_w)
610                         val |= H_FILTER_ENABLE;
611                 if (win->h != win->out_h)
612                         val |= V_FILTER_ENABLE;
613
614                 if (invert_h)
615                         val |= H_DIRECTION_DECREMENT;
616                 if (invert_v)
617                         val |= V_DIRECTION_DECREMENT;
618
619                 tegra_dc_writel(dc, val, DC_WIN_WIN_OPTIONS);
620
621                 win->dirty = no_vsync ? 0 : 1;
622         }
623
624         if (update_blend) {
625                 tegra_dc_set_blending(dc, &dc->blend);
626                 for (i = 0; i < DC_N_WINDOWS; i++) {
627                         if (!no_vsync)
628                                 dc->windows[i].dirty = 1;
629                         update_mask |= WIN_A_ACT_REQ << i;
630                 }
631         }
632
633         tegra_dc_writel(dc, update_mask << 8, DC_CMD_STATE_CONTROL);
634
635         if (!no_vsync) {
636                 val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
637                 val |= FRAME_END_INT;
638                 tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
639
640                 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
641                 val |= FRAME_END_INT;
642                 tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
643         }
644
645         tegra_dc_writel(dc, update_mask, DC_CMD_STATE_CONTROL);
646         mutex_unlock(&dc->lock);
647
648         return 0;
649 }
650 EXPORT_SYMBOL(tegra_dc_update_windows);
651
652 u32 tegra_dc_get_syncpt_id(const struct tegra_dc *dc)
653 {
654         return dc->syncpt_id;
655 }
656 EXPORT_SYMBOL(tegra_dc_get_syncpt_id);
657
658 u32 tegra_dc_incr_syncpt_max(struct tegra_dc *dc)
659 {
660         u32 max;
661
662         mutex_lock(&dc->lock);
663         max = nvhost_syncpt_incr_max(&dc->ndev->host->syncpt, dc->syncpt_id,
664                                         ((dc->enabled) ? 1 : 0) );
665         dc->syncpt_max = max;
666         mutex_unlock(&dc->lock);
667
668         return max;
669 }
670
671 void tegra_dc_incr_syncpt_min(struct tegra_dc *dc, u32 val)
672 {
673         mutex_lock(&dc->lock);
674         if ( dc->enabled )
675                 while (dc->syncpt_min < val) {
676                         dc->syncpt_min++;
677                         nvhost_syncpt_cpu_incr(&dc->ndev->host->syncpt,
678                                 dc->syncpt_id);
679                 }
680         mutex_unlock(&dc->lock);
681 }
682
683 static bool tegra_dc_windows_are_clean(struct tegra_dc_win *windows[],
684                                              int n)
685 {
686         int i;
687
688         for (i = 0; i < n; i++) {
689                 if (windows[i]->dirty)
690                         return false;
691         }
692
693         return true;
694 }
695
696 /* does not support syncing windows on multiple dcs in one call */
697 int tegra_dc_sync_windows(struct tegra_dc_win *windows[], int n)
698 {
699         if (n < 1 || n > DC_N_WINDOWS)
700                 return -EINVAL;
701
702         if (!windows[0]->dc->enabled)
703                 return -EFAULT;
704
705         return wait_event_interruptible_timeout(windows[0]->dc->wq,
706                                          tegra_dc_windows_are_clean(windows, n),
707                                          HZ);
708 }
709 EXPORT_SYMBOL(tegra_dc_sync_windows);
710
711 static unsigned long tegra_dc_clk_get_rate(struct tegra_dc *dc)
712 {
713 #ifdef CONFIG_TEGRA_FPGA_PLATFORM
714         return 27000000;
715 #else
716         return clk_get_rate(dc->clk);
717 #endif
718 }
719
720 static unsigned long tegra_dc_pclk_round_rate(struct tegra_dc *dc, int pclk)
721 {
722         unsigned long rate;
723         unsigned long div;
724
725         rate = tegra_dc_clk_get_rate(dc);
726
727         div = DIV_ROUND_CLOSEST(rate * 2, pclk);
728
729         if (div < 2)
730                 return 0;
731
732         return rate * 2 / div;
733 }
734
735 void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk)
736 {
737         int pclk;
738
739         if (dc->out->type == TEGRA_DC_OUT_HDMI) {
740                 unsigned long rate;
741                 struct clk *pll_d_out0_clk =
742                         clk_get_sys(NULL, "pll_d_out0");
743                 struct clk *pll_d_clk =
744                         clk_get_sys(NULL, "pll_d");
745
746                 if (dc->mode.pclk > 70000000)
747                         rate = 594000000;
748                 else
749                         rate = 216000000;
750
751                 if (rate != clk_get_rate(pll_d_clk))
752                         clk_set_rate(pll_d_clk, rate);
753
754                 if (clk_get_parent(clk) != pll_d_out0_clk)
755                         clk_set_parent(clk, pll_d_out0_clk);
756         }
757
758         if (dc->out->type == TEGRA_DC_OUT_DSI) {
759                 unsigned long rate;
760                 struct clk *pll_d_out0_clk =
761                         clk_get_sys(NULL, "pll_d_out0");
762                 struct clk *pll_d_clk =
763                         clk_get_sys(NULL, "pll_d");
764
765                 rate = dc->mode.pclk;
766                 if (rate != clk_get_rate(pll_d_clk))
767                         clk_set_rate(pll_d_clk, rate);
768
769                 if (clk_get_parent(clk) != pll_d_out0_clk)
770                         clk_set_parent(clk, pll_d_out0_clk);
771         }
772
773         pclk = tegra_dc_pclk_round_rate(dc, dc->mode.pclk);
774         tegra_dvfs_set_rate(clk, pclk);
775 }
776
777 static void calc_h_ref_to_sync(const struct tegra_dc_mode *mode,
778         long *refmin, long *refmax)
779 {
780         long a, b;
781         a = 0; /* Constraint 5 */
782         /* Constraint 1 */
783         if (a + mode->h_sync_width + mode->h_back_porch <= 11)
784                 a = 1 + 11 - mode->h_sync_width - mode->h_back_porch;
785         /* Constraint 6 */
786         if (mode->h_front_porch < a + 1)
787                 a = mode->h_front_porch - 1;
788
789         b = mode->h_front_porch - 1; /* Constraint 6 */
790         /* Constraint 1 */
791         if (b + mode->h_sync_width + mode->h_back_porch <= 11)
792                 b = 1 + 11 - mode->h_sync_width - mode->h_back_porch;
793         /* Constraint 5 */
794         if (b < 0)
795                 b = 0;
796
797         if (refmin)
798                 *refmin = a;
799         if (refmax)
800                 *refmax = b;
801 }
802
803 static void calc_v_ref_to_sync(const struct tegra_dc_mode *mode, long *refmin)
804 {
805         long a;
806         a = 1; /* Constraint 5 */
807         /* Constraint 2 */
808         if (a + mode->v_sync_width + mode->v_back_porch <= 1)
809                 a = 1 + 1 - mode->v_sync_width - mode->v_back_porch;
810         /* Constraint 6 */
811         if (mode->v_front_porch < a + 1)
812                 a = mode->v_front_porch - 1;
813
814         if (refmin)
815                 *refmin = a;
816 }
817
818 static int calc_ref_to_sync(struct tegra_dc_mode *mode)
819 {
820         long a, b;
821
822         calc_h_ref_to_sync(mode, &a, &b);
823         if (b > a && b % 2)
824                 mode->h_ref_to_sync = b - 1; /* use largest even value */
825         else
826                 mode->h_ref_to_sync = b; /* even or only possible value */
827
828         /* use smallest valid value for vertical ref */
829         calc_v_ref_to_sync(mode, &a);
830         mode->v_ref_to_sync = a;
831
832         return 0;
833 }
834
835 #ifdef DEBUG
836 /* return in 1000ths of a Hertz */
837 static int calc_refresh(const struct tegra_dc_mode *m)
838 {
839         long h_total, v_total, refresh;
840         h_total = m->h_active + m->h_front_porch + m->h_back_porch +
841                 m->h_sync_width;
842         v_total = m->v_active + m->v_front_porch + m->v_back_porch +
843                 m->v_sync_width;
844         refresh = m->pclk / h_total;
845         refresh *= 1000;
846         refresh /= v_total;
847         return refresh;
848 }
849
850 static void print_mode(struct tegra_dc *dc,
851                         const struct tegra_dc_mode *mode, const char *note)
852 {
853         if (mode) {
854                 int refresh = calc_refresh(mode);
855                 dev_info(&dc->ndev->dev, "%s():MODE:%dx%d@%d.%03uHz pclk=%d\n",
856                         note ? note : "",
857                         mode->h_active, mode->v_active,
858                         refresh / 1000, refresh % 1000,
859                         mode->pclk);
860         }
861 }
862 #else
863 static inline void print_mode(struct tegra_dc *dc,
864                         const struct tegra_dc_mode *mode, const char *note) { }
865 #endif
866
867 static int tegra_dc_program_mode(struct tegra_dc *dc, struct tegra_dc_mode *mode)
868 {
869         unsigned long val;
870         unsigned long rate;
871         unsigned long div;
872         unsigned long pclk;
873
874         print_mode(dc, mode, __func__);
875
876         tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS);
877         tegra_dc_writel(dc, mode->h_ref_to_sync | (mode->v_ref_to_sync << 16),
878                         DC_DISP_REF_TO_SYNC);
879         tegra_dc_writel(dc, mode->h_sync_width | (mode->v_sync_width << 16),
880                         DC_DISP_SYNC_WIDTH);
881         tegra_dc_writel(dc, mode->h_back_porch | (mode->v_back_porch << 16),
882                         DC_DISP_BACK_PORCH);
883         tegra_dc_writel(dc, mode->h_active | (mode->v_active << 16),
884                         DC_DISP_DISP_ACTIVE);
885         tegra_dc_writel(dc, mode->h_front_porch | (mode->v_front_porch << 16),
886                         DC_DISP_FRONT_PORCH);
887
888         tegra_dc_writel(dc, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL,
889                         DC_DISP_DATA_ENABLE_OPTIONS);
890
891         val = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_POLARITY1);
892         if (mode->flags & TEGRA_DC_MODE_FLAG_NEG_V_SYNC)
893                 val |= PIN1_LVS_OUTPUT;
894         else
895                 val &= ~PIN1_LVS_OUTPUT;
896
897         if (mode->flags & TEGRA_DC_MODE_FLAG_NEG_H_SYNC)
898                 val |= PIN1_LHS_OUTPUT;
899         else
900                 val &= ~PIN1_LHS_OUTPUT;
901         tegra_dc_writel(dc, val, DC_COM_PIN_OUTPUT_POLARITY1);
902
903         /* TODO: MIPI/CRT/HDMI clock cals */
904
905         val = DISP_DATA_FORMAT_DF1P1C;
906
907         if (dc->out->align == TEGRA_DC_ALIGN_MSB)
908                 val |= DISP_DATA_ALIGNMENT_MSB;
909         else
910                 val |= DISP_DATA_ALIGNMENT_LSB;
911
912         if (dc->out->order == TEGRA_DC_ORDER_RED_BLUE)
913                 val |= DISP_DATA_ORDER_RED_BLUE;
914         else
915                 val |= DISP_DATA_ORDER_BLUE_RED;
916
917         tegra_dc_writel(dc, val, DC_DISP_DISP_INTERFACE_CONTROL);
918
919         rate = tegra_dc_clk_get_rate(dc);
920
921         pclk = tegra_dc_pclk_round_rate(dc, mode->pclk);
922         if (pclk < (mode->pclk / 100 * 99) ||
923             pclk > (mode->pclk / 100 * 109)) {
924                 dev_err(&dc->ndev->dev,
925                         "can't divide %ld clock to %d -1/+9%% %ld %d %d\n",
926                         rate, mode->pclk,
927                         pclk, (mode->pclk / 100 * 99),
928                         (mode->pclk / 100 * 109));
929                 return -EINVAL;
930         }
931
932         div = (rate * 2 / pclk) - 2;
933
934         tegra_dc_writel(dc, 0x00010001,
935                         DC_DISP_SHIFT_CLOCK_OPTIONS);
936         tegra_dc_writel(dc, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(div),
937                         DC_DISP_DISP_CLOCK_CONTROL);
938
939         return 0;
940 }
941
942
943 int tegra_dc_set_mode(struct tegra_dc *dc, const struct tegra_dc_mode *mode)
944 {
945         memcpy(&dc->mode, mode, sizeof(dc->mode));
946
947         print_mode(dc, mode, __func__);
948
949         return 0;
950 }
951 EXPORT_SYMBOL(tegra_dc_set_mode);
952
953 int tegra_dc_set_fb_mode(struct tegra_dc *dc,
954                 const struct fb_videomode *fbmode, bool stereo_mode)
955 {
956         struct tegra_dc_mode mode;
957
958         mode.pclk = PICOS2KHZ(fbmode->pixclock) * 1000;
959         mode.h_sync_width = fbmode->hsync_len;
960         mode.v_sync_width = fbmode->vsync_len;
961         mode.h_back_porch = fbmode->left_margin;
962         mode.v_back_porch = fbmode->upper_margin;
963         mode.h_active = fbmode->xres;
964         mode.v_active = fbmode->yres;
965         mode.h_front_porch = fbmode->right_margin;
966         mode.v_front_porch = fbmode->lower_margin;
967         mode.stereo_mode = stereo_mode;
968         calc_ref_to_sync(&mode);
969         printk("Using mode %dx%d pclk=%d href=%d vref=%d\n",
970                 mode.h_active, mode.v_active, mode.pclk,
971                 mode.h_ref_to_sync, mode.v_ref_to_sync
972         );
973
974         if (mode.stereo_mode) {
975                 mode.pclk *= 2;
976                 /* total v_active = yres*2 + activespace */
977                 mode.v_active = fbmode->yres*2 +
978                                 fbmode->vsync_len +
979                                 fbmode->upper_margin +
980                                 fbmode->lower_margin;
981         }
982
983         mode.flags = 0;
984
985         if (!(fbmode->sync & FB_SYNC_HOR_HIGH_ACT))
986                 mode.flags |= TEGRA_DC_MODE_FLAG_NEG_H_SYNC;
987
988         if (!(fbmode->sync & FB_SYNC_VERT_HIGH_ACT))
989                 mode.flags |= TEGRA_DC_MODE_FLAG_NEG_V_SYNC;
990
991         return tegra_dc_set_mode(dc, &mode);
992 }
993 EXPORT_SYMBOL(tegra_dc_set_fb_mode);
994
995 void
996 tegra_dc_config_pwm(struct tegra_dc *dc, struct tegra_dc_pwm_params *cfg)
997 {
998         unsigned int ctrl;
999
1000         mutex_lock(&dc->lock);
1001         if (!dc->enabled) {
1002                 mutex_unlock(&dc->lock);
1003                 return;
1004         }
1005
1006         ctrl = ((cfg->period << PM_PERIOD_SHIFT) |
1007                 (cfg->clk_div << PM_CLK_DIVIDER_SHIFT) |
1008                 cfg->clk_select);
1009
1010         switch (cfg->which_pwm) {
1011         case TEGRA_PWM_PM0:
1012                 tegra_dc_writel(dc, ctrl, DC_COM_PM0_CONTROL);
1013                 tegra_dc_writel(dc, cfg->duty_cycle, DC_COM_PM0_DUTY_CYCLE);
1014                 break;
1015         case TEGRA_PWM_PM1:
1016                 tegra_dc_writel(dc, ctrl, DC_COM_PM1_CONTROL);
1017                 tegra_dc_writel(dc, cfg->duty_cycle, DC_COM_PM1_DUTY_CYCLE);
1018                 break;
1019         default:
1020                 dev_err(&dc->ndev->dev, "Error\n");
1021                 break;
1022         }
1023         mutex_unlock(&dc->lock);
1024 }
1025 EXPORT_SYMBOL(tegra_dc_config_pwm);
1026
1027 static void tegra_dc_set_out_pin_polars(struct tegra_dc *dc,
1028                                 const struct tegra_dc_out_pin *pins,
1029                                 const unsigned int n_pins)
1030 {
1031         unsigned int i;
1032
1033         int name;
1034         int pol;
1035
1036         u32 pol1, pol3;
1037
1038         u32 set1, unset1;
1039         u32 set3, unset3;
1040
1041         set1 = set3 = unset1 = unset3 = 0;
1042
1043         for (i = 0; i < n_pins; i++) {
1044                 name = (pins + i)->name;
1045                 pol  = (pins + i)->pol;
1046
1047                 /* set polarity by name */
1048                 switch (name) {
1049                 case TEGRA_DC_OUT_PIN_DATA_ENABLE:
1050                         if (pol == TEGRA_DC_OUT_PIN_POL_LOW)
1051                                 set3 |= LSPI_OUTPUT_POLARITY_LOW;
1052                         else
1053                                 unset3 |= LSPI_OUTPUT_POLARITY_LOW;
1054                         break;
1055                 case TEGRA_DC_OUT_PIN_H_SYNC:
1056                         if (pol == TEGRA_DC_OUT_PIN_POL_LOW)
1057                                 set1 |= LHS_OUTPUT_POLARITY_LOW;
1058                         else
1059                                 unset1 |= LHS_OUTPUT_POLARITY_LOW;
1060                         break;
1061                 case TEGRA_DC_OUT_PIN_V_SYNC:
1062                         if (pol == TEGRA_DC_OUT_PIN_POL_LOW)
1063                                 set1 |= LVS_OUTPUT_POLARITY_LOW;
1064                         else
1065                                 unset1 |= LVS_OUTPUT_POLARITY_LOW;
1066                         break;
1067                 case TEGRA_DC_OUT_PIN_PIXEL_CLOCK:
1068                         if (pol == TEGRA_DC_OUT_PIN_POL_LOW)
1069                                 set1 |= LSC0_OUTPUT_POLARITY_LOW;
1070                         else
1071                                 unset1 |= LSC0_OUTPUT_POLARITY_LOW;
1072                         break;
1073                 default:
1074                         printk("Invalid argument in function %s\n",
1075                                __FUNCTION__);
1076                         break;
1077                 }
1078         }
1079
1080         pol1 = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_POLARITY1);
1081         pol3 = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_POLARITY3);
1082
1083         pol1 |= set1;
1084         pol1 &= ~unset1;
1085
1086         pol3 |= set3;
1087         pol3 &= ~unset3;
1088
1089         tegra_dc_writel(dc, pol1, DC_COM_PIN_OUTPUT_POLARITY1);
1090         tegra_dc_writel(dc, pol3, DC_COM_PIN_OUTPUT_POLARITY3);
1091 }
1092
1093 static void tegra_dc_set_out(struct tegra_dc *dc, struct tegra_dc_out *out)
1094 {
1095         dc->out = out;
1096
1097         if (out->n_modes > 0)
1098                 tegra_dc_set_mode(dc, &dc->out->modes[0]);
1099
1100         switch (out->type) {
1101         case TEGRA_DC_OUT_RGB:
1102                 dc->out_ops = &tegra_dc_rgb_ops;
1103                 break;
1104
1105         case TEGRA_DC_OUT_HDMI:
1106                 dc->out_ops = &tegra_dc_hdmi_ops;
1107                 break;
1108 #ifdef CONFIG_TEGRA_DSI
1109         case TEGRA_DC_OUT_DSI:
1110                 dc->out_ops = &tegra_dc_dsi_ops;
1111                 break;
1112 #endif
1113         default:
1114                 dc->out_ops = NULL;
1115                 break;
1116         }
1117
1118         if (dc->out_ops && dc->out_ops->init)
1119                 dc->out_ops->init(dc);
1120
1121 }
1122
1123 unsigned tegra_dc_get_out_height(struct tegra_dc *dc)
1124 {
1125         if (dc->out)
1126                 return dc->out->height;
1127         else
1128                 return 0;
1129 }
1130 EXPORT_SYMBOL(tegra_dc_get_out_height);
1131
1132 unsigned tegra_dc_get_out_width(struct tegra_dc *dc)
1133 {
1134         if (dc->out)
1135                 return dc->out->width;
1136         else
1137                 return 0;
1138 }
1139 EXPORT_SYMBOL(tegra_dc_get_out_width);
1140
1141 static irqreturn_t tegra_dc_irq(int irq, void *ptr)
1142 {
1143 #ifndef CONFIG_TEGRA_FPGA_PLATFORM
1144         struct tegra_dc *dc = ptr;
1145         unsigned long status;
1146         unsigned long val;
1147         unsigned long underflow_mask;
1148         int i;
1149
1150         status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
1151         tegra_dc_writel(dc, status, DC_CMD_INT_STATUS);
1152
1153         if (status & FRAME_END_INT) {
1154                 int completed = 0;
1155                 int dirty = 0;
1156
1157                 val = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
1158                 for (i = 0; i < DC_N_WINDOWS; i++) {
1159                         if (!(val & (WIN_A_UPDATE << i))) {
1160                                 dc->windows[i].dirty = 0;
1161                                 completed = 1;
1162                         } else {
1163                                 dirty = 1;
1164                         }
1165                 }
1166
1167                 if (!dirty) {
1168                         val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
1169                         val &= ~FRAME_END_INT;
1170                         tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
1171                 }
1172
1173                 if (completed)
1174                         wake_up(&dc->wq);
1175         }
1176
1177
1178         /*
1179          * Overlays can get thier internal state corrupted during and underflow
1180          * condition.  The only way to fix this state is to reset the DC.
1181          * if we get 4 consecutive frames with underflows, assume we're
1182          * hosed and reset.
1183          */
1184         underflow_mask = status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT);
1185         if (underflow_mask) {
1186                 val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
1187                 val |= V_BLANK_INT;
1188                 tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
1189                 dc->underflow_mask |= underflow_mask;
1190         }
1191
1192         if (status & V_BLANK_INT) {
1193                 int i;
1194
1195                 for (i = 0; i< DC_N_WINDOWS; i++) {
1196                         if (dc->underflow_mask & (WIN_A_UF_INT <<i)) {
1197                                 dc->windows[i].underflows++;
1198
1199                                 if (dc->windows[i].underflows > 4)
1200                                         schedule_work(&dc->reset_work);
1201                         } else {
1202                                 dc->windows[i].underflows = 0;
1203                         }
1204                 }
1205
1206                 if (!dc->underflow_mask) {
1207                         val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
1208                         val &= ~V_BLANK_INT;
1209                         tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
1210                 }
1211
1212                 dc->underflow_mask = 0;
1213         }
1214
1215
1216         return IRQ_HANDLED;
1217 #else
1218         return IRQ_NONE;
1219 #endif
1220 }
1221
1222 static void tegra_dc_set_color_control(struct tegra_dc *dc)
1223 {
1224         u32 color_control;
1225
1226         switch (dc->out->depth) {
1227         case 3:
1228                 color_control = BASE_COLOR_SIZE111;
1229                 break;
1230
1231         case 6:
1232                 color_control = BASE_COLOR_SIZE222;
1233                 break;
1234
1235         case 8:
1236                 color_control = BASE_COLOR_SIZE332;
1237                 break;
1238
1239         case 9:
1240                 color_control = BASE_COLOR_SIZE333;
1241                 break;
1242
1243         case 12:
1244                 color_control = BASE_COLOR_SIZE444;
1245                 break;
1246
1247         case 15:
1248                 color_control = BASE_COLOR_SIZE555;
1249                 break;
1250
1251         case 16:
1252                 color_control = BASE_COLOR_SIZE565;
1253                 break;
1254
1255         case 18:
1256                 color_control = BASE_COLOR_SIZE666;
1257                 break;
1258
1259         default:
1260                 color_control = BASE_COLOR_SIZE888;
1261                 break;
1262         }
1263
1264         switch (dc->out->dither) {
1265         case TEGRA_DC_DISABLE_DITHER:
1266                 color_control |= DITHER_CONTROL_DISABLE;
1267                 break;
1268         case TEGRA_DC_ORDERED_DITHER:
1269                 color_control |= DITHER_CONTROL_ORDERED;
1270                 break;
1271         case TEGRA_DC_ERRDIFF_DITHER:
1272                 /* The line buffer for error-diffusion dither is limited
1273                  * to 640 pixels per line. This limits the maximum
1274                  * horizontal active area size to 640 pixels when error
1275                  * diffusion is enabled.
1276                  */
1277                 BUG_ON(dc->mode.h_active > 640);
1278                 color_control |= DITHER_CONTROL_ERRDIFF;
1279                 break;
1280         }
1281
1282         tegra_dc_writel(dc, color_control, DC_DISP_DISP_COLOR_CONTROL);
1283 }
1284
1285 static void tegra_dc_init(struct tegra_dc *dc)
1286 {
1287         u32 disp_syncpt;
1288         u32 vblank_syncpt;
1289         int i;
1290
1291         tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
1292         if (dc->ndev->id == 0) {
1293                 disp_syncpt = NVSYNCPT_DISP0;
1294                 vblank_syncpt = NVSYNCPT_VBLANK0;
1295
1296                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0A,
1297                                       TEGRA_MC_PRIO_MED);
1298                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0B,
1299                                       TEGRA_MC_PRIO_MED);
1300                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0C,
1301                                       TEGRA_MC_PRIO_MED);
1302                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY1B,
1303                                       TEGRA_MC_PRIO_MED);
1304                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAYHC,
1305                                       TEGRA_MC_PRIO_HIGH);
1306         } else if (dc->ndev->id == 1) {
1307                 disp_syncpt = NVSYNCPT_DISP1;
1308                 vblank_syncpt = NVSYNCPT_VBLANK1;
1309
1310                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0AB,
1311                                       TEGRA_MC_PRIO_MED);
1312                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0BB,
1313                                       TEGRA_MC_PRIO_MED);
1314                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0CB,
1315                                       TEGRA_MC_PRIO_MED);
1316                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY1BB,
1317                                       TEGRA_MC_PRIO_MED);
1318                 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAYHCB,
1319                                       TEGRA_MC_PRIO_HIGH);
1320         }
1321         tegra_dc_writel(dc, 0x00000100 | vblank_syncpt, DC_CMD_CONT_SYNCPT_VSYNC);
1322         tegra_dc_writel(dc, 0x00004700, DC_CMD_INT_TYPE);
1323         tegra_dc_writel(dc, 0x0001c700, DC_CMD_INT_POLARITY);
1324         tegra_dc_writel(dc, 0x00202020, DC_DISP_MEM_HIGH_PRIORITY);
1325         tegra_dc_writel(dc, 0x00010101, DC_DISP_MEM_HIGH_PRIORITY_TIMER);
1326
1327         tegra_dc_writel(dc, (FRAME_END_INT |
1328                              V_BLANK_INT |
1329                              WIN_A_UF_INT |
1330                              WIN_B_UF_INT |
1331                              WIN_C_UF_INT), DC_CMD_INT_MASK);
1332         tegra_dc_writel(dc, (WIN_A_UF_INT |
1333                              WIN_B_UF_INT |
1334                              WIN_C_UF_INT), DC_CMD_INT_ENABLE);
1335
1336         tegra_dc_writel(dc, 0x00000000, DC_DISP_BORDER_COLOR);
1337
1338         tegra_dc_set_color_control(dc);
1339         for (i = 0; i < DC_N_WINDOWS; i++) {
1340                 tegra_dc_writel(dc, WINDOW_A_SELECT << i,
1341                                 DC_CMD_DISPLAY_WINDOW_HEADER);
1342                 tegra_dc_set_csc(dc);
1343                 tegra_dc_set_scaling_filter(dc);
1344         }
1345
1346
1347         dc->syncpt_id = disp_syncpt;
1348
1349         dc->syncpt_min = dc->syncpt_max =
1350                 nvhost_syncpt_read(&dc->ndev->host->syncpt, disp_syncpt);
1351
1352         print_mode(dc, &dc->mode, __func__);
1353
1354         if (dc->mode.pclk)
1355                 tegra_dc_program_mode(dc, &dc->mode);
1356 }
1357
1358 static bool _tegra_dc_controller_enable(struct tegra_dc *dc)
1359 {
1360         if (dc->out->enable)
1361                 dc->out->enable();
1362
1363         tegra_dc_setup_clk(dc, dc->clk);
1364
1365         clk_enable(dc->clk);
1366         clk_enable(dc->emc_clk);
1367         tegra_periph_reset_deassert(dc->clk);
1368         msleep(10);
1369
1370         enable_irq(dc->irq);
1371
1372         tegra_dc_init(dc);
1373
1374         if (dc->out_ops && dc->out_ops->enable)
1375                 dc->out_ops->enable(dc);
1376
1377         if (dc->out->out_pins)
1378                 tegra_dc_set_out_pin_polars(dc, dc->out->out_pins,
1379                                             dc->out->n_out_pins);
1380
1381         if (dc->out->postpoweron)
1382                 dc->out->postpoweron();
1383
1384         /* force a full blending update */
1385         dc->blend.z[0] = -1;
1386
1387         return true;
1388 }
1389
1390 static bool _tegra_dc_enable(struct tegra_dc *dc)
1391 {
1392         if (dc->mode.pclk == 0)
1393                 return false;
1394
1395         if (!dc->out)
1396                 return false;
1397
1398         tegra_dc_io_start(dc);
1399
1400         return _tegra_dc_controller_enable(dc);
1401 }
1402
1403 void tegra_dc_enable(struct tegra_dc *dc)
1404 {
1405         mutex_lock(&dc->lock);
1406
1407         if (!dc->enabled)
1408                 dc->enabled = _tegra_dc_enable(dc);
1409
1410         mutex_unlock(&dc->lock);
1411 }
1412
1413 static void _tegra_dc_controller_disable(struct tegra_dc *dc)
1414 {
1415         disable_irq(dc->irq);
1416
1417         if (dc->overlay)
1418                 tegra_overlay_disable(dc->overlay);
1419
1420         if (dc->out_ops && dc->out_ops->disable)
1421                 dc->out_ops->disable(dc);
1422
1423         clk_disable(dc->emc_clk);
1424         clk_disable(dc->clk);
1425         tegra_dvfs_set_rate(dc->clk, 0);
1426
1427         if (dc->out && dc->out->disable)
1428                 dc->out->disable();
1429
1430         /* flush any pending syncpt waits */
1431         while (dc->syncpt_min < dc->syncpt_max) {
1432                 dc->syncpt_min++;
1433                 nvhost_syncpt_cpu_incr(&dc->ndev->host->syncpt, dc->syncpt_id);
1434         }
1435 }
1436
1437 static void _tegra_dc_disable(struct tegra_dc *dc)
1438 {
1439         _tegra_dc_controller_disable(dc);
1440         tegra_dc_io_end(dc);
1441 }
1442
1443 void tegra_dc_disable(struct tegra_dc *dc)
1444 {
1445         mutex_lock(&dc->lock);
1446
1447         if (dc->enabled) {
1448                 dc->enabled = false;
1449
1450                 if (!dc->suspended)
1451                         _tegra_dc_disable(dc);
1452         }
1453
1454         mutex_unlock(&dc->lock);
1455 }
1456
1457 static void tegra_dc_reset_worker(struct work_struct *work)
1458 {
1459         struct tegra_dc *dc =
1460                 container_of(work, struct tegra_dc, reset_work);
1461
1462         unsigned long val = 0;
1463
1464         dev_warn(&dc->ndev->dev, "overlay stuck in underflow state.  resetting.\n");
1465
1466         mutex_lock(&shared_lock);
1467         mutex_lock(&dc->lock);
1468
1469         if (dc->enabled == false || dc->suspended)
1470                 return;
1471
1472         dc->enabled = false;
1473
1474         /*
1475          * off host read bus
1476          */
1477         val = tegra_dc_readl(dc, DC_CMD_CONT_SYNCPT_VSYNC);
1478         val &= ~(0x00000100);
1479         tegra_dc_writel(dc, val, DC_CMD_CONT_SYNCPT_VSYNC);
1480
1481         /*
1482          * set DC to STOP mode
1483          */
1484         tegra_dc_writel(dc, DISP_CTRL_MODE_STOP, DC_CMD_DISPLAY_COMMAND);
1485
1486         msleep(10);
1487
1488         _tegra_dc_controller_disable(dc);
1489
1490         if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) {
1491                 mutex_lock(&tegra_dcs[1]->lock);
1492                 disable_irq(tegra_dcs[1]->irq);
1493         } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) {
1494                 mutex_lock(&tegra_dcs[0]->lock);
1495                 disable_irq(tegra_dcs[0]->irq);
1496         }
1497
1498         msleep(5);
1499
1500         tegra_periph_reset_assert(dc->clk);
1501         msleep(2);
1502
1503         if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) {
1504                 enable_irq(tegra_dcs[1]->irq);
1505                 mutex_unlock(&tegra_dcs[1]->lock);
1506         } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) {
1507                 enable_irq(tegra_dcs[0]->irq);
1508                 mutex_unlock(&tegra_dcs[0]->lock);
1509         }
1510
1511         /* _tegra_dc_enable deasserts reset */
1512         _tegra_dc_controller_enable(dc);
1513
1514         dc->enabled = true;
1515         mutex_unlock(&dc->lock);
1516         mutex_unlock(&shared_lock);
1517 }
1518
1519
1520 static int tegra_dc_probe(struct nvhost_device *ndev)
1521 {
1522         struct tegra_dc *dc;
1523         struct clk *clk;
1524         struct clk *emc_clk;
1525         struct resource *res;
1526         struct resource *base_res;
1527         struct resource *fb_mem = NULL;
1528         int ret = 0;
1529         void __iomem *base;
1530         int irq;
1531         int i;
1532         unsigned long emc_clk_rate;
1533
1534         if (!ndev->dev.platform_data) {
1535                 dev_err(&ndev->dev, "no platform data\n");
1536                 return -ENOENT;
1537         }
1538
1539         dc = kzalloc(sizeof(struct tegra_dc), GFP_KERNEL);
1540         if (!dc) {
1541                 dev_err(&ndev->dev, "can't allocate memory for tegra_dc\n");
1542                 return -ENOMEM;
1543         }
1544
1545         irq = nvhost_get_irq_byname(ndev, "irq");
1546         if (irq <= 0) {
1547                 dev_err(&ndev->dev, "no irq\n");
1548                 ret = -ENOENT;
1549                 goto err_free;
1550         }
1551
1552         res = nvhost_get_resource_byname(ndev, IORESOURCE_MEM, "regs");
1553         if (!res) {
1554                 dev_err(&ndev->dev, "no mem resource\n");
1555                 ret = -ENOENT;
1556                 goto err_free;
1557         }
1558
1559         base_res = request_mem_region(res->start, resource_size(res), ndev->name);
1560         if (!base_res) {
1561                 dev_err(&ndev->dev, "request_mem_region failed\n");
1562                 ret = -EBUSY;
1563                 goto err_free;
1564         }
1565
1566         base = ioremap(res->start, resource_size(res));
1567         if (!base) {
1568                 dev_err(&ndev->dev, "registers can't be mapped\n");
1569                 ret = -EBUSY;
1570                 goto err_release_resource_reg;
1571         }
1572
1573         fb_mem = nvhost_get_resource_byname(ndev, IORESOURCE_MEM, "fbmem");
1574
1575         clk = clk_get(&ndev->dev, NULL);
1576         if (IS_ERR_OR_NULL(clk)) {
1577                 dev_err(&ndev->dev, "can't get clock\n");
1578                 ret = -ENOENT;
1579                 goto err_iounmap_reg;
1580         }
1581
1582         emc_clk = clk_get(&ndev->dev, "emc");
1583         if (IS_ERR_OR_NULL(emc_clk)) {
1584                 dev_err(&ndev->dev, "can't get emc clock\n");
1585                 ret = -ENOENT;
1586                 goto err_put_clk;
1587         }
1588
1589         dc->clk = clk;
1590         dc->emc_clk = emc_clk;
1591         dc->base_res = base_res;
1592         dc->base = base;
1593         dc->irq = irq;
1594         dc->ndev = ndev;
1595         dc->pdata = ndev->dev.platform_data;
1596
1597         /*
1598          * The emc is a shared clock, it will be set based on
1599          * the requirements for each user on the bus.
1600          */
1601         emc_clk_rate = dc->pdata->emc_clk_rate;
1602         clk_set_rate(emc_clk, emc_clk_rate ? emc_clk_rate : ULONG_MAX);
1603
1604         if (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED)
1605                 dc->enabled = true;
1606
1607         mutex_init(&dc->lock);
1608         init_waitqueue_head(&dc->wq);
1609         INIT_WORK(&dc->reset_work, tegra_dc_reset_worker);
1610
1611         dc->n_windows = DC_N_WINDOWS;
1612         for (i = 0; i < dc->n_windows; i++) {
1613                 dc->windows[i].idx = i;
1614                 dc->windows[i].dc = dc;
1615         }
1616
1617         if (request_irq(irq, tegra_dc_irq, IRQF_DISABLED,
1618                         dev_name(&ndev->dev), dc)) {
1619                 dev_err(&ndev->dev, "request_irq %d failed\n", irq);
1620                 ret = -EBUSY;
1621                 goto err_put_emc_clk;
1622         }
1623
1624         /* hack to ballence enable_irq calls in _tegra_dc_enable() */
1625         disable_irq(dc->irq);
1626
1627         ret = tegra_dc_add(dc, ndev->id);
1628         if (ret < 0) {
1629                 dev_err(&ndev->dev, "can't add dc\n");
1630                 goto err_free_irq;
1631         }
1632
1633         nvhost_set_drvdata(ndev, dc);
1634
1635         if (dc->pdata->default_out)
1636                 tegra_dc_set_out(dc, dc->pdata->default_out);
1637         else
1638                 dev_err(&ndev->dev, "No default output specified.  Leaving output disabled.\n");
1639
1640         mutex_lock(&dc->lock);
1641         if (dc->enabled)
1642                 _tegra_dc_enable(dc);
1643         mutex_unlock(&dc->lock);
1644
1645         tegra_dc_dbg_add(dc);
1646
1647         dev_info(&ndev->dev, "probed\n");
1648
1649         if (dc->pdata->fb) {
1650                 if (dc->pdata->fb->bits_per_pixel == -1) {
1651                         unsigned long fmt;
1652                         tegra_dc_writel(dc,
1653                                         WINDOW_A_SELECT << dc->pdata->fb->win,
1654                                         DC_CMD_DISPLAY_WINDOW_HEADER);
1655
1656                         fmt = tegra_dc_readl(dc, DC_WIN_COLOR_DEPTH);
1657                         dc->pdata->fb->bits_per_pixel =
1658                                 tegra_dc_fmt_bpp(fmt);
1659                 }
1660
1661                 dc->fb = tegra_fb_register(ndev, dc, dc->pdata->fb, fb_mem);
1662                 if (IS_ERR_OR_NULL(dc->fb))
1663                         dc->fb = NULL;
1664         }
1665
1666         if (dc->fb) {
1667                 dc->overlay = tegra_overlay_register(ndev, dc);
1668                 if (IS_ERR_OR_NULL(dc->overlay))
1669                         dc->overlay = NULL;
1670         }
1671
1672         if (dc->out_ops && dc->out_ops->detect)
1673                 dc->out_ops->detect(dc);
1674
1675         return 0;
1676
1677 err_free_irq:
1678         free_irq(irq, dc);
1679 err_put_emc_clk:
1680         clk_put(emc_clk);
1681 err_put_clk:
1682         clk_put(clk);
1683 err_iounmap_reg:
1684         iounmap(base);
1685         if (fb_mem)
1686                 release_resource(fb_mem);
1687 err_release_resource_reg:
1688         release_resource(base_res);
1689 err_free:
1690         kfree(dc);
1691
1692         return ret;
1693 }
1694
1695 static int tegra_dc_remove(struct nvhost_device *ndev)
1696 {
1697         struct tegra_dc *dc = nvhost_get_drvdata(ndev);
1698
1699         if (dc->overlay) {
1700                 tegra_overlay_unregister(dc->overlay);
1701         }
1702
1703         if (dc->fb) {
1704                 tegra_fb_unregister(dc->fb);
1705                 if (dc->fb_mem)
1706                         release_resource(dc->fb_mem);
1707         }
1708
1709
1710         if (dc->enabled)
1711                 _tegra_dc_disable(dc);
1712
1713         free_irq(dc->irq, dc);
1714         clk_put(dc->emc_clk);
1715         clk_put(dc->clk);
1716         iounmap(dc->base);
1717         if (dc->fb_mem)
1718                 release_resource(dc->base_res);
1719         kfree(dc);
1720         return 0;
1721 }
1722
1723 #ifdef CONFIG_PM
1724 static int tegra_dc_suspend(struct nvhost_device *ndev, pm_message_t state)
1725 {
1726         struct tegra_dc *dc = nvhost_get_drvdata(ndev);
1727
1728         dev_info(&ndev->dev, "suspend\n");
1729
1730         mutex_lock(&dc->lock);
1731
1732         if (dc->out_ops && dc->out_ops->suspend)
1733                 dc->out_ops->suspend(dc);
1734
1735         if (dc->enabled) {
1736                 tegra_fb_suspend(dc->fb);
1737                 _tegra_dc_disable(dc);
1738
1739                 dc->suspended = true;
1740         }
1741         mutex_unlock(&dc->lock);
1742
1743         return 0;
1744 }
1745
1746 static int tegra_dc_resume(struct nvhost_device *ndev)
1747 {
1748         struct tegra_dc *dc = nvhost_get_drvdata(ndev);
1749
1750         dev_info(&ndev->dev, "resume\n");
1751
1752         mutex_lock(&dc->lock);
1753         dc->suspended = false;
1754
1755         if (dc->enabled)
1756                 _tegra_dc_enable(dc);
1757
1758         if (dc->out_ops && dc->out_ops->resume)
1759                 dc->out_ops->resume(dc);
1760         mutex_unlock(&dc->lock);
1761
1762         return 0;
1763 }
1764
1765 #endif
1766
1767 extern int suspend_set(const char *val, struct kernel_param *kp)
1768 {
1769         if (!strcmp(val, "dump"))
1770                 dump_regs(tegra_dcs[0]);
1771 #ifdef CONFIG_PM
1772         else if (!strcmp(val, "suspend"))
1773                 tegra_dc_suspend(tegra_dcs[0]->ndev, PMSG_SUSPEND);
1774         else if (!strcmp(val, "resume"))
1775                 tegra_dc_resume(tegra_dcs[0]->ndev);
1776 #endif
1777
1778         return 0;
1779 }
1780
1781 extern int suspend_get(char *buffer, struct kernel_param *kp)
1782 {
1783         return 0;
1784 }
1785
1786 int suspend;
1787
1788 module_param_call(suspend, suspend_set, suspend_get, &suspend, 0644);
1789
1790 struct nvhost_driver tegra_dc_driver = {
1791         .driver = {
1792                 .name = "tegradc",
1793                 .owner = THIS_MODULE,
1794         },
1795         .probe = tegra_dc_probe,
1796         .remove = tegra_dc_remove,
1797 #ifdef CONFIG_PM
1798         .suspend = tegra_dc_suspend,
1799         .resume = tegra_dc_resume,
1800 #endif
1801 };
1802
1803 static int __init tegra_dc_module_init(void)
1804 {
1805         return nvhost_driver_register(&tegra_dc_driver);
1806 }
1807
1808 static void __exit tegra_dc_module_exit(void)
1809 {
1810         nvhost_driver_unregister(&tegra_dc_driver);
1811 }
1812
1813 module_exit(tegra_dc_module_exit);
1814 module_init(tegra_dc_module_init);