aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-12 14:01:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-12 14:01:37 -0400
commit084165a3f8c8a88c83bdfa3941f897ae0f020211 (patch)
tree150c01ce41dee82eea7056be0c130c58bbe1ba93
parentef6000b4c6706cbb1787836442b5a74542b1809f (diff)
parentc456a2f30de53e77a2eb8eeb4202d742516aa76b (diff)
Merge tag 'fbdev-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux
Pull fbdev updates from Tomi Valkeinen: "Main changes: - amba-cldc: DT backlight support, Nomadik support, Versatile improvements, fixes - efifb: fix fbcon RGB565 palette - exynos: remove unused DSI driver" * tag 'fbdev-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (42 commits) video: smscufx: remove unused variable matroxfb: fix size of memcpy fbdev: ssd1307fb: fix a possible NULL dereference fbdev: ssd1307fb: constify the device_info pointer simplefb: Disable and release clocks and regulators in destroy callback video: fbdev: constify fb_fix_screeninfo and fb_var_screeninfo structures matroxfb: constify local structures video: fbdev: i810: add in missing white space in error message text video: fbdev: add missing \n at end of printk error message ARM: exynos_defconfig: Remove old non-working MIPI driver video: fbdev: exynos: Remove old non-working MIPI driver omapfb: fix return value check in dsi_bind() MAINTAINERS: update fbdev entries video: fbdev: offb: Call pci_enable_device() before using the PCI VGA device fbdev: vfb: simplify memory management fbdev: vfb: add option for video mode fbdev: vfb: add description to module parameters video: fbdev: intelfb: remove impossible condition fb: adv7393: off by one in probe function video: fbdev: pxafb: add missing of_node_put() in of_get_pxafb_mode_info() ...
-rw-r--r--MAINTAINERS12
-rw-r--r--arch/arm/configs/exynos_defconfig2
-rw-r--r--drivers/video/fbdev/Kconfig7
-rw-r--r--drivers/video/fbdev/Makefile3
-rw-r--r--drivers/video/fbdev/amba-clcd-nomadik.c259
-rw-r--r--drivers/video/fbdev/amba-clcd-nomadik.h24
-rw-r--r--drivers/video/fbdev/amba-clcd-versatile.c395
-rw-r--r--drivers/video/fbdev/amba-clcd-versatile.h17
-rw-r--r--drivers/video/fbdev/amba-clcd.c190
-rw-r--r--drivers/video/fbdev/arcfb.c4
-rw-r--r--drivers/video/fbdev/asiliantfb.c4
-rw-r--r--drivers/video/fbdev/aty/aty128fb.c6
-rw-r--r--drivers/video/fbdev/aty/atyfb_base.c2
-rw-r--r--drivers/video/fbdev/aty/radeon_monitor.c2
-rw-r--r--drivers/video/fbdev/bfin_adv7393fb.c5
-rw-r--r--drivers/video/fbdev/efifb.c6
-rw-r--r--drivers/video/fbdev/exynos/Kconfig32
-rw-r--r--drivers/video/fbdev/exynos/Makefile9
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi.c574
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c880
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h46
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c618
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h112
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h149
-rw-r--r--drivers/video/fbdev/exynos/s6e8ax0.c887
-rw-r--r--drivers/video/fbdev/hecubafb.c4
-rw-r--r--drivers/video/fbdev/hgafb.c2
-rw-r--r--drivers/video/fbdev/i740fb.c2
-rw-r--r--drivers/video/fbdev/i810/i810_main.c2
-rw-r--r--drivers/video/fbdev/intelfb/intelfbdrv.c5
-rw-r--r--drivers/video/fbdev/kyro/fbdev.c2
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_Ti3026.c2
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_g450.c2
-rw-r--r--drivers/video/fbdev/mb862xx/mb862xx-i2c.c9
-rw-r--r--drivers/video/fbdev/mx3fb.c2
-rw-r--r--drivers/video/fbdev/mxsfb.c9
-rw-r--r--drivers/video/fbdev/offb.c15
-rw-r--r--drivers/video/fbdev/omap/lcd_mipid.c9
-rw-r--r--drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c14
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c7
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/dsi.c12
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c8
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c8
-rw-r--r--drivers/video/fbdev/pm2fb.c2
-rw-r--r--drivers/video/fbdev/pxafb.c3
-rw-r--r--drivers/video/fbdev/s1d13xxxfb.c4
-rw-r--r--drivers/video/fbdev/s3c2410fb.c2
-rw-r--r--drivers/video/fbdev/s3c2410fb.h2
-rw-r--r--drivers/video/fbdev/savage/savagefb_driver.c2
-rw-r--r--drivers/video/fbdev/simplefb.c13
-rw-r--r--drivers/video/fbdev/sm712fb.c2
-rw-r--r--drivers/video/fbdev/smscufx.c2
-rw-r--r--drivers/video/fbdev/ssd1307fb.c9
-rw-r--r--drivers/video/fbdev/tdfxfb.c4
-rw-r--r--drivers/video/fbdev/uvesafb.c2
-rw-r--r--drivers/video/fbdev/vfb.c129
-rw-r--r--drivers/video/fbdev/vga16fb.c2
-rw-r--r--include/linux/amba/clcd.h63
-rw-r--r--include/video/exynos_mipi_dsim.h358
59 files changed, 1042 insertions, 3916 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 5e925a25e77d..ea4fbc993d91 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4775,15 +4775,6 @@ L: iommu@lists.linux-foundation.org
4775S: Maintained 4775S: Maintained
4776F: drivers/iommu/exynos-iommu.c 4776F: drivers/iommu/exynos-iommu.c
4777 4777
4778EXYNOS MIPI DISPLAY DRIVERS
4779M: Inki Dae <inki.dae@samsung.com>
4780M: Donghwa Lee <dh09.lee@samsung.com>
4781M: Kyungmin Park <kyungmin.park@samsung.com>
4782L: linux-fbdev@vger.kernel.org
4783S: Maintained
4784F: drivers/video/fbdev/exynos/exynos_mipi*
4785F: include/video/exynos_mipi*
4786
4787EZchip NPS platform support 4778EZchip NPS platform support
4788M: Noam Camus <noamc@ezchip.com> 4779M: Noam Camus <noamc@ezchip.com>
4789S: Supported 4780S: Supported
@@ -4962,12 +4953,9 @@ F: drivers/net/wan/dlci.c
4962F: drivers/net/wan/sdla.c 4953F: drivers/net/wan/sdla.c
4963 4954
4964FRAMEBUFFER LAYER 4955FRAMEBUFFER LAYER
4965M: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
4966M: Tomi Valkeinen <tomi.valkeinen@ti.com> 4956M: Tomi Valkeinen <tomi.valkeinen@ti.com>
4967L: linux-fbdev@vger.kernel.org 4957L: linux-fbdev@vger.kernel.org
4968W: http://linux-fbdev.sourceforge.net/
4969Q: http://patchwork.kernel.org/project/linux-fbdev/list/ 4958Q: http://patchwork.kernel.org/project/linux-fbdev/list/
4970T: git git://git.kernel.org/pub/scm/linux/kernel/git/plagnioj/linux-fbdev.git
4971S: Maintained 4959S: Maintained
4972F: Documentation/fb/ 4960F: Documentation/fb/
4973F: drivers/video/ 4961F: drivers/video/
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 4e484f406419..c58f6841f8aa 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -168,8 +168,6 @@ CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
168CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y 168CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
169CONFIG_DRM_NXP_PTN3460=y 169CONFIG_DRM_NXP_PTN3460=y
170CONFIG_DRM_PARADE_PS8622=y 170CONFIG_DRM_PARADE_PS8622=y
171CONFIG_EXYNOS_VIDEO=y
172CONFIG_EXYNOS_MIPI_DSI=y
173CONFIG_LCD_CLASS_DEVICE=y 171CONFIG_LCD_CLASS_DEVICE=y
174CONFIG_LCD_PLATFORM=y 172CONFIG_LCD_PLATFORM=y
175CONFIG_BACKLIGHT_PWM=y 173CONFIG_BACKLIGHT_PWM=y
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 88b008fb8a4e..af2f117208f1 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -284,12 +284,14 @@ config FB_PM2_FIFO_DISCONNECT
284config FB_ARMCLCD 284config FB_ARMCLCD
285 tristate "ARM PrimeCell PL110 support" 285 tristate "ARM PrimeCell PL110 support"
286 depends on ARM || ARM64 || COMPILE_TEST 286 depends on ARM || ARM64 || COMPILE_TEST
287 depends on FB && ARM_AMBA 287 depends on FB && ARM_AMBA && HAS_IOMEM
288 select FB_CFB_FILLRECT 288 select FB_CFB_FILLRECT
289 select FB_CFB_COPYAREA 289 select FB_CFB_COPYAREA
290 select FB_CFB_IMAGEBLIT 290 select FB_CFB_IMAGEBLIT
291 select FB_MODE_HELPERS if OF 291 select FB_MODE_HELPERS if OF
292 select VIDEOMODE_HELPERS if OF 292 select VIDEOMODE_HELPERS if OF
293 select BACKLIGHT_LCD_SUPPORT if OF
294 select BACKLIGHT_CLASS_DEVICE if OF
293 help 295 help
294 This framebuffer device driver is for the ARM PrimeCell PL110 296 This framebuffer device driver is for the ARM PrimeCell PL110
295 Colour LCD controller. ARM PrimeCells provide the building 297 Colour LCD controller. ARM PrimeCells provide the building
@@ -305,6 +307,8 @@ config PLAT_VERSATILE_CLCD
305 def_bool ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_INTEGRATOR 307 def_bool ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_INTEGRATOR
306 depends on ARM 308 depends on ARM
307 depends on FB_ARMCLCD && FB=y 309 depends on FB_ARMCLCD && FB=y
310 select REGMAP
311 select MFD_SYSCON
308 312
309config FB_ACORN 313config FB_ACORN
310 bool "Acorn VIDC support" 314 bool "Acorn VIDC support"
@@ -2443,7 +2447,6 @@ config FB_SIMPLE
2443 2447
2444source "drivers/video/fbdev/omap/Kconfig" 2448source "drivers/video/fbdev/omap/Kconfig"
2445source "drivers/video/fbdev/omap2/Kconfig" 2449source "drivers/video/fbdev/omap2/Kconfig"
2446source "drivers/video/fbdev/exynos/Kconfig"
2447source "drivers/video/fbdev/mmp/Kconfig" 2450source "drivers/video/fbdev/mmp/Kconfig"
2448 2451
2449config FB_SH_MOBILE_MERAM 2452config FB_SH_MOBILE_MERAM
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index f6731867dd26..ee8c81405a7f 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -6,8 +6,6 @@
6 6
7obj-y += core/ 7obj-y += core/
8 8
9obj-$(CONFIG_EXYNOS_VIDEO) += exynos/
10
11obj-$(CONFIG_FB_MACMODES) += macmodes.o 9obj-$(CONFIG_FB_MACMODES) += macmodes.o
12obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o 10obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
13 11
@@ -79,6 +77,7 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
79obj-$(CONFIG_FB_PVR2) += pvr2fb.o 77obj-$(CONFIG_FB_PVR2) += pvr2fb.o
80obj-$(CONFIG_FB_VOODOO1) += sstfb.o 78obj-$(CONFIG_FB_VOODOO1) += sstfb.o
81obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o 79obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
80obj-$(CONFIG_ARCH_NOMADIK) += amba-clcd-nomadik.o
82obj-$(CONFIG_PLAT_VERSATILE_CLCD) += amba-clcd-versatile.o 81obj-$(CONFIG_PLAT_VERSATILE_CLCD) += amba-clcd-versatile.o
83obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o 82obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
84obj-$(CONFIG_FB_68328) += 68328fb.o 83obj-$(CONFIG_FB_68328) += 68328fb.o
diff --git a/drivers/video/fbdev/amba-clcd-nomadik.c b/drivers/video/fbdev/amba-clcd-nomadik.c
new file mode 100644
index 000000000000..0c06fcaaa6e8
--- /dev/null
+++ b/drivers/video/fbdev/amba-clcd-nomadik.c
@@ -0,0 +1,259 @@
1#include <linux/amba/bus.h>
2#include <linux/amba/clcd.h>
3#include <linux/gpio/consumer.h>
4#include <linux/of.h>
5#include <linux/of_graph.h>
6#include <linux/delay.h>
7#include <linux/bitops.h>
8#include <linux/mfd/syscon.h>
9#include <linux/regmap.h>
10
11#include "amba-clcd-nomadik.h"
12
13static struct gpio_desc *grestb;
14static struct gpio_desc *scen;
15static struct gpio_desc *scl;
16static struct gpio_desc *sda;
17
18static u8 tpg110_readwrite_reg(bool write, u8 address, u8 outval)
19{
20 int i;
21 u8 inval = 0;
22
23 /* Assert SCEN */
24 gpiod_set_value_cansleep(scen, 1);
25 ndelay(150);
26 /* Hammer out the address */
27 for (i = 5; i >= 0; i--) {
28 if (address & BIT(i))
29 gpiod_set_value_cansleep(sda, 1);
30 else
31 gpiod_set_value_cansleep(sda, 0);
32 ndelay(150);
33 /* Send an SCL pulse */
34 gpiod_set_value_cansleep(scl, 1);
35 ndelay(160);
36 gpiod_set_value_cansleep(scl, 0);
37 ndelay(160);
38 }
39
40 if (write) {
41 /* WRITE */
42 gpiod_set_value_cansleep(sda, 0);
43 } else {
44 /* READ */
45 gpiod_set_value_cansleep(sda, 1);
46 }
47 ndelay(150);
48 /* Send an SCL pulse */
49 gpiod_set_value_cansleep(scl, 1);
50 ndelay(160);
51 gpiod_set_value_cansleep(scl, 0);
52 ndelay(160);
53
54 if (!write)
55 /* HiZ turn-around cycle */
56 gpiod_direction_input(sda);
57 ndelay(150);
58 /* Send an SCL pulse */
59 gpiod_set_value_cansleep(scl, 1);
60 ndelay(160);
61 gpiod_set_value_cansleep(scl, 0);
62 ndelay(160);
63
64 /* Hammer in/out the data */
65 for (i = 7; i >= 0; i--) {
66 int value;
67
68 if (write) {
69 value = !!(outval & BIT(i));
70 gpiod_set_value_cansleep(sda, value);
71 } else {
72 value = gpiod_get_value(sda);
73 if (value)
74 inval |= BIT(i);
75 }
76 ndelay(150);
77 /* Send an SCL pulse */
78 gpiod_set_value_cansleep(scl, 1);
79 ndelay(160);
80 gpiod_set_value_cansleep(scl, 0);
81 ndelay(160);
82 }
83
84 gpiod_direction_output(sda, 0);
85 /* Deassert SCEN */
86 gpiod_set_value_cansleep(scen, 0);
87 /* Satisfies SCEN pulse width */
88 udelay(1);
89
90 return inval;
91}
92
93static u8 tpg110_read_reg(u8 address)
94{
95 return tpg110_readwrite_reg(false, address, 0);
96}
97
98static void tpg110_write_reg(u8 address, u8 outval)
99{
100 tpg110_readwrite_reg(true, address, outval);
101}
102
103static void tpg110_startup(struct device *dev)
104{
105 u8 val;
106
107 dev_info(dev, "TPG110 display enable\n");
108 /* De-assert the reset signal */
109 gpiod_set_value_cansleep(grestb, 0);
110 mdelay(1);
111 dev_info(dev, "de-asserted GRESTB\n");
112
113 /* Test display communication */
114 tpg110_write_reg(0x00, 0x55);
115 val = tpg110_read_reg(0x00);
116 if (val == 0x55)
117 dev_info(dev, "passed communication test\n");
118 val = tpg110_read_reg(0x01);
119 dev_info(dev, "TPG110 chip ID: %d version: %d\n",
120 val>>4, val&0x0f);
121
122 /* Show display resolution */
123 val = tpg110_read_reg(0x02);
124 val &= 7;
125 switch (val) {
126 case 0x0:
127 dev_info(dev, "IN 400x240 RGB -> OUT 800x480 RGB (dual scan)");
128 break;
129 case 0x1:
130 dev_info(dev, "IN 480x272 RGB -> OUT 800x480 RGB (dual scan)");
131 break;
132 case 0x4:
133 dev_info(dev, "480x640 RGB");
134 break;
135 case 0x5:
136 dev_info(dev, "480x272 RGB");
137 break;
138 case 0x6:
139 dev_info(dev, "640x480 RGB");
140 break;
141 case 0x7:
142 dev_info(dev, "800x480 RGB");
143 break;
144 default:
145 dev_info(dev, "ILLEGAL RESOLUTION");
146 break;
147 }
148
149 val = tpg110_read_reg(0x03);
150 dev_info(dev, "resolution is controlled by %s\n",
151 (val & BIT(7)) ? "software" : "hardware");
152}
153
154static void tpg110_enable(struct clcd_fb *fb)
155{
156 struct device *dev = &fb->dev->dev;
157 static bool startup;
158 u8 val;
159
160 if (!startup) {
161 tpg110_startup(dev);
162 startup = true;
163 }
164
165 /* Take chip out of standby */
166 val = tpg110_read_reg(0x03);
167 val |= BIT(0);
168 tpg110_write_reg(0x03, val);
169}
170
171static void tpg110_disable(struct clcd_fb *fb)
172{
173 u8 val;
174
175 dev_info(&fb->dev->dev, "TPG110 display disable\n");
176 val = tpg110_read_reg(0x03);
177 /* Put into standby */
178 val &= ~BIT(0);
179 tpg110_write_reg(0x03, val);
180}
181
182static void tpg110_init(struct device *dev, struct device_node *np,
183 struct clcd_board *board)
184{
185 dev_info(dev, "TPG110 display init\n");
186
187 grestb = devm_get_gpiod_from_child(dev, "grestb", &np->fwnode);
188 if (IS_ERR(grestb)) {
189 dev_err(dev, "no GRESTB GPIO\n");
190 return;
191 }
192 /* This asserts the GRESTB signal, putting the display into reset */
193 gpiod_direction_output(grestb, 1);
194
195 scen = devm_get_gpiod_from_child(dev, "scen", &np->fwnode);
196 if (IS_ERR(scen)) {
197 dev_err(dev, "no SCEN GPIO\n");
198 return;
199 }
200 gpiod_direction_output(scen, 0);
201 scl = devm_get_gpiod_from_child(dev, "scl", &np->fwnode);
202 if (IS_ERR(scl)) {
203 dev_err(dev, "no SCL GPIO\n");
204 return;
205 }
206 gpiod_direction_output(scl, 0);
207 sda = devm_get_gpiod_from_child(dev, "sda", &np->fwnode);
208 if (IS_ERR(sda)) {
209 dev_err(dev, "no SDA GPIO\n");
210 return;
211 }
212 gpiod_direction_output(sda, 0);
213 board->enable = tpg110_enable;
214 board->disable = tpg110_disable;
215}
216
217int nomadik_clcd_init_panel(struct clcd_fb *fb,
218 struct device_node *endpoint)
219{
220 struct device_node *panel;
221
222 panel = of_graph_get_remote_port_parent(endpoint);
223 if (!panel)
224 return -ENODEV;
225
226 if (of_device_is_compatible(panel, "tpo,tpg110"))
227 tpg110_init(&fb->dev->dev, panel, fb->board);
228 else
229 dev_info(&fb->dev->dev, "unknown panel\n");
230
231 /* Unknown panel, fall through */
232 return 0;
233}
234EXPORT_SYMBOL_GPL(nomadik_clcd_init_panel);
235
236#define PMU_CTRL_OFFSET 0x0000
237#define PMU_CTRL_LCDNDIF BIT(26)
238
239int nomadik_clcd_init_board(struct amba_device *adev,
240 struct clcd_board *board)
241{
242 struct regmap *pmu_regmap;
243
244 dev_info(&adev->dev, "Nomadik CLCD board init\n");
245 pmu_regmap =
246 syscon_regmap_lookup_by_compatible("stericsson,nomadik-pmu");
247 if (IS_ERR(pmu_regmap)) {
248 dev_err(&adev->dev, "could not find PMU syscon regmap\n");
249 return PTR_ERR(pmu_regmap);
250 }
251 regmap_update_bits(pmu_regmap,
252 PMU_CTRL_OFFSET,
253 PMU_CTRL_LCDNDIF,
254 0);
255 dev_info(&adev->dev, "set PMU mux to CLCD mode\n");
256
257 return 0;
258}
259EXPORT_SYMBOL_GPL(nomadik_clcd_init_board);
diff --git a/drivers/video/fbdev/amba-clcd-nomadik.h b/drivers/video/fbdev/amba-clcd-nomadik.h
new file mode 100644
index 000000000000..50aa9bda69fd
--- /dev/null
+++ b/drivers/video/fbdev/amba-clcd-nomadik.h
@@ -0,0 +1,24 @@
1#ifndef _AMBA_CLCD_NOMADIK_H
2#define _AMBA_CLCD_NOMADIK_H
3
4#include <linux/amba/bus.h>
5
6#ifdef CONFIG_ARCH_NOMADIK
7int nomadik_clcd_init_board(struct amba_device *adev,
8 struct clcd_board *board);
9int nomadik_clcd_init_panel(struct clcd_fb *fb,
10 struct device_node *endpoint);
11#else
12static inline int nomadik_clcd_init_board(struct amba_device *adev,
13 struct clcd_board *board)
14{
15 return 0;
16}
17static inline int nomadik_clcd_init_panel(struct clcd_fb *fb,
18 struct device_node *endpoint)
19{
20 return 0;
21}
22#endif
23
24#endif /* inclusion guard */
diff --git a/drivers/video/fbdev/amba-clcd-versatile.c b/drivers/video/fbdev/amba-clcd-versatile.c
index a8a22daa3f9d..19ad8645d93c 100644
--- a/drivers/video/fbdev/amba-clcd-versatile.c
+++ b/drivers/video/fbdev/amba-clcd-versatile.c
@@ -3,6 +3,12 @@
3#include <linux/amba/bus.h> 3#include <linux/amba/bus.h>
4#include <linux/amba/clcd.h> 4#include <linux/amba/clcd.h>
5#include <linux/platform_data/video-clcd-versatile.h> 5#include <linux/platform_data/video-clcd-versatile.h>
6#include <linux/of.h>
7#include <linux/of_graph.h>
8#include <linux/regmap.h>
9#include <linux/mfd/syscon.h>
10#include <linux/bitops.h>
11#include "amba-clcd-versatile.h"
6 12
7static struct clcd_panel vga = { 13static struct clcd_panel vga = {
8 .mode = { 14 .mode = {
@@ -178,3 +184,392 @@ void versatile_clcd_remove_dma(struct clcd_fb *fb)
178 dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base, 184 dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base,
179 fb->fb.fix.smem_start); 185 fb->fb.fix.smem_start);
180} 186}
187
188#ifdef CONFIG_OF
189
190static struct regmap *versatile_syscon_map;
191static struct regmap *versatile_ib2_map;
192
193/*
194 * We detect the different syscon types from the compatible strings.
195 */
196enum versatile_clcd {
197 INTEGRATOR_CLCD_CM,
198 VERSATILE_CLCD,
199 REALVIEW_CLCD_EB,
200 REALVIEW_CLCD_PB1176,
201 REALVIEW_CLCD_PB11MP,
202 REALVIEW_CLCD_PBA8,
203 REALVIEW_CLCD_PBX,
204};
205
206static const struct of_device_id versatile_clcd_of_match[] = {
207 {
208 .compatible = "arm,core-module-integrator",
209 .data = (void *)INTEGRATOR_CLCD_CM,
210 },
211 {
212 .compatible = "arm,versatile-sysreg",
213 .data = (void *)VERSATILE_CLCD,
214 },
215 {
216 .compatible = "arm,realview-eb-syscon",
217 .data = (void *)REALVIEW_CLCD_EB,
218 },
219 {
220 .compatible = "arm,realview-pb1176-syscon",
221 .data = (void *)REALVIEW_CLCD_PB1176,
222 },
223 {
224 .compatible = "arm,realview-pb11mp-syscon",
225 .data = (void *)REALVIEW_CLCD_PB11MP,
226 },
227 {
228 .compatible = "arm,realview-pba8-syscon",
229 .data = (void *)REALVIEW_CLCD_PBA8,
230 },
231 {
232 .compatible = "arm,realview-pbx-syscon",
233 .data = (void *)REALVIEW_CLCD_PBX,
234 },
235 {},
236};
237
238/*
239 * Core module CLCD control on the Integrator/CP, bits
240 * 8 thru 19 of the CM_CONTROL register controls a bunch
241 * of CLCD settings.
242 */
243#define INTEGRATOR_HDR_CTRL_OFFSET 0x0C
244#define INTEGRATOR_CLCD_LCDBIASEN BIT(8)
245#define INTEGRATOR_CLCD_LCDBIASUP BIT(9)
246#define INTEGRATOR_CLCD_LCDBIASDN BIT(10)
247/* Bits 11,12,13 controls the LCD type */
248#define INTEGRATOR_CLCD_LCDMUX_MASK (BIT(11)|BIT(12)|BIT(13))
249#define INTEGRATOR_CLCD_LCDMUX_LCD24 BIT(11)
250#define INTEGRATOR_CLCD_LCDMUX_VGA565 BIT(12)
251#define INTEGRATOR_CLCD_LCDMUX_SHARP (BIT(11)|BIT(12))
252#define INTEGRATOR_CLCD_LCDMUX_VGA555 BIT(13)
253#define INTEGRATOR_CLCD_LCDMUX_VGA24 (BIT(11)|BIT(12)|BIT(13))
254#define INTEGRATOR_CLCD_LCD0_EN BIT(14)
255#define INTEGRATOR_CLCD_LCD1_EN BIT(15)
256/* R/L flip on Sharp */
257#define INTEGRATOR_CLCD_LCD_STATIC1 BIT(16)
258/* U/D flip on Sharp */
259#define INTEGRATOR_CLCD_LCD_STATIC2 BIT(17)
260/* No connection on Sharp */
261#define INTEGRATOR_CLCD_LCD_STATIC BIT(18)
262/* 0 = 24bit VGA, 1 = 18bit VGA */
263#define INTEGRATOR_CLCD_LCD_N24BITEN BIT(19)
264
265#define INTEGRATOR_CLCD_MASK (INTEGRATOR_CLCD_LCDBIASEN | \
266 INTEGRATOR_CLCD_LCDBIASUP | \
267 INTEGRATOR_CLCD_LCDBIASDN | \
268 INTEGRATOR_CLCD_LCDMUX_MASK | \
269 INTEGRATOR_CLCD_LCD0_EN | \
270 INTEGRATOR_CLCD_LCD1_EN | \
271 INTEGRATOR_CLCD_LCD_STATIC1 | \
272 INTEGRATOR_CLCD_LCD_STATIC2 | \
273 INTEGRATOR_CLCD_LCD_STATIC | \
274 INTEGRATOR_CLCD_LCD_N24BITEN)
275
276static void integrator_clcd_enable(struct clcd_fb *fb)
277{
278 struct fb_var_screeninfo *var = &fb->fb.var;
279 u32 val;
280
281 dev_info(&fb->dev->dev, "enable Integrator CLCD connectors\n");
282
283 /* FIXME: really needed? */
284 val = INTEGRATOR_CLCD_LCD_STATIC1 | INTEGRATOR_CLCD_LCD_STATIC2 |
285 INTEGRATOR_CLCD_LCD0_EN | INTEGRATOR_CLCD_LCD1_EN;
286 if (var->bits_per_pixel <= 8 ||
287 (var->bits_per_pixel == 16 && var->green.length == 5))
288 /* Pseudocolor, RGB555, BGR555 */
289 val |= INTEGRATOR_CLCD_LCDMUX_VGA555;
290 else if (fb->fb.var.bits_per_pixel <= 16)
291 /* truecolor RGB565 */
292 val |= INTEGRATOR_CLCD_LCDMUX_VGA565;
293 else
294 val = 0; /* no idea for this, don't trust the docs */
295
296 regmap_update_bits(versatile_syscon_map,
297 INTEGRATOR_HDR_CTRL_OFFSET,
298 INTEGRATOR_CLCD_MASK,
299 val);
300}
301
302/*
303 * This configuration register in the Versatile and RealView
304 * family is uniformly present but appears more and more
305 * unutilized starting with the RealView series.
306 */
307#define SYS_CLCD 0x50
308#define SYS_CLCD_MODE_MASK (BIT(0)|BIT(1))
309#define SYS_CLCD_MODE_888 0
310#define SYS_CLCD_MODE_5551 BIT(0)
311#define SYS_CLCD_MODE_565_R_LSB BIT(1)
312#define SYS_CLCD_MODE_565_B_LSB (BIT(0)|BIT(1))
313#define SYS_CLCD_CONNECTOR_MASK (BIT(2)|BIT(3)|BIT(4)|BIT(5))
314#define SYS_CLCD_NLCDIOON BIT(2)
315#define SYS_CLCD_VDDPOSSWITCH BIT(3)
316#define SYS_CLCD_PWR3V5SWITCH BIT(4)
317#define SYS_CLCD_VDDNEGSWITCH BIT(5)
318#define SYS_CLCD_TSNSS BIT(6) /* touchscreen enable */
319#define SYS_CLCD_SSPEXP BIT(7) /* SSP expansion enable */
320
321/* The Versatile can detect the connected panel type */
322#define SYS_CLCD_CLCDID_MASK (BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12))
323#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8)
324#define SYS_CLCD_ID_SHARP_8_4 (0x01 << 8)
325#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8)
326#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
327#define SYS_CLCD_ID_VGA (0x1f << 8)
328
329#define SYS_CLCD_TSNDAV BIT(13) /* data ready from TS */
330
331/* IB2 control register for the Versatile daughterboard */
332#define IB2_CTRL 0x00
333#define IB2_CTRL_LCD_SD BIT(1) /* 1 = shut down LCD */
334#define IB2_CTRL_LCD_BL_ON BIT(0)
335#define IB2_CTRL_LCD_MASK (BIT(0)|BIT(1))
336
337static void versatile_clcd_disable(struct clcd_fb *fb)
338{
339 dev_info(&fb->dev->dev, "disable Versatile CLCD connectors\n");
340 regmap_update_bits(versatile_syscon_map,
341 SYS_CLCD,
342 SYS_CLCD_CONNECTOR_MASK,
343 0);
344
345 /* If we're on an IB2 daughterboard, turn off display */
346 if (versatile_ib2_map) {
347 dev_info(&fb->dev->dev, "disable IB2 display\n");
348 regmap_update_bits(versatile_ib2_map,
349 IB2_CTRL,
350 IB2_CTRL_LCD_MASK,
351 IB2_CTRL_LCD_SD);
352 }
353}
354
355static void versatile_clcd_enable(struct clcd_fb *fb)
356{
357 struct fb_var_screeninfo *var = &fb->fb.var;
358 u32 val = 0;
359
360 dev_info(&fb->dev->dev, "enable Versatile CLCD connectors\n");
361 switch (var->green.length) {
362 case 5:
363 val |= SYS_CLCD_MODE_5551;
364 break;
365 case 6:
366 if (var->red.offset == 0)
367 val |= SYS_CLCD_MODE_565_R_LSB;
368 else
369 val |= SYS_CLCD_MODE_565_B_LSB;
370 break;
371 case 8:
372 val |= SYS_CLCD_MODE_888;
373 break;
374 }
375
376 /* Set up the MUX */
377 regmap_update_bits(versatile_syscon_map,
378 SYS_CLCD,
379 SYS_CLCD_MODE_MASK,
380 val);
381
382 /* Then enable the display */
383 regmap_update_bits(versatile_syscon_map,
384 SYS_CLCD,
385 SYS_CLCD_CONNECTOR_MASK,
386 SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH);
387
388 /* If we're on an IB2 daughterboard, turn on display */
389 if (versatile_ib2_map) {
390 dev_info(&fb->dev->dev, "enable IB2 display\n");
391 regmap_update_bits(versatile_ib2_map,
392 IB2_CTRL,
393 IB2_CTRL_LCD_MASK,
394 IB2_CTRL_LCD_BL_ON);
395 }
396}
397
398static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs)
399{
400 clcdfb_decode(fb, regs);
401
402 /* Always clear BGR for RGB565: we do the routing externally */
403 if (fb->fb.var.green.length == 6)
404 regs->cntl &= ~CNTL_BGR;
405}
406
407static void realview_clcd_disable(struct clcd_fb *fb)
408{
409 dev_info(&fb->dev->dev, "disable RealView CLCD connectors\n");
410 regmap_update_bits(versatile_syscon_map,
411 SYS_CLCD,
412 SYS_CLCD_CONNECTOR_MASK,
413 0);
414}
415
416static void realview_clcd_enable(struct clcd_fb *fb)
417{
418 dev_info(&fb->dev->dev, "enable RealView CLCD connectors\n");
419 regmap_update_bits(versatile_syscon_map,
420 SYS_CLCD,
421 SYS_CLCD_CONNECTOR_MASK,
422 SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH);
423}
424
425struct versatile_panel {
426 u32 id;
427 char *compatible;
428 bool ib2;
429};
430
431static const struct versatile_panel versatile_panels[] = {
432 {
433 .id = SYS_CLCD_ID_VGA,
434 .compatible = "VGA",
435 },
436 {
437 .id = SYS_CLCD_ID_SANYO_3_8,
438 .compatible = "sanyo,tm38qv67a02a",
439 },
440 {
441 .id = SYS_CLCD_ID_SHARP_8_4,
442 .compatible = "sharp,lq084v1dg21",
443 },
444 {
445 .id = SYS_CLCD_ID_EPSON_2_2,
446 .compatible = "epson,l2f50113t00",
447 },
448 {
449 .id = SYS_CLCD_ID_SANYO_2_5,
450 .compatible = "sanyo,alr252rgt",
451 .ib2 = true,
452 },
453};
454
455static void versatile_panel_probe(struct device *dev,
456 struct device_node *endpoint)
457{
458 struct versatile_panel const *vpanel = NULL;
459 struct device_node *panel = NULL;
460 u32 val;
461 int ret;
462 int i;
463
464 /*
465 * The Versatile CLCD has a panel auto-detection mechanism.
466 * We use this and look for the compatible panel in the
467 * device tree.
468 */
469 ret = regmap_read(versatile_syscon_map, SYS_CLCD, &val);
470 if (ret) {
471 dev_err(dev, "cannot read CLCD syscon register\n");
472 return;
473 }
474 val &= SYS_CLCD_CLCDID_MASK;
475
476 /* First find corresponding panel information */
477 for (i = 0; i < ARRAY_SIZE(versatile_panels); i++) {
478 vpanel = &versatile_panels[i];
479
480 if (val == vpanel->id) {
481 dev_err(dev, "autodetected panel \"%s\"\n",
482 vpanel->compatible);
483 break;
484 }
485 }
486 if (i == ARRAY_SIZE(versatile_panels)) {
487 dev_err(dev, "could not auto-detect panel\n");
488 return;
489 }
490
491 panel = of_graph_get_remote_port_parent(endpoint);
492 if (!panel) {
493 dev_err(dev, "could not locate panel in DT\n");
494 return;
495 }
496 if (!of_device_is_compatible(panel, vpanel->compatible))
497 dev_err(dev, "panel in DT is not compatible with the "
498 "auto-detected panel, continuing anyway\n");
499
500 /*
501 * If we have a Sanyo 2.5" port
502 * that we're running on an IB2 and proceed to look for the
503 * IB2 syscon regmap.
504 */
505 if (!vpanel->ib2)
506 return;
507
508 versatile_ib2_map = syscon_regmap_lookup_by_compatible(
509 "arm,versatile-ib2-syscon");
510 if (IS_ERR(versatile_ib2_map)) {
511 dev_err(dev, "could not locate IB2 control register\n");
512 versatile_ib2_map = NULL;
513 return;
514 }
515}
516
517int versatile_clcd_init_panel(struct clcd_fb *fb,
518 struct device_node *endpoint)
519{
520 const struct of_device_id *clcd_id;
521 enum versatile_clcd versatile_clcd_type;
522 struct device_node *np;
523 struct regmap *map;
524 struct device *dev = &fb->dev->dev;
525
526 np = of_find_matching_node_and_match(NULL, versatile_clcd_of_match,
527 &clcd_id);
528 if (!np) {
529 dev_err(dev, "no Versatile syscon node\n");
530 return -ENODEV;
531 }
532 versatile_clcd_type = (enum versatile_clcd)clcd_id->data;
533
534 map = syscon_node_to_regmap(np);
535 if (IS_ERR(map)) {
536 dev_err(dev, "no Versatile syscon regmap\n");
537 return PTR_ERR(map);
538 }
539
540 switch (versatile_clcd_type) {
541 case INTEGRATOR_CLCD_CM:
542 versatile_syscon_map = map;
543 fb->board->enable = integrator_clcd_enable;
544 /* Override the caps, we have only these */
545 fb->board->caps = CLCD_CAP_5551 | CLCD_CAP_RGB565 |
546 CLCD_CAP_888;
547 dev_info(dev, "set up callbacks for Integrator PL110\n");
548 break;
549 case VERSATILE_CLCD:
550 versatile_syscon_map = map;
551 fb->board->enable = versatile_clcd_enable;
552 fb->board->disable = versatile_clcd_disable;
553 fb->board->decode = versatile_clcd_decode;
554 versatile_panel_probe(dev, endpoint);
555 dev_info(dev, "set up callbacks for Versatile\n");
556 break;
557 case REALVIEW_CLCD_EB:
558 case REALVIEW_CLCD_PB1176:
559 case REALVIEW_CLCD_PB11MP:
560 case REALVIEW_CLCD_PBA8:
561 case REALVIEW_CLCD_PBX:
562 versatile_syscon_map = map;
563 fb->board->enable = realview_clcd_enable;
564 fb->board->disable = realview_clcd_disable;
565 dev_info(dev, "set up callbacks for RealView PL111\n");
566 break;
567 default:
568 dev_info(dev, "unknown Versatile system controller\n");
569 break;
570 }
571
572 return 0;
573}
574EXPORT_SYMBOL_GPL(versatile_clcd_init_panel);
575#endif
diff --git a/drivers/video/fbdev/amba-clcd-versatile.h b/drivers/video/fbdev/amba-clcd-versatile.h
new file mode 100644
index 000000000000..1b14359c2cf6
--- /dev/null
+++ b/drivers/video/fbdev/amba-clcd-versatile.h
@@ -0,0 +1,17 @@
1/*
2 * Special local versatile callbacks
3 */
4#include <linux/of.h>
5#include <linux/amba/bus.h>
6#include <linux/platform_data/video-clcd-versatile.h>
7
8#if defined(CONFIG_PLAT_VERSATILE_CLCD) && defined(CONFIG_OF)
9int versatile_clcd_init_panel(struct clcd_fb *fb,
10 struct device_node *endpoint);
11#else
12static inline int versatile_clcd_init_panel(struct clcd_fb *fb,
13 struct device_node *endpoint)
14{
15 return 0;
16}
17#endif
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 9b158869cb89..ec2671d98abc 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -30,10 +30,14 @@
30#include <linux/of.h> 30#include <linux/of.h>
31#include <linux/of_address.h> 31#include <linux/of_address.h>
32#include <linux/of_graph.h> 32#include <linux/of_graph.h>
33#include <linux/backlight.h>
33#include <video/display_timing.h> 34#include <video/display_timing.h>
34#include <video/of_display_timing.h> 35#include <video/of_display_timing.h>
35#include <video/videomode.h> 36#include <video/videomode.h>
36 37
38#include "amba-clcd-nomadik.h"
39#include "amba-clcd-versatile.h"
40
37#define to_clcd(info) container_of(info, struct clcd_fb, fb) 41#define to_clcd(info) container_of(info, struct clcd_fb, fb)
38 42
39/* This is limited to 16 characters when displayed by X startup */ 43/* This is limited to 16 characters when displayed by X startup */
@@ -71,6 +75,11 @@ static void clcdfb_disable(struct clcd_fb *fb)
71 if (fb->board->disable) 75 if (fb->board->disable)
72 fb->board->disable(fb); 76 fb->board->disable(fb);
73 77
78 if (fb->panel->backlight) {
79 fb->panel->backlight->props.power = FB_BLANK_POWERDOWN;
80 backlight_update_status(fb->panel->backlight);
81 }
82
74 val = readl(fb->regs + fb->off_cntl); 83 val = readl(fb->regs + fb->off_cntl);
75 if (val & CNTL_LCDPWR) { 84 if (val & CNTL_LCDPWR) {
76 val &= ~CNTL_LCDPWR; 85 val &= ~CNTL_LCDPWR;
@@ -117,6 +126,14 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
117 writel(cntl, fb->regs + fb->off_cntl); 126 writel(cntl, fb->regs + fb->off_cntl);
118 127
119 /* 128 /*
129 * Turn on backlight
130 */
131 if (fb->panel->backlight) {
132 fb->panel->backlight->props.power = FB_BLANK_UNBLANK;
133 backlight_update_status(fb->panel->backlight);
134 }
135
136 /*
120 * finally, enable the interface. 137 * finally, enable the interface.
121 */ 138 */
122 if (fb->board->enable) 139 if (fb->board->enable)
@@ -211,6 +228,15 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
211 var->blue.length = 4; 228 var->blue.length = 4;
212 } 229 }
213 break; 230 break;
231 case 24:
232 if (fb->vendor->packed_24_bit_pixels) {
233 var->red.length = 8;
234 var->green.length = 8;
235 var->blue.length = 8;
236 } else {
237 ret = -EINVAL;
238 }
239 break;
214 case 32: 240 case 32:
215 /* If we can't do 888, reject */ 241 /* If we can't do 888, reject */
216 caps &= CLCD_CAP_888; 242 caps &= CLCD_CAP_888;
@@ -297,6 +323,12 @@ static int clcdfb_set_par(struct fb_info *info)
297 323
298 clcdfb_disable(fb); 324 clcdfb_disable(fb);
299 325
326 /* Some variants must be clocked here */
327 if (fb->vendor->clock_timregs && !fb->clk_enabled) {
328 fb->clk_enabled = true;
329 clk_enable(fb->clk);
330 }
331
300 writel(regs.tim0, fb->regs + CLCD_TIM0); 332 writel(regs.tim0, fb->regs + CLCD_TIM0);
301 writel(regs.tim1, fb->regs + CLCD_TIM1); 333 writel(regs.tim1, fb->regs + CLCD_TIM1);
302 writel(regs.tim2, fb->regs + CLCD_TIM2); 334 writel(regs.tim2, fb->regs + CLCD_TIM2);
@@ -551,7 +583,7 @@ static int clcdfb_register(struct clcd_fb *fb)
551 583
552#ifdef CONFIG_OF 584#ifdef CONFIG_OF
553static int clcdfb_of_get_dpi_panel_mode(struct device_node *node, 585static int clcdfb_of_get_dpi_panel_mode(struct device_node *node,
554 struct fb_videomode *mode) 586 struct clcd_panel *clcd_panel)
555{ 587{
556 int err; 588 int err;
557 struct display_timing timing; 589 struct display_timing timing;
@@ -563,10 +595,31 @@ static int clcdfb_of_get_dpi_panel_mode(struct device_node *node,
563 595
564 videomode_from_timing(&timing, &video); 596 videomode_from_timing(&timing, &video);
565 597
566 err = fb_videomode_from_videomode(&video, mode); 598 err = fb_videomode_from_videomode(&video, &clcd_panel->mode);
567 if (err) 599 if (err)
568 return err; 600 return err;
569 601
602 /* Set up some inversion flags */
603 if (timing.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
604 clcd_panel->tim2 |= TIM2_IPC;
605 else if (!(timing.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE))
606 /*
607 * To preserve backwards compatibility, the IPC (inverted
608 * pixel clock) flag needs to be set on any display that
609 * doesn't explicitly specify that the pixel clock is
610 * active on the negative or positive edge.
611 */
612 clcd_panel->tim2 |= TIM2_IPC;
613
614 if (timing.flags & DISPLAY_FLAGS_HSYNC_LOW)
615 clcd_panel->tim2 |= TIM2_IHS;
616
617 if (timing.flags & DISPLAY_FLAGS_VSYNC_LOW)
618 clcd_panel->tim2 |= TIM2_IVS;
619
620 if (timing.flags & DISPLAY_FLAGS_DE_LOW)
621 clcd_panel->tim2 |= TIM2_IOE;
622
570 return 0; 623 return 0;
571} 624}
572 625
@@ -576,11 +629,34 @@ static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
576 mode->refresh); 629 mode->refresh);
577} 630}
578 631
632static int clcdfb_of_get_backlight(struct device_node *endpoint,
633 struct clcd_panel *clcd_panel)
634{
635 struct device_node *panel;
636 struct device_node *backlight;
637
638 panel = of_graph_get_remote_port_parent(endpoint);
639 if (!panel)
640 return -ENODEV;
641
642 /* Look up the optional backlight phandle */
643 backlight = of_parse_phandle(panel, "backlight", 0);
644 if (backlight) {
645 clcd_panel->backlight = of_find_backlight_by_node(backlight);
646 of_node_put(backlight);
647
648 if (!clcd_panel->backlight)
649 return -EPROBE_DEFER;
650 }
651 return 0;
652}
653
579static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint, 654static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint,
580 struct fb_videomode *mode) 655 struct clcd_panel *clcd_panel)
581{ 656{
582 int err; 657 int err;
583 struct device_node *panel; 658 struct device_node *panel;
659 struct fb_videomode *mode;
584 char *name; 660 char *name;
585 int len; 661 int len;
586 662
@@ -590,11 +666,12 @@ static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint,
590 666
591 /* Only directly connected DPI panels supported for now */ 667 /* Only directly connected DPI panels supported for now */
592 if (of_device_is_compatible(panel, "panel-dpi")) 668 if (of_device_is_compatible(panel, "panel-dpi"))
593 err = clcdfb_of_get_dpi_panel_mode(panel, mode); 669 err = clcdfb_of_get_dpi_panel_mode(panel, clcd_panel);
594 else 670 else
595 err = -ENOENT; 671 err = -ENOENT;
596 if (err) 672 if (err)
597 return err; 673 return err;
674 mode = &clcd_panel->mode;
598 675
599 len = clcdfb_snprintf_mode(NULL, 0, mode); 676 len = clcdfb_snprintf_mode(NULL, 0, mode);
600 name = devm_kzalloc(dev, len + 1, GFP_KERNEL); 677 name = devm_kzalloc(dev, len + 1, GFP_KERNEL);
@@ -616,6 +693,7 @@ static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
616 } panels[] = { 693 } panels[] = {
617 { 0x110, 1, 7, 13, CLCD_CAP_5551 }, 694 { 0x110, 1, 7, 13, CLCD_CAP_5551 },
618 { 0x110, 0, 8, 16, CLCD_CAP_888 }, 695 { 0x110, 0, 8, 16, CLCD_CAP_888 },
696 { 0x110, 16, 8, 0, CLCD_CAP_888 },
619 { 0x111, 4, 14, 20, CLCD_CAP_444 }, 697 { 0x111, 4, 14, 20, CLCD_CAP_444 },
620 { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 }, 698 { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 },
621 { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 | 699 { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 |
@@ -625,8 +703,8 @@ static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
625 }; 703 };
626 int i; 704 int i;
627 705
628 /* Bypass pixel clock divider, data output on the falling edge */ 706 /* Bypass pixel clock divider */
629 fb->panel->tim2 = TIM2_BCD | TIM2_IPC; 707 fb->panel->tim2 |= TIM2_BCD;
630 708
631 /* TFT display, vert. comp. interrupt at the start of the back porch */ 709 /* TFT display, vert. comp. interrupt at the start of the back porch */
632 fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1); 710 fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1);
@@ -643,6 +721,49 @@ static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
643 fb->panel->caps = panels[i].caps; 721 fb->panel->caps = panels[i].caps;
644 } 722 }
645 723
724 /*
725 * If we actually physically connected the R lines to B and
726 * vice versa
727 */
728 if (r0 != 0 && b0 == 0)
729 fb->panel->bgr_connection = true;
730
731 if (fb->panel->caps && fb->vendor->st_bitmux_control) {
732 /*
733 * Set up the special bits for the Nomadik control register
734 * (other platforms tend to do this through an external
735 * register).
736 */
737
738 /* Offset of the highest used color */
739 int maxoff = max3(r0, g0, b0);
740 /* Most significant bit out, highest used bit */
741 int msb = 0;
742
743 if (fb->panel->caps & CLCD_CAP_888) {
744 msb = maxoff + 8 - 1;
745 } else if (fb->panel->caps & CLCD_CAP_565) {
746 msb = maxoff + 5 - 1;
747 fb->panel->cntl |= CNTL_ST_1XBPP_565;
748 } else if (fb->panel->caps & CLCD_CAP_5551) {
749 msb = maxoff + 5 - 1;
750 fb->panel->cntl |= CNTL_ST_1XBPP_5551;
751 } else if (fb->panel->caps & CLCD_CAP_444) {
752 msb = maxoff + 4 - 1;
753 fb->panel->cntl |= CNTL_ST_1XBPP_444;
754 }
755
756 /* Send out as many bits as we need */
757 if (msb > 17)
758 fb->panel->cntl |= CNTL_ST_CDWID_24;
759 else if (msb > 15)
760 fb->panel->cntl |= CNTL_ST_CDWID_18;
761 else if (msb > 11)
762 fb->panel->cntl |= CNTL_ST_CDWID_16;
763 else
764 fb->panel->cntl |= CNTL_ST_CDWID_12;
765 }
766
646 return fb->panel->caps ? 0 : -EINVAL; 767 return fb->panel->caps ? 0 : -EINVAL;
647} 768}
648 769
@@ -658,11 +779,24 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
658 if (!fb->panel) 779 if (!fb->panel)
659 return -ENOMEM; 780 return -ENOMEM;
660 781
782 /*
783 * Fetch the panel endpoint.
784 */
661 endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL); 785 endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
662 if (!endpoint) 786 if (!endpoint)
663 return -ENODEV; 787 return -ENODEV;
664 788
665 err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, &fb->panel->mode); 789 if (fb->vendor->init_panel) {
790 err = fb->vendor->init_panel(fb, endpoint);
791 if (err)
792 return err;
793 }
794
795 err = clcdfb_of_get_backlight(endpoint, fb->panel);
796 if (err)
797 return err;
798
799 err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, fb->panel);
666 if (err) 800 if (err)
667 return err; 801 return err;
668 802
@@ -693,11 +827,11 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
693 827
694 if (of_property_read_u32_array(endpoint, 828 if (of_property_read_u32_array(endpoint,
695 "arm,pl11x,tft-r0g0b0-pads", 829 "arm,pl11x,tft-r0g0b0-pads",
696 tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) == 0) 830 tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0)
697 return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0], 831 return -ENOENT;
698 tft_r0b0g0[1], tft_r0b0g0[2]);
699 832
700 return -ENOENT; 833 return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
834 tft_r0b0g0[1], tft_r0b0g0[2]);
701} 835}
702 836
703static int clcdfb_of_vram_setup(struct clcd_fb *fb) 837static int clcdfb_of_vram_setup(struct clcd_fb *fb)
@@ -818,6 +952,7 @@ static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
818static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) 952static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
819{ 953{
820 struct clcd_board *board = dev_get_platdata(&dev->dev); 954 struct clcd_board *board = dev_get_platdata(&dev->dev);
955 struct clcd_vendor_data *vendor = id->data;
821 struct clcd_fb *fb; 956 struct clcd_fb *fb;
822 int ret; 957 int ret;
823 958
@@ -827,6 +962,12 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
827 if (!board) 962 if (!board)
828 return -EINVAL; 963 return -EINVAL;
829 964
965 if (vendor->init_board) {
966 ret = vendor->init_board(dev, board);
967 if (ret)
968 return ret;
969 }
970
830 ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); 971 ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
831 if (ret) 972 if (ret)
832 goto out; 973 goto out;
@@ -845,17 +986,18 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
845 } 986 }
846 987
847 fb->dev = dev; 988 fb->dev = dev;
989 fb->vendor = vendor;
848 fb->board = board; 990 fb->board = board;
849 991
850 dev_info(&fb->dev->dev, "PL%03x rev%u at 0x%08llx\n", 992 dev_info(&fb->dev->dev, "PL%03x designer %02x rev%u at 0x%08llx\n",
851 amba_part(dev), amba_rev(dev), 993 amba_part(dev), amba_manf(dev), amba_rev(dev),
852 (unsigned long long)dev->res.start); 994 (unsigned long long)dev->res.start);
853 995
854 ret = fb->board->setup(fb); 996 ret = fb->board->setup(fb);
855 if (ret) 997 if (ret)
856 goto free_fb; 998 goto free_fb;
857 999
858 ret = clcdfb_register(fb); 1000 ret = clcdfb_register(fb);
859 if (ret == 0) { 1001 if (ret == 0) {
860 amba_set_drvdata(dev, fb); 1002 amba_set_drvdata(dev, fb);
861 goto out; 1003 goto out;
@@ -891,10 +1033,30 @@ static int clcdfb_remove(struct amba_device *dev)
891 return 0; 1033 return 0;
892} 1034}
893 1035
1036static struct clcd_vendor_data vendor_arm = {
1037 /* Sets up the versatile board displays */
1038 .init_panel = versatile_clcd_init_panel,
1039};
1040
1041static struct clcd_vendor_data vendor_nomadik = {
1042 .clock_timregs = true,
1043 .packed_24_bit_pixels = true,
1044 .st_bitmux_control = true,
1045 .init_board = nomadik_clcd_init_board,
1046 .init_panel = nomadik_clcd_init_panel,
1047};
1048
894static struct amba_id clcdfb_id_table[] = { 1049static struct amba_id clcdfb_id_table[] = {
895 { 1050 {
896 .id = 0x00041110, 1051 .id = 0x00041110,
897 .mask = 0x000ffffe, 1052 .mask = 0x000ffffe,
1053 .data = &vendor_arm,
1054 },
1055 /* ST Electronics Nomadik variant */
1056 {
1057 .id = 0x00180110,
1058 .mask = 0x00fffffe,
1059 .data = &vendor_nomadik,
898 }, 1060 },
899 { 0, 0 }, 1061 { 0, 0 },
900}; 1062};
diff --git a/drivers/video/fbdev/arcfb.c b/drivers/video/fbdev/arcfb.c
index 1b0b233b8b39..1928cb2b5386 100644
--- a/drivers/video/fbdev/arcfb.c
+++ b/drivers/video/fbdev/arcfb.c
@@ -79,7 +79,7 @@ struct arcfb_par {
79 spinlock_t lock; 79 spinlock_t lock;
80}; 80};
81 81
82static struct fb_fix_screeninfo arcfb_fix = { 82static const struct fb_fix_screeninfo arcfb_fix = {
83 .id = "arcfb", 83 .id = "arcfb",
84 .type = FB_TYPE_PACKED_PIXELS, 84 .type = FB_TYPE_PACKED_PIXELS,
85 .visual = FB_VISUAL_MONO01, 85 .visual = FB_VISUAL_MONO01,
@@ -89,7 +89,7 @@ static struct fb_fix_screeninfo arcfb_fix = {
89 .accel = FB_ACCEL_NONE, 89 .accel = FB_ACCEL_NONE,
90}; 90};
91 91
92static struct fb_var_screeninfo arcfb_var = { 92static const struct fb_var_screeninfo arcfb_var = {
93 .xres = 128, 93 .xres = 128,
94 .yres = 64, 94 .yres = 64,
95 .xres_virtual = 128, 95 .xres_virtual = 128,
diff --git a/drivers/video/fbdev/asiliantfb.c b/drivers/video/fbdev/asiliantfb.c
index 7e8ddf00ccc2..91eea4583382 100644
--- a/drivers/video/fbdev/asiliantfb.c
+++ b/drivers/video/fbdev/asiliantfb.c
@@ -474,7 +474,7 @@ static void chips_hw_init(struct fb_info *p)
474 write_fr(chips_init_fr[i].addr, chips_init_fr[i].data); 474 write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
475} 475}
476 476
477static struct fb_fix_screeninfo asiliantfb_fix = { 477static const struct fb_fix_screeninfo asiliantfb_fix = {
478 .id = "Asiliant 69000", 478 .id = "Asiliant 69000",
479 .type = FB_TYPE_PACKED_PIXELS, 479 .type = FB_TYPE_PACKED_PIXELS,
480 .visual = FB_VISUAL_PSEUDOCOLOR, 480 .visual = FB_VISUAL_PSEUDOCOLOR,
@@ -483,7 +483,7 @@ static struct fb_fix_screeninfo asiliantfb_fix = {
483 .smem_len = 0x200000, /* 2MB */ 483 .smem_len = 0x200000, /* 2MB */
484}; 484};
485 485
486static struct fb_var_screeninfo asiliantfb_var = { 486static const struct fb_var_screeninfo asiliantfb_var = {
487 .xres = 640, 487 .xres = 640,
488 .yres = 480, 488 .yres = 480,
489 .xres_virtual = 640, 489 .xres_virtual = 640,
diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c
index 0a4626886b00..fa07242a78d2 100644
--- a/drivers/video/fbdev/aty/aty128fb.c
+++ b/drivers/video/fbdev/aty/aty128fb.c
@@ -93,7 +93,7 @@
93 93
94#ifndef CONFIG_PPC_PMAC 94#ifndef CONFIG_PPC_PMAC
95/* default mode */ 95/* default mode */
96static struct fb_var_screeninfo default_var = { 96static const struct fb_var_screeninfo default_var = {
97 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 97 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
98 640, 480, 640, 480, 0, 0, 8, 0, 98 640, 480, 640, 480, 0, 0, 8, 0,
99 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, 99 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
@@ -104,7 +104,7 @@ static struct fb_var_screeninfo default_var = {
104#else /* CONFIG_PPC_PMAC */ 104#else /* CONFIG_PPC_PMAC */
105/* default to 1024x768 at 75Hz on PPC - this will work 105/* default to 1024x768 at 75Hz on PPC - this will work
106 * on the iMac, the usual 640x480 @ 60Hz doesn't. */ 106 * on the iMac, the usual 640x480 @ 60Hz doesn't. */
107static struct fb_var_screeninfo default_var = { 107static const struct fb_var_screeninfo default_var = {
108 /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */ 108 /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
109 1024, 768, 1024, 768, 0, 0, 8, 0, 109 1024, 768, 1024, 768, 0, 0, 8, 0,
110 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, 110 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
@@ -375,7 +375,7 @@ static const struct aty128_meminfo ddr_sgram = {
375 .name = "64-bit DDR SGRAM", 375 .name = "64-bit DDR SGRAM",
376}; 376};
377 377
378static struct fb_fix_screeninfo aty128fb_fix = { 378static const struct fb_fix_screeninfo aty128fb_fix = {
379 .id = "ATY Rage128", 379 .id = "ATY Rage128",
380 .type = FB_TYPE_PACKED_PIXELS, 380 .type = FB_TYPE_PACKED_PIXELS,
381 .visual = FB_VISUAL_PSEUDOCOLOR, 381 .visual = FB_VISUAL_PSEUDOCOLOR,
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index f34ed47fcaf8..11026e726b68 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -212,7 +212,7 @@ struct pci_mmap_map {
212 unsigned long prot_mask; 212 unsigned long prot_mask;
213}; 213};
214 214
215static struct fb_fix_screeninfo atyfb_fix = { 215static const struct fb_fix_screeninfo atyfb_fix = {
216 .id = "ATY Mach64", 216 .id = "ATY Mach64",
217 .type = FB_TYPE_PACKED_PIXELS, 217 .type = FB_TYPE_PACKED_PIXELS,
218 .visual = FB_VISUAL_PSEUDOCOLOR, 218 .visual = FB_VISUAL_PSEUDOCOLOR,
diff --git a/drivers/video/fbdev/aty/radeon_monitor.c b/drivers/video/fbdev/aty/radeon_monitor.c
index f1ce229de78d..278b421ab3fe 100644
--- a/drivers/video/fbdev/aty/radeon_monitor.c
+++ b/drivers/video/fbdev/aty/radeon_monitor.c
@@ -4,7 +4,7 @@
4 4
5#include "../edid.h" 5#include "../edid.h"
6 6
7static struct fb_var_screeninfo radeonfb_default_var = { 7static const struct fb_var_screeninfo radeonfb_default_var = {
8 .xres = 640, 8 .xres = 640,
9 .yres = 480, 9 .yres = 480,
10 .xres_virtual = 640, 10 .xres_virtual = 640,
diff --git a/drivers/video/fbdev/bfin_adv7393fb.c b/drivers/video/fbdev/bfin_adv7393fb.c
index e2d7d039ce3b..542ffaddc6ab 100644
--- a/drivers/video/fbdev/bfin_adv7393fb.c
+++ b/drivers/video/fbdev/bfin_adv7393fb.c
@@ -375,7 +375,6 @@ static int bfin_adv7393_fb_probe(struct i2c_client *client,
375{ 375{
376 int ret = 0; 376 int ret = 0;
377 struct proc_dir_entry *entry; 377 struct proc_dir_entry *entry;
378 int num_modes = ARRAY_SIZE(known_modes);
379 378
380 struct adv7393fb_device *fbdev = NULL; 379 struct adv7393fb_device *fbdev = NULL;
381 380
@@ -384,7 +383,7 @@ static int bfin_adv7393_fb_probe(struct i2c_client *client,
384 return -EINVAL; 383 return -EINVAL;
385 } 384 }
386 385
387 if (mode > num_modes) { 386 if (mode >= ARRAY_SIZE(known_modes)) {
388 dev_err(&client->dev, "mode %d: not supported", mode); 387 dev_err(&client->dev, "mode %d: not supported", mode);
389 return -EFAULT; 388 return -EFAULT;
390 } 389 }
@@ -797,7 +796,7 @@ static struct i2c_driver bfin_adv7393_fb_driver = {
797 796
798static int __init bfin_adv7393_fb_driver_init(void) 797static int __init bfin_adv7393_fb_driver_init(void)
799{ 798{
800#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) 799#if IS_ENABLED(CONFIG_I2C_BLACKFIN_TWI)
801 request_module("i2c-bfin-twi"); 800 request_module("i2c-bfin-twi");
802#else 801#else
803 request_module("i2c-gpio"); 802 request_module("i2c-gpio");
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index 924bad45c176..37a37c4d04cb 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -50,9 +50,9 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
50 return 1; 50 return 1;
51 51
52 if (regno < 16) { 52 if (regno < 16) {
53 red >>= 8; 53 red >>= 16 - info->var.red.length;
54 green >>= 8; 54 green >>= 16 - info->var.green.length;
55 blue >>= 8; 55 blue >>= 16 - info->var.blue.length;
56 ((u32 *)(info->pseudo_palette))[regno] = 56 ((u32 *)(info->pseudo_palette))[regno] =
57 (red << info->var.red.offset) | 57 (red << info->var.red.offset) |
58 (green << info->var.green.offset) | 58 (green << info->var.green.offset) |
diff --git a/drivers/video/fbdev/exynos/Kconfig b/drivers/video/fbdev/exynos/Kconfig
deleted file mode 100644
index d916bef94f25..000000000000
--- a/drivers/video/fbdev/exynos/Kconfig
+++ /dev/null
@@ -1,32 +0,0 @@
1#
2# Exynos Video configuration
3#
4
5menuconfig EXYNOS_VIDEO
6 tristate "Exynos Video driver support"
7 depends on ARCH_S5PV210 || ARCH_EXYNOS
8 help
9 This enables support for EXYNOS Video device.
10
11if EXYNOS_VIDEO
12
13#
14# MIPI DSI driver
15#
16
17config EXYNOS_MIPI_DSI
18 tristate "EXYNOS MIPI DSI driver support."
19 select GENERIC_PHY
20 help
21 This enables support for MIPI-DSI device.
22
23config EXYNOS_LCD_S6E8AX0
24 tristate "S6E8AX0 MIPI AMOLED LCD Driver"
25 depends on EXYNOS_MIPI_DSI && BACKLIGHT_CLASS_DEVICE
26 depends on (LCD_CLASS_DEVICE = y)
27 default n
28 help
29 If you have an S6E8AX0 MIPI AMOLED LCD Panel, say Y to enable its
30 LCD control driver.
31
32endif # EXYNOS_VIDEO
diff --git a/drivers/video/fbdev/exynos/Makefile b/drivers/video/fbdev/exynos/Makefile
deleted file mode 100644
index 02d8dc522fea..000000000000
--- a/drivers/video/fbdev/exynos/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
1#
2# Makefile for the exynos video drivers.
3#
4
5obj-$(CONFIG_EXYNOS_MIPI_DSI) += exynos-mipi-dsi-mod.o
6
7exynos-mipi-dsi-mod-objs += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
8 exynos_mipi_dsi_lowlevel.o
9obj-$(CONFIG_EXYNOS_LCD_S6E8AX0) += s6e8ax0.o
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c
deleted file mode 100644
index 92e4af3caaf8..000000000000
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c
+++ /dev/null
@@ -1,574 +0,0 @@
1/* linux/drivers/video/exynos/exynos_mipi_dsi.c
2 *
3 * Samsung SoC MIPI-DSIM driver.
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd
6 *
7 * InKi Dae, <inki.dae@samsung.com>
8 * Donghwa Lee, <dh09.lee@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/clk.h>
19#include <linux/mutex.h>
20#include <linux/wait.h>
21#include <linux/fs.h>
22#include <linux/mm.h>
23#include <linux/fb.h>
24#include <linux/ctype.h>
25#include <linux/platform_device.h>
26#include <linux/io.h>
27#include <linux/irq.h>
28#include <linux/memory.h>
29#include <linux/delay.h>
30#include <linux/interrupt.h>
31#include <linux/kthread.h>
32#include <linux/notifier.h>
33#include <linux/phy/phy.h>
34#include <linux/regulator/consumer.h>
35#include <linux/pm_runtime.h>
36#include <linux/err.h>
37
38#include <video/exynos_mipi_dsim.h>
39
40#include "exynos_mipi_dsi_common.h"
41#include "exynos_mipi_dsi_lowlevel.h"
42
43struct mipi_dsim_ddi {
44 int bus_id;
45 struct list_head list;
46 struct mipi_dsim_lcd_device *dsim_lcd_dev;
47 struct mipi_dsim_lcd_driver *dsim_lcd_drv;
48};
49
50static LIST_HEAD(dsim_ddi_list);
51
52static DEFINE_MUTEX(mipi_dsim_lock);
53
54static struct mipi_dsim_platform_data *to_dsim_plat(struct platform_device
55 *pdev)
56{
57 return pdev->dev.platform_data;
58}
59
60static struct regulator_bulk_data supplies[] = {
61 { .supply = "vdd11", },
62 { .supply = "vdd18", },
63};
64
65static int exynos_mipi_regulator_enable(struct mipi_dsim_device *dsim)
66{
67 int ret;
68
69 mutex_lock(&dsim->lock);
70 ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
71 mutex_unlock(&dsim->lock);
72
73 return ret;
74}
75
76static int exynos_mipi_regulator_disable(struct mipi_dsim_device *dsim)
77{
78 int ret;
79
80 mutex_lock(&dsim->lock);
81 ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
82 mutex_unlock(&dsim->lock);
83
84 return ret;
85}
86
87/* update all register settings to MIPI DSI controller. */
88static void exynos_mipi_update_cfg(struct mipi_dsim_device *dsim)
89{
90 /*
91 * data from Display controller(FIMD) is not transferred in video mode
92 * but in case of command mode, all settings is not updated to
93 * registers.
94 */
95 exynos_mipi_dsi_stand_by(dsim, 0);
96
97 exynos_mipi_dsi_init_dsim(dsim);
98 exynos_mipi_dsi_init_link(dsim);
99
100 exynos_mipi_dsi_set_hs_enable(dsim);
101
102 /* set display timing. */
103 exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config);
104
105 exynos_mipi_dsi_init_interrupt(dsim);
106
107 /*
108 * data from Display controller(FIMD) is transferred in video mode
109 * but in case of command mode, all settings are updated to registers.
110 */
111 exynos_mipi_dsi_stand_by(dsim, 1);
112}
113
114static int exynos_mipi_dsi_early_blank_mode(struct mipi_dsim_device *dsim,
115 int power)
116{
117 struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
118 struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
119
120 switch (power) {
121 case FB_BLANK_POWERDOWN:
122 if (dsim->suspended)
123 return 0;
124
125 if (client_drv && client_drv->suspend)
126 client_drv->suspend(client_dev);
127
128 clk_disable(dsim->clock);
129
130 exynos_mipi_regulator_disable(dsim);
131
132 dsim->suspended = true;
133
134 break;
135 default:
136 break;
137 }
138
139 return 0;
140}
141
142static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)
143{
144 struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
145 struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
146
147 switch (power) {
148 case FB_BLANK_UNBLANK:
149 if (!dsim->suspended)
150 return 0;
151
152 /* lcd panel power on. */
153 if (client_drv && client_drv->power_on)
154 client_drv->power_on(client_dev, 1);
155
156 exynos_mipi_regulator_enable(dsim);
157
158 /* enable MIPI-DSI PHY. */
159 phy_power_on(dsim->phy);
160
161 clk_enable(dsim->clock);
162
163 exynos_mipi_update_cfg(dsim);
164
165 /* set lcd panel sequence commands. */
166 if (client_drv && client_drv->set_sequence)
167 client_drv->set_sequence(client_dev);
168
169 dsim->suspended = false;
170
171 break;
172 case FB_BLANK_NORMAL:
173 /* TODO. */
174 break;
175 default:
176 break;
177 }
178
179 return 0;
180}
181
182int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
183{
184 struct mipi_dsim_ddi *dsim_ddi;
185
186 if (!lcd_dev->name) {
187 pr_err("dsim_lcd_device name is NULL.\n");
188 return -EFAULT;
189 }
190
191 dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL);
192 if (!dsim_ddi) {
193 pr_err("failed to allocate dsim_ddi object.\n");
194 return -ENOMEM;
195 }
196
197 dsim_ddi->dsim_lcd_dev = lcd_dev;
198
199 mutex_lock(&mipi_dsim_lock);
200 list_add_tail(&dsim_ddi->list, &dsim_ddi_list);
201 mutex_unlock(&mipi_dsim_lock);
202
203 return 0;
204}
205
206static struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(
207 struct mipi_dsim_lcd_driver *lcd_drv)
208{
209 struct mipi_dsim_ddi *dsim_ddi, *next;
210 struct mipi_dsim_lcd_device *lcd_dev;
211
212 mutex_lock(&mipi_dsim_lock);
213
214 list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
215 if (!dsim_ddi)
216 goto out;
217
218 lcd_dev = dsim_ddi->dsim_lcd_dev;
219 if (!lcd_dev)
220 continue;
221
222 if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0) {
223 /**
224 * bus_id would be used to identify
225 * connected bus.
226 */
227 dsim_ddi->bus_id = lcd_dev->bus_id;
228 mutex_unlock(&mipi_dsim_lock);
229
230 return dsim_ddi;
231 }
232
233 list_del(&dsim_ddi->list);
234 kfree(dsim_ddi);
235 }
236
237out:
238 mutex_unlock(&mipi_dsim_lock);
239
240 return NULL;
241}
242
243int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
244{
245 struct mipi_dsim_ddi *dsim_ddi;
246
247 if (!lcd_drv->name) {
248 pr_err("dsim_lcd_driver name is NULL.\n");
249 return -EFAULT;
250 }
251
252 dsim_ddi = exynos_mipi_dsi_find_lcd_device(lcd_drv);
253 if (!dsim_ddi) {
254 pr_err("mipi_dsim_ddi object not found.\n");
255 return -EFAULT;
256 }
257
258 dsim_ddi->dsim_lcd_drv = lcd_drv;
259
260 pr_info("registered panel driver(%s) to mipi-dsi driver.\n",
261 lcd_drv->name);
262
263 return 0;
264
265}
266EXPORT_SYMBOL_GPL(exynos_mipi_dsi_register_lcd_driver);
267
268static struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(
269 struct mipi_dsim_device *dsim,
270 const char *name)
271{
272 struct mipi_dsim_ddi *dsim_ddi, *next;
273 struct mipi_dsim_lcd_driver *lcd_drv;
274 struct mipi_dsim_lcd_device *lcd_dev;
275 int ret;
276
277 mutex_lock(&dsim->lock);
278
279 list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
280 lcd_drv = dsim_ddi->dsim_lcd_drv;
281 lcd_dev = dsim_ddi->dsim_lcd_dev;
282 if (!lcd_drv || !lcd_dev ||
283 (dsim->id != dsim_ddi->bus_id))
284 continue;
285
286 dev_dbg(dsim->dev, "lcd_drv->id = %d, lcd_dev->id = %d\n",
287 lcd_drv->id, lcd_dev->id);
288 dev_dbg(dsim->dev, "lcd_dev->bus_id = %d, dsim->id = %d\n",
289 lcd_dev->bus_id, dsim->id);
290
291 if ((strcmp(lcd_drv->name, name) == 0)) {
292 lcd_dev->master = dsim;
293
294 lcd_dev->dev.parent = dsim->dev;
295 dev_set_name(&lcd_dev->dev, "%s", lcd_drv->name);
296
297 ret = device_register(&lcd_dev->dev);
298 if (ret < 0) {
299 dev_err(dsim->dev,
300 "can't register %s, status %d\n",
301 dev_name(&lcd_dev->dev), ret);
302 mutex_unlock(&dsim->lock);
303
304 return NULL;
305 }
306
307 dsim->dsim_lcd_dev = lcd_dev;
308 dsim->dsim_lcd_drv = lcd_drv;
309
310 mutex_unlock(&dsim->lock);
311
312 return dsim_ddi;
313 }
314 }
315
316 mutex_unlock(&dsim->lock);
317
318 return NULL;
319}
320
321/* define MIPI-DSI Master operations. */
322static struct mipi_dsim_master_ops master_ops = {
323 .cmd_read = exynos_mipi_dsi_rd_data,
324 .cmd_write = exynos_mipi_dsi_wr_data,
325 .get_dsim_frame_done = exynos_mipi_dsi_get_frame_done_status,
326 .clear_dsim_frame_done = exynos_mipi_dsi_clear_frame_done,
327 .set_early_blank_mode = exynos_mipi_dsi_early_blank_mode,
328 .set_blank_mode = exynos_mipi_dsi_blank_mode,
329};
330
331static int exynos_mipi_dsi_probe(struct platform_device *pdev)
332{
333 struct resource *res;
334 struct mipi_dsim_device *dsim;
335 struct mipi_dsim_config *dsim_config;
336 struct mipi_dsim_platform_data *dsim_pd;
337 struct mipi_dsim_ddi *dsim_ddi;
338 int ret = -EINVAL;
339
340 dsim = devm_kzalloc(&pdev->dev, sizeof(struct mipi_dsim_device),
341 GFP_KERNEL);
342 if (!dsim) {
343 dev_err(&pdev->dev, "failed to allocate dsim object.\n");
344 return -ENOMEM;
345 }
346
347 dsim->pd = to_dsim_plat(pdev);
348 dsim->dev = &pdev->dev;
349 dsim->id = pdev->id;
350
351 /* get mipi_dsim_platform_data. */
352 dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
353 if (dsim_pd == NULL) {
354 dev_err(&pdev->dev, "failed to get platform data for dsim.\n");
355 return -EINVAL;
356 }
357 /* get mipi_dsim_config. */
358 dsim_config = dsim_pd->dsim_config;
359 if (dsim_config == NULL) {
360 dev_err(&pdev->dev, "failed to get dsim config data.\n");
361 return -EINVAL;
362 }
363
364 dsim->dsim_config = dsim_config;
365 dsim->master_ops = &master_ops;
366
367 mutex_init(&dsim->lock);
368
369 ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(supplies),
370 supplies);
371 if (ret) {
372 dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
373 return ret;
374 }
375
376 dsim->phy = devm_phy_get(&pdev->dev, "dsim");
377 if (IS_ERR(dsim->phy))
378 return PTR_ERR(dsim->phy);
379
380 dsim->clock = devm_clk_get(&pdev->dev, "dsim0");
381 if (IS_ERR(dsim->clock)) {
382 dev_err(&pdev->dev, "failed to get dsim clock source\n");
383 return -ENODEV;
384 }
385
386 clk_enable(dsim->clock);
387
388 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
389
390 dsim->reg_base = devm_ioremap_resource(&pdev->dev, res);
391 if (IS_ERR(dsim->reg_base)) {
392 ret = PTR_ERR(dsim->reg_base);
393 goto error;
394 }
395
396 mutex_init(&dsim->lock);
397
398 /* bind lcd ddi matched with panel name. */
399 dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
400 if (!dsim_ddi) {
401 dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
402 ret = -EINVAL;
403 goto error;
404 }
405
406 ret = platform_get_irq(pdev, 0);
407 if (ret < 0) {
408 dev_err(&pdev->dev, "failed to request dsim irq resource\n");
409 goto error;
410 }
411 dsim->irq = ret;
412
413 init_completion(&dsim_wr_comp);
414 init_completion(&dsim_rd_comp);
415 platform_set_drvdata(pdev, dsim);
416
417 ret = devm_request_irq(&pdev->dev, dsim->irq,
418 exynos_mipi_dsi_interrupt_handler,
419 IRQF_SHARED, dev_name(&pdev->dev), dsim);
420 if (ret != 0) {
421 dev_err(&pdev->dev, "failed to request dsim irq\n");
422 ret = -EINVAL;
423 goto error;
424 }
425
426 /* enable interrupts */
427 exynos_mipi_dsi_init_interrupt(dsim);
428
429 /* initialize mipi-dsi client(lcd panel). */
430 if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->probe)
431 dsim_ddi->dsim_lcd_drv->probe(dsim_ddi->dsim_lcd_dev);
432
433 /* in case mipi-dsi has been enabled by bootloader */
434 if (dsim_pd->enabled) {
435 exynos_mipi_regulator_enable(dsim);
436 goto done;
437 }
438
439 /* lcd panel power on. */
440 if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->power_on)
441 dsim_ddi->dsim_lcd_drv->power_on(dsim_ddi->dsim_lcd_dev, 1);
442
443 exynos_mipi_regulator_enable(dsim);
444
445 /* enable MIPI-DSI PHY. */
446 phy_power_on(dsim->phy);
447
448 exynos_mipi_update_cfg(dsim);
449
450 /* set lcd panel sequence commands. */
451 if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->set_sequence)
452 dsim_ddi->dsim_lcd_drv->set_sequence(dsim_ddi->dsim_lcd_dev);
453
454 dsim->suspended = false;
455
456done:
457 platform_set_drvdata(pdev, dsim);
458
459 dev_dbg(&pdev->dev, "%s() completed successfully (%s mode)\n", __func__,
460 dsim_config->e_interface == DSIM_COMMAND ? "CPU" : "RGB");
461
462 return 0;
463
464error:
465 clk_disable(dsim->clock);
466 return ret;
467}
468
469static int exynos_mipi_dsi_remove(struct platform_device *pdev)
470{
471 struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
472 struct mipi_dsim_ddi *dsim_ddi, *next;
473 struct mipi_dsim_lcd_driver *dsim_lcd_drv;
474
475 clk_disable(dsim->clock);
476
477 list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
478 if (dsim_ddi) {
479 if (dsim->id != dsim_ddi->bus_id)
480 continue;
481
482 dsim_lcd_drv = dsim_ddi->dsim_lcd_drv;
483
484 if (dsim_lcd_drv->remove)
485 dsim_lcd_drv->remove(dsim_ddi->dsim_lcd_dev);
486
487 kfree(dsim_ddi);
488 }
489 }
490
491 return 0;
492}
493
494#ifdef CONFIG_PM_SLEEP
495static int exynos_mipi_dsi_suspend(struct device *dev)
496{
497 struct platform_device *pdev = to_platform_device(dev);
498 struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
499 struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
500 struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
501
502 disable_irq(dsim->irq);
503
504 if (dsim->suspended)
505 return 0;
506
507 if (client_drv && client_drv->suspend)
508 client_drv->suspend(client_dev);
509
510 /* disable MIPI-DSI PHY. */
511 phy_power_off(dsim->phy);
512
513 clk_disable(dsim->clock);
514
515 exynos_mipi_regulator_disable(dsim);
516
517 dsim->suspended = true;
518
519 return 0;
520}
521
522static int exynos_mipi_dsi_resume(struct device *dev)
523{
524 struct platform_device *pdev = to_platform_device(dev);
525 struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
526 struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
527 struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
528
529 enable_irq(dsim->irq);
530
531 if (!dsim->suspended)
532 return 0;
533
534 /* lcd panel power on. */
535 if (client_drv && client_drv->power_on)
536 client_drv->power_on(client_dev, 1);
537
538 exynos_mipi_regulator_enable(dsim);
539
540 /* enable MIPI-DSI PHY. */
541 phy_power_on(dsim->phy);
542
543 clk_enable(dsim->clock);
544
545 exynos_mipi_update_cfg(dsim);
546
547 /* set lcd panel sequence commands. */
548 if (client_drv && client_drv->set_sequence)
549 client_drv->set_sequence(client_dev);
550
551 dsim->suspended = false;
552
553 return 0;
554}
555#endif
556
557static const struct dev_pm_ops exynos_mipi_dsi_pm_ops = {
558 SET_SYSTEM_SLEEP_PM_OPS(exynos_mipi_dsi_suspend, exynos_mipi_dsi_resume)
559};
560
561static struct platform_driver exynos_mipi_dsi_driver = {
562 .probe = exynos_mipi_dsi_probe,
563 .remove = exynos_mipi_dsi_remove,
564 .driver = {
565 .name = "exynos-mipi-dsim",
566 .pm = &exynos_mipi_dsi_pm_ops,
567 },
568};
569
570module_platform_driver(exynos_mipi_dsi_driver);
571
572MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
573MODULE_DESCRIPTION("Samsung SoC MIPI-DSI driver");
574MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
deleted file mode 100644
index 2358a2fbbbcd..000000000000
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
+++ /dev/null
@@ -1,880 +0,0 @@
1/* linux/drivers/video/exynos/exynos_mipi_dsi_common.c
2 *
3 * Samsung SoC MIPI-DSI common driver.
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd
6 *
7 * InKi Dae, <inki.dae@samsung.com>
8 * Donghwa Lee, <dh09.lee@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/mutex.h>
19#include <linux/wait.h>
20#include <linux/fs.h>
21#include <linux/mm.h>
22#include <linux/fb.h>
23#include <linux/ctype.h>
24#include <linux/platform_device.h>
25#include <linux/io.h>
26#include <linux/memory.h>
27#include <linux/delay.h>
28#include <linux/irqreturn.h>
29#include <linux/kthread.h>
30
31#include <video/mipi_display.h>
32#include <video/exynos_mipi_dsim.h>
33
34#include "exynos_mipi_dsi_regs.h"
35#include "exynos_mipi_dsi_lowlevel.h"
36#include "exynos_mipi_dsi_common.h"
37
38#define MIPI_FIFO_TIMEOUT msecs_to_jiffies(250)
39#define MIPI_RX_FIFO_READ_DONE 0x30800002
40#define MIPI_MAX_RX_FIFO 20
41#define MHZ (1000 * 1000)
42#define FIN_HZ (24 * MHZ)
43
44#define DFIN_PLL_MIN_HZ (6 * MHZ)
45#define DFIN_PLL_MAX_HZ (12 * MHZ)
46
47#define DFVCO_MIN_HZ (500 * MHZ)
48#define DFVCO_MAX_HZ (1000 * MHZ)
49
50#define TRY_GET_FIFO_TIMEOUT (5000 * 2)
51#define TRY_FIFO_CLEAR (10)
52
53/* MIPI-DSIM status types. */
54enum {
55 DSIM_STATE_INIT, /* should be initialized. */
56 DSIM_STATE_STOP, /* CPU and LCDC are LP mode. */
57 DSIM_STATE_HSCLKEN, /* HS clock was enabled. */
58 DSIM_STATE_ULPS
59};
60
61/* define DSI lane types. */
62enum {
63 DSIM_LANE_CLOCK = (1 << 0),
64 DSIM_LANE_DATA0 = (1 << 1),
65 DSIM_LANE_DATA1 = (1 << 2),
66 DSIM_LANE_DATA2 = (1 << 3),
67 DSIM_LANE_DATA3 = (1 << 4)
68};
69
70static unsigned int dpll_table[15] = {
71 100, 120, 170, 220, 270,
72 320, 390, 450, 510, 560,
73 640, 690, 770, 870, 950
74};
75
76irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id)
77{
78 struct mipi_dsim_device *dsim = dev_id;
79 unsigned int intsrc, intmsk;
80
81 intsrc = exynos_mipi_dsi_read_interrupt(dsim);
82 intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim);
83 intmsk = ~intmsk & intsrc;
84
85 if (intsrc & INTMSK_RX_DONE) {
86 complete(&dsim_rd_comp);
87 dev_dbg(dsim->dev, "MIPI INTMSK_RX_DONE\n");
88 }
89 if (intsrc & INTMSK_FIFO_EMPTY) {
90 complete(&dsim_wr_comp);
91 dev_dbg(dsim->dev, "MIPI INTMSK_FIFO_EMPTY\n");
92 }
93
94 exynos_mipi_dsi_clear_interrupt(dsim, intmsk);
95
96 return IRQ_HANDLED;
97}
98
99/*
100 * write long packet to mipi dsi slave
101 * @dsim: mipi dsim device structure.
102 * @data0: packet data to send.
103 * @data1: size of packet data
104 */
105static void exynos_mipi_dsi_long_data_wr(struct mipi_dsim_device *dsim,
106 const unsigned char *data0, unsigned int data_size)
107{
108 unsigned int data_cnt = 0, payload = 0;
109
110 /* in case that data count is more then 4 */
111 for (data_cnt = 0; data_cnt < data_size; data_cnt += 4) {
112 /*
113 * after sending 4bytes per one time,
114 * send remainder data less then 4.
115 */
116 if ((data_size - data_cnt) < 4) {
117 if ((data_size - data_cnt) == 3) {
118 payload = data0[data_cnt] |
119 data0[data_cnt + 1] << 8 |
120 data0[data_cnt + 2] << 16;
121 dev_dbg(dsim->dev, "count = 3 payload = %x, %x %x %x\n",
122 payload, data0[data_cnt],
123 data0[data_cnt + 1],
124 data0[data_cnt + 2]);
125 } else if ((data_size - data_cnt) == 2) {
126 payload = data0[data_cnt] |
127 data0[data_cnt + 1] << 8;
128 dev_dbg(dsim->dev,
129 "count = 2 payload = %x, %x %x\n", payload,
130 data0[data_cnt],
131 data0[data_cnt + 1]);
132 } else if ((data_size - data_cnt) == 1) {
133 payload = data0[data_cnt];
134 }
135
136 exynos_mipi_dsi_wr_tx_data(dsim, payload);
137 /* send 4bytes per one time. */
138 } else {
139 payload = data0[data_cnt] |
140 data0[data_cnt + 1] << 8 |
141 data0[data_cnt + 2] << 16 |
142 data0[data_cnt + 3] << 24;
143
144 dev_dbg(dsim->dev,
145 "count = 4 payload = %x, %x %x %x %x\n",
146 payload, *(u8 *)(data0 + data_cnt),
147 data0[data_cnt + 1],
148 data0[data_cnt + 2],
149 data0[data_cnt + 3]);
150
151 exynos_mipi_dsi_wr_tx_data(dsim, payload);
152 }
153 }
154}
155
156int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
157 const unsigned char *data0, unsigned int data_size)
158{
159 unsigned int check_rx_ack = 0;
160
161 if (dsim->state == DSIM_STATE_ULPS) {
162 dev_err(dsim->dev, "state is ULPS.\n");
163
164 return -EINVAL;
165 }
166
167 /* FIXME!!! why does it need this delay? */
168 msleep(20);
169
170 mutex_lock(&dsim->lock);
171
172 switch (data_id) {
173 /* short packet types of packet types for command. */
174 case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
175 case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
176 case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
177 case MIPI_DSI_DCS_SHORT_WRITE:
178 case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
179 case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
180 exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0[0], data0[1]);
181 if (check_rx_ack) {
182 /* process response func should be implemented */
183 mutex_unlock(&dsim->lock);
184 return 0;
185 } else {
186 mutex_unlock(&dsim->lock);
187 return -EINVAL;
188 }
189
190 /* general command */
191 case MIPI_DSI_COLOR_MODE_OFF:
192 case MIPI_DSI_COLOR_MODE_ON:
193 case MIPI_DSI_SHUTDOWN_PERIPHERAL:
194 case MIPI_DSI_TURN_ON_PERIPHERAL:
195 exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0[0], data0[1]);
196 if (check_rx_ack) {
197 /* process response func should be implemented. */
198 mutex_unlock(&dsim->lock);
199 return 0;
200 } else {
201 mutex_unlock(&dsim->lock);
202 return -EINVAL;
203 }
204
205 /* packet types for video data */
206 case MIPI_DSI_V_SYNC_START:
207 case MIPI_DSI_V_SYNC_END:
208 case MIPI_DSI_H_SYNC_START:
209 case MIPI_DSI_H_SYNC_END:
210 case MIPI_DSI_END_OF_TRANSMISSION:
211 mutex_unlock(&dsim->lock);
212 return 0;
213
214 /* long packet type and null packet */
215 case MIPI_DSI_NULL_PACKET:
216 case MIPI_DSI_BLANKING_PACKET:
217 mutex_unlock(&dsim->lock);
218 return 0;
219 case MIPI_DSI_GENERIC_LONG_WRITE:
220 case MIPI_DSI_DCS_LONG_WRITE:
221 {
222 unsigned int size, payload = 0;
223 reinit_completion(&dsim_wr_comp);
224
225 size = data_size * 4;
226
227 /* if data count is less then 4, then send 3bytes data. */
228 if (data_size < 4) {
229 payload = data0[0] |
230 data0[1] << 8 |
231 data0[2] << 16;
232
233 exynos_mipi_dsi_wr_tx_data(dsim, payload);
234
235 dev_dbg(dsim->dev, "count = %d payload = %x,%x %x %x\n",
236 data_size, payload, data0[0],
237 data0[1], data0[2]);
238
239 /* in case that data count is more then 4 */
240 } else
241 exynos_mipi_dsi_long_data_wr(dsim, data0, data_size);
242
243 /* put data into header fifo */
244 exynos_mipi_dsi_wr_tx_header(dsim, data_id, data_size & 0xff,
245 (data_size & 0xff00) >> 8);
246
247 if (!wait_for_completion_interruptible_timeout(&dsim_wr_comp,
248 MIPI_FIFO_TIMEOUT)) {
249 dev_warn(dsim->dev, "command write timeout.\n");
250 mutex_unlock(&dsim->lock);
251 return -EAGAIN;
252 }
253
254 if (check_rx_ack) {
255 /* process response func should be implemented. */
256 mutex_unlock(&dsim->lock);
257 return 0;
258 } else {
259 mutex_unlock(&dsim->lock);
260 return -EINVAL;
261 }
262 }
263
264 /* packet typo for video data */
265 case MIPI_DSI_PACKED_PIXEL_STREAM_16:
266 case MIPI_DSI_PACKED_PIXEL_STREAM_18:
267 case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
268 case MIPI_DSI_PACKED_PIXEL_STREAM_24:
269 if (check_rx_ack) {
270 /* process response func should be implemented. */
271 mutex_unlock(&dsim->lock);
272 return 0;
273 } else {
274 mutex_unlock(&dsim->lock);
275 return -EINVAL;
276 }
277 default:
278 dev_warn(dsim->dev,
279 "data id %x is not supported current DSI spec.\n",
280 data_id);
281
282 mutex_unlock(&dsim->lock);
283 return -EINVAL;
284 }
285}
286
287static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim,
288 unsigned int req_size, unsigned int rx_data, u8 *rx_buf)
289{
290 unsigned int rcv_pkt, i, j;
291 u16 rxsize;
292
293 /* for long packet */
294 rxsize = (u16)((rx_data & 0x00ffff00) >> 8);
295 dev_dbg(dsim->dev, "mipi dsi rx size : %d\n", rxsize);
296 if (rxsize != req_size) {
297 dev_dbg(dsim->dev,
298 "received size mismatch received: %d, requested: %d\n",
299 rxsize, req_size);
300 goto err;
301 }
302
303 for (i = 0; i < (rxsize >> 2); i++) {
304 rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
305 dev_dbg(dsim->dev, "received pkt : %08x\n", rcv_pkt);
306 for (j = 0; j < 4; j++) {
307 rx_buf[(i * 4) + j] =
308 (u8)(rcv_pkt >> (j * 8)) & 0xff;
309 dev_dbg(dsim->dev, "received value : %02x\n",
310 (rcv_pkt >> (j * 8)) & 0xff);
311 }
312 }
313 if (rxsize % 4) {
314 rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
315 dev_dbg(dsim->dev, "received pkt : %08x\n", rcv_pkt);
316 for (j = 0; j < (rxsize % 4); j++) {
317 rx_buf[(i * 4) + j] =
318 (u8)(rcv_pkt >> (j * 8)) & 0xff;
319 dev_dbg(dsim->dev, "received value : %02x\n",
320 (rcv_pkt >> (j * 8)) & 0xff);
321 }
322 }
323
324 return rxsize;
325
326err:
327 return -EINVAL;
328}
329
330static unsigned int exynos_mipi_dsi_response_size(unsigned int req_size)
331{
332 switch (req_size) {
333 case 1:
334 return MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE;
335 case 2:
336 return MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE;
337 default:
338 return MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE;
339 }
340}
341
342int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,
343 unsigned int data0, unsigned int req_size, u8 *rx_buf)
344{
345 unsigned int rx_data, rcv_pkt, i;
346 u8 response = 0;
347 u16 rxsize;
348
349 if (dsim->state == DSIM_STATE_ULPS) {
350 dev_err(dsim->dev, "state is ULPS.\n");
351
352 return -EINVAL;
353 }
354
355 /* FIXME!!! */
356 msleep(20);
357
358 mutex_lock(&dsim->lock);
359 reinit_completion(&dsim_rd_comp);
360 exynos_mipi_dsi_rd_tx_header(dsim,
361 MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, req_size);
362
363 response = exynos_mipi_dsi_response_size(req_size);
364
365 switch (data_id) {
366 case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
367 case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
368 case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
369 case MIPI_DSI_DCS_READ:
370 exynos_mipi_dsi_rd_tx_header(dsim,
371 data_id, data0);
372 /* process response func should be implemented. */
373 break;
374 default:
375 dev_warn(dsim->dev,
376 "data id %x is not supported current DSI spec.\n",
377 data_id);
378
379 mutex_unlock(&dsim->lock);
380 return -EINVAL;
381 }
382
383 if (!wait_for_completion_interruptible_timeout(&dsim_rd_comp,
384 MIPI_FIFO_TIMEOUT)) {
385 pr_err("RX done interrupt timeout\n");
386 mutex_unlock(&dsim->lock);
387 return 0;
388 }
389
390 msleep(20);
391
392 rx_data = exynos_mipi_dsi_rd_rx_fifo(dsim);
393
394 if ((u8)(rx_data & 0xff) != response) {
395 printk(KERN_ERR
396 "mipi dsi wrong response rx_data : %x, response:%x\n",
397 rx_data, response);
398 goto clear_rx_fifo;
399 }
400
401 if (req_size <= 2) {
402 /* for short packet */
403 for (i = 0; i < req_size; i++)
404 rx_buf[i] = (rx_data >> (8 + (i * 8))) & 0xff;
405 rxsize = req_size;
406 } else {
407 /* for long packet */
408 rxsize = exynos_mipi_dsi_long_data_rd(dsim, req_size, rx_data,
409 rx_buf);
410 if (rxsize != req_size)
411 goto clear_rx_fifo;
412 }
413
414 rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
415
416 msleep(20);
417
418 if (rcv_pkt != MIPI_RX_FIFO_READ_DONE) {
419 dev_info(dsim->dev,
420 "Can't found RX FIFO READ DONE FLAG : %x\n", rcv_pkt);
421 goto clear_rx_fifo;
422 }
423
424 mutex_unlock(&dsim->lock);
425
426 return rxsize;
427
428clear_rx_fifo:
429 i = 0;
430 while (1) {
431 rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
432 if ((rcv_pkt == MIPI_RX_FIFO_READ_DONE)
433 || (i > MIPI_MAX_RX_FIFO))
434 break;
435 dev_dbg(dsim->dev,
436 "mipi dsi clear rx fifo : %08x\n", rcv_pkt);
437 i++;
438 }
439 dev_info(dsim->dev,
440 "mipi dsi rx done count : %d, rcv_pkt : %08x\n", i, rcv_pkt);
441
442 mutex_unlock(&dsim->lock);
443
444 return 0;
445}
446
447static int exynos_mipi_dsi_pll_on(struct mipi_dsim_device *dsim,
448 unsigned int enable)
449{
450 int sw_timeout;
451
452 if (enable) {
453 sw_timeout = 1000;
454
455 exynos_mipi_dsi_enable_pll(dsim, 1);
456 while (1) {
457 sw_timeout--;
458 if (exynos_mipi_dsi_is_pll_stable(dsim))
459 return 0;
460 if (sw_timeout == 0)
461 return -EINVAL;
462 }
463 } else
464 exynos_mipi_dsi_enable_pll(dsim, 0);
465
466 return 0;
467}
468
469static unsigned long exynos_mipi_dsi_change_pll(struct mipi_dsim_device *dsim,
470 unsigned int pre_divider, unsigned int main_divider,
471 unsigned int scaler)
472{
473 unsigned long dfin_pll, dfvco, dpll_out;
474 unsigned int i, freq_band = 0xf;
475
476 dfin_pll = (FIN_HZ / pre_divider);
477
478 /******************************************************
479 * Serial Clock(=ByteClk X 8) FreqBand[3:0] *
480 ******************************************************
481 * ~ 99.99 MHz 0000
482 * 100 ~ 119.99 MHz 0001
483 * 120 ~ 159.99 MHz 0010
484 * 160 ~ 199.99 MHz 0011
485 * 200 ~ 239.99 MHz 0100
486 * 140 ~ 319.99 MHz 0101
487 * 320 ~ 389.99 MHz 0110
488 * 390 ~ 449.99 MHz 0111
489 * 450 ~ 509.99 MHz 1000
490 * 510 ~ 559.99 MHz 1001
491 * 560 ~ 639.99 MHz 1010
492 * 640 ~ 689.99 MHz 1011
493 * 690 ~ 769.99 MHz 1100
494 * 770 ~ 869.99 MHz 1101
495 * 870 ~ 949.99 MHz 1110
496 * 950 ~ 1000 MHz 1111
497 ******************************************************/
498 if (dfin_pll < DFIN_PLL_MIN_HZ || dfin_pll > DFIN_PLL_MAX_HZ) {
499 dev_warn(dsim->dev, "fin_pll range should be 6MHz ~ 12MHz\n");
500 exynos_mipi_dsi_enable_afc(dsim, 0, 0);
501 } else {
502 if (dfin_pll < 7 * MHZ)
503 exynos_mipi_dsi_enable_afc(dsim, 1, 0x1);
504 else if (dfin_pll < 8 * MHZ)
505 exynos_mipi_dsi_enable_afc(dsim, 1, 0x0);
506 else if (dfin_pll < 9 * MHZ)
507 exynos_mipi_dsi_enable_afc(dsim, 1, 0x3);
508 else if (dfin_pll < 10 * MHZ)
509 exynos_mipi_dsi_enable_afc(dsim, 1, 0x2);
510 else if (dfin_pll < 11 * MHZ)
511 exynos_mipi_dsi_enable_afc(dsim, 1, 0x5);
512 else
513 exynos_mipi_dsi_enable_afc(dsim, 1, 0x4);
514 }
515
516 dfvco = dfin_pll * main_divider;
517 dev_dbg(dsim->dev, "dfvco = %lu, dfin_pll = %lu, main_divider = %d\n",
518 dfvco, dfin_pll, main_divider);
519 if (dfvco < DFVCO_MIN_HZ || dfvco > DFVCO_MAX_HZ)
520 dev_warn(dsim->dev, "fvco range should be 500MHz ~ 1000MHz\n");
521
522 dpll_out = dfvco / (1 << scaler);
523 dev_dbg(dsim->dev, "dpll_out = %lu, dfvco = %lu, scaler = %d\n",
524 dpll_out, dfvco, scaler);
525
526 for (i = 0; i < ARRAY_SIZE(dpll_table); i++) {
527 if (dpll_out < dpll_table[i] * MHZ) {
528 freq_band = i;
529 break;
530 }
531 }
532
533 dev_dbg(dsim->dev, "freq_band = %d\n", freq_band);
534
535 exynos_mipi_dsi_pll_freq(dsim, pre_divider, main_divider, scaler);
536
537 exynos_mipi_dsi_hs_zero_ctrl(dsim, 0);
538 exynos_mipi_dsi_prep_ctrl(dsim, 0);
539
540 /* Freq Band */
541 exynos_mipi_dsi_pll_freq_band(dsim, freq_band);
542
543 /* Stable time */
544 exynos_mipi_dsi_pll_stable_time(dsim, dsim->dsim_config->pll_stable_time);
545
546 /* Enable PLL */
547 dev_dbg(dsim->dev, "FOUT of mipi dphy pll is %luMHz\n",
548 (dpll_out / MHZ));
549
550 return dpll_out;
551}
552
553static int exynos_mipi_dsi_set_clock(struct mipi_dsim_device *dsim,
554 unsigned int byte_clk_sel, unsigned int enable)
555{
556 unsigned int esc_div;
557 unsigned long esc_clk_error_rate;
558 unsigned long hs_clk = 0, byte_clk = 0, escape_clk = 0;
559
560 if (enable) {
561 dsim->e_clk_src = byte_clk_sel;
562
563 /* Escape mode clock and byte clock source */
564 exynos_mipi_dsi_set_byte_clock_src(dsim, byte_clk_sel);
565
566 /* DPHY, DSIM Link : D-PHY clock out */
567 if (byte_clk_sel == DSIM_PLL_OUT_DIV8) {
568 hs_clk = exynos_mipi_dsi_change_pll(dsim,
569 dsim->dsim_config->p, dsim->dsim_config->m,
570 dsim->dsim_config->s);
571 if (hs_clk == 0) {
572 dev_err(dsim->dev,
573 "failed to get hs clock.\n");
574 return -EINVAL;
575 }
576
577 byte_clk = hs_clk / 8;
578 exynos_mipi_dsi_enable_pll_bypass(dsim, 0);
579 exynos_mipi_dsi_pll_on(dsim, 1);
580 /* DPHY : D-PHY clock out, DSIM link : external clock out */
581 } else if (byte_clk_sel == DSIM_EXT_CLK_DIV8) {
582 dev_warn(dsim->dev, "this project is not support\n");
583 dev_warn(dsim->dev,
584 "external clock source for MIPI DSIM.\n");
585 } else if (byte_clk_sel == DSIM_EXT_CLK_BYPASS) {
586 dev_warn(dsim->dev, "this project is not support\n");
587 dev_warn(dsim->dev,
588 "external clock source for MIPI DSIM\n");
589 }
590
591 /* escape clock divider */
592 esc_div = byte_clk / (dsim->dsim_config->esc_clk);
593 dev_dbg(dsim->dev,
594 "esc_div = %d, byte_clk = %lu, esc_clk = %lu\n",
595 esc_div, byte_clk, dsim->dsim_config->esc_clk);
596 if ((byte_clk / esc_div) >= (20 * MHZ) ||
597 (byte_clk / esc_div) >
598 dsim->dsim_config->esc_clk)
599 esc_div += 1;
600
601 escape_clk = byte_clk / esc_div;
602 dev_dbg(dsim->dev,
603 "escape_clk = %lu, byte_clk = %lu, esc_div = %d\n",
604 escape_clk, byte_clk, esc_div);
605
606 /* enable escape clock. */
607 exynos_mipi_dsi_enable_byte_clock(dsim, 1);
608
609 /* enable byte clk and escape clock */
610 exynos_mipi_dsi_set_esc_clk_prs(dsim, 1, esc_div);
611 /* escape clock on lane */
612 exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
613 (DSIM_LANE_CLOCK | dsim->data_lane), 1);
614
615 dev_dbg(dsim->dev, "byte clock is %luMHz\n",
616 (byte_clk / MHZ));
617 dev_dbg(dsim->dev, "escape clock that user's need is %lu\n",
618 (dsim->dsim_config->esc_clk / MHZ));
619 dev_dbg(dsim->dev, "escape clock divider is %x\n", esc_div);
620 dev_dbg(dsim->dev, "escape clock is %luMHz\n",
621 ((byte_clk / esc_div) / MHZ));
622
623 if ((byte_clk / esc_div) > escape_clk) {
624 esc_clk_error_rate = escape_clk /
625 (byte_clk / esc_div);
626 dev_warn(dsim->dev, "error rate is %lu over.\n",
627 (esc_clk_error_rate / 100));
628 } else if ((byte_clk / esc_div) < (escape_clk)) {
629 esc_clk_error_rate = (byte_clk / esc_div) /
630 escape_clk;
631 dev_warn(dsim->dev, "error rate is %lu under.\n",
632 (esc_clk_error_rate / 100));
633 }
634 } else {
635 exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
636 (DSIM_LANE_CLOCK | dsim->data_lane), 0);
637 exynos_mipi_dsi_set_esc_clk_prs(dsim, 0, 0);
638
639 /* disable escape clock. */
640 exynos_mipi_dsi_enable_byte_clock(dsim, 0);
641
642 if (byte_clk_sel == DSIM_PLL_OUT_DIV8)
643 exynos_mipi_dsi_pll_on(dsim, 0);
644 }
645
646 return 0;
647}
648
649int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim)
650{
651 dsim->state = DSIM_STATE_INIT;
652
653 switch (dsim->dsim_config->e_no_data_lane) {
654 case DSIM_DATA_LANE_1:
655 dsim->data_lane = DSIM_LANE_DATA0;
656 break;
657 case DSIM_DATA_LANE_2:
658 dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
659 break;
660 case DSIM_DATA_LANE_3:
661 dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
662 DSIM_LANE_DATA2;
663 break;
664 case DSIM_DATA_LANE_4:
665 dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
666 DSIM_LANE_DATA2 | DSIM_LANE_DATA3;
667 break;
668 default:
669 dev_info(dsim->dev, "data lane is invalid.\n");
670 return -EINVAL;
671 }
672
673 exynos_mipi_dsi_sw_reset(dsim);
674 exynos_mipi_dsi_func_reset(dsim);
675
676 exynos_mipi_dsi_dp_dn_swap(dsim, 0);
677
678 return 0;
679}
680
681void exynos_mipi_dsi_init_interrupt(struct mipi_dsim_device *dsim)
682{
683 unsigned int src = 0;
684
685 src = (INTSRC_SFR_FIFO_EMPTY | INTSRC_RX_DATA_DONE);
686 exynos_mipi_dsi_set_interrupt(dsim, src, 1);
687
688 src = 0;
689 src = ~(INTMSK_RX_DONE | INTMSK_FIFO_EMPTY);
690 exynos_mipi_dsi_set_interrupt_mask(dsim, src, 1);
691}
692
693int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
694 unsigned int enable)
695{
696 /* enable only frame done interrupt */
697 exynos_mipi_dsi_set_interrupt_mask(dsim, INTMSK_FRAME_DONE, enable);
698
699 return 0;
700}
701
702void exynos_mipi_dsi_stand_by(struct mipi_dsim_device *dsim,
703 unsigned int enable)
704{
705
706 /* consider Main display and Sub display. */
707
708 exynos_mipi_dsi_set_main_stand_by(dsim, enable);
709}
710
711int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
712 struct mipi_dsim_config *dsim_config)
713{
714 struct mipi_dsim_platform_data *dsim_pd;
715 struct fb_videomode *timing;
716
717 dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
718 timing = (struct fb_videomode *)dsim_pd->lcd_panel_info;
719
720 /* in case of VIDEO MODE (RGB INTERFACE), it sets polarities. */
721 if (dsim_config->e_interface == (u32) DSIM_VIDEO) {
722 if (dsim_config->auto_vertical_cnt == 0) {
723 exynos_mipi_dsi_set_main_disp_vporch(dsim,
724 dsim_config->cmd_allow,
725 timing->lower_margin,
726 timing->upper_margin);
727 exynos_mipi_dsi_set_main_disp_hporch(dsim,
728 timing->right_margin,
729 timing->left_margin);
730 exynos_mipi_dsi_set_main_disp_sync_area(dsim,
731 timing->vsync_len,
732 timing->hsync_len);
733 }
734 }
735
736 exynos_mipi_dsi_set_main_disp_resol(dsim, timing->xres,
737 timing->yres);
738
739 exynos_mipi_dsi_display_config(dsim, dsim_config);
740
741 dev_info(dsim->dev, "lcd panel ==> width = %d, height = %d\n",
742 timing->xres, timing->yres);
743
744 return 0;
745}
746
747int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim)
748{
749 unsigned int time_out = 100;
750
751 switch (dsim->state) {
752 case DSIM_STATE_INIT:
753 exynos_mipi_dsi_init_fifo_pointer(dsim, 0x1f);
754
755 /* dsi configuration */
756 exynos_mipi_dsi_init_config(dsim);
757 exynos_mipi_dsi_enable_lane(dsim, DSIM_LANE_CLOCK, 1);
758 exynos_mipi_dsi_enable_lane(dsim, dsim->data_lane, 1);
759
760 /* set clock configuration */
761 exynos_mipi_dsi_set_clock(dsim, dsim->dsim_config->e_byte_clk, 1);
762
763 /* check clock and data lane state are stop state */
764 while (!(exynos_mipi_dsi_is_lane_state(dsim))) {
765 time_out--;
766 if (time_out == 0) {
767 dev_err(dsim->dev,
768 "DSI Master is not stop state.\n");
769 dev_err(dsim->dev,
770 "Check initialization process\n");
771
772 return -EINVAL;
773 }
774 }
775 if (time_out != 0) {
776 dev_info(dsim->dev,
777 "DSI Master driver has been completed.\n");
778 dev_info(dsim->dev, "DSI Master state is stop state\n");
779 }
780
781 dsim->state = DSIM_STATE_STOP;
782
783 /* BTA sequence counters */
784 exynos_mipi_dsi_set_stop_state_counter(dsim,
785 dsim->dsim_config->stop_holding_cnt);
786 exynos_mipi_dsi_set_bta_timeout(dsim,
787 dsim->dsim_config->bta_timeout);
788 exynos_mipi_dsi_set_lpdr_timeout(dsim,
789 dsim->dsim_config->rx_timeout);
790
791 return 0;
792 default:
793 dev_info(dsim->dev, "DSI Master is already init.\n");
794 return 0;
795 }
796
797 return 0;
798}
799
800int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim)
801{
802 if (dsim->state != DSIM_STATE_STOP) {
803 dev_warn(dsim->dev, "DSIM is not in stop state.\n");
804 return 0;
805 }
806
807 if (dsim->e_clk_src == DSIM_EXT_CLK_BYPASS) {
808 dev_warn(dsim->dev, "clock source is external bypass.\n");
809 return 0;
810 }
811
812 dsim->state = DSIM_STATE_HSCLKEN;
813
814 /* set LCDC and CPU transfer mode to HS. */
815 exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
816 exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
817 exynos_mipi_dsi_enable_hs_clock(dsim, 1);
818
819 return 0;
820}
821
822int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
823 unsigned int mode)
824{
825 if (mode) {
826 if (dsim->state != DSIM_STATE_HSCLKEN) {
827 dev_err(dsim->dev, "HS Clock lane is not enabled.\n");
828 return -EINVAL;
829 }
830
831 exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
832 } else {
833 if (dsim->state == DSIM_STATE_INIT || dsim->state ==
834 DSIM_STATE_ULPS) {
835 dev_err(dsim->dev,
836 "DSI Master is not STOP or HSDT state.\n");
837 return -EINVAL;
838 }
839
840 exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
841 }
842
843 return 0;
844}
845
846int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
847{
848 return _exynos_mipi_dsi_get_frame_done_status(dsim);
849}
850
851int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
852{
853 _exynos_mipi_dsi_clear_frame_done(dsim);
854
855 return 0;
856}
857
858int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
859 unsigned int val)
860{
861 int try = TRY_FIFO_CLEAR;
862
863 exynos_mipi_dsi_sw_reset_release(dsim);
864 exynos_mipi_dsi_func_reset(dsim);
865
866 do {
867 if (exynos_mipi_dsi_get_sw_reset_release(dsim)) {
868 exynos_mipi_dsi_init_interrupt(dsim);
869 dev_dbg(dsim->dev, "reset release done.\n");
870 return 0;
871 }
872 } while (--try);
873
874 dev_err(dsim->dev, "failed to clear dsim fifo.\n");
875 return -EAGAIN;
876}
877
878MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
879MODULE_DESCRIPTION("Samsung SoC MIPI-DSI common driver");
880MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h
deleted file mode 100644
index 412552274df3..000000000000
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h
+++ /dev/null
@@ -1,46 +0,0 @@
1/* linux/drivers/video/exynos_mipi_dsi_common.h
2 *
3 * Header file for Samsung SoC MIPI-DSI common driver.
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd
6 *
7 * InKi Dae <inki.dae@samsung.com>
8 * Donghwa Lee <dh09.lee@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef _EXYNOS_MIPI_DSI_COMMON_H
16#define _EXYNOS_MIPI_DSI_COMMON_H
17
18static DECLARE_COMPLETION(dsim_rd_comp);
19static DECLARE_COMPLETION(dsim_wr_comp);
20
21int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
22 const unsigned char *data0, unsigned int data_size);
23int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,
24 unsigned int data0, unsigned int req_size, u8 *rx_buf);
25irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id);
26void exynos_mipi_dsi_init_interrupt(struct mipi_dsim_device *dsim);
27int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim);
28void exynos_mipi_dsi_stand_by(struct mipi_dsim_device *dsim,
29 unsigned int enable);
30int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
31 struct mipi_dsim_config *dsim_info);
32int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim);
33int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim);
34int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
35 unsigned int mode);
36int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
37 unsigned int enable);
38int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
39int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
40
41extern struct fb_info *registered_fb[FB_MAX] __read_mostly;
42
43int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
44 unsigned int val);
45
46#endif /* _EXYNOS_MIPI_DSI_COMMON_H */
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c
deleted file mode 100644
index c148d06540c1..000000000000
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c
+++ /dev/null
@@ -1,618 +0,0 @@
1/* linux/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
2 *
3 * Samsung SoC MIPI-DSI lowlevel driver.
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd
6 *
7 * InKi Dae, <inki.dae@samsung.com>
8 * Donghwa Lee, <dh09.lee@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/mutex.h>
19#include <linux/wait.h>
20#include <linux/delay.h>
21#include <linux/fs.h>
22#include <linux/mm.h>
23#include <linux/ctype.h>
24#include <linux/platform_device.h>
25#include <linux/io.h>
26
27#include <video/exynos_mipi_dsim.h>
28
29#include "exynos_mipi_dsi_regs.h"
30#include "exynos_mipi_dsi_lowlevel.h"
31
32void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim)
33{
34 unsigned int reg;
35
36 reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
37
38 reg |= DSIM_FUNCRST;
39
40 writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
41}
42
43void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim)
44{
45 unsigned int reg;
46
47 reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
48
49 reg |= DSIM_SWRST;
50
51 writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
52}
53
54void exynos_mipi_dsi_sw_reset_release(struct mipi_dsim_device *dsim)
55{
56 unsigned int reg;
57
58 reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
59
60 reg |= INTSRC_SW_RST_RELEASE;
61
62 writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
63}
64
65int exynos_mipi_dsi_get_sw_reset_release(struct mipi_dsim_device *dsim)
66{
67 return (readl(dsim->reg_base + EXYNOS_DSIM_INTSRC)) &
68 INTSRC_SW_RST_RELEASE;
69}
70
71unsigned int exynos_mipi_dsi_read_interrupt_mask(struct mipi_dsim_device *dsim)
72{
73 unsigned int reg;
74
75 reg = readl(dsim->reg_base + EXYNOS_DSIM_INTMSK);
76
77 return reg;
78}
79
80void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
81 unsigned int mode, unsigned int mask)
82{
83 unsigned int reg = 0;
84
85 if (mask)
86 reg |= mode;
87 else
88 reg &= ~mode;
89
90 writel(reg, dsim->reg_base + EXYNOS_DSIM_INTMSK);
91}
92
93void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
94 unsigned int cfg)
95{
96 unsigned int reg;
97
98 reg = readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
99
100 writel(reg & ~(cfg), dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
101 mdelay(10);
102 reg |= cfg;
103
104 writel(reg, dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
105}
106
107/*
108 * this function set PLL P, M and S value in D-PHY
109 */
110void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
111 unsigned int value)
112{
113 writel(DSIM_AFC_CTL(value), dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
114}
115
116void exynos_mipi_dsi_set_main_stand_by(struct mipi_dsim_device *dsim,
117 unsigned int enable)
118{
119 unsigned int reg;
120
121 reg = readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL);
122
123 reg &= ~DSIM_MAIN_STAND_BY;
124
125 if (enable)
126 reg |= DSIM_MAIN_STAND_BY;
127
128 writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
129}
130
131void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
132 unsigned int width_resol, unsigned int height_resol)
133{
134 unsigned int reg;
135
136 /* standby should be set after configuration so set to not ready*/
137 reg = (readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL)) &
138 ~(DSIM_MAIN_STAND_BY);
139 writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
140
141 reg &= ~((0x7ff << 16) | (0x7ff << 0));
142 reg |= DSIM_MAIN_VRESOL(height_resol) | DSIM_MAIN_HRESOL(width_resol);
143
144 reg |= DSIM_MAIN_STAND_BY;
145 writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
146}
147
148void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
149 unsigned int cmd_allow, unsigned int vfront, unsigned int vback)
150{
151 unsigned int reg;
152
153 reg = (readl(dsim->reg_base + EXYNOS_DSIM_MVPORCH)) &
154 ~((DSIM_CMD_ALLOW_MASK) | (DSIM_STABLE_VFP_MASK) |
155 (DSIM_MAIN_VBP_MASK));
156
157 reg |= (DSIM_CMD_ALLOW_SHIFT(cmd_allow & 0xf) |
158 DSIM_STABLE_VFP_SHIFT(vfront & 0x7ff) |
159 DSIM_MAIN_VBP_SHIFT(vback & 0x7ff));
160
161 writel(reg, dsim->reg_base + EXYNOS_DSIM_MVPORCH);
162}
163
164void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
165 unsigned int front, unsigned int back)
166{
167 unsigned int reg;
168
169 reg = (readl(dsim->reg_base + EXYNOS_DSIM_MHPORCH)) &
170 ~((DSIM_MAIN_HFP_MASK) | (DSIM_MAIN_HBP_MASK));
171
172 reg |= DSIM_MAIN_HFP_SHIFT(front) | DSIM_MAIN_HBP_SHIFT(back);
173
174 writel(reg, dsim->reg_base + EXYNOS_DSIM_MHPORCH);
175}
176
177void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
178 unsigned int vert, unsigned int hori)
179{
180 unsigned int reg;
181
182 reg = (readl(dsim->reg_base + EXYNOS_DSIM_MSYNC)) &
183 ~((DSIM_MAIN_VSA_MASK) | (DSIM_MAIN_HSA_MASK));
184
185 reg |= (DSIM_MAIN_VSA_SHIFT(vert & 0x3ff) |
186 DSIM_MAIN_HSA_SHIFT(hori));
187
188 writel(reg, dsim->reg_base + EXYNOS_DSIM_MSYNC);
189}
190
191void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
192 unsigned int vert, unsigned int hori)
193{
194 unsigned int reg;
195
196 reg = (readl(dsim->reg_base + EXYNOS_DSIM_SDRESOL)) &
197 ~(DSIM_SUB_STANDY_MASK);
198
199 writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
200
201 reg &= ~(DSIM_SUB_VRESOL_MASK) | ~(DSIM_SUB_HRESOL_MASK);
202 reg |= (DSIM_SUB_VRESOL_SHIFT(vert & 0x7ff) |
203 DSIM_SUB_HRESOL_SHIFT(hori & 0x7ff));
204 writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
205
206 reg |= DSIM_SUB_STANDY_SHIFT(1);
207 writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
208}
209
210void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim)
211{
212 struct mipi_dsim_config *dsim_config = dsim->dsim_config;
213
214 unsigned int cfg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
215 ~((1 << 28) | (0x1f << 20) | (0x3 << 5));
216
217 cfg = ((DSIM_AUTO_FLUSH(dsim_config->auto_flush)) |
218 (DSIM_EOT_DISABLE(dsim_config->eot_disable)) |
219 (DSIM_AUTO_MODE_SHIFT(dsim_config->auto_vertical_cnt)) |
220 (DSIM_HSE_MODE_SHIFT(dsim_config->hse)) |
221 (DSIM_HFP_MODE_SHIFT(dsim_config->hfp)) |
222 (DSIM_HBP_MODE_SHIFT(dsim_config->hbp)) |
223 (DSIM_HSA_MODE_SHIFT(dsim_config->hsa)) |
224 (DSIM_NUM_OF_DATALANE_SHIFT(dsim_config->e_no_data_lane)));
225
226 writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
227}
228
229void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
230 struct mipi_dsim_config *dsim_config)
231{
232 u32 reg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
233 ~((0x3 << 26) | (1 << 25) | (0x3 << 18) | (0x7 << 12) |
234 (0x3 << 16) | (0x7 << 8));
235
236 if (dsim_config->e_interface == DSIM_VIDEO)
237 reg |= (1 << 25);
238 else if (dsim_config->e_interface == DSIM_COMMAND)
239 reg &= ~(1 << 25);
240 else {
241 dev_err(dsim->dev, "unknown lcd type.\n");
242 return;
243 }
244
245 /* main lcd */
246 reg |= ((u8) (dsim_config->e_burst_mode) & 0x3) << 26 |
247 ((u8) (dsim_config->e_virtual_ch) & 0x3) << 18 |
248 ((u8) (dsim_config->e_pixel_format) & 0x7) << 12;
249
250 writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
251}
252
253void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim, unsigned int lane,
254 unsigned int enable)
255{
256 unsigned int reg;
257
258 reg = readl(dsim->reg_base + EXYNOS_DSIM_CONFIG);
259
260 if (enable)
261 reg |= DSIM_LANE_ENx(lane);
262 else
263 reg &= ~DSIM_LANE_ENx(lane);
264
265 writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
266}
267
268
269void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
270 unsigned int count)
271{
272 unsigned int cfg;
273
274 /* get the data lane number. */
275 cfg = DSIM_NUM_OF_DATALANE_SHIFT(count);
276
277 writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
278}
279
280void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim, unsigned int enable,
281 unsigned int afc_code)
282{
283 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
284
285 if (enable) {
286 reg |= (1 << 14);
287 reg &= ~(0x7 << 5);
288 reg |= (afc_code & 0x7) << 5;
289 } else
290 reg &= ~(1 << 14);
291
292 writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
293}
294
295void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
296 unsigned int enable)
297{
298 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
299 ~(DSIM_PLL_BYPASS_SHIFT(0x1));
300
301 reg |= DSIM_PLL_BYPASS_SHIFT(enable);
302
303 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
304}
305
306void exynos_mipi_dsi_set_pll_pms(struct mipi_dsim_device *dsim, unsigned int p,
307 unsigned int m, unsigned int s)
308{
309 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
310
311 reg |= ((p & 0x3f) << 13) | ((m & 0x1ff) << 4) | ((s & 0x7) << 1);
312
313 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
314}
315
316void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
317 unsigned int freq_band)
318{
319 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
320 ~(DSIM_FREQ_BAND_SHIFT(0x1f));
321
322 reg |= DSIM_FREQ_BAND_SHIFT(freq_band & 0x1f);
323
324 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
325}
326
327void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
328 unsigned int pre_divider, unsigned int main_divider,
329 unsigned int scaler)
330{
331 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
332 ~(0x7ffff << 1);
333
334 reg |= (pre_divider & 0x3f) << 13 | (main_divider & 0x1ff) << 4 |
335 (scaler & 0x7) << 1;
336
337 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
338}
339
340void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
341 unsigned int lock_time)
342{
343 writel(lock_time, dsim->reg_base + EXYNOS_DSIM_PLLTMR);
344}
345
346void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim, unsigned int enable)
347{
348 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
349 ~(DSIM_PLL_EN_SHIFT(0x1));
350
351 reg |= DSIM_PLL_EN_SHIFT(enable & 0x1);
352
353 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
354}
355
356void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
357 unsigned int src)
358{
359 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
360 ~(DSIM_BYTE_CLK_SRC_SHIFT(0x3));
361
362 reg |= (DSIM_BYTE_CLK_SRC_SHIFT(src));
363
364 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
365}
366
367void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
368 unsigned int enable)
369{
370 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
371 ~(DSIM_BYTE_CLKEN_SHIFT(0x1));
372
373 reg |= DSIM_BYTE_CLKEN_SHIFT(enable);
374
375 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
376}
377
378void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
379 unsigned int enable, unsigned int prs_val)
380{
381 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
382 ~(DSIM_ESC_CLKEN_SHIFT(0x1) | 0xffff);
383
384 reg |= DSIM_ESC_CLKEN_SHIFT(enable);
385 if (enable)
386 reg |= prs_val;
387
388 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
389}
390
391void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
392 unsigned int lane_sel, unsigned int enable)
393{
394 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
395
396 if (enable)
397 reg |= DSIM_LANE_ESC_CLKEN(lane_sel);
398 else
399
400 reg &= ~DSIM_LANE_ESC_CLKEN(lane_sel);
401
402 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
403}
404
405void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
406 unsigned int enable)
407{
408 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
409 ~(DSIM_FORCE_STOP_STATE_SHIFT(0x1));
410
411 reg |= (DSIM_FORCE_STOP_STATE_SHIFT(enable & 0x1));
412
413 writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
414}
415
416unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim)
417{
418 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
419
420 /**
421 * check clock and data lane states.
422 * if MIPI-DSI controller was enabled at bootloader then
423 * TX_READY_HS_CLK is enabled otherwise STOP_STATE_CLK.
424 * so it should be checked for two case.
425 */
426 if ((reg & DSIM_STOP_STATE_DAT(0xf)) &&
427 ((reg & DSIM_STOP_STATE_CLK) ||
428 (reg & DSIM_TX_READY_HS_CLK)))
429 return 1;
430
431 return 0;
432}
433
434void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
435 unsigned int cnt_val)
436{
437 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
438 ~(DSIM_STOP_STATE_CNT_SHIFT(0x7ff));
439
440 reg |= (DSIM_STOP_STATE_CNT_SHIFT(cnt_val & 0x7ff));
441
442 writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
443}
444
445void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
446 unsigned int timeout)
447{
448 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
449 ~(DSIM_BTA_TOUT_SHIFT(0xff));
450
451 reg |= (DSIM_BTA_TOUT_SHIFT(timeout));
452
453 writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
454}
455
456void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
457 unsigned int timeout)
458{
459 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
460 ~(DSIM_LPDR_TOUT_SHIFT(0xffff));
461
462 reg |= (DSIM_LPDR_TOUT_SHIFT(timeout));
463
464 writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
465}
466
467void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
468 unsigned int lp)
469{
470 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
471
472 reg &= ~DSIM_CMD_LPDT_LP;
473
474 if (lp)
475 reg |= DSIM_CMD_LPDT_LP;
476
477 writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
478}
479
480void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
481 unsigned int lp)
482{
483 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
484
485 reg &= ~DSIM_TX_LPDT_LP;
486
487 if (lp)
488 reg |= DSIM_TX_LPDT_LP;
489
490 writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
491}
492
493void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
494 unsigned int enable)
495{
496 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
497 ~(DSIM_TX_REQUEST_HSCLK_SHIFT(0x1));
498
499 reg |= DSIM_TX_REQUEST_HSCLK_SHIFT(enable);
500
501 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
502}
503
504void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
505 unsigned int swap_en)
506{
507 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
508
509 reg &= ~(0x3 << 0);
510 reg |= (swap_en & 0x3) << 0;
511
512 writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
513}
514
515void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
516 unsigned int hs_zero)
517{
518 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
519 ~(0xf << 28);
520
521 reg |= ((hs_zero & 0xf) << 28);
522
523 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
524}
525
526void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep)
527{
528 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
529 ~(0x7 << 20);
530
531 reg |= ((prep & 0x7) << 20);
532
533 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
534}
535
536unsigned int exynos_mipi_dsi_read_interrupt(struct mipi_dsim_device *dsim)
537{
538 return readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
539}
540
541void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim,
542 unsigned int src)
543{
544 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
545
546 reg |= src;
547
548 writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
549}
550
551void exynos_mipi_dsi_set_interrupt(struct mipi_dsim_device *dsim,
552 unsigned int src, unsigned int enable)
553{
554 unsigned int reg = 0;
555
556 if (enable)
557 reg |= src;
558 else
559 reg &= ~src;
560
561 writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
562}
563
564unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim)
565{
566 unsigned int reg;
567
568 reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
569
570 return reg & (1 << 31) ? 1 : 0;
571}
572
573unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim)
574{
575 return readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL) & ~(0x1f);
576}
577
578void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim,
579 unsigned int di, unsigned int data0, unsigned int data1)
580{
581 unsigned int reg = (data1 << 16) | (data0 << 8) | ((di & 0x3f) << 0);
582
583 writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
584}
585
586void exynos_mipi_dsi_rd_tx_header(struct mipi_dsim_device *dsim,
587 unsigned int di, unsigned int data0)
588{
589 unsigned int reg = (data0 << 8) | (di << 0);
590
591 writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
592}
593
594unsigned int exynos_mipi_dsi_rd_rx_fifo(struct mipi_dsim_device *dsim)
595{
596 return readl(dsim->reg_base + EXYNOS_DSIM_RXFIFO);
597}
598
599unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
600{
601 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
602
603 return (reg & INTSRC_FRAME_DONE) ? 1 : 0;
604}
605
606void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
607{
608 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
609
610 writel(reg | INTSRC_FRAME_DONE, dsim->reg_base +
611 EXYNOS_DSIM_INTSRC);
612}
613
614void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
615 unsigned int tx_data)
616{
617 writel(tx_data, dsim->reg_base + EXYNOS_DSIM_PAYLOAD);
618}
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h
deleted file mode 100644
index 85460701c7ea..000000000000
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h
+++ /dev/null
@@ -1,112 +0,0 @@
1/* linux/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
2 *
3 * Header file for Samsung SoC MIPI-DSI lowlevel driver.
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd
6 *
7 * InKi Dae <inki.dae@samsung.com>
8 * Donghwa Lee <dh09.lee@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef _EXYNOS_MIPI_DSI_LOWLEVEL_H
16#define _EXYNOS_MIPI_DSI_LOWLEVEL_H
17
18void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim);
19void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim);
20void exynos_mipi_dsi_sw_reset_release(struct mipi_dsim_device *dsim);
21int exynos_mipi_dsi_get_sw_reset_release(struct mipi_dsim_device *dsim);
22void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
23 unsigned int mode, unsigned int mask);
24void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
25 unsigned int count);
26void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
27 unsigned int cfg);
28void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
29 unsigned int value);
30void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
31 unsigned int value);
32void exynos_mipi_dsi_set_main_stand_by(struct mipi_dsim_device *dsim,
33 unsigned int enable);
34void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
35 unsigned int width_resol, unsigned int height_resol);
36void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
37 unsigned int cmd_allow, unsigned int vfront, unsigned int vback);
38void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
39 unsigned int front, unsigned int back);
40void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
41 unsigned int vert, unsigned int hori);
42void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
43 unsigned int vert, unsigned int hori);
44void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim);
45void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
46 struct mipi_dsim_config *dsim_config);
47void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
48 unsigned int count);
49void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim, unsigned int lane,
50 unsigned int enable);
51void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim, unsigned int enable,
52 unsigned int afc_code);
53void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
54 unsigned int enable);
55void exynos_mipi_dsi_set_pll_pms(struct mipi_dsim_device *dsim, unsigned int p,
56 unsigned int m, unsigned int s);
57void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
58 unsigned int freq_band);
59void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
60 unsigned int pre_divider, unsigned int main_divider,
61 unsigned int scaler);
62void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
63 unsigned int lock_time);
64void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim,
65 unsigned int enable);
66void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
67 unsigned int src);
68void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
69 unsigned int enable);
70void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
71 unsigned int enable, unsigned int prs_val);
72void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
73 unsigned int lane_sel, unsigned int enable);
74void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
75 unsigned int enable);
76unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim);
77void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
78 unsigned int cnt_val);
79void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
80 unsigned int timeout);
81void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
82 unsigned int timeout);
83void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
84 unsigned int lp);
85void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
86 unsigned int lp);
87void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
88 unsigned int enable);
89void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
90 unsigned int swap_en);
91void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
92 unsigned int hs_zero);
93void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep);
94unsigned int exynos_mipi_dsi_read_interrupt(struct mipi_dsim_device *dsim);
95unsigned int exynos_mipi_dsi_read_interrupt_mask(struct mipi_dsim_device *dsim);
96void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim,
97 unsigned int src);
98void exynos_mipi_dsi_set_interrupt(struct mipi_dsim_device *dsim,
99 unsigned int src, unsigned int enable);
100unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim);
101unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim);
102unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
103void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
104void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim, unsigned int di,
105 unsigned int data0, unsigned int data1);
106void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
107 unsigned int tx_data);
108void exynos_mipi_dsi_rd_tx_header(struct mipi_dsim_device *dsim,
109 unsigned int data0, unsigned int data1);
110unsigned int exynos_mipi_dsi_rd_rx_fifo(struct mipi_dsim_device *dsim);
111
112#endif /* _EXYNOS_MIPI_DSI_LOWLEVEL_H */
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h
deleted file mode 100644
index 4227106d3fd0..000000000000
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h
+++ /dev/null
@@ -1,149 +0,0 @@
1/* linux/driver/video/exynos/exynos_mipi_dsi_regs.h
2 *
3 * Register definition file for Samsung MIPI-DSIM driver
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd
6 *
7 * InKi Dae <inki.dae@samsung.com>
8 * Donghwa Lee <dh09.lee@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef _EXYNOS_MIPI_DSI_REGS_H
16#define _EXYNOS_MIPI_DSI_REGS_H
17
18#define EXYNOS_DSIM_STATUS 0x0 /* Status register */
19#define EXYNOS_DSIM_SWRST 0x4 /* Software reset register */
20#define EXYNOS_DSIM_CLKCTRL 0x8 /* Clock control register */
21#define EXYNOS_DSIM_TIMEOUT 0xc /* Time out register */
22#define EXYNOS_DSIM_CONFIG 0x10 /* Configuration register */
23#define EXYNOS_DSIM_ESCMODE 0x14 /* Escape mode register */
24
25/* Main display image resolution register */
26#define EXYNOS_DSIM_MDRESOL 0x18
27#define EXYNOS_DSIM_MVPORCH 0x1c /* Main display Vporch register */
28#define EXYNOS_DSIM_MHPORCH 0x20 /* Main display Hporch register */
29#define EXYNOS_DSIM_MSYNC 0x24 /* Main display sync area register */
30
31/* Sub display image resolution register */
32#define EXYNOS_DSIM_SDRESOL 0x28
33#define EXYNOS_DSIM_INTSRC 0x2c /* Interrupt source register */
34#define EXYNOS_DSIM_INTMSK 0x30 /* Interrupt mask register */
35#define EXYNOS_DSIM_PKTHDR 0x34 /* Packet Header FIFO register */
36#define EXYNOS_DSIM_PAYLOAD 0x38 /* Payload FIFO register */
37#define EXYNOS_DSIM_RXFIFO 0x3c /* Read FIFO register */
38#define EXYNOS_DSIM_FIFOTHLD 0x40 /* FIFO threshold level register */
39#define EXYNOS_DSIM_FIFOCTRL 0x44 /* FIFO status and control register */
40
41/* FIFO memory AC characteristic register */
42#define EXYNOS_DSIM_PLLCTRL 0x4c /* PLL control register */
43#define EXYNOS_DSIM_PLLTMR 0x50 /* PLL timer register */
44#define EXYNOS_DSIM_PHYACCHR 0x54 /* D-PHY AC characteristic register */
45#define EXYNOS_DSIM_PHYACCHR1 0x58 /* D-PHY AC characteristic register1 */
46
47/* DSIM_STATUS */
48#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0)
49#define DSIM_STOP_STATE_CLK (1 << 8)
50#define DSIM_TX_READY_HS_CLK (1 << 10)
51
52/* DSIM_SWRST */
53#define DSIM_FUNCRST (1 << 16)
54#define DSIM_SWRST (1 << 0)
55
56/* EXYNOS_DSIM_TIMEOUT */
57#define DSIM_LPDR_TOUT_SHIFT(x) ((x) << 0)
58#define DSIM_BTA_TOUT_SHIFT(x) ((x) << 16)
59
60/* EXYNOS_DSIM_CLKCTRL */
61#define DSIM_LANE_ESC_CLKEN(x) (((x) & 0x1f) << 19)
62#define DSIM_BYTE_CLKEN_SHIFT(x) ((x) << 24)
63#define DSIM_BYTE_CLK_SRC_SHIFT(x) ((x) << 25)
64#define DSIM_PLL_BYPASS_SHIFT(x) ((x) << 27)
65#define DSIM_ESC_CLKEN_SHIFT(x) ((x) << 28)
66#define DSIM_TX_REQUEST_HSCLK_SHIFT(x) ((x) << 31)
67
68/* EXYNOS_DSIM_CONFIG */
69#define DSIM_LANE_ENx(x) (((x) & 0x1f) << 0)
70#define DSIM_NUM_OF_DATALANE_SHIFT(x) ((x) << 5)
71#define DSIM_HSA_MODE_SHIFT(x) ((x) << 20)
72#define DSIM_HBP_MODE_SHIFT(x) ((x) << 21)
73#define DSIM_HFP_MODE_SHIFT(x) ((x) << 22)
74#define DSIM_HSE_MODE_SHIFT(x) ((x) << 23)
75#define DSIM_AUTO_MODE_SHIFT(x) ((x) << 24)
76#define DSIM_EOT_DISABLE(x) ((x) << 28)
77#define DSIM_AUTO_FLUSH(x) ((x) << 29)
78
79#define DSIM_NUM_OF_DATA_LANE(x) ((x) << DSIM_NUM_OF_DATALANE_SHIFT)
80
81/* EXYNOS_DSIM_ESCMODE */
82#define DSIM_TX_LPDT_LP (1 << 6)
83#define DSIM_CMD_LPDT_LP (1 << 7)
84#define DSIM_FORCE_STOP_STATE_SHIFT(x) ((x) << 20)
85#define DSIM_STOP_STATE_CNT_SHIFT(x) ((x) << 21)
86
87/* EXYNOS_DSIM_MDRESOL */
88#define DSIM_MAIN_STAND_BY (1 << 31)
89#define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16)
90#define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0)
91
92/* EXYNOS_DSIM_MVPORCH */
93#define DSIM_CMD_ALLOW_SHIFT(x) ((x) << 28)
94#define DSIM_STABLE_VFP_SHIFT(x) ((x) << 16)
95#define DSIM_MAIN_VBP_SHIFT(x) ((x) << 0)
96#define DSIM_CMD_ALLOW_MASK (0xf << 28)
97#define DSIM_STABLE_VFP_MASK (0x7ff << 16)
98#define DSIM_MAIN_VBP_MASK (0x7ff << 0)
99
100/* EXYNOS_DSIM_MHPORCH */
101#define DSIM_MAIN_HFP_SHIFT(x) ((x) << 16)
102#define DSIM_MAIN_HBP_SHIFT(x) ((x) << 0)
103#define DSIM_MAIN_HFP_MASK ((0xffff) << 16)
104#define DSIM_MAIN_HBP_MASK ((0xffff) << 0)
105
106/* EXYNOS_DSIM_MSYNC */
107#define DSIM_MAIN_VSA_SHIFT(x) ((x) << 22)
108#define DSIM_MAIN_HSA_SHIFT(x) ((x) << 0)
109#define DSIM_MAIN_VSA_MASK ((0x3ff) << 22)
110#define DSIM_MAIN_HSA_MASK ((0xffff) << 0)
111
112/* EXYNOS_DSIM_SDRESOL */
113#define DSIM_SUB_STANDY_SHIFT(x) ((x) << 31)
114#define DSIM_SUB_VRESOL_SHIFT(x) ((x) << 16)
115#define DSIM_SUB_HRESOL_SHIFT(x) ((x) << 0)
116#define DSIM_SUB_STANDY_MASK ((0x1) << 31)
117#define DSIM_SUB_VRESOL_MASK ((0x7ff) << 16)
118#define DSIM_SUB_HRESOL_MASK ((0x7ff) << 0)
119
120/* EXYNOS_DSIM_INTSRC */
121#define INTSRC_PLL_STABLE (1 << 31)
122#define INTSRC_SW_RST_RELEASE (1 << 30)
123#define INTSRC_SFR_FIFO_EMPTY (1 << 29)
124#define INTSRC_FRAME_DONE (1 << 24)
125#define INTSRC_RX_DATA_DONE (1 << 18)
126
127/* EXYNOS_DSIM_INTMSK */
128#define INTMSK_FIFO_EMPTY (1 << 29)
129#define INTMSK_BTA (1 << 25)
130#define INTMSK_FRAME_DONE (1 << 24)
131#define INTMSK_RX_TIMEOUT (1 << 21)
132#define INTMSK_BTA_TIMEOUT (1 << 20)
133#define INTMSK_RX_DONE (1 << 18)
134#define INTMSK_RX_TE (1 << 17)
135#define INTMSK_RX_ACK (1 << 16)
136#define INTMSK_RX_ECC_ERR (1 << 15)
137#define INTMSK_RX_CRC_ERR (1 << 14)
138
139/* EXYNOS_DSIM_FIFOCTRL */
140#define SFR_HEADER_EMPTY (1 << 22)
141
142/* EXYNOS_DSIM_PHYACCHR */
143#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)
144
145/* EXYNOS_DSIM_PLLCTRL */
146#define DSIM_PLL_EN_SHIFT(x) ((x) << 23)
147#define DSIM_FREQ_BAND_SHIFT(x) ((x) << 24)
148
149#endif /* _EXYNOS_MIPI_DSI_REGS_H */
diff --git a/drivers/video/fbdev/exynos/s6e8ax0.c b/drivers/video/fbdev/exynos/s6e8ax0.c
deleted file mode 100644
index de2f3e793786..000000000000
--- a/drivers/video/fbdev/exynos/s6e8ax0.c
+++ /dev/null
@@ -1,887 +0,0 @@
1/* linux/drivers/video/exynos/s6e8ax0.c
2 *
3 * MIPI-DSI based s6e8ax0 AMOLED lcd 4.65 inch panel driver.
4 *
5 * Inki Dae, <inki.dae@samsung.com>
6 * Donghwa Lee, <dh09.lee@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/mutex.h>
17#include <linux/wait.h>
18#include <linux/ctype.h>
19#include <linux/io.h>
20#include <linux/delay.h>
21#include <linux/irq.h>
22#include <linux/interrupt.h>
23#include <linux/lcd.h>
24#include <linux/fb.h>
25#include <linux/backlight.h>
26#include <linux/regulator/consumer.h>
27
28#include <video/mipi_display.h>
29#include <video/exynos_mipi_dsim.h>
30
31#define LDI_MTP_LENGTH 24
32#define DSIM_PM_STABLE_TIME 10
33#define MIN_BRIGHTNESS 0
34#define MAX_BRIGHTNESS 24
35#define GAMMA_TABLE_COUNT 26
36
37#define POWER_IS_ON(pwr) ((pwr) == FB_BLANK_UNBLANK)
38#define POWER_IS_OFF(pwr) ((pwr) == FB_BLANK_POWERDOWN)
39#define POWER_IS_NRM(pwr) ((pwr) == FB_BLANK_NORMAL)
40
41#define lcd_to_master(a) (a->dsim_dev->master)
42#define lcd_to_master_ops(a) ((lcd_to_master(a))->master_ops)
43
44enum {
45 DSIM_NONE_STATE = 0,
46 DSIM_RESUME_COMPLETE = 1,
47 DSIM_FRAME_DONE = 2,
48};
49
50struct s6e8ax0 {
51 struct device *dev;
52 unsigned int power;
53 unsigned int id;
54 unsigned int gamma;
55 unsigned int acl_enable;
56 unsigned int cur_acl;
57
58 struct lcd_device *ld;
59 struct backlight_device *bd;
60
61 struct mipi_dsim_lcd_device *dsim_dev;
62 struct lcd_platform_data *ddi_pd;
63 struct mutex lock;
64 bool enabled;
65};
66
67
68static struct regulator_bulk_data supplies[] = {
69 { .supply = "vdd3", },
70 { .supply = "vci", },
71};
72
73static void s6e8ax0_regulator_enable(struct s6e8ax0 *lcd)
74{
75 int ret = 0;
76 struct lcd_platform_data *pd = NULL;
77
78 pd = lcd->ddi_pd;
79 mutex_lock(&lcd->lock);
80 if (!lcd->enabled) {
81 ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
82 if (ret)
83 goto out;
84
85 lcd->enabled = true;
86 }
87 msleep(pd->power_on_delay);
88out:
89 mutex_unlock(&lcd->lock);
90}
91
92static void s6e8ax0_regulator_disable(struct s6e8ax0 *lcd)
93{
94 int ret = 0;
95
96 mutex_lock(&lcd->lock);
97 if (lcd->enabled) {
98 ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
99 if (ret)
100 goto out;
101
102 lcd->enabled = false;
103 }
104out:
105 mutex_unlock(&lcd->lock);
106}
107
108static const unsigned char s6e8ax0_22_gamma_30[] = {
109 0xfa, 0x01, 0x60, 0x10, 0x60, 0xf5, 0x00, 0xff, 0xad, 0xaf,
110 0xbA, 0xc3, 0xd8, 0xc5, 0x9f, 0xc6, 0x9e, 0xc1, 0xdc, 0xc0,
111 0x00, 0x61, 0x00, 0x5a, 0x00, 0x74,
112};
113
114static const unsigned char s6e8ax0_22_gamma_50[] = {
115 0xfa, 0x01, 0x60, 0x10, 0x60, 0xe8, 0x1f, 0xf7, 0xad, 0xc0,
116 0xb5, 0xc4, 0xdc, 0xc4, 0x9e, 0xc6, 0x9c, 0xbb, 0xd8, 0xbb,
117 0x00, 0x70, 0x00, 0x68, 0x00, 0x86,
118};
119
120static const unsigned char s6e8ax0_22_gamma_60[] = {
121 0xfa, 0x01, 0x60, 0x10, 0x60, 0xde, 0x1f, 0xef, 0xad, 0xc4,
122 0xb3, 0xc3, 0xdd, 0xc4, 0x9e, 0xc6, 0x9c, 0xbc, 0xd6, 0xba,
123 0x00, 0x75, 0x00, 0x6e, 0x00, 0x8d,
124};
125
126static const unsigned char s6e8ax0_22_gamma_70[] = {
127 0xfa, 0x01, 0x60, 0x10, 0x60, 0xd8, 0x1f, 0xe7, 0xaf, 0xc8,
128 0xb4, 0xc4, 0xdd, 0xc3, 0x9d, 0xc6, 0x9c, 0xbb, 0xd6, 0xb9,
129 0x00, 0x7a, 0x00, 0x72, 0x00, 0x93,
130};
131
132static const unsigned char s6e8ax0_22_gamma_80[] = {
133 0xfa, 0x01, 0x60, 0x10, 0x60, 0xc9, 0x1f, 0xde, 0xae, 0xc9,
134 0xb1, 0xc3, 0xdd, 0xc2, 0x9d, 0xc5, 0x9b, 0xbc, 0xd6, 0xbb,
135 0x00, 0x7f, 0x00, 0x77, 0x00, 0x99,
136};
137
138static const unsigned char s6e8ax0_22_gamma_90[] = {
139 0xfa, 0x01, 0x60, 0x10, 0x60, 0xc7, 0x1f, 0xd9, 0xb0, 0xcc,
140 0xb2, 0xc3, 0xdc, 0xc1, 0x9c, 0xc6, 0x9c, 0xbc, 0xd4, 0xb9,
141 0x00, 0x83, 0x00, 0x7b, 0x00, 0x9e,
142};
143
144static const unsigned char s6e8ax0_22_gamma_100[] = {
145 0xfa, 0x01, 0x60, 0x10, 0x60, 0xbd, 0x80, 0xcd, 0xba, 0xce,
146 0xb3, 0xc4, 0xde, 0xc3, 0x9c, 0xc4, 0x9, 0xb8, 0xd3, 0xb6,
147 0x00, 0x88, 0x00, 0x80, 0x00, 0xa5,
148};
149
150static const unsigned char s6e8ax0_22_gamma_120[] = {
151 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb9, 0x95, 0xc8, 0xb1, 0xcf,
152 0xb2, 0xc6, 0xdf, 0xc5, 0x9b, 0xc3, 0x99, 0xb6, 0xd2, 0xb6,
153 0x00, 0x8f, 0x00, 0x86, 0x00, 0xac,
154};
155
156static const unsigned char s6e8ax0_22_gamma_130[] = {
157 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb7, 0xa0, 0xc7, 0xb1, 0xd0,
158 0xb2, 0xc4, 0xdd, 0xc3, 0x9a, 0xc3, 0x98, 0xb6, 0xd0, 0xb4,
159 0x00, 0x92, 0x00, 0x8a, 0x00, 0xb1,
160};
161
162static const unsigned char s6e8ax0_22_gamma_140[] = {
163 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb7, 0xa0, 0xc5, 0xb2, 0xd0,
164 0xb3, 0xc3, 0xde, 0xc3, 0x9b, 0xc2, 0x98, 0xb6, 0xd0, 0xb4,
165 0x00, 0x95, 0x00, 0x8d, 0x00, 0xb5,
166};
167
168static const unsigned char s6e8ax0_22_gamma_150[] = {
169 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb3, 0xa0, 0xc2, 0xb2, 0xd0,
170 0xb2, 0xc1, 0xdd, 0xc2, 0x9b, 0xc2, 0x98, 0xb4, 0xcf, 0xb1,
171 0x00, 0x99, 0x00, 0x90, 0x00, 0xba,
172};
173
174static const unsigned char s6e8ax0_22_gamma_160[] = {
175 0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xa5, 0xbf, 0xb0, 0xd0,
176 0xb1, 0xc3, 0xde, 0xc2, 0x99, 0xc1, 0x97, 0xb4, 0xce, 0xb1,
177 0x00, 0x9c, 0x00, 0x93, 0x00, 0xbe,
178};
179
180static const unsigned char s6e8ax0_22_gamma_170[] = {
181 0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb5, 0xbf, 0xb1, 0xd1,
182 0xb1, 0xc3, 0xde, 0xc3, 0x99, 0xc0, 0x96, 0xb4, 0xce, 0xb1,
183 0x00, 0x9f, 0x00, 0x96, 0x00, 0xc2,
184};
185
186static const unsigned char s6e8ax0_22_gamma_180[] = {
187 0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb7, 0xbe, 0xb3, 0xd2,
188 0xb3, 0xc3, 0xde, 0xc2, 0x97, 0xbf, 0x95, 0xb4, 0xcd, 0xb1,
189 0x00, 0xa2, 0x00, 0x99, 0x00, 0xc5,
190};
191
192static const unsigned char s6e8ax0_22_gamma_190[] = {
193 0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb9, 0xbe, 0xb2, 0xd2,
194 0xb2, 0xc3, 0xdd, 0xc3, 0x98, 0xbf, 0x95, 0xb2, 0xcc, 0xaf,
195 0x00, 0xa5, 0x00, 0x9c, 0x00, 0xc9,
196};
197
198static const unsigned char s6e8ax0_22_gamma_200[] = {
199 0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb9, 0xbc, 0xb2, 0xd2,
200 0xb1, 0xc4, 0xdd, 0xc3, 0x97, 0xbe, 0x95, 0xb1, 0xcb, 0xae,
201 0x00, 0xa8, 0x00, 0x9f, 0x00, 0xcd,
202};
203
204static const unsigned char s6e8ax0_22_gamma_210[] = {
205 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xc1, 0xbd, 0xb1, 0xd1,
206 0xb1, 0xc2, 0xde, 0xc2, 0x97, 0xbe, 0x94, 0xB0, 0xc9, 0xad,
207 0x00, 0xae, 0x00, 0xa4, 0x00, 0xd4,
208};
209
210static const unsigned char s6e8ax0_22_gamma_220[] = {
211 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xc7, 0xbd, 0xb1, 0xd1,
212 0xb1, 0xc2, 0xdd, 0xc2, 0x97, 0xbd, 0x94, 0xb0, 0xc9, 0xad,
213 0x00, 0xad, 0x00, 0xa2, 0x00, 0xd3,
214};
215
216static const unsigned char s6e8ax0_22_gamma_230[] = {
217 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xc3, 0xbd, 0xb2, 0xd1,
218 0xb1, 0xc3, 0xdd, 0xc1, 0x96, 0xbd, 0x94, 0xb0, 0xc9, 0xad,
219 0x00, 0xb0, 0x00, 0xa7, 0x00, 0xd7,
220};
221
222static const unsigned char s6e8ax0_22_gamma_240[] = {
223 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xcb, 0xbd, 0xb1, 0xd2,
224 0xb1, 0xc3, 0xdD, 0xc2, 0x95, 0xbd, 0x93, 0xaf, 0xc8, 0xab,
225 0x00, 0xb3, 0x00, 0xa9, 0x00, 0xdb,
226};
227
228static const unsigned char s6e8ax0_22_gamma_250[] = {
229 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb3, 0xcc, 0xbe, 0xb0, 0xd2,
230 0xb0, 0xc3, 0xdD, 0xc2, 0x94, 0xbc, 0x92, 0xae, 0xc8, 0xab,
231 0x00, 0xb6, 0x00, 0xab, 0x00, 0xde,
232};
233
234static const unsigned char s6e8ax0_22_gamma_260[] = {
235 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb3, 0xd0, 0xbe, 0xaf, 0xd1,
236 0xaf, 0xc2, 0xdd, 0xc1, 0x96, 0xbc, 0x93, 0xaf, 0xc8, 0xac,
237 0x00, 0xb7, 0x00, 0xad, 0x00, 0xe0,
238};
239
240static const unsigned char s6e8ax0_22_gamma_270[] = {
241 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb2, 0xcF, 0xbd, 0xb0, 0xd2,
242 0xaf, 0xc2, 0xdc, 0xc1, 0x95, 0xbd, 0x93, 0xae, 0xc6, 0xaa,
243 0x00, 0xba, 0x00, 0xb0, 0x00, 0xe4,
244};
245
246static const unsigned char s6e8ax0_22_gamma_280[] = {
247 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb2, 0xd0, 0xbd, 0xaf, 0xd0,
248 0xad, 0xc4, 0xdd, 0xc3, 0x95, 0xbd, 0x93, 0xac, 0xc5, 0xa9,
249 0x00, 0xbd, 0x00, 0xb2, 0x00, 0xe7,
250};
251
252static const unsigned char s6e8ax0_22_gamma_300[] = {
253 0xfa, 0x01, 0x60, 0x10, 0x60, 0xb5, 0xd3, 0xbd, 0xb1, 0xd2,
254 0xb0, 0xc0, 0xdc, 0xc0, 0x94, 0xba, 0x91, 0xac, 0xc5, 0xa9,
255 0x00, 0xc2, 0x00, 0xb7, 0x00, 0xed,
256};
257
258static const unsigned char *s6e8ax0_22_gamma_table[] = {
259 s6e8ax0_22_gamma_30,
260 s6e8ax0_22_gamma_50,
261 s6e8ax0_22_gamma_60,
262 s6e8ax0_22_gamma_70,
263 s6e8ax0_22_gamma_80,
264 s6e8ax0_22_gamma_90,
265 s6e8ax0_22_gamma_100,
266 s6e8ax0_22_gamma_120,
267 s6e8ax0_22_gamma_130,
268 s6e8ax0_22_gamma_140,
269 s6e8ax0_22_gamma_150,
270 s6e8ax0_22_gamma_160,
271 s6e8ax0_22_gamma_170,
272 s6e8ax0_22_gamma_180,
273 s6e8ax0_22_gamma_190,
274 s6e8ax0_22_gamma_200,
275 s6e8ax0_22_gamma_210,
276 s6e8ax0_22_gamma_220,
277 s6e8ax0_22_gamma_230,
278 s6e8ax0_22_gamma_240,
279 s6e8ax0_22_gamma_250,
280 s6e8ax0_22_gamma_260,
281 s6e8ax0_22_gamma_270,
282 s6e8ax0_22_gamma_280,
283 s6e8ax0_22_gamma_300,
284};
285
286static void s6e8ax0_panel_cond(struct s6e8ax0 *lcd)
287{
288 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
289
290 static const unsigned char data_to_send[] = {
291 0xf8, 0x3d, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3c, 0x7d,
292 0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08,
293 0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x23, 0xc0,
294 0xc8, 0x08, 0x48, 0xc1, 0x00, 0xc1, 0xff, 0xff, 0xc8
295 };
296 static const unsigned char data_to_send_panel_reverse[] = {
297 0xf8, 0x19, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3c, 0x7d,
298 0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08,
299 0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x23, 0xc0,
300 0xc1, 0x01, 0x41, 0xc1, 0x00, 0xc1, 0xf6, 0xf6, 0xc1
301 };
302
303 if (lcd->dsim_dev->panel_reverse)
304 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
305 data_to_send_panel_reverse,
306 ARRAY_SIZE(data_to_send_panel_reverse));
307 else
308 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
309 data_to_send, ARRAY_SIZE(data_to_send));
310}
311
312static void s6e8ax0_display_cond(struct s6e8ax0 *lcd)
313{
314 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
315 static const unsigned char data_to_send[] = {
316 0xf2, 0x80, 0x03, 0x0d
317 };
318
319 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
320 data_to_send, ARRAY_SIZE(data_to_send));
321}
322
323/* Gamma 2.2 Setting (200cd, 7500K, 10MPCD) */
324static void s6e8ax0_gamma_cond(struct s6e8ax0 *lcd)
325{
326 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
327 unsigned int gamma = lcd->bd->props.brightness;
328
329 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
330 s6e8ax0_22_gamma_table[gamma],
331 GAMMA_TABLE_COUNT);
332}
333
334static void s6e8ax0_gamma_update(struct s6e8ax0 *lcd)
335{
336 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
337 static const unsigned char data_to_send[] = {
338 0xf7, 0x03
339 };
340
341 ops->cmd_write(lcd_to_master(lcd),
342 MIPI_DSI_DCS_SHORT_WRITE_PARAM, data_to_send,
343 ARRAY_SIZE(data_to_send));
344}
345
346static void s6e8ax0_etc_cond1(struct s6e8ax0 *lcd)
347{
348 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
349 static const unsigned char data_to_send[] = {
350 0xd1, 0xfe, 0x80, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x40,
351 0x0d, 0x00, 0x00
352 };
353
354 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
355 data_to_send, ARRAY_SIZE(data_to_send));
356}
357
358static void s6e8ax0_etc_cond2(struct s6e8ax0 *lcd)
359{
360 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
361 static const unsigned char data_to_send[] = {
362 0xb6, 0x0c, 0x02, 0x03, 0x32, 0xff, 0x44, 0x44, 0xc0,
363 0x00
364 };
365
366 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
367 data_to_send, ARRAY_SIZE(data_to_send));
368}
369
370static void s6e8ax0_etc_cond3(struct s6e8ax0 *lcd)
371{
372 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
373 static const unsigned char data_to_send[] = {
374 0xe1, 0x10, 0x1c, 0x17, 0x08, 0x1d
375 };
376
377 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
378 data_to_send, ARRAY_SIZE(data_to_send));
379}
380
381static void s6e8ax0_etc_cond4(struct s6e8ax0 *lcd)
382{
383 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
384 static const unsigned char data_to_send[] = {
385 0xe2, 0xed, 0x07, 0xc3, 0x13, 0x0d, 0x03
386 };
387
388 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
389 data_to_send, ARRAY_SIZE(data_to_send));
390}
391
392static void s6e8ax0_etc_cond5(struct s6e8ax0 *lcd)
393{
394 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
395 static const unsigned char data_to_send[] = {
396 0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x19, 0x33, 0x02
397 };
398
399 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
400 data_to_send, ARRAY_SIZE(data_to_send));
401}
402static void s6e8ax0_etc_cond6(struct s6e8ax0 *lcd)
403{
404 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
405 static const unsigned char data_to_send[] = {
406 0xe3, 0x40
407 };
408
409 ops->cmd_write(lcd_to_master(lcd),
410 MIPI_DSI_DCS_SHORT_WRITE_PARAM,
411 data_to_send, ARRAY_SIZE(data_to_send));
412}
413
414static void s6e8ax0_etc_cond7(struct s6e8ax0 *lcd)
415{
416 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
417 static const unsigned char data_to_send[] = {
418 0xe4, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00
419 };
420
421 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
422 data_to_send, ARRAY_SIZE(data_to_send));
423}
424
425static void s6e8ax0_elvss_set(struct s6e8ax0 *lcd)
426{
427 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
428 static const unsigned char data_to_send[] = {
429 0xb1, 0x04, 0x00
430 };
431
432 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
433 data_to_send, ARRAY_SIZE(data_to_send));
434}
435
436static void s6e8ax0_elvss_nvm_set(struct s6e8ax0 *lcd)
437{
438 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
439 static const unsigned char data_to_send[] = {
440 0xd9, 0x5c, 0x20, 0x0c, 0x0f, 0x41, 0x00, 0x10, 0x11,
441 0x12, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcb, 0xed,
442 0x64, 0xaf
443 };
444
445 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
446 data_to_send, ARRAY_SIZE(data_to_send));
447}
448
449static void s6e8ax0_sleep_in(struct s6e8ax0 *lcd)
450{
451 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
452 static const unsigned char data_to_send[] = {
453 0x10, 0x00
454 };
455
456 ops->cmd_write(lcd_to_master(lcd),
457 MIPI_DSI_DCS_SHORT_WRITE,
458 data_to_send, ARRAY_SIZE(data_to_send));
459}
460
461static void s6e8ax0_sleep_out(struct s6e8ax0 *lcd)
462{
463 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
464 static const unsigned char data_to_send[] = {
465 0x11, 0x00
466 };
467
468 ops->cmd_write(lcd_to_master(lcd),
469 MIPI_DSI_DCS_SHORT_WRITE,
470 data_to_send, ARRAY_SIZE(data_to_send));
471}
472
473static void s6e8ax0_display_on(struct s6e8ax0 *lcd)
474{
475 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
476 static const unsigned char data_to_send[] = {
477 0x29, 0x00
478 };
479
480 ops->cmd_write(lcd_to_master(lcd),
481 MIPI_DSI_DCS_SHORT_WRITE,
482 data_to_send, ARRAY_SIZE(data_to_send));
483}
484
485static void s6e8ax0_display_off(struct s6e8ax0 *lcd)
486{
487 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
488 static const unsigned char data_to_send[] = {
489 0x28, 0x00
490 };
491
492 ops->cmd_write(lcd_to_master(lcd),
493 MIPI_DSI_DCS_SHORT_WRITE,
494 data_to_send, ARRAY_SIZE(data_to_send));
495}
496
497static void s6e8ax0_apply_level2_key(struct s6e8ax0 *lcd)
498{
499 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
500 static const unsigned char data_to_send[] = {
501 0xf0, 0x5a, 0x5a
502 };
503
504 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
505 data_to_send, ARRAY_SIZE(data_to_send));
506}
507
508static void s6e8ax0_acl_on(struct s6e8ax0 *lcd)
509{
510 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
511 static const unsigned char data_to_send[] = {
512 0xc0, 0x01
513 };
514
515 ops->cmd_write(lcd_to_master(lcd),
516 MIPI_DSI_DCS_SHORT_WRITE,
517 data_to_send, ARRAY_SIZE(data_to_send));
518}
519
520static void s6e8ax0_acl_off(struct s6e8ax0 *lcd)
521{
522 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
523 static const unsigned char data_to_send[] = {
524 0xc0, 0x00
525 };
526
527 ops->cmd_write(lcd_to_master(lcd),
528 MIPI_DSI_DCS_SHORT_WRITE,
529 data_to_send, ARRAY_SIZE(data_to_send));
530}
531
532/* Full white 50% reducing setting */
533static void s6e8ax0_acl_ctrl_set(struct s6e8ax0 *lcd)
534{
535 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
536 /* Full white 50% reducing setting */
537 static const unsigned char cutoff_50[] = {
538 0xc1, 0x47, 0x53, 0x13, 0x53, 0x00, 0x00, 0x02, 0xcf,
539 0x00, 0x00, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x01, 0x08, 0x0f, 0x16, 0x1d, 0x24, 0x2a, 0x31, 0x38,
541 0x3f, 0x46
542 };
543 /* Full white 45% reducing setting */
544 static const unsigned char cutoff_45[] = {
545 0xc1, 0x47, 0x53, 0x13, 0x53, 0x00, 0x00, 0x02, 0xcf,
546 0x00, 0x00, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x01, 0x07, 0x0d, 0x13, 0x19, 0x1f, 0x25, 0x2b, 0x31,
548 0x37, 0x3d
549 };
550 /* Full white 40% reducing setting */
551 static const unsigned char cutoff_40[] = {
552 0xc1, 0x47, 0x53, 0x13, 0x53, 0x00, 0x00, 0x02, 0xcf,
553 0x00, 0x00, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x01, 0x06, 0x0c, 0x11, 0x16, 0x1c, 0x21, 0x26, 0x2b,
555 0x31, 0x36
556 };
557
558 if (lcd->acl_enable) {
559 if (lcd->cur_acl == 0) {
560 if (lcd->gamma == 0 || lcd->gamma == 1) {
561 s6e8ax0_acl_off(lcd);
562 dev_dbg(&lcd->ld->dev,
563 "cur_acl=%d\n", lcd->cur_acl);
564 } else
565 s6e8ax0_acl_on(lcd);
566 }
567 switch (lcd->gamma) {
568 case 0: /* 30cd */
569 s6e8ax0_acl_off(lcd);
570 lcd->cur_acl = 0;
571 break;
572 case 1 ... 3: /* 50cd ~ 90cd */
573 ops->cmd_write(lcd_to_master(lcd),
574 MIPI_DSI_DCS_LONG_WRITE,
575 cutoff_40,
576 ARRAY_SIZE(cutoff_40));
577 lcd->cur_acl = 40;
578 break;
579 case 4 ... 7: /* 120cd ~ 210cd */
580 ops->cmd_write(lcd_to_master(lcd),
581 MIPI_DSI_DCS_LONG_WRITE,
582 cutoff_45,
583 ARRAY_SIZE(cutoff_45));
584 lcd->cur_acl = 45;
585 break;
586 case 8 ... 10: /* 220cd ~ 300cd */
587 ops->cmd_write(lcd_to_master(lcd),
588 MIPI_DSI_DCS_LONG_WRITE,
589 cutoff_50,
590 ARRAY_SIZE(cutoff_50));
591 lcd->cur_acl = 50;
592 break;
593 default:
594 break;
595 }
596 } else {
597 s6e8ax0_acl_off(lcd);
598 lcd->cur_acl = 0;
599 dev_dbg(&lcd->ld->dev, "cur_acl = %d\n", lcd->cur_acl);
600 }
601}
602
603static void s6e8ax0_read_id(struct s6e8ax0 *lcd, u8 *mtp_id)
604{
605 unsigned int ret;
606 unsigned int addr = 0xd1; /* MTP ID */
607 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
608
609 ret = ops->cmd_read(lcd_to_master(lcd),
610 MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM,
611 addr, 3, mtp_id);
612}
613
614static int s6e8ax0_panel_init(struct s6e8ax0 *lcd)
615{
616 s6e8ax0_apply_level2_key(lcd);
617 s6e8ax0_sleep_out(lcd);
618 msleep(1);
619 s6e8ax0_panel_cond(lcd);
620 s6e8ax0_display_cond(lcd);
621 s6e8ax0_gamma_cond(lcd);
622 s6e8ax0_gamma_update(lcd);
623
624 s6e8ax0_etc_cond1(lcd);
625 s6e8ax0_etc_cond2(lcd);
626 s6e8ax0_etc_cond3(lcd);
627 s6e8ax0_etc_cond4(lcd);
628 s6e8ax0_etc_cond5(lcd);
629 s6e8ax0_etc_cond6(lcd);
630 s6e8ax0_etc_cond7(lcd);
631
632 s6e8ax0_elvss_nvm_set(lcd);
633 s6e8ax0_elvss_set(lcd);
634
635 s6e8ax0_acl_ctrl_set(lcd);
636 s6e8ax0_acl_on(lcd);
637
638 /* if ID3 value is not 33h, branch private elvss mode */
639 msleep(lcd->ddi_pd->power_on_delay);
640
641 return 0;
642}
643
644static int s6e8ax0_update_gamma_ctrl(struct s6e8ax0 *lcd, int brightness)
645{
646 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
647
648 ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
649 s6e8ax0_22_gamma_table[brightness],
650 ARRAY_SIZE(s6e8ax0_22_gamma_table));
651
652 /* update gamma table. */
653 s6e8ax0_gamma_update(lcd);
654 lcd->gamma = brightness;
655
656 return 0;
657}
658
659static int s6e8ax0_gamma_ctrl(struct s6e8ax0 *lcd, int gamma)
660{
661 s6e8ax0_update_gamma_ctrl(lcd, gamma);
662
663 return 0;
664}
665
666static int s6e8ax0_set_power(struct lcd_device *ld, int power)
667{
668 struct s6e8ax0 *lcd = lcd_get_data(ld);
669 struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
670 int ret = 0;
671
672 if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
673 power != FB_BLANK_NORMAL) {
674 dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
675 return -EINVAL;
676 }
677
678 if ((power == FB_BLANK_UNBLANK) && ops->set_blank_mode) {
679 /* LCD power on */
680 if ((POWER_IS_ON(power) && POWER_IS_OFF(lcd->power))
681 || (POWER_IS_ON(power) && POWER_IS_NRM(lcd->power))) {
682 ret = ops->set_blank_mode(lcd_to_master(lcd), power);
683 if (!ret && lcd->power != power)
684 lcd->power = power;
685 }
686 } else if ((power == FB_BLANK_POWERDOWN) && ops->set_early_blank_mode) {
687 /* LCD power off */
688 if ((POWER_IS_OFF(power) && POWER_IS_ON(lcd->power)) ||
689 (POWER_IS_ON(lcd->power) && POWER_IS_NRM(power))) {
690 ret = ops->set_early_blank_mode(lcd_to_master(lcd),
691 power);
692 if (!ret && lcd->power != power)
693 lcd->power = power;
694 }
695 }
696
697 return ret;
698}
699
700static int s6e8ax0_get_power(struct lcd_device *ld)
701{
702 struct s6e8ax0 *lcd = lcd_get_data(ld);
703
704 return lcd->power;
705}
706
707static int s6e8ax0_set_brightness(struct backlight_device *bd)
708{
709 int ret = 0, brightness = bd->props.brightness;
710 struct s6e8ax0 *lcd = bl_get_data(bd);
711
712 if (brightness < MIN_BRIGHTNESS ||
713 brightness > bd->props.max_brightness) {
714 dev_err(lcd->dev, "lcd brightness should be %d to %d.\n",
715 MIN_BRIGHTNESS, MAX_BRIGHTNESS);
716 return -EINVAL;
717 }
718
719 ret = s6e8ax0_gamma_ctrl(lcd, brightness);
720 if (ret) {
721 dev_err(&bd->dev, "lcd brightness setting failed.\n");
722 return -EIO;
723 }
724
725 return ret;
726}
727
728static struct lcd_ops s6e8ax0_lcd_ops = {
729 .set_power = s6e8ax0_set_power,
730 .get_power = s6e8ax0_get_power,
731};
732
733static const struct backlight_ops s6e8ax0_backlight_ops = {
734 .update_status = s6e8ax0_set_brightness,
735};
736
737static void s6e8ax0_power_on(struct mipi_dsim_lcd_device *dsim_dev, int power)
738{
739 struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
740
741 msleep(lcd->ddi_pd->power_on_delay);
742
743 /* lcd power on */
744 if (power)
745 s6e8ax0_regulator_enable(lcd);
746 else
747 s6e8ax0_regulator_disable(lcd);
748
749 msleep(lcd->ddi_pd->reset_delay);
750
751 /* lcd reset */
752 if (lcd->ddi_pd->reset)
753 lcd->ddi_pd->reset(lcd->ld);
754 msleep(5);
755}
756
757static void s6e8ax0_set_sequence(struct mipi_dsim_lcd_device *dsim_dev)
758{
759 struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
760
761 s6e8ax0_panel_init(lcd);
762 s6e8ax0_display_on(lcd);
763
764 lcd->power = FB_BLANK_UNBLANK;
765}
766
767static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
768{
769 struct s6e8ax0 *lcd;
770 int ret;
771 u8 mtp_id[3] = {0, };
772
773 lcd = devm_kzalloc(&dsim_dev->dev, sizeof(struct s6e8ax0), GFP_KERNEL);
774 if (!lcd) {
775 dev_err(&dsim_dev->dev, "failed to allocate s6e8ax0 structure.\n");
776 return -ENOMEM;
777 }
778
779 lcd->dsim_dev = dsim_dev;
780 lcd->ddi_pd = (struct lcd_platform_data *)dsim_dev->platform_data;
781 lcd->dev = &dsim_dev->dev;
782
783 mutex_init(&lcd->lock);
784
785 ret = devm_regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
786 if (ret) {
787 dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
788 return ret;
789 }
790
791 lcd->ld = devm_lcd_device_register(lcd->dev, "s6e8ax0", lcd->dev, lcd,
792 &s6e8ax0_lcd_ops);
793 if (IS_ERR(lcd->ld)) {
794 dev_err(lcd->dev, "failed to register lcd ops.\n");
795 return PTR_ERR(lcd->ld);
796 }
797
798 lcd->bd = devm_backlight_device_register(lcd->dev, "s6e8ax0-bl",
799 lcd->dev, lcd, &s6e8ax0_backlight_ops, NULL);
800 if (IS_ERR(lcd->bd)) {
801 dev_err(lcd->dev, "failed to register backlight ops.\n");
802 return PTR_ERR(lcd->bd);
803 }
804
805 lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
806 lcd->bd->props.brightness = MAX_BRIGHTNESS;
807
808 s6e8ax0_read_id(lcd, mtp_id);
809 if (mtp_id[0] == 0x00)
810 dev_err(lcd->dev, "read id failed\n");
811
812 dev_info(lcd->dev, "Read ID : %x, %x, %x\n",
813 mtp_id[0], mtp_id[1], mtp_id[2]);
814
815 if (mtp_id[2] == 0x33)
816 dev_info(lcd->dev,
817 "ID-3 is 0xff does not support dynamic elvss\n");
818 else
819 dev_info(lcd->dev,
820 "ID-3 is 0x%x support dynamic elvss\n", mtp_id[2]);
821
822 lcd->acl_enable = 1;
823 lcd->cur_acl = 0;
824
825 dev_set_drvdata(&dsim_dev->dev, lcd);
826
827 dev_dbg(lcd->dev, "probed s6e8ax0 panel driver.\n");
828
829 return 0;
830}
831
832static int __maybe_unused s6e8ax0_suspend(struct mipi_dsim_lcd_device *dsim_dev)
833{
834 struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
835
836 s6e8ax0_sleep_in(lcd);
837 msleep(lcd->ddi_pd->power_off_delay);
838 s6e8ax0_display_off(lcd);
839
840 s6e8ax0_regulator_disable(lcd);
841
842 return 0;
843}
844
845static int __maybe_unused s6e8ax0_resume(struct mipi_dsim_lcd_device *dsim_dev)
846{
847 struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
848
849 s6e8ax0_sleep_out(lcd);
850 msleep(lcd->ddi_pd->power_on_delay);
851
852 s6e8ax0_regulator_enable(lcd);
853 s6e8ax0_set_sequence(dsim_dev);
854
855 return 0;
856}
857
858static struct mipi_dsim_lcd_driver s6e8ax0_dsim_ddi_driver = {
859 .name = "s6e8ax0",
860 .id = -1,
861
862 .power_on = s6e8ax0_power_on,
863 .set_sequence = s6e8ax0_set_sequence,
864 .probe = s6e8ax0_probe,
865 .suspend = IS_ENABLED(CONFIG_PM) ? s6e8ax0_suspend : NULL,
866 .resume = IS_ENABLED(CONFIG_PM) ? s6e8ax0_resume : NULL,
867};
868
869static int s6e8ax0_init(void)
870{
871 exynos_mipi_dsi_register_lcd_driver(&s6e8ax0_dsim_ddi_driver);
872
873 return 0;
874}
875
876static void s6e8ax0_exit(void)
877{
878 return;
879}
880
881module_init(s6e8ax0_init);
882module_exit(s6e8ax0_exit);
883
884MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
885MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
886MODULE_DESCRIPTION("MIPI-DSI based s6e8ax0 AMOLED LCD Panel Driver");
887MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/hecubafb.c b/drivers/video/fbdev/hecubafb.c
index e4031ef39491..8577195cb533 100644
--- a/drivers/video/fbdev/hecubafb.c
+++ b/drivers/video/fbdev/hecubafb.c
@@ -47,7 +47,7 @@
47#define DPY_W 600 47#define DPY_W 600
48#define DPY_H 800 48#define DPY_H 800
49 49
50static struct fb_fix_screeninfo hecubafb_fix = { 50static const struct fb_fix_screeninfo hecubafb_fix = {
51 .id = "hecubafb", 51 .id = "hecubafb",
52 .type = FB_TYPE_PACKED_PIXELS, 52 .type = FB_TYPE_PACKED_PIXELS,
53 .visual = FB_VISUAL_MONO01, 53 .visual = FB_VISUAL_MONO01,
@@ -58,7 +58,7 @@ static struct fb_fix_screeninfo hecubafb_fix = {
58 .accel = FB_ACCEL_NONE, 58 .accel = FB_ACCEL_NONE,
59}; 59};
60 60
61static struct fb_var_screeninfo hecubafb_var = { 61static const struct fb_var_screeninfo hecubafb_var = {
62 .xres = DPY_W, 62 .xres = DPY_W,
63 .yres = DPY_H, 63 .yres = DPY_H,
64 .xres_virtual = DPY_W, 64 .xres_virtual = DPY_W,
diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c
index 15d3ccff2965..463028543173 100644
--- a/drivers/video/fbdev/hgafb.c
+++ b/drivers/video/fbdev/hgafb.c
@@ -106,7 +106,7 @@ static DEFINE_SPINLOCK(hga_reg_lock);
106 106
107/* Framebuffer driver structures */ 107/* Framebuffer driver structures */
108 108
109static struct fb_var_screeninfo hga_default_var = { 109static const struct fb_var_screeninfo hga_default_var = {
110 .xres = 720, 110 .xres = 720,
111 .yres = 348, 111 .yres = 348,
112 .xres_virtual = 720, 112 .xres_virtual = 720,
diff --git a/drivers/video/fbdev/i740fb.c b/drivers/video/fbdev/i740fb.c
index cf5ccd0f2252..7bc5f6056c77 100644
--- a/drivers/video/fbdev/i740fb.c
+++ b/drivers/video/fbdev/i740fb.c
@@ -82,7 +82,7 @@ struct i740fb_par {
82#define DACSPEED24_SD 128 82#define DACSPEED24_SD 128
83#define DACSPEED32 86 83#define DACSPEED32 86
84 84
85static struct fb_fix_screeninfo i740fb_fix = { 85static const struct fb_fix_screeninfo i740fb_fix = {
86 .id = "i740fb", 86 .id = "i740fb",
87 .type = FB_TYPE_PACKED_PIXELS, 87 .type = FB_TYPE_PACKED_PIXELS,
88 .visual = FB_VISUAL_TRUECOLOR, 88 .visual = FB_VISUAL_TRUECOLOR,
diff --git a/drivers/video/fbdev/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c
index 025b882a4826..483ab2592d0c 100644
--- a/drivers/video/fbdev/i810/i810_main.c
+++ b/drivers/video/fbdev/i810/i810_main.c
@@ -1691,7 +1691,7 @@ static int i810_alloc_agp_mem(struct fb_info *info)
1691 if (!(par->i810_gtt.i810_cursor_memory = 1691 if (!(par->i810_gtt.i810_cursor_memory =
1692 agp_allocate_memory(bridge, par->cursor_heap.size >> 12, 1692 agp_allocate_memory(bridge, par->cursor_heap.size >> 12,
1693 AGP_PHYSICAL_MEMORY))) { 1693 AGP_PHYSICAL_MEMORY))) {
1694 printk("i810fb_alloc_cursormem: can't allocate" 1694 printk("i810fb_alloc_cursormem: can't allocate "
1695 "cursor memory\n"); 1695 "cursor memory\n");
1696 agp_backend_release(bridge); 1696 agp_backend_release(bridge);
1697 return -ENOMEM; 1697 return -ENOMEM;
diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c
index bf207444ba0c..ff2a5d2023e1 100644
--- a/drivers/video/fbdev/intelfb/intelfbdrv.c
+++ b/drivers/video/fbdev/intelfb/intelfbdrv.c
@@ -1301,11 +1301,6 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,
1301 break; 1301 break;
1302 } 1302 }
1303 1303
1304 if (v.xoffset < 0)
1305 v.xoffset = 0;
1306 if (v.yoffset < 0)
1307 v.yoffset = 0;
1308
1309 if (v.xoffset > v.xres_virtual - v.xres) 1304 if (v.xoffset > v.xres_virtual - v.xres)
1310 v.xoffset = v.xres_virtual - v.xres; 1305 v.xoffset = v.xres_virtual - v.xres;
1311 if (v.yoffset > v.yres_virtual - v.yres) 1306 if (v.yoffset > v.yres_virtual - v.yres)
diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c
index 5bb01533271e..f77478fb3d14 100644
--- a/drivers/video/fbdev/kyro/fbdev.c
+++ b/drivers/video/fbdev/kyro/fbdev.c
@@ -44,7 +44,7 @@ static struct fb_fix_screeninfo kyro_fix = {
44 .accel = FB_ACCEL_NONE, 44 .accel = FB_ACCEL_NONE,
45}; 45};
46 46
47static struct fb_var_screeninfo kyro_var = { 47static const struct fb_var_screeninfo kyro_var = {
48 /* 640x480, 16bpp @ 60 Hz */ 48 /* 640x480, 16bpp @ 60 Hz */
49 .xres = 640, 49 .xres = 640,
50 .yres = 480, 50 .yres = 480,
diff --git a/drivers/video/fbdev/matrox/matroxfb_Ti3026.c b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c
index 195ad7cac1ba..68fa037d8cbc 100644
--- a/drivers/video/fbdev/matrox/matroxfb_Ti3026.c
+++ b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c
@@ -372,7 +372,7 @@ static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m)
372 372
373 DBG(__func__) 373 DBG(__func__)
374 374
375 memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg)); 375 memcpy(hw->DACreg, MGADACbpp32, sizeof(MGADACbpp32));
376 switch (minfo->fbcon.var.bits_per_pixel) { 376 switch (minfo->fbcon.var.bits_per_pixel) {
377 case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1; /* or _8_1, they are same */ 377 case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1; /* or _8_1, they are same */
378 hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR; 378 hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
diff --git a/drivers/video/fbdev/matrox/matroxfb_g450.c b/drivers/video/fbdev/matrox/matroxfb_g450.c
index cff0546ea6fd..f108ae66fc83 100644
--- a/drivers/video/fbdev/matrox/matroxfb_g450.c
+++ b/drivers/video/fbdev/matrox/matroxfb_g450.c
@@ -433,7 +433,7 @@ static void cve2_init_TVdata(int norm, struct mavenregs* data, const struct outp
433 0x00, /* 3E written multiple times */ 433 0x00, /* 3E written multiple times */
434 0x00, /* 3F not written */ 434 0x00, /* 3F not written */
435 } }; 435 } };
436 static struct mavenregs ntscregs = { { 436 static const struct mavenregs ntscregs = { {
437 0x21, 0xF0, 0x7C, 0x1F, /* 00: chroma subcarrier */ 437 0x21, 0xF0, 0x7C, 0x1F, /* 00: chroma subcarrier */
438 0x00, 438 0x00,
439 0x00, /* test */ 439 0x00, /* test */
diff --git a/drivers/video/fbdev/mb862xx/mb862xx-i2c.c b/drivers/video/fbdev/mb862xx/mb862xx-i2c.c
index c87e17afb3e2..ba96c44f2761 100644
--- a/drivers/video/fbdev/mb862xx/mb862xx-i2c.c
+++ b/drivers/video/fbdev/mb862xx/mb862xx-i2c.c
@@ -157,17 +157,10 @@ static struct i2c_adapter mb862xx_i2c_adapter = {
157 157
158int mb862xx_i2c_init(struct mb862xxfb_par *par) 158int mb862xx_i2c_init(struct mb862xxfb_par *par)
159{ 159{
160 int ret;
161
162 mb862xx_i2c_adapter.algo_data = par; 160 mb862xx_i2c_adapter.algo_data = par;
163 par->adap = &mb862xx_i2c_adapter; 161 par->adap = &mb862xx_i2c_adapter;
164 162
165 ret = i2c_add_adapter(par->adap); 163 return i2c_add_adapter(par->adap);
166 if (ret < 0) {
167 dev_err(par->dev, "failed to add %s\n",
168 mb862xx_i2c_adapter.name);
169 }
170 return ret;
171} 164}
172 165
173void mb862xx_i2c_exit(struct mb862xxfb_par *par) 166void mb862xx_i2c_exit(struct mb862xxfb_par *par)
diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index f91b1db262b0..8778e01cebac 100644
--- a/drivers/video/fbdev/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
@@ -845,7 +845,7 @@ static int __set_par(struct fb_info *fbi, bool lock)
845 if (fbi->var.sync & FB_SYNC_SHARP_MODE) 845 if (fbi->var.sync & FB_SYNC_SHARP_MODE)
846 mode = IPU_PANEL_SHARP_TFT; 846 mode = IPU_PANEL_SHARP_TFT;
847 847
848 dev_dbg(fbi->device, "pixclock = %ul Hz\n", 848 dev_dbg(fbi->device, "pixclock = %u Hz\n",
849 (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); 849 (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
850 850
851 if (sdc_init_panel(mx3fb, mode, 851 if (sdc_init_panel(mx3fb, mode,
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c
index 4e6608ceac09..7846f0e8bbbb 100644
--- a/drivers/video/fbdev/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
@@ -800,6 +800,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host,
800 struct fb_videomode *vmode) 800 struct fb_videomode *vmode)
801{ 801{
802 int ret; 802 int ret;
803 struct device *dev = &host->pdev->dev;
803 struct fb_info *fb_info = &host->fb_info; 804 struct fb_info *fb_info = &host->fb_info;
804 struct fb_var_screeninfo *var = &fb_info->var; 805 struct fb_var_screeninfo *var = &fb_info->var;
805 dma_addr_t fb_phys; 806 dma_addr_t fb_phys;
@@ -825,12 +826,10 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host,
825 826
826 /* Memory allocation for framebuffer */ 827 /* Memory allocation for framebuffer */
827 fb_size = SZ_2M; 828 fb_size = SZ_2M;
828 fb_virt = alloc_pages_exact(fb_size, GFP_DMA); 829 fb_virt = dma_alloc_wc(dev, PAGE_ALIGN(fb_size), &fb_phys, GFP_KERNEL);
829 if (!fb_virt) 830 if (!fb_virt)
830 return -ENOMEM; 831 return -ENOMEM;
831 832
832 fb_phys = virt_to_phys(fb_virt);
833
834 fb_info->fix.smem_start = fb_phys; 833 fb_info->fix.smem_start = fb_phys;
835 fb_info->screen_base = fb_virt; 834 fb_info->screen_base = fb_virt;
836 fb_info->screen_size = fb_info->fix.smem_len = fb_size; 835 fb_info->screen_size = fb_info->fix.smem_len = fb_size;
@@ -843,9 +842,11 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host,
843 842
844static void mxsfb_free_videomem(struct mxsfb_info *host) 843static void mxsfb_free_videomem(struct mxsfb_info *host)
845{ 844{
845 struct device *dev = &host->pdev->dev;
846 struct fb_info *fb_info = &host->fb_info; 846 struct fb_info *fb_info = &host->fb_info;
847 847
848 free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len); 848 dma_free_wc(dev, fb_info->screen_size, fb_info->screen_base,
849 fb_info->fix.smem_start);
849} 850}
850 851
851static const struct platform_device_id mxsfb_devtype[] = { 852static const struct platform_device_id mxsfb_devtype[] = {
diff --git a/drivers/video/fbdev/offb.c b/drivers/video/fbdev/offb.c
index fb60a8f0cc94..906c6e75c260 100644
--- a/drivers/video/fbdev/offb.c
+++ b/drivers/video/fbdev/offb.c
@@ -625,6 +625,21 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
625 if (address == OF_BAD_ADDR && addr_prop) 625 if (address == OF_BAD_ADDR && addr_prop)
626 address = (u64)addr_prop; 626 address = (u64)addr_prop;
627 if (address != OF_BAD_ADDR) { 627 if (address != OF_BAD_ADDR) {
628#ifdef CONFIG_PCI
629 const __be32 *vidp, *didp;
630 u32 vid, did;
631 struct pci_dev *pdev;
632
633 vidp = of_get_property(dp, "vendor-id", NULL);
634 didp = of_get_property(dp, "device-id", NULL);
635 if (vidp && didp) {
636 vid = be32_to_cpup(vidp);
637 did = be32_to_cpup(didp);
638 pdev = pci_get_device(vid, did, NULL);
639 if (!pdev || pci_enable_device(pdev))
640 return;
641 }
642#endif
628 /* kludge for valkyrie */ 643 /* kludge for valkyrie */
629 if (strcmp(dp->name, "valkyrie") == 0) 644 if (strcmp(dp->name, "valkyrie") == 0)
630 address += 0x1000; 645 address += 0x1000;
diff --git a/drivers/video/fbdev/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c
index 0e4cee9a8d79..c81f150589e1 100644
--- a/drivers/video/fbdev/omap/lcd_mipid.c
+++ b/drivers/video/fbdev/omap/lcd_mipid.c
@@ -60,7 +60,6 @@ struct mipid_device {
60 struct mutex mutex; 60 struct mutex mutex;
61 struct lcd_panel panel; 61 struct lcd_panel panel;
62 62
63 struct workqueue_struct *esd_wq;
64 struct delayed_work esd_work; 63 struct delayed_work esd_work;
65 void (*esd_check)(struct mipid_device *m); 64 void (*esd_check)(struct mipid_device *m);
66}; 65};
@@ -390,7 +389,7 @@ static void ls041y3_esd_check(struct mipid_device *md)
390static void mipid_esd_start_check(struct mipid_device *md) 389static void mipid_esd_start_check(struct mipid_device *md)
391{ 390{
392 if (md->esd_check != NULL) 391 if (md->esd_check != NULL)
393 queue_delayed_work(md->esd_wq, &md->esd_work, 392 schedule_delayed_work(&md->esd_work,
394 MIPID_ESD_CHECK_PERIOD); 393 MIPID_ESD_CHECK_PERIOD);
395} 394}
396 395
@@ -476,11 +475,6 @@ static int mipid_init(struct lcd_panel *panel,
476 struct mipid_device *md = to_mipid_device(panel); 475 struct mipid_device *md = to_mipid_device(panel);
477 476
478 md->fbdev = fbdev; 477 md->fbdev = fbdev;
479 md->esd_wq = create_singlethread_workqueue("mipid_esd");
480 if (md->esd_wq == NULL) {
481 dev_err(&md->spi->dev, "can't create ESD workqueue\n");
482 return -ENOMEM;
483 }
484 INIT_DELAYED_WORK(&md->esd_work, mipid_esd_work); 478 INIT_DELAYED_WORK(&md->esd_work, mipid_esd_work);
485 mutex_init(&md->mutex); 479 mutex_init(&md->mutex);
486 480
@@ -500,7 +494,6 @@ static void mipid_cleanup(struct lcd_panel *panel)
500 494
501 if (md->enabled) 495 if (md->enabled)
502 mipid_esd_stop_check(md); 496 mipid_esd_stop_check(md);
503 destroy_workqueue(md->esd_wq);
504} 497}
505 498
506static struct lcd_panel mipid_panel = { 499static struct lcd_panel mipid_panel = {
diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c
index b58012b82b6f..8b810696a42b 100644
--- a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c
+++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c
@@ -75,8 +75,6 @@ struct panel_drv_data {
75 75
76 bool intro_printed; 76 bool intro_printed;
77 77
78 struct workqueue_struct *workqueue;
79
80 bool ulps_enabled; 78 bool ulps_enabled;
81 unsigned ulps_timeout; 79 unsigned ulps_timeout;
82 struct delayed_work ulps_work; 80 struct delayed_work ulps_work;
@@ -232,7 +230,7 @@ static int dsicm_set_update_window(struct panel_drv_data *ddata,
232static void dsicm_queue_ulps_work(struct panel_drv_data *ddata) 230static void dsicm_queue_ulps_work(struct panel_drv_data *ddata)
233{ 231{
234 if (ddata->ulps_timeout > 0) 232 if (ddata->ulps_timeout > 0)
235 queue_delayed_work(ddata->workqueue, &ddata->ulps_work, 233 schedule_delayed_work(&ddata->ulps_work,
236 msecs_to_jiffies(ddata->ulps_timeout)); 234 msecs_to_jiffies(ddata->ulps_timeout));
237} 235}
238 236
@@ -1244,11 +1242,6 @@ static int dsicm_probe(struct platform_device *pdev)
1244 dev_dbg(dev, "Using GPIO TE\n"); 1242 dev_dbg(dev, "Using GPIO TE\n");
1245 } 1243 }
1246 1244
1247 ddata->workqueue = create_singlethread_workqueue("dsicm_wq");
1248 if (ddata->workqueue == NULL) {
1249 dev_err(dev, "can't create workqueue\n");
1250 return -ENOMEM;
1251 }
1252 INIT_DELAYED_WORK(&ddata->ulps_work, dsicm_ulps_work); 1245 INIT_DELAYED_WORK(&ddata->ulps_work, dsicm_ulps_work);
1253 1246
1254 dsicm_hw_reset(ddata); 1247 dsicm_hw_reset(ddata);
@@ -1262,7 +1255,7 @@ static int dsicm_probe(struct platform_device *pdev)
1262 dev, ddata, &dsicm_bl_ops, &props); 1255 dev, ddata, &dsicm_bl_ops, &props);
1263 if (IS_ERR(bldev)) { 1256 if (IS_ERR(bldev)) {
1264 r = PTR_ERR(bldev); 1257 r = PTR_ERR(bldev);
1265 goto err_bl; 1258 goto err_reg;
1266 } 1259 }
1267 1260
1268 ddata->bldev = bldev; 1261 ddata->bldev = bldev;
@@ -1285,8 +1278,6 @@ static int dsicm_probe(struct platform_device *pdev)
1285err_sysfs_create: 1278err_sysfs_create:
1286 if (bldev != NULL) 1279 if (bldev != NULL)
1287 backlight_device_unregister(bldev); 1280 backlight_device_unregister(bldev);
1288err_bl:
1289 destroy_workqueue(ddata->workqueue);
1290err_reg: 1281err_reg:
1291 return r; 1282 return r;
1292} 1283}
@@ -1316,7 +1307,6 @@ static int __exit dsicm_remove(struct platform_device *pdev)
1316 omap_dss_put_device(ddata->in); 1307 omap_dss_put_device(ddata->in);
1317 1308
1318 dsicm_cancel_ulps_work(ddata); 1309 dsicm_cancel_ulps_work(ddata);
1319 destroy_workqueue(ddata->workqueue);
1320 1310
1321 /* reset, to be sure that the panel is in a valid state */ 1311 /* reset, to be sure that the panel is in a valid state */
1322 dsicm_hw_reset(ddata); 1312 dsicm_hw_reset(ddata);
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c b/drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c
index 3691bde4ce0a..a864608c5df1 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c
@@ -644,6 +644,7 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
644{ 644{
645 645
646 int r; 646 int r;
647 long time_left;
647 DECLARE_COMPLETION_ONSTACK(completion); 648 DECLARE_COMPLETION_ONSTACK(completion);
648 649
649 r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion, 650 r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
@@ -652,15 +653,15 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
652 if (r) 653 if (r)
653 return r; 654 return r;
654 655
655 timeout = wait_for_completion_interruptible_timeout(&completion, 656 time_left = wait_for_completion_interruptible_timeout(&completion,
656 timeout); 657 timeout);
657 658
658 omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask); 659 omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
659 660
660 if (timeout == 0) 661 if (time_left == 0)
661 return -ETIMEDOUT; 662 return -ETIMEDOUT;
662 663
663 if (timeout == -ERESTARTSYS) 664 if (time_left == -ERESTARTSYS)
664 return -ERESTARTSYS; 665 return -ERESTARTSYS;
665 666
666 return 0; 667 return 0;
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
index 9e4800a4e3d1..30d49f3800b3 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
@@ -1167,7 +1167,6 @@ static int dsi_regulator_init(struct platform_device *dsidev)
1167{ 1167{
1168 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1168 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1169 struct regulator *vdds_dsi; 1169 struct regulator *vdds_dsi;
1170 int r;
1171 1170
1172 if (dsi->vdds_dsi_reg != NULL) 1171 if (dsi->vdds_dsi_reg != NULL)
1173 return 0; 1172 return 0;
@@ -1180,13 +1179,6 @@ static int dsi_regulator_init(struct platform_device *dsidev)
1180 return PTR_ERR(vdds_dsi); 1179 return PTR_ERR(vdds_dsi);
1181 } 1180 }
1182 1181
1183 r = regulator_set_voltage(vdds_dsi, 1800000, 1800000);
1184 if (r) {
1185 devm_regulator_put(vdds_dsi);
1186 DSSERR("can't set the DSI regulator voltage\n");
1187 return r;
1188 }
1189
1190 dsi->vdds_dsi_reg = vdds_dsi; 1182 dsi->vdds_dsi_reg = vdds_dsi;
1191 1183
1192 return 0; 1184 return 0;
@@ -5348,7 +5340,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
5348 5340
5349 dsi->phy_base = devm_ioremap(&dsidev->dev, res->start, 5341 dsi->phy_base = devm_ioremap(&dsidev->dev, res->start,
5350 resource_size(res)); 5342 resource_size(res));
5351 if (!dsi->proto_base) { 5343 if (!dsi->phy_base) {
5352 DSSERR("can't ioremap DSI PHY\n"); 5344 DSSERR("can't ioremap DSI PHY\n");
5353 return -ENOMEM; 5345 return -ENOMEM;
5354 } 5346 }
@@ -5368,7 +5360,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
5368 5360
5369 dsi->pll_base = devm_ioremap(&dsidev->dev, res->start, 5361 dsi->pll_base = devm_ioremap(&dsidev->dev, res->start,
5370 resource_size(res)); 5362 resource_size(res));
5371 if (!dsi->proto_base) { 5363 if (!dsi->pll_base) {
5372 DSSERR("can't ioremap DSI PLL\n"); 5364 DSSERR("can't ioremap DSI PLL\n");
5373 return -ENOMEM; 5365 return -ENOMEM;
5374 } 5366 }
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
index 926a6f20dbb2..156a254705ea 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
@@ -100,7 +100,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
100 100
101static int hdmi_init_regulator(void) 101static int hdmi_init_regulator(void)
102{ 102{
103 int r;
104 struct regulator *reg; 103 struct regulator *reg;
105 104
106 if (hdmi.vdda_reg != NULL) 105 if (hdmi.vdda_reg != NULL)
@@ -114,13 +113,6 @@ static int hdmi_init_regulator(void)
114 return PTR_ERR(reg); 113 return PTR_ERR(reg);
115 } 114 }
116 115
117 r = regulator_set_voltage(reg, 1800000, 1800000);
118 if (r) {
119 devm_regulator_put(reg);
120 DSSWARN("can't set the regulator voltage\n");
121 return r;
122 }
123
124 hdmi.vdda_reg = reg; 116 hdmi.vdda_reg = reg;
125 117
126 return 0; 118 return 0;
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
index 0ee829a165c3..4da36bcab977 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
@@ -119,7 +119,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
119 119
120static int hdmi_init_regulator(void) 120static int hdmi_init_regulator(void)
121{ 121{
122 int r;
123 struct regulator *reg; 122 struct regulator *reg;
124 123
125 if (hdmi.vdda_reg != NULL) 124 if (hdmi.vdda_reg != NULL)
@@ -131,13 +130,6 @@ static int hdmi_init_regulator(void)
131 return PTR_ERR(reg); 130 return PTR_ERR(reg);
132 } 131 }
133 132
134 r = regulator_set_voltage(reg, 1800000, 1800000);
135 if (r) {
136 devm_regulator_put(reg);
137 DSSWARN("can't set the regulator voltage\n");
138 return r;
139 }
140
141 hdmi.vdda_reg = reg; 133 hdmi.vdda_reg = reg;
142 134
143 return 0; 135 return 0;
diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
index aa8d28880912..1a4070f719c2 100644
--- a/drivers/video/fbdev/pm2fb.c
+++ b/drivers/video/fbdev/pm2fb.c
@@ -113,7 +113,7 @@ static struct fb_fix_screeninfo pm2fb_fix = {
113/* 113/*
114 * Default video mode. In case the modedb doesn't work. 114 * Default video mode. In case the modedb doesn't work.
115 */ 115 */
116static struct fb_var_screeninfo pm2fb_var = { 116static const struct fb_var_screeninfo pm2fb_var = {
117 /* "640x480, 8 bpp @ 60 Hz */ 117 /* "640x480, 8 bpp @ 60 Hz */
118 .xres = 640, 118 .xres = 640,
119 .yres = 480, 119 .yres = 480,
diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index 2c0487f4f805..ef73f14d7ba0 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -2125,7 +2125,7 @@ static int of_get_pxafb_display(struct device *dev, struct device_node *disp,
2125 2125
2126 timings = of_get_display_timings(disp); 2126 timings = of_get_display_timings(disp);
2127 if (!timings) 2127 if (!timings)
2128 goto out; 2128 return -EINVAL;
2129 2129
2130 ret = -ENOMEM; 2130 ret = -ENOMEM;
2131 info->modes = kmalloc_array(timings->num_timings, 2131 info->modes = kmalloc_array(timings->num_timings,
@@ -2186,6 +2186,7 @@ static int of_get_pxafb_mode_info(struct device *dev,
2186 ret = of_property_read_u32(np, "bus-width", &bus_width); 2186 ret = of_property_read_u32(np, "bus-width", &bus_width);
2187 if (ret) { 2187 if (ret) {
2188 dev_err(dev, "no bus-width specified: %d\n", ret); 2188 dev_err(dev, "no bus-width specified: %d\n", ret);
2189 of_node_put(np);
2189 return ret; 2190 return ret;
2190 } 2191 }
2191 2192
diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c
index 96aa46dc696c..5d6179ef0298 100644
--- a/drivers/video/fbdev/s1d13xxxfb.c
+++ b/drivers/video/fbdev/s1d13xxxfb.c
@@ -83,7 +83,7 @@ static const char *s1d13xxxfb_prod_names[] = {
83/* 83/*
84 * here we define the default struct fb_fix_screeninfo 84 * here we define the default struct fb_fix_screeninfo
85 */ 85 */
86static struct fb_fix_screeninfo s1d13xxxfb_fix = { 86static const struct fb_fix_screeninfo s1d13xxxfb_fix = {
87 .id = S1D_FBID, 87 .id = S1D_FBID,
88 .type = FB_TYPE_PACKED_PIXELS, 88 .type = FB_TYPE_PACKED_PIXELS,
89 .visual = FB_VISUAL_PSEUDOCOLOR, 89 .visual = FB_VISUAL_PSEUDOCOLOR,
@@ -929,7 +929,7 @@ static int s1d13xxxfb_suspend(struct platform_device *dev, pm_message_t state)
929 s1dfb->disp_save = kmalloc(info->fix.smem_len, GFP_KERNEL); 929 s1dfb->disp_save = kmalloc(info->fix.smem_len, GFP_KERNEL);
930 930
931 if (!s1dfb->disp_save) { 931 if (!s1dfb->disp_save) {
932 printk(KERN_ERR PFX "no memory to save screen"); 932 printk(KERN_ERR PFX "no memory to save screen\n");
933 return -ENOMEM; 933 return -ENOMEM;
934 } 934 }
935 935
diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c
index 0dd86be36afb..a67e4567e656 100644
--- a/drivers/video/fbdev/s3c2410fb.c
+++ b/drivers/video/fbdev/s3c2410fb.c
@@ -767,7 +767,7 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
767 return IRQ_HANDLED; 767 return IRQ_HANDLED;
768} 768}
769 769
770#ifdef CONFIG_CPU_FREQ 770#ifdef CONFIG_ARM_S3C24XX_CPUFREQ
771 771
772static int s3c2410fb_cpufreq_transition(struct notifier_block *nb, 772static int s3c2410fb_cpufreq_transition(struct notifier_block *nb,
773 unsigned long val, void *data) 773 unsigned long val, void *data)
diff --git a/drivers/video/fbdev/s3c2410fb.h b/drivers/video/fbdev/s3c2410fb.h
index 47a17bd23011..cdd11e2f8859 100644
--- a/drivers/video/fbdev/s3c2410fb.h
+++ b/drivers/video/fbdev/s3c2410fb.h
@@ -32,7 +32,7 @@ struct s3c2410fb_info {
32 unsigned long clk_rate; 32 unsigned long clk_rate;
33 unsigned int palette_ready; 33 unsigned int palette_ready;
34 34
35#ifdef CONFIG_CPU_FREQ 35#ifdef CONFIG_ARM_S3C24XX_CPUFREQ
36 struct notifier_block freq_transition; 36 struct notifier_block freq_transition;
37#endif 37#endif
38 38
diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c
index 6c77ab09b0b2..c30a91c1137c 100644
--- a/drivers/video/fbdev/savage/savagefb_driver.c
+++ b/drivers/video/fbdev/savage/savagefb_driver.c
@@ -1660,7 +1660,7 @@ static struct fb_ops savagefb_ops = {
1660 1660
1661/* --------------------------------------------------------------------- */ 1661/* --------------------------------------------------------------------- */
1662 1662
1663static struct fb_var_screeninfo savagefb_var800x600x8 = { 1663static const struct fb_var_screeninfo savagefb_var800x600x8 = {
1664 .accel_flags = FB_ACCELF_TEXT, 1664 .accel_flags = FB_ACCELF_TEXT,
1665 .xres = 800, 1665 .xres = 800,
1666 .yres = 600, 1666 .yres = 600,
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index e9cf19977285..61f799a515dc 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -33,14 +33,14 @@
33#include <linux/parser.h> 33#include <linux/parser.h>
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35 35
36static struct fb_fix_screeninfo simplefb_fix = { 36static const struct fb_fix_screeninfo simplefb_fix = {
37 .id = "simple", 37 .id = "simple",
38 .type = FB_TYPE_PACKED_PIXELS, 38 .type = FB_TYPE_PACKED_PIXELS,
39 .visual = FB_VISUAL_TRUECOLOR, 39 .visual = FB_VISUAL_TRUECOLOR,
40 .accel = FB_ACCEL_NONE, 40 .accel = FB_ACCEL_NONE,
41}; 41};
42 42
43static struct fb_var_screeninfo simplefb_var = { 43static const struct fb_var_screeninfo simplefb_var = {
44 .height = -1, 44 .height = -1,
45 .width = -1, 45 .width = -1,
46 .activate = FB_ACTIVATE_NOW, 46 .activate = FB_ACTIVATE_NOW,
@@ -74,8 +74,14 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
74 return 0; 74 return 0;
75} 75}
76 76
77struct simplefb_par;
78static void simplefb_clocks_destroy(struct simplefb_par *par);
79static void simplefb_regulators_destroy(struct simplefb_par *par);
80
77static void simplefb_destroy(struct fb_info *info) 81static void simplefb_destroy(struct fb_info *info)
78{ 82{
83 simplefb_regulators_destroy(info->par);
84 simplefb_clocks_destroy(info->par);
79 if (info->screen_base) 85 if (info->screen_base)
80 iounmap(info->screen_base); 86 iounmap(info->screen_base);
81} 87}
@@ -487,11 +493,8 @@ error_fb_release:
487static int simplefb_remove(struct platform_device *pdev) 493static int simplefb_remove(struct platform_device *pdev)
488{ 494{
489 struct fb_info *info = platform_get_drvdata(pdev); 495 struct fb_info *info = platform_get_drvdata(pdev);
490 struct simplefb_par *par = info->par;
491 496
492 unregister_framebuffer(info); 497 unregister_framebuffer(info);
493 simplefb_regulators_destroy(par);
494 simplefb_clocks_destroy(par);
495 framebuffer_release(info); 498 framebuffer_release(info);
496 499
497 return 0; 500 return 0;
diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index 86ae1d4556fc..73cb4ffff3c5 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -56,7 +56,7 @@ struct smtcfb_info {
56 56
57void __iomem *smtc_regbaseaddress; /* Memory Map IO starting address */ 57void __iomem *smtc_regbaseaddress; /* Memory Map IO starting address */
58 58
59static struct fb_var_screeninfo smtcfb_var = { 59static const struct fb_var_screeninfo smtcfb_var = {
60 .xres = 1024, 60 .xres = 1024,
61 .yres = 600, 61 .yres = 600,
62 .xres_virtual = 1024, 62 .xres_virtual = 1024,
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 9279e5f6696e..ec2e7e353685 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1761,10 +1761,8 @@ error:
1761static void ufx_usb_disconnect(struct usb_interface *interface) 1761static void ufx_usb_disconnect(struct usb_interface *interface)
1762{ 1762{
1763 struct ufx_data *dev; 1763 struct ufx_data *dev;
1764 struct fb_info *info;
1765 1764
1766 dev = usb_get_intfdata(interface); 1765 dev = usb_get_intfdata(interface);
1767 info = dev->info;
1768 1766
1769 pr_debug("USB disconnect starting\n"); 1767 pr_debug("USB disconnect starting\n");
1770 1768
diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index a9c45c89b15e..2925d5ce8d3e 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -64,7 +64,7 @@ struct ssd1307fb_par {
64 u32 contrast; 64 u32 contrast;
65 u32 dclk_div; 65 u32 dclk_div;
66 u32 dclk_frq; 66 u32 dclk_frq;
67 struct ssd1307fb_deviceinfo *device_info; 67 const struct ssd1307fb_deviceinfo *device_info;
68 struct i2c_client *client; 68 struct i2c_client *client;
69 u32 height; 69 u32 height;
70 struct fb_info *info; 70 struct fb_info *info;
@@ -84,7 +84,7 @@ struct ssd1307fb_array {
84 u8 data[0]; 84 u8 data[0];
85}; 85};
86 86
87static struct fb_fix_screeninfo ssd1307fb_fix = { 87static const struct fb_fix_screeninfo ssd1307fb_fix = {
88 .id = "Solomon SSD1307", 88 .id = "Solomon SSD1307",
89 .type = FB_TYPE_PACKED_PIXELS, 89 .type = FB_TYPE_PACKED_PIXELS,
90 .visual = FB_VISUAL_MONO10, 90 .visual = FB_VISUAL_MONO10,
@@ -94,7 +94,7 @@ static struct fb_fix_screeninfo ssd1307fb_fix = {
94 .accel = FB_ACCEL_NONE, 94 .accel = FB_ACCEL_NONE,
95}; 95};
96 96
97static struct fb_var_screeninfo ssd1307fb_var = { 97static const struct fb_var_screeninfo ssd1307fb_var = {
98 .bits_per_pixel = 1, 98 .bits_per_pixel = 1,
99}; 99};
100 100
@@ -559,8 +559,7 @@ static int ssd1307fb_probe(struct i2c_client *client,
559 par->info = info; 559 par->info = info;
560 par->client = client; 560 par->client = client;
561 561
562 par->device_info = (struct ssd1307fb_deviceinfo *)of_match_device( 562 par->device_info = of_device_get_match_data(&client->dev);
563 ssd1307fb_of_match, &client->dev)->data;
564 563
565 par->reset = of_get_named_gpio(client->dev.of_node, 564 par->reset = of_get_named_gpio(client->dev.of_node,
566 "reset-gpios", 0); 565 "reset-gpios", 0);
diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c
index 621fa441a6db..d5fa313806fe 100644
--- a/drivers/video/fbdev/tdfxfb.c
+++ b/drivers/video/fbdev/tdfxfb.c
@@ -82,7 +82,7 @@
82#define VOODOO3_MAX_PIXCLOCK 300000 82#define VOODOO3_MAX_PIXCLOCK 300000
83#define VOODOO5_MAX_PIXCLOCK 350000 83#define VOODOO5_MAX_PIXCLOCK 350000
84 84
85static struct fb_fix_screeninfo tdfx_fix = { 85static const struct fb_fix_screeninfo tdfx_fix = {
86 .type = FB_TYPE_PACKED_PIXELS, 86 .type = FB_TYPE_PACKED_PIXELS,
87 .visual = FB_VISUAL_PSEUDOCOLOR, 87 .visual = FB_VISUAL_PSEUDOCOLOR,
88 .ypanstep = 1, 88 .ypanstep = 1,
@@ -90,7 +90,7 @@ static struct fb_fix_screeninfo tdfx_fix = {
90 .accel = FB_ACCEL_3DFX_BANSHEE 90 .accel = FB_ACCEL_3DFX_BANSHEE
91}; 91};
92 92
93static struct fb_var_screeninfo tdfx_var = { 93static const struct fb_var_screeninfo tdfx_var = {
94 /* "640x480, 8 bpp @ 60 Hz */ 94 /* "640x480, 8 bpp @ 60 Hz */
95 .xres = 640, 95 .xres = 640,
96 .yres = 480, 96 .yres = 480,
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 178ae93b7ebd..98af9e02959b 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -33,7 +33,7 @@ static struct cb_id uvesafb_cn_id = {
33static char v86d_path[PATH_MAX] = "/sbin/v86d"; 33static char v86d_path[PATH_MAX] = "/sbin/v86d";
34static char v86d_started; /* has v86d been started by uvesafb? */ 34static char v86d_started; /* has v86d been started by uvesafb? */
35 35
36static struct fb_fix_screeninfo uvesafb_fix = { 36static const struct fb_fix_screeninfo uvesafb_fix = {
37 .id = "VESA VGA", 37 .id = "VESA VGA",
38 .type = FB_TYPE_PACKED_PIXELS, 38 .type = FB_TYPE_PACKED_PIXELS,
39 .accel = FB_ACCEL_NONE, 39 .accel = FB_ACCEL_NONE,
diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
index b9c2f81fb6b9..da653a080394 100644
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -35,76 +35,23 @@
35static void *videomemory; 35static void *videomemory;
36static u_long videomemorysize = VIDEOMEMSIZE; 36static u_long videomemorysize = VIDEOMEMSIZE;
37module_param(videomemorysize, ulong, 0); 37module_param(videomemorysize, ulong, 0);
38MODULE_PARM_DESC(videomemorysize, "RAM available to frame buffer (in bytes)");
38 39
39/********************************************************************** 40static char *mode_option = NULL;
40 * 41module_param(mode_option, charp, 0);
41 * Memory management 42MODULE_PARM_DESC(mode_option, "Preferred video mode (e.g. 640x480-8@60)");
42 *
43 **********************************************************************/
44static void *rvmalloc(unsigned long size)
45{
46 void *mem;
47 unsigned long adr;
48
49 size = PAGE_ALIGN(size);
50 mem = vmalloc_32(size);
51 if (!mem)
52 return NULL;
53
54 /*
55 * VFB must clear memory to prevent kernel info
56 * leakage into userspace
57 * VGA-based drivers MUST NOT clear memory if
58 * they want to be able to take over vgacon
59 */
60
61 memset(mem, 0, size);
62 adr = (unsigned long) mem;
63 while (size > 0) {
64 SetPageReserved(vmalloc_to_page((void *)adr));
65 adr += PAGE_SIZE;
66 size -= PAGE_SIZE;
67 }
68
69 return mem;
70}
71
72static void rvfree(void *mem, unsigned long size)
73{
74 unsigned long adr;
75
76 if (!mem)
77 return;
78
79 adr = (unsigned long) mem;
80 while ((long) size > 0) {
81 ClearPageReserved(vmalloc_to_page((void *)adr));
82 adr += PAGE_SIZE;
83 size -= PAGE_SIZE;
84 }
85 vfree(mem);
86}
87 43
88static struct fb_var_screeninfo vfb_default = { 44static const struct fb_videomode vfb_default = {
89 .xres = 640, 45 .xres = 640,
90 .yres = 480, 46 .yres = 480,
91 .xres_virtual = 640, 47 .pixclock = 20000,
92 .yres_virtual = 480, 48 .left_margin = 64,
93 .bits_per_pixel = 8, 49 .right_margin = 64,
94 .red = { 0, 8, 0 }, 50 .upper_margin = 32,
95 .green = { 0, 8, 0 }, 51 .lower_margin = 32,
96 .blue = { 0, 8, 0 }, 52 .hsync_len = 64,
97 .activate = FB_ACTIVATE_TEST, 53 .vsync_len = 2,
98 .height = -1, 54 .vmode = FB_VMODE_NONINTERLACED,
99 .width = -1,
100 .pixclock = 20000,
101 .left_margin = 64,
102 .right_margin = 64,
103 .upper_margin = 32,
104 .lower_margin = 32,
105 .hsync_len = 64,
106 .vsync_len = 2,
107 .vmode = FB_VMODE_NONINTERLACED,
108}; 55};
109 56
110static struct fb_fix_screeninfo vfb_fix = { 57static struct fb_fix_screeninfo vfb_fix = {
@@ -119,6 +66,7 @@ static struct fb_fix_screeninfo vfb_fix = {
119 66
120static bool vfb_enable __initdata = 0; /* disabled by default */ 67static bool vfb_enable __initdata = 0; /* disabled by default */
121module_param(vfb_enable, bool, 0); 68module_param(vfb_enable, bool, 0);
69MODULE_PARM_DESC(vfb_enable, "Enable Virtual FB driver");
122 70
123static int vfb_check_var(struct fb_var_screeninfo *var, 71static int vfb_check_var(struct fb_var_screeninfo *var,
124 struct fb_info *info); 72 struct fb_info *info);
@@ -421,35 +369,7 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
421static int vfb_mmap(struct fb_info *info, 369static int vfb_mmap(struct fb_info *info,
422 struct vm_area_struct *vma) 370 struct vm_area_struct *vma)
423{ 371{
424 unsigned long start = vma->vm_start; 372 return remap_vmalloc_range(vma, (void *)info->fix.smem_start, vma->vm_pgoff);
425 unsigned long size = vma->vm_end - vma->vm_start;
426 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
427 unsigned long page, pos;
428
429 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
430 return -EINVAL;
431 if (size > info->fix.smem_len)
432 return -EINVAL;
433 if (offset > info->fix.smem_len - size)
434 return -EINVAL;
435
436 pos = (unsigned long)info->fix.smem_start + offset;
437
438 while (size > 0) {
439 page = vmalloc_to_pfn((void *)pos);
440 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
441 return -EAGAIN;
442 }
443 start += PAGE_SIZE;
444 pos += PAGE_SIZE;
445 if (size > PAGE_SIZE)
446 size -= PAGE_SIZE;
447 else
448 size = 0;
449 }
450
451 return 0;
452
453} 373}
454 374
455#ifndef MODULE 375#ifndef MODULE
@@ -477,6 +397,8 @@ static int __init vfb_setup(char *options)
477 /* Test disable for backwards compatibility */ 397 /* Test disable for backwards compatibility */
478 if (!strcmp(this_opt, "disable")) 398 if (!strcmp(this_opt, "disable"))
479 vfb_enable = 0; 399 vfb_enable = 0;
400 else
401 mode_option = this_opt;
480 } 402 }
481 return 1; 403 return 1;
482} 404}
@@ -489,12 +411,13 @@ static int __init vfb_setup(char *options)
489static int vfb_probe(struct platform_device *dev) 411static int vfb_probe(struct platform_device *dev)
490{ 412{
491 struct fb_info *info; 413 struct fb_info *info;
414 unsigned int size = PAGE_ALIGN(videomemorysize);
492 int retval = -ENOMEM; 415 int retval = -ENOMEM;
493 416
494 /* 417 /*
495 * For real video cards we use ioremap. 418 * For real video cards we use ioremap.
496 */ 419 */
497 if (!(videomemory = rvmalloc(videomemorysize))) 420 if (!(videomemory = vmalloc_32_user(size)))
498 return retval; 421 return retval;
499 422
500 info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev); 423 info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
@@ -504,11 +427,13 @@ static int vfb_probe(struct platform_device *dev)
504 info->screen_base = (char __iomem *)videomemory; 427 info->screen_base = (char __iomem *)videomemory;
505 info->fbops = &vfb_ops; 428 info->fbops = &vfb_ops;
506 429
507 retval = fb_find_mode(&info->var, info, NULL, 430 if (!fb_find_mode(&info->var, info, mode_option,
508 NULL, 0, NULL, 8); 431 NULL, 0, &vfb_default, 8)){
432 fb_err(info, "Unable to find usable video mode.\n");
433 retval = -EINVAL;
434 goto err1;
435 }
509 436
510 if (!retval || (retval == 4))
511 info->var = vfb_default;
512 vfb_fix.smem_start = (unsigned long) videomemory; 437 vfb_fix.smem_start = (unsigned long) videomemory;
513 vfb_fix.smem_len = videomemorysize; 438 vfb_fix.smem_len = videomemorysize;
514 info->fix = vfb_fix; 439 info->fix = vfb_fix;
@@ -533,7 +458,7 @@ err2:
533err1: 458err1:
534 framebuffer_release(info); 459 framebuffer_release(info);
535err: 460err:
536 rvfree(videomemory, videomemorysize); 461 vfree(videomemory);
537 return retval; 462 return retval;
538} 463}
539 464
@@ -543,7 +468,7 @@ static int vfb_remove(struct platform_device *dev)
543 468
544 if (info) { 469 if (info) {
545 unregister_framebuffer(info); 470 unregister_framebuffer(info);
546 rvfree(videomemory, videomemorysize); 471 vfree(videomemory);
547 fb_dealloc_cmap(&info->cmap); 472 fb_dealloc_cmap(&info->cmap);
548 framebuffer_release(info); 473 framebuffer_release(info);
549 } 474 }
diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c
index 283d335a759f..5f0690c8fc93 100644
--- a/drivers/video/fbdev/vga16fb.c
+++ b/drivers/video/fbdev/vga16fb.c
@@ -85,7 +85,7 @@ static struct fb_var_screeninfo vga16fb_defined = {
85}; 85};
86 86
87/* name should not depend on EGA/VGA */ 87/* name should not depend on EGA/VGA */
88static struct fb_fix_screeninfo vga16fb_fix = { 88static const struct fb_fix_screeninfo vga16fb_fix = {
89 .id = "VGA16 VGA", 89 .id = "VGA16 VGA",
90 .smem_start = VGA_FB_PHYS, 90 .smem_start = VGA_FB_PHYS,
91 .smem_len = VGA_FB_PHYS_LEN, 91 .smem_len = VGA_FB_PHYS_LEN,
diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h
index e82e3ee2c54a..1035879b322c 100644
--- a/include/linux/amba/clcd.h
+++ b/include/linux/amba/clcd.h
@@ -67,6 +67,17 @@
67#define CNTL_LDMAFIFOTIME (1 << 15) 67#define CNTL_LDMAFIFOTIME (1 << 15)
68#define CNTL_WATERMARK (1 << 16) 68#define CNTL_WATERMARK (1 << 16)
69 69
70/* ST Microelectronics variant bits */
71#define CNTL_ST_1XBPP_444 0x0
72#define CNTL_ST_1XBPP_5551 (1 << 17)
73#define CNTL_ST_1XBPP_565 (1 << 18)
74#define CNTL_ST_CDWID_12 0x0
75#define CNTL_ST_CDWID_16 (1 << 19)
76#define CNTL_ST_CDWID_18 (1 << 20)
77#define CNTL_ST_CDWID_24 ((1 << 19)|(1 << 20))
78#define CNTL_ST_CEAEN (1 << 21)
79#define CNTL_ST_LCDBPP24_PACKED (6 << 1)
80
70enum { 81enum {
71 /* individual formats */ 82 /* individual formats */
72 CLCD_CAP_RGB444 = (1 << 0), 83 CLCD_CAP_RGB444 = (1 << 0),
@@ -93,6 +104,8 @@ enum {
93 CLCD_CAP_ALL = CLCD_CAP_BGR | CLCD_CAP_RGB, 104 CLCD_CAP_ALL = CLCD_CAP_BGR | CLCD_CAP_RGB,
94}; 105};
95 106
107struct backlight_device;
108
96struct clcd_panel { 109struct clcd_panel {
97 struct fb_videomode mode; 110 struct fb_videomode mode;
98 signed short width; /* width in mm */ 111 signed short width; /* width in mm */
@@ -105,6 +118,13 @@ struct clcd_panel {
105 fixedtimings:1, 118 fixedtimings:1,
106 grayscale:1; 119 grayscale:1;
107 unsigned int connector; 120 unsigned int connector;
121 struct backlight_device *backlight;
122 /*
123 * If the B/R lines are switched between the CLCD
124 * and the panel we need to know this and not try to
125 * compensate with the BGR bit in the control register.
126 */
127 bool bgr_connection;
108}; 128};
109 129
110struct clcd_regs { 130struct clcd_regs {
@@ -170,11 +190,38 @@ struct clcd_board {
170struct amba_device; 190struct amba_device;
171struct clk; 191struct clk;
172 192
193/**
194 * struct clcd_vendor_data - holds hardware (IP-block) vendor-specific
195 * variant information
196 *
197 * @clock_timregs: the CLCD needs to be clocked when accessing the
198 * timer registers, or the hardware will hang.
199 * @packed_24_bit_pixels: this variant supports 24bit packed pixel data,
200 * so that RGB accesses 3 bytes at a time, not just on even 32bit
201 * boundaries, packing the pixel data in memory. ST Microelectronics
202 * have this.
203 * @st_bitmux_control: ST Microelectronics have implemented output
204 * bit line multiplexing into the CLCD control register. This indicates
205 * that we need to use this.
206 * @init_board: custom board init function for this variant
207 * @init_panel: custom panel init function for this variant
208 */
209struct clcd_vendor_data {
210 bool clock_timregs;
211 bool packed_24_bit_pixels;
212 bool st_bitmux_control;
213 int (*init_board)(struct amba_device *adev,
214 struct clcd_board *board);
215 int (*init_panel)(struct clcd_fb *fb,
216 struct device_node *panel);
217};
218
173/* this data structure describes each frame buffer device we find */ 219/* this data structure describes each frame buffer device we find */
174struct clcd_fb { 220struct clcd_fb {
175 struct fb_info fb; 221 struct fb_info fb;
176 struct amba_device *dev; 222 struct amba_device *dev;
177 struct clk *clk; 223 struct clk *clk;
224 struct clcd_vendor_data *vendor;
178 struct clcd_panel *panel; 225 struct clcd_panel *panel;
179 struct clcd_board *board; 226 struct clcd_board *board;
180 void *board_data; 227 void *board_data;
@@ -231,16 +278,22 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
231 if (var->grayscale) 278 if (var->grayscale)
232 val |= CNTL_LCDBW; 279 val |= CNTL_LCDBW;
233 280
234 if (fb->panel->caps && fb->board->caps && 281 if (fb->panel->caps && fb->board->caps && var->bits_per_pixel >= 16) {
235 var->bits_per_pixel >= 16) {
236 /* 282 /*
237 * if board and panel supply capabilities, we can support 283 * if board and panel supply capabilities, we can support
238 * changing BGR/RGB depending on supplied parameters 284 * changing BGR/RGB depending on supplied parameters. Here
285 * we switch to what the framebuffer is providing if need
286 * be, so if the framebuffer is BGR but the display connection
287 * is RGB (first case) we switch it around. Vice versa mutatis
288 * mutandis if the framebuffer is RGB but the display connection
289 * is BGR, we flip it around.
239 */ 290 */
240 if (var->red.offset == 0) 291 if (var->red.offset == 0)
241 val &= ~CNTL_BGR; 292 val &= ~CNTL_BGR;
242 else 293 else
243 val |= CNTL_BGR; 294 val |= CNTL_BGR;
295 if (fb->panel->bgr_connection)
296 val ^= CNTL_BGR;
244 } 297 }
245 298
246 switch (var->bits_per_pixel) { 299 switch (var->bits_per_pixel) {
@@ -270,6 +323,10 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
270 else 323 else
271 val |= CNTL_LCDBPP16_444; 324 val |= CNTL_LCDBPP16_444;
272 break; 325 break;
326 case 24:
327 /* Modified variant supporting 24 bit packed pixels */
328 val |= CNTL_ST_LCDBPP24_PACKED;
329 break;
273 case 32: 330 case 32:
274 val |= CNTL_LCDBPP24; 331 val |= CNTL_LCDBPP24;
275 break; 332 break;
diff --git a/include/video/exynos_mipi_dsim.h b/include/video/exynos_mipi_dsim.h
deleted file mode 100644
index 6a578f8a1b3e..000000000000
--- a/include/video/exynos_mipi_dsim.h
+++ /dev/null
@@ -1,358 +0,0 @@
1/* include/video/exynos_mipi_dsim.h
2 *
3 * Platform data header for Samsung SoC MIPI-DSIM.
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd
6 *
7 * InKi Dae <inki.dae@samsung.com>
8 * Donghwa Lee <dh09.lee@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef _EXYNOS_MIPI_DSIM_H
16#define _EXYNOS_MIPI_DSIM_H
17
18#include <linux/device.h>
19#include <linux/fb.h>
20
21#define PANEL_NAME_SIZE (32)
22
23/*
24 * Enumerate display interface type.
25 *
26 * DSIM_COMMAND means cpu interface and rgb interface for DSIM_VIDEO.
27 *
28 * P.S. MIPI DSI Master has two display controller intefaces, RGB Interface
29 * for main display and CPU Interface(same as I80 Interface) for main
30 * and sub display.
31 */
32enum mipi_dsim_interface_type {
33 DSIM_COMMAND,
34 DSIM_VIDEO
35};
36
37enum mipi_dsim_virtual_ch_no {
38 DSIM_VIRTUAL_CH_0,
39 DSIM_VIRTUAL_CH_1,
40 DSIM_VIRTUAL_CH_2,
41 DSIM_VIRTUAL_CH_3
42};
43
44enum mipi_dsim_burst_mode_type {
45 DSIM_NON_BURST_SYNC_EVENT,
46 DSIM_BURST_SYNC_EVENT,
47 DSIM_NON_BURST_SYNC_PULSE,
48 DSIM_BURST,
49 DSIM_NON_VIDEO_MODE
50};
51
52enum mipi_dsim_no_of_data_lane {
53 DSIM_DATA_LANE_1,
54 DSIM_DATA_LANE_2,
55 DSIM_DATA_LANE_3,
56 DSIM_DATA_LANE_4
57};
58
59enum mipi_dsim_byte_clk_src {
60 DSIM_PLL_OUT_DIV8,
61 DSIM_EXT_CLK_DIV8,
62 DSIM_EXT_CLK_BYPASS
63};
64
65enum mipi_dsim_pixel_format {
66 DSIM_CMD_3BPP,
67 DSIM_CMD_8BPP,
68 DSIM_CMD_12BPP,
69 DSIM_CMD_16BPP,
70 DSIM_VID_16BPP_565,
71 DSIM_VID_18BPP_666PACKED,
72 DSIM_18BPP_666LOOSELYPACKED,
73 DSIM_24BPP_888
74};
75
76/*
77 * struct mipi_dsim_config - interface for configuring mipi-dsi controller.
78 *
79 * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse.
80 * @eot_disable: enable or disable EoT packet in HS mode.
81 * @auto_vertical_cnt: specifies auto vertical count mode.
82 * in Video mode, the vertical line transition uses line counter
83 * configured by VSA, VBP, and Vertical resolution.
84 * If this bit is set to '1', the line counter does not use VSA and VBP
85 * registers.(in command mode, this variable is ignored)
86 * @hse: set horizontal sync event mode.
87 * In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC
88 * start packet to MIPI DSI slave at MIPI DSI spec1.1r02.
89 * this bit transfers HSYNC end packet in VSYNC pulse and Vporch area
90 * (in mommand mode, this variable is ignored)
91 * @hfp: specifies HFP disable mode.
92 * if this variable is set, DSI master ignores HFP area in VIDEO mode.
93 * (in command mode, this variable is ignored)
94 * @hbp: specifies HBP disable mode.
95 * if this variable is set, DSI master ignores HBP area in VIDEO mode.
96 * (in command mode, this variable is ignored)
97 * @hsa: specifies HSA disable mode.
98 * if this variable is set, DSI master ignores HSA area in VIDEO mode.
99 * (in command mode, this variable is ignored)
100 * @cma_allow: specifies the number of horizontal lines, where command packet
101 * transmission is allowed after Stable VFP period.
102 * @e_interface: specifies interface to be used.(CPU or RGB interface)
103 * @e_virtual_ch: specifies virtual channel number that main or
104 * sub diaplsy uses.
105 * @e_pixel_format: specifies pixel stream format for main or sub display.
106 * @e_burst_mode: selects Burst mode in Video mode.
107 * in Non-burst mode, RGB data area is filled with RGB data and NULL
108 * packets, according to input bandwidth of RGB interface.
109 * In Burst mode, RGB data area is filled with RGB data only.
110 * @e_no_data_lane: specifies data lane count to be used by Master.
111 * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8)
112 * DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported.
113 * @pll_stable_time: specifies the PLL Timer for stability of the ganerated
114 * clock(System clock cycle base)
115 * if the timer value goes to 0x00000000, the clock stable bit of status
116 * and interrupt register is set.
117 * @esc_clk: specifies escape clock frequency for getting the escape clock
118 * prescaler value.
119 * @stop_holding_cnt: specifies the interval value between transmitting
120 * read packet(or write "set_tear_on" command) and BTA request.
121 * after transmitting read packet or write "set_tear_on" command,
122 * BTA requests to D-PHY automatically. this counter value specifies
123 * the interval between them.
124 * @bta_timeout: specifies the timer for BTA.
125 * this register specifies time out from BTA request to change
126 * the direction with respect to Tx escape clock.
127 * @rx_timeout: specifies the timer for LP Rx mode timeout.
128 * this register specifies time out on how long RxValid deasserts,
129 * after RxLpdt asserts with respect to Tx escape clock.
130 * - RxValid specifies Rx data valid indicator.
131 * - RxLpdt specifies an indicator that D-PHY is under RxLpdt mode.
132 * - RxValid and RxLpdt specifies signal from D-PHY.
133 */
134struct mipi_dsim_config {
135 unsigned char auto_flush;
136 unsigned char eot_disable;
137
138 unsigned char auto_vertical_cnt;
139 unsigned char hse;
140 unsigned char hfp;
141 unsigned char hbp;
142 unsigned char hsa;
143 unsigned char cmd_allow;
144
145 enum mipi_dsim_interface_type e_interface;
146 enum mipi_dsim_virtual_ch_no e_virtual_ch;
147 enum mipi_dsim_pixel_format e_pixel_format;
148 enum mipi_dsim_burst_mode_type e_burst_mode;
149 enum mipi_dsim_no_of_data_lane e_no_data_lane;
150 enum mipi_dsim_byte_clk_src e_byte_clk;
151
152 /*
153 * ===========================================
154 * | P | M | S | MHz |
155 * -------------------------------------------
156 * | 3 | 100 | 3 | 100 |
157 * | 3 | 100 | 2 | 200 |
158 * | 3 | 63 | 1 | 252 |
159 * | 4 | 100 | 1 | 300 |
160 * | 4 | 110 | 1 | 330 |
161 * | 12 | 350 | 1 | 350 |
162 * | 3 | 100 | 1 | 400 |
163 * | 4 | 150 | 1 | 450 |
164 * | 6 | 118 | 1 | 472 |
165 * | 3 | 120 | 1 | 480 |
166 * | 12 | 250 | 0 | 500 |
167 * | 4 | 100 | 0 | 600 |
168 * | 3 | 81 | 0 | 648 |
169 * | 3 | 88 | 0 | 704 |
170 * | 3 | 90 | 0 | 720 |
171 * | 3 | 100 | 0 | 800 |
172 * | 12 | 425 | 0 | 850 |
173 * | 4 | 150 | 0 | 900 |
174 * | 12 | 475 | 0 | 950 |
175 * | 6 | 250 | 0 | 1000 |
176 * -------------------------------------------
177 */
178
179 /*
180 * pms could be calculated as the following.
181 * M * 24 / P * 2 ^ S = MHz
182 */
183 unsigned char p;
184 unsigned short m;
185 unsigned char s;
186
187 unsigned int pll_stable_time;
188 unsigned long esc_clk;
189
190 unsigned short stop_holding_cnt;
191 unsigned char bta_timeout;
192 unsigned short rx_timeout;
193};
194
195/*
196 * struct mipi_dsim_device - global interface for mipi-dsi driver.
197 *
198 * @dev: driver model representation of the device.
199 * @id: unique device id.
200 * @clock: pointer to MIPI-DSI clock of clock framework.
201 * @irq: interrupt number to MIPI-DSI controller.
202 * @reg_base: base address to memory mapped SRF of MIPI-DSI controller.
203 * (virtual address)
204 * @lock: the mutex protecting this data structure.
205 * @dsim_info: infomation for configuring mipi-dsi controller.
206 * @master_ops: callbacks to mipi-dsi operations.
207 * @dsim_lcd_dev: pointer to activated ddi device.
208 * (it would be registered by mipi-dsi driver.)
209 * @dsim_lcd_drv: pointer to activated_ddi driver.
210 * (it would be registered by mipi-dsi driver.)
211 * @lcd_info: pointer to mipi_lcd_info structure.
212 * @state: specifies status of MIPI-DSI controller.
213 * the status could be RESET, INIT, STOP, HSCLKEN and ULPS.
214 * @data_lane: specifiec enabled data lane number.
215 * this variable would be set by driver according to e_no_data_lane
216 * automatically.
217 * @e_clk_src: select byte clock source.
218 * @pd: pointer to MIPI-DSI driver platform data.
219 * @phy: pointer to the MIPI-DSI PHY
220 */
221struct mipi_dsim_device {
222 struct device *dev;
223 int id;
224 struct clk *clock;
225 unsigned int irq;
226 void __iomem *reg_base;
227 struct mutex lock;
228
229 struct mipi_dsim_config *dsim_config;
230 struct mipi_dsim_master_ops *master_ops;
231 struct mipi_dsim_lcd_device *dsim_lcd_dev;
232 struct mipi_dsim_lcd_driver *dsim_lcd_drv;
233
234 unsigned int state;
235 unsigned int data_lane;
236 unsigned int e_clk_src;
237 bool suspended;
238
239 struct mipi_dsim_platform_data *pd;
240 struct phy *phy;
241};
242
243/*
244 * struct mipi_dsim_platform_data - interface to platform data
245 * for mipi-dsi driver.
246 *
247 * @lcd_panel_name: specifies lcd panel name registered to mipi-dsi driver.
248 * lcd panel driver searched would be actived.
249 * @dsim_config: pointer of structure for configuring mipi-dsi controller.
250 * @enabled: indicate whether mipi controller got enabled or not.
251 * @lcd_panel_info: pointer for lcd panel specific structure.
252 * this structure specifies width, height, timing and polarity and so on.
253 */
254struct mipi_dsim_platform_data {
255 char lcd_panel_name[PANEL_NAME_SIZE];
256
257 struct mipi_dsim_config *dsim_config;
258 unsigned int enabled;
259 void *lcd_panel_info;
260};
261
262/*
263 * struct mipi_dsim_master_ops - callbacks to mipi-dsi operations.
264 *
265 * @cmd_write: transfer command to lcd panel at LP mode.
266 * @cmd_read: read command from rx register.
267 * @get_dsim_frame_done: get the status that all screen data have been
268 * transferred to mipi-dsi.
269 * @clear_dsim_frame_done: clear frame done status.
270 * @get_fb_frame_done: get frame done status of display controller.
271 * @trigger: trigger display controller.
272 * - this one would be used only in case of CPU mode.
273 * @set_early_blank_mode: set framebuffer blank mode.
274 * - this callback should be called prior to fb_blank() by a client driver
275 * only if needing.
276 * @set_blank_mode: set framebuffer blank mode.
277 * - this callback should be called after fb_blank() by a client driver
278 * only if needing.
279 */
280
281struct mipi_dsim_master_ops {
282 int (*cmd_write)(struct mipi_dsim_device *dsim, unsigned int data_id,
283 const unsigned char *data0, unsigned int data1);
284 int (*cmd_read)(struct mipi_dsim_device *dsim, unsigned int data_id,
285 unsigned int data0, unsigned int req_size, u8 *rx_buf);
286 int (*get_dsim_frame_done)(struct mipi_dsim_device *dsim);
287 int (*clear_dsim_frame_done)(struct mipi_dsim_device *dsim);
288
289 int (*get_fb_frame_done)(struct fb_info *info);
290 void (*trigger)(struct fb_info *info);
291 int (*set_early_blank_mode)(struct mipi_dsim_device *dsim, int power);
292 int (*set_blank_mode)(struct mipi_dsim_device *dsim, int power);
293};
294
295/*
296 * device structure for mipi-dsi based lcd panel.
297 *
298 * @name: name of the device to use with this device, or an
299 * alias for that name.
300 * @dev: driver model representation of the device.
301 * @id: id of device to be registered.
302 * @bus_id: bus id for identifing connected bus
303 * and this bus id should be same as id of mipi_dsim_device.
304 * @irq: irq number for signaling when framebuffer transfer of
305 * lcd panel module is completed.
306 * this irq would be used only for MIPI-DSI based CPU mode lcd panel.
307 * @master: pointer to mipi-dsi master device object.
308 * @platform_data: lcd panel specific platform data.
309 */
310struct mipi_dsim_lcd_device {
311 char *name;
312 struct device dev;
313 int id;
314 int bus_id;
315 int irq;
316 int panel_reverse;
317
318 struct mipi_dsim_device *master;
319 void *platform_data;
320};
321
322/*
323 * driver structure for mipi-dsi based lcd panel.
324 *
325 * this structure should be registered by lcd panel driver.
326 * mipi-dsi driver seeks lcd panel registered through name field
327 * and calls these callback functions in appropriate time.
328 *
329 * @name: name of the driver to use with this device, or an
330 * alias for that name.
331 * @id: id of driver to be registered.
332 * this id would be used for finding device object registered.
333 */
334struct mipi_dsim_lcd_driver {
335 char *name;
336 int id;
337
338 void (*power_on)(struct mipi_dsim_lcd_device *dsim_dev, int enable);
339 void (*set_sequence)(struct mipi_dsim_lcd_device *dsim_dev);
340 int (*probe)(struct mipi_dsim_lcd_device *dsim_dev);
341 int (*remove)(struct mipi_dsim_lcd_device *dsim_dev);
342 void (*shutdown)(struct mipi_dsim_lcd_device *dsim_dev);
343 int (*suspend)(struct mipi_dsim_lcd_device *dsim_dev);
344 int (*resume)(struct mipi_dsim_lcd_device *dsim_dev);
345};
346
347/*
348 * register mipi_dsim_lcd_device to mipi-dsi master.
349 */
350int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device
351 *lcd_dev);
352/**
353 * register mipi_dsim_lcd_driver object defined by lcd panel driver
354 * to mipi-dsi driver.
355 */
356int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver
357 *lcd_drv);
358#endif /* _EXYNOS_MIPI_DSIM_H */