2 * linux/drivers/video/omap2/dss/dispc.c
4 * Copyright (C) 2009 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
7 * Some code and ideas taken from drivers/video/omap/ driver
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
23 #define DSS_SUBSYS_NAME "DISPC"
25 #include <linux/kernel.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/vmalloc.h>
28 #include <linux/clk.h>
30 #include <linux/jiffies.h>
31 #include <linux/seq_file.h>
32 #include <linux/delay.h>
33 #include <linux/workqueue.h>
35 #include <plat/sram.h>
36 #include <plat/clock.h>
38 #include <plat/display.h>
43 #define DISPC_BASE 0x48050400
45 #define DISPC_SZ_REGS SZ_1K
47 struct dispc_reg
{ u16 idx
; };
49 #define DISPC_REG(idx) ((const struct dispc_reg) { idx })
52 #define DISPC_REVISION DISPC_REG(0x0000)
53 #define DISPC_SYSCONFIG DISPC_REG(0x0010)
54 #define DISPC_SYSSTATUS DISPC_REG(0x0014)
55 #define DISPC_IRQSTATUS DISPC_REG(0x0018)
56 #define DISPC_IRQENABLE DISPC_REG(0x001C)
57 #define DISPC_CONTROL DISPC_REG(0x0040)
58 #define DISPC_CONFIG DISPC_REG(0x0044)
59 #define DISPC_CAPABLE DISPC_REG(0x0048)
60 #define DISPC_DEFAULT_COLOR0 DISPC_REG(0x004C)
61 #define DISPC_DEFAULT_COLOR1 DISPC_REG(0x0050)
62 #define DISPC_TRANS_COLOR0 DISPC_REG(0x0054)
63 #define DISPC_TRANS_COLOR1 DISPC_REG(0x0058)
64 #define DISPC_LINE_STATUS DISPC_REG(0x005C)
65 #define DISPC_LINE_NUMBER DISPC_REG(0x0060)
66 #define DISPC_TIMING_H DISPC_REG(0x0064)
67 #define DISPC_TIMING_V DISPC_REG(0x0068)
68 #define DISPC_POL_FREQ DISPC_REG(0x006C)
69 #define DISPC_DIVISOR DISPC_REG(0x0070)
70 #define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
71 #define DISPC_SIZE_DIG DISPC_REG(0x0078)
72 #define DISPC_SIZE_LCD DISPC_REG(0x007C)
75 #define DISPC_GFX_BA0 DISPC_REG(0x0080)
76 #define DISPC_GFX_BA1 DISPC_REG(0x0084)
77 #define DISPC_GFX_POSITION DISPC_REG(0x0088)
78 #define DISPC_GFX_SIZE DISPC_REG(0x008C)
79 #define DISPC_GFX_ATTRIBUTES DISPC_REG(0x00A0)
80 #define DISPC_GFX_FIFO_THRESHOLD DISPC_REG(0x00A4)
81 #define DISPC_GFX_FIFO_SIZE_STATUS DISPC_REG(0x00A8)
82 #define DISPC_GFX_ROW_INC DISPC_REG(0x00AC)
83 #define DISPC_GFX_PIXEL_INC DISPC_REG(0x00B0)
84 #define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4)
85 #define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8)
87 #define DISPC_DATA_CYCLE1 DISPC_REG(0x01D4)
88 #define DISPC_DATA_CYCLE2 DISPC_REG(0x01D8)
89 #define DISPC_DATA_CYCLE3 DISPC_REG(0x01DC)
91 #define DISPC_CPR_COEF_R DISPC_REG(0x0220)
92 #define DISPC_CPR_COEF_G DISPC_REG(0x0224)
93 #define DISPC_CPR_COEF_B DISPC_REG(0x0228)
95 #define DISPC_GFX_PRELOAD DISPC_REG(0x022C)
97 /* DISPC Video plane, n = 0 for VID1 and n = 1 for VID2 */
98 #define DISPC_VID_REG(n, idx) DISPC_REG(0x00BC + (n)*0x90 + idx)
100 #define DISPC_VID_BA0(n) DISPC_VID_REG(n, 0x0000)
101 #define DISPC_VID_BA1(n) DISPC_VID_REG(n, 0x0004)
102 #define DISPC_VID_POSITION(n) DISPC_VID_REG(n, 0x0008)
103 #define DISPC_VID_SIZE(n) DISPC_VID_REG(n, 0x000C)
104 #define DISPC_VID_ATTRIBUTES(n) DISPC_VID_REG(n, 0x0010)
105 #define DISPC_VID_FIFO_THRESHOLD(n) DISPC_VID_REG(n, 0x0014)
106 #define DISPC_VID_FIFO_SIZE_STATUS(n) DISPC_VID_REG(n, 0x0018)
107 #define DISPC_VID_ROW_INC(n) DISPC_VID_REG(n, 0x001C)
108 #define DISPC_VID_PIXEL_INC(n) DISPC_VID_REG(n, 0x0020)
109 #define DISPC_VID_FIR(n) DISPC_VID_REG(n, 0x0024)
110 #define DISPC_VID_PICTURE_SIZE(n) DISPC_VID_REG(n, 0x0028)
111 #define DISPC_VID_ACCU0(n) DISPC_VID_REG(n, 0x002C)
112 #define DISPC_VID_ACCU1(n) DISPC_VID_REG(n, 0x0030)
114 /* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
115 #define DISPC_VID_FIR_COEF_H(n, i) DISPC_REG(0x00F0 + (n)*0x90 + (i)*0x8)
116 /* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
117 #define DISPC_VID_FIR_COEF_HV(n, i) DISPC_REG(0x00F4 + (n)*0x90 + (i)*0x8)
118 /* coef index i = {0, 1, 2, 3, 4} */
119 #define DISPC_VID_CONV_COEF(n, i) DISPC_REG(0x0130 + (n)*0x90 + (i)*0x4)
120 /* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
121 #define DISPC_VID_FIR_COEF_V(n, i) DISPC_REG(0x01E0 + (n)*0x20 + (i)*0x4)
123 #define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
126 #define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
127 DISPC_IRQ_OCP_ERR | \
128 DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
129 DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
130 DISPC_IRQ_SYNC_LOST | \
131 DISPC_IRQ_SYNC_LOST_DIGIT)
133 #define DISPC_MAX_NR_ISRS 8
135 struct omap_dispc_isr_data
{
136 omap_dispc_isr_t isr
;
141 #define REG_GET(idx, start, end) \
142 FLD_GET(dispc_read_reg(idx), start, end)
144 #define REG_FLD_MOD(idx, val, start, end) \
145 dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
147 static const struct dispc_reg dispc_reg_att
[] = { DISPC_GFX_ATTRIBUTES
,
148 DISPC_VID_ATTRIBUTES(0),
149 DISPC_VID_ATTRIBUTES(1) };
151 struct dispc_irq_stats
{
152 unsigned long last_reset
;
164 struct omap_dispc_isr_data registered_isr
[DISPC_MAX_NR_ISRS
];
166 struct work_struct error_work
;
168 u32 ctx
[DISPC_SZ_REGS
/ sizeof(u32
)];
170 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
171 spinlock_t irq_stats_lock
;
172 struct dispc_irq_stats irq_stats
;
176 static void _omap_dispc_set_irqs(void);
178 static inline void dispc_write_reg(const struct dispc_reg idx
, u32 val
)
180 __raw_writel(val
, dispc
.base
+ idx
.idx
);
183 static inline u32
dispc_read_reg(const struct dispc_reg idx
)
185 return __raw_readl(dispc
.base
+ idx
.idx
);
189 dispc.ctx[(DISPC_##reg).idx / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
191 dispc_write_reg(DISPC_##reg, dispc.ctx[(DISPC_##reg).idx / sizeof(u32)])
193 void dispc_save_context(void)
195 if (cpu_is_omap24xx())
220 SR(GFX_FIFO_THRESHOLD
);
241 SR(VID_ATTRIBUTES(0));
242 SR(VID_FIFO_THRESHOLD(0));
244 SR(VID_PIXEL_INC(0));
246 SR(VID_PICTURE_SIZE(0));
250 SR(VID_FIR_COEF_H(0, 0));
251 SR(VID_FIR_COEF_H(0, 1));
252 SR(VID_FIR_COEF_H(0, 2));
253 SR(VID_FIR_COEF_H(0, 3));
254 SR(VID_FIR_COEF_H(0, 4));
255 SR(VID_FIR_COEF_H(0, 5));
256 SR(VID_FIR_COEF_H(0, 6));
257 SR(VID_FIR_COEF_H(0, 7));
259 SR(VID_FIR_COEF_HV(0, 0));
260 SR(VID_FIR_COEF_HV(0, 1));
261 SR(VID_FIR_COEF_HV(0, 2));
262 SR(VID_FIR_COEF_HV(0, 3));
263 SR(VID_FIR_COEF_HV(0, 4));
264 SR(VID_FIR_COEF_HV(0, 5));
265 SR(VID_FIR_COEF_HV(0, 6));
266 SR(VID_FIR_COEF_HV(0, 7));
268 SR(VID_CONV_COEF(0, 0));
269 SR(VID_CONV_COEF(0, 1));
270 SR(VID_CONV_COEF(0, 2));
271 SR(VID_CONV_COEF(0, 3));
272 SR(VID_CONV_COEF(0, 4));
274 SR(VID_FIR_COEF_V(0, 0));
275 SR(VID_FIR_COEF_V(0, 1));
276 SR(VID_FIR_COEF_V(0, 2));
277 SR(VID_FIR_COEF_V(0, 3));
278 SR(VID_FIR_COEF_V(0, 4));
279 SR(VID_FIR_COEF_V(0, 5));
280 SR(VID_FIR_COEF_V(0, 6));
281 SR(VID_FIR_COEF_V(0, 7));
290 SR(VID_ATTRIBUTES(1));
291 SR(VID_FIFO_THRESHOLD(1));
293 SR(VID_PIXEL_INC(1));
295 SR(VID_PICTURE_SIZE(1));
299 SR(VID_FIR_COEF_H(1, 0));
300 SR(VID_FIR_COEF_H(1, 1));
301 SR(VID_FIR_COEF_H(1, 2));
302 SR(VID_FIR_COEF_H(1, 3));
303 SR(VID_FIR_COEF_H(1, 4));
304 SR(VID_FIR_COEF_H(1, 5));
305 SR(VID_FIR_COEF_H(1, 6));
306 SR(VID_FIR_COEF_H(1, 7));
308 SR(VID_FIR_COEF_HV(1, 0));
309 SR(VID_FIR_COEF_HV(1, 1));
310 SR(VID_FIR_COEF_HV(1, 2));
311 SR(VID_FIR_COEF_HV(1, 3));
312 SR(VID_FIR_COEF_HV(1, 4));
313 SR(VID_FIR_COEF_HV(1, 5));
314 SR(VID_FIR_COEF_HV(1, 6));
315 SR(VID_FIR_COEF_HV(1, 7));
317 SR(VID_CONV_COEF(1, 0));
318 SR(VID_CONV_COEF(1, 1));
319 SR(VID_CONV_COEF(1, 2));
320 SR(VID_CONV_COEF(1, 3));
321 SR(VID_CONV_COEF(1, 4));
323 SR(VID_FIR_COEF_V(1, 0));
324 SR(VID_FIR_COEF_V(1, 1));
325 SR(VID_FIR_COEF_V(1, 2));
326 SR(VID_FIR_COEF_V(1, 3));
327 SR(VID_FIR_COEF_V(1, 4));
328 SR(VID_FIR_COEF_V(1, 5));
329 SR(VID_FIR_COEF_V(1, 6));
330 SR(VID_FIR_COEF_V(1, 7));
335 void dispc_restore_context(void)
359 RR(GFX_FIFO_THRESHOLD
);
380 RR(VID_ATTRIBUTES(0));
381 RR(VID_FIFO_THRESHOLD(0));
383 RR(VID_PIXEL_INC(0));
385 RR(VID_PICTURE_SIZE(0));
389 RR(VID_FIR_COEF_H(0, 0));
390 RR(VID_FIR_COEF_H(0, 1));
391 RR(VID_FIR_COEF_H(0, 2));
392 RR(VID_FIR_COEF_H(0, 3));
393 RR(VID_FIR_COEF_H(0, 4));
394 RR(VID_FIR_COEF_H(0, 5));
395 RR(VID_FIR_COEF_H(0, 6));
396 RR(VID_FIR_COEF_H(0, 7));
398 RR(VID_FIR_COEF_HV(0, 0));
399 RR(VID_FIR_COEF_HV(0, 1));
400 RR(VID_FIR_COEF_HV(0, 2));
401 RR(VID_FIR_COEF_HV(0, 3));
402 RR(VID_FIR_COEF_HV(0, 4));
403 RR(VID_FIR_COEF_HV(0, 5));
404 RR(VID_FIR_COEF_HV(0, 6));
405 RR(VID_FIR_COEF_HV(0, 7));
407 RR(VID_CONV_COEF(0, 0));
408 RR(VID_CONV_COEF(0, 1));
409 RR(VID_CONV_COEF(0, 2));
410 RR(VID_CONV_COEF(0, 3));
411 RR(VID_CONV_COEF(0, 4));
413 RR(VID_FIR_COEF_V(0, 0));
414 RR(VID_FIR_COEF_V(0, 1));
415 RR(VID_FIR_COEF_V(0, 2));
416 RR(VID_FIR_COEF_V(0, 3));
417 RR(VID_FIR_COEF_V(0, 4));
418 RR(VID_FIR_COEF_V(0, 5));
419 RR(VID_FIR_COEF_V(0, 6));
420 RR(VID_FIR_COEF_V(0, 7));
429 RR(VID_ATTRIBUTES(1));
430 RR(VID_FIFO_THRESHOLD(1));
432 RR(VID_PIXEL_INC(1));
434 RR(VID_PICTURE_SIZE(1));
438 RR(VID_FIR_COEF_H(1, 0));
439 RR(VID_FIR_COEF_H(1, 1));
440 RR(VID_FIR_COEF_H(1, 2));
441 RR(VID_FIR_COEF_H(1, 3));
442 RR(VID_FIR_COEF_H(1, 4));
443 RR(VID_FIR_COEF_H(1, 5));
444 RR(VID_FIR_COEF_H(1, 6));
445 RR(VID_FIR_COEF_H(1, 7));
447 RR(VID_FIR_COEF_HV(1, 0));
448 RR(VID_FIR_COEF_HV(1, 1));
449 RR(VID_FIR_COEF_HV(1, 2));
450 RR(VID_FIR_COEF_HV(1, 3));
451 RR(VID_FIR_COEF_HV(1, 4));
452 RR(VID_FIR_COEF_HV(1, 5));
453 RR(VID_FIR_COEF_HV(1, 6));
454 RR(VID_FIR_COEF_HV(1, 7));
456 RR(VID_CONV_COEF(1, 0));
457 RR(VID_CONV_COEF(1, 1));
458 RR(VID_CONV_COEF(1, 2));
459 RR(VID_CONV_COEF(1, 3));
460 RR(VID_CONV_COEF(1, 4));
462 RR(VID_FIR_COEF_V(1, 0));
463 RR(VID_FIR_COEF_V(1, 1));
464 RR(VID_FIR_COEF_V(1, 2));
465 RR(VID_FIR_COEF_V(1, 3));
466 RR(VID_FIR_COEF_V(1, 4));
467 RR(VID_FIR_COEF_V(1, 5));
468 RR(VID_FIR_COEF_V(1, 6));
469 RR(VID_FIR_COEF_V(1, 7));
473 /* enable last, because LCD & DIGIT enable are here */
480 static inline void enable_clocks(bool enable
)
483 dss_clk_enable(DSS_CLK_ICK
| DSS_CLK_FCK1
);
485 dss_clk_disable(DSS_CLK_ICK
| DSS_CLK_FCK1
);
488 bool dispc_go_busy(enum omap_channel channel
)
492 if (channel
== OMAP_DSS_CHANNEL_LCD
)
495 bit
= 6; /* GODIGIT */
497 return REG_GET(DISPC_CONTROL
, bit
, bit
) == 1;
500 void dispc_go(enum omap_channel channel
)
506 if (channel
== OMAP_DSS_CHANNEL_LCD
)
507 bit
= 0; /* LCDENABLE */
509 bit
= 1; /* DIGITALENABLE */
511 /* if the channel is not enabled, we don't need GO */
512 if (REG_GET(DISPC_CONTROL
, bit
, bit
) == 0)
515 if (channel
== OMAP_DSS_CHANNEL_LCD
)
518 bit
= 6; /* GODIGIT */
520 if (REG_GET(DISPC_CONTROL
, bit
, bit
) == 1) {
521 DSSERR("GO bit not down for channel %d\n", channel
);
525 DSSDBG("GO %s\n", channel
== OMAP_DSS_CHANNEL_LCD
? "LCD" : "DIGIT");
527 REG_FLD_MOD(DISPC_CONTROL
, 1, bit
, bit
);
532 static void _dispc_write_firh_reg(enum omap_plane plane
, int reg
, u32 value
)
534 BUG_ON(plane
== OMAP_DSS_GFX
);
536 dispc_write_reg(DISPC_VID_FIR_COEF_H(plane
-1, reg
), value
);
539 static void _dispc_write_firhv_reg(enum omap_plane plane
, int reg
, u32 value
)
541 BUG_ON(plane
== OMAP_DSS_GFX
);
543 dispc_write_reg(DISPC_VID_FIR_COEF_HV(plane
-1, reg
), value
);
546 static void _dispc_write_firv_reg(enum omap_plane plane
, int reg
, u32 value
)
548 BUG_ON(plane
== OMAP_DSS_GFX
);
550 dispc_write_reg(DISPC_VID_FIR_COEF_V(plane
-1, reg
), value
);
553 static void _dispc_set_scale_coef(enum omap_plane plane
, int hscaleup
,
554 int vscaleup
, int five_taps
)
556 /* Coefficients for horizontal up-sampling */
557 static const u32 coef_hup
[8] = {
568 /* Coefficients for horizontal down-sampling */
569 static const u32 coef_hdown
[8] = {
580 /* Coefficients for horizontal and vertical up-sampling */
581 static const u32 coef_hvup
[2][8] = {
604 /* Coefficients for horizontal and vertical down-sampling */
605 static const u32 coef_hvdown
[2][8] = {
628 /* Coefficients for vertical up-sampling */
629 static const u32 coef_vup
[8] = {
641 /* Coefficients for vertical down-sampling */
642 static const u32 coef_vdown
[8] = {
655 const u32
*hv_coef_mod
;
665 hv_coef
= coef_hvup
[five_taps
];
671 hv_coef_mod
= coef_hvdown
[five_taps
];
673 hv_coef
= coef_hvdown
[five_taps
];
677 hv_coef_mod
= coef_hvup
[five_taps
];
682 for (i
= 0; i
< 8; i
++) {
691 hv
|= (hv_coef_mod
[i
] & 0xff);
694 _dispc_write_firh_reg(plane
, i
, h
);
695 _dispc_write_firhv_reg(plane
, i
, hv
);
701 for (i
= 0; i
< 8; i
++) {
704 _dispc_write_firv_reg(plane
, i
, v
);
708 static void _dispc_setup_color_conv_coef(void)
710 const struct color_conv_coef
{
711 int ry
, rcr
, rcb
, gy
, gcr
, gcb
, by
, bcr
, bcb
;
714 298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
717 const struct color_conv_coef
*ct
;
719 #define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0))
723 dispc_write_reg(DISPC_VID_CONV_COEF(0, 0), CVAL(ct
->rcr
, ct
->ry
));
724 dispc_write_reg(DISPC_VID_CONV_COEF(0, 1), CVAL(ct
->gy
, ct
->rcb
));
725 dispc_write_reg(DISPC_VID_CONV_COEF(0, 2), CVAL(ct
->gcb
, ct
->gcr
));
726 dispc_write_reg(DISPC_VID_CONV_COEF(0, 3), CVAL(ct
->bcr
, ct
->by
));
727 dispc_write_reg(DISPC_VID_CONV_COEF(0, 4), CVAL(0, ct
->bcb
));
729 dispc_write_reg(DISPC_VID_CONV_COEF(1, 0), CVAL(ct
->rcr
, ct
->ry
));
730 dispc_write_reg(DISPC_VID_CONV_COEF(1, 1), CVAL(ct
->gy
, ct
->rcb
));
731 dispc_write_reg(DISPC_VID_CONV_COEF(1, 2), CVAL(ct
->gcb
, ct
->gcr
));
732 dispc_write_reg(DISPC_VID_CONV_COEF(1, 3), CVAL(ct
->bcr
, ct
->by
));
733 dispc_write_reg(DISPC_VID_CONV_COEF(1, 4), CVAL(0, ct
->bcb
));
737 REG_FLD_MOD(DISPC_VID_ATTRIBUTES(0), ct
->full_range
, 11, 11);
738 REG_FLD_MOD(DISPC_VID_ATTRIBUTES(1), ct
->full_range
, 11, 11);
742 static void _dispc_set_plane_ba0(enum omap_plane plane
, u32 paddr
)
744 const struct dispc_reg ba0_reg
[] = { DISPC_GFX_BA0
,
748 dispc_write_reg(ba0_reg
[plane
], paddr
);
751 static void _dispc_set_plane_ba1(enum omap_plane plane
, u32 paddr
)
753 const struct dispc_reg ba1_reg
[] = { DISPC_GFX_BA1
,
757 dispc_write_reg(ba1_reg
[plane
], paddr
);
760 static void _dispc_set_plane_pos(enum omap_plane plane
, int x
, int y
)
762 const struct dispc_reg pos_reg
[] = { DISPC_GFX_POSITION
,
763 DISPC_VID_POSITION(0),
764 DISPC_VID_POSITION(1) };
766 u32 val
= FLD_VAL(y
, 26, 16) | FLD_VAL(x
, 10, 0);
767 dispc_write_reg(pos_reg
[plane
], val
);
770 static void _dispc_set_pic_size(enum omap_plane plane
, int width
, int height
)
772 const struct dispc_reg siz_reg
[] = { DISPC_GFX_SIZE
,
773 DISPC_VID_PICTURE_SIZE(0),
774 DISPC_VID_PICTURE_SIZE(1) };
775 u32 val
= FLD_VAL(height
- 1, 26, 16) | FLD_VAL(width
- 1, 10, 0);
776 dispc_write_reg(siz_reg
[plane
], val
);
779 static void _dispc_set_vid_size(enum omap_plane plane
, int width
, int height
)
782 const struct dispc_reg vsi_reg
[] = { DISPC_VID_SIZE(0),
785 BUG_ON(plane
== OMAP_DSS_GFX
);
787 val
= FLD_VAL(height
- 1, 26, 16) | FLD_VAL(width
- 1, 10, 0);
788 dispc_write_reg(vsi_reg
[plane
-1], val
);
791 static void _dispc_setup_global_alpha(enum omap_plane plane
, u8 global_alpha
)
794 BUG_ON(plane
== OMAP_DSS_VIDEO1
);
796 if (cpu_is_omap24xx())
799 if (plane
== OMAP_DSS_GFX
)
800 REG_FLD_MOD(DISPC_GLOBAL_ALPHA
, global_alpha
, 7, 0);
801 else if (plane
== OMAP_DSS_VIDEO2
)
802 REG_FLD_MOD(DISPC_GLOBAL_ALPHA
, global_alpha
, 23, 16);
805 static void _dispc_set_pix_inc(enum omap_plane plane
, s32 inc
)
807 const struct dispc_reg ri_reg
[] = { DISPC_GFX_PIXEL_INC
,
808 DISPC_VID_PIXEL_INC(0),
809 DISPC_VID_PIXEL_INC(1) };
811 dispc_write_reg(ri_reg
[plane
], inc
);
814 static void _dispc_set_row_inc(enum omap_plane plane
, s32 inc
)
816 const struct dispc_reg ri_reg
[] = { DISPC_GFX_ROW_INC
,
817 DISPC_VID_ROW_INC(0),
818 DISPC_VID_ROW_INC(1) };
820 dispc_write_reg(ri_reg
[plane
], inc
);
823 static void _dispc_set_color_mode(enum omap_plane plane
,
824 enum omap_color_mode color_mode
)
828 switch (color_mode
) {
829 case OMAP_DSS_COLOR_CLUT1
:
831 case OMAP_DSS_COLOR_CLUT2
:
833 case OMAP_DSS_COLOR_CLUT4
:
835 case OMAP_DSS_COLOR_CLUT8
:
837 case OMAP_DSS_COLOR_RGB12U
:
839 case OMAP_DSS_COLOR_ARGB16
:
841 case OMAP_DSS_COLOR_RGB16
:
843 case OMAP_DSS_COLOR_RGB24U
:
845 case OMAP_DSS_COLOR_RGB24P
:
847 case OMAP_DSS_COLOR_YUV2
:
849 case OMAP_DSS_COLOR_UYVY
:
851 case OMAP_DSS_COLOR_ARGB32
:
853 case OMAP_DSS_COLOR_RGBA32
:
855 case OMAP_DSS_COLOR_RGBX32
:
861 REG_FLD_MOD(dispc_reg_att
[plane
], m
, 4, 1);
864 static void _dispc_set_channel_out(enum omap_plane plane
,
865 enum omap_channel channel
)
874 case OMAP_DSS_VIDEO1
:
875 case OMAP_DSS_VIDEO2
:
883 val
= dispc_read_reg(dispc_reg_att
[plane
]);
884 val
= FLD_MOD(val
, channel
, shift
, shift
);
885 dispc_write_reg(dispc_reg_att
[plane
], val
);
888 void dispc_set_burst_size(enum omap_plane plane
,
889 enum omap_burst_size burst_size
)
900 case OMAP_DSS_VIDEO1
:
901 case OMAP_DSS_VIDEO2
:
909 val
= dispc_read_reg(dispc_reg_att
[plane
]);
910 val
= FLD_MOD(val
, burst_size
, shift
+1, shift
);
911 dispc_write_reg(dispc_reg_att
[plane
], val
);
916 static void _dispc_set_vid_color_conv(enum omap_plane plane
, bool enable
)
920 BUG_ON(plane
== OMAP_DSS_GFX
);
922 val
= dispc_read_reg(dispc_reg_att
[plane
]);
923 val
= FLD_MOD(val
, enable
, 9, 9);
924 dispc_write_reg(dispc_reg_att
[plane
], val
);
927 void dispc_enable_replication(enum omap_plane plane
, bool enable
)
931 if (plane
== OMAP_DSS_GFX
)
937 REG_FLD_MOD(dispc_reg_att
[plane
], enable
, bit
, bit
);
941 void dispc_set_lcd_size(u16 width
, u16 height
)
944 BUG_ON((width
> (1 << 11)) || (height
> (1 << 11)));
945 val
= FLD_VAL(height
- 1, 26, 16) | FLD_VAL(width
- 1, 10, 0);
947 dispc_write_reg(DISPC_SIZE_LCD
, val
);
951 void dispc_set_digit_size(u16 width
, u16 height
)
954 BUG_ON((width
> (1 << 11)) || (height
> (1 << 11)));
955 val
= FLD_VAL(height
- 1, 26, 16) | FLD_VAL(width
- 1, 10, 0);
957 dispc_write_reg(DISPC_SIZE_DIG
, val
);
961 static void dispc_read_plane_fifo_sizes(void)
963 const struct dispc_reg fsz_reg
[] = { DISPC_GFX_FIFO_SIZE_STATUS
,
964 DISPC_VID_FIFO_SIZE_STATUS(0),
965 DISPC_VID_FIFO_SIZE_STATUS(1) };
971 for (plane
= 0; plane
< ARRAY_SIZE(dispc
.fifo_size
); ++plane
) {
972 if (cpu_is_omap24xx())
973 size
= FLD_GET(dispc_read_reg(fsz_reg
[plane
]), 8, 0);
974 else if (cpu_is_omap34xx())
975 size
= FLD_GET(dispc_read_reg(fsz_reg
[plane
]), 10, 0);
979 dispc
.fifo_size
[plane
] = size
;
985 u32
dispc_get_plane_fifo_size(enum omap_plane plane
)
987 return dispc
.fifo_size
[plane
];
990 void dispc_setup_plane_fifo(enum omap_plane plane
, u32 low
, u32 high
)
992 const struct dispc_reg ftrs_reg
[] = { DISPC_GFX_FIFO_THRESHOLD
,
993 DISPC_VID_FIFO_THRESHOLD(0),
994 DISPC_VID_FIFO_THRESHOLD(1) };
997 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n",
999 REG_GET(ftrs_reg
[plane
], 11, 0),
1000 REG_GET(ftrs_reg
[plane
], 27, 16),
1003 if (cpu_is_omap24xx())
1004 dispc_write_reg(ftrs_reg
[plane
],
1005 FLD_VAL(high
, 24, 16) | FLD_VAL(low
, 8, 0));
1007 dispc_write_reg(ftrs_reg
[plane
],
1008 FLD_VAL(high
, 27, 16) | FLD_VAL(low
, 11, 0));
1013 void dispc_enable_fifomerge(bool enable
)
1017 DSSDBG("FIFO merge %s\n", enable
? "enabled" : "disabled");
1018 REG_FLD_MOD(DISPC_CONFIG
, enable
? 1 : 0, 14, 14);
1023 static void _dispc_set_fir(enum omap_plane plane
, int hinc
, int vinc
)
1026 const struct dispc_reg fir_reg
[] = { DISPC_VID_FIR(0),
1029 BUG_ON(plane
== OMAP_DSS_GFX
);
1031 if (cpu_is_omap24xx())
1032 val
= FLD_VAL(vinc
, 27, 16) | FLD_VAL(hinc
, 11, 0);
1034 val
= FLD_VAL(vinc
, 28, 16) | FLD_VAL(hinc
, 12, 0);
1035 dispc_write_reg(fir_reg
[plane
-1], val
);
1038 static void _dispc_set_vid_accu0(enum omap_plane plane
, int haccu
, int vaccu
)
1041 const struct dispc_reg ac0_reg
[] = { DISPC_VID_ACCU0(0),
1042 DISPC_VID_ACCU0(1) };
1044 BUG_ON(plane
== OMAP_DSS_GFX
);
1046 val
= FLD_VAL(vaccu
, 25, 16) | FLD_VAL(haccu
, 9, 0);
1047 dispc_write_reg(ac0_reg
[plane
-1], val
);
1050 static void _dispc_set_vid_accu1(enum omap_plane plane
, int haccu
, int vaccu
)
1053 const struct dispc_reg ac1_reg
[] = { DISPC_VID_ACCU1(0),
1054 DISPC_VID_ACCU1(1) };
1056 BUG_ON(plane
== OMAP_DSS_GFX
);
1058 val
= FLD_VAL(vaccu
, 25, 16) | FLD_VAL(haccu
, 9, 0);
1059 dispc_write_reg(ac1_reg
[plane
-1], val
);
1063 static void _dispc_set_scaling(enum omap_plane plane
,
1064 u16 orig_width
, u16 orig_height
,
1065 u16 out_width
, u16 out_height
,
1066 bool ilace
, bool five_taps
,
1071 int hscaleup
, vscaleup
;
1076 BUG_ON(plane
== OMAP_DSS_GFX
);
1078 hscaleup
= orig_width
<= out_width
;
1079 vscaleup
= orig_height
<= out_height
;
1081 _dispc_set_scale_coef(plane
, hscaleup
, vscaleup
, five_taps
);
1083 if (!orig_width
|| orig_width
== out_width
)
1086 fir_hinc
= 1024 * orig_width
/ out_width
;
1088 if (!orig_height
|| orig_height
== out_height
)
1091 fir_vinc
= 1024 * orig_height
/ out_height
;
1093 _dispc_set_fir(plane
, fir_hinc
, fir_vinc
);
1095 l
= dispc_read_reg(dispc_reg_att
[plane
]);
1096 l
&= ~((0x0f << 5) | (0x3 << 21));
1098 l
|= fir_hinc
? (1 << 5) : 0;
1099 l
|= fir_vinc
? (1 << 6) : 0;
1101 l
|= hscaleup
? 0 : (1 << 7);
1102 l
|= vscaleup
? 0 : (1 << 8);
1104 l
|= five_taps
? (1 << 21) : 0;
1105 l
|= five_taps
? (1 << 22) : 0;
1107 dispc_write_reg(dispc_reg_att
[plane
], l
);
1110 * field 0 = even field = bottom field
1111 * field 1 = odd field = top field
1113 if (ilace
&& !fieldmode
) {
1115 accu0
= (fir_vinc
/ 2) & 0x3ff;
1116 if (accu0
>= 1024/2) {
1122 _dispc_set_vid_accu0(plane
, 0, accu0
);
1123 _dispc_set_vid_accu1(plane
, 0, accu1
);
1126 static void _dispc_set_rotation_attrs(enum omap_plane plane
, u8 rotation
,
1127 bool mirroring
, enum omap_color_mode color_mode
)
1129 if (color_mode
== OMAP_DSS_COLOR_YUV2
||
1130 color_mode
== OMAP_DSS_COLOR_UYVY
) {
1135 case OMAP_DSS_ROT_0
:
1138 case OMAP_DSS_ROT_90
:
1141 case OMAP_DSS_ROT_180
:
1144 case OMAP_DSS_ROT_270
:
1150 case OMAP_DSS_ROT_0
:
1153 case OMAP_DSS_ROT_90
:
1156 case OMAP_DSS_ROT_180
:
1159 case OMAP_DSS_ROT_270
:
1165 REG_FLD_MOD(dispc_reg_att
[plane
], vidrot
, 13, 12);
1167 if (rotation
== OMAP_DSS_ROT_90
|| rotation
== OMAP_DSS_ROT_270
)
1168 REG_FLD_MOD(dispc_reg_att
[plane
], 0x1, 18, 18);
1170 REG_FLD_MOD(dispc_reg_att
[plane
], 0x0, 18, 18);
1172 REG_FLD_MOD(dispc_reg_att
[plane
], 0, 13, 12);
1173 REG_FLD_MOD(dispc_reg_att
[plane
], 0, 18, 18);
1177 static int color_mode_to_bpp(enum omap_color_mode color_mode
)
1179 switch (color_mode
) {
1180 case OMAP_DSS_COLOR_CLUT1
:
1182 case OMAP_DSS_COLOR_CLUT2
:
1184 case OMAP_DSS_COLOR_CLUT4
:
1186 case OMAP_DSS_COLOR_CLUT8
:
1188 case OMAP_DSS_COLOR_RGB12U
:
1189 case OMAP_DSS_COLOR_RGB16
:
1190 case OMAP_DSS_COLOR_ARGB16
:
1191 case OMAP_DSS_COLOR_YUV2
:
1192 case OMAP_DSS_COLOR_UYVY
:
1194 case OMAP_DSS_COLOR_RGB24P
:
1196 case OMAP_DSS_COLOR_RGB24U
:
1197 case OMAP_DSS_COLOR_ARGB32
:
1198 case OMAP_DSS_COLOR_RGBA32
:
1199 case OMAP_DSS_COLOR_RGBX32
:
1206 static s32
pixinc(int pixels
, u8 ps
)
1210 else if (pixels
> 1)
1211 return 1 + (pixels
- 1) * ps
;
1212 else if (pixels
< 0)
1213 return 1 - (-pixels
+ 1) * ps
;
1218 static void calc_vrfb_rotation_offset(u8 rotation
, bool mirror
,
1220 u16 width
, u16 height
,
1221 enum omap_color_mode color_mode
, bool fieldmode
,
1222 unsigned int field_offset
,
1223 unsigned *offset0
, unsigned *offset1
,
1224 s32
*row_inc
, s32
*pix_inc
)
1228 /* FIXME CLUT formats */
1229 switch (color_mode
) {
1230 case OMAP_DSS_COLOR_CLUT1
:
1231 case OMAP_DSS_COLOR_CLUT2
:
1232 case OMAP_DSS_COLOR_CLUT4
:
1233 case OMAP_DSS_COLOR_CLUT8
:
1236 case OMAP_DSS_COLOR_YUV2
:
1237 case OMAP_DSS_COLOR_UYVY
:
1241 ps
= color_mode_to_bpp(color_mode
) / 8;
1245 DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation
, screen_width
,
1249 * field 0 = even field = bottom field
1250 * field 1 = odd field = top field
1252 switch (rotation
+ mirror
* 4) {
1253 case OMAP_DSS_ROT_0
:
1254 case OMAP_DSS_ROT_180
:
1256 * If the pixel format is YUV or UYVY divide the width
1257 * of the image by 2 for 0 and 180 degree rotation.
1259 if (color_mode
== OMAP_DSS_COLOR_YUV2
||
1260 color_mode
== OMAP_DSS_COLOR_UYVY
)
1262 case OMAP_DSS_ROT_90
:
1263 case OMAP_DSS_ROT_270
:
1266 *offset0
= field_offset
* screen_width
* ps
;
1270 *row_inc
= pixinc(1 + (screen_width
- width
) +
1271 (fieldmode
? screen_width
: 0),
1273 *pix_inc
= pixinc(1, ps
);
1276 case OMAP_DSS_ROT_0
+ 4:
1277 case OMAP_DSS_ROT_180
+ 4:
1278 /* If the pixel format is YUV or UYVY divide the width
1279 * of the image by 2 for 0 degree and 180 degree
1281 if (color_mode
== OMAP_DSS_COLOR_YUV2
||
1282 color_mode
== OMAP_DSS_COLOR_UYVY
)
1284 case OMAP_DSS_ROT_90
+ 4:
1285 case OMAP_DSS_ROT_270
+ 4:
1288 *offset0
= field_offset
* screen_width
* ps
;
1291 *row_inc
= pixinc(1 - (screen_width
+ width
) -
1292 (fieldmode
? screen_width
: 0),
1294 *pix_inc
= pixinc(1, ps
);
1302 static void calc_dma_rotation_offset(u8 rotation
, bool mirror
,
1304 u16 width
, u16 height
,
1305 enum omap_color_mode color_mode
, bool fieldmode
,
1306 unsigned int field_offset
,
1307 unsigned *offset0
, unsigned *offset1
,
1308 s32
*row_inc
, s32
*pix_inc
)
1313 /* FIXME CLUT formats */
1314 switch (color_mode
) {
1315 case OMAP_DSS_COLOR_CLUT1
:
1316 case OMAP_DSS_COLOR_CLUT2
:
1317 case OMAP_DSS_COLOR_CLUT4
:
1318 case OMAP_DSS_COLOR_CLUT8
:
1322 ps
= color_mode_to_bpp(color_mode
) / 8;
1326 DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation
, screen_width
,
1329 /* width & height are overlay sizes, convert to fb sizes */
1331 if (rotation
== OMAP_DSS_ROT_0
|| rotation
== OMAP_DSS_ROT_180
) {
1340 * field 0 = even field = bottom field
1341 * field 1 = odd field = top field
1343 switch (rotation
+ mirror
* 4) {
1344 case OMAP_DSS_ROT_0
:
1347 *offset0
= *offset1
+ field_offset
* screen_width
* ps
;
1349 *offset0
= *offset1
;
1350 *row_inc
= pixinc(1 + (screen_width
- fbw
) +
1351 (fieldmode
? screen_width
: 0),
1353 *pix_inc
= pixinc(1, ps
);
1355 case OMAP_DSS_ROT_90
:
1356 *offset1
= screen_width
* (fbh
- 1) * ps
;
1358 *offset0
= *offset1
+ field_offset
* ps
;
1360 *offset0
= *offset1
;
1361 *row_inc
= pixinc(screen_width
* (fbh
- 1) + 1 +
1362 (fieldmode
? 1 : 0), ps
);
1363 *pix_inc
= pixinc(-screen_width
, ps
);
1365 case OMAP_DSS_ROT_180
:
1366 *offset1
= (screen_width
* (fbh
- 1) + fbw
- 1) * ps
;
1368 *offset0
= *offset1
- field_offset
* screen_width
* ps
;
1370 *offset0
= *offset1
;
1371 *row_inc
= pixinc(-1 -
1372 (screen_width
- fbw
) -
1373 (fieldmode
? screen_width
: 0),
1375 *pix_inc
= pixinc(-1, ps
);
1377 case OMAP_DSS_ROT_270
:
1378 *offset1
= (fbw
- 1) * ps
;
1380 *offset0
= *offset1
- field_offset
* ps
;
1382 *offset0
= *offset1
;
1383 *row_inc
= pixinc(-screen_width
* (fbh
- 1) - 1 -
1384 (fieldmode
? 1 : 0), ps
);
1385 *pix_inc
= pixinc(screen_width
, ps
);
1389 case OMAP_DSS_ROT_0
+ 4:
1390 *offset1
= (fbw
- 1) * ps
;
1392 *offset0
= *offset1
+ field_offset
* screen_width
* ps
;
1394 *offset0
= *offset1
;
1395 *row_inc
= pixinc(screen_width
* 2 - 1 +
1396 (fieldmode
? screen_width
: 0),
1398 *pix_inc
= pixinc(-1, ps
);
1401 case OMAP_DSS_ROT_90
+ 4:
1404 *offset0
= *offset1
+ field_offset
* ps
;
1406 *offset0
= *offset1
;
1407 *row_inc
= pixinc(-screen_width
* (fbh
- 1) + 1 +
1408 (fieldmode
? 1 : 0),
1410 *pix_inc
= pixinc(screen_width
, ps
);
1413 case OMAP_DSS_ROT_180
+ 4:
1414 *offset1
= screen_width
* (fbh
- 1) * ps
;
1416 *offset0
= *offset1
- field_offset
* screen_width
* ps
;
1418 *offset0
= *offset1
;
1419 *row_inc
= pixinc(1 - screen_width
* 2 -
1420 (fieldmode
? screen_width
: 0),
1422 *pix_inc
= pixinc(1, ps
);
1425 case OMAP_DSS_ROT_270
+ 4:
1426 *offset1
= (screen_width
* (fbh
- 1) + fbw
- 1) * ps
;
1428 *offset0
= *offset1
- field_offset
* ps
;
1430 *offset0
= *offset1
;
1431 *row_inc
= pixinc(screen_width
* (fbh
- 1) - 1 -
1432 (fieldmode
? 1 : 0),
1434 *pix_inc
= pixinc(-screen_width
, ps
);
1442 static unsigned long calc_fclk_five_taps(u16 width
, u16 height
,
1443 u16 out_width
, u16 out_height
, enum omap_color_mode color_mode
)
1446 /* FIXME venc pclk? */
1447 u64 tmp
, pclk
= dispc_pclk_rate();
1449 if (height
> out_height
) {
1450 /* FIXME get real display PPL */
1451 unsigned int ppl
= 800;
1453 tmp
= pclk
* height
* out_width
;
1454 do_div(tmp
, 2 * out_height
* ppl
);
1457 if (height
> 2 * out_height
) {
1458 if (ppl
== out_width
)
1461 tmp
= pclk
* (height
- 2 * out_height
) * out_width
;
1462 do_div(tmp
, 2 * out_height
* (ppl
- out_width
));
1463 fclk
= max(fclk
, (u32
) tmp
);
1467 if (width
> out_width
) {
1469 do_div(tmp
, out_width
);
1470 fclk
= max(fclk
, (u32
) tmp
);
1472 if (color_mode
== OMAP_DSS_COLOR_RGB24U
)
1479 static unsigned long calc_fclk(u16 width
, u16 height
,
1480 u16 out_width
, u16 out_height
)
1482 unsigned int hf
, vf
;
1485 * FIXME how to determine the 'A' factor
1486 * for the no downscaling case ?
1489 if (width
> 3 * out_width
)
1491 else if (width
> 2 * out_width
)
1493 else if (width
> out_width
)
1498 if (height
> out_height
)
1503 /* FIXME venc pclk? */
1504 return dispc_pclk_rate() * vf
* hf
;
1507 void dispc_set_channel_out(enum omap_plane plane
, enum omap_channel channel_out
)
1510 _dispc_set_channel_out(plane
, channel_out
);
1514 static int _dispc_setup_plane(enum omap_plane plane
,
1515 u32 paddr
, u16 screen_width
,
1516 u16 pos_x
, u16 pos_y
,
1517 u16 width
, u16 height
,
1518 u16 out_width
, u16 out_height
,
1519 enum omap_color_mode color_mode
,
1521 enum omap_dss_rotation_type rotation_type
,
1522 u8 rotation
, int mirror
,
1525 const int maxdownscale
= cpu_is_omap34xx() ? 4 : 2;
1529 unsigned offset0
, offset1
;
1532 u16 frame_height
= height
;
1533 unsigned int field_offset
= 0;
1538 if (ilace
&& height
== out_height
)
1547 DSSDBG("adjusting for ilace: height %d, pos_y %d, "
1549 height
, pos_y
, out_height
);
1552 if (plane
== OMAP_DSS_GFX
) {
1553 if (width
!= out_width
|| height
!= out_height
)
1556 switch (color_mode
) {
1557 case OMAP_DSS_COLOR_ARGB16
:
1558 case OMAP_DSS_COLOR_ARGB32
:
1559 case OMAP_DSS_COLOR_RGBA32
:
1560 case OMAP_DSS_COLOR_RGBX32
:
1561 if (cpu_is_omap24xx())
1564 case OMAP_DSS_COLOR_RGB12U
:
1565 case OMAP_DSS_COLOR_RGB16
:
1566 case OMAP_DSS_COLOR_RGB24P
:
1567 case OMAP_DSS_COLOR_RGB24U
:
1576 unsigned long fclk
= 0;
1578 if (out_width
< width
/ maxdownscale
||
1579 out_width
> width
* 8)
1582 if (out_height
< height
/ maxdownscale
||
1583 out_height
> height
* 8)
1586 switch (color_mode
) {
1587 case OMAP_DSS_COLOR_RGBX32
:
1588 case OMAP_DSS_COLOR_RGB12U
:
1589 if (cpu_is_omap24xx())
1592 case OMAP_DSS_COLOR_RGB16
:
1593 case OMAP_DSS_COLOR_RGB24P
:
1594 case OMAP_DSS_COLOR_RGB24U
:
1597 case OMAP_DSS_COLOR_ARGB16
:
1598 case OMAP_DSS_COLOR_ARGB32
:
1599 case OMAP_DSS_COLOR_RGBA32
:
1600 if (cpu_is_omap24xx())
1602 if (plane
== OMAP_DSS_VIDEO1
)
1606 case OMAP_DSS_COLOR_YUV2
:
1607 case OMAP_DSS_COLOR_UYVY
:
1615 /* Must use 5-tap filter? */
1616 five_taps
= height
> out_height
* 2;
1619 fclk
= calc_fclk(width
, height
,
1620 out_width
, out_height
);
1622 /* Try 5-tap filter if 3-tap fclk is too high */
1623 if (cpu_is_omap34xx() && height
> out_height
&&
1624 fclk
> dispc_fclk_rate())
1628 if (width
> (2048 >> five_taps
)) {
1629 DSSERR("failed to set up scaling, fclk too low\n");
1634 fclk
= calc_fclk_five_taps(width
, height
,
1635 out_width
, out_height
, color_mode
);
1637 DSSDBG("required fclk rate = %lu Hz\n", fclk
);
1638 DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
1640 if (!fclk
|| fclk
> dispc_fclk_rate()) {
1641 DSSERR("failed to set up scaling, "
1642 "required fclk rate = %lu Hz, "
1643 "current fclk rate = %lu Hz\n",
1644 fclk
, dispc_fclk_rate());
1649 if (ilace
&& !fieldmode
) {
1651 * when downscaling the bottom field may have to start several
1652 * source lines below the top field. Unfortunately ACCUI
1653 * registers will only hold the fractional part of the offset
1654 * so the integer part must be added to the base address of the
1657 if (!height
|| height
== out_height
)
1660 field_offset
= height
/ out_height
/ 2;
1663 /* Fields are independent but interleaved in memory. */
1667 if (rotation_type
== OMAP_DSS_ROT_DMA
)
1668 calc_dma_rotation_offset(rotation
, mirror
,
1669 screen_width
, width
, frame_height
, color_mode
,
1670 fieldmode
, field_offset
,
1671 &offset0
, &offset1
, &row_inc
, &pix_inc
);
1673 calc_vrfb_rotation_offset(rotation
, mirror
,
1674 screen_width
, width
, frame_height
, color_mode
,
1675 fieldmode
, field_offset
,
1676 &offset0
, &offset1
, &row_inc
, &pix_inc
);
1678 DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
1679 offset0
, offset1
, row_inc
, pix_inc
);
1681 _dispc_set_color_mode(plane
, color_mode
);
1683 _dispc_set_plane_ba0(plane
, paddr
+ offset0
);
1684 _dispc_set_plane_ba1(plane
, paddr
+ offset1
);
1686 _dispc_set_row_inc(plane
, row_inc
);
1687 _dispc_set_pix_inc(plane
, pix_inc
);
1689 DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x
, pos_y
, width
, height
,
1690 out_width
, out_height
);
1692 _dispc_set_plane_pos(plane
, pos_x
, pos_y
);
1694 _dispc_set_pic_size(plane
, width
, height
);
1696 if (plane
!= OMAP_DSS_GFX
) {
1697 _dispc_set_scaling(plane
, width
, height
,
1698 out_width
, out_height
,
1699 ilace
, five_taps
, fieldmode
);
1700 _dispc_set_vid_size(plane
, out_width
, out_height
);
1701 _dispc_set_vid_color_conv(plane
, cconv
);
1704 _dispc_set_rotation_attrs(plane
, rotation
, mirror
, color_mode
);
1706 if (plane
!= OMAP_DSS_VIDEO1
)
1707 _dispc_setup_global_alpha(plane
, global_alpha
);
1712 static void _dispc_enable_plane(enum omap_plane plane
, bool enable
)
1714 REG_FLD_MOD(dispc_reg_att
[plane
], enable
? 1 : 0, 0, 0);
1717 static void dispc_disable_isr(void *data
, u32 mask
)
1719 struct completion
*compl = data
;
1723 static void _enable_lcd_out(bool enable
)
1725 REG_FLD_MOD(DISPC_CONTROL
, enable
? 1 : 0, 0, 0);
1728 void dispc_enable_lcd_out(bool enable
)
1730 struct completion frame_done_completion
;
1736 /* When we disable LCD output, we need to wait until frame is done.
1737 * Otherwise the DSS is still working, and turning off the clocks
1738 * prevents DSS from going to OFF mode */
1739 is_on
= REG_GET(DISPC_CONTROL
, 0, 0);
1741 if (!enable
&& is_on
) {
1742 init_completion(&frame_done_completion
);
1744 r
= omap_dispc_register_isr(dispc_disable_isr
,
1745 &frame_done_completion
,
1746 DISPC_IRQ_FRAMEDONE
);
1749 DSSERR("failed to register FRAMEDONE isr\n");
1752 _enable_lcd_out(enable
);
1754 if (!enable
&& is_on
) {
1755 if (!wait_for_completion_timeout(&frame_done_completion
,
1756 msecs_to_jiffies(100)))
1757 DSSERR("timeout waiting for FRAME DONE\n");
1759 r
= omap_dispc_unregister_isr(dispc_disable_isr
,
1760 &frame_done_completion
,
1761 DISPC_IRQ_FRAMEDONE
);
1764 DSSERR("failed to unregister FRAMEDONE isr\n");
1770 static void _enable_digit_out(bool enable
)
1772 REG_FLD_MOD(DISPC_CONTROL
, enable
? 1 : 0, 1, 1);
1775 void dispc_enable_digit_out(bool enable
)
1777 struct completion frame_done_completion
;
1782 if (REG_GET(DISPC_CONTROL
, 1, 1) == enable
) {
1788 unsigned long flags
;
1789 /* When we enable digit output, we'll get an extra digit
1790 * sync lost interrupt, that we need to ignore */
1791 spin_lock_irqsave(&dispc
.irq_lock
, flags
);
1792 dispc
.irq_error_mask
&= ~DISPC_IRQ_SYNC_LOST_DIGIT
;
1793 _omap_dispc_set_irqs();
1794 spin_unlock_irqrestore(&dispc
.irq_lock
, flags
);
1797 /* When we disable digit output, we need to wait until fields are done.
1798 * Otherwise the DSS is still working, and turning off the clocks
1799 * prevents DSS from going to OFF mode. And when enabling, we need to
1800 * wait for the extra sync losts */
1801 init_completion(&frame_done_completion
);
1803 r
= omap_dispc_register_isr(dispc_disable_isr
, &frame_done_completion
,
1804 DISPC_IRQ_EVSYNC_EVEN
| DISPC_IRQ_EVSYNC_ODD
);
1806 DSSERR("failed to register EVSYNC isr\n");
1808 _enable_digit_out(enable
);
1810 /* XXX I understand from TRM that we should only wait for the
1811 * current field to complete. But it seems we have to wait
1812 * for both fields */
1813 if (!wait_for_completion_timeout(&frame_done_completion
,
1814 msecs_to_jiffies(100)))
1815 DSSERR("timeout waiting for EVSYNC\n");
1817 if (!wait_for_completion_timeout(&frame_done_completion
,
1818 msecs_to_jiffies(100)))
1819 DSSERR("timeout waiting for EVSYNC\n");
1821 r
= omap_dispc_unregister_isr(dispc_disable_isr
,
1822 &frame_done_completion
,
1823 DISPC_IRQ_EVSYNC_EVEN
| DISPC_IRQ_EVSYNC_ODD
);
1825 DSSERR("failed to unregister EVSYNC isr\n");
1828 unsigned long flags
;
1829 spin_lock_irqsave(&dispc
.irq_lock
, flags
);
1830 dispc
.irq_error_mask
= DISPC_IRQ_MASK_ERROR
;
1831 dispc_write_reg(DISPC_IRQSTATUS
, DISPC_IRQ_SYNC_LOST_DIGIT
);
1832 _omap_dispc_set_irqs();
1833 spin_unlock_irqrestore(&dispc
.irq_lock
, flags
);
1839 void dispc_lcd_enable_signal_polarity(bool act_high
)
1842 REG_FLD_MOD(DISPC_CONTROL
, act_high
? 1 : 0, 29, 29);
1846 void dispc_lcd_enable_signal(bool enable
)
1849 REG_FLD_MOD(DISPC_CONTROL
, enable
? 1 : 0, 28, 28);
1853 void dispc_pck_free_enable(bool enable
)
1856 REG_FLD_MOD(DISPC_CONTROL
, enable
? 1 : 0, 27, 27);
1860 void dispc_enable_fifohandcheck(bool enable
)
1863 REG_FLD_MOD(DISPC_CONFIG
, enable
? 1 : 0, 16, 16);
1868 void dispc_set_lcd_display_type(enum omap_lcd_display_type type
)
1873 case OMAP_DSS_LCD_DISPLAY_STN
:
1877 case OMAP_DSS_LCD_DISPLAY_TFT
:
1887 REG_FLD_MOD(DISPC_CONTROL
, mode
, 3, 3);
1891 void dispc_set_loadmode(enum omap_dss_load_mode mode
)
1894 REG_FLD_MOD(DISPC_CONFIG
, mode
, 2, 1);
1899 void dispc_set_default_color(enum omap_channel channel
, u32 color
)
1901 const struct dispc_reg def_reg
[] = { DISPC_DEFAULT_COLOR0
,
1902 DISPC_DEFAULT_COLOR1
};
1905 dispc_write_reg(def_reg
[channel
], color
);
1909 u32
dispc_get_default_color(enum omap_channel channel
)
1911 const struct dispc_reg def_reg
[] = { DISPC_DEFAULT_COLOR0
,
1912 DISPC_DEFAULT_COLOR1
};
1915 BUG_ON(channel
!= OMAP_DSS_CHANNEL_DIGIT
&&
1916 channel
!= OMAP_DSS_CHANNEL_LCD
);
1919 l
= dispc_read_reg(def_reg
[channel
]);
1925 void dispc_set_trans_key(enum omap_channel ch
,
1926 enum omap_dss_trans_key_type type
,
1929 const struct dispc_reg tr_reg
[] = {
1930 DISPC_TRANS_COLOR0
, DISPC_TRANS_COLOR1
};
1933 if (ch
== OMAP_DSS_CHANNEL_LCD
)
1934 REG_FLD_MOD(DISPC_CONFIG
, type
, 11, 11);
1935 else /* OMAP_DSS_CHANNEL_DIGIT */
1936 REG_FLD_MOD(DISPC_CONFIG
, type
, 13, 13);
1938 dispc_write_reg(tr_reg
[ch
], trans_key
);
1942 void dispc_get_trans_key(enum omap_channel ch
,
1943 enum omap_dss_trans_key_type
*type
,
1946 const struct dispc_reg tr_reg
[] = {
1947 DISPC_TRANS_COLOR0
, DISPC_TRANS_COLOR1
};
1951 if (ch
== OMAP_DSS_CHANNEL_LCD
)
1952 *type
= REG_GET(DISPC_CONFIG
, 11, 11);
1953 else if (ch
== OMAP_DSS_CHANNEL_DIGIT
)
1954 *type
= REG_GET(DISPC_CONFIG
, 13, 13);
1960 *trans_key
= dispc_read_reg(tr_reg
[ch
]);
1964 void dispc_enable_trans_key(enum omap_channel ch
, bool enable
)
1967 if (ch
== OMAP_DSS_CHANNEL_LCD
)
1968 REG_FLD_MOD(DISPC_CONFIG
, enable
, 10, 10);
1969 else /* OMAP_DSS_CHANNEL_DIGIT */
1970 REG_FLD_MOD(DISPC_CONFIG
, enable
, 12, 12);
1973 void dispc_enable_alpha_blending(enum omap_channel ch
, bool enable
)
1975 if (cpu_is_omap24xx())
1979 if (ch
== OMAP_DSS_CHANNEL_LCD
)
1980 REG_FLD_MOD(DISPC_CONFIG
, enable
, 18, 18);
1981 else /* OMAP_DSS_CHANNEL_DIGIT */
1982 REG_FLD_MOD(DISPC_CONFIG
, enable
, 19, 19);
1985 bool dispc_alpha_blending_enabled(enum omap_channel ch
)
1989 if (cpu_is_omap24xx())
1993 if (ch
== OMAP_DSS_CHANNEL_LCD
)
1994 enabled
= REG_GET(DISPC_CONFIG
, 18, 18);
1995 else if (ch
== OMAP_DSS_CHANNEL_DIGIT
)
1996 enabled
= REG_GET(DISPC_CONFIG
, 18, 18);
2006 bool dispc_trans_key_enabled(enum omap_channel ch
)
2011 if (ch
== OMAP_DSS_CHANNEL_LCD
)
2012 enabled
= REG_GET(DISPC_CONFIG
, 10, 10);
2013 else if (ch
== OMAP_DSS_CHANNEL_DIGIT
)
2014 enabled
= REG_GET(DISPC_CONFIG
, 12, 12);
2023 void dispc_set_tft_data_lines(u8 data_lines
)
2027 switch (data_lines
) {
2046 REG_FLD_MOD(DISPC_CONTROL
, code
, 9, 8);
2050 void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode
)
2058 case OMAP_DSS_PARALLELMODE_BYPASS
:
2063 case OMAP_DSS_PARALLELMODE_RFBI
:
2068 case OMAP_DSS_PARALLELMODE_DSI
:
2080 l
= dispc_read_reg(DISPC_CONTROL
);
2082 l
= FLD_MOD(l
, stallmode
, 11, 11);
2083 l
= FLD_MOD(l
, gpout0
, 15, 15);
2084 l
= FLD_MOD(l
, gpout1
, 16, 16);
2086 dispc_write_reg(DISPC_CONTROL
, l
);
2091 static bool _dispc_lcd_timings_ok(int hsw
, int hfp
, int hbp
,
2092 int vsw
, int vfp
, int vbp
)
2094 if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0
) {
2095 if (hsw
< 1 || hsw
> 64 ||
2096 hfp
< 1 || hfp
> 256 ||
2097 hbp
< 1 || hbp
> 256 ||
2098 vsw
< 1 || vsw
> 64 ||
2099 vfp
< 0 || vfp
> 255 ||
2100 vbp
< 0 || vbp
> 255)
2103 if (hsw
< 1 || hsw
> 256 ||
2104 hfp
< 1 || hfp
> 4096 ||
2105 hbp
< 1 || hbp
> 4096 ||
2106 vsw
< 1 || vsw
> 256 ||
2107 vfp
< 0 || vfp
> 4095 ||
2108 vbp
< 0 || vbp
> 4095)
2115 bool dispc_lcd_timings_ok(struct omap_video_timings
*timings
)
2117 return _dispc_lcd_timings_ok(timings
->hsw
, timings
->hfp
,
2118 timings
->hbp
, timings
->vsw
,
2119 timings
->vfp
, timings
->vbp
);
2122 static void _dispc_set_lcd_timings(int hsw
, int hfp
, int hbp
,
2123 int vsw
, int vfp
, int vbp
)
2125 u32 timing_h
, timing_v
;
2127 if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0
) {
2128 timing_h
= FLD_VAL(hsw
-1, 5, 0) | FLD_VAL(hfp
-1, 15, 8) |
2129 FLD_VAL(hbp
-1, 27, 20);
2131 timing_v
= FLD_VAL(vsw
-1, 5, 0) | FLD_VAL(vfp
, 15, 8) |
2132 FLD_VAL(vbp
, 27, 20);
2134 timing_h
= FLD_VAL(hsw
-1, 7, 0) | FLD_VAL(hfp
-1, 19, 8) |
2135 FLD_VAL(hbp
-1, 31, 20);
2137 timing_v
= FLD_VAL(vsw
-1, 7, 0) | FLD_VAL(vfp
, 19, 8) |
2138 FLD_VAL(vbp
, 31, 20);
2142 dispc_write_reg(DISPC_TIMING_H
, timing_h
);
2143 dispc_write_reg(DISPC_TIMING_V
, timing_v
);
2147 /* change name to mode? */
2148 void dispc_set_lcd_timings(struct omap_video_timings
*timings
)
2150 unsigned xtot
, ytot
;
2151 unsigned long ht
, vt
;
2153 if (!_dispc_lcd_timings_ok(timings
->hsw
, timings
->hfp
,
2154 timings
->hbp
, timings
->vsw
,
2155 timings
->vfp
, timings
->vbp
))
2158 _dispc_set_lcd_timings(timings
->hsw
, timings
->hfp
, timings
->hbp
,
2159 timings
->vsw
, timings
->vfp
, timings
->vbp
);
2161 dispc_set_lcd_size(timings
->x_res
, timings
->y_res
);
2163 xtot
= timings
->x_res
+ timings
->hfp
+ timings
->hsw
+ timings
->hbp
;
2164 ytot
= timings
->y_res
+ timings
->vfp
+ timings
->vsw
+ timings
->vbp
;
2166 ht
= (timings
->pixel_clock
* 1000) / xtot
;
2167 vt
= (timings
->pixel_clock
* 1000) / xtot
/ ytot
;
2169 DSSDBG("xres %u yres %u\n", timings
->x_res
, timings
->y_res
);
2170 DSSDBG("pck %u\n", timings
->pixel_clock
);
2171 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
2172 timings
->hsw
, timings
->hfp
, timings
->hbp
,
2173 timings
->vsw
, timings
->vfp
, timings
->vbp
);
2175 DSSDBG("hsync %luHz, vsync %luHz\n", ht
, vt
);
2178 static void dispc_set_lcd_divisor(u16 lck_div
, u16 pck_div
)
2180 BUG_ON(lck_div
< 1);
2181 BUG_ON(pck_div
< 2);
2184 dispc_write_reg(DISPC_DIVISOR
,
2185 FLD_VAL(lck_div
, 23, 16) | FLD_VAL(pck_div
, 7, 0));
2189 static void dispc_get_lcd_divisor(int *lck_div
, int *pck_div
)
2192 l
= dispc_read_reg(DISPC_DIVISOR
);
2193 *lck_div
= FLD_GET(l
, 23, 16);
2194 *pck_div
= FLD_GET(l
, 7, 0);
2197 unsigned long dispc_fclk_rate(void)
2199 unsigned long r
= 0;
2201 if (dss_get_dispc_clk_source() == 0)
2202 r
= dss_clk_get_rate(DSS_CLK_FCK1
);
2204 #ifdef CONFIG_OMAP2_DSS_DSI
2205 r
= dsi_get_dsi1_pll_rate();
2212 unsigned long dispc_lclk_rate(void)
2218 l
= dispc_read_reg(DISPC_DIVISOR
);
2220 lcd
= FLD_GET(l
, 23, 16);
2222 r
= dispc_fclk_rate();
2227 unsigned long dispc_pclk_rate(void)
2233 l
= dispc_read_reg(DISPC_DIVISOR
);
2235 lcd
= FLD_GET(l
, 23, 16);
2236 pcd
= FLD_GET(l
, 7, 0);
2238 r
= dispc_fclk_rate();
2240 return r
/ lcd
/ pcd
;
2243 void dispc_dump_clocks(struct seq_file
*s
)
2249 dispc_get_lcd_divisor(&lcd
, &pcd
);
2251 seq_printf(s
, "- DISPC -\n");
2253 seq_printf(s
, "dispc fclk source = %s\n",
2254 dss_get_dispc_clk_source() == 0 ?
2255 "dss1_alwon_fclk" : "dsi1_pll_fclk");
2257 seq_printf(s
, "fck\t\t%-16lu\n", dispc_fclk_rate());
2258 seq_printf(s
, "lck\t\t%-16lulck div\t%u\n", dispc_lclk_rate(), lcd
);
2259 seq_printf(s
, "pck\t\t%-16lupck div\t%u\n", dispc_pclk_rate(), pcd
);
2264 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2265 void dispc_dump_irqs(struct seq_file
*s
)
2267 unsigned long flags
;
2268 struct dispc_irq_stats stats
;
2270 spin_lock_irqsave(&dispc
.irq_stats_lock
, flags
);
2272 stats
= dispc
.irq_stats
;
2273 memset(&dispc
.irq_stats
, 0, sizeof(dispc
.irq_stats
));
2274 dispc
.irq_stats
.last_reset
= jiffies
;
2276 spin_unlock_irqrestore(&dispc
.irq_stats_lock
, flags
);
2278 seq_printf(s
, "period %u ms\n",
2279 jiffies_to_msecs(jiffies
- stats
.last_reset
));
2281 seq_printf(s
, "irqs %d\n", stats
.irq_count
);
2283 seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
2289 PIS(ACBIAS_COUNT_STAT
);
2291 PIS(GFX_FIFO_UNDERFLOW
);
2293 PIS(PAL_GAMMA_MASK
);
2295 PIS(VID1_FIFO_UNDERFLOW
);
2297 PIS(VID2_FIFO_UNDERFLOW
);
2300 PIS(SYNC_LOST_DIGIT
);
2306 void dispc_dump_regs(struct seq_file
*s
)
2308 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
2310 dss_clk_enable(DSS_CLK_ICK
| DSS_CLK_FCK1
);
2312 DUMPREG(DISPC_REVISION
);
2313 DUMPREG(DISPC_SYSCONFIG
);
2314 DUMPREG(DISPC_SYSSTATUS
);
2315 DUMPREG(DISPC_IRQSTATUS
);
2316 DUMPREG(DISPC_IRQENABLE
);
2317 DUMPREG(DISPC_CONTROL
);
2318 DUMPREG(DISPC_CONFIG
);
2319 DUMPREG(DISPC_CAPABLE
);
2320 DUMPREG(DISPC_DEFAULT_COLOR0
);
2321 DUMPREG(DISPC_DEFAULT_COLOR1
);
2322 DUMPREG(DISPC_TRANS_COLOR0
);
2323 DUMPREG(DISPC_TRANS_COLOR1
);
2324 DUMPREG(DISPC_LINE_STATUS
);
2325 DUMPREG(DISPC_LINE_NUMBER
);
2326 DUMPREG(DISPC_TIMING_H
);
2327 DUMPREG(DISPC_TIMING_V
);
2328 DUMPREG(DISPC_POL_FREQ
);
2329 DUMPREG(DISPC_DIVISOR
);
2330 DUMPREG(DISPC_GLOBAL_ALPHA
);
2331 DUMPREG(DISPC_SIZE_DIG
);
2332 DUMPREG(DISPC_SIZE_LCD
);
2334 DUMPREG(DISPC_GFX_BA0
);
2335 DUMPREG(DISPC_GFX_BA1
);
2336 DUMPREG(DISPC_GFX_POSITION
);
2337 DUMPREG(DISPC_GFX_SIZE
);
2338 DUMPREG(DISPC_GFX_ATTRIBUTES
);
2339 DUMPREG(DISPC_GFX_FIFO_THRESHOLD
);
2340 DUMPREG(DISPC_GFX_FIFO_SIZE_STATUS
);
2341 DUMPREG(DISPC_GFX_ROW_INC
);
2342 DUMPREG(DISPC_GFX_PIXEL_INC
);
2343 DUMPREG(DISPC_GFX_WINDOW_SKIP
);
2344 DUMPREG(DISPC_GFX_TABLE_BA
);
2346 DUMPREG(DISPC_DATA_CYCLE1
);
2347 DUMPREG(DISPC_DATA_CYCLE2
);
2348 DUMPREG(DISPC_DATA_CYCLE3
);
2350 DUMPREG(DISPC_CPR_COEF_R
);
2351 DUMPREG(DISPC_CPR_COEF_G
);
2352 DUMPREG(DISPC_CPR_COEF_B
);
2354 DUMPREG(DISPC_GFX_PRELOAD
);
2356 DUMPREG(DISPC_VID_BA0(0));
2357 DUMPREG(DISPC_VID_BA1(0));
2358 DUMPREG(DISPC_VID_POSITION(0));
2359 DUMPREG(DISPC_VID_SIZE(0));
2360 DUMPREG(DISPC_VID_ATTRIBUTES(0));
2361 DUMPREG(DISPC_VID_FIFO_THRESHOLD(0));
2362 DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(0));
2363 DUMPREG(DISPC_VID_ROW_INC(0));
2364 DUMPREG(DISPC_VID_PIXEL_INC(0));
2365 DUMPREG(DISPC_VID_FIR(0));
2366 DUMPREG(DISPC_VID_PICTURE_SIZE(0));
2367 DUMPREG(DISPC_VID_ACCU0(0));
2368 DUMPREG(DISPC_VID_ACCU1(0));
2370 DUMPREG(DISPC_VID_BA0(1));
2371 DUMPREG(DISPC_VID_BA1(1));
2372 DUMPREG(DISPC_VID_POSITION(1));
2373 DUMPREG(DISPC_VID_SIZE(1));
2374 DUMPREG(DISPC_VID_ATTRIBUTES(1));
2375 DUMPREG(DISPC_VID_FIFO_THRESHOLD(1));
2376 DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(1));
2377 DUMPREG(DISPC_VID_ROW_INC(1));
2378 DUMPREG(DISPC_VID_PIXEL_INC(1));
2379 DUMPREG(DISPC_VID_FIR(1));
2380 DUMPREG(DISPC_VID_PICTURE_SIZE(1));
2381 DUMPREG(DISPC_VID_ACCU0(1));
2382 DUMPREG(DISPC_VID_ACCU1(1));
2384 DUMPREG(DISPC_VID_FIR_COEF_H(0, 0));
2385 DUMPREG(DISPC_VID_FIR_COEF_H(0, 1));
2386 DUMPREG(DISPC_VID_FIR_COEF_H(0, 2));
2387 DUMPREG(DISPC_VID_FIR_COEF_H(0, 3));
2388 DUMPREG(DISPC_VID_FIR_COEF_H(0, 4));
2389 DUMPREG(DISPC_VID_FIR_COEF_H(0, 5));
2390 DUMPREG(DISPC_VID_FIR_COEF_H(0, 6));
2391 DUMPREG(DISPC_VID_FIR_COEF_H(0, 7));
2392 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 0));
2393 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 1));
2394 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 2));
2395 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 3));
2396 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 4));
2397 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 5));
2398 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 6));
2399 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 7));
2400 DUMPREG(DISPC_VID_CONV_COEF(0, 0));
2401 DUMPREG(DISPC_VID_CONV_COEF(0, 1));
2402 DUMPREG(DISPC_VID_CONV_COEF(0, 2));
2403 DUMPREG(DISPC_VID_CONV_COEF(0, 3));
2404 DUMPREG(DISPC_VID_CONV_COEF(0, 4));
2405 DUMPREG(DISPC_VID_FIR_COEF_V(0, 0));
2406 DUMPREG(DISPC_VID_FIR_COEF_V(0, 1));
2407 DUMPREG(DISPC_VID_FIR_COEF_V(0, 2));
2408 DUMPREG(DISPC_VID_FIR_COEF_V(0, 3));
2409 DUMPREG(DISPC_VID_FIR_COEF_V(0, 4));
2410 DUMPREG(DISPC_VID_FIR_COEF_V(0, 5));
2411 DUMPREG(DISPC_VID_FIR_COEF_V(0, 6));
2412 DUMPREG(DISPC_VID_FIR_COEF_V(0, 7));
2414 DUMPREG(DISPC_VID_FIR_COEF_H(1, 0));
2415 DUMPREG(DISPC_VID_FIR_COEF_H(1, 1));
2416 DUMPREG(DISPC_VID_FIR_COEF_H(1, 2));
2417 DUMPREG(DISPC_VID_FIR_COEF_H(1, 3));
2418 DUMPREG(DISPC_VID_FIR_COEF_H(1, 4));
2419 DUMPREG(DISPC_VID_FIR_COEF_H(1, 5));
2420 DUMPREG(DISPC_VID_FIR_COEF_H(1, 6));
2421 DUMPREG(DISPC_VID_FIR_COEF_H(1, 7));
2422 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 0));
2423 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 1));
2424 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 2));
2425 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 3));
2426 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 4));
2427 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 5));
2428 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 6));
2429 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 7));
2430 DUMPREG(DISPC_VID_CONV_COEF(1, 0));
2431 DUMPREG(DISPC_VID_CONV_COEF(1, 1));
2432 DUMPREG(DISPC_VID_CONV_COEF(1, 2));
2433 DUMPREG(DISPC_VID_CONV_COEF(1, 3));
2434 DUMPREG(DISPC_VID_CONV_COEF(1, 4));
2435 DUMPREG(DISPC_VID_FIR_COEF_V(1, 0));
2436 DUMPREG(DISPC_VID_FIR_COEF_V(1, 1));
2437 DUMPREG(DISPC_VID_FIR_COEF_V(1, 2));
2438 DUMPREG(DISPC_VID_FIR_COEF_V(1, 3));
2439 DUMPREG(DISPC_VID_FIR_COEF_V(1, 4));
2440 DUMPREG(DISPC_VID_FIR_COEF_V(1, 5));
2441 DUMPREG(DISPC_VID_FIR_COEF_V(1, 6));
2442 DUMPREG(DISPC_VID_FIR_COEF_V(1, 7));
2444 DUMPREG(DISPC_VID_PRELOAD(0));
2445 DUMPREG(DISPC_VID_PRELOAD(1));
2447 dss_clk_disable(DSS_CLK_ICK
| DSS_CLK_FCK1
);
2451 static void _dispc_set_pol_freq(bool onoff
, bool rf
, bool ieo
, bool ipc
,
2452 bool ihs
, bool ivs
, u8 acbi
, u8 acb
)
2456 DSSDBG("onoff %d rf %d ieo %d ipc %d ihs %d ivs %d acbi %d acb %d\n",
2457 onoff
, rf
, ieo
, ipc
, ihs
, ivs
, acbi
, acb
);
2459 l
|= FLD_VAL(onoff
, 17, 17);
2460 l
|= FLD_VAL(rf
, 16, 16);
2461 l
|= FLD_VAL(ieo
, 15, 15);
2462 l
|= FLD_VAL(ipc
, 14, 14);
2463 l
|= FLD_VAL(ihs
, 13, 13);
2464 l
|= FLD_VAL(ivs
, 12, 12);
2465 l
|= FLD_VAL(acbi
, 11, 8);
2466 l
|= FLD_VAL(acb
, 7, 0);
2469 dispc_write_reg(DISPC_POL_FREQ
, l
);
2473 void dispc_set_pol_freq(enum omap_panel_config config
, u8 acbi
, u8 acb
)
2475 _dispc_set_pol_freq((config
& OMAP_DSS_LCD_ONOFF
) != 0,
2476 (config
& OMAP_DSS_LCD_RF
) != 0,
2477 (config
& OMAP_DSS_LCD_IEO
) != 0,
2478 (config
& OMAP_DSS_LCD_IPC
) != 0,
2479 (config
& OMAP_DSS_LCD_IHS
) != 0,
2480 (config
& OMAP_DSS_LCD_IVS
) != 0,
2484 /* with fck as input clock rate, find dispc dividers that produce req_pck */
2485 void dispc_find_clk_divs(bool is_tft
, unsigned long req_pck
, unsigned long fck
,
2486 struct dispc_clock_info
*cinfo
)
2488 u16 pcd_min
= is_tft
? 2 : 3;
2489 unsigned long best_pck
;
2490 u16 best_ld
, cur_ld
;
2491 u16 best_pd
, cur_pd
;
2497 for (cur_ld
= 1; cur_ld
<= 255; ++cur_ld
) {
2498 unsigned long lck
= fck
/ cur_ld
;
2500 for (cur_pd
= pcd_min
; cur_pd
<= 255; ++cur_pd
) {
2501 unsigned long pck
= lck
/ cur_pd
;
2502 long old_delta
= abs(best_pck
- req_pck
);
2503 long new_delta
= abs(pck
- req_pck
);
2505 if (best_pck
== 0 || new_delta
< old_delta
) {
2518 if (lck
/ pcd_min
< req_pck
)
2523 cinfo
->lck_div
= best_ld
;
2524 cinfo
->pck_div
= best_pd
;
2525 cinfo
->lck
= fck
/ cinfo
->lck_div
;
2526 cinfo
->pck
= cinfo
->lck
/ cinfo
->pck_div
;
2529 /* calculate clock rates using dividers in cinfo */
2530 int dispc_calc_clock_rates(unsigned long dispc_fclk_rate
,
2531 struct dispc_clock_info
*cinfo
)
2533 if (cinfo
->lck_div
> 255 || cinfo
->lck_div
== 0)
2535 if (cinfo
->pck_div
< 2 || cinfo
->pck_div
> 255)
2538 cinfo
->lck
= dispc_fclk_rate
/ cinfo
->lck_div
;
2539 cinfo
->pck
= cinfo
->lck
/ cinfo
->pck_div
;
2544 int dispc_set_clock_div(struct dispc_clock_info
*cinfo
)
2546 DSSDBG("lck = %lu (%u)\n", cinfo
->lck
, cinfo
->lck_div
);
2547 DSSDBG("pck = %lu (%u)\n", cinfo
->pck
, cinfo
->pck_div
);
2549 dispc_set_lcd_divisor(cinfo
->lck_div
, cinfo
->pck_div
);
2554 int dispc_get_clock_div(struct dispc_clock_info
*cinfo
)
2558 fck
= dispc_fclk_rate();
2560 cinfo
->lck_div
= REG_GET(DISPC_DIVISOR
, 23, 16);
2561 cinfo
->pck_div
= REG_GET(DISPC_DIVISOR
, 7, 0);
2563 cinfo
->lck
= fck
/ cinfo
->lck_div
;
2564 cinfo
->pck
= cinfo
->lck
/ cinfo
->pck_div
;
2569 /* dispc.irq_lock has to be locked by the caller */
2570 static void _omap_dispc_set_irqs(void)
2575 struct omap_dispc_isr_data
*isr_data
;
2577 mask
= dispc
.irq_error_mask
;
2579 for (i
= 0; i
< DISPC_MAX_NR_ISRS
; i
++) {
2580 isr_data
= &dispc
.registered_isr
[i
];
2582 if (isr_data
->isr
== NULL
)
2585 mask
|= isr_data
->mask
;
2590 old_mask
= dispc_read_reg(DISPC_IRQENABLE
);
2591 /* clear the irqstatus for newly enabled irqs */
2592 dispc_write_reg(DISPC_IRQSTATUS
, (mask
^ old_mask
) & mask
);
2594 dispc_write_reg(DISPC_IRQENABLE
, mask
);
2599 int omap_dispc_register_isr(omap_dispc_isr_t isr
, void *arg
, u32 mask
)
2603 unsigned long flags
;
2604 struct omap_dispc_isr_data
*isr_data
;
2609 spin_lock_irqsave(&dispc
.irq_lock
, flags
);
2611 /* check for duplicate entry */
2612 for (i
= 0; i
< DISPC_MAX_NR_ISRS
; i
++) {
2613 isr_data
= &dispc
.registered_isr
[i
];
2614 if (isr_data
->isr
== isr
&& isr_data
->arg
== arg
&&
2615 isr_data
->mask
== mask
) {
2624 for (i
= 0; i
< DISPC_MAX_NR_ISRS
; i
++) {
2625 isr_data
= &dispc
.registered_isr
[i
];
2627 if (isr_data
->isr
!= NULL
)
2630 isr_data
->isr
= isr
;
2631 isr_data
->arg
= arg
;
2632 isr_data
->mask
= mask
;
2638 _omap_dispc_set_irqs();
2640 spin_unlock_irqrestore(&dispc
.irq_lock
, flags
);
2644 spin_unlock_irqrestore(&dispc
.irq_lock
, flags
);
2648 EXPORT_SYMBOL(omap_dispc_register_isr
);
2650 int omap_dispc_unregister_isr(omap_dispc_isr_t isr
, void *arg
, u32 mask
)
2653 unsigned long flags
;
2655 struct omap_dispc_isr_data
*isr_data
;
2657 spin_lock_irqsave(&dispc
.irq_lock
, flags
);
2659 for (i
= 0; i
< DISPC_MAX_NR_ISRS
; i
++) {
2660 isr_data
= &dispc
.registered_isr
[i
];
2661 if (isr_data
->isr
!= isr
|| isr_data
->arg
!= arg
||
2662 isr_data
->mask
!= mask
)
2665 /* found the correct isr */
2667 isr_data
->isr
= NULL
;
2668 isr_data
->arg
= NULL
;
2676 _omap_dispc_set_irqs();
2678 spin_unlock_irqrestore(&dispc
.irq_lock
, flags
);
2682 EXPORT_SYMBOL(omap_dispc_unregister_isr
);
2685 static void print_irq_status(u32 status
)
2687 if ((status
& dispc
.irq_error_mask
) == 0)
2690 printk(KERN_DEBUG
"DISPC IRQ: 0x%x: ", status
);
2693 if (status & DISPC_IRQ_##x) \
2695 PIS(GFX_FIFO_UNDERFLOW
);
2697 PIS(VID1_FIFO_UNDERFLOW
);
2698 PIS(VID2_FIFO_UNDERFLOW
);
2700 PIS(SYNC_LOST_DIGIT
);
2707 /* Called from dss.c. Note that we don't touch clocks here,
2708 * but we presume they are on because we got an IRQ. However,
2709 * an irq handler may turn the clocks off, so we may not have
2710 * clock later in the function. */
2711 void dispc_irq_handler(void)
2715 u32 handledirqs
= 0;
2716 u32 unhandled_errors
;
2717 struct omap_dispc_isr_data
*isr_data
;
2718 struct omap_dispc_isr_data registered_isr
[DISPC_MAX_NR_ISRS
];
2720 spin_lock(&dispc
.irq_lock
);
2722 irqstatus
= dispc_read_reg(DISPC_IRQSTATUS
);
2724 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2725 spin_lock(&dispc
.irq_stats_lock
);
2726 dispc
.irq_stats
.irq_count
++;
2727 dss_collect_irq_stats(irqstatus
, dispc
.irq_stats
.irqs
);
2728 spin_unlock(&dispc
.irq_stats_lock
);
2733 print_irq_status(irqstatus
);
2735 /* Ack the interrupt. Do it here before clocks are possibly turned
2737 dispc_write_reg(DISPC_IRQSTATUS
, irqstatus
);
2738 /* flush posted write */
2739 dispc_read_reg(DISPC_IRQSTATUS
);
2741 /* make a copy and unlock, so that isrs can unregister
2743 memcpy(registered_isr
, dispc
.registered_isr
,
2744 sizeof(registered_isr
));
2746 spin_unlock(&dispc
.irq_lock
);
2748 for (i
= 0; i
< DISPC_MAX_NR_ISRS
; i
++) {
2749 isr_data
= ®istered_isr
[i
];
2754 if (isr_data
->mask
& irqstatus
) {
2755 isr_data
->isr(isr_data
->arg
, irqstatus
);
2756 handledirqs
|= isr_data
->mask
;
2760 spin_lock(&dispc
.irq_lock
);
2762 unhandled_errors
= irqstatus
& ~handledirqs
& dispc
.irq_error_mask
;
2764 if (unhandled_errors
) {
2765 dispc
.error_irqs
|= unhandled_errors
;
2767 dispc
.irq_error_mask
&= ~unhandled_errors
;
2768 _omap_dispc_set_irqs();
2770 schedule_work(&dispc
.error_work
);
2773 spin_unlock(&dispc
.irq_lock
);
2776 static void dispc_error_worker(struct work_struct
*work
)
2780 unsigned long flags
;
2782 spin_lock_irqsave(&dispc
.irq_lock
, flags
);
2783 errors
= dispc
.error_irqs
;
2784 dispc
.error_irqs
= 0;
2785 spin_unlock_irqrestore(&dispc
.irq_lock
, flags
);
2787 if (errors
& DISPC_IRQ_GFX_FIFO_UNDERFLOW
) {
2788 DSSERR("GFX_FIFO_UNDERFLOW, disabling GFX\n");
2789 for (i
= 0; i
< omap_dss_get_num_overlays(); ++i
) {
2790 struct omap_overlay
*ovl
;
2791 ovl
= omap_dss_get_overlay(i
);
2793 if (!(ovl
->caps
& OMAP_DSS_OVL_CAP_DISPC
))
2797 dispc_enable_plane(ovl
->id
, 0);
2798 dispc_go(ovl
->manager
->id
);
2805 if (errors
& DISPC_IRQ_VID1_FIFO_UNDERFLOW
) {
2806 DSSERR("VID1_FIFO_UNDERFLOW, disabling VID1\n");
2807 for (i
= 0; i
< omap_dss_get_num_overlays(); ++i
) {
2808 struct omap_overlay
*ovl
;
2809 ovl
= omap_dss_get_overlay(i
);
2811 if (!(ovl
->caps
& OMAP_DSS_OVL_CAP_DISPC
))
2815 dispc_enable_plane(ovl
->id
, 0);
2816 dispc_go(ovl
->manager
->id
);
2823 if (errors
& DISPC_IRQ_VID2_FIFO_UNDERFLOW
) {
2824 DSSERR("VID2_FIFO_UNDERFLOW, disabling VID2\n");
2825 for (i
= 0; i
< omap_dss_get_num_overlays(); ++i
) {
2826 struct omap_overlay
*ovl
;
2827 ovl
= omap_dss_get_overlay(i
);
2829 if (!(ovl
->caps
& OMAP_DSS_OVL_CAP_DISPC
))
2833 dispc_enable_plane(ovl
->id
, 0);
2834 dispc_go(ovl
->manager
->id
);
2841 if (errors
& DISPC_IRQ_SYNC_LOST
) {
2842 struct omap_overlay_manager
*manager
= NULL
;
2843 bool enable
= false;
2845 DSSERR("SYNC_LOST, disabling LCD\n");
2847 for (i
= 0; i
< omap_dss_get_num_overlay_managers(); ++i
) {
2848 struct omap_overlay_manager
*mgr
;
2849 mgr
= omap_dss_get_overlay_manager(i
);
2851 if (mgr
->id
== OMAP_DSS_CHANNEL_LCD
) {
2853 enable
= mgr
->device
->state
==
2854 OMAP_DSS_DISPLAY_ACTIVE
;
2855 mgr
->device
->disable(mgr
->device
);
2861 for (i
= 0; i
< omap_dss_get_num_overlays(); ++i
) {
2862 struct omap_overlay
*ovl
;
2863 ovl
= omap_dss_get_overlay(i
);
2865 if (!(ovl
->caps
& OMAP_DSS_OVL_CAP_DISPC
))
2868 if (ovl
->id
!= 0 && ovl
->manager
== manager
)
2869 dispc_enable_plane(ovl
->id
, 0);
2872 dispc_go(manager
->id
);
2875 manager
->device
->enable(manager
->device
);
2879 if (errors
& DISPC_IRQ_SYNC_LOST_DIGIT
) {
2880 struct omap_overlay_manager
*manager
= NULL
;
2881 bool enable
= false;
2883 DSSERR("SYNC_LOST_DIGIT, disabling TV\n");
2885 for (i
= 0; i
< omap_dss_get_num_overlay_managers(); ++i
) {
2886 struct omap_overlay_manager
*mgr
;
2887 mgr
= omap_dss_get_overlay_manager(i
);
2889 if (mgr
->id
== OMAP_DSS_CHANNEL_DIGIT
) {
2891 enable
= mgr
->device
->state
==
2892 OMAP_DSS_DISPLAY_ACTIVE
;
2893 mgr
->device
->disable(mgr
->device
);
2899 for (i
= 0; i
< omap_dss_get_num_overlays(); ++i
) {
2900 struct omap_overlay
*ovl
;
2901 ovl
= omap_dss_get_overlay(i
);
2903 if (!(ovl
->caps
& OMAP_DSS_OVL_CAP_DISPC
))
2906 if (ovl
->id
!= 0 && ovl
->manager
== manager
)
2907 dispc_enable_plane(ovl
->id
, 0);
2910 dispc_go(manager
->id
);
2913 manager
->device
->enable(manager
->device
);
2917 if (errors
& DISPC_IRQ_OCP_ERR
) {
2918 DSSERR("OCP_ERR\n");
2919 for (i
= 0; i
< omap_dss_get_num_overlay_managers(); ++i
) {
2920 struct omap_overlay_manager
*mgr
;
2921 mgr
= omap_dss_get_overlay_manager(i
);
2923 if (mgr
->caps
& OMAP_DSS_OVL_CAP_DISPC
)
2924 mgr
->device
->disable(mgr
->device
);
2928 spin_lock_irqsave(&dispc
.irq_lock
, flags
);
2929 dispc
.irq_error_mask
|= errors
;
2930 _omap_dispc_set_irqs();
2931 spin_unlock_irqrestore(&dispc
.irq_lock
, flags
);
2934 int omap_dispc_wait_for_irq_timeout(u32 irqmask
, unsigned long timeout
)
2936 void dispc_irq_wait_handler(void *data
, u32 mask
)
2938 complete((struct completion
*)data
);
2942 DECLARE_COMPLETION_ONSTACK(completion
);
2944 r
= omap_dispc_register_isr(dispc_irq_wait_handler
, &completion
,
2950 timeout
= wait_for_completion_timeout(&completion
, timeout
);
2952 omap_dispc_unregister_isr(dispc_irq_wait_handler
, &completion
, irqmask
);
2957 if (timeout
== -ERESTARTSYS
)
2958 return -ERESTARTSYS
;
2963 int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask
,
2964 unsigned long timeout
)
2966 void dispc_irq_wait_handler(void *data
, u32 mask
)
2968 complete((struct completion
*)data
);
2972 DECLARE_COMPLETION_ONSTACK(completion
);
2974 r
= omap_dispc_register_isr(dispc_irq_wait_handler
, &completion
,
2980 timeout
= wait_for_completion_interruptible_timeout(&completion
,
2983 omap_dispc_unregister_isr(dispc_irq_wait_handler
, &completion
, irqmask
);
2988 if (timeout
== -ERESTARTSYS
)
2989 return -ERESTARTSYS
;
2994 #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
2995 void dispc_fake_vsync_irq(void)
2997 u32 irqstatus
= DISPC_IRQ_VSYNC
;
3000 local_irq_disable();
3002 for (i
= 0; i
< DISPC_MAX_NR_ISRS
; i
++) {
3003 struct omap_dispc_isr_data
*isr_data
;
3004 isr_data
= &dispc
.registered_isr
[i
];
3009 if (isr_data
->mask
& irqstatus
)
3010 isr_data
->isr(isr_data
->arg
, irqstatus
);
3017 static void _omap_dispc_initialize_irq(void)
3019 unsigned long flags
;
3021 spin_lock_irqsave(&dispc
.irq_lock
, flags
);
3023 memset(dispc
.registered_isr
, 0, sizeof(dispc
.registered_isr
));
3025 dispc
.irq_error_mask
= DISPC_IRQ_MASK_ERROR
;
3027 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
3029 dispc_write_reg(DISPC_IRQSTATUS
, dispc_read_reg(DISPC_IRQSTATUS
));
3031 _omap_dispc_set_irqs();
3033 spin_unlock_irqrestore(&dispc
.irq_lock
, flags
);
3036 void dispc_enable_sidle(void)
3038 REG_FLD_MOD(DISPC_SYSCONFIG
, 2, 4, 3); /* SIDLEMODE: smart idle */
3041 void dispc_disable_sidle(void)
3043 REG_FLD_MOD(DISPC_SYSCONFIG
, 1, 4, 3); /* SIDLEMODE: no idle */
3046 static void _omap_dispc_initial_config(void)
3050 l
= dispc_read_reg(DISPC_SYSCONFIG
);
3051 l
= FLD_MOD(l
, 2, 13, 12); /* MIDLEMODE: smart standby */
3052 l
= FLD_MOD(l
, 2, 4, 3); /* SIDLEMODE: smart idle */
3053 l
= FLD_MOD(l
, 1, 2, 2); /* ENWAKEUP */
3054 l
= FLD_MOD(l
, 1, 0, 0); /* AUTOIDLE */
3055 dispc_write_reg(DISPC_SYSCONFIG
, l
);
3058 REG_FLD_MOD(DISPC_CONFIG
, 1, 9, 9);
3060 /* L3 firewall setting: enable access to OCM RAM */
3061 /* XXX this should be somewhere in plat-omap */
3062 if (cpu_is_omap24xx())
3063 __raw_writel(0x402000b0, OMAP2_L3_IO_ADDRESS(0x680050a0));
3065 _dispc_setup_color_conv_coef();
3067 dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY
);
3069 dispc_read_plane_fifo_sizes();
3072 int dispc_init(void)
3076 spin_lock_init(&dispc
.irq_lock
);
3078 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3079 spin_lock_init(&dispc
.irq_stats_lock
);
3080 dispc
.irq_stats
.last_reset
= jiffies
;
3083 INIT_WORK(&dispc
.error_work
, dispc_error_worker
);
3085 dispc
.base
= ioremap(DISPC_BASE
, DISPC_SZ_REGS
);
3087 DSSERR("can't ioremap DISPC\n");
3093 _omap_dispc_initial_config();
3095 _omap_dispc_initialize_irq();
3097 dispc_save_context();
3099 rev
= dispc_read_reg(DISPC_REVISION
);
3100 printk(KERN_INFO
"OMAP DISPC rev %d.%d\n",
3101 FLD_GET(rev
, 7, 4), FLD_GET(rev
, 3, 0));
3108 void dispc_exit(void)
3110 iounmap(dispc
.base
);
3113 int dispc_enable_plane(enum omap_plane plane
, bool enable
)
3115 DSSDBG("dispc_enable_plane %d, %d\n", plane
, enable
);
3118 _dispc_enable_plane(plane
, enable
);
3124 int dispc_setup_plane(enum omap_plane plane
,
3125 u32 paddr
, u16 screen_width
,
3126 u16 pos_x
, u16 pos_y
,
3127 u16 width
, u16 height
,
3128 u16 out_width
, u16 out_height
,
3129 enum omap_color_mode color_mode
,
3131 enum omap_dss_rotation_type rotation_type
,
3132 u8 rotation
, bool mirror
, u8 global_alpha
)
3136 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> "
3137 "%dx%d, ilace %d, cmode %x, rot %d, mir %d\n",
3138 plane
, paddr
, screen_width
, pos_x
, pos_y
,
3140 out_width
, out_height
,
3146 r
= _dispc_setup_plane(plane
,
3147 paddr
, screen_width
,
3150 out_width
, out_height
,