diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 19:57:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 19:57:51 -0400 |
commit | 804ce9866d56130032c9c8afc90a1297b7deed56 (patch) | |
tree | 6dd70984f411d2a3624d3f8db7facc3d6396b9ad /drivers/video/omap2 | |
parent | f5e7e844a571124ffc117d4696787d6afc4fc5ae (diff) | |
parent | c895305e806b4346006d3cfba2b432d52268ecd3 (diff) |
Merge tag 'fbdev-updates-for-3.5' of git://github.com/schandinat/linux-2.6
Pull fbdev updates from Florian Tobias Schandinat:
- driver for AUO-K1900 and AUO-K1901 epaper controller
- large updates for OMAP (e.g. decouple HDMI audio and video)
- some updates for Exynos and SH Mobile
- various other small fixes and cleanups
* tag 'fbdev-updates-for-3.5' of git://github.com/schandinat/linux-2.6: (130 commits)
video: bfin_adv7393fb: Fix cleanup code
video: exynos_dp: reduce delay time when configuring video setting
video: exynos_dp: move sw reset prioir to enabling sw defined function
video: exynos_dp: use devm_ functions
fb: handle NULL pointers in framebuffer release
OMAPDSS: HDMI: OMAP4: Update IRQ flags for the HPD IRQ request
OMAPDSS: Apply VENC timings even if panel is disabled
OMAPDSS: VENC/DISPC: Delay dividing Y resolution for managers connected to VENC
OMAPDSS: DISPC: Support rotation through TILER
OMAPDSS: VRFB: remove compiler warnings when CONFIG_BUG=n
OMAPFB: remove compiler warnings when CONFIG_BUG=n
OMAPDSS: remove compiler warnings when CONFIG_BUG=n
OMAPDSS: DISPC: fix usage of dispc_ovl_set_accu_uv
OMAPDSS: use DSI_FIFO_BUG workaround only for manual update displays
OMAPDSS: DSI: Support command mode interleaving during video mode blanking periods
OMAPDSS: DISPC: Update Accumulator configuration for chroma plane
drivers/video: fsl-diu-fb: don't initialize the THRESHOLDS registers
video: exynos mipi dsi: support reverse panel type
video: exynos mipi dsi: Properly interpret the interrupt source flags
video: exynos mipi dsi: Avoid races in probe()
...
Diffstat (limited to 'drivers/video/omap2')
32 files changed, 2493 insertions, 1516 deletions
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c index 74e7cf078505..ad741c3d1ae1 100644 --- a/drivers/video/omap2/displays/panel-acx565akm.c +++ b/drivers/video/omap2/displays/panel-acx565akm.c | |||
@@ -739,12 +739,6 @@ static void acx_panel_set_timings(struct omap_dss_device *dssdev, | |||
739 | } | 739 | } |
740 | } | 740 | } |
741 | 741 | ||
742 | static void acx_panel_get_timings(struct omap_dss_device *dssdev, | ||
743 | struct omap_video_timings *timings) | ||
744 | { | ||
745 | *timings = dssdev->panel.timings; | ||
746 | } | ||
747 | |||
748 | static int acx_panel_check_timings(struct omap_dss_device *dssdev, | 742 | static int acx_panel_check_timings(struct omap_dss_device *dssdev, |
749 | struct omap_video_timings *timings) | 743 | struct omap_video_timings *timings) |
750 | { | 744 | { |
@@ -762,7 +756,6 @@ static struct omap_dss_driver acx_panel_driver = { | |||
762 | .resume = acx_panel_resume, | 756 | .resume = acx_panel_resume, |
763 | 757 | ||
764 | .set_timings = acx_panel_set_timings, | 758 | .set_timings = acx_panel_set_timings, |
765 | .get_timings = acx_panel_get_timings, | ||
766 | .check_timings = acx_panel_check_timings, | 759 | .check_timings = acx_panel_check_timings, |
767 | 760 | ||
768 | .get_recommended_bpp = acx_get_recommended_bpp, | 761 | .get_recommended_bpp = acx_get_recommended_bpp, |
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c index 30fe4dfeb227..e42f9dc22123 100644 --- a/drivers/video/omap2/displays/panel-generic-dpi.c +++ b/drivers/video/omap2/displays/panel-generic-dpi.c | |||
@@ -386,6 +386,106 @@ static struct panel_config generic_dpi_panels[] = { | |||
386 | 386 | ||
387 | .name = "innolux_at080tn52", | 387 | .name = "innolux_at080tn52", |
388 | }, | 388 | }, |
389 | |||
390 | /* Mitsubishi AA084SB01 */ | ||
391 | { | ||
392 | { | ||
393 | .x_res = 800, | ||
394 | .y_res = 600, | ||
395 | .pixel_clock = 40000, | ||
396 | |||
397 | .hsw = 1, | ||
398 | .hfp = 254, | ||
399 | .hbp = 1, | ||
400 | |||
401 | .vsw = 1, | ||
402 | .vfp = 26, | ||
403 | .vbp = 1, | ||
404 | }, | ||
405 | .config = OMAP_DSS_LCD_TFT, | ||
406 | .name = "mitsubishi_aa084sb01", | ||
407 | }, | ||
408 | /* EDT ET0500G0DH6 */ | ||
409 | { | ||
410 | { | ||
411 | .x_res = 800, | ||
412 | .y_res = 480, | ||
413 | .pixel_clock = 33260, | ||
414 | |||
415 | .hsw = 128, | ||
416 | .hfp = 216, | ||
417 | .hbp = 40, | ||
418 | |||
419 | .vsw = 2, | ||
420 | .vfp = 35, | ||
421 | .vbp = 10, | ||
422 | }, | ||
423 | .config = OMAP_DSS_LCD_TFT, | ||
424 | .name = "edt_et0500g0dh6", | ||
425 | }, | ||
426 | |||
427 | /* Prime-View PD050VL1 */ | ||
428 | { | ||
429 | { | ||
430 | .x_res = 640, | ||
431 | .y_res = 480, | ||
432 | |||
433 | .pixel_clock = 25000, | ||
434 | |||
435 | .hsw = 96, | ||
436 | .hfp = 18, | ||
437 | .hbp = 46, | ||
438 | |||
439 | .vsw = 2, | ||
440 | .vfp = 10, | ||
441 | .vbp = 33, | ||
442 | }, | ||
443 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
444 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, | ||
445 | .name = "primeview_pd050vl1", | ||
446 | }, | ||
447 | |||
448 | /* Prime-View PM070WL4 */ | ||
449 | { | ||
450 | { | ||
451 | .x_res = 800, | ||
452 | .y_res = 480, | ||
453 | |||
454 | .pixel_clock = 32000, | ||
455 | |||
456 | .hsw = 128, | ||
457 | .hfp = 42, | ||
458 | .hbp = 86, | ||
459 | |||
460 | .vsw = 2, | ||
461 | .vfp = 10, | ||
462 | .vbp = 33, | ||
463 | }, | ||
464 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
465 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, | ||
466 | .name = "primeview_pm070wl4", | ||
467 | }, | ||
468 | |||
469 | /* Prime-View PD104SLF */ | ||
470 | { | ||
471 | { | ||
472 | .x_res = 800, | ||
473 | .y_res = 600, | ||
474 | |||
475 | .pixel_clock = 40000, | ||
476 | |||
477 | .hsw = 128, | ||
478 | .hfp = 42, | ||
479 | .hbp = 86, | ||
480 | |||
481 | .vsw = 4, | ||
482 | .vfp = 1, | ||
483 | .vbp = 23, | ||
484 | }, | ||
485 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
486 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, | ||
487 | .name = "primeview_pd104slf", | ||
488 | }, | ||
389 | }; | 489 | }; |
390 | 490 | ||
391 | struct panel_drv_data { | 491 | struct panel_drv_data { |
@@ -549,12 +649,6 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev, | |||
549 | dpi_set_timings(dssdev, timings); | 649 | dpi_set_timings(dssdev, timings); |
550 | } | 650 | } |
551 | 651 | ||
552 | static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev, | ||
553 | struct omap_video_timings *timings) | ||
554 | { | ||
555 | *timings = dssdev->panel.timings; | ||
556 | } | ||
557 | |||
558 | static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, | 652 | static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, |
559 | struct omap_video_timings *timings) | 653 | struct omap_video_timings *timings) |
560 | { | 654 | { |
@@ -571,7 +665,6 @@ static struct omap_dss_driver dpi_driver = { | |||
571 | .resume = generic_dpi_panel_resume, | 665 | .resume = generic_dpi_panel_resume, |
572 | 666 | ||
573 | .set_timings = generic_dpi_panel_set_timings, | 667 | .set_timings = generic_dpi_panel_set_timings, |
574 | .get_timings = generic_dpi_panel_get_timings, | ||
575 | .check_timings = generic_dpi_panel_check_timings, | 668 | .check_timings = generic_dpi_panel_check_timings, |
576 | 669 | ||
577 | .driver = { | 670 | .driver = { |
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c index dc9408dc93d1..4a34cdc1371b 100644 --- a/drivers/video/omap2/displays/panel-n8x0.c +++ b/drivers/video/omap2/displays/panel-n8x0.c | |||
@@ -610,12 +610,6 @@ static int n8x0_panel_resume(struct omap_dss_device *dssdev) | |||
610 | return 0; | 610 | return 0; |
611 | } | 611 | } |
612 | 612 | ||
613 | static void n8x0_panel_get_timings(struct omap_dss_device *dssdev, | ||
614 | struct omap_video_timings *timings) | ||
615 | { | ||
616 | *timings = dssdev->panel.timings; | ||
617 | } | ||
618 | |||
619 | static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev, | 613 | static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev, |
620 | u16 *xres, u16 *yres) | 614 | u16 *xres, u16 *yres) |
621 | { | 615 | { |
@@ -678,8 +672,6 @@ static struct omap_dss_driver n8x0_panel_driver = { | |||
678 | .get_resolution = n8x0_panel_get_resolution, | 672 | .get_resolution = n8x0_panel_get_resolution, |
679 | .get_recommended_bpp = omapdss_default_get_recommended_bpp, | 673 | .get_recommended_bpp = omapdss_default_get_recommended_bpp, |
680 | 674 | ||
681 | .get_timings = n8x0_panel_get_timings, | ||
682 | |||
683 | .driver = { | 675 | .driver = { |
684 | .name = "n8x0_panel", | 676 | .name = "n8x0_panel", |
685 | .owner = THIS_MODULE, | 677 | .owner = THIS_MODULE, |
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index b2dd88b48420..2ce9992f403b 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/gpio.h> | 30 | #include <linux/gpio.h> |
31 | #include <linux/workqueue.h> | 31 | #include <linux/workqueue.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/regulator/consumer.h> | ||
34 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
35 | 34 | ||
36 | #include <video/omapdss.h> | 35 | #include <video/omapdss.h> |
@@ -55,73 +54,6 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); | |||
55 | 54 | ||
56 | static int taal_panel_reset(struct omap_dss_device *dssdev); | 55 | static int taal_panel_reset(struct omap_dss_device *dssdev); |
57 | 56 | ||
58 | struct panel_regulator { | ||
59 | struct regulator *regulator; | ||
60 | const char *name; | ||
61 | int min_uV; | ||
62 | int max_uV; | ||
63 | }; | ||
64 | |||
65 | static void free_regulators(struct panel_regulator *regulators, int n) | ||
66 | { | ||
67 | int i; | ||
68 | |||
69 | for (i = 0; i < n; i++) { | ||
70 | /* disable/put in reverse order */ | ||
71 | regulator_disable(regulators[n - i - 1].regulator); | ||
72 | regulator_put(regulators[n - i - 1].regulator); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | static int init_regulators(struct omap_dss_device *dssdev, | ||
77 | struct panel_regulator *regulators, int n) | ||
78 | { | ||
79 | int r, i, v; | ||
80 | |||
81 | for (i = 0; i < n; i++) { | ||
82 | struct regulator *reg; | ||
83 | |||
84 | reg = regulator_get(&dssdev->dev, regulators[i].name); | ||
85 | if (IS_ERR(reg)) { | ||
86 | dev_err(&dssdev->dev, "failed to get regulator %s\n", | ||
87 | regulators[i].name); | ||
88 | r = PTR_ERR(reg); | ||
89 | goto err; | ||
90 | } | ||
91 | |||
92 | /* FIXME: better handling of fixed vs. variable regulators */ | ||
93 | v = regulator_get_voltage(reg); | ||
94 | if (v < regulators[i].min_uV || v > regulators[i].max_uV) { | ||
95 | r = regulator_set_voltage(reg, regulators[i].min_uV, | ||
96 | regulators[i].max_uV); | ||
97 | if (r) { | ||
98 | dev_err(&dssdev->dev, | ||
99 | "failed to set regulator %s voltage\n", | ||
100 | regulators[i].name); | ||
101 | regulator_put(reg); | ||
102 | goto err; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | r = regulator_enable(reg); | ||
107 | if (r) { | ||
108 | dev_err(&dssdev->dev, "failed to enable regulator %s\n", | ||
109 | regulators[i].name); | ||
110 | regulator_put(reg); | ||
111 | goto err; | ||
112 | } | ||
113 | |||
114 | regulators[i].regulator = reg; | ||
115 | } | ||
116 | |||
117 | return 0; | ||
118 | |||
119 | err: | ||
120 | free_regulators(regulators, i); | ||
121 | |||
122 | return r; | ||
123 | } | ||
124 | |||
125 | /** | 57 | /** |
126 | * struct panel_config - panel configuration | 58 | * struct panel_config - panel configuration |
127 | * @name: panel name | 59 | * @name: panel name |
@@ -150,8 +82,6 @@ struct panel_config { | |||
150 | unsigned int low; | 82 | unsigned int low; |
151 | } reset_sequence; | 83 | } reset_sequence; |
152 | 84 | ||
153 | struct panel_regulator *regulators; | ||
154 | int num_regulators; | ||
155 | }; | 85 | }; |
156 | 86 | ||
157 | enum { | 87 | enum { |
@@ -577,12 +507,6 @@ static const struct backlight_ops taal_bl_ops = { | |||
577 | .update_status = taal_bl_update_status, | 507 | .update_status = taal_bl_update_status, |
578 | }; | 508 | }; |
579 | 509 | ||
580 | static void taal_get_timings(struct omap_dss_device *dssdev, | ||
581 | struct omap_video_timings *timings) | ||
582 | { | ||
583 | *timings = dssdev->panel.timings; | ||
584 | } | ||
585 | |||
586 | static void taal_get_resolution(struct omap_dss_device *dssdev, | 510 | static void taal_get_resolution(struct omap_dss_device *dssdev, |
587 | u16 *xres, u16 *yres) | 511 | u16 *xres, u16 *yres) |
588 | { | 512 | { |
@@ -977,11 +901,6 @@ static int taal_probe(struct omap_dss_device *dssdev) | |||
977 | 901 | ||
978 | atomic_set(&td->do_update, 0); | 902 | atomic_set(&td->do_update, 0); |
979 | 903 | ||
980 | r = init_regulators(dssdev, panel_config->regulators, | ||
981 | panel_config->num_regulators); | ||
982 | if (r) | ||
983 | goto err_reg; | ||
984 | |||
985 | td->workqueue = create_singlethread_workqueue("taal_esd"); | 904 | td->workqueue = create_singlethread_workqueue("taal_esd"); |
986 | if (td->workqueue == NULL) { | 905 | if (td->workqueue == NULL) { |
987 | dev_err(&dssdev->dev, "can't create ESD workqueue\n"); | 906 | dev_err(&dssdev->dev, "can't create ESD workqueue\n"); |
@@ -1087,8 +1006,6 @@ err_bl: | |||
1087 | err_rst_gpio: | 1006 | err_rst_gpio: |
1088 | destroy_workqueue(td->workqueue); | 1007 | destroy_workqueue(td->workqueue); |
1089 | err_wq: | 1008 | err_wq: |
1090 | free_regulators(panel_config->regulators, panel_config->num_regulators); | ||
1091 | err_reg: | ||
1092 | kfree(td); | 1009 | kfree(td); |
1093 | err: | 1010 | err: |
1094 | return r; | 1011 | return r; |
@@ -1125,9 +1042,6 @@ static void __exit taal_remove(struct omap_dss_device *dssdev) | |||
1125 | /* reset, to be sure that the panel is in a valid state */ | 1042 | /* reset, to be sure that the panel is in a valid state */ |
1126 | taal_hw_reset(dssdev); | 1043 | taal_hw_reset(dssdev); |
1127 | 1044 | ||
1128 | free_regulators(td->panel_config->regulators, | ||
1129 | td->panel_config->num_regulators); | ||
1130 | |||
1131 | if (gpio_is_valid(panel_data->reset_gpio)) | 1045 | if (gpio_is_valid(panel_data->reset_gpio)) |
1132 | gpio_free(panel_data->reset_gpio); | 1046 | gpio_free(panel_data->reset_gpio); |
1133 | 1047 | ||
@@ -1909,8 +1823,6 @@ static struct omap_dss_driver taal_driver = { | |||
1909 | .run_test = taal_run_test, | 1823 | .run_test = taal_run_test, |
1910 | .memory_read = taal_memory_read, | 1824 | .memory_read = taal_memory_read, |
1911 | 1825 | ||
1912 | .get_timings = taal_get_timings, | ||
1913 | |||
1914 | .driver = { | 1826 | .driver = { |
1915 | .name = "taal", | 1827 | .name = "taal", |
1916 | .owner = THIS_MODULE, | 1828 | .owner = THIS_MODULE, |
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c index 52637fa8fda8..bff306e041ca 100644 --- a/drivers/video/omap2/displays/panel-tfp410.c +++ b/drivers/video/omap2/displays/panel-tfp410.c | |||
@@ -47,13 +47,9 @@ struct panel_drv_data { | |||
47 | struct mutex lock; | 47 | struct mutex lock; |
48 | 48 | ||
49 | int pd_gpio; | 49 | int pd_gpio; |
50 | }; | ||
51 | 50 | ||
52 | static inline struct tfp410_platform_data | 51 | struct i2c_adapter *i2c_adapter; |
53 | *get_pdata(const struct omap_dss_device *dssdev) | 52 | }; |
54 | { | ||
55 | return dssdev->data; | ||
56 | } | ||
57 | 53 | ||
58 | static int tfp410_power_on(struct omap_dss_device *dssdev) | 54 | static int tfp410_power_on(struct omap_dss_device *dssdev) |
59 | { | 55 | { |
@@ -68,7 +64,7 @@ static int tfp410_power_on(struct omap_dss_device *dssdev) | |||
68 | goto err0; | 64 | goto err0; |
69 | 65 | ||
70 | if (gpio_is_valid(ddata->pd_gpio)) | 66 | if (gpio_is_valid(ddata->pd_gpio)) |
71 | gpio_set_value(ddata->pd_gpio, 1); | 67 | gpio_set_value_cansleep(ddata->pd_gpio, 1); |
72 | 68 | ||
73 | return 0; | 69 | return 0; |
74 | err0: | 70 | err0: |
@@ -83,18 +79,18 @@ static void tfp410_power_off(struct omap_dss_device *dssdev) | |||
83 | return; | 79 | return; |
84 | 80 | ||
85 | if (gpio_is_valid(ddata->pd_gpio)) | 81 | if (gpio_is_valid(ddata->pd_gpio)) |
86 | gpio_set_value(ddata->pd_gpio, 0); | 82 | gpio_set_value_cansleep(ddata->pd_gpio, 0); |
87 | 83 | ||
88 | omapdss_dpi_display_disable(dssdev); | 84 | omapdss_dpi_display_disable(dssdev); |
89 | } | 85 | } |
90 | 86 | ||
91 | static int tfp410_probe(struct omap_dss_device *dssdev) | 87 | static int tfp410_probe(struct omap_dss_device *dssdev) |
92 | { | 88 | { |
93 | struct tfp410_platform_data *pdata = get_pdata(dssdev); | ||
94 | struct panel_drv_data *ddata; | 89 | struct panel_drv_data *ddata; |
95 | int r; | 90 | int r; |
91 | int i2c_bus_num; | ||
96 | 92 | ||
97 | ddata = kzalloc(sizeof(*ddata), GFP_KERNEL); | 93 | ddata = devm_kzalloc(&dssdev->dev, sizeof(*ddata), GFP_KERNEL); |
98 | if (!ddata) | 94 | if (!ddata) |
99 | return -ENOMEM; | 95 | return -ENOMEM; |
100 | 96 | ||
@@ -104,10 +100,15 @@ static int tfp410_probe(struct omap_dss_device *dssdev) | |||
104 | ddata->dssdev = dssdev; | 100 | ddata->dssdev = dssdev; |
105 | mutex_init(&ddata->lock); | 101 | mutex_init(&ddata->lock); |
106 | 102 | ||
107 | if (pdata) | 103 | if (dssdev->data) { |
104 | struct tfp410_platform_data *pdata = dssdev->data; | ||
105 | |||
108 | ddata->pd_gpio = pdata->power_down_gpio; | 106 | ddata->pd_gpio = pdata->power_down_gpio; |
109 | else | 107 | i2c_bus_num = pdata->i2c_bus_num; |
108 | } else { | ||
110 | ddata->pd_gpio = -1; | 109 | ddata->pd_gpio = -1; |
110 | i2c_bus_num = -1; | ||
111 | } | ||
111 | 112 | ||
112 | if (gpio_is_valid(ddata->pd_gpio)) { | 113 | if (gpio_is_valid(ddata->pd_gpio)) { |
113 | r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW, | 114 | r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW, |
@@ -115,13 +116,31 @@ static int tfp410_probe(struct omap_dss_device *dssdev) | |||
115 | if (r) { | 116 | if (r) { |
116 | dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", | 117 | dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", |
117 | ddata->pd_gpio); | 118 | ddata->pd_gpio); |
118 | ddata->pd_gpio = -1; | 119 | return r; |
119 | } | 120 | } |
120 | } | 121 | } |
121 | 122 | ||
123 | if (i2c_bus_num != -1) { | ||
124 | struct i2c_adapter *adapter; | ||
125 | |||
126 | adapter = i2c_get_adapter(i2c_bus_num); | ||
127 | if (!adapter) { | ||
128 | dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", | ||
129 | i2c_bus_num); | ||
130 | r = -EINVAL; | ||
131 | goto err_i2c; | ||
132 | } | ||
133 | |||
134 | ddata->i2c_adapter = adapter; | ||
135 | } | ||
136 | |||
122 | dev_set_drvdata(&dssdev->dev, ddata); | 137 | dev_set_drvdata(&dssdev->dev, ddata); |
123 | 138 | ||
124 | return 0; | 139 | return 0; |
140 | err_i2c: | ||
141 | if (gpio_is_valid(ddata->pd_gpio)) | ||
142 | gpio_free(ddata->pd_gpio); | ||
143 | return r; | ||
125 | } | 144 | } |
126 | 145 | ||
127 | static void __exit tfp410_remove(struct omap_dss_device *dssdev) | 146 | static void __exit tfp410_remove(struct omap_dss_device *dssdev) |
@@ -130,14 +149,15 @@ static void __exit tfp410_remove(struct omap_dss_device *dssdev) | |||
130 | 149 | ||
131 | mutex_lock(&ddata->lock); | 150 | mutex_lock(&ddata->lock); |
132 | 151 | ||
152 | if (ddata->i2c_adapter) | ||
153 | i2c_put_adapter(ddata->i2c_adapter); | ||
154 | |||
133 | if (gpio_is_valid(ddata->pd_gpio)) | 155 | if (gpio_is_valid(ddata->pd_gpio)) |
134 | gpio_free(ddata->pd_gpio); | 156 | gpio_free(ddata->pd_gpio); |
135 | 157 | ||
136 | dev_set_drvdata(&dssdev->dev, NULL); | 158 | dev_set_drvdata(&dssdev->dev, NULL); |
137 | 159 | ||
138 | mutex_unlock(&ddata->lock); | 160 | mutex_unlock(&ddata->lock); |
139 | |||
140 | kfree(ddata); | ||
141 | } | 161 | } |
142 | 162 | ||
143 | static int tfp410_enable(struct omap_dss_device *dssdev) | 163 | static int tfp410_enable(struct omap_dss_device *dssdev) |
@@ -269,27 +289,17 @@ static int tfp410_read_edid(struct omap_dss_device *dssdev, | |||
269 | u8 *edid, int len) | 289 | u8 *edid, int len) |
270 | { | 290 | { |
271 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 291 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
272 | struct tfp410_platform_data *pdata = get_pdata(dssdev); | ||
273 | struct i2c_adapter *adapter; | ||
274 | int r, l, bytes_read; | 292 | int r, l, bytes_read; |
275 | 293 | ||
276 | mutex_lock(&ddata->lock); | 294 | mutex_lock(&ddata->lock); |
277 | 295 | ||
278 | if (pdata->i2c_bus_num == 0) { | 296 | if (!ddata->i2c_adapter) { |
279 | r = -ENODEV; | 297 | r = -ENODEV; |
280 | goto err; | 298 | goto err; |
281 | } | 299 | } |
282 | 300 | ||
283 | adapter = i2c_get_adapter(pdata->i2c_bus_num); | ||
284 | if (!adapter) { | ||
285 | dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", | ||
286 | pdata->i2c_bus_num); | ||
287 | r = -EINVAL; | ||
288 | goto err; | ||
289 | } | ||
290 | |||
291 | l = min(EDID_LENGTH, len); | 301 | l = min(EDID_LENGTH, len); |
292 | r = tfp410_ddc_read(adapter, edid, l, 0); | 302 | r = tfp410_ddc_read(ddata->i2c_adapter, edid, l, 0); |
293 | if (r) | 303 | if (r) |
294 | goto err; | 304 | goto err; |
295 | 305 | ||
@@ -299,7 +309,7 @@ static int tfp410_read_edid(struct omap_dss_device *dssdev, | |||
299 | if (len > EDID_LENGTH && edid[0x7e] > 0) { | 309 | if (len > EDID_LENGTH && edid[0x7e] > 0) { |
300 | l = min(EDID_LENGTH, len - EDID_LENGTH); | 310 | l = min(EDID_LENGTH, len - EDID_LENGTH); |
301 | 311 | ||
302 | r = tfp410_ddc_read(adapter, edid + EDID_LENGTH, | 312 | r = tfp410_ddc_read(ddata->i2c_adapter, edid + EDID_LENGTH, |
303 | l, EDID_LENGTH); | 313 | l, EDID_LENGTH); |
304 | if (r) | 314 | if (r) |
305 | goto err; | 315 | goto err; |
@@ -319,21 +329,15 @@ err: | |||
319 | static bool tfp410_detect(struct omap_dss_device *dssdev) | 329 | static bool tfp410_detect(struct omap_dss_device *dssdev) |
320 | { | 330 | { |
321 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 331 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
322 | struct tfp410_platform_data *pdata = get_pdata(dssdev); | ||
323 | struct i2c_adapter *adapter; | ||
324 | unsigned char out; | 332 | unsigned char out; |
325 | int r; | 333 | int r; |
326 | 334 | ||
327 | mutex_lock(&ddata->lock); | 335 | mutex_lock(&ddata->lock); |
328 | 336 | ||
329 | if (pdata->i2c_bus_num == 0) | 337 | if (!ddata->i2c_adapter) |
330 | goto out; | ||
331 | |||
332 | adapter = i2c_get_adapter(pdata->i2c_bus_num); | ||
333 | if (!adapter) | ||
334 | goto out; | 338 | goto out; |
335 | 339 | ||
336 | r = tfp410_ddc_read(adapter, &out, 1, 0); | 340 | r = tfp410_ddc_read(ddata->i2c_adapter, &out, 1, 0); |
337 | 341 | ||
338 | mutex_unlock(&ddata->lock); | 342 | mutex_unlock(&ddata->lock); |
339 | 343 | ||
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index 32f3fcd7f0f0..4b6448b3c31f 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c | |||
@@ -272,13 +272,16 @@ static const struct omap_video_timings tpo_td043_timings = { | |||
272 | static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) | 272 | static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) |
273 | { | 273 | { |
274 | int nreset_gpio = tpo_td043->nreset_gpio; | 274 | int nreset_gpio = tpo_td043->nreset_gpio; |
275 | int r; | ||
275 | 276 | ||
276 | if (tpo_td043->powered_on) | 277 | if (tpo_td043->powered_on) |
277 | return 0; | 278 | return 0; |
278 | 279 | ||
279 | regulator_enable(tpo_td043->vcc_reg); | 280 | r = regulator_enable(tpo_td043->vcc_reg); |
281 | if (r != 0) | ||
282 | return r; | ||
280 | 283 | ||
281 | /* wait for regulator to stabilize */ | 284 | /* wait for panel to stabilize */ |
282 | msleep(160); | 285 | msleep(160); |
283 | 286 | ||
284 | if (gpio_is_valid(nreset_gpio)) | 287 | if (gpio_is_valid(nreset_gpio)) |
@@ -470,6 +473,18 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev) | |||
470 | gpio_free(nreset_gpio); | 473 | gpio_free(nreset_gpio); |
471 | } | 474 | } |
472 | 475 | ||
476 | static void tpo_td043_set_timings(struct omap_dss_device *dssdev, | ||
477 | struct omap_video_timings *timings) | ||
478 | { | ||
479 | dpi_set_timings(dssdev, timings); | ||
480 | } | ||
481 | |||
482 | static int tpo_td043_check_timings(struct omap_dss_device *dssdev, | ||
483 | struct omap_video_timings *timings) | ||
484 | { | ||
485 | return dpi_check_timings(dssdev, timings); | ||
486 | } | ||
487 | |||
473 | static struct omap_dss_driver tpo_td043_driver = { | 488 | static struct omap_dss_driver tpo_td043_driver = { |
474 | .probe = tpo_td043_probe, | 489 | .probe = tpo_td043_probe, |
475 | .remove = tpo_td043_remove, | 490 | .remove = tpo_td043_remove, |
@@ -481,6 +496,9 @@ static struct omap_dss_driver tpo_td043_driver = { | |||
481 | .set_mirror = tpo_td043_set_hmirror, | 496 | .set_mirror = tpo_td043_set_hmirror, |
482 | .get_mirror = tpo_td043_get_hmirror, | 497 | .get_mirror = tpo_td043_get_hmirror, |
483 | 498 | ||
499 | .set_timings = tpo_td043_set_timings, | ||
500 | .check_timings = tpo_td043_check_timings, | ||
501 | |||
484 | .driver = { | 502 | .driver = { |
485 | .name = "tpo_td043mtea1_panel", | 503 | .name = "tpo_td043mtea1_panel", |
486 | .owner = THIS_MODULE, | 504 | .owner = THIS_MODULE, |
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index 7be7c06a249e..43324e5ed25f 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig | |||
@@ -68,6 +68,10 @@ config OMAP4_DSS_HDMI | |||
68 | HDMI Interface. This adds the High Definition Multimedia Interface. | 68 | HDMI Interface. This adds the High Definition Multimedia Interface. |
69 | See http://www.hdmi.org/ for HDMI specification. | 69 | See http://www.hdmi.org/ for HDMI specification. |
70 | 70 | ||
71 | config OMAP4_DSS_HDMI_AUDIO | ||
72 | bool | ||
73 | depends on OMAP4_DSS_HDMI | ||
74 | |||
71 | config OMAP2_DSS_SDI | 75 | config OMAP2_DSS_SDI |
72 | bool "SDI support" | 76 | bool "SDI support" |
73 | depends on ARCH_OMAP3 | 77 | depends on ARCH_OMAP3 |
@@ -90,15 +94,6 @@ config OMAP2_DSS_DSI | |||
90 | 94 | ||
91 | See http://www.mipi.org/ for DSI spesifications. | 95 | See http://www.mipi.org/ for DSI spesifications. |
92 | 96 | ||
93 | config OMAP2_DSS_FAKE_VSYNC | ||
94 | bool "Fake VSYNC irq from manual update displays" | ||
95 | default n | ||
96 | help | ||
97 | If this is selected, DSI will generate a fake DISPC VSYNC interrupt | ||
98 | when DSI has sent a frame. This is only needed with DSI or RFBI | ||
99 | displays using manual mode, and you want VSYNC to, for example, | ||
100 | time animation. | ||
101 | |||
102 | config OMAP2_DSS_MIN_FCK_PER_PCK | 97 | config OMAP2_DSS_MIN_FCK_PER_PCK |
103 | int "Minimum FCK/PCK ratio (for scaling)" | 98 | int "Minimum FCK/PCK ratio (for scaling)" |
104 | range 0 32 | 99 | range 0 32 |
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index b10b3bc1931e..ab22cc224f3e 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c | |||
@@ -99,6 +99,11 @@ struct mgr_priv_data { | |||
99 | 99 | ||
100 | /* If true, a display is enabled using this manager */ | 100 | /* If true, a display is enabled using this manager */ |
101 | bool enabled; | 101 | bool enabled; |
102 | |||
103 | bool extra_info_dirty; | ||
104 | bool shadow_extra_info_dirty; | ||
105 | |||
106 | struct omap_video_timings timings; | ||
102 | }; | 107 | }; |
103 | 108 | ||
104 | static struct { | 109 | static struct { |
@@ -176,7 +181,7 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr) | |||
176 | } | 181 | } |
177 | 182 | ||
178 | static int dss_check_settings_low(struct omap_overlay_manager *mgr, | 183 | static int dss_check_settings_low(struct omap_overlay_manager *mgr, |
179 | struct omap_dss_device *dssdev, bool applying) | 184 | bool applying) |
180 | { | 185 | { |
181 | struct omap_overlay_info *oi; | 186 | struct omap_overlay_info *oi; |
182 | struct omap_overlay_manager_info *mi; | 187 | struct omap_overlay_manager_info *mi; |
@@ -187,6 +192,9 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr, | |||
187 | 192 | ||
188 | mp = get_mgr_priv(mgr); | 193 | mp = get_mgr_priv(mgr); |
189 | 194 | ||
195 | if (!mp->enabled) | ||
196 | return 0; | ||
197 | |||
190 | if (applying && mp->user_info_dirty) | 198 | if (applying && mp->user_info_dirty) |
191 | mi = &mp->user_info; | 199 | mi = &mp->user_info; |
192 | else | 200 | else |
@@ -206,26 +214,24 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr, | |||
206 | ois[ovl->id] = oi; | 214 | ois[ovl->id] = oi; |
207 | } | 215 | } |
208 | 216 | ||
209 | return dss_mgr_check(mgr, dssdev, mi, ois); | 217 | return dss_mgr_check(mgr, mi, &mp->timings, ois); |
210 | } | 218 | } |
211 | 219 | ||
212 | /* | 220 | /* |
213 | * check manager and overlay settings using overlay_info from data->info | 221 | * check manager and overlay settings using overlay_info from data->info |
214 | */ | 222 | */ |
215 | static int dss_check_settings(struct omap_overlay_manager *mgr, | 223 | static int dss_check_settings(struct omap_overlay_manager *mgr) |
216 | struct omap_dss_device *dssdev) | ||
217 | { | 224 | { |
218 | return dss_check_settings_low(mgr, dssdev, false); | 225 | return dss_check_settings_low(mgr, false); |
219 | } | 226 | } |
220 | 227 | ||
221 | /* | 228 | /* |
222 | * check manager and overlay settings using overlay_info from ovl->info if | 229 | * check manager and overlay settings using overlay_info from ovl->info if |
223 | * dirty and from data->info otherwise | 230 | * dirty and from data->info otherwise |
224 | */ | 231 | */ |
225 | static int dss_check_settings_apply(struct omap_overlay_manager *mgr, | 232 | static int dss_check_settings_apply(struct omap_overlay_manager *mgr) |
226 | struct omap_dss_device *dssdev) | ||
227 | { | 233 | { |
228 | return dss_check_settings_low(mgr, dssdev, true); | 234 | return dss_check_settings_low(mgr, true); |
229 | } | 235 | } |
230 | 236 | ||
231 | static bool need_isr(void) | 237 | static bool need_isr(void) |
@@ -261,6 +267,20 @@ static bool need_isr(void) | |||
261 | if (mp->shadow_info_dirty) | 267 | if (mp->shadow_info_dirty) |
262 | return true; | 268 | return true; |
263 | 269 | ||
270 | /* | ||
271 | * NOTE: we don't check extra_info flags for disabled | ||
272 | * managers, once the manager is enabled, the extra_info | ||
273 | * related manager changes will be taken in by HW. | ||
274 | */ | ||
275 | |||
276 | /* to write new values to registers */ | ||
277 | if (mp->extra_info_dirty) | ||
278 | return true; | ||
279 | |||
280 | /* to set GO bit */ | ||
281 | if (mp->shadow_extra_info_dirty) | ||
282 | return true; | ||
283 | |||
264 | list_for_each_entry(ovl, &mgr->overlays, list) { | 284 | list_for_each_entry(ovl, &mgr->overlays, list) { |
265 | struct ovl_priv_data *op; | 285 | struct ovl_priv_data *op; |
266 | 286 | ||
@@ -305,7 +325,7 @@ static bool need_go(struct omap_overlay_manager *mgr) | |||
305 | 325 | ||
306 | mp = get_mgr_priv(mgr); | 326 | mp = get_mgr_priv(mgr); |
307 | 327 | ||
308 | if (mp->shadow_info_dirty) | 328 | if (mp->shadow_info_dirty || mp->shadow_extra_info_dirty) |
309 | return true; | 329 | return true; |
310 | 330 | ||
311 | list_for_each_entry(ovl, &mgr->overlays, list) { | 331 | list_for_each_entry(ovl, &mgr->overlays, list) { |
@@ -320,20 +340,16 @@ static bool need_go(struct omap_overlay_manager *mgr) | |||
320 | /* returns true if an extra_info field is currently being updated */ | 340 | /* returns true if an extra_info field is currently being updated */ |
321 | static bool extra_info_update_ongoing(void) | 341 | static bool extra_info_update_ongoing(void) |
322 | { | 342 | { |
323 | const int num_ovls = omap_dss_get_num_overlays(); | 343 | const int num_mgrs = dss_feat_get_num_mgrs(); |
324 | struct ovl_priv_data *op; | ||
325 | struct omap_overlay *ovl; | ||
326 | struct mgr_priv_data *mp; | ||
327 | int i; | 344 | int i; |
328 | 345 | ||
329 | for (i = 0; i < num_ovls; ++i) { | 346 | for (i = 0; i < num_mgrs; ++i) { |
330 | ovl = omap_dss_get_overlay(i); | 347 | struct omap_overlay_manager *mgr; |
331 | op = get_ovl_priv(ovl); | 348 | struct omap_overlay *ovl; |
332 | 349 | struct mgr_priv_data *mp; | |
333 | if (!ovl->manager) | ||
334 | continue; | ||
335 | 350 | ||
336 | mp = get_mgr_priv(ovl->manager); | 351 | mgr = omap_dss_get_overlay_manager(i); |
352 | mp = get_mgr_priv(mgr); | ||
337 | 353 | ||
338 | if (!mp->enabled) | 354 | if (!mp->enabled) |
339 | continue; | 355 | continue; |
@@ -341,8 +357,15 @@ static bool extra_info_update_ongoing(void) | |||
341 | if (!mp->updating) | 357 | if (!mp->updating) |
342 | continue; | 358 | continue; |
343 | 359 | ||
344 | if (op->extra_info_dirty || op->shadow_extra_info_dirty) | 360 | if (mp->extra_info_dirty || mp->shadow_extra_info_dirty) |
345 | return true; | 361 | return true; |
362 | |||
363 | list_for_each_entry(ovl, &mgr->overlays, list) { | ||
364 | struct ovl_priv_data *op = get_ovl_priv(ovl); | ||
365 | |||
366 | if (op->extra_info_dirty || op->shadow_extra_info_dirty) | ||
367 | return true; | ||
368 | } | ||
346 | } | 369 | } |
347 | 370 | ||
348 | return false; | 371 | return false; |
@@ -525,11 +548,13 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) | |||
525 | 548 | ||
526 | oi = &op->info; | 549 | oi = &op->info; |
527 | 550 | ||
551 | mp = get_mgr_priv(ovl->manager); | ||
552 | |||
528 | replication = dss_use_replication(ovl->manager->device, oi->color_mode); | 553 | replication = dss_use_replication(ovl->manager->device, oi->color_mode); |
529 | 554 | ||
530 | ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; | 555 | ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; |
531 | 556 | ||
532 | r = dispc_ovl_setup(ovl->id, oi, ilace, replication); | 557 | r = dispc_ovl_setup(ovl->id, oi, ilace, replication, &mp->timings); |
533 | if (r) { | 558 | if (r) { |
534 | /* | 559 | /* |
535 | * We can't do much here, as this function can be called from | 560 | * We can't do much here, as this function can be called from |
@@ -543,8 +568,6 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) | |||
543 | return; | 568 | return; |
544 | } | 569 | } |
545 | 570 | ||
546 | mp = get_mgr_priv(ovl->manager); | ||
547 | |||
548 | op->info_dirty = false; | 571 | op->info_dirty = false; |
549 | if (mp->updating) | 572 | if (mp->updating) |
550 | op->shadow_info_dirty = true; | 573 | op->shadow_info_dirty = true; |
@@ -601,6 +624,22 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) | |||
601 | } | 624 | } |
602 | } | 625 | } |
603 | 626 | ||
627 | static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr) | ||
628 | { | ||
629 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | ||
630 | |||
631 | DSSDBGF("%d", mgr->id); | ||
632 | |||
633 | if (!mp->extra_info_dirty) | ||
634 | return; | ||
635 | |||
636 | dispc_mgr_set_timings(mgr->id, &mp->timings); | ||
637 | |||
638 | mp->extra_info_dirty = false; | ||
639 | if (mp->updating) | ||
640 | mp->shadow_extra_info_dirty = true; | ||
641 | } | ||
642 | |||
604 | static void dss_write_regs_common(void) | 643 | static void dss_write_regs_common(void) |
605 | { | 644 | { |
606 | const int num_mgrs = omap_dss_get_num_overlay_managers(); | 645 | const int num_mgrs = omap_dss_get_num_overlay_managers(); |
@@ -646,7 +685,7 @@ static void dss_write_regs(void) | |||
646 | if (!mp->enabled || mgr_manual_update(mgr) || mp->busy) | 685 | if (!mp->enabled || mgr_manual_update(mgr) || mp->busy) |
647 | continue; | 686 | continue; |
648 | 687 | ||
649 | r = dss_check_settings(mgr, mgr->device); | 688 | r = dss_check_settings(mgr); |
650 | if (r) { | 689 | if (r) { |
651 | DSSERR("cannot write registers for manager %s: " | 690 | DSSERR("cannot write registers for manager %s: " |
652 | "illegal configuration\n", mgr->name); | 691 | "illegal configuration\n", mgr->name); |
@@ -654,6 +693,7 @@ static void dss_write_regs(void) | |||
654 | } | 693 | } |
655 | 694 | ||
656 | dss_mgr_write_regs(mgr); | 695 | dss_mgr_write_regs(mgr); |
696 | dss_mgr_write_regs_extra(mgr); | ||
657 | } | 697 | } |
658 | } | 698 | } |
659 | 699 | ||
@@ -693,6 +733,7 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr) | |||
693 | 733 | ||
694 | mp = get_mgr_priv(mgr); | 734 | mp = get_mgr_priv(mgr); |
695 | mp->shadow_info_dirty = false; | 735 | mp->shadow_info_dirty = false; |
736 | mp->shadow_extra_info_dirty = false; | ||
696 | 737 | ||
697 | list_for_each_entry(ovl, &mgr->overlays, list) { | 738 | list_for_each_entry(ovl, &mgr->overlays, list) { |
698 | op = get_ovl_priv(ovl); | 739 | op = get_ovl_priv(ovl); |
@@ -711,7 +752,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) | |||
711 | 752 | ||
712 | WARN_ON(mp->updating); | 753 | WARN_ON(mp->updating); |
713 | 754 | ||
714 | r = dss_check_settings(mgr, mgr->device); | 755 | r = dss_check_settings(mgr); |
715 | if (r) { | 756 | if (r) { |
716 | DSSERR("cannot start manual update: illegal configuration\n"); | 757 | DSSERR("cannot start manual update: illegal configuration\n"); |
717 | spin_unlock_irqrestore(&data_lock, flags); | 758 | spin_unlock_irqrestore(&data_lock, flags); |
@@ -719,6 +760,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) | |||
719 | } | 760 | } |
720 | 761 | ||
721 | dss_mgr_write_regs(mgr); | 762 | dss_mgr_write_regs(mgr); |
763 | dss_mgr_write_regs_extra(mgr); | ||
722 | 764 | ||
723 | dss_write_regs_common(); | 765 | dss_write_regs_common(); |
724 | 766 | ||
@@ -857,7 +899,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) | |||
857 | 899 | ||
858 | spin_lock_irqsave(&data_lock, flags); | 900 | spin_lock_irqsave(&data_lock, flags); |
859 | 901 | ||
860 | r = dss_check_settings_apply(mgr, mgr->device); | 902 | r = dss_check_settings_apply(mgr); |
861 | if (r) { | 903 | if (r) { |
862 | spin_unlock_irqrestore(&data_lock, flags); | 904 | spin_unlock_irqrestore(&data_lock, flags); |
863 | DSSERR("failed to apply settings: illegal configuration.\n"); | 905 | DSSERR("failed to apply settings: illegal configuration.\n"); |
@@ -918,16 +960,13 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl, | |||
918 | bool use_fifo_merge) | 960 | bool use_fifo_merge) |
919 | { | 961 | { |
920 | struct ovl_priv_data *op = get_ovl_priv(ovl); | 962 | struct ovl_priv_data *op = get_ovl_priv(ovl); |
921 | struct omap_dss_device *dssdev; | ||
922 | u32 fifo_low, fifo_high; | 963 | u32 fifo_low, fifo_high; |
923 | 964 | ||
924 | if (!op->enabled && !op->enabling) | 965 | if (!op->enabled && !op->enabling) |
925 | return; | 966 | return; |
926 | 967 | ||
927 | dssdev = ovl->manager->device; | ||
928 | |||
929 | dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, | 968 | dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, |
930 | use_fifo_merge); | 969 | use_fifo_merge, ovl_manual_update(ovl)); |
931 | 970 | ||
932 | dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); | 971 | dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); |
933 | } | 972 | } |
@@ -1050,7 +1089,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) | |||
1050 | 1089 | ||
1051 | mp->enabled = true; | 1090 | mp->enabled = true; |
1052 | 1091 | ||
1053 | r = dss_check_settings(mgr, mgr->device); | 1092 | r = dss_check_settings(mgr); |
1054 | if (r) { | 1093 | if (r) { |
1055 | DSSERR("failed to enable manager %d: check_settings failed\n", | 1094 | DSSERR("failed to enable manager %d: check_settings failed\n", |
1056 | mgr->id); | 1095 | mgr->id); |
@@ -1225,6 +1264,35 @@ err: | |||
1225 | return r; | 1264 | return r; |
1226 | } | 1265 | } |
1227 | 1266 | ||
1267 | static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr, | ||
1268 | struct omap_video_timings *timings) | ||
1269 | { | ||
1270 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | ||
1271 | |||
1272 | mp->timings = *timings; | ||
1273 | mp->extra_info_dirty = true; | ||
1274 | } | ||
1275 | |||
1276 | void dss_mgr_set_timings(struct omap_overlay_manager *mgr, | ||
1277 | struct omap_video_timings *timings) | ||
1278 | { | ||
1279 | unsigned long flags; | ||
1280 | |||
1281 | mutex_lock(&apply_lock); | ||
1282 | |||
1283 | spin_lock_irqsave(&data_lock, flags); | ||
1284 | |||
1285 | dss_apply_mgr_timings(mgr, timings); | ||
1286 | |||
1287 | dss_write_regs(); | ||
1288 | dss_set_go_bits(); | ||
1289 | |||
1290 | spin_unlock_irqrestore(&data_lock, flags); | ||
1291 | |||
1292 | wait_pending_extra_info_updates(); | ||
1293 | |||
1294 | mutex_unlock(&apply_lock); | ||
1295 | } | ||
1228 | 1296 | ||
1229 | int dss_ovl_set_info(struct omap_overlay *ovl, | 1297 | int dss_ovl_set_info(struct omap_overlay *ovl, |
1230 | struct omap_overlay_info *info) | 1298 | struct omap_overlay_info *info) |
@@ -1393,7 +1461,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) | |||
1393 | 1461 | ||
1394 | op->enabling = true; | 1462 | op->enabling = true; |
1395 | 1463 | ||
1396 | r = dss_check_settings(ovl->manager, ovl->manager->device); | 1464 | r = dss_check_settings(ovl->manager); |
1397 | if (r) { | 1465 | if (r) { |
1398 | DSSERR("failed to enable overlay %d: check_settings failed\n", | 1466 | DSSERR("failed to enable overlay %d: check_settings failed\n", |
1399 | ovl->id); | 1467 | ovl->id); |
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index e8a120771ac6..72ded9cd2cb0 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c | |||
@@ -43,6 +43,8 @@ static struct { | |||
43 | 43 | ||
44 | struct regulator *vdds_dsi_reg; | 44 | struct regulator *vdds_dsi_reg; |
45 | struct regulator *vdds_sdi_reg; | 45 | struct regulator *vdds_sdi_reg; |
46 | |||
47 | const char *default_display_name; | ||
46 | } core; | 48 | } core; |
47 | 49 | ||
48 | static char *def_disp_name; | 50 | static char *def_disp_name; |
@@ -54,9 +56,6 @@ bool dss_debug; | |||
54 | module_param_named(debug, dss_debug, bool, 0644); | 56 | module_param_named(debug, dss_debug, bool, 0644); |
55 | #endif | 57 | #endif |
56 | 58 | ||
57 | static int omap_dss_register_device(struct omap_dss_device *); | ||
58 | static void omap_dss_unregister_device(struct omap_dss_device *); | ||
59 | |||
60 | /* REGULATORS */ | 59 | /* REGULATORS */ |
61 | 60 | ||
62 | struct regulator *dss_get_vdds_dsi(void) | 61 | struct regulator *dss_get_vdds_dsi(void) |
@@ -87,6 +86,51 @@ struct regulator *dss_get_vdds_sdi(void) | |||
87 | return reg; | 86 | return reg; |
88 | } | 87 | } |
89 | 88 | ||
89 | int dss_get_ctx_loss_count(struct device *dev) | ||
90 | { | ||
91 | struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; | ||
92 | int cnt; | ||
93 | |||
94 | if (!board_data->get_context_loss_count) | ||
95 | return -ENOENT; | ||
96 | |||
97 | cnt = board_data->get_context_loss_count(dev); | ||
98 | |||
99 | WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt); | ||
100 | |||
101 | return cnt; | ||
102 | } | ||
103 | |||
104 | int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask) | ||
105 | { | ||
106 | struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; | ||
107 | |||
108 | if (!board_data->dsi_enable_pads) | ||
109 | return -ENOENT; | ||
110 | |||
111 | return board_data->dsi_enable_pads(dsi_id, lane_mask); | ||
112 | } | ||
113 | |||
114 | void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask) | ||
115 | { | ||
116 | struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; | ||
117 | |||
118 | if (!board_data->dsi_enable_pads) | ||
119 | return; | ||
120 | |||
121 | return board_data->dsi_disable_pads(dsi_id, lane_mask); | ||
122 | } | ||
123 | |||
124 | int dss_set_min_bus_tput(struct device *dev, unsigned long tput) | ||
125 | { | ||
126 | struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; | ||
127 | |||
128 | if (pdata->set_min_bus_tput) | ||
129 | return pdata->set_min_bus_tput(dev, tput); | ||
130 | else | ||
131 | return 0; | ||
132 | } | ||
133 | |||
90 | #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) | 134 | #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) |
91 | static int dss_debug_show(struct seq_file *s, void *unused) | 135 | static int dss_debug_show(struct seq_file *s, void *unused) |
92 | { | 136 | { |
@@ -121,34 +165,6 @@ static int dss_initialize_debugfs(void) | |||
121 | debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, | 165 | debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, |
122 | &dss_debug_dump_clocks, &dss_debug_fops); | 166 | &dss_debug_dump_clocks, &dss_debug_fops); |
123 | 167 | ||
124 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
125 | debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, | ||
126 | &dispc_dump_irqs, &dss_debug_fops); | ||
127 | #endif | ||
128 | |||
129 | #if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS) | ||
130 | dsi_create_debugfs_files_irq(dss_debugfs_dir, &dss_debug_fops); | ||
131 | #endif | ||
132 | |||
133 | debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, | ||
134 | &dss_dump_regs, &dss_debug_fops); | ||
135 | debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir, | ||
136 | &dispc_dump_regs, &dss_debug_fops); | ||
137 | #ifdef CONFIG_OMAP2_DSS_RFBI | ||
138 | debugfs_create_file("rfbi", S_IRUGO, dss_debugfs_dir, | ||
139 | &rfbi_dump_regs, &dss_debug_fops); | ||
140 | #endif | ||
141 | #ifdef CONFIG_OMAP2_DSS_DSI | ||
142 | dsi_create_debugfs_files_reg(dss_debugfs_dir, &dss_debug_fops); | ||
143 | #endif | ||
144 | #ifdef CONFIG_OMAP2_DSS_VENC | ||
145 | debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir, | ||
146 | &venc_dump_regs, &dss_debug_fops); | ||
147 | #endif | ||
148 | #ifdef CONFIG_OMAP4_DSS_HDMI | ||
149 | debugfs_create_file("hdmi", S_IRUGO, dss_debugfs_dir, | ||
150 | &hdmi_dump_regs, &dss_debug_fops); | ||
151 | #endif | ||
152 | return 0; | 168 | return 0; |
153 | } | 169 | } |
154 | 170 | ||
@@ -157,6 +173,19 @@ static void dss_uninitialize_debugfs(void) | |||
157 | if (dss_debugfs_dir) | 173 | if (dss_debugfs_dir) |
158 | debugfs_remove_recursive(dss_debugfs_dir); | 174 | debugfs_remove_recursive(dss_debugfs_dir); |
159 | } | 175 | } |
176 | |||
177 | int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)) | ||
178 | { | ||
179 | struct dentry *d; | ||
180 | |||
181 | d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, | ||
182 | write, &dss_debug_fops); | ||
183 | |||
184 | if (IS_ERR(d)) | ||
185 | return PTR_ERR(d); | ||
186 | |||
187 | return 0; | ||
188 | } | ||
160 | #else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ | 189 | #else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ |
161 | static inline int dss_initialize_debugfs(void) | 190 | static inline int dss_initialize_debugfs(void) |
162 | { | 191 | { |
@@ -165,14 +194,18 @@ static inline int dss_initialize_debugfs(void) | |||
165 | static inline void dss_uninitialize_debugfs(void) | 194 | static inline void dss_uninitialize_debugfs(void) |
166 | { | 195 | { |
167 | } | 196 | } |
197 | static inline int dss_debugfs_create_file(const char *name, | ||
198 | void (*write)(struct seq_file *)) | ||
199 | { | ||
200 | return 0; | ||
201 | } | ||
168 | #endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ | 202 | #endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ |
169 | 203 | ||
170 | /* PLATFORM DEVICE */ | 204 | /* PLATFORM DEVICE */ |
171 | static int omap_dss_probe(struct platform_device *pdev) | 205 | static int __init omap_dss_probe(struct platform_device *pdev) |
172 | { | 206 | { |
173 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | 207 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; |
174 | int r; | 208 | int r; |
175 | int i; | ||
176 | 209 | ||
177 | core.pdev = pdev; | 210 | core.pdev = pdev; |
178 | 211 | ||
@@ -187,28 +220,13 @@ static int omap_dss_probe(struct platform_device *pdev) | |||
187 | if (r) | 220 | if (r) |
188 | goto err_debugfs; | 221 | goto err_debugfs; |
189 | 222 | ||
190 | for (i = 0; i < pdata->num_devices; ++i) { | 223 | if (def_disp_name) |
191 | struct omap_dss_device *dssdev = pdata->devices[i]; | 224 | core.default_display_name = def_disp_name; |
192 | 225 | else if (pdata->default_device) | |
193 | r = omap_dss_register_device(dssdev); | 226 | core.default_display_name = pdata->default_device->name; |
194 | if (r) { | ||
195 | DSSERR("device %d %s register failed %d\n", i, | ||
196 | dssdev->name ?: "unnamed", r); | ||
197 | |||
198 | while (--i >= 0) | ||
199 | omap_dss_unregister_device(pdata->devices[i]); | ||
200 | |||
201 | goto err_register; | ||
202 | } | ||
203 | |||
204 | if (def_disp_name && strcmp(def_disp_name, dssdev->name) == 0) | ||
205 | pdata->default_device = dssdev; | ||
206 | } | ||
207 | 227 | ||
208 | return 0; | 228 | return 0; |
209 | 229 | ||
210 | err_register: | ||
211 | dss_uninitialize_debugfs(); | ||
212 | err_debugfs: | 230 | err_debugfs: |
213 | 231 | ||
214 | return r; | 232 | return r; |
@@ -216,17 +234,11 @@ err_debugfs: | |||
216 | 234 | ||
217 | static int omap_dss_remove(struct platform_device *pdev) | 235 | static int omap_dss_remove(struct platform_device *pdev) |
218 | { | 236 | { |
219 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
220 | int i; | ||
221 | |||
222 | dss_uninitialize_debugfs(); | 237 | dss_uninitialize_debugfs(); |
223 | 238 | ||
224 | dss_uninit_overlays(pdev); | 239 | dss_uninit_overlays(pdev); |
225 | dss_uninit_overlay_managers(pdev); | 240 | dss_uninit_overlay_managers(pdev); |
226 | 241 | ||
227 | for (i = 0; i < pdata->num_devices; ++i) | ||
228 | omap_dss_unregister_device(pdata->devices[i]); | ||
229 | |||
230 | return 0; | 242 | return 0; |
231 | } | 243 | } |
232 | 244 | ||
@@ -251,7 +263,6 @@ static int omap_dss_resume(struct platform_device *pdev) | |||
251 | } | 263 | } |
252 | 264 | ||
253 | static struct platform_driver omap_dss_driver = { | 265 | static struct platform_driver omap_dss_driver = { |
254 | .probe = omap_dss_probe, | ||
255 | .remove = omap_dss_remove, | 266 | .remove = omap_dss_remove, |
256 | .shutdown = omap_dss_shutdown, | 267 | .shutdown = omap_dss_shutdown, |
257 | .suspend = omap_dss_suspend, | 268 | .suspend = omap_dss_suspend, |
@@ -326,7 +337,6 @@ static int dss_driver_probe(struct device *dev) | |||
326 | int r; | 337 | int r; |
327 | struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); | 338 | struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); |
328 | struct omap_dss_device *dssdev = to_dss_device(dev); | 339 | struct omap_dss_device *dssdev = to_dss_device(dev); |
329 | struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; | ||
330 | bool force; | 340 | bool force; |
331 | 341 | ||
332 | DSSDBG("driver_probe: dev %s/%s, drv %s\n", | 342 | DSSDBG("driver_probe: dev %s/%s, drv %s\n", |
@@ -335,7 +345,8 @@ static int dss_driver_probe(struct device *dev) | |||
335 | 345 | ||
336 | dss_init_device(core.pdev, dssdev); | 346 | dss_init_device(core.pdev, dssdev); |
337 | 347 | ||
338 | force = pdata->default_device == dssdev; | 348 | force = core.default_display_name && |
349 | strcmp(core.default_display_name, dssdev->name) == 0; | ||
339 | dss_recheck_connections(dssdev, force); | 350 | dss_recheck_connections(dssdev, force); |
340 | 351 | ||
341 | r = dssdrv->probe(dssdev); | 352 | r = dssdrv->probe(dssdev); |
@@ -381,6 +392,8 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver) | |||
381 | if (dssdriver->get_recommended_bpp == NULL) | 392 | if (dssdriver->get_recommended_bpp == NULL) |
382 | dssdriver->get_recommended_bpp = | 393 | dssdriver->get_recommended_bpp = |
383 | omapdss_default_get_recommended_bpp; | 394 | omapdss_default_get_recommended_bpp; |
395 | if (dssdriver->get_timings == NULL) | ||
396 | dssdriver->get_timings = omapdss_default_get_timings; | ||
384 | 397 | ||
385 | return driver_register(&dssdriver->driver); | 398 | return driver_register(&dssdriver->driver); |
386 | } | 399 | } |
@@ -427,27 +440,38 @@ static void omap_dss_dev_release(struct device *dev) | |||
427 | reset_device(dev, 0); | 440 | reset_device(dev, 0); |
428 | } | 441 | } |
429 | 442 | ||
430 | static int omap_dss_register_device(struct omap_dss_device *dssdev) | 443 | int omap_dss_register_device(struct omap_dss_device *dssdev, |
444 | struct device *parent, int disp_num) | ||
431 | { | 445 | { |
432 | static int dev_num; | ||
433 | |||
434 | WARN_ON(!dssdev->driver_name); | 446 | WARN_ON(!dssdev->driver_name); |
435 | 447 | ||
436 | reset_device(&dssdev->dev, 1); | 448 | reset_device(&dssdev->dev, 1); |
437 | dssdev->dev.bus = &dss_bus_type; | 449 | dssdev->dev.bus = &dss_bus_type; |
438 | dssdev->dev.parent = &dss_bus; | 450 | dssdev->dev.parent = parent; |
439 | dssdev->dev.release = omap_dss_dev_release; | 451 | dssdev->dev.release = omap_dss_dev_release; |
440 | dev_set_name(&dssdev->dev, "display%d", dev_num++); | 452 | dev_set_name(&dssdev->dev, "display%d", disp_num); |
441 | return device_register(&dssdev->dev); | 453 | return device_register(&dssdev->dev); |
442 | } | 454 | } |
443 | 455 | ||
444 | static void omap_dss_unregister_device(struct omap_dss_device *dssdev) | 456 | void omap_dss_unregister_device(struct omap_dss_device *dssdev) |
445 | { | 457 | { |
446 | device_unregister(&dssdev->dev); | 458 | device_unregister(&dssdev->dev); |
447 | } | 459 | } |
448 | 460 | ||
461 | static int dss_unregister_dss_dev(struct device *dev, void *data) | ||
462 | { | ||
463 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
464 | omap_dss_unregister_device(dssdev); | ||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | void omap_dss_unregister_child_devices(struct device *parent) | ||
469 | { | ||
470 | device_for_each_child(parent, NULL, dss_unregister_dss_dev); | ||
471 | } | ||
472 | |||
449 | /* BUS */ | 473 | /* BUS */ |
450 | static int omap_dss_bus_register(void) | 474 | static int __init omap_dss_bus_register(void) |
451 | { | 475 | { |
452 | int r; | 476 | int r; |
453 | 477 | ||
@@ -469,12 +493,56 @@ static int omap_dss_bus_register(void) | |||
469 | } | 493 | } |
470 | 494 | ||
471 | /* INIT */ | 495 | /* INIT */ |
496 | static int (*dss_output_drv_reg_funcs[])(void) __initdata = { | ||
497 | #ifdef CONFIG_OMAP2_DSS_DPI | ||
498 | dpi_init_platform_driver, | ||
499 | #endif | ||
500 | #ifdef CONFIG_OMAP2_DSS_SDI | ||
501 | sdi_init_platform_driver, | ||
502 | #endif | ||
503 | #ifdef CONFIG_OMAP2_DSS_RFBI | ||
504 | rfbi_init_platform_driver, | ||
505 | #endif | ||
506 | #ifdef CONFIG_OMAP2_DSS_VENC | ||
507 | venc_init_platform_driver, | ||
508 | #endif | ||
509 | #ifdef CONFIG_OMAP2_DSS_DSI | ||
510 | dsi_init_platform_driver, | ||
511 | #endif | ||
512 | #ifdef CONFIG_OMAP4_DSS_HDMI | ||
513 | hdmi_init_platform_driver, | ||
514 | #endif | ||
515 | }; | ||
516 | |||
517 | static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { | ||
518 | #ifdef CONFIG_OMAP2_DSS_DPI | ||
519 | dpi_uninit_platform_driver, | ||
520 | #endif | ||
521 | #ifdef CONFIG_OMAP2_DSS_SDI | ||
522 | sdi_uninit_platform_driver, | ||
523 | #endif | ||
524 | #ifdef CONFIG_OMAP2_DSS_RFBI | ||
525 | rfbi_uninit_platform_driver, | ||
526 | #endif | ||
527 | #ifdef CONFIG_OMAP2_DSS_VENC | ||
528 | venc_uninit_platform_driver, | ||
529 | #endif | ||
530 | #ifdef CONFIG_OMAP2_DSS_DSI | ||
531 | dsi_uninit_platform_driver, | ||
532 | #endif | ||
533 | #ifdef CONFIG_OMAP4_DSS_HDMI | ||
534 | hdmi_uninit_platform_driver, | ||
535 | #endif | ||
536 | }; | ||
537 | |||
538 | static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)]; | ||
472 | 539 | ||
473 | static int __init omap_dss_register_drivers(void) | 540 | static int __init omap_dss_register_drivers(void) |
474 | { | 541 | { |
475 | int r; | 542 | int r; |
543 | int i; | ||
476 | 544 | ||
477 | r = platform_driver_register(&omap_dss_driver); | 545 | r = platform_driver_probe(&omap_dss_driver, omap_dss_probe); |
478 | if (r) | 546 | if (r) |
479 | return r; | 547 | return r; |
480 | 548 | ||
@@ -490,40 +558,18 @@ static int __init omap_dss_register_drivers(void) | |||
490 | goto err_dispc; | 558 | goto err_dispc; |
491 | } | 559 | } |
492 | 560 | ||
493 | r = rfbi_init_platform_driver(); | 561 | /* |
494 | if (r) { | 562 | * It's ok if the output-driver register fails. It happens, for example, |
495 | DSSERR("Failed to initialize rfbi platform driver\n"); | 563 | * when there is no output-device (e.g. SDI for OMAP4). |
496 | goto err_rfbi; | 564 | */ |
497 | } | 565 | for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) { |
498 | 566 | r = dss_output_drv_reg_funcs[i](); | |
499 | r = venc_init_platform_driver(); | 567 | if (r == 0) |
500 | if (r) { | 568 | dss_output_drv_loaded[i] = true; |
501 | DSSERR("Failed to initialize venc platform driver\n"); | ||
502 | goto err_venc; | ||
503 | } | ||
504 | |||
505 | r = dsi_init_platform_driver(); | ||
506 | if (r) { | ||
507 | DSSERR("Failed to initialize DSI platform driver\n"); | ||
508 | goto err_dsi; | ||
509 | } | ||
510 | |||
511 | r = hdmi_init_platform_driver(); | ||
512 | if (r) { | ||
513 | DSSERR("Failed to initialize hdmi\n"); | ||
514 | goto err_hdmi; | ||
515 | } | 569 | } |
516 | 570 | ||
517 | return 0; | 571 | return 0; |
518 | 572 | ||
519 | err_hdmi: | ||
520 | dsi_uninit_platform_driver(); | ||
521 | err_dsi: | ||
522 | venc_uninit_platform_driver(); | ||
523 | err_venc: | ||
524 | rfbi_uninit_platform_driver(); | ||
525 | err_rfbi: | ||
526 | dispc_uninit_platform_driver(); | ||
527 | err_dispc: | 573 | err_dispc: |
528 | dss_uninit_platform_driver(); | 574 | dss_uninit_platform_driver(); |
529 | err_dss: | 575 | err_dss: |
@@ -534,10 +580,13 @@ err_dss: | |||
534 | 580 | ||
535 | static void __exit omap_dss_unregister_drivers(void) | 581 | static void __exit omap_dss_unregister_drivers(void) |
536 | { | 582 | { |
537 | hdmi_uninit_platform_driver(); | 583 | int i; |
538 | dsi_uninit_platform_driver(); | 584 | |
539 | venc_uninit_platform_driver(); | 585 | for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i) { |
540 | rfbi_uninit_platform_driver(); | 586 | if (dss_output_drv_loaded[i]) |
587 | dss_output_drv_unreg_funcs[i](); | ||
588 | } | ||
589 | |||
541 | dispc_uninit_platform_driver(); | 590 | dispc_uninit_platform_driver(); |
542 | dss_uninit_platform_driver(); | 591 | dss_uninit_platform_driver(); |
543 | 592 | ||
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index ee30937482e1..4749ac356469 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -131,23 +131,6 @@ static inline u32 dispc_read_reg(const u16 idx) | |||
131 | return __raw_readl(dispc.base + idx); | 131 | return __raw_readl(dispc.base + idx); |
132 | } | 132 | } |
133 | 133 | ||
134 | static int dispc_get_ctx_loss_count(void) | ||
135 | { | ||
136 | struct device *dev = &dispc.pdev->dev; | ||
137 | struct omap_display_platform_data *pdata = dev->platform_data; | ||
138 | struct omap_dss_board_info *board_data = pdata->board_data; | ||
139 | int cnt; | ||
140 | |||
141 | if (!board_data->get_context_loss_count) | ||
142 | return -ENOENT; | ||
143 | |||
144 | cnt = board_data->get_context_loss_count(dev); | ||
145 | |||
146 | WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt); | ||
147 | |||
148 | return cnt; | ||
149 | } | ||
150 | |||
151 | #define SR(reg) \ | 134 | #define SR(reg) \ |
152 | dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) | 135 | dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) |
153 | #define RR(reg) \ | 136 | #define RR(reg) \ |
@@ -251,7 +234,7 @@ static void dispc_save_context(void) | |||
251 | if (dss_has_feature(FEAT_CORE_CLK_DIV)) | 234 | if (dss_has_feature(FEAT_CORE_CLK_DIV)) |
252 | SR(DIVISOR); | 235 | SR(DIVISOR); |
253 | 236 | ||
254 | dispc.ctx_loss_cnt = dispc_get_ctx_loss_count(); | 237 | dispc.ctx_loss_cnt = dss_get_ctx_loss_count(&dispc.pdev->dev); |
255 | dispc.ctx_valid = true; | 238 | dispc.ctx_valid = true; |
256 | 239 | ||
257 | DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt); | 240 | DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt); |
@@ -266,7 +249,7 @@ static void dispc_restore_context(void) | |||
266 | if (!dispc.ctx_valid) | 249 | if (!dispc.ctx_valid) |
267 | return; | 250 | return; |
268 | 251 | ||
269 | ctx = dispc_get_ctx_loss_count(); | 252 | ctx = dss_get_ctx_loss_count(&dispc.pdev->dev); |
270 | 253 | ||
271 | if (ctx >= 0 && ctx == dispc.ctx_loss_cnt) | 254 | if (ctx >= 0 && ctx == dispc.ctx_loss_cnt) |
272 | return; | 255 | return; |
@@ -413,14 +396,6 @@ static inline bool dispc_mgr_is_lcd(enum omap_channel channel) | |||
413 | return false; | 396 | return false; |
414 | } | 397 | } |
415 | 398 | ||
416 | static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel) | ||
417 | { | ||
418 | struct omap_overlay_manager *mgr = | ||
419 | omap_dss_get_overlay_manager(channel); | ||
420 | |||
421 | return mgr ? mgr->device : NULL; | ||
422 | } | ||
423 | |||
424 | u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) | 399 | u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) |
425 | { | 400 | { |
426 | switch (channel) { | 401 | switch (channel) { |
@@ -432,6 +407,7 @@ u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) | |||
432 | return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; | 407 | return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; |
433 | default: | 408 | default: |
434 | BUG(); | 409 | BUG(); |
410 | return 0; | ||
435 | } | 411 | } |
436 | } | 412 | } |
437 | 413 | ||
@@ -446,6 +422,7 @@ u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) | |||
446 | return 0; | 422 | return 0; |
447 | default: | 423 | default: |
448 | BUG(); | 424 | BUG(); |
425 | return 0; | ||
449 | } | 426 | } |
450 | } | 427 | } |
451 | 428 | ||
@@ -764,7 +741,7 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane, | |||
764 | case OMAP_DSS_COLOR_XRGB16_1555: | 741 | case OMAP_DSS_COLOR_XRGB16_1555: |
765 | m = 0xf; break; | 742 | m = 0xf; break; |
766 | default: | 743 | default: |
767 | BUG(); break; | 744 | BUG(); return; |
768 | } | 745 | } |
769 | } else { | 746 | } else { |
770 | switch (color_mode) { | 747 | switch (color_mode) { |
@@ -801,13 +778,25 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane, | |||
801 | case OMAP_DSS_COLOR_XRGB16_1555: | 778 | case OMAP_DSS_COLOR_XRGB16_1555: |
802 | m = 0xf; break; | 779 | m = 0xf; break; |
803 | default: | 780 | default: |
804 | BUG(); break; | 781 | BUG(); return; |
805 | } | 782 | } |
806 | } | 783 | } |
807 | 784 | ||
808 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); | 785 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); |
809 | } | 786 | } |
810 | 787 | ||
788 | static void dispc_ovl_configure_burst_type(enum omap_plane plane, | ||
789 | enum omap_dss_rotation_type rotation_type) | ||
790 | { | ||
791 | if (dss_has_feature(FEAT_BURST_2D) == 0) | ||
792 | return; | ||
793 | |||
794 | if (rotation_type == OMAP_DSS_ROT_TILER) | ||
795 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 1, 29, 29); | ||
796 | else | ||
797 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 0, 29, 29); | ||
798 | } | ||
799 | |||
811 | void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) | 800 | void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) |
812 | { | 801 | { |
813 | int shift; | 802 | int shift; |
@@ -845,6 +834,7 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) | |||
845 | break; | 834 | break; |
846 | default: | 835 | default: |
847 | BUG(); | 836 | BUG(); |
837 | return; | ||
848 | } | 838 | } |
849 | 839 | ||
850 | val = FLD_MOD(val, chan, shift, shift); | 840 | val = FLD_MOD(val, chan, shift, shift); |
@@ -872,6 +862,7 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) | |||
872 | break; | 862 | break; |
873 | default: | 863 | default: |
874 | BUG(); | 864 | BUG(); |
865 | return 0; | ||
875 | } | 866 | } |
876 | 867 | ||
877 | val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); | 868 | val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); |
@@ -983,20 +974,13 @@ static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable) | |||
983 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift); | 974 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift); |
984 | } | 975 | } |
985 | 976 | ||
986 | void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height) | 977 | static void dispc_mgr_set_size(enum omap_channel channel, u16 width, |
978 | u16 height) | ||
987 | { | 979 | { |
988 | u32 val; | 980 | u32 val; |
989 | BUG_ON((width > (1 << 11)) || (height > (1 << 11))); | ||
990 | val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); | ||
991 | dispc_write_reg(DISPC_SIZE_MGR(channel), val); | ||
992 | } | ||
993 | 981 | ||
994 | void dispc_set_digit_size(u16 width, u16 height) | ||
995 | { | ||
996 | u32 val; | ||
997 | BUG_ON((width > (1 << 11)) || (height > (1 << 11))); | ||
998 | val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); | 982 | val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); |
999 | dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val); | 983 | dispc_write_reg(DISPC_SIZE_MGR(channel), val); |
1000 | } | 984 | } |
1001 | 985 | ||
1002 | static void dispc_read_plane_fifo_sizes(void) | 986 | static void dispc_read_plane_fifo_sizes(void) |
@@ -1063,7 +1047,8 @@ void dispc_enable_fifomerge(bool enable) | |||
1063 | } | 1047 | } |
1064 | 1048 | ||
1065 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | 1049 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, |
1066 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge) | 1050 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, |
1051 | bool manual_update) | ||
1067 | { | 1052 | { |
1068 | /* | 1053 | /* |
1069 | * All sizes are in bytes. Both the buffer and burst are made of | 1054 | * All sizes are in bytes. Both the buffer and burst are made of |
@@ -1091,7 +1076,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | |||
1091 | * combined fifo size | 1076 | * combined fifo size |
1092 | */ | 1077 | */ |
1093 | 1078 | ||
1094 | if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { | 1079 | if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { |
1095 | *fifo_low = ovl_fifo_size - burst_size * 2; | 1080 | *fifo_low = ovl_fifo_size - burst_size * 2; |
1096 | *fifo_high = total_fifo_size - burst_size; | 1081 | *fifo_high = total_fifo_size - burst_size; |
1097 | } else { | 1082 | } else { |
@@ -1185,6 +1170,94 @@ static void dispc_ovl_set_scale_param(enum omap_plane plane, | |||
1185 | dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp); | 1170 | dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp); |
1186 | } | 1171 | } |
1187 | 1172 | ||
1173 | static void dispc_ovl_set_accu_uv(enum omap_plane plane, | ||
1174 | u16 orig_width, u16 orig_height, u16 out_width, u16 out_height, | ||
1175 | bool ilace, enum omap_color_mode color_mode, u8 rotation) | ||
1176 | { | ||
1177 | int h_accu2_0, h_accu2_1; | ||
1178 | int v_accu2_0, v_accu2_1; | ||
1179 | int chroma_hinc, chroma_vinc; | ||
1180 | int idx; | ||
1181 | |||
1182 | struct accu { | ||
1183 | s8 h0_m, h0_n; | ||
1184 | s8 h1_m, h1_n; | ||
1185 | s8 v0_m, v0_n; | ||
1186 | s8 v1_m, v1_n; | ||
1187 | }; | ||
1188 | |||
1189 | const struct accu *accu_table; | ||
1190 | const struct accu *accu_val; | ||
1191 | |||
1192 | static const struct accu accu_nv12[4] = { | ||
1193 | { 0, 1, 0, 1 , -1, 2, 0, 1 }, | ||
1194 | { 1, 2, -3, 4 , 0, 1, 0, 1 }, | ||
1195 | { -1, 1, 0, 1 , -1, 2, 0, 1 }, | ||
1196 | { -1, 2, -1, 2 , -1, 1, 0, 1 }, | ||
1197 | }; | ||
1198 | |||
1199 | static const struct accu accu_nv12_ilace[4] = { | ||
1200 | { 0, 1, 0, 1 , -3, 4, -1, 4 }, | ||
1201 | { -1, 4, -3, 4 , 0, 1, 0, 1 }, | ||
1202 | { -1, 1, 0, 1 , -1, 4, -3, 4 }, | ||
1203 | { -3, 4, -3, 4 , -1, 1, 0, 1 }, | ||
1204 | }; | ||
1205 | |||
1206 | static const struct accu accu_yuv[4] = { | ||
1207 | { 0, 1, 0, 1, 0, 1, 0, 1 }, | ||
1208 | { 0, 1, 0, 1, 0, 1, 0, 1 }, | ||
1209 | { -1, 1, 0, 1, 0, 1, 0, 1 }, | ||
1210 | { 0, 1, 0, 1, -1, 1, 0, 1 }, | ||
1211 | }; | ||
1212 | |||
1213 | switch (rotation) { | ||
1214 | case OMAP_DSS_ROT_0: | ||
1215 | idx = 0; | ||
1216 | break; | ||
1217 | case OMAP_DSS_ROT_90: | ||
1218 | idx = 1; | ||
1219 | break; | ||
1220 | case OMAP_DSS_ROT_180: | ||
1221 | idx = 2; | ||
1222 | break; | ||
1223 | case OMAP_DSS_ROT_270: | ||
1224 | idx = 3; | ||
1225 | break; | ||
1226 | default: | ||
1227 | BUG(); | ||
1228 | return; | ||
1229 | } | ||
1230 | |||
1231 | switch (color_mode) { | ||
1232 | case OMAP_DSS_COLOR_NV12: | ||
1233 | if (ilace) | ||
1234 | accu_table = accu_nv12_ilace; | ||
1235 | else | ||
1236 | accu_table = accu_nv12; | ||
1237 | break; | ||
1238 | case OMAP_DSS_COLOR_YUV2: | ||
1239 | case OMAP_DSS_COLOR_UYVY: | ||
1240 | accu_table = accu_yuv; | ||
1241 | break; | ||
1242 | default: | ||
1243 | BUG(); | ||
1244 | return; | ||
1245 | } | ||
1246 | |||
1247 | accu_val = &accu_table[idx]; | ||
1248 | |||
1249 | chroma_hinc = 1024 * orig_width / out_width; | ||
1250 | chroma_vinc = 1024 * orig_height / out_height; | ||
1251 | |||
1252 | h_accu2_0 = (accu_val->h0_m * chroma_hinc / accu_val->h0_n) % 1024; | ||
1253 | h_accu2_1 = (accu_val->h1_m * chroma_hinc / accu_val->h1_n) % 1024; | ||
1254 | v_accu2_0 = (accu_val->v0_m * chroma_vinc / accu_val->v0_n) % 1024; | ||
1255 | v_accu2_1 = (accu_val->v1_m * chroma_vinc / accu_val->v1_n) % 1024; | ||
1256 | |||
1257 | dispc_ovl_set_vid_accu2_0(plane, h_accu2_0, v_accu2_0); | ||
1258 | dispc_ovl_set_vid_accu2_1(plane, h_accu2_1, v_accu2_1); | ||
1259 | } | ||
1260 | |||
1188 | static void dispc_ovl_set_scaling_common(enum omap_plane plane, | 1261 | static void dispc_ovl_set_scaling_common(enum omap_plane plane, |
1189 | u16 orig_width, u16 orig_height, | 1262 | u16 orig_width, u16 orig_height, |
1190 | u16 out_width, u16 out_height, | 1263 | u16 out_width, u16 out_height, |
@@ -1258,6 +1331,10 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
1258 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); | 1331 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); |
1259 | return; | 1332 | return; |
1260 | } | 1333 | } |
1334 | |||
1335 | dispc_ovl_set_accu_uv(plane, orig_width, orig_height, out_width, | ||
1336 | out_height, ilace, color_mode, rotation); | ||
1337 | |||
1261 | switch (color_mode) { | 1338 | switch (color_mode) { |
1262 | case OMAP_DSS_COLOR_NV12: | 1339 | case OMAP_DSS_COLOR_NV12: |
1263 | /* UV is subsampled by 2 vertically*/ | 1340 | /* UV is subsampled by 2 vertically*/ |
@@ -1280,6 +1357,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
1280 | break; | 1357 | break; |
1281 | default: | 1358 | default: |
1282 | BUG(); | 1359 | BUG(); |
1360 | return; | ||
1283 | } | 1361 | } |
1284 | 1362 | ||
1285 | if (out_width != orig_width) | 1363 | if (out_width != orig_width) |
@@ -1297,9 +1375,6 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
1297 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5); | 1375 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5); |
1298 | /* set V scaling */ | 1376 | /* set V scaling */ |
1299 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6); | 1377 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6); |
1300 | |||
1301 | dispc_ovl_set_vid_accu2_0(plane, 0x80, 0); | ||
1302 | dispc_ovl_set_vid_accu2_1(plane, 0x80, 0); | ||
1303 | } | 1378 | } |
1304 | 1379 | ||
1305 | static void dispc_ovl_set_scaling(enum omap_plane plane, | 1380 | static void dispc_ovl_set_scaling(enum omap_plane plane, |
@@ -1410,6 +1485,7 @@ static int color_mode_to_bpp(enum omap_color_mode color_mode) | |||
1410 | return 32; | 1485 | return 32; |
1411 | default: | 1486 | default: |
1412 | BUG(); | 1487 | BUG(); |
1488 | return 0; | ||
1413 | } | 1489 | } |
1414 | } | 1490 | } |
1415 | 1491 | ||
@@ -1423,6 +1499,7 @@ static s32 pixinc(int pixels, u8 ps) | |||
1423 | return 1 - (-pixels + 1) * ps; | 1499 | return 1 - (-pixels + 1) * ps; |
1424 | else | 1500 | else |
1425 | BUG(); | 1501 | BUG(); |
1502 | return 0; | ||
1426 | } | 1503 | } |
1427 | 1504 | ||
1428 | static void calc_vrfb_rotation_offset(u8 rotation, bool mirror, | 1505 | static void calc_vrfb_rotation_offset(u8 rotation, bool mirror, |
@@ -1431,7 +1508,7 @@ static void calc_vrfb_rotation_offset(u8 rotation, bool mirror, | |||
1431 | enum omap_color_mode color_mode, bool fieldmode, | 1508 | enum omap_color_mode color_mode, bool fieldmode, |
1432 | unsigned int field_offset, | 1509 | unsigned int field_offset, |
1433 | unsigned *offset0, unsigned *offset1, | 1510 | unsigned *offset0, unsigned *offset1, |
1434 | s32 *row_inc, s32 *pix_inc) | 1511 | s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim) |
1435 | { | 1512 | { |
1436 | u8 ps; | 1513 | u8 ps; |
1437 | 1514 | ||
@@ -1477,10 +1554,10 @@ static void calc_vrfb_rotation_offset(u8 rotation, bool mirror, | |||
1477 | else | 1554 | else |
1478 | *offset0 = 0; | 1555 | *offset0 = 0; |
1479 | 1556 | ||
1480 | *row_inc = pixinc(1 + (screen_width - width) + | 1557 | *row_inc = pixinc(1 + |
1481 | (fieldmode ? screen_width : 0), | 1558 | (y_predecim * screen_width - x_predecim * width) + |
1482 | ps); | 1559 | (fieldmode ? screen_width : 0), ps); |
1483 | *pix_inc = pixinc(1, ps); | 1560 | *pix_inc = pixinc(x_predecim, ps); |
1484 | break; | 1561 | break; |
1485 | 1562 | ||
1486 | case OMAP_DSS_ROT_0 + 4: | 1563 | case OMAP_DSS_ROT_0 + 4: |
@@ -1498,14 +1575,15 @@ static void calc_vrfb_rotation_offset(u8 rotation, bool mirror, | |||
1498 | *offset0 = field_offset * screen_width * ps; | 1575 | *offset0 = field_offset * screen_width * ps; |
1499 | else | 1576 | else |
1500 | *offset0 = 0; | 1577 | *offset0 = 0; |
1501 | *row_inc = pixinc(1 - (screen_width + width) - | 1578 | *row_inc = pixinc(1 - |
1502 | (fieldmode ? screen_width : 0), | 1579 | (y_predecim * screen_width + x_predecim * width) - |
1503 | ps); | 1580 | (fieldmode ? screen_width : 0), ps); |
1504 | *pix_inc = pixinc(1, ps); | 1581 | *pix_inc = pixinc(x_predecim, ps); |
1505 | break; | 1582 | break; |
1506 | 1583 | ||
1507 | default: | 1584 | default: |
1508 | BUG(); | 1585 | BUG(); |
1586 | return; | ||
1509 | } | 1587 | } |
1510 | } | 1588 | } |
1511 | 1589 | ||
@@ -1515,7 +1593,7 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, | |||
1515 | enum omap_color_mode color_mode, bool fieldmode, | 1593 | enum omap_color_mode color_mode, bool fieldmode, |
1516 | unsigned int field_offset, | 1594 | unsigned int field_offset, |
1517 | unsigned *offset0, unsigned *offset1, | 1595 | unsigned *offset0, unsigned *offset1, |
1518 | s32 *row_inc, s32 *pix_inc) | 1596 | s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim) |
1519 | { | 1597 | { |
1520 | u8 ps; | 1598 | u8 ps; |
1521 | u16 fbw, fbh; | 1599 | u16 fbw, fbh; |
@@ -1557,10 +1635,14 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, | |||
1557 | *offset0 = *offset1 + field_offset * screen_width * ps; | 1635 | *offset0 = *offset1 + field_offset * screen_width * ps; |
1558 | else | 1636 | else |
1559 | *offset0 = *offset1; | 1637 | *offset0 = *offset1; |
1560 | *row_inc = pixinc(1 + (screen_width - fbw) + | 1638 | *row_inc = pixinc(1 + |
1561 | (fieldmode ? screen_width : 0), | 1639 | (y_predecim * screen_width - fbw * x_predecim) + |
1562 | ps); | 1640 | (fieldmode ? screen_width : 0), ps); |
1563 | *pix_inc = pixinc(1, ps); | 1641 | if (color_mode == OMAP_DSS_COLOR_YUV2 || |
1642 | color_mode == OMAP_DSS_COLOR_UYVY) | ||
1643 | *pix_inc = pixinc(x_predecim, 2 * ps); | ||
1644 | else | ||
1645 | *pix_inc = pixinc(x_predecim, ps); | ||
1564 | break; | 1646 | break; |
1565 | case OMAP_DSS_ROT_90: | 1647 | case OMAP_DSS_ROT_90: |
1566 | *offset1 = screen_width * (fbh - 1) * ps; | 1648 | *offset1 = screen_width * (fbh - 1) * ps; |
@@ -1568,9 +1650,9 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, | |||
1568 | *offset0 = *offset1 + field_offset * ps; | 1650 | *offset0 = *offset1 + field_offset * ps; |
1569 | else | 1651 | else |
1570 | *offset0 = *offset1; | 1652 | *offset0 = *offset1; |
1571 | *row_inc = pixinc(screen_width * (fbh - 1) + 1 + | 1653 | *row_inc = pixinc(screen_width * (fbh * x_predecim - 1) + |
1572 | (fieldmode ? 1 : 0), ps); | 1654 | y_predecim + (fieldmode ? 1 : 0), ps); |
1573 | *pix_inc = pixinc(-screen_width, ps); | 1655 | *pix_inc = pixinc(-x_predecim * screen_width, ps); |
1574 | break; | 1656 | break; |
1575 | case OMAP_DSS_ROT_180: | 1657 | case OMAP_DSS_ROT_180: |
1576 | *offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps; | 1658 | *offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps; |
@@ -1579,10 +1661,13 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, | |||
1579 | else | 1661 | else |
1580 | *offset0 = *offset1; | 1662 | *offset0 = *offset1; |
1581 | *row_inc = pixinc(-1 - | 1663 | *row_inc = pixinc(-1 - |
1582 | (screen_width - fbw) - | 1664 | (y_predecim * screen_width - fbw * x_predecim) - |
1583 | (fieldmode ? screen_width : 0), | 1665 | (fieldmode ? screen_width : 0), ps); |
1584 | ps); | 1666 | if (color_mode == OMAP_DSS_COLOR_YUV2 || |
1585 | *pix_inc = pixinc(-1, ps); | 1667 | color_mode == OMAP_DSS_COLOR_UYVY) |
1668 | *pix_inc = pixinc(-x_predecim, 2 * ps); | ||
1669 | else | ||
1670 | *pix_inc = pixinc(-x_predecim, ps); | ||
1586 | break; | 1671 | break; |
1587 | case OMAP_DSS_ROT_270: | 1672 | case OMAP_DSS_ROT_270: |
1588 | *offset1 = (fbw - 1) * ps; | 1673 | *offset1 = (fbw - 1) * ps; |
@@ -1590,9 +1675,9 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, | |||
1590 | *offset0 = *offset1 - field_offset * ps; | 1675 | *offset0 = *offset1 - field_offset * ps; |
1591 | else | 1676 | else |
1592 | *offset0 = *offset1; | 1677 | *offset0 = *offset1; |
1593 | *row_inc = pixinc(-screen_width * (fbh - 1) - 1 - | 1678 | *row_inc = pixinc(-screen_width * (fbh * x_predecim - 1) - |
1594 | (fieldmode ? 1 : 0), ps); | 1679 | y_predecim - (fieldmode ? 1 : 0), ps); |
1595 | *pix_inc = pixinc(screen_width, ps); | 1680 | *pix_inc = pixinc(x_predecim * screen_width, ps); |
1596 | break; | 1681 | break; |
1597 | 1682 | ||
1598 | /* mirroring */ | 1683 | /* mirroring */ |
@@ -1602,10 +1687,14 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, | |||
1602 | *offset0 = *offset1 + field_offset * screen_width * ps; | 1687 | *offset0 = *offset1 + field_offset * screen_width * ps; |
1603 | else | 1688 | else |
1604 | *offset0 = *offset1; | 1689 | *offset0 = *offset1; |
1605 | *row_inc = pixinc(screen_width * 2 - 1 + | 1690 | *row_inc = pixinc(y_predecim * screen_width * 2 - 1 + |
1606 | (fieldmode ? screen_width : 0), | 1691 | (fieldmode ? screen_width : 0), |
1607 | ps); | 1692 | ps); |
1608 | *pix_inc = pixinc(-1, ps); | 1693 | if (color_mode == OMAP_DSS_COLOR_YUV2 || |
1694 | color_mode == OMAP_DSS_COLOR_UYVY) | ||
1695 | *pix_inc = pixinc(-x_predecim, 2 * ps); | ||
1696 | else | ||
1697 | *pix_inc = pixinc(-x_predecim, ps); | ||
1609 | break; | 1698 | break; |
1610 | 1699 | ||
1611 | case OMAP_DSS_ROT_90 + 4: | 1700 | case OMAP_DSS_ROT_90 + 4: |
@@ -1614,10 +1703,10 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, | |||
1614 | *offset0 = *offset1 + field_offset * ps; | 1703 | *offset0 = *offset1 + field_offset * ps; |
1615 | else | 1704 | else |
1616 | *offset0 = *offset1; | 1705 | *offset0 = *offset1; |
1617 | *row_inc = pixinc(-screen_width * (fbh - 1) + 1 + | 1706 | *row_inc = pixinc(-screen_width * (fbh * x_predecim - 1) + |
1618 | (fieldmode ? 1 : 0), | 1707 | y_predecim + (fieldmode ? 1 : 0), |
1619 | ps); | 1708 | ps); |
1620 | *pix_inc = pixinc(screen_width, ps); | 1709 | *pix_inc = pixinc(x_predecim * screen_width, ps); |
1621 | break; | 1710 | break; |
1622 | 1711 | ||
1623 | case OMAP_DSS_ROT_180 + 4: | 1712 | case OMAP_DSS_ROT_180 + 4: |
@@ -1626,10 +1715,14 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, | |||
1626 | *offset0 = *offset1 - field_offset * screen_width * ps; | 1715 | *offset0 = *offset1 - field_offset * screen_width * ps; |
1627 | else | 1716 | else |
1628 | *offset0 = *offset1; | 1717 | *offset0 = *offset1; |
1629 | *row_inc = pixinc(1 - screen_width * 2 - | 1718 | *row_inc = pixinc(1 - y_predecim * screen_width * 2 - |
1630 | (fieldmode ? screen_width : 0), | 1719 | (fieldmode ? screen_width : 0), |
1631 | ps); | 1720 | ps); |
1632 | *pix_inc = pixinc(1, ps); | 1721 | if (color_mode == OMAP_DSS_COLOR_YUV2 || |
1722 | color_mode == OMAP_DSS_COLOR_UYVY) | ||
1723 | *pix_inc = pixinc(x_predecim, 2 * ps); | ||
1724 | else | ||
1725 | *pix_inc = pixinc(x_predecim, ps); | ||
1633 | break; | 1726 | break; |
1634 | 1727 | ||
1635 | case OMAP_DSS_ROT_270 + 4: | 1728 | case OMAP_DSS_ROT_270 + 4: |
@@ -1638,34 +1731,130 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, | |||
1638 | *offset0 = *offset1 - field_offset * ps; | 1731 | *offset0 = *offset1 - field_offset * ps; |
1639 | else | 1732 | else |
1640 | *offset0 = *offset1; | 1733 | *offset0 = *offset1; |
1641 | *row_inc = pixinc(screen_width * (fbh - 1) - 1 - | 1734 | *row_inc = pixinc(screen_width * (fbh * x_predecim - 1) - |
1642 | (fieldmode ? 1 : 0), | 1735 | y_predecim - (fieldmode ? 1 : 0), |
1643 | ps); | 1736 | ps); |
1644 | *pix_inc = pixinc(-screen_width, ps); | 1737 | *pix_inc = pixinc(-x_predecim * screen_width, ps); |
1645 | break; | 1738 | break; |
1646 | 1739 | ||
1647 | default: | 1740 | default: |
1648 | BUG(); | 1741 | BUG(); |
1742 | return; | ||
1743 | } | ||
1744 | } | ||
1745 | |||
1746 | static void calc_tiler_rotation_offset(u16 screen_width, u16 width, | ||
1747 | enum omap_color_mode color_mode, bool fieldmode, | ||
1748 | unsigned int field_offset, unsigned *offset0, unsigned *offset1, | ||
1749 | s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim) | ||
1750 | { | ||
1751 | u8 ps; | ||
1752 | |||
1753 | switch (color_mode) { | ||
1754 | case OMAP_DSS_COLOR_CLUT1: | ||
1755 | case OMAP_DSS_COLOR_CLUT2: | ||
1756 | case OMAP_DSS_COLOR_CLUT4: | ||
1757 | case OMAP_DSS_COLOR_CLUT8: | ||
1758 | BUG(); | ||
1759 | return; | ||
1760 | default: | ||
1761 | ps = color_mode_to_bpp(color_mode) / 8; | ||
1762 | break; | ||
1649 | } | 1763 | } |
1764 | |||
1765 | DSSDBG("scrw %d, width %d\n", screen_width, width); | ||
1766 | |||
1767 | /* | ||
1768 | * field 0 = even field = bottom field | ||
1769 | * field 1 = odd field = top field | ||
1770 | */ | ||
1771 | *offset1 = 0; | ||
1772 | if (field_offset) | ||
1773 | *offset0 = *offset1 + field_offset * screen_width * ps; | ||
1774 | else | ||
1775 | *offset0 = *offset1; | ||
1776 | *row_inc = pixinc(1 + (y_predecim * screen_width - width * x_predecim) + | ||
1777 | (fieldmode ? screen_width : 0), ps); | ||
1778 | if (color_mode == OMAP_DSS_COLOR_YUV2 || | ||
1779 | color_mode == OMAP_DSS_COLOR_UYVY) | ||
1780 | *pix_inc = pixinc(x_predecim, 2 * ps); | ||
1781 | else | ||
1782 | *pix_inc = pixinc(x_predecim, ps); | ||
1650 | } | 1783 | } |
1651 | 1784 | ||
1652 | static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width, | 1785 | /* |
1786 | * This function is used to avoid synclosts in OMAP3, because of some | ||
1787 | * undocumented horizontal position and timing related limitations. | ||
1788 | */ | ||
1789 | static int check_horiz_timing_omap3(enum omap_channel channel, | ||
1790 | const struct omap_video_timings *t, u16 pos_x, | ||
1791 | u16 width, u16 height, u16 out_width, u16 out_height) | ||
1792 | { | ||
1793 | int DS = DIV_ROUND_UP(height, out_height); | ||
1794 | unsigned long nonactive, lclk, pclk; | ||
1795 | static const u8 limits[3] = { 8, 10, 20 }; | ||
1796 | u64 val, blank; | ||
1797 | int i; | ||
1798 | |||
1799 | nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; | ||
1800 | pclk = dispc_mgr_pclk_rate(channel); | ||
1801 | if (dispc_mgr_is_lcd(channel)) | ||
1802 | lclk = dispc_mgr_lclk_rate(channel); | ||
1803 | else | ||
1804 | lclk = dispc_fclk_rate(); | ||
1805 | |||
1806 | i = 0; | ||
1807 | if (out_height < height) | ||
1808 | i++; | ||
1809 | if (out_width < width) | ||
1810 | i++; | ||
1811 | blank = div_u64((u64)(t->hbp + t->hsw + t->hfp) * lclk, pclk); | ||
1812 | DSSDBG("blanking period + ppl = %llu (limit = %u)\n", blank, limits[i]); | ||
1813 | if (blank <= limits[i]) | ||
1814 | return -EINVAL; | ||
1815 | |||
1816 | /* | ||
1817 | * Pixel data should be prepared before visible display point starts. | ||
1818 | * So, atleast DS-2 lines must have already been fetched by DISPC | ||
1819 | * during nonactive - pos_x period. | ||
1820 | */ | ||
1821 | val = div_u64((u64)(nonactive - pos_x) * lclk, pclk); | ||
1822 | DSSDBG("(nonactive - pos_x) * pcd = %llu max(0, DS - 2) * width = %d\n", | ||
1823 | val, max(0, DS - 2) * width); | ||
1824 | if (val < max(0, DS - 2) * width) | ||
1825 | return -EINVAL; | ||
1826 | |||
1827 | /* | ||
1828 | * All lines need to be refilled during the nonactive period of which | ||
1829 | * only one line can be loaded during the active period. So, atleast | ||
1830 | * DS - 1 lines should be loaded during nonactive period. | ||
1831 | */ | ||
1832 | val = div_u64((u64)nonactive * lclk, pclk); | ||
1833 | DSSDBG("nonactive * pcd = %llu, max(0, DS - 1) * width = %d\n", | ||
1834 | val, max(0, DS - 1) * width); | ||
1835 | if (val < max(0, DS - 1) * width) | ||
1836 | return -EINVAL; | ||
1837 | |||
1838 | return 0; | ||
1839 | } | ||
1840 | |||
1841 | static unsigned long calc_core_clk_five_taps(enum omap_channel channel, | ||
1842 | const struct omap_video_timings *mgr_timings, u16 width, | ||
1653 | u16 height, u16 out_width, u16 out_height, | 1843 | u16 height, u16 out_width, u16 out_height, |
1654 | enum omap_color_mode color_mode) | 1844 | enum omap_color_mode color_mode) |
1655 | { | 1845 | { |
1656 | u32 fclk = 0; | 1846 | u32 core_clk = 0; |
1657 | u64 tmp, pclk = dispc_mgr_pclk_rate(channel); | 1847 | u64 tmp, pclk = dispc_mgr_pclk_rate(channel); |
1658 | 1848 | ||
1659 | if (height <= out_height && width <= out_width) | 1849 | if (height <= out_height && width <= out_width) |
1660 | return (unsigned long) pclk; | 1850 | return (unsigned long) pclk; |
1661 | 1851 | ||
1662 | if (height > out_height) { | 1852 | if (height > out_height) { |
1663 | struct omap_dss_device *dssdev = dispc_mgr_get_device(channel); | 1853 | unsigned int ppl = mgr_timings->x_res; |
1664 | unsigned int ppl = dssdev->panel.timings.x_res; | ||
1665 | 1854 | ||
1666 | tmp = pclk * height * out_width; | 1855 | tmp = pclk * height * out_width; |
1667 | do_div(tmp, 2 * out_height * ppl); | 1856 | do_div(tmp, 2 * out_height * ppl); |
1668 | fclk = tmp; | 1857 | core_clk = tmp; |
1669 | 1858 | ||
1670 | if (height > 2 * out_height) { | 1859 | if (height > 2 * out_height) { |
1671 | if (ppl == out_width) | 1860 | if (ppl == out_width) |
@@ -1673,23 +1862,23 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width, | |||
1673 | 1862 | ||
1674 | tmp = pclk * (height - 2 * out_height) * out_width; | 1863 | tmp = pclk * (height - 2 * out_height) * out_width; |
1675 | do_div(tmp, 2 * out_height * (ppl - out_width)); | 1864 | do_div(tmp, 2 * out_height * (ppl - out_width)); |
1676 | fclk = max(fclk, (u32) tmp); | 1865 | core_clk = max_t(u32, core_clk, tmp); |
1677 | } | 1866 | } |
1678 | } | 1867 | } |
1679 | 1868 | ||
1680 | if (width > out_width) { | 1869 | if (width > out_width) { |
1681 | tmp = pclk * width; | 1870 | tmp = pclk * width; |
1682 | do_div(tmp, out_width); | 1871 | do_div(tmp, out_width); |
1683 | fclk = max(fclk, (u32) tmp); | 1872 | core_clk = max_t(u32, core_clk, tmp); |
1684 | 1873 | ||
1685 | if (color_mode == OMAP_DSS_COLOR_RGB24U) | 1874 | if (color_mode == OMAP_DSS_COLOR_RGB24U) |
1686 | fclk <<= 1; | 1875 | core_clk <<= 1; |
1687 | } | 1876 | } |
1688 | 1877 | ||
1689 | return fclk; | 1878 | return core_clk; |
1690 | } | 1879 | } |
1691 | 1880 | ||
1692 | static unsigned long calc_fclk(enum omap_channel channel, u16 width, | 1881 | static unsigned long calc_core_clk(enum omap_channel channel, u16 width, |
1693 | u16 height, u16 out_width, u16 out_height) | 1882 | u16 height, u16 out_width, u16 out_height) |
1694 | { | 1883 | { |
1695 | unsigned int hf, vf; | 1884 | unsigned int hf, vf; |
@@ -1730,15 +1919,20 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width, | |||
1730 | } | 1919 | } |
1731 | 1920 | ||
1732 | static int dispc_ovl_calc_scaling(enum omap_plane plane, | 1921 | static int dispc_ovl_calc_scaling(enum omap_plane plane, |
1733 | enum omap_channel channel, u16 width, u16 height, | 1922 | enum omap_channel channel, |
1734 | u16 out_width, u16 out_height, | 1923 | const struct omap_video_timings *mgr_timings, |
1735 | enum omap_color_mode color_mode, bool *five_taps) | 1924 | u16 width, u16 height, u16 out_width, u16 out_height, |
1925 | enum omap_color_mode color_mode, bool *five_taps, | ||
1926 | int *x_predecim, int *y_predecim, u16 pos_x) | ||
1736 | { | 1927 | { |
1737 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | 1928 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); |
1738 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | 1929 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); |
1739 | const int maxsinglelinewidth = | 1930 | const int maxsinglelinewidth = |
1740 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); | 1931 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); |
1741 | unsigned long fclk = 0; | 1932 | const int max_decim_limit = 16; |
1933 | unsigned long core_clk = 0; | ||
1934 | int decim_x, decim_y, error, min_factor; | ||
1935 | u16 in_width, in_height, in_width_max = 0; | ||
1742 | 1936 | ||
1743 | if (width == out_width && height == out_height) | 1937 | if (width == out_width && height == out_height) |
1744 | return 0; | 1938 | return 0; |
@@ -1746,64 +1940,154 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
1746 | if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) | 1940 | if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) |
1747 | return -EINVAL; | 1941 | return -EINVAL; |
1748 | 1942 | ||
1749 | if (out_width < width / maxdownscale || | 1943 | *x_predecim = max_decim_limit; |
1750 | out_width > width * 8) | 1944 | *y_predecim = max_decim_limit; |
1945 | |||
1946 | if (color_mode == OMAP_DSS_COLOR_CLUT1 || | ||
1947 | color_mode == OMAP_DSS_COLOR_CLUT2 || | ||
1948 | color_mode == OMAP_DSS_COLOR_CLUT4 || | ||
1949 | color_mode == OMAP_DSS_COLOR_CLUT8) { | ||
1950 | *x_predecim = 1; | ||
1951 | *y_predecim = 1; | ||
1952 | *five_taps = false; | ||
1953 | return 0; | ||
1954 | } | ||
1955 | |||
1956 | decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale); | ||
1957 | decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale); | ||
1958 | |||
1959 | min_factor = min(decim_x, decim_y); | ||
1960 | |||
1961 | if (decim_x > *x_predecim || out_width > width * 8) | ||
1751 | return -EINVAL; | 1962 | return -EINVAL; |
1752 | 1963 | ||
1753 | if (out_height < height / maxdownscale || | 1964 | if (decim_y > *y_predecim || out_height > height * 8) |
1754 | out_height > height * 8) | ||
1755 | return -EINVAL; | 1965 | return -EINVAL; |
1756 | 1966 | ||
1757 | if (cpu_is_omap24xx()) { | 1967 | if (cpu_is_omap24xx()) { |
1758 | if (width > maxsinglelinewidth) | ||
1759 | DSSERR("Cannot scale max input width exceeded"); | ||
1760 | *five_taps = false; | 1968 | *five_taps = false; |
1761 | fclk = calc_fclk(channel, width, height, out_width, | 1969 | |
1762 | out_height); | 1970 | do { |
1971 | in_height = DIV_ROUND_UP(height, decim_y); | ||
1972 | in_width = DIV_ROUND_UP(width, decim_x); | ||
1973 | core_clk = calc_core_clk(channel, in_width, in_height, | ||
1974 | out_width, out_height); | ||
1975 | error = (in_width > maxsinglelinewidth || !core_clk || | ||
1976 | core_clk > dispc_core_clk_rate()); | ||
1977 | if (error) { | ||
1978 | if (decim_x == decim_y) { | ||
1979 | decim_x = min_factor; | ||
1980 | decim_y++; | ||
1981 | } else { | ||
1982 | swap(decim_x, decim_y); | ||
1983 | if (decim_x < decim_y) | ||
1984 | decim_x++; | ||
1985 | } | ||
1986 | } | ||
1987 | } while (decim_x <= *x_predecim && decim_y <= *y_predecim && | ||
1988 | error); | ||
1989 | |||
1990 | if (in_width > maxsinglelinewidth) { | ||
1991 | DSSERR("Cannot scale max input width exceeded"); | ||
1992 | return -EINVAL; | ||
1993 | } | ||
1763 | } else if (cpu_is_omap34xx()) { | 1994 | } else if (cpu_is_omap34xx()) { |
1764 | if (width > (maxsinglelinewidth * 2)) { | 1995 | |
1996 | do { | ||
1997 | in_height = DIV_ROUND_UP(height, decim_y); | ||
1998 | in_width = DIV_ROUND_UP(width, decim_x); | ||
1999 | core_clk = calc_core_clk_five_taps(channel, mgr_timings, | ||
2000 | in_width, in_height, out_width, out_height, | ||
2001 | color_mode); | ||
2002 | |||
2003 | error = check_horiz_timing_omap3(channel, mgr_timings, | ||
2004 | pos_x, in_width, in_height, out_width, | ||
2005 | out_height); | ||
2006 | |||
2007 | if (in_width > maxsinglelinewidth) | ||
2008 | if (in_height > out_height && | ||
2009 | in_height < out_height * 2) | ||
2010 | *five_taps = false; | ||
2011 | if (!*five_taps) | ||
2012 | core_clk = calc_core_clk(channel, in_width, | ||
2013 | in_height, out_width, out_height); | ||
2014 | error = (error || in_width > maxsinglelinewidth * 2 || | ||
2015 | (in_width > maxsinglelinewidth && *five_taps) || | ||
2016 | !core_clk || core_clk > dispc_core_clk_rate()); | ||
2017 | if (error) { | ||
2018 | if (decim_x == decim_y) { | ||
2019 | decim_x = min_factor; | ||
2020 | decim_y++; | ||
2021 | } else { | ||
2022 | swap(decim_x, decim_y); | ||
2023 | if (decim_x < decim_y) | ||
2024 | decim_x++; | ||
2025 | } | ||
2026 | } | ||
2027 | } while (decim_x <= *x_predecim && decim_y <= *y_predecim | ||
2028 | && error); | ||
2029 | |||
2030 | if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, | ||
2031 | height, out_width, out_height)){ | ||
2032 | DSSERR("horizontal timing too tight\n"); | ||
2033 | return -EINVAL; | ||
2034 | } | ||
2035 | |||
2036 | if (in_width > (maxsinglelinewidth * 2)) { | ||
1765 | DSSERR("Cannot setup scaling"); | 2037 | DSSERR("Cannot setup scaling"); |
1766 | DSSERR("width exceeds maximum width possible"); | 2038 | DSSERR("width exceeds maximum width possible"); |
1767 | return -EINVAL; | 2039 | return -EINVAL; |
1768 | } | 2040 | } |
1769 | fclk = calc_fclk_five_taps(channel, width, height, out_width, | 2041 | |
1770 | out_height, color_mode); | 2042 | if (in_width > maxsinglelinewidth && *five_taps) { |
1771 | if (width > maxsinglelinewidth) { | 2043 | DSSERR("cannot setup scaling with five taps"); |
1772 | if (height > out_height && height < out_height * 2) | 2044 | return -EINVAL; |
1773 | *five_taps = false; | ||
1774 | else { | ||
1775 | DSSERR("cannot setup scaling with five taps"); | ||
1776 | return -EINVAL; | ||
1777 | } | ||
1778 | } | 2045 | } |
1779 | if (!*five_taps) | ||
1780 | fclk = calc_fclk(channel, width, height, out_width, | ||
1781 | out_height); | ||
1782 | } else { | 2046 | } else { |
1783 | if (width > maxsinglelinewidth) { | 2047 | int decim_x_min = decim_x; |
2048 | in_height = DIV_ROUND_UP(height, decim_y); | ||
2049 | in_width_max = dispc_core_clk_rate() / | ||
2050 | DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), | ||
2051 | out_width); | ||
2052 | decim_x = DIV_ROUND_UP(width, in_width_max); | ||
2053 | |||
2054 | decim_x = decim_x > decim_x_min ? decim_x : decim_x_min; | ||
2055 | if (decim_x > *x_predecim) | ||
2056 | return -EINVAL; | ||
2057 | |||
2058 | do { | ||
2059 | in_width = DIV_ROUND_UP(width, decim_x); | ||
2060 | } while (decim_x <= *x_predecim && | ||
2061 | in_width > maxsinglelinewidth && decim_x++); | ||
2062 | |||
2063 | if (in_width > maxsinglelinewidth) { | ||
1784 | DSSERR("Cannot scale width exceeds max line width"); | 2064 | DSSERR("Cannot scale width exceeds max line width"); |
1785 | return -EINVAL; | 2065 | return -EINVAL; |
1786 | } | 2066 | } |
1787 | fclk = calc_fclk(channel, width, height, out_width, | 2067 | |
1788 | out_height); | 2068 | core_clk = calc_core_clk(channel, in_width, in_height, |
2069 | out_width, out_height); | ||
1789 | } | 2070 | } |
1790 | 2071 | ||
1791 | DSSDBG("required fclk rate = %lu Hz\n", fclk); | 2072 | DSSDBG("required core clk rate = %lu Hz\n", core_clk); |
1792 | DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); | 2073 | DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate()); |
1793 | 2074 | ||
1794 | if (!fclk || fclk > dispc_fclk_rate()) { | 2075 | if (!core_clk || core_clk > dispc_core_clk_rate()) { |
1795 | DSSERR("failed to set up scaling, " | 2076 | DSSERR("failed to set up scaling, " |
1796 | "required fclk rate = %lu Hz, " | 2077 | "required core clk rate = %lu Hz, " |
1797 | "current fclk rate = %lu Hz\n", | 2078 | "current core clk rate = %lu Hz\n", |
1798 | fclk, dispc_fclk_rate()); | 2079 | core_clk, dispc_core_clk_rate()); |
1799 | return -EINVAL; | 2080 | return -EINVAL; |
1800 | } | 2081 | } |
1801 | 2082 | ||
2083 | *x_predecim = decim_x; | ||
2084 | *y_predecim = decim_y; | ||
1802 | return 0; | 2085 | return 0; |
1803 | } | 2086 | } |
1804 | 2087 | ||
1805 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 2088 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, |
1806 | bool ilace, bool replication) | 2089 | bool ilace, bool replication, |
2090 | const struct omap_video_timings *mgr_timings) | ||
1807 | { | 2091 | { |
1808 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | 2092 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); |
1809 | bool five_taps = true; | 2093 | bool five_taps = true; |
@@ -1814,8 +2098,11 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | |||
1814 | s32 pix_inc; | 2098 | s32 pix_inc; |
1815 | u16 frame_height = oi->height; | 2099 | u16 frame_height = oi->height; |
1816 | unsigned int field_offset = 0; | 2100 | unsigned int field_offset = 0; |
1817 | u16 outw, outh; | 2101 | u16 in_height = oi->height; |
2102 | u16 in_width = oi->width; | ||
2103 | u16 out_width, out_height; | ||
1818 | enum omap_channel channel; | 2104 | enum omap_channel channel; |
2105 | int x_predecim = 1, y_predecim = 1; | ||
1819 | 2106 | ||
1820 | channel = dispc_ovl_get_channel_out(plane); | 2107 | channel = dispc_ovl_get_channel_out(plane); |
1821 | 2108 | ||
@@ -1829,32 +2116,35 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | |||
1829 | if (oi->paddr == 0) | 2116 | if (oi->paddr == 0) |
1830 | return -EINVAL; | 2117 | return -EINVAL; |
1831 | 2118 | ||
1832 | outw = oi->out_width == 0 ? oi->width : oi->out_width; | 2119 | out_width = oi->out_width == 0 ? oi->width : oi->out_width; |
1833 | outh = oi->out_height == 0 ? oi->height : oi->out_height; | 2120 | out_height = oi->out_height == 0 ? oi->height : oi->out_height; |
1834 | 2121 | ||
1835 | if (ilace && oi->height == outh) | 2122 | if (ilace && oi->height == out_height) |
1836 | fieldmode = 1; | 2123 | fieldmode = 1; |
1837 | 2124 | ||
1838 | if (ilace) { | 2125 | if (ilace) { |
1839 | if (fieldmode) | 2126 | if (fieldmode) |
1840 | oi->height /= 2; | 2127 | in_height /= 2; |
1841 | oi->pos_y /= 2; | 2128 | oi->pos_y /= 2; |
1842 | outh /= 2; | 2129 | out_height /= 2; |
1843 | 2130 | ||
1844 | DSSDBG("adjusting for ilace: height %d, pos_y %d, " | 2131 | DSSDBG("adjusting for ilace: height %d, pos_y %d, " |
1845 | "out_height %d\n", | 2132 | "out_height %d\n", |
1846 | oi->height, oi->pos_y, outh); | 2133 | in_height, oi->pos_y, out_height); |
1847 | } | 2134 | } |
1848 | 2135 | ||
1849 | if (!dss_feat_color_mode_supported(plane, oi->color_mode)) | 2136 | if (!dss_feat_color_mode_supported(plane, oi->color_mode)) |
1850 | return -EINVAL; | 2137 | return -EINVAL; |
1851 | 2138 | ||
1852 | r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height, | 2139 | r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width, |
1853 | outw, outh, oi->color_mode, | 2140 | in_height, out_width, out_height, oi->color_mode, |
1854 | &five_taps); | 2141 | &five_taps, &x_predecim, &y_predecim, oi->pos_x); |
1855 | if (r) | 2142 | if (r) |
1856 | return r; | 2143 | return r; |
1857 | 2144 | ||
2145 | in_width = DIV_ROUND_UP(in_width, x_predecim); | ||
2146 | in_height = DIV_ROUND_UP(in_height, y_predecim); | ||
2147 | |||
1858 | if (oi->color_mode == OMAP_DSS_COLOR_YUV2 || | 2148 | if (oi->color_mode == OMAP_DSS_COLOR_YUV2 || |
1859 | oi->color_mode == OMAP_DSS_COLOR_UYVY || | 2149 | oi->color_mode == OMAP_DSS_COLOR_UYVY || |
1860 | oi->color_mode == OMAP_DSS_COLOR_NV12) | 2150 | oi->color_mode == OMAP_DSS_COLOR_NV12) |
@@ -1868,32 +2158,46 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | |||
1868 | * so the integer part must be added to the base address of the | 2158 | * so the integer part must be added to the base address of the |
1869 | * bottom field. | 2159 | * bottom field. |
1870 | */ | 2160 | */ |
1871 | if (!oi->height || oi->height == outh) | 2161 | if (!in_height || in_height == out_height) |
1872 | field_offset = 0; | 2162 | field_offset = 0; |
1873 | else | 2163 | else |
1874 | field_offset = oi->height / outh / 2; | 2164 | field_offset = in_height / out_height / 2; |
1875 | } | 2165 | } |
1876 | 2166 | ||
1877 | /* Fields are independent but interleaved in memory. */ | 2167 | /* Fields are independent but interleaved in memory. */ |
1878 | if (fieldmode) | 2168 | if (fieldmode) |
1879 | field_offset = 1; | 2169 | field_offset = 1; |
1880 | 2170 | ||
1881 | if (oi->rotation_type == OMAP_DSS_ROT_DMA) | 2171 | offset0 = 0; |
2172 | offset1 = 0; | ||
2173 | row_inc = 0; | ||
2174 | pix_inc = 0; | ||
2175 | |||
2176 | if (oi->rotation_type == OMAP_DSS_ROT_TILER) | ||
2177 | calc_tiler_rotation_offset(oi->screen_width, in_width, | ||
2178 | oi->color_mode, fieldmode, field_offset, | ||
2179 | &offset0, &offset1, &row_inc, &pix_inc, | ||
2180 | x_predecim, y_predecim); | ||
2181 | else if (oi->rotation_type == OMAP_DSS_ROT_DMA) | ||
1882 | calc_dma_rotation_offset(oi->rotation, oi->mirror, | 2182 | calc_dma_rotation_offset(oi->rotation, oi->mirror, |
1883 | oi->screen_width, oi->width, frame_height, | 2183 | oi->screen_width, in_width, frame_height, |
1884 | oi->color_mode, fieldmode, field_offset, | 2184 | oi->color_mode, fieldmode, field_offset, |
1885 | &offset0, &offset1, &row_inc, &pix_inc); | 2185 | &offset0, &offset1, &row_inc, &pix_inc, |
2186 | x_predecim, y_predecim); | ||
1886 | else | 2187 | else |
1887 | calc_vrfb_rotation_offset(oi->rotation, oi->mirror, | 2188 | calc_vrfb_rotation_offset(oi->rotation, oi->mirror, |
1888 | oi->screen_width, oi->width, frame_height, | 2189 | oi->screen_width, in_width, frame_height, |
1889 | oi->color_mode, fieldmode, field_offset, | 2190 | oi->color_mode, fieldmode, field_offset, |
1890 | &offset0, &offset1, &row_inc, &pix_inc); | 2191 | &offset0, &offset1, &row_inc, &pix_inc, |
2192 | x_predecim, y_predecim); | ||
1891 | 2193 | ||
1892 | DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", | 2194 | DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", |
1893 | offset0, offset1, row_inc, pix_inc); | 2195 | offset0, offset1, row_inc, pix_inc); |
1894 | 2196 | ||
1895 | dispc_ovl_set_color_mode(plane, oi->color_mode); | 2197 | dispc_ovl_set_color_mode(plane, oi->color_mode); |
1896 | 2198 | ||
2199 | dispc_ovl_configure_burst_type(plane, oi->rotation_type); | ||
2200 | |||
1897 | dispc_ovl_set_ba0(plane, oi->paddr + offset0); | 2201 | dispc_ovl_set_ba0(plane, oi->paddr + offset0); |
1898 | dispc_ovl_set_ba1(plane, oi->paddr + offset1); | 2202 | dispc_ovl_set_ba1(plane, oi->paddr + offset1); |
1899 | 2203 | ||
@@ -1906,19 +2210,18 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | |||
1906 | dispc_ovl_set_row_inc(plane, row_inc); | 2210 | dispc_ovl_set_row_inc(plane, row_inc); |
1907 | dispc_ovl_set_pix_inc(plane, pix_inc); | 2211 | dispc_ovl_set_pix_inc(plane, pix_inc); |
1908 | 2212 | ||
1909 | DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width, | 2213 | DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width, |
1910 | oi->height, outw, outh); | 2214 | in_height, out_width, out_height); |
1911 | 2215 | ||
1912 | dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y); | 2216 | dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y); |
1913 | 2217 | ||
1914 | dispc_ovl_set_pic_size(plane, oi->width, oi->height); | 2218 | dispc_ovl_set_pic_size(plane, in_width, in_height); |
1915 | 2219 | ||
1916 | if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) { | 2220 | if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) { |
1917 | dispc_ovl_set_scaling(plane, oi->width, oi->height, | 2221 | dispc_ovl_set_scaling(plane, in_width, in_height, out_width, |
1918 | outw, outh, | 2222 | out_height, ilace, five_taps, fieldmode, |
1919 | ilace, five_taps, fieldmode, | ||
1920 | oi->color_mode, oi->rotation); | 2223 | oi->color_mode, oi->rotation); |
1921 | dispc_ovl_set_vid_size(plane, outw, outh); | 2224 | dispc_ovl_set_vid_size(plane, out_width, out_height); |
1922 | dispc_ovl_set_vid_color_conv(plane, cconv); | 2225 | dispc_ovl_set_vid_color_conv(plane, cconv); |
1923 | } | 2226 | } |
1924 | 2227 | ||
@@ -2087,8 +2390,10 @@ bool dispc_mgr_is_enabled(enum omap_channel channel) | |||
2087 | return !!REG_GET(DISPC_CONTROL, 1, 1); | 2390 | return !!REG_GET(DISPC_CONTROL, 1, 1); |
2088 | else if (channel == OMAP_DSS_CHANNEL_LCD2) | 2391 | else if (channel == OMAP_DSS_CHANNEL_LCD2) |
2089 | return !!REG_GET(DISPC_CONTROL2, 0, 0); | 2392 | return !!REG_GET(DISPC_CONTROL2, 0, 0); |
2090 | else | 2393 | else { |
2091 | BUG(); | 2394 | BUG(); |
2395 | return false; | ||
2396 | } | ||
2092 | } | 2397 | } |
2093 | 2398 | ||
2094 | void dispc_mgr_enable(enum omap_channel channel, bool enable) | 2399 | void dispc_mgr_enable(enum omap_channel channel, bool enable) |
@@ -2285,6 +2590,12 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) | |||
2285 | REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11); | 2590 | REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11); |
2286 | } | 2591 | } |
2287 | 2592 | ||
2593 | static bool _dispc_mgr_size_ok(u16 width, u16 height) | ||
2594 | { | ||
2595 | return width <= dss_feat_get_param_max(FEAT_PARAM_MGR_WIDTH) && | ||
2596 | height <= dss_feat_get_param_max(FEAT_PARAM_MGR_HEIGHT); | ||
2597 | } | ||
2598 | |||
2288 | static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, | 2599 | static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, |
2289 | int vsw, int vfp, int vbp) | 2600 | int vsw, int vfp, int vbp) |
2290 | { | 2601 | { |
@@ -2309,11 +2620,20 @@ static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, | |||
2309 | return true; | 2620 | return true; |
2310 | } | 2621 | } |
2311 | 2622 | ||
2312 | bool dispc_lcd_timings_ok(struct omap_video_timings *timings) | 2623 | bool dispc_mgr_timings_ok(enum omap_channel channel, |
2624 | const struct omap_video_timings *timings) | ||
2313 | { | 2625 | { |
2314 | return _dispc_lcd_timings_ok(timings->hsw, timings->hfp, | 2626 | bool timings_ok; |
2315 | timings->hbp, timings->vsw, | 2627 | |
2316 | timings->vfp, timings->vbp); | 2628 | timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); |
2629 | |||
2630 | if (dispc_mgr_is_lcd(channel)) | ||
2631 | timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw, | ||
2632 | timings->hfp, timings->hbp, | ||
2633 | timings->vsw, timings->vfp, | ||
2634 | timings->vbp); | ||
2635 | |||
2636 | return timings_ok; | ||
2317 | } | 2637 | } |
2318 | 2638 | ||
2319 | static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, | 2639 | static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, |
@@ -2340,37 +2660,45 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, | |||
2340 | } | 2660 | } |
2341 | 2661 | ||
2342 | /* change name to mode? */ | 2662 | /* change name to mode? */ |
2343 | void dispc_mgr_set_lcd_timings(enum omap_channel channel, | 2663 | void dispc_mgr_set_timings(enum omap_channel channel, |
2344 | struct omap_video_timings *timings) | 2664 | struct omap_video_timings *timings) |
2345 | { | 2665 | { |
2346 | unsigned xtot, ytot; | 2666 | unsigned xtot, ytot; |
2347 | unsigned long ht, vt; | 2667 | unsigned long ht, vt; |
2668 | struct omap_video_timings t = *timings; | ||
2669 | |||
2670 | DSSDBG("channel %d xres %u yres %u\n", channel, t.x_res, t.y_res); | ||
2348 | 2671 | ||
2349 | if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp, | 2672 | if (!dispc_mgr_timings_ok(channel, &t)) { |
2350 | timings->hbp, timings->vsw, | ||
2351 | timings->vfp, timings->vbp)) | ||
2352 | BUG(); | 2673 | BUG(); |
2674 | return; | ||
2675 | } | ||
2676 | |||
2677 | if (dispc_mgr_is_lcd(channel)) { | ||
2678 | _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw, | ||
2679 | t.vfp, t.vbp); | ||
2680 | |||
2681 | xtot = t.x_res + t.hfp + t.hsw + t.hbp; | ||
2682 | ytot = t.y_res + t.vfp + t.vsw + t.vbp; | ||
2353 | 2683 | ||
2354 | _dispc_mgr_set_lcd_timings(channel, timings->hsw, timings->hfp, | 2684 | ht = (timings->pixel_clock * 1000) / xtot; |
2355 | timings->hbp, timings->vsw, timings->vfp, | 2685 | vt = (timings->pixel_clock * 1000) / xtot / ytot; |
2356 | timings->vbp); | ||
2357 | 2686 | ||
2358 | dispc_mgr_set_lcd_size(channel, timings->x_res, timings->y_res); | 2687 | DSSDBG("pck %u\n", timings->pixel_clock); |
2688 | DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", | ||
2689 | t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp); | ||
2359 | 2690 | ||
2360 | xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp; | 2691 | DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); |
2361 | ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp; | 2692 | } else { |
2693 | enum dss_hdmi_venc_clk_source_select source; | ||
2362 | 2694 | ||
2363 | ht = (timings->pixel_clock * 1000) / xtot; | 2695 | source = dss_get_hdmi_venc_clk_source(); |
2364 | vt = (timings->pixel_clock * 1000) / xtot / ytot; | ||
2365 | 2696 | ||
2366 | DSSDBG("channel %d xres %u yres %u\n", channel, timings->x_res, | 2697 | if (source == DSS_VENC_TV_CLK) |
2367 | timings->y_res); | 2698 | t.y_res /= 2; |
2368 | DSSDBG("pck %u\n", timings->pixel_clock); | 2699 | } |
2369 | DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", | ||
2370 | timings->hsw, timings->hfp, timings->hbp, | ||
2371 | timings->vsw, timings->vfp, timings->vbp); | ||
2372 | 2700 | ||
2373 | DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); | 2701 | dispc_mgr_set_size(channel, t.x_res, t.y_res); |
2374 | } | 2702 | } |
2375 | 2703 | ||
2376 | static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div, | 2704 | static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div, |
@@ -2411,6 +2739,7 @@ unsigned long dispc_fclk_rate(void) | |||
2411 | break; | 2739 | break; |
2412 | default: | 2740 | default: |
2413 | BUG(); | 2741 | BUG(); |
2742 | return 0; | ||
2414 | } | 2743 | } |
2415 | 2744 | ||
2416 | return r; | 2745 | return r; |
@@ -2441,6 +2770,7 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel) | |||
2441 | break; | 2770 | break; |
2442 | default: | 2771 | default: |
2443 | BUG(); | 2772 | BUG(); |
2773 | return 0; | ||
2444 | } | 2774 | } |
2445 | 2775 | ||
2446 | return r / lcd; | 2776 | return r / lcd; |
@@ -2462,20 +2792,35 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel) | |||
2462 | 2792 | ||
2463 | return r / pcd; | 2793 | return r / pcd; |
2464 | } else { | 2794 | } else { |
2465 | struct omap_dss_device *dssdev = | 2795 | enum dss_hdmi_venc_clk_source_select source; |
2466 | dispc_mgr_get_device(channel); | ||
2467 | 2796 | ||
2468 | switch (dssdev->type) { | 2797 | source = dss_get_hdmi_venc_clk_source(); |
2469 | case OMAP_DISPLAY_TYPE_VENC: | 2798 | |
2799 | switch (source) { | ||
2800 | case DSS_VENC_TV_CLK: | ||
2470 | return venc_get_pixel_clock(); | 2801 | return venc_get_pixel_clock(); |
2471 | case OMAP_DISPLAY_TYPE_HDMI: | 2802 | case DSS_HDMI_M_PCLK: |
2472 | return hdmi_get_pixel_clock(); | 2803 | return hdmi_get_pixel_clock(); |
2473 | default: | 2804 | default: |
2474 | BUG(); | 2805 | BUG(); |
2806 | return 0; | ||
2475 | } | 2807 | } |
2476 | } | 2808 | } |
2477 | } | 2809 | } |
2478 | 2810 | ||
2811 | unsigned long dispc_core_clk_rate(void) | ||
2812 | { | ||
2813 | int lcd; | ||
2814 | unsigned long fclk = dispc_fclk_rate(); | ||
2815 | |||
2816 | if (dss_has_feature(FEAT_CORE_CLK_DIV)) | ||
2817 | lcd = REG_GET(DISPC_DIVISOR, 23, 16); | ||
2818 | else | ||
2819 | lcd = REG_GET(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD), 23, 16); | ||
2820 | |||
2821 | return fclk / lcd; | ||
2822 | } | ||
2823 | |||
2479 | void dispc_dump_clocks(struct seq_file *s) | 2824 | void dispc_dump_clocks(struct seq_file *s) |
2480 | { | 2825 | { |
2481 | int lcd, pcd; | 2826 | int lcd, pcd; |
@@ -2588,7 +2933,7 @@ void dispc_dump_irqs(struct seq_file *s) | |||
2588 | } | 2933 | } |
2589 | #endif | 2934 | #endif |
2590 | 2935 | ||
2591 | void dispc_dump_regs(struct seq_file *s) | 2936 | static void dispc_dump_regs(struct seq_file *s) |
2592 | { | 2937 | { |
2593 | int i, j; | 2938 | int i, j; |
2594 | const char *mgr_names[] = { | 2939 | const char *mgr_names[] = { |
@@ -3247,27 +3592,6 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask, | |||
3247 | return 0; | 3592 | return 0; |
3248 | } | 3593 | } |
3249 | 3594 | ||
3250 | #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC | ||
3251 | void dispc_fake_vsync_irq(void) | ||
3252 | { | ||
3253 | u32 irqstatus = DISPC_IRQ_VSYNC; | ||
3254 | int i; | ||
3255 | |||
3256 | WARN_ON(!in_interrupt()); | ||
3257 | |||
3258 | for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { | ||
3259 | struct omap_dispc_isr_data *isr_data; | ||
3260 | isr_data = &dispc.registered_isr[i]; | ||
3261 | |||
3262 | if (!isr_data->isr) | ||
3263 | continue; | ||
3264 | |||
3265 | if (isr_data->mask & irqstatus) | ||
3266 | isr_data->isr(isr_data->arg, irqstatus); | ||
3267 | } | ||
3268 | } | ||
3269 | #endif | ||
3270 | |||
3271 | static void _omap_dispc_initialize_irq(void) | 3595 | static void _omap_dispc_initialize_irq(void) |
3272 | { | 3596 | { |
3273 | unsigned long flags; | 3597 | unsigned long flags; |
@@ -3330,7 +3654,7 @@ static void _omap_dispc_initial_config(void) | |||
3330 | } | 3654 | } |
3331 | 3655 | ||
3332 | /* DISPC HW IP initialisation */ | 3656 | /* DISPC HW IP initialisation */ |
3333 | static int omap_dispchw_probe(struct platform_device *pdev) | 3657 | static int __init omap_dispchw_probe(struct platform_device *pdev) |
3334 | { | 3658 | { |
3335 | u32 rev; | 3659 | u32 rev; |
3336 | int r = 0; | 3660 | int r = 0; |
@@ -3399,6 +3723,11 @@ static int omap_dispchw_probe(struct platform_device *pdev) | |||
3399 | 3723 | ||
3400 | dispc_runtime_put(); | 3724 | dispc_runtime_put(); |
3401 | 3725 | ||
3726 | dss_debugfs_create_file("dispc", dispc_dump_regs); | ||
3727 | |||
3728 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
3729 | dss_debugfs_create_file("dispc_irq", dispc_dump_irqs); | ||
3730 | #endif | ||
3402 | return 0; | 3731 | return 0; |
3403 | 3732 | ||
3404 | err_runtime_get: | 3733 | err_runtime_get: |
@@ -3407,7 +3736,7 @@ err_runtime_get: | |||
3407 | return r; | 3736 | return r; |
3408 | } | 3737 | } |
3409 | 3738 | ||
3410 | static int omap_dispchw_remove(struct platform_device *pdev) | 3739 | static int __exit omap_dispchw_remove(struct platform_device *pdev) |
3411 | { | 3740 | { |
3412 | pm_runtime_disable(&pdev->dev); | 3741 | pm_runtime_disable(&pdev->dev); |
3413 | 3742 | ||
@@ -3419,19 +3748,12 @@ static int omap_dispchw_remove(struct platform_device *pdev) | |||
3419 | static int dispc_runtime_suspend(struct device *dev) | 3748 | static int dispc_runtime_suspend(struct device *dev) |
3420 | { | 3749 | { |
3421 | dispc_save_context(); | 3750 | dispc_save_context(); |
3422 | dss_runtime_put(); | ||
3423 | 3751 | ||
3424 | return 0; | 3752 | return 0; |
3425 | } | 3753 | } |
3426 | 3754 | ||
3427 | static int dispc_runtime_resume(struct device *dev) | 3755 | static int dispc_runtime_resume(struct device *dev) |
3428 | { | 3756 | { |
3429 | int r; | ||
3430 | |||
3431 | r = dss_runtime_get(); | ||
3432 | if (r < 0) | ||
3433 | return r; | ||
3434 | |||
3435 | dispc_restore_context(); | 3757 | dispc_restore_context(); |
3436 | 3758 | ||
3437 | return 0; | 3759 | return 0; |
@@ -3443,8 +3765,7 @@ static const struct dev_pm_ops dispc_pm_ops = { | |||
3443 | }; | 3765 | }; |
3444 | 3766 | ||
3445 | static struct platform_driver omap_dispchw_driver = { | 3767 | static struct platform_driver omap_dispchw_driver = { |
3446 | .probe = omap_dispchw_probe, | 3768 | .remove = __exit_p(omap_dispchw_remove), |
3447 | .remove = omap_dispchw_remove, | ||
3448 | .driver = { | 3769 | .driver = { |
3449 | .name = "omapdss_dispc", | 3770 | .name = "omapdss_dispc", |
3450 | .owner = THIS_MODULE, | 3771 | .owner = THIS_MODULE, |
@@ -3452,12 +3773,12 @@ static struct platform_driver omap_dispchw_driver = { | |||
3452 | }, | 3773 | }, |
3453 | }; | 3774 | }; |
3454 | 3775 | ||
3455 | int dispc_init_platform_driver(void) | 3776 | int __init dispc_init_platform_driver(void) |
3456 | { | 3777 | { |
3457 | return platform_driver_register(&omap_dispchw_driver); | 3778 | return platform_driver_probe(&omap_dispchw_driver, omap_dispchw_probe); |
3458 | } | 3779 | } |
3459 | 3780 | ||
3460 | void dispc_uninit_platform_driver(void) | 3781 | void __exit dispc_uninit_platform_driver(void) |
3461 | { | 3782 | { |
3462 | return platform_driver_unregister(&omap_dispchw_driver); | 3783 | platform_driver_unregister(&omap_dispchw_driver); |
3463 | } | 3784 | } |
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h index 5836bd1650f9..f278080e1063 100644 --- a/drivers/video/omap2/dss/dispc.h +++ b/drivers/video/omap2/dss/dispc.h | |||
@@ -120,6 +120,7 @@ static inline u16 DISPC_DEFAULT_COLOR(enum omap_channel channel) | |||
120 | return 0x03AC; | 120 | return 0x03AC; |
121 | default: | 121 | default: |
122 | BUG(); | 122 | BUG(); |
123 | return 0; | ||
123 | } | 124 | } |
124 | } | 125 | } |
125 | 126 | ||
@@ -134,6 +135,7 @@ static inline u16 DISPC_TRANS_COLOR(enum omap_channel channel) | |||
134 | return 0x03B0; | 135 | return 0x03B0; |
135 | default: | 136 | default: |
136 | BUG(); | 137 | BUG(); |
138 | return 0; | ||
137 | } | 139 | } |
138 | } | 140 | } |
139 | 141 | ||
@@ -144,10 +146,12 @@ static inline u16 DISPC_TIMING_H(enum omap_channel channel) | |||
144 | return 0x0064; | 146 | return 0x0064; |
145 | case OMAP_DSS_CHANNEL_DIGIT: | 147 | case OMAP_DSS_CHANNEL_DIGIT: |
146 | BUG(); | 148 | BUG(); |
149 | return 0; | ||
147 | case OMAP_DSS_CHANNEL_LCD2: | 150 | case OMAP_DSS_CHANNEL_LCD2: |
148 | return 0x0400; | 151 | return 0x0400; |
149 | default: | 152 | default: |
150 | BUG(); | 153 | BUG(); |
154 | return 0; | ||
151 | } | 155 | } |
152 | } | 156 | } |
153 | 157 | ||
@@ -158,10 +162,12 @@ static inline u16 DISPC_TIMING_V(enum omap_channel channel) | |||
158 | return 0x0068; | 162 | return 0x0068; |
159 | case OMAP_DSS_CHANNEL_DIGIT: | 163 | case OMAP_DSS_CHANNEL_DIGIT: |
160 | BUG(); | 164 | BUG(); |
165 | return 0; | ||
161 | case OMAP_DSS_CHANNEL_LCD2: | 166 | case OMAP_DSS_CHANNEL_LCD2: |
162 | return 0x0404; | 167 | return 0x0404; |
163 | default: | 168 | default: |
164 | BUG(); | 169 | BUG(); |
170 | return 0; | ||
165 | } | 171 | } |
166 | } | 172 | } |
167 | 173 | ||
@@ -172,10 +178,12 @@ static inline u16 DISPC_POL_FREQ(enum omap_channel channel) | |||
172 | return 0x006C; | 178 | return 0x006C; |
173 | case OMAP_DSS_CHANNEL_DIGIT: | 179 | case OMAP_DSS_CHANNEL_DIGIT: |
174 | BUG(); | 180 | BUG(); |
181 | return 0; | ||
175 | case OMAP_DSS_CHANNEL_LCD2: | 182 | case OMAP_DSS_CHANNEL_LCD2: |
176 | return 0x0408; | 183 | return 0x0408; |
177 | default: | 184 | default: |
178 | BUG(); | 185 | BUG(); |
186 | return 0; | ||
179 | } | 187 | } |
180 | } | 188 | } |
181 | 189 | ||
@@ -186,10 +194,12 @@ static inline u16 DISPC_DIVISORo(enum omap_channel channel) | |||
186 | return 0x0070; | 194 | return 0x0070; |
187 | case OMAP_DSS_CHANNEL_DIGIT: | 195 | case OMAP_DSS_CHANNEL_DIGIT: |
188 | BUG(); | 196 | BUG(); |
197 | return 0; | ||
189 | case OMAP_DSS_CHANNEL_LCD2: | 198 | case OMAP_DSS_CHANNEL_LCD2: |
190 | return 0x040C; | 199 | return 0x040C; |
191 | default: | 200 | default: |
192 | BUG(); | 201 | BUG(); |
202 | return 0; | ||
193 | } | 203 | } |
194 | } | 204 | } |
195 | 205 | ||
@@ -205,6 +215,7 @@ static inline u16 DISPC_SIZE_MGR(enum omap_channel channel) | |||
205 | return 0x03CC; | 215 | return 0x03CC; |
206 | default: | 216 | default: |
207 | BUG(); | 217 | BUG(); |
218 | return 0; | ||
208 | } | 219 | } |
209 | } | 220 | } |
210 | 221 | ||
@@ -215,10 +226,12 @@ static inline u16 DISPC_DATA_CYCLE1(enum omap_channel channel) | |||
215 | return 0x01D4; | 226 | return 0x01D4; |
216 | case OMAP_DSS_CHANNEL_DIGIT: | 227 | case OMAP_DSS_CHANNEL_DIGIT: |
217 | BUG(); | 228 | BUG(); |
229 | return 0; | ||
218 | case OMAP_DSS_CHANNEL_LCD2: | 230 | case OMAP_DSS_CHANNEL_LCD2: |
219 | return 0x03C0; | 231 | return 0x03C0; |
220 | default: | 232 | default: |
221 | BUG(); | 233 | BUG(); |
234 | return 0; | ||
222 | } | 235 | } |
223 | } | 236 | } |
224 | 237 | ||
@@ -229,10 +242,12 @@ static inline u16 DISPC_DATA_CYCLE2(enum omap_channel channel) | |||
229 | return 0x01D8; | 242 | return 0x01D8; |
230 | case OMAP_DSS_CHANNEL_DIGIT: | 243 | case OMAP_DSS_CHANNEL_DIGIT: |
231 | BUG(); | 244 | BUG(); |
245 | return 0; | ||
232 | case OMAP_DSS_CHANNEL_LCD2: | 246 | case OMAP_DSS_CHANNEL_LCD2: |
233 | return 0x03C4; | 247 | return 0x03C4; |
234 | default: | 248 | default: |
235 | BUG(); | 249 | BUG(); |
250 | return 0; | ||
236 | } | 251 | } |
237 | } | 252 | } |
238 | 253 | ||
@@ -243,10 +258,12 @@ static inline u16 DISPC_DATA_CYCLE3(enum omap_channel channel) | |||
243 | return 0x01DC; | 258 | return 0x01DC; |
244 | case OMAP_DSS_CHANNEL_DIGIT: | 259 | case OMAP_DSS_CHANNEL_DIGIT: |
245 | BUG(); | 260 | BUG(); |
261 | return 0; | ||
246 | case OMAP_DSS_CHANNEL_LCD2: | 262 | case OMAP_DSS_CHANNEL_LCD2: |
247 | return 0x03C8; | 263 | return 0x03C8; |
248 | default: | 264 | default: |
249 | BUG(); | 265 | BUG(); |
266 | return 0; | ||
250 | } | 267 | } |
251 | } | 268 | } |
252 | 269 | ||
@@ -257,10 +274,12 @@ static inline u16 DISPC_CPR_COEF_R(enum omap_channel channel) | |||
257 | return 0x0220; | 274 | return 0x0220; |
258 | case OMAP_DSS_CHANNEL_DIGIT: | 275 | case OMAP_DSS_CHANNEL_DIGIT: |
259 | BUG(); | 276 | BUG(); |
277 | return 0; | ||
260 | case OMAP_DSS_CHANNEL_LCD2: | 278 | case OMAP_DSS_CHANNEL_LCD2: |
261 | return 0x03BC; | 279 | return 0x03BC; |
262 | default: | 280 | default: |
263 | BUG(); | 281 | BUG(); |
282 | return 0; | ||
264 | } | 283 | } |
265 | } | 284 | } |
266 | 285 | ||
@@ -271,10 +290,12 @@ static inline u16 DISPC_CPR_COEF_G(enum omap_channel channel) | |||
271 | return 0x0224; | 290 | return 0x0224; |
272 | case OMAP_DSS_CHANNEL_DIGIT: | 291 | case OMAP_DSS_CHANNEL_DIGIT: |
273 | BUG(); | 292 | BUG(); |
293 | return 0; | ||
274 | case OMAP_DSS_CHANNEL_LCD2: | 294 | case OMAP_DSS_CHANNEL_LCD2: |
275 | return 0x03B8; | 295 | return 0x03B8; |
276 | default: | 296 | default: |
277 | BUG(); | 297 | BUG(); |
298 | return 0; | ||
278 | } | 299 | } |
279 | } | 300 | } |
280 | 301 | ||
@@ -285,10 +306,12 @@ static inline u16 DISPC_CPR_COEF_B(enum omap_channel channel) | |||
285 | return 0x0228; | 306 | return 0x0228; |
286 | case OMAP_DSS_CHANNEL_DIGIT: | 307 | case OMAP_DSS_CHANNEL_DIGIT: |
287 | BUG(); | 308 | BUG(); |
309 | return 0; | ||
288 | case OMAP_DSS_CHANNEL_LCD2: | 310 | case OMAP_DSS_CHANNEL_LCD2: |
289 | return 0x03B4; | 311 | return 0x03B4; |
290 | default: | 312 | default: |
291 | BUG(); | 313 | BUG(); |
314 | return 0; | ||
292 | } | 315 | } |
293 | } | 316 | } |
294 | 317 | ||
@@ -306,6 +329,7 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane) | |||
306 | return 0x0300; | 329 | return 0x0300; |
307 | default: | 330 | default: |
308 | BUG(); | 331 | BUG(); |
332 | return 0; | ||
309 | } | 333 | } |
310 | } | 334 | } |
311 | 335 | ||
@@ -321,6 +345,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane) | |||
321 | return 0x0008; | 345 | return 0x0008; |
322 | default: | 346 | default: |
323 | BUG(); | 347 | BUG(); |
348 | return 0; | ||
324 | } | 349 | } |
325 | } | 350 | } |
326 | 351 | ||
@@ -335,6 +360,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane) | |||
335 | return 0x000C; | 360 | return 0x000C; |
336 | default: | 361 | default: |
337 | BUG(); | 362 | BUG(); |
363 | return 0; | ||
338 | } | 364 | } |
339 | } | 365 | } |
340 | 366 | ||
@@ -343,6 +369,7 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane) | |||
343 | switch (plane) { | 369 | switch (plane) { |
344 | case OMAP_DSS_GFX: | 370 | case OMAP_DSS_GFX: |
345 | BUG(); | 371 | BUG(); |
372 | return 0; | ||
346 | case OMAP_DSS_VIDEO1: | 373 | case OMAP_DSS_VIDEO1: |
347 | return 0x0544; | 374 | return 0x0544; |
348 | case OMAP_DSS_VIDEO2: | 375 | case OMAP_DSS_VIDEO2: |
@@ -351,6 +378,7 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane) | |||
351 | return 0x0310; | 378 | return 0x0310; |
352 | default: | 379 | default: |
353 | BUG(); | 380 | BUG(); |
381 | return 0; | ||
354 | } | 382 | } |
355 | } | 383 | } |
356 | 384 | ||
@@ -359,6 +387,7 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane) | |||
359 | switch (plane) { | 387 | switch (plane) { |
360 | case OMAP_DSS_GFX: | 388 | case OMAP_DSS_GFX: |
361 | BUG(); | 389 | BUG(); |
390 | return 0; | ||
362 | case OMAP_DSS_VIDEO1: | 391 | case OMAP_DSS_VIDEO1: |
363 | return 0x0548; | 392 | return 0x0548; |
364 | case OMAP_DSS_VIDEO2: | 393 | case OMAP_DSS_VIDEO2: |
@@ -367,6 +396,7 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane) | |||
367 | return 0x0314; | 396 | return 0x0314; |
368 | default: | 397 | default: |
369 | BUG(); | 398 | BUG(); |
399 | return 0; | ||
370 | } | 400 | } |
371 | } | 401 | } |
372 | 402 | ||
@@ -381,6 +411,7 @@ static inline u16 DISPC_POS_OFFSET(enum omap_plane plane) | |||
381 | return 0x009C; | 411 | return 0x009C; |
382 | default: | 412 | default: |
383 | BUG(); | 413 | BUG(); |
414 | return 0; | ||
384 | } | 415 | } |
385 | } | 416 | } |
386 | 417 | ||
@@ -395,6 +426,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane) | |||
395 | return 0x00A8; | 426 | return 0x00A8; |
396 | default: | 427 | default: |
397 | BUG(); | 428 | BUG(); |
429 | return 0; | ||
398 | } | 430 | } |
399 | } | 431 | } |
400 | 432 | ||
@@ -410,6 +442,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane) | |||
410 | return 0x0070; | 442 | return 0x0070; |
411 | default: | 443 | default: |
412 | BUG(); | 444 | BUG(); |
445 | return 0; | ||
413 | } | 446 | } |
414 | } | 447 | } |
415 | 448 | ||
@@ -418,6 +451,7 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane) | |||
418 | switch (plane) { | 451 | switch (plane) { |
419 | case OMAP_DSS_GFX: | 452 | case OMAP_DSS_GFX: |
420 | BUG(); | 453 | BUG(); |
454 | return 0; | ||
421 | case OMAP_DSS_VIDEO1: | 455 | case OMAP_DSS_VIDEO1: |
422 | return 0x0568; | 456 | return 0x0568; |
423 | case OMAP_DSS_VIDEO2: | 457 | case OMAP_DSS_VIDEO2: |
@@ -426,6 +460,7 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane) | |||
426 | return 0x032C; | 460 | return 0x032C; |
427 | default: | 461 | default: |
428 | BUG(); | 462 | BUG(); |
463 | return 0; | ||
429 | } | 464 | } |
430 | } | 465 | } |
431 | 466 | ||
@@ -441,6 +476,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane) | |||
441 | return 0x008C; | 476 | return 0x008C; |
442 | default: | 477 | default: |
443 | BUG(); | 478 | BUG(); |
479 | return 0; | ||
444 | } | 480 | } |
445 | } | 481 | } |
446 | 482 | ||
@@ -456,6 +492,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane) | |||
456 | return 0x0088; | 492 | return 0x0088; |
457 | default: | 493 | default: |
458 | BUG(); | 494 | BUG(); |
495 | return 0; | ||
459 | } | 496 | } |
460 | } | 497 | } |
461 | 498 | ||
@@ -471,6 +508,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane) | |||
471 | return 0x00A4; | 508 | return 0x00A4; |
472 | default: | 509 | default: |
473 | BUG(); | 510 | BUG(); |
511 | return 0; | ||
474 | } | 512 | } |
475 | } | 513 | } |
476 | 514 | ||
@@ -486,6 +524,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane) | |||
486 | return 0x0098; | 524 | return 0x0098; |
487 | default: | 525 | default: |
488 | BUG(); | 526 | BUG(); |
527 | return 0; | ||
489 | } | 528 | } |
490 | } | 529 | } |
491 | 530 | ||
@@ -498,8 +537,10 @@ static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane) | |||
498 | case OMAP_DSS_VIDEO2: | 537 | case OMAP_DSS_VIDEO2: |
499 | case OMAP_DSS_VIDEO3: | 538 | case OMAP_DSS_VIDEO3: |
500 | BUG(); | 539 | BUG(); |
540 | return 0; | ||
501 | default: | 541 | default: |
502 | BUG(); | 542 | BUG(); |
543 | return 0; | ||
503 | } | 544 | } |
504 | } | 545 | } |
505 | 546 | ||
@@ -512,8 +553,10 @@ static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane) | |||
512 | case OMAP_DSS_VIDEO2: | 553 | case OMAP_DSS_VIDEO2: |
513 | case OMAP_DSS_VIDEO3: | 554 | case OMAP_DSS_VIDEO3: |
514 | BUG(); | 555 | BUG(); |
556 | return 0; | ||
515 | default: | 557 | default: |
516 | BUG(); | 558 | BUG(); |
559 | return 0; | ||
517 | } | 560 | } |
518 | } | 561 | } |
519 | 562 | ||
@@ -522,6 +565,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane) | |||
522 | switch (plane) { | 565 | switch (plane) { |
523 | case OMAP_DSS_GFX: | 566 | case OMAP_DSS_GFX: |
524 | BUG(); | 567 | BUG(); |
568 | return 0; | ||
525 | case OMAP_DSS_VIDEO1: | 569 | case OMAP_DSS_VIDEO1: |
526 | case OMAP_DSS_VIDEO2: | 570 | case OMAP_DSS_VIDEO2: |
527 | return 0x0024; | 571 | return 0x0024; |
@@ -529,6 +573,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane) | |||
529 | return 0x0090; | 573 | return 0x0090; |
530 | default: | 574 | default: |
531 | BUG(); | 575 | BUG(); |
576 | return 0; | ||
532 | } | 577 | } |
533 | } | 578 | } |
534 | 579 | ||
@@ -537,6 +582,7 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane) | |||
537 | switch (plane) { | 582 | switch (plane) { |
538 | case OMAP_DSS_GFX: | 583 | case OMAP_DSS_GFX: |
539 | BUG(); | 584 | BUG(); |
585 | return 0; | ||
540 | case OMAP_DSS_VIDEO1: | 586 | case OMAP_DSS_VIDEO1: |
541 | return 0x0580; | 587 | return 0x0580; |
542 | case OMAP_DSS_VIDEO2: | 588 | case OMAP_DSS_VIDEO2: |
@@ -545,6 +591,7 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane) | |||
545 | return 0x0424; | 591 | return 0x0424; |
546 | default: | 592 | default: |
547 | BUG(); | 593 | BUG(); |
594 | return 0; | ||
548 | } | 595 | } |
549 | } | 596 | } |
550 | 597 | ||
@@ -553,6 +600,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane) | |||
553 | switch (plane) { | 600 | switch (plane) { |
554 | case OMAP_DSS_GFX: | 601 | case OMAP_DSS_GFX: |
555 | BUG(); | 602 | BUG(); |
603 | return 0; | ||
556 | case OMAP_DSS_VIDEO1: | 604 | case OMAP_DSS_VIDEO1: |
557 | case OMAP_DSS_VIDEO2: | 605 | case OMAP_DSS_VIDEO2: |
558 | return 0x0028; | 606 | return 0x0028; |
@@ -560,6 +608,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane) | |||
560 | return 0x0094; | 608 | return 0x0094; |
561 | default: | 609 | default: |
562 | BUG(); | 610 | BUG(); |
611 | return 0; | ||
563 | } | 612 | } |
564 | } | 613 | } |
565 | 614 | ||
@@ -569,6 +618,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane) | |||
569 | switch (plane) { | 618 | switch (plane) { |
570 | case OMAP_DSS_GFX: | 619 | case OMAP_DSS_GFX: |
571 | BUG(); | 620 | BUG(); |
621 | return 0; | ||
572 | case OMAP_DSS_VIDEO1: | 622 | case OMAP_DSS_VIDEO1: |
573 | case OMAP_DSS_VIDEO2: | 623 | case OMAP_DSS_VIDEO2: |
574 | return 0x002C; | 624 | return 0x002C; |
@@ -576,6 +626,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane) | |||
576 | return 0x0000; | 626 | return 0x0000; |
577 | default: | 627 | default: |
578 | BUG(); | 628 | BUG(); |
629 | return 0; | ||
579 | } | 630 | } |
580 | } | 631 | } |
581 | 632 | ||
@@ -584,6 +635,7 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane) | |||
584 | switch (plane) { | 635 | switch (plane) { |
585 | case OMAP_DSS_GFX: | 636 | case OMAP_DSS_GFX: |
586 | BUG(); | 637 | BUG(); |
638 | return 0; | ||
587 | case OMAP_DSS_VIDEO1: | 639 | case OMAP_DSS_VIDEO1: |
588 | return 0x0584; | 640 | return 0x0584; |
589 | case OMAP_DSS_VIDEO2: | 641 | case OMAP_DSS_VIDEO2: |
@@ -592,6 +644,7 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane) | |||
592 | return 0x0428; | 644 | return 0x0428; |
593 | default: | 645 | default: |
594 | BUG(); | 646 | BUG(); |
647 | return 0; | ||
595 | } | 648 | } |
596 | } | 649 | } |
597 | 650 | ||
@@ -600,6 +653,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane) | |||
600 | switch (plane) { | 653 | switch (plane) { |
601 | case OMAP_DSS_GFX: | 654 | case OMAP_DSS_GFX: |
602 | BUG(); | 655 | BUG(); |
656 | return 0; | ||
603 | case OMAP_DSS_VIDEO1: | 657 | case OMAP_DSS_VIDEO1: |
604 | case OMAP_DSS_VIDEO2: | 658 | case OMAP_DSS_VIDEO2: |
605 | return 0x0030; | 659 | return 0x0030; |
@@ -607,6 +661,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane) | |||
607 | return 0x0004; | 661 | return 0x0004; |
608 | default: | 662 | default: |
609 | BUG(); | 663 | BUG(); |
664 | return 0; | ||
610 | } | 665 | } |
611 | } | 666 | } |
612 | 667 | ||
@@ -615,6 +670,7 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane) | |||
615 | switch (plane) { | 670 | switch (plane) { |
616 | case OMAP_DSS_GFX: | 671 | case OMAP_DSS_GFX: |
617 | BUG(); | 672 | BUG(); |
673 | return 0; | ||
618 | case OMAP_DSS_VIDEO1: | 674 | case OMAP_DSS_VIDEO1: |
619 | return 0x0588; | 675 | return 0x0588; |
620 | case OMAP_DSS_VIDEO2: | 676 | case OMAP_DSS_VIDEO2: |
@@ -623,6 +679,7 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane) | |||
623 | return 0x042C; | 679 | return 0x042C; |
624 | default: | 680 | default: |
625 | BUG(); | 681 | BUG(); |
682 | return 0; | ||
626 | } | 683 | } |
627 | } | 684 | } |
628 | 685 | ||
@@ -632,6 +689,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i) | |||
632 | switch (plane) { | 689 | switch (plane) { |
633 | case OMAP_DSS_GFX: | 690 | case OMAP_DSS_GFX: |
634 | BUG(); | 691 | BUG(); |
692 | return 0; | ||
635 | case OMAP_DSS_VIDEO1: | 693 | case OMAP_DSS_VIDEO1: |
636 | case OMAP_DSS_VIDEO2: | 694 | case OMAP_DSS_VIDEO2: |
637 | return 0x0034 + i * 0x8; | 695 | return 0x0034 + i * 0x8; |
@@ -639,6 +697,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i) | |||
639 | return 0x0010 + i * 0x8; | 697 | return 0x0010 + i * 0x8; |
640 | default: | 698 | default: |
641 | BUG(); | 699 | BUG(); |
700 | return 0; | ||
642 | } | 701 | } |
643 | } | 702 | } |
644 | 703 | ||
@@ -648,6 +707,7 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i) | |||
648 | switch (plane) { | 707 | switch (plane) { |
649 | case OMAP_DSS_GFX: | 708 | case OMAP_DSS_GFX: |
650 | BUG(); | 709 | BUG(); |
710 | return 0; | ||
651 | case OMAP_DSS_VIDEO1: | 711 | case OMAP_DSS_VIDEO1: |
652 | return 0x058C + i * 0x8; | 712 | return 0x058C + i * 0x8; |
653 | case OMAP_DSS_VIDEO2: | 713 | case OMAP_DSS_VIDEO2: |
@@ -656,6 +716,7 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i) | |||
656 | return 0x0430 + i * 0x8; | 716 | return 0x0430 + i * 0x8; |
657 | default: | 717 | default: |
658 | BUG(); | 718 | BUG(); |
719 | return 0; | ||
659 | } | 720 | } |
660 | } | 721 | } |
661 | 722 | ||
@@ -665,6 +726,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i) | |||
665 | switch (plane) { | 726 | switch (plane) { |
666 | case OMAP_DSS_GFX: | 727 | case OMAP_DSS_GFX: |
667 | BUG(); | 728 | BUG(); |
729 | return 0; | ||
668 | case OMAP_DSS_VIDEO1: | 730 | case OMAP_DSS_VIDEO1: |
669 | case OMAP_DSS_VIDEO2: | 731 | case OMAP_DSS_VIDEO2: |
670 | return 0x0038 + i * 0x8; | 732 | return 0x0038 + i * 0x8; |
@@ -672,6 +734,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i) | |||
672 | return 0x0014 + i * 0x8; | 734 | return 0x0014 + i * 0x8; |
673 | default: | 735 | default: |
674 | BUG(); | 736 | BUG(); |
737 | return 0; | ||
675 | } | 738 | } |
676 | } | 739 | } |
677 | 740 | ||
@@ -681,6 +744,7 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i) | |||
681 | switch (plane) { | 744 | switch (plane) { |
682 | case OMAP_DSS_GFX: | 745 | case OMAP_DSS_GFX: |
683 | BUG(); | 746 | BUG(); |
747 | return 0; | ||
684 | case OMAP_DSS_VIDEO1: | 748 | case OMAP_DSS_VIDEO1: |
685 | return 0x0590 + i * 8; | 749 | return 0x0590 + i * 8; |
686 | case OMAP_DSS_VIDEO2: | 750 | case OMAP_DSS_VIDEO2: |
@@ -689,6 +753,7 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i) | |||
689 | return 0x0434 + i * 0x8; | 753 | return 0x0434 + i * 0x8; |
690 | default: | 754 | default: |
691 | BUG(); | 755 | BUG(); |
756 | return 0; | ||
692 | } | 757 | } |
693 | } | 758 | } |
694 | 759 | ||
@@ -698,12 +763,14 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i) | |||
698 | switch (plane) { | 763 | switch (plane) { |
699 | case OMAP_DSS_GFX: | 764 | case OMAP_DSS_GFX: |
700 | BUG(); | 765 | BUG(); |
766 | return 0; | ||
701 | case OMAP_DSS_VIDEO1: | 767 | case OMAP_DSS_VIDEO1: |
702 | case OMAP_DSS_VIDEO2: | 768 | case OMAP_DSS_VIDEO2: |
703 | case OMAP_DSS_VIDEO3: | 769 | case OMAP_DSS_VIDEO3: |
704 | return 0x0074 + i * 0x4; | 770 | return 0x0074 + i * 0x4; |
705 | default: | 771 | default: |
706 | BUG(); | 772 | BUG(); |
773 | return 0; | ||
707 | } | 774 | } |
708 | } | 775 | } |
709 | 776 | ||
@@ -713,6 +780,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i) | |||
713 | switch (plane) { | 780 | switch (plane) { |
714 | case OMAP_DSS_GFX: | 781 | case OMAP_DSS_GFX: |
715 | BUG(); | 782 | BUG(); |
783 | return 0; | ||
716 | case OMAP_DSS_VIDEO1: | 784 | case OMAP_DSS_VIDEO1: |
717 | return 0x0124 + i * 0x4; | 785 | return 0x0124 + i * 0x4; |
718 | case OMAP_DSS_VIDEO2: | 786 | case OMAP_DSS_VIDEO2: |
@@ -721,6 +789,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i) | |||
721 | return 0x0050 + i * 0x4; | 789 | return 0x0050 + i * 0x4; |
722 | default: | 790 | default: |
723 | BUG(); | 791 | BUG(); |
792 | return 0; | ||
724 | } | 793 | } |
725 | } | 794 | } |
726 | 795 | ||
@@ -730,6 +799,7 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i) | |||
730 | switch (plane) { | 799 | switch (plane) { |
731 | case OMAP_DSS_GFX: | 800 | case OMAP_DSS_GFX: |
732 | BUG(); | 801 | BUG(); |
802 | return 0; | ||
733 | case OMAP_DSS_VIDEO1: | 803 | case OMAP_DSS_VIDEO1: |
734 | return 0x05CC + i * 0x4; | 804 | return 0x05CC + i * 0x4; |
735 | case OMAP_DSS_VIDEO2: | 805 | case OMAP_DSS_VIDEO2: |
@@ -738,6 +808,7 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i) | |||
738 | return 0x0470 + i * 0x4; | 808 | return 0x0470 + i * 0x4; |
739 | default: | 809 | default: |
740 | BUG(); | 810 | BUG(); |
811 | return 0; | ||
741 | } | 812 | } |
742 | } | 813 | } |
743 | 814 | ||
@@ -754,6 +825,7 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane) | |||
754 | return 0x00A0; | 825 | return 0x00A0; |
755 | default: | 826 | default: |
756 | BUG(); | 827 | BUG(); |
828 | return 0; | ||
757 | } | 829 | } |
758 | } | 830 | } |
759 | #endif | 831 | #endif |
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 4424c198dbcd..249010630370 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c | |||
@@ -304,10 +304,18 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) | |||
304 | return 24; | 304 | return 24; |
305 | default: | 305 | default: |
306 | BUG(); | 306 | BUG(); |
307 | return 0; | ||
307 | } | 308 | } |
308 | } | 309 | } |
309 | EXPORT_SYMBOL(omapdss_default_get_recommended_bpp); | 310 | EXPORT_SYMBOL(omapdss_default_get_recommended_bpp); |
310 | 311 | ||
312 | void omapdss_default_get_timings(struct omap_dss_device *dssdev, | ||
313 | struct omap_video_timings *timings) | ||
314 | { | ||
315 | *timings = dssdev->panel.timings; | ||
316 | } | ||
317 | EXPORT_SYMBOL(omapdss_default_get_timings); | ||
318 | |||
311 | /* Checks if replication logic should be used. Only use for active matrix, | 319 | /* Checks if replication logic should be used. Only use for active matrix, |
312 | * when overlay is in RGB12U or RGB16 mode, and LCD interface is | 320 | * when overlay is in RGB12U or RGB16 mode, and LCD interface is |
313 | * 18bpp or 24bpp */ | 321 | * 18bpp or 24bpp */ |
@@ -340,6 +348,7 @@ bool dss_use_replication(struct omap_dss_device *dssdev, | |||
340 | break; | 348 | break; |
341 | default: | 349 | default: |
342 | BUG(); | 350 | BUG(); |
351 | return false; | ||
343 | } | 352 | } |
344 | 353 | ||
345 | return bpp > 16; | 354 | return bpp > 16; |
@@ -352,46 +361,6 @@ void dss_init_device(struct platform_device *pdev, | |||
352 | int i; | 361 | int i; |
353 | int r; | 362 | int r; |
354 | 363 | ||
355 | switch (dssdev->type) { | ||
356 | #ifdef CONFIG_OMAP2_DSS_DPI | ||
357 | case OMAP_DISPLAY_TYPE_DPI: | ||
358 | r = dpi_init_display(dssdev); | ||
359 | break; | ||
360 | #endif | ||
361 | #ifdef CONFIG_OMAP2_DSS_RFBI | ||
362 | case OMAP_DISPLAY_TYPE_DBI: | ||
363 | r = rfbi_init_display(dssdev); | ||
364 | break; | ||
365 | #endif | ||
366 | #ifdef CONFIG_OMAP2_DSS_VENC | ||
367 | case OMAP_DISPLAY_TYPE_VENC: | ||
368 | r = venc_init_display(dssdev); | ||
369 | break; | ||
370 | #endif | ||
371 | #ifdef CONFIG_OMAP2_DSS_SDI | ||
372 | case OMAP_DISPLAY_TYPE_SDI: | ||
373 | r = sdi_init_display(dssdev); | ||
374 | break; | ||
375 | #endif | ||
376 | #ifdef CONFIG_OMAP2_DSS_DSI | ||
377 | case OMAP_DISPLAY_TYPE_DSI: | ||
378 | r = dsi_init_display(dssdev); | ||
379 | break; | ||
380 | #endif | ||
381 | case OMAP_DISPLAY_TYPE_HDMI: | ||
382 | r = hdmi_init_display(dssdev); | ||
383 | break; | ||
384 | default: | ||
385 | DSSERR("Support for display '%s' not compiled in.\n", | ||
386 | dssdev->name); | ||
387 | return; | ||
388 | } | ||
389 | |||
390 | if (r) { | ||
391 | DSSERR("failed to init display %s\n", dssdev->name); | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | /* create device sysfs files */ | 364 | /* create device sysfs files */ |
396 | i = 0; | 365 | i = 0; |
397 | while ((attr = display_sysfs_attrs[i++]) != NULL) { | 366 | while ((attr = display_sysfs_attrs[i++]) != NULL) { |
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index faaf305fda27..8c2056c9537b 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c | |||
@@ -156,7 +156,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev) | |||
156 | t->pixel_clock = pck; | 156 | t->pixel_clock = pck; |
157 | } | 157 | } |
158 | 158 | ||
159 | dispc_mgr_set_lcd_timings(dssdev->manager->id, t); | 159 | dss_mgr_set_timings(dssdev->manager, t); |
160 | 160 | ||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
@@ -202,10 +202,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | |||
202 | goto err_reg_enable; | 202 | goto err_reg_enable; |
203 | } | 203 | } |
204 | 204 | ||
205 | r = dss_runtime_get(); | ||
206 | if (r) | ||
207 | goto err_get_dss; | ||
208 | |||
209 | r = dispc_runtime_get(); | 205 | r = dispc_runtime_get(); |
210 | if (r) | 206 | if (r) |
211 | goto err_get_dispc; | 207 | goto err_get_dispc; |
@@ -244,8 +240,6 @@ err_dsi_pll_init: | |||
244 | err_get_dsi: | 240 | err_get_dsi: |
245 | dispc_runtime_put(); | 241 | dispc_runtime_put(); |
246 | err_get_dispc: | 242 | err_get_dispc: |
247 | dss_runtime_put(); | ||
248 | err_get_dss: | ||
249 | if (cpu_is_omap34xx()) | 243 | if (cpu_is_omap34xx()) |
250 | regulator_disable(dpi.vdds_dsi_reg); | 244 | regulator_disable(dpi.vdds_dsi_reg); |
251 | err_reg_enable: | 245 | err_reg_enable: |
@@ -266,7 +260,6 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) | |||
266 | } | 260 | } |
267 | 261 | ||
268 | dispc_runtime_put(); | 262 | dispc_runtime_put(); |
269 | dss_runtime_put(); | ||
270 | 263 | ||
271 | if (cpu_is_omap34xx()) | 264 | if (cpu_is_omap34xx()) |
272 | regulator_disable(dpi.vdds_dsi_reg); | 265 | regulator_disable(dpi.vdds_dsi_reg); |
@@ -283,21 +276,15 @@ void dpi_set_timings(struct omap_dss_device *dssdev, | |||
283 | DSSDBG("dpi_set_timings\n"); | 276 | DSSDBG("dpi_set_timings\n"); |
284 | dssdev->panel.timings = *timings; | 277 | dssdev->panel.timings = *timings; |
285 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | 278 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { |
286 | r = dss_runtime_get(); | ||
287 | if (r) | ||
288 | return; | ||
289 | |||
290 | r = dispc_runtime_get(); | 279 | r = dispc_runtime_get(); |
291 | if (r) { | 280 | if (r) |
292 | dss_runtime_put(); | ||
293 | return; | 281 | return; |
294 | } | ||
295 | 282 | ||
296 | dpi_set_mode(dssdev); | 283 | dpi_set_mode(dssdev); |
297 | dispc_mgr_go(dssdev->manager->id); | ||
298 | 284 | ||
299 | dispc_runtime_put(); | 285 | dispc_runtime_put(); |
300 | dss_runtime_put(); | 286 | } else { |
287 | dss_mgr_set_timings(dssdev->manager, timings); | ||
301 | } | 288 | } |
302 | } | 289 | } |
303 | EXPORT_SYMBOL(dpi_set_timings); | 290 | EXPORT_SYMBOL(dpi_set_timings); |
@@ -312,7 +299,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev, | |||
312 | unsigned long pck; | 299 | unsigned long pck; |
313 | struct dispc_clock_info dispc_cinfo; | 300 | struct dispc_clock_info dispc_cinfo; |
314 | 301 | ||
315 | if (!dispc_lcd_timings_ok(timings)) | 302 | if (dss_mgr_check_timings(dssdev->manager, timings)) |
316 | return -EINVAL; | 303 | return -EINVAL; |
317 | 304 | ||
318 | if (timings->pixel_clock == 0) | 305 | if (timings->pixel_clock == 0) |
@@ -352,7 +339,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev, | |||
352 | } | 339 | } |
353 | EXPORT_SYMBOL(dpi_check_timings); | 340 | EXPORT_SYMBOL(dpi_check_timings); |
354 | 341 | ||
355 | int dpi_init_display(struct omap_dss_device *dssdev) | 342 | static int __init dpi_init_display(struct omap_dss_device *dssdev) |
356 | { | 343 | { |
357 | DSSDBG("init_display\n"); | 344 | DSSDBG("init_display\n"); |
358 | 345 | ||
@@ -378,12 +365,58 @@ int dpi_init_display(struct omap_dss_device *dssdev) | |||
378 | return 0; | 365 | return 0; |
379 | } | 366 | } |
380 | 367 | ||
381 | int dpi_init(void) | 368 | static void __init dpi_probe_pdata(struct platform_device *pdev) |
382 | { | 369 | { |
370 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
371 | int i, r; | ||
372 | |||
373 | for (i = 0; i < pdata->num_devices; ++i) { | ||
374 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
375 | |||
376 | if (dssdev->type != OMAP_DISPLAY_TYPE_DPI) | ||
377 | continue; | ||
378 | |||
379 | r = dpi_init_display(dssdev); | ||
380 | if (r) { | ||
381 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
382 | continue; | ||
383 | } | ||
384 | |||
385 | r = omap_dss_register_device(dssdev, &pdev->dev, i); | ||
386 | if (r) | ||
387 | DSSERR("device %s register failed: %d\n", | ||
388 | dssdev->name, r); | ||
389 | } | ||
390 | } | ||
391 | |||
392 | static int __init omap_dpi_probe(struct platform_device *pdev) | ||
393 | { | ||
394 | dpi_probe_pdata(pdev); | ||
395 | |||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static int __exit omap_dpi_remove(struct platform_device *pdev) | ||
400 | { | ||
401 | omap_dss_unregister_child_devices(&pdev->dev); | ||
402 | |||
383 | return 0; | 403 | return 0; |
384 | } | 404 | } |
385 | 405 | ||
386 | void dpi_exit(void) | 406 | static struct platform_driver omap_dpi_driver = { |
407 | .remove = __exit_p(omap_dpi_remove), | ||
408 | .driver = { | ||
409 | .name = "omapdss_dpi", | ||
410 | .owner = THIS_MODULE, | ||
411 | }, | ||
412 | }; | ||
413 | |||
414 | int __init dpi_init_platform_driver(void) | ||
387 | { | 415 | { |
416 | return platform_driver_probe(&omap_dpi_driver, omap_dpi_probe); | ||
388 | } | 417 | } |
389 | 418 | ||
419 | void __exit dpi_uninit_platform_driver(void) | ||
420 | { | ||
421 | platform_driver_unregister(&omap_dpi_driver); | ||
422 | } | ||
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 210a3c4f6150..ec363d8390ed 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -256,14 +256,13 @@ struct dsi_data { | |||
256 | struct platform_device *pdev; | 256 | struct platform_device *pdev; |
257 | void __iomem *base; | 257 | void __iomem *base; |
258 | 258 | ||
259 | int module_id; | ||
260 | |||
259 | int irq; | 261 | int irq; |
260 | 262 | ||
261 | struct clk *dss_clk; | 263 | struct clk *dss_clk; |
262 | struct clk *sys_clk; | 264 | struct clk *sys_clk; |
263 | 265 | ||
264 | int (*enable_pads)(int dsi_id, unsigned lane_mask); | ||
265 | void (*disable_pads)(int dsi_id, unsigned lane_mask); | ||
266 | |||
267 | struct dsi_clock_info current_cinfo; | 266 | struct dsi_clock_info current_cinfo; |
268 | 267 | ||
269 | bool vdds_dsi_enabled; | 268 | bool vdds_dsi_enabled; |
@@ -361,11 +360,6 @@ struct platform_device *dsi_get_dsidev_from_id(int module) | |||
361 | return dsi_pdev_map[module]; | 360 | return dsi_pdev_map[module]; |
362 | } | 361 | } |
363 | 362 | ||
364 | static inline int dsi_get_dsidev_id(struct platform_device *dsidev) | ||
365 | { | ||
366 | return dsidev->id; | ||
367 | } | ||
368 | |||
369 | static inline void dsi_write_reg(struct platform_device *dsidev, | 363 | static inline void dsi_write_reg(struct platform_device *dsidev, |
370 | const struct dsi_reg idx, u32 val) | 364 | const struct dsi_reg idx, u32 val) |
371 | { | 365 | { |
@@ -452,6 +446,7 @@ u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt) | |||
452 | return 16; | 446 | return 16; |
453 | default: | 447 | default: |
454 | BUG(); | 448 | BUG(); |
449 | return 0; | ||
455 | } | 450 | } |
456 | } | 451 | } |
457 | 452 | ||
@@ -1184,10 +1179,9 @@ static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev) | |||
1184 | static unsigned long dsi_fclk_rate(struct platform_device *dsidev) | 1179 | static unsigned long dsi_fclk_rate(struct platform_device *dsidev) |
1185 | { | 1180 | { |
1186 | unsigned long r; | 1181 | unsigned long r; |
1187 | int dsi_module = dsi_get_dsidev_id(dsidev); | ||
1188 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1182 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1189 | 1183 | ||
1190 | if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) { | 1184 | if (dss_get_dsi_clk_source(dsi->module_id) == OMAP_DSS_CLK_SRC_FCK) { |
1191 | /* DSI FCLK source is DSS_CLK_FCK */ | 1185 | /* DSI FCLK source is DSS_CLK_FCK */ |
1192 | r = clk_get_rate(dsi->dss_clk); | 1186 | r = clk_get_rate(dsi->dss_clk); |
1193 | } else { | 1187 | } else { |
@@ -1279,10 +1273,9 @@ static int dsi_pll_power(struct platform_device *dsidev, | |||
1279 | } | 1273 | } |
1280 | 1274 | ||
1281 | /* calculate clock rates using dividers in cinfo */ | 1275 | /* calculate clock rates using dividers in cinfo */ |
1282 | static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, | 1276 | static int dsi_calc_clock_rates(struct platform_device *dsidev, |
1283 | struct dsi_clock_info *cinfo) | 1277 | struct dsi_clock_info *cinfo) |
1284 | { | 1278 | { |
1285 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
1286 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1279 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1287 | 1280 | ||
1288 | if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max) | 1281 | if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max) |
@@ -1297,21 +1290,8 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, | |||
1297 | if (cinfo->regm_dsi > dsi->regm_dsi_max) | 1290 | if (cinfo->regm_dsi > dsi->regm_dsi_max) |
1298 | return -EINVAL; | 1291 | return -EINVAL; |
1299 | 1292 | ||
1300 | if (cinfo->use_sys_clk) { | 1293 | cinfo->clkin = clk_get_rate(dsi->sys_clk); |
1301 | cinfo->clkin = clk_get_rate(dsi->sys_clk); | 1294 | cinfo->fint = cinfo->clkin / cinfo->regn; |
1302 | /* XXX it is unclear if highfreq should be used | ||
1303 | * with DSS_SYS_CLK source also */ | ||
1304 | cinfo->highfreq = 0; | ||
1305 | } else { | ||
1306 | cinfo->clkin = dispc_mgr_pclk_rate(dssdev->manager->id); | ||
1307 | |||
1308 | if (cinfo->clkin < 32000000) | ||
1309 | cinfo->highfreq = 0; | ||
1310 | else | ||
1311 | cinfo->highfreq = 1; | ||
1312 | } | ||
1313 | |||
1314 | cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); | ||
1315 | 1295 | ||
1316 | if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min) | 1296 | if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min) |
1317 | return -EINVAL; | 1297 | return -EINVAL; |
@@ -1378,27 +1358,21 @@ retry: | |||
1378 | 1358 | ||
1379 | memset(&cur, 0, sizeof(cur)); | 1359 | memset(&cur, 0, sizeof(cur)); |
1380 | cur.clkin = dss_sys_clk; | 1360 | cur.clkin = dss_sys_clk; |
1381 | cur.use_sys_clk = 1; | ||
1382 | cur.highfreq = 0; | ||
1383 | 1361 | ||
1384 | /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ | 1362 | /* 0.75MHz < Fint = clkin / regn < 2.1MHz */ |
1385 | /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ | ||
1386 | /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ | 1363 | /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ |
1387 | for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { | 1364 | for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { |
1388 | if (cur.highfreq == 0) | 1365 | cur.fint = cur.clkin / cur.regn; |
1389 | cur.fint = cur.clkin / cur.regn; | ||
1390 | else | ||
1391 | cur.fint = cur.clkin / (2 * cur.regn); | ||
1392 | 1366 | ||
1393 | if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min) | 1367 | if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min) |
1394 | continue; | 1368 | continue; |
1395 | 1369 | ||
1396 | /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ | 1370 | /* DSIPHY(MHz) = (2 * regm / regn) * clkin */ |
1397 | for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) { | 1371 | for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) { |
1398 | unsigned long a, b; | 1372 | unsigned long a, b; |
1399 | 1373 | ||
1400 | a = 2 * cur.regm * (cur.clkin/1000); | 1374 | a = 2 * cur.regm * (cur.clkin/1000); |
1401 | b = cur.regn * (cur.highfreq + 1); | 1375 | b = cur.regn; |
1402 | cur.clkin4ddr = a / b * 1000; | 1376 | cur.clkin4ddr = a / b * 1000; |
1403 | 1377 | ||
1404 | if (cur.clkin4ddr > 1800 * 1000 * 1000) | 1378 | if (cur.clkin4ddr > 1800 * 1000 * 1000) |
@@ -1486,9 +1460,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, | |||
1486 | 1460 | ||
1487 | DSSDBGF(); | 1461 | DSSDBGF(); |
1488 | 1462 | ||
1489 | dsi->current_cinfo.use_sys_clk = cinfo->use_sys_clk; | 1463 | dsi->current_cinfo.clkin = cinfo->clkin; |
1490 | dsi->current_cinfo.highfreq = cinfo->highfreq; | ||
1491 | |||
1492 | dsi->current_cinfo.fint = cinfo->fint; | 1464 | dsi->current_cinfo.fint = cinfo->fint; |
1493 | dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr; | 1465 | dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr; |
1494 | dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk = | 1466 | dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk = |
@@ -1503,17 +1475,13 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, | |||
1503 | 1475 | ||
1504 | DSSDBG("DSI Fint %ld\n", cinfo->fint); | 1476 | DSSDBG("DSI Fint %ld\n", cinfo->fint); |
1505 | 1477 | ||
1506 | DSSDBG("clkin (%s) rate %ld, highfreq %d\n", | 1478 | DSSDBG("clkin rate %ld\n", cinfo->clkin); |
1507 | cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree", | ||
1508 | cinfo->clkin, | ||
1509 | cinfo->highfreq); | ||
1510 | 1479 | ||
1511 | /* DSIPHY == CLKIN4DDR */ | 1480 | /* DSIPHY == CLKIN4DDR */ |
1512 | DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu / %d = %lu\n", | 1481 | DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu = %lu\n", |
1513 | cinfo->regm, | 1482 | cinfo->regm, |
1514 | cinfo->regn, | 1483 | cinfo->regn, |
1515 | cinfo->clkin, | 1484 | cinfo->clkin, |
1516 | cinfo->highfreq + 1, | ||
1517 | cinfo->clkin4ddr); | 1485 | cinfo->clkin4ddr); |
1518 | 1486 | ||
1519 | DSSDBG("Data rate on 1 DSI lane %ld Mbps\n", | 1487 | DSSDBG("Data rate on 1 DSI lane %ld Mbps\n", |
@@ -1568,10 +1536,6 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, | |||
1568 | 1536 | ||
1569 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) | 1537 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) |
1570 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ | 1538 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ |
1571 | l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1, | ||
1572 | 11, 11); /* DSI_PLL_CLKSEL */ | ||
1573 | l = FLD_MOD(l, cinfo->highfreq, | ||
1574 | 12, 12); /* DSI_PLL_HIGHFREQ */ | ||
1575 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ | 1539 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ |
1576 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ | 1540 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ |
1577 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ | 1541 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ |
@@ -1716,7 +1680,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, | |||
1716 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1680 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1717 | struct dsi_clock_info *cinfo = &dsi->current_cinfo; | 1681 | struct dsi_clock_info *cinfo = &dsi->current_cinfo; |
1718 | enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; | 1682 | enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; |
1719 | int dsi_module = dsi_get_dsidev_id(dsidev); | 1683 | int dsi_module = dsi->module_id; |
1720 | 1684 | ||
1721 | dispc_clk_src = dss_get_dispc_clk_source(); | 1685 | dispc_clk_src = dss_get_dispc_clk_source(); |
1722 | dsi_clk_src = dss_get_dsi_clk_source(dsi_module); | 1686 | dsi_clk_src = dss_get_dsi_clk_source(dsi_module); |
@@ -1726,8 +1690,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, | |||
1726 | 1690 | ||
1727 | seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); | 1691 | seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); |
1728 | 1692 | ||
1729 | seq_printf(s, "dsi pll source = %s\n", | 1693 | seq_printf(s, "dsi pll clkin\t%lu\n", cinfo->clkin); |
1730 | cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree"); | ||
1731 | 1694 | ||
1732 | seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); | 1695 | seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); |
1733 | 1696 | ||
@@ -1789,7 +1752,6 @@ static void dsi_dump_dsidev_irqs(struct platform_device *dsidev, | |||
1789 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1752 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1790 | unsigned long flags; | 1753 | unsigned long flags; |
1791 | struct dsi_irq_stats stats; | 1754 | struct dsi_irq_stats stats; |
1792 | int dsi_module = dsi_get_dsidev_id(dsidev); | ||
1793 | 1755 | ||
1794 | spin_lock_irqsave(&dsi->irq_stats_lock, flags); | 1756 | spin_lock_irqsave(&dsi->irq_stats_lock, flags); |
1795 | 1757 | ||
@@ -1806,7 +1768,7 @@ static void dsi_dump_dsidev_irqs(struct platform_device *dsidev, | |||
1806 | #define PIS(x) \ | 1768 | #define PIS(x) \ |
1807 | seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); | 1769 | seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); |
1808 | 1770 | ||
1809 | seq_printf(s, "-- DSI%d interrupts --\n", dsi_module + 1); | 1771 | seq_printf(s, "-- DSI%d interrupts --\n", dsi->module_id + 1); |
1810 | PIS(VC0); | 1772 | PIS(VC0); |
1811 | PIS(VC1); | 1773 | PIS(VC1); |
1812 | PIS(VC2); | 1774 | PIS(VC2); |
@@ -1886,22 +1848,6 @@ static void dsi2_dump_irqs(struct seq_file *s) | |||
1886 | 1848 | ||
1887 | dsi_dump_dsidev_irqs(dsidev, s); | 1849 | dsi_dump_dsidev_irqs(dsidev, s); |
1888 | } | 1850 | } |
1889 | |||
1890 | void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir, | ||
1891 | const struct file_operations *debug_fops) | ||
1892 | { | ||
1893 | struct platform_device *dsidev; | ||
1894 | |||
1895 | dsidev = dsi_get_dsidev_from_id(0); | ||
1896 | if (dsidev) | ||
1897 | debugfs_create_file("dsi1_irqs", S_IRUGO, debugfs_dir, | ||
1898 | &dsi1_dump_irqs, debug_fops); | ||
1899 | |||
1900 | dsidev = dsi_get_dsidev_from_id(1); | ||
1901 | if (dsidev) | ||
1902 | debugfs_create_file("dsi2_irqs", S_IRUGO, debugfs_dir, | ||
1903 | &dsi2_dump_irqs, debug_fops); | ||
1904 | } | ||
1905 | #endif | 1851 | #endif |
1906 | 1852 | ||
1907 | static void dsi_dump_dsidev_regs(struct platform_device *dsidev, | 1853 | static void dsi_dump_dsidev_regs(struct platform_device *dsidev, |
@@ -2002,21 +1948,6 @@ static void dsi2_dump_regs(struct seq_file *s) | |||
2002 | dsi_dump_dsidev_regs(dsidev, s); | 1948 | dsi_dump_dsidev_regs(dsidev, s); |
2003 | } | 1949 | } |
2004 | 1950 | ||
2005 | void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir, | ||
2006 | const struct file_operations *debug_fops) | ||
2007 | { | ||
2008 | struct platform_device *dsidev; | ||
2009 | |||
2010 | dsidev = dsi_get_dsidev_from_id(0); | ||
2011 | if (dsidev) | ||
2012 | debugfs_create_file("dsi1_regs", S_IRUGO, debugfs_dir, | ||
2013 | &dsi1_dump_regs, debug_fops); | ||
2014 | |||
2015 | dsidev = dsi_get_dsidev_from_id(1); | ||
2016 | if (dsidev) | ||
2017 | debugfs_create_file("dsi2_regs", S_IRUGO, debugfs_dir, | ||
2018 | &dsi2_dump_regs, debug_fops); | ||
2019 | } | ||
2020 | enum dsi_cio_power_state { | 1951 | enum dsi_cio_power_state { |
2021 | DSI_COMPLEXIO_POWER_OFF = 0x0, | 1952 | DSI_COMPLEXIO_POWER_OFF = 0x0, |
2022 | DSI_COMPLEXIO_POWER_ON = 0x1, | 1953 | DSI_COMPLEXIO_POWER_ON = 0x1, |
@@ -2073,6 +2004,7 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) | |||
2073 | return 1365 * 3; /* 1365x24 bits */ | 2004 | return 1365 * 3; /* 1365x24 bits */ |
2074 | default: | 2005 | default: |
2075 | BUG(); | 2006 | BUG(); |
2007 | return 0; | ||
2076 | } | 2008 | } |
2077 | } | 2009 | } |
2078 | 2010 | ||
@@ -2337,7 +2269,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) | |||
2337 | 2269 | ||
2338 | DSSDBGF(); | 2270 | DSSDBGF(); |
2339 | 2271 | ||
2340 | r = dsi->enable_pads(dsidev->id, dsi_get_lane_mask(dssdev)); | 2272 | r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); |
2341 | if (r) | 2273 | if (r) |
2342 | return r; | 2274 | return r; |
2343 | 2275 | ||
@@ -2447,7 +2379,7 @@ err_cio_pwr: | |||
2447 | dsi_cio_disable_lane_override(dsidev); | 2379 | dsi_cio_disable_lane_override(dsidev); |
2448 | err_scp_clk_dom: | 2380 | err_scp_clk_dom: |
2449 | dsi_disable_scp_clk(dsidev); | 2381 | dsi_disable_scp_clk(dsidev); |
2450 | dsi->disable_pads(dsidev->id, dsi_get_lane_mask(dssdev)); | 2382 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); |
2451 | return r; | 2383 | return r; |
2452 | } | 2384 | } |
2453 | 2385 | ||
@@ -2461,7 +2393,7 @@ static void dsi_cio_uninit(struct omap_dss_device *dssdev) | |||
2461 | 2393 | ||
2462 | dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); | 2394 | dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); |
2463 | dsi_disable_scp_clk(dsidev); | 2395 | dsi_disable_scp_clk(dsidev); |
2464 | dsi->disable_pads(dsidev->id, dsi_get_lane_mask(dssdev)); | 2396 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); |
2465 | } | 2397 | } |
2466 | 2398 | ||
2467 | static void dsi_config_tx_fifo(struct platform_device *dsidev, | 2399 | static void dsi_config_tx_fifo(struct platform_device *dsidev, |
@@ -2485,6 +2417,7 @@ static void dsi_config_tx_fifo(struct platform_device *dsidev, | |||
2485 | if (add + size > 4) { | 2417 | if (add + size > 4) { |
2486 | DSSERR("Illegal FIFO configuration\n"); | 2418 | DSSERR("Illegal FIFO configuration\n"); |
2487 | BUG(); | 2419 | BUG(); |
2420 | return; | ||
2488 | } | 2421 | } |
2489 | 2422 | ||
2490 | v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4); | 2423 | v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4); |
@@ -2517,6 +2450,7 @@ static void dsi_config_rx_fifo(struct platform_device *dsidev, | |||
2517 | if (add + size > 4) { | 2450 | if (add + size > 4) { |
2518 | DSSERR("Illegal FIFO configuration\n"); | 2451 | DSSERR("Illegal FIFO configuration\n"); |
2519 | BUG(); | 2452 | BUG(); |
2453 | return; | ||
2520 | } | 2454 | } |
2521 | 2455 | ||
2522 | v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4); | 2456 | v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4); |
@@ -2658,6 +2592,7 @@ static int dsi_sync_vc(struct platform_device *dsidev, int channel) | |||
2658 | return dsi_sync_vc_l4(dsidev, channel); | 2592 | return dsi_sync_vc_l4(dsidev, channel); |
2659 | default: | 2593 | default: |
2660 | BUG(); | 2594 | BUG(); |
2595 | return -EINVAL; | ||
2661 | } | 2596 | } |
2662 | } | 2597 | } |
2663 | 2598 | ||
@@ -3226,6 +3161,7 @@ static int dsi_vc_generic_send_read_request(struct omap_dss_device *dssdev, | |||
3226 | data = reqdata[0] | (reqdata[1] << 8); | 3161 | data = reqdata[0] | (reqdata[1] << 8); |
3227 | } else { | 3162 | } else { |
3228 | BUG(); | 3163 | BUG(); |
3164 | return -EINVAL; | ||
3229 | } | 3165 | } |
3230 | 3166 | ||
3231 | r = dsi_vc_send_short(dsidev, channel, data_type, data, 0); | 3167 | r = dsi_vc_send_short(dsidev, channel, data_type, data, 0); |
@@ -3340,7 +3276,6 @@ static int dsi_vc_read_rx_fifo(struct platform_device *dsidev, int channel, | |||
3340 | goto err; | 3276 | goto err; |
3341 | } | 3277 | } |
3342 | 3278 | ||
3343 | BUG(); | ||
3344 | err: | 3279 | err: |
3345 | DSSERR("dsi_vc_read_rx_fifo(ch %d type %s) failed\n", channel, | 3280 | DSSERR("dsi_vc_read_rx_fifo(ch %d type %s) failed\n", channel, |
3346 | type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" : "DCS"); | 3281 | type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" : "DCS"); |
@@ -3735,6 +3670,186 @@ static void dsi_config_blanking_modes(struct omap_dss_device *dssdev) | |||
3735 | dsi_write_reg(dsidev, DSI_CTRL, r); | 3670 | dsi_write_reg(dsidev, DSI_CTRL, r); |
3736 | } | 3671 | } |
3737 | 3672 | ||
3673 | /* | ||
3674 | * According to section 'HS Command Mode Interleaving' in OMAP TRM, Scenario 3 | ||
3675 | * results in maximum transition time for data and clock lanes to enter and | ||
3676 | * exit HS mode. Hence, this is the scenario where the least amount of command | ||
3677 | * mode data can be interleaved. We program the minimum amount of TXBYTECLKHS | ||
3678 | * clock cycles that can be used to interleave command mode data in HS so that | ||
3679 | * all scenarios are satisfied. | ||
3680 | */ | ||
3681 | static int dsi_compute_interleave_hs(int blank, bool ddr_alwon, int enter_hs, | ||
3682 | int exit_hs, int exiths_clk, int ddr_pre, int ddr_post) | ||
3683 | { | ||
3684 | int transition; | ||
3685 | |||
3686 | /* | ||
3687 | * If DDR_CLK_ALWAYS_ON is set, we need to consider HS mode transition | ||
3688 | * time of data lanes only, if it isn't set, we need to consider HS | ||
3689 | * transition time of both data and clock lanes. HS transition time | ||
3690 | * of Scenario 3 is considered. | ||
3691 | */ | ||
3692 | if (ddr_alwon) { | ||
3693 | transition = enter_hs + exit_hs + max(enter_hs, 2) + 1; | ||
3694 | } else { | ||
3695 | int trans1, trans2; | ||
3696 | trans1 = ddr_pre + enter_hs + exit_hs + max(enter_hs, 2) + 1; | ||
3697 | trans2 = ddr_pre + enter_hs + exiths_clk + ddr_post + ddr_pre + | ||
3698 | enter_hs + 1; | ||
3699 | transition = max(trans1, trans2); | ||
3700 | } | ||
3701 | |||
3702 | return blank > transition ? blank - transition : 0; | ||
3703 | } | ||
3704 | |||
3705 | /* | ||
3706 | * According to section 'LP Command Mode Interleaving' in OMAP TRM, Scenario 1 | ||
3707 | * results in maximum transition time for data lanes to enter and exit LP mode. | ||
3708 | * Hence, this is the scenario where the least amount of command mode data can | ||
3709 | * be interleaved. We program the minimum amount of bytes that can be | ||
3710 | * interleaved in LP so that all scenarios are satisfied. | ||
3711 | */ | ||
3712 | static int dsi_compute_interleave_lp(int blank, int enter_hs, int exit_hs, | ||
3713 | int lp_clk_div, int tdsi_fclk) | ||
3714 | { | ||
3715 | int trans_lp; /* time required for a LP transition, in TXBYTECLKHS */ | ||
3716 | int tlp_avail; /* time left for interleaving commands, in CLKIN4DDR */ | ||
3717 | int ttxclkesc; /* period of LP transmit escape clock, in CLKIN4DDR */ | ||
3718 | int thsbyte_clk = 16; /* Period of TXBYTECLKHS clock, in CLKIN4DDR */ | ||
3719 | int lp_inter; /* cmd mode data that can be interleaved, in bytes */ | ||
3720 | |||
3721 | /* maximum LP transition time according to Scenario 1 */ | ||
3722 | trans_lp = exit_hs + max(enter_hs, 2) + 1; | ||
3723 | |||
3724 | /* CLKIN4DDR = 16 * TXBYTECLKHS */ | ||
3725 | tlp_avail = thsbyte_clk * (blank - trans_lp); | ||
3726 | |||
3727 | ttxclkesc = tdsi_fclk / lp_clk_div; | ||
3728 | |||
3729 | lp_inter = ((tlp_avail - 8 * thsbyte_clk - 5 * tdsi_fclk) / ttxclkesc - | ||
3730 | 26) / 16; | ||
3731 | |||
3732 | return max(lp_inter, 0); | ||
3733 | } | ||
3734 | |||
3735 | static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev) | ||
3736 | { | ||
3737 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3738 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
3739 | int blanking_mode; | ||
3740 | int hfp_blanking_mode, hbp_blanking_mode, hsa_blanking_mode; | ||
3741 | int hsa, hfp, hbp, width_bytes, bllp, lp_clk_div; | ||
3742 | int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat; | ||
3743 | int tclk_trail, ths_exit, exiths_clk; | ||
3744 | bool ddr_alwon; | ||
3745 | struct omap_video_timings *timings = &dssdev->panel.timings; | ||
3746 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | ||
3747 | int ndl = dsi->num_lanes_used - 1; | ||
3748 | int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1; | ||
3749 | int hsa_interleave_hs = 0, hsa_interleave_lp = 0; | ||
3750 | int hfp_interleave_hs = 0, hfp_interleave_lp = 0; | ||
3751 | int hbp_interleave_hs = 0, hbp_interleave_lp = 0; | ||
3752 | int bl_interleave_hs = 0, bl_interleave_lp = 0; | ||
3753 | u32 r; | ||
3754 | |||
3755 | r = dsi_read_reg(dsidev, DSI_CTRL); | ||
3756 | blanking_mode = FLD_GET(r, 20, 20); | ||
3757 | hfp_blanking_mode = FLD_GET(r, 21, 21); | ||
3758 | hbp_blanking_mode = FLD_GET(r, 22, 22); | ||
3759 | hsa_blanking_mode = FLD_GET(r, 23, 23); | ||
3760 | |||
3761 | r = dsi_read_reg(dsidev, DSI_VM_TIMING1); | ||
3762 | hbp = FLD_GET(r, 11, 0); | ||
3763 | hfp = FLD_GET(r, 23, 12); | ||
3764 | hsa = FLD_GET(r, 31, 24); | ||
3765 | |||
3766 | r = dsi_read_reg(dsidev, DSI_CLK_TIMING); | ||
3767 | ddr_clk_post = FLD_GET(r, 7, 0); | ||
3768 | ddr_clk_pre = FLD_GET(r, 15, 8); | ||
3769 | |||
3770 | r = dsi_read_reg(dsidev, DSI_VM_TIMING7); | ||
3771 | exit_hs_mode_lat = FLD_GET(r, 15, 0); | ||
3772 | enter_hs_mode_lat = FLD_GET(r, 31, 16); | ||
3773 | |||
3774 | r = dsi_read_reg(dsidev, DSI_CLK_CTRL); | ||
3775 | lp_clk_div = FLD_GET(r, 12, 0); | ||
3776 | ddr_alwon = FLD_GET(r, 13, 13); | ||
3777 | |||
3778 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0); | ||
3779 | ths_exit = FLD_GET(r, 7, 0); | ||
3780 | |||
3781 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); | ||
3782 | tclk_trail = FLD_GET(r, 15, 8); | ||
3783 | |||
3784 | exiths_clk = ths_exit + tclk_trail; | ||
3785 | |||
3786 | width_bytes = DIV_ROUND_UP(timings->x_res * bpp, 8); | ||
3787 | bllp = hbp + hfp + hsa + DIV_ROUND_UP(width_bytes + 6, ndl); | ||
3788 | |||
3789 | if (!hsa_blanking_mode) { | ||
3790 | hsa_interleave_hs = dsi_compute_interleave_hs(hsa, ddr_alwon, | ||
3791 | enter_hs_mode_lat, exit_hs_mode_lat, | ||
3792 | exiths_clk, ddr_clk_pre, ddr_clk_post); | ||
3793 | hsa_interleave_lp = dsi_compute_interleave_lp(hsa, | ||
3794 | enter_hs_mode_lat, exit_hs_mode_lat, | ||
3795 | lp_clk_div, dsi_fclk_hsdiv); | ||
3796 | } | ||
3797 | |||
3798 | if (!hfp_blanking_mode) { | ||
3799 | hfp_interleave_hs = dsi_compute_interleave_hs(hfp, ddr_alwon, | ||
3800 | enter_hs_mode_lat, exit_hs_mode_lat, | ||
3801 | exiths_clk, ddr_clk_pre, ddr_clk_post); | ||
3802 | hfp_interleave_lp = dsi_compute_interleave_lp(hfp, | ||
3803 | enter_hs_mode_lat, exit_hs_mode_lat, | ||
3804 | lp_clk_div, dsi_fclk_hsdiv); | ||
3805 | } | ||
3806 | |||
3807 | if (!hbp_blanking_mode) { | ||
3808 | hbp_interleave_hs = dsi_compute_interleave_hs(hbp, ddr_alwon, | ||
3809 | enter_hs_mode_lat, exit_hs_mode_lat, | ||
3810 | exiths_clk, ddr_clk_pre, ddr_clk_post); | ||
3811 | |||
3812 | hbp_interleave_lp = dsi_compute_interleave_lp(hbp, | ||
3813 | enter_hs_mode_lat, exit_hs_mode_lat, | ||
3814 | lp_clk_div, dsi_fclk_hsdiv); | ||
3815 | } | ||
3816 | |||
3817 | if (!blanking_mode) { | ||
3818 | bl_interleave_hs = dsi_compute_interleave_hs(bllp, ddr_alwon, | ||
3819 | enter_hs_mode_lat, exit_hs_mode_lat, | ||
3820 | exiths_clk, ddr_clk_pre, ddr_clk_post); | ||
3821 | |||
3822 | bl_interleave_lp = dsi_compute_interleave_lp(bllp, | ||
3823 | enter_hs_mode_lat, exit_hs_mode_lat, | ||
3824 | lp_clk_div, dsi_fclk_hsdiv); | ||
3825 | } | ||
3826 | |||
3827 | DSSDBG("DSI HS interleaving(TXBYTECLKHS) HSA %d, HFP %d, HBP %d, BLLP %d\n", | ||
3828 | hsa_interleave_hs, hfp_interleave_hs, hbp_interleave_hs, | ||
3829 | bl_interleave_hs); | ||
3830 | |||
3831 | DSSDBG("DSI LP interleaving(bytes) HSA %d, HFP %d, HBP %d, BLLP %d\n", | ||
3832 | hsa_interleave_lp, hfp_interleave_lp, hbp_interleave_lp, | ||
3833 | bl_interleave_lp); | ||
3834 | |||
3835 | r = dsi_read_reg(dsidev, DSI_VM_TIMING4); | ||
3836 | r = FLD_MOD(r, hsa_interleave_hs, 23, 16); | ||
3837 | r = FLD_MOD(r, hfp_interleave_hs, 15, 8); | ||
3838 | r = FLD_MOD(r, hbp_interleave_hs, 7, 0); | ||
3839 | dsi_write_reg(dsidev, DSI_VM_TIMING4, r); | ||
3840 | |||
3841 | r = dsi_read_reg(dsidev, DSI_VM_TIMING5); | ||
3842 | r = FLD_MOD(r, hsa_interleave_lp, 23, 16); | ||
3843 | r = FLD_MOD(r, hfp_interleave_lp, 15, 8); | ||
3844 | r = FLD_MOD(r, hbp_interleave_lp, 7, 0); | ||
3845 | dsi_write_reg(dsidev, DSI_VM_TIMING5, r); | ||
3846 | |||
3847 | r = dsi_read_reg(dsidev, DSI_VM_TIMING6); | ||
3848 | r = FLD_MOD(r, bl_interleave_hs, 31, 15); | ||
3849 | r = FLD_MOD(r, bl_interleave_lp, 16, 0); | ||
3850 | dsi_write_reg(dsidev, DSI_VM_TIMING6, r); | ||
3851 | } | ||
3852 | |||
3738 | static int dsi_proto_config(struct omap_dss_device *dssdev) | 3853 | static int dsi_proto_config(struct omap_dss_device *dssdev) |
3739 | { | 3854 | { |
3740 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3855 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -3769,6 +3884,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
3769 | break; | 3884 | break; |
3770 | default: | 3885 | default: |
3771 | BUG(); | 3886 | BUG(); |
3887 | return -EINVAL; | ||
3772 | } | 3888 | } |
3773 | 3889 | ||
3774 | r = dsi_read_reg(dsidev, DSI_CTRL); | 3890 | r = dsi_read_reg(dsidev, DSI_CTRL); |
@@ -3793,6 +3909,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
3793 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 3909 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { |
3794 | dsi_config_vp_sync_events(dssdev); | 3910 | dsi_config_vp_sync_events(dssdev); |
3795 | dsi_config_blanking_modes(dssdev); | 3911 | dsi_config_blanking_modes(dssdev); |
3912 | dsi_config_cmd_mode_interleaving(dssdev); | ||
3796 | } | 3913 | } |
3797 | 3914 | ||
3798 | dsi_vc_initial_config(dsidev, 0); | 3915 | dsi_vc_initial_config(dsidev, 0); |
@@ -4008,6 +4125,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | |||
4008 | break; | 4125 | break; |
4009 | default: | 4126 | default: |
4010 | BUG(); | 4127 | BUG(); |
4128 | return -EINVAL; | ||
4011 | }; | 4129 | }; |
4012 | 4130 | ||
4013 | dsi_if_enable(dsidev, false); | 4131 | dsi_if_enable(dsidev, false); |
@@ -4192,10 +4310,6 @@ static void dsi_framedone_irq_callback(void *data, u32 mask) | |||
4192 | __cancel_delayed_work(&dsi->framedone_timeout_work); | 4310 | __cancel_delayed_work(&dsi->framedone_timeout_work); |
4193 | 4311 | ||
4194 | dsi_handle_framedone(dsidev, 0); | 4312 | dsi_handle_framedone(dsidev, 0); |
4195 | |||
4196 | #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC | ||
4197 | dispc_fake_vsync_irq(); | ||
4198 | #endif | ||
4199 | } | 4313 | } |
4200 | 4314 | ||
4201 | int omap_dsi_update(struct omap_dss_device *dssdev, int channel, | 4315 | int omap_dsi_update(struct omap_dss_device *dssdev, int channel, |
@@ -4259,13 +4373,12 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
4259 | dispc_mgr_enable_stallmode(dssdev->manager->id, true); | 4373 | dispc_mgr_enable_stallmode(dssdev->manager->id, true); |
4260 | dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1); | 4374 | dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1); |
4261 | 4375 | ||
4262 | dispc_mgr_set_lcd_timings(dssdev->manager->id, &timings); | 4376 | dss_mgr_set_timings(dssdev->manager, &timings); |
4263 | } else { | 4377 | } else { |
4264 | dispc_mgr_enable_stallmode(dssdev->manager->id, false); | 4378 | dispc_mgr_enable_stallmode(dssdev->manager->id, false); |
4265 | dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0); | 4379 | dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0); |
4266 | 4380 | ||
4267 | dispc_mgr_set_lcd_timings(dssdev->manager->id, | 4381 | dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); |
4268 | &dssdev->panel.timings); | ||
4269 | } | 4382 | } |
4270 | 4383 | ||
4271 | dispc_mgr_set_lcd_display_type(dssdev->manager->id, | 4384 | dispc_mgr_set_lcd_display_type(dssdev->manager->id, |
@@ -4294,13 +4407,11 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) | |||
4294 | struct dsi_clock_info cinfo; | 4407 | struct dsi_clock_info cinfo; |
4295 | int r; | 4408 | int r; |
4296 | 4409 | ||
4297 | /* we always use DSS_CLK_SYSCK as input clock */ | ||
4298 | cinfo.use_sys_clk = true; | ||
4299 | cinfo.regn = dssdev->clocks.dsi.regn; | 4410 | cinfo.regn = dssdev->clocks.dsi.regn; |
4300 | cinfo.regm = dssdev->clocks.dsi.regm; | 4411 | cinfo.regm = dssdev->clocks.dsi.regm; |
4301 | cinfo.regm_dispc = dssdev->clocks.dsi.regm_dispc; | 4412 | cinfo.regm_dispc = dssdev->clocks.dsi.regm_dispc; |
4302 | cinfo.regm_dsi = dssdev->clocks.dsi.regm_dsi; | 4413 | cinfo.regm_dsi = dssdev->clocks.dsi.regm_dsi; |
4303 | r = dsi_calc_clock_rates(dssdev, &cinfo); | 4414 | r = dsi_calc_clock_rates(dsidev, &cinfo); |
4304 | if (r) { | 4415 | if (r) { |
4305 | DSSERR("Failed to calc dsi clocks\n"); | 4416 | DSSERR("Failed to calc dsi clocks\n"); |
4306 | return r; | 4417 | return r; |
@@ -4345,7 +4456,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) | |||
4345 | static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | 4456 | static int dsi_display_init_dsi(struct omap_dss_device *dssdev) |
4346 | { | 4457 | { |
4347 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4458 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4348 | int dsi_module = dsi_get_dsidev_id(dsidev); | 4459 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4349 | int r; | 4460 | int r; |
4350 | 4461 | ||
4351 | r = dsi_pll_init(dsidev, true, true); | 4462 | r = dsi_pll_init(dsidev, true, true); |
@@ -4357,7 +4468,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
4357 | goto err1; | 4468 | goto err1; |
4358 | 4469 | ||
4359 | dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); | 4470 | dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); |
4360 | dss_select_dsi_clk_source(dsi_module, dssdev->clocks.dsi.dsi_fclk_src); | 4471 | dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); |
4361 | dss_select_lcd_clk_source(dssdev->manager->id, | 4472 | dss_select_lcd_clk_source(dssdev->manager->id, |
4362 | dssdev->clocks.dispc.channel.lcd_clk_src); | 4473 | dssdev->clocks.dispc.channel.lcd_clk_src); |
4363 | 4474 | ||
@@ -4396,7 +4507,7 @@ err3: | |||
4396 | dsi_cio_uninit(dssdev); | 4507 | dsi_cio_uninit(dssdev); |
4397 | err2: | 4508 | err2: |
4398 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | 4509 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); |
4399 | dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK); | 4510 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); |
4400 | dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); | 4511 | dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); |
4401 | 4512 | ||
4402 | err1: | 4513 | err1: |
@@ -4410,7 +4521,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, | |||
4410 | { | 4521 | { |
4411 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4522 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4412 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4523 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4413 | int dsi_module = dsi_get_dsidev_id(dsidev); | ||
4414 | 4524 | ||
4415 | if (enter_ulps && !dsi->ulps_enabled) | 4525 | if (enter_ulps && !dsi->ulps_enabled) |
4416 | dsi_enter_ulps(dsidev); | 4526 | dsi_enter_ulps(dsidev); |
@@ -4423,7 +4533,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, | |||
4423 | dsi_vc_enable(dsidev, 3, 0); | 4533 | dsi_vc_enable(dsidev, 3, 0); |
4424 | 4534 | ||
4425 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | 4535 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); |
4426 | dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK); | 4536 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); |
4427 | dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); | 4537 | dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); |
4428 | dsi_cio_uninit(dssdev); | 4538 | dsi_cio_uninit(dssdev); |
4429 | dsi_pll_uninit(dsidev, disconnect_lanes); | 4539 | dsi_pll_uninit(dsidev, disconnect_lanes); |
@@ -4527,7 +4637,7 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) | |||
4527 | } | 4637 | } |
4528 | EXPORT_SYMBOL(omapdss_dsi_enable_te); | 4638 | EXPORT_SYMBOL(omapdss_dsi_enable_te); |
4529 | 4639 | ||
4530 | int dsi_init_display(struct omap_dss_device *dssdev) | 4640 | static int __init dsi_init_display(struct omap_dss_device *dssdev) |
4531 | { | 4641 | { |
4532 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4642 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4533 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4643 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
@@ -4680,13 +4790,39 @@ static void dsi_put_clocks(struct platform_device *dsidev) | |||
4680 | clk_put(dsi->sys_clk); | 4790 | clk_put(dsi->sys_clk); |
4681 | } | 4791 | } |
4682 | 4792 | ||
4793 | static void __init dsi_probe_pdata(struct platform_device *dsidev) | ||
4794 | { | ||
4795 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4796 | struct omap_dss_board_info *pdata = dsidev->dev.platform_data; | ||
4797 | int i, r; | ||
4798 | |||
4799 | for (i = 0; i < pdata->num_devices; ++i) { | ||
4800 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
4801 | |||
4802 | if (dssdev->type != OMAP_DISPLAY_TYPE_DSI) | ||
4803 | continue; | ||
4804 | |||
4805 | if (dssdev->phy.dsi.module != dsi->module_id) | ||
4806 | continue; | ||
4807 | |||
4808 | r = dsi_init_display(dssdev); | ||
4809 | if (r) { | ||
4810 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
4811 | continue; | ||
4812 | } | ||
4813 | |||
4814 | r = omap_dss_register_device(dssdev, &dsidev->dev, i); | ||
4815 | if (r) | ||
4816 | DSSERR("device %s register failed: %d\n", | ||
4817 | dssdev->name, r); | ||
4818 | } | ||
4819 | } | ||
4820 | |||
4683 | /* DSI1 HW IP initialisation */ | 4821 | /* DSI1 HW IP initialisation */ |
4684 | static int omap_dsihw_probe(struct platform_device *dsidev) | 4822 | static int __init omap_dsihw_probe(struct platform_device *dsidev) |
4685 | { | 4823 | { |
4686 | struct omap_display_platform_data *dss_plat_data; | ||
4687 | struct omap_dss_board_info *board_info; | ||
4688 | u32 rev; | 4824 | u32 rev; |
4689 | int r, i, dsi_module = dsi_get_dsidev_id(dsidev); | 4825 | int r, i; |
4690 | struct resource *dsi_mem; | 4826 | struct resource *dsi_mem; |
4691 | struct dsi_data *dsi; | 4827 | struct dsi_data *dsi; |
4692 | 4828 | ||
@@ -4694,15 +4830,11 @@ static int omap_dsihw_probe(struct platform_device *dsidev) | |||
4694 | if (!dsi) | 4830 | if (!dsi) |
4695 | return -ENOMEM; | 4831 | return -ENOMEM; |
4696 | 4832 | ||
4833 | dsi->module_id = dsidev->id; | ||
4697 | dsi->pdev = dsidev; | 4834 | dsi->pdev = dsidev; |
4698 | dsi_pdev_map[dsi_module] = dsidev; | 4835 | dsi_pdev_map[dsi->module_id] = dsidev; |
4699 | dev_set_drvdata(&dsidev->dev, dsi); | 4836 | dev_set_drvdata(&dsidev->dev, dsi); |
4700 | 4837 | ||
4701 | dss_plat_data = dsidev->dev.platform_data; | ||
4702 | board_info = dss_plat_data->board_data; | ||
4703 | dsi->enable_pads = board_info->dsi_enable_pads; | ||
4704 | dsi->disable_pads = board_info->dsi_disable_pads; | ||
4705 | |||
4706 | spin_lock_init(&dsi->irq_lock); | 4838 | spin_lock_init(&dsi->irq_lock); |
4707 | spin_lock_init(&dsi->errors_lock); | 4839 | spin_lock_init(&dsi->errors_lock); |
4708 | dsi->errors = 0; | 4840 | dsi->errors = 0; |
@@ -4780,8 +4912,21 @@ static int omap_dsihw_probe(struct platform_device *dsidev) | |||
4780 | else | 4912 | else |
4781 | dsi->num_lanes_supported = 3; | 4913 | dsi->num_lanes_supported = 3; |
4782 | 4914 | ||
4915 | dsi_probe_pdata(dsidev); | ||
4916 | |||
4783 | dsi_runtime_put(dsidev); | 4917 | dsi_runtime_put(dsidev); |
4784 | 4918 | ||
4919 | if (dsi->module_id == 0) | ||
4920 | dss_debugfs_create_file("dsi1_regs", dsi1_dump_regs); | ||
4921 | else if (dsi->module_id == 1) | ||
4922 | dss_debugfs_create_file("dsi2_regs", dsi2_dump_regs); | ||
4923 | |||
4924 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
4925 | if (dsi->module_id == 0) | ||
4926 | dss_debugfs_create_file("dsi1_irqs", dsi1_dump_irqs); | ||
4927 | else if (dsi->module_id == 1) | ||
4928 | dss_debugfs_create_file("dsi2_irqs", dsi2_dump_irqs); | ||
4929 | #endif | ||
4785 | return 0; | 4930 | return 0; |
4786 | 4931 | ||
4787 | err_runtime_get: | 4932 | err_runtime_get: |
@@ -4790,12 +4935,14 @@ err_runtime_get: | |||
4790 | return r; | 4935 | return r; |
4791 | } | 4936 | } |
4792 | 4937 | ||
4793 | static int omap_dsihw_remove(struct platform_device *dsidev) | 4938 | static int __exit omap_dsihw_remove(struct platform_device *dsidev) |
4794 | { | 4939 | { |
4795 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4940 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4796 | 4941 | ||
4797 | WARN_ON(dsi->scp_clk_refcount > 0); | 4942 | WARN_ON(dsi->scp_clk_refcount > 0); |
4798 | 4943 | ||
4944 | omap_dss_unregister_child_devices(&dsidev->dev); | ||
4945 | |||
4799 | pm_runtime_disable(&dsidev->dev); | 4946 | pm_runtime_disable(&dsidev->dev); |
4800 | 4947 | ||
4801 | dsi_put_clocks(dsidev); | 4948 | dsi_put_clocks(dsidev); |
@@ -4816,7 +4963,6 @@ static int omap_dsihw_remove(struct platform_device *dsidev) | |||
4816 | static int dsi_runtime_suspend(struct device *dev) | 4963 | static int dsi_runtime_suspend(struct device *dev) |
4817 | { | 4964 | { |
4818 | dispc_runtime_put(); | 4965 | dispc_runtime_put(); |
4819 | dss_runtime_put(); | ||
4820 | 4966 | ||
4821 | return 0; | 4967 | return 0; |
4822 | } | 4968 | } |
@@ -4825,20 +4971,11 @@ static int dsi_runtime_resume(struct device *dev) | |||
4825 | { | 4971 | { |
4826 | int r; | 4972 | int r; |
4827 | 4973 | ||
4828 | r = dss_runtime_get(); | ||
4829 | if (r) | ||
4830 | goto err_get_dss; | ||
4831 | |||
4832 | r = dispc_runtime_get(); | 4974 | r = dispc_runtime_get(); |
4833 | if (r) | 4975 | if (r) |
4834 | goto err_get_dispc; | 4976 | return r; |
4835 | 4977 | ||
4836 | return 0; | 4978 | return 0; |
4837 | |||
4838 | err_get_dispc: | ||
4839 | dss_runtime_put(); | ||
4840 | err_get_dss: | ||
4841 | return r; | ||
4842 | } | 4979 | } |
4843 | 4980 | ||
4844 | static const struct dev_pm_ops dsi_pm_ops = { | 4981 | static const struct dev_pm_ops dsi_pm_ops = { |
@@ -4847,8 +4984,7 @@ static const struct dev_pm_ops dsi_pm_ops = { | |||
4847 | }; | 4984 | }; |
4848 | 4985 | ||
4849 | static struct platform_driver omap_dsihw_driver = { | 4986 | static struct platform_driver omap_dsihw_driver = { |
4850 | .probe = omap_dsihw_probe, | 4987 | .remove = __exit_p(omap_dsihw_remove), |
4851 | .remove = omap_dsihw_remove, | ||
4852 | .driver = { | 4988 | .driver = { |
4853 | .name = "omapdss_dsi", | 4989 | .name = "omapdss_dsi", |
4854 | .owner = THIS_MODULE, | 4990 | .owner = THIS_MODULE, |
@@ -4856,12 +4992,12 @@ static struct platform_driver omap_dsihw_driver = { | |||
4856 | }, | 4992 | }, |
4857 | }; | 4993 | }; |
4858 | 4994 | ||
4859 | int dsi_init_platform_driver(void) | 4995 | int __init dsi_init_platform_driver(void) |
4860 | { | 4996 | { |
4861 | return platform_driver_register(&omap_dsihw_driver); | 4997 | return platform_driver_probe(&omap_dsihw_driver, omap_dsihw_probe); |
4862 | } | 4998 | } |
4863 | 4999 | ||
4864 | void dsi_uninit_platform_driver(void) | 5000 | void __exit dsi_uninit_platform_driver(void) |
4865 | { | 5001 | { |
4866 | return platform_driver_unregister(&omap_dsihw_driver); | 5002 | platform_driver_unregister(&omap_dsihw_driver); |
4867 | } | 5003 | } |
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index bd2d5e159463..6ea1ff149f6f 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c | |||
@@ -62,6 +62,9 @@ struct dss_reg { | |||
62 | #define REG_FLD_MOD(idx, val, start, end) \ | 62 | #define REG_FLD_MOD(idx, val, start, end) \ |
63 | dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) | 63 | dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) |
64 | 64 | ||
65 | static int dss_runtime_get(void); | ||
66 | static void dss_runtime_put(void); | ||
67 | |||
65 | static struct { | 68 | static struct { |
66 | struct platform_device *pdev; | 69 | struct platform_device *pdev; |
67 | void __iomem *base; | 70 | void __iomem *base; |
@@ -277,7 +280,7 @@ void dss_dump_clocks(struct seq_file *s) | |||
277 | dss_runtime_put(); | 280 | dss_runtime_put(); |
278 | } | 281 | } |
279 | 282 | ||
280 | void dss_dump_regs(struct seq_file *s) | 283 | static void dss_dump_regs(struct seq_file *s) |
281 | { | 284 | { |
282 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) | 285 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) |
283 | 286 | ||
@@ -322,6 +325,7 @@ void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src) | |||
322 | break; | 325 | break; |
323 | default: | 326 | default: |
324 | BUG(); | 327 | BUG(); |
328 | return; | ||
325 | } | 329 | } |
326 | 330 | ||
327 | dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end); | 331 | dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end); |
@@ -335,7 +339,7 @@ void dss_select_dsi_clk_source(int dsi_module, | |||
335 | enum omap_dss_clk_source clk_src) | 339 | enum omap_dss_clk_source clk_src) |
336 | { | 340 | { |
337 | struct platform_device *dsidev; | 341 | struct platform_device *dsidev; |
338 | int b; | 342 | int b, pos; |
339 | 343 | ||
340 | switch (clk_src) { | 344 | switch (clk_src) { |
341 | case OMAP_DSS_CLK_SRC_FCK: | 345 | case OMAP_DSS_CLK_SRC_FCK: |
@@ -355,9 +359,11 @@ void dss_select_dsi_clk_source(int dsi_module, | |||
355 | break; | 359 | break; |
356 | default: | 360 | default: |
357 | BUG(); | 361 | BUG(); |
362 | return; | ||
358 | } | 363 | } |
359 | 364 | ||
360 | REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ | 365 | pos = dsi_module == 0 ? 1 : 10; |
366 | REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* DSIx_CLK_SWITCH */ | ||
361 | 367 | ||
362 | dss.dsi_clk_source[dsi_module] = clk_src; | 368 | dss.dsi_clk_source[dsi_module] = clk_src; |
363 | } | 369 | } |
@@ -389,6 +395,7 @@ void dss_select_lcd_clk_source(enum omap_channel channel, | |||
389 | break; | 395 | break; |
390 | default: | 396 | default: |
391 | BUG(); | 397 | BUG(); |
398 | return; | ||
392 | } | 399 | } |
393 | 400 | ||
394 | pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12; | 401 | pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12; |
@@ -706,7 +713,7 @@ static void dss_put_clocks(void) | |||
706 | clk_put(dss.dss_clk); | 713 | clk_put(dss.dss_clk); |
707 | } | 714 | } |
708 | 715 | ||
709 | int dss_runtime_get(void) | 716 | static int dss_runtime_get(void) |
710 | { | 717 | { |
711 | int r; | 718 | int r; |
712 | 719 | ||
@@ -717,7 +724,7 @@ int dss_runtime_get(void) | |||
717 | return r < 0 ? r : 0; | 724 | return r < 0 ? r : 0; |
718 | } | 725 | } |
719 | 726 | ||
720 | void dss_runtime_put(void) | 727 | static void dss_runtime_put(void) |
721 | { | 728 | { |
722 | int r; | 729 | int r; |
723 | 730 | ||
@@ -740,7 +747,7 @@ void dss_debug_dump_clocks(struct seq_file *s) | |||
740 | #endif | 747 | #endif |
741 | 748 | ||
742 | /* DSS HW IP initialisation */ | 749 | /* DSS HW IP initialisation */ |
743 | static int omap_dsshw_probe(struct platform_device *pdev) | 750 | static int __init omap_dsshw_probe(struct platform_device *pdev) |
744 | { | 751 | { |
745 | struct resource *dss_mem; | 752 | struct resource *dss_mem; |
746 | u32 rev; | 753 | u32 rev; |
@@ -785,40 +792,24 @@ static int omap_dsshw_probe(struct platform_device *pdev) | |||
785 | dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; | 792 | dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; |
786 | dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; | 793 | dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; |
787 | 794 | ||
788 | r = dpi_init(); | ||
789 | if (r) { | ||
790 | DSSERR("Failed to initialize DPI\n"); | ||
791 | goto err_dpi; | ||
792 | } | ||
793 | |||
794 | r = sdi_init(); | ||
795 | if (r) { | ||
796 | DSSERR("Failed to initialize SDI\n"); | ||
797 | goto err_sdi; | ||
798 | } | ||
799 | |||
800 | rev = dss_read_reg(DSS_REVISION); | 795 | rev = dss_read_reg(DSS_REVISION); |
801 | printk(KERN_INFO "OMAP DSS rev %d.%d\n", | 796 | printk(KERN_INFO "OMAP DSS rev %d.%d\n", |
802 | FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); | 797 | FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); |
803 | 798 | ||
804 | dss_runtime_put(); | 799 | dss_runtime_put(); |
805 | 800 | ||
801 | dss_debugfs_create_file("dss", dss_dump_regs); | ||
802 | |||
806 | return 0; | 803 | return 0; |
807 | err_sdi: | 804 | |
808 | dpi_exit(); | ||
809 | err_dpi: | ||
810 | dss_runtime_put(); | ||
811 | err_runtime_get: | 805 | err_runtime_get: |
812 | pm_runtime_disable(&pdev->dev); | 806 | pm_runtime_disable(&pdev->dev); |
813 | dss_put_clocks(); | 807 | dss_put_clocks(); |
814 | return r; | 808 | return r; |
815 | } | 809 | } |
816 | 810 | ||
817 | static int omap_dsshw_remove(struct platform_device *pdev) | 811 | static int __exit omap_dsshw_remove(struct platform_device *pdev) |
818 | { | 812 | { |
819 | dpi_exit(); | ||
820 | sdi_exit(); | ||
821 | |||
822 | pm_runtime_disable(&pdev->dev); | 813 | pm_runtime_disable(&pdev->dev); |
823 | 814 | ||
824 | dss_put_clocks(); | 815 | dss_put_clocks(); |
@@ -829,11 +820,24 @@ static int omap_dsshw_remove(struct platform_device *pdev) | |||
829 | static int dss_runtime_suspend(struct device *dev) | 820 | static int dss_runtime_suspend(struct device *dev) |
830 | { | 821 | { |
831 | dss_save_context(); | 822 | dss_save_context(); |
823 | dss_set_min_bus_tput(dev, 0); | ||
832 | return 0; | 824 | return 0; |
833 | } | 825 | } |
834 | 826 | ||
835 | static int dss_runtime_resume(struct device *dev) | 827 | static int dss_runtime_resume(struct device *dev) |
836 | { | 828 | { |
829 | int r; | ||
830 | /* | ||
831 | * Set an arbitrarily high tput request to ensure OPP100. | ||
832 | * What we should really do is to make a request to stay in OPP100, | ||
833 | * without any tput requirements, but that is not currently possible | ||
834 | * via the PM layer. | ||
835 | */ | ||
836 | |||
837 | r = dss_set_min_bus_tput(dev, 1000000000); | ||
838 | if (r) | ||
839 | return r; | ||
840 | |||
837 | dss_restore_context(); | 841 | dss_restore_context(); |
838 | return 0; | 842 | return 0; |
839 | } | 843 | } |
@@ -844,8 +848,7 @@ static const struct dev_pm_ops dss_pm_ops = { | |||
844 | }; | 848 | }; |
845 | 849 | ||
846 | static struct platform_driver omap_dsshw_driver = { | 850 | static struct platform_driver omap_dsshw_driver = { |
847 | .probe = omap_dsshw_probe, | 851 | .remove = __exit_p(omap_dsshw_remove), |
848 | .remove = omap_dsshw_remove, | ||
849 | .driver = { | 852 | .driver = { |
850 | .name = "omapdss_dss", | 853 | .name = "omapdss_dss", |
851 | .owner = THIS_MODULE, | 854 | .owner = THIS_MODULE, |
@@ -853,12 +856,12 @@ static struct platform_driver omap_dsshw_driver = { | |||
853 | }, | 856 | }, |
854 | }; | 857 | }; |
855 | 858 | ||
856 | int dss_init_platform_driver(void) | 859 | int __init dss_init_platform_driver(void) |
857 | { | 860 | { |
858 | return platform_driver_register(&omap_dsshw_driver); | 861 | return platform_driver_probe(&omap_dsshw_driver, omap_dsshw_probe); |
859 | } | 862 | } |
860 | 863 | ||
861 | void dss_uninit_platform_driver(void) | 864 | void dss_uninit_platform_driver(void) |
862 | { | 865 | { |
863 | return platform_driver_unregister(&omap_dsshw_driver); | 866 | platform_driver_unregister(&omap_dsshw_driver); |
864 | } | 867 | } |
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index d4b3dff2ead3..dd1092ceaeef 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
@@ -150,9 +150,6 @@ struct dsi_clock_info { | |||
150 | u16 regm_dsi; /* OMAP3: REGM4 | 150 | u16 regm_dsi; /* OMAP3: REGM4 |
151 | * OMAP4: REGM5 */ | 151 | * OMAP4: REGM5 */ |
152 | u16 lp_clk_div; | 152 | u16 lp_clk_div; |
153 | |||
154 | u8 highfreq; | ||
155 | bool use_sys_clk; | ||
156 | }; | 153 | }; |
157 | 154 | ||
158 | struct seq_file; | 155 | struct seq_file; |
@@ -162,6 +159,16 @@ struct platform_device; | |||
162 | struct bus_type *dss_get_bus(void); | 159 | struct bus_type *dss_get_bus(void); |
163 | struct regulator *dss_get_vdds_dsi(void); | 160 | struct regulator *dss_get_vdds_dsi(void); |
164 | struct regulator *dss_get_vdds_sdi(void); | 161 | struct regulator *dss_get_vdds_sdi(void); |
162 | int dss_get_ctx_loss_count(struct device *dev); | ||
163 | int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask); | ||
164 | void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); | ||
165 | int dss_set_min_bus_tput(struct device *dev, unsigned long tput); | ||
166 | int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); | ||
167 | |||
168 | int omap_dss_register_device(struct omap_dss_device *dssdev, | ||
169 | struct device *parent, int disp_num); | ||
170 | void omap_dss_unregister_device(struct omap_dss_device *dssdev); | ||
171 | void omap_dss_unregister_child_devices(struct device *parent); | ||
165 | 172 | ||
166 | /* apply */ | 173 | /* apply */ |
167 | void dss_apply_init(void); | 174 | void dss_apply_init(void); |
@@ -179,6 +186,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr, | |||
179 | int dss_mgr_set_device(struct omap_overlay_manager *mgr, | 186 | int dss_mgr_set_device(struct omap_overlay_manager *mgr, |
180 | struct omap_dss_device *dssdev); | 187 | struct omap_dss_device *dssdev); |
181 | int dss_mgr_unset_device(struct omap_overlay_manager *mgr); | 188 | int dss_mgr_unset_device(struct omap_overlay_manager *mgr); |
189 | void dss_mgr_set_timings(struct omap_overlay_manager *mgr, | ||
190 | struct omap_video_timings *timings); | ||
191 | const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); | ||
182 | 192 | ||
183 | bool dss_ovl_is_enabled(struct omap_overlay *ovl); | 193 | bool dss_ovl_is_enabled(struct omap_overlay *ovl); |
184 | int dss_ovl_enable(struct omap_overlay *ovl); | 194 | int dss_ovl_enable(struct omap_overlay *ovl); |
@@ -208,9 +218,11 @@ int dss_init_overlay_managers(struct platform_device *pdev); | |||
208 | void dss_uninit_overlay_managers(struct platform_device *pdev); | 218 | void dss_uninit_overlay_managers(struct platform_device *pdev); |
209 | int dss_mgr_simple_check(struct omap_overlay_manager *mgr, | 219 | int dss_mgr_simple_check(struct omap_overlay_manager *mgr, |
210 | const struct omap_overlay_manager_info *info); | 220 | const struct omap_overlay_manager_info *info); |
221 | int dss_mgr_check_timings(struct omap_overlay_manager *mgr, | ||
222 | const struct omap_video_timings *timings); | ||
211 | int dss_mgr_check(struct omap_overlay_manager *mgr, | 223 | int dss_mgr_check(struct omap_overlay_manager *mgr, |
212 | struct omap_dss_device *dssdev, | ||
213 | struct omap_overlay_manager_info *info, | 224 | struct omap_overlay_manager_info *info, |
225 | const struct omap_video_timings *mgr_timings, | ||
214 | struct omap_overlay_info **overlay_infos); | 226 | struct omap_overlay_info **overlay_infos); |
215 | 227 | ||
216 | /* overlay */ | 228 | /* overlay */ |
@@ -220,22 +232,18 @@ void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr); | |||
220 | void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); | 232 | void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); |
221 | int dss_ovl_simple_check(struct omap_overlay *ovl, | 233 | int dss_ovl_simple_check(struct omap_overlay *ovl, |
222 | const struct omap_overlay_info *info); | 234 | const struct omap_overlay_info *info); |
223 | int dss_ovl_check(struct omap_overlay *ovl, | 235 | int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, |
224 | struct omap_overlay_info *info, struct omap_dss_device *dssdev); | 236 | const struct omap_video_timings *mgr_timings); |
225 | 237 | ||
226 | /* DSS */ | 238 | /* DSS */ |
227 | int dss_init_platform_driver(void); | 239 | int dss_init_platform_driver(void) __init; |
228 | void dss_uninit_platform_driver(void); | 240 | void dss_uninit_platform_driver(void); |
229 | 241 | ||
230 | int dss_runtime_get(void); | ||
231 | void dss_runtime_put(void); | ||
232 | |||
233 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); | 242 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); |
234 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); | 243 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); |
235 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); | 244 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); |
236 | void dss_dump_clocks(struct seq_file *s); | 245 | void dss_dump_clocks(struct seq_file *s); |
237 | 246 | ||
238 | void dss_dump_regs(struct seq_file *s); | ||
239 | #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) | 247 | #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) |
240 | void dss_debug_dump_clocks(struct seq_file *s); | 248 | void dss_debug_dump_clocks(struct seq_file *s); |
241 | #endif | 249 | #endif |
@@ -265,19 +273,8 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck, | |||
265 | struct dispc_clock_info *dispc_cinfo); | 273 | struct dispc_clock_info *dispc_cinfo); |
266 | 274 | ||
267 | /* SDI */ | 275 | /* SDI */ |
268 | #ifdef CONFIG_OMAP2_DSS_SDI | 276 | int sdi_init_platform_driver(void) __init; |
269 | int sdi_init(void); | 277 | void sdi_uninit_platform_driver(void) __exit; |
270 | void sdi_exit(void); | ||
271 | int sdi_init_display(struct omap_dss_device *display); | ||
272 | #else | ||
273 | static inline int sdi_init(void) | ||
274 | { | ||
275 | return 0; | ||
276 | } | ||
277 | static inline void sdi_exit(void) | ||
278 | { | ||
279 | } | ||
280 | #endif | ||
281 | 278 | ||
282 | /* DSI */ | 279 | /* DSI */ |
283 | #ifdef CONFIG_OMAP2_DSS_DSI | 280 | #ifdef CONFIG_OMAP2_DSS_DSI |
@@ -285,19 +282,14 @@ static inline void sdi_exit(void) | |||
285 | struct dentry; | 282 | struct dentry; |
286 | struct file_operations; | 283 | struct file_operations; |
287 | 284 | ||
288 | int dsi_init_platform_driver(void); | 285 | int dsi_init_platform_driver(void) __init; |
289 | void dsi_uninit_platform_driver(void); | 286 | void dsi_uninit_platform_driver(void) __exit; |
290 | 287 | ||
291 | int dsi_runtime_get(struct platform_device *dsidev); | 288 | int dsi_runtime_get(struct platform_device *dsidev); |
292 | void dsi_runtime_put(struct platform_device *dsidev); | 289 | void dsi_runtime_put(struct platform_device *dsidev); |
293 | 290 | ||
294 | void dsi_dump_clocks(struct seq_file *s); | 291 | void dsi_dump_clocks(struct seq_file *s); |
295 | void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir, | ||
296 | const struct file_operations *debug_fops); | ||
297 | void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir, | ||
298 | const struct file_operations *debug_fops); | ||
299 | 292 | ||
300 | int dsi_init_display(struct omap_dss_device *display); | ||
301 | void dsi_irq_handler(void); | 293 | void dsi_irq_handler(void); |
302 | u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); | 294 | u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); |
303 | 295 | ||
@@ -314,13 +306,6 @@ void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); | |||
314 | void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); | 306 | void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); |
315 | struct platform_device *dsi_get_dsidev_from_id(int module); | 307 | struct platform_device *dsi_get_dsidev_from_id(int module); |
316 | #else | 308 | #else |
317 | static inline int dsi_init_platform_driver(void) | ||
318 | { | ||
319 | return 0; | ||
320 | } | ||
321 | static inline void dsi_uninit_platform_driver(void) | ||
322 | { | ||
323 | } | ||
324 | static inline int dsi_runtime_get(struct platform_device *dsidev) | 309 | static inline int dsi_runtime_get(struct platform_device *dsidev) |
325 | { | 310 | { |
326 | return 0; | 311 | return 0; |
@@ -377,28 +362,14 @@ static inline struct platform_device *dsi_get_dsidev_from_id(int module) | |||
377 | #endif | 362 | #endif |
378 | 363 | ||
379 | /* DPI */ | 364 | /* DPI */ |
380 | #ifdef CONFIG_OMAP2_DSS_DPI | 365 | int dpi_init_platform_driver(void) __init; |
381 | int dpi_init(void); | 366 | void dpi_uninit_platform_driver(void) __exit; |
382 | void dpi_exit(void); | ||
383 | int dpi_init_display(struct omap_dss_device *dssdev); | ||
384 | #else | ||
385 | static inline int dpi_init(void) | ||
386 | { | ||
387 | return 0; | ||
388 | } | ||
389 | static inline void dpi_exit(void) | ||
390 | { | ||
391 | } | ||
392 | #endif | ||
393 | 367 | ||
394 | /* DISPC */ | 368 | /* DISPC */ |
395 | int dispc_init_platform_driver(void); | 369 | int dispc_init_platform_driver(void) __init; |
396 | void dispc_uninit_platform_driver(void); | 370 | void dispc_uninit_platform_driver(void) __exit; |
397 | void dispc_dump_clocks(struct seq_file *s); | 371 | void dispc_dump_clocks(struct seq_file *s); |
398 | void dispc_dump_irqs(struct seq_file *s); | ||
399 | void dispc_dump_regs(struct seq_file *s); | ||
400 | void dispc_irq_handler(void); | 372 | void dispc_irq_handler(void); |
401 | void dispc_fake_vsync_irq(void); | ||
402 | 373 | ||
403 | int dispc_runtime_get(void); | 374 | int dispc_runtime_get(void); |
404 | void dispc_runtime_put(void); | 375 | void dispc_runtime_put(void); |
@@ -409,12 +380,12 @@ void dispc_disable_sidle(void); | |||
409 | void dispc_lcd_enable_signal_polarity(bool act_high); | 380 | void dispc_lcd_enable_signal_polarity(bool act_high); |
410 | void dispc_lcd_enable_signal(bool enable); | 381 | void dispc_lcd_enable_signal(bool enable); |
411 | void dispc_pck_free_enable(bool enable); | 382 | void dispc_pck_free_enable(bool enable); |
412 | void dispc_set_digit_size(u16 width, u16 height); | ||
413 | void dispc_enable_fifomerge(bool enable); | 383 | void dispc_enable_fifomerge(bool enable); |
414 | void dispc_enable_gamma_table(bool enable); | 384 | void dispc_enable_gamma_table(bool enable); |
415 | void dispc_set_loadmode(enum omap_dss_load_mode mode); | 385 | void dispc_set_loadmode(enum omap_dss_load_mode mode); |
416 | 386 | ||
417 | bool dispc_lcd_timings_ok(struct omap_video_timings *timings); | 387 | bool dispc_mgr_timings_ok(enum omap_channel channel, |
388 | const struct omap_video_timings *timings); | ||
418 | unsigned long dispc_fclk_rate(void); | 389 | unsigned long dispc_fclk_rate(void); |
419 | void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, | 390 | void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, |
420 | struct dispc_clock_info *cinfo); | 391 | struct dispc_clock_info *cinfo); |
@@ -424,15 +395,16 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, | |||
424 | 395 | ||
425 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); | 396 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); |
426 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | 397 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, |
427 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); | 398 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, |
399 | bool manual_update); | ||
428 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 400 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, |
429 | bool ilace, bool replication); | 401 | bool ilace, bool replication, |
402 | const struct omap_video_timings *mgr_timings); | ||
430 | int dispc_ovl_enable(enum omap_plane plane, bool enable); | 403 | int dispc_ovl_enable(enum omap_plane plane, bool enable); |
431 | void dispc_ovl_set_channel_out(enum omap_plane plane, | 404 | void dispc_ovl_set_channel_out(enum omap_plane plane, |
432 | enum omap_channel channel); | 405 | enum omap_channel channel); |
433 | 406 | ||
434 | void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable); | 407 | void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable); |
435 | void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height); | ||
436 | u32 dispc_mgr_get_vsync_irq(enum omap_channel channel); | 408 | u32 dispc_mgr_get_vsync_irq(enum omap_channel channel); |
437 | u32 dispc_mgr_get_framedone_irq(enum omap_channel channel); | 409 | u32 dispc_mgr_get_framedone_irq(enum omap_channel channel); |
438 | bool dispc_mgr_go_busy(enum omap_channel channel); | 410 | bool dispc_mgr_go_busy(enum omap_channel channel); |
@@ -445,12 +417,13 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable); | |||
445 | void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); | 417 | void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); |
446 | void dispc_mgr_set_lcd_display_type(enum omap_channel channel, | 418 | void dispc_mgr_set_lcd_display_type(enum omap_channel channel, |
447 | enum omap_lcd_display_type type); | 419 | enum omap_lcd_display_type type); |
448 | void dispc_mgr_set_lcd_timings(enum omap_channel channel, | 420 | void dispc_mgr_set_timings(enum omap_channel channel, |
449 | struct omap_video_timings *timings); | 421 | struct omap_video_timings *timings); |
450 | void dispc_mgr_set_pol_freq(enum omap_channel channel, | 422 | void dispc_mgr_set_pol_freq(enum omap_channel channel, |
451 | enum omap_panel_config config, u8 acbi, u8 acb); | 423 | enum omap_panel_config config, u8 acbi, u8 acb); |
452 | unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); | 424 | unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); |
453 | unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); | 425 | unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); |
426 | unsigned long dispc_core_clk_rate(void); | ||
454 | int dispc_mgr_set_clock_div(enum omap_channel channel, | 427 | int dispc_mgr_set_clock_div(enum omap_channel channel, |
455 | struct dispc_clock_info *cinfo); | 428 | struct dispc_clock_info *cinfo); |
456 | int dispc_mgr_get_clock_div(enum omap_channel channel, | 429 | int dispc_mgr_get_clock_div(enum omap_channel channel, |
@@ -460,19 +433,10 @@ void dispc_mgr_setup(enum omap_channel channel, | |||
460 | 433 | ||
461 | /* VENC */ | 434 | /* VENC */ |
462 | #ifdef CONFIG_OMAP2_DSS_VENC | 435 | #ifdef CONFIG_OMAP2_DSS_VENC |
463 | int venc_init_platform_driver(void); | 436 | int venc_init_platform_driver(void) __init; |
464 | void venc_uninit_platform_driver(void); | 437 | void venc_uninit_platform_driver(void) __exit; |
465 | void venc_dump_regs(struct seq_file *s); | ||
466 | int venc_init_display(struct omap_dss_device *display); | ||
467 | unsigned long venc_get_pixel_clock(void); | 438 | unsigned long venc_get_pixel_clock(void); |
468 | #else | 439 | #else |
469 | static inline int venc_init_platform_driver(void) | ||
470 | { | ||
471 | return 0; | ||
472 | } | ||
473 | static inline void venc_uninit_platform_driver(void) | ||
474 | { | ||
475 | } | ||
476 | static inline unsigned long venc_get_pixel_clock(void) | 440 | static inline unsigned long venc_get_pixel_clock(void) |
477 | { | 441 | { |
478 | WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__); | 442 | WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__); |
@@ -482,23 +446,10 @@ static inline unsigned long venc_get_pixel_clock(void) | |||
482 | 446 | ||
483 | /* HDMI */ | 447 | /* HDMI */ |
484 | #ifdef CONFIG_OMAP4_DSS_HDMI | 448 | #ifdef CONFIG_OMAP4_DSS_HDMI |
485 | int hdmi_init_platform_driver(void); | 449 | int hdmi_init_platform_driver(void) __init; |
486 | void hdmi_uninit_platform_driver(void); | 450 | void hdmi_uninit_platform_driver(void) __exit; |
487 | int hdmi_init_display(struct omap_dss_device *dssdev); | ||
488 | unsigned long hdmi_get_pixel_clock(void); | 451 | unsigned long hdmi_get_pixel_clock(void); |
489 | void hdmi_dump_regs(struct seq_file *s); | ||
490 | #else | 452 | #else |
491 | static inline int hdmi_init_display(struct omap_dss_device *dssdev) | ||
492 | { | ||
493 | return 0; | ||
494 | } | ||
495 | static inline int hdmi_init_platform_driver(void) | ||
496 | { | ||
497 | return 0; | ||
498 | } | ||
499 | static inline void hdmi_uninit_platform_driver(void) | ||
500 | { | ||
501 | } | ||
502 | static inline unsigned long hdmi_get_pixel_clock(void) | 453 | static inline unsigned long hdmi_get_pixel_clock(void) |
503 | { | 454 | { |
504 | WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__); | 455 | WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__); |
@@ -514,22 +465,18 @@ int omapdss_hdmi_read_edid(u8 *buf, int len); | |||
514 | bool omapdss_hdmi_detect(void); | 465 | bool omapdss_hdmi_detect(void); |
515 | int hdmi_panel_init(void); | 466 | int hdmi_panel_init(void); |
516 | void hdmi_panel_exit(void); | 467 | void hdmi_panel_exit(void); |
468 | #ifdef CONFIG_OMAP4_DSS_HDMI_AUDIO | ||
469 | int hdmi_audio_enable(void); | ||
470 | void hdmi_audio_disable(void); | ||
471 | int hdmi_audio_start(void); | ||
472 | void hdmi_audio_stop(void); | ||
473 | bool hdmi_mode_has_audio(void); | ||
474 | int hdmi_audio_config(struct omap_dss_audio *audio); | ||
475 | #endif | ||
517 | 476 | ||
518 | /* RFBI */ | 477 | /* RFBI */ |
519 | #ifdef CONFIG_OMAP2_DSS_RFBI | 478 | int rfbi_init_platform_driver(void) __init; |
520 | int rfbi_init_platform_driver(void); | 479 | void rfbi_uninit_platform_driver(void) __exit; |
521 | void rfbi_uninit_platform_driver(void); | ||
522 | void rfbi_dump_regs(struct seq_file *s); | ||
523 | int rfbi_init_display(struct omap_dss_device *display); | ||
524 | #else | ||
525 | static inline int rfbi_init_platform_driver(void) | ||
526 | { | ||
527 | return 0; | ||
528 | } | ||
529 | static inline void rfbi_uninit_platform_driver(void) | ||
530 | { | ||
531 | } | ||
532 | #endif | ||
533 | 480 | ||
534 | 481 | ||
535 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | 482 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index ce14aa6dd672..938709724f0c 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c | |||
@@ -52,6 +52,8 @@ struct omap_dss_features { | |||
52 | const char * const *clksrc_names; | 52 | const char * const *clksrc_names; |
53 | const struct dss_param_range *dss_params; | 53 | const struct dss_param_range *dss_params; |
54 | 54 | ||
55 | const enum omap_dss_rotation_type supported_rotation_types; | ||
56 | |||
55 | const u32 buffer_size_unit; | 57 | const u32 buffer_size_unit; |
56 | const u32 burst_size_unit; | 58 | const u32 burst_size_unit; |
57 | }; | 59 | }; |
@@ -311,6 +313,8 @@ static const struct dss_param_range omap2_dss_param_range[] = { | |||
311 | * scaler cannot scale a image with width more than 768. | 313 | * scaler cannot scale a image with width more than 768. |
312 | */ | 314 | */ |
313 | [FEAT_PARAM_LINEWIDTH] = { 1, 768 }, | 315 | [FEAT_PARAM_LINEWIDTH] = { 1, 768 }, |
316 | [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, | ||
317 | [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, | ||
314 | }; | 318 | }; |
315 | 319 | ||
316 | static const struct dss_param_range omap3_dss_param_range[] = { | 320 | static const struct dss_param_range omap3_dss_param_range[] = { |
@@ -324,6 +328,8 @@ static const struct dss_param_range omap3_dss_param_range[] = { | |||
324 | [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, | 328 | [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, |
325 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, | 329 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, |
326 | [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, | 330 | [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, |
331 | [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, | ||
332 | [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, | ||
327 | }; | 333 | }; |
328 | 334 | ||
329 | static const struct dss_param_range omap4_dss_param_range[] = { | 335 | static const struct dss_param_range omap4_dss_param_range[] = { |
@@ -337,6 +343,8 @@ static const struct dss_param_range omap4_dss_param_range[] = { | |||
337 | [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, | 343 | [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, |
338 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, | 344 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, |
339 | [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, | 345 | [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, |
346 | [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, | ||
347 | [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, | ||
340 | }; | 348 | }; |
341 | 349 | ||
342 | static const enum dss_feat_id omap2_dss_feat_list[] = { | 350 | static const enum dss_feat_id omap2_dss_feat_list[] = { |
@@ -399,6 +407,7 @@ static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = { | |||
399 | FEAT_FIR_COEF_V, | 407 | FEAT_FIR_COEF_V, |
400 | FEAT_ALPHA_FREE_ZORDER, | 408 | FEAT_ALPHA_FREE_ZORDER, |
401 | FEAT_FIFO_MERGE, | 409 | FEAT_FIFO_MERGE, |
410 | FEAT_BURST_2D, | ||
402 | }; | 411 | }; |
403 | 412 | ||
404 | static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = { | 413 | static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = { |
@@ -416,6 +425,7 @@ static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = { | |||
416 | FEAT_FIR_COEF_V, | 425 | FEAT_FIR_COEF_V, |
417 | FEAT_ALPHA_FREE_ZORDER, | 426 | FEAT_ALPHA_FREE_ZORDER, |
418 | FEAT_FIFO_MERGE, | 427 | FEAT_FIFO_MERGE, |
428 | FEAT_BURST_2D, | ||
419 | }; | 429 | }; |
420 | 430 | ||
421 | static const enum dss_feat_id omap4_dss_feat_list[] = { | 431 | static const enum dss_feat_id omap4_dss_feat_list[] = { |
@@ -434,6 +444,7 @@ static const enum dss_feat_id omap4_dss_feat_list[] = { | |||
434 | FEAT_FIR_COEF_V, | 444 | FEAT_FIR_COEF_V, |
435 | FEAT_ALPHA_FREE_ZORDER, | 445 | FEAT_ALPHA_FREE_ZORDER, |
436 | FEAT_FIFO_MERGE, | 446 | FEAT_FIFO_MERGE, |
447 | FEAT_BURST_2D, | ||
437 | }; | 448 | }; |
438 | 449 | ||
439 | /* OMAP2 DSS Features */ | 450 | /* OMAP2 DSS Features */ |
@@ -451,6 +462,7 @@ static const struct omap_dss_features omap2_dss_features = { | |||
451 | .overlay_caps = omap2_dss_overlay_caps, | 462 | .overlay_caps = omap2_dss_overlay_caps, |
452 | .clksrc_names = omap2_dss_clk_source_names, | 463 | .clksrc_names = omap2_dss_clk_source_names, |
453 | .dss_params = omap2_dss_param_range, | 464 | .dss_params = omap2_dss_param_range, |
465 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, | ||
454 | .buffer_size_unit = 1, | 466 | .buffer_size_unit = 1, |
455 | .burst_size_unit = 8, | 467 | .burst_size_unit = 8, |
456 | }; | 468 | }; |
@@ -470,6 +482,7 @@ static const struct omap_dss_features omap3430_dss_features = { | |||
470 | .overlay_caps = omap3430_dss_overlay_caps, | 482 | .overlay_caps = omap3430_dss_overlay_caps, |
471 | .clksrc_names = omap3_dss_clk_source_names, | 483 | .clksrc_names = omap3_dss_clk_source_names, |
472 | .dss_params = omap3_dss_param_range, | 484 | .dss_params = omap3_dss_param_range, |
485 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, | ||
473 | .buffer_size_unit = 1, | 486 | .buffer_size_unit = 1, |
474 | .burst_size_unit = 8, | 487 | .burst_size_unit = 8, |
475 | }; | 488 | }; |
@@ -488,6 +501,7 @@ static const struct omap_dss_features omap3630_dss_features = { | |||
488 | .overlay_caps = omap3630_dss_overlay_caps, | 501 | .overlay_caps = omap3630_dss_overlay_caps, |
489 | .clksrc_names = omap3_dss_clk_source_names, | 502 | .clksrc_names = omap3_dss_clk_source_names, |
490 | .dss_params = omap3_dss_param_range, | 503 | .dss_params = omap3_dss_param_range, |
504 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, | ||
491 | .buffer_size_unit = 1, | 505 | .buffer_size_unit = 1, |
492 | .burst_size_unit = 8, | 506 | .burst_size_unit = 8, |
493 | }; | 507 | }; |
@@ -508,6 +522,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { | |||
508 | .overlay_caps = omap4_dss_overlay_caps, | 522 | .overlay_caps = omap4_dss_overlay_caps, |
509 | .clksrc_names = omap4_dss_clk_source_names, | 523 | .clksrc_names = omap4_dss_clk_source_names, |
510 | .dss_params = omap4_dss_param_range, | 524 | .dss_params = omap4_dss_param_range, |
525 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, | ||
511 | .buffer_size_unit = 16, | 526 | .buffer_size_unit = 16, |
512 | .burst_size_unit = 16, | 527 | .burst_size_unit = 16, |
513 | }; | 528 | }; |
@@ -527,6 +542,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = { | |||
527 | .overlay_caps = omap4_dss_overlay_caps, | 542 | .overlay_caps = omap4_dss_overlay_caps, |
528 | .clksrc_names = omap4_dss_clk_source_names, | 543 | .clksrc_names = omap4_dss_clk_source_names, |
529 | .dss_params = omap4_dss_param_range, | 544 | .dss_params = omap4_dss_param_range, |
545 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, | ||
530 | .buffer_size_unit = 16, | 546 | .buffer_size_unit = 16, |
531 | .burst_size_unit = 16, | 547 | .burst_size_unit = 16, |
532 | }; | 548 | }; |
@@ -546,6 +562,7 @@ static const struct omap_dss_features omap4_dss_features = { | |||
546 | .overlay_caps = omap4_dss_overlay_caps, | 562 | .overlay_caps = omap4_dss_overlay_caps, |
547 | .clksrc_names = omap4_dss_clk_source_names, | 563 | .clksrc_names = omap4_dss_clk_source_names, |
548 | .dss_params = omap4_dss_param_range, | 564 | .dss_params = omap4_dss_param_range, |
565 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, | ||
549 | .buffer_size_unit = 16, | 566 | .buffer_size_unit = 16, |
550 | .burst_size_unit = 16, | 567 | .burst_size_unit = 16, |
551 | }; | 568 | }; |
@@ -562,13 +579,17 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { | |||
562 | .pll_enable = ti_hdmi_4xxx_pll_enable, | 579 | .pll_enable = ti_hdmi_4xxx_pll_enable, |
563 | .pll_disable = ti_hdmi_4xxx_pll_disable, | 580 | .pll_disable = ti_hdmi_4xxx_pll_disable, |
564 | .video_enable = ti_hdmi_4xxx_wp_video_start, | 581 | .video_enable = ti_hdmi_4xxx_wp_video_start, |
582 | .video_disable = ti_hdmi_4xxx_wp_video_stop, | ||
565 | .dump_wrapper = ti_hdmi_4xxx_wp_dump, | 583 | .dump_wrapper = ti_hdmi_4xxx_wp_dump, |
566 | .dump_core = ti_hdmi_4xxx_core_dump, | 584 | .dump_core = ti_hdmi_4xxx_core_dump, |
567 | .dump_pll = ti_hdmi_4xxx_pll_dump, | 585 | .dump_pll = ti_hdmi_4xxx_pll_dump, |
568 | .dump_phy = ti_hdmi_4xxx_phy_dump, | 586 | .dump_phy = ti_hdmi_4xxx_phy_dump, |
569 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | 587 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
570 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | ||
571 | .audio_enable = ti_hdmi_4xxx_wp_audio_enable, | 588 | .audio_enable = ti_hdmi_4xxx_wp_audio_enable, |
589 | .audio_disable = ti_hdmi_4xxx_wp_audio_disable, | ||
590 | .audio_start = ti_hdmi_4xxx_audio_start, | ||
591 | .audio_stop = ti_hdmi_4xxx_audio_stop, | ||
592 | .audio_config = ti_hdmi_4xxx_audio_config, | ||
572 | #endif | 593 | #endif |
573 | 594 | ||
574 | }; | 595 | }; |
@@ -662,6 +683,11 @@ void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end) | |||
662 | *end = omap_current_dss_features->reg_fields[id].end; | 683 | *end = omap_current_dss_features->reg_fields[id].end; |
663 | } | 684 | } |
664 | 685 | ||
686 | bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type) | ||
687 | { | ||
688 | return omap_current_dss_features->supported_rotation_types & rot_type; | ||
689 | } | ||
690 | |||
665 | void dss_features_init(void) | 691 | void dss_features_init(void) |
666 | { | 692 | { |
667 | if (cpu_is_omap24xx()) | 693 | if (cpu_is_omap24xx()) |
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index c332e7ddfce1..bdf469f080e7 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h | |||
@@ -62,6 +62,7 @@ enum dss_feat_id { | |||
62 | FEAT_FIFO_MERGE, | 62 | FEAT_FIFO_MERGE, |
63 | /* An unknown HW bug causing the normal FIFO thresholds not to work */ | 63 | /* An unknown HW bug causing the normal FIFO thresholds not to work */ |
64 | FEAT_OMAP3_DSI_FIFO_BUG, | 64 | FEAT_OMAP3_DSI_FIFO_BUG, |
65 | FEAT_BURST_2D, | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | /* DSS register field id */ | 68 | /* DSS register field id */ |
@@ -91,6 +92,8 @@ enum dss_range_param { | |||
91 | FEAT_PARAM_DSIPLL_LPDIV, | 92 | FEAT_PARAM_DSIPLL_LPDIV, |
92 | FEAT_PARAM_DOWNSCALE, | 93 | FEAT_PARAM_DOWNSCALE, |
93 | FEAT_PARAM_LINEWIDTH, | 94 | FEAT_PARAM_LINEWIDTH, |
95 | FEAT_PARAM_MGR_WIDTH, | ||
96 | FEAT_PARAM_MGR_HEIGHT, | ||
94 | }; | 97 | }; |
95 | 98 | ||
96 | /* DSS Feature Functions */ | 99 | /* DSS Feature Functions */ |
@@ -108,6 +111,8 @@ const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id); | |||
108 | u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ | 111 | u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ |
109 | u32 dss_feat_get_burst_size_unit(void); /* in bytes */ | 112 | u32 dss_feat_get_burst_size_unit(void); /* in bytes */ |
110 | 113 | ||
114 | bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type); | ||
115 | |||
111 | bool dss_has_feature(enum dss_feat_id id); | 116 | bool dss_has_feature(enum dss_feat_id id); |
112 | void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); | 117 | void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); |
113 | void dss_features_init(void); | 118 | void dss_features_init(void); |
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index c4b4f6950a92..8195c7166d20 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
@@ -33,12 +33,6 @@ | |||
33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
34 | #include <linux/clk.h> | 34 | #include <linux/clk.h> |
35 | #include <video/omapdss.h> | 35 | #include <video/omapdss.h> |
36 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | ||
37 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | ||
38 | #include <sound/soc.h> | ||
39 | #include <sound/pcm_params.h> | ||
40 | #include "ti_hdmi_4xxx_ip.h" | ||
41 | #endif | ||
42 | 36 | ||
43 | #include "ti_hdmi.h" | 37 | #include "ti_hdmi.h" |
44 | #include "dss.h" | 38 | #include "dss.h" |
@@ -63,7 +57,6 @@ | |||
63 | 57 | ||
64 | static struct { | 58 | static struct { |
65 | struct mutex lock; | 59 | struct mutex lock; |
66 | struct omap_display_platform_data *pdata; | ||
67 | struct platform_device *pdev; | 60 | struct platform_device *pdev; |
68 | struct hdmi_ip_data ip_data; | 61 | struct hdmi_ip_data ip_data; |
69 | 62 | ||
@@ -130,25 +123,12 @@ static int hdmi_runtime_get(void) | |||
130 | 123 | ||
131 | DSSDBG("hdmi_runtime_get\n"); | 124 | DSSDBG("hdmi_runtime_get\n"); |
132 | 125 | ||
133 | /* | ||
134 | * HACK: Add dss_runtime_get() to ensure DSS clock domain is enabled. | ||
135 | * This should be removed later. | ||
136 | */ | ||
137 | r = dss_runtime_get(); | ||
138 | if (r < 0) | ||
139 | goto err_get_dss; | ||
140 | |||
141 | r = pm_runtime_get_sync(&hdmi.pdev->dev); | 126 | r = pm_runtime_get_sync(&hdmi.pdev->dev); |
142 | WARN_ON(r < 0); | 127 | WARN_ON(r < 0); |
143 | if (r < 0) | 128 | if (r < 0) |
144 | goto err_get_hdmi; | 129 | return r; |
145 | 130 | ||
146 | return 0; | 131 | return 0; |
147 | |||
148 | err_get_hdmi: | ||
149 | dss_runtime_put(); | ||
150 | err_get_dss: | ||
151 | return r; | ||
152 | } | 132 | } |
153 | 133 | ||
154 | static void hdmi_runtime_put(void) | 134 | static void hdmi_runtime_put(void) |
@@ -159,15 +139,9 @@ static void hdmi_runtime_put(void) | |||
159 | 139 | ||
160 | r = pm_runtime_put_sync(&hdmi.pdev->dev); | 140 | r = pm_runtime_put_sync(&hdmi.pdev->dev); |
161 | WARN_ON(r < 0); | 141 | WARN_ON(r < 0); |
162 | |||
163 | /* | ||
164 | * HACK: This is added to complement the dss_runtime_get() call in | ||
165 | * hdmi_runtime_get(). This should be removed later. | ||
166 | */ | ||
167 | dss_runtime_put(); | ||
168 | } | 142 | } |
169 | 143 | ||
170 | int hdmi_init_display(struct omap_dss_device *dssdev) | 144 | static int __init hdmi_init_display(struct omap_dss_device *dssdev) |
171 | { | 145 | { |
172 | DSSDBG("init_display\n"); | 146 | DSSDBG("init_display\n"); |
173 | 147 | ||
@@ -344,7 +318,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) | |||
344 | 318 | ||
345 | hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); | 319 | hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); |
346 | 320 | ||
347 | hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); | 321 | hdmi.ip_data.ops->video_disable(&hdmi.ip_data); |
348 | 322 | ||
349 | /* config the PLL and PHY hdmi_set_pll_pwrfirst */ | 323 | /* config the PLL and PHY hdmi_set_pll_pwrfirst */ |
350 | r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); | 324 | r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); |
@@ -376,10 +350,11 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) | |||
376 | dispc_enable_gamma_table(0); | 350 | dispc_enable_gamma_table(0); |
377 | 351 | ||
378 | /* tv size */ | 352 | /* tv size */ |
379 | dispc_set_digit_size(dssdev->panel.timings.x_res, | 353 | dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); |
380 | dssdev->panel.timings.y_res); | ||
381 | 354 | ||
382 | hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1); | 355 | r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); |
356 | if (r) | ||
357 | goto err_vid_enable; | ||
383 | 358 | ||
384 | r = dss_mgr_enable(dssdev->manager); | 359 | r = dss_mgr_enable(dssdev->manager); |
385 | if (r) | 360 | if (r) |
@@ -388,7 +363,8 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) | |||
388 | return 0; | 363 | return 0; |
389 | 364 | ||
390 | err_mgr_enable: | 365 | err_mgr_enable: |
391 | hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); | 366 | hdmi.ip_data.ops->video_disable(&hdmi.ip_data); |
367 | err_vid_enable: | ||
392 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); | 368 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); |
393 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); | 369 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); |
394 | err: | 370 | err: |
@@ -400,7 +376,7 @@ static void hdmi_power_off(struct omap_dss_device *dssdev) | |||
400 | { | 376 | { |
401 | dss_mgr_disable(dssdev->manager); | 377 | dss_mgr_disable(dssdev->manager); |
402 | 378 | ||
403 | hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); | 379 | hdmi.ip_data.ops->video_disable(&hdmi.ip_data); |
404 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); | 380 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); |
405 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); | 381 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); |
406 | hdmi_runtime_put(); | 382 | hdmi_runtime_put(); |
@@ -436,10 +412,12 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev) | |||
436 | r = hdmi_power_on(dssdev); | 412 | r = hdmi_power_on(dssdev); |
437 | if (r) | 413 | if (r) |
438 | DSSERR("failed to power on device\n"); | 414 | DSSERR("failed to power on device\n"); |
415 | } else { | ||
416 | dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); | ||
439 | } | 417 | } |
440 | } | 418 | } |
441 | 419 | ||
442 | void hdmi_dump_regs(struct seq_file *s) | 420 | static void hdmi_dump_regs(struct seq_file *s) |
443 | { | 421 | { |
444 | mutex_lock(&hdmi.lock); | 422 | mutex_lock(&hdmi.lock); |
445 | 423 | ||
@@ -555,248 +533,201 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) | |||
555 | mutex_unlock(&hdmi.lock); | 533 | mutex_unlock(&hdmi.lock); |
556 | } | 534 | } |
557 | 535 | ||
558 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | 536 | static int hdmi_get_clocks(struct platform_device *pdev) |
559 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | ||
560 | |||
561 | static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd, | ||
562 | struct snd_soc_dai *dai) | ||
563 | { | 537 | { |
564 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 538 | struct clk *clk; |
565 | struct snd_soc_codec *codec = rtd->codec; | ||
566 | struct platform_device *pdev = to_platform_device(codec->dev); | ||
567 | struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec); | ||
568 | int err = 0; | ||
569 | 539 | ||
570 | if (!(ip_data->ops) && !(ip_data->ops->audio_enable)) { | 540 | clk = clk_get(&pdev->dev, "sys_clk"); |
571 | dev_err(&pdev->dev, "Cannot enable/disable audio\n"); | 541 | if (IS_ERR(clk)) { |
572 | return -ENODEV; | 542 | DSSERR("can't get sys_clk\n"); |
543 | return PTR_ERR(clk); | ||
573 | } | 544 | } |
574 | 545 | ||
575 | switch (cmd) { | 546 | hdmi.sys_clk = clk; |
576 | case SNDRV_PCM_TRIGGER_START: | 547 | |
577 | case SNDRV_PCM_TRIGGER_RESUME: | 548 | return 0; |
578 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 549 | } |
579 | ip_data->ops->audio_enable(ip_data, true); | 550 | |
580 | break; | 551 | static void hdmi_put_clocks(void) |
581 | case SNDRV_PCM_TRIGGER_STOP: | 552 | { |
582 | case SNDRV_PCM_TRIGGER_SUSPEND: | 553 | if (hdmi.sys_clk) |
583 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 554 | clk_put(hdmi.sys_clk); |
584 | ip_data->ops->audio_enable(ip_data, false); | 555 | } |
585 | break; | 556 | |
586 | default: | 557 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
587 | err = -EINVAL; | 558 | int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts) |
588 | } | 559 | { |
589 | return err; | 560 | u32 deep_color; |
590 | } | 561 | bool deep_color_correct = false; |
591 | 562 | u32 pclk = hdmi.ip_data.cfg.timings.pixel_clock; | |
592 | static int hdmi_audio_hw_params(struct snd_pcm_substream *substream, | 563 | |
593 | struct snd_pcm_hw_params *params, | 564 | if (n == NULL || cts == NULL) |
594 | struct snd_soc_dai *dai) | ||
595 | { | ||
596 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
597 | struct snd_soc_codec *codec = rtd->codec; | ||
598 | struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec); | ||
599 | struct hdmi_audio_format audio_format; | ||
600 | struct hdmi_audio_dma audio_dma; | ||
601 | struct hdmi_core_audio_config core_cfg; | ||
602 | struct hdmi_core_infoframe_audio aud_if_cfg; | ||
603 | int err, n, cts; | ||
604 | enum hdmi_core_audio_sample_freq sample_freq; | ||
605 | |||
606 | switch (params_format(params)) { | ||
607 | case SNDRV_PCM_FORMAT_S16_LE: | ||
608 | core_cfg.i2s_cfg.word_max_length = | ||
609 | HDMI_AUDIO_I2S_MAX_WORD_20BITS; | ||
610 | core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_16_BITS; | ||
611 | core_cfg.i2s_cfg.in_length_bits = | ||
612 | HDMI_AUDIO_I2S_INPUT_LENGTH_16; | ||
613 | core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT; | ||
614 | audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; | ||
615 | audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; | ||
616 | audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; | ||
617 | audio_dma.transfer_size = 0x10; | ||
618 | break; | ||
619 | case SNDRV_PCM_FORMAT_S24_LE: | ||
620 | core_cfg.i2s_cfg.word_max_length = | ||
621 | HDMI_AUDIO_I2S_MAX_WORD_24BITS; | ||
622 | core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_24_BITS; | ||
623 | core_cfg.i2s_cfg.in_length_bits = | ||
624 | HDMI_AUDIO_I2S_INPUT_LENGTH_24; | ||
625 | audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE; | ||
626 | audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS; | ||
627 | audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT; | ||
628 | core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; | ||
629 | audio_dma.transfer_size = 0x20; | ||
630 | break; | ||
631 | default: | ||
632 | return -EINVAL; | 565 | return -EINVAL; |
633 | } | ||
634 | 566 | ||
635 | switch (params_rate(params)) { | 567 | /* TODO: When implemented, query deep color mode here. */ |
568 | deep_color = 100; | ||
569 | |||
570 | /* | ||
571 | * When using deep color, the default N value (as in the HDMI | ||
572 | * specification) yields to an non-integer CTS. Hence, we | ||
573 | * modify it while keeping the restrictions described in | ||
574 | * section 7.2.1 of the HDMI 1.4a specification. | ||
575 | */ | ||
576 | switch (sample_freq) { | ||
636 | case 32000: | 577 | case 32000: |
637 | sample_freq = HDMI_AUDIO_FS_32000; | 578 | case 48000: |
579 | case 96000: | ||
580 | case 192000: | ||
581 | if (deep_color == 125) | ||
582 | if (pclk == 27027 || pclk == 74250) | ||
583 | deep_color_correct = true; | ||
584 | if (deep_color == 150) | ||
585 | if (pclk == 27027) | ||
586 | deep_color_correct = true; | ||
638 | break; | 587 | break; |
639 | case 44100: | 588 | case 44100: |
640 | sample_freq = HDMI_AUDIO_FS_44100; | 589 | case 88200: |
641 | break; | 590 | case 176400: |
642 | case 48000: | 591 | if (deep_color == 125) |
643 | sample_freq = HDMI_AUDIO_FS_48000; | 592 | if (pclk == 27027) |
593 | deep_color_correct = true; | ||
644 | break; | 594 | break; |
645 | default: | 595 | default: |
646 | return -EINVAL; | 596 | return -EINVAL; |
647 | } | 597 | } |
648 | 598 | ||
649 | err = hdmi_config_audio_acr(ip_data, params_rate(params), &n, &cts); | 599 | if (deep_color_correct) { |
650 | if (err < 0) | 600 | switch (sample_freq) { |
651 | return err; | 601 | case 32000: |
652 | 602 | *n = 8192; | |
653 | /* Audio wrapper config */ | 603 | break; |
654 | audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; | 604 | case 44100: |
655 | audio_format.active_chnnls_msk = 0x03; | 605 | *n = 12544; |
656 | audio_format.type = HDMI_AUDIO_TYPE_LPCM; | 606 | break; |
657 | audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST; | 607 | case 48000: |
658 | /* Disable start/stop signals of IEC 60958 blocks */ | 608 | *n = 8192; |
659 | audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF; | 609 | break; |
610 | case 88200: | ||
611 | *n = 25088; | ||
612 | break; | ||
613 | case 96000: | ||
614 | *n = 16384; | ||
615 | break; | ||
616 | case 176400: | ||
617 | *n = 50176; | ||
618 | break; | ||
619 | case 192000: | ||
620 | *n = 32768; | ||
621 | break; | ||
622 | default: | ||
623 | return -EINVAL; | ||
624 | } | ||
625 | } else { | ||
626 | switch (sample_freq) { | ||
627 | case 32000: | ||
628 | *n = 4096; | ||
629 | break; | ||
630 | case 44100: | ||
631 | *n = 6272; | ||
632 | break; | ||
633 | case 48000: | ||
634 | *n = 6144; | ||
635 | break; | ||
636 | case 88200: | ||
637 | *n = 12544; | ||
638 | break; | ||
639 | case 96000: | ||
640 | *n = 12288; | ||
641 | break; | ||
642 | case 176400: | ||
643 | *n = 25088; | ||
644 | break; | ||
645 | case 192000: | ||
646 | *n = 24576; | ||
647 | break; | ||
648 | default: | ||
649 | return -EINVAL; | ||
650 | } | ||
651 | } | ||
652 | /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ | ||
653 | *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); | ||
660 | 654 | ||
661 | audio_dma.block_size = 0xC0; | 655 | return 0; |
662 | audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; | 656 | } |
663 | audio_dma.fifo_threshold = 0x20; /* in number of samples */ | ||
664 | 657 | ||
665 | hdmi_wp_audio_config_dma(ip_data, &audio_dma); | 658 | int hdmi_audio_enable(void) |
666 | hdmi_wp_audio_config_format(ip_data, &audio_format); | 659 | { |
660 | DSSDBG("audio_enable\n"); | ||
667 | 661 | ||
668 | /* | 662 | return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data); |
669 | * I2S config | 663 | } |
670 | */ | ||
671 | core_cfg.i2s_cfg.en_high_bitrate_aud = false; | ||
672 | /* Only used with high bitrate audio */ | ||
673 | core_cfg.i2s_cfg.cbit_order = false; | ||
674 | /* Serial data and word select should change on sck rising edge */ | ||
675 | core_cfg.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; | ||
676 | core_cfg.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; | ||
677 | /* Set I2S word select polarity */ | ||
678 | core_cfg.i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT; | ||
679 | core_cfg.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; | ||
680 | /* Set serial data to word select shift. See Phillips spec. */ | ||
681 | core_cfg.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT; | ||
682 | /* Enable one of the four available serial data channels */ | ||
683 | core_cfg.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; | ||
684 | |||
685 | /* Core audio config */ | ||
686 | core_cfg.freq_sample = sample_freq; | ||
687 | core_cfg.n = n; | ||
688 | core_cfg.cts = cts; | ||
689 | if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { | ||
690 | core_cfg.aud_par_busclk = 0; | ||
691 | core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW; | ||
692 | core_cfg.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK); | ||
693 | } else { | ||
694 | core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8); | ||
695 | core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW; | ||
696 | core_cfg.use_mclk = true; | ||
697 | } | ||
698 | 664 | ||
699 | if (core_cfg.use_mclk) | 665 | void hdmi_audio_disable(void) |
700 | core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS; | 666 | { |
701 | core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH; | 667 | DSSDBG("audio_disable\n"); |
702 | core_cfg.en_spdif = false; | ||
703 | /* Use sample frequency from channel status word */ | ||
704 | core_cfg.fs_override = true; | ||
705 | /* Enable ACR packets */ | ||
706 | core_cfg.en_acr_pkt = true; | ||
707 | /* Disable direct streaming digital audio */ | ||
708 | core_cfg.en_dsd_audio = false; | ||
709 | /* Use parallel audio interface */ | ||
710 | core_cfg.en_parallel_aud_input = true; | ||
711 | |||
712 | hdmi_core_audio_config(ip_data, &core_cfg); | ||
713 | 668 | ||
714 | /* | 669 | hdmi.ip_data.ops->audio_disable(&hdmi.ip_data); |
715 | * Configure packet | ||
716 | * info frame audio see doc CEA861-D page 74 | ||
717 | */ | ||
718 | aud_if_cfg.db1_coding_type = HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM; | ||
719 | aud_if_cfg.db1_channel_count = 2; | ||
720 | aud_if_cfg.db2_sample_freq = HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM; | ||
721 | aud_if_cfg.db2_sample_size = HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM; | ||
722 | aud_if_cfg.db4_channel_alloc = 0x00; | ||
723 | aud_if_cfg.db5_downmix_inh = false; | ||
724 | aud_if_cfg.db5_lsv = 0; | ||
725 | |||
726 | hdmi_core_audio_infoframe_config(ip_data, &aud_if_cfg); | ||
727 | return 0; | ||
728 | } | 670 | } |
729 | 671 | ||
730 | static int hdmi_audio_startup(struct snd_pcm_substream *substream, | 672 | int hdmi_audio_start(void) |
731 | struct snd_soc_dai *dai) | ||
732 | { | 673 | { |
733 | if (!hdmi.ip_data.cfg.cm.mode) { | 674 | DSSDBG("audio_start\n"); |
734 | pr_err("Current video settings do not support audio.\n"); | 675 | |
735 | return -EIO; | 676 | return hdmi.ip_data.ops->audio_start(&hdmi.ip_data); |
736 | } | ||
737 | return 0; | ||
738 | } | 677 | } |
739 | 678 | ||
740 | static int hdmi_audio_codec_probe(struct snd_soc_codec *codec) | 679 | void hdmi_audio_stop(void) |
741 | { | 680 | { |
742 | struct hdmi_ip_data *priv = &hdmi.ip_data; | 681 | DSSDBG("audio_stop\n"); |
743 | 682 | ||
744 | snd_soc_codec_set_drvdata(codec, priv); | 683 | hdmi.ip_data.ops->audio_stop(&hdmi.ip_data); |
745 | return 0; | ||
746 | } | 684 | } |
747 | 685 | ||
748 | static struct snd_soc_codec_driver hdmi_audio_codec_drv = { | 686 | bool hdmi_mode_has_audio(void) |
749 | .probe = hdmi_audio_codec_probe, | 687 | { |
750 | }; | 688 | if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI) |
689 | return true; | ||
690 | else | ||
691 | return false; | ||
692 | } | ||
751 | 693 | ||
752 | static struct snd_soc_dai_ops hdmi_audio_codec_ops = { | 694 | int hdmi_audio_config(struct omap_dss_audio *audio) |
753 | .hw_params = hdmi_audio_hw_params, | 695 | { |
754 | .trigger = hdmi_audio_trigger, | 696 | return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio); |
755 | .startup = hdmi_audio_startup, | 697 | } |
756 | }; | ||
757 | 698 | ||
758 | static struct snd_soc_dai_driver hdmi_codec_dai_drv = { | ||
759 | .name = "hdmi-audio-codec", | ||
760 | .playback = { | ||
761 | .channels_min = 2, | ||
762 | .channels_max = 2, | ||
763 | .rates = SNDRV_PCM_RATE_32000 | | ||
764 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, | ||
765 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
766 | SNDRV_PCM_FMTBIT_S24_LE, | ||
767 | }, | ||
768 | .ops = &hdmi_audio_codec_ops, | ||
769 | }; | ||
770 | #endif | 699 | #endif |
771 | 700 | ||
772 | static int hdmi_get_clocks(struct platform_device *pdev) | 701 | static void __init hdmi_probe_pdata(struct platform_device *pdev) |
773 | { | 702 | { |
774 | struct clk *clk; | 703 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; |
704 | int r, i; | ||
775 | 705 | ||
776 | clk = clk_get(&pdev->dev, "sys_clk"); | 706 | for (i = 0; i < pdata->num_devices; ++i) { |
777 | if (IS_ERR(clk)) { | 707 | struct omap_dss_device *dssdev = pdata->devices[i]; |
778 | DSSERR("can't get sys_clk\n"); | ||
779 | return PTR_ERR(clk); | ||
780 | } | ||
781 | 708 | ||
782 | hdmi.sys_clk = clk; | 709 | if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) |
710 | continue; | ||
783 | 711 | ||
784 | return 0; | 712 | r = hdmi_init_display(dssdev); |
785 | } | 713 | if (r) { |
714 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
715 | continue; | ||
716 | } | ||
786 | 717 | ||
787 | static void hdmi_put_clocks(void) | 718 | r = omap_dss_register_device(dssdev, &pdev->dev, i); |
788 | { | 719 | if (r) |
789 | if (hdmi.sys_clk) | 720 | DSSERR("device %s register failed: %d\n", |
790 | clk_put(hdmi.sys_clk); | 721 | dssdev->name, r); |
722 | } | ||
791 | } | 723 | } |
792 | 724 | ||
793 | /* HDMI HW IP initialisation */ | 725 | /* HDMI HW IP initialisation */ |
794 | static int omapdss_hdmihw_probe(struct platform_device *pdev) | 726 | static int __init omapdss_hdmihw_probe(struct platform_device *pdev) |
795 | { | 727 | { |
796 | struct resource *hdmi_mem; | 728 | struct resource *hdmi_mem; |
797 | int r; | 729 | int r; |
798 | 730 | ||
799 | hdmi.pdata = pdev->dev.platform_data; | ||
800 | hdmi.pdev = pdev; | 731 | hdmi.pdev = pdev; |
801 | 732 | ||
802 | mutex_init(&hdmi.lock); | 733 | mutex_init(&hdmi.lock); |
@@ -830,28 +761,18 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
830 | 761 | ||
831 | hdmi_panel_init(); | 762 | hdmi_panel_init(); |
832 | 763 | ||
833 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | 764 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); |
834 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | 765 | |
766 | hdmi_probe_pdata(pdev); | ||
835 | 767 | ||
836 | /* Register ASoC codec DAI */ | ||
837 | r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv, | ||
838 | &hdmi_codec_dai_drv, 1); | ||
839 | if (r) { | ||
840 | DSSERR("can't register ASoC HDMI audio codec\n"); | ||
841 | return r; | ||
842 | } | ||
843 | #endif | ||
844 | return 0; | 768 | return 0; |
845 | } | 769 | } |
846 | 770 | ||
847 | static int omapdss_hdmihw_remove(struct platform_device *pdev) | 771 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) |
848 | { | 772 | { |
849 | hdmi_panel_exit(); | 773 | omap_dss_unregister_child_devices(&pdev->dev); |
850 | 774 | ||
851 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | 775 | hdmi_panel_exit(); |
852 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | ||
853 | snd_soc_unregister_codec(&pdev->dev); | ||
854 | #endif | ||
855 | 776 | ||
856 | pm_runtime_disable(&pdev->dev); | 777 | pm_runtime_disable(&pdev->dev); |
857 | 778 | ||
@@ -867,7 +788,6 @@ static int hdmi_runtime_suspend(struct device *dev) | |||
867 | clk_disable(hdmi.sys_clk); | 788 | clk_disable(hdmi.sys_clk); |
868 | 789 | ||
869 | dispc_runtime_put(); | 790 | dispc_runtime_put(); |
870 | dss_runtime_put(); | ||
871 | 791 | ||
872 | return 0; | 792 | return 0; |
873 | } | 793 | } |
@@ -876,23 +796,13 @@ static int hdmi_runtime_resume(struct device *dev) | |||
876 | { | 796 | { |
877 | int r; | 797 | int r; |
878 | 798 | ||
879 | r = dss_runtime_get(); | ||
880 | if (r < 0) | ||
881 | goto err_get_dss; | ||
882 | |||
883 | r = dispc_runtime_get(); | 799 | r = dispc_runtime_get(); |
884 | if (r < 0) | 800 | if (r < 0) |
885 | goto err_get_dispc; | 801 | return r; |
886 | |||
887 | 802 | ||
888 | clk_enable(hdmi.sys_clk); | 803 | clk_enable(hdmi.sys_clk); |
889 | 804 | ||
890 | return 0; | 805 | return 0; |
891 | |||
892 | err_get_dispc: | ||
893 | dss_runtime_put(); | ||
894 | err_get_dss: | ||
895 | return r; | ||
896 | } | 806 | } |
897 | 807 | ||
898 | static const struct dev_pm_ops hdmi_pm_ops = { | 808 | static const struct dev_pm_ops hdmi_pm_ops = { |
@@ -901,8 +811,7 @@ static const struct dev_pm_ops hdmi_pm_ops = { | |||
901 | }; | 811 | }; |
902 | 812 | ||
903 | static struct platform_driver omapdss_hdmihw_driver = { | 813 | static struct platform_driver omapdss_hdmihw_driver = { |
904 | .probe = omapdss_hdmihw_probe, | 814 | .remove = __exit_p(omapdss_hdmihw_remove), |
905 | .remove = omapdss_hdmihw_remove, | ||
906 | .driver = { | 815 | .driver = { |
907 | .name = "omapdss_hdmi", | 816 | .name = "omapdss_hdmi", |
908 | .owner = THIS_MODULE, | 817 | .owner = THIS_MODULE, |
@@ -910,12 +819,12 @@ static struct platform_driver omapdss_hdmihw_driver = { | |||
910 | }, | 819 | }, |
911 | }; | 820 | }; |
912 | 821 | ||
913 | int hdmi_init_platform_driver(void) | 822 | int __init hdmi_init_platform_driver(void) |
914 | { | 823 | { |
915 | return platform_driver_register(&omapdss_hdmihw_driver); | 824 | return platform_driver_probe(&omapdss_hdmihw_driver, omapdss_hdmihw_probe); |
916 | } | 825 | } |
917 | 826 | ||
918 | void hdmi_uninit_platform_driver(void) | 827 | void __exit hdmi_uninit_platform_driver(void) |
919 | { | 828 | { |
920 | return platform_driver_unregister(&omapdss_hdmihw_driver); | 829 | platform_driver_unregister(&omapdss_hdmihw_driver); |
921 | } | 830 | } |
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c index 533d5dc634d2..1179e3c4b1c7 100644 --- a/drivers/video/omap2/dss/hdmi_panel.c +++ b/drivers/video/omap2/dss/hdmi_panel.c | |||
@@ -30,7 +30,12 @@ | |||
30 | #include "dss.h" | 30 | #include "dss.h" |
31 | 31 | ||
32 | static struct { | 32 | static struct { |
33 | struct mutex hdmi_lock; | 33 | /* This protects the panel ops, mainly when accessing the HDMI IP. */ |
34 | struct mutex lock; | ||
35 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | ||
36 | /* This protects the audio ops, specifically. */ | ||
37 | spinlock_t audio_lock; | ||
38 | #endif | ||
34 | } hdmi; | 39 | } hdmi; |
35 | 40 | ||
36 | 41 | ||
@@ -54,12 +59,168 @@ static void hdmi_panel_remove(struct omap_dss_device *dssdev) | |||
54 | 59 | ||
55 | } | 60 | } |
56 | 61 | ||
62 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | ||
63 | static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev) | ||
64 | { | ||
65 | unsigned long flags; | ||
66 | int r; | ||
67 | |||
68 | mutex_lock(&hdmi.lock); | ||
69 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
70 | |||
71 | /* enable audio only if the display is active and supports audio */ | ||
72 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || | ||
73 | !hdmi_mode_has_audio()) { | ||
74 | DSSERR("audio not supported or display is off\n"); | ||
75 | r = -EPERM; | ||
76 | goto err; | ||
77 | } | ||
78 | |||
79 | r = hdmi_audio_enable(); | ||
80 | |||
81 | if (!r) | ||
82 | dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; | ||
83 | |||
84 | err: | ||
85 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
86 | mutex_unlock(&hdmi.lock); | ||
87 | return r; | ||
88 | } | ||
89 | |||
90 | static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev) | ||
91 | { | ||
92 | unsigned long flags; | ||
93 | |||
94 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
95 | |||
96 | hdmi_audio_disable(); | ||
97 | |||
98 | dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED; | ||
99 | |||
100 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
101 | } | ||
102 | |||
103 | static int hdmi_panel_audio_start(struct omap_dss_device *dssdev) | ||
104 | { | ||
105 | unsigned long flags; | ||
106 | int r; | ||
107 | |||
108 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
109 | /* | ||
110 | * No need to check the panel state. It was checked when trasitioning | ||
111 | * to AUDIO_ENABLED. | ||
112 | */ | ||
113 | if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED) { | ||
114 | DSSERR("audio start from invalid state\n"); | ||
115 | r = -EPERM; | ||
116 | goto err; | ||
117 | } | ||
118 | |||
119 | r = hdmi_audio_start(); | ||
120 | |||
121 | if (!r) | ||
122 | dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING; | ||
123 | |||
124 | err: | ||
125 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
126 | return r; | ||
127 | } | ||
128 | |||
129 | static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev) | ||
130 | { | ||
131 | unsigned long flags; | ||
132 | |||
133 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
134 | |||
135 | hdmi_audio_stop(); | ||
136 | dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; | ||
137 | |||
138 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
139 | } | ||
140 | |||
141 | static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev) | ||
142 | { | ||
143 | bool r = false; | ||
144 | |||
145 | mutex_lock(&hdmi.lock); | ||
146 | |||
147 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
148 | goto err; | ||
149 | |||
150 | if (!hdmi_mode_has_audio()) | ||
151 | goto err; | ||
152 | |||
153 | r = true; | ||
154 | err: | ||
155 | mutex_unlock(&hdmi.lock); | ||
156 | return r; | ||
157 | } | ||
158 | |||
159 | static int hdmi_panel_audio_config(struct omap_dss_device *dssdev, | ||
160 | struct omap_dss_audio *audio) | ||
161 | { | ||
162 | unsigned long flags; | ||
163 | int r; | ||
164 | |||
165 | mutex_lock(&hdmi.lock); | ||
166 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
167 | |||
168 | /* config audio only if the display is active and supports audio */ | ||
169 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || | ||
170 | !hdmi_mode_has_audio()) { | ||
171 | DSSERR("audio not supported or display is off\n"); | ||
172 | r = -EPERM; | ||
173 | goto err; | ||
174 | } | ||
175 | |||
176 | r = hdmi_audio_config(audio); | ||
177 | |||
178 | if (!r) | ||
179 | dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED; | ||
180 | |||
181 | err: | ||
182 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
183 | mutex_unlock(&hdmi.lock); | ||
184 | return r; | ||
185 | } | ||
186 | |||
187 | #else | ||
188 | static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev) | ||
189 | { | ||
190 | return -EPERM; | ||
191 | } | ||
192 | |||
193 | static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev) | ||
194 | { | ||
195 | } | ||
196 | |||
197 | static int hdmi_panel_audio_start(struct omap_dss_device *dssdev) | ||
198 | { | ||
199 | return -EPERM; | ||
200 | } | ||
201 | |||
202 | static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev) | ||
203 | { | ||
204 | } | ||
205 | |||
206 | static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev) | ||
207 | { | ||
208 | return false; | ||
209 | } | ||
210 | |||
211 | static int hdmi_panel_audio_config(struct omap_dss_device *dssdev, | ||
212 | struct omap_dss_audio *audio) | ||
213 | { | ||
214 | return -EPERM; | ||
215 | } | ||
216 | #endif | ||
217 | |||
57 | static int hdmi_panel_enable(struct omap_dss_device *dssdev) | 218 | static int hdmi_panel_enable(struct omap_dss_device *dssdev) |
58 | { | 219 | { |
59 | int r = 0; | 220 | int r = 0; |
60 | DSSDBG("ENTER hdmi_panel_enable\n"); | 221 | DSSDBG("ENTER hdmi_panel_enable\n"); |
61 | 222 | ||
62 | mutex_lock(&hdmi.hdmi_lock); | 223 | mutex_lock(&hdmi.lock); |
63 | 224 | ||
64 | if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { | 225 | if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { |
65 | r = -EINVAL; | 226 | r = -EINVAL; |
@@ -75,40 +236,52 @@ static int hdmi_panel_enable(struct omap_dss_device *dssdev) | |||
75 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | 236 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; |
76 | 237 | ||
77 | err: | 238 | err: |
78 | mutex_unlock(&hdmi.hdmi_lock); | 239 | mutex_unlock(&hdmi.lock); |
79 | 240 | ||
80 | return r; | 241 | return r; |
81 | } | 242 | } |
82 | 243 | ||
83 | static void hdmi_panel_disable(struct omap_dss_device *dssdev) | 244 | static void hdmi_panel_disable(struct omap_dss_device *dssdev) |
84 | { | 245 | { |
85 | mutex_lock(&hdmi.hdmi_lock); | 246 | mutex_lock(&hdmi.lock); |
86 | 247 | ||
87 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | 248 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { |
249 | /* | ||
250 | * TODO: notify audio users that the display was disabled. For | ||
251 | * now, disable audio locally to not break our audio state | ||
252 | * machine. | ||
253 | */ | ||
254 | hdmi_panel_audio_disable(dssdev); | ||
88 | omapdss_hdmi_display_disable(dssdev); | 255 | omapdss_hdmi_display_disable(dssdev); |
256 | } | ||
89 | 257 | ||
90 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | 258 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; |
91 | 259 | ||
92 | mutex_unlock(&hdmi.hdmi_lock); | 260 | mutex_unlock(&hdmi.lock); |
93 | } | 261 | } |
94 | 262 | ||
95 | static int hdmi_panel_suspend(struct omap_dss_device *dssdev) | 263 | static int hdmi_panel_suspend(struct omap_dss_device *dssdev) |
96 | { | 264 | { |
97 | int r = 0; | 265 | int r = 0; |
98 | 266 | ||
99 | mutex_lock(&hdmi.hdmi_lock); | 267 | mutex_lock(&hdmi.lock); |
100 | 268 | ||
101 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { | 269 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { |
102 | r = -EINVAL; | 270 | r = -EINVAL; |
103 | goto err; | 271 | goto err; |
104 | } | 272 | } |
105 | 273 | ||
106 | dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; | 274 | /* |
275 | * TODO: notify audio users that the display was suspended. For now, | ||
276 | * disable audio locally to not break our audio state machine. | ||
277 | */ | ||
278 | hdmi_panel_audio_disable(dssdev); | ||
107 | 279 | ||
280 | dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; | ||
108 | omapdss_hdmi_display_disable(dssdev); | 281 | omapdss_hdmi_display_disable(dssdev); |
109 | 282 | ||
110 | err: | 283 | err: |
111 | mutex_unlock(&hdmi.hdmi_lock); | 284 | mutex_unlock(&hdmi.lock); |
112 | 285 | ||
113 | return r; | 286 | return r; |
114 | } | 287 | } |
@@ -117,7 +290,7 @@ static int hdmi_panel_resume(struct omap_dss_device *dssdev) | |||
117 | { | 290 | { |
118 | int r = 0; | 291 | int r = 0; |
119 | 292 | ||
120 | mutex_lock(&hdmi.hdmi_lock); | 293 | mutex_lock(&hdmi.lock); |
121 | 294 | ||
122 | if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { | 295 | if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { |
123 | r = -EINVAL; | 296 | r = -EINVAL; |
@@ -129,11 +302,12 @@ static int hdmi_panel_resume(struct omap_dss_device *dssdev) | |||
129 | DSSERR("failed to power on\n"); | 302 | DSSERR("failed to power on\n"); |
130 | goto err; | 303 | goto err; |
131 | } | 304 | } |
305 | /* TODO: notify audio users that the panel resumed. */ | ||
132 | 306 | ||
133 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | 307 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; |
134 | 308 | ||
135 | err: | 309 | err: |
136 | mutex_unlock(&hdmi.hdmi_lock); | 310 | mutex_unlock(&hdmi.lock); |
137 | 311 | ||
138 | return r; | 312 | return r; |
139 | } | 313 | } |
@@ -141,11 +315,11 @@ err: | |||
141 | static void hdmi_get_timings(struct omap_dss_device *dssdev, | 315 | static void hdmi_get_timings(struct omap_dss_device *dssdev, |
142 | struct omap_video_timings *timings) | 316 | struct omap_video_timings *timings) |
143 | { | 317 | { |
144 | mutex_lock(&hdmi.hdmi_lock); | 318 | mutex_lock(&hdmi.lock); |
145 | 319 | ||
146 | *timings = dssdev->panel.timings; | 320 | *timings = dssdev->panel.timings; |
147 | 321 | ||
148 | mutex_unlock(&hdmi.hdmi_lock); | 322 | mutex_unlock(&hdmi.lock); |
149 | } | 323 | } |
150 | 324 | ||
151 | static void hdmi_set_timings(struct omap_dss_device *dssdev, | 325 | static void hdmi_set_timings(struct omap_dss_device *dssdev, |
@@ -153,12 +327,18 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev, | |||
153 | { | 327 | { |
154 | DSSDBG("hdmi_set_timings\n"); | 328 | DSSDBG("hdmi_set_timings\n"); |
155 | 329 | ||
156 | mutex_lock(&hdmi.hdmi_lock); | 330 | mutex_lock(&hdmi.lock); |
331 | |||
332 | /* | ||
333 | * TODO: notify audio users that there was a timings change. For | ||
334 | * now, disable audio locally to not break our audio state machine. | ||
335 | */ | ||
336 | hdmi_panel_audio_disable(dssdev); | ||
157 | 337 | ||
158 | dssdev->panel.timings = *timings; | 338 | dssdev->panel.timings = *timings; |
159 | omapdss_hdmi_display_set_timing(dssdev); | 339 | omapdss_hdmi_display_set_timing(dssdev); |
160 | 340 | ||
161 | mutex_unlock(&hdmi.hdmi_lock); | 341 | mutex_unlock(&hdmi.lock); |
162 | } | 342 | } |
163 | 343 | ||
164 | static int hdmi_check_timings(struct omap_dss_device *dssdev, | 344 | static int hdmi_check_timings(struct omap_dss_device *dssdev, |
@@ -168,11 +348,11 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev, | |||
168 | 348 | ||
169 | DSSDBG("hdmi_check_timings\n"); | 349 | DSSDBG("hdmi_check_timings\n"); |
170 | 350 | ||
171 | mutex_lock(&hdmi.hdmi_lock); | 351 | mutex_lock(&hdmi.lock); |
172 | 352 | ||
173 | r = omapdss_hdmi_display_check_timing(dssdev, timings); | 353 | r = omapdss_hdmi_display_check_timing(dssdev, timings); |
174 | 354 | ||
175 | mutex_unlock(&hdmi.hdmi_lock); | 355 | mutex_unlock(&hdmi.lock); |
176 | return r; | 356 | return r; |
177 | } | 357 | } |
178 | 358 | ||
@@ -180,7 +360,7 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len) | |||
180 | { | 360 | { |
181 | int r; | 361 | int r; |
182 | 362 | ||
183 | mutex_lock(&hdmi.hdmi_lock); | 363 | mutex_lock(&hdmi.lock); |
184 | 364 | ||
185 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { | 365 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { |
186 | r = omapdss_hdmi_display_enable(dssdev); | 366 | r = omapdss_hdmi_display_enable(dssdev); |
@@ -194,7 +374,7 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len) | |||
194 | dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) | 374 | dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) |
195 | omapdss_hdmi_display_disable(dssdev); | 375 | omapdss_hdmi_display_disable(dssdev); |
196 | err: | 376 | err: |
197 | mutex_unlock(&hdmi.hdmi_lock); | 377 | mutex_unlock(&hdmi.lock); |
198 | 378 | ||
199 | return r; | 379 | return r; |
200 | } | 380 | } |
@@ -203,7 +383,7 @@ static bool hdmi_detect(struct omap_dss_device *dssdev) | |||
203 | { | 383 | { |
204 | int r; | 384 | int r; |
205 | 385 | ||
206 | mutex_lock(&hdmi.hdmi_lock); | 386 | mutex_lock(&hdmi.lock); |
207 | 387 | ||
208 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { | 388 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { |
209 | r = omapdss_hdmi_display_enable(dssdev); | 389 | r = omapdss_hdmi_display_enable(dssdev); |
@@ -217,7 +397,7 @@ static bool hdmi_detect(struct omap_dss_device *dssdev) | |||
217 | dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) | 397 | dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) |
218 | omapdss_hdmi_display_disable(dssdev); | 398 | omapdss_hdmi_display_disable(dssdev); |
219 | err: | 399 | err: |
220 | mutex_unlock(&hdmi.hdmi_lock); | 400 | mutex_unlock(&hdmi.lock); |
221 | 401 | ||
222 | return r; | 402 | return r; |
223 | } | 403 | } |
@@ -234,6 +414,12 @@ static struct omap_dss_driver hdmi_driver = { | |||
234 | .check_timings = hdmi_check_timings, | 414 | .check_timings = hdmi_check_timings, |
235 | .read_edid = hdmi_read_edid, | 415 | .read_edid = hdmi_read_edid, |
236 | .detect = hdmi_detect, | 416 | .detect = hdmi_detect, |
417 | .audio_enable = hdmi_panel_audio_enable, | ||
418 | .audio_disable = hdmi_panel_audio_disable, | ||
419 | .audio_start = hdmi_panel_audio_start, | ||
420 | .audio_stop = hdmi_panel_audio_stop, | ||
421 | .audio_supported = hdmi_panel_audio_supported, | ||
422 | .audio_config = hdmi_panel_audio_config, | ||
237 | .driver = { | 423 | .driver = { |
238 | .name = "hdmi_panel", | 424 | .name = "hdmi_panel", |
239 | .owner = THIS_MODULE, | 425 | .owner = THIS_MODULE, |
@@ -242,7 +428,11 @@ static struct omap_dss_driver hdmi_driver = { | |||
242 | 428 | ||
243 | int hdmi_panel_init(void) | 429 | int hdmi_panel_init(void) |
244 | { | 430 | { |
245 | mutex_init(&hdmi.hdmi_lock); | 431 | mutex_init(&hdmi.lock); |
432 | |||
433 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | ||
434 | spin_lock_init(&hdmi.audio_lock); | ||
435 | #endif | ||
246 | 436 | ||
247 | omap_dss_register_driver(&hdmi_driver); | 437 | omap_dss_register_driver(&hdmi_driver); |
248 | 438 | ||
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index e7364603f6a1..0cbcde4c688a 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c | |||
@@ -654,9 +654,20 @@ static int dss_mgr_check_zorder(struct omap_overlay_manager *mgr, | |||
654 | return 0; | 654 | return 0; |
655 | } | 655 | } |
656 | 656 | ||
657 | int dss_mgr_check_timings(struct omap_overlay_manager *mgr, | ||
658 | const struct omap_video_timings *timings) | ||
659 | { | ||
660 | if (!dispc_mgr_timings_ok(mgr->id, timings)) { | ||
661 | DSSERR("check_manager: invalid timings\n"); | ||
662 | return -EINVAL; | ||
663 | } | ||
664 | |||
665 | return 0; | ||
666 | } | ||
667 | |||
657 | int dss_mgr_check(struct omap_overlay_manager *mgr, | 668 | int dss_mgr_check(struct omap_overlay_manager *mgr, |
658 | struct omap_dss_device *dssdev, | ||
659 | struct omap_overlay_manager_info *info, | 669 | struct omap_overlay_manager_info *info, |
670 | const struct omap_video_timings *mgr_timings, | ||
660 | struct omap_overlay_info **overlay_infos) | 671 | struct omap_overlay_info **overlay_infos) |
661 | { | 672 | { |
662 | struct omap_overlay *ovl; | 673 | struct omap_overlay *ovl; |
@@ -668,6 +679,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr, | |||
668 | return r; | 679 | return r; |
669 | } | 680 | } |
670 | 681 | ||
682 | r = dss_mgr_check_timings(mgr, mgr_timings); | ||
683 | if (r) | ||
684 | return r; | ||
685 | |||
671 | list_for_each_entry(ovl, &mgr->overlays, list) { | 686 | list_for_each_entry(ovl, &mgr->overlays, list) { |
672 | struct omap_overlay_info *oi; | 687 | struct omap_overlay_info *oi; |
673 | int r; | 688 | int r; |
@@ -677,7 +692,7 @@ int dss_mgr_check(struct omap_overlay_manager *mgr, | |||
677 | if (oi == NULL) | 692 | if (oi == NULL) |
678 | continue; | 693 | continue; |
679 | 694 | ||
680 | r = dss_ovl_check(ovl, oi, dssdev); | 695 | r = dss_ovl_check(ovl, oi, mgr_timings); |
681 | if (r) | 696 | if (r) |
682 | return r; | 697 | return r; |
683 | } | 698 | } |
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 6e821810deec..b0ba60f88dd2 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c | |||
@@ -628,19 +628,23 @@ int dss_ovl_simple_check(struct omap_overlay *ovl, | |||
628 | return -EINVAL; | 628 | return -EINVAL; |
629 | } | 629 | } |
630 | 630 | ||
631 | if (dss_feat_rotation_type_supported(info->rotation_type) == 0) { | ||
632 | DSSERR("check_overlay: rotation type %d not supported\n", | ||
633 | info->rotation_type); | ||
634 | return -EINVAL; | ||
635 | } | ||
636 | |||
631 | return 0; | 637 | return 0; |
632 | } | 638 | } |
633 | 639 | ||
634 | int dss_ovl_check(struct omap_overlay *ovl, | 640 | int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, |
635 | struct omap_overlay_info *info, struct omap_dss_device *dssdev) | 641 | const struct omap_video_timings *mgr_timings) |
636 | { | 642 | { |
637 | u16 outw, outh; | 643 | u16 outw, outh; |
638 | u16 dw, dh; | 644 | u16 dw, dh; |
639 | 645 | ||
640 | if (dssdev == NULL) | 646 | dw = mgr_timings->x_res; |
641 | return 0; | 647 | dh = mgr_timings->y_res; |
642 | |||
643 | dssdev->driver->get_resolution(dssdev, &dw, &dh); | ||
644 | 648 | ||
645 | if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { | 649 | if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { |
646 | outw = info->width; | 650 | outw = info->width; |
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 788a0ef6323a..3d8c206e90e5 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c | |||
@@ -304,13 +304,23 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, | |||
304 | u16 height, void (*callback)(void *data), void *data) | 304 | u16 height, void (*callback)(void *data), void *data) |
305 | { | 305 | { |
306 | u32 l; | 306 | u32 l; |
307 | struct omap_video_timings timings = { | ||
308 | .hsw = 1, | ||
309 | .hfp = 1, | ||
310 | .hbp = 1, | ||
311 | .vsw = 1, | ||
312 | .vfp = 0, | ||
313 | .vbp = 0, | ||
314 | .x_res = width, | ||
315 | .y_res = height, | ||
316 | }; | ||
307 | 317 | ||
308 | /*BUG_ON(callback == 0);*/ | 318 | /*BUG_ON(callback == 0);*/ |
309 | BUG_ON(rfbi.framedone_callback != NULL); | 319 | BUG_ON(rfbi.framedone_callback != NULL); |
310 | 320 | ||
311 | DSSDBG("rfbi_transfer_area %dx%d\n", width, height); | 321 | DSSDBG("rfbi_transfer_area %dx%d\n", width, height); |
312 | 322 | ||
313 | dispc_mgr_set_lcd_size(dssdev->manager->id, width, height); | 323 | dss_mgr_set_timings(dssdev->manager, &timings); |
314 | 324 | ||
315 | dispc_mgr_enable(dssdev->manager->id, true); | 325 | dispc_mgr_enable(dssdev->manager->id, true); |
316 | 326 | ||
@@ -766,6 +776,16 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, | |||
766 | u16 *x, u16 *y, u16 *w, u16 *h) | 776 | u16 *x, u16 *y, u16 *w, u16 *h) |
767 | { | 777 | { |
768 | u16 dw, dh; | 778 | u16 dw, dh; |
779 | struct omap_video_timings timings = { | ||
780 | .hsw = 1, | ||
781 | .hfp = 1, | ||
782 | .hbp = 1, | ||
783 | .vsw = 1, | ||
784 | .vfp = 0, | ||
785 | .vbp = 0, | ||
786 | .x_res = *w, | ||
787 | .y_res = *h, | ||
788 | }; | ||
769 | 789 | ||
770 | dssdev->driver->get_resolution(dssdev, &dw, &dh); | 790 | dssdev->driver->get_resolution(dssdev, &dw, &dh); |
771 | 791 | ||
@@ -784,7 +804,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, | |||
784 | if (*w == 0 || *h == 0) | 804 | if (*w == 0 || *h == 0) |
785 | return -EINVAL; | 805 | return -EINVAL; |
786 | 806 | ||
787 | dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h); | 807 | dss_mgr_set_timings(dssdev->manager, &timings); |
788 | 808 | ||
789 | return 0; | 809 | return 0; |
790 | } | 810 | } |
@@ -799,7 +819,7 @@ int omap_rfbi_update(struct omap_dss_device *dssdev, | |||
799 | } | 819 | } |
800 | EXPORT_SYMBOL(omap_rfbi_update); | 820 | EXPORT_SYMBOL(omap_rfbi_update); |
801 | 821 | ||
802 | void rfbi_dump_regs(struct seq_file *s) | 822 | static void rfbi_dump_regs(struct seq_file *s) |
803 | { | 823 | { |
804 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) | 824 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) |
805 | 825 | ||
@@ -900,15 +920,39 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) | |||
900 | } | 920 | } |
901 | EXPORT_SYMBOL(omapdss_rfbi_display_disable); | 921 | EXPORT_SYMBOL(omapdss_rfbi_display_disable); |
902 | 922 | ||
903 | int rfbi_init_display(struct omap_dss_device *dssdev) | 923 | static int __init rfbi_init_display(struct omap_dss_device *dssdev) |
904 | { | 924 | { |
905 | rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; | 925 | rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; |
906 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; | 926 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; |
907 | return 0; | 927 | return 0; |
908 | } | 928 | } |
909 | 929 | ||
930 | static void __init rfbi_probe_pdata(struct platform_device *pdev) | ||
931 | { | ||
932 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
933 | int i, r; | ||
934 | |||
935 | for (i = 0; i < pdata->num_devices; ++i) { | ||
936 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
937 | |||
938 | if (dssdev->type != OMAP_DISPLAY_TYPE_DBI) | ||
939 | continue; | ||
940 | |||
941 | r = rfbi_init_display(dssdev); | ||
942 | if (r) { | ||
943 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
944 | continue; | ||
945 | } | ||
946 | |||
947 | r = omap_dss_register_device(dssdev, &pdev->dev, i); | ||
948 | if (r) | ||
949 | DSSERR("device %s register failed: %d\n", | ||
950 | dssdev->name, r); | ||
951 | } | ||
952 | } | ||
953 | |||
910 | /* RFBI HW IP initialisation */ | 954 | /* RFBI HW IP initialisation */ |
911 | static int omap_rfbihw_probe(struct platform_device *pdev) | 955 | static int __init omap_rfbihw_probe(struct platform_device *pdev) |
912 | { | 956 | { |
913 | u32 rev; | 957 | u32 rev; |
914 | struct resource *rfbi_mem; | 958 | struct resource *rfbi_mem; |
@@ -956,6 +1000,10 @@ static int omap_rfbihw_probe(struct platform_device *pdev) | |||
956 | 1000 | ||
957 | rfbi_runtime_put(); | 1001 | rfbi_runtime_put(); |
958 | 1002 | ||
1003 | dss_debugfs_create_file("rfbi", rfbi_dump_regs); | ||
1004 | |||
1005 | rfbi_probe_pdata(pdev); | ||
1006 | |||
959 | return 0; | 1007 | return 0; |
960 | 1008 | ||
961 | err_runtime_get: | 1009 | err_runtime_get: |
@@ -963,8 +1011,9 @@ err_runtime_get: | |||
963 | return r; | 1011 | return r; |
964 | } | 1012 | } |
965 | 1013 | ||
966 | static int omap_rfbihw_remove(struct platform_device *pdev) | 1014 | static int __exit omap_rfbihw_remove(struct platform_device *pdev) |
967 | { | 1015 | { |
1016 | omap_dss_unregister_child_devices(&pdev->dev); | ||
968 | pm_runtime_disable(&pdev->dev); | 1017 | pm_runtime_disable(&pdev->dev); |
969 | return 0; | 1018 | return 0; |
970 | } | 1019 | } |
@@ -972,7 +1021,6 @@ static int omap_rfbihw_remove(struct platform_device *pdev) | |||
972 | static int rfbi_runtime_suspend(struct device *dev) | 1021 | static int rfbi_runtime_suspend(struct device *dev) |
973 | { | 1022 | { |
974 | dispc_runtime_put(); | 1023 | dispc_runtime_put(); |
975 | dss_runtime_put(); | ||
976 | 1024 | ||
977 | return 0; | 1025 | return 0; |
978 | } | 1026 | } |
@@ -981,20 +1029,11 @@ static int rfbi_runtime_resume(struct device *dev) | |||
981 | { | 1029 | { |
982 | int r; | 1030 | int r; |
983 | 1031 | ||
984 | r = dss_runtime_get(); | ||
985 | if (r < 0) | ||
986 | goto err_get_dss; | ||
987 | |||
988 | r = dispc_runtime_get(); | 1032 | r = dispc_runtime_get(); |
989 | if (r < 0) | 1033 | if (r < 0) |
990 | goto err_get_dispc; | 1034 | return r; |
991 | 1035 | ||
992 | return 0; | 1036 | return 0; |
993 | |||
994 | err_get_dispc: | ||
995 | dss_runtime_put(); | ||
996 | err_get_dss: | ||
997 | return r; | ||
998 | } | 1037 | } |
999 | 1038 | ||
1000 | static const struct dev_pm_ops rfbi_pm_ops = { | 1039 | static const struct dev_pm_ops rfbi_pm_ops = { |
@@ -1003,8 +1042,7 @@ static const struct dev_pm_ops rfbi_pm_ops = { | |||
1003 | }; | 1042 | }; |
1004 | 1043 | ||
1005 | static struct platform_driver omap_rfbihw_driver = { | 1044 | static struct platform_driver omap_rfbihw_driver = { |
1006 | .probe = omap_rfbihw_probe, | 1045 | .remove = __exit_p(omap_rfbihw_remove), |
1007 | .remove = omap_rfbihw_remove, | ||
1008 | .driver = { | 1046 | .driver = { |
1009 | .name = "omapdss_rfbi", | 1047 | .name = "omapdss_rfbi", |
1010 | .owner = THIS_MODULE, | 1048 | .owner = THIS_MODULE, |
@@ -1012,12 +1050,12 @@ static struct platform_driver omap_rfbihw_driver = { | |||
1012 | }, | 1050 | }, |
1013 | }; | 1051 | }; |
1014 | 1052 | ||
1015 | int rfbi_init_platform_driver(void) | 1053 | int __init rfbi_init_platform_driver(void) |
1016 | { | 1054 | { |
1017 | return platform_driver_register(&omap_rfbihw_driver); | 1055 | return platform_driver_probe(&omap_rfbihw_driver, omap_rfbihw_probe); |
1018 | } | 1056 | } |
1019 | 1057 | ||
1020 | void rfbi_uninit_platform_driver(void) | 1058 | void __exit rfbi_uninit_platform_driver(void) |
1021 | { | 1059 | { |
1022 | return platform_driver_unregister(&omap_rfbihw_driver); | 1060 | platform_driver_unregister(&omap_rfbihw_driver); |
1023 | } | 1061 | } |
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 8266ca0d666b..3a43dc2a9b46 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/regulator/consumer.h> | 25 | #include <linux/regulator/consumer.h> |
26 | #include <linux/export.h> | 26 | #include <linux/export.h> |
27 | #include <linux/platform_device.h> | ||
27 | 28 | ||
28 | #include <video/omapdss.h> | 29 | #include <video/omapdss.h> |
29 | #include "dss.h" | 30 | #include "dss.h" |
@@ -71,10 +72,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
71 | if (r) | 72 | if (r) |
72 | goto err_reg_enable; | 73 | goto err_reg_enable; |
73 | 74 | ||
74 | r = dss_runtime_get(); | ||
75 | if (r) | ||
76 | goto err_get_dss; | ||
77 | |||
78 | r = dispc_runtime_get(); | 75 | r = dispc_runtime_get(); |
79 | if (r) | 76 | if (r) |
80 | goto err_get_dispc; | 77 | goto err_get_dispc; |
@@ -107,7 +104,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
107 | } | 104 | } |
108 | 105 | ||
109 | 106 | ||
110 | dispc_mgr_set_lcd_timings(dssdev->manager->id, t); | 107 | dss_mgr_set_timings(dssdev->manager, t); |
111 | 108 | ||
112 | r = dss_set_clock_div(&dss_cinfo); | 109 | r = dss_set_clock_div(&dss_cinfo); |
113 | if (r) | 110 | if (r) |
@@ -137,8 +134,6 @@ err_set_dss_clock_div: | |||
137 | err_calc_clock_div: | 134 | err_calc_clock_div: |
138 | dispc_runtime_put(); | 135 | dispc_runtime_put(); |
139 | err_get_dispc: | 136 | err_get_dispc: |
140 | dss_runtime_put(); | ||
141 | err_get_dss: | ||
142 | regulator_disable(sdi.vdds_sdi_reg); | 137 | regulator_disable(sdi.vdds_sdi_reg); |
143 | err_reg_enable: | 138 | err_reg_enable: |
144 | omap_dss_stop_device(dssdev); | 139 | omap_dss_stop_device(dssdev); |
@@ -154,7 +149,6 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) | |||
154 | dss_sdi_disable(); | 149 | dss_sdi_disable(); |
155 | 150 | ||
156 | dispc_runtime_put(); | 151 | dispc_runtime_put(); |
157 | dss_runtime_put(); | ||
158 | 152 | ||
159 | regulator_disable(sdi.vdds_sdi_reg); | 153 | regulator_disable(sdi.vdds_sdi_reg); |
160 | 154 | ||
@@ -162,7 +156,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) | |||
162 | } | 156 | } |
163 | EXPORT_SYMBOL(omapdss_sdi_display_disable); | 157 | EXPORT_SYMBOL(omapdss_sdi_display_disable); |
164 | 158 | ||
165 | int sdi_init_display(struct omap_dss_device *dssdev) | 159 | static int __init sdi_init_display(struct omap_dss_device *dssdev) |
166 | { | 160 | { |
167 | DSSDBG("SDI init\n"); | 161 | DSSDBG("SDI init\n"); |
168 | 162 | ||
@@ -182,11 +176,58 @@ int sdi_init_display(struct omap_dss_device *dssdev) | |||
182 | return 0; | 176 | return 0; |
183 | } | 177 | } |
184 | 178 | ||
185 | int sdi_init(void) | 179 | static void __init sdi_probe_pdata(struct platform_device *pdev) |
180 | { | ||
181 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
182 | int i, r; | ||
183 | |||
184 | for (i = 0; i < pdata->num_devices; ++i) { | ||
185 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
186 | |||
187 | if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) | ||
188 | continue; | ||
189 | |||
190 | r = sdi_init_display(dssdev); | ||
191 | if (r) { | ||
192 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
193 | continue; | ||
194 | } | ||
195 | |||
196 | r = omap_dss_register_device(dssdev, &pdev->dev, i); | ||
197 | if (r) | ||
198 | DSSERR("device %s register failed: %d\n", | ||
199 | dssdev->name, r); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | static int __init omap_sdi_probe(struct platform_device *pdev) | ||
186 | { | 204 | { |
205 | sdi_probe_pdata(pdev); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static int __exit omap_sdi_remove(struct platform_device *pdev) | ||
211 | { | ||
212 | omap_dss_unregister_child_devices(&pdev->dev); | ||
213 | |||
187 | return 0; | 214 | return 0; |
188 | } | 215 | } |
189 | 216 | ||
190 | void sdi_exit(void) | 217 | static struct platform_driver omap_sdi_driver = { |
218 | .remove = __exit_p(omap_sdi_remove), | ||
219 | .driver = { | ||
220 | .name = "omapdss_sdi", | ||
221 | .owner = THIS_MODULE, | ||
222 | }, | ||
223 | }; | ||
224 | |||
225 | int __init sdi_init_platform_driver(void) | ||
226 | { | ||
227 | return platform_driver_probe(&omap_sdi_driver, omap_sdi_probe); | ||
228 | } | ||
229 | |||
230 | void __exit sdi_uninit_platform_driver(void) | ||
191 | { | 231 | { |
232 | platform_driver_unregister(&omap_sdi_driver); | ||
192 | } | 233 | } |
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h index 1f58b84d6901..e734cb444bc7 100644 --- a/drivers/video/omap2/dss/ti_hdmi.h +++ b/drivers/video/omap2/dss/ti_hdmi.h | |||
@@ -96,7 +96,9 @@ struct ti_hdmi_ip_ops { | |||
96 | 96 | ||
97 | void (*pll_disable)(struct hdmi_ip_data *ip_data); | 97 | void (*pll_disable)(struct hdmi_ip_data *ip_data); |
98 | 98 | ||
99 | void (*video_enable)(struct hdmi_ip_data *ip_data, bool start); | 99 | int (*video_enable)(struct hdmi_ip_data *ip_data); |
100 | |||
101 | void (*video_disable)(struct hdmi_ip_data *ip_data); | ||
100 | 102 | ||
101 | void (*dump_wrapper)(struct hdmi_ip_data *ip_data, struct seq_file *s); | 103 | void (*dump_wrapper)(struct hdmi_ip_data *ip_data, struct seq_file *s); |
102 | 104 | ||
@@ -106,9 +108,17 @@ struct ti_hdmi_ip_ops { | |||
106 | 108 | ||
107 | void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s); | 109 | void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s); |
108 | 110 | ||
109 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | 111 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
110 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | 112 | int (*audio_enable)(struct hdmi_ip_data *ip_data); |
111 | void (*audio_enable)(struct hdmi_ip_data *ip_data, bool start); | 113 | |
114 | void (*audio_disable)(struct hdmi_ip_data *ip_data); | ||
115 | |||
116 | int (*audio_start)(struct hdmi_ip_data *ip_data); | ||
117 | |||
118 | void (*audio_stop)(struct hdmi_ip_data *ip_data); | ||
119 | |||
120 | int (*audio_config)(struct hdmi_ip_data *ip_data, | ||
121 | struct omap_dss_audio *audio); | ||
112 | #endif | 122 | #endif |
113 | 123 | ||
114 | }; | 124 | }; |
@@ -173,7 +183,8 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); | |||
173 | void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); | 183 | void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); |
174 | int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); | 184 | int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); |
175 | bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data); | 185 | bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data); |
176 | void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start); | 186 | int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data); |
187 | void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data); | ||
177 | int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); | 188 | int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); |
178 | void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data); | 189 | void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data); |
179 | void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); | 190 | void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); |
@@ -181,8 +192,13 @@ void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); | |||
181 | void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); | 192 | void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); |
182 | void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); | 193 | void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); |
183 | void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); | 194 | void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); |
184 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | 195 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
185 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | 196 | int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts); |
186 | void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable); | 197 | int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data); |
198 | void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data); | ||
199 | int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data); | ||
200 | void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data); | ||
201 | int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, | ||
202 | struct omap_dss_audio *audio); | ||
187 | #endif | 203 | #endif |
188 | #endif | 204 | #endif |
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index bfe6fe65c8be..4dae1b291079 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | |||
@@ -29,9 +29,14 @@ | |||
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
30 | #include <linux/seq_file.h> | 30 | #include <linux/seq_file.h> |
31 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
32 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | ||
33 | #include <sound/asound.h> | ||
34 | #include <sound/asoundef.h> | ||
35 | #endif | ||
32 | 36 | ||
33 | #include "ti_hdmi_4xxx_ip.h" | 37 | #include "ti_hdmi_4xxx_ip.h" |
34 | #include "dss.h" | 38 | #include "dss.h" |
39 | #include "dss_features.h" | ||
35 | 40 | ||
36 | static inline void hdmi_write_reg(void __iomem *base_addr, | 41 | static inline void hdmi_write_reg(void __iomem *base_addr, |
37 | const u16 idx, u32 val) | 42 | const u16 idx, u32 val) |
@@ -298,9 +303,9 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data) | |||
298 | REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); | 303 | REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); |
299 | 304 | ||
300 | r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio), | 305 | r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio), |
301 | NULL, hpd_irq_handler, | 306 | NULL, hpd_irq_handler, |
302 | IRQF_DISABLED | IRQF_TRIGGER_RISING | | 307 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | |
303 | IRQF_TRIGGER_FALLING, "hpd", ip_data); | 308 | IRQF_ONESHOT, "hpd", ip_data); |
304 | if (r) { | 309 | if (r) { |
305 | DSSERR("HPD IRQ request failed\n"); | 310 | DSSERR("HPD IRQ request failed\n"); |
306 | hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); | 311 | hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); |
@@ -699,9 +704,15 @@ static void hdmi_wp_init(struct omap_video_timings *timings, | |||
699 | 704 | ||
700 | } | 705 | } |
701 | 706 | ||
702 | void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start) | 707 | int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data) |
708 | { | ||
709 | REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, true, 31, 31); | ||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data) | ||
703 | { | 714 | { |
704 | REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, start, 31, 31); | 715 | REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, false, 31, 31); |
705 | } | 716 | } |
706 | 717 | ||
707 | static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, | 718 | static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, |
@@ -886,10 +897,12 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) | |||
886 | 897 | ||
887 | #define CORE_REG(i, name) name(i) | 898 | #define CORE_REG(i, name) name(i) |
888 | #define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ | 899 | #define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ |
889 | hdmi_read_reg(hdmi_pll_base(ip_data), r)) | 900 | hdmi_read_reg(hdmi_core_sys_base(ip_data), r)) |
890 | #define DUMPCOREAV(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \ | 901 | #define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\ |
902 | hdmi_read_reg(hdmi_av_base(ip_data), r)) | ||
903 | #define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \ | ||
891 | (i < 10) ? 32 - strlen(#r) : 31 - strlen(#r), " ", \ | 904 | (i < 10) ? 32 - strlen(#r) : 31 - strlen(#r), " ", \ |
892 | hdmi_read_reg(hdmi_pll_base(ip_data), CORE_REG(i, r))) | 905 | hdmi_read_reg(hdmi_av_base(ip_data), CORE_REG(i, r))) |
893 | 906 | ||
894 | DUMPCORE(HDMI_CORE_SYS_VND_IDL); | 907 | DUMPCORE(HDMI_CORE_SYS_VND_IDL); |
895 | DUMPCORE(HDMI_CORE_SYS_DEV_IDL); | 908 | DUMPCORE(HDMI_CORE_SYS_DEV_IDL); |
@@ -898,6 +911,13 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) | |||
898 | DUMPCORE(HDMI_CORE_SYS_SRST); | 911 | DUMPCORE(HDMI_CORE_SYS_SRST); |
899 | DUMPCORE(HDMI_CORE_CTRL1); | 912 | DUMPCORE(HDMI_CORE_CTRL1); |
900 | DUMPCORE(HDMI_CORE_SYS_SYS_STAT); | 913 | DUMPCORE(HDMI_CORE_SYS_SYS_STAT); |
914 | DUMPCORE(HDMI_CORE_SYS_DE_DLY); | ||
915 | DUMPCORE(HDMI_CORE_SYS_DE_CTRL); | ||
916 | DUMPCORE(HDMI_CORE_SYS_DE_TOP); | ||
917 | DUMPCORE(HDMI_CORE_SYS_DE_CNTL); | ||
918 | DUMPCORE(HDMI_CORE_SYS_DE_CNTH); | ||
919 | DUMPCORE(HDMI_CORE_SYS_DE_LINL); | ||
920 | DUMPCORE(HDMI_CORE_SYS_DE_LINH_1); | ||
901 | DUMPCORE(HDMI_CORE_SYS_VID_ACEN); | 921 | DUMPCORE(HDMI_CORE_SYS_VID_ACEN); |
902 | DUMPCORE(HDMI_CORE_SYS_VID_MODE); | 922 | DUMPCORE(HDMI_CORE_SYS_VID_MODE); |
903 | DUMPCORE(HDMI_CORE_SYS_INTR_STATE); | 923 | DUMPCORE(HDMI_CORE_SYS_INTR_STATE); |
@@ -907,102 +927,91 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) | |||
907 | DUMPCORE(HDMI_CORE_SYS_INTR4); | 927 | DUMPCORE(HDMI_CORE_SYS_INTR4); |
908 | DUMPCORE(HDMI_CORE_SYS_UMASK1); | 928 | DUMPCORE(HDMI_CORE_SYS_UMASK1); |
909 | DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL); | 929 | DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL); |
910 | DUMPCORE(HDMI_CORE_SYS_DE_DLY); | ||
911 | DUMPCORE(HDMI_CORE_SYS_DE_CTRL); | ||
912 | DUMPCORE(HDMI_CORE_SYS_DE_TOP); | ||
913 | DUMPCORE(HDMI_CORE_SYS_DE_CNTL); | ||
914 | DUMPCORE(HDMI_CORE_SYS_DE_CNTH); | ||
915 | DUMPCORE(HDMI_CORE_SYS_DE_LINL); | ||
916 | DUMPCORE(HDMI_CORE_SYS_DE_LINH_1); | ||
917 | 930 | ||
918 | DUMPCORE(HDMI_CORE_DDC_CMD); | ||
919 | DUMPCORE(HDMI_CORE_DDC_STATUS); | ||
920 | DUMPCORE(HDMI_CORE_DDC_ADDR); | 931 | DUMPCORE(HDMI_CORE_DDC_ADDR); |
932 | DUMPCORE(HDMI_CORE_DDC_SEGM); | ||
921 | DUMPCORE(HDMI_CORE_DDC_OFFSET); | 933 | DUMPCORE(HDMI_CORE_DDC_OFFSET); |
922 | DUMPCORE(HDMI_CORE_DDC_COUNT1); | 934 | DUMPCORE(HDMI_CORE_DDC_COUNT1); |
923 | DUMPCORE(HDMI_CORE_DDC_COUNT2); | 935 | DUMPCORE(HDMI_CORE_DDC_COUNT2); |
936 | DUMPCORE(HDMI_CORE_DDC_STATUS); | ||
937 | DUMPCORE(HDMI_CORE_DDC_CMD); | ||
924 | DUMPCORE(HDMI_CORE_DDC_DATA); | 938 | DUMPCORE(HDMI_CORE_DDC_DATA); |
925 | DUMPCORE(HDMI_CORE_DDC_SEGM); | ||
926 | 939 | ||
927 | DUMPCORE(HDMI_CORE_AV_HDMI_CTRL); | 940 | DUMPCOREAV(HDMI_CORE_AV_ACR_CTRL); |
928 | DUMPCORE(HDMI_CORE_AV_DPD); | 941 | DUMPCOREAV(HDMI_CORE_AV_FREQ_SVAL); |
929 | DUMPCORE(HDMI_CORE_AV_PB_CTRL1); | 942 | DUMPCOREAV(HDMI_CORE_AV_N_SVAL1); |
930 | DUMPCORE(HDMI_CORE_AV_PB_CTRL2); | 943 | DUMPCOREAV(HDMI_CORE_AV_N_SVAL2); |
931 | DUMPCORE(HDMI_CORE_AV_AVI_TYPE); | 944 | DUMPCOREAV(HDMI_CORE_AV_N_SVAL3); |
932 | DUMPCORE(HDMI_CORE_AV_AVI_VERS); | 945 | DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL1); |
933 | DUMPCORE(HDMI_CORE_AV_AVI_LEN); | 946 | DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL2); |
934 | DUMPCORE(HDMI_CORE_AV_AVI_CHSUM); | 947 | DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL3); |
948 | DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL1); | ||
949 | DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL2); | ||
950 | DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL3); | ||
951 | DUMPCOREAV(HDMI_CORE_AV_AUD_MODE); | ||
952 | DUMPCOREAV(HDMI_CORE_AV_SPDIF_CTRL); | ||
953 | DUMPCOREAV(HDMI_CORE_AV_HW_SPDIF_FS); | ||
954 | DUMPCOREAV(HDMI_CORE_AV_SWAP_I2S); | ||
955 | DUMPCOREAV(HDMI_CORE_AV_SPDIF_ERTH); | ||
956 | DUMPCOREAV(HDMI_CORE_AV_I2S_IN_MAP); | ||
957 | DUMPCOREAV(HDMI_CORE_AV_I2S_IN_CTRL); | ||
958 | DUMPCOREAV(HDMI_CORE_AV_I2S_CHST0); | ||
959 | DUMPCOREAV(HDMI_CORE_AV_I2S_CHST1); | ||
960 | DUMPCOREAV(HDMI_CORE_AV_I2S_CHST2); | ||
961 | DUMPCOREAV(HDMI_CORE_AV_I2S_CHST4); | ||
962 | DUMPCOREAV(HDMI_CORE_AV_I2S_CHST5); | ||
963 | DUMPCOREAV(HDMI_CORE_AV_ASRC); | ||
964 | DUMPCOREAV(HDMI_CORE_AV_I2S_IN_LEN); | ||
965 | DUMPCOREAV(HDMI_CORE_AV_HDMI_CTRL); | ||
966 | DUMPCOREAV(HDMI_CORE_AV_AUDO_TXSTAT); | ||
967 | DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_1); | ||
968 | DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_2); | ||
969 | DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_3); | ||
970 | DUMPCOREAV(HDMI_CORE_AV_TEST_TXCTRL); | ||
971 | DUMPCOREAV(HDMI_CORE_AV_DPD); | ||
972 | DUMPCOREAV(HDMI_CORE_AV_PB_CTRL1); | ||
973 | DUMPCOREAV(HDMI_CORE_AV_PB_CTRL2); | ||
974 | DUMPCOREAV(HDMI_CORE_AV_AVI_TYPE); | ||
975 | DUMPCOREAV(HDMI_CORE_AV_AVI_VERS); | ||
976 | DUMPCOREAV(HDMI_CORE_AV_AVI_LEN); | ||
977 | DUMPCOREAV(HDMI_CORE_AV_AVI_CHSUM); | ||
935 | 978 | ||
936 | for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++) | 979 | for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++) |
937 | DUMPCOREAV(i, HDMI_CORE_AV_AVI_DBYTE); | 980 | DUMPCOREAV2(i, HDMI_CORE_AV_AVI_DBYTE); |
981 | |||
982 | DUMPCOREAV(HDMI_CORE_AV_SPD_TYPE); | ||
983 | DUMPCOREAV(HDMI_CORE_AV_SPD_VERS); | ||
984 | DUMPCOREAV(HDMI_CORE_AV_SPD_LEN); | ||
985 | DUMPCOREAV(HDMI_CORE_AV_SPD_CHSUM); | ||
938 | 986 | ||
939 | for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++) | 987 | for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++) |
940 | DUMPCOREAV(i, HDMI_CORE_AV_SPD_DBYTE); | 988 | DUMPCOREAV2(i, HDMI_CORE_AV_SPD_DBYTE); |
989 | |||
990 | DUMPCOREAV(HDMI_CORE_AV_AUDIO_TYPE); | ||
991 | DUMPCOREAV(HDMI_CORE_AV_AUDIO_VERS); | ||
992 | DUMPCOREAV(HDMI_CORE_AV_AUDIO_LEN); | ||
993 | DUMPCOREAV(HDMI_CORE_AV_AUDIO_CHSUM); | ||
941 | 994 | ||
942 | for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++) | 995 | for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++) |
943 | DUMPCOREAV(i, HDMI_CORE_AV_AUD_DBYTE); | 996 | DUMPCOREAV2(i, HDMI_CORE_AV_AUD_DBYTE); |
997 | |||
998 | DUMPCOREAV(HDMI_CORE_AV_MPEG_TYPE); | ||
999 | DUMPCOREAV(HDMI_CORE_AV_MPEG_VERS); | ||
1000 | DUMPCOREAV(HDMI_CORE_AV_MPEG_LEN); | ||
1001 | DUMPCOREAV(HDMI_CORE_AV_MPEG_CHSUM); | ||
944 | 1002 | ||
945 | for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++) | 1003 | for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++) |
946 | DUMPCOREAV(i, HDMI_CORE_AV_MPEG_DBYTE); | 1004 | DUMPCOREAV2(i, HDMI_CORE_AV_MPEG_DBYTE); |
947 | 1005 | ||
948 | for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++) | 1006 | for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++) |
949 | DUMPCOREAV(i, HDMI_CORE_AV_GEN_DBYTE); | 1007 | DUMPCOREAV2(i, HDMI_CORE_AV_GEN_DBYTE); |
1008 | |||
1009 | DUMPCOREAV(HDMI_CORE_AV_CP_BYTE1); | ||
950 | 1010 | ||
951 | for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++) | 1011 | for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++) |
952 | DUMPCOREAV(i, HDMI_CORE_AV_GEN2_DBYTE); | 1012 | DUMPCOREAV2(i, HDMI_CORE_AV_GEN2_DBYTE); |
953 | 1013 | ||
954 | DUMPCORE(HDMI_CORE_AV_ACR_CTRL); | 1014 | DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID); |
955 | DUMPCORE(HDMI_CORE_AV_FREQ_SVAL); | ||
956 | DUMPCORE(HDMI_CORE_AV_N_SVAL1); | ||
957 | DUMPCORE(HDMI_CORE_AV_N_SVAL2); | ||
958 | DUMPCORE(HDMI_CORE_AV_N_SVAL3); | ||
959 | DUMPCORE(HDMI_CORE_AV_CTS_SVAL1); | ||
960 | DUMPCORE(HDMI_CORE_AV_CTS_SVAL2); | ||
961 | DUMPCORE(HDMI_CORE_AV_CTS_SVAL3); | ||
962 | DUMPCORE(HDMI_CORE_AV_CTS_HVAL1); | ||
963 | DUMPCORE(HDMI_CORE_AV_CTS_HVAL2); | ||
964 | DUMPCORE(HDMI_CORE_AV_CTS_HVAL3); | ||
965 | DUMPCORE(HDMI_CORE_AV_AUD_MODE); | ||
966 | DUMPCORE(HDMI_CORE_AV_SPDIF_CTRL); | ||
967 | DUMPCORE(HDMI_CORE_AV_HW_SPDIF_FS); | ||
968 | DUMPCORE(HDMI_CORE_AV_SWAP_I2S); | ||
969 | DUMPCORE(HDMI_CORE_AV_SPDIF_ERTH); | ||
970 | DUMPCORE(HDMI_CORE_AV_I2S_IN_MAP); | ||
971 | DUMPCORE(HDMI_CORE_AV_I2S_IN_CTRL); | ||
972 | DUMPCORE(HDMI_CORE_AV_I2S_CHST0); | ||
973 | DUMPCORE(HDMI_CORE_AV_I2S_CHST1); | ||
974 | DUMPCORE(HDMI_CORE_AV_I2S_CHST2); | ||
975 | DUMPCORE(HDMI_CORE_AV_I2S_CHST4); | ||
976 | DUMPCORE(HDMI_CORE_AV_I2S_CHST5); | ||
977 | DUMPCORE(HDMI_CORE_AV_ASRC); | ||
978 | DUMPCORE(HDMI_CORE_AV_I2S_IN_LEN); | ||
979 | DUMPCORE(HDMI_CORE_AV_HDMI_CTRL); | ||
980 | DUMPCORE(HDMI_CORE_AV_AUDO_TXSTAT); | ||
981 | DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_1); | ||
982 | DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_2); | ||
983 | DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_3); | ||
984 | DUMPCORE(HDMI_CORE_AV_TEST_TXCTRL); | ||
985 | DUMPCORE(HDMI_CORE_AV_DPD); | ||
986 | DUMPCORE(HDMI_CORE_AV_PB_CTRL1); | ||
987 | DUMPCORE(HDMI_CORE_AV_PB_CTRL2); | ||
988 | DUMPCORE(HDMI_CORE_AV_AVI_TYPE); | ||
989 | DUMPCORE(HDMI_CORE_AV_AVI_VERS); | ||
990 | DUMPCORE(HDMI_CORE_AV_AVI_LEN); | ||
991 | DUMPCORE(HDMI_CORE_AV_AVI_CHSUM); | ||
992 | DUMPCORE(HDMI_CORE_AV_SPD_TYPE); | ||
993 | DUMPCORE(HDMI_CORE_AV_SPD_VERS); | ||
994 | DUMPCORE(HDMI_CORE_AV_SPD_LEN); | ||
995 | DUMPCORE(HDMI_CORE_AV_SPD_CHSUM); | ||
996 | DUMPCORE(HDMI_CORE_AV_AUDIO_TYPE); | ||
997 | DUMPCORE(HDMI_CORE_AV_AUDIO_VERS); | ||
998 | DUMPCORE(HDMI_CORE_AV_AUDIO_LEN); | ||
999 | DUMPCORE(HDMI_CORE_AV_AUDIO_CHSUM); | ||
1000 | DUMPCORE(HDMI_CORE_AV_MPEG_TYPE); | ||
1001 | DUMPCORE(HDMI_CORE_AV_MPEG_VERS); | ||
1002 | DUMPCORE(HDMI_CORE_AV_MPEG_LEN); | ||
1003 | DUMPCORE(HDMI_CORE_AV_MPEG_CHSUM); | ||
1004 | DUMPCORE(HDMI_CORE_AV_CP_BYTE1); | ||
1005 | DUMPCORE(HDMI_CORE_AV_CEC_ADDR_ID); | ||
1006 | } | 1015 | } |
1007 | 1016 | ||
1008 | void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) | 1017 | void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) |
@@ -1016,9 +1025,8 @@ void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) | |||
1016 | DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); | 1025 | DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); |
1017 | } | 1026 | } |
1018 | 1027 | ||
1019 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | 1028 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
1020 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | 1029 | static void ti_hdmi_4xxx_wp_audio_config_format(struct hdmi_ip_data *ip_data, |
1021 | void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data, | ||
1022 | struct hdmi_audio_format *aud_fmt) | 1030 | struct hdmi_audio_format *aud_fmt) |
1023 | { | 1031 | { |
1024 | u32 r; | 1032 | u32 r; |
@@ -1037,7 +1045,7 @@ void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data, | |||
1037 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r); | 1045 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r); |
1038 | } | 1046 | } |
1039 | 1047 | ||
1040 | void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, | 1048 | static void ti_hdmi_4xxx_wp_audio_config_dma(struct hdmi_ip_data *ip_data, |
1041 | struct hdmi_audio_dma *aud_dma) | 1049 | struct hdmi_audio_dma *aud_dma) |
1042 | { | 1050 | { |
1043 | u32 r; | 1051 | u32 r; |
@@ -1055,7 +1063,7 @@ void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, | |||
1055 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r); | 1063 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r); |
1056 | } | 1064 | } |
1057 | 1065 | ||
1058 | void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, | 1066 | static void ti_hdmi_4xxx_core_audio_config(struct hdmi_ip_data *ip_data, |
1059 | struct hdmi_core_audio_config *cfg) | 1067 | struct hdmi_core_audio_config *cfg) |
1060 | { | 1068 | { |
1061 | u32 r; | 1069 | u32 r; |
@@ -1106,27 +1114,33 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, | |||
1106 | REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, | 1114 | REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, |
1107 | cfg->fs_override, 1, 1); | 1115 | cfg->fs_override, 1, 1); |
1108 | 1116 | ||
1109 | /* I2S parameters */ | 1117 | /* |
1110 | REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_CHST4, | 1118 | * Set IEC-60958-3 channel status word. It is passed to the IP |
1111 | cfg->freq_sample, 3, 0); | 1119 | * just as it is received. The user of the driver is responsible |
1112 | 1120 | * for its contents. | |
1121 | */ | ||
1122 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST0, | ||
1123 | cfg->iec60958_cfg->status[0]); | ||
1124 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST1, | ||
1125 | cfg->iec60958_cfg->status[1]); | ||
1126 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST2, | ||
1127 | cfg->iec60958_cfg->status[2]); | ||
1128 | /* yes, this is correct: status[3] goes to CHST4 register */ | ||
1129 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST4, | ||
1130 | cfg->iec60958_cfg->status[3]); | ||
1131 | /* yes, this is correct: status[4] goes to CHST5 register */ | ||
1132 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, | ||
1133 | cfg->iec60958_cfg->status[4]); | ||
1134 | |||
1135 | /* set I2S parameters */ | ||
1113 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL); | 1136 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL); |
1114 | r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7); | ||
1115 | r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6); | 1137 | r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6); |
1116 | r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5); | ||
1117 | r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4); | 1138 | r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4); |
1118 | r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3); | ||
1119 | r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2); | 1139 | r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2); |
1120 | r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1); | 1140 | r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1); |
1121 | r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0); | 1141 | r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0); |
1122 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r); | 1142 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r); |
1123 | 1143 | ||
1124 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_CHST5); | ||
1125 | r = FLD_MOD(r, cfg->freq_sample, 7, 4); | ||
1126 | r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1); | ||
1127 | r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0); | ||
1128 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, r); | ||
1129 | |||
1130 | REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN, | 1144 | REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN, |
1131 | cfg->i2s_cfg.in_length_bits, 3, 0); | 1145 | cfg->i2s_cfg.in_length_bits, 3, 0); |
1132 | 1146 | ||
@@ -1138,12 +1152,19 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, | |||
1138 | r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2); | 1152 | r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2); |
1139 | r = FLD_MOD(r, cfg->en_spdif, 1, 1); | 1153 | r = FLD_MOD(r, cfg->en_spdif, 1, 1); |
1140 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r); | 1154 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r); |
1155 | |||
1156 | /* Audio channel mappings */ | ||
1157 | /* TODO: Make channel mapping dynamic. For now, map channels | ||
1158 | * in the ALSA order: FL/FR/RL/RR/C/LFE/SL/SR. Remapping is needed as | ||
1159 | * HDMI speaker order is different. See CEA-861 Section 6.6.2. | ||
1160 | */ | ||
1161 | hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_MAP, 0x78); | ||
1162 | REG_FLD_MOD(av_base, HDMI_CORE_AV_SWAP_I2S, 1, 5, 5); | ||
1141 | } | 1163 | } |
1142 | 1164 | ||
1143 | void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, | 1165 | static void ti_hdmi_4xxx_core_audio_infoframe_cfg(struct hdmi_ip_data *ip_data, |
1144 | struct hdmi_core_infoframe_audio *info_aud) | 1166 | struct snd_cea_861_aud_if *info_aud) |
1145 | { | 1167 | { |
1146 | u8 val; | ||
1147 | u8 sum = 0, checksum = 0; | 1168 | u8 sum = 0, checksum = 0; |
1148 | void __iomem *av_base = hdmi_av_base(ip_data); | 1169 | void __iomem *av_base = hdmi_av_base(ip_data); |
1149 | 1170 | ||
@@ -1157,24 +1178,23 @@ void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, | |||
1157 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a); | 1178 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a); |
1158 | sum += 0x84 + 0x001 + 0x00a; | 1179 | sum += 0x84 + 0x001 + 0x00a; |
1159 | 1180 | ||
1160 | val = (info_aud->db1_coding_type << 4) | 1181 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), |
1161 | | (info_aud->db1_channel_count - 1); | 1182 | info_aud->db1_ct_cc); |
1162 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), val); | 1183 | sum += info_aud->db1_ct_cc; |
1163 | sum += val; | ||
1164 | 1184 | ||
1165 | val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size; | 1185 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), |
1166 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), val); | 1186 | info_aud->db2_sf_ss); |
1167 | sum += val; | 1187 | sum += info_aud->db2_sf_ss; |
1168 | 1188 | ||
1169 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), 0x00); | 1189 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3); |
1190 | sum += info_aud->db3; | ||
1170 | 1191 | ||
1171 | val = info_aud->db4_channel_alloc; | 1192 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca); |
1172 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), val); | 1193 | sum += info_aud->db4_ca; |
1173 | sum += val; | ||
1174 | 1194 | ||
1175 | val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3); | 1195 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), |
1176 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), val); | 1196 | info_aud->db5_dminh_lsv); |
1177 | sum += val; | 1197 | sum += info_aud->db5_dminh_lsv; |
1178 | 1198 | ||
1179 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00); | 1199 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00); |
1180 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00); | 1200 | hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00); |
@@ -1192,70 +1212,212 @@ void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, | |||
1192 | */ | 1212 | */ |
1193 | } | 1213 | } |
1194 | 1214 | ||
1195 | int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, | 1215 | int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, |
1196 | u32 sample_freq, u32 *n, u32 *cts) | 1216 | struct omap_dss_audio *audio) |
1197 | { | 1217 | { |
1198 | u32 r; | 1218 | struct hdmi_audio_format audio_format; |
1199 | u32 deep_color = 0; | 1219 | struct hdmi_audio_dma audio_dma; |
1200 | u32 pclk = ip_data->cfg.timings.pixel_clock; | 1220 | struct hdmi_core_audio_config core; |
1201 | 1221 | int err, n, cts, channel_count; | |
1202 | if (n == NULL || cts == NULL) | 1222 | unsigned int fs_nr; |
1223 | bool word_length_16b = false; | ||
1224 | |||
1225 | if (!audio || !audio->iec || !audio->cea || !ip_data) | ||
1203 | return -EINVAL; | 1226 | return -EINVAL; |
1227 | |||
1228 | core.iec60958_cfg = audio->iec; | ||
1204 | /* | 1229 | /* |
1205 | * Obtain current deep color configuration. This needed | 1230 | * In the IEC-60958 status word, check if the audio sample word length |
1206 | * to calculate the TMDS clock based on the pixel clock. | 1231 | * is 16-bit as several optimizations can be performed in such case. |
1207 | */ | 1232 | */ |
1208 | r = REG_GET(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, 1, 0); | 1233 | if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24)) |
1209 | switch (r) { | 1234 | if (audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16) |
1210 | case 1: /* No deep color selected */ | 1235 | word_length_16b = true; |
1211 | deep_color = 100; | 1236 | |
1237 | /* I2S configuration. See Phillips' specification */ | ||
1238 | if (word_length_16b) | ||
1239 | core.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT; | ||
1240 | else | ||
1241 | core.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; | ||
1242 | /* | ||
1243 | * The I2S input word length is twice the lenght given in the IEC-60958 | ||
1244 | * status word. If the word size is greater than | ||
1245 | * 20 bits, increment by one. | ||
1246 | */ | ||
1247 | core.i2s_cfg.in_length_bits = audio->iec->status[4] | ||
1248 | & IEC958_AES4_CON_WORDLEN; | ||
1249 | if (audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24) | ||
1250 | core.i2s_cfg.in_length_bits++; | ||
1251 | core.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; | ||
1252 | core.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; | ||
1253 | core.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; | ||
1254 | core.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT; | ||
1255 | |||
1256 | /* convert sample frequency to a number */ | ||
1257 | switch (audio->iec->status[3] & IEC958_AES3_CON_FS) { | ||
1258 | case IEC958_AES3_CON_FS_32000: | ||
1259 | fs_nr = 32000; | ||
1260 | break; | ||
1261 | case IEC958_AES3_CON_FS_44100: | ||
1262 | fs_nr = 44100; | ||
1263 | break; | ||
1264 | case IEC958_AES3_CON_FS_48000: | ||
1265 | fs_nr = 48000; | ||
1212 | break; | 1266 | break; |
1213 | case 2: /* 10-bit deep color selected */ | 1267 | case IEC958_AES3_CON_FS_88200: |
1214 | deep_color = 125; | 1268 | fs_nr = 88200; |
1215 | break; | 1269 | break; |
1216 | case 3: /* 12-bit deep color selected */ | 1270 | case IEC958_AES3_CON_FS_96000: |
1217 | deep_color = 150; | 1271 | fs_nr = 96000; |
1272 | break; | ||
1273 | case IEC958_AES3_CON_FS_176400: | ||
1274 | fs_nr = 176400; | ||
1275 | break; | ||
1276 | case IEC958_AES3_CON_FS_192000: | ||
1277 | fs_nr = 192000; | ||
1218 | break; | 1278 | break; |
1219 | default: | 1279 | default: |
1220 | return -EINVAL; | 1280 | return -EINVAL; |
1221 | } | 1281 | } |
1222 | 1282 | ||
1223 | switch (sample_freq) { | 1283 | err = hdmi_compute_acr(fs_nr, &n, &cts); |
1224 | case 32000: | 1284 | |
1225 | if ((deep_color == 125) && ((pclk == 54054) | 1285 | /* Audio clock regeneration settings */ |
1226 | || (pclk == 74250))) | 1286 | core.n = n; |
1227 | *n = 8192; | 1287 | core.cts = cts; |
1228 | else | 1288 | if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { |
1229 | *n = 4096; | 1289 | core.aud_par_busclk = 0; |
1290 | core.cts_mode = HDMI_AUDIO_CTS_MODE_SW; | ||
1291 | core.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK); | ||
1292 | } else { | ||
1293 | core.aud_par_busclk = (((128 * 31) - 1) << 8); | ||
1294 | core.cts_mode = HDMI_AUDIO_CTS_MODE_HW; | ||
1295 | core.use_mclk = true; | ||
1296 | } | ||
1297 | |||
1298 | if (core.use_mclk) | ||
1299 | core.mclk_mode = HDMI_AUDIO_MCLK_128FS; | ||
1300 | |||
1301 | /* Audio channels settings */ | ||
1302 | channel_count = (audio->cea->db1_ct_cc & | ||
1303 | CEA861_AUDIO_INFOFRAME_DB1CC) + 1; | ||
1304 | |||
1305 | switch (channel_count) { | ||
1306 | case 2: | ||
1307 | audio_format.active_chnnls_msk = 0x03; | ||
1308 | break; | ||
1309 | case 3: | ||
1310 | audio_format.active_chnnls_msk = 0x07; | ||
1311 | break; | ||
1312 | case 4: | ||
1313 | audio_format.active_chnnls_msk = 0x0f; | ||
1314 | break; | ||
1315 | case 5: | ||
1316 | audio_format.active_chnnls_msk = 0x1f; | ||
1230 | break; | 1317 | break; |
1231 | case 44100: | 1318 | case 6: |
1232 | *n = 6272; | 1319 | audio_format.active_chnnls_msk = 0x3f; |
1233 | break; | 1320 | break; |
1234 | case 48000: | 1321 | case 7: |
1235 | if ((deep_color == 125) && ((pclk == 54054) | 1322 | audio_format.active_chnnls_msk = 0x7f; |
1236 | || (pclk == 74250))) | 1323 | break; |
1237 | *n = 8192; | 1324 | case 8: |
1238 | else | 1325 | audio_format.active_chnnls_msk = 0xff; |
1239 | *n = 6144; | ||
1240 | break; | 1326 | break; |
1241 | default: | 1327 | default: |
1242 | *n = 0; | ||
1243 | return -EINVAL; | 1328 | return -EINVAL; |
1244 | } | 1329 | } |
1245 | 1330 | ||
1246 | /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ | 1331 | /* |
1247 | *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); | 1332 | * the HDMI IP needs to enable four stereo channels when transmitting |
1333 | * more than 2 audio channels | ||
1334 | */ | ||
1335 | if (channel_count == 2) { | ||
1336 | audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; | ||
1337 | core.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; | ||
1338 | core.layout = HDMI_AUDIO_LAYOUT_2CH; | ||
1339 | } else { | ||
1340 | audio_format.stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS; | ||
1341 | core.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN | | ||
1342 | HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN | | ||
1343 | HDMI_AUDIO_I2S_SD3_EN; | ||
1344 | core.layout = HDMI_AUDIO_LAYOUT_8CH; | ||
1345 | } | ||
1346 | |||
1347 | core.en_spdif = false; | ||
1348 | /* use sample frequency from channel status word */ | ||
1349 | core.fs_override = true; | ||
1350 | /* enable ACR packets */ | ||
1351 | core.en_acr_pkt = true; | ||
1352 | /* disable direct streaming digital audio */ | ||
1353 | core.en_dsd_audio = false; | ||
1354 | /* use parallel audio interface */ | ||
1355 | core.en_parallel_aud_input = true; | ||
1356 | |||
1357 | /* DMA settings */ | ||
1358 | if (word_length_16b) | ||
1359 | audio_dma.transfer_size = 0x10; | ||
1360 | else | ||
1361 | audio_dma.transfer_size = 0x20; | ||
1362 | audio_dma.block_size = 0xC0; | ||
1363 | audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; | ||
1364 | audio_dma.fifo_threshold = 0x20; /* in number of samples */ | ||
1365 | |||
1366 | /* audio FIFO format settings */ | ||
1367 | if (word_length_16b) { | ||
1368 | audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; | ||
1369 | audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; | ||
1370 | audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; | ||
1371 | } else { | ||
1372 | audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE; | ||
1373 | audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS; | ||
1374 | audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT; | ||
1375 | } | ||
1376 | audio_format.type = HDMI_AUDIO_TYPE_LPCM; | ||
1377 | audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST; | ||
1378 | /* disable start/stop signals of IEC 60958 blocks */ | ||
1379 | audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; | ||
1380 | |||
1381 | /* configure DMA and audio FIFO format*/ | ||
1382 | ti_hdmi_4xxx_wp_audio_config_dma(ip_data, &audio_dma); | ||
1383 | ti_hdmi_4xxx_wp_audio_config_format(ip_data, &audio_format); | ||
1384 | |||
1385 | /* configure the core*/ | ||
1386 | ti_hdmi_4xxx_core_audio_config(ip_data, &core); | ||
1387 | |||
1388 | /* configure CEA 861 audio infoframe*/ | ||
1389 | ti_hdmi_4xxx_core_audio_infoframe_cfg(ip_data, audio->cea); | ||
1248 | 1390 | ||
1249 | return 0; | 1391 | return 0; |
1250 | } | 1392 | } |
1251 | 1393 | ||
1252 | void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable) | 1394 | int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data) |
1395 | { | ||
1396 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1397 | HDMI_WP_AUDIO_CTRL, true, 31, 31); | ||
1398 | return 0; | ||
1399 | } | ||
1400 | |||
1401 | void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data) | ||
1402 | { | ||
1403 | REG_FLD_MOD(hdmi_wp_base(ip_data), | ||
1404 | HDMI_WP_AUDIO_CTRL, false, 31, 31); | ||
1405 | } | ||
1406 | |||
1407 | int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data) | ||
1253 | { | 1408 | { |
1254 | REG_FLD_MOD(hdmi_av_base(ip_data), | 1409 | REG_FLD_MOD(hdmi_av_base(ip_data), |
1255 | HDMI_CORE_AV_AUD_MODE, enable, 0, 0); | 1410 | HDMI_CORE_AV_AUD_MODE, true, 0, 0); |
1256 | REG_FLD_MOD(hdmi_wp_base(ip_data), | 1411 | REG_FLD_MOD(hdmi_wp_base(ip_data), |
1257 | HDMI_WP_AUDIO_CTRL, enable, 31, 31); | 1412 | HDMI_WP_AUDIO_CTRL, true, 30, 30); |
1413 | return 0; | ||
1414 | } | ||
1415 | |||
1416 | void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data) | ||
1417 | { | ||
1418 | REG_FLD_MOD(hdmi_av_base(ip_data), | ||
1419 | HDMI_CORE_AV_AUD_MODE, false, 0, 0); | ||
1258 | REG_FLD_MOD(hdmi_wp_base(ip_data), | 1420 | REG_FLD_MOD(hdmi_wp_base(ip_data), |
1259 | HDMI_WP_AUDIO_CTRL, enable, 30, 30); | 1421 | HDMI_WP_AUDIO_CTRL, false, 30, 30); |
1260 | } | 1422 | } |
1261 | #endif | 1423 | #endif |
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h index a14d1a0e6e41..8366ae19e82e 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h | |||
@@ -24,11 +24,6 @@ | |||
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <video/omapdss.h> | 25 | #include <video/omapdss.h> |
26 | #include "ti_hdmi.h" | 26 | #include "ti_hdmi.h" |
27 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | ||
28 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | ||
29 | #include <sound/soc.h> | ||
30 | #include <sound/pcm_params.h> | ||
31 | #endif | ||
32 | 27 | ||
33 | /* HDMI Wrapper */ | 28 | /* HDMI Wrapper */ |
34 | 29 | ||
@@ -57,6 +52,13 @@ | |||
57 | #define HDMI_CORE_SYS_SRST 0x14 | 52 | #define HDMI_CORE_SYS_SRST 0x14 |
58 | #define HDMI_CORE_CTRL1 0x20 | 53 | #define HDMI_CORE_CTRL1 0x20 |
59 | #define HDMI_CORE_SYS_SYS_STAT 0x24 | 54 | #define HDMI_CORE_SYS_SYS_STAT 0x24 |
55 | #define HDMI_CORE_SYS_DE_DLY 0xC8 | ||
56 | #define HDMI_CORE_SYS_DE_CTRL 0xCC | ||
57 | #define HDMI_CORE_SYS_DE_TOP 0xD0 | ||
58 | #define HDMI_CORE_SYS_DE_CNTL 0xD8 | ||
59 | #define HDMI_CORE_SYS_DE_CNTH 0xDC | ||
60 | #define HDMI_CORE_SYS_DE_LINL 0xE0 | ||
61 | #define HDMI_CORE_SYS_DE_LINH_1 0xE4 | ||
60 | #define HDMI_CORE_SYS_VID_ACEN 0x124 | 62 | #define HDMI_CORE_SYS_VID_ACEN 0x124 |
61 | #define HDMI_CORE_SYS_VID_MODE 0x128 | 63 | #define HDMI_CORE_SYS_VID_MODE 0x128 |
62 | #define HDMI_CORE_SYS_INTR_STATE 0x1C0 | 64 | #define HDMI_CORE_SYS_INTR_STATE 0x1C0 |
@@ -66,50 +68,24 @@ | |||
66 | #define HDMI_CORE_SYS_INTR4 0x1D0 | 68 | #define HDMI_CORE_SYS_INTR4 0x1D0 |
67 | #define HDMI_CORE_SYS_UMASK1 0x1D4 | 69 | #define HDMI_CORE_SYS_UMASK1 0x1D4 |
68 | #define HDMI_CORE_SYS_TMDS_CTRL 0x208 | 70 | #define HDMI_CORE_SYS_TMDS_CTRL 0x208 |
69 | #define HDMI_CORE_SYS_DE_DLY 0xC8 | 71 | |
70 | #define HDMI_CORE_SYS_DE_CTRL 0xCC | ||
71 | #define HDMI_CORE_SYS_DE_TOP 0xD0 | ||
72 | #define HDMI_CORE_SYS_DE_CNTL 0xD8 | ||
73 | #define HDMI_CORE_SYS_DE_CNTH 0xDC | ||
74 | #define HDMI_CORE_SYS_DE_LINL 0xE0 | ||
75 | #define HDMI_CORE_SYS_DE_LINH_1 0xE4 | ||
76 | #define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1 | 72 | #define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1 |
77 | #define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1 | 73 | #define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1 |
78 | #define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1 | 74 | #define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1 |
79 | #define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1 | 75 | #define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1 |
80 | 76 | ||
81 | /* HDMI DDC E-DID */ | 77 | /* HDMI DDC E-DID */ |
82 | #define HDMI_CORE_DDC_CMD 0x3CC | ||
83 | #define HDMI_CORE_DDC_STATUS 0x3C8 | ||
84 | #define HDMI_CORE_DDC_ADDR 0x3B4 | 78 | #define HDMI_CORE_DDC_ADDR 0x3B4 |
79 | #define HDMI_CORE_DDC_SEGM 0x3B8 | ||
85 | #define HDMI_CORE_DDC_OFFSET 0x3BC | 80 | #define HDMI_CORE_DDC_OFFSET 0x3BC |
86 | #define HDMI_CORE_DDC_COUNT1 0x3C0 | 81 | #define HDMI_CORE_DDC_COUNT1 0x3C0 |
87 | #define HDMI_CORE_DDC_COUNT2 0x3C4 | 82 | #define HDMI_CORE_DDC_COUNT2 0x3C4 |
83 | #define HDMI_CORE_DDC_STATUS 0x3C8 | ||
84 | #define HDMI_CORE_DDC_CMD 0x3CC | ||
88 | #define HDMI_CORE_DDC_DATA 0x3D0 | 85 | #define HDMI_CORE_DDC_DATA 0x3D0 |
89 | #define HDMI_CORE_DDC_SEGM 0x3B8 | ||
90 | 86 | ||
91 | /* HDMI IP Core Audio Video */ | 87 | /* HDMI IP Core Audio Video */ |
92 | 88 | ||
93 | #define HDMI_CORE_AV_HDMI_CTRL 0xBC | ||
94 | #define HDMI_CORE_AV_DPD 0xF4 | ||
95 | #define HDMI_CORE_AV_PB_CTRL1 0xF8 | ||
96 | #define HDMI_CORE_AV_PB_CTRL2 0xFC | ||
97 | #define HDMI_CORE_AV_AVI_TYPE 0x100 | ||
98 | #define HDMI_CORE_AV_AVI_VERS 0x104 | ||
99 | #define HDMI_CORE_AV_AVI_LEN 0x108 | ||
100 | #define HDMI_CORE_AV_AVI_CHSUM 0x10C | ||
101 | #define HDMI_CORE_AV_AVI_DBYTE(n) (n * 4 + 0x110) | ||
102 | #define HDMI_CORE_AV_AVI_DBYTE_NELEMS 15 | ||
103 | #define HDMI_CORE_AV_SPD_DBYTE(n) (n * 4 + 0x190) | ||
104 | #define HDMI_CORE_AV_SPD_DBYTE_NELEMS 27 | ||
105 | #define HDMI_CORE_AV_AUD_DBYTE(n) (n * 4 + 0x210) | ||
106 | #define HDMI_CORE_AV_AUD_DBYTE_NELEMS 10 | ||
107 | #define HDMI_CORE_AV_MPEG_DBYTE(n) (n * 4 + 0x290) | ||
108 | #define HDMI_CORE_AV_MPEG_DBYTE_NELEMS 27 | ||
109 | #define HDMI_CORE_AV_GEN_DBYTE(n) (n * 4 + 0x300) | ||
110 | #define HDMI_CORE_AV_GEN_DBYTE_NELEMS 31 | ||
111 | #define HDMI_CORE_AV_GEN2_DBYTE(n) (n * 4 + 0x380) | ||
112 | #define HDMI_CORE_AV_GEN2_DBYTE_NELEMS 31 | ||
113 | #define HDMI_CORE_AV_ACR_CTRL 0x4 | 89 | #define HDMI_CORE_AV_ACR_CTRL 0x4 |
114 | #define HDMI_CORE_AV_FREQ_SVAL 0x8 | 90 | #define HDMI_CORE_AV_FREQ_SVAL 0x8 |
115 | #define HDMI_CORE_AV_N_SVAL1 0xC | 91 | #define HDMI_CORE_AV_N_SVAL1 0xC |
@@ -148,25 +124,39 @@ | |||
148 | #define HDMI_CORE_AV_AVI_VERS 0x104 | 124 | #define HDMI_CORE_AV_AVI_VERS 0x104 |
149 | #define HDMI_CORE_AV_AVI_LEN 0x108 | 125 | #define HDMI_CORE_AV_AVI_LEN 0x108 |
150 | #define HDMI_CORE_AV_AVI_CHSUM 0x10C | 126 | #define HDMI_CORE_AV_AVI_CHSUM 0x10C |
127 | #define HDMI_CORE_AV_AVI_DBYTE(n) (n * 4 + 0x110) | ||
151 | #define HDMI_CORE_AV_SPD_TYPE 0x180 | 128 | #define HDMI_CORE_AV_SPD_TYPE 0x180 |
152 | #define HDMI_CORE_AV_SPD_VERS 0x184 | 129 | #define HDMI_CORE_AV_SPD_VERS 0x184 |
153 | #define HDMI_CORE_AV_SPD_LEN 0x188 | 130 | #define HDMI_CORE_AV_SPD_LEN 0x188 |
154 | #define HDMI_CORE_AV_SPD_CHSUM 0x18C | 131 | #define HDMI_CORE_AV_SPD_CHSUM 0x18C |
132 | #define HDMI_CORE_AV_SPD_DBYTE(n) (n * 4 + 0x190) | ||
155 | #define HDMI_CORE_AV_AUDIO_TYPE 0x200 | 133 | #define HDMI_CORE_AV_AUDIO_TYPE 0x200 |
156 | #define HDMI_CORE_AV_AUDIO_VERS 0x204 | 134 | #define HDMI_CORE_AV_AUDIO_VERS 0x204 |
157 | #define HDMI_CORE_AV_AUDIO_LEN 0x208 | 135 | #define HDMI_CORE_AV_AUDIO_LEN 0x208 |
158 | #define HDMI_CORE_AV_AUDIO_CHSUM 0x20C | 136 | #define HDMI_CORE_AV_AUDIO_CHSUM 0x20C |
137 | #define HDMI_CORE_AV_AUD_DBYTE(n) (n * 4 + 0x210) | ||
159 | #define HDMI_CORE_AV_MPEG_TYPE 0x280 | 138 | #define HDMI_CORE_AV_MPEG_TYPE 0x280 |
160 | #define HDMI_CORE_AV_MPEG_VERS 0x284 | 139 | #define HDMI_CORE_AV_MPEG_VERS 0x284 |
161 | #define HDMI_CORE_AV_MPEG_LEN 0x288 | 140 | #define HDMI_CORE_AV_MPEG_LEN 0x288 |
162 | #define HDMI_CORE_AV_MPEG_CHSUM 0x28C | 141 | #define HDMI_CORE_AV_MPEG_CHSUM 0x28C |
142 | #define HDMI_CORE_AV_MPEG_DBYTE(n) (n * 4 + 0x290) | ||
143 | #define HDMI_CORE_AV_GEN_DBYTE(n) (n * 4 + 0x300) | ||
163 | #define HDMI_CORE_AV_CP_BYTE1 0x37C | 144 | #define HDMI_CORE_AV_CP_BYTE1 0x37C |
145 | #define HDMI_CORE_AV_GEN2_DBYTE(n) (n * 4 + 0x380) | ||
164 | #define HDMI_CORE_AV_CEC_ADDR_ID 0x3FC | 146 | #define HDMI_CORE_AV_CEC_ADDR_ID 0x3FC |
147 | |||
165 | #define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4 | 148 | #define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4 |
166 | #define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4 | 149 | #define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4 |
167 | #define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4 | 150 | #define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4 |
168 | #define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4 | 151 | #define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4 |
169 | 152 | ||
153 | #define HDMI_CORE_AV_AVI_DBYTE_NELEMS 15 | ||
154 | #define HDMI_CORE_AV_SPD_DBYTE_NELEMS 27 | ||
155 | #define HDMI_CORE_AV_AUD_DBYTE_NELEMS 10 | ||
156 | #define HDMI_CORE_AV_MPEG_DBYTE_NELEMS 27 | ||
157 | #define HDMI_CORE_AV_GEN_DBYTE_NELEMS 31 | ||
158 | #define HDMI_CORE_AV_GEN2_DBYTE_NELEMS 31 | ||
159 | |||
170 | /* PLL */ | 160 | /* PLL */ |
171 | 161 | ||
172 | #define PLLCTRL_PLL_CONTROL 0x0 | 162 | #define PLLCTRL_PLL_CONTROL 0x0 |
@@ -284,35 +274,6 @@ enum hdmi_core_infoframe { | |||
284 | HDMI_INFOFRAME_AVI_DB5PR_8 = 7, | 274 | HDMI_INFOFRAME_AVI_DB5PR_8 = 7, |
285 | HDMI_INFOFRAME_AVI_DB5PR_9 = 8, | 275 | HDMI_INFOFRAME_AVI_DB5PR_9 = 8, |
286 | HDMI_INFOFRAME_AVI_DB5PR_10 = 9, | 276 | HDMI_INFOFRAME_AVI_DB5PR_10 = 9, |
287 | HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM = 0, | ||
288 | HDMI_INFOFRAME_AUDIO_DB1CT_IEC60958 = 1, | ||
289 | HDMI_INFOFRAME_AUDIO_DB1CT_AC3 = 2, | ||
290 | HDMI_INFOFRAME_AUDIO_DB1CT_MPEG1 = 3, | ||
291 | HDMI_INFOFRAME_AUDIO_DB1CT_MP3 = 4, | ||
292 | HDMI_INFOFRAME_AUDIO_DB1CT_MPEG2_MULTICH = 5, | ||
293 | HDMI_INFOFRAME_AUDIO_DB1CT_AAC = 6, | ||
294 | HDMI_INFOFRAME_AUDIO_DB1CT_DTS = 7, | ||
295 | HDMI_INFOFRAME_AUDIO_DB1CT_ATRAC = 8, | ||
296 | HDMI_INFOFRAME_AUDIO_DB1CT_ONEBIT = 9, | ||
297 | HDMI_INFOFRAME_AUDIO_DB1CT_DOLBY_DIGITAL_PLUS = 10, | ||
298 | HDMI_INFOFRAME_AUDIO_DB1CT_DTS_HD = 11, | ||
299 | HDMI_INFOFRAME_AUDIO_DB1CT_MAT = 12, | ||
300 | HDMI_INFOFRAME_AUDIO_DB1CT_DST = 13, | ||
301 | HDMI_INFOFRAME_AUDIO_DB1CT_WMA_PRO = 14, | ||
302 | HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM = 0, | ||
303 | HDMI_INFOFRAME_AUDIO_DB2SF_32000 = 1, | ||
304 | HDMI_INFOFRAME_AUDIO_DB2SF_44100 = 2, | ||
305 | HDMI_INFOFRAME_AUDIO_DB2SF_48000 = 3, | ||
306 | HDMI_INFOFRAME_AUDIO_DB2SF_88200 = 4, | ||
307 | HDMI_INFOFRAME_AUDIO_DB2SF_96000 = 5, | ||
308 | HDMI_INFOFRAME_AUDIO_DB2SF_176400 = 6, | ||
309 | HDMI_INFOFRAME_AUDIO_DB2SF_192000 = 7, | ||
310 | HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM = 0, | ||
311 | HDMI_INFOFRAME_AUDIO_DB2SS_16BIT = 1, | ||
312 | HDMI_INFOFRAME_AUDIO_DB2SS_20BIT = 2, | ||
313 | HDMI_INFOFRAME_AUDIO_DB2SS_24BIT = 3, | ||
314 | HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PERMITTED = 0, | ||
315 | HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PROHIBITED = 1 | ||
316 | }; | 277 | }; |
317 | 278 | ||
318 | enum hdmi_packing_mode { | 279 | enum hdmi_packing_mode { |
@@ -322,17 +283,6 @@ enum hdmi_packing_mode { | |||
322 | HDMI_PACK_ALREADYPACKED = 7 | 283 | HDMI_PACK_ALREADYPACKED = 7 |
323 | }; | 284 | }; |
324 | 285 | ||
325 | enum hdmi_core_audio_sample_freq { | ||
326 | HDMI_AUDIO_FS_32000 = 0x3, | ||
327 | HDMI_AUDIO_FS_44100 = 0x0, | ||
328 | HDMI_AUDIO_FS_48000 = 0x2, | ||
329 | HDMI_AUDIO_FS_88200 = 0x8, | ||
330 | HDMI_AUDIO_FS_96000 = 0xA, | ||
331 | HDMI_AUDIO_FS_176400 = 0xC, | ||
332 | HDMI_AUDIO_FS_192000 = 0xE, | ||
333 | HDMI_AUDIO_FS_NOT_INDICATED = 0x1 | ||
334 | }; | ||
335 | |||
336 | enum hdmi_core_audio_layout { | 286 | enum hdmi_core_audio_layout { |
337 | HDMI_AUDIO_LAYOUT_2CH = 0, | 287 | HDMI_AUDIO_LAYOUT_2CH = 0, |
338 | HDMI_AUDIO_LAYOUT_8CH = 1 | 288 | HDMI_AUDIO_LAYOUT_8CH = 1 |
@@ -387,37 +337,12 @@ enum hdmi_audio_blk_strt_end_sig { | |||
387 | }; | 337 | }; |
388 | 338 | ||
389 | enum hdmi_audio_i2s_config { | 339 | enum hdmi_audio_i2s_config { |
390 | HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT = 0, | ||
391 | HDMI_AUDIO_I2S_WS_POLARIT_YLOW_IS_RIGHT = 1, | ||
392 | HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0, | 340 | HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0, |
393 | HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1, | 341 | HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1, |
394 | HDMI_AUDIO_I2S_MAX_WORD_20BITS = 0, | ||
395 | HDMI_AUDIO_I2S_MAX_WORD_24BITS = 1, | ||
396 | HDMI_AUDIO_I2S_CHST_WORD_NOT_SPECIFIED = 0, | ||
397 | HDMI_AUDIO_I2S_CHST_WORD_16_BITS = 1, | ||
398 | HDMI_AUDIO_I2S_CHST_WORD_17_BITS = 6, | ||
399 | HDMI_AUDIO_I2S_CHST_WORD_18_BITS = 2, | ||
400 | HDMI_AUDIO_I2S_CHST_WORD_19_BITS = 4, | ||
401 | HDMI_AUDIO_I2S_CHST_WORD_20_BITS_20MAX = 5, | ||
402 | HDMI_AUDIO_I2S_CHST_WORD_20_BITS_24MAX = 1, | ||
403 | HDMI_AUDIO_I2S_CHST_WORD_21_BITS = 6, | ||
404 | HDMI_AUDIO_I2S_CHST_WORD_22_BITS = 2, | ||
405 | HDMI_AUDIO_I2S_CHST_WORD_23_BITS = 4, | ||
406 | HDMI_AUDIO_I2S_CHST_WORD_24_BITS = 5, | ||
407 | HDMI_AUDIO_I2S_SCK_EDGE_FALLING = 0, | 342 | HDMI_AUDIO_I2S_SCK_EDGE_FALLING = 0, |
408 | HDMI_AUDIO_I2S_SCK_EDGE_RISING = 1, | 343 | HDMI_AUDIO_I2S_SCK_EDGE_RISING = 1, |
409 | HDMI_AUDIO_I2S_VBIT_FOR_PCM = 0, | 344 | HDMI_AUDIO_I2S_VBIT_FOR_PCM = 0, |
410 | HDMI_AUDIO_I2S_VBIT_FOR_COMPRESSED = 1, | 345 | HDMI_AUDIO_I2S_VBIT_FOR_COMPRESSED = 1, |
411 | HDMI_AUDIO_I2S_INPUT_LENGTH_NA = 0, | ||
412 | HDMI_AUDIO_I2S_INPUT_LENGTH_16 = 2, | ||
413 | HDMI_AUDIO_I2S_INPUT_LENGTH_17 = 12, | ||
414 | HDMI_AUDIO_I2S_INPUT_LENGTH_18 = 4, | ||
415 | HDMI_AUDIO_I2S_INPUT_LENGTH_19 = 8, | ||
416 | HDMI_AUDIO_I2S_INPUT_LENGTH_20 = 10, | ||
417 | HDMI_AUDIO_I2S_INPUT_LENGTH_21 = 13, | ||
418 | HDMI_AUDIO_I2S_INPUT_LENGTH_22 = 5, | ||
419 | HDMI_AUDIO_I2S_INPUT_LENGTH_23 = 9, | ||
420 | HDMI_AUDIO_I2S_INPUT_LENGTH_24 = 11, | ||
421 | HDMI_AUDIO_I2S_FIRST_BIT_SHIFT = 0, | 346 | HDMI_AUDIO_I2S_FIRST_BIT_SHIFT = 0, |
422 | HDMI_AUDIO_I2S_FIRST_BIT_NO_SHIFT = 1, | 347 | HDMI_AUDIO_I2S_FIRST_BIT_NO_SHIFT = 1, |
423 | HDMI_AUDIO_I2S_SD0_EN = 1, | 348 | HDMI_AUDIO_I2S_SD0_EN = 1, |
@@ -446,20 +371,6 @@ struct hdmi_core_video_config { | |||
446 | enum hdmi_core_tclkselclkmult tclk_sel_clkmult; | 371 | enum hdmi_core_tclkselclkmult tclk_sel_clkmult; |
447 | }; | 372 | }; |
448 | 373 | ||
449 | /* | ||
450 | * Refer to section 8.2 in HDMI 1.3 specification for | ||
451 | * details about infoframe databytes | ||
452 | */ | ||
453 | struct hdmi_core_infoframe_audio { | ||
454 | u8 db1_coding_type; | ||
455 | u8 db1_channel_count; | ||
456 | u8 db2_sample_freq; | ||
457 | u8 db2_sample_size; | ||
458 | u8 db4_channel_alloc; | ||
459 | bool db5_downmix_inh; | ||
460 | u8 db5_lsv; /* Level shift values for downmix */ | ||
461 | }; | ||
462 | |||
463 | struct hdmi_core_packet_enable_repeat { | 374 | struct hdmi_core_packet_enable_repeat { |
464 | u32 audio_pkt; | 375 | u32 audio_pkt; |
465 | u32 audio_pkt_repeat; | 376 | u32 audio_pkt_repeat; |
@@ -496,15 +407,10 @@ struct hdmi_audio_dma { | |||
496 | }; | 407 | }; |
497 | 408 | ||
498 | struct hdmi_core_audio_i2s_config { | 409 | struct hdmi_core_audio_i2s_config { |
499 | u8 word_max_length; | ||
500 | u8 word_length; | ||
501 | u8 in_length_bits; | 410 | u8 in_length_bits; |
502 | u8 justification; | 411 | u8 justification; |
503 | u8 en_high_bitrate_aud; | ||
504 | u8 sck_edge_mode; | 412 | u8 sck_edge_mode; |
505 | u8 cbit_order; | ||
506 | u8 vbit; | 413 | u8 vbit; |
507 | u8 ws_polarity; | ||
508 | u8 direction; | 414 | u8 direction; |
509 | u8 shift; | 415 | u8 shift; |
510 | u8 active_sds; | 416 | u8 active_sds; |
@@ -512,7 +418,7 @@ struct hdmi_core_audio_i2s_config { | |||
512 | 418 | ||
513 | struct hdmi_core_audio_config { | 419 | struct hdmi_core_audio_config { |
514 | struct hdmi_core_audio_i2s_config i2s_cfg; | 420 | struct hdmi_core_audio_i2s_config i2s_cfg; |
515 | enum hdmi_core_audio_sample_freq freq_sample; | 421 | struct snd_aes_iec958 *iec60958_cfg; |
516 | bool fs_override; | 422 | bool fs_override; |
517 | u32 n; | 423 | u32 n; |
518 | u32 cts; | 424 | u32 cts; |
@@ -527,17 +433,4 @@ struct hdmi_core_audio_config { | |||
527 | bool en_spdif; | 433 | bool en_spdif; |
528 | }; | 434 | }; |
529 | 435 | ||
530 | #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ | ||
531 | defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) | ||
532 | int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, | ||
533 | u32 sample_freq, u32 *n, u32 *cts); | ||
534 | void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, | ||
535 | struct hdmi_core_infoframe_audio *info_aud); | ||
536 | void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, | ||
537 | struct hdmi_core_audio_config *cfg); | ||
538 | void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, | ||
539 | struct hdmi_audio_dma *aud_dma); | ||
540 | void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data, | ||
541 | struct hdmi_audio_format *aud_fmt); | ||
542 | #endif | ||
543 | #endif | 436 | #endif |
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 9c3daf71750c..2b8973931ff4 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c | |||
@@ -415,6 +415,7 @@ static const struct venc_config *venc_timings_to_config( | |||
415 | return &venc_config_ntsc_trm; | 415 | return &venc_config_ntsc_trm; |
416 | 416 | ||
417 | BUG(); | 417 | BUG(); |
418 | return NULL; | ||
418 | } | 419 | } |
419 | 420 | ||
420 | static int venc_power_on(struct omap_dss_device *dssdev) | 421 | static int venc_power_on(struct omap_dss_device *dssdev) |
@@ -440,10 +441,11 @@ static int venc_power_on(struct omap_dss_device *dssdev) | |||
440 | 441 | ||
441 | venc_write_reg(VENC_OUTPUT_CONTROL, l); | 442 | venc_write_reg(VENC_OUTPUT_CONTROL, l); |
442 | 443 | ||
443 | dispc_set_digit_size(dssdev->panel.timings.x_res, | 444 | dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); |
444 | dssdev->panel.timings.y_res/2); | ||
445 | 445 | ||
446 | regulator_enable(venc.vdda_dac_reg); | 446 | r = regulator_enable(venc.vdda_dac_reg); |
447 | if (r) | ||
448 | goto err; | ||
447 | 449 | ||
448 | if (dssdev->platform_enable) | 450 | if (dssdev->platform_enable) |
449 | dssdev->platform_enable(dssdev); | 451 | dssdev->platform_enable(dssdev); |
@@ -485,16 +487,68 @@ unsigned long venc_get_pixel_clock(void) | |||
485 | return 13500000; | 487 | return 13500000; |
486 | } | 488 | } |
487 | 489 | ||
490 | static ssize_t display_output_type_show(struct device *dev, | ||
491 | struct device_attribute *attr, char *buf) | ||
492 | { | ||
493 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
494 | const char *ret; | ||
495 | |||
496 | switch (dssdev->phy.venc.type) { | ||
497 | case OMAP_DSS_VENC_TYPE_COMPOSITE: | ||
498 | ret = "composite"; | ||
499 | break; | ||
500 | case OMAP_DSS_VENC_TYPE_SVIDEO: | ||
501 | ret = "svideo"; | ||
502 | break; | ||
503 | default: | ||
504 | return -EINVAL; | ||
505 | } | ||
506 | |||
507 | return snprintf(buf, PAGE_SIZE, "%s\n", ret); | ||
508 | } | ||
509 | |||
510 | static ssize_t display_output_type_store(struct device *dev, | ||
511 | struct device_attribute *attr, const char *buf, size_t size) | ||
512 | { | ||
513 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
514 | enum omap_dss_venc_type new_type; | ||
515 | |||
516 | if (sysfs_streq("composite", buf)) | ||
517 | new_type = OMAP_DSS_VENC_TYPE_COMPOSITE; | ||
518 | else if (sysfs_streq("svideo", buf)) | ||
519 | new_type = OMAP_DSS_VENC_TYPE_SVIDEO; | ||
520 | else | ||
521 | return -EINVAL; | ||
522 | |||
523 | mutex_lock(&venc.venc_lock); | ||
524 | |||
525 | if (dssdev->phy.venc.type != new_type) { | ||
526 | dssdev->phy.venc.type = new_type; | ||
527 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | ||
528 | venc_power_off(dssdev); | ||
529 | venc_power_on(dssdev); | ||
530 | } | ||
531 | } | ||
532 | |||
533 | mutex_unlock(&venc.venc_lock); | ||
534 | |||
535 | return size; | ||
536 | } | ||
537 | |||
538 | static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR, | ||
539 | display_output_type_show, display_output_type_store); | ||
540 | |||
488 | /* driver */ | 541 | /* driver */ |
489 | static int venc_panel_probe(struct omap_dss_device *dssdev) | 542 | static int venc_panel_probe(struct omap_dss_device *dssdev) |
490 | { | 543 | { |
491 | dssdev->panel.timings = omap_dss_pal_timings; | 544 | dssdev->panel.timings = omap_dss_pal_timings; |
492 | 545 | ||
493 | return 0; | 546 | return device_create_file(&dssdev->dev, &dev_attr_output_type); |
494 | } | 547 | } |
495 | 548 | ||
496 | static void venc_panel_remove(struct omap_dss_device *dssdev) | 549 | static void venc_panel_remove(struct omap_dss_device *dssdev) |
497 | { | 550 | { |
551 | device_remove_file(&dssdev->dev, &dev_attr_output_type); | ||
498 | } | 552 | } |
499 | 553 | ||
500 | static int venc_panel_enable(struct omap_dss_device *dssdev) | 554 | static int venc_panel_enable(struct omap_dss_device *dssdev) |
@@ -577,12 +631,6 @@ static int venc_panel_resume(struct omap_dss_device *dssdev) | |||
577 | return venc_panel_enable(dssdev); | 631 | return venc_panel_enable(dssdev); |
578 | } | 632 | } |
579 | 633 | ||
580 | static void venc_get_timings(struct omap_dss_device *dssdev, | ||
581 | struct omap_video_timings *timings) | ||
582 | { | ||
583 | *timings = dssdev->panel.timings; | ||
584 | } | ||
585 | |||
586 | static void venc_set_timings(struct omap_dss_device *dssdev, | 634 | static void venc_set_timings(struct omap_dss_device *dssdev, |
587 | struct omap_video_timings *timings) | 635 | struct omap_video_timings *timings) |
588 | { | 636 | { |
@@ -597,6 +645,8 @@ static void venc_set_timings(struct omap_dss_device *dssdev, | |||
597 | /* turn the venc off and on to get new timings to use */ | 645 | /* turn the venc off and on to get new timings to use */ |
598 | venc_panel_disable(dssdev); | 646 | venc_panel_disable(dssdev); |
599 | venc_panel_enable(dssdev); | 647 | venc_panel_enable(dssdev); |
648 | } else { | ||
649 | dss_mgr_set_timings(dssdev->manager, timings); | ||
600 | } | 650 | } |
601 | } | 651 | } |
602 | 652 | ||
@@ -661,7 +711,6 @@ static struct omap_dss_driver venc_driver = { | |||
661 | .get_resolution = omapdss_default_get_resolution, | 711 | .get_resolution = omapdss_default_get_resolution, |
662 | .get_recommended_bpp = omapdss_default_get_recommended_bpp, | 712 | .get_recommended_bpp = omapdss_default_get_recommended_bpp, |
663 | 713 | ||
664 | .get_timings = venc_get_timings, | ||
665 | .set_timings = venc_set_timings, | 714 | .set_timings = venc_set_timings, |
666 | .check_timings = venc_check_timings, | 715 | .check_timings = venc_check_timings, |
667 | 716 | ||
@@ -675,7 +724,7 @@ static struct omap_dss_driver venc_driver = { | |||
675 | }; | 724 | }; |
676 | /* driver end */ | 725 | /* driver end */ |
677 | 726 | ||
678 | int venc_init_display(struct omap_dss_device *dssdev) | 727 | static int __init venc_init_display(struct omap_dss_device *dssdev) |
679 | { | 728 | { |
680 | DSSDBG("init_display\n"); | 729 | DSSDBG("init_display\n"); |
681 | 730 | ||
@@ -695,7 +744,7 @@ int venc_init_display(struct omap_dss_device *dssdev) | |||
695 | return 0; | 744 | return 0; |
696 | } | 745 | } |
697 | 746 | ||
698 | void venc_dump_regs(struct seq_file *s) | 747 | static void venc_dump_regs(struct seq_file *s) |
699 | { | 748 | { |
700 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) | 749 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) |
701 | 750 | ||
@@ -779,8 +828,32 @@ static void venc_put_clocks(void) | |||
779 | clk_put(venc.tv_dac_clk); | 828 | clk_put(venc.tv_dac_clk); |
780 | } | 829 | } |
781 | 830 | ||
831 | static void __init venc_probe_pdata(struct platform_device *pdev) | ||
832 | { | ||
833 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
834 | int r, i; | ||
835 | |||
836 | for (i = 0; i < pdata->num_devices; ++i) { | ||
837 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
838 | |||
839 | if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) | ||
840 | continue; | ||
841 | |||
842 | r = venc_init_display(dssdev); | ||
843 | if (r) { | ||
844 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
845 | continue; | ||
846 | } | ||
847 | |||
848 | r = omap_dss_register_device(dssdev, &pdev->dev, i); | ||
849 | if (r) | ||
850 | DSSERR("device %s register failed: %d\n", | ||
851 | dssdev->name, r); | ||
852 | } | ||
853 | } | ||
854 | |||
782 | /* VENC HW IP initialisation */ | 855 | /* VENC HW IP initialisation */ |
783 | static int omap_venchw_probe(struct platform_device *pdev) | 856 | static int __init omap_venchw_probe(struct platform_device *pdev) |
784 | { | 857 | { |
785 | u8 rev_id; | 858 | u8 rev_id; |
786 | struct resource *venc_mem; | 859 | struct resource *venc_mem; |
@@ -824,6 +897,10 @@ static int omap_venchw_probe(struct platform_device *pdev) | |||
824 | if (r) | 897 | if (r) |
825 | goto err_reg_panel_driver; | 898 | goto err_reg_panel_driver; |
826 | 899 | ||
900 | dss_debugfs_create_file("venc", venc_dump_regs); | ||
901 | |||
902 | venc_probe_pdata(pdev); | ||
903 | |||
827 | return 0; | 904 | return 0; |
828 | 905 | ||
829 | err_reg_panel_driver: | 906 | err_reg_panel_driver: |
@@ -833,12 +910,15 @@ err_runtime_get: | |||
833 | return r; | 910 | return r; |
834 | } | 911 | } |
835 | 912 | ||
836 | static int omap_venchw_remove(struct platform_device *pdev) | 913 | static int __exit omap_venchw_remove(struct platform_device *pdev) |
837 | { | 914 | { |
915 | omap_dss_unregister_child_devices(&pdev->dev); | ||
916 | |||
838 | if (venc.vdda_dac_reg != NULL) { | 917 | if (venc.vdda_dac_reg != NULL) { |
839 | regulator_put(venc.vdda_dac_reg); | 918 | regulator_put(venc.vdda_dac_reg); |
840 | venc.vdda_dac_reg = NULL; | 919 | venc.vdda_dac_reg = NULL; |
841 | } | 920 | } |
921 | |||
842 | omap_dss_unregister_driver(&venc_driver); | 922 | omap_dss_unregister_driver(&venc_driver); |
843 | 923 | ||
844 | pm_runtime_disable(&pdev->dev); | 924 | pm_runtime_disable(&pdev->dev); |
@@ -853,7 +933,6 @@ static int venc_runtime_suspend(struct device *dev) | |||
853 | clk_disable(venc.tv_dac_clk); | 933 | clk_disable(venc.tv_dac_clk); |
854 | 934 | ||
855 | dispc_runtime_put(); | 935 | dispc_runtime_put(); |
856 | dss_runtime_put(); | ||
857 | 936 | ||
858 | return 0; | 937 | return 0; |
859 | } | 938 | } |
@@ -862,23 +941,14 @@ static int venc_runtime_resume(struct device *dev) | |||
862 | { | 941 | { |
863 | int r; | 942 | int r; |
864 | 943 | ||
865 | r = dss_runtime_get(); | ||
866 | if (r < 0) | ||
867 | goto err_get_dss; | ||
868 | |||
869 | r = dispc_runtime_get(); | 944 | r = dispc_runtime_get(); |
870 | if (r < 0) | 945 | if (r < 0) |
871 | goto err_get_dispc; | 946 | return r; |
872 | 947 | ||
873 | if (venc.tv_dac_clk) | 948 | if (venc.tv_dac_clk) |
874 | clk_enable(venc.tv_dac_clk); | 949 | clk_enable(venc.tv_dac_clk); |
875 | 950 | ||
876 | return 0; | 951 | return 0; |
877 | |||
878 | err_get_dispc: | ||
879 | dss_runtime_put(); | ||
880 | err_get_dss: | ||
881 | return r; | ||
882 | } | 952 | } |
883 | 953 | ||
884 | static const struct dev_pm_ops venc_pm_ops = { | 954 | static const struct dev_pm_ops venc_pm_ops = { |
@@ -887,8 +957,7 @@ static const struct dev_pm_ops venc_pm_ops = { | |||
887 | }; | 957 | }; |
888 | 958 | ||
889 | static struct platform_driver omap_venchw_driver = { | 959 | static struct platform_driver omap_venchw_driver = { |
890 | .probe = omap_venchw_probe, | 960 | .remove = __exit_p(omap_venchw_remove), |
891 | .remove = omap_venchw_remove, | ||
892 | .driver = { | 961 | .driver = { |
893 | .name = "omapdss_venc", | 962 | .name = "omapdss_venc", |
894 | .owner = THIS_MODULE, | 963 | .owner = THIS_MODULE, |
@@ -896,18 +965,18 @@ static struct platform_driver omap_venchw_driver = { | |||
896 | }, | 965 | }, |
897 | }; | 966 | }; |
898 | 967 | ||
899 | int venc_init_platform_driver(void) | 968 | int __init venc_init_platform_driver(void) |
900 | { | 969 | { |
901 | if (cpu_is_omap44xx()) | 970 | if (cpu_is_omap44xx()) |
902 | return 0; | 971 | return 0; |
903 | 972 | ||
904 | return platform_driver_register(&omap_venchw_driver); | 973 | return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe); |
905 | } | 974 | } |
906 | 975 | ||
907 | void venc_uninit_platform_driver(void) | 976 | void __exit venc_uninit_platform_driver(void) |
908 | { | 977 | { |
909 | if (cpu_is_omap44xx()) | 978 | if (cpu_is_omap44xx()) |
910 | return; | 979 | return; |
911 | 980 | ||
912 | return platform_driver_unregister(&omap_venchw_driver); | 981 | platform_driver_unregister(&omap_venchw_driver); |
913 | } | 982 | } |
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 6a09ef87e14f..c6cf372d22c5 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c | |||
@@ -70,7 +70,7 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) | |||
70 | 70 | ||
71 | DBG("omapfb_setup_plane\n"); | 71 | DBG("omapfb_setup_plane\n"); |
72 | 72 | ||
73 | if (ofbi->num_overlays != 1) { | 73 | if (ofbi->num_overlays == 0) { |
74 | r = -EINVAL; | 74 | r = -EINVAL; |
75 | goto out; | 75 | goto out; |
76 | } | 76 | } |
@@ -185,7 +185,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) | |||
185 | { | 185 | { |
186 | struct omapfb_info *ofbi = FB2OFB(fbi); | 186 | struct omapfb_info *ofbi = FB2OFB(fbi); |
187 | 187 | ||
188 | if (ofbi->num_overlays != 1) { | 188 | if (ofbi->num_overlays == 0) { |
189 | memset(pi, 0, sizeof(*pi)); | 189 | memset(pi, 0, sizeof(*pi)); |
190 | } else { | 190 | } else { |
191 | struct omap_overlay *ovl; | 191 | struct omap_overlay *ovl; |
@@ -225,6 +225,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) | |||
225 | down_write_nested(&rg->lock, rg->id); | 225 | down_write_nested(&rg->lock, rg->id); |
226 | atomic_inc(&rg->lock_count); | 226 | atomic_inc(&rg->lock_count); |
227 | 227 | ||
228 | if (rg->size == size && rg->type == mi->type) | ||
229 | goto out; | ||
230 | |||
228 | if (atomic_read(&rg->map_count)) { | 231 | if (atomic_read(&rg->map_count)) { |
229 | r = -EBUSY; | 232 | r = -EBUSY; |
230 | goto out; | 233 | goto out; |
@@ -247,12 +250,10 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) | |||
247 | } | 250 | } |
248 | } | 251 | } |
249 | 252 | ||
250 | if (rg->size != size || rg->type != mi->type) { | 253 | r = omapfb_realloc_fbmem(fbi, size, mi->type); |
251 | r = omapfb_realloc_fbmem(fbi, size, mi->type); | 254 | if (r) { |
252 | if (r) { | 255 | dev_err(fbdev->dev, "realloc fbmem failed\n"); |
253 | dev_err(fbdev->dev, "realloc fbmem failed\n"); | 256 | goto out; |
254 | goto out; | ||
255 | } | ||
256 | } | 257 | } |
257 | 258 | ||
258 | out: | 259 | out: |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index b00db4068d21..3450ea0966c9 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
@@ -179,6 +179,7 @@ static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot) | |||
179 | break; | 179 | break; |
180 | default: | 180 | default: |
181 | BUG(); | 181 | BUG(); |
182 | return 0; | ||
182 | } | 183 | } |
183 | 184 | ||
184 | offset *= vrfb->bytespp; | 185 | offset *= vrfb->bytespp; |
@@ -1502,7 +1503,7 @@ static int omapfb_parse_vram_param(const char *param, int max_entries, | |||
1502 | 1503 | ||
1503 | fbnum = simple_strtoul(p, &p, 10); | 1504 | fbnum = simple_strtoul(p, &p, 10); |
1504 | 1505 | ||
1505 | if (p == param) | 1506 | if (p == start) |
1506 | return -EINVAL; | 1507 | return -EINVAL; |
1507 | 1508 | ||
1508 | if (*p != ':') | 1509 | if (*p != ':') |
@@ -2307,7 +2308,7 @@ static int omapfb_init_display(struct omapfb2_device *fbdev, | |||
2307 | return 0; | 2308 | return 0; |
2308 | } | 2309 | } |
2309 | 2310 | ||
2310 | static int omapfb_probe(struct platform_device *pdev) | 2311 | static int __init omapfb_probe(struct platform_device *pdev) |
2311 | { | 2312 | { |
2312 | struct omapfb2_device *fbdev = NULL; | 2313 | struct omapfb2_device *fbdev = NULL; |
2313 | int r = 0; | 2314 | int r = 0; |
@@ -2448,7 +2449,7 @@ err0: | |||
2448 | return r; | 2449 | return r; |
2449 | } | 2450 | } |
2450 | 2451 | ||
2451 | static int omapfb_remove(struct platform_device *pdev) | 2452 | static int __exit omapfb_remove(struct platform_device *pdev) |
2452 | { | 2453 | { |
2453 | struct omapfb2_device *fbdev = platform_get_drvdata(pdev); | 2454 | struct omapfb2_device *fbdev = platform_get_drvdata(pdev); |
2454 | 2455 | ||
@@ -2462,8 +2463,7 @@ static int omapfb_remove(struct platform_device *pdev) | |||
2462 | } | 2463 | } |
2463 | 2464 | ||
2464 | static struct platform_driver omapfb_driver = { | 2465 | static struct platform_driver omapfb_driver = { |
2465 | .probe = omapfb_probe, | 2466 | .remove = __exit_p(omapfb_remove), |
2466 | .remove = omapfb_remove, | ||
2467 | .driver = { | 2467 | .driver = { |
2468 | .name = "omapfb", | 2468 | .name = "omapfb", |
2469 | .owner = THIS_MODULE, | 2469 | .owner = THIS_MODULE, |
@@ -2474,7 +2474,7 @@ static int __init omapfb_init(void) | |||
2474 | { | 2474 | { |
2475 | DBG("omapfb_init\n"); | 2475 | DBG("omapfb_init\n"); |
2476 | 2476 | ||
2477 | if (platform_driver_register(&omapfb_driver)) { | 2477 | if (platform_driver_probe(&omapfb_driver, omapfb_probe)) { |
2478 | printk(KERN_ERR "failed to register omapfb driver\n"); | 2478 | printk(KERN_ERR "failed to register omapfb driver\n"); |
2479 | return -ENODEV; | 2479 | return -ENODEV; |
2480 | } | 2480 | } |
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h index c0bdc9b54ecf..30361a09aecd 100644 --- a/drivers/video/omap2/omapfb/omapfb.h +++ b/drivers/video/omap2/omapfb/omapfb.h | |||
@@ -166,6 +166,7 @@ static inline struct omapfb_display_data *get_display_data( | |||
166 | 166 | ||
167 | /* This should never happen */ | 167 | /* This should never happen */ |
168 | BUG(); | 168 | BUG(); |
169 | return NULL; | ||
169 | } | 170 | } |
170 | 171 | ||
171 | static inline void omapfb_lock(struct omapfb2_device *fbdev) | 172 | static inline void omapfb_lock(struct omapfb2_device *fbdev) |
diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/omap2/vrfb.c index 4e5b960c32c8..7e990220ad2a 100644 --- a/drivers/video/omap2/vrfb.c +++ b/drivers/video/omap2/vrfb.c | |||
@@ -179,8 +179,10 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, | |||
179 | pixel_size_exp = 2; | 179 | pixel_size_exp = 2; |
180 | else if (bytespp == 2) | 180 | else if (bytespp == 2) |
181 | pixel_size_exp = 1; | 181 | pixel_size_exp = 1; |
182 | else | 182 | else { |
183 | BUG(); | 183 | BUG(); |
184 | return; | ||
185 | } | ||
184 | 186 | ||
185 | vrfb_width = ALIGN(width * bytespp, VRFB_PAGE_WIDTH) / bytespp; | 187 | vrfb_width = ALIGN(width * bytespp, VRFB_PAGE_WIDTH) / bytespp; |
186 | vrfb_height = ALIGN(height, VRFB_PAGE_HEIGHT); | 188 | vrfb_height = ALIGN(height, VRFB_PAGE_HEIGHT); |