diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/omap2/displays/panel-generic-dpi.c | 23 | ||||
-rw-r--r-- | drivers/video/omap2/displays/panel-tpo-td043mtea1.c | 153 | ||||
-rw-r--r-- | drivers/video/omap2/dss/apply.c | 221 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 112 | ||||
-rw-r--r-- | drivers/video/omap2/dss/display.c | 10 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 65 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.c | 17 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 10 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 178 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.h | 54 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 262 | ||||
-rw-r--r-- | drivers/video/omap2/dss/rfbi.c | 36 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi.h | 56 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 94 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h | 47 | ||||
-rw-r--r-- | drivers/video/omap2/dss/venc.c | 32 |
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 | ||
368 | struct panel_drv_data { | 391 | struct 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 | ||
49 | static const u16 tpo_td043_def_gamma[12] = { | 49 | static 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 | ||
53 | struct tpo_td043_device { | 53 | struct 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 | ||
62 | static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) | 66 | static 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 | ||
268 | static int tpo_td043_power_on(struct omap_dss_device *dssdev) | 272 | static 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; |
305 | err1: | ||
306 | omapdss_dpi_display_disable(dssdev); | ||
307 | err0: | ||
308 | return r; | ||
309 | } | 298 | } |
310 | 299 | ||
311 | static void tpo_td043_power_off(struct omap_dss_device *dssdev) | 300 | static 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 | |||
323 | static 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; | ||
354 | err1: | ||
355 | omapdss_dpi_display_disable(dssdev); | ||
356 | err0: | ||
357 | return r; | ||
358 | } | ||
359 | |||
360 | static 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 | ||
338 | static int tpo_td043_enable(struct omap_dss_device *dssdev) | 376 | static 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 | ||
353 | static void tpo_td043_disable(struct omap_dss_device *dssdev) | 383 | static 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 | ||
362 | static int tpo_td043_suspend(struct omap_dss_device *dssdev) | 392 | static 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 | ||
369 | static int tpo_td043_resume(struct omap_dss_device *dssdev) | 403 | static 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 | ||
382 | static int tpo_td043_probe(struct omap_dss_device *dssdev) | 410 | static 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 | ||
542 | static 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 | |||
555 | static 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 | |||
573 | static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm, | ||
574 | tpo_td043_spi_suspend, tpo_td043_spi_resume); | ||
575 | |||
512 | static struct spi_driver tpo_td043_spi_driver = { | 576 | static 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 | ||
591 | static 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 | |||
588 | static void dss_write_regs(void) | 618 | static 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 | ||
862 | static void dss_ovl_setup_fifo(struct omap_overlay *ovl) | 896 | static 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 | |||
905 | static 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 | ||
900 | static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) | 923 | static 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 | |||
938 | static 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 | ||
914 | static void dss_setup_fifos(void) | 950 | static 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 | |||
973 | static 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 | |||
1002 | static 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 | ||
926 | int dss_mgr_enable(struct omap_overlay_manager *mgr) | 1025 | int 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(); | ||
993 | out: | 1114 | out: |
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 | ||
911 | u32 dispc_ovl_get_burst_size(enum omap_plane plane) | 911 | static 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 | ||
1020 | u32 dispc_ovl_get_fifo_size(enum omap_plane plane) | 1020 | static 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 | ||
1054 | void dispc_enable_fifomerge(bool enable) | 1054 | void 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 | ||
1065 | void 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 | |||
1060 | static void dispc_ovl_set_fir(enum omap_plane plane, | 1103 | static 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 | ||
3362 | err_runtime_get: | 3409 | err_runtime_get: |
3363 | pm_runtime_disable(&pdev->dev); | 3410 | pm_runtime_disable(&pdev->dev); |
3364 | free_irq(dispc.irq, dispc.pdev); | ||
3365 | err_irq: | ||
3366 | iounmap(dispc.base); | ||
3367 | err_ioremap: | ||
3368 | clk_put(dispc.dss_clk); | 3411 | clk_put(dispc.dss_clk); |
3369 | err_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 | } |
280 | EXPORT_SYMBOL(omapdss_default_get_resolution); | 280 | EXPORT_SYMBOL(omapdss_default_get_resolution); |
281 | 281 | ||
282 | void 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 | |||
292 | int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) | 282 | int 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 | } |
4525 | EXPORT_SYMBOL(omapdss_dsi_enable_te); | 4525 | EXPORT_SYMBOL(omapdss_dsi_enable_te); |
4526 | 4526 | ||
4527 | void 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 | |||
4535 | int dsi_init_display(struct omap_dss_device *dssdev) | 4527 | int 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 | ||
4794 | err_get_dsi: | 4784 | err_runtime_get: |
4795 | free_irq(dsi->irq, dsi->pdev); | ||
4796 | err_get_irq: | ||
4797 | iounmap(dsi->base); | ||
4798 | err_ioremap: | ||
4799 | pm_runtime_disable(&dsidev->dev); | 4785 | pm_runtime_disable(&dsidev->dev); |
4800 | err_get_clk: | 4786 | dsi_put_clocks(dsidev); |
4801 | kfree(dsi); | ||
4802 | err_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: | |||
808 | err_runtime_get: | 808 | err_runtime_get: |
809 | pm_runtime_disable(&pdev->dev); | 809 | pm_runtime_disable(&pdev->dev); |
810 | dss_put_clocks(); | 810 | dss_put_clocks(); |
811 | err_clocks: | ||
812 | iounmap(dss.base); | ||
813 | err_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); |
203 | bool dss_use_replication(struct omap_dss_device *dssdev, | 203 | bool dss_use_replication(struct omap_dss_device *dssdev, |
204 | enum omap_color_mode mode); | 204 | enum omap_color_mode mode); |
205 | void 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 */ |
210 | int dss_init_overlay_managers(struct platform_device *pdev); | 207 | int 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, | |||
313 | int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, | 310 | int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, |
314 | bool enable_hsdiv); | 311 | bool enable_hsdiv); |
315 | void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); | 312 | void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); |
316 | void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, | ||
317 | u32 fifo_size, u32 burst_size, | ||
318 | u32 *fifo_low, u32 *fifo_high); | ||
319 | void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); | 313 | void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); |
320 | void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); | 314 | void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); |
321 | struct platform_device *dsi_get_dsidev_from_id(int module); | 315 | struct 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 | ||
431 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); | 425 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); |
432 | u32 dispc_ovl_get_fifo_size(enum omap_plane plane); | 426 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, |
433 | u32 dispc_ovl_get_burst_size(enum omap_plane plane); | 427 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); |
434 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 428 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, |
435 | bool ilace, bool replication); | 429 | bool ilace, bool replication); |
436 | int dispc_ovl_enable(enum omap_plane plane, bool enable); | 430 | int 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 | ||
341 | static 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 | |||
350 | static 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 | |||
369 | static 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 | |||
387 | static 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 | |||
403 | static 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 | |||
420 | static 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 */ |
341 | static const struct omap_dss_features omap2_dss_features = { | 439 | static 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 */ | ||
515 | static 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 */ |
548 | bool dss_has_feature(enum dss_feat_id id) | 641 | bool 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 | ||
553 | void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end) | 655 | void 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 */ |
33 | enum dss_feat_id { | 33 | enum 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 | ||
91 | static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { | 87 | static 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 | 104 | static 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} }, |
133 | static 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 | */ | ||
144 | static 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 | |||
151 | static 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 | |||
162 | static int hdmi_runtime_get(void) | 127 | static 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 | ||
191 | static int get_timings_index(void) | 156 | static 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) { | 169 | static 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 | |||
185 | static 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 | ||
211 | static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) | 212 | static 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; | 231 | end: return cm; |
251 | } | ||
252 | 232 | ||
253 | static 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 | ||
269 | unsigned long hdmi_get_pixel_clock(void) | 235 | unsigned 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 | ||
275 | static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, | 241 | static 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 | ||
326 | static int hdmi_power_on(struct omap_dss_device *dssdev) | 292 | static 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, | |||
734 | static int hdmi_audio_startup(struct snd_pcm_substream *substream, | 708 | static 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 | ||
962 | err_get_ick: | 961 | err_runtime_get: |
963 | rfbi_runtime_put(); | ||
964 | err_get_rfbi: | ||
965 | pm_runtime_disable(&pdev->dev); | 962 | pm_runtime_disable(&pdev->dev); |
966 | iounmap(rfbi.base); | ||
967 | err_ioremap: | ||
968 | return r; | 963 | return r; |
969 | } | 964 | } |
970 | 965 | ||
971 | static int omap_rfbihw_remove(struct platform_device *pdev) | 966 | static 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 */ | ||
45 | struct hdmi_video_timings { | 46 | struct 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; |
59 | struct hdmi_timings { | ||
60 | struct hdmi_video_timings timings; | ||
61 | int vsync_pol; | ||
62 | int hsync_pol; | ||
63 | }; | 60 | }; |
64 | 61 | ||
65 | struct hdmi_cm { | 62 | struct hdmi_cm { |
@@ -68,8 +65,7 @@ struct hdmi_cm { | |||
68 | }; | 65 | }; |
69 | 66 | ||
70 | struct hdmi_config { | 67 | struct 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 | */ | ||
120 | struct 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 | |||
120 | struct hdmi_ip_data { | 157 | struct 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 | ||
597 | static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data, | 597 | static 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 | ||
691 | static void hdmi_wp_init(struct omap_video_timings *timings, | 691 | static 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 | ||
716 | void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start) | 709 | void 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 | ||
737 | static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, | 730 | static 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 | ||
750 | static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data, | 743 | static 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 | */ |
453 | struct 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 | */ | ||
493 | struct hdmi_core_infoframe_audio { | 453 | struct 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 | ||
520 | struct hdmi_video_interface { | ||
521 | int vsp; /* Vsync polarity */ | ||
522 | int hsp; /* Hsync polarity */ | ||
523 | int interlacing; | ||
524 | int tm; /* Timing mode */ | ||
525 | }; | ||
526 | |||
527 | struct hdmi_audio_format { | 480 | struct 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 | ||
820 | err_get_venc: | 829 | err_reg_panel_driver: |
830 | err_runtime_get: | ||
821 | pm_runtime_disable(&pdev->dev); | 831 | pm_runtime_disable(&pdev->dev); |
822 | venc_put_clocks(); | 832 | venc_put_clocks(); |
823 | err_get_clk: | ||
824 | iounmap(venc.base); | ||
825 | err_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 | ||