diff options
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 494 |
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 | ||
122 | enum 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 | |||
136 | static 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 | |||
122 | static void _omap_dispc_set_irqs(void); | 213 | static void _omap_dispc_set_irqs(void); |
123 | 214 | ||
124 | static inline void dispc_write_reg(const u16 idx, u32 val) | 215 | static 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 | ||
225 | static 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 | |||
231 | static 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 | ||
390 | static 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 | |||
399 | u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) | 501 | u32 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 | ||
414 | u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) | 506 | u32 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 | ||
429 | bool dispc_mgr_go_busy(enum omap_channel channel) | 511 | bool 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 | ||
444 | void dispc_mgr_go(enum omap_channel channel) | 516 | void 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 | ||
487 | static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) | 538 | static 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 | ||
923 | static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) | 990 | static 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 | ||
937 | static void dispc_mgr_set_cpr_coef(enum omap_channel channel, | 998 | static 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 | ||
2088 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 2149 | int 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 | ||
2255 | static void _enable_lcd_out(enum omap_channel channel, bool enable) | 2316 | static 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 | ||
2267 | static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable) | 2323 | static 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 | ||
2385 | bool dispc_mgr_is_enabled(enum omap_channel channel) | 2438 | bool 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 | ||
2399 | void dispc_mgr_enable(enum omap_channel channel, bool enable) | 2443 | void 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 | ||
2433 | void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable) | 2477 | void 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 | ||
2442 | void dispc_mgr_set_lcd_display_type(enum omap_channel channel, | 2483 | void 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 | ||
2467 | void dispc_set_loadmode(enum omap_dss_load_mode mode) | 2488 | void 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 | ||
2492 | static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable) | 2508 | static 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 | ||
2502 | static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, | 2513 | static 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 | ||
2556 | void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode) | 2564 | void 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 | ||
2585 | void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) | 2593 | void 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 | ||
2593 | static bool _dispc_mgr_size_ok(u16 width, u16 height) | 2598 | static 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 | ||
2639 | static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, | 2644 | static 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 | ||
2824 | void dispc_dump_clocks(struct seq_file *s) | 2874 | static 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 | |||
2895 | void 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 | ||
3096 | static 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 | |||
3117 | void 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 */ |
3130 | void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, | 3155 | void 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 | ||
3195 | int dispc_mgr_set_clock_div(enum omap_channel channel, | 3217 | void 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 | ||
3206 | int dispc_mgr_get_clock_div(enum omap_channel channel, | 3226 | int 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 | ||