aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/dc/dc.c')
-rw-r--r--drivers/video/tegra/dc/dc.c3120
1 files changed, 3120 insertions, 0 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
new file mode 100644
index 00000000000..8b3bf041a7d
--- /dev/null
+++ b/drivers/video/tegra/dc/dc.c
@@ -0,0 +1,3120 @@
1/*
2 * drivers/video/tegra/dc/dc.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Author: Erik Gilling <konkers@android.com>
6 *
7 * Copyright (C) 2010-2012 NVIDIA Corporation
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/err.h>
23#include <linux/errno.h>
24#include <linux/interrupt.h>
25#include <linux/slab.h>
26#include <linux/io.h>
27#include <linux/clk.h>
28#include <linux/mutex.h>
29#include <linux/delay.h>
30#include <linux/dma-mapping.h>
31#include <linux/workqueue.h>
32#include <linux/ktime.h>
33#include <linux/debugfs.h>
34#include <linux/seq_file.h>
35#include <linux/backlight.h>
36#include <video/tegrafb.h>
37#include <drm/drm_fixed.h>
38#ifdef CONFIG_SWITCH
39#include <linux/switch.h>
40#endif
41
42
43#include <mach/clk.h>
44#include <mach/dc.h>
45#include <mach/fb.h>
46#include <mach/mc.h>
47#include <linux/nvhost.h>
48#include <mach/latency_allowance.h>
49
50#include "dc_reg.h"
51#include "dc_priv.h"
52#include "nvsd.h"
53
54#define TEGRA_CRC_LATCHED_DELAY 34
55
56#define DC_COM_PIN_OUTPUT_POLARITY1_INIT_VAL 0x01000000
57#define DC_COM_PIN_OUTPUT_POLARITY3_INIT_VAL 0x0
58
59#ifndef CONFIG_TEGRA_FPGA_PLATFORM
60#define ALL_UF_INT (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)
61#else
62/* ignore underflows when on simulation and fpga platform */
63#define ALL_UF_INT (0)
64#endif
65
66static int no_vsync;
67
68static void _tegra_dc_controller_disable(struct tegra_dc *dc);
69
70module_param_named(no_vsync, no_vsync, int, S_IRUGO | S_IWUSR);
71
72static int use_dynamic_emc = 1;
73
74module_param_named(use_dynamic_emc, use_dynamic_emc, int, S_IRUGO | S_IWUSR);
75
76struct tegra_dc *tegra_dcs[TEGRA_MAX_DC];
77
78DEFINE_MUTEX(tegra_dc_lock);
79DEFINE_MUTEX(shared_lock);
80
81static const struct {
82 bool h;
83 bool v;
84} can_filter[] = {
85 /* Window A has no filtering */
86 { false, false },
87 /* Window B has both H and V filtering */
88 { true, true },
89 /* Window C has only H filtering */
90 { false, true },
91};
92static inline bool win_use_v_filter(const struct tegra_dc_win *win)
93{
94 return can_filter[win->idx].v &&
95 win->h.full != dfixed_const(win->out_h);
96}
97static inline bool win_use_h_filter(const struct tegra_dc_win *win)
98{
99 return can_filter[win->idx].h &&
100 win->w.full != dfixed_const(win->out_w);
101}
102
103static inline int tegra_dc_fmt_bpp(int fmt)
104{
105 switch (fmt) {
106 case TEGRA_WIN_FMT_P1:
107 return 1;
108
109 case TEGRA_WIN_FMT_P2:
110 return 2;
111
112 case TEGRA_WIN_FMT_P4:
113 return 4;
114
115 case TEGRA_WIN_FMT_P8:
116 return 8;
117
118 case TEGRA_WIN_FMT_B4G4R4A4:
119 case TEGRA_WIN_FMT_B5G5R5A:
120 case TEGRA_WIN_FMT_B5G6R5:
121 case TEGRA_WIN_FMT_AB5G5R5:
122 return 16;
123
124 case TEGRA_WIN_FMT_B8G8R8A8:
125 case TEGRA_WIN_FMT_R8G8B8A8:
126 case TEGRA_WIN_FMT_B6x2G6x2R6x2A8:
127 case TEGRA_WIN_FMT_R6x2G6x2B6x2A8:
128 return 32;
129
130 /* for planar formats, size of the Y plane, 8bit */
131 case TEGRA_WIN_FMT_YCbCr420P:
132 case TEGRA_WIN_FMT_YUV420P:
133 case TEGRA_WIN_FMT_YCbCr422P:
134 case TEGRA_WIN_FMT_YUV422P:
135 case TEGRA_WIN_FMT_YCbCr422R:
136 case TEGRA_WIN_FMT_YUV422R:
137 case TEGRA_WIN_FMT_YCbCr422RA:
138 case TEGRA_WIN_FMT_YUV422RA:
139 return 8;
140
141 case TEGRA_WIN_FMT_YCbCr422:
142 case TEGRA_WIN_FMT_YUV422:
143 /* FIXME: need to know the bpp of these formats */
144 return 0;
145 }
146 return 0;
147}
148
149static inline bool tegra_dc_is_yuv_planar(int fmt)
150{
151 switch (fmt) {
152 case TEGRA_WIN_FMT_YUV420P:
153 case TEGRA_WIN_FMT_YCbCr420P:
154 case TEGRA_WIN_FMT_YCbCr422P:
155 case TEGRA_WIN_FMT_YUV422P:
156 case TEGRA_WIN_FMT_YCbCr422R:
157 case TEGRA_WIN_FMT_YUV422R:
158 case TEGRA_WIN_FMT_YCbCr422RA:
159 case TEGRA_WIN_FMT_YUV422RA:
160 return true;
161 }
162 return false;
163}
164
165#define DUMP_REG(a) do { \
166 snprintf(buff, sizeof(buff), "%-32s\t%03x\t%08lx\n", \
167 #a, a, tegra_dc_readl(dc, a)); \
168 print(data, buff); \
169 } while (0)
170
171static void _dump_regs(struct tegra_dc *dc, void *data,
172 void (* print)(void *data, const char *str))
173{
174 int i;
175 char buff[256];
176
177 tegra_dc_io_start(dc);
178 clk_enable(dc->clk);
179
180 DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0);
181 DUMP_REG(DC_CMD_DISPLAY_COMMAND);
182 DUMP_REG(DC_CMD_SIGNAL_RAISE);
183 DUMP_REG(DC_CMD_INT_STATUS);
184 DUMP_REG(DC_CMD_INT_MASK);
185 DUMP_REG(DC_CMD_INT_ENABLE);
186 DUMP_REG(DC_CMD_INT_TYPE);
187 DUMP_REG(DC_CMD_INT_POLARITY);
188 DUMP_REG(DC_CMD_SIGNAL_RAISE1);
189 DUMP_REG(DC_CMD_SIGNAL_RAISE2);
190 DUMP_REG(DC_CMD_SIGNAL_RAISE3);
191 DUMP_REG(DC_CMD_STATE_ACCESS);
192 DUMP_REG(DC_CMD_STATE_CONTROL);
193 DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
194 DUMP_REG(DC_CMD_REG_ACT_CONTROL);
195
196 DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0);
197 DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1);
198 DUMP_REG(DC_DISP_DISP_WIN_OPTIONS);
199 DUMP_REG(DC_DISP_MEM_HIGH_PRIORITY);
200 DUMP_REG(DC_DISP_MEM_HIGH_PRIORITY_TIMER);
201 DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS);
202 DUMP_REG(DC_DISP_REF_TO_SYNC);
203 DUMP_REG(DC_DISP_SYNC_WIDTH);
204 DUMP_REG(DC_DISP_BACK_PORCH);
205 DUMP_REG(DC_DISP_DISP_ACTIVE);
206 DUMP_REG(DC_DISP_FRONT_PORCH);
207 DUMP_REG(DC_DISP_H_PULSE0_CONTROL);
208 DUMP_REG(DC_DISP_H_PULSE0_POSITION_A);
209 DUMP_REG(DC_DISP_H_PULSE0_POSITION_B);
210 DUMP_REG(DC_DISP_H_PULSE0_POSITION_C);
211 DUMP_REG(DC_DISP_H_PULSE0_POSITION_D);
212 DUMP_REG(DC_DISP_H_PULSE1_CONTROL);
213 DUMP_REG(DC_DISP_H_PULSE1_POSITION_A);
214 DUMP_REG(DC_DISP_H_PULSE1_POSITION_B);
215 DUMP_REG(DC_DISP_H_PULSE1_POSITION_C);
216 DUMP_REG(DC_DISP_H_PULSE1_POSITION_D);
217 DUMP_REG(DC_DISP_H_PULSE2_CONTROL);
218 DUMP_REG(DC_DISP_H_PULSE2_POSITION_A);
219 DUMP_REG(DC_DISP_H_PULSE2_POSITION_B);
220 DUMP_REG(DC_DISP_H_PULSE2_POSITION_C);
221 DUMP_REG(DC_DISP_H_PULSE2_POSITION_D);
222 DUMP_REG(DC_DISP_V_PULSE0_CONTROL);
223 DUMP_REG(DC_DISP_V_PULSE0_POSITION_A);
224 DUMP_REG(DC_DISP_V_PULSE0_POSITION_B);
225 DUMP_REG(DC_DISP_V_PULSE0_POSITION_C);
226 DUMP_REG(DC_DISP_V_PULSE1_CONTROL);
227 DUMP_REG(DC_DISP_V_PULSE1_POSITION_A);
228 DUMP_REG(DC_DISP_V_PULSE1_POSITION_B);
229 DUMP_REG(DC_DISP_V_PULSE1_POSITION_C);
230 DUMP_REG(DC_DISP_V_PULSE2_CONTROL);
231 DUMP_REG(DC_DISP_V_PULSE2_POSITION_A);
232 DUMP_REG(DC_DISP_V_PULSE3_CONTROL);
233 DUMP_REG(DC_DISP_V_PULSE3_POSITION_A);
234 DUMP_REG(DC_DISP_M0_CONTROL);
235 DUMP_REG(DC_DISP_M1_CONTROL);
236 DUMP_REG(DC_DISP_DI_CONTROL);
237 DUMP_REG(DC_DISP_PP_CONTROL);
238 DUMP_REG(DC_DISP_PP_SELECT_A);
239 DUMP_REG(DC_DISP_PP_SELECT_B);
240 DUMP_REG(DC_DISP_PP_SELECT_C);
241 DUMP_REG(DC_DISP_PP_SELECT_D);
242 DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL);
243 DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL);
244 DUMP_REG(DC_DISP_DISP_COLOR_CONTROL);
245 DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS);
246 DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS);
247 DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS);
248 DUMP_REG(DC_DISP_LCD_SPI_OPTIONS);
249 DUMP_REG(DC_DISP_BORDER_COLOR);
250 DUMP_REG(DC_DISP_COLOR_KEY0_LOWER);
251 DUMP_REG(DC_DISP_COLOR_KEY0_UPPER);
252 DUMP_REG(DC_DISP_COLOR_KEY1_LOWER);
253 DUMP_REG(DC_DISP_COLOR_KEY1_UPPER);
254 DUMP_REG(DC_DISP_CURSOR_FOREGROUND);
255 DUMP_REG(DC_DISP_CURSOR_BACKGROUND);
256 DUMP_REG(DC_DISP_CURSOR_START_ADDR);
257 DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS);
258 DUMP_REG(DC_DISP_CURSOR_POSITION);
259 DUMP_REG(DC_DISP_CURSOR_POSITION_NS);
260 DUMP_REG(DC_DISP_INIT_SEQ_CONTROL);
261 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A);
262 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B);
263 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C);
264 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D);
265 DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL);
266 DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST);
267 DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST);
268 DUMP_REG(DC_DISP_MCCIF_DISPLAY0C_HYST);
269 DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST);
270 DUMP_REG(DC_DISP_DAC_CRT_CTRL);
271 DUMP_REG(DC_DISP_DISP_MISC_CONTROL);
272
273
274 for (i = 0; i < 3; i++) {
275 print(data, "\n");
276 snprintf(buff, sizeof(buff), "WINDOW %c:\n", 'A' + i);
277 print(data, buff);
278
279 tegra_dc_writel(dc, WINDOW_A_SELECT << i,
280 DC_CMD_DISPLAY_WINDOW_HEADER);
281 DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
282 DUMP_REG(DC_WIN_WIN_OPTIONS);
283 DUMP_REG(DC_WIN_BYTE_SWAP);
284 DUMP_REG(DC_WIN_BUFFER_CONTROL);
285 DUMP_REG(DC_WIN_COLOR_DEPTH);
286 DUMP_REG(DC_WIN_POSITION);
287 DUMP_REG(DC_WIN_SIZE);
288 DUMP_REG(DC_WIN_PRESCALED_SIZE);
289 DUMP_REG(DC_WIN_H_INITIAL_DDA);
290 DUMP_REG(DC_WIN_V_INITIAL_DDA);
291 DUMP_REG(DC_WIN_DDA_INCREMENT);
292 DUMP_REG(DC_WIN_LINE_STRIDE);
293 DUMP_REG(DC_WIN_BUF_STRIDE);
294 DUMP_REG(DC_WIN_UV_BUF_STRIDE);
295 DUMP_REG(DC_WIN_BLEND_NOKEY);
296 DUMP_REG(DC_WIN_BLEND_1WIN);
297 DUMP_REG(DC_WIN_BLEND_2WIN_X);
298 DUMP_REG(DC_WIN_BLEND_2WIN_Y);
299 DUMP_REG(DC_WIN_BLEND_3WIN_XY);
300 DUMP_REG(DC_WINBUF_START_ADDR);
301 DUMP_REG(DC_WINBUF_START_ADDR_U);
302 DUMP_REG(DC_WINBUF_START_ADDR_V);
303 DUMP_REG(DC_WINBUF_ADDR_H_OFFSET);
304 DUMP_REG(DC_WINBUF_ADDR_V_OFFSET);
305 DUMP_REG(DC_WINBUF_UFLOW_STATUS);
306 DUMP_REG(DC_WIN_CSC_YOF);
307 DUMP_REG(DC_WIN_CSC_KYRGB);
308 DUMP_REG(DC_WIN_CSC_KUR);
309 DUMP_REG(DC_WIN_CSC_KVR);
310 DUMP_REG(DC_WIN_CSC_KUG);
311 DUMP_REG(DC_WIN_CSC_KVG);
312 DUMP_REG(DC_WIN_CSC_KUB);
313 DUMP_REG(DC_WIN_CSC_KVB);
314 }
315
316 DUMP_REG(DC_CMD_DISPLAY_POWER_CONTROL);
317 DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE2);
318 DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY2);
319 DUMP_REG(DC_COM_PIN_OUTPUT_DATA2);
320 DUMP_REG(DC_COM_PIN_INPUT_ENABLE2);
321 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT5);
322 DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0);
323 DUMP_REG(DC_DISP_M1_CONTROL);
324 DUMP_REG(DC_COM_PM1_CONTROL);
325 DUMP_REG(DC_COM_PM1_DUTY_CYCLE);
326 DUMP_REG(DC_DISP_SD_CONTROL);
327
328 clk_disable(dc->clk);
329 tegra_dc_io_end(dc);
330}
331
332#undef DUMP_REG
333
334#ifdef DEBUG
335static void dump_regs_print(void *data, const char *str)
336{
337 struct tegra_dc *dc = data;
338 dev_dbg(&dc->ndev->dev, "%s", str);
339}
340
341static void dump_regs(struct tegra_dc *dc)
342{
343 _dump_regs(dc, dc, dump_regs_print);
344}
345#else /* !DEBUG */
346
347static void dump_regs(struct tegra_dc *dc) {}
348
349#endif /* DEBUG */
350
351#ifdef CONFIG_DEBUG_FS
352
353static void dbg_regs_print(void *data, const char *str)
354{
355 struct seq_file *s = data;
356
357 seq_printf(s, "%s", str);
358}
359
360#undef DUMP_REG
361
362static int dbg_dc_show(struct seq_file *s, void *unused)
363{
364 struct tegra_dc *dc = s->private;
365
366 _dump_regs(dc, s, dbg_regs_print);
367
368 return 0;
369}
370
371
372static int dbg_dc_open(struct inode *inode, struct file *file)
373{
374 return single_open(file, dbg_dc_show, inode->i_private);
375}
376
377static const struct file_operations regs_fops = {
378 .open = dbg_dc_open,
379 .read = seq_read,
380 .llseek = seq_lseek,
381 .release = single_release,
382};
383
384static int dbg_dc_mode_show(struct seq_file *s, void *unused)
385{
386 struct tegra_dc *dc = s->private;
387 struct tegra_dc_mode *m;
388
389 mutex_lock(&dc->lock);
390 m = &dc->mode;
391 seq_printf(s,
392 "pclk: %d\n"
393 "h_ref_to_sync: %d\n"
394 "v_ref_to_sync: %d\n"
395 "h_sync_width: %d\n"
396 "v_sync_width: %d\n"
397 "h_back_porch: %d\n"
398 "v_back_porch: %d\n"
399 "h_active: %d\n"
400 "v_active: %d\n"
401 "h_front_porch: %d\n"
402 "v_front_porch: %d\n"
403 "stereo_mode: %d\n",
404 m->pclk, m->h_ref_to_sync, m->v_ref_to_sync,
405 m->h_sync_width, m->v_sync_width,
406 m->h_back_porch, m->v_back_porch,
407 m->h_active, m->v_active,
408 m->h_front_porch, m->v_front_porch,
409 m->stereo_mode);
410 mutex_unlock(&dc->lock);
411 return 0;
412}
413
414static int dbg_dc_mode_open(struct inode *inode, struct file *file)
415{
416 return single_open(file, dbg_dc_mode_show, inode->i_private);
417}
418
419static const struct file_operations mode_fops = {
420 .open = dbg_dc_mode_open,
421 .read = seq_read,
422 .llseek = seq_lseek,
423 .release = single_release,
424};
425
426static int dbg_dc_stats_show(struct seq_file *s, void *unused)
427{
428 struct tegra_dc *dc = s->private;
429
430 mutex_lock(&dc->lock);
431 seq_printf(s,
432 "underflows: %llu\n"
433 "underflows_a: %llu\n"
434 "underflows_b: %llu\n"
435 "underflows_c: %llu\n",
436 dc->stats.underflows,
437 dc->stats.underflows_a,
438 dc->stats.underflows_b,
439 dc->stats.underflows_c);
440 mutex_unlock(&dc->lock);
441
442 return 0;
443}
444
445static int dbg_dc_stats_open(struct inode *inode, struct file *file)
446{
447 return single_open(file, dbg_dc_stats_show, inode->i_private);
448}
449
450static const struct file_operations stats_fops = {
451 .open = dbg_dc_stats_open,
452 .read = seq_read,
453 .llseek = seq_lseek,
454 .release = single_release,
455};
456
457static void __devexit tegra_dc_remove_debugfs(struct tegra_dc *dc)
458{
459 if (dc->debugdir)
460 debugfs_remove_recursive(dc->debugdir);
461 dc->debugdir = NULL;
462}
463
464static void tegra_dc_create_debugfs(struct tegra_dc *dc)
465{
466 struct dentry *retval;
467
468 dc->debugdir = debugfs_create_dir(dev_name(&dc->ndev->dev), NULL);
469 if (!dc->debugdir)
470 goto remove_out;
471
472 retval = debugfs_create_file("regs", S_IRUGO, dc->debugdir, dc,
473 &regs_fops);
474 if (!retval)
475 goto remove_out;
476
477 retval = debugfs_create_file("mode", S_IRUGO, dc->debugdir, dc,
478 &mode_fops);
479 if (!retval)
480 goto remove_out;
481
482 retval = debugfs_create_file("stats", S_IRUGO, dc->debugdir, dc,
483 &stats_fops);
484 if (!retval)
485 goto remove_out;
486
487 return;
488remove_out:
489 dev_err(&dc->ndev->dev, "could not create debugfs\n");
490 tegra_dc_remove_debugfs(dc);
491}
492
493#else /* !CONFIG_DEBUGFS */
494static inline void tegra_dc_create_debugfs(struct tegra_dc *dc) { };
495static inline void __devexit tegra_dc_remove_debugfs(struct tegra_dc *dc) { };
496#endif /* CONFIG_DEBUGFS */
497
498static int tegra_dc_set(struct tegra_dc *dc, int index)
499{
500 int ret = 0;
501
502 mutex_lock(&tegra_dc_lock);
503 if (index >= TEGRA_MAX_DC) {
504 ret = -EINVAL;
505 goto out;
506 }
507
508 if (dc != NULL && tegra_dcs[index] != NULL) {
509 ret = -EBUSY;
510 goto out;
511 }
512
513 tegra_dcs[index] = dc;
514
515out:
516 mutex_unlock(&tegra_dc_lock);
517
518 return ret;
519}
520
521static unsigned int tegra_dc_has_multiple_dc(void)
522{
523 unsigned int idx;
524 unsigned int cnt = 0;
525 struct tegra_dc *dc;
526
527 mutex_lock(&tegra_dc_lock);
528 for (idx = 0; idx < TEGRA_MAX_DC; idx++)
529 cnt += ((dc = tegra_dcs[idx]) != NULL && dc->enabled) ? 1 : 0;
530 mutex_unlock(&tegra_dc_lock);
531
532 return (cnt > 1);
533}
534
535struct tegra_dc *tegra_dc_get_dc(unsigned idx)
536{
537 if (idx < TEGRA_MAX_DC)
538 return tegra_dcs[idx];
539 else
540 return NULL;
541}
542EXPORT_SYMBOL(tegra_dc_get_dc);
543
544struct tegra_dc_win *tegra_dc_get_window(struct tegra_dc *dc, unsigned win)
545{
546 if (win >= dc->n_windows)
547 return NULL;
548
549 return &dc->windows[win];
550}
551EXPORT_SYMBOL(tegra_dc_get_window);
552
553static int get_topmost_window(u32 *depths, unsigned long *wins)
554{
555 int idx, best = -1;
556
557 for_each_set_bit(idx, wins, DC_N_WINDOWS) {
558 if (best == -1 || depths[idx] < depths[best])
559 best = idx;
560 }
561 clear_bit(best, wins);
562 return best;
563}
564
565bool tegra_dc_get_connected(struct tegra_dc *dc)
566{
567 return dc->connected;
568}
569EXPORT_SYMBOL(tegra_dc_get_connected);
570
571static u32 blend_topwin(u32 flags)
572{
573 if (flags & TEGRA_WIN_FLAG_BLEND_COVERAGE)
574 return BLEND(NOKEY, ALPHA, 0xff, 0xff);
575 else if (flags & TEGRA_WIN_FLAG_BLEND_PREMULT)
576 return BLEND(NOKEY, PREMULT, 0xff, 0xff);
577 else
578 return BLEND(NOKEY, FIX, 0xff, 0xff);
579}
580
581static u32 blend_2win(int idx, unsigned long behind_mask, u32* flags, int xy)
582{
583 int other;
584
585 for (other = 0; other < DC_N_WINDOWS; other++) {
586 if (other != idx && (xy-- == 0))
587 break;
588 }
589 if (BIT(other) & behind_mask)
590 return blend_topwin(flags[idx]);
591 else if (flags[other])
592 return BLEND(NOKEY, DEPENDANT, 0x00, 0x00);
593 else
594 return BLEND(NOKEY, FIX, 0x00, 0x00);
595}
596
597static u32 blend_3win(int idx, unsigned long behind_mask, u32* flags)
598{
599 unsigned long infront_mask;
600 int first;
601
602 infront_mask = ~(behind_mask | BIT(idx));
603 infront_mask &= (BIT(DC_N_WINDOWS) - 1);
604 first = ffs(infront_mask) - 1;
605
606 if (!infront_mask)
607 return blend_topwin(flags[idx]);
608 else if (behind_mask && first != -1 && flags[first])
609 return BLEND(NOKEY, DEPENDANT, 0x00, 0x00);
610 else
611 return BLEND(NOKEY, FIX, 0x0, 0x0);
612}
613
614static void tegra_dc_set_blending(struct tegra_dc *dc, struct tegra_dc_blend *blend)
615{
616 unsigned long mask = BIT(DC_N_WINDOWS) - 1;
617
618 while (mask) {
619 int idx = get_topmost_window(blend->z, &mask);
620
621 tegra_dc_writel(dc, WINDOW_A_SELECT << idx,
622 DC_CMD_DISPLAY_WINDOW_HEADER);
623 tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff),
624 DC_WIN_BLEND_NOKEY);
625 tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff),
626 DC_WIN_BLEND_1WIN);
627 tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 0),
628 DC_WIN_BLEND_2WIN_X);
629 tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 1),
630 DC_WIN_BLEND_2WIN_Y);
631 tegra_dc_writel(dc, blend_3win(idx, mask, blend->flags),
632 DC_WIN_BLEND_3WIN_XY);
633 }
634}
635
636static void tegra_dc_init_csc_defaults(struct tegra_dc_csc *csc)
637{
638 csc->yof = 0x00f0;
639 csc->kyrgb = 0x012a;
640 csc->kur = 0x0000;
641 csc->kvr = 0x0198;
642 csc->kug = 0x039b;
643 csc->kvg = 0x032f;
644 csc->kub = 0x0204;
645 csc->kvb = 0x0000;
646}
647
648static void tegra_dc_set_csc(struct tegra_dc *dc, struct tegra_dc_csc *csc)
649{
650 tegra_dc_writel(dc, csc->yof, DC_WIN_CSC_YOF);
651 tegra_dc_writel(dc, csc->kyrgb, DC_WIN_CSC_KYRGB);
652 tegra_dc_writel(dc, csc->kur, DC_WIN_CSC_KUR);
653 tegra_dc_writel(dc, csc->kvr, DC_WIN_CSC_KVR);
654 tegra_dc_writel(dc, csc->kug, DC_WIN_CSC_KUG);
655 tegra_dc_writel(dc, csc->kvg, DC_WIN_CSC_KVG);
656 tegra_dc_writel(dc, csc->kub, DC_WIN_CSC_KUB);
657 tegra_dc_writel(dc, csc->kvb, DC_WIN_CSC_KVB);
658}
659
660int tegra_dc_update_csc(struct tegra_dc *dc, int win_idx)
661{
662 mutex_lock(&dc->lock);
663
664 if (!dc->enabled) {
665 mutex_unlock(&dc->lock);
666 return -EFAULT;
667 }
668
669 tegra_dc_writel(dc, WINDOW_A_SELECT << win_idx,
670 DC_CMD_DISPLAY_WINDOW_HEADER);
671
672 tegra_dc_set_csc(dc, &dc->windows[win_idx].csc);
673
674 mutex_unlock(&dc->lock);
675
676 return 0;
677}
678EXPORT_SYMBOL(tegra_dc_update_csc);
679
680static void tegra_dc_init_lut_defaults(struct tegra_dc_lut *lut)
681{
682 int i;
683 for (i = 0; i < 256; i++)
684 lut->r[i] = lut->g[i] = lut->b[i] = (u8)i;
685}
686
687static int tegra_dc_loop_lut(struct tegra_dc *dc,
688 struct tegra_dc_win *win,
689 int(*lambda)(struct tegra_dc *dc, int i, u32 rgb))
690{
691 struct tegra_dc_lut *lut = &win->lut;
692 struct tegra_dc_lut *global_lut = &dc->fb_lut;
693 int i;
694 for (i = 0; i < 256; i++) {
695
696 u32 r = (u32)lut->r[i];
697 u32 g = (u32)lut->g[i];
698 u32 b = (u32)lut->b[i];
699
700 if (!(win->ppflags & TEGRA_WIN_PPFLAG_CP_FBOVERRIDE)) {
701 r = (u32)global_lut->r[r];
702 g = (u32)global_lut->g[g];
703 b = (u32)global_lut->b[b];
704 }
705
706 if (!lambda(dc, i, r | (g<<8) | (b<<16)))
707 return 0;
708 }
709 return 1;
710}
711
712static int tegra_dc_lut_isdefaults_lambda(struct tegra_dc *dc, int i, u32 rgb)
713{
714 if (rgb != (i | (i<<8) | (i<<16)))
715 return 0;
716 return 1;
717}
718
719static int tegra_dc_set_lut_setreg_lambda(struct tegra_dc *dc, int i, u32 rgb)
720{
721 tegra_dc_writel(dc, rgb, DC_WIN_COLOR_PALETTE(i));
722 return 1;
723}
724
725static void tegra_dc_set_lut(struct tegra_dc *dc, struct tegra_dc_win* win)
726{
727 unsigned long val = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
728
729 tegra_dc_loop_lut(dc, win, tegra_dc_set_lut_setreg_lambda);
730
731 if (win->ppflags & TEGRA_WIN_PPFLAG_CP_ENABLE)
732 val |= CP_ENABLE;
733 else
734 val &= ~CP_ENABLE;
735
736 tegra_dc_writel(dc, val, DC_WIN_WIN_OPTIONS);
737}
738
739static int tegra_dc_update_winlut(struct tegra_dc *dc, int win_idx, int fbovr)
740{
741 struct tegra_dc_win *win = &dc->windows[win_idx];
742
743 mutex_lock(&dc->lock);
744
745 if (!dc->enabled) {
746 mutex_unlock(&dc->lock);
747 return -EFAULT;
748 }
749
750 if (fbovr > 0)
751 win->ppflags |= TEGRA_WIN_PPFLAG_CP_FBOVERRIDE;
752 else if (fbovr == 0)
753 win->ppflags &= ~TEGRA_WIN_PPFLAG_CP_FBOVERRIDE;
754
755 if (!tegra_dc_loop_lut(dc, win, tegra_dc_lut_isdefaults_lambda))
756 win->ppflags |= TEGRA_WIN_PPFLAG_CP_ENABLE;
757 else
758 win->ppflags &= ~TEGRA_WIN_PPFLAG_CP_ENABLE;
759
760 tegra_dc_writel(dc, WINDOW_A_SELECT << win_idx,
761 DC_CMD_DISPLAY_WINDOW_HEADER);
762
763 tegra_dc_set_lut(dc, win);
764
765 mutex_unlock(&dc->lock);
766
767 return 0;
768}
769
770int tegra_dc_update_lut(struct tegra_dc *dc, int win_idx, int fboveride)
771{
772 if (win_idx > -1)
773 return tegra_dc_update_winlut(dc, win_idx, fboveride);
774
775 for (win_idx = 0; win_idx < DC_N_WINDOWS; win_idx++) {
776 int err = tegra_dc_update_winlut(dc, win_idx, fboveride);
777 if (err)
778 return err;
779 }
780
781 return 0;
782}
783EXPORT_SYMBOL(tegra_dc_update_lut);
784
785static void tegra_dc_set_scaling_filter(struct tegra_dc *dc)
786{
787 unsigned i;
788 unsigned v0 = 128;
789 unsigned v1 = 0;
790 /* linear horizontal and vertical filters */
791 for (i = 0; i < 16; i++) {
792 tegra_dc_writel(dc, (v1 << 16) | (v0 << 8),
793 DC_WIN_H_FILTER_P(i));
794
795 tegra_dc_writel(dc, v0,
796 DC_WIN_V_FILTER_P(i));
797 v0 -= 8;
798 v1 += 8;
799 }
800}
801
802static void tegra_dc_set_latency_allowance(struct tegra_dc *dc,
803 struct tegra_dc_win *w)
804{
805 /* windows A, B, C for first and second display */
806 static const enum tegra_la_id la_id_tab[2][3] = {
807 /* first display */
808 { TEGRA_LA_DISPLAY_0A, TEGRA_LA_DISPLAY_0B,
809 TEGRA_LA_DISPLAY_0C },
810 /* second display */
811 { TEGRA_LA_DISPLAY_0AB, TEGRA_LA_DISPLAY_0BB,
812 TEGRA_LA_DISPLAY_0CB },
813 };
814 /* window B V-filter tap for first and second display. */
815 static const enum tegra_la_id vfilter_tab[2] = {
816 TEGRA_LA_DISPLAY_1B, TEGRA_LA_DISPLAY_1BB,
817 };
818 unsigned long bw;
819
820 BUG_ON(dc->ndev->id >= ARRAY_SIZE(la_id_tab));
821 BUG_ON(dc->ndev->id >= ARRAY_SIZE(vfilter_tab));
822 BUG_ON(w->idx >= ARRAY_SIZE(*la_id_tab));
823
824 bw = w->new_bandwidth;
825
826 /* tegra_dc_get_bandwidth() treats V filter windows as double
827 * bandwidth, but LA has a seperate client for V filter */
828 if (w->idx == 1 && win_use_v_filter(w))
829 bw /= 2;
830
831 /* our bandwidth is in bytes/sec, but LA takes MBps.
832 * round up bandwidth to 1MBps */
833 bw = bw / 1000000 + 1;
834
835#ifdef CONFIG_TEGRA_SILICON_PLATFORM
836 tegra_set_latency_allowance(la_id_tab[dc->ndev->id][w->idx], bw);
837 /* if window B, also set the 1B client for the 2-tap V filter. */
838 if (w->idx == 1)
839 tegra_set_latency_allowance(vfilter_tab[dc->ndev->id], bw);
840#endif
841
842 w->bandwidth = w->new_bandwidth;
843}
844
845static unsigned int tegra_dc_windows_is_overlapped(struct tegra_dc_win *a,
846 struct tegra_dc_win *b)
847{
848 if (!WIN_IS_ENABLED(a) || !WIN_IS_ENABLED(b))
849 return 0;
850
851 /* because memory access to load the fifo can overlap, only care
852 * if windows overlap vertically */
853 return ((a->out_y + a->out_h > b->out_y) && (a->out_y <= b->out_y)) ||
854 ((b->out_y + b->out_h > a->out_y) && (b->out_y <= a->out_y));
855}
856
857static unsigned long tegra_dc_find_max_bandwidth(struct tegra_dc_win *wins[],
858 int n)
859{
860 unsigned i;
861 unsigned j;
862 unsigned overlap_count;
863 unsigned max_bw = 0;
864
865 WARN_ONCE(n > 3, "Code assumes at most 3 windows, bandwidth is likely"
866 "inaccurate.\n");
867
868 /* If we had a large number of windows, we would compute adjacency
869 * graph representing 2 window overlaps, find all cliques in the graph,
870 * assign bandwidth to each clique, and then select the clique with
871 * maximum bandwidth. But because we have at most 3 windows,
872 * implementing proper Bron-Kerbosh algorithm would be an overkill,
873 * brute force will suffice.
874 *
875 * Thus: find maximum bandwidth for either single or a pair of windows
876 * and count number of window pair overlaps. If there are three
877 * pairs, all 3 window overlap.
878 */
879
880 overlap_count = 0;
881 for (i = 0; i < n; i++) {
882 unsigned int bw1;
883
884 if (wins[i] == NULL)
885 continue;
886 bw1 = wins[i]->new_bandwidth;
887 if (bw1 > max_bw)
888 /* Single window */
889 max_bw = bw1;
890
891 for (j = i + 1; j < n; j++) {
892 if (wins[j] == NULL)
893 continue;
894 if (tegra_dc_windows_is_overlapped(wins[i], wins[j])) {
895 unsigned int bw2 = wins[j]->new_bandwidth;
896 if (bw1 + bw2 > max_bw)
897 /* Window pair overlaps */
898 max_bw = bw1 + bw2;
899 overlap_count++;
900 }
901 }
902 }
903
904 if (overlap_count == 3)
905 /* All three windows overlap */
906 max_bw = wins[0]->new_bandwidth + wins[1]->new_bandwidth +
907 wins[2]->new_bandwidth;
908
909 return max_bw;
910}
911
912/*
913 * Calculate peak EMC bandwidth for each enabled window =
914 * pixel_clock * win_bpp * (use_v_filter ? 2 : 1)) * H_scale_factor *
915 * (windows_tiling ? 2 : 1)
916 *
917 *
918 * note:
919 * (*) We use 2 tap V filter, so need double BW if use V filter
920 * (*) Tiling mode on T30 and DDR3 requires double BW
921 */
922static unsigned long tegra_dc_calc_win_bandwidth(struct tegra_dc *dc,
923 struct tegra_dc_win *w)
924{
925 unsigned long ret;
926 int tiled_windows_bw_multiplier;
927 unsigned long bpp;
928
929 if (!WIN_IS_ENABLED(w))
930 return 0;
931
932 if (dfixed_trunc(w->w) == 0 || dfixed_trunc(w->h) == 0 ||
933 w->out_w == 0 || w->out_h == 0)
934 return 0;
935
936 tiled_windows_bw_multiplier =
937 tegra_mc_get_tiled_memory_bandwidth_multiplier();
938
939 /* all of tegra's YUV formats(420 and 422) fetch 2 bytes per pixel,
940 * but the size reported by tegra_dc_fmt_bpp for the planar version
941 * is of the luma plane's size only. */
942 bpp = tegra_dc_is_yuv_planar(w->fmt) ?
943 2 * tegra_dc_fmt_bpp(w->fmt) : tegra_dc_fmt_bpp(w->fmt);
944 /* perform calculations with most significant bits of pixel clock
945 * to prevent overflow of long. */
946 ret = (unsigned long)(dc->mode.pclk >> 16) *
947 bpp / 8 *
948 (win_use_v_filter(w) ? 2 : 1) * dfixed_trunc(w->w) / w->out_w *
949 (WIN_IS_TILED(w) ? tiled_windows_bw_multiplier : 1);
950
951/*
952 * Assuming 48% efficiency: i.e. if we calculate we need 70MBps, we
953 * will request 147MBps from EMC.
954 */
955 ret = ret * 2 + ret / 10;
956
957 /* if overflowed */
958 if (ret > (1UL << 31))
959 return ULONG_MAX;
960
961 return ret << 16; /* restore the scaling we did above */
962}
963
964static unsigned long tegra_dc_get_bandwidth(
965 struct tegra_dc_win *windows[], int n)
966{
967 int i;
968
969 BUG_ON(n > DC_N_WINDOWS);
970
971 /* emc rate and latency allowance both need to know per window
972 * bandwidths */
973 for (i = 0; i < n; i++) {
974 struct tegra_dc_win *w = windows[i];
975 if (w)
976 w->new_bandwidth = tegra_dc_calc_win_bandwidth(w->dc, w);
977 }
978
979 return tegra_dc_find_max_bandwidth(windows, n);
980}
981
982/* to save power, call when display memory clients would be idle */
983static void tegra_dc_clear_bandwidth(struct tegra_dc *dc)
984{
985 if (tegra_is_clk_enabled(dc->emc_clk))
986 clk_disable(dc->emc_clk);
987 dc->emc_clk_rate = 0;
988}
989
990static void tegra_dc_program_bandwidth(struct tegra_dc *dc)
991{
992 unsigned i;
993
994 if (dc->emc_clk_rate != dc->new_emc_clk_rate) {
995 /* going from 0 to non-zero */
996 if (!dc->emc_clk_rate && !tegra_is_clk_enabled(dc->emc_clk))
997 clk_enable(dc->emc_clk);
998
999 dc->emc_clk_rate = dc->new_emc_clk_rate;
1000 clk_set_rate(dc->emc_clk, dc->emc_clk_rate);
1001
1002 if (!dc->new_emc_clk_rate) /* going from non-zero to 0 */
1003 clk_disable(dc->emc_clk);
1004 }
1005
1006 for (i = 0; i < DC_N_WINDOWS; i++) {
1007 struct tegra_dc_win *w = &dc->windows[i];
1008 if (w->bandwidth != w->new_bandwidth && w->new_bandwidth != 0)
1009 tegra_dc_set_latency_allowance(dc, w);
1010 }
1011}
1012
1013static int tegra_dc_set_dynamic_emc(struct tegra_dc_win *windows[], int n)
1014{
1015 unsigned long new_rate;
1016 struct tegra_dc *dc;
1017
1018 if (!use_dynamic_emc)
1019 return 0;
1020
1021 dc = windows[0]->dc;
1022
1023 /* calculate the new rate based on this POST */
1024 new_rate = tegra_dc_get_bandwidth(windows, n);
1025 new_rate = EMC_BW_TO_FREQ(new_rate);
1026
1027 if (tegra_dc_has_multiple_dc())
1028 new_rate = ULONG_MAX;
1029
1030 dc->new_emc_clk_rate = new_rate;
1031
1032 return 0;
1033}
1034
1035static inline u32 compute_dda_inc(fixed20_12 in, unsigned out_int,
1036 bool v, unsigned Bpp)
1037{
1038 /*
1039 * min(round((prescaled_size_in_pixels - 1) * 0x1000 /
1040 * (post_scaled_size_in_pixels - 1)), MAX)
1041 * Where the value of MAX is as follows:
1042 * For V_DDA_INCREMENT: 15.0 (0xF000)
1043 * For H_DDA_INCREMENT: 4.0 (0x4000) for 4 Bytes/pix formats.
1044 * 8.0 (0x8000) for 2 Bytes/pix formats.
1045 */
1046
1047 fixed20_12 out = dfixed_init(out_int);
1048 u32 dda_inc;
1049 int max;
1050
1051 if (v) {
1052 max = 15;
1053 } else {
1054 switch (Bpp) {
1055 default:
1056 WARN_ON_ONCE(1);
1057 /* fallthrough */
1058 case 4:
1059 max = 4;
1060 break;
1061 case 2:
1062 max = 8;
1063 break;
1064 }
1065 }
1066
1067 out.full = max_t(u32, out.full - dfixed_const(1), dfixed_const(1));
1068 in.full -= dfixed_const(1);
1069
1070 dda_inc = dfixed_div(in, out);
1071
1072 dda_inc = min_t(u32, dda_inc, dfixed_const(max));
1073
1074 return dda_inc;
1075}
1076
1077static inline u32 compute_initial_dda(fixed20_12 in)
1078{
1079 return dfixed_frac(in);
1080}
1081
1082/* does not support updating windows on multiple dcs in one call */
1083int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
1084{
1085 struct tegra_dc *dc;
1086 unsigned long update_mask = GENERAL_ACT_REQ;
1087 unsigned long val;
1088 bool update_blend = false;
1089 int i;
1090
1091 dc = windows[0]->dc;
1092
1093 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) {
1094 /* Acquire one_shot_lock to avoid race condition between
1095 * cancellation of old delayed work and schedule of new
1096 * delayed work. */
1097 mutex_lock(&dc->one_shot_lock);
1098 cancel_delayed_work_sync(&dc->one_shot_work);
1099 }
1100 mutex_lock(&dc->lock);
1101
1102 if (!dc->enabled) {
1103 mutex_unlock(&dc->lock);
1104 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
1105 mutex_unlock(&dc->one_shot_lock);
1106 return -EFAULT;
1107 }
1108
1109 if (no_vsync)
1110 tegra_dc_writel(dc, WRITE_MUX_ACTIVE | READ_MUX_ACTIVE, DC_CMD_STATE_ACCESS);
1111 else
1112 tegra_dc_writel(dc, WRITE_MUX_ASSEMBLY | READ_MUX_ASSEMBLY, DC_CMD_STATE_ACCESS);
1113
1114 for (i = 0; i < DC_N_WINDOWS; i++) {
1115 tegra_dc_writel(dc, WINDOW_A_SELECT << i,
1116 DC_CMD_DISPLAY_WINDOW_HEADER);
1117 tegra_dc_writel(dc, 0, DC_WIN_WIN_OPTIONS);
1118 if (!no_vsync)
1119 update_mask |= WIN_A_ACT_REQ << i;
1120 }
1121
1122 for (i = 0; i < n; i++) {
1123 struct tegra_dc_win *win = windows[i];
1124 unsigned h_dda;
1125 unsigned v_dda;
1126 fixed20_12 h_offset, v_offset;
1127 bool invert_h = (win->flags & TEGRA_WIN_FLAG_INVERT_H) != 0;
1128 bool invert_v = (win->flags & TEGRA_WIN_FLAG_INVERT_V) != 0;
1129 bool yuvp = tegra_dc_is_yuv_planar(win->fmt);
1130 unsigned Bpp = tegra_dc_fmt_bpp(win->fmt) / 8;
1131 /* Bytes per pixel of bandwidth, used for dda_inc calculation */
1132 unsigned Bpp_bw = Bpp * (yuvp ? 2 : 1);
1133 const bool filter_h = win_use_h_filter(win);
1134 const bool filter_v = win_use_v_filter(win);
1135
1136 if (win->z != dc->blend.z[win->idx]) {
1137 dc->blend.z[win->idx] = win->z;
1138 update_blend = true;
1139 }
1140 if ((win->flags & TEGRA_WIN_BLEND_FLAGS_MASK) !=
1141 dc->blend.flags[win->idx]) {
1142 dc->blend.flags[win->idx] =
1143 win->flags & TEGRA_WIN_BLEND_FLAGS_MASK;
1144 update_blend = true;
1145 }
1146
1147 tegra_dc_writel(dc, WINDOW_A_SELECT << win->idx,
1148 DC_CMD_DISPLAY_WINDOW_HEADER);
1149
1150 if (!no_vsync)
1151 update_mask |= WIN_A_ACT_REQ << win->idx;
1152
1153 if (!WIN_IS_ENABLED(win)) {
1154 tegra_dc_writel(dc, 0, DC_WIN_WIN_OPTIONS);
1155 continue;
1156 }
1157
1158 tegra_dc_writel(dc, win->fmt, DC_WIN_COLOR_DEPTH);
1159 tegra_dc_writel(dc, 0, DC_WIN_BYTE_SWAP);
1160
1161 tegra_dc_writel(dc,
1162 V_POSITION(win->out_y) | H_POSITION(win->out_x),
1163 DC_WIN_POSITION);
1164 tegra_dc_writel(dc,
1165 V_SIZE(win->out_h) | H_SIZE(win->out_w),
1166 DC_WIN_SIZE);
1167 tegra_dc_writel(dc,
1168 V_PRESCALED_SIZE(dfixed_trunc(win->h)) |
1169 H_PRESCALED_SIZE(dfixed_trunc(win->w) * Bpp),
1170 DC_WIN_PRESCALED_SIZE);
1171
1172 h_dda = compute_dda_inc(win->w, win->out_w, false, Bpp_bw);
1173 v_dda = compute_dda_inc(win->h, win->out_h, true, Bpp_bw);
1174 tegra_dc_writel(dc, V_DDA_INC(v_dda) | H_DDA_INC(h_dda),
1175 DC_WIN_DDA_INCREMENT);
1176 h_dda = compute_initial_dda(win->x);
1177 v_dda = compute_initial_dda(win->y);
1178 tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA);
1179 tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA);
1180
1181 tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
1182 tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
1183 tegra_dc_writel(dc,
1184 (unsigned long)win->phys_addr,
1185 DC_WINBUF_START_ADDR);
1186
1187 if (!yuvp) {
1188 tegra_dc_writel(dc, win->stride, DC_WIN_LINE_STRIDE);
1189 } else {
1190 tegra_dc_writel(dc,
1191 (unsigned long)win->phys_addr_u,
1192 DC_WINBUF_START_ADDR_U);
1193 tegra_dc_writel(dc,
1194 (unsigned long)win->phys_addr_v,
1195 DC_WINBUF_START_ADDR_V);
1196 tegra_dc_writel(dc,
1197 LINE_STRIDE(win->stride) |
1198 UV_LINE_STRIDE(win->stride_uv),
1199 DC_WIN_LINE_STRIDE);
1200 }
1201
1202 h_offset = win->x;
1203 if (invert_h) {
1204 h_offset.full += win->w.full - dfixed_const(1);
1205 }
1206
1207 v_offset = win->y;
1208 if (invert_v) {
1209 v_offset.full += win->h.full - dfixed_const(1);
1210 }
1211
1212 tegra_dc_writel(dc, dfixed_trunc(h_offset) * Bpp,
1213 DC_WINBUF_ADDR_H_OFFSET);
1214 tegra_dc_writel(dc, dfixed_trunc(v_offset),
1215 DC_WINBUF_ADDR_V_OFFSET);
1216
1217 if (WIN_IS_TILED(win))
1218 tegra_dc_writel(dc,
1219 DC_WIN_BUFFER_ADDR_MODE_TILE |
1220 DC_WIN_BUFFER_ADDR_MODE_TILE_UV,
1221 DC_WIN_BUFFER_ADDR_MODE);
1222 else
1223 tegra_dc_writel(dc,
1224 DC_WIN_BUFFER_ADDR_MODE_LINEAR |
1225 DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV,
1226 DC_WIN_BUFFER_ADDR_MODE);
1227
1228 val = WIN_ENABLE;
1229 if (yuvp)
1230 val |= CSC_ENABLE;
1231 else if (tegra_dc_fmt_bpp(win->fmt) < 24)
1232 val |= COLOR_EXPAND;
1233
1234 if (win->ppflags & TEGRA_WIN_PPFLAG_CP_ENABLE)
1235 val |= CP_ENABLE;
1236
1237 if (filter_h)
1238 val |= H_FILTER_ENABLE;
1239 if (filter_v)
1240 val |= V_FILTER_ENABLE;
1241
1242 if (invert_h)
1243 val |= H_DIRECTION_DECREMENT;
1244 if (invert_v)
1245 val |= V_DIRECTION_DECREMENT;
1246
1247 tegra_dc_writel(dc, val, DC_WIN_WIN_OPTIONS);
1248
1249 win->dirty = no_vsync ? 0 : 1;
1250
1251 dev_dbg(&dc->ndev->dev, "%s():idx=%d z=%d x=%d y=%d w=%d h=%d "
1252 "out_x=%u out_y=%u out_w=%u out_h=%u "
1253 "fmt=%d yuvp=%d Bpp=%u filter_h=%d filter_v=%d",
1254 __func__, win->idx, win->z,
1255 dfixed_trunc(win->x), dfixed_trunc(win->y),
1256 dfixed_trunc(win->w), dfixed_trunc(win->h),
1257 win->out_x, win->out_y, win->out_w, win->out_h,
1258 win->fmt, yuvp, Bpp, filter_h, filter_v);
1259 }
1260
1261 if (update_blend) {
1262 tegra_dc_set_blending(dc, &dc->blend);
1263 for (i = 0; i < DC_N_WINDOWS; i++) {
1264 if (!no_vsync)
1265 dc->windows[i].dirty = 1;
1266 update_mask |= WIN_A_ACT_REQ << i;
1267 }
1268 }
1269
1270 tegra_dc_set_dynamic_emc(windows, n);
1271
1272 tegra_dc_writel(dc, update_mask << 8, DC_CMD_STATE_CONTROL);
1273
1274 tegra_dc_writel(dc, FRAME_END_INT | V_BLANK_INT, DC_CMD_INT_STATUS);
1275 if (!no_vsync) {
1276 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
1277 val |= (FRAME_END_INT | V_BLANK_INT | ALL_UF_INT);
1278 tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
1279 } else {
1280 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
1281 val &= ~(FRAME_END_INT | V_BLANK_INT | ALL_UF_INT);
1282 tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
1283 }
1284
1285 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
1286 schedule_delayed_work(&dc->one_shot_work,
1287 msecs_to_jiffies(dc->one_shot_delay_ms));
1288
1289 /* update EMC clock if calculated bandwidth has changed */
1290 tegra_dc_program_bandwidth(dc);
1291
1292 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
1293 update_mask |= NC_HOST_TRIG;
1294
1295 tegra_dc_writel(dc, update_mask, DC_CMD_STATE_CONTROL);
1296
1297 mutex_unlock(&dc->lock);
1298 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
1299 mutex_unlock(&dc->one_shot_lock);
1300
1301 return 0;
1302}
1303EXPORT_SYMBOL(tegra_dc_update_windows);
1304
1305u32 tegra_dc_get_syncpt_id(const struct tegra_dc *dc, int i)
1306{
1307 return dc->syncpt[i].id;
1308}
1309EXPORT_SYMBOL(tegra_dc_get_syncpt_id);
1310
1311u32 tegra_dc_incr_syncpt_max(struct tegra_dc *dc, int i)
1312{
1313 u32 max;
1314
1315 mutex_lock(&dc->lock);
1316 max = nvhost_syncpt_incr_max(&nvhost_get_host(dc->ndev)->syncpt,
1317 dc->syncpt[i].id, ((dc->enabled) ? 1 : 0));
1318 dc->syncpt[i].max = max;
1319 mutex_unlock(&dc->lock);
1320
1321 return max;
1322}
1323
1324void tegra_dc_incr_syncpt_min(struct tegra_dc *dc, int i, u32 val)
1325{
1326 mutex_lock(&dc->lock);
1327 if ( dc->enabled )
1328 while (dc->syncpt[i].min < val) {
1329 dc->syncpt[i].min++;
1330 nvhost_syncpt_cpu_incr(
1331 &nvhost_get_host(dc->ndev)->syncpt,
1332 dc->syncpt[i].id);
1333 }
1334 mutex_unlock(&dc->lock);
1335}
1336
1337static bool tegra_dc_windows_are_clean(struct tegra_dc_win *windows[],
1338 int n)
1339{
1340 int i;
1341
1342 for (i = 0; i < n; i++) {
1343 if (windows[i]->dirty)
1344 return false;
1345 }
1346
1347 return true;
1348}
1349
1350/* does not support syncing windows on multiple dcs in one call */
1351int tegra_dc_sync_windows(struct tegra_dc_win *windows[], int n)
1352{
1353 if (n < 1 || n > DC_N_WINDOWS)
1354 return -EINVAL;
1355
1356 if (!windows[0]->dc->enabled)
1357 return -EFAULT;
1358
1359#ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
1360 /* Don't want to timeout on simulator */
1361 return wait_event_interruptible(windows[0]->dc->wq,
1362 tegra_dc_windows_are_clean(windows, n));
1363#else
1364 return wait_event_interruptible_timeout(windows[0]->dc->wq,
1365 tegra_dc_windows_are_clean(windows, n),
1366 HZ);
1367#endif
1368}
1369EXPORT_SYMBOL(tegra_dc_sync_windows);
1370
1371static unsigned long tegra_dc_clk_get_rate(struct tegra_dc *dc)
1372{
1373#ifdef CONFIG_TEGRA_SILICON_PLATFORM
1374 return clk_get_rate(dc->clk);
1375#else
1376 return 27000000;
1377#endif
1378}
1379
1380static unsigned long tegra_dc_pclk_round_rate(struct tegra_dc *dc, int pclk)
1381{
1382 unsigned long rate;
1383 unsigned long div;
1384
1385 rate = tegra_dc_clk_get_rate(dc);
1386
1387 div = DIV_ROUND_CLOSEST(rate * 2, pclk);
1388
1389 if (div < 2)
1390 return 0;
1391
1392 return rate * 2 / div;
1393}
1394
1395static unsigned long tegra_dc_pclk_predict_rate(struct clk *parent, int pclk)
1396{
1397 unsigned long rate;
1398 unsigned long div;
1399
1400 rate = clk_get_rate(parent);
1401
1402 div = DIV_ROUND_CLOSEST(rate * 2, pclk);
1403
1404 if (div < 2)
1405 return 0;
1406
1407 return rate * 2 / div;
1408}
1409
1410void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk)
1411{
1412 int pclk;
1413
1414 if (dc->out->type == TEGRA_DC_OUT_RGB) {
1415 unsigned long rate;
1416 struct clk *parent_clk =
1417 clk_get_sys(NULL, dc->out->parent_clk ? : "pll_p");
1418
1419 if (dc->out->parent_clk_backup &&
1420 (parent_clk == clk_get_sys(NULL, "pll_p"))) {
1421 rate = tegra_dc_pclk_predict_rate(
1422 parent_clk, dc->mode.pclk);
1423 /* use pll_d as last resort */
1424 if (rate < (dc->mode.pclk / 100 * 99) ||
1425 rate > (dc->mode.pclk / 100 * 109))
1426 parent_clk = clk_get_sys(
1427 NULL, dc->out->parent_clk_backup);
1428 }
1429
1430 if (clk_get_parent(clk) != parent_clk)
1431 clk_set_parent(clk, parent_clk);
1432
1433 if (parent_clk != clk_get_sys(NULL, "pll_p")) {
1434 struct clk *base_clk = clk_get_parent(parent_clk);
1435
1436 /* Assuming either pll_d or pll_d2 is used */
1437 rate = dc->mode.pclk * 2;
1438
1439 if (rate != clk_get_rate(base_clk))
1440 clk_set_rate(base_clk, rate);
1441 }
1442 }
1443
1444 if (dc->out->type == TEGRA_DC_OUT_HDMI) {
1445 unsigned long rate;
1446 struct clk *parent_clk =
1447 clk_get_sys(NULL, dc->out->parent_clk ? : "pll_d_out0");
1448 struct clk *base_clk = clk_get_parent(parent_clk);
1449
1450 /*
1451 * Providing dynamic frequency rate setting for T20/T30 HDMI.
1452 * The required rate needs to be setup at 4x multiplier,
1453 * as out0 is 1/2 of the actual PLL output.
1454 */
1455
1456 rate = dc->mode.pclk * 4;
1457 if (rate != clk_get_rate(base_clk))
1458 clk_set_rate(base_clk, rate);
1459
1460 if (clk_get_parent(clk) != parent_clk)
1461 clk_set_parent(clk, parent_clk);
1462 }
1463
1464 if (dc->out->type == TEGRA_DC_OUT_DSI) {
1465 unsigned long rate;
1466 struct clk *parent_clk;
1467 struct clk *base_clk;
1468
1469 if (clk == dc->clk) {
1470 parent_clk = clk_get_sys(NULL,
1471 dc->out->parent_clk ? : "pll_d_out0");
1472 base_clk = clk_get_parent(parent_clk);
1473 tegra_clk_cfg_ex(base_clk,
1474 TEGRA_CLK_PLLD_DSI_OUT_ENB, 1);
1475 } else {
1476 if (dc->pdata->default_out->dsi->dsi_instance) {
1477 parent_clk = clk_get_sys(NULL,
1478 dc->out->parent_clk ? : "pll_d2_out0");
1479 base_clk = clk_get_parent(parent_clk);
1480 tegra_clk_cfg_ex(base_clk,
1481 TEGRA_CLK_PLLD_CSI_OUT_ENB, 1);
1482 } else {
1483 parent_clk = clk_get_sys(NULL,
1484 dc->out->parent_clk ? : "pll_d_out0");
1485 base_clk = clk_get_parent(parent_clk);
1486 tegra_clk_cfg_ex(base_clk,
1487 TEGRA_CLK_PLLD_DSI_OUT_ENB, 1);
1488 }
1489 }
1490
1491 rate = dc->mode.pclk * dc->shift_clk_div * 2;
1492 if (rate != clk_get_rate(base_clk))
1493 clk_set_rate(base_clk, rate);
1494
1495 if (clk_get_parent(clk) != parent_clk)
1496 clk_set_parent(clk, parent_clk);
1497 }
1498
1499 pclk = tegra_dc_pclk_round_rate(dc, dc->mode.pclk);
1500 tegra_dvfs_set_rate(clk, pclk);
1501}
1502
1503/* return non-zero if constraint is violated */
1504static int calc_h_ref_to_sync(const struct tegra_dc_mode *mode, int *href)
1505{
1506 long a, b;
1507
1508 /* Constraint 5: H_REF_TO_SYNC >= 0 */
1509 a = 0;
1510
1511 /* Constraint 6: H_FRONT_PORT >= (H_REF_TO_SYNC + 1) */
1512 b = mode->h_front_porch - 1;
1513
1514 /* Constraint 1: H_REF_TO_SYNC + H_SYNC_WIDTH + H_BACK_PORCH > 11 */
1515 if (a + mode->h_sync_width + mode->h_back_porch <= 11)
1516 a = 1 + 11 - mode->h_sync_width - mode->h_back_porch;
1517 /* check Constraint 1 and 6 */
1518 if (a > b)
1519 return 1;
1520
1521 /* Constraint 4: H_SYNC_WIDTH >= 1 */
1522 if (mode->h_sync_width < 1)
1523 return 4;
1524
1525 /* Constraint 7: H_DISP_ACTIVE >= 16 */
1526 if (mode->h_active < 16)
1527 return 7;
1528
1529 if (href) {
1530 if (b > a && a % 2)
1531 *href = a + 1; /* use smallest even value */
1532 else
1533 *href = a; /* even or only possible value */
1534 }
1535
1536 return 0;
1537}
1538
1539static int calc_v_ref_to_sync(const struct tegra_dc_mode *mode, int *vref)
1540{
1541 long a;
1542 a = 1; /* Constraint 5: V_REF_TO_SYNC >= 1 */
1543
1544 /* Constraint 2: V_REF_TO_SYNC + V_SYNC_WIDTH + V_BACK_PORCH > 1 */
1545 if (a + mode->v_sync_width + mode->v_back_porch <= 1)
1546 a = 1 + 1 - mode->v_sync_width - mode->v_back_porch;
1547
1548 /* Constraint 6 */
1549 if (mode->v_front_porch < a + 1)
1550 a = mode->v_front_porch - 1;
1551
1552 /* Constraint 4: V_SYNC_WIDTH >= 1 */
1553 if (mode->v_sync_width < 1)
1554 return 4;
1555
1556 /* Constraint 7: V_DISP_ACTIVE >= 16 */
1557 if (mode->v_active < 16)
1558 return 7;
1559
1560 if (vref)
1561 *vref = a;
1562 return 0;
1563}
1564
1565static int calc_ref_to_sync(struct tegra_dc_mode *mode)
1566{
1567 int ret;
1568 ret = calc_h_ref_to_sync(mode, &mode->h_ref_to_sync);
1569 if (ret)
1570 return ret;
1571 ret = calc_v_ref_to_sync(mode, &mode->v_ref_to_sync);
1572 if (ret)
1573 return ret;
1574
1575 return 0;
1576}
1577
1578static bool check_ref_to_sync(struct tegra_dc_mode *mode)
1579{
1580 /* Constraint 1: H_REF_TO_SYNC + H_SYNC_WIDTH + H_BACK_PORCH > 11. */
1581 if (mode->h_ref_to_sync + mode->h_sync_width + mode->h_back_porch <= 11)
1582 return false;
1583
1584 /* Constraint 2: V_REF_TO_SYNC + V_SYNC_WIDTH + V_BACK_PORCH > 1. */
1585 if (mode->v_ref_to_sync + mode->v_sync_width + mode->v_back_porch <= 1)
1586 return false;
1587
1588 /* Constraint 3: V_FRONT_PORCH + V_SYNC_WIDTH + V_BACK_PORCH > 1
1589 * (vertical blank). */
1590 if (mode->v_front_porch + mode->v_sync_width + mode->v_back_porch <= 1)
1591 return false;
1592
1593 /* Constraint 4: V_SYNC_WIDTH >= 1; H_SYNC_WIDTH >= 1. */
1594 if (mode->v_sync_width < 1 || mode->h_sync_width < 1)
1595 return false;
1596
1597 /* Constraint 5: V_REF_TO_SYNC >= 1; H_REF_TO_SYNC >= 0. */
1598 if (mode->v_ref_to_sync < 1 || mode->h_ref_to_sync < 0)
1599 return false;
1600
1601 /* Constraint 6: V_FRONT_PORT >= (V_REF_TO_SYNC + 1);
1602 * H_FRONT_PORT >= (H_REF_TO_SYNC + 1). */
1603 if (mode->v_front_porch < mode->v_ref_to_sync + 1 ||
1604 mode->h_front_porch < mode->h_ref_to_sync + 1)
1605 return false;
1606
1607 /* Constraint 7: H_DISP_ACTIVE >= 16; V_DISP_ACTIVE >= 16. */
1608 if (mode->h_active < 16 || mode->v_active < 16)
1609 return false;
1610
1611 return true;
1612}
1613
1614#ifdef DEBUG
1615/* return in 1000ths of a Hertz */
1616static int calc_refresh(const struct tegra_dc_mode *m)
1617{
1618 long h_total, v_total, refresh;
1619 h_total = m->h_active + m->h_front_porch + m->h_back_porch +
1620 m->h_sync_width;
1621 v_total = m->v_active + m->v_front_porch + m->v_back_porch +
1622 m->v_sync_width;
1623 refresh = m->pclk / h_total;
1624 refresh *= 1000;
1625 refresh /= v_total;
1626 return refresh;
1627}
1628
1629static void print_mode(struct tegra_dc *dc,
1630 const struct tegra_dc_mode *mode, const char *note)
1631{
1632 if (mode) {
1633 int refresh = calc_refresh(dc, mode);
1634 dev_info(&dc->ndev->dev, "%s():MODE:%dx%d@%d.%03uHz pclk=%d\n",
1635 note ? note : "",
1636 mode->h_active, mode->v_active,
1637 refresh / 1000, refresh % 1000,
1638 mode->pclk);
1639 }
1640}
1641#else /* !DEBUG */
1642static inline void print_mode(struct tegra_dc *dc,
1643 const struct tegra_dc_mode *mode, const char *note) { }
1644#endif /* DEBUG */
1645
1646static inline void enable_dc_irq(unsigned int irq)
1647{
1648#ifndef CONFIG_TEGRA_FPGA_PLATFORM
1649 enable_irq(irq);
1650#else
1651 /* Always disable DC interrupts on FPGA. */
1652 disable_irq(irq);
1653#endif
1654}
1655
1656static inline void disable_dc_irq(unsigned int irq)
1657{
1658 disable_irq(irq);
1659}
1660
1661static int tegra_dc_program_mode(struct tegra_dc *dc, struct tegra_dc_mode *mode)
1662{
1663 unsigned long val;
1664 unsigned long rate;
1665 unsigned long div;
1666 unsigned long pclk;
1667
1668 print_mode(dc, mode, __func__);
1669
1670 /* use default EMC rate when switching modes */
1671 dc->new_emc_clk_rate = tegra_dc_get_default_emc_clk_rate(dc);
1672 tegra_dc_program_bandwidth(dc);
1673
1674 tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS);
1675 tegra_dc_writel(dc, mode->h_ref_to_sync | (mode->v_ref_to_sync << 16),
1676 DC_DISP_REF_TO_SYNC);
1677 tegra_dc_writel(dc, mode->h_sync_width | (mode->v_sync_width << 16),
1678 DC_DISP_SYNC_WIDTH);
1679 tegra_dc_writel(dc, mode->h_back_porch | (mode->v_back_porch << 16),
1680 DC_DISP_BACK_PORCH);
1681 tegra_dc_writel(dc, mode->h_active | (mode->v_active << 16),
1682 DC_DISP_DISP_ACTIVE);
1683 tegra_dc_writel(dc, mode->h_front_porch | (mode->v_front_porch << 16),
1684 DC_DISP_FRONT_PORCH);
1685
1686 tegra_dc_writel(dc, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL,
1687 DC_DISP_DATA_ENABLE_OPTIONS);
1688
1689 /* TODO: MIPI/CRT/HDMI clock cals */
1690
1691 val = DISP_DATA_FORMAT_DF1P1C;
1692
1693 if (dc->out->align == TEGRA_DC_ALIGN_MSB)
1694 val |= DISP_DATA_ALIGNMENT_MSB;
1695 else
1696 val |= DISP_DATA_ALIGNMENT_LSB;
1697
1698 if (dc->out->order == TEGRA_DC_ORDER_RED_BLUE)
1699 val |= DISP_DATA_ORDER_RED_BLUE;
1700 else
1701 val |= DISP_DATA_ORDER_BLUE_RED;
1702
1703 tegra_dc_writel(dc, val, DC_DISP_DISP_INTERFACE_CONTROL);
1704
1705 rate = tegra_dc_clk_get_rate(dc);
1706
1707 pclk = tegra_dc_pclk_round_rate(dc, mode->pclk);
1708 if (pclk < (mode->pclk / 100 * 99) ||
1709 pclk > (mode->pclk / 100 * 109)) {
1710 dev_err(&dc->ndev->dev,
1711 "can't divide %ld clock to %d -1/+9%% %ld %d %d\n",
1712 rate, mode->pclk,
1713 pclk, (mode->pclk / 100 * 99),
1714 (mode->pclk / 100 * 109));
1715 return -EINVAL;
1716 }
1717
1718 div = (rate * 2 / pclk) - 2;
1719
1720 tegra_dc_writel(dc, 0x00010001,
1721 DC_DISP_SHIFT_CLOCK_OPTIONS);
1722 tegra_dc_writel(dc, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(div),
1723 DC_DISP_DISP_CLOCK_CONTROL);
1724
1725#ifdef CONFIG_SWITCH
1726 switch_set_state(&dc->modeset_switch,
1727 (mode->h_active << 16) | mode->v_active);
1728#endif
1729
1730 tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
1731 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
1732
1733 return 0;
1734}
1735
1736
1737int tegra_dc_set_mode(struct tegra_dc *dc, const struct tegra_dc_mode *mode)
1738{
1739 memcpy(&dc->mode, mode, sizeof(dc->mode));
1740
1741 print_mode(dc, mode, __func__);
1742
1743 return 0;
1744}
1745EXPORT_SYMBOL(tegra_dc_set_mode);
1746
1747int tegra_dc_set_fb_mode(struct tegra_dc *dc,
1748 const struct fb_videomode *fbmode, bool stereo_mode)
1749{
1750 struct tegra_dc_mode mode;
1751
1752 if (!fbmode->pixclock)
1753 return -EINVAL;
1754
1755 mode.pclk = PICOS2KHZ(fbmode->pixclock) * 1000;
1756 mode.h_sync_width = fbmode->hsync_len;
1757 mode.v_sync_width = fbmode->vsync_len;
1758 mode.h_back_porch = fbmode->left_margin;
1759 mode.v_back_porch = fbmode->upper_margin;
1760 mode.h_active = fbmode->xres;
1761 mode.v_active = fbmode->yres;
1762 mode.h_front_porch = fbmode->right_margin;
1763 mode.v_front_porch = fbmode->lower_margin;
1764 mode.stereo_mode = stereo_mode;
1765 if (dc->out->type == TEGRA_DC_OUT_HDMI) {
1766 /* HDMI controller requires h_ref=1, v_ref=1 */
1767 mode.h_ref_to_sync = 1;
1768 mode.v_ref_to_sync = 1;
1769 } else {
1770 calc_ref_to_sync(&mode);
1771 }
1772 if (!check_ref_to_sync(&mode)) {
1773 dev_err(&dc->ndev->dev,
1774 "Display timing doesn't meet restrictions.\n");
1775 return -EINVAL;
1776 }
1777 dev_info(&dc->ndev->dev, "Using mode %dx%d pclk=%d href=%d vref=%d\n",
1778 mode.h_active, mode.v_active, mode.pclk,
1779 mode.h_ref_to_sync, mode.v_ref_to_sync
1780 );
1781
1782#ifndef CONFIG_TEGRA_HDMI_74MHZ_LIMIT
1783 /* Double the pixel clock and update v_active only for frame packed mode */
1784 if (mode.stereo_mode) {
1785 mode.pclk *= 2;
1786 /* total v_active = yres*2 + activespace */
1787 mode.v_active = fbmode->yres*2 +
1788 fbmode->vsync_len +
1789 fbmode->upper_margin +
1790 fbmode->lower_margin;
1791 }
1792#endif
1793
1794 mode.flags = 0;
1795
1796 if (!(fbmode->sync & FB_SYNC_HOR_HIGH_ACT))
1797 mode.flags |= TEGRA_DC_MODE_FLAG_NEG_H_SYNC;
1798
1799 if (!(fbmode->sync & FB_SYNC_VERT_HIGH_ACT))
1800 mode.flags |= TEGRA_DC_MODE_FLAG_NEG_V_SYNC;
1801
1802 return tegra_dc_set_mode(dc, &mode);
1803}
1804EXPORT_SYMBOL(tegra_dc_set_fb_mode);
1805
1806void
1807tegra_dc_config_pwm(struct tegra_dc *dc, struct tegra_dc_pwm_params *cfg)
1808{
1809 unsigned int ctrl;
1810 unsigned long out_sel;
1811 unsigned long cmd_state;
1812
1813 mutex_lock(&dc->lock);
1814 if (!dc->enabled) {
1815 mutex_unlock(&dc->lock);
1816 return;
1817 }
1818
1819 ctrl = ((cfg->period << PM_PERIOD_SHIFT) |
1820 (cfg->clk_div << PM_CLK_DIVIDER_SHIFT) |
1821 cfg->clk_select);
1822
1823 /* The new value should be effected immediately */
1824 cmd_state = tegra_dc_readl(dc, DC_CMD_STATE_ACCESS);
1825 tegra_dc_writel(dc, (cmd_state | (1 << 2)), DC_CMD_STATE_ACCESS);
1826
1827 if (cfg->switch_to_sfio && cfg->gpio_conf_to_sfio)
1828 cfg->switch_to_sfio(cfg->gpio_conf_to_sfio);
1829 else
1830 dev_err(&dc->ndev->dev, "Error: Need gpio_conf_to_sfio\n");
1831
1832 switch (cfg->which_pwm) {
1833 case TEGRA_PWM_PM0:
1834 /* Select the LM0 on PM0 */
1835 out_sel = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_SELECT5);
1836 out_sel &= ~(7 << 0);
1837 out_sel |= (3 << 0);
1838 tegra_dc_writel(dc, out_sel, DC_COM_PIN_OUTPUT_SELECT5);
1839 tegra_dc_writel(dc, ctrl, DC_COM_PM0_CONTROL);
1840 tegra_dc_writel(dc, cfg->duty_cycle, DC_COM_PM0_DUTY_CYCLE);
1841 break;
1842 case TEGRA_PWM_PM1:
1843 /* Select the LM1 on PM1 */
1844 out_sel = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_SELECT5);
1845 out_sel &= ~(7 << 4);
1846 out_sel |= (3 << 4);
1847 tegra_dc_writel(dc, out_sel, DC_COM_PIN_OUTPUT_SELECT5);
1848 tegra_dc_writel(dc, ctrl, DC_COM_PM1_CONTROL);
1849 tegra_dc_writel(dc, cfg->duty_cycle, DC_COM_PM1_DUTY_CYCLE);
1850 break;
1851 default:
1852 dev_err(&dc->ndev->dev, "Error: Need which_pwm\n");
1853 break;
1854 }
1855 tegra_dc_writel(dc, cmd_state, DC_CMD_STATE_ACCESS);
1856 mutex_unlock(&dc->lock);
1857}
1858EXPORT_SYMBOL(tegra_dc_config_pwm);
1859
1860void tegra_dc_set_out_pin_polars(struct tegra_dc *dc,
1861 const struct tegra_dc_out_pin *pins,
1862 const unsigned int n_pins)
1863{
1864 unsigned int i;
1865
1866 int name;
1867 int pol;
1868
1869 u32 pol1, pol3;
1870
1871 u32 set1, unset1;
1872 u32 set3, unset3;
1873
1874 set1 = set3 = unset1 = unset3 = 0;
1875
1876 for (i = 0; i < n_pins; i++) {
1877 name = (pins + i)->name;
1878 pol = (pins + i)->pol;
1879
1880 /* set polarity by name */
1881 switch (name) {
1882 case TEGRA_DC_OUT_PIN_DATA_ENABLE:
1883 if (pol == TEGRA_DC_OUT_PIN_POL_LOW)
1884 set3 |= LSPI_OUTPUT_POLARITY_LOW;
1885 else
1886 unset3 |= LSPI_OUTPUT_POLARITY_LOW;
1887 break;
1888 case TEGRA_DC_OUT_PIN_H_SYNC:
1889 if (pol == TEGRA_DC_OUT_PIN_POL_LOW)
1890 set1 |= LHS_OUTPUT_POLARITY_LOW;
1891 else
1892 unset1 |= LHS_OUTPUT_POLARITY_LOW;
1893 break;
1894 case TEGRA_DC_OUT_PIN_V_SYNC:
1895 if (pol == TEGRA_DC_OUT_PIN_POL_LOW)
1896 set1 |= LVS_OUTPUT_POLARITY_LOW;
1897 else
1898 unset1 |= LVS_OUTPUT_POLARITY_LOW;
1899 break;
1900 case TEGRA_DC_OUT_PIN_PIXEL_CLOCK:
1901 if (pol == TEGRA_DC_OUT_PIN_POL_LOW)
1902 set1 |= LSC0_OUTPUT_POLARITY_LOW;
1903 else
1904 unset1 |= LSC0_OUTPUT_POLARITY_LOW;
1905 break;
1906 default:
1907 printk("Invalid argument in function %s\n",
1908 __FUNCTION__);
1909 break;
1910 }
1911 }
1912
1913 pol1 = DC_COM_PIN_OUTPUT_POLARITY1_INIT_VAL;
1914 pol3 = DC_COM_PIN_OUTPUT_POLARITY3_INIT_VAL;
1915
1916 pol1 |= set1;
1917 pol1 &= ~unset1;
1918
1919 pol3 |= set3;
1920 pol3 &= ~unset3;
1921
1922 tegra_dc_writel(dc, pol1, DC_COM_PIN_OUTPUT_POLARITY1);
1923 tegra_dc_writel(dc, pol3, DC_COM_PIN_OUTPUT_POLARITY3);
1924}
1925
1926static void tegra_dc_set_out(struct tegra_dc *dc, struct tegra_dc_out *out)
1927{
1928 dc->out = out;
1929
1930 if (out->n_modes > 0)
1931 tegra_dc_set_mode(dc, &dc->out->modes[0]);
1932
1933 switch (out->type) {
1934 case TEGRA_DC_OUT_RGB:
1935 dc->out_ops = &tegra_dc_rgb_ops;
1936 break;
1937
1938 case TEGRA_DC_OUT_HDMI:
1939 dc->out_ops = &tegra_dc_hdmi_ops;
1940 break;
1941
1942 case TEGRA_DC_OUT_DSI:
1943 dc->out_ops = &tegra_dc_dsi_ops;
1944 break;
1945
1946 default:
1947 dc->out_ops = NULL;
1948 break;
1949 }
1950
1951 if (dc->out_ops && dc->out_ops->init)
1952 dc->out_ops->init(dc);
1953
1954}
1955
1956unsigned tegra_dc_get_out_height(const struct tegra_dc *dc)
1957{
1958 if (dc->out)
1959 return dc->out->height;
1960 else
1961 return 0;
1962}
1963EXPORT_SYMBOL(tegra_dc_get_out_height);
1964
1965unsigned tegra_dc_get_out_width(const struct tegra_dc *dc)
1966{
1967 if (dc->out)
1968 return dc->out->width;
1969 else
1970 return 0;
1971}
1972EXPORT_SYMBOL(tegra_dc_get_out_width);
1973
1974unsigned tegra_dc_get_out_max_pixclock(const struct tegra_dc *dc)
1975{
1976 if (dc->out && dc->out->max_pixclock)
1977 return dc->out->max_pixclock;
1978 else
1979 return 0;
1980}
1981EXPORT_SYMBOL(tegra_dc_get_out_max_pixclock);
1982
1983void tegra_dc_enable_crc(struct tegra_dc *dc)
1984{
1985 u32 val;
1986 tegra_dc_io_start(dc);
1987
1988 val = CRC_ALWAYS_ENABLE | CRC_INPUT_DATA_ACTIVE_DATA |
1989 CRC_ENABLE_ENABLE;
1990 tegra_dc_writel(dc, val, DC_COM_CRC_CONTROL);
1991 tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
1992 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
1993}
1994
1995void tegra_dc_disable_crc(struct tegra_dc *dc)
1996{
1997 tegra_dc_writel(dc, 0x0, DC_COM_CRC_CONTROL);
1998 tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
1999 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
2000
2001 tegra_dc_io_end(dc);
2002}
2003
2004u32 tegra_dc_read_checksum_latched(struct tegra_dc *dc)
2005{
2006 int crc = 0;
2007
2008 if(!dc) {
2009 dev_err(&dc->ndev->dev, "Failed to get dc.\n");
2010 goto crc_error;
2011 }
2012
2013 /* TODO: Replace mdelay with code to sync VBlANK, since
2014 * DC_COM_CRC_CHECKSUM_LATCHED is available after VBLANK */
2015 mdelay(TEGRA_CRC_LATCHED_DELAY);
2016
2017 crc = tegra_dc_readl(dc, DC_COM_CRC_CHECKSUM_LATCHED);
2018crc_error:
2019 return crc;
2020}
2021
2022static void tegra_dc_vblank(struct work_struct *work)
2023{
2024 struct tegra_dc *dc = container_of(work, struct tegra_dc, vblank_work);
2025 bool nvsd_updated = false;
2026
2027 mutex_lock(&dc->lock);
2028
2029 /* Update the SD brightness */
2030 if (dc->enabled && dc->out->sd_settings)
2031 nvsd_updated = nvsd_update_brightness(dc);
2032
2033 mutex_unlock(&dc->lock);
2034
2035 /* Do the actual brightness update outside of the mutex */
2036 if (nvsd_updated && dc->out->sd_settings &&
2037 dc->out->sd_settings->bl_device) {
2038
2039 struct platform_device *pdev = dc->out->sd_settings->bl_device;
2040 struct backlight_device *bl = platform_get_drvdata(pdev);
2041 if (bl)
2042 backlight_update_status(bl);
2043 }
2044}
2045
2046/* Must acquire dc lock and dc one-shot lock before invoking this function.
2047 * Acquire dc one-shot lock first and then dc lock. */
2048void tegra_dc_host_trigger(struct tegra_dc *dc)
2049{
2050 /* We release the lock here to prevent deadlock between
2051 * cancel_delayed_work_sync and one-shot work. */
2052 mutex_unlock(&dc->lock);
2053
2054 cancel_delayed_work_sync(&dc->one_shot_work);
2055 mutex_lock(&dc->lock);
2056
2057 schedule_delayed_work(&dc->one_shot_work,
2058 msecs_to_jiffies(dc->one_shot_delay_ms));
2059 tegra_dc_program_bandwidth(dc);
2060 tegra_dc_writel(dc, NC_HOST_TRIG, DC_CMD_STATE_CONTROL);
2061}
2062
2063static void tegra_dc_one_shot_worker(struct work_struct *work)
2064{
2065 struct tegra_dc *dc = container_of(
2066 to_delayed_work(work), struct tegra_dc, one_shot_work);
2067 mutex_lock(&dc->lock);
2068 /* memory client has gone idle */
2069 tegra_dc_clear_bandwidth(dc);
2070 mutex_unlock(&dc->lock);
2071}
2072
2073/* return an arbitrarily large number if count overflow occurs.
2074 * make it a nice base-10 number to show up in stats output */
2075static u64 tegra_dc_underflow_count(struct tegra_dc *dc, unsigned reg)
2076{
2077 unsigned count = tegra_dc_readl(dc, reg);
2078 tegra_dc_writel(dc, 0, reg);
2079 return ((count & 0x80000000) == 0) ? count : 10000000000ll;
2080}
2081
2082static void tegra_dc_underflow_handler(struct tegra_dc *dc)
2083{
2084 u32 val;
2085 int i;
2086
2087 dc->stats.underflows++;
2088 if (dc->underflow_mask & WIN_A_UF_INT)
2089 dc->stats.underflows_a += tegra_dc_underflow_count(dc,
2090 DC_WINBUF_AD_UFLOW_STATUS);
2091 if (dc->underflow_mask & WIN_B_UF_INT)
2092 dc->stats.underflows_b += tegra_dc_underflow_count(dc,
2093 DC_WINBUF_BD_UFLOW_STATUS);
2094 if (dc->underflow_mask & WIN_C_UF_INT)
2095 dc->stats.underflows_c += tegra_dc_underflow_count(dc,
2096 DC_WINBUF_CD_UFLOW_STATUS);
2097
2098 /* Check for any underflow reset conditions */
2099 for (i = 0; i < DC_N_WINDOWS; i++) {
2100 if (dc->underflow_mask & (WIN_A_UF_INT << i)) {
2101 dc->windows[i].underflows++;
2102
2103#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2104 if (dc->windows[i].underflows > 4)
2105 schedule_work(&dc->reset_work);
2106#endif
2107 } else {
2108 dc->windows[i].underflows = 0;
2109 }
2110 }
2111
2112 /* Clear the underflow mask now that we've checked it. */
2113 tegra_dc_writel(dc, dc->underflow_mask, DC_CMD_INT_STATUS);
2114 dc->underflow_mask = 0;
2115 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
2116 tegra_dc_writel(dc, val | ALL_UF_INT, DC_CMD_INT_MASK);
2117}
2118
2119#ifndef CONFIG_TEGRA_FPGA_PLATFORM
2120static bool tegra_dc_windows_are_dirty(struct tegra_dc *dc)
2121{
2122#ifndef CONFIG_TEGRA_SIMULATION_PLATFORM
2123 u32 val;
2124
2125 val = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
2126 if (val & (WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE))
2127 return true;
2128#endif
2129 return false;
2130}
2131
2132static void tegra_dc_trigger_windows(struct tegra_dc *dc)
2133{
2134 u32 val, i;
2135 u32 completed = 0;
2136 u32 dirty = 0;
2137
2138 val = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
2139 for (i = 0; i < DC_N_WINDOWS; i++) {
2140#ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
2141 /* FIXME: this is not needed when the simulator
2142 clears WIN_x_UPDATE bits as in HW */
2143 dc->windows[i].dirty = 0;
2144 completed = 1;
2145#else
2146 if (!(val & (WIN_A_UPDATE << i))) {
2147 dc->windows[i].dirty = 0;
2148 completed = 1;
2149 } else {
2150 dirty = 1;
2151 }
2152#endif
2153 }
2154
2155 if (!dirty) {
2156 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
2157 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
2158 val &= ~V_BLANK_INT;
2159 else
2160 val &= ~FRAME_END_INT;
2161 tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
2162 }
2163
2164 if (completed) {
2165 if (!dirty) {
2166 /* With the last completed window, go ahead
2167 and enable the vblank interrupt for nvsd. */
2168 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
2169 val |= V_BLANK_INT;
2170 tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
2171 }
2172
2173 wake_up(&dc->wq);
2174 }
2175}
2176
2177static void tegra_dc_one_shot_irq(struct tegra_dc *dc, unsigned long status)
2178{
2179 if (status & V_BLANK_INT) {
2180 /* Sync up windows. */
2181 tegra_dc_trigger_windows(dc);
2182
2183 /* Schedule any additional bottom-half vblank actvities. */
2184 schedule_work(&dc->vblank_work);
2185 }
2186
2187 if (status & FRAME_END_INT) {
2188 /* Mark the frame_end as complete. */
2189 if (!completion_done(&dc->frame_end_complete))
2190 complete(&dc->frame_end_complete);
2191 }
2192}
2193
2194static void tegra_dc_continuous_irq(struct tegra_dc *dc, unsigned long status)
2195{
2196 if (status & V_BLANK_INT) {
2197 /* Schedule any additional bottom-half vblank actvities. */
2198 schedule_work(&dc->vblank_work);
2199
2200 /* All windows updated. Mask subsequent V_BLANK interrupts */
2201 if (!tegra_dc_windows_are_dirty(dc)) {
2202 u32 val;
2203
2204 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
2205 val &= ~V_BLANK_INT;
2206 tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
2207 }
2208 }
2209
2210 if (status & FRAME_END_INT) {
2211 /* Mark the frame_end as complete. */
2212 if (!completion_done(&dc->frame_end_complete))
2213 complete(&dc->frame_end_complete);
2214
2215 tegra_dc_trigger_windows(dc);
2216 }
2217}
2218#endif
2219
2220static irqreturn_t tegra_dc_irq(int irq, void *ptr)
2221{
2222#ifndef CONFIG_TEGRA_FPGA_PLATFORM
2223 struct tegra_dc *dc = ptr;
2224 unsigned long status;
2225 unsigned long underflow_mask;
2226 u32 val;
2227
2228 if (!nvhost_module_powered(nvhost_get_host(dc->ndev)->dev)) {
2229 WARN(1, "IRQ when DC not powered!\n");
2230 tegra_dc_io_start(dc);
2231 status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
2232 tegra_dc_writel(dc, status, DC_CMD_INT_STATUS);
2233 tegra_dc_io_end(dc);
2234 return IRQ_HANDLED;
2235 }
2236
2237 /* clear all status flags except underflow, save those for the worker */
2238 status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
2239 tegra_dc_writel(dc, status & ~ALL_UF_INT, DC_CMD_INT_STATUS);
2240 val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
2241 tegra_dc_writel(dc, val & ~ALL_UF_INT, DC_CMD_INT_MASK);
2242
2243 /*
2244 * Overlays can get thier internal state corrupted during and underflow
2245 * condition. The only way to fix this state is to reset the DC.
2246 * if we get 4 consecutive frames with underflows, assume we're
2247 * hosed and reset.
2248 */
2249 underflow_mask = status & ALL_UF_INT;
2250
2251 /* Check underflow */
2252 if (underflow_mask) {
2253 dc->underflow_mask |= underflow_mask;
2254 schedule_delayed_work(&dc->underflow_work,
2255 msecs_to_jiffies(1));
2256 }
2257
2258 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
2259 tegra_dc_one_shot_irq(dc, status);
2260 else
2261 tegra_dc_continuous_irq(dc, status);
2262
2263 return IRQ_HANDLED;
2264#else /* CONFIG_TEGRA_FPGA_PLATFORM */
2265 return IRQ_NONE;
2266#endif /* !CONFIG_TEGRA_FPGA_PLATFORM */
2267}
2268
2269static void tegra_dc_set_color_control(struct tegra_dc *dc)
2270{
2271 u32 color_control;
2272
2273 switch (dc->out->depth) {
2274 case 3:
2275 color_control = BASE_COLOR_SIZE111;
2276 break;
2277
2278 case 6:
2279 color_control = BASE_COLOR_SIZE222;
2280 break;
2281
2282 case 8:
2283 color_control = BASE_COLOR_SIZE332;
2284 break;
2285
2286 case 9:
2287 color_control = BASE_COLOR_SIZE333;
2288 break;
2289
2290 case 12:
2291 color_control = BASE_COLOR_SIZE444;
2292 break;
2293
2294 case 15:
2295 color_control = BASE_COLOR_SIZE555;
2296 break;
2297
2298 case 16:
2299 color_control = BASE_COLOR_SIZE565;
2300 break;
2301
2302 case 18:
2303 color_control = BASE_COLOR_SIZE666;
2304 break;
2305
2306 default:
2307 color_control = BASE_COLOR_SIZE888;
2308 break;
2309 }
2310
2311 switch (dc->out->dither) {
2312 case TEGRA_DC_DISABLE_DITHER:
2313 color_control |= DITHER_CONTROL_DISABLE;
2314 break;
2315 case TEGRA_DC_ORDERED_DITHER:
2316 color_control |= DITHER_CONTROL_ORDERED;
2317 break;
2318 case TEGRA_DC_ERRDIFF_DITHER:
2319 /* The line buffer for error-diffusion dither is limited
2320 * to 1280 pixels per line. This limits the maximum
2321 * horizontal active area size to 1280 pixels when error
2322 * diffusion is enabled.
2323 */
2324 BUG_ON(dc->mode.h_active > 1280);
2325 color_control |= DITHER_CONTROL_ERRDIFF;
2326 break;
2327 }
2328
2329 tegra_dc_writel(dc, color_control, DC_DISP_DISP_COLOR_CONTROL);
2330}
2331
2332static u32 get_syncpt(struct tegra_dc *dc, int idx)
2333{
2334 u32 syncpt_id;
2335
2336 switch (dc->ndev->id) {
2337 case 0:
2338 switch (idx) {
2339 case 0:
2340 syncpt_id = NVSYNCPT_DISP0_A;
2341 break;
2342 case 1:
2343 syncpt_id = NVSYNCPT_DISP0_B;
2344 break;
2345 case 2:
2346 syncpt_id = NVSYNCPT_DISP0_C;
2347 break;
2348 default:
2349 BUG();
2350 break;
2351 }
2352 break;
2353 case 1:
2354 switch (idx) {
2355 case 0:
2356 syncpt_id = NVSYNCPT_DISP1_A;
2357 break;
2358 case 1:
2359 syncpt_id = NVSYNCPT_DISP1_B;
2360 break;
2361 case 2:
2362 syncpt_id = NVSYNCPT_DISP1_C;
2363 break;
2364 default:
2365 BUG();
2366 break;
2367 }
2368 break;
2369 default:
2370 BUG();
2371 break;
2372 }
2373
2374 return syncpt_id;
2375}
2376
2377static int tegra_dc_init(struct tegra_dc *dc)
2378{
2379 int i;
2380
2381 tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
2382 if (dc->ndev->id == 0) {
2383 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0A,
2384 TEGRA_MC_PRIO_MED);
2385 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0B,
2386 TEGRA_MC_PRIO_MED);
2387 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0C,
2388 TEGRA_MC_PRIO_MED);
2389 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY1B,
2390 TEGRA_MC_PRIO_MED);
2391 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAYHC,
2392 TEGRA_MC_PRIO_HIGH);
2393 } else if (dc->ndev->id == 1) {
2394 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0AB,
2395 TEGRA_MC_PRIO_MED);
2396 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0BB,
2397 TEGRA_MC_PRIO_MED);
2398 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0CB,
2399 TEGRA_MC_PRIO_MED);
2400 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY1BB,
2401 TEGRA_MC_PRIO_MED);
2402 tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAYHCB,
2403 TEGRA_MC_PRIO_HIGH);
2404 }
2405 tegra_dc_writel(dc, 0x00000100 | dc->vblank_syncpt,
2406 DC_CMD_CONT_SYNCPT_VSYNC);
2407 tegra_dc_writel(dc, 0x00004700, DC_CMD_INT_TYPE);
2408 tegra_dc_writel(dc, 0x0001c700, DC_CMD_INT_POLARITY);
2409 tegra_dc_writel(dc, 0x00202020, DC_DISP_MEM_HIGH_PRIORITY);
2410 tegra_dc_writel(dc, 0x00010101, DC_DISP_MEM_HIGH_PRIORITY_TIMER);
2411
2412 /* enable interrupts for vblank, frame_end and underflows */
2413 tegra_dc_writel(dc, (FRAME_END_INT | V_BLANK_INT | ALL_UF_INT),
2414 DC_CMD_INT_ENABLE);
2415 tegra_dc_writel(dc, ALL_UF_INT, DC_CMD_INT_MASK);
2416
2417 tegra_dc_writel(dc, 0x00000000, DC_DISP_BORDER_COLOR);
2418
2419 tegra_dc_set_color_control(dc);
2420 for (i = 0; i < DC_N_WINDOWS; i++) {
2421 struct tegra_dc_win *win = &dc->windows[i];
2422 tegra_dc_writel(dc, WINDOW_A_SELECT << i,
2423 DC_CMD_DISPLAY_WINDOW_HEADER);
2424 tegra_dc_set_csc(dc, &win->csc);
2425 tegra_dc_set_lut(dc, win);
2426 tegra_dc_set_scaling_filter(dc);
2427 }
2428
2429
2430 for (i = 0; i < dc->n_windows; i++) {
2431 u32 syncpt = get_syncpt(dc, i);
2432
2433 dc->syncpt[i].id = syncpt;
2434
2435 dc->syncpt[i].min = dc->syncpt[i].max =
2436 nvhost_syncpt_read(&nvhost_get_host(dc->ndev)->syncpt,
2437 syncpt);
2438 }
2439
2440 print_mode(dc, &dc->mode, __func__);
2441
2442 if (dc->mode.pclk)
2443 if (tegra_dc_program_mode(dc, &dc->mode))
2444 return -EINVAL;
2445
2446 /* Initialize SD AFTER the modeset.
2447 nvsd_init handles the sd_settings = NULL case. */
2448 nvsd_init(dc, dc->out->sd_settings);
2449
2450 return 0;
2451}
2452
2453static bool _tegra_dc_controller_enable(struct tegra_dc *dc)
2454{
2455 int failed_init = 0;
2456
2457 if (dc->out->enable)
2458 dc->out->enable();
2459
2460 tegra_dc_setup_clk(dc, dc->clk);
2461 clk_enable(dc->clk);
2462
2463 /* do not accept interrupts during initialization */
2464 tegra_dc_writel(dc, 0, DC_CMD_INT_ENABLE);
2465 tegra_dc_writel(dc, 0, DC_CMD_INT_MASK);
2466
2467 enable_dc_irq(dc->irq);
2468
2469 failed_init = tegra_dc_init(dc);
2470 if (failed_init) {
2471 _tegra_dc_controller_disable(dc);
2472 return false;
2473 }
2474
2475 if (dc->out_ops && dc->out_ops->enable)
2476 dc->out_ops->enable(dc);
2477
2478 if (dc->out->postpoweron)
2479 dc->out->postpoweron();
2480
2481 /* force a full blending update */
2482 dc->blend.z[0] = -1;
2483
2484 tegra_dc_ext_enable(dc->ext);
2485
2486 return true;
2487}
2488
2489#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2490static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc)
2491{
2492 bool ret = true;
2493
2494 if (dc->out->enable)
2495 dc->out->enable();
2496
2497 tegra_dc_setup_clk(dc, dc->clk);
2498 clk_enable(dc->clk);
2499
2500 if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) {
2501 mutex_lock(&tegra_dcs[1]->lock);
2502 disable_irq(tegra_dcs[1]->irq);
2503 } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) {
2504 mutex_lock(&tegra_dcs[0]->lock);
2505 disable_irq(tegra_dcs[0]->irq);
2506 }
2507
2508 msleep(5);
2509 tegra_periph_reset_assert(dc->clk);
2510 msleep(2);
2511#ifdef CONFIG_TEGRA_SILICON_PLATFORM
2512 tegra_periph_reset_deassert(dc->clk);
2513 msleep(1);
2514#endif
2515
2516 if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) {
2517 enable_dc_irq(tegra_dcs[1]->irq);
2518 mutex_unlock(&tegra_dcs[1]->lock);
2519 } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) {
2520 enable_dc_irq(tegra_dcs[0]->irq);
2521 mutex_unlock(&tegra_dcs[0]->lock);
2522 }
2523
2524 enable_dc_irq(dc->irq);
2525
2526 if (tegra_dc_init(dc)) {
2527 dev_err(&dc->ndev->dev, "cannot initialize\n");
2528 ret = false;
2529 }
2530
2531 if (dc->out_ops && dc->out_ops->enable)
2532 dc->out_ops->enable(dc);
2533
2534 if (dc->out->postpoweron)
2535 dc->out->postpoweron();
2536
2537 /* force a full blending update */
2538 dc->blend.z[0] = -1;
2539
2540 tegra_dc_ext_enable(dc->ext);
2541
2542 if (!ret) {
2543 dev_err(&dc->ndev->dev, "initialization failed,disabling");
2544 _tegra_dc_controller_disable(dc);
2545 }
2546
2547 return ret;
2548}
2549#endif
2550
2551static bool _tegra_dc_enable(struct tegra_dc *dc)
2552{
2553 if (dc->mode.pclk == 0)
2554 return false;
2555
2556 if (!dc->out)
2557 return false;
2558
2559 tegra_dc_io_start(dc);
2560
2561 return _tegra_dc_controller_enable(dc);
2562}
2563
2564void tegra_dc_enable(struct tegra_dc *dc)
2565{
2566 mutex_lock(&dc->lock);
2567
2568 if (!dc->enabled)
2569 dc->enabled = _tegra_dc_enable(dc);
2570
2571 mutex_unlock(&dc->lock);
2572}
2573
2574static void _tegra_dc_controller_disable(struct tegra_dc *dc)
2575{
2576 unsigned i;
2577
2578 if (dc->out_ops && dc->out_ops->disable)
2579 dc->out_ops->disable(dc);
2580
2581 tegra_dc_writel(dc, 0, DC_CMD_INT_MASK);
2582 tegra_dc_writel(dc, 0, DC_CMD_INT_ENABLE);
2583 disable_irq(dc->irq);
2584
2585 tegra_dc_clear_bandwidth(dc);
2586 clk_disable(dc->clk);
2587 tegra_dvfs_set_rate(dc->clk, 0);
2588
2589 if (dc->out && dc->out->disable)
2590 dc->out->disable();
2591
2592 for (i = 0; i < dc->n_windows; i++) {
2593 struct tegra_dc_win *w = &dc->windows[i];
2594
2595 /* reset window bandwidth */
2596 w->bandwidth = 0;
2597 w->new_bandwidth = 0;
2598
2599 /* disable windows */
2600 w->flags &= ~TEGRA_WIN_FLAG_ENABLED;
2601
2602 /* flush any pending syncpt waits */
2603 while (dc->syncpt[i].min < dc->syncpt[i].max) {
2604 dc->syncpt[i].min++;
2605 nvhost_syncpt_cpu_incr(
2606 &nvhost_get_host(dc->ndev)->syncpt,
2607 dc->syncpt[i].id);
2608 }
2609 }
2610}
2611
2612void tegra_dc_stats_enable(struct tegra_dc *dc, bool enable)
2613{
2614#if 0 /* underflow interrupt is already enabled by dc reset worker */
2615 u32 val;
2616 if (dc->enabled) {
2617 val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
2618 if (enable)
2619 val |= (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT);
2620 else
2621 val &= ~(WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT);
2622 tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
2623 }
2624#endif
2625}
2626
2627bool tegra_dc_stats_get(struct tegra_dc *dc)
2628{
2629#if 0 /* right now it is always enabled */
2630 u32 val;
2631 bool res;
2632
2633 if (dc->enabled) {
2634 val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
2635 res = !!(val & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT));
2636 } else {
2637 res = false;
2638 }
2639
2640 return res;
2641#endif
2642 return true;
2643}
2644
2645/* make the screen blank by disabling all windows */
2646void tegra_dc_blank(struct tegra_dc *dc)
2647{
2648 struct tegra_dc_win *dcwins[DC_N_WINDOWS];
2649 unsigned i;
2650
2651 for (i = 0; i < DC_N_WINDOWS; i++) {
2652 dcwins[i] = tegra_dc_get_window(dc, i);
2653 dcwins[i]->flags &= ~TEGRA_WIN_FLAG_ENABLED;
2654 }
2655
2656 tegra_dc_update_windows(dcwins, DC_N_WINDOWS);
2657 tegra_dc_sync_windows(dcwins, DC_N_WINDOWS);
2658}
2659
2660static void _tegra_dc_disable(struct tegra_dc *dc)
2661{
2662 _tegra_dc_controller_disable(dc);
2663 tegra_dc_io_end(dc);
2664}
2665
2666void tegra_dc_disable(struct tegra_dc *dc)
2667{
2668 tegra_dc_ext_disable(dc->ext);
2669
2670 /* it's important that new underflow work isn't scheduled before the
2671 * lock is acquired. */
2672 cancel_delayed_work_sync(&dc->underflow_work);
2673 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) {
2674 mutex_lock(&dc->one_shot_lock);
2675 cancel_delayed_work_sync(&dc->one_shot_work);
2676 }
2677
2678 mutex_lock(&dc->lock);
2679
2680 if (dc->enabled) {
2681 dc->enabled = false;
2682
2683 if (!dc->suspended)
2684 _tegra_dc_disable(dc);
2685 }
2686
2687#ifdef CONFIG_SWITCH
2688 switch_set_state(&dc->modeset_switch, 0);
2689#endif
2690
2691 mutex_unlock(&dc->lock);
2692 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
2693 mutex_unlock(&dc->one_shot_lock);
2694}
2695
2696#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2697static void tegra_dc_reset_worker(struct work_struct *work)
2698{
2699 struct tegra_dc *dc =
2700 container_of(work, struct tegra_dc, reset_work);
2701
2702 unsigned long val = 0;
2703
2704 mutex_lock(&shared_lock);
2705
2706 dev_warn(&dc->ndev->dev, "overlay stuck in underflow state. resetting.\n");
2707
2708 tegra_dc_ext_disable(dc->ext);
2709
2710 mutex_lock(&dc->lock);
2711
2712 if (dc->enabled == false)
2713 goto unlock;
2714
2715 dc->enabled = false;
2716
2717 /*
2718 * off host read bus
2719 */
2720 val = tegra_dc_readl(dc, DC_CMD_CONT_SYNCPT_VSYNC);
2721 val &= ~(0x00000100);
2722 tegra_dc_writel(dc, val, DC_CMD_CONT_SYNCPT_VSYNC);
2723
2724 /*
2725 * set DC to STOP mode
2726 */
2727 tegra_dc_writel(dc, DISP_CTRL_MODE_STOP, DC_CMD_DISPLAY_COMMAND);
2728
2729 msleep(10);
2730
2731 _tegra_dc_controller_disable(dc);
2732
2733 /* _tegra_dc_controller_reset_enable deasserts reset */
2734 _tegra_dc_controller_reset_enable(dc);
2735
2736 dc->enabled = true;
2737unlock:
2738 mutex_unlock(&dc->lock);
2739 mutex_unlock(&shared_lock);
2740}
2741#endif
2742
2743static void tegra_dc_underflow_worker(struct work_struct *work)
2744{
2745 struct tegra_dc *dc = container_of(
2746 to_delayed_work(work), struct tegra_dc, underflow_work);
2747
2748 mutex_lock(&dc->lock);
2749 if (dc->enabled) {
2750 tegra_dc_underflow_handler(dc);
2751 }
2752 mutex_unlock(&dc->lock);
2753}
2754
2755#ifdef CONFIG_SWITCH
2756static ssize_t switch_modeset_print_mode(struct switch_dev *sdev, char *buf)
2757{
2758 struct tegra_dc *dc =
2759 container_of(sdev, struct tegra_dc, modeset_switch);
2760
2761 if (!sdev->state)
2762 return sprintf(buf, "offline\n");
2763
2764 return sprintf(buf, "%dx%d\n", dc->mode.h_active, dc->mode.v_active);
2765}
2766#endif
2767
2768static int tegra_dc_probe(struct nvhost_device *ndev)
2769{
2770 struct tegra_dc *dc;
2771 struct clk *clk;
2772 struct clk *emc_clk;
2773 struct resource *res;
2774 struct resource *base_res;
2775 struct resource *fb_mem = NULL;
2776 int ret = 0;
2777 void __iomem *base;
2778 int irq;
2779 int i;
2780
2781 if (!ndev->dev.platform_data) {
2782 dev_err(&ndev->dev, "no platform data\n");
2783 return -ENOENT;
2784 }
2785
2786 dc = kzalloc(sizeof(struct tegra_dc), GFP_KERNEL);
2787 if (!dc) {
2788 dev_err(&ndev->dev, "can't allocate memory for tegra_dc\n");
2789 return -ENOMEM;
2790 }
2791
2792 irq = nvhost_get_irq_byname(ndev, "irq");
2793 if (irq <= 0) {
2794 dev_err(&ndev->dev, "no irq\n");
2795 ret = -ENOENT;
2796 goto err_free;
2797 }
2798
2799 res = nvhost_get_resource_byname(ndev, IORESOURCE_MEM, "regs");
2800 if (!res) {
2801 dev_err(&ndev->dev, "no mem resource\n");
2802 ret = -ENOENT;
2803 goto err_free;
2804 }
2805
2806 base_res = request_mem_region(res->start, resource_size(res), ndev->name);
2807 if (!base_res) {
2808 dev_err(&ndev->dev, "request_mem_region failed\n");
2809 ret = -EBUSY;
2810 goto err_free;
2811 }
2812
2813 base = ioremap(res->start, resource_size(res));
2814 if (!base) {
2815 dev_err(&ndev->dev, "registers can't be mapped\n");
2816 ret = -EBUSY;
2817 goto err_release_resource_reg;
2818 }
2819
2820 fb_mem = nvhost_get_resource_byname(ndev, IORESOURCE_MEM, "fbmem");
2821
2822 clk = clk_get(&ndev->dev, NULL);
2823 if (IS_ERR_OR_NULL(clk)) {
2824 dev_err(&ndev->dev, "can't get clock\n");
2825 ret = -ENOENT;
2826 goto err_iounmap_reg;
2827 }
2828
2829 emc_clk = clk_get(&ndev->dev, "emc");
2830 if (IS_ERR_OR_NULL(emc_clk)) {
2831 dev_err(&ndev->dev, "can't get emc clock\n");
2832 ret = -ENOENT;
2833 goto err_put_clk;
2834 }
2835
2836 dc->clk = clk;
2837 dc->emc_clk = emc_clk;
2838 dc->shift_clk_div = 1;
2839 /* Initialize one shot work delay, it will be assigned by dsi
2840 * according to refresh rate later. */
2841 dc->one_shot_delay_ms = 40;
2842
2843 dc->base_res = base_res;
2844 dc->base = base;
2845 dc->irq = irq;
2846 dc->ndev = ndev;
2847 dc->pdata = ndev->dev.platform_data;
2848
2849 /*
2850 * The emc is a shared clock, it will be set based on
2851 * the requirements for each user on the bus.
2852 */
2853 dc->emc_clk_rate = 0;
2854
2855 if (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED)
2856 dc->enabled = true;
2857
2858 mutex_init(&dc->lock);
2859 mutex_init(&dc->one_shot_lock);
2860 init_completion(&dc->frame_end_complete);
2861 init_waitqueue_head(&dc->wq);
2862#ifdef CONFIG_ARCH_TEGRA_2x_SOC
2863 INIT_WORK(&dc->reset_work, tegra_dc_reset_worker);
2864#endif
2865 INIT_WORK(&dc->vblank_work, tegra_dc_vblank);
2866 INIT_DELAYED_WORK(&dc->underflow_work, tegra_dc_underflow_worker);
2867 INIT_DELAYED_WORK(&dc->one_shot_work, tegra_dc_one_shot_worker);
2868
2869 tegra_dc_init_lut_defaults(&dc->fb_lut);
2870
2871 dc->n_windows = DC_N_WINDOWS;
2872 for (i = 0; i < dc->n_windows; i++) {
2873 struct tegra_dc_win *win = &dc->windows[i];
2874 win->idx = i;
2875 win->dc = dc;
2876 tegra_dc_init_csc_defaults(&win->csc);
2877 tegra_dc_init_lut_defaults(&win->lut);
2878 }
2879
2880 ret = tegra_dc_set(dc, ndev->id);
2881 if (ret < 0) {
2882 dev_err(&ndev->dev, "can't add dc\n");
2883 goto err_free_irq;
2884 }
2885
2886 nvhost_set_drvdata(ndev, dc);
2887
2888#ifdef CONFIG_SWITCH
2889 dc->modeset_switch.name = dev_name(&ndev->dev);
2890 dc->modeset_switch.state = 0;
2891 dc->modeset_switch.print_state = switch_modeset_print_mode;
2892 switch_dev_register(&dc->modeset_switch);
2893#endif
2894
2895 if (dc->pdata->default_out)
2896 tegra_dc_set_out(dc, dc->pdata->default_out);
2897 else
2898 dev_err(&ndev->dev, "No default output specified. Leaving output disabled.\n");
2899
2900 dc->vblank_syncpt = (dc->ndev->id == 0) ?
2901 NVSYNCPT_VBLANK0 : NVSYNCPT_VBLANK1;
2902
2903 dc->ext = tegra_dc_ext_register(ndev, dc);
2904 if (IS_ERR_OR_NULL(dc->ext)) {
2905 dev_warn(&ndev->dev, "Failed to enable Tegra DC extensions.\n");
2906 dc->ext = NULL;
2907 }
2908
2909 /* interrupt handler must be registered before tegra_fb_register() */
2910 if (request_irq(irq, tegra_dc_irq, IRQF_DISABLED,
2911 dev_name(&ndev->dev), dc)) {
2912 dev_err(&ndev->dev, "request_irq %d failed\n", irq);
2913 ret = -EBUSY;
2914 goto err_put_emc_clk;
2915 }
2916
2917 /* hack to balance enable_irq calls in _tegra_dc_enable() */
2918 disable_dc_irq(dc->irq);
2919
2920 mutex_lock(&dc->lock);
2921 if (dc->enabled)
2922 _tegra_dc_enable(dc);
2923 mutex_unlock(&dc->lock);
2924
2925 tegra_dc_create_debugfs(dc);
2926
2927 dev_info(&ndev->dev, "probed\n");
2928
2929 if (dc->pdata->fb) {
2930 if (dc->pdata->fb->bits_per_pixel == -1) {
2931 unsigned long fmt;
2932 tegra_dc_writel(dc,
2933 WINDOW_A_SELECT << dc->pdata->fb->win,
2934 DC_CMD_DISPLAY_WINDOW_HEADER);
2935
2936 fmt = tegra_dc_readl(dc, DC_WIN_COLOR_DEPTH);
2937 dc->pdata->fb->bits_per_pixel =
2938 tegra_dc_fmt_bpp(fmt);
2939 }
2940
2941 dc->fb = tegra_fb_register(ndev, dc, dc->pdata->fb, fb_mem);
2942 if (IS_ERR_OR_NULL(dc->fb))
2943 dc->fb = NULL;
2944 }
2945
2946 if (dc->out && dc->out->hotplug_init)
2947 dc->out->hotplug_init();
2948
2949 if (dc->out_ops && dc->out_ops->detect)
2950 dc->out_ops->detect(dc);
2951 else
2952 dc->connected = true;
2953
2954 tegra_dc_create_sysfs(&dc->ndev->dev);
2955
2956 return 0;
2957
2958err_free_irq:
2959 free_irq(irq, dc);
2960err_put_emc_clk:
2961 clk_put(emc_clk);
2962err_put_clk:
2963 clk_put(clk);
2964err_iounmap_reg:
2965 iounmap(base);
2966 if (fb_mem)
2967 release_resource(fb_mem);
2968err_release_resource_reg:
2969 release_resource(base_res);
2970err_free:
2971 kfree(dc);
2972
2973 return ret;
2974}
2975
2976static int tegra_dc_remove(struct nvhost_device *ndev)
2977{
2978 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
2979
2980 tegra_dc_remove_sysfs(&dc->ndev->dev);
2981 tegra_dc_remove_debugfs(dc);
2982
2983 if (dc->fb) {
2984 tegra_fb_unregister(dc->fb);
2985 if (dc->fb_mem)
2986 release_resource(dc->fb_mem);
2987 }
2988
2989 tegra_dc_ext_disable(dc->ext);
2990
2991 if (dc->ext)
2992 tegra_dc_ext_unregister(dc->ext);
2993
2994 if (dc->enabled)
2995 _tegra_dc_disable(dc);
2996
2997#ifdef CONFIG_SWITCH
2998 switch_dev_unregister(&dc->modeset_switch);
2999#endif
3000 free_irq(dc->irq, dc);
3001 clk_put(dc->emc_clk);
3002 clk_put(dc->clk);
3003 iounmap(dc->base);
3004 if (dc->fb_mem)
3005 release_resource(dc->base_res);
3006 kfree(dc);
3007 tegra_dc_set(NULL, ndev->id);
3008 return 0;
3009}
3010
3011#ifdef CONFIG_PM
3012static int tegra_dc_suspend(struct nvhost_device *ndev, pm_message_t state)
3013{
3014 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
3015
3016 dev_info(&ndev->dev, "suspend\n");
3017
3018 tegra_dc_ext_disable(dc->ext);
3019
3020 mutex_lock(&dc->lock);
3021
3022 if (dc->out_ops && dc->out_ops->suspend)
3023 dc->out_ops->suspend(dc);
3024
3025 if (dc->enabled) {
3026 _tegra_dc_disable(dc);
3027
3028 dc->suspended = true;
3029 }
3030
3031 if (dc->out && dc->out->postsuspend) {
3032 dc->out->postsuspend();
3033 if (dc->out->type && dc->out->type == TEGRA_DC_OUT_HDMI)
3034 /*
3035 * avoid resume event due to voltage falling
3036 */
3037 msleep(100);
3038 }
3039
3040 mutex_unlock(&dc->lock);
3041
3042 return 0;
3043}
3044
3045static int tegra_dc_resume(struct nvhost_device *ndev)
3046{
3047 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
3048
3049 dev_info(&ndev->dev, "resume\n");
3050
3051 mutex_lock(&dc->lock);
3052 dc->suspended = false;
3053
3054 if (dc->enabled)
3055 _tegra_dc_enable(dc);
3056
3057 if (dc->out && dc->out->hotplug_init)
3058 dc->out->hotplug_init();
3059
3060 if (dc->out_ops && dc->out_ops->resume)
3061 dc->out_ops->resume(dc);
3062 mutex_unlock(&dc->lock);
3063
3064 return 0;
3065}
3066
3067#endif /* CONFIG_PM */
3068
3069extern int suspend_set(const char *val, struct kernel_param *kp)
3070{
3071 if (!strcmp(val, "dump"))
3072 dump_regs(tegra_dcs[0]);
3073#ifdef CONFIG_PM
3074 else if (!strcmp(val, "suspend"))
3075 tegra_dc_suspend(tegra_dcs[0]->ndev, PMSG_SUSPEND);
3076 else if (!strcmp(val, "resume"))
3077 tegra_dc_resume(tegra_dcs[0]->ndev);
3078#endif
3079
3080 return 0;
3081}
3082
3083extern int suspend_get(char *buffer, struct kernel_param *kp)
3084{
3085 return 0;
3086}
3087
3088int suspend;
3089
3090module_param_call(suspend, suspend_set, suspend_get, &suspend, 0644);
3091
3092struct nvhost_driver tegra_dc_driver = {
3093 .driver = {
3094 .name = "tegradc",
3095 .owner = THIS_MODULE,
3096 },
3097 .probe = tegra_dc_probe,
3098 .remove = tegra_dc_remove,
3099#ifdef CONFIG_PM
3100 .suspend = tegra_dc_suspend,
3101 .resume = tegra_dc_resume,
3102#endif
3103};
3104
3105static int __init tegra_dc_module_init(void)
3106{
3107 int ret = tegra_dc_ext_module_init();
3108 if (ret)
3109 return ret;
3110 return nvhost_driver_register(&tegra_dc_driver);
3111}
3112
3113static void __exit tegra_dc_module_exit(void)
3114{
3115 nvhost_driver_unregister(&tegra_dc_driver);
3116 tegra_dc_ext_module_exit();
3117}
3118
3119module_exit(tegra_dc_module_exit);
3120module_init(tegra_dc_module_init);