aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss')
-rw-r--r--drivers/video/omap2/dss/Kconfig26
-rw-r--r--drivers/video/omap2/dss/core.c117
-rw-r--r--drivers/video/omap2/dss/dispc.c42
-rw-r--r--drivers/video/omap2/dss/display.c119
-rw-r--r--drivers/video/omap2/dss/dpi.c144
-rw-r--r--drivers/video/omap2/dss/dsi.c1031
-rw-r--r--drivers/video/omap2/dss/dss.c42
-rw-r--r--drivers/video/omap2/dss/dss.h23
-rw-r--r--drivers/video/omap2/dss/manager.c48
-rw-r--r--drivers/video/omap2/dss/overlay.c2
-rw-r--r--drivers/video/omap2/dss/rfbi.c321
-rw-r--r--drivers/video/omap2/dss/sdi.c115
-rw-r--r--drivers/video/omap2/dss/venc.c296
13 files changed, 729 insertions, 1597 deletions
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index c63ce767b277..87afb81b2c44 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -30,19 +30,29 @@ config OMAP2_DSS_COLLECT_IRQ_STATS
30 depends on OMAP2_DSS_DEBUG_SUPPORT 30 depends on OMAP2_DSS_DEBUG_SUPPORT
31 default n 31 default n
32 help 32 help
33 Collect DSS IRQ statistics, printable via debugfs 33 Collect DSS IRQ statistics, printable via debugfs.
34
35 The statistics can be found from
36 <debugfs>/omapdss/dispc_irq for DISPC interrupts, and
37 <debugfs>/omapdss/dsi_irq for DSI interrupts.
34 38
35config OMAP2_DSS_RFBI 39config OMAP2_DSS_RFBI
36 bool "RFBI support" 40 bool "RFBI support"
37 default n 41 default n
38 help 42 help
39 MIPI DBI, or RFBI (Remote Framebuffer Interface), support. 43 MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas
44 Instrument's terminology).
45
46 DBI is a bus between the host processor and a peripheral,
47 such as a display or a framebuffer chip.
48
49 See http://www.mipi.org/ for DBI spesifications.
40 50
41config OMAP2_DSS_VENC 51config OMAP2_DSS_VENC
42 bool "VENC support" 52 bool "VENC support"
43 default y 53 default y
44 help 54 help
45 OMAP Video Encoder support. 55 OMAP Video Encoder support for S-Video and composite TV-out.
46 56
47config OMAP2_DSS_SDI 57config OMAP2_DSS_SDI
48 bool "SDI support" 58 bool "SDI support"
@@ -51,12 +61,20 @@ config OMAP2_DSS_SDI
51 help 61 help
52 SDI (Serial Display Interface) support. 62 SDI (Serial Display Interface) support.
53 63
64 SDI is a high speed one-way display serial bus between the host
65 processor and a display.
66
54config OMAP2_DSS_DSI 67config OMAP2_DSS_DSI
55 bool "DSI support" 68 bool "DSI support"
56 depends on ARCH_OMAP3 69 depends on ARCH_OMAP3
57 default n 70 default n
58 help 71 help
59 MIPI DSI support. 72 MIPI DSI (Display Serial Interface) support.
73
74 DSI is a high speed half-duplex serial interface between the host
75 processor and a peripheral, such as a display or a framebuffer chip.
76
77 See http://www.mipi.org/ for DSI spesifications.
60 78
61config OMAP2_DSS_USE_DSI_PLL 79config OMAP2_DSS_USE_DSI_PLL
62 bool "Use DSI PLL for PCLK (EXPERIMENTAL)" 80 bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 82918eec6d2e..7ebe50b335ed 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -31,6 +31,7 @@
31#include <linux/debugfs.h> 31#include <linux/debugfs.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/regulator/consumer.h>
34 35
35#include <plat/display.h> 36#include <plat/display.h>
36#include <plat/clock.h> 37#include <plat/clock.h>
@@ -47,6 +48,10 @@ static struct {
47 struct clk *dss_54m_fck; 48 struct clk *dss_54m_fck;
48 struct clk *dss_96m_fck; 49 struct clk *dss_96m_fck;
49 unsigned num_clks_enabled; 50 unsigned num_clks_enabled;
51
52 struct regulator *vdds_dsi_reg;
53 struct regulator *vdds_sdi_reg;
54 struct regulator *vdda_dac_reg;
50} core; 55} core;
51 56
52static void dss_clk_enable_all_no_ctx(void); 57static void dss_clk_enable_all_no_ctx(void);
@@ -284,9 +289,11 @@ static void dss_clk_enable_no_ctx(enum dss_clock clks)
284 289
285void dss_clk_enable(enum dss_clock clks) 290void dss_clk_enable(enum dss_clock clks)
286{ 291{
292 bool check_ctx = core.num_clks_enabled == 0;
293
287 dss_clk_enable_no_ctx(clks); 294 dss_clk_enable_no_ctx(clks);
288 295
289 if (cpu_is_omap34xx() && dss_need_ctx_restore()) 296 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
290 restore_all_ctx(); 297 restore_all_ctx();
291} 298}
292 299
@@ -352,6 +359,50 @@ static void dss_clk_disable_all(void)
352 dss_clk_disable(clks); 359 dss_clk_disable(clks);
353} 360}
354 361
362/* REGULATORS */
363
364struct regulator *dss_get_vdds_dsi(void)
365{
366 struct regulator *reg;
367
368 if (core.vdds_dsi_reg != NULL)
369 return core.vdds_dsi_reg;
370
371 reg = regulator_get(&core.pdev->dev, "vdds_dsi");
372 if (!IS_ERR(reg))
373 core.vdds_dsi_reg = reg;
374
375 return reg;
376}
377
378struct regulator *dss_get_vdds_sdi(void)
379{
380 struct regulator *reg;
381
382 if (core.vdds_sdi_reg != NULL)
383 return core.vdds_sdi_reg;
384
385 reg = regulator_get(&core.pdev->dev, "vdds_sdi");
386 if (!IS_ERR(reg))
387 core.vdds_sdi_reg = reg;
388
389 return reg;
390}
391
392struct regulator *dss_get_vdda_dac(void)
393{
394 struct regulator *reg;
395
396 if (core.vdda_dac_reg != NULL)
397 return core.vdda_dac_reg;
398
399 reg = regulator_get(&core.pdev->dev, "vdda_dac");
400 if (!IS_ERR(reg))
401 core.vdda_dac_reg = reg;
402
403 return reg;
404}
405
355/* DEBUGFS */ 406/* DEBUGFS */
356#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 407#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
357static void dss_debug_dump_clocks(struct seq_file *s) 408static void dss_debug_dump_clocks(struct seq_file *s)
@@ -397,10 +448,12 @@ static int dss_initialize_debugfs(void)
397 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, 448 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
398 &dss_debug_dump_clocks, &dss_debug_fops); 449 &dss_debug_dump_clocks, &dss_debug_fops);
399 450
451#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
400 debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, 452 debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir,
401 &dispc_dump_irqs, &dss_debug_fops); 453 &dispc_dump_irqs, &dss_debug_fops);
454#endif
402 455
403#ifdef CONFIG_OMAP2_DSS_DSI 456#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
404 debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, 457 debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir,
405 &dsi_dump_irqs, &dss_debug_fops); 458 &dsi_dump_irqs, &dss_debug_fops);
406#endif 459#endif
@@ -473,7 +526,7 @@ static int omap_dss_probe(struct platform_device *pdev)
473 } 526 }
474#endif 527#endif
475 528
476 r = dpi_init(); 529 r = dpi_init(pdev);
477 if (r) { 530 if (r) {
478 DSSERR("Failed to initialize dpi\n"); 531 DSSERR("Failed to initialize dpi\n");
479 goto fail0; 532 goto fail0;
@@ -718,16 +771,14 @@ static int dss_driver_probe(struct device *dev)
718 771
719 dss_init_device(core.pdev, dssdev); 772 dss_init_device(core.pdev, dssdev);
720 773
721 /* skip this if the device is behind a ctrl */ 774 force = pdata->default_device == dssdev;
722 if (!dssdev->panel.ctrl) { 775 dss_recheck_connections(dssdev, force);
723 force = pdata->default_device == dssdev;
724 dss_recheck_connections(dssdev, force);
725 }
726 776
727 r = dssdrv->probe(dssdev); 777 r = dssdrv->probe(dssdev);
728 778
729 if (r) { 779 if (r) {
730 DSSERR("driver probe failed: %d\n", r); 780 DSSERR("driver probe failed: %d\n", r);
781 dss_uninit_device(core.pdev, dssdev);
731 return r; 782 return r;
732 } 783 }
733 784
@@ -760,6 +811,13 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
760 dssdriver->driver.bus = &dss_bus_type; 811 dssdriver->driver.bus = &dss_bus_type;
761 dssdriver->driver.probe = dss_driver_probe; 812 dssdriver->driver.probe = dss_driver_probe;
762 dssdriver->driver.remove = dss_driver_remove; 813 dssdriver->driver.remove = dss_driver_remove;
814
815 if (dssdriver->get_resolution == NULL)
816 dssdriver->get_resolution = omapdss_default_get_resolution;
817 if (dssdriver->get_recommended_bpp == NULL)
818 dssdriver->get_recommended_bpp =
819 omapdss_default_get_recommended_bpp;
820
763 return driver_register(&dssdriver->driver); 821 return driver_register(&dssdriver->driver);
764} 822}
765EXPORT_SYMBOL(omap_dss_register_driver); 823EXPORT_SYMBOL(omap_dss_register_driver);
@@ -808,8 +866,6 @@ static void omap_dss_dev_release(struct device *dev)
808int omap_dss_register_device(struct omap_dss_device *dssdev) 866int omap_dss_register_device(struct omap_dss_device *dssdev)
809{ 867{
810 static int dev_num; 868 static int dev_num;
811 static int panel_num;
812 int r;
813 869
814 WARN_ON(!dssdev->driver_name); 870 WARN_ON(!dssdev->driver_name);
815 871
@@ -818,36 +874,12 @@ int omap_dss_register_device(struct omap_dss_device *dssdev)
818 dssdev->dev.parent = &dss_bus; 874 dssdev->dev.parent = &dss_bus;
819 dssdev->dev.release = omap_dss_dev_release; 875 dssdev->dev.release = omap_dss_dev_release;
820 dev_set_name(&dssdev->dev, "display%d", dev_num++); 876 dev_set_name(&dssdev->dev, "display%d", dev_num++);
821 r = device_register(&dssdev->dev); 877 return device_register(&dssdev->dev);
822 if (r)
823 return r;
824
825 if (dssdev->ctrl.panel) {
826 struct omap_dss_device *panel = dssdev->ctrl.panel;
827
828 panel->panel.ctrl = dssdev;
829
830 reset_device(&panel->dev, 1);
831 panel->dev.bus = &dss_bus_type;
832 panel->dev.parent = &dssdev->dev;
833 panel->dev.release = omap_dss_dev_release;
834 dev_set_name(&panel->dev, "panel%d", panel_num++);
835 r = device_register(&panel->dev);
836 if (r)
837 return r;
838 }
839
840 return 0;
841} 878}
842 879
843void omap_dss_unregister_device(struct omap_dss_device *dssdev) 880void omap_dss_unregister_device(struct omap_dss_device *dssdev)
844{ 881{
845 device_unregister(&dssdev->dev); 882 device_unregister(&dssdev->dev);
846
847 if (dssdev->ctrl.panel) {
848 struct omap_dss_device *panel = dssdev->ctrl.panel;
849 device_unregister(&panel->dev);
850 }
851} 883}
852 884
853/* BUS */ 885/* BUS */
@@ -901,6 +933,21 @@ static int __init omap_dss_init(void)
901 933
902static void __exit omap_dss_exit(void) 934static void __exit omap_dss_exit(void)
903{ 935{
936 if (core.vdds_dsi_reg != NULL) {
937 regulator_put(core.vdds_dsi_reg);
938 core.vdds_dsi_reg = NULL;
939 }
940
941 if (core.vdds_sdi_reg != NULL) {
942 regulator_put(core.vdds_sdi_reg);
943 core.vdds_sdi_reg = NULL;
944 }
945
946 if (core.vdda_dac_reg != NULL) {
947 regulator_put(core.vdda_dac_reg);
948 core.vdda_dac_reg = NULL;
949 }
950
904 platform_driver_unregister(&omap_dss_driver); 951 platform_driver_unregister(&omap_dss_driver);
905 952
906 omap_dss_bus_unregister(); 953 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index de8bfbac9e26..e777e352dbcd 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1725,7 +1725,7 @@ static void _enable_lcd_out(bool enable)
1725 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); 1725 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
1726} 1726}
1727 1727
1728void dispc_enable_lcd_out(bool enable) 1728static void dispc_enable_lcd_out(bool enable)
1729{ 1729{
1730 struct completion frame_done_completion; 1730 struct completion frame_done_completion;
1731 bool is_on; 1731 bool is_on;
@@ -1772,7 +1772,7 @@ static void _enable_digit_out(bool enable)
1772 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1); 1772 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
1773} 1773}
1774 1774
1775void dispc_enable_digit_out(bool enable) 1775static void dispc_enable_digit_out(bool enable)
1776{ 1776{
1777 struct completion frame_done_completion; 1777 struct completion frame_done_completion;
1778 int r; 1778 int r;
@@ -1836,6 +1836,26 @@ void dispc_enable_digit_out(bool enable)
1836 enable_clocks(0); 1836 enable_clocks(0);
1837} 1837}
1838 1838
1839bool dispc_is_channel_enabled(enum omap_channel channel)
1840{
1841 if (channel == OMAP_DSS_CHANNEL_LCD)
1842 return !!REG_GET(DISPC_CONTROL, 0, 0);
1843 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1844 return !!REG_GET(DISPC_CONTROL, 1, 1);
1845 else
1846 BUG();
1847}
1848
1849void dispc_enable_channel(enum omap_channel channel, bool enable)
1850{
1851 if (channel == OMAP_DSS_CHANNEL_LCD)
1852 dispc_enable_lcd_out(enable);
1853 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1854 dispc_enable_digit_out(enable);
1855 else
1856 BUG();
1857}
1858
1839void dispc_lcd_enable_signal_polarity(bool act_high) 1859void dispc_lcd_enable_signal_polarity(bool act_high)
1840{ 1860{
1841 enable_clocks(1); 1861 enable_clocks(1);
@@ -2198,7 +2218,7 @@ unsigned long dispc_fclk_rate(void)
2198{ 2218{
2199 unsigned long r = 0; 2219 unsigned long r = 0;
2200 2220
2201 if (dss_get_dispc_clk_source() == 0) 2221 if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK)
2202 r = dss_clk_get_rate(DSS_CLK_FCK1); 2222 r = dss_clk_get_rate(DSS_CLK_FCK1);
2203 else 2223 else
2204#ifdef CONFIG_OMAP2_DSS_DSI 2224#ifdef CONFIG_OMAP2_DSS_DSI
@@ -2251,7 +2271,7 @@ void dispc_dump_clocks(struct seq_file *s)
2251 seq_printf(s, "- DISPC -\n"); 2271 seq_printf(s, "- DISPC -\n");
2252 2272
2253 seq_printf(s, "dispc fclk source = %s\n", 2273 seq_printf(s, "dispc fclk source = %s\n",
2254 dss_get_dispc_clk_source() == 0 ? 2274 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
2255 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2275 "dss1_alwon_fclk" : "dsi1_pll_fclk");
2256 2276
2257 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2277 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
@@ -2301,8 +2321,6 @@ void dispc_dump_irqs(struct seq_file *s)
2301 PIS(WAKEUP); 2321 PIS(WAKEUP);
2302#undef PIS 2322#undef PIS
2303} 2323}
2304#else
2305void dispc_dump_irqs(struct seq_file *s) { }
2306#endif 2324#endif
2307 2325
2308void dispc_dump_regs(struct seq_file *s) 2326void dispc_dump_regs(struct seq_file *s)
@@ -2854,12 +2872,13 @@ static void dispc_error_worker(struct work_struct *work)
2854 manager = mgr; 2872 manager = mgr;
2855 enable = mgr->device->state == 2873 enable = mgr->device->state ==
2856 OMAP_DSS_DISPLAY_ACTIVE; 2874 OMAP_DSS_DISPLAY_ACTIVE;
2857 mgr->device->disable(mgr->device); 2875 mgr->device->driver->disable(mgr->device);
2858 break; 2876 break;
2859 } 2877 }
2860 } 2878 }
2861 2879
2862 if (manager) { 2880 if (manager) {
2881 struct omap_dss_device *dssdev = manager->device;
2863 for (i = 0; i < omap_dss_get_num_overlays(); ++i) { 2882 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
2864 struct omap_overlay *ovl; 2883 struct omap_overlay *ovl;
2865 ovl = omap_dss_get_overlay(i); 2884 ovl = omap_dss_get_overlay(i);
@@ -2874,7 +2893,7 @@ static void dispc_error_worker(struct work_struct *work)
2874 dispc_go(manager->id); 2893 dispc_go(manager->id);
2875 mdelay(50); 2894 mdelay(50);
2876 if (enable) 2895 if (enable)
2877 manager->device->enable(manager->device); 2896 dssdev->driver->enable(dssdev);
2878 } 2897 }
2879 } 2898 }
2880 2899
@@ -2892,12 +2911,13 @@ static void dispc_error_worker(struct work_struct *work)
2892 manager = mgr; 2911 manager = mgr;
2893 enable = mgr->device->state == 2912 enable = mgr->device->state ==
2894 OMAP_DSS_DISPLAY_ACTIVE; 2913 OMAP_DSS_DISPLAY_ACTIVE;
2895 mgr->device->disable(mgr->device); 2914 mgr->device->driver->disable(mgr->device);
2896 break; 2915 break;
2897 } 2916 }
2898 } 2917 }
2899 2918
2900 if (manager) { 2919 if (manager) {
2920 struct omap_dss_device *dssdev = manager->device;
2901 for (i = 0; i < omap_dss_get_num_overlays(); ++i) { 2921 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
2902 struct omap_overlay *ovl; 2922 struct omap_overlay *ovl;
2903 ovl = omap_dss_get_overlay(i); 2923 ovl = omap_dss_get_overlay(i);
@@ -2912,7 +2932,7 @@ static void dispc_error_worker(struct work_struct *work)
2912 dispc_go(manager->id); 2932 dispc_go(manager->id);
2913 mdelay(50); 2933 mdelay(50);
2914 if (enable) 2934 if (enable)
2915 manager->device->enable(manager->device); 2935 dssdev->driver->enable(dssdev);
2916 } 2936 }
2917 } 2937 }
2918 2938
@@ -2923,7 +2943,7 @@ static void dispc_error_worker(struct work_struct *work)
2923 mgr = omap_dss_get_overlay_manager(i); 2943 mgr = omap_dss_get_overlay_manager(i);
2924 2944
2925 if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC) 2945 if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC)
2926 mgr->device->disable(mgr->device); 2946 mgr->device->driver->disable(mgr->device);
2927 } 2947 }
2928 } 2948 }
2929 2949
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 3b92b84b9560..6a74ea116d29 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -53,11 +53,11 @@ static ssize_t display_enabled_store(struct device *dev,
53 53
54 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { 54 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
55 if (enabled) { 55 if (enabled) {
56 r = dssdev->enable(dssdev); 56 r = dssdev->driver->enable(dssdev);
57 if (r) 57 if (r)
58 return r; 58 return r;
59 } else { 59 } else {
60 dssdev->disable(dssdev); 60 dssdev->driver->disable(dssdev);
61 } 61 }
62 } 62 }
63 63
@@ -69,8 +69,8 @@ static ssize_t display_upd_mode_show(struct device *dev,
69{ 69{
70 struct omap_dss_device *dssdev = to_dss_device(dev); 70 struct omap_dss_device *dssdev = to_dss_device(dev);
71 enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO; 71 enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
72 if (dssdev->get_update_mode) 72 if (dssdev->driver->get_update_mode)
73 mode = dssdev->get_update_mode(dssdev); 73 mode = dssdev->driver->get_update_mode(dssdev);
74 return snprintf(buf, PAGE_SIZE, "%d\n", mode); 74 return snprintf(buf, PAGE_SIZE, "%d\n", mode);
75} 75}
76 76
@@ -94,7 +94,7 @@ static ssize_t display_upd_mode_store(struct device *dev,
94 return -EINVAL; 94 return -EINVAL;
95 } 95 }
96 96
97 r = dssdev->set_update_mode(dssdev, mode); 97 r = dssdev->driver->set_update_mode(dssdev, mode);
98 if (r) 98 if (r)
99 return r; 99 return r;
100 100
@@ -106,7 +106,8 @@ static ssize_t display_tear_show(struct device *dev,
106{ 106{
107 struct omap_dss_device *dssdev = to_dss_device(dev); 107 struct omap_dss_device *dssdev = to_dss_device(dev);
108 return snprintf(buf, PAGE_SIZE, "%d\n", 108 return snprintf(buf, PAGE_SIZE, "%d\n",
109 dssdev->get_te ? dssdev->get_te(dssdev) : 0); 109 dssdev->driver->get_te ?
110 dssdev->driver->get_te(dssdev) : 0);
110} 111}
111 112
112static ssize_t display_tear_store(struct device *dev, 113static ssize_t display_tear_store(struct device *dev,
@@ -116,12 +117,12 @@ static ssize_t display_tear_store(struct device *dev,
116 unsigned long te; 117 unsigned long te;
117 int r; 118 int r;
118 119
119 if (!dssdev->enable_te || !dssdev->get_te) 120 if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
120 return -ENOENT; 121 return -ENOENT;
121 122
122 te = simple_strtoul(buf, NULL, 0); 123 te = simple_strtoul(buf, NULL, 0);
123 124
124 r = dssdev->enable_te(dssdev, te); 125 r = dssdev->driver->enable_te(dssdev, te);
125 if (r) 126 if (r)
126 return r; 127 return r;
127 128
@@ -134,10 +135,10 @@ static ssize_t display_timings_show(struct device *dev,
134 struct omap_dss_device *dssdev = to_dss_device(dev); 135 struct omap_dss_device *dssdev = to_dss_device(dev);
135 struct omap_video_timings t; 136 struct omap_video_timings t;
136 137
137 if (!dssdev->get_timings) 138 if (!dssdev->driver->get_timings)
138 return -ENOENT; 139 return -ENOENT;
139 140
140 dssdev->get_timings(dssdev, &t); 141 dssdev->driver->get_timings(dssdev, &t);
141 142
142 return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n", 143 return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
143 t.pixel_clock, 144 t.pixel_clock,
@@ -152,7 +153,7 @@ static ssize_t display_timings_store(struct device *dev,
152 struct omap_video_timings t; 153 struct omap_video_timings t;
153 int r, found; 154 int r, found;
154 155
155 if (!dssdev->set_timings || !dssdev->check_timings) 156 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
156 return -ENOENT; 157 return -ENOENT;
157 158
158 found = 0; 159 found = 0;
@@ -171,11 +172,11 @@ static ssize_t display_timings_store(struct device *dev,
171 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9) 172 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
172 return -EINVAL; 173 return -EINVAL;
173 174
174 r = dssdev->check_timings(dssdev, &t); 175 r = dssdev->driver->check_timings(dssdev, &t);
175 if (r) 176 if (r)
176 return r; 177 return r;
177 178
178 dssdev->set_timings(dssdev, &t); 179 dssdev->driver->set_timings(dssdev, &t);
179 180
180 return size; 181 return size;
181} 182}
@@ -185,9 +186,9 @@ static ssize_t display_rotate_show(struct device *dev,
185{ 186{
186 struct omap_dss_device *dssdev = to_dss_device(dev); 187 struct omap_dss_device *dssdev = to_dss_device(dev);
187 int rotate; 188 int rotate;
188 if (!dssdev->get_rotate) 189 if (!dssdev->driver->get_rotate)
189 return -ENOENT; 190 return -ENOENT;
190 rotate = dssdev->get_rotate(dssdev); 191 rotate = dssdev->driver->get_rotate(dssdev);
191 return snprintf(buf, PAGE_SIZE, "%u\n", rotate); 192 return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
192} 193}
193 194
@@ -198,12 +199,12 @@ static ssize_t display_rotate_store(struct device *dev,
198 unsigned long rot; 199 unsigned long rot;
199 int r; 200 int r;
200 201
201 if (!dssdev->set_rotate || !dssdev->get_rotate) 202 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
202 return -ENOENT; 203 return -ENOENT;
203 204
204 rot = simple_strtoul(buf, NULL, 0); 205 rot = simple_strtoul(buf, NULL, 0);
205 206
206 r = dssdev->set_rotate(dssdev, rot); 207 r = dssdev->driver->set_rotate(dssdev, rot);
207 if (r) 208 if (r)
208 return r; 209 return r;
209 210
@@ -215,9 +216,9 @@ static ssize_t display_mirror_show(struct device *dev,
215{ 216{
216 struct omap_dss_device *dssdev = to_dss_device(dev); 217 struct omap_dss_device *dssdev = to_dss_device(dev);
217 int mirror; 218 int mirror;
218 if (!dssdev->get_mirror) 219 if (!dssdev->driver->get_mirror)
219 return -ENOENT; 220 return -ENOENT;
220 mirror = dssdev->get_mirror(dssdev); 221 mirror = dssdev->driver->get_mirror(dssdev);
221 return snprintf(buf, PAGE_SIZE, "%u\n", mirror); 222 return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
222} 223}
223 224
@@ -228,12 +229,12 @@ static ssize_t display_mirror_store(struct device *dev,
228 unsigned long mirror; 229 unsigned long mirror;
229 int r; 230 int r;
230 231
231 if (!dssdev->set_mirror || !dssdev->get_mirror) 232 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
232 return -ENOENT; 233 return -ENOENT;
233 234
234 mirror = simple_strtoul(buf, NULL, 0); 235 mirror = simple_strtoul(buf, NULL, 0);
235 236
236 r = dssdev->set_mirror(dssdev, mirror); 237 r = dssdev->driver->set_mirror(dssdev, mirror);
237 if (r) 238 if (r)
238 return r; 239 return r;
239 240
@@ -246,10 +247,10 @@ static ssize_t display_wss_show(struct device *dev,
246 struct omap_dss_device *dssdev = to_dss_device(dev); 247 struct omap_dss_device *dssdev = to_dss_device(dev);
247 unsigned int wss; 248 unsigned int wss;
248 249
249 if (!dssdev->get_wss) 250 if (!dssdev->driver->get_wss)
250 return -ENOENT; 251 return -ENOENT;
251 252
252 wss = dssdev->get_wss(dssdev); 253 wss = dssdev->driver->get_wss(dssdev);
253 254
254 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss); 255 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
255} 256}
@@ -261,7 +262,7 @@ static ssize_t display_wss_store(struct device *dev,
261 unsigned long wss; 262 unsigned long wss;
262 int r; 263 int r;
263 264
264 if (!dssdev->get_wss || !dssdev->set_wss) 265 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
265 return -ENOENT; 266 return -ENOENT;
266 267
267 if (strict_strtoul(buf, 0, &wss)) 268 if (strict_strtoul(buf, 0, &wss))
@@ -270,7 +271,7 @@ static ssize_t display_wss_store(struct device *dev,
270 if (wss > 0xfffff) 271 if (wss > 0xfffff)
271 return -EINVAL; 272 return -EINVAL;
272 273
273 r = dssdev->set_wss(dssdev, wss); 274 r = dssdev->driver->set_wss(dssdev, wss);
274 if (r) 275 if (r)
275 return r; 276 return r;
276 277
@@ -303,12 +304,13 @@ static struct device_attribute *display_sysfs_attrs[] = {
303 NULL 304 NULL
304}; 305};
305 306
306static void default_get_resolution(struct omap_dss_device *dssdev, 307void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
307 u16 *xres, u16 *yres) 308 u16 *xres, u16 *yres)
308{ 309{
309 *xres = dssdev->panel.timings.x_res; 310 *xres = dssdev->panel.timings.x_res;
310 *yres = dssdev->panel.timings.y_res; 311 *yres = dssdev->panel.timings.y_res;
311} 312}
313EXPORT_SYMBOL(omapdss_default_get_resolution);
312 314
313void default_get_overlay_fifo_thresholds(enum omap_plane plane, 315void default_get_overlay_fifo_thresholds(enum omap_plane plane,
314 u32 fifo_size, enum omap_burst_size *burst_size, 316 u32 fifo_size, enum omap_burst_size *burst_size,
@@ -323,24 +325,8 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
323 *fifo_low = fifo_size - burst_size_bytes; 325 *fifo_low = fifo_size - burst_size_bytes;
324} 326}
325 327
326static int default_wait_vsync(struct omap_dss_device *dssdev) 328int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
327{ 329{
328 unsigned long timeout = msecs_to_jiffies(500);
329 u32 irq;
330
331 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
332 irq = DISPC_IRQ_EVSYNC_ODD;
333 else
334 irq = DISPC_IRQ_VSYNC;
335
336 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
337}
338
339static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
340{
341 if (dssdev->panel.recommended_bpp)
342 return dssdev->panel.recommended_bpp;
343
344 switch (dssdev->type) { 330 switch (dssdev->type) {
345 case OMAP_DISPLAY_TYPE_DPI: 331 case OMAP_DISPLAY_TYPE_DPI:
346 if (dssdev->phy.dpi.data_lines == 24) 332 if (dssdev->phy.dpi.data_lines == 24)
@@ -362,6 +348,7 @@ static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
362 BUG(); 348 BUG();
363 } 349 }
364} 350}
351EXPORT_SYMBOL(omapdss_default_get_recommended_bpp);
365 352
366/* Checks if replication logic should be used. Only use for active matrix, 353/* Checks if replication logic should be used. Only use for active matrix,
367 * when overlay is in RGB12U or RGB16 mode, and LCD interface is 354 * when overlay is in RGB12U or RGB16 mode, and LCD interface is
@@ -425,10 +412,6 @@ void dss_init_device(struct platform_device *pdev,
425 return; 412 return;
426 } 413 }
427 414
428 dssdev->get_resolution = default_get_resolution;
429 dssdev->get_recommended_bpp = default_get_recommended_bpp;
430 dssdev->wait_vsync = default_wait_vsync;
431
432 switch (dssdev->type) { 415 switch (dssdev->type) {
433 case OMAP_DISPLAY_TYPE_DPI: 416 case OMAP_DISPLAY_TYPE_DPI:
434 r = dpi_init_display(dssdev); 417 r = dpi_init_display(dssdev);
@@ -502,13 +485,13 @@ static int dss_suspend_device(struct device *dev, void *data)
502 return 0; 485 return 0;
503 } 486 }
504 487
505 if (!dssdev->suspend) { 488 if (!dssdev->driver->suspend) {
506 DSSERR("display '%s' doesn't implement suspend\n", 489 DSSERR("display '%s' doesn't implement suspend\n",
507 dssdev->name); 490 dssdev->name);
508 return -ENOSYS; 491 return -ENOSYS;
509 } 492 }
510 493
511 r = dssdev->suspend(dssdev); 494 r = dssdev->driver->suspend(dssdev);
512 if (r) 495 if (r)
513 return r; 496 return r;
514 497
@@ -537,8 +520,8 @@ static int dss_resume_device(struct device *dev, void *data)
537 int r; 520 int r;
538 struct omap_dss_device *dssdev = to_dss_device(dev); 521 struct omap_dss_device *dssdev = to_dss_device(dev);
539 522
540 if (dssdev->activate_after_resume && dssdev->resume) { 523 if (dssdev->activate_after_resume && dssdev->driver->resume) {
541 r = dssdev->resume(dssdev); 524 r = dssdev->driver->resume(dssdev);
542 if (r) 525 if (r)
543 return r; 526 return r;
544 } 527 }
@@ -558,7 +541,7 @@ int dss_resume_all_devices(void)
558static int dss_disable_device(struct device *dev, void *data) 541static int dss_disable_device(struct device *dev, void *data)
559{ 542{
560 struct omap_dss_device *dssdev = to_dss_device(dev); 543 struct omap_dss_device *dssdev = to_dss_device(dev);
561 dssdev->disable(dssdev); 544 dssdev->driver->disable(dssdev);
562 return 0; 545 return 0;
563} 546}
564 547
@@ -591,10 +574,6 @@ struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
591 574
592 int match(struct device *dev, void *data) 575 int match(struct device *dev, void *data)
593 { 576 {
594 /* skip panels connected to controllers */
595 if (to_dss_device(dev)->panel.ctrl)
596 return 0;
597
598 return 1; 577 return 1;
599 } 578 }
600 579
@@ -626,45 +605,21 @@ EXPORT_SYMBOL(omap_dss_find_device);
626 605
627int omap_dss_start_device(struct omap_dss_device *dssdev) 606int omap_dss_start_device(struct omap_dss_device *dssdev)
628{ 607{
629 int r;
630
631 if (!dssdev->driver) { 608 if (!dssdev->driver) {
632 DSSDBG("no driver\n"); 609 DSSDBG("no driver\n");
633 r = -ENODEV; 610 return -ENODEV;
634 goto err0;
635 }
636
637 if (dssdev->ctrl.panel && !dssdev->ctrl.panel->driver) {
638 DSSDBG("no panel driver\n");
639 r = -ENODEV;
640 goto err0;
641 } 611 }
642 612
643 if (!try_module_get(dssdev->dev.driver->owner)) { 613 if (!try_module_get(dssdev->dev.driver->owner)) {
644 r = -ENODEV; 614 return -ENODEV;
645 goto err0;
646 }
647
648 if (dssdev->ctrl.panel) {
649 if (!try_module_get(dssdev->ctrl.panel->dev.driver->owner)) {
650 r = -ENODEV;
651 goto err1;
652 }
653 } 615 }
654 616
655 return 0; 617 return 0;
656err1:
657 module_put(dssdev->dev.driver->owner);
658err0:
659 return r;
660} 618}
661EXPORT_SYMBOL(omap_dss_start_device); 619EXPORT_SYMBOL(omap_dss_start_device);
662 620
663void omap_dss_stop_device(struct omap_dss_device *dssdev) 621void omap_dss_stop_device(struct omap_dss_device *dssdev)
664{ 622{
665 if (dssdev->ctrl.panel)
666 module_put(dssdev->ctrl.panel->dev.driver->owner);
667
668 module_put(dssdev->dev.driver->owner); 623 module_put(dssdev->dev.driver->owner);
669} 624}
670EXPORT_SYMBOL(omap_dss_stop_device); 625EXPORT_SYMBOL(omap_dss_stop_device);
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 2d71031baa25..960e977a8bf0 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -25,7 +25,10 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/err.h>
28#include <linux/errno.h> 29#include <linux/errno.h>
30#include <linux/platform_device.h>
31#include <linux/regulator/consumer.h>
29 32
30#include <plat/display.h> 33#include <plat/display.h>
31#include <plat/cpu.h> 34#include <plat/cpu.h>
@@ -33,7 +36,7 @@
33#include "dss.h" 36#include "dss.h"
34 37
35static struct { 38static struct {
36 int update_enabled; 39 struct regulator *vdds_dsi_reg;
37} dpi; 40} dpi;
38 41
39#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 42#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
@@ -53,7 +56,7 @@ static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
53 if (r) 56 if (r)
54 return r; 57 return r;
55 58
56 dss_select_clk_source(0, 1); 59 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
57 60
58 r = dispc_set_clock_div(&dispc_cinfo); 61 r = dispc_set_clock_div(&dispc_cinfo);
59 if (r) 62 if (r)
@@ -150,7 +153,7 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
150 return 0; 153 return 0;
151} 154}
152 155
153static int dpi_display_enable(struct omap_dss_device *dssdev) 156int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
154{ 157{
155 int r; 158 int r;
156 159
@@ -160,10 +163,10 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
160 goto err0; 163 goto err0;
161 } 164 }
162 165
163 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 166 if (cpu_is_omap34xx()) {
164 DSSERR("display already enabled\n"); 167 r = regulator_enable(dpi.vdds_dsi_reg);
165 r = -EINVAL; 168 if (r)
166 goto err1; 169 goto err1;
167 } 170 }
168 171
169 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 172 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
@@ -184,18 +187,10 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
184 187
185 mdelay(2); 188 mdelay(2);
186 189
187 dispc_enable_lcd_out(1); 190 dssdev->manager->enable(dssdev->manager);
188
189 r = dssdev->driver->enable(dssdev);
190 if (r)
191 goto err5;
192
193 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
194 191
195 return 0; 192 return 0;
196 193
197err5:
198 dispc_enable_lcd_out(0);
199err4: 194err4:
200#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 195#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
201 dsi_pll_uninit(); 196 dsi_pll_uninit();
@@ -204,78 +199,35 @@ err3:
204#endif 199#endif
205err2: 200err2:
206 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 201 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
202 if (cpu_is_omap34xx())
203 regulator_disable(dpi.vdds_dsi_reg);
207err1: 204err1:
208 omap_dss_stop_device(dssdev); 205 omap_dss_stop_device(dssdev);
209err0: 206err0:
210 return r; 207 return r;
211} 208}
209EXPORT_SYMBOL(omapdss_dpi_display_enable);
212 210
213static int dpi_display_resume(struct omap_dss_device *dssdev); 211void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
214
215static void dpi_display_disable(struct omap_dss_device *dssdev)
216{ 212{
217 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) 213 dssdev->manager->disable(dssdev->manager);
218 return;
219
220 if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
221 dpi_display_resume(dssdev);
222
223 dssdev->driver->disable(dssdev);
224
225 dispc_enable_lcd_out(0);
226 214
227#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 215#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
228 dss_select_clk_source(0, 0); 216 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
229 dsi_pll_uninit(); 217 dsi_pll_uninit();
230 dss_clk_disable(DSS_CLK_FCK2); 218 dss_clk_disable(DSS_CLK_FCK2);
231#endif 219#endif
232 220
233 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 221 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
234 222
235 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 223 if (cpu_is_omap34xx())
224 regulator_disable(dpi.vdds_dsi_reg);
236 225
237 omap_dss_stop_device(dssdev); 226 omap_dss_stop_device(dssdev);
238} 227}
228EXPORT_SYMBOL(omapdss_dpi_display_disable);
239 229
240static int dpi_display_suspend(struct omap_dss_device *dssdev) 230void dpi_set_timings(struct omap_dss_device *dssdev,
241{
242 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
243 return -EINVAL;
244
245 DSSDBG("dpi_display_suspend\n");
246
247 if (dssdev->driver->suspend)
248 dssdev->driver->suspend(dssdev);
249
250 dispc_enable_lcd_out(0);
251
252 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
253
254 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
255
256 return 0;
257}
258
259static int dpi_display_resume(struct omap_dss_device *dssdev)
260{
261 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
262 return -EINVAL;
263
264 DSSDBG("dpi_display_resume\n");
265
266 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
267
268 dispc_enable_lcd_out(1);
269
270 if (dssdev->driver->resume)
271 dssdev->driver->resume(dssdev);
272
273 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
274
275 return 0;
276}
277
278static void dpi_set_timings(struct omap_dss_device *dssdev,
279 struct omap_video_timings *timings) 231 struct omap_video_timings *timings)
280{ 232{
281 DSSDBG("dpi_set_timings\n"); 233 DSSDBG("dpi_set_timings\n");
@@ -285,8 +237,9 @@ static void dpi_set_timings(struct omap_dss_device *dssdev,
285 dispc_go(OMAP_DSS_CHANNEL_LCD); 237 dispc_go(OMAP_DSS_CHANNEL_LCD);
286 } 238 }
287} 239}
240EXPORT_SYMBOL(dpi_set_timings);
288 241
289static int dpi_check_timings(struct omap_dss_device *dssdev, 242int dpi_check_timings(struct omap_dss_device *dssdev,
290 struct omap_video_timings *timings) 243 struct omap_video_timings *timings)
291{ 244{
292 bool is_tft; 245 bool is_tft;
@@ -340,56 +293,25 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
340 293
341 return 0; 294 return 0;
342} 295}
343 296EXPORT_SYMBOL(dpi_check_timings);
344static void dpi_get_timings(struct omap_dss_device *dssdev,
345 struct omap_video_timings *timings)
346{
347 *timings = dssdev->panel.timings;
348}
349
350static int dpi_display_set_update_mode(struct omap_dss_device *dssdev,
351 enum omap_dss_update_mode mode)
352{
353 if (mode == OMAP_DSS_UPDATE_MANUAL)
354 return -EINVAL;
355
356 if (mode == OMAP_DSS_UPDATE_DISABLED) {
357 dispc_enable_lcd_out(0);
358 dpi.update_enabled = 0;
359 } else {
360 dispc_enable_lcd_out(1);
361 dpi.update_enabled = 1;
362 }
363
364 return 0;
365}
366
367static enum omap_dss_update_mode dpi_display_get_update_mode(
368 struct omap_dss_device *dssdev)
369{
370 return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
371 OMAP_DSS_UPDATE_DISABLED;
372}
373 297
374int dpi_init_display(struct omap_dss_device *dssdev) 298int dpi_init_display(struct omap_dss_device *dssdev)
375{ 299{
376 DSSDBG("init_display\n"); 300 DSSDBG("init_display\n");
377 301
378 dssdev->enable = dpi_display_enable;
379 dssdev->disable = dpi_display_disable;
380 dssdev->suspend = dpi_display_suspend;
381 dssdev->resume = dpi_display_resume;
382 dssdev->set_timings = dpi_set_timings;
383 dssdev->check_timings = dpi_check_timings;
384 dssdev->get_timings = dpi_get_timings;
385 dssdev->set_update_mode = dpi_display_set_update_mode;
386 dssdev->get_update_mode = dpi_display_get_update_mode;
387
388 return 0; 302 return 0;
389} 303}
390 304
391int dpi_init(void) 305int dpi_init(struct platform_device *pdev)
392{ 306{
307 if (cpu_is_omap34xx()) {
308 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
309 if (IS_ERR(dpi.vdds_dsi_reg)) {
310 DSSERR("can't get VDDS_DSI regulator\n");
311 return PTR_ERR(dpi.vdds_dsi_reg);
312 }
313 }
314
393 return 0; 315 return 0;
394} 316}
395 317
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6122178f5f85..3af207b2bde3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -27,11 +27,12 @@
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/semaphore.h>
30#include <linux/seq_file.h> 31#include <linux/seq_file.h>
31#include <linux/platform_device.h> 32#include <linux/platform_device.h>
32#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
33#include <linux/kthread.h>
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h>
35 36
36#include <plat/display.h> 37#include <plat/display.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
@@ -199,7 +200,6 @@ enum dsi_vc_mode {
199}; 200};
200 201
201struct dsi_update_region { 202struct dsi_update_region {
202 bool dirty;
203 u16 x, y, w, h; 203 u16 x, y, w, h;
204 struct omap_dss_device *device; 204 struct omap_dss_device *device;
205}; 205};
@@ -224,29 +224,25 @@ static struct
224 enum dsi_vc_mode mode; 224 enum dsi_vc_mode mode;
225 struct omap_dss_device *dssdev; 225 struct omap_dss_device *dssdev;
226 enum fifo_size fifo_size; 226 enum fifo_size fifo_size;
227 int dest_per; /* destination peripheral 0-3 */
228 } vc[4]; 227 } vc[4];
229 228
230 struct mutex lock; 229 struct mutex lock;
231 struct mutex bus_lock; 230 struct semaphore bus_lock;
232 231
233 unsigned pll_locked; 232 unsigned pll_locked;
234 233
235 struct completion bta_completion; 234 struct completion bta_completion;
236 235
237 struct task_struct *thread; 236 int update_channel;
238 wait_queue_head_t waitqueue;
239
240 spinlock_t update_lock;
241 bool framedone_received;
242 struct dsi_update_region update_region; 237 struct dsi_update_region update_region;
243 struct dsi_update_region active_update_region;
244 struct completion update_completion;
245 238
246 enum omap_dss_update_mode user_update_mode;
247 enum omap_dss_update_mode update_mode;
248 bool te_enabled; 239 bool te_enabled;
249 bool use_ext_te; 240
241 struct work_struct framedone_work;
242 void (*framedone_callback)(int, void *);
243 void *framedone_data;
244
245 struct delayed_work framedone_timeout_work;
250 246
251#ifdef DSI_CATCH_MISSING_TE 247#ifdef DSI_CATCH_MISSING_TE
252 struct timer_list te_timer; 248 struct timer_list te_timer;
@@ -261,8 +257,6 @@ static struct
261#ifdef DEBUG 257#ifdef DEBUG
262 ktime_t perf_setup_time; 258 ktime_t perf_setup_time;
263 ktime_t perf_start_time; 259 ktime_t perf_start_time;
264 ktime_t perf_start_time_auto;
265 int perf_measure_frames;
266#endif 260#endif
267 int debug_read; 261 int debug_read;
268 int debug_write; 262 int debug_write;
@@ -299,16 +293,21 @@ void dsi_restore_context(void)
299 293
300void dsi_bus_lock(void) 294void dsi_bus_lock(void)
301{ 295{
302 mutex_lock(&dsi.bus_lock); 296 down(&dsi.bus_lock);
303} 297}
304EXPORT_SYMBOL(dsi_bus_lock); 298EXPORT_SYMBOL(dsi_bus_lock);
305 299
306void dsi_bus_unlock(void) 300void dsi_bus_unlock(void)
307{ 301{
308 mutex_unlock(&dsi.bus_lock); 302 up(&dsi.bus_lock);
309} 303}
310EXPORT_SYMBOL(dsi_bus_unlock); 304EXPORT_SYMBOL(dsi_bus_unlock);
311 305
306static bool dsi_bus_is_locked(void)
307{
308 return dsi.bus_lock.count == 0;
309}
310
312static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 311static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
313 int value) 312 int value)
314{ 313{
@@ -333,12 +332,6 @@ static void dsi_perf_mark_start(void)
333 dsi.perf_start_time = ktime_get(); 332 dsi.perf_start_time = ktime_get();
334} 333}
335 334
336static void dsi_perf_mark_start_auto(void)
337{
338 dsi.perf_measure_frames = 0;
339 dsi.perf_start_time_auto = ktime_get();
340}
341
342static void dsi_perf_show(const char *name) 335static void dsi_perf_show(const char *name)
343{ 336{
344 ktime_t t, setup_time, trans_time; 337 ktime_t t, setup_time, trans_time;
@@ -348,9 +341,6 @@ static void dsi_perf_show(const char *name)
348 if (!dsi_perf) 341 if (!dsi_perf)
349 return; 342 return;
350 343
351 if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED)
352 return;
353
354 t = ktime_get(); 344 t = ktime_get();
355 345
356 setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time); 346 setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time);
@@ -365,76 +355,23 @@ static void dsi_perf_show(const char *name)
365 355
366 total_us = setup_us + trans_us; 356 total_us = setup_us + trans_us;
367 357
368 total_bytes = dsi.active_update_region.w * 358 total_bytes = dsi.update_region.w *
369 dsi.active_update_region.h * 359 dsi.update_region.h *
370 dsi.active_update_region.device->ctrl.pixel_size / 8; 360 dsi.update_region.device->ctrl.pixel_size / 8;
371
372 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
373 static u32 s_total_trans_us, s_total_setup_us;
374 static u32 s_min_trans_us = 0xffffffff, s_min_setup_us;
375 static u32 s_max_trans_us, s_max_setup_us;
376 const int numframes = 100;
377 ktime_t total_time_auto;
378 u32 total_time_auto_us;
379
380 dsi.perf_measure_frames++;
381
382 if (setup_us < s_min_setup_us)
383 s_min_setup_us = setup_us;
384 361
385 if (setup_us > s_max_setup_us) 362 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
386 s_max_setup_us = setup_us; 363 "%u bytes, %u kbytes/sec\n",
387 364 name,
388 s_total_setup_us += setup_us; 365 setup_us,
389 366 trans_us,
390 if (trans_us < s_min_trans_us) 367 total_us,
391 s_min_trans_us = trans_us; 368 1000*1000 / total_us,
392 369 total_bytes,
393 if (trans_us > s_max_trans_us) 370 total_bytes * 1000 / total_us);
394 s_max_trans_us = trans_us;
395
396 s_total_trans_us += trans_us;
397
398 if (dsi.perf_measure_frames < numframes)
399 return;
400
401 total_time_auto = ktime_sub(t, dsi.perf_start_time_auto);
402 total_time_auto_us = (u32)ktime_to_us(total_time_auto);
403
404 printk(KERN_INFO "DSI(%s): %u fps, setup %u/%u/%u, "
405 "trans %u/%u/%u\n",
406 name,
407 1000 * 1000 * numframes / total_time_auto_us,
408 s_min_setup_us,
409 s_max_setup_us,
410 s_total_setup_us / numframes,
411 s_min_trans_us,
412 s_max_trans_us,
413 s_total_trans_us / numframes);
414
415 s_total_setup_us = 0;
416 s_min_setup_us = 0xffffffff;
417 s_max_setup_us = 0;
418 s_total_trans_us = 0;
419 s_min_trans_us = 0xffffffff;
420 s_max_trans_us = 0;
421 dsi_perf_mark_start_auto();
422 } else {
423 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
424 "%u bytes, %u kbytes/sec\n",
425 name,
426 setup_us,
427 trans_us,
428 total_us,
429 1000*1000 / total_us,
430 total_bytes,
431 total_bytes * 1000 / total_us);
432 }
433} 371}
434#else 372#else
435#define dsi_perf_mark_setup() 373#define dsi_perf_mark_setup()
436#define dsi_perf_mark_start() 374#define dsi_perf_mark_start()
437#define dsi_perf_mark_start_auto()
438#define dsi_perf_show(x) 375#define dsi_perf_show(x)
439#endif 376#endif
440 377
@@ -774,7 +711,7 @@ static unsigned long dsi_fclk_rate(void)
774{ 711{
775 unsigned long r; 712 unsigned long r;
776 713
777 if (dss_get_dsi_clk_source() == 0) { 714 if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) {
778 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ 715 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */
779 r = dss_clk_get_rate(DSS_CLK_FCK1); 716 r = dss_clk_get_rate(DSS_CLK_FCK1);
780 } else { 717 } else {
@@ -1227,17 +1164,19 @@ void dsi_dump_clocks(struct seq_file *s)
1227 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", 1164 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n",
1228 cinfo->dsi1_pll_fclk, 1165 cinfo->dsi1_pll_fclk,
1229 cinfo->regm3, 1166 cinfo->regm3,
1230 dss_get_dispc_clk_source() == 0 ? "off" : "on"); 1167 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
1168 "off" : "on");
1231 1169
1232 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", 1170 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n",
1233 cinfo->dsi2_pll_fclk, 1171 cinfo->dsi2_pll_fclk,
1234 cinfo->regm4, 1172 cinfo->regm4,
1235 dss_get_dsi_clk_source() == 0 ? "off" : "on"); 1173 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
1174 "off" : "on");
1236 1175
1237 seq_printf(s, "- DSI -\n"); 1176 seq_printf(s, "- DSI -\n");
1238 1177
1239 seq_printf(s, "dsi fclk source = %s\n", 1178 seq_printf(s, "dsi fclk source = %s\n",
1240 dss_get_dsi_clk_source() == 0 ? 1179 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
1241 "dss1_alwon_fclk" : "dsi2_pll_fclk"); 1180 "dss1_alwon_fclk" : "dsi2_pll_fclk");
1242 1181
1243 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); 1182 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate());
@@ -1756,29 +1695,10 @@ static int dsi_force_tx_stop_mode_io(void)
1756 return 0; 1695 return 0;
1757} 1696}
1758 1697
1759static void dsi_vc_print_status(int channel)
1760{
1761 u32 r;
1762
1763 r = dsi_read_reg(DSI_VC_CTRL(channel));
1764 DSSDBG("vc %d: TX_FIFO_NOT_EMPTY %d, BTA_EN %d, VC_BUSY %d, "
1765 "TX_FIFO_FULL %d, RX_FIFO_NOT_EMPTY %d, ",
1766 channel,
1767 FLD_GET(r, 5, 5),
1768 FLD_GET(r, 6, 6),
1769 FLD_GET(r, 15, 15),
1770 FLD_GET(r, 16, 16),
1771 FLD_GET(r, 20, 20));
1772
1773 r = dsi_read_reg(DSI_TX_FIFO_VC_EMPTINESS);
1774 DSSDBG("EMPTINESS %d\n", (r >> (8 * channel)) & 0xff);
1775}
1776
1777static int dsi_vc_enable(int channel, bool enable) 1698static int dsi_vc_enable(int channel, bool enable)
1778{ 1699{
1779 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) 1700 DSSDBG("dsi_vc_enable channel %d, enable %d\n",
1780 DSSDBG("dsi_vc_enable channel %d, enable %d\n", 1701 channel, enable);
1781 channel, enable);
1782 1702
1783 enable = enable ? 1 : 0; 1703 enable = enable ? 1 : 0;
1784 1704
@@ -1859,10 +1779,12 @@ static void dsi_vc_config_vp(int channel)
1859} 1779}
1860 1780
1861 1781
1862static void dsi_vc_enable_hs(int channel, bool enable) 1782void omapdss_dsi_vc_enable_hs(int channel, bool enable)
1863{ 1783{
1864 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); 1784 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
1865 1785
1786 WARN_ON(!dsi_bus_is_locked());
1787
1866 dsi_vc_enable(channel, 0); 1788 dsi_vc_enable(channel, 0);
1867 dsi_if_enable(0); 1789 dsi_if_enable(0);
1868 1790
@@ -1873,6 +1795,7 @@ static void dsi_vc_enable_hs(int channel, bool enable)
1873 1795
1874 dsi_force_tx_stop_mode_io(); 1796 dsi_force_tx_stop_mode_io();
1875} 1797}
1798EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
1876 1799
1877static void dsi_vc_flush_long_data(int channel) 1800static void dsi_vc_flush_long_data(int channel)
1878{ 1801{
@@ -1955,11 +1878,10 @@ static u16 dsi_vc_flush_receive_data(int channel)
1955 1878
1956static int dsi_vc_send_bta(int channel) 1879static int dsi_vc_send_bta(int channel)
1957{ 1880{
1958 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO && 1881 if (dsi.debug_write || dsi.debug_read)
1959 (dsi.debug_write || dsi.debug_read))
1960 DSSDBG("dsi_vc_send_bta %d\n", channel); 1882 DSSDBG("dsi_vc_send_bta %d\n", channel);
1961 1883
1962 WARN_ON(!mutex_is_locked(&dsi.bus_lock)); 1884 WARN_ON(!dsi_bus_is_locked());
1963 1885
1964 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ 1886 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */
1965 DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); 1887 DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
@@ -2010,10 +1932,9 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type,
2010 u32 val; 1932 u32 val;
2011 u8 data_id; 1933 u8 data_id;
2012 1934
2013 WARN_ON(!mutex_is_locked(&dsi.bus_lock)); 1935 WARN_ON(!dsi_bus_is_locked());
2014 1936
2015 /*data_id = data_type | channel << 6; */ 1937 data_id = data_type | channel << 6;
2016 data_id = data_type | dsi.vc[channel].dest_per << 6;
2017 1938
2018 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | 1939 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
2019 FLD_VAL(ecc, 31, 24); 1940 FLD_VAL(ecc, 31, 24);
@@ -2056,13 +1977,10 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
2056 1977
2057 dsi_vc_write_long_header(channel, data_type, len, ecc); 1978 dsi_vc_write_long_header(channel, data_type, len, ecc);
2058 1979
2059 /*dsi_vc_print_status(0); */
2060
2061 p = data; 1980 p = data;
2062 for (i = 0; i < len >> 2; i++) { 1981 for (i = 0; i < len >> 2; i++) {
2063 if (dsi.debug_write) 1982 if (dsi.debug_write)
2064 DSSDBG("\tsending full packet %d\n", i); 1983 DSSDBG("\tsending full packet %d\n", i);
2065 /*dsi_vc_print_status(0); */
2066 1984
2067 b1 = *p++; 1985 b1 = *p++;
2068 b2 = *p++; 1986 b2 = *p++;
@@ -2105,7 +2023,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2105 u32 r; 2023 u32 r;
2106 u8 data_id; 2024 u8 data_id;
2107 2025
2108 WARN_ON(!mutex_is_locked(&dsi.bus_lock)); 2026 WARN_ON(!dsi_bus_is_locked());
2109 2027
2110 if (dsi.debug_write) 2028 if (dsi.debug_write)
2111 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", 2029 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
@@ -2119,7 +2037,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2119 return -EINVAL; 2037 return -EINVAL;
2120 } 2038 }
2121 2039
2122 data_id = data_type | dsi.vc[channel].dest_per << 6; 2040 data_id = data_type | channel << 6;
2123 2041
2124 r = (data_id << 0) | (data << 8) | (ecc << 24); 2042 r = (data_id << 0) | (data << 8) | (ecc << 24);
2125 2043
@@ -2163,14 +2081,35 @@ int dsi_vc_dcs_write(int channel, u8 *data, int len)
2163 2081
2164 r = dsi_vc_dcs_write_nosync(channel, data, len); 2082 r = dsi_vc_dcs_write_nosync(channel, data, len);
2165 if (r) 2083 if (r)
2166 return r; 2084 goto err;
2167 2085
2168 r = dsi_vc_send_bta_sync(channel); 2086 r = dsi_vc_send_bta_sync(channel);
2087 if (r)
2088 goto err;
2169 2089
2090 return 0;
2091err:
2092 DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n",
2093 channel, data[0], len);
2170 return r; 2094 return r;
2171} 2095}
2172EXPORT_SYMBOL(dsi_vc_dcs_write); 2096EXPORT_SYMBOL(dsi_vc_dcs_write);
2173 2097
2098int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd)
2099{
2100 return dsi_vc_dcs_write(channel, &dcs_cmd, 1);
2101}
2102EXPORT_SYMBOL(dsi_vc_dcs_write_0);
2103
2104int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param)
2105{
2106 u8 buf[2];
2107 buf[0] = dcs_cmd;
2108 buf[1] = param;
2109 return dsi_vc_dcs_write(channel, buf, 2);
2110}
2111EXPORT_SYMBOL(dsi_vc_dcs_write_1);
2112
2174int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) 2113int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2175{ 2114{
2176 u32 val; 2115 u32 val;
@@ -2182,16 +2121,17 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2182 2121
2183 r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); 2122 r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0);
2184 if (r) 2123 if (r)
2185 return r; 2124 goto err;
2186 2125
2187 r = dsi_vc_send_bta_sync(channel); 2126 r = dsi_vc_send_bta_sync(channel);
2188 if (r) 2127 if (r)
2189 return r; 2128 goto err;
2190 2129
2191 /* RX_FIFO_NOT_EMPTY */ 2130 /* RX_FIFO_NOT_EMPTY */
2192 if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) { 2131 if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) {
2193 DSSERR("RX fifo empty when trying to read.\n"); 2132 DSSERR("RX fifo empty when trying to read.\n");
2194 return -EIO; 2133 r = -EIO;
2134 goto err;
2195 } 2135 }
2196 2136
2197 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 2137 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
@@ -2201,15 +2141,18 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2201 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 2141 if (dt == DSI_DT_RX_ACK_WITH_ERR) {
2202 u16 err = FLD_GET(val, 23, 8); 2142 u16 err = FLD_GET(val, 23, 8);
2203 dsi_show_rx_ack_with_err(err); 2143 dsi_show_rx_ack_with_err(err);
2204 return -EIO; 2144 r = -EIO;
2145 goto err;
2205 2146
2206 } else if (dt == DSI_DT_RX_SHORT_READ_1) { 2147 } else if (dt == DSI_DT_RX_SHORT_READ_1) {
2207 u8 data = FLD_GET(val, 15, 8); 2148 u8 data = FLD_GET(val, 15, 8);
2208 if (dsi.debug_read) 2149 if (dsi.debug_read)
2209 DSSDBG("\tDCS short response, 1 byte: %02x\n", data); 2150 DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
2210 2151
2211 if (buflen < 1) 2152 if (buflen < 1) {
2212 return -EIO; 2153 r = -EIO;
2154 goto err;
2155 }
2213 2156
2214 buf[0] = data; 2157 buf[0] = data;
2215 2158
@@ -2219,8 +2162,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2219 if (dsi.debug_read) 2162 if (dsi.debug_read)
2220 DSSDBG("\tDCS short response, 2 byte: %04x\n", data); 2163 DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
2221 2164
2222 if (buflen < 2) 2165 if (buflen < 2) {
2223 return -EIO; 2166 r = -EIO;
2167 goto err;
2168 }
2224 2169
2225 buf[0] = data & 0xff; 2170 buf[0] = data & 0xff;
2226 buf[1] = (data >> 8) & 0xff; 2171 buf[1] = (data >> 8) & 0xff;
@@ -2232,8 +2177,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2232 if (dsi.debug_read) 2177 if (dsi.debug_read)
2233 DSSDBG("\tDCS long response, len %d\n", len); 2178 DSSDBG("\tDCS long response, len %d\n", len);
2234 2179
2235 if (len > buflen) 2180 if (len > buflen) {
2236 return -EIO; 2181 r = -EIO;
2182 goto err;
2183 }
2237 2184
2238 /* two byte checksum ends the packet, not included in len */ 2185 /* two byte checksum ends the packet, not included in len */
2239 for (w = 0; w < len + 2;) { 2186 for (w = 0; w < len + 2;) {
@@ -2255,14 +2202,52 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2255 } 2202 }
2256 2203
2257 return len; 2204 return len;
2258
2259 } else { 2205 } else {
2260 DSSERR("\tunknown datatype 0x%02x\n", dt); 2206 DSSERR("\tunknown datatype 0x%02x\n", dt);
2261 return -EIO; 2207 r = -EIO;
2208 goto err;
2262 } 2209 }
2210
2211 BUG();
2212err:
2213 DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n",
2214 channel, dcs_cmd);
2215 return r;
2216
2263} 2217}
2264EXPORT_SYMBOL(dsi_vc_dcs_read); 2218EXPORT_SYMBOL(dsi_vc_dcs_read);
2265 2219
2220int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
2221{
2222 int r;
2223
2224 r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1);
2225
2226 if (r < 0)
2227 return r;
2228
2229 if (r != 1)
2230 return -EIO;
2231
2232 return 0;
2233}
2234EXPORT_SYMBOL(dsi_vc_dcs_read_1);
2235
2236int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data)
2237{
2238 int r;
2239
2240 r = dsi_vc_dcs_read(channel, dcs_cmd, (u8 *)data, 2);
2241
2242 if (r < 0)
2243 return r;
2244
2245 if (r != 2)
2246 return -EIO;
2247
2248 return 0;
2249}
2250EXPORT_SYMBOL(dsi_vc_dcs_read_2);
2266 2251
2267int dsi_vc_set_max_rx_packet_size(int channel, u16 len) 2252int dsi_vc_set_max_rx_packet_size(int channel, u16 len)
2268{ 2253{
@@ -2491,15 +2476,15 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2491 u32 r; 2476 u32 r;
2492 int buswidth = 0; 2477 int buswidth = 0;
2493 2478
2494 dsi_config_tx_fifo(DSI_FIFO_SIZE_128, 2479 dsi_config_tx_fifo(DSI_FIFO_SIZE_32,
2495 DSI_FIFO_SIZE_0, 2480 DSI_FIFO_SIZE_32,
2496 DSI_FIFO_SIZE_0, 2481 DSI_FIFO_SIZE_32,
2497 DSI_FIFO_SIZE_0); 2482 DSI_FIFO_SIZE_32);
2498 2483
2499 dsi_config_rx_fifo(DSI_FIFO_SIZE_128, 2484 dsi_config_rx_fifo(DSI_FIFO_SIZE_32,
2500 DSI_FIFO_SIZE_0, 2485 DSI_FIFO_SIZE_32,
2501 DSI_FIFO_SIZE_0, 2486 DSI_FIFO_SIZE_32,
2502 DSI_FIFO_SIZE_0); 2487 DSI_FIFO_SIZE_32);
2503 2488
2504 /* XXX what values for the timeouts? */ 2489 /* XXX what values for the timeouts? */
2505 dsi_set_stop_state_counter(1000); 2490 dsi_set_stop_state_counter(1000);
@@ -2537,12 +2522,9 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2537 dsi_write_reg(DSI_CTRL, r); 2522 dsi_write_reg(DSI_CTRL, r);
2538 2523
2539 dsi_vc_initial_config(0); 2524 dsi_vc_initial_config(0);
2540 2525 dsi_vc_initial_config(1);
2541 /* set all vc targets to peripheral 0 */ 2526 dsi_vc_initial_config(2);
2542 dsi.vc[0].dest_per = 0; 2527 dsi_vc_initial_config(3);
2543 dsi.vc[1].dest_per = 0;
2544 dsi.vc[2].dest_per = 0;
2545 dsi.vc[3].dest_per = 0;
2546 2528
2547 return 0; 2529 return 0;
2548} 2530}
@@ -2777,18 +2759,16 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2777 unsigned packet_payload; 2759 unsigned packet_payload;
2778 unsigned packet_len; 2760 unsigned packet_len;
2779 u32 l; 2761 u32 l;
2780 bool use_te_trigger; 2762 const unsigned channel = dsi.update_channel;
2781 const unsigned channel = 0;
2782 /* line buffer is 1024 x 24bits */ 2763 /* line buffer is 1024 x 24bits */
2783 /* XXX: for some reason using full buffer size causes considerable TX 2764 /* XXX: for some reason using full buffer size causes considerable TX
2784 * slowdown with update sizes that fill the whole buffer */ 2765 * slowdown with update sizes that fill the whole buffer */
2785 const unsigned line_buf_size = 1023 * 3; 2766 const unsigned line_buf_size = 1023 * 3;
2786 2767
2787 use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; 2768 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
2769 x, y, w, h);
2788 2770
2789 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) 2771 dsi_vc_config_vp(channel);
2790 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
2791 x, y, w, h);
2792 2772
2793 bytespp = dssdev->ctrl.pixel_size / 8; 2773 bytespp = dssdev->ctrl.pixel_size / 8;
2794 bytespl = w * bytespp; 2774 bytespl = w * bytespp;
@@ -2808,15 +2788,12 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2808 if (bytespf % packet_payload) 2788 if (bytespf % packet_payload)
2809 total_len += (bytespf % packet_payload) + 1; 2789 total_len += (bytespf % packet_payload) + 1;
2810 2790
2811 if (0)
2812 dsi_vc_print_status(1);
2813
2814 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ 2791 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
2815 dsi_write_reg(DSI_VC_TE(channel), l); 2792 dsi_write_reg(DSI_VC_TE(channel), l);
2816 2793
2817 dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0); 2794 dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0);
2818 2795
2819 if (use_te_trigger) 2796 if (dsi.te_enabled)
2820 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ 2797 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
2821 else 2798 else
2822 l = FLD_MOD(l, 1, 31, 31); /* TE_START */ 2799 l = FLD_MOD(l, 1, 31, 31); /* TE_START */
@@ -2830,9 +2807,14 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2830 */ 2807 */
2831 dispc_disable_sidle(); 2808 dispc_disable_sidle();
2832 2809
2810 dsi_perf_mark_start();
2811
2812 schedule_delayed_work(&dsi.framedone_timeout_work,
2813 msecs_to_jiffies(250));
2814
2833 dss_start_update(dssdev); 2815 dss_start_update(dssdev);
2834 2816
2835 if (use_te_trigger) { 2817 if (dsi.te_enabled) {
2836 /* disable LP_RX_TO, so that we can receive TE. Time to wait 2818 /* disable LP_RX_TO, so that we can receive TE. Time to wait
2837 * for TE is longer than the timer allows */ 2819 * for TE is longer than the timer allows */
2838 REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ 2820 REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
@@ -2852,110 +2834,64 @@ static void dsi_te_timeout(unsigned long arg)
2852} 2834}
2853#endif 2835#endif
2854 2836
2855static void dsi_framedone_irq_callback(void *data, u32 mask) 2837static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2856{ 2838{
2857 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and 2839 int r;
2858 * turns itself off. However, DSI still has the pixels in its buffers, 2840 const int channel = dsi.update_channel;
2859 * and is sending the data. 2841
2860 */ 2842 DSSERR("Framedone not received for 250ms!\n");
2861 2843
2862 /* SIDLEMODE back to smart-idle */ 2844 /* SIDLEMODE back to smart-idle */
2863 dispc_enable_sidle(); 2845 dispc_enable_sidle();
2864 2846
2865 dsi.framedone_received = true; 2847 if (dsi.te_enabled) {
2866 wake_up(&dsi.waitqueue); 2848 /* enable LP_RX_TO again after the TE */
2867} 2849 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2868
2869static void dsi_set_update_region(struct omap_dss_device *dssdev,
2870 u16 x, u16 y, u16 w, u16 h)
2871{
2872 spin_lock(&dsi.update_lock);
2873 if (dsi.update_region.dirty) {
2874 dsi.update_region.x = min(x, dsi.update_region.x);
2875 dsi.update_region.y = min(y, dsi.update_region.y);
2876 dsi.update_region.w = max(w, dsi.update_region.w);
2877 dsi.update_region.h = max(h, dsi.update_region.h);
2878 } else {
2879 dsi.update_region.x = x;
2880 dsi.update_region.y = y;
2881 dsi.update_region.w = w;
2882 dsi.update_region.h = h;
2883 } 2850 }
2884 2851
2885 dsi.update_region.device = dssdev; 2852 /* Send BTA after the frame. We need this for the TE to work, as TE
2886 dsi.update_region.dirty = true; 2853 * trigger is only sent for BTAs without preceding packet. Thus we need
2887 2854 * to BTA after the pixel packets so that next BTA will cause TE
2888 spin_unlock(&dsi.update_lock); 2855 * trigger.
2889 2856 *
2890} 2857 * This is not needed when TE is not in use, but we do it anyway to
2891 2858 * make sure that the transfer has been completed. It would be more
2892static int dsi_set_update_mode(struct omap_dss_device *dssdev, 2859 * optimal, but more complex, to wait only just before starting next
2893 enum omap_dss_update_mode mode) 2860 * transfer. */
2894{ 2861 r = dsi_vc_send_bta_sync(channel);
2895 int r = 0; 2862 if (r)
2896 int i; 2863 DSSERR("BTA after framedone failed\n");
2897
2898 WARN_ON(!mutex_is_locked(&dsi.bus_lock));
2899
2900 if (dsi.update_mode != mode) {
2901 dsi.update_mode = mode;
2902
2903 /* Mark the overlays dirty, and do apply(), so that we get the
2904 * overlays configured properly after update mode change. */
2905 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
2906 struct omap_overlay *ovl;
2907 ovl = omap_dss_get_overlay(i);
2908 if (ovl->manager == dssdev->manager)
2909 ovl->info_dirty = true;
2910 }
2911
2912 r = dssdev->manager->apply(dssdev->manager);
2913
2914 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE &&
2915 mode == OMAP_DSS_UPDATE_AUTO) {
2916 u16 w, h;
2917
2918 DSSDBG("starting auto update\n");
2919
2920 dssdev->get_resolution(dssdev, &w, &h);
2921
2922 dsi_set_update_region(dssdev, 0, 0, w, h);
2923
2924 dsi_perf_mark_start_auto();
2925 2864
2926 wake_up(&dsi.waitqueue); 2865 /* RX_FIFO_NOT_EMPTY */
2927 } 2866 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
2867 DSSERR("Received error during frame transfer:\n");
2868 dsi_vc_flush_receive_data(channel);
2928 } 2869 }
2929 2870
2930 return r; 2871 dsi.framedone_callback(-ETIMEDOUT, dsi.framedone_data);
2931} 2872}
2932 2873
2933static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) 2874static void dsi_framedone_irq_callback(void *data, u32 mask)
2934{ 2875{
2935 int r = 0; 2876 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and
2877 * turns itself off. However, DSI still has the pixels in its buffers,
2878 * and is sending the data.
2879 */
2936 2880
2937 if (dssdev->driver->enable_te) { 2881 /* SIDLEMODE back to smart-idle */
2938 r = dssdev->driver->enable_te(dssdev, enable); 2882 dispc_enable_sidle();
2939 /* XXX for some reason, DSI TE breaks if we don't wait here.
2940 * Panel bug? Needs more studying */
2941 msleep(100);
2942 }
2943 2883
2944 return r; 2884 schedule_work(&dsi.framedone_work);
2945} 2885}
2946 2886
2947static void dsi_handle_framedone(void) 2887static void dsi_handle_framedone(void)
2948{ 2888{
2949 int r; 2889 int r;
2950 const int channel = 0; 2890 const int channel = dsi.update_channel;
2951 bool use_te_trigger;
2952
2953 use_te_trigger = dsi.te_enabled && !dsi.use_ext_te;
2954 2891
2955 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) 2892 DSSDBG("FRAMEDONE\n");
2956 DSSDBG("FRAMEDONE\n");
2957 2893
2958 if (use_te_trigger) { 2894 if (dsi.te_enabled) {
2959 /* enable LP_RX_TO again after the TE */ 2895 /* enable LP_RX_TO again after the TE */
2960 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 2896 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2961 } 2897 }
@@ -2976,7 +2912,7 @@ static void dsi_handle_framedone(void)
2976 /* RX_FIFO_NOT_EMPTY */ 2912 /* RX_FIFO_NOT_EMPTY */
2977 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2913 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
2978 DSSERR("Received error during frame transfer:\n"); 2914 DSSERR("Received error during frame transfer:\n");
2979 dsi_vc_flush_receive_data(0); 2915 dsi_vc_flush_receive_data(channel);
2980 } 2916 }
2981 2917
2982#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC 2918#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
@@ -2984,118 +2920,79 @@ static void dsi_handle_framedone(void)
2984#endif 2920#endif
2985} 2921}
2986 2922
2987static int dsi_update_thread(void *data) 2923static void dsi_framedone_work_callback(struct work_struct *work)
2988{ 2924{
2989 unsigned long timeout; 2925 DSSDBGF();
2990 struct omap_dss_device *device;
2991 u16 x, y, w, h;
2992
2993 while (1) {
2994 bool sched;
2995
2996 wait_event_interruptible(dsi.waitqueue,
2997 dsi.update_mode == OMAP_DSS_UPDATE_AUTO ||
2998 (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
2999 dsi.update_region.dirty == true) ||
3000 kthread_should_stop());
3001
3002 if (kthread_should_stop())
3003 break;
3004
3005 dsi_bus_lock();
3006
3007 if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED ||
3008 kthread_should_stop()) {
3009 dsi_bus_unlock();
3010 break;
3011 }
3012
3013 dsi_perf_mark_setup();
3014
3015 if (dsi.update_region.dirty) {
3016 spin_lock(&dsi.update_lock);
3017 dsi.active_update_region = dsi.update_region;
3018 dsi.update_region.dirty = false;
3019 spin_unlock(&dsi.update_lock);
3020 }
3021 2926
3022 device = dsi.active_update_region.device; 2927 cancel_delayed_work_sync(&dsi.framedone_timeout_work);
3023 x = dsi.active_update_region.x;
3024 y = dsi.active_update_region.y;
3025 w = dsi.active_update_region.w;
3026 h = dsi.active_update_region.h;
3027 2928
3028 if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2929 dsi_handle_framedone();
3029 2930
3030 if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL) 2931 dsi_perf_show("DISPC");
3031 dss_setup_partial_planes(device,
3032 &x, &y, &w, &h);
3033 2932
3034 dispc_set_lcd_size(w, h); 2933 dsi.framedone_callback(0, dsi.framedone_data);
3035 } 2934}
3036 2935
3037 if (dsi.active_update_region.dirty) { 2936int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
3038 dsi.active_update_region.dirty = false; 2937 u16 *x, u16 *y, u16 *w, u16 *h)
3039 /* XXX TODO we don't need to send the coords, if they 2938{
3040 * are the same that are already programmed to the 2939 u16 dw, dh;
3041 * panel. That should speed up manual update a bit */
3042 device->driver->setup_update(device, x, y, w, h);
3043 }
3044 2940
3045 dsi_perf_mark_start(); 2941 dssdev->driver->get_resolution(dssdev, &dw, &dh);
3046 2942
3047 if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2943 if (*x > dw || *y > dh)
3048 dsi_vc_config_vp(0); 2944 return -EINVAL;
3049 2945
3050 if (dsi.te_enabled && dsi.use_ext_te) 2946 if (*x + *w > dw)
3051 device->driver->wait_for_te(device); 2947 return -EINVAL;
3052 2948
3053 dsi.framedone_received = false; 2949 if (*y + *h > dh)
2950 return -EINVAL;
3054 2951
3055 dsi_update_screen_dispc(device, x, y, w, h); 2952 if (*w == 1)
2953 return -EINVAL;
3056 2954
3057 /* wait for framedone */ 2955 if (*w == 0 || *h == 0)
3058 timeout = msecs_to_jiffies(1000); 2956 return -EINVAL;
3059 wait_event_timeout(dsi.waitqueue,
3060 dsi.framedone_received == true,
3061 timeout);
3062 2957
3063 if (!dsi.framedone_received) { 2958 dsi_perf_mark_setup();
3064 DSSERR("framedone timeout\n");
3065 DSSERR("failed update %d,%d %dx%d\n",
3066 x, y, w, h);
3067 2959
3068 dispc_enable_sidle(); 2960 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
3069 dispc_enable_lcd_out(0); 2961 dss_setup_partial_planes(dssdev, x, y, w, h);
2962 dispc_set_lcd_size(*w, *h);
2963 }
3070 2964
3071 dsi_reset_tx_fifo(0); 2965 return 0;
3072 } else { 2966}
3073 dsi_handle_framedone(); 2967EXPORT_SYMBOL(omap_dsi_prepare_update);
3074 dsi_perf_show("DISPC");
3075 }
3076 } else {
3077 dsi_update_screen_l4(device, x, y, w, h);
3078 dsi_perf_show("L4");
3079 }
3080 2968
3081 sched = atomic_read(&dsi.bus_lock.count) < 0; 2969int omap_dsi_update(struct omap_dss_device *dssdev,
2970 int channel,
2971 u16 x, u16 y, u16 w, u16 h,
2972 void (*callback)(int, void *), void *data)
2973{
2974 dsi.update_channel = channel;
3082 2975
3083 complete_all(&dsi.update_completion); 2976 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2977 dsi.framedone_callback = callback;
2978 dsi.framedone_data = data;
3084 2979
3085 dsi_bus_unlock(); 2980 dsi.update_region.x = x;
2981 dsi.update_region.y = y;
2982 dsi.update_region.w = w;
2983 dsi.update_region.h = h;
2984 dsi.update_region.device = dssdev;
3086 2985
3087 /* XXX We need to give others chance to get the bus lock. Is 2986 dsi_update_screen_dispc(dssdev, x, y, w, h);
3088 * there a better way for this? */ 2987 } else {
3089 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO && sched) 2988 dsi_update_screen_l4(dssdev, x, y, w, h);
3090 schedule_timeout_interruptible(1); 2989 dsi_perf_show("L4");
2990 callback(0, data);
3091 } 2991 }
3092 2992
3093 DSSDBG("update thread exiting\n");
3094
3095 return 0; 2993 return 0;
3096} 2994}
3097 2995EXPORT_SYMBOL(omap_dsi_update);
3098
3099 2996
3100/* Display funcs */ 2997/* Display funcs */
3101 2998
@@ -3203,7 +3100,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3203 if (r) 3100 if (r)
3204 goto err1; 3101 goto err1;
3205 3102
3206 dss_select_clk_source(true, true); 3103 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
3104 dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK);
3207 3105
3208 DSSDBG("PLL OK\n"); 3106 DSSDBG("PLL OK\n");
3209 3107
@@ -3229,25 +3127,18 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3229 3127
3230 /* enable interface */ 3128 /* enable interface */
3231 dsi_vc_enable(0, 1); 3129 dsi_vc_enable(0, 1);
3130 dsi_vc_enable(1, 1);
3131 dsi_vc_enable(2, 1);
3132 dsi_vc_enable(3, 1);
3232 dsi_if_enable(1); 3133 dsi_if_enable(1);
3233 dsi_force_tx_stop_mode_io(); 3134 dsi_force_tx_stop_mode_io();
3234 3135
3235 if (dssdev->driver->enable) {
3236 r = dssdev->driver->enable(dssdev);
3237 if (r)
3238 goto err4;
3239 }
3240
3241 /* enable high-speed after initial config */
3242 dsi_vc_enable_hs(0, 1);
3243
3244 return 0; 3136 return 0;
3245err4:
3246 dsi_if_enable(0);
3247err3: 3137err3:
3248 dsi_complexio_uninit(); 3138 dsi_complexio_uninit();
3249err2: 3139err2:
3250 dss_select_clk_source(false, false); 3140 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3141 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3251err1: 3142err1:
3252 dsi_pll_uninit(); 3143 dsi_pll_uninit();
3253err0: 3144err0:
@@ -3256,10 +3147,8 @@ err0:
3256 3147
3257static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) 3148static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3258{ 3149{
3259 if (dssdev->driver->disable) 3150 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3260 dssdev->driver->disable(dssdev); 3151 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3261
3262 dss_select_clk_source(false, false);
3263 dsi_complexio_uninit(); 3152 dsi_complexio_uninit();
3264 dsi_pll_uninit(); 3153 dsi_pll_uninit();
3265} 3154}
@@ -3280,14 +3169,15 @@ static int dsi_core_init(void)
3280 return 0; 3169 return 0;
3281} 3170}
3282 3171
3283static int dsi_display_enable(struct omap_dss_device *dssdev) 3172int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
3284{ 3173{
3285 int r = 0; 3174 int r = 0;
3286 3175
3287 DSSDBG("dsi_display_enable\n"); 3176 DSSDBG("dsi_display_enable\n");
3288 3177
3178 WARN_ON(!dsi_bus_is_locked());
3179
3289 mutex_lock(&dsi.lock); 3180 mutex_lock(&dsi.lock);
3290 dsi_bus_lock();
3291 3181
3292 r = omap_dss_start_device(dssdev); 3182 r = omap_dss_start_device(dssdev);
3293 if (r) { 3183 if (r) {
@@ -3295,100 +3185,47 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
3295 goto err0; 3185 goto err0;
3296 } 3186 }
3297 3187
3298 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
3299 DSSERR("dssdev already enabled\n");
3300 r = -EINVAL;
3301 goto err1;
3302 }
3303
3304 enable_clocks(1); 3188 enable_clocks(1);
3305 dsi_enable_pll_clock(1); 3189 dsi_enable_pll_clock(1);
3306 3190
3307 r = _dsi_reset(); 3191 r = _dsi_reset();
3308 if (r) 3192 if (r)
3309 goto err2; 3193 goto err1;
3310 3194
3311 dsi_core_init(); 3195 dsi_core_init();
3312 3196
3313 r = dsi_display_init_dispc(dssdev); 3197 r = dsi_display_init_dispc(dssdev);
3314 if (r) 3198 if (r)
3315 goto err2; 3199 goto err1;
3316 3200
3317 r = dsi_display_init_dsi(dssdev); 3201 r = dsi_display_init_dsi(dssdev);
3318 if (r) 3202 if (r)
3319 goto err3; 3203 goto err2;
3320
3321 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
3322
3323 dsi.use_ext_te = dssdev->phy.dsi.ext_te;
3324 r = dsi_set_te(dssdev, dsi.te_enabled);
3325 if (r)
3326 goto err4;
3327
3328 dsi_set_update_mode(dssdev, dsi.user_update_mode);
3329 3204
3330 dsi_bus_unlock();
3331 mutex_unlock(&dsi.lock); 3205 mutex_unlock(&dsi.lock);
3332 3206
3333 return 0; 3207 return 0;
3334 3208
3335err4:
3336
3337 dsi_display_uninit_dsi(dssdev);
3338err3:
3339 dsi_display_uninit_dispc(dssdev);
3340err2: 3209err2:
3210 dsi_display_uninit_dispc(dssdev);
3211err1:
3341 enable_clocks(0); 3212 enable_clocks(0);
3342 dsi_enable_pll_clock(0); 3213 dsi_enable_pll_clock(0);
3343err1:
3344 omap_dss_stop_device(dssdev); 3214 omap_dss_stop_device(dssdev);
3345err0: 3215err0:
3346 dsi_bus_unlock();
3347 mutex_unlock(&dsi.lock); 3216 mutex_unlock(&dsi.lock);
3348 DSSDBG("dsi_display_enable FAILED\n"); 3217 DSSDBG("dsi_display_enable FAILED\n");
3349 return r; 3218 return r;
3350} 3219}
3220EXPORT_SYMBOL(omapdss_dsi_display_enable);
3351 3221
3352static void dsi_display_disable(struct omap_dss_device *dssdev) 3222void omapdss_dsi_display_disable(struct omap_dss_device *dssdev)
3353{ 3223{
3354 DSSDBG("dsi_display_disable\n"); 3224 DSSDBG("dsi_display_disable\n");
3355 3225
3356 mutex_lock(&dsi.lock); 3226 WARN_ON(!dsi_bus_is_locked());
3357 dsi_bus_lock();
3358
3359 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
3360 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
3361 goto end;
3362
3363 dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
3364 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
3365
3366 dsi_display_uninit_dispc(dssdev);
3367
3368 dsi_display_uninit_dsi(dssdev);
3369
3370 enable_clocks(0);
3371 dsi_enable_pll_clock(0);
3372
3373 omap_dss_stop_device(dssdev);
3374end:
3375 dsi_bus_unlock();
3376 mutex_unlock(&dsi.lock);
3377}
3378
3379static int dsi_display_suspend(struct omap_dss_device *dssdev)
3380{
3381 DSSDBG("dsi_display_suspend\n");
3382 3227
3383 mutex_lock(&dsi.lock); 3228 mutex_lock(&dsi.lock);
3384 dsi_bus_lock();
3385
3386 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
3387 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
3388 goto end;
3389
3390 dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
3391 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
3392 3229
3393 dsi_display_uninit_dispc(dssdev); 3230 dsi_display_uninit_dispc(dssdev);
3394 3231
@@ -3396,312 +3233,19 @@ static int dsi_display_suspend(struct omap_dss_device *dssdev)
3396 3233
3397 enable_clocks(0); 3234 enable_clocks(0);
3398 dsi_enable_pll_clock(0); 3235 dsi_enable_pll_clock(0);
3399end:
3400 dsi_bus_unlock();
3401 mutex_unlock(&dsi.lock);
3402
3403 return 0;
3404}
3405
3406static int dsi_display_resume(struct omap_dss_device *dssdev)
3407{
3408 int r;
3409
3410 DSSDBG("dsi_display_resume\n");
3411
3412 mutex_lock(&dsi.lock);
3413 dsi_bus_lock();
3414
3415 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
3416 DSSERR("dssdev not suspended\n");
3417 r = -EINVAL;
3418 goto err0;
3419 }
3420
3421 enable_clocks(1);
3422 dsi_enable_pll_clock(1);
3423
3424 r = _dsi_reset();
3425 if (r)
3426 goto err1;
3427
3428 dsi_core_init();
3429
3430 r = dsi_display_init_dispc(dssdev);
3431 if (r)
3432 goto err1;
3433
3434 r = dsi_display_init_dsi(dssdev);
3435 if (r)
3436 goto err2;
3437
3438 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
3439
3440 r = dsi_set_te(dssdev, dsi.te_enabled);
3441 if (r)
3442 goto err2;
3443
3444 dsi_set_update_mode(dssdev, dsi.user_update_mode);
3445
3446 dsi_bus_unlock();
3447 mutex_unlock(&dsi.lock);
3448
3449 return 0;
3450
3451err2:
3452 dsi_display_uninit_dispc(dssdev);
3453err1:
3454 enable_clocks(0);
3455 dsi_enable_pll_clock(0);
3456err0:
3457 dsi_bus_unlock();
3458 mutex_unlock(&dsi.lock);
3459 DSSDBG("dsi_display_resume FAILED\n");
3460 return r;
3461}
3462
3463static int dsi_display_update(struct omap_dss_device *dssdev,
3464 u16 x, u16 y, u16 w, u16 h)
3465{
3466 int r = 0;
3467 u16 dw, dh;
3468
3469 DSSDBG("dsi_display_update(%d,%d %dx%d)\n", x, y, w, h);
3470 3236
3471 mutex_lock(&dsi.lock); 3237 omap_dss_stop_device(dssdev);
3472
3473 if (dsi.update_mode != OMAP_DSS_UPDATE_MANUAL)
3474 goto end;
3475
3476 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3477 goto end;
3478
3479 dssdev->get_resolution(dssdev, &dw, &dh);
3480
3481 if (x > dw || y > dh)
3482 goto end;
3483
3484 if (x + w > dw)
3485 w = dw - x;
3486
3487 if (y + h > dh)
3488 h = dh - y;
3489
3490 if (w == 0 || h == 0)
3491 goto end;
3492
3493 if (w == 1) {
3494 r = -EINVAL;
3495 goto end;
3496 }
3497
3498 dsi_set_update_region(dssdev, x, y, w, h);
3499
3500 wake_up(&dsi.waitqueue);
3501
3502end:
3503 mutex_unlock(&dsi.lock);
3504
3505 return r;
3506}
3507
3508static int dsi_display_sync(struct omap_dss_device *dssdev)
3509{
3510 bool wait;
3511
3512 DSSDBG("dsi_display_sync()\n");
3513
3514 mutex_lock(&dsi.lock);
3515 dsi_bus_lock();
3516
3517 if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
3518 dsi.update_region.dirty) {
3519 INIT_COMPLETION(dsi.update_completion);
3520 wait = true;
3521 } else {
3522 wait = false;
3523 }
3524
3525 dsi_bus_unlock();
3526 mutex_unlock(&dsi.lock);
3527
3528 if (wait)
3529 wait_for_completion_interruptible(&dsi.update_completion);
3530
3531 DSSDBG("dsi_display_sync() done\n");
3532 return 0;
3533}
3534
3535static int dsi_display_set_update_mode(struct omap_dss_device *dssdev,
3536 enum omap_dss_update_mode mode)
3537{
3538 int r = 0;
3539
3540 DSSDBGF("%d", mode);
3541
3542 mutex_lock(&dsi.lock);
3543 dsi_bus_lock();
3544
3545 dsi.user_update_mode = mode;
3546 r = dsi_set_update_mode(dssdev, mode);
3547 3238
3548 dsi_bus_unlock();
3549 mutex_unlock(&dsi.lock); 3239 mutex_unlock(&dsi.lock);
3550
3551 return r;
3552} 3240}
3241EXPORT_SYMBOL(omapdss_dsi_display_disable);
3553 3242
3554static enum omap_dss_update_mode dsi_display_get_update_mode( 3243int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
3555 struct omap_dss_device *dssdev)
3556{ 3244{
3557 return dsi.update_mode;
3558}
3559
3560
3561static int dsi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
3562{
3563 int r = 0;
3564
3565 DSSDBGF("%d", enable);
3566
3567 if (!dssdev->driver->enable_te)
3568 return -ENOENT;
3569
3570 dsi_bus_lock();
3571
3572 dsi.te_enabled = enable; 3245 dsi.te_enabled = enable;
3573
3574 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3575 goto end;
3576
3577 r = dsi_set_te(dssdev, enable);
3578end:
3579 dsi_bus_unlock();
3580
3581 return r;
3582}
3583
3584static int dsi_display_get_te(struct omap_dss_device *dssdev)
3585{
3586 return dsi.te_enabled;
3587}
3588
3589static int dsi_display_set_rotate(struct omap_dss_device *dssdev, u8 rotate)
3590{
3591
3592 DSSDBGF("%d", rotate);
3593
3594 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
3595 return -EINVAL;
3596
3597 dsi_bus_lock();
3598 dssdev->driver->set_rotate(dssdev, rotate);
3599 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
3600 u16 w, h;
3601 /* the display dimensions may have changed, so set a new
3602 * update region */
3603 dssdev->get_resolution(dssdev, &w, &h);
3604 dsi_set_update_region(dssdev, 0, 0, w, h);
3605 }
3606 dsi_bus_unlock();
3607
3608 return 0; 3246 return 0;
3609} 3247}
3610 3248EXPORT_SYMBOL(omapdss_dsi_enable_te);
3611static u8 dsi_display_get_rotate(struct omap_dss_device *dssdev)
3612{
3613 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
3614 return 0;
3615
3616 return dssdev->driver->get_rotate(dssdev);
3617}
3618
3619static int dsi_display_set_mirror(struct omap_dss_device *dssdev, bool mirror)
3620{
3621 DSSDBGF("%d", mirror);
3622
3623 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
3624 return -EINVAL;
3625
3626 dsi_bus_lock();
3627 dssdev->driver->set_mirror(dssdev, mirror);
3628 dsi_bus_unlock();
3629
3630 return 0;
3631}
3632
3633static bool dsi_display_get_mirror(struct omap_dss_device *dssdev)
3634{
3635 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
3636 return 0;
3637
3638 return dssdev->driver->get_mirror(dssdev);
3639}
3640
3641static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num)
3642{
3643 int r;
3644
3645 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3646 return -EIO;
3647
3648 DSSDBGF("%d", test_num);
3649
3650 dsi_bus_lock();
3651
3652 /* run test first in low speed mode */
3653 dsi_vc_enable_hs(0, 0);
3654
3655 if (dssdev->driver->run_test) {
3656 r = dssdev->driver->run_test(dssdev, test_num);
3657 if (r)
3658 goto end;
3659 }
3660
3661 /* then in high speed */
3662 dsi_vc_enable_hs(0, 1);
3663
3664 if (dssdev->driver->run_test) {
3665 r = dssdev->driver->run_test(dssdev, test_num);
3666 if (r)
3667 goto end;
3668 }
3669
3670end:
3671 dsi_vc_enable_hs(0, 1);
3672
3673 dsi_bus_unlock();
3674
3675 return r;
3676}
3677
3678static int dsi_display_memory_read(struct omap_dss_device *dssdev,
3679 void *buf, size_t size,
3680 u16 x, u16 y, u16 w, u16 h)
3681{
3682 int r;
3683
3684 DSSDBGF("");
3685
3686 if (!dssdev->driver->memory_read)
3687 return -EINVAL;
3688
3689 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3690 return -EIO;
3691
3692 dsi_bus_lock();
3693
3694 r = dssdev->driver->memory_read(dssdev, buf, size,
3695 x, y, w, h);
3696
3697 /* Memory read usually changes the update area. This will
3698 * force the next update to re-set the update area */
3699 dsi.active_update_region.dirty = true;
3700
3701 dsi_bus_unlock();
3702
3703 return r;
3704}
3705 3249
3706void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 3250void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
3707 u32 fifo_size, enum omap_burst_size *burst_size, 3251 u32 fifo_size, enum omap_burst_size *burst_size,
@@ -3720,26 +3264,6 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3720{ 3264{
3721 DSSDBG("DSI init\n"); 3265 DSSDBG("DSI init\n");
3722 3266
3723 dssdev->enable = dsi_display_enable;
3724 dssdev->disable = dsi_display_disable;
3725 dssdev->suspend = dsi_display_suspend;
3726 dssdev->resume = dsi_display_resume;
3727 dssdev->update = dsi_display_update;
3728 dssdev->sync = dsi_display_sync;
3729 dssdev->set_update_mode = dsi_display_set_update_mode;
3730 dssdev->get_update_mode = dsi_display_get_update_mode;
3731 dssdev->enable_te = dsi_display_enable_te;
3732 dssdev->get_te = dsi_display_get_te;
3733
3734 dssdev->get_rotate = dsi_display_get_rotate;
3735 dssdev->set_rotate = dsi_display_set_rotate;
3736
3737 dssdev->get_mirror = dsi_display_get_mirror;
3738 dssdev->set_mirror = dsi_display_set_mirror;
3739
3740 dssdev->run_test = dsi_display_run_test;
3741 dssdev->memory_read = dsi_display_memory_read;
3742
3743 /* XXX these should be figured out dynamically */ 3267 /* XXX these should be figured out dynamically */
3744 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 3268 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
3745 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 3269 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
@@ -3754,9 +3278,6 @@ int dsi_init(struct platform_device *pdev)
3754{ 3278{
3755 u32 rev; 3279 u32 rev;
3756 int r; 3280 int r;
3757 struct sched_param param = {
3758 .sched_priority = MAX_USER_RT_PRIO-1
3759 };
3760 3281
3761 spin_lock_init(&dsi.errors_lock); 3282 spin_lock_init(&dsi.errors_lock);
3762 dsi.errors = 0; 3283 dsi.errors = 0;
@@ -3767,31 +3288,19 @@ int dsi_init(struct platform_device *pdev)
3767#endif 3288#endif
3768 3289
3769 init_completion(&dsi.bta_completion); 3290 init_completion(&dsi.bta_completion);
3770 init_completion(&dsi.update_completion);
3771
3772 dsi.thread = kthread_create(dsi_update_thread, NULL, "dsi");
3773 if (IS_ERR(dsi.thread)) {
3774 DSSERR("cannot create kthread\n");
3775 r = PTR_ERR(dsi.thread);
3776 goto err0;
3777 }
3778 sched_setscheduler(dsi.thread, SCHED_FIFO, &param);
3779
3780 init_waitqueue_head(&dsi.waitqueue);
3781 spin_lock_init(&dsi.update_lock);
3782 3291
3783 mutex_init(&dsi.lock); 3292 mutex_init(&dsi.lock);
3784 mutex_init(&dsi.bus_lock); 3293 sema_init(&dsi.bus_lock, 1);
3294
3295 INIT_WORK(&dsi.framedone_work, dsi_framedone_work_callback);
3296 INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work,
3297 dsi_framedone_timeout_work_callback);
3785 3298
3786#ifdef DSI_CATCH_MISSING_TE 3299#ifdef DSI_CATCH_MISSING_TE
3787 init_timer(&dsi.te_timer); 3300 init_timer(&dsi.te_timer);
3788 dsi.te_timer.function = dsi_te_timeout; 3301 dsi.te_timer.function = dsi_te_timeout;
3789 dsi.te_timer.data = 0; 3302 dsi.te_timer.data = 0;
3790#endif 3303#endif
3791
3792 dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
3793 dsi.user_update_mode = OMAP_DSS_UPDATE_DISABLED;
3794
3795 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); 3304 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS);
3796 if (!dsi.base) { 3305 if (!dsi.base) {
3797 DSSERR("can't ioremap DSI\n"); 3306 DSSERR("can't ioremap DSI\n");
@@ -3799,7 +3308,7 @@ int dsi_init(struct platform_device *pdev)
3799 goto err1; 3308 goto err1;
3800 } 3309 }
3801 3310
3802 dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi"); 3311 dsi.vdds_dsi_reg = dss_get_vdds_dsi();
3803 if (IS_ERR(dsi.vdds_dsi_reg)) { 3312 if (IS_ERR(dsi.vdds_dsi_reg)) {
3804 iounmap(dsi.base); 3313 iounmap(dsi.base);
3805 DSSERR("can't get VDDS_DSI regulator\n"); 3314 DSSERR("can't get VDDS_DSI regulator\n");
@@ -3815,23 +3324,15 @@ int dsi_init(struct platform_device *pdev)
3815 3324
3816 enable_clocks(0); 3325 enable_clocks(0);
3817 3326
3818 wake_up_process(dsi.thread);
3819
3820 return 0; 3327 return 0;
3821err2: 3328err2:
3822 iounmap(dsi.base); 3329 iounmap(dsi.base);
3823err1: 3330err1:
3824 kthread_stop(dsi.thread);
3825err0:
3826 return r; 3331 return r;
3827} 3332}
3828 3333
3829void dsi_exit(void) 3334void dsi_exit(void)
3830{ 3335{
3831 kthread_stop(dsi.thread);
3832
3833 regulator_put(dsi.vdds_dsi_reg);
3834
3835 iounmap(dsi.base); 3336 iounmap(dsi.base);
3836 3337
3837 DSSDBG("omap_dsi_exit\n"); 3338 DSSDBG("omap_dsi_exit\n");
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 0a26b7d84d41..8254a4232a53 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -68,6 +68,9 @@ static struct {
68 struct dss_clock_info cache_dss_cinfo; 68 struct dss_clock_info cache_dss_cinfo;
69 struct dispc_clock_info cache_dispc_cinfo; 69 struct dispc_clock_info cache_dispc_cinfo;
70 70
71 enum dss_clk_source dsi_clk_source;
72 enum dss_clk_source dispc_clk_source;
73
71 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 74 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
72} dss; 75} dss;
73 76
@@ -247,23 +250,42 @@ void dss_dump_regs(struct seq_file *s)
247#undef DUMPREG 250#undef DUMPREG
248} 251}
249 252
250void dss_select_clk_source(bool dsi, bool dispc) 253void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
254{
255 int b;
256
257 BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK &&
258 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
259
260 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
261
262 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */
263
264 dss.dispc_clk_source = clk_src;
265}
266
267void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
251{ 268{
252 u32 r; 269 int b;
253 r = dss_read_reg(DSS_CONTROL); 270
254 r = FLD_MOD(r, dsi, 1, 1); /* DSI_CLK_SWITCH */ 271 BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK &&
255 r = FLD_MOD(r, dispc, 0, 0); /* DISPC_CLK_SWITCH */ 272 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
256 dss_write_reg(DSS_CONTROL, r); 273
274 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
275
276 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
277
278 dss.dsi_clk_source = clk_src;
257} 279}
258 280
259int dss_get_dsi_clk_source(void) 281enum dss_clk_source dss_get_dispc_clk_source(void)
260{ 282{
261 return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1); 283 return dss.dispc_clk_source;
262} 284}
263 285
264int dss_get_dispc_clk_source(void) 286enum dss_clk_source dss_get_dsi_clk_source(void)
265{ 287{
266 return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0); 288 return dss.dsi_clk_source;
267} 289}
268 290
269/* calculate clock rates using dividers in cinfo */ 291/* calculate clock rates using dividers in cinfo */
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 2bcb1245d6c2..24326a5fd292 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -119,6 +119,12 @@ enum dss_clock {
119 DSS_CLK_96M = 1 << 4, 119 DSS_CLK_96M = 1 << 4,
120}; 120};
121 121
122enum dss_clk_source {
123 DSS_SRC_DSI1_PLL_FCLK,
124 DSS_SRC_DSI2_PLL_FCLK,
125 DSS_SRC_DSS1_ALWON_FCLK,
126};
127
122struct dss_clock_info { 128struct dss_clock_info {
123 /* rates that we get with dividers below */ 129 /* rates that we get with dividers below */
124 unsigned long fck; 130 unsigned long fck;
@@ -169,6 +175,9 @@ unsigned long dss_clk_get_rate(enum dss_clock clk);
169int dss_need_ctx_restore(void); 175int dss_need_ctx_restore(void);
170void dss_dump_clocks(struct seq_file *s); 176void dss_dump_clocks(struct seq_file *s);
171struct bus_type *dss_get_bus(void); 177struct bus_type *dss_get_bus(void);
178struct regulator *dss_get_vdds_dsi(void);
179struct regulator *dss_get_vdds_sdi(void);
180struct regulator *dss_get_vdda_dac(void);
172 181
173/* display */ 182/* display */
174int dss_suspend_all_devices(void); 183int dss_suspend_all_devices(void);
@@ -216,9 +225,11 @@ void dss_sdi_init(u8 datapairs);
216int dss_sdi_enable(void); 225int dss_sdi_enable(void);
217void dss_sdi_disable(void); 226void dss_sdi_disable(void);
218 227
219void dss_select_clk_source(bool dsi, bool dispc); 228void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
220int dss_get_dsi_clk_source(void); 229void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
221int dss_get_dispc_clk_source(void); 230enum dss_clk_source dss_get_dispc_clk_source(void);
231enum dss_clk_source dss_get_dsi_clk_source(void);
232
222void dss_set_venc_output(enum omap_dss_venc_type type); 233void dss_set_venc_output(enum omap_dss_venc_type type);
223void dss_set_dac_pwrdn_bgz(bool enable); 234void dss_set_dac_pwrdn_bgz(bool enable);
224 235
@@ -261,7 +272,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
261 u32 *fifo_low, u32 *fifo_high); 272 u32 *fifo_low, u32 *fifo_high);
262 273
263/* DPI */ 274/* DPI */
264int dpi_init(void); 275int dpi_init(struct platform_device *pdev);
265void dpi_exit(void); 276void dpi_exit(void);
266int dpi_init_display(struct omap_dss_device *dssdev); 277int dpi_init_display(struct omap_dss_device *dssdev);
267 278
@@ -313,8 +324,8 @@ int dispc_setup_plane(enum omap_plane plane,
313 324
314bool dispc_go_busy(enum omap_channel channel); 325bool dispc_go_busy(enum omap_channel channel);
315void dispc_go(enum omap_channel channel); 326void dispc_go(enum omap_channel channel);
316void dispc_enable_lcd_out(bool enable); 327void dispc_enable_channel(enum omap_channel channel, bool enable);
317void dispc_enable_digit_out(bool enable); 328bool dispc_is_channel_enabled(enum omap_channel channel);
318int dispc_enable_plane(enum omap_plane plane, bool enable); 329int dispc_enable_plane(enum omap_plane plane, bool enable);
319void dispc_enable_replication(enum omap_plane plane, bool enable); 330void dispc_enable_replication(enum omap_plane plane, bool enable);
320 331
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 27d9c465c851..913142d4cab1 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -501,6 +501,19 @@ static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
501 return 0; 501 return 0;
502} 502}
503 503
504static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
505{
506 unsigned long timeout = msecs_to_jiffies(500);
507 u32 irq;
508
509 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
510 irq = DISPC_IRQ_EVSYNC_ODD;
511 else
512 irq = DISPC_IRQ_VSYNC;
513
514 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
515}
516
504static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) 517static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
505{ 518{
506 unsigned long timeout = msecs_to_jiffies(500); 519 unsigned long timeout = msecs_to_jiffies(500);
@@ -509,17 +522,18 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
509 u32 irq; 522 u32 irq;
510 int r; 523 int r;
511 int i; 524 int i;
525 struct omap_dss_device *dssdev = mgr->device;
512 526
513 if (!mgr->device) 527 if (!dssdev)
514 return 0; 528 return 0;
515 529
516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 530 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
517 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 531 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
518 channel = OMAP_DSS_CHANNEL_DIGIT; 532 channel = OMAP_DSS_CHANNEL_DIGIT;
519 } else { 533 } else {
520 if (mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 534 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
521 enum omap_dss_update_mode mode; 535 enum omap_dss_update_mode mode;
522 mode = mgr->device->get_update_mode(mgr->device); 536 mode = dssdev->driver->get_update_mode(dssdev);
523 if (mode != OMAP_DSS_UPDATE_AUTO) 537 if (mode != OMAP_DSS_UPDATE_AUTO)
524 return 0; 538 return 0;
525 539
@@ -592,7 +606,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
592 } else { 606 } else {
593 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 607 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
594 enum omap_dss_update_mode mode; 608 enum omap_dss_update_mode mode;
595 mode = dssdev->get_update_mode(dssdev); 609 mode = dssdev->driver->get_update_mode(dssdev);
596 if (mode != OMAP_DSS_UPDATE_AUTO) 610 if (mode != OMAP_DSS_UPDATE_AUTO)
597 return 0; 611 return 0;
598 612
@@ -1064,7 +1078,7 @@ void dss_start_update(struct omap_dss_device *dssdev)
1064 mc->shadow_dirty = false; 1078 mc->shadow_dirty = false;
1065 } 1079 }
1066 1080
1067 dispc_enable_lcd_out(1); 1081 dssdev->manager->enable(dssdev->manager);
1068} 1082}
1069 1083
1070static void dss_apply_irq_handler(void *data, u32 mask) 1084static void dss_apply_irq_handler(void *data, u32 mask)
@@ -1196,7 +1210,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1196 1210
1197 oc->manual_update = 1211 oc->manual_update =
1198 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && 1212 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
1199 dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; 1213 dssdev->driver->get_update_mode(dssdev) !=
1214 OMAP_DSS_UPDATE_AUTO;
1200 1215
1201 ++num_planes_enabled; 1216 ++num_planes_enabled;
1202 } 1217 }
@@ -1237,7 +1252,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1237 1252
1238 mc->manual_update = 1253 mc->manual_update =
1239 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && 1254 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
1240 dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; 1255 dssdev->driver->get_update_mode(dssdev) !=
1256 OMAP_DSS_UPDATE_AUTO;
1241 } 1257 }
1242 1258
1243 /* XXX TODO: Try to get fifomerge working. The problem is that it 1259 /* XXX TODO: Try to get fifomerge working. The problem is that it
@@ -1351,6 +1367,18 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
1351 *info = mgr->info; 1367 *info = mgr->info;
1352} 1368}
1353 1369
1370static int dss_mgr_enable(struct omap_overlay_manager *mgr)
1371{
1372 dispc_enable_channel(mgr->id, 1);
1373 return 0;
1374}
1375
1376static int dss_mgr_disable(struct omap_overlay_manager *mgr)
1377{
1378 dispc_enable_channel(mgr->id, 0);
1379 return 0;
1380}
1381
1354static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager) 1382static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
1355{ 1383{
1356 ++num_managers; 1384 ++num_managers;
@@ -1394,6 +1422,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1394 mgr->set_manager_info = &omap_dss_mgr_set_info; 1422 mgr->set_manager_info = &omap_dss_mgr_set_info;
1395 mgr->get_manager_info = &omap_dss_mgr_get_info; 1423 mgr->get_manager_info = &omap_dss_mgr_get_info;
1396 mgr->wait_for_go = &dss_mgr_wait_for_go; 1424 mgr->wait_for_go = &dss_mgr_wait_for_go;
1425 mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
1426
1427 mgr->enable = &dss_mgr_enable;
1428 mgr->disable = &dss_mgr_disable;
1397 1429
1398 mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC; 1430 mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC;
1399 1431
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index b7f9a7339842..0c5bea263ac6 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -350,7 +350,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
350 return -EINVAL; 350 return -EINVAL;
351 } 351 }
352 352
353 dssdev->get_resolution(dssdev, &dw, &dh); 353 dssdev->driver->get_resolution(dssdev, &dw, &dh);
354 354
355 DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n", 355 DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
356 ovl->id, 356 ovl->id,
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index b936495c065d..cc23f53cc62d 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -36,8 +36,6 @@
36#include <plat/display.h> 36#include <plat/display.h>
37#include "dss.h" 37#include "dss.h"
38 38
39/*#define MEASURE_PERF*/
40
41#define RFBI_BASE 0x48050800 39#define RFBI_BASE 0x48050800
42 40
43struct rfbi_reg { u16 idx; }; 41struct rfbi_reg { u16 idx; };
@@ -66,8 +64,6 @@ struct rfbi_reg { u16 idx; };
66#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090) 64#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090)
67#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094) 65#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094)
68 66
69#define RFBI_CMD_FIFO_LEN_BYTES (16 * sizeof(struct update_param))
70
71#define REG_FLD_MOD(idx, val, start, end) \ 67#define REG_FLD_MOD(idx, val, start, end) \
72 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end)) 68 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
73 69
@@ -102,7 +98,6 @@ enum update_cmd {
102 98
103static int rfbi_convert_timings(struct rfbi_timings *t); 99static int rfbi_convert_timings(struct rfbi_timings *t);
104static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 100static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
105static void process_cmd_fifo(void);
106 101
107static struct { 102static struct {
108 void __iomem *base; 103 void __iomem *base;
@@ -125,11 +120,6 @@ static struct {
125 struct completion cmd_done; 120 struct completion cmd_done;
126 atomic_t cmd_fifo_full; 121 atomic_t cmd_fifo_full;
127 atomic_t cmd_pending; 122 atomic_t cmd_pending;
128#ifdef MEASURE_PERF
129 unsigned perf_bytes;
130 ktime_t perf_setup_time;
131 ktime_t perf_start_time;
132#endif
133} rfbi; 123} rfbi;
134 124
135struct update_region { 125struct update_region {
@@ -139,16 +129,6 @@ struct update_region {
139 u16 h; 129 u16 h;
140}; 130};
141 131
142struct update_param {
143 u8 rfbi_module;
144 u8 cmd;
145
146 union {
147 struct update_region r;
148 struct completion *sync;
149 } par;
150};
151
152static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) 132static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
153{ 133{
154 __raw_writel(val, rfbi.base + idx.idx); 134 __raw_writel(val, rfbi.base + idx.idx);
@@ -321,55 +301,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
321} 301}
322EXPORT_SYMBOL(omap_rfbi_write_pixels); 302EXPORT_SYMBOL(omap_rfbi_write_pixels);
323 303
324#ifdef MEASURE_PERF
325static void perf_mark_setup(void)
326{
327 rfbi.perf_setup_time = ktime_get();
328}
329
330static void perf_mark_start(void)
331{
332 rfbi.perf_start_time = ktime_get();
333}
334
335static void perf_show(const char *name)
336{
337 ktime_t t, setup_time, trans_time;
338 u32 total_bytes;
339 u32 setup_us, trans_us, total_us;
340
341 t = ktime_get();
342
343 setup_time = ktime_sub(rfbi.perf_start_time, rfbi.perf_setup_time);
344 setup_us = (u32)ktime_to_us(setup_time);
345 if (setup_us == 0)
346 setup_us = 1;
347
348 trans_time = ktime_sub(t, rfbi.perf_start_time);
349 trans_us = (u32)ktime_to_us(trans_time);
350 if (trans_us == 0)
351 trans_us = 1;
352
353 total_us = setup_us + trans_us;
354
355 total_bytes = rfbi.perf_bytes;
356
357 DSSINFO("%s update %u us + %u us = %u us (%uHz), %u bytes, "
358 "%u kbytes/sec\n",
359 name,
360 setup_us,
361 trans_us,
362 total_us,
363 1000*1000 / total_us,
364 total_bytes,
365 total_bytes * 1000 / total_us);
366}
367#else
368#define perf_mark_setup()
369#define perf_mark_start()
370#define perf_show(x)
371#endif
372
373void rfbi_transfer_area(u16 width, u16 height, 304void rfbi_transfer_area(u16 width, u16 height,
374 void (callback)(void *data), void *data) 305 void (callback)(void *data), void *data)
375{ 306{
@@ -382,7 +313,7 @@ void rfbi_transfer_area(u16 width, u16 height,
382 313
383 dispc_set_lcd_size(width, height); 314 dispc_set_lcd_size(width, height);
384 315
385 dispc_enable_lcd_out(1); 316 dispc_enable_channel(OMAP_DSS_CHANNEL_LCD, true);
386 317
387 rfbi.framedone_callback = callback; 318 rfbi.framedone_callback = callback;
388 rfbi.framedone_callback_data = data; 319 rfbi.framedone_callback_data = data;
@@ -396,8 +327,6 @@ void rfbi_transfer_area(u16 width, u16 height,
396 if (!rfbi.te_enabled) 327 if (!rfbi.te_enabled)
397 l = FLD_MOD(l, 1, 4, 4); /* ITE */ 328 l = FLD_MOD(l, 1, 4, 4); /* ITE */
398 329
399 perf_mark_start();
400
401 rfbi_write_reg(RFBI_CONTROL, l); 330 rfbi_write_reg(RFBI_CONTROL, l);
402} 331}
403 332
@@ -407,8 +336,6 @@ static void framedone_callback(void *data, u32 mask)
407 336
408 DSSDBG("FRAMEDONE\n"); 337 DSSDBG("FRAMEDONE\n");
409 338
410 perf_show("DISPC");
411
412 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); 339 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
413 340
414 rfbi_enable_clocks(0); 341 rfbi_enable_clocks(0);
@@ -416,11 +343,10 @@ static void framedone_callback(void *data, u32 mask)
416 callback = rfbi.framedone_callback; 343 callback = rfbi.framedone_callback;
417 rfbi.framedone_callback = NULL; 344 rfbi.framedone_callback = NULL;
418 345
419 /*callback(rfbi.framedone_callback_data);*/ 346 if (callback != NULL)
347 callback(rfbi.framedone_callback_data);
420 348
421 atomic_set(&rfbi.cmd_pending, 0); 349 atomic_set(&rfbi.cmd_pending, 0);
422
423 process_cmd_fifo();
424} 350}
425 351
426#if 1 /* VERBOSE */ 352#if 1 /* VERBOSE */
@@ -937,52 +863,43 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
937} 863}
938EXPORT_SYMBOL(rfbi_configure); 864EXPORT_SYMBOL(rfbi_configure);
939 865
940static int rfbi_find_display(struct omap_dss_device *dssdev) 866int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
867 u16 *x, u16 *y, u16 *w, u16 *h)
941{ 868{
942 if (dssdev == rfbi.dssdev[0]) 869 u16 dw, dh;
943 return 0;
944 870
945 if (dssdev == rfbi.dssdev[1]) 871 dssdev->driver->get_resolution(dssdev, &dw, &dh);
946 return 1;
947 872
948 BUG(); 873 if (*x > dw || *y > dh)
949 return -1; 874 return -EINVAL;
950}
951 875
876 if (*x + *w > dw)
877 return -EINVAL;
952 878
953static void signal_fifo_waiters(void) 879 if (*y + *h > dh)
954{ 880 return -EINVAL;
955 if (atomic_read(&rfbi.cmd_fifo_full) > 0) {
956 /* DSSDBG("SIGNALING: Fifo not full for waiter!\n"); */
957 complete(&rfbi.cmd_done);
958 atomic_dec(&rfbi.cmd_fifo_full);
959 }
960}
961 881
962/* returns 1 for async op, and 0 for sync op */ 882 if (*w == 1)
963static int do_update(struct omap_dss_device *dssdev, struct update_region *upd) 883 return -EINVAL;
964{
965 u16 x = upd->x;
966 u16 y = upd->y;
967 u16 w = upd->w;
968 u16 h = upd->h;
969 884
970 perf_mark_setup(); 885 if (*w == 0 || *h == 0)
886 return -EINVAL;
971 887
972 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
973 /*dssdev->driver->enable_te(dssdev, 1); */ 889 dss_setup_partial_planes(dssdev, x, y, w, h);
974 dss_setup_partial_planes(dssdev, &x, &y, &w, &h); 890 dispc_set_lcd_size(*w, *h);
975 } 891 }
976 892
977#ifdef MEASURE_PERF 893 return 0;
978 rfbi.perf_bytes = w * h * 2; /* XXX always 16bit */ 894}
979#endif 895EXPORT_SYMBOL(omap_rfbi_prepare_update);
980
981 dssdev->driver->setup_update(dssdev, x, y, w, h);
982 896
897int omap_rfbi_update(struct omap_dss_device *dssdev,
898 u16 x, u16 y, u16 w, u16 h,
899 void (*callback)(void *), void *data)
900{
983 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 901 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
984 rfbi_transfer_area(w, h, NULL, NULL); 902 rfbi_transfer_area(w, h, callback, data);
985 return 1;
986 } else { 903 } else {
987 struct omap_overlay *ovl; 904 struct omap_overlay *ovl;
988 void __iomem *addr; 905 void __iomem *addr;
@@ -994,123 +911,12 @@ static int do_update(struct omap_dss_device *dssdev, struct update_region *upd)
994 911
995 omap_rfbi_write_pixels(addr, scr_width, x, y, w, h); 912 omap_rfbi_write_pixels(addr, scr_width, x, y, w, h);
996 913
997 perf_show("L4"); 914 callback(data);
998
999 return 0;
1000 } 915 }
1001}
1002
1003static void process_cmd_fifo(void)
1004{
1005 int len;
1006 struct update_param p;
1007 struct omap_dss_device *dssdev;
1008 unsigned long flags;
1009
1010 if (atomic_inc_return(&rfbi.cmd_pending) != 1)
1011 return;
1012
1013 while (true) {
1014 spin_lock_irqsave(&rfbi.cmd_lock, flags);
1015
1016 len = kfifo_out(&rfbi.cmd_fifo, (unsigned char *)&p,
1017 sizeof(struct update_param));
1018 if (len == 0) {
1019 DSSDBG("nothing more in fifo\n");
1020 atomic_set(&rfbi.cmd_pending, 0);
1021 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1022 break;
1023 }
1024
1025 /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/
1026
1027 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1028
1029 BUG_ON(len != sizeof(struct update_param));
1030 BUG_ON(p.rfbi_module > 1);
1031
1032 dssdev = rfbi.dssdev[p.rfbi_module];
1033
1034 if (p.cmd == RFBI_CMD_UPDATE) {
1035 if (do_update(dssdev, &p.par.r))
1036 break; /* async op */
1037 } else if (p.cmd == RFBI_CMD_SYNC) {
1038 DSSDBG("Signaling SYNC done!\n");
1039 complete(p.par.sync);
1040 } else
1041 BUG();
1042 }
1043
1044 signal_fifo_waiters();
1045}
1046 916
1047static void rfbi_push_cmd(struct update_param *p) 917 return 0;
1048{
1049 int ret;
1050
1051 while (1) {
1052 unsigned long flags;
1053 int available;
1054
1055 spin_lock_irqsave(&rfbi.cmd_lock, flags);
1056 available = RFBI_CMD_FIFO_LEN_BYTES -
1057 kfifo_len(&rfbi.cmd_fifo);
1058
1059/* DSSDBG("%d bytes left in fifo\n", available); */
1060 if (available < sizeof(struct update_param)) {
1061 DSSDBG("Going to wait because FIFO FULL..\n");
1062 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1063 atomic_inc(&rfbi.cmd_fifo_full);
1064 wait_for_completion(&rfbi.cmd_done);
1065 /*DSSDBG("Woke up because fifo not full anymore\n");*/
1066 continue;
1067 }
1068
1069 ret = kfifo_in(&rfbi.cmd_fifo, (unsigned char *)p,
1070 sizeof(struct update_param));
1071/* DSSDBG("pushed %d bytes\n", ret);*/
1072
1073 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1074
1075 BUG_ON(ret != sizeof(struct update_param));
1076
1077 break;
1078 }
1079}
1080
1081static void rfbi_push_update(int rfbi_module, int x, int y, int w, int h)
1082{
1083 struct update_param p;
1084
1085 p.rfbi_module = rfbi_module;
1086 p.cmd = RFBI_CMD_UPDATE;
1087
1088 p.par.r.x = x;
1089 p.par.r.y = y;
1090 p.par.r.w = w;
1091 p.par.r.h = h;
1092
1093 DSSDBG("RFBI pushed %d,%d %dx%d\n", x, y, w, h);
1094
1095 rfbi_push_cmd(&p);
1096
1097 process_cmd_fifo();
1098}
1099
1100static void rfbi_push_sync(int rfbi_module, struct completion *sync_comp)
1101{
1102 struct update_param p;
1103
1104 p.rfbi_module = rfbi_module;
1105 p.cmd = RFBI_CMD_SYNC;
1106 p.par.sync = sync_comp;
1107
1108 rfbi_push_cmd(&p);
1109
1110 DSSDBG("RFBI sync pushed to cmd fifo\n");
1111
1112 process_cmd_fifo();
1113} 918}
919EXPORT_SYMBOL(omap_rfbi_update);
1114 920
1115void rfbi_dump_regs(struct seq_file *s) 921void rfbi_dump_regs(struct seq_file *s)
1116{ 922{
@@ -1155,12 +961,8 @@ int rfbi_init(void)
1155{ 961{
1156 u32 rev; 962 u32 rev;
1157 u32 l; 963 u32 l;
1158 int r;
1159 964
1160 spin_lock_init(&rfbi.cmd_lock); 965 spin_lock_init(&rfbi.cmd_lock);
1161 r = kfifo_alloc(&rfbi.cmd_fifo, RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL);
1162 if (r)
1163 return r;
1164 966
1165 init_completion(&rfbi.cmd_done); 967 init_completion(&rfbi.cmd_done);
1166 atomic_set(&rfbi.cmd_fifo_full, 0); 968 atomic_set(&rfbi.cmd_fifo_full, 0);
@@ -1196,49 +998,10 @@ void rfbi_exit(void)
1196{ 998{
1197 DSSDBG("rfbi_exit\n"); 999 DSSDBG("rfbi_exit\n");
1198 1000
1199 kfifo_free(&rfbi.cmd_fifo);
1200
1201 iounmap(rfbi.base); 1001 iounmap(rfbi.base);
1202} 1002}
1203 1003
1204/* struct omap_display support */ 1004int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1205static int rfbi_display_update(struct omap_dss_device *dssdev,
1206 u16 x, u16 y, u16 w, u16 h)
1207{
1208 int rfbi_module;
1209
1210 if (w == 0 || h == 0)
1211 return 0;
1212
1213 rfbi_module = rfbi_find_display(dssdev);
1214
1215 rfbi_push_update(rfbi_module, x, y, w, h);
1216
1217 return 0;
1218}
1219
1220static int rfbi_display_sync(struct omap_dss_device *dssdev)
1221{
1222 struct completion sync_comp;
1223 int rfbi_module;
1224
1225 rfbi_module = rfbi_find_display(dssdev);
1226
1227 init_completion(&sync_comp);
1228 rfbi_push_sync(rfbi_module, &sync_comp);
1229 DSSDBG("Waiting for SYNC to happen...\n");
1230 wait_for_completion(&sync_comp);
1231 DSSDBG("Released from SYNC\n");
1232 return 0;
1233}
1234
1235static int rfbi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
1236{
1237 dssdev->driver->enable_te(dssdev, enable);
1238 return 0;
1239}
1240
1241static int rfbi_display_enable(struct omap_dss_device *dssdev)
1242{ 1005{
1243 int r; 1006 int r;
1244 1007
@@ -1269,41 +1032,25 @@ static int rfbi_display_enable(struct omap_dss_device *dssdev)
1269 &dssdev->ctrl.rfbi_timings); 1032 &dssdev->ctrl.rfbi_timings);
1270 1033
1271 1034
1272 if (dssdev->driver->enable) {
1273 r = dssdev->driver->enable(dssdev);
1274 if (r)
1275 goto err2;
1276 }
1277
1278 return 0; 1035 return 0;
1279err2:
1280 omap_dispc_unregister_isr(framedone_callback, NULL,
1281 DISPC_IRQ_FRAMEDONE);
1282err1: 1036err1:
1283 omap_dss_stop_device(dssdev); 1037 omap_dss_stop_device(dssdev);
1284err0: 1038err0:
1285 return r; 1039 return r;
1286} 1040}
1041EXPORT_SYMBOL(omapdss_rfbi_display_enable);
1287 1042
1288static void rfbi_display_disable(struct omap_dss_device *dssdev) 1043void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
1289{ 1044{
1290 dssdev->driver->disable(dssdev);
1291 omap_dispc_unregister_isr(framedone_callback, NULL, 1045 omap_dispc_unregister_isr(framedone_callback, NULL,
1292 DISPC_IRQ_FRAMEDONE); 1046 DISPC_IRQ_FRAMEDONE);
1293 omap_dss_stop_device(dssdev); 1047 omap_dss_stop_device(dssdev);
1294} 1048}
1049EXPORT_SYMBOL(omapdss_rfbi_display_disable);
1295 1050
1296int rfbi_init_display(struct omap_dss_device *dssdev) 1051int rfbi_init_display(struct omap_dss_device *dssdev)
1297{ 1052{
1298 dssdev->enable = rfbi_display_enable;
1299 dssdev->disable = rfbi_display_disable;
1300 dssdev->update = rfbi_display_update;
1301 dssdev->sync = rfbi_display_sync;
1302 dssdev->enable_te = rfbi_display_enable_te;
1303
1304 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; 1053 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
1305
1306 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 1054 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1307
1308 return 0; 1055 return 0;
1309} 1056}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index c24f307d3da1..12eb4042dd82 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -41,7 +41,7 @@ static void sdi_basic_init(void)
41 dispc_lcd_enable_signal_polarity(1); 41 dispc_lcd_enable_signal_polarity(1);
42} 42}
43 43
44static int sdi_display_enable(struct omap_dss_device *dssdev) 44int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
45{ 45{
46 struct omap_video_timings *t = &dssdev->panel.timings; 46 struct omap_video_timings *t = &dssdev->panel.timings;
47 struct dss_clock_info dss_cinfo; 47 struct dss_clock_info dss_cinfo;
@@ -57,12 +57,6 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
57 goto err0; 57 goto err0;
58 } 58 }
59 59
60 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
61 DSSERR("dssdev already enabled\n");
62 r = -EINVAL;
63 goto err1;
64 }
65
66 /* In case of skip_init sdi_init has already enabled the clocks */ 60 /* In case of skip_init sdi_init has already enabled the clocks */
67 if (!sdi.skip_init) 61 if (!sdi.skip_init)
68 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 62 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
@@ -119,7 +113,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
119 mdelay(2); 113 mdelay(2);
120 } 114 }
121 115
122 dispc_enable_lcd_out(1); 116 dssdev->manager->enable(dssdev->manager);
123 117
124 if (dssdev->driver->enable) { 118 if (dssdev->driver->enable) {
125 r = dssdev->driver->enable(dssdev); 119 r = dssdev->driver->enable(dssdev);
@@ -127,13 +121,11 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
127 goto err3; 121 goto err3;
128 } 122 }
129 123
130 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
131
132 sdi.skip_init = 0; 124 sdi.skip_init = 0;
133 125
134 return 0; 126 return 0;
135err3: 127err3:
136 dispc_enable_lcd_out(0); 128 dssdev->manager->disable(dssdev->manager);
137err2: 129err2:
138 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 130 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
139err1: 131err1:
@@ -141,120 +133,27 @@ err1:
141err0: 133err0:
142 return r; 134 return r;
143} 135}
136EXPORT_SYMBOL(omapdss_sdi_display_enable);
144 137
145static int sdi_display_resume(struct omap_dss_device *dssdev); 138void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
146
147static void sdi_display_disable(struct omap_dss_device *dssdev)
148{ 139{
149 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
150 return;
151
152 if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
153 if (sdi_display_resume(dssdev))
154 return;
155
156 if (dssdev->driver->disable) 140 if (dssdev->driver->disable)
157 dssdev->driver->disable(dssdev); 141 dssdev->driver->disable(dssdev);
158 142
159 dispc_enable_lcd_out(0); 143 dssdev->manager->disable(dssdev->manager);
160 144
161 dss_sdi_disable(); 145 dss_sdi_disable();
162 146
163 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 147 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
164 148
165 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
166
167 omap_dss_stop_device(dssdev); 149 omap_dss_stop_device(dssdev);
168} 150}
169 151EXPORT_SYMBOL(omapdss_sdi_display_disable);
170static int sdi_display_suspend(struct omap_dss_device *dssdev)
171{
172 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
173 return -EINVAL;
174
175 if (dssdev->driver->suspend)
176 dssdev->driver->suspend(dssdev);
177
178 dispc_enable_lcd_out(0);
179
180 dss_sdi_disable();
181
182 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
183
184 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
185
186 return 0;
187}
188
189static int sdi_display_resume(struct omap_dss_device *dssdev)
190{
191 int r;
192
193 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
194 return -EINVAL;
195
196 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
197
198 r = dss_sdi_enable();
199 if (r)
200 goto err;
201 mdelay(2);
202
203 dispc_enable_lcd_out(1);
204
205 if (dssdev->driver->resume)
206 dssdev->driver->resume(dssdev);
207
208 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
209
210 return 0;
211err:
212 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
213 return r;
214}
215
216static int sdi_display_set_update_mode(struct omap_dss_device *dssdev,
217 enum omap_dss_update_mode mode)
218{
219 if (mode == OMAP_DSS_UPDATE_MANUAL)
220 return -EINVAL;
221
222 if (mode == OMAP_DSS_UPDATE_DISABLED) {
223 dispc_enable_lcd_out(0);
224 sdi.update_enabled = 0;
225 } else {
226 dispc_enable_lcd_out(1);
227 sdi.update_enabled = 1;
228 }
229
230 return 0;
231}
232
233static enum omap_dss_update_mode sdi_display_get_update_mode(
234 struct omap_dss_device *dssdev)
235{
236 return sdi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
237 OMAP_DSS_UPDATE_DISABLED;
238}
239
240static void sdi_get_timings(struct omap_dss_device *dssdev,
241 struct omap_video_timings *timings)
242{
243 *timings = dssdev->panel.timings;
244}
245 152
246int sdi_init_display(struct omap_dss_device *dssdev) 153int sdi_init_display(struct omap_dss_device *dssdev)
247{ 154{
248 DSSDBG("SDI init\n"); 155 DSSDBG("SDI init\n");
249 156
250 dssdev->enable = sdi_display_enable;
251 dssdev->disable = sdi_display_disable;
252 dssdev->suspend = sdi_display_suspend;
253 dssdev->resume = sdi_display_resume;
254 dssdev->set_update_mode = sdi_display_set_update_mode;
255 dssdev->get_update_mode = sdi_display_get_update_mode;
256 dssdev->get_timings = sdi_get_timings;
257
258 return 0; 157 return 0;
259} 158}
260 159
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 749a5a0f5be4..f0ba5732d84a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -400,114 +400,6 @@ static const struct venc_config *venc_timings_to_config(
400 BUG(); 400 BUG();
401} 401}
402 402
403
404
405
406
407/* driver */
408static int venc_panel_probe(struct omap_dss_device *dssdev)
409{
410 dssdev->panel.timings = omap_dss_pal_timings;
411
412 return 0;
413}
414
415static void venc_panel_remove(struct omap_dss_device *dssdev)
416{
417}
418
419static int venc_panel_enable(struct omap_dss_device *dssdev)
420{
421 int r = 0;
422
423 /* wait couple of vsyncs until enabling the LCD */
424 msleep(50);
425
426 if (dssdev->platform_enable)
427 r = dssdev->platform_enable(dssdev);
428
429 return r;
430}
431
432static void venc_panel_disable(struct omap_dss_device *dssdev)
433{
434 if (dssdev->platform_disable)
435 dssdev->platform_disable(dssdev);
436
437 /* wait at least 5 vsyncs after disabling the LCD */
438
439 msleep(100);
440}
441
442static int venc_panel_suspend(struct omap_dss_device *dssdev)
443{
444 venc_panel_disable(dssdev);
445 return 0;
446}
447
448static int venc_panel_resume(struct omap_dss_device *dssdev)
449{
450 return venc_panel_enable(dssdev);
451}
452
453static struct omap_dss_driver venc_driver = {
454 .probe = venc_panel_probe,
455 .remove = venc_panel_remove,
456
457 .enable = venc_panel_enable,
458 .disable = venc_panel_disable,
459 .suspend = venc_panel_suspend,
460 .resume = venc_panel_resume,
461
462 .driver = {
463 .name = "venc",
464 .owner = THIS_MODULE,
465 },
466};
467/* driver end */
468
469
470
471int venc_init(struct platform_device *pdev)
472{
473 u8 rev_id;
474
475 mutex_init(&venc.venc_lock);
476
477 venc.wss_data = 0;
478
479 venc.base = ioremap(VENC_BASE, SZ_1K);
480 if (!venc.base) {
481 DSSERR("can't ioremap VENC\n");
482 return -ENOMEM;
483 }
484
485 venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac");
486 if (IS_ERR(venc.vdda_dac_reg)) {
487 iounmap(venc.base);
488 DSSERR("can't get VDDA_DAC regulator\n");
489 return PTR_ERR(venc.vdda_dac_reg);
490 }
491
492 venc_enable_clocks(1);
493
494 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
495 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
496
497 venc_enable_clocks(0);
498
499 return omap_dss_register_driver(&venc_driver);
500}
501
502void venc_exit(void)
503{
504 omap_dss_unregister_driver(&venc_driver);
505
506 regulator_put(venc.vdda_dac_reg);
507
508 iounmap(venc.base);
509}
510
511static void venc_power_on(struct omap_dss_device *dssdev) 403static void venc_power_on(struct omap_dss_device *dssdev)
512{ 404{
513 u32 l; 405 u32 l;
@@ -540,7 +432,7 @@ static void venc_power_on(struct omap_dss_device *dssdev)
540 if (dssdev->platform_enable) 432 if (dssdev->platform_enable)
541 dssdev->platform_enable(dssdev); 433 dssdev->platform_enable(dssdev);
542 434
543 dispc_enable_digit_out(1); 435 dssdev->manager->enable(dssdev->manager);
544} 436}
545 437
546static void venc_power_off(struct omap_dss_device *dssdev) 438static void venc_power_off(struct omap_dss_device *dssdev)
@@ -548,7 +440,7 @@ static void venc_power_off(struct omap_dss_device *dssdev)
548 venc_write_reg(VENC_OUTPUT_CONTROL, 0); 440 venc_write_reg(VENC_OUTPUT_CONTROL, 0);
549 dss_set_dac_pwrdn_bgz(0); 441 dss_set_dac_pwrdn_bgz(0);
550 442
551 dispc_enable_digit_out(0); 443 dssdev->manager->disable(dssdev->manager);
552 444
553 if (dssdev->platform_disable) 445 if (dssdev->platform_disable)
554 dssdev->platform_disable(dssdev); 446 dssdev->platform_disable(dssdev);
@@ -558,7 +450,23 @@ static void venc_power_off(struct omap_dss_device *dssdev)
558 venc_enable_clocks(0); 450 venc_enable_clocks(0);
559} 451}
560 452
561static int venc_enable_display(struct omap_dss_device *dssdev) 453
454
455
456
457/* driver */
458static int venc_panel_probe(struct omap_dss_device *dssdev)
459{
460 dssdev->panel.timings = omap_dss_pal_timings;
461
462 return 0;
463}
464
465static void venc_panel_remove(struct omap_dss_device *dssdev)
466{
467}
468
469static int venc_panel_enable(struct omap_dss_device *dssdev)
562{ 470{
563 int r = 0; 471 int r = 0;
564 472
@@ -568,7 +476,13 @@ static int venc_enable_display(struct omap_dss_device *dssdev)
568 476
569 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 477 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
570 r = -EINVAL; 478 r = -EINVAL;
571 goto err; 479 goto err1;
480 }
481
482 if (dssdev->platform_enable) {
483 r = dssdev->platform_enable(dssdev);
484 if (r)
485 goto err2;
572 } 486 }
573 487
574 venc_power_on(dssdev); 488 venc_power_on(dssdev);
@@ -576,13 +490,21 @@ static int venc_enable_display(struct omap_dss_device *dssdev)
576 venc.wss_data = 0; 490 venc.wss_data = 0;
577 491
578 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 492 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
579err: 493
494 /* wait couple of vsyncs until enabling the LCD */
495 msleep(50);
496
580 mutex_unlock(&venc.venc_lock); 497 mutex_unlock(&venc.venc_lock);
581 498
582 return r; 499 return r;
500err2:
501 venc_power_off(dssdev);
502err1:
503 mutex_unlock(&venc.venc_lock);
504 return r;
583} 505}
584 506
585static void venc_disable_display(struct omap_dss_device *dssdev) 507static void venc_panel_disable(struct omap_dss_device *dssdev)
586{ 508{
587 DSSDBG("venc_disable_display\n"); 509 DSSDBG("venc_disable_display\n");
588 510
@@ -599,53 +521,40 @@ static void venc_disable_display(struct omap_dss_device *dssdev)
599 521
600 venc_power_off(dssdev); 522 venc_power_off(dssdev);
601 523
524 /* wait at least 5 vsyncs after disabling the LCD */
525 msleep(100);
526
527 if (dssdev->platform_disable)
528 dssdev->platform_disable(dssdev);
529
602 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 530 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
603end: 531end:
604 mutex_unlock(&venc.venc_lock); 532 mutex_unlock(&venc.venc_lock);
605} 533}
606 534
607static int venc_display_suspend(struct omap_dss_device *dssdev) 535static int venc_panel_suspend(struct omap_dss_device *dssdev)
608{ 536{
609 int r = 0; 537 venc_panel_disable(dssdev);
610 538 return 0;
611 DSSDBG("venc_display_suspend\n");
612
613 mutex_lock(&venc.venc_lock);
614
615 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
616 r = -EINVAL;
617 goto err;
618 }
619
620 venc_power_off(dssdev);
621
622 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
623err:
624 mutex_unlock(&venc.venc_lock);
625
626 return r;
627} 539}
628 540
629static int venc_display_resume(struct omap_dss_device *dssdev) 541static int venc_panel_resume(struct omap_dss_device *dssdev)
630{ 542{
631 int r = 0; 543 return venc_panel_enable(dssdev);
632 544}
633 DSSDBG("venc_display_resume\n");
634
635 mutex_lock(&venc.venc_lock);
636
637 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
638 r = -EINVAL;
639 goto err;
640 }
641
642 venc_power_on(dssdev);
643 545
644 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 546static enum omap_dss_update_mode venc_get_update_mode(
645err: 547 struct omap_dss_device *dssdev)
646 mutex_unlock(&venc.venc_lock); 548{
549 return OMAP_DSS_UPDATE_AUTO;
550}
647 551
648 return r; 552static int venc_set_update_mode(struct omap_dss_device *dssdev,
553 enum omap_dss_update_mode mode)
554{
555 if (mode != OMAP_DSS_UPDATE_AUTO)
556 return -EINVAL;
557 return 0;
649} 558}
650 559
651static void venc_get_timings(struct omap_dss_device *dssdev, 560static void venc_get_timings(struct omap_dss_device *dssdev,
@@ -666,8 +575,8 @@ static void venc_set_timings(struct omap_dss_device *dssdev,
666 dssdev->panel.timings = *timings; 575 dssdev->panel.timings = *timings;
667 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 576 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
668 /* turn the venc off and on to get new timings to use */ 577 /* turn the venc off and on to get new timings to use */
669 venc_disable_display(dssdev); 578 venc_panel_disable(dssdev);
670 venc_enable_display(dssdev); 579 venc_panel_enable(dssdev);
671 } 580 }
672} 581}
673 582
@@ -716,30 +625,79 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
716 return 0; 625 return 0;
717} 626}
718 627
719static enum omap_dss_update_mode venc_display_get_update_mode( 628static struct omap_dss_driver venc_driver = {
720 struct omap_dss_device *dssdev) 629 .probe = venc_panel_probe,
630 .remove = venc_panel_remove,
631
632 .enable = venc_panel_enable,
633 .disable = venc_panel_disable,
634 .suspend = venc_panel_suspend,
635 .resume = venc_panel_resume,
636
637 .get_resolution = omapdss_default_get_resolution,
638 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
639
640 .set_update_mode = venc_set_update_mode,
641 .get_update_mode = venc_get_update_mode,
642
643 .get_timings = venc_get_timings,
644 .set_timings = venc_set_timings,
645 .check_timings = venc_check_timings,
646
647 .get_wss = venc_get_wss,
648 .set_wss = venc_set_wss,
649
650 .driver = {
651 .name = "venc",
652 .owner = THIS_MODULE,
653 },
654};
655/* driver end */
656
657
658
659int venc_init(struct platform_device *pdev)
721{ 660{
722 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 661 u8 rev_id;
723 return OMAP_DSS_UPDATE_AUTO; 662
724 else 663 mutex_init(&venc.venc_lock);
725 return OMAP_DSS_UPDATE_DISABLED; 664
665 venc.wss_data = 0;
666
667 venc.base = ioremap(VENC_BASE, SZ_1K);
668 if (!venc.base) {
669 DSSERR("can't ioremap VENC\n");
670 return -ENOMEM;
671 }
672
673 venc.vdda_dac_reg = dss_get_vdda_dac();
674 if (IS_ERR(venc.vdda_dac_reg)) {
675 iounmap(venc.base);
676 DSSERR("can't get VDDA_DAC regulator\n");
677 return PTR_ERR(venc.vdda_dac_reg);
678 }
679
680 venc_enable_clocks(1);
681
682 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
683 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
684
685 venc_enable_clocks(0);
686
687 return omap_dss_register_driver(&venc_driver);
688}
689
690void venc_exit(void)
691{
692 omap_dss_unregister_driver(&venc_driver);
693
694 iounmap(venc.base);
726} 695}
727 696
728int venc_init_display(struct omap_dss_device *dssdev) 697int venc_init_display(struct omap_dss_device *dssdev)
729{ 698{
730 DSSDBG("init_display\n"); 699 DSSDBG("init_display\n");
731 700
732 dssdev->enable = venc_enable_display;
733 dssdev->disable = venc_disable_display;
734 dssdev->suspend = venc_display_suspend;
735 dssdev->resume = venc_display_resume;
736 dssdev->get_timings = venc_get_timings;
737 dssdev->set_timings = venc_set_timings;
738 dssdev->check_timings = venc_check_timings;
739 dssdev->get_wss = venc_get_wss;
740 dssdev->set_wss = venc_set_wss;
741 dssdev->get_update_mode = venc_display_get_update_mode;
742
743 return 0; 701 return 0;
744} 702}
745 703