aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 23:43:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 23:43:40 -0400
commit437538267b672f9320833907f1b5acbb2605f4be (patch)
treed10173b35a5b86bc037bb2ece1b406d5575a2094 /drivers/video/omap2
parent9586c959bfc917695893bef0102433a7d0675691 (diff)
parent6bff98b455cf3e666fd0e3d0d908eba874de0eee (diff)
Merge tag 'fbdev-updates-for-3.4' of git://github.com/schandinat/linux-2.6
Pull fbdev updates for 3.4 from Florian Tobias Schandinat: - drivers for Samsung Exynos MIPI DSI and display port - i740fb to support those old Intel chips - large updates to OMAP, viafb and sh_mobile_lcdcfb - some updates to s3c-fb and udlfb, few patches to others Fix up conflicts in drivers/video/udlfb.c due to Key Sievers' fix making it in twice. * tag 'fbdev-updates-for-3.4' of git://github.com/schandinat/linux-2.6: (156 commits) Revert "video:uvesafb: Fix oops that uvesafb try to execute NX-protected page" OMAPDSS: register dss drivers in module init video: pxafb: add clk_prepare/clk_unprepare calls fbdev: bfin_adv7393fb: Drop needless include fbdev: sh_mipi_dsi: add extra phyctrl for sh_mipi_dsi_info fbdev: remove dependency of FB_SH_MOBILE_MERAM from FB_SH_MOBILE_LCDC Revert "MAINTAINERS: add entry for exynos mipi display drivers" fbdev: da8xx: add support for SP10Q010 display fbdev: da8xx:: fix reporting of the display timing info drivers/video/pvr2fb.c: ensure arguments to request_irq and free_irq are compatible OMAPDSS: APPLY: fix clearing shadow dirty flag with manual update fbdev: sh_mobile_meram: Implement system suspend/resume fbdev: sh_mobile_meram: Remove unneeded sanity checks fbdev: sh_mobile_meram: Don't perform update in register operation arm: mach-shmobile: Constify sh_mobile_meram_cfg structures fbdev: sh_mobile_lcdc: Don't store copy of platform data fbdev: sh_mobile_meram: Remove unused sh_mobile_meram_icb_cfg fields arm: mach-shmobile: Don't set MERAM ICB numbers in platform data fbdev: sh_mobile_meram: Allocate ICBs automatically fbdev: sh_mobile_meram: Use genalloc to manage MERAM allocation ...
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c13
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c23
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c12
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c12
-rw-r--r--drivers/video/omap2/displays/panel-taal.c4
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c177
-rw-r--r--drivers/video/omap2/dss/apply.c275
-rw-r--r--drivers/video/omap2/dss/core.c135
-rw-r--r--drivers/video/omap2/dss/dispc.c121
-rw-r--r--drivers/video/omap2/dss/dispc_coefs.c9
-rw-r--r--drivers/video/omap2/dss/display.c10
-rw-r--r--drivers/video/omap2/dss/dsi.c65
-rw-r--r--drivers/video/omap2/dss/dss.c17
-rw-r--r--drivers/video/omap2/dss/dss.h10
-rw-r--r--drivers/video/omap2/dss/dss_features.c181
-rw-r--r--drivers/video/omap2/dss/dss_features.h54
-rw-r--r--drivers/video/omap2/dss/hdmi.c278
-rw-r--r--drivers/video/omap2/dss/manager.c12
-rw-r--r--drivers/video/omap2/dss/rfbi.c36
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h56
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c94
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h47
-rw-r--r--drivers/video/omap2/dss/venc.c32
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c2
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c101
-rw-r--r--drivers/video/omap2/vram.c99
26 files changed, 993 insertions, 882 deletions
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 51a87e149e24..d26f37ac69d8 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -809,18 +809,7 @@ static struct spi_driver acx565akm_spi_driver = {
809 .remove = __devexit_p(acx565akm_spi_remove), 809 .remove = __devexit_p(acx565akm_spi_remove),
810}; 810};
811 811
812static int __init acx565akm_init(void) 812module_spi_driver(acx565akm_spi_driver);
813{
814 return spi_register_driver(&acx565akm_spi_driver);
815}
816
817static void __exit acx565akm_exit(void)
818{
819 spi_unregister_driver(&acx565akm_spi_driver);
820}
821
822module_init(acx565akm_init);
823module_exit(acx565akm_exit);
824 813
825MODULE_AUTHOR("Nokia Corporation"); 814MODULE_AUTHOR("Nokia Corporation");
826MODULE_DESCRIPTION("acx565akm LCD Driver"); 815MODULE_DESCRIPTION("acx565akm LCD Driver");
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 28b9a6d61b0f..30fe4dfeb227 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -363,6 +363,29 @@ static struct panel_config generic_dpi_panels[] = {
363 363
364 .name = "ortustech_com43h4m10xtc", 364 .name = "ortustech_com43h4m10xtc",
365 }, 365 },
366
367 /* Innolux AT080TN52 */
368 {
369 {
370 .x_res = 800,
371 .y_res = 600,
372
373 .pixel_clock = 41142,
374
375 .hsw = 20,
376 .hfp = 210,
377 .hbp = 46,
378
379 .vsw = 10,
380 .vfp = 12,
381 .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
387 .name = "innolux_at080tn52",
388 },
366}; 389};
367 390
368struct panel_drv_data { 391struct panel_drv_data {
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index e0eb35be303e..0841cc2b3f77 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -264,16 +264,6 @@ static struct spi_driver lb035q02_spi_driver = {
264 .remove = __devexit_p(lb035q02_panel_spi_remove), 264 .remove = __devexit_p(lb035q02_panel_spi_remove),
265}; 265};
266 266
267static int __init lb035q02_panel_drv_init(void) 267module_spi_driver(lb035q02_spi_driver);
268{
269 return spi_register_driver(&lb035q02_spi_driver);
270}
271
272static void __exit lb035q02_panel_drv_exit(void)
273{
274 spi_unregister_driver(&lb035q02_spi_driver);
275}
276 268
277module_init(lb035q02_panel_drv_init);
278module_exit(lb035q02_panel_drv_exit);
279MODULE_LICENSE("GPL"); 269MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 0eb31caddca8..8b38b39213f4 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -350,18 +350,8 @@ static struct spi_driver nec_8048_spi_driver = {
350 }, 350 },
351}; 351};
352 352
353static int __init nec_8048_lcd_init(void) 353module_spi_driver(nec_8048_spi_driver);
354{
355 return spi_register_driver(&nec_8048_spi_driver);
356}
357
358static void __exit nec_8048_lcd_exit(void)
359{
360 return spi_unregister_driver(&nec_8048_spi_driver);
361}
362 354
363module_init(nec_8048_lcd_init);
364module_exit(nec_8048_lcd_exit);
365MODULE_AUTHOR("Erik Gilling <konkers@android.com>"); 355MODULE_AUTHOR("Erik Gilling <konkers@android.com>");
366MODULE_DESCRIPTION("NEC-nl8048hl11-01b Driver"); 356MODULE_DESCRIPTION("NEC-nl8048hl11-01b Driver");
367MODULE_LICENSE("GPL"); 357MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 00c5c615585f..0f21fa5a16ae 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1019,14 +1019,12 @@ static int taal_probe(struct omap_dss_device *dssdev)
1019 if (panel_data->use_ext_te) { 1019 if (panel_data->use_ext_te) {
1020 int gpio = panel_data->ext_te_gpio; 1020 int gpio = panel_data->ext_te_gpio;
1021 1021
1022 r = gpio_request(gpio, "taal irq"); 1022 r = gpio_request_one(gpio, GPIOF_IN, "taal irq");
1023 if (r) { 1023 if (r) {
1024 dev_err(&dssdev->dev, "GPIO request failed\n"); 1024 dev_err(&dssdev->dev, "GPIO request failed\n");
1025 goto err_gpio; 1025 goto err_gpio;
1026 } 1026 }
1027 1027
1028 gpio_direction_input(gpio);
1029
1030 r = request_irq(gpio_to_irq(gpio), taal_te_isr, 1028 r = request_irq(gpio_to_irq(gpio), taal_te_isr,
1031 IRQF_TRIGGER_RISING, 1029 IRQF_TRIGGER_RISING,
1032 "taal vsync", dssdev); 1030 "taal vsync", dssdev);
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index e6649aa89591..32f3fcd7f0f0 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -47,16 +47,20 @@
47 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) 47 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
48 48
49static const u16 tpo_td043_def_gamma[12] = { 49static const u16 tpo_td043_def_gamma[12] = {
50 106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020 50 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
51}; 51};
52 52
53struct tpo_td043_device { 53struct tpo_td043_device {
54 struct spi_device *spi; 54 struct spi_device *spi;
55 struct regulator *vcc_reg; 55 struct regulator *vcc_reg;
56 int nreset_gpio;
56 u16 gamma[12]; 57 u16 gamma[12];
57 u32 mode; 58 u32 mode;
58 u32 hmirror:1; 59 u32 hmirror:1;
59 u32 vmirror:1; 60 u32 vmirror:1;
61 u32 powered_on:1;
62 u32 spi_suspended:1;
63 u32 power_on_resume:1;
60}; 64};
61 65
62static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) 66static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
@@ -265,28 +269,16 @@ static const struct omap_video_timings tpo_td043_timings = {
265 .vbp = 34, 269 .vbp = 34,
266}; 270};
267 271
268static int tpo_td043_power_on(struct omap_dss_device *dssdev) 272static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
269{ 273{
270 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 274 int nreset_gpio = tpo_td043->nreset_gpio;
271 int nreset_gpio = dssdev->reset_gpio;
272 int r;
273 275
274 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 276 if (tpo_td043->powered_on)
275 return 0; 277 return 0;
276 278
277 r = omapdss_dpi_display_enable(dssdev);
278 if (r)
279 goto err0;
280
281 if (dssdev->platform_enable) {
282 r = dssdev->platform_enable(dssdev);
283 if (r)
284 goto err1;
285 }
286
287 regulator_enable(tpo_td043->vcc_reg); 279 regulator_enable(tpo_td043->vcc_reg);
288 280
289 /* wait for power up */ 281 /* wait for regulator to stabilize */
290 msleep(160); 282 msleep(160);
291 283
292 if (gpio_is_valid(nreset_gpio)) 284 if (gpio_is_valid(nreset_gpio))
@@ -301,19 +293,15 @@ static int tpo_td043_power_on(struct omap_dss_device *dssdev)
301 tpo_td043->vmirror); 293 tpo_td043->vmirror);
302 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); 294 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
303 295
296 tpo_td043->powered_on = 1;
304 return 0; 297 return 0;
305err1:
306 omapdss_dpi_display_disable(dssdev);
307err0:
308 return r;
309} 298}
310 299
311static void tpo_td043_power_off(struct omap_dss_device *dssdev) 300static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
312{ 301{
313 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 302 int nreset_gpio = tpo_td043->nreset_gpio;
314 int nreset_gpio = dssdev->reset_gpio;
315 303
316 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 304 if (!tpo_td043->powered_on)
317 return; 305 return;
318 306
319 tpo_td043_write(tpo_td043->spi, 3, 307 tpo_td043_write(tpo_td043->spi, 3,
@@ -329,54 +317,94 @@ static void tpo_td043_power_off(struct omap_dss_device *dssdev)
329 317
330 regulator_disable(tpo_td043->vcc_reg); 318 regulator_disable(tpo_td043->vcc_reg);
331 319
320 tpo_td043->powered_on = 0;
321}
322
323static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
324{
325 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
326 int r;
327
328 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
329 return 0;
330
331 r = omapdss_dpi_display_enable(dssdev);
332 if (r)
333 goto err0;
334
335 if (dssdev->platform_enable) {
336 r = dssdev->platform_enable(dssdev);
337 if (r)
338 goto err1;
339 }
340
341 /*
342 * If we are resuming from system suspend, SPI clocks might not be
343 * enabled yet, so we'll program the LCD from SPI PM resume callback.
344 */
345 if (!tpo_td043->spi_suspended) {
346 r = tpo_td043_power_on(tpo_td043);
347 if (r)
348 goto err1;
349 }
350
351 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
352
353 return 0;
354err1:
355 omapdss_dpi_display_disable(dssdev);
356err0:
357 return r;
358}
359
360static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
361{
362 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
363
364 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
365 return;
366
332 if (dssdev->platform_disable) 367 if (dssdev->platform_disable)
333 dssdev->platform_disable(dssdev); 368 dssdev->platform_disable(dssdev);
334 369
335 omapdss_dpi_display_disable(dssdev); 370 omapdss_dpi_display_disable(dssdev);
371
372 if (!tpo_td043->spi_suspended)
373 tpo_td043_power_off(tpo_td043);
336} 374}
337 375
338static int tpo_td043_enable(struct omap_dss_device *dssdev) 376static int tpo_td043_enable(struct omap_dss_device *dssdev)
339{ 377{
340 int ret;
341
342 dev_dbg(&dssdev->dev, "enable\n"); 378 dev_dbg(&dssdev->dev, "enable\n");
343 379
344 ret = tpo_td043_power_on(dssdev); 380 return tpo_td043_enable_dss(dssdev);
345 if (ret)
346 return ret;
347
348 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
349
350 return 0;
351} 381}
352 382
353static void tpo_td043_disable(struct omap_dss_device *dssdev) 383static void tpo_td043_disable(struct omap_dss_device *dssdev)
354{ 384{
355 dev_dbg(&dssdev->dev, "disable\n"); 385 dev_dbg(&dssdev->dev, "disable\n");
356 386
357 tpo_td043_power_off(dssdev); 387 tpo_td043_disable_dss(dssdev);
358 388
359 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 389 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
360} 390}
361 391
362static int tpo_td043_suspend(struct omap_dss_device *dssdev) 392static int tpo_td043_suspend(struct omap_dss_device *dssdev)
363{ 393{
364 tpo_td043_power_off(dssdev); 394 dev_dbg(&dssdev->dev, "suspend\n");
395
396 tpo_td043_disable_dss(dssdev);
397
365 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 398 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
399
366 return 0; 400 return 0;
367} 401}
368 402
369static int tpo_td043_resume(struct omap_dss_device *dssdev) 403static int tpo_td043_resume(struct omap_dss_device *dssdev)
370{ 404{
371 int r = 0; 405 dev_dbg(&dssdev->dev, "resume\n");
372
373 r = tpo_td043_power_on(dssdev);
374 if (r)
375 return r;
376 406
377 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 407 return tpo_td043_enable_dss(dssdev);
378
379 return 0;
380} 408}
381 409
382static int tpo_td043_probe(struct omap_dss_device *dssdev) 410static int tpo_td043_probe(struct omap_dss_device *dssdev)
@@ -408,17 +436,12 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
408 } 436 }
409 437
410 if (gpio_is_valid(nreset_gpio)) { 438 if (gpio_is_valid(nreset_gpio)) {
411 ret = gpio_request(nreset_gpio, "lcd reset"); 439 ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW,
440 "lcd reset");
412 if (ret < 0) { 441 if (ret < 0) {
413 dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); 442 dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
414 goto fail_gpio_req; 443 goto fail_gpio_req;
415 } 444 }
416
417 ret = gpio_direction_output(nreset_gpio, 0);
418 if (ret < 0) {
419 dev_err(&dssdev->dev, "couldn't set GPIO direction\n");
420 goto fail_gpio_direction;
421 }
422 } 445 }
423 446
424 ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group); 447 ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
@@ -427,8 +450,6 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
427 450
428 return 0; 451 return 0;
429 452
430fail_gpio_direction:
431 gpio_free(nreset_gpio);
432fail_gpio_req: 453fail_gpio_req:
433 regulator_put(tpo_td043->vcc_reg); 454 regulator_put(tpo_td043->vcc_reg);
434fail_regulator: 455fail_regulator:
@@ -491,6 +512,7 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
491 return -ENOMEM; 512 return -ENOMEM;
492 513
493 tpo_td043->spi = spi; 514 tpo_td043->spi = spi;
515 tpo_td043->nreset_gpio = dssdev->reset_gpio;
494 dev_set_drvdata(&spi->dev, tpo_td043); 516 dev_set_drvdata(&spi->dev, tpo_td043);
495 dev_set_drvdata(&dssdev->dev, tpo_td043); 517 dev_set_drvdata(&dssdev->dev, tpo_td043);
496 518
@@ -509,27 +531,52 @@ static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
509 return 0; 531 return 0;
510} 532}
511 533
534#ifdef CONFIG_PM_SLEEP
535static int tpo_td043_spi_suspend(struct device *dev)
536{
537 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
538
539 dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043);
540
541 tpo_td043->power_on_resume = tpo_td043->powered_on;
542 tpo_td043_power_off(tpo_td043);
543 tpo_td043->spi_suspended = 1;
544
545 return 0;
546}
547
548static int tpo_td043_spi_resume(struct device *dev)
549{
550 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
551 int ret;
552
553 dev_dbg(dev, "tpo_td043_spi_resume\n");
554
555 if (tpo_td043->power_on_resume) {
556 ret = tpo_td043_power_on(tpo_td043);
557 if (ret)
558 return ret;
559 }
560 tpo_td043->spi_suspended = 0;
561
562 return 0;
563}
564#endif
565
566static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
567 tpo_td043_spi_suspend, tpo_td043_spi_resume);
568
512static struct spi_driver tpo_td043_spi_driver = { 569static struct spi_driver tpo_td043_spi_driver = {
513 .driver = { 570 .driver = {
514 .name = "tpo_td043mtea1_panel_spi", 571 .name = "tpo_td043mtea1_panel_spi",
515 .owner = THIS_MODULE, 572 .owner = THIS_MODULE,
573 .pm = &tpo_td043_spi_pm,
516 }, 574 },
517 .probe = tpo_td043_spi_probe, 575 .probe = tpo_td043_spi_probe,
518 .remove = __devexit_p(tpo_td043_spi_remove), 576 .remove = __devexit_p(tpo_td043_spi_remove),
519}; 577};
520 578
521static int __init tpo_td043_init(void) 579module_spi_driver(tpo_td043_spi_driver);
522{
523 return spi_register_driver(&tpo_td043_spi_driver);
524}
525
526static void __exit tpo_td043_exit(void)
527{
528 spi_unregister_driver(&tpo_td043_spi_driver);
529}
530
531module_init(tpo_td043_init);
532module_exit(tpo_td043_exit);
533 580
534MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>"); 581MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
535MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); 582MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 87b3e25294cf..b10b3bc1931e 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -105,6 +105,9 @@ static struct {
105 struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; 105 struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
106 struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; 106 struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
107 107
108 bool fifo_merge_dirty;
109 bool fifo_merge;
110
108 bool irq_enabled; 111 bool irq_enabled;
109} dss_data; 112} dss_data;
110 113
@@ -351,6 +354,7 @@ static void wait_pending_extra_info_updates(void)
351 bool updating; 354 bool updating;
352 unsigned long flags; 355 unsigned long flags;
353 unsigned long t; 356 unsigned long t;
357 int r;
354 358
355 spin_lock_irqsave(&data_lock, flags); 359 spin_lock_irqsave(&data_lock, flags);
356 360
@@ -366,11 +370,11 @@ static void wait_pending_extra_info_updates(void)
366 spin_unlock_irqrestore(&data_lock, flags); 370 spin_unlock_irqrestore(&data_lock, flags);
367 371
368 t = msecs_to_jiffies(500); 372 t = msecs_to_jiffies(500);
369 wait_for_completion_timeout(&extra_updated_completion, t); 373 r = wait_for_completion_timeout(&extra_updated_completion, t);
370 374 if (r == 0)
371 updating = extra_info_update_ongoing(); 375 DSSWARN("timeout in wait_pending_extra_info_updates\n");
372 376 else if (r < 0)
373 WARN_ON(updating); 377 DSSERR("wait_pending_extra_info_updates failed: %d\n", r);
374} 378}
375 379
376int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) 380int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
@@ -388,6 +392,10 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
388 if (mgr_manual_update(mgr)) 392 if (mgr_manual_update(mgr))
389 return 0; 393 return 0;
390 394
395 r = dispc_runtime_get();
396 if (r)
397 return r;
398
391 irq = dispc_mgr_get_vsync_irq(mgr->id); 399 irq = dispc_mgr_get_vsync_irq(mgr->id);
392 400
393 mp = get_mgr_priv(mgr); 401 mp = get_mgr_priv(mgr);
@@ -428,6 +436,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
428 } 436 }
429 } 437 }
430 438
439 dispc_runtime_put();
440
431 return r; 441 return r;
432} 442}
433 443
@@ -451,6 +461,10 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
451 if (ovl_manual_update(ovl)) 461 if (ovl_manual_update(ovl))
452 return 0; 462 return 0;
453 463
464 r = dispc_runtime_get();
465 if (r)
466 return r;
467
454 irq = dispc_mgr_get_vsync_irq(ovl->manager->id); 468 irq = dispc_mgr_get_vsync_irq(ovl->manager->id);
455 469
456 op = get_ovl_priv(ovl); 470 op = get_ovl_priv(ovl);
@@ -491,6 +505,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
491 } 505 }
492 } 506 }
493 507
508 dispc_runtime_put();
509
494 return r; 510 return r;
495} 511}
496 512
@@ -585,11 +601,40 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
585 } 601 }
586} 602}
587 603
604static void dss_write_regs_common(void)
605{
606 const int num_mgrs = omap_dss_get_num_overlay_managers();
607 int i;
608
609 if (!dss_data.fifo_merge_dirty)
610 return;
611
612 for (i = 0; i < num_mgrs; ++i) {
613 struct omap_overlay_manager *mgr;
614 struct mgr_priv_data *mp;
615
616 mgr = omap_dss_get_overlay_manager(i);
617 mp = get_mgr_priv(mgr);
618
619 if (mp->enabled) {
620 if (dss_data.fifo_merge_dirty) {
621 dispc_enable_fifomerge(dss_data.fifo_merge);
622 dss_data.fifo_merge_dirty = false;
623 }
624
625 if (mp->updating)
626 mp->shadow_info_dirty = true;
627 }
628 }
629}
630
588static void dss_write_regs(void) 631static void dss_write_regs(void)
589{ 632{
590 const int num_mgrs = omap_dss_get_num_overlay_managers(); 633 const int num_mgrs = omap_dss_get_num_overlay_managers();
591 int i; 634 int i;
592 635
636 dss_write_regs_common();
637
593 for (i = 0; i < num_mgrs; ++i) { 638 for (i = 0; i < num_mgrs; ++i) {
594 struct omap_overlay_manager *mgr; 639 struct omap_overlay_manager *mgr;
595 struct mgr_priv_data *mp; 640 struct mgr_priv_data *mp;
@@ -640,6 +685,22 @@ static void dss_set_go_bits(void)
640 685
641} 686}
642 687
688static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
689{
690 struct omap_overlay *ovl;
691 struct mgr_priv_data *mp;
692 struct ovl_priv_data *op;
693
694 mp = get_mgr_priv(mgr);
695 mp->shadow_info_dirty = false;
696
697 list_for_each_entry(ovl, &mgr->overlays, list) {
698 op = get_ovl_priv(ovl);
699 op->shadow_info_dirty = false;
700 op->shadow_extra_info_dirty = false;
701 }
702}
703
643void dss_mgr_start_update(struct omap_overlay_manager *mgr) 704void dss_mgr_start_update(struct omap_overlay_manager *mgr)
644{ 705{
645 struct mgr_priv_data *mp = get_mgr_priv(mgr); 706 struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -659,6 +720,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
659 720
660 dss_mgr_write_regs(mgr); 721 dss_mgr_write_regs(mgr);
661 722
723 dss_write_regs_common();
724
662 mp->updating = true; 725 mp->updating = true;
663 726
664 if (!dss_data.irq_enabled && need_isr()) 727 if (!dss_data.irq_enabled && need_isr())
@@ -666,6 +729,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
666 729
667 dispc_mgr_enable(mgr->id, true); 730 dispc_mgr_enable(mgr->id, true);
668 731
732 mgr_clear_shadow_dirty(mgr);
733
669 spin_unlock_irqrestore(&data_lock, flags); 734 spin_unlock_irqrestore(&data_lock, flags);
670} 735}
671 736
@@ -709,22 +774,6 @@ static void dss_unregister_vsync_isr(void)
709 dss_data.irq_enabled = false; 774 dss_data.irq_enabled = false;
710} 775}
711 776
712static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
713{
714 struct omap_overlay *ovl;
715 struct mgr_priv_data *mp;
716 struct ovl_priv_data *op;
717
718 mp = get_mgr_priv(mgr);
719 mp->shadow_info_dirty = false;
720
721 list_for_each_entry(ovl, &mgr->overlays, list) {
722 op = get_ovl_priv(ovl);
723 op->shadow_info_dirty = false;
724 op->shadow_extra_info_dirty = false;
725 }
726}
727
728static void dss_apply_irq_handler(void *data, u32 mask) 777static void dss_apply_irq_handler(void *data, u32 mask)
729{ 778{
730 const int num_mgrs = dss_feat_get_num_mgrs(); 779 const int num_mgrs = dss_feat_get_num_mgrs();
@@ -754,9 +803,6 @@ static void dss_apply_irq_handler(void *data, u32 mask)
754 803
755 if (was_busy && !mp->busy) 804 if (was_busy && !mp->busy)
756 mgr_clear_shadow_dirty(mgr); 805 mgr_clear_shadow_dirty(mgr);
757 } else {
758 if (was_updating && !mp->updating)
759 mgr_clear_shadow_dirty(mgr);
760 } 806 }
761 } 807 }
762 808
@@ -859,11 +905,20 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
859 op->extra_info_dirty = true; 905 op->extra_info_dirty = true;
860} 906}
861 907
862static void dss_ovl_setup_fifo(struct omap_overlay *ovl) 908static void dss_apply_fifo_merge(bool use_fifo_merge)
909{
910 if (dss_data.fifo_merge == use_fifo_merge)
911 return;
912
913 dss_data.fifo_merge = use_fifo_merge;
914 dss_data.fifo_merge_dirty = true;
915}
916
917static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
918 bool use_fifo_merge)
863{ 919{
864 struct ovl_priv_data *op = get_ovl_priv(ovl); 920 struct ovl_priv_data *op = get_ovl_priv(ovl);
865 struct omap_dss_device *dssdev; 921 struct omap_dss_device *dssdev;
866 u32 size, burst_size;
867 u32 fifo_low, fifo_high; 922 u32 fifo_low, fifo_high;
868 923
869 if (!op->enabled && !op->enabling) 924 if (!op->enabled && !op->enabling)
@@ -871,33 +926,14 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
871 926
872 dssdev = ovl->manager->device; 927 dssdev = ovl->manager->device;
873 928
874 size = dispc_ovl_get_fifo_size(ovl->id); 929 dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high,
875 930 use_fifo_merge);
876 burst_size = dispc_ovl_get_burst_size(ovl->id);
877
878 switch (dssdev->type) {
879 case OMAP_DISPLAY_TYPE_DPI:
880 case OMAP_DISPLAY_TYPE_DBI:
881 case OMAP_DISPLAY_TYPE_SDI:
882 case OMAP_DISPLAY_TYPE_VENC:
883 case OMAP_DISPLAY_TYPE_HDMI:
884 default_get_overlay_fifo_thresholds(ovl->id, size,
885 burst_size, &fifo_low, &fifo_high);
886 break;
887#ifdef CONFIG_OMAP2_DSS_DSI
888 case OMAP_DISPLAY_TYPE_DSI:
889 dsi_get_overlay_fifo_thresholds(ovl->id, size,
890 burst_size, &fifo_low, &fifo_high);
891 break;
892#endif
893 default:
894 BUG();
895 }
896 931
897 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); 932 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
898} 933}
899 934
900static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) 935static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
936 bool use_fifo_merge)
901{ 937{
902 struct omap_overlay *ovl; 938 struct omap_overlay *ovl;
903 struct mgr_priv_data *mp; 939 struct mgr_priv_data *mp;
@@ -908,19 +944,94 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
908 return; 944 return;
909 945
910 list_for_each_entry(ovl, &mgr->overlays, list) 946 list_for_each_entry(ovl, &mgr->overlays, list)
911 dss_ovl_setup_fifo(ovl); 947 dss_ovl_setup_fifo(ovl, use_fifo_merge);
948}
949
950static void dss_setup_fifos(bool use_fifo_merge)
951{
952 const int num_mgrs = omap_dss_get_num_overlay_managers();
953 struct omap_overlay_manager *mgr;
954 int i;
955
956 for (i = 0; i < num_mgrs; ++i) {
957 mgr = omap_dss_get_overlay_manager(i);
958 dss_mgr_setup_fifos(mgr, use_fifo_merge);
959 }
912} 960}
913 961
914static void dss_setup_fifos(void) 962static int get_num_used_managers(void)
915{ 963{
916 const int num_mgrs = omap_dss_get_num_overlay_managers(); 964 const int num_mgrs = omap_dss_get_num_overlay_managers();
917 struct omap_overlay_manager *mgr; 965 struct omap_overlay_manager *mgr;
966 struct mgr_priv_data *mp;
918 int i; 967 int i;
968 int enabled_mgrs;
969
970 enabled_mgrs = 0;
919 971
920 for (i = 0; i < num_mgrs; ++i) { 972 for (i = 0; i < num_mgrs; ++i) {
921 mgr = omap_dss_get_overlay_manager(i); 973 mgr = omap_dss_get_overlay_manager(i);
922 dss_mgr_setup_fifos(mgr); 974 mp = get_mgr_priv(mgr);
975
976 if (!mp->enabled)
977 continue;
978
979 enabled_mgrs++;
980 }
981
982 return enabled_mgrs;
983}
984
985static int get_num_used_overlays(void)
986{
987 const int num_ovls = omap_dss_get_num_overlays();
988 struct omap_overlay *ovl;
989 struct ovl_priv_data *op;
990 struct mgr_priv_data *mp;
991 int i;
992 int enabled_ovls;
993
994 enabled_ovls = 0;
995
996 for (i = 0; i < num_ovls; ++i) {
997 ovl = omap_dss_get_overlay(i);
998 op = get_ovl_priv(ovl);
999
1000 if (!op->enabled && !op->enabling)
1001 continue;
1002
1003 mp = get_mgr_priv(ovl->manager);
1004
1005 if (!mp->enabled)
1006 continue;
1007
1008 enabled_ovls++;
923 } 1009 }
1010
1011 return enabled_ovls;
1012}
1013
1014static bool get_use_fifo_merge(void)
1015{
1016 int enabled_mgrs = get_num_used_managers();
1017 int enabled_ovls = get_num_used_overlays();
1018
1019 if (!dss_has_feature(FEAT_FIFO_MERGE))
1020 return false;
1021
1022 /*
1023 * In theory the only requirement for fifomerge is enabled_ovls <= 1.
1024 * However, if we have two managers enabled and set/unset the fifomerge,
1025 * we need to set the GO bits in particular sequence for the managers,
1026 * and wait in between.
1027 *
1028 * This is rather difficult as new apply calls can happen at any time,
1029 * so we simplify the problem by requiring also that enabled_mgrs <= 1.
1030 * In practice this shouldn't matter, because when only one overlay is
1031 * enabled, most likely only one output is enabled.
1032 */
1033
1034 return enabled_mgrs <= 1 && enabled_ovls <= 1;
924} 1035}
925 1036
926int dss_mgr_enable(struct omap_overlay_manager *mgr) 1037int dss_mgr_enable(struct omap_overlay_manager *mgr)
@@ -928,6 +1039,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
928 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1039 struct mgr_priv_data *mp = get_mgr_priv(mgr);
929 unsigned long flags; 1040 unsigned long flags;
930 int r; 1041 int r;
1042 bool fifo_merge;
931 1043
932 mutex_lock(&apply_lock); 1044 mutex_lock(&apply_lock);
933 1045
@@ -945,11 +1057,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
945 goto err; 1057 goto err;
946 } 1058 }
947 1059
948 dss_setup_fifos(); 1060 /* step 1: setup fifos/fifomerge before enabling the manager */
1061
1062 fifo_merge = get_use_fifo_merge();
1063 dss_setup_fifos(fifo_merge);
1064 dss_apply_fifo_merge(fifo_merge);
949 1065
950 dss_write_regs(); 1066 dss_write_regs();
951 dss_set_go_bits(); 1067 dss_set_go_bits();
952 1068
1069 spin_unlock_irqrestore(&data_lock, flags);
1070
1071 /* wait until fifo config is in */
1072 wait_pending_extra_info_updates();
1073
1074 /* step 2: enable the manager */
1075 spin_lock_irqsave(&data_lock, flags);
1076
953 if (!mgr_manual_update(mgr)) 1077 if (!mgr_manual_update(mgr))
954 mp->updating = true; 1078 mp->updating = true;
955 1079
@@ -974,6 +1098,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
974{ 1098{
975 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1099 struct mgr_priv_data *mp = get_mgr_priv(mgr);
976 unsigned long flags; 1100 unsigned long flags;
1101 bool fifo_merge;
977 1102
978 mutex_lock(&apply_lock); 1103 mutex_lock(&apply_lock);
979 1104
@@ -988,8 +1113,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
988 mp->updating = false; 1113 mp->updating = false;
989 mp->enabled = false; 1114 mp->enabled = false;
990 1115
1116 fifo_merge = get_use_fifo_merge();
1117 dss_setup_fifos(fifo_merge);
1118 dss_apply_fifo_merge(fifo_merge);
1119
1120 dss_write_regs();
1121 dss_set_go_bits();
1122
991 spin_unlock_irqrestore(&data_lock, flags); 1123 spin_unlock_irqrestore(&data_lock, flags);
992 1124
1125 wait_pending_extra_info_updates();
993out: 1126out:
994 mutex_unlock(&apply_lock); 1127 mutex_unlock(&apply_lock);
995} 1128}
@@ -1241,6 +1374,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1241{ 1374{
1242 struct ovl_priv_data *op = get_ovl_priv(ovl); 1375 struct ovl_priv_data *op = get_ovl_priv(ovl);
1243 unsigned long flags; 1376 unsigned long flags;
1377 bool fifo_merge;
1244 int r; 1378 int r;
1245 1379
1246 mutex_lock(&apply_lock); 1380 mutex_lock(&apply_lock);
@@ -1266,7 +1400,22 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1266 goto err2; 1400 goto err2;
1267 } 1401 }
1268 1402
1269 dss_setup_fifos(); 1403 /* step 1: configure fifos/fifomerge for currently enabled ovls */
1404
1405 fifo_merge = get_use_fifo_merge();
1406 dss_setup_fifos(fifo_merge);
1407 dss_apply_fifo_merge(fifo_merge);
1408
1409 dss_write_regs();
1410 dss_set_go_bits();
1411
1412 spin_unlock_irqrestore(&data_lock, flags);
1413
1414 /* wait for fifo configs to go in */
1415 wait_pending_extra_info_updates();
1416
1417 /* step 2: enable the overlay */
1418 spin_lock_irqsave(&data_lock, flags);
1270 1419
1271 op->enabling = false; 1420 op->enabling = false;
1272 dss_apply_ovl_enable(ovl, true); 1421 dss_apply_ovl_enable(ovl, true);
@@ -1294,6 +1443,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1294{ 1443{
1295 struct ovl_priv_data *op = get_ovl_priv(ovl); 1444 struct ovl_priv_data *op = get_ovl_priv(ovl);
1296 unsigned long flags; 1445 unsigned long flags;
1446 bool fifo_merge;
1297 int r; 1447 int r;
1298 1448
1299 mutex_lock(&apply_lock); 1449 mutex_lock(&apply_lock);
@@ -1308,9 +1458,11 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1308 goto err; 1458 goto err;
1309 } 1459 }
1310 1460
1461 /* step 1: disable the overlay */
1311 spin_lock_irqsave(&data_lock, flags); 1462 spin_lock_irqsave(&data_lock, flags);
1312 1463
1313 dss_apply_ovl_enable(ovl, false); 1464 dss_apply_ovl_enable(ovl, false);
1465
1314 dss_write_regs(); 1466 dss_write_regs();
1315 dss_set_go_bits(); 1467 dss_set_go_bits();
1316 1468
@@ -1319,6 +1471,21 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1319 /* wait for the overlay to be disabled */ 1471 /* wait for the overlay to be disabled */
1320 wait_pending_extra_info_updates(); 1472 wait_pending_extra_info_updates();
1321 1473
1474 /* step 2: configure fifos/fifomerge */
1475 spin_lock_irqsave(&data_lock, flags);
1476
1477 fifo_merge = get_use_fifo_merge();
1478 dss_setup_fifos(fifo_merge);
1479 dss_apply_fifo_merge(fifo_merge);
1480
1481 dss_write_regs();
1482 dss_set_go_bits();
1483
1484 spin_unlock_irqrestore(&data_lock, flags);
1485
1486 /* wait for fifo config to go in */
1487 wait_pending_extra_info_updates();
1488
1322 mutex_unlock(&apply_lock); 1489 mutex_unlock(&apply_lock);
1323 1490
1324 return 0; 1491 return 0;
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 8613f86fb56d..e8a120771ac6 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -183,42 +183,6 @@ static int omap_dss_probe(struct platform_device *pdev)
183 dss_init_overlay_managers(pdev); 183 dss_init_overlay_managers(pdev);
184 dss_init_overlays(pdev); 184 dss_init_overlays(pdev);
185 185
186 r = dss_init_platform_driver();
187 if (r) {
188 DSSERR("Failed to initialize DSS platform driver\n");
189 goto err_dss;
190 }
191
192 r = dispc_init_platform_driver();
193 if (r) {
194 DSSERR("Failed to initialize dispc platform driver\n");
195 goto err_dispc;
196 }
197
198 r = rfbi_init_platform_driver();
199 if (r) {
200 DSSERR("Failed to initialize rfbi platform driver\n");
201 goto err_rfbi;
202 }
203
204 r = venc_init_platform_driver();
205 if (r) {
206 DSSERR("Failed to initialize venc platform driver\n");
207 goto err_venc;
208 }
209
210 r = dsi_init_platform_driver();
211 if (r) {
212 DSSERR("Failed to initialize DSI platform driver\n");
213 goto err_dsi;
214 }
215
216 r = hdmi_init_platform_driver();
217 if (r) {
218 DSSERR("Failed to initialize hdmi\n");
219 goto err_hdmi;
220 }
221
222 r = dss_initialize_debugfs(); 186 r = dss_initialize_debugfs();
223 if (r) 187 if (r)
224 goto err_debugfs; 188 goto err_debugfs;
@@ -246,18 +210,6 @@ static int omap_dss_probe(struct platform_device *pdev)
246err_register: 210err_register:
247 dss_uninitialize_debugfs(); 211 dss_uninitialize_debugfs();
248err_debugfs: 212err_debugfs:
249 hdmi_uninit_platform_driver();
250err_hdmi:
251 dsi_uninit_platform_driver();
252err_dsi:
253 venc_uninit_platform_driver();
254err_venc:
255 dispc_uninit_platform_driver();
256err_dispc:
257 rfbi_uninit_platform_driver();
258err_rfbi:
259 dss_uninit_platform_driver();
260err_dss:
261 213
262 return r; 214 return r;
263} 215}
@@ -269,13 +221,6 @@ static int omap_dss_remove(struct platform_device *pdev)
269 221
270 dss_uninitialize_debugfs(); 222 dss_uninitialize_debugfs();
271 223
272 hdmi_uninit_platform_driver();
273 dsi_uninit_platform_driver();
274 venc_uninit_platform_driver();
275 rfbi_uninit_platform_driver();
276 dispc_uninit_platform_driver();
277 dss_uninit_platform_driver();
278
279 dss_uninit_overlays(pdev); 224 dss_uninit_overlays(pdev);
280 dss_uninit_overlay_managers(pdev); 225 dss_uninit_overlay_managers(pdev);
281 226
@@ -525,6 +470,80 @@ static int omap_dss_bus_register(void)
525 470
526/* INIT */ 471/* INIT */
527 472
473static int __init omap_dss_register_drivers(void)
474{
475 int r;
476
477 r = platform_driver_register(&omap_dss_driver);
478 if (r)
479 return r;
480
481 r = dss_init_platform_driver();
482 if (r) {
483 DSSERR("Failed to initialize DSS platform driver\n");
484 goto err_dss;
485 }
486
487 r = dispc_init_platform_driver();
488 if (r) {
489 DSSERR("Failed to initialize dispc platform driver\n");
490 goto err_dispc;
491 }
492
493 r = rfbi_init_platform_driver();
494 if (r) {
495 DSSERR("Failed to initialize rfbi platform driver\n");
496 goto err_rfbi;
497 }
498
499 r = venc_init_platform_driver();
500 if (r) {
501 DSSERR("Failed to initialize venc platform driver\n");
502 goto err_venc;
503 }
504
505 r = dsi_init_platform_driver();
506 if (r) {
507 DSSERR("Failed to initialize DSI platform driver\n");
508 goto err_dsi;
509 }
510
511 r = hdmi_init_platform_driver();
512 if (r) {
513 DSSERR("Failed to initialize hdmi\n");
514 goto err_hdmi;
515 }
516
517 return 0;
518
519err_hdmi:
520 dsi_uninit_platform_driver();
521err_dsi:
522 venc_uninit_platform_driver();
523err_venc:
524 rfbi_uninit_platform_driver();
525err_rfbi:
526 dispc_uninit_platform_driver();
527err_dispc:
528 dss_uninit_platform_driver();
529err_dss:
530 platform_driver_unregister(&omap_dss_driver);
531
532 return r;
533}
534
535static void __exit omap_dss_unregister_drivers(void)
536{
537 hdmi_uninit_platform_driver();
538 dsi_uninit_platform_driver();
539 venc_uninit_platform_driver();
540 rfbi_uninit_platform_driver();
541 dispc_uninit_platform_driver();
542 dss_uninit_platform_driver();
543
544 platform_driver_unregister(&omap_dss_driver);
545}
546
528#ifdef CONFIG_OMAP2_DSS_MODULE 547#ifdef CONFIG_OMAP2_DSS_MODULE
529static void omap_dss_bus_unregister(void) 548static void omap_dss_bus_unregister(void)
530{ 549{
@@ -541,7 +560,7 @@ static int __init omap_dss_init(void)
541 if (r) 560 if (r)
542 return r; 561 return r;
543 562
544 r = platform_driver_register(&omap_dss_driver); 563 r = omap_dss_register_drivers();
545 if (r) { 564 if (r) {
546 omap_dss_bus_unregister(); 565 omap_dss_bus_unregister();
547 return r; 566 return r;
@@ -562,7 +581,7 @@ static void __exit omap_dss_exit(void)
562 core.vdds_sdi_reg = NULL; 581 core.vdds_sdi_reg = NULL;
563 } 582 }
564 583
565 platform_driver_unregister(&omap_dss_driver); 584 omap_dss_unregister_drivers();
566 585
567 omap_dss_bus_unregister(); 586 omap_dss_bus_unregister();
568} 587}
@@ -577,7 +596,7 @@ static int __init omap_dss_init(void)
577 596
578static int __init omap_dss_init2(void) 597static int __init omap_dss_init2(void)
579{ 598{
580 return platform_driver_register(&omap_dss_driver); 599 return omap_dss_register_drivers();
581} 600}
582 601
583core_initcall(omap_dss_init); 602core_initcall(omap_dss_init);
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index e1626a1d5c45..bddd64b435b9 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -37,7 +37,6 @@
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/pm_runtime.h> 38#include <linux/pm_runtime.h>
39 39
40#include <plat/sram.h>
41#include <plat/clock.h> 40#include <plat/clock.h>
42 41
43#include <video/omapdss.h> 42#include <video/omapdss.h>
@@ -736,11 +735,11 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane,
736 switch (color_mode) { 735 switch (color_mode) {
737 case OMAP_DSS_COLOR_NV12: 736 case OMAP_DSS_COLOR_NV12:
738 m = 0x0; break; 737 m = 0x0; break;
739 case OMAP_DSS_COLOR_RGB12U: 738 case OMAP_DSS_COLOR_RGBX16:
740 m = 0x1; break; 739 m = 0x1; break;
741 case OMAP_DSS_COLOR_RGBA16: 740 case OMAP_DSS_COLOR_RGBA16:
742 m = 0x2; break; 741 m = 0x2; break;
743 case OMAP_DSS_COLOR_RGBX16: 742 case OMAP_DSS_COLOR_RGB12U:
744 m = 0x4; break; 743 m = 0x4; break;
745 case OMAP_DSS_COLOR_ARGB16: 744 case OMAP_DSS_COLOR_ARGB16:
746 m = 0x5; break; 745 m = 0x5; break;
@@ -789,9 +788,9 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane,
789 m = 0x8; break; 788 m = 0x8; break;
790 case OMAP_DSS_COLOR_RGB24P: 789 case OMAP_DSS_COLOR_RGB24P:
791 m = 0x9; break; 790 m = 0x9; break;
792 case OMAP_DSS_COLOR_YUV2: 791 case OMAP_DSS_COLOR_RGBX16:
793 m = 0xa; break; 792 m = 0xa; break;
794 case OMAP_DSS_COLOR_UYVY: 793 case OMAP_DSS_COLOR_RGBA16:
795 m = 0xb; break; 794 m = 0xb; break;
796 case OMAP_DSS_COLOR_ARGB32: 795 case OMAP_DSS_COLOR_ARGB32:
797 m = 0xc; break; 796 m = 0xc; break;
@@ -909,7 +908,7 @@ static void dispc_configure_burst_sizes(void)
909 dispc_ovl_set_burst_size(i, burst_size); 908 dispc_ovl_set_burst_size(i, burst_size);
910} 909}
911 910
912u32 dispc_ovl_get_burst_size(enum omap_plane plane) 911static u32 dispc_ovl_get_burst_size(enum omap_plane plane)
913{ 912{
914 unsigned unit = dss_feat_get_burst_size_unit(); 913 unsigned unit = dss_feat_get_burst_size_unit();
915 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ 914 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
@@ -1018,7 +1017,7 @@ static void dispc_read_plane_fifo_sizes(void)
1018 } 1017 }
1019} 1018}
1020 1019
1021u32 dispc_ovl_get_fifo_size(enum omap_plane plane) 1020static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
1022{ 1021{
1023 return dispc.fifo_size[plane]; 1022 return dispc.fifo_size[plane];
1024} 1023}
@@ -1039,13 +1038,13 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
1039 dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); 1038 dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
1040 dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); 1039 dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
1041 1040
1042 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", 1041 DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n",
1043 plane, 1042 plane,
1044 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), 1043 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1045 lo_start, lo_end), 1044 lo_start, lo_end) * unit,
1046 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), 1045 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1047 hi_start, hi_end), 1046 hi_start, hi_end) * unit,
1048 low, high); 1047 low * unit, high * unit);
1049 1048
1050 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), 1049 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
1051 FLD_VAL(high, hi_start, hi_end) | 1050 FLD_VAL(high, hi_start, hi_end) |
@@ -1054,10 +1053,53 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
1054 1053
1055void dispc_enable_fifomerge(bool enable) 1054void dispc_enable_fifomerge(bool enable)
1056{ 1055{
1056 if (!dss_has_feature(FEAT_FIFO_MERGE)) {
1057 WARN_ON(enable);
1058 return;
1059 }
1060
1057 DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); 1061 DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled");
1058 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); 1062 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
1059} 1063}
1060 1064
1065void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
1066 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge)
1067{
1068 /*
1069 * All sizes are in bytes. Both the buffer and burst are made of
1070 * buffer_units, and the fifo thresholds must be buffer_unit aligned.
1071 */
1072
1073 unsigned buf_unit = dss_feat_get_buffer_size_unit();
1074 unsigned ovl_fifo_size, total_fifo_size, burst_size;
1075 int i;
1076
1077 burst_size = dispc_ovl_get_burst_size(plane);
1078 ovl_fifo_size = dispc_ovl_get_fifo_size(plane);
1079
1080 if (use_fifomerge) {
1081 total_fifo_size = 0;
1082 for (i = 0; i < omap_dss_get_num_overlays(); ++i)
1083 total_fifo_size += dispc_ovl_get_fifo_size(i);
1084 } else {
1085 total_fifo_size = ovl_fifo_size;
1086 }
1087
1088 /*
1089 * We use the same low threshold for both fifomerge and non-fifomerge
1090 * cases, but for fifomerge we calculate the high threshold using the
1091 * combined fifo size
1092 */
1093
1094 if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) {
1095 *fifo_low = ovl_fifo_size - burst_size * 2;
1096 *fifo_high = total_fifo_size - burst_size;
1097 } else {
1098 *fifo_low = ovl_fifo_size - burst_size;
1099 *fifo_high = total_fifo_size - buf_unit;
1100 }
1101}
1102
1061static void dispc_ovl_set_fir(enum omap_plane plane, 1103static void dispc_ovl_set_fir(enum omap_plane plane,
1062 int hinc, int vinc, 1104 int hinc, int vinc,
1063 enum omap_color_component color_comp) 1105 enum omap_color_component color_comp)
@@ -1651,6 +1693,7 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1651 u16 height, u16 out_width, u16 out_height) 1693 u16 height, u16 out_width, u16 out_height)
1652{ 1694{
1653 unsigned int hf, vf; 1695 unsigned int hf, vf;
1696 unsigned long pclk = dispc_mgr_pclk_rate(channel);
1654 1697
1655 /* 1698 /*
1656 * FIXME how to determine the 'A' factor 1699 * FIXME how to determine the 'A' factor
@@ -1673,13 +1716,16 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1673 1716
1674 if (cpu_is_omap24xx()) { 1717 if (cpu_is_omap24xx()) {
1675 if (vf > 1 && hf > 1) 1718 if (vf > 1 && hf > 1)
1676 return dispc_mgr_pclk_rate(channel) * 4; 1719 return pclk * 4;
1677 else 1720 else
1678 return dispc_mgr_pclk_rate(channel) * 2; 1721 return pclk * 2;
1679 } else if (cpu_is_omap34xx()) { 1722 } else if (cpu_is_omap34xx()) {
1680 return dispc_mgr_pclk_rate(channel) * vf * hf; 1723 return pclk * vf * hf;
1681 } else { 1724 } else {
1682 return dispc_mgr_pclk_rate(channel) * hf; 1725 if (hf > 1)
1726 return DIV_ROUND_UP(pclk, out_width) * width;
1727 else
1728 return pclk;
1683 } 1729 }
1684} 1730}
1685 1731
@@ -3298,15 +3344,6 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3298 3344
3299 dispc.pdev = pdev; 3345 dispc.pdev = pdev;
3300 3346
3301 clk = clk_get(&pdev->dev, "fck");
3302 if (IS_ERR(clk)) {
3303 DSSERR("can't get fck\n");
3304 r = PTR_ERR(clk);
3305 goto err_get_clk;
3306 }
3307
3308 dispc.dss_clk = clk;
3309
3310 spin_lock_init(&dispc.irq_lock); 3347 spin_lock_init(&dispc.irq_lock);
3311 3348
3312#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 3349#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -3319,29 +3356,38 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3319 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0); 3356 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3320 if (!dispc_mem) { 3357 if (!dispc_mem) {
3321 DSSERR("can't get IORESOURCE_MEM DISPC\n"); 3358 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3322 r = -EINVAL; 3359 return -EINVAL;
3323 goto err_ioremap;
3324 } 3360 }
3325 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem)); 3361
3362 dispc.base = devm_ioremap(&pdev->dev, dispc_mem->start,
3363 resource_size(dispc_mem));
3326 if (!dispc.base) { 3364 if (!dispc.base) {
3327 DSSERR("can't ioremap DISPC\n"); 3365 DSSERR("can't ioremap DISPC\n");
3328 r = -ENOMEM; 3366 return -ENOMEM;
3329 goto err_ioremap;
3330 } 3367 }
3368
3331 dispc.irq = platform_get_irq(dispc.pdev, 0); 3369 dispc.irq = platform_get_irq(dispc.pdev, 0);
3332 if (dispc.irq < 0) { 3370 if (dispc.irq < 0) {
3333 DSSERR("platform_get_irq failed\n"); 3371 DSSERR("platform_get_irq failed\n");
3334 r = -ENODEV; 3372 return -ENODEV;
3335 goto err_irq;
3336 } 3373 }
3337 3374
3338 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED, 3375 r = devm_request_irq(&pdev->dev, dispc.irq, omap_dispc_irq_handler,
3339 "OMAP DISPC", dispc.pdev); 3376 IRQF_SHARED, "OMAP DISPC", dispc.pdev);
3340 if (r < 0) { 3377 if (r < 0) {
3341 DSSERR("request_irq failed\n"); 3378 DSSERR("request_irq failed\n");
3342 goto err_irq; 3379 return r;
3380 }
3381
3382 clk = clk_get(&pdev->dev, "fck");
3383 if (IS_ERR(clk)) {
3384 DSSERR("can't get fck\n");
3385 r = PTR_ERR(clk);
3386 return r;
3343 } 3387 }
3344 3388
3389 dispc.dss_clk = clk;
3390
3345 pm_runtime_enable(&pdev->dev); 3391 pm_runtime_enable(&pdev->dev);
3346 3392
3347 r = dispc_runtime_get(); 3393 r = dispc_runtime_get();
@@ -3362,12 +3408,7 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3362 3408
3363err_runtime_get: 3409err_runtime_get:
3364 pm_runtime_disable(&pdev->dev); 3410 pm_runtime_disable(&pdev->dev);
3365 free_irq(dispc.irq, dispc.pdev);
3366err_irq:
3367 iounmap(dispc.base);
3368err_ioremap:
3369 clk_put(dispc.dss_clk); 3411 clk_put(dispc.dss_clk);
3370err_get_clk:
3371 return r; 3412 return r;
3372} 3413}
3373 3414
@@ -3377,8 +3418,6 @@ static int omap_dispchw_remove(struct platform_device *pdev)
3377 3418
3378 clk_put(dispc.dss_clk); 3419 clk_put(dispc.dss_clk);
3379 3420
3380 free_irq(dispc.irq, dispc.pdev);
3381 iounmap(dispc.base);
3382 return 0; 3421 return 0;
3383} 3422}
3384 3423
diff --git a/drivers/video/omap2/dss/dispc_coefs.c b/drivers/video/omap2/dss/dispc_coefs.c
index 069bccbb3f12..038c15b04215 100644
--- a/drivers/video/omap2/dss/dispc_coefs.c
+++ b/drivers/video/omap2/dss/dispc_coefs.c
@@ -19,14 +19,13 @@
19 19
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <video/omapdss.h> 21#include <video/omapdss.h>
22#include "dispc.h"
23 22
24#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0])) 23#include "dispc.h"
25 24
26static const struct dispc_coef coef3_M8[8] = { 25static const struct dispc_coef coef3_M8[8] = {
27 { 0, 0, 128, 0, 0 }, 26 { 0, 0, 128, 0, 0 },
28 { 0, -4, 123, 9, 0 }, 27 { 0, -4, 123, 9, 0 },
29 { 0, -4, 108, 87, 0 }, 28 { 0, -4, 108, 24, 0 },
30 { 0, -2, 87, 43, 0 }, 29 { 0, -2, 87, 43, 0 },
31 { 0, 64, 64, 0, 0 }, 30 { 0, 64, 64, 0, 0 },
32 { 0, 43, 87, -2, 0 }, 31 { 0, 43, 87, -2, 0 },
@@ -168,7 +167,7 @@ static const struct dispc_coef coef5_M8[8] = {
168 167
169static const struct dispc_coef coef5_M9[8] = { 168static const struct dispc_coef coef5_M9[8] = {
170 { -3, 10, 114, 10, -3 }, 169 { -3, 10, 114, 10, -3 },
171 { -6, 24, 110, 0, -1 }, 170 { -6, 24, 111, 0, -1 },
172 { -8, 40, 103, -7, 0 }, 171 { -8, 40, 103, -7, 0 },
173 { -11, 58, 91, -11, 1 }, 172 { -11, 58, 91, -11, 1 },
174 { 0, -12, 76, 76, -12 }, 173 { 0, -12, 76, 76, -12 },
@@ -319,7 +318,7 @@ const struct dispc_coef *dispc_ovl_get_scale_coef(int inc, int five_taps)
319 }; 318 };
320 319
321 inc /= 128; 320 inc /= 128;
322 for (i = 0; i < ARRAY_LEN(coefs); ++i) 321 for (i = 0; i < ARRAY_SIZE(coefs); ++i)
323 if (inc >= coefs[i].Mmin && inc <= coefs[i].Mmax) 322 if (inc >= coefs[i].Mmin && inc <= coefs[i].Mmax)
324 return five_taps ? coefs[i].coef_5 : coefs[i].coef_3; 323 return five_taps ? coefs[i].coef_5 : coefs[i].coef_3;
325 return NULL; 324 return NULL;
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index be331dc5a61b..4424c198dbcd 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -279,16 +279,6 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
279} 279}
280EXPORT_SYMBOL(omapdss_default_get_resolution); 280EXPORT_SYMBOL(omapdss_default_get_resolution);
281 281
282void default_get_overlay_fifo_thresholds(enum omap_plane plane,
283 u32 fifo_size, u32 burst_size,
284 u32 *fifo_low, u32 *fifo_high)
285{
286 unsigned buf_unit = dss_feat_get_buffer_size_unit();
287
288 *fifo_high = fifo_size - buf_unit;
289 *fifo_low = fifo_size - burst_size;
290}
291
292int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) 282int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
293{ 283{
294 switch (dssdev->type) { 284 switch (dssdev->type) {
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 52f36ec1c8bb..662d14f8c2c3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4524,14 +4524,6 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
4524} 4524}
4525EXPORT_SYMBOL(omapdss_dsi_enable_te); 4525EXPORT_SYMBOL(omapdss_dsi_enable_te);
4526 4526
4527void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
4528 u32 fifo_size, u32 burst_size,
4529 u32 *fifo_low, u32 *fifo_high)
4530{
4531 *fifo_high = fifo_size - burst_size;
4532 *fifo_low = fifo_size - burst_size * 2;
4533}
4534
4535int dsi_init_display(struct omap_dss_device *dssdev) 4527int dsi_init_display(struct omap_dss_device *dssdev)
4536{ 4528{
4537 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4529 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4695,11 +4687,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4695 struct resource *dsi_mem; 4687 struct resource *dsi_mem;
4696 struct dsi_data *dsi; 4688 struct dsi_data *dsi;
4697 4689
4698 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); 4690 dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
4699 if (!dsi) { 4691 if (!dsi)
4700 r = -ENOMEM; 4692 return -ENOMEM;
4701 goto err_alloc;
4702 }
4703 4693
4704 dsi->pdev = dsidev; 4694 dsi->pdev = dsidev;
4705 dsi_pdev_map[dsi_module] = dsidev; 4695 dsi_pdev_map[dsi_module] = dsidev;
@@ -4722,12 +4712,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4722 mutex_init(&dsi->lock); 4712 mutex_init(&dsi->lock);
4723 sema_init(&dsi->bus_lock, 1); 4713 sema_init(&dsi->bus_lock, 1);
4724 4714
4725 r = dsi_get_clocks(dsidev);
4726 if (r)
4727 goto err_get_clk;
4728
4729 pm_runtime_enable(&dsidev->dev);
4730
4731 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work, 4715 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work,
4732 dsi_framedone_timeout_work_callback); 4716 dsi_framedone_timeout_work_callback);
4733 4717
@@ -4739,27 +4723,27 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4739 dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0); 4723 dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0);
4740 if (!dsi_mem) { 4724 if (!dsi_mem) {
4741 DSSERR("can't get IORESOURCE_MEM DSI\n"); 4725 DSSERR("can't get IORESOURCE_MEM DSI\n");
4742 r = -EINVAL; 4726 return -EINVAL;
4743 goto err_ioremap;
4744 } 4727 }
4745 dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem)); 4728
4729 dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start,
4730 resource_size(dsi_mem));
4746 if (!dsi->base) { 4731 if (!dsi->base) {
4747 DSSERR("can't ioremap DSI\n"); 4732 DSSERR("can't ioremap DSI\n");
4748 r = -ENOMEM; 4733 return -ENOMEM;
4749 goto err_ioremap;
4750 } 4734 }
4735
4751 dsi->irq = platform_get_irq(dsi->pdev, 0); 4736 dsi->irq = platform_get_irq(dsi->pdev, 0);
4752 if (dsi->irq < 0) { 4737 if (dsi->irq < 0) {
4753 DSSERR("platform_get_irq failed\n"); 4738 DSSERR("platform_get_irq failed\n");
4754 r = -ENODEV; 4739 return -ENODEV;
4755 goto err_get_irq;
4756 } 4740 }
4757 4741
4758 r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED, 4742 r = devm_request_irq(&dsidev->dev, dsi->irq, omap_dsi_irq_handler,
4759 dev_name(&dsidev->dev), dsi->pdev); 4743 IRQF_SHARED, dev_name(&dsidev->dev), dsi->pdev);
4760 if (r < 0) { 4744 if (r < 0) {
4761 DSSERR("request_irq failed\n"); 4745 DSSERR("request_irq failed\n");
4762 goto err_get_irq; 4746 return r;
4763 } 4747 }
4764 4748
4765 /* DSI VCs initialization */ 4749 /* DSI VCs initialization */
@@ -4771,9 +4755,15 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4771 4755
4772 dsi_calc_clock_param_ranges(dsidev); 4756 dsi_calc_clock_param_ranges(dsidev);
4773 4757
4758 r = dsi_get_clocks(dsidev);
4759 if (r)
4760 return r;
4761
4762 pm_runtime_enable(&dsidev->dev);
4763
4774 r = dsi_runtime_get(dsidev); 4764 r = dsi_runtime_get(dsidev);
4775 if (r) 4765 if (r)
4776 goto err_get_dsi; 4766 goto err_runtime_get;
4777 4767
4778 rev = dsi_read_reg(dsidev, DSI_REVISION); 4768 rev = dsi_read_reg(dsidev, DSI_REVISION);
4779 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", 4769 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
@@ -4791,15 +4781,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4791 4781
4792 return 0; 4782 return 0;
4793 4783
4794err_get_dsi: 4784err_runtime_get:
4795 free_irq(dsi->irq, dsi->pdev);
4796err_get_irq:
4797 iounmap(dsi->base);
4798err_ioremap:
4799 pm_runtime_disable(&dsidev->dev); 4785 pm_runtime_disable(&dsidev->dev);
4800err_get_clk: 4786 dsi_put_clocks(dsidev);
4801 kfree(dsi);
4802err_alloc:
4803 return r; 4787 return r;
4804} 4788}
4805 4789
@@ -4823,11 +4807,6 @@ static int omap_dsihw_remove(struct platform_device *dsidev)
4823 dsi->vdds_dsi_reg = NULL; 4807 dsi->vdds_dsi_reg = NULL;
4824 } 4808 }
4825 4809
4826 free_irq(dsi->irq, dsi->pdev);
4827 iounmap(dsi->base);
4828
4829 kfree(dsi);
4830
4831 return 0; 4810 return 0;
4832} 4811}
4833 4812
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 77c2b5a32b5d..4a6b5eeef6a7 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -748,19 +748,19 @@ static int omap_dsshw_probe(struct platform_device *pdev)
748 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); 748 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
749 if (!dss_mem) { 749 if (!dss_mem) {
750 DSSERR("can't get IORESOURCE_MEM DSS\n"); 750 DSSERR("can't get IORESOURCE_MEM DSS\n");
751 r = -EINVAL; 751 return -EINVAL;
752 goto err_ioremap;
753 } 752 }
754 dss.base = ioremap(dss_mem->start, resource_size(dss_mem)); 753
754 dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
755 resource_size(dss_mem));
755 if (!dss.base) { 756 if (!dss.base) {
756 DSSERR("can't ioremap DSS\n"); 757 DSSERR("can't ioremap DSS\n");
757 r = -ENOMEM; 758 return -ENOMEM;
758 goto err_ioremap;
759 } 759 }
760 760
761 r = dss_get_clocks(); 761 r = dss_get_clocks();
762 if (r) 762 if (r)
763 goto err_clocks; 763 return r;
764 764
765 pm_runtime_enable(&pdev->dev); 765 pm_runtime_enable(&pdev->dev);
766 766
@@ -808,9 +808,6 @@ err_dpi:
808err_runtime_get: 808err_runtime_get:
809 pm_runtime_disable(&pdev->dev); 809 pm_runtime_disable(&pdev->dev);
810 dss_put_clocks(); 810 dss_put_clocks();
811err_clocks:
812 iounmap(dss.base);
813err_ioremap:
814 return r; 811 return r;
815} 812}
816 813
@@ -819,8 +816,6 @@ static int omap_dsshw_remove(struct platform_device *pdev)
819 dpi_exit(); 816 dpi_exit();
820 sdi_exit(); 817 sdi_exit();
821 818
822 iounmap(dss.base);
823
824 pm_runtime_disable(&pdev->dev); 819 pm_runtime_disable(&pdev->dev);
825 820
826 dss_put_clocks(); 821 dss_put_clocks();
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 32ff69fb3333..d4b3dff2ead3 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -202,9 +202,6 @@ void dss_uninit_device(struct platform_device *pdev,
202 struct omap_dss_device *dssdev); 202 struct omap_dss_device *dssdev);
203bool dss_use_replication(struct omap_dss_device *dssdev, 203bool dss_use_replication(struct omap_dss_device *dssdev,
204 enum omap_color_mode mode); 204 enum omap_color_mode mode);
205void default_get_overlay_fifo_thresholds(enum omap_plane plane,
206 u32 fifo_size, u32 burst_size,
207 u32 *fifo_low, u32 *fifo_high);
208 205
209/* manager */ 206/* manager */
210int dss_init_overlay_managers(struct platform_device *pdev); 207int dss_init_overlay_managers(struct platform_device *pdev);
@@ -313,9 +310,6 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
313int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, 310int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
314 bool enable_hsdiv); 311 bool enable_hsdiv);
315void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); 312void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
316void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
317 u32 fifo_size, u32 burst_size,
318 u32 *fifo_low, u32 *fifo_high);
319void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); 313void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
320void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); 314void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
321struct platform_device *dsi_get_dsidev_from_id(int module); 315struct platform_device *dsi_get_dsidev_from_id(int module);
@@ -429,8 +423,8 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
429 423
430 424
431void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); 425void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
432u32 dispc_ovl_get_fifo_size(enum omap_plane plane); 426void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
433u32 dispc_ovl_get_burst_size(enum omap_plane plane); 427 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge);
434int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 428int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
435 bool ilace, bool replication); 429 bool ilace, bool replication);
436int dispc_ovl_enable(enum omap_plane plane, bool enable); 430int dispc_ovl_enable(enum omap_plane plane, bool enable);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index afcb59301c37..ce14aa6dd672 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -41,7 +41,8 @@ struct omap_dss_features {
41 const struct dss_reg_field *reg_fields; 41 const struct dss_reg_field *reg_fields;
42 const int num_reg_fields; 42 const int num_reg_fields;
43 43
44 const u32 has_feature; 44 const enum dss_feat_id *features;
45 const int num_features;
45 46
46 const int num_mgrs; 47 const int num_mgrs;
47 const int num_ovls; 48 const int num_ovls;
@@ -189,7 +190,8 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
189 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U | 190 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
190 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 | 191 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
191 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32 | 192 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32 |
192 OMAP_DSS_COLOR_ARGB16_1555, 193 OMAP_DSS_COLOR_ARGB16_1555 | OMAP_DSS_COLOR_RGBX16 |
194 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_XRGB16_1555,
193 195
194 /* OMAP_DSS_VIDEO1 */ 196 /* OMAP_DSS_VIDEO1 */
195 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U | 197 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
@@ -337,15 +339,110 @@ static const struct dss_param_range omap4_dss_param_range[] = {
337 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 339 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
338}; 340};
339 341
342static const enum dss_feat_id omap2_dss_feat_list[] = {
343 FEAT_LCDENABLEPOL,
344 FEAT_LCDENABLESIGNAL,
345 FEAT_PCKFREEENABLE,
346 FEAT_FUNCGATED,
347 FEAT_ROWREPEATENABLE,
348 FEAT_RESIZECONF,
349};
350
351static const enum dss_feat_id omap3430_dss_feat_list[] = {
352 FEAT_LCDENABLEPOL,
353 FEAT_LCDENABLESIGNAL,
354 FEAT_PCKFREEENABLE,
355 FEAT_FUNCGATED,
356 FEAT_LINEBUFFERSPLIT,
357 FEAT_ROWREPEATENABLE,
358 FEAT_RESIZECONF,
359 FEAT_DSI_PLL_FREQSEL,
360 FEAT_DSI_REVERSE_TXCLKESC,
361 FEAT_VENC_REQUIRES_TV_DAC_CLK,
362 FEAT_CPR,
363 FEAT_PRELOAD,
364 FEAT_FIR_COEF_V,
365 FEAT_ALPHA_FIXED_ZORDER,
366 FEAT_FIFO_MERGE,
367 FEAT_OMAP3_DSI_FIFO_BUG,
368};
369
370static const enum dss_feat_id omap3630_dss_feat_list[] = {
371 FEAT_LCDENABLEPOL,
372 FEAT_LCDENABLESIGNAL,
373 FEAT_PCKFREEENABLE,
374 FEAT_FUNCGATED,
375 FEAT_LINEBUFFERSPLIT,
376 FEAT_ROWREPEATENABLE,
377 FEAT_RESIZECONF,
378 FEAT_DSI_PLL_PWR_BUG,
379 FEAT_DSI_PLL_FREQSEL,
380 FEAT_CPR,
381 FEAT_PRELOAD,
382 FEAT_FIR_COEF_V,
383 FEAT_ALPHA_FIXED_ZORDER,
384 FEAT_FIFO_MERGE,
385 FEAT_OMAP3_DSI_FIFO_BUG,
386};
387
388static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = {
389 FEAT_MGR_LCD2,
390 FEAT_CORE_CLK_DIV,
391 FEAT_LCD_CLK_SRC,
392 FEAT_DSI_DCS_CMD_CONFIG_VC,
393 FEAT_DSI_VC_OCP_WIDTH,
394 FEAT_DSI_GNQ,
395 FEAT_HANDLE_UV_SEPARATE,
396 FEAT_ATTR2,
397 FEAT_CPR,
398 FEAT_PRELOAD,
399 FEAT_FIR_COEF_V,
400 FEAT_ALPHA_FREE_ZORDER,
401 FEAT_FIFO_MERGE,
402};
403
404static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = {
405 FEAT_MGR_LCD2,
406 FEAT_CORE_CLK_DIV,
407 FEAT_LCD_CLK_SRC,
408 FEAT_DSI_DCS_CMD_CONFIG_VC,
409 FEAT_DSI_VC_OCP_WIDTH,
410 FEAT_DSI_GNQ,
411 FEAT_HDMI_CTS_SWMODE,
412 FEAT_HANDLE_UV_SEPARATE,
413 FEAT_ATTR2,
414 FEAT_CPR,
415 FEAT_PRELOAD,
416 FEAT_FIR_COEF_V,
417 FEAT_ALPHA_FREE_ZORDER,
418 FEAT_FIFO_MERGE,
419};
420
421static const enum dss_feat_id omap4_dss_feat_list[] = {
422 FEAT_MGR_LCD2,
423 FEAT_CORE_CLK_DIV,
424 FEAT_LCD_CLK_SRC,
425 FEAT_DSI_DCS_CMD_CONFIG_VC,
426 FEAT_DSI_VC_OCP_WIDTH,
427 FEAT_DSI_GNQ,
428 FEAT_HDMI_CTS_SWMODE,
429 FEAT_HDMI_AUDIO_USE_MCLK,
430 FEAT_HANDLE_UV_SEPARATE,
431 FEAT_ATTR2,
432 FEAT_CPR,
433 FEAT_PRELOAD,
434 FEAT_FIR_COEF_V,
435 FEAT_ALPHA_FREE_ZORDER,
436 FEAT_FIFO_MERGE,
437};
438
340/* OMAP2 DSS Features */ 439/* OMAP2 DSS Features */
341static const struct omap_dss_features omap2_dss_features = { 440static const struct omap_dss_features omap2_dss_features = {
342 .reg_fields = omap2_dss_reg_fields, 441 .reg_fields = omap2_dss_reg_fields,
343 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields), 442 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
344 443
345 .has_feature = 444 .features = omap2_dss_feat_list,
346 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | 445 .num_features = ARRAY_SIZE(omap2_dss_feat_list),
347 FEAT_PCKFREEENABLE | FEAT_FUNCGATED |
348 FEAT_ROWREPEATENABLE | FEAT_RESIZECONF,
349 446
350 .num_mgrs = 2, 447 .num_mgrs = 2,
351 .num_ovls = 3, 448 .num_ovls = 3,
@@ -363,14 +460,8 @@ static const struct omap_dss_features omap3430_dss_features = {
363 .reg_fields = omap3_dss_reg_fields, 460 .reg_fields = omap3_dss_reg_fields,
364 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 461 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
365 462
366 .has_feature = 463 .features = omap3430_dss_feat_list,
367 FEAT_LCDENABLEPOL | 464 .num_features = ARRAY_SIZE(omap3430_dss_feat_list),
368 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
369 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
370 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
371 FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC |
372 FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD |
373 FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
374 465
375 .num_mgrs = 2, 466 .num_mgrs = 2,
376 .num_ovls = 3, 467 .num_ovls = 3,
@@ -387,14 +478,8 @@ static const struct omap_dss_features omap3630_dss_features = {
387 .reg_fields = omap3_dss_reg_fields, 478 .reg_fields = omap3_dss_reg_fields,
388 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 479 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
389 480
390 .has_feature = 481 .features = omap3630_dss_feat_list,
391 FEAT_LCDENABLEPOL | 482 .num_features = ARRAY_SIZE(omap3630_dss_feat_list),
392 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
393 FEAT_FUNCGATED |
394 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
395 FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
396 FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD |
397 FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
398 483
399 .num_mgrs = 2, 484 .num_mgrs = 2,
400 .num_ovls = 3, 485 .num_ovls = 3,
@@ -413,13 +498,27 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
413 .reg_fields = omap4_dss_reg_fields, 498 .reg_fields = omap4_dss_reg_fields,
414 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 499 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
415 500
416 .has_feature = 501 .features = omap4430_es1_0_dss_feat_list,
417 FEAT_MGR_LCD2 | 502 .num_features = ARRAY_SIZE(omap4430_es1_0_dss_feat_list),
418 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 503
419 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | 504 .num_mgrs = 3,
420 FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | 505 .num_ovls = 4,
421 FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V | 506 .supported_displays = omap4_dss_supported_displays,
422 FEAT_ALPHA_FREE_ZORDER, 507 .supported_color_modes = omap4_dss_supported_color_modes,
508 .overlay_caps = omap4_dss_overlay_caps,
509 .clksrc_names = omap4_dss_clk_source_names,
510 .dss_params = omap4_dss_param_range,
511 .buffer_size_unit = 16,
512 .burst_size_unit = 16,
513};
514
515/* For OMAP4430 ES 2.0, 2.1 and 2.2 revisions */
516static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
517 .reg_fields = omap4_dss_reg_fields,
518 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
519
520 .features = omap4430_es2_0_1_2_dss_feat_list,
521 .num_features = ARRAY_SIZE(omap4430_es2_0_1_2_dss_feat_list),
423 522
424 .num_mgrs = 3, 523 .num_mgrs = 3,
425 .num_ovls = 4, 524 .num_ovls = 4,
@@ -437,13 +536,8 @@ static const struct omap_dss_features omap4_dss_features = {
437 .reg_fields = omap4_dss_reg_fields, 536 .reg_fields = omap4_dss_reg_fields,
438 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 537 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
439 538
440 .has_feature = 539 .features = omap4_dss_feat_list,
441 FEAT_MGR_LCD2 | 540 .num_features = ARRAY_SIZE(omap4_dss_feat_list),
442 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
443 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
444 FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
445 FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR |
446 FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER,
447 541
448 .num_mgrs = 3, 542 .num_mgrs = 3,
449 .num_ovls = 4, 543 .num_ovls = 4,
@@ -547,7 +641,16 @@ u32 dss_feat_get_burst_size_unit(void)
547/* DSS has_feature check */ 641/* DSS has_feature check */
548bool dss_has_feature(enum dss_feat_id id) 642bool dss_has_feature(enum dss_feat_id id)
549{ 643{
550 return omap_current_dss_features->has_feature & id; 644 int i;
645 const enum dss_feat_id *features = omap_current_dss_features->features;
646 const int num_features = omap_current_dss_features->num_features;
647
648 for (i = 0; i < num_features; i++) {
649 if (features[i] == id)
650 return true;
651 }
652
653 return false;
551} 654}
552 655
553void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end) 656void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end)
@@ -569,6 +672,10 @@ void dss_features_init(void)
569 omap_current_dss_features = &omap3430_dss_features; 672 omap_current_dss_features = &omap3430_dss_features;
570 else if (omap_rev() == OMAP4430_REV_ES1_0) 673 else if (omap_rev() == OMAP4430_REV_ES1_0)
571 omap_current_dss_features = &omap4430_es1_0_dss_features; 674 omap_current_dss_features = &omap4430_es1_0_dss_features;
675 else if (omap_rev() == OMAP4430_REV_ES2_0 ||
676 omap_rev() == OMAP4430_REV_ES2_1 ||
677 omap_rev() == OMAP4430_REV_ES2_2)
678 omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
572 else if (cpu_is_omap44xx()) 679 else if (cpu_is_omap44xx())
573 omap_current_dss_features = &omap4_dss_features; 680 omap_current_dss_features = &omap4_dss_features;
574 else 681 else
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index cd833bbaac3d..c332e7ddfce1 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -31,33 +31,37 @@
31 31
32/* DSS has feature id */ 32/* DSS has feature id */
33enum dss_feat_id { 33enum dss_feat_id {
34 FEAT_LCDENABLEPOL = 1 << 3, 34 FEAT_LCDENABLEPOL,
35 FEAT_LCDENABLESIGNAL = 1 << 4, 35 FEAT_LCDENABLESIGNAL,
36 FEAT_PCKFREEENABLE = 1 << 5, 36 FEAT_PCKFREEENABLE,
37 FEAT_FUNCGATED = 1 << 6, 37 FEAT_FUNCGATED,
38 FEAT_MGR_LCD2 = 1 << 7, 38 FEAT_MGR_LCD2,
39 FEAT_LINEBUFFERSPLIT = 1 << 8, 39 FEAT_LINEBUFFERSPLIT,
40 FEAT_ROWREPEATENABLE = 1 << 9, 40 FEAT_ROWREPEATENABLE,
41 FEAT_RESIZECONF = 1 << 10, 41 FEAT_RESIZECONF,
42 /* Independent core clk divider */ 42 /* Independent core clk divider */
43 FEAT_CORE_CLK_DIV = 1 << 11, 43 FEAT_CORE_CLK_DIV,
44 FEAT_LCD_CLK_SRC = 1 << 12, 44 FEAT_LCD_CLK_SRC,
45 /* DSI-PLL power command 0x3 is not working */ 45 /* DSI-PLL power command 0x3 is not working */
46 FEAT_DSI_PLL_PWR_BUG = 1 << 13, 46 FEAT_DSI_PLL_PWR_BUG,
47 FEAT_DSI_PLL_FREQSEL = 1 << 14, 47 FEAT_DSI_PLL_FREQSEL,
48 FEAT_DSI_DCS_CMD_CONFIG_VC = 1 << 15, 48 FEAT_DSI_DCS_CMD_CONFIG_VC,
49 FEAT_DSI_VC_OCP_WIDTH = 1 << 16, 49 FEAT_DSI_VC_OCP_WIDTH,
50 FEAT_DSI_REVERSE_TXCLKESC = 1 << 17, 50 FEAT_DSI_REVERSE_TXCLKESC,
51 FEAT_DSI_GNQ = 1 << 18, 51 FEAT_DSI_GNQ,
52 FEAT_HDMI_CTS_SWMODE = 1 << 19, 52 FEAT_HDMI_CTS_SWMODE,
53 FEAT_HANDLE_UV_SEPARATE = 1 << 20, 53 FEAT_HDMI_AUDIO_USE_MCLK,
54 FEAT_ATTR2 = 1 << 21, 54 FEAT_HANDLE_UV_SEPARATE,
55 FEAT_VENC_REQUIRES_TV_DAC_CLK = 1 << 22, 55 FEAT_ATTR2,
56 FEAT_CPR = 1 << 23, 56 FEAT_VENC_REQUIRES_TV_DAC_CLK,
57 FEAT_PRELOAD = 1 << 24, 57 FEAT_CPR,
58 FEAT_FIR_COEF_V = 1 << 25, 58 FEAT_PRELOAD,
59 FEAT_ALPHA_FIXED_ZORDER = 1 << 26, 59 FEAT_FIR_COEF_V,
60 FEAT_ALPHA_FREE_ZORDER = 1 << 27, 60 FEAT_ALPHA_FIXED_ZORDER,
61 FEAT_ALPHA_FREE_ZORDER,
62 FEAT_FIFO_MERGE,
63 /* An unknown HW bug causing the normal FIFO thresholds not to work */
64 FEAT_OMAP3_DSI_FIFO_BUG,
61}; 65};
62 66
63/* DSS register field id */ 67/* DSS register field id */
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a36b934b2db4..c4b4f6950a92 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -58,8 +58,6 @@
58#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4 58#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
59#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4 59#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
60 60
61#define OMAP_HDMI_TIMINGS_NB 34
62
63#define HDMI_DEFAULT_REGN 16 61#define HDMI_DEFAULT_REGN 16
64#define HDMI_DEFAULT_REGM2 1 62#define HDMI_DEFAULT_REGM2 1
65 63
@@ -68,8 +66,6 @@ static struct {
68 struct omap_display_platform_data *pdata; 66 struct omap_display_platform_data *pdata;
69 struct platform_device *pdev; 67 struct platform_device *pdev;
70 struct hdmi_ip_data ip_data; 68 struct hdmi_ip_data ip_data;
71 int code;
72 int mode;
73 69
74 struct clk *sys_clk; 70 struct clk *sys_clk;
75} hdmi; 71} hdmi;
@@ -88,77 +84,46 @@ static struct {
88 * map it to corresponding CEA or VESA index. 84 * map it to corresponding CEA or VESA index.
89 */ 85 */
90 86
91static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { 87static const struct hdmi_config cea_timings[] = {
92 { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0}, 88{ {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} },
93 { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1}, 89{ {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} },
94 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}, 90{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} },
95 { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0}, 91{ {1920, 540, 74250, 44, 88, 148, 5, 2, 15, 1, 1, 1}, {5, HDMI_HDMI} },
96 { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0}, 92{ {1440, 240, 27027, 124, 38, 114, 3, 4, 15, 0, 0, 1}, {6, HDMI_HDMI} },
97 { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0}, 93{ {1920, 1080, 148500, 44, 88, 148, 5, 4, 36, 1, 1, 0}, {16, HDMI_HDMI} },
98 { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0}, 94{ {720, 576, 27000, 64, 12, 68, 5, 5, 39, 0, 0, 0}, {17, HDMI_HDMI} },
99 { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1}, 95{ {1280, 720, 74250, 40, 440, 220, 5, 5, 20, 1, 1, 0}, {19, HDMI_HDMI} },
100 { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1}, 96{ {1920, 540, 74250, 44, 528, 148, 5, 2, 15, 1, 1, 1}, {20, HDMI_HDMI} },
101 { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1}, 97{ {1440, 288, 27000, 126, 24, 138, 3, 2, 19, 0, 0, 1}, {21, HDMI_HDMI} },
102 { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0}, 98{ {1440, 576, 54000, 128, 24, 136, 5, 5, 39, 0, 0, 0}, {29, HDMI_HDMI} },
103 { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0}, 99{ {1920, 1080, 148500, 44, 528, 148, 5, 4, 36, 1, 1, 0}, {31, HDMI_HDMI} },
104 { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1}, 100{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} },
105 { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0}, 101{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} },
106 { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1}, 102{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} },
107 /* VESA From Here */
108 { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
109 { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
110 { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
111 { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
112 { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
113 { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1},
114 { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
115 { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
116 { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
117 { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
118 { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
119 { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
120 { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
121 { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
122 { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
123 { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
124 { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
125 { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
126 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
127};
128
129/*
130 * This is a static mapping array which maps the timing values
131 * with corresponding CEA / VESA code
132 */
133static const int code_index[OMAP_HDMI_TIMINGS_NB] = {
134 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
135 /* <--15 CEA 17--> vesa*/
136 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
137 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
138}; 103};
139 104static const struct hdmi_config vesa_timings[] = {
140/* 105/* VESA From Here */
141 * This is reverse static mapping which maps the CEA / VESA code 106{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} },
142 * to the corresponding timing values 107{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} },
143 */ 108{ {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} },
144static const int code_cea[39] = { 109{ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} },
145 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1, 110{ {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} },
146 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1, 111{ {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} },
147 7, 6, 6, -1, -1, -1, -1, -1, -1, 11, 112{ {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} },
148 11, 12, 14, -1, -1, 13, 13, 4, 4 113{ {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38, 1, 1, 0}, {0x23, HDMI_DVI} },
114{ {1024, 768, 65000, 136, 24, 160, 6, 3, 29, 0, 0, 0}, {0x10, HDMI_DVI} },
115{ {1400, 1050, 121750, 144, 88, 232, 4, 3, 32, 1, 0, 0}, {0x2A, HDMI_DVI} },
116{ {1440, 900, 106500, 152, 80, 232, 6, 3, 25, 1, 0, 0}, {0x2F, HDMI_DVI} },
117{ {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, 1, 0, 0}, {0x3A, HDMI_DVI} },
118{ {1366, 768, 85500, 143, 70, 213, 3, 3, 24, 1, 1, 0}, {0x51, HDMI_DVI} },
119{ {1920, 1080, 148500, 44, 148, 80, 5, 4, 36, 1, 1, 0}, {0x52, HDMI_DVI} },
120{ {1280, 768, 68250, 32, 48, 80, 7, 3, 12, 0, 1, 0}, {0x16, HDMI_DVI} },
121{ {1400, 1050, 101000, 32, 48, 80, 4, 3, 23, 0, 1, 0}, {0x29, HDMI_DVI} },
122{ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21, 0, 1, 0}, {0x39, HDMI_DVI} },
123{ {1280, 800, 79500, 32, 48, 80, 6, 3, 14, 0, 1, 0}, {0x1B, HDMI_DVI} },
124{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} }
149}; 125};
150 126
151static const int code_vesa[85] = {
152 -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
153 -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
154 -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
155 -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
156 -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
157 -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
158 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
159 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
160 -1, 27, 28, -1, 33};
161
162static int hdmi_runtime_get(void) 127static int hdmi_runtime_get(void)
163{ 128{
164 int r; 129 int r;
@@ -210,88 +175,89 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
210 return 0; 175 return 0;
211} 176}
212 177
213static int get_timings_index(void) 178static const struct hdmi_config *hdmi_find_timing(
179 const struct hdmi_config *timings_arr,
180 int len)
214{ 181{
215 int code; 182 int i;
216 183
217 if (hdmi.mode == 0) 184 for (i = 0; i < len; i++) {
218 code = code_vesa[hdmi.code]; 185 if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code)
219 else 186 return &timings_arr[i];
220 code = code_cea[hdmi.code]; 187 }
188 return NULL;
189}
221 190
222 if (code == -1) { 191static const struct hdmi_config *hdmi_get_timings(void)
223 /* HDMI code 4 corresponds to 640 * 480 VGA */ 192{
224 hdmi.code = 4; 193 const struct hdmi_config *arr;
225 /* DVI mode 1 corresponds to HDMI 0 to DVI */ 194 int len;
226 hdmi.mode = HDMI_DVI; 195
196 if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) {
197 arr = vesa_timings;
198 len = ARRAY_SIZE(vesa_timings);
199 } else {
200 arr = cea_timings;
201 len = ARRAY_SIZE(cea_timings);
202 }
203
204 return hdmi_find_timing(arr, len);
205}
206
207static bool hdmi_timings_compare(struct omap_video_timings *timing1,
208 const struct hdmi_video_timings *timing2)
209{
210 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
227 211
228 code = code_vesa[hdmi.code]; 212 if ((timing2->pixel_clock == timing1->pixel_clock) &&
213 (timing2->x_res == timing1->x_res) &&
214 (timing2->y_res == timing1->y_res)) {
215
216 timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
217 timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
218 timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
219 timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
220
221 DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
222 "timing2_hsync = %d timing2_vsync = %d\n",
223 timing1_hsync, timing1_vsync,
224 timing2_hsync, timing2_vsync);
225
226 if ((timing1_hsync == timing2_hsync) &&
227 (timing1_vsync == timing2_vsync)) {
228 return true;
229 }
229 } 230 }
230 return code; 231 return false;
231} 232}
232 233
233static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) 234static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
234{ 235{
235 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0; 236 int i;
236 int timing_vsync = 0, timing_hsync = 0;
237 struct hdmi_video_timings temp;
238 struct hdmi_cm cm = {-1}; 237 struct hdmi_cm cm = {-1};
239 DSSDBG("hdmi_get_code\n"); 238 DSSDBG("hdmi_get_code\n");
240 239
241 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) { 240 for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
242 temp = cea_vesa_timings[i].timings; 241 if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
243 if ((temp.pixel_clock == timing->pixel_clock) && 242 cm = cea_timings[i].cm;
244 (temp.x_res == timing->x_res) && 243 goto end;
245 (temp.y_res == timing->y_res)) { 244 }
246 245 }
247 temp_hsync = temp.hfp + temp.hsw + temp.hbp; 246 for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
248 timing_hsync = timing->hfp + timing->hsw + timing->hbp; 247 if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
249 temp_vsync = temp.vfp + temp.vsw + temp.vbp; 248 cm = vesa_timings[i].cm;
250 timing_vsync = timing->vfp + timing->vsw + timing->vbp; 249 goto end;
251
252 DSSDBG("temp_hsync = %d , temp_vsync = %d"
253 "timing_hsync = %d, timing_vsync = %d\n",
254 temp_hsync, temp_hsync,
255 timing_hsync, timing_vsync);
256
257 if ((temp_hsync == timing_hsync) &&
258 (temp_vsync == timing_vsync)) {
259 code = i;
260 cm.code = code_index[i];
261 if (code < 14)
262 cm.mode = HDMI_HDMI;
263 else
264 cm.mode = HDMI_DVI;
265 DSSDBG("Hdmi_code = %d mode = %d\n",
266 cm.code, cm.mode);
267 break;
268 }
269 } 250 }
270 } 251 }
271 252
272 return cm; 253end: return cm;
273}
274 254
275static void update_hdmi_timings(struct hdmi_config *cfg,
276 struct omap_video_timings *timings, int code)
277{
278 cfg->timings.timings.x_res = timings->x_res;
279 cfg->timings.timings.y_res = timings->y_res;
280 cfg->timings.timings.hbp = timings->hbp;
281 cfg->timings.timings.hfp = timings->hfp;
282 cfg->timings.timings.hsw = timings->hsw;
283 cfg->timings.timings.vbp = timings->vbp;
284 cfg->timings.timings.vfp = timings->vfp;
285 cfg->timings.timings.vsw = timings->vsw;
286 cfg->timings.timings.pixel_clock = timings->pixel_clock;
287 cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
288 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
289} 255}
290 256
291unsigned long hdmi_get_pixel_clock(void) 257unsigned long hdmi_get_pixel_clock(void)
292{ 258{
293 /* HDMI Pixel Clock in Mhz */ 259 /* HDMI Pixel Clock in Mhz */
294 return hdmi.ip_data.cfg.timings.timings.pixel_clock * 1000; 260 return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
295} 261}
296 262
297static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, 263static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
@@ -312,24 +278,24 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
312 278
313 refclk = clkin / pi->regn; 279 refclk = clkin / pi->regn;
314 280
315 /*
316 * multiplier is pixel_clk/ref_clk
317 * Multiplying by 100 to avoid fractional part removal
318 */
319 pi->regm = (phy * 100 / (refclk)) / 100;
320
321 if (dssdev->clocks.hdmi.regm2 == 0) 281 if (dssdev->clocks.hdmi.regm2 == 0)
322 pi->regm2 = HDMI_DEFAULT_REGM2; 282 pi->regm2 = HDMI_DEFAULT_REGM2;
323 else 283 else
324 pi->regm2 = dssdev->clocks.hdmi.regm2; 284 pi->regm2 = dssdev->clocks.hdmi.regm2;
325 285
326 /* 286 /*
287 * multiplier is pixel_clk/ref_clk
288 * Multiplying by 100 to avoid fractional part removal
289 */
290 pi->regm = phy * pi->regm2 / refclk;
291
292 /*
327 * fractional multiplier is remainder of the difference between 293 * fractional multiplier is remainder of the difference between
328 * multiplier and actual phy(required pixel clock thus should be 294 * multiplier and actual phy(required pixel clock thus should be
329 * multiplied by 2^18(262144) divided by the reference clock 295 * multiplied by 2^18(262144) divided by the reference clock
330 */ 296 */
331 mf = (phy - pi->regm * refclk) * 262144; 297 mf = (phy - pi->regm / pi->regm2 * refclk) * 262144;
332 pi->regmf = mf / (refclk); 298 pi->regmf = pi->regm2 * mf / refclk;
333 299
334 /* 300 /*
335 * Dcofreq should be set to 1 if required pixel clock 301 * Dcofreq should be set to 1 if required pixel clock
@@ -347,7 +313,8 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
347 313
348static int hdmi_power_on(struct omap_dss_device *dssdev) 314static int hdmi_power_on(struct omap_dss_device *dssdev)
349{ 315{
350 int r, code = 0; 316 int r;
317 const struct hdmi_config *timing;
351 struct omap_video_timings *p; 318 struct omap_video_timings *p;
352 unsigned long phy; 319 unsigned long phy;
353 320
@@ -363,9 +330,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
363 dssdev->panel.timings.x_res, 330 dssdev->panel.timings.x_res,
364 dssdev->panel.timings.y_res); 331 dssdev->panel.timings.y_res);
365 332
366 code = get_timings_index(); 333 timing = hdmi_get_timings();
367 update_hdmi_timings(&hdmi.ip_data.cfg, p, code); 334 if (timing == NULL) {
368 335 /* HDMI code 4 corresponds to 640 * 480 VGA */
336 hdmi.ip_data.cfg.cm.code = 4;
337 /* DVI mode 1 corresponds to HDMI 0 to DVI */
338 hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
339 hdmi.ip_data.cfg = vesa_timings[0];
340 } else {
341 hdmi.ip_data.cfg = *timing;
342 }
369 phy = p->pixel_clock; 343 phy = p->pixel_clock;
370 344
371 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); 345 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
@@ -385,8 +359,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
385 goto err; 359 goto err;
386 } 360 }
387 361
388 hdmi.ip_data.cfg.cm.mode = hdmi.mode;
389 hdmi.ip_data.cfg.cm.code = hdmi.code;
390 hdmi.ip_data.ops->video_configure(&hdmi.ip_data); 362 hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
391 363
392 /* Make selection of HDMI in DSS */ 364 /* Make selection of HDMI in DSS */
@@ -453,8 +425,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
453 struct hdmi_cm cm; 425 struct hdmi_cm cm;
454 426
455 cm = hdmi_get_code(&dssdev->panel.timings); 427 cm = hdmi_get_code(&dssdev->panel.timings);
456 hdmi.code = cm.code; 428 hdmi.ip_data.cfg.cm.code = cm.code;
457 hdmi.mode = cm.mode; 429 hdmi.ip_data.cfg.cm.mode = cm.mode;
458 430
459 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 431 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
460 int r; 432 int r;
@@ -717,13 +689,15 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
717 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { 689 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
718 core_cfg.aud_par_busclk = 0; 690 core_cfg.aud_par_busclk = 0;
719 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW; 691 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
720 core_cfg.use_mclk = false; 692 core_cfg.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK);
721 } else { 693 } else {
722 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8); 694 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8);
723 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW; 695 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
724 core_cfg.use_mclk = true; 696 core_cfg.use_mclk = true;
725 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
726 } 697 }
698
699 if (core_cfg.use_mclk)
700 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
727 core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH; 701 core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH;
728 core_cfg.en_spdif = false; 702 core_cfg.en_spdif = false;
729 /* Use sample frequency from channel status word */ 703 /* Use sample frequency from channel status word */
@@ -756,7 +730,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
756static int hdmi_audio_startup(struct snd_pcm_substream *substream, 730static int hdmi_audio_startup(struct snd_pcm_substream *substream,
757 struct snd_soc_dai *dai) 731 struct snd_soc_dai *dai)
758{ 732{
759 if (!hdmi.mode) { 733 if (!hdmi.ip_data.cfg.cm.mode) {
760 pr_err("Current video settings do not support audio.\n"); 734 pr_err("Current video settings do not support audio.\n");
761 return -EIO; 735 return -EIO;
762 } 736 }
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index d1858e71c64e..e7364603f6a1 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -494,6 +494,11 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
494{ 494{
495 unsigned long timeout = msecs_to_jiffies(500); 495 unsigned long timeout = msecs_to_jiffies(500);
496 u32 irq; 496 u32 irq;
497 int r;
498
499 r = dispc_runtime_get();
500 if (r)
501 return r;
497 502
498 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 503 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
499 irq = DISPC_IRQ_EVSYNC_ODD; 504 irq = DISPC_IRQ_EVSYNC_ODD;
@@ -505,7 +510,12 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
505 else 510 else
506 irq = DISPC_IRQ_VSYNC2; 511 irq = DISPC_IRQ_VSYNC2;
507 } 512 }
508 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 513
514 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
515
516 dispc_runtime_put();
517
518 return r;
509} 519}
510 520
511int dss_init_overlay_managers(struct platform_device *pdev) 521int dss_init_overlay_managers(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 55f398014f33..788a0ef6323a 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -922,35 +922,34 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
922 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0); 922 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
923 if (!rfbi_mem) { 923 if (!rfbi_mem) {
924 DSSERR("can't get IORESOURCE_MEM RFBI\n"); 924 DSSERR("can't get IORESOURCE_MEM RFBI\n");
925 r = -EINVAL; 925 return -EINVAL;
926 goto err_ioremap;
927 } 926 }
928 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem)); 927
928 rfbi.base = devm_ioremap(&pdev->dev, rfbi_mem->start,
929 resource_size(rfbi_mem));
929 if (!rfbi.base) { 930 if (!rfbi.base) {
930 DSSERR("can't ioremap RFBI\n"); 931 DSSERR("can't ioremap RFBI\n");
931 r = -ENOMEM; 932 return -ENOMEM;
932 goto err_ioremap;
933 } 933 }
934 934
935 pm_runtime_enable(&pdev->dev);
936
937 r = rfbi_runtime_get();
938 if (r)
939 goto err_get_rfbi;
940
941 msleep(10);
942
943 clk = clk_get(&pdev->dev, "ick"); 935 clk = clk_get(&pdev->dev, "ick");
944 if (IS_ERR(clk)) { 936 if (IS_ERR(clk)) {
945 DSSERR("can't get ick\n"); 937 DSSERR("can't get ick\n");
946 r = PTR_ERR(clk); 938 return PTR_ERR(clk);
947 goto err_get_ick;
948 } 939 }
949 940
950 rfbi.l4_khz = clk_get_rate(clk) / 1000; 941 rfbi.l4_khz = clk_get_rate(clk) / 1000;
951 942
952 clk_put(clk); 943 clk_put(clk);
953 944
945 pm_runtime_enable(&pdev->dev);
946
947 r = rfbi_runtime_get();
948 if (r)
949 goto err_runtime_get;
950
951 msleep(10);
952
954 rev = rfbi_read_reg(RFBI_REVISION); 953 rev = rfbi_read_reg(RFBI_REVISION);
955 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n", 954 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
956 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 955 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -959,19 +958,14 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
959 958
960 return 0; 959 return 0;
961 960
962err_get_ick: 961err_runtime_get:
963 rfbi_runtime_put();
964err_get_rfbi:
965 pm_runtime_disable(&pdev->dev); 962 pm_runtime_disable(&pdev->dev);
966 iounmap(rfbi.base);
967err_ioremap:
968 return r; 963 return r;
969} 964}
970 965
971static int omap_rfbihw_remove(struct platform_device *pdev) 966static int omap_rfbihw_remove(struct platform_device *pdev)
972{ 967{
973 pm_runtime_disable(&pdev->dev); 968 pm_runtime_disable(&pdev->dev);
974 iounmap(rfbi.base);
975 return 0; 969 return 0;
976} 970}
977 971
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index 50dadba5070a..1f58b84d6901 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -42,6 +42,7 @@ enum hdmi_clk_refsel {
42 HDMI_REFSEL_SYSCLK = 3 42 HDMI_REFSEL_SYSCLK = 3
43}; 43};
44 44
45/* HDMI timing structure */
45struct hdmi_video_timings { 46struct hdmi_video_timings {
46 u16 x_res; 47 u16 x_res;
47 u16 y_res; 48 u16 y_res;
@@ -53,13 +54,9 @@ struct hdmi_video_timings {
53 u16 vsw; 54 u16 vsw;
54 u16 vfp; 55 u16 vfp;
55 u16 vbp; 56 u16 vbp;
56}; 57 bool vsync_pol;
57 58 bool hsync_pol;
58/* HDMI timing structure */ 59 bool interlace;
59struct hdmi_timings {
60 struct hdmi_video_timings timings;
61 int vsync_pol;
62 int hsync_pol;
63}; 60};
64 61
65struct hdmi_cm { 62struct hdmi_cm {
@@ -68,8 +65,7 @@ struct hdmi_cm {
68}; 65};
69 66
70struct hdmi_config { 67struct hdmi_config {
71 struct hdmi_timings timings; 68 struct hdmi_video_timings timings;
72 u16 interlace;
73 struct hdmi_cm cm; 69 struct hdmi_cm cm;
74}; 70};
75 71
@@ -117,6 +113,47 @@ struct ti_hdmi_ip_ops {
117 113
118}; 114};
119 115
116/*
117 * Refer to section 8.2 in HDMI 1.3 specification for
118 * details about infoframe databytes
119 */
120struct hdmi_core_infoframe_avi {
121 /* Y0, Y1 rgb,yCbCr */
122 u8 db1_format;
123 /* A0 Active information Present */
124 u8 db1_active_info;
125 /* B0, B1 Bar info data valid */
126 u8 db1_bar_info_dv;
127 /* S0, S1 scan information */
128 u8 db1_scan_info;
129 /* C0, C1 colorimetry */
130 u8 db2_colorimetry;
131 /* M0, M1 Aspect ratio (4:3, 16:9) */
132 u8 db2_aspect_ratio;
133 /* R0...R3 Active format aspect ratio */
134 u8 db2_active_fmt_ar;
135 /* ITC IT content. */
136 u8 db3_itc;
137 /* EC0, EC1, EC2 Extended colorimetry */
138 u8 db3_ec;
139 /* Q1, Q0 Quantization range */
140 u8 db3_q_range;
141 /* SC1, SC0 Non-uniform picture scaling */
142 u8 db3_nup_scaling;
143 /* VIC0..6 Video format identification */
144 u8 db4_videocode;
145 /* PR0..PR3 Pixel repetition factor */
146 u8 db5_pixel_repeat;
147 /* Line number end of top bar */
148 u16 db6_7_line_eoftop;
149 /* Line number start of bottom bar */
150 u16 db8_9_line_sofbottom;
151 /* Pixel number end of left bar */
152 u16 db10_11_pixel_eofleft;
153 /* Pixel number start of right bar */
154 u16 db12_13_pixel_sofright;
155};
156
120struct hdmi_ip_data { 157struct hdmi_ip_data {
121 void __iomem *base_wp; /* HDMI wrapper */ 158 void __iomem *base_wp; /* HDMI wrapper */
122 unsigned long core_sys_offset; 159 unsigned long core_sys_offset;
@@ -126,6 +163,7 @@ struct hdmi_ip_data {
126 const struct ti_hdmi_ip_ops *ops; 163 const struct ti_hdmi_ip_ops *ops;
127 struct hdmi_config cfg; 164 struct hdmi_config cfg;
128 struct hdmi_pll_info pll_data; 165 struct hdmi_pll_info pll_data;
166 struct hdmi_core_infoframe_avi avi_cfg;
129 167
130 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ 168 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
131 int hpd_gpio; 169 int hpd_gpio;
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index 6847a478b459..bfe6fe65c8be 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -587,12 +587,12 @@ static void hdmi_core_video_config(struct hdmi_ip_data *ip_data,
587 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); 587 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
588} 588}
589 589
590static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data, 590static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data)
591 struct hdmi_core_infoframe_avi info_avi)
592{ 591{
593 u32 val; 592 u32 val;
594 char sum = 0, checksum = 0; 593 char sum = 0, checksum = 0;
595 void __iomem *av_base = hdmi_av_base(ip_data); 594 void __iomem *av_base = hdmi_av_base(ip_data);
595 struct hdmi_core_infoframe_avi info_avi = ip_data->avi_cfg;
596 596
597 sum += 0x82 + 0x002 + 0x00D; 597 sum += 0x82 + 0x002 + 0x00D;
598 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082); 598 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082);
@@ -682,8 +682,7 @@ static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data,
682} 682}
683 683
684static void hdmi_wp_init(struct omap_video_timings *timings, 684static void hdmi_wp_init(struct omap_video_timings *timings,
685 struct hdmi_video_format *video_fmt, 685 struct hdmi_video_format *video_fmt)
686 struct hdmi_video_interface *video_int)
687{ 686{
688 pr_debug("Enter hdmi_wp_init\n"); 687 pr_debug("Enter hdmi_wp_init\n");
689 688
@@ -698,12 +697,6 @@ static void hdmi_wp_init(struct omap_video_timings *timings,
698 video_fmt->y_res = 0; 697 video_fmt->y_res = 0;
699 video_fmt->x_res = 0; 698 video_fmt->x_res = 0;
700 699
701 video_int->vsp = 0;
702 video_int->hsp = 0;
703
704 video_int->interlacing = 0;
705 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
706
707} 700}
708 701
709void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start) 702void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start)
@@ -716,15 +709,15 @@ static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
716{ 709{
717 pr_debug("Enter hdmi_wp_video_init_format\n"); 710 pr_debug("Enter hdmi_wp_video_init_format\n");
718 711
719 video_fmt->y_res = param->timings.timings.y_res; 712 video_fmt->y_res = param->timings.y_res;
720 video_fmt->x_res = param->timings.timings.x_res; 713 video_fmt->x_res = param->timings.x_res;
721 714
722 timings->hbp = param->timings.timings.hbp; 715 timings->hbp = param->timings.hbp;
723 timings->hfp = param->timings.timings.hfp; 716 timings->hfp = param->timings.hfp;
724 timings->hsw = param->timings.timings.hsw; 717 timings->hsw = param->timings.hsw;
725 timings->vbp = param->timings.timings.vbp; 718 timings->vbp = param->timings.vbp;
726 timings->vfp = param->timings.timings.vfp; 719 timings->vfp = param->timings.vfp;
727 timings->vsw = param->timings.timings.vsw; 720 timings->vsw = param->timings.vsw;
728} 721}
729 722
730static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, 723static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
@@ -740,17 +733,16 @@ static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
740 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l); 733 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l);
741} 734}
742 735
743static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data, 736static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data)
744 struct hdmi_video_interface *video_int)
745{ 737{
746 u32 r; 738 u32 r;
747 pr_debug("Enter hdmi_wp_video_config_interface\n"); 739 pr_debug("Enter hdmi_wp_video_config_interface\n");
748 740
749 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); 741 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG);
750 r = FLD_MOD(r, video_int->vsp, 7, 7); 742 r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7);
751 r = FLD_MOD(r, video_int->hsp, 6, 6); 743 r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6);
752 r = FLD_MOD(r, video_int->interlacing, 3, 3); 744 r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3);
753 r = FLD_MOD(r, video_int->tm, 1, 0); 745 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */
754 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); 746 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r);
755} 747}
756 748
@@ -778,15 +770,13 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
778 /* HDMI */ 770 /* HDMI */
779 struct omap_video_timings video_timing; 771 struct omap_video_timings video_timing;
780 struct hdmi_video_format video_format; 772 struct hdmi_video_format video_format;
781 struct hdmi_video_interface video_interface;
782 /* HDMI core */ 773 /* HDMI core */
783 struct hdmi_core_infoframe_avi avi_cfg; 774 struct hdmi_core_infoframe_avi avi_cfg = ip_data->avi_cfg;
784 struct hdmi_core_video_config v_core_cfg; 775 struct hdmi_core_video_config v_core_cfg;
785 struct hdmi_core_packet_enable_repeat repeat_cfg; 776 struct hdmi_core_packet_enable_repeat repeat_cfg;
786 struct hdmi_config *cfg = &ip_data->cfg; 777 struct hdmi_config *cfg = &ip_data->cfg;
787 778
788 hdmi_wp_init(&video_timing, &video_format, 779 hdmi_wp_init(&video_timing, &video_format);
789 &video_interface);
790 780
791 hdmi_core_init(&v_core_cfg, 781 hdmi_core_init(&v_core_cfg,
792 &avi_cfg, 782 &avi_cfg,
@@ -801,12 +791,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
801 791
802 hdmi_wp_video_config_format(ip_data, &video_format); 792 hdmi_wp_video_config_format(ip_data, &video_format);
803 793
804 video_interface.vsp = cfg->timings.vsync_pol; 794 hdmi_wp_video_config_interface(ip_data);
805 video_interface.hsp = cfg->timings.hsync_pol;
806 video_interface.interlacing = cfg->interlace;
807 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
808
809 hdmi_wp_video_config_interface(ip_data, &video_interface);
810 795
811 /* 796 /*
812 * configure core video part 797 * configure core video part
@@ -848,7 +833,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
848 avi_cfg.db10_11_pixel_eofleft = 0; 833 avi_cfg.db10_11_pixel_eofleft = 0;
849 avi_cfg.db12_13_pixel_sofright = 0; 834 avi_cfg.db12_13_pixel_sofright = 0;
850 835
851 hdmi_core_aux_infoframe_avi_config(ip_data, avi_cfg); 836 hdmi_core_aux_infoframe_avi_config(ip_data);
852 837
853 /* enable/repeat the infoframe */ 838 /* enable/repeat the infoframe */
854 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; 839 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
@@ -1076,13 +1061,9 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
1076 u32 r; 1061 u32 r;
1077 void __iomem *av_base = hdmi_av_base(ip_data); 1062 void __iomem *av_base = hdmi_av_base(ip_data);
1078 1063
1079 /* audio clock recovery parameters */ 1064 /*
1080 r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL); 1065 * Parameters for generation of Audio Clock Recovery packets
1081 r = FLD_MOD(r, cfg->use_mclk, 2, 2); 1066 */
1082 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1083 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1084 hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r);
1085
1086 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0); 1067 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
1087 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0); 1068 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
1088 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0); 1069 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
@@ -1094,14 +1075,6 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
1094 REG_FLD_MOD(av_base, 1075 REG_FLD_MOD(av_base,
1095 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0); 1076 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
1096 } else { 1077 } else {
1097 /*
1098 * HDMI IP uses this configuration to divide the MCLK to
1099 * update CTS value.
1100 */
1101 REG_FLD_MOD(av_base,
1102 HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1103
1104 /* Configure clock for audio packets */
1105 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1, 1078 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
1106 cfg->aud_par_busclk, 7, 0); 1079 cfg->aud_par_busclk, 7, 0);
1107 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2, 1080 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
@@ -1110,6 +1083,25 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
1110 (cfg->aud_par_busclk >> 16), 7, 0); 1083 (cfg->aud_par_busclk >> 16), 7, 0);
1111 } 1084 }
1112 1085
1086 /* Set ACR clock divisor */
1087 REG_FLD_MOD(av_base,
1088 HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1089
1090 r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL);
1091 /*
1092 * Use TMDS clock for ACR packets. For devices that use
1093 * the MCLK, this is the first part of the MCLK initialization.
1094 */
1095 r = FLD_MOD(r, 0, 2, 2);
1096
1097 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1098 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1099 hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r);
1100
1101 /* For devices using MCLK, this completes its initialization. */
1102 if (cfg->use_mclk)
1103 REG_FLD_MOD(av_base, HDMI_CORE_AV_ACR_CTRL, 1, 2, 2);
1104
1113 /* Override of SPDIF sample frequency with value in I2S_CHST4 */ 1105 /* Override of SPDIF sample frequency with value in I2S_CHST4 */
1114 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, 1106 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL,
1115 cfg->fs_override, 1, 1); 1107 cfg->fs_override, 1, 1);
@@ -1205,7 +1197,7 @@ int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
1205{ 1197{
1206 u32 r; 1198 u32 r;
1207 u32 deep_color = 0; 1199 u32 deep_color = 0;
1208 u32 pclk = ip_data->cfg.timings.timings.pixel_clock; 1200 u32 pclk = ip_data->cfg.timings.pixel_clock;
1209 1201
1210 if (n == NULL || cts == NULL) 1202 if (n == NULL || cts == NULL)
1211 return -EINVAL; 1203 return -EINVAL;
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
index a442998980f1..a14d1a0e6e41 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
@@ -450,46 +450,6 @@ struct hdmi_core_video_config {
450 * Refer to section 8.2 in HDMI 1.3 specification for 450 * Refer to section 8.2 in HDMI 1.3 specification for
451 * details about infoframe databytes 451 * details about infoframe databytes
452 */ 452 */
453struct hdmi_core_infoframe_avi {
454 /* Y0, Y1 rgb,yCbCr */
455 u8 db1_format;
456 /* A0 Active information Present */
457 u8 db1_active_info;
458 /* B0, B1 Bar info data valid */
459 u8 db1_bar_info_dv;
460 /* S0, S1 scan information */
461 u8 db1_scan_info;
462 /* C0, C1 colorimetry */
463 u8 db2_colorimetry;
464 /* M0, M1 Aspect ratio (4:3, 16:9) */
465 u8 db2_aspect_ratio;
466 /* R0...R3 Active format aspect ratio */
467 u8 db2_active_fmt_ar;
468 /* ITC IT content. */
469 u8 db3_itc;
470 /* EC0, EC1, EC2 Extended colorimetry */
471 u8 db3_ec;
472 /* Q1, Q0 Quantization range */
473 u8 db3_q_range;
474 /* SC1, SC0 Non-uniform picture scaling */
475 u8 db3_nup_scaling;
476 /* VIC0..6 Video format identification */
477 u8 db4_videocode;
478 /* PR0..PR3 Pixel repetition factor */
479 u8 db5_pixel_repeat;
480 /* Line number end of top bar */
481 u16 db6_7_line_eoftop;
482 /* Line number start of bottom bar */
483 u16 db8_9_line_sofbottom;
484 /* Pixel number end of left bar */
485 u16 db10_11_pixel_eofleft;
486 /* Pixel number start of right bar */
487 u16 db12_13_pixel_sofright;
488};
489/*
490 * Refer to section 8.2 in HDMI 1.3 specification for
491 * details about infoframe databytes
492 */
493struct hdmi_core_infoframe_audio { 453struct hdmi_core_infoframe_audio {
494 u8 db1_coding_type; 454 u8 db1_coding_type;
495 u8 db1_channel_count; 455 u8 db1_channel_count;
@@ -517,13 +477,6 @@ struct hdmi_video_format {
517 u32 x_res; /* pixel per line */ 477 u32 x_res; /* pixel per line */
518}; 478};
519 479
520struct hdmi_video_interface {
521 int vsp; /* Vsync polarity */
522 int hsp; /* Hsync polarity */
523 int interlacing;
524 int tm; /* Timing mode */
525};
526
527struct hdmi_audio_format { 480struct hdmi_audio_format {
528 enum hdmi_stereo_channels stereo_channels; 481 enum hdmi_stereo_channels stereo_channels;
529 u8 active_chnnls_msk; 482 u8 active_chnnls_msk;
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 5c3d0f901510..9c3daf71750c 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -699,6 +699,11 @@ void venc_dump_regs(struct seq_file *s)
699{ 699{
700#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) 700#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
701 701
702 if (cpu_is_omap44xx()) {
703 seq_printf(s, "VENC currently disabled on OMAP44xx\n");
704 return;
705 }
706
702 if (venc_runtime_get()) 707 if (venc_runtime_get())
703 return; 708 return;
704 709
@@ -790,39 +795,41 @@ static int omap_venchw_probe(struct platform_device *pdev)
790 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0); 795 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
791 if (!venc_mem) { 796 if (!venc_mem) {
792 DSSERR("can't get IORESOURCE_MEM VENC\n"); 797 DSSERR("can't get IORESOURCE_MEM VENC\n");
793 r = -EINVAL; 798 return -EINVAL;
794 goto err_ioremap;
795 } 799 }
796 venc.base = ioremap(venc_mem->start, resource_size(venc_mem)); 800
801 venc.base = devm_ioremap(&pdev->dev, venc_mem->start,
802 resource_size(venc_mem));
797 if (!venc.base) { 803 if (!venc.base) {
798 DSSERR("can't ioremap VENC\n"); 804 DSSERR("can't ioremap VENC\n");
799 r = -ENOMEM; 805 return -ENOMEM;
800 goto err_ioremap;
801 } 806 }
802 807
803 r = venc_get_clocks(pdev); 808 r = venc_get_clocks(pdev);
804 if (r) 809 if (r)
805 goto err_get_clk; 810 return r;
806 811
807 pm_runtime_enable(&pdev->dev); 812 pm_runtime_enable(&pdev->dev);
808 813
809 r = venc_runtime_get(); 814 r = venc_runtime_get();
810 if (r) 815 if (r)
811 goto err_get_venc; 816 goto err_runtime_get;
812 817
813 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff); 818 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
814 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id); 819 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
815 820
816 venc_runtime_put(); 821 venc_runtime_put();
817 822
818 return omap_dss_register_driver(&venc_driver); 823 r = omap_dss_register_driver(&venc_driver);
824 if (r)
825 goto err_reg_panel_driver;
826
827 return 0;
819 828
820err_get_venc: 829err_reg_panel_driver:
830err_runtime_get:
821 pm_runtime_disable(&pdev->dev); 831 pm_runtime_disable(&pdev->dev);
822 venc_put_clocks(); 832 venc_put_clocks();
823err_get_clk:
824 iounmap(venc.base);
825err_ioremap:
826 return r; 833 return r;
827} 834}
828 835
@@ -837,7 +844,6 @@ static int omap_venchw_remove(struct platform_device *pdev)
837 pm_runtime_disable(&pdev->dev); 844 pm_runtime_disable(&pdev->dev);
838 venc_put_clocks(); 845 venc_put_clocks();
839 846
840 iounmap(venc.base);
841 return 0; 847 return 0;
842} 848}
843 849
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 16ba6196f330..6a09ef87e14f 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -215,7 +215,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
215 int r = 0, i; 215 int r = 0, i;
216 size_t size; 216 size_t size;
217 217
218 if (mi->type > OMAPFB_MEMTYPE_MAX) 218 if (mi->type != OMAPFB_MEMTYPE_SDRAM)
219 return -EINVAL; 219 return -EINVAL;
220 220
221 size = PAGE_ALIGN(mi->size); 221 size = PAGE_ALIGN(mi->size);
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index ce158311ff59..b00db4068d21 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1399,7 +1399,7 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1399 1399
1400 if (!paddr) { 1400 if (!paddr) {
1401 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id); 1401 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
1402 r = omap_vram_alloc(OMAP_VRAM_MEMTYPE_SDRAM, size, &paddr); 1402 r = omap_vram_alloc(size, &paddr);
1403 } else { 1403 } else {
1404 DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr, 1404 DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
1405 ofbi->id); 1405 ofbi->id);
@@ -1487,60 +1487,6 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1487 return omapfb_alloc_fbmem(fbi, size, paddr); 1487 return omapfb_alloc_fbmem(fbi, size, paddr);
1488} 1488}
1489 1489
1490static enum omap_color_mode fb_format_to_dss_mode(enum omapfb_color_format fmt)
1491{
1492 enum omap_color_mode mode;
1493
1494 switch (fmt) {
1495 case OMAPFB_COLOR_RGB565:
1496 mode = OMAP_DSS_COLOR_RGB16;
1497 break;
1498 case OMAPFB_COLOR_YUV422:
1499 mode = OMAP_DSS_COLOR_YUV2;
1500 break;
1501 case OMAPFB_COLOR_CLUT_8BPP:
1502 mode = OMAP_DSS_COLOR_CLUT8;
1503 break;
1504 case OMAPFB_COLOR_CLUT_4BPP:
1505 mode = OMAP_DSS_COLOR_CLUT4;
1506 break;
1507 case OMAPFB_COLOR_CLUT_2BPP:
1508 mode = OMAP_DSS_COLOR_CLUT2;
1509 break;
1510 case OMAPFB_COLOR_CLUT_1BPP:
1511 mode = OMAP_DSS_COLOR_CLUT1;
1512 break;
1513 case OMAPFB_COLOR_RGB444:
1514 mode = OMAP_DSS_COLOR_RGB12U;
1515 break;
1516 case OMAPFB_COLOR_YUY422:
1517 mode = OMAP_DSS_COLOR_UYVY;
1518 break;
1519 case OMAPFB_COLOR_ARGB16:
1520 mode = OMAP_DSS_COLOR_ARGB16;
1521 break;
1522 case OMAPFB_COLOR_RGB24U:
1523 mode = OMAP_DSS_COLOR_RGB24U;
1524 break;
1525 case OMAPFB_COLOR_RGB24P:
1526 mode = OMAP_DSS_COLOR_RGB24P;
1527 break;
1528 case OMAPFB_COLOR_ARGB32:
1529 mode = OMAP_DSS_COLOR_ARGB32;
1530 break;
1531 case OMAPFB_COLOR_RGBA32:
1532 mode = OMAP_DSS_COLOR_RGBA32;
1533 break;
1534 case OMAPFB_COLOR_RGBX32:
1535 mode = OMAP_DSS_COLOR_RGBX32;
1536 break;
1537 default:
1538 mode = -EINVAL;
1539 }
1540
1541 return mode;
1542}
1543
1544static int omapfb_parse_vram_param(const char *param, int max_entries, 1490static int omapfb_parse_vram_param(const char *param, int max_entries,
1545 unsigned long *sizes, unsigned long *paddrs) 1491 unsigned long *sizes, unsigned long *paddrs)
1546{ 1492{
@@ -1614,23 +1560,6 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
1614 memset(&vram_paddrs, 0, sizeof(vram_paddrs)); 1560 memset(&vram_paddrs, 0, sizeof(vram_paddrs));
1615 } 1561 }
1616 1562
1617 if (fbdev->dev->platform_data) {
1618 struct omapfb_platform_data *opd;
1619 opd = fbdev->dev->platform_data;
1620 for (i = 0; i < opd->mem_desc.region_cnt; ++i) {
1621 if (!vram_sizes[i]) {
1622 unsigned long size;
1623 unsigned long paddr;
1624
1625 size = opd->mem_desc.region[i].size;
1626 paddr = opd->mem_desc.region[i].paddr;
1627
1628 vram_sizes[i] = size;
1629 vram_paddrs[i] = paddr;
1630 }
1631 }
1632 }
1633
1634 for (i = 0; i < fbdev->num_fbs; i++) { 1563 for (i = 0; i < fbdev->num_fbs; i++) {
1635 /* allocate memory automatically only for fb0, or if 1564 /* allocate memory automatically only for fb0, or if
1636 * excplicitly defined with vram or plat data option */ 1565 * excplicitly defined with vram or plat data option */
@@ -1669,7 +1598,7 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1669 int old_type = rg->type; 1598 int old_type = rg->type;
1670 int r; 1599 int r;
1671 1600
1672 if (type > OMAPFB_MEMTYPE_MAX) 1601 if (type != OMAPFB_MEMTYPE_SDRAM)
1673 return -EINVAL; 1602 return -EINVAL;
1674 1603
1675 size = PAGE_ALIGN(size); 1604 size = PAGE_ALIGN(size);
@@ -1828,32 +1757,6 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1828 1757
1829 var->rotate = def_rotate; 1758 var->rotate = def_rotate;
1830 1759
1831 /*
1832 * Check if there is a default color format set in the board file,
1833 * and use this format instead the default deducted from the
1834 * display bpp.
1835 */
1836 if (fbdev->dev->platform_data) {
1837 struct omapfb_platform_data *opd;
1838 int id = ofbi->id;
1839
1840 opd = fbdev->dev->platform_data;
1841 if (opd->mem_desc.region[id].format_used) {
1842 enum omap_color_mode mode;
1843 enum omapfb_color_format format;
1844
1845 format = opd->mem_desc.region[id].format;
1846 mode = fb_format_to_dss_mode(format);
1847 if (mode < 0) {
1848 r = mode;
1849 goto err;
1850 }
1851 r = dss_mode_to_fb_mode(mode, var);
1852 if (r < 0)
1853 goto err;
1854 }
1855 }
1856
1857 if (display) { 1760 if (display) {
1858 u16 w, h; 1761 u16 w, h;
1859 int rotation = (var->rotate + ofbi->rotation[0]) % 4; 1762 int rotation = (var->rotate + ofbi->rotation[0]) % 4;
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 9441e2eb3dee..87e421e25afe 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -33,7 +33,6 @@
33 33
34#include <asm/setup.h> 34#include <asm/setup.h>
35 35
36#include <plat/sram.h>
37#include <plat/vram.h> 36#include <plat/vram.h>
38#include <plat/dma.h> 37#include <plat/dma.h>
39 38
@@ -43,10 +42,6 @@
43#define DBG(format, ...) 42#define DBG(format, ...)
44#endif 43#endif
45 44
46#define OMAP2_SRAM_START 0x40200000
47/* Maximum size, in reality this is smaller if SRAM is partially locked. */
48#define OMAP2_SRAM_SIZE 0xa0000 /* 640k */
49
50/* postponed regions are used to temporarily store region information at boot 45/* postponed regions are used to temporarily store region information at boot
51 * time when we cannot yet allocate the region list */ 46 * time when we cannot yet allocate the region list */
52#define MAX_POSTPONED_REGIONS 10 47#define MAX_POSTPONED_REGIONS 10
@@ -74,15 +69,6 @@ struct vram_region {
74static DEFINE_MUTEX(region_mutex); 69static DEFINE_MUTEX(region_mutex);
75static LIST_HEAD(region_list); 70static LIST_HEAD(region_list);
76 71
77static inline int region_mem_type(unsigned long paddr)
78{
79 if (paddr >= OMAP2_SRAM_START &&
80 paddr < OMAP2_SRAM_START + OMAP2_SRAM_SIZE)
81 return OMAP_VRAM_MEMTYPE_SRAM;
82 else
83 return OMAP_VRAM_MEMTYPE_SDRAM;
84}
85
86static struct vram_region *omap_vram_create_region(unsigned long paddr, 72static struct vram_region *omap_vram_create_region(unsigned long paddr,
87 unsigned pages) 73 unsigned pages)
88{ 74{
@@ -212,9 +198,6 @@ static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
212 198
213 DBG("checking region %lx %d\n", rm->paddr, rm->pages); 199 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
214 200
215 if (region_mem_type(rm->paddr) != region_mem_type(paddr))
216 continue;
217
218 start = rm->paddr; 201 start = rm->paddr;
219 end = start + (rm->pages << PAGE_SHIFT) - 1; 202 end = start + (rm->pages << PAGE_SHIFT) - 1;
220 if (start > paddr || end < paddr + size - 1) 203 if (start > paddr || end < paddr + size - 1)
@@ -320,7 +303,7 @@ err:
320 return r; 303 return r;
321} 304}
322 305
323static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr) 306static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
324{ 307{
325 struct vram_region *rm; 308 struct vram_region *rm;
326 struct vram_alloc *alloc; 309 struct vram_alloc *alloc;
@@ -330,9 +313,6 @@ static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
330 313
331 DBG("checking region %lx %d\n", rm->paddr, rm->pages); 314 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
332 315
333 if (region_mem_type(rm->paddr) != mtype)
334 continue;
335
336 start = rm->paddr; 316 start = rm->paddr;
337 317
338 list_for_each_entry(alloc, &rm->alloc_list, list) { 318 list_for_each_entry(alloc, &rm->alloc_list, list) {
@@ -365,21 +345,21 @@ found:
365 return -ENOMEM; 345 return -ENOMEM;
366} 346}
367 347
368int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr) 348int omap_vram_alloc(size_t size, unsigned long *paddr)
369{ 349{
370 unsigned pages; 350 unsigned pages;
371 int r; 351 int r;
372 352
373 BUG_ON(mtype > OMAP_VRAM_MEMTYPE_MAX || !size); 353 BUG_ON(!size);
374 354
375 DBG("alloc mem type %d size %d\n", mtype, size); 355 DBG("alloc mem size %d\n", size);
376 356
377 size = PAGE_ALIGN(size); 357 size = PAGE_ALIGN(size);
378 pages = size >> PAGE_SHIFT; 358 pages = size >> PAGE_SHIFT;
379 359
380 mutex_lock(&region_mutex); 360 mutex_lock(&region_mutex);
381 361
382 r = _omap_vram_alloc(mtype, pages, paddr); 362 r = _omap_vram_alloc(pages, paddr);
383 363
384 mutex_unlock(&region_mutex); 364 mutex_unlock(&region_mutex);
385 365
@@ -501,10 +481,6 @@ arch_initcall(omap_vram_init);
501/* boottime vram alloc stuff */ 481/* boottime vram alloc stuff */
502 482
503/* set from board file */ 483/* set from board file */
504static u32 omap_vram_sram_start __initdata;
505static u32 omap_vram_sram_size __initdata;
506
507/* set from board file */
508static u32 omap_vram_sdram_start __initdata; 484static u32 omap_vram_sdram_start __initdata;
509static u32 omap_vram_sdram_size __initdata; 485static u32 omap_vram_sdram_size __initdata;
510 486
@@ -587,73 +563,8 @@ void __init omap_vram_reserve_sdram_memblock(void)
587 pr_info("Reserving %u bytes SDRAM for VRAM\n", size); 563 pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
588} 564}
589 565
590/*
591 * Called at sram init time, before anything is pushed to the SRAM stack.
592 * Because of the stack scheme, we will allocate everything from the
593 * start of the lowest address region to the end of SRAM. This will also
594 * include padding for page alignment and possible holes between regions.
595 *
596 * As opposed to the SDRAM case, we'll also do any dynamic allocations at
597 * this point, since the driver built as a module would have problem with
598 * freeing / reallocating the regions.
599 */
600unsigned long __init omap_vram_reserve_sram(unsigned long sram_pstart,
601 unsigned long sram_vstart,
602 unsigned long sram_size,
603 unsigned long pstart_avail,
604 unsigned long size_avail)
605{
606 unsigned long pend_avail;
607 unsigned long reserved;
608 u32 paddr;
609 u32 size;
610
611 paddr = omap_vram_sram_start;
612 size = omap_vram_sram_size;
613
614 if (!size)
615 return 0;
616
617 reserved = 0;
618 pend_avail = pstart_avail + size_avail;
619
620 if (!paddr) {
621 /* Dynamic allocation */
622 if ((size_avail & PAGE_MASK) < size) {
623 pr_err("Not enough SRAM for VRAM\n");
624 return 0;
625 }
626 size_avail = (size_avail - size) & PAGE_MASK;
627 paddr = pstart_avail + size_avail;
628 }
629
630 if (paddr < sram_pstart ||
631 paddr + size > sram_pstart + sram_size) {
632 pr_err("Illegal SRAM region for VRAM\n");
633 return 0;
634 }
635
636 /* Reserve everything above the start of the region. */
637 if (pend_avail - paddr > reserved)
638 reserved = pend_avail - paddr;
639 size_avail = pend_avail - reserved - pstart_avail;
640
641 omap_vram_add_region(paddr, size);
642
643 if (reserved)
644 pr_info("Reserving %lu bytes SRAM for VRAM\n", reserved);
645
646 return reserved;
647}
648
649void __init omap_vram_set_sdram_vram(u32 size, u32 start) 566void __init omap_vram_set_sdram_vram(u32 size, u32 start)
650{ 567{
651 omap_vram_sdram_start = start; 568 omap_vram_sdram_start = start;
652 omap_vram_sdram_size = size; 569 omap_vram_sdram_size = size;
653} 570}
654
655void __init omap_vram_set_sram_vram(u32 size, u32 start)
656{
657 omap_vram_sram_start = start;
658 omap_vram_sram_size = size;
659}