diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-01-13 00:04:04 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-01-13 00:04:04 -0500 |
| commit | 90aeb7c01c2da631cb611871a50980cbb6ca7149 (patch) | |
| tree | 0f46706d61bd5f125e351cfa3a133b88a27bdc1f | |
| parent | 2c761270d5520dd84ab0b4e47c24d99ff8503c38 (diff) | |
| parent | 807a7515aea421f2b340140482ed4c8811c523c6 (diff) | |
Merge branch 'for-linus' of git://gitorious.org/linux-omap-dss2/linux
* 'for-linus' of git://gitorious.org/linux-omap-dss2/linux:
OMAP: DSS2: OMAPFB: fix crash when panel driver was not loaded
OMAP: DSS2: Reject scaling settings when they cannot be supported
OMAP: DSS2: Make check-delay-loops consistent
OMAP: DSS2: OMAPFB: fix omapfb_free_fbmem()
video/omap: add __init/__exit macros to drivers/video/omap/lcd_htcherald.c
OMAP: DSS2: Fix compile warning
MAINTAINERS: Combine DSS2 and OMAPFB2 into one entry
MAINTAINERS: change omapfb maintainer
OMAP: OMAPFB: add dummy release function for omapdss
OMAP: OMAPFB: fix clk_get for RFBI
OMAP: DSS2: RFBI: convert to new kfifo API
OMAP: DSS2: Fix crash when panel doesn't define enable_te()
OMAP: DSS2: Collect interrupt statistics
OMAP: DSS2: DSI: print debug DCS cmd in hex
OMAP: DSS2: DSI: fix VC channels in send_short and send_null
| -rw-r--r-- | MAINTAINERS | 17 | ||||
| -rw-r--r-- | drivers/video/omap/dispc.c | 18 | ||||
| -rw-r--r-- | drivers/video/omap/lcd_htcherald.c | 4 | ||||
| -rw-r--r-- | drivers/video/omap/omapfb.h | 2 | ||||
| -rw-r--r-- | drivers/video/omap/omapfb_main.c | 25 | ||||
| -rw-r--r-- | drivers/video/omap/rfbi.c | 4 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/core.c | 10 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/dispc.c | 74 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/dsi.c | 159 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/dss.c | 6 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/dss.h | 14 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/rfbi.c | 30 | ||||
| -rw-r--r-- | drivers/video/omap2/omapfb/omapfb-main.c | 6 |
14 files changed, 309 insertions, 67 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 6914588eef89..c8f47bf154f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -3940,29 +3940,20 @@ S: Maintained | |||
| 3940 | F: sound/soc/omap/ | 3940 | F: sound/soc/omap/ |
| 3941 | 3941 | ||
| 3942 | OMAP FRAMEBUFFER SUPPORT | 3942 | OMAP FRAMEBUFFER SUPPORT |
| 3943 | M: Imre Deak <imre.deak@nokia.com> | 3943 | M: Tomi Valkeinen <tomi.valkeinen@nokia.com> |
| 3944 | L: linux-fbdev@vger.kernel.org | 3944 | L: linux-fbdev@vger.kernel.org |
| 3945 | L: linux-omap@vger.kernel.org | 3945 | L: linux-omap@vger.kernel.org |
| 3946 | S: Maintained | 3946 | S: Maintained |
| 3947 | F: drivers/video/omap/ | 3947 | F: drivers/video/omap/ |
| 3948 | 3948 | ||
| 3949 | OMAP DISPLAY SUBSYSTEM SUPPORT (DSS2) | 3949 | OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2) |
| 3950 | M: Tomi Valkeinen <tomi.valkeinen@nokia.com> | 3950 | M: Tomi Valkeinen <tomi.valkeinen@nokia.com> |
| 3951 | L: linux-omap@vger.kernel.org | 3951 | L: linux-omap@vger.kernel.org |
| 3952 | L: linux-fbdev@vger.kernel.org (moderated for non-subscribers) | 3952 | L: linux-fbdev@vger.kernel.org |
| 3953 | S: Maintained | 3953 | S: Maintained |
| 3954 | F: drivers/video/omap2/dss/ | 3954 | F: drivers/video/omap2/ |
| 3955 | F: drivers/video/omap2/vrfb.c | ||
| 3956 | F: drivers/video/omap2/vram.c | ||
| 3957 | F: Documentation/arm/OMAP/DSS | 3955 | F: Documentation/arm/OMAP/DSS |
| 3958 | 3956 | ||
| 3959 | OMAP FRAMEBUFFER SUPPORT (FOR DSS2) | ||
| 3960 | M: Tomi Valkeinen <tomi.valkeinen@nokia.com> | ||
| 3961 | L: linux-omap@vger.kernel.org | ||
| 3962 | L: linux-fbdev@vger.kernel.org (moderated for non-subscribers) | ||
| 3963 | S: Maintained | ||
| 3964 | F: drivers/video/omap2/omapfb/ | ||
| 3965 | |||
| 3966 | OMAP MMC SUPPORT | 3957 | OMAP MMC SUPPORT |
| 3967 | M: Jarkko Lavinen <jarkko.lavinen@nokia.com> | 3958 | M: Jarkko Lavinen <jarkko.lavinen@nokia.com> |
| 3968 | L: linux-omap@vger.kernel.org | 3959 | L: linux-omap@vger.kernel.org |
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index c7c6455f1fa8..e192b058a688 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c | |||
| @@ -189,11 +189,6 @@ static struct { | |||
| 189 | struct omapfb_color_key color_key; | 189 | struct omapfb_color_key color_key; |
| 190 | } dispc; | 190 | } dispc; |
| 191 | 191 | ||
| 192 | static struct platform_device omapdss_device = { | ||
| 193 | .name = "omapdss", | ||
| 194 | .id = -1, | ||
| 195 | }; | ||
| 196 | |||
| 197 | static void enable_lcd_clocks(int enable); | 192 | static void enable_lcd_clocks(int enable); |
| 198 | 193 | ||
| 199 | static void inline dispc_write_reg(int idx, u32 val) | 194 | static void inline dispc_write_reg(int idx, u32 val) |
| @@ -920,20 +915,20 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) | |||
| 920 | 915 | ||
| 921 | static int get_dss_clocks(void) | 916 | static int get_dss_clocks(void) |
| 922 | { | 917 | { |
| 923 | dispc.dss_ick = clk_get(&omapdss_device.dev, "ick"); | 918 | dispc.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick"); |
| 924 | if (IS_ERR(dispc.dss_ick)) { | 919 | if (IS_ERR(dispc.dss_ick)) { |
| 925 | dev_err(dispc.fbdev->dev, "can't get ick\n"); | 920 | dev_err(dispc.fbdev->dev, "can't get ick\n"); |
| 926 | return PTR_ERR(dispc.dss_ick); | 921 | return PTR_ERR(dispc.dss_ick); |
| 927 | } | 922 | } |
| 928 | 923 | ||
| 929 | dispc.dss1_fck = clk_get(&omapdss_device.dev, "dss1_fck"); | 924 | dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck"); |
| 930 | if (IS_ERR(dispc.dss1_fck)) { | 925 | if (IS_ERR(dispc.dss1_fck)) { |
| 931 | dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); | 926 | dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); |
| 932 | clk_put(dispc.dss_ick); | 927 | clk_put(dispc.dss_ick); |
| 933 | return PTR_ERR(dispc.dss1_fck); | 928 | return PTR_ERR(dispc.dss1_fck); |
| 934 | } | 929 | } |
| 935 | 930 | ||
| 936 | dispc.dss_54m_fck = clk_get(&omapdss_device.dev, "tv_fck"); | 931 | dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_fck"); |
| 937 | if (IS_ERR(dispc.dss_54m_fck)) { | 932 | if (IS_ERR(dispc.dss_54m_fck)) { |
| 938 | dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); | 933 | dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); |
| 939 | clk_put(dispc.dss_ick); | 934 | clk_put(dispc.dss_ick); |
| @@ -1385,12 +1380,6 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, | |||
| 1385 | int skip_init = 0; | 1380 | int skip_init = 0; |
| 1386 | int i; | 1381 | int i; |
| 1387 | 1382 | ||
| 1388 | r = platform_device_register(&omapdss_device); | ||
| 1389 | if (r) { | ||
| 1390 | dev_err(fbdev->dev, "can't register omapdss device\n"); | ||
| 1391 | return r; | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | memset(&dispc, 0, sizeof(dispc)); | 1383 | memset(&dispc, 0, sizeof(dispc)); |
| 1395 | 1384 | ||
| 1396 | dispc.base = ioremap(DISPC_BASE, SZ_1K); | 1385 | dispc.base = ioremap(DISPC_BASE, SZ_1K); |
| @@ -1534,7 +1523,6 @@ static void omap_dispc_cleanup(void) | |||
| 1534 | free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); | 1523 | free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); |
| 1535 | put_dss_clocks(); | 1524 | put_dss_clocks(); |
| 1536 | iounmap(dispc.base); | 1525 | iounmap(dispc.base); |
| 1537 | platform_device_unregister(&omapdss_device); | ||
| 1538 | } | 1526 | } |
| 1539 | 1527 | ||
| 1540 | const struct lcd_ctrl omap2_int_ctrl = { | 1528 | const struct lcd_ctrl omap2_int_ctrl = { |
diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/omap/lcd_htcherald.c index a9007c5d1fad..4802419da83b 100644 --- a/drivers/video/omap/lcd_htcherald.c +++ b/drivers/video/omap/lcd_htcherald.c | |||
| @@ -115,12 +115,12 @@ struct platform_driver htcherald_panel_driver = { | |||
| 115 | }, | 115 | }, |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | static int htcherald_panel_drv_init(void) | 118 | static int __init htcherald_panel_drv_init(void) |
| 119 | { | 119 | { |
| 120 | return platform_driver_register(&htcherald_panel_driver); | 120 | return platform_driver_register(&htcherald_panel_driver); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | static void htcherald_panel_drv_cleanup(void) | 123 | static void __exit htcherald_panel_drv_cleanup(void) |
| 124 | { | 124 | { |
| 125 | platform_driver_unregister(&htcherald_panel_driver); | 125 | platform_driver_unregister(&htcherald_panel_driver); |
| 126 | } | 126 | } |
diff --git a/drivers/video/omap/omapfb.h b/drivers/video/omap/omapfb.h index 46e4714014e8..af3c9e571ec3 100644 --- a/drivers/video/omap/omapfb.h +++ b/drivers/video/omap/omapfb.h | |||
| @@ -203,6 +203,8 @@ struct omapfb_device { | |||
| 203 | 203 | ||
| 204 | struct omapfb_mem_desc mem_desc; | 204 | struct omapfb_mem_desc mem_desc; |
| 205 | struct fb_info *fb_info[OMAPFB_PLANE_NUM]; | 205 | struct fb_info *fb_info[OMAPFB_PLANE_NUM]; |
| 206 | |||
| 207 | struct platform_device *dssdev; /* dummy dev for clocks */ | ||
| 206 | }; | 208 | }; |
| 207 | 209 | ||
| 208 | #ifdef CONFIG_ARCH_OMAP1 | 210 | #ifdef CONFIG_ARCH_OMAP1 |
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index c7f59a5ccdbc..2c4f470fa086 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c | |||
| @@ -83,6 +83,19 @@ static struct caps_table_struct color_caps[] = { | |||
| 83 | { 1 << OMAPFB_COLOR_YUY422, "YUY422", }, | 83 | { 1 << OMAPFB_COLOR_YUY422, "YUY422", }, |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | static void omapdss_release(struct device *dev) | ||
| 87 | { | ||
| 88 | } | ||
| 89 | |||
| 90 | /* dummy device for clocks */ | ||
| 91 | static struct platform_device omapdss_device = { | ||
| 92 | .name = "omapdss", | ||
| 93 | .id = -1, | ||
| 94 | .dev = { | ||
| 95 | .release = omapdss_release, | ||
| 96 | }, | ||
| 97 | }; | ||
| 98 | |||
| 86 | /* | 99 | /* |
| 87 | * --------------------------------------------------------------------------- | 100 | * --------------------------------------------------------------------------- |
| 88 | * LCD panel | 101 | * LCD panel |
| @@ -1700,6 +1713,7 @@ static int omapfb_do_probe(struct platform_device *pdev, | |||
| 1700 | 1713 | ||
| 1701 | fbdev->dev = &pdev->dev; | 1714 | fbdev->dev = &pdev->dev; |
| 1702 | fbdev->panel = panel; | 1715 | fbdev->panel = panel; |
| 1716 | fbdev->dssdev = &omapdss_device; | ||
| 1703 | platform_set_drvdata(pdev, fbdev); | 1717 | platform_set_drvdata(pdev, fbdev); |
| 1704 | 1718 | ||
| 1705 | mutex_init(&fbdev->rqueue_mutex); | 1719 | mutex_init(&fbdev->rqueue_mutex); |
| @@ -1814,8 +1828,16 @@ cleanup: | |||
| 1814 | 1828 | ||
| 1815 | static int omapfb_probe(struct platform_device *pdev) | 1829 | static int omapfb_probe(struct platform_device *pdev) |
| 1816 | { | 1830 | { |
| 1831 | int r; | ||
| 1832 | |||
| 1817 | BUG_ON(fbdev_pdev != NULL); | 1833 | BUG_ON(fbdev_pdev != NULL); |
| 1818 | 1834 | ||
| 1835 | r = platform_device_register(&omapdss_device); | ||
| 1836 | if (r) { | ||
| 1837 | dev_err(&pdev->dev, "can't register omapdss device\n"); | ||
| 1838 | return r; | ||
| 1839 | } | ||
| 1840 | |||
| 1819 | /* Delay actual initialization until the LCD is registered */ | 1841 | /* Delay actual initialization until the LCD is registered */ |
| 1820 | fbdev_pdev = pdev; | 1842 | fbdev_pdev = pdev; |
| 1821 | if (fbdev_panel != NULL) | 1843 | if (fbdev_panel != NULL) |
| @@ -1843,6 +1865,9 @@ static int omapfb_remove(struct platform_device *pdev) | |||
| 1843 | fbdev->state = OMAPFB_DISABLED; | 1865 | fbdev->state = OMAPFB_DISABLED; |
| 1844 | omapfb_free_resources(fbdev, saved_state); | 1866 | omapfb_free_resources(fbdev, saved_state); |
| 1845 | 1867 | ||
| 1868 | platform_device_unregister(&omapdss_device); | ||
| 1869 | fbdev->dssdev = NULL; | ||
| 1870 | |||
| 1846 | return 0; | 1871 | return 0; |
| 1847 | } | 1872 | } |
| 1848 | 1873 | ||
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index fed7b1bda19c..1162603c72e5 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c | |||
| @@ -83,13 +83,13 @@ static inline u32 rfbi_read_reg(int idx) | |||
| 83 | 83 | ||
| 84 | static int rfbi_get_clocks(void) | 84 | static int rfbi_get_clocks(void) |
| 85 | { | 85 | { |
| 86 | rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "ick"); | 86 | rfbi.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick"); |
| 87 | if (IS_ERR(rfbi.dss_ick)) { | 87 | if (IS_ERR(rfbi.dss_ick)) { |
| 88 | dev_err(rfbi.fbdev->dev, "can't get ick\n"); | 88 | dev_err(rfbi.fbdev->dev, "can't get ick\n"); |
| 89 | return PTR_ERR(rfbi.dss_ick); | 89 | return PTR_ERR(rfbi.dss_ick); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck"); | 92 | rfbi.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck"); |
| 93 | if (IS_ERR(rfbi.dss1_fck)) { | 93 | if (IS_ERR(rfbi.dss1_fck)) { |
| 94 | dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); | 94 | dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); |
| 95 | clk_put(rfbi.dss_ick); | 95 | clk_put(rfbi.dss_ick); |
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index 71d8dec30635..c63ce767b277 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig | |||
| @@ -25,6 +25,13 @@ config OMAP2_DSS_DEBUG_SUPPORT | |||
| 25 | This enables debug messages. You need to enable printing | 25 | This enables debug messages. You need to enable printing |
| 26 | with 'debug' module parameter. | 26 | with 'debug' module parameter. |
| 27 | 27 | ||
| 28 | config OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 29 | bool "Collect DSS IRQ statistics" | ||
| 30 | depends on OMAP2_DSS_DEBUG_SUPPORT | ||
| 31 | default n | ||
| 32 | help | ||
| 33 | Collect DSS IRQ statistics, printable via debugfs | ||
| 34 | |||
| 28 | config OMAP2_DSS_RFBI | 35 | config OMAP2_DSS_RFBI |
| 29 | bool "RFBI support" | 36 | bool "RFBI support" |
| 30 | default n | 37 | default n |
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 29497a0c9a91..82918eec6d2e 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c | |||
| @@ -124,6 +124,7 @@ static void restore_all_ctx(void) | |||
| 124 | dss_clk_disable_all_no_ctx(); | 124 | dss_clk_disable_all_no_ctx(); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) | ||
| 127 | /* CLOCKS */ | 128 | /* CLOCKS */ |
| 128 | static void core_dump_clocks(struct seq_file *s) | 129 | static void core_dump_clocks(struct seq_file *s) |
| 129 | { | 130 | { |
| @@ -149,6 +150,7 @@ static void core_dump_clocks(struct seq_file *s) | |||
| 149 | clocks[i]->usecount); | 150 | clocks[i]->usecount); |
| 150 | } | 151 | } |
| 151 | } | 152 | } |
| 153 | #endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */ | ||
| 152 | 154 | ||
| 153 | static int dss_get_clock(struct clk **clock, const char *clk_name) | 155 | static int dss_get_clock(struct clk **clock, const char *clk_name) |
| 154 | { | 156 | { |
| @@ -395,6 +397,14 @@ static int dss_initialize_debugfs(void) | |||
| 395 | debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, | 397 | debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, |
| 396 | &dss_debug_dump_clocks, &dss_debug_fops); | 398 | &dss_debug_dump_clocks, &dss_debug_fops); |
| 397 | 399 | ||
| 400 | debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, | ||
| 401 | &dispc_dump_irqs, &dss_debug_fops); | ||
| 402 | |||
| 403 | #ifdef CONFIG_OMAP2_DSS_DSI | ||
| 404 | debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, | ||
| 405 | &dsi_dump_irqs, &dss_debug_fops); | ||
| 406 | #endif | ||
| 407 | |||
| 398 | debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, | 408 | debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, |
| 399 | &dss_dump_regs, &dss_debug_fops); | 409 | &dss_dump_regs, &dss_debug_fops); |
| 400 | debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir, | 410 | debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir, |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 6dabf4b2f005..de8bfbac9e26 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
| @@ -148,6 +148,12 @@ static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES, | |||
| 148 | DISPC_VID_ATTRIBUTES(0), | 148 | DISPC_VID_ATTRIBUTES(0), |
| 149 | DISPC_VID_ATTRIBUTES(1) }; | 149 | DISPC_VID_ATTRIBUTES(1) }; |
| 150 | 150 | ||
| 151 | struct dispc_irq_stats { | ||
| 152 | unsigned long last_reset; | ||
| 153 | unsigned irq_count; | ||
| 154 | unsigned irqs[32]; | ||
| 155 | }; | ||
| 156 | |||
| 151 | static struct { | 157 | static struct { |
| 152 | void __iomem *base; | 158 | void __iomem *base; |
| 153 | 159 | ||
| @@ -160,6 +166,11 @@ static struct { | |||
| 160 | struct work_struct error_work; | 166 | struct work_struct error_work; |
| 161 | 167 | ||
| 162 | u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; | 168 | u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; |
| 169 | |||
| 170 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 171 | spinlock_t irq_stats_lock; | ||
| 172 | struct dispc_irq_stats irq_stats; | ||
| 173 | #endif | ||
| 163 | } dispc; | 174 | } dispc; |
| 164 | 175 | ||
| 165 | static void _omap_dispc_set_irqs(void); | 176 | static void _omap_dispc_set_irqs(void); |
| @@ -1443,7 +1454,10 @@ static unsigned long calc_fclk_five_taps(u16 width, u16 height, | |||
| 1443 | do_div(tmp, 2 * out_height * ppl); | 1454 | do_div(tmp, 2 * out_height * ppl); |
| 1444 | fclk = tmp; | 1455 | fclk = tmp; |
| 1445 | 1456 | ||
| 1446 | if (height > 2 * out_height && ppl != out_width) { | 1457 | if (height > 2 * out_height) { |
| 1458 | if (ppl == out_width) | ||
| 1459 | return 0; | ||
| 1460 | |||
| 1447 | tmp = pclk * (height - 2 * out_height) * out_width; | 1461 | tmp = pclk * (height - 2 * out_height) * out_width; |
| 1448 | do_div(tmp, 2 * out_height * (ppl - out_width)); | 1462 | do_div(tmp, 2 * out_height * (ppl - out_width)); |
| 1449 | fclk = max(fclk, (u32) tmp); | 1463 | fclk = max(fclk, (u32) tmp); |
| @@ -1623,7 +1637,7 @@ static int _dispc_setup_plane(enum omap_plane plane, | |||
| 1623 | DSSDBG("required fclk rate = %lu Hz\n", fclk); | 1637 | DSSDBG("required fclk rate = %lu Hz\n", fclk); |
| 1624 | DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); | 1638 | DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); |
| 1625 | 1639 | ||
| 1626 | if (fclk > dispc_fclk_rate()) { | 1640 | if (!fclk || fclk > dispc_fclk_rate()) { |
| 1627 | DSSERR("failed to set up scaling, " | 1641 | DSSERR("failed to set up scaling, " |
| 1628 | "required fclk rate = %lu Hz, " | 1642 | "required fclk rate = %lu Hz, " |
| 1629 | "current fclk rate = %lu Hz\n", | 1643 | "current fclk rate = %lu Hz\n", |
| @@ -2247,6 +2261,50 @@ void dispc_dump_clocks(struct seq_file *s) | |||
| 2247 | enable_clocks(0); | 2261 | enable_clocks(0); |
| 2248 | } | 2262 | } |
| 2249 | 2263 | ||
| 2264 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 2265 | void dispc_dump_irqs(struct seq_file *s) | ||
| 2266 | { | ||
| 2267 | unsigned long flags; | ||
| 2268 | struct dispc_irq_stats stats; | ||
| 2269 | |||
| 2270 | spin_lock_irqsave(&dispc.irq_stats_lock, flags); | ||
| 2271 | |||
| 2272 | stats = dispc.irq_stats; | ||
| 2273 | memset(&dispc.irq_stats, 0, sizeof(dispc.irq_stats)); | ||
| 2274 | dispc.irq_stats.last_reset = jiffies; | ||
| 2275 | |||
| 2276 | spin_unlock_irqrestore(&dispc.irq_stats_lock, flags); | ||
| 2277 | |||
| 2278 | seq_printf(s, "period %u ms\n", | ||
| 2279 | jiffies_to_msecs(jiffies - stats.last_reset)); | ||
| 2280 | |||
| 2281 | seq_printf(s, "irqs %d\n", stats.irq_count); | ||
| 2282 | #define PIS(x) \ | ||
| 2283 | seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]); | ||
| 2284 | |||
| 2285 | PIS(FRAMEDONE); | ||
| 2286 | PIS(VSYNC); | ||
| 2287 | PIS(EVSYNC_EVEN); | ||
| 2288 | PIS(EVSYNC_ODD); | ||
| 2289 | PIS(ACBIAS_COUNT_STAT); | ||
| 2290 | PIS(PROG_LINE_NUM); | ||
| 2291 | PIS(GFX_FIFO_UNDERFLOW); | ||
| 2292 | PIS(GFX_END_WIN); | ||
| 2293 | PIS(PAL_GAMMA_MASK); | ||
| 2294 | PIS(OCP_ERR); | ||
| 2295 | PIS(VID1_FIFO_UNDERFLOW); | ||
| 2296 | PIS(VID1_END_WIN); | ||
| 2297 | PIS(VID2_FIFO_UNDERFLOW); | ||
| 2298 | PIS(VID2_END_WIN); | ||
| 2299 | PIS(SYNC_LOST); | ||
| 2300 | PIS(SYNC_LOST_DIGIT); | ||
| 2301 | PIS(WAKEUP); | ||
| 2302 | #undef PIS | ||
| 2303 | } | ||
| 2304 | #else | ||
| 2305 | void dispc_dump_irqs(struct seq_file *s) { } | ||
| 2306 | #endif | ||
| 2307 | |||
| 2250 | void dispc_dump_regs(struct seq_file *s) | 2308 | void dispc_dump_regs(struct seq_file *s) |
| 2251 | { | 2309 | { |
| 2252 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) | 2310 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) |
| @@ -2665,6 +2723,13 @@ void dispc_irq_handler(void) | |||
| 2665 | 2723 | ||
| 2666 | irqstatus = dispc_read_reg(DISPC_IRQSTATUS); | 2724 | irqstatus = dispc_read_reg(DISPC_IRQSTATUS); |
| 2667 | 2725 | ||
| 2726 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 2727 | spin_lock(&dispc.irq_stats_lock); | ||
| 2728 | dispc.irq_stats.irq_count++; | ||
| 2729 | dss_collect_irq_stats(irqstatus, dispc.irq_stats.irqs); | ||
| 2730 | spin_unlock(&dispc.irq_stats_lock); | ||
| 2731 | #endif | ||
| 2732 | |||
| 2668 | #ifdef DEBUG | 2733 | #ifdef DEBUG |
| 2669 | if (dss_debug) | 2734 | if (dss_debug) |
| 2670 | print_irq_status(irqstatus); | 2735 | print_irq_status(irqstatus); |
| @@ -3012,6 +3077,11 @@ int dispc_init(void) | |||
| 3012 | 3077 | ||
| 3013 | spin_lock_init(&dispc.irq_lock); | 3078 | spin_lock_init(&dispc.irq_lock); |
| 3014 | 3079 | ||
| 3080 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 3081 | spin_lock_init(&dispc.irq_stats_lock); | ||
| 3082 | dispc.irq_stats.last_reset = jiffies; | ||
| 3083 | #endif | ||
| 3084 | |||
| 3015 | INIT_WORK(&dispc.error_work, dispc_error_worker); | 3085 | INIT_WORK(&dispc.error_work, dispc_error_worker); |
| 3016 | 3086 | ||
| 3017 | dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); | 3087 | dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); |
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 5936487b5def..6122178f5f85 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
| @@ -204,6 +204,14 @@ struct dsi_update_region { | |||
| 204 | struct omap_dss_device *device; | 204 | struct omap_dss_device *device; |
| 205 | }; | 205 | }; |
| 206 | 206 | ||
| 207 | struct dsi_irq_stats { | ||
| 208 | unsigned long last_reset; | ||
| 209 | unsigned irq_count; | ||
| 210 | unsigned dsi_irqs[32]; | ||
| 211 | unsigned vc_irqs[4][32]; | ||
| 212 | unsigned cio_irqs[32]; | ||
| 213 | }; | ||
| 214 | |||
| 207 | static struct | 215 | static struct |
| 208 | { | 216 | { |
| 209 | void __iomem *base; | 217 | void __iomem *base; |
| @@ -258,6 +266,11 @@ static struct | |||
| 258 | #endif | 266 | #endif |
| 259 | int debug_read; | 267 | int debug_read; |
| 260 | int debug_write; | 268 | int debug_write; |
| 269 | |||
| 270 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 271 | spinlock_t irq_stats_lock; | ||
| 272 | struct dsi_irq_stats irq_stats; | ||
| 273 | #endif | ||
| 261 | } dsi; | 274 | } dsi; |
| 262 | 275 | ||
| 263 | #ifdef DEBUG | 276 | #ifdef DEBUG |
| @@ -528,6 +541,12 @@ void dsi_irq_handler(void) | |||
| 528 | 541 | ||
| 529 | irqstatus = dsi_read_reg(DSI_IRQSTATUS); | 542 | irqstatus = dsi_read_reg(DSI_IRQSTATUS); |
| 530 | 543 | ||
| 544 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 545 | spin_lock(&dsi.irq_stats_lock); | ||
| 546 | dsi.irq_stats.irq_count++; | ||
| 547 | dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); | ||
| 548 | #endif | ||
| 549 | |||
| 531 | if (irqstatus & DSI_IRQ_ERROR_MASK) { | 550 | if (irqstatus & DSI_IRQ_ERROR_MASK) { |
| 532 | DSSERR("DSI error, irqstatus %x\n", irqstatus); | 551 | DSSERR("DSI error, irqstatus %x\n", irqstatus); |
| 533 | print_irq_status(irqstatus); | 552 | print_irq_status(irqstatus); |
| @@ -549,6 +568,10 @@ void dsi_irq_handler(void) | |||
| 549 | 568 | ||
| 550 | vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); | 569 | vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); |
| 551 | 570 | ||
| 571 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 572 | dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); | ||
| 573 | #endif | ||
| 574 | |||
| 552 | if (vcstatus & DSI_VC_IRQ_BTA) | 575 | if (vcstatus & DSI_VC_IRQ_BTA) |
| 553 | complete(&dsi.bta_completion); | 576 | complete(&dsi.bta_completion); |
| 554 | 577 | ||
| @@ -568,6 +591,10 @@ void dsi_irq_handler(void) | |||
| 568 | if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { | 591 | if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { |
| 569 | ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); | 592 | ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); |
| 570 | 593 | ||
| 594 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 595 | dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs); | ||
| 596 | #endif | ||
| 597 | |||
| 571 | dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); | 598 | dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); |
| 572 | /* flush posted write */ | 599 | /* flush posted write */ |
| 573 | dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); | 600 | dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); |
| @@ -579,6 +606,10 @@ void dsi_irq_handler(void) | |||
| 579 | dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); | 606 | dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); |
| 580 | /* flush posted write */ | 607 | /* flush posted write */ |
| 581 | dsi_read_reg(DSI_IRQSTATUS); | 608 | dsi_read_reg(DSI_IRQSTATUS); |
| 609 | |||
| 610 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 611 | spin_unlock(&dsi.irq_stats_lock); | ||
| 612 | #endif | ||
| 582 | } | 613 | } |
| 583 | 614 | ||
| 584 | 615 | ||
| @@ -797,12 +828,12 @@ static int dsi_pll_power(enum dsi_pll_power_state state) | |||
| 797 | 828 | ||
| 798 | /* PLL_PWR_STATUS */ | 829 | /* PLL_PWR_STATUS */ |
| 799 | while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { | 830 | while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { |
| 800 | udelay(1); | 831 | if (++t > 1000) { |
| 801 | if (t++ > 1000) { | ||
| 802 | DSSERR("Failed to set DSI PLL power mode to %d\n", | 832 | DSSERR("Failed to set DSI PLL power mode to %d\n", |
| 803 | state); | 833 | state); |
| 804 | return -ENODEV; | 834 | return -ENODEV; |
| 805 | } | 835 | } |
| 836 | udelay(1); | ||
| 806 | } | 837 | } |
| 807 | 838 | ||
| 808 | return 0; | 839 | return 0; |
| @@ -1226,6 +1257,95 @@ void dsi_dump_clocks(struct seq_file *s) | |||
| 1226 | enable_clocks(0); | 1257 | enable_clocks(0); |
| 1227 | } | 1258 | } |
| 1228 | 1259 | ||
| 1260 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 1261 | void dsi_dump_irqs(struct seq_file *s) | ||
| 1262 | { | ||
| 1263 | unsigned long flags; | ||
| 1264 | struct dsi_irq_stats stats; | ||
| 1265 | |||
| 1266 | spin_lock_irqsave(&dsi.irq_stats_lock, flags); | ||
| 1267 | |||
| 1268 | stats = dsi.irq_stats; | ||
| 1269 | memset(&dsi.irq_stats, 0, sizeof(dsi.irq_stats)); | ||
| 1270 | dsi.irq_stats.last_reset = jiffies; | ||
| 1271 | |||
| 1272 | spin_unlock_irqrestore(&dsi.irq_stats_lock, flags); | ||
| 1273 | |||
| 1274 | seq_printf(s, "period %u ms\n", | ||
| 1275 | jiffies_to_msecs(jiffies - stats.last_reset)); | ||
| 1276 | |||
| 1277 | seq_printf(s, "irqs %d\n", stats.irq_count); | ||
| 1278 | #define PIS(x) \ | ||
| 1279 | seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); | ||
| 1280 | |||
| 1281 | seq_printf(s, "-- DSI interrupts --\n"); | ||
| 1282 | PIS(VC0); | ||
| 1283 | PIS(VC1); | ||
| 1284 | PIS(VC2); | ||
| 1285 | PIS(VC3); | ||
| 1286 | PIS(WAKEUP); | ||
| 1287 | PIS(RESYNC); | ||
| 1288 | PIS(PLL_LOCK); | ||
| 1289 | PIS(PLL_UNLOCK); | ||
| 1290 | PIS(PLL_RECALL); | ||
| 1291 | PIS(COMPLEXIO_ERR); | ||
| 1292 | PIS(HS_TX_TIMEOUT); | ||
| 1293 | PIS(LP_RX_TIMEOUT); | ||
| 1294 | PIS(TE_TRIGGER); | ||
| 1295 | PIS(ACK_TRIGGER); | ||
| 1296 | PIS(SYNC_LOST); | ||
| 1297 | PIS(LDO_POWER_GOOD); | ||
| 1298 | PIS(TA_TIMEOUT); | ||
| 1299 | #undef PIS | ||
| 1300 | |||
| 1301 | #define PIS(x) \ | ||
| 1302 | seq_printf(s, "%-20s %10d %10d %10d %10d\n", #x, \ | ||
| 1303 | stats.vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \ | ||
| 1304 | stats.vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \ | ||
| 1305 | stats.vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \ | ||
| 1306 | stats.vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]); | ||
| 1307 | |||
| 1308 | seq_printf(s, "-- VC interrupts --\n"); | ||
| 1309 | PIS(CS); | ||
| 1310 | PIS(ECC_CORR); | ||
| 1311 | PIS(PACKET_SENT); | ||
| 1312 | PIS(FIFO_TX_OVF); | ||
| 1313 | PIS(FIFO_RX_OVF); | ||
| 1314 | PIS(BTA); | ||
| 1315 | PIS(ECC_NO_CORR); | ||
| 1316 | PIS(FIFO_TX_UDF); | ||
| 1317 | PIS(PP_BUSY_CHANGE); | ||
| 1318 | #undef PIS | ||
| 1319 | |||
| 1320 | #define PIS(x) \ | ||
| 1321 | seq_printf(s, "%-20s %10d\n", #x, \ | ||
| 1322 | stats.cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]); | ||
| 1323 | |||
| 1324 | seq_printf(s, "-- CIO interrupts --\n"); | ||
| 1325 | PIS(ERRSYNCESC1); | ||
| 1326 | PIS(ERRSYNCESC2); | ||
| 1327 | PIS(ERRSYNCESC3); | ||
| 1328 | PIS(ERRESC1); | ||
| 1329 | PIS(ERRESC2); | ||
| 1330 | PIS(ERRESC3); | ||
| 1331 | PIS(ERRCONTROL1); | ||
| 1332 | PIS(ERRCONTROL2); | ||
| 1333 | PIS(ERRCONTROL3); | ||
| 1334 | PIS(STATEULPS1); | ||
| 1335 | PIS(STATEULPS2); | ||
| 1336 | PIS(STATEULPS3); | ||
| 1337 | PIS(ERRCONTENTIONLP0_1); | ||
| 1338 | PIS(ERRCONTENTIONLP1_1); | ||
| 1339 | PIS(ERRCONTENTIONLP0_2); | ||
| 1340 | PIS(ERRCONTENTIONLP1_2); | ||
| 1341 | PIS(ERRCONTENTIONLP0_3); | ||
| 1342 | PIS(ERRCONTENTIONLP1_3); | ||
| 1343 | PIS(ULPSACTIVENOT_ALL0); | ||
| 1344 | PIS(ULPSACTIVENOT_ALL1); | ||
| 1345 | #undef PIS | ||
| 1346 | } | ||
| 1347 | #endif | ||
| 1348 | |||
| 1229 | void dsi_dump_regs(struct seq_file *s) | 1349 | void dsi_dump_regs(struct seq_file *s) |
| 1230 | { | 1350 | { |
| 1231 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) | 1351 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) |
| @@ -1321,12 +1441,12 @@ static int dsi_complexio_power(enum dsi_complexio_power_state state) | |||
| 1321 | 1441 | ||
| 1322 | /* PWR_STATUS */ | 1442 | /* PWR_STATUS */ |
| 1323 | while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { | 1443 | while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { |
| 1324 | udelay(1); | 1444 | if (++t > 1000) { |
| 1325 | if (t++ > 1000) { | ||
| 1326 | DSSERR("failed to set complexio power state to " | 1445 | DSSERR("failed to set complexio power state to " |
| 1327 | "%d\n", state); | 1446 | "%d\n", state); |
| 1328 | return -ENODEV; | 1447 | return -ENODEV; |
| 1329 | } | 1448 | } |
| 1449 | udelay(1); | ||
| 1330 | } | 1450 | } |
| 1331 | 1451 | ||
| 1332 | return 0; | 1452 | return 0; |
| @@ -1526,10 +1646,10 @@ static void dsi_complexio_uninit(void) | |||
| 1526 | 1646 | ||
| 1527 | static int _dsi_wait_reset(void) | 1647 | static int _dsi_wait_reset(void) |
| 1528 | { | 1648 | { |
| 1529 | int i = 0; | 1649 | int t = 0; |
| 1530 | 1650 | ||
| 1531 | while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) { | 1651 | while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) { |
| 1532 | if (i++ > 5) { | 1652 | if (++t > 5) { |
| 1533 | DSSERR("soft reset failed\n"); | 1653 | DSSERR("soft reset failed\n"); |
| 1534 | return -ENODEV; | 1654 | return -ENODEV; |
| 1535 | } | 1655 | } |
| @@ -1999,7 +2119,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) | |||
| 1999 | return -EINVAL; | 2119 | return -EINVAL; |
| 2000 | } | 2120 | } |
| 2001 | 2121 | ||
| 2002 | data_id = data_type | channel << 6; | 2122 | data_id = data_type | dsi.vc[channel].dest_per << 6; |
| 2003 | 2123 | ||
| 2004 | r = (data_id << 0) | (data << 8) | (ecc << 24); | 2124 | r = (data_id << 0) | (data << 8) | (ecc << 24); |
| 2005 | 2125 | ||
| @@ -2011,7 +2131,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) | |||
| 2011 | int dsi_vc_send_null(int channel) | 2131 | int dsi_vc_send_null(int channel) |
| 2012 | { | 2132 | { |
| 2013 | u8 nullpkg[] = {0, 0, 0, 0}; | 2133 | u8 nullpkg[] = {0, 0, 0, 0}; |
| 2014 | return dsi_vc_send_long(0, DSI_DT_NULL_PACKET, nullpkg, 4, 0); | 2134 | return dsi_vc_send_long(channel, DSI_DT_NULL_PACKET, nullpkg, 4, 0); |
| 2015 | } | 2135 | } |
| 2016 | EXPORT_SYMBOL(dsi_vc_send_null); | 2136 | EXPORT_SYMBOL(dsi_vc_send_null); |
| 2017 | 2137 | ||
| @@ -2058,7 +2178,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) | |||
| 2058 | int r; | 2178 | int r; |
| 2059 | 2179 | ||
| 2060 | if (dsi.debug_read) | 2180 | if (dsi.debug_read) |
| 2061 | DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %u)\n", channel, dcs_cmd); | 2181 | DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd); |
| 2062 | 2182 | ||
| 2063 | r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); | 2183 | r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); |
| 2064 | if (r) | 2184 | if (r) |
| @@ -2586,7 +2706,6 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | |||
| 2586 | /* using fifo not empty */ | 2706 | /* using fifo not empty */ |
| 2587 | /* TX_FIFO_NOT_EMPTY */ | 2707 | /* TX_FIFO_NOT_EMPTY */ |
| 2588 | while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) { | 2708 | while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) { |
| 2589 | udelay(1); | ||
| 2590 | fifo_stalls++; | 2709 | fifo_stalls++; |
| 2591 | if (fifo_stalls > 0xfffff) { | 2710 | if (fifo_stalls > 0xfffff) { |
| 2592 | DSSERR("fifo stalls overflow, pixels left %d\n", | 2711 | DSSERR("fifo stalls overflow, pixels left %d\n", |
| @@ -2594,6 +2713,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | |||
| 2594 | dsi_if_enable(0); | 2713 | dsi_if_enable(0); |
| 2595 | return -EIO; | 2714 | return -EIO; |
| 2596 | } | 2715 | } |
| 2716 | udelay(1); | ||
| 2597 | } | 2717 | } |
| 2598 | #elif 1 | 2718 | #elif 1 |
| 2599 | /* using fifo emptiness */ | 2719 | /* using fifo emptiness */ |
| @@ -2812,11 +2932,15 @@ static int dsi_set_update_mode(struct omap_dss_device *dssdev, | |||
| 2812 | 2932 | ||
| 2813 | static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) | 2933 | static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) |
| 2814 | { | 2934 | { |
| 2815 | int r; | 2935 | int r = 0; |
| 2816 | r = dssdev->driver->enable_te(dssdev, enable); | 2936 | |
| 2817 | /* XXX for some reason, DSI TE breaks if we don't wait here. | 2937 | if (dssdev->driver->enable_te) { |
| 2818 | * Panel bug? Needs more studying */ | 2938 | r = dssdev->driver->enable_te(dssdev, enable); |
| 2819 | msleep(100); | 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 | |||
| 2820 | return r; | 2944 | return r; |
| 2821 | } | 2945 | } |
| 2822 | 2946 | ||
| @@ -3637,6 +3761,11 @@ int dsi_init(struct platform_device *pdev) | |||
| 3637 | spin_lock_init(&dsi.errors_lock); | 3761 | spin_lock_init(&dsi.errors_lock); |
| 3638 | dsi.errors = 0; | 3762 | dsi.errors = 0; |
| 3639 | 3763 | ||
| 3764 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 3765 | spin_lock_init(&dsi.irq_stats_lock); | ||
| 3766 | dsi.irq_stats.last_reset = jiffies; | ||
| 3767 | #endif | ||
| 3768 | |||
| 3640 | init_completion(&dsi.bta_completion); | 3769 | init_completion(&dsi.bta_completion); |
| 3641 | init_completion(&dsi.update_completion); | 3770 | init_completion(&dsi.update_completion); |
| 3642 | 3771 | ||
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 9b05ee65a15d..0a26b7d84d41 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c | |||
| @@ -467,14 +467,14 @@ static irqreturn_t dss_irq_handler_omap3(int irq, void *arg) | |||
| 467 | 467 | ||
| 468 | static int _omap_dss_wait_reset(void) | 468 | static int _omap_dss_wait_reset(void) |
| 469 | { | 469 | { |
| 470 | unsigned timeout = 1000; | 470 | int t = 0; |
| 471 | 471 | ||
| 472 | while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) { | 472 | while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) { |
| 473 | udelay(1); | 473 | if (++t > 1000) { |
| 474 | if (!--timeout) { | ||
| 475 | DSSERR("soft reset failed\n"); | 474 | DSSERR("soft reset failed\n"); |
| 476 | return -ENODEV; | 475 | return -ENODEV; |
| 477 | } | 476 | } |
| 477 | udelay(1); | ||
| 478 | } | 478 | } |
| 479 | 479 | ||
| 480 | return 0; | 480 | return 0; |
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 8da5ac42151b..2bcb1245d6c2 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
| @@ -240,6 +240,7 @@ int dsi_init(struct platform_device *pdev); | |||
| 240 | void dsi_exit(void); | 240 | void dsi_exit(void); |
| 241 | 241 | ||
| 242 | void dsi_dump_clocks(struct seq_file *s); | 242 | void dsi_dump_clocks(struct seq_file *s); |
| 243 | void dsi_dump_irqs(struct seq_file *s); | ||
| 243 | void dsi_dump_regs(struct seq_file *s); | 244 | void dsi_dump_regs(struct seq_file *s); |
| 244 | 245 | ||
| 245 | void dsi_save_context(void); | 246 | void dsi_save_context(void); |
| @@ -268,6 +269,7 @@ int dpi_init_display(struct omap_dss_device *dssdev); | |||
| 268 | int dispc_init(void); | 269 | int dispc_init(void); |
| 269 | void dispc_exit(void); | 270 | void dispc_exit(void); |
| 270 | void dispc_dump_clocks(struct seq_file *s); | 271 | void dispc_dump_clocks(struct seq_file *s); |
| 272 | void dispc_dump_irqs(struct seq_file *s); | ||
| 271 | void dispc_dump_regs(struct seq_file *s); | 273 | void dispc_dump_regs(struct seq_file *s); |
| 272 | void dispc_irq_handler(void); | 274 | void dispc_irq_handler(void); |
| 273 | void dispc_fake_vsync_irq(void); | 275 | void dispc_fake_vsync_irq(void); |
| @@ -367,4 +369,16 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t); | |||
| 367 | unsigned long rfbi_get_max_tx_rate(void); | 369 | unsigned long rfbi_get_max_tx_rate(void); |
| 368 | int rfbi_init_display(struct omap_dss_device *display); | 370 | int rfbi_init_display(struct omap_dss_device *display); |
| 369 | 371 | ||
| 372 | |||
| 373 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 374 | static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr) | ||
| 375 | { | ||
| 376 | int b; | ||
| 377 | for (b = 0; b < 32; ++b) { | ||
| 378 | if (irqstatus & (1 << b)) | ||
| 379 | irq_arr[b]++; | ||
| 380 | } | ||
| 381 | } | ||
| 382 | #endif | ||
| 383 | |||
| 370 | #endif | 384 | #endif |
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index d0b3006ad8a5..b936495c065d 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c | |||
| @@ -120,7 +120,7 @@ static struct { | |||
| 120 | 120 | ||
| 121 | struct omap_dss_device *dssdev[2]; | 121 | struct omap_dss_device *dssdev[2]; |
| 122 | 122 | ||
| 123 | struct kfifo *cmd_fifo; | 123 | struct kfifo cmd_fifo; |
| 124 | spinlock_t cmd_lock; | 124 | spinlock_t cmd_lock; |
| 125 | struct completion cmd_done; | 125 | struct completion cmd_done; |
| 126 | atomic_t cmd_fifo_full; | 126 | atomic_t cmd_fifo_full; |
| @@ -1011,20 +1011,20 @@ static void process_cmd_fifo(void) | |||
| 1011 | return; | 1011 | return; |
| 1012 | 1012 | ||
| 1013 | while (true) { | 1013 | while (true) { |
| 1014 | spin_lock_irqsave(rfbi.cmd_fifo->lock, flags); | 1014 | spin_lock_irqsave(&rfbi.cmd_lock, flags); |
| 1015 | 1015 | ||
| 1016 | len = __kfifo_get(rfbi.cmd_fifo, (unsigned char *)&p, | 1016 | len = kfifo_out(&rfbi.cmd_fifo, (unsigned char *)&p, |
| 1017 | sizeof(struct update_param)); | 1017 | sizeof(struct update_param)); |
| 1018 | if (len == 0) { | 1018 | if (len == 0) { |
| 1019 | DSSDBG("nothing more in fifo\n"); | 1019 | DSSDBG("nothing more in fifo\n"); |
| 1020 | atomic_set(&rfbi.cmd_pending, 0); | 1020 | atomic_set(&rfbi.cmd_pending, 0); |
| 1021 | spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); | 1021 | spin_unlock_irqrestore(&rfbi.cmd_lock, flags); |
| 1022 | break; | 1022 | break; |
| 1023 | } | 1023 | } |
| 1024 | 1024 | ||
| 1025 | /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/ | 1025 | /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/ |
| 1026 | 1026 | ||
| 1027 | spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); | 1027 | spin_unlock_irqrestore(&rfbi.cmd_lock, flags); |
| 1028 | 1028 | ||
| 1029 | BUG_ON(len != sizeof(struct update_param)); | 1029 | BUG_ON(len != sizeof(struct update_param)); |
| 1030 | BUG_ON(p.rfbi_module > 1); | 1030 | BUG_ON(p.rfbi_module > 1); |
| @@ -1052,25 +1052,25 @@ static void rfbi_push_cmd(struct update_param *p) | |||
| 1052 | unsigned long flags; | 1052 | unsigned long flags; |
| 1053 | int available; | 1053 | int available; |
| 1054 | 1054 | ||
| 1055 | spin_lock_irqsave(rfbi.cmd_fifo->lock, flags); | 1055 | spin_lock_irqsave(&rfbi.cmd_lock, flags); |
| 1056 | available = RFBI_CMD_FIFO_LEN_BYTES - | 1056 | available = RFBI_CMD_FIFO_LEN_BYTES - |
| 1057 | __kfifo_len(rfbi.cmd_fifo); | 1057 | kfifo_len(&rfbi.cmd_fifo); |
| 1058 | 1058 | ||
| 1059 | /* DSSDBG("%d bytes left in fifo\n", available); */ | 1059 | /* DSSDBG("%d bytes left in fifo\n", available); */ |
| 1060 | if (available < sizeof(struct update_param)) { | 1060 | if (available < sizeof(struct update_param)) { |
| 1061 | DSSDBG("Going to wait because FIFO FULL..\n"); | 1061 | DSSDBG("Going to wait because FIFO FULL..\n"); |
| 1062 | spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); | 1062 | spin_unlock_irqrestore(&rfbi.cmd_lock, flags); |
| 1063 | atomic_inc(&rfbi.cmd_fifo_full); | 1063 | atomic_inc(&rfbi.cmd_fifo_full); |
| 1064 | wait_for_completion(&rfbi.cmd_done); | 1064 | wait_for_completion(&rfbi.cmd_done); |
| 1065 | /*DSSDBG("Woke up because fifo not full anymore\n");*/ | 1065 | /*DSSDBG("Woke up because fifo not full anymore\n");*/ |
| 1066 | continue; | 1066 | continue; |
| 1067 | } | 1067 | } |
| 1068 | 1068 | ||
| 1069 | ret = __kfifo_put(rfbi.cmd_fifo, (unsigned char *)p, | 1069 | ret = kfifo_in(&rfbi.cmd_fifo, (unsigned char *)p, |
| 1070 | sizeof(struct update_param)); | 1070 | sizeof(struct update_param)); |
| 1071 | /* DSSDBG("pushed %d bytes\n", ret);*/ | 1071 | /* DSSDBG("pushed %d bytes\n", ret);*/ |
| 1072 | 1072 | ||
| 1073 | spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); | 1073 | spin_unlock_irqrestore(&rfbi.cmd_lock, flags); |
| 1074 | 1074 | ||
| 1075 | BUG_ON(ret != sizeof(struct update_param)); | 1075 | BUG_ON(ret != sizeof(struct update_param)); |
| 1076 | 1076 | ||
| @@ -1155,12 +1155,12 @@ int rfbi_init(void) | |||
| 1155 | { | 1155 | { |
| 1156 | u32 rev; | 1156 | u32 rev; |
| 1157 | u32 l; | 1157 | u32 l; |
| 1158 | int r; | ||
| 1158 | 1159 | ||
| 1159 | spin_lock_init(&rfbi.cmd_lock); | 1160 | spin_lock_init(&rfbi.cmd_lock); |
| 1160 | rfbi.cmd_fifo = kfifo_alloc(RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL, | 1161 | r = kfifo_alloc(&rfbi.cmd_fifo, RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL); |
| 1161 | &rfbi.cmd_lock); | 1162 | if (r) |
| 1162 | if (IS_ERR(rfbi.cmd_fifo)) | 1163 | return r; |
| 1163 | return -ENOMEM; | ||
| 1164 | 1164 | ||
| 1165 | init_completion(&rfbi.cmd_done); | 1165 | init_completion(&rfbi.cmd_done); |
| 1166 | atomic_set(&rfbi.cmd_fifo_full, 0); | 1166 | atomic_set(&rfbi.cmd_fifo_full, 0); |
| @@ -1196,7 +1196,7 @@ void rfbi_exit(void) | |||
| 1196 | { | 1196 | { |
| 1197 | DSSDBG("rfbi_exit\n"); | 1197 | DSSDBG("rfbi_exit\n"); |
| 1198 | 1198 | ||
| 1199 | kfifo_free(rfbi.cmd_fifo); | 1199 | kfifo_free(&rfbi.cmd_fifo); |
| 1200 | 1200 | ||
| 1201 | iounmap(rfbi.base); | 1201 | iounmap(rfbi.base); |
| 1202 | } | 1202 | } |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index ef299839858a..d17caef6915a 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
| @@ -1311,6 +1311,7 @@ static void omapfb_free_fbmem(struct fb_info *fbi) | |||
| 1311 | if (rg->vrfb.vaddr[0]) { | 1311 | if (rg->vrfb.vaddr[0]) { |
| 1312 | iounmap(rg->vrfb.vaddr[0]); | 1312 | iounmap(rg->vrfb.vaddr[0]); |
| 1313 | omap_vrfb_release_ctx(&rg->vrfb); | 1313 | omap_vrfb_release_ctx(&rg->vrfb); |
| 1314 | rg->vrfb.vaddr[0] = NULL; | ||
| 1314 | } | 1315 | } |
| 1315 | } | 1316 | } |
| 1316 | 1317 | ||
| @@ -2114,6 +2115,11 @@ static int omapfb_probe(struct platform_device *pdev) | |||
| 2114 | dssdev = NULL; | 2115 | dssdev = NULL; |
| 2115 | for_each_dss_dev(dssdev) { | 2116 | for_each_dss_dev(dssdev) { |
| 2116 | omap_dss_get_device(dssdev); | 2117 | omap_dss_get_device(dssdev); |
| 2118 | if (!dssdev->driver) { | ||
| 2119 | dev_err(&pdev->dev, "no driver for display\n"); | ||
| 2120 | r = -EINVAL; | ||
| 2121 | goto cleanup; | ||
| 2122 | } | ||
| 2117 | fbdev->displays[fbdev->num_displays++] = dssdev; | 2123 | fbdev->displays[fbdev->num_displays++] = dssdev; |
| 2118 | } | 2124 | } |
| 2119 | 2125 | ||
