aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dispc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r--drivers/video/omap2/dss/dispc.c494
1 files changed, 256 insertions, 238 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 397d4eee11bb..5b289c5f695b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -119,6 +119,97 @@ enum omap_color_component {
119 DISPC_COLOR_COMPONENT_UV = 1 << 1, 119 DISPC_COLOR_COMPONENT_UV = 1 << 1,
120}; 120};
121 121
122enum mgr_reg_fields {
123 DISPC_MGR_FLD_ENABLE,
124 DISPC_MGR_FLD_STNTFT,
125 DISPC_MGR_FLD_GO,
126 DISPC_MGR_FLD_TFTDATALINES,
127 DISPC_MGR_FLD_STALLMODE,
128 DISPC_MGR_FLD_TCKENABLE,
129 DISPC_MGR_FLD_TCKSELECTION,
130 DISPC_MGR_FLD_CPR,
131 DISPC_MGR_FLD_FIFOHANDCHECK,
132 /* used to maintain a count of the above fields */
133 DISPC_MGR_FLD_NUM,
134};
135
136static const struct {
137 const char *name;
138 u32 vsync_irq;
139 u32 framedone_irq;
140 u32 sync_lost_irq;
141 struct reg_field reg_desc[DISPC_MGR_FLD_NUM];
142} mgr_desc[] = {
143 [OMAP_DSS_CHANNEL_LCD] = {
144 .name = "LCD",
145 .vsync_irq = DISPC_IRQ_VSYNC,
146 .framedone_irq = DISPC_IRQ_FRAMEDONE,
147 .sync_lost_irq = DISPC_IRQ_SYNC_LOST,
148 .reg_desc = {
149 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 0, 0 },
150 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL, 3, 3 },
151 [DISPC_MGR_FLD_GO] = { DISPC_CONTROL, 5, 5 },
152 [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL, 9, 8 },
153 [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL, 11, 11 },
154 [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG, 10, 10 },
155 [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG, 11, 11 },
156 [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG, 15, 15 },
157 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG, 16, 16 },
158 },
159 },
160 [OMAP_DSS_CHANNEL_DIGIT] = {
161 .name = "DIGIT",
162 .vsync_irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN,
163 .framedone_irq = 0,
164 .sync_lost_irq = DISPC_IRQ_SYNC_LOST_DIGIT,
165 .reg_desc = {
166 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 1, 1 },
167 [DISPC_MGR_FLD_STNTFT] = { },
168 [DISPC_MGR_FLD_GO] = { DISPC_CONTROL, 6, 6 },
169 [DISPC_MGR_FLD_TFTDATALINES] = { },
170 [DISPC_MGR_FLD_STALLMODE] = { },
171 [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG, 12, 12 },
172 [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG, 13, 13 },
173 [DISPC_MGR_FLD_CPR] = { },
174 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG, 16, 16 },
175 },
176 },
177 [OMAP_DSS_CHANNEL_LCD2] = {
178 .name = "LCD2",
179 .vsync_irq = DISPC_IRQ_VSYNC2,
180 .framedone_irq = DISPC_IRQ_FRAMEDONE2,
181 .sync_lost_irq = DISPC_IRQ_SYNC_LOST2,
182 .reg_desc = {
183 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL2, 0, 0 },
184 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL2, 3, 3 },
185 [DISPC_MGR_FLD_GO] = { DISPC_CONTROL2, 5, 5 },
186 [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL2, 9, 8 },
187 [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL2, 11, 11 },
188 [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG2, 10, 10 },
189 [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG2, 11, 11 },
190 [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG2, 15, 15 },
191 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG2, 16, 16 },
192 },
193 },
194 [OMAP_DSS_CHANNEL_LCD3] = {
195 .name = "LCD3",
196 .vsync_irq = DISPC_IRQ_VSYNC3,
197 .framedone_irq = DISPC_IRQ_FRAMEDONE3,
198 .sync_lost_irq = DISPC_IRQ_SYNC_LOST3,
199 .reg_desc = {
200 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL3, 0, 0 },
201 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL3, 3, 3 },
202 [DISPC_MGR_FLD_GO] = { DISPC_CONTROL3, 5, 5 },
203 [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL3, 9, 8 },
204 [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL3, 11, 11 },
205 [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG3, 10, 10 },
206 [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG3, 11, 11 },
207 [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG3, 15, 15 },
208 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG3, 16, 16 },
209 },
210 },
211};
212
122static void _omap_dispc_set_irqs(void); 213static void _omap_dispc_set_irqs(void);
123 214
124static inline void dispc_write_reg(const u16 idx, u32 val) 215static inline void dispc_write_reg(const u16 idx, u32 val)
@@ -131,6 +222,18 @@ static inline u32 dispc_read_reg(const u16 idx)
131 return __raw_readl(dispc.base + idx); 222 return __raw_readl(dispc.base + idx);
132} 223}
133 224
225static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
226{
227 const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
228 return REG_GET(rfld.reg, rfld.high, rfld.low);
229}
230
231static void mgr_fld_write(enum omap_channel channel,
232 enum mgr_reg_fields regfld, int val) {
233 const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
234 REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
235}
236
134#define SR(reg) \ 237#define SR(reg) \
135 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) 238 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
136#define RR(reg) \ 239#define RR(reg) \
@@ -153,6 +256,10 @@ static void dispc_save_context(void)
153 SR(CONTROL2); 256 SR(CONTROL2);
154 SR(CONFIG2); 257 SR(CONFIG2);
155 } 258 }
259 if (dss_has_feature(FEAT_MGR_LCD3)) {
260 SR(CONTROL3);
261 SR(CONFIG3);
262 }
156 263
157 for (i = 0; i < dss_feat_get_num_mgrs(); i++) { 264 for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
158 SR(DEFAULT_COLOR(i)); 265 SR(DEFAULT_COLOR(i));
@@ -266,6 +373,8 @@ static void dispc_restore_context(void)
266 RR(GLOBAL_ALPHA); 373 RR(GLOBAL_ALPHA);
267 if (dss_has_feature(FEAT_MGR_LCD2)) 374 if (dss_has_feature(FEAT_MGR_LCD2))
268 RR(CONFIG2); 375 RR(CONFIG2);
376 if (dss_has_feature(FEAT_MGR_LCD3))
377 RR(CONFIG3);
269 378
270 for (i = 0; i < dss_feat_get_num_mgrs(); i++) { 379 for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
271 RR(DEFAULT_COLOR(i)); 380 RR(DEFAULT_COLOR(i));
@@ -351,6 +460,8 @@ static void dispc_restore_context(void)
351 RR(CONTROL); 460 RR(CONTROL);
352 if (dss_has_feature(FEAT_MGR_LCD2)) 461 if (dss_has_feature(FEAT_MGR_LCD2))
353 RR(CONTROL2); 462 RR(CONTROL2);
463 if (dss_has_feature(FEAT_MGR_LCD3))
464 RR(CONTROL3);
354 /* clear spurious SYNC_LOST_DIGIT interrupts */ 465 /* clear spurious SYNC_LOST_DIGIT interrupts */
355 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 466 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
356 467
@@ -387,101 +498,41 @@ void dispc_runtime_put(void)
387 WARN_ON(r < 0 && r != -ENOSYS); 498 WARN_ON(r < 0 && r != -ENOSYS);
388} 499}
389 500
390static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
391{
392 if (channel == OMAP_DSS_CHANNEL_LCD ||
393 channel == OMAP_DSS_CHANNEL_LCD2)
394 return true;
395 else
396 return false;
397}
398
399u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) 501u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
400{ 502{
401 switch (channel) { 503 return mgr_desc[channel].vsync_irq;
402 case OMAP_DSS_CHANNEL_LCD:
403 return DISPC_IRQ_VSYNC;
404 case OMAP_DSS_CHANNEL_LCD2:
405 return DISPC_IRQ_VSYNC2;
406 case OMAP_DSS_CHANNEL_DIGIT:
407 return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
408 default:
409 BUG();
410 return 0;
411 }
412} 504}
413 505
414u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) 506u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
415{ 507{
416 switch (channel) { 508 return mgr_desc[channel].framedone_irq;
417 case OMAP_DSS_CHANNEL_LCD:
418 return DISPC_IRQ_FRAMEDONE;
419 case OMAP_DSS_CHANNEL_LCD2:
420 return DISPC_IRQ_FRAMEDONE2;
421 case OMAP_DSS_CHANNEL_DIGIT:
422 return 0;
423 default:
424 BUG();
425 return 0;
426 }
427} 509}
428 510
429bool dispc_mgr_go_busy(enum omap_channel channel) 511bool dispc_mgr_go_busy(enum omap_channel channel)
430{ 512{
431 int bit; 513 return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
432
433 if (dispc_mgr_is_lcd(channel))
434 bit = 5; /* GOLCD */
435 else
436 bit = 6; /* GODIGIT */
437
438 if (channel == OMAP_DSS_CHANNEL_LCD2)
439 return REG_GET(DISPC_CONTROL2, bit, bit) == 1;
440 else
441 return REG_GET(DISPC_CONTROL, bit, bit) == 1;
442} 514}
443 515
444void dispc_mgr_go(enum omap_channel channel) 516void dispc_mgr_go(enum omap_channel channel)
445{ 517{
446 int bit;
447 bool enable_bit, go_bit; 518 bool enable_bit, go_bit;
448 519
449 if (dispc_mgr_is_lcd(channel))
450 bit = 0; /* LCDENABLE */
451 else
452 bit = 1; /* DIGITALENABLE */
453
454 /* if the channel is not enabled, we don't need GO */ 520 /* if the channel is not enabled, we don't need GO */
455 if (channel == OMAP_DSS_CHANNEL_LCD2) 521 enable_bit = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE) == 1;
456 enable_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
457 else
458 enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
459 522
460 if (!enable_bit) 523 if (!enable_bit)
461 return; 524 return;
462 525
463 if (dispc_mgr_is_lcd(channel)) 526 go_bit = mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
464 bit = 5; /* GOLCD */
465 else
466 bit = 6; /* GODIGIT */
467
468 if (channel == OMAP_DSS_CHANNEL_LCD2)
469 go_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
470 else
471 go_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
472 527
473 if (go_bit) { 528 if (go_bit) {
474 DSSERR("GO bit not down for channel %d\n", channel); 529 DSSERR("GO bit not down for channel %d\n", channel);
475 return; 530 return;
476 } 531 }
477 532
478 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : 533 DSSDBG("GO %s\n", mgr_desc[channel].name);
479 (channel == OMAP_DSS_CHANNEL_LCD2 ? "LCD2" : "DIGIT"));
480 534
481 if (channel == OMAP_DSS_CHANNEL_LCD2) 535 mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
482 REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit);
483 else
484 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
485} 536}
486 537
487static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) 538static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
@@ -832,6 +883,15 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
832 chan = 0; 883 chan = 0;
833 chan2 = 1; 884 chan2 = 1;
834 break; 885 break;
886 case OMAP_DSS_CHANNEL_LCD3:
887 if (dss_has_feature(FEAT_MGR_LCD3)) {
888 chan = 0;
889 chan2 = 2;
890 } else {
891 BUG();
892 return;
893 }
894 break;
835 default: 895 default:
836 BUG(); 896 BUG();
837 return; 897 return;
@@ -867,7 +927,14 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
867 927
868 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); 928 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
869 929
870 if (dss_has_feature(FEAT_MGR_LCD2)) { 930 if (dss_has_feature(FEAT_MGR_LCD3)) {
931 if (FLD_GET(val, 31, 30) == 0)
932 channel = FLD_GET(val, shift, shift);
933 else if (FLD_GET(val, 31, 30) == 1)
934 channel = OMAP_DSS_CHANNEL_LCD2;
935 else
936 channel = OMAP_DSS_CHANNEL_LCD3;
937 } else if (dss_has_feature(FEAT_MGR_LCD2)) {
871 if (FLD_GET(val, 31, 30) == 0) 938 if (FLD_GET(val, 31, 30) == 0)
872 channel = FLD_GET(val, shift, shift); 939 channel = FLD_GET(val, shift, shift);
873 else 940 else
@@ -922,16 +989,10 @@ void dispc_enable_gamma_table(bool enable)
922 989
923static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) 990static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
924{ 991{
925 u16 reg; 992 if (channel == OMAP_DSS_CHANNEL_DIGIT)
926
927 if (channel == OMAP_DSS_CHANNEL_LCD)
928 reg = DISPC_CONFIG;
929 else if (channel == OMAP_DSS_CHANNEL_LCD2)
930 reg = DISPC_CONFIG2;
931 else
932 return; 993 return;
933 994
934 REG_FLD_MOD(reg, enable, 15, 15); 995 mgr_fld_write(channel, DISPC_MGR_FLD_CPR, enable);
935} 996}
936 997
937static void dispc_mgr_set_cpr_coef(enum omap_channel channel, 998static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
@@ -939,7 +1000,7 @@ static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
939{ 1000{
940 u32 coef_r, coef_g, coef_b; 1001 u32 coef_r, coef_g, coef_b;
941 1002
942 if (!dispc_mgr_is_lcd(channel)) 1003 if (!dss_mgr_is_lcd(channel))
943 return; 1004 return;
944 1005
945 coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) | 1006 coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) |
@@ -1798,7 +1859,7 @@ static int check_horiz_timing_omap3(enum omap_channel channel,
1798 1859
1799 nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; 1860 nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
1800 pclk = dispc_mgr_pclk_rate(channel); 1861 pclk = dispc_mgr_pclk_rate(channel);
1801 if (dispc_mgr_is_lcd(channel)) 1862 if (dss_mgr_is_lcd(channel))
1802 lclk = dispc_mgr_lclk_rate(channel); 1863 lclk = dispc_mgr_lclk_rate(channel);
1803 else 1864 else
1804 lclk = dispc_fclk_rate(); 1865 lclk = dispc_fclk_rate();
@@ -2086,8 +2147,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
2086} 2147}
2087 2148
2088int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 2149int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
2089 bool ilace, bool replication, 2150 bool replication, const struct omap_video_timings *mgr_timings)
2090 const struct omap_video_timings *mgr_timings)
2091{ 2151{
2092 struct omap_overlay *ovl = omap_dss_get_overlay(plane); 2152 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
2093 bool five_taps = true; 2153 bool five_taps = true;
@@ -2103,6 +2163,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
2103 u16 out_width, out_height; 2163 u16 out_width, out_height;
2104 enum omap_channel channel; 2164 enum omap_channel channel;
2105 int x_predecim = 1, y_predecim = 1; 2165 int x_predecim = 1, y_predecim = 1;
2166 bool ilace = mgr_timings->interlace;
2106 2167
2107 channel = dispc_ovl_get_channel_out(plane); 2168 channel = dispc_ovl_get_channel_out(plane);
2108 2169
@@ -2254,14 +2315,9 @@ static void dispc_disable_isr(void *data, u32 mask)
2254 2315
2255static void _enable_lcd_out(enum omap_channel channel, bool enable) 2316static void _enable_lcd_out(enum omap_channel channel, bool enable)
2256{ 2317{
2257 if (channel == OMAP_DSS_CHANNEL_LCD2) { 2318 mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
2258 REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0); 2319 /* flush posted write */
2259 /* flush posted write */ 2320 mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2260 dispc_read_reg(DISPC_CONTROL2);
2261 } else {
2262 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
2263 dispc_read_reg(DISPC_CONTROL);
2264 }
2265} 2321}
2266 2322
2267static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable) 2323static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
@@ -2274,12 +2330,9 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
2274 /* When we disable LCD output, we need to wait until frame is done. 2330 /* When we disable LCD output, we need to wait until frame is done.
2275 * Otherwise the DSS is still working, and turning off the clocks 2331 * Otherwise the DSS is still working, and turning off the clocks
2276 * prevents DSS from going to OFF mode */ 2332 * prevents DSS from going to OFF mode */
2277 is_on = channel == OMAP_DSS_CHANNEL_LCD2 ? 2333 is_on = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2278 REG_GET(DISPC_CONTROL2, 0, 0) :
2279 REG_GET(DISPC_CONTROL, 0, 0);
2280 2334
2281 irq = channel == OMAP_DSS_CHANNEL_LCD2 ? DISPC_IRQ_FRAMEDONE2 : 2335 irq = mgr_desc[channel].framedone_irq;
2282 DISPC_IRQ_FRAMEDONE;
2283 2336
2284 if (!enable && is_on) { 2337 if (!enable && is_on) {
2285 init_completion(&frame_done_completion); 2338 init_completion(&frame_done_completion);
@@ -2384,21 +2437,12 @@ static void dispc_mgr_enable_digit_out(bool enable)
2384 2437
2385bool dispc_mgr_is_enabled(enum omap_channel channel) 2438bool dispc_mgr_is_enabled(enum omap_channel channel)
2386{ 2439{
2387 if (channel == OMAP_DSS_CHANNEL_LCD) 2440 return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2388 return !!REG_GET(DISPC_CONTROL, 0, 0);
2389 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
2390 return !!REG_GET(DISPC_CONTROL, 1, 1);
2391 else if (channel == OMAP_DSS_CHANNEL_LCD2)
2392 return !!REG_GET(DISPC_CONTROL2, 0, 0);
2393 else {
2394 BUG();
2395 return false;
2396 }
2397} 2441}
2398 2442
2399void dispc_mgr_enable(enum omap_channel channel, bool enable) 2443void dispc_mgr_enable(enum omap_channel channel, bool enable)
2400{ 2444{
2401 if (dispc_mgr_is_lcd(channel)) 2445 if (dss_mgr_is_lcd(channel))
2402 dispc_mgr_enable_lcd_out(channel, enable); 2446 dispc_mgr_enable_lcd_out(channel, enable);
2403 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 2447 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
2404 dispc_mgr_enable_digit_out(enable); 2448 dispc_mgr_enable_digit_out(enable);
@@ -2432,36 +2476,13 @@ void dispc_pck_free_enable(bool enable)
2432 2476
2433void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable) 2477void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
2434{ 2478{
2435 if (channel == OMAP_DSS_CHANNEL_LCD2) 2479 mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
2436 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
2437 else
2438 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
2439} 2480}
2440 2481
2441 2482
2442void dispc_mgr_set_lcd_display_type(enum omap_channel channel, 2483void dispc_mgr_set_lcd_type_tft(enum omap_channel channel)
2443 enum omap_lcd_display_type type)
2444{ 2484{
2445 int mode; 2485 mgr_fld_write(channel, DISPC_MGR_FLD_STNTFT, 1);
2446
2447 switch (type) {
2448 case OMAP_DSS_LCD_DISPLAY_STN:
2449 mode = 0;
2450 break;
2451
2452 case OMAP_DSS_LCD_DISPLAY_TFT:
2453 mode = 1;
2454 break;
2455
2456 default:
2457 BUG();
2458 return;
2459 }
2460
2461 if (channel == OMAP_DSS_CHANNEL_LCD2)
2462 REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3);
2463 else
2464 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
2465} 2486}
2466 2487
2467void dispc_set_loadmode(enum omap_dss_load_mode mode) 2488void dispc_set_loadmode(enum omap_dss_load_mode mode)
@@ -2479,24 +2500,14 @@ static void dispc_mgr_set_trans_key(enum omap_channel ch,
2479 enum omap_dss_trans_key_type type, 2500 enum omap_dss_trans_key_type type,
2480 u32 trans_key) 2501 u32 trans_key)
2481{ 2502{
2482 if (ch == OMAP_DSS_CHANNEL_LCD) 2503 mgr_fld_write(ch, DISPC_MGR_FLD_TCKSELECTION, type);
2483 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
2484 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2485 REG_FLD_MOD(DISPC_CONFIG, type, 13, 13);
2486 else /* OMAP_DSS_CHANNEL_LCD2 */
2487 REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11);
2488 2504
2489 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); 2505 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
2490} 2506}
2491 2507
2492static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable) 2508static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
2493{ 2509{
2494 if (ch == OMAP_DSS_CHANNEL_LCD) 2510 mgr_fld_write(ch, DISPC_MGR_FLD_TCKENABLE, enable);
2495 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
2496 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2497 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
2498 else /* OMAP_DSS_CHANNEL_LCD2 */
2499 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
2500} 2511}
2501 2512
2502static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, 2513static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
@@ -2547,10 +2558,7 @@ void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2547 return; 2558 return;
2548 } 2559 }
2549 2560
2550 if (channel == OMAP_DSS_CHANNEL_LCD2) 2561 mgr_fld_write(channel, DISPC_MGR_FLD_TFTDATALINES, code);
2551 REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8);
2552 else
2553 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
2554} 2562}
2555 2563
2556void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode) 2564void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
@@ -2584,10 +2592,7 @@ void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
2584 2592
2585void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) 2593void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
2586{ 2594{
2587 if (channel == OMAP_DSS_CHANNEL_LCD2) 2595 mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable);
2588 REG_FLD_MOD(DISPC_CONTROL2, enable, 11, 11);
2589 else
2590 REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11);
2591} 2596}
2592 2597
2593static bool _dispc_mgr_size_ok(u16 width, u16 height) 2598static bool _dispc_mgr_size_ok(u16 width, u16 height)
@@ -2627,7 +2632,7 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
2627 2632
2628 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); 2633 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
2629 2634
2630 if (dispc_mgr_is_lcd(channel)) 2635 if (dss_mgr_is_lcd(channel))
2631 timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw, 2636 timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw,
2632 timings->hfp, timings->hbp, 2637 timings->hfp, timings->hbp,
2633 timings->vsw, timings->vfp, 2638 timings->vsw, timings->vfp,
@@ -2637,9 +2642,16 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
2637} 2642}
2638 2643
2639static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, 2644static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
2640 int hfp, int hbp, int vsw, int vfp, int vbp) 2645 int hfp, int hbp, int vsw, int vfp, int vbp,
2646 enum omap_dss_signal_level vsync_level,
2647 enum omap_dss_signal_level hsync_level,
2648 enum omap_dss_signal_edge data_pclk_edge,
2649 enum omap_dss_signal_level de_level,
2650 enum omap_dss_signal_edge sync_pclk_edge)
2651
2641{ 2652{
2642 u32 timing_h, timing_v; 2653 u32 timing_h, timing_v, l;
2654 bool onoff, rf, ipc;
2643 2655
2644 if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { 2656 if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
2645 timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) | 2657 timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
@@ -2657,6 +2669,44 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
2657 2669
2658 dispc_write_reg(DISPC_TIMING_H(channel), timing_h); 2670 dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
2659 dispc_write_reg(DISPC_TIMING_V(channel), timing_v); 2671 dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
2672
2673 switch (data_pclk_edge) {
2674 case OMAPDSS_DRIVE_SIG_RISING_EDGE:
2675 ipc = false;
2676 break;
2677 case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
2678 ipc = true;
2679 break;
2680 case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
2681 default:
2682 BUG();
2683 }
2684
2685 switch (sync_pclk_edge) {
2686 case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
2687 onoff = false;
2688 rf = false;
2689 break;
2690 case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
2691 onoff = true;
2692 rf = false;
2693 break;
2694 case OMAPDSS_DRIVE_SIG_RISING_EDGE:
2695 onoff = true;
2696 rf = true;
2697 break;
2698 default:
2699 BUG();
2700 };
2701
2702 l = dispc_read_reg(DISPC_POL_FREQ(channel));
2703 l |= FLD_VAL(onoff, 17, 17);
2704 l |= FLD_VAL(rf, 16, 16);
2705 l |= FLD_VAL(de_level, 15, 15);
2706 l |= FLD_VAL(ipc, 14, 14);
2707 l |= FLD_VAL(hsync_level, 13, 13);
2708 l |= FLD_VAL(vsync_level, 12, 12);
2709 dispc_write_reg(DISPC_POL_FREQ(channel), l);
2660} 2710}
2661 2711
2662/* change name to mode? */ 2712/* change name to mode? */
@@ -2674,9 +2724,10 @@ void dispc_mgr_set_timings(enum omap_channel channel,
2674 return; 2724 return;
2675 } 2725 }
2676 2726
2677 if (dispc_mgr_is_lcd(channel)) { 2727 if (dss_mgr_is_lcd(channel)) {
2678 _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw, 2728 _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw,
2679 t.vfp, t.vbp); 2729 t.vfp, t.vbp, t.vsync_level, t.hsync_level,
2730 t.data_pclk_edge, t.de_level, t.sync_pclk_edge);
2680 2731
2681 xtot = t.x_res + t.hfp + t.hsw + t.hbp; 2732 xtot = t.x_res + t.hfp + t.hsw + t.hbp;
2682 ytot = t.y_res + t.vfp + t.vsw + t.vbp; 2733 ytot = t.y_res + t.vfp + t.vsw + t.vbp;
@@ -2687,14 +2738,13 @@ void dispc_mgr_set_timings(enum omap_channel channel,
2687 DSSDBG("pck %u\n", timings->pixel_clock); 2738 DSSDBG("pck %u\n", timings->pixel_clock);
2688 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", 2739 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
2689 t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp); 2740 t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp);
2741 DSSDBG("vsync_level %d hsync_level %d data_pclk_edge %d de_level %d sync_pclk_edge %d\n",
2742 t.vsync_level, t.hsync_level, t.data_pclk_edge,
2743 t.de_level, t.sync_pclk_edge);
2690 2744
2691 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 2745 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
2692 } else { 2746 } else {
2693 enum dss_hdmi_venc_clk_source_select source; 2747 if (t.interlace == true)
2694
2695 source = dss_get_hdmi_venc_clk_source();
2696
2697 if (source == DSS_VENC_TV_CLK)
2698 t.y_res /= 2; 2748 t.y_res /= 2;
2699 } 2749 }
2700 2750
@@ -2780,7 +2830,7 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
2780{ 2830{
2781 unsigned long r; 2831 unsigned long r;
2782 2832
2783 if (dispc_mgr_is_lcd(channel)) { 2833 if (dss_mgr_is_lcd(channel)) {
2784 int pcd; 2834 int pcd;
2785 u32 l; 2835 u32 l;
2786 2836
@@ -2821,12 +2871,32 @@ unsigned long dispc_core_clk_rate(void)
2821 return fclk / lcd; 2871 return fclk / lcd;
2822} 2872}
2823 2873
2824void dispc_dump_clocks(struct seq_file *s) 2874static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
2825{ 2875{
2826 int lcd, pcd; 2876 int lcd, pcd;
2877 enum omap_dss_clk_source lcd_clk_src;
2878
2879 seq_printf(s, "- %s -\n", mgr_desc[channel].name);
2880
2881 lcd_clk_src = dss_get_lcd_clk_source(channel);
2882
2883 seq_printf(s, "%s clk source = %s (%s)\n", mgr_desc[channel].name,
2884 dss_get_generic_clk_source_name(lcd_clk_src),
2885 dss_feat_get_clk_source_name(lcd_clk_src));
2886
2887 dispc_mgr_get_lcd_divisor(channel, &lcd, &pcd);
2888
2889 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2890 dispc_mgr_lclk_rate(channel), lcd);
2891 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2892 dispc_mgr_pclk_rate(channel), pcd);
2893}
2894
2895void dispc_dump_clocks(struct seq_file *s)
2896{
2897 int lcd;
2827 u32 l; 2898 u32 l;
2828 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); 2899 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2829 enum omap_dss_clk_source lcd_clk_src;
2830 2900
2831 if (dispc_runtime_get()) 2901 if (dispc_runtime_get())
2832 return; 2902 return;
@@ -2847,36 +2917,13 @@ void dispc_dump_clocks(struct seq_file *s)
2847 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2917 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2848 (dispc_fclk_rate()/lcd), lcd); 2918 (dispc_fclk_rate()/lcd), lcd);
2849 } 2919 }
2850 seq_printf(s, "- LCD1 -\n");
2851
2852 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD);
2853
2854 seq_printf(s, "lcd1_clk source = %s (%s)\n",
2855 dss_get_generic_clk_source_name(lcd_clk_src),
2856 dss_feat_get_clk_source_name(lcd_clk_src));
2857
2858 dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2859
2860 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2861 dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd);
2862 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2863 dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd);
2864 if (dss_has_feature(FEAT_MGR_LCD2)) {
2865 seq_printf(s, "- LCD2 -\n");
2866
2867 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2);
2868 2920
2869 seq_printf(s, "lcd2_clk source = %s (%s)\n", 2921 dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD);
2870 dss_get_generic_clk_source_name(lcd_clk_src),
2871 dss_feat_get_clk_source_name(lcd_clk_src));
2872 2922
2873 dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); 2923 if (dss_has_feature(FEAT_MGR_LCD2))
2874 2924 dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD2);
2875 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2925 if (dss_has_feature(FEAT_MGR_LCD3))
2876 dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd); 2926 dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD3);
2877 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2878 dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
2879 }
2880 2927
2881 dispc_runtime_put(); 2928 dispc_runtime_put();
2882} 2929}
@@ -2929,6 +2976,12 @@ void dispc_dump_irqs(struct seq_file *s)
2929 PIS(ACBIAS_COUNT_STAT2); 2976 PIS(ACBIAS_COUNT_STAT2);
2930 PIS(SYNC_LOST2); 2977 PIS(SYNC_LOST2);
2931 } 2978 }
2979 if (dss_has_feature(FEAT_MGR_LCD3)) {
2980 PIS(FRAMEDONE3);
2981 PIS(VSYNC3);
2982 PIS(ACBIAS_COUNT_STAT3);
2983 PIS(SYNC_LOST3);
2984 }
2932#undef PIS 2985#undef PIS
2933} 2986}
2934#endif 2987#endif
@@ -2940,6 +2993,7 @@ static void dispc_dump_regs(struct seq_file *s)
2940 [OMAP_DSS_CHANNEL_LCD] = "LCD", 2993 [OMAP_DSS_CHANNEL_LCD] = "LCD",
2941 [OMAP_DSS_CHANNEL_DIGIT] = "TV", 2994 [OMAP_DSS_CHANNEL_DIGIT] = "TV",
2942 [OMAP_DSS_CHANNEL_LCD2] = "LCD2", 2995 [OMAP_DSS_CHANNEL_LCD2] = "LCD2",
2996 [OMAP_DSS_CHANNEL_LCD3] = "LCD3",
2943 }; 2997 };
2944 const char *ovl_names[] = { 2998 const char *ovl_names[] = {
2945 [OMAP_DSS_GFX] = "GFX", 2999 [OMAP_DSS_GFX] = "GFX",
@@ -2972,6 +3026,10 @@ static void dispc_dump_regs(struct seq_file *s)
2972 DUMPREG(DISPC_CONTROL2); 3026 DUMPREG(DISPC_CONTROL2);
2973 DUMPREG(DISPC_CONFIG2); 3027 DUMPREG(DISPC_CONFIG2);
2974 } 3028 }
3029 if (dss_has_feature(FEAT_MGR_LCD3)) {
3030 DUMPREG(DISPC_CONTROL3);
3031 DUMPREG(DISPC_CONFIG3);
3032 }
2975 3033
2976#undef DUMPREG 3034#undef DUMPREG
2977 3035
@@ -3093,41 +3151,8 @@ static void dispc_dump_regs(struct seq_file *s)
3093#undef DUMPREG 3151#undef DUMPREG
3094} 3152}
3095 3153
3096static void _dispc_mgr_set_pol_freq(enum omap_channel channel, bool onoff,
3097 bool rf, bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi,
3098 u8 acb)
3099{
3100 u32 l = 0;
3101
3102 DSSDBG("onoff %d rf %d ieo %d ipc %d ihs %d ivs %d acbi %d acb %d\n",
3103 onoff, rf, ieo, ipc, ihs, ivs, acbi, acb);
3104
3105 l |= FLD_VAL(onoff, 17, 17);
3106 l |= FLD_VAL(rf, 16, 16);
3107 l |= FLD_VAL(ieo, 15, 15);
3108 l |= FLD_VAL(ipc, 14, 14);
3109 l |= FLD_VAL(ihs, 13, 13);
3110 l |= FLD_VAL(ivs, 12, 12);
3111 l |= FLD_VAL(acbi, 11, 8);
3112 l |= FLD_VAL(acb, 7, 0);
3113
3114 dispc_write_reg(DISPC_POL_FREQ(channel), l);
3115}
3116
3117void dispc_mgr_set_pol_freq(enum omap_channel channel,
3118 enum omap_panel_config config, u8 acbi, u8 acb)
3119{
3120 _dispc_mgr_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0,
3121 (config & OMAP_DSS_LCD_RF) != 0,
3122 (config & OMAP_DSS_LCD_IEO) != 0,
3123 (config & OMAP_DSS_LCD_IPC) != 0,
3124 (config & OMAP_DSS_LCD_IHS) != 0,
3125 (config & OMAP_DSS_LCD_IVS) != 0,
3126 acbi, acb);
3127}
3128
3129/* with fck as input clock rate, find dispc dividers that produce req_pck */ 3154/* with fck as input clock rate, find dispc dividers that produce req_pck */
3130void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 3155void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck,
3131 struct dispc_clock_info *cinfo) 3156 struct dispc_clock_info *cinfo)
3132{ 3157{
3133 u16 pcd_min, pcd_max; 3158 u16 pcd_min, pcd_max;
@@ -3138,9 +3163,6 @@ void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
3138 pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD); 3163 pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD);
3139 pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD); 3164 pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD);
3140 3165
3141 if (!is_tft)
3142 pcd_min = 3;
3143
3144 best_pck = 0; 3166 best_pck = 0;
3145 best_ld = 0; 3167 best_ld = 0;
3146 best_pd = 0; 3168 best_pd = 0;
@@ -3192,15 +3214,13 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
3192 return 0; 3214 return 0;
3193} 3215}
3194 3216
3195int dispc_mgr_set_clock_div(enum omap_channel channel, 3217void dispc_mgr_set_clock_div(enum omap_channel channel,
3196 struct dispc_clock_info *cinfo) 3218 struct dispc_clock_info *cinfo)
3197{ 3219{
3198 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); 3220 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
3199 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); 3221 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
3200 3222
3201 dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div); 3223 dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
3202
3203 return 0;
3204} 3224}
3205 3225
3206int dispc_mgr_get_clock_div(enum omap_channel channel, 3226int dispc_mgr_get_clock_div(enum omap_channel channel,
@@ -3354,6 +3374,8 @@ static void print_irq_status(u32 status)
3354 PIS(SYNC_LOST_DIGIT); 3374 PIS(SYNC_LOST_DIGIT);
3355 if (dss_has_feature(FEAT_MGR_LCD2)) 3375 if (dss_has_feature(FEAT_MGR_LCD2))
3356 PIS(SYNC_LOST2); 3376 PIS(SYNC_LOST2);
3377 if (dss_has_feature(FEAT_MGR_LCD3))
3378 PIS(SYNC_LOST3);
3357#undef PIS 3379#undef PIS
3358 3380
3359 printk("\n"); 3381 printk("\n");
@@ -3450,12 +3472,6 @@ static void dispc_error_worker(struct work_struct *work)
3450 DISPC_IRQ_VID3_FIFO_UNDERFLOW, 3472 DISPC_IRQ_VID3_FIFO_UNDERFLOW,
3451 }; 3473 };
3452 3474
3453 static const unsigned sync_lost_bits[] = {
3454 DISPC_IRQ_SYNC_LOST,
3455 DISPC_IRQ_SYNC_LOST_DIGIT,
3456 DISPC_IRQ_SYNC_LOST2,
3457 };
3458
3459 spin_lock_irqsave(&dispc.irq_lock, flags); 3475 spin_lock_irqsave(&dispc.irq_lock, flags);
3460 errors = dispc.error_irqs; 3476 errors = dispc.error_irqs;
3461 dispc.error_irqs = 0; 3477 dispc.error_irqs = 0;
@@ -3484,7 +3500,7 @@ static void dispc_error_worker(struct work_struct *work)
3484 unsigned bit; 3500 unsigned bit;
3485 3501
3486 mgr = omap_dss_get_overlay_manager(i); 3502 mgr = omap_dss_get_overlay_manager(i);
3487 bit = sync_lost_bits[i]; 3503 bit = mgr_desc[i].sync_lost_irq;
3488 3504
3489 if (bit & errors) { 3505 if (bit & errors) {
3490 struct omap_dss_device *dssdev = mgr->device; 3506 struct omap_dss_device *dssdev = mgr->device;
@@ -3603,6 +3619,8 @@ static void _omap_dispc_initialize_irq(void)
3603 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 3619 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
3604 if (dss_has_feature(FEAT_MGR_LCD2)) 3620 if (dss_has_feature(FEAT_MGR_LCD2))
3605 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2; 3621 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
3622 if (dss_has_feature(FEAT_MGR_LCD3))
3623 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
3606 if (dss_feat_get_num_ovls() > 3) 3624 if (dss_feat_get_num_ovls() > 3)
3607 dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW; 3625 dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
3608 3626