aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-15 16:03:48 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-15 16:03:48 -0500
commit2b8318881ddbcb67c5e8d2178b42284749442222 (patch)
treeb43ded0118bb7a6d9f89f6875c18d7ef447ba3be
parente81d372ff9f694e13fa46e8b5aaed505c7fd2a1f (diff)
parente7f5c9a16ea2648a3e85af8e34191026bf3dcb62 (diff)
Merge tag 'fbdev-for-3.8' of git://gitorious.org/linux-omap-dss2/linux
Pull fbdev changes from Tomi Valkeinen: "OMAPDSS changes, including: - use dynanic debug prints - OMAP platform dependency removals - Creation of compat-layer, helping us to improve omapdrm - Misc cleanups, aiming to make omadss more in line with the upcoming common display framework Exynos DP changes for the 3.8 merge window: - Device Tree support for Samsung Exynos DP - SW Link training is cleaned up. - HPD interrupt is supported. Samsung Framebuffer changes for the 3.8 merge window: - The bit definitions of header file are updated. - Some minor typos are fixed. - Some minor bugs of s3c_fb_check_var() are fixed. FB related changes for SH Mobile, Freescale DIU Add support for the Solomon SSD1307 OLED Controller" * tag 'fbdev-for-3.8' of git://gitorious.org/linux-omap-dss2/linux: (191 commits) OMAPDSS: fix TV-out issue with DSI PLL Revert "OMAPFB: simplify locking" OMAPFB: remove silly loop in fb2display() OMAPFB: fix error handling in omapfb_find_best_mode() OMAPFB: use devm_kzalloc to allocate omapfb2_device OMAPDSS: DISPC: remove dispc fck uses OMAPDSS: DISPC: get dss clock rate from dss driver drivers/video/console/softcursor.c: remove redundant NULL check before kfree() drivers/video: add support for the Solomon SSD1307 OLED Controller OMAPDSS: use omapdss_compat_init() in other drivers OMAPDSS: export dispc functions OMAPDSS: export dss_feat functions OMAPDSS: export dss_mgr_ops functions OMAPDSS: separate compat files in the Makefile OMAPDSS: move display sysfs init to compat layer OMAPDSS: DPI: use dispc's check_timings OMAPDSS: DISPC: add dispc_ovl_check() OMAPDSS: move irq handling to dispc-compat OMAPDSS: move omap_dispc_wait_for_irq_interruptible_timeout to dispc-compat.c OMAPDSS: move blocking mgr enable/disable to compat layer ... Conflicts: arch/arm/mach-davinci/devices-da8xx.c arch/arm/plat-omap/common.c drivers/media/platform/omap/omap_vout.c
-rw-r--r--Documentation/arm/OMAP/DSS10
-rw-r--r--Documentation/devicetree/bindings/video/exynos_dp.txt80
-rw-r--r--Documentation/devicetree/bindings/video/ssd1307fb.txt24
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/mach-davinci/da830.c2
-rw-r--r--arch/arm/mach-davinci/da850.c2
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c22
-rw-r--r--arch/arm/mach-davinci/pm_domain.c1
-rw-r--r--arch/arm/mach-omap2/board-rx51-video.c14
-rw-r--r--arch/arm/mach-omap2/board-rx51.c3
-rw-r--r--arch/arm/mach-omap2/display.c15
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c198
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c4
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c6
-rw-r--r--arch/arm/plat-omap/fb.c5
-rw-r--r--arch/arm/plat-omap/include/plat/vram.h43
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c6
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c6
-rw-r--r--arch/sh/boards/mach-kfr2r09/lcd_wqvga.c16
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c7
-rw-r--r--arch/sh/include/mach-kfr2r09/mach/kfr2r09.h6
-rw-r--r--drivers/media/platform/omap/omap_vout.c21
-rw-r--r--drivers/media/platform/omap/omap_voutlib.c38
-rw-r--r--drivers/media/platform/omap/omap_voutlib.h3
-rw-r--r--drivers/staging/omapdrm/omap_drv.c11
-rw-r--r--drivers/video/Kconfig17
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/console/softcursor.c3
-rw-r--r--drivers/video/da8xx-fb.c170
-rw-r--r--drivers/video/exynos/exynos_dp_core.c697
-rw-r--r--drivers/video/exynos/exynos_dp_core.h21
-rw-r--r--drivers/video/exynos/exynos_dp_reg.c77
-rw-r--r--drivers/video/exynos/exynos_dp_reg.h3
-rw-r--r--drivers/video/fsl-diu-fb.c201
-rw-r--r--drivers/video/omap2/Kconfig3
-rw-r--r--drivers/video/omap2/Makefile1
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c23
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c36
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c34
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c89
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c24
-rw-r--r--drivers/video/omap2/displays/panel-picodlp.c45
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c17
-rw-r--r--drivers/video/omap2/displays/panel-taal.c72
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c33
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c20
-rw-r--r--drivers/video/omap2/dss/Kconfig35
-rw-r--r--drivers/video/omap2/dss/Makefile7
-rw-r--r--drivers/video/omap2/dss/apply.c331
-rw-r--r--drivers/video/omap2/dss/core.c72
-rw-r--r--drivers/video/omap2/dss/dispc-compat.c667
-rw-r--r--drivers/video/omap2/dss/dispc-compat.h30
-rw-r--r--drivers/video/omap2/dss/dispc.c1063
-rw-r--r--drivers/video/omap2/dss/display-sysfs.c321
-rw-r--r--drivers/video/omap2/dss/display.c386
-rw-r--r--drivers/video/omap2/dss/dpi.c126
-rw-r--r--drivers/video/omap2/dss/dsi.c247
-rw-r--r--drivers/video/omap2/dss/dss.c101
-rw-r--r--drivers/video/omap2/dss/dss.h124
-rw-r--r--drivers/video/omap2/dss/dss_features.c15
-rw-r--r--drivers/video/omap2/dss/dss_features.h7
-rw-r--r--drivers/video/omap2/dss/hdmi.c159
-rw-r--r--drivers/video/omap2/dss/hdmi_panel.c82
-rw-r--r--drivers/video/omap2/dss/manager.c39
-rw-r--r--drivers/video/omap2/dss/output.c90
-rw-r--r--drivers/video/omap2/dss/overlay.c17
-rw-r--r--drivers/video/omap2/dss/rfbi.c23
-rw-r--r--drivers/video/omap2/dss/sdi.c11
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h3
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c11
-rw-r--r--drivers/video/omap2/dss/venc.c11
-rw-r--r--drivers/video/omap2/dss/venc_panel.c19
-rw-r--r--drivers/video/omap2/omapfb/Kconfig1
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c46
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c204
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c4
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h20
-rw-r--r--drivers/video/omap2/vram.c514
-rw-r--r--drivers/video/s3c-fb.c24
-rw-r--r--drivers/video/sh_mipi_dsi.c69
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c74
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h1
-rw-r--r--drivers/video/ssd1307fb.c396
-rw-r--r--include/linux/fsl-diu-fb.h9
-rw-r--r--include/video/da8xx-fb.h25
-rw-r--r--include/video/omapdss.h91
-rw-r--r--include/video/samsung_fimd.h168
-rw-r--r--include/video/sh_mipi_dsi.h4
-rw-r--r--include/video/sh_mobile_lcdc.h1
89 files changed, 4013 insertions, 3771 deletions
diff --git a/Documentation/arm/OMAP/DSS b/Documentation/arm/OMAP/DSS
index a564ceea9e98..4484e021290e 100644
--- a/Documentation/arm/OMAP/DSS
+++ b/Documentation/arm/OMAP/DSS
@@ -285,7 +285,10 @@ FB0 +-- GFX ---- LCD ---- LCD
285Misc notes 285Misc notes
286---------- 286----------
287 287
288OMAP FB allocates the framebuffer memory using the OMAP VRAM allocator. 288OMAP FB allocates the framebuffer memory using the standard dma allocator. You
289can enable Contiguous Memory Allocator (CONFIG_CMA) to improve the dma
290allocator, and if CMA is enabled, you use "cma=" kernel parameter to increase
291the global memory area for CMA.
289 292
290Using DSI DPLL to generate pixel clock it is possible produce the pixel clock 293Using DSI DPLL to generate pixel clock it is possible produce the pixel clock
291of 86.5MHz (max possible), and with that you get 1280x1024@57 output from DVI. 294of 86.5MHz (max possible), and with that you get 1280x1024@57 output from DVI.
@@ -301,11 +304,6 @@ framebuffer parameters.
301Kernel boot arguments 304Kernel boot arguments
302--------------------- 305---------------------
303 306
304vram=<size>[,<physaddr>]
305 - Amount of total VRAM to preallocate and optionally a physical start
306 memory address. For example, "10M". omapfb allocates memory for
307 framebuffers from VRAM.
308
309omapfb.mode=<display>:<mode>[,...] 307omapfb.mode=<display>:<mode>[,...]
310 - Default video mode for specified displays. For example, 308 - Default video mode for specified displays. For example,
311 "dvi:800x400MR-24@60". See drivers/video/modedb.c. 309 "dvi:800x400MR-24@60". See drivers/video/modedb.c.
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
new file mode 100644
index 000000000000..c60da67a5d76
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -0,0 +1,80 @@
1The Exynos display port interface should be configured based on
2the type of panel connected to it.
3
4We use two nodes:
5 -dp-controller node
6 -dptx-phy node(defined inside dp-controller node)
7
8For the DP-PHY initialization, we use the dptx-phy node.
9Required properties for dptx-phy:
10 -reg:
11 Base address of DP PHY register.
12 -samsung,enable-mask:
13 The bit-mask used to enable/disable DP PHY.
14
15For the Panel initialization, we read data from dp-controller node.
16Required properties for dp-controller:
17 -compatible:
18 should be "samsung,exynos5-dp".
19 -reg:
20 physical base address of the controller and length
21 of memory mapped region.
22 -interrupts:
23 interrupt combiner values.
24 -interrupt-parent:
25 phandle to Interrupt combiner node.
26 -samsung,color-space:
27 input video data format.
28 COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
29 -samsung,dynamic-range:
30 dynamic range for input video data.
31 VESA = 0, CEA = 1
32 -samsung,ycbcr-coeff:
33 YCbCr co-efficients for input video.
34 COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
35 -samsung,color-depth:
36 number of bits per colour component.
37 COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
38 -samsung,link-rate:
39 link rate supported by the panel.
40 LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
41 -samsung,lane-count:
42 number of lanes supported by the panel.
43 LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
44
45Optional properties for dp-controller:
46 -interlaced:
47 interlace scan mode.
48 Progressive if defined, Interlaced if not defined
49 -vsync-active-high:
50 VSYNC polarity configuration.
51 High if defined, Low if not defined
52 -hsync-active-high:
53 HSYNC polarity configuration.
54 High if defined, Low if not defined
55
56Example:
57
58SOC specific portion:
59 dp-controller {
60 compatible = "samsung,exynos5-dp";
61 reg = <0x145b0000 0x10000>;
62 interrupts = <10 3>;
63 interrupt-parent = <&combiner>;
64
65 dptx-phy {
66 reg = <0x10040720>;
67 samsung,enable-mask = <1>;
68 };
69
70 };
71
72Board Specific portion:
73 dp-controller {
74 samsung,color-space = <0>;
75 samsung,dynamic-range = <0>;
76 samsung,ycbcr-coeff = <0>;
77 samsung,color-depth = <1>;
78 samsung,link-rate = <0x0a>;
79 samsung,lane-count = <4>;
80 };
diff --git a/Documentation/devicetree/bindings/video/ssd1307fb.txt b/Documentation/devicetree/bindings/video/ssd1307fb.txt
new file mode 100644
index 000000000000..3d0060cff062
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/ssd1307fb.txt
@@ -0,0 +1,24 @@
1* Solomon SSD1307 Framebuffer Driver
2
3Required properties:
4 - compatible: Should be "solomon,ssd1307fb-<bus>". The only supported bus for
5 now is i2c.
6 - reg: Should contain address of the controller on the I2C bus. Most likely
7 0x3c or 0x3d
8 - pwm: Should contain the pwm to use according to the OF device tree PWM
9 specification [0]
10 - reset-gpios: Should contain the GPIO used to reset the OLED display
11
12Optional properties:
13 - reset-active-low: Is the reset gpio is active on physical low?
14
15[0]: Documentation/devicetree/bindings/pwm/pwm.txt
16
17Examples:
18ssd1307: oled@3c {
19 compatible = "solomon,ssd1307fb-i2c";
20 reg = <0x3c>;
21 pwms = <&pwm 4 3000>;
22 reset-gpios = <&gpio2 7>;
23 reset-active-low;
24};
diff --git a/MAINTAINERS b/MAINTAINERS
index b95ae9b07121..f71d2f901a69 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3162,6 +3162,12 @@ F: drivers/video/
3162F: include/video/ 3162F: include/video/
3163F: include/linux/fb.h 3163F: include/linux/fb.h
3164 3164
3165FREESCALE DIU FRAMEBUFFER DRIVER
3166M: Timur Tabi <timur@freescale.com>
3167L: linux-fbdev@vger.kernel.org
3168S: Supported
3169F: drivers/video/fsl-diu-fb.*
3170
3165FREESCALE DMA DRIVER 3171FREESCALE DMA DRIVER
3166M: Li Yang <leoli@freescale.com> 3172M: Li Yang <leoli@freescale.com>
3167M: Zhang Wei <zw@zh-kernel.org> 3173M: Zhang Wei <zw@zh-kernel.org>
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 510648e0394b..678a54a64dae 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -408,7 +408,7 @@ static struct clk_lookup da830_clks[] = {
408 CLK(NULL, "pwm2", &pwm2_clk), 408 CLK(NULL, "pwm2", &pwm2_clk),
409 CLK("eqep.0", NULL, &eqep0_clk), 409 CLK("eqep.0", NULL, &eqep0_clk),
410 CLK("eqep.1", NULL, &eqep1_clk), 410 CLK("eqep.1", NULL, &eqep1_clk),
411 CLK("da8xx_lcdc.0", NULL, &lcdc_clk), 411 CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
412 CLK("davinci-mcasp.0", NULL, &mcasp0_clk), 412 CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
413 CLK("davinci-mcasp.1", NULL, &mcasp1_clk), 413 CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
414 CLK("davinci-mcasp.2", NULL, &mcasp2_clk), 414 CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 68c5fe01857c..6b9154e9f908 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -403,7 +403,7 @@ static struct clk_lookup da850_clks[] = {
403 CLK(NULL, "rmii", &rmii_clk), 403 CLK(NULL, "rmii", &rmii_clk),
404 CLK("davinci_emac.1", NULL, &emac_clk), 404 CLK("davinci_emac.1", NULL, &emac_clk),
405 CLK("davinci-mcasp.0", NULL, &mcasp_clk), 405 CLK("davinci-mcasp.0", NULL, &mcasp_clk),
406 CLK("da8xx_lcdc.0", NULL, &lcdc_clk), 406 CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
407 CLK("davinci_mmc.0", NULL, &mmcsd0_clk), 407 CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
408 CLK("davinci_mmc.1", NULL, &mmcsd1_clk), 408 CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
409 CLK(NULL, "aemif", &aemif_clk), 409 CLK(NULL, "aemif", &aemif_clk),
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 46c9a0c09ae5..fcdbe437409e 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -589,29 +589,9 @@ int __init da8xx_register_uio_pruss(void)
589 return platform_device_register(&da8xx_uio_pruss_dev); 589 return platform_device_register(&da8xx_uio_pruss_dev);
590} 590}
591 591
592static const struct display_panel disp_panel = {
593 QVGA,
594 16,
595 16,
596 COLOR_ACTIVE,
597};
598
599static struct lcd_ctrl_config lcd_cfg = { 592static struct lcd_ctrl_config lcd_cfg = {
600 &disp_panel, 593 .panel_shade = COLOR_ACTIVE,
601 .ac_bias = 255,
602 .ac_bias_intrpt = 0,
603 .dma_burst_sz = 16,
604 .bpp = 16, 594 .bpp = 16,
605 .fdd = 255,
606 .tft_alt_mode = 0,
607 .stn_565_mode = 0,
608 .mono_8bit_mode = 0,
609 .invert_line_clock = 1,
610 .invert_frm_clock = 1,
611 .sync_edge = 0,
612 .sync_ctrl = 1,
613 .raster_order = 0,
614 .fifo_th = 6,
615}; 595};
616 596
617struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = { 597struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = {
diff --git a/arch/arm/mach-davinci/pm_domain.c b/arch/arm/mach-davinci/pm_domain.c
index 00946e23c1ee..c90250e3bef8 100644
--- a/arch/arm/mach-davinci/pm_domain.c
+++ b/arch/arm/mach-davinci/pm_domain.c
@@ -53,6 +53,7 @@ static struct dev_pm_domain davinci_pm_domain = {
53 53
54static struct pm_clk_notifier_block platform_bus_notifier = { 54static struct pm_clk_notifier_block platform_bus_notifier = {
55 .pm_domain = &davinci_pm_domain, 55 .pm_domain = &davinci_pm_domain,
56 .con_ids = { "fck", NULL, },
56}; 57};
57 58
58static int __init davinci_pm_runtime_init(void) 59static int __init davinci_pm_runtime_init(void)
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
index c22e111bcd00..46f4fc982766 100644
--- a/arch/arm/mach-omap2/board-rx51-video.c
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -16,7 +16,6 @@
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <asm/mach-types.h> 17#include <asm/mach-types.h>
18#include <video/omapdss.h> 18#include <video/omapdss.h>
19#include <plat/vram.h>
20#include <linux/platform_data/spi-omap2-mcspi.h> 19#include <linux/platform_data/spi-omap2-mcspi.h>
21 20
22#include "board-rx51.h" 21#include "board-rx51.h"
@@ -87,17 +86,4 @@ static int __init rx51_video_init(void)
87} 86}
88 87
89subsys_initcall(rx51_video_init); 88subsys_initcall(rx51_video_init);
90
91void __init rx51_video_mem_init(void)
92{
93 /*
94 * GFX 864x480x32bpp
95 * VID1/2 1280x720x32bpp double buffered
96 */
97 omap_vram_set_sdram_vram(PAGE_ALIGN(864 * 480 * 4) +
98 2 * PAGE_ALIGN(1280 * 720 * 4 * 2), 0);
99}
100
101#else
102void __init rx51_video_mem_init(void) { }
103#endif /* defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) */ 89#endif /* defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) */
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index f1d6efe079ca..d0374ea2dfb0 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -34,8 +34,6 @@
34 34
35#define RX51_GPIO_SLEEP_IND 162 35#define RX51_GPIO_SLEEP_IND 162
36 36
37extern void rx51_video_mem_init(void);
38
39static struct gpio_led gpio_leds[] = { 37static struct gpio_led gpio_leds[] = {
40 { 38 {
41 .name = "sleep_ind", 39 .name = "sleep_ind",
@@ -112,7 +110,6 @@ static void __init rx51_init(void)
112 110
113static void __init rx51_reserve(void) 111static void __init rx51_reserve(void)
114{ 112{
115 rx51_video_mem_init();
116 omap_reserve(); 113 omap_reserve();
117} 114}
118 115
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 38ba58c97628..cc75aaf6e764 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -102,17 +102,20 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = {
102 { "dss_hdmi", "omapdss_hdmi", -1 }, 102 { "dss_hdmi", "omapdss_hdmi", -1 },
103}; 103};
104 104
105static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags) 105static void __init omap4_tpd12s015_mux_pads(void)
106{ 106{
107 u32 reg;
108 u16 control_i2c_1;
109
110 omap_mux_init_signal("hdmi_cec", 107 omap_mux_init_signal("hdmi_cec",
111 OMAP_PIN_INPUT_PULLUP); 108 OMAP_PIN_INPUT_PULLUP);
112 omap_mux_init_signal("hdmi_ddc_scl", 109 omap_mux_init_signal("hdmi_ddc_scl",
113 OMAP_PIN_INPUT_PULLUP); 110 OMAP_PIN_INPUT_PULLUP);
114 omap_mux_init_signal("hdmi_ddc_sda", 111 omap_mux_init_signal("hdmi_ddc_sda",
115 OMAP_PIN_INPUT_PULLUP); 112 OMAP_PIN_INPUT_PULLUP);
113}
114
115static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
116{
117 u32 reg;
118 u16 control_i2c_1;
116 119
117 /* 120 /*
118 * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and 121 * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and
@@ -163,8 +166,10 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
163 166
164int __init omap_hdmi_init(enum omap_hdmi_flags flags) 167int __init omap_hdmi_init(enum omap_hdmi_flags flags)
165{ 168{
166 if (cpu_is_omap44xx()) 169 if (cpu_is_omap44xx()) {
167 omap4_hdmi_mux_pads(flags); 170 omap4_hdmi_mux_pads(flags);
171 omap4_tpd12s015_mux_pads();
172 }
168 173
169 return 0; 174 return 0;
170} 175}
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 25eb88a923e6..032d10817e79 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -213,95 +213,6 @@ static struct platform_device irda_device = {
213 .num_resources = ARRAY_SIZE(irda_resources), 213 .num_resources = ARRAY_SIZE(irda_resources),
214}; 214};
215 215
216static unsigned char lcd_backlight_seq[3][2] = {
217 { 0x04, 0x07 },
218 { 0x23, 0x80 },
219 { 0x03, 0x01 },
220};
221
222static void lcd_backlight_on(void)
223{
224 struct i2c_adapter *a;
225 struct i2c_msg msg;
226 int k;
227
228 a = i2c_get_adapter(1);
229 for (k = 0; a && k < 3; k++) {
230 msg.addr = 0x6d;
231 msg.buf = &lcd_backlight_seq[k][0];
232 msg.len = 2;
233 msg.flags = 0;
234 if (i2c_transfer(a, &msg, 1) != 1)
235 break;
236 }
237}
238
239static void lcd_backlight_reset(void)
240{
241 gpio_set_value(GPIO_PORT235, 0);
242 mdelay(24);
243 gpio_set_value(GPIO_PORT235, 1);
244}
245
246/* LCDC0 */
247static const struct fb_videomode lcdc0_modes[] = {
248 {
249 .name = "R63302(QHD)",
250 .xres = 544,
251 .yres = 961,
252 .left_margin = 72,
253 .right_margin = 600,
254 .hsync_len = 16,
255 .upper_margin = 8,
256 .lower_margin = 8,
257 .vsync_len = 2,
258 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
259 },
260};
261
262static struct sh_mobile_lcdc_info lcdc0_info = {
263 .clock_source = LCDC_CLK_PERIPHERAL,
264 .ch[0] = {
265 .chan = LCDC_CHAN_MAINLCD,
266 .interface_type = RGB24,
267 .clock_divider = 1,
268 .flags = LCDC_FLAGS_DWPOL,
269 .fourcc = V4L2_PIX_FMT_RGB565,
270 .lcd_modes = lcdc0_modes,
271 .num_modes = ARRAY_SIZE(lcdc0_modes),
272 .panel_cfg = {
273 .width = 44,
274 .height = 79,
275 .display_on = lcd_backlight_on,
276 .display_off = lcd_backlight_reset,
277 },
278 }
279};
280
281static struct resource lcdc0_resources[] = {
282 [0] = {
283 .name = "LCDC0",
284 .start = 0xfe940000, /* P4-only space */
285 .end = 0xfe943fff,
286 .flags = IORESOURCE_MEM,
287 },
288 [1] = {
289 .start = intcs_evt2irq(0x580),
290 .flags = IORESOURCE_IRQ,
291 },
292};
293
294static struct platform_device lcdc0_device = {
295 .name = "sh_mobile_lcdc_fb",
296 .num_resources = ARRAY_SIZE(lcdc0_resources),
297 .resource = lcdc0_resources,
298 .id = 0,
299 .dev = {
300 .platform_data = &lcdc0_info,
301 .coherent_dma_mask = ~0,
302 },
303};
304
305/* MIPI-DSI */ 216/* MIPI-DSI */
306static struct resource mipidsi0_resources[] = { 217static struct resource mipidsi0_resources[] = {
307 [0] = { 218 [0] = {
@@ -358,7 +269,7 @@ sh_mipi_set_dot_clock_pck_err:
358 269
359static struct sh_mipi_dsi_info mipidsi0_info = { 270static struct sh_mipi_dsi_info mipidsi0_info = {
360 .data_format = MIPI_RGB888, 271 .data_format = MIPI_RGB888,
361 .lcd_chan = &lcdc0_info.ch[0], 272 .channel = LCDC_CHAN_MAINLCD,
362 .lane = 2, 273 .lane = 2,
363 .vsynw_offset = 20, 274 .vsynw_offset = 20,
364 .clksrc = 1, 275 .clksrc = 1,
@@ -378,6 +289,109 @@ static struct platform_device mipidsi0_device = {
378 }, 289 },
379}; 290};
380 291
292static unsigned char lcd_backlight_seq[3][2] = {
293 { 0x04, 0x07 },
294 { 0x23, 0x80 },
295 { 0x03, 0x01 },
296};
297
298static int lcd_backlight_set_brightness(int brightness)
299{
300 struct i2c_adapter *adap;
301 struct i2c_msg msg;
302 unsigned int i;
303 int ret;
304
305 if (brightness == 0) {
306 /* Reset the chip */
307 gpio_set_value(GPIO_PORT235, 0);
308 mdelay(24);
309 gpio_set_value(GPIO_PORT235, 1);
310 return 0;
311 }
312
313 adap = i2c_get_adapter(1);
314 if (adap == NULL)
315 return -ENODEV;
316
317 for (i = 0; i < ARRAY_SIZE(lcd_backlight_seq); i++) {
318 msg.addr = 0x6d;
319 msg.buf = &lcd_backlight_seq[i][0];
320 msg.len = 2;
321 msg.flags = 0;
322
323 ret = i2c_transfer(adap, &msg, 1);
324 if (ret < 0)
325 break;
326 }
327
328 i2c_put_adapter(adap);
329 return ret < 0 ? ret : 0;
330}
331
332/* LCDC0 */
333static const struct fb_videomode lcdc0_modes[] = {
334 {
335 .name = "R63302(QHD)",
336 .xres = 544,
337 .yres = 961,
338 .left_margin = 72,
339 .right_margin = 600,
340 .hsync_len = 16,
341 .upper_margin = 8,
342 .lower_margin = 8,
343 .vsync_len = 2,
344 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
345 },
346};
347
348static struct sh_mobile_lcdc_info lcdc0_info = {
349 .clock_source = LCDC_CLK_PERIPHERAL,
350 .ch[0] = {
351 .chan = LCDC_CHAN_MAINLCD,
352 .interface_type = RGB24,
353 .clock_divider = 1,
354 .flags = LCDC_FLAGS_DWPOL,
355 .fourcc = V4L2_PIX_FMT_RGB565,
356 .lcd_modes = lcdc0_modes,
357 .num_modes = ARRAY_SIZE(lcdc0_modes),
358 .panel_cfg = {
359 .width = 44,
360 .height = 79,
361 },
362 .bl_info = {
363 .name = "sh_mobile_lcdc_bl",
364 .max_brightness = 1,
365 .set_brightness = lcd_backlight_set_brightness,
366 },
367 .tx_dev = &mipidsi0_device,
368 }
369};
370
371static struct resource lcdc0_resources[] = {
372 [0] = {
373 .name = "LCDC0",
374 .start = 0xfe940000, /* P4-only space */
375 .end = 0xfe943fff,
376 .flags = IORESOURCE_MEM,
377 },
378 [1] = {
379 .start = intcs_evt2irq(0x580),
380 .flags = IORESOURCE_IRQ,
381 },
382};
383
384static struct platform_device lcdc0_device = {
385 .name = "sh_mobile_lcdc_fb",
386 .num_resources = ARRAY_SIZE(lcdc0_resources),
387 .resource = lcdc0_resources,
388 .id = 0,
389 .dev = {
390 .platform_data = &lcdc0_info,
391 .coherent_dma_mask = ~0,
392 },
393};
394
381/* Fixed 2.8V regulators to be used by SDHI0 */ 395/* Fixed 2.8V regulators to be used by SDHI0 */
382static struct regulator_consumer_supply fixed2v8_power_consumers[] = 396static struct regulator_consumer_supply fixed2v8_power_consumers[] =
383{ 397{
@@ -531,8 +545,8 @@ static struct platform_device *ag5evm_devices[] __initdata = {
531 &fsi_device, 545 &fsi_device,
532 &mmc_device, 546 &mmc_device,
533 &irda_device, 547 &irda_device,
534 &lcdc0_device,
535 &mipidsi0_device, 548 &mipidsi0_device,
549 &lcdc0_device,
536 &sdhi0_device, 550 &sdhi0_device,
537 &sdhi1_device, 551 &sdhi1_device,
538}; 552};
@@ -621,7 +635,7 @@ static void __init ag5evm_init(void)
621 /* LCD backlight controller */ 635 /* LCD backlight controller */
622 gpio_request(GPIO_PORT235, NULL); /* RESET */ 636 gpio_request(GPIO_PORT235, NULL); /* RESET */
623 gpio_direction_output(GPIO_PORT235, 0); 637 gpio_direction_output(GPIO_PORT235, 0);
624 lcd_backlight_reset(); 638 lcd_backlight_set_brightness(0);
625 639
626 /* enable SDHI0 on CN15 [SD I/F] */ 640 /* enable SDHI0 on CN15 [SD I/F] */
627 gpio_request(GPIO_FN_SDHIWP0, NULL); 641 gpio_request(GPIO_FN_SDHIWP0, NULL);
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 40657854e3ad..99ef190d0909 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -552,11 +552,9 @@ static struct resource mipidsi0_resources[] = {
552 }, 552 },
553}; 553};
554 554
555static struct sh_mobile_lcdc_info lcdc_info;
556
557static struct sh_mipi_dsi_info mipidsi0_info = { 555static struct sh_mipi_dsi_info mipidsi0_info = {
558 .data_format = MIPI_RGB888, 556 .data_format = MIPI_RGB888,
559 .lcd_chan = &lcdc_info.ch[0], 557 .channel = LCDC_CHAN_MAINLCD,
560 .lane = 2, 558 .lane = 2,
561 .vsynw_offset = 17, 559 .vsynw_offset = 17,
562 .phyctrl = 0x6 << 8, 560 .phyctrl = 0x6 << 8,
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 3f56e70795b7..2fed62f66045 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -370,11 +370,6 @@ static int mackerel_set_brightness(int brightness)
370 return 0; 370 return 0;
371} 371}
372 372
373static int mackerel_get_brightness(void)
374{
375 return gpio_get_value(GPIO_PORT31);
376}
377
378static const struct sh_mobile_meram_cfg lcd_meram_cfg = { 373static const struct sh_mobile_meram_cfg lcd_meram_cfg = {
379 .icb[0] = { 374 .icb[0] = {
380 .meram_size = 0x40, 375 .meram_size = 0x40,
@@ -403,7 +398,6 @@ static struct sh_mobile_lcdc_info lcdc_info = {
403 .name = "sh_mobile_lcdc_bl", 398 .name = "sh_mobile_lcdc_bl",
404 .max_brightness = 1, 399 .max_brightness = 1,
405 .set_brightness = mackerel_set_brightness, 400 .set_brightness = mackerel_set_brightness,
406 .get_brightness = mackerel_get_brightness,
407 }, 401 },
408 .meram_cfg = &lcd_meram_cfg, 402 .meram_cfg = &lcd_meram_cfg,
409 } 403 }
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index 3a77b30f53d4..a3367b783fc7 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -29,6 +29,7 @@
29#include <linux/memblock.h> 29#include <linux/memblock.h>
30#include <linux/io.h> 30#include <linux/io.h>
31#include <linux/omapfb.h> 31#include <linux/omapfb.h>
32#include <linux/dma-mapping.h>
32 33
33#include <asm/mach/map.h> 34#include <asm/mach/map.h>
34 35
@@ -105,7 +106,7 @@ static struct platform_device omap_fb_device = {
105 .id = -1, 106 .id = -1,
106 .dev = { 107 .dev = {
107 .dma_mask = &omap_fb_dma_mask, 108 .dma_mask = &omap_fb_dma_mask,
108 .coherent_dma_mask = ~(u32)0, 109 .coherent_dma_mask = DMA_BIT_MASK(32),
109 .platform_data = &omapfb_config, 110 .platform_data = &omapfb_config,
110 }, 111 },
111 .num_resources = 0, 112 .num_resources = 0,
@@ -141,7 +142,7 @@ static struct platform_device omap_fb_device = {
141 .id = -1, 142 .id = -1,
142 .dev = { 143 .dev = {
143 .dma_mask = &omap_fb_dma_mask, 144 .dma_mask = &omap_fb_dma_mask,
144 .coherent_dma_mask = ~(u32)0, 145 .coherent_dma_mask = DMA_BIT_MASK(32),
145 .platform_data = &omapfb_config, 146 .platform_data = &omapfb_config,
146 }, 147 },
147 .num_resources = 0, 148 .num_resources = 0,
diff --git a/arch/arm/plat-omap/include/plat/vram.h b/arch/arm/plat-omap/include/plat/vram.h
deleted file mode 100644
index 4d65b7d06e6c..000000000000
--- a/arch/arm/plat-omap/include/plat/vram.h
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * VRAM manager for OMAP
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef __OMAP_VRAM_H__
22#define __OMAP_VRAM_H__
23
24#include <linux/types.h>
25
26extern int omap_vram_add_region(unsigned long paddr, size_t size);
27extern int omap_vram_free(unsigned long paddr, size_t size);
28extern int omap_vram_alloc(size_t size, unsigned long *paddr);
29extern int omap_vram_reserve(unsigned long paddr, size_t size);
30extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
31 unsigned long *largest_free_block);
32
33#ifdef CONFIG_OMAP2_VRAM
34extern void omap_vram_set_sdram_vram(u32 size, u32 start);
35
36extern void omap_vram_reserve_sdram_memblock(void);
37#else
38static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
39
40static inline void omap_vram_reserve_sdram_memblock(void) { }
41#endif
42
43#endif
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 9e963c1d1447..5620e33c18a0 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -179,11 +179,6 @@ static int ap320_wvga_set_brightness(int brightness)
179 return 0; 179 return 0;
180} 180}
181 181
182static int ap320_wvga_get_brightness(void)
183{
184 return gpio_get_value(GPIO_PTS3);
185}
186
187static void ap320_wvga_power_on(void) 182static void ap320_wvga_power_on(void)
188{ 183{
189 msleep(100); 184 msleep(100);
@@ -232,7 +227,6 @@ static struct sh_mobile_lcdc_info lcdc_info = {
232 .name = "sh_mobile_lcdc_bl", 227 .name = "sh_mobile_lcdc_bl",
233 .max_brightness = 1, 228 .max_brightness = 1,
234 .set_brightness = ap320_wvga_set_brightness, 229 .set_brightness = ap320_wvga_set_brightness,
235 .get_brightness = ap320_wvga_get_brightness,
236 }, 230 },
237 } 231 }
238}; 232};
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 64559e8af14b..3fede4556c91 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -329,11 +329,6 @@ static int ecovec24_set_brightness(int brightness)
329 return 0; 329 return 0;
330} 330}
331 331
332static int ecovec24_get_brightness(void)
333{
334 return gpio_get_value(GPIO_PTR1);
335}
336
337static struct sh_mobile_lcdc_info lcdc_info = { 332static struct sh_mobile_lcdc_info lcdc_info = {
338 .ch[0] = { 333 .ch[0] = {
339 .interface_type = RGB18, 334 .interface_type = RGB18,
@@ -347,7 +342,6 @@ static struct sh_mobile_lcdc_info lcdc_info = {
347 .name = "sh_mobile_lcdc_bl", 342 .name = "sh_mobile_lcdc_bl",
348 .max_brightness = 1, 343 .max_brightness = 1,
349 .set_brightness = ecovec24_set_brightness, 344 .set_brightness = ecovec24_set_brightness,
350 .get_brightness = ecovec24_get_brightness,
351 }, 345 },
352 } 346 }
353}; 347};
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
index c148b36ecb65..c62050332629 100644
--- a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
+++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
@@ -283,7 +283,7 @@ void kfr2r09_lcd_start(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
283#define MAIN_MLED4 0x40 283#define MAIN_MLED4 0x40
284#define MAIN_MSW 0x80 284#define MAIN_MSW 0x80
285 285
286static int kfr2r09_lcd_backlight(int on) 286int kfr2r09_lcd_set_brightness(int brightness)
287{ 287{
288 struct i2c_adapter *a; 288 struct i2c_adapter *a;
289 struct i2c_msg msg; 289 struct i2c_msg msg;
@@ -295,7 +295,7 @@ static int kfr2r09_lcd_backlight(int on)
295 return -ENODEV; 295 return -ENODEV;
296 296
297 buf[0] = 0x00; 297 buf[0] = 0x00;
298 if (on) 298 if (brightness)
299 buf[1] = CTRL_CPSW | CTRL_C10 | CTRL_CKSW; 299 buf[1] = CTRL_CPSW | CTRL_C10 | CTRL_CKSW;
300 else 300 else
301 buf[1] = 0; 301 buf[1] = 0;
@@ -309,7 +309,7 @@ static int kfr2r09_lcd_backlight(int on)
309 return -ENODEV; 309 return -ENODEV;
310 310
311 buf[0] = 0x01; 311 buf[0] = 0x01;
312 if (on) 312 if (brightness)
313 buf[1] = MAIN_MSW | MAIN_MLED4 | 0x0c; 313 buf[1] = MAIN_MSW | MAIN_MLED4 | 0x0c;
314 else 314 else
315 buf[1] = 0; 315 buf[1] = 0;
@@ -324,13 +324,3 @@ static int kfr2r09_lcd_backlight(int on)
324 324
325 return 0; 325 return 0;
326} 326}
327
328void kfr2r09_lcd_on(void)
329{
330 kfr2r09_lcd_backlight(1);
331}
332
333void kfr2r09_lcd_off(void)
334{
335 kfr2r09_lcd_backlight(0);
336}
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index f2a4304fbe23..ab502f12ef57 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -158,8 +158,11 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
158 .height = 58, 158 .height = 58,
159 .setup_sys = kfr2r09_lcd_setup, 159 .setup_sys = kfr2r09_lcd_setup,
160 .start_transfer = kfr2r09_lcd_start, 160 .start_transfer = kfr2r09_lcd_start,
161 .display_on = kfr2r09_lcd_on, 161 },
162 .display_off = kfr2r09_lcd_off, 162 .bl_info = {
163 .name = "sh_mobile_lcdc_bl",
164 .max_brightness = 1,
165 .set_brightness = kfr2r09_lcd_set_brightness,
163 }, 166 },
164 .sys_bus_cfg = { 167 .sys_bus_cfg = {
165 .ldmt2r = 0x07010904, 168 .ldmt2r = 0x07010904,
diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
index ba3d93d333f8..c20c9e5f5eab 100644
--- a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
+++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
@@ -4,15 +4,13 @@
4#include <video/sh_mobile_lcdc.h> 4#include <video/sh_mobile_lcdc.h>
5 5
6#if defined(CONFIG_FB_SH_MOBILE_LCDC) || defined(CONFIG_FB_SH_MOBILE_LCDC_MODULE) 6#if defined(CONFIG_FB_SH_MOBILE_LCDC) || defined(CONFIG_FB_SH_MOBILE_LCDC_MODULE)
7void kfr2r09_lcd_on(void); 7int kfr2r09_lcd_set_brightness(int brightness);
8void kfr2r09_lcd_off(void);
9int kfr2r09_lcd_setup(void *sys_ops_handle, 8int kfr2r09_lcd_setup(void *sys_ops_handle,
10 struct sh_mobile_lcdc_sys_bus_ops *sys_ops); 9 struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
11void kfr2r09_lcd_start(void *sys_ops_handle, 10void kfr2r09_lcd_start(void *sys_ops_handle,
12 struct sh_mobile_lcdc_sys_bus_ops *sys_ops); 11 struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
13#else 12#else
14static void kfr2r09_lcd_on(void) {} 13static int kfr2r09_lcd_set_brightness(int brightness) {}
15static void kfr2r09_lcd_off(void) {}
16static int kfr2r09_lcd_setup(void *sys_ops_handle, 14static int kfr2r09_lcd_setup(void *sys_ops_handle,
17 struct sh_mobile_lcdc_sys_bus_ops *sys_ops) 15 struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
18{ 16{
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 202d1b4b9bee..35cc526e6c93 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -44,8 +44,6 @@
44#include <media/v4l2-device.h> 44#include <media/v4l2-device.h>
45#include <media/v4l2-ioctl.h> 45#include <media/v4l2-ioctl.h>
46 46
47#include <plat/cpu.h>
48#include <linux/omap-dma.h>
49#include <video/omapvrfb.h> 47#include <video/omapvrfb.h>
50#include <video/omapdss.h> 48#include <video/omapdss.h>
51 49
@@ -2043,7 +2041,7 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev)
2043 vout->vid_info.id = k + 1; 2041 vout->vid_info.id = k + 1;
2044 2042
2045 /* Set VRFB as rotation_type for omap2 and omap3 */ 2043 /* Set VRFB as rotation_type for omap2 and omap3 */
2046 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 2044 if (omap_vout_dss_omap24xx() || omap_vout_dss_omap34xx())
2047 vout->vid_info.rotation_type = VOUT_ROT_VRFB; 2045 vout->vid_info.rotation_type = VOUT_ROT_VRFB;
2048 2046
2049 /* Setup the default configuration for the video devices 2047 /* Setup the default configuration for the video devices
@@ -2160,14 +2158,23 @@ static int __init omap_vout_probe(struct platform_device *pdev)
2160 struct omap_dss_device *def_display; 2158 struct omap_dss_device *def_display;
2161 struct omap2video_device *vid_dev = NULL; 2159 struct omap2video_device *vid_dev = NULL;
2162 2160
2161 ret = omapdss_compat_init();
2162 if (ret) {
2163 dev_err(&pdev->dev, "failed to init dss\n");
2164 return ret;
2165 }
2166
2163 if (pdev->num_resources == 0) { 2167 if (pdev->num_resources == 0) {
2164 dev_err(&pdev->dev, "probed for an unknown device\n"); 2168 dev_err(&pdev->dev, "probed for an unknown device\n");
2165 return -ENODEV; 2169 ret = -ENODEV;
2170 goto err_dss_init;
2166 } 2171 }
2167 2172
2168 vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL); 2173 vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
2169 if (vid_dev == NULL) 2174 if (vid_dev == NULL) {
2170 return -ENOMEM; 2175 ret = -ENOMEM;
2176 goto err_dss_init;
2177 }
2171 2178
2172 vid_dev->num_displays = 0; 2179 vid_dev->num_displays = 0;
2173 for_each_dss_dev(dssdev) { 2180 for_each_dss_dev(dssdev) {
@@ -2262,6 +2269,8 @@ probe_err1:
2262 } 2269 }
2263probe_err0: 2270probe_err0:
2264 kfree(vid_dev); 2271 kfree(vid_dev);
2272err_dss_init:
2273 omapdss_compat_uninit();
2265 return ret; 2274 return ret;
2266} 2275}
2267 2276
diff --git a/drivers/media/platform/omap/omap_voutlib.c b/drivers/media/platform/omap/omap_voutlib.c
index 115408b9274f..80b0d88f125c 100644
--- a/drivers/media/platform/omap/omap_voutlib.c
+++ b/drivers/media/platform/omap/omap_voutlib.c
@@ -26,7 +26,7 @@
26 26
27#include <linux/dma-mapping.h> 27#include <linux/dma-mapping.h>
28 28
29#include <plat/cpu.h> 29#include <video/omapdss.h>
30 30
31#include "omap_voutlib.h" 31#include "omap_voutlib.h"
32 32
@@ -124,7 +124,7 @@ int omap_vout_new_window(struct v4l2_rect *crop,
124 win->chromakey = new_win->chromakey; 124 win->chromakey = new_win->chromakey;
125 125
126 /* Adjust the cropping window to allow for resizing limitation */ 126 /* Adjust the cropping window to allow for resizing limitation */
127 if (cpu_is_omap24xx()) { 127 if (omap_vout_dss_omap24xx()) {
128 /* For 24xx limit is 8x to 1/2x scaling. */ 128 /* For 24xx limit is 8x to 1/2x scaling. */
129 if ((crop->height/win->w.height) >= 2) 129 if ((crop->height/win->w.height) >= 2)
130 crop->height = win->w.height * 2; 130 crop->height = win->w.height * 2;
@@ -140,7 +140,7 @@ int omap_vout_new_window(struct v4l2_rect *crop,
140 if (crop->height != win->w.height) 140 if (crop->height != win->w.height)
141 crop->width = 768; 141 crop->width = 768;
142 } 142 }
143 } else if (cpu_is_omap34xx()) { 143 } else if (omap_vout_dss_omap34xx()) {
144 /* For 34xx limit is 8x to 1/4x scaling. */ 144 /* For 34xx limit is 8x to 1/4x scaling. */
145 if ((crop->height/win->w.height) >= 4) 145 if ((crop->height/win->w.height) >= 4)
146 crop->height = win->w.height * 4; 146 crop->height = win->w.height * 4;
@@ -196,7 +196,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
196 if (try_crop.width <= 0 || try_crop.height <= 0) 196 if (try_crop.width <= 0 || try_crop.height <= 0)
197 return -EINVAL; 197 return -EINVAL;
198 198
199 if (cpu_is_omap24xx()) { 199 if (omap_vout_dss_omap24xx()) {
200 if (try_crop.height != win->w.height) { 200 if (try_crop.height != win->w.height) {
201 /* If we're resizing vertically, we can't support a 201 /* If we're resizing vertically, we can't support a
202 * crop width wider than 768 pixels. 202 * crop width wider than 768 pixels.
@@ -207,9 +207,9 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
207 } 207 }
208 /* vertical resizing */ 208 /* vertical resizing */
209 vresize = (1024 * try_crop.height) / win->w.height; 209 vresize = (1024 * try_crop.height) / win->w.height;
210 if (cpu_is_omap24xx() && (vresize > 2048)) 210 if (omap_vout_dss_omap24xx() && (vresize > 2048))
211 vresize = 2048; 211 vresize = 2048;
212 else if (cpu_is_omap34xx() && (vresize > 4096)) 212 else if (omap_vout_dss_omap34xx() && (vresize > 4096))
213 vresize = 4096; 213 vresize = 4096;
214 214
215 win->w.height = ((1024 * try_crop.height) / vresize) & ~1; 215 win->w.height = ((1024 * try_crop.height) / vresize) & ~1;
@@ -226,9 +226,9 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
226 } 226 }
227 /* horizontal resizing */ 227 /* horizontal resizing */
228 hresize = (1024 * try_crop.width) / win->w.width; 228 hresize = (1024 * try_crop.width) / win->w.width;
229 if (cpu_is_omap24xx() && (hresize > 2048)) 229 if (omap_vout_dss_omap24xx() && (hresize > 2048))
230 hresize = 2048; 230 hresize = 2048;
231 else if (cpu_is_omap34xx() && (hresize > 4096)) 231 else if (omap_vout_dss_omap34xx() && (hresize > 4096))
232 hresize = 4096; 232 hresize = 4096;
233 233
234 win->w.width = ((1024 * try_crop.width) / hresize) & ~1; 234 win->w.width = ((1024 * try_crop.width) / hresize) & ~1;
@@ -243,7 +243,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
243 if (try_crop.width == 0) 243 if (try_crop.width == 0)
244 try_crop.width = 2; 244 try_crop.width = 2;
245 } 245 }
246 if (cpu_is_omap24xx()) { 246 if (omap_vout_dss_omap24xx()) {
247 if ((try_crop.height/win->w.height) >= 2) 247 if ((try_crop.height/win->w.height) >= 2)
248 try_crop.height = win->w.height * 2; 248 try_crop.height = win->w.height * 2;
249 249
@@ -258,7 +258,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
258 if (try_crop.height != win->w.height) 258 if (try_crop.height != win->w.height)
259 try_crop.width = 768; 259 try_crop.width = 768;
260 } 260 }
261 } else if (cpu_is_omap34xx()) { 261 } else if (omap_vout_dss_omap34xx()) {
262 if ((try_crop.height/win->w.height) >= 4) 262 if ((try_crop.height/win->w.height) >= 4)
263 try_crop.height = win->w.height * 4; 263 try_crop.height = win->w.height * 4;
264 264
@@ -337,3 +337,21 @@ void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size)
337 } 337 }
338 free_pages((unsigned long) virtaddr, order); 338 free_pages((unsigned long) virtaddr, order);
339} 339}
340
341bool omap_vout_dss_omap24xx(void)
342{
343 return omapdss_get_version() == OMAPDSS_VER_OMAP24xx;
344}
345
346bool omap_vout_dss_omap34xx(void)
347{
348 switch (omapdss_get_version()) {
349 case OMAPDSS_VER_OMAP34xx_ES1:
350 case OMAPDSS_VER_OMAP34xx_ES3:
351 case OMAPDSS_VER_OMAP3630:
352 case OMAPDSS_VER_AM35xx:
353 return true;
354 default:
355 return false;
356 }
357}
diff --git a/drivers/media/platform/omap/omap_voutlib.h b/drivers/media/platform/omap/omap_voutlib.h
index e51750a597e3..f9d1c0779f33 100644
--- a/drivers/media/platform/omap/omap_voutlib.h
+++ b/drivers/media/platform/omap/omap_voutlib.h
@@ -32,5 +32,8 @@ void omap_vout_new_format(struct v4l2_pix_format *pix,
32 struct v4l2_window *win); 32 struct v4l2_window *win);
33unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr); 33unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr);
34void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size); 34void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size);
35
36bool omap_vout_dss_omap24xx(void);
37bool omap_vout_dss_omap34xx(void);
35#endif /* #ifndef OMAP_VOUTLIB_H */ 38#endif /* #ifndef OMAP_VOUTLIB_H */
36 39
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index d4823fd67768..84943e5ba1d6 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -565,6 +565,14 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
565 565
566 dev->dev_private = priv; 566 dev->dev_private = priv;
567 567
568 ret = omapdss_compat_init();
569 if (ret) {
570 dev_err(dev->dev, "coult not init omapdss\n");
571 dev->dev_private = NULL;
572 kfree(priv);
573 return ret;
574 }
575
568 priv->wq = alloc_ordered_workqueue("omapdrm", 0); 576 priv->wq = alloc_ordered_workqueue("omapdrm", 0);
569 577
570 INIT_LIST_HEAD(&priv->obj_list); 578 INIT_LIST_HEAD(&priv->obj_list);
@@ -576,6 +584,7 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
576 dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret); 584 dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret);
577 dev->dev_private = NULL; 585 dev->dev_private = NULL;
578 kfree(priv); 586 kfree(priv);
587 omapdss_compat_uninit();
579 return ret; 588 return ret;
580 } 589 }
581 590
@@ -610,6 +619,8 @@ static int dev_unload(struct drm_device *dev)
610 flush_workqueue(priv->wq); 619 flush_workqueue(priv->wq);
611 destroy_workqueue(priv->wq); 620 destroy_workqueue(priv->wq);
612 621
622 omapdss_compat_uninit();
623
613 kfree(dev->dev_private); 624 kfree(dev->dev_private);
614 dev->dev_private = NULL; 625 dev->dev_private = NULL;
615 626
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d08d7998a4aa..9c31277b3a81 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2045,7 +2045,7 @@ config FB_S3C_DEBUG_REGWRITE
2045 bool "Debug register writes" 2045 bool "Debug register writes"
2046 depends on FB_S3C 2046 depends on FB_S3C
2047 ---help--- 2047 ---help---
2048 Show all register writes via printk(KERN_DEBUG) 2048 Show all register writes via pr_debug()
2049 2049
2050config FB_S3C2410 2050config FB_S3C2410
2051 tristate "S3C2410 LCD framebuffer support" 2051 tristate "S3C2410 LCD framebuffer support"
@@ -2442,4 +2442,19 @@ config FB_SH_MOBILE_MERAM
2442 Up to 4 memory channels can be configured, allowing 4 RGB or 2442 Up to 4 memory channels can be configured, allowing 4 RGB or
2443 2 YCbCr framebuffers to be configured. 2443 2 YCbCr framebuffers to be configured.
2444 2444
2445config FB_SSD1307
2446 tristate "Solomon SSD1307 framebuffer support"
2447 depends on FB && I2C
2448 depends on OF
2449 depends on GENERIC_GPIO
2450 select FB_SYS_FOPS
2451 select FB_SYS_FILLRECT
2452 select FB_SYS_COPYAREA
2453 select FB_SYS_IMAGEBLIT
2454 select FB_DEFERRED_IO
2455 select PWM
2456 help
2457 This driver implements support for the Solomon SSD1307
2458 OLED controller over I2C.
2459
2445endmenu 2460endmenu
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 23e948ebfab8..768a137a1bac 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -161,6 +161,7 @@ obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o
161obj-$(CONFIG_FB_MX3) += mx3fb.o 161obj-$(CONFIG_FB_MX3) += mx3fb.o
162obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o 162obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
163obj-$(CONFIG_FB_MXS) += mxsfb.o 163obj-$(CONFIG_FB_MXS) += mxsfb.o
164obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
164 165
165# the test framebuffer is last 166# the test framebuffer is last
166obj-$(CONFIG_FB_VIRTUAL) += vfb.o 167obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 25f835bf3d72..46dd8f5d2e9e 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -35,8 +35,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
35 dsize = s_pitch * cursor->image.height; 35 dsize = s_pitch * cursor->image.height;
36 36
37 if (dsize + sizeof(struct fb_image) != ops->cursor_size) { 37 if (dsize + sizeof(struct fb_image) != ops->cursor_size) {
38 if (ops->cursor_src != NULL) 38 kfree(ops->cursor_src);
39 kfree(ops->cursor_src);
40 ops->cursor_size = dsize + sizeof(struct fb_image); 39 ops->cursor_size = dsize + sizeof(struct fb_image);
41 40
42 ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC); 41 ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC);
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 80665f66ac1a..46534e00fe01 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -213,62 +213,51 @@ static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = {
213 .accel = FB_ACCEL_NONE 213 .accel = FB_ACCEL_NONE
214}; 214};
215 215
216struct da8xx_panel { 216static struct fb_videomode known_lcd_panels[] = {
217 const char name[25]; /* Full name <vendor>_<model> */
218 unsigned short width;
219 unsigned short height;
220 int hfp; /* Horizontal front porch */
221 int hbp; /* Horizontal back porch */
222 int hsw; /* Horizontal Sync Pulse Width */
223 int vfp; /* Vertical front porch */
224 int vbp; /* Vertical back porch */
225 int vsw; /* Vertical Sync Pulse Width */
226 unsigned int pxl_clk; /* Pixel clock */
227 unsigned char invert_pxl_clk; /* Invert Pixel clock */
228};
229
230static struct da8xx_panel known_lcd_panels[] = {
231 /* Sharp LCD035Q3DG01 */ 217 /* Sharp LCD035Q3DG01 */
232 [0] = { 218 [0] = {
233 .name = "Sharp_LCD035Q3DG01", 219 .name = "Sharp_LCD035Q3DG01",
234 .width = 320, 220 .xres = 320,
235 .height = 240, 221 .yres = 240,
236 .hfp = 8, 222 .pixclock = 4608000,
237 .hbp = 6, 223 .left_margin = 6,
238 .hsw = 0, 224 .right_margin = 8,
239 .vfp = 2, 225 .upper_margin = 2,
240 .vbp = 2, 226 .lower_margin = 2,
241 .vsw = 0, 227 .hsync_len = 0,
242 .pxl_clk = 4608000, 228 .vsync_len = 0,
243 .invert_pxl_clk = 1, 229 .sync = FB_SYNC_CLK_INVERT |
230 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
244 }, 231 },
245 /* Sharp LK043T1DG01 */ 232 /* Sharp LK043T1DG01 */
246 [1] = { 233 [1] = {
247 .name = "Sharp_LK043T1DG01", 234 .name = "Sharp_LK043T1DG01",
248 .width = 480, 235 .xres = 480,
249 .height = 272, 236 .yres = 272,
250 .hfp = 2, 237 .pixclock = 7833600,
251 .hbp = 2, 238 .left_margin = 2,
252 .hsw = 41, 239 .right_margin = 2,
253 .vfp = 2, 240 .upper_margin = 2,
254 .vbp = 2, 241 .lower_margin = 2,
255 .vsw = 10, 242 .hsync_len = 41,
256 .pxl_clk = 7833600, 243 .vsync_len = 10,
257 .invert_pxl_clk = 0, 244 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
245 .flag = 0,
258 }, 246 },
259 [2] = { 247 [2] = {
260 /* Hitachi SP10Q010 */ 248 /* Hitachi SP10Q010 */
261 .name = "SP10Q010", 249 .name = "SP10Q010",
262 .width = 320, 250 .xres = 320,
263 .height = 240, 251 .yres = 240,
264 .hfp = 10, 252 .pixclock = 7833600,
265 .hbp = 10, 253 .left_margin = 10,
266 .hsw = 10, 254 .right_margin = 10,
267 .vfp = 10, 255 .upper_margin = 10,
268 .vbp = 10, 256 .lower_margin = 10,
269 .vsw = 10, 257 .hsync_len = 10,
270 .pxl_clk = 7833600, 258 .vsync_len = 10,
271 .invert_pxl_clk = 0, 259 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
260 .flag = 0,
272 }, 261 },
273}; 262};
274 263
@@ -399,10 +388,9 @@ static int lcd_cfg_dma(int burst_size, int fifo_th)
399 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8); 388 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
400 break; 389 break;
401 case 16: 390 case 16:
391 default:
402 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16); 392 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
403 break; 393 break;
404 default:
405 return -EINVAL;
406 } 394 }
407 395
408 reg |= (fifo_th << 8); 396 reg |= (fifo_th << 8);
@@ -447,7 +435,8 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
447 lcdc_write(reg, LCD_RASTER_TIMING_1_REG); 435 lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
448} 436}
449 437
450static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) 438static int lcd_cfg_display(const struct lcd_ctrl_config *cfg,
439 struct fb_videomode *panel)
451{ 440{
452 u32 reg; 441 u32 reg;
453 u32 reg_int; 442 u32 reg_int;
@@ -456,7 +445,7 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
456 LCD_MONO_8BIT_MODE | 445 LCD_MONO_8BIT_MODE |
457 LCD_MONOCHROME_MODE); 446 LCD_MONOCHROME_MODE);
458 447
459 switch (cfg->p_disp_panel->panel_shade) { 448 switch (cfg->panel_shade) {
460 case MONOCHROME: 449 case MONOCHROME:
461 reg |= LCD_MONOCHROME_MODE; 450 reg |= LCD_MONOCHROME_MODE;
462 if (cfg->mono_8bit_mode) 451 if (cfg->mono_8bit_mode)
@@ -469,7 +458,9 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
469 break; 458 break;
470 459
471 case COLOR_PASSIVE: 460 case COLOR_PASSIVE:
472 if (cfg->stn_565_mode) 461 /* AC bias applicable only for Pasive panels */
462 lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
463 if (cfg->bpp == 12 && cfg->stn_565_mode)
473 reg |= LCD_STN_565_ENABLE; 464 reg |= LCD_STN_565_ENABLE;
474 break; 465 break;
475 466
@@ -490,22 +481,19 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
490 481
491 reg = lcdc_read(LCD_RASTER_TIMING_2_REG); 482 reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
492 483
493 if (cfg->sync_ctrl) 484 reg |= LCD_SYNC_CTRL;
494 reg |= LCD_SYNC_CTRL;
495 else
496 reg &= ~LCD_SYNC_CTRL;
497 485
498 if (cfg->sync_edge) 486 if (cfg->sync_edge)
499 reg |= LCD_SYNC_EDGE; 487 reg |= LCD_SYNC_EDGE;
500 else 488 else
501 reg &= ~LCD_SYNC_EDGE; 489 reg &= ~LCD_SYNC_EDGE;
502 490
503 if (cfg->invert_line_clock) 491 if (panel->sync & FB_SYNC_HOR_HIGH_ACT)
504 reg |= LCD_INVERT_LINE_CLOCK; 492 reg |= LCD_INVERT_LINE_CLOCK;
505 else 493 else
506 reg &= ~LCD_INVERT_LINE_CLOCK; 494 reg &= ~LCD_INVERT_LINE_CLOCK;
507 495
508 if (cfg->invert_frm_clock) 496 if (panel->sync & FB_SYNC_VERT_HIGH_ACT)
509 reg |= LCD_INVERT_FRAME_CLOCK; 497 reg |= LCD_INVERT_FRAME_CLOCK;
510 else 498 else
511 reg &= ~LCD_INVERT_FRAME_CLOCK; 499 reg &= ~LCD_INVERT_FRAME_CLOCK;
@@ -728,7 +716,7 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
728} 716}
729 717
730static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, 718static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
731 struct da8xx_panel *panel) 719 struct fb_videomode *panel)
732{ 720{
733 u32 bpp; 721 u32 bpp;
734 int ret = 0; 722 int ret = 0;
@@ -738,7 +726,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
738 /* Calculate the divider */ 726 /* Calculate the divider */
739 lcd_calc_clk_divider(par); 727 lcd_calc_clk_divider(par);
740 728
741 if (panel->invert_pxl_clk) 729 if (panel->sync & FB_SYNC_CLK_INVERT)
742 lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) | 730 lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
743 LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG); 731 LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
744 else 732 else
@@ -750,30 +738,23 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
750 if (ret < 0) 738 if (ret < 0)
751 return ret; 739 return ret;
752 740
753 /* Configure the AC bias properties. */
754 lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
755
756 /* Configure the vertical and horizontal sync properties. */ 741 /* Configure the vertical and horizontal sync properties. */
757 lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp); 742 lcd_cfg_vertical_sync(panel->lower_margin, panel->vsync_len,
758 lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp); 743 panel->upper_margin);
744 lcd_cfg_horizontal_sync(panel->right_margin, panel->hsync_len,
745 panel->left_margin);
759 746
760 /* Configure for disply */ 747 /* Configure for disply */
761 ret = lcd_cfg_display(cfg); 748 ret = lcd_cfg_display(cfg, panel);
762 if (ret < 0) 749 if (ret < 0)
763 return ret; 750 return ret;
764 751
765 if (QVGA != cfg->p_disp_panel->panel_type) 752 bpp = cfg->bpp;
766 return -EINVAL;
767 753
768 if (cfg->bpp <= cfg->p_disp_panel->max_bpp &&
769 cfg->bpp >= cfg->p_disp_panel->min_bpp)
770 bpp = cfg->bpp;
771 else
772 bpp = cfg->p_disp_panel->max_bpp;
773 if (bpp == 12) 754 if (bpp == 12)
774 bpp = 16; 755 bpp = 16;
775 ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width, 756 ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->xres,
776 (unsigned int)panel->height, bpp, 757 (unsigned int)panel->yres, bpp,
777 cfg->raster_order); 758 cfg->raster_order);
778 if (ret < 0) 759 if (ret < 0)
779 return ret; 760 return ret;
@@ -1235,7 +1216,7 @@ static int __devinit fb_probe(struct platform_device *device)
1235 struct da8xx_lcdc_platform_data *fb_pdata = 1216 struct da8xx_lcdc_platform_data *fb_pdata =
1236 device->dev.platform_data; 1217 device->dev.platform_data;
1237 struct lcd_ctrl_config *lcd_cfg; 1218 struct lcd_ctrl_config *lcd_cfg;
1238 struct da8xx_panel *lcdc_info; 1219 struct fb_videomode *lcdc_info;
1239 struct fb_info *da8xx_fb_info; 1220 struct fb_info *da8xx_fb_info;
1240 struct clk *fb_clk = NULL; 1221 struct clk *fb_clk = NULL;
1241 struct da8xx_fb_par *par; 1222 struct da8xx_fb_par *par;
@@ -1267,7 +1248,7 @@ static int __devinit fb_probe(struct platform_device *device)
1267 goto err_request_mem; 1248 goto err_request_mem;
1268 } 1249 }
1269 1250
1270 fb_clk = clk_get(&device->dev, NULL); 1251 fb_clk = clk_get(&device->dev, "fck");
1271 if (IS_ERR(fb_clk)) { 1252 if (IS_ERR(fb_clk)) {
1272 dev_err(&device->dev, "Can not get device clock\n"); 1253 dev_err(&device->dev, "Can not get device clock\n");
1273 ret = -ENODEV; 1254 ret = -ENODEV;
@@ -1283,6 +1264,7 @@ static int __devinit fb_probe(struct platform_device *device)
1283 lcd_revision = LCD_VERSION_1; 1264 lcd_revision = LCD_VERSION_1;
1284 break; 1265 break;
1285 case 0x4F200800: 1266 case 0x4F200800:
1267 case 0x4F201000:
1286 lcd_revision = LCD_VERSION_2; 1268 lcd_revision = LCD_VERSION_2;
1287 break; 1269 break;
1288 default: 1270 default:
@@ -1323,7 +1305,7 @@ static int __devinit fb_probe(struct platform_device *device)
1323#ifdef CONFIG_CPU_FREQ 1305#ifdef CONFIG_CPU_FREQ
1324 par->lcd_fck_rate = clk_get_rate(fb_clk); 1306 par->lcd_fck_rate = clk_get_rate(fb_clk);
1325#endif 1307#endif
1326 par->pxl_clk = lcdc_info->pxl_clk; 1308 par->pxl_clk = lcdc_info->pixclock;
1327 if (fb_pdata->panel_power_ctrl) { 1309 if (fb_pdata->panel_power_ctrl) {
1328 par->panel_power_ctrl = fb_pdata->panel_power_ctrl; 1310 par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
1329 par->panel_power_ctrl(1); 1311 par->panel_power_ctrl(1);
@@ -1336,8 +1318,8 @@ static int __devinit fb_probe(struct platform_device *device)
1336 } 1318 }
1337 1319
1338 /* allocate frame buffer */ 1320 /* allocate frame buffer */
1339 par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp; 1321 par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp;
1340 ulcm = lcm((lcdc_info->width * lcd_cfg->bpp)/8, PAGE_SIZE); 1322 ulcm = lcm((lcdc_info->xres * lcd_cfg->bpp)/8, PAGE_SIZE);
1341 par->vram_size = roundup(par->vram_size/8, ulcm); 1323 par->vram_size = roundup(par->vram_size/8, ulcm);
1342 par->vram_size = par->vram_size * LCD_NUM_BUFFERS; 1324 par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
1343 1325
@@ -1355,10 +1337,10 @@ static int __devinit fb_probe(struct platform_device *device)
1355 da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt; 1337 da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt;
1356 da8xx_fb_fix.smem_start = par->vram_phys; 1338 da8xx_fb_fix.smem_start = par->vram_phys;
1357 da8xx_fb_fix.smem_len = par->vram_size; 1339 da8xx_fb_fix.smem_len = par->vram_size;
1358 da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; 1340 da8xx_fb_fix.line_length = (lcdc_info->xres * lcd_cfg->bpp) / 8;
1359 1341
1360 par->dma_start = par->vram_phys; 1342 par->dma_start = par->vram_phys;
1361 par->dma_end = par->dma_start + lcdc_info->height * 1343 par->dma_end = par->dma_start + lcdc_info->yres *
1362 da8xx_fb_fix.line_length - 1; 1344 da8xx_fb_fix.line_length - 1;
1363 1345
1364 /* allocate palette buffer */ 1346 /* allocate palette buffer */
@@ -1384,22 +1366,22 @@ static int __devinit fb_probe(struct platform_device *device)
1384 /* Initialize par */ 1366 /* Initialize par */
1385 da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp; 1367 da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
1386 1368
1387 da8xx_fb_var.xres = lcdc_info->width; 1369 da8xx_fb_var.xres = lcdc_info->xres;
1388 da8xx_fb_var.xres_virtual = lcdc_info->width; 1370 da8xx_fb_var.xres_virtual = lcdc_info->xres;
1389 1371
1390 da8xx_fb_var.yres = lcdc_info->height; 1372 da8xx_fb_var.yres = lcdc_info->yres;
1391 da8xx_fb_var.yres_virtual = lcdc_info->height * LCD_NUM_BUFFERS; 1373 da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS;
1392 1374
1393 da8xx_fb_var.grayscale = 1375 da8xx_fb_var.grayscale =
1394 lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0; 1376 lcd_cfg->panel_shade == MONOCHROME ? 1 : 0;
1395 da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp; 1377 da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
1396 1378
1397 da8xx_fb_var.hsync_len = lcdc_info->hsw; 1379 da8xx_fb_var.hsync_len = lcdc_info->hsync_len;
1398 da8xx_fb_var.vsync_len = lcdc_info->vsw; 1380 da8xx_fb_var.vsync_len = lcdc_info->vsync_len;
1399 da8xx_fb_var.right_margin = lcdc_info->hfp; 1381 da8xx_fb_var.right_margin = lcdc_info->right_margin;
1400 da8xx_fb_var.left_margin = lcdc_info->hbp; 1382 da8xx_fb_var.left_margin = lcdc_info->left_margin;
1401 da8xx_fb_var.lower_margin = lcdc_info->vfp; 1383 da8xx_fb_var.lower_margin = lcdc_info->lower_margin;
1402 da8xx_fb_var.upper_margin = lcdc_info->vbp; 1384 da8xx_fb_var.upper_margin = lcdc_info->upper_margin;
1403 da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par); 1385 da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
1404 1386
1405 /* Initialize fbinfo */ 1387 /* Initialize fbinfo */
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e75412..28fd686c6b81 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/of.h>
21 22
22#include <video/exynos_dp.h> 23#include <video/exynos_dp.h>
23 24
@@ -48,10 +49,6 @@ static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
48{ 49{
49 int timeout_loop = 0; 50 int timeout_loop = 0;
50 51
51 exynos_dp_init_hpd(dp);
52
53 usleep_range(200, 210);
54
55 while (exynos_dp_get_plug_in_status(dp) != 0) { 52 while (exynos_dp_get_plug_in_status(dp) != 0) {
56 timeout_loop++; 53 timeout_loop++;
57 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 54 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
@@ -90,9 +87,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
90 */ 87 */
91 88
92 /* Read Extension Flag, Number of 128-byte EDID extension blocks */ 89 /* Read Extension Flag, Number of 128-byte EDID extension blocks */
93 exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, 90 retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
94 EDID_EXTENSION_FLAG, 91 EDID_EXTENSION_FLAG,
95 &extend_block); 92 &extend_block);
93 if (retval)
94 return retval;
96 95
97 if (extend_block > 0) { 96 if (extend_block > 0) {
98 dev_dbg(dp->dev, "EDID data includes a single extension!\n"); 97 dev_dbg(dp->dev, "EDID data includes a single extension!\n");
@@ -181,14 +180,15 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
181 int retval; 180 int retval;
182 181
183 /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */ 182 /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */
184 exynos_dp_read_bytes_from_dpcd(dp, 183 retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV,
185 DPCD_ADDR_DPCD_REV, 184 12, buf);
186 12, buf); 185 if (retval)
186 return retval;
187 187
188 /* Read EDID */ 188 /* Read EDID */
189 for (i = 0; i < 3; i++) { 189 for (i = 0; i < 3; i++) {
190 retval = exynos_dp_read_edid(dp); 190 retval = exynos_dp_read_edid(dp);
191 if (retval == 0) 191 if (!retval)
192 break; 192 break;
193 } 193 }
194 194
@@ -261,11 +261,10 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
261 } 261 }
262} 262}
263 263
264static void exynos_dp_link_start(struct exynos_dp_device *dp) 264static int exynos_dp_link_start(struct exynos_dp_device *dp)
265{ 265{
266 u8 buf[4]; 266 u8 buf[4];
267 int lane; 267 int lane, lane_count, pll_tries, retval;
268 int lane_count;
269 268
270 lane_count = dp->link_train.lane_count; 269 lane_count = dp->link_train.lane_count;
271 270
@@ -275,10 +274,6 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
275 for (lane = 0; lane < lane_count; lane++) 274 for (lane = 0; lane < lane_count; lane++)
276 dp->link_train.cr_loop[lane] = 0; 275 dp->link_train.cr_loop[lane] = 0;
277 276
278 /* Set sink to D0 (Sink Not Ready) mode. */
279 exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
280 DPCD_SET_POWER_STATE_D0);
281
282 /* Set link rate and count as you want to establish*/ 277 /* Set link rate and count as you want to establish*/
283 exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate); 278 exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
284 exynos_dp_set_lane_count(dp, dp->link_train.lane_count); 279 exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
@@ -286,29 +281,46 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
286 /* Setup RX configuration */ 281 /* Setup RX configuration */
287 buf[0] = dp->link_train.link_rate; 282 buf[0] = dp->link_train.link_rate;
288 buf[1] = dp->link_train.lane_count; 283 buf[1] = dp->link_train.lane_count;
289 exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET, 284 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
290 2, buf); 285 2, buf);
286 if (retval)
287 return retval;
291 288
292 /* Set TX pre-emphasis to minimum */ 289 /* Set TX pre-emphasis to minimum */
293 for (lane = 0; lane < lane_count; lane++) 290 for (lane = 0; lane < lane_count; lane++)
294 exynos_dp_set_lane_lane_pre_emphasis(dp, 291 exynos_dp_set_lane_lane_pre_emphasis(dp,
295 PRE_EMPHASIS_LEVEL_0, lane); 292 PRE_EMPHASIS_LEVEL_0, lane);
296 293
294 /* Wait for PLL lock */
295 pll_tries = 0;
296 while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
297 if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
298 dev_err(dp->dev, "Wait for PLL lock timed out\n");
299 return -ETIMEDOUT;
300 }
301
302 pll_tries++;
303 usleep_range(90, 120);
304 }
305
297 /* Set training pattern 1 */ 306 /* Set training pattern 1 */
298 exynos_dp_set_training_pattern(dp, TRAINING_PTN1); 307 exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
299 308
300 /* Set RX training pattern */ 309 /* Set RX training pattern */
301 exynos_dp_write_byte_to_dpcd(dp, 310 retval = exynos_dp_write_byte_to_dpcd(dp,
302 DPCD_ADDR_TRAINING_PATTERN_SET, 311 DPCD_ADDR_TRAINING_PATTERN_SET,
303 DPCD_SCRAMBLING_DISABLED | 312 DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1);
304 DPCD_TRAINING_PATTERN_1); 313 if (retval)
314 return retval;
305 315
306 for (lane = 0; lane < lane_count; lane++) 316 for (lane = 0; lane < lane_count; lane++)
307 buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 | 317 buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
308 DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0; 318 DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
309 exynos_dp_write_bytes_to_dpcd(dp, 319
310 DPCD_ADDR_TRAINING_LANE0_SET, 320 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET,
311 lane_count, buf); 321 lane_count, buf);
322
323 return retval;
312} 324}
313 325
314static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane) 326static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
@@ -332,18 +344,17 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
332 return 0; 344 return 0;
333} 345}
334 346
335static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count) 347static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
348 int lane_count)
336{ 349{
337 int lane; 350 int lane;
338 u8 lane_align;
339 u8 lane_status; 351 u8 lane_status;
340 352
341 lane_align = link_align[2]; 353 if ((link_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
342 if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
343 return -EINVAL; 354 return -EINVAL;
344 355
345 for (lane = 0; lane < lane_count; lane++) { 356 for (lane = 0; lane < lane_count; lane++) {
346 lane_status = exynos_dp_get_lane_status(link_align, lane); 357 lane_status = exynos_dp_get_lane_status(link_status, lane);
347 lane_status &= DPCD_CHANNEL_EQ_BITS; 358 lane_status &= DPCD_CHANNEL_EQ_BITS;
348 if (lane_status != DPCD_CHANNEL_EQ_BITS) 359 if (lane_status != DPCD_CHANNEL_EQ_BITS)
349 return -EINVAL; 360 return -EINVAL;
@@ -427,60 +438,60 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
427 dp->link_train.lt_state = FAILED; 438 dp->link_train.lt_state = FAILED;
428} 439}
429 440
430static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp) 441static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
442 u8 adjust_request[2])
431{ 443{
432 u8 link_status[2]; 444 int lane, lane_count;
433 int lane; 445 u8 voltage_swing, pre_emphasis, training_lane;
434 int lane_count;
435 446
436 u8 adjust_request[2]; 447 lane_count = dp->link_train.lane_count;
437 u8 voltage_swing; 448 for (lane = 0; lane < lane_count; lane++) {
438 u8 pre_emphasis; 449 voltage_swing = exynos_dp_get_adjust_request_voltage(
439 u8 training_lane; 450 adjust_request, lane);
451 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
452 adjust_request, lane);
453 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
454 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
455
456 if (voltage_swing == VOLTAGE_LEVEL_3)
457 training_lane |= DPCD_MAX_SWING_REACHED;
458 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
459 training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
460
461 dp->link_train.training_lane[lane] = training_lane;
462 }
463}
464
465static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
466{
467 int lane, lane_count, retval;
468 u8 voltage_swing, pre_emphasis, training_lane;
469 u8 link_status[2], adjust_request[2];
440 470
441 usleep_range(100, 101); 471 usleep_range(100, 101);
442 472
443 lane_count = dp->link_train.lane_count; 473 lane_count = dp->link_train.lane_count;
444 474
445 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, 475 retval = exynos_dp_read_bytes_from_dpcd(dp,
446 2, link_status); 476 DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
477 if (retval)
478 return retval;
479
480 retval = exynos_dp_read_bytes_from_dpcd(dp,
481 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
482 if (retval)
483 return retval;
447 484
448 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { 485 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
449 /* set training pattern 2 for EQ */ 486 /* set training pattern 2 for EQ */
450 exynos_dp_set_training_pattern(dp, TRAINING_PTN2); 487 exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
451 488
452 for (lane = 0; lane < lane_count; lane++) { 489 retval = exynos_dp_write_byte_to_dpcd(dp,
453 exynos_dp_read_bytes_from_dpcd(dp, 490 DPCD_ADDR_TRAINING_PATTERN_SET,
454 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 491 DPCD_SCRAMBLING_DISABLED |
455 2, adjust_request); 492 DPCD_TRAINING_PATTERN_2);
456 voltage_swing = exynos_dp_get_adjust_request_voltage( 493 if (retval)
457 adjust_request, lane); 494 return retval;
458 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
459 adjust_request, lane);
460 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
461 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
462
463 if (voltage_swing == VOLTAGE_LEVEL_3)
464 training_lane |= DPCD_MAX_SWING_REACHED;
465 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
466 training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
467
468 dp->link_train.training_lane[lane] = training_lane;
469
470 exynos_dp_set_lane_link_training(dp,
471 dp->link_train.training_lane[lane],
472 lane);
473 }
474
475 exynos_dp_write_byte_to_dpcd(dp,
476 DPCD_ADDR_TRAINING_PATTERN_SET,
477 DPCD_SCRAMBLING_DISABLED |
478 DPCD_TRAINING_PATTERN_2);
479
480 exynos_dp_write_bytes_to_dpcd(dp,
481 DPCD_ADDR_TRAINING_LANE0_SET,
482 lane_count,
483 dp->link_train.training_lane);
484 495
485 dev_info(dp->dev, "Link Training Clock Recovery success\n"); 496 dev_info(dp->dev, "Link Training Clock Recovery success\n");
486 dp->link_train.lt_state = EQUALIZER_TRAINING; 497 dp->link_train.lt_state = EQUALIZER_TRAINING;
@@ -488,152 +499,116 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
488 for (lane = 0; lane < lane_count; lane++) { 499 for (lane = 0; lane < lane_count; lane++) {
489 training_lane = exynos_dp_get_lane_link_training( 500 training_lane = exynos_dp_get_lane_link_training(
490 dp, lane); 501 dp, lane);
491 exynos_dp_read_bytes_from_dpcd(dp,
492 DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
493 2, adjust_request);
494 voltage_swing = exynos_dp_get_adjust_request_voltage( 502 voltage_swing = exynos_dp_get_adjust_request_voltage(
495 adjust_request, lane); 503 adjust_request, lane);
496 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( 504 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
497 adjust_request, lane); 505 adjust_request, lane);
498 506
499 if (voltage_swing == VOLTAGE_LEVEL_3 || 507 if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
500 pre_emphasis == PRE_EMPHASIS_LEVEL_3) { 508 voltage_swing &&
501 dev_err(dp->dev, "voltage or pre emphasis reached max level\n"); 509 DPCD_PRE_EMPHASIS_GET(training_lane) ==
502 goto reduce_link_rate; 510 pre_emphasis)
503 }
504
505 if ((DPCD_VOLTAGE_SWING_GET(training_lane) ==
506 voltage_swing) &&
507 (DPCD_PRE_EMPHASIS_GET(training_lane) ==
508 pre_emphasis)) {
509 dp->link_train.cr_loop[lane]++; 511 dp->link_train.cr_loop[lane]++;
510 if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP) {
511 dev_err(dp->dev, "CR Max loop\n");
512 goto reduce_link_rate;
513 }
514 }
515
516 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
517 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
518 512
519 if (voltage_swing == VOLTAGE_LEVEL_3) 513 if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
520 training_lane |= DPCD_MAX_SWING_REACHED; 514 voltage_swing == VOLTAGE_LEVEL_3 ||
521 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) 515 pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
522 training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED; 516 dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
517 dp->link_train.cr_loop[lane],
518 voltage_swing, pre_emphasis);
519 exynos_dp_reduce_link_rate(dp);
520 return -EIO;
521 }
522 }
523 }
523 524
524 dp->link_train.training_lane[lane] = training_lane; 525 exynos_dp_get_adjust_training_lane(dp, adjust_request);
525 526
526 exynos_dp_set_lane_link_training(dp, 527 for (lane = 0; lane < lane_count; lane++)
527 dp->link_train.training_lane[lane], lane); 528 exynos_dp_set_lane_link_training(dp,
528 } 529 dp->link_train.training_lane[lane], lane);
529 530
530 exynos_dp_write_bytes_to_dpcd(dp, 531 retval = exynos_dp_write_bytes_to_dpcd(dp,
531 DPCD_ADDR_TRAINING_LANE0_SET, 532 DPCD_ADDR_TRAINING_LANE0_SET, lane_count,
532 lane_count,
533 dp->link_train.training_lane); 533 dp->link_train.training_lane);
534 } 534 if (retval)
535 535 return retval;
536 return 0;
537 536
538reduce_link_rate: 537 return retval;
539 exynos_dp_reduce_link_rate(dp);
540 return -EIO;
541} 538}
542 539
543static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp) 540static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
544{ 541{
545 u8 link_status[2]; 542 int lane, lane_count, retval;
546 u8 link_align[3];
547 int lane;
548 int lane_count;
549 u32 reg; 543 u32 reg;
550 544 u8 link_align, link_status[2], adjust_request[2];
551 u8 adjust_request[2];
552 u8 voltage_swing;
553 u8 pre_emphasis;
554 u8 training_lane;
555 545
556 usleep_range(400, 401); 546 usleep_range(400, 401);
557 547
558 lane_count = dp->link_train.lane_count; 548 lane_count = dp->link_train.lane_count;
559 549
560 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, 550 retval = exynos_dp_read_bytes_from_dpcd(dp,
561 2, link_status); 551 DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
552 if (retval)
553 return retval;
562 554
563 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { 555 if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
564 link_align[0] = link_status[0]; 556 exynos_dp_reduce_link_rate(dp);
565 link_align[1] = link_status[1]; 557 return -EIO;
558 }
566 559
567 exynos_dp_read_byte_from_dpcd(dp, 560 retval = exynos_dp_read_bytes_from_dpcd(dp,
568 DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, 561 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
569 &link_align[2]); 562 if (retval)
563 return retval;
570 564
571 for (lane = 0; lane < lane_count; lane++) { 565 retval = exynos_dp_read_byte_from_dpcd(dp,
572 exynos_dp_read_bytes_from_dpcd(dp, 566 DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &link_align);
573 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 567 if (retval)
574 2, adjust_request); 568 return retval;
575 voltage_swing = exynos_dp_get_adjust_request_voltage(
576 adjust_request, lane);
577 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
578 adjust_request, lane);
579 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
580 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
581 569
582 if (voltage_swing == VOLTAGE_LEVEL_3) 570 exynos_dp_get_adjust_training_lane(dp, adjust_request);
583 training_lane |= DPCD_MAX_SWING_REACHED;
584 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
585 training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
586 571
587 dp->link_train.training_lane[lane] = training_lane; 572 if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) {
588 } 573 /* traing pattern Set to Normal */
574 exynos_dp_training_pattern_dis(dp);
589 575
590 if (exynos_dp_channel_eq_ok(link_align, lane_count) == 0) { 576 dev_info(dp->dev, "Link Training success!\n");
591 /* traing pattern Set to Normal */
592 exynos_dp_training_pattern_dis(dp);
593 577
594 dev_info(dp->dev, "Link Training success!\n"); 578 exynos_dp_get_link_bandwidth(dp, &reg);
595 579 dp->link_train.link_rate = reg;
596 exynos_dp_get_link_bandwidth(dp, &reg); 580 dev_dbg(dp->dev, "final bandwidth = %.2x\n",
597 dp->link_train.link_rate = reg; 581 dp->link_train.link_rate);
598 dev_dbg(dp->dev, "final bandwidth = %.2x\n",
599 dp->link_train.link_rate);
600 582
601 exynos_dp_get_lane_count(dp, &reg); 583 exynos_dp_get_lane_count(dp, &reg);
602 dp->link_train.lane_count = reg; 584 dp->link_train.lane_count = reg;
603 dev_dbg(dp->dev, "final lane count = %.2x\n", 585 dev_dbg(dp->dev, "final lane count = %.2x\n",
604 dp->link_train.lane_count); 586 dp->link_train.lane_count);
605 587
606 /* set enhanced mode if available */ 588 /* set enhanced mode if available */
607 exynos_dp_set_enhanced_mode(dp); 589 exynos_dp_set_enhanced_mode(dp);
608 dp->link_train.lt_state = FINISHED; 590 dp->link_train.lt_state = FINISHED;
609 } else {
610 /* not all locked */
611 dp->link_train.eq_loop++;
612 591
613 if (dp->link_train.eq_loop > MAX_EQ_LOOP) { 592 return 0;
614 dev_err(dp->dev, "EQ Max loop\n"); 593 }
615 goto reduce_link_rate;
616 }
617 594
618 for (lane = 0; lane < lane_count; lane++) 595 /* not all locked */
619 exynos_dp_set_lane_link_training(dp, 596 dp->link_train.eq_loop++;
620 dp->link_train.training_lane[lane],
621 lane);
622 597
623 exynos_dp_write_bytes_to_dpcd(dp, 598 if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
624 DPCD_ADDR_TRAINING_LANE0_SET, 599 dev_err(dp->dev, "EQ Max loop\n");
625 lane_count, 600 exynos_dp_reduce_link_rate(dp);
626 dp->link_train.training_lane); 601 return -EIO;
627 }
628 } else {
629 goto reduce_link_rate;
630 } 602 }
631 603
632 return 0; 604 for (lane = 0; lane < lane_count; lane++)
605 exynos_dp_set_lane_link_training(dp,
606 dp->link_train.training_lane[lane], lane);
607
608 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET,
609 lane_count, dp->link_train.training_lane);
633 610
634reduce_link_rate: 611 return retval;
635 exynos_dp_reduce_link_rate(dp);
636 return -EIO;
637} 612}
638 613
639static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp, 614static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
@@ -701,16 +676,17 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
701 676
702static int exynos_dp_sw_link_training(struct exynos_dp_device *dp) 677static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
703{ 678{
704 int retval = 0; 679 int retval = 0, training_finished = 0;
705 int training_finished = 0;
706 680
707 dp->link_train.lt_state = START; 681 dp->link_train.lt_state = START;
708 682
709 /* Process here */ 683 /* Process here */
710 while (!training_finished) { 684 while (!retval && !training_finished) {
711 switch (dp->link_train.lt_state) { 685 switch (dp->link_train.lt_state) {
712 case START: 686 case START:
713 exynos_dp_link_start(dp); 687 retval = exynos_dp_link_start(dp);
688 if (retval)
689 dev_err(dp->dev, "LT link start failed!\n");
714 break; 690 break;
715 case CLOCK_RECOVERY: 691 case CLOCK_RECOVERY:
716 retval = exynos_dp_process_clock_recovery(dp); 692 retval = exynos_dp_process_clock_recovery(dp);
@@ -729,6 +705,8 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
729 return -EREMOTEIO; 705 return -EREMOTEIO;
730 } 706 }
731 } 707 }
708 if (retval)
709 dev_err(dp->dev, "eDP link training failed (%d)\n", retval);
732 710
733 return retval; 711 return retval;
734} 712}
@@ -752,19 +730,15 @@ static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
752 return retval; 730 return retval;
753} 731}
754 732
755static int exynos_dp_config_video(struct exynos_dp_device *dp, 733static int exynos_dp_config_video(struct exynos_dp_device *dp)
756 struct video_info *video_info)
757{ 734{
758 int retval = 0; 735 int retval = 0;
759 int timeout_loop = 0; 736 int timeout_loop = 0;
760 int done_count = 0; 737 int done_count = 0;
761 738
762 exynos_dp_config_video_slave_mode(dp, video_info); 739 exynos_dp_config_video_slave_mode(dp);
763 740
764 exynos_dp_set_video_color_format(dp, video_info->color_depth, 741 exynos_dp_set_video_color_format(dp);
765 video_info->color_space,
766 video_info->dynamic_range,
767 video_info->ycbcr_coeff);
768 742
769 if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 743 if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
770 dev_err(dp->dev, "PLL is not locked yet.\n"); 744 dev_err(dp->dev, "PLL is not locked yet.\n");
@@ -852,10 +826,213 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
852{ 826{
853 struct exynos_dp_device *dp = arg; 827 struct exynos_dp_device *dp = arg;
854 828
855 dev_err(dp->dev, "exynos_dp_irq_handler\n"); 829 enum dp_irq_type irq_type;
830
831 irq_type = exynos_dp_get_irq_type(dp);
832 switch (irq_type) {
833 case DP_IRQ_TYPE_HP_CABLE_IN:
834 dev_dbg(dp->dev, "Received irq - cable in\n");
835 schedule_work(&dp->hotplug_work);
836 exynos_dp_clear_hotplug_interrupts(dp);
837 break;
838 case DP_IRQ_TYPE_HP_CABLE_OUT:
839 dev_dbg(dp->dev, "Received irq - cable out\n");
840 exynos_dp_clear_hotplug_interrupts(dp);
841 break;
842 case DP_IRQ_TYPE_HP_CHANGE:
843 /*
844 * We get these change notifications once in a while, but there
845 * is nothing we can do with them. Just ignore it for now and
846 * only handle cable changes.
847 */
848 dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n");
849 exynos_dp_clear_hotplug_interrupts(dp);
850 break;
851 default:
852 dev_err(dp->dev, "Received irq - unknown type!\n");
853 break;
854 }
856 return IRQ_HANDLED; 855 return IRQ_HANDLED;
857} 856}
858 857
858static void exynos_dp_hotplug(struct work_struct *work)
859{
860 struct exynos_dp_device *dp;
861 int ret;
862
863 dp = container_of(work, struct exynos_dp_device, hotplug_work);
864
865 ret = exynos_dp_detect_hpd(dp);
866 if (ret) {
867 /* Cable has been disconnected, we're done */
868 return;
869 }
870
871 ret = exynos_dp_handle_edid(dp);
872 if (ret) {
873 dev_err(dp->dev, "unable to handle edid\n");
874 return;
875 }
876
877 ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
878 dp->video_info->link_rate);
879 if (ret) {
880 dev_err(dp->dev, "unable to do link train\n");
881 return;
882 }
883
884 exynos_dp_enable_scramble(dp, 1);
885 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
886 exynos_dp_enable_enhanced_mode(dp, 1);
887
888 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
889 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
890
891 exynos_dp_init_video(dp);
892 ret = exynos_dp_config_video(dp);
893 if (ret)
894 dev_err(dp->dev, "unable to config video\n");
895}
896
897#ifdef CONFIG_OF
898static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
899{
900 struct device_node *dp_node = dev->of_node;
901 struct exynos_dp_platdata *pd;
902 struct video_info *dp_video_config;
903
904 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
905 if (!pd) {
906 dev_err(dev, "memory allocation for pdata failed\n");
907 return ERR_PTR(-ENOMEM);
908 }
909 dp_video_config = devm_kzalloc(dev,
910 sizeof(*dp_video_config), GFP_KERNEL);
911
912 if (!dp_video_config) {
913 dev_err(dev, "memory allocation for video config failed\n");
914 return ERR_PTR(-ENOMEM);
915 }
916 pd->video_info = dp_video_config;
917
918 dp_video_config->h_sync_polarity =
919 of_property_read_bool(dp_node, "hsync-active-high");
920
921 dp_video_config->v_sync_polarity =
922 of_property_read_bool(dp_node, "vsync-active-high");
923
924 dp_video_config->interlaced =
925 of_property_read_bool(dp_node, "interlaced");
926
927 if (of_property_read_u32(dp_node, "samsung,color-space",
928 &dp_video_config->color_space)) {
929 dev_err(dev, "failed to get color-space\n");
930 return ERR_PTR(-EINVAL);
931 }
932
933 if (of_property_read_u32(dp_node, "samsung,dynamic-range",
934 &dp_video_config->dynamic_range)) {
935 dev_err(dev, "failed to get dynamic-range\n");
936 return ERR_PTR(-EINVAL);
937 }
938
939 if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
940 &dp_video_config->ycbcr_coeff)) {
941 dev_err(dev, "failed to get ycbcr-coeff\n");
942 return ERR_PTR(-EINVAL);
943 }
944
945 if (of_property_read_u32(dp_node, "samsung,color-depth",
946 &dp_video_config->color_depth)) {
947 dev_err(dev, "failed to get color-depth\n");
948 return ERR_PTR(-EINVAL);
949 }
950
951 if (of_property_read_u32(dp_node, "samsung,link-rate",
952 &dp_video_config->link_rate)) {
953 dev_err(dev, "failed to get link-rate\n");
954 return ERR_PTR(-EINVAL);
955 }
956
957 if (of_property_read_u32(dp_node, "samsung,lane-count",
958 &dp_video_config->lane_count)) {
959 dev_err(dev, "failed to get lane-count\n");
960 return ERR_PTR(-EINVAL);
961 }
962
963 return pd;
964}
965
966static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
967{
968 struct device_node *dp_phy_node;
969 u32 phy_base;
970
971 dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
972 if (!dp_phy_node) {
973 dev_err(dp->dev, "could not find dptx-phy node\n");
974 return -ENODEV;
975 }
976
977 if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
978 dev_err(dp->dev, "faild to get reg for dptx-phy\n");
979 return -EINVAL;
980 }
981
982 if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
983 &dp->enable_mask)) {
984 dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
985 return -EINVAL;
986 }
987
988 dp->phy_addr = ioremap(phy_base, SZ_4);
989 if (!dp->phy_addr) {
990 dev_err(dp->dev, "failed to ioremap dp-phy\n");
991 return -ENOMEM;
992 }
993
994 return 0;
995}
996
997static void exynos_dp_phy_init(struct exynos_dp_device *dp)
998{
999 u32 reg;
1000
1001 reg = __raw_readl(dp->phy_addr);
1002 reg |= dp->enable_mask;
1003 __raw_writel(reg, dp->phy_addr);
1004}
1005
1006static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
1007{
1008 u32 reg;
1009
1010 reg = __raw_readl(dp->phy_addr);
1011 reg &= ~(dp->enable_mask);
1012 __raw_writel(reg, dp->phy_addr);
1013}
1014#else
1015static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
1016{
1017 return NULL;
1018}
1019
1020static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
1021{
1022 return -EINVAL;
1023}
1024
1025static void exynos_dp_phy_init(struct exynos_dp_device *dp)
1026{
1027 return;
1028}
1029
1030static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
1031{
1032 return;
1033}
1034#endif /* CONFIG_OF */
1035
859static int __devinit exynos_dp_probe(struct platform_device *pdev) 1036static int __devinit exynos_dp_probe(struct platform_device *pdev)
860{ 1037{
861 struct resource *res; 1038 struct resource *res;
@@ -864,12 +1041,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
864 1041
865 int ret = 0; 1042 int ret = 0;
866 1043
867 pdata = pdev->dev.platform_data;
868 if (!pdata) {
869 dev_err(&pdev->dev, "no platform data\n");
870 return -EINVAL;
871 }
872
873 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), 1044 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
874 GFP_KERNEL); 1045 GFP_KERNEL);
875 if (!dp) { 1046 if (!dp) {
@@ -879,6 +1050,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
879 1050
880 dp->dev = &pdev->dev; 1051 dp->dev = &pdev->dev;
881 1052
1053 if (pdev->dev.of_node) {
1054 pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
1055 if (IS_ERR(pdata))
1056 return PTR_ERR(pdata);
1057
1058 ret = exynos_dp_dt_parse_phydata(dp);
1059 if (ret)
1060 return ret;
1061 } else {
1062 pdata = pdev->dev.platform_data;
1063 if (!pdata) {
1064 dev_err(&pdev->dev, "no platform data\n");
1065 return -EINVAL;
1066 }
1067 }
1068
882 dp->clock = devm_clk_get(&pdev->dev, "dp"); 1069 dp->clock = devm_clk_get(&pdev->dev, "dp");
883 if (IS_ERR(dp->clock)) { 1070 if (IS_ERR(dp->clock)) {
884 dev_err(&pdev->dev, "failed to get clock\n"); 1071 dev_err(&pdev->dev, "failed to get clock\n");
@@ -896,50 +1083,29 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
896 } 1083 }
897 1084
898 dp->irq = platform_get_irq(pdev, 0); 1085 dp->irq = platform_get_irq(pdev, 0);
899 if (!dp->irq) { 1086 if (dp->irq == -ENXIO) {
900 dev_err(&pdev->dev, "failed to get irq\n"); 1087 dev_err(&pdev->dev, "failed to get irq\n");
901 return -ENODEV; 1088 return -ENODEV;
902 } 1089 }
903 1090
904 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0, 1091 INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
905 "exynos-dp", dp);
906 if (ret) {
907 dev_err(&pdev->dev, "failed to request irq\n");
908 return ret;
909 }
910 1092
911 dp->video_info = pdata->video_info; 1093 dp->video_info = pdata->video_info;
912 if (pdata->phy_init)
913 pdata->phy_init();
914
915 exynos_dp_init_dp(dp);
916
917 ret = exynos_dp_detect_hpd(dp);
918 if (ret) {
919 dev_err(&pdev->dev, "unable to detect hpd\n");
920 return ret;
921 }
922 1094
923 exynos_dp_handle_edid(dp); 1095 if (pdev->dev.of_node) {
924 1096 if (dp->phy_addr)
925 ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count, 1097 exynos_dp_phy_init(dp);
926 dp->video_info->link_rate); 1098 } else {
927 if (ret) { 1099 if (pdata->phy_init)
928 dev_err(&pdev->dev, "unable to do link train\n"); 1100 pdata->phy_init();
929 return ret;
930 } 1101 }
931 1102
932 exynos_dp_enable_scramble(dp, 1); 1103 exynos_dp_init_dp(dp);
933 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
934 exynos_dp_enable_enhanced_mode(dp, 1);
935
936 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
937 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
938 1104
939 exynos_dp_init_video(dp); 1105 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
940 ret = exynos_dp_config_video(dp, dp->video_info); 1106 "exynos-dp", dp);
941 if (ret) { 1107 if (ret) {
942 dev_err(&pdev->dev, "unable to config video\n"); 1108 dev_err(&pdev->dev, "failed to request irq\n");
943 return ret; 1109 return ret;
944 } 1110 }
945 1111
@@ -953,23 +1119,41 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
953 struct exynos_dp_platdata *pdata = pdev->dev.platform_data; 1119 struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
954 struct exynos_dp_device *dp = platform_get_drvdata(pdev); 1120 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
955 1121
956 if (pdata && pdata->phy_exit) 1122 disable_irq(dp->irq);
957 pdata->phy_exit(); 1123
1124 if (work_pending(&dp->hotplug_work))
1125 flush_work(&dp->hotplug_work);
1126
1127 if (pdev->dev.of_node) {
1128 if (dp->phy_addr)
1129 exynos_dp_phy_exit(dp);
1130 } else {
1131 if (pdata->phy_exit)
1132 pdata->phy_exit();
1133 }
958 1134
959 clk_disable_unprepare(dp->clock); 1135 clk_disable_unprepare(dp->clock);
960 1136
1137
961 return 0; 1138 return 0;
962} 1139}
963 1140
964#ifdef CONFIG_PM_SLEEP 1141#ifdef CONFIG_PM_SLEEP
965static int exynos_dp_suspend(struct device *dev) 1142static int exynos_dp_suspend(struct device *dev)
966{ 1143{
967 struct platform_device *pdev = to_platform_device(dev); 1144 struct exynos_dp_platdata *pdata = dev->platform_data;
968 struct exynos_dp_platdata *pdata = pdev->dev.platform_data; 1145 struct exynos_dp_device *dp = dev_get_drvdata(dev);
969 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
970 1146
971 if (pdata && pdata->phy_exit) 1147 if (work_pending(&dp->hotplug_work))
972 pdata->phy_exit(); 1148 flush_work(&dp->hotplug_work);
1149
1150 if (dev->of_node) {
1151 if (dp->phy_addr)
1152 exynos_dp_phy_exit(dp);
1153 } else {
1154 if (pdata->phy_exit)
1155 pdata->phy_exit();
1156 }
973 1157
974 clk_disable_unprepare(dp->clock); 1158 clk_disable_unprepare(dp->clock);
975 1159
@@ -978,32 +1162,22 @@ static int exynos_dp_suspend(struct device *dev)
978 1162
979static int exynos_dp_resume(struct device *dev) 1163static int exynos_dp_resume(struct device *dev)
980{ 1164{
981 struct platform_device *pdev = to_platform_device(dev); 1165 struct exynos_dp_platdata *pdata = dev->platform_data;
982 struct exynos_dp_platdata *pdata = pdev->dev.platform_data; 1166 struct exynos_dp_device *dp = dev_get_drvdata(dev);
983 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
984 1167
985 if (pdata && pdata->phy_init) 1168 if (dev->of_node) {
986 pdata->phy_init(); 1169 if (dp->phy_addr)
1170 exynos_dp_phy_init(dp);
1171 } else {
1172 if (pdata->phy_init)
1173 pdata->phy_init();
1174 }
987 1175
988 clk_prepare_enable(dp->clock); 1176 clk_prepare_enable(dp->clock);
989 1177
990 exynos_dp_init_dp(dp); 1178 exynos_dp_init_dp(dp);
991 1179
992 exynos_dp_detect_hpd(dp); 1180 enable_irq(dp->irq);
993 exynos_dp_handle_edid(dp);
994
995 exynos_dp_set_link_train(dp, dp->video_info->lane_count,
996 dp->video_info->link_rate);
997
998 exynos_dp_enable_scramble(dp, 1);
999 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
1000 exynos_dp_enable_enhanced_mode(dp, 1);
1001
1002 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
1003 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
1004
1005 exynos_dp_init_video(dp);
1006 exynos_dp_config_video(dp, dp->video_info);
1007 1181
1008 return 0; 1182 return 0;
1009} 1183}
@@ -1013,6 +1187,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
1013 SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume) 1187 SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
1014}; 1188};
1015 1189
1190static const struct of_device_id exynos_dp_match[] = {
1191 { .compatible = "samsung,exynos5-dp" },
1192 {},
1193};
1194MODULE_DEVICE_TABLE(of, exynos_dp_match);
1195
1016static struct platform_driver exynos_dp_driver = { 1196static struct platform_driver exynos_dp_driver = {
1017 .probe = exynos_dp_probe, 1197 .probe = exynos_dp_probe,
1018 .remove = __devexit_p(exynos_dp_remove), 1198 .remove = __devexit_p(exynos_dp_remove),
@@ -1020,6 +1200,7 @@ static struct platform_driver exynos_dp_driver = {
1020 .name = "exynos-dp", 1200 .name = "exynos-dp",
1021 .owner = THIS_MODULE, 1201 .owner = THIS_MODULE,
1022 .pm = &exynos_dp_pm_ops, 1202 .pm = &exynos_dp_pm_ops,
1203 .of_match_table = of_match_ptr(exynos_dp_match),
1023 }, 1204 },
1024}; 1205};
1025 1206
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a6531c0e..6c567bbf2fb8 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -13,6 +13,13 @@
13#ifndef _EXYNOS_DP_CORE_H 13#ifndef _EXYNOS_DP_CORE_H
14#define _EXYNOS_DP_CORE_H 14#define _EXYNOS_DP_CORE_H
15 15
16enum dp_irq_type {
17 DP_IRQ_TYPE_HP_CABLE_IN,
18 DP_IRQ_TYPE_HP_CABLE_OUT,
19 DP_IRQ_TYPE_HP_CHANGE,
20 DP_IRQ_TYPE_UNKNOWN,
21};
22
16struct link_train { 23struct link_train {
17 int eq_loop; 24 int eq_loop;
18 int cr_loop[4]; 25 int cr_loop[4];
@@ -29,9 +36,12 @@ struct exynos_dp_device {
29 struct clk *clock; 36 struct clk *clock;
30 unsigned int irq; 37 unsigned int irq;
31 void __iomem *reg_base; 38 void __iomem *reg_base;
39 void __iomem *phy_addr;
40 unsigned int enable_mask;
32 41
33 struct video_info *video_info; 42 struct video_info *video_info;
34 struct link_train link_train; 43 struct link_train link_train;
44 struct work_struct hotplug_work;
35}; 45};
36 46
37/* exynos_dp_reg.c */ 47/* exynos_dp_reg.c */
@@ -50,6 +60,8 @@ void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
50 bool enable); 60 bool enable);
51void exynos_dp_init_analog_func(struct exynos_dp_device *dp); 61void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
52void exynos_dp_init_hpd(struct exynos_dp_device *dp); 62void exynos_dp_init_hpd(struct exynos_dp_device *dp);
63enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
64void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp);
53void exynos_dp_reset_aux(struct exynos_dp_device *dp); 65void exynos_dp_reset_aux(struct exynos_dp_device *dp);
54void exynos_dp_init_aux(struct exynos_dp_device *dp); 66void exynos_dp_init_aux(struct exynos_dp_device *dp);
55int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp); 67int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
@@ -107,11 +119,7 @@ u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
107void exynos_dp_reset_macro(struct exynos_dp_device *dp); 119void exynos_dp_reset_macro(struct exynos_dp_device *dp);
108void exynos_dp_init_video(struct exynos_dp_device *dp); 120void exynos_dp_init_video(struct exynos_dp_device *dp);
109 121
110void exynos_dp_set_video_color_format(struct exynos_dp_device *dp, 122void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
111 u32 color_depth,
112 u32 color_space,
113 u32 dynamic_range,
114 u32 ycbcr_coeff);
115int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp); 123int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
116void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, 124void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
117 enum clock_recovery_m_value_type type, 125 enum clock_recovery_m_value_type type,
@@ -121,8 +129,7 @@ void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
121void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable); 129void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
122void exynos_dp_start_video(struct exynos_dp_device *dp); 130void exynos_dp_start_video(struct exynos_dp_device *dp);
123int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp); 131int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp);
124void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp, 132void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp);
125 struct video_info *video_info);
126void exynos_dp_enable_scrambling(struct exynos_dp_device *dp); 133void exynos_dp_enable_scrambling(struct exynos_dp_device *dp);
127void exynos_dp_disable_scrambling(struct exynos_dp_device *dp); 134void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
128 135
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 3f5ca8a0d5ea..29d9d035c73a 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -19,11 +19,11 @@
19#include "exynos_dp_core.h" 19#include "exynos_dp_core.h"
20#include "exynos_dp_reg.h" 20#include "exynos_dp_reg.h"
21 21
22#define COMMON_INT_MASK_1 (0) 22#define COMMON_INT_MASK_1 0
23#define COMMON_INT_MASK_2 (0) 23#define COMMON_INT_MASK_2 0
24#define COMMON_INT_MASK_3 (0) 24#define COMMON_INT_MASK_3 0
25#define COMMON_INT_MASK_4 (0) 25#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
26#define INT_STA_MASK (0) 26#define INT_STA_MASK INT_HPD
27 27
28void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable) 28void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
29{ 29{
@@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
88void exynos_dp_init_interrupt(struct exynos_dp_device *dp) 88void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
89{ 89{
90 /* Set interrupt pin assertion polarity as high */ 90 /* Set interrupt pin assertion polarity as high */
91 writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL); 91 writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
92 92
93 /* Clear pending regisers */ 93 /* Clear pending regisers */
94 writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 94 writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
@@ -324,7 +324,7 @@ void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
324 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 324 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
325} 325}
326 326
327void exynos_dp_init_hpd(struct exynos_dp_device *dp) 327void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
328{ 328{
329 u32 reg; 329 u32 reg;
330 330
@@ -333,12 +333,38 @@ void exynos_dp_init_hpd(struct exynos_dp_device *dp)
333 333
334 reg = INT_HPD; 334 reg = INT_HPD;
335 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); 335 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
336}
337
338void exynos_dp_init_hpd(struct exynos_dp_device *dp)
339{
340 u32 reg;
341
342 exynos_dp_clear_hotplug_interrupts(dp);
336 343
337 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 344 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
338 reg &= ~(F_HPD | HPD_CTRL); 345 reg &= ~(F_HPD | HPD_CTRL);
339 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 346 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
340} 347}
341 348
349enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
350{
351 u32 reg;
352
353 /* Parse hotplug interrupt status register */
354 reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
355
356 if (reg & PLUG)
357 return DP_IRQ_TYPE_HP_CABLE_IN;
358
359 if (reg & HPD_LOST)
360 return DP_IRQ_TYPE_HP_CABLE_OUT;
361
362 if (reg & HOTPLUG_CHG)
363 return DP_IRQ_TYPE_HP_CHANGE;
364
365 return DP_IRQ_TYPE_UNKNOWN;
366}
367
342void exynos_dp_reset_aux(struct exynos_dp_device *dp) 368void exynos_dp_reset_aux(struct exynos_dp_device *dp)
343{ 369{
344 u32 reg; 370 u32 reg;
@@ -491,7 +517,7 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
491 int i; 517 int i;
492 int retval; 518 int retval;
493 519
494 for (i = 0; i < 10; i++) { 520 for (i = 0; i < 3; i++) {
495 /* Clear AUX CH data buffer */ 521 /* Clear AUX CH data buffer */
496 reg = BUF_CLR; 522 reg = BUF_CLR;
497 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 523 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
@@ -552,7 +578,7 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
552 else 578 else
553 cur_data_count = count - start_offset; 579 cur_data_count = count - start_offset;
554 580
555 for (i = 0; i < 10; i++) { 581 for (i = 0; i < 3; i++) {
556 /* Select DPCD device address */ 582 /* Select DPCD device address */
557 reg = AUX_ADDR_7_0(reg_addr + start_offset); 583 reg = AUX_ADDR_7_0(reg_addr + start_offset);
558 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 584 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
@@ -617,7 +643,7 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
617 cur_data_count = count - start_offset; 643 cur_data_count = count - start_offset;
618 644
619 /* AUX CH Request Transaction process */ 645 /* AUX CH Request Transaction process */
620 for (i = 0; i < 10; i++) { 646 for (i = 0; i < 3; i++) {
621 /* Select DPCD device address */ 647 /* Select DPCD device address */
622 reg = AUX_ADDR_7_0(reg_addr + start_offset); 648 reg = AUX_ADDR_7_0(reg_addr + start_offset);
623 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 649 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
@@ -700,17 +726,15 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
700 int i; 726 int i;
701 int retval; 727 int retval;
702 728
703 for (i = 0; i < 10; i++) { 729 for (i = 0; i < 3; i++) {
704 /* Clear AUX CH data buffer */ 730 /* Clear AUX CH data buffer */
705 reg = BUF_CLR; 731 reg = BUF_CLR;
706 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 732 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
707 733
708 /* Select EDID device */ 734 /* Select EDID device */
709 retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); 735 retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
710 if (retval != 0) { 736 if (retval != 0)
711 dev_err(dp->dev, "Select EDID device fail!\n");
712 continue; 737 continue;
713 }
714 738
715 /* 739 /*
716 * Set I2C transaction and read data 740 * Set I2C transaction and read data
@@ -750,7 +774,7 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
750 int retval = 0; 774 int retval = 0;
751 775
752 for (i = 0; i < count; i += 16) { 776 for (i = 0; i < count; i += 16) {
753 for (j = 0; j < 100; j++) { 777 for (j = 0; j < 3; j++) {
754 /* Clear AUX CH data buffer */ 778 /* Clear AUX CH data buffer */
755 reg = BUF_CLR; 779 reg = BUF_CLR;
756 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 780 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
@@ -1034,24 +1058,20 @@ void exynos_dp_init_video(struct exynos_dp_device *dp)
1034 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); 1058 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
1035} 1059}
1036 1060
1037void exynos_dp_set_video_color_format(struct exynos_dp_device *dp, 1061void exynos_dp_set_video_color_format(struct exynos_dp_device *dp)
1038 u32 color_depth,
1039 u32 color_space,
1040 u32 dynamic_range,
1041 u32 ycbcr_coeff)
1042{ 1062{
1043 u32 reg; 1063 u32 reg;
1044 1064
1045 /* Configure the input color depth, color space, dynamic range */ 1065 /* Configure the input color depth, color space, dynamic range */
1046 reg = (dynamic_range << IN_D_RANGE_SHIFT) | 1066 reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
1047 (color_depth << IN_BPC_SHIFT) | 1067 (dp->video_info->color_depth << IN_BPC_SHIFT) |
1048 (color_space << IN_COLOR_F_SHIFT); 1068 (dp->video_info->color_space << IN_COLOR_F_SHIFT);
1049 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2); 1069 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
1050 1070
1051 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ 1071 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
1052 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); 1072 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
1053 reg &= ~IN_YC_COEFFI_MASK; 1073 reg &= ~IN_YC_COEFFI_MASK;
1054 if (ycbcr_coeff) 1074 if (dp->video_info->ycbcr_coeff)
1055 reg |= IN_YC_COEFFI_ITU709; 1075 reg |= IN_YC_COEFFI_ITU709;
1056 else 1076 else
1057 reg |= IN_YC_COEFFI_ITU601; 1077 reg |= IN_YC_COEFFI_ITU601;
@@ -1178,8 +1198,7 @@ int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
1178 return 0; 1198 return 0;
1179} 1199}
1180 1200
1181void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp, 1201void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
1182 struct video_info *video_info)
1183{ 1202{
1184 u32 reg; 1203 u32 reg;
1185 1204
@@ -1190,17 +1209,17 @@ void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
1190 1209
1191 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1210 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1192 reg &= ~INTERACE_SCAN_CFG; 1211 reg &= ~INTERACE_SCAN_CFG;
1193 reg |= (video_info->interlaced << 2); 1212 reg |= (dp->video_info->interlaced << 2);
1194 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1213 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1195 1214
1196 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1215 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1197 reg &= ~VSYNC_POLARITY_CFG; 1216 reg &= ~VSYNC_POLARITY_CFG;
1198 reg |= (video_info->v_sync_polarity << 1); 1217 reg |= (dp->video_info->v_sync_polarity << 1);
1199 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1218 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1200 1219
1201 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1220 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1202 reg &= ~HSYNC_POLARITY_CFG; 1221 reg &= ~HSYNC_POLARITY_CFG;
1203 reg |= (video_info->h_sync_polarity << 0); 1222 reg |= (dp->video_info->h_sync_polarity << 0);
1204 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1223 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1205 1224
1206 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; 1225 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 1f2f014cfe88..2e9bd0e0b9f2 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -242,7 +242,8 @@
242 242
243/* EXYNOS_DP_INT_CTL */ 243/* EXYNOS_DP_INT_CTL */
244#define SOFT_INT_CTRL (0x1 << 2) 244#define SOFT_INT_CTRL (0x1 << 2)
245#define INT_POL (0x1 << 0) 245#define INT_POL1 (0x1 << 1)
246#define INT_POL0 (0x1 << 0)
246 247
247/* EXYNOS_DP_SYS_CTL_1 */ 248/* EXYNOS_DP_SYS_CTL_1 */
248#define DET_STA (0x1 << 2) 249#define DET_STA (0x1 << 2)
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index ede9e55413f8..d3fc92eaee89 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -337,13 +337,11 @@ struct mfb_info {
337 int registered; 337 int registered;
338 unsigned long pseudo_palette[16]; 338 unsigned long pseudo_palette[16];
339 struct diu_ad *ad; 339 struct diu_ad *ad;
340 int cursor_reset;
341 unsigned char g_alpha; 340 unsigned char g_alpha;
342 unsigned int count; 341 unsigned int count;
343 int x_aoi_d; /* aoi display x offset to physical screen */ 342 int x_aoi_d; /* aoi display x offset to physical screen */
344 int y_aoi_d; /* aoi display y offset to physical screen */ 343 int y_aoi_d; /* aoi display y offset to physical screen */
345 struct fsl_diu_data *parent; 344 struct fsl_diu_data *parent;
346 u8 *edid_data;
347}; 345};
348 346
349/** 347/**
@@ -378,6 +376,8 @@ struct fsl_diu_data {
378 struct diu_ad ad[NUM_AOIS] __aligned(8); 376 struct diu_ad ad[NUM_AOIS] __aligned(8);
379 u8 gamma[256 * 3] __aligned(32); 377 u8 gamma[256 * 3] __aligned(32);
380 u8 cursor[MAX_CURS * MAX_CURS * 2] __aligned(32); 378 u8 cursor[MAX_CURS * MAX_CURS * 2] __aligned(32);
379 uint8_t edid_data[EDID_LENGTH];
380 bool has_edid;
381} __aligned(32); 381} __aligned(32);
382 382
383/* Determine the DMA address of a member of the fsl_diu_data structure */ 383/* Determine the DMA address of a member of the fsl_diu_data structure */
@@ -430,6 +430,22 @@ static struct mfb_info mfb_template[] = {
430 }, 430 },
431}; 431};
432 432
433#ifdef DEBUG
434static void __attribute__ ((unused)) fsl_diu_dump(struct diu __iomem *hw)
435{
436 mb();
437 pr_debug("DIU: desc=%08x,%08x,%08x, gamma=%08x pallete=%08x "
438 "cursor=%08x curs_pos=%08x diu_mode=%08x bgnd=%08x "
439 "disp_size=%08x hsyn_para=%08x vsyn_para=%08x syn_pol=%08x "
440 "thresholds=%08x int_mask=%08x plut=%08x\n",
441 hw->desc[0], hw->desc[1], hw->desc[2], hw->gamma,
442 hw->pallete, hw->cursor, hw->curs_pos, hw->diu_mode,
443 hw->bgnd, hw->disp_size, hw->hsyn_para, hw->vsyn_para,
444 hw->syn_pol, hw->thresholds, hw->int_mask, hw->plut);
445 rmb();
446}
447#endif
448
433/** 449/**
434 * fsl_diu_name_to_port - convert a port name to a monitor port enum 450 * fsl_diu_name_to_port - convert a port name to a monitor port enum
435 * 451 *
@@ -481,8 +497,7 @@ static void fsl_diu_enable_panel(struct fb_info *info)
481 497
482 switch (mfbi->index) { 498 switch (mfbi->index) {
483 case PLANE0: 499 case PLANE0:
484 if (hw->desc[0] != ad->paddr) 500 wr_reg_wa(&hw->desc[0], ad->paddr);
485 wr_reg_wa(&hw->desc[0], ad->paddr);
486 break; 501 break;
487 case PLANE1_AOI0: 502 case PLANE1_AOI0:
488 cmfbi = &data->mfb[2]; 503 cmfbi = &data->mfb[2];
@@ -534,8 +549,7 @@ static void fsl_diu_disable_panel(struct fb_info *info)
534 549
535 switch (mfbi->index) { 550 switch (mfbi->index) {
536 case PLANE0: 551 case PLANE0:
537 if (hw->desc[0] != data->dummy_ad.paddr) 552 wr_reg_wa(&hw->desc[0], 0);
538 wr_reg_wa(&hw->desc[0], data->dummy_ad.paddr);
539 break; 553 break;
540 case PLANE1_AOI0: 554 case PLANE1_AOI0:
541 cmfbi = &data->mfb[2]; 555 cmfbi = &data->mfb[2];
@@ -792,7 +806,8 @@ static void update_lcdc(struct fb_info *info)
792 806
793 hw = data->diu_reg; 807 hw = data->diu_reg;
794 808
795 diu_ops.set_monitor_port(data->monitor_port); 809 if (diu_ops.set_monitor_port)
810 diu_ops.set_monitor_port(data->monitor_port);
796 gamma_table_base = data->gamma; 811 gamma_table_base = data->gamma;
797 812
798 /* Prep for DIU init - gamma table, cursor table */ 813 /* Prep for DIU init - gamma table, cursor table */
@@ -811,12 +826,8 @@ static void update_lcdc(struct fb_info *info)
811 out_be32(&hw->gamma, DMA_ADDR(data, gamma)); 826 out_be32(&hw->gamma, DMA_ADDR(data, gamma));
812 out_be32(&hw->cursor, DMA_ADDR(data, cursor)); 827 out_be32(&hw->cursor, DMA_ADDR(data, cursor));
813 828
814 out_be32(&hw->bgnd, 0x007F7F7F); /* BGND */ 829 out_be32(&hw->bgnd, 0x007F7F7F); /* Set background to grey */
815 out_be32(&hw->bgnd_wb, 0); /* BGND_WB */ 830 out_be32(&hw->disp_size, (var->yres << 16) | var->xres);
816 out_be32(&hw->disp_size, (var->yres << 16 | var->xres));
817 /* DISP SIZE */
818 out_be32(&hw->wb_size, 0); /* WB SIZE */
819 out_be32(&hw->wb_mem_addr, 0); /* WB MEM ADDR */
820 831
821 /* Horizontal and vertical configuration register */ 832 /* Horizontal and vertical configuration register */
822 temp = var->left_margin << 22 | /* BP_H */ 833 temp = var->left_margin << 22 | /* BP_H */
@@ -833,9 +844,20 @@ static void update_lcdc(struct fb_info *info)
833 844
834 diu_ops.set_pixel_clock(var->pixclock); 845 diu_ops.set_pixel_clock(var->pixclock);
835 846
836 out_be32(&hw->syn_pol, 0); /* SYNC SIGNALS POLARITY */ 847#ifndef CONFIG_PPC_MPC512x
837 out_be32(&hw->int_status, 0); /* INTERRUPT STATUS */ 848 /*
849 * The PLUT register is defined differently on the MPC5121 than it
850 * is on other SOCs. Unfortunately, there's no documentation that
851 * explains how it's supposed to be programmed, so for now, we leave
852 * it at the default value on the MPC5121.
853 *
854 * For other SOCs, program it for the highest priority, which will
855 * reduce the chance of underrun. Technically, we should scale the
856 * priority to match the screen resolution, but doing that properly
857 * requires delicate fine-tuning for each use-case.
858 */
838 out_be32(&hw->plut, 0x01F5F666); 859 out_be32(&hw->plut, 0x01F5F666);
860#endif
839 861
840 /* Enable the DIU */ 862 /* Enable the DIU */
841 enable_lcdc(info); 863 enable_lcdc(info);
@@ -965,7 +987,6 @@ static int fsl_diu_set_par(struct fb_info *info)
965 hw = data->diu_reg; 987 hw = data->diu_reg;
966 988
967 set_fix(info); 989 set_fix(info);
968 mfbi->cursor_reset = 1;
969 990
970 len = info->var.yres_virtual * info->fix.line_length; 991 len = info->var.yres_virtual * info->fix.line_length;
971 /* Alloc & dealloc each time resolution/bpp change */ 992 /* Alloc & dealloc each time resolution/bpp change */
@@ -1107,6 +1128,12 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
1107 1128
1108 if (!arg) 1129 if (!arg)
1109 return -EINVAL; 1130 return -EINVAL;
1131
1132 dev_dbg(info->dev, "ioctl %08x (dir=%s%s type=%u nr=%u size=%u)\n", cmd,
1133 _IOC_DIR(cmd) & _IOC_READ ? "R" : "",
1134 _IOC_DIR(cmd) & _IOC_WRITE ? "W" : "",
1135 _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
1136
1110 switch (cmd) { 1137 switch (cmd) {
1111 case MFB_SET_PIXFMT_OLD: 1138 case MFB_SET_PIXFMT_OLD:
1112 dev_warn(info->dev, 1139 dev_warn(info->dev,
@@ -1180,6 +1207,23 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
1180 ad->ckmin_b = ck.blue_min; 1207 ad->ckmin_b = ck.blue_min;
1181 } 1208 }
1182 break; 1209 break;
1210#ifdef CONFIG_PPC_MPC512x
1211 case MFB_SET_GAMMA: {
1212 struct fsl_diu_data *data = mfbi->parent;
1213
1214 if (copy_from_user(data->gamma, buf, sizeof(data->gamma)))
1215 return -EFAULT;
1216 setbits32(&data->diu_reg->gamma, 0); /* Force table reload */
1217 break;
1218 }
1219 case MFB_GET_GAMMA: {
1220 struct fsl_diu_data *data = mfbi->parent;
1221
1222 if (copy_to_user(buf, data->gamma, sizeof(data->gamma)))
1223 return -EFAULT;
1224 break;
1225 }
1226#endif
1183 default: 1227 default:
1184 dev_err(info->dev, "unknown ioctl command (0x%08X)\n", cmd); 1228 dev_err(info->dev, "unknown ioctl command (0x%08X)\n", cmd);
1185 return -ENOIOCTLCMD; 1229 return -ENOIOCTLCMD;
@@ -1206,8 +1250,22 @@ static int fsl_diu_open(struct fb_info *info, int user)
1206 res = fsl_diu_set_par(info); 1250 res = fsl_diu_set_par(info);
1207 if (res < 0) 1251 if (res < 0)
1208 mfbi->count--; 1252 mfbi->count--;
1209 else 1253 else {
1254 struct fsl_diu_data *data = mfbi->parent;
1255
1256#ifdef CONFIG_NOT_COHERENT_CACHE
1257 /*
1258 * Enable underrun detection and vertical sync
1259 * interrupts.
1260 */
1261 clrbits32(&data->diu_reg->int_mask,
1262 INT_UNDRUN | INT_VSYNC);
1263#else
1264 /* Enable underrun detection */
1265 clrbits32(&data->diu_reg->int_mask, INT_UNDRUN);
1266#endif
1210 fsl_diu_enable_panel(info); 1267 fsl_diu_enable_panel(info);
1268 }
1211 } 1269 }
1212 1270
1213 spin_unlock(&diu_lock); 1271 spin_unlock(&diu_lock);
@@ -1223,8 +1281,13 @@ static int fsl_diu_release(struct fb_info *info, int user)
1223 1281
1224 spin_lock(&diu_lock); 1282 spin_lock(&diu_lock);
1225 mfbi->count--; 1283 mfbi->count--;
1226 if (mfbi->count == 0) 1284 if (mfbi->count == 0) {
1285 struct fsl_diu_data *data = mfbi->parent;
1286
1287 /* Disable interrupts */
1288 out_be32(&data->diu_reg->int_mask, 0xffffffff);
1227 fsl_diu_disable_panel(info); 1289 fsl_diu_disable_panel(info);
1290 }
1228 1291
1229 spin_unlock(&diu_lock); 1292 spin_unlock(&diu_lock);
1230 return res; 1293 return res;
@@ -1248,6 +1311,7 @@ static int __devinit install_fb(struct fb_info *info)
1248{ 1311{
1249 int rc; 1312 int rc;
1250 struct mfb_info *mfbi = info->par; 1313 struct mfb_info *mfbi = info->par;
1314 struct fsl_diu_data *data = mfbi->parent;
1251 const char *aoi_mode, *init_aoi_mode = "320x240"; 1315 const char *aoi_mode, *init_aoi_mode = "320x240";
1252 struct fb_videomode *db = fsl_diu_mode_db; 1316 struct fb_videomode *db = fsl_diu_mode_db;
1253 unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db); 1317 unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db);
@@ -1264,9 +1328,9 @@ static int __devinit install_fb(struct fb_info *info)
1264 return rc; 1328 return rc;
1265 1329
1266 if (mfbi->index == PLANE0) { 1330 if (mfbi->index == PLANE0) {
1267 if (mfbi->edid_data) { 1331 if (data->has_edid) {
1268 /* Now build modedb from EDID */ 1332 /* Now build modedb from EDID */
1269 fb_edid_to_monspecs(mfbi->edid_data, &info->monspecs); 1333 fb_edid_to_monspecs(data->edid_data, &info->monspecs);
1270 fb_videomode_to_modelist(info->monspecs.modedb, 1334 fb_videomode_to_modelist(info->monspecs.modedb,
1271 info->monspecs.modedb_len, 1335 info->monspecs.modedb_len,
1272 &info->modelist); 1336 &info->modelist);
@@ -1284,7 +1348,7 @@ static int __devinit install_fb(struct fb_info *info)
1284 * For plane 0 we continue and look into 1348 * For plane 0 we continue and look into
1285 * driver's internal modedb. 1349 * driver's internal modedb.
1286 */ 1350 */
1287 if ((mfbi->index == PLANE0) && mfbi->edid_data) 1351 if ((mfbi->index == PLANE0) && data->has_edid)
1288 has_default_mode = 0; 1352 has_default_mode = 0;
1289 else 1353 else
1290 return -EINVAL; 1354 return -EINVAL;
@@ -1348,9 +1412,6 @@ static void uninstall_fb(struct fb_info *info)
1348 if (!mfbi->registered) 1412 if (!mfbi->registered)
1349 return; 1413 return;
1350 1414
1351 if (mfbi->index == PLANE0)
1352 kfree(mfbi->edid_data);
1353
1354 unregister_framebuffer(info); 1415 unregister_framebuffer(info);
1355 unmap_video_memory(info); 1416 unmap_video_memory(info);
1356 if (&info->cmap) 1417 if (&info->cmap)
@@ -1362,7 +1423,7 @@ static void uninstall_fb(struct fb_info *info)
1362static irqreturn_t fsl_diu_isr(int irq, void *dev_id) 1423static irqreturn_t fsl_diu_isr(int irq, void *dev_id)
1363{ 1424{
1364 struct diu __iomem *hw = dev_id; 1425 struct diu __iomem *hw = dev_id;
1365 unsigned int status = in_be32(&hw->int_status); 1426 uint32_t status = in_be32(&hw->int_status);
1366 1427
1367 if (status) { 1428 if (status) {
1368 /* This is the workaround for underrun */ 1429 /* This is the workaround for underrun */
@@ -1387,40 +1448,6 @@ static irqreturn_t fsl_diu_isr(int irq, void *dev_id)
1387 return IRQ_NONE; 1448 return IRQ_NONE;
1388} 1449}
1389 1450
1390static int request_irq_local(struct fsl_diu_data *data)
1391{
1392 struct diu __iomem *hw = data->diu_reg;
1393 u32 ints;
1394 int ret;
1395
1396 /* Read to clear the status */
1397 in_be32(&hw->int_status);
1398
1399 ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb", hw);
1400 if (!ret) {
1401 ints = INT_PARERR | INT_LS_BF_VS;
1402#if !defined(CONFIG_NOT_COHERENT_CACHE)
1403 ints |= INT_VSYNC;
1404#endif
1405
1406 /* Read to clear the status */
1407 in_be32(&hw->int_status);
1408 out_be32(&hw->int_mask, ints);
1409 }
1410
1411 return ret;
1412}
1413
1414static void free_irq_local(struct fsl_diu_data *data)
1415{
1416 struct diu __iomem *hw = data->diu_reg;
1417
1418 /* Disable all LCDC interrupt */
1419 out_be32(&hw->int_mask, 0x1f);
1420
1421 free_irq(data->irq, NULL);
1422}
1423
1424#ifdef CONFIG_PM 1451#ifdef CONFIG_PM
1425/* 1452/*
1426 * Power management hooks. Note that we won't be called from IRQ context, 1453 * Power management hooks. Note that we won't be called from IRQ context,
@@ -1496,8 +1523,8 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
1496 struct device_node *np = pdev->dev.of_node; 1523 struct device_node *np = pdev->dev.of_node;
1497 struct mfb_info *mfbi; 1524 struct mfb_info *mfbi;
1498 struct fsl_diu_data *data; 1525 struct fsl_diu_data *data;
1499 int diu_mode;
1500 dma_addr_t dma_addr; /* DMA addr of fsl_diu_data struct */ 1526 dma_addr_t dma_addr; /* DMA addr of fsl_diu_data struct */
1527 const void *prop;
1501 unsigned int i; 1528 unsigned int i;
1502 int ret; 1529 int ret;
1503 1530
@@ -1541,17 +1568,13 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
1541 memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info)); 1568 memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info));
1542 mfbi->parent = data; 1569 mfbi->parent = data;
1543 mfbi->ad = &data->ad[i]; 1570 mfbi->ad = &data->ad[i];
1571 }
1544 1572
1545 if (mfbi->index == PLANE0) { 1573 /* Get the EDID data from the device tree, if present */
1546 const u8 *prop; 1574 prop = of_get_property(np, "edid", &ret);
1547 int len; 1575 if (prop && ret == EDID_LENGTH) {
1548 1576 memcpy(data->edid_data, prop, EDID_LENGTH);
1549 /* Get EDID */ 1577 data->has_edid = true;
1550 prop = of_get_property(np, "edid", &len);
1551 if (prop && len == EDID_LENGTH)
1552 mfbi->edid_data = kmemdup(prop, EDID_LENGTH,
1553 GFP_KERNEL);
1554 }
1555 } 1578 }
1556 1579
1557 data->diu_reg = of_iomap(np, 0); 1580 data->diu_reg = of_iomap(np, 0);
@@ -1561,10 +1584,6 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
1561 goto error; 1584 goto error;
1562 } 1585 }
1563 1586
1564 diu_mode = in_be32(&data->diu_reg->diu_mode);
1565 if (diu_mode == MFB_MODE0)
1566 out_be32(&data->diu_reg->diu_mode, 0); /* disable DIU */
1567
1568 /* Get the IRQ of the DIU */ 1587 /* Get the IRQ of the DIU */
1569 data->irq = irq_of_parse_and_map(np, 0); 1588 data->irq = irq_of_parse_and_map(np, 0);
1570 1589
@@ -1586,11 +1605,11 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
1586 data->dummy_ad.paddr = DMA_ADDR(data, dummy_ad); 1605 data->dummy_ad.paddr = DMA_ADDR(data, dummy_ad);
1587 1606
1588 /* 1607 /*
1589 * Let DIU display splash screen if it was pre-initialized 1608 * Let DIU continue to display splash screen if it was pre-initialized
1590 * by the bootloader, set dummy area descriptor otherwise. 1609 * by the bootloader; otherwise, clear the display.
1591 */ 1610 */
1592 if (diu_mode == MFB_MODE0) 1611 if (in_be32(&data->diu_reg->diu_mode) == MFB_MODE0)
1593 out_be32(&data->diu_reg->desc[0], data->dummy_ad.paddr); 1612 out_be32(&data->diu_reg->desc[0], 0);
1594 1613
1595 out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr); 1614 out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr);
1596 out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr); 1615 out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr);
@@ -1603,7 +1622,16 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
1603 } 1622 }
1604 } 1623 }
1605 1624
1606 if (request_irq_local(data)) { 1625 /*
1626 * Older versions of U-Boot leave interrupts enabled, so disable
1627 * all of them and clear the status register.
1628 */
1629 out_be32(&data->diu_reg->int_mask, 0xffffffff);
1630 in_be32(&data->diu_reg->int_status);
1631
1632 ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb",
1633 &data->diu_reg);
1634 if (ret) {
1607 dev_err(&pdev->dev, "could not claim irq\n"); 1635 dev_err(&pdev->dev, "could not claim irq\n");
1608 goto error; 1636 goto error;
1609 } 1637 }
@@ -1638,7 +1666,8 @@ static int fsl_diu_remove(struct platform_device *pdev)
1638 1666
1639 data = dev_get_drvdata(&pdev->dev); 1667 data = dev_get_drvdata(&pdev->dev);
1640 disable_lcdc(&data->fsl_diu_info[0]); 1668 disable_lcdc(&data->fsl_diu_info[0]);
1641 free_irq_local(data); 1669
1670 free_irq(data->irq, &data->diu_reg);
1642 1671
1643 for (i = 0; i < NUM_AOIS; i++) 1672 for (i = 0; i < NUM_AOIS; i++)
1644 uninstall_fb(&data->fsl_diu_info[i]); 1673 uninstall_fb(&data->fsl_diu_info[i]);
@@ -1741,6 +1770,9 @@ static int __init fsl_diu_init(void)
1741 coherence_data_size = be32_to_cpup(prop) * 13; 1770 coherence_data_size = be32_to_cpup(prop) * 13;
1742 coherence_data_size /= 8; 1771 coherence_data_size /= 8;
1743 1772
1773 pr_debug("fsl-diu-fb: coherence data size is %zu bytes\n",
1774 coherence_data_size);
1775
1744 prop = of_get_property(np, "d-cache-line-size", NULL); 1776 prop = of_get_property(np, "d-cache-line-size", NULL);
1745 if (prop == NULL) { 1777 if (prop == NULL) {
1746 pr_err("fsl-diu-fb: missing 'd-cache-line-size' property' " 1778 pr_err("fsl-diu-fb: missing 'd-cache-line-size' property' "
@@ -1750,10 +1782,17 @@ static int __init fsl_diu_init(void)
1750 } 1782 }
1751 d_cache_line_size = be32_to_cpup(prop); 1783 d_cache_line_size = be32_to_cpup(prop);
1752 1784
1785 pr_debug("fsl-diu-fb: cache lines size is %u bytes\n",
1786 d_cache_line_size);
1787
1753 of_node_put(np); 1788 of_node_put(np);
1754 coherence_data = vmalloc(coherence_data_size); 1789 coherence_data = vmalloc(coherence_data_size);
1755 if (!coherence_data) 1790 if (!coherence_data) {
1791 pr_err("fsl-diu-fb: could not allocate coherence data "
1792 "(size=%zu)\n", coherence_data_size);
1756 return -ENOMEM; 1793 return -ENOMEM;
1794 }
1795
1757#endif 1796#endif
1758 1797
1759 ret = platform_driver_register(&fsl_diu_driver); 1798 ret = platform_driver_register(&fsl_diu_driver);
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
index d877c361abda..346d67d6cf4d 100644
--- a/drivers/video/omap2/Kconfig
+++ b/drivers/video/omap2/Kconfig
@@ -1,6 +1,3 @@
1config OMAP2_VRAM
2 bool
3
4config OMAP2_VRFB 1config OMAP2_VRFB
5 bool 2 bool
6 3
diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
index 5ddef129f798..5ea7cb9aed17 100644
--- a/drivers/video/omap2/Makefile
+++ b/drivers/video/omap2/Makefile
@@ -1,4 +1,3 @@
1obj-$(CONFIG_OMAP2_VRAM) += vram.o
2obj-$(CONFIG_OMAP2_VRFB) += vrfb.o 1obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
3 2
4obj-$(CONFIG_OMAP2_DSS) += dss/ 3obj-$(CONFIG_OMAP2_DSS) += dss/
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index c835aa70f96f..65eb76c840a1 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -710,27 +710,6 @@ static void acx_panel_disable(struct omap_dss_device *dssdev)
710 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 710 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
711} 711}
712 712
713static int acx_panel_suspend(struct omap_dss_device *dssdev)
714{
715 dev_dbg(&dssdev->dev, "%s\n", __func__);
716 acx_panel_power_off(dssdev);
717 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
718 return 0;
719}
720
721static int acx_panel_resume(struct omap_dss_device *dssdev)
722{
723 int r;
724
725 dev_dbg(&dssdev->dev, "%s\n", __func__);
726 r = acx_panel_power_on(dssdev);
727 if (r)
728 return r;
729
730 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
731 return 0;
732}
733
734static void acx_panel_set_timings(struct omap_dss_device *dssdev, 713static void acx_panel_set_timings(struct omap_dss_device *dssdev,
735 struct omap_video_timings *timings) 714 struct omap_video_timings *timings)
736{ 715{
@@ -752,8 +731,6 @@ static struct omap_dss_driver acx_panel_driver = {
752 731
753 .enable = acx_panel_enable, 732 .enable = acx_panel_enable,
754 .disable = acx_panel_disable, 733 .disable = acx_panel_disable,
755 .suspend = acx_panel_suspend,
756 .resume = acx_panel_resume,
757 734
758 .set_timings = acx_panel_set_timings, 735 .set_timings = acx_panel_set_timings,
759 .check_timings = acx_panel_check_timings, 736 .check_timings = acx_panel_check_timings,
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 88295c526815..54ca8ae21078 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -688,40 +688,6 @@ static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
688 mutex_unlock(&drv_data->lock); 688 mutex_unlock(&drv_data->lock);
689} 689}
690 690
691static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
692{
693 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
694
695 mutex_lock(&drv_data->lock);
696
697 generic_dpi_panel_power_off(dssdev);
698
699 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
700
701 mutex_unlock(&drv_data->lock);
702
703 return 0;
704}
705
706static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
707{
708 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
709 int r;
710
711 mutex_lock(&drv_data->lock);
712
713 r = generic_dpi_panel_power_on(dssdev);
714 if (r)
715 goto err;
716
717 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
718
719err:
720 mutex_unlock(&drv_data->lock);
721
722 return r;
723}
724
725static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev, 691static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
726 struct omap_video_timings *timings) 692 struct omap_video_timings *timings)
727{ 693{
@@ -769,8 +735,6 @@ static struct omap_dss_driver dpi_driver = {
769 735
770 .enable = generic_dpi_panel_enable, 736 .enable = generic_dpi_panel_enable,
771 .disable = generic_dpi_panel_disable, 737 .disable = generic_dpi_panel_disable,
772 .suspend = generic_dpi_panel_suspend,
773 .resume = generic_dpi_panel_resume,
774 738
775 .set_timings = generic_dpi_panel_set_timings, 739 .set_timings = generic_dpi_panel_set_timings,
776 .get_timings = generic_dpi_panel_get_timings, 740 .get_timings = generic_dpi_panel_get_timings,
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 90c1cabf244e..ace419b801eb 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -143,46 +143,12 @@ static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
143 mutex_unlock(&ld->lock); 143 mutex_unlock(&ld->lock);
144} 144}
145 145
146static int lb035q02_panel_suspend(struct omap_dss_device *dssdev)
147{
148 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
149
150 mutex_lock(&ld->lock);
151
152 lb035q02_panel_power_off(dssdev);
153 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
154
155 mutex_unlock(&ld->lock);
156 return 0;
157}
158
159static int lb035q02_panel_resume(struct omap_dss_device *dssdev)
160{
161 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
162 int r;
163
164 mutex_lock(&ld->lock);
165
166 r = lb035q02_panel_power_on(dssdev);
167 if (r)
168 goto err;
169 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
170
171 mutex_unlock(&ld->lock);
172 return 0;
173err:
174 mutex_unlock(&ld->lock);
175 return r;
176}
177
178static struct omap_dss_driver lb035q02_driver = { 146static struct omap_dss_driver lb035q02_driver = {
179 .probe = lb035q02_panel_probe, 147 .probe = lb035q02_panel_probe,
180 .remove = lb035q02_panel_remove, 148 .remove = lb035q02_panel_remove,
181 149
182 .enable = lb035q02_panel_enable, 150 .enable = lb035q02_panel_enable,
183 .disable = lb035q02_panel_disable, 151 .disable = lb035q02_panel_disable,
184 .suspend = lb035q02_panel_suspend,
185 .resume = lb035q02_panel_resume,
186 152
187 .driver = { 153 .driver = {
188 .name = "lgphilips_lb035q02_panel", 154 .name = "lgphilips_lb035q02_panel",
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 3fc5ad081a21..d1cb722fcdbc 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -574,54 +574,6 @@ static void n8x0_panel_disable(struct omap_dss_device *dssdev)
574 mutex_unlock(&ddata->lock); 574 mutex_unlock(&ddata->lock);
575} 575}
576 576
577static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
578{
579 struct panel_drv_data *ddata = get_drv_data(dssdev);
580
581 dev_dbg(&dssdev->dev, "suspend\n");
582
583 mutex_lock(&ddata->lock);
584
585 rfbi_bus_lock();
586
587 n8x0_panel_power_off(dssdev);
588
589 rfbi_bus_unlock();
590
591 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
592
593 mutex_unlock(&ddata->lock);
594
595 return 0;
596}
597
598static int n8x0_panel_resume(struct omap_dss_device *dssdev)
599{
600 struct panel_drv_data *ddata = get_drv_data(dssdev);
601 int r;
602
603 dev_dbg(&dssdev->dev, "resume\n");
604
605 mutex_lock(&ddata->lock);
606
607 rfbi_bus_lock();
608
609 r = n8x0_panel_power_on(dssdev);
610
611 rfbi_bus_unlock();
612
613 if (r) {
614 mutex_unlock(&ddata->lock);
615 return r;
616 }
617
618 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
619
620 mutex_unlock(&ddata->lock);
621
622 return 0;
623}
624
625static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev, 577static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
626 u16 *xres, u16 *yres) 578 u16 *xres, u16 *yres)
627{ 579{
@@ -683,8 +635,6 @@ static struct omap_dss_driver n8x0_panel_driver = {
683 635
684 .enable = n8x0_panel_enable, 636 .enable = n8x0_panel_enable,
685 .disable = n8x0_panel_disable, 637 .disable = n8x0_panel_disable,
686 .suspend = n8x0_panel_suspend,
687 .resume = n8x0_panel_resume,
688 638
689 .update = n8x0_panel_update, 639 .update = n8x0_panel_update,
690 .sync = n8x0_panel_sync, 640 .sync = n8x0_panel_sync,
@@ -702,18 +652,25 @@ static struct omap_dss_driver n8x0_panel_driver = {
702 652
703static int mipid_spi_probe(struct spi_device *spi) 653static int mipid_spi_probe(struct spi_device *spi)
704{ 654{
655 int r;
656
705 dev_dbg(&spi->dev, "mipid_spi_probe\n"); 657 dev_dbg(&spi->dev, "mipid_spi_probe\n");
706 658
707 spi->mode = SPI_MODE_0; 659 spi->mode = SPI_MODE_0;
708 660
709 s_drv_data.spidev = spi; 661 s_drv_data.spidev = spi;
710 662
711 return 0; 663 r = omap_dss_register_driver(&n8x0_panel_driver);
664 if (r)
665 pr_err("n8x0_panel: dss driver registration failed\n");
666
667 return r;
712} 668}
713 669
714static int mipid_spi_remove(struct spi_device *spi) 670static int mipid_spi_remove(struct spi_device *spi)
715{ 671{
716 dev_dbg(&spi->dev, "mipid_spi_remove\n"); 672 dev_dbg(&spi->dev, "mipid_spi_remove\n");
673 omap_dss_unregister_driver(&n8x0_panel_driver);
717 return 0; 674 return 0;
718} 675}
719 676
@@ -725,34 +682,6 @@ static struct spi_driver mipid_spi_driver = {
725 .probe = mipid_spi_probe, 682 .probe = mipid_spi_probe,
726 .remove = __devexit_p(mipid_spi_remove), 683 .remove = __devexit_p(mipid_spi_remove),
727}; 684};
685module_spi_driver(mipid_spi_driver);
728 686
729static int __init n8x0_panel_drv_init(void)
730{
731 int r;
732
733 r = spi_register_driver(&mipid_spi_driver);
734 if (r) {
735 pr_err("n8x0_panel: spi driver registration failed\n");
736 return r;
737 }
738
739 r = omap_dss_register_driver(&n8x0_panel_driver);
740 if (r) {
741 pr_err("n8x0_panel: dss driver registration failed\n");
742 spi_unregister_driver(&mipid_spi_driver);
743 return r;
744 }
745
746 return 0;
747}
748
749static void __exit n8x0_panel_drv_exit(void)
750{
751 spi_unregister_driver(&mipid_spi_driver);
752
753 omap_dss_unregister_driver(&n8x0_panel_driver);
754}
755
756module_init(n8x0_panel_drv_init);
757module_exit(n8x0_panel_drv_exit);
758MODULE_LICENSE("GPL"); 687MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 908fd268f3dc..2a79c283bebe 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -236,28 +236,6 @@ static void nec_8048_panel_disable(struct omap_dss_device *dssdev)
236 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 236 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
237} 237}
238 238
239static int nec_8048_panel_suspend(struct omap_dss_device *dssdev)
240{
241 nec_8048_panel_power_off(dssdev);
242
243 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
244
245 return 0;
246}
247
248static int nec_8048_panel_resume(struct omap_dss_device *dssdev)
249{
250 int r;
251
252 r = nec_8048_panel_power_on(dssdev);
253 if (r)
254 return r;
255
256 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
257
258 return 0;
259}
260
261static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev) 239static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev)
262{ 240{
263 return 16; 241 return 16;
@@ -268,8 +246,6 @@ static struct omap_dss_driver nec_8048_driver = {
268 .remove = nec_8048_panel_remove, 246 .remove = nec_8048_panel_remove,
269 .enable = nec_8048_panel_enable, 247 .enable = nec_8048_panel_enable,
270 .disable = nec_8048_panel_disable, 248 .disable = nec_8048_panel_disable,
271 .suspend = nec_8048_panel_suspend,
272 .resume = nec_8048_panel_resume,
273 .get_recommended_bpp = nec_8048_recommended_bpp, 249 .get_recommended_bpp = nec_8048_recommended_bpp,
274 250
275 .driver = { 251 .driver = {
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 9df87640ddd2..1b94018aac3e 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -50,6 +50,7 @@ struct picodlp_i2c_data {
50 50
51static struct i2c_device_id picodlp_i2c_id[] = { 51static struct i2c_device_id picodlp_i2c_id[] = {
52 { "picodlp_i2c_driver", 0 }, 52 { "picodlp_i2c_driver", 0 },
53 { }
53}; 54};
54 55
55struct picodlp_i2c_command { 56struct picodlp_i2c_command {
@@ -503,47 +504,6 @@ static void picodlp_panel_disable(struct omap_dss_device *dssdev)
503 dev_dbg(&dssdev->dev, "disabling picodlp panel\n"); 504 dev_dbg(&dssdev->dev, "disabling picodlp panel\n");
504} 505}
505 506
506static int picodlp_panel_suspend(struct omap_dss_device *dssdev)
507{
508 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
509
510 mutex_lock(&picod->lock);
511 /* Turn off DLP Power */
512 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
513 mutex_unlock(&picod->lock);
514 dev_err(&dssdev->dev, "unable to suspend picodlp panel,"
515 " panel is not ACTIVE\n");
516 return -EINVAL;
517 }
518
519 picodlp_panel_power_off(dssdev);
520
521 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
522 mutex_unlock(&picod->lock);
523
524 dev_dbg(&dssdev->dev, "suspending picodlp panel\n");
525 return 0;
526}
527
528static int picodlp_panel_resume(struct omap_dss_device *dssdev)
529{
530 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
531 int r;
532
533 mutex_lock(&picod->lock);
534 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
535 mutex_unlock(&picod->lock);
536 dev_err(&dssdev->dev, "unable to resume picodlp panel,"
537 " panel is not ACTIVE\n");
538 return -EINVAL;
539 }
540
541 r = picodlp_panel_power_on(dssdev);
542 mutex_unlock(&picod->lock);
543 dev_dbg(&dssdev->dev, "resuming picodlp panel\n");
544 return r;
545}
546
547static void picodlp_get_resolution(struct omap_dss_device *dssdev, 507static void picodlp_get_resolution(struct omap_dss_device *dssdev,
548 u16 *xres, u16 *yres) 508 u16 *xres, u16 *yres)
549{ 509{
@@ -560,9 +520,6 @@ static struct omap_dss_driver picodlp_driver = {
560 520
561 .get_resolution = picodlp_get_resolution, 521 .get_resolution = picodlp_get_resolution,
562 522
563 .suspend = picodlp_panel_suspend,
564 .resume = picodlp_panel_resume,
565
566 .driver = { 523 .driver = {
567 .name = "picodlp_panel", 524 .name = "picodlp_panel",
568 .owner = THIS_MODULE, 525 .owner = THIS_MODULE,
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index 1ec3b277ff15..cada8c621e01 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -194,29 +194,12 @@ static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
194 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 194 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
195} 195}
196 196
197static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
198{
199 sharp_ls_power_off(dssdev);
200 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
201 return 0;
202}
203
204static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
205{
206 int r;
207 r = sharp_ls_power_on(dssdev);
208 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
209 return r;
210}
211
212static struct omap_dss_driver sharp_ls_driver = { 197static struct omap_dss_driver sharp_ls_driver = {
213 .probe = sharp_ls_panel_probe, 198 .probe = sharp_ls_panel_probe,
214 .remove = __exit_p(sharp_ls_panel_remove), 199 .remove = __exit_p(sharp_ls_panel_remove),
215 200
216 .enable = sharp_ls_panel_enable, 201 .enable = sharp_ls_panel_enable,
217 .disable = sharp_ls_panel_disable, 202 .disable = sharp_ls_panel_disable,
218 .suspend = sharp_ls_panel_suspend,
219 .resume = sharp_ls_panel_resume,
220 203
221 .driver = { 204 .driver = {
222 .name = "sharp_ls_panel", 205 .name = "sharp_ls_panel",
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index f2f644680ca8..a32407a5735a 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1245,76 +1245,6 @@ static void taal_disable(struct omap_dss_device *dssdev)
1245 mutex_unlock(&td->lock); 1245 mutex_unlock(&td->lock);
1246} 1246}
1247 1247
1248static int taal_suspend(struct omap_dss_device *dssdev)
1249{
1250 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1251 int r;
1252
1253 dev_dbg(&dssdev->dev, "suspend\n");
1254
1255 mutex_lock(&td->lock);
1256
1257 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
1258 r = -EINVAL;
1259 goto err;
1260 }
1261
1262 taal_cancel_ulps_work(dssdev);
1263 taal_cancel_esd_work(dssdev);
1264
1265 dsi_bus_lock(dssdev);
1266
1267 r = taal_wake_up(dssdev);
1268 if (!r)
1269 taal_power_off(dssdev);
1270
1271 dsi_bus_unlock(dssdev);
1272
1273 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
1274
1275 mutex_unlock(&td->lock);
1276
1277 return 0;
1278err:
1279 mutex_unlock(&td->lock);
1280 return r;
1281}
1282
1283static int taal_resume(struct omap_dss_device *dssdev)
1284{
1285 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1286 int r;
1287
1288 dev_dbg(&dssdev->dev, "resume\n");
1289
1290 mutex_lock(&td->lock);
1291
1292 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
1293 r = -EINVAL;
1294 goto err;
1295 }
1296
1297 dsi_bus_lock(dssdev);
1298
1299 r = taal_power_on(dssdev);
1300
1301 dsi_bus_unlock(dssdev);
1302
1303 if (r) {
1304 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1305 } else {
1306 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1307 taal_queue_esd_work(dssdev);
1308 }
1309
1310 mutex_unlock(&td->lock);
1311
1312 return r;
1313err:
1314 mutex_unlock(&td->lock);
1315 return r;
1316}
1317
1318static void taal_framedone_cb(int err, void *data) 1248static void taal_framedone_cb(int err, void *data)
1319{ 1249{
1320 struct omap_dss_device *dssdev = data; 1250 struct omap_dss_device *dssdev = data;
@@ -1818,8 +1748,6 @@ static struct omap_dss_driver taal_driver = {
1818 1748
1819 .enable = taal_enable, 1749 .enable = taal_enable,
1820 .disable = taal_disable, 1750 .disable = taal_disable,
1821 .suspend = taal_suspend,
1822 .resume = taal_resume,
1823 1751
1824 .update = taal_update, 1752 .update = taal_update,
1825 .sync = taal_sync, 1753 .sync = taal_sync,
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 383811cf8648..8281baafe1ef 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -189,37 +189,6 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
189 mutex_unlock(&ddata->lock); 189 mutex_unlock(&ddata->lock);
190} 190}
191 191
192static int tfp410_suspend(struct omap_dss_device *dssdev)
193{
194 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
195
196 mutex_lock(&ddata->lock);
197
198 tfp410_power_off(dssdev);
199
200 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
201
202 mutex_unlock(&ddata->lock);
203
204 return 0;
205}
206
207static int tfp410_resume(struct omap_dss_device *dssdev)
208{
209 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
210 int r;
211
212 mutex_lock(&ddata->lock);
213
214 r = tfp410_power_on(dssdev);
215 if (r == 0)
216 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
217
218 mutex_unlock(&ddata->lock);
219
220 return r;
221}
222
223static void tfp410_set_timings(struct omap_dss_device *dssdev, 192static void tfp410_set_timings(struct omap_dss_device *dssdev,
224 struct omap_video_timings *timings) 193 struct omap_video_timings *timings)
225{ 194{
@@ -355,8 +324,6 @@ static struct omap_dss_driver tfp410_driver = {
355 324
356 .enable = tfp410_enable, 325 .enable = tfp410_enable,
357 .disable = tfp410_disable, 326 .disable = tfp410_disable,
358 .suspend = tfp410_suspend,
359 .resume = tfp410_resume,
360 327
361 .set_timings = tfp410_set_timings, 328 .set_timings = tfp410_set_timings,
362 .get_timings = tfp410_get_timings, 329 .get_timings = tfp410_get_timings,
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index b5e6dbc59f0a..316b3da6d2cb 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -401,24 +401,6 @@ static void tpo_td043_disable(struct omap_dss_device *dssdev)
401 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 401 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
402} 402}
403 403
404static int tpo_td043_suspend(struct omap_dss_device *dssdev)
405{
406 dev_dbg(&dssdev->dev, "suspend\n");
407
408 tpo_td043_disable_dss(dssdev);
409
410 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
411
412 return 0;
413}
414
415static int tpo_td043_resume(struct omap_dss_device *dssdev)
416{
417 dev_dbg(&dssdev->dev, "resume\n");
418
419 return tpo_td043_enable_dss(dssdev);
420}
421
422static int tpo_td043_probe(struct omap_dss_device *dssdev) 404static int tpo_td043_probe(struct omap_dss_device *dssdev)
423{ 405{
424 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 406 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
@@ -500,8 +482,6 @@ static struct omap_dss_driver tpo_td043_driver = {
500 482
501 .enable = tpo_td043_enable, 483 .enable = tpo_td043_enable,
502 .disable = tpo_td043_disable, 484 .disable = tpo_td043_disable,
503 .suspend = tpo_td043_suspend,
504 .resume = tpo_td043_resume,
505 .set_mirror = tpo_td043_set_hmirror, 485 .set_mirror = tpo_td043_set_hmirror,
506 .get_mirror = tpo_td043_get_hmirror, 486 .get_mirror = tpo_td043_get_hmirror,
507 487
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 80f5390aa136..cb0f145c7077 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,33 +1,30 @@
1menuconfig OMAP2_DSS 1menuconfig OMAP2_DSS
2 tristate "OMAP2+ Display Subsystem support" 2 tristate "OMAP2+ Display Subsystem support"
3 depends on ARCH_OMAP2PLUS
4 help 3 help
5 OMAP2+ Display Subsystem support. 4 OMAP2+ Display Subsystem support.
6 5
7if OMAP2_DSS 6if OMAP2_DSS
8 7
9config OMAP2_VRAM_SIZE 8config OMAP2_DSS_DEBUG
10 int "VRAM size (MB)" 9 bool "Debug support"
11 range 0 32 10 default n
12 default 0
13 help 11 help
14 The amount of SDRAM to reserve at boot time for video RAM use. 12 This enables printing of debug messages. Alternatively, debug messages
15 This VRAM will be used by omapfb and other drivers that need 13 can also be enabled by setting CONFIG_DYNAMIC_DEBUG and then setting
16 large continuous RAM area for video use. 14 appropriate flags in <debugfs>/dynamic_debug/control.
17 15
18 You can also set this with "vram=<bytes>" kernel argument, or 16config OMAP2_DSS_DEBUGFS
19 in the board file. 17 bool "Debugfs filesystem support"
20 18 depends on DEBUG_FS
21config OMAP2_DSS_DEBUG_SUPPORT 19 default n
22 bool "Debug support"
23 default y
24 help 20 help
25 This enables debug messages. You need to enable printing 21 This enables debugfs for OMAPDSS at <debugfs>/omapdss. This enables
26 with 'debug' module parameter. 22 querying about clock configuration and register configuration of dss,
23 dispc, dsi, hdmi and rfbi.
27 24
28config OMAP2_DSS_COLLECT_IRQ_STATS 25config OMAP2_DSS_COLLECT_IRQ_STATS
29 bool "Collect DSS IRQ statistics" 26 bool "Collect DSS IRQ statistics"
30 depends on OMAP2_DSS_DEBUG_SUPPORT 27 depends on OMAP2_DSS_DEBUGFS
31 default n 28 default n
32 help 29 help
33 Collect DSS IRQ statistics, printable via debugfs. 30 Collect DSS IRQ statistics, printable via debugfs.
@@ -62,7 +59,6 @@ config OMAP2_DSS_VENC
62 59
63config OMAP4_DSS_HDMI 60config OMAP4_DSS_HDMI
64 bool "HDMI support" 61 bool "HDMI support"
65 depends on ARCH_OMAP4
66 default y 62 default y
67 help 63 help
68 HDMI Interface. This adds the High Definition Multimedia Interface. 64 HDMI Interface. This adds the High Definition Multimedia Interface.
@@ -70,11 +66,9 @@ config OMAP4_DSS_HDMI
70 66
71config OMAP4_DSS_HDMI_AUDIO 67config OMAP4_DSS_HDMI_AUDIO
72 bool 68 bool
73 depends on OMAP4_DSS_HDMI
74 69
75config OMAP2_DSS_SDI 70config OMAP2_DSS_SDI
76 bool "SDI support" 71 bool "SDI support"
77 depends on ARCH_OMAP3
78 default n 72 default n
79 help 73 help
80 SDI (Serial Display Interface) support. 74 SDI (Serial Display Interface) support.
@@ -84,7 +78,6 @@ config OMAP2_DSS_SDI
84 78
85config OMAP2_DSS_DSI 79config OMAP2_DSS_DSI
86 bool "DSI support" 80 bool "DSI support"
87 depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5
88 default n 81 default n
89 help 82 help
90 MIPI DSI (Display Serial Interface) support. 83 MIPI DSI (Display Serial Interface) support.
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 4549869bfe1a..61949ff7940c 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,10 @@
1obj-$(CONFIG_OMAP2_DSS) += omapdss.o 1obj-$(CONFIG_OMAP2_DSS) += omapdss.o
2# Core DSS files
2omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ 3omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
3 manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o 4 output.o
5# DSS compat layer files
6omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
7 dispc-compat.o display-sysfs.o
4omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o 8omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
5omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o 9omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
6omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o 10omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
@@ -8,3 +12,4 @@ omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
8omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 12omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
9omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \ 13omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
10 hdmi_panel.o ti_hdmi_4xxx_ip.o 14 hdmi_panel.o ti_hdmi_4xxx_ip.o
15ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 19d66f471b4b..d446bdfc4c82 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -18,6 +18,7 @@
18#define DSS_SUBSYS_NAME "APPLY" 18#define DSS_SUBSYS_NAME "APPLY"
19 19
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/module.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/spinlock.h> 23#include <linux/spinlock.h>
23#include <linux/jiffies.h> 24#include <linux/jiffies.h>
@@ -26,6 +27,7 @@
26 27
27#include "dss.h" 28#include "dss.h"
28#include "dss_features.h" 29#include "dss_features.h"
30#include "dispc-compat.h"
29 31
30/* 32/*
31 * We have 4 levels of cache for the dispc settings. First two are in SW and 33 * We have 4 levels of cache for the dispc settings. First two are in SW and
@@ -70,7 +72,6 @@ struct ovl_priv_data {
70 bool shadow_extra_info_dirty; 72 bool shadow_extra_info_dirty;
71 73
72 bool enabled; 74 bool enabled;
73 enum omap_channel channel;
74 u32 fifo_low, fifo_high; 75 u32 fifo_low, fifo_high;
75 76
76 /* 77 /*
@@ -105,6 +106,9 @@ struct mgr_priv_data {
105 106
106 struct omap_video_timings timings; 107 struct omap_video_timings timings;
107 struct dss_lcd_mgr_config lcd_config; 108 struct dss_lcd_mgr_config lcd_config;
109
110 void (*framedone_handler)(void *);
111 void *framedone_handler_data;
108}; 112};
109 113
110static struct { 114static struct {
@@ -132,7 +136,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
132 return &dss_data.mgr_priv_data_array[mgr->id]; 136 return &dss_data.mgr_priv_data_array[mgr->id];
133} 137}
134 138
135void dss_apply_init(void) 139static void apply_init_priv(void)
136{ 140{
137 const int num_ovls = dss_feat_get_num_ovls(); 141 const int num_ovls = dss_feat_get_num_ovls();
138 struct mgr_priv_data *mp; 142 struct mgr_priv_data *mp;
@@ -414,11 +418,46 @@ static void wait_pending_extra_info_updates(void)
414 r = wait_for_completion_timeout(&extra_updated_completion, t); 418 r = wait_for_completion_timeout(&extra_updated_completion, t);
415 if (r == 0) 419 if (r == 0)
416 DSSWARN("timeout in wait_pending_extra_info_updates\n"); 420 DSSWARN("timeout in wait_pending_extra_info_updates\n");
417 else if (r < 0)
418 DSSERR("wait_pending_extra_info_updates failed: %d\n", r);
419} 421}
420 422
421int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) 423static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
424{
425 return ovl->manager ?
426 (ovl->manager->output ? ovl->manager->output->device : NULL) :
427 NULL;
428}
429
430static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
431{
432 return mgr->output ? mgr->output->device : NULL;
433}
434
435static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
436{
437 unsigned long timeout = msecs_to_jiffies(500);
438 struct omap_dss_device *dssdev = mgr->get_device(mgr);
439 u32 irq;
440 int r;
441
442 r = dispc_runtime_get();
443 if (r)
444 return r;
445
446 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
447 irq = DISPC_IRQ_EVSYNC_ODD;
448 else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
449 irq = DISPC_IRQ_EVSYNC_EVEN;
450 else
451 irq = dispc_mgr_get_vsync_irq(mgr->id);
452
453 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
454
455 dispc_runtime_put();
456
457 return r;
458}
459
460static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
422{ 461{
423 unsigned long timeout = msecs_to_jiffies(500); 462 unsigned long timeout = msecs_to_jiffies(500);
424 struct mgr_priv_data *mp = get_mgr_priv(mgr); 463 struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -488,7 +527,7 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
488 return r; 527 return r;
489} 528}
490 529
491int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) 530static int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
492{ 531{
493 unsigned long timeout = msecs_to_jiffies(500); 532 unsigned long timeout = msecs_to_jiffies(500);
494 struct ovl_priv_data *op; 533 struct ovl_priv_data *op;
@@ -573,7 +612,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
573 struct mgr_priv_data *mp; 612 struct mgr_priv_data *mp;
574 int r; 613 int r;
575 614
576 DSSDBGF("%d", ovl->id); 615 DSSDBG("writing ovl %d regs", ovl->id);
577 616
578 if (!op->enabled || !op->info_dirty) 617 if (!op->enabled || !op->info_dirty)
579 return; 618 return;
@@ -608,7 +647,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
608 struct ovl_priv_data *op = get_ovl_priv(ovl); 647 struct ovl_priv_data *op = get_ovl_priv(ovl);
609 struct mgr_priv_data *mp; 648 struct mgr_priv_data *mp;
610 649
611 DSSDBGF("%d", ovl->id); 650 DSSDBG("writing ovl %d regs extra", ovl->id);
612 651
613 if (!op->extra_info_dirty) 652 if (!op->extra_info_dirty)
614 return; 653 return;
@@ -617,7 +656,6 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
617 * disabled */ 656 * disabled */
618 657
619 dispc_ovl_enable(ovl->id, op->enabled); 658 dispc_ovl_enable(ovl->id, op->enabled);
620 dispc_ovl_set_channel_out(ovl->id, op->channel);
621 dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high); 659 dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
622 660
623 mp = get_mgr_priv(ovl->manager); 661 mp = get_mgr_priv(ovl->manager);
@@ -632,7 +670,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
632 struct mgr_priv_data *mp = get_mgr_priv(mgr); 670 struct mgr_priv_data *mp = get_mgr_priv(mgr);
633 struct omap_overlay *ovl; 671 struct omap_overlay *ovl;
634 672
635 DSSDBGF("%d", mgr->id); 673 DSSDBG("writing mgr %d regs", mgr->id);
636 674
637 if (!mp->enabled) 675 if (!mp->enabled)
638 return; 676 return;
@@ -658,7 +696,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
658{ 696{
659 struct mgr_priv_data *mp = get_mgr_priv(mgr); 697 struct mgr_priv_data *mp = get_mgr_priv(mgr);
660 698
661 DSSDBGF("%d", mgr->id); 699 DSSDBG("writing mgr %d regs extra", mgr->id);
662 700
663 if (!mp->extra_info_dirty) 701 if (!mp->extra_info_dirty)
664 return; 702 return;
@@ -666,22 +704,8 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
666 dispc_mgr_set_timings(mgr->id, &mp->timings); 704 dispc_mgr_set_timings(mgr->id, &mp->timings);
667 705
668 /* lcd_config parameters */ 706 /* lcd_config parameters */
669 if (dss_mgr_is_lcd(mgr->id)) { 707 if (dss_mgr_is_lcd(mgr->id))
670 dispc_mgr_set_io_pad_mode(mp->lcd_config.io_pad_mode); 708 dispc_mgr_set_lcd_config(mgr->id, &mp->lcd_config);
671
672 dispc_mgr_enable_stallmode(mgr->id, mp->lcd_config.stallmode);
673 dispc_mgr_enable_fifohandcheck(mgr->id,
674 mp->lcd_config.fifohandcheck);
675
676 dispc_mgr_set_clock_div(mgr->id, &mp->lcd_config.clock_info);
677
678 dispc_mgr_set_tft_data_lines(mgr->id,
679 mp->lcd_config.video_port_width);
680
681 dispc_lcd_enable_signal_polarity(mp->lcd_config.lcden_sig_polarity);
682
683 dispc_mgr_set_lcd_type_tft(mgr->id);
684 }
685 709
686 mp->extra_info_dirty = false; 710 mp->extra_info_dirty = false;
687 if (mp->updating) 711 if (mp->updating)
@@ -761,7 +785,7 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
761 } 785 }
762} 786}
763 787
764void dss_mgr_start_update(struct omap_overlay_manager *mgr) 788static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr)
765{ 789{
766 struct mgr_priv_data *mp = get_mgr_priv(mgr); 790 struct mgr_priv_data *mp = get_mgr_priv(mgr);
767 unsigned long flags; 791 unsigned long flags;
@@ -786,9 +810,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
786 if (!dss_data.irq_enabled && need_isr()) 810 if (!dss_data.irq_enabled && need_isr())
787 dss_register_vsync_isr(); 811 dss_register_vsync_isr();
788 812
789 dispc_mgr_enable(mgr->id, true); 813 dispc_mgr_enable_sync(mgr->id);
790
791 mgr_clear_shadow_dirty(mgr);
792 814
793 spin_unlock_irqrestore(&data_lock, flags); 815 spin_unlock_irqrestore(&data_lock, flags);
794} 816}
@@ -845,7 +867,6 @@ static void dss_apply_irq_handler(void *data, u32 mask)
845 for (i = 0; i < num_mgrs; i++) { 867 for (i = 0; i < num_mgrs; i++) {
846 struct omap_overlay_manager *mgr; 868 struct omap_overlay_manager *mgr;
847 struct mgr_priv_data *mp; 869 struct mgr_priv_data *mp;
848 bool was_updating;
849 870
850 mgr = omap_dss_get_overlay_manager(i); 871 mgr = omap_dss_get_overlay_manager(i);
851 mp = get_mgr_priv(mgr); 872 mp = get_mgr_priv(mgr);
@@ -853,7 +874,6 @@ static void dss_apply_irq_handler(void *data, u32 mask)
853 if (!mp->enabled) 874 if (!mp->enabled)
854 continue; 875 continue;
855 876
856 was_updating = mp->updating;
857 mp->updating = dispc_mgr_is_enabled(i); 877 mp->updating = dispc_mgr_is_enabled(i);
858 878
859 if (!mgr_manual_update(mgr)) { 879 if (!mgr_manual_update(mgr)) {
@@ -872,6 +892,21 @@ static void dss_apply_irq_handler(void *data, u32 mask)
872 if (!extra_updating) 892 if (!extra_updating)
873 complete_all(&extra_updated_completion); 893 complete_all(&extra_updated_completion);
874 894
895 /* call framedone handlers for manual update displays */
896 for (i = 0; i < num_mgrs; i++) {
897 struct omap_overlay_manager *mgr;
898 struct mgr_priv_data *mp;
899
900 mgr = omap_dss_get_overlay_manager(i);
901 mp = get_mgr_priv(mgr);
902
903 if (!mgr_manual_update(mgr) || !mp->framedone_handler)
904 continue;
905
906 if (mask & dispc_mgr_get_framedone_irq(i))
907 mp->framedone_handler(mp->framedone_handler_data);
908 }
909
875 if (!need_isr()) 910 if (!need_isr())
876 dss_unregister_vsync_isr(); 911 dss_unregister_vsync_isr();
877 912
@@ -906,7 +941,7 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
906 mp->info = mp->user_info; 941 mp->info = mp->user_info;
907} 942}
908 943
909int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) 944static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
910{ 945{
911 unsigned long flags; 946 unsigned long flags;
912 struct omap_overlay *ovl; 947 struct omap_overlay *ovl;
@@ -1005,7 +1040,7 @@ static void dss_setup_fifos(void)
1005 } 1040 }
1006} 1041}
1007 1042
1008int dss_mgr_enable(struct omap_overlay_manager *mgr) 1043static int dss_mgr_enable_compat(struct omap_overlay_manager *mgr)
1009{ 1044{
1010 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1045 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1011 unsigned long flags; 1046 unsigned long flags;
@@ -1035,10 +1070,13 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
1035 if (!mgr_manual_update(mgr)) 1070 if (!mgr_manual_update(mgr))
1036 mp->updating = true; 1071 mp->updating = true;
1037 1072
1073 if (!dss_data.irq_enabled && need_isr())
1074 dss_register_vsync_isr();
1075
1038 spin_unlock_irqrestore(&data_lock, flags); 1076 spin_unlock_irqrestore(&data_lock, flags);
1039 1077
1040 if (!mgr_manual_update(mgr)) 1078 if (!mgr_manual_update(mgr))
1041 dispc_mgr_enable(mgr->id, true); 1079 dispc_mgr_enable_sync(mgr->id);
1042 1080
1043out: 1081out:
1044 mutex_unlock(&apply_lock); 1082 mutex_unlock(&apply_lock);
@@ -1052,7 +1090,7 @@ err:
1052 return r; 1090 return r;
1053} 1091}
1054 1092
1055void dss_mgr_disable(struct omap_overlay_manager *mgr) 1093static void dss_mgr_disable_compat(struct omap_overlay_manager *mgr)
1056{ 1094{
1057 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1095 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1058 unsigned long flags; 1096 unsigned long flags;
@@ -1063,7 +1101,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
1063 goto out; 1101 goto out;
1064 1102
1065 if (!mgr_manual_update(mgr)) 1103 if (!mgr_manual_update(mgr))
1066 dispc_mgr_enable(mgr->id, false); 1104 dispc_mgr_disable_sync(mgr->id);
1067 1105
1068 spin_lock_irqsave(&data_lock, flags); 1106 spin_lock_irqsave(&data_lock, flags);
1069 1107
@@ -1076,7 +1114,7 @@ out:
1076 mutex_unlock(&apply_lock); 1114 mutex_unlock(&apply_lock);
1077} 1115}
1078 1116
1079int dss_mgr_set_info(struct omap_overlay_manager *mgr, 1117static int dss_mgr_set_info(struct omap_overlay_manager *mgr,
1080 struct omap_overlay_manager_info *info) 1118 struct omap_overlay_manager_info *info)
1081{ 1119{
1082 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1120 struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1097,7 +1135,7 @@ int dss_mgr_set_info(struct omap_overlay_manager *mgr,
1097 return 0; 1135 return 0;
1098} 1136}
1099 1137
1100void dss_mgr_get_info(struct omap_overlay_manager *mgr, 1138static void dss_mgr_get_info(struct omap_overlay_manager *mgr,
1101 struct omap_overlay_manager_info *info) 1139 struct omap_overlay_manager_info *info)
1102{ 1140{
1103 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1141 struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1110,7 +1148,7 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
1110 spin_unlock_irqrestore(&data_lock, flags); 1148 spin_unlock_irqrestore(&data_lock, flags);
1111} 1149}
1112 1150
1113int dss_mgr_set_output(struct omap_overlay_manager *mgr, 1151static int dss_mgr_set_output(struct omap_overlay_manager *mgr,
1114 struct omap_dss_output *output) 1152 struct omap_dss_output *output)
1115{ 1153{
1116 int r; 1154 int r;
@@ -1142,7 +1180,7 @@ err:
1142 return r; 1180 return r;
1143} 1181}
1144 1182
1145int dss_mgr_unset_output(struct omap_overlay_manager *mgr) 1183static int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
1146{ 1184{
1147 int r; 1185 int r;
1148 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1186 struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1189,7 +1227,7 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
1189 mp->extra_info_dirty = true; 1227 mp->extra_info_dirty = true;
1190} 1228}
1191 1229
1192void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 1230static void dss_mgr_set_timings_compat(struct omap_overlay_manager *mgr,
1193 const struct omap_video_timings *timings) 1231 const struct omap_video_timings *timings)
1194{ 1232{
1195 unsigned long flags; 1233 unsigned long flags;
@@ -1217,7 +1255,7 @@ static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
1217 mp->extra_info_dirty = true; 1255 mp->extra_info_dirty = true;
1218} 1256}
1219 1257
1220void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, 1258static void dss_mgr_set_lcd_config_compat(struct omap_overlay_manager *mgr,
1221 const struct dss_lcd_mgr_config *config) 1259 const struct dss_lcd_mgr_config *config)
1222{ 1260{
1223 unsigned long flags; 1261 unsigned long flags;
@@ -1236,7 +1274,7 @@ out:
1236 spin_unlock_irqrestore(&data_lock, flags); 1274 spin_unlock_irqrestore(&data_lock, flags);
1237} 1275}
1238 1276
1239int dss_ovl_set_info(struct omap_overlay *ovl, 1277static int dss_ovl_set_info(struct omap_overlay *ovl,
1240 struct omap_overlay_info *info) 1278 struct omap_overlay_info *info)
1241{ 1279{
1242 struct ovl_priv_data *op = get_ovl_priv(ovl); 1280 struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -1257,7 +1295,7 @@ int dss_ovl_set_info(struct omap_overlay *ovl,
1257 return 0; 1295 return 0;
1258} 1296}
1259 1297
1260void dss_ovl_get_info(struct omap_overlay *ovl, 1298static void dss_ovl_get_info(struct omap_overlay *ovl,
1261 struct omap_overlay_info *info) 1299 struct omap_overlay_info *info)
1262{ 1300{
1263 struct ovl_priv_data *op = get_ovl_priv(ovl); 1301 struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -1270,7 +1308,7 @@ void dss_ovl_get_info(struct omap_overlay *ovl,
1270 spin_unlock_irqrestore(&data_lock, flags); 1308 spin_unlock_irqrestore(&data_lock, flags);
1271} 1309}
1272 1310
1273int dss_ovl_set_manager(struct omap_overlay *ovl, 1311static int dss_ovl_set_manager(struct omap_overlay *ovl,
1274 struct omap_overlay_manager *mgr) 1312 struct omap_overlay_manager *mgr)
1275{ 1313{
1276 struct ovl_priv_data *op = get_ovl_priv(ovl); 1314 struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -1289,45 +1327,40 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
1289 goto err; 1327 goto err;
1290 } 1328 }
1291 1329
1330 r = dispc_runtime_get();
1331 if (r)
1332 goto err;
1333
1292 spin_lock_irqsave(&data_lock, flags); 1334 spin_lock_irqsave(&data_lock, flags);
1293 1335
1294 if (op->enabled) { 1336 if (op->enabled) {
1295 spin_unlock_irqrestore(&data_lock, flags); 1337 spin_unlock_irqrestore(&data_lock, flags);
1296 DSSERR("overlay has to be disabled to change the manager\n"); 1338 DSSERR("overlay has to be disabled to change the manager\n");
1297 r = -EINVAL; 1339 r = -EINVAL;
1298 goto err; 1340 goto err1;
1299 } 1341 }
1300 1342
1301 op->channel = mgr->id; 1343 dispc_ovl_set_channel_out(ovl->id, mgr->id);
1302 op->extra_info_dirty = true;
1303 1344
1304 ovl->manager = mgr; 1345 ovl->manager = mgr;
1305 list_add_tail(&ovl->list, &mgr->overlays); 1346 list_add_tail(&ovl->list, &mgr->overlays);
1306 1347
1307 spin_unlock_irqrestore(&data_lock, flags); 1348 spin_unlock_irqrestore(&data_lock, flags);
1308 1349
1309 /* XXX: When there is an overlay on a DSI manual update display, and 1350 dispc_runtime_put();
1310 * the overlay is first disabled, then moved to tv, and enabled, we
1311 * seem to get SYNC_LOST_DIGIT error.
1312 *
1313 * Waiting doesn't seem to help, but updating the manual update display
1314 * after disabling the overlay seems to fix this. This hints that the
1315 * overlay is perhaps somehow tied to the LCD output until the output
1316 * is updated.
1317 *
1318 * Userspace workaround for this is to update the LCD after disabling
1319 * the overlay, but before moving the overlay to TV.
1320 */
1321 1351
1322 mutex_unlock(&apply_lock); 1352 mutex_unlock(&apply_lock);
1323 1353
1324 return 0; 1354 return 0;
1355
1356err1:
1357 dispc_runtime_put();
1325err: 1358err:
1326 mutex_unlock(&apply_lock); 1359 mutex_unlock(&apply_lock);
1327 return r; 1360 return r;
1328} 1361}
1329 1362
1330int dss_ovl_unset_manager(struct omap_overlay *ovl) 1363static int dss_ovl_unset_manager(struct omap_overlay *ovl)
1331{ 1364{
1332 struct ovl_priv_data *op = get_ovl_priv(ovl); 1365 struct ovl_priv_data *op = get_ovl_priv(ovl);
1333 unsigned long flags; 1366 unsigned long flags;
@@ -1355,9 +1388,24 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
1355 /* wait for pending extra_info updates to ensure the ovl is disabled */ 1388 /* wait for pending extra_info updates to ensure the ovl is disabled */
1356 wait_pending_extra_info_updates(); 1389 wait_pending_extra_info_updates();
1357 1390
1391 /*
1392 * For a manual update display, there is no guarantee that the overlay
1393 * is really disabled in HW, we may need an extra update from this
1394 * manager before the configurations can go in. Return an error if the
1395 * overlay needed an update from the manager.
1396 *
1397 * TODO: Instead of returning an error, try to do a dummy manager update
1398 * here to disable the overlay in hardware. Use the *GATED fields in
1399 * the DISPC_CONFIG registers to do a dummy update.
1400 */
1358 spin_lock_irqsave(&data_lock, flags); 1401 spin_lock_irqsave(&data_lock, flags);
1359 1402
1360 op->channel = -1; 1403 if (ovl_manual_update(ovl) && op->extra_info_dirty) {
1404 spin_unlock_irqrestore(&data_lock, flags);
1405 DSSERR("need an update to change the manager\n");
1406 r = -EINVAL;
1407 goto err;
1408 }
1361 1409
1362 ovl->manager = NULL; 1410 ovl->manager = NULL;
1363 list_del(&ovl->list); 1411 list_del(&ovl->list);
@@ -1372,7 +1420,7 @@ err:
1372 return r; 1420 return r;
1373} 1421}
1374 1422
1375bool dss_ovl_is_enabled(struct omap_overlay *ovl) 1423static bool dss_ovl_is_enabled(struct omap_overlay *ovl)
1376{ 1424{
1377 struct ovl_priv_data *op = get_ovl_priv(ovl); 1425 struct ovl_priv_data *op = get_ovl_priv(ovl);
1378 unsigned long flags; 1426 unsigned long flags;
@@ -1387,7 +1435,7 @@ bool dss_ovl_is_enabled(struct omap_overlay *ovl)
1387 return e; 1435 return e;
1388} 1436}
1389 1437
1390int dss_ovl_enable(struct omap_overlay *ovl) 1438static int dss_ovl_enable(struct omap_overlay *ovl)
1391{ 1439{
1392 struct ovl_priv_data *op = get_ovl_priv(ovl); 1440 struct ovl_priv_data *op = get_ovl_priv(ovl);
1393 unsigned long flags; 1441 unsigned long flags;
@@ -1437,7 +1485,7 @@ err1:
1437 return r; 1485 return r;
1438} 1486}
1439 1487
1440int dss_ovl_disable(struct omap_overlay *ovl) 1488static int dss_ovl_disable(struct omap_overlay *ovl)
1441{ 1489{
1442 struct ovl_priv_data *op = get_ovl_priv(ovl); 1490 struct ovl_priv_data *op = get_ovl_priv(ovl);
1443 unsigned long flags; 1491 unsigned long flags;
@@ -1472,3 +1520,152 @@ err:
1472 return r; 1520 return r;
1473} 1521}
1474 1522
1523static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager *mgr,
1524 void (*handler)(void *), void *data)
1525{
1526 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1527
1528 if (mp->framedone_handler)
1529 return -EBUSY;
1530
1531 mp->framedone_handler = handler;
1532 mp->framedone_handler_data = data;
1533
1534 return 0;
1535}
1536
1537static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager *mgr,
1538 void (*handler)(void *), void *data)
1539{
1540 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1541
1542 WARN_ON(mp->framedone_handler != handler ||
1543 mp->framedone_handler_data != data);
1544
1545 mp->framedone_handler = NULL;
1546 mp->framedone_handler_data = NULL;
1547}
1548
1549static const struct dss_mgr_ops apply_mgr_ops = {
1550 .start_update = dss_mgr_start_update_compat,
1551 .enable = dss_mgr_enable_compat,
1552 .disable = dss_mgr_disable_compat,
1553 .set_timings = dss_mgr_set_timings_compat,
1554 .set_lcd_config = dss_mgr_set_lcd_config_compat,
1555 .register_framedone_handler = dss_mgr_register_framedone_handler_compat,
1556 .unregister_framedone_handler = dss_mgr_unregister_framedone_handler_compat,
1557};
1558
1559static int compat_refcnt;
1560static DEFINE_MUTEX(compat_init_lock);
1561
1562int omapdss_compat_init(void)
1563{
1564 struct platform_device *pdev = dss_get_core_pdev();
1565 struct omap_dss_device *dssdev = NULL;
1566 int i, r;
1567
1568 mutex_lock(&compat_init_lock);
1569
1570 if (compat_refcnt++ > 0)
1571 goto out;
1572
1573 apply_init_priv();
1574
1575 dss_init_overlay_managers(pdev);
1576 dss_init_overlays(pdev);
1577
1578 for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
1579 struct omap_overlay_manager *mgr;
1580
1581 mgr = omap_dss_get_overlay_manager(i);
1582
1583 mgr->set_output = &dss_mgr_set_output;
1584 mgr->unset_output = &dss_mgr_unset_output;
1585 mgr->apply = &omap_dss_mgr_apply;
1586 mgr->set_manager_info = &dss_mgr_set_info;
1587 mgr->get_manager_info = &dss_mgr_get_info;
1588 mgr->wait_for_go = &dss_mgr_wait_for_go;
1589 mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
1590 mgr->get_device = &dss_mgr_get_device;
1591 }
1592
1593 for (i = 0; i < omap_dss_get_num_overlays(); i++) {
1594 struct omap_overlay *ovl = omap_dss_get_overlay(i);
1595
1596 ovl->is_enabled = &dss_ovl_is_enabled;
1597 ovl->enable = &dss_ovl_enable;
1598 ovl->disable = &dss_ovl_disable;
1599 ovl->set_manager = &dss_ovl_set_manager;
1600 ovl->unset_manager = &dss_ovl_unset_manager;
1601 ovl->set_overlay_info = &dss_ovl_set_info;
1602 ovl->get_overlay_info = &dss_ovl_get_info;
1603 ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
1604 ovl->get_device = &dss_ovl_get_device;
1605 }
1606
1607 r = dss_install_mgr_ops(&apply_mgr_ops);
1608 if (r)
1609 goto err_mgr_ops;
1610
1611 for_each_dss_dev(dssdev) {
1612 r = display_init_sysfs(pdev, dssdev);
1613 /* XXX uninit sysfs files on error */
1614 if (r)
1615 goto err_disp_sysfs;
1616 }
1617
1618 dispc_runtime_get();
1619
1620 r = dss_dispc_initialize_irq();
1621 if (r)
1622 goto err_init_irq;
1623
1624 dispc_runtime_put();
1625
1626out:
1627 mutex_unlock(&compat_init_lock);
1628
1629 return 0;
1630
1631err_init_irq:
1632 dispc_runtime_put();
1633
1634err_disp_sysfs:
1635 dss_uninstall_mgr_ops();
1636
1637err_mgr_ops:
1638 dss_uninit_overlay_managers(pdev);
1639 dss_uninit_overlays(pdev);
1640
1641 compat_refcnt--;
1642
1643 mutex_unlock(&compat_init_lock);
1644
1645 return r;
1646}
1647EXPORT_SYMBOL(omapdss_compat_init);
1648
1649void omapdss_compat_uninit(void)
1650{
1651 struct platform_device *pdev = dss_get_core_pdev();
1652 struct omap_dss_device *dssdev = NULL;
1653
1654 mutex_lock(&compat_init_lock);
1655
1656 if (--compat_refcnt > 0)
1657 goto out;
1658
1659 dss_dispc_uninitialize_irq();
1660
1661 for_each_dss_dev(dssdev)
1662 display_uninit_sysfs(pdev, dssdev);
1663
1664 dss_uninstall_mgr_ops();
1665
1666 dss_uninit_overlay_managers(pdev);
1667 dss_uninit_overlays(pdev);
1668out:
1669 mutex_unlock(&compat_init_lock);
1670}
1671EXPORT_SYMBOL(omapdss_compat_uninit);
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index d94ef9e31a35..f8779d4750ba 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -53,15 +53,23 @@ static char *def_disp_name;
53module_param_named(def_disp, def_disp_name, charp, 0); 53module_param_named(def_disp, def_disp_name, charp, 0);
54MODULE_PARM_DESC(def_disp, "default display name"); 54MODULE_PARM_DESC(def_disp, "default display name");
55 55
56#ifdef DEBUG 56const char *omapdss_get_default_display_name(void)
57bool dss_debug;
58module_param_named(debug, dss_debug, bool, 0644);
59#endif
60
61const char *dss_get_default_display_name(void)
62{ 57{
63 return core.default_display_name; 58 return core.default_display_name;
64} 59}
60EXPORT_SYMBOL(omapdss_get_default_display_name);
61
62enum omapdss_version omapdss_get_version(void)
63{
64 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
65 return pdata->version;
66}
67EXPORT_SYMBOL(omapdss_get_version);
68
69struct platform_device *dss_get_core_pdev(void)
70{
71 return core.pdev;
72}
65 73
66/* REGULATORS */ 74/* REGULATORS */
67 75
@@ -93,21 +101,6 @@ struct regulator *dss_get_vdds_sdi(void)
93 return reg; 101 return reg;
94} 102}
95 103
96int dss_get_ctx_loss_count(struct device *dev)
97{
98 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
99 int cnt;
100
101 if (!board_data->get_context_loss_count)
102 return -ENOENT;
103
104 cnt = board_data->get_context_loss_count(dev);
105
106 WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
107
108 return cnt;
109}
110
111int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask) 104int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask)
112{ 105{
113 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; 106 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
@@ -122,7 +115,7 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)
122{ 115{
123 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; 116 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
124 117
125 if (!board_data->dsi_enable_pads) 118 if (!board_data->dsi_disable_pads)
126 return; 119 return;
127 120
128 return board_data->dsi_disable_pads(dsi_id, lane_mask); 121 return board_data->dsi_disable_pads(dsi_id, lane_mask);
@@ -138,7 +131,7 @@ int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
138 return 0; 131 return 0;
139} 132}
140 133
141#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 134#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
142static int dss_debug_show(struct seq_file *s, void *unused) 135static int dss_debug_show(struct seq_file *s, void *unused)
143{ 136{
144 void (*func)(struct seq_file *) = s->private; 137 void (*func)(struct seq_file *) = s->private;
@@ -193,7 +186,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
193 186
194 return 0; 187 return 0;
195} 188}
196#else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ 189#else /* CONFIG_OMAP2_DSS_DEBUGFS */
197static inline int dss_initialize_debugfs(void) 190static inline int dss_initialize_debugfs(void)
198{ 191{
199 return 0; 192 return 0;
@@ -205,7 +198,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
205{ 198{
206 return 0; 199 return 0;
207} 200}
208#endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ 201#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
209 202
210/* PLATFORM DEVICE */ 203/* PLATFORM DEVICE */
211static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d) 204static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)
@@ -237,12 +230,7 @@ static int __init omap_dss_probe(struct platform_device *pdev)
237 230
238 core.pdev = pdev; 231 core.pdev = pdev;
239 232
240 dss_features_init(pdata->version); 233 dss_features_init(omapdss_get_version());
241
242 dss_apply_init();
243
244 dss_init_overlay_managers(pdev);
245 dss_init_overlays(pdev);
246 234
247 r = dss_initialize_debugfs(); 235 r = dss_initialize_debugfs();
248 if (r) 236 if (r)
@@ -268,9 +256,6 @@ static int omap_dss_remove(struct platform_device *pdev)
268 256
269 dss_uninitialize_debugfs(); 257 dss_uninitialize_debugfs();
270 258
271 dss_uninit_overlays(pdev);
272 dss_uninit_overlay_managers(pdev);
273
274 return 0; 259 return 0;
275} 260}
276 261
@@ -358,15 +343,10 @@ static int dss_driver_probe(struct device *dev)
358 dev_name(dev), dssdev->driver_name, 343 dev_name(dev), dssdev->driver_name,
359 dssdrv->driver.name); 344 dssdrv->driver.name);
360 345
361 r = dss_init_device(core.pdev, dssdev);
362 if (r)
363 return r;
364
365 r = dssdrv->probe(dssdev); 346 r = dssdrv->probe(dssdev);
366 347
367 if (r) { 348 if (r) {
368 DSSERR("driver probe failed: %d\n", r); 349 DSSERR("driver probe failed: %d\n", r);
369 dss_uninit_device(core.pdev, dssdev);
370 return r; 350 return r;
371 } 351 }
372 352
@@ -387,8 +367,6 @@ static int dss_driver_remove(struct device *dev)
387 367
388 dssdrv->remove(dssdev); 368 dssdrv->remove(dssdev);
389 369
390 dss_uninit_device(core.pdev, dssdev);
391
392 dssdev->driver = NULL; 370 dssdev->driver = NULL;
393 371
394 return 0; 372 return 0;
@@ -507,6 +485,9 @@ static int __init omap_dss_bus_register(void)
507 485
508/* INIT */ 486/* INIT */
509static int (*dss_output_drv_reg_funcs[])(void) __initdata = { 487static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
488#ifdef CONFIG_OMAP2_DSS_DSI
489 dsi_init_platform_driver,
490#endif
510#ifdef CONFIG_OMAP2_DSS_DPI 491#ifdef CONFIG_OMAP2_DSS_DPI
511 dpi_init_platform_driver, 492 dpi_init_platform_driver,
512#endif 493#endif
@@ -519,15 +500,15 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
519#ifdef CONFIG_OMAP2_DSS_VENC 500#ifdef CONFIG_OMAP2_DSS_VENC
520 venc_init_platform_driver, 501 venc_init_platform_driver,
521#endif 502#endif
522#ifdef CONFIG_OMAP2_DSS_DSI
523 dsi_init_platform_driver,
524#endif
525#ifdef CONFIG_OMAP4_DSS_HDMI 503#ifdef CONFIG_OMAP4_DSS_HDMI
526 hdmi_init_platform_driver, 504 hdmi_init_platform_driver,
527#endif 505#endif
528}; 506};
529 507
530static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { 508static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = {
509#ifdef CONFIG_OMAP2_DSS_DSI
510 dsi_uninit_platform_driver,
511#endif
531#ifdef CONFIG_OMAP2_DSS_DPI 512#ifdef CONFIG_OMAP2_DSS_DPI
532 dpi_uninit_platform_driver, 513 dpi_uninit_platform_driver,
533#endif 514#endif
@@ -540,9 +521,6 @@ static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = {
540#ifdef CONFIG_OMAP2_DSS_VENC 521#ifdef CONFIG_OMAP2_DSS_VENC
541 venc_uninit_platform_driver, 522 venc_uninit_platform_driver,
542#endif 523#endif
543#ifdef CONFIG_OMAP2_DSS_DSI
544 dsi_uninit_platform_driver,
545#endif
546#ifdef CONFIG_OMAP4_DSS_HDMI 524#ifdef CONFIG_OMAP4_DSS_HDMI
547 hdmi_uninit_platform_driver, 525 hdmi_uninit_platform_driver,
548#endif 526#endif
diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/omap2/dss/dispc-compat.c
new file mode 100644
index 000000000000..928884c9a0a9
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc-compat.c
@@ -0,0 +1,667 @@
1/*
2 * Copyright (C) 2012 Texas Instruments
3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#define DSS_SUBSYS_NAME "APPLY"
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/spinlock.h>
24#include <linux/jiffies.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/seq_file.h>
28
29#include <video/omapdss.h>
30
31#include "dss.h"
32#include "dss_features.h"
33#include "dispc-compat.h"
34
35#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
36 DISPC_IRQ_OCP_ERR | \
37 DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
38 DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
39 DISPC_IRQ_SYNC_LOST | \
40 DISPC_IRQ_SYNC_LOST_DIGIT)
41
42#define DISPC_MAX_NR_ISRS 8
43
44struct omap_dispc_isr_data {
45 omap_dispc_isr_t isr;
46 void *arg;
47 u32 mask;
48};
49
50struct dispc_irq_stats {
51 unsigned long last_reset;
52 unsigned irq_count;
53 unsigned irqs[32];
54};
55
56static struct {
57 spinlock_t irq_lock;
58 u32 irq_error_mask;
59 struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
60 u32 error_irqs;
61 struct work_struct error_work;
62
63#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
64 spinlock_t irq_stats_lock;
65 struct dispc_irq_stats irq_stats;
66#endif
67} dispc_compat;
68
69
70#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
71static void dispc_dump_irqs(struct seq_file *s)
72{
73 unsigned long flags;
74 struct dispc_irq_stats stats;
75
76 spin_lock_irqsave(&dispc_compat.irq_stats_lock, flags);
77
78 stats = dispc_compat.irq_stats;
79 memset(&dispc_compat.irq_stats, 0, sizeof(dispc_compat.irq_stats));
80 dispc_compat.irq_stats.last_reset = jiffies;
81
82 spin_unlock_irqrestore(&dispc_compat.irq_stats_lock, flags);
83
84 seq_printf(s, "period %u ms\n",
85 jiffies_to_msecs(jiffies - stats.last_reset));
86
87 seq_printf(s, "irqs %d\n", stats.irq_count);
88#define PIS(x) \
89 seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
90
91 PIS(FRAMEDONE);
92 PIS(VSYNC);
93 PIS(EVSYNC_EVEN);
94 PIS(EVSYNC_ODD);
95 PIS(ACBIAS_COUNT_STAT);
96 PIS(PROG_LINE_NUM);
97 PIS(GFX_FIFO_UNDERFLOW);
98 PIS(GFX_END_WIN);
99 PIS(PAL_GAMMA_MASK);
100 PIS(OCP_ERR);
101 PIS(VID1_FIFO_UNDERFLOW);
102 PIS(VID1_END_WIN);
103 PIS(VID2_FIFO_UNDERFLOW);
104 PIS(VID2_END_WIN);
105 if (dss_feat_get_num_ovls() > 3) {
106 PIS(VID3_FIFO_UNDERFLOW);
107 PIS(VID3_END_WIN);
108 }
109 PIS(SYNC_LOST);
110 PIS(SYNC_LOST_DIGIT);
111 PIS(WAKEUP);
112 if (dss_has_feature(FEAT_MGR_LCD2)) {
113 PIS(FRAMEDONE2);
114 PIS(VSYNC2);
115 PIS(ACBIAS_COUNT_STAT2);
116 PIS(SYNC_LOST2);
117 }
118 if (dss_has_feature(FEAT_MGR_LCD3)) {
119 PIS(FRAMEDONE3);
120 PIS(VSYNC3);
121 PIS(ACBIAS_COUNT_STAT3);
122 PIS(SYNC_LOST3);
123 }
124#undef PIS
125}
126#endif
127
128/* dispc.irq_lock has to be locked by the caller */
129static void _omap_dispc_set_irqs(void)
130{
131 u32 mask;
132 int i;
133 struct omap_dispc_isr_data *isr_data;
134
135 mask = dispc_compat.irq_error_mask;
136
137 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
138 isr_data = &dispc_compat.registered_isr[i];
139
140 if (isr_data->isr == NULL)
141 continue;
142
143 mask |= isr_data->mask;
144 }
145
146 dispc_write_irqenable(mask);
147}
148
149int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
150{
151 int i;
152 int ret;
153 unsigned long flags;
154 struct omap_dispc_isr_data *isr_data;
155
156 if (isr == NULL)
157 return -EINVAL;
158
159 spin_lock_irqsave(&dispc_compat.irq_lock, flags);
160
161 /* check for duplicate entry */
162 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
163 isr_data = &dispc_compat.registered_isr[i];
164 if (isr_data->isr == isr && isr_data->arg == arg &&
165 isr_data->mask == mask) {
166 ret = -EINVAL;
167 goto err;
168 }
169 }
170
171 isr_data = NULL;
172 ret = -EBUSY;
173
174 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
175 isr_data = &dispc_compat.registered_isr[i];
176
177 if (isr_data->isr != NULL)
178 continue;
179
180 isr_data->isr = isr;
181 isr_data->arg = arg;
182 isr_data->mask = mask;
183 ret = 0;
184
185 break;
186 }
187
188 if (ret)
189 goto err;
190
191 _omap_dispc_set_irqs();
192
193 spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
194
195 return 0;
196err:
197 spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
198
199 return ret;
200}
201EXPORT_SYMBOL(omap_dispc_register_isr);
202
203int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
204{
205 int i;
206 unsigned long flags;
207 int ret = -EINVAL;
208 struct omap_dispc_isr_data *isr_data;
209
210 spin_lock_irqsave(&dispc_compat.irq_lock, flags);
211
212 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
213 isr_data = &dispc_compat.registered_isr[i];
214 if (isr_data->isr != isr || isr_data->arg != arg ||
215 isr_data->mask != mask)
216 continue;
217
218 /* found the correct isr */
219
220 isr_data->isr = NULL;
221 isr_data->arg = NULL;
222 isr_data->mask = 0;
223
224 ret = 0;
225 break;
226 }
227
228 if (ret == 0)
229 _omap_dispc_set_irqs();
230
231 spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
232
233 return ret;
234}
235EXPORT_SYMBOL(omap_dispc_unregister_isr);
236
237static void print_irq_status(u32 status)
238{
239 if ((status & dispc_compat.irq_error_mask) == 0)
240 return;
241
242#define PIS(x) (status & DISPC_IRQ_##x) ? (#x " ") : ""
243
244 pr_debug("DISPC IRQ: 0x%x: %s%s%s%s%s%s%s%s%s\n",
245 status,
246 PIS(OCP_ERR),
247 PIS(GFX_FIFO_UNDERFLOW),
248 PIS(VID1_FIFO_UNDERFLOW),
249 PIS(VID2_FIFO_UNDERFLOW),
250 dss_feat_get_num_ovls() > 3 ? PIS(VID3_FIFO_UNDERFLOW) : "",
251 PIS(SYNC_LOST),
252 PIS(SYNC_LOST_DIGIT),
253 dss_has_feature(FEAT_MGR_LCD2) ? PIS(SYNC_LOST2) : "",
254 dss_has_feature(FEAT_MGR_LCD3) ? PIS(SYNC_LOST3) : "");
255#undef PIS
256}
257
258/* Called from dss.c. Note that we don't touch clocks here,
259 * but we presume they are on because we got an IRQ. However,
260 * an irq handler may turn the clocks off, so we may not have
261 * clock later in the function. */
262static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
263{
264 int i;
265 u32 irqstatus, irqenable;
266 u32 handledirqs = 0;
267 u32 unhandled_errors;
268 struct omap_dispc_isr_data *isr_data;
269 struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
270
271 spin_lock(&dispc_compat.irq_lock);
272
273 irqstatus = dispc_read_irqstatus();
274 irqenable = dispc_read_irqenable();
275
276 /* IRQ is not for us */
277 if (!(irqstatus & irqenable)) {
278 spin_unlock(&dispc_compat.irq_lock);
279 return IRQ_NONE;
280 }
281
282#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
283 spin_lock(&dispc_compat.irq_stats_lock);
284 dispc_compat.irq_stats.irq_count++;
285 dss_collect_irq_stats(irqstatus, dispc_compat.irq_stats.irqs);
286 spin_unlock(&dispc_compat.irq_stats_lock);
287#endif
288
289 print_irq_status(irqstatus);
290
291 /* Ack the interrupt. Do it here before clocks are possibly turned
292 * off */
293 dispc_clear_irqstatus(irqstatus);
294 /* flush posted write */
295 dispc_read_irqstatus();
296
297 /* make a copy and unlock, so that isrs can unregister
298 * themselves */
299 memcpy(registered_isr, dispc_compat.registered_isr,
300 sizeof(registered_isr));
301
302 spin_unlock(&dispc_compat.irq_lock);
303
304 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
305 isr_data = &registered_isr[i];
306
307 if (!isr_data->isr)
308 continue;
309
310 if (isr_data->mask & irqstatus) {
311 isr_data->isr(isr_data->arg, irqstatus);
312 handledirqs |= isr_data->mask;
313 }
314 }
315
316 spin_lock(&dispc_compat.irq_lock);
317
318 unhandled_errors = irqstatus & ~handledirqs & dispc_compat.irq_error_mask;
319
320 if (unhandled_errors) {
321 dispc_compat.error_irqs |= unhandled_errors;
322
323 dispc_compat.irq_error_mask &= ~unhandled_errors;
324 _omap_dispc_set_irqs();
325
326 schedule_work(&dispc_compat.error_work);
327 }
328
329 spin_unlock(&dispc_compat.irq_lock);
330
331 return IRQ_HANDLED;
332}
333
334static void dispc_error_worker(struct work_struct *work)
335{
336 int i;
337 u32 errors;
338 unsigned long flags;
339 static const unsigned fifo_underflow_bits[] = {
340 DISPC_IRQ_GFX_FIFO_UNDERFLOW,
341 DISPC_IRQ_VID1_FIFO_UNDERFLOW,
342 DISPC_IRQ_VID2_FIFO_UNDERFLOW,
343 DISPC_IRQ_VID3_FIFO_UNDERFLOW,
344 };
345
346 spin_lock_irqsave(&dispc_compat.irq_lock, flags);
347 errors = dispc_compat.error_irqs;
348 dispc_compat.error_irqs = 0;
349 spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
350
351 dispc_runtime_get();
352
353 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
354 struct omap_overlay *ovl;
355 unsigned bit;
356
357 ovl = omap_dss_get_overlay(i);
358 bit = fifo_underflow_bits[i];
359
360 if (bit & errors) {
361 DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
362 ovl->name);
363 dispc_ovl_enable(ovl->id, false);
364 dispc_mgr_go(ovl->manager->id);
365 msleep(50);
366 }
367 }
368
369 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
370 struct omap_overlay_manager *mgr;
371 unsigned bit;
372
373 mgr = omap_dss_get_overlay_manager(i);
374 bit = dispc_mgr_get_sync_lost_irq(i);
375
376 if (bit & errors) {
377 int j;
378
379 DSSERR("SYNC_LOST on channel %s, restarting the output "
380 "with video overlays disabled\n",
381 mgr->name);
382
383 dss_mgr_disable(mgr);
384
385 for (j = 0; j < omap_dss_get_num_overlays(); ++j) {
386 struct omap_overlay *ovl;
387 ovl = omap_dss_get_overlay(j);
388
389 if (ovl->id != OMAP_DSS_GFX &&
390 ovl->manager == mgr)
391 ovl->disable(ovl);
392 }
393
394 dss_mgr_enable(mgr);
395 }
396 }
397
398 if (errors & DISPC_IRQ_OCP_ERR) {
399 DSSERR("OCP_ERR\n");
400 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
401 struct omap_overlay_manager *mgr;
402
403 mgr = omap_dss_get_overlay_manager(i);
404 dss_mgr_disable(mgr);
405 }
406 }
407
408 spin_lock_irqsave(&dispc_compat.irq_lock, flags);
409 dispc_compat.irq_error_mask |= errors;
410 _omap_dispc_set_irqs();
411 spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
412
413 dispc_runtime_put();
414}
415
416int dss_dispc_initialize_irq(void)
417{
418 int r;
419
420#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
421 spin_lock_init(&dispc_compat.irq_stats_lock);
422 dispc_compat.irq_stats.last_reset = jiffies;
423 dss_debugfs_create_file("dispc_irq", dispc_dump_irqs);
424#endif
425
426 spin_lock_init(&dispc_compat.irq_lock);
427
428 memset(dispc_compat.registered_isr, 0,
429 sizeof(dispc_compat.registered_isr));
430
431 dispc_compat.irq_error_mask = DISPC_IRQ_MASK_ERROR;
432 if (dss_has_feature(FEAT_MGR_LCD2))
433 dispc_compat.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
434 if (dss_has_feature(FEAT_MGR_LCD3))
435 dispc_compat.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
436 if (dss_feat_get_num_ovls() > 3)
437 dispc_compat.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
438
439 /*
440 * there's SYNC_LOST_DIGIT waiting after enabling the DSS,
441 * so clear it
442 */
443 dispc_clear_irqstatus(dispc_read_irqstatus());
444
445 INIT_WORK(&dispc_compat.error_work, dispc_error_worker);
446
447 _omap_dispc_set_irqs();
448
449 r = dispc_request_irq(omap_dispc_irq_handler, &dispc_compat);
450 if (r) {
451 DSSERR("dispc_request_irq failed\n");
452 return r;
453 }
454
455 return 0;
456}
457
458void dss_dispc_uninitialize_irq(void)
459{
460 dispc_free_irq(&dispc_compat);
461}
462
463static void dispc_mgr_disable_isr(void *data, u32 mask)
464{
465 struct completion *compl = data;
466 complete(compl);
467}
468
469static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
470{
471 dispc_mgr_enable(channel, true);
472}
473
474static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
475{
476 DECLARE_COMPLETION_ONSTACK(framedone_compl);
477 int r;
478 u32 irq;
479
480 if (dispc_mgr_is_enabled(channel) == false)
481 return;
482
483 /*
484 * When we disable LCD output, we need to wait for FRAMEDONE to know
485 * that DISPC has finished with the LCD output.
486 */
487
488 irq = dispc_mgr_get_framedone_irq(channel);
489
490 r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
491 irq);
492 if (r)
493 DSSERR("failed to register FRAMEDONE isr\n");
494
495 dispc_mgr_enable(channel, false);
496
497 /* if we couldn't register for framedone, just sleep and exit */
498 if (r) {
499 msleep(100);
500 return;
501 }
502
503 if (!wait_for_completion_timeout(&framedone_compl,
504 msecs_to_jiffies(100)))
505 DSSERR("timeout waiting for FRAME DONE\n");
506
507 r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
508 irq);
509 if (r)
510 DSSERR("failed to unregister FRAMEDONE isr\n");
511}
512
513static void dispc_digit_out_enable_isr(void *data, u32 mask)
514{
515 struct completion *compl = data;
516
517 /* ignore any sync lost interrupts */
518 if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
519 complete(compl);
520}
521
522static void dispc_mgr_enable_digit_out(void)
523{
524 DECLARE_COMPLETION_ONSTACK(vsync_compl);
525 int r;
526 u32 irq_mask;
527
528 if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == true)
529 return;
530
531 /*
532 * Digit output produces some sync lost interrupts during the first
533 * frame when enabling. Those need to be ignored, so we register for the
534 * sync lost irq to prevent the error handler from triggering.
535 */
536
537 irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
538 dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
539
540 r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
541 irq_mask);
542 if (r) {
543 DSSERR("failed to register %x isr\n", irq_mask);
544 return;
545 }
546
547 dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true);
548
549 /* wait for the first evsync */
550 if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
551 DSSERR("timeout waiting for digit out to start\n");
552
553 r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
554 irq_mask);
555 if (r)
556 DSSERR("failed to unregister %x isr\n", irq_mask);
557}
558
559static void dispc_mgr_disable_digit_out(void)
560{
561 DECLARE_COMPLETION_ONSTACK(framedone_compl);
562 int r, i;
563 u32 irq_mask;
564 int num_irqs;
565
566 if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == false)
567 return;
568
569 /*
570 * When we disable the digit output, we need to wait for FRAMEDONE to
571 * know that DISPC has finished with the output.
572 */
573
574 irq_mask = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_DIGIT);
575 num_irqs = 1;
576
577 if (!irq_mask) {
578 /*
579 * omap 2/3 don't have framedone irq for TV, so we need to use
580 * vsyncs for this.
581 */
582
583 irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
584 /*
585 * We need to wait for both even and odd vsyncs. Note that this
586 * is not totally reliable, as we could get a vsync interrupt
587 * before we disable the output, which leads to timeout in the
588 * wait_for_completion.
589 */
590 num_irqs = 2;
591 }
592
593 r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
594 irq_mask);
595 if (r)
596 DSSERR("failed to register %x isr\n", irq_mask);
597
598 dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false);
599
600 /* if we couldn't register the irq, just sleep and exit */
601 if (r) {
602 msleep(100);
603 return;
604 }
605
606 for (i = 0; i < num_irqs; ++i) {
607 if (!wait_for_completion_timeout(&framedone_compl,
608 msecs_to_jiffies(100)))
609 DSSERR("timeout waiting for digit out to stop\n");
610 }
611
612 r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
613 irq_mask);
614 if (r)
615 DSSERR("failed to unregister %x isr\n", irq_mask);
616}
617
618void dispc_mgr_enable_sync(enum omap_channel channel)
619{
620 if (dss_mgr_is_lcd(channel))
621 dispc_mgr_enable_lcd_out(channel);
622 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
623 dispc_mgr_enable_digit_out();
624 else
625 WARN_ON(1);
626}
627
628void dispc_mgr_disable_sync(enum omap_channel channel)
629{
630 if (dss_mgr_is_lcd(channel))
631 dispc_mgr_disable_lcd_out(channel);
632 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
633 dispc_mgr_disable_digit_out();
634 else
635 WARN_ON(1);
636}
637
638int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
639 unsigned long timeout)
640{
641 void dispc_irq_wait_handler(void *data, u32 mask)
642 {
643 complete((struct completion *)data);
644 }
645
646 int r;
647 DECLARE_COMPLETION_ONSTACK(completion);
648
649 r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
650 irqmask);
651
652 if (r)
653 return r;
654
655 timeout = wait_for_completion_interruptible_timeout(&completion,
656 timeout);
657
658 omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
659
660 if (timeout == 0)
661 return -ETIMEDOUT;
662
663 if (timeout == -ERESTARTSYS)
664 return -ERESTARTSYS;
665
666 return 0;
667}
diff --git a/drivers/video/omap2/dss/dispc-compat.h b/drivers/video/omap2/dss/dispc-compat.h
new file mode 100644
index 000000000000..14a69b3d4fb0
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc-compat.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2012 Texas Instruments
3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef __OMAP2_DSS_DISPC_COMPAT_H
19#define __OMAP2_DSS_DISPC_COMPAT_H
20
21void dispc_mgr_enable_sync(enum omap_channel channel);
22void dispc_mgr_disable_sync(enum omap_channel channel);
23
24int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
25 unsigned long timeout);
26
27int dss_dispc_initialize_irq(void);
28void dss_dispc_uninitialize_irq(void);
29
30#endif
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a5ab354f267a..05ff2b91d9e8 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -33,9 +33,9 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/workqueue.h> 34#include <linux/workqueue.h>
35#include <linux/hardirq.h> 35#include <linux/hardirq.h>
36#include <linux/interrupt.h>
37#include <linux/platform_device.h> 36#include <linux/platform_device.h>
38#include <linux/pm_runtime.h> 37#include <linux/pm_runtime.h>
38#include <linux/sizes.h>
39 39
40#include <video/omapdss.h> 40#include <video/omapdss.h>
41 41
@@ -46,21 +46,6 @@
46/* DISPC */ 46/* DISPC */
47#define DISPC_SZ_REGS SZ_4K 47#define DISPC_SZ_REGS SZ_4K
48 48
49#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
50 DISPC_IRQ_OCP_ERR | \
51 DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
52 DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
53 DISPC_IRQ_SYNC_LOST | \
54 DISPC_IRQ_SYNC_LOST_DIGIT)
55
56#define DISPC_MAX_NR_ISRS 8
57
58struct omap_dispc_isr_data {
59 omap_dispc_isr_t isr;
60 void *arg;
61 u32 mask;
62};
63
64enum omap_burst_size { 49enum omap_burst_size {
65 BURST_SIZE_X2 = 0, 50 BURST_SIZE_X2 = 0,
66 BURST_SIZE_X4 = 1, 51 BURST_SIZE_X4 = 1,
@@ -73,12 +58,6 @@ enum omap_burst_size {
73#define REG_FLD_MOD(idx, val, start, end) \ 58#define REG_FLD_MOD(idx, val, start, end) \
74 dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end)) 59 dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
75 60
76struct dispc_irq_stats {
77 unsigned long last_reset;
78 unsigned irq_count;
79 unsigned irqs[32];
80};
81
82struct dispc_features { 61struct dispc_features {
83 u8 sw_start; 62 u8 sw_start;
84 u8 fp_start; 63 u8 fp_start;
@@ -86,19 +65,26 @@ struct dispc_features {
86 u16 sw_max; 65 u16 sw_max;
87 u16 vp_max; 66 u16 vp_max;
88 u16 hp_max; 67 u16 hp_max;
89 int (*calc_scaling) (enum omap_plane plane, 68 u8 mgr_width_start;
69 u8 mgr_height_start;
70 u16 mgr_width_max;
71 u16 mgr_height_max;
72 int (*calc_scaling) (unsigned long pclk, unsigned long lclk,
90 const struct omap_video_timings *mgr_timings, 73 const struct omap_video_timings *mgr_timings,
91 u16 width, u16 height, u16 out_width, u16 out_height, 74 u16 width, u16 height, u16 out_width, u16 out_height,
92 enum omap_color_mode color_mode, bool *five_taps, 75 enum omap_color_mode color_mode, bool *five_taps,
93 int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, 76 int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
94 u16 pos_x, unsigned long *core_clk, bool mem_to_mem); 77 u16 pos_x, unsigned long *core_clk, bool mem_to_mem);
95 unsigned long (*calc_core_clk) (enum omap_plane plane, 78 unsigned long (*calc_core_clk) (unsigned long pclk,
96 u16 width, u16 height, u16 out_width, u16 out_height, 79 u16 width, u16 height, u16 out_width, u16 out_height,
97 bool mem_to_mem); 80 bool mem_to_mem);
98 u8 num_fifos; 81 u8 num_fifos;
99 82
100 /* swap GFX & WB fifos */ 83 /* swap GFX & WB fifos */
101 bool gfx_fifo_workaround:1; 84 bool gfx_fifo_workaround:1;
85
86 /* no DISPC_IRQ_FRAMEDONETV on this SoC */
87 bool no_framedone_tv:1;
102}; 88};
103 89
104#define DISPC_MAX_NR_FIFOS 5 90#define DISPC_MAX_NR_FIFOS 5
@@ -110,27 +96,15 @@ static struct {
110 int ctx_loss_cnt; 96 int ctx_loss_cnt;
111 97
112 int irq; 98 int irq;
113 struct clk *dss_clk;
114 99
115 u32 fifo_size[DISPC_MAX_NR_FIFOS]; 100 u32 fifo_size[DISPC_MAX_NR_FIFOS];
116 /* maps which plane is using a fifo. fifo-id -> plane-id */ 101 /* maps which plane is using a fifo. fifo-id -> plane-id */
117 int fifo_assignment[DISPC_MAX_NR_FIFOS]; 102 int fifo_assignment[DISPC_MAX_NR_FIFOS];
118 103
119 spinlock_t irq_lock;
120 u32 irq_error_mask;
121 struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
122 u32 error_irqs;
123 struct work_struct error_work;
124
125 bool ctx_valid; 104 bool ctx_valid;
126 u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; 105 u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
127 106
128 const struct dispc_features *feat; 107 const struct dispc_features *feat;
129
130#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
131 spinlock_t irq_stats_lock;
132 struct dispc_irq_stats irq_stats;
133#endif
134} dispc; 108} dispc;
135 109
136enum omap_color_component { 110enum omap_color_component {
@@ -186,7 +160,7 @@ static const struct {
186 [OMAP_DSS_CHANNEL_DIGIT] = { 160 [OMAP_DSS_CHANNEL_DIGIT] = {
187 .name = "DIGIT", 161 .name = "DIGIT",
188 .vsync_irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN, 162 .vsync_irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN,
189 .framedone_irq = 0, 163 .framedone_irq = DISPC_IRQ_FRAMEDONETV,
190 .sync_lost_irq = DISPC_IRQ_SYNC_LOST_DIGIT, 164 .sync_lost_irq = DISPC_IRQ_SYNC_LOST_DIGIT,
191 .reg_desc = { 165 .reg_desc = {
192 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 1, 1 }, 166 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 1, 1 },
@@ -241,7 +215,6 @@ struct color_conv_coef {
241 int full_range; 215 int full_range;
242}; 216};
243 217
244static void _omap_dispc_set_irqs(void);
245static unsigned long dispc_plane_pclk_rate(enum omap_plane plane); 218static unsigned long dispc_plane_pclk_rate(enum omap_plane plane);
246static unsigned long dispc_plane_lclk_rate(enum omap_plane plane); 219static unsigned long dispc_plane_lclk_rate(enum omap_plane plane);
247 220
@@ -374,7 +347,7 @@ static void dispc_save_context(void)
374 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 347 if (dss_has_feature(FEAT_CORE_CLK_DIV))
375 SR(DIVISOR); 348 SR(DIVISOR);
376 349
377 dispc.ctx_loss_cnt = dss_get_ctx_loss_count(&dispc.pdev->dev); 350 dispc.ctx_loss_cnt = dss_get_ctx_loss_count();
378 dispc.ctx_valid = true; 351 dispc.ctx_valid = true;
379 352
380 DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt); 353 DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt);
@@ -389,7 +362,7 @@ static void dispc_restore_context(void)
389 if (!dispc.ctx_valid) 362 if (!dispc.ctx_valid)
390 return; 363 return;
391 364
392 ctx = dss_get_ctx_loss_count(&dispc.pdev->dev); 365 ctx = dss_get_ctx_loss_count();
393 366
394 if (ctx >= 0 && ctx == dispc.ctx_loss_cnt) 367 if (ctx >= 0 && ctx == dispc.ctx_loss_cnt)
395 return; 368 return;
@@ -496,7 +469,7 @@ static void dispc_restore_context(void)
496 if (dss_has_feature(FEAT_MGR_LCD3)) 469 if (dss_has_feature(FEAT_MGR_LCD3))
497 RR(CONTROL3); 470 RR(CONTROL3);
498 /* clear spurious SYNC_LOST_DIGIT interrupts */ 471 /* clear spurious SYNC_LOST_DIGIT interrupts */
499 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 472 dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT);
500 473
501 /* 474 /*
502 * enable last so IRQs won't trigger before 475 * enable last so IRQs won't trigger before
@@ -520,6 +493,7 @@ int dispc_runtime_get(void)
520 WARN_ON(r < 0); 493 WARN_ON(r < 0);
521 return r < 0 ? r : 0; 494 return r < 0 ? r : 0;
522} 495}
496EXPORT_SYMBOL(dispc_runtime_get);
523 497
524void dispc_runtime_put(void) 498void dispc_runtime_put(void)
525{ 499{
@@ -530,16 +504,28 @@ void dispc_runtime_put(void)
530 r = pm_runtime_put_sync(&dispc.pdev->dev); 504 r = pm_runtime_put_sync(&dispc.pdev->dev);
531 WARN_ON(r < 0 && r != -ENOSYS); 505 WARN_ON(r < 0 && r != -ENOSYS);
532} 506}
507EXPORT_SYMBOL(dispc_runtime_put);
533 508
534u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) 509u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
535{ 510{
536 return mgr_desc[channel].vsync_irq; 511 return mgr_desc[channel].vsync_irq;
537} 512}
513EXPORT_SYMBOL(dispc_mgr_get_vsync_irq);
538 514
539u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) 515u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
540{ 516{
517 if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv)
518 return 0;
519
541 return mgr_desc[channel].framedone_irq; 520 return mgr_desc[channel].framedone_irq;
542} 521}
522EXPORT_SYMBOL(dispc_mgr_get_framedone_irq);
523
524u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel)
525{
526 return mgr_desc[channel].sync_lost_irq;
527}
528EXPORT_SYMBOL(dispc_mgr_get_sync_lost_irq);
543 529
544u32 dispc_wb_get_framedone_irq(void) 530u32 dispc_wb_get_framedone_irq(void)
545{ 531{
@@ -550,28 +536,18 @@ bool dispc_mgr_go_busy(enum omap_channel channel)
550{ 536{
551 return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; 537 return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
552} 538}
539EXPORT_SYMBOL(dispc_mgr_go_busy);
553 540
554void dispc_mgr_go(enum omap_channel channel) 541void dispc_mgr_go(enum omap_channel channel)
555{ 542{
556 bool enable_bit, go_bit; 543 WARN_ON(dispc_mgr_is_enabled(channel) == false);
557 544 WARN_ON(dispc_mgr_go_busy(channel));
558 /* if the channel is not enabled, we don't need GO */
559 enable_bit = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE) == 1;
560
561 if (!enable_bit)
562 return;
563
564 go_bit = mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
565
566 if (go_bit) {
567 DSSERR("GO bit not down for channel %d\n", channel);
568 return;
569 }
570 545
571 DSSDBG("GO %s\n", mgr_desc[channel].name); 546 DSSDBG("GO %s\n", mgr_desc[channel].name);
572 547
573 mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); 548 mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
574} 549}
550EXPORT_SYMBOL(dispc_mgr_go);
575 551
576bool dispc_wb_go_busy(void) 552bool dispc_wb_go_busy(void)
577{ 553{
@@ -975,6 +951,7 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
975 } 951 }
976 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); 952 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
977} 953}
954EXPORT_SYMBOL(dispc_ovl_set_channel_out);
978 955
979static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) 956static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
980{ 957{
@@ -1040,7 +1017,7 @@ static void dispc_configure_burst_sizes(void)
1040 const int burst_size = BURST_SIZE_X8; 1017 const int burst_size = BURST_SIZE_X8;
1041 1018
1042 /* Configure burst size always to maximum size */ 1019 /* Configure burst size always to maximum size */
1043 for (i = 0; i < omap_dss_get_num_overlays(); ++i) 1020 for (i = 0; i < dss_feat_get_num_ovls(); ++i)
1044 dispc_ovl_set_burst_size(i, burst_size); 1021 dispc_ovl_set_burst_size(i, burst_size);
1045} 1022}
1046 1023
@@ -1074,7 +1051,7 @@ static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
1074} 1051}
1075 1052
1076static void dispc_mgr_set_cpr_coef(enum omap_channel channel, 1053static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
1077 struct omap_dss_cpr_coefs *coefs) 1054 const struct omap_dss_cpr_coefs *coefs)
1078{ 1055{
1079 u32 coef_r, coef_g, coef_b; 1056 u32 coef_r, coef_g, coef_b;
1080 1057
@@ -1122,7 +1099,9 @@ static void dispc_mgr_set_size(enum omap_channel channel, u16 width,
1122{ 1099{
1123 u32 val; 1100 u32 val;
1124 1101
1125 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1102 val = FLD_VAL(height - 1, dispc.feat->mgr_height_start, 16) |
1103 FLD_VAL(width - 1, dispc.feat->mgr_width_start, 0);
1104
1126 dispc_write_reg(DISPC_SIZE_MGR(channel), val); 1105 dispc_write_reg(DISPC_SIZE_MGR(channel), val);
1127} 1106}
1128 1107
@@ -1244,7 +1223,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
1244 1223
1245 if (use_fifomerge) { 1224 if (use_fifomerge) {
1246 total_fifo_size = 0; 1225 total_fifo_size = 0;
1247 for (i = 0; i < omap_dss_get_num_overlays(); ++i) 1226 for (i = 0; i < dss_feat_get_num_ovls(); ++i)
1248 total_fifo_size += dispc_ovl_get_fifo_size(i); 1227 total_fifo_size += dispc_ovl_get_fifo_size(i);
1249 } else { 1228 } else {
1250 total_fifo_size = ovl_fifo_size; 1229 total_fifo_size = ovl_fifo_size;
@@ -1989,16 +1968,14 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
1989 * This function is used to avoid synclosts in OMAP3, because of some 1968 * This function is used to avoid synclosts in OMAP3, because of some
1990 * undocumented horizontal position and timing related limitations. 1969 * undocumented horizontal position and timing related limitations.
1991 */ 1970 */
1992static int check_horiz_timing_omap3(enum omap_plane plane, 1971static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,
1993 const struct omap_video_timings *t, u16 pos_x, 1972 const struct omap_video_timings *t, u16 pos_x,
1994 u16 width, u16 height, u16 out_width, u16 out_height) 1973 u16 width, u16 height, u16 out_width, u16 out_height)
1995{ 1974{
1996 int DS = DIV_ROUND_UP(height, out_height); 1975 const int ds = DIV_ROUND_UP(height, out_height);
1997 unsigned long nonactive; 1976 unsigned long nonactive;
1998 static const u8 limits[3] = { 8, 10, 20 }; 1977 static const u8 limits[3] = { 8, 10, 20 };
1999 u64 val, blank; 1978 u64 val, blank;
2000 unsigned long pclk = dispc_plane_pclk_rate(plane);
2001 unsigned long lclk = dispc_plane_lclk_rate(plane);
2002 int i; 1979 int i;
2003 1980
2004 nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; 1981 nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
@@ -2020,8 +1997,8 @@ static int check_horiz_timing_omap3(enum omap_plane plane,
2020 */ 1997 */
2021 val = div_u64((u64)(nonactive - pos_x) * lclk, pclk); 1998 val = div_u64((u64)(nonactive - pos_x) * lclk, pclk);
2022 DSSDBG("(nonactive - pos_x) * pcd = %llu max(0, DS - 2) * width = %d\n", 1999 DSSDBG("(nonactive - pos_x) * pcd = %llu max(0, DS - 2) * width = %d\n",
2023 val, max(0, DS - 2) * width); 2000 val, max(0, ds - 2) * width);
2024 if (val < max(0, DS - 2) * width) 2001 if (val < max(0, ds - 2) * width)
2025 return -EINVAL; 2002 return -EINVAL;
2026 2003
2027 /* 2004 /*
@@ -2031,21 +2008,20 @@ static int check_horiz_timing_omap3(enum omap_plane plane,
2031 */ 2008 */
2032 val = div_u64((u64)nonactive * lclk, pclk); 2009 val = div_u64((u64)nonactive * lclk, pclk);
2033 DSSDBG("nonactive * pcd = %llu, max(0, DS - 1) * width = %d\n", 2010 DSSDBG("nonactive * pcd = %llu, max(0, DS - 1) * width = %d\n",
2034 val, max(0, DS - 1) * width); 2011 val, max(0, ds - 1) * width);
2035 if (val < max(0, DS - 1) * width) 2012 if (val < max(0, ds - 1) * width)
2036 return -EINVAL; 2013 return -EINVAL;
2037 2014
2038 return 0; 2015 return 0;
2039} 2016}
2040 2017
2041static unsigned long calc_core_clk_five_taps(enum omap_plane plane, 2018static unsigned long calc_core_clk_five_taps(unsigned long pclk,
2042 const struct omap_video_timings *mgr_timings, u16 width, 2019 const struct omap_video_timings *mgr_timings, u16 width,
2043 u16 height, u16 out_width, u16 out_height, 2020 u16 height, u16 out_width, u16 out_height,
2044 enum omap_color_mode color_mode) 2021 enum omap_color_mode color_mode)
2045{ 2022{
2046 u32 core_clk = 0; 2023 u32 core_clk = 0;
2047 u64 tmp; 2024 u64 tmp;
2048 unsigned long pclk = dispc_plane_pclk_rate(plane);
2049 2025
2050 if (height <= out_height && width <= out_width) 2026 if (height <= out_height && width <= out_width)
2051 return (unsigned long) pclk; 2027 return (unsigned long) pclk;
@@ -2079,22 +2055,19 @@ static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
2079 return core_clk; 2055 return core_clk;
2080} 2056}
2081 2057
2082static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, 2058static unsigned long calc_core_clk_24xx(unsigned long pclk, u16 width,
2083 u16 height, u16 out_width, u16 out_height, bool mem_to_mem) 2059 u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
2084{ 2060{
2085 unsigned long pclk = dispc_plane_pclk_rate(plane);
2086
2087 if (height > out_height && width > out_width) 2061 if (height > out_height && width > out_width)
2088 return pclk * 4; 2062 return pclk * 4;
2089 else 2063 else
2090 return pclk * 2; 2064 return pclk * 2;
2091} 2065}
2092 2066
2093static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, 2067static unsigned long calc_core_clk_34xx(unsigned long pclk, u16 width,
2094 u16 height, u16 out_width, u16 out_height, bool mem_to_mem) 2068 u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
2095{ 2069{
2096 unsigned int hf, vf; 2070 unsigned int hf, vf;
2097 unsigned long pclk = dispc_plane_pclk_rate(plane);
2098 2071
2099 /* 2072 /*
2100 * FIXME how to determine the 'A' factor 2073 * FIXME how to determine the 'A' factor
@@ -2117,11 +2090,9 @@ static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
2117 return pclk * vf * hf; 2090 return pclk * vf * hf;
2118} 2091}
2119 2092
2120static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width, 2093static unsigned long calc_core_clk_44xx(unsigned long pclk, u16 width,
2121 u16 height, u16 out_width, u16 out_height, bool mem_to_mem) 2094 u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
2122{ 2095{
2123 unsigned long pclk;
2124
2125 /* 2096 /*
2126 * If the overlay/writeback is in mem to mem mode, there are no 2097 * If the overlay/writeback is in mem to mem mode, there are no
2127 * downscaling limitations with respect to pixel clock, return 1 as 2098 * downscaling limitations with respect to pixel clock, return 1 as
@@ -2131,15 +2102,13 @@ static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
2131 if (mem_to_mem) 2102 if (mem_to_mem)
2132 return 1; 2103 return 1;
2133 2104
2134 pclk = dispc_plane_pclk_rate(plane);
2135
2136 if (width > out_width) 2105 if (width > out_width)
2137 return DIV_ROUND_UP(pclk, out_width) * width; 2106 return DIV_ROUND_UP(pclk, out_width) * width;
2138 else 2107 else
2139 return pclk; 2108 return pclk;
2140} 2109}
2141 2110
2142static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane, 2111static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,
2143 const struct omap_video_timings *mgr_timings, 2112 const struct omap_video_timings *mgr_timings,
2144 u16 width, u16 height, u16 out_width, u16 out_height, 2113 u16 width, u16 height, u16 out_width, u16 out_height,
2145 enum omap_color_mode color_mode, bool *five_taps, 2114 enum omap_color_mode color_mode, bool *five_taps,
@@ -2157,7 +2126,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
2157 do { 2126 do {
2158 in_height = DIV_ROUND_UP(height, *decim_y); 2127 in_height = DIV_ROUND_UP(height, *decim_y);
2159 in_width = DIV_ROUND_UP(width, *decim_x); 2128 in_width = DIV_ROUND_UP(width, *decim_x);
2160 *core_clk = dispc.feat->calc_core_clk(plane, in_width, 2129 *core_clk = dispc.feat->calc_core_clk(pclk, in_width,
2161 in_height, out_width, out_height, mem_to_mem); 2130 in_height, out_width, out_height, mem_to_mem);
2162 error = (in_width > maxsinglelinewidth || !*core_clk || 2131 error = (in_width > maxsinglelinewidth || !*core_clk ||
2163 *core_clk > dispc_core_clk_rate()); 2132 *core_clk > dispc_core_clk_rate());
@@ -2180,7 +2149,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
2180 return 0; 2149 return 0;
2181} 2150}
2182 2151
2183static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane, 2152static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
2184 const struct omap_video_timings *mgr_timings, 2153 const struct omap_video_timings *mgr_timings,
2185 u16 width, u16 height, u16 out_width, u16 out_height, 2154 u16 width, u16 height, u16 out_width, u16 out_height,
2186 enum omap_color_mode color_mode, bool *five_taps, 2155 enum omap_color_mode color_mode, bool *five_taps,
@@ -2196,10 +2165,10 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
2196 do { 2165 do {
2197 in_height = DIV_ROUND_UP(height, *decim_y); 2166 in_height = DIV_ROUND_UP(height, *decim_y);
2198 in_width = DIV_ROUND_UP(width, *decim_x); 2167 in_width = DIV_ROUND_UP(width, *decim_x);
2199 *core_clk = calc_core_clk_five_taps(plane, mgr_timings, 2168 *core_clk = calc_core_clk_five_taps(pclk, mgr_timings,
2200 in_width, in_height, out_width, out_height, color_mode); 2169 in_width, in_height, out_width, out_height, color_mode);
2201 2170
2202 error = check_horiz_timing_omap3(plane, mgr_timings, 2171 error = check_horiz_timing_omap3(pclk, lclk, mgr_timings,
2203 pos_x, in_width, in_height, out_width, 2172 pos_x, in_width, in_height, out_width,
2204 out_height); 2173 out_height);
2205 2174
@@ -2208,7 +2177,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
2208 in_height < out_height * 2) 2177 in_height < out_height * 2)
2209 *five_taps = false; 2178 *five_taps = false;
2210 if (!*five_taps) 2179 if (!*five_taps)
2211 *core_clk = dispc.feat->calc_core_clk(plane, in_width, 2180 *core_clk = dispc.feat->calc_core_clk(pclk, in_width,
2212 in_height, out_width, out_height, 2181 in_height, out_width, out_height,
2213 mem_to_mem); 2182 mem_to_mem);
2214 2183
@@ -2227,8 +2196,8 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
2227 } 2196 }
2228 } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); 2197 } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
2229 2198
2230 if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height, 2199 if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width,
2231 out_width, out_height)){ 2200 height, out_width, out_height)){
2232 DSSERR("horizontal timing too tight\n"); 2201 DSSERR("horizontal timing too tight\n");
2233 return -EINVAL; 2202 return -EINVAL;
2234 } 2203 }
@@ -2246,7 +2215,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
2246 return 0; 2215 return 0;
2247} 2216}
2248 2217
2249static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, 2218static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
2250 const struct omap_video_timings *mgr_timings, 2219 const struct omap_video_timings *mgr_timings,
2251 u16 width, u16 height, u16 out_width, u16 out_height, 2220 u16 width, u16 height, u16 out_width, u16 out_height,
2252 enum omap_color_mode color_mode, bool *five_taps, 2221 enum omap_color_mode color_mode, bool *five_taps,
@@ -2258,14 +2227,14 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
2258 u16 in_height = DIV_ROUND_UP(height, *decim_y); 2227 u16 in_height = DIV_ROUND_UP(height, *decim_y);
2259 const int maxsinglelinewidth = 2228 const int maxsinglelinewidth =
2260 dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); 2229 dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
2261 unsigned long pclk = dispc_plane_pclk_rate(plane);
2262 const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); 2230 const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
2263 2231
2264 if (mem_to_mem) 2232 if (mem_to_mem) {
2265 in_width_max = DIV_ROUND_UP(out_width, maxdownscale); 2233 in_width_max = out_width * maxdownscale;
2266 else 2234 } else {
2267 in_width_max = dispc_core_clk_rate() / 2235 in_width_max = dispc_core_clk_rate() /
2268 DIV_ROUND_UP(pclk, out_width); 2236 DIV_ROUND_UP(pclk, out_width);
2237 }
2269 2238
2270 *decim_x = DIV_ROUND_UP(width, in_width_max); 2239 *decim_x = DIV_ROUND_UP(width, in_width_max);
2271 2240
@@ -2283,12 +2252,12 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
2283 return -EINVAL; 2252 return -EINVAL;
2284 } 2253 }
2285 2254
2286 *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height, 2255 *core_clk = dispc.feat->calc_core_clk(pclk, in_width, in_height,
2287 out_width, out_height, mem_to_mem); 2256 out_width, out_height, mem_to_mem);
2288 return 0; 2257 return 0;
2289} 2258}
2290 2259
2291static int dispc_ovl_calc_scaling(enum omap_plane plane, 2260static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
2292 enum omap_overlay_caps caps, 2261 enum omap_overlay_caps caps,
2293 const struct omap_video_timings *mgr_timings, 2262 const struct omap_video_timings *mgr_timings,
2294 u16 width, u16 height, u16 out_width, u16 out_height, 2263 u16 width, u16 height, u16 out_width, u16 out_height,
@@ -2307,9 +2276,14 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
2307 if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0) 2276 if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
2308 return -EINVAL; 2277 return -EINVAL;
2309 2278
2310 *x_predecim = max_decim_limit; 2279 if (mem_to_mem) {
2311 *y_predecim = (rotation_type == OMAP_DSS_ROT_TILER && 2280 *x_predecim = *y_predecim = 1;
2312 dss_has_feature(FEAT_BURST_2D)) ? 2 : max_decim_limit; 2281 } else {
2282 *x_predecim = max_decim_limit;
2283 *y_predecim = (rotation_type == OMAP_DSS_ROT_TILER &&
2284 dss_has_feature(FEAT_BURST_2D)) ?
2285 2 : max_decim_limit;
2286 }
2313 2287
2314 if (color_mode == OMAP_DSS_COLOR_CLUT1 || 2288 if (color_mode == OMAP_DSS_COLOR_CLUT1 ||
2315 color_mode == OMAP_DSS_COLOR_CLUT2 || 2289 color_mode == OMAP_DSS_COLOR_CLUT2 ||
@@ -2330,7 +2304,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
2330 if (decim_y > *y_predecim || out_height > height * 8) 2304 if (decim_y > *y_predecim || out_height > height * 8)
2331 return -EINVAL; 2305 return -EINVAL;
2332 2306
2333 ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height, 2307 ret = dispc.feat->calc_scaling(pclk, lclk, mgr_timings, width, height,
2334 out_width, out_height, color_mode, five_taps, 2308 out_width, out_height, color_mode, five_taps,
2335 x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk, 2309 x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk,
2336 mem_to_mem); 2310 mem_to_mem);
@@ -2353,6 +2327,47 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
2353 return 0; 2327 return 0;
2354} 2328}
2355 2329
2330int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel,
2331 const struct omap_overlay_info *oi,
2332 const struct omap_video_timings *timings,
2333 int *x_predecim, int *y_predecim)
2334{
2335 enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
2336 bool five_taps = true;
2337 bool fieldmode = 0;
2338 u16 in_height = oi->height;
2339 u16 in_width = oi->width;
2340 bool ilace = timings->interlace;
2341 u16 out_width, out_height;
2342 int pos_x = oi->pos_x;
2343 unsigned long pclk = dispc_mgr_pclk_rate(channel);
2344 unsigned long lclk = dispc_mgr_lclk_rate(channel);
2345
2346 out_width = oi->out_width == 0 ? oi->width : oi->out_width;
2347 out_height = oi->out_height == 0 ? oi->height : oi->out_height;
2348
2349 if (ilace && oi->height == out_height)
2350 fieldmode = 1;
2351
2352 if (ilace) {
2353 if (fieldmode)
2354 in_height /= 2;
2355 out_height /= 2;
2356
2357 DSSDBG("adjusting for ilace: height %d, out_height %d\n",
2358 in_height, out_height);
2359 }
2360
2361 if (!dss_feat_color_mode_supported(plane, oi->color_mode))
2362 return -EINVAL;
2363
2364 return dispc_ovl_calc_scaling(pclk, lclk, caps, timings, in_width,
2365 in_height, out_width, out_height, oi->color_mode,
2366 &five_taps, x_predecim, y_predecim, pos_x,
2367 oi->rotation_type, false);
2368}
2369EXPORT_SYMBOL(dispc_ovl_check);
2370
2356static int dispc_ovl_setup_common(enum omap_plane plane, 2371static int dispc_ovl_setup_common(enum omap_plane plane,
2357 enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr, 2372 enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
2358 u16 screen_width, int pos_x, int pos_y, u16 width, u16 height, 2373 u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
@@ -2368,12 +2383,14 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
2368 unsigned offset0, offset1; 2383 unsigned offset0, offset1;
2369 s32 row_inc; 2384 s32 row_inc;
2370 s32 pix_inc; 2385 s32 pix_inc;
2371 u16 frame_height = height; 2386 u16 frame_width, frame_height;
2372 unsigned int field_offset = 0; 2387 unsigned int field_offset = 0;
2373 u16 in_height = height; 2388 u16 in_height = height;
2374 u16 in_width = width; 2389 u16 in_width = width;
2375 int x_predecim = 1, y_predecim = 1; 2390 int x_predecim = 1, y_predecim = 1;
2376 bool ilace = mgr_timings->interlace; 2391 bool ilace = mgr_timings->interlace;
2392 unsigned long pclk = dispc_plane_pclk_rate(plane);
2393 unsigned long lclk = dispc_plane_lclk_rate(plane);
2377 2394
2378 if (paddr == 0) 2395 if (paddr == 0)
2379 return -EINVAL; 2396 return -EINVAL;
@@ -2398,7 +2415,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
2398 if (!dss_feat_color_mode_supported(plane, color_mode)) 2415 if (!dss_feat_color_mode_supported(plane, color_mode))
2399 return -EINVAL; 2416 return -EINVAL;
2400 2417
2401 r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width, 2418 r = dispc_ovl_calc_scaling(pclk, lclk, caps, mgr_timings, in_width,
2402 in_height, out_width, out_height, color_mode, 2419 in_height, out_width, out_height, color_mode,
2403 &five_taps, &x_predecim, &y_predecim, pos_x, 2420 &five_taps, &x_predecim, &y_predecim, pos_x,
2404 rotation_type, mem_to_mem); 2421 rotation_type, mem_to_mem);
@@ -2436,20 +2453,28 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
2436 row_inc = 0; 2453 row_inc = 0;
2437 pix_inc = 0; 2454 pix_inc = 0;
2438 2455
2456 if (plane == OMAP_DSS_WB) {
2457 frame_width = out_width;
2458 frame_height = out_height;
2459 } else {
2460 frame_width = in_width;
2461 frame_height = height;
2462 }
2463
2439 if (rotation_type == OMAP_DSS_ROT_TILER) 2464 if (rotation_type == OMAP_DSS_ROT_TILER)
2440 calc_tiler_rotation_offset(screen_width, in_width, 2465 calc_tiler_rotation_offset(screen_width, frame_width,
2441 color_mode, fieldmode, field_offset, 2466 color_mode, fieldmode, field_offset,
2442 &offset0, &offset1, &row_inc, &pix_inc, 2467 &offset0, &offset1, &row_inc, &pix_inc,
2443 x_predecim, y_predecim); 2468 x_predecim, y_predecim);
2444 else if (rotation_type == OMAP_DSS_ROT_DMA) 2469 else if (rotation_type == OMAP_DSS_ROT_DMA)
2445 calc_dma_rotation_offset(rotation, mirror, 2470 calc_dma_rotation_offset(rotation, mirror, screen_width,
2446 screen_width, in_width, frame_height, 2471 frame_width, frame_height,
2447 color_mode, fieldmode, field_offset, 2472 color_mode, fieldmode, field_offset,
2448 &offset0, &offset1, &row_inc, &pix_inc, 2473 &offset0, &offset1, &row_inc, &pix_inc,
2449 x_predecim, y_predecim); 2474 x_predecim, y_predecim);
2450 else 2475 else
2451 calc_vrfb_rotation_offset(rotation, mirror, 2476 calc_vrfb_rotation_offset(rotation, mirror,
2452 screen_width, in_width, frame_height, 2477 screen_width, frame_width, frame_height,
2453 color_mode, fieldmode, field_offset, 2478 color_mode, fieldmode, field_offset,
2454 &offset0, &offset1, &row_inc, &pix_inc, 2479 &offset0, &offset1, &row_inc, &pix_inc,
2455 x_predecim, y_predecim); 2480 x_predecim, y_predecim);
@@ -2503,7 +2528,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
2503 bool mem_to_mem) 2528 bool mem_to_mem)
2504{ 2529{
2505 int r; 2530 int r;
2506 struct omap_overlay *ovl = omap_dss_get_overlay(plane); 2531 enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
2507 enum omap_channel channel; 2532 enum omap_channel channel;
2508 2533
2509 channel = dispc_ovl_get_channel_out(plane); 2534 channel = dispc_ovl_get_channel_out(plane);
@@ -2514,7 +2539,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
2514 oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height, 2539 oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
2515 oi->color_mode, oi->rotation, oi->mirror, channel, replication); 2540 oi->color_mode, oi->rotation, oi->mirror, channel, replication);
2516 2541
2517 r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr, 2542 r = dispc_ovl_setup_common(plane, caps, oi->paddr, oi->p_uv_addr,
2518 oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, 2543 oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
2519 oi->out_width, oi->out_height, oi->color_mode, oi->rotation, 2544 oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
2520 oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha, 2545 oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
@@ -2522,6 +2547,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
2522 2547
2523 return r; 2548 return r;
2524} 2549}
2550EXPORT_SYMBOL(dispc_ovl_setup);
2525 2551
2526int dispc_wb_setup(const struct omap_dss_writeback_info *wi, 2552int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
2527 bool mem_to_mem, const struct omap_video_timings *mgr_timings) 2553 bool mem_to_mem, const struct omap_video_timings *mgr_timings)
@@ -2582,192 +2608,39 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable)
2582 2608
2583 return 0; 2609 return 0;
2584} 2610}
2611EXPORT_SYMBOL(dispc_ovl_enable);
2585 2612
2586static void dispc_disable_isr(void *data, u32 mask) 2613bool dispc_ovl_enabled(enum omap_plane plane)
2587{ 2614{
2588 struct completion *compl = data; 2615 return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
2589 complete(compl);
2590} 2616}
2617EXPORT_SYMBOL(dispc_ovl_enabled);
2591 2618
2592static void _enable_lcd_out(enum omap_channel channel, bool enable) 2619void dispc_mgr_enable(enum omap_channel channel, bool enable)
2593{ 2620{
2594 mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable); 2621 mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
2595 /* flush posted write */ 2622 /* flush posted write */
2596 mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); 2623 mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2597} 2624}
2598 2625EXPORT_SYMBOL(dispc_mgr_enable);
2599static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
2600{
2601 struct completion frame_done_completion;
2602 bool is_on;
2603 int r;
2604 u32 irq;
2605
2606 /* When we disable LCD output, we need to wait until frame is done.
2607 * Otherwise the DSS is still working, and turning off the clocks
2608 * prevents DSS from going to OFF mode */
2609 is_on = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2610
2611 irq = mgr_desc[channel].framedone_irq;
2612
2613 if (!enable && is_on) {
2614 init_completion(&frame_done_completion);
2615
2616 r = omap_dispc_register_isr(dispc_disable_isr,
2617 &frame_done_completion, irq);
2618
2619 if (r)
2620 DSSERR("failed to register FRAMEDONE isr\n");
2621 }
2622
2623 _enable_lcd_out(channel, enable);
2624
2625 if (!enable && is_on) {
2626 if (!wait_for_completion_timeout(&frame_done_completion,
2627 msecs_to_jiffies(100)))
2628 DSSERR("timeout waiting for FRAME DONE\n");
2629
2630 r = omap_dispc_unregister_isr(dispc_disable_isr,
2631 &frame_done_completion, irq);
2632
2633 if (r)
2634 DSSERR("failed to unregister FRAMEDONE isr\n");
2635 }
2636}
2637
2638static void _enable_digit_out(bool enable)
2639{
2640 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
2641 /* flush posted write */
2642 dispc_read_reg(DISPC_CONTROL);
2643}
2644
2645static void dispc_mgr_enable_digit_out(bool enable)
2646{
2647 struct completion frame_done_completion;
2648 enum dss_hdmi_venc_clk_source_select src;
2649 int r, i;
2650 u32 irq_mask;
2651 int num_irqs;
2652
2653 if (REG_GET(DISPC_CONTROL, 1, 1) == enable)
2654 return;
2655
2656 src = dss_get_hdmi_venc_clk_source();
2657
2658 if (enable) {
2659 unsigned long flags;
2660 /* When we enable digit output, we'll get an extra digit
2661 * sync lost interrupt, that we need to ignore */
2662 spin_lock_irqsave(&dispc.irq_lock, flags);
2663 dispc.irq_error_mask &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
2664 _omap_dispc_set_irqs();
2665 spin_unlock_irqrestore(&dispc.irq_lock, flags);
2666 }
2667
2668 /* When we disable digit output, we need to wait until fields are done.
2669 * Otherwise the DSS is still working, and turning off the clocks
2670 * prevents DSS from going to OFF mode. And when enabling, we need to
2671 * wait for the extra sync losts */
2672 init_completion(&frame_done_completion);
2673
2674 if (src == DSS_HDMI_M_PCLK && enable == false) {
2675 irq_mask = DISPC_IRQ_FRAMEDONETV;
2676 num_irqs = 1;
2677 } else {
2678 irq_mask = DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
2679 /* XXX I understand from TRM that we should only wait for the
2680 * current field to complete. But it seems we have to wait for
2681 * both fields */
2682 num_irqs = 2;
2683 }
2684
2685 r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion,
2686 irq_mask);
2687 if (r)
2688 DSSERR("failed to register %x isr\n", irq_mask);
2689
2690 _enable_digit_out(enable);
2691
2692 for (i = 0; i < num_irqs; ++i) {
2693 if (!wait_for_completion_timeout(&frame_done_completion,
2694 msecs_to_jiffies(100)))
2695 DSSERR("timeout waiting for digit out to %s\n",
2696 enable ? "start" : "stop");
2697 }
2698
2699 r = omap_dispc_unregister_isr(dispc_disable_isr, &frame_done_completion,
2700 irq_mask);
2701 if (r)
2702 DSSERR("failed to unregister %x isr\n", irq_mask);
2703
2704 if (enable) {
2705 unsigned long flags;
2706 spin_lock_irqsave(&dispc.irq_lock, flags);
2707 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST_DIGIT;
2708 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
2709 _omap_dispc_set_irqs();
2710 spin_unlock_irqrestore(&dispc.irq_lock, flags);
2711 }
2712}
2713 2626
2714bool dispc_mgr_is_enabled(enum omap_channel channel) 2627bool dispc_mgr_is_enabled(enum omap_channel channel)
2715{ 2628{
2716 return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); 2629 return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2717} 2630}
2718 2631EXPORT_SYMBOL(dispc_mgr_is_enabled);
2719void dispc_mgr_enable(enum omap_channel channel, bool enable)
2720{
2721 if (dss_mgr_is_lcd(channel))
2722 dispc_mgr_enable_lcd_out(channel, enable);
2723 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
2724 dispc_mgr_enable_digit_out(enable);
2725 else
2726 BUG();
2727}
2728 2632
2729void dispc_wb_enable(bool enable) 2633void dispc_wb_enable(bool enable)
2730{ 2634{
2731 enum omap_plane plane = OMAP_DSS_WB; 2635 dispc_ovl_enable(OMAP_DSS_WB, enable);
2732 struct completion frame_done_completion;
2733 bool is_on;
2734 int r;
2735 u32 irq;
2736
2737 is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
2738 irq = DISPC_IRQ_FRAMEDONEWB;
2739
2740 if (!enable && is_on) {
2741 init_completion(&frame_done_completion);
2742
2743 r = omap_dispc_register_isr(dispc_disable_isr,
2744 &frame_done_completion, irq);
2745 if (r)
2746 DSSERR("failed to register FRAMEDONEWB isr\n");
2747 }
2748
2749 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
2750
2751 if (!enable && is_on) {
2752 if (!wait_for_completion_timeout(&frame_done_completion,
2753 msecs_to_jiffies(100)))
2754 DSSERR("timeout waiting for FRAMEDONEWB\n");
2755
2756 r = omap_dispc_unregister_isr(dispc_disable_isr,
2757 &frame_done_completion, irq);
2758 if (r)
2759 DSSERR("failed to unregister FRAMEDONEWB isr\n");
2760 }
2761} 2636}
2762 2637
2763bool dispc_wb_is_enabled(void) 2638bool dispc_wb_is_enabled(void)
2764{ 2639{
2765 enum omap_plane plane = OMAP_DSS_WB; 2640 return dispc_ovl_enabled(OMAP_DSS_WB);
2766
2767 return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
2768} 2641}
2769 2642
2770void dispc_lcd_enable_signal_polarity(bool act_high) 2643static void dispc_lcd_enable_signal_polarity(bool act_high)
2771{ 2644{
2772 if (!dss_has_feature(FEAT_LCDENABLEPOL)) 2645 if (!dss_has_feature(FEAT_LCDENABLEPOL))
2773 return; 2646 return;
@@ -2791,13 +2664,13 @@ void dispc_pck_free_enable(bool enable)
2791 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); 2664 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
2792} 2665}
2793 2666
2794void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable) 2667static void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
2795{ 2668{
2796 mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable); 2669 mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
2797} 2670}
2798 2671
2799 2672
2800void dispc_mgr_set_lcd_type_tft(enum omap_channel channel) 2673static void dispc_mgr_set_lcd_type_tft(enum omap_channel channel)
2801{ 2674{
2802 mgr_fld_write(channel, DISPC_MGR_FLD_STNTFT, 1); 2675 mgr_fld_write(channel, DISPC_MGR_FLD_STNTFT, 1);
2803} 2676}
@@ -2840,7 +2713,7 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
2840} 2713}
2841 2714
2842void dispc_mgr_setup(enum omap_channel channel, 2715void dispc_mgr_setup(enum omap_channel channel,
2843 struct omap_overlay_manager_info *info) 2716 const struct omap_overlay_manager_info *info)
2844{ 2717{
2845 dispc_mgr_set_default_color(channel, info->default_color); 2718 dispc_mgr_set_default_color(channel, info->default_color);
2846 dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key); 2719 dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key);
@@ -2852,8 +2725,9 @@ void dispc_mgr_setup(enum omap_channel channel,
2852 dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs); 2725 dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs);
2853 } 2726 }
2854} 2727}
2728EXPORT_SYMBOL(dispc_mgr_setup);
2855 2729
2856void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines) 2730static void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2857{ 2731{
2858 int code; 2732 int code;
2859 2733
@@ -2878,7 +2752,7 @@ void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2878 mgr_fld_write(channel, DISPC_MGR_FLD_TFTDATALINES, code); 2752 mgr_fld_write(channel, DISPC_MGR_FLD_TFTDATALINES, code);
2879} 2753}
2880 2754
2881void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode) 2755static void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
2882{ 2756{
2883 u32 l; 2757 u32 l;
2884 int gpout0, gpout1; 2758 int gpout0, gpout1;
@@ -2907,15 +2781,33 @@ void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
2907 dispc_write_reg(DISPC_CONTROL, l); 2781 dispc_write_reg(DISPC_CONTROL, l);
2908} 2782}
2909 2783
2910void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) 2784static void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
2911{ 2785{
2912 mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable); 2786 mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable);
2913} 2787}
2914 2788
2789void dispc_mgr_set_lcd_config(enum omap_channel channel,
2790 const struct dss_lcd_mgr_config *config)
2791{
2792 dispc_mgr_set_io_pad_mode(config->io_pad_mode);
2793
2794 dispc_mgr_enable_stallmode(channel, config->stallmode);
2795 dispc_mgr_enable_fifohandcheck(channel, config->fifohandcheck);
2796
2797 dispc_mgr_set_clock_div(channel, &config->clock_info);
2798
2799 dispc_mgr_set_tft_data_lines(channel, config->video_port_width);
2800
2801 dispc_lcd_enable_signal_polarity(config->lcden_sig_polarity);
2802
2803 dispc_mgr_set_lcd_type_tft(channel);
2804}
2805EXPORT_SYMBOL(dispc_mgr_set_lcd_config);
2806
2915static bool _dispc_mgr_size_ok(u16 width, u16 height) 2807static bool _dispc_mgr_size_ok(u16 width, u16 height)
2916{ 2808{
2917 return width <= dss_feat_get_param_max(FEAT_PARAM_MGR_WIDTH) && 2809 return width <= dispc.feat->mgr_width_max &&
2918 height <= dss_feat_get_param_max(FEAT_PARAM_MGR_HEIGHT); 2810 height <= dispc.feat->mgr_height_max;
2919} 2811}
2920 2812
2921static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, 2813static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
@@ -3010,7 +2902,7 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
3010 2902
3011/* change name to mode? */ 2903/* change name to mode? */
3012void dispc_mgr_set_timings(enum omap_channel channel, 2904void dispc_mgr_set_timings(enum omap_channel channel,
3013 struct omap_video_timings *timings) 2905 const struct omap_video_timings *timings)
3014{ 2906{
3015 unsigned xtot, ytot; 2907 unsigned xtot, ytot;
3016 unsigned long ht, vt; 2908 unsigned long ht, vt;
@@ -3049,6 +2941,7 @@ void dispc_mgr_set_timings(enum omap_channel channel,
3049 2941
3050 dispc_mgr_set_size(channel, t.x_res, t.y_res); 2942 dispc_mgr_set_size(channel, t.x_res, t.y_res);
3051} 2943}
2944EXPORT_SYMBOL(dispc_mgr_set_timings);
3052 2945
3053static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div, 2946static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
3054 u16 pck_div) 2947 u16 pck_div)
@@ -3076,7 +2969,7 @@ unsigned long dispc_fclk_rate(void)
3076 2969
3077 switch (dss_get_dispc_clk_source()) { 2970 switch (dss_get_dispc_clk_source()) {
3078 case OMAP_DSS_CLK_SRC_FCK: 2971 case OMAP_DSS_CLK_SRC_FCK:
3079 r = clk_get_rate(dispc.dss_clk); 2972 r = dss_get_dispc_clk_rate();
3080 break; 2973 break;
3081 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 2974 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
3082 dsidev = dsi_get_dsidev_from_id(0); 2975 dsidev = dsi_get_dsidev_from_id(0);
@@ -3101,28 +2994,32 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
3101 unsigned long r; 2994 unsigned long r;
3102 u32 l; 2995 u32 l;
3103 2996
3104 l = dispc_read_reg(DISPC_DIVISORo(channel)); 2997 if (dss_mgr_is_lcd(channel)) {
2998 l = dispc_read_reg(DISPC_DIVISORo(channel));
3105 2999
3106 lcd = FLD_GET(l, 23, 16); 3000 lcd = FLD_GET(l, 23, 16);
3107 3001
3108 switch (dss_get_lcd_clk_source(channel)) { 3002 switch (dss_get_lcd_clk_source(channel)) {
3109 case OMAP_DSS_CLK_SRC_FCK: 3003 case OMAP_DSS_CLK_SRC_FCK:
3110 r = clk_get_rate(dispc.dss_clk); 3004 r = dss_get_dispc_clk_rate();
3111 break; 3005 break;
3112 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 3006 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
3113 dsidev = dsi_get_dsidev_from_id(0); 3007 dsidev = dsi_get_dsidev_from_id(0);
3114 r = dsi_get_pll_hsdiv_dispc_rate(dsidev); 3008 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
3115 break; 3009 break;
3116 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 3010 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
3117 dsidev = dsi_get_dsidev_from_id(1); 3011 dsidev = dsi_get_dsidev_from_id(1);
3118 r = dsi_get_pll_hsdiv_dispc_rate(dsidev); 3012 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
3119 break; 3013 break;
3120 default: 3014 default:
3121 BUG(); 3015 BUG();
3122 return 0; 3016 return 0;
3123 } 3017 }
3124 3018
3125 return r / lcd; 3019 return r / lcd;
3020 } else {
3021 return dispc_fclk_rate();
3022 }
3126} 3023}
3127 3024
3128unsigned long dispc_mgr_pclk_rate(enum omap_channel channel) 3025unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
@@ -3172,21 +3069,28 @@ unsigned long dispc_core_clk_rate(void)
3172 3069
3173static unsigned long dispc_plane_pclk_rate(enum omap_plane plane) 3070static unsigned long dispc_plane_pclk_rate(enum omap_plane plane)
3174{ 3071{
3175 enum omap_channel channel = dispc_ovl_get_channel_out(plane); 3072 enum omap_channel channel;
3073
3074 if (plane == OMAP_DSS_WB)
3075 return 0;
3076
3077 channel = dispc_ovl_get_channel_out(plane);
3176 3078
3177 return dispc_mgr_pclk_rate(channel); 3079 return dispc_mgr_pclk_rate(channel);
3178} 3080}
3179 3081
3180static unsigned long dispc_plane_lclk_rate(enum omap_plane plane) 3082static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
3181{ 3083{
3182 enum omap_channel channel = dispc_ovl_get_channel_out(plane); 3084 enum omap_channel channel;
3183 3085
3184 if (dss_mgr_is_lcd(channel)) 3086 if (plane == OMAP_DSS_WB)
3185 return dispc_mgr_lclk_rate(channel); 3087 return 0;
3186 else 3088
3187 return dispc_fclk_rate(); 3089 channel = dispc_ovl_get_channel_out(plane);
3188 3090
3091 return dispc_mgr_lclk_rate(channel);
3189} 3092}
3093
3190static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) 3094static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
3191{ 3095{
3192 int lcd, pcd; 3096 int lcd, pcd;
@@ -3244,64 +3148,6 @@ void dispc_dump_clocks(struct seq_file *s)
3244 dispc_runtime_put(); 3148 dispc_runtime_put();
3245} 3149}
3246 3150
3247#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3248void dispc_dump_irqs(struct seq_file *s)
3249{
3250 unsigned long flags;
3251 struct dispc_irq_stats stats;
3252
3253 spin_lock_irqsave(&dispc.irq_stats_lock, flags);
3254
3255 stats = dispc.irq_stats;
3256 memset(&dispc.irq_stats, 0, sizeof(dispc.irq_stats));
3257 dispc.irq_stats.last_reset = jiffies;
3258
3259 spin_unlock_irqrestore(&dispc.irq_stats_lock, flags);
3260
3261 seq_printf(s, "period %u ms\n",
3262 jiffies_to_msecs(jiffies - stats.last_reset));
3263
3264 seq_printf(s, "irqs %d\n", stats.irq_count);
3265#define PIS(x) \
3266 seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
3267
3268 PIS(FRAMEDONE);
3269 PIS(VSYNC);
3270 PIS(EVSYNC_EVEN);
3271 PIS(EVSYNC_ODD);
3272 PIS(ACBIAS_COUNT_STAT);
3273 PIS(PROG_LINE_NUM);
3274 PIS(GFX_FIFO_UNDERFLOW);
3275 PIS(GFX_END_WIN);
3276 PIS(PAL_GAMMA_MASK);
3277 PIS(OCP_ERR);
3278 PIS(VID1_FIFO_UNDERFLOW);
3279 PIS(VID1_END_WIN);
3280 PIS(VID2_FIFO_UNDERFLOW);
3281 PIS(VID2_END_WIN);
3282 if (dss_feat_get_num_ovls() > 3) {
3283 PIS(VID3_FIFO_UNDERFLOW);
3284 PIS(VID3_END_WIN);
3285 }
3286 PIS(SYNC_LOST);
3287 PIS(SYNC_LOST_DIGIT);
3288 PIS(WAKEUP);
3289 if (dss_has_feature(FEAT_MGR_LCD2)) {
3290 PIS(FRAMEDONE2);
3291 PIS(VSYNC2);
3292 PIS(ACBIAS_COUNT_STAT2);
3293 PIS(SYNC_LOST2);
3294 }
3295 if (dss_has_feature(FEAT_MGR_LCD3)) {
3296 PIS(FRAMEDONE3);
3297 PIS(VSYNC3);
3298 PIS(ACBIAS_COUNT_STAT3);
3299 PIS(SYNC_LOST3);
3300 }
3301#undef PIS
3302}
3303#endif
3304
3305static void dispc_dump_regs(struct seq_file *s) 3151static void dispc_dump_regs(struct seq_file *s)
3306{ 3152{
3307 int i, j; 3153 int i, j;
@@ -3351,7 +3197,7 @@ static void dispc_dump_regs(struct seq_file *s)
3351 3197
3352#define DISPC_REG(i, name) name(i) 3198#define DISPC_REG(i, name) name(i)
3353#define DUMPREG(i, r) seq_printf(s, "%s(%s)%*s %08x\n", #r, p_names[i], \ 3199#define DUMPREG(i, r) seq_printf(s, "%s(%s)%*s %08x\n", #r, p_names[i], \
3354 48 - strlen(#r) - strlen(p_names[i]), " ", \ 3200 (int)(48 - strlen(#r) - strlen(p_names[i])), " ", \
3355 dispc_read_reg(DISPC_REG(i, r))) 3201 dispc_read_reg(DISPC_REG(i, r)))
3356 3202
3357 p_names = mgr_names; 3203 p_names = mgr_names;
@@ -3428,7 +3274,7 @@ static void dispc_dump_regs(struct seq_file *s)
3428#define DISPC_REG(plane, name, i) name(plane, i) 3274#define DISPC_REG(plane, name, i) name(plane, i)
3429#define DUMPREG(plane, name, i) \ 3275#define DUMPREG(plane, name, i) \
3430 seq_printf(s, "%s_%d(%s)%*s %08x\n", #name, i, p_names[plane], \ 3276 seq_printf(s, "%s_%d(%s)%*s %08x\n", #name, i, p_names[plane], \
3431 46 - strlen(#name) - strlen(p_names[plane]), " ", \ 3277 (int)(46 - strlen(#name) - strlen(p_names[plane])), " ", \
3432 dispc_read_reg(DISPC_REG(plane, name, i))) 3278 dispc_read_reg(DISPC_REG(plane, name, i)))
3433 3279
3434 /* Video pipeline coefficient registers */ 3280 /* Video pipeline coefficient registers */
@@ -3531,7 +3377,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
3531} 3377}
3532 3378
3533void dispc_mgr_set_clock_div(enum omap_channel channel, 3379void dispc_mgr_set_clock_div(enum omap_channel channel,
3534 struct dispc_clock_info *cinfo) 3380 const struct dispc_clock_info *cinfo)
3535{ 3381{
3536 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); 3382 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
3537 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); 3383 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
@@ -3555,403 +3401,34 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
3555 return 0; 3401 return 0;
3556} 3402}
3557 3403
3558/* dispc.irq_lock has to be locked by the caller */ 3404u32 dispc_read_irqstatus(void)
3559static void _omap_dispc_set_irqs(void)
3560{ 3405{
3561 u32 mask; 3406 return dispc_read_reg(DISPC_IRQSTATUS);
3562 u32 old_mask;
3563 int i;
3564 struct omap_dispc_isr_data *isr_data;
3565
3566 mask = dispc.irq_error_mask;
3567
3568 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
3569 isr_data = &dispc.registered_isr[i];
3570
3571 if (isr_data->isr == NULL)
3572 continue;
3573
3574 mask |= isr_data->mask;
3575 }
3576
3577 old_mask = dispc_read_reg(DISPC_IRQENABLE);
3578 /* clear the irqstatus for newly enabled irqs */
3579 dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask);
3580
3581 dispc_write_reg(DISPC_IRQENABLE, mask);
3582}
3583
3584int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
3585{
3586 int i;
3587 int ret;
3588 unsigned long flags;
3589 struct omap_dispc_isr_data *isr_data;
3590
3591 if (isr == NULL)
3592 return -EINVAL;
3593
3594 spin_lock_irqsave(&dispc.irq_lock, flags);
3595
3596 /* check for duplicate entry */
3597 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
3598 isr_data = &dispc.registered_isr[i];
3599 if (isr_data->isr == isr && isr_data->arg == arg &&
3600 isr_data->mask == mask) {
3601 ret = -EINVAL;
3602 goto err;
3603 }
3604 }
3605
3606 isr_data = NULL;
3607 ret = -EBUSY;
3608
3609 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
3610 isr_data = &dispc.registered_isr[i];
3611
3612 if (isr_data->isr != NULL)
3613 continue;
3614
3615 isr_data->isr = isr;
3616 isr_data->arg = arg;
3617 isr_data->mask = mask;
3618 ret = 0;
3619
3620 break;
3621 }
3622
3623 if (ret)
3624 goto err;
3625
3626 _omap_dispc_set_irqs();
3627
3628 spin_unlock_irqrestore(&dispc.irq_lock, flags);
3629
3630 return 0;
3631err:
3632 spin_unlock_irqrestore(&dispc.irq_lock, flags);
3633
3634 return ret;
3635}
3636EXPORT_SYMBOL(omap_dispc_register_isr);
3637
3638int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
3639{
3640 int i;
3641 unsigned long flags;
3642 int ret = -EINVAL;
3643 struct omap_dispc_isr_data *isr_data;
3644
3645 spin_lock_irqsave(&dispc.irq_lock, flags);
3646
3647 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
3648 isr_data = &dispc.registered_isr[i];
3649 if (isr_data->isr != isr || isr_data->arg != arg ||
3650 isr_data->mask != mask)
3651 continue;
3652
3653 /* found the correct isr */
3654
3655 isr_data->isr = NULL;
3656 isr_data->arg = NULL;
3657 isr_data->mask = 0;
3658
3659 ret = 0;
3660 break;
3661 }
3662
3663 if (ret == 0)
3664 _omap_dispc_set_irqs();
3665
3666 spin_unlock_irqrestore(&dispc.irq_lock, flags);
3667
3668 return ret;
3669}
3670EXPORT_SYMBOL(omap_dispc_unregister_isr);
3671
3672#ifdef DEBUG
3673static void print_irq_status(u32 status)
3674{
3675 if ((status & dispc.irq_error_mask) == 0)
3676 return;
3677
3678 printk(KERN_DEBUG "DISPC IRQ: 0x%x: ", status);
3679
3680#define PIS(x) \
3681 if (status & DISPC_IRQ_##x) \
3682 printk(#x " ");
3683 PIS(GFX_FIFO_UNDERFLOW);
3684 PIS(OCP_ERR);
3685 PIS(VID1_FIFO_UNDERFLOW);
3686 PIS(VID2_FIFO_UNDERFLOW);
3687 if (dss_feat_get_num_ovls() > 3)
3688 PIS(VID3_FIFO_UNDERFLOW);
3689 PIS(SYNC_LOST);
3690 PIS(SYNC_LOST_DIGIT);
3691 if (dss_has_feature(FEAT_MGR_LCD2))
3692 PIS(SYNC_LOST2);
3693 if (dss_has_feature(FEAT_MGR_LCD3))
3694 PIS(SYNC_LOST3);
3695#undef PIS
3696
3697 printk("\n");
3698}
3699#endif
3700
3701/* Called from dss.c. Note that we don't touch clocks here,
3702 * but we presume they are on because we got an IRQ. However,
3703 * an irq handler may turn the clocks off, so we may not have
3704 * clock later in the function. */
3705static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
3706{
3707 int i;
3708 u32 irqstatus, irqenable;
3709 u32 handledirqs = 0;
3710 u32 unhandled_errors;
3711 struct omap_dispc_isr_data *isr_data;
3712 struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
3713
3714 spin_lock(&dispc.irq_lock);
3715
3716 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
3717 irqenable = dispc_read_reg(DISPC_IRQENABLE);
3718
3719 /* IRQ is not for us */
3720 if (!(irqstatus & irqenable)) {
3721 spin_unlock(&dispc.irq_lock);
3722 return IRQ_NONE;
3723 }
3724
3725#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3726 spin_lock(&dispc.irq_stats_lock);
3727 dispc.irq_stats.irq_count++;
3728 dss_collect_irq_stats(irqstatus, dispc.irq_stats.irqs);
3729 spin_unlock(&dispc.irq_stats_lock);
3730#endif
3731
3732#ifdef DEBUG
3733 if (dss_debug)
3734 print_irq_status(irqstatus);
3735#endif
3736 /* Ack the interrupt. Do it here before clocks are possibly turned
3737 * off */
3738 dispc_write_reg(DISPC_IRQSTATUS, irqstatus);
3739 /* flush posted write */
3740 dispc_read_reg(DISPC_IRQSTATUS);
3741
3742 /* make a copy and unlock, so that isrs can unregister
3743 * themselves */
3744 memcpy(registered_isr, dispc.registered_isr,
3745 sizeof(registered_isr));
3746
3747 spin_unlock(&dispc.irq_lock);
3748
3749 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
3750 isr_data = &registered_isr[i];
3751
3752 if (!isr_data->isr)
3753 continue;
3754
3755 if (isr_data->mask & irqstatus) {
3756 isr_data->isr(isr_data->arg, irqstatus);
3757 handledirqs |= isr_data->mask;
3758 }
3759 }
3760
3761 spin_lock(&dispc.irq_lock);
3762
3763 unhandled_errors = irqstatus & ~handledirqs & dispc.irq_error_mask;
3764
3765 if (unhandled_errors) {
3766 dispc.error_irqs |= unhandled_errors;
3767
3768 dispc.irq_error_mask &= ~unhandled_errors;
3769 _omap_dispc_set_irqs();
3770
3771 schedule_work(&dispc.error_work);
3772 }
3773
3774 spin_unlock(&dispc.irq_lock);
3775
3776 return IRQ_HANDLED;
3777}
3778
3779static void dispc_error_worker(struct work_struct *work)
3780{
3781 int i;
3782 u32 errors;
3783 unsigned long flags;
3784 static const unsigned fifo_underflow_bits[] = {
3785 DISPC_IRQ_GFX_FIFO_UNDERFLOW,
3786 DISPC_IRQ_VID1_FIFO_UNDERFLOW,
3787 DISPC_IRQ_VID2_FIFO_UNDERFLOW,
3788 DISPC_IRQ_VID3_FIFO_UNDERFLOW,
3789 };
3790
3791 spin_lock_irqsave(&dispc.irq_lock, flags);
3792 errors = dispc.error_irqs;
3793 dispc.error_irqs = 0;
3794 spin_unlock_irqrestore(&dispc.irq_lock, flags);
3795
3796 dispc_runtime_get();
3797
3798 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3799 struct omap_overlay *ovl;
3800 unsigned bit;
3801
3802 ovl = omap_dss_get_overlay(i);
3803 bit = fifo_underflow_bits[i];
3804
3805 if (bit & errors) {
3806 DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
3807 ovl->name);
3808 dispc_ovl_enable(ovl->id, false);
3809 dispc_mgr_go(ovl->manager->id);
3810 msleep(50);
3811 }
3812 }
3813
3814 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
3815 struct omap_overlay_manager *mgr;
3816 unsigned bit;
3817
3818 mgr = omap_dss_get_overlay_manager(i);
3819 bit = mgr_desc[i].sync_lost_irq;
3820
3821 if (bit & errors) {
3822 struct omap_dss_device *dssdev = mgr->get_device(mgr);
3823 bool enable;
3824
3825 DSSERR("SYNC_LOST on channel %s, restarting the output "
3826 "with video overlays disabled\n",
3827 mgr->name);
3828
3829 enable = dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
3830 dssdev->driver->disable(dssdev);
3831
3832 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3833 struct omap_overlay *ovl;
3834 ovl = omap_dss_get_overlay(i);
3835
3836 if (ovl->id != OMAP_DSS_GFX &&
3837 ovl->manager == mgr)
3838 dispc_ovl_enable(ovl->id, false);
3839 }
3840
3841 dispc_mgr_go(mgr->id);
3842 msleep(50);
3843
3844 if (enable)
3845 dssdev->driver->enable(dssdev);
3846 }
3847 }
3848
3849 if (errors & DISPC_IRQ_OCP_ERR) {
3850 DSSERR("OCP_ERR\n");
3851 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
3852 struct omap_overlay_manager *mgr;
3853 struct omap_dss_device *dssdev;
3854
3855 mgr = omap_dss_get_overlay_manager(i);
3856 dssdev = mgr->get_device(mgr);
3857
3858 if (dssdev && dssdev->driver)
3859 dssdev->driver->disable(dssdev);
3860 }
3861 }
3862
3863 spin_lock_irqsave(&dispc.irq_lock, flags);
3864 dispc.irq_error_mask |= errors;
3865 _omap_dispc_set_irqs();
3866 spin_unlock_irqrestore(&dispc.irq_lock, flags);
3867
3868 dispc_runtime_put();
3869} 3407}
3408EXPORT_SYMBOL(dispc_read_irqstatus);
3870 3409
3871int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout) 3410void dispc_clear_irqstatus(u32 mask)
3872{ 3411{
3873 void dispc_irq_wait_handler(void *data, u32 mask) 3412 dispc_write_reg(DISPC_IRQSTATUS, mask);
3874 {
3875 complete((struct completion *)data);
3876 }
3877
3878 int r;
3879 DECLARE_COMPLETION_ONSTACK(completion);
3880
3881 r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
3882 irqmask);
3883
3884 if (r)
3885 return r;
3886
3887 timeout = wait_for_completion_timeout(&completion, timeout);
3888
3889 omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
3890
3891 if (timeout == 0)
3892 return -ETIMEDOUT;
3893
3894 if (timeout == -ERESTARTSYS)
3895 return -ERESTARTSYS;
3896
3897 return 0;
3898} 3413}
3414EXPORT_SYMBOL(dispc_clear_irqstatus);
3899 3415
3900int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask, 3416u32 dispc_read_irqenable(void)
3901 unsigned long timeout)
3902{ 3417{
3903 void dispc_irq_wait_handler(void *data, u32 mask) 3418 return dispc_read_reg(DISPC_IRQENABLE);
3904 {
3905 complete((struct completion *)data);
3906 }
3907
3908 int r;
3909 DECLARE_COMPLETION_ONSTACK(completion);
3910
3911 r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
3912 irqmask);
3913
3914 if (r)
3915 return r;
3916
3917 timeout = wait_for_completion_interruptible_timeout(&completion,
3918 timeout);
3919
3920 omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
3921
3922 if (timeout == 0)
3923 return -ETIMEDOUT;
3924
3925 if (timeout == -ERESTARTSYS)
3926 return -ERESTARTSYS;
3927
3928 return 0;
3929} 3419}
3420EXPORT_SYMBOL(dispc_read_irqenable);
3930 3421
3931static void _omap_dispc_initialize_irq(void) 3422void dispc_write_irqenable(u32 mask)
3932{ 3423{
3933 unsigned long flags; 3424 u32 old_mask = dispc_read_reg(DISPC_IRQENABLE);
3934
3935 spin_lock_irqsave(&dispc.irq_lock, flags);
3936
3937 memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr));
3938
3939 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
3940 if (dss_has_feature(FEAT_MGR_LCD2))
3941 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
3942 if (dss_has_feature(FEAT_MGR_LCD3))
3943 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
3944 if (dss_feat_get_num_ovls() > 3)
3945 dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
3946
3947 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
3948 * so clear it */
3949 dispc_write_reg(DISPC_IRQSTATUS, dispc_read_reg(DISPC_IRQSTATUS));
3950 3425
3951 _omap_dispc_set_irqs(); 3426 /* clear the irqstatus for newly enabled irqs */
3427 dispc_clear_irqstatus((mask ^ old_mask) & mask);
3952 3428
3953 spin_unlock_irqrestore(&dispc.irq_lock, flags); 3429 dispc_write_reg(DISPC_IRQENABLE, mask);
3954} 3430}
3431EXPORT_SYMBOL(dispc_write_irqenable);
3955 3432
3956void dispc_enable_sidle(void) 3433void dispc_enable_sidle(void)
3957{ 3434{
@@ -3998,9 +3475,14 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
3998 .sw_max = 64, 3475 .sw_max = 64,
3999 .vp_max = 255, 3476 .vp_max = 255,
4000 .hp_max = 256, 3477 .hp_max = 256,
3478 .mgr_width_start = 10,
3479 .mgr_height_start = 26,
3480 .mgr_width_max = 2048,
3481 .mgr_height_max = 2048,
4001 .calc_scaling = dispc_ovl_calc_scaling_24xx, 3482 .calc_scaling = dispc_ovl_calc_scaling_24xx,
4002 .calc_core_clk = calc_core_clk_24xx, 3483 .calc_core_clk = calc_core_clk_24xx,
4003 .num_fifos = 3, 3484 .num_fifos = 3,
3485 .no_framedone_tv = true,
4004}; 3486};
4005 3487
4006static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = { 3488static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
@@ -4010,9 +3492,14 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
4010 .sw_max = 64, 3492 .sw_max = 64,
4011 .vp_max = 255, 3493 .vp_max = 255,
4012 .hp_max = 256, 3494 .hp_max = 256,
3495 .mgr_width_start = 10,
3496 .mgr_height_start = 26,
3497 .mgr_width_max = 2048,
3498 .mgr_height_max = 2048,
4013 .calc_scaling = dispc_ovl_calc_scaling_34xx, 3499 .calc_scaling = dispc_ovl_calc_scaling_34xx,
4014 .calc_core_clk = calc_core_clk_34xx, 3500 .calc_core_clk = calc_core_clk_34xx,
4015 .num_fifos = 3, 3501 .num_fifos = 3,
3502 .no_framedone_tv = true,
4016}; 3503};
4017 3504
4018static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = { 3505static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
@@ -4022,9 +3509,14 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
4022 .sw_max = 256, 3509 .sw_max = 256,
4023 .vp_max = 4095, 3510 .vp_max = 4095,
4024 .hp_max = 4096, 3511 .hp_max = 4096,
3512 .mgr_width_start = 10,
3513 .mgr_height_start = 26,
3514 .mgr_width_max = 2048,
3515 .mgr_height_max = 2048,
4025 .calc_scaling = dispc_ovl_calc_scaling_34xx, 3516 .calc_scaling = dispc_ovl_calc_scaling_34xx,
4026 .calc_core_clk = calc_core_clk_34xx, 3517 .calc_core_clk = calc_core_clk_34xx,
4027 .num_fifos = 3, 3518 .num_fifos = 3,
3519 .no_framedone_tv = true,
4028}; 3520};
4029 3521
4030static const struct dispc_features omap44xx_dispc_feats __initconst = { 3522static const struct dispc_features omap44xx_dispc_feats __initconst = {
@@ -4034,6 +3526,27 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
4034 .sw_max = 256, 3526 .sw_max = 256,
4035 .vp_max = 4095, 3527 .vp_max = 4095,
4036 .hp_max = 4096, 3528 .hp_max = 4096,
3529 .mgr_width_start = 10,
3530 .mgr_height_start = 26,
3531 .mgr_width_max = 2048,
3532 .mgr_height_max = 2048,
3533 .calc_scaling = dispc_ovl_calc_scaling_44xx,
3534 .calc_core_clk = calc_core_clk_44xx,
3535 .num_fifos = 5,
3536 .gfx_fifo_workaround = true,
3537};
3538
3539static const struct dispc_features omap54xx_dispc_feats __initconst = {
3540 .sw_start = 7,
3541 .fp_start = 19,
3542 .bp_start = 31,
3543 .sw_max = 256,
3544 .vp_max = 4095,
3545 .hp_max = 4096,
3546 .mgr_width_start = 11,
3547 .mgr_height_start = 27,
3548 .mgr_width_max = 4096,
3549 .mgr_height_max = 4096,
4037 .calc_scaling = dispc_ovl_calc_scaling_44xx, 3550 .calc_scaling = dispc_ovl_calc_scaling_44xx,
4038 .calc_core_clk = calc_core_clk_44xx, 3551 .calc_core_clk = calc_core_clk_44xx,
4039 .num_fifos = 5, 3552 .num_fifos = 5,
@@ -4042,7 +3555,6 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
4042 3555
4043static int __init dispc_init_features(struct platform_device *pdev) 3556static int __init dispc_init_features(struct platform_device *pdev)
4044{ 3557{
4045 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
4046 const struct dispc_features *src; 3558 const struct dispc_features *src;
4047 struct dispc_features *dst; 3559 struct dispc_features *dst;
4048 3560
@@ -4052,7 +3564,7 @@ static int __init dispc_init_features(struct platform_device *pdev)
4052 return -ENOMEM; 3564 return -ENOMEM;
4053 } 3565 }
4054 3566
4055 switch (pdata->version) { 3567 switch (omapdss_get_version()) {
4056 case OMAPDSS_VER_OMAP24xx: 3568 case OMAPDSS_VER_OMAP24xx:
4057 src = &omap24xx_dispc_feats; 3569 src = &omap24xx_dispc_feats;
4058 break; 3570 break;
@@ -4074,7 +3586,7 @@ static int __init dispc_init_features(struct platform_device *pdev)
4074 break; 3586 break;
4075 3587
4076 case OMAPDSS_VER_OMAP5: 3588 case OMAPDSS_VER_OMAP5:
4077 src = &omap44xx_dispc_feats; 3589 src = &omap54xx_dispc_feats;
4078 break; 3590 break;
4079 3591
4080 default: 3592 default:
@@ -4087,13 +3599,25 @@ static int __init dispc_init_features(struct platform_device *pdev)
4087 return 0; 3599 return 0;
4088} 3600}
4089 3601
3602int dispc_request_irq(irq_handler_t handler, void *dev_id)
3603{
3604 return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler,
3605 IRQF_SHARED, "OMAP DISPC", dev_id);
3606}
3607EXPORT_SYMBOL(dispc_request_irq);
3608
3609void dispc_free_irq(void *dev_id)
3610{
3611 devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id);
3612}
3613EXPORT_SYMBOL(dispc_free_irq);
3614
4090/* DISPC HW IP initialisation */ 3615/* DISPC HW IP initialisation */
4091static int __init omap_dispchw_probe(struct platform_device *pdev) 3616static int __init omap_dispchw_probe(struct platform_device *pdev)
4092{ 3617{
4093 u32 rev; 3618 u32 rev;
4094 int r = 0; 3619 int r = 0;
4095 struct resource *dispc_mem; 3620 struct resource *dispc_mem;
4096 struct clk *clk;
4097 3621
4098 dispc.pdev = pdev; 3622 dispc.pdev = pdev;
4099 3623
@@ -4101,15 +3625,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
4101 if (r) 3625 if (r)
4102 return r; 3626 return r;
4103 3627
4104 spin_lock_init(&dispc.irq_lock);
4105
4106#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
4107 spin_lock_init(&dispc.irq_stats_lock);
4108 dispc.irq_stats.last_reset = jiffies;
4109#endif
4110
4111 INIT_WORK(&dispc.error_work, dispc_error_worker);
4112
4113 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0); 3628 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
4114 if (!dispc_mem) { 3629 if (!dispc_mem) {
4115 DSSERR("can't get IORESOURCE_MEM DISPC\n"); 3630 DSSERR("can't get IORESOURCE_MEM DISPC\n");
@@ -4129,22 +3644,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
4129 return -ENODEV; 3644 return -ENODEV;
4130 } 3645 }
4131 3646
4132 r = devm_request_irq(&pdev->dev, dispc.irq, omap_dispc_irq_handler,
4133 IRQF_SHARED, "OMAP DISPC", dispc.pdev);
4134 if (r < 0) {
4135 DSSERR("request_irq failed\n");
4136 return r;
4137 }
4138
4139 clk = clk_get(&pdev->dev, "fck");
4140 if (IS_ERR(clk)) {
4141 DSSERR("can't get fck\n");
4142 r = PTR_ERR(clk);
4143 return r;
4144 }
4145
4146 dispc.dss_clk = clk;
4147
4148 pm_runtime_enable(&pdev->dev); 3647 pm_runtime_enable(&pdev->dev);
4149 3648
4150 r = dispc_runtime_get(); 3649 r = dispc_runtime_get();
@@ -4153,8 +3652,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
4153 3652
4154 _omap_dispc_initial_config(); 3653 _omap_dispc_initial_config();
4155 3654
4156 _omap_dispc_initialize_irq();
4157
4158 rev = dispc_read_reg(DISPC_REVISION); 3655 rev = dispc_read_reg(DISPC_REVISION);
4159 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n", 3656 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
4160 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 3657 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -4163,14 +3660,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
4163 3660
4164 dss_debugfs_create_file("dispc", dispc_dump_regs); 3661 dss_debugfs_create_file("dispc", dispc_dump_regs);
4165 3662
4166#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
4167 dss_debugfs_create_file("dispc_irq", dispc_dump_irqs);
4168#endif
4169 return 0; 3663 return 0;
4170 3664
4171err_runtime_get: 3665err_runtime_get:
4172 pm_runtime_disable(&pdev->dev); 3666 pm_runtime_disable(&pdev->dev);
4173 clk_put(dispc.dss_clk);
4174 return r; 3667 return r;
4175} 3668}
4176 3669
@@ -4178,8 +3671,6 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
4178{ 3671{
4179 pm_runtime_disable(&pdev->dev); 3672 pm_runtime_disable(&pdev->dev);
4180 3673
4181 clk_put(dispc.dss_clk);
4182
4183 return 0; 3674 return 0;
4184} 3675}
4185 3676
diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/omap2/dss/display-sysfs.c
new file mode 100644
index 000000000000..18211a9ab354
--- /dev/null
+++ b/drivers/video/omap2/dss/display-sysfs.c
@@ -0,0 +1,321 @@
1/*
2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
4 *
5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#define DSS_SUBSYS_NAME "DISPLAY"
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/jiffies.h>
26#include <linux/platform_device.h>
27
28#include <video/omapdss.h>
29#include "dss.h"
30#include "dss_features.h"
31
32static ssize_t display_enabled_show(struct device *dev,
33 struct device_attribute *attr, char *buf)
34{
35 struct omap_dss_device *dssdev = to_dss_device(dev);
36 bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
37
38 return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
39}
40
41static ssize_t display_enabled_store(struct device *dev,
42 struct device_attribute *attr,
43 const char *buf, size_t size)
44{
45 struct omap_dss_device *dssdev = to_dss_device(dev);
46 int r;
47 bool enabled;
48
49 r = strtobool(buf, &enabled);
50 if (r)
51 return r;
52
53 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
54 if (enabled) {
55 r = dssdev->driver->enable(dssdev);
56 if (r)
57 return r;
58 } else {
59 dssdev->driver->disable(dssdev);
60 }
61 }
62
63 return size;
64}
65
66static ssize_t display_tear_show(struct device *dev,
67 struct device_attribute *attr, char *buf)
68{
69 struct omap_dss_device *dssdev = to_dss_device(dev);
70 return snprintf(buf, PAGE_SIZE, "%d\n",
71 dssdev->driver->get_te ?
72 dssdev->driver->get_te(dssdev) : 0);
73}
74
75static ssize_t display_tear_store(struct device *dev,
76 struct device_attribute *attr, const char *buf, size_t size)
77{
78 struct omap_dss_device *dssdev = to_dss_device(dev);
79 int r;
80 bool te;
81
82 if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
83 return -ENOENT;
84
85 r = strtobool(buf, &te);
86 if (r)
87 return r;
88
89 r = dssdev->driver->enable_te(dssdev, te);
90 if (r)
91 return r;
92
93 return size;
94}
95
96static ssize_t display_timings_show(struct device *dev,
97 struct device_attribute *attr, char *buf)
98{
99 struct omap_dss_device *dssdev = to_dss_device(dev);
100 struct omap_video_timings t;
101
102 if (!dssdev->driver->get_timings)
103 return -ENOENT;
104
105 dssdev->driver->get_timings(dssdev, &t);
106
107 return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
108 t.pixel_clock,
109 t.x_res, t.hfp, t.hbp, t.hsw,
110 t.y_res, t.vfp, t.vbp, t.vsw);
111}
112
113static ssize_t display_timings_store(struct device *dev,
114 struct device_attribute *attr, const char *buf, size_t size)
115{
116 struct omap_dss_device *dssdev = to_dss_device(dev);
117 struct omap_video_timings t = dssdev->panel.timings;
118 int r, found;
119
120 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
121 return -ENOENT;
122
123 found = 0;
124#ifdef CONFIG_OMAP2_DSS_VENC
125 if (strncmp("pal", buf, 3) == 0) {
126 t = omap_dss_pal_timings;
127 found = 1;
128 } else if (strncmp("ntsc", buf, 4) == 0) {
129 t = omap_dss_ntsc_timings;
130 found = 1;
131 }
132#endif
133 if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
134 &t.pixel_clock,
135 &t.x_res, &t.hfp, &t.hbp, &t.hsw,
136 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
137 return -EINVAL;
138
139 r = dssdev->driver->check_timings(dssdev, &t);
140 if (r)
141 return r;
142
143 dssdev->driver->disable(dssdev);
144 dssdev->driver->set_timings(dssdev, &t);
145 r = dssdev->driver->enable(dssdev);
146 if (r)
147 return r;
148
149 return size;
150}
151
152static ssize_t display_rotate_show(struct device *dev,
153 struct device_attribute *attr, char *buf)
154{
155 struct omap_dss_device *dssdev = to_dss_device(dev);
156 int rotate;
157 if (!dssdev->driver->get_rotate)
158 return -ENOENT;
159 rotate = dssdev->driver->get_rotate(dssdev);
160 return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
161}
162
163static ssize_t display_rotate_store(struct device *dev,
164 struct device_attribute *attr, const char *buf, size_t size)
165{
166 struct omap_dss_device *dssdev = to_dss_device(dev);
167 int rot, r;
168
169 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
170 return -ENOENT;
171
172 r = kstrtoint(buf, 0, &rot);
173 if (r)
174 return r;
175
176 r = dssdev->driver->set_rotate(dssdev, rot);
177 if (r)
178 return r;
179
180 return size;
181}
182
183static ssize_t display_mirror_show(struct device *dev,
184 struct device_attribute *attr, char *buf)
185{
186 struct omap_dss_device *dssdev = to_dss_device(dev);
187 int mirror;
188 if (!dssdev->driver->get_mirror)
189 return -ENOENT;
190 mirror = dssdev->driver->get_mirror(dssdev);
191 return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
192}
193
194static ssize_t display_mirror_store(struct device *dev,
195 struct device_attribute *attr, const char *buf, size_t size)
196{
197 struct omap_dss_device *dssdev = to_dss_device(dev);
198 int r;
199 bool mirror;
200
201 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
202 return -ENOENT;
203
204 r = strtobool(buf, &mirror);
205 if (r)
206 return r;
207
208 r = dssdev->driver->set_mirror(dssdev, mirror);
209 if (r)
210 return r;
211
212 return size;
213}
214
215static ssize_t display_wss_show(struct device *dev,
216 struct device_attribute *attr, char *buf)
217{
218 struct omap_dss_device *dssdev = to_dss_device(dev);
219 unsigned int wss;
220
221 if (!dssdev->driver->get_wss)
222 return -ENOENT;
223
224 wss = dssdev->driver->get_wss(dssdev);
225
226 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
227}
228
229static ssize_t display_wss_store(struct device *dev,
230 struct device_attribute *attr, const char *buf, size_t size)
231{
232 struct omap_dss_device *dssdev = to_dss_device(dev);
233 u32 wss;
234 int r;
235
236 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
237 return -ENOENT;
238
239 r = kstrtou32(buf, 0, &wss);
240 if (r)
241 return r;
242
243 if (wss > 0xfffff)
244 return -EINVAL;
245
246 r = dssdev->driver->set_wss(dssdev, wss);
247 if (r)
248 return r;
249
250 return size;
251}
252
253static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
254 display_enabled_show, display_enabled_store);
255static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
256 display_tear_show, display_tear_store);
257static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
258 display_timings_show, display_timings_store);
259static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR,
260 display_rotate_show, display_rotate_store);
261static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
262 display_mirror_show, display_mirror_store);
263static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
264 display_wss_show, display_wss_store);
265
266static struct device_attribute *display_sysfs_attrs[] = {
267 &dev_attr_enabled,
268 &dev_attr_tear_elim,
269 &dev_attr_timings,
270 &dev_attr_rotate,
271 &dev_attr_mirror,
272 &dev_attr_wss,
273 NULL
274};
275
276int display_init_sysfs(struct platform_device *pdev,
277 struct omap_dss_device *dssdev)
278{
279 struct device_attribute *attr;
280 int i, r;
281
282 /* create device sysfs files */
283 i = 0;
284 while ((attr = display_sysfs_attrs[i++]) != NULL) {
285 r = device_create_file(&dssdev->dev, attr);
286 if (r) {
287 for (i = i - 2; i >= 0; i--) {
288 attr = display_sysfs_attrs[i];
289 device_remove_file(&dssdev->dev, attr);
290 }
291
292 DSSERR("failed to create sysfs file\n");
293 return r;
294 }
295 }
296
297 /* create display? sysfs links */
298 r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
299 dev_name(&dssdev->dev));
300 if (r) {
301 while ((attr = display_sysfs_attrs[i++]) != NULL)
302 device_remove_file(&dssdev->dev, attr);
303
304 DSSERR("failed to create sysfs display link\n");
305 return r;
306 }
307
308 return 0;
309}
310
311void display_uninit_sysfs(struct platform_device *pdev,
312 struct omap_dss_device *dssdev)
313{
314 struct device_attribute *attr;
315 int i = 0;
316
317 sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
318
319 while ((attr = display_sysfs_attrs[i++]) != NULL)
320 device_remove_file(&dssdev->dev, attr);
321}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index ccf8550fafde..0aa8ad8f9667 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -31,250 +31,6 @@
31#include "dss.h" 31#include "dss.h"
32#include "dss_features.h" 32#include "dss_features.h"
33 33
34static ssize_t display_enabled_show(struct device *dev,
35 struct device_attribute *attr, char *buf)
36{
37 struct omap_dss_device *dssdev = to_dss_device(dev);
38 bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
39
40 return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
41}
42
43static ssize_t display_enabled_store(struct device *dev,
44 struct device_attribute *attr,
45 const char *buf, size_t size)
46{
47 struct omap_dss_device *dssdev = to_dss_device(dev);
48 int r;
49 bool enabled;
50
51 r = strtobool(buf, &enabled);
52 if (r)
53 return r;
54
55 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
56 if (enabled) {
57 r = dssdev->driver->enable(dssdev);
58 if (r)
59 return r;
60 } else {
61 dssdev->driver->disable(dssdev);
62 }
63 }
64
65 return size;
66}
67
68static ssize_t display_tear_show(struct device *dev,
69 struct device_attribute *attr, char *buf)
70{
71 struct omap_dss_device *dssdev = to_dss_device(dev);
72 return snprintf(buf, PAGE_SIZE, "%d\n",
73 dssdev->driver->get_te ?
74 dssdev->driver->get_te(dssdev) : 0);
75}
76
77static ssize_t display_tear_store(struct device *dev,
78 struct device_attribute *attr, const char *buf, size_t size)
79{
80 struct omap_dss_device *dssdev = to_dss_device(dev);
81 int r;
82 bool te;
83
84 if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
85 return -ENOENT;
86
87 r = strtobool(buf, &te);
88 if (r)
89 return r;
90
91 r = dssdev->driver->enable_te(dssdev, te);
92 if (r)
93 return r;
94
95 return size;
96}
97
98static ssize_t display_timings_show(struct device *dev,
99 struct device_attribute *attr, char *buf)
100{
101 struct omap_dss_device *dssdev = to_dss_device(dev);
102 struct omap_video_timings t;
103
104 if (!dssdev->driver->get_timings)
105 return -ENOENT;
106
107 dssdev->driver->get_timings(dssdev, &t);
108
109 return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
110 t.pixel_clock,
111 t.x_res, t.hfp, t.hbp, t.hsw,
112 t.y_res, t.vfp, t.vbp, t.vsw);
113}
114
115static ssize_t display_timings_store(struct device *dev,
116 struct device_attribute *attr, const char *buf, size_t size)
117{
118 struct omap_dss_device *dssdev = to_dss_device(dev);
119 struct omap_video_timings t = dssdev->panel.timings;
120 int r, found;
121
122 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
123 return -ENOENT;
124
125 found = 0;
126#ifdef CONFIG_OMAP2_DSS_VENC
127 if (strncmp("pal", buf, 3) == 0) {
128 t = omap_dss_pal_timings;
129 found = 1;
130 } else if (strncmp("ntsc", buf, 4) == 0) {
131 t = omap_dss_ntsc_timings;
132 found = 1;
133 }
134#endif
135 if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
136 &t.pixel_clock,
137 &t.x_res, &t.hfp, &t.hbp, &t.hsw,
138 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
139 return -EINVAL;
140
141 r = dssdev->driver->check_timings(dssdev, &t);
142 if (r)
143 return r;
144
145 dssdev->driver->disable(dssdev);
146 dssdev->driver->set_timings(dssdev, &t);
147 r = dssdev->driver->enable(dssdev);
148 if (r)
149 return r;
150
151 return size;
152}
153
154static ssize_t display_rotate_show(struct device *dev,
155 struct device_attribute *attr, char *buf)
156{
157 struct omap_dss_device *dssdev = to_dss_device(dev);
158 int rotate;
159 if (!dssdev->driver->get_rotate)
160 return -ENOENT;
161 rotate = dssdev->driver->get_rotate(dssdev);
162 return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
163}
164
165static ssize_t display_rotate_store(struct device *dev,
166 struct device_attribute *attr, const char *buf, size_t size)
167{
168 struct omap_dss_device *dssdev = to_dss_device(dev);
169 int rot, r;
170
171 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
172 return -ENOENT;
173
174 r = kstrtoint(buf, 0, &rot);
175 if (r)
176 return r;
177
178 r = dssdev->driver->set_rotate(dssdev, rot);
179 if (r)
180 return r;
181
182 return size;
183}
184
185static ssize_t display_mirror_show(struct device *dev,
186 struct device_attribute *attr, char *buf)
187{
188 struct omap_dss_device *dssdev = to_dss_device(dev);
189 int mirror;
190 if (!dssdev->driver->get_mirror)
191 return -ENOENT;
192 mirror = dssdev->driver->get_mirror(dssdev);
193 return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
194}
195
196static ssize_t display_mirror_store(struct device *dev,
197 struct device_attribute *attr, const char *buf, size_t size)
198{
199 struct omap_dss_device *dssdev = to_dss_device(dev);
200 int r;
201 bool mirror;
202
203 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
204 return -ENOENT;
205
206 r = strtobool(buf, &mirror);
207 if (r)
208 return r;
209
210 r = dssdev->driver->set_mirror(dssdev, mirror);
211 if (r)
212 return r;
213
214 return size;
215}
216
217static ssize_t display_wss_show(struct device *dev,
218 struct device_attribute *attr, char *buf)
219{
220 struct omap_dss_device *dssdev = to_dss_device(dev);
221 unsigned int wss;
222
223 if (!dssdev->driver->get_wss)
224 return -ENOENT;
225
226 wss = dssdev->driver->get_wss(dssdev);
227
228 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
229}
230
231static ssize_t display_wss_store(struct device *dev,
232 struct device_attribute *attr, const char *buf, size_t size)
233{
234 struct omap_dss_device *dssdev = to_dss_device(dev);
235 u32 wss;
236 int r;
237
238 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
239 return -ENOENT;
240
241 r = kstrtou32(buf, 0, &wss);
242 if (r)
243 return r;
244
245 if (wss > 0xfffff)
246 return -EINVAL;
247
248 r = dssdev->driver->set_wss(dssdev, wss);
249 if (r)
250 return r;
251
252 return size;
253}
254
255static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
256 display_enabled_show, display_enabled_store);
257static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
258 display_tear_show, display_tear_store);
259static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
260 display_timings_show, display_timings_store);
261static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR,
262 display_rotate_show, display_rotate_store);
263static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
264 display_mirror_show, display_mirror_store);
265static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
266 display_wss_show, display_wss_store);
267
268static struct device_attribute *display_sysfs_attrs[] = {
269 &dev_attr_enabled,
270 &dev_attr_tear_elim,
271 &dev_attr_timings,
272 &dev_attr_rotate,
273 &dev_attr_mirror,
274 &dev_attr_wss,
275 NULL
276};
277
278void omapdss_default_get_resolution(struct omap_dss_device *dssdev, 34void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
279 u16 *xres, u16 *yres) 35 u16 *xres, u16 *yres)
280{ 36{
@@ -320,136 +76,8 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
320} 76}
321EXPORT_SYMBOL(omapdss_default_get_timings); 77EXPORT_SYMBOL(omapdss_default_get_timings);
322 78
323/*
324 * Connect dssdev to a manager if the manager is free or if force is specified.
325 * Connect all overlays to that manager if they are free or if force is
326 * specified.
327 */
328static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
329{
330 struct omap_dss_output *out;
331 struct omap_overlay_manager *mgr;
332 int i, r;
333
334 out = omapdss_get_output_from_dssdev(dssdev);
335
336 WARN_ON(dssdev->output);
337 WARN_ON(out->device);
338
339 r = omapdss_output_set_device(out, dssdev);
340 if (r) {
341 DSSERR("failed to connect output to new device\n");
342 return r;
343 }
344
345 mgr = omap_dss_get_overlay_manager(dssdev->channel);
346
347 if (mgr->output && !force)
348 return 0;
349
350 if (mgr->output)
351 mgr->unset_output(mgr);
352
353 r = mgr->set_output(mgr, out);
354 if (r) {
355 DSSERR("failed to connect manager to output of new device\n");
356
357 /* remove the output-device connection we just made */
358 omapdss_output_unset_device(out);
359 return r;
360 }
361
362 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
363 struct omap_overlay *ovl = omap_dss_get_overlay(i);
364
365 if (!ovl->manager || force) {
366 if (ovl->manager)
367 ovl->unset_manager(ovl);
368
369 r = ovl->set_manager(ovl, mgr);
370 if (r) {
371 DSSERR("failed to set initial overlay\n");
372 return r;
373 }
374 }
375 }
376
377 return 0;
378}
379
380static void dss_uninit_connections(struct omap_dss_device *dssdev)
381{
382 if (dssdev->output) {
383 struct omap_overlay_manager *mgr = dssdev->output->manager;
384
385 if (mgr)
386 mgr->unset_output(mgr);
387
388 omapdss_output_unset_device(dssdev->output);
389 }
390}
391
392int dss_init_device(struct platform_device *pdev,
393 struct omap_dss_device *dssdev)
394{
395 struct device_attribute *attr;
396 int i, r;
397 const char *def_disp_name = dss_get_default_display_name();
398 bool force;
399
400 force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0;
401 dss_init_connections(dssdev, force);
402
403 /* create device sysfs files */
404 i = 0;
405 while ((attr = display_sysfs_attrs[i++]) != NULL) {
406 r = device_create_file(&dssdev->dev, attr);
407 if (r) {
408 for (i = i - 2; i >= 0; i--) {
409 attr = display_sysfs_attrs[i];
410 device_remove_file(&dssdev->dev, attr);
411 }
412
413 dss_uninit_connections(dssdev);
414
415 DSSERR("failed to create sysfs file\n");
416 return r;
417 }
418 }
419
420 /* create display? sysfs links */
421 r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
422 dev_name(&dssdev->dev));
423 if (r) {
424 while ((attr = display_sysfs_attrs[i++]) != NULL)
425 device_remove_file(&dssdev->dev, attr);
426
427 dss_uninit_connections(dssdev);
428
429 DSSERR("failed to create sysfs display link\n");
430 return r;
431 }
432
433 return 0;
434}
435
436void dss_uninit_device(struct platform_device *pdev,
437 struct omap_dss_device *dssdev)
438{
439 struct device_attribute *attr;
440 int i = 0;
441
442 sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
443
444 while ((attr = display_sysfs_attrs[i++]) != NULL)
445 device_remove_file(&dssdev->dev, attr);
446
447 dss_uninit_connections(dssdev);
448}
449
450static int dss_suspend_device(struct device *dev, void *data) 79static int dss_suspend_device(struct device *dev, void *data)
451{ 80{
452 int r;
453 struct omap_dss_device *dssdev = to_dss_device(dev); 81 struct omap_dss_device *dssdev = to_dss_device(dev);
454 82
455 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { 83 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
@@ -457,15 +85,7 @@ static int dss_suspend_device(struct device *dev, void *data)
457 return 0; 85 return 0;
458 } 86 }
459 87
460 if (!dssdev->driver->suspend) { 88 dssdev->driver->disable(dssdev);
461 DSSERR("display '%s' doesn't implement suspend\n",
462 dssdev->name);
463 return -ENOSYS;
464 }
465
466 r = dssdev->driver->suspend(dssdev);
467 if (r)
468 return r;
469 89
470 dssdev->activate_after_resume = true; 90 dssdev->activate_after_resume = true;
471 91
@@ -492,8 +112,8 @@ static int dss_resume_device(struct device *dev, void *data)
492 int r; 112 int r;
493 struct omap_dss_device *dssdev = to_dss_device(dev); 113 struct omap_dss_device *dssdev = to_dss_device(dev);
494 114
495 if (dssdev->activate_after_resume && dssdev->driver->resume) { 115 if (dssdev->activate_after_resume) {
496 r = dssdev->driver->resume(dssdev); 116 r = dssdev->driver->enable(dssdev);
497 if (r) 117 if (r)
498 return r; 118 return r;
499 } 119 }
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 56748cf8760e..4af136a04e53 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -49,34 +49,53 @@ static struct {
49 struct omap_dss_output output; 49 struct omap_dss_output output;
50} dpi; 50} dpi;
51 51
52static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) 52static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
53{ 53{
54 int dsi_module; 54 /*
55 55 * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
56 dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1; 56 * would also be used for DISPC fclk. Meaning, when the DPI output is
57 * disabled, DISPC clock will be disabled, and TV out will stop.
58 */
59 switch (omapdss_get_version()) {
60 case OMAPDSS_VER_OMAP24xx:
61 case OMAPDSS_VER_OMAP34xx_ES1:
62 case OMAPDSS_VER_OMAP34xx_ES3:
63 case OMAPDSS_VER_OMAP3630:
64 case OMAPDSS_VER_AM35xx:
65 return NULL;
66 default:
67 break;
68 }
57 69
58 return dsi_get_dsidev_from_id(dsi_module); 70 switch (channel) {
71 case OMAP_DSS_CHANNEL_LCD:
72 return dsi_get_dsidev_from_id(0);
73 case OMAP_DSS_CHANNEL_LCD2:
74 return dsi_get_dsidev_from_id(1);
75 default:
76 return NULL;
77 }
59} 78}
60 79
61static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev) 80static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
62{ 81{
63 if (dssdev->clocks.dispc.dispc_fclk_src == 82 switch (channel) {
64 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC || 83 case OMAP_DSS_CHANNEL_LCD:
65 dssdev->clocks.dispc.dispc_fclk_src == 84 return OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC;
66 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC || 85 case OMAP_DSS_CHANNEL_LCD2:
67 dssdev->clocks.dispc.channel.lcd_clk_src == 86 return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
68 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC || 87 default:
69 dssdev->clocks.dispc.channel.lcd_clk_src == 88 /* this shouldn't happen */
70 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC) 89 WARN_ON(1);
71 return true; 90 return OMAP_DSS_CLK_SRC_FCK;
72 else 91 }
73 return false;
74} 92}
75 93
76static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, 94static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
77 unsigned long pck_req, unsigned long *fck, int *lck_div, 95 unsigned long pck_req, unsigned long *fck, int *lck_div,
78 int *pck_div) 96 int *pck_div)
79{ 97{
98 struct omap_overlay_manager *mgr = dssdev->output->manager;
80 struct dsi_clock_info dsi_cinfo; 99 struct dsi_clock_info dsi_cinfo;
81 struct dispc_clock_info dispc_cinfo; 100 struct dispc_clock_info dispc_cinfo;
82 int r; 101 int r;
@@ -90,7 +109,8 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
90 if (r) 109 if (r)
91 return r; 110 return r;
92 111
93 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); 112 dss_select_lcd_clk_source(mgr->id,
113 dpi_get_alt_clk_src(mgr->id));
94 114
95 dpi.mgr_config.clock_info = dispc_cinfo; 115 dpi.mgr_config.clock_info = dispc_cinfo;
96 116
@@ -135,7 +155,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
135 unsigned long pck; 155 unsigned long pck;
136 int r = 0; 156 int r = 0;
137 157
138 if (dpi_use_dsi_pll(dssdev)) 158 if (dpi.dsidev)
139 r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck, 159 r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
140 &lck_div, &pck_div); 160 &lck_div, &pck_div);
141 else 161 else
@@ -214,7 +234,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
214 if (r) 234 if (r)
215 goto err_src_sel; 235 goto err_src_sel;
216 236
217 if (dpi_use_dsi_pll(dssdev)) { 237 if (dpi.dsidev) {
218 r = dsi_runtime_get(dpi.dsidev); 238 r = dsi_runtime_get(dpi.dsidev);
219 if (r) 239 if (r)
220 goto err_get_dsi; 240 goto err_get_dsi;
@@ -242,10 +262,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
242 262
243err_mgr_enable: 263err_mgr_enable:
244err_set_mode: 264err_set_mode:
245 if (dpi_use_dsi_pll(dssdev)) 265 if (dpi.dsidev)
246 dsi_pll_uninit(dpi.dsidev, true); 266 dsi_pll_uninit(dpi.dsidev, true);
247err_dsi_pll_init: 267err_dsi_pll_init:
248 if (dpi_use_dsi_pll(dssdev)) 268 if (dpi.dsidev)
249 dsi_runtime_put(dpi.dsidev); 269 dsi_runtime_put(dpi.dsidev);
250err_get_dsi: 270err_get_dsi:
251err_src_sel: 271err_src_sel:
@@ -271,8 +291,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
271 291
272 dss_mgr_disable(mgr); 292 dss_mgr_disable(mgr);
273 293
274 if (dpi_use_dsi_pll(dssdev)) { 294 if (dpi.dsidev) {
275 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 295 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
276 dsi_pll_uninit(dpi.dsidev, true); 296 dsi_pll_uninit(dpi.dsidev, true);
277 dsi_runtime_put(dpi.dsidev); 297 dsi_runtime_put(dpi.dsidev);
278 } 298 }
@@ -311,13 +331,13 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
311 unsigned long pck; 331 unsigned long pck;
312 struct dispc_clock_info dispc_cinfo; 332 struct dispc_clock_info dispc_cinfo;
313 333
314 if (dss_mgr_check_timings(mgr, timings)) 334 if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
315 return -EINVAL; 335 return -EINVAL;
316 336
317 if (timings->pixel_clock == 0) 337 if (timings->pixel_clock == 0)
318 return -EINVAL; 338 return -EINVAL;
319 339
320 if (dpi_use_dsi_pll(dssdev)) { 340 if (dpi.dsidev) {
321 struct dsi_clock_info dsi_cinfo; 341 struct dsi_clock_info dsi_cinfo;
322 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, 342 r = dsi_pll_calc_clock_div_pck(dpi.dsidev,
323 timings->pixel_clock * 1000, 343 timings->pixel_clock * 1000,
@@ -359,8 +379,32 @@ void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
359} 379}
360EXPORT_SYMBOL(omapdss_dpi_set_data_lines); 380EXPORT_SYMBOL(omapdss_dpi_set_data_lines);
361 381
382static int __init dpi_verify_dsi_pll(struct platform_device *dsidev)
383{
384 int r;
385
386 /* do initial setup with the PLL to see if it is operational */
387
388 r = dsi_runtime_get(dsidev);
389 if (r)
390 return r;
391
392 r = dsi_pll_init(dsidev, 0, 1);
393 if (r) {
394 dsi_runtime_put(dsidev);
395 return r;
396 }
397
398 dsi_pll_uninit(dsidev, true);
399 dsi_runtime_put(dsidev);
400
401 return 0;
402}
403
362static int __init dpi_init_display(struct omap_dss_device *dssdev) 404static int __init dpi_init_display(struct omap_dss_device *dssdev)
363{ 405{
406 struct platform_device *dsidev;
407
364 DSSDBG("init_display\n"); 408 DSSDBG("init_display\n");
365 409
366 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && 410 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
@@ -377,19 +421,30 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
377 dpi.vdds_dsi_reg = vdds_dsi; 421 dpi.vdds_dsi_reg = vdds_dsi;
378 } 422 }
379 423
380 if (dpi_use_dsi_pll(dssdev)) { 424 /*
381 enum omap_dss_clk_source dispc_fclk_src = 425 * XXX We shouldn't need dssdev->channel for this. The dsi pll clock
382 dssdev->clocks.dispc.dispc_fclk_src; 426 * source for DPI is SoC integration detail, not something that should
383 dpi.dsidev = dpi_get_dsidev(dispc_fclk_src); 427 * be configured in the dssdev
428 */
429 dsidev = dpi_get_dsidev(dssdev->channel);
430
431 if (dsidev && dpi_verify_dsi_pll(dsidev)) {
432 dsidev = NULL;
433 DSSWARN("DSI PLL not operational\n");
384 } 434 }
385 435
436 if (dsidev)
437 DSSDBG("using DSI PLL for DPI clock\n");
438
439 dpi.dsidev = dsidev;
440
386 return 0; 441 return 0;
387} 442}
388 443
389static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev) 444static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
390{ 445{
391 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 446 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
392 const char *def_disp_name = dss_get_default_display_name(); 447 const char *def_disp_name = omapdss_get_default_display_name();
393 struct omap_dss_device *def_dssdev; 448 struct omap_dss_device *def_dssdev;
394 int i; 449 int i;
395 450
@@ -438,9 +493,18 @@ static void __init dpi_probe_pdata(struct platform_device *dpidev)
438 return; 493 return;
439 } 494 }
440 495
496 r = omapdss_output_set_device(&dpi.output, dssdev);
497 if (r) {
498 DSSERR("failed to connect output to new device: %s\n",
499 dssdev->name);
500 dss_put_device(dssdev);
501 return;
502 }
503
441 r = dss_add_device(dssdev); 504 r = dss_add_device(dssdev);
442 if (r) { 505 if (r) {
443 DSSERR("device %s register failed: %d\n", dssdev->name, r); 506 DSSERR("device %s register failed: %d\n", dssdev->name, r);
507 omapdss_output_unset_device(&dpi.output);
444 dss_put_device(dssdev); 508 dss_put_device(dssdev);
445 return; 509 return;
446 } 510 }
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index bee92846cfab..28d41d16b7be 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -45,7 +45,6 @@
45#include "dss.h" 45#include "dss.h"
46#include "dss_features.h" 46#include "dss_features.h"
47 47
48/*#define VERBOSE_IRQ*/
49#define DSI_CATCH_MISSING_TE 48#define DSI_CATCH_MISSING_TE
50 49
51struct dsi_reg { u16 idx; }; 50struct dsi_reg { u16 idx; };
@@ -535,42 +534,38 @@ static inline void dsi_perf_show(struct platform_device *dsidev,
535} 534}
536#endif 535#endif
537 536
537static int verbose_irq;
538
538static void print_irq_status(u32 status) 539static void print_irq_status(u32 status)
539{ 540{
540 if (status == 0) 541 if (status == 0)
541 return; 542 return;
542 543
543#ifndef VERBOSE_IRQ 544 if (!verbose_irq && (status & ~DSI_IRQ_CHANNEL_MASK) == 0)
544 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
545 return; 545 return;
546#endif
547 printk(KERN_DEBUG "DSI IRQ: 0x%x: ", status);
548 546
549#define PIS(x) \ 547#define PIS(x) (status & DSI_IRQ_##x) ? (#x " ") : ""
550 if (status & DSI_IRQ_##x) \ 548
551 printk(#x " "); 549 pr_debug("DSI IRQ: 0x%x: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
552#ifdef VERBOSE_IRQ 550 status,
553 PIS(VC0); 551 verbose_irq ? PIS(VC0) : "",
554 PIS(VC1); 552 verbose_irq ? PIS(VC1) : "",
555 PIS(VC2); 553 verbose_irq ? PIS(VC2) : "",
556 PIS(VC3); 554 verbose_irq ? PIS(VC3) : "",
557#endif 555 PIS(WAKEUP),
558 PIS(WAKEUP); 556 PIS(RESYNC),
559 PIS(RESYNC); 557 PIS(PLL_LOCK),
560 PIS(PLL_LOCK); 558 PIS(PLL_UNLOCK),
561 PIS(PLL_UNLOCK); 559 PIS(PLL_RECALL),
562 PIS(PLL_RECALL); 560 PIS(COMPLEXIO_ERR),
563 PIS(COMPLEXIO_ERR); 561 PIS(HS_TX_TIMEOUT),
564 PIS(HS_TX_TIMEOUT); 562 PIS(LP_RX_TIMEOUT),
565 PIS(LP_RX_TIMEOUT); 563 PIS(TE_TRIGGER),
566 PIS(TE_TRIGGER); 564 PIS(ACK_TRIGGER),
567 PIS(ACK_TRIGGER); 565 PIS(SYNC_LOST),
568 PIS(SYNC_LOST); 566 PIS(LDO_POWER_GOOD),
569 PIS(LDO_POWER_GOOD); 567 PIS(TA_TIMEOUT));
570 PIS(TA_TIMEOUT);
571#undef PIS 568#undef PIS
572
573 printk("\n");
574} 569}
575 570
576static void print_irq_status_vc(int channel, u32 status) 571static void print_irq_status_vc(int channel, u32 status)
@@ -578,28 +573,24 @@ static void print_irq_status_vc(int channel, u32 status)
578 if (status == 0) 573 if (status == 0)
579 return; 574 return;
580 575
581#ifndef VERBOSE_IRQ 576 if (!verbose_irq && (status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
582 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
583 return; 577 return;
584#endif
585 printk(KERN_DEBUG "DSI VC(%d) IRQ 0x%x: ", channel, status);
586 578
587#define PIS(x) \ 579#define PIS(x) (status & DSI_VC_IRQ_##x) ? (#x " ") : ""
588 if (status & DSI_VC_IRQ_##x) \ 580
589 printk(#x " "); 581 pr_debug("DSI VC(%d) IRQ 0x%x: %s%s%s%s%s%s%s%s%s\n",
590 PIS(CS); 582 channel,
591 PIS(ECC_CORR); 583 status,
592#ifdef VERBOSE_IRQ 584 PIS(CS),
593 PIS(PACKET_SENT); 585 PIS(ECC_CORR),
594#endif 586 PIS(ECC_NO_CORR),
595 PIS(FIFO_TX_OVF); 587 verbose_irq ? PIS(PACKET_SENT) : "",
596 PIS(FIFO_RX_OVF); 588 PIS(BTA),
597 PIS(BTA); 589 PIS(FIFO_TX_OVF),
598 PIS(ECC_NO_CORR); 590 PIS(FIFO_RX_OVF),
599 PIS(FIFO_TX_UDF); 591 PIS(FIFO_TX_UDF),
600 PIS(PP_BUSY_CHANGE); 592 PIS(PP_BUSY_CHANGE));
601#undef PIS 593#undef PIS
602 printk("\n");
603} 594}
604 595
605static void print_irq_status_cio(u32 status) 596static void print_irq_status_cio(u32 status)
@@ -607,34 +598,31 @@ static void print_irq_status_cio(u32 status)
607 if (status == 0) 598 if (status == 0)
608 return; 599 return;
609 600
610 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status); 601#define PIS(x) (status & DSI_CIO_IRQ_##x) ? (#x " ") : ""
611 602
612#define PIS(x) \ 603 pr_debug("DSI CIO IRQ 0x%x: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
613 if (status & DSI_CIO_IRQ_##x) \ 604 status,
614 printk(#x " "); 605 PIS(ERRSYNCESC1),
615 PIS(ERRSYNCESC1); 606 PIS(ERRSYNCESC2),
616 PIS(ERRSYNCESC2); 607 PIS(ERRSYNCESC3),
617 PIS(ERRSYNCESC3); 608 PIS(ERRESC1),
618 PIS(ERRESC1); 609 PIS(ERRESC2),
619 PIS(ERRESC2); 610 PIS(ERRESC3),
620 PIS(ERRESC3); 611 PIS(ERRCONTROL1),
621 PIS(ERRCONTROL1); 612 PIS(ERRCONTROL2),
622 PIS(ERRCONTROL2); 613 PIS(ERRCONTROL3),
623 PIS(ERRCONTROL3); 614 PIS(STATEULPS1),
624 PIS(STATEULPS1); 615 PIS(STATEULPS2),
625 PIS(STATEULPS2); 616 PIS(STATEULPS3),
626 PIS(STATEULPS3); 617 PIS(ERRCONTENTIONLP0_1),
627 PIS(ERRCONTENTIONLP0_1); 618 PIS(ERRCONTENTIONLP1_1),
628 PIS(ERRCONTENTIONLP1_1); 619 PIS(ERRCONTENTIONLP0_2),
629 PIS(ERRCONTENTIONLP0_2); 620 PIS(ERRCONTENTIONLP1_2),
630 PIS(ERRCONTENTIONLP1_2); 621 PIS(ERRCONTENTIONLP0_3),
631 PIS(ERRCONTENTIONLP0_3); 622 PIS(ERRCONTENTIONLP1_3),
632 PIS(ERRCONTENTIONLP1_3); 623 PIS(ULPSACTIVENOT_ALL0),
633 PIS(ULPSACTIVENOT_ALL0); 624 PIS(ULPSACTIVENOT_ALL1));
634 PIS(ULPSACTIVENOT_ALL1);
635#undef PIS 625#undef PIS
636
637 printk("\n");
638} 626}
639 627
640#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 628#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -1116,28 +1104,16 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
1116 } 1104 }
1117} 1105}
1118 1106
1119#ifdef DEBUG
1120static void _dsi_print_reset_status(struct platform_device *dsidev) 1107static void _dsi_print_reset_status(struct platform_device *dsidev)
1121{ 1108{
1122 u32 l; 1109 u32 l;
1123 int b0, b1, b2; 1110 int b0, b1, b2;
1124 1111
1125 if (!dss_debug)
1126 return;
1127
1128 /* A dummy read using the SCP interface to any DSIPHY register is 1112 /* A dummy read using the SCP interface to any DSIPHY register is
1129 * required after DSIPHY reset to complete the reset of the DSI complex 1113 * required after DSIPHY reset to complete the reset of the DSI complex
1130 * I/O. */ 1114 * I/O. */
1131 l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); 1115 l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
1132 1116
1133 printk(KERN_DEBUG "DSI resets: ");
1134
1135 l = dsi_read_reg(dsidev, DSI_PLL_STATUS);
1136 printk("PLL (%d) ", FLD_GET(l, 0, 0));
1137
1138 l = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
1139 printk("CIO (%d) ", FLD_GET(l, 29, 29));
1140
1141 if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) { 1117 if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
1142 b0 = 28; 1118 b0 = 28;
1143 b1 = 27; 1119 b1 = 27;
@@ -1148,18 +1124,21 @@ static void _dsi_print_reset_status(struct platform_device *dsidev)
1148 b2 = 26; 1124 b2 = 26;
1149 } 1125 }
1150 1126
1151 l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); 1127#define DSI_FLD_GET(fld, start, end)\
1152 printk("PHY (%x%x%x, %d, %d, %d)\n", 1128 FLD_GET(dsi_read_reg(dsidev, DSI_##fld), start, end)
1153 FLD_GET(l, b0, b0), 1129
1154 FLD_GET(l, b1, b1), 1130 pr_debug("DSI resets: PLL (%d) CIO (%d) PHY (%x%x%x, %d, %d, %d)\n",
1155 FLD_GET(l, b2, b2), 1131 DSI_FLD_GET(PLL_STATUS, 0, 0),
1156 FLD_GET(l, 29, 29), 1132 DSI_FLD_GET(COMPLEXIO_CFG1, 29, 29),
1157 FLD_GET(l, 30, 30), 1133 DSI_FLD_GET(DSIPHY_CFG5, b0, b0),
1158 FLD_GET(l, 31, 31)); 1134 DSI_FLD_GET(DSIPHY_CFG5, b1, b1),
1135 DSI_FLD_GET(DSIPHY_CFG5, b2, b2),
1136 DSI_FLD_GET(DSIPHY_CFG5, 29, 29),
1137 DSI_FLD_GET(DSIPHY_CFG5, 30, 30),
1138 DSI_FLD_GET(DSIPHY_CFG5, 31, 31));
1139
1140#undef DSI_FLD_GET
1159} 1141}
1160#else
1161#define _dsi_print_reset_status(x)
1162#endif
1163 1142
1164static inline int dsi_if_enable(struct platform_device *dsidev, bool enable) 1143static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
1165{ 1144{
@@ -1407,6 +1386,11 @@ retry:
1407 cur.dsi_pll_hsdiv_dispc_clk = 1386 cur.dsi_pll_hsdiv_dispc_clk =
1408 cur.clkin4ddr / cur.regm_dispc; 1387 cur.clkin4ddr / cur.regm_dispc;
1409 1388
1389 if (cur.regm_dispc > 1 &&
1390 cur.regm_dispc % 2 != 0 &&
1391 req_pck >= 1000000)
1392 continue;
1393
1410 /* this will narrow down the search a bit, 1394 /* this will narrow down the search a bit,
1411 * but still give pixclocks below what was 1395 * but still give pixclocks below what was
1412 * requested */ 1396 * requested */
@@ -1621,7 +1605,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
1621 u8 regn_start, regn_end, regm_start, regm_end; 1605 u8 regn_start, regn_end, regm_start, regm_end;
1622 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end; 1606 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
1623 1607
1624 DSSDBGF(); 1608 DSSDBG("DSI PLL clock config starts");
1625 1609
1626 dsi->current_cinfo.clkin = cinfo->clkin; 1610 dsi->current_cinfo.clkin = cinfo->clkin;
1627 dsi->current_cinfo.fint = cinfo->fint; 1611 dsi->current_cinfo.fint = cinfo->fint;
@@ -1757,11 +1741,21 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
1757 1741
1758 DSSDBG("PLL init\n"); 1742 DSSDBG("PLL init\n");
1759 1743
1744 /*
1745 * It seems that on many OMAPs we need to enable both to have a
1746 * functional HSDivider.
1747 */
1748 enable_hsclk = enable_hsdiv = true;
1749
1760 if (dsi->vdds_dsi_reg == NULL) { 1750 if (dsi->vdds_dsi_reg == NULL) {
1761 struct regulator *vdds_dsi; 1751 struct regulator *vdds_dsi;
1762 1752
1763 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); 1753 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
1764 1754
1755 /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
1756 if (IS_ERR(vdds_dsi))
1757 vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
1758
1765 if (IS_ERR(vdds_dsi)) { 1759 if (IS_ERR(vdds_dsi)) {
1766 DSSERR("can't get VDDS_DSI regulator\n"); 1760 DSSERR("can't get VDDS_DSI regulator\n");
1767 return PTR_ERR(vdds_dsi); 1761 return PTR_ERR(vdds_dsi);
@@ -2440,7 +2434,7 @@ static int dsi_cio_init(struct platform_device *dsidev)
2440 int r; 2434 int r;
2441 u32 l; 2435 u32 l;
2442 2436
2443 DSSDBGF(); 2437 DSSDBG("DSI CIO init starts");
2444 2438
2445 r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev)); 2439 r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
2446 if (r) 2440 if (r)
@@ -2791,7 +2785,7 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
2791{ 2785{
2792 u32 r; 2786 u32 r;
2793 2787
2794 DSSDBGF("%d", channel); 2788 DSSDBG("Initial config of virtual channel %d", channel);
2795 2789
2796 r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel)); 2790 r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
2797 2791
@@ -2823,7 +2817,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
2823 if (dsi->vc[channel].source == source) 2817 if (dsi->vc[channel].source == source)
2824 return 0; 2818 return 0;
2825 2819
2826 DSSDBGF("%d", channel); 2820 DSSDBG("Source config of virtual channel %d", channel);
2827 2821
2828 dsi_sync_vc(dsidev, channel); 2822 dsi_sync_vc(dsidev, channel);
2829 2823
@@ -3581,7 +3575,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
3581 int r, i; 3575 int r, i;
3582 unsigned mask; 3576 unsigned mask;
3583 3577
3584 DSSDBGF(); 3578 DSSDBG("Entering ULPS");
3585 3579
3586 WARN_ON(!dsi_bus_is_locked(dsidev)); 3580 WARN_ON(!dsi_bus_is_locked(dsidev));
3587 3581
@@ -4285,7 +4279,7 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
4285 unsigned long pck; 4279 unsigned long pck;
4286 int r; 4280 int r;
4287 4281
4288 DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk); 4282 DSSDBG("Setting DSI clocks: ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
4289 4283
4290 mutex_lock(&dsi->lock); 4284 mutex_lock(&dsi->lock);
4291 4285
@@ -4541,7 +4535,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
4541 dsi_handle_framedone(dsi->pdev, -ETIMEDOUT); 4535 dsi_handle_framedone(dsi->pdev, -ETIMEDOUT);
4542} 4536}
4543 4537
4544static void dsi_framedone_irq_callback(void *data, u32 mask) 4538static void dsi_framedone_irq_callback(void *data)
4545{ 4539{
4546 struct platform_device *dsidev = (struct platform_device *) data; 4540 struct platform_device *dsidev = (struct platform_device *) data;
4547 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4541 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -4615,7 +4609,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4615 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4609 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4616 struct omap_overlay_manager *mgr = dssdev->output->manager; 4610 struct omap_overlay_manager *mgr = dssdev->output->manager;
4617 int r; 4611 int r;
4618 u32 irq = 0;
4619 4612
4620 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { 4613 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
4621 dsi->timings.hsw = 1; 4614 dsi->timings.hsw = 1;
@@ -4625,12 +4618,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4625 dsi->timings.vfp = 0; 4618 dsi->timings.vfp = 0;
4626 dsi->timings.vbp = 0; 4619 dsi->timings.vbp = 0;
4627 4620
4628 irq = dispc_mgr_get_framedone_irq(mgr->id); 4621 r = dss_mgr_register_framedone_handler(mgr,
4629 4622 dsi_framedone_irq_callback, dsidev);
4630 r = omap_dispc_register_isr(dsi_framedone_irq_callback,
4631 (void *) dsidev, irq);
4632 if (r) { 4623 if (r) {
4633 DSSERR("can't get FRAMEDONE irq\n"); 4624 DSSERR("can't register FRAMEDONE handler\n");
4634 goto err; 4625 goto err;
4635 } 4626 }
4636 4627
@@ -4668,8 +4659,8 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4668 return 0; 4659 return 0;
4669err1: 4660err1:
4670 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) 4661 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
4671 omap_dispc_unregister_isr(dsi_framedone_irq_callback, 4662 dss_mgr_unregister_framedone_handler(mgr,
4672 (void *) dsidev, irq); 4663 dsi_framedone_irq_callback, dsidev);
4673err: 4664err:
4674 return r; 4665 return r;
4675} 4666}
@@ -4680,14 +4671,9 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
4680 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4671 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4681 struct omap_overlay_manager *mgr = dssdev->output->manager; 4672 struct omap_overlay_manager *mgr = dssdev->output->manager;
4682 4673
4683 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { 4674 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
4684 u32 irq; 4675 dss_mgr_unregister_framedone_handler(mgr,
4685 4676 dsi_framedone_irq_callback, dsidev);
4686 irq = dispc_mgr_get_framedone_irq(mgr->id);
4687
4688 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4689 (void *) dsidev, irq);
4690 }
4691} 4677}
4692 4678
4693static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) 4679static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
@@ -4730,7 +4716,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4730 if (r) 4716 if (r)
4731 goto err1; 4717 goto err1;
4732 4718
4733 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
4734 dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); 4719 dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);
4735 dss_select_lcd_clk_source(mgr->id, 4720 dss_select_lcd_clk_source(mgr->id,
4736 dssdev->clocks.dispc.channel.lcd_clk_src); 4721 dssdev->clocks.dispc.channel.lcd_clk_src);
@@ -4765,7 +4750,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4765err3: 4750err3:
4766 dsi_cio_uninit(dsidev); 4751 dsi_cio_uninit(dsidev);
4767err2: 4752err2:
4768 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
4769 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4753 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
4770 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); 4754 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
4771 4755
@@ -4792,7 +4776,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
4792 dsi_vc_enable(dsidev, 2, 0); 4776 dsi_vc_enable(dsidev, 2, 0);
4793 dsi_vc_enable(dsidev, 3, 0); 4777 dsi_vc_enable(dsidev, 3, 0);
4794 4778
4795 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
4796 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4779 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
4797 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); 4780 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
4798 dsi_cio_uninit(dsidev); 4781 dsi_cio_uninit(dsidev);
@@ -4981,6 +4964,10 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
4981 4964
4982 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); 4965 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
4983 4966
4967 /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
4968 if (IS_ERR(vdds_dsi))
4969 vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
4970
4984 if (IS_ERR(vdds_dsi)) { 4971 if (IS_ERR(vdds_dsi)) {
4985 DSSERR("can't get VDDS_DSI regulator\n"); 4972 DSSERR("can't get VDDS_DSI regulator\n");
4986 return PTR_ERR(vdds_dsi); 4973 return PTR_ERR(vdds_dsi);
@@ -5121,7 +5108,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p
5121{ 5108{
5122 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 5109 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
5123 struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); 5110 struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
5124 const char *def_disp_name = dss_get_default_display_name(); 5111 const char *def_disp_name = omapdss_get_default_display_name();
5125 struct omap_dss_device *def_dssdev; 5112 struct omap_dss_device *def_dssdev;
5126 int i; 5113 int i;
5127 5114
@@ -5151,6 +5138,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p
5151 5138
5152static void __init dsi_probe_pdata(struct platform_device *dsidev) 5139static void __init dsi_probe_pdata(struct platform_device *dsidev)
5153{ 5140{
5141 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5154 struct omap_dss_device *plat_dssdev; 5142 struct omap_dss_device *plat_dssdev;
5155 struct omap_dss_device *dssdev; 5143 struct omap_dss_device *dssdev;
5156 int r; 5144 int r;
@@ -5173,9 +5161,18 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
5173 return; 5161 return;
5174 } 5162 }
5175 5163
5164 r = omapdss_output_set_device(&dsi->output, dssdev);
5165 if (r) {
5166 DSSERR("failed to connect output to new device: %s\n",
5167 dssdev->name);
5168 dss_put_device(dssdev);
5169 return;
5170 }
5171
5176 r = dss_add_device(dssdev); 5172 r = dss_add_device(dssdev);
5177 if (r) { 5173 if (r) {
5178 DSSERR("device %s register failed: %d\n", dssdev->name, r); 5174 DSSERR("device %s register failed: %d\n", dssdev->name, r);
5175 omapdss_output_unset_device(&dsi->output);
5179 dss_put_device(dssdev); 5176 dss_put_device(dssdev);
5180 return; 5177 return;
5181 } 5178 }
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 602102cebcbf..054c2a22b3f1 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -32,6 +32,7 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
34#include <linux/gfp.h> 34#include <linux/gfp.h>
35#include <linux/sizes.h>
35 36
36#include <video/omapdss.h> 37#include <video/omapdss.h>
37 38
@@ -76,6 +77,7 @@ static struct {
76 77
77 struct clk *dpll4_m4_ck; 78 struct clk *dpll4_m4_ck;
78 struct clk *dss_clk; 79 struct clk *dss_clk;
80 unsigned long dss_clk_rate;
79 81
80 unsigned long cache_req_pck; 82 unsigned long cache_req_pck;
81 unsigned long cache_prate; 83 unsigned long cache_prate;
@@ -96,6 +98,8 @@ static const char * const dss_generic_clk_source_names[] = {
96 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC", 98 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
97 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI", 99 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
98 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", 100 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK",
101 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC",
102 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI",
99}; 103};
100 104
101static inline void dss_write_reg(const struct dss_reg idx, u32 val) 105static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -151,6 +155,21 @@ static void dss_restore_context(void)
151#undef SR 155#undef SR
152#undef RR 156#undef RR
153 157
158int dss_get_ctx_loss_count(void)
159{
160 struct omap_dss_board_info *board_data = dss.pdev->dev.platform_data;
161 int cnt;
162
163 if (!board_data->get_context_loss_count)
164 return -ENOENT;
165
166 cnt = board_data->get_context_loss_count(&dss.pdev->dev);
167
168 WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
169
170 return cnt;
171}
172
154void dss_sdi_init(int datapairs) 173void dss_sdi_init(int datapairs)
155{ 174{
156 u32 l; 175 u32 l;
@@ -301,7 +320,7 @@ static void dss_dump_regs(struct seq_file *s)
301#undef DUMPREG 320#undef DUMPREG
302} 321}
303 322
304void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src) 323static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
305{ 324{
306 struct platform_device *dsidev; 325 struct platform_device *dsidev;
307 int b; 326 int b;
@@ -372,8 +391,10 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
372 struct platform_device *dsidev; 391 struct platform_device *dsidev;
373 int b, ix, pos; 392 int b, ix, pos;
374 393
375 if (!dss_has_feature(FEAT_LCD_CLK_SRC)) 394 if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
395 dss_select_dispc_clk_source(clk_src);
376 return; 396 return;
397 }
377 398
378 switch (clk_src) { 399 switch (clk_src) {
379 case OMAP_DSS_CLK_SRC_FCK: 400 case OMAP_DSS_CLK_SRC_FCK:
@@ -429,6 +450,29 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
429 } 450 }
430} 451}
431 452
453/* calculate clock rates using dividers in cinfo */
454int dss_calc_clock_rates(struct dss_clock_info *cinfo)
455{
456 if (dss.dpll4_m4_ck) {
457 unsigned long prate;
458
459 if (cinfo->fck_div > dss.feat->fck_div_max ||
460 cinfo->fck_div == 0)
461 return -EINVAL;
462
463 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
464
465 cinfo->fck = prate / cinfo->fck_div *
466 dss.feat->dss_fck_multiplier;
467 } else {
468 if (cinfo->fck_div != 0)
469 return -EINVAL;
470 cinfo->fck = clk_get_rate(dss.dss_clk);
471 }
472
473 return 0;
474}
475
432int dss_set_clock_div(struct dss_clock_info *cinfo) 476int dss_set_clock_div(struct dss_clock_info *cinfo)
433{ 477{
434 if (dss.dpll4_m4_ck) { 478 if (dss.dpll4_m4_ck) {
@@ -446,6 +490,10 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
446 return -EINVAL; 490 return -EINVAL;
447 } 491 }
448 492
493 dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
494
495 WARN_ONCE(dss.dss_clk_rate != cinfo->fck, "clk rate mismatch");
496
449 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); 497 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
450 498
451 return 0; 499 return 0;
@@ -459,6 +507,41 @@ unsigned long dss_get_dpll4_rate(void)
459 return 0; 507 return 0;
460} 508}
461 509
510unsigned long dss_get_dispc_clk_rate(void)
511{
512 return dss.dss_clk_rate;
513}
514
515static int dss_setup_default_clock(void)
516{
517 unsigned long max_dss_fck, prate;
518 unsigned fck_div;
519 struct dss_clock_info dss_cinfo = { 0 };
520 int r;
521
522 if (dss.dpll4_m4_ck == NULL)
523 return 0;
524
525 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
526
527 prate = dss_get_dpll4_rate();
528
529 fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
530 max_dss_fck);
531
532 dss_cinfo.fck_div = fck_div;
533
534 r = dss_calc_clock_rates(&dss_cinfo);
535 if (r)
536 return r;
537
538 r = dss_set_clock_div(&dss_cinfo);
539 if (r)
540 return r;
541
542 return 0;
543}
544
462int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, 545int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
463 struct dispc_clock_info *dispc_cinfo) 546 struct dispc_clock_info *dispc_cinfo)
464{ 547{
@@ -748,7 +831,7 @@ static void dss_runtime_put(void)
748} 831}
749 832
750/* DEBUGFS */ 833/* DEBUGFS */
751#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 834#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
752void dss_debug_dump_clocks(struct seq_file *s) 835void dss_debug_dump_clocks(struct seq_file *s)
753{ 836{
754 dss_dump_clocks(s); 837 dss_dump_clocks(s);
@@ -796,7 +879,6 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
796 879
797static int __init dss_init_features(struct platform_device *pdev) 880static int __init dss_init_features(struct platform_device *pdev)
798{ 881{
799 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
800 const struct dss_features *src; 882 const struct dss_features *src;
801 struct dss_features *dst; 883 struct dss_features *dst;
802 884
@@ -806,7 +888,7 @@ static int __init dss_init_features(struct platform_device *pdev)
806 return -ENOMEM; 888 return -ENOMEM;
807 } 889 }
808 890
809 switch (pdata->version) { 891 switch (omapdss_get_version()) {
810 case OMAPDSS_VER_OMAP24xx: 892 case OMAPDSS_VER_OMAP24xx:
811 src = &omap24xx_dss_feats; 893 src = &omap24xx_dss_feats;
812 break; 894 break;
@@ -871,15 +953,23 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
871 if (r) 953 if (r)
872 return r; 954 return r;
873 955
956 r = dss_setup_default_clock();
957 if (r)
958 goto err_setup_clocks;
959
874 pm_runtime_enable(&pdev->dev); 960 pm_runtime_enable(&pdev->dev);
875 961
876 r = dss_runtime_get(); 962 r = dss_runtime_get();
877 if (r) 963 if (r)
878 goto err_runtime_get; 964 goto err_runtime_get;
879 965
966 dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
967
880 /* Select DPLL */ 968 /* Select DPLL */
881 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); 969 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
882 970
971 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
972
883#ifdef CONFIG_OMAP2_DSS_VENC 973#ifdef CONFIG_OMAP2_DSS_VENC
884 REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ 974 REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
885 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ 975 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
@@ -903,6 +993,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
903 993
904err_runtime_get: 994err_runtime_get:
905 pm_runtime_disable(&pdev->dev); 995 pm_runtime_disable(&pdev->dev);
996err_setup_clocks:
906 dss_put_clocks(); 997 dss_put_clocks();
907 return r; 998 return r;
908} 999}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 6728892f9dad..610c8e563daa 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -23,44 +23,20 @@
23#ifndef __OMAP2_DSS_H 23#ifndef __OMAP2_DSS_H
24#define __OMAP2_DSS_H 24#define __OMAP2_DSS_H
25 25
26#ifdef CONFIG_OMAP2_DSS_DEBUG_SUPPORT 26#include <linux/interrupt.h>
27#define DEBUG
28#endif
29 27
30#ifdef DEBUG 28#ifdef pr_fmt
31extern bool dss_debug; 29#undef pr_fmt
32#ifdef DSS_SUBSYS_NAME
33#define DSSDBG(format, ...) \
34 if (dss_debug) \
35 printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME ": " format, \
36 ## __VA_ARGS__)
37#else
38#define DSSDBG(format, ...) \
39 if (dss_debug) \
40 printk(KERN_DEBUG "omapdss: " format, ## __VA_ARGS__)
41#endif 30#endif
42 31
43#ifdef DSS_SUBSYS_NAME 32#ifdef DSS_SUBSYS_NAME
44#define DSSDBGF(format, ...) \ 33#define pr_fmt(fmt) DSS_SUBSYS_NAME ": " fmt
45 if (dss_debug) \
46 printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME \
47 ": %s(" format ")\n", \
48 __func__, \
49 ## __VA_ARGS__)
50#else 34#else
51#define DSSDBGF(format, ...) \ 35#define pr_fmt(fmt) fmt
52 if (dss_debug) \
53 printk(KERN_DEBUG "omapdss: " \
54 ": %s(" format ")\n", \
55 __func__, \
56 ## __VA_ARGS__)
57#endif
58
59#else /* DEBUG */
60#define DSSDBG(format, ...)
61#define DSSDBGF(format, ...)
62#endif 36#endif
63 37
38#define DSSDBG(format, ...) \
39 pr_debug(format, ## __VA_ARGS__)
64 40
65#ifdef DSS_SUBSYS_NAME 41#ifdef DSS_SUBSYS_NAME
66#define DSSERR(format, ...) \ 42#define DSSERR(format, ...) \
@@ -186,11 +162,10 @@ struct seq_file;
186struct platform_device; 162struct platform_device;
187 163
188/* core */ 164/* core */
189const char *dss_get_default_display_name(void); 165struct platform_device *dss_get_core_pdev(void);
190struct bus_type *dss_get_bus(void); 166struct bus_type *dss_get_bus(void);
191struct regulator *dss_get_vdds_dsi(void); 167struct regulator *dss_get_vdds_dsi(void);
192struct regulator *dss_get_vdds_sdi(void); 168struct regulator *dss_get_vdds_sdi(void);
193int dss_get_ctx_loss_count(struct device *dev);
194int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask); 169int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask);
195void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); 170void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
196int dss_set_min_bus_tput(struct device *dev, unsigned long tput); 171int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
@@ -204,55 +179,18 @@ void dss_put_device(struct omap_dss_device *dssdev);
204void dss_copy_device_pdata(struct omap_dss_device *dst, 179void dss_copy_device_pdata(struct omap_dss_device *dst,
205 const struct omap_dss_device *src); 180 const struct omap_dss_device *src);
206 181
207/* apply */
208void dss_apply_init(void);
209int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr);
210int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
211void dss_mgr_start_update(struct omap_overlay_manager *mgr);
212int omap_dss_mgr_apply(struct omap_overlay_manager *mgr);
213
214int dss_mgr_enable(struct omap_overlay_manager *mgr);
215void dss_mgr_disable(struct omap_overlay_manager *mgr);
216int dss_mgr_set_info(struct omap_overlay_manager *mgr,
217 struct omap_overlay_manager_info *info);
218void dss_mgr_get_info(struct omap_overlay_manager *mgr,
219 struct omap_overlay_manager_info *info);
220int dss_mgr_set_device(struct omap_overlay_manager *mgr,
221 struct omap_dss_device *dssdev);
222int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
223int dss_mgr_set_output(struct omap_overlay_manager *mgr,
224 struct omap_dss_output *output);
225int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
226void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
227 const struct omap_video_timings *timings);
228void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
229 const struct dss_lcd_mgr_config *config);
230const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
231
232bool dss_ovl_is_enabled(struct omap_overlay *ovl);
233int dss_ovl_enable(struct omap_overlay *ovl);
234int dss_ovl_disable(struct omap_overlay *ovl);
235int dss_ovl_set_info(struct omap_overlay *ovl,
236 struct omap_overlay_info *info);
237void dss_ovl_get_info(struct omap_overlay *ovl,
238 struct omap_overlay_info *info);
239int dss_ovl_set_manager(struct omap_overlay *ovl,
240 struct omap_overlay_manager *mgr);
241int dss_ovl_unset_manager(struct omap_overlay *ovl);
242
243/* output */ 182/* output */
244void dss_register_output(struct omap_dss_output *out); 183void dss_register_output(struct omap_dss_output *out);
245void dss_unregister_output(struct omap_dss_output *out); 184void dss_unregister_output(struct omap_dss_output *out);
246struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev);
247 185
248/* display */ 186/* display */
249int dss_suspend_all_devices(void); 187int dss_suspend_all_devices(void);
250int dss_resume_all_devices(void); 188int dss_resume_all_devices(void);
251void dss_disable_all_devices(void); 189void dss_disable_all_devices(void);
252 190
253int dss_init_device(struct platform_device *pdev, 191int display_init_sysfs(struct platform_device *pdev,
254 struct omap_dss_device *dssdev); 192 struct omap_dss_device *dssdev);
255void dss_uninit_device(struct platform_device *pdev, 193void display_uninit_sysfs(struct platform_device *pdev,
256 struct omap_dss_device *dssdev); 194 struct omap_dss_device *dssdev);
257 195
258/* manager */ 196/* manager */
@@ -299,21 +237,23 @@ void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
299int dss_init_platform_driver(void) __init; 237int dss_init_platform_driver(void) __init;
300void dss_uninit_platform_driver(void); 238void dss_uninit_platform_driver(void);
301 239
240unsigned long dss_get_dispc_clk_rate(void);
302int dss_dpi_select_source(enum omap_channel channel); 241int dss_dpi_select_source(enum omap_channel channel);
303void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 242void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
304enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); 243enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
305const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 244const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
306void dss_dump_clocks(struct seq_file *s); 245void dss_dump_clocks(struct seq_file *s);
307 246
308#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 247#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
309void dss_debug_dump_clocks(struct seq_file *s); 248void dss_debug_dump_clocks(struct seq_file *s);
310#endif 249#endif
311 250
251int dss_get_ctx_loss_count(void);
252
312void dss_sdi_init(int datapairs); 253void dss_sdi_init(int datapairs);
313int dss_sdi_enable(void); 254int dss_sdi_enable(void);
314void dss_sdi_disable(void); 255void dss_sdi_disable(void);
315 256
316void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src);
317void dss_select_dsi_clk_source(int dsi_module, 257void dss_select_dsi_clk_source(int dsi_module,
318 enum omap_dss_clk_source clk_src); 258 enum omap_dss_clk_source clk_src);
319void dss_select_lcd_clk_source(enum omap_channel channel, 259void dss_select_lcd_clk_source(enum omap_channel channel,
@@ -326,6 +266,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
326void dss_set_dac_pwrdn_bgz(bool enable); 266void dss_set_dac_pwrdn_bgz(bool enable);
327 267
328unsigned long dss_get_dpll4_rate(void); 268unsigned long dss_get_dpll4_rate(void);
269int dss_calc_clock_rates(struct dss_clock_info *cinfo);
329int dss_set_clock_div(struct dss_clock_info *cinfo); 270int dss_set_clock_div(struct dss_clock_info *cinfo);
330int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, 271int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
331 struct dispc_clock_info *dispc_cinfo); 272 struct dispc_clock_info *dispc_cinfo);
@@ -413,8 +354,6 @@ static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
413} 354}
414static inline struct platform_device *dsi_get_dsidev_from_id(int module) 355static inline struct platform_device *dsi_get_dsidev_from_id(int module)
415{ 356{
416 WARN("%s: DSI not compiled in, returning platform device as NULL\n",
417 __func__);
418 return NULL; 357 return NULL;
419} 358}
420#endif 359#endif
@@ -427,15 +366,10 @@ void dpi_uninit_platform_driver(void) __exit;
427int dispc_init_platform_driver(void) __init; 366int dispc_init_platform_driver(void) __init;
428void dispc_uninit_platform_driver(void) __exit; 367void dispc_uninit_platform_driver(void) __exit;
429void dispc_dump_clocks(struct seq_file *s); 368void dispc_dump_clocks(struct seq_file *s);
430void dispc_irq_handler(void);
431
432int dispc_runtime_get(void);
433void dispc_runtime_put(void);
434 369
435void dispc_enable_sidle(void); 370void dispc_enable_sidle(void);
436void dispc_disable_sidle(void); 371void dispc_disable_sidle(void);
437 372
438void dispc_lcd_enable_signal_polarity(bool act_high);
439void dispc_lcd_enable_signal(bool enable); 373void dispc_lcd_enable_signal(bool enable);
440void dispc_pck_free_enable(bool enable); 374void dispc_pck_free_enable(bool enable);
441void dispc_enable_fifomerge(bool enable); 375void dispc_enable_fifomerge(bool enable);
@@ -455,36 +389,14 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
455void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, 389void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
456 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, 390 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
457 bool manual_update); 391 bool manual_update);
458int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, 392
459 bool replication, const struct omap_video_timings *mgr_timings,
460 bool mem_to_mem);
461int dispc_ovl_enable(enum omap_plane plane, bool enable);
462void dispc_ovl_set_channel_out(enum omap_plane plane,
463 enum omap_channel channel);
464
465void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
466u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
467u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
468bool dispc_mgr_go_busy(enum omap_channel channel);
469void dispc_mgr_go(enum omap_channel channel);
470bool dispc_mgr_is_enabled(enum omap_channel channel);
471void dispc_mgr_enable(enum omap_channel channel, bool enable);
472bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
473void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
474void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
475void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
476void dispc_mgr_set_lcd_type_tft(enum omap_channel channel);
477void dispc_mgr_set_timings(enum omap_channel channel,
478 struct omap_video_timings *timings);
479unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); 393unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
480unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); 394unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
481unsigned long dispc_core_clk_rate(void); 395unsigned long dispc_core_clk_rate(void);
482void dispc_mgr_set_clock_div(enum omap_channel channel, 396void dispc_mgr_set_clock_div(enum omap_channel channel,
483 struct dispc_clock_info *cinfo); 397 const struct dispc_clock_info *cinfo);
484int dispc_mgr_get_clock_div(enum omap_channel channel, 398int dispc_mgr_get_clock_div(enum omap_channel channel,
485 struct dispc_clock_info *cinfo); 399 struct dispc_clock_info *cinfo);
486void dispc_mgr_setup(enum omap_channel channel,
487 struct omap_overlay_manager_info *info);
488 400
489u32 dispc_wb_get_framedone_irq(void); 401u32 dispc_wb_get_framedone_irq(void);
490bool dispc_wb_go_busy(void); 402bool dispc_wb_go_busy(void);
@@ -536,6 +448,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
536#endif 448#endif
537int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); 449int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
538void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); 450void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
451int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev);
452void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev);
539void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, 453void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
540 struct omap_video_timings *timings); 454 struct omap_video_timings *timings);
541int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, 455int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 3e8287c8709d..18688c12e30d 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/module.h>
21#include <linux/types.h> 22#include <linux/types.h>
22#include <linux/err.h> 23#include <linux/err.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
@@ -429,8 +430,6 @@ static const struct dss_param_range omap2_dss_param_range[] = {
429 * scaler cannot scale a image with width more than 768. 430 * scaler cannot scale a image with width more than 768.
430 */ 431 */
431 [FEAT_PARAM_LINEWIDTH] = { 1, 768 }, 432 [FEAT_PARAM_LINEWIDTH] = { 1, 768 },
432 [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
433 [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
434}; 433};
435 434
436static const struct dss_param_range omap3_dss_param_range[] = { 435static const struct dss_param_range omap3_dss_param_range[] = {
@@ -445,8 +444,6 @@ static const struct dss_param_range omap3_dss_param_range[] = {
445 [FEAT_PARAM_DSI_FCK] = { 0, 173000000 }, 444 [FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
446 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 445 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
447 [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, 446 [FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
448 [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
449 [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
450}; 447};
451 448
452static const struct dss_param_range omap4_dss_param_range[] = { 449static const struct dss_param_range omap4_dss_param_range[] = {
@@ -461,8 +458,6 @@ static const struct dss_param_range omap4_dss_param_range[] = {
461 [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, 458 [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
462 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 459 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
463 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 460 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
464 [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
465 [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
466}; 461};
467 462
468static const struct dss_param_range omap5_dss_param_range[] = { 463static const struct dss_param_range omap5_dss_param_range[] = {
@@ -477,8 +472,6 @@ static const struct dss_param_range omap5_dss_param_range[] = {
477 [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, 472 [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
478 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 473 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
479 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 474 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
480 [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
481 [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
482}; 475};
483 476
484static const enum dss_feat_id omap2_dss_feat_list[] = { 477static const enum dss_feat_id omap2_dss_feat_list[] = {
@@ -820,6 +813,7 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
820 .audio_start = ti_hdmi_4xxx_audio_start, 813 .audio_start = ti_hdmi_4xxx_audio_start,
821 .audio_stop = ti_hdmi_4xxx_audio_stop, 814 .audio_stop = ti_hdmi_4xxx_audio_stop,
822 .audio_config = ti_hdmi_4xxx_audio_config, 815 .audio_config = ti_hdmi_4xxx_audio_config,
816 .audio_get_dma_port = ti_hdmi_4xxx_audio_get_dma_port,
823#endif 817#endif
824 818
825}; 819};
@@ -846,11 +840,13 @@ int dss_feat_get_num_mgrs(void)
846{ 840{
847 return omap_current_dss_features->num_mgrs; 841 return omap_current_dss_features->num_mgrs;
848} 842}
843EXPORT_SYMBOL(dss_feat_get_num_mgrs);
849 844
850int dss_feat_get_num_ovls(void) 845int dss_feat_get_num_ovls(void)
851{ 846{
852 return omap_current_dss_features->num_ovls; 847 return omap_current_dss_features->num_ovls;
853} 848}
849EXPORT_SYMBOL(dss_feat_get_num_ovls);
854 850
855int dss_feat_get_num_wbs(void) 851int dss_feat_get_num_wbs(void)
856{ 852{
@@ -871,16 +867,19 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
871{ 867{
872 return omap_current_dss_features->supported_displays[channel]; 868 return omap_current_dss_features->supported_displays[channel];
873} 869}
870EXPORT_SYMBOL(dss_feat_get_supported_displays);
874 871
875enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel) 872enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
876{ 873{
877 return omap_current_dss_features->supported_outputs[channel]; 874 return omap_current_dss_features->supported_outputs[channel];
878} 875}
876EXPORT_SYMBOL(dss_feat_get_supported_outputs);
879 877
880enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane) 878enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
881{ 879{
882 return omap_current_dss_features->supported_color_modes[plane]; 880 return omap_current_dss_features->supported_color_modes[plane];
883} 881}
882EXPORT_SYMBOL(dss_feat_get_supported_color_modes);
884 883
885enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane) 884enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane)
886{ 885{
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index fc492ef72a51..489b9bec4a6d 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -98,19 +98,12 @@ enum dss_range_param {
98 FEAT_PARAM_DSI_FCK, 98 FEAT_PARAM_DSI_FCK,
99 FEAT_PARAM_DOWNSCALE, 99 FEAT_PARAM_DOWNSCALE,
100 FEAT_PARAM_LINEWIDTH, 100 FEAT_PARAM_LINEWIDTH,
101 FEAT_PARAM_MGR_WIDTH,
102 FEAT_PARAM_MGR_HEIGHT,
103}; 101};
104 102
105/* DSS Feature Functions */ 103/* DSS Feature Functions */
106int dss_feat_get_num_mgrs(void);
107int dss_feat_get_num_ovls(void);
108int dss_feat_get_num_wbs(void); 104int dss_feat_get_num_wbs(void);
109unsigned long dss_feat_get_param_min(enum dss_range_param param); 105unsigned long dss_feat_get_param_min(enum dss_range_param param);
110unsigned long dss_feat_get_param_max(enum dss_range_param param); 106unsigned long dss_feat_get_param_max(enum dss_range_param param);
111enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
112enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
113enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
114enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); 107enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
115bool dss_feat_color_mode_supported(enum omap_plane plane, 108bool dss_feat_color_mode_supported(enum omap_plane plane,
116 enum omap_color_mode color_mode); 109 enum omap_color_mode color_mode);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0d6d7213a858..769d0828581c 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -60,6 +60,7 @@
60static struct { 60static struct {
61 struct mutex lock; 61 struct mutex lock;
62 struct platform_device *pdev; 62 struct platform_device *pdev;
63
63 struct hdmi_ip_data ip_data; 64 struct hdmi_ip_data ip_data;
64 65
65 struct clk *sys_clk; 66 struct clk *sys_clk;
@@ -295,6 +296,12 @@ static const struct hdmi_config vesa_timings[] = {
295 false, }, 296 false, },
296 { 0x55, HDMI_DVI }, 297 { 0x55, HDMI_DVI },
297 }, 298 },
299 {
300 { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26,
301 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
302 false, },
303 { 0x44, HDMI_DVI },
304 },
298}; 305};
299 306
300static int hdmi_runtime_get(void) 307static int hdmi_runtime_get(void)
@@ -323,7 +330,6 @@ static void hdmi_runtime_put(void)
323 330
324static int __init hdmi_init_display(struct omap_dss_device *dssdev) 331static int __init hdmi_init_display(struct omap_dss_device *dssdev)
325{ 332{
326 struct omap_dss_board_info *pdata = hdmi.pdev->dev.platform_data;
327 int r; 333 int r;
328 334
329 struct gpio gpios[] = { 335 struct gpio gpios[] = {
@@ -334,13 +340,17 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)
334 340
335 DSSDBG("init_display\n"); 341 DSSDBG("init_display\n");
336 342
337 dss_init_hdmi_ip_ops(&hdmi.ip_data, pdata->version); 343 dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
338 344
339 if (hdmi.vdda_hdmi_dac_reg == NULL) { 345 if (hdmi.vdda_hdmi_dac_reg == NULL) {
340 struct regulator *reg; 346 struct regulator *reg;
341 347
342 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); 348 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
343 349
350 /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
351 if (IS_ERR(reg))
352 reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
353
344 if (IS_ERR(reg)) { 354 if (IS_ERR(reg)) {
345 DSSERR("can't get VDDA_HDMI_DAC regulator\n"); 355 DSSERR("can't get VDDA_HDMI_DAC regulator\n");
346 return PTR_ERR(reg); 356 return PTR_ERR(reg);
@@ -356,7 +366,7 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)
356 return 0; 366 return 0;
357} 367}
358 368
359static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev) 369static void hdmi_uninit_display(struct omap_dss_device *dssdev)
360{ 370{
361 DSSDBG("uninit_display\n"); 371 DSSDBG("uninit_display\n");
362 372
@@ -399,7 +409,8 @@ static bool hdmi_timings_compare(struct omap_video_timings *timing1,
399{ 409{
400 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; 410 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
401 411
402 if ((timing2->pixel_clock == timing1->pixel_clock) && 412 if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
413 DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
403 (timing2->x_res == timing1->x_res) && 414 (timing2->x_res == timing1->x_res) &&
404 (timing2->y_res == timing1->y_res)) { 415 (timing2->y_res == timing1->y_res)) {
405 416
@@ -501,12 +512,9 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
501 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); 512 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
502} 513}
503 514
504static int hdmi_power_on(struct omap_dss_device *dssdev) 515static int hdmi_power_on_core(struct omap_dss_device *dssdev)
505{ 516{
506 int r; 517 int r;
507 struct omap_video_timings *p;
508 struct omap_overlay_manager *mgr = dssdev->output->manager;
509 unsigned long phy;
510 518
511 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); 519 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
512 gpio_set_value(hdmi.ls_oe_gpio, 1); 520 gpio_set_value(hdmi.ls_oe_gpio, 1);
@@ -522,6 +530,38 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
522 if (r) 530 if (r)
523 goto err_runtime_get; 531 goto err_runtime_get;
524 532
533 /* Make selection of HDMI in DSS */
534 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
535
536 return 0;
537
538err_runtime_get:
539 regulator_disable(hdmi.vdda_hdmi_dac_reg);
540err_vdac_enable:
541 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
542 gpio_set_value(hdmi.ls_oe_gpio, 0);
543 return r;
544}
545
546static void hdmi_power_off_core(struct omap_dss_device *dssdev)
547{
548 hdmi_runtime_put();
549 regulator_disable(hdmi.vdda_hdmi_dac_reg);
550 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
551 gpio_set_value(hdmi.ls_oe_gpio, 0);
552}
553
554static int hdmi_power_on_full(struct omap_dss_device *dssdev)
555{
556 int r;
557 struct omap_video_timings *p;
558 struct omap_overlay_manager *mgr = dssdev->output->manager;
559 unsigned long phy;
560
561 r = hdmi_power_on_core(dssdev);
562 if (r)
563 return r;
564
525 dss_mgr_disable(mgr); 565 dss_mgr_disable(mgr);
526 566
527 p = &hdmi.ip_data.cfg.timings; 567 p = &hdmi.ip_data.cfg.timings;
@@ -549,17 +589,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
549 589
550 hdmi.ip_data.ops->video_configure(&hdmi.ip_data); 590 hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
551 591
552 /* Make selection of HDMI in DSS */
553 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
554
555 /* Select the dispc clock source as PRCM clock, to ensure that it is not
556 * DSI PLL source as the clock selected by DSI PLL might not be
557 * sufficient for the resolution selected / that can be changed
558 * dynamically by user. This can be moved to single location , say
559 * Boardfile.
560 */
561 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
562
563 /* bypass TV gamma table */ 592 /* bypass TV gamma table */
564 dispc_enable_gamma_table(0); 593 dispc_enable_gamma_table(0);
565 594
@@ -583,16 +612,11 @@ err_vid_enable:
583err_phy_enable: 612err_phy_enable:
584 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 613 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
585err_pll_enable: 614err_pll_enable:
586 hdmi_runtime_put(); 615 hdmi_power_off_core(dssdev);
587err_runtime_get:
588 regulator_disable(hdmi.vdda_hdmi_dac_reg);
589err_vdac_enable:
590 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
591 gpio_set_value(hdmi.ls_oe_gpio, 0);
592 return -EIO; 616 return -EIO;
593} 617}
594 618
595static void hdmi_power_off(struct omap_dss_device *dssdev) 619static void hdmi_power_off_full(struct omap_dss_device *dssdev)
596{ 620{
597 struct omap_overlay_manager *mgr = dssdev->output->manager; 621 struct omap_overlay_manager *mgr = dssdev->output->manager;
598 622
@@ -601,12 +625,8 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
601 hdmi.ip_data.ops->video_disable(&hdmi.ip_data); 625 hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
602 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 626 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
603 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 627 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
604 hdmi_runtime_put();
605
606 regulator_disable(hdmi.vdda_hdmi_dac_reg);
607 628
608 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); 629 hdmi_power_off_core(dssdev);
609 gpio_set_value(hdmi.ls_oe_gpio, 0);
610} 630}
611 631
612int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, 632int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -716,7 +736,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
716 goto err0; 736 goto err0;
717 } 737 }
718 738
719 r = hdmi_power_on(dssdev); 739 r = hdmi_power_on_full(dssdev);
720 if (r) { 740 if (r) {
721 DSSERR("failed to power on device\n"); 741 DSSERR("failed to power on device\n");
722 goto err1; 742 goto err1;
@@ -738,13 +758,48 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
738 758
739 mutex_lock(&hdmi.lock); 759 mutex_lock(&hdmi.lock);
740 760
741 hdmi_power_off(dssdev); 761 hdmi_power_off_full(dssdev);
742 762
743 omap_dss_stop_device(dssdev); 763 omap_dss_stop_device(dssdev);
744 764
745 mutex_unlock(&hdmi.lock); 765 mutex_unlock(&hdmi.lock);
746} 766}
747 767
768int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev)
769{
770 int r = 0;
771
772 DSSDBG("ENTER omapdss_hdmi_core_enable\n");
773
774 mutex_lock(&hdmi.lock);
775
776 hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
777
778 r = hdmi_power_on_core(dssdev);
779 if (r) {
780 DSSERR("failed to power on device\n");
781 goto err0;
782 }
783
784 mutex_unlock(&hdmi.lock);
785 return 0;
786
787err0:
788 mutex_unlock(&hdmi.lock);
789 return r;
790}
791
792void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev)
793{
794 DSSDBG("Enter omapdss_hdmi_core_disable\n");
795
796 mutex_lock(&hdmi.lock);
797
798 hdmi_power_off_core(dssdev);
799
800 mutex_unlock(&hdmi.lock);
801}
802
748static int hdmi_get_clocks(struct platform_device *pdev) 803static int hdmi_get_clocks(struct platform_device *pdev)
749{ 804{
750 struct clk *clk; 805 struct clk *clk;
@@ -913,7 +968,7 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
913static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev) 968static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
914{ 969{
915 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 970 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
916 const char *def_disp_name = dss_get_default_display_name(); 971 const char *def_disp_name = omapdss_get_default_display_name();
917 struct omap_dss_device *def_dssdev; 972 struct omap_dss_device *def_dssdev;
918 int i; 973 int i;
919 974
@@ -971,9 +1026,19 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
971 return; 1026 return;
972 } 1027 }
973 1028
1029 r = omapdss_output_set_device(&hdmi.output, dssdev);
1030 if (r) {
1031 DSSERR("failed to connect output to new device: %s\n",
1032 dssdev->name);
1033 dss_put_device(dssdev);
1034 return;
1035 }
1036
974 r = dss_add_device(dssdev); 1037 r = dss_add_device(dssdev);
975 if (r) { 1038 if (r) {
976 DSSERR("device %s register failed: %d\n", dssdev->name, r); 1039 DSSERR("device %s register failed: %d\n", dssdev->name, r);
1040 omapdss_output_unset_device(&hdmi.output);
1041 hdmi_uninit_display(dssdev);
977 dss_put_device(dssdev); 1042 dss_put_device(dssdev);
978 return; 1043 return;
979 } 1044 }
@@ -1000,22 +1065,22 @@ static void __exit hdmi_uninit_output(struct platform_device *pdev)
1000/* HDMI HW IP initialisation */ 1065/* HDMI HW IP initialisation */
1001static int __init omapdss_hdmihw_probe(struct platform_device *pdev) 1066static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1002{ 1067{
1003 struct resource *hdmi_mem; 1068 struct resource *res;
1004 int r; 1069 int r;
1005 1070
1006 hdmi.pdev = pdev; 1071 hdmi.pdev = pdev;
1007 1072
1008 mutex_init(&hdmi.lock); 1073 mutex_init(&hdmi.lock);
1074 mutex_init(&hdmi.ip_data.lock);
1009 1075
1010 hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); 1076 res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1011 if (!hdmi_mem) { 1077 if (!res) {
1012 DSSERR("can't get IORESOURCE_MEM HDMI\n"); 1078 DSSERR("can't get IORESOURCE_MEM HDMI\n");
1013 return -EINVAL; 1079 return -EINVAL;
1014 } 1080 }
1015 1081
1016 /* Base address taken from platform */ 1082 /* Base address taken from platform */
1017 hdmi.ip_data.base_wp = ioremap(hdmi_mem->start, 1083 hdmi.ip_data.base_wp = devm_request_and_ioremap(&pdev->dev, res);
1018 resource_size(hdmi_mem));
1019 if (!hdmi.ip_data.base_wp) { 1084 if (!hdmi.ip_data.base_wp) {
1020 DSSERR("can't ioremap WP\n"); 1085 DSSERR("can't ioremap WP\n");
1021 return -ENOMEM; 1086 return -ENOMEM;
@@ -1023,7 +1088,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1023 1088
1024 r = hdmi_get_clocks(pdev); 1089 r = hdmi_get_clocks(pdev);
1025 if (r) { 1090 if (r) {
1026 iounmap(hdmi.ip_data.base_wp); 1091 DSSERR("can't get clocks\n");
1027 return r; 1092 return r;
1028 } 1093 }
1029 1094
@@ -1034,9 +1099,11 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1034 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 1099 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
1035 hdmi.ip_data.phy_offset = HDMI_PHY; 1100 hdmi.ip_data.phy_offset = HDMI_PHY;
1036 1101
1037 mutex_init(&hdmi.ip_data.lock); 1102 r = hdmi_panel_init();
1038 1103 if (r) {
1039 hdmi_panel_init(); 1104 DSSERR("can't init panel\n");
1105 goto err_panel_init;
1106 }
1040 1107
1041 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 1108 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
1042 1109
@@ -1045,6 +1112,10 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1045 hdmi_probe_pdata(pdev); 1112 hdmi_probe_pdata(pdev);
1046 1113
1047 return 0; 1114 return 0;
1115
1116err_panel_init:
1117 hdmi_put_clocks();
1118 return r;
1048} 1119}
1049 1120
1050static int __exit hdmi_remove_child(struct device *dev, void *data) 1121static int __exit hdmi_remove_child(struct device *dev, void *data)
@@ -1068,8 +1139,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
1068 1139
1069 hdmi_put_clocks(); 1140 hdmi_put_clocks();
1070 1141
1071 iounmap(hdmi.ip_data.base_wp);
1072
1073 return 0; 1142 return 0;
1074} 1143}
1075 1144
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 69fb115bab32..dfb8eda81b61 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -280,58 +280,6 @@ static void hdmi_panel_disable(struct omap_dss_device *dssdev)
280 mutex_unlock(&hdmi.lock); 280 mutex_unlock(&hdmi.lock);
281} 281}
282 282
283static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
284{
285 int r = 0;
286
287 mutex_lock(&hdmi.lock);
288
289 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
290 r = -EINVAL;
291 goto err;
292 }
293
294 /*
295 * TODO: notify audio users that the display was suspended. For now,
296 * disable audio locally to not break our audio state machine.
297 */
298 hdmi_panel_audio_disable(dssdev);
299
300 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
301 omapdss_hdmi_display_disable(dssdev);
302
303err:
304 mutex_unlock(&hdmi.lock);
305
306 return r;
307}
308
309static int hdmi_panel_resume(struct omap_dss_device *dssdev)
310{
311 int r = 0;
312
313 mutex_lock(&hdmi.lock);
314
315 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
316 r = -EINVAL;
317 goto err;
318 }
319
320 r = omapdss_hdmi_display_enable(dssdev);
321 if (r) {
322 DSSERR("failed to power on\n");
323 goto err;
324 }
325 /* TODO: notify audio users that the panel resumed. */
326
327 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
328
329err:
330 mutex_unlock(&hdmi.lock);
331
332 return r;
333}
334
335static void hdmi_get_timings(struct omap_dss_device *dssdev, 283static void hdmi_get_timings(struct omap_dss_device *dssdev,
336 struct omap_video_timings *timings) 284 struct omap_video_timings *timings)
337{ 285{
@@ -379,20 +327,22 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev,
379static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len) 327static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
380{ 328{
381 int r; 329 int r;
330 bool need_enable;
382 331
383 mutex_lock(&hdmi.lock); 332 mutex_lock(&hdmi.lock);
384 333
385 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { 334 need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED;
386 r = omapdss_hdmi_display_enable(dssdev); 335
336 if (need_enable) {
337 r = omapdss_hdmi_core_enable(dssdev);
387 if (r) 338 if (r)
388 goto err; 339 goto err;
389 } 340 }
390 341
391 r = omapdss_hdmi_read_edid(buf, len); 342 r = omapdss_hdmi_read_edid(buf, len);
392 343
393 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED || 344 if (need_enable)
394 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) 345 omapdss_hdmi_core_disable(dssdev);
395 omapdss_hdmi_display_disable(dssdev);
396err: 346err:
397 mutex_unlock(&hdmi.lock); 347 mutex_unlock(&hdmi.lock);
398 348
@@ -402,20 +352,22 @@ err:
402static bool hdmi_detect(struct omap_dss_device *dssdev) 352static bool hdmi_detect(struct omap_dss_device *dssdev)
403{ 353{
404 int r; 354 int r;
355 bool need_enable;
405 356
406 mutex_lock(&hdmi.lock); 357 mutex_lock(&hdmi.lock);
407 358
408 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { 359 need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED;
409 r = omapdss_hdmi_display_enable(dssdev); 360
361 if (need_enable) {
362 r = omapdss_hdmi_core_enable(dssdev);
410 if (r) 363 if (r)
411 goto err; 364 goto err;
412 } 365 }
413 366
414 r = omapdss_hdmi_detect(); 367 r = omapdss_hdmi_detect();
415 368
416 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED || 369 if (need_enable)
417 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) 370 omapdss_hdmi_core_disable(dssdev);
418 omapdss_hdmi_display_disable(dssdev);
419err: 371err:
420 mutex_unlock(&hdmi.lock); 372 mutex_unlock(&hdmi.lock);
421 373
@@ -427,8 +379,6 @@ static struct omap_dss_driver hdmi_driver = {
427 .remove = hdmi_panel_remove, 379 .remove = hdmi_panel_remove,
428 .enable = hdmi_panel_enable, 380 .enable = hdmi_panel_enable,
429 .disable = hdmi_panel_disable, 381 .disable = hdmi_panel_disable,
430 .suspend = hdmi_panel_suspend,
431 .resume = hdmi_panel_resume,
432 .get_timings = hdmi_get_timings, 382 .get_timings = hdmi_get_timings,
433 .set_timings = hdmi_set_timings, 383 .set_timings = hdmi_set_timings,
434 .check_timings = hdmi_check_timings, 384 .check_timings = hdmi_check_timings,
@@ -454,9 +404,7 @@ int hdmi_panel_init(void)
454 spin_lock_init(&hdmi.audio_lock); 404 spin_lock_init(&hdmi.audio_lock);
455#endif 405#endif
456 406
457 omap_dss_register_driver(&hdmi_driver); 407 return omap_dss_register_driver(&hdmi_driver);
458
459 return 0;
460} 408}
461 409
462void hdmi_panel_exit(void) 410void hdmi_panel_exit(void)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index c54d2f620ce3..2551eaa14c42 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -36,36 +36,6 @@
36static int num_managers; 36static int num_managers;
37static struct omap_overlay_manager *managers; 37static struct omap_overlay_manager *managers;
38 38
39static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
40{
41 return mgr->output ? mgr->output->device : NULL;
42}
43
44static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
45{
46 unsigned long timeout = msecs_to_jiffies(500);
47 struct omap_dss_device *dssdev = mgr->get_device(mgr);
48 u32 irq;
49 int r;
50
51 r = dispc_runtime_get();
52 if (r)
53 return r;
54
55 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
56 irq = DISPC_IRQ_EVSYNC_ODD;
57 else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
58 irq = DISPC_IRQ_EVSYNC_EVEN;
59 else
60 irq = dispc_mgr_get_vsync_irq(mgr->id);
61
62 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
63
64 dispc_runtime_put();
65
66 return r;
67}
68
69int dss_init_overlay_managers(struct platform_device *pdev) 39int dss_init_overlay_managers(struct platform_device *pdev)
70{ 40{
71 int i, r; 41 int i, r;
@@ -99,15 +69,6 @@ int dss_init_overlay_managers(struct platform_device *pdev)
99 break; 69 break;
100 } 70 }
101 71
102 mgr->set_output = &dss_mgr_set_output;
103 mgr->unset_output = &dss_mgr_unset_output;
104 mgr->apply = &omap_dss_mgr_apply;
105 mgr->set_manager_info = &dss_mgr_set_info;
106 mgr->get_manager_info = &dss_mgr_get_info;
107 mgr->wait_for_go = &dss_mgr_wait_for_go;
108 mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
109 mgr->get_device = &dss_mgr_get_device;
110
111 mgr->caps = 0; 72 mgr->caps = 0;
112 mgr->supported_displays = 73 mgr->supported_displays =
113 dss_feat_get_supported_displays(mgr->id); 74 dss_feat_get_supported_displays(mgr->id);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 813f26682b7a..79dea1a1a732 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -114,35 +114,67 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
114 return NULL; 114 return NULL;
115} 115}
116 116
117struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev) 117static const struct dss_mgr_ops *dss_mgr_ops;
118
119int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops)
118{ 120{
119 struct omap_dss_output *out = NULL; 121 if (dss_mgr_ops)
120 enum omap_dss_output_id id; 122 return -EBUSY;
121 123
122 switch (dssdev->type) { 124 dss_mgr_ops = mgr_ops;
123 case OMAP_DISPLAY_TYPE_DPI: 125
124 out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI); 126 return 0;
125 break; 127}
126 case OMAP_DISPLAY_TYPE_DBI: 128EXPORT_SYMBOL(dss_install_mgr_ops);
127 out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI); 129
128 break; 130void dss_uninstall_mgr_ops(void)
129 case OMAP_DISPLAY_TYPE_SDI: 131{
130 out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI); 132 dss_mgr_ops = NULL;
131 break; 133}
132 case OMAP_DISPLAY_TYPE_VENC: 134EXPORT_SYMBOL(dss_uninstall_mgr_ops);
133 out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC); 135
134 break; 136void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
135 case OMAP_DISPLAY_TYPE_HDMI: 137 const struct omap_video_timings *timings)
136 out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI); 138{
137 break; 139 dss_mgr_ops->set_timings(mgr, timings);
138 case OMAP_DISPLAY_TYPE_DSI: 140}
139 id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 : 141EXPORT_SYMBOL(dss_mgr_set_timings);
140 OMAP_DSS_OUTPUT_DSI2; 142
141 out = omap_dss_get_output(id); 143void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
142 break; 144 const struct dss_lcd_mgr_config *config)
143 default: 145{
144 break; 146 dss_mgr_ops->set_lcd_config(mgr, config);
145 } 147}
148EXPORT_SYMBOL(dss_mgr_set_lcd_config);
149
150int dss_mgr_enable(struct omap_overlay_manager *mgr)
151{
152 return dss_mgr_ops->enable(mgr);
153}
154EXPORT_SYMBOL(dss_mgr_enable);
155
156void dss_mgr_disable(struct omap_overlay_manager *mgr)
157{
158 dss_mgr_ops->disable(mgr);
159}
160EXPORT_SYMBOL(dss_mgr_disable);
146 161
147 return out; 162void dss_mgr_start_update(struct omap_overlay_manager *mgr)
163{
164 dss_mgr_ops->start_update(mgr);
165}
166EXPORT_SYMBOL(dss_mgr_start_update);
167
168int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
169 void (*handler)(void *), void *data)
170{
171 return dss_mgr_ops->register_framedone_handler(mgr, handler, data);
172}
173EXPORT_SYMBOL(dss_mgr_register_framedone_handler);
174
175void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
176 void (*handler)(void *), void *data)
177{
178 dss_mgr_ops->unregister_framedone_handler(mgr, handler, data);
148} 179}
180EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 45f4994bc6b0..eccde322c28a 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -38,13 +38,6 @@
38static int num_overlays; 38static int num_overlays;
39static struct omap_overlay *overlays; 39static struct omap_overlay *overlays;
40 40
41static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
42{
43 return ovl->manager ?
44 (ovl->manager->output ? ovl->manager->output->device : NULL) :
45 NULL;
46}
47
48int omap_dss_get_num_overlays(void) 41int omap_dss_get_num_overlays(void)
49{ 42{
50 return num_overlays; 43 return num_overlays;
@@ -93,16 +86,6 @@ void dss_init_overlays(struct platform_device *pdev)
93 break; 86 break;
94 } 87 }
95 88
96 ovl->is_enabled = &dss_ovl_is_enabled;
97 ovl->enable = &dss_ovl_enable;
98 ovl->disable = &dss_ovl_disable;
99 ovl->set_manager = &dss_ovl_set_manager;
100 ovl->unset_manager = &dss_ovl_unset_manager;
101 ovl->set_overlay_info = &dss_ovl_set_info;
102 ovl->get_overlay_info = &dss_ovl_get_info;
103 ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
104 ovl->get_device = &dss_ovl_get_device;
105
106 ovl->caps = dss_feat_get_overlay_caps(ovl->id); 89 ovl->caps = dss_feat_get_overlay_caps(ovl->id);
107 ovl->supported_modes = 90 ovl->supported_modes =
108 dss_feat_get_supported_color_modes(ovl->id); 91 dss_feat_get_supported_color_modes(ovl->id);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 7282e5af3e1a..e903dd3f54d9 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -342,7 +342,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
342 return 0; 342 return 0;
343} 343}
344 344
345static void framedone_callback(void *data, u32 mask) 345static void framedone_callback(void *data)
346{ 346{
347 void (*callback)(void *data); 347 void (*callback)(void *data);
348 348
@@ -908,8 +908,8 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
908 goto err0; 908 goto err0;
909 } 909 }
910 910
911 r = omap_dispc_register_isr(framedone_callback, NULL, 911 r = dss_mgr_register_framedone_handler(out->manager,
912 DISPC_IRQ_FRAMEDONE); 912 framedone_callback, NULL);
913 if (r) { 913 if (r) {
914 DSSERR("can't get FRAMEDONE irq\n"); 914 DSSERR("can't get FRAMEDONE irq\n");
915 goto err1; 915 goto err1;
@@ -933,8 +933,10 @@ EXPORT_SYMBOL(omapdss_rfbi_display_enable);
933 933
934void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) 934void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
935{ 935{
936 omap_dispc_unregister_isr(framedone_callback, NULL, 936 struct omap_dss_output *out = dssdev->output;
937 DISPC_IRQ_FRAMEDONE); 937
938 dss_mgr_unregister_framedone_handler(out->manager,
939 framedone_callback, NULL);
938 omap_dss_stop_device(dssdev); 940 omap_dss_stop_device(dssdev);
939 941
940 rfbi_runtime_put(); 942 rfbi_runtime_put();
@@ -950,7 +952,7 @@ static int __init rfbi_init_display(struct omap_dss_device *dssdev)
950static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev) 952static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev)
951{ 953{
952 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 954 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
953 const char *def_disp_name = dss_get_default_display_name(); 955 const char *def_disp_name = omapdss_get_default_display_name();
954 struct omap_dss_device *def_dssdev; 956 struct omap_dss_device *def_dssdev;
955 int i; 957 int i;
956 958
@@ -999,9 +1001,18 @@ static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
999 return; 1001 return;
1000 } 1002 }
1001 1003
1004 r = omapdss_output_set_device(&rfbi.output, dssdev);
1005 if (r) {
1006 DSSERR("failed to connect output to new device: %s\n",
1007 dssdev->name);
1008 dss_put_device(dssdev);
1009 return;
1010 }
1011
1002 r = dss_add_device(dssdev); 1012 r = dss_add_device(dssdev);
1003 if (r) { 1013 if (r) {
1004 DSSERR("device %s register failed: %d\n", dssdev->name, r); 1014 DSSERR("device %s register failed: %d\n", dssdev->name, r);
1015 omapdss_output_unset_device(&rfbi.output);
1005 dss_put_device(dssdev); 1016 dss_put_device(dssdev);
1006 return; 1017 return;
1007 } 1018 }
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 7760851f6e5d..62b5374ce438 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -205,7 +205,7 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev)
205static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev) 205static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev)
206{ 206{
207 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 207 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
208 const char *def_disp_name = dss_get_default_display_name(); 208 const char *def_disp_name = omapdss_get_default_display_name();
209 struct omap_dss_device *def_dssdev; 209 struct omap_dss_device *def_dssdev;
210 int i; 210 int i;
211 211
@@ -254,9 +254,18 @@ static void __init sdi_probe_pdata(struct platform_device *sdidev)
254 return; 254 return;
255 } 255 }
256 256
257 r = omapdss_output_set_device(&sdi.output, dssdev);
258 if (r) {
259 DSSERR("failed to connect output to new device: %s\n",
260 dssdev->name);
261 dss_put_device(dssdev);
262 return;
263 }
264
257 r = dss_add_device(dssdev); 265 r = dss_add_device(dssdev);
258 if (r) { 266 if (r) {
259 DSSERR("device %s register failed: %d\n", dssdev->name, r); 267 DSSERR("device %s register failed: %d\n", dssdev->name, r);
268 omapdss_output_unset_device(&sdi.output);
260 dss_put_device(dssdev); 269 dss_put_device(dssdev);
261 return; 270 return;
262 } 271 }
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index b046c208cb97..216aa704f9d7 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -102,6 +102,8 @@ struct ti_hdmi_ip_ops {
102 102
103 int (*audio_config)(struct hdmi_ip_data *ip_data, 103 int (*audio_config)(struct hdmi_ip_data *ip_data,
104 struct omap_dss_audio *audio); 104 struct omap_dss_audio *audio);
105
106 int (*audio_get_dma_port)(u32 *offset, u32 *size);
105#endif 107#endif
106 108
107}; 109};
@@ -183,5 +185,6 @@ int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data);
183void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data); 185void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data);
184int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, 186int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data,
185 struct omap_dss_audio *audio); 187 struct omap_dss_audio *audio);
188int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size);
186#endif 189#endif
187#endif 190#endif
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index c23b85a20cdc..e18b222ed739 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -899,7 +899,7 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
899#define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\ 899#define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\
900 hdmi_read_reg(hdmi_av_base(ip_data), r)) 900 hdmi_read_reg(hdmi_av_base(ip_data), r))
901#define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \ 901#define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \
902 (i < 10) ? 32 - strlen(#r) : 31 - strlen(#r), " ", \ 902 (i < 10) ? 32 - (int)strlen(#r) : 31 - (int)strlen(#r), " ", \
903 hdmi_read_reg(hdmi_av_base(ip_data), CORE_REG(i, r))) 903 hdmi_read_reg(hdmi_av_base(ip_data), CORE_REG(i, r)))
904 904
905 DUMPCORE(HDMI_CORE_SYS_VND_IDL); 905 DUMPCORE(HDMI_CORE_SYS_VND_IDL);
@@ -1418,4 +1418,13 @@ void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data)
1418 REG_FLD_MOD(hdmi_wp_base(ip_data), 1418 REG_FLD_MOD(hdmi_wp_base(ip_data),
1419 HDMI_WP_AUDIO_CTRL, false, 30, 30); 1419 HDMI_WP_AUDIO_CTRL, false, 30, 30);
1420} 1420}
1421
1422int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size)
1423{
1424 if (!offset || !size)
1425 return -EINVAL;
1426 *offset = HDMI_WP_AUDIO_DATA;
1427 *size = 4;
1428 return 0;
1429}
1421#endif 1430#endif
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 56efa3bb465d..006caf3cb509 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -744,7 +744,7 @@ static void venc_put_clocks(void)
744static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev) 744static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
745{ 745{
746 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 746 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
747 const char *def_disp_name = dss_get_default_display_name(); 747 const char *def_disp_name = omapdss_get_default_display_name();
748 struct omap_dss_device *def_dssdev; 748 struct omap_dss_device *def_dssdev;
749 int i; 749 int i;
750 750
@@ -795,9 +795,18 @@ static void __init venc_probe_pdata(struct platform_device *vencdev)
795 return; 795 return;
796 } 796 }
797 797
798 r = omapdss_output_set_device(&venc.output, dssdev);
799 if (r) {
800 DSSERR("failed to connect output to new device: %s\n",
801 dssdev->name);
802 dss_put_device(dssdev);
803 return;
804 }
805
798 r = dss_add_device(dssdev); 806 r = dss_add_device(dssdev);
799 if (r) { 807 if (r) {
800 DSSERR("device %s register failed: %d\n", dssdev->name, r); 808 DSSERR("device %s register failed: %d\n", dssdev->name, r);
809 omapdss_output_unset_device(&venc.output);
801 dss_put_device(dssdev); 810 dss_put_device(dssdev);
802 return; 811 return;
803 } 812 }
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index d55b8784ecfd..0d2b1a0834a0 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -157,12 +157,6 @@ static void venc_panel_disable(struct omap_dss_device *dssdev)
157 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) 157 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
158 goto end; 158 goto end;
159 159
160 if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
161 /* suspended is the same as disabled with venc */
162 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
163 goto end;
164 }
165
166 omapdss_venc_display_disable(dssdev); 160 omapdss_venc_display_disable(dssdev);
167 161
168 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 162 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
@@ -170,17 +164,6 @@ end:
170 mutex_unlock(&venc_panel.lock); 164 mutex_unlock(&venc_panel.lock);
171} 165}
172 166
173static int venc_panel_suspend(struct omap_dss_device *dssdev)
174{
175 venc_panel_disable(dssdev);
176 return 0;
177}
178
179static int venc_panel_resume(struct omap_dss_device *dssdev)
180{
181 return venc_panel_enable(dssdev);
182}
183
184static void venc_panel_set_timings(struct omap_dss_device *dssdev, 167static void venc_panel_set_timings(struct omap_dss_device *dssdev,
185 struct omap_video_timings *timings) 168 struct omap_video_timings *timings)
186{ 169{
@@ -222,8 +205,6 @@ static struct omap_dss_driver venc_driver = {
222 205
223 .enable = venc_panel_enable, 206 .enable = venc_panel_enable,
224 .disable = venc_panel_disable, 207 .disable = venc_panel_disable,
225 .suspend = venc_panel_suspend,
226 .resume = venc_panel_resume,
227 208
228 .get_resolution = omapdss_default_get_resolution, 209 .get_resolution = omapdss_default_get_resolution,
229 .get_recommended_bpp = omapdss_default_get_recommended_bpp, 210 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index 4ea17dc3258c..4cb12ce68855 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -2,7 +2,6 @@ menuconfig FB_OMAP2
2 tristate "OMAP2+ frame buffer support" 2 tristate "OMAP2+ frame buffer support"
3 depends on FB && OMAP2_DSS && !DRM_OMAP 3 depends on FB && OMAP2_DSS && !DRM_OMAP
4 4
5 select OMAP2_VRAM
6 select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 5 select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
7 select FB_CFB_FILLRECT 6 select FB_CFB_FILLRECT
8 select FB_CFB_COPYAREA 7 select FB_CFB_COPYAREA
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 532a31b3d96b..d30b45d72649 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -28,10 +28,10 @@
28#include <linux/omapfb.h> 28#include <linux/omapfb.h>
29#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
30#include <linux/export.h> 30#include <linux/export.h>
31#include <linux/sizes.h>
31 32
32#include <video/omapdss.h> 33#include <video/omapdss.h>
33#include <video/omapvrfb.h> 34#include <video/omapvrfb.h>
34#include <plat/vram.h>
35 35
36#include "omapfb.h" 36#include "omapfb.h"
37 37
@@ -211,6 +211,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
211{ 211{
212 struct omapfb_info *ofbi = FB2OFB(fbi); 212 struct omapfb_info *ofbi = FB2OFB(fbi);
213 struct omapfb2_device *fbdev = ofbi->fbdev; 213 struct omapfb2_device *fbdev = ofbi->fbdev;
214 struct omap_dss_device *display = fb2display(fbi);
214 struct omapfb2_mem_region *rg; 215 struct omapfb2_mem_region *rg;
215 int r = 0, i; 216 int r = 0, i;
216 size_t size; 217 size_t size;
@@ -220,6 +221,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
220 221
221 size = PAGE_ALIGN(mi->size); 222 size = PAGE_ALIGN(mi->size);
222 223
224 if (display && display->driver->sync)
225 display->driver->sync(display);
226
223 rg = ofbi->region; 227 rg = ofbi->region;
224 228
225 down_write_nested(&rg->lock, rg->id); 229 down_write_nested(&rg->lock, rg->id);
@@ -279,7 +283,7 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
279 return 0; 283 return 0;
280} 284}
281 285
282static int omapfb_update_window_nolock(struct fb_info *fbi, 286static int omapfb_update_window(struct fb_info *fbi,
283 u32 x, u32 y, u32 w, u32 h) 287 u32 x, u32 y, u32 w, u32 h)
284{ 288{
285 struct omap_dss_device *display = fb2display(fbi); 289 struct omap_dss_device *display = fb2display(fbi);
@@ -299,27 +303,6 @@ static int omapfb_update_window_nolock(struct fb_info *fbi,
299 return display->driver->update(display, x, y, w, h); 303 return display->driver->update(display, x, y, w, h);
300} 304}
301 305
302/* This function is exported for SGX driver use */
303int omapfb_update_window(struct fb_info *fbi,
304 u32 x, u32 y, u32 w, u32 h)
305{
306 struct omapfb_info *ofbi = FB2OFB(fbi);
307 struct omapfb2_device *fbdev = ofbi->fbdev;
308 int r;
309
310 if (!lock_fb_info(fbi))
311 return -ENODEV;
312 omapfb_lock(fbdev);
313
314 r = omapfb_update_window_nolock(fbi, x, y, w, h);
315
316 omapfb_unlock(fbdev);
317 unlock_fb_info(fbi);
318
319 return r;
320}
321EXPORT_SYMBOL(omapfb_update_window);
322
323int omapfb_set_update_mode(struct fb_info *fbi, 306int omapfb_set_update_mode(struct fb_info *fbi,
324 enum omapfb_update_mode mode) 307 enum omapfb_update_mode mode)
325{ 308{
@@ -646,7 +629,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
646 break; 629 break;
647 } 630 }
648 631
649 r = omapfb_update_window_nolock(fbi, p.uwnd_o.x, p.uwnd_o.y, 632 r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y,
650 p.uwnd_o.width, p.uwnd_o.height); 633 p.uwnd_o.width, p.uwnd_o.height);
651 break; 634 break;
652 635
@@ -663,7 +646,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
663 break; 646 break;
664 } 647 }
665 648
666 r = omapfb_update_window_nolock(fbi, p.uwnd.x, p.uwnd.y, 649 r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y,
667 p.uwnd.width, p.uwnd.height); 650 p.uwnd.width, p.uwnd.height);
668 break; 651 break;
669 652
@@ -853,14 +836,15 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
853 break; 836 break;
854 837
855 case OMAPFB_GET_VRAM_INFO: { 838 case OMAPFB_GET_VRAM_INFO: {
856 unsigned long vram, free, largest;
857
858 DBG("ioctl GET_VRAM_INFO\n"); 839 DBG("ioctl GET_VRAM_INFO\n");
859 840
860 omap_vram_get_info(&vram, &free, &largest); 841 /*
861 p.vram_info.total = vram; 842 * We don't have the ability to get this vram info anymore.
862 p.vram_info.free = free; 843 * Fill in something that should keep the applications working.
863 p.vram_info.largest_free_block = largest; 844 */
845 p.vram_info.total = SZ_1M * 64;
846 p.vram_info.free = SZ_1M * 64;
847 p.vram_info.largest_free_block = SZ_1M * 64;
864 848
865 if (copy_to_user((void __user *)arg, &p.vram_info, 849 if (copy_to_user((void __user *)arg, &p.vram_info,
866 sizeof(p.vram_info))) 850 sizeof(p.vram_info)))
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index bc225e46fdd2..ca585ef37f25 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -31,7 +31,6 @@
31#include <linux/omapfb.h> 31#include <linux/omapfb.h>
32 32
33#include <video/omapdss.h> 33#include <video/omapdss.h>
34#include <plat/vram.h>
35#include <video/omapvrfb.h> 34#include <video/omapvrfb.h>
36 35
37#include "omapfb.h" 36#include "omapfb.h"
@@ -1258,11 +1257,10 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1258 1257
1259 switch (blank) { 1258 switch (blank) {
1260 case FB_BLANK_UNBLANK: 1259 case FB_BLANK_UNBLANK:
1261 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) 1260 if (display->state == OMAP_DSS_DISPLAY_ACTIVE)
1262 goto exit; 1261 goto exit;
1263 1262
1264 if (display->driver->resume) 1263 r = display->driver->enable(display);
1265 r = display->driver->resume(display);
1266 1264
1267 if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) && 1265 if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) &&
1268 d->update_mode == OMAPFB_AUTO_UPDATE && 1266 d->update_mode == OMAPFB_AUTO_UPDATE &&
@@ -1283,8 +1281,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1283 if (d->auto_update_work_enabled) 1281 if (d->auto_update_work_enabled)
1284 omapfb_stop_auto_update(fbdev, display); 1282 omapfb_stop_auto_update(fbdev, display);
1285 1283
1286 if (display->driver->suspend) 1284 display->driver->disable(display);
1287 r = display->driver->suspend(display);
1288 1285
1289 break; 1286 break;
1290 1287
@@ -1335,24 +1332,25 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
1335 1332
1336 rg = ofbi->region; 1333 rg = ofbi->region;
1337 1334
1338 WARN_ON(atomic_read(&rg->map_count)); 1335 if (rg->token == NULL)
1339 1336 return;
1340 if (rg->paddr)
1341 if (omap_vram_free(rg->paddr, rg->size))
1342 dev_err(fbdev->dev, "VRAM FREE failed\n");
1343 1337
1344 if (rg->vaddr) 1338 WARN_ON(atomic_read(&rg->map_count));
1345 iounmap(rg->vaddr);
1346 1339
1347 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 1340 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
1348 /* unmap the 0 angle rotation */ 1341 /* unmap the 0 angle rotation */
1349 if (rg->vrfb.vaddr[0]) { 1342 if (rg->vrfb.vaddr[0]) {
1350 iounmap(rg->vrfb.vaddr[0]); 1343 iounmap(rg->vrfb.vaddr[0]);
1351 omap_vrfb_release_ctx(&rg->vrfb);
1352 rg->vrfb.vaddr[0] = NULL; 1344 rg->vrfb.vaddr[0] = NULL;
1353 } 1345 }
1346
1347 omap_vrfb_release_ctx(&rg->vrfb);
1354 } 1348 }
1355 1349
1350 dma_free_attrs(fbdev->dev, rg->size, rg->token, rg->dma_handle,
1351 &rg->attrs);
1352
1353 rg->token = NULL;
1356 rg->vaddr = NULL; 1354 rg->vaddr = NULL;
1357 rg->paddr = 0; 1355 rg->paddr = 0;
1358 rg->alloc = 0; 1356 rg->alloc = 0;
@@ -1387,7 +1385,9 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1387 struct omapfb_info *ofbi = FB2OFB(fbi); 1385 struct omapfb_info *ofbi = FB2OFB(fbi);
1388 struct omapfb2_device *fbdev = ofbi->fbdev; 1386 struct omapfb2_device *fbdev = ofbi->fbdev;
1389 struct omapfb2_mem_region *rg; 1387 struct omapfb2_mem_region *rg;
1390 void __iomem *vaddr; 1388 void *token;
1389 DEFINE_DMA_ATTRS(attrs);
1390 dma_addr_t dma_handle;
1391 int r; 1391 int r;
1392 1392
1393 rg = ofbi->region; 1393 rg = ofbi->region;
@@ -1402,42 +1402,40 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1402 1402
1403 size = PAGE_ALIGN(size); 1403 size = PAGE_ALIGN(size);
1404 1404
1405 if (!paddr) { 1405 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
1406 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
1407 r = omap_vram_alloc(size, &paddr);
1408 } else {
1409 DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
1410 ofbi->id);
1411 r = omap_vram_reserve(paddr, size);
1412 }
1413 1406
1414 if (r) { 1407 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
1408 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
1409
1410 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
1411
1412 token = dma_alloc_attrs(fbdev->dev, size, &dma_handle,
1413 GFP_KERNEL, &attrs);
1414
1415 if (token == NULL) {
1415 dev_err(fbdev->dev, "failed to allocate framebuffer\n"); 1416 dev_err(fbdev->dev, "failed to allocate framebuffer\n");
1416 return -ENOMEM; 1417 return -ENOMEM;
1417 } 1418 }
1418 1419
1419 if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) { 1420 DBG("allocated VRAM paddr %lx, vaddr %p\n",
1420 vaddr = ioremap_wc(paddr, size); 1421 (unsigned long)dma_handle, token);
1421
1422 if (!vaddr) {
1423 dev_err(fbdev->dev, "failed to ioremap framebuffer\n");
1424 omap_vram_free(paddr, size);
1425 return -ENOMEM;
1426 }
1427 1422
1428 DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr); 1423 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
1429 } else {
1430 r = omap_vrfb_request_ctx(&rg->vrfb); 1424 r = omap_vrfb_request_ctx(&rg->vrfb);
1431 if (r) { 1425 if (r) {
1426 dma_free_attrs(fbdev->dev, size, token, dma_handle,
1427 &attrs);
1432 dev_err(fbdev->dev, "vrfb create ctx failed\n"); 1428 dev_err(fbdev->dev, "vrfb create ctx failed\n");
1433 return r; 1429 return r;
1434 } 1430 }
1435
1436 vaddr = NULL;
1437 } 1431 }
1438 1432
1439 rg->paddr = paddr; 1433 rg->attrs = attrs;
1440 rg->vaddr = vaddr; 1434 rg->token = token;
1435 rg->dma_handle = dma_handle;
1436
1437 rg->paddr = (unsigned long)dma_handle;
1438 rg->vaddr = (void __iomem *)token;
1441 rg->size = size; 1439 rg->size = size;
1442 rg->alloc = 1; 1440 rg->alloc = 1;
1443 1441
@@ -1531,6 +1529,9 @@ static int omapfb_parse_vram_param(const char *param, int max_entries,
1531 1529
1532 } 1530 }
1533 1531
1532 WARN_ONCE(paddr,
1533 "reserving memory at predefined address not supported\n");
1534
1534 paddrs[fbnum] = paddr; 1535 paddrs[fbnum] = paddr;
1535 sizes[fbnum] = size; 1536 sizes[fbnum] = size;
1536 1537
@@ -1610,7 +1611,6 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1610{ 1611{
1611 struct omapfb_info *ofbi = FB2OFB(fbi); 1612 struct omapfb_info *ofbi = FB2OFB(fbi);
1612 struct omapfb2_device *fbdev = ofbi->fbdev; 1613 struct omapfb2_device *fbdev = ofbi->fbdev;
1613 struct omap_dss_device *display = fb2display(fbi);
1614 struct omapfb2_mem_region *rg = ofbi->region; 1614 struct omapfb2_mem_region *rg = ofbi->region;
1615 unsigned long old_size = rg->size; 1615 unsigned long old_size = rg->size;
1616 unsigned long old_paddr = rg->paddr; 1616 unsigned long old_paddr = rg->paddr;
@@ -1625,9 +1625,6 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1625 if (old_size == size && old_type == type) 1625 if (old_size == size && old_type == type)
1626 return 0; 1626 return 0;
1627 1627
1628 if (display && display->driver->sync)
1629 display->driver->sync(display);
1630
1631 omapfb_free_fbmem(fbi); 1628 omapfb_free_fbmem(fbi);
1632 1629
1633 if (size == 0) { 1630 if (size == 0) {
@@ -1882,7 +1879,6 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
1882 } 1879 }
1883 1880
1884 dev_set_drvdata(fbdev->dev, NULL); 1881 dev_set_drvdata(fbdev->dev, NULL);
1885 kfree(fbdev);
1886} 1882}
1887 1883
1888static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) 1884static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
@@ -2258,26 +2254,28 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
2258{ 2254{
2259 struct fb_monspecs *specs; 2255 struct fb_monspecs *specs;
2260 u8 *edid; 2256 u8 *edid;
2261 int r, i, best_xres, best_idx, len; 2257 int r, i, best_idx, len;
2262 2258
2263 if (!display->driver->read_edid) 2259 if (!display->driver->read_edid)
2264 return -ENODEV; 2260 return -ENODEV;
2265 2261
2266 len = 0x80 * 2; 2262 len = 0x80 * 2;
2267 edid = kmalloc(len, GFP_KERNEL); 2263 edid = kmalloc(len, GFP_KERNEL);
2264 if (edid == NULL)
2265 return -ENOMEM;
2268 2266
2269 r = display->driver->read_edid(display, edid, len); 2267 r = display->driver->read_edid(display, edid, len);
2270 if (r < 0) 2268 if (r < 0)
2271 goto err1; 2269 goto err1;
2272 2270
2273 specs = kzalloc(sizeof(*specs), GFP_KERNEL); 2271 specs = kzalloc(sizeof(*specs), GFP_KERNEL);
2272 if (specs == NULL) {
2273 r = -ENOMEM;
2274 goto err1;
2275 }
2274 2276
2275 fb_edid_to_monspecs(edid, specs); 2277 fb_edid_to_monspecs(edid, specs);
2276 2278
2277 if (edid[126] > 0)
2278 fb_edid_add_monspecs(edid + 0x80, specs);
2279
2280 best_xres = 0;
2281 best_idx = -1; 2279 best_idx = -1;
2282 2280
2283 for (i = 0; i < specs->modedb_len; ++i) { 2281 for (i = 0; i < specs->modedb_len; ++i) {
@@ -2293,16 +2291,20 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
2293 if (m->xres == 2880 || m->xres == 1440) 2291 if (m->xres == 2880 || m->xres == 1440)
2294 continue; 2292 continue;
2295 2293
2294 if (m->vmode & FB_VMODE_INTERLACED ||
2295 m->vmode & FB_VMODE_DOUBLE)
2296 continue;
2297
2296 fb_videomode_to_omap_timings(m, display, &t); 2298 fb_videomode_to_omap_timings(m, display, &t);
2297 2299
2298 r = display->driver->check_timings(display, &t); 2300 r = display->driver->check_timings(display, &t);
2299 if (r == 0 && best_xres < m->xres) { 2301 if (r == 0) {
2300 best_xres = m->xres;
2301 best_idx = i; 2302 best_idx = i;
2303 break;
2302 } 2304 }
2303 } 2305 }
2304 2306
2305 if (best_xres == 0) { 2307 if (best_idx == -1) {
2306 r = -ENOENT; 2308 r = -ENOENT;
2307 goto err2; 2309 goto err2;
2308 } 2310 }
@@ -2371,15 +2373,62 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
2371 return 0; 2373 return 0;
2372} 2374}
2373 2375
2376static int omapfb_init_connections(struct omapfb2_device *fbdev,
2377 struct omap_dss_device *def_dssdev)
2378{
2379 int i, r;
2380 struct omap_overlay_manager *mgr;
2381
2382 if (!def_dssdev->output) {
2383 dev_err(fbdev->dev, "no output for the default display\n");
2384 return -EINVAL;
2385 }
2386
2387 for (i = 0; i < fbdev->num_displays; ++i) {
2388 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
2389 struct omap_dss_output *out = dssdev->output;
2390
2391 mgr = omap_dss_get_overlay_manager(dssdev->channel);
2392
2393 if (!mgr || !out)
2394 continue;
2395
2396 if (mgr->output)
2397 mgr->unset_output(mgr);
2398
2399 mgr->set_output(mgr, out);
2400 }
2401
2402 mgr = def_dssdev->output->manager;
2403
2404 if (!mgr) {
2405 dev_err(fbdev->dev, "no ovl manager for the default display\n");
2406 return -EINVAL;
2407 }
2408
2409 for (i = 0; i < fbdev->num_overlays; i++) {
2410 struct omap_overlay *ovl = fbdev->overlays[i];
2411
2412 if (ovl->manager)
2413 ovl->unset_manager(ovl);
2414
2415 r = ovl->set_manager(ovl, mgr);
2416 if (r)
2417 dev_warn(fbdev->dev,
2418 "failed to connect overlay %s to manager %s\n",
2419 ovl->name, mgr->name);
2420 }
2421
2422 return 0;
2423}
2424
2374static int __init omapfb_probe(struct platform_device *pdev) 2425static int __init omapfb_probe(struct platform_device *pdev)
2375{ 2426{
2376 struct omapfb2_device *fbdev = NULL; 2427 struct omapfb2_device *fbdev = NULL;
2377 int r = 0; 2428 int r = 0;
2378 int i; 2429 int i;
2379 struct omap_overlay *ovl;
2380 struct omap_dss_device *def_display; 2430 struct omap_dss_device *def_display;
2381 struct omap_dss_device *dssdev; 2431 struct omap_dss_device *dssdev;
2382 struct omap_dss_device *ovl_device;
2383 2432
2384 DBG("omapfb_probe\n"); 2433 DBG("omapfb_probe\n");
2385 2434
@@ -2389,7 +2438,8 @@ static int __init omapfb_probe(struct platform_device *pdev)
2389 goto err0; 2438 goto err0;
2390 } 2439 }
2391 2440
2392 fbdev = kzalloc(sizeof(struct omapfb2_device), GFP_KERNEL); 2441 fbdev = devm_kzalloc(&pdev->dev, sizeof(struct omapfb2_device),
2442 GFP_KERNEL);
2393 if (fbdev == NULL) { 2443 if (fbdev == NULL) {
2394 r = -ENOMEM; 2444 r = -ENOMEM;
2395 goto err0; 2445 goto err0;
@@ -2401,13 +2451,15 @@ static int __init omapfb_probe(struct platform_device *pdev)
2401 "ignoring the module parameter vrfb=y\n"); 2451 "ignoring the module parameter vrfb=y\n");
2402 } 2452 }
2403 2453
2454 r = omapdss_compat_init();
2455 if (r)
2456 goto err0;
2404 2457
2405 mutex_init(&fbdev->mtx); 2458 mutex_init(&fbdev->mtx);
2406 2459
2407 fbdev->dev = &pdev->dev; 2460 fbdev->dev = &pdev->dev;
2408 platform_set_drvdata(pdev, fbdev); 2461 platform_set_drvdata(pdev, fbdev);
2409 2462
2410 r = 0;
2411 fbdev->num_displays = 0; 2463 fbdev->num_displays = 0;
2412 dssdev = NULL; 2464 dssdev = NULL;
2413 for_each_dss_dev(dssdev) { 2465 for_each_dss_dev(dssdev) {
@@ -2430,9 +2482,6 @@ static int __init omapfb_probe(struct platform_device *pdev)
2430 d->update_mode = OMAPFB_AUTO_UPDATE; 2482 d->update_mode = OMAPFB_AUTO_UPDATE;
2431 } 2483 }
2432 2484
2433 if (r)
2434 goto cleanup;
2435
2436 if (fbdev->num_displays == 0) { 2485 if (fbdev->num_displays == 0) {
2437 dev_err(&pdev->dev, "no displays\n"); 2486 dev_err(&pdev->dev, "no displays\n");
2438 r = -EINVAL; 2487 r = -EINVAL;
@@ -2447,15 +2496,33 @@ static int __init omapfb_probe(struct platform_device *pdev)
2447 for (i = 0; i < fbdev->num_managers; i++) 2496 for (i = 0; i < fbdev->num_managers; i++)
2448 fbdev->managers[i] = omap_dss_get_overlay_manager(i); 2497 fbdev->managers[i] = omap_dss_get_overlay_manager(i);
2449 2498
2450 /* gfx overlay should be the default one. find a display 2499 def_display = NULL;
2451 * connected to that, and use it as default display */ 2500
2452 ovl = omap_dss_get_overlay(0); 2501 for (i = 0; i < fbdev->num_displays; ++i) {
2453 ovl_device = ovl->get_device(ovl); 2502 struct omap_dss_device *dssdev;
2454 if (ovl_device) { 2503 const char *def_name;
2455 def_display = ovl_device; 2504
2456 } else { 2505 def_name = omapdss_get_default_display_name();
2457 dev_warn(&pdev->dev, "cannot find default display\n"); 2506
2458 def_display = NULL; 2507 dssdev = fbdev->displays[i].dssdev;
2508
2509 if (def_name == NULL ||
2510 (dssdev->name && strcmp(def_name, dssdev->name) == 0)) {
2511 def_display = dssdev;
2512 break;
2513 }
2514 }
2515
2516 if (def_display == NULL) {
2517 dev_err(fbdev->dev, "failed to find default display\n");
2518 r = -EINVAL;
2519 goto cleanup;
2520 }
2521
2522 r = omapfb_init_connections(fbdev, def_display);
2523 if (r) {
2524 dev_err(fbdev->dev, "failed to init overlay connections\n");
2525 goto cleanup;
2459 } 2526 }
2460 2527
2461 if (def_mode && strlen(def_mode) > 0) { 2528 if (def_mode && strlen(def_mode) > 0) {
@@ -2506,6 +2573,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
2506 2573
2507cleanup: 2574cleanup:
2508 omapfb_free_resources(fbdev); 2575 omapfb_free_resources(fbdev);
2576 omapdss_compat_uninit();
2509err0: 2577err0:
2510 dev_err(&pdev->dev, "failed to setup omapfb\n"); 2578 dev_err(&pdev->dev, "failed to setup omapfb\n");
2511 return r; 2579 return r;
@@ -2521,6 +2589,8 @@ static int __exit omapfb_remove(struct platform_device *pdev)
2521 2589
2522 omapfb_free_resources(fbdev); 2590 omapfb_free_resources(fbdev);
2523 2591
2592 omapdss_compat_uninit();
2593
2524 return 0; 2594 return 0;
2525} 2595}
2526 2596
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 17aa174e187c..18fa9e1d0033 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -441,6 +441,7 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
441 struct fb_info *fbi = dev_get_drvdata(dev); 441 struct fb_info *fbi = dev_get_drvdata(dev);
442 struct omapfb_info *ofbi = FB2OFB(fbi); 442 struct omapfb_info *ofbi = FB2OFB(fbi);
443 struct omapfb2_device *fbdev = ofbi->fbdev; 443 struct omapfb2_device *fbdev = ofbi->fbdev;
444 struct omap_dss_device *display = fb2display(fbi);
444 struct omapfb2_mem_region *rg; 445 struct omapfb2_mem_region *rg;
445 unsigned long size; 446 unsigned long size;
446 int r; 447 int r;
@@ -455,6 +456,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
455 if (!lock_fb_info(fbi)) 456 if (!lock_fb_info(fbi))
456 return -ENODEV; 457 return -ENODEV;
457 458
459 if (display && display->driver->sync)
460 display->driver->sync(display);
461
458 rg = ofbi->region; 462 rg = ofbi->region;
459 463
460 down_write_nested(&rg->lock, rg->id); 464 down_write_nested(&rg->lock, rg->id);
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 5ced9b334d35..623cd872a367 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -28,6 +28,8 @@
28#endif 28#endif
29 29
30#include <linux/rwsem.h> 30#include <linux/rwsem.h>
31#include <linux/dma-attrs.h>
32#include <linux/dma-mapping.h>
31 33
32#include <video/omapdss.h> 34#include <video/omapdss.h>
33 35
@@ -49,6 +51,9 @@ extern bool omapfb_debug;
49 51
50struct omapfb2_mem_region { 52struct omapfb2_mem_region {
51 int id; 53 int id;
54 struct dma_attrs attrs;
55 void *token;
56 dma_addr_t dma_handle;
52 u32 paddr; 57 u32 paddr;
53 void __iomem *vaddr; 58 void __iomem *vaddr;
54 struct vrfb vrfb; 59 struct vrfb vrfb;
@@ -124,9 +129,6 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev);
124 129
125int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg); 130int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
126 131
127int omapfb_update_window(struct fb_info *fbi,
128 u32 x, u32 y, u32 w, u32 h);
129
130int dss_mode_to_fb_mode(enum omap_color_mode dssmode, 132int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
131 struct fb_var_screeninfo *var); 133 struct fb_var_screeninfo *var);
132 134
@@ -144,16 +146,16 @@ int omapfb_set_update_mode(struct fb_info *fbi, enum omapfb_update_mode mode);
144static inline struct omap_dss_device *fb2display(struct fb_info *fbi) 146static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
145{ 147{
146 struct omapfb_info *ofbi = FB2OFB(fbi); 148 struct omapfb_info *ofbi = FB2OFB(fbi);
147 int i; 149 struct omap_overlay *ovl;
148 150
149 /* XXX: returns the display connected to first attached overlay */ 151 /* XXX: returns the display connected to first attached overlay */
150 for (i = 0; i < ofbi->num_overlays; i++) {
151 struct omap_overlay *ovl = ofbi->overlays[i];
152 152
153 return ovl->get_device(ovl); 153 if (ofbi->num_overlays == 0)
154 } 154 return NULL;
155 155
156 return NULL; 156 ovl = ofbi->overlays[0];
157
158 return ovl->get_device(ovl);
157} 159}
158 160
159static inline struct omapfb_display_data *get_display_data( 161static inline struct omapfb_display_data *get_display_data(
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
deleted file mode 100644
index f2b15c4a75bc..000000000000
--- a/drivers/video/omap2/vram.c
+++ /dev/null
@@ -1,514 +0,0 @@
1/*
2 * VRAM manager for OMAP
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*#define DEBUG*/
22
23#include <linux/kernel.h>
24#include <linux/mm.h>
25#include <linux/list.h>
26#include <linux/slab.h>
27#include <linux/seq_file.h>
28#include <linux/memblock.h>
29#include <linux/completion.h>
30#include <linux/debugfs.h>
31#include <linux/jiffies.h>
32#include <linux/module.h>
33
34#include <asm/setup.h>
35
36#include <plat/vram.h>
37
38#ifdef DEBUG
39#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
40#else
41#define DBG(format, ...)
42#endif
43
44/* postponed regions are used to temporarily store region information at boot
45 * time when we cannot yet allocate the region list */
46#define MAX_POSTPONED_REGIONS 10
47
48static bool vram_initialized;
49static int postponed_cnt;
50static struct {
51 unsigned long paddr;
52 size_t size;
53} postponed_regions[MAX_POSTPONED_REGIONS];
54
55struct vram_alloc {
56 struct list_head list;
57 unsigned long paddr;
58 unsigned pages;
59};
60
61struct vram_region {
62 struct list_head list;
63 struct list_head alloc_list;
64 unsigned long paddr;
65 unsigned pages;
66};
67
68static DEFINE_MUTEX(region_mutex);
69static LIST_HEAD(region_list);
70
71static struct vram_region *omap_vram_create_region(unsigned long paddr,
72 unsigned pages)
73{
74 struct vram_region *rm;
75
76 rm = kzalloc(sizeof(*rm), GFP_KERNEL);
77
78 if (rm) {
79 INIT_LIST_HEAD(&rm->alloc_list);
80 rm->paddr = paddr;
81 rm->pages = pages;
82 }
83
84 return rm;
85}
86
87#if 0
88static void omap_vram_free_region(struct vram_region *vr)
89{
90 list_del(&vr->list);
91 kfree(vr);
92}
93#endif
94
95static struct vram_alloc *omap_vram_create_allocation(struct vram_region *vr,
96 unsigned long paddr, unsigned pages)
97{
98 struct vram_alloc *va;
99 struct vram_alloc *new;
100
101 new = kzalloc(sizeof(*va), GFP_KERNEL);
102
103 if (!new)
104 return NULL;
105
106 new->paddr = paddr;
107 new->pages = pages;
108
109 list_for_each_entry(va, &vr->alloc_list, list) {
110 if (va->paddr > new->paddr)
111 break;
112 }
113
114 list_add_tail(&new->list, &va->list);
115
116 return new;
117}
118
119static void omap_vram_free_allocation(struct vram_alloc *va)
120{
121 list_del(&va->list);
122 kfree(va);
123}
124
125int omap_vram_add_region(unsigned long paddr, size_t size)
126{
127 struct vram_region *rm;
128 unsigned pages;
129
130 if (vram_initialized) {
131 DBG("adding region paddr %08lx size %d\n",
132 paddr, size);
133
134 size &= PAGE_MASK;
135 pages = size >> PAGE_SHIFT;
136
137 rm = omap_vram_create_region(paddr, pages);
138 if (rm == NULL)
139 return -ENOMEM;
140
141 list_add(&rm->list, &region_list);
142 } else {
143 if (postponed_cnt == MAX_POSTPONED_REGIONS)
144 return -ENOMEM;
145
146 postponed_regions[postponed_cnt].paddr = paddr;
147 postponed_regions[postponed_cnt].size = size;
148
149 ++postponed_cnt;
150 }
151 return 0;
152}
153
154int omap_vram_free(unsigned long paddr, size_t size)
155{
156 struct vram_region *rm;
157 struct vram_alloc *alloc;
158 unsigned start, end;
159
160 DBG("free mem paddr %08lx size %d\n", paddr, size);
161
162 size = PAGE_ALIGN(size);
163
164 mutex_lock(&region_mutex);
165
166 list_for_each_entry(rm, &region_list, list) {
167 list_for_each_entry(alloc, &rm->alloc_list, list) {
168 start = alloc->paddr;
169 end = alloc->paddr + (alloc->pages >> PAGE_SHIFT);
170
171 if (start >= paddr && end < paddr + size)
172 goto found;
173 }
174 }
175
176 mutex_unlock(&region_mutex);
177 return -EINVAL;
178
179found:
180 omap_vram_free_allocation(alloc);
181
182 mutex_unlock(&region_mutex);
183 return 0;
184}
185EXPORT_SYMBOL(omap_vram_free);
186
187static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
188{
189 struct vram_region *rm;
190 struct vram_alloc *alloc;
191 size_t size;
192
193 size = pages << PAGE_SHIFT;
194
195 list_for_each_entry(rm, &region_list, list) {
196 unsigned long start, end;
197
198 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
199
200 start = rm->paddr;
201 end = start + (rm->pages << PAGE_SHIFT) - 1;
202 if (start > paddr || end < paddr + size - 1)
203 continue;
204
205 DBG("block ok, checking allocs\n");
206
207 list_for_each_entry(alloc, &rm->alloc_list, list) {
208 end = alloc->paddr - 1;
209
210 if (start <= paddr && end >= paddr + size - 1)
211 goto found;
212
213 start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
214 }
215
216 end = rm->paddr + (rm->pages << PAGE_SHIFT) - 1;
217
218 if (!(start <= paddr && end >= paddr + size - 1))
219 continue;
220found:
221 DBG("found area start %lx, end %lx\n", start, end);
222
223 if (omap_vram_create_allocation(rm, paddr, pages) == NULL)
224 return -ENOMEM;
225
226 return 0;
227 }
228
229 return -ENOMEM;
230}
231
232int omap_vram_reserve(unsigned long paddr, size_t size)
233{
234 unsigned pages;
235 int r;
236
237 DBG("reserve mem paddr %08lx size %d\n", paddr, size);
238
239 size = PAGE_ALIGN(size);
240 pages = size >> PAGE_SHIFT;
241
242 mutex_lock(&region_mutex);
243
244 r = _omap_vram_reserve(paddr, pages);
245
246 mutex_unlock(&region_mutex);
247
248 return r;
249}
250EXPORT_SYMBOL(omap_vram_reserve);
251
252static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
253{
254 struct vram_region *rm;
255 struct vram_alloc *alloc;
256
257 list_for_each_entry(rm, &region_list, list) {
258 unsigned long start, end;
259
260 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
261
262 start = rm->paddr;
263
264 list_for_each_entry(alloc, &rm->alloc_list, list) {
265 end = alloc->paddr;
266
267 if (end - start >= pages << PAGE_SHIFT)
268 goto found;
269
270 start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
271 }
272
273 end = rm->paddr + (rm->pages << PAGE_SHIFT);
274found:
275 if (end - start < pages << PAGE_SHIFT)
276 continue;
277
278 DBG("found %lx, end %lx\n", start, end);
279
280 alloc = omap_vram_create_allocation(rm, start, pages);
281 if (alloc == NULL)
282 return -ENOMEM;
283
284 *paddr = start;
285
286 return 0;
287 }
288
289 return -ENOMEM;
290}
291
292int omap_vram_alloc(size_t size, unsigned long *paddr)
293{
294 unsigned pages;
295 int r;
296
297 BUG_ON(!size);
298
299 DBG("alloc mem size %d\n", size);
300
301 size = PAGE_ALIGN(size);
302 pages = size >> PAGE_SHIFT;
303
304 mutex_lock(&region_mutex);
305
306 r = _omap_vram_alloc(pages, paddr);
307
308 mutex_unlock(&region_mutex);
309
310 return r;
311}
312EXPORT_SYMBOL(omap_vram_alloc);
313
314void omap_vram_get_info(unsigned long *vram,
315 unsigned long *free_vram,
316 unsigned long *largest_free_block)
317{
318 struct vram_region *vr;
319 struct vram_alloc *va;
320
321 *vram = 0;
322 *free_vram = 0;
323 *largest_free_block = 0;
324
325 mutex_lock(&region_mutex);
326
327 list_for_each_entry(vr, &region_list, list) {
328 unsigned free;
329 unsigned long pa;
330
331 pa = vr->paddr;
332 *vram += vr->pages << PAGE_SHIFT;
333
334 list_for_each_entry(va, &vr->alloc_list, list) {
335 free = va->paddr - pa;
336 *free_vram += free;
337 if (free > *largest_free_block)
338 *largest_free_block = free;
339 pa = va->paddr + (va->pages << PAGE_SHIFT);
340 }
341
342 free = vr->paddr + (vr->pages << PAGE_SHIFT) - pa;
343 *free_vram += free;
344 if (free > *largest_free_block)
345 *largest_free_block = free;
346 }
347
348 mutex_unlock(&region_mutex);
349}
350EXPORT_SYMBOL(omap_vram_get_info);
351
352#if defined(CONFIG_DEBUG_FS)
353static int vram_debug_show(struct seq_file *s, void *unused)
354{
355 struct vram_region *vr;
356 struct vram_alloc *va;
357 unsigned size;
358
359 mutex_lock(&region_mutex);
360
361 list_for_each_entry(vr, &region_list, list) {
362 size = vr->pages << PAGE_SHIFT;
363 seq_printf(s, "%08lx-%08lx (%d bytes)\n",
364 vr->paddr, vr->paddr + size - 1,
365 size);
366
367 list_for_each_entry(va, &vr->alloc_list, list) {
368 size = va->pages << PAGE_SHIFT;
369 seq_printf(s, " %08lx-%08lx (%d bytes)\n",
370 va->paddr, va->paddr + size - 1,
371 size);
372 }
373 }
374
375 mutex_unlock(&region_mutex);
376
377 return 0;
378}
379
380static int vram_debug_open(struct inode *inode, struct file *file)
381{
382 return single_open(file, vram_debug_show, inode->i_private);
383}
384
385static const struct file_operations vram_debug_fops = {
386 .open = vram_debug_open,
387 .read = seq_read,
388 .llseek = seq_lseek,
389 .release = single_release,
390};
391
392static int __init omap_vram_create_debugfs(void)
393{
394 struct dentry *d;
395
396 d = debugfs_create_file("vram", S_IRUGO, NULL,
397 NULL, &vram_debug_fops);
398 if (IS_ERR(d))
399 return PTR_ERR(d);
400
401 return 0;
402}
403#endif
404
405static __init int omap_vram_init(void)
406{
407 int i;
408
409 vram_initialized = 1;
410
411 for (i = 0; i < postponed_cnt; i++)
412 omap_vram_add_region(postponed_regions[i].paddr,
413 postponed_regions[i].size);
414
415#ifdef CONFIG_DEBUG_FS
416 if (omap_vram_create_debugfs())
417 pr_err("VRAM: Failed to create debugfs file\n");
418#endif
419
420 return 0;
421}
422
423arch_initcall(omap_vram_init);
424
425/* boottime vram alloc stuff */
426
427/* set from board file */
428static u32 omap_vram_sdram_start __initdata;
429static u32 omap_vram_sdram_size __initdata;
430
431/* set from kernel cmdline */
432static u32 omap_vram_def_sdram_size __initdata;
433static u32 omap_vram_def_sdram_start __initdata;
434
435static int __init omap_vram_early_vram(char *p)
436{
437 omap_vram_def_sdram_size = memparse(p, &p);
438 if (*p == ',')
439 omap_vram_def_sdram_start = simple_strtoul(p + 1, &p, 16);
440 return 0;
441}
442early_param("vram", omap_vram_early_vram);
443
444/*
445 * Called from map_io. We need to call to this early enough so that we
446 * can reserve the fixed SDRAM regions before VM could get hold of them.
447 */
448void __init omap_vram_reserve_sdram_memblock(void)
449{
450 u32 paddr;
451 u32 size = 0;
452
453 /* cmdline arg overrides the board file definition */
454 if (omap_vram_def_sdram_size) {
455 size = omap_vram_def_sdram_size;
456 paddr = omap_vram_def_sdram_start;
457 }
458
459 if (!size) {
460 size = omap_vram_sdram_size;
461 paddr = omap_vram_sdram_start;
462 }
463
464#ifdef CONFIG_OMAP2_VRAM_SIZE
465 if (!size) {
466 size = CONFIG_OMAP2_VRAM_SIZE * 1024 * 1024;
467 paddr = 0;
468 }
469#endif
470
471 if (!size)
472 return;
473
474 size = ALIGN(size, SZ_2M);
475
476 if (paddr) {
477 if (paddr & ~PAGE_MASK) {
478 pr_err("VRAM start address 0x%08x not page aligned\n",
479 paddr);
480 return;
481 }
482
483 if (!memblock_is_region_memory(paddr, size)) {
484 pr_err("Illegal SDRAM region 0x%08x..0x%08x for VRAM\n",
485 paddr, paddr + size - 1);
486 return;
487 }
488
489 if (memblock_is_region_reserved(paddr, size)) {
490 pr_err("FB: failed to reserve VRAM - busy\n");
491 return;
492 }
493
494 if (memblock_reserve(paddr, size) < 0) {
495 pr_err("FB: failed to reserve VRAM - no memory\n");
496 return;
497 }
498 } else {
499 paddr = memblock_alloc(size, SZ_2M);
500 }
501
502 memblock_free(paddr, size);
503 memblock_remove(paddr, size);
504
505 omap_vram_add_region(paddr, size);
506
507 pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
508}
509
510void __init omap_vram_set_sdram_vram(u32 size, u32 start)
511{
512 omap_vram_sdram_start = start;
513 omap_vram_sdram_size = size;
514}
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 2ed7b633bbd9..1a00ad241edd 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -189,7 +189,7 @@ struct s3c_fb_vsync {
189 189
190/** 190/**
191 * struct s3c_fb - overall hardware state of the hardware 191 * struct s3c_fb - overall hardware state of the hardware
192 * @slock: The spinlock protection for this data sturucture. 192 * @slock: The spinlock protection for this data structure.
193 * @dev: The device that we bound to, for printing, etc. 193 * @dev: The device that we bound to, for printing, etc.
194 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. 194 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
195 * @lcd_clk: The clk (sclk) feeding pixclk. 195 * @lcd_clk: The clk (sclk) feeding pixclk.
@@ -268,10 +268,10 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
268 case 8: 268 case 8:
269 if (sfb->variant.palette[win->index] != 0) { 269 if (sfb->variant.palette[win->index] != 0) {
270 /* non palletised, A:1,R:2,G:3,B:2 mode */ 270 /* non palletised, A:1,R:2,G:3,B:2 mode */
271 var->red.offset = 4; 271 var->red.offset = 5;
272 var->green.offset = 2; 272 var->green.offset = 2;
273 var->blue.offset = 0; 273 var->blue.offset = 0;
274 var->red.length = 5; 274 var->red.length = 2;
275 var->green.length = 3; 275 var->green.length = 3;
276 var->blue.length = 2; 276 var->blue.length = 2;
277 var->transp.offset = 7; 277 var->transp.offset = 7;
@@ -288,6 +288,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
288 /* 666 with one bit alpha/transparency */ 288 /* 666 with one bit alpha/transparency */
289 var->transp.offset = 18; 289 var->transp.offset = 18;
290 var->transp.length = 1; 290 var->transp.length = 1;
291 /* drop through */
291 case 18: 292 case 18:
292 var->bits_per_pixel = 32; 293 var->bits_per_pixel = 32;
293 294
@@ -329,6 +330,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
329 330
330 default: 331 default:
331 dev_err(sfb->dev, "invalid bpp\n"); 332 dev_err(sfb->dev, "invalid bpp\n");
333 return -EINVAL;
332 } 334 }
333 335
334 dev_dbg(sfb->dev, "%s: verified parameters\n", __func__); 336 dev_dbg(sfb->dev, "%s: verified parameters\n", __func__);
@@ -1544,8 +1546,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
1544#ifdef CONFIG_PM_SLEEP 1546#ifdef CONFIG_PM_SLEEP
1545static int s3c_fb_suspend(struct device *dev) 1547static int s3c_fb_suspend(struct device *dev)
1546{ 1548{
1547 struct platform_device *pdev = to_platform_device(dev); 1549 struct s3c_fb *sfb = dev_get_drvdata(dev);
1548 struct s3c_fb *sfb = platform_get_drvdata(pdev);
1549 struct s3c_fb_win *win; 1550 struct s3c_fb_win *win;
1550 int win_no; 1551 int win_no;
1551 1552
@@ -1572,8 +1573,7 @@ static int s3c_fb_suspend(struct device *dev)
1572 1573
1573static int s3c_fb_resume(struct device *dev) 1574static int s3c_fb_resume(struct device *dev)
1574{ 1575{
1575 struct platform_device *pdev = to_platform_device(dev); 1576 struct s3c_fb *sfb = dev_get_drvdata(dev);
1576 struct s3c_fb *sfb = platform_get_drvdata(pdev);
1577 struct s3c_fb_platdata *pd = sfb->pdata; 1577 struct s3c_fb_platdata *pd = sfb->pdata;
1578 struct s3c_fb_win *win; 1578 struct s3c_fb_win *win;
1579 int win_no; 1579 int win_no;
@@ -1623,7 +1623,7 @@ static int s3c_fb_resume(struct device *dev)
1623 if (!win) 1623 if (!win)
1624 continue; 1624 continue;
1625 1625
1626 dev_dbg(&pdev->dev, "resuming window %d\n", win_no); 1626 dev_dbg(dev, "resuming window %d\n", win_no);
1627 s3c_fb_set_par(win->fbinfo); 1627 s3c_fb_set_par(win->fbinfo);
1628 } 1628 }
1629 1629
@@ -1636,8 +1636,7 @@ static int s3c_fb_resume(struct device *dev)
1636#ifdef CONFIG_PM_RUNTIME 1636#ifdef CONFIG_PM_RUNTIME
1637static int s3c_fb_runtime_suspend(struct device *dev) 1637static int s3c_fb_runtime_suspend(struct device *dev)
1638{ 1638{
1639 struct platform_device *pdev = to_platform_device(dev); 1639 struct s3c_fb *sfb = dev_get_drvdata(dev);
1640 struct s3c_fb *sfb = platform_get_drvdata(pdev);
1641 1640
1642 if (!sfb->variant.has_clksel) 1641 if (!sfb->variant.has_clksel)
1643 clk_disable_unprepare(sfb->lcd_clk); 1642 clk_disable_unprepare(sfb->lcd_clk);
@@ -1649,8 +1648,7 @@ static int s3c_fb_runtime_suspend(struct device *dev)
1649 1648
1650static int s3c_fb_runtime_resume(struct device *dev) 1649static int s3c_fb_runtime_resume(struct device *dev)
1651{ 1650{
1652 struct platform_device *pdev = to_platform_device(dev); 1651 struct s3c_fb *sfb = dev_get_drvdata(dev);
1653 struct s3c_fb *sfb = platform_get_drvdata(pdev);
1654 struct s3c_fb_platdata *pd = sfb->pdata; 1652 struct s3c_fb_platdata *pd = sfb->pdata;
1655 1653
1656 clk_prepare_enable(sfb->bus_clk); 1654 clk_prepare_enable(sfb->bus_clk);
@@ -1910,7 +1908,7 @@ static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {
1910static struct s3c_fb_driverdata s3c_fb_data_exynos5 = { 1908static struct s3c_fb_driverdata s3c_fb_data_exynos5 = {
1911 .variant = { 1909 .variant = {
1912 .nr_windows = 5, 1910 .nr_windows = 5,
1913 .vidtcon = VIDTCON0, 1911 .vidtcon = FIMD_V8_VIDTCON0,
1914 .wincon = WINCON(0), 1912 .wincon = WINCON(0),
1915 .winmap = WINxMAP(0), 1913 .winmap = WINxMAP(0),
1916 .keycon = WKEYCON, 1914 .keycon = WKEYCON,
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 3951fdae5f68..f4962292792c 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -127,13 +127,12 @@ static void sh_mipi_shutdown(struct platform_device *pdev)
127 sh_mipi_dsi_enable(mipi, false); 127 sh_mipi_dsi_enable(mipi, false);
128} 128}
129 129
130static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) 130static int sh_mipi_setup(struct sh_mipi *mipi, const struct fb_videomode *mode)
131{ 131{
132 void __iomem *base = mipi->base; 132 void __iomem *base = mipi->base;
133 struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; 133 struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
134 u32 pctype, datatype, pixfmt, linelength, vmctr2; 134 u32 pctype, datatype, pixfmt, linelength, vmctr2;
135 u32 tmp, top, bottom, delay, div; 135 u32 tmp, top, bottom, delay, div;
136 bool yuv;
137 int bpp; 136 int bpp;
138 137
139 /* 138 /*
@@ -146,95 +145,79 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
146 pctype = 0; 145 pctype = 0;
147 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; 146 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
148 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 147 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
149 linelength = ch->lcd_modes[0].xres * 3; 148 linelength = mode->xres * 3;
150 yuv = false;
151 break; 149 break;
152 case MIPI_RGB565: 150 case MIPI_RGB565:
153 pctype = 1; 151 pctype = 1;
154 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; 152 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
155 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 153 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
156 linelength = ch->lcd_modes[0].xres * 2; 154 linelength = mode->xres * 2;
157 yuv = false;
158 break; 155 break;
159 case MIPI_RGB666_LP: 156 case MIPI_RGB666_LP:
160 pctype = 2; 157 pctype = 2;
161 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; 158 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
162 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 159 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
163 linelength = ch->lcd_modes[0].xres * 3; 160 linelength = mode->xres * 3;
164 yuv = false;
165 break; 161 break;
166 case MIPI_RGB666: 162 case MIPI_RGB666:
167 pctype = 3; 163 pctype = 3;
168 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; 164 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
169 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; 165 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
170 linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8; 166 linelength = (mode->xres * 18 + 7) / 8;
171 yuv = false;
172 break; 167 break;
173 case MIPI_BGR888: 168 case MIPI_BGR888:
174 pctype = 8; 169 pctype = 8;
175 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; 170 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
176 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 171 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
177 linelength = ch->lcd_modes[0].xres * 3; 172 linelength = mode->xres * 3;
178 yuv = false;
179 break; 173 break;
180 case MIPI_BGR565: 174 case MIPI_BGR565:
181 pctype = 9; 175 pctype = 9;
182 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; 176 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
183 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 177 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
184 linelength = ch->lcd_modes[0].xres * 2; 178 linelength = mode->xres * 2;
185 yuv = false;
186 break; 179 break;
187 case MIPI_BGR666_LP: 180 case MIPI_BGR666_LP:
188 pctype = 0xa; 181 pctype = 0xa;
189 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; 182 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
190 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 183 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
191 linelength = ch->lcd_modes[0].xres * 3; 184 linelength = mode->xres * 3;
192 yuv = false;
193 break; 185 break;
194 case MIPI_BGR666: 186 case MIPI_BGR666:
195 pctype = 0xb; 187 pctype = 0xb;
196 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; 188 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
197 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; 189 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
198 linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8; 190 linelength = (mode->xres * 18 + 7) / 8;
199 yuv = false;
200 break; 191 break;
201 case MIPI_YUYV: 192 case MIPI_YUYV:
202 pctype = 4; 193 pctype = 4;
203 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; 194 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
204 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 195 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
205 linelength = ch->lcd_modes[0].xres * 2; 196 linelength = mode->xres * 2;
206 yuv = true;
207 break; 197 break;
208 case MIPI_UYVY: 198 case MIPI_UYVY:
209 pctype = 5; 199 pctype = 5;
210 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; 200 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
211 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 201 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
212 linelength = ch->lcd_modes[0].xres * 2; 202 linelength = mode->xres * 2;
213 yuv = true;
214 break; 203 break;
215 case MIPI_YUV420_L: 204 case MIPI_YUV420_L:
216 pctype = 6; 205 pctype = 6;
217 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; 206 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
218 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; 207 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
219 linelength = (ch->lcd_modes[0].xres * 12 + 7) / 8; 208 linelength = (mode->xres * 12 + 7) / 8;
220 yuv = true;
221 break; 209 break;
222 case MIPI_YUV420: 210 case MIPI_YUV420:
223 pctype = 7; 211 pctype = 7;
224 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; 212 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
225 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; 213 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
226 /* Length of U/V line */ 214 /* Length of U/V line */
227 linelength = (ch->lcd_modes[0].xres + 1) / 2; 215 linelength = (mode->xres + 1) / 2;
228 yuv = true;
229 break; 216 break;
230 default: 217 default:
231 return -EINVAL; 218 return -EINVAL;
232 } 219 }
233 220
234 if ((yuv && ch->interface_type != YUV422) ||
235 (!yuv && ch->interface_type != RGB24))
236 return -EINVAL;
237
238 if (!pdata->lane) 221 if (!pdata->lane)
239 return -EINVAL; 222 return -EINVAL;
240 223
@@ -293,7 +276,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
293 */ 276 */
294 iowrite32(0x00000006, mipi->linkbase + DTCTR); 277 iowrite32(0x00000006, mipi->linkbase + DTCTR);
295 /* VSYNC width = 2 (<< 17) */ 278 /* VSYNC width = 2 (<< 17) */
296 iowrite32((ch->lcd_modes[0].vsync_len << pdata->vsynw_offset) | 279 iowrite32((mode->vsync_len << pdata->vsynw_offset) |
297 (pdata->clksrc << 16) | (pctype << 12) | datatype, 280 (pdata->clksrc << 16) | (pctype << 12) | datatype,
298 mipi->linkbase + VMCTR1); 281 mipi->linkbase + VMCTR1);
299 282
@@ -327,7 +310,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
327 top = linelength << 16; /* RGBLEN */ 310 top = linelength << 16; /* RGBLEN */
328 bottom = 0x00000001; 311 bottom = 0x00000001;
329 if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */ 312 if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */
330 bottom = (pdata->lane * ch->lcd_modes[0].hsync_len) - 10; 313 bottom = (pdata->lane * mode->hsync_len) - 10;
331 iowrite32(top | bottom , mipi->linkbase + VMLEN1); 314 iowrite32(top | bottom , mipi->linkbase + VMLEN1);
332 315
333 /* 316 /*
@@ -347,18 +330,18 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
347 div = 2; 330 div = 2;
348 331
349 if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */ 332 if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */
350 top = ch->lcd_modes[0].hsync_len + ch->lcd_modes[0].left_margin; 333 top = mode->hsync_len + mode->left_margin;
351 top = ((pdata->lane * top / div) - 10) << 16; 334 top = ((pdata->lane * top / div) - 10) << 16;
352 } 335 }
353 if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */ 336 if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */
354 bottom = ch->lcd_modes[0].right_margin; 337 bottom = mode->right_margin;
355 bottom = (pdata->lane * bottom / div) - 12; 338 bottom = (pdata->lane * bottom / div) - 12;
356 } 339 }
357 340
358 bpp = linelength / ch->lcd_modes[0].xres; /* byte / pixel */ 341 bpp = linelength / mode->xres; /* byte / pixel */
359 if ((pdata->lane / div) > bpp) { 342 if ((pdata->lane / div) > bpp) {
360 tmp = ch->lcd_modes[0].xres / bpp; /* output cycle */ 343 tmp = mode->xres / bpp; /* output cycle */
361 tmp = ch->lcd_modes[0].xres - tmp; /* (input - output) cycle */ 344 tmp = mode->xres - tmp; /* (input - output) cycle */
362 delay = (pdata->lane * tmp); 345 delay = (pdata->lane * tmp);
363 } 346 }
364 347
@@ -369,7 +352,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
369 /* setup LCD panel */ 352 /* setup LCD panel */
370 353
371 /* cf. drivers/video/omap/lcd_mipid.c */ 354 /* cf. drivers/video/omap/lcd_mipid.c */
372 sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE); 355 sh_mipi_dcs(pdata->channel, MIPI_DCS_EXIT_SLEEP_MODE);
373 msleep(120); 356 msleep(120);
374 /* 357 /*
375 * [7] - Page Address Mode 358 * [7] - Page Address Mode
@@ -381,11 +364,11 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
381 * [1] - Flip Horizontal 364 * [1] - Flip Horizontal
382 * [0] - Flip Vertical 365 * [0] - Flip Vertical
383 */ 366 */
384 sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00); 367 sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
385 /* cf. set_data_lines() */ 368 /* cf. set_data_lines() */
386 sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT, 369 sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_PIXEL_FORMAT,
387 pixfmt << 4); 370 pixfmt << 4);
388 sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON); 371 sh_mipi_dcs(pdata->channel, MIPI_DCS_SET_DISPLAY_ON);
389 372
390 /* Enable timeout counters */ 373 /* Enable timeout counters */
391 iowrite32(0x00000f00, base + DSICTRL); 374 iowrite32(0x00000f00, base + DSICTRL);
@@ -405,7 +388,7 @@ static int mipi_display_on(struct sh_mobile_lcdc_entity *entity)
405 if (ret < 0) 388 if (ret < 0)
406 goto mipi_display_on_fail1; 389 goto mipi_display_on_fail1;
407 390
408 ret = sh_mipi_setup(mipi, pdata); 391 ret = sh_mipi_setup(mipi, &entity->def_mode);
409 if (ret < 0) 392 if (ret < 0)
410 goto mipi_display_on_fail2; 393 goto mipi_display_on_fail2;
411 394
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 699487c287b2..e78fe4bc1524 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -438,7 +438,7 @@ static unsigned long lcdc_sys_read_data(void *handle)
438 return lcdc_read(ch->lcdc, _LDDRDR) & LDDRDR_DRD_MASK; 438 return lcdc_read(ch->lcdc, _LDDRDR) & LDDRDR_DRD_MASK;
439} 439}
440 440
441struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = { 441static struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
442 lcdc_sys_write_index, 442 lcdc_sys_write_index,
443 lcdc_sys_write_data, 443 lcdc_sys_write_data,
444 lcdc_sys_read_data, 444 lcdc_sys_read_data,
@@ -586,8 +586,8 @@ static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
586 * Just turn on, if we run a resume here, the 586 * Just turn on, if we run a resume here, the
587 * logo disappears. 587 * logo disappears.
588 */ 588 */
589 info->var.width = monspec->max_x * 10; 589 info->var.width = ch->display.width;
590 info->var.height = monspec->max_y * 10; 590 info->var.height = ch->display.height;
591 sh_mobile_lcdc_display_on(ch); 591 sh_mobile_lcdc_display_on(ch);
592 } else { 592 } else {
593 /* New monitor or have to wake up */ 593 /* New monitor or have to wake up */
@@ -1614,6 +1614,15 @@ static int sh_mobile_lcdc_overlay_blank(int blank, struct fb_info *info)
1614 return 1; 1614 return 1;
1615} 1615}
1616 1616
1617static int
1618sh_mobile_lcdc_overlay_mmap(struct fb_info *info, struct vm_area_struct *vma)
1619{
1620 struct sh_mobile_lcdc_overlay *ovl = info->par;
1621
1622 return dma_mmap_coherent(ovl->channel->lcdc->dev, vma, ovl->fb_mem,
1623 ovl->dma_handle, ovl->fb_size);
1624}
1625
1617static struct fb_ops sh_mobile_lcdc_overlay_ops = { 1626static struct fb_ops sh_mobile_lcdc_overlay_ops = {
1618 .owner = THIS_MODULE, 1627 .owner = THIS_MODULE,
1619 .fb_read = fb_sys_read, 1628 .fb_read = fb_sys_read,
@@ -1626,6 +1635,7 @@ static struct fb_ops sh_mobile_lcdc_overlay_ops = {
1626 .fb_ioctl = sh_mobile_lcdc_overlay_ioctl, 1635 .fb_ioctl = sh_mobile_lcdc_overlay_ioctl,
1627 .fb_check_var = sh_mobile_lcdc_overlay_check_var, 1636 .fb_check_var = sh_mobile_lcdc_overlay_check_var,
1628 .fb_set_par = sh_mobile_lcdc_overlay_set_par, 1637 .fb_set_par = sh_mobile_lcdc_overlay_set_par,
1638 .fb_mmap = sh_mobile_lcdc_overlay_mmap,
1629}; 1639};
1630 1640
1631static void 1641static void
@@ -2093,6 +2103,15 @@ static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
2093 return 0; 2103 return 0;
2094} 2104}
2095 2105
2106static int
2107sh_mobile_lcdc_mmap(struct fb_info *info, struct vm_area_struct *vma)
2108{
2109 struct sh_mobile_lcdc_chan *ch = info->par;
2110
2111 return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem,
2112 ch->dma_handle, ch->fb_size);
2113}
2114
2096static struct fb_ops sh_mobile_lcdc_ops = { 2115static struct fb_ops sh_mobile_lcdc_ops = {
2097 .owner = THIS_MODULE, 2116 .owner = THIS_MODULE,
2098 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 2117 .fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -2108,6 +2127,7 @@ static struct fb_ops sh_mobile_lcdc_ops = {
2108 .fb_release = sh_mobile_lcdc_release, 2127 .fb_release = sh_mobile_lcdc_release,
2109 .fb_check_var = sh_mobile_lcdc_check_var, 2128 .fb_check_var = sh_mobile_lcdc_check_var,
2110 .fb_set_par = sh_mobile_lcdc_set_par, 2129 .fb_set_par = sh_mobile_lcdc_set_par,
2130 .fb_mmap = sh_mobile_lcdc_mmap,
2111}; 2131};
2112 2132
2113static void 2133static void
@@ -2167,7 +2187,7 @@ sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan *ch)
2167 2187
2168static int __devinit 2188static int __devinit
2169sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, 2189sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
2170 const struct fb_videomode *mode, 2190 const struct fb_videomode *modes,
2171 unsigned int num_modes) 2191 unsigned int num_modes)
2172{ 2192{
2173 struct sh_mobile_lcdc_priv *priv = ch->lcdc; 2193 struct sh_mobile_lcdc_priv *priv = ch->lcdc;
@@ -2193,7 +2213,7 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
2193 info->pseudo_palette = &ch->pseudo_palette; 2213 info->pseudo_palette = &ch->pseudo_palette;
2194 info->par = ch; 2214 info->par = ch;
2195 2215
2196 fb_videomode_to_modelist(mode, num_modes, &info->modelist); 2216 fb_videomode_to_modelist(modes, num_modes, &info->modelist);
2197 2217
2198 ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0); 2218 ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
2199 if (ret < 0) { 2219 if (ret < 0) {
@@ -2227,9 +2247,9 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
2227 * default. 2247 * default.
2228 */ 2248 */
2229 var = &info->var; 2249 var = &info->var;
2230 fb_videomode_to_var(var, mode); 2250 fb_videomode_to_var(var, modes);
2231 var->width = ch->cfg->panel_cfg.width; 2251 var->width = ch->display.width;
2232 var->height = ch->cfg->panel_cfg.height; 2252 var->height = ch->display.height;
2233 var->xres_virtual = ch->xres_virtual; 2253 var->xres_virtual = ch->xres_virtual;
2234 var->yres_virtual = ch->yres_virtual; 2254 var->yres_virtual = ch->yres_virtual;
2235 var->activate = FB_ACTIVATE_NOW; 2255 var->activate = FB_ACTIVATE_NOW;
@@ -2262,6 +2282,7 @@ static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
2262 bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) 2282 bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
2263 brightness = 0; 2283 brightness = 0;
2264 2284
2285 ch->bl_brightness = brightness;
2265 return ch->cfg->bl_info.set_brightness(brightness); 2286 return ch->cfg->bl_info.set_brightness(brightness);
2266} 2287}
2267 2288
@@ -2269,7 +2290,7 @@ static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
2269{ 2290{
2270 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); 2291 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
2271 2292
2272 return ch->cfg->bl_info.get_brightness(); 2293 return ch->bl_brightness;
2273} 2294}
2274 2295
2275static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev, 2296static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
@@ -2516,10 +2537,10 @@ static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *
2516} 2537}
2517 2538
2518static int __devinit 2539static int __devinit
2519sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv, 2540sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_overlay *ovl)
2520 struct sh_mobile_lcdc_overlay *ovl)
2521{ 2541{
2522 const struct sh_mobile_lcdc_format_info *format; 2542 const struct sh_mobile_lcdc_format_info *format;
2543 struct device *dev = ovl->channel->lcdc->dev;
2523 int ret; 2544 int ret;
2524 2545
2525 if (ovl->cfg->fourcc == 0) 2546 if (ovl->cfg->fourcc == 0)
@@ -2528,7 +2549,7 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
2528 /* Validate the format. */ 2549 /* Validate the format. */
2529 format = sh_mobile_format_info(ovl->cfg->fourcc); 2550 format = sh_mobile_format_info(ovl->cfg->fourcc);
2530 if (format == NULL) { 2551 if (format == NULL) {
2531 dev_err(priv->dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc); 2552 dev_err(dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc);
2532 return -EINVAL; 2553 return -EINVAL;
2533 } 2554 }
2534 2555
@@ -2556,10 +2577,10 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
2556 /* Allocate frame buffer memory. */ 2577 /* Allocate frame buffer memory. */
2557 ovl->fb_size = ovl->cfg->max_xres * ovl->cfg->max_yres 2578 ovl->fb_size = ovl->cfg->max_xres * ovl->cfg->max_yres
2558 * format->bpp / 8 * 2; 2579 * format->bpp / 8 * 2;
2559 ovl->fb_mem = dma_alloc_coherent(priv->dev, ovl->fb_size, 2580 ovl->fb_mem = dma_alloc_coherent(dev, ovl->fb_size, &ovl->dma_handle,
2560 &ovl->dma_handle, GFP_KERNEL); 2581 GFP_KERNEL);
2561 if (!ovl->fb_mem) { 2582 if (!ovl->fb_mem) {
2562 dev_err(priv->dev, "unable to allocate buffer\n"); 2583 dev_err(dev, "unable to allocate buffer\n");
2563 return -ENOMEM; 2584 return -ENOMEM;
2564 } 2585 }
2565 2586
@@ -2571,11 +2592,11 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
2571} 2592}
2572 2593
2573static int __devinit 2594static int __devinit
2574sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, 2595sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch)
2575 struct sh_mobile_lcdc_chan *ch)
2576{ 2596{
2577 const struct sh_mobile_lcdc_format_info *format; 2597 const struct sh_mobile_lcdc_format_info *format;
2578 const struct sh_mobile_lcdc_chan_cfg *cfg = ch->cfg; 2598 const struct sh_mobile_lcdc_chan_cfg *cfg = ch->cfg;
2599 struct device *dev = ch->lcdc->dev;
2579 const struct fb_videomode *max_mode; 2600 const struct fb_videomode *max_mode;
2580 const struct fb_videomode *mode; 2601 const struct fb_videomode *mode;
2581 unsigned int num_modes; 2602 unsigned int num_modes;
@@ -2588,7 +2609,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
2588 /* Validate the format. */ 2609 /* Validate the format. */
2589 format = sh_mobile_format_info(cfg->fourcc); 2610 format = sh_mobile_format_info(cfg->fourcc);
2590 if (format == NULL) { 2611 if (format == NULL) {
2591 dev_err(priv->dev, "Invalid FOURCC %08x.\n", cfg->fourcc); 2612 dev_err(dev, "Invalid FOURCC %08x.\n", cfg->fourcc);
2592 return -EINVAL; 2613 return -EINVAL;
2593 } 2614 }
2594 2615
@@ -2604,7 +2625,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
2604 /* NV12/NV21 buffers must have even number of lines */ 2625 /* NV12/NV21 buffers must have even number of lines */
2605 if ((cfg->fourcc == V4L2_PIX_FMT_NV12 || 2626 if ((cfg->fourcc == V4L2_PIX_FMT_NV12 ||
2606 cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) { 2627 cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) {
2607 dev_err(priv->dev, "yres must be multiple of 2 for " 2628 dev_err(dev, "yres must be multiple of 2 for "
2608 "YCbCr420 mode.\n"); 2629 "YCbCr420 mode.\n");
2609 return -EINVAL; 2630 return -EINVAL;
2610 } 2631 }
@@ -2618,7 +2639,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
2618 if (!max_size) 2639 if (!max_size)
2619 max_size = MAX_XRES * MAX_YRES; 2640 max_size = MAX_XRES * MAX_YRES;
2620 else 2641 else
2621 dev_dbg(priv->dev, "Found largest videomode %ux%u\n", 2642 dev_dbg(dev, "Found largest videomode %ux%u\n",
2622 max_mode->xres, max_mode->yres); 2643 max_mode->xres, max_mode->yres);
2623 2644
2624 if (cfg->lcd_modes == NULL) { 2645 if (cfg->lcd_modes == NULL) {
@@ -2652,10 +2673,10 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
2652 2673
2653 /* Allocate frame buffer memory. */ 2674 /* Allocate frame buffer memory. */
2654 ch->fb_size = max_size * format->bpp / 8 * 2; 2675 ch->fb_size = max_size * format->bpp / 8 * 2;
2655 ch->fb_mem = dma_alloc_coherent(priv->dev, ch->fb_size, &ch->dma_handle, 2676 ch->fb_mem = dma_alloc_coherent(dev, ch->fb_size, &ch->dma_handle,
2656 GFP_KERNEL); 2677 GFP_KERNEL);
2657 if (ch->fb_mem == NULL) { 2678 if (ch->fb_mem == NULL) {
2658 dev_err(priv->dev, "unable to allocate buffer\n"); 2679 dev_err(dev, "unable to allocate buffer\n");
2659 return -ENOMEM; 2680 return -ENOMEM;
2660 } 2681 }
2661 2682
@@ -2663,8 +2684,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
2663 if (cfg->tx_dev) { 2684 if (cfg->tx_dev) {
2664 if (!cfg->tx_dev->dev.driver || 2685 if (!cfg->tx_dev->dev.driver ||
2665 !try_module_get(cfg->tx_dev->dev.driver->owner)) { 2686 !try_module_get(cfg->tx_dev->dev.driver->owner)) {
2666 dev_warn(priv->dev, 2687 dev_warn(dev, "unable to get transmitter device\n");
2667 "unable to get transmitter device\n");
2668 return -EINVAL; 2688 return -EINVAL;
2669 } 2689 }
2670 ch->tx_dev = platform_get_drvdata(cfg->tx_dev); 2690 ch->tx_dev = platform_get_drvdata(cfg->tx_dev);
@@ -2772,9 +2792,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
2772 pm_runtime_enable(&pdev->dev); 2792 pm_runtime_enable(&pdev->dev);
2773 2793
2774 for (i = 0; i < num_channels; i++) { 2794 for (i = 0; i < num_channels; i++) {
2775 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 2795 struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
2776 2796
2777 error = sh_mobile_lcdc_channel_init(priv, ch); 2797 error = sh_mobile_lcdc_channel_init(ch);
2778 if (error) 2798 if (error)
2779 goto err1; 2799 goto err1;
2780 } 2800 }
@@ -2785,7 +2805,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
2785 ovl->cfg = &pdata->overlays[i]; 2805 ovl->cfg = &pdata->overlays[i];
2786 ovl->channel = &priv->ch[0]; 2806 ovl->channel = &priv->ch[0];
2787 2807
2788 error = sh_mobile_lcdc_overlay_init(priv, ovl); 2808 error = sh_mobile_lcdc_overlay_init(ovl);
2789 if (error) 2809 if (error)
2790 goto err1; 2810 goto err1;
2791 } 2811 }
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index 0f92f6544b94..f839adef1d90 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -94,6 +94,7 @@ struct sh_mobile_lcdc_chan {
94 94
95 /* Backlight */ 95 /* Backlight */
96 struct backlight_device *bl; 96 struct backlight_device *bl;
97 unsigned int bl_brightness;
97 98
98 /* FB */ 99 /* FB */
99 struct fb_info *info; 100 struct fb_info *info;
diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
new file mode 100644
index 000000000000..6101f5c2f62f
--- /dev/null
+++ b/drivers/video/ssd1307fb.c
@@ -0,0 +1,396 @@
1/*
2 * Driver for the Solomon SSD1307 OLED controler
3 *
4 * Copyright 2012 Free Electrons
5 *
6 * Licensed under the GPLv2 or later.
7 */
8
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/i2c.h>
12#include <linux/fb.h>
13#include <linux/uaccess.h>
14#include <linux/of_device.h>
15#include <linux/of_gpio.h>
16#include <linux/pwm.h>
17#include <linux/delay.h>
18
19#define SSD1307FB_WIDTH 96
20#define SSD1307FB_HEIGHT 16
21
22#define SSD1307FB_DATA 0x40
23#define SSD1307FB_COMMAND 0x80
24
25#define SSD1307FB_CONTRAST 0x81
26#define SSD1307FB_SEG_REMAP_ON 0xa1
27#define SSD1307FB_DISPLAY_OFF 0xae
28#define SSD1307FB_DISPLAY_ON 0xaf
29#define SSD1307FB_START_PAGE_ADDRESS 0xb0
30
31struct ssd1307fb_par {
32 struct i2c_client *client;
33 struct fb_info *info;
34 struct pwm_device *pwm;
35 u32 pwm_period;
36 int reset;
37};
38
39static struct fb_fix_screeninfo ssd1307fb_fix __devinitdata = {
40 .id = "Solomon SSD1307",
41 .type = FB_TYPE_PACKED_PIXELS,
42 .visual = FB_VISUAL_MONO10,
43 .xpanstep = 0,
44 .ypanstep = 0,
45 .ywrapstep = 0,
46 .line_length = SSD1307FB_WIDTH / 8,
47 .accel = FB_ACCEL_NONE,
48};
49
50static struct fb_var_screeninfo ssd1307fb_var __devinitdata = {
51 .xres = SSD1307FB_WIDTH,
52 .yres = SSD1307FB_HEIGHT,
53 .xres_virtual = SSD1307FB_WIDTH,
54 .yres_virtual = SSD1307FB_HEIGHT,
55 .bits_per_pixel = 1,
56};
57
58static int ssd1307fb_write_array(struct i2c_client *client, u8 type, u8 *cmd, u32 len)
59{
60 u8 *buf;
61 int ret = 0;
62
63 buf = kzalloc(len + 1, GFP_KERNEL);
64 if (!buf) {
65 dev_err(&client->dev, "Couldn't allocate sending buffer.\n");
66 return -ENOMEM;
67 }
68
69 buf[0] = type;
70 memcpy(buf + 1, cmd, len);
71
72 ret = i2c_master_send(client, buf, len + 1);
73 if (ret != len + 1) {
74 dev_err(&client->dev, "Couldn't send I2C command.\n");
75 goto error;
76 }
77
78error:
79 kfree(buf);
80 return ret;
81}
82
83static inline int ssd1307fb_write_cmd_array(struct i2c_client *client, u8 *cmd, u32 len)
84{
85 return ssd1307fb_write_array(client, SSD1307FB_COMMAND, cmd, len);
86}
87
88static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd)
89{
90 return ssd1307fb_write_cmd_array(client, &cmd, 1);
91}
92
93static inline int ssd1307fb_write_data_array(struct i2c_client *client, u8 *cmd, u32 len)
94{
95 return ssd1307fb_write_array(client, SSD1307FB_DATA, cmd, len);
96}
97
98static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
99{
100 return ssd1307fb_write_data_array(client, &data, 1);
101}
102
103static void ssd1307fb_update_display(struct ssd1307fb_par *par)
104{
105 u8 *vmem = par->info->screen_base;
106 int i, j, k;
107
108 /*
109 * The screen is divided in pages, each having a height of 8
110 * pixels, and the width of the screen. When sending a byte of
111 * data to the controller, it gives the 8 bits for the current
112 * column. I.e, the first byte are the 8 bits of the first
113 * column, then the 8 bits for the second column, etc.
114 *
115 *
116 * Representation of the screen, assuming it is 5 bits
117 * wide. Each letter-number combination is a bit that controls
118 * one pixel.
119 *
120 * A0 A1 A2 A3 A4
121 * B0 B1 B2 B3 B4
122 * C0 C1 C2 C3 C4
123 * D0 D1 D2 D3 D4
124 * E0 E1 E2 E3 E4
125 * F0 F1 F2 F3 F4
126 * G0 G1 G2 G3 G4
127 * H0 H1 H2 H3 H4
128 *
129 * If you want to update this screen, you need to send 5 bytes:
130 * (1) A0 B0 C0 D0 E0 F0 G0 H0
131 * (2) A1 B1 C1 D1 E1 F1 G1 H1
132 * (3) A2 B2 C2 D2 E2 F2 G2 H2
133 * (4) A3 B3 C3 D3 E3 F3 G3 H3
134 * (5) A4 B4 C4 D4 E4 F4 G4 H4
135 */
136
137 for (i = 0; i < (SSD1307FB_HEIGHT / 8); i++) {
138 ssd1307fb_write_cmd(par->client, SSD1307FB_START_PAGE_ADDRESS + (i + 1));
139 ssd1307fb_write_cmd(par->client, 0x00);
140 ssd1307fb_write_cmd(par->client, 0x10);
141
142 for (j = 0; j < SSD1307FB_WIDTH; j++) {
143 u8 buf = 0;
144 for (k = 0; k < 8; k++) {
145 u32 page_length = SSD1307FB_WIDTH * i;
146 u32 index = page_length + (SSD1307FB_WIDTH * k + j) / 8;
147 u8 byte = *(vmem + index);
148 u8 bit = byte & (1 << (7 - (j % 8)));
149 bit = bit >> (7 - (j % 8));
150 buf |= bit << k;
151 }
152 ssd1307fb_write_data(par->client, buf);
153 }
154 }
155}
156
157
158static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf,
159 size_t count, loff_t *ppos)
160{
161 struct ssd1307fb_par *par = info->par;
162 unsigned long total_size;
163 unsigned long p = *ppos;
164 u8 __iomem *dst;
165
166 total_size = info->fix.smem_len;
167
168 if (p > total_size)
169 return -EINVAL;
170
171 if (count + p > total_size)
172 count = total_size - p;
173
174 if (!count)
175 return -EINVAL;
176
177 dst = (void __force *) (info->screen_base + p);
178
179 if (copy_from_user(dst, buf, count))
180 return -EFAULT;
181
182 ssd1307fb_update_display(par);
183
184 *ppos += count;
185
186 return count;
187}
188
189static void ssd1307fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
190{
191 struct ssd1307fb_par *par = info->par;
192 sys_fillrect(info, rect);
193 ssd1307fb_update_display(par);
194}
195
196static void ssd1307fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
197{
198 struct ssd1307fb_par *par = info->par;
199 sys_copyarea(info, area);
200 ssd1307fb_update_display(par);
201}
202
203static void ssd1307fb_imageblit(struct fb_info *info, const struct fb_image *image)
204{
205 struct ssd1307fb_par *par = info->par;
206 sys_imageblit(info, image);
207 ssd1307fb_update_display(par);
208}
209
210static struct fb_ops ssd1307fb_ops = {
211 .owner = THIS_MODULE,
212 .fb_read = fb_sys_read,
213 .fb_write = ssd1307fb_write,
214 .fb_fillrect = ssd1307fb_fillrect,
215 .fb_copyarea = ssd1307fb_copyarea,
216 .fb_imageblit = ssd1307fb_imageblit,
217};
218
219static void ssd1307fb_deferred_io(struct fb_info *info,
220 struct list_head *pagelist)
221{
222 ssd1307fb_update_display(info->par);
223}
224
225static struct fb_deferred_io ssd1307fb_defio = {
226 .delay = HZ,
227 .deferred_io = ssd1307fb_deferred_io,
228};
229
230static int __devinit ssd1307fb_probe(struct i2c_client *client, const struct i2c_device_id *id)
231{
232 struct fb_info *info;
233 u32 vmem_size = SSD1307FB_WIDTH * SSD1307FB_HEIGHT / 8;
234 struct ssd1307fb_par *par;
235 u8 *vmem;
236 int ret;
237
238 if (!client->dev.of_node) {
239 dev_err(&client->dev, "No device tree data found!\n");
240 return -EINVAL;
241 }
242
243 info = framebuffer_alloc(sizeof(struct ssd1307fb_par), &client->dev);
244 if (!info) {
245 dev_err(&client->dev, "Couldn't allocate framebuffer.\n");
246 return -ENOMEM;
247 }
248
249 vmem = devm_kzalloc(&client->dev, vmem_size, GFP_KERNEL);
250 if (!vmem) {
251 dev_err(&client->dev, "Couldn't allocate graphical memory.\n");
252 ret = -ENOMEM;
253 goto fb_alloc_error;
254 }
255
256 info->fbops = &ssd1307fb_ops;
257 info->fix = ssd1307fb_fix;
258 info->fbdefio = &ssd1307fb_defio;
259
260 info->var = ssd1307fb_var;
261 info->var.red.length = 1;
262 info->var.red.offset = 0;
263 info->var.green.length = 1;
264 info->var.green.offset = 0;
265 info->var.blue.length = 1;
266 info->var.blue.offset = 0;
267
268 info->screen_base = (u8 __force __iomem *)vmem;
269 info->fix.smem_start = (unsigned long)vmem;
270 info->fix.smem_len = vmem_size;
271
272 fb_deferred_io_init(info);
273
274 par = info->par;
275 par->info = info;
276 par->client = client;
277
278 par->reset = of_get_named_gpio(client->dev.of_node,
279 "reset-gpios", 0);
280 if (!gpio_is_valid(par->reset)) {
281 ret = -EINVAL;
282 goto reset_oled_error;
283 }
284
285 ret = devm_gpio_request_one(&client->dev, par->reset,
286 GPIOF_OUT_INIT_HIGH,
287 "oled-reset");
288 if (ret) {
289 dev_err(&client->dev,
290 "failed to request gpio %d: %d\n",
291 par->reset, ret);
292 goto reset_oled_error;
293 }
294
295 par->pwm = pwm_get(&client->dev, NULL);
296 if (IS_ERR(par->pwm)) {
297 dev_err(&client->dev, "Could not get PWM from device tree!\n");
298 ret = PTR_ERR(par->pwm);
299 goto pwm_error;
300 }
301
302 par->pwm_period = pwm_get_period(par->pwm);
303
304 dev_dbg(&client->dev, "Using PWM%d with a %dns period.\n", par->pwm->pwm, par->pwm_period);
305
306 ret = register_framebuffer(info);
307 if (ret) {
308 dev_err(&client->dev, "Couldn't register the framebuffer\n");
309 goto fbreg_error;
310 }
311
312 i2c_set_clientdata(client, info);
313
314 /* Reset the screen */
315 gpio_set_value(par->reset, 0);
316 udelay(4);
317 gpio_set_value(par->reset, 1);
318 udelay(4);
319
320 /* Enable the PWM */
321 pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
322 pwm_enable(par->pwm);
323
324 /* Map column 127 of the OLED to segment 0 */
325 ret = ssd1307fb_write_cmd(client, SSD1307FB_SEG_REMAP_ON);
326 if (ret < 0) {
327 dev_err(&client->dev, "Couldn't remap the screen.\n");
328 goto remap_error;
329 }
330
331 /* Turn on the display */
332 ret = ssd1307fb_write_cmd(client, SSD1307FB_DISPLAY_ON);
333 if (ret < 0) {
334 dev_err(&client->dev, "Couldn't turn the display on.\n");
335 goto remap_error;
336 }
337
338 dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size);
339
340 return 0;
341
342remap_error:
343 unregister_framebuffer(info);
344 pwm_disable(par->pwm);
345fbreg_error:
346 pwm_put(par->pwm);
347pwm_error:
348reset_oled_error:
349 fb_deferred_io_cleanup(info);
350fb_alloc_error:
351 framebuffer_release(info);
352 return ret;
353}
354
355static int __devexit ssd1307fb_remove(struct i2c_client *client)
356{
357 struct fb_info *info = i2c_get_clientdata(client);
358 struct ssd1307fb_par *par = info->par;
359
360 unregister_framebuffer(info);
361 pwm_disable(par->pwm);
362 pwm_put(par->pwm);
363 fb_deferred_io_cleanup(info);
364 framebuffer_release(info);
365
366 return 0;
367}
368
369static const struct i2c_device_id ssd1307fb_i2c_id[] = {
370 { "ssd1307fb", 0 },
371 { }
372};
373MODULE_DEVICE_TABLE(i2c, ssd1307fb_i2c_id);
374
375static const struct of_device_id ssd1307fb_of_match[] = {
376 { .compatible = "solomon,ssd1307fb-i2c" },
377 {},
378};
379MODULE_DEVICE_TABLE(of, ssd1307fb_of_match);
380
381static struct i2c_driver ssd1307fb_driver = {
382 .probe = ssd1307fb_probe,
383 .remove = __devexit_p(ssd1307fb_remove),
384 .id_table = ssd1307fb_i2c_id,
385 .driver = {
386 .name = "ssd1307fb",
387 .of_match_table = of_match_ptr(ssd1307fb_of_match),
388 .owner = THIS_MODULE,
389 },
390};
391
392module_i2c_driver(ssd1307fb_driver);
393
394MODULE_DESCRIPTION("FB driver for the Solomon SSD1307 OLED controler");
395MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
396MODULE_LICENSE("GPL");
diff --git a/include/linux/fsl-diu-fb.h b/include/linux/fsl-diu-fb.h
index 11c16a1fb9e3..a1e8277120c7 100644
--- a/include/linux/fsl-diu-fb.h
+++ b/include/linux/fsl-diu-fb.h
@@ -47,6 +47,15 @@ struct aoi_display_offset {
47#define MFB_GET_PIXFMT _IOR('M', 8, __u32) 47#define MFB_GET_PIXFMT _IOR('M', 8, __u32)
48 48
49/* 49/*
50 * The MPC5121 BSP comes with a gamma_set utility that initializes the
51 * gamma table. Unfortunately, it uses bad values for the IOCTL commands,
52 * but there's nothing we can do about it now. These ioctls are only
53 * supported on the MPC5121.
54 */
55#define MFB_SET_GAMMA _IOW('M', 1, __u8)
56#define MFB_GET_GAMMA _IOR('M', 1, __u8)
57
58/*
50 * The original definitions of MFB_SET_PIXFMT and MFB_GET_PIXFMT used the 59 * The original definitions of MFB_SET_PIXFMT and MFB_GET_PIXFMT used the
51 * wrong value for 'size' field of the ioctl. The current macros above use the 60 * wrong value for 'size' field of the ioctl. The current macros above use the
52 * right size, but we still need to provide backwards compatibility, at least 61 * right size, but we still need to provide backwards compatibility, at least
diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h
index 5a0e4f9efb53..f88825928dd1 100644
--- a/include/video/da8xx-fb.h
+++ b/include/video/da8xx-fb.h
@@ -12,10 +12,6 @@
12#ifndef DA8XX_FB_H 12#ifndef DA8XX_FB_H
13#define DA8XX_FB_H 13#define DA8XX_FB_H
14 14
15enum panel_type {
16 QVGA = 0
17};
18
19enum panel_shade { 15enum panel_shade {
20 MONOCHROME = 0, 16 MONOCHROME = 0,
21 COLOR_ACTIVE, 17 COLOR_ACTIVE,
@@ -27,13 +23,6 @@ enum raster_load_mode {
27 LOAD_PALETTE, 23 LOAD_PALETTE,
28}; 24};
29 25
30struct display_panel {
31 enum panel_type panel_type; /* QVGA */
32 int max_bpp;
33 int min_bpp;
34 enum panel_shade panel_shade;
35};
36
37struct da8xx_lcdc_platform_data { 26struct da8xx_lcdc_platform_data {
38 const char manu_name[10]; 27 const char manu_name[10];
39 void *controller_data; 28 void *controller_data;
@@ -42,7 +31,7 @@ struct da8xx_lcdc_platform_data {
42}; 31};
43 32
44struct lcd_ctrl_config { 33struct lcd_ctrl_config {
45 const struct display_panel *p_disp_panel; 34 enum panel_shade panel_shade;
46 35
47 /* AC Bias Pin Frequency */ 36 /* AC Bias Pin Frequency */
48 int ac_bias; 37 int ac_bias;
@@ -68,18 +57,9 @@ struct lcd_ctrl_config {
68 /* Mono 8-bit Mode: 1=D0-D7 or 0=D0-D3 */ 57 /* Mono 8-bit Mode: 1=D0-D7 or 0=D0-D3 */
69 unsigned char mono_8bit_mode; 58 unsigned char mono_8bit_mode;
70 59
71 /* Invert line clock */
72 unsigned char invert_line_clock;
73
74 /* Invert frame clock */
75 unsigned char invert_frm_clock;
76
77 /* Horizontal and Vertical Sync Edge: 0=rising 1=falling */ 60 /* Horizontal and Vertical Sync Edge: 0=rising 1=falling */
78 unsigned char sync_edge; 61 unsigned char sync_edge;
79 62
80 /* Horizontal and Vertical Sync: Control: 0=ignore */
81 unsigned char sync_ctrl;
82
83 /* Raster Data Order Select: 1=Most-to-least 0=Least-to-most */ 63 /* Raster Data Order Select: 1=Most-to-least 0=Least-to-most */
84 unsigned char raster_order; 64 unsigned char raster_order;
85 65
@@ -103,5 +83,8 @@ struct lcd_sync_arg {
103#define FBIPUT_HSYNC _IOW('F', 9, int) 83#define FBIPUT_HSYNC _IOW('F', 9, int)
104#define FBIPUT_VSYNC _IOW('F', 10, int) 84#define FBIPUT_VSYNC _IOW('F', 10, int)
105 85
86/* Proprietary FB_SYNC_ flags */
87#define FB_SYNC_CLK_INVERT 0x40000000
88
106#endif /* ifndef DA8XX_FB_H */ 89#endif /* ifndef DA8XX_FB_H */
107 90
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 88c829466fc1..caefa093337d 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -21,6 +21,7 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/kobject.h> 22#include <linux/kobject.h>
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/interrupt.h>
24 25
25#define DISPC_IRQ_FRAMEDONE (1 << 0) 26#define DISPC_IRQ_FRAMEDONE (1 << 0)
26#define DISPC_IRQ_VSYNC (1 << 1) 27#define DISPC_IRQ_VSYNC (1 << 1)
@@ -55,6 +56,7 @@
55 56
56struct omap_dss_device; 57struct omap_dss_device;
57struct omap_overlay_manager; 58struct omap_overlay_manager;
59struct dss_lcd_mgr_config;
58struct snd_aes_iec958; 60struct snd_aes_iec958;
59struct snd_cea_861_aud_if; 61struct snd_cea_861_aud_if;
60 62
@@ -158,7 +160,6 @@ enum omap_display_caps {
158enum omap_dss_display_state { 160enum omap_dss_display_state {
159 OMAP_DSS_DISPLAY_DISABLED = 0, 161 OMAP_DSS_DISPLAY_DISABLED = 0,
160 OMAP_DSS_DISPLAY_ACTIVE, 162 OMAP_DSS_DISPLAY_ACTIVE,
161 OMAP_DSS_DISPLAY_SUSPENDED,
162}; 163};
163 164
164enum omap_dss_audio_state { 165enum omap_dss_audio_state {
@@ -621,10 +622,6 @@ struct omap_dss_device {
621 struct { 622 struct {
622 struct omap_video_timings timings; 623 struct omap_video_timings timings;
623 624
624 int acbi; /* ac-bias pin transitions per interrupt */
625 /* Unit: line clocks */
626 int acb; /* ac-bias pin frequency */
627
628 enum omap_dss_dsi_pixel_format dsi_pix_fmt; 625 enum omap_dss_dsi_pixel_format dsi_pix_fmt;
629 enum omap_dss_dsi_mode dsi_mode; 626 enum omap_dss_dsi_mode dsi_mode;
630 struct omap_dss_dsi_videomode_timings dsi_vm_timings; 627 struct omap_dss_dsi_videomode_timings dsi_vm_timings;
@@ -686,8 +683,6 @@ struct omap_dss_driver {
686 683
687 int (*enable)(struct omap_dss_device *display); 684 int (*enable)(struct omap_dss_device *display);
688 void (*disable)(struct omap_dss_device *display); 685 void (*disable)(struct omap_dss_device *display);
689 int (*suspend)(struct omap_dss_device *display);
690 int (*resume)(struct omap_dss_device *display);
691 int (*run_test)(struct omap_dss_device *display, int test); 686 int (*run_test)(struct omap_dss_device *display, int test);
692 687
693 int (*update)(struct omap_dss_device *dssdev, 688 int (*update)(struct omap_dss_device *dssdev,
@@ -745,6 +740,8 @@ struct omap_dss_driver {
745 740
746}; 741};
747 742
743enum omapdss_version omapdss_get_version(void);
744
748int omap_dss_register_driver(struct omap_dss_driver *); 745int omap_dss_register_driver(struct omap_dss_driver *);
749void omap_dss_unregister_driver(struct omap_dss_driver *); 746void omap_dss_unregister_driver(struct omap_dss_driver *);
750 747
@@ -754,10 +751,19 @@ void omap_dss_put_device(struct omap_dss_device *dssdev);
754struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from); 751struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
755struct omap_dss_device *omap_dss_find_device(void *data, 752struct omap_dss_device *omap_dss_find_device(void *data,
756 int (*match)(struct omap_dss_device *dssdev, void *data)); 753 int (*match)(struct omap_dss_device *dssdev, void *data));
754const char *omapdss_get_default_display_name(void);
757 755
758int omap_dss_start_device(struct omap_dss_device *dssdev); 756int omap_dss_start_device(struct omap_dss_device *dssdev);
759void omap_dss_stop_device(struct omap_dss_device *dssdev); 757void omap_dss_stop_device(struct omap_dss_device *dssdev);
760 758
759int dss_feat_get_num_mgrs(void);
760int dss_feat_get_num_ovls(void);
761enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
762enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
763enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
764
765
766
761int omap_dss_get_num_overlay_managers(void); 767int omap_dss_get_num_overlay_managers(void);
762struct omap_overlay_manager *omap_dss_get_overlay_manager(int num); 768struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
763 769
@@ -779,9 +785,43 @@ typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
779int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask); 785int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
780int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask); 786int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
781 787
782int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout); 788u32 dispc_read_irqstatus(void);
783int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask, 789void dispc_clear_irqstatus(u32 mask);
784 unsigned long timeout); 790u32 dispc_read_irqenable(void);
791void dispc_write_irqenable(u32 mask);
792
793int dispc_request_irq(irq_handler_t handler, void *dev_id);
794void dispc_free_irq(void *dev_id);
795
796int dispc_runtime_get(void);
797void dispc_runtime_put(void);
798
799void dispc_mgr_enable(enum omap_channel channel, bool enable);
800bool dispc_mgr_is_enabled(enum omap_channel channel);
801u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
802u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
803u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel);
804bool dispc_mgr_go_busy(enum omap_channel channel);
805void dispc_mgr_go(enum omap_channel channel);
806void dispc_mgr_set_lcd_config(enum omap_channel channel,
807 const struct dss_lcd_mgr_config *config);
808void dispc_mgr_set_timings(enum omap_channel channel,
809 const struct omap_video_timings *timings);
810void dispc_mgr_setup(enum omap_channel channel,
811 const struct omap_overlay_manager_info *info);
812
813int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel,
814 const struct omap_overlay_info *oi,
815 const struct omap_video_timings *timings,
816 int *x_predecim, int *y_predecim);
817
818int dispc_ovl_enable(enum omap_plane plane, bool enable);
819bool dispc_ovl_enabled(enum omap_plane plane);
820void dispc_ovl_set_channel_out(enum omap_plane plane,
821 enum omap_channel channel);
822int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
823 bool replication, const struct omap_video_timings *mgr_timings,
824 bool mem_to_mem);
785 825
786#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver) 826#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
787#define to_dss_device(x) container_of((x), struct omap_dss_device, dev) 827#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
@@ -840,4 +880,35 @@ void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev,
840void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev, 880void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
841 struct rfbi_timings *timings); 881 struct rfbi_timings *timings);
842 882
883int omapdss_compat_init(void);
884void omapdss_compat_uninit(void);
885
886struct dss_mgr_ops {
887 void (*start_update)(struct omap_overlay_manager *mgr);
888 int (*enable)(struct omap_overlay_manager *mgr);
889 void (*disable)(struct omap_overlay_manager *mgr);
890 void (*set_timings)(struct omap_overlay_manager *mgr,
891 const struct omap_video_timings *timings);
892 void (*set_lcd_config)(struct omap_overlay_manager *mgr,
893 const struct dss_lcd_mgr_config *config);
894 int (*register_framedone_handler)(struct omap_overlay_manager *mgr,
895 void (*handler)(void *), void *data);
896 void (*unregister_framedone_handler)(struct omap_overlay_manager *mgr,
897 void (*handler)(void *), void *data);
898};
899
900int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops);
901void dss_uninstall_mgr_ops(void);
902
903void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
904 const struct omap_video_timings *timings);
905void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
906 const struct dss_lcd_mgr_config *config);
907int dss_mgr_enable(struct omap_overlay_manager *mgr);
908void dss_mgr_disable(struct omap_overlay_manager *mgr);
909void dss_mgr_start_update(struct omap_overlay_manager *mgr);
910int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
911 void (*handler)(void *), void *data);
912void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
913 void (*handler)(void *), void *data);
843#endif 914#endif
diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h
index 7ae6c07f2ef8..e7554486a2b7 100644
--- a/include/video/samsung_fimd.h
+++ b/include/video/samsung_fimd.h
@@ -24,12 +24,15 @@
24 24
25#define VIDCON0 (0x00) 25#define VIDCON0 (0x00)
26#define VIDCON0_INTERLACE (1 << 29) 26#define VIDCON0_INTERLACE (1 << 29)
27#define VIDCON0_VIDOUT_MASK (0x3 << 26) 27#define VIDCON0_VIDOUT_MASK (0x7 << 26)
28#define VIDCON0_VIDOUT_SHIFT (26) 28#define VIDCON0_VIDOUT_SHIFT (26)
29#define VIDCON0_VIDOUT_RGB (0x0 << 26) 29#define VIDCON0_VIDOUT_RGB (0x0 << 26)
30#define VIDCON0_VIDOUT_TV (0x1 << 26) 30#define VIDCON0_VIDOUT_TV (0x1 << 26)
31#define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26) 31#define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26)
32#define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26) 32#define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26)
33#define VIDCON0_VIDOUT_WB_RGB (0x4 << 26)
34#define VIDCON0_VIDOUT_WB_I80_LDI0 (0x6 << 26)
35#define VIDCON0_VIDOUT_WB_I80_LDI1 (0x7 << 26)
33 36
34#define VIDCON0_L1_DATA_MASK (0x7 << 23) 37#define VIDCON0_L1_DATA_MASK (0x7 << 23)
35#define VIDCON0_L1_DATA_SHIFT (23) 38#define VIDCON0_L1_DATA_SHIFT (23)
@@ -77,6 +80,7 @@
77#define VIDCON1_LINECNT_MASK (0x7ff << 16) 80#define VIDCON1_LINECNT_MASK (0x7ff << 16)
78#define VIDCON1_LINECNT_SHIFT (16) 81#define VIDCON1_LINECNT_SHIFT (16)
79#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff) 82#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff)
83#define VIDCON1_FSTATUS_EVEN (1 << 15)
80#define VIDCON1_VSTATUS_MASK (0x3 << 13) 84#define VIDCON1_VSTATUS_MASK (0x3 << 13)
81#define VIDCON1_VSTATUS_SHIFT (13) 85#define VIDCON1_VSTATUS_SHIFT (13)
82#define VIDCON1_VSTATUS_VSYNC (0x0 << 13) 86#define VIDCON1_VSTATUS_VSYNC (0x0 << 13)
@@ -116,6 +120,7 @@
116 120
117/* VIDTCON0 */ 121/* VIDTCON0 */
118 122
123#define VIDTCON0 (0x10)
119#define VIDTCON0_VBPDE_MASK (0xff << 24) 124#define VIDTCON0_VBPDE_MASK (0xff << 24)
120#define VIDTCON0_VBPDE_SHIFT (24) 125#define VIDTCON0_VBPDE_SHIFT (24)
121#define VIDTCON0_VBPDE_LIMIT (0xff) 126#define VIDTCON0_VBPDE_LIMIT (0xff)
@@ -138,6 +143,7 @@
138 143
139/* VIDTCON1 */ 144/* VIDTCON1 */
140 145
146#define VIDTCON1 (0x14)
141#define VIDTCON1_VFPDE_MASK (0xff << 24) 147#define VIDTCON1_VFPDE_MASK (0xff << 24)
142#define VIDTCON1_VFPDE_SHIFT (24) 148#define VIDTCON1_VFPDE_SHIFT (24)
143#define VIDTCON1_VFPDE_LIMIT (0xff) 149#define VIDTCON1_VFPDE_LIMIT (0xff)
@@ -159,6 +165,7 @@
159#define VIDTCON1_HSPW(_x) ((_x) << 0) 165#define VIDTCON1_HSPW(_x) ((_x) << 0)
160 166
161#define VIDTCON2 (0x18) 167#define VIDTCON2 (0x18)
168#define VIDTCON2 (0x18)
162#define VIDTCON2_LINEVAL_E(_x) ((((_x) & 0x800) >> 11) << 23) 169#define VIDTCON2_LINEVAL_E(_x) ((((_x) & 0x800) >> 11) << 23)
163#define VIDTCON2_LINEVAL_MASK (0x7ff << 11) 170#define VIDTCON2_LINEVAL_MASK (0x7ff << 11)
164#define VIDTCON2_LINEVAL_SHIFT (11) 171#define VIDTCON2_LINEVAL_SHIFT (11)
@@ -173,18 +180,27 @@
173 180
174/* WINCONx */ 181/* WINCONx */
175 182
176 183#define WINCON(_win) (0x20 + ((_win) * 4))
184#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
185#define WINCONx_CSCWIDTH_SHIFT (26)
186#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
187#define WINCONx_CSCWIDTH_NARROW (0x3 << 26)
188#define WINCONx_ENLOCAL (1 << 22)
189#define WINCONx_BUFSTATUS (1 << 21)
190#define WINCONx_BUFSEL (1 << 20)
191#define WINCONx_BUFAUTOEN (1 << 19)
177#define WINCONx_BITSWP (1 << 18) 192#define WINCONx_BITSWP (1 << 18)
178#define WINCONx_BYTSWP (1 << 17) 193#define WINCONx_BYTSWP (1 << 17)
179#define WINCONx_HAWSWP (1 << 16) 194#define WINCONx_HAWSWP (1 << 16)
180#define WINCONx_WSWP (1 << 15) 195#define WINCONx_WSWP (1 << 15)
196#define WINCONx_YCbCr (1 << 13)
181#define WINCONx_BURSTLEN_MASK (0x3 << 9) 197#define WINCONx_BURSTLEN_MASK (0x3 << 9)
182#define WINCONx_BURSTLEN_SHIFT (9) 198#define WINCONx_BURSTLEN_SHIFT (9)
183#define WINCONx_BURSTLEN_16WORD (0x0 << 9) 199#define WINCONx_BURSTLEN_16WORD (0x0 << 9)
184#define WINCONx_BURSTLEN_8WORD (0x1 << 9) 200#define WINCONx_BURSTLEN_8WORD (0x1 << 9)
185#define WINCONx_BURSTLEN_4WORD (0x2 << 9) 201#define WINCONx_BURSTLEN_4WORD (0x2 << 9)
186
187#define WINCONx_ENWIN (1 << 0) 202#define WINCONx_ENWIN (1 << 0)
203
188#define WINCON0_BPPMODE_MASK (0xf << 2) 204#define WINCON0_BPPMODE_MASK (0xf << 2)
189#define WINCON0_BPPMODE_SHIFT (2) 205#define WINCON0_BPPMODE_SHIFT (2)
190#define WINCON0_BPPMODE_1BPP (0x0 << 2) 206#define WINCON0_BPPMODE_1BPP (0x0 << 2)
@@ -196,9 +212,8 @@
196#define WINCON0_BPPMODE_18BPP_666 (0x8 << 2) 212#define WINCON0_BPPMODE_18BPP_666 (0x8 << 2)
197#define WINCON0_BPPMODE_24BPP_888 (0xb << 2) 213#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
198 214
215#define WINCON1_LOCALSEL_CAMIF (1 << 23)
199#define WINCON1_BLD_PIX (1 << 6) 216#define WINCON1_BLD_PIX (1 << 6)
200
201#define WINCON1_ALPHA_SEL (1 << 1)
202#define WINCON1_BPPMODE_MASK (0xf << 2) 217#define WINCON1_BPPMODE_MASK (0xf << 2)
203#define WINCON1_BPPMODE_SHIFT (2) 218#define WINCON1_BPPMODE_SHIFT (2)
204#define WINCON1_BPPMODE_1BPP (0x0 << 2) 219#define WINCON1_BPPMODE_1BPP (0x0 << 2)
@@ -216,6 +231,7 @@
216#define WINCON1_BPPMODE_24BPP_A1887 (0xc << 2) 231#define WINCON1_BPPMODE_24BPP_A1887 (0xc << 2)
217#define WINCON1_BPPMODE_25BPP_A1888 (0xd << 2) 232#define WINCON1_BPPMODE_25BPP_A1888 (0xd << 2)
218#define WINCON1_BPPMODE_28BPP_A4888 (0xd << 2) 233#define WINCON1_BPPMODE_28BPP_A4888 (0xd << 2)
234#define WINCON1_ALPHA_SEL (1 << 1)
219 235
220/* S5PV210 */ 236/* S5PV210 */
221#define SHADOWCON (0x34) 237#define SHADOWCON (0x34)
@@ -225,6 +241,9 @@
225/* Local input channels (windows 0-2) */ 241/* Local input channels (windows 0-2) */
226#define SHADOWCON_CHx_LOCAL_ENABLE(_win) (1 << (5 + (_win))) 242#define SHADOWCON_CHx_LOCAL_ENABLE(_win) (1 << (5 + (_win)))
227 243
244/* VIDOSDx */
245
246#define VIDOSD_BASE (0x40)
228#define VIDOSDxA_TOPLEFT_X_E(_x) ((((_x) & 0x800) >> 11) << 23) 247#define VIDOSDxA_TOPLEFT_X_E(_x) ((((_x) & 0x800) >> 11) << 23)
229#define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11) 248#define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11)
230#define VIDOSDxA_TOPLEFT_X_SHIFT (11) 249#define VIDOSDxA_TOPLEFT_X_SHIFT (11)
@@ -293,6 +312,7 @@
293 312
294/* Interrupt controls and status */ 313/* Interrupt controls and status */
295 314
315#define VIDINTCON0 (0x130)
296#define VIDINTCON0_FIFOINTERVAL_MASK (0x3f << 20) 316#define VIDINTCON0_FIFOINTERVAL_MASK (0x3f << 20)
297#define VIDINTCON0_FIFOINTERVAL_SHIFT (20) 317#define VIDINTCON0_FIFOINTERVAL_SHIFT (20)
298#define VIDINTCON0_FIFOINTERVAL_LIMIT (0x3f) 318#define VIDINTCON0_FIFOINTERVAL_LIMIT (0x3f)
@@ -321,6 +341,9 @@
321#define VIDINTCON0_FIFIOSEL_SHIFT (5) 341#define VIDINTCON0_FIFIOSEL_SHIFT (5)
322#define VIDINTCON0_FIFIOSEL_WINDOW0 (0x1 << 5) 342#define VIDINTCON0_FIFIOSEL_WINDOW0 (0x1 << 5)
323#define VIDINTCON0_FIFIOSEL_WINDOW1 (0x2 << 5) 343#define VIDINTCON0_FIFIOSEL_WINDOW1 (0x2 << 5)
344#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5)
345#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5)
346#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5)
324 347
325#define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 2) 348#define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 2)
326#define VIDINTCON0_FIFOLEVEL_SHIFT (2) 349#define VIDINTCON0_FIFOLEVEL_SHIFT (2)
@@ -357,16 +380,39 @@
357#define WxKEYCON1_COLVAL_LIMIT (0xffffff) 380#define WxKEYCON1_COLVAL_LIMIT (0xffffff)
358#define WxKEYCON1_COLVAL(_x) ((_x) << 0) 381#define WxKEYCON1_COLVAL(_x) ((_x) << 0)
359 382
383/* Dithering control */
384#define DITHMODE (0x170)
385#define DITHMODE_R_POS_MASK (0x3 << 5)
386#define DITHMODE_R_POS_SHIFT (5)
387#define DITHMODE_R_POS_8BIT (0x0 << 5)
388#define DITHMODE_R_POS_6BIT (0x1 << 5)
389#define DITHMODE_R_POS_5BIT (0x2 << 5)
390#define DITHMODE_G_POS_MASK (0x3 << 3)
391#define DITHMODE_G_POS_SHIFT (3)
392#define DITHMODE_G_POS_8BIT (0x0 << 3)
393#define DITHMODE_G_POS_6BIT (0x1 << 3)
394#define DITHMODE_G_POS_5BIT (0x2 << 3)
395#define DITHMODE_B_POS_MASK (0x3 << 1)
396#define DITHMODE_B_POS_SHIFT (1)
397#define DITHMODE_B_POS_8BIT (0x0 << 1)
398#define DITHMODE_B_POS_6BIT (0x1 << 1)
399#define DITHMODE_B_POS_5BIT (0x2 << 1)
400#define DITHMODE_DITH_EN (1 << 0)
360 401
361/* Window blanking (MAP) */ 402/* Window blanking (MAP) */
362 403#define WINxMAP(_win) (0x180 + ((_win) * 4))
363#define WINxMAP_MAP (1 << 24) 404#define WINxMAP_MAP (1 << 24)
364#define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0) 405#define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0)
365#define WINxMAP_MAP_COLOUR_SHIFT (0) 406#define WINxMAP_MAP_COLOUR_SHIFT (0)
366#define WINxMAP_MAP_COLOUR_LIMIT (0xffffff) 407#define WINxMAP_MAP_COLOUR_LIMIT (0xffffff)
367#define WINxMAP_MAP_COLOUR(_x) ((_x) << 0) 408#define WINxMAP_MAP_COLOUR(_x) ((_x) << 0)
368 409
410/* Winodw palette control */
411#define WPALCON (0x1A0)
369#define WPALCON_PAL_UPDATE (1 << 9) 412#define WPALCON_PAL_UPDATE (1 << 9)
413#define WPALCON_W4PAL_16BPP_A555 (1 << 8)
414#define WPALCON_W3PAL_16BPP_A555 (1 << 7)
415#define WPALCON_W2PAL_16BPP_A555 (1 << 6)
370#define WPALCON_W1PAL_MASK (0x7 << 3) 416#define WPALCON_W1PAL_MASK (0x7 << 3)
371#define WPALCON_W1PAL_SHIFT (3) 417#define WPALCON_W1PAL_SHIFT (3)
372#define WPALCON_W1PAL_25BPP_A888 (0x0 << 3) 418#define WPALCON_W1PAL_25BPP_A888 (0x0 << 3)
@@ -376,7 +422,6 @@
376#define WPALCON_W1PAL_18BPP (0x4 << 3) 422#define WPALCON_W1PAL_18BPP (0x4 << 3)
377#define WPALCON_W1PAL_16BPP_A555 (0x5 << 3) 423#define WPALCON_W1PAL_16BPP_A555 (0x5 << 3)
378#define WPALCON_W1PAL_16BPP_565 (0x6 << 3) 424#define WPALCON_W1PAL_16BPP_565 (0x6 << 3)
379
380#define WPALCON_W0PAL_MASK (0x7 << 0) 425#define WPALCON_W0PAL_MASK (0x7 << 0)
381#define WPALCON_W0PAL_SHIFT (0) 426#define WPALCON_W0PAL_SHIFT (0)
382#define WPALCON_W0PAL_25BPP_A888 (0x0 << 0) 427#define WPALCON_W0PAL_25BPP_A888 (0x0 << 0)
@@ -394,115 +439,6 @@
394#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0) 439#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0)
395 440
396#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */ 441#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */
397#define VIDCON1_FSTATUS_EVEN (1 << 15)
398
399/* Video timing controls */
400#define VIDTCON0 (0x10)
401#define VIDTCON1 (0x14)
402#define VIDTCON2 (0x18)
403
404/* Window position controls */
405
406#define WINCON(_win) (0x20 + ((_win) * 4))
407
408/* OSD1 and OSD4 do not have register D */
409
410#define VIDOSD_BASE (0x40)
411
412#define VIDINTCON0 (0x130)
413
414/* WINCONx */
415
416#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
417#define WINCONx_CSCWIDTH_SHIFT (26)
418#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
419#define WINCONx_CSCWIDTH_NARROW (0x3 << 26)
420
421#define WINCONx_ENLOCAL (1 << 22)
422#define WINCONx_BUFSTATUS (1 << 21)
423#define WINCONx_BUFSEL (1 << 20)
424#define WINCONx_BUFAUTOEN (1 << 19)
425#define WINCONx_YCbCr (1 << 13)
426
427#define WINCON1_LOCALSEL_CAMIF (1 << 23)
428
429#define WINCON2_LOCALSEL_CAMIF (1 << 23)
430#define WINCON2_BLD_PIX (1 << 6)
431
432#define WINCON2_ALPHA_SEL (1 << 1)
433#define WINCON2_BPPMODE_MASK (0xf << 2)
434#define WINCON2_BPPMODE_SHIFT (2)
435#define WINCON2_BPPMODE_1BPP (0x0 << 2)
436#define WINCON2_BPPMODE_2BPP (0x1 << 2)
437#define WINCON2_BPPMODE_4BPP (0x2 << 2)
438#define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2)
439#define WINCON2_BPPMODE_16BPP_565 (0x5 << 2)
440#define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2)
441#define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2)
442#define WINCON2_BPPMODE_18BPP_666 (0x8 << 2)
443#define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2)
444#define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2)
445#define WINCON2_BPPMODE_24BPP_888 (0xb << 2)
446#define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2)
447#define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2)
448#define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2)
449
450#define WINCON3_BLD_PIX (1 << 6)
451
452#define WINCON3_ALPHA_SEL (1 << 1)
453#define WINCON3_BPPMODE_MASK (0xf << 2)
454#define WINCON3_BPPMODE_SHIFT (2)
455#define WINCON3_BPPMODE_1BPP (0x0 << 2)
456#define WINCON3_BPPMODE_2BPP (0x1 << 2)
457#define WINCON3_BPPMODE_4BPP (0x2 << 2)
458#define WINCON3_BPPMODE_16BPP_565 (0x5 << 2)
459#define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2)
460#define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2)
461#define WINCON3_BPPMODE_18BPP_666 (0x8 << 2)
462#define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2)
463#define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2)
464#define WINCON3_BPPMODE_24BPP_888 (0xb << 2)
465#define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2)
466#define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2)
467#define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2)
468
469#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5)
470#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5)
471#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5)
472
473#define DITHMODE (0x170)
474#define WINxMAP(_win) (0x180 + ((_win) * 4))
475
476
477#define DITHMODE_R_POS_MASK (0x3 << 5)
478#define DITHMODE_R_POS_SHIFT (5)
479#define DITHMODE_R_POS_8BIT (0x0 << 5)
480#define DITHMODE_R_POS_6BIT (0x1 << 5)
481#define DITHMODE_R_POS_5BIT (0x2 << 5)
482
483#define DITHMODE_G_POS_MASK (0x3 << 3)
484#define DITHMODE_G_POS_SHIFT (3)
485#define DITHMODE_G_POS_8BIT (0x0 << 3)
486#define DITHMODE_G_POS_6BIT (0x1 << 3)
487#define DITHMODE_G_POS_5BIT (0x2 << 3)
488
489#define DITHMODE_B_POS_MASK (0x3 << 1)
490#define DITHMODE_B_POS_SHIFT (1)
491#define DITHMODE_B_POS_8BIT (0x0 << 1)
492#define DITHMODE_B_POS_6BIT (0x1 << 1)
493#define DITHMODE_B_POS_5BIT (0x2 << 1)
494
495#define DITHMODE_DITH_EN (1 << 0)
496
497#define WPALCON (0x1A0)
498
499/* Palette control */
500/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
501 * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
502#define WPALCON_W4PAL_16BPP_A555 (1 << 8)
503#define WPALCON_W3PAL_16BPP_A555 (1 << 7)
504#define WPALCON_W2PAL_16BPP_A555 (1 << 6)
505
506 442
507/* Notes on per-window bpp settings 443/* Notes on per-window bpp settings
508 * 444 *
diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h
index 06c67fbc4eee..a01f197e6ac1 100644
--- a/include/video/sh_mipi_dsi.h
+++ b/include/video/sh_mipi_dsi.h
@@ -25,8 +25,6 @@ enum sh_mipi_dsi_data_fmt {
25 MIPI_YUV420, 25 MIPI_YUV420,
26}; 26};
27 27
28struct sh_mobile_lcdc_chan_cfg;
29
30#define SH_MIPI_DSI_HSABM (1 << 0) 28#define SH_MIPI_DSI_HSABM (1 << 0)
31#define SH_MIPI_DSI_HBPBM (1 << 1) 29#define SH_MIPI_DSI_HBPBM (1 << 1)
32#define SH_MIPI_DSI_HFPBM (1 << 2) 30#define SH_MIPI_DSI_HFPBM (1 << 2)
@@ -47,7 +45,7 @@ struct sh_mobile_lcdc_chan_cfg;
47 45
48struct sh_mipi_dsi_info { 46struct sh_mipi_dsi_info {
49 enum sh_mipi_dsi_data_fmt data_format; 47 enum sh_mipi_dsi_data_fmt data_format;
50 struct sh_mobile_lcdc_chan_cfg *lcd_chan; 48 int channel;
51 int lane; 49 int lane;
52 unsigned long flags; 50 unsigned long flags;
53 u32 clksrc; 51 u32 clksrc;
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index ff43ffc1aab2..2605fa8adb9c 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -163,7 +163,6 @@ struct sh_mobile_lcdc_bl_info {
163 const char *name; 163 const char *name;
164 int max_brightness; 164 int max_brightness;
165 int (*set_brightness)(int brightness); 165 int (*set_brightness)(int brightness);
166 int (*get_brightness)(void);
167}; 166};
168 167
169struct sh_mobile_lcdc_overlay_cfg { 168struct sh_mobile_lcdc_overlay_cfg {