aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig15
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/backlight/88pm860x_bl.c5
-rw-r--r--drivers/video/backlight/Kconfig24
-rw-r--r--drivers/video/backlight/Makefile89
-rw-r--r--drivers/video/backlight/aat2870_bl.c2
-rw-r--r--drivers/video/backlight/adp8860_bl.c2
-rw-r--r--drivers/video/backlight/adp8870_bl.c2
-rw-r--r--drivers/video/backlight/ams369fg06.c104
-rw-r--r--drivers/video/backlight/as3711_bl.c380
-rw-r--r--drivers/video/backlight/corgi_lcd.c18
-rw-r--r--drivers/video/backlight/hx8357.c497
-rw-r--r--drivers/video/backlight/l4f00242t03.c36
-rw-r--r--drivers/video/backlight/ld9040.c109
-rw-r--r--drivers/video/backlight/lm3630_bl.c4
-rw-r--r--drivers/video/backlight/lm3639_bl.c5
-rw-r--r--drivers/video/backlight/lms283gf05.c4
-rw-r--r--drivers/video/backlight/lms501kf03.c441
-rw-r--r--drivers/video/backlight/lp855x_bl.c169
-rw-r--r--drivers/video/backlight/ltv350qv.c10
-rw-r--r--drivers/video/backlight/omap1_bl.c10
-rw-r--r--drivers/video/backlight/pwm_bl.c8
-rw-r--r--drivers/video/backlight/s6e63m0.c153
-rw-r--r--drivers/video/backlight/tdo24m.c10
-rw-r--r--drivers/video/backlight/tosa_bl.c2
-rw-r--r--drivers/video/backlight/tosa_lcd.c12
-rw-r--r--drivers/video/backlight/vgg2432a4.c9
-rw-r--r--drivers/video/console/fbcon.c10
-rw-r--r--drivers/video/exynos/exynos_dp_core.c23
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi.c70
-rw-r--r--drivers/video/exynos/s6e8ax0.c14
-rw-r--r--drivers/video/goldfishfb.c318
-rw-r--r--drivers/video/mmp/Kconfig11
-rw-r--r--drivers/video/mmp/Makefile1
-rw-r--r--drivers/video/mmp/core.c258
-rw-r--r--drivers/video/mmp/fb/Kconfig13
-rw-r--r--drivers/video/mmp/fb/Makefile1
-rw-r--r--drivers/video/mmp/fb/mmpfb.c685
-rw-r--r--drivers/video/mmp/fb/mmpfb.h54
-rw-r--r--drivers/video/mmp/hw/Kconfig20
-rw-r--r--drivers/video/mmp/hw/Makefile2
-rw-r--r--drivers/video/mmp/hw/mmp_ctrl.c591
-rw-r--r--drivers/video/mmp/hw/mmp_ctrl.h1974
-rw-r--r--drivers/video/mmp/hw/mmp_spi.c180
-rw-r--r--drivers/video/mmp/panel/Kconfig6
-rw-r--r--drivers/video/mmp/panel/Makefile1
-rw-r--r--drivers/video/mmp/panel/tpo_tj032md01bw.c186
-rw-r--r--drivers/video/mx3fb.c2
48 files changed, 6069 insertions, 473 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index e4e1765b82f2..80cbd21b483f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -364,7 +364,7 @@ config FB_SA1100
364 Y here. 364 Y here.
365 365
366config FB_IMX 366config FB_IMX
367 tristate "Freescale i.MX LCD support" 367 tristate "Freescale i.MX1/21/25/27 LCD support"
368 depends on FB && IMX_HAVE_PLATFORM_IMX_FB 368 depends on FB && IMX_HAVE_PLATFORM_IMX_FB
369 select FB_CFB_FILLRECT 369 select FB_CFB_FILLRECT
370 select FB_CFB_COPYAREA 370 select FB_CFB_COPYAREA
@@ -2025,7 +2025,8 @@ config FB_TMIO_ACCELL
2025 2025
2026config FB_S3C 2026config FB_S3C
2027 tristate "Samsung S3C framebuffer support" 2027 tristate "Samsung S3C framebuffer support"
2028 depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0) 2028 depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \
2029 ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
2029 select FB_CFB_FILLRECT 2030 select FB_CFB_FILLRECT
2030 select FB_CFB_COPYAREA 2031 select FB_CFB_COPYAREA
2031 select FB_CFB_IMAGEBLIT 2032 select FB_CFB_IMAGEBLIT
@@ -2183,6 +2184,15 @@ config FB_XILINX
2183 framebuffer. ML300 carries a 640*480 LCD display on the board, 2184 framebuffer. ML300 carries a 640*480 LCD display on the board,
2184 ML403 uses a standard DB15 VGA connector. 2185 ML403 uses a standard DB15 VGA connector.
2185 2186
2187config FB_GOLDFISH
2188 tristate "Goldfish Framebuffer"
2189 depends on FB
2190 select FB_CFB_FILLRECT
2191 select FB_CFB_COPYAREA
2192 select FB_CFB_IMAGEBLIT
2193 ---help---
2194 Framebuffer driver for Goldfish Virtual Platform
2195
2186config FB_COBALT 2196config FB_COBALT
2187 tristate "Cobalt server LCD frame buffer support" 2197 tristate "Cobalt server LCD frame buffer support"
2188 depends on FB && (MIPS_COBALT || MIPS_SEAD3) 2198 depends on FB && (MIPS_COBALT || MIPS_SEAD3)
@@ -2422,6 +2432,7 @@ config FB_PUV3_UNIGFX
2422source "drivers/video/omap/Kconfig" 2432source "drivers/video/omap/Kconfig"
2423source "drivers/video/omap2/Kconfig" 2433source "drivers/video/omap2/Kconfig"
2424source "drivers/video/exynos/Kconfig" 2434source "drivers/video/exynos/Kconfig"
2435source "drivers/video/mmp/Kconfig"
2425source "drivers/video/backlight/Kconfig" 2436source "drivers/video/backlight/Kconfig"
2426 2437
2427if VT 2438if VT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 768a137a1bac..0577f834fdcd 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -98,6 +98,7 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
98obj-$(CONFIG_FB_PVR2) += pvr2fb.o 98obj-$(CONFIG_FB_PVR2) += pvr2fb.o
99obj-$(CONFIG_FB_VOODOO1) += sstfb.o 99obj-$(CONFIG_FB_VOODOO1) += sstfb.o
100obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o 100obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
101obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
101obj-$(CONFIG_FB_68328) += 68328fb.o 102obj-$(CONFIG_FB_68328) += 68328fb.o
102obj-$(CONFIG_FB_GBE) += gbefb.o 103obj-$(CONFIG_FB_GBE) += gbefb.o
103obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o 104obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
@@ -105,6 +106,7 @@ obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
105obj-$(CONFIG_FB_PXA) += pxafb.o 106obj-$(CONFIG_FB_PXA) += pxafb.o
106obj-$(CONFIG_FB_PXA168) += pxa168fb.o 107obj-$(CONFIG_FB_PXA168) += pxa168fb.o
107obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o 108obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
109obj-$(CONFIG_MMP_DISP) += mmp/
108obj-$(CONFIG_FB_W100) += w100fb.o 110obj-$(CONFIG_FB_W100) += w100fb.o
109obj-$(CONFIG_FB_TMIO) += tmiofb.o 111obj-$(CONFIG_FB_TMIO) += tmiofb.o
110obj-$(CONFIG_FB_AU1100) += au1100fb.o 112obj-$(CONFIG_FB_AU1100) += au1100fb.o
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index c072ed9aea36..2cd63507ed74 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -165,8 +165,10 @@ static int pm860x_backlight_dt_init(struct platform_device *pdev,
165 struct pm860x_backlight_data *data, 165 struct pm860x_backlight_data *data,
166 char *name) 166 char *name)
167{ 167{
168 struct device_node *nproot = pdev->dev.parent->of_node, *np; 168 struct device_node *nproot, *np;
169 int iset = 0; 169 int iset = 0;
170
171 nproot = of_node_get(pdev->dev.parent->of_node);
170 if (!nproot) 172 if (!nproot)
171 return -ENODEV; 173 return -ENODEV;
172 nproot = of_find_node_by_name(nproot, "backlights"); 174 nproot = of_find_node_by_name(nproot, "backlights");
@@ -184,6 +186,7 @@ static int pm860x_backlight_dt_init(struct platform_device *pdev,
184 break; 186 break;
185 } 187 }
186 } 188 }
189 of_node_put(nproot);
187 return 0; 190 return 0;
188} 191}
189#else 192#else
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 765a945f8ea1..be27b551473f 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -126,6 +126,21 @@ config LCD_AMS369FG06
126 If you have an AMS369FG06 AMOLED Panel, say Y to enable its 126 If you have an AMS369FG06 AMOLED Panel, say Y to enable its
127 LCD control driver. 127 LCD control driver.
128 128
129config LCD_LMS501KF03
130 tristate "LMS501KF03 LCD Driver"
131 depends on SPI
132 default n
133 help
134 If you have an LMS501KF03 LCD Panel, say Y to enable its
135 LCD control driver.
136
137config LCD_HX8357
138 tristate "Himax HX-8357 LCD Driver"
139 depends on SPI
140 help
141 If you have a HX-8357 LCD panel, say Y to enable its LCD control
142 driver.
143
129endif # LCD_CLASS_DEVICE 144endif # LCD_CLASS_DEVICE
130 145
131# 146#
@@ -366,7 +381,7 @@ config BACKLIGHT_LP855X
366 tristate "Backlight driver for TI LP855X" 381 tristate "Backlight driver for TI LP855X"
367 depends on BACKLIGHT_CLASS_DEVICE && I2C 382 depends on BACKLIGHT_CLASS_DEVICE && I2C
368 help 383 help
369 This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556 384 This supports TI LP8550, LP8551, LP8552, LP8553, LP8556 and LP8557
370 backlight driver. 385 backlight driver.
371 386
372config BACKLIGHT_OT200 387config BACKLIGHT_OT200
@@ -390,6 +405,13 @@ config BACKLIGHT_TPS65217
390 If you have a Texas Instruments TPS65217 say Y to enable the 405 If you have a Texas Instruments TPS65217 say Y to enable the
391 backlight driver. 406 backlight driver.
392 407
408config BACKLIGHT_AS3711
409 tristate "AS3711 Backlight"
410 depends on BACKLIGHT_CLASS_DEVICE && MFD_AS3711
411 help
412 If you have an Austrian Microsystems AS3711 say Y to enable the
413 backlight driver.
414
393endif # BACKLIGHT_CLASS_DEVICE 415endif # BACKLIGHT_CLASS_DEVICE
394 416
395endif # BACKLIGHT_LCD_SUPPORT 417endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index e7ce7291635d..4606c218e8e4 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -1,47 +1,50 @@
1# Backlight & LCD drivers 1# Backlight & LCD drivers
2 2
3obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o 3obj-$(CONFIG_LCD_AMS369FG06) += ams369fg06.o
4obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o 4obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
5obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o 5obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
6obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o 6obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
7obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o 7obj-$(CONFIG_LCD_HX8357) += hx8357.o
8obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o 8obj-$(CONFIG_LCD_ILI9320) += ili9320.o
9obj-$(CONFIG_LCD_ILI9320) += ili9320.o 9obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o
10obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o 10obj-$(CONFIG_LCD_LD9040) += ld9040.o
11obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o 11obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o
12obj-$(CONFIG_LCD_TDO24M) += tdo24m.o 12obj-$(CONFIG_LCD_LMS501KF03) += lms501kf03.o
13obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o 13obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
14obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o 14obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
15obj-$(CONFIG_LCD_LD9040) += ld9040.o 15obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o
16obj-$(CONFIG_LCD_AMS369FG06) += ams369fg06.o 16obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
17obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
18obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
17 19
18obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 20obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
19obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o 21obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
20obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o 22obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
21obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o 23obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
22obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o 24obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
23obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o 25obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
24obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o 26obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o
25obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o 27obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
26obj-$(CONFIG_BACKLIGHT_LM3630) += lm3630_bl.o 28obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
27obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o 29obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
28obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o 30obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
29obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o 31obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o
30obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o 32obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o
31obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o 33obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o
32obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o 34obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
33obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o 35obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
34obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o 36obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o
35obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o 37obj-$(CONFIG_BACKLIGHT_LM3630) += lm3630_bl.o
36obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o 38obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
37obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o 39obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
38obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o 40obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
39obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o 41obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
40obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o 42obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
41obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o 43obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
42obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o 44obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
43obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
44obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o 45obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
45obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o 46obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
46obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o 47obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
47obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o 48obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
49obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
50obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c
index 7ff752288b92..c6fc668d6236 100644
--- a/drivers/video/backlight/aat2870_bl.c
+++ b/drivers/video/backlight/aat2870_bl.c
@@ -74,7 +74,7 @@ static int aat2870_bl_get_brightness(struct backlight_device *bd)
74 74
75static int aat2870_bl_update_status(struct backlight_device *bd) 75static int aat2870_bl_update_status(struct backlight_device *bd)
76{ 76{
77 struct aat2870_bl_driver_data *aat2870_bl = dev_get_drvdata(&bd->dev); 77 struct aat2870_bl_driver_data *aat2870_bl = bl_get_data(bd);
78 struct aat2870_data *aat2870 = 78 struct aat2870_data *aat2870 =
79 dev_get_drvdata(aat2870_bl->pdev->dev.parent); 79 dev_get_drvdata(aat2870_bl->pdev->dev.parent);
80 int brightness = bd->props.brightness; 80 int brightness = bd->props.brightness;
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 6bb72c0cb803..a77c9cad3320 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -783,7 +783,7 @@ static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message)
783 783
784static int adp8860_i2c_resume(struct i2c_client *client) 784static int adp8860_i2c_resume(struct i2c_client *client)
785{ 785{
786 adp8860_set_bits(client, ADP8860_MDCR, NSTBY); 786 adp8860_set_bits(client, ADP8860_MDCR, NSTBY | BLEN);
787 787
788 return 0; 788 return 0;
789} 789}
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 63c882b8177a..712c25a0d8fe 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -957,7 +957,7 @@ static int adp8870_i2c_suspend(struct i2c_client *client, pm_message_t message)
957 957
958static int adp8870_i2c_resume(struct i2c_client *client) 958static int adp8870_i2c_resume(struct i2c_client *client)
959{ 959{
960 adp8870_set_bits(client, ADP8870_MDCR, NSTBY); 960 adp8870_set_bits(client, ADP8870_MDCR, NSTBY | BLEN);
961 961
962 return 0; 962 return 0;
963} 963}
diff --git a/drivers/video/backlight/ams369fg06.c b/drivers/video/backlight/ams369fg06.c
index f57e1905236a..d29e49443f29 100644
--- a/drivers/video/backlight/ams369fg06.c
+++ b/drivers/video/backlight/ams369fg06.c
@@ -10,25 +10,16 @@
10 * under the terms of the GNU General Public License as published by the 10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your 11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. 12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */ 13 */
23 14
24#include <linux/wait.h> 15#include <linux/backlight.h>
25#include <linux/module.h>
26#include <linux/fb.h>
27#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/fb.h>
28#include <linux/gpio.h> 18#include <linux/gpio.h>
29#include <linux/spi/spi.h>
30#include <linux/lcd.h> 19#include <linux/lcd.h>
31#include <linux/backlight.h> 20#include <linux/module.h>
21#include <linux/spi/spi.h>
22#include <linux/wait.h>
32 23
33#define SLEEPMSEC 0x1000 24#define SLEEPMSEC 0x1000
34#define ENDDEF 0x2000 25#define ENDDEF 0x2000
@@ -210,8 +201,9 @@ static int ams369fg06_panel_send_sequence(struct ams369fg06 *lcd,
210 ret = ams369fg06_spi_write(lcd, wbuf[i], wbuf[i+1]); 201 ret = ams369fg06_spi_write(lcd, wbuf[i], wbuf[i+1]);
211 if (ret) 202 if (ret)
212 break; 203 break;
213 } else 204 } else {
214 mdelay(wbuf[i+1]); 205 msleep(wbuf[i+1]);
206 }
215 i += 2; 207 i += 2;
216 } 208 }
217 209
@@ -313,41 +305,32 @@ static int ams369fg06_ldi_disable(struct ams369fg06 *lcd)
313 305
314static int ams369fg06_power_is_on(int power) 306static int ams369fg06_power_is_on(int power)
315{ 307{
316 return ((power) <= FB_BLANK_NORMAL); 308 return power <= FB_BLANK_NORMAL;
317} 309}
318 310
319static int ams369fg06_power_on(struct ams369fg06 *lcd) 311static int ams369fg06_power_on(struct ams369fg06 *lcd)
320{ 312{
321 int ret = 0; 313 int ret = 0;
322 struct lcd_platform_data *pd = NULL; 314 struct lcd_platform_data *pd;
323 struct backlight_device *bd = NULL; 315 struct backlight_device *bd;
324 316
325 pd = lcd->lcd_pd; 317 pd = lcd->lcd_pd;
326 if (!pd) {
327 dev_err(lcd->dev, "platform data is NULL.\n");
328 return -EFAULT;
329 }
330
331 bd = lcd->bd; 318 bd = lcd->bd;
332 if (!bd) {
333 dev_err(lcd->dev, "backlight device is NULL.\n");
334 return -EFAULT;
335 }
336 319
337 if (!pd->power_on) { 320 if (!pd->power_on) {
338 dev_err(lcd->dev, "power_on is NULL.\n"); 321 dev_err(lcd->dev, "power_on is NULL.\n");
339 return -EFAULT; 322 return -EINVAL;
340 } else { 323 } else {
341 pd->power_on(lcd->ld, 1); 324 pd->power_on(lcd->ld, 1);
342 mdelay(pd->power_on_delay); 325 msleep(pd->power_on_delay);
343 } 326 }
344 327
345 if (!pd->reset) { 328 if (!pd->reset) {
346 dev_err(lcd->dev, "reset is NULL.\n"); 329 dev_err(lcd->dev, "reset is NULL.\n");
347 return -EFAULT; 330 return -EINVAL;
348 } else { 331 } else {
349 pd->reset(lcd->ld); 332 pd->reset(lcd->ld);
350 mdelay(pd->reset_delay); 333 msleep(pd->reset_delay);
351 } 334 }
352 335
353 ret = ams369fg06_ldi_init(lcd); 336 ret = ams369fg06_ldi_init(lcd);
@@ -374,14 +357,10 @@ static int ams369fg06_power_on(struct ams369fg06 *lcd)
374 357
375static int ams369fg06_power_off(struct ams369fg06 *lcd) 358static int ams369fg06_power_off(struct ams369fg06 *lcd)
376{ 359{
377 int ret = 0; 360 int ret;
378 struct lcd_platform_data *pd = NULL; 361 struct lcd_platform_data *pd;
379 362
380 pd = lcd->lcd_pd; 363 pd = lcd->lcd_pd;
381 if (!pd) {
382 dev_err(lcd->dev, "platform data is NULL\n");
383 return -EFAULT;
384 }
385 364
386 ret = ams369fg06_ldi_disable(lcd); 365 ret = ams369fg06_ldi_disable(lcd);
387 if (ret) { 366 if (ret) {
@@ -389,13 +368,9 @@ static int ams369fg06_power_off(struct ams369fg06 *lcd)
389 return -EIO; 368 return -EIO;
390 } 369 }
391 370
392 mdelay(pd->power_off_delay); 371 msleep(pd->power_off_delay);
393 372
394 if (!pd->power_on) { 373 pd->power_on(lcd->ld, 0);
395 dev_err(lcd->dev, "power_on is NULL.\n");
396 return -EFAULT;
397 } else
398 pd->power_on(lcd->ld, 0);
399 374
400 return 0; 375 return 0;
401} 376}
@@ -446,7 +421,7 @@ static int ams369fg06_set_brightness(struct backlight_device *bd)
446{ 421{
447 int ret = 0; 422 int ret = 0;
448 int brightness = bd->props.brightness; 423 int brightness = bd->props.brightness;
449 struct ams369fg06 *lcd = dev_get_drvdata(&bd->dev); 424 struct ams369fg06 *lcd = bl_get_data(bd);
450 425
451 if (brightness < MIN_BRIGHTNESS || 426 if (brightness < MIN_BRIGHTNESS ||
452 brightness > bd->props.max_brightness) { 427 brightness > bd->props.max_brightness) {
@@ -501,7 +476,7 @@ static int ams369fg06_probe(struct spi_device *spi)
501 lcd->lcd_pd = spi->dev.platform_data; 476 lcd->lcd_pd = spi->dev.platform_data;
502 if (!lcd->lcd_pd) { 477 if (!lcd->lcd_pd) {
503 dev_err(&spi->dev, "platform data is NULL\n"); 478 dev_err(&spi->dev, "platform data is NULL\n");
504 return -EFAULT; 479 return -EINVAL;
505 } 480 }
506 481
507 ld = lcd_device_register("ams369fg06", &spi->dev, lcd, 482 ld = lcd_device_register("ams369fg06", &spi->dev, lcd,
@@ -534,10 +509,11 @@ static int ams369fg06_probe(struct spi_device *spi)
534 lcd->power = FB_BLANK_POWERDOWN; 509 lcd->power = FB_BLANK_POWERDOWN;
535 510
536 ams369fg06_power(lcd, FB_BLANK_UNBLANK); 511 ams369fg06_power(lcd, FB_BLANK_UNBLANK);
537 } else 512 } else {
538 lcd->power = FB_BLANK_UNBLANK; 513 lcd->power = FB_BLANK_UNBLANK;
514 }
539 515
540 dev_set_drvdata(&spi->dev, lcd); 516 spi_set_drvdata(spi, lcd);
541 517
542 dev_info(&spi->dev, "ams369fg06 panel driver has been probed.\n"); 518 dev_info(&spi->dev, "ams369fg06 panel driver has been probed.\n");
543 519
@@ -550,7 +526,7 @@ out_lcd_unregister:
550 526
551static int ams369fg06_remove(struct spi_device *spi) 527static int ams369fg06_remove(struct spi_device *spi)
552{ 528{
553 struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev); 529 struct ams369fg06 *lcd = spi_get_drvdata(spi);
554 530
555 ams369fg06_power(lcd, FB_BLANK_POWERDOWN); 531 ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
556 backlight_device_unregister(lcd->bd); 532 backlight_device_unregister(lcd->bd);
@@ -560,44 +536,26 @@ static int ams369fg06_remove(struct spi_device *spi)
560} 536}
561 537
562#if defined(CONFIG_PM) 538#if defined(CONFIG_PM)
563static unsigned int before_power;
564
565static int ams369fg06_suspend(struct spi_device *spi, pm_message_t mesg) 539static int ams369fg06_suspend(struct spi_device *spi, pm_message_t mesg)
566{ 540{
567 int ret = 0; 541 struct ams369fg06 *lcd = spi_get_drvdata(spi);
568 struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
569 542
570 dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power); 543 dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
571 544
572 before_power = lcd->power;
573
574 /* 545 /*
575 * when lcd panel is suspend, lcd panel becomes off 546 * when lcd panel is suspend, lcd panel becomes off
576 * regardless of status. 547 * regardless of status.
577 */ 548 */
578 ret = ams369fg06_power(lcd, FB_BLANK_POWERDOWN); 549 return ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
579
580 return ret;
581} 550}
582 551
583static int ams369fg06_resume(struct spi_device *spi) 552static int ams369fg06_resume(struct spi_device *spi)
584{ 553{
585 int ret = 0; 554 struct ams369fg06 *lcd = spi_get_drvdata(spi);
586 struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
587 555
588 /* 556 lcd->power = FB_BLANK_POWERDOWN;
589 * after suspended, if lcd panel status is FB_BLANK_UNBLANK
590 * (at that time, before_power is FB_BLANK_UNBLANK) then
591 * it changes that status to FB_BLANK_POWERDOWN to get lcd on.
592 */
593 if (before_power == FB_BLANK_UNBLANK)
594 lcd->power = FB_BLANK_POWERDOWN;
595
596 dev_dbg(&spi->dev, "before_power = %d\n", before_power);
597 557
598 ret = ams369fg06_power(lcd, before_power); 558 return ams369fg06_power(lcd, FB_BLANK_UNBLANK);
599
600 return ret;
601} 559}
602#else 560#else
603#define ams369fg06_suspend NULL 561#define ams369fg06_suspend NULL
@@ -606,7 +564,7 @@ static int ams369fg06_resume(struct spi_device *spi)
606 564
607static void ams369fg06_shutdown(struct spi_device *spi) 565static void ams369fg06_shutdown(struct spi_device *spi)
608{ 566{
609 struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev); 567 struct ams369fg06 *lcd = spi_get_drvdata(spi);
610 568
611 ams369fg06_power(lcd, FB_BLANK_POWERDOWN); 569 ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
612} 570}
diff --git a/drivers/video/backlight/as3711_bl.c b/drivers/video/backlight/as3711_bl.c
new file mode 100644
index 000000000000..41d52fe52543
--- /dev/null
+++ b/drivers/video/backlight/as3711_bl.c
@@ -0,0 +1,380 @@
1/*
2 * AS3711 PMIC backlight driver, using DCDC Step Up Converters
3 *
4 * Copyright (C) 2012 Renesas Electronics Corporation
5 * Author: Guennadi Liakhovetski, <g.liakhovetski@gmx.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the version 2 of the GNU General Public License as
9 * published by the Free Software Foundation
10 */
11
12#include <linux/backlight.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/err.h>
16#include <linux/fb.h>
17#include <linux/kernel.h>
18#include <linux/mfd/as3711.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/regmap.h>
22#include <linux/slab.h>
23
24enum as3711_bl_type {
25 AS3711_BL_SU1,
26 AS3711_BL_SU2,
27};
28
29struct as3711_bl_data {
30 bool powered;
31 const char *fb_name;
32 struct device *fb_dev;
33 enum as3711_bl_type type;
34 int brightness;
35 struct backlight_device *bl;
36};
37
38struct as3711_bl_supply {
39 struct as3711_bl_data su1;
40 struct as3711_bl_data su2;
41 const struct as3711_bl_pdata *pdata;
42 struct as3711 *as3711;
43};
44
45static struct as3711_bl_supply *to_supply(struct as3711_bl_data *su)
46{
47 switch (su->type) {
48 case AS3711_BL_SU1:
49 return container_of(su, struct as3711_bl_supply, su1);
50 case AS3711_BL_SU2:
51 return container_of(su, struct as3711_bl_supply, su2);
52 }
53 return NULL;
54}
55
56static int as3711_set_brightness_auto_i(struct as3711_bl_data *data,
57 unsigned int brightness)
58{
59 struct as3711_bl_supply *supply = to_supply(data);
60 struct as3711 *as3711 = supply->as3711;
61 const struct as3711_bl_pdata *pdata = supply->pdata;
62 int ret = 0;
63
64 /* Only all equal current values are supported */
65 if (pdata->su2_auto_curr1)
66 ret = regmap_write(as3711->regmap, AS3711_CURR1_VALUE,
67 brightness);
68 if (!ret && pdata->su2_auto_curr2)
69 ret = regmap_write(as3711->regmap, AS3711_CURR2_VALUE,
70 brightness);
71 if (!ret && pdata->su2_auto_curr3)
72 ret = regmap_write(as3711->regmap, AS3711_CURR3_VALUE,
73 brightness);
74
75 return ret;
76}
77
78static int as3711_set_brightness_v(struct as3711 *as3711,
79 unsigned int brightness,
80 unsigned int reg)
81{
82 if (brightness > 31)
83 return -EINVAL;
84
85 return regmap_update_bits(as3711->regmap, reg, 0xf0,
86 brightness << 4);
87}
88
89static int as3711_bl_su2_reset(struct as3711_bl_supply *supply)
90{
91 struct as3711 *as3711 = supply->as3711;
92 int ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_5,
93 3, supply->pdata->su2_fbprot);
94 if (!ret)
95 ret = regmap_update_bits(as3711->regmap,
96 AS3711_STEPUP_CONTROL_2, 1, 0);
97 if (!ret)
98 ret = regmap_update_bits(as3711->regmap,
99 AS3711_STEPUP_CONTROL_2, 1, 1);
100 return ret;
101}
102
103/*
104 * Someone with less fragile or less expensive hardware could try to simplify
105 * the brightness adjustment procedure.
106 */
107static int as3711_bl_update_status(struct backlight_device *bl)
108{
109 struct as3711_bl_data *data = bl_get_data(bl);
110 struct as3711_bl_supply *supply = to_supply(data);
111 struct as3711 *as3711 = supply->as3711;
112 int brightness = bl->props.brightness;
113 int ret = 0;
114
115 dev_dbg(&bl->dev, "%s(): brightness %u, pwr %x, blank %x, state %x\n",
116 __func__, bl->props.brightness, bl->props.power,
117 bl->props.fb_blank, bl->props.state);
118
119 if (bl->props.power != FB_BLANK_UNBLANK ||
120 bl->props.fb_blank != FB_BLANK_UNBLANK ||
121 bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
122 brightness = 0;
123
124 if (data->type == AS3711_BL_SU1) {
125 ret = as3711_set_brightness_v(as3711, brightness,
126 AS3711_STEPUP_CONTROL_1);
127 } else {
128 const struct as3711_bl_pdata *pdata = supply->pdata;
129
130 switch (pdata->su2_feedback) {
131 case AS3711_SU2_VOLTAGE:
132 ret = as3711_set_brightness_v(as3711, brightness,
133 AS3711_STEPUP_CONTROL_2);
134 break;
135 case AS3711_SU2_CURR_AUTO:
136 ret = as3711_set_brightness_auto_i(data, brightness / 4);
137 if (ret < 0)
138 return ret;
139 if (brightness) {
140 ret = as3711_bl_su2_reset(supply);
141 if (ret < 0)
142 return ret;
143 udelay(500);
144 ret = as3711_set_brightness_auto_i(data, brightness);
145 } else {
146 ret = regmap_update_bits(as3711->regmap,
147 AS3711_STEPUP_CONTROL_2, 1, 0);
148 }
149 break;
150 /* Manual one current feedback pin below */
151 case AS3711_SU2_CURR1:
152 ret = regmap_write(as3711->regmap, AS3711_CURR1_VALUE,
153 brightness);
154 break;
155 case AS3711_SU2_CURR2:
156 ret = regmap_write(as3711->regmap, AS3711_CURR2_VALUE,
157 brightness);
158 break;
159 case AS3711_SU2_CURR3:
160 ret = regmap_write(as3711->regmap, AS3711_CURR3_VALUE,
161 brightness);
162 break;
163 default:
164 ret = -EINVAL;
165 }
166 }
167 if (!ret)
168 data->brightness = brightness;
169
170 return ret;
171}
172
173static int as3711_bl_get_brightness(struct backlight_device *bl)
174{
175 struct as3711_bl_data *data = bl_get_data(bl);
176
177 return data->brightness;
178}
179
180static const struct backlight_ops as3711_bl_ops = {
181 .update_status = as3711_bl_update_status,
182 .get_brightness = as3711_bl_get_brightness,
183};
184
185static int as3711_bl_init_su2(struct as3711_bl_supply *supply)
186{
187 struct as3711 *as3711 = supply->as3711;
188 const struct as3711_bl_pdata *pdata = supply->pdata;
189 u8 ctl = 0;
190 int ret;
191
192 dev_dbg(as3711->dev, "%s(): use %u\n", __func__, pdata->su2_feedback);
193
194 /* Turn SU2 off */
195 ret = regmap_write(as3711->regmap, AS3711_STEPUP_CONTROL_2, 0);
196 if (ret < 0)
197 return ret;
198
199 switch (pdata->su2_feedback) {
200 case AS3711_SU2_VOLTAGE:
201 ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 0);
202 break;
203 case AS3711_SU2_CURR1:
204 ctl = 1;
205 ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 1);
206 break;
207 case AS3711_SU2_CURR2:
208 ctl = 4;
209 ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 2);
210 break;
211 case AS3711_SU2_CURR3:
212 ctl = 0x10;
213 ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 3);
214 break;
215 case AS3711_SU2_CURR_AUTO:
216 if (pdata->su2_auto_curr1)
217 ctl = 2;
218 if (pdata->su2_auto_curr2)
219 ctl |= 8;
220 if (pdata->su2_auto_curr3)
221 ctl |= 0x20;
222 ret = 0;
223 break;
224 default:
225 return -EINVAL;
226 }
227
228 if (!ret)
229 ret = regmap_write(as3711->regmap, AS3711_CURR_CONTROL, ctl);
230
231 return ret;
232}
233
234static int as3711_bl_register(struct platform_device *pdev,
235 unsigned int max_brightness, struct as3711_bl_data *su)
236{
237 struct backlight_properties props = {.type = BACKLIGHT_RAW,};
238 struct backlight_device *bl;
239
240 /* max tuning I = 31uA for voltage- and 38250uA for current-feedback */
241 props.max_brightness = max_brightness;
242
243 bl = backlight_device_register(su->type == AS3711_BL_SU1 ?
244 "as3711-su1" : "as3711-su2",
245 &pdev->dev, su,
246 &as3711_bl_ops, &props);
247 if (IS_ERR(bl)) {
248 dev_err(&pdev->dev, "failed to register backlight\n");
249 return PTR_ERR(bl);
250 }
251
252 bl->props.brightness = props.max_brightness;
253
254 backlight_update_status(bl);
255
256 su->bl = bl;
257
258 return 0;
259}
260
261static int as3711_backlight_probe(struct platform_device *pdev)
262{
263 struct as3711_bl_pdata *pdata = dev_get_platdata(&pdev->dev);
264 struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent);
265 struct as3711_bl_supply *supply;
266 struct as3711_bl_data *su;
267 unsigned int max_brightness;
268 int ret;
269
270 if (!pdata || (!pdata->su1_fb && !pdata->su2_fb)) {
271 dev_err(&pdev->dev, "No platform data, exiting...\n");
272 return -ENODEV;
273 }
274
275 /*
276 * Due to possible hardware damage I chose to block all modes,
277 * unsupported on my hardware. Anyone, wishing to use any of those modes
278 * will have to first review the code, then activate and test it.
279 */
280 if (pdata->su1_fb ||
281 pdata->su2_fbprot != AS3711_SU2_GPIO4 ||
282 pdata->su2_feedback != AS3711_SU2_CURR_AUTO) {
283 dev_warn(&pdev->dev,
284 "Attention! An untested mode has been chosen!\n"
285 "Please, review the code, enable, test, and report success:-)\n");
286 return -EINVAL;
287 }
288
289 supply = devm_kzalloc(&pdev->dev, sizeof(*supply), GFP_KERNEL);
290 if (!supply)
291 return -ENOMEM;
292
293 supply->as3711 = as3711;
294 supply->pdata = pdata;
295
296 if (pdata->su1_fb) {
297 su = &supply->su1;
298 su->fb_name = pdata->su1_fb;
299 su->type = AS3711_BL_SU1;
300
301 max_brightness = min(pdata->su1_max_uA, 31);
302 ret = as3711_bl_register(pdev, max_brightness, su);
303 if (ret < 0)
304 return ret;
305 }
306
307 if (pdata->su2_fb) {
308 su = &supply->su2;
309 su->fb_name = pdata->su2_fb;
310 su->type = AS3711_BL_SU2;
311
312 switch (pdata->su2_fbprot) {
313 case AS3711_SU2_GPIO2:
314 case AS3711_SU2_GPIO3:
315 case AS3711_SU2_GPIO4:
316 case AS3711_SU2_LX_SD4:
317 break;
318 default:
319 ret = -EINVAL;
320 goto esu2;
321 }
322
323 switch (pdata->su2_feedback) {
324 case AS3711_SU2_VOLTAGE:
325 max_brightness = min(pdata->su2_max_uA, 31);
326 break;
327 case AS3711_SU2_CURR1:
328 case AS3711_SU2_CURR2:
329 case AS3711_SU2_CURR3:
330 case AS3711_SU2_CURR_AUTO:
331 max_brightness = min(pdata->su2_max_uA / 150, 255);
332 break;
333 default:
334 ret = -EINVAL;
335 goto esu2;
336 }
337
338 ret = as3711_bl_init_su2(supply);
339 if (ret < 0)
340 return ret;
341
342 ret = as3711_bl_register(pdev, max_brightness, su);
343 if (ret < 0)
344 goto esu2;
345 }
346
347 platform_set_drvdata(pdev, supply);
348
349 return 0;
350
351esu2:
352 backlight_device_unregister(supply->su1.bl);
353 return ret;
354}
355
356static int as3711_backlight_remove(struct platform_device *pdev)
357{
358 struct as3711_bl_supply *supply = platform_get_drvdata(pdev);
359
360 backlight_device_unregister(supply->su1.bl);
361 backlight_device_unregister(supply->su2.bl);
362
363 return 0;
364}
365
366static struct platform_driver as3711_backlight_driver = {
367 .driver = {
368 .name = "as3711-backlight",
369 .owner = THIS_MODULE,
370 },
371 .probe = as3711_backlight_probe,
372 .remove = as3711_backlight_remove,
373};
374
375module_platform_driver(as3711_backlight_driver);
376
377MODULE_DESCRIPTION("Backlight Driver for AS3711 PMICs");
378MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de");
379MODULE_LICENSE("GPL");
380MODULE_ALIAS("platform:as3711-backlight");
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index e323fcbe884e..aa782f302983 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -337,7 +337,7 @@ static void corgi_lcd_power_off(struct corgi_lcd *lcd)
337 337
338static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m) 338static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m)
339{ 339{
340 struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); 340 struct corgi_lcd *lcd = lcd_get_data(ld);
341 int mode = CORGI_LCD_MODE_QVGA; 341 int mode = CORGI_LCD_MODE_QVGA;
342 342
343 if (m->xres == 640 || m->xres == 480) 343 if (m->xres == 640 || m->xres == 480)
@@ -364,7 +364,7 @@ static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m)
364 364
365static int corgi_lcd_set_power(struct lcd_device *ld, int power) 365static int corgi_lcd_set_power(struct lcd_device *ld, int power)
366{ 366{
367 struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); 367 struct corgi_lcd *lcd = lcd_get_data(ld);
368 368
369 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power)) 369 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
370 corgi_lcd_power_on(lcd); 370 corgi_lcd_power_on(lcd);
@@ -378,7 +378,7 @@ static int corgi_lcd_set_power(struct lcd_device *ld, int power)
378 378
379static int corgi_lcd_get_power(struct lcd_device *ld) 379static int corgi_lcd_get_power(struct lcd_device *ld)
380{ 380{
381 struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); 381 struct corgi_lcd *lcd = lcd_get_data(ld);
382 382
383 return lcd->power; 383 return lcd->power;
384} 384}
@@ -391,7 +391,7 @@ static struct lcd_ops corgi_lcd_ops = {
391 391
392static int corgi_bl_get_intensity(struct backlight_device *bd) 392static int corgi_bl_get_intensity(struct backlight_device *bd)
393{ 393{
394 struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev); 394 struct corgi_lcd *lcd = bl_get_data(bd);
395 395
396 return lcd->intensity; 396 return lcd->intensity;
397} 397}
@@ -423,7 +423,7 @@ static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
423 423
424static int corgi_bl_update_status(struct backlight_device *bd) 424static int corgi_bl_update_status(struct backlight_device *bd)
425{ 425{
426 struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev); 426 struct corgi_lcd *lcd = bl_get_data(bd);
427 int intensity = bd->props.brightness; 427 int intensity = bd->props.brightness;
428 428
429 if (bd->props.power != FB_BLANK_UNBLANK) 429 if (bd->props.power != FB_BLANK_UNBLANK)
@@ -460,7 +460,7 @@ static const struct backlight_ops corgi_bl_ops = {
460#ifdef CONFIG_PM 460#ifdef CONFIG_PM
461static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state) 461static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state)
462{ 462{
463 struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); 463 struct corgi_lcd *lcd = spi_get_drvdata(spi);
464 464
465 corgibl_flags |= CORGIBL_SUSPENDED; 465 corgibl_flags |= CORGIBL_SUSPENDED;
466 corgi_bl_set_intensity(lcd, 0); 466 corgi_bl_set_intensity(lcd, 0);
@@ -470,7 +470,7 @@ static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state)
470 470
471static int corgi_lcd_resume(struct spi_device *spi) 471static int corgi_lcd_resume(struct spi_device *spi)
472{ 472{
473 struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); 473 struct corgi_lcd *lcd = spi_get_drvdata(spi);
474 474
475 corgibl_flags &= ~CORGIBL_SUSPENDED; 475 corgibl_flags &= ~CORGIBL_SUSPENDED;
476 corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK); 476 corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
@@ -577,7 +577,7 @@ static int corgi_lcd_probe(struct spi_device *spi)
577 577
578 lcd->kick_battery = pdata->kick_battery; 578 lcd->kick_battery = pdata->kick_battery;
579 579
580 dev_set_drvdata(&spi->dev, lcd); 580 spi_set_drvdata(spi, lcd);
581 corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK); 581 corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
582 backlight_update_status(lcd->bl_dev); 582 backlight_update_status(lcd->bl_dev);
583 583
@@ -594,7 +594,7 @@ err_unregister_lcd:
594 594
595static int corgi_lcd_remove(struct spi_device *spi) 595static int corgi_lcd_remove(struct spi_device *spi)
596{ 596{
597 struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); 597 struct corgi_lcd *lcd = spi_get_drvdata(spi);
598 598
599 lcd->bl_dev->props.power = FB_BLANK_UNBLANK; 599 lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
600 lcd->bl_dev->props.brightness = 0; 600 lcd->bl_dev->props.brightness = 0;
diff --git a/drivers/video/backlight/hx8357.c b/drivers/video/backlight/hx8357.c
new file mode 100644
index 000000000000..a0482b567bfe
--- /dev/null
+++ b/drivers/video/backlight/hx8357.c
@@ -0,0 +1,497 @@
1/*
2 * Driver for the Himax HX-8357 LCD Controller
3 *
4 * Copyright 2012 Free Electrons
5 *
6 * Licensed under the GPLv2 or later.
7 */
8
9#include <linux/delay.h>
10#include <linux/lcd.h>
11#include <linux/module.h>
12#include <linux/of.h>
13#include <linux/of_device.h>
14#include <linux/of_gpio.h>
15#include <linux/spi/spi.h>
16
17#define HX8357_NUM_IM_PINS 3
18
19#define HX8357_SWRESET 0x01
20#define HX8357_GET_RED_CHANNEL 0x06
21#define HX8357_GET_GREEN_CHANNEL 0x07
22#define HX8357_GET_BLUE_CHANNEL 0x08
23#define HX8357_GET_POWER_MODE 0x0a
24#define HX8357_GET_MADCTL 0x0b
25#define HX8357_GET_PIXEL_FORMAT 0x0c
26#define HX8357_GET_DISPLAY_MODE 0x0d
27#define HX8357_GET_SIGNAL_MODE 0x0e
28#define HX8357_GET_DIAGNOSTIC_RESULT 0x0f
29#define HX8357_ENTER_SLEEP_MODE 0x10
30#define HX8357_EXIT_SLEEP_MODE 0x11
31#define HX8357_ENTER_PARTIAL_MODE 0x12
32#define HX8357_ENTER_NORMAL_MODE 0x13
33#define HX8357_EXIT_INVERSION_MODE 0x20
34#define HX8357_ENTER_INVERSION_MODE 0x21
35#define HX8357_SET_DISPLAY_OFF 0x28
36#define HX8357_SET_DISPLAY_ON 0x29
37#define HX8357_SET_COLUMN_ADDRESS 0x2a
38#define HX8357_SET_PAGE_ADDRESS 0x2b
39#define HX8357_WRITE_MEMORY_START 0x2c
40#define HX8357_READ_MEMORY_START 0x2e
41#define HX8357_SET_PARTIAL_AREA 0x30
42#define HX8357_SET_SCROLL_AREA 0x33
43#define HX8357_SET_TEAR_OFF 0x34
44#define HX8357_SET_TEAR_ON 0x35
45#define HX8357_SET_ADDRESS_MODE 0x36
46#define HX8357_SET_SCROLL_START 0x37
47#define HX8357_EXIT_IDLE_MODE 0x38
48#define HX8357_ENTER_IDLE_MODE 0x39
49#define HX8357_SET_PIXEL_FORMAT 0x3a
50#define HX8357_SET_PIXEL_FORMAT_DBI_3BIT (0x1)
51#define HX8357_SET_PIXEL_FORMAT_DBI_16BIT (0x5)
52#define HX8357_SET_PIXEL_FORMAT_DBI_18BIT (0x6)
53#define HX8357_SET_PIXEL_FORMAT_DPI_3BIT (0x1 << 4)
54#define HX8357_SET_PIXEL_FORMAT_DPI_16BIT (0x5 << 4)
55#define HX8357_SET_PIXEL_FORMAT_DPI_18BIT (0x6 << 4)
56#define HX8357_WRITE_MEMORY_CONTINUE 0x3c
57#define HX8357_READ_MEMORY_CONTINUE 0x3e
58#define HX8357_SET_TEAR_SCAN_LINES 0x44
59#define HX8357_GET_SCAN_LINES 0x45
60#define HX8357_READ_DDB_START 0xa1
61#define HX8357_SET_DISPLAY_MODE 0xb4
62#define HX8357_SET_DISPLAY_MODE_RGB_THROUGH (0x3)
63#define HX8357_SET_DISPLAY_MODE_RGB_INTERFACE (1 << 4)
64#define HX8357_SET_PANEL_DRIVING 0xc0
65#define HX8357_SET_DISPLAY_FRAME 0xc5
66#define HX8357_SET_RGB 0xc6
67#define HX8357_SET_RGB_ENABLE_HIGH (1 << 1)
68#define HX8357_SET_GAMMA 0xc8
69#define HX8357_SET_POWER 0xd0
70#define HX8357_SET_VCOM 0xd1
71#define HX8357_SET_POWER_NORMAL 0xd2
72#define HX8357_SET_PANEL_RELATED 0xe9
73
74struct hx8357_data {
75 unsigned im_pins[HX8357_NUM_IM_PINS];
76 unsigned reset;
77 struct spi_device *spi;
78 int state;
79};
80
81static u8 hx8357_seq_power[] = {
82 HX8357_SET_POWER, 0x44, 0x41, 0x06,
83};
84
85static u8 hx8357_seq_vcom[] = {
86 HX8357_SET_VCOM, 0x40, 0x10,
87};
88
89static u8 hx8357_seq_power_normal[] = {
90 HX8357_SET_POWER_NORMAL, 0x05, 0x12,
91};
92
93static u8 hx8357_seq_panel_driving[] = {
94 HX8357_SET_PANEL_DRIVING, 0x14, 0x3b, 0x00, 0x02, 0x11,
95};
96
97static u8 hx8357_seq_display_frame[] = {
98 HX8357_SET_DISPLAY_FRAME, 0x0c,
99};
100
101static u8 hx8357_seq_panel_related[] = {
102 HX8357_SET_PANEL_RELATED, 0x01,
103};
104
105static u8 hx8357_seq_undefined1[] = {
106 0xea, 0x03, 0x00, 0x00,
107};
108
109static u8 hx8357_seq_undefined2[] = {
110 0xeb, 0x40, 0x54, 0x26, 0xdb,
111};
112
113static u8 hx8357_seq_gamma[] = {
114 HX8357_SET_GAMMA, 0x00, 0x15, 0x00, 0x22, 0x00,
115 0x08, 0x77, 0x26, 0x77, 0x22, 0x04, 0x00,
116};
117
118static u8 hx8357_seq_address_mode[] = {
119 HX8357_SET_ADDRESS_MODE, 0xc0,
120};
121
122static u8 hx8357_seq_pixel_format[] = {
123 HX8357_SET_PIXEL_FORMAT,
124 HX8357_SET_PIXEL_FORMAT_DPI_18BIT |
125 HX8357_SET_PIXEL_FORMAT_DBI_18BIT,
126};
127
128static u8 hx8357_seq_column_address[] = {
129 HX8357_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0x3f,
130};
131
132static u8 hx8357_seq_page_address[] = {
133 HX8357_SET_PAGE_ADDRESS, 0x00, 0x00, 0x01, 0xdf,
134};
135
136static u8 hx8357_seq_rgb[] = {
137 HX8357_SET_RGB, 0x02,
138};
139
140static u8 hx8357_seq_display_mode[] = {
141 HX8357_SET_DISPLAY_MODE,
142 HX8357_SET_DISPLAY_MODE_RGB_THROUGH |
143 HX8357_SET_DISPLAY_MODE_RGB_INTERFACE,
144};
145
146static int hx8357_spi_write_then_read(struct lcd_device *lcdev,
147 u8 *txbuf, u16 txlen,
148 u8 *rxbuf, u16 rxlen)
149{
150 struct hx8357_data *lcd = lcd_get_data(lcdev);
151 struct spi_message msg;
152 struct spi_transfer xfer[2];
153 u16 *local_txbuf = NULL;
154 int ret = 0;
155
156 memset(xfer, 0, sizeof(xfer));
157 spi_message_init(&msg);
158
159 if (txlen) {
160 int i;
161
162 local_txbuf = kcalloc(txlen, sizeof(*local_txbuf), GFP_KERNEL);
163
164 if (!local_txbuf)
165 return -ENOMEM;
166
167 for (i = 0; i < txlen; i++) {
168 local_txbuf[i] = txbuf[i];
169 if (i > 0)
170 local_txbuf[i] |= 1 << 8;
171 }
172
173 xfer[0].len = 2 * txlen;
174 xfer[0].bits_per_word = 9;
175 xfer[0].tx_buf = local_txbuf;
176 spi_message_add_tail(&xfer[0], &msg);
177 }
178
179 if (rxlen) {
180 xfer[1].len = rxlen;
181 xfer[1].bits_per_word = 8;
182 xfer[1].rx_buf = rxbuf;
183 spi_message_add_tail(&xfer[1], &msg);
184 }
185
186 ret = spi_sync(lcd->spi, &msg);
187 if (ret < 0)
188 dev_err(&lcdev->dev, "Couldn't send SPI data\n");
189
190 if (txlen)
191 kfree(local_txbuf);
192
193 return ret;
194}
195
196static inline int hx8357_spi_write_array(struct lcd_device *lcdev,
197 u8 *value, u8 len)
198{
199 return hx8357_spi_write_then_read(lcdev, value, len, NULL, 0);
200}
201
202static inline int hx8357_spi_write_byte(struct lcd_device *lcdev,
203 u8 value)
204{
205 return hx8357_spi_write_then_read(lcdev, &value, 1, NULL, 0);
206}
207
208static int hx8357_enter_standby(struct lcd_device *lcdev)
209{
210 int ret;
211
212 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_OFF);
213 if (ret < 0)
214 return ret;
215
216 usleep_range(10000, 12000);
217
218 ret = hx8357_spi_write_byte(lcdev, HX8357_ENTER_SLEEP_MODE);
219 if (ret < 0)
220 return ret;
221
222 msleep(120);
223
224 return 0;
225}
226
227static int hx8357_exit_standby(struct lcd_device *lcdev)
228{
229 int ret;
230
231 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
232 if (ret < 0)
233 return ret;
234
235 msleep(120);
236
237 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
238 if (ret < 0)
239 return ret;
240
241 return 0;
242}
243
244static int hx8357_lcd_init(struct lcd_device *lcdev)
245{
246 struct hx8357_data *lcd = lcd_get_data(lcdev);
247 int ret;
248
249 /*
250 * Set the interface selection pins to SPI mode, with three
251 * wires
252 */
253 gpio_set_value_cansleep(lcd->im_pins[0], 1);
254 gpio_set_value_cansleep(lcd->im_pins[1], 0);
255 gpio_set_value_cansleep(lcd->im_pins[2], 1);
256
257 /* Reset the screen */
258 gpio_set_value(lcd->reset, 1);
259 usleep_range(10000, 12000);
260 gpio_set_value(lcd->reset, 0);
261 usleep_range(10000, 12000);
262 gpio_set_value(lcd->reset, 1);
263 msleep(120);
264
265 ret = hx8357_spi_write_array(lcdev, hx8357_seq_power,
266 ARRAY_SIZE(hx8357_seq_power));
267 if (ret < 0)
268 return ret;
269
270 ret = hx8357_spi_write_array(lcdev, hx8357_seq_vcom,
271 ARRAY_SIZE(hx8357_seq_vcom));
272 if (ret < 0)
273 return ret;
274
275 ret = hx8357_spi_write_array(lcdev, hx8357_seq_power_normal,
276 ARRAY_SIZE(hx8357_seq_power_normal));
277 if (ret < 0)
278 return ret;
279
280 ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_driving,
281 ARRAY_SIZE(hx8357_seq_panel_driving));
282 if (ret < 0)
283 return ret;
284
285 ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_frame,
286 ARRAY_SIZE(hx8357_seq_display_frame));
287 if (ret < 0)
288 return ret;
289
290 ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_related,
291 ARRAY_SIZE(hx8357_seq_panel_related));
292 if (ret < 0)
293 return ret;
294
295 ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined1,
296 ARRAY_SIZE(hx8357_seq_undefined1));
297 if (ret < 0)
298 return ret;
299
300 ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined2,
301 ARRAY_SIZE(hx8357_seq_undefined2));
302 if (ret < 0)
303 return ret;
304
305 ret = hx8357_spi_write_array(lcdev, hx8357_seq_gamma,
306 ARRAY_SIZE(hx8357_seq_gamma));
307 if (ret < 0)
308 return ret;
309
310 ret = hx8357_spi_write_array(lcdev, hx8357_seq_address_mode,
311 ARRAY_SIZE(hx8357_seq_address_mode));
312 if (ret < 0)
313 return ret;
314
315 ret = hx8357_spi_write_array(lcdev, hx8357_seq_pixel_format,
316 ARRAY_SIZE(hx8357_seq_pixel_format));
317 if (ret < 0)
318 return ret;
319
320 ret = hx8357_spi_write_array(lcdev, hx8357_seq_column_address,
321 ARRAY_SIZE(hx8357_seq_column_address));
322 if (ret < 0)
323 return ret;
324
325 ret = hx8357_spi_write_array(lcdev, hx8357_seq_page_address,
326 ARRAY_SIZE(hx8357_seq_page_address));
327 if (ret < 0)
328 return ret;
329
330 ret = hx8357_spi_write_array(lcdev, hx8357_seq_rgb,
331 ARRAY_SIZE(hx8357_seq_rgb));
332 if (ret < 0)
333 return ret;
334
335 ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_mode,
336 ARRAY_SIZE(hx8357_seq_display_mode));
337 if (ret < 0)
338 return ret;
339
340 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
341 if (ret < 0)
342 return ret;
343
344 msleep(120);
345
346 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
347 if (ret < 0)
348 return ret;
349
350 usleep_range(5000, 7000);
351
352 ret = hx8357_spi_write_byte(lcdev, HX8357_WRITE_MEMORY_START);
353 if (ret < 0)
354 return ret;
355
356 return 0;
357}
358
359#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
360
361static int hx8357_set_power(struct lcd_device *lcdev, int power)
362{
363 struct hx8357_data *lcd = lcd_get_data(lcdev);
364 int ret = 0;
365
366 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->state))
367 ret = hx8357_exit_standby(lcdev);
368 else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->state))
369 ret = hx8357_enter_standby(lcdev);
370
371 if (ret == 0)
372 lcd->state = power;
373 else
374 dev_warn(&lcdev->dev, "failed to set power mode %d\n", power);
375
376 return ret;
377}
378
379static int hx8357_get_power(struct lcd_device *lcdev)
380{
381 struct hx8357_data *lcd = lcd_get_data(lcdev);
382
383 return lcd->state;
384}
385
386static struct lcd_ops hx8357_ops = {
387 .set_power = hx8357_set_power,
388 .get_power = hx8357_get_power,
389};
390
391static int hx8357_probe(struct spi_device *spi)
392{
393 struct lcd_device *lcdev;
394 struct hx8357_data *lcd;
395 int i, ret;
396
397 lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL);
398 if (!lcd) {
399 dev_err(&spi->dev, "Couldn't allocate lcd internal structure!\n");
400 return -ENOMEM;
401 }
402
403 ret = spi_setup(spi);
404 if (ret < 0) {
405 dev_err(&spi->dev, "SPI setup failed.\n");
406 return ret;
407 }
408
409 lcd->spi = spi;
410
411 lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0);
412 if (!gpio_is_valid(lcd->reset)) {
413 dev_err(&spi->dev, "Missing dt property: gpios-reset\n");
414 return -EINVAL;
415 }
416
417 ret = devm_gpio_request_one(&spi->dev, lcd->reset,
418 GPIOF_OUT_INIT_HIGH,
419 "hx8357-reset");
420 if (ret) {
421 dev_err(&spi->dev,
422 "failed to request gpio %d: %d\n",
423 lcd->reset, ret);
424 return -EINVAL;
425 }
426
427 for (i = 0; i < HX8357_NUM_IM_PINS; i++) {
428 lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node,
429 "im-gpios", i);
430 if (lcd->im_pins[i] == -EPROBE_DEFER) {
431 dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n");
432 return -EPROBE_DEFER;
433 }
434 if (!gpio_is_valid(lcd->im_pins[i])) {
435 dev_err(&spi->dev, "Missing dt property: im-gpios\n");
436 return -EINVAL;
437 }
438
439 ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i],
440 GPIOF_OUT_INIT_LOW, "im_pins");
441 if (ret) {
442 dev_err(&spi->dev, "failed to request gpio %d: %d\n",
443 lcd->im_pins[i], ret);
444 return -EINVAL;
445 }
446 }
447
448 lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops);
449 if (IS_ERR(lcdev)) {
450 ret = PTR_ERR(lcdev);
451 return ret;
452 }
453 spi_set_drvdata(spi, lcdev);
454
455 ret = hx8357_lcd_init(lcdev);
456 if (ret) {
457 dev_err(&spi->dev, "Couldn't initialize panel\n");
458 goto init_error;
459 }
460
461 dev_info(&spi->dev, "Panel probed\n");
462
463 return 0;
464
465init_error:
466 lcd_device_unregister(lcdev);
467 return ret;
468}
469
470static int hx8357_remove(struct spi_device *spi)
471{
472 struct lcd_device *lcdev = spi_get_drvdata(spi);
473
474 lcd_device_unregister(lcdev);
475 return 0;
476}
477
478static const struct of_device_id hx8357_dt_ids[] = {
479 { .compatible = "himax,hx8357" },
480 {},
481};
482MODULE_DEVICE_TABLE(of, hx8357_dt_ids);
483
484static struct spi_driver hx8357_driver = {
485 .probe = hx8357_probe,
486 .remove = hx8357_remove,
487 .driver = {
488 .name = "hx8357",
489 .of_match_table = of_match_ptr(hx8357_dt_ids),
490 },
491};
492
493module_spi_driver(hx8357_driver);
494
495MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
496MODULE_DESCRIPTION("Himax HX-8357 LCD Driver");
497MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
index 9a35196d12d7..fb6155771326 100644
--- a/drivers/video/backlight/l4f00242t03.c
+++ b/drivers/video/backlight/l4f00242t03.c
@@ -49,7 +49,7 @@ static void l4f00242t03_reset(unsigned int gpio)
49static void l4f00242t03_lcd_init(struct spi_device *spi) 49static void l4f00242t03_lcd_init(struct spi_device *spi)
50{ 50{
51 struct l4f00242t03_pdata *pdata = spi->dev.platform_data; 51 struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
52 struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); 52 struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
53 const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) }; 53 const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };
54 54
55 dev_dbg(&spi->dev, "initializing LCD\n"); 55 dev_dbg(&spi->dev, "initializing LCD\n");
@@ -70,7 +70,7 @@ static void l4f00242t03_lcd_init(struct spi_device *spi)
70static void l4f00242t03_lcd_powerdown(struct spi_device *spi) 70static void l4f00242t03_lcd_powerdown(struct spi_device *spi)
71{ 71{
72 struct l4f00242t03_pdata *pdata = spi->dev.platform_data; 72 struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
73 struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); 73 struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
74 74
75 dev_dbg(&spi->dev, "Powering down LCD\n"); 75 dev_dbg(&spi->dev, "Powering down LCD\n");
76 76
@@ -168,7 +168,7 @@ static int l4f00242t03_probe(struct spi_device *spi)
168 return -ENOMEM; 168 return -ENOMEM;
169 } 169 }
170 170
171 dev_set_drvdata(&spi->dev, priv); 171 spi_set_drvdata(spi, priv);
172 spi->bits_per_word = 9; 172 spi->bits_per_word = 9;
173 spi_setup(spi); 173 spi_setup(spi);
174 174
@@ -190,27 +190,24 @@ static int l4f00242t03_probe(struct spi_device *spi)
190 return ret; 190 return ret;
191 } 191 }
192 192
193 priv->io_reg = regulator_get(&spi->dev, "vdd"); 193 priv->io_reg = devm_regulator_get(&spi->dev, "vdd");
194 if (IS_ERR(priv->io_reg)) { 194 if (IS_ERR(priv->io_reg)) {
195 dev_err(&spi->dev, "%s: Unable to get the IO regulator\n", 195 dev_err(&spi->dev, "%s: Unable to get the IO regulator\n",
196 __func__); 196 __func__);
197 return PTR_ERR(priv->io_reg); 197 return PTR_ERR(priv->io_reg);
198 } 198 }
199 199
200 priv->core_reg = regulator_get(&spi->dev, "vcore"); 200 priv->core_reg = devm_regulator_get(&spi->dev, "vcore");
201 if (IS_ERR(priv->core_reg)) { 201 if (IS_ERR(priv->core_reg)) {
202 ret = PTR_ERR(priv->core_reg);
203 dev_err(&spi->dev, "%s: Unable to get the core regulator\n", 202 dev_err(&spi->dev, "%s: Unable to get the core regulator\n",
204 __func__); 203 __func__);
205 goto err1; 204 return PTR_ERR(priv->core_reg);
206 } 205 }
207 206
208 priv->ld = lcd_device_register("l4f00242t03", 207 priv->ld = lcd_device_register("l4f00242t03",
209 &spi->dev, priv, &l4f_ops); 208 &spi->dev, priv, &l4f_ops);
210 if (IS_ERR(priv->ld)) { 209 if (IS_ERR(priv->ld))
211 ret = PTR_ERR(priv->ld); 210 return PTR_ERR(priv->ld);
212 goto err2;
213 }
214 211
215 /* Init the LCD */ 212 /* Init the LCD */
216 l4f00242t03_lcd_init(spi); 213 l4f00242t03_lcd_init(spi);
@@ -220,33 +217,22 @@ static int l4f00242t03_probe(struct spi_device *spi)
220 dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n"); 217 dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n");
221 218
222 return 0; 219 return 0;
223
224err2:
225 regulator_put(priv->core_reg);
226err1:
227 regulator_put(priv->io_reg);
228
229 return ret;
230} 220}
231 221
232static int l4f00242t03_remove(struct spi_device *spi) 222static int l4f00242t03_remove(struct spi_device *spi)
233{ 223{
234 struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); 224 struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
235 225
236 l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); 226 l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
237 lcd_device_unregister(priv->ld); 227 lcd_device_unregister(priv->ld);
238 228 spi_set_drvdata(spi, NULL);
239 dev_set_drvdata(&spi->dev, NULL);
240
241 regulator_put(priv->io_reg);
242 regulator_put(priv->core_reg);
243 229
244 return 0; 230 return 0;
245} 231}
246 232
247static void l4f00242t03_shutdown(struct spi_device *spi) 233static void l4f00242t03_shutdown(struct spi_device *spi)
248{ 234{
249 struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); 235 struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
250 236
251 if (priv) 237 if (priv)
252 l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); 238 l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c
index 1cb352418513..1b642f5f381a 100644
--- a/drivers/video/backlight/ld9040.c
+++ b/drivers/video/backlight/ld9040.c
@@ -9,29 +9,20 @@
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */ 12 */
22 13
23#include <linux/wait.h> 14#include <linux/backlight.h>
24#include <linux/fb.h>
25#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/fb.h>
26#include <linux/gpio.h> 17#include <linux/gpio.h>
27#include <linux/spi/spi.h>
28#include <linux/irq.h>
29#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/irq.h>
30#include <linux/kernel.h> 20#include <linux/kernel.h>
31#include <linux/lcd.h> 21#include <linux/lcd.h>
32#include <linux/backlight.h>
33#include <linux/module.h> 22#include <linux/module.h>
34#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
24#include <linux/spi/spi.h>
25#include <linux/wait.h>
35 26
36#include "ld9040_gamma.h" 27#include "ld9040_gamma.h"
37 28
@@ -43,7 +34,6 @@
43 34
44#define MIN_BRIGHTNESS 0 35#define MIN_BRIGHTNESS 0
45#define MAX_BRIGHTNESS 24 36#define MAX_BRIGHTNESS 24
46#define power_is_on(pwr) ((pwr) <= FB_BLANK_NORMAL)
47 37
48struct ld9040 { 38struct ld9040 {
49 struct device *dev; 39 struct device *dev;
@@ -78,7 +68,7 @@ static void ld9040_regulator_enable(struct ld9040 *lcd)
78 68
79 lcd->enabled = true; 69 lcd->enabled = true;
80 } 70 }
81 mdelay(pd->power_on_delay); 71 msleep(pd->power_on_delay);
82out: 72out:
83 mutex_unlock(&lcd->lock); 73 mutex_unlock(&lcd->lock);
84} 74}
@@ -474,8 +464,9 @@ static int ld9040_panel_send_sequence(struct ld9040 *lcd,
474 ret = ld9040_spi_write(lcd, wbuf[i], wbuf[i+1]); 464 ret = ld9040_spi_write(lcd, wbuf[i], wbuf[i+1]);
475 if (ret) 465 if (ret)
476 break; 466 break;
477 } else 467 } else {
478 udelay(wbuf[i+1]*1000); 468 msleep(wbuf[i+1]);
469 }
479 i += 2; 470 i += 2;
480 } 471 }
481 472
@@ -513,14 +504,9 @@ gamma_err:
513 504
514static int ld9040_gamma_ctl(struct ld9040 *lcd, int gamma) 505static int ld9040_gamma_ctl(struct ld9040 *lcd, int gamma)
515{ 506{
516 int ret = 0; 507 return _ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
517
518 ret = _ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
519
520 return ret;
521} 508}
522 509
523
524static int ld9040_ldi_init(struct ld9040 *lcd) 510static int ld9040_ldi_init(struct ld9040 *lcd)
525{ 511{
526 int ret, i; 512 int ret, i;
@@ -539,7 +525,7 @@ static int ld9040_ldi_init(struct ld9040 *lcd)
539 for (i = 0; i < ARRAY_SIZE(init_seq); i++) { 525 for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
540 ret = ld9040_panel_send_sequence(lcd, init_seq[i]); 526 ret = ld9040_panel_send_sequence(lcd, init_seq[i]);
541 /* workaround: minimum delay time for transferring CMD */ 527 /* workaround: minimum delay time for transferring CMD */
542 udelay(300); 528 usleep_range(300, 310);
543 if (ret) 529 if (ret)
544 break; 530 break;
545 } 531 }
@@ -549,11 +535,7 @@ static int ld9040_ldi_init(struct ld9040 *lcd)
549 535
550static int ld9040_ldi_enable(struct ld9040 *lcd) 536static int ld9040_ldi_enable(struct ld9040 *lcd)
551{ 537{
552 int ret = 0; 538 return ld9040_panel_send_sequence(lcd, seq_display_on);
553
554 ret = ld9040_panel_send_sequence(lcd, seq_display_on);
555
556 return ret;
557} 539}
558 540
559static int ld9040_ldi_disable(struct ld9040 *lcd) 541static int ld9040_ldi_disable(struct ld9040 *lcd)
@@ -566,25 +548,27 @@ static int ld9040_ldi_disable(struct ld9040 *lcd)
566 return ret; 548 return ret;
567} 549}
568 550
551static int ld9040_power_is_on(int power)
552{
553 return power <= FB_BLANK_NORMAL;
554}
555
569static int ld9040_power_on(struct ld9040 *lcd) 556static int ld9040_power_on(struct ld9040 *lcd)
570{ 557{
571 int ret = 0; 558 int ret = 0;
572 struct lcd_platform_data *pd = NULL; 559 struct lcd_platform_data *pd;
560
573 pd = lcd->lcd_pd; 561 pd = lcd->lcd_pd;
574 if (!pd) {
575 dev_err(lcd->dev, "platform data is NULL.\n");
576 return -EFAULT;
577 }
578 562
579 /* lcd power on */ 563 /* lcd power on */
580 ld9040_regulator_enable(lcd); 564 ld9040_regulator_enable(lcd);
581 565
582 if (!pd->reset) { 566 if (!pd->reset) {
583 dev_err(lcd->dev, "reset is NULL.\n"); 567 dev_err(lcd->dev, "reset is NULL.\n");
584 return -EFAULT; 568 return -EINVAL;
585 } else { 569 } else {
586 pd->reset(lcd->ld); 570 pd->reset(lcd->ld);
587 mdelay(pd->reset_delay); 571 msleep(pd->reset_delay);
588 } 572 }
589 573
590 ret = ld9040_ldi_init(lcd); 574 ret = ld9040_ldi_init(lcd);
@@ -604,14 +588,10 @@ static int ld9040_power_on(struct ld9040 *lcd)
604 588
605static int ld9040_power_off(struct ld9040 *lcd) 589static int ld9040_power_off(struct ld9040 *lcd)
606{ 590{
607 int ret = 0; 591 int ret;
608 struct lcd_platform_data *pd = NULL; 592 struct lcd_platform_data *pd;
609 593
610 pd = lcd->lcd_pd; 594 pd = lcd->lcd_pd;
611 if (!pd) {
612 dev_err(lcd->dev, "platform data is NULL.\n");
613 return -EFAULT;
614 }
615 595
616 ret = ld9040_ldi_disable(lcd); 596 ret = ld9040_ldi_disable(lcd);
617 if (ret) { 597 if (ret) {
@@ -619,7 +599,7 @@ static int ld9040_power_off(struct ld9040 *lcd)
619 return -EIO; 599 return -EIO;
620 } 600 }
621 601
622 mdelay(pd->power_off_delay); 602 msleep(pd->power_off_delay);
623 603
624 /* lcd power off */ 604 /* lcd power off */
625 ld9040_regulator_disable(lcd); 605 ld9040_regulator_disable(lcd);
@@ -631,9 +611,9 @@ static int ld9040_power(struct ld9040 *lcd, int power)
631{ 611{
632 int ret = 0; 612 int ret = 0;
633 613
634 if (power_is_on(power) && !power_is_on(lcd->power)) 614 if (ld9040_power_is_on(power) && !ld9040_power_is_on(lcd->power))
635 ret = ld9040_power_on(lcd); 615 ret = ld9040_power_on(lcd);
636 else if (!power_is_on(power) && power_is_on(lcd->power)) 616 else if (!ld9040_power_is_on(power) && ld9040_power_is_on(lcd->power))
637 ret = ld9040_power_off(lcd); 617 ret = ld9040_power_off(lcd);
638 618
639 if (!ret) 619 if (!ret)
@@ -698,7 +678,6 @@ static const struct backlight_ops ld9040_backlight_ops = {
698 .update_status = ld9040_set_brightness, 678 .update_status = ld9040_set_brightness,
699}; 679};
700 680
701
702static int ld9040_probe(struct spi_device *spi) 681static int ld9040_probe(struct spi_device *spi)
703{ 682{
704 int ret = 0; 683 int ret = 0;
@@ -726,22 +705,20 @@ static int ld9040_probe(struct spi_device *spi)
726 lcd->lcd_pd = spi->dev.platform_data; 705 lcd->lcd_pd = spi->dev.platform_data;
727 if (!lcd->lcd_pd) { 706 if (!lcd->lcd_pd) {
728 dev_err(&spi->dev, "platform data is NULL.\n"); 707 dev_err(&spi->dev, "platform data is NULL.\n");
729 return -EFAULT; 708 return -EINVAL;
730 } 709 }
731 710
732 mutex_init(&lcd->lock); 711 mutex_init(&lcd->lock);
733 712
734 ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies); 713 ret = devm_regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
735 if (ret) { 714 if (ret) {
736 dev_err(lcd->dev, "Failed to get regulators: %d\n", ret); 715 dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
737 return ret; 716 return ret;
738 } 717 }
739 718
740 ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops); 719 ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops);
741 if (IS_ERR(ld)) { 720 if (IS_ERR(ld))
742 ret = PTR_ERR(ld); 721 return PTR_ERR(ld);
743 goto out_free_regulator;
744 }
745 722
746 lcd->ld = ld; 723 lcd->ld = ld;
747 724
@@ -772,30 +749,28 @@ static int ld9040_probe(struct spi_device *spi)
772 lcd->power = FB_BLANK_POWERDOWN; 749 lcd->power = FB_BLANK_POWERDOWN;
773 750
774 ld9040_power(lcd, FB_BLANK_UNBLANK); 751 ld9040_power(lcd, FB_BLANK_UNBLANK);
775 } else 752 } else {
776 lcd->power = FB_BLANK_UNBLANK; 753 lcd->power = FB_BLANK_UNBLANK;
754 }
777 755
778 dev_set_drvdata(&spi->dev, lcd); 756 spi_set_drvdata(spi, lcd);
779 757
780 dev_info(&spi->dev, "ld9040 panel driver has been probed.\n"); 758 dev_info(&spi->dev, "ld9040 panel driver has been probed.\n");
781 return 0; 759 return 0;
782 760
783out_unregister_lcd: 761out_unregister_lcd:
784 lcd_device_unregister(lcd->ld); 762 lcd_device_unregister(lcd->ld);
785out_free_regulator:
786 regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
787 763
788 return ret; 764 return ret;
789} 765}
790 766
791static int ld9040_remove(struct spi_device *spi) 767static int ld9040_remove(struct spi_device *spi)
792{ 768{
793 struct ld9040 *lcd = dev_get_drvdata(&spi->dev); 769 struct ld9040 *lcd = spi_get_drvdata(spi);
794 770
795 ld9040_power(lcd, FB_BLANK_POWERDOWN); 771 ld9040_power(lcd, FB_BLANK_POWERDOWN);
796 backlight_device_unregister(lcd->bd); 772 backlight_device_unregister(lcd->bd);
797 lcd_device_unregister(lcd->ld); 773 lcd_device_unregister(lcd->ld);
798 regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
799 774
800 return 0; 775 return 0;
801} 776}
@@ -803,8 +778,7 @@ static int ld9040_remove(struct spi_device *spi)
803#if defined(CONFIG_PM) 778#if defined(CONFIG_PM)
804static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg) 779static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
805{ 780{
806 int ret = 0; 781 struct ld9040 *lcd = spi_get_drvdata(spi);
807 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
808 782
809 dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power); 783 dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
810 784
@@ -812,21 +786,16 @@ static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
812 * when lcd panel is suspend, lcd panel becomes off 786 * when lcd panel is suspend, lcd panel becomes off
813 * regardless of status. 787 * regardless of status.
814 */ 788 */
815 ret = ld9040_power(lcd, FB_BLANK_POWERDOWN); 789 return ld9040_power(lcd, FB_BLANK_POWERDOWN);
816
817 return ret;
818} 790}
819 791
820static int ld9040_resume(struct spi_device *spi) 792static int ld9040_resume(struct spi_device *spi)
821{ 793{
822 int ret = 0; 794 struct ld9040 *lcd = spi_get_drvdata(spi);
823 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
824 795
825 lcd->power = FB_BLANK_POWERDOWN; 796 lcd->power = FB_BLANK_POWERDOWN;
826 797
827 ret = ld9040_power(lcd, FB_BLANK_UNBLANK); 798 return ld9040_power(lcd, FB_BLANK_UNBLANK);
828
829 return ret;
830} 799}
831#else 800#else
832#define ld9040_suspend NULL 801#define ld9040_suspend NULL
@@ -836,7 +805,7 @@ static int ld9040_resume(struct spi_device *spi)
836/* Power down all displays on reboot, poweroff or halt. */ 805/* Power down all displays on reboot, poweroff or halt. */
837static void ld9040_shutdown(struct spi_device *spi) 806static void ld9040_shutdown(struct spi_device *spi)
838{ 807{
839 struct ld9040 *lcd = dev_get_drvdata(&spi->dev); 808 struct ld9040 *lcd = spi_get_drvdata(spi);
840 809
841 ld9040_power(lcd, FB_BLANK_POWERDOWN); 810 ld9040_power(lcd, FB_BLANK_POWERDOWN);
842} 811}
diff --git a/drivers/video/backlight/lm3630_bl.c b/drivers/video/backlight/lm3630_bl.c
index a6d637b5c68f..76a62e978fc3 100644
--- a/drivers/video/backlight/lm3630_bl.c
+++ b/drivers/video/backlight/lm3630_bl.c
@@ -320,7 +320,7 @@ static int lm3630_backlight_register(struct lm3630_chip_data *pchip,
320 backlight_device_register(name, pchip->dev, pchip, 320 backlight_device_register(name, pchip->dev, pchip,
321 &lm3630_bank_a_ops, &props); 321 &lm3630_bank_a_ops, &props);
322 if (IS_ERR(pchip->bled1)) 322 if (IS_ERR(pchip->bled1))
323 return -EIO; 323 return PTR_ERR(pchip->bled1);
324 break; 324 break;
325 case BLED_2: 325 case BLED_2:
326 props.brightness = pdata->init_brt_led2; 326 props.brightness = pdata->init_brt_led2;
@@ -329,7 +329,7 @@ static int lm3630_backlight_register(struct lm3630_chip_data *pchip,
329 backlight_device_register(name, pchip->dev, pchip, 329 backlight_device_register(name, pchip->dev, pchip,
330 &lm3630_bank_b_ops, &props); 330 &lm3630_bank_b_ops, &props);
331 if (IS_ERR(pchip->bled2)) 331 if (IS_ERR(pchip->bled2))
332 return -EIO; 332 return PTR_ERR(pchip->bled2);
333 break; 333 break;
334 } 334 }
335 return 0; 335 return 0;
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c
index 7ab2d2a04e41..053964da8dd3 100644
--- a/drivers/video/backlight/lm3639_bl.c
+++ b/drivers/video/backlight/lm3639_bl.c
@@ -350,14 +350,13 @@ static int lm3639_probe(struct i2c_client *client,
350 &lm3639_bled_ops, &props); 350 &lm3639_bled_ops, &props);
351 if (IS_ERR(pchip->bled)) { 351 if (IS_ERR(pchip->bled)) {
352 dev_err(&client->dev, "fail : backlight register\n"); 352 dev_err(&client->dev, "fail : backlight register\n");
353 ret = -EIO; 353 ret = PTR_ERR(pchip->bled);
354 goto err_out; 354 goto err_out;
355 } 355 }
356 356
357 ret = device_create_file(&(pchip->bled->dev), &dev_attr_bled_mode); 357 ret = device_create_file(&(pchip->bled->dev), &dev_attr_bled_mode);
358 if (ret < 0) { 358 if (ret < 0) {
359 dev_err(&client->dev, "failed : add sysfs entries\n"); 359 dev_err(&client->dev, "failed : add sysfs entries\n");
360 ret = -EIO;
361 goto err_bled_mode; 360 goto err_bled_mode;
362 } 361 }
363 362
@@ -369,7 +368,6 @@ static int lm3639_probe(struct i2c_client *client,
369 &client->dev, &pchip->cdev_flash); 368 &client->dev, &pchip->cdev_flash);
370 if (ret < 0) { 369 if (ret < 0) {
371 dev_err(&client->dev, "fail : flash register\n"); 370 dev_err(&client->dev, "fail : flash register\n");
372 ret = -EIO;
373 goto err_flash; 371 goto err_flash;
374 } 372 }
375 373
@@ -381,7 +379,6 @@ static int lm3639_probe(struct i2c_client *client,
381 &client->dev, &pchip->cdev_torch); 379 &client->dev, &pchip->cdev_torch);
382 if (ret < 0) { 380 if (ret < 0) {
383 dev_err(&client->dev, "fail : torch register\n"); 381 dev_err(&client->dev, "fail : torch register\n");
384 ret = -EIO;
385 goto err_torch; 382 goto err_torch;
386 } 383 }
387 384
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c
index 55819b384701..4eec47261cd3 100644
--- a/drivers/video/backlight/lms283gf05.c
+++ b/drivers/video/backlight/lms283gf05.c
@@ -180,7 +180,7 @@ static int lms283gf05_probe(struct spi_device *spi)
180 st->spi = spi; 180 st->spi = spi;
181 st->ld = ld; 181 st->ld = ld;
182 182
183 dev_set_drvdata(&spi->dev, st); 183 spi_set_drvdata(spi, st);
184 184
185 /* kick in the LCD */ 185 /* kick in the LCD */
186 if (pdata) 186 if (pdata)
@@ -192,7 +192,7 @@ static int lms283gf05_probe(struct spi_device *spi)
192 192
193static int lms283gf05_remove(struct spi_device *spi) 193static int lms283gf05_remove(struct spi_device *spi)
194{ 194{
195 struct lms283gf05_state *st = dev_get_drvdata(&spi->dev); 195 struct lms283gf05_state *st = spi_get_drvdata(spi);
196 196
197 lcd_device_unregister(st->ld); 197 lcd_device_unregister(st->ld);
198 198
diff --git a/drivers/video/backlight/lms501kf03.c b/drivers/video/backlight/lms501kf03.c
new file mode 100644
index 000000000000..b43882abefaf
--- /dev/null
+++ b/drivers/video/backlight/lms501kf03.c
@@ -0,0 +1,441 @@
1/*
2 * lms501kf03 TFT LCD panel driver.
3 *
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Author: Jingoo Han <jg1.han@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/backlight.h>
14#include <linux/delay.h>
15#include <linux/fb.h>
16#include <linux/gpio.h>
17#include <linux/lcd.h>
18#include <linux/module.h>
19#include <linux/spi/spi.h>
20#include <linux/wait.h>
21
22#define COMMAND_ONLY 0x00
23#define DATA_ONLY 0x01
24
25struct lms501kf03 {
26 struct device *dev;
27 struct spi_device *spi;
28 unsigned int power;
29 struct lcd_device *ld;
30 struct lcd_platform_data *lcd_pd;
31};
32
33static const unsigned char seq_password[] = {
34 0xb9, 0xff, 0x83, 0x69,
35};
36
37static const unsigned char seq_power[] = {
38 0xb1, 0x01, 0x00, 0x34, 0x06, 0x00, 0x14, 0x14, 0x20, 0x28,
39 0x12, 0x12, 0x17, 0x0a, 0x01, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
40};
41
42static const unsigned char seq_display[] = {
43 0xb2, 0x00, 0x2b, 0x03, 0x03, 0x70, 0x00, 0xff, 0x00, 0x00,
44 0x00, 0x00, 0x03, 0x03, 0x00, 0x01,
45};
46
47static const unsigned char seq_rgb_if[] = {
48 0xb3, 0x09,
49};
50
51static const unsigned char seq_display_inv[] = {
52 0xb4, 0x01, 0x08, 0x77, 0x0e, 0x06,
53};
54
55static const unsigned char seq_vcom[] = {
56 0xb6, 0x4c, 0x2e,
57};
58
59static const unsigned char seq_gate[] = {
60 0xd5, 0x00, 0x05, 0x03, 0x29, 0x01, 0x07, 0x17, 0x68, 0x13,
61 0x37, 0x20, 0x31, 0x8a, 0x46, 0x9b, 0x57, 0x13, 0x02, 0x75,
62 0xb9, 0x64, 0xa8, 0x07, 0x0f, 0x04, 0x07,
63};
64
65static const unsigned char seq_panel[] = {
66 0xcc, 0x02,
67};
68
69static const unsigned char seq_col_mod[] = {
70 0x3a, 0x77,
71};
72
73static const unsigned char seq_w_gamma[] = {
74 0xe0, 0x00, 0x04, 0x09, 0x0f, 0x1f, 0x3f, 0x1f, 0x2f, 0x0a,
75 0x0f, 0x10, 0x16, 0x18, 0x16, 0x17, 0x0d, 0x15, 0x00, 0x04,
76 0x09, 0x0f, 0x38, 0x3f, 0x20, 0x39, 0x0a, 0x0f, 0x10, 0x16,
77 0x18, 0x16, 0x17, 0x0d, 0x15,
78};
79
80static const unsigned char seq_rgb_gamma[] = {
81 0xc1, 0x01, 0x03, 0x07, 0x0f, 0x1a, 0x22, 0x2c, 0x33, 0x3c,
82 0x46, 0x4f, 0x58, 0x60, 0x69, 0x71, 0x79, 0x82, 0x89, 0x92,
83 0x9a, 0xa1, 0xa9, 0xb1, 0xb9, 0xc1, 0xc9, 0xcf, 0xd6, 0xde,
84 0xe5, 0xec, 0xf3, 0xf9, 0xff, 0xdd, 0x39, 0x07, 0x1c, 0xcb,
85 0xab, 0x5f, 0x49, 0x80, 0x03, 0x07, 0x0f, 0x19, 0x20, 0x2a,
86 0x31, 0x39, 0x42, 0x4b, 0x53, 0x5b, 0x63, 0x6b, 0x73, 0x7b,
87 0x83, 0x8a, 0x92, 0x9b, 0xa2, 0xaa, 0xb2, 0xba, 0xc2, 0xca,
88 0xd0, 0xd8, 0xe1, 0xe8, 0xf0, 0xf8, 0xff, 0xf7, 0xd8, 0xbe,
89 0xa7, 0x39, 0x40, 0x85, 0x8c, 0xc0, 0x04, 0x07, 0x0c, 0x17,
90 0x1c, 0x23, 0x2b, 0x34, 0x3b, 0x43, 0x4c, 0x54, 0x5b, 0x63,
91 0x6a, 0x73, 0x7a, 0x82, 0x8a, 0x91, 0x98, 0xa1, 0xa8, 0xb0,
92 0xb7, 0xc1, 0xc9, 0xcf, 0xd9, 0xe3, 0xea, 0xf4, 0xff, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94};
95
96static const unsigned char seq_up_dn[] = {
97 0x36, 0x10,
98};
99
100static const unsigned char seq_sleep_in[] = {
101 0x10,
102};
103
104static const unsigned char seq_sleep_out[] = {
105 0x11,
106};
107
108static const unsigned char seq_display_on[] = {
109 0x29,
110};
111
112static const unsigned char seq_display_off[] = {
113 0x10,
114};
115
116static int lms501kf03_spi_write_byte(struct lms501kf03 *lcd, int addr, int data)
117{
118 u16 buf[1];
119 struct spi_message msg;
120
121 struct spi_transfer xfer = {
122 .len = 2,
123 .tx_buf = buf,
124 };
125
126 buf[0] = (addr << 8) | data;
127
128 spi_message_init(&msg);
129 spi_message_add_tail(&xfer, &msg);
130
131 return spi_sync(lcd->spi, &msg);
132}
133
134static int lms501kf03_spi_write(struct lms501kf03 *lcd, unsigned char address,
135 unsigned char command)
136{
137 return lms501kf03_spi_write_byte(lcd, address, command);
138}
139
140static int lms501kf03_panel_send_sequence(struct lms501kf03 *lcd,
141 const unsigned char *wbuf,
142 unsigned int len)
143{
144 int ret = 0, i = 0;
145
146 while (i < len) {
147 if (i == 0)
148 ret = lms501kf03_spi_write(lcd, COMMAND_ONLY, wbuf[i]);
149 else
150 ret = lms501kf03_spi_write(lcd, DATA_ONLY, wbuf[i]);
151 if (ret)
152 break;
153 i += 1;
154 }
155
156 return ret;
157}
158
159static int lms501kf03_ldi_init(struct lms501kf03 *lcd)
160{
161 int ret, i;
162 static const unsigned char *init_seq[] = {
163 seq_password,
164 seq_power,
165 seq_display,
166 seq_rgb_if,
167 seq_display_inv,
168 seq_vcom,
169 seq_gate,
170 seq_panel,
171 seq_col_mod,
172 seq_w_gamma,
173 seq_rgb_gamma,
174 seq_sleep_out,
175 };
176
177 static const unsigned int size_seq[] = {
178 ARRAY_SIZE(seq_password),
179 ARRAY_SIZE(seq_power),
180 ARRAY_SIZE(seq_display),
181 ARRAY_SIZE(seq_rgb_if),
182 ARRAY_SIZE(seq_display_inv),
183 ARRAY_SIZE(seq_vcom),
184 ARRAY_SIZE(seq_gate),
185 ARRAY_SIZE(seq_panel),
186 ARRAY_SIZE(seq_col_mod),
187 ARRAY_SIZE(seq_w_gamma),
188 ARRAY_SIZE(seq_rgb_gamma),
189 ARRAY_SIZE(seq_sleep_out),
190 };
191
192 for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
193 ret = lms501kf03_panel_send_sequence(lcd, init_seq[i],
194 size_seq[i]);
195 if (ret)
196 break;
197 }
198 /*
199 * According to the datasheet, 120ms delay time is required.
200 * After sleep out sequence, command is blocked for 120ms.
201 * Thus, LDI should wait for 120ms.
202 */
203 msleep(120);
204
205 return ret;
206}
207
208static int lms501kf03_ldi_enable(struct lms501kf03 *lcd)
209{
210 return lms501kf03_panel_send_sequence(lcd, seq_display_on,
211 ARRAY_SIZE(seq_display_on));
212}
213
214static int lms501kf03_ldi_disable(struct lms501kf03 *lcd)
215{
216 return lms501kf03_panel_send_sequence(lcd, seq_display_off,
217 ARRAY_SIZE(seq_display_off));
218}
219
220static int lms501kf03_power_is_on(int power)
221{
222 return (power) <= FB_BLANK_NORMAL;
223}
224
225static int lms501kf03_power_on(struct lms501kf03 *lcd)
226{
227 int ret = 0;
228 struct lcd_platform_data *pd;
229
230 pd = lcd->lcd_pd;
231
232 if (!pd->power_on) {
233 dev_err(lcd->dev, "power_on is NULL.\n");
234 return -EINVAL;
235 } else {
236 pd->power_on(lcd->ld, 1);
237 msleep(pd->power_on_delay);
238 }
239
240 if (!pd->reset) {
241 dev_err(lcd->dev, "reset is NULL.\n");
242 return -EINVAL;
243 } else {
244 pd->reset(lcd->ld);
245 msleep(pd->reset_delay);
246 }
247
248 ret = lms501kf03_ldi_init(lcd);
249 if (ret) {
250 dev_err(lcd->dev, "failed to initialize ldi.\n");
251 return ret;
252 }
253
254 ret = lms501kf03_ldi_enable(lcd);
255 if (ret) {
256 dev_err(lcd->dev, "failed to enable ldi.\n");
257 return ret;
258 }
259
260 return 0;
261}
262
263static int lms501kf03_power_off(struct lms501kf03 *lcd)
264{
265 int ret = 0;
266 struct lcd_platform_data *pd;
267
268 pd = lcd->lcd_pd;
269
270 ret = lms501kf03_ldi_disable(lcd);
271 if (ret) {
272 dev_err(lcd->dev, "lcd setting failed.\n");
273 return -EIO;
274 }
275
276 msleep(pd->power_off_delay);
277
278 pd->power_on(lcd->ld, 0);
279
280 return 0;
281}
282
283static int lms501kf03_power(struct lms501kf03 *lcd, int power)
284{
285 int ret = 0;
286
287 if (lms501kf03_power_is_on(power) &&
288 !lms501kf03_power_is_on(lcd->power))
289 ret = lms501kf03_power_on(lcd);
290 else if (!lms501kf03_power_is_on(power) &&
291 lms501kf03_power_is_on(lcd->power))
292 ret = lms501kf03_power_off(lcd);
293
294 if (!ret)
295 lcd->power = power;
296
297 return ret;
298}
299
300static int lms501kf03_get_power(struct lcd_device *ld)
301{
302 struct lms501kf03 *lcd = lcd_get_data(ld);
303
304 return lcd->power;
305}
306
307static int lms501kf03_set_power(struct lcd_device *ld, int power)
308{
309 struct lms501kf03 *lcd = lcd_get_data(ld);
310
311 if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
312 power != FB_BLANK_NORMAL) {
313 dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
314 return -EINVAL;
315 }
316
317 return lms501kf03_power(lcd, power);
318}
319
320static struct lcd_ops lms501kf03_lcd_ops = {
321 .get_power = lms501kf03_get_power,
322 .set_power = lms501kf03_set_power,
323};
324
325static int lms501kf03_probe(struct spi_device *spi)
326{
327 struct lms501kf03 *lcd = NULL;
328 struct lcd_device *ld = NULL;
329 int ret = 0;
330
331 lcd = devm_kzalloc(&spi->dev, sizeof(struct lms501kf03), GFP_KERNEL);
332 if (!lcd)
333 return -ENOMEM;
334
335 /* lms501kf03 lcd panel uses 3-wire 9-bit SPI Mode. */
336 spi->bits_per_word = 9;
337
338 ret = spi_setup(spi);
339 if (ret < 0) {
340 dev_err(&spi->dev, "spi setup failed.\n");
341 return ret;
342 }
343
344 lcd->spi = spi;
345 lcd->dev = &spi->dev;
346
347 lcd->lcd_pd = spi->dev.platform_data;
348 if (!lcd->lcd_pd) {
349 dev_err(&spi->dev, "platform data is NULL\n");
350 return -EINVAL;
351 }
352
353 ld = lcd_device_register("lms501kf03", &spi->dev, lcd,
354 &lms501kf03_lcd_ops);
355 if (IS_ERR(ld))
356 return PTR_ERR(ld);
357
358 lcd->ld = ld;
359
360 if (!lcd->lcd_pd->lcd_enabled) {
361 /*
362 * if lcd panel was off from bootloader then
363 * current lcd status is powerdown and then
364 * it enables lcd panel.
365 */
366 lcd->power = FB_BLANK_POWERDOWN;
367
368 lms501kf03_power(lcd, FB_BLANK_UNBLANK);
369 } else {
370 lcd->power = FB_BLANK_UNBLANK;
371 }
372
373 spi_set_drvdata(spi, lcd);
374
375 dev_info(&spi->dev, "lms501kf03 panel driver has been probed.\n");
376
377 return 0;
378}
379
380static int lms501kf03_remove(struct spi_device *spi)
381{
382 struct lms501kf03 *lcd = spi_get_drvdata(spi);
383
384 lms501kf03_power(lcd, FB_BLANK_POWERDOWN);
385 lcd_device_unregister(lcd->ld);
386
387 return 0;
388}
389
390#if defined(CONFIG_PM)
391
392static int lms501kf03_suspend(struct spi_device *spi, pm_message_t mesg)
393{
394 struct lms501kf03 *lcd = spi_get_drvdata(spi);
395
396 dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
397
398 /*
399 * when lcd panel is suspend, lcd panel becomes off
400 * regardless of status.
401 */
402 return lms501kf03_power(lcd, FB_BLANK_POWERDOWN);
403}
404
405static int lms501kf03_resume(struct spi_device *spi)
406{
407 struct lms501kf03 *lcd = spi_get_drvdata(spi);
408
409 lcd->power = FB_BLANK_POWERDOWN;
410
411 return lms501kf03_power(lcd, FB_BLANK_UNBLANK);
412}
413#else
414#define lms501kf03_suspend NULL
415#define lms501kf03_resume NULL
416#endif
417
418static void lms501kf03_shutdown(struct spi_device *spi)
419{
420 struct lms501kf03 *lcd = spi_get_drvdata(spi);
421
422 lms501kf03_power(lcd, FB_BLANK_POWERDOWN);
423}
424
425static struct spi_driver lms501kf03_driver = {
426 .driver = {
427 .name = "lms501kf03",
428 .owner = THIS_MODULE,
429 },
430 .probe = lms501kf03_probe,
431 .remove = lms501kf03_remove,
432 .shutdown = lms501kf03_shutdown,
433 .suspend = lms501kf03_suspend,
434 .resume = lms501kf03_resume,
435};
436
437module_spi_driver(lms501kf03_driver);
438
439MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
440MODULE_DESCRIPTION("lms501kf03 LCD Driver");
441MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
index 6e4db0c874c8..7ae9ae6f4655 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -17,21 +17,48 @@
17#include <linux/platform_data/lp855x.h> 17#include <linux/platform_data/lp855x.h>
18#include <linux/pwm.h> 18#include <linux/pwm.h>
19 19
20/* Registers */ 20/* LP8550/1/2/3/6 Registers */
21#define BRIGHTNESS_CTRL 0x00 21#define LP855X_BRIGHTNESS_CTRL 0x00
22#define DEVICE_CTRL 0x01 22#define LP855X_DEVICE_CTRL 0x01
23#define EEPROM_START 0xA0 23#define LP855X_EEPROM_START 0xA0
24#define EEPROM_END 0xA7 24#define LP855X_EEPROM_END 0xA7
25#define EPROM_START 0xA0 25#define LP8556_EPROM_START 0xA0
26#define EPROM_END 0xAF 26#define LP8556_EPROM_END 0xAF
27
28/* LP8557 Registers */
29#define LP8557_BL_CMD 0x00
30#define LP8557_BL_MASK 0x01
31#define LP8557_BL_ON 0x01
32#define LP8557_BL_OFF 0x00
33#define LP8557_BRIGHTNESS_CTRL 0x04
34#define LP8557_CONFIG 0x10
35#define LP8557_EPROM_START 0x10
36#define LP8557_EPROM_END 0x1E
27 37
28#define BUF_SIZE 20 38#define BUF_SIZE 20
29#define DEFAULT_BL_NAME "lcd-backlight" 39#define DEFAULT_BL_NAME "lcd-backlight"
30#define MAX_BRIGHTNESS 255 40#define MAX_BRIGHTNESS 255
31 41
42struct lp855x;
43
44/*
45 * struct lp855x_device_config
46 * @pre_init_device: init device function call before updating the brightness
47 * @reg_brightness: register address for brigthenss control
48 * @reg_devicectrl: register address for device control
49 * @post_init_device: late init device function call
50 */
51struct lp855x_device_config {
52 int (*pre_init_device)(struct lp855x *);
53 u8 reg_brightness;
54 u8 reg_devicectrl;
55 int (*post_init_device)(struct lp855x *);
56};
57
32struct lp855x { 58struct lp855x {
33 const char *chipname; 59 const char *chipname;
34 enum lp855x_chip_id chip_id; 60 enum lp855x_chip_id chip_id;
61 struct lp855x_device_config *cfg;
35 struct i2c_client *client; 62 struct i2c_client *client;
36 struct backlight_device *bl; 63 struct backlight_device *bl;
37 struct device *dev; 64 struct device *dev;
@@ -39,9 +66,15 @@ struct lp855x {
39 struct pwm_device *pwm; 66 struct pwm_device *pwm;
40}; 67};
41 68
42static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data) 69static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
70{
71 return i2c_smbus_write_byte_data(lp->client, reg, data);
72}
73
74static int lp855x_update_bit(struct lp855x *lp, u8 reg, u8 mask, u8 data)
43{ 75{
44 int ret; 76 int ret;
77 u8 tmp;
45 78
46 ret = i2c_smbus_read_byte_data(lp->client, reg); 79 ret = i2c_smbus_read_byte_data(lp->client, reg);
47 if (ret < 0) { 80 if (ret < 0) {
@@ -49,13 +82,11 @@ static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
49 return ret; 82 return ret;
50 } 83 }
51 84
52 *data = (u8)ret; 85 tmp = (u8)ret;
53 return 0; 86 tmp &= ~mask;
54} 87 tmp |= data & mask;
55 88
56static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data) 89 return lp855x_write_byte(lp, reg, tmp);
57{
58 return i2c_smbus_write_byte_data(lp->client, reg, data);
59} 90}
60 91
61static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr) 92static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
@@ -67,12 +98,16 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
67 case LP8551: 98 case LP8551:
68 case LP8552: 99 case LP8552:
69 case LP8553: 100 case LP8553:
70 start = EEPROM_START; 101 start = LP855X_EEPROM_START;
71 end = EEPROM_END; 102 end = LP855X_EEPROM_END;
72 break; 103 break;
73 case LP8556: 104 case LP8556:
74 start = EPROM_START; 105 start = LP8556_EPROM_START;
75 end = EPROM_END; 106 end = LP8556_EPROM_END;
107 break;
108 case LP8557:
109 start = LP8557_EPROM_START;
110 end = LP8557_EPROM_END;
76 break; 111 break;
77 default: 112 default:
78 return false; 113 return false;
@@ -81,21 +116,76 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
81 return (addr >= start && addr <= end); 116 return (addr >= start && addr <= end);
82} 117}
83 118
84static int lp855x_init_registers(struct lp855x *lp) 119static int lp8557_bl_off(struct lp855x *lp)
120{
121 /* BL_ON = 0 before updating EPROM settings */
122 return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK,
123 LP8557_BL_OFF);
124}
125
126static int lp8557_bl_on(struct lp855x *lp)
127{
128 /* BL_ON = 1 after updating EPROM settings */
129 return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK,
130 LP8557_BL_ON);
131}
132
133static struct lp855x_device_config lp855x_dev_cfg = {
134 .reg_brightness = LP855X_BRIGHTNESS_CTRL,
135 .reg_devicectrl = LP855X_DEVICE_CTRL,
136};
137
138static struct lp855x_device_config lp8557_dev_cfg = {
139 .reg_brightness = LP8557_BRIGHTNESS_CTRL,
140 .reg_devicectrl = LP8557_CONFIG,
141 .pre_init_device = lp8557_bl_off,
142 .post_init_device = lp8557_bl_on,
143};
144
145/*
146 * Device specific configuration flow
147 *
148 * a) pre_init_device(optional)
149 * b) update the brightness register
150 * c) update device control register
151 * d) update ROM area(optional)
152 * e) post_init_device(optional)
153 *
154 */
155static int lp855x_configure(struct lp855x *lp)
85{ 156{
86 u8 val, addr; 157 u8 val, addr;
87 int i, ret; 158 int i, ret;
88 struct lp855x_platform_data *pd = lp->pdata; 159 struct lp855x_platform_data *pd = lp->pdata;
89 160
161 switch (lp->chip_id) {
162 case LP8550 ... LP8556:
163 lp->cfg = &lp855x_dev_cfg;
164 break;
165 case LP8557:
166 lp->cfg = &lp8557_dev_cfg;
167 break;
168 default:
169 return -EINVAL;
170 }
171
172 if (lp->cfg->pre_init_device) {
173 ret = lp->cfg->pre_init_device(lp);
174 if (ret) {
175 dev_err(lp->dev, "pre init device err: %d\n", ret);
176 goto err;
177 }
178 }
179
90 val = pd->initial_brightness; 180 val = pd->initial_brightness;
91 ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val); 181 ret = lp855x_write_byte(lp, lp->cfg->reg_brightness, val);
92 if (ret) 182 if (ret)
93 return ret; 183 goto err;
94 184
95 val = pd->device_control; 185 val = pd->device_control;
96 ret = lp855x_write_byte(lp, DEVICE_CTRL, val); 186 ret = lp855x_write_byte(lp, lp->cfg->reg_devicectrl, val);
97 if (ret) 187 if (ret)
98 return ret; 188 goto err;
99 189
100 if (pd->load_new_rom_data && pd->size_program) { 190 if (pd->load_new_rom_data && pd->size_program) {
101 for (i = 0; i < pd->size_program; i++) { 191 for (i = 0; i < pd->size_program; i++) {
@@ -106,10 +196,21 @@ static int lp855x_init_registers(struct lp855x *lp)
106 196
107 ret = lp855x_write_byte(lp, addr, val); 197 ret = lp855x_write_byte(lp, addr, val);
108 if (ret) 198 if (ret)
109 return ret; 199 goto err;
200 }
201 }
202
203 if (lp->cfg->post_init_device) {
204 ret = lp->cfg->post_init_device(lp);
205 if (ret) {
206 dev_err(lp->dev, "post init device err: %d\n", ret);
207 goto err;
110 } 208 }
111 } 209 }
112 210
211 return 0;
212
213err:
113 return ret; 214 return ret;
114} 215}
115 216
@@ -151,7 +252,7 @@ static int lp855x_bl_update_status(struct backlight_device *bl)
151 252
152 } else if (mode == REGISTER_BASED) { 253 } else if (mode == REGISTER_BASED) {
153 u8 val = bl->props.brightness; 254 u8 val = bl->props.brightness;
154 lp855x_write_byte(lp, BRIGHTNESS_CTRL, val); 255 lp855x_write_byte(lp, lp->cfg->reg_brightness, val);
155 } 256 }
156 257
157 return 0; 258 return 0;
@@ -159,16 +260,6 @@ static int lp855x_bl_update_status(struct backlight_device *bl)
159 260
160static int lp855x_bl_get_brightness(struct backlight_device *bl) 261static int lp855x_bl_get_brightness(struct backlight_device *bl)
161{ 262{
162 struct lp855x *lp = bl_get_data(bl);
163 enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
164
165 if (mode == REGISTER_BASED) {
166 u8 val = 0;
167
168 lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
169 bl->props.brightness = val;
170 }
171
172 return bl->props.brightness; 263 return bl->props.brightness;
173} 264}
174 265
@@ -271,11 +362,10 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
271 lp->chip_id = id->driver_data; 362 lp->chip_id = id->driver_data;
272 i2c_set_clientdata(cl, lp); 363 i2c_set_clientdata(cl, lp);
273 364
274 ret = lp855x_init_registers(lp); 365 ret = lp855x_configure(lp);
275 if (ret) { 366 if (ret) {
276 dev_err(lp->dev, "i2c communication err: %d", ret); 367 dev_err(lp->dev, "device config err: %d", ret);
277 if (mode == REGISTER_BASED) 368 goto err_dev;
278 goto err_dev;
279 } 369 }
280 370
281 ret = lp855x_backlight_register(lp); 371 ret = lp855x_backlight_register(lp);
@@ -318,6 +408,7 @@ static const struct i2c_device_id lp855x_ids[] = {
318 {"lp8552", LP8552}, 408 {"lp8552", LP8552},
319 {"lp8553", LP8553}, 409 {"lp8553", LP8553},
320 {"lp8556", LP8556}, 410 {"lp8556", LP8556},
411 {"lp8557", LP8557},
321 { } 412 { }
322}; 413};
323MODULE_DEVICE_TABLE(i2c, lp855x_ids); 414MODULE_DEVICE_TABLE(i2c, lp855x_ids);
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index 226d813edf01..c0b4b8f2de98 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -252,7 +252,7 @@ static int ltv350qv_probe(struct spi_device *spi)
252 if (ret) 252 if (ret)
253 goto out_unregister; 253 goto out_unregister;
254 254
255 dev_set_drvdata(&spi->dev, lcd); 255 spi_set_drvdata(spi, lcd);
256 256
257 return 0; 257 return 0;
258 258
@@ -263,7 +263,7 @@ out_unregister:
263 263
264static int ltv350qv_remove(struct spi_device *spi) 264static int ltv350qv_remove(struct spi_device *spi)
265{ 265{
266 struct ltv350qv *lcd = dev_get_drvdata(&spi->dev); 266 struct ltv350qv *lcd = spi_get_drvdata(spi);
267 267
268 ltv350qv_power(lcd, FB_BLANK_POWERDOWN); 268 ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
269 lcd_device_unregister(lcd->ld); 269 lcd_device_unregister(lcd->ld);
@@ -274,14 +274,14 @@ static int ltv350qv_remove(struct spi_device *spi)
274#ifdef CONFIG_PM 274#ifdef CONFIG_PM
275static int ltv350qv_suspend(struct spi_device *spi, pm_message_t state) 275static int ltv350qv_suspend(struct spi_device *spi, pm_message_t state)
276{ 276{
277 struct ltv350qv *lcd = dev_get_drvdata(&spi->dev); 277 struct ltv350qv *lcd = spi_get_drvdata(spi);
278 278
279 return ltv350qv_power(lcd, FB_BLANK_POWERDOWN); 279 return ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
280} 280}
281 281
282static int ltv350qv_resume(struct spi_device *spi) 282static int ltv350qv_resume(struct spi_device *spi)
283{ 283{
284 struct ltv350qv *lcd = dev_get_drvdata(&spi->dev); 284 struct ltv350qv *lcd = spi_get_drvdata(spi);
285 285
286 return ltv350qv_power(lcd, FB_BLANK_UNBLANK); 286 return ltv350qv_power(lcd, FB_BLANK_UNBLANK);
287} 287}
@@ -293,7 +293,7 @@ static int ltv350qv_resume(struct spi_device *spi)
293/* Power down all displays on reboot, poweroff or halt */ 293/* Power down all displays on reboot, poweroff or halt */
294static void ltv350qv_shutdown(struct spi_device *spi) 294static void ltv350qv_shutdown(struct spi_device *spi)
295{ 295{
296 struct ltv350qv *lcd = dev_get_drvdata(&spi->dev); 296 struct ltv350qv *lcd = spi_get_drvdata(spi);
297 297
298 ltv350qv_power(lcd, FB_BLANK_POWERDOWN); 298 ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
299} 299}
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index af31c269baa6..627110163067 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -77,7 +77,7 @@ static void omapbl_blank(struct omap_backlight *bl, int mode)
77static int omapbl_suspend(struct platform_device *pdev, pm_message_t state) 77static int omapbl_suspend(struct platform_device *pdev, pm_message_t state)
78{ 78{
79 struct backlight_device *dev = platform_get_drvdata(pdev); 79 struct backlight_device *dev = platform_get_drvdata(pdev);
80 struct omap_backlight *bl = dev_get_drvdata(&dev->dev); 80 struct omap_backlight *bl = bl_get_data(dev);
81 81
82 omapbl_blank(bl, FB_BLANK_POWERDOWN); 82 omapbl_blank(bl, FB_BLANK_POWERDOWN);
83 return 0; 83 return 0;
@@ -86,7 +86,7 @@ static int omapbl_suspend(struct platform_device *pdev, pm_message_t state)
86static int omapbl_resume(struct platform_device *pdev) 86static int omapbl_resume(struct platform_device *pdev)
87{ 87{
88 struct backlight_device *dev = platform_get_drvdata(pdev); 88 struct backlight_device *dev = platform_get_drvdata(pdev);
89 struct omap_backlight *bl = dev_get_drvdata(&dev->dev); 89 struct omap_backlight *bl = bl_get_data(dev);
90 90
91 omapbl_blank(bl, bl->powermode); 91 omapbl_blank(bl, bl->powermode);
92 return 0; 92 return 0;
@@ -98,7 +98,7 @@ static int omapbl_resume(struct platform_device *pdev)
98 98
99static int omapbl_set_power(struct backlight_device *dev, int state) 99static int omapbl_set_power(struct backlight_device *dev, int state)
100{ 100{
101 struct omap_backlight *bl = dev_get_drvdata(&dev->dev); 101 struct omap_backlight *bl = bl_get_data(dev);
102 102
103 omapbl_blank(bl, state); 103 omapbl_blank(bl, state);
104 bl->powermode = state; 104 bl->powermode = state;
@@ -108,7 +108,7 @@ static int omapbl_set_power(struct backlight_device *dev, int state)
108 108
109static int omapbl_update_status(struct backlight_device *dev) 109static int omapbl_update_status(struct backlight_device *dev)
110{ 110{
111 struct omap_backlight *bl = dev_get_drvdata(&dev->dev); 111 struct omap_backlight *bl = bl_get_data(dev);
112 112
113 if (bl->current_intensity != dev->props.brightness) { 113 if (bl->current_intensity != dev->props.brightness) {
114 if (bl->powermode == FB_BLANK_UNBLANK) 114 if (bl->powermode == FB_BLANK_UNBLANK)
@@ -124,7 +124,7 @@ static int omapbl_update_status(struct backlight_device *dev)
124 124
125static int omapbl_get_intensity(struct backlight_device *dev) 125static int omapbl_get_intensity(struct backlight_device *dev)
126{ 126{
127 struct omap_backlight *bl = dev_get_drvdata(&dev->dev); 127 struct omap_backlight *bl = bl_get_data(dev);
128 return bl->current_intensity; 128 return bl->current_intensity;
129} 129}
130 130
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 069983ca49ff..f2f4c43d6e22 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -37,7 +37,7 @@ struct pwm_bl_data {
37 37
38static int pwm_backlight_update_status(struct backlight_device *bl) 38static int pwm_backlight_update_status(struct backlight_device *bl)
39{ 39{
40 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); 40 struct pwm_bl_data *pb = bl_get_data(bl);
41 int brightness = bl->props.brightness; 41 int brightness = bl->props.brightness;
42 int max = bl->props.max_brightness; 42 int max = bl->props.max_brightness;
43 43
@@ -83,7 +83,7 @@ static int pwm_backlight_get_brightness(struct backlight_device *bl)
83static int pwm_backlight_check_fb(struct backlight_device *bl, 83static int pwm_backlight_check_fb(struct backlight_device *bl,
84 struct fb_info *info) 84 struct fb_info *info)
85{ 85{
86 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); 86 struct pwm_bl_data *pb = bl_get_data(bl);
87 87
88 return !pb->check_fb || pb->check_fb(pb->dev, info); 88 return !pb->check_fb || pb->check_fb(pb->dev, info);
89} 89}
@@ -264,7 +264,7 @@ err_alloc:
264static int pwm_backlight_remove(struct platform_device *pdev) 264static int pwm_backlight_remove(struct platform_device *pdev)
265{ 265{
266 struct backlight_device *bl = platform_get_drvdata(pdev); 266 struct backlight_device *bl = platform_get_drvdata(pdev);
267 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); 267 struct pwm_bl_data *pb = bl_get_data(bl);
268 268
269 backlight_device_unregister(bl); 269 backlight_device_unregister(bl);
270 pwm_config(pb->pwm, 0, pb->period); 270 pwm_config(pb->pwm, 0, pb->period);
@@ -278,7 +278,7 @@ static int pwm_backlight_remove(struct platform_device *pdev)
278static int pwm_backlight_suspend(struct device *dev) 278static int pwm_backlight_suspend(struct device *dev)
279{ 279{
280 struct backlight_device *bl = dev_get_drvdata(dev); 280 struct backlight_device *bl = dev_get_drvdata(dev);
281 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); 281 struct pwm_bl_data *pb = bl_get_data(bl);
282 282
283 if (pb->notify) 283 if (pb->notify)
284 pb->notify(pb->dev, 0); 284 pb->notify(pb->dev, 0);
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c
index 3e1c1135f6df..9c2677f0ef7d 100644
--- a/drivers/video/backlight/s6e63m0.c
+++ b/drivers/video/backlight/s6e63m0.c
@@ -9,28 +9,19 @@
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */ 12 */
22 13
23#include <linux/wait.h> 14#include <linux/backlight.h>
24#include <linux/fb.h>
25#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/fb.h>
26#include <linux/gpio.h> 17#include <linux/gpio.h>
27#include <linux/spi/spi.h>
28#include <linux/irq.h>
29#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/irq.h>
30#include <linux/kernel.h> 20#include <linux/kernel.h>
31#include <linux/lcd.h> 21#include <linux/lcd.h>
32#include <linux/backlight.h>
33#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/spi/spi.h>
24#include <linux/wait.h>
34 25
35#include "s6e63m0_gamma.h" 26#include "s6e63m0_gamma.h"
36 27
@@ -43,8 +34,6 @@
43#define MIN_BRIGHTNESS 0 34#define MIN_BRIGHTNESS 0
44#define MAX_BRIGHTNESS 10 35#define MAX_BRIGHTNESS 10
45 36
46#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
47
48struct s6e63m0 { 37struct s6e63m0 {
49 struct device *dev; 38 struct device *dev;
50 struct spi_device *spi; 39 struct spi_device *spi;
@@ -57,7 +46,7 @@ struct s6e63m0 {
57 struct lcd_platform_data *lcd_pd; 46 struct lcd_platform_data *lcd_pd;
58}; 47};
59 48
60static const unsigned short SEQ_PANEL_CONDITION_SET[] = { 49static const unsigned short seq_panel_condition_set[] = {
61 0xF8, 0x01, 50 0xF8, 0x01,
62 DATA_ONLY, 0x27, 51 DATA_ONLY, 0x27,
63 DATA_ONLY, 0x27, 52 DATA_ONLY, 0x27,
@@ -76,7 +65,7 @@ static const unsigned short SEQ_PANEL_CONDITION_SET[] = {
76 ENDDEF, 0x0000 65 ENDDEF, 0x0000
77}; 66};
78 67
79static const unsigned short SEQ_DISPLAY_CONDITION_SET[] = { 68static const unsigned short seq_display_condition_set[] = {
80 0xf2, 0x02, 69 0xf2, 0x02,
81 DATA_ONLY, 0x03, 70 DATA_ONLY, 0x03,
82 DATA_ONLY, 0x1c, 71 DATA_ONLY, 0x1c,
@@ -90,7 +79,7 @@ static const unsigned short SEQ_DISPLAY_CONDITION_SET[] = {
90 ENDDEF, 0x0000 79 ENDDEF, 0x0000
91}; 80};
92 81
93static const unsigned short SEQ_GAMMA_SETTING[] = { 82static const unsigned short seq_gamma_setting[] = {
94 0xfa, 0x00, 83 0xfa, 0x00,
95 DATA_ONLY, 0x18, 84 DATA_ONLY, 0x18,
96 DATA_ONLY, 0x08, 85 DATA_ONLY, 0x08,
@@ -119,7 +108,7 @@ static const unsigned short SEQ_GAMMA_SETTING[] = {
119 ENDDEF, 0x0000 108 ENDDEF, 0x0000
120}; 109};
121 110
122static const unsigned short SEQ_ETC_CONDITION_SET[] = { 111static const unsigned short seq_etc_condition_set[] = {
123 0xf6, 0x00, 112 0xf6, 0x00,
124 DATA_ONLY, 0x8c, 113 DATA_ONLY, 0x8c,
125 DATA_ONLY, 0x07, 114 DATA_ONLY, 0x07,
@@ -318,47 +307,47 @@ static const unsigned short SEQ_ETC_CONDITION_SET[] = {
318 ENDDEF, 0x0000 307 ENDDEF, 0x0000
319}; 308};
320 309
321static const unsigned short SEQ_ACL_ON[] = { 310static const unsigned short seq_acl_on[] = {
322 /* ACL on */ 311 /* ACL on */
323 0xc0, 0x01, 312 0xc0, 0x01,
324 313
325 ENDDEF, 0x0000 314 ENDDEF, 0x0000
326}; 315};
327 316
328static const unsigned short SEQ_ACL_OFF[] = { 317static const unsigned short seq_acl_off[] = {
329 /* ACL off */ 318 /* ACL off */
330 0xc0, 0x00, 319 0xc0, 0x00,
331 320
332 ENDDEF, 0x0000 321 ENDDEF, 0x0000
333}; 322};
334 323
335static const unsigned short SEQ_ELVSS_ON[] = { 324static const unsigned short seq_elvss_on[] = {
336 /* ELVSS on */ 325 /* ELVSS on */
337 0xb1, 0x0b, 326 0xb1, 0x0b,
338 327
339 ENDDEF, 0x0000 328 ENDDEF, 0x0000
340}; 329};
341 330
342static const unsigned short SEQ_ELVSS_OFF[] = { 331static const unsigned short seq_elvss_off[] = {
343 /* ELVSS off */ 332 /* ELVSS off */
344 0xb1, 0x0a, 333 0xb1, 0x0a,
345 334
346 ENDDEF, 0x0000 335 ENDDEF, 0x0000
347}; 336};
348 337
349static const unsigned short SEQ_STAND_BY_OFF[] = { 338static const unsigned short seq_stand_by_off[] = {
350 0x11, COMMAND_ONLY, 339 0x11, COMMAND_ONLY,
351 340
352 ENDDEF, 0x0000 341 ENDDEF, 0x0000
353}; 342};
354 343
355static const unsigned short SEQ_STAND_BY_ON[] = { 344static const unsigned short seq_stand_by_on[] = {
356 0x10, COMMAND_ONLY, 345 0x10, COMMAND_ONLY,
357 346
358 ENDDEF, 0x0000 347 ENDDEF, 0x0000
359}; 348};
360 349
361static const unsigned short SEQ_DISPLAY_ON[] = { 350static const unsigned short seq_display_on[] = {
362 0x29, COMMAND_ONLY, 351 0x29, COMMAND_ONLY,
363 352
364 ENDDEF, 0x0000 353 ENDDEF, 0x0000
@@ -406,8 +395,9 @@ static int s6e63m0_panel_send_sequence(struct s6e63m0 *lcd,
406 ret = s6e63m0_spi_write(lcd, wbuf[i], wbuf[i+1]); 395 ret = s6e63m0_spi_write(lcd, wbuf[i], wbuf[i+1]);
407 if (ret) 396 if (ret)
408 break; 397 break;
409 } else 398 } else {
410 udelay(wbuf[i+1]*1000); 399 msleep(wbuf[i+1]);
400 }
411 i += 2; 401 i += 2;
412 } 402 }
413 403
@@ -457,12 +447,12 @@ static int s6e63m0_ldi_init(struct s6e63m0 *lcd)
457{ 447{
458 int ret, i; 448 int ret, i;
459 const unsigned short *init_seq[] = { 449 const unsigned short *init_seq[] = {
460 SEQ_PANEL_CONDITION_SET, 450 seq_panel_condition_set,
461 SEQ_DISPLAY_CONDITION_SET, 451 seq_display_condition_set,
462 SEQ_GAMMA_SETTING, 452 seq_gamma_setting,
463 SEQ_ETC_CONDITION_SET, 453 seq_etc_condition_set,
464 SEQ_ACL_ON, 454 seq_acl_on,
465 SEQ_ELVSS_ON, 455 seq_elvss_on,
466 }; 456 };
467 457
468 for (i = 0; i < ARRAY_SIZE(init_seq); i++) { 458 for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
@@ -478,8 +468,8 @@ static int s6e63m0_ldi_enable(struct s6e63m0 *lcd)
478{ 468{
479 int ret = 0, i; 469 int ret = 0, i;
480 const unsigned short *enable_seq[] = { 470 const unsigned short *enable_seq[] = {
481 SEQ_STAND_BY_OFF, 471 seq_stand_by_off,
482 SEQ_DISPLAY_ON, 472 seq_display_on,
483 }; 473 };
484 474
485 for (i = 0; i < ARRAY_SIZE(enable_seq); i++) { 475 for (i = 0; i < ARRAY_SIZE(enable_seq); i++) {
@@ -495,43 +485,39 @@ static int s6e63m0_ldi_disable(struct s6e63m0 *lcd)
495{ 485{
496 int ret; 486 int ret;
497 487
498 ret = s6e63m0_panel_send_sequence(lcd, SEQ_STAND_BY_ON); 488 ret = s6e63m0_panel_send_sequence(lcd, seq_stand_by_on);
499 489
500 return ret; 490 return ret;
501} 491}
502 492
493static int s6e63m0_power_is_on(int power)
494{
495 return power <= FB_BLANK_NORMAL;
496}
497
503static int s6e63m0_power_on(struct s6e63m0 *lcd) 498static int s6e63m0_power_on(struct s6e63m0 *lcd)
504{ 499{
505 int ret = 0; 500 int ret = 0;
506 struct lcd_platform_data *pd = NULL; 501 struct lcd_platform_data *pd;
507 struct backlight_device *bd = NULL; 502 struct backlight_device *bd;
508 503
509 pd = lcd->lcd_pd; 504 pd = lcd->lcd_pd;
510 if (!pd) {
511 dev_err(lcd->dev, "platform data is NULL.\n");
512 return -EFAULT;
513 }
514
515 bd = lcd->bd; 505 bd = lcd->bd;
516 if (!bd) {
517 dev_err(lcd->dev, "backlight device is NULL.\n");
518 return -EFAULT;
519 }
520 506
521 if (!pd->power_on) { 507 if (!pd->power_on) {
522 dev_err(lcd->dev, "power_on is NULL.\n"); 508 dev_err(lcd->dev, "power_on is NULL.\n");
523 return -EFAULT; 509 return -EINVAL;
524 } else { 510 } else {
525 pd->power_on(lcd->ld, 1); 511 pd->power_on(lcd->ld, 1);
526 mdelay(pd->power_on_delay); 512 msleep(pd->power_on_delay);
527 } 513 }
528 514
529 if (!pd->reset) { 515 if (!pd->reset) {
530 dev_err(lcd->dev, "reset is NULL.\n"); 516 dev_err(lcd->dev, "reset is NULL.\n");
531 return -EFAULT; 517 return -EINVAL;
532 } else { 518 } else {
533 pd->reset(lcd->ld); 519 pd->reset(lcd->ld);
534 mdelay(pd->reset_delay); 520 msleep(pd->reset_delay);
535 } 521 }
536 522
537 ret = s6e63m0_ldi_init(lcd); 523 ret = s6e63m0_ldi_init(lcd);
@@ -558,14 +544,10 @@ static int s6e63m0_power_on(struct s6e63m0 *lcd)
558 544
559static int s6e63m0_power_off(struct s6e63m0 *lcd) 545static int s6e63m0_power_off(struct s6e63m0 *lcd)
560{ 546{
561 int ret = 0; 547 int ret;
562 struct lcd_platform_data *pd = NULL; 548 struct lcd_platform_data *pd;
563 549
564 pd = lcd->lcd_pd; 550 pd = lcd->lcd_pd;
565 if (!pd) {
566 dev_err(lcd->dev, "platform data is NULL.\n");
567 return -EFAULT;
568 }
569 551
570 ret = s6e63m0_ldi_disable(lcd); 552 ret = s6e63m0_ldi_disable(lcd);
571 if (ret) { 553 if (ret) {
@@ -573,13 +555,9 @@ static int s6e63m0_power_off(struct s6e63m0 *lcd)
573 return -EIO; 555 return -EIO;
574 } 556 }
575 557
576 mdelay(pd->power_off_delay); 558 msleep(pd->power_off_delay);
577 559
578 if (!pd->power_on) { 560 pd->power_on(lcd->ld, 0);
579 dev_err(lcd->dev, "power_on is NULL.\n");
580 return -EFAULT;
581 } else
582 pd->power_on(lcd->ld, 0);
583 561
584 return 0; 562 return 0;
585} 563}
@@ -588,9 +566,9 @@ static int s6e63m0_power(struct s6e63m0 *lcd, int power)
588{ 566{
589 int ret = 0; 567 int ret = 0;
590 568
591 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power)) 569 if (s6e63m0_power_is_on(power) && !s6e63m0_power_is_on(lcd->power))
592 ret = s6e63m0_power_on(lcd); 570 ret = s6e63m0_power_on(lcd);
593 else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power)) 571 else if (!s6e63m0_power_is_on(power) && s6e63m0_power_is_on(lcd->power))
594 ret = s6e63m0_power_off(lcd); 572 ret = s6e63m0_power_off(lcd);
595 573
596 if (!ret) 574 if (!ret)
@@ -760,7 +738,7 @@ static int s6e63m0_probe(struct spi_device *spi)
760 lcd->lcd_pd = spi->dev.platform_data; 738 lcd->lcd_pd = spi->dev.platform_data;
761 if (!lcd->lcd_pd) { 739 if (!lcd->lcd_pd) {
762 dev_err(&spi->dev, "platform data is NULL.\n"); 740 dev_err(&spi->dev, "platform data is NULL.\n");
763 return -EFAULT; 741 return -EINVAL;
764 } 742 }
765 743
766 ld = lcd_device_register("s6e63m0", &spi->dev, lcd, &s6e63m0_lcd_ops); 744 ld = lcd_device_register("s6e63m0", &spi->dev, lcd, &s6e63m0_lcd_ops);
@@ -788,7 +766,7 @@ static int s6e63m0_probe(struct spi_device *spi)
788 * know that. 766 * know that.
789 */ 767 */
790 lcd->gamma_table_count = 768 lcd->gamma_table_count =
791 sizeof(gamma_table) / (MAX_GAMMA_LEVEL * sizeof(int)); 769 sizeof(gamma_table) / (MAX_GAMMA_LEVEL * sizeof(int *));
792 770
793 ret = device_create_file(&(spi->dev), &dev_attr_gamma_mode); 771 ret = device_create_file(&(spi->dev), &dev_attr_gamma_mode);
794 if (ret < 0) 772 if (ret < 0)
@@ -811,10 +789,11 @@ static int s6e63m0_probe(struct spi_device *spi)
811 lcd->power = FB_BLANK_POWERDOWN; 789 lcd->power = FB_BLANK_POWERDOWN;
812 790
813 s6e63m0_power(lcd, FB_BLANK_UNBLANK); 791 s6e63m0_power(lcd, FB_BLANK_UNBLANK);
814 } else 792 } else {
815 lcd->power = FB_BLANK_UNBLANK; 793 lcd->power = FB_BLANK_UNBLANK;
794 }
816 795
817 dev_set_drvdata(&spi->dev, lcd); 796 spi_set_drvdata(spi, lcd);
818 797
819 dev_info(&spi->dev, "s6e63m0 panel driver has been probed.\n"); 798 dev_info(&spi->dev, "s6e63m0 panel driver has been probed.\n");
820 799
@@ -827,7 +806,7 @@ out_lcd_unregister:
827 806
828static int s6e63m0_remove(struct spi_device *spi) 807static int s6e63m0_remove(struct spi_device *spi)
829{ 808{
830 struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); 809 struct s6e63m0 *lcd = spi_get_drvdata(spi);
831 810
832 s6e63m0_power(lcd, FB_BLANK_POWERDOWN); 811 s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
833 device_remove_file(&spi->dev, &dev_attr_gamma_table); 812 device_remove_file(&spi->dev, &dev_attr_gamma_table);
@@ -839,44 +818,26 @@ static int s6e63m0_remove(struct spi_device *spi)
839} 818}
840 819
841#if defined(CONFIG_PM) 820#if defined(CONFIG_PM)
842static unsigned int before_power;
843
844static int s6e63m0_suspend(struct spi_device *spi, pm_message_t mesg) 821static int s6e63m0_suspend(struct spi_device *spi, pm_message_t mesg)
845{ 822{
846 int ret = 0; 823 struct s6e63m0 *lcd = spi_get_drvdata(spi);
847 struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
848 824
849 dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power); 825 dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
850 826
851 before_power = lcd->power;
852
853 /* 827 /*
854 * when lcd panel is suspend, lcd panel becomes off 828 * when lcd panel is suspend, lcd panel becomes off
855 * regardless of status. 829 * regardless of status.
856 */ 830 */
857 ret = s6e63m0_power(lcd, FB_BLANK_POWERDOWN); 831 return s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
858
859 return ret;
860} 832}
861 833
862static int s6e63m0_resume(struct spi_device *spi) 834static int s6e63m0_resume(struct spi_device *spi)
863{ 835{
864 int ret = 0; 836 struct s6e63m0 *lcd = spi_get_drvdata(spi);
865 struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
866
867 /*
868 * after suspended, if lcd panel status is FB_BLANK_UNBLANK
869 * (at that time, before_power is FB_BLANK_UNBLANK) then
870 * it changes that status to FB_BLANK_POWERDOWN to get lcd on.
871 */
872 if (before_power == FB_BLANK_UNBLANK)
873 lcd->power = FB_BLANK_POWERDOWN;
874 837
875 dev_dbg(&spi->dev, "before_power = %d\n", before_power); 838 lcd->power = FB_BLANK_POWERDOWN;
876 839
877 ret = s6e63m0_power(lcd, before_power); 840 return s6e63m0_power(lcd, FB_BLANK_UNBLANK);
878
879 return ret;
880} 841}
881#else 842#else
882#define s6e63m0_suspend NULL 843#define s6e63m0_suspend NULL
@@ -886,7 +847,7 @@ static int s6e63m0_resume(struct spi_device *spi)
886/* Power down all displays on reboot, poweroff or halt. */ 847/* Power down all displays on reboot, poweroff or halt. */
887static void s6e63m0_shutdown(struct spi_device *spi) 848static void s6e63m0_shutdown(struct spi_device *spi)
888{ 849{
889 struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); 850 struct s6e63m0 *lcd = spi_get_drvdata(spi);
890 851
891 s6e63m0_power(lcd, FB_BLANK_POWERDOWN); 852 s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
892} 853}
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c
index ad2325f3d652..00162085eec0 100644
--- a/drivers/video/backlight/tdo24m.c
+++ b/drivers/video/backlight/tdo24m.c
@@ -390,7 +390,7 @@ static int tdo24m_probe(struct spi_device *spi)
390 if (IS_ERR(lcd->lcd_dev)) 390 if (IS_ERR(lcd->lcd_dev))
391 return PTR_ERR(lcd->lcd_dev); 391 return PTR_ERR(lcd->lcd_dev);
392 392
393 dev_set_drvdata(&spi->dev, lcd); 393 spi_set_drvdata(spi, lcd);
394 err = tdo24m_power(lcd, FB_BLANK_UNBLANK); 394 err = tdo24m_power(lcd, FB_BLANK_UNBLANK);
395 if (err) 395 if (err)
396 goto out_unregister; 396 goto out_unregister;
@@ -404,7 +404,7 @@ out_unregister:
404 404
405static int tdo24m_remove(struct spi_device *spi) 405static int tdo24m_remove(struct spi_device *spi)
406{ 406{
407 struct tdo24m *lcd = dev_get_drvdata(&spi->dev); 407 struct tdo24m *lcd = spi_get_drvdata(spi);
408 408
409 tdo24m_power(lcd, FB_BLANK_POWERDOWN); 409 tdo24m_power(lcd, FB_BLANK_POWERDOWN);
410 lcd_device_unregister(lcd->lcd_dev); 410 lcd_device_unregister(lcd->lcd_dev);
@@ -415,14 +415,14 @@ static int tdo24m_remove(struct spi_device *spi)
415#ifdef CONFIG_PM 415#ifdef CONFIG_PM
416static int tdo24m_suspend(struct spi_device *spi, pm_message_t state) 416static int tdo24m_suspend(struct spi_device *spi, pm_message_t state)
417{ 417{
418 struct tdo24m *lcd = dev_get_drvdata(&spi->dev); 418 struct tdo24m *lcd = spi_get_drvdata(spi);
419 419
420 return tdo24m_power(lcd, FB_BLANK_POWERDOWN); 420 return tdo24m_power(lcd, FB_BLANK_POWERDOWN);
421} 421}
422 422
423static int tdo24m_resume(struct spi_device *spi) 423static int tdo24m_resume(struct spi_device *spi)
424{ 424{
425 struct tdo24m *lcd = dev_get_drvdata(&spi->dev); 425 struct tdo24m *lcd = spi_get_drvdata(spi);
426 426
427 return tdo24m_power(lcd, FB_BLANK_UNBLANK); 427 return tdo24m_power(lcd, FB_BLANK_UNBLANK);
428} 428}
@@ -434,7 +434,7 @@ static int tdo24m_resume(struct spi_device *spi)
434/* Power down all displays on reboot, poweroff or halt */ 434/* Power down all displays on reboot, poweroff or halt */
435static void tdo24m_shutdown(struct spi_device *spi) 435static void tdo24m_shutdown(struct spi_device *spi)
436{ 436{
437 struct tdo24m *lcd = dev_get_drvdata(&spi->dev); 437 struct tdo24m *lcd = spi_get_drvdata(spi);
438 438
439 tdo24m_power(lcd, FB_BLANK_POWERDOWN); 439 tdo24m_power(lcd, FB_BLANK_POWERDOWN);
440} 440}
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index 588682cc1614..2326fa810c59 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -54,7 +54,7 @@ static void tosa_bl_set_backlight(struct tosa_bl_data *data, int brightness)
54static int tosa_bl_update_status(struct backlight_device *dev) 54static int tosa_bl_update_status(struct backlight_device *dev)
55{ 55{
56 struct backlight_properties *props = &dev->props; 56 struct backlight_properties *props = &dev->props;
57 struct tosa_bl_data *data = dev_get_drvdata(&dev->dev); 57 struct tosa_bl_data *data = bl_get_data(dev);
58 int power = max(props->power, props->fb_blank); 58 int power = max(props->power, props->fb_blank);
59 int brightness = props->brightness; 59 int brightness = props->brightness;
60 60
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c
index 96bae941585a..666fe2593ea4 100644
--- a/drivers/video/backlight/tosa_lcd.c
+++ b/drivers/video/backlight/tosa_lcd.c
@@ -193,7 +193,7 @@ static int tosa_lcd_probe(struct spi_device *spi)
193 return ret; 193 return ret;
194 194
195 data->spi = spi; 195 data->spi = spi;
196 dev_set_drvdata(&spi->dev, data); 196 spi_set_drvdata(spi, data);
197 197
198 ret = devm_gpio_request_one(&spi->dev, TOSA_GPIO_TG_ON, 198 ret = devm_gpio_request_one(&spi->dev, TOSA_GPIO_TG_ON,
199 GPIOF_OUT_INIT_LOW, "tg #pwr"); 199 GPIOF_OUT_INIT_LOW, "tg #pwr");
@@ -220,13 +220,13 @@ static int tosa_lcd_probe(struct spi_device *spi)
220err_register: 220err_register:
221 tosa_lcd_tg_off(data); 221 tosa_lcd_tg_off(data);
222err_gpio_tg: 222err_gpio_tg:
223 dev_set_drvdata(&spi->dev, NULL); 223 spi_set_drvdata(spi, NULL);
224 return ret; 224 return ret;
225} 225}
226 226
227static int tosa_lcd_remove(struct spi_device *spi) 227static int tosa_lcd_remove(struct spi_device *spi)
228{ 228{
229 struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev); 229 struct tosa_lcd_data *data = spi_get_drvdata(spi);
230 230
231 lcd_device_unregister(data->lcd); 231 lcd_device_unregister(data->lcd);
232 232
@@ -235,7 +235,7 @@ static int tosa_lcd_remove(struct spi_device *spi)
235 235
236 tosa_lcd_tg_off(data); 236 tosa_lcd_tg_off(data);
237 237
238 dev_set_drvdata(&spi->dev, NULL); 238 spi_set_drvdata(spi, NULL);
239 239
240 return 0; 240 return 0;
241} 241}
@@ -243,7 +243,7 @@ static int tosa_lcd_remove(struct spi_device *spi)
243#ifdef CONFIG_PM 243#ifdef CONFIG_PM
244static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state) 244static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state)
245{ 245{
246 struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev); 246 struct tosa_lcd_data *data = spi_get_drvdata(spi);
247 247
248 tosa_lcd_tg_off(data); 248 tosa_lcd_tg_off(data);
249 249
@@ -252,7 +252,7 @@ static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state)
252 252
253static int tosa_lcd_resume(struct spi_device *spi) 253static int tosa_lcd_resume(struct spi_device *spi)
254{ 254{
255 struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev); 255 struct tosa_lcd_data *data = spi_get_drvdata(spi);
256 256
257 tosa_lcd_tg_init(data); 257 tosa_lcd_tg_init(data);
258 if (POWER_IS_ON(data->lcd_power)) 258 if (POWER_IS_ON(data->lcd_power))
diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c
index 45e81b4cf8b4..84d582f591dc 100644
--- a/drivers/video/backlight/vgg2432a4.c
+++ b/drivers/video/backlight/vgg2432a4.c
@@ -208,12 +208,11 @@ static int vgg2432a4_lcd_init(struct ili9320 *lcd,
208#ifdef CONFIG_PM 208#ifdef CONFIG_PM
209static int vgg2432a4_suspend(struct spi_device *spi, pm_message_t state) 209static int vgg2432a4_suspend(struct spi_device *spi, pm_message_t state)
210{ 210{
211 return ili9320_suspend(dev_get_drvdata(&spi->dev), state); 211 return ili9320_suspend(spi_get_drvdata(spi), state);
212} 212}
213
214static int vgg2432a4_resume(struct spi_device *spi) 213static int vgg2432a4_resume(struct spi_device *spi)
215{ 214{
216 return ili9320_resume(dev_get_drvdata(&spi->dev)); 215 return ili9320_resume(spi_get_drvdata(spi));
217} 216}
218#else 217#else
219#define vgg2432a4_suspend NULL 218#define vgg2432a4_suspend NULL
@@ -242,12 +241,12 @@ static int vgg2432a4_probe(struct spi_device *spi)
242 241
243static int vgg2432a4_remove(struct spi_device *spi) 242static int vgg2432a4_remove(struct spi_device *spi)
244{ 243{
245 return ili9320_remove(dev_get_drvdata(&spi->dev)); 244 return ili9320_remove(spi_get_drvdata(spi));
246} 245}
247 246
248static void vgg2432a4_shutdown(struct spi_device *spi) 247static void vgg2432a4_shutdown(struct spi_device *spi)
249{ 248{
250 ili9320_shutdown(dev_get_drvdata(&spi->dev)); 249 ili9320_shutdown(spi_get_drvdata(spi));
251} 250}
252 251
253static struct spi_driver vgg2432a4_driver = { 252static struct spi_driver vgg2432a4_driver = {
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index fdefa8fd72c4..f8a61e210d2e 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -1242,8 +1242,16 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
1242 if (!height || !width) 1242 if (!height || !width)
1243 return; 1243 return;
1244 1244
1245 if (sy < vc->vc_top && vc->vc_top == logo_lines) 1245 if (sy < vc->vc_top && vc->vc_top == logo_lines) {
1246 vc->vc_top = 0; 1246 vc->vc_top = 0;
1247 /*
1248 * If the font dimensions are not an integral of the display
1249 * dimensions then the ops->clear below won't end up clearing
1250 * the margins. Call clear_margins here in case the logo
1251 * bitmap stretched into the margin area.
1252 */
1253 fbcon_clear_margins(vc, 0);
1254 }
1247 1255
1248 /* Split blits that cross physical y_wrap boundary */ 1256 /* Split blits that cross physical y_wrap boundary */
1249 1257
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index 2ed97769aa6d..de9d4da0e3da 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -965,10 +965,11 @@ static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
965 965
966static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) 966static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
967{ 967{
968 struct device_node *dp_phy_node; 968 struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
969 u32 phy_base; 969 u32 phy_base;
970 int ret = 0;
970 971
971 dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy"); 972 dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
972 if (!dp_phy_node) { 973 if (!dp_phy_node) {
973 dev_err(dp->dev, "could not find dptx-phy node\n"); 974 dev_err(dp->dev, "could not find dptx-phy node\n");
974 return -ENODEV; 975 return -ENODEV;
@@ -976,22 +977,28 @@ static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
976 977
977 if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) { 978 if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
978 dev_err(dp->dev, "faild to get reg for dptx-phy\n"); 979 dev_err(dp->dev, "faild to get reg for dptx-phy\n");
979 return -EINVAL; 980 ret = -EINVAL;
981 goto err;
980 } 982 }
981 983
982 if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", 984 if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
983 &dp->enable_mask)) { 985 &dp->enable_mask)) {
984 dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n"); 986 dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
985 return -EINVAL; 987 ret = -EINVAL;
988 goto err;
986 } 989 }
987 990
988 dp->phy_addr = ioremap(phy_base, SZ_4); 991 dp->phy_addr = ioremap(phy_base, SZ_4);
989 if (!dp->phy_addr) { 992 if (!dp->phy_addr) {
990 dev_err(dp->dev, "failed to ioremap dp-phy\n"); 993 dev_err(dp->dev, "failed to ioremap dp-phy\n");
991 return -ENOMEM; 994 ret = -ENOMEM;
995 goto err;
992 } 996 }
993 997
994 return 0; 998err:
999 of_node_put(dp_phy_node);
1000
1001 return ret;
995} 1002}
996 1003
997static void exynos_dp_phy_init(struct exynos_dp_device *dp) 1004static void exynos_dp_phy_init(struct exynos_dp_device *dp)
@@ -1117,8 +1124,6 @@ static int exynos_dp_remove(struct platform_device *pdev)
1117 struct exynos_dp_platdata *pdata = pdev->dev.platform_data; 1124 struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
1118 struct exynos_dp_device *dp = platform_get_drvdata(pdev); 1125 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
1119 1126
1120 disable_irq(dp->irq);
1121
1122 flush_work(&dp->hotplug_work); 1127 flush_work(&dp->hotplug_work);
1123 1128
1124 if (pdev->dev.of_node) { 1129 if (pdev->dev.of_node) {
@@ -1141,6 +1146,8 @@ static int exynos_dp_suspend(struct device *dev)
1141 struct exynos_dp_platdata *pdata = dev->platform_data; 1146 struct exynos_dp_platdata *pdata = dev->platform_data;
1142 struct exynos_dp_device *dp = dev_get_drvdata(dev); 1147 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1143 1148
1149 disable_irq(dp->irq);
1150
1144 flush_work(&dp->hotplug_work); 1151 flush_work(&dp->hotplug_work);
1145 1152
1146 if (dev->of_node) { 1153 if (dev->of_node) {
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 4a17cdccef34..fac7df6d1aba 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -338,7 +338,8 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
338 struct mipi_dsim_ddi *dsim_ddi; 338 struct mipi_dsim_ddi *dsim_ddi;
339 int ret = -EINVAL; 339 int ret = -EINVAL;
340 340
341 dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL); 341 dsim = devm_kzalloc(&pdev->dev, sizeof(struct mipi_dsim_device),
342 GFP_KERNEL);
342 if (!dsim) { 343 if (!dsim) {
343 dev_err(&pdev->dev, "failed to allocate dsim object.\n"); 344 dev_err(&pdev->dev, "failed to allocate dsim object.\n");
344 return -ENOMEM; 345 return -ENOMEM;
@@ -352,13 +353,13 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
352 dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd; 353 dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
353 if (dsim_pd == NULL) { 354 if (dsim_pd == NULL) {
354 dev_err(&pdev->dev, "failed to get platform data for dsim.\n"); 355 dev_err(&pdev->dev, "failed to get platform data for dsim.\n");
355 goto err_clock_get; 356 return -EINVAL;
356 } 357 }
357 /* get mipi_dsim_config. */ 358 /* get mipi_dsim_config. */
358 dsim_config = dsim_pd->dsim_config; 359 dsim_config = dsim_pd->dsim_config;
359 if (dsim_config == NULL) { 360 if (dsim_config == NULL) {
360 dev_err(&pdev->dev, "failed to get dsim config data.\n"); 361 dev_err(&pdev->dev, "failed to get dsim config data.\n");
361 goto err_clock_get; 362 return -EINVAL;
362 } 363 }
363 364
364 dsim->dsim_config = dsim_config; 365 dsim->dsim_config = dsim_config;
@@ -366,41 +367,28 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
366 367
367 mutex_init(&dsim->lock); 368 mutex_init(&dsim->lock);
368 369
369 ret = regulator_bulk_get(&pdev->dev, ARRAY_SIZE(supplies), supplies); 370 ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(supplies),
371 supplies);
370 if (ret) { 372 if (ret) {
371 dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret); 373 dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
372 goto err_clock_get; 374 return ret;
373 } 375 }
374 376
375 dsim->clock = clk_get(&pdev->dev, "dsim0"); 377 dsim->clock = devm_clk_get(&pdev->dev, "dsim0");
376 if (IS_ERR(dsim->clock)) { 378 if (IS_ERR(dsim->clock)) {
377 dev_err(&pdev->dev, "failed to get dsim clock source\n"); 379 dev_err(&pdev->dev, "failed to get dsim clock source\n");
378 ret = -ENODEV; 380 return -ENODEV;
379 goto err_clock_get;
380 } 381 }
381 382
382 clk_enable(dsim->clock); 383 clk_enable(dsim->clock);
383 384
384 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 385 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
385 if (!res) {
386 dev_err(&pdev->dev, "failed to get io memory region\n");
387 ret = -ENODEV;
388 goto err_platform_get;
389 }
390
391 dsim->res = request_mem_region(res->start, resource_size(res),
392 dev_name(&pdev->dev));
393 if (!dsim->res) {
394 dev_err(&pdev->dev, "failed to request io memory region\n");
395 ret = -ENOMEM;
396 goto err_mem_region;
397 }
398 386
399 dsim->reg_base = ioremap(res->start, resource_size(res)); 387 dsim->reg_base = devm_request_and_ioremap(&pdev->dev, res);
400 if (!dsim->reg_base) { 388 if (!dsim->reg_base) {
401 dev_err(&pdev->dev, "failed to remap io region\n"); 389 dev_err(&pdev->dev, "failed to remap io region\n");
402 ret = -ENOMEM; 390 ret = -ENOMEM;
403 goto err_ioremap; 391 goto error;
404 } 392 }
405 393
406 mutex_init(&dsim->lock); 394 mutex_init(&dsim->lock);
@@ -410,26 +398,27 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
410 if (!dsim_ddi) { 398 if (!dsim_ddi) {
411 dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n"); 399 dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
412 ret = -EINVAL; 400 ret = -EINVAL;
413 goto err_bind; 401 goto error;
414 } 402 }
415 403
416 dsim->irq = platform_get_irq(pdev, 0); 404 dsim->irq = platform_get_irq(pdev, 0);
417 if (dsim->irq < 0) { 405 if (IS_ERR_VALUE(dsim->irq)) {
418 dev_err(&pdev->dev, "failed to request dsim irq resource\n"); 406 dev_err(&pdev->dev, "failed to request dsim irq resource\n");
419 ret = -EINVAL; 407 ret = -EINVAL;
420 goto err_platform_get_irq; 408 goto error;
421 } 409 }
422 410
423 init_completion(&dsim_wr_comp); 411 init_completion(&dsim_wr_comp);
424 init_completion(&dsim_rd_comp); 412 init_completion(&dsim_rd_comp);
425 platform_set_drvdata(pdev, dsim); 413 platform_set_drvdata(pdev, dsim);
426 414
427 ret = request_irq(dsim->irq, exynos_mipi_dsi_interrupt_handler, 415 ret = devm_request_irq(&pdev->dev, dsim->irq,
416 exynos_mipi_dsi_interrupt_handler,
428 IRQF_SHARED, dev_name(&pdev->dev), dsim); 417 IRQF_SHARED, dev_name(&pdev->dev), dsim);
429 if (ret != 0) { 418 if (ret != 0) {
430 dev_err(&pdev->dev, "failed to request dsim irq\n"); 419 dev_err(&pdev->dev, "failed to request dsim irq\n");
431 ret = -EINVAL; 420 ret = -EINVAL;
432 goto err_bind; 421 goto error;
433 } 422 }
434 423
435 /* enable interrupts */ 424 /* enable interrupts */
@@ -471,22 +460,8 @@ done:
471 460
472 return 0; 461 return 0;
473 462
474err_bind: 463error:
475 iounmap(dsim->reg_base);
476
477err_ioremap:
478 release_mem_region(dsim->res->start, resource_size(dsim->res));
479
480err_mem_region:
481 release_resource(dsim->res);
482
483err_platform_get:
484 clk_disable(dsim->clock); 464 clk_disable(dsim->clock);
485 clk_put(dsim->clock);
486err_clock_get:
487 kfree(dsim);
488
489err_platform_get_irq:
490 return ret; 465 return ret;
491} 466}
492 467
@@ -496,13 +471,7 @@ static int exynos_mipi_dsi_remove(struct platform_device *pdev)
496 struct mipi_dsim_ddi *dsim_ddi, *next; 471 struct mipi_dsim_ddi *dsim_ddi, *next;
497 struct mipi_dsim_lcd_driver *dsim_lcd_drv; 472 struct mipi_dsim_lcd_driver *dsim_lcd_drv;
498 473
499 iounmap(dsim->reg_base);
500
501 clk_disable(dsim->clock); 474 clk_disable(dsim->clock);
502 clk_put(dsim->clock);
503
504 release_resource(dsim->res);
505 release_mem_region(dsim->res->start, resource_size(dsim->res));
506 475
507 list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) { 476 list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
508 if (dsim_ddi) { 477 if (dsim_ddi) {
@@ -518,9 +487,6 @@ static int exynos_mipi_dsi_remove(struct platform_device *pdev)
518 } 487 }
519 } 488 }
520 489
521 regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
522 kfree(dsim);
523
524 return 0; 490 return 0;
525} 491}
526 492
diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/exynos/s6e8ax0.c
index 05d080b63bc0..ca2602413aa4 100644
--- a/drivers/video/exynos/s6e8ax0.c
+++ b/drivers/video/exynos/s6e8ax0.c
@@ -776,7 +776,7 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
776 int ret; 776 int ret;
777 u8 mtp_id[3] = {0, }; 777 u8 mtp_id[3] = {0, };
778 778
779 lcd = kzalloc(sizeof(struct s6e8ax0), GFP_KERNEL); 779 lcd = devm_kzalloc(&dsim_dev->dev, sizeof(struct s6e8ax0), GFP_KERNEL);
780 if (!lcd) { 780 if (!lcd) {
781 dev_err(&dsim_dev->dev, "failed to allocate s6e8ax0 structure.\n"); 781 dev_err(&dsim_dev->dev, "failed to allocate s6e8ax0 structure.\n");
782 return -ENOMEM; 782 return -ENOMEM;
@@ -788,18 +788,17 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
788 788
789 mutex_init(&lcd->lock); 789 mutex_init(&lcd->lock);
790 790
791 ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies); 791 ret = devm_regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
792 if (ret) { 792 if (ret) {
793 dev_err(lcd->dev, "Failed to get regulators: %d\n", ret); 793 dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
794 goto err_lcd_register; 794 return ret;
795 } 795 }
796 796
797 lcd->ld = lcd_device_register("s6e8ax0", lcd->dev, lcd, 797 lcd->ld = lcd_device_register("s6e8ax0", lcd->dev, lcd,
798 &s6e8ax0_lcd_ops); 798 &s6e8ax0_lcd_ops);
799 if (IS_ERR(lcd->ld)) { 799 if (IS_ERR(lcd->ld)) {
800 dev_err(lcd->dev, "failed to register lcd ops.\n"); 800 dev_err(lcd->dev, "failed to register lcd ops.\n");
801 ret = PTR_ERR(lcd->ld); 801 return PTR_ERR(lcd->ld);
802 goto err_lcd_register;
803 } 802 }
804 803
805 lcd->bd = backlight_device_register("s6e8ax0-bl", lcd->dev, lcd, 804 lcd->bd = backlight_device_register("s6e8ax0-bl", lcd->dev, lcd,
@@ -838,11 +837,6 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
838 837
839err_backlight_register: 838err_backlight_register:
840 lcd_device_unregister(lcd->ld); 839 lcd_device_unregister(lcd->ld);
841
842err_lcd_register:
843 regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
844 kfree(lcd);
845
846 return ret; 840 return ret;
847} 841}
848 842
diff --git a/drivers/video/goldfishfb.c b/drivers/video/goldfishfb.c
new file mode 100644
index 000000000000..489abb32fc04
--- /dev/null
+++ b/drivers/video/goldfishfb.c
@@ -0,0 +1,318 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (C) 2012 Intel, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/dma-mapping.h>
19#include <linux/errno.h>
20#include <linux/string.h>
21#include <linux/slab.h>
22#include <linux/delay.h>
23#include <linux/mm.h>
24#include <linux/fb.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/ioport.h>
28#include <linux/platform_device.h>
29
30enum {
31 FB_GET_WIDTH = 0x00,
32 FB_GET_HEIGHT = 0x04,
33 FB_INT_STATUS = 0x08,
34 FB_INT_ENABLE = 0x0c,
35 FB_SET_BASE = 0x10,
36 FB_SET_ROTATION = 0x14,
37 FB_SET_BLANK = 0x18,
38 FB_GET_PHYS_WIDTH = 0x1c,
39 FB_GET_PHYS_HEIGHT = 0x20,
40
41 FB_INT_VSYNC = 1U << 0,
42 FB_INT_BASE_UPDATE_DONE = 1U << 1
43};
44
45struct goldfish_fb {
46 void __iomem *reg_base;
47 int irq;
48 spinlock_t lock;
49 wait_queue_head_t wait;
50 int base_update_count;
51 int rotation;
52 struct fb_info fb;
53 u32 cmap[16];
54};
55
56static irqreturn_t goldfish_fb_interrupt(int irq, void *dev_id)
57{
58 unsigned long irq_flags;
59 struct goldfish_fb *fb = dev_id;
60 u32 status;
61
62 spin_lock_irqsave(&fb->lock, irq_flags);
63 status = readl(fb->reg_base + FB_INT_STATUS);
64 if (status & FB_INT_BASE_UPDATE_DONE) {
65 fb->base_update_count++;
66 wake_up(&fb->wait);
67 }
68 spin_unlock_irqrestore(&fb->lock, irq_flags);
69 return status ? IRQ_HANDLED : IRQ_NONE;
70}
71
72static inline u32 convert_bitfield(int val, struct fb_bitfield *bf)
73{
74 unsigned int mask = (1 << bf->length) - 1;
75
76 return (val >> (16 - bf->length) & mask) << bf->offset;
77}
78
79static int
80goldfish_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
81 unsigned int blue, unsigned int transp, struct fb_info *info)
82{
83 struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
84
85 if (regno < 16) {
86 fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) |
87 convert_bitfield(blue, &fb->fb.var.blue) |
88 convert_bitfield(green, &fb->fb.var.green) |
89 convert_bitfield(red, &fb->fb.var.red);
90 return 0;
91 } else {
92 return 1;
93 }
94}
95
96static int goldfish_fb_check_var(struct fb_var_screeninfo *var,
97 struct fb_info *info)
98{
99 if ((var->rotate & 1) != (info->var.rotate & 1)) {
100 if ((var->xres != info->var.yres) ||
101 (var->yres != info->var.xres) ||
102 (var->xres_virtual != info->var.yres) ||
103 (var->yres_virtual > info->var.xres * 2) ||
104 (var->yres_virtual < info->var.xres)) {
105 return -EINVAL;
106 }
107 } else {
108 if ((var->xres != info->var.xres) ||
109 (var->yres != info->var.yres) ||
110 (var->xres_virtual != info->var.xres) ||
111 (var->yres_virtual > info->var.yres * 2) ||
112 (var->yres_virtual < info->var.yres)) {
113 return -EINVAL;
114 }
115 }
116 if ((var->xoffset != info->var.xoffset) ||
117 (var->bits_per_pixel != info->var.bits_per_pixel) ||
118 (var->grayscale != info->var.grayscale)) {
119 return -EINVAL;
120 }
121 return 0;
122}
123
124static int goldfish_fb_set_par(struct fb_info *info)
125{
126 struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
127 if (fb->rotation != fb->fb.var.rotate) {
128 info->fix.line_length = info->var.xres * 2;
129 fb->rotation = fb->fb.var.rotate;
130 writel(fb->rotation, fb->reg_base + FB_SET_ROTATION);
131 }
132 return 0;
133}
134
135
136static int goldfish_fb_pan_display(struct fb_var_screeninfo *var,
137 struct fb_info *info)
138{
139 unsigned long irq_flags;
140 int base_update_count;
141 struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
142
143 spin_lock_irqsave(&fb->lock, irq_flags);
144 base_update_count = fb->base_update_count;
145 writel(fb->fb.fix.smem_start + fb->fb.var.xres * 2 * var->yoffset,
146 fb->reg_base + FB_SET_BASE);
147 spin_unlock_irqrestore(&fb->lock, irq_flags);
148 wait_event_timeout(fb->wait,
149 fb->base_update_count != base_update_count, HZ / 15);
150 if (fb->base_update_count == base_update_count)
151 pr_err("goldfish_fb_pan_display: timeout wating for base update\n");
152 return 0;
153}
154
155static int goldfish_fb_blank(int blank, struct fb_info *info)
156{
157 struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
158 switch (blank) {
159 case FB_BLANK_NORMAL:
160 writel(1, fb->reg_base + FB_SET_BLANK);
161 break;
162 case FB_BLANK_UNBLANK:
163 writel(0, fb->reg_base + FB_SET_BLANK);
164 break;
165 }
166 return 0;
167}
168
169static struct fb_ops goldfish_fb_ops = {
170 .owner = THIS_MODULE,
171 .fb_check_var = goldfish_fb_check_var,
172 .fb_set_par = goldfish_fb_set_par,
173 .fb_setcolreg = goldfish_fb_setcolreg,
174 .fb_pan_display = goldfish_fb_pan_display,
175 .fb_blank = goldfish_fb_blank,
176 .fb_fillrect = cfb_fillrect,
177 .fb_copyarea = cfb_copyarea,
178 .fb_imageblit = cfb_imageblit,
179};
180
181
182static int goldfish_fb_probe(struct platform_device *pdev)
183{
184 int ret;
185 struct resource *r;
186 struct goldfish_fb *fb;
187 size_t framesize;
188 u32 width, height;
189 dma_addr_t fbpaddr;
190
191 fb = kzalloc(sizeof(*fb), GFP_KERNEL);
192 if (fb == NULL) {
193 ret = -ENOMEM;
194 goto err_fb_alloc_failed;
195 }
196 spin_lock_init(&fb->lock);
197 init_waitqueue_head(&fb->wait);
198 platform_set_drvdata(pdev, fb);
199
200 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
201 if (r == NULL) {
202 ret = -ENODEV;
203 goto err_no_io_base;
204 }
205 fb->reg_base = ioremap(r->start, PAGE_SIZE);
206 if (fb->reg_base == NULL) {
207 ret = -ENOMEM;
208 goto err_no_io_base;
209 }
210
211 fb->irq = platform_get_irq(pdev, 0);
212 if (fb->irq <= 0) {
213 ret = -ENODEV;
214 goto err_no_irq;
215 }
216
217 width = readl(fb->reg_base + FB_GET_WIDTH);
218 height = readl(fb->reg_base + FB_GET_HEIGHT);
219
220 fb->fb.fbops = &goldfish_fb_ops;
221 fb->fb.flags = FBINFO_FLAG_DEFAULT;
222 fb->fb.pseudo_palette = fb->cmap;
223 fb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
224 fb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
225 fb->fb.fix.line_length = width * 2;
226 fb->fb.fix.accel = FB_ACCEL_NONE;
227 fb->fb.fix.ypanstep = 1;
228
229 fb->fb.var.xres = width;
230 fb->fb.var.yres = height;
231 fb->fb.var.xres_virtual = width;
232 fb->fb.var.yres_virtual = height * 2;
233 fb->fb.var.bits_per_pixel = 16;
234 fb->fb.var.activate = FB_ACTIVATE_NOW;
235 fb->fb.var.height = readl(fb->reg_base + FB_GET_PHYS_HEIGHT);
236 fb->fb.var.width = readl(fb->reg_base + FB_GET_PHYS_WIDTH);
237 fb->fb.var.pixclock = 10000;
238
239 fb->fb.var.red.offset = 11;
240 fb->fb.var.red.length = 5;
241 fb->fb.var.green.offset = 5;
242 fb->fb.var.green.length = 6;
243 fb->fb.var.blue.offset = 0;
244 fb->fb.var.blue.length = 5;
245
246 framesize = width * height * 2 * 2;
247 fb->fb.screen_base = (char __force __iomem *)dma_alloc_coherent(
248 &pdev->dev, framesize,
249 &fbpaddr, GFP_KERNEL);
250 pr_debug("allocating frame buffer %d * %d, got %p\n",
251 width, height, fb->fb.screen_base);
252 if (fb->fb.screen_base == NULL) {
253 ret = -ENOMEM;
254 goto err_alloc_screen_base_failed;
255 }
256 fb->fb.fix.smem_start = fbpaddr;
257 fb->fb.fix.smem_len = framesize;
258
259 ret = fb_set_var(&fb->fb, &fb->fb.var);
260 if (ret)
261 goto err_fb_set_var_failed;
262
263 ret = request_irq(fb->irq, goldfish_fb_interrupt, IRQF_SHARED,
264 pdev->name, fb);
265 if (ret)
266 goto err_request_irq_failed;
267
268 writel(FB_INT_BASE_UPDATE_DONE, fb->reg_base + FB_INT_ENABLE);
269 goldfish_fb_pan_display(&fb->fb.var, &fb->fb); /* updates base */
270
271 ret = register_framebuffer(&fb->fb);
272 if (ret)
273 goto err_register_framebuffer_failed;
274 return 0;
275
276err_register_framebuffer_failed:
277 free_irq(fb->irq, fb);
278err_request_irq_failed:
279err_fb_set_var_failed:
280 dma_free_coherent(&pdev->dev, framesize,
281 (void *)fb->fb.screen_base,
282 fb->fb.fix.smem_start);
283err_alloc_screen_base_failed:
284err_no_irq:
285 iounmap(fb->reg_base);
286err_no_io_base:
287 kfree(fb);
288err_fb_alloc_failed:
289 return ret;
290}
291
292static int goldfish_fb_remove(struct platform_device *pdev)
293{
294 size_t framesize;
295 struct goldfish_fb *fb = platform_get_drvdata(pdev);
296
297 framesize = fb->fb.var.xres_virtual * fb->fb.var.yres_virtual * 2;
298 unregister_framebuffer(&fb->fb);
299 free_irq(fb->irq, fb);
300
301 dma_free_coherent(&pdev->dev, framesize, (void *)fb->fb.screen_base,
302 fb->fb.fix.smem_start);
303 iounmap(fb->reg_base);
304 return 0;
305}
306
307
308static struct platform_driver goldfish_fb_driver = {
309 .probe = goldfish_fb_probe,
310 .remove = goldfish_fb_remove,
311 .driver = {
312 .name = "goldfish_fb"
313 }
314};
315
316module_platform_driver(goldfish_fb_driver);
317
318MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/mmp/Kconfig b/drivers/video/mmp/Kconfig
new file mode 100644
index 000000000000..e9ea39e13722
--- /dev/null
+++ b/drivers/video/mmp/Kconfig
@@ -0,0 +1,11 @@
1menuconfig MMP_DISP
2 tristate "Marvell MMP Display Subsystem support"
3 depends on CPU_PXA910 || CPU_MMP2 || CPU_MMP3 || CPU_PXA988
4 help
5 Marvell Display Subsystem support.
6
7if MMP_DISP
8source "drivers/video/mmp/hw/Kconfig"
9source "drivers/video/mmp/panel/Kconfig"
10source "drivers/video/mmp/fb/Kconfig"
11endif
diff --git a/drivers/video/mmp/Makefile b/drivers/video/mmp/Makefile
new file mode 100644
index 000000000000..a014cb358bf8
--- /dev/null
+++ b/drivers/video/mmp/Makefile
@@ -0,0 +1 @@
obj-y += core.o hw/ panel/ fb/
diff --git a/drivers/video/mmp/core.c b/drivers/video/mmp/core.c
new file mode 100644
index 000000000000..9ed83419038b
--- /dev/null
+++ b/drivers/video/mmp/core.c
@@ -0,0 +1,258 @@
1/*
2 * linux/drivers/video/mmp/common.c
3 * This driver is a common framework for Marvell Display Controller
4 *
5 * Copyright (C) 2012 Marvell Technology Group Ltd.
6 * Authors: Zhou Zhu <zzhu3@marvell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include <linux/slab.h>
24#include <linux/dma-mapping.h>
25#include <linux/export.h>
26#include <video/mmp_disp.h>
27
28static struct mmp_overlay *path_get_overlay(struct mmp_path *path,
29 int overlay_id)
30{
31 if (path && overlay_id < path->overlay_num)
32 return &path->overlays[overlay_id];
33 return 0;
34}
35
36static int path_check_status(struct mmp_path *path)
37{
38 int i;
39 for (i = 0; i < path->overlay_num; i++)
40 if (path->overlays[i].status)
41 return 1;
42
43 return 0;
44}
45
46/*
47 * Get modelist write pointer of modelist.
48 * It also returns modelist number
49 * this function fetches modelist from phy/panel:
50 * for HDMI/parallel or dsi to hdmi cases, get from phy
51 * or get from panel
52 */
53static int path_get_modelist(struct mmp_path *path,
54 struct mmp_mode **modelist)
55{
56 BUG_ON(!path || !modelist);
57
58 if (path->panel && path->panel->get_modelist)
59 return path->panel->get_modelist(path->panel, modelist);
60
61 return 0;
62}
63
64/*
65 * panel list is used to pair panel/path when path/panel registered
66 * path list is used for both buffer driver and platdriver
67 * plat driver do path register/unregister
68 * panel driver do panel register/unregister
69 * buffer driver get registered path
70 */
71static LIST_HEAD(panel_list);
72static LIST_HEAD(path_list);
73static DEFINE_MUTEX(disp_lock);
74
75/*
76 * mmp_register_panel - register panel to panel_list and connect to path
77 * @p: panel to be registered
78 *
79 * this function provides interface for panel drivers to register panel
80 * to panel_list and connect to path which matchs panel->plat_path_name.
81 * no error returns when no matching path is found as path register after
82 * panel register is permitted.
83 */
84void mmp_register_panel(struct mmp_panel *panel)
85{
86 struct mmp_path *path;
87
88 mutex_lock(&disp_lock);
89
90 /* add */
91 list_add_tail(&panel->node, &panel_list);
92
93 /* try to register to path */
94 list_for_each_entry(path, &path_list, node) {
95 if (!strcmp(panel->plat_path_name, path->name)) {
96 dev_info(panel->dev, "connect to path %s\n",
97 path->name);
98 path->panel = panel;
99 break;
100 }
101 }
102
103 mutex_unlock(&disp_lock);
104}
105EXPORT_SYMBOL_GPL(mmp_register_panel);
106
107/*
108 * mmp_unregister_panel - unregister panel from panel_list and disconnect
109 * @p: panel to be unregistered
110 *
111 * this function provides interface for panel drivers to unregister panel
112 * from panel_list and disconnect from path.
113 */
114void mmp_unregister_panel(struct mmp_panel *panel)
115{
116 struct mmp_path *path;
117
118 mutex_lock(&disp_lock);
119 list_del(&panel->node);
120
121 list_for_each_entry(path, &path_list, node) {
122 if (path->panel && path->panel == panel) {
123 dev_info(panel->dev, "disconnect from path %s\n",
124 path->name);
125 path->panel = NULL;
126 break;
127 }
128 }
129 mutex_unlock(&disp_lock);
130}
131EXPORT_SYMBOL_GPL(mmp_unregister_panel);
132
133/*
134 * mmp_get_path - get path by name
135 * @p: path name
136 *
137 * this function checks path name in path_list and return matching path
138 * return NULL if no matching path
139 */
140struct mmp_path *mmp_get_path(const char *name)
141{
142 struct mmp_path *path;
143 int found = 0;
144
145 mutex_lock(&disp_lock);
146 list_for_each_entry(path, &path_list, node) {
147 if (!strcmp(name, path->name)) {
148 found = 1;
149 break;
150 }
151 }
152 mutex_unlock(&disp_lock);
153
154 return found ? path : NULL;
155}
156EXPORT_SYMBOL_GPL(mmp_get_path);
157
158/*
159 * mmp_register_path - init and register path by path_info
160 * @p: path info provided by display controller
161 *
162 * this function init by path info and register path to path_list
163 * this function also try to connect path with panel by name
164 */
165struct mmp_path *mmp_register_path(struct mmp_path_info *info)
166{
167 int i;
168 size_t size;
169 struct mmp_path *path = NULL;
170 struct mmp_panel *panel;
171
172 size = sizeof(struct mmp_path)
173 + sizeof(struct mmp_overlay) * info->overlay_num;
174 path = kzalloc(size, GFP_KERNEL);
175 if (!path)
176 goto failed;
177
178 /* path set */
179 mutex_init(&path->access_ok);
180 path->dev = info->dev;
181 path->id = info->id;
182 path->name = info->name;
183 path->output_type = info->output_type;
184 path->overlay_num = info->overlay_num;
185 path->plat_data = info->plat_data;
186 path->ops.set_mode = info->set_mode;
187
188 mutex_lock(&disp_lock);
189 /* get panel */
190 list_for_each_entry(panel, &panel_list, node) {
191 if (!strcmp(info->name, panel->plat_path_name)) {
192 dev_info(path->dev, "get panel %s\n", panel->name);
193 path->panel = panel;
194 break;
195 }
196 }
197
198 dev_info(path->dev, "register %s, overlay_num %d\n",
199 path->name, path->overlay_num);
200
201 /* default op set: if already set by driver, never cover it */
202 if (!path->ops.check_status)
203 path->ops.check_status = path_check_status;
204 if (!path->ops.get_overlay)
205 path->ops.get_overlay = path_get_overlay;
206 if (!path->ops.get_modelist)
207 path->ops.get_modelist = path_get_modelist;
208
209 /* step3: init overlays */
210 for (i = 0; i < path->overlay_num; i++) {
211 path->overlays[i].path = path;
212 path->overlays[i].id = i;
213 mutex_init(&path->overlays[i].access_ok);
214 path->overlays[i].ops = info->overlay_ops;
215 }
216
217 /* add to pathlist */
218 list_add_tail(&path->node, &path_list);
219
220 mutex_unlock(&disp_lock);
221 return path;
222
223failed:
224 kfree(path);
225 mutex_unlock(&disp_lock);
226 return NULL;
227}
228EXPORT_SYMBOL_GPL(mmp_register_path);
229
230/*
231 * mmp_unregister_path - unregister and destory path
232 * @p: path to be destoried.
233 *
234 * this function registers path and destorys it.
235 */
236void mmp_unregister_path(struct mmp_path *path)
237{
238 int i;
239
240 if (!path)
241 return;
242
243 mutex_lock(&disp_lock);
244 /* del from pathlist */
245 list_del(&path->node);
246
247 /* deinit overlays */
248 for (i = 0; i < path->overlay_num; i++)
249 mutex_destroy(&path->overlays[i].access_ok);
250
251 mutex_destroy(&path->access_ok);
252
253 kfree(path);
254 mutex_unlock(&disp_lock);
255
256 dev_info(path->dev, "de-register %s\n", path->name);
257}
258EXPORT_SYMBOL_GPL(mmp_unregister_path);
diff --git a/drivers/video/mmp/fb/Kconfig b/drivers/video/mmp/fb/Kconfig
new file mode 100644
index 000000000000..9b0141f105f5
--- /dev/null
+++ b/drivers/video/mmp/fb/Kconfig
@@ -0,0 +1,13 @@
1if MMP_DISP
2
3config MMP_FB
4 bool "fb driver for Marvell MMP Display Subsystem"
5 depends on FB
6 select FB_CFB_FILLRECT
7 select FB_CFB_COPYAREA
8 select FB_CFB_IMAGEBLIT
9 default y
10 help
11 fb driver for Marvell MMP Display Subsystem
12
13endif
diff --git a/drivers/video/mmp/fb/Makefile b/drivers/video/mmp/fb/Makefile
new file mode 100644
index 000000000000..709fd1f76abe
--- /dev/null
+++ b/drivers/video/mmp/fb/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_MMP_FB) += mmpfb.o
diff --git a/drivers/video/mmp/fb/mmpfb.c b/drivers/video/mmp/fb/mmpfb.c
new file mode 100644
index 000000000000..6d1fa96c5cc3
--- /dev/null
+++ b/drivers/video/mmp/fb/mmpfb.c
@@ -0,0 +1,685 @@
1/*
2 * linux/drivers/video/mmp/fb/mmpfb.c
3 * Framebuffer driver for Marvell Display controller.
4 *
5 * Copyright (C) 2012 Marvell Technology Group Ltd.
6 * Authors: Zhou Zhu <zzhu3@marvell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22#include <linux/module.h>
23#include <linux/dma-mapping.h>
24#include <linux/platform_device.h>
25#include "mmpfb.h"
26
27static int var_to_pixfmt(struct fb_var_screeninfo *var)
28{
29 /*
30 * Pseudocolor mode?
31 */
32 if (var->bits_per_pixel == 8)
33 return PIXFMT_PSEUDOCOLOR;
34
35 /*
36 * Check for YUV422PLANAR.
37 */
38 if (var->bits_per_pixel == 16 && var->red.length == 8 &&
39 var->green.length == 4 && var->blue.length == 4) {
40 if (var->green.offset >= var->blue.offset)
41 return PIXFMT_YUV422P;
42 else
43 return PIXFMT_YVU422P;
44 }
45
46 /*
47 * Check for YUV420PLANAR.
48 */
49 if (var->bits_per_pixel == 12 && var->red.length == 8 &&
50 var->green.length == 2 && var->blue.length == 2) {
51 if (var->green.offset >= var->blue.offset)
52 return PIXFMT_YUV420P;
53 else
54 return PIXFMT_YVU420P;
55 }
56
57 /*
58 * Check for YUV422PACK.
59 */
60 if (var->bits_per_pixel == 16 && var->red.length == 16 &&
61 var->green.length == 16 && var->blue.length == 16) {
62 if (var->red.offset == 0)
63 return PIXFMT_YUYV;
64 else if (var->green.offset >= var->blue.offset)
65 return PIXFMT_UYVY;
66 else
67 return PIXFMT_VYUY;
68 }
69
70 /*
71 * Check for 565/1555.
72 */
73 if (var->bits_per_pixel == 16 && var->red.length <= 5 &&
74 var->green.length <= 6 && var->blue.length <= 5) {
75 if (var->transp.length == 0) {
76 if (var->red.offset >= var->blue.offset)
77 return PIXFMT_RGB565;
78 else
79 return PIXFMT_BGR565;
80 }
81 }
82
83 /*
84 * Check for 888/A888.
85 */
86 if (var->bits_per_pixel <= 32 && var->red.length <= 8 &&
87 var->green.length <= 8 && var->blue.length <= 8) {
88 if (var->bits_per_pixel == 24 && var->transp.length == 0) {
89 if (var->red.offset >= var->blue.offset)
90 return PIXFMT_RGB888PACK;
91 else
92 return PIXFMT_BGR888PACK;
93 }
94
95 if (var->bits_per_pixel == 32 && var->transp.offset == 24) {
96 if (var->red.offset >= var->blue.offset)
97 return PIXFMT_RGBA888;
98 else
99 return PIXFMT_BGRA888;
100 } else {
101 if (var->red.offset >= var->blue.offset)
102 return PIXFMT_RGB888UNPACK;
103 else
104 return PIXFMT_BGR888UNPACK;
105 }
106
107 /* fall through */
108 }
109
110 return -EINVAL;
111}
112
113static void pixfmt_to_var(struct fb_var_screeninfo *var, int pix_fmt)
114{
115 switch (pix_fmt) {
116 case PIXFMT_RGB565:
117 var->bits_per_pixel = 16;
118 var->red.offset = 11; var->red.length = 5;
119 var->green.offset = 5; var->green.length = 6;
120 var->blue.offset = 0; var->blue.length = 5;
121 var->transp.offset = 0; var->transp.length = 0;
122 break;
123 case PIXFMT_BGR565:
124 var->bits_per_pixel = 16;
125 var->red.offset = 0; var->red.length = 5;
126 var->green.offset = 5; var->green.length = 6;
127 var->blue.offset = 11; var->blue.length = 5;
128 var->transp.offset = 0; var->transp.length = 0;
129 break;
130 case PIXFMT_RGB888UNPACK:
131 var->bits_per_pixel = 32;
132 var->red.offset = 16; var->red.length = 8;
133 var->green.offset = 8; var->green.length = 8;
134 var->blue.offset = 0; var->blue.length = 8;
135 var->transp.offset = 0; var->transp.length = 0;
136 break;
137 case PIXFMT_BGR888UNPACK:
138 var->bits_per_pixel = 32;
139 var->red.offset = 0; var->red.length = 8;
140 var->green.offset = 8; var->green.length = 8;
141 var->blue.offset = 16; var->blue.length = 8;
142 var->transp.offset = 0; var->transp.length = 0;
143 break;
144 case PIXFMT_RGBA888:
145 var->bits_per_pixel = 32;
146 var->red.offset = 16; var->red.length = 8;
147 var->green.offset = 8; var->green.length = 8;
148 var->blue.offset = 0; var->blue.length = 8;
149 var->transp.offset = 24; var->transp.length = 8;
150 break;
151 case PIXFMT_BGRA888:
152 var->bits_per_pixel = 32;
153 var->red.offset = 0; var->red.length = 8;
154 var->green.offset = 8; var->green.length = 8;
155 var->blue.offset = 16; var->blue.length = 8;
156 var->transp.offset = 24; var->transp.length = 8;
157 break;
158 case PIXFMT_RGB888PACK:
159 var->bits_per_pixel = 24;
160 var->red.offset = 16; var->red.length = 8;
161 var->green.offset = 8; var->green.length = 8;
162 var->blue.offset = 0; var->blue.length = 8;
163 var->transp.offset = 0; var->transp.length = 0;
164 break;
165 case PIXFMT_BGR888PACK:
166 var->bits_per_pixel = 24;
167 var->red.offset = 0; var->red.length = 8;
168 var->green.offset = 8; var->green.length = 8;
169 var->blue.offset = 16; var->blue.length = 8;
170 var->transp.offset = 0; var->transp.length = 0;
171 break;
172 case PIXFMT_YUV420P:
173 var->bits_per_pixel = 12;
174 var->red.offset = 4; var->red.length = 8;
175 var->green.offset = 2; var->green.length = 2;
176 var->blue.offset = 0; var->blue.length = 2;
177 var->transp.offset = 0; var->transp.length = 0;
178 break;
179 case PIXFMT_YVU420P:
180 var->bits_per_pixel = 12;
181 var->red.offset = 4; var->red.length = 8;
182 var->green.offset = 0; var->green.length = 2;
183 var->blue.offset = 2; var->blue.length = 2;
184 var->transp.offset = 0; var->transp.length = 0;
185 break;
186 case PIXFMT_YUV422P:
187 var->bits_per_pixel = 16;
188 var->red.offset = 8; var->red.length = 8;
189 var->green.offset = 4; var->green.length = 4;
190 var->blue.offset = 0; var->blue.length = 4;
191 var->transp.offset = 0; var->transp.length = 0;
192 break;
193 case PIXFMT_YVU422P:
194 var->bits_per_pixel = 16;
195 var->red.offset = 8; var->red.length = 8;
196 var->green.offset = 0; var->green.length = 4;
197 var->blue.offset = 4; var->blue.length = 4;
198 var->transp.offset = 0; var->transp.length = 0;
199 break;
200 case PIXFMT_UYVY:
201 var->bits_per_pixel = 16;
202 var->red.offset = 8; var->red.length = 16;
203 var->green.offset = 4; var->green.length = 16;
204 var->blue.offset = 0; var->blue.length = 16;
205 var->transp.offset = 0; var->transp.length = 0;
206 break;
207 case PIXFMT_VYUY:
208 var->bits_per_pixel = 16;
209 var->red.offset = 8; var->red.length = 16;
210 var->green.offset = 0; var->green.length = 16;
211 var->blue.offset = 4; var->blue.length = 16;
212 var->transp.offset = 0; var->transp.length = 0;
213 break;
214 case PIXFMT_YUYV:
215 var->bits_per_pixel = 16;
216 var->red.offset = 0; var->red.length = 16;
217 var->green.offset = 4; var->green.length = 16;
218 var->blue.offset = 8; var->blue.length = 16;
219 var->transp.offset = 0; var->transp.length = 0;
220 break;
221 case PIXFMT_PSEUDOCOLOR:
222 var->bits_per_pixel = 8;
223 var->red.offset = 0; var->red.length = 8;
224 var->green.offset = 0; var->green.length = 8;
225 var->blue.offset = 0; var->blue.length = 8;
226 var->transp.offset = 0; var->transp.length = 0;
227 break;
228 }
229}
230
231/*
232 * fb framework has its limitation:
233 * 1. input color/output color is not seprated
234 * 2. fb_videomode not include output color
235 * so for fb usage, we keep a output format which is not changed
236 * then it's added for mmpmode
237 */
238static void fbmode_to_mmpmode(struct mmp_mode *mode,
239 struct fb_videomode *videomode, int output_fmt)
240{
241 u64 div_result = 1000000000000ll;
242 mode->name = videomode->name;
243 mode->refresh = videomode->refresh;
244 mode->xres = videomode->xres;
245 mode->yres = videomode->yres;
246
247 do_div(div_result, videomode->pixclock);
248 mode->pixclock_freq = (u32)div_result;
249
250 mode->left_margin = videomode->left_margin;
251 mode->right_margin = videomode->right_margin;
252 mode->upper_margin = videomode->upper_margin;
253 mode->lower_margin = videomode->lower_margin;
254 mode->hsync_len = videomode->hsync_len;
255 mode->vsync_len = videomode->vsync_len;
256 mode->hsync_invert = !!(videomode->sync & FB_SYNC_HOR_HIGH_ACT);
257 mode->vsync_invert = !!(videomode->sync & FB_SYNC_VERT_HIGH_ACT);
258 /* no defined flag in fb, use vmode>>3*/
259 mode->invert_pixclock = !!(videomode->vmode & 8);
260 mode->pix_fmt_out = output_fmt;
261}
262
263static void mmpmode_to_fbmode(struct fb_videomode *videomode,
264 struct mmp_mode *mode)
265{
266 u64 div_result = 1000000000000ll;
267
268 videomode->name = mode->name;
269 videomode->refresh = mode->refresh;
270 videomode->xres = mode->xres;
271 videomode->yres = mode->yres;
272
273 do_div(div_result, mode->pixclock_freq);
274 videomode->pixclock = (u32)div_result;
275
276 videomode->left_margin = mode->left_margin;
277 videomode->right_margin = mode->right_margin;
278 videomode->upper_margin = mode->upper_margin;
279 videomode->lower_margin = mode->lower_margin;
280 videomode->hsync_len = mode->hsync_len;
281 videomode->vsync_len = mode->vsync_len;
282 videomode->sync = (mode->hsync_invert ? FB_SYNC_HOR_HIGH_ACT : 0)
283 | (mode->vsync_invert ? FB_SYNC_VERT_HIGH_ACT : 0);
284 videomode->vmode = mode->invert_pixclock ? 8 : 0;
285}
286
287static int mmpfb_check_var(struct fb_var_screeninfo *var,
288 struct fb_info *info)
289{
290 struct mmpfb_info *fbi = info->par;
291
292 if (var->bits_per_pixel == 8)
293 return -EINVAL;
294 /*
295 * Basic geometry sanity checks.
296 */
297 if (var->xoffset + var->xres > var->xres_virtual)
298 return -EINVAL;
299 if (var->yoffset + var->yres > var->yres_virtual)
300 return -EINVAL;
301
302 /*
303 * Check size of framebuffer.
304 */
305 if (var->xres_virtual * var->yres_virtual *
306 (var->bits_per_pixel >> 3) > fbi->fb_size)
307 return -EINVAL;
308
309 return 0;
310}
311
312static unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
313{
314 return ((chan & 0xffff) >> (16 - bf->length)) << bf->offset;
315}
316
317static u32 to_rgb(u16 red, u16 green, u16 blue)
318{
319 red >>= 8;
320 green >>= 8;
321 blue >>= 8;
322
323 return (red << 16) | (green << 8) | blue;
324}
325
326static int mmpfb_setcolreg(unsigned int regno, unsigned int red,
327 unsigned int green, unsigned int blue,
328 unsigned int trans, struct fb_info *info)
329{
330 struct mmpfb_info *fbi = info->par;
331 u32 val;
332
333 if (info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 16) {
334 val = chan_to_field(red, &info->var.red);
335 val |= chan_to_field(green, &info->var.green);
336 val |= chan_to_field(blue , &info->var.blue);
337 fbi->pseudo_palette[regno] = val;
338 }
339
340 if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) {
341 val = to_rgb(red, green, blue);
342 /* TODO */
343 }
344
345 return 0;
346}
347
348static int mmpfb_pan_display(struct fb_var_screeninfo *var,
349 struct fb_info *info)
350{
351 struct mmpfb_info *fbi = info->par;
352 struct mmp_addr addr;
353
354 memset(&addr, 0, sizeof(addr));
355 addr.phys[0] = (var->yoffset * var->xres_virtual + var->xoffset)
356 * var->bits_per_pixel / 8 + fbi->fb_start_dma;
357 mmp_overlay_set_addr(fbi->overlay, &addr);
358
359 return 0;
360}
361
362static int var_update(struct fb_info *info)
363{
364 struct mmpfb_info *fbi = info->par;
365 struct fb_var_screeninfo *var = &info->var;
366 struct fb_videomode *m;
367 int pix_fmt;
368
369 /* set pix_fmt */
370 pix_fmt = var_to_pixfmt(var);
371 if (pix_fmt < 0)
372 return -EINVAL;
373 pixfmt_to_var(var, pix_fmt);
374 fbi->pix_fmt = pix_fmt;
375
376 /* set var according to best video mode*/
377 m = (struct fb_videomode *)fb_match_mode(var, &info->modelist);
378 if (!m) {
379 dev_err(fbi->dev, "set par: no match mode, use best mode\n");
380 m = (struct fb_videomode *)fb_find_best_mode(var,
381 &info->modelist);
382 fb_videomode_to_var(var, m);
383 }
384 memcpy(&fbi->mode, m, sizeof(struct fb_videomode));
385
386 /* fix to 2* yres */
387 var->yres_virtual = var->yres * 2;
388 info->fix.visual = (pix_fmt == PIXFMT_PSEUDOCOLOR) ?
389 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
390 info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
391 info->fix.ypanstep = var->yres;
392 return 0;
393}
394
395static int mmpfb_set_par(struct fb_info *info)
396{
397 struct mmpfb_info *fbi = info->par;
398 struct fb_var_screeninfo *var = &info->var;
399 struct mmp_addr addr;
400 struct mmp_win win;
401 struct mmp_mode mode;
402 int ret;
403
404 ret = var_update(info);
405 if (ret != 0)
406 return ret;
407
408 /* set window/path according to new videomode */
409 fbmode_to_mmpmode(&mode, &fbi->mode, fbi->output_fmt);
410 mmp_path_set_mode(fbi->path, &mode);
411
412 memset(&win, 0, sizeof(win));
413 win.xsrc = win.xdst = fbi->mode.xres;
414 win.ysrc = win.ydst = fbi->mode.yres;
415 win.pix_fmt = fbi->pix_fmt;
416 mmp_overlay_set_win(fbi->overlay, &win);
417
418 /* set address always */
419 memset(&addr, 0, sizeof(addr));
420 addr.phys[0] = (var->yoffset * var->xres_virtual + var->xoffset)
421 * var->bits_per_pixel / 8 + fbi->fb_start_dma;
422 mmp_overlay_set_addr(fbi->overlay, &addr);
423
424 return 0;
425}
426
427static void mmpfb_power(struct mmpfb_info *fbi, int power)
428{
429 struct mmp_addr addr;
430 struct mmp_win win;
431 struct fb_var_screeninfo *var = &fbi->fb_info->var;
432
433 /* for power on, always set address/window again */
434 if (power) {
435 memset(&win, 0, sizeof(win));
436 win.xsrc = win.xdst = fbi->mode.xres;
437 win.ysrc = win.ydst = fbi->mode.yres;
438 win.pix_fmt = fbi->pix_fmt;
439 mmp_overlay_set_win(fbi->overlay, &win);
440
441 /* set address always */
442 memset(&addr, 0, sizeof(addr));
443 addr.phys[0] = fbi->fb_start_dma +
444 (var->yoffset * var->xres_virtual + var->xoffset)
445 * var->bits_per_pixel / 8;
446 mmp_overlay_set_addr(fbi->overlay, &addr);
447 }
448 mmp_overlay_set_onoff(fbi->overlay, power);
449}
450
451static int mmpfb_blank(int blank, struct fb_info *info)
452{
453 struct mmpfb_info *fbi = info->par;
454
455 mmpfb_power(fbi, (blank == FB_BLANK_UNBLANK));
456
457 return 0;
458}
459
460static struct fb_ops mmpfb_ops = {
461 .owner = THIS_MODULE,
462 .fb_blank = mmpfb_blank,
463 .fb_check_var = mmpfb_check_var,
464 .fb_set_par = mmpfb_set_par,
465 .fb_setcolreg = mmpfb_setcolreg,
466 .fb_pan_display = mmpfb_pan_display,
467 .fb_fillrect = cfb_fillrect,
468 .fb_copyarea = cfb_copyarea,
469 .fb_imageblit = cfb_imageblit,
470};
471
472static int modes_setup(struct mmpfb_info *fbi)
473{
474 struct fb_videomode *videomodes;
475 struct mmp_mode *mmp_modes;
476 struct fb_info *info = fbi->fb_info;
477 int videomode_num, i;
478
479 /* get videomodes from path */
480 videomode_num = mmp_path_get_modelist(fbi->path, &mmp_modes);
481 if (!videomode_num) {
482 dev_warn(fbi->dev, "can't get videomode num\n");
483 return 0;
484 }
485 /* put videomode list to info structure */
486 videomodes = kzalloc(sizeof(struct fb_videomode) * videomode_num,
487 GFP_KERNEL);
488 if (!videomodes) {
489 dev_err(fbi->dev, "can't malloc video modes\n");
490 return -ENOMEM;
491 }
492 for (i = 0; i < videomode_num; i++)
493 mmpmode_to_fbmode(&videomodes[i], &mmp_modes[i]);
494 fb_videomode_to_modelist(videomodes, videomode_num, &info->modelist);
495
496 /* set videomode[0] as default mode */
497 memcpy(&fbi->mode, &videomodes[0], sizeof(struct fb_videomode));
498 fbi->output_fmt = mmp_modes[0].pix_fmt_out;
499 fb_videomode_to_var(&info->var, &fbi->mode);
500 mmp_path_set_mode(fbi->path, &mmp_modes[0]);
501
502 kfree(videomodes);
503 return videomode_num;
504}
505
506static int fb_info_setup(struct fb_info *info,
507 struct mmpfb_info *fbi)
508{
509 int ret = 0;
510 /* Initialise static fb parameters.*/
511 info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK |
512 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
513 info->node = -1;
514 strcpy(info->fix.id, fbi->name);
515 info->fix.type = FB_TYPE_PACKED_PIXELS;
516 info->fix.type_aux = 0;
517 info->fix.xpanstep = 0;
518 info->fix.ypanstep = info->var.yres;
519 info->fix.ywrapstep = 0;
520 info->fix.accel = FB_ACCEL_NONE;
521 info->fix.smem_start = fbi->fb_start_dma;
522 info->fix.smem_len = fbi->fb_size;
523 info->fix.visual = (fbi->pix_fmt == PIXFMT_PSEUDOCOLOR) ?
524 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
525 info->fix.line_length = info->var.xres_virtual *
526 info->var.bits_per_pixel / 8;
527 info->fbops = &mmpfb_ops;
528 info->pseudo_palette = fbi->pseudo_palette;
529 info->screen_base = fbi->fb_start;
530 info->screen_size = fbi->fb_size;
531
532 /* For FB framework: Allocate color map and Register framebuffer*/
533 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
534 ret = -ENOMEM;
535
536 return ret;
537}
538
539static void fb_info_clear(struct fb_info *info)
540{
541 fb_dealloc_cmap(&info->cmap);
542}
543
544static int mmpfb_probe(struct platform_device *pdev)
545{
546 struct mmp_buffer_driver_mach_info *mi;
547 struct fb_info *info = 0;
548 struct mmpfb_info *fbi = 0;
549 int ret, modes_num;
550
551 mi = pdev->dev.platform_data;
552 if (mi == NULL) {
553 dev_err(&pdev->dev, "no platform data defined\n");
554 return -EINVAL;
555 }
556
557 /* initialize fb */
558 info = framebuffer_alloc(sizeof(struct mmpfb_info), &pdev->dev);
559 if (info == NULL)
560 return -ENOMEM;
561 fbi = info->par;
562 if (!fbi) {
563 ret = -EINVAL;
564 goto failed;
565 }
566
567 /* init fb */
568 fbi->fb_info = info;
569 platform_set_drvdata(pdev, fbi);
570 fbi->dev = &pdev->dev;
571 fbi->name = mi->name;
572 fbi->pix_fmt = mi->default_pixfmt;
573 pixfmt_to_var(&info->var, fbi->pix_fmt);
574 mutex_init(&fbi->access_ok);
575
576 /* get display path by name */
577 fbi->path = mmp_get_path(mi->path_name);
578 if (!fbi->path) {
579 dev_err(&pdev->dev, "can't get the path %s\n", mi->path_name);
580 ret = -EINVAL;
581 goto failed_destroy_mutex;
582 }
583
584 dev_info(fbi->dev, "path %s get\n", fbi->path->name);
585
586 /* get overlay */
587 fbi->overlay = mmp_path_get_overlay(fbi->path, mi->overlay_id);
588 if (!fbi->overlay) {
589 ret = -EINVAL;
590 goto failed_destroy_mutex;
591 }
592 /* set fetch used */
593 mmp_overlay_set_fetch(fbi->overlay, mi->dmafetch_id);
594
595 modes_num = modes_setup(fbi);
596 if (modes_num < 0) {
597 ret = modes_num;
598 goto failed_destroy_mutex;
599 }
600
601 /*
602 * if get modes success, means not hotplug panels, use caculated buffer
603 * or use default size
604 */
605 if (modes_num > 0) {
606 /* fix to 2* yres */
607 info->var.yres_virtual = info->var.yres * 2;
608
609 /* Allocate framebuffer memory: size = modes xy *4 */
610 fbi->fb_size = info->var.xres_virtual * info->var.yres_virtual
611 * info->var.bits_per_pixel / 8;
612 } else {
613 fbi->fb_size = MMPFB_DEFAULT_SIZE;
614 }
615
616 fbi->fb_start = dma_alloc_coherent(&pdev->dev, PAGE_ALIGN(fbi->fb_size),
617 &fbi->fb_start_dma, GFP_KERNEL);
618 if (fbi->fb_start == NULL) {
619 dev_err(&pdev->dev, "can't alloc framebuffer\n");
620 ret = -ENOMEM;
621 goto failed_destroy_mutex;
622 }
623 memset(fbi->fb_start, 0, fbi->fb_size);
624 dev_info(fbi->dev, "fb %dk allocated\n", fbi->fb_size/1024);
625
626 /* fb power on */
627 if (modes_num > 0)
628 mmpfb_power(fbi, 1);
629
630 ret = fb_info_setup(info, fbi);
631 if (ret < 0)
632 goto failed_free_buff;
633
634 ret = register_framebuffer(info);
635 if (ret < 0) {
636 dev_err(&pdev->dev, "Failed to register fb: %d\n", ret);
637 ret = -ENXIO;
638 goto failed_clear_info;
639 }
640
641 dev_info(fbi->dev, "loaded to /dev/fb%d <%s>.\n",
642 info->node, info->fix.id);
643
644#ifdef CONFIG_LOGO
645 if (fbi->fb_start) {
646 fb_prepare_logo(info, 0);
647 fb_show_logo(info, 0);
648 }
649#endif
650
651 return 0;
652
653failed_clear_info:
654 fb_info_clear(info);
655failed_free_buff:
656 dma_free_coherent(&pdev->dev, PAGE_ALIGN(fbi->fb_size), fbi->fb_start,
657 fbi->fb_start_dma);
658failed_destroy_mutex:
659 mutex_destroy(&fbi->access_ok);
660failed:
661 dev_err(fbi->dev, "mmp-fb: frame buffer device init failed\n");
662 platform_set_drvdata(pdev, NULL);
663
664 framebuffer_release(info);
665
666 return ret;
667}
668
669static struct platform_driver mmpfb_driver = {
670 .driver = {
671 .name = "mmp-fb",
672 .owner = THIS_MODULE,
673 },
674 .probe = mmpfb_probe,
675};
676
677static int mmpfb_init(void)
678{
679 return platform_driver_register(&mmpfb_driver);
680}
681module_init(mmpfb_init);
682
683MODULE_AUTHOR("Zhou Zhu <zhou.zhu@marvell.com>");
684MODULE_DESCRIPTION("Framebuffer driver for Marvell displays");
685MODULE_LICENSE("GPL");
diff --git a/drivers/video/mmp/fb/mmpfb.h b/drivers/video/mmp/fb/mmpfb.h
new file mode 100644
index 000000000000..88c23c10a9ec
--- /dev/null
+++ b/drivers/video/mmp/fb/mmpfb.h
@@ -0,0 +1,54 @@
1/*
2 * linux/drivers/video/mmp/fb/mmpfb.h
3 * Framebuffer driver for Marvell Display controller.
4 *
5 * Copyright (C) 2012 Marvell Technology Group Ltd.
6 * Authors: Zhou Zhu <zzhu3@marvell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#ifndef _MMP_FB_H_
24#define _MMP_FB_H_
25
26#include <video/mmp_disp.h>
27#include <linux/fb.h>
28
29/* LCD controller private state. */
30struct mmpfb_info {
31 struct device *dev;
32 int id;
33 const char *name;
34
35 struct fb_info *fb_info;
36 /* basicaly videomode is for output */
37 struct fb_videomode mode;
38 int pix_fmt;
39
40 void *fb_start;
41 int fb_size;
42 dma_addr_t fb_start_dma;
43
44 struct mmp_overlay *overlay;
45 struct mmp_path *path;
46
47 struct mutex access_ok;
48
49 unsigned int pseudo_palette[16];
50 int output_fmt;
51};
52
53#define MMPFB_DEFAULT_SIZE (PAGE_ALIGN(1920 * 1080 * 4 * 2))
54#endif /* _MMP_FB_H_ */
diff --git a/drivers/video/mmp/hw/Kconfig b/drivers/video/mmp/hw/Kconfig
new file mode 100644
index 000000000000..02f109a20cd0
--- /dev/null
+++ b/drivers/video/mmp/hw/Kconfig
@@ -0,0 +1,20 @@
1if MMP_DISP
2
3config MMP_DISP_CONTROLLER
4 bool "mmp display controller hw support"
5 depends on CPU_PXA910 || CPU_MMP2 || CPU_MMP3 || CPU_PXA988
6 default n
7 help
8 Marvell MMP display hw controller support
9 this controller is used on Marvell PXA910,
10 MMP2, MMP3, PXA988 chips
11
12config MMP_DISP_SPI
13 bool "mmp display controller spi port"
14 depends on MMP_DISP_CONTROLLER && SPI_MASTER
15 default y
16 help
17 Marvell MMP display hw controller spi port support
18 will register as a spi master for panel usage
19
20endif
diff --git a/drivers/video/mmp/hw/Makefile b/drivers/video/mmp/hw/Makefile
new file mode 100644
index 000000000000..0000a714fedf
--- /dev/null
+++ b/drivers/video/mmp/hw/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_MMP_DISP_CONTROLLER) += mmp_ctrl.o
2obj-$(CONFIG_MMP_DISP_SPI) += mmp_spi.o
diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/mmp/hw/mmp_ctrl.c
new file mode 100644
index 000000000000..4bd31b2af398
--- /dev/null
+++ b/drivers/video/mmp/hw/mmp_ctrl.c
@@ -0,0 +1,591 @@
1/*
2 * linux/drivers/video/mmp/hw/mmp_ctrl.c
3 * Marvell MMP series Display Controller support
4 *
5 * Copyright (C) 2012 Marvell Technology Group Ltd.
6 * Authors: Guoqing Li <ligq@marvell.com>
7 * Lisa Du <cldu@marvell.com>
8 * Zhou Zhu <zzhu3@marvell.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program. If not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/kernel.h>
27#include <linux/errno.h>
28#include <linux/string.h>
29#include <linux/interrupt.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32#include <linux/platform_device.h>
33#include <linux/dma-mapping.h>
34#include <linux/clk.h>
35#include <linux/err.h>
36#include <linux/vmalloc.h>
37#include <linux/uaccess.h>
38#include <linux/kthread.h>
39#include <linux/io.h>
40
41#include "mmp_ctrl.h"
42
43static irqreturn_t ctrl_handle_irq(int irq, void *dev_id)
44{
45 struct mmphw_ctrl *ctrl = (struct mmphw_ctrl *)dev_id;
46 u32 isr, imask, tmp;
47
48 isr = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR);
49 imask = readl_relaxed(ctrl->reg_base + SPU_IRQ_ENA);
50
51 do {
52 /* clear clock only */
53 tmp = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR);
54 if (tmp & isr)
55 writel_relaxed(~isr, ctrl->reg_base + SPU_IRQ_ISR);
56 } while ((isr = readl(ctrl->reg_base + SPU_IRQ_ISR)) & imask);
57
58 return IRQ_HANDLED;
59}
60
61static u32 fmt_to_reg(struct mmp_overlay *overlay, int pix_fmt)
62{
63 u32 link_config = path_to_path_plat(overlay->path)->link_config;
64 u32 rbswap, uvswap = 0, yuvswap = 0,
65 csc_en = 0, val = 0,
66 vid = overlay_is_vid(overlay);
67
68 switch (pix_fmt) {
69 case PIXFMT_RGB565:
70 case PIXFMT_RGB1555:
71 case PIXFMT_RGB888PACK:
72 case PIXFMT_RGB888UNPACK:
73 case PIXFMT_RGBA888:
74 rbswap = !(link_config & 0x1);
75 break;
76 case PIXFMT_VYUY:
77 case PIXFMT_YVU422P:
78 case PIXFMT_YVU420P:
79 rbswap = link_config & 0x1;
80 uvswap = 1;
81 break;
82 case PIXFMT_YUYV:
83 rbswap = link_config & 0x1;
84 yuvswap = 1;
85 break;
86 default:
87 rbswap = link_config & 0x1;
88 break;
89 }
90
91 switch (pix_fmt) {
92 case PIXFMT_RGB565:
93 case PIXFMT_BGR565:
94 val = 0;
95 break;
96 case PIXFMT_RGB1555:
97 case PIXFMT_BGR1555:
98 val = 0x1;
99 break;
100 case PIXFMT_RGB888PACK:
101 case PIXFMT_BGR888PACK:
102 val = 0x2;
103 break;
104 case PIXFMT_RGB888UNPACK:
105 case PIXFMT_BGR888UNPACK:
106 val = 0x3;
107 break;
108 case PIXFMT_RGBA888:
109 case PIXFMT_BGRA888:
110 val = 0x4;
111 break;
112 case PIXFMT_UYVY:
113 case PIXFMT_VYUY:
114 case PIXFMT_YUYV:
115 val = 0x5;
116 csc_en = 1;
117 break;
118 case PIXFMT_YUV422P:
119 case PIXFMT_YVU422P:
120 val = 0x6;
121 csc_en = 1;
122 break;
123 case PIXFMT_YUV420P:
124 case PIXFMT_YVU420P:
125 val = 0x7;
126 csc_en = 1;
127 break;
128 default:
129 break;
130 }
131
132 return (dma_palette(0) | dma_fmt(vid, val) |
133 dma_swaprb(vid, rbswap) | dma_swapuv(vid, uvswap) |
134 dma_swapyuv(vid, yuvswap) | dma_csc(vid, csc_en));
135}
136
137static void dmafetch_set_fmt(struct mmp_overlay *overlay)
138{
139 u32 tmp;
140 struct mmp_path *path = overlay->path;
141 tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
142 tmp &= ~dma_mask(overlay_is_vid(overlay));
143 tmp |= fmt_to_reg(overlay, overlay->win.pix_fmt);
144 writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
145}
146
147static void overlay_set_win(struct mmp_overlay *overlay, struct mmp_win *win)
148{
149 struct lcd_regs *regs = path_regs(overlay->path);
150 u32 pitch;
151
152 /* assert win supported */
153 memcpy(&overlay->win, win, sizeof(struct mmp_win));
154
155 mutex_lock(&overlay->access_ok);
156 pitch = win->xsrc * pixfmt_to_stride(win->pix_fmt);
157 writel_relaxed(pitch, &regs->g_pitch);
158 writel_relaxed((win->ysrc << 16) | win->xsrc, &regs->g_size);
159 writel_relaxed((win->ydst << 16) | win->xdst, &regs->g_size_z);
160 writel_relaxed(0, &regs->g_start);
161
162 dmafetch_set_fmt(overlay);
163 mutex_unlock(&overlay->access_ok);
164}
165
166static void dmafetch_onoff(struct mmp_overlay *overlay, int on)
167{
168 u32 mask = overlay_is_vid(overlay) ? CFG_GRA_ENA_MASK :
169 CFG_DMA_ENA_MASK;
170 u32 enable = overlay_is_vid(overlay) ? CFG_GRA_ENA(1) : CFG_DMA_ENA(1);
171 u32 tmp;
172 struct mmp_path *path = overlay->path;
173
174 mutex_lock(&overlay->access_ok);
175 tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
176 tmp &= ~mask;
177 tmp |= (on ? enable : 0);
178 writel(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
179 mutex_unlock(&overlay->access_ok);
180}
181
182static void path_enabledisable(struct mmp_path *path, int on)
183{
184 u32 tmp;
185 mutex_lock(&path->access_ok);
186 tmp = readl_relaxed(ctrl_regs(path) + LCD_SCLK(path));
187 if (on)
188 tmp &= ~SCLK_DISABLE;
189 else
190 tmp |= SCLK_DISABLE;
191 writel_relaxed(tmp, ctrl_regs(path) + LCD_SCLK(path));
192 mutex_unlock(&path->access_ok);
193}
194
195static void path_onoff(struct mmp_path *path, int on)
196{
197 if (path->status == on) {
198 dev_info(path->dev, "path %s is already %s\n",
199 path->name, stat_name(path->status));
200 return;
201 }
202
203 if (on) {
204 path_enabledisable(path, 1);
205
206 if (path->panel && path->panel->set_onoff)
207 path->panel->set_onoff(path->panel, 1);
208 } else {
209 if (path->panel && path->panel->set_onoff)
210 path->panel->set_onoff(path->panel, 0);
211
212 path_enabledisable(path, 0);
213 }
214 path->status = on;
215}
216
217static void overlay_set_onoff(struct mmp_overlay *overlay, int on)
218{
219 if (overlay->status == on) {
220 dev_info(overlay_to_ctrl(overlay)->dev, "overlay %s is already %s\n",
221 overlay->path->name, stat_name(overlay->status));
222 return;
223 }
224 overlay->status = on;
225 dmafetch_onoff(overlay, on);
226 if (overlay->path->ops.check_status(overlay->path)
227 != overlay->path->status)
228 path_onoff(overlay->path, on);
229}
230
231static void overlay_set_fetch(struct mmp_overlay *overlay, int fetch_id)
232{
233 overlay->dmafetch_id = fetch_id;
234}
235
236static int overlay_set_addr(struct mmp_overlay *overlay, struct mmp_addr *addr)
237{
238 struct lcd_regs *regs = path_regs(overlay->path);
239
240 /* FIXME: assert addr supported */
241 memcpy(&overlay->addr, addr, sizeof(struct mmp_win));
242 writel(addr->phys[0], &regs->g_0);
243
244 return overlay->addr.phys[0];
245}
246
247static void path_set_mode(struct mmp_path *path, struct mmp_mode *mode)
248{
249 struct lcd_regs *regs = path_regs(path);
250 u32 total_x, total_y, vsync_ctrl, tmp, sclk_src, sclk_div,
251 link_config = path_to_path_plat(path)->link_config;
252
253 /* FIXME: assert videomode supported */
254 memcpy(&path->mode, mode, sizeof(struct mmp_mode));
255
256 mutex_lock(&path->access_ok);
257
258 /* polarity of timing signals */
259 tmp = readl_relaxed(ctrl_regs(path) + intf_ctrl(path->id)) & 0x1;
260 tmp |= mode->vsync_invert ? 0 : 0x8;
261 tmp |= mode->hsync_invert ? 0 : 0x4;
262 tmp |= link_config & CFG_DUMBMODE_MASK;
263 tmp |= CFG_DUMB_ENA(1);
264 writel_relaxed(tmp, ctrl_regs(path) + intf_ctrl(path->id));
265
266 writel_relaxed((mode->yres << 16) | mode->xres, &regs->screen_active);
267 writel_relaxed((mode->left_margin << 16) | mode->right_margin,
268 &regs->screen_h_porch);
269 writel_relaxed((mode->upper_margin << 16) | mode->lower_margin,
270 &regs->screen_v_porch);
271 total_x = mode->xres + mode->left_margin + mode->right_margin +
272 mode->hsync_len;
273 total_y = mode->yres + mode->upper_margin + mode->lower_margin +
274 mode->vsync_len;
275 writel_relaxed((total_y << 16) | total_x, &regs->screen_size);
276
277 /* vsync ctrl */
278 if (path->output_type == PATH_OUT_DSI)
279 vsync_ctrl = 0x01330133;
280 else
281 vsync_ctrl = ((mode->xres + mode->right_margin) << 16)
282 | (mode->xres + mode->right_margin);
283 writel_relaxed(vsync_ctrl, &regs->vsync_ctrl);
284
285 /* set pixclock div */
286 sclk_src = clk_get_rate(path_to_ctrl(path)->clk);
287 sclk_div = sclk_src / mode->pixclock_freq;
288 if (sclk_div * mode->pixclock_freq < sclk_src)
289 sclk_div++;
290
291 dev_info(path->dev, "%s sclk_src %d sclk_div 0x%x pclk %d\n",
292 __func__, sclk_src, sclk_div, mode->pixclock_freq);
293
294 tmp = readl_relaxed(ctrl_regs(path) + LCD_SCLK(path));
295 tmp &= ~CLK_INT_DIV_MASK;
296 tmp |= sclk_div;
297 writel_relaxed(tmp, ctrl_regs(path) + LCD_SCLK(path));
298
299 mutex_unlock(&path->access_ok);
300}
301
302static struct mmp_overlay_ops mmphw_overlay_ops = {
303 .set_fetch = overlay_set_fetch,
304 .set_onoff = overlay_set_onoff,
305 .set_win = overlay_set_win,
306 .set_addr = overlay_set_addr,
307};
308
309static void ctrl_set_default(struct mmphw_ctrl *ctrl)
310{
311 u32 tmp, irq_mask;
312
313 /*
314 * LCD Global control(LCD_TOP_CTRL) should be configed before
315 * any other LCD registers read/write, or there maybe issues.
316 */
317 tmp = readl_relaxed(ctrl->reg_base + LCD_TOP_CTRL);
318 tmp |= 0xfff0;
319 writel_relaxed(tmp, ctrl->reg_base + LCD_TOP_CTRL);
320
321
322 /* disable all interrupts */
323 irq_mask = path_imasks(0) | err_imask(0) |
324 path_imasks(1) | err_imask(1);
325 tmp = readl_relaxed(ctrl->reg_base + SPU_IRQ_ENA);
326 tmp &= ~irq_mask;
327 tmp |= irq_mask;
328 writel_relaxed(tmp, ctrl->reg_base + SPU_IRQ_ENA);
329}
330
331static void path_set_default(struct mmp_path *path)
332{
333 struct lcd_regs *regs = path_regs(path);
334 u32 dma_ctrl1, mask, tmp, path_config;
335
336 path_config = path_to_path_plat(path)->path_config;
337
338 /* Configure IOPAD: should be parallel only */
339 if (PATH_OUT_PARALLEL == path->output_type) {
340 mask = CFG_IOPADMODE_MASK | CFG_BURST_MASK | CFG_BOUNDARY_MASK;
341 tmp = readl_relaxed(ctrl_regs(path) + SPU_IOPAD_CONTROL);
342 tmp &= ~mask;
343 tmp |= path_config;
344 writel_relaxed(tmp, ctrl_regs(path) + SPU_IOPAD_CONTROL);
345 }
346
347 /* Select path clock source */
348 tmp = readl_relaxed(ctrl_regs(path) + LCD_SCLK(path));
349 tmp &= ~SCLK_SRC_SEL_MASK;
350 tmp |= path_config;
351 writel_relaxed(tmp, ctrl_regs(path) + LCD_SCLK(path));
352
353 /*
354 * Configure default bits: vsync triggers DMA,
355 * power save enable, configure alpha registers to
356 * display 100% graphics, and set pixel command.
357 */
358 dma_ctrl1 = 0x2032ff81;
359
360 dma_ctrl1 |= CFG_VSYNC_INV_MASK;
361 writel_relaxed(dma_ctrl1, ctrl_regs(path) + dma_ctrl(1, path->id));
362
363 /* Configure default register values */
364 writel_relaxed(0x00000000, &regs->blank_color);
365 writel_relaxed(0x00000000, &regs->g_1);
366 writel_relaxed(0x00000000, &regs->g_start);
367
368 /*
369 * 1.enable multiple burst request in DMA AXI
370 * bus arbiter for faster read if not tv path;
371 * 2.enable horizontal smooth filter;
372 */
373 if (PATH_PN == path->id) {
374 mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK
375 | CFG_ARBFAST_ENA(1);
376 tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
377 tmp |= mask;
378 writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
379 } else if (PATH_TV == path->id) {
380 mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK
381 | CFG_ARBFAST_ENA(1);
382 tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
383 tmp &= ~mask;
384 tmp |= CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK;
385 writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
386 }
387}
388
389static int path_init(struct mmphw_path_plat *path_plat,
390 struct mmp_mach_path_config *config)
391{
392 struct mmphw_ctrl *ctrl = path_plat->ctrl;
393 struct mmp_path_info *path_info;
394 struct mmp_path *path = NULL;
395
396 dev_info(ctrl->dev, "%s: %s\n", __func__, config->name);
397
398 /* init driver data */
399 path_info = kzalloc(sizeof(struct mmp_path_info), GFP_KERNEL);
400 if (!path_info) {
401 dev_err(ctrl->dev, "%s: unable to alloc path_info for %s\n",
402 __func__, config->name);
403 return 0;
404 }
405 path_info->name = config->name;
406 path_info->id = path_plat->id;
407 path_info->dev = ctrl->dev;
408 path_info->overlay_num = config->overlay_num;
409 path_info->overlay_ops = &mmphw_overlay_ops;
410 path_info->set_mode = path_set_mode;
411 path_info->plat_data = path_plat;
412
413 /* create/register platform device */
414 path = mmp_register_path(path_info);
415 if (!path) {
416 kfree(path_info);
417 return 0;
418 }
419 path_plat->path = path;
420 path_plat->path_config = config->path_config;
421 path_plat->link_config = config->link_config;
422 path_set_default(path);
423
424 kfree(path_info);
425 return 1;
426}
427
428static void path_deinit(struct mmphw_path_plat *path_plat)
429{
430 if (!path_plat)
431 return;
432
433 if (path_plat->path)
434 mmp_unregister_path(path_plat->path);
435}
436
437static int mmphw_probe(struct platform_device *pdev)
438{
439 struct mmp_mach_plat_info *mi;
440 struct resource *res;
441 int ret, i, size, irq;
442 struct mmphw_path_plat *path_plat;
443 struct mmphw_ctrl *ctrl = NULL;
444
445 /* get resources from platform data */
446 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
447 if (res == NULL) {
448 dev_err(&pdev->dev, "%s: no IO memory defined\n", __func__);
449 ret = -ENOENT;
450 goto failed;
451 }
452
453 irq = platform_get_irq(pdev, 0);
454 if (irq < 0) {
455 dev_err(&pdev->dev, "%s: no IRQ defined\n", __func__);
456 ret = -ENOENT;
457 goto failed;
458 }
459
460 /* get configs from platform data */
461 mi = pdev->dev.platform_data;
462 if (mi == NULL || !mi->path_num || !mi->paths) {
463 dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
464 ret = -EINVAL;
465 goto failed;
466 }
467
468 /* allocate */
469 size = sizeof(struct mmphw_ctrl) + sizeof(struct mmphw_path_plat) *
470 mi->path_num;
471 ctrl = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
472 if (!ctrl) {
473 ret = -ENOMEM;
474 goto failed;
475 }
476
477 ctrl->name = mi->name;
478 ctrl->path_num = mi->path_num;
479 ctrl->dev = &pdev->dev;
480 ctrl->irq = irq;
481 platform_set_drvdata(pdev, ctrl);
482 mutex_init(&ctrl->access_ok);
483
484 /* map registers.*/
485 if (!devm_request_mem_region(ctrl->dev, res->start,
486 resource_size(res), ctrl->name)) {
487 dev_err(ctrl->dev,
488 "can't request region for resource %pR\n", res);
489 ret = -EINVAL;
490 goto failed;
491 }
492
493 ctrl->reg_base = devm_ioremap_nocache(ctrl->dev,
494 res->start, resource_size(res));
495 if (ctrl->reg_base == NULL) {
496 dev_err(ctrl->dev, "%s: res %x - %x map failed\n", __func__,
497 res->start, res->end);
498 ret = -ENOMEM;
499 goto failed;
500 }
501
502 /* request irq */
503 ret = devm_request_irq(ctrl->dev, ctrl->irq, ctrl_handle_irq,
504 IRQF_SHARED, "lcd_controller", ctrl);
505 if (ret < 0) {
506 dev_err(ctrl->dev, "%s unable to request IRQ %d\n",
507 __func__, ctrl->irq);
508 ret = -ENXIO;
509 goto failed;
510 }
511
512 /* get clock */
513 ctrl->clk = devm_clk_get(ctrl->dev, mi->clk_name);
514 if (IS_ERR(ctrl->clk)) {
515 dev_err(ctrl->dev, "unable to get clk %s\n", mi->clk_name);
516 ret = -ENOENT;
517 goto failed_get_clk;
518 }
519 clk_prepare_enable(ctrl->clk);
520
521 /* init global regs */
522 ctrl_set_default(ctrl);
523
524 /* init pathes from machine info and register them */
525 for (i = 0; i < ctrl->path_num; i++) {
526 /* get from config and machine info */
527 path_plat = &ctrl->path_plats[i];
528 path_plat->id = i;
529 path_plat->ctrl = ctrl;
530
531 /* path init */
532 if (!path_init(path_plat, &mi->paths[i])) {
533 ret = -EINVAL;
534 goto failed_path_init;
535 }
536 }
537
538#ifdef CONFIG_MMP_DISP_SPI
539 ret = lcd_spi_register(ctrl);
540 if (ret < 0)
541 goto failed_path_init;
542#endif
543
544 dev_info(ctrl->dev, "device init done\n");
545
546 return 0;
547
548failed_path_init:
549 for (i = 0; i < ctrl->path_num; i++) {
550 path_plat = &ctrl->path_plats[i];
551 path_deinit(path_plat);
552 }
553
554 if (ctrl->clk) {
555 devm_clk_put(ctrl->dev, ctrl->clk);
556 clk_disable_unprepare(ctrl->clk);
557 }
558failed_get_clk:
559 devm_free_irq(ctrl->dev, ctrl->irq, ctrl);
560failed:
561 if (ctrl) {
562 if (ctrl->reg_base)
563 devm_iounmap(ctrl->dev, ctrl->reg_base);
564 devm_release_mem_region(ctrl->dev, res->start,
565 resource_size(res));
566 devm_kfree(ctrl->dev, ctrl);
567 }
568
569 platform_set_drvdata(pdev, NULL);
570 dev_err(&pdev->dev, "device init failed\n");
571
572 return ret;
573}
574
575static struct platform_driver mmphw_driver = {
576 .driver = {
577 .name = "mmp-disp",
578 .owner = THIS_MODULE,
579 },
580 .probe = mmphw_probe,
581};
582
583static int mmphw_init(void)
584{
585 return platform_driver_register(&mmphw_driver);
586}
587module_init(mmphw_init);
588
589MODULE_AUTHOR("Li Guoqing<ligq@marvell.com>");
590MODULE_DESCRIPTION("Framebuffer driver for mmp");
591MODULE_LICENSE("GPL");
diff --git a/drivers/video/mmp/hw/mmp_ctrl.h b/drivers/video/mmp/hw/mmp_ctrl.h
new file mode 100644
index 000000000000..6408d8ef3abb
--- /dev/null
+++ b/drivers/video/mmp/hw/mmp_ctrl.h
@@ -0,0 +1,1974 @@
1/*
2 * drivers/video/mmp/hw/mmp_ctrl.h
3 *
4 *
5 * Copyright (C) 2012 Marvell Technology Group Ltd.
6 * Authors: Guoqing Li <ligq@marvell.com>
7 * Lisa Du <cldu@marvell.com>
8 * Zhou Zhu <zzhu3@marvell.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program. If not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24
25#ifndef _MMP_CTRL_H_
26#define _MMP_CTRL_H_
27
28#include <video/mmp_disp.h>
29
30/* ------------< LCD register >------------ */
31struct lcd_regs {
32/* TV patch register for MMP2 */
33/* 32 bit TV Video Frame0 Y Starting Address */
34#define LCD_TVD_START_ADDR_Y0 (0x0000)
35/* 32 bit TV Video Frame0 U Starting Address */
36#define LCD_TVD_START_ADDR_U0 (0x0004)
37/* 32 bit TV Video Frame0 V Starting Address */
38#define LCD_TVD_START_ADDR_V0 (0x0008)
39/* 32 bit TV Video Frame0 Command Starting Address */
40#define LCD_TVD_START_ADDR_C0 (0x000C)
41/* 32 bit TV Video Frame1 Y Starting Address Register*/
42#define LCD_TVD_START_ADDR_Y1 (0x0010)
43/* 32 bit TV Video Frame1 U Starting Address Register*/
44#define LCD_TVD_START_ADDR_U1 (0x0014)
45/* 32 bit TV Video Frame1 V Starting Address Register*/
46#define LCD_TVD_START_ADDR_V1 (0x0018)
47/* 32 bit TV Video Frame1 Command Starting Address Register*/
48#define LCD_TVD_START_ADDR_C1 (0x001C)
49/* 32 bit TV Video Y andC Line Length(Pitch)Register*/
50#define LCD_TVD_PITCH_YC (0x0020)
51/* 32 bit TV Video U andV Line Length(Pitch)Register*/
52#define LCD_TVD_PITCH_UV (0x0024)
53/* 32 bit TV Video Starting Point on Screen Register*/
54#define LCD_TVD_OVSA_HPXL_VLN (0x0028)
55/* 32 bit TV Video Source Size Register*/
56#define LCD_TVD_HPXL_VLN (0x002C)
57/* 32 bit TV Video Destination Size (After Zooming)Register*/
58#define LCD_TVDZM_HPXL_VLN (0x0030)
59 u32 v_y0;
60 u32 v_u0;
61 u32 v_v0;
62 u32 v_c0;
63 u32 v_y1;
64 u32 v_u1;
65 u32 v_v1;
66 u32 v_c1;
67 u32 v_pitch_yc; /* Video Y and C Line Length (Pitch) */
68 u32 v_pitch_uv; /* Video U and V Line Length (Pitch) */
69 u32 v_start; /* Video Starting Point on Screen */
70 u32 v_size; /* Video Source Size */
71 u32 v_size_z; /* Video Destination Size (After Zooming) */
72
73/* 32 bit TV Graphic Frame 0 Starting Address Register*/
74#define LCD_TVG_START_ADDR0 (0x0034)
75/* 32 bit TV Graphic Frame 1 Starting Address Register*/
76#define LCD_TVG_START_ADDR1 (0x0038)
77/* 32 bit TV Graphic Line Length(Pitch)Register*/
78#define LCD_TVG_PITCH (0x003C)
79/* 32 bit TV Graphic Starting Point on Screen Register*/
80#define LCD_TVG_OVSA_HPXL_VLN (0x0040)
81/* 32 bit TV Graphic Source Size Register*/
82#define LCD_TVG_HPXL_VLN (0x0044)
83/* 32 bit TV Graphic Destination size (after Zooming)Register*/
84#define LCD_TVGZM_HPXL_VLN (0x0048)
85 u32 g_0; /* Graphic Frame 0/1 Starting Address */
86 u32 g_1;
87 u32 g_pitch; /* Graphic Line Length (Pitch) */
88 u32 g_start; /* Graphic Starting Point on Screen */
89 u32 g_size; /* Graphic Source Size */
90 u32 g_size_z; /* Graphic Destination Size (After Zooming) */
91
92/* 32 bit TV Hardware Cursor Starting Point on screen Register*/
93#define LCD_TVC_OVSA_HPXL_VLN (0x004C)
94/* 32 bit TV Hardware Cursor Size Register */
95#define LCD_TVC_HPXL_VLN (0x0050)
96 u32 hc_start; /* Hardware Cursor */
97 u32 hc_size; /* Hardware Cursor */
98
99/* 32 bit TV Total Screen Size Register*/
100#define LCD_TV_V_H_TOTAL (0x0054)
101/* 32 bit TV Screen Active Size Register*/
102#define LCD_TV_V_H_ACTIVE (0x0058)
103/* 32 bit TV Screen Horizontal Porch Register*/
104#define LCD_TV_H_PORCH (0x005C)
105/* 32 bit TV Screen Vertical Porch Register*/
106#define LCD_TV_V_PORCH (0x0060)
107 u32 screen_size; /* Screen Total Size */
108 u32 screen_active; /* Screen Active Size */
109 u32 screen_h_porch; /* Screen Horizontal Porch */
110 u32 screen_v_porch; /* Screen Vertical Porch */
111
112/* 32 bit TV Screen Blank Color Register*/
113#define LCD_TV_BLANKCOLOR (0x0064)
114/* 32 bit TV Hardware Cursor Color1 Register*/
115#define LCD_TV_ALPHA_COLOR1 (0x0068)
116/* 32 bit TV Hardware Cursor Color2 Register*/
117#define LCD_TV_ALPHA_COLOR2 (0x006C)
118 u32 blank_color; /* Screen Blank Color */
119 u32 hc_Alpha_color1; /* Hardware Cursor Color1 */
120 u32 hc_Alpha_color2; /* Hardware Cursor Color2 */
121
122/* 32 bit TV Video Y Color Key Control*/
123#define LCD_TV_COLORKEY_Y (0x0070)
124/* 32 bit TV Video U Color Key Control*/
125#define LCD_TV_COLORKEY_U (0x0074)
126/* 32 bit TV Video V Color Key Control*/
127#define LCD_TV_COLORKEY_V (0x0078)
128 u32 v_colorkey_y; /* Video Y Color Key Control */
129 u32 v_colorkey_u; /* Video U Color Key Control */
130 u32 v_colorkey_v; /* Video V Color Key Control */
131
132/* 32 bit TV VSYNC PulsePixel Edge Control Register*/
133#define LCD_TV_SEPXLCNT (0x007C)
134 u32 vsync_ctrl; /* VSYNC PulsePixel Edge Control */
135};
136
137#define intf_ctrl(id) ((id) ? (((id) & 1) ? LCD_TVIF_CTRL : \
138 LCD_DUMB2_CTRL) : LCD_SPU_DUMB_CTRL)
139#define dma_ctrl0(id) ((id) ? (((id) & 1) ? LCD_TV_CTRL0 : \
140 LCD_PN2_CTRL0) : LCD_SPU_DMA_CTRL0)
141#define dma_ctrl1(id) ((id) ? (((id) & 1) ? LCD_TV_CTRL1 : \
142 LCD_PN2_CTRL1) : LCD_SPU_DMA_CTRL1)
143#define dma_ctrl(ctrl1, id) (ctrl1 ? dma_ctrl1(id) : dma_ctrl0(id))
144
145/* 32 bit TV Path DMA Control 0*/
146#define LCD_TV_CTRL0 (0x0080)
147/* 32 bit TV Path DMA Control 1*/
148#define LCD_TV_CTRL1 (0x0084)
149/* 32 bit TV Path Video Contrast*/
150#define LCD_TV_CONTRAST (0x0088)
151/* 32 bit TV Path Video Saturation*/
152#define LCD_TV_SATURATION (0x008C)
153/* 32 bit TV Path Video Hue Adjust*/
154#define LCD_TV_CBSH_HUE (0x0090)
155/* 32 bit TV Path TVIF Control Register */
156#define LCD_TVIF_CTRL (0x0094)
157#define TV_VBLNK_VALID_EN (1 << 12)
158
159/* 32 bit TV Path I/O Pad Control*/
160#define LCD_TVIOPAD_CTRL (0x0098)
161/* 32 bit TV Path Cloc Divider */
162#define LCD_TCLK_DIV (0x009C)
163
164#define LCD_SCLK(path) ((PATH_PN == path->id) ? LCD_CFG_SCLK_DIV :\
165 ((PATH_TV == path->id) ? LCD_TCLK_DIV : LCD_PN2_SCLK_DIV))
166
167/* dither configure */
168#ifdef CONFIG_CPU_PXA988
169#define LCD_DITHER_CTRL (0x01EC)
170#else
171#define LCD_DITHER_CTRL (0x00A0)
172#endif
173
174#define DITHER_TBL_INDEX_SEL(s) ((s) << 16)
175#define DITHER_MODE2(m) ((m) << 12)
176#define DITHER_MODE2_SHIFT (12)
177#define DITHER_4X8_EN2 (1 << 9)
178#define DITHER_4X8_EN2_SHIFT (9)
179#define DITHER_EN2 (1 << 8)
180#define DITHER_MODE1(m) ((m) << 4)
181#define DITHER_MODE1_SHIFT (4)
182#define DITHER_4X8_EN1 (1 << 1)
183#define DITHER_4X8_EN1_SHIFT (1)
184#define DITHER_EN1 (1)
185
186/* dither table data was fixed by video bpp of input and output*/
187#ifdef CONFIG_CPU_PXA988
188#define DITHER_TB_4X4_INDEX0 (0x6e4ca280)
189#define DITHER_TB_4X4_INDEX1 (0x5d7f91b3)
190#define DITHER_TB_4X8_INDEX0 (0xb391a280)
191#define DITHER_TB_4X8_INDEX1 (0x7f5d6e4c)
192#define DITHER_TB_4X8_INDEX2 (0x80a291b3)
193#define DITHER_TB_4X8_INDEX3 (0x4c6e5d7f)
194#define LCD_DITHER_TBL_DATA (0x01F0)
195#else
196#define DITHER_TB_4X4_INDEX0 (0x3b19f7d5)
197#define DITHER_TB_4X4_INDEX1 (0x082ac4e6)
198#define DITHER_TB_4X8_INDEX0 (0xf7d508e6)
199#define DITHER_TB_4X8_INDEX1 (0x3b194c2a)
200#define DITHER_TB_4X8_INDEX2 (0xc4e6d5f7)
201#define DITHER_TB_4X8_INDEX3 (0x082a193b)
202#define LCD_DITHER_TBL_DATA (0x00A4)
203#endif
204
205/* Video Frame 0&1 start address registers */
206#define LCD_SPU_DMA_START_ADDR_Y0 0x00C0
207#define LCD_SPU_DMA_START_ADDR_U0 0x00C4
208#define LCD_SPU_DMA_START_ADDR_V0 0x00C8
209#define LCD_CFG_DMA_START_ADDR_0 0x00CC /* Cmd address */
210#define LCD_SPU_DMA_START_ADDR_Y1 0x00D0
211#define LCD_SPU_DMA_START_ADDR_U1 0x00D4
212#define LCD_SPU_DMA_START_ADDR_V1 0x00D8
213#define LCD_CFG_DMA_START_ADDR_1 0x00DC /* Cmd address */
214
215/* YC & UV Pitch */
216#define LCD_SPU_DMA_PITCH_YC 0x00E0
217#define SPU_DMA_PITCH_C(c) ((c)<<16)
218#define SPU_DMA_PITCH_Y(y) (y)
219#define LCD_SPU_DMA_PITCH_UV 0x00E4
220#define SPU_DMA_PITCH_V(v) ((v)<<16)
221#define SPU_DMA_PITCH_U(u) (u)
222
223/* Video Starting Point on Screen Register */
224#define LCD_SPUT_DMA_OVSA_HPXL_VLN 0x00E8
225#define CFG_DMA_OVSA_VLN(y) ((y)<<16) /* 0~0xfff */
226#define CFG_DMA_OVSA_HPXL(x) (x) /* 0~0xfff */
227
228/* Video Size Register */
229#define LCD_SPU_DMA_HPXL_VLN 0x00EC
230#define CFG_DMA_VLN(y) ((y)<<16)
231#define CFG_DMA_HPXL(x) (x)
232
233/* Video Size After zooming Register */
234#define LCD_SPU_DZM_HPXL_VLN 0x00F0
235#define CFG_DZM_VLN(y) ((y)<<16)
236#define CFG_DZM_HPXL(x) (x)
237
238/* Graphic Frame 0&1 Starting Address Register */
239#define LCD_CFG_GRA_START_ADDR0 0x00F4
240#define LCD_CFG_GRA_START_ADDR1 0x00F8
241
242/* Graphic Frame Pitch */
243#define LCD_CFG_GRA_PITCH 0x00FC
244
245/* Graphic Starting Point on Screen Register */
246#define LCD_SPU_GRA_OVSA_HPXL_VLN 0x0100
247#define CFG_GRA_OVSA_VLN(y) ((y)<<16)
248#define CFG_GRA_OVSA_HPXL(x) (x)
249
250/* Graphic Size Register */
251#define LCD_SPU_GRA_HPXL_VLN 0x0104
252#define CFG_GRA_VLN(y) ((y)<<16)
253#define CFG_GRA_HPXL(x) (x)
254
255/* Graphic Size after Zooming Register */
256#define LCD_SPU_GZM_HPXL_VLN 0x0108
257#define CFG_GZM_VLN(y) ((y)<<16)
258#define CFG_GZM_HPXL(x) (x)
259
260/* HW Cursor Starting Point on Screen Register */
261#define LCD_SPU_HWC_OVSA_HPXL_VLN 0x010C
262#define CFG_HWC_OVSA_VLN(y) ((y)<<16)
263#define CFG_HWC_OVSA_HPXL(x) (x)
264
265/* HW Cursor Size */
266#define LCD_SPU_HWC_HPXL_VLN 0x0110
267#define CFG_HWC_VLN(y) ((y)<<16)
268#define CFG_HWC_HPXL(x) (x)
269
270/* Total Screen Size Register */
271#define LCD_SPUT_V_H_TOTAL 0x0114
272#define CFG_V_TOTAL(y) ((y)<<16)
273#define CFG_H_TOTAL(x) (x)
274
275/* Total Screen Active Size Register */
276#define LCD_SPU_V_H_ACTIVE 0x0118
277#define CFG_V_ACTIVE(y) ((y)<<16)
278#define CFG_H_ACTIVE(x) (x)
279
280/* Screen H&V Porch Register */
281#define LCD_SPU_H_PORCH 0x011C
282#define CFG_H_BACK_PORCH(b) ((b)<<16)
283#define CFG_H_FRONT_PORCH(f) (f)
284#define LCD_SPU_V_PORCH 0x0120
285#define CFG_V_BACK_PORCH(b) ((b)<<16)
286#define CFG_V_FRONT_PORCH(f) (f)
287
288/* Screen Blank Color Register */
289#define LCD_SPU_BLANKCOLOR 0x0124
290#define CFG_BLANKCOLOR_MASK 0x00FFFFFF
291#define CFG_BLANKCOLOR_R_MASK 0x000000FF
292#define CFG_BLANKCOLOR_G_MASK 0x0000FF00
293#define CFG_BLANKCOLOR_B_MASK 0x00FF0000
294
295/* HW Cursor Color 1&2 Register */
296#define LCD_SPU_ALPHA_COLOR1 0x0128
297#define CFG_HWC_COLOR1 0x00FFFFFF
298#define CFG_HWC_COLOR1_R(red) ((red)<<16)
299#define CFG_HWC_COLOR1_G(green) ((green)<<8)
300#define CFG_HWC_COLOR1_B(blue) (blue)
301#define CFG_HWC_COLOR1_R_MASK 0x000000FF
302#define CFG_HWC_COLOR1_G_MASK 0x0000FF00
303#define CFG_HWC_COLOR1_B_MASK 0x00FF0000
304#define LCD_SPU_ALPHA_COLOR2 0x012C
305#define CFG_HWC_COLOR2 0x00FFFFFF
306#define CFG_HWC_COLOR2_R_MASK 0x000000FF
307#define CFG_HWC_COLOR2_G_MASK 0x0000FF00
308#define CFG_HWC_COLOR2_B_MASK 0x00FF0000
309
310/* Video YUV Color Key Control */
311#define LCD_SPU_COLORKEY_Y 0x0130
312#define CFG_CKEY_Y2(y2) ((y2)<<24)
313#define CFG_CKEY_Y2_MASK 0xFF000000
314#define CFG_CKEY_Y1(y1) ((y1)<<16)
315#define CFG_CKEY_Y1_MASK 0x00FF0000
316#define CFG_CKEY_Y(y) ((y)<<8)
317#define CFG_CKEY_Y_MASK 0x0000FF00
318#define CFG_ALPHA_Y(y) (y)
319#define CFG_ALPHA_Y_MASK 0x000000FF
320#define LCD_SPU_COLORKEY_U 0x0134
321#define CFG_CKEY_U2(u2) ((u2)<<24)
322#define CFG_CKEY_U2_MASK 0xFF000000
323#define CFG_CKEY_U1(u1) ((u1)<<16)
324#define CFG_CKEY_U1_MASK 0x00FF0000
325#define CFG_CKEY_U(u) ((u)<<8)
326#define CFG_CKEY_U_MASK 0x0000FF00
327#define CFG_ALPHA_U(u) (u)
328#define CFG_ALPHA_U_MASK 0x000000FF
329#define LCD_SPU_COLORKEY_V 0x0138
330#define CFG_CKEY_V2(v2) ((v2)<<24)
331#define CFG_CKEY_V2_MASK 0xFF000000
332#define CFG_CKEY_V1(v1) ((v1)<<16)
333#define CFG_CKEY_V1_MASK 0x00FF0000
334#define CFG_CKEY_V(v) ((v)<<8)
335#define CFG_CKEY_V_MASK 0x0000FF00
336#define CFG_ALPHA_V(v) (v)
337#define CFG_ALPHA_V_MASK 0x000000FF
338
339/* Graphics/Video DMA color key enable bits in LCD_TV_CTRL1 */
340#define CFG_CKEY_GRA 0x2
341#define CFG_CKEY_DMA 0x1
342
343/* Interlace mode enable bits in LCD_TV_CTRL1 */
344#define CFG_TV_INTERLACE_EN (1 << 22)
345#define CFG_TV_NIB (1 << 0)
346
347#define LCD_PN_SEPXLCNT 0x013c /* MMP2 */
348
349/* SPI Read Data Register */
350#define LCD_SPU_SPI_RXDATA 0x0140
351
352/* Smart Panel Read Data Register */
353#define LCD_SPU_ISA_RSDATA 0x0144
354#define ISA_RXDATA_16BIT_1_DATA_MASK 0x000000FF
355#define ISA_RXDATA_16BIT_2_DATA_MASK 0x0000FF00
356#define ISA_RXDATA_16BIT_3_DATA_MASK 0x00FF0000
357#define ISA_RXDATA_16BIT_4_DATA_MASK 0xFF000000
358#define ISA_RXDATA_32BIT_1_DATA_MASK 0x00FFFFFF
359
360#define LCD_SPU_DBG_ISA (0x0148) /* TTC */
361#define LCD_SPU_DMAVLD_YC (0x014C)
362#define LCD_SPU_DMAVLD_UV (0x0150)
363#define LCD_SPU_DMAVLD_UVSPU_GRAVLD (0x0154)
364
365#define LCD_READ_IOPAD (0x0148) /* MMP2*/
366#define LCD_DMAVLD_YC (0x014C)
367#define LCD_DMAVLD_UV (0x0150)
368#define LCD_TVGGRAVLD_HLEN (0x0154)
369
370/* HWC SRAM Read Data Register */
371#define LCD_SPU_HWC_RDDAT 0x0158
372
373/* Gamma Table SRAM Read Data Register */
374#define LCD_SPU_GAMMA_RDDAT 0x015c
375#define CFG_GAMMA_RDDAT_MASK 0x000000FF
376
377/* Palette Table SRAM Read Data Register */
378#define LCD_SPU_PALETTE_RDDAT 0x0160
379#define CFG_PALETTE_RDDAT_MASK 0x00FFFFFF
380
381#define LCD_SPU_DBG_DMATOP (0x0164) /* TTC */
382#define LCD_SPU_DBG_GRATOP (0x0168)
383#define LCD_SPU_DBG_TXCTRL (0x016C)
384#define LCD_SPU_DBG_SLVTOP (0x0170)
385#define LCD_SPU_DBG_MUXTOP (0x0174)
386
387#define LCD_SLV_DBG (0x0164) /* MMP2 */
388#define LCD_TVDVLD_YC (0x0168)
389#define LCD_TVDVLD_UV (0x016C)
390#define LCD_TVC_RDDAT (0x0170)
391#define LCD_TV_GAMMA_RDDAT (0x0174)
392
393/* I/O Pads Input Read Only Register */
394#define LCD_SPU_IOPAD_IN 0x0178
395#define CFG_IOPAD_IN_MASK 0x0FFFFFFF
396
397#define LCD_TV_PALETTE_RDDAT (0x0178) /* MMP2 */
398
399/* Reserved Read Only Registers */
400#define LCD_CFG_RDREG5F 0x017C
401#define IRE_FRAME_CNT_MASK 0x000000C0
402#define IPE_FRAME_CNT_MASK 0x00000030
403#define GRA_FRAME_CNT_MASK 0x0000000C /* Graphic */
404#define DMA_FRAME_CNT_MASK 0x00000003 /* Video */
405
406#define LCD_FRAME_CNT (0x017C) /* MMP2 */
407
408/* SPI Control Register. */
409#define LCD_SPU_SPI_CTRL 0x0180
410#define CFG_SCLKCNT(div) ((div)<<24) /* 0xFF~0x2 */
411#define CFG_SCLKCNT_MASK 0xFF000000
412#define CFG_RXBITS(rx) (((rx) - 1)<<16) /* 0x1F~0x1 */
413#define CFG_RXBITS_MASK 0x00FF0000
414#define CFG_TXBITS(tx) (((tx) - 1)<<8) /* 0x1F~0x1 */
415#define CFG_TXBITS_MASK 0x0000FF00
416#define CFG_CLKINV(clk) ((clk)<<7)
417#define CFG_CLKINV_MASK 0x00000080
418#define CFG_KEEPXFER(transfer) ((transfer)<<6)
419#define CFG_KEEPXFER_MASK 0x00000040
420#define CFG_RXBITSTO0(rx) ((rx)<<5)
421#define CFG_RXBITSTO0_MASK 0x00000020
422#define CFG_TXBITSTO0(tx) ((tx)<<4)
423#define CFG_TXBITSTO0_MASK 0x00000010
424#define CFG_SPI_ENA(spi) ((spi)<<3)
425#define CFG_SPI_ENA_MASK 0x00000008
426#define CFG_SPI_SEL(spi) ((spi)<<2)
427#define CFG_SPI_SEL_MASK 0x00000004
428#define CFG_SPI_3W4WB(wire) ((wire)<<1)
429#define CFG_SPI_3W4WB_MASK 0x00000002
430#define CFG_SPI_START(start) (start)
431#define CFG_SPI_START_MASK 0x00000001
432
433/* SPI Tx Data Register */
434#define LCD_SPU_SPI_TXDATA 0x0184
435
436/*
437 1. Smart Pannel 8-bit Bus Control Register.
438 2. AHB Slave Path Data Port Register
439*/
440#define LCD_SPU_SMPN_CTRL 0x0188
441
442/* DMA Control 0 Register */
443#define LCD_SPU_DMA_CTRL0 0x0190
444#define CFG_NOBLENDING(nb) ((nb)<<31)
445#define CFG_NOBLENDING_MASK 0x80000000
446#define CFG_GAMMA_ENA(gn) ((gn)<<30)
447#define CFG_GAMMA_ENA_MASK 0x40000000
448#define CFG_CBSH_ENA(cn) ((cn)<<29)
449#define CFG_CBSH_ENA_MASK 0x20000000
450#define CFG_PALETTE_ENA(pn) ((pn)<<28)
451#define CFG_PALETTE_ENA_MASK 0x10000000
452#define CFG_ARBFAST_ENA(an) ((an)<<27)
453#define CFG_ARBFAST_ENA_MASK 0x08000000
454#define CFG_HWC_1BITMOD(mode) ((mode)<<26)
455#define CFG_HWC_1BITMOD_MASK 0x04000000
456#define CFG_HWC_1BITENA(mn) ((mn)<<25)
457#define CFG_HWC_1BITENA_MASK 0x02000000
458#define CFG_HWC_ENA(cn) ((cn)<<24)
459#define CFG_HWC_ENA_MASK 0x01000000
460#define CFG_DMAFORMAT(dmaformat) ((dmaformat)<<20)
461#define CFG_DMAFORMAT_MASK 0x00F00000
462#define CFG_GRAFORMAT(graformat) ((graformat)<<16)
463#define CFG_GRAFORMAT_MASK 0x000F0000
464/* for graphic part */
465#define CFG_GRA_FTOGGLE(toggle) ((toggle)<<15)
466#define CFG_GRA_FTOGGLE_MASK 0x00008000
467#define CFG_GRA_HSMOOTH(smooth) ((smooth)<<14)
468#define CFG_GRA_HSMOOTH_MASK 0x00004000
469#define CFG_GRA_TSTMODE(test) ((test)<<13)
470#define CFG_GRA_TSTMODE_MASK 0x00002000
471#define CFG_GRA_SWAPRB(swap) ((swap)<<12)
472#define CFG_GRA_SWAPRB_MASK 0x00001000
473#define CFG_GRA_SWAPUV(swap) ((swap)<<11)
474#define CFG_GRA_SWAPUV_MASK 0x00000800
475#define CFG_GRA_SWAPYU(swap) ((swap)<<10)
476#define CFG_GRA_SWAPYU_MASK 0x00000400
477#define CFG_GRA_SWAP_MASK 0x00001C00
478#define CFG_YUV2RGB_GRA(cvrt) ((cvrt)<<9)
479#define CFG_YUV2RGB_GRA_MASK 0x00000200
480#define CFG_GRA_ENA(gra) ((gra)<<8)
481#define CFG_GRA_ENA_MASK 0x00000100
482#define dma0_gfx_masks (CFG_GRAFORMAT_MASK | CFG_GRA_FTOGGLE_MASK | \
483 CFG_GRA_HSMOOTH_MASK | CFG_GRA_TSTMODE_MASK | CFG_GRA_SWAP_MASK | \
484 CFG_YUV2RGB_GRA_MASK | CFG_GRA_ENA_MASK)
485/* for video part */
486#define CFG_DMA_FTOGGLE(toggle) ((toggle)<<7)
487#define CFG_DMA_FTOGGLE_MASK 0x00000080
488#define CFG_DMA_HSMOOTH(smooth) ((smooth)<<6)
489#define CFG_DMA_HSMOOTH_MASK 0x00000040
490#define CFG_DMA_TSTMODE(test) ((test)<<5)
491#define CFG_DMA_TSTMODE_MASK 0x00000020
492#define CFG_DMA_SWAPRB(swap) ((swap)<<4)
493#define CFG_DMA_SWAPRB_MASK 0x00000010
494#define CFG_DMA_SWAPUV(swap) ((swap)<<3)
495#define CFG_DMA_SWAPUV_MASK 0x00000008
496#define CFG_DMA_SWAPYU(swap) ((swap)<<2)
497#define CFG_DMA_SWAPYU_MASK 0x00000004
498#define CFG_DMA_SWAP_MASK 0x0000001C
499#define CFG_YUV2RGB_DMA(cvrt) ((cvrt)<<1)
500#define CFG_YUV2RGB_DMA_MASK 0x00000002
501#define CFG_DMA_ENA(video) (video)
502#define CFG_DMA_ENA_MASK 0x00000001
503#define dma0_vid_masks (CFG_DMAFORMAT_MASK | CFG_DMA_FTOGGLE_MASK | \
504 CFG_DMA_HSMOOTH_MASK | CFG_DMA_TSTMODE_MASK | CFG_DMA_SWAP_MASK | \
505 CFG_YUV2RGB_DMA_MASK | CFG_DMA_ENA_MASK)
506#define dma_palette(val) ((val ? 1 : 0) << 28)
507#define dma_fmt(vid, val) ((val & 0xf) << ((vid) ? 20 : 16))
508#define dma_swaprb(vid, val) ((val ? 1 : 0) << ((vid) ? 4 : 12))
509#define dma_swapuv(vid, val) ((val ? 1 : 0) << ((vid) ? 3 : 11))
510#define dma_swapyuv(vid, val) ((val ? 1 : 0) << ((vid) ? 2 : 10))
511#define dma_csc(vid, val) ((val ? 1 : 0) << ((vid) ? 1 : 9))
512#define dma_hsmooth(vid, val) ((val ? 1 : 0) << ((vid) ? 6 : 14))
513#define dma_mask(vid) (dma_palette(1) | dma_fmt(vid, 0xf) | dma_csc(vid, 1) \
514 | dma_swaprb(vid, 1) | dma_swapuv(vid, 1) | dma_swapyuv(vid, 1))
515
516/* DMA Control 1 Register */
517#define LCD_SPU_DMA_CTRL1 0x0194
518#define CFG_FRAME_TRIG(trig) ((trig)<<31)
519#define CFG_FRAME_TRIG_MASK 0x80000000
520#define CFG_VSYNC_TRIG(trig) ((trig)<<28)
521#define CFG_VSYNC_TRIG_MASK 0x70000000
522#define CFG_VSYNC_INV(inv) ((inv)<<27)
523#define CFG_VSYNC_INV_MASK 0x08000000
524#define CFG_COLOR_KEY_MODE(cmode) ((cmode)<<24)
525#define CFG_COLOR_KEY_MASK 0x07000000
526#define CFG_CARRY(carry) ((carry)<<23)
527#define CFG_CARRY_MASK 0x00800000
528#define CFG_LNBUF_ENA(lnbuf) ((lnbuf)<<22)
529#define CFG_LNBUF_ENA_MASK 0x00400000
530#define CFG_GATED_ENA(gated) ((gated)<<21)
531#define CFG_GATED_ENA_MASK 0x00200000
532#define CFG_PWRDN_ENA(power) ((power)<<20)
533#define CFG_PWRDN_ENA_MASK 0x00100000
534#define CFG_DSCALE(dscale) ((dscale)<<18)
535#define CFG_DSCALE_MASK 0x000C0000
536#define CFG_ALPHA_MODE(amode) ((amode)<<16)
537#define CFG_ALPHA_MODE_MASK 0x00030000
538#define CFG_ALPHA(alpha) ((alpha)<<8)
539#define CFG_ALPHA_MASK 0x0000FF00
540#define CFG_PXLCMD(pxlcmd) (pxlcmd)
541#define CFG_PXLCMD_MASK 0x000000FF
542
543/* SRAM Control Register */
544#define LCD_SPU_SRAM_CTRL 0x0198
545#define CFG_SRAM_INIT_WR_RD(mode) ((mode)<<14)
546#define CFG_SRAM_INIT_WR_RD_MASK 0x0000C000
547#define CFG_SRAM_ADDR_LCDID(id) ((id)<<8)
548#define CFG_SRAM_ADDR_LCDID_MASK 0x00000F00
549#define CFG_SRAM_ADDR(addr) (addr)
550#define CFG_SRAM_ADDR_MASK 0x000000FF
551
552/* SRAM Write Data Register */
553#define LCD_SPU_SRAM_WRDAT 0x019C
554
555/* SRAM RTC/WTC Control Register */
556#define LCD_SPU_SRAM_PARA0 0x01A0
557
558/* SRAM Power Down Control Register */
559#define LCD_SPU_SRAM_PARA1 0x01A4
560#define CFG_CSB_256x32(hwc) ((hwc)<<15) /* HWC */
561#define CFG_CSB_256x32_MASK 0x00008000
562#define CFG_CSB_256x24(palette) ((palette)<<14) /* Palette */
563#define CFG_CSB_256x24_MASK 0x00004000
564#define CFG_CSB_256x8(gamma) ((gamma)<<13) /* Gamma */
565#define CFG_CSB_256x8_MASK 0x00002000
566#define CFG_PDWN256x32(pdwn) ((pdwn)<<7) /* HWC */
567#define CFG_PDWN256x32_MASK 0x00000080
568#define CFG_PDWN256x24(pdwn) ((pdwn)<<6) /* Palette */
569#define CFG_PDWN256x24_MASK 0x00000040
570#define CFG_PDWN256x8(pdwn) ((pdwn)<<5) /* Gamma */
571#define CFG_PDWN256x8_MASK 0x00000020
572#define CFG_PDWN32x32(pdwn) ((pdwn)<<3)
573#define CFG_PDWN32x32_MASK 0x00000008
574#define CFG_PDWN16x66(pdwn) ((pdwn)<<2)
575#define CFG_PDWN16x66_MASK 0x00000004
576#define CFG_PDWN32x66(pdwn) ((pdwn)<<1)
577#define CFG_PDWN32x66_MASK 0x00000002
578#define CFG_PDWN64x66(pdwn) (pdwn)
579#define CFG_PDWN64x66_MASK 0x00000001
580
581/* Smart or Dumb Panel Clock Divider */
582#define LCD_CFG_SCLK_DIV 0x01A8
583#define SCLK_SRC_SEL(src) ((src)<<31)
584#define SCLK_SRC_SEL_MASK 0x80000000
585#define SCLK_DISABLE (1<<28)
586#define CLK_FRACDIV(frac) ((frac)<<16)
587#define CLK_FRACDIV_MASK 0x0FFF0000
588#define DSI1_BITCLK_DIV(div) (div<<8)
589#define DSI1_BITCLK_DIV_MASK 0x00000F00
590#define CLK_INT_DIV(div) (div)
591#define CLK_INT_DIV_MASK 0x000000FF
592
593/* Video Contrast Register */
594#define LCD_SPU_CONTRAST 0x01AC
595#define CFG_BRIGHTNESS(bright) ((bright)<<16)
596#define CFG_BRIGHTNESS_MASK 0xFFFF0000
597#define CFG_CONTRAST(contrast) (contrast)
598#define CFG_CONTRAST_MASK 0x0000FFFF
599
600/* Video Saturation Register */
601#define LCD_SPU_SATURATION 0x01B0
602#define CFG_C_MULTS(mult) ((mult)<<16)
603#define CFG_C_MULTS_MASK 0xFFFF0000
604#define CFG_SATURATION(sat) (sat)
605#define CFG_SATURATION_MASK 0x0000FFFF
606
607/* Video Hue Adjust Register */
608#define LCD_SPU_CBSH_HUE 0x01B4
609#define CFG_SIN0(sin0) ((sin0)<<16)
610#define CFG_SIN0_MASK 0xFFFF0000
611#define CFG_COS0(con0) (con0)
612#define CFG_COS0_MASK 0x0000FFFF
613
614/* Dump LCD Panel Control Register */
615#define LCD_SPU_DUMB_CTRL 0x01B8
616#define CFG_DUMBMODE(mode) ((mode)<<28)
617#define CFG_DUMBMODE_MASK 0xF0000000
618#define CFG_LCDGPIO_O(data) ((data)<<20)
619#define CFG_LCDGPIO_O_MASK 0x0FF00000
620#define CFG_LCDGPIO_ENA(gpio) ((gpio)<<12)
621#define CFG_LCDGPIO_ENA_MASK 0x000FF000
622#define CFG_BIAS_OUT(bias) ((bias)<<8)
623#define CFG_BIAS_OUT_MASK 0x00000100
624#define CFG_REVERSE_RGB(RGB) ((RGB)<<7)
625#define CFG_REVERSE_RGB_MASK 0x00000080
626#define CFG_INV_COMPBLANK(blank) ((blank)<<6)
627#define CFG_INV_COMPBLANK_MASK 0x00000040
628#define CFG_INV_COMPSYNC(sync) ((sync)<<5)
629#define CFG_INV_COMPSYNC_MASK 0x00000020
630#define CFG_INV_HENA(hena) ((hena)<<4)
631#define CFG_INV_HENA_MASK 0x00000010
632#define CFG_INV_VSYNC(vsync) ((vsync)<<3)
633#define CFG_INV_VSYNC_MASK 0x00000008
634#define CFG_INV_HSYNC(hsync) ((hsync)<<2)
635#define CFG_INV_HSYNC_MASK 0x00000004
636#define CFG_INV_PCLK(pclk) ((pclk)<<1)
637#define CFG_INV_PCLK_MASK 0x00000002
638#define CFG_DUMB_ENA(dumb) (dumb)
639#define CFG_DUMB_ENA_MASK 0x00000001
640
641/* LCD I/O Pads Control Register */
642#define SPU_IOPAD_CONTROL 0x01BC
643#define CFG_GRA_VM_ENA(vm) ((vm)<<15)
644#define CFG_GRA_VM_ENA_MASK 0x00008000
645#define CFG_DMA_VM_ENA(vm) ((vm)<<13)
646#define CFG_DMA_VM_ENA_MASK 0x00002000
647#define CFG_CMD_VM_ENA(vm) ((vm)<<12)
648#define CFG_CMD_VM_ENA_MASK 0x00001000
649#define CFG_CSC(csc) ((csc)<<8)
650#define CFG_CSC_MASK 0x00000300
651#define CFG_BOUNDARY(size) ((size)<<5)
652#define CFG_BOUNDARY_MASK 0x00000020
653#define CFG_BURST(len) ((len)<<4)
654#define CFG_BURST_MASK 0x00000010
655#define CFG_IOPADMODE(iopad) (iopad)
656#define CFG_IOPADMODE_MASK 0x0000000F
657
658/* LCD Interrupt Control Register */
659#define SPU_IRQ_ENA 0x01C0
660#define DMA_FRAME_IRQ0_ENA(irq) ((irq)<<31)
661#define DMA_FRAME_IRQ0_ENA_MASK 0x80000000
662#define DMA_FRAME_IRQ1_ENA(irq) ((irq)<<30)
663#define DMA_FRAME_IRQ1_ENA_MASK 0x40000000
664#define DMA_FF_UNDERFLOW_ENA(ff) ((ff)<<29)
665#define DMA_FF_UNDERFLOW_ENA_MASK 0x20000000
666#define AXI_BUS_ERROR_IRQ_ENA(irq) ((irq)<<28)
667#define AXI_BUS_ERROR_IRQ_ENA_MASK 0x10000000
668#define GRA_FRAME_IRQ0_ENA(irq) ((irq)<<27)
669#define GRA_FRAME_IRQ0_ENA_MASK 0x08000000
670#define GRA_FRAME_IRQ1_ENA(irq) ((irq)<<26)
671#define GRA_FRAME_IRQ1_ENA_MASK 0x04000000
672#define GRA_FF_UNDERFLOW_ENA(ff) ((ff)<<25)
673#define GRA_FF_UNDERFLOW_ENA_MASK 0x02000000
674#define VSYNC_IRQ_ENA(vsync_irq) ((vsync_irq)<<23)
675#define VSYNC_IRQ_ENA_MASK 0x00800000
676#define DUMB_FRAMEDONE_ENA(fdone) ((fdone)<<22)
677#define DUMB_FRAMEDONE_ENA_MASK 0x00400000
678#define TWC_FRAMEDONE_ENA(fdone) ((fdone)<<21)
679#define TWC_FRAMEDONE_ENA_MASK 0x00200000
680#define HWC_FRAMEDONE_ENA(fdone) ((fdone)<<20)
681#define HWC_FRAMEDONE_ENA_MASK 0x00100000
682#define SLV_IRQ_ENA(irq) ((irq)<<19)
683#define SLV_IRQ_ENA_MASK 0x00080000
684#define SPI_IRQ_ENA(irq) ((irq)<<18)
685#define SPI_IRQ_ENA_MASK 0x00040000
686#define PWRDN_IRQ_ENA(irq) ((irq)<<17)
687#define PWRDN_IRQ_ENA_MASK 0x00020000
688#define AXI_LATENCY_TOO_LONG_IRQ_ENA(irq) ((irq)<<16)
689#define AXI_LATENCY_TOO_LONG_IRQ_ENA_MASK 0x00010000
690#define CLEAN_SPU_IRQ_ISR(irq) (irq)
691#define CLEAN_SPU_IRQ_ISR_MASK 0x0000FFFF
692#define TV_DMA_FRAME_IRQ0_ENA(irq) ((irq)<<15)
693#define TV_DMA_FRAME_IRQ0_ENA_MASK 0x00008000
694#define TV_DMA_FRAME_IRQ1_ENA(irq) ((irq)<<14)
695#define TV_DMA_FRAME_IRQ1_ENA_MASK 0x00004000
696#define TV_DMA_FF_UNDERFLOW_ENA(unerrun) ((unerrun)<<13)
697#define TV_DMA_FF_UNDERFLOW_ENA_MASK 0x00002000
698#define TVSYNC_IRQ_ENA(irq) ((irq)<<12)
699#define TVSYNC_IRQ_ENA_MASK 0x00001000
700#define TV_FRAME_IRQ0_ENA(irq) ((irq)<<11)
701#define TV_FRAME_IRQ0_ENA_MASK 0x00000800
702#define TV_FRAME_IRQ1_ENA(irq) ((irq)<<10)
703#define TV_FRAME_IRQ1_ENA_MASK 0x00000400
704#define TV_GRA_FF_UNDERFLOW_ENA(unerrun) ((unerrun)<<9)
705#define TV_GRA_FF_UNDERFLOW_ENA_MASK 0x00000200
706#define TV_FRAMEDONE_ENA(irq) ((irq)<<8)
707#define TV_FRAMEDONE_ENA_MASK 0x00000100
708
709/* FIXME - JUST GUESS */
710#define PN2_DMA_FRAME_IRQ0_ENA(irq) ((irq)<<7)
711#define PN2_DMA_FRAME_IRQ0_ENA_MASK 0x00000080
712#define PN2_DMA_FRAME_IRQ1_ENA(irq) ((irq)<<6)
713#define PN2_DMA_FRAME_IRQ1_ENA_MASK 0x00000040
714#define PN2_DMA_FF_UNDERFLOW_ENA(ff) ((ff)<<5)
715#define PN2_DMA_FF_UNDERFLOW_ENA_MASK 0x00000020
716#define PN2_GRA_FRAME_IRQ0_ENA(irq) ((irq)<<3)
717#define PN2_GRA_FRAME_IRQ0_ENA_MASK 0x00000008
718#define PN2_GRA_FRAME_IRQ1_ENA(irq) ((irq)<<2)
719#define PN2_GRA_FRAME_IRQ1_ENA_MASK 0x04000004
720#define PN2_GRA_FF_UNDERFLOW_ENA(ff) ((ff)<<1)
721#define PN2_GRA_FF_UNDERFLOW_ENA_MASK 0x00000002
722#define PN2_VSYNC_IRQ_ENA(irq) ((irq)<<0)
723#define PN2_SYNC_IRQ_ENA_MASK 0x00000001
724
725#define gf0_imask(id) ((id) ? (((id) & 1) ? TV_FRAME_IRQ0_ENA_MASK \
726 : PN2_GRA_FRAME_IRQ0_ENA_MASK) : GRA_FRAME_IRQ0_ENA_MASK)
727#define gf1_imask(id) ((id) ? (((id) & 1) ? TV_FRAME_IRQ1_ENA_MASK \
728 : PN2_GRA_FRAME_IRQ1_ENA_MASK) : GRA_FRAME_IRQ1_ENA_MASK)
729#define vsync_imask(id) ((id) ? (((id) & 1) ? TVSYNC_IRQ_ENA_MASK \
730 : PN2_SYNC_IRQ_ENA_MASK) : VSYNC_IRQ_ENA_MASK)
731#define vsync_imasks (vsync_imask(0) | vsync_imask(1))
732
733#define display_done_imask(id) ((id) ? (((id) & 1) ? TV_FRAMEDONE_ENA_MASK\
734 : (PN2_DMA_FRAME_IRQ0_ENA_MASK | PN2_DMA_FRAME_IRQ1_ENA_MASK))\
735 : DUMB_FRAMEDONE_ENA_MASK)
736
737#define display_done_imasks (display_done_imask(0) | display_done_imask(1))
738
739#define vf0_imask(id) ((id) ? (((id) & 1) ? TV_DMA_FRAME_IRQ0_ENA_MASK \
740 : PN2_DMA_FRAME_IRQ0_ENA_MASK) : DMA_FRAME_IRQ0_ENA_MASK)
741#define vf1_imask(id) ((id) ? (((id) & 1) ? TV_DMA_FRAME_IRQ1_ENA_MASK \
742 : PN2_DMA_FRAME_IRQ1_ENA_MASK) : DMA_FRAME_IRQ1_ENA_MASK)
743
744#define gfx_imasks (gf0_imask(0) | gf1_imask(0) | gf0_imask(1) | \
745 gf1_imask(1))
746#define vid_imasks (vf0_imask(0) | vf1_imask(0) | vf0_imask(1) | \
747 vf1_imask(1))
748#define vid_imask(id) (display_done_imask(id))
749
750#define pn1_imasks (gf0_imask(0) | gf1_imask(0) | vsync_imask(0) | \
751 display_done_imask(0) | vf0_imask(0) | vf1_imask(0))
752#define tv_imasks (gf0_imask(1) | gf1_imask(1) | vsync_imask(1) | \
753 display_done_imask(1) | vf0_imask(1) | vf1_imask(1))
754#define path_imasks(id) ((id) ? (tv_imasks) : (pn1_imasks))
755
756/* error indications */
757#define vid_udflow_imask(id) ((id) ? (((id) & 1) ? \
758 (TV_DMA_FF_UNDERFLOW_ENA_MASK) : (PN2_DMA_FF_UNDERFLOW_ENA_MASK)) : \
759 (DMA_FF_UNDERFLOW_ENA_MASK))
760#define gfx_udflow_imask(id) ((id) ? (((id) & 1) ? \
761 (TV_GRA_FF_UNDERFLOW_ENA_MASK) : (PN2_GRA_FF_UNDERFLOW_ENA_MASK)) : \
762 (GRA_FF_UNDERFLOW_ENA_MASK))
763
764#define err_imask(id) (vid_udflow_imask(id) | gfx_udflow_imask(id) | \
765 AXI_BUS_ERROR_IRQ_ENA_MASK | AXI_LATENCY_TOO_LONG_IRQ_ENA_MASK)
766#define err_imasks (err_imask(0) | err_imask(1) | err_imask(2))
767/* LCD Interrupt Status Register */
768#define SPU_IRQ_ISR 0x01C4
769#define DMA_FRAME_IRQ0(irq) ((irq)<<31)
770#define DMA_FRAME_IRQ0_MASK 0x80000000
771#define DMA_FRAME_IRQ1(irq) ((irq)<<30)
772#define DMA_FRAME_IRQ1_MASK 0x40000000
773#define DMA_FF_UNDERFLOW(ff) ((ff)<<29)
774#define DMA_FF_UNDERFLOW_MASK 0x20000000
775#define AXI_BUS_ERROR_IRQ(irq) ((irq)<<28)
776#define AXI_BUS_ERROR_IRQ_MASK 0x10000000
777#define GRA_FRAME_IRQ0(irq) ((irq)<<27)
778#define GRA_FRAME_IRQ0_MASK 0x08000000
779#define GRA_FRAME_IRQ1(irq) ((irq)<<26)
780#define GRA_FRAME_IRQ1_MASK 0x04000000
781#define GRA_FF_UNDERFLOW(ff) ((ff)<<25)
782#define GRA_FF_UNDERFLOW_MASK 0x02000000
783#define VSYNC_IRQ(vsync_irq) ((vsync_irq)<<23)
784#define VSYNC_IRQ_MASK 0x00800000
785#define DUMB_FRAMEDONE(fdone) ((fdone)<<22)
786#define DUMB_FRAMEDONE_MASK 0x00400000
787#define TWC_FRAMEDONE(fdone) ((fdone)<<21)
788#define TWC_FRAMEDONE_MASK 0x00200000
789#define HWC_FRAMEDONE(fdone) ((fdone)<<20)
790#define HWC_FRAMEDONE_MASK 0x00100000
791#define SLV_IRQ(irq) ((irq)<<19)
792#define SLV_IRQ_MASK 0x00080000
793#define SPI_IRQ(irq) ((irq)<<18)
794#define SPI_IRQ_MASK 0x00040000
795#define PWRDN_IRQ(irq) ((irq)<<17)
796#define PWRDN_IRQ_MASK 0x00020000
797#define AXI_LATENCY_TOO_LONGR_IRQ(irq) ((irq)<<16)
798#define AXI_LATENCY_TOO_LONGR_IRQ_MASK 0x00010000
799#define TV_DMA_FRAME_IRQ0(irq) ((irq)<<15)
800#define TV_DMA_FRAME_IRQ0_MASK 0x00008000
801#define TV_DMA_FRAME_IRQ1(irq) ((irq)<<14)
802#define TV_DMA_FRAME_IRQ1_MASK 0x00004000
803#define TV_DMA_FF_UNDERFLOW(unerrun) ((unerrun)<<13)
804#define TV_DMA_FF_UNDERFLOW_MASK 0x00002000
805#define TVSYNC_IRQ(irq) ((irq)<<12)
806#define TVSYNC_IRQ_MASK 0x00001000
807#define TV_FRAME_IRQ0(irq) ((irq)<<11)
808#define TV_FRAME_IRQ0_MASK 0x00000800
809#define TV_FRAME_IRQ1(irq) ((irq)<<10)
810#define TV_FRAME_IRQ1_MASK 0x00000400
811#define TV_GRA_FF_UNDERFLOW(unerrun) ((unerrun)<<9)
812#define TV_GRA_FF_UNDERFLOW_MASK 0x00000200
813#define PN2_DMA_FRAME_IRQ0(irq) ((irq)<<7)
814#define PN2_DMA_FRAME_IRQ0_MASK 0x00000080
815#define PN2_DMA_FRAME_IRQ1(irq) ((irq)<<6)
816#define PN2_DMA_FRAME_IRQ1_MASK 0x00000040
817#define PN2_DMA_FF_UNDERFLOW(ff) ((ff)<<5)
818#define PN2_DMA_FF_UNDERFLOW_MASK 0x00000020
819#define PN2_GRA_FRAME_IRQ0(irq) ((irq)<<3)
820#define PN2_GRA_FRAME_IRQ0_MASK 0x00000008
821#define PN2_GRA_FRAME_IRQ1(irq) ((irq)<<2)
822#define PN2_GRA_FRAME_IRQ1_MASK 0x04000004
823#define PN2_GRA_FF_UNDERFLOW(ff) ((ff)<<1)
824#define PN2_GRA_FF_UNDERFLOW_MASK 0x00000002
825#define PN2_VSYNC_IRQ(irq) ((irq)<<0)
826#define PN2_SYNC_IRQ_MASK 0x00000001
827
828/* LCD FIFO Depth register */
829#define LCD_FIFO_DEPTH 0x01c8
830#define VIDEO_FIFO(fi) ((fi) << 0)
831#define VIDEO_FIFO_MASK 0x00000003
832#define GRAPHIC_FIFO(fi) ((fi) << 2)
833#define GRAPHIC_FIFO_MASK 0x0000000c
834
835/* read-only */
836#define DMA_FRAME_IRQ0_LEVEL_MASK 0x00008000
837#define DMA_FRAME_IRQ1_LEVEL_MASK 0x00004000
838#define DMA_FRAME_CNT_ISR_MASK 0x00003000
839#define GRA_FRAME_IRQ0_LEVEL_MASK 0x00000800
840#define GRA_FRAME_IRQ1_LEVEL_MASK 0x00000400
841#define GRA_FRAME_CNT_ISR_MASK 0x00000300
842#define VSYNC_IRQ_LEVEL_MASK 0x00000080
843#define DUMB_FRAMEDONE_LEVEL_MASK 0x00000040
844#define TWC_FRAMEDONE_LEVEL_MASK 0x00000020
845#define HWC_FRAMEDONE_LEVEL_MASK 0x00000010
846#define SLV_FF_EMPTY_MASK 0x00000008
847#define DMA_FF_ALLEMPTY_MASK 0x00000004
848#define GRA_FF_ALLEMPTY_MASK 0x00000002
849#define PWRDN_IRQ_LEVEL_MASK 0x00000001
850
851/* 32 bit LCD Interrupt Reset Status*/
852#define SPU_IRQ_RSR (0x01C8)
853/* 32 bit Panel Path Graphic Partial Display Horizontal Control Register*/
854#define LCD_GRA_CUTHPXL (0x01CC)
855/* 32 bit Panel Path Graphic Partial Display Vertical Control Register*/
856#define LCD_GRA_CUTVLN (0x01D0)
857/* 32 bit TV Path Graphic Partial Display Horizontal Control Register*/
858#define LCD_TVG_CUTHPXL (0x01D4)
859/* 32 bit TV Path Graphic Partial Display Vertical Control Register*/
860#define LCD_TVG_CUTVLN (0x01D8)
861/* 32 bit LCD Global Control Register*/
862#define LCD_TOP_CTRL (0x01DC)
863/* 32 bit LCD SQU Line Buffer Control Register 1*/
864#define LCD_SQULN1_CTRL (0x01E0)
865/* 32 bit LCD SQU Line Buffer Control Register 2*/
866#define LCD_SQULN2_CTRL (0x01E4)
867#define squln_ctrl(id) ((id) ? (((id) & 1) ? LCD_SQULN2_CTRL : \
868 LCD_PN2_SQULN1_CTRL) : LCD_SQULN1_CTRL)
869
870/* 32 bit LCD Mixed Overlay Control Register */
871#define LCD_AFA_ALL2ONE (0x01E8)
872
873#define LCD_PN2_SCLK_DIV (0x01EC)
874#define LCD_PN2_TCLK_DIV (0x01F0)
875#define LCD_LVDS_SCLK_DIV_WR (0x01F4)
876#define LCD_LVDS_SCLK_DIV_RD (0x01FC)
877#define PN2_LCD_DMA_START_ADDR_Y0 (0x0200)
878#define PN2_LCD_DMA_START_ADDR_U0 (0x0204)
879#define PN2_LCD_DMA_START_ADDR_V0 (0x0208)
880#define PN2_LCD_DMA_START_ADDR_C0 (0x020C)
881#define PN2_LCD_DMA_START_ADDR_Y1 (0x0210)
882#define PN2_LCD_DMA_START_ADDR_U1 (0x0214)
883#define PN2_LCD_DMA_START_ADDR_V1 (0x0218)
884#define PN2_LCD_DMA_START_ADDR_C1 (0x021C)
885#define PN2_LCD_DMA_PITCH_YC (0x0220)
886#define PN2_LCD_DMA_PITCH_UV (0x0224)
887#define PN2_LCD_DMA_OVSA_HPXL_VLN (0x0228)
888#define PN2_LCD_DMA_HPXL_VLN (0x022C)
889#define PN2_LCD_DMAZM_HPXL_VLN (0x0230)
890#define PN2_LCD_GRA_START_ADDR0 (0x0234)
891#define PN2_LCD_GRA_START_ADDR1 (0x0238)
892#define PN2_LCD_GRA_PITCH (0x023C)
893#define PN2_LCD_GRA_OVSA_HPXL_VLN (0x0240)
894#define PN2_LCD_GRA_HPXL_VLN (0x0244)
895#define PN2_LCD_GRAZM_HPXL_VLN (0x0248)
896#define PN2_LCD_HWC_OVSA_HPXL_VLN (0x024C)
897#define PN2_LCD_HWC_HPXL_VLN (0x0250)
898#define LCD_PN2_V_H_TOTAL (0x0254)
899#define LCD_PN2_V_H_ACTIVE (0x0258)
900#define LCD_PN2_H_PORCH (0x025C)
901#define LCD_PN2_V_PORCH (0x0260)
902#define LCD_PN2_BLANKCOLOR (0x0264)
903#define LCD_PN2_ALPHA_COLOR1 (0x0268)
904#define LCD_PN2_ALPHA_COLOR2 (0x026C)
905#define LCD_PN2_COLORKEY_Y (0x0270)
906#define LCD_PN2_COLORKEY_U (0x0274)
907#define LCD_PN2_COLORKEY_V (0x0278)
908#define LCD_PN2_SEPXLCNT (0x027C)
909#define LCD_TV_V_H_TOTAL_FLD (0x0280)
910#define LCD_TV_V_PORCH_FLD (0x0284)
911#define LCD_TV_SEPXLCNT_FLD (0x0288)
912
913#define LCD_2ND_ALPHA (0x0294)
914#define LCD_PN2_CONTRAST (0x0298)
915#define LCD_PN2_SATURATION (0x029c)
916#define LCD_PN2_CBSH_HUE (0x02a0)
917#define LCD_TIMING_EXT (0x02C0)
918#define LCD_PN2_LAYER_ALPHA_SEL1 (0x02c4)
919#define LCD_PN2_CTRL0 (0x02C8)
920#define TV_LAYER_ALPHA_SEL1 (0x02cc)
921#define LCD_SMPN2_CTRL (0x02D0)
922#define LCD_IO_OVERL_MAP_CTRL (0x02D4)
923#define LCD_DUMB2_CTRL (0x02d8)
924#define LCD_PN2_CTRL1 (0x02DC)
925#define PN2_IOPAD_CONTROL (0x02E0)
926#define LCD_PN2_SQULN1_CTRL (0x02E4)
927#define PN2_LCD_GRA_CUTHPXL (0x02e8)
928#define PN2_LCD_GRA_CUTVLN (0x02ec)
929#define LCD_PN2_SQULN2_CTRL (0x02F0)
930#define ALL_LAYER_ALPHA_SEL (0x02F4)
931
932/* pxa988 has different MASTER_CTRL from MMP3/MMP2 */
933#ifdef CONFIG_CPU_PXA988
934#define TIMING_MASTER_CONTROL (0x01F4)
935#define MASTER_ENH(id) (1 << ((id) + 5))
936#define MASTER_ENV(id) (1 << ((id) + 6))
937#else
938#define TIMING_MASTER_CONTROL (0x02F8)
939#define MASTER_ENH(id) (1 << (id))
940#define MASTER_ENV(id) (1 << ((id) + 4))
941#endif
942
943#define DSI_START_SEL_SHIFT(id) (((id) << 1) + 8)
944#define timing_master_config(path, dsi_id, lcd_id) \
945 (MASTER_ENH(path) | MASTER_ENV(path) | \
946 (((lcd_id) + ((dsi_id) << 1)) << DSI_START_SEL_SHIFT(path)))
947
948#define LCD_2ND_BLD_CTL (0x02Fc)
949#define LVDS_SRC_MASK (3 << 30)
950#define LVDS_SRC_SHIFT (30)
951#define LVDS_FMT_MASK (1 << 28)
952#define LVDS_FMT_SHIFT (28)
953
954#define CLK_SCLK (1 << 0)
955#define CLK_LVDS_RD (1 << 1)
956#define CLK_LVDS_WR (1 << 2)
957
958#define gra_partdisp_ctrl_hor(id) ((id) ? (((id) & 1) ? \
959 LCD_TVG_CUTHPXL : PN2_LCD_GRA_CUTHPXL) : LCD_GRA_CUTHPXL)
960#define gra_partdisp_ctrl_ver(id) ((id) ? (((id) & 1) ? \
961 LCD_TVG_CUTVLN : PN2_LCD_GRA_CUTVLN) : LCD_GRA_CUTVLN)
962
963/*
964 * defined Video Memory Color format for DMA control 0 register
965 * DMA0 bit[23:20]
966 */
967#define VMODE_RGB565 0x0
968#define VMODE_RGB1555 0x1
969#define VMODE_RGB888PACKED 0x2
970#define VMODE_RGB888UNPACKED 0x3
971#define VMODE_RGBA888 0x4
972#define VMODE_YUV422PACKED 0x5
973#define VMODE_YUV422PLANAR 0x6
974#define VMODE_YUV420PLANAR 0x7
975#define VMODE_SMPNCMD 0x8
976#define VMODE_PALETTE4BIT 0x9
977#define VMODE_PALETTE8BIT 0xa
978#define VMODE_RESERVED 0xb
979
980/*
981 * defined Graphic Memory Color format for DMA control 0 register
982 * DMA0 bit[19:16]
983 */
984#define GMODE_RGB565 0x0
985#define GMODE_RGB1555 0x1
986#define GMODE_RGB888PACKED 0x2
987#define GMODE_RGB888UNPACKED 0x3
988#define GMODE_RGBA888 0x4
989#define GMODE_YUV422PACKED 0x5
990#define GMODE_YUV422PLANAR 0x6
991#define GMODE_YUV420PLANAR 0x7
992#define GMODE_SMPNCMD 0x8
993#define GMODE_PALETTE4BIT 0x9
994#define GMODE_PALETTE8BIT 0xa
995#define GMODE_RESERVED 0xb
996
997/*
998 * define for DMA control 1 register
999 */
1000#define DMA1_FRAME_TRIG 31 /* bit location */
1001#define DMA1_VSYNC_MODE 28
1002#define DMA1_VSYNC_INV 27
1003#define DMA1_CKEY 24
1004#define DMA1_CARRY 23
1005#define DMA1_LNBUF_ENA 22
1006#define DMA1_GATED_ENA 21
1007#define DMA1_PWRDN_ENA 20
1008#define DMA1_DSCALE 18
1009#define DMA1_ALPHA_MODE 16
1010#define DMA1_ALPHA 08
1011#define DMA1_PXLCMD 00
1012
1013/*
1014 * defined for Configure Dumb Mode
1015 * DUMB LCD Panel bit[31:28]
1016 */
1017#define DUMB16_RGB565_0 0x0
1018#define DUMB16_RGB565_1 0x1
1019#define DUMB18_RGB666_0 0x2
1020#define DUMB18_RGB666_1 0x3
1021#define DUMB12_RGB444_0 0x4
1022#define DUMB12_RGB444_1 0x5
1023#define DUMB24_RGB888_0 0x6
1024#define DUMB_BLANK 0x7
1025
1026/*
1027 * defined for Configure I/O Pin Allocation Mode
1028 * LCD LCD I/O Pads control register bit[3:0]
1029 */
1030#define IOPAD_DUMB24 0x0
1031#define IOPAD_DUMB18SPI 0x1
1032#define IOPAD_DUMB18GPIO 0x2
1033#define IOPAD_DUMB16SPI 0x3
1034#define IOPAD_DUMB16GPIO 0x4
1035#define IOPAD_DUMB12 0x5
1036#define IOPAD_SMART18SPI 0x6
1037#define IOPAD_SMART16SPI 0x7
1038#define IOPAD_SMART8BOTH 0x8
1039#define IOPAD_DUMB18_SMART8 0x9
1040#define IOPAD_DUMB16_SMART8SPI 0xa
1041#define IOPAD_DUMB16_SMART8GPIO 0xb
1042#define IOPAD_DUMB16_DUMB16 0xc
1043#define IOPAD_SMART8_SMART8 0xc
1044
1045/*
1046 *defined for indicating boundary and cycle burst length
1047 */
1048#define CFG_BOUNDARY_1KB (1<<5)
1049#define CFG_BOUNDARY_4KB (0<<5)
1050#define CFG_CYC_BURST_LEN16 (1<<4)
1051#define CFG_CYC_BURST_LEN8 (0<<4)
1052
1053/*
1054 * defined Dumb Panel Clock Divider register
1055 * SCLK_Source bit[31]
1056 */
1057 /* 0: PLL clock select*/
1058#define AXI_BUS_SEL 0x80000000
1059#define CCD_CLK_SEL 0x40000000
1060#define DCON_CLK_SEL 0x20000000
1061#define ENA_CLK_INT_DIV CONFIG_FB_DOVE_CLCD_SCLK_DIV
1062#define IDLE_CLK_INT_DIV 0x1 /* idle Integer Divider */
1063#define DIS_CLK_INT_DIV 0x0 /* Disable Integer Divider */
1064
1065/* SRAM ID */
1066#define SRAMID_GAMMA_YR 0x0
1067#define SRAMID_GAMMA_UG 0x1
1068#define SRAMID_GAMMA_VB 0x2
1069#define SRAMID_PALATTE 0x3
1070#define SRAMID_HWC 0xf
1071
1072/* SRAM INIT Read/Write */
1073#define SRAMID_INIT_READ 0x0
1074#define SRAMID_INIT_WRITE 0x2
1075#define SRAMID_INIT_DEFAULT 0x3
1076
1077/*
1078 * defined VSYNC selection mode for DMA control 1 register
1079 * DMA1 bit[30:28]
1080 */
1081#define VMODE_SMPN 0x0
1082#define VMODE_SMPNIRQ 0x1
1083#define VMODE_DUMB 0x2
1084#define VMODE_IPE 0x3
1085#define VMODE_IRE 0x4
1086
1087/*
1088 * defined Configure Alpha and Alpha mode for DMA control 1 register
1089 * DMA1 bit[15:08](alpha) / bit[17:16](alpha mode)
1090 */
1091/* ALPHA mode */
1092#define MODE_ALPHA_DMA 0x0
1093#define MODE_ALPHA_GRA 0x1
1094#define MODE_ALPHA_CFG 0x2
1095
1096/* alpha value */
1097#define ALPHA_NOGRAPHIC 0xFF /* all video, no graphic */
1098#define ALPHA_NOVIDEO 0x00 /* all graphic, no video */
1099#define ALPHA_GRAPHNVIDEO 0x0F /* Selects graphic & video */
1100
1101/*
1102 * defined Pixel Command for DMA control 1 register
1103 * DMA1 bit[07:00]
1104 */
1105#define PIXEL_CMD 0x81
1106
1107/* DSI */
1108/* DSI1 - 4 Lane Controller base */
1109#define DSI1_REGS_PHYSICAL_BASE 0xD420B800
1110/* DSI2 - 3 Lane Controller base */
1111#define DSI2_REGS_PHYSICAL_BASE 0xD420BA00
1112
1113/* DSI Controller Registers */
1114struct dsi_lcd_regs {
1115#define DSI_LCD1_CTRL_0 0x100 /* DSI Active Panel 1 Control register 0 */
1116#define DSI_LCD1_CTRL_1 0x104 /* DSI Active Panel 1 Control register 1 */
1117 u32 ctrl0;
1118 u32 ctrl1;
1119 u32 reserved1[2];
1120
1121#define DSI_LCD1_TIMING_0 0x110 /* Timing register 0 */
1122#define DSI_LCD1_TIMING_1 0x114 /* Timing register 1 */
1123#define DSI_LCD1_TIMING_2 0x118 /* Timing register 2 */
1124#define DSI_LCD1_TIMING_3 0x11C /* Timing register 3 */
1125#define DSI_LCD1_WC_0 0x120 /* Word Count register 0 */
1126#define DSI_LCD1_WC_1 0x124 /* Word Count register 1 */
1127#define DSI_LCD1_WC_2 0x128 /* Word Count register 2 */
1128 u32 timing0;
1129 u32 timing1;
1130 u32 timing2;
1131 u32 timing3;
1132 u32 wc0;
1133 u32 wc1;
1134 u32 wc2;
1135 u32 reserved2[1];
1136 u32 slot_cnt0;
1137 u32 slot_cnt1;
1138 u32 reserved3[2];
1139 u32 status_0;
1140 u32 status_1;
1141 u32 status_2;
1142 u32 status_3;
1143 u32 status_4;
1144};
1145
1146struct dsi_regs {
1147#define DSI_CTRL_0 0x000 /* DSI control register 0 */
1148#define DSI_CTRL_1 0x004 /* DSI control register 1 */
1149 u32 ctrl0;
1150 u32 ctrl1;
1151 u32 reserved1[2];
1152 u32 irq_status;
1153 u32 irq_mask;
1154 u32 reserved2[2];
1155
1156#define DSI_CPU_CMD_0 0x020 /* DSI CPU packet command register 0 */
1157#define DSI_CPU_CMD_1 0x024 /* DSU CPU Packet Command Register 1 */
1158#define DSI_CPU_CMD_3 0x02C /* DSU CPU Packet Command Register 3 */
1159#define DSI_CPU_WDAT_0 0x030 /* DSI CUP */
1160 u32 cmd0;
1161 u32 cmd1;
1162 u32 cmd2;
1163 u32 cmd3;
1164 u32 dat0;
1165 u32 status0;
1166 u32 status1;
1167 u32 status2;
1168 u32 status3;
1169 u32 status4;
1170 u32 reserved3[2];
1171
1172 u32 smt_cmd;
1173 u32 smt_ctrl0;
1174 u32 smt_ctrl1;
1175 u32 reserved4[1];
1176
1177 u32 rx0_status;
1178
1179/* Rx Packet Header - data from slave device */
1180#define DSI_RX_PKT_HDR_0 0x064
1181 u32 rx0_header;
1182 u32 rx1_status;
1183 u32 rx1_header;
1184 u32 rx_ctrl;
1185 u32 rx_ctrl1;
1186 u32 rx2_status;
1187 u32 rx2_header;
1188 u32 reserved5[1];
1189
1190 u32 phy_ctrl1;
1191#define DSI_PHY_CTRL_2 0x088 /* DSI DPHI Control Register 2 */
1192#define DSI_PHY_CTRL_3 0x08C /* DPHY Control Register 3 */
1193 u32 phy_ctrl2;
1194 u32 phy_ctrl3;
1195 u32 phy_status0;
1196 u32 phy_status1;
1197 u32 reserved6[5];
1198 u32 phy_status2;
1199
1200#define DSI_PHY_RCOMP_0 0x0B0 /* DPHY Rcomp Control Register */
1201 u32 phy_rcomp0;
1202 u32 reserved7[3];
1203#define DSI_PHY_TIME_0 0x0C0 /* DPHY Timing Control Register 0 */
1204#define DSI_PHY_TIME_1 0x0C4 /* DPHY Timing Control Register 1 */
1205#define DSI_PHY_TIME_2 0x0C8 /* DPHY Timing Control Register 2 */
1206#define DSI_PHY_TIME_3 0x0CC /* DPHY Timing Control Register 3 */
1207#define DSI_PHY_TIME_4 0x0D0 /* DPHY Timing Control Register 4 */
1208#define DSI_PHY_TIME_5 0x0D4 /* DPHY Timing Control Register 5 */
1209 u32 phy_timing0;
1210 u32 phy_timing1;
1211 u32 phy_timing2;
1212 u32 phy_timing3;
1213 u32 phy_code_0;
1214 u32 phy_code_1;
1215 u32 reserved8[2];
1216 u32 mem_ctrl;
1217 u32 tx_timer;
1218 u32 rx_timer;
1219 u32 turn_timer;
1220 u32 reserved9[4];
1221
1222#define DSI_LCD1_CTRL_0 0x100 /* DSI Active Panel 1 Control register 0 */
1223#define DSI_LCD1_CTRL_1 0x104 /* DSI Active Panel 1 Control register 1 */
1224#define DSI_LCD1_TIMING_0 0x110 /* Timing register 0 */
1225#define DSI_LCD1_TIMING_1 0x114 /* Timing register 1 */
1226#define DSI_LCD1_TIMING_2 0x118 /* Timing register 2 */
1227#define DSI_LCD1_TIMING_3 0x11C /* Timing register 3 */
1228#define DSI_LCD1_WC_0 0x120 /* Word Count register 0 */
1229#define DSI_LCD1_WC_1 0x124 /* Word Count register 1 */
1230#define DSI_LCD1_WC_2 0x128 /* Word Count register 2 */
1231 struct dsi_lcd_regs lcd1;
1232 u32 reserved10[11];
1233 struct dsi_lcd_regs lcd2;
1234};
1235
1236#define DSI_LCD2_CTRL_0 0x180 /* DSI Active Panel 2 Control register 0 */
1237#define DSI_LCD2_CTRL_1 0x184 /* DSI Active Panel 2 Control register 1 */
1238#define DSI_LCD2_TIMING_0 0x190 /* Timing register 0 */
1239#define DSI_LCD2_TIMING_1 0x194 /* Timing register 1 */
1240#define DSI_LCD2_TIMING_2 0x198 /* Timing register 2 */
1241#define DSI_LCD2_TIMING_3 0x19C /* Timing register 3 */
1242#define DSI_LCD2_WC_0 0x1A0 /* Word Count register 0 */
1243#define DSI_LCD2_WC_1 0x1A4 /* Word Count register 1 */
1244#define DSI_LCD2_WC_2 0x1A8 /* Word Count register 2 */
1245
1246/* DSI_CTRL_0 0x0000 DSI Control Register 0 */
1247#define DSI_CTRL_0_CFG_SOFT_RST (1<<31)
1248#define DSI_CTRL_0_CFG_SOFT_RST_REG (1<<30)
1249#define DSI_CTRL_0_CFG_LCD1_TX_EN (1<<8)
1250#define DSI_CTRL_0_CFG_LCD1_SLV (1<<4)
1251#define DSI_CTRL_0_CFG_LCD1_EN (1<<0)
1252
1253/* DSI_CTRL_1 0x0004 DSI Control Register 1 */
1254#define DSI_CTRL_1_CFG_EOTP (1<<8)
1255#define DSI_CTRL_1_CFG_RSVD (2<<4)
1256#define DSI_CTRL_1_CFG_LCD2_VCH_NO_MASK (3<<2)
1257#define DSI_CTRL_1_CFG_LCD2_VCH_NO_SHIFT 2
1258#define DSI_CTRL_1_CFG_LCD1_VCH_NO_MASK (3<<0)
1259#define DSI_CTRL_1_CFG_LCD1_VCH_NO_SHIFT 0
1260
1261/* DSI_LCD1_CTRL_1 0x0104 DSI Active Panel 1 Control Register 1 */
1262/* LCD 1 Vsync Reset Enable */
1263#define DSI_LCD1_CTRL_1_CFG_L1_VSYNC_RST_EN (1<<31)
1264/* LCD 1 2K Pixel Buffer Mode Enable */
1265#define DSI_LCD1_CTRL_1_CFG_L1_M2K_EN (1<<30)
1266/* Bit(s) DSI_LCD1_CTRL_1_RSRV_29_23 reserved */
1267/* Long Blanking Packet Enable */
1268#define DSI_LCD1_CTRL_1_CFG_L1_HLP_PKT_EN (1<<22)
1269/* Extra Long Blanking Packet Enable */
1270#define DSI_LCD1_CTRL_1_CFG_L1_HEX_PKT_EN (1<<21)
1271/* Front Porch Packet Enable */
1272#define DSI_LCD1_CTRL_1_CFG_L1_HFP_PKT_EN (1<<20)
1273/* hact Packet Enable */
1274#define DSI_LCD1_CTRL_1_CFG_L1_HACT_PKT_EN (1<<19)
1275/* Back Porch Packet Enable */
1276#define DSI_LCD1_CTRL_1_CFG_L1_HBP_PKT_EN (1<<18)
1277/* hse Packet Enable */
1278#define DSI_LCD1_CTRL_1_CFG_L1_HSE_PKT_EN (1<<17)
1279/* hsa Packet Enable */
1280#define DSI_LCD1_CTRL_1_CFG_L1_HSA_PKT_EN (1<<16)
1281/* All Item Enable after Pixel Data */
1282#define DSI_LCD1_CTRL_1_CFG_L1_ALL_SLOT_EN (1<<15)
1283/* Extra Long Packet Enable after Pixel Data */
1284#define DSI_LCD1_CTRL_1_CFG_L1_HEX_SLOT_EN (1<<14)
1285/* Bit(s) DSI_LCD1_CTRL_1_RSRV_13_11 reserved */
1286/* Turn Around Bus at Last h Line */
1287#define DSI_LCD1_CTRL_1_CFG_L1_LAST_LINE_TURN (1<<10)
1288/* Go to Low Power Every Frame */
1289#define DSI_LCD1_CTRL_1_CFG_L1_LPM_FRAME_EN (1<<9)
1290/* Go to Low Power Every Line */
1291#define DSI_LCD1_CTRL_1_CFG_L1_LPM_LINE_EN (1<<8)
1292/* Bit(s) DSI_LCD1_CTRL_1_RSRV_7_4 reserved */
1293/* DSI Transmission Mode for LCD 1 */
1294#define DSI_LCD1_CTRL_1_CFG_L1_BURST_MODE_SHIFT 2
1295#define DSI_LCD1_CTRL_1_CFG_L1_BURST_MODE_MASK (3<<2)
1296/* LCD 1 Input Data RGB Mode for LCD 1 */
1297#define DSI_LCD2_CTRL_1_CFG_L1_RGB_TYPE_SHIFT 0
1298#define DSI_LCD2_CTRL_1_CFG_L1_RGB_TYPE_MASK (3<<2)
1299
1300/* DSI_PHY_CTRL_2 0x0088 DPHY Control Register 2 */
1301/* Bit(s) DSI_PHY_CTRL_2_RSRV_31_12 reserved */
1302/* DPHY LP Receiver Enable */
1303#define DSI_PHY_CTRL_2_CFG_CSR_LANE_RESC_EN_MASK (0xf<<8)
1304#define DSI_PHY_CTRL_2_CFG_CSR_LANE_RESC_EN_SHIFT 8
1305/* DPHY Data Lane Enable */
1306#define DSI_PHY_CTRL_2_CFG_CSR_LANE_EN_MASK (0xf<<4)
1307#define DSI_PHY_CTRL_2_CFG_CSR_LANE_EN_SHIFT 4
1308/* DPHY Bus Turn Around */
1309#define DSI_PHY_CTRL_2_CFG_CSR_LANE_TURN_MASK (0xf)
1310#define DSI_PHY_CTRL_2_CFG_CSR_LANE_TURN_SHIFT 0
1311
1312/* DSI_CPU_CMD_1 0x0024 DSI CPU Packet Command Register 1 */
1313/* Bit(s) DSI_CPU_CMD_1_RSRV_31_24 reserved */
1314/* LPDT TX Enable */
1315#define DSI_CPU_CMD_1_CFG_TXLP_LPDT_MASK (0xf<<20)
1316#define DSI_CPU_CMD_1_CFG_TXLP_LPDT_SHIFT 20
1317/* ULPS TX Enable */
1318#define DSI_CPU_CMD_1_CFG_TXLP_ULPS_MASK (0xf<<16)
1319#define DSI_CPU_CMD_1_CFG_TXLP_ULPS_SHIFT 16
1320/* Low Power TX Trigger Code */
1321#define DSI_CPU_CMD_1_CFG_TXLP_TRIGGER_CODE_MASK (0xffff)
1322#define DSI_CPU_CMD_1_CFG_TXLP_TRIGGER_CODE_SHIFT 0
1323
1324/* DSI_PHY_TIME_0 0x00c0 DPHY Timing Control Register 0 */
1325/* Length of HS Exit Period in tx_clk_esc Cycles */
1326#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_EXIT_MASK (0xff<<24)
1327#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_EXIT_SHIFT 24
1328/* DPHY HS Trail Period Length */
1329#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_TRAIL_MASK (0xff<<16)
1330#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_TRAIL_SHIFT 16
1331/* DPHY HS Zero State Length */
1332#define DSI_PHY_TIME_0_CDG_CSR_TIME_HS_ZERO_MASK (0xff<<8)
1333#define DSI_PHY_TIME_0_CDG_CSR_TIME_HS_ZERO_SHIFT 8
1334/* DPHY HS Prepare State Length */
1335#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_PREP_MASK (0xff)
1336#define DSI_PHY_TIME_0_CFG_CSR_TIME_HS_PREP_SHIFT 0
1337
1338/* DSI_PHY_TIME_1 0x00c4 DPHY Timing Control Register 1 */
1339/* Time to Drive LP-00 by New Transmitter */
1340#define DSI_PHY_TIME_1_CFG_CSR_TIME_TA_GET_MASK (0xff<<24)
1341#define DSI_PHY_TIME_1_CFG_CSR_TIME_TA_GET_SHIFT 24
1342/* Time to Drive LP-00 after Turn Request */
1343#define DSI_PHY_TIME_1_CFG_CSR_TIME_TA_GO_MASK (0xff<<16)
1344#define DSI_PHY_TIME_1_CFG_CSR_TIME_TA_GO_SHIFT 16
1345/* DPHY HS Wakeup Period Length */
1346#define DSI_PHY_TIME_1_CFG_CSR_TIME_WAKEUP_MASK (0xffff)
1347#define DSI_PHY_TIME_1_CFG_CSR_TIME_WAKEUP_SHIFT 0
1348
1349/* DSI_PHY_TIME_2 0x00c8 DPHY Timing Control Register 2 */
1350/* DPHY CLK Exit Period Length */
1351#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_EXIT_MASK (0xff<<24)
1352#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_EXIT_SHIFT 24
1353/* DPHY CLK Trail Period Length */
1354#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_TRAIL_MASK (0xff<<16)
1355#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_TRAIL_SHIFT 16
1356/* DPHY CLK Zero State Length */
1357#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_ZERO_MASK (0xff<<8)
1358#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_ZERO_SHIFT 8
1359/* DPHY CLK LP Length */
1360#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_LPX_MASK (0xff)
1361#define DSI_PHY_TIME_2_CFG_CSR_TIME_CK_LPX_SHIFT 0
1362
1363/* DSI_PHY_TIME_3 0x00cc DPHY Timing Control Register 3 */
1364/* Bit(s) DSI_PHY_TIME_3_RSRV_31_16 reserved */
1365/* DPHY LP Length */
1366#define DSI_PHY_TIME_3_CFG_CSR_TIME_LPX_MASK (0xff<<8)
1367#define DSI_PHY_TIME_3_CFG_CSR_TIME_LPX_SHIFT 8
1368/* DPHY HS req to rdy Length */
1369#define DSI_PHY_TIME_3_CFG_CSR_TIME_REQRDY_MASK (0xff)
1370#define DSI_PHY_TIME_3_CFG_CSR_TIME_REQRDY_SHIFT 0
1371
1372/*
1373 * DSI timings
1374 * PXA988 has diffrent ESC CLK with MMP2/MMP3
1375 * it will be used in dsi_set_dphy() in pxa688_phy.c
1376 * as low power mode clock.
1377 */
1378#ifdef CONFIG_CPU_PXA988
1379#define DSI_ESC_CLK 52 /* Unit: Mhz */
1380#define DSI_ESC_CLK_T 19 /* Unit: ns */
1381#else
1382#define DSI_ESC_CLK 66 /* Unit: Mhz */
1383#define DSI_ESC_CLK_T 15 /* Unit: ns */
1384#endif
1385
1386/* LVDS */
1387/* LVDS_PHY_CTRL */
1388#define LVDS_PHY_CTL 0x2A4
1389#define LVDS_PLL_LOCK (1 << 31)
1390#define LVDS_PHY_EXT_MASK (7 << 28)
1391#define LVDS_PHY_EXT_SHIFT (28)
1392#define LVDS_CLK_PHASE_MASK (0x7f << 16)
1393#define LVDS_CLK_PHASE_SHIFT (16)
1394#define LVDS_SSC_RESET_EXT (1 << 13)
1395#define LVDS_SSC_MODE_DOWN_SPREAD (1 << 12)
1396#define LVDS_SSC_EN (1 << 11)
1397#define LVDS_PU_PLL (1 << 10)
1398#define LVDS_PU_TX (1 << 9)
1399#define LVDS_PU_IVREF (1 << 8)
1400#define LVDS_CLK_SEL (1 << 7)
1401#define LVDS_CLK_SEL_LVDS_PCLK (1 << 7)
1402#define LVDS_PD_CH_MASK (0x3f << 1)
1403#define LVDS_PD_CH(ch) ((ch) << 1)
1404#define LVDS_RST (1 << 0)
1405
1406#define LVDS_PHY_CTL_EXT 0x2A8
1407
1408/* LVDS_PHY_CTRL_EXT1 */
1409#define LVDS_SSC_RNGE_MASK (0x7ff << 16)
1410#define LVDS_SSC_RNGE_SHIFT (16)
1411#define LVDS_RESERVE_IN_MASK (0xf << 12)
1412#define LVDS_RESERVE_IN_SHIFT (12)
1413#define LVDS_TEST_MON_MASK (0x7 << 8)
1414#define LVDS_TEST_MON_SHIFT (8)
1415#define LVDS_POL_SWAP_MASK (0x3f << 0)
1416#define LVDS_POL_SWAP_SHIFT (0)
1417
1418/* LVDS_PHY_CTRL_EXT2 */
1419#define LVDS_TX_DIF_AMP_MASK (0xf << 24)
1420#define LVDS_TX_DIF_AMP_SHIFT (24)
1421#define LVDS_TX_DIF_CM_MASK (0x3 << 22)
1422#define LVDS_TX_DIF_CM_SHIFT (22)
1423#define LVDS_SELLV_TXCLK_MASK (0x1f << 16)
1424#define LVDS_SELLV_TXCLK_SHIFT (16)
1425#define LVDS_TX_CMFB_EN (0x1 << 15)
1426#define LVDS_TX_TERM_EN (0x1 << 14)
1427#define LVDS_SELLV_TXDATA_MASK (0x1f << 8)
1428#define LVDS_SELLV_TXDATA_SHIFT (8)
1429#define LVDS_SELLV_OP7_MASK (0x3 << 6)
1430#define LVDS_SELLV_OP7_SHIFT (6)
1431#define LVDS_SELLV_OP6_MASK (0x3 << 4)
1432#define LVDS_SELLV_OP6_SHIFT (4)
1433#define LVDS_SELLV_OP9_MASK (0x3 << 2)
1434#define LVDS_SELLV_OP9_SHIFT (2)
1435#define LVDS_STRESSTST_EN (0x1 << 0)
1436
1437/* LVDS_PHY_CTRL_EXT3 */
1438#define LVDS_KVCO_MASK (0xf << 28)
1439#define LVDS_KVCO_SHIFT (28)
1440#define LVDS_CTUNE_MASK (0x3 << 26)
1441#define LVDS_CTUNE_SHIFT (26)
1442#define LVDS_VREG_IVREF_MASK (0x3 << 24)
1443#define LVDS_VREG_IVREF_SHIFT (24)
1444#define LVDS_VDDL_MASK (0xf << 20)
1445#define LVDS_VDDL_SHIFT (20)
1446#define LVDS_VDDM_MASK (0x3 << 18)
1447#define LVDS_VDDM_SHIFT (18)
1448#define LVDS_FBDIV_MASK (0xf << 8)
1449#define LVDS_FBDIV_SHIFT (8)
1450#define LVDS_REFDIV_MASK (0x7f << 0)
1451#define LVDS_REFDIV_SHIFT (0)
1452
1453/* LVDS_PHY_CTRL_EXT4 */
1454#define LVDS_SSC_FREQ_DIV_MASK (0xffff << 16)
1455#define LVDS_SSC_FREQ_DIV_SHIFT (16)
1456#define LVDS_INTPI_MASK (0xf << 12)
1457#define LVDS_INTPI_SHIFT (12)
1458#define LVDS_VCODIV_SEL_SE_MASK (0xf << 8)
1459#define LVDS_VCODIV_SEL_SE_SHIFT (8)
1460#define LVDS_RESET_INTP_EXT (0x1 << 7)
1461#define LVDS_VCO_VRNG_MASK (0x7 << 4)
1462#define LVDS_VCO_VRNG_SHIFT (4)
1463#define LVDS_PI_EN (0x1 << 3)
1464#define LVDS_ICP_MASK (0x7 << 0)
1465#define LVDS_ICP_SHIFT (0)
1466
1467/* LVDS_PHY_CTRL_EXT5 */
1468#define LVDS_FREQ_OFFSET_MASK (0x1ffff << 15)
1469#define LVDS_FREQ_OFFSET_SHIFT (15)
1470#define LVDS_FREQ_OFFSET_VALID (0x1 << 2)
1471#define LVDS_FREQ_OFFSET_MODE_CK_DIV4_OUT (0x1 << 1)
1472#define LVDS_FREQ_OFFSET_MODE_EN (0x1 << 0)
1473
1474/* VDMA */
1475struct vdma_ch_regs {
1476#define VDMA_DC_SADDR_1 0x320
1477#define VDMA_DC_SADDR_2 0x3A0
1478#define VDMA_DC_SZ_1 0x324
1479#define VDMA_DC_SZ_2 0x3A4
1480#define VDMA_CTRL_1 0x328
1481#define VDMA_CTRL_2 0x3A8
1482#define VDMA_SRC_SZ_1 0x32C
1483#define VDMA_SRC_SZ_2 0x3AC
1484#define VDMA_SA_1 0x330
1485#define VDMA_SA_2 0x3B0
1486#define VDMA_DA_1 0x334
1487#define VDMA_DA_2 0x3B4
1488#define VDMA_SZ_1 0x338
1489#define VDMA_SZ_2 0x3B8
1490 u32 dc_saddr;
1491 u32 dc_size;
1492 u32 ctrl;
1493 u32 src_size;
1494 u32 src_addr;
1495 u32 dst_addr;
1496 u32 dst_size;
1497#define VDMA_PITCH_1 0x33C
1498#define VDMA_PITCH_2 0x3BC
1499#define VDMA_ROT_CTRL_1 0x340
1500#define VDMA_ROT_CTRL_2 0x3C0
1501#define VDMA_RAM_CTRL0_1 0x344
1502#define VDMA_RAM_CTRL0_2 0x3C4
1503#define VDMA_RAM_CTRL1_1 0x348
1504#define VDMA_RAM_CTRL1_2 0x3C8
1505 u32 pitch;
1506 u32 rot_ctrl;
1507 u32 ram_ctrl0;
1508 u32 ram_ctrl1;
1509
1510};
1511struct vdma_regs {
1512#define VDMA_ARBR_CTRL 0x300
1513#define VDMA_IRQR 0x304
1514#define VDMA_IRQM 0x308
1515#define VDMA_IRQS 0x30C
1516#define VDMA_MDMA_ARBR_CTRL 0x310
1517 u32 arbr_ctr;
1518 u32 irq_raw;
1519 u32 irq_mask;
1520 u32 irq_status;
1521 u32 mdma_arbr_ctrl;
1522 u32 reserved[3];
1523
1524 struct vdma_ch_regs ch1;
1525 u32 reserved2[21];
1526 struct vdma_ch_regs ch2;
1527};
1528
1529/* CMU */
1530#define CMU_PIP_DE_H_CFG 0x0008
1531#define CMU_PRI1_H_CFG 0x000C
1532#define CMU_PRI2_H_CFG 0x0010
1533#define CMU_ACE_MAIN_DE1_H_CFG 0x0014
1534#define CMU_ACE_MAIN_DE2_H_CFG 0x0018
1535#define CMU_ACE_PIP_DE1_H_CFG 0x001C
1536#define CMU_ACE_PIP_DE2_H_CFG 0x0020
1537#define CMU_PIP_DE_V_CFG 0x0024
1538#define CMU_PRI_V_CFG 0x0028
1539#define CMU_ACE_MAIN_DE_V_CFG 0x002C
1540#define CMU_ACE_PIP_DE_V_CFG 0x0030
1541#define CMU_BAR_0_CFG 0x0034
1542#define CMU_BAR_1_CFG 0x0038
1543#define CMU_BAR_2_CFG 0x003C
1544#define CMU_BAR_3_CFG 0x0040
1545#define CMU_BAR_4_CFG 0x0044
1546#define CMU_BAR_5_CFG 0x0048
1547#define CMU_BAR_6_CFG 0x004C
1548#define CMU_BAR_7_CFG 0x0050
1549#define CMU_BAR_8_CFG 0x0054
1550#define CMU_BAR_9_CFG 0x0058
1551#define CMU_BAR_10_CFG 0x005C
1552#define CMU_BAR_11_CFG 0x0060
1553#define CMU_BAR_12_CFG 0x0064
1554#define CMU_BAR_13_CFG 0x0068
1555#define CMU_BAR_14_CFG 0x006C
1556#define CMU_BAR_15_CFG 0x0070
1557#define CMU_BAR_CTRL 0x0074
1558#define PATTERN_TOTAL 0x0078
1559#define PATTERN_ACTIVE 0x007C
1560#define PATTERN_FRONT_PORCH 0x0080
1561#define PATTERN_BACK_PORCH 0x0084
1562#define CMU_CLK_CTRL 0x0088
1563
1564#define CMU_ICSC_M_C0_L 0x0900
1565#define CMU_ICSC_M_C0_H 0x0901
1566#define CMU_ICSC_M_C1_L 0x0902
1567#define CMU_ICSC_M_C1_H 0x0903
1568#define CMU_ICSC_M_C2_L 0x0904
1569#define CMU_ICSC_M_C2_H 0x0905
1570#define CMU_ICSC_M_C3_L 0x0906
1571#define CMU_ICSC_M_C3_H 0x0907
1572#define CMU_ICSC_M_C4_L 0x0908
1573#define CMU_ICSC_M_C4_H 0x0909
1574#define CMU_ICSC_M_C5_L 0x090A
1575#define CMU_ICSC_M_C5_H 0x090B
1576#define CMU_ICSC_M_C6_L 0x090C
1577#define CMU_ICSC_M_C6_H 0x090D
1578#define CMU_ICSC_M_C7_L 0x090E
1579#define CMU_ICSC_M_C7_H 0x090F
1580#define CMU_ICSC_M_C8_L 0x0910
1581#define CMU_ICSC_M_C8_H 0x0911
1582#define CMU_ICSC_M_O1_0 0x0914
1583#define CMU_ICSC_M_O1_1 0x0915
1584#define CMU_ICSC_M_O1_2 0x0916
1585#define CMU_ICSC_M_O2_0 0x0918
1586#define CMU_ICSC_M_O2_1 0x0919
1587#define CMU_ICSC_M_O2_2 0x091A
1588#define CMU_ICSC_M_O3_0 0x091C
1589#define CMU_ICSC_M_O3_1 0x091D
1590#define CMU_ICSC_M_O3_2 0x091E
1591#define CMU_ICSC_P_C0_L 0x0920
1592#define CMU_ICSC_P_C0_H 0x0921
1593#define CMU_ICSC_P_C1_L 0x0922
1594#define CMU_ICSC_P_C1_H 0x0923
1595#define CMU_ICSC_P_C2_L 0x0924
1596#define CMU_ICSC_P_C2_H 0x0925
1597#define CMU_ICSC_P_C3_L 0x0926
1598#define CMU_ICSC_P_C3_H 0x0927
1599#define CMU_ICSC_P_C4_L 0x0928
1600#define CMU_ICSC_P_C4_H 0x0929
1601#define CMU_ICSC_P_C5_L 0x092A
1602#define CMU_ICSC_P_C5_H 0x092B
1603#define CMU_ICSC_P_C6_L 0x092C
1604#define CMU_ICSC_P_C6_H 0x092D
1605#define CMU_ICSC_P_C7_L 0x092E
1606#define CMU_ICSC_P_C7_H 0x092F
1607#define CMU_ICSC_P_C8_L 0x0930
1608#define CMU_ICSC_P_C8_H 0x0931
1609#define CMU_ICSC_P_O1_0 0x0934
1610#define CMU_ICSC_P_O1_1 0x0935
1611#define CMU_ICSC_P_O1_2 0x0936
1612#define CMU_ICSC_P_O2_0 0x0938
1613#define CMU_ICSC_P_O2_1 0x0939
1614#define CMU_ICSC_P_O2_2 0x093A
1615#define CMU_ICSC_P_O3_0 0x093C
1616#define CMU_ICSC_P_O3_1 0x093D
1617#define CMU_ICSC_P_O3_2 0x093E
1618#define CMU_BR_M_EN 0x0940
1619#define CMU_BR_M_TH1_L 0x0942
1620#define CMU_BR_M_TH1_H 0x0943
1621#define CMU_BR_M_TH2_L 0x0944
1622#define CMU_BR_M_TH2_H 0x0945
1623#define CMU_ACE_M_EN 0x0950
1624#define CMU_ACE_M_WFG1 0x0951
1625#define CMU_ACE_M_WFG2 0x0952
1626#define CMU_ACE_M_WFG3 0x0953
1627#define CMU_ACE_M_TH0 0x0954
1628#define CMU_ACE_M_TH1 0x0955
1629#define CMU_ACE_M_TH2 0x0956
1630#define CMU_ACE_M_TH3 0x0957
1631#define CMU_ACE_M_TH4 0x0958
1632#define CMU_ACE_M_TH5 0x0959
1633#define CMU_ACE_M_OP0_L 0x095A
1634#define CMU_ACE_M_OP0_H 0x095B
1635#define CMU_ACE_M_OP5_L 0x095C
1636#define CMU_ACE_M_OP5_H 0x095D
1637#define CMU_ACE_M_GB2 0x095E
1638#define CMU_ACE_M_GB3 0x095F
1639#define CMU_ACE_M_MS1 0x0960
1640#define CMU_ACE_M_MS2 0x0961
1641#define CMU_ACE_M_MS3 0x0962
1642#define CMU_BR_P_EN 0x0970
1643#define CMU_BR_P_TH1_L 0x0972
1644#define CMU_BR_P_TH1_H 0x0973
1645#define CMU_BR_P_TH2_L 0x0974
1646#define CMU_BR_P_TH2_H 0x0975
1647#define CMU_ACE_P_EN 0x0980
1648#define CMU_ACE_P_WFG1 0x0981
1649#define CMU_ACE_P_WFG2 0x0982
1650#define CMU_ACE_P_WFG3 0x0983
1651#define CMU_ACE_P_TH0 0x0984
1652#define CMU_ACE_P_TH1 0x0985
1653#define CMU_ACE_P_TH2 0x0986
1654#define CMU_ACE_P_TH3 0x0987
1655#define CMU_ACE_P_TH4 0x0988
1656#define CMU_ACE_P_TH5 0x0989
1657#define CMU_ACE_P_OP0_L 0x098A
1658#define CMU_ACE_P_OP0_H 0x098B
1659#define CMU_ACE_P_OP5_L 0x098C
1660#define CMU_ACE_P_OP5_H 0x098D
1661#define CMU_ACE_P_GB2 0x098E
1662#define CMU_ACE_P_GB3 0x098F
1663#define CMU_ACE_P_MS1 0x0990
1664#define CMU_ACE_P_MS2 0x0991
1665#define CMU_ACE_P_MS3 0x0992
1666#define CMU_FTDC_M_EN 0x09A0
1667#define CMU_FTDC_P_EN 0x09A1
1668#define CMU_FTDC_INLOW_L 0x09A2
1669#define CMU_FTDC_INLOW_H 0x09A3
1670#define CMU_FTDC_INHIGH_L 0x09A4
1671#define CMU_FTDC_INHIGH_H 0x09A5
1672#define CMU_FTDC_OUTLOW_L 0x09A6
1673#define CMU_FTDC_OUTLOW_H 0x09A7
1674#define CMU_FTDC_OUTHIGH_L 0x09A8
1675#define CMU_FTDC_OUTHIGH_H 0x09A9
1676#define CMU_FTDC_YLOW 0x09AA
1677#define CMU_FTDC_YHIGH 0x09AB
1678#define CMU_FTDC_CH1 0x09AC
1679#define CMU_FTDC_CH2_L 0x09AE
1680#define CMU_FTDC_CH2_H 0x09AF
1681#define CMU_FTDC_CH3_L 0x09B0
1682#define CMU_FTDC_CH3_H 0x09B1
1683#define CMU_FTDC_1_C00_6 0x09B2
1684#define CMU_FTDC_1_C01_6 0x09B8
1685#define CMU_FTDC_1_C11_6 0x09BE
1686#define CMU_FTDC_1_C10_6 0x09C4
1687#define CMU_FTDC_1_OFF00_6 0x09CA
1688#define CMU_FTDC_1_OFF10_6 0x09D0
1689#define CMU_HS_M_EN 0x0A00
1690#define CMU_HS_M_AX1_L 0x0A02
1691#define CMU_HS_M_AX1_H 0x0A03
1692#define CMU_HS_M_AX2_L 0x0A04
1693#define CMU_HS_M_AX2_H 0x0A05
1694#define CMU_HS_M_AX3_L 0x0A06
1695#define CMU_HS_M_AX3_H 0x0A07
1696#define CMU_HS_M_AX4_L 0x0A08
1697#define CMU_HS_M_AX4_H 0x0A09
1698#define CMU_HS_M_AX5_L 0x0A0A
1699#define CMU_HS_M_AX5_H 0x0A0B
1700#define CMU_HS_M_AX6_L 0x0A0C
1701#define CMU_HS_M_AX6_H 0x0A0D
1702#define CMU_HS_M_AX7_L 0x0A0E
1703#define CMU_HS_M_AX7_H 0x0A0F
1704#define CMU_HS_M_AX8_L 0x0A10
1705#define CMU_HS_M_AX8_H 0x0A11
1706#define CMU_HS_M_AX9_L 0x0A12
1707#define CMU_HS_M_AX9_H 0x0A13
1708#define CMU_HS_M_AX10_L 0x0A14
1709#define CMU_HS_M_AX10_H 0x0A15
1710#define CMU_HS_M_AX11_L 0x0A16
1711#define CMU_HS_M_AX11_H 0x0A17
1712#define CMU_HS_M_AX12_L 0x0A18
1713#define CMU_HS_M_AX12_H 0x0A19
1714#define CMU_HS_M_AX13_L 0x0A1A
1715#define CMU_HS_M_AX13_H 0x0A1B
1716#define CMU_HS_M_AX14_L 0x0A1C
1717#define CMU_HS_M_AX14_H 0x0A1D
1718#define CMU_HS_M_H1_H14 0x0A1E
1719#define CMU_HS_M_S1_S14 0x0A2C
1720#define CMU_HS_M_GL 0x0A3A
1721#define CMU_HS_M_MAXSAT_RGB_Y_L 0x0A3C
1722#define CMU_HS_M_MAXSAT_RGB_Y_H 0x0A3D
1723#define CMU_HS_M_MAXSAT_RCR_L 0x0A3E
1724#define CMU_HS_M_MAXSAT_RCR_H 0x0A3F
1725#define CMU_HS_M_MAXSAT_RCB_L 0x0A40
1726#define CMU_HS_M_MAXSAT_RCB_H 0x0A41
1727#define CMU_HS_M_MAXSAT_GCR_L 0x0A42
1728#define CMU_HS_M_MAXSAT_GCR_H 0x0A43
1729#define CMU_HS_M_MAXSAT_GCB_L 0x0A44
1730#define CMU_HS_M_MAXSAT_GCB_H 0x0A45
1731#define CMU_HS_M_MAXSAT_BCR_L 0x0A46
1732#define CMU_HS_M_MAXSAT_BCR_H 0x0A47
1733#define CMU_HS_M_MAXSAT_BCB_L 0x0A48
1734#define CMU_HS_M_MAXSAT_BCB_H 0x0A49
1735#define CMU_HS_M_ROFF_L 0x0A4A
1736#define CMU_HS_M_ROFF_H 0x0A4B
1737#define CMU_HS_M_GOFF_L 0x0A4C
1738#define CMU_HS_M_GOFF_H 0x0A4D
1739#define CMU_HS_M_BOFF_L 0x0A4E
1740#define CMU_HS_M_BOFF_H 0x0A4F
1741#define CMU_HS_P_EN 0x0A50
1742#define CMU_HS_P_AX1_L 0x0A52
1743#define CMU_HS_P_AX1_H 0x0A53
1744#define CMU_HS_P_AX2_L 0x0A54
1745#define CMU_HS_P_AX2_H 0x0A55
1746#define CMU_HS_P_AX3_L 0x0A56
1747#define CMU_HS_P_AX3_H 0x0A57
1748#define CMU_HS_P_AX4_L 0x0A58
1749#define CMU_HS_P_AX4_H 0x0A59
1750#define CMU_HS_P_AX5_L 0x0A5A
1751#define CMU_HS_P_AX5_H 0x0A5B
1752#define CMU_HS_P_AX6_L 0x0A5C
1753#define CMU_HS_P_AX6_H 0x0A5D
1754#define CMU_HS_P_AX7_L 0x0A5E
1755#define CMU_HS_P_AX7_H 0x0A5F
1756#define CMU_HS_P_AX8_L 0x0A60
1757#define CMU_HS_P_AX8_H 0x0A61
1758#define CMU_HS_P_AX9_L 0x0A62
1759#define CMU_HS_P_AX9_H 0x0A63
1760#define CMU_HS_P_AX10_L 0x0A64
1761#define CMU_HS_P_AX10_H 0x0A65
1762#define CMU_HS_P_AX11_L 0x0A66
1763#define CMU_HS_P_AX11_H 0x0A67
1764#define CMU_HS_P_AX12_L 0x0A68
1765#define CMU_HS_P_AX12_H 0x0A69
1766#define CMU_HS_P_AX13_L 0x0A6A
1767#define CMU_HS_P_AX13_H 0x0A6B
1768#define CMU_HS_P_AX14_L 0x0A6C
1769#define CMU_HS_P_AX14_H 0x0A6D
1770#define CMU_HS_P_H1_H14 0x0A6E
1771#define CMU_HS_P_S1_S14 0x0A7C
1772#define CMU_HS_P_GL 0x0A8A
1773#define CMU_HS_P_MAXSAT_RGB_Y_L 0x0A8C
1774#define CMU_HS_P_MAXSAT_RGB_Y_H 0x0A8D
1775#define CMU_HS_P_MAXSAT_RCR_L 0x0A8E
1776#define CMU_HS_P_MAXSAT_RCR_H 0x0A8F
1777#define CMU_HS_P_MAXSAT_RCB_L 0x0A90
1778#define CMU_HS_P_MAXSAT_RCB_H 0x0A91
1779#define CMU_HS_P_MAXSAT_GCR_L 0x0A92
1780#define CMU_HS_P_MAXSAT_GCR_H 0x0A93
1781#define CMU_HS_P_MAXSAT_GCB_L 0x0A94
1782#define CMU_HS_P_MAXSAT_GCB_H 0x0A95
1783#define CMU_HS_P_MAXSAT_BCR_L 0x0A96
1784#define CMU_HS_P_MAXSAT_BCR_H 0x0A97
1785#define CMU_HS_P_MAXSAT_BCB_L 0x0A98
1786#define CMU_HS_P_MAXSAT_BCB_H 0x0A99
1787#define CMU_HS_P_ROFF_L 0x0A9A
1788#define CMU_HS_P_ROFF_H 0x0A9B
1789#define CMU_HS_P_GOFF_L 0x0A9C
1790#define CMU_HS_P_GOFF_H 0x0A9D
1791#define CMU_HS_P_BOFF_L 0x0A9E
1792#define CMU_HS_P_BOFF_H 0x0A9F
1793#define CMU_GLCSC_M_C0_L 0x0AA0
1794#define CMU_GLCSC_M_C0_H 0x0AA1
1795#define CMU_GLCSC_M_C1_L 0x0AA2
1796#define CMU_GLCSC_M_C1_H 0x0AA3
1797#define CMU_GLCSC_M_C2_L 0x0AA4
1798#define CMU_GLCSC_M_C2_H 0x0AA5
1799#define CMU_GLCSC_M_C3_L 0x0AA6
1800#define CMU_GLCSC_M_C3_H 0x0AA7
1801#define CMU_GLCSC_M_C4_L 0x0AA8
1802#define CMU_GLCSC_M_C4_H 0x0AA9
1803#define CMU_GLCSC_M_C5_L 0x0AAA
1804#define CMU_GLCSC_M_C5_H 0x0AAB
1805#define CMU_GLCSC_M_C6_L 0x0AAC
1806#define CMU_GLCSC_M_C6_H 0x0AAD
1807#define CMU_GLCSC_M_C7_L 0x0AAE
1808#define CMU_GLCSC_M_C7_H 0x0AAF
1809#define CMU_GLCSC_M_C8_L 0x0AB0
1810#define CMU_GLCSC_M_C8_H 0x0AB1
1811#define CMU_GLCSC_M_O1_1 0x0AB4
1812#define CMU_GLCSC_M_O1_2 0x0AB5
1813#define CMU_GLCSC_M_O1_3 0x0AB6
1814#define CMU_GLCSC_M_O2_1 0x0AB8
1815#define CMU_GLCSC_M_O2_2 0x0AB9
1816#define CMU_GLCSC_M_O2_3 0x0ABA
1817#define CMU_GLCSC_M_O3_1 0x0ABC
1818#define CMU_GLCSC_M_O3_2 0x0ABD
1819#define CMU_GLCSC_M_O3_3 0x0ABE
1820#define CMU_GLCSC_P_C0_L 0x0AC0
1821#define CMU_GLCSC_P_C0_H 0x0AC1
1822#define CMU_GLCSC_P_C1_L 0x0AC2
1823#define CMU_GLCSC_P_C1_H 0x0AC3
1824#define CMU_GLCSC_P_C2_L 0x0AC4
1825#define CMU_GLCSC_P_C2_H 0x0AC5
1826#define CMU_GLCSC_P_C3_L 0x0AC6
1827#define CMU_GLCSC_P_C3_H 0x0AC7
1828#define CMU_GLCSC_P_C4_L 0x0AC8
1829#define CMU_GLCSC_P_C4_H 0x0AC9
1830#define CMU_GLCSC_P_C5_L 0x0ACA
1831#define CMU_GLCSC_P_C5_H 0x0ACB
1832#define CMU_GLCSC_P_C6_L 0x0ACC
1833#define CMU_GLCSC_P_C6_H 0x0ACD
1834#define CMU_GLCSC_P_C7_L 0x0ACE
1835#define CMU_GLCSC_P_C7_H 0x0ACF
1836#define CMU_GLCSC_P_C8_L 0x0AD0
1837#define CMU_GLCSC_P_C8_H 0x0AD1
1838#define CMU_GLCSC_P_O1_1 0x0AD4
1839#define CMU_GLCSC_P_O1_2 0x0AD5
1840#define CMU_GLCSC_P_O1_3 0x0AD6
1841#define CMU_GLCSC_P_O2_1 0x0AD8
1842#define CMU_GLCSC_P_O2_2 0x0AD9
1843#define CMU_GLCSC_P_O2_3 0x0ADA
1844#define CMU_GLCSC_P_O3_1 0x0ADC
1845#define CMU_GLCSC_P_O3_2 0x0ADD
1846#define CMU_GLCSC_P_O3_3 0x0ADE
1847#define CMU_PIXVAL_M_EN 0x0AE0
1848#define CMU_PIXVAL_P_EN 0x0AE1
1849
1850#define CMU_CLK_CTRL_TCLK 0x0
1851#define CMU_CLK_CTRL_SCLK 0x2
1852#define CMU_CLK_CTRL_MSK 0x2
1853#define CMU_CLK_CTRL_ENABLE 0x1
1854
1855#define LCD_TOP_CTRL_TV 0x2
1856#define LCD_TOP_CTRL_PN 0x0
1857#define LCD_TOP_CTRL_SEL_MSK 0x2
1858#define LCD_IO_CMU_IN_SEL_MSK (0x3 << 20)
1859#define LCD_IO_CMU_IN_SEL_TV 0
1860#define LCD_IO_CMU_IN_SEL_PN 1
1861#define LCD_IO_CMU_IN_SEL_PN2 2
1862#define LCD_IO_TV_OUT_SEL_MSK (0x3 << 26)
1863#define LCD_IO_PN_OUT_SEL_MSK (0x3 << 24)
1864#define LCD_IO_PN2_OUT_SEL_MSK (0x3 << 28)
1865#define LCD_IO_TV_OUT_SEL_NON 3
1866#define LCD_IO_PN_OUT_SEL_NON 3
1867#define LCD_IO_PN2_OUT_SEL_NON 3
1868#define LCD_TOP_CTRL_CMU_ENABLE 0x1
1869#define LCD_IO_OVERL_MSK 0xC00000
1870#define LCD_IO_OVERL_TV 0x0
1871#define LCD_IO_OVERL_LCD1 0x400000
1872#define LCD_IO_OVERL_LCD2 0xC00000
1873#define HINVERT_MSK 0x4
1874#define VINVERT_MSK 0x8
1875#define HINVERT_LEN 0x2
1876#define VINVERT_LEN 0x3
1877
1878#define CMU_CTRL 0x88
1879#define CMU_CTRL_A0_MSK 0x6
1880#define CMU_CTRL_A0_TV 0x0
1881#define CMU_CTRL_A0_LCD1 0x1
1882#define CMU_CTRL_A0_LCD2 0x2
1883#define CMU_CTRL_A0_HDMI 0x3
1884
1885#define ICR_DRV_ROUTE_OFF 0x0
1886#define ICR_DRV_ROUTE_TV 0x1
1887#define ICR_DRV_ROUTE_LCD1 0x2
1888#define ICR_DRV_ROUTE_LCD2 0x3
1889
1890enum {
1891 PATH_PN = 0,
1892 PATH_TV,
1893 PATH_P2,
1894};
1895
1896/*
1897 * mmp path describes part of mmp path related info:
1898 * which is hiden in display driver and not exported to buffer driver
1899 */
1900struct mmphw_ctrl;
1901struct mmphw_path_plat {
1902 int id;
1903 struct mmphw_ctrl *ctrl;
1904 struct mmp_path *path;
1905 u32 path_config;
1906 u32 link_config;
1907};
1908
1909/* mmp ctrl describes mmp controller related info */
1910struct mmphw_ctrl {
1911 /* platform related, get from config */
1912 const char *name;
1913 int irq;
1914 void *reg_base;
1915 struct clk *clk;
1916
1917 /* sys info */
1918 struct device *dev;
1919
1920 /* state */
1921 int open_count;
1922 int status;
1923 struct mutex access_ok;
1924
1925 /*pathes*/
1926 int path_num;
1927 struct mmphw_path_plat path_plats[0];
1928};
1929
1930static inline int overlay_is_vid(struct mmp_overlay *overlay)
1931{
1932 return overlay->dmafetch_id & 1;
1933}
1934
1935static inline struct mmphw_path_plat *path_to_path_plat(struct mmp_path *path)
1936{
1937 return (struct mmphw_path_plat *)path->plat_data;
1938}
1939
1940static inline struct mmphw_ctrl *path_to_ctrl(struct mmp_path *path)
1941{
1942 return path_to_path_plat(path)->ctrl;
1943}
1944
1945static inline struct mmphw_ctrl *overlay_to_ctrl(struct mmp_overlay *overlay)
1946{
1947 return path_to_ctrl(overlay->path);
1948}
1949
1950static inline void *ctrl_regs(struct mmp_path *path)
1951{
1952 return path_to_ctrl(path)->reg_base;
1953}
1954
1955/* path regs, for regs symmetrical for both pathes */
1956static inline struct lcd_regs *path_regs(struct mmp_path *path)
1957{
1958 if (path->id == PATH_PN)
1959 return (struct lcd_regs *)(ctrl_regs(path) + 0xc0);
1960 else if (path->id == PATH_TV)
1961 return (struct lcd_regs *)ctrl_regs(path);
1962 else if (path->id == PATH_P2)
1963 return (struct lcd_regs *)(ctrl_regs(path) + 0x200);
1964 else {
1965 dev_err(path->dev, "path id %d invalid\n", path->id);
1966 BUG_ON(1);
1967 return NULL;
1968 }
1969}
1970
1971#ifdef CONFIG_MMP_DISP_SPI
1972extern int lcd_spi_register(struct mmphw_ctrl *ctrl);
1973#endif
1974#endif /* _MMP_CTRL_H_ */
diff --git a/drivers/video/mmp/hw/mmp_spi.c b/drivers/video/mmp/hw/mmp_spi.c
new file mode 100644
index 000000000000..e62ca7bf0d5e
--- /dev/null
+++ b/drivers/video/mmp/hw/mmp_spi.c
@@ -0,0 +1,180 @@
1/*
2 * linux/drivers/video/mmp/hw/mmp_spi.c
3 * using the spi in LCD controler for commands send
4 *
5 * Copyright (C) 2012 Marvell Technology Group Ltd.
6 * Authors: Guoqing Li <ligq@marvell.com>
7 * Lisa Du <cldu@marvell.com>
8 * Zhou Zhu <zzhu3@marvell.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program. If not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24#include <linux/errno.h>
25#include <linux/delay.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/spi/spi.h>
29#include "mmp_ctrl.h"
30
31/**
32 * spi_write - write command to the SPI port
33 * @data: can be 8/16/32-bit, MSB justified data to write.
34 * @len: data length.
35 *
36 * Wait bus transfer complete IRQ.
37 * The caller is expected to perform the necessary locking.
38 *
39 * Returns:
40 * %-ETIMEDOUT timeout occurred
41 * 0 success
42 */
43static inline int lcd_spi_write(struct spi_device *spi, u32 data)
44{
45 int timeout = 100000, isr, ret = 0;
46 u32 tmp;
47 void *reg_base =
48 *(void **)spi_master_get_devdata(spi->master);
49
50 /* clear ISR */
51 writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
52
53 switch (spi->bits_per_word) {
54 case 8:
55 writel_relaxed((u8)data, reg_base + LCD_SPU_SPI_TXDATA);
56 break;
57 case 16:
58 writel_relaxed((u16)data, reg_base + LCD_SPU_SPI_TXDATA);
59 break;
60 case 32:
61 writel_relaxed((u32)data, reg_base + LCD_SPU_SPI_TXDATA);
62 break;
63 default:
64 dev_err(&spi->dev, "Wrong spi bit length\n");
65 }
66
67 /* SPI start to send command */
68 tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
69 tmp &= ~CFG_SPI_START_MASK;
70 tmp |= CFG_SPI_START(1);
71 writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
72
73 isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
74 while (!(isr & SPI_IRQ_ENA_MASK)) {
75 udelay(100);
76 isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
77 if (!--timeout) {
78 ret = -ETIMEDOUT;
79 dev_err(&spi->dev, "spi cmd send time out\n");
80 break;
81 }
82 }
83
84 tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
85 tmp &= ~CFG_SPI_START_MASK;
86 tmp |= CFG_SPI_START(0);
87 writel_relaxed(tmp, reg_base + LCD_SPU_SPI_CTRL);
88
89 writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
90
91 return ret;
92}
93
94static int lcd_spi_setup(struct spi_device *spi)
95{
96 void *reg_base =
97 *(void **)spi_master_get_devdata(spi->master);
98 u32 tmp;
99
100 tmp = CFG_SCLKCNT(16) |
101 CFG_TXBITS(spi->bits_per_word) |
102 CFG_SPI_SEL(1) | CFG_SPI_ENA(1) |
103 CFG_SPI_3W4WB(1);
104 writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
105
106 /*
107 * After set mode it need a time to pull up the spi singals,
108 * or it would cause the wrong waveform when send spi command,
109 * especially on pxa910h
110 */
111 tmp = readl_relaxed(reg_base + SPU_IOPAD_CONTROL);
112 if ((tmp & CFG_IOPADMODE_MASK) != IOPAD_DUMB18SPI)
113 writel_relaxed(IOPAD_DUMB18SPI |
114 (tmp & ~CFG_IOPADMODE_MASK),
115 reg_base + SPU_IOPAD_CONTROL);
116 udelay(20);
117 return 0;
118}
119
120static int lcd_spi_one_transfer(struct spi_device *spi, struct spi_message *m)
121{
122 struct spi_transfer *t;
123 int i;
124
125 list_for_each_entry(t, &m->transfers, transfer_list) {
126 switch (spi->bits_per_word) {
127 case 8:
128 for (i = 0; i < t->len; i++)
129 lcd_spi_write(spi, ((u8 *)t->tx_buf)[i]);
130 break;
131 case 16:
132 for (i = 0; i < t->len/2; i++)
133 lcd_spi_write(spi, ((u16 *)t->tx_buf)[i]);
134 break;
135 case 32:
136 for (i = 0; i < t->len/4; i++)
137 lcd_spi_write(spi, ((u32 *)t->tx_buf)[i]);
138 break;
139 default:
140 dev_err(&spi->dev, "Wrong spi bit length\n");
141 }
142 }
143
144 m->status = 0;
145 if (m->complete)
146 m->complete(m->context);
147 return 0;
148}
149
150int lcd_spi_register(struct mmphw_ctrl *ctrl)
151{
152 struct spi_master *master;
153 void **p_regbase;
154 int err;
155
156 master = spi_alloc_master(ctrl->dev, sizeof(void *));
157 if (!master) {
158 dev_err(ctrl->dev, "unable to allocate SPI master\n");
159 return -ENOMEM;
160 }
161 p_regbase = spi_master_get_devdata(master);
162 *p_regbase = ctrl->reg_base;
163
164 /* set bus num to 5 to avoid conflict with other spi hosts */
165 master->bus_num = 5;
166 master->num_chipselect = 1;
167 master->setup = lcd_spi_setup;
168 master->transfer = lcd_spi_one_transfer;
169
170 err = spi_register_master(master);
171 if (err < 0) {
172 dev_err(ctrl->dev, "unable to register SPI master\n");
173 spi_master_put(master);
174 return err;
175 }
176
177 dev_info(&master->dev, "registered\n");
178
179 return 0;
180}
diff --git a/drivers/video/mmp/panel/Kconfig b/drivers/video/mmp/panel/Kconfig
new file mode 100644
index 000000000000..4b2c4f457b11
--- /dev/null
+++ b/drivers/video/mmp/panel/Kconfig
@@ -0,0 +1,6 @@
1config MMP_PANEL_TPOHVGA
2 bool "tpohvga panel TJ032MD01BW support"
3 depends on SPI_MASTER
4 default n
5 help
6 tpohvga panel support
diff --git a/drivers/video/mmp/panel/Makefile b/drivers/video/mmp/panel/Makefile
new file mode 100644
index 000000000000..2f91611c7e5e
--- /dev/null
+++ b/drivers/video/mmp/panel/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_MMP_PANEL_TPOHVGA) += tpo_tj032md01bw.o
diff --git a/drivers/video/mmp/panel/tpo_tj032md01bw.c b/drivers/video/mmp/panel/tpo_tj032md01bw.c
new file mode 100644
index 000000000000..998978b08f5e
--- /dev/null
+++ b/drivers/video/mmp/panel/tpo_tj032md01bw.c
@@ -0,0 +1,186 @@
1/*
2 * linux/drivers/video/mmp/panel/tpo_tj032md01bw.c
3 * active panel using spi interface to do init
4 *
5 * Copyright (C) 2012 Marvell Technology Group Ltd.
6 * Authors: Guoqing Li <ligq@marvell.com>
7 * Lisa Du <cldu@marvell.com>
8 * Zhou Zhu <zzhu3@marvell.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program. If not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/kernel.h>
28#include <linux/errno.h>
29#include <linux/string.h>
30#include <linux/delay.h>
31#include <linux/platform_device.h>
32#include <linux/err.h>
33#include <linux/spi/spi.h>
34#include <video/mmp_disp.h>
35
36static u16 init[] = {
37 0x0801,
38 0x0800,
39 0x0200,
40 0x0304,
41 0x040e,
42 0x0903,
43 0x0b18,
44 0x0c53,
45 0x0d01,
46 0x0ee0,
47 0x0f01,
48 0x1058,
49 0x201e,
50 0x210a,
51 0x220a,
52 0x231e,
53 0x2400,
54 0x2532,
55 0x2600,
56 0x27ac,
57 0x2904,
58 0x2aa2,
59 0x2b45,
60 0x2c45,
61 0x2d15,
62 0x2e5a,
63 0x2fff,
64 0x306b,
65 0x310d,
66 0x3248,
67 0x3382,
68 0x34bd,
69 0x35e7,
70 0x3618,
71 0x3794,
72 0x3801,
73 0x395d,
74 0x3aae,
75 0x3bff,
76 0x07c9,
77};
78
79static u16 poweroff[] = {
80 0x07d9,
81};
82
83struct tpohvga_plat_data {
84 void (*plat_onoff)(int status);
85 struct spi_device *spi;
86};
87
88static void tpohvga_onoff(struct mmp_panel *panel, int status)
89{
90 struct tpohvga_plat_data *plat = panel->plat_data;
91 int ret;
92
93 if (status) {
94 plat->plat_onoff(1);
95
96 ret = spi_write(plat->spi, init, sizeof(init));
97 if (ret < 0)
98 dev_warn(panel->dev, "init cmd failed(%d)\n", ret);
99 } else {
100 ret = spi_write(plat->spi, poweroff, sizeof(poweroff));
101 if (ret < 0)
102 dev_warn(panel->dev, "poweroff cmd failed(%d)\n", ret);
103
104 plat->plat_onoff(0);
105 }
106}
107
108static struct mmp_mode mmp_modes_tpohvga[] = {
109 [0] = {
110 .pixclock_freq = 10394400,
111 .refresh = 60,
112 .xres = 320,
113 .yres = 480,
114 .hsync_len = 10,
115 .left_margin = 15,
116 .right_margin = 10,
117 .vsync_len = 2,
118 .upper_margin = 4,
119 .lower_margin = 2,
120 .invert_pixclock = 1,
121 .pix_fmt_out = PIXFMT_RGB565,
122 },
123};
124
125static int tpohvga_get_modelist(struct mmp_panel *panel,
126 struct mmp_mode **modelist)
127{
128 *modelist = mmp_modes_tpohvga;
129 return 1;
130}
131
132static struct mmp_panel panel_tpohvga = {
133 .name = "tpohvga",
134 .panel_type = PANELTYPE_ACTIVE,
135 .get_modelist = tpohvga_get_modelist,
136 .set_onoff = tpohvga_onoff,
137};
138
139static int tpohvga_probe(struct spi_device *spi)
140{
141 struct mmp_mach_panel_info *mi;
142 int ret;
143 struct tpohvga_plat_data *plat_data;
144
145 /* get configs from platform data */
146 mi = spi->dev.platform_data;
147 if (mi == NULL) {
148 dev_err(&spi->dev, "%s: no platform data defined\n", __func__);
149 return -EINVAL;
150 }
151
152 /* setup spi related info */
153 spi->bits_per_word = 16;
154 ret = spi_setup(spi);
155 if (ret < 0) {
156 dev_err(&spi->dev, "spi setup failed %d", ret);
157 return ret;
158 }
159
160 plat_data = kzalloc(sizeof(*plat_data), GFP_KERNEL);
161 if (plat_data == NULL)
162 return -ENOMEM;
163
164 plat_data->spi = spi;
165 plat_data->plat_onoff = mi->plat_set_onoff;
166 panel_tpohvga.plat_data = plat_data;
167 panel_tpohvga.plat_path_name = mi->plat_path_name;
168 panel_tpohvga.dev = &spi->dev;
169
170 mmp_register_panel(&panel_tpohvga);
171
172 return 0;
173}
174
175static struct spi_driver panel_tpohvga_driver = {
176 .driver = {
177 .name = "tpo-hvga",
178 .owner = THIS_MODULE,
179 },
180 .probe = tpohvga_probe,
181};
182module_spi_driver(panel_tpohvga_driver);
183
184MODULE_AUTHOR("Lisa Du<cldu@marvell.com>");
185MODULE_DESCRIPTION("Panel driver for tpohvga");
186MODULE_LICENSE("GPL");
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index 736887208574..cfdb380ec81e 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -1306,7 +1306,7 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi)
1306 dma_free_writecombine(fbi->device, fbi->fix.smem_len, 1306 dma_free_writecombine(fbi->device, fbi->fix.smem_len,
1307 fbi->screen_base, fbi->fix.smem_start); 1307 fbi->screen_base, fbi->fix.smem_start);
1308 1308
1309 fbi->screen_base = 0; 1309 fbi->screen_base = NULL;
1310 mutex_lock(&fbi->mm_lock); 1310 mutex_lock(&fbi->mm_lock);
1311 fbi->fix.smem_start = 0; 1311 fbi->fix.smem_start = 0;
1312 fbi->fix.smem_len = 0; 1312 fbi->fix.smem_len = 0;