aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c23
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c153
-rw-r--r--drivers/video/omap2/dss/apply.c221
-rw-r--r--drivers/video/omap2/dss/dispc.c112
-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.c178
-rw-r--r--drivers/video/omap2/dss/dss_features.h54
-rw-r--r--drivers/video/omap2/dss/hdmi.c262
-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
16 files changed, 842 insertions, 528 deletions
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-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index e6649aa89591..d63e5e5dbbfa 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
377 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
378 406
379 return 0; 407 return tpo_td043_enable_dss(dssdev);
380} 408}
381 409
382static int tpo_td043_probe(struct omap_dss_device *dssdev) 410static int tpo_td043_probe(struct omap_dss_device *dssdev)
@@ -491,6 +519,7 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
491 return -ENOMEM; 519 return -ENOMEM;
492 520
493 tpo_td043->spi = spi; 521 tpo_td043->spi = spi;
522 tpo_td043->nreset_gpio = dssdev->reset_gpio;
494 dev_set_drvdata(&spi->dev, tpo_td043); 523 dev_set_drvdata(&spi->dev, tpo_td043);
495 dev_set_drvdata(&dssdev->dev, tpo_td043); 524 dev_set_drvdata(&dssdev->dev, tpo_td043);
496 525
@@ -509,10 +538,46 @@ static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
509 return 0; 538 return 0;
510} 539}
511 540
541#ifdef CONFIG_PM_SLEEP
542static int tpo_td043_spi_suspend(struct device *dev)
543{
544 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
545
546 dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043);
547
548 tpo_td043->power_on_resume = tpo_td043->powered_on;
549 tpo_td043_power_off(tpo_td043);
550 tpo_td043->spi_suspended = 1;
551
552 return 0;
553}
554
555static int tpo_td043_spi_resume(struct device *dev)
556{
557 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
558 int ret;
559
560 dev_dbg(dev, "tpo_td043_spi_resume\n");
561
562 if (tpo_td043->power_on_resume) {
563 ret = tpo_td043_power_on(tpo_td043);
564 if (ret)
565 return ret;
566 }
567 tpo_td043->spi_suspended = 0;
568
569 return 0;
570}
571#endif
572
573static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
574 tpo_td043_spi_suspend, tpo_td043_spi_resume);
575
512static struct spi_driver tpo_td043_spi_driver = { 576static struct spi_driver tpo_td043_spi_driver = {
513 .driver = { 577 .driver = {
514 .name = "tpo_td043mtea1_panel_spi", 578 .name = "tpo_td043mtea1_panel_spi",
515 .owner = THIS_MODULE, 579 .owner = THIS_MODULE,
580 .pm = &tpo_td043_spi_pm,
516 }, 581 },
517 .probe = tpo_td043_spi_probe, 582 .probe = tpo_td043_spi_probe,
518 .remove = __devexit_p(tpo_td043_spi_remove), 583 .remove = __devexit_p(tpo_td043_spi_remove),
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 052dc874cd3d..b0264a164652 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
@@ -585,11 +588,40 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
585 } 588 }
586} 589}
587 590
591static void dss_write_regs_common(void)
592{
593 const int num_mgrs = omap_dss_get_num_overlay_managers();
594 int i;
595
596 if (!dss_data.fifo_merge_dirty)
597 return;
598
599 for (i = 0; i < num_mgrs; ++i) {
600 struct omap_overlay_manager *mgr;
601 struct mgr_priv_data *mp;
602
603 mgr = omap_dss_get_overlay_manager(i);
604 mp = get_mgr_priv(mgr);
605
606 if (mp->enabled) {
607 if (dss_data.fifo_merge_dirty) {
608 dispc_enable_fifomerge(dss_data.fifo_merge);
609 dss_data.fifo_merge_dirty = false;
610 }
611
612 if (mp->updating)
613 mp->shadow_info_dirty = true;
614 }
615 }
616}
617
588static void dss_write_regs(void) 618static void dss_write_regs(void)
589{ 619{
590 const int num_mgrs = omap_dss_get_num_overlay_managers(); 620 const int num_mgrs = omap_dss_get_num_overlay_managers();
591 int i; 621 int i;
592 622
623 dss_write_regs_common();
624
593 for (i = 0; i < num_mgrs; ++i) { 625 for (i = 0; i < num_mgrs; ++i) {
594 struct omap_overlay_manager *mgr; 626 struct omap_overlay_manager *mgr;
595 struct mgr_priv_data *mp; 627 struct mgr_priv_data *mp;
@@ -659,6 +691,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
659 691
660 dss_mgr_write_regs(mgr); 692 dss_mgr_write_regs(mgr);
661 693
694 dss_write_regs_common();
695
662 mp->updating = true; 696 mp->updating = true;
663 697
664 if (!dss_data.irq_enabled && need_isr()) 698 if (!dss_data.irq_enabled && need_isr())
@@ -859,11 +893,20 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
859 op->extra_info_dirty = true; 893 op->extra_info_dirty = true;
860} 894}
861 895
862static void dss_ovl_setup_fifo(struct omap_overlay *ovl) 896static void dss_apply_fifo_merge(bool use_fifo_merge)
897{
898 if (dss_data.fifo_merge == use_fifo_merge)
899 return;
900
901 dss_data.fifo_merge = use_fifo_merge;
902 dss_data.fifo_merge_dirty = true;
903}
904
905static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
906 bool use_fifo_merge)
863{ 907{
864 struct ovl_priv_data *op = get_ovl_priv(ovl); 908 struct ovl_priv_data *op = get_ovl_priv(ovl);
865 struct omap_dss_device *dssdev; 909 struct omap_dss_device *dssdev;
866 u32 size, burst_size;
867 u32 fifo_low, fifo_high; 910 u32 fifo_low, fifo_high;
868 911
869 if (!op->enabled && !op->enabling) 912 if (!op->enabled && !op->enabling)
@@ -871,33 +914,14 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
871 914
872 dssdev = ovl->manager->device; 915 dssdev = ovl->manager->device;
873 916
874 size = dispc_ovl_get_fifo_size(ovl->id); 917 dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high,
875 918 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 919
897 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); 920 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
898} 921}
899 922
900static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) 923static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
924 bool use_fifo_merge)
901{ 925{
902 struct omap_overlay *ovl; 926 struct omap_overlay *ovl;
903 struct mgr_priv_data *mp; 927 struct mgr_priv_data *mp;
@@ -908,19 +932,94 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
908 return; 932 return;
909 933
910 list_for_each_entry(ovl, &mgr->overlays, list) 934 list_for_each_entry(ovl, &mgr->overlays, list)
911 dss_ovl_setup_fifo(ovl); 935 dss_ovl_setup_fifo(ovl, use_fifo_merge);
936}
937
938static void dss_setup_fifos(bool use_fifo_merge)
939{
940 const int num_mgrs = omap_dss_get_num_overlay_managers();
941 struct omap_overlay_manager *mgr;
942 int i;
943
944 for (i = 0; i < num_mgrs; ++i) {
945 mgr = omap_dss_get_overlay_manager(i);
946 dss_mgr_setup_fifos(mgr, use_fifo_merge);
947 }
912} 948}
913 949
914static void dss_setup_fifos(void) 950static int get_num_used_managers(void)
915{ 951{
916 const int num_mgrs = omap_dss_get_num_overlay_managers(); 952 const int num_mgrs = omap_dss_get_num_overlay_managers();
917 struct omap_overlay_manager *mgr; 953 struct omap_overlay_manager *mgr;
954 struct mgr_priv_data *mp;
918 int i; 955 int i;
956 int enabled_mgrs;
957
958 enabled_mgrs = 0;
919 959
920 for (i = 0; i < num_mgrs; ++i) { 960 for (i = 0; i < num_mgrs; ++i) {
921 mgr = omap_dss_get_overlay_manager(i); 961 mgr = omap_dss_get_overlay_manager(i);
922 dss_mgr_setup_fifos(mgr); 962 mp = get_mgr_priv(mgr);
963
964 if (!mp->enabled)
965 continue;
966
967 enabled_mgrs++;
923 } 968 }
969
970 return enabled_mgrs;
971}
972
973static int get_num_used_overlays(void)
974{
975 const int num_ovls = omap_dss_get_num_overlays();
976 struct omap_overlay *ovl;
977 struct ovl_priv_data *op;
978 struct mgr_priv_data *mp;
979 int i;
980 int enabled_ovls;
981
982 enabled_ovls = 0;
983
984 for (i = 0; i < num_ovls; ++i) {
985 ovl = omap_dss_get_overlay(i);
986 op = get_ovl_priv(ovl);
987
988 if (!op->enabled && !op->enabling)
989 continue;
990
991 mp = get_mgr_priv(ovl->manager);
992
993 if (!mp->enabled)
994 continue;
995
996 enabled_ovls++;
997 }
998
999 return enabled_ovls;
1000}
1001
1002static bool get_use_fifo_merge(void)
1003{
1004 int enabled_mgrs = get_num_used_managers();
1005 int enabled_ovls = get_num_used_overlays();
1006
1007 if (!dss_has_feature(FEAT_FIFO_MERGE))
1008 return false;
1009
1010 /*
1011 * In theory the only requirement for fifomerge is enabled_ovls <= 1.
1012 * However, if we have two managers enabled and set/unset the fifomerge,
1013 * we need to set the GO bits in particular sequence for the managers,
1014 * and wait in between.
1015 *
1016 * This is rather difficult as new apply calls can happen at any time,
1017 * so we simplify the problem by requiring also that enabled_mgrs <= 1.
1018 * In practice this shouldn't matter, because when only one overlay is
1019 * enabled, most likely only one output is enabled.
1020 */
1021
1022 return enabled_mgrs <= 1 && enabled_ovls <= 1;
924} 1023}
925 1024
926int dss_mgr_enable(struct omap_overlay_manager *mgr) 1025int dss_mgr_enable(struct omap_overlay_manager *mgr)
@@ -928,6 +1027,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
928 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1027 struct mgr_priv_data *mp = get_mgr_priv(mgr);
929 unsigned long flags; 1028 unsigned long flags;
930 int r; 1029 int r;
1030 bool fifo_merge;
931 1031
932 mutex_lock(&apply_lock); 1032 mutex_lock(&apply_lock);
933 1033
@@ -945,11 +1045,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
945 goto err; 1045 goto err;
946 } 1046 }
947 1047
948 dss_setup_fifos(); 1048 /* step 1: setup fifos/fifomerge before enabling the manager */
1049
1050 fifo_merge = get_use_fifo_merge();
1051 dss_setup_fifos(fifo_merge);
1052 dss_apply_fifo_merge(fifo_merge);
949 1053
950 dss_write_regs(); 1054 dss_write_regs();
951 dss_set_go_bits(); 1055 dss_set_go_bits();
952 1056
1057 spin_unlock_irqrestore(&data_lock, flags);
1058
1059 /* wait until fifo config is in */
1060 wait_pending_extra_info_updates();
1061
1062 /* step 2: enable the manager */
1063 spin_lock_irqsave(&data_lock, flags);
1064
953 if (!mgr_manual_update(mgr)) 1065 if (!mgr_manual_update(mgr))
954 mp->updating = true; 1066 mp->updating = true;
955 1067
@@ -974,6 +1086,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
974{ 1086{
975 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1087 struct mgr_priv_data *mp = get_mgr_priv(mgr);
976 unsigned long flags; 1088 unsigned long flags;
1089 bool fifo_merge;
977 1090
978 mutex_lock(&apply_lock); 1091 mutex_lock(&apply_lock);
979 1092
@@ -988,8 +1101,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
988 mp->updating = false; 1101 mp->updating = false;
989 mp->enabled = false; 1102 mp->enabled = false;
990 1103
1104 fifo_merge = get_use_fifo_merge();
1105 dss_setup_fifos(fifo_merge);
1106 dss_apply_fifo_merge(fifo_merge);
1107
1108 dss_write_regs();
1109 dss_set_go_bits();
1110
991 spin_unlock_irqrestore(&data_lock, flags); 1111 spin_unlock_irqrestore(&data_lock, flags);
992 1112
1113 wait_pending_extra_info_updates();
993out: 1114out:
994 mutex_unlock(&apply_lock); 1115 mutex_unlock(&apply_lock);
995} 1116}
@@ -1241,6 +1362,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1241{ 1362{
1242 struct ovl_priv_data *op = get_ovl_priv(ovl); 1363 struct ovl_priv_data *op = get_ovl_priv(ovl);
1243 unsigned long flags; 1364 unsigned long flags;
1365 bool fifo_merge;
1244 int r; 1366 int r;
1245 1367
1246 mutex_lock(&apply_lock); 1368 mutex_lock(&apply_lock);
@@ -1266,7 +1388,22 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1266 goto err2; 1388 goto err2;
1267 } 1389 }
1268 1390
1269 dss_setup_fifos(); 1391 /* step 1: configure fifos/fifomerge for currently enabled ovls */
1392
1393 fifo_merge = get_use_fifo_merge();
1394 dss_setup_fifos(fifo_merge);
1395 dss_apply_fifo_merge(fifo_merge);
1396
1397 dss_write_regs();
1398 dss_set_go_bits();
1399
1400 spin_unlock_irqrestore(&data_lock, flags);
1401
1402 /* wait for fifo configs to go in */
1403 wait_pending_extra_info_updates();
1404
1405 /* step 2: enable the overlay */
1406 spin_lock_irqsave(&data_lock, flags);
1270 1407
1271 op->enabling = false; 1408 op->enabling = false;
1272 dss_apply_ovl_enable(ovl, true); 1409 dss_apply_ovl_enable(ovl, true);
@@ -1276,6 +1413,9 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1276 1413
1277 spin_unlock_irqrestore(&data_lock, flags); 1414 spin_unlock_irqrestore(&data_lock, flags);
1278 1415
1416 /* wait for overlay to be enabled */
1417 wait_pending_extra_info_updates();
1418
1279 mutex_unlock(&apply_lock); 1419 mutex_unlock(&apply_lock);
1280 1420
1281 return 0; 1421 return 0;
@@ -1291,6 +1431,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1291{ 1431{
1292 struct ovl_priv_data *op = get_ovl_priv(ovl); 1432 struct ovl_priv_data *op = get_ovl_priv(ovl);
1293 unsigned long flags; 1433 unsigned long flags;
1434 bool fifo_merge;
1294 int r; 1435 int r;
1295 1436
1296 mutex_lock(&apply_lock); 1437 mutex_lock(&apply_lock);
@@ -1305,14 +1446,34 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1305 goto err; 1446 goto err;
1306 } 1447 }
1307 1448
1449 /* step 1: disable the overlay */
1308 spin_lock_irqsave(&data_lock, flags); 1450 spin_lock_irqsave(&data_lock, flags);
1309 1451
1310 dss_apply_ovl_enable(ovl, false); 1452 dss_apply_ovl_enable(ovl, false);
1453
1311 dss_write_regs(); 1454 dss_write_regs();
1312 dss_set_go_bits(); 1455 dss_set_go_bits();
1313 1456
1314 spin_unlock_irqrestore(&data_lock, flags); 1457 spin_unlock_irqrestore(&data_lock, flags);
1315 1458
1459 /* wait for the overlay to be disabled */
1460 wait_pending_extra_info_updates();
1461
1462 /* step 2: configure fifos/fifomerge */
1463 spin_lock_irqsave(&data_lock, flags);
1464
1465 fifo_merge = get_use_fifo_merge();
1466 dss_setup_fifos(fifo_merge);
1467 dss_apply_fifo_merge(fifo_merge);
1468
1469 dss_write_regs();
1470 dss_set_go_bits();
1471
1472 spin_unlock_irqrestore(&data_lock, flags);
1473
1474 /* wait for fifo config to go in */
1475 wait_pending_extra_info_updates();
1476
1316 mutex_unlock(&apply_lock); 1477 mutex_unlock(&apply_lock);
1317 1478
1318 return 0; 1479 return 0;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0aecb680f8a7..700bb563cfcd 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -908,7 +908,7 @@ static void dispc_configure_burst_sizes(void)
908 dispc_ovl_set_burst_size(i, burst_size); 908 dispc_ovl_set_burst_size(i, burst_size);
909} 909}
910 910
911u32 dispc_ovl_get_burst_size(enum omap_plane plane) 911static u32 dispc_ovl_get_burst_size(enum omap_plane plane)
912{ 912{
913 unsigned unit = dss_feat_get_burst_size_unit(); 913 unsigned unit = dss_feat_get_burst_size_unit();
914 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ 914 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
@@ -1017,7 +1017,7 @@ static void dispc_read_plane_fifo_sizes(void)
1017 } 1017 }
1018} 1018}
1019 1019
1020u32 dispc_ovl_get_fifo_size(enum omap_plane plane) 1020static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
1021{ 1021{
1022 return dispc.fifo_size[plane]; 1022 return dispc.fifo_size[plane];
1023} 1023}
@@ -1038,13 +1038,13 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
1038 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);
1039 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);
1040 1040
1041 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",
1042 plane, 1042 plane,
1043 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), 1043 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1044 lo_start, lo_end), 1044 lo_start, lo_end) * unit,
1045 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), 1045 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1046 hi_start, hi_end), 1046 hi_start, hi_end) * unit,
1047 low, high); 1047 low * unit, high * unit);
1048 1048
1049 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), 1049 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
1050 FLD_VAL(high, hi_start, hi_end) | 1050 FLD_VAL(high, hi_start, hi_end) |
@@ -1053,10 +1053,53 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
1053 1053
1054void dispc_enable_fifomerge(bool enable) 1054void dispc_enable_fifomerge(bool enable)
1055{ 1055{
1056 if (!dss_has_feature(FEAT_FIFO_MERGE)) {
1057 WARN_ON(enable);
1058 return;
1059 }
1060
1056 DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); 1061 DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled");
1057 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); 1062 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
1058} 1063}
1059 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
1060static void dispc_ovl_set_fir(enum omap_plane plane, 1103static void dispc_ovl_set_fir(enum omap_plane plane,
1061 int hinc, int vinc, 1104 int hinc, int vinc,
1062 enum omap_color_component color_comp) 1105 enum omap_color_component color_comp)
@@ -1650,6 +1693,7 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1650 u16 height, u16 out_width, u16 out_height) 1693 u16 height, u16 out_width, u16 out_height)
1651{ 1694{
1652 unsigned int hf, vf; 1695 unsigned int hf, vf;
1696 unsigned long pclk = dispc_mgr_pclk_rate(channel);
1653 1697
1654 /* 1698 /*
1655 * FIXME how to determine the 'A' factor 1699 * FIXME how to determine the 'A' factor
@@ -1672,13 +1716,16 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1672 1716
1673 if (cpu_is_omap24xx()) { 1717 if (cpu_is_omap24xx()) {
1674 if (vf > 1 && hf > 1) 1718 if (vf > 1 && hf > 1)
1675 return dispc_mgr_pclk_rate(channel) * 4; 1719 return pclk * 4;
1676 else 1720 else
1677 return dispc_mgr_pclk_rate(channel) * 2; 1721 return pclk * 2;
1678 } else if (cpu_is_omap34xx()) { 1722 } else if (cpu_is_omap34xx()) {
1679 return dispc_mgr_pclk_rate(channel) * vf * hf; 1723 return pclk * vf * hf;
1680 } else { 1724 } else {
1681 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;
1682 } 1729 }
1683} 1730}
1684 1731
@@ -3297,15 +3344,6 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3297 3344
3298 dispc.pdev = pdev; 3345 dispc.pdev = pdev;
3299 3346
3300 clk = clk_get(&pdev->dev, "fck");
3301 if (IS_ERR(clk)) {
3302 DSSERR("can't get fck\n");
3303 r = PTR_ERR(clk);
3304 goto err_get_clk;
3305 }
3306
3307 dispc.dss_clk = clk;
3308
3309 spin_lock_init(&dispc.irq_lock); 3347 spin_lock_init(&dispc.irq_lock);
3310 3348
3311#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 3349#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -3318,29 +3356,38 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3318 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0); 3356 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3319 if (!dispc_mem) { 3357 if (!dispc_mem) {
3320 DSSERR("can't get IORESOURCE_MEM DISPC\n"); 3358 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3321 r = -EINVAL; 3359 return -EINVAL;
3322 goto err_ioremap;
3323 } 3360 }
3324 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));
3325 if (!dispc.base) { 3364 if (!dispc.base) {
3326 DSSERR("can't ioremap DISPC\n"); 3365 DSSERR("can't ioremap DISPC\n");
3327 r = -ENOMEM; 3366 return -ENOMEM;
3328 goto err_ioremap;
3329 } 3367 }
3368
3330 dispc.irq = platform_get_irq(dispc.pdev, 0); 3369 dispc.irq = platform_get_irq(dispc.pdev, 0);
3331 if (dispc.irq < 0) { 3370 if (dispc.irq < 0) {
3332 DSSERR("platform_get_irq failed\n"); 3371 DSSERR("platform_get_irq failed\n");
3333 r = -ENODEV; 3372 return -ENODEV;
3334 goto err_irq;
3335 } 3373 }
3336 3374
3337 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED, 3375 r = devm_request_irq(&pdev->dev, dispc.irq, omap_dispc_irq_handler,
3338 "OMAP DISPC", dispc.pdev); 3376 IRQF_SHARED, "OMAP DISPC", dispc.pdev);
3339 if (r < 0) { 3377 if (r < 0) {
3340 DSSERR("request_irq failed\n"); 3378 DSSERR("request_irq failed\n");
3341 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;
3342 } 3387 }
3343 3388
3389 dispc.dss_clk = clk;
3390
3344 pm_runtime_enable(&pdev->dev); 3391 pm_runtime_enable(&pdev->dev);
3345 3392
3346 r = dispc_runtime_get(); 3393 r = dispc_runtime_get();
@@ -3361,12 +3408,7 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3361 3408
3362err_runtime_get: 3409err_runtime_get:
3363 pm_runtime_disable(&pdev->dev); 3410 pm_runtime_disable(&pdev->dev);
3364 free_irq(dispc.irq, dispc.pdev);
3365err_irq:
3366 iounmap(dispc.base);
3367err_ioremap:
3368 clk_put(dispc.dss_clk); 3411 clk_put(dispc.dss_clk);
3369err_get_clk:
3370 return r; 3412 return r;
3371} 3413}
3372 3414
@@ -3376,8 +3418,6 @@ static int omap_dispchw_remove(struct platform_device *pdev)
3376 3418
3377 clk_put(dispc.dss_clk); 3419 clk_put(dispc.dss_clk);
3378 3420
3379 free_irq(dispc.irq, dispc.pdev);
3380 iounmap(dispc.base);
3381 return 0; 3421 return 0;
3382} 3422}
3383 3423
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..0a926432ccdc 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;
@@ -337,15 +338,110 @@ static const struct dss_param_range omap4_dss_param_range[] = {
337 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 338 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
338}; 339};
339 340
341static const enum dss_feat_id omap2_dss_feat_list[] = {
342 FEAT_LCDENABLEPOL,
343 FEAT_LCDENABLESIGNAL,
344 FEAT_PCKFREEENABLE,
345 FEAT_FUNCGATED,
346 FEAT_ROWREPEATENABLE,
347 FEAT_RESIZECONF,
348};
349
350static const enum dss_feat_id omap3430_dss_feat_list[] = {
351 FEAT_LCDENABLEPOL,
352 FEAT_LCDENABLESIGNAL,
353 FEAT_PCKFREEENABLE,
354 FEAT_FUNCGATED,
355 FEAT_LINEBUFFERSPLIT,
356 FEAT_ROWREPEATENABLE,
357 FEAT_RESIZECONF,
358 FEAT_DSI_PLL_FREQSEL,
359 FEAT_DSI_REVERSE_TXCLKESC,
360 FEAT_VENC_REQUIRES_TV_DAC_CLK,
361 FEAT_CPR,
362 FEAT_PRELOAD,
363 FEAT_FIR_COEF_V,
364 FEAT_ALPHA_FIXED_ZORDER,
365 FEAT_FIFO_MERGE,
366 FEAT_OMAP3_DSI_FIFO_BUG,
367};
368
369static const enum dss_feat_id omap3630_dss_feat_list[] = {
370 FEAT_LCDENABLEPOL,
371 FEAT_LCDENABLESIGNAL,
372 FEAT_PCKFREEENABLE,
373 FEAT_FUNCGATED,
374 FEAT_LINEBUFFERSPLIT,
375 FEAT_ROWREPEATENABLE,
376 FEAT_RESIZECONF,
377 FEAT_DSI_PLL_PWR_BUG,
378 FEAT_DSI_PLL_FREQSEL,
379 FEAT_CPR,
380 FEAT_PRELOAD,
381 FEAT_FIR_COEF_V,
382 FEAT_ALPHA_FIXED_ZORDER,
383 FEAT_FIFO_MERGE,
384 FEAT_OMAP3_DSI_FIFO_BUG,
385};
386
387static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = {
388 FEAT_MGR_LCD2,
389 FEAT_CORE_CLK_DIV,
390 FEAT_LCD_CLK_SRC,
391 FEAT_DSI_DCS_CMD_CONFIG_VC,
392 FEAT_DSI_VC_OCP_WIDTH,
393 FEAT_DSI_GNQ,
394 FEAT_HANDLE_UV_SEPARATE,
395 FEAT_ATTR2,
396 FEAT_CPR,
397 FEAT_PRELOAD,
398 FEAT_FIR_COEF_V,
399 FEAT_ALPHA_FREE_ZORDER,
400 FEAT_FIFO_MERGE,
401};
402
403static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = {
404 FEAT_MGR_LCD2,
405 FEAT_CORE_CLK_DIV,
406 FEAT_LCD_CLK_SRC,
407 FEAT_DSI_DCS_CMD_CONFIG_VC,
408 FEAT_DSI_VC_OCP_WIDTH,
409 FEAT_DSI_GNQ,
410 FEAT_HDMI_CTS_SWMODE,
411 FEAT_HANDLE_UV_SEPARATE,
412 FEAT_ATTR2,
413 FEAT_CPR,
414 FEAT_PRELOAD,
415 FEAT_FIR_COEF_V,
416 FEAT_ALPHA_FREE_ZORDER,
417 FEAT_FIFO_MERGE,
418};
419
420static const enum dss_feat_id omap4_dss_feat_list[] = {
421 FEAT_MGR_LCD2,
422 FEAT_CORE_CLK_DIV,
423 FEAT_LCD_CLK_SRC,
424 FEAT_DSI_DCS_CMD_CONFIG_VC,
425 FEAT_DSI_VC_OCP_WIDTH,
426 FEAT_DSI_GNQ,
427 FEAT_HDMI_CTS_SWMODE,
428 FEAT_HDMI_AUDIO_USE_MCLK,
429 FEAT_HANDLE_UV_SEPARATE,
430 FEAT_ATTR2,
431 FEAT_CPR,
432 FEAT_PRELOAD,
433 FEAT_FIR_COEF_V,
434 FEAT_ALPHA_FREE_ZORDER,
435 FEAT_FIFO_MERGE,
436};
437
340/* OMAP2 DSS Features */ 438/* OMAP2 DSS Features */
341static const struct omap_dss_features omap2_dss_features = { 439static const struct omap_dss_features omap2_dss_features = {
342 .reg_fields = omap2_dss_reg_fields, 440 .reg_fields = omap2_dss_reg_fields,
343 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields), 441 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
344 442
345 .has_feature = 443 .features = omap2_dss_feat_list,
346 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | 444 .num_features = ARRAY_SIZE(omap2_dss_feat_list),
347 FEAT_PCKFREEENABLE | FEAT_FUNCGATED |
348 FEAT_ROWREPEATENABLE | FEAT_RESIZECONF,
349 445
350 .num_mgrs = 2, 446 .num_mgrs = 2,
351 .num_ovls = 3, 447 .num_ovls = 3,
@@ -363,14 +459,8 @@ static const struct omap_dss_features omap3430_dss_features = {
363 .reg_fields = omap3_dss_reg_fields, 459 .reg_fields = omap3_dss_reg_fields,
364 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 460 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
365 461
366 .has_feature = 462 .features = omap3430_dss_feat_list,
367 FEAT_LCDENABLEPOL | 463 .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 464
375 .num_mgrs = 2, 465 .num_mgrs = 2,
376 .num_ovls = 3, 466 .num_ovls = 3,
@@ -387,14 +477,8 @@ static const struct omap_dss_features omap3630_dss_features = {
387 .reg_fields = omap3_dss_reg_fields, 477 .reg_fields = omap3_dss_reg_fields,
388 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 478 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
389 479
390 .has_feature = 480 .features = omap3630_dss_feat_list,
391 FEAT_LCDENABLEPOL | 481 .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 482
399 .num_mgrs = 2, 483 .num_mgrs = 2,
400 .num_ovls = 3, 484 .num_ovls = 3,
@@ -413,13 +497,27 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
413 .reg_fields = omap4_dss_reg_fields, 497 .reg_fields = omap4_dss_reg_fields,
414 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 498 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
415 499
416 .has_feature = 500 .features = omap4430_es1_0_dss_feat_list,
417 FEAT_MGR_LCD2 | 501 .num_features = ARRAY_SIZE(omap4430_es1_0_dss_feat_list),
418 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 502
419 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | 503 .num_mgrs = 3,
420 FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | 504 .num_ovls = 4,
421 FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V | 505 .supported_displays = omap4_dss_supported_displays,
422 FEAT_ALPHA_FREE_ZORDER, 506 .supported_color_modes = omap4_dss_supported_color_modes,
507 .overlay_caps = omap4_dss_overlay_caps,
508 .clksrc_names = omap4_dss_clk_source_names,
509 .dss_params = omap4_dss_param_range,
510 .buffer_size_unit = 16,
511 .burst_size_unit = 16,
512};
513
514/* For OMAP4430 ES 2.0, 2.1 and 2.2 revisions */
515static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
516 .reg_fields = omap4_dss_reg_fields,
517 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
518
519 .features = omap4430_es2_0_1_2_dss_feat_list,
520 .num_features = ARRAY_SIZE(omap4430_es2_0_1_2_dss_feat_list),
423 521
424 .num_mgrs = 3, 522 .num_mgrs = 3,
425 .num_ovls = 4, 523 .num_ovls = 4,
@@ -437,13 +535,8 @@ static const struct omap_dss_features omap4_dss_features = {
437 .reg_fields = omap4_dss_reg_fields, 535 .reg_fields = omap4_dss_reg_fields,
438 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 536 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
439 537
440 .has_feature = 538 .features = omap4_dss_feat_list,
441 FEAT_MGR_LCD2 | 539 .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 540
448 .num_mgrs = 3, 541 .num_mgrs = 3,
449 .num_ovls = 4, 542 .num_ovls = 4,
@@ -547,7 +640,16 @@ u32 dss_feat_get_burst_size_unit(void)
547/* DSS has_feature check */ 640/* DSS has_feature check */
548bool dss_has_feature(enum dss_feat_id id) 641bool dss_has_feature(enum dss_feat_id id)
549{ 642{
550 return omap_current_dss_features->has_feature & id; 643 int i;
644 const enum dss_feat_id *features = omap_current_dss_features->features;
645 const int num_features = omap_current_dss_features->num_features;
646
647 for (i = 0; i < num_features; i++) {
648 if (features[i] == id)
649 return true;
650 }
651
652 return false;
551} 653}
552 654
553void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end) 655void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end)
@@ -569,6 +671,10 @@ void dss_features_init(void)
569 omap_current_dss_features = &omap3430_dss_features; 671 omap_current_dss_features = &omap3430_dss_features;
570 else if (omap_rev() == OMAP4430_REV_ES1_0) 672 else if (omap_rev() == OMAP4430_REV_ES1_0)
571 omap_current_dss_features = &omap4430_es1_0_dss_features; 673 omap_current_dss_features = &omap4430_es1_0_dss_features;
674 else if (omap_rev() == OMAP4430_REV_ES2_0 ||
675 omap_rev() == OMAP4430_REV_ES2_1 ||
676 omap_rev() == OMAP4430_REV_ES2_2)
677 omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
572 else if (cpu_is_omap44xx()) 678 else if (cpu_is_omap44xx())
573 omap_current_dss_features = &omap4_dss_features; 679 omap_current_dss_features = &omap4_dss_features;
574 else 680 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 d7aa3b056529..012ee49c78de 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}; 103};
128 104static const struct hdmi_config vesa_timings[] = {
129/* 105/* VESA From Here */
130 * This is a static mapping array which maps the timing values 106{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} },
131 * with corresponding CEA / VESA code 107{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} },
132 */ 108{ {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} },
133static const int code_index[OMAP_HDMI_TIMINGS_NB] = { 109{ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} },
134 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32, 110{ {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} },
135 /* <--15 CEA 17--> vesa*/ 111{ {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} },
136 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A, 112{ {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} },
137 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B 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} }
138}; 125};
139 126
140/*
141 * This is reverse static mapping which maps the CEA / VESA code
142 * to the corresponding timing values
143 */
144static const int code_cea[39] = {
145 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1,
146 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1,
147 7, 6, 6, -1, -1, -1, -1, -1, -1, 11,
148 11, 12, 14, -1, -1, 13, 13, 4, 4
149};
150
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;
@@ -188,88 +153,89 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
188 return 0; 153 return 0;
189} 154}
190 155
191static int get_timings_index(void) 156static const struct hdmi_config *hdmi_find_timing(
157 const struct hdmi_config *timings_arr,
158 int len)
192{ 159{
193 int code; 160 int i;
194 161
195 if (hdmi.mode == 0) 162 for (i = 0; i < len; i++) {
196 code = code_vesa[hdmi.code]; 163 if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code)
197 else 164 return &timings_arr[i];
198 code = code_cea[hdmi.code]; 165 }
166 return NULL;
167}
199 168
200 if (code == -1) { 169static const struct hdmi_config *hdmi_get_timings(void)
201 /* HDMI code 4 corresponds to 640 * 480 VGA */ 170{
202 hdmi.code = 4; 171 const struct hdmi_config *arr;
203 /* DVI mode 1 corresponds to HDMI 0 to DVI */ 172 int len;
204 hdmi.mode = HDMI_DVI; 173
174 if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) {
175 arr = vesa_timings;
176 len = ARRAY_SIZE(vesa_timings);
177 } else {
178 arr = cea_timings;
179 len = ARRAY_SIZE(cea_timings);
180 }
181
182 return hdmi_find_timing(arr, len);
183}
184
185static bool hdmi_timings_compare(struct omap_video_timings *timing1,
186 const struct hdmi_video_timings *timing2)
187{
188 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
205 189
206 code = code_vesa[hdmi.code]; 190 if ((timing2->pixel_clock == timing1->pixel_clock) &&
191 (timing2->x_res == timing1->x_res) &&
192 (timing2->y_res == timing1->y_res)) {
193
194 timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
195 timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
196 timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
197 timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
198
199 DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
200 "timing2_hsync = %d timing2_vsync = %d\n",
201 timing1_hsync, timing1_vsync,
202 timing2_hsync, timing2_vsync);
203
204 if ((timing1_hsync == timing2_hsync) &&
205 (timing1_vsync == timing2_vsync)) {
206 return true;
207 }
207 } 208 }
208 return code; 209 return false;
209} 210}
210 211
211static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) 212static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
212{ 213{
213 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0; 214 int i;
214 int timing_vsync = 0, timing_hsync = 0;
215 struct hdmi_video_timings temp;
216 struct hdmi_cm cm = {-1}; 215 struct hdmi_cm cm = {-1};
217 DSSDBG("hdmi_get_code\n"); 216 DSSDBG("hdmi_get_code\n");
218 217
219 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) { 218 for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
220 temp = cea_vesa_timings[i].timings; 219 if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
221 if ((temp.pixel_clock == timing->pixel_clock) && 220 cm = cea_timings[i].cm;
222 (temp.x_res == timing->x_res) && 221 goto end;
223 (temp.y_res == timing->y_res)) { 222 }
224 223 }
225 temp_hsync = temp.hfp + temp.hsw + temp.hbp; 224 for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
226 timing_hsync = timing->hfp + timing->hsw + timing->hbp; 225 if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
227 temp_vsync = temp.vfp + temp.vsw + temp.vbp; 226 cm = vesa_timings[i].cm;
228 timing_vsync = timing->vfp + timing->vsw + timing->vbp; 227 goto end;
229
230 DSSDBG("temp_hsync = %d , temp_vsync = %d"
231 "timing_hsync = %d, timing_vsync = %d\n",
232 temp_hsync, temp_hsync,
233 timing_hsync, timing_vsync);
234
235 if ((temp_hsync == timing_hsync) &&
236 (temp_vsync == timing_vsync)) {
237 code = i;
238 cm.code = code_index[i];
239 if (code < 14)
240 cm.mode = HDMI_HDMI;
241 else
242 cm.mode = HDMI_DVI;
243 DSSDBG("Hdmi_code = %d mode = %d\n",
244 cm.code, cm.mode);
245 break;
246 }
247 } 228 }
248 } 229 }
249 230
250 return cm; 231end: return cm;
251}
252 232
253static void update_hdmi_timings(struct hdmi_config *cfg,
254 struct omap_video_timings *timings, int code)
255{
256 cfg->timings.timings.x_res = timings->x_res;
257 cfg->timings.timings.y_res = timings->y_res;
258 cfg->timings.timings.hbp = timings->hbp;
259 cfg->timings.timings.hfp = timings->hfp;
260 cfg->timings.timings.hsw = timings->hsw;
261 cfg->timings.timings.vbp = timings->vbp;
262 cfg->timings.timings.vfp = timings->vfp;
263 cfg->timings.timings.vsw = timings->vsw;
264 cfg->timings.timings.pixel_clock = timings->pixel_clock;
265 cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
266 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
267} 233}
268 234
269unsigned long hdmi_get_pixel_clock(void) 235unsigned long hdmi_get_pixel_clock(void)
270{ 236{
271 /* HDMI Pixel Clock in Mhz */ 237 /* HDMI Pixel Clock in Mhz */
272 return hdmi.ip_data.cfg.timings.timings.pixel_clock * 1000; 238 return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
273} 239}
274 240
275static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, 241static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
@@ -325,7 +291,8 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
325 291
326static int hdmi_power_on(struct omap_dss_device *dssdev) 292static int hdmi_power_on(struct omap_dss_device *dssdev)
327{ 293{
328 int r, code = 0; 294 int r;
295 const struct hdmi_config *timing;
329 struct omap_video_timings *p; 296 struct omap_video_timings *p;
330 unsigned long phy; 297 unsigned long phy;
331 298
@@ -341,9 +308,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
341 dssdev->panel.timings.x_res, 308 dssdev->panel.timings.x_res,
342 dssdev->panel.timings.y_res); 309 dssdev->panel.timings.y_res);
343 310
344 code = get_timings_index(); 311 timing = hdmi_get_timings();
345 update_hdmi_timings(&hdmi.ip_data.cfg, p, code); 312 if (timing == NULL) {
346 313 /* HDMI code 4 corresponds to 640 * 480 VGA */
314 hdmi.ip_data.cfg.cm.code = 4;
315 /* DVI mode 1 corresponds to HDMI 0 to DVI */
316 hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
317 hdmi.ip_data.cfg = vesa_timings[0];
318 } else {
319 hdmi.ip_data.cfg = *timing;
320 }
347 phy = p->pixel_clock; 321 phy = p->pixel_clock;
348 322
349 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); 323 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
@@ -363,8 +337,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
363 goto err; 337 goto err;
364 } 338 }
365 339
366 hdmi.ip_data.cfg.cm.mode = hdmi.mode;
367 hdmi.ip_data.cfg.cm.code = hdmi.code;
368 hdmi.ip_data.ops->video_configure(&hdmi.ip_data); 340 hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
369 341
370 /* Make selection of HDMI in DSS */ 342 /* Make selection of HDMI in DSS */
@@ -431,8 +403,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
431 struct hdmi_cm cm; 403 struct hdmi_cm cm;
432 404
433 cm = hdmi_get_code(&dssdev->panel.timings); 405 cm = hdmi_get_code(&dssdev->panel.timings);
434 hdmi.code = cm.code; 406 hdmi.ip_data.cfg.cm.code = cm.code;
435 hdmi.mode = cm.mode; 407 hdmi.ip_data.cfg.cm.mode = cm.mode;
436 408
437 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 409 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
438 int r; 410 int r;
@@ -695,13 +667,15 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
695 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { 667 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
696 core_cfg.aud_par_busclk = 0; 668 core_cfg.aud_par_busclk = 0;
697 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW; 669 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
698 core_cfg.use_mclk = false; 670 core_cfg.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK);
699 } else { 671 } else {
700 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8); 672 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8);
701 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW; 673 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
702 core_cfg.use_mclk = true; 674 core_cfg.use_mclk = true;
703 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
704 } 675 }
676
677 if (core_cfg.use_mclk)
678 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
705 core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH; 679 core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH;
706 core_cfg.en_spdif = false; 680 core_cfg.en_spdif = false;
707 /* Use sample frequency from channel status word */ 681 /* Use sample frequency from channel status word */
@@ -734,7 +708,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
734static int hdmi_audio_startup(struct snd_pcm_substream *substream, 708static int hdmi_audio_startup(struct snd_pcm_substream *substream,
735 struct snd_soc_dai *dai) 709 struct snd_soc_dai *dai)
736{ 710{
737 if (!hdmi.mode) { 711 if (!hdmi.ip_data.cfg.cm.mode) {
738 pr_err("Current video settings do not support audio.\n"); 712 pr_err("Current video settings do not support audio.\n");
739 return -EIO; 713 return -EIO;
740 } 714 }
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 2d72334ca3da..bb784d2329b6 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -594,12 +594,12 @@ static void hdmi_core_video_config(struct hdmi_ip_data *ip_data,
594 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); 594 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
595} 595}
596 596
597static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data, 597static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data)
598 struct hdmi_core_infoframe_avi info_avi)
599{ 598{
600 u32 val; 599 u32 val;
601 char sum = 0, checksum = 0; 600 char sum = 0, checksum = 0;
602 void __iomem *av_base = hdmi_av_base(ip_data); 601 void __iomem *av_base = hdmi_av_base(ip_data);
602 struct hdmi_core_infoframe_avi info_avi = ip_data->avi_cfg;
603 603
604 sum += 0x82 + 0x002 + 0x00D; 604 sum += 0x82 + 0x002 + 0x00D;
605 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082); 605 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082);
@@ -689,8 +689,7 @@ static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data,
689} 689}
690 690
691static void hdmi_wp_init(struct omap_video_timings *timings, 691static void hdmi_wp_init(struct omap_video_timings *timings,
692 struct hdmi_video_format *video_fmt, 692 struct hdmi_video_format *video_fmt)
693 struct hdmi_video_interface *video_int)
694{ 693{
695 pr_debug("Enter hdmi_wp_init\n"); 694 pr_debug("Enter hdmi_wp_init\n");
696 695
@@ -705,12 +704,6 @@ static void hdmi_wp_init(struct omap_video_timings *timings,
705 video_fmt->y_res = 0; 704 video_fmt->y_res = 0;
706 video_fmt->x_res = 0; 705 video_fmt->x_res = 0;
707 706
708 video_int->vsp = 0;
709 video_int->hsp = 0;
710
711 video_int->interlacing = 0;
712 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
713
714} 707}
715 708
716void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start) 709void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start)
@@ -723,15 +716,15 @@ static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
723{ 716{
724 pr_debug("Enter hdmi_wp_video_init_format\n"); 717 pr_debug("Enter hdmi_wp_video_init_format\n");
725 718
726 video_fmt->y_res = param->timings.timings.y_res; 719 video_fmt->y_res = param->timings.y_res;
727 video_fmt->x_res = param->timings.timings.x_res; 720 video_fmt->x_res = param->timings.x_res;
728 721
729 timings->hbp = param->timings.timings.hbp; 722 timings->hbp = param->timings.hbp;
730 timings->hfp = param->timings.timings.hfp; 723 timings->hfp = param->timings.hfp;
731 timings->hsw = param->timings.timings.hsw; 724 timings->hsw = param->timings.hsw;
732 timings->vbp = param->timings.timings.vbp; 725 timings->vbp = param->timings.vbp;
733 timings->vfp = param->timings.timings.vfp; 726 timings->vfp = param->timings.vfp;
734 timings->vsw = param->timings.timings.vsw; 727 timings->vsw = param->timings.vsw;
735} 728}
736 729
737static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, 730static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
@@ -747,17 +740,16 @@ static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
747 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l); 740 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l);
748} 741}
749 742
750static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data, 743static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data)
751 struct hdmi_video_interface *video_int)
752{ 744{
753 u32 r; 745 u32 r;
754 pr_debug("Enter hdmi_wp_video_config_interface\n"); 746 pr_debug("Enter hdmi_wp_video_config_interface\n");
755 747
756 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); 748 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG);
757 r = FLD_MOD(r, video_int->vsp, 7, 7); 749 r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7);
758 r = FLD_MOD(r, video_int->hsp, 6, 6); 750 r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6);
759 r = FLD_MOD(r, video_int->interlacing, 3, 3); 751 r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3);
760 r = FLD_MOD(r, video_int->tm, 1, 0); 752 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */
761 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); 753 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r);
762} 754}
763 755
@@ -785,15 +777,13 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
785 /* HDMI */ 777 /* HDMI */
786 struct omap_video_timings video_timing; 778 struct omap_video_timings video_timing;
787 struct hdmi_video_format video_format; 779 struct hdmi_video_format video_format;
788 struct hdmi_video_interface video_interface;
789 /* HDMI core */ 780 /* HDMI core */
790 struct hdmi_core_infoframe_avi avi_cfg; 781 struct hdmi_core_infoframe_avi avi_cfg = ip_data->avi_cfg;
791 struct hdmi_core_video_config v_core_cfg; 782 struct hdmi_core_video_config v_core_cfg;
792 struct hdmi_core_packet_enable_repeat repeat_cfg; 783 struct hdmi_core_packet_enable_repeat repeat_cfg;
793 struct hdmi_config *cfg = &ip_data->cfg; 784 struct hdmi_config *cfg = &ip_data->cfg;
794 785
795 hdmi_wp_init(&video_timing, &video_format, 786 hdmi_wp_init(&video_timing, &video_format);
796 &video_interface);
797 787
798 hdmi_core_init(&v_core_cfg, 788 hdmi_core_init(&v_core_cfg,
799 &avi_cfg, 789 &avi_cfg,
@@ -808,12 +798,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
808 798
809 hdmi_wp_video_config_format(ip_data, &video_format); 799 hdmi_wp_video_config_format(ip_data, &video_format);
810 800
811 video_interface.vsp = cfg->timings.vsync_pol; 801 hdmi_wp_video_config_interface(ip_data);
812 video_interface.hsp = cfg->timings.hsync_pol;
813 video_interface.interlacing = cfg->interlace;
814 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
815
816 hdmi_wp_video_config_interface(ip_data, &video_interface);
817 802
818 /* 803 /*
819 * configure core video part 804 * configure core video part
@@ -855,7 +840,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
855 avi_cfg.db10_11_pixel_eofleft = 0; 840 avi_cfg.db10_11_pixel_eofleft = 0;
856 avi_cfg.db12_13_pixel_sofright = 0; 841 avi_cfg.db12_13_pixel_sofright = 0;
857 842
858 hdmi_core_aux_infoframe_avi_config(ip_data, avi_cfg); 843 hdmi_core_aux_infoframe_avi_config(ip_data);
859 844
860 /* enable/repeat the infoframe */ 845 /* enable/repeat the infoframe */
861 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; 846 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
@@ -1083,13 +1068,9 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
1083 u32 r; 1068 u32 r;
1084 void __iomem *av_base = hdmi_av_base(ip_data); 1069 void __iomem *av_base = hdmi_av_base(ip_data);
1085 1070
1086 /* audio clock recovery parameters */ 1071 /*
1087 r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL); 1072 * Parameters for generation of Audio Clock Recovery packets
1088 r = FLD_MOD(r, cfg->use_mclk, 2, 2); 1073 */
1089 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1090 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1091 hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r);
1092
1093 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0); 1074 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
1094 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0); 1075 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
1095 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0); 1076 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
@@ -1101,14 +1082,6 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
1101 REG_FLD_MOD(av_base, 1082 REG_FLD_MOD(av_base,
1102 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0); 1083 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
1103 } else { 1084 } else {
1104 /*
1105 * HDMI IP uses this configuration to divide the MCLK to
1106 * update CTS value.
1107 */
1108 REG_FLD_MOD(av_base,
1109 HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1110
1111 /* Configure clock for audio packets */
1112 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1, 1085 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
1113 cfg->aud_par_busclk, 7, 0); 1086 cfg->aud_par_busclk, 7, 0);
1114 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2, 1087 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
@@ -1117,6 +1090,25 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
1117 (cfg->aud_par_busclk >> 16), 7, 0); 1090 (cfg->aud_par_busclk >> 16), 7, 0);
1118 } 1091 }
1119 1092
1093 /* Set ACR clock divisor */
1094 REG_FLD_MOD(av_base,
1095 HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1096
1097 r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL);
1098 /*
1099 * Use TMDS clock for ACR packets. For devices that use
1100 * the MCLK, this is the first part of the MCLK initialization.
1101 */
1102 r = FLD_MOD(r, 0, 2, 2);
1103
1104 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1105 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1106 hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r);
1107
1108 /* For devices using MCLK, this completes its initialization. */
1109 if (cfg->use_mclk)
1110 REG_FLD_MOD(av_base, HDMI_CORE_AV_ACR_CTRL, 1, 2, 2);
1111
1120 /* Override of SPDIF sample frequency with value in I2S_CHST4 */ 1112 /* Override of SPDIF sample frequency with value in I2S_CHST4 */
1121 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, 1113 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL,
1122 cfg->fs_override, 1, 1); 1114 cfg->fs_override, 1, 1);
@@ -1212,7 +1204,7 @@ int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
1212{ 1204{
1213 u32 r; 1205 u32 r;
1214 u32 deep_color = 0; 1206 u32 deep_color = 0;
1215 u32 pclk = ip_data->cfg.timings.timings.pixel_clock; 1207 u32 pclk = ip_data->cfg.timings.pixel_clock;
1216 1208
1217 if (n == NULL || cts == NULL) 1209 if (n == NULL || cts == NULL)
1218 return -EINVAL; 1210 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