aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 19:57:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 19:57:51 -0400
commit804ce9866d56130032c9c8afc90a1297b7deed56 (patch)
tree6dd70984f411d2a3624d3f8db7facc3d6396b9ad /drivers/video/omap2
parentf5e7e844a571124ffc117d4696787d6afc4fc5ae (diff)
parentc895305e806b4346006d3cfba2b432d52268ecd3 (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')
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c7
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c107
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c8
-rw-r--r--drivers/video/omap2/displays/panel-taal.c88
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c76
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c22
-rw-r--r--drivers/video/omap2/dss/Kconfig13
-rw-r--r--drivers/video/omap2/dss/apply.c134
-rw-r--r--drivers/video/omap2/dss/core.c255
-rw-r--r--drivers/video/omap2/dss/dispc.c747
-rw-r--r--drivers/video/omap2/dss/dispc.h72
-rw-r--r--drivers/video/omap2/dss/display.c49
-rw-r--r--drivers/video/omap2/dss/dpi.c75
-rw-r--r--drivers/video/omap2/dss/dsi.c404
-rw-r--r--drivers/video/omap2/dss/dss.c65
-rw-r--r--drivers/video/omap2/dss/dss.h151
-rw-r--r--drivers/video/omap2/dss/dss_features.c30
-rw-r--r--drivers/video/omap2/dss/dss_features.h5
-rw-r--r--drivers/video/omap2/dss/hdmi.c443
-rw-r--r--drivers/video/omap2/dss/hdmi_panel.c236
-rw-r--r--drivers/video/omap2/dss/manager.c19
-rw-r--r--drivers/video/omap2/dss/overlay.c16
-rw-r--r--drivers/video/omap2/dss/rfbi.c84
-rw-r--r--drivers/video/omap2/dss/sdi.c63
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h32
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c480
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h161
-rw-r--r--drivers/video/omap2/dss/venc.c133
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c17
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c12
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h1
-rw-r--r--drivers/video/omap2/vrfb.c4
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
742static void acx_panel_get_timings(struct omap_dss_device *dssdev,
743 struct omap_video_timings *timings)
744{
745 *timings = dssdev->panel.timings;
746}
747
748static int acx_panel_check_timings(struct omap_dss_device *dssdev, 742static 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
391struct panel_drv_data { 491struct 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
552static 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
558static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, 652static 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
613static void n8x0_panel_get_timings(struct omap_dss_device *dssdev,
614 struct omap_video_timings *timings)
615{
616 *timings = dssdev->panel.timings;
617}
618
619static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev, 613static 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
56static int taal_panel_reset(struct omap_dss_device *dssdev); 55static int taal_panel_reset(struct omap_dss_device *dssdev);
57 56
58struct panel_regulator {
59 struct regulator *regulator;
60 const char *name;
61 int min_uV;
62 int max_uV;
63};
64
65static 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
76static 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
119err:
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
157enum { 87enum {
@@ -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
580static void taal_get_timings(struct omap_dss_device *dssdev,
581 struct omap_video_timings *timings)
582{
583 *timings = dssdev->panel.timings;
584}
585
586static void taal_get_resolution(struct omap_dss_device *dssdev, 510static 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:
1087err_rst_gpio: 1006err_rst_gpio:
1088 destroy_workqueue(td->workqueue); 1007 destroy_workqueue(td->workqueue);
1089err_wq: 1008err_wq:
1090 free_regulators(panel_config->regulators, panel_config->num_regulators);
1091err_reg:
1092 kfree(td); 1009 kfree(td);
1093err: 1010err:
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
52static 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
58static int tfp410_power_on(struct omap_dss_device *dssdev) 54static 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;
74err0: 70err0:
@@ -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
91static int tfp410_probe(struct omap_dss_device *dssdev) 87static 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;
140err_i2c:
141 if (gpio_is_valid(ddata->pd_gpio))
142 gpio_free(ddata->pd_gpio);
143 return r;
125} 144}
126 145
127static void __exit tfp410_remove(struct omap_dss_device *dssdev) 146static 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
143static int tfp410_enable(struct omap_dss_device *dssdev) 163static 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:
319static bool tfp410_detect(struct omap_dss_device *dssdev) 329static 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 = {
272static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) 272static 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
476static 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
482static 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
473static struct omap_dss_driver tpo_td043_driver = { 488static 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
71config OMAP4_DSS_HDMI_AUDIO
72 bool
73 depends on OMAP4_DSS_HDMI
74
71config OMAP2_DSS_SDI 75config 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
93config 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
102config OMAP2_DSS_MIN_FCK_PER_PCK 97config 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
104static struct { 109static struct {
@@ -176,7 +181,7 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
176} 181}
177 182
178static int dss_check_settings_low(struct omap_overlay_manager *mgr, 183static 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 */
215static int dss_check_settings(struct omap_overlay_manager *mgr, 223static 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 */
225static int dss_check_settings_apply(struct omap_overlay_manager *mgr, 232static 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
231static bool need_isr(void) 237static 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 */
321static bool extra_info_update_ongoing(void) 341static 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
627static 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
604static void dss_write_regs_common(void) 643static 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
1267static 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
1276void 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
1229int dss_ovl_set_info(struct omap_overlay *ovl, 1297int 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
48static char *def_disp_name; 50static char *def_disp_name;
@@ -54,9 +56,6 @@ bool dss_debug;
54module_param_named(debug, dss_debug, bool, 0644); 56module_param_named(debug, dss_debug, bool, 0644);
55#endif 57#endif
56 58
57static int omap_dss_register_device(struct omap_dss_device *);
58static void omap_dss_unregister_device(struct omap_dss_device *);
59
60/* REGULATORS */ 59/* REGULATORS */
61 60
62struct regulator *dss_get_vdds_dsi(void) 61struct 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
89int 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
104int 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
114void 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
124int 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)
91static int dss_debug_show(struct seq_file *s, void *unused) 135static 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
177int 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 */
161static inline int dss_initialize_debugfs(void) 190static inline int dss_initialize_debugfs(void)
162{ 191{
@@ -165,14 +194,18 @@ static inline int dss_initialize_debugfs(void)
165static inline void dss_uninitialize_debugfs(void) 194static inline void dss_uninitialize_debugfs(void)
166{ 195{
167} 196}
197static 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 */
171static int omap_dss_probe(struct platform_device *pdev) 205static 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
210err_register:
211 dss_uninitialize_debugfs();
212err_debugfs: 230err_debugfs:
213 231
214 return r; 232 return r;
@@ -216,17 +234,11 @@ err_debugfs:
216 234
217static int omap_dss_remove(struct platform_device *pdev) 235static 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
253static struct platform_driver omap_dss_driver = { 265static 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
430static int omap_dss_register_device(struct omap_dss_device *dssdev) 443int 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
444static void omap_dss_unregister_device(struct omap_dss_device *dssdev) 456void 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
461static 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
468void 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 */
450static int omap_dss_bus_register(void) 474static 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 */
496static 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
517static 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
538static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)];
472 539
473static int __init omap_dss_register_drivers(void) 540static 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
519err_hdmi:
520 dsi_uninit_platform_driver();
521err_dsi:
522 venc_uninit_platform_driver();
523err_venc:
524 rfbi_uninit_platform_driver();
525err_rfbi:
526 dispc_uninit_platform_driver();
527err_dispc: 573err_dispc:
528 dss_uninit_platform_driver(); 574 dss_uninit_platform_driver();
529err_dss: 575err_dss:
@@ -534,10 +580,13 @@ err_dss:
534 580
535static void __exit omap_dss_unregister_drivers(void) 581static 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
134static 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
416static 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
424u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) 399u32 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
788static 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
811void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) 800void 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
986void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height) 977static 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
994void 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
1002static void dispc_read_plane_fifo_sizes(void) 986static void dispc_read_plane_fifo_sizes(void)
@@ -1063,7 +1047,8 @@ void dispc_enable_fifomerge(bool enable)
1063} 1047}
1064 1048
1065void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, 1049void 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
1173static 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
1188static void dispc_ovl_set_scaling_common(enum omap_plane plane, 1261static 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
1305static void dispc_ovl_set_scaling(enum omap_plane plane, 1380static 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
1428static void calc_vrfb_rotation_offset(u8 rotation, bool mirror, 1505static 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
1746static 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
1652static 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 */
1789static 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
1841static 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
1692static unsigned long calc_fclk(enum omap_channel channel, u16 width, 1881static 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
1732static int dispc_ovl_calc_scaling(enum omap_plane plane, 1921static 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
1805int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 2088int 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
2094void dispc_mgr_enable(enum omap_channel channel, bool enable) 2399void 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
2593static 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
2288static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, 2599static 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
2312bool dispc_lcd_timings_ok(struct omap_video_timings *timings) 2623bool 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
2319static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, 2639static 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? */
2343void dispc_mgr_set_lcd_timings(enum omap_channel channel, 2663void 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
2376static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div, 2704static 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
2811unsigned 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
2479void dispc_dump_clocks(struct seq_file *s) 2824void 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
2591void dispc_dump_regs(struct seq_file *s) 2936static 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
3251void 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
3271static void _omap_dispc_initialize_irq(void) 3595static 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 */
3333static int omap_dispchw_probe(struct platform_device *pdev) 3657static 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
3404err_runtime_get: 3733err_runtime_get:
@@ -3407,7 +3736,7 @@ err_runtime_get:
3407 return r; 3736 return r;
3408} 3737}
3409 3738
3410static int omap_dispchw_remove(struct platform_device *pdev) 3739static 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)
3419static int dispc_runtime_suspend(struct device *dev) 3748static 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
3427static int dispc_runtime_resume(struct device *dev) 3755static 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
3445static struct platform_driver omap_dispchw_driver = { 3767static 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
3455int dispc_init_platform_driver(void) 3776int __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
3460void dispc_uninit_platform_driver(void) 3781void __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}
309EXPORT_SYMBOL(omapdss_default_get_recommended_bpp); 310EXPORT_SYMBOL(omapdss_default_get_recommended_bpp);
310 311
312void omapdss_default_get_timings(struct omap_dss_device *dssdev,
313 struct omap_video_timings *timings)
314{
315 *timings = dssdev->panel.timings;
316}
317EXPORT_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:
244err_get_dsi: 240err_get_dsi:
245 dispc_runtime_put(); 241 dispc_runtime_put();
246err_get_dispc: 242err_get_dispc:
247 dss_runtime_put();
248err_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);
251err_reg_enable: 245err_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}
303EXPORT_SYMBOL(dpi_set_timings); 290EXPORT_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}
353EXPORT_SYMBOL(dpi_check_timings); 340EXPORT_SYMBOL(dpi_check_timings);
354 341
355int dpi_init_display(struct omap_dss_device *dssdev) 342static 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
381int dpi_init(void) 368static 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
392static int __init omap_dpi_probe(struct platform_device *pdev)
393{
394 dpi_probe_pdata(pdev);
395
396 return 0;
397}
398
399static 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
386void dpi_exit(void) 406static 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
414int __init dpi_init_platform_driver(void)
387{ 415{
416 return platform_driver_probe(&omap_dpi_driver, omap_dpi_probe);
388} 417}
389 418
419void __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
364static inline int dsi_get_dsidev_id(struct platform_device *dsidev)
365{
366 return dsidev->id;
367}
368
369static inline void dsi_write_reg(struct platform_device *dsidev, 363static 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)
1184static unsigned long dsi_fclk_rate(struct platform_device *dsidev) 1179static 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 */
1282static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, 1276static 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
1890void 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
1907static void dsi_dump_dsidev_regs(struct platform_device *dsidev, 1853static 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
2005void 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}
2020enum dsi_cio_power_state { 1951enum 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);
2448err_scp_clk_dom: 2380err_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
2467static void dsi_config_tx_fifo(struct platform_device *dsidev, 2399static 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();
3344err: 3279err:
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 */
3681static 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 */
3712static 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
3735static 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
3738static int dsi_proto_config(struct omap_dss_device *dssdev) 3853static 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
4201int omap_dsi_update(struct omap_dss_device *dssdev, int channel, 4315int 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)
4345static int dsi_display_init_dsi(struct omap_dss_device *dssdev) 4456static 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);
4397err2: 4508err2:
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
4402err1: 4513err1:
@@ -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}
4528EXPORT_SYMBOL(omapdss_dsi_enable_te); 4638EXPORT_SYMBOL(omapdss_dsi_enable_te);
4529 4639
4530int dsi_init_display(struct omap_dss_device *dssdev) 4640static 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
4793static 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 */
4684static int omap_dsihw_probe(struct platform_device *dsidev) 4822static 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
4787err_runtime_get: 4932err_runtime_get:
@@ -4790,12 +4935,14 @@ err_runtime_get:
4790 return r; 4935 return r;
4791} 4936}
4792 4937
4793static int omap_dsihw_remove(struct platform_device *dsidev) 4938static 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)
4816static int dsi_runtime_suspend(struct device *dev) 4963static 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
4838err_get_dispc:
4839 dss_runtime_put();
4840err_get_dss:
4841 return r;
4842} 4979}
4843 4980
4844static const struct dev_pm_ops dsi_pm_ops = { 4981static 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
4849static struct platform_driver omap_dsihw_driver = { 4986static 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
4859int dsi_init_platform_driver(void) 4995int __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
4864void dsi_uninit_platform_driver(void) 5000void __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
65static int dss_runtime_get(void);
66static void dss_runtime_put(void);
67
65static struct { 68static 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
280void dss_dump_regs(struct seq_file *s) 283static 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
709int dss_runtime_get(void) 716static 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
720void dss_runtime_put(void) 727static 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 */
743static int omap_dsshw_probe(struct platform_device *pdev) 750static 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;
807err_sdi: 804
808 dpi_exit();
809err_dpi:
810 dss_runtime_put();
811err_runtime_get: 805err_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
817static int omap_dsshw_remove(struct platform_device *pdev) 811static 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)
829static int dss_runtime_suspend(struct device *dev) 820static 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
835static int dss_runtime_resume(struct device *dev) 827static 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
846static struct platform_driver omap_dsshw_driver = { 850static 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
856int dss_init_platform_driver(void) 859int __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
861void dss_uninit_platform_driver(void) 864void 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
158struct seq_file; 155struct seq_file;
@@ -162,6 +159,16 @@ struct platform_device;
162struct bus_type *dss_get_bus(void); 159struct bus_type *dss_get_bus(void);
163struct regulator *dss_get_vdds_dsi(void); 160struct regulator *dss_get_vdds_dsi(void);
164struct regulator *dss_get_vdds_sdi(void); 161struct regulator *dss_get_vdds_sdi(void);
162int dss_get_ctx_loss_count(struct device *dev);
163int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask);
164void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
165int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
166int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
167
168int omap_dss_register_device(struct omap_dss_device *dssdev,
169 struct device *parent, int disp_num);
170void omap_dss_unregister_device(struct omap_dss_device *dssdev);
171void omap_dss_unregister_child_devices(struct device *parent);
165 172
166/* apply */ 173/* apply */
167void dss_apply_init(void); 174void dss_apply_init(void);
@@ -179,6 +186,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
179int dss_mgr_set_device(struct omap_overlay_manager *mgr, 186int dss_mgr_set_device(struct omap_overlay_manager *mgr,
180 struct omap_dss_device *dssdev); 187 struct omap_dss_device *dssdev);
181int dss_mgr_unset_device(struct omap_overlay_manager *mgr); 188int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
189void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
190 struct omap_video_timings *timings);
191const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
182 192
183bool dss_ovl_is_enabled(struct omap_overlay *ovl); 193bool dss_ovl_is_enabled(struct omap_overlay *ovl);
184int dss_ovl_enable(struct omap_overlay *ovl); 194int dss_ovl_enable(struct omap_overlay *ovl);
@@ -208,9 +218,11 @@ int dss_init_overlay_managers(struct platform_device *pdev);
208void dss_uninit_overlay_managers(struct platform_device *pdev); 218void dss_uninit_overlay_managers(struct platform_device *pdev);
209int dss_mgr_simple_check(struct omap_overlay_manager *mgr, 219int 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);
221int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
222 const struct omap_video_timings *timings);
211int dss_mgr_check(struct omap_overlay_manager *mgr, 223int 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);
220void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); 232void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
221int dss_ovl_simple_check(struct omap_overlay *ovl, 233int dss_ovl_simple_check(struct omap_overlay *ovl,
222 const struct omap_overlay_info *info); 234 const struct omap_overlay_info *info);
223int dss_ovl_check(struct omap_overlay *ovl, 235int 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 */
227int dss_init_platform_driver(void); 239int dss_init_platform_driver(void) __init;
228void dss_uninit_platform_driver(void); 240void dss_uninit_platform_driver(void);
229 241
230int dss_runtime_get(void);
231void dss_runtime_put(void);
232
233void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 242void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
234enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); 243enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
235const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 244const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
236void dss_dump_clocks(struct seq_file *s); 245void dss_dump_clocks(struct seq_file *s);
237 246
238void 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)
240void dss_debug_dump_clocks(struct seq_file *s); 248void 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 276int sdi_init_platform_driver(void) __init;
269int sdi_init(void); 277void sdi_uninit_platform_driver(void) __exit;
270void sdi_exit(void);
271int sdi_init_display(struct omap_dss_device *display);
272#else
273static inline int sdi_init(void)
274{
275 return 0;
276}
277static 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)
285struct dentry; 282struct dentry;
286struct file_operations; 283struct file_operations;
287 284
288int dsi_init_platform_driver(void); 285int dsi_init_platform_driver(void) __init;
289void dsi_uninit_platform_driver(void); 286void dsi_uninit_platform_driver(void) __exit;
290 287
291int dsi_runtime_get(struct platform_device *dsidev); 288int dsi_runtime_get(struct platform_device *dsidev);
292void dsi_runtime_put(struct platform_device *dsidev); 289void dsi_runtime_put(struct platform_device *dsidev);
293 290
294void dsi_dump_clocks(struct seq_file *s); 291void dsi_dump_clocks(struct seq_file *s);
295void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir,
296 const struct file_operations *debug_fops);
297void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
298 const struct file_operations *debug_fops);
299 292
300int dsi_init_display(struct omap_dss_device *display);
301void dsi_irq_handler(void); 293void dsi_irq_handler(void);
302u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); 294u8 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);
314void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); 306void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
315struct platform_device *dsi_get_dsidev_from_id(int module); 307struct platform_device *dsi_get_dsidev_from_id(int module);
316#else 308#else
317static inline int dsi_init_platform_driver(void)
318{
319 return 0;
320}
321static inline void dsi_uninit_platform_driver(void)
322{
323}
324static inline int dsi_runtime_get(struct platform_device *dsidev) 309static 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 365int dpi_init_platform_driver(void) __init;
381int dpi_init(void); 366void dpi_uninit_platform_driver(void) __exit;
382void dpi_exit(void);
383int dpi_init_display(struct omap_dss_device *dssdev);
384#else
385static inline int dpi_init(void)
386{
387 return 0;
388}
389static inline void dpi_exit(void)
390{
391}
392#endif
393 367
394/* DISPC */ 368/* DISPC */
395int dispc_init_platform_driver(void); 369int dispc_init_platform_driver(void) __init;
396void dispc_uninit_platform_driver(void); 370void dispc_uninit_platform_driver(void) __exit;
397void dispc_dump_clocks(struct seq_file *s); 371void dispc_dump_clocks(struct seq_file *s);
398void dispc_dump_irqs(struct seq_file *s);
399void dispc_dump_regs(struct seq_file *s);
400void dispc_irq_handler(void); 372void dispc_irq_handler(void);
401void dispc_fake_vsync_irq(void);
402 373
403int dispc_runtime_get(void); 374int dispc_runtime_get(void);
404void dispc_runtime_put(void); 375void dispc_runtime_put(void);
@@ -409,12 +380,12 @@ void dispc_disable_sidle(void);
409void dispc_lcd_enable_signal_polarity(bool act_high); 380void dispc_lcd_enable_signal_polarity(bool act_high);
410void dispc_lcd_enable_signal(bool enable); 381void dispc_lcd_enable_signal(bool enable);
411void dispc_pck_free_enable(bool enable); 382void dispc_pck_free_enable(bool enable);
412void dispc_set_digit_size(u16 width, u16 height);
413void dispc_enable_fifomerge(bool enable); 383void dispc_enable_fifomerge(bool enable);
414void dispc_enable_gamma_table(bool enable); 384void dispc_enable_gamma_table(bool enable);
415void dispc_set_loadmode(enum omap_dss_load_mode mode); 385void dispc_set_loadmode(enum omap_dss_load_mode mode);
416 386
417bool dispc_lcd_timings_ok(struct omap_video_timings *timings); 387bool dispc_mgr_timings_ok(enum omap_channel channel,
388 const struct omap_video_timings *timings);
418unsigned long dispc_fclk_rate(void); 389unsigned long dispc_fclk_rate(void);
419void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 390void 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
425void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); 396void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
426void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, 397void 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);
428int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 400int 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);
430int dispc_ovl_enable(enum omap_plane plane, bool enable); 403int dispc_ovl_enable(enum omap_plane plane, bool enable);
431void dispc_ovl_set_channel_out(enum omap_plane plane, 404void dispc_ovl_set_channel_out(enum omap_plane plane,
432 enum omap_channel channel); 405 enum omap_channel channel);
433 406
434void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable); 407void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
435void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
436u32 dispc_mgr_get_vsync_irq(enum omap_channel channel); 408u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
437u32 dispc_mgr_get_framedone_irq(enum omap_channel channel); 409u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
438bool dispc_mgr_go_busy(enum omap_channel channel); 410bool dispc_mgr_go_busy(enum omap_channel channel);
@@ -445,12 +417,13 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
445void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); 417void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
446void dispc_mgr_set_lcd_display_type(enum omap_channel channel, 418void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
447 enum omap_lcd_display_type type); 419 enum omap_lcd_display_type type);
448void dispc_mgr_set_lcd_timings(enum omap_channel channel, 420void dispc_mgr_set_timings(enum omap_channel channel,
449 struct omap_video_timings *timings); 421 struct omap_video_timings *timings);
450void dispc_mgr_set_pol_freq(enum omap_channel channel, 422void 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);
452unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); 424unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
453unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); 425unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
426unsigned long dispc_core_clk_rate(void);
454int dispc_mgr_set_clock_div(enum omap_channel channel, 427int dispc_mgr_set_clock_div(enum omap_channel channel,
455 struct dispc_clock_info *cinfo); 428 struct dispc_clock_info *cinfo);
456int dispc_mgr_get_clock_div(enum omap_channel channel, 429int 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
463int venc_init_platform_driver(void); 436int venc_init_platform_driver(void) __init;
464void venc_uninit_platform_driver(void); 437void venc_uninit_platform_driver(void) __exit;
465void venc_dump_regs(struct seq_file *s);
466int venc_init_display(struct omap_dss_device *display);
467unsigned long venc_get_pixel_clock(void); 438unsigned long venc_get_pixel_clock(void);
468#else 439#else
469static inline int venc_init_platform_driver(void)
470{
471 return 0;
472}
473static inline void venc_uninit_platform_driver(void)
474{
475}
476static inline unsigned long venc_get_pixel_clock(void) 440static 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
485int hdmi_init_platform_driver(void); 449int hdmi_init_platform_driver(void) __init;
486void hdmi_uninit_platform_driver(void); 450void hdmi_uninit_platform_driver(void) __exit;
487int hdmi_init_display(struct omap_dss_device *dssdev);
488unsigned long hdmi_get_pixel_clock(void); 451unsigned long hdmi_get_pixel_clock(void);
489void hdmi_dump_regs(struct seq_file *s);
490#else 452#else
491static inline int hdmi_init_display(struct omap_dss_device *dssdev)
492{
493 return 0;
494}
495static inline int hdmi_init_platform_driver(void)
496{
497 return 0;
498}
499static inline void hdmi_uninit_platform_driver(void)
500{
501}
502static inline unsigned long hdmi_get_pixel_clock(void) 453static 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);
514bool omapdss_hdmi_detect(void); 465bool omapdss_hdmi_detect(void);
515int hdmi_panel_init(void); 466int hdmi_panel_init(void);
516void hdmi_panel_exit(void); 467void hdmi_panel_exit(void);
468#ifdef CONFIG_OMAP4_DSS_HDMI_AUDIO
469int hdmi_audio_enable(void);
470void hdmi_audio_disable(void);
471int hdmi_audio_start(void);
472void hdmi_audio_stop(void);
473bool hdmi_mode_has_audio(void);
474int hdmi_audio_config(struct omap_dss_audio *audio);
475#endif
517 476
518/* RFBI */ 477/* RFBI */
519#ifdef CONFIG_OMAP2_DSS_RFBI 478int rfbi_init_platform_driver(void) __init;
520int rfbi_init_platform_driver(void); 479void rfbi_uninit_platform_driver(void) __exit;
521void rfbi_uninit_platform_driver(void);
522void rfbi_dump_regs(struct seq_file *s);
523int rfbi_init_display(struct omap_dss_device *display);
524#else
525static inline int rfbi_init_platform_driver(void)
526{
527 return 0;
528}
529static 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
316static const struct dss_param_range omap3_dss_param_range[] = { 320static 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
329static const struct dss_param_range omap4_dss_param_range[] = { 335static 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
342static const enum dss_feat_id omap2_dss_feat_list[] = { 350static 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
404static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = { 413static 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
421static const enum dss_feat_id omap4_dss_feat_list[] = { 431static 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
686bool 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
665void dss_features_init(void) 691void 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);
108u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ 111u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
109u32 dss_feat_get_burst_size_unit(void); /* in bytes */ 112u32 dss_feat_get_burst_size_unit(void); /* in bytes */
110 113
114bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type);
115
111bool dss_has_feature(enum dss_feat_id id); 116bool dss_has_feature(enum dss_feat_id id);
112void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 117void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
113void dss_features_init(void); 118void 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
64static struct { 58static 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
148err_get_hdmi:
149 dss_runtime_put();
150err_get_dss:
151 return r;
152} 132}
153 133
154static void hdmi_runtime_put(void) 134static 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
170int hdmi_init_display(struct omap_dss_device *dssdev) 144static 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
390err_mgr_enable: 365err_mgr_enable:
391 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); 366 hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
367err_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);
394err: 370err:
@@ -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
442void hdmi_dump_regs(struct seq_file *s) 420static 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) || \ 536static int hdmi_get_clocks(struct platform_device *pdev)
559 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
560
561static 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; 551static 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; 558int 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;
592static 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); 658int 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) 665void 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
730static int hdmi_audio_startup(struct snd_pcm_substream *substream, 672int 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
740static int hdmi_audio_codec_probe(struct snd_soc_codec *codec) 679void 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
748static struct snd_soc_codec_driver hdmi_audio_codec_drv = { 686bool 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
752static struct snd_soc_dai_ops hdmi_audio_codec_ops = { 694int 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
758static 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
772static int hdmi_get_clocks(struct platform_device *pdev) 701static 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
787static 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 */
794static int omapdss_hdmihw_probe(struct platform_device *pdev) 726static 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
847static int omapdss_hdmihw_remove(struct platform_device *pdev) 771static 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
892err_get_dispc:
893 dss_runtime_put();
894err_get_dss:
895 return r;
896} 806}
897 807
898static const struct dev_pm_ops hdmi_pm_ops = { 808static 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
903static struct platform_driver omapdss_hdmihw_driver = { 813static 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
913int hdmi_init_platform_driver(void) 822int __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
918void hdmi_uninit_platform_driver(void) 827void __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
32static struct { 32static 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)
63static 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
84err:
85 spin_unlock_irqrestore(&hdmi.audio_lock, flags);
86 mutex_unlock(&hdmi.lock);
87 return r;
88}
89
90static 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
103static 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
124err:
125 spin_unlock_irqrestore(&hdmi.audio_lock, flags);
126 return r;
127}
128
129static 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
141static 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;
154err:
155 mutex_unlock(&hdmi.lock);
156 return r;
157}
158
159static 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
181err:
182 spin_unlock_irqrestore(&hdmi.audio_lock, flags);
183 mutex_unlock(&hdmi.lock);
184 return r;
185}
186
187#else
188static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev)
189{
190 return -EPERM;
191}
192
193static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev)
194{
195}
196
197static int hdmi_panel_audio_start(struct omap_dss_device *dssdev)
198{
199 return -EPERM;
200}
201
202static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev)
203{
204}
205
206static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev)
207{
208 return false;
209}
210
211static int hdmi_panel_audio_config(struct omap_dss_device *dssdev,
212 struct omap_dss_audio *audio)
213{
214 return -EPERM;
215}
216#endif
217
57static int hdmi_panel_enable(struct omap_dss_device *dssdev) 218static 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
77err: 238err:
78 mutex_unlock(&hdmi.hdmi_lock); 239 mutex_unlock(&hdmi.lock);
79 240
80 return r; 241 return r;
81} 242}
82 243
83static void hdmi_panel_disable(struct omap_dss_device *dssdev) 244static 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
95static int hdmi_panel_suspend(struct omap_dss_device *dssdev) 263static 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
110err: 283err:
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
135err: 309err:
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:
141static void hdmi_get_timings(struct omap_dss_device *dssdev, 315static 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
151static void hdmi_set_timings(struct omap_dss_device *dssdev, 325static 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
164static int hdmi_check_timings(struct omap_dss_device *dssdev, 344static 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);
196err: 376err:
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);
219err: 399err:
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
243int hdmi_panel_init(void) 429int 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
657int 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
657int dss_mgr_check(struct omap_overlay_manager *mgr, 668int 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
634int dss_ovl_check(struct omap_overlay *ovl, 640int 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}
800EXPORT_SYMBOL(omap_rfbi_update); 820EXPORT_SYMBOL(omap_rfbi_update);
801 821
802void rfbi_dump_regs(struct seq_file *s) 822static 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}
901EXPORT_SYMBOL(omapdss_rfbi_display_disable); 921EXPORT_SYMBOL(omapdss_rfbi_display_disable);
902 922
903int rfbi_init_display(struct omap_dss_device *dssdev) 923static 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
930static 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 */
911static int omap_rfbihw_probe(struct platform_device *pdev) 955static 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
961err_runtime_get: 1009err_runtime_get:
@@ -963,8 +1011,9 @@ err_runtime_get:
963 return r; 1011 return r;
964} 1012}
965 1013
966static int omap_rfbihw_remove(struct platform_device *pdev) 1014static 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)
972static int rfbi_runtime_suspend(struct device *dev) 1021static 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
994err_get_dispc:
995 dss_runtime_put();
996err_get_dss:
997 return r;
998} 1037}
999 1038
1000static const struct dev_pm_ops rfbi_pm_ops = { 1039static 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
1005static struct platform_driver omap_rfbihw_driver = { 1044static 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
1015int rfbi_init_platform_driver(void) 1053int __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
1020void rfbi_uninit_platform_driver(void) 1058void __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:
137err_calc_clock_div: 134err_calc_clock_div:
138 dispc_runtime_put(); 135 dispc_runtime_put();
139err_get_dispc: 136err_get_dispc:
140 dss_runtime_put();
141err_get_dss:
142 regulator_disable(sdi.vdds_sdi_reg); 137 regulator_disable(sdi.vdds_sdi_reg);
143err_reg_enable: 138err_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}
163EXPORT_SYMBOL(omapdss_sdi_display_disable); 157EXPORT_SYMBOL(omapdss_sdi_display_disable);
164 158
165int sdi_init_display(struct omap_dss_device *dssdev) 159static 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
185int sdi_init(void) 179static 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
203static int __init omap_sdi_probe(struct platform_device *pdev)
186{ 204{
205 sdi_probe_pdata(pdev);
206
207 return 0;
208}
209
210static 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
190void sdi_exit(void) 217static 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
225int __init sdi_init_platform_driver(void)
226{
227 return platform_driver_probe(&omap_sdi_driver, omap_sdi_probe);
228}
229
230void __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);
173void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); 183void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
174int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); 184int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
175bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data); 185bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data);
176void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start); 186int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data);
187void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data);
177int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); 188int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
178void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data); 189void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data);
179void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); 190void 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);
181void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); 192void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
182void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); 193void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
183void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); 194void 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) 196int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts);
186void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable); 197int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data);
198void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data);
199int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data);
200void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data);
201int 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
36static inline void hdmi_write_reg(void __iomem *base_addr, 41static 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
702void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start) 707int 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
713void 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
707static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, 718static 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
1008void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) 1017void 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) 1029static void ti_hdmi_4xxx_wp_audio_config_format(struct hdmi_ip_data *ip_data,
1021void 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
1040void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, 1048static 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
1058void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, 1066static 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
1143void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, 1165static 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
1195int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, 1215int 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
1252void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable) 1394int 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
1401void 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
1407int 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
1416void 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
318enum hdmi_packing_mode { 279enum 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
325enum 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
336enum hdmi_core_audio_layout { 286enum 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
389enum hdmi_audio_i2s_config { 339enum 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 */
453struct 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
463struct hdmi_core_packet_enable_repeat { 374struct 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
498struct hdmi_core_audio_i2s_config { 409struct 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
513struct hdmi_core_audio_config { 419struct 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)
532int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
533 u32 sample_freq, u32 *n, u32 *cts);
534void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data,
535 struct hdmi_core_infoframe_audio *info_aud);
536void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
537 struct hdmi_core_audio_config *cfg);
538void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data,
539 struct hdmi_audio_dma *aud_dma);
540void 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
420static int venc_power_on(struct omap_dss_device *dssdev) 421static 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
490static 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
510static 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
538static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
539 display_output_type_show, display_output_type_store);
540
488/* driver */ 541/* driver */
489static int venc_panel_probe(struct omap_dss_device *dssdev) 542static 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
496static void venc_panel_remove(struct omap_dss_device *dssdev) 549static 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
500static int venc_panel_enable(struct omap_dss_device *dssdev) 554static 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
580static void venc_get_timings(struct omap_dss_device *dssdev,
581 struct omap_video_timings *timings)
582{
583 *timings = dssdev->panel.timings;
584}
585
586static void venc_set_timings(struct omap_dss_device *dssdev, 634static 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
678int venc_init_display(struct omap_dss_device *dssdev) 727static 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
698void venc_dump_regs(struct seq_file *s) 747static 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
831static 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 */
783static int omap_venchw_probe(struct platform_device *pdev) 856static 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
829err_reg_panel_driver: 906err_reg_panel_driver:
@@ -833,12 +910,15 @@ err_runtime_get:
833 return r; 910 return r;
834} 911}
835 912
836static int omap_venchw_remove(struct platform_device *pdev) 913static 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
878err_get_dispc:
879 dss_runtime_put();
880err_get_dss:
881 return r;
882} 952}
883 953
884static const struct dev_pm_ops venc_pm_ops = { 954static 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
889static struct platform_driver omap_venchw_driver = { 959static 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
899int venc_init_platform_driver(void) 968int __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
907void venc_uninit_platform_driver(void) 976void __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
2310static int omapfb_probe(struct platform_device *pdev) 2311static 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
2451static int omapfb_remove(struct platform_device *pdev) 2452static 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
2464static struct platform_driver omapfb_driver = { 2465static 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
171static inline void omapfb_lock(struct omapfb2_device *fbdev) 172static 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);