aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2012-07-25 04:55:46 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2012-07-25 04:55:46 -0400
commitd9053b487965042b9c849ce40c7f1fb7a0b84b39 (patch)
tree1fbb2559dd8fd400cf1dff5711cc5e408ea79ef6 /drivers/video
parent4c5b1fb8a1348542afb153aef72f6067989f578e (diff)
parent974a65825e0b5fbda49605f0416a2c975d66e9e6 (diff)
Merge branch 'for-florian' of git://gitorious.org/linux-omap-dss2/linux into fbdev-next
Conflicts: drivers/video/omap2/dss/core.c drivers/video/omap2/dss/dispc.c
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c10
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c179
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c8
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c1
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c9
-rw-r--r--drivers/video/omap2/displays/panel-picodlp.c9
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c9
-rw-r--r--drivers/video/omap2/displays/panel-taal.c1
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c7
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c8
-rw-r--r--drivers/video/omap2/dss/Kconfig4
-rw-r--r--drivers/video/omap2/dss/apply.c91
-rw-r--r--drivers/video/omap2/dss/dispc.c494
-rw-r--r--drivers/video/omap2/dss/dispc.h28
-rw-r--r--drivers/video/omap2/dss/display.c40
-rw-r--r--drivers/video/omap2/dss/dpi.c64
-rw-r--r--drivers/video/omap2/dss/dsi.c152
-rw-r--r--drivers/video/omap2/dss/dss.c19
-rw-r--r--drivers/video/omap2/dss/dss.h54
-rw-r--r--drivers/video/omap2/dss/dss_features.h5
-rw-r--r--drivers/video/omap2/dss/hdmi.c246
-rw-r--r--drivers/video/omap2/dss/hdmi_panel.c9
-rw-r--r--drivers/video/omap2/dss/manager.c51
-rw-r--r--drivers/video/omap2/dss/overlay.c33
-rw-r--r--drivers/video/omap2/dss/rfbi.c40
-rw-r--r--drivers/video/omap2/dss/sdi.c42
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h21
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c26
-rw-r--r--drivers/video/omap2/dss/venc.c8
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c51
30 files changed, 1085 insertions, 634 deletions
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index ad741c3d1ae1..eaeed4340e04 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -487,6 +487,13 @@ static struct omap_video_timings acx_panel_timings = {
487 .vfp = 3, 487 .vfp = 3,
488 .vsw = 3, 488 .vsw = 3,
489 .vbp = 4, 489 .vbp = 4,
490
491 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
492 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
493
494 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
495 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
496 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
490}; 497};
491 498
492static int acx_panel_probe(struct omap_dss_device *dssdev) 499static int acx_panel_probe(struct omap_dss_device *dssdev)
@@ -498,8 +505,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
498 struct backlight_properties props; 505 struct backlight_properties props;
499 506
500 dev_dbg(&dssdev->dev, "%s\n", __func__); 507 dev_dbg(&dssdev->dev, "%s\n", __func__);
501 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | 508
502 OMAP_DSS_LCD_IHS;
503 /* FIXME AC bias ? */ 509 /* FIXME AC bias ? */
504 dssdev->panel.timings = acx_panel_timings; 510 dssdev->panel.timings = acx_panel_timings;
505 511
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index e42f9dc22123..bc5af2500eb9 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -40,12 +40,6 @@
40struct panel_config { 40struct panel_config {
41 struct omap_video_timings timings; 41 struct omap_video_timings timings;
42 42
43 int acbi; /* ac-bias pin transitions per interrupt */
44 /* Unit: line clocks */
45 int acb; /* ac-bias pin frequency */
46
47 enum omap_panel_config config;
48
49 int power_on_delay; 43 int power_on_delay;
50 int power_off_delay; 44 int power_off_delay;
51 45
@@ -73,11 +67,13 @@ static struct panel_config generic_dpi_panels[] = {
73 .vsw = 11, 67 .vsw = 11,
74 .vfp = 3, 68 .vfp = 3,
75 .vbp = 2, 69 .vbp = 2,
70
71 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
72 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
73 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
74 .de_level = OMAPDSS_SIG_ACTIVE_LOW,
75 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
76 }, 76 },
77 .acbi = 0x0,
78 .acb = 0x0,
79 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
80 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
81 .power_on_delay = 50, 77 .power_on_delay = 50,
82 .power_off_delay = 100, 78 .power_off_delay = 100,
83 .name = "sharp_lq", 79 .name = "sharp_lq",
@@ -98,11 +94,13 @@ static struct panel_config generic_dpi_panels[] = {
98 .vsw = 1, 94 .vsw = 1,
99 .vfp = 1, 95 .vfp = 1,
100 .vbp = 1, 96 .vbp = 1,
97
98 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
99 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
100 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
101 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
102 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
101 }, 103 },
102 .acbi = 0x0,
103 .acb = 0x28,
104 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
105 OMAP_DSS_LCD_IHS,
106 .power_on_delay = 50, 104 .power_on_delay = 50,
107 .power_off_delay = 100, 105 .power_off_delay = 100,
108 .name = "sharp_ls", 106 .name = "sharp_ls",
@@ -123,12 +121,13 @@ static struct panel_config generic_dpi_panels[] = {
123 .vfp = 4, 121 .vfp = 4,
124 .vsw = 2, 122 .vsw = 2,
125 .vbp = 2, 123 .vbp = 2,
124
125 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
126 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
127 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
128 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
129 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
126 }, 130 },
127 .acbi = 0x0,
128 .acb = 0x0,
129 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
130 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC |
131 OMAP_DSS_LCD_ONOFF,
132 .power_on_delay = 0, 131 .power_on_delay = 0,
133 .power_off_delay = 0, 132 .power_off_delay = 0,
134 .name = "toppoly_tdo35s", 133 .name = "toppoly_tdo35s",
@@ -149,11 +148,13 @@ static struct panel_config generic_dpi_panels[] = {
149 .vfp = 4, 148 .vfp = 4,
150 .vsw = 10, 149 .vsw = 10,
151 .vbp = 12 - 10, 150 .vbp = 12 - 10,
151
152 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
153 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
154 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
155 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
156 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
152 }, 157 },
153 .acbi = 0x0,
154 .acb = 0x0,
155 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
156 OMAP_DSS_LCD_IHS,
157 .power_on_delay = 0, 158 .power_on_delay = 0,
158 .power_off_delay = 0, 159 .power_off_delay = 0,
159 .name = "samsung_lte430wq_f0c", 160 .name = "samsung_lte430wq_f0c",
@@ -174,11 +175,13 @@ static struct panel_config generic_dpi_panels[] = {
174 .vsw = 2, 175 .vsw = 2,
175 .vfp = 4, 176 .vfp = 4,
176 .vbp = 11, 177 .vbp = 11,
178
179 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
180 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
181 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
182 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
183 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
177 }, 184 },
178 .acbi = 0x0,
179 .acb = 0x0,
180 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
181 OMAP_DSS_LCD_IHS,
182 .power_on_delay = 0, 185 .power_on_delay = 0,
183 .power_off_delay = 0, 186 .power_off_delay = 0,
184 .name = "seiko_70wvw1tz3", 187 .name = "seiko_70wvw1tz3",
@@ -199,11 +202,13 @@ static struct panel_config generic_dpi_panels[] = {
199 .vsw = 10, 202 .vsw = 10,
200 .vfp = 2, 203 .vfp = 2,
201 .vbp = 2, 204 .vbp = 2,
205
206 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
207 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
208 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
209 .de_level = OMAPDSS_SIG_ACTIVE_LOW,
210 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
202 }, 211 },
203 .acbi = 0x0,
204 .acb = 0x0,
205 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
206 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
207 .power_on_delay = 0, 212 .power_on_delay = 0,
208 .power_off_delay = 0, 213 .power_off_delay = 0,
209 .name = "powertip_ph480272t", 214 .name = "powertip_ph480272t",
@@ -224,11 +229,13 @@ static struct panel_config generic_dpi_panels[] = {
224 .vsw = 3, 229 .vsw = 3,
225 .vfp = 12, 230 .vfp = 12,
226 .vbp = 25, 231 .vbp = 25,
232
233 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
234 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
235 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
236 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
237 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
227 }, 238 },
228 .acbi = 0x0,
229 .acb = 0x28,
230 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
231 OMAP_DSS_LCD_IHS,
232 .power_on_delay = 0, 239 .power_on_delay = 0,
233 .power_off_delay = 0, 240 .power_off_delay = 0,
234 .name = "innolux_at070tn83", 241 .name = "innolux_at070tn83",
@@ -249,9 +256,13 @@ static struct panel_config generic_dpi_panels[] = {
249 .vsw = 1, 256 .vsw = 1,
250 .vfp = 2, 257 .vfp = 2,
251 .vbp = 7, 258 .vbp = 7,
259
260 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
261 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
262 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
263 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
264 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
252 }, 265 },
253 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
254 OMAP_DSS_LCD_IHS,
255 .name = "nec_nl2432dr22-11b", 266 .name = "nec_nl2432dr22-11b",
256 }, 267 },
257 268
@@ -270,9 +281,13 @@ static struct panel_config generic_dpi_panels[] = {
270 .vsw = 1, 281 .vsw = 1,
271 .vfp = 1, 282 .vfp = 1,
272 .vbp = 1, 283 .vbp = 1,
273 },
274 .config = OMAP_DSS_LCD_TFT,
275 284
285 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
286 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
287 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
288 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
289 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
290 },
276 .name = "h4", 291 .name = "h4",
277 }, 292 },
278 293
@@ -291,10 +306,13 @@ static struct panel_config generic_dpi_panels[] = {
291 .vsw = 10, 306 .vsw = 10,
292 .vfp = 2, 307 .vfp = 2,
293 .vbp = 2, 308 .vbp = 2,
294 },
295 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
296 OMAP_DSS_LCD_IHS,
297 309
310 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
311 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
312 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
313 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
314 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
315 },
298 .name = "apollon", 316 .name = "apollon",
299 }, 317 },
300 /* FocalTech ETM070003DH6 */ 318 /* FocalTech ETM070003DH6 */
@@ -312,9 +330,13 @@ static struct panel_config generic_dpi_panels[] = {
312 .vsw = 3, 330 .vsw = 3,
313 .vfp = 13, 331 .vfp = 13,
314 .vbp = 29, 332 .vbp = 29,
333
334 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
335 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
336 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
337 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
338 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
315 }, 339 },
316 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
317 OMAP_DSS_LCD_IHS,
318 .name = "focaltech_etm070003dh6", 340 .name = "focaltech_etm070003dh6",
319 }, 341 },
320 342
@@ -333,11 +355,13 @@ static struct panel_config generic_dpi_panels[] = {
333 .vsw = 23, 355 .vsw = 23,
334 .vfp = 1, 356 .vfp = 1,
335 .vbp = 1, 357 .vbp = 1,
358
359 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
360 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
361 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
362 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
363 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
336 }, 364 },
337 .acbi = 0x0,
338 .acb = 0x0,
339 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
340 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
341 .power_on_delay = 0, 365 .power_on_delay = 0,
342 .power_off_delay = 0, 366 .power_off_delay = 0,
343 .name = "microtips_umsh_8173md", 367 .name = "microtips_umsh_8173md",
@@ -358,9 +382,13 @@ static struct panel_config generic_dpi_panels[] = {
358 .vsw = 10, 382 .vsw = 10,
359 .vfp = 4, 383 .vfp = 4,
360 .vbp = 2, 384 .vbp = 2,
361 },
362 .config = OMAP_DSS_LCD_TFT,
363 385
386 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
387 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
388 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
389 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
390 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
391 },
364 .name = "ortustech_com43h4m10xtc", 392 .name = "ortustech_com43h4m10xtc",
365 }, 393 },
366 394
@@ -379,11 +407,13 @@ static struct panel_config generic_dpi_panels[] = {
379 .vsw = 10, 407 .vsw = 10,
380 .vfp = 12, 408 .vfp = 12,
381 .vbp = 23, 409 .vbp = 23,
382 },
383 .acb = 0x0,
384 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
385 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
386 410
411 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
412 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
413 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
414 .de_level = OMAPDSS_SIG_ACTIVE_LOW,
415 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
416 },
387 .name = "innolux_at080tn52", 417 .name = "innolux_at080tn52",
388 }, 418 },
389 419
@@ -401,8 +431,13 @@ static struct panel_config generic_dpi_panels[] = {
401 .vsw = 1, 431 .vsw = 1,
402 .vfp = 26, 432 .vfp = 26,
403 .vbp = 1, 433 .vbp = 1,
434
435 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
436 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
437 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
438 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
439 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
404 }, 440 },
405 .config = OMAP_DSS_LCD_TFT,
406 .name = "mitsubishi_aa084sb01", 441 .name = "mitsubishi_aa084sb01",
407 }, 442 },
408 /* EDT ET0500G0DH6 */ 443 /* EDT ET0500G0DH6 */
@@ -419,8 +454,13 @@ static struct panel_config generic_dpi_panels[] = {
419 .vsw = 2, 454 .vsw = 2,
420 .vfp = 35, 455 .vfp = 35,
421 .vbp = 10, 456 .vbp = 10,
457
458 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
459 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
460 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
461 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
462 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
422 }, 463 },
423 .config = OMAP_DSS_LCD_TFT,
424 .name = "edt_et0500g0dh6", 464 .name = "edt_et0500g0dh6",
425 }, 465 },
426 466
@@ -439,9 +479,13 @@ static struct panel_config generic_dpi_panels[] = {
439 .vsw = 2, 479 .vsw = 2,
440 .vfp = 10, 480 .vfp = 10,
441 .vbp = 33, 481 .vbp = 33,
482
483 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
484 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
485 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
486 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
487 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
442 }, 488 },
443 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
444 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
445 .name = "primeview_pd050vl1", 489 .name = "primeview_pd050vl1",
446 }, 490 },
447 491
@@ -460,9 +504,13 @@ static struct panel_config generic_dpi_panels[] = {
460 .vsw = 2, 504 .vsw = 2,
461 .vfp = 10, 505 .vfp = 10,
462 .vbp = 33, 506 .vbp = 33,
507
508 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
509 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
510 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
511 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
512 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
463 }, 513 },
464 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
465 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
466 .name = "primeview_pm070wl4", 514 .name = "primeview_pm070wl4",
467 }, 515 },
468 516
@@ -481,9 +529,13 @@ static struct panel_config generic_dpi_panels[] = {
481 .vsw = 4, 529 .vsw = 4,
482 .vfp = 1, 530 .vfp = 1,
483 .vbp = 23, 531 .vbp = 23,
532
533 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
534 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
535 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
536 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
537 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
484 }, 538 },
485 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
486 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
487 .name = "primeview_pd104slf", 539 .name = "primeview_pd104slf",
488 }, 540 },
489}; 541};
@@ -573,10 +625,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
573 if (!panel_config) 625 if (!panel_config)
574 return -EINVAL; 626 return -EINVAL;
575 627
576 dssdev->panel.config = panel_config->config;
577 dssdev->panel.timings = panel_config->timings; 628 dssdev->panel.timings = panel_config->timings;
578 dssdev->panel.acb = panel_config->acb;
579 dssdev->panel.acbi = panel_config->acbi;
580 629
581 drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); 630 drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
582 if (!drv_data) 631 if (!drv_data)
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 0841cc2b3f77..802807798846 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -40,6 +40,12 @@ static struct omap_video_timings lb035q02_timings = {
40 .vsw = 2, 40 .vsw = 2,
41 .vfp = 4, 41 .vfp = 4,
42 .vbp = 18, 42 .vbp = 18,
43
44 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
45 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
46 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
47 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
48 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
43}; 49};
44 50
45static int lb035q02_panel_power_on(struct omap_dss_device *dssdev) 51static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
@@ -82,8 +88,6 @@ static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
82 struct lb035q02_data *ld; 88 struct lb035q02_data *ld;
83 int r; 89 int r;
84 90
85 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
86 OMAP_DSS_LCD_IHS;
87 dssdev->panel.timings = lb035q02_timings; 91 dssdev->panel.timings = lb035q02_timings;
88 92
89 ld = kzalloc(sizeof(*ld), GFP_KERNEL); 93 ld = kzalloc(sizeof(*ld), GFP_KERNEL);
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 4a34cdc1371b..e6c115373c00 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -473,7 +473,6 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
473 473
474 mutex_init(&ddata->lock); 474 mutex_init(&ddata->lock);
475 475
476 dssdev->panel.config = OMAP_DSS_LCD_TFT;
477 dssdev->panel.timings.x_res = 800; 476 dssdev->panel.timings.x_res = 800;
478 dssdev->panel.timings.y_res = 480; 477 dssdev->panel.timings.y_res = 480;
479 dssdev->ctrl.pixel_size = 16; 478 dssdev->ctrl.pixel_size = 16;
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 8b38b39213f4..b122b0f31c43 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -76,6 +76,12 @@ static struct omap_video_timings nec_8048_panel_timings = {
76 .vfp = 3, 76 .vfp = 3,
77 .vsw = 1, 77 .vsw = 1,
78 .vbp = 4, 78 .vbp = 4,
79
80 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
81 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
82 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
83 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
84 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
79}; 85};
80 86
81static int nec_8048_bl_update_status(struct backlight_device *bl) 87static int nec_8048_bl_update_status(struct backlight_device *bl)
@@ -116,9 +122,6 @@ static int nec_8048_panel_probe(struct omap_dss_device *dssdev)
116 struct backlight_properties props; 122 struct backlight_properties props;
117 int r; 123 int r;
118 124
119 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
120 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_RF |
121 OMAP_DSS_LCD_ONOFF;
122 dssdev->panel.timings = nec_8048_panel_timings; 125 dssdev->panel.timings = nec_8048_panel_timings;
123 126
124 necd = kzalloc(sizeof(*necd), GFP_KERNEL); 127 necd = kzalloc(sizeof(*necd), GFP_KERNEL);
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 98ebdaddab5a..2d35bd388860 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -69,6 +69,12 @@ static struct omap_video_timings pico_ls_timings = {
69 .vsw = 2, 69 .vsw = 2,
70 .vfp = 3, 70 .vfp = 3,
71 .vbp = 14, 71 .vbp = 14,
72
73 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
74 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
75 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
76 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
77 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
72}; 78};
73 79
74static inline struct picodlp_panel_data 80static inline struct picodlp_panel_data
@@ -414,9 +420,6 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
414 struct i2c_client *picodlp_i2c_client; 420 struct i2c_client *picodlp_i2c_client;
415 int r = 0, picodlp_adapter_id; 421 int r = 0, picodlp_adapter_id;
416 422
417 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF |
418 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS;
419 dssdev->panel.acb = 0x0;
420 dssdev->panel.timings = pico_ls_timings; 423 dssdev->panel.timings = pico_ls_timings;
421 424
422 picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL); 425 picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL);
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index ba38b3ad17d6..bd86ba9ccf76 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -44,6 +44,12 @@ static struct omap_video_timings sharp_ls_timings = {
44 .vsw = 1, 44 .vsw = 1,
45 .vfp = 1, 45 .vfp = 1,
46 .vbp = 1, 46 .vbp = 1,
47
48 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
49 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
50 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
51 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
52 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
47}; 53};
48 54
49static int sharp_ls_bl_update_status(struct backlight_device *bl) 55static int sharp_ls_bl_update_status(struct backlight_device *bl)
@@ -86,9 +92,6 @@ static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
86 struct sharp_data *sd; 92 struct sharp_data *sd;
87 int r; 93 int r;
88 94
89 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
90 OMAP_DSS_LCD_IHS;
91 dssdev->panel.acb = 0x28;
92 dssdev->panel.timings = sharp_ls_timings; 95 dssdev->panel.timings = sharp_ls_timings;
93 96
94 sd = kzalloc(sizeof(*sd), GFP_KERNEL); 97 sd = kzalloc(sizeof(*sd), GFP_KERNEL);
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 901576eb5a84..3f5acc7771da 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -882,7 +882,6 @@ static int taal_probe(struct omap_dss_device *dssdev)
882 goto err; 882 goto err;
883 } 883 }
884 884
885 dssdev->panel.config = OMAP_DSS_LCD_TFT;
886 dssdev->panel.timings = panel_config->timings; 885 dssdev->panel.timings = panel_config->timings;
887 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; 886 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
888 887
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index bff306e041ca..40cc0cfa5d17 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -39,6 +39,12 @@ static const struct omap_video_timings tfp410_default_timings = {
39 .vfp = 3, 39 .vfp = 3,
40 .vsw = 4, 40 .vsw = 4,
41 .vbp = 7, 41 .vbp = 7,
42
43 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
44 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
45 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
46 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
47 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
42}; 48};
43 49
44struct panel_drv_data { 50struct panel_drv_data {
@@ -95,7 +101,6 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
95 return -ENOMEM; 101 return -ENOMEM;
96 102
97 dssdev->panel.timings = tfp410_default_timings; 103 dssdev->panel.timings = tfp410_default_timings;
98 dssdev->panel.config = OMAP_DSS_LCD_TFT;
99 104
100 ddata->dssdev = dssdev; 105 ddata->dssdev = dssdev;
101 mutex_init(&ddata->lock); 106 mutex_init(&ddata->lock);
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index 4b6448b3c31f..fa7baa650ae0 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -267,6 +267,12 @@ static const struct omap_video_timings tpo_td043_timings = {
267 .vsw = 1, 267 .vsw = 1,
268 .vfp = 39, 268 .vfp = 39,
269 .vbp = 34, 269 .vbp = 34,
270
271 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
272 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
273 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
274 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
275 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
270}; 276};
271 277
272static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) 278static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
@@ -423,8 +429,6 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
423 return -ENODEV; 429 return -ENODEV;
424 } 430 }
425 431
426 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS |
427 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC;
428 dssdev->panel.timings = tpo_td043_timings; 432 dssdev->panel.timings = tpo_td043_timings;
429 dssdev->ctrl.pixel_size = 24; 433 dssdev->ctrl.pixel_size = 24;
430 434
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 43324e5ed25f..b337a8469fd8 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -52,7 +52,7 @@ config OMAP2_DSS_RFBI
52 DBI is a bus between the host processor and a peripheral, 52 DBI is a bus between the host processor and a peripheral,
53 such as a display or a framebuffer chip. 53 such as a display or a framebuffer chip.
54 54
55 See http://www.mipi.org/ for DBI spesifications. 55 See http://www.mipi.org/ for DBI specifications.
56 56
57config OMAP2_DSS_VENC 57config OMAP2_DSS_VENC
58 bool "VENC support" 58 bool "VENC support"
@@ -92,7 +92,7 @@ config OMAP2_DSS_DSI
92 DSI is a high speed half-duplex serial interface between the host 92 DSI is a high speed half-duplex serial interface between the host
93 processor and a peripheral, such as a display or a framebuffer chip. 93 processor and a peripheral, such as a display or a framebuffer chip.
94 94
95 See http://www.mipi.org/ for DSI spesifications. 95 See http://www.mipi.org/ for DSI specifications.
96 96
97config OMAP2_DSS_MIN_FCK_PER_PCK 97config OMAP2_DSS_MIN_FCK_PER_PCK
98 int "Minimum FCK/PCK ratio (for scaling)" 98 int "Minimum FCK/PCK ratio (for scaling)"
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index ab22cc224f3e..0fefc68372b9 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -104,6 +104,7 @@ struct mgr_priv_data {
104 bool shadow_extra_info_dirty; 104 bool shadow_extra_info_dirty;
105 105
106 struct omap_video_timings timings; 106 struct omap_video_timings timings;
107 struct dss_lcd_mgr_config lcd_config;
107}; 108};
108 109
109static struct { 110static struct {
@@ -137,6 +138,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
137void dss_apply_init(void) 138void dss_apply_init(void)
138{ 139{
139 const int num_ovls = dss_feat_get_num_ovls(); 140 const int num_ovls = dss_feat_get_num_ovls();
141 struct mgr_priv_data *mp;
140 int i; 142 int i;
141 143
142 spin_lock_init(&data_lock); 144 spin_lock_init(&data_lock);
@@ -168,16 +170,35 @@ void dss_apply_init(void)
168 170
169 op->user_info = op->info; 171 op->user_info = op->info;
170 } 172 }
173
174 /*
175 * Initialize some of the lcd_config fields for TV manager, this lets
176 * us prevent checking if the manager is LCD or TV at some places
177 */
178 mp = &dss_data.mgr_priv_data_array[OMAP_DSS_CHANNEL_DIGIT];
179
180 mp->lcd_config.video_port_width = 24;
181 mp->lcd_config.clock_info.lck_div = 1;
182 mp->lcd_config.clock_info.pck_div = 1;
171} 183}
172 184
185/*
186 * A LCD manager's stallmode decides whether it is in manual or auto update. TV
187 * manager is always auto update, stallmode field for TV manager is false by
188 * default
189 */
173static bool ovl_manual_update(struct omap_overlay *ovl) 190static bool ovl_manual_update(struct omap_overlay *ovl)
174{ 191{
175 return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 192 struct mgr_priv_data *mp = get_mgr_priv(ovl->manager);
193
194 return mp->lcd_config.stallmode;
176} 195}
177 196
178static bool mgr_manual_update(struct omap_overlay_manager *mgr) 197static bool mgr_manual_update(struct omap_overlay_manager *mgr)
179{ 198{
180 return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 199 struct mgr_priv_data *mp = get_mgr_priv(mgr);
200
201 return mp->lcd_config.stallmode;
181} 202}
182 203
183static int dss_check_settings_low(struct omap_overlay_manager *mgr, 204static int dss_check_settings_low(struct omap_overlay_manager *mgr,
@@ -214,7 +235,7 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr,
214 ois[ovl->id] = oi; 235 ois[ovl->id] = oi;
215 } 236 }
216 237
217 return dss_mgr_check(mgr, mi, &mp->timings, ois); 238 return dss_mgr_check(mgr, mi, &mp->timings, &mp->lcd_config, ois);
218} 239}
219 240
220/* 241/*
@@ -537,7 +558,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
537{ 558{
538 struct ovl_priv_data *op = get_ovl_priv(ovl); 559 struct ovl_priv_data *op = get_ovl_priv(ovl);
539 struct omap_overlay_info *oi; 560 struct omap_overlay_info *oi;
540 bool ilace, replication; 561 bool replication;
541 struct mgr_priv_data *mp; 562 struct mgr_priv_data *mp;
542 int r; 563 int r;
543 564
@@ -550,11 +571,9 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
550 571
551 mp = get_mgr_priv(ovl->manager); 572 mp = get_mgr_priv(ovl->manager);
552 573
553 replication = dss_use_replication(ovl->manager->device, oi->color_mode); 574 replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
554
555 ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
556 575
557 r = dispc_ovl_setup(ovl->id, oi, ilace, replication, &mp->timings); 576 r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings);
558 if (r) { 577 if (r) {
559 /* 578 /*
560 * We can't do much here, as this function can be called from 579 * We can't do much here, as this function can be called from
@@ -635,6 +654,24 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
635 654
636 dispc_mgr_set_timings(mgr->id, &mp->timings); 655 dispc_mgr_set_timings(mgr->id, &mp->timings);
637 656
657 /* lcd_config parameters */
658 if (dss_mgr_is_lcd(mgr->id)) {
659 dispc_mgr_set_io_pad_mode(mp->lcd_config.io_pad_mode);
660
661 dispc_mgr_enable_stallmode(mgr->id, mp->lcd_config.stallmode);
662 dispc_mgr_enable_fifohandcheck(mgr->id,
663 mp->lcd_config.fifohandcheck);
664
665 dispc_mgr_set_clock_div(mgr->id, &mp->lcd_config.clock_info);
666
667 dispc_mgr_set_tft_data_lines(mgr->id,
668 mp->lcd_config.video_port_width);
669
670 dispc_lcd_enable_signal_polarity(mp->lcd_config.lcden_sig_polarity);
671
672 dispc_mgr_set_lcd_type_tft(mgr->id);
673 }
674
638 mp->extra_info_dirty = false; 675 mp->extra_info_dirty = false;
639 if (mp->updating) 676 if (mp->updating)
640 mp->shadow_extra_info_dirty = true; 677 mp->shadow_extra_info_dirty = true;
@@ -1294,6 +1331,44 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
1294 mutex_unlock(&apply_lock); 1331 mutex_unlock(&apply_lock);
1295} 1332}
1296 1333
1334static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
1335 const struct dss_lcd_mgr_config *config)
1336{
1337 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1338
1339 mp->lcd_config = *config;
1340 mp->extra_info_dirty = true;
1341}
1342
1343void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
1344 const struct dss_lcd_mgr_config *config)
1345{
1346 unsigned long flags;
1347 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1348
1349 mutex_lock(&apply_lock);
1350
1351 if (mp->enabled) {
1352 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
1353 mgr->name);
1354 goto out;
1355 }
1356
1357 spin_lock_irqsave(&data_lock, flags);
1358
1359 dss_apply_mgr_lcd_config(mgr, config);
1360
1361 dss_write_regs();
1362 dss_set_go_bits();
1363
1364 spin_unlock_irqrestore(&data_lock, flags);
1365
1366 wait_pending_extra_info_updates();
1367
1368out:
1369 mutex_unlock(&apply_lock);
1370}
1371
1297int dss_ovl_set_info(struct omap_overlay *ovl, 1372int dss_ovl_set_info(struct omap_overlay *ovl,
1298 struct omap_overlay_info *info) 1373 struct omap_overlay_info *info)
1299{ 1374{
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
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index f278080e1063..92d8a9be86fc 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -36,6 +36,8 @@
36#define DISPC_CONTROL2 0x0238 36#define DISPC_CONTROL2 0x0238
37#define DISPC_CONFIG2 0x0620 37#define DISPC_CONFIG2 0x0620
38#define DISPC_DIVISOR 0x0804 38#define DISPC_DIVISOR 0x0804
39#define DISPC_CONTROL3 0x0848
40#define DISPC_CONFIG3 0x084C
39 41
40/* DISPC overlay registers */ 42/* DISPC overlay registers */
41#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \ 43#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
@@ -118,6 +120,8 @@ static inline u16 DISPC_DEFAULT_COLOR(enum omap_channel channel)
118 return 0x0050; 120 return 0x0050;
119 case OMAP_DSS_CHANNEL_LCD2: 121 case OMAP_DSS_CHANNEL_LCD2:
120 return 0x03AC; 122 return 0x03AC;
123 case OMAP_DSS_CHANNEL_LCD3:
124 return 0x0814;
121 default: 125 default:
122 BUG(); 126 BUG();
123 return 0; 127 return 0;
@@ -133,6 +137,8 @@ static inline u16 DISPC_TRANS_COLOR(enum omap_channel channel)
133 return 0x0058; 137 return 0x0058;
134 case OMAP_DSS_CHANNEL_LCD2: 138 case OMAP_DSS_CHANNEL_LCD2:
135 return 0x03B0; 139 return 0x03B0;
140 case OMAP_DSS_CHANNEL_LCD3:
141 return 0x0818;
136 default: 142 default:
137 BUG(); 143 BUG();
138 return 0; 144 return 0;
@@ -149,6 +155,8 @@ static inline u16 DISPC_TIMING_H(enum omap_channel channel)
149 return 0; 155 return 0;
150 case OMAP_DSS_CHANNEL_LCD2: 156 case OMAP_DSS_CHANNEL_LCD2:
151 return 0x0400; 157 return 0x0400;
158 case OMAP_DSS_CHANNEL_LCD3:
159 return 0x0840;
152 default: 160 default:
153 BUG(); 161 BUG();
154 return 0; 162 return 0;
@@ -165,6 +173,8 @@ static inline u16 DISPC_TIMING_V(enum omap_channel channel)
165 return 0; 173 return 0;
166 case OMAP_DSS_CHANNEL_LCD2: 174 case OMAP_DSS_CHANNEL_LCD2:
167 return 0x0404; 175 return 0x0404;
176 case OMAP_DSS_CHANNEL_LCD3:
177 return 0x0844;
168 default: 178 default:
169 BUG(); 179 BUG();
170 return 0; 180 return 0;
@@ -181,6 +191,8 @@ static inline u16 DISPC_POL_FREQ(enum omap_channel channel)
181 return 0; 191 return 0;
182 case OMAP_DSS_CHANNEL_LCD2: 192 case OMAP_DSS_CHANNEL_LCD2:
183 return 0x0408; 193 return 0x0408;
194 case OMAP_DSS_CHANNEL_LCD3:
195 return 0x083C;
184 default: 196 default:
185 BUG(); 197 BUG();
186 return 0; 198 return 0;
@@ -197,6 +209,8 @@ static inline u16 DISPC_DIVISORo(enum omap_channel channel)
197 return 0; 209 return 0;
198 case OMAP_DSS_CHANNEL_LCD2: 210 case OMAP_DSS_CHANNEL_LCD2:
199 return 0x040C; 211 return 0x040C;
212 case OMAP_DSS_CHANNEL_LCD3:
213 return 0x0838;
200 default: 214 default:
201 BUG(); 215 BUG();
202 return 0; 216 return 0;
@@ -213,6 +227,8 @@ static inline u16 DISPC_SIZE_MGR(enum omap_channel channel)
213 return 0x0078; 227 return 0x0078;
214 case OMAP_DSS_CHANNEL_LCD2: 228 case OMAP_DSS_CHANNEL_LCD2:
215 return 0x03CC; 229 return 0x03CC;
230 case OMAP_DSS_CHANNEL_LCD3:
231 return 0x0834;
216 default: 232 default:
217 BUG(); 233 BUG();
218 return 0; 234 return 0;
@@ -229,6 +245,8 @@ static inline u16 DISPC_DATA_CYCLE1(enum omap_channel channel)
229 return 0; 245 return 0;
230 case OMAP_DSS_CHANNEL_LCD2: 246 case OMAP_DSS_CHANNEL_LCD2:
231 return 0x03C0; 247 return 0x03C0;
248 case OMAP_DSS_CHANNEL_LCD3:
249 return 0x0828;
232 default: 250 default:
233 BUG(); 251 BUG();
234 return 0; 252 return 0;
@@ -245,6 +263,8 @@ static inline u16 DISPC_DATA_CYCLE2(enum omap_channel channel)
245 return 0; 263 return 0;
246 case OMAP_DSS_CHANNEL_LCD2: 264 case OMAP_DSS_CHANNEL_LCD2:
247 return 0x03C4; 265 return 0x03C4;
266 case OMAP_DSS_CHANNEL_LCD3:
267 return 0x082C;
248 default: 268 default:
249 BUG(); 269 BUG();
250 return 0; 270 return 0;
@@ -261,6 +281,8 @@ static inline u16 DISPC_DATA_CYCLE3(enum omap_channel channel)
261 return 0; 281 return 0;
262 case OMAP_DSS_CHANNEL_LCD2: 282 case OMAP_DSS_CHANNEL_LCD2:
263 return 0x03C8; 283 return 0x03C8;
284 case OMAP_DSS_CHANNEL_LCD3:
285 return 0x0830;
264 default: 286 default:
265 BUG(); 287 BUG();
266 return 0; 288 return 0;
@@ -277,6 +299,8 @@ static inline u16 DISPC_CPR_COEF_R(enum omap_channel channel)
277 return 0; 299 return 0;
278 case OMAP_DSS_CHANNEL_LCD2: 300 case OMAP_DSS_CHANNEL_LCD2:
279 return 0x03BC; 301 return 0x03BC;
302 case OMAP_DSS_CHANNEL_LCD3:
303 return 0x0824;
280 default: 304 default:
281 BUG(); 305 BUG();
282 return 0; 306 return 0;
@@ -293,6 +317,8 @@ static inline u16 DISPC_CPR_COEF_G(enum omap_channel channel)
293 return 0; 317 return 0;
294 case OMAP_DSS_CHANNEL_LCD2: 318 case OMAP_DSS_CHANNEL_LCD2:
295 return 0x03B8; 319 return 0x03B8;
320 case OMAP_DSS_CHANNEL_LCD3:
321 return 0x0820;
296 default: 322 default:
297 BUG(); 323 BUG();
298 return 0; 324 return 0;
@@ -309,6 +335,8 @@ static inline u16 DISPC_CPR_COEF_B(enum omap_channel channel)
309 return 0; 335 return 0;
310 case OMAP_DSS_CHANNEL_LCD2: 336 case OMAP_DSS_CHANNEL_LCD2:
311 return 0x03B4; 337 return 0x03B4;
338 case OMAP_DSS_CHANNEL_LCD3:
339 return 0x081C;
312 default: 340 default:
313 BUG(); 341 BUG();
314 return 0; 342 return 0;
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 249010630370..5bd957e85505 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -116,7 +116,7 @@ static ssize_t display_timings_store(struct device *dev,
116 struct device_attribute *attr, const char *buf, size_t size) 116 struct device_attribute *attr, const char *buf, size_t size)
117{ 117{
118 struct omap_dss_device *dssdev = to_dss_device(dev); 118 struct omap_dss_device *dssdev = to_dss_device(dev);
119 struct omap_video_timings t; 119 struct omap_video_timings t = dssdev->panel.timings;
120 int r, found; 120 int r, found;
121 121
122 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings) 122 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
@@ -316,44 +316,6 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
316} 316}
317EXPORT_SYMBOL(omapdss_default_get_timings); 317EXPORT_SYMBOL(omapdss_default_get_timings);
318 318
319/* Checks if replication logic should be used. Only use for active matrix,
320 * when overlay is in RGB12U or RGB16 mode, and LCD interface is
321 * 18bpp or 24bpp */
322bool dss_use_replication(struct omap_dss_device *dssdev,
323 enum omap_color_mode mode)
324{
325 int bpp;
326
327 if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
328 return false;
329
330 if (dssdev->type == OMAP_DISPLAY_TYPE_DPI &&
331 (dssdev->panel.config & OMAP_DSS_LCD_TFT) == 0)
332 return false;
333
334 switch (dssdev->type) {
335 case OMAP_DISPLAY_TYPE_DPI:
336 bpp = dssdev->phy.dpi.data_lines;
337 break;
338 case OMAP_DISPLAY_TYPE_HDMI:
339 case OMAP_DISPLAY_TYPE_VENC:
340 case OMAP_DISPLAY_TYPE_SDI:
341 bpp = 24;
342 break;
343 case OMAP_DISPLAY_TYPE_DBI:
344 bpp = dssdev->ctrl.pixel_size;
345 break;
346 case OMAP_DISPLAY_TYPE_DSI:
347 bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
348 break;
349 default:
350 BUG();
351 return false;
352 }
353
354 return bpp > 16;
355}
356
357void dss_init_device(struct platform_device *pdev, 319void dss_init_device(struct platform_device *pdev,
358 struct omap_dss_device *dssdev) 320 struct omap_dss_device *dssdev)
359{ 321{
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 8c2056c9537b..3266be23fc0d 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -38,6 +38,8 @@
38static struct { 38static struct {
39 struct regulator *vdds_dsi_reg; 39 struct regulator *vdds_dsi_reg;
40 struct platform_device *dsidev; 40 struct platform_device *dsidev;
41
42 struct dss_lcd_mgr_config mgr_config;
41} dpi; 43} dpi;
42 44
43static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) 45static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@@ -64,7 +66,7 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
64 return false; 66 return false;
65} 67}
66 68
67static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, 69static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
68 unsigned long pck_req, unsigned long *fck, int *lck_div, 70 unsigned long pck_req, unsigned long *fck, int *lck_div,
69 int *pck_div) 71 int *pck_div)
70{ 72{
@@ -72,8 +74,8 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
72 struct dispc_clock_info dispc_cinfo; 74 struct dispc_clock_info dispc_cinfo;
73 int r; 75 int r;
74 76
75 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, pck_req, 77 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, pck_req, &dsi_cinfo,
76 &dsi_cinfo, &dispc_cinfo); 78 &dispc_cinfo);
77 if (r) 79 if (r)
78 return r; 80 return r;
79 81
@@ -83,11 +85,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
83 85
84 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); 86 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
85 87
86 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); 88 dpi.mgr_config.clock_info = dispc_cinfo;
87 if (r) {
88 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
89 return r;
90 }
91 89
92 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 90 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
93 *lck_div = dispc_cinfo.lck_div; 91 *lck_div = dispc_cinfo.lck_div;
@@ -96,7 +94,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
96 return 0; 94 return 0;
97} 95}
98 96
99static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft, 97static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
100 unsigned long pck_req, unsigned long *fck, int *lck_div, 98 unsigned long pck_req, unsigned long *fck, int *lck_div,
101 int *pck_div) 99 int *pck_div)
102{ 100{
@@ -104,7 +102,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
104 struct dispc_clock_info dispc_cinfo; 102 struct dispc_clock_info dispc_cinfo;
105 int r; 103 int r;
106 104
107 r = dss_calc_clock_div(is_tft, pck_req, &dss_cinfo, &dispc_cinfo); 105 r = dss_calc_clock_div(pck_req, &dss_cinfo, &dispc_cinfo);
108 if (r) 106 if (r)
109 return r; 107 return r;
110 108
@@ -112,9 +110,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
112 if (r) 110 if (r)
113 return r; 111 return r;
114 112
115 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); 113 dpi.mgr_config.clock_info = dispc_cinfo;
116 if (r)
117 return r;
118 114
119 *fck = dss_cinfo.fck; 115 *fck = dss_cinfo.fck;
120 *lck_div = dispc_cinfo.lck_div; 116 *lck_div = dispc_cinfo.lck_div;
@@ -129,20 +125,14 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
129 int lck_div = 0, pck_div = 0; 125 int lck_div = 0, pck_div = 0;
130 unsigned long fck = 0; 126 unsigned long fck = 0;
131 unsigned long pck; 127 unsigned long pck;
132 bool is_tft;
133 int r = 0; 128 int r = 0;
134 129
135 dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
136 dssdev->panel.acbi, dssdev->panel.acb);
137
138 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
139
140 if (dpi_use_dsi_pll(dssdev)) 130 if (dpi_use_dsi_pll(dssdev))
141 r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000, 131 r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
142 &fck, &lck_div, &pck_div); 132 &lck_div, &pck_div);
143 else 133 else
144 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000, 134 r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck,
145 &fck, &lck_div, &pck_div); 135 &lck_div, &pck_div);
146 if (r) 136 if (r)
147 return r; 137 return r;
148 138
@@ -161,19 +151,18 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
161 return 0; 151 return 0;
162} 152}
163 153
164static void dpi_basic_init(struct omap_dss_device *dssdev) 154static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
165{ 155{
166 bool is_tft; 156 dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
157
158 dpi.mgr_config.stallmode = false;
159 dpi.mgr_config.fifohandcheck = false;
167 160
168 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 161 dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines;
169 162
170 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS); 163 dpi.mgr_config.lcden_sig_polarity = 0;
171 dispc_mgr_enable_stallmode(dssdev->manager->id, false);
172 164
173 dispc_mgr_set_lcd_display_type(dssdev->manager->id, is_tft ? 165 dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
174 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
175 dispc_mgr_set_tft_data_lines(dssdev->manager->id,
176 dssdev->phy.dpi.data_lines);
177} 166}
178 167
179int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) 168int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
@@ -206,8 +195,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
206 if (r) 195 if (r)
207 goto err_get_dispc; 196 goto err_get_dispc;
208 197
209 dpi_basic_init(dssdev);
210
211 if (dpi_use_dsi_pll(dssdev)) { 198 if (dpi_use_dsi_pll(dssdev)) {
212 r = dsi_runtime_get(dpi.dsidev); 199 r = dsi_runtime_get(dpi.dsidev);
213 if (r) 200 if (r)
@@ -222,6 +209,8 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
222 if (r) 209 if (r)
223 goto err_set_mode; 210 goto err_set_mode;
224 211
212 dpi_config_lcd_manager(dssdev);
213
225 mdelay(2); 214 mdelay(2);
226 215
227 r = dss_mgr_enable(dssdev->manager); 216 r = dss_mgr_enable(dssdev->manager);
@@ -292,7 +281,6 @@ EXPORT_SYMBOL(dpi_set_timings);
292int dpi_check_timings(struct omap_dss_device *dssdev, 281int dpi_check_timings(struct omap_dss_device *dssdev,
293 struct omap_video_timings *timings) 282 struct omap_video_timings *timings)
294{ 283{
295 bool is_tft;
296 int r; 284 int r;
297 int lck_div, pck_div; 285 int lck_div, pck_div;
298 unsigned long fck; 286 unsigned long fck;
@@ -305,11 +293,9 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
305 if (timings->pixel_clock == 0) 293 if (timings->pixel_clock == 0)
306 return -EINVAL; 294 return -EINVAL;
307 295
308 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
309
310 if (dpi_use_dsi_pll(dssdev)) { 296 if (dpi_use_dsi_pll(dssdev)) {
311 struct dsi_clock_info dsi_cinfo; 297 struct dsi_clock_info dsi_cinfo;
312 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, 298 r = dsi_pll_calc_clock_div_pck(dpi.dsidev,
313 timings->pixel_clock * 1000, 299 timings->pixel_clock * 1000,
314 &dsi_cinfo, &dispc_cinfo); 300 &dsi_cinfo, &dispc_cinfo);
315 301
@@ -319,7 +305,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
319 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 305 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
320 } else { 306 } else {
321 struct dss_clock_info dss_cinfo; 307 struct dss_clock_info dss_cinfo;
322 r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000, 308 r = dss_calc_clock_div(timings->pixel_clock * 1000,
323 &dss_cinfo, &dispc_cinfo); 309 &dss_cinfo, &dispc_cinfo);
324 310
325 if (r) 311 if (r)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 14ce8cc079e3..b07e8864f82f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -331,6 +331,8 @@ struct dsi_data {
331 unsigned num_lanes_used; 331 unsigned num_lanes_used;
332 332
333 unsigned scp_clk_refcount; 333 unsigned scp_clk_refcount;
334
335 struct dss_lcd_mgr_config mgr_config;
334}; 336};
335 337
336struct dsi_packet_sent_handler_data { 338struct dsi_packet_sent_handler_data {
@@ -1085,9 +1087,9 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
1085 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1087 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1086 1088
1087 if (enable) 1089 if (enable)
1088 clk_enable(dsi->sys_clk); 1090 clk_prepare_enable(dsi->sys_clk);
1089 else 1091 else
1090 clk_disable(dsi->sys_clk); 1092 clk_disable_unprepare(dsi->sys_clk);
1091 1093
1092 if (enable && dsi->pll_locked) { 1094 if (enable && dsi->pll_locked) {
1093 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) 1095 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
@@ -1316,7 +1318,7 @@ static int dsi_calc_clock_rates(struct platform_device *dsidev,
1316 return 0; 1318 return 0;
1317} 1319}
1318 1320
1319int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, 1321int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
1320 unsigned long req_pck, struct dsi_clock_info *dsi_cinfo, 1322 unsigned long req_pck, struct dsi_clock_info *dsi_cinfo,
1321 struct dispc_clock_info *dispc_cinfo) 1323 struct dispc_clock_info *dispc_cinfo)
1322{ 1324{
@@ -1335,8 +1337,8 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
1335 dsi->cache_cinfo.clkin == dss_sys_clk) { 1337 dsi->cache_cinfo.clkin == dss_sys_clk) {
1336 DSSDBG("DSI clock info found from cache\n"); 1338 DSSDBG("DSI clock info found from cache\n");
1337 *dsi_cinfo = dsi->cache_cinfo; 1339 *dsi_cinfo = dsi->cache_cinfo;
1338 dispc_find_clk_divs(is_tft, req_pck, 1340 dispc_find_clk_divs(req_pck, dsi_cinfo->dsi_pll_hsdiv_dispc_clk,
1339 dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo); 1341 dispc_cinfo);
1340 return 0; 1342 return 0;
1341 } 1343 }
1342 1344
@@ -1402,7 +1404,7 @@ retry:
1402 1404
1403 match = 1; 1405 match = 1;
1404 1406
1405 dispc_find_clk_divs(is_tft, req_pck, 1407 dispc_find_clk_divs(req_pck,
1406 cur.dsi_pll_hsdiv_dispc_clk, 1408 cur.dsi_pll_hsdiv_dispc_clk,
1407 &cur_dispc); 1409 &cur_dispc);
1408 1410
@@ -3631,17 +3633,14 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
3631static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev) 3633static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
3632{ 3634{
3633 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3635 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3634 int de_pol = dssdev->panel.dsi_vm_data.vp_de_pol;
3635 int hsync_pol = dssdev->panel.dsi_vm_data.vp_hsync_pol;
3636 int vsync_pol = dssdev->panel.dsi_vm_data.vp_vsync_pol;
3637 bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end; 3636 bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end;
3638 bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end; 3637 bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
3639 u32 r; 3638 u32 r;
3640 3639
3641 r = dsi_read_reg(dsidev, DSI_CTRL); 3640 r = dsi_read_reg(dsidev, DSI_CTRL);
3642 r = FLD_MOD(r, de_pol, 9, 9); /* VP_DE_POL */ 3641 r = FLD_MOD(r, 1, 9, 9); /* VP_DE_POL */
3643 r = FLD_MOD(r, hsync_pol, 10, 10); /* VP_HSYNC_POL */ 3642 r = FLD_MOD(r, 1, 10, 10); /* VP_HSYNC_POL */
3644 r = FLD_MOD(r, vsync_pol, 11, 11); /* VP_VSYNC_POL */ 3643 r = FLD_MOD(r, 1, 11, 11); /* VP_VSYNC_POL */
3645 r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */ 3644 r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */
3646 r = FLD_MOD(r, vsync_end, 16, 16); /* VP_VSYNC_END */ 3645 r = FLD_MOD(r, vsync_end, 16, 16); /* VP_VSYNC_END */
3647 r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */ 3646 r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */
@@ -4340,52 +4339,101 @@ EXPORT_SYMBOL(omap_dsi_update);
4340 4339
4341/* Display funcs */ 4340/* Display funcs */
4342 4341
4342static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
4343{
4344 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4345 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4346 struct dispc_clock_info dispc_cinfo;
4347 int r;
4348 unsigned long long fck;
4349
4350 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
4351
4352 dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
4353 dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
4354
4355 r = dispc_calc_clock_rates(fck, &dispc_cinfo);
4356 if (r) {
4357 DSSERR("Failed to calc dispc clocks\n");
4358 return r;
4359 }
4360
4361 dsi->mgr_config.clock_info = dispc_cinfo;
4362
4363 return 0;
4364}
4365
4343static int dsi_display_init_dispc(struct omap_dss_device *dssdev) 4366static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4344{ 4367{
4368 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4369 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4370 struct omap_video_timings timings;
4345 int r; 4371 int r;
4372 u32 irq = 0;
4346 4373
4347 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { 4374 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
4348 u16 dw, dh; 4375 u16 dw, dh;
4349 u32 irq;
4350 struct omap_video_timings timings = {
4351 .hsw = 1,
4352 .hfp = 1,
4353 .hbp = 1,
4354 .vsw = 1,
4355 .vfp = 0,
4356 .vbp = 0,
4357 };
4358 4376
4359 dssdev->driver->get_resolution(dssdev, &dw, &dh); 4377 dssdev->driver->get_resolution(dssdev, &dw, &dh);
4378
4360 timings.x_res = dw; 4379 timings.x_res = dw;
4361 timings.y_res = dh; 4380 timings.y_res = dh;
4381 timings.hsw = 1;
4382 timings.hfp = 1;
4383 timings.hbp = 1;
4384 timings.vsw = 1;
4385 timings.vfp = 0;
4386 timings.vbp = 0;
4362 4387
4363 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? 4388 irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
4364 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
4365 4389
4366 r = omap_dispc_register_isr(dsi_framedone_irq_callback, 4390 r = omap_dispc_register_isr(dsi_framedone_irq_callback,
4367 (void *) dssdev, irq); 4391 (void *) dssdev, irq);
4368 if (r) { 4392 if (r) {
4369 DSSERR("can't get FRAMEDONE irq\n"); 4393 DSSERR("can't get FRAMEDONE irq\n");
4370 return r; 4394 goto err;
4371 } 4395 }
4372 4396
4373 dispc_mgr_enable_stallmode(dssdev->manager->id, true); 4397 dsi->mgr_config.stallmode = true;
4374 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1); 4398 dsi->mgr_config.fifohandcheck = true;
4375
4376 dss_mgr_set_timings(dssdev->manager, &timings);
4377 } else { 4399 } else {
4378 dispc_mgr_enable_stallmode(dssdev->manager->id, false); 4400 timings = dssdev->panel.timings;
4379 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0);
4380 4401
4381 dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); 4402 dsi->mgr_config.stallmode = false;
4403 dsi->mgr_config.fifohandcheck = false;
4382 } 4404 }
4383 4405
4384 dispc_mgr_set_lcd_display_type(dssdev->manager->id, 4406 /*
4385 OMAP_DSS_LCD_DISPLAY_TFT); 4407 * override interlace, logic level and edge related parameters in
4386 dispc_mgr_set_tft_data_lines(dssdev->manager->id, 4408 * omap_video_timings with default values
4387 dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)); 4409 */
4410 timings.interlace = false;
4411 timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
4412 timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
4413 timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
4414 timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
4415 timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
4416
4417 dss_mgr_set_timings(dssdev->manager, &timings);
4418
4419 r = dsi_configure_dispc_clocks(dssdev);
4420 if (r)
4421 goto err1;
4422
4423 dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
4424 dsi->mgr_config.video_port_width =
4425 dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
4426 dsi->mgr_config.lcden_sig_polarity = 0;
4427
4428 dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
4429
4388 return 0; 4430 return 0;
4431err1:
4432 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE)
4433 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4434 (void *) dssdev, irq);
4435err:
4436 return r;
4389} 4437}
4390 4438
4391static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) 4439static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
@@ -4393,8 +4441,7 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
4393 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { 4441 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
4394 u32 irq; 4442 u32 irq;
4395 4443
4396 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? 4444 irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
4397 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
4398 4445
4399 omap_dispc_unregister_isr(dsi_framedone_irq_callback, 4446 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4400 (void *) dssdev, irq); 4447 (void *) dssdev, irq);
@@ -4426,33 +4473,6 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
4426 return 0; 4473 return 0;
4427} 4474}
4428 4475
4429static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
4430{
4431 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4432 struct dispc_clock_info dispc_cinfo;
4433 int r;
4434 unsigned long long fck;
4435
4436 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
4437
4438 dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
4439 dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
4440
4441 r = dispc_calc_clock_rates(fck, &dispc_cinfo);
4442 if (r) {
4443 DSSERR("Failed to calc dispc clocks\n");
4444 return r;
4445 }
4446
4447 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
4448 if (r) {
4449 DSSERR("Failed to set dispc clocks\n");
4450 return r;
4451 }
4452
4453 return 0;
4454}
4455
4456static int dsi_display_init_dsi(struct omap_dss_device *dssdev) 4476static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4457{ 4477{
4458 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4478 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4474,10 +4494,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4474 4494
4475 DSSDBG("PLL OK\n"); 4495 DSSDBG("PLL OK\n");
4476 4496
4477 r = dsi_configure_dispc_clocks(dssdev);
4478 if (r)
4479 goto err2;
4480
4481 r = dsi_cio_init(dssdev); 4497 r = dsi_cio_init(dssdev);
4482 if (r) 4498 if (r)
4483 goto err2; 4499 goto err2;
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index d2b57197b292..04b4586113e3 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -388,7 +388,8 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
388 dsi_wait_pll_hsdiv_dispc_active(dsidev); 388 dsi_wait_pll_hsdiv_dispc_active(dsidev);
389 break; 389 break;
390 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 390 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
391 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2); 391 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
392 channel != OMAP_DSS_CHANNEL_LCD3);
392 b = 1; 393 b = 1;
393 dsidev = dsi_get_dsidev_from_id(1); 394 dsidev = dsi_get_dsidev_from_id(1);
394 dsi_wait_pll_hsdiv_dispc_active(dsidev); 395 dsi_wait_pll_hsdiv_dispc_active(dsidev);
@@ -398,10 +399,12 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
398 return; 399 return;
399 } 400 }
400 401
401 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12; 402 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
403 (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
402 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */ 404 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
403 405
404 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; 406 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
407 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
405 dss.lcd_clk_source[ix] = clk_src; 408 dss.lcd_clk_source[ix] = clk_src;
406} 409}
407 410
@@ -418,7 +421,8 @@ enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
418enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) 421enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
419{ 422{
420 if (dss_has_feature(FEAT_LCD_CLK_SRC)) { 423 if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
421 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; 424 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
425 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
422 return dss.lcd_clk_source[ix]; 426 return dss.lcd_clk_source[ix];
423 } else { 427 } else {
424 /* LCD_CLK source is the same as DISPC_FCLK source for 428 /* LCD_CLK source is the same as DISPC_FCLK source for
@@ -502,8 +506,7 @@ unsigned long dss_get_dpll4_rate(void)
502 return 0; 506 return 0;
503} 507}
504 508
505int dss_calc_clock_div(bool is_tft, unsigned long req_pck, 509int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
506 struct dss_clock_info *dss_cinfo,
507 struct dispc_clock_info *dispc_cinfo) 510 struct dispc_clock_info *dispc_cinfo)
508{ 511{
509 unsigned long prate; 512 unsigned long prate;
@@ -551,7 +554,7 @@ retry:
551 fck = clk_get_rate(dss.dss_clk); 554 fck = clk_get_rate(dss.dss_clk);
552 fck_div = 1; 555 fck_div = 1;
553 556
554 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 557 dispc_find_clk_divs(req_pck, fck, &cur_dispc);
555 match = 1; 558 match = 1;
556 559
557 best_dss.fck = fck; 560 best_dss.fck = fck;
@@ -581,7 +584,7 @@ retry:
581 584
582 match = 1; 585 match = 1;
583 586
584 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 587 dispc_find_clk_divs(req_pck, fck, &cur_dispc);
585 588
586 if (abs(cur_dispc.pck - req_pck) < 589 if (abs(cur_dispc.pck - req_pck) <
587 abs(best_dispc.pck - req_pck)) { 590 abs(best_dispc.pck - req_pck)) {
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index dd1092ceaeef..f67afe76f217 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -152,6 +152,25 @@ struct dsi_clock_info {
152 u16 lp_clk_div; 152 u16 lp_clk_div;
153}; 153};
154 154
155struct reg_field {
156 u16 reg;
157 u8 high;
158 u8 low;
159};
160
161struct dss_lcd_mgr_config {
162 enum dss_io_pad_mode io_pad_mode;
163
164 bool stallmode;
165 bool fifohandcheck;
166
167 struct dispc_clock_info clock_info;
168
169 int video_port_width;
170
171 int lcden_sig_polarity;
172};
173
155struct seq_file; 174struct seq_file;
156struct platform_device; 175struct platform_device;
157 176
@@ -188,6 +207,8 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
188int dss_mgr_unset_device(struct omap_overlay_manager *mgr); 207int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
189void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 208void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
190 struct omap_video_timings *timings); 209 struct omap_video_timings *timings);
210void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
211 const struct dss_lcd_mgr_config *config);
191const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); 212const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
192 213
193bool dss_ovl_is_enabled(struct omap_overlay *ovl); 214bool dss_ovl_is_enabled(struct omap_overlay *ovl);
@@ -210,8 +231,6 @@ void dss_init_device(struct platform_device *pdev,
210 struct omap_dss_device *dssdev); 231 struct omap_dss_device *dssdev);
211void dss_uninit_device(struct platform_device *pdev, 232void dss_uninit_device(struct platform_device *pdev,
212 struct omap_dss_device *dssdev); 233 struct omap_dss_device *dssdev);
213bool dss_use_replication(struct omap_dss_device *dssdev,
214 enum omap_color_mode mode);
215 234
216/* manager */ 235/* manager */
217int dss_init_overlay_managers(struct platform_device *pdev); 236int dss_init_overlay_managers(struct platform_device *pdev);
@@ -223,8 +242,18 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
223int dss_mgr_check(struct omap_overlay_manager *mgr, 242int dss_mgr_check(struct omap_overlay_manager *mgr,
224 struct omap_overlay_manager_info *info, 243 struct omap_overlay_manager_info *info,
225 const struct omap_video_timings *mgr_timings, 244 const struct omap_video_timings *mgr_timings,
245 const struct dss_lcd_mgr_config *config,
226 struct omap_overlay_info **overlay_infos); 246 struct omap_overlay_info **overlay_infos);
227 247
248static inline bool dss_mgr_is_lcd(enum omap_channel id)
249{
250 if (id == OMAP_DSS_CHANNEL_LCD || id == OMAP_DSS_CHANNEL_LCD2 ||
251 id == OMAP_DSS_CHANNEL_LCD3)
252 return true;
253 else
254 return false;
255}
256
228/* overlay */ 257/* overlay */
229void dss_init_overlays(struct platform_device *pdev); 258void dss_init_overlays(struct platform_device *pdev);
230void dss_uninit_overlays(struct platform_device *pdev); 259void dss_uninit_overlays(struct platform_device *pdev);
@@ -234,6 +263,8 @@ int dss_ovl_simple_check(struct omap_overlay *ovl,
234 const struct omap_overlay_info *info); 263 const struct omap_overlay_info *info);
235int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, 264int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
236 const struct omap_video_timings *mgr_timings); 265 const struct omap_video_timings *mgr_timings);
266bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
267 enum omap_color_mode mode);
237 268
238/* DSS */ 269/* DSS */
239int dss_init_platform_driver(void) __init; 270int dss_init_platform_driver(void) __init;
@@ -268,8 +299,7 @@ unsigned long dss_get_dpll4_rate(void);
268int dss_calc_clock_rates(struct dss_clock_info *cinfo); 299int dss_calc_clock_rates(struct dss_clock_info *cinfo);
269int dss_set_clock_div(struct dss_clock_info *cinfo); 300int dss_set_clock_div(struct dss_clock_info *cinfo);
270int dss_get_clock_div(struct dss_clock_info *cinfo); 301int dss_get_clock_div(struct dss_clock_info *cinfo);
271int dss_calc_clock_div(bool is_tft, unsigned long req_pck, 302int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
272 struct dss_clock_info *dss_cinfo,
273 struct dispc_clock_info *dispc_cinfo); 303 struct dispc_clock_info *dispc_cinfo);
274 304
275/* SDI */ 305/* SDI */
@@ -296,7 +326,7 @@ u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
296unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); 326unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
297int dsi_pll_set_clock_div(struct platform_device *dsidev, 327int dsi_pll_set_clock_div(struct platform_device *dsidev,
298 struct dsi_clock_info *cinfo); 328 struct dsi_clock_info *cinfo);
299int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, 329int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
300 unsigned long req_pck, struct dsi_clock_info *cinfo, 330 unsigned long req_pck, struct dsi_clock_info *cinfo,
301 struct dispc_clock_info *dispc_cinfo); 331 struct dispc_clock_info *dispc_cinfo);
302int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, 332int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
@@ -330,7 +360,7 @@ static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
330 return -ENODEV; 360 return -ENODEV;
331} 361}
332static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, 362static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
333 bool is_tft, unsigned long req_pck, 363 unsigned long req_pck,
334 struct dsi_clock_info *dsi_cinfo, 364 struct dsi_clock_info *dsi_cinfo,
335 struct dispc_clock_info *dispc_cinfo) 365 struct dispc_clock_info *dispc_cinfo)
336{ 366{
@@ -387,7 +417,7 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode);
387bool dispc_mgr_timings_ok(enum omap_channel channel, 417bool dispc_mgr_timings_ok(enum omap_channel channel,
388 const struct omap_video_timings *timings); 418 const struct omap_video_timings *timings);
389unsigned long dispc_fclk_rate(void); 419unsigned long dispc_fclk_rate(void);
390void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 420void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck,
391 struct dispc_clock_info *cinfo); 421 struct dispc_clock_info *cinfo);
392int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, 422int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
393 struct dispc_clock_info *cinfo); 423 struct dispc_clock_info *cinfo);
@@ -398,8 +428,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
398 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, 428 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
399 bool manual_update); 429 bool manual_update);
400int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 430int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
401 bool ilace, bool replication, 431 bool replication, const struct omap_video_timings *mgr_timings);
402 const struct omap_video_timings *mgr_timings);
403int dispc_ovl_enable(enum omap_plane plane, bool enable); 432int dispc_ovl_enable(enum omap_plane plane, bool enable);
404void dispc_ovl_set_channel_out(enum omap_plane plane, 433void dispc_ovl_set_channel_out(enum omap_plane plane,
405 enum omap_channel channel); 434 enum omap_channel channel);
@@ -415,16 +444,13 @@ bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
415void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode); 444void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
416void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable); 445void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
417void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); 446void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
418void dispc_mgr_set_lcd_display_type(enum omap_channel channel, 447void dispc_mgr_set_lcd_type_tft(enum omap_channel channel);
419 enum omap_lcd_display_type type);
420void dispc_mgr_set_timings(enum omap_channel channel, 448void dispc_mgr_set_timings(enum omap_channel channel,
421 struct omap_video_timings *timings); 449 struct omap_video_timings *timings);
422void dispc_mgr_set_pol_freq(enum omap_channel channel,
423 enum omap_panel_config config, u8 acbi, u8 acb);
424unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); 450unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
425unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); 451unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
426unsigned long dispc_core_clk_rate(void); 452unsigned long dispc_core_clk_rate(void);
427int dispc_mgr_set_clock_div(enum omap_channel channel, 453void dispc_mgr_set_clock_div(enum omap_channel channel,
428 struct dispc_clock_info *cinfo); 454 struct dispc_clock_info *cinfo);
429int dispc_mgr_get_clock_div(enum omap_channel channel, 455int dispc_mgr_get_clock_div(enum omap_channel channel,
430 struct dispc_clock_info *cinfo); 456 struct dispc_clock_info *cinfo);
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index bdf469f080e7..996ffcbfed58 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -24,9 +24,9 @@
24#include "ti_hdmi.h" 24#include "ti_hdmi.h"
25#endif 25#endif
26 26
27#define MAX_DSS_MANAGERS 3 27#define MAX_DSS_MANAGERS 4
28#define MAX_DSS_OVERLAYS 4 28#define MAX_DSS_OVERLAYS 4
29#define MAX_DSS_LCD_MANAGERS 2 29#define MAX_DSS_LCD_MANAGERS 3
30#define MAX_NUM_DSI 2 30#define MAX_NUM_DSI 2
31 31
32/* DSS has feature id */ 32/* DSS has feature id */
@@ -36,6 +36,7 @@ enum dss_feat_id {
36 FEAT_PCKFREEENABLE, 36 FEAT_PCKFREEENABLE,
37 FEAT_FUNCGATED, 37 FEAT_FUNCGATED,
38 FEAT_MGR_LCD2, 38 FEAT_MGR_LCD2,
39 FEAT_MGR_LCD3,
39 FEAT_LINEBUFFERSPLIT, 40 FEAT_LINEBUFFERSPLIT,
40 FEAT_ROWREPEATENABLE, 41 FEAT_ROWREPEATENABLE,
41 FEAT_RESIZECONF, 42 FEAT_RESIZECONF,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 26a2430a7028..060216fdc578 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -78,43 +78,214 @@ static struct {
78 */ 78 */
79 79
80static const struct hdmi_config cea_timings[] = { 80static const struct hdmi_config cea_timings[] = {
81{ {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} }, 81 {
82{ {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} }, 82 { 640, 480, 25200, 96, 16, 48, 2, 10, 33,
83{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} }, 83 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
84{ {1920, 540, 74250, 44, 88, 148, 5, 2, 15, 1, 1, 1}, {5, HDMI_HDMI} }, 84 false, },
85{ {1440, 240, 27027, 124, 38, 114, 3, 4, 15, 0, 0, 1}, {6, HDMI_HDMI} }, 85 { 1, HDMI_HDMI },
86{ {1920, 1080, 148500, 44, 88, 148, 5, 4, 36, 1, 1, 0}, {16, HDMI_HDMI} }, 86 },
87{ {720, 576, 27000, 64, 12, 68, 5, 5, 39, 0, 0, 0}, {17, HDMI_HDMI} }, 87 {
88{ {1280, 720, 74250, 40, 440, 220, 5, 5, 20, 1, 1, 0}, {19, HDMI_HDMI} }, 88 { 720, 480, 27027, 62, 16, 60, 6, 9, 30,
89{ {1920, 540, 74250, 44, 528, 148, 5, 2, 15, 1, 1, 1}, {20, HDMI_HDMI} }, 89 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
90{ {1440, 288, 27000, 126, 24, 138, 3, 2, 19, 0, 0, 1}, {21, HDMI_HDMI} }, 90 false, },
91{ {1440, 576, 54000, 128, 24, 136, 5, 5, 39, 0, 0, 0}, {29, HDMI_HDMI} }, 91 { 2, HDMI_HDMI },
92{ {1920, 1080, 148500, 44, 528, 148, 5, 4, 36, 1, 1, 0}, {31, HDMI_HDMI} }, 92 },
93{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} }, 93 {
94{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} }, 94 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
95{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} }, 95 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
96 false, },
97 { 4, HDMI_HDMI },
98 },
99 {
100 { 1920, 540, 74250, 44, 88, 148, 5, 2, 15,
101 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
102 true, },
103 { 5, HDMI_HDMI },
104 },
105 {
106 { 1440, 240, 27027, 124, 38, 114, 3, 4, 15,
107 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
108 true, },
109 { 6, HDMI_HDMI },
110 },
111 {
112 { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36,
113 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
114 false, },
115 { 16, HDMI_HDMI },
116 },
117 {
118 { 720, 576, 27000, 64, 12, 68, 5, 5, 39,
119 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
120 false, },
121 { 17, HDMI_HDMI },
122 },
123 {
124 { 1280, 720, 74250, 40, 440, 220, 5, 5, 20,
125 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
126 false, },
127 { 19, HDMI_HDMI },
128 },
129 {
130 { 1920, 540, 74250, 44, 528, 148, 5, 2, 15,
131 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
132 true, },
133 { 20, HDMI_HDMI },
134 },
135 {
136 { 1440, 288, 27000, 126, 24, 138, 3, 2, 19,
137 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
138 true, },
139 { 21, HDMI_HDMI },
140 },
141 {
142 { 1440, 576, 54000, 128, 24, 136, 5, 5, 39,
143 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
144 false, },
145 { 29, HDMI_HDMI },
146 },
147 {
148 { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36,
149 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
150 false, },
151 { 31, HDMI_HDMI },
152 },
153 {
154 { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36,
155 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
156 false, },
157 { 32, HDMI_HDMI },
158 },
159 {
160 { 2880, 480, 108108, 248, 64, 240, 6, 9, 30,
161 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
162 false, },
163 { 35, HDMI_HDMI },
164 },
165 {
166 { 2880, 576, 108000, 256, 48, 272, 5, 5, 39,
167 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
168 false, },
169 { 37, HDMI_HDMI },
170 },
96}; 171};
172
97static const struct hdmi_config vesa_timings[] = { 173static const struct hdmi_config vesa_timings[] = {
98/* VESA From Here */ 174/* VESA From Here */
99{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} }, 175 {
100{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} }, 176 { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
101{ {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} }, 177 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
102{ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} }, 178 false, },
103{ {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} }, 179 { 4, HDMI_DVI },
104{ {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} }, 180 },
105{ {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} }, 181 {
106{ {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38, 1, 1, 0}, {0x23, HDMI_DVI} }, 182 { 800, 600, 40000, 128, 40, 88, 4, 1, 23,
107{ {1024, 768, 65000, 136, 24, 160, 6, 3, 29, 0, 0, 0}, {0x10, HDMI_DVI} }, 183 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
108{ {1400, 1050, 121750, 144, 88, 232, 4, 3, 32, 1, 0, 0}, {0x2A, HDMI_DVI} }, 184 false, },
109{ {1440, 900, 106500, 152, 80, 232, 6, 3, 25, 1, 0, 0}, {0x2F, HDMI_DVI} }, 185 { 9, HDMI_DVI },
110{ {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, 1, 0, 0}, {0x3A, HDMI_DVI} }, 186 },
111{ {1366, 768, 85500, 143, 70, 213, 3, 3, 24, 1, 1, 0}, {0x51, HDMI_DVI} }, 187 {
112{ {1920, 1080, 148500, 44, 148, 80, 5, 4, 36, 1, 1, 0}, {0x52, HDMI_DVI} }, 188 { 848, 480, 33750, 112, 16, 112, 8, 6, 23,
113{ {1280, 768, 68250, 32, 48, 80, 7, 3, 12, 0, 1, 0}, {0x16, HDMI_DVI} }, 189 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
114{ {1400, 1050, 101000, 32, 48, 80, 4, 3, 23, 0, 1, 0}, {0x29, HDMI_DVI} }, 190 false, },
115{ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21, 0, 1, 0}, {0x39, HDMI_DVI} }, 191 { 0xE, HDMI_DVI },
116{ {1280, 800, 79500, 32, 48, 80, 6, 3, 14, 0, 1, 0}, {0x1B, HDMI_DVI} }, 192 },
117{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} } 193 {
194 { 1280, 768, 79500, 128, 64, 192, 7, 3, 20,
195 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
196 false, },
197 { 0x17, HDMI_DVI },
198 },
199 {
200 { 1280, 800, 83500, 128, 72, 200, 6, 3, 22,
201 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
202 false, },
203 { 0x1C, HDMI_DVI },
204 },
205 {
206 { 1360, 768, 85500, 112, 64, 256, 6, 3, 18,
207 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
208 false, },
209 { 0x27, HDMI_DVI },
210 },
211 {
212 { 1280, 960, 108000, 112, 96, 312, 3, 1, 36,
213 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
214 false, },
215 { 0x20, HDMI_DVI },
216 },
217 {
218 { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38,
219 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
220 false, },
221 { 0x23, HDMI_DVI },
222 },
223 {
224 { 1024, 768, 65000, 136, 24, 160, 6, 3, 29,
225 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
226 false, },
227 { 0x10, HDMI_DVI },
228 },
229 {
230 { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32,
231 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
232 false, },
233 { 0x2A, HDMI_DVI },
234 },
235 {
236 { 1440, 900, 106500, 152, 80, 232, 6, 3, 25,
237 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
238 false, },
239 { 0x2F, HDMI_DVI },
240 },
241 {
242 { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30,
243 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
244 false, },
245 { 0x3A, HDMI_DVI },
246 },
247 {
248 { 1366, 768, 85500, 143, 70, 213, 3, 3, 24,
249 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
250 false, },
251 { 0x51, HDMI_DVI },
252 },
253 {
254 { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36,
255 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
256 false, },
257 { 0x52, HDMI_DVI },
258 },
259 {
260 { 1280, 768, 68250, 32, 48, 80, 7, 3, 12,
261 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
262 false, },
263 { 0x16, HDMI_DVI },
264 },
265 {
266 { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23,
267 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
268 false, },
269 { 0x29, HDMI_DVI },
270 },
271 {
272 { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21,
273 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
274 false, },
275 { 0x39, HDMI_DVI },
276 },
277 {
278 { 1280, 800, 79500, 32, 48, 80, 6, 3, 14,
279 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
280 false, },
281 { 0x1B, HDMI_DVI },
282 },
283 {
284 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
285 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
286 false, },
287 { 0x55, HDMI_DVI },
288 },
118}; 289};
119 290
120static int hdmi_runtime_get(void) 291static int hdmi_runtime_get(void)
@@ -179,7 +350,7 @@ static const struct hdmi_config *hdmi_get_timings(void)
179} 350}
180 351
181static bool hdmi_timings_compare(struct omap_video_timings *timing1, 352static bool hdmi_timings_compare(struct omap_video_timings *timing1,
182 const struct hdmi_video_timings *timing2) 353 const struct omap_video_timings *timing2)
183{ 354{
184 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; 355 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
185 356
@@ -758,6 +929,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
758 hdmi.ip_data.core_av_offset = HDMI_CORE_AV; 929 hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
759 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 930 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
760 hdmi.ip_data.phy_offset = HDMI_PHY; 931 hdmi.ip_data.phy_offset = HDMI_PHY;
932 mutex_init(&hdmi.ip_data.lock);
761 933
762 hdmi_panel_init(); 934 hdmi_panel_init();
763 935
@@ -785,7 +957,7 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
785 957
786static int hdmi_runtime_suspend(struct device *dev) 958static int hdmi_runtime_suspend(struct device *dev)
787{ 959{
788 clk_disable(hdmi.sys_clk); 960 clk_disable_unprepare(hdmi.sys_clk);
789 961
790 dispc_runtime_put(); 962 dispc_runtime_put();
791 963
@@ -800,7 +972,7 @@ static int hdmi_runtime_resume(struct device *dev)
800 if (r < 0) 972 if (r < 0)
801 return r; 973 return r;
802 974
803 clk_enable(hdmi.sys_clk); 975 clk_prepare_enable(hdmi.sys_clk);
804 976
805 return 0; 977 return 0;
806} 978}
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 1179e3c4b1c7..e10844faadf9 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -43,10 +43,11 @@ static int hdmi_panel_probe(struct omap_dss_device *dssdev)
43{ 43{
44 DSSDBG("ENTER hdmi_panel_probe\n"); 44 DSSDBG("ENTER hdmi_panel_probe\n");
45 45
46 dssdev->panel.config = OMAP_DSS_LCD_TFT | 46 dssdev->panel.timings = (struct omap_video_timings)
47 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; 47 { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
48 48 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
49 dssdev->panel.timings = (struct omap_video_timings){640, 480, 25175, 96, 16, 48, 2 , 11, 31}; 49 false,
50 };
50 51
51 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", 52 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
52 dssdev->panel.timings.x_res, 53 dssdev->panel.timings.x_res,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 0cbcde4c688a..53710fadc82d 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -500,16 +500,12 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
500 if (r) 500 if (r)
501 return r; 501 return r;
502 502
503 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 503 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
504 irq = DISPC_IRQ_EVSYNC_ODD; 504 irq = DISPC_IRQ_EVSYNC_ODD;
505 } else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) { 505 else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI)
506 irq = DISPC_IRQ_EVSYNC_EVEN; 506 irq = DISPC_IRQ_EVSYNC_EVEN;
507 } else { 507 else
508 if (mgr->id == OMAP_DSS_CHANNEL_LCD) 508 irq = dispc_mgr_get_vsync_irq(mgr->id);
509 irq = DISPC_IRQ_VSYNC;
510 else
511 irq = DISPC_IRQ_VSYNC2;
512 }
513 509
514 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 510 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
515 511
@@ -545,6 +541,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
545 mgr->name = "lcd2"; 541 mgr->name = "lcd2";
546 mgr->id = OMAP_DSS_CHANNEL_LCD2; 542 mgr->id = OMAP_DSS_CHANNEL_LCD2;
547 break; 543 break;
544 case 3:
545 mgr->name = "lcd3";
546 mgr->id = OMAP_DSS_CHANNEL_LCD3;
547 break;
548 } 548 }
549 549
550 mgr->set_device = &dss_mgr_set_device; 550 mgr->set_device = &dss_mgr_set_device;
@@ -665,9 +665,40 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
665 return 0; 665 return 0;
666} 666}
667 667
668static int dss_mgr_check_lcd_config(struct omap_overlay_manager *mgr,
669 const struct dss_lcd_mgr_config *config)
670{
671 struct dispc_clock_info cinfo = config->clock_info;
672 int dl = config->video_port_width;
673 bool stallmode = config->stallmode;
674 bool fifohandcheck = config->fifohandcheck;
675
676 if (cinfo.lck_div < 1 || cinfo.lck_div > 255)
677 return -EINVAL;
678
679 if (cinfo.pck_div < 1 || cinfo.pck_div > 255)
680 return -EINVAL;
681
682 if (dl != 12 && dl != 16 && dl != 18 && dl != 24)
683 return -EINVAL;
684
685 /* fifohandcheck should be used only with stallmode */
686 if (stallmode == false && fifohandcheck == true)
687 return -EINVAL;
688
689 /*
690 * io pad mode can be only checked by using dssdev connected to the
691 * manager. Ignore checking these for now, add checks when manager
692 * is capable of holding information related to the connected interface
693 */
694
695 return 0;
696}
697
668int dss_mgr_check(struct omap_overlay_manager *mgr, 698int dss_mgr_check(struct omap_overlay_manager *mgr,
669 struct omap_overlay_manager_info *info, 699 struct omap_overlay_manager_info *info,
670 const struct omap_video_timings *mgr_timings, 700 const struct omap_video_timings *mgr_timings,
701 const struct dss_lcd_mgr_config *lcd_config,
671 struct omap_overlay_info **overlay_infos) 702 struct omap_overlay_info **overlay_infos)
672{ 703{
673 struct omap_overlay *ovl; 704 struct omap_overlay *ovl;
@@ -683,6 +714,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr,
683 if (r) 714 if (r)
684 return r; 715 return r;
685 716
717 r = dss_mgr_check_lcd_config(mgr, lcd_config);
718 if (r)
719 return r;
720
686 list_for_each_entry(ovl, &mgr->overlays, list) { 721 list_for_each_entry(ovl, &mgr->overlays, list) {
687 struct omap_overlay_info *oi; 722 struct omap_overlay_info *oi;
688 int r; 723 int r;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index b0ba60f88dd2..952c6fad9a81 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -528,14 +528,24 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
528 struct omap_overlay_manager *lcd_mgr; 528 struct omap_overlay_manager *lcd_mgr;
529 struct omap_overlay_manager *tv_mgr; 529 struct omap_overlay_manager *tv_mgr;
530 struct omap_overlay_manager *lcd2_mgr = NULL; 530 struct omap_overlay_manager *lcd2_mgr = NULL;
531 struct omap_overlay_manager *lcd3_mgr = NULL;
531 struct omap_overlay_manager *mgr = NULL; 532 struct omap_overlay_manager *mgr = NULL;
532 533
533 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); 534 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
534 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); 535 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
536 if (dss_has_feature(FEAT_MGR_LCD3))
537 lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
535 if (dss_has_feature(FEAT_MGR_LCD2)) 538 if (dss_has_feature(FEAT_MGR_LCD2))
536 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2); 539 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
537 540
538 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { 541 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
542 if (!lcd3_mgr->device || force) {
543 if (lcd3_mgr->device)
544 lcd3_mgr->unset_device(lcd3_mgr);
545 lcd3_mgr->set_device(lcd3_mgr, dssdev);
546 mgr = lcd3_mgr;
547 }
548 } else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
539 if (!lcd2_mgr->device || force) { 549 if (!lcd2_mgr->device || force) {
540 if (lcd2_mgr->device) 550 if (lcd2_mgr->device)
541 lcd2_mgr->unset_device(lcd2_mgr); 551 lcd2_mgr->unset_device(lcd2_mgr);
@@ -677,3 +687,16 @@ int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
677 687
678 return 0; 688 return 0;
679} 689}
690
691/*
692 * Checks if replication logic should be used. Only use when overlay is in
693 * RGB12U or RGB16 mode, and video port width interface is 18bpp or 24bpp
694 */
695bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
696 enum omap_color_mode mode)
697{
698 if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
699 return false;
700
701 return config.video_port_width > 16;
702}
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 7985fa12b9b4..7c087424b634 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -300,10 +300,11 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
300} 300}
301EXPORT_SYMBOL(omap_rfbi_write_pixels); 301EXPORT_SYMBOL(omap_rfbi_write_pixels);
302 302
303static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, 303static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
304 u16 height, void (*callback)(void *data), void *data) 304 u16 height, void (*callback)(void *data), void *data)
305{ 305{
306 u32 l; 306 u32 l;
307 int r;
307 struct omap_video_timings timings = { 308 struct omap_video_timings timings = {
308 .hsw = 1, 309 .hsw = 1,
309 .hfp = 1, 310 .hfp = 1,
@@ -322,7 +323,9 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
322 323
323 dss_mgr_set_timings(dssdev->manager, &timings); 324 dss_mgr_set_timings(dssdev->manager, &timings);
324 325
325 dispc_mgr_enable(dssdev->manager->id, true); 326 r = dss_mgr_enable(dssdev->manager);
327 if (r)
328 return r;
326 329
327 rfbi.framedone_callback = callback; 330 rfbi.framedone_callback = callback;
328 rfbi.framedone_callback_data = data; 331 rfbi.framedone_callback_data = data;
@@ -335,6 +338,8 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
335 l = FLD_MOD(l, 1, 4, 4); /* ITE */ 338 l = FLD_MOD(l, 1, 4, 4); /* ITE */
336 339
337 rfbi_write_reg(RFBI_CONTROL, l); 340 rfbi_write_reg(RFBI_CONTROL, l);
341
342 return 0;
338} 343}
339 344
340static void framedone_callback(void *data, u32 mask) 345static void framedone_callback(void *data, u32 mask)
@@ -814,8 +819,11 @@ int omap_rfbi_update(struct omap_dss_device *dssdev,
814 u16 x, u16 y, u16 w, u16 h, 819 u16 x, u16 y, u16 w, u16 h,
815 void (*callback)(void *), void *data) 820 void (*callback)(void *), void *data)
816{ 821{
817 rfbi_transfer_area(dssdev, w, h, callback, data); 822 int r;
818 return 0; 823
824 r = rfbi_transfer_area(dssdev, w, h, callback, data);
825
826 return r;
819} 827}
820EXPORT_SYMBOL(omap_rfbi_update); 828EXPORT_SYMBOL(omap_rfbi_update);
821 829
@@ -859,6 +867,22 @@ static void rfbi_dump_regs(struct seq_file *s)
859#undef DUMPREG 867#undef DUMPREG
860} 868}
861 869
870static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
871{
872 struct dss_lcd_mgr_config mgr_config;
873
874 mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
875
876 mgr_config.stallmode = true;
877 /* Do we need fifohandcheck for RFBI? */
878 mgr_config.fifohandcheck = false;
879
880 mgr_config.video_port_width = dssdev->ctrl.pixel_size;
881 mgr_config.lcden_sig_polarity = 0;
882
883 dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
884}
885
862int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 886int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
863{ 887{
864 int r; 888 int r;
@@ -885,13 +909,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
885 goto err1; 909 goto err1;
886 } 910 }
887 911
888 dispc_mgr_set_lcd_display_type(dssdev->manager->id, 912 rfbi_config_lcd_manager(dssdev);
889 OMAP_DSS_LCD_DISPLAY_TFT);
890
891 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_RFBI);
892 dispc_mgr_enable_stallmode(dssdev->manager->id, true);
893
894 dispc_mgr_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
895 913
896 rfbi_configure(dssdev->phy.rfbi.channel, 914 rfbi_configure(dssdev->phy.rfbi.channel,
897 dssdev->ctrl.pixel_size, 915 dssdev->ctrl.pixel_size,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3a43dc2a9b46..5d31699fbd3c 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -32,19 +32,21 @@
32static struct { 32static struct {
33 bool update_enabled; 33 bool update_enabled;
34 struct regulator *vdds_sdi_reg; 34 struct regulator *vdds_sdi_reg;
35} sdi;
36 35
37static void sdi_basic_init(struct omap_dss_device *dssdev) 36 struct dss_lcd_mgr_config mgr_config;
37} sdi;
38 38
39static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
39{ 40{
40 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS); 41 sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
41 dispc_mgr_enable_stallmode(dssdev->manager->id, false); 42
43 sdi.mgr_config.stallmode = false;
44 sdi.mgr_config.fifohandcheck = false;
42 45
43 dispc_mgr_set_lcd_display_type(dssdev->manager->id, 46 sdi.mgr_config.video_port_width = 24;
44 OMAP_DSS_LCD_DISPLAY_TFT); 47 sdi.mgr_config.lcden_sig_polarity = 1;
45 48
46 dispc_mgr_set_tft_data_lines(dssdev->manager->id, 24); 49 dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config);
47 dispc_lcd_enable_signal_polarity(1);
48} 50}
49 51
50int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) 52int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
@@ -52,8 +54,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
52 struct omap_video_timings *t = &dssdev->panel.timings; 54 struct omap_video_timings *t = &dssdev->panel.timings;
53 struct dss_clock_info dss_cinfo; 55 struct dss_clock_info dss_cinfo;
54 struct dispc_clock_info dispc_cinfo; 56 struct dispc_clock_info dispc_cinfo;
55 u16 lck_div, pck_div;
56 unsigned long fck;
57 unsigned long pck; 57 unsigned long pck;
58 int r; 58 int r;
59 59
@@ -76,24 +76,17 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
76 if (r) 76 if (r)
77 goto err_get_dispc; 77 goto err_get_dispc;
78 78
79 sdi_basic_init(dssdev);
80
81 /* 15.5.9.1.2 */ 79 /* 15.5.9.1.2 */
82 dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF; 80 dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
83 81 dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
84 dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
85 dssdev->panel.acbi, dssdev->panel.acb);
86 82
87 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 83 r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
88 &dss_cinfo, &dispc_cinfo);
89 if (r) 84 if (r)
90 goto err_calc_clock_div; 85 goto err_calc_clock_div;
91 86
92 fck = dss_cinfo.fck; 87 sdi.mgr_config.clock_info = dispc_cinfo;
93 lck_div = dispc_cinfo.lck_div;
94 pck_div = dispc_cinfo.pck_div;
95 88
96 pck = fck / lck_div / pck_div / 1000; 89 pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
97 90
98 if (pck != t->pixel_clock) { 91 if (pck != t->pixel_clock) {
99 DSSWARN("Could not find exact pixel clock. Requested %d kHz, " 92 DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
@@ -110,9 +103,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
110 if (r) 103 if (r)
111 goto err_set_dss_clock_div; 104 goto err_set_dss_clock_div;
112 105
113 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); 106 sdi_config_lcd_manager(dssdev);
114 if (r)
115 goto err_set_dispc_clock_div;
116 107
117 dss_sdi_init(dssdev->phy.sdi.datapairs); 108 dss_sdi_init(dssdev->phy.sdi.datapairs);
118 r = dss_sdi_enable(); 109 r = dss_sdi_enable();
@@ -129,7 +120,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
129err_mgr_enable: 120err_mgr_enable:
130 dss_sdi_disable(); 121 dss_sdi_disable();
131err_sdi_enable: 122err_sdi_enable:
132err_set_dispc_clock_div:
133err_set_dss_clock_div: 123err_set_dss_clock_div:
134err_calc_clock_div: 124err_calc_clock_div:
135 dispc_runtime_put(); 125 dispc_runtime_put();
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index e734cb444bc7..b046c208cb97 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -42,30 +42,13 @@ enum hdmi_clk_refsel {
42 HDMI_REFSEL_SYSCLK = 3 42 HDMI_REFSEL_SYSCLK = 3
43}; 43};
44 44
45/* HDMI timing structure */
46struct hdmi_video_timings {
47 u16 x_res;
48 u16 y_res;
49 /* Unit: KHz */
50 u32 pixel_clock;
51 u16 hsw;
52 u16 hfp;
53 u16 hbp;
54 u16 vsw;
55 u16 vfp;
56 u16 vbp;
57 bool vsync_pol;
58 bool hsync_pol;
59 bool interlace;
60};
61
62struct hdmi_cm { 45struct hdmi_cm {
63 int code; 46 int code;
64 int mode; 47 int mode;
65}; 48};
66 49
67struct hdmi_config { 50struct hdmi_config {
68 struct hdmi_video_timings timings; 51 struct omap_video_timings timings;
69 struct hdmi_cm cm; 52 struct hdmi_cm cm;
70}; 53};
71 54
@@ -177,7 +160,7 @@ struct hdmi_ip_data {
177 160
178 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ 161 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
179 int hpd_gpio; 162 int hpd_gpio;
180 bool phy_tx_enabled; 163 struct mutex lock;
181}; 164};
182int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); 165int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
183void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); 166void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index 4dae1b291079..c23b85a20cdc 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -157,6 +157,10 @@ static int hdmi_pll_init(struct hdmi_ip_data *ip_data)
157/* PHY_PWR_CMD */ 157/* PHY_PWR_CMD */
158static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val) 158static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val)
159{ 159{
160 /* Return if already the state */
161 if (REG_GET(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, 5, 4) == val)
162 return 0;
163
160 /* Command for power control of HDMI PHY */ 164 /* Command for power control of HDMI PHY */
161 REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6); 165 REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6);
162 166
@@ -231,21 +235,13 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
231 235
232static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data) 236static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
233{ 237{
234 unsigned long flags;
235 bool hpd; 238 bool hpd;
236 int r; 239 int r;
237 /* this should be in ti_hdmi_4xxx_ip private data */
238 static DEFINE_SPINLOCK(phy_tx_lock);
239 240
240 spin_lock_irqsave(&phy_tx_lock, flags); 241 mutex_lock(&ip_data->lock);
241 242
242 hpd = gpio_get_value(ip_data->hpd_gpio); 243 hpd = gpio_get_value(ip_data->hpd_gpio);
243 244
244 if (hpd == ip_data->phy_tx_enabled) {
245 spin_unlock_irqrestore(&phy_tx_lock, flags);
246 return 0;
247 }
248
249 if (hpd) 245 if (hpd)
250 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON); 246 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
251 else 247 else
@@ -257,9 +253,8 @@ static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
257 goto err; 253 goto err;
258 } 254 }
259 255
260 ip_data->phy_tx_enabled = hpd;
261err: 256err:
262 spin_unlock_irqrestore(&phy_tx_lock, flags); 257 mutex_unlock(&ip_data->lock);
263 return r; 258 return r;
264} 259}
265 260
@@ -327,7 +322,6 @@ void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
327 free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data); 322 free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
328 323
329 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); 324 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
330 ip_data->phy_tx_enabled = false;
331} 325}
332 326
333static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) 327static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
@@ -747,11 +741,15 @@ static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
747static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) 741static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data)
748{ 742{
749 u32 r; 743 u32 r;
744 bool vsync_pol, hsync_pol;
750 pr_debug("Enter hdmi_wp_video_config_interface\n"); 745 pr_debug("Enter hdmi_wp_video_config_interface\n");
751 746
747 vsync_pol = ip_data->cfg.timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
748 hsync_pol = ip_data->cfg.timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
749
752 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); 750 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG);
753 r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7); 751 r = FLD_MOD(r, vsync_pol, 7, 7);
754 r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6); 752 r = FLD_MOD(r, hsync_pol, 6, 6);
755 r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3); 753 r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3);
756 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ 754 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */
757 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); 755 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r);
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3907c8b6ecbc..3a220877461a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -272,6 +272,8 @@ const struct omap_video_timings omap_dss_pal_timings = {
272 .vsw = 5, 272 .vsw = 5,
273 .vfp = 5, 273 .vfp = 5,
274 .vbp = 41, 274 .vbp = 41,
275
276 .interlace = true,
275}; 277};
276EXPORT_SYMBOL(omap_dss_pal_timings); 278EXPORT_SYMBOL(omap_dss_pal_timings);
277 279
@@ -285,6 +287,8 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
285 .vsw = 6, 287 .vsw = 6,
286 .vfp = 6, 288 .vfp = 6,
287 .vbp = 31, 289 .vbp = 31,
290
291 .interlace = true,
288}; 292};
289EXPORT_SYMBOL(omap_dss_ntsc_timings); 293EXPORT_SYMBOL(omap_dss_ntsc_timings);
290 294
@@ -930,7 +934,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
930static int venc_runtime_suspend(struct device *dev) 934static int venc_runtime_suspend(struct device *dev)
931{ 935{
932 if (venc.tv_dac_clk) 936 if (venc.tv_dac_clk)
933 clk_disable(venc.tv_dac_clk); 937 clk_disable_unprepare(venc.tv_dac_clk);
934 938
935 dispc_runtime_put(); 939 dispc_runtime_put();
936 940
@@ -946,7 +950,7 @@ static int venc_runtime_resume(struct device *dev)
946 return r; 950 return r;
947 951
948 if (venc.tv_dac_clk) 952 if (venc.tv_dac_clk)
949 clk_enable(venc.tv_dac_clk); 953 clk_prepare_enable(venc.tv_dac_clk);
950 954
951 return 0; 955 return 0;
952} 956}
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 3450ea0966c9..08ec1a7103f2 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -733,6 +733,12 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
733 var->lower_margin = timings.vfp; 733 var->lower_margin = timings.vfp;
734 var->hsync_len = timings.hsw; 734 var->hsync_len = timings.hsw;
735 var->vsync_len = timings.vsw; 735 var->vsync_len = timings.vsw;
736 var->sync |= timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH ?
737 FB_SYNC_HOR_HIGH_ACT : 0;
738 var->sync |= timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH ?
739 FB_SYNC_VERT_HIGH_ACT : 0;
740 var->vmode = timings.interlace ?
741 FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
736 } else { 742 } else {
737 var->pixclock = 0; 743 var->pixclock = 0;
738 var->left_margin = 0; 744 var->left_margin = 0;
@@ -741,12 +747,10 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
741 var->lower_margin = 0; 747 var->lower_margin = 0;
742 var->hsync_len = 0; 748 var->hsync_len = 0;
743 var->vsync_len = 0; 749 var->vsync_len = 0;
750 var->sync = 0;
751 var->vmode = FB_VMODE_NONINTERLACED;
744 } 752 }
745 753
746 /* TODO: get these from panel->config */
747 var->vmode = FB_VMODE_NONINTERLACED;
748 var->sync = 0;
749
750 return 0; 754 return 0;
751} 755}
752 756
@@ -1993,6 +1997,7 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1993} 1997}
1994 1998
1995static int omapfb_mode_to_timings(const char *mode_str, 1999static int omapfb_mode_to_timings(const char *mode_str,
2000 struct omap_dss_device *display,
1996 struct omap_video_timings *timings, u8 *bpp) 2001 struct omap_video_timings *timings, u8 *bpp)
1997{ 2002{
1998 struct fb_info *fbi; 2003 struct fb_info *fbi;
@@ -2046,6 +2051,14 @@ static int omapfb_mode_to_timings(const char *mode_str,
2046 goto err; 2051 goto err;
2047 } 2052 }
2048 2053
2054 if (display->driver->get_timings) {
2055 display->driver->get_timings(display, timings);
2056 } else {
2057 timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
2058 timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
2059 timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
2060 }
2061
2049 timings->pixel_clock = PICOS2KHZ(var->pixclock); 2062 timings->pixel_clock = PICOS2KHZ(var->pixclock);
2050 timings->hbp = var->left_margin; 2063 timings->hbp = var->left_margin;
2051 timings->hfp = var->right_margin; 2064 timings->hfp = var->right_margin;
@@ -2055,6 +2068,13 @@ static int omapfb_mode_to_timings(const char *mode_str,
2055 timings->vsw = var->vsync_len; 2068 timings->vsw = var->vsync_len;
2056 timings->x_res = var->xres; 2069 timings->x_res = var->xres;
2057 timings->y_res = var->yres; 2070 timings->y_res = var->yres;
2071 timings->hsync_level = var->sync & FB_SYNC_HOR_HIGH_ACT ?
2072 OMAPDSS_SIG_ACTIVE_HIGH :
2073 OMAPDSS_SIG_ACTIVE_LOW;
2074 timings->vsync_level = var->sync & FB_SYNC_VERT_HIGH_ACT ?
2075 OMAPDSS_SIG_ACTIVE_HIGH :
2076 OMAPDSS_SIG_ACTIVE_LOW;
2077 timings->interlace = var->vmode & FB_VMODE_INTERLACED;
2058 2078
2059 switch (var->bits_per_pixel) { 2079 switch (var->bits_per_pixel) {
2060 case 16: 2080 case 16:
@@ -2085,7 +2105,7 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2085 struct omap_video_timings timings, temp_timings; 2105 struct omap_video_timings timings, temp_timings;
2086 struct omapfb_display_data *d; 2106 struct omapfb_display_data *d;
2087 2107
2088 r = omapfb_mode_to_timings(mode_str, &timings, &bpp); 2108 r = omapfb_mode_to_timings(mode_str, display, &timings, &bpp);
2089 if (r) 2109 if (r)
2090 return r; 2110 return r;
2091 2111
@@ -2178,8 +2198,17 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2178} 2198}
2179 2199
2180static void fb_videomode_to_omap_timings(struct fb_videomode *m, 2200static void fb_videomode_to_omap_timings(struct fb_videomode *m,
2201 struct omap_dss_device *display,
2181 struct omap_video_timings *t) 2202 struct omap_video_timings *t)
2182{ 2203{
2204 if (display->driver->get_timings) {
2205 display->driver->get_timings(display, t);
2206 } else {
2207 t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
2208 t->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
2209 t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
2210 }
2211
2183 t->x_res = m->xres; 2212 t->x_res = m->xres;
2184 t->y_res = m->yres; 2213 t->y_res = m->yres;
2185 t->pixel_clock = PICOS2KHZ(m->pixclock); 2214 t->pixel_clock = PICOS2KHZ(m->pixclock);
@@ -2189,6 +2218,13 @@ static void fb_videomode_to_omap_timings(struct fb_videomode *m,
2189 t->vsw = m->vsync_len; 2218 t->vsw = m->vsync_len;
2190 t->vfp = m->lower_margin; 2219 t->vfp = m->lower_margin;
2191 t->vbp = m->upper_margin; 2220 t->vbp = m->upper_margin;
2221 t->hsync_level = m->sync & FB_SYNC_HOR_HIGH_ACT ?
2222 OMAPDSS_SIG_ACTIVE_HIGH :
2223 OMAPDSS_SIG_ACTIVE_LOW;
2224 t->vsync_level = m->sync & FB_SYNC_VERT_HIGH_ACT ?
2225 OMAPDSS_SIG_ACTIVE_HIGH :
2226 OMAPDSS_SIG_ACTIVE_LOW;
2227 t->interlace = m->vmode & FB_VMODE_INTERLACED;
2192} 2228}
2193 2229
2194static int omapfb_find_best_mode(struct omap_dss_device *display, 2230static int omapfb_find_best_mode(struct omap_dss_device *display,
@@ -2231,7 +2267,7 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
2231 if (m->xres == 2880 || m->xres == 1440) 2267 if (m->xres == 2880 || m->xres == 1440)
2232 continue; 2268 continue;
2233 2269
2234 fb_videomode_to_omap_timings(m, &t); 2270 fb_videomode_to_omap_timings(m, display, &t);
2235 2271
2236 r = display->driver->check_timings(display, &t); 2272 r = display->driver->check_timings(display, &t);
2237 if (r == 0 && best_xres < m->xres) { 2273 if (r == 0 && best_xres < m->xres) {
@@ -2245,7 +2281,8 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
2245 goto err2; 2281 goto err2;
2246 } 2282 }
2247 2283
2248 fb_videomode_to_omap_timings(&specs->modedb[best_idx], timings); 2284 fb_videomode_to_omap_timings(&specs->modedb[best_idx], display,
2285 timings);
2249 2286
2250 r = 0; 2287 r = 0;
2251 2288