aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-03-08 15:21:04 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-03-08 15:21:04 -0500
commit988addf82e4c03739375279de73929580a2d4a6a (patch)
tree989ae1cd4e264bbad80c65f04480486246e7b9f3 /drivers/video
parent004c1c7096659d352b83047a7593e91d8a30e3c5 (diff)
parent25cf84cf377c0aae5dbcf937ea89bc7893db5176 (diff)
Merge branch 'origin' into devel-stable
Conflicts: arch/arm/mach-mx2/devices.c arch/arm/mach-mx2/devices.h sound/soc/pxa/pxa-ssp.c
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/aty/aty128fb.c14
-rw-r--r--drivers/video/aty/atyfb_base.c10
-rw-r--r--drivers/video/aty/radeon_backlight.c6
-rw-r--r--drivers/video/backlight/88pm860x_bl.c304
-rw-r--r--drivers/video/backlight/Kconfig13
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/max8925_bl.c200
-rw-r--r--drivers/video/console/Kconfig1
-rw-r--r--drivers/video/console/fbcon.c18
-rw-r--r--drivers/video/console/vgacon.c2
-rw-r--r--drivers/video/efifb.c11
-rw-r--r--drivers/video/fbmem.c1
-rw-r--r--drivers/video/fsl-diu-fb.c5
-rw-r--r--drivers/video/macfb.c736
-rw-r--r--drivers/video/macmodes.c80
-rw-r--r--drivers/video/omap/lcd_ams_delta.c93
-rw-r--r--drivers/video/omap/omapfb_main.c7
-rw-r--r--drivers/video/omap2/displays/Kconfig18
-rw-r--r--drivers/video/omap2/displays/Makefile3
-rw-r--r--drivers/video/omap2/displays/panel-generic.c56
-rw-r--r--drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c159
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c77
-rw-r--r--drivers/video/omap2/displays/panel-taal.c253
-rw-r--r--drivers/video/omap2/displays/panel-toppoly-tdo35s.c154
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c528
-rw-r--r--drivers/video/omap2/dss/Kconfig26
-rw-r--r--drivers/video/omap2/dss/core.c117
-rw-r--r--drivers/video/omap2/dss/dispc.c42
-rw-r--r--drivers/video/omap2/dss/display.c119
-rw-r--r--drivers/video/omap2/dss/dpi.c144
-rw-r--r--drivers/video/omap2/dss/dsi.c1031
-rw-r--r--drivers/video/omap2/dss/dss.c42
-rw-r--r--drivers/video/omap2/dss/dss.h23
-rw-r--r--drivers/video/omap2/dss/manager.c48
-rw-r--r--drivers/video/omap2/dss/overlay.c2
-rw-r--r--drivers/video/omap2/dss/rfbi.c321
-rw-r--r--drivers/video/omap2/dss/sdi.c115
-rw-r--r--drivers/video/omap2/dss/venc.c296
-rw-r--r--drivers/video/omap2/omapfb/Kconfig11
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c68
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c133
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h9
-rw-r--r--drivers/video/pvr2fb.c2
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c88
-rw-r--r--drivers/video/sunxvr500.c1
-rw-r--r--drivers/video/valkyriefb.c6
-rw-r--r--drivers/video/valkyriefb.h31
47 files changed, 3149 insertions, 2277 deletions
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index e4e4d433b007..9ee67d6da710 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1931,22 +1931,22 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
1931 * PowerMac2,2 summer 2000 iMacs 1931 * PowerMac2,2 summer 2000 iMacs
1932 * PowerMac4,1 january 2001 iMacs "flower power" 1932 * PowerMac4,1 january 2001 iMacs "flower power"
1933 */ 1933 */
1934 if (machine_is_compatible("PowerMac2,1") || 1934 if (of_machine_is_compatible("PowerMac2,1") ||
1935 machine_is_compatible("PowerMac2,2") || 1935 of_machine_is_compatible("PowerMac2,2") ||
1936 machine_is_compatible("PowerMac4,1")) 1936 of_machine_is_compatible("PowerMac4,1"))
1937 default_vmode = VMODE_1024_768_75; 1937 default_vmode = VMODE_1024_768_75;
1938 1938
1939 /* iBook SE */ 1939 /* iBook SE */
1940 if (machine_is_compatible("PowerBook2,2")) 1940 if (of_machine_is_compatible("PowerBook2,2"))
1941 default_vmode = VMODE_800_600_60; 1941 default_vmode = VMODE_800_600_60;
1942 1942
1943 /* PowerBook Firewire (Pismo), iBook Dual USB */ 1943 /* PowerBook Firewire (Pismo), iBook Dual USB */
1944 if (machine_is_compatible("PowerBook3,1") || 1944 if (of_machine_is_compatible("PowerBook3,1") ||
1945 machine_is_compatible("PowerBook4,1")) 1945 of_machine_is_compatible("PowerBook4,1"))
1946 default_vmode = VMODE_1024_768_60; 1946 default_vmode = VMODE_1024_768_60;
1947 1947
1948 /* PowerBook Titanium */ 1948 /* PowerBook Titanium */
1949 if (machine_is_compatible("PowerBook3,2")) 1949 if (of_machine_is_compatible("PowerBook3,2"))
1950 default_vmode = VMODE_1152_768_60; 1950 default_vmode = VMODE_1152_768_60;
1951 1951
1952 if (default_cmode > 16) 1952 if (default_cmode > 16)
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 1ddeb4c34763..e45ab8db2ddc 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2439,7 +2439,7 @@ static int __devinit aty_init(struct fb_info *info)
2439 * The Apple iBook1 uses non-standard memory frequencies. 2439 * The Apple iBook1 uses non-standard memory frequencies.
2440 * We detect it and set the frequency manually. 2440 * We detect it and set the frequency manually.
2441 */ 2441 */
2442 if (machine_is_compatible("PowerBook2,1")) { 2442 if (of_machine_is_compatible("PowerBook2,1")) {
2443 par->pll_limits.mclk = 70; 2443 par->pll_limits.mclk = 70;
2444 par->pll_limits.xclk = 53; 2444 par->pll_limits.xclk = 53;
2445 } 2445 }
@@ -2659,7 +2659,7 @@ static int __devinit aty_init(struct fb_info *info)
2659 FBINFO_HWACCEL_YPAN; 2659 FBINFO_HWACCEL_YPAN;
2660 2660
2661#ifdef CONFIG_PMAC_BACKLIGHT 2661#ifdef CONFIG_PMAC_BACKLIGHT
2662 if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { 2662 if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) {
2663 /* 2663 /*
2664 * these bits let the 101 powerbook 2664 * these bits let the 101 powerbook
2665 * wake up from sleep -- paulus 2665 * wake up from sleep -- paulus
@@ -2690,9 +2690,9 @@ static int __devinit aty_init(struct fb_info *info)
2690 if (M64_HAS(G3_PB_1024x768)) 2690 if (M64_HAS(G3_PB_1024x768))
2691 /* G3 PowerBook with 1024x768 LCD */ 2691 /* G3 PowerBook with 1024x768 LCD */
2692 default_vmode = VMODE_1024_768_60; 2692 default_vmode = VMODE_1024_768_60;
2693 else if (machine_is_compatible("iMac")) 2693 else if (of_machine_is_compatible("iMac"))
2694 default_vmode = VMODE_1024_768_75; 2694 default_vmode = VMODE_1024_768_75;
2695 else if (machine_is_compatible("PowerBook2,1")) 2695 else if (of_machine_is_compatible("PowerBook2,1"))
2696 /* iBook with 800x600 LCD */ 2696 /* iBook with 800x600 LCD */
2697 default_vmode = VMODE_800_600_60; 2697 default_vmode = VMODE_800_600_60;
2698 else 2698 else
@@ -3104,7 +3104,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
3104 } 3104 }
3105 3105
3106 dp = pci_device_to_OF_node(pdev); 3106 dp = pci_device_to_OF_node(pdev);
3107 if (node == dp->node) { 3107 if (node == dp->phandle) {
3108 struct fb_var_screeninfo *var = &default_var; 3108 struct fb_var_screeninfo *var = &default_var;
3109 unsigned int N, P, Q, M, T, R; 3109 unsigned int N, P, Q, M, T, R;
3110 u32 v_total, h_total; 3110 u32 v_total, h_total;
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 1a056adb61c8..fa1198c4ccc5 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -175,9 +175,9 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
175 175
176#ifdef CONFIG_PMAC_BACKLIGHT 176#ifdef CONFIG_PMAC_BACKLIGHT
177 pdata->negative = pdata->negative || 177 pdata->negative = pdata->negative ||
178 machine_is_compatible("PowerBook4,3") || 178 of_machine_is_compatible("PowerBook4,3") ||
179 machine_is_compatible("PowerBook6,3") || 179 of_machine_is_compatible("PowerBook6,3") ||
180 machine_is_compatible("PowerBook6,5"); 180 of_machine_is_compatible("PowerBook6,5");
181#endif 181#endif
182 182
183 rinfo->info->bl_dev = bd; 183 rinfo->info->bl_dev = bd;
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
new file mode 100644
index 000000000000..b8f705cca438
--- /dev/null
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -0,0 +1,304 @@
1/*
2 * Backlight driver for Marvell Semiconductor 88PM8606
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/fb.h>
16#include <linux/i2c.h>
17#include <linux/backlight.h>
18#include <linux/mfd/88pm860x.h>
19
20#define MAX_BRIGHTNESS (0xFF)
21#define MIN_BRIGHTNESS (0)
22
23#define CURRENT_MASK (0x1F << 1)
24
25struct pm860x_backlight_data {
26 struct pm860x_chip *chip;
27 struct i2c_client *i2c;
28 int current_brightness;
29 int port;
30 int pwm;
31 int iset;
32};
33
34static inline int wled_a(int port)
35{
36 int ret;
37
38 ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
39 return ret;
40}
41
42static inline int wled_b(int port)
43{
44 int ret;
45
46 ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
47 return ret;
48}
49
50/* WLED2 & WLED3 share the same IDC */
51static inline int wled_idc(int port)
52{
53 int ret;
54
55 switch (port) {
56 case PM8606_BACKLIGHT1:
57 case PM8606_BACKLIGHT2:
58 ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
59 break;
60 case PM8606_BACKLIGHT3:
61 default:
62 ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
63 break;
64 }
65 return ret;
66}
67
68static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
69{
70 struct pm860x_backlight_data *data = bl_get_data(bl);
71 struct pm860x_chip *chip = data->chip;
72 unsigned char value;
73 int ret;
74
75 if (brightness > MAX_BRIGHTNESS)
76 value = MAX_BRIGHTNESS;
77 else
78 value = brightness;
79
80 ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
81 if (ret < 0)
82 goto out;
83
84 if ((data->current_brightness == 0) && brightness) {
85 if (data->iset) {
86 ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
87 CURRENT_MASK, data->iset);
88 if (ret < 0)
89 goto out;
90 }
91 if (data->pwm) {
92 ret = pm860x_set_bits(data->i2c, PM8606_PWM,
93 PM8606_PWM_FREQ_MASK, data->pwm);
94 if (ret < 0)
95 goto out;
96 }
97 if (brightness == MAX_BRIGHTNESS) {
98 /* set WLED_ON bit as 100% */
99 ret = pm860x_set_bits(data->i2c, wled_b(data->port),
100 PM8606_WLED_ON, PM8606_WLED_ON);
101 }
102 } else {
103 if (brightness == MAX_BRIGHTNESS) {
104 /* set WLED_ON bit as 100% */
105 ret = pm860x_set_bits(data->i2c, wled_b(data->port),
106 PM8606_WLED_ON, PM8606_WLED_ON);
107 } else {
108 /* clear WLED_ON bit since it's not 100% */
109 ret = pm860x_set_bits(data->i2c, wled_b(data->port),
110 PM8606_WLED_ON, 0);
111 }
112 }
113 if (ret < 0)
114 goto out;
115
116 dev_dbg(chip->dev, "set brightness %d\n", value);
117 data->current_brightness = value;
118 return 0;
119out:
120 dev_dbg(chip->dev, "set brightness %d failure with return "
121 "value:%d\n", value, ret);
122 return ret;
123}
124
125static int pm860x_backlight_update_status(struct backlight_device *bl)
126{
127 int brightness = bl->props.brightness;
128
129 if (bl->props.power != FB_BLANK_UNBLANK)
130 brightness = 0;
131
132 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
133 brightness = 0;
134
135 if (bl->props.state & BL_CORE_SUSPENDED)
136 brightness = 0;
137
138 return pm860x_backlight_set(bl, brightness);
139}
140
141static int pm860x_backlight_get_brightness(struct backlight_device *bl)
142{
143 struct pm860x_backlight_data *data = bl_get_data(bl);
144 struct pm860x_chip *chip = data->chip;
145 int ret;
146
147 ret = pm860x_reg_read(data->i2c, wled_a(data->port));
148 if (ret < 0)
149 goto out;
150 data->current_brightness = ret;
151 dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
152 return data->current_brightness;
153out:
154 return -EINVAL;
155}
156
157static struct backlight_ops pm860x_backlight_ops = {
158 .options = BL_CORE_SUSPENDRESUME,
159 .update_status = pm860x_backlight_update_status,
160 .get_brightness = pm860x_backlight_get_brightness,
161};
162
163static int __check_device(struct pm860x_backlight_pdata *pdata, char *name)
164{
165 struct pm860x_backlight_pdata *p = pdata;
166 int ret = -EINVAL;
167
168 while (p && p->id) {
169 if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0))
170 break;
171
172 if (!strncmp(name, pm860x_backlight_name[p->flags],
173 MFD_NAME_SIZE)) {
174 ret = (int)p->flags;
175 break;
176 }
177 p++;
178 }
179 return ret;
180}
181
182static int pm860x_backlight_probe(struct platform_device *pdev)
183{
184 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
185 struct pm860x_platform_data *pm860x_pdata;
186 struct pm860x_backlight_pdata *pdata = NULL;
187 struct pm860x_backlight_data *data;
188 struct backlight_device *bl;
189 struct resource *res;
190 unsigned char value;
191 char name[MFD_NAME_SIZE];
192 int ret;
193
194 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
195 if (res == NULL) {
196 dev_err(&pdev->dev, "No I/O resource!\n");
197 return -EINVAL;
198 }
199
200 if (pdev->dev.parent->platform_data) {
201 pm860x_pdata = pdev->dev.parent->platform_data;
202 pdata = pm860x_pdata->backlight;
203 }
204 if (pdata == NULL) {
205 dev_err(&pdev->dev, "platform data isn't assigned to "
206 "backlight\n");
207 return -EINVAL;
208 }
209
210 data = kzalloc(sizeof(struct pm860x_backlight_data), GFP_KERNEL);
211 if (data == NULL)
212 return -ENOMEM;
213 strncpy(name, res->name, MFD_NAME_SIZE);
214 data->chip = chip;
215 data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
216 : chip->companion;
217 data->current_brightness = MAX_BRIGHTNESS;
218 data->pwm = pdata->pwm;
219 data->iset = pdata->iset;
220 data->port = __check_device(pdata, name);
221 if (data->port < 0) {
222 dev_err(&pdev->dev, "wrong platform data is assigned");
223 return -EINVAL;
224 }
225
226 bl = backlight_device_register(name, &pdev->dev, data,
227 &pm860x_backlight_ops);
228 if (IS_ERR(bl)) {
229 dev_err(&pdev->dev, "failed to register backlight\n");
230 kfree(data);
231 return PTR_ERR(bl);
232 }
233 bl->props.max_brightness = MAX_BRIGHTNESS;
234 bl->props.brightness = MAX_BRIGHTNESS;
235
236 platform_set_drvdata(pdev, bl);
237
238 /* Enable reference VSYS */
239 ret = pm860x_reg_read(data->i2c, PM8606_VSYS);
240 if (ret < 0)
241 goto out;
242 if ((ret & PM8606_VSYS_EN) == 0) {
243 value = ret | PM8606_VSYS_EN;
244 ret = pm860x_reg_write(data->i2c, PM8606_VSYS, value);
245 if (ret < 0)
246 goto out;
247 }
248 /* Enable reference OSC */
249 ret = pm860x_reg_read(data->i2c, PM8606_MISC);
250 if (ret < 0)
251 goto out;
252 if ((ret & PM8606_MISC_OSC_EN) == 0) {
253 value = ret | PM8606_MISC_OSC_EN;
254 ret = pm860x_reg_write(data->i2c, PM8606_MISC, value);
255 if (ret < 0)
256 goto out;
257 }
258 /* read current backlight */
259 ret = pm860x_backlight_get_brightness(bl);
260 if (ret < 0)
261 goto out;
262
263 backlight_update_status(bl);
264 return 0;
265out:
266 kfree(data);
267 return ret;
268}
269
270static int pm860x_backlight_remove(struct platform_device *pdev)
271{
272 struct backlight_device *bl = platform_get_drvdata(pdev);
273 struct pm860x_backlight_data *data = bl_get_data(bl);
274
275 backlight_device_unregister(bl);
276 kfree(data);
277 return 0;
278}
279
280static struct platform_driver pm860x_backlight_driver = {
281 .driver = {
282 .name = "88pm860x-backlight",
283 .owner = THIS_MODULE,
284 },
285 .probe = pm860x_backlight_probe,
286 .remove = pm860x_backlight_remove,
287};
288
289static int __init pm860x_backlight_init(void)
290{
291 return platform_driver_register(&pm860x_backlight_driver);
292}
293module_init(pm860x_backlight_init);
294
295static void __exit pm860x_backlight_exit(void)
296{
297 platform_driver_unregister(&pm860x_backlight_driver);
298}
299module_exit(pm860x_backlight_exit);
300
301MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606");
302MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
303MODULE_LICENSE("GPL");
304MODULE_ALIAS("platform:88pm860x-backlight");
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 09bfa9662e4d..0c77fc610212 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -212,6 +212,13 @@ config BACKLIGHT_DA903X
212 If you have a LCD backlight connected to the WLED output of DA9030 212 If you have a LCD backlight connected to the WLED output of DA9030
213 or DA9034 WLED output, say Y here to enable this driver. 213 or DA9034 WLED output, say Y here to enable this driver.
214 214
215config BACKLIGHT_MAX8925
216 tristate "Backlight driver for MAX8925"
217 depends on BACKLIGHT_CLASS_DEVICE && MFD_MAX8925
218 help
219 If you have a LCD backlight connected to the WLED output of MAX8925
220 WLED output, say Y here to enable this driver.
221
215config BACKLIGHT_MBP_NVIDIA 222config BACKLIGHT_MBP_NVIDIA
216 tristate "MacBook Pro Nvidia Backlight Driver" 223 tristate "MacBook Pro Nvidia Backlight Driver"
217 depends on BACKLIGHT_CLASS_DEVICE && X86 224 depends on BACKLIGHT_CLASS_DEVICE && X86
@@ -262,3 +269,9 @@ config BACKLIGHT_ADP5520
262 To compile this driver as a module, choose M here: the module will 269 To compile this driver as a module, choose M here: the module will
263 be called adp5520_bl. 270 be called adp5520_bl.
264 271
272config BACKLIGHT_88PM860X
273 tristate "Backlight Driver for 88PM8606 using WLED"
274 depends on BACKLIGHT_CLASS_DEVICE && MFD_88PM860X
275 help
276 Say Y to enable the backlight driver for Marvell 88PM8606.
277
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 9a405548874c..6c704d41462d 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -22,10 +22,12 @@ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
22obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o 22obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
23obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o 23obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
24obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o 24obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
25obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
25obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o 26obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
26obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o 27obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
27obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o 28obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
28obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o 29obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
29obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o 30obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o
30obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o 31obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
32obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
31 33
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
new file mode 100644
index 000000000000..c267069a52a3
--- /dev/null
+++ b/drivers/video/backlight/max8925_bl.c
@@ -0,0 +1,200 @@
1/*
2 * Backlight driver for Maxim MAX8925
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/fb.h>
16#include <linux/i2c.h>
17#include <linux/backlight.h>
18#include <linux/mfd/max8925.h>
19
20#define MAX_BRIGHTNESS (0xff)
21#define MIN_BRIGHTNESS (0)
22
23#define LWX_FREQ(x) (((x - 601) / 100) & 0x7)
24
25struct max8925_backlight_data {
26 struct max8925_chip *chip;
27
28 int current_brightness;
29};
30
31static int max8925_backlight_set(struct backlight_device *bl, int brightness)
32{
33 struct max8925_backlight_data *data = bl_get_data(bl);
34 struct max8925_chip *chip = data->chip;
35 unsigned char value;
36 int ret;
37
38 if (brightness > MAX_BRIGHTNESS)
39 value = MAX_BRIGHTNESS;
40 else
41 value = brightness;
42
43 ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
44 if (ret < 0)
45 goto out;
46
47 if (!data->current_brightness && brightness)
48 /* enable WLED output */
49 ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
50 else if (!brightness)
51 /* disable WLED output */
52 ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
53 if (ret < 0)
54 goto out;
55 dev_dbg(chip->dev, "set brightness %d\n", value);
56 data->current_brightness = value;
57 return 0;
58out:
59 dev_dbg(chip->dev, "set brightness %d failure with return value:%d\n",
60 value, ret);
61 return ret;
62}
63
64static int max8925_backlight_update_status(struct backlight_device *bl)
65{
66 int brightness = bl->props.brightness;
67
68 if (bl->props.power != FB_BLANK_UNBLANK)
69 brightness = 0;
70
71 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
72 brightness = 0;
73
74 if (bl->props.state & BL_CORE_SUSPENDED)
75 brightness = 0;
76
77 return max8925_backlight_set(bl, brightness);
78}
79
80static int max8925_backlight_get_brightness(struct backlight_device *bl)
81{
82 struct max8925_backlight_data *data = bl_get_data(bl);
83 struct max8925_chip *chip = data->chip;
84 int ret;
85
86 ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL);
87 if (ret < 0)
88 return -EINVAL;
89 data->current_brightness = ret;
90 dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
91 return ret;
92}
93
94static struct backlight_ops max8925_backlight_ops = {
95 .options = BL_CORE_SUSPENDRESUME,
96 .update_status = max8925_backlight_update_status,
97 .get_brightness = max8925_backlight_get_brightness,
98};
99
100static int __devinit max8925_backlight_probe(struct platform_device *pdev)
101{
102 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
103 struct max8925_platform_data *max8925_pdata;
104 struct max8925_backlight_pdata *pdata = NULL;
105 struct max8925_backlight_data *data;
106 struct backlight_device *bl;
107 struct resource *res;
108 char name[MAX8925_NAME_SIZE];
109 unsigned char value;
110 int ret;
111
112 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
113 if (res == NULL) {
114 dev_err(&pdev->dev, "No I/O resource!\n");
115 return -EINVAL;
116 }
117
118 if (pdev->dev.parent->platform_data) {
119 max8925_pdata = pdev->dev.parent->platform_data;
120 pdata = max8925_pdata->backlight;
121 }
122
123 if (!pdata) {
124 dev_err(&pdev->dev, "platform data isn't assigned to "
125 "backlight\n");
126 return -EINVAL;
127 }
128
129 data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL);
130 if (data == NULL)
131 return -ENOMEM;
132 strncpy(name, res->name, MAX8925_NAME_SIZE);
133 data->chip = chip;
134 data->current_brightness = 0;
135
136 bl = backlight_device_register(name, &pdev->dev, data,
137 &max8925_backlight_ops);
138 if (IS_ERR(bl)) {
139 dev_err(&pdev->dev, "failed to register backlight\n");
140 kfree(data);
141 return PTR_ERR(bl);
142 }
143 bl->props.max_brightness = MAX_BRIGHTNESS;
144 bl->props.brightness = MAX_BRIGHTNESS;
145
146 platform_set_drvdata(pdev, bl);
147
148 value = 0;
149 if (pdata->lxw_scl)
150 value |= (1 << 7);
151 if (pdata->lxw_freq)
152 value |= (LWX_FREQ(pdata->lxw_freq) << 4);
153 if (pdata->dual_string)
154 value |= (1 << 1);
155 ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
156 if (ret < 0)
157 goto out;
158
159 backlight_update_status(bl);
160 return 0;
161out:
162 kfree(data);
163 return ret;
164}
165
166static int __devexit max8925_backlight_remove(struct platform_device *pdev)
167{
168 struct backlight_device *bl = platform_get_drvdata(pdev);
169 struct max8925_backlight_data *data = bl_get_data(bl);
170
171 backlight_device_unregister(bl);
172 kfree(data);
173 return 0;
174}
175
176static struct platform_driver max8925_backlight_driver = {
177 .driver = {
178 .name = "max8925-backlight",
179 .owner = THIS_MODULE,
180 },
181 .probe = max8925_backlight_probe,
182 .remove = __devexit_p(max8925_backlight_remove),
183};
184
185static int __init max8925_backlight_init(void)
186{
187 return platform_driver_register(&max8925_backlight_driver);
188}
189module_init(max8925_backlight_init);
190
191static void __exit max8925_backlight_exit(void)
192{
193 platform_driver_unregister(&max8925_backlight_driver);
194};
195module_exit(max8925_backlight_exit);
196
197MODULE_DESCRIPTION("Backlight Driver for Maxim MAX8925");
198MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
199MODULE_LICENSE("GPL");
200MODULE_ALIAS("platform:max8925-backlight");
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fc7d9bbb548c..8e8f18d29d7a 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -37,6 +37,7 @@ config VGACON_SOFT_SCROLLBACK
37config VGACON_SOFT_SCROLLBACK_SIZE 37config VGACON_SOFT_SCROLLBACK_SIZE
38 int "Scrollback Buffer Size (in KB)" 38 int "Scrollback Buffer Size (in KB)"
39 depends on VGACON_SOFT_SCROLLBACK 39 depends on VGACON_SOFT_SCROLLBACK
40 range 1 1024
40 default "64" 41 default "64"
41 help 42 help
42 Enter the amount of System RAM to allocate for the scrollback 43 Enter the amount of System RAM to allocate for the scrollback
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3681c6a88212..b0a3fa00706d 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -3025,6 +3025,20 @@ static int fbcon_fb_unregistered(struct fb_info *info)
3025 return 0; 3025 return 0;
3026} 3026}
3027 3027
3028static void fbcon_remap_all(int idx)
3029{
3030 int i;
3031 for (i = first_fb_vc; i <= last_fb_vc; i++)
3032 set_con2fb_map(i, idx, 0);
3033
3034 if (con_is_bound(&fb_con)) {
3035 printk(KERN_INFO "fbcon: Remapping primary device, "
3036 "fb%i, to tty %i-%i\n", idx,
3037 first_fb_vc + 1, last_fb_vc + 1);
3038 info_idx = idx;
3039 }
3040}
3041
3028#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY 3042#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
3029static void fbcon_select_primary(struct fb_info *info) 3043static void fbcon_select_primary(struct fb_info *info)
3030{ 3044{
@@ -3225,6 +3239,10 @@ static int fbcon_event_notify(struct notifier_block *self,
3225 caps = event->data; 3239 caps = event->data;
3226 fbcon_get_requirement(info, caps); 3240 fbcon_get_requirement(info, caps);
3227 break; 3241 break;
3242 case FB_EVENT_REMAP_ALL_CONSOLE:
3243 idx = info->node;
3244 fbcon_remap_all(idx);
3245 break;
3228 } 3246 }
3229done: 3247done:
3230 return ret; 3248 return ret;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index cc4bbbe44aca..182dd6f8aadd 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -112,7 +112,7 @@ static int vga_video_font_height;
112static int vga_scan_lines __read_mostly; 112static int vga_scan_lines __read_mostly;
113static unsigned int vga_rolled_over; 113static unsigned int vga_rolled_over;
114 114
115int vgacon_text_mode_force = 0; 115static int vgacon_text_mode_force;
116 116
117bool vgacon_text_force(void) 117bool vgacon_text_force(void)
118{ 118{
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index eb12182b2059..d25df51bb0d2 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -161,8 +161,17 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
161 return 0; 161 return 0;
162} 162}
163 163
164static void efifb_destroy(struct fb_info *info)
165{
166 if (info->screen_base)
167 iounmap(info->screen_base);
168 release_mem_region(info->aperture_base, info->aperture_size);
169 framebuffer_release(info);
170}
171
164static struct fb_ops efifb_ops = { 172static struct fb_ops efifb_ops = {
165 .owner = THIS_MODULE, 173 .owner = THIS_MODULE,
174 .fb_destroy = efifb_destroy,
166 .fb_setcolreg = efifb_setcolreg, 175 .fb_setcolreg = efifb_setcolreg,
167 .fb_fillrect = cfb_fillrect, 176 .fb_fillrect = cfb_fillrect,
168 .fb_copyarea = cfb_copyarea, 177 .fb_copyarea = cfb_copyarea,
@@ -281,7 +290,7 @@ static int __init efifb_probe(struct platform_device *dev)
281 info->par = NULL; 290 info->par = NULL;
282 291
283 info->aperture_base = efifb_fix.smem_start; 292 info->aperture_base = efifb_fix.smem_start;
284 info->aperture_size = size_total; 293 info->aperture_size = size_remap;
285 294
286 info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); 295 info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
287 if (!info->screen_base) { 296 if (!info->screen_base) {
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 99bbd282ce63..a15b44e9c003 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1513,7 +1513,6 @@ register_framebuffer(struct fb_info *fb_info)
1513 fb_info->fix.id, 1513 fb_info->fix.id,
1514 registered_fb[i]->fix.id); 1514 registered_fb[i]->fix.id);
1515 unregister_framebuffer(registered_fb[i]); 1515 unregister_framebuffer(registered_fb[i]);
1516 break;
1517 } 1516 }
1518 } 1517 }
1519 } 1518 }
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 72d68b3dc478..4637bcbe03a4 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1633,6 +1633,11 @@ static int __init fsl_diu_setup(char *options)
1633#endif 1633#endif
1634 1634
1635static struct of_device_id fsl_diu_match[] = { 1635static struct of_device_id fsl_diu_match[] = {
1636#ifdef CONFIG_PPC_MPC512x
1637 {
1638 .compatible = "fsl,mpc5121-diu",
1639 },
1640#endif
1636 { 1641 {
1637 .compatible = "fsl,diu", 1642 .compatible = "fsl,diu",
1638 }, 1643 },
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index d66887e8cbb1..43207cc6cc19 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -1,29 +1,33 @@
1/* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we 1/*
2 don't know how to set */ 2 * macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
3 3 * don't know how to set.
4/* (c) 1999 David Huggins-Daines <dhd@debian.org> 4 *
5 5 * (c) 1999 David Huggins-Daines <dhd@debian.org>
6 Primarily based on vesafb.c, by Gerd Knorr 6 *
7 (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de> 7 * Primarily based on vesafb.c, by Gerd Knorr
8 8 * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
9 Also uses information and code from: 9 *
10 10 * Also uses information and code from:
11 The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen 11 *
12 Mellinger, Mikael Forselius, Michael Schmitz, and others. 12 * The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
13 13 * Mellinger, Mikael Forselius, Michael Schmitz, and others.
14 valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan 14 *
15 Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven. 15 * valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
16 16 * Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
17 This code is free software. You may copy, modify, and distribute 17 *
18 it subject to the terms and conditions of the GNU General Public 18 * The VideoToolbox "Bugs" web page at
19 License, version 2, or any later version, at your convenience. */ 19 * http://rajsky.psych.nyu.edu/Tips/VideoBugs.html
20 *
21 * This code is free software. You may copy, modify, and distribute
22 * it subject to the terms and conditions of the GNU General Public
23 * License, version 2, or any later version, at your convenience.
24 */
20 25
21#include <linux/module.h> 26#include <linux/module.h>
22#include <linux/kernel.h> 27#include <linux/kernel.h>
23#include <linux/errno.h> 28#include <linux/errno.h>
24#include <linux/string.h> 29#include <linux/string.h>
25#include <linux/mm.h> 30#include <linux/mm.h>
26#include <linux/slab.h>
27#include <linux/delay.h> 31#include <linux/delay.h>
28#include <linux/nubus.h> 32#include <linux/nubus.h>
29#include <linux/init.h> 33#include <linux/init.h>
@@ -31,9 +35,6 @@
31 35
32#include <asm/setup.h> 36#include <asm/setup.h>
33#include <asm/bootinfo.h> 37#include <asm/bootinfo.h>
34#include <asm/uaccess.h>
35#include <asm/pgtable.h>
36#include <asm/irq.h>
37#include <asm/macintosh.h> 38#include <asm/macintosh.h>
38#include <asm/io.h> 39#include <asm/io.h>
39 40
@@ -44,7 +45,7 @@
44#define DAFB_BASE 0xf9800200 45#define DAFB_BASE 0xf9800200
45 46
46/* Address for the built-in Civic framebuffer in Quadra AVs */ 47/* Address for the built-in Civic framebuffer in Quadra AVs */
47#define CIVIC_BASE 0x50f30800 /* Only tested on 660AV! */ 48#define CIVIC_BASE 0x50f30800
48 49
49/* GSC (Gray Scale Controller) base address */ 50/* GSC (Gray Scale Controller) base address */
50#define GSC_BASE 0x50F20000 51#define GSC_BASE 0x50F20000
@@ -52,37 +53,9 @@
52/* CSC (Color Screen Controller) base address */ 53/* CSC (Color Screen Controller) base address */
53#define CSC_BASE 0x50F20000 54#define CSC_BASE 0x50F20000
54 55
55static int (*macfb_setpalette) (unsigned int regno, unsigned int red, 56static int (*macfb_setpalette)(unsigned int regno, unsigned int red,
56 unsigned int green, unsigned int blue, 57 unsigned int green, unsigned int blue,
57 struct fb_info *info) = NULL; 58 struct fb_info *info);
58static int valkyrie_setpalette (unsigned int regno, unsigned int red,
59 unsigned int green, unsigned int blue,
60 struct fb_info *info);
61static int dafb_setpalette (unsigned int regno, unsigned int red,
62 unsigned int green, unsigned int blue,
63 struct fb_info *fb_info);
64static int rbv_setpalette (unsigned int regno, unsigned int red,
65 unsigned int green, unsigned int blue,
66 struct fb_info *fb_info);
67static int mdc_setpalette (unsigned int regno, unsigned int red,
68 unsigned int green, unsigned int blue,
69 struct fb_info *fb_info);
70static int toby_setpalette (unsigned int regno, unsigned int red,
71 unsigned int green, unsigned int blue,
72 struct fb_info *fb_info);
73static int civic_setpalette (unsigned int regno, unsigned int red,
74 unsigned int green, unsigned int blue,
75 struct fb_info *fb_info);
76static int csc_setpalette (unsigned int regno, unsigned int red,
77 unsigned int green, unsigned int blue,
78 struct fb_info *fb_info);
79
80static struct {
81 unsigned char addr;
82 /* Note: word-aligned */
83 char pad[3];
84 unsigned char lut;
85} __iomem *valkyrie_cmap_regs;
86 59
87static struct { 60static struct {
88 unsigned char addr; 61 unsigned char addr;
@@ -116,15 +89,15 @@ static struct {
116} __iomem *civic_cmap_regs; 89} __iomem *civic_cmap_regs;
117 90
118static struct { 91static struct {
119 char pad1[0x40]; 92 char pad1[0x40];
120 unsigned char clut_waddr; /* 0x40 */ 93 unsigned char clut_waddr; /* 0x40 */
121 char pad2; 94 char pad2;
122 unsigned char clut_data; /* 0x42 */ 95 unsigned char clut_data; /* 0x42 */
123 char pad3[0x3]; 96 char pad3[0x3];
124 unsigned char clut_raddr; /* 0x46 */ 97 unsigned char clut_raddr; /* 0x46 */
125} __iomem *csc_cmap_regs; 98} __iomem *csc_cmap_regs;
126 99
127/* We will leave these the way they are for the time being */ 100/* The registers in these structs are in NuBus slot space */
128struct mdc_cmap_regs { 101struct mdc_cmap_regs {
129 char pad1[0x200200]; 102 char pad1[0x200200];
130 unsigned char addr; 103 unsigned char addr;
@@ -145,13 +118,10 @@ struct jet_cmap_regs {
145 unsigned char lut; 118 unsigned char lut;
146}; 119};
147 120
148#define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */ 121#define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */
149
150/* mode */
151static int video_slot = 0;
152 122
153static struct fb_var_screeninfo macfb_defined = { 123static struct fb_var_screeninfo macfb_defined = {
154 .bits_per_pixel = 8, 124 .bits_per_pixel = 8,
155 .activate = FB_ACTIVATE_NOW, 125 .activate = FB_ACTIVATE_NOW,
156 .width = -1, 126 .width = -1,
157 .height = -1, 127 .height = -1,
@@ -167,181 +137,152 @@ static struct fb_fix_screeninfo macfb_fix = {
167 .accel = FB_ACCEL_NONE, 137 .accel = FB_ACCEL_NONE,
168}; 138};
169 139
140static void *slot_addr;
170static struct fb_info fb_info; 141static struct fb_info fb_info;
171static u32 pseudo_palette[16]; 142static u32 pseudo_palette[16];
172static int inverse = 0; 143static int inverse;
173static int vidtest = 0; 144static int vidtest;
174 145
175static int valkyrie_setpalette (unsigned int regno, unsigned int red, 146/*
176 unsigned int green, unsigned int blue, 147 * Unlike the Valkyrie, the DAFB cannot set individual colormap
177 struct fb_info *info) 148 * registers. Therefore, we do what the MacOS driver does (no
178{ 149 * kidding!) and simply set them one by one until we hit the one we
179 unsigned long flags; 150 * want.
180 151 */
181 red >>= 8; 152static int dafb_setpalette(unsigned int regno, unsigned int red,
182 green >>= 8; 153 unsigned int green, unsigned int blue,
183 blue >>= 8; 154 struct fb_info *info)
184
185 local_irq_save(flags);
186
187 /* tell clut which address to fill */
188 nubus_writeb(regno, &valkyrie_cmap_regs->addr);
189 nop();
190
191 /* send one color channel at a time */
192 nubus_writeb(red, &valkyrie_cmap_regs->lut);
193 nop();
194 nubus_writeb(green, &valkyrie_cmap_regs->lut);
195 nop();
196 nubus_writeb(blue, &valkyrie_cmap_regs->lut);
197
198 local_irq_restore(flags);
199 return 0;
200}
201
202/* Unlike the Valkyrie, the DAFB cannot set individual colormap
203 registers. Therefore, we do what the MacOS driver does (no
204 kidding!) and simply set them one by one until we hit the one we
205 want. */
206static int dafb_setpalette (unsigned int regno, unsigned int red,
207 unsigned int green, unsigned int blue,
208 struct fb_info *info)
209{ 155{
210 /* FIXME: really, really need to use ioremap() here,
211 phys_to_virt() doesn't work anymore */
212 static int lastreg = -1; 156 static int lastreg = -1;
213 unsigned long flags; 157 unsigned long flags;
214
215 red >>= 8;
216 green >>= 8;
217 blue >>= 8;
218 158
219 local_irq_save(flags); 159 local_irq_save(flags);
220 160
221 /* fbdev will set an entire colourmap, but X won't. Hopefully 161 /*
222 this should accommodate both of them */ 162 * fbdev will set an entire colourmap, but X won't. Hopefully
223 if (regno != lastreg+1) { 163 * this should accommodate both of them
164 */
165 if (regno != lastreg + 1) {
224 int i; 166 int i;
225 167
226 /* Stab in the dark trying to reset the CLUT pointer */ 168 /* Stab in the dark trying to reset the CLUT pointer */
227 nubus_writel(0, &dafb_cmap_regs->reset); 169 nubus_writel(0, &dafb_cmap_regs->reset);
228 nop(); 170 nop();
229 171
230 /* Loop until we get to the register we want */ 172 /* Loop until we get to the register we want */
231 for (i = 0; i < regno; i++) { 173 for (i = 0; i < regno; i++) {
232 nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut); 174 nubus_writeb(info->cmap.red[i] >> 8,
175 &dafb_cmap_regs->lut);
233 nop(); 176 nop();
234 nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut); 177 nubus_writeb(info->cmap.green[i] >> 8,
178 &dafb_cmap_regs->lut);
235 nop(); 179 nop();
236 nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut); 180 nubus_writeb(info->cmap.blue[i] >> 8,
181 &dafb_cmap_regs->lut);
237 nop(); 182 nop();
238 } 183 }
239 } 184 }
240 185
241 nubus_writeb(red, &dafb_cmap_regs->lut); 186 nubus_writeb(red, &dafb_cmap_regs->lut);
242 nop(); 187 nop();
243 nubus_writeb(green, &dafb_cmap_regs->lut); 188 nubus_writeb(green, &dafb_cmap_regs->lut);
244 nop(); 189 nop();
245 nubus_writeb(blue, &dafb_cmap_regs->lut); 190 nubus_writeb(blue, &dafb_cmap_regs->lut);
246 191
247 local_irq_restore(flags); 192 local_irq_restore(flags);
248 lastreg = regno; 193 lastreg = regno;
249 return 0; 194 return 0;
250} 195}
251 196
252/* V8 and Brazil seem to use the same DAC. Sonora does as well. */ 197/* V8 and Brazil seem to use the same DAC. Sonora does as well. */
253static int v8_brazil_setpalette (unsigned int regno, unsigned int red, 198static int v8_brazil_setpalette(unsigned int regno, unsigned int red,
254 unsigned int green, unsigned int blue, 199 unsigned int green, unsigned int blue,
255 struct fb_info *info) 200 struct fb_info *info)
256{ 201{
257 unsigned int bpp = info->var.bits_per_pixel; 202 unsigned int bpp = info->var.bits_per_pixel;
258 unsigned char _red =red>>8;
259 unsigned char _green=green>>8;
260 unsigned char _blue =blue>>8;
261 unsigned char _regno;
262 unsigned long flags; 203 unsigned long flags;
263 204
264 if (bpp > 8) return 1; /* failsafe */ 205 if (bpp > 8)
206 return 1; /* failsafe */
265 207
266 local_irq_save(flags); 208 local_irq_save(flags);
267 209
268 /* On these chips, the CLUT register numbers are spread out 210 /* On these chips, the CLUT register numbers are spread out
269 across the register space. Thus: 211 * across the register space. Thus:
270 212 * In 8bpp, all regnos are valid.
271 In 8bpp, all regnos are valid. 213 * In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
272 214 * In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff
273 In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc 215 */
274 216 regno = (regno << (8 - bpp)) | (0xFF >> bpp);
275 In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */ 217 nubus_writeb(regno, &v8_brazil_cmap_regs->addr);
276 _regno = (regno << (8 - bpp)) | (0xFF >> bpp); 218 nop();
277 nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
278 219
279 /* send one color channel at a time */ 220 /* send one color channel at a time */
280 nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop(); 221 nubus_writeb(red, &v8_brazil_cmap_regs->lut);
281 nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop(); 222 nop();
282 nubus_writeb(_blue, &v8_brazil_cmap_regs->lut); 223 nubus_writeb(green, &v8_brazil_cmap_regs->lut);
224 nop();
225 nubus_writeb(blue, &v8_brazil_cmap_regs->lut);
283 226
284 local_irq_restore(flags); 227 local_irq_restore(flags);
285 return 0; 228 return 0;
286} 229}
287 230
288static int rbv_setpalette (unsigned int regno, unsigned int red, 231/* RAM-Based Video */
289 unsigned int green, unsigned int blue, 232static int rbv_setpalette(unsigned int regno, unsigned int red,
290 struct fb_info *info) 233 unsigned int green, unsigned int blue,
234 struct fb_info *info)
291{ 235{
292 /* use MSBs */
293 unsigned char _red =red>>8;
294 unsigned char _green=green>>8;
295 unsigned char _blue =blue>>8;
296 unsigned char _regno;
297 unsigned long flags; 236 unsigned long flags;
298 237
299 if (info->var.bits_per_pixel > 8) return 1; /* failsafe */ 238 if (info->var.bits_per_pixel > 8)
239 return 1; /* failsafe */
300 240
301 local_irq_save(flags); 241 local_irq_save(flags);
302 242
303 /* From the VideoToolbox driver. Seems to be saying that 243 /* From the VideoToolbox driver. Seems to be saying that
304 * regno #254 and #255 are the important ones for 1-bit color, 244 * regno #254 and #255 are the important ones for 1-bit color,
305 * regno #252-255 are the important ones for 2-bit color, etc. 245 * regno #252-255 are the important ones for 2-bit color, etc.
306 */ 246 */
307 _regno = regno + (256-(1 << info->var.bits_per_pixel)); 247 regno += 256 - (1 << info->var.bits_per_pixel);
308 248
309 /* reset clut? (VideoToolbox sez "not necessary") */ 249 /* reset clut? (VideoToolbox sez "not necessary") */
310 nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop(); 250 nubus_writeb(0xFF, &rbv_cmap_regs->cntl);
311 251 nop();
252
312 /* tell clut which address to use. */ 253 /* tell clut which address to use. */
313 nubus_writeb(_regno, &rbv_cmap_regs->addr); nop(); 254 nubus_writeb(regno, &rbv_cmap_regs->addr);
314 255 nop();
256
315 /* send one color channel at a time. */ 257 /* send one color channel at a time. */
316 nubus_writeb(_red, &rbv_cmap_regs->lut); nop(); 258 nubus_writeb(red, &rbv_cmap_regs->lut);
317 nubus_writeb(_green, &rbv_cmap_regs->lut); nop(); 259 nop();
318 nubus_writeb(_blue, &rbv_cmap_regs->lut); 260 nubus_writeb(green, &rbv_cmap_regs->lut);
319 261 nop();
320 local_irq_restore(flags); /* done. */ 262 nubus_writeb(blue, &rbv_cmap_regs->lut);
263
264 local_irq_restore(flags);
321 return 0; 265 return 0;
322} 266}
323 267
324/* Macintosh Display Card (8x24) */ 268/* Macintosh Display Card (8*24) */
325static int mdc_setpalette(unsigned int regno, unsigned int red, 269static int mdc_setpalette(unsigned int regno, unsigned int red,
326 unsigned int green, unsigned int blue, 270 unsigned int green, unsigned int blue,
327 struct fb_info *info) 271 struct fb_info *info)
328{ 272{
329 volatile struct mdc_cmap_regs *cmap_regs = 273 struct mdc_cmap_regs *cmap_regs = slot_addr;
330 nubus_slot_addr(video_slot);
331 /* use MSBs */
332 unsigned char _red =red>>8;
333 unsigned char _green=green>>8;
334 unsigned char _blue =blue>>8;
335 unsigned char _regno=regno;
336 unsigned long flags; 274 unsigned long flags;
337 275
338 local_irq_save(flags); 276 local_irq_save(flags);
339 277
340 /* the nop's are there to order writes. */ 278 /* the nop's are there to order writes. */
341 nubus_writeb(_regno, &cmap_regs->addr); nop(); 279 nubus_writeb(regno, &cmap_regs->addr);
342 nubus_writeb(_red, &cmap_regs->lut); nop(); 280 nop();
343 nubus_writeb(_green, &cmap_regs->lut); nop(); 281 nubus_writeb(red, &cmap_regs->lut);
344 nubus_writeb(_blue, &cmap_regs->lut); 282 nop();
283 nubus_writeb(green, &cmap_regs->lut);
284 nop();
285 nubus_writeb(blue, &cmap_regs->lut);
345 286
346 local_irq_restore(flags); 287 local_irq_restore(flags);
347 return 0; 288 return 0;
@@ -350,24 +291,26 @@ static int mdc_setpalette(unsigned int regno, unsigned int red,
350/* Toby frame buffer */ 291/* Toby frame buffer */
351static int toby_setpalette(unsigned int regno, unsigned int red, 292static int toby_setpalette(unsigned int regno, unsigned int red,
352 unsigned int green, unsigned int blue, 293 unsigned int green, unsigned int blue,
353 struct fb_info *info) 294 struct fb_info *info)
354{ 295{
355 volatile struct toby_cmap_regs *cmap_regs = 296 struct toby_cmap_regs *cmap_regs = slot_addr;
356 nubus_slot_addr(video_slot);
357 unsigned int bpp = info->var.bits_per_pixel; 297 unsigned int bpp = info->var.bits_per_pixel;
358 /* use MSBs */
359 unsigned char _red =~(red>>8);
360 unsigned char _green=~(green>>8);
361 unsigned char _blue =~(blue>>8);
362 unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
363 unsigned long flags; 298 unsigned long flags;
364 299
300 red = ~red;
301 green = ~green;
302 blue = ~blue;
303 regno = (regno << (8 - bpp)) | (0xFF >> bpp);
304
365 local_irq_save(flags); 305 local_irq_save(flags);
366 306
367 nubus_writeb(_regno, &cmap_regs->addr); nop(); 307 nubus_writeb(regno, &cmap_regs->addr);
368 nubus_writeb(_red, &cmap_regs->lut); nop(); 308 nop();
369 nubus_writeb(_green, &cmap_regs->lut); nop(); 309 nubus_writeb(red, &cmap_regs->lut);
370 nubus_writeb(_blue, &cmap_regs->lut); 310 nop();
311 nubus_writeb(green, &cmap_regs->lut);
312 nop();
313 nubus_writeb(blue, &cmap_regs->lut);
371 314
372 local_irq_restore(flags); 315 local_irq_restore(flags);
373 return 0; 316 return 0;
@@ -378,20 +321,18 @@ static int jet_setpalette(unsigned int regno, unsigned int red,
378 unsigned int green, unsigned int blue, 321 unsigned int green, unsigned int blue,
379 struct fb_info *info) 322 struct fb_info *info)
380{ 323{
381 volatile struct jet_cmap_regs *cmap_regs = 324 struct jet_cmap_regs *cmap_regs = slot_addr;
382 nubus_slot_addr(video_slot);
383 /* use MSBs */
384 unsigned char _red = (red>>8);
385 unsigned char _green = (green>>8);
386 unsigned char _blue = (blue>>8);
387 unsigned long flags; 325 unsigned long flags;
388 326
389 local_irq_save(flags); 327 local_irq_save(flags);
390 328
391 nubus_writeb(regno, &cmap_regs->addr); nop(); 329 nubus_writeb(regno, &cmap_regs->addr);
392 nubus_writeb(_red, &cmap_regs->lut); nop(); 330 nop();
393 nubus_writeb(_green, &cmap_regs->lut); nop(); 331 nubus_writeb(red, &cmap_regs->lut);
394 nubus_writeb(_blue, &cmap_regs->lut); 332 nop();
333 nubus_writeb(green, &cmap_regs->lut);
334 nop();
335 nubus_writeb(blue, &cmap_regs->lut);
395 336
396 local_irq_restore(flags); 337 local_irq_restore(flags);
397 return 0; 338 return 0;
@@ -400,53 +341,27 @@ static int jet_setpalette(unsigned int regno, unsigned int red,
400/* 341/*
401 * Civic framebuffer -- Quadra AV built-in video. A chip 342 * Civic framebuffer -- Quadra AV built-in video. A chip
402 * called Sebastian holds the actual color palettes, and 343 * called Sebastian holds the actual color palettes, and
403 * apparently, there are two different banks of 512K RAM 344 * apparently, there are two different banks of 512K RAM
404 * which can act as separate framebuffers for doing video 345 * which can act as separate framebuffers for doing video
405 * input and viewing the screen at the same time! The 840AV 346 * input and viewing the screen at the same time! The 840AV
406 * Can add another 1MB RAM to give the two framebuffers 347 * Can add another 1MB RAM to give the two framebuffers
407 * 1MB RAM apiece. 348 * 1MB RAM apiece.
408 *
409 * FIXME: this doesn't seem to work anymore.
410 */ 349 */
411static int civic_setpalette (unsigned int regno, unsigned int red, 350static int civic_setpalette(unsigned int regno, unsigned int red,
412 unsigned int green, unsigned int blue, 351 unsigned int green, unsigned int blue,
413 struct fb_info *info) 352 struct fb_info *info)
414{ 353{
415 static int lastreg = -1;
416 unsigned long flags; 354 unsigned long flags;
417 int clut_status; 355 int clut_status;
418 356
419 if (info->var.bits_per_pixel > 8) return 1; /* failsafe */ 357 if (info->var.bits_per_pixel > 8)
420 358 return 1; /* failsafe */
421 red >>= 8;
422 green >>= 8;
423 blue >>= 8;
424 359
425 local_irq_save(flags); 360 local_irq_save(flags);
426
427 /*
428 * Set the register address
429 */
430 nubus_writeb(regno, &civic_cmap_regs->addr); nop();
431 361
432 /* 362 /* Set the register address */
433 * Wait for VBL interrupt here; 363 nubus_writeb(regno, &civic_cmap_regs->addr);
434 * They're usually not enabled from Penguin, so we won't check 364 nop();
435 */
436#if 0
437 {
438#define CIVIC_VBL_OFFSET 0x120
439 volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET);
440 /* do interrupt setup stuff here? */
441 *vbl = 0L; nop(); /* clear */
442 *vbl = 1L; nop(); /* set */
443 while (*vbl != 0L) /* wait for next vbl */
444 {
445 usleep(10); /* needed? */
446 }
447 /* do interrupt shutdown stuff here? */
448 }
449#endif
450 365
451 /* 366 /*
452 * Grab a status word and do some checking; 367 * Grab a status word and do some checking;
@@ -459,39 +374,52 @@ static int civic_setpalette (unsigned int regno, unsigned int red,
459#if 0 374#if 0
460 if ((clut_status & 0x000D) != 0) 375 if ((clut_status & 0x000D) != 0)
461 { 376 {
462 nubus_writeb(0x00, &civic_cmap_regs->lut); nop(); 377 nubus_writeb(0x00, &civic_cmap_regs->lut);
463 nubus_writeb(0x00, &civic_cmap_regs->lut); nop(); 378 nop();
379 nubus_writeb(0x00, &civic_cmap_regs->lut);
380 nop();
464 } 381 }
465#endif 382#endif
466 383
467 nubus_writeb( red, &civic_cmap_regs->lut); nop(); 384 nubus_writeb(red, &civic_cmap_regs->lut);
468 nubus_writeb(green, &civic_cmap_regs->lut); nop(); 385 nop();
469 nubus_writeb( blue, &civic_cmap_regs->lut); nop(); 386 nubus_writeb(green, &civic_cmap_regs->lut);
470 nubus_writeb( 0x00, &civic_cmap_regs->lut); nop(); 387 nop();
388 nubus_writeb(blue, &civic_cmap_regs->lut);
389 nop();
390 nubus_writeb(0x00, &civic_cmap_regs->lut);
471 } 391 }
472 else 392 else
473 { 393 {
474 unsigned char junk; 394 unsigned char junk;
475 395
476 junk = nubus_readb(&civic_cmap_regs->lut); nop(); 396 junk = nubus_readb(&civic_cmap_regs->lut);
477 junk = nubus_readb(&civic_cmap_regs->lut); nop(); 397 nop();
478 junk = nubus_readb(&civic_cmap_regs->lut); nop(); 398 junk = nubus_readb(&civic_cmap_regs->lut);
479 junk = nubus_readb(&civic_cmap_regs->lut); nop(); 399 nop();
400 junk = nubus_readb(&civic_cmap_regs->lut);
401 nop();
402 junk = nubus_readb(&civic_cmap_regs->lut);
403 nop();
480 404
481 if ((clut_status & 0x000D) != 0) 405 if ((clut_status & 0x000D) != 0)
482 { 406 {
483 nubus_writeb(0x00, &civic_cmap_regs->lut); nop(); 407 nubus_writeb(0x00, &civic_cmap_regs->lut);
484 nubus_writeb(0x00, &civic_cmap_regs->lut); nop(); 408 nop();
409 nubus_writeb(0x00, &civic_cmap_regs->lut);
410 nop();
485 } 411 }
486 412
487 nubus_writeb( red, &civic_cmap_regs->lut); nop(); 413 nubus_writeb(red, &civic_cmap_regs->lut);
488 nubus_writeb(green, &civic_cmap_regs->lut); nop(); 414 nop();
489 nubus_writeb( blue, &civic_cmap_regs->lut); nop(); 415 nubus_writeb(green, &civic_cmap_regs->lut);
490 nubus_writeb( junk, &civic_cmap_regs->lut); nop(); 416 nop();
417 nubus_writeb(blue, &civic_cmap_regs->lut);
418 nop();
419 nubus_writeb(junk, &civic_cmap_regs->lut);
491 } 420 }
492 421
493 local_irq_restore(flags); 422 local_irq_restore(flags);
494 lastreg = regno;
495 return 0; 423 return 0;
496} 424}
497 425
@@ -500,16 +428,21 @@ static int civic_setpalette (unsigned int regno, unsigned int red,
500 * (and the 5300 too, but that's a PowerMac). This function 428 * (and the 5300 too, but that's a PowerMac). This function
501 * brought to you in part by the ECSC driver for MkLinux. 429 * brought to you in part by the ECSC driver for MkLinux.
502 */ 430 */
503 431static int csc_setpalette(unsigned int regno, unsigned int red,
504static int csc_setpalette (unsigned int regno, unsigned int red, 432 unsigned int green, unsigned int blue,
505 unsigned int green, unsigned int blue, 433 struct fb_info *info)
506 struct fb_info *info)
507{ 434{
508 mdelay(1); 435 unsigned long flags;
436
437 local_irq_save(flags);
438
439 udelay(1); /* mklinux on PB 5300 waits for 260 ns */
509 nubus_writeb(regno, &csc_cmap_regs->clut_waddr); 440 nubus_writeb(regno, &csc_cmap_regs->clut_waddr);
510 nubus_writeb(red, &csc_cmap_regs->clut_data); 441 nubus_writeb(red, &csc_cmap_regs->clut_data);
511 nubus_writeb(green, &csc_cmap_regs->clut_data); 442 nubus_writeb(green, &csc_cmap_regs->clut_data);
512 nubus_writeb(blue, &csc_cmap_regs->clut_data); 443 nubus_writeb(blue, &csc_cmap_regs->clut_data);
444
445 local_irq_restore(flags);
513 return 0; 446 return 0;
514} 447}
515 448
@@ -518,10 +451,10 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
518 struct fb_info *fb_info) 451 struct fb_info *fb_info)
519{ 452{
520 /* 453 /*
521 * Set a single color register. The values supplied are 454 * Set a single color register. The values supplied are
522 * already rounded down to the hardware's capabilities 455 * already rounded down to the hardware's capabilities
523 * (according to the entries in the `var' structure). Return 456 * (according to the entries in the `var' structure).
524 * != 0 for invalid regno. 457 * Return non-zero for invalid regno.
525 */ 458 */
526 459
527 if (regno >= fb_info->cmap.len) 460 if (regno >= fb_info->cmap.len)
@@ -536,8 +469,8 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
536 case 4: 469 case 4:
537 case 8: 470 case 8:
538 if (macfb_setpalette) 471 if (macfb_setpalette)
539 macfb_setpalette(regno, red, green, blue, 472 macfb_setpalette(regno, red >> 8, green >> 8,
540 fb_info); 473 blue >> 8, fb_info);
541 else 474 else
542 return 1; 475 return 1;
543 break; 476 break;
@@ -555,28 +488,22 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
555 } else { 488 } else {
556 /* 0:5:6:5 */ 489 /* 0:5:6:5 */
557 ((u32*) (fb_info->pseudo_palette))[regno] = 490 ((u32*) (fb_info->pseudo_palette))[regno] =
558 ((red & 0xf800) ) | 491 ((red & 0xf800) >> 0) |
559 ((green & 0xfc00) >> 5) | 492 ((green & 0xfc00) >> 5) |
560 ((blue & 0xf800) >> 11); 493 ((blue & 0xf800) >> 11);
561 } 494 }
562 break; 495 break;
563 /* I'm pretty sure that one or the other of these 496 /*
564 doesn't exist on 68k Macs */ 497 * 24-bit colour almost doesn't exist on 68k Macs --
498 * http://support.apple.com/kb/TA28634 (Old Article: 10992)
499 */
565 case 24: 500 case 24:
566 red >>= 8;
567 green >>= 8;
568 blue >>= 8;
569 ((u32 *)(fb_info->pseudo_palette))[regno] =
570 (red << fb_info->var.red.offset) |
571 (green << fb_info->var.green.offset) |
572 (blue << fb_info->var.blue.offset);
573 break;
574 case 32: 501 case 32:
575 red >>= 8; 502 red >>= 8;
576 green >>= 8; 503 green >>= 8;
577 blue >>= 8; 504 blue >>= 8;
578 ((u32 *)(fb_info->pseudo_palette))[regno] = 505 ((u32 *)(fb_info->pseudo_palette))[regno] =
579 (red << fb_info->var.red.offset) | 506 (red << fb_info->var.red.offset) |
580 (green << fb_info->var.green.offset) | 507 (green << fb_info->var.green.offset) |
581 (blue << fb_info->var.blue.offset); 508 (blue << fb_info->var.blue.offset);
582 break; 509 break;
@@ -597,25 +524,24 @@ static struct fb_ops macfb_ops = {
597static void __init macfb_setup(char *options) 524static void __init macfb_setup(char *options)
598{ 525{
599 char *this_opt; 526 char *this_opt;
600 527
601 if (!options || !*options) 528 if (!options || !*options)
602 return; 529 return;
603 530
604 while ((this_opt = strsep(&options, ",")) != NULL) { 531 while ((this_opt = strsep(&options, ",")) != NULL) {
605 if (!*this_opt) continue; 532 if (!*this_opt)
606 533 continue;
607 if (! strcmp(this_opt, "inverse")) 534
608 inverse=1; 535 if (!strcmp(this_opt, "inverse"))
609 /* This means "turn on experimental CLUT code" */ 536 inverse = 1;
610 else if (!strcmp(this_opt, "vidtest")) 537 else
611 vidtest=1; 538 if (!strcmp(this_opt, "vidtest"))
539 vidtest = 1; /* enable experimental CLUT code */
612 } 540 }
613} 541}
614 542
615static void __init iounmap_macfb(void) 543static void __init iounmap_macfb(void)
616{ 544{
617 if (valkyrie_cmap_regs)
618 iounmap(valkyrie_cmap_regs);
619 if (dafb_cmap_regs) 545 if (dafb_cmap_regs)
620 iounmap(dafb_cmap_regs); 546 iounmap(dafb_cmap_regs);
621 if (v8_brazil_cmap_regs) 547 if (v8_brazil_cmap_regs)
@@ -642,48 +568,55 @@ static int __init macfb_init(void)
642 if (!MACH_IS_MAC) 568 if (!MACH_IS_MAC)
643 return -ENODEV; 569 return -ENODEV;
644 570
645 /* There can only be one internal video controller anyway so 571 if (mac_bi_data.id == MAC_MODEL_Q630 ||
646 we're not too worried about this */ 572 mac_bi_data.id == MAC_MODEL_P588)
573 return -ENODEV; /* See valkyriefb.c */
574
647 macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF; 575 macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
648 macfb_defined.yres = mac_bi_data.dimensions >> 16; 576 macfb_defined.yres = mac_bi_data.dimensions >> 16;
649 macfb_defined.bits_per_pixel = mac_bi_data.videodepth; 577 macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
578
650 macfb_fix.line_length = mac_bi_data.videorow; 579 macfb_fix.line_length = mac_bi_data.videorow;
651 macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres; 580 macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
652 /* Note: physical address (since 2.1.127) */ 581 /* Note: physical address (since 2.1.127) */
653 macfb_fix.smem_start = mac_bi_data.videoaddr; 582 macfb_fix.smem_start = mac_bi_data.videoaddr;
654 /* This is actually redundant with the initial mappings. 583
655 However, there are some non-obvious aspects to the way
656 those mappings are set up, so this is in fact the safest
657 way to ensure that this driver will work on every possible
658 Mac */
659 fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
660
661 printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
662 macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
663 printk("macfb: mode is %dx%dx%d, linelength=%d\n",
664 macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
665
666 /* 584 /*
667 * Fill in the available video resolution 585 * This is actually redundant with the initial mappings.
586 * However, there are some non-obvious aspects to the way
587 * those mappings are set up, so this is in fact the safest
588 * way to ensure that this driver will work on every possible Mac
668 */ 589 */
669 590 fb_info.screen_base = ioremap(mac_bi_data.videoaddr,
670 macfb_defined.xres_virtual = macfb_defined.xres; 591 macfb_fix.smem_len);
671 macfb_defined.yres_virtual = macfb_defined.yres; 592 if (!fb_info.screen_base)
672 macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres); 593 return -ENODEV;
673 macfb_defined.width = PIXEL_TO_MM(macfb_defined.xres);
674 594
675 printk("macfb: scrolling: redraw\n"); 595 printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
596 macfb_fix.smem_start, fb_info.screen_base,
597 macfb_fix.smem_len / 1024);
598 printk("macfb: mode is %dx%dx%d, linelength=%d\n",
599 macfb_defined.xres, macfb_defined.yres,
600 macfb_defined.bits_per_pixel, macfb_fix.line_length);
601
602 /* Fill in the available video resolution */
603 macfb_defined.xres_virtual = macfb_defined.xres;
676 macfb_defined.yres_virtual = macfb_defined.yres; 604 macfb_defined.yres_virtual = macfb_defined.yres;
605 macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
606 macfb_defined.width = PIXEL_TO_MM(macfb_defined.xres);
677 607
678 /* some dummy values for timing to make fbset happy */ 608 /* Some dummy values for timing to make fbset happy */
679 macfb_defined.pixclock = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres; 609 macfb_defined.pixclock = 10000000 / macfb_defined.xres *
610 1000 / macfb_defined.yres;
680 macfb_defined.left_margin = (macfb_defined.xres / 8) & 0xf8; 611 macfb_defined.left_margin = (macfb_defined.xres / 8) & 0xf8;
681 macfb_defined.hsync_len = (macfb_defined.xres / 8) & 0xf8; 612 macfb_defined.hsync_len = (macfb_defined.xres / 8) & 0xf8;
682 613
683 switch (macfb_defined.bits_per_pixel) { 614 switch (macfb_defined.bits_per_pixel) {
684 case 1: 615 case 1:
685 /* XXX: I think this will catch any program that tries 616 /*
686 to do FBIO_PUTCMAP when the visual is monochrome */ 617 * XXX: I think this will catch any program that tries
618 * to do FBIO_PUTCMAP when the visual is monochrome.
619 */
687 macfb_defined.red.length = macfb_defined.bits_per_pixel; 620 macfb_defined.red.length = macfb_defined.bits_per_pixel;
688 macfb_defined.green.length = macfb_defined.bits_per_pixel; 621 macfb_defined.green.length = macfb_defined.bits_per_pixel;
689 macfb_defined.blue.length = macfb_defined.bits_per_pixel; 622 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
@@ -708,53 +641,52 @@ static int __init macfb_init(void)
708 macfb_defined.green.length = 5; 641 macfb_defined.green.length = 5;
709 macfb_defined.blue.offset = 0; 642 macfb_defined.blue.offset = 0;
710 macfb_defined.blue.length = 5; 643 macfb_defined.blue.length = 5;
711 printk("macfb: directcolor: "
712 "size=1:5:5:5, shift=15:10:5:0\n");
713 video_cmap_len = 16; 644 video_cmap_len = 16;
714 /* Should actually be FB_VISUAL_DIRECTCOLOR, but this 645 /*
715 works too */ 646 * Should actually be FB_VISUAL_DIRECTCOLOR, but this
647 * works too
648 */
716 macfb_fix.visual = FB_VISUAL_TRUECOLOR; 649 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
717 break; 650 break;
718 case 24: 651 case 24:
719 case 32: 652 case 32:
720 /* XXX: have to test these... can any 68k Macs
721 actually do this on internal video? */
722 macfb_defined.red.offset = 16; 653 macfb_defined.red.offset = 16;
723 macfb_defined.red.length = 8; 654 macfb_defined.red.length = 8;
724 macfb_defined.green.offset = 8; 655 macfb_defined.green.offset = 8;
725 macfb_defined.green.length = 8; 656 macfb_defined.green.length = 8;
726 macfb_defined.blue.offset = 0; 657 macfb_defined.blue.offset = 0;
727 macfb_defined.blue.length = 8; 658 macfb_defined.blue.length = 8;
728 printk("macfb: truecolor: "
729 "size=0:8:8:8, shift=0:16:8:0\n");
730 video_cmap_len = 16; 659 video_cmap_len = 16;
731 macfb_fix.visual = FB_VISUAL_TRUECOLOR; 660 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
661 break;
732 default: 662 default:
733 video_cmap_len = 0; 663 video_cmap_len = 0;
734 macfb_fix.visual = FB_VISUAL_MONO01; 664 macfb_fix.visual = FB_VISUAL_MONO01;
735 printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel); 665 printk("macfb: unknown or unsupported bit depth: %d\n",
666 macfb_defined.bits_per_pixel);
736 break; 667 break;
737 } 668 }
738 669
739 /* Hardware dependent stuff */ 670 /*
740 /* We take a wild guess that if the video physical address is 671 * We take a wild guess that if the video physical address is
741 * in nubus slot space, that the nubus card is driving video. 672 * in nubus slot space, that the nubus card is driving video.
742 * Penguin really ought to tell us whether we are using internal 673 * Penguin really ought to tell us whether we are using internal
743 * video or not. 674 * video or not.
675 * Hopefully we only find one of them. Otherwise our NuBus
676 * code is really broken :-)
744 */ 677 */
745 /* Hopefully we only find one of them. Otherwise our NuBus
746 code is really broken :-) */
747 678
748 while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev)) 679 while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY,
749 != NULL) 680 NUBUS_TYPE_VIDEO, ndev)))
750 { 681 {
751 if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr 682 unsigned long base = ndev->board->slot_addr;
752 && (mac_bi_data.videoaddr < 683
753 (unsigned long)nubus_slot_addr(ndev->board->slot+1)))) 684 if (mac_bi_data.videoaddr < base ||
685 mac_bi_data.videoaddr - base > 0xFFFFFF)
754 continue; 686 continue;
687
755 video_is_nubus = 1; 688 video_is_nubus = 1;
756 /* We should probably just use the slot address... */ 689 slot_addr = (unsigned char *)base;
757 video_slot = ndev->board->slot;
758 690
759 switch(ndev->dr_hw) { 691 switch(ndev->dr_hw) {
760 case NUBUS_DRHW_APPLE_MDC: 692 case NUBUS_DRHW_APPLE_MDC:
@@ -771,7 +703,7 @@ static int __init macfb_init(void)
771 strcpy(macfb_fix.id, "Jet"); 703 strcpy(macfb_fix.id, "Jet");
772 macfb_setpalette = jet_setpalette; 704 macfb_setpalette = jet_setpalette;
773 macfb_defined.activate = FB_ACTIVATE_NOW; 705 macfb_defined.activate = FB_ACTIVATE_NOW;
774 break; 706 break;
775 default: 707 default:
776 strcpy(macfb_fix.id, "Generic NuBus"); 708 strcpy(macfb_fix.id, "Generic NuBus");
777 break; 709 break;
@@ -779,30 +711,19 @@ static int __init macfb_init(void)
779 } 711 }
780 712
781 /* If it's not a NuBus card, it must be internal video */ 713 /* If it's not a NuBus card, it must be internal video */
782 /* FIXME: this function is getting way too big. (this driver
783 is too...) */
784 if (!video_is_nubus) 714 if (!video_is_nubus)
785 switch( mac_bi_data.id ) 715 switch (mac_bi_data.id) {
786 { 716 /*
787 /* Valkyrie Quadras */ 717 * DAFB Quadras
788 case MAC_MODEL_Q630: 718 * Note: these first four have the v7 DAFB, which is
789 /* I'm not sure about this one */ 719 * known to be rather unlike the ones used in the
790 case MAC_MODEL_P588: 720 * other models
791 strcpy(macfb_fix.id, "Valkyrie"); 721 */
792 macfb_setpalette = valkyrie_setpalette;
793 macfb_defined.activate = FB_ACTIVATE_NOW;
794 valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
795 break;
796
797 /* DAFB Quadras */
798 /* Note: these first four have the v7 DAFB, which is
799 known to be rather unlike the ones used in the
800 other models */
801 case MAC_MODEL_P475: 722 case MAC_MODEL_P475:
802 case MAC_MODEL_P475F: 723 case MAC_MODEL_P475F:
803 case MAC_MODEL_P575: 724 case MAC_MODEL_P575:
804 case MAC_MODEL_Q605: 725 case MAC_MODEL_Q605:
805 726
806 case MAC_MODEL_Q800: 727 case MAC_MODEL_Q800:
807 case MAC_MODEL_Q650: 728 case MAC_MODEL_Q650:
808 case MAC_MODEL_Q610: 729 case MAC_MODEL_Q610:
@@ -817,17 +738,21 @@ static int __init macfb_init(void)
817 dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); 738 dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
818 break; 739 break;
819 740
820 /* LC II uses the V8 framebuffer */ 741 /*
742 * LC II uses the V8 framebuffer
743 */
821 case MAC_MODEL_LCII: 744 case MAC_MODEL_LCII:
822 strcpy(macfb_fix.id, "V8"); 745 strcpy(macfb_fix.id, "V8");
823 macfb_setpalette = v8_brazil_setpalette; 746 macfb_setpalette = v8_brazil_setpalette;
824 macfb_defined.activate = FB_ACTIVATE_NOW; 747 macfb_defined.activate = FB_ACTIVATE_NOW;
825 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); 748 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
826 break; 749 break;
827 750
828 /* IIvi, IIvx use the "Brazil" framebuffer (which is 751 /*
829 very much like the V8, it seems, and probably uses 752 * IIvi, IIvx use the "Brazil" framebuffer (which is
830 the same DAC) */ 753 * very much like the V8, it seems, and probably uses
754 * the same DAC)
755 */
831 case MAC_MODEL_IIVI: 756 case MAC_MODEL_IIVI:
832 case MAC_MODEL_IIVX: 757 case MAC_MODEL_IIVX:
833 case MAC_MODEL_P600: 758 case MAC_MODEL_P600:
@@ -836,12 +761,14 @@ static int __init macfb_init(void)
836 macfb_defined.activate = FB_ACTIVATE_NOW; 761 macfb_defined.activate = FB_ACTIVATE_NOW;
837 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); 762 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
838 break; 763 break;
839 764
840 /* LC III (and friends) use the Sonora framebuffer */ 765 /*
841 /* Incidentally this is also used in the non-AV models 766 * LC III (and friends) use the Sonora framebuffer
842 of the x100 PowerMacs */ 767 * Incidentally this is also used in the non-AV models
843 /* These do in fact seem to use the same DAC interface 768 * of the x100 PowerMacs
844 as the LC II. */ 769 * These do in fact seem to use the same DAC interface
770 * as the LC II.
771 */
845 case MAC_MODEL_LCIII: 772 case MAC_MODEL_LCIII:
846 case MAC_MODEL_P520: 773 case MAC_MODEL_P520:
847 case MAC_MODEL_P550: 774 case MAC_MODEL_P550:
@@ -852,9 +779,11 @@ static int __init macfb_init(void)
852 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); 779 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
853 break; 780 break;
854 781
855 /* IIci and IIsi use the infamous RBV chip 782 /*
856 (the IIsi is just a rebadged and crippled 783 * IIci and IIsi use the infamous RBV chip
857 IIci in a different case, BTW) */ 784 * (the IIsi is just a rebadged and crippled
785 * IIci in a different case, BTW)
786 */
858 case MAC_MODEL_IICI: 787 case MAC_MODEL_IICI:
859 case MAC_MODEL_IISI: 788 case MAC_MODEL_IISI:
860 macfb_setpalette = rbv_setpalette; 789 macfb_setpalette = rbv_setpalette;
@@ -863,7 +792,9 @@ static int __init macfb_init(void)
863 rbv_cmap_regs = ioremap(DAC_BASE, 0x1000); 792 rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
864 break; 793 break;
865 794
866 /* AVs use the Civic framebuffer */ 795 /*
796 * AVs use the Civic framebuffer
797 */
867 case MAC_MODEL_Q840: 798 case MAC_MODEL_Q840:
868 case MAC_MODEL_C660: 799 case MAC_MODEL_C660:
869 macfb_setpalette = civic_setpalette; 800 macfb_setpalette = civic_setpalette;
@@ -873,15 +804,10 @@ static int __init macfb_init(void)
873 break; 804 break;
874 805
875 806
876 /* Write a setpalette function for your machine, then 807 /*
877 you can add something similar here. These are 808 * Assorted weirdos
878 grouped by classes of video chipsets. Some of this 809 * We think this may be like the LC II
879 information is from the VideoToolbox "Bugs" web 810 */
880 page at
881 http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
882
883 /* Assorted weirdos */
884 /* We think this may be like the LC II */
885 case MAC_MODEL_LC: 811 case MAC_MODEL_LC:
886 if (vidtest) { 812 if (vidtest) {
887 macfb_setpalette = v8_brazil_setpalette; 813 macfb_setpalette = v8_brazil_setpalette;
@@ -891,7 +817,10 @@ static int __init macfb_init(void)
891 } 817 }
892 strcpy(macfb_fix.id, "LC"); 818 strcpy(macfb_fix.id, "LC");
893 break; 819 break;
894 /* We think this may be like the LC II */ 820
821 /*
822 * We think this may be like the LC II
823 */
895 case MAC_MODEL_CCL: 824 case MAC_MODEL_CCL:
896 if (vidtest) { 825 if (vidtest) {
897 macfb_setpalette = v8_brazil_setpalette; 826 macfb_setpalette = v8_brazil_setpalette;
@@ -902,31 +831,42 @@ static int __init macfb_init(void)
902 strcpy(macfb_fix.id, "Color Classic"); 831 strcpy(macfb_fix.id, "Color Classic");
903 break; 832 break;
904 833
905 /* And we *do* mean "weirdos" */ 834 /*
835 * And we *do* mean "weirdos"
836 */
906 case MAC_MODEL_TV: 837 case MAC_MODEL_TV:
907 strcpy(macfb_fix.id, "Mac TV"); 838 strcpy(macfb_fix.id, "Mac TV");
908 break; 839 break;
909 840
910 /* These don't have colour, so no need to worry */ 841 /*
842 * These don't have colour, so no need to worry
843 */
911 case MAC_MODEL_SE30: 844 case MAC_MODEL_SE30:
912 case MAC_MODEL_CLII: 845 case MAC_MODEL_CLII:
913 strcpy(macfb_fix.id, "Monochrome"); 846 strcpy(macfb_fix.id, "Monochrome");
914 break; 847 break;
915 848
916 /* Powerbooks are particularly difficult. Many of 849 /*
917 them have separate framebuffers for external and 850 * Powerbooks are particularly difficult. Many of
918 internal video, which is admittedly pretty cool, 851 * them have separate framebuffers for external and
919 but will be a bit of a headache to support here. 852 * internal video, which is admittedly pretty cool,
920 Also, many of them are grayscale, and we don't 853 * but will be a bit of a headache to support here.
921 really support that. */ 854 * Also, many of them are grayscale, and we don't
922 855 * really support that.
856 */
857
858 /*
859 * Slot 0 ROM says TIM. No external video. B&W.
860 */
923 case MAC_MODEL_PB140: 861 case MAC_MODEL_PB140:
924 case MAC_MODEL_PB145: 862 case MAC_MODEL_PB145:
925 case MAC_MODEL_PB170: 863 case MAC_MODEL_PB170:
926 strcpy(macfb_fix.id, "DDC"); 864 strcpy(macfb_fix.id, "DDC");
927 break; 865 break;
928 866
929 /* Internal is GSC, External (if present) is ViSC */ 867 /*
868 * Internal is GSC, External (if present) is ViSC
869 */
930 case MAC_MODEL_PB150: /* no external video */ 870 case MAC_MODEL_PB150: /* no external video */
931 case MAC_MODEL_PB160: 871 case MAC_MODEL_PB160:
932 case MAC_MODEL_PB165: 872 case MAC_MODEL_PB165:
@@ -936,13 +876,17 @@ static int __init macfb_init(void)
936 strcpy(macfb_fix.id, "GSC"); 876 strcpy(macfb_fix.id, "GSC");
937 break; 877 break;
938 878
939 /* Internal is TIM, External is ViSC */ 879 /*
880 * Internal is TIM, External is ViSC
881 */
940 case MAC_MODEL_PB165C: 882 case MAC_MODEL_PB165C:
941 case MAC_MODEL_PB180C: 883 case MAC_MODEL_PB180C:
942 strcpy(macfb_fix.id, "TIM"); 884 strcpy(macfb_fix.id, "TIM");
943 break; 885 break;
944 886
945 /* Internal is CSC, External is Keystone+Ariel. */ 887 /*
888 * Internal is CSC, External is Keystone+Ariel.
889 */
946 case MAC_MODEL_PB190: /* external video is optional */ 890 case MAC_MODEL_PB190: /* external video is optional */
947 case MAC_MODEL_PB520: 891 case MAC_MODEL_PB520:
948 case MAC_MODEL_PB250: 892 case MAC_MODEL_PB250:
@@ -954,7 +898,7 @@ static int __init macfb_init(void)
954 strcpy(macfb_fix.id, "CSC"); 898 strcpy(macfb_fix.id, "CSC");
955 csc_cmap_regs = ioremap(CSC_BASE, 0x1000); 899 csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
956 break; 900 break;
957 901
958 default: 902 default:
959 strcpy(macfb_fix.id, "Unknown"); 903 strcpy(macfb_fix.id, "Unknown");
960 break; 904 break;
@@ -969,7 +913,7 @@ static int __init macfb_init(void)
969 err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0); 913 err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
970 if (err) 914 if (err)
971 goto fail_unmap; 915 goto fail_unmap;
972 916
973 err = register_framebuffer(&fb_info); 917 err = register_framebuffer(&fb_info);
974 if (err) 918 if (err)
975 goto fail_dealloc; 919 goto fail_dealloc;
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
index 083f60321ed8..af86c081d2be 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/macmodes.c
@@ -33,6 +33,10 @@
33 33
34static const struct fb_videomode mac_modedb[] = { 34static const struct fb_videomode mac_modedb[] = {
35 { 35 {
36 /* 512x384, 60Hz, Non-Interlaced (15.67 MHz dot clock) */
37 "mac2", 60, 512, 384, 63828, 80, 16, 19, 1, 32, 3,
38 0, FB_VMODE_NONINTERLACED
39 }, {
36 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 40 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
37 "mac5", 60, 640, 480, 39722, 32, 32, 33, 10, 96, 2, 41 "mac5", 60, 640, 480, 39722, 32, 32, 33, 10, 96, 2,
38 0, FB_VMODE_NONINTERLACED 42 0, FB_VMODE_NONINTERLACED
@@ -41,6 +45,10 @@ static const struct fb_videomode mac_modedb[] = {
41 "mac6", 67, 640, 480, 33334, 80, 80, 39, 3, 64, 3, 45 "mac6", 67, 640, 480, 33334, 80, 80, 39, 3, 64, 3,
42 0, FB_VMODE_NONINTERLACED 46 0, FB_VMODE_NONINTERLACED
43 }, { 47 }, {
48 /* 640x870, 75Hz (portrait), Non-Interlaced (57.28 MHz dot clock) */
49 "mac7", 75, 640, 870, 17457, 80, 32, 42, 3, 80, 3,
50 0, FB_VMODE_NONINTERLACED
51 }, {
44 /* 800x600, 56 Hz, Non-Interlaced (36.00 MHz dotclock) */ 52 /* 800x600, 56 Hz, Non-Interlaced (36.00 MHz dotclock) */
45 "mac9", 56, 800, 600, 27778, 112, 40, 22, 1, 72, 2, 53 "mac9", 56, 800, 600, 27778, 112, 40, 22, 1, 72, 2,
46 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 54 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
@@ -105,10 +113,6 @@ static const struct fb_videomode mac_modedb[] = {
105 "mac1", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen, 113 "mac1", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen,
106 sync, FB_VMODE_INTERLACED 114 sync, FB_VMODE_INTERLACED
107 }, { 115 }, {
108 /* VMODE_512_384_60: 512x384, 60Hz, Non-Interlaced */
109 "mac2", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen,
110 sync, FB_VMODE_NONINTERLACED
111 }, {
112 /* VMODE_640_480_50I: 640x480, 50Hz, Interlaced (PAL) */ 116 /* VMODE_640_480_50I: 640x480, 50Hz, Interlaced (PAL) */
113 "mac3", 50, 640, 480, pixclock, left, right, upper, lower, hslen, vslen, 117 "mac3", 50, 640, 480, pixclock, left, right, upper, lower, hslen, vslen,
114 sync, FB_VMODE_INTERLACED 118 sync, FB_VMODE_INTERLACED
@@ -117,10 +121,6 @@ static const struct fb_videomode mac_modedb[] = {
117 "mac4", 60, 640, 480, pixclock, left, right, upper, lower, hslen, vslen, 121 "mac4", 60, 640, 480, pixclock, left, right, upper, lower, hslen, vslen,
118 sync, FB_VMODE_INTERLACED 122 sync, FB_VMODE_INTERLACED
119 }, { 123 }, {
120 /* VMODE_640_870_75P: 640x870, 75Hz (portrait), Non-Interlaced */
121 "mac7", 75, 640, 870, pixclock, left, right, upper, lower, hslen, vslen,
122 sync, FB_VMODE_NONINTERLACED
123 }, {
124 /* VMODE_768_576_50I: 768x576, 50Hz (PAL full frame), Interlaced */ 124 /* VMODE_768_576_50I: 768x576, 50Hz (PAL full frame), Interlaced */
125 "mac8", 50, 768, 576, pixclock, left, right, upper, lower, hslen, vslen, 125 "mac8", 50, 768, 576, pixclock, left, right, upper, lower, hslen, vslen,
126 sync, FB_VMODE_INTERLACED 126 sync, FB_VMODE_INTERLACED
@@ -134,38 +134,42 @@ static const struct fb_videomode mac_modedb[] = {
134 * 134 *
135 * These MUST be ordered in 135 * These MUST be ordered in
136 * - increasing resolution 136 * - increasing resolution
137 * - decreasing refresh rate 137 * - decreasing pixel clock period
138 */ 138 */
139 139
140static const struct mode_map { 140static const struct mode_map {
141 int vmode; 141 int vmode;
142 const struct fb_videomode *mode; 142 const struct fb_videomode *mode;
143} mac_modes[] = { 143} mac_modes[] = {
144 /* 512x384 */
145 { VMODE_512_384_60, &mac_modedb[0] },
144 /* 640x480 */ 146 /* 640x480 */
145 { VMODE_640_480_67, &mac_modedb[1] }, 147 { VMODE_640_480_60, &mac_modedb[1] },
146 { VMODE_640_480_60, &mac_modedb[0] }, 148 { VMODE_640_480_67, &mac_modedb[2] },
149 /* 640x870 */
150 { VMODE_640_870_75P, &mac_modedb[3] },
147 /* 800x600 */ 151 /* 800x600 */
148 { VMODE_800_600_75, &mac_modedb[5] }, 152 { VMODE_800_600_56, &mac_modedb[4] },
149 { VMODE_800_600_72, &mac_modedb[4] }, 153 { VMODE_800_600_60, &mac_modedb[5] },
150 { VMODE_800_600_60, &mac_modedb[3] }, 154 { VMODE_800_600_75, &mac_modedb[7] },
151 { VMODE_800_600_56, &mac_modedb[2] }, 155 { VMODE_800_600_72, &mac_modedb[6] },
152 /* 832x624 */ 156 /* 832x624 */
153 { VMODE_832_624_75, &mac_modedb[6] }, 157 { VMODE_832_624_75, &mac_modedb[8] },
154 /* 1024x768 */ 158 /* 1024x768 */
155 { VMODE_1024_768_75, &mac_modedb[10] }, 159 { VMODE_1024_768_60, &mac_modedb[9] },
156 { VMODE_1024_768_75V, &mac_modedb[9] }, 160 { VMODE_1024_768_70, &mac_modedb[10] },
157 { VMODE_1024_768_70, &mac_modedb[8] }, 161 { VMODE_1024_768_75V, &mac_modedb[11] },
158 { VMODE_1024_768_60, &mac_modedb[7] }, 162 { VMODE_1024_768_75, &mac_modedb[12] },
159 /* 1152x768 */ 163 /* 1152x768 */
160 { VMODE_1152_768_60, &mac_modedb[14] }, 164 { VMODE_1152_768_60, &mac_modedb[16] },
161 /* 1152x870 */ 165 /* 1152x870 */
162 { VMODE_1152_870_75, &mac_modedb[11] }, 166 { VMODE_1152_870_75, &mac_modedb[13] },
163 /* 1280x960 */ 167 /* 1280x960 */
164 { VMODE_1280_960_75, &mac_modedb[12] }, 168 { VMODE_1280_960_75, &mac_modedb[14] },
165 /* 1280x1024 */ 169 /* 1280x1024 */
166 { VMODE_1280_1024_75, &mac_modedb[13] }, 170 { VMODE_1280_1024_75, &mac_modedb[15] },
167 /* 1600x1024 */ 171 /* 1600x1024 */
168 { VMODE_1600_1024_60, &mac_modedb[15] }, 172 { VMODE_1600_1024_60, &mac_modedb[17] },
169 { -1, NULL } 173 { -1, NULL }
170}; 174};
171 175
@@ -299,7 +303,6 @@ EXPORT_SYMBOL(mac_vmode_to_var);
299int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, 303int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
300 int *cmode) 304 int *cmode)
301{ 305{
302 const struct fb_videomode *mode = NULL;
303 const struct mode_map *map; 306 const struct mode_map *map;
304 307
305 if (var->bits_per_pixel <= 8) 308 if (var->bits_per_pixel <= 8)
@@ -311,8 +314,13 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
311 else 314 else
312 return -EINVAL; 315 return -EINVAL;
313 316
317 /*
318 * Find the mac_mode with a matching resolution or failing that, the
319 * closest larger resolution. Skip modes with a shorter pixel clock period.
320 */
314 for (map = mac_modes; map->vmode != -1; map++) { 321 for (map = mac_modes; map->vmode != -1; map++) {
315 mode = map->mode; 322 const struct fb_videomode *mode = map->mode;
323
316 if (var->xres > mode->xres || var->yres > mode->yres) 324 if (var->xres > mode->xres || var->yres > mode->yres)
317 continue; 325 continue;
318 if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres) 326 if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres)
@@ -322,6 +330,24 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
322 if ((var->vmode & FB_VMODE_MASK) != mode->vmode) 330 if ((var->vmode & FB_VMODE_MASK) != mode->vmode)
323 continue; 331 continue;
324 *vmode = map->vmode; 332 *vmode = map->vmode;
333
334 /*
335 * Having found a good resolution, find the matching pixel clock
336 * or failing that, the closest longer pixel clock period.
337 */
338 map++;
339 while (map->vmode != -1) {
340 const struct fb_videomode *clk_mode = map->mode;
341
342 if (mode->xres != clk_mode->xres || mode->yres != clk_mode->yres)
343 break;
344 if (var->pixclock > mode->pixclock)
345 break;
346 if (mode->vmode != clk_mode->vmode)
347 continue;
348 *vmode = map->vmode;
349 map++;
350 }
325 return 0; 351 return 0;
326 } 352 }
327 return -EINVAL; 353 return -EINVAL;
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index 567db6ac32c8..6978ae4ef83a 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -24,6 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/lcd.h>
27 28
28#include <plat/board-ams-delta.h> 29#include <plat/board-ams-delta.h>
29#include <mach/hardware.h> 30#include <mach/hardware.h>
@@ -32,6 +33,71 @@
32 33
33#define AMS_DELTA_DEFAULT_CONTRAST 112 34#define AMS_DELTA_DEFAULT_CONTRAST 112
34 35
36#define AMS_DELTA_MAX_CONTRAST 0x00FF
37#define AMS_DELTA_LCD_POWER 0x0100
38
39
40/* LCD class device section */
41
42static int ams_delta_lcd;
43
44static int ams_delta_lcd_set_power(struct lcd_device *dev, int power)
45{
46 if (power == FB_BLANK_UNBLANK) {
47 if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) {
48 omap_writeb(ams_delta_lcd & AMS_DELTA_MAX_CONTRAST,
49 OMAP_PWL_ENABLE);
50 omap_writeb(1, OMAP_PWL_CLK_ENABLE);
51 ams_delta_lcd |= AMS_DELTA_LCD_POWER;
52 }
53 } else {
54 if (ams_delta_lcd & AMS_DELTA_LCD_POWER) {
55 omap_writeb(0, OMAP_PWL_ENABLE);
56 omap_writeb(0, OMAP_PWL_CLK_ENABLE);
57 ams_delta_lcd &= ~AMS_DELTA_LCD_POWER;
58 }
59 }
60 return 0;
61}
62
63static int ams_delta_lcd_set_contrast(struct lcd_device *dev, int value)
64{
65 if ((value >= 0) && (value <= AMS_DELTA_MAX_CONTRAST)) {
66 omap_writeb(value, OMAP_PWL_ENABLE);
67 ams_delta_lcd &= ~AMS_DELTA_MAX_CONTRAST;
68 ams_delta_lcd |= value;
69 }
70 return 0;
71}
72
73#ifdef CONFIG_LCD_CLASS_DEVICE
74static int ams_delta_lcd_get_power(struct lcd_device *dev)
75{
76 if (ams_delta_lcd & AMS_DELTA_LCD_POWER)
77 return FB_BLANK_UNBLANK;
78 else
79 return FB_BLANK_POWERDOWN;
80}
81
82static int ams_delta_lcd_get_contrast(struct lcd_device *dev)
83{
84 if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER))
85 return 0;
86
87 return ams_delta_lcd & AMS_DELTA_MAX_CONTRAST;
88}
89
90static struct lcd_ops ams_delta_lcd_ops = {
91 .get_power = ams_delta_lcd_get_power,
92 .set_power = ams_delta_lcd_set_power,
93 .get_contrast = ams_delta_lcd_get_contrast,
94 .set_contrast = ams_delta_lcd_set_contrast,
95};
96#endif
97
98
99/* omapfb panel section */
100
35static int ams_delta_panel_init(struct lcd_panel *panel, 101static int ams_delta_panel_init(struct lcd_panel *panel,
36 struct omapfb_device *fbdev) 102 struct omapfb_device *fbdev)
37{ 103{
@@ -48,10 +114,6 @@ static int ams_delta_panel_enable(struct lcd_panel *panel)
48 AMS_DELTA_LATCH2_LCD_NDISP); 114 AMS_DELTA_LATCH2_LCD_NDISP);
49 ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, 115 ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN,
50 AMS_DELTA_LATCH2_LCD_VBLEN); 116 AMS_DELTA_LATCH2_LCD_VBLEN);
51
52 omap_writeb(1, OMAP_PWL_CLK_ENABLE);
53 omap_writeb(AMS_DELTA_DEFAULT_CONTRAST, OMAP_PWL_ENABLE);
54
55 return 0; 117 return 0;
56} 118}
57 119
@@ -91,8 +153,31 @@ static struct lcd_panel ams_delta_panel = {
91 .get_caps = ams_delta_panel_get_caps, 153 .get_caps = ams_delta_panel_get_caps,
92}; 154};
93 155
156
157/* platform driver section */
158
94static int ams_delta_panel_probe(struct platform_device *pdev) 159static int ams_delta_panel_probe(struct platform_device *pdev)
95{ 160{
161 struct lcd_device *lcd_device = NULL;
162#ifdef CONFIG_LCD_CLASS_DEVICE
163 int ret;
164
165 lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL,
166 &ams_delta_lcd_ops);
167
168 if (IS_ERR(lcd_device)) {
169 ret = PTR_ERR(lcd_device);
170 dev_err(&pdev->dev, "failed to register device\n");
171 return ret;
172 }
173
174 platform_set_drvdata(pdev, lcd_device);
175 lcd_device->props.max_contrast = AMS_DELTA_MAX_CONTRAST;
176#endif
177
178 ams_delta_lcd_set_contrast(lcd_device, AMS_DELTA_DEFAULT_CONTRAST);
179 ams_delta_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
180
96 omapfb_register_panel(&ams_delta_panel); 181 omapfb_register_panel(&ams_delta_panel);
97 return 0; 182 return 0;
98} 183}
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 2c4f470fa086..8ce60e1b220a 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -486,10 +486,11 @@ static int set_color_mode(struct omapfb_plane_struct *plane,
486 return 0; 486 return 0;
487 case 12: 487 case 12:
488 var->bits_per_pixel = 16; 488 var->bits_per_pixel = 16;
489 plane->color_mode = OMAPFB_COLOR_RGB444;
490 return 0;
491 case 16: 489 case 16:
492 plane->color_mode = OMAPFB_COLOR_RGB565; 490 if (plane->fbdev->panel->bpp == 12)
491 plane->color_mode = OMAPFB_COLOR_RGB444;
492 else
493 plane->color_mode = OMAPFB_COLOR_RGB565;
493 return 0; 494 return 0;
494 default: 495 default:
495 return -EINVAL; 496 return -EINVAL;
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index b12a59c9c50a..dfb57ee50861 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -13,10 +13,28 @@ config PANEL_SHARP_LS037V7DW01
13 help 13 help
14 LCD Panel used in TI's SDP3430 and EVM boards 14 LCD Panel used in TI's SDP3430 and EVM boards
15 15
16config PANEL_SHARP_LQ043T1DG01
17 tristate "Sharp LQ043T1DG01 LCD Panel"
18 depends on OMAP2_DSS
19 help
20 LCD Panel used in TI's OMAP3517 EVM boards
21
16config PANEL_TAAL 22config PANEL_TAAL
17 tristate "Taal DSI Panel" 23 tristate "Taal DSI Panel"
18 depends on OMAP2_DSS_DSI 24 depends on OMAP2_DSS_DSI
19 help 25 help
20 Taal DSI command mode panel from TPO. 26 Taal DSI command mode panel from TPO.
21 27
28config PANEL_TOPPOLY_TDO35S
29 tristate "Toppoly TDO35S LCD Panel support"
30 depends on OMAP2_DSS
31 help
32 LCD Panel used in CM-T35
33
34config PANEL_TPO_TD043MTEA1
35 tristate "TPO TD043MTEA1 LCD Panel"
36 depends on OMAP2_DSS && I2C
37 help
38 LCD Panel used in OMAP3 Pandora
39
22endmenu 40endmenu
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index 955646440b3a..e2bb32168dee 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,4 +1,7 @@
1obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o 1obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o
2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
3obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o
3 4
4obj-$(CONFIG_PANEL_TAAL) += panel-taal.o 5obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
6obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o
7obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c
index eb48d1afd800..c59e4baed8b2 100644
--- a/drivers/video/omap2/displays/panel-generic.c
+++ b/drivers/video/omap2/displays/panel-generic.c
@@ -35,6 +35,35 @@ static struct omap_video_timings generic_panel_timings = {
35 .vbp = 7, 35 .vbp = 7,
36}; 36};
37 37
38static int generic_panel_power_on(struct omap_dss_device *dssdev)
39{
40 int r;
41
42 r = omapdss_dpi_display_enable(dssdev);
43 if (r)
44 goto err0;
45
46 if (dssdev->platform_enable) {
47 r = dssdev->platform_enable(dssdev);
48 if (r)
49 goto err1;
50 }
51
52 return 0;
53err1:
54 omapdss_dpi_display_disable(dssdev);
55err0:
56 return r;
57}
58
59static void generic_panel_power_off(struct omap_dss_device *dssdev)
60{
61 if (dssdev->platform_disable)
62 dssdev->platform_disable(dssdev);
63
64 omapdss_dpi_display_disable(dssdev);
65}
66
38static int generic_panel_probe(struct omap_dss_device *dssdev) 67static int generic_panel_probe(struct omap_dss_device *dssdev)
39{ 68{
40 dssdev->panel.config = OMAP_DSS_LCD_TFT; 69 dssdev->panel.config = OMAP_DSS_LCD_TFT;
@@ -51,27 +80,40 @@ static int generic_panel_enable(struct omap_dss_device *dssdev)
51{ 80{
52 int r = 0; 81 int r = 0;
53 82
54 if (dssdev->platform_enable) 83 r = generic_panel_power_on(dssdev);
55 r = dssdev->platform_enable(dssdev); 84 if (r)
85 return r;
56 86
57 return r; 87 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
88
89 return 0;
58} 90}
59 91
60static void generic_panel_disable(struct omap_dss_device *dssdev) 92static void generic_panel_disable(struct omap_dss_device *dssdev)
61{ 93{
62 if (dssdev->platform_disable) 94 generic_panel_power_off(dssdev);
63 dssdev->platform_disable(dssdev); 95
96 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
64} 97}
65 98
66static int generic_panel_suspend(struct omap_dss_device *dssdev) 99static int generic_panel_suspend(struct omap_dss_device *dssdev)
67{ 100{
68 generic_panel_disable(dssdev); 101 generic_panel_power_off(dssdev);
102 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
69 return 0; 103 return 0;
70} 104}
71 105
72static int generic_panel_resume(struct omap_dss_device *dssdev) 106static int generic_panel_resume(struct omap_dss_device *dssdev)
73{ 107{
74 return generic_panel_enable(dssdev); 108 int r = 0;
109
110 r = generic_panel_power_on(dssdev);
111 if (r)
112 return r;
113
114 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
115
116 return 0;
75} 117}
76 118
77static struct omap_dss_driver generic_driver = { 119static struct omap_dss_driver generic_driver = {
diff --git a/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c
new file mode 100644
index 000000000000..10267461991c
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c
@@ -0,0 +1,159 @@
1/*
2 * LCD panel driver for Sharp LQ043T1DG01
3 *
4 * Copyright (C) 2009 Texas Instruments Inc
5 * Author: Vaibhav Hiremath <hvaibhav@ti.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 version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <linux/device.h>
23#include <linux/err.h>
24
25#include <plat/display.h>
26
27static struct omap_video_timings sharp_lq_timings = {
28 .x_res = 480,
29 .y_res = 272,
30
31 .pixel_clock = 9000,
32
33 .hsw = 42,
34 .hfp = 3,
35 .hbp = 2,
36
37 .vsw = 11,
38 .vfp = 3,
39 .vbp = 2,
40};
41
42static int sharp_lq_panel_power_on(struct omap_dss_device *dssdev)
43{
44 int r;
45
46 r = omapdss_dpi_display_enable(dssdev);
47 if (r)
48 goto err0;
49
50 /* wait couple of vsyncs until enabling the LCD */
51 msleep(50);
52
53 if (dssdev->platform_enable) {
54 r = dssdev->platform_enable(dssdev);
55 if (r)
56 goto err1;
57 }
58
59 return 0;
60err1:
61 omapdss_dpi_display_disable(dssdev);
62err0:
63 return r;
64}
65
66static void sharp_lq_panel_power_off(struct omap_dss_device *dssdev)
67{
68 if (dssdev->platform_disable)
69 dssdev->platform_disable(dssdev);
70
71 /* wait at least 5 vsyncs after disabling the LCD */
72 msleep(100);
73
74 omapdss_dpi_display_disable(dssdev);
75}
76
77static int sharp_lq_panel_probe(struct omap_dss_device *dssdev)
78{
79
80 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
81 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO;
82 dssdev->panel.acb = 0x0;
83 dssdev->panel.timings = sharp_lq_timings;
84
85 return 0;
86}
87
88static void sharp_lq_panel_remove(struct omap_dss_device *dssdev)
89{
90}
91
92static int sharp_lq_panel_enable(struct omap_dss_device *dssdev)
93{
94 int r = 0;
95
96 r = sharp_lq_panel_power_on(dssdev);
97 if (r)
98 return r;
99
100 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
101
102 return 0;
103}
104
105static void sharp_lq_panel_disable(struct omap_dss_device *dssdev)
106{
107 sharp_lq_panel_power_off(dssdev);
108
109 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
110}
111
112static int sharp_lq_panel_suspend(struct omap_dss_device *dssdev)
113{
114 sharp_lq_panel_power_off(dssdev);
115 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
116 return 0;
117}
118
119static int sharp_lq_panel_resume(struct omap_dss_device *dssdev)
120{
121 int r = 0;
122
123 r = sharp_lq_panel_power_on(dssdev);
124 if (r)
125 return r;
126
127 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
128
129 return 0;
130}
131
132static struct omap_dss_driver sharp_lq_driver = {
133 .probe = sharp_lq_panel_probe,
134 .remove = sharp_lq_panel_remove,
135
136 .enable = sharp_lq_panel_enable,
137 .disable = sharp_lq_panel_disable,
138 .suspend = sharp_lq_panel_suspend,
139 .resume = sharp_lq_panel_resume,
140
141 .driver = {
142 .name = "sharp_lq_panel",
143 .owner = THIS_MODULE,
144 },
145};
146
147static int __init sharp_lq_panel_drv_init(void)
148{
149 return omap_dss_register_driver(&sharp_lq_driver);
150}
151
152static void __exit sharp_lq_panel_drv_exit(void)
153{
154 omap_dss_unregister_driver(&sharp_lq_driver);
155}
156
157module_init(sharp_lq_panel_drv_init);
158module_exit(sharp_lq_panel_drv_exit);
159MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index bbe880bbe795..8d51a5e6341c 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -20,19 +20,10 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/regulator/consumer.h>
24#include <linux/err.h> 23#include <linux/err.h>
25 24
26#include <plat/display.h> 25#include <plat/display.h>
27 26
28struct sharp_data {
29 /* XXX This regulator should actually be in SDP board file, not here,
30 * as it doesn't actually power the LCD, but something else that
31 * affects the output to LCD (I think. Somebody clarify). It doesn't do
32 * harm here, as SDP is the only board using this currently */
33 struct regulator *vdvi_reg;
34};
35
36static struct omap_video_timings sharp_ls_timings = { 27static struct omap_video_timings sharp_ls_timings = {
37 .x_res = 480, 28 .x_res = 480,
38 .y_res = 640, 29 .y_res = 640,
@@ -50,77 +41,81 @@ static struct omap_video_timings sharp_ls_timings = {
50 41
51static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) 42static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
52{ 43{
53 struct sharp_data *sd;
54
55 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | 44 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
56 OMAP_DSS_LCD_IHS; 45 OMAP_DSS_LCD_IHS;
57 dssdev->panel.acb = 0x28; 46 dssdev->panel.acb = 0x28;
58 dssdev->panel.timings = sharp_ls_timings; 47 dssdev->panel.timings = sharp_ls_timings;
59 48
60 sd = kzalloc(sizeof(*sd), GFP_KERNEL);
61 if (!sd)
62 return -ENOMEM;
63
64 dev_set_drvdata(&dssdev->dev, sd);
65
66 sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi");
67 if (IS_ERR(sd->vdvi_reg)) {
68 kfree(sd);
69 pr_err("failed to get VDVI regulator\n");
70 return PTR_ERR(sd->vdvi_reg);
71 }
72
73 return 0; 49 return 0;
74} 50}
75 51
76static void sharp_ls_panel_remove(struct omap_dss_device *dssdev) 52static void sharp_ls_panel_remove(struct omap_dss_device *dssdev)
77{ 53{
78 struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
79
80 regulator_put(sd->vdvi_reg);
81
82 kfree(sd);
83} 54}
84 55
85static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) 56static int sharp_ls_power_on(struct omap_dss_device *dssdev)
86{ 57{
87 struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
88 int r = 0; 58 int r = 0;
89 59
60 r = omapdss_dpi_display_enable(dssdev);
61 if (r)
62 goto err0;
63
90 /* wait couple of vsyncs until enabling the LCD */ 64 /* wait couple of vsyncs until enabling the LCD */
91 msleep(50); 65 msleep(50);
92 66
93 regulator_enable(sd->vdvi_reg); 67 if (dssdev->platform_enable) {
94
95 if (dssdev->platform_enable)
96 r = dssdev->platform_enable(dssdev); 68 r = dssdev->platform_enable(dssdev);
69 if (r)
70 goto err1;
71 }
97 72
73 return 0;
74err1:
75 omapdss_dpi_display_disable(dssdev);
76err0:
98 return r; 77 return r;
99} 78}
100 79
101static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) 80static void sharp_ls_power_off(struct omap_dss_device *dssdev)
102{ 81{
103 struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
104
105 if (dssdev->platform_disable) 82 if (dssdev->platform_disable)
106 dssdev->platform_disable(dssdev); 83 dssdev->platform_disable(dssdev);
107 84
108 regulator_disable(sd->vdvi_reg);
109
110 /* wait at least 5 vsyncs after disabling the LCD */ 85 /* wait at least 5 vsyncs after disabling the LCD */
111 86
112 msleep(100); 87 msleep(100);
88
89 omapdss_dpi_display_disable(dssdev);
90}
91
92static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
93{
94 int r;
95 r = sharp_ls_power_on(dssdev);
96 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
97 return r;
98}
99
100static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
101{
102 sharp_ls_power_off(dssdev);
103 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
113} 104}
114 105
115static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev) 106static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
116{ 107{
117 sharp_ls_panel_disable(dssdev); 108 sharp_ls_power_off(dssdev);
109 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
118 return 0; 110 return 0;
119} 111}
120 112
121static int sharp_ls_panel_resume(struct omap_dss_device *dssdev) 113static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
122{ 114{
123 return sharp_ls_panel_enable(dssdev); 115 int r;
116 r = sharp_ls_power_on(dssdev);
117 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
118 return r;
124} 119}
125 120
126static struct omap_dss_driver sharp_ls_driver = { 121static struct omap_dss_driver sharp_ls_driver = {
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 1f01dfc5e52e..fcd6a61a91eb 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -63,6 +63,8 @@
63/* #define TAAL_USE_ESD_CHECK */ 63/* #define TAAL_USE_ESD_CHECK */
64#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000) 64#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000)
65 65
66static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
67
66struct taal_data { 68struct taal_data {
67 struct backlight_device *bldev; 69 struct backlight_device *bldev;
68 70
@@ -510,15 +512,12 @@ static int taal_probe(struct omap_dss_device *dssdev)
510 if (td->esd_wq == NULL) { 512 if (td->esd_wq == NULL) {
511 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); 513 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
512 r = -ENOMEM; 514 r = -ENOMEM;
513 goto err2; 515 goto err1;
514 } 516 }
515 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); 517 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
516 518
517 dev_set_drvdata(&dssdev->dev, td); 519 dev_set_drvdata(&dssdev->dev, td);
518 520
519 dssdev->get_timings = taal_get_timings;
520 dssdev->get_resolution = taal_get_resolution;
521
522 /* if no platform set_backlight() defined, presume DSI backlight 521 /* if no platform set_backlight() defined, presume DSI backlight
523 * control */ 522 * control */
524 if (!dssdev->set_backlight) 523 if (!dssdev->set_backlight)
@@ -528,7 +527,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
528 &taal_bl_ops); 527 &taal_bl_ops);
529 if (IS_ERR(bldev)) { 528 if (IS_ERR(bldev)) {
530 r = PTR_ERR(bldev); 529 r = PTR_ERR(bldev);
531 goto err1; 530 goto err2;
532 } 531 }
533 532
534 td->bldev = bldev; 533 td->bldev = bldev;
@@ -621,14 +620,12 @@ static void taal_remove(struct omap_dss_device *dssdev)
621 kfree(td); 620 kfree(td);
622} 621}
623 622
624static int taal_enable(struct omap_dss_device *dssdev) 623static int taal_power_on(struct omap_dss_device *dssdev)
625{ 624{
626 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 625 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
627 u8 id1, id2, id3; 626 u8 id1, id2, id3;
628 int r; 627 int r;
629 628
630 dev_dbg(&dssdev->dev, "enable\n");
631
632 if (dssdev->platform_enable) { 629 if (dssdev->platform_enable) {
633 r = dssdev->platform_enable(dssdev); 630 r = dssdev->platform_enable(dssdev);
634 if (r) 631 if (r)
@@ -638,6 +635,16 @@ static int taal_enable(struct omap_dss_device *dssdev)
638 /* it seems we have to wait a bit until taal is ready */ 635 /* it seems we have to wait a bit until taal is ready */
639 msleep(5); 636 msleep(5);
640 637
638 dsi_bus_lock();
639
640 r = omapdss_dsi_display_enable(dssdev);
641 if (r) {
642 dev_err(&dssdev->dev, "failed to enable DSI\n");
643 goto err0;
644 }
645
646 omapdss_dsi_vc_enable_hs(TCH, false);
647
641 r = taal_sleep_out(td); 648 r = taal_sleep_out(td);
642 if (r) 649 if (r)
643 goto err; 650 goto err;
@@ -661,6 +668,10 @@ static int taal_enable(struct omap_dss_device *dssdev)
661 668
662 taal_dcs_write_0(DCS_DISPLAY_ON); 669 taal_dcs_write_0(DCS_DISPLAY_ON);
663 670
671 r = _taal_enable_te(dssdev, td->te_enabled);
672 if (r)
673 goto err;
674
664#ifdef TAAL_USE_ESD_CHECK 675#ifdef TAAL_USE_ESD_CHECK
665 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); 676 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
666#endif 677#endif
@@ -676,19 +687,27 @@ static int taal_enable(struct omap_dss_device *dssdev)
676 td->intro_printed = true; 687 td->intro_printed = true;
677 } 688 }
678 689
690 omapdss_dsi_vc_enable_hs(TCH, true);
691
692 dsi_bus_unlock();
693
679 return 0; 694 return 0;
680err: 695err:
696 dsi_bus_unlock();
697
698 omapdss_dsi_display_disable(dssdev);
699err0:
681 if (dssdev->platform_disable) 700 if (dssdev->platform_disable)
682 dssdev->platform_disable(dssdev); 701 dssdev->platform_disable(dssdev);
683 702
684 return r; 703 return r;
685} 704}
686 705
687static void taal_disable(struct omap_dss_device *dssdev) 706static void taal_power_off(struct omap_dss_device *dssdev)
688{ 707{
689 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 708 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
690 709
691 dev_dbg(&dssdev->dev, "disable\n"); 710 dsi_bus_lock();
692 711
693 cancel_delayed_work(&td->esd_work); 712 cancel_delayed_work(&td->esd_work);
694 713
@@ -698,41 +717,124 @@ static void taal_disable(struct omap_dss_device *dssdev)
698 /* wait a bit so that the message goes through */ 717 /* wait a bit so that the message goes through */
699 msleep(10); 718 msleep(10);
700 719
720 omapdss_dsi_display_disable(dssdev);
721
701 if (dssdev->platform_disable) 722 if (dssdev->platform_disable)
702 dssdev->platform_disable(dssdev); 723 dssdev->platform_disable(dssdev);
703 724
704 td->enabled = 0; 725 td->enabled = 0;
726
727 dsi_bus_unlock();
728}
729
730static int taal_enable(struct omap_dss_device *dssdev)
731{
732 int r;
733 dev_dbg(&dssdev->dev, "enable\n");
734
735 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
736 return -EINVAL;
737
738 r = taal_power_on(dssdev);
739 if (r)
740 return r;
741
742 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
743
744 return r;
745}
746
747static void taal_disable(struct omap_dss_device *dssdev)
748{
749 dev_dbg(&dssdev->dev, "disable\n");
750
751 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
752 taal_power_off(dssdev);
753
754 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
705} 755}
706 756
707static int taal_suspend(struct omap_dss_device *dssdev) 757static int taal_suspend(struct omap_dss_device *dssdev)
708{ 758{
709 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 759 dev_dbg(&dssdev->dev, "suspend\n");
710 struct backlight_device *bldev = td->bldev;
711 760
712 bldev->props.power = FB_BLANK_POWERDOWN; 761 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
713 taal_bl_update_status(bldev); 762 return -EINVAL;
763
764 taal_power_off(dssdev);
765 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
714 766
715 return 0; 767 return 0;
716} 768}
717 769
718static int taal_resume(struct omap_dss_device *dssdev) 770static int taal_resume(struct omap_dss_device *dssdev)
719{ 771{
772 int r;
773 dev_dbg(&dssdev->dev, "resume\n");
774
775 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
776 return -EINVAL;
777
778 r = taal_power_on(dssdev);
779 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
780 return r;
781}
782
783static void taal_framedone_cb(int err, void *data)
784{
785 struct omap_dss_device *dssdev = data;
786 dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
787 dsi_bus_unlock();
788}
789
790static int taal_update(struct omap_dss_device *dssdev,
791 u16 x, u16 y, u16 w, u16 h)
792{
720 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 793 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
721 struct backlight_device *bldev = td->bldev; 794 int r;
722 795
723 bldev->props.power = FB_BLANK_UNBLANK; 796 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
724 taal_bl_update_status(bldev); 797
798 dsi_bus_lock();
799
800 if (!td->enabled) {
801 r = 0;
802 goto err;
803 }
804
805 r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h);
806 if (r)
807 goto err;
808
809 r = taal_set_update_window(x, y, w, h);
810 if (r)
811 goto err;
812
813 r = omap_dsi_update(dssdev, TCH, x, y, w, h,
814 taal_framedone_cb, dssdev);
815 if (r)
816 goto err;
725 817
818 /* note: no bus_unlock here. unlock is in framedone_cb */
726 return 0; 819 return 0;
820err:
821 dsi_bus_unlock();
822 return r;
727} 823}
728 824
729static void taal_setup_update(struct omap_dss_device *dssdev, 825static int taal_sync(struct omap_dss_device *dssdev)
730 u16 x, u16 y, u16 w, u16 h)
731{ 826{
732 taal_set_update_window(x, y, w, h); 827 dev_dbg(&dssdev->dev, "sync\n");
828
829 dsi_bus_lock();
830 dsi_bus_unlock();
831
832 dev_dbg(&dssdev->dev, "sync done\n");
833
834 return 0;
733} 835}
734 836
735static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) 837static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
736{ 838{
737 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 839 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
738 int r; 840 int r;
@@ -744,25 +846,32 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
744 else 846 else
745 r = taal_dcs_write_0(DCS_TEAR_OFF); 847 r = taal_dcs_write_0(DCS_TEAR_OFF);
746 848
849 omapdss_dsi_enable_te(dssdev, enable);
850
851 /* XXX for some reason, DSI TE breaks if we don't wait here.
852 * Panel bug? Needs more studying */
853 msleep(100);
854
747 return r; 855 return r;
748} 856}
749 857
750static int taal_wait_te(struct omap_dss_device *dssdev) 858static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
751{ 859{
752 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 860 int r;
753 long wait = msecs_to_jiffies(500);
754 861
755 if (!td->use_ext_te || !td->te_enabled) 862 dsi_bus_lock();
756 return 0;
757 863
758 INIT_COMPLETION(td->te_completion); 864 r = _taal_enable_te(dssdev, enable);
759 wait = wait_for_completion_timeout(&td->te_completion, wait);
760 if (wait == 0) {
761 dev_err(&dssdev->dev, "timeout waiting TE\n");
762 return -ETIME;
763 }
764 865
765 return 0; 866 dsi_bus_unlock();
867
868 return r;
869}
870
871static int taal_get_te(struct omap_dss_device *dssdev)
872{
873 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
874 return td->te_enabled;
766} 875}
767 876
768static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) 877static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
@@ -772,16 +881,21 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
772 881
773 dev_dbg(&dssdev->dev, "rotate %d\n", rotate); 882 dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
774 883
884 dsi_bus_lock();
885
775 if (td->enabled) { 886 if (td->enabled) {
776 r = taal_set_addr_mode(rotate, td->mirror); 887 r = taal_set_addr_mode(rotate, td->mirror);
777
778 if (r) 888 if (r)
779 return r; 889 goto err;
780 } 890 }
781 891
782 td->rotate = rotate; 892 td->rotate = rotate;
783 893
894 dsi_bus_unlock();
784 return 0; 895 return 0;
896err:
897 dsi_bus_unlock();
898 return r;
785} 899}
786 900
787static u8 taal_get_rotate(struct omap_dss_device *dssdev) 901static u8 taal_get_rotate(struct omap_dss_device *dssdev)
@@ -797,16 +911,20 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
797 911
798 dev_dbg(&dssdev->dev, "mirror %d\n", enable); 912 dev_dbg(&dssdev->dev, "mirror %d\n", enable);
799 913
914 dsi_bus_lock();
800 if (td->enabled) { 915 if (td->enabled) {
801 r = taal_set_addr_mode(td->rotate, enable); 916 r = taal_set_addr_mode(td->rotate, enable);
802
803 if (r) 917 if (r)
804 return r; 918 goto err;
805 } 919 }
806 920
807 td->mirror = enable; 921 td->mirror = enable;
808 922
923 dsi_bus_unlock();
809 return 0; 924 return 0;
925err:
926 dsi_bus_unlock();
927 return r;
810} 928}
811 929
812static bool taal_get_mirror(struct omap_dss_device *dssdev) 930static bool taal_get_mirror(struct omap_dss_device *dssdev)
@@ -820,17 +938,23 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
820 u8 id1, id2, id3; 938 u8 id1, id2, id3;
821 int r; 939 int r;
822 940
941 dsi_bus_lock();
942
823 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 943 r = taal_dcs_read_1(DCS_GET_ID1, &id1);
824 if (r) 944 if (r)
825 return r; 945 goto err;
826 r = taal_dcs_read_1(DCS_GET_ID2, &id2); 946 r = taal_dcs_read_1(DCS_GET_ID2, &id2);
827 if (r) 947 if (r)
828 return r; 948 goto err;
829 r = taal_dcs_read_1(DCS_GET_ID3, &id3); 949 r = taal_dcs_read_1(DCS_GET_ID3, &id3);
830 if (r) 950 if (r)
831 return r; 951 goto err;
832 952
953 dsi_bus_unlock();
833 return 0; 954 return 0;
955err:
956 dsi_bus_unlock();
957 return r;
834} 958}
835 959
836static int taal_memory_read(struct omap_dss_device *dssdev, 960static int taal_memory_read(struct omap_dss_device *dssdev,
@@ -841,6 +965,10 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
841 int first = 1; 965 int first = 1;
842 int plen; 966 int plen;
843 unsigned buf_used = 0; 967 unsigned buf_used = 0;
968 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
969
970 if (!td->enabled)
971 return -ENODEV;
844 972
845 if (size < w * h * 3) 973 if (size < w * h * 3)
846 return -ENOMEM; 974 return -ENOMEM;
@@ -849,6 +977,8 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
849 dssdev->panel.timings.x_res * 977 dssdev->panel.timings.x_res *
850 dssdev->panel.timings.y_res * 3); 978 dssdev->panel.timings.y_res * 3);
851 979
980 dsi_bus_lock();
981
852 /* plen 1 or 2 goes into short packet. until checksum error is fixed, 982 /* plen 1 or 2 goes into short packet. until checksum error is fixed,
853 * use short packets. plen 32 works, but bigger packets seem to cause 983 * use short packets. plen 32 works, but bigger packets seem to cause
854 * an error. */ 984 * an error. */
@@ -857,11 +987,11 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
857 else 987 else
858 plen = 2; 988 plen = 2;
859 989
860 taal_setup_update(dssdev, x, y, w, h); 990 taal_set_update_window(x, y, w, h);
861 991
862 r = dsi_vc_set_max_rx_packet_size(TCH, plen); 992 r = dsi_vc_set_max_rx_packet_size(TCH, plen);
863 if (r) 993 if (r)
864 return r; 994 goto err0;
865 995
866 while (buf_used < size) { 996 while (buf_used < size) {
867 u8 dcs_cmd = first ? 0x2e : 0x3e; 997 u8 dcs_cmd = first ? 0x2e : 0x3e;
@@ -894,7 +1024,8 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
894 1024
895err: 1025err:
896 dsi_vc_set_max_rx_packet_size(TCH, 1); 1026 dsi_vc_set_max_rx_packet_size(TCH, 1);
897 1027err0:
1028 dsi_bus_unlock();
898 return r; 1029 return r;
899} 1030}
900 1031
@@ -939,8 +1070,11 @@ static void taal_esd_work(struct work_struct *work)
939 } 1070 }
940 /* Self-diagnostics result is also shown on TE GPIO line. We need 1071 /* Self-diagnostics result is also shown on TE GPIO line. We need
941 * to re-enable TE after self diagnostics */ 1072 * to re-enable TE after self diagnostics */
942 if (td->use_ext_te && td->te_enabled) 1073 if (td->use_ext_te && td->te_enabled) {
943 taal_enable_te(dssdev, true); 1074 r = taal_dcs_write_1(DCS_TEAR_ON, 0);
1075 if (r)
1076 goto err;
1077 }
944 1078
945 dsi_bus_unlock(); 1079 dsi_bus_unlock();
946 1080
@@ -958,6 +1092,20 @@ err:
958 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); 1092 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
959} 1093}
960 1094
1095static int taal_set_update_mode(struct omap_dss_device *dssdev,
1096 enum omap_dss_update_mode mode)
1097{
1098 if (mode != OMAP_DSS_UPDATE_MANUAL)
1099 return -EINVAL;
1100 return 0;
1101}
1102
1103static enum omap_dss_update_mode taal_get_update_mode(
1104 struct omap_dss_device *dssdev)
1105{
1106 return OMAP_DSS_UPDATE_MANUAL;
1107}
1108
961static struct omap_dss_driver taal_driver = { 1109static struct omap_dss_driver taal_driver = {
962 .probe = taal_probe, 1110 .probe = taal_probe,
963 .remove = taal_remove, 1111 .remove = taal_remove,
@@ -967,9 +1115,18 @@ static struct omap_dss_driver taal_driver = {
967 .suspend = taal_suspend, 1115 .suspend = taal_suspend,
968 .resume = taal_resume, 1116 .resume = taal_resume,
969 1117
970 .setup_update = taal_setup_update, 1118 .set_update_mode = taal_set_update_mode,
1119 .get_update_mode = taal_get_update_mode,
1120
1121 .update = taal_update,
1122 .sync = taal_sync,
1123
1124 .get_resolution = taal_get_resolution,
1125 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1126
971 .enable_te = taal_enable_te, 1127 .enable_te = taal_enable_te,
972 .wait_for_te = taal_wait_te, 1128 .get_te = taal_get_te,
1129
973 .set_rotate = taal_rotate, 1130 .set_rotate = taal_rotate,
974 .get_rotate = taal_get_rotate, 1131 .get_rotate = taal_get_rotate,
975 .set_mirror = taal_mirror, 1132 .set_mirror = taal_mirror,
@@ -977,6 +1134,8 @@ static struct omap_dss_driver taal_driver = {
977 .run_test = taal_run_test, 1134 .run_test = taal_run_test,
978 .memory_read = taal_memory_read, 1135 .memory_read = taal_memory_read,
979 1136
1137 .get_timings = taal_get_timings,
1138
980 .driver = { 1139 .driver = {
981 .name = "taal", 1140 .name = "taal",
982 .owner = THIS_MODULE, 1141 .owner = THIS_MODULE,
diff --git a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
new file mode 100644
index 000000000000..fa434ca6e4b7
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
@@ -0,0 +1,154 @@
1/*
2 * LCD panel driver for Toppoly TDO35S
3 *
4 * Copyright (C) 2009 CompuLab, Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on generic panel support
8 * Copyright (C) 2008 Nokia Corporation
9 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published by
13 * the Free Software Foundation.
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/delay.h>
26
27#include <plat/display.h>
28
29static struct omap_video_timings toppoly_tdo_panel_timings = {
30 /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
31 .x_res = 480,
32 .y_res = 640,
33
34 .pixel_clock = 26000,
35
36 .hfp = 104,
37 .hsw = 8,
38 .hbp = 8,
39
40 .vfp = 4,
41 .vsw = 2,
42 .vbp = 2,
43};
44
45static int toppoly_tdo_panel_power_on(struct omap_dss_device *dssdev)
46{
47 int r;
48
49 r = omapdss_dpi_display_enable(dssdev);
50 if (r)
51 goto err0;
52
53 if (dssdev->platform_enable) {
54 r = dssdev->platform_enable(dssdev);
55 if (r)
56 goto err1;
57 }
58
59 return 0;
60err1:
61 omapdss_dpi_display_disable(dssdev);
62err0:
63 return r;
64}
65
66static void toppoly_tdo_panel_power_off(struct omap_dss_device *dssdev)
67{
68 if (dssdev->platform_disable)
69 dssdev->platform_disable(dssdev);
70
71 omapdss_dpi_display_disable(dssdev);
72}
73
74static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev)
75{
76 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
77 OMAP_DSS_LCD_IHS;
78 dssdev->panel.timings = toppoly_tdo_panel_timings;
79
80 return 0;
81}
82
83static void toppoly_tdo_panel_remove(struct omap_dss_device *dssdev)
84{
85}
86
87static int toppoly_tdo_panel_enable(struct omap_dss_device *dssdev)
88{
89 int r = 0;
90
91 r = toppoly_tdo_panel_power_on(dssdev);
92 if (r)
93 return r;
94
95 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
96
97 return 0;
98}
99
100static void toppoly_tdo_panel_disable(struct omap_dss_device *dssdev)
101{
102 toppoly_tdo_panel_power_off(dssdev);
103
104 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
105}
106
107static int toppoly_tdo_panel_suspend(struct omap_dss_device *dssdev)
108{
109 toppoly_tdo_panel_power_off(dssdev);
110 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
111 return 0;
112}
113
114static int toppoly_tdo_panel_resume(struct omap_dss_device *dssdev)
115{
116 int r = 0;
117
118 r = toppoly_tdo_panel_power_on(dssdev);
119 if (r)
120 return r;
121
122 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
123
124 return 0;
125}
126
127static struct omap_dss_driver generic_driver = {
128 .probe = toppoly_tdo_panel_probe,
129 .remove = toppoly_tdo_panel_remove,
130
131 .enable = toppoly_tdo_panel_enable,
132 .disable = toppoly_tdo_panel_disable,
133 .suspend = toppoly_tdo_panel_suspend,
134 .resume = toppoly_tdo_panel_resume,
135
136 .driver = {
137 .name = "toppoly_tdo35s_panel",
138 .owner = THIS_MODULE,
139 },
140};
141
142static int __init toppoly_tdo_panel_drv_init(void)
143{
144 return omap_dss_register_driver(&generic_driver);
145}
146
147static void __exit toppoly_tdo_panel_drv_exit(void)
148{
149 omap_dss_unregister_driver(&generic_driver);
150}
151
152module_init(toppoly_tdo_panel_drv_init);
153module_exit(toppoly_tdo_panel_drv_exit);
154MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
new file mode 100644
index 000000000000..d578feee3550
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -0,0 +1,528 @@
1/*
2 * LCD panel driver for TPO TD043MTEA1
3 *
4 * Author: Gražvydas Ignotas <notasas@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/delay.h>
14#include <linux/spi/spi.h>
15#include <linux/regulator/consumer.h>
16#include <linux/gpio.h>
17#include <linux/err.h>
18
19#include <plat/display.h>
20
21#define TPO_R02_MODE(x) ((x) & 7)
22#define TPO_R02_MODE_800x480 7
23#define TPO_R02_NCLK_RISING BIT(3)
24#define TPO_R02_HSYNC_HIGH BIT(4)
25#define TPO_R02_VSYNC_HIGH BIT(5)
26
27#define TPO_R03_NSTANDBY BIT(0)
28#define TPO_R03_EN_CP_CLK BIT(1)
29#define TPO_R03_EN_VGL_PUMP BIT(2)
30#define TPO_R03_EN_PWM BIT(3)
31#define TPO_R03_DRIVING_CAP_100 BIT(4)
32#define TPO_R03_EN_PRE_CHARGE BIT(6)
33#define TPO_R03_SOFTWARE_CTL BIT(7)
34
35#define TPO_R04_NFLIP_H BIT(0)
36#define TPO_R04_NFLIP_V BIT(1)
37#define TPO_R04_CP_CLK_FREQ_1H BIT(2)
38#define TPO_R04_VGL_FREQ_1H BIT(4)
39
40#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \
41 TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \
42 TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
43 TPO_R03_SOFTWARE_CTL)
44
45#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \
46 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
47
48static const u16 tpo_td043_def_gamma[12] = {
49 106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020
50};
51
52struct tpo_td043_device {
53 struct spi_device *spi;
54 struct regulator *vcc_reg;
55 u16 gamma[12];
56 u32 mode;
57 u32 hmirror:1;
58 u32 vmirror:1;
59};
60
61static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
62{
63 struct spi_message m;
64 struct spi_transfer xfer;
65 u16 w;
66 int r;
67
68 spi_message_init(&m);
69
70 memset(&xfer, 0, sizeof(xfer));
71
72 w = ((u16)addr << 10) | (1 << 8) | data;
73 xfer.tx_buf = &w;
74 xfer.bits_per_word = 16;
75 xfer.len = 2;
76 spi_message_add_tail(&xfer, &m);
77
78 r = spi_sync(spi, &m);
79 if (r < 0)
80 dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r);
81 return r;
82}
83
84static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12])
85{
86 u8 i, val;
87
88 /* gamma bits [9:8] */
89 for (val = i = 0; i < 4; i++)
90 val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
91 tpo_td043_write(spi, 0x11, val);
92
93 for (val = i = 0; i < 4; i++)
94 val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2);
95 tpo_td043_write(spi, 0x12, val);
96
97 for (val = i = 0; i < 4; i++)
98 val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2);
99 tpo_td043_write(spi, 0x13, val);
100
101 /* gamma bits [7:0] */
102 for (val = i = 0; i < 12; i++)
103 tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff);
104}
105
106static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
107{
108 u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \
109 TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
110 if (h)
111 reg4 &= ~TPO_R04_NFLIP_H;
112 if (v)
113 reg4 &= ~TPO_R04_NFLIP_V;
114
115 return tpo_td043_write(spi, 4, reg4);
116}
117
118static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
119{
120 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
121
122 tpo_td043->hmirror = enable;
123 return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
124 tpo_td043->vmirror);
125}
126
127static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
128{
129 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
130
131 return tpo_td043->hmirror;
132}
133
134static ssize_t tpo_td043_vmirror_show(struct device *dev,
135 struct device_attribute *attr, char *buf)
136{
137 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
138
139 return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror);
140}
141
142static ssize_t tpo_td043_vmirror_store(struct device *dev,
143 struct device_attribute *attr, const char *buf, size_t count)
144{
145 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
146 long val;
147 int ret;
148
149 ret = strict_strtol(buf, 0, &val);
150 if (ret < 0)
151 return ret;
152
153 ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val);
154 if (ret < 0)
155 return ret;
156
157 tpo_td043->vmirror = val;
158
159 return count;
160}
161
162static ssize_t tpo_td043_mode_show(struct device *dev,
163 struct device_attribute *attr, char *buf)
164{
165 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
166
167 return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode);
168}
169
170static ssize_t tpo_td043_mode_store(struct device *dev,
171 struct device_attribute *attr, const char *buf, size_t count)
172{
173 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
174 long val;
175 int ret;
176
177 ret = strict_strtol(buf, 0, &val);
178 if (ret != 0 || val & ~7)
179 return -EINVAL;
180
181 tpo_td043->mode = val;
182
183 val |= TPO_R02_NCLK_RISING;
184 tpo_td043_write(tpo_td043->spi, 2, val);
185
186 return count;
187}
188
189static ssize_t tpo_td043_gamma_show(struct device *dev,
190 struct device_attribute *attr, char *buf)
191{
192 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
193 ssize_t len = 0;
194 int ret;
195 int i;
196
197 for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) {
198 ret = snprintf(buf + len, PAGE_SIZE - len, "%u ",
199 tpo_td043->gamma[i]);
200 if (ret < 0)
201 return ret;
202 len += ret;
203 }
204 buf[len - 1] = '\n';
205
206 return len;
207}
208
209static ssize_t tpo_td043_gamma_store(struct device *dev,
210 struct device_attribute *attr, const char *buf, size_t count)
211{
212 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
213 unsigned int g[12];
214 int ret;
215 int i;
216
217 ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u",
218 &g[0], &g[1], &g[2], &g[3], &g[4], &g[5],
219 &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]);
220
221 if (ret != 12)
222 return -EINVAL;
223
224 for (i = 0; i < 12; i++)
225 tpo_td043->gamma[i] = g[i];
226
227 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
228
229 return count;
230}
231
232static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR,
233 tpo_td043_vmirror_show, tpo_td043_vmirror_store);
234static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
235 tpo_td043_mode_show, tpo_td043_mode_store);
236static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR,
237 tpo_td043_gamma_show, tpo_td043_gamma_store);
238
239static struct attribute *tpo_td043_attrs[] = {
240 &dev_attr_vmirror.attr,
241 &dev_attr_mode.attr,
242 &dev_attr_gamma.attr,
243 NULL,
244};
245
246static struct attribute_group tpo_td043_attr_group = {
247 .attrs = tpo_td043_attrs,
248};
249
250static const struct omap_video_timings tpo_td043_timings = {
251 .x_res = 800,
252 .y_res = 480,
253
254 .pixel_clock = 36000,
255
256 .hsw = 1,
257 .hfp = 68,
258 .hbp = 214,
259
260 .vsw = 1,
261 .vfp = 39,
262 .vbp = 34,
263};
264
265static int tpo_td043_power_on(struct omap_dss_device *dssdev)
266{
267 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
268 int nreset_gpio = dssdev->reset_gpio;
269 int r;
270
271 r = omapdss_dpi_display_enable(dssdev);
272 if (r)
273 goto err0;
274
275 if (dssdev->platform_enable) {
276 r = dssdev->platform_enable(dssdev);
277 if (r)
278 goto err1;
279 }
280
281 regulator_enable(tpo_td043->vcc_reg);
282
283 /* wait for power up */
284 msleep(160);
285
286 if (gpio_is_valid(nreset_gpio))
287 gpio_set_value(nreset_gpio, 1);
288
289 tpo_td043_write(tpo_td043->spi, 2,
290 TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING);
291 tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL);
292 tpo_td043_write(tpo_td043->spi, 0x20, 0xf0);
293 tpo_td043_write(tpo_td043->spi, 0x21, 0xf0);
294 tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
295 tpo_td043->vmirror);
296 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
297
298 return 0;
299err1:
300 omapdss_dpi_display_disable(dssdev);
301err0:
302 return r;
303}
304
305static void tpo_td043_power_off(struct omap_dss_device *dssdev)
306{
307 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
308 int nreset_gpio = dssdev->reset_gpio;
309
310 tpo_td043_write(tpo_td043->spi, 3,
311 TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
312
313 if (gpio_is_valid(nreset_gpio))
314 gpio_set_value(nreset_gpio, 0);
315
316 /* wait for at least 2 vsyncs before cutting off power */
317 msleep(50);
318
319 tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY);
320
321 regulator_disable(tpo_td043->vcc_reg);
322
323 if (dssdev->platform_disable)
324 dssdev->platform_disable(dssdev);
325
326 omapdss_dpi_display_disable(dssdev);
327}
328
329static int tpo_td043_enable(struct omap_dss_device *dssdev)
330{
331 int ret;
332
333 dev_dbg(&dssdev->dev, "enable\n");
334
335 ret = tpo_td043_power_on(dssdev);
336 if (ret)
337 return ret;
338
339 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
340
341 return 0;
342}
343
344static void tpo_td043_disable(struct omap_dss_device *dssdev)
345{
346 dev_dbg(&dssdev->dev, "disable\n");
347
348 tpo_td043_power_off(dssdev);
349
350 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
351}
352
353static int tpo_td043_suspend(struct omap_dss_device *dssdev)
354{
355 tpo_td043_power_off(dssdev);
356 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
357 return 0;
358}
359
360static int tpo_td043_resume(struct omap_dss_device *dssdev)
361{
362 int r = 0;
363
364 r = tpo_td043_power_on(dssdev);
365 if (r)
366 return r;
367
368 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
369
370 return 0;
371}
372
373static int tpo_td043_probe(struct omap_dss_device *dssdev)
374{
375 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
376 int nreset_gpio = dssdev->reset_gpio;
377 int ret = 0;
378
379 dev_dbg(&dssdev->dev, "probe\n");
380
381 if (tpo_td043 == NULL) {
382 dev_err(&dssdev->dev, "missing tpo_td043_device\n");
383 return -ENODEV;
384 }
385
386 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS |
387 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC;
388 dssdev->panel.timings = tpo_td043_timings;
389 dssdev->ctrl.pixel_size = 24;
390
391 tpo_td043->mode = TPO_R02_MODE_800x480;
392 memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma));
393
394 tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc");
395 if (IS_ERR(tpo_td043->vcc_reg)) {
396 dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n");
397 ret = PTR_ERR(tpo_td043->vcc_reg);
398 goto fail_regulator;
399 }
400
401 if (gpio_is_valid(nreset_gpio)) {
402 ret = gpio_request(nreset_gpio, "lcd reset");
403 if (ret < 0) {
404 dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
405 goto fail_gpio_req;
406 }
407
408 ret = gpio_direction_output(nreset_gpio, 0);
409 if (ret < 0) {
410 dev_err(&dssdev->dev, "couldn't set GPIO direction\n");
411 goto fail_gpio_direction;
412 }
413 }
414
415 ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
416 if (ret)
417 dev_warn(&dssdev->dev, "failed to create sysfs files\n");
418
419 return 0;
420
421fail_gpio_direction:
422 gpio_free(nreset_gpio);
423fail_gpio_req:
424 regulator_put(tpo_td043->vcc_reg);
425fail_regulator:
426 kfree(tpo_td043);
427 return ret;
428}
429
430static void tpo_td043_remove(struct omap_dss_device *dssdev)
431{
432 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
433 int nreset_gpio = dssdev->reset_gpio;
434
435 dev_dbg(&dssdev->dev, "remove\n");
436
437 sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
438 regulator_put(tpo_td043->vcc_reg);
439 if (gpio_is_valid(nreset_gpio))
440 gpio_free(nreset_gpio);
441}
442
443static struct omap_dss_driver tpo_td043_driver = {
444 .probe = tpo_td043_probe,
445 .remove = tpo_td043_remove,
446
447 .enable = tpo_td043_enable,
448 .disable = tpo_td043_disable,
449 .suspend = tpo_td043_suspend,
450 .resume = tpo_td043_resume,
451 .set_mirror = tpo_td043_set_hmirror,
452 .get_mirror = tpo_td043_get_hmirror,
453
454 .driver = {
455 .name = "tpo_td043mtea1_panel",
456 .owner = THIS_MODULE,
457 },
458};
459
460static int tpo_td043_spi_probe(struct spi_device *spi)
461{
462 struct omap_dss_device *dssdev = spi->dev.platform_data;
463 struct tpo_td043_device *tpo_td043;
464 int ret;
465
466 if (dssdev == NULL) {
467 dev_err(&spi->dev, "missing dssdev\n");
468 return -ENODEV;
469 }
470
471 spi->bits_per_word = 16;
472 spi->mode = SPI_MODE_0;
473
474 ret = spi_setup(spi);
475 if (ret < 0) {
476 dev_err(&spi->dev, "spi_setup failed: %d\n", ret);
477 return ret;
478 }
479
480 tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL);
481 if (tpo_td043 == NULL)
482 return -ENOMEM;
483
484 tpo_td043->spi = spi;
485 dev_set_drvdata(&spi->dev, tpo_td043);
486 dev_set_drvdata(&dssdev->dev, tpo_td043);
487
488 omap_dss_register_driver(&tpo_td043_driver);
489
490 return 0;
491}
492
493static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
494{
495 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev);
496
497 omap_dss_unregister_driver(&tpo_td043_driver);
498 kfree(tpo_td043);
499
500 return 0;
501}
502
503static struct spi_driver tpo_td043_spi_driver = {
504 .driver = {
505 .name = "tpo_td043mtea1_panel_spi",
506 .bus = &spi_bus_type,
507 .owner = THIS_MODULE,
508 },
509 .probe = tpo_td043_spi_probe,
510 .remove = __devexit_p(tpo_td043_spi_remove),
511};
512
513static int __init tpo_td043_init(void)
514{
515 return spi_register_driver(&tpo_td043_spi_driver);
516}
517
518static void __exit tpo_td043_exit(void)
519{
520 spi_unregister_driver(&tpo_td043_spi_driver);
521}
522
523module_init(tpo_td043_init);
524module_exit(tpo_td043_exit);
525
526MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
527MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
528MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index c63ce767b277..87afb81b2c44 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -30,19 +30,29 @@ config OMAP2_DSS_COLLECT_IRQ_STATS
30 depends on OMAP2_DSS_DEBUG_SUPPORT 30 depends on OMAP2_DSS_DEBUG_SUPPORT
31 default n 31 default n
32 help 32 help
33 Collect DSS IRQ statistics, printable via debugfs 33 Collect DSS IRQ statistics, printable via debugfs.
34
35 The statistics can be found from
36 <debugfs>/omapdss/dispc_irq for DISPC interrupts, and
37 <debugfs>/omapdss/dsi_irq for DSI interrupts.
34 38
35config OMAP2_DSS_RFBI 39config OMAP2_DSS_RFBI
36 bool "RFBI support" 40 bool "RFBI support"
37 default n 41 default n
38 help 42 help
39 MIPI DBI, or RFBI (Remote Framebuffer Interface), support. 43 MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas
44 Instrument's terminology).
45
46 DBI is a bus between the host processor and a peripheral,
47 such as a display or a framebuffer chip.
48
49 See http://www.mipi.org/ for DBI spesifications.
40 50
41config OMAP2_DSS_VENC 51config OMAP2_DSS_VENC
42 bool "VENC support" 52 bool "VENC support"
43 default y 53 default y
44 help 54 help
45 OMAP Video Encoder support. 55 OMAP Video Encoder support for S-Video and composite TV-out.
46 56
47config OMAP2_DSS_SDI 57config OMAP2_DSS_SDI
48 bool "SDI support" 58 bool "SDI support"
@@ -51,12 +61,20 @@ config OMAP2_DSS_SDI
51 help 61 help
52 SDI (Serial Display Interface) support. 62 SDI (Serial Display Interface) support.
53 63
64 SDI is a high speed one-way display serial bus between the host
65 processor and a display.
66
54config OMAP2_DSS_DSI 67config OMAP2_DSS_DSI
55 bool "DSI support" 68 bool "DSI support"
56 depends on ARCH_OMAP3 69 depends on ARCH_OMAP3
57 default n 70 default n
58 help 71 help
59 MIPI DSI support. 72 MIPI DSI (Display Serial Interface) support.
73
74 DSI is a high speed half-duplex serial interface between the host
75 processor and a peripheral, such as a display or a framebuffer chip.
76
77 See http://www.mipi.org/ for DSI spesifications.
60 78
61config OMAP2_DSS_USE_DSI_PLL 79config OMAP2_DSS_USE_DSI_PLL
62 bool "Use DSI PLL for PCLK (EXPERIMENTAL)" 80 bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 82918eec6d2e..7ebe50b335ed 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -31,6 +31,7 @@
31#include <linux/debugfs.h> 31#include <linux/debugfs.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/regulator/consumer.h>
34 35
35#include <plat/display.h> 36#include <plat/display.h>
36#include <plat/clock.h> 37#include <plat/clock.h>
@@ -47,6 +48,10 @@ static struct {
47 struct clk *dss_54m_fck; 48 struct clk *dss_54m_fck;
48 struct clk *dss_96m_fck; 49 struct clk *dss_96m_fck;
49 unsigned num_clks_enabled; 50 unsigned num_clks_enabled;
51
52 struct regulator *vdds_dsi_reg;
53 struct regulator *vdds_sdi_reg;
54 struct regulator *vdda_dac_reg;
50} core; 55} core;
51 56
52static void dss_clk_enable_all_no_ctx(void); 57static void dss_clk_enable_all_no_ctx(void);
@@ -284,9 +289,11 @@ static void dss_clk_enable_no_ctx(enum dss_clock clks)
284 289
285void dss_clk_enable(enum dss_clock clks) 290void dss_clk_enable(enum dss_clock clks)
286{ 291{
292 bool check_ctx = core.num_clks_enabled == 0;
293
287 dss_clk_enable_no_ctx(clks); 294 dss_clk_enable_no_ctx(clks);
288 295
289 if (cpu_is_omap34xx() && dss_need_ctx_restore()) 296 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
290 restore_all_ctx(); 297 restore_all_ctx();
291} 298}
292 299
@@ -352,6 +359,50 @@ static void dss_clk_disable_all(void)
352 dss_clk_disable(clks); 359 dss_clk_disable(clks);
353} 360}
354 361
362/* REGULATORS */
363
364struct regulator *dss_get_vdds_dsi(void)
365{
366 struct regulator *reg;
367
368 if (core.vdds_dsi_reg != NULL)
369 return core.vdds_dsi_reg;
370
371 reg = regulator_get(&core.pdev->dev, "vdds_dsi");
372 if (!IS_ERR(reg))
373 core.vdds_dsi_reg = reg;
374
375 return reg;
376}
377
378struct regulator *dss_get_vdds_sdi(void)
379{
380 struct regulator *reg;
381
382 if (core.vdds_sdi_reg != NULL)
383 return core.vdds_sdi_reg;
384
385 reg = regulator_get(&core.pdev->dev, "vdds_sdi");
386 if (!IS_ERR(reg))
387 core.vdds_sdi_reg = reg;
388
389 return reg;
390}
391
392struct regulator *dss_get_vdda_dac(void)
393{
394 struct regulator *reg;
395
396 if (core.vdda_dac_reg != NULL)
397 return core.vdda_dac_reg;
398
399 reg = regulator_get(&core.pdev->dev, "vdda_dac");
400 if (!IS_ERR(reg))
401 core.vdda_dac_reg = reg;
402
403 return reg;
404}
405
355/* DEBUGFS */ 406/* DEBUGFS */
356#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 407#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
357static void dss_debug_dump_clocks(struct seq_file *s) 408static void dss_debug_dump_clocks(struct seq_file *s)
@@ -397,10 +448,12 @@ static int dss_initialize_debugfs(void)
397 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, 448 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
398 &dss_debug_dump_clocks, &dss_debug_fops); 449 &dss_debug_dump_clocks, &dss_debug_fops);
399 450
451#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
400 debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, 452 debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir,
401 &dispc_dump_irqs, &dss_debug_fops); 453 &dispc_dump_irqs, &dss_debug_fops);
454#endif
402 455
403#ifdef CONFIG_OMAP2_DSS_DSI 456#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
404 debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, 457 debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir,
405 &dsi_dump_irqs, &dss_debug_fops); 458 &dsi_dump_irqs, &dss_debug_fops);
406#endif 459#endif
@@ -473,7 +526,7 @@ static int omap_dss_probe(struct platform_device *pdev)
473 } 526 }
474#endif 527#endif
475 528
476 r = dpi_init(); 529 r = dpi_init(pdev);
477 if (r) { 530 if (r) {
478 DSSERR("Failed to initialize dpi\n"); 531 DSSERR("Failed to initialize dpi\n");
479 goto fail0; 532 goto fail0;
@@ -718,16 +771,14 @@ static int dss_driver_probe(struct device *dev)
718 771
719 dss_init_device(core.pdev, dssdev); 772 dss_init_device(core.pdev, dssdev);
720 773
721 /* skip this if the device is behind a ctrl */ 774 force = pdata->default_device == dssdev;
722 if (!dssdev->panel.ctrl) { 775 dss_recheck_connections(dssdev, force);
723 force = pdata->default_device == dssdev;
724 dss_recheck_connections(dssdev, force);
725 }
726 776
727 r = dssdrv->probe(dssdev); 777 r = dssdrv->probe(dssdev);
728 778
729 if (r) { 779 if (r) {
730 DSSERR("driver probe failed: %d\n", r); 780 DSSERR("driver probe failed: %d\n", r);
781 dss_uninit_device(core.pdev, dssdev);
731 return r; 782 return r;
732 } 783 }
733 784
@@ -760,6 +811,13 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
760 dssdriver->driver.bus = &dss_bus_type; 811 dssdriver->driver.bus = &dss_bus_type;
761 dssdriver->driver.probe = dss_driver_probe; 812 dssdriver->driver.probe = dss_driver_probe;
762 dssdriver->driver.remove = dss_driver_remove; 813 dssdriver->driver.remove = dss_driver_remove;
814
815 if (dssdriver->get_resolution == NULL)
816 dssdriver->get_resolution = omapdss_default_get_resolution;
817 if (dssdriver->get_recommended_bpp == NULL)
818 dssdriver->get_recommended_bpp =
819 omapdss_default_get_recommended_bpp;
820
763 return driver_register(&dssdriver->driver); 821 return driver_register(&dssdriver->driver);
764} 822}
765EXPORT_SYMBOL(omap_dss_register_driver); 823EXPORT_SYMBOL(omap_dss_register_driver);
@@ -808,8 +866,6 @@ static void omap_dss_dev_release(struct device *dev)
808int omap_dss_register_device(struct omap_dss_device *dssdev) 866int omap_dss_register_device(struct omap_dss_device *dssdev)
809{ 867{
810 static int dev_num; 868 static int dev_num;
811 static int panel_num;
812 int r;
813 869
814 WARN_ON(!dssdev->driver_name); 870 WARN_ON(!dssdev->driver_name);
815 871
@@ -818,36 +874,12 @@ int omap_dss_register_device(struct omap_dss_device *dssdev)
818 dssdev->dev.parent = &dss_bus; 874 dssdev->dev.parent = &dss_bus;
819 dssdev->dev.release = omap_dss_dev_release; 875 dssdev->dev.release = omap_dss_dev_release;
820 dev_set_name(&dssdev->dev, "display%d", dev_num++); 876 dev_set_name(&dssdev->dev, "display%d", dev_num++);
821 r = device_register(&dssdev->dev); 877 return device_register(&dssdev->dev);
822 if (r)
823 return r;
824
825 if (dssdev->ctrl.panel) {
826 struct omap_dss_device *panel = dssdev->ctrl.panel;
827
828 panel->panel.ctrl = dssdev;
829
830 reset_device(&panel->dev, 1);
831 panel->dev.bus = &dss_bus_type;
832 panel->dev.parent = &dssdev->dev;
833 panel->dev.release = omap_dss_dev_release;
834 dev_set_name(&panel->dev, "panel%d", panel_num++);
835 r = device_register(&panel->dev);
836 if (r)
837 return r;
838 }
839
840 return 0;
841} 878}
842 879
843void omap_dss_unregister_device(struct omap_dss_device *dssdev) 880void omap_dss_unregister_device(struct omap_dss_device *dssdev)
844{ 881{
845 device_unregister(&dssdev->dev); 882 device_unregister(&dssdev->dev);
846
847 if (dssdev->ctrl.panel) {
848 struct omap_dss_device *panel = dssdev->ctrl.panel;
849 device_unregister(&panel->dev);
850 }
851} 883}
852 884
853/* BUS */ 885/* BUS */
@@ -901,6 +933,21 @@ static int __init omap_dss_init(void)
901 933
902static void __exit omap_dss_exit(void) 934static void __exit omap_dss_exit(void)
903{ 935{
936 if (core.vdds_dsi_reg != NULL) {
937 regulator_put(core.vdds_dsi_reg);
938 core.vdds_dsi_reg = NULL;
939 }
940
941 if (core.vdds_sdi_reg != NULL) {
942 regulator_put(core.vdds_sdi_reg);
943 core.vdds_sdi_reg = NULL;
944 }
945
946 if (core.vdda_dac_reg != NULL) {
947 regulator_put(core.vdda_dac_reg);
948 core.vdda_dac_reg = NULL;
949 }
950
904 platform_driver_unregister(&omap_dss_driver); 951 platform_driver_unregister(&omap_dss_driver);
905 952
906 omap_dss_bus_unregister(); 953 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index de8bfbac9e26..e777e352dbcd 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1725,7 +1725,7 @@ static void _enable_lcd_out(bool enable)
1725 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); 1725 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
1726} 1726}
1727 1727
1728void dispc_enable_lcd_out(bool enable) 1728static void dispc_enable_lcd_out(bool enable)
1729{ 1729{
1730 struct completion frame_done_completion; 1730 struct completion frame_done_completion;
1731 bool is_on; 1731 bool is_on;
@@ -1772,7 +1772,7 @@ static void _enable_digit_out(bool enable)
1772 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1); 1772 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
1773} 1773}
1774 1774
1775void dispc_enable_digit_out(bool enable) 1775static void dispc_enable_digit_out(bool enable)
1776{ 1776{
1777 struct completion frame_done_completion; 1777 struct completion frame_done_completion;
1778 int r; 1778 int r;
@@ -1836,6 +1836,26 @@ void dispc_enable_digit_out(bool enable)
1836 enable_clocks(0); 1836 enable_clocks(0);
1837} 1837}
1838 1838
1839bool dispc_is_channel_enabled(enum omap_channel channel)
1840{
1841 if (channel == OMAP_DSS_CHANNEL_LCD)
1842 return !!REG_GET(DISPC_CONTROL, 0, 0);
1843 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1844 return !!REG_GET(DISPC_CONTROL, 1, 1);
1845 else
1846 BUG();
1847}
1848
1849void dispc_enable_channel(enum omap_channel channel, bool enable)
1850{
1851 if (channel == OMAP_DSS_CHANNEL_LCD)
1852 dispc_enable_lcd_out(enable);
1853 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1854 dispc_enable_digit_out(enable);
1855 else
1856 BUG();
1857}
1858
1839void dispc_lcd_enable_signal_polarity(bool act_high) 1859void dispc_lcd_enable_signal_polarity(bool act_high)
1840{ 1860{
1841 enable_clocks(1); 1861 enable_clocks(1);
@@ -2198,7 +2218,7 @@ unsigned long dispc_fclk_rate(void)
2198{ 2218{
2199 unsigned long r = 0; 2219 unsigned long r = 0;
2200 2220
2201 if (dss_get_dispc_clk_source() == 0) 2221 if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK)
2202 r = dss_clk_get_rate(DSS_CLK_FCK1); 2222 r = dss_clk_get_rate(DSS_CLK_FCK1);
2203 else 2223 else
2204#ifdef CONFIG_OMAP2_DSS_DSI 2224#ifdef CONFIG_OMAP2_DSS_DSI
@@ -2251,7 +2271,7 @@ void dispc_dump_clocks(struct seq_file *s)
2251 seq_printf(s, "- DISPC -\n"); 2271 seq_printf(s, "- DISPC -\n");
2252 2272
2253 seq_printf(s, "dispc fclk source = %s\n", 2273 seq_printf(s, "dispc fclk source = %s\n",
2254 dss_get_dispc_clk_source() == 0 ? 2274 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
2255 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2275 "dss1_alwon_fclk" : "dsi1_pll_fclk");
2256 2276
2257 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2277 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
@@ -2301,8 +2321,6 @@ void dispc_dump_irqs(struct seq_file *s)
2301 PIS(WAKEUP); 2321 PIS(WAKEUP);
2302#undef PIS 2322#undef PIS
2303} 2323}
2304#else
2305void dispc_dump_irqs(struct seq_file *s) { }
2306#endif 2324#endif
2307 2325
2308void dispc_dump_regs(struct seq_file *s) 2326void dispc_dump_regs(struct seq_file *s)
@@ -2854,12 +2872,13 @@ static void dispc_error_worker(struct work_struct *work)
2854 manager = mgr; 2872 manager = mgr;
2855 enable = mgr->device->state == 2873 enable = mgr->device->state ==
2856 OMAP_DSS_DISPLAY_ACTIVE; 2874 OMAP_DSS_DISPLAY_ACTIVE;
2857 mgr->device->disable(mgr->device); 2875 mgr->device->driver->disable(mgr->device);
2858 break; 2876 break;
2859 } 2877 }
2860 } 2878 }
2861 2879
2862 if (manager) { 2880 if (manager) {
2881 struct omap_dss_device *dssdev = manager->device;
2863 for (i = 0; i < omap_dss_get_num_overlays(); ++i) { 2882 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
2864 struct omap_overlay *ovl; 2883 struct omap_overlay *ovl;
2865 ovl = omap_dss_get_overlay(i); 2884 ovl = omap_dss_get_overlay(i);
@@ -2874,7 +2893,7 @@ static void dispc_error_worker(struct work_struct *work)
2874 dispc_go(manager->id); 2893 dispc_go(manager->id);
2875 mdelay(50); 2894 mdelay(50);
2876 if (enable) 2895 if (enable)
2877 manager->device->enable(manager->device); 2896 dssdev->driver->enable(dssdev);
2878 } 2897 }
2879 } 2898 }
2880 2899
@@ -2892,12 +2911,13 @@ static void dispc_error_worker(struct work_struct *work)
2892 manager = mgr; 2911 manager = mgr;
2893 enable = mgr->device->state == 2912 enable = mgr->device->state ==
2894 OMAP_DSS_DISPLAY_ACTIVE; 2913 OMAP_DSS_DISPLAY_ACTIVE;
2895 mgr->device->disable(mgr->device); 2914 mgr->device->driver->disable(mgr->device);
2896 break; 2915 break;
2897 } 2916 }
2898 } 2917 }
2899 2918
2900 if (manager) { 2919 if (manager) {
2920 struct omap_dss_device *dssdev = manager->device;
2901 for (i = 0; i < omap_dss_get_num_overlays(); ++i) { 2921 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
2902 struct omap_overlay *ovl; 2922 struct omap_overlay *ovl;
2903 ovl = omap_dss_get_overlay(i); 2923 ovl = omap_dss_get_overlay(i);
@@ -2912,7 +2932,7 @@ static void dispc_error_worker(struct work_struct *work)
2912 dispc_go(manager->id); 2932 dispc_go(manager->id);
2913 mdelay(50); 2933 mdelay(50);
2914 if (enable) 2934 if (enable)
2915 manager->device->enable(manager->device); 2935 dssdev->driver->enable(dssdev);
2916 } 2936 }
2917 } 2937 }
2918 2938
@@ -2923,7 +2943,7 @@ static void dispc_error_worker(struct work_struct *work)
2923 mgr = omap_dss_get_overlay_manager(i); 2943 mgr = omap_dss_get_overlay_manager(i);
2924 2944
2925 if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC) 2945 if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC)
2926 mgr->device->disable(mgr->device); 2946 mgr->device->driver->disable(mgr->device);
2927 } 2947 }
2928 } 2948 }
2929 2949
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 3b92b84b9560..6a74ea116d29 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -53,11 +53,11 @@ static ssize_t display_enabled_store(struct device *dev,
53 53
54 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { 54 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
55 if (enabled) { 55 if (enabled) {
56 r = dssdev->enable(dssdev); 56 r = dssdev->driver->enable(dssdev);
57 if (r) 57 if (r)
58 return r; 58 return r;
59 } else { 59 } else {
60 dssdev->disable(dssdev); 60 dssdev->driver->disable(dssdev);
61 } 61 }
62 } 62 }
63 63
@@ -69,8 +69,8 @@ static ssize_t display_upd_mode_show(struct device *dev,
69{ 69{
70 struct omap_dss_device *dssdev = to_dss_device(dev); 70 struct omap_dss_device *dssdev = to_dss_device(dev);
71 enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO; 71 enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
72 if (dssdev->get_update_mode) 72 if (dssdev->driver->get_update_mode)
73 mode = dssdev->get_update_mode(dssdev); 73 mode = dssdev->driver->get_update_mode(dssdev);
74 return snprintf(buf, PAGE_SIZE, "%d\n", mode); 74 return snprintf(buf, PAGE_SIZE, "%d\n", mode);
75} 75}
76 76
@@ -94,7 +94,7 @@ static ssize_t display_upd_mode_store(struct device *dev,
94 return -EINVAL; 94 return -EINVAL;
95 } 95 }
96 96
97 r = dssdev->set_update_mode(dssdev, mode); 97 r = dssdev->driver->set_update_mode(dssdev, mode);
98 if (r) 98 if (r)
99 return r; 99 return r;
100 100
@@ -106,7 +106,8 @@ static ssize_t display_tear_show(struct device *dev,
106{ 106{
107 struct omap_dss_device *dssdev = to_dss_device(dev); 107 struct omap_dss_device *dssdev = to_dss_device(dev);
108 return snprintf(buf, PAGE_SIZE, "%d\n", 108 return snprintf(buf, PAGE_SIZE, "%d\n",
109 dssdev->get_te ? dssdev->get_te(dssdev) : 0); 109 dssdev->driver->get_te ?
110 dssdev->driver->get_te(dssdev) : 0);
110} 111}
111 112
112static ssize_t display_tear_store(struct device *dev, 113static ssize_t display_tear_store(struct device *dev,
@@ -116,12 +117,12 @@ static ssize_t display_tear_store(struct device *dev,
116 unsigned long te; 117 unsigned long te;
117 int r; 118 int r;
118 119
119 if (!dssdev->enable_te || !dssdev->get_te) 120 if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
120 return -ENOENT; 121 return -ENOENT;
121 122
122 te = simple_strtoul(buf, NULL, 0); 123 te = simple_strtoul(buf, NULL, 0);
123 124
124 r = dssdev->enable_te(dssdev, te); 125 r = dssdev->driver->enable_te(dssdev, te);
125 if (r) 126 if (r)
126 return r; 127 return r;
127 128
@@ -134,10 +135,10 @@ static ssize_t display_timings_show(struct device *dev,
134 struct omap_dss_device *dssdev = to_dss_device(dev); 135 struct omap_dss_device *dssdev = to_dss_device(dev);
135 struct omap_video_timings t; 136 struct omap_video_timings t;
136 137
137 if (!dssdev->get_timings) 138 if (!dssdev->driver->get_timings)
138 return -ENOENT; 139 return -ENOENT;
139 140
140 dssdev->get_timings(dssdev, &t); 141 dssdev->driver->get_timings(dssdev, &t);
141 142
142 return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n", 143 return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
143 t.pixel_clock, 144 t.pixel_clock,
@@ -152,7 +153,7 @@ static ssize_t display_timings_store(struct device *dev,
152 struct omap_video_timings t; 153 struct omap_video_timings t;
153 int r, found; 154 int r, found;
154 155
155 if (!dssdev->set_timings || !dssdev->check_timings) 156 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
156 return -ENOENT; 157 return -ENOENT;
157 158
158 found = 0; 159 found = 0;
@@ -171,11 +172,11 @@ static ssize_t display_timings_store(struct device *dev,
171 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9) 172 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
172 return -EINVAL; 173 return -EINVAL;
173 174
174 r = dssdev->check_timings(dssdev, &t); 175 r = dssdev->driver->check_timings(dssdev, &t);
175 if (r) 176 if (r)
176 return r; 177 return r;
177 178
178 dssdev->set_timings(dssdev, &t); 179 dssdev->driver->set_timings(dssdev, &t);
179 180
180 return size; 181 return size;
181} 182}
@@ -185,9 +186,9 @@ static ssize_t display_rotate_show(struct device *dev,
185{ 186{
186 struct omap_dss_device *dssdev = to_dss_device(dev); 187 struct omap_dss_device *dssdev = to_dss_device(dev);
187 int rotate; 188 int rotate;
188 if (!dssdev->get_rotate) 189 if (!dssdev->driver->get_rotate)
189 return -ENOENT; 190 return -ENOENT;
190 rotate = dssdev->get_rotate(dssdev); 191 rotate = dssdev->driver->get_rotate(dssdev);
191 return snprintf(buf, PAGE_SIZE, "%u\n", rotate); 192 return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
192} 193}
193 194
@@ -198,12 +199,12 @@ static ssize_t display_rotate_store(struct device *dev,
198 unsigned long rot; 199 unsigned long rot;
199 int r; 200 int r;
200 201
201 if (!dssdev->set_rotate || !dssdev->get_rotate) 202 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
202 return -ENOENT; 203 return -ENOENT;
203 204
204 rot = simple_strtoul(buf, NULL, 0); 205 rot = simple_strtoul(buf, NULL, 0);
205 206
206 r = dssdev->set_rotate(dssdev, rot); 207 r = dssdev->driver->set_rotate(dssdev, rot);
207 if (r) 208 if (r)
208 return r; 209 return r;
209 210
@@ -215,9 +216,9 @@ static ssize_t display_mirror_show(struct device *dev,
215{ 216{
216 struct omap_dss_device *dssdev = to_dss_device(dev); 217 struct omap_dss_device *dssdev = to_dss_device(dev);
217 int mirror; 218 int mirror;
218 if (!dssdev->get_mirror) 219 if (!dssdev->driver->get_mirror)
219 return -ENOENT; 220 return -ENOENT;
220 mirror = dssdev->get_mirror(dssdev); 221 mirror = dssdev->driver->get_mirror(dssdev);
221 return snprintf(buf, PAGE_SIZE, "%u\n", mirror); 222 return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
222} 223}
223 224
@@ -228,12 +229,12 @@ static ssize_t display_mirror_store(struct device *dev,
228 unsigned long mirror; 229 unsigned long mirror;
229 int r; 230 int r;
230 231
231 if (!dssdev->set_mirror || !dssdev->get_mirror) 232 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
232 return -ENOENT; 233 return -ENOENT;
233 234
234 mirror = simple_strtoul(buf, NULL, 0); 235 mirror = simple_strtoul(buf, NULL, 0);
235 236
236 r = dssdev->set_mirror(dssdev, mirror); 237 r = dssdev->driver->set_mirror(dssdev, mirror);
237 if (r) 238 if (r)
238 return r; 239 return r;
239 240
@@ -246,10 +247,10 @@ static ssize_t display_wss_show(struct device *dev,
246 struct omap_dss_device *dssdev = to_dss_device(dev); 247 struct omap_dss_device *dssdev = to_dss_device(dev);
247 unsigned int wss; 248 unsigned int wss;
248 249
249 if (!dssdev->get_wss) 250 if (!dssdev->driver->get_wss)
250 return -ENOENT; 251 return -ENOENT;
251 252
252 wss = dssdev->get_wss(dssdev); 253 wss = dssdev->driver->get_wss(dssdev);
253 254
254 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss); 255 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
255} 256}
@@ -261,7 +262,7 @@ static ssize_t display_wss_store(struct device *dev,
261 unsigned long wss; 262 unsigned long wss;
262 int r; 263 int r;
263 264
264 if (!dssdev->get_wss || !dssdev->set_wss) 265 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
265 return -ENOENT; 266 return -ENOENT;
266 267
267 if (strict_strtoul(buf, 0, &wss)) 268 if (strict_strtoul(buf, 0, &wss))
@@ -270,7 +271,7 @@ static ssize_t display_wss_store(struct device *dev,
270 if (wss > 0xfffff) 271 if (wss > 0xfffff)
271 return -EINVAL; 272 return -EINVAL;
272 273
273 r = dssdev->set_wss(dssdev, wss); 274 r = dssdev->driver->set_wss(dssdev, wss);
274 if (r) 275 if (r)
275 return r; 276 return r;
276 277
@@ -303,12 +304,13 @@ static struct device_attribute *display_sysfs_attrs[] = {
303 NULL 304 NULL
304}; 305};
305 306
306static void default_get_resolution(struct omap_dss_device *dssdev, 307void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
307 u16 *xres, u16 *yres) 308 u16 *xres, u16 *yres)
308{ 309{
309 *xres = dssdev->panel.timings.x_res; 310 *xres = dssdev->panel.timings.x_res;
310 *yres = dssdev->panel.timings.y_res; 311 *yres = dssdev->panel.timings.y_res;
311} 312}
313EXPORT_SYMBOL(omapdss_default_get_resolution);
312 314
313void default_get_overlay_fifo_thresholds(enum omap_plane plane, 315void default_get_overlay_fifo_thresholds(enum omap_plane plane,
314 u32 fifo_size, enum omap_burst_size *burst_size, 316 u32 fifo_size, enum omap_burst_size *burst_size,
@@ -323,24 +325,8 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
323 *fifo_low = fifo_size - burst_size_bytes; 325 *fifo_low = fifo_size - burst_size_bytes;
324} 326}
325 327
326static int default_wait_vsync(struct omap_dss_device *dssdev) 328int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
327{ 329{
328 unsigned long timeout = msecs_to_jiffies(500);
329 u32 irq;
330
331 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
332 irq = DISPC_IRQ_EVSYNC_ODD;
333 else
334 irq = DISPC_IRQ_VSYNC;
335
336 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
337}
338
339static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
340{
341 if (dssdev->panel.recommended_bpp)
342 return dssdev->panel.recommended_bpp;
343
344 switch (dssdev->type) { 330 switch (dssdev->type) {
345 case OMAP_DISPLAY_TYPE_DPI: 331 case OMAP_DISPLAY_TYPE_DPI:
346 if (dssdev->phy.dpi.data_lines == 24) 332 if (dssdev->phy.dpi.data_lines == 24)
@@ -362,6 +348,7 @@ static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
362 BUG(); 348 BUG();
363 } 349 }
364} 350}
351EXPORT_SYMBOL(omapdss_default_get_recommended_bpp);
365 352
366/* Checks if replication logic should be used. Only use for active matrix, 353/* Checks if replication logic should be used. Only use for active matrix,
367 * when overlay is in RGB12U or RGB16 mode, and LCD interface is 354 * when overlay is in RGB12U or RGB16 mode, and LCD interface is
@@ -425,10 +412,6 @@ void dss_init_device(struct platform_device *pdev,
425 return; 412 return;
426 } 413 }
427 414
428 dssdev->get_resolution = default_get_resolution;
429 dssdev->get_recommended_bpp = default_get_recommended_bpp;
430 dssdev->wait_vsync = default_wait_vsync;
431
432 switch (dssdev->type) { 415 switch (dssdev->type) {
433 case OMAP_DISPLAY_TYPE_DPI: 416 case OMAP_DISPLAY_TYPE_DPI:
434 r = dpi_init_display(dssdev); 417 r = dpi_init_display(dssdev);
@@ -502,13 +485,13 @@ static int dss_suspend_device(struct device *dev, void *data)
502 return 0; 485 return 0;
503 } 486 }
504 487
505 if (!dssdev->suspend) { 488 if (!dssdev->driver->suspend) {
506 DSSERR("display '%s' doesn't implement suspend\n", 489 DSSERR("display '%s' doesn't implement suspend\n",
507 dssdev->name); 490 dssdev->name);
508 return -ENOSYS; 491 return -ENOSYS;
509 } 492 }
510 493
511 r = dssdev->suspend(dssdev); 494 r = dssdev->driver->suspend(dssdev);
512 if (r) 495 if (r)
513 return r; 496 return r;
514 497
@@ -537,8 +520,8 @@ static int dss_resume_device(struct device *dev, void *data)
537 int r; 520 int r;
538 struct omap_dss_device *dssdev = to_dss_device(dev); 521 struct omap_dss_device *dssdev = to_dss_device(dev);
539 522
540 if (dssdev->activate_after_resume && dssdev->resume) { 523 if (dssdev->activate_after_resume && dssdev->driver->resume) {
541 r = dssdev->resume(dssdev); 524 r = dssdev->driver->resume(dssdev);
542 if (r) 525 if (r)
543 return r; 526 return r;
544 } 527 }
@@ -558,7 +541,7 @@ int dss_resume_all_devices(void)
558static int dss_disable_device(struct device *dev, void *data) 541static int dss_disable_device(struct device *dev, void *data)
559{ 542{
560 struct omap_dss_device *dssdev = to_dss_device(dev); 543 struct omap_dss_device *dssdev = to_dss_device(dev);
561 dssdev->disable(dssdev); 544 dssdev->driver->disable(dssdev);
562 return 0; 545 return 0;
563} 546}
564 547
@@ -591,10 +574,6 @@ struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
591 574
592 int match(struct device *dev, void *data) 575 int match(struct device *dev, void *data)
593 { 576 {
594 /* skip panels connected to controllers */
595 if (to_dss_device(dev)->panel.ctrl)
596 return 0;
597
598 return 1; 577 return 1;
599 } 578 }
600 579
@@ -626,45 +605,21 @@ EXPORT_SYMBOL(omap_dss_find_device);
626 605
627int omap_dss_start_device(struct omap_dss_device *dssdev) 606int omap_dss_start_device(struct omap_dss_device *dssdev)
628{ 607{
629 int r;
630
631 if (!dssdev->driver) { 608 if (!dssdev->driver) {
632 DSSDBG("no driver\n"); 609 DSSDBG("no driver\n");
633 r = -ENODEV; 610 return -ENODEV;
634 goto err0;
635 }
636
637 if (dssdev->ctrl.panel && !dssdev->ctrl.panel->driver) {
638 DSSDBG("no panel driver\n");
639 r = -ENODEV;
640 goto err0;
641 } 611 }
642 612
643 if (!try_module_get(dssdev->dev.driver->owner)) { 613 if (!try_module_get(dssdev->dev.driver->owner)) {
644 r = -ENODEV; 614 return -ENODEV;
645 goto err0;
646 }
647
648 if (dssdev->ctrl.panel) {
649 if (!try_module_get(dssdev->ctrl.panel->dev.driver->owner)) {
650 r = -ENODEV;
651 goto err1;
652 }
653 } 615 }
654 616
655 return 0; 617 return 0;
656err1:
657 module_put(dssdev->dev.driver->owner);
658err0:
659 return r;
660} 618}
661EXPORT_SYMBOL(omap_dss_start_device); 619EXPORT_SYMBOL(omap_dss_start_device);
662 620
663void omap_dss_stop_device(struct omap_dss_device *dssdev) 621void omap_dss_stop_device(struct omap_dss_device *dssdev)
664{ 622{
665 if (dssdev->ctrl.panel)
666 module_put(dssdev->ctrl.panel->dev.driver->owner);
667
668 module_put(dssdev->dev.driver->owner); 623 module_put(dssdev->dev.driver->owner);
669} 624}
670EXPORT_SYMBOL(omap_dss_stop_device); 625EXPORT_SYMBOL(omap_dss_stop_device);
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 2d71031baa25..960e977a8bf0 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -25,7 +25,10 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/err.h>
28#include <linux/errno.h> 29#include <linux/errno.h>
30#include <linux/platform_device.h>
31#include <linux/regulator/consumer.h>
29 32
30#include <plat/display.h> 33#include <plat/display.h>
31#include <plat/cpu.h> 34#include <plat/cpu.h>
@@ -33,7 +36,7 @@
33#include "dss.h" 36#include "dss.h"
34 37
35static struct { 38static struct {
36 int update_enabled; 39 struct regulator *vdds_dsi_reg;
37} dpi; 40} dpi;
38 41
39#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 42#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
@@ -53,7 +56,7 @@ static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
53 if (r) 56 if (r)
54 return r; 57 return r;
55 58
56 dss_select_clk_source(0, 1); 59 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
57 60
58 r = dispc_set_clock_div(&dispc_cinfo); 61 r = dispc_set_clock_div(&dispc_cinfo);
59 if (r) 62 if (r)
@@ -150,7 +153,7 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
150 return 0; 153 return 0;
151} 154}
152 155
153static int dpi_display_enable(struct omap_dss_device *dssdev) 156int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
154{ 157{
155 int r; 158 int r;
156 159
@@ -160,10 +163,10 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
160 goto err0; 163 goto err0;
161 } 164 }
162 165
163 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 166 if (cpu_is_omap34xx()) {
164 DSSERR("display already enabled\n"); 167 r = regulator_enable(dpi.vdds_dsi_reg);
165 r = -EINVAL; 168 if (r)
166 goto err1; 169 goto err1;
167 } 170 }
168 171
169 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 172 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
@@ -184,18 +187,10 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
184 187
185 mdelay(2); 188 mdelay(2);
186 189
187 dispc_enable_lcd_out(1); 190 dssdev->manager->enable(dssdev->manager);
188
189 r = dssdev->driver->enable(dssdev);
190 if (r)
191 goto err5;
192
193 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
194 191
195 return 0; 192 return 0;
196 193
197err5:
198 dispc_enable_lcd_out(0);
199err4: 194err4:
200#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 195#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
201 dsi_pll_uninit(); 196 dsi_pll_uninit();
@@ -204,78 +199,35 @@ err3:
204#endif 199#endif
205err2: 200err2:
206 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 201 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
202 if (cpu_is_omap34xx())
203 regulator_disable(dpi.vdds_dsi_reg);
207err1: 204err1:
208 omap_dss_stop_device(dssdev); 205 omap_dss_stop_device(dssdev);
209err0: 206err0:
210 return r; 207 return r;
211} 208}
209EXPORT_SYMBOL(omapdss_dpi_display_enable);
212 210
213static int dpi_display_resume(struct omap_dss_device *dssdev); 211void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
214
215static void dpi_display_disable(struct omap_dss_device *dssdev)
216{ 212{
217 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) 213 dssdev->manager->disable(dssdev->manager);
218 return;
219
220 if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
221 dpi_display_resume(dssdev);
222
223 dssdev->driver->disable(dssdev);
224
225 dispc_enable_lcd_out(0);
226 214
227#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 215#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
228 dss_select_clk_source(0, 0); 216 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
229 dsi_pll_uninit(); 217 dsi_pll_uninit();
230 dss_clk_disable(DSS_CLK_FCK2); 218 dss_clk_disable(DSS_CLK_FCK2);
231#endif 219#endif
232 220
233 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 221 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
234 222
235 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 223 if (cpu_is_omap34xx())
224 regulator_disable(dpi.vdds_dsi_reg);
236 225
237 omap_dss_stop_device(dssdev); 226 omap_dss_stop_device(dssdev);
238} 227}
228EXPORT_SYMBOL(omapdss_dpi_display_disable);
239 229
240static int dpi_display_suspend(struct omap_dss_device *dssdev) 230void dpi_set_timings(struct omap_dss_device *dssdev,
241{
242 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
243 return -EINVAL;
244
245 DSSDBG("dpi_display_suspend\n");
246
247 if (dssdev->driver->suspend)
248 dssdev->driver->suspend(dssdev);
249
250 dispc_enable_lcd_out(0);
251
252 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
253
254 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
255
256 return 0;
257}
258
259static int dpi_display_resume(struct omap_dss_device *dssdev)
260{
261 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
262 return -EINVAL;
263
264 DSSDBG("dpi_display_resume\n");
265
266 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
267
268 dispc_enable_lcd_out(1);
269
270 if (dssdev->driver->resume)
271 dssdev->driver->resume(dssdev);
272
273 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
274
275 return 0;
276}
277
278static void dpi_set_timings(struct omap_dss_device *dssdev,
279 struct omap_video_timings *timings) 231 struct omap_video_timings *timings)
280{ 232{
281 DSSDBG("dpi_set_timings\n"); 233 DSSDBG("dpi_set_timings\n");
@@ -285,8 +237,9 @@ static void dpi_set_timings(struct omap_dss_device *dssdev,
285 dispc_go(OMAP_DSS_CHANNEL_LCD); 237 dispc_go(OMAP_DSS_CHANNEL_LCD);
286 } 238 }
287} 239}
240EXPORT_SYMBOL(dpi_set_timings);
288 241
289static int dpi_check_timings(struct omap_dss_device *dssdev, 242int dpi_check_timings(struct omap_dss_device *dssdev,
290 struct omap_video_timings *timings) 243 struct omap_video_timings *timings)
291{ 244{
292 bool is_tft; 245 bool is_tft;
@@ -340,56 +293,25 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
340 293
341 return 0; 294 return 0;
342} 295}
343 296EXPORT_SYMBOL(dpi_check_timings);
344static void dpi_get_timings(struct omap_dss_device *dssdev,
345 struct omap_video_timings *timings)
346{
347 *timings = dssdev->panel.timings;
348}
349
350static int dpi_display_set_update_mode(struct omap_dss_device *dssdev,
351 enum omap_dss_update_mode mode)
352{
353 if (mode == OMAP_DSS_UPDATE_MANUAL)
354 return -EINVAL;
355
356 if (mode == OMAP_DSS_UPDATE_DISABLED) {
357 dispc_enable_lcd_out(0);
358 dpi.update_enabled = 0;
359 } else {
360 dispc_enable_lcd_out(1);
361 dpi.update_enabled = 1;
362 }
363
364 return 0;
365}
366
367static enum omap_dss_update_mode dpi_display_get_update_mode(
368 struct omap_dss_device *dssdev)
369{
370 return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
371 OMAP_DSS_UPDATE_DISABLED;
372}
373 297
374int dpi_init_display(struct omap_dss_device *dssdev) 298int dpi_init_display(struct omap_dss_device *dssdev)
375{ 299{
376 DSSDBG("init_display\n"); 300 DSSDBG("init_display\n");
377 301
378 dssdev->enable = dpi_display_enable;
379 dssdev->disable = dpi_display_disable;
380 dssdev->suspend = dpi_display_suspend;
381 dssdev->resume = dpi_display_resume;
382 dssdev->set_timings = dpi_set_timings;
383 dssdev->check_timings = dpi_check_timings;
384 dssdev->get_timings = dpi_get_timings;
385 dssdev->set_update_mode = dpi_display_set_update_mode;
386 dssdev->get_update_mode = dpi_display_get_update_mode;
387
388 return 0; 302 return 0;
389} 303}
390 304
391int dpi_init(void) 305int dpi_init(struct platform_device *pdev)
392{ 306{
307 if (cpu_is_omap34xx()) {
308 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
309 if (IS_ERR(dpi.vdds_dsi_reg)) {
310 DSSERR("can't get VDDS_DSI regulator\n");
311 return PTR_ERR(dpi.vdds_dsi_reg);
312 }
313 }
314
393 return 0; 315 return 0;
394} 316}
395 317
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6122178f5f85..3af207b2bde3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -27,11 +27,12 @@
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/semaphore.h>
30#include <linux/seq_file.h> 31#include <linux/seq_file.h>
31#include <linux/platform_device.h> 32#include <linux/platform_device.h>
32#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
33#include <linux/kthread.h>
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h>
35 36
36#include <plat/display.h> 37#include <plat/display.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
@@ -199,7 +200,6 @@ enum dsi_vc_mode {
199}; 200};
200 201
201struct dsi_update_region { 202struct dsi_update_region {
202 bool dirty;
203 u16 x, y, w, h; 203 u16 x, y, w, h;
204 struct omap_dss_device *device; 204 struct omap_dss_device *device;
205}; 205};
@@ -224,29 +224,25 @@ static struct
224 enum dsi_vc_mode mode; 224 enum dsi_vc_mode mode;
225 struct omap_dss_device *dssdev; 225 struct omap_dss_device *dssdev;
226 enum fifo_size fifo_size; 226 enum fifo_size fifo_size;
227 int dest_per; /* destination peripheral 0-3 */
228 } vc[4]; 227 } vc[4];
229 228
230 struct mutex lock; 229 struct mutex lock;
231 struct mutex bus_lock; 230 struct semaphore bus_lock;
232 231
233 unsigned pll_locked; 232 unsigned pll_locked;
234 233
235 struct completion bta_completion; 234 struct completion bta_completion;
236 235
237 struct task_struct *thread; 236 int update_channel;
238 wait_queue_head_t waitqueue;
239
240 spinlock_t update_lock;
241 bool framedone_received;
242 struct dsi_update_region update_region; 237 struct dsi_update_region update_region;
243 struct dsi_update_region active_update_region;
244 struct completion update_completion;
245 238
246 enum omap_dss_update_mode user_update_mode;
247 enum omap_dss_update_mode update_mode;
248 bool te_enabled; 239 bool te_enabled;
249 bool use_ext_te; 240
241 struct work_struct framedone_work;
242 void (*framedone_callback)(int, void *);
243 void *framedone_data;
244
245 struct delayed_work framedone_timeout_work;
250 246
251#ifdef DSI_CATCH_MISSING_TE 247#ifdef DSI_CATCH_MISSING_TE
252 struct timer_list te_timer; 248 struct timer_list te_timer;
@@ -261,8 +257,6 @@ static struct
261#ifdef DEBUG 257#ifdef DEBUG
262 ktime_t perf_setup_time; 258 ktime_t perf_setup_time;
263 ktime_t perf_start_time; 259 ktime_t perf_start_time;
264 ktime_t perf_start_time_auto;
265 int perf_measure_frames;
266#endif 260#endif
267 int debug_read; 261 int debug_read;
268 int debug_write; 262 int debug_write;
@@ -299,16 +293,21 @@ void dsi_restore_context(void)
299 293
300void dsi_bus_lock(void) 294void dsi_bus_lock(void)
301{ 295{
302 mutex_lock(&dsi.bus_lock); 296 down(&dsi.bus_lock);
303} 297}
304EXPORT_SYMBOL(dsi_bus_lock); 298EXPORT_SYMBOL(dsi_bus_lock);
305 299
306void dsi_bus_unlock(void) 300void dsi_bus_unlock(void)
307{ 301{
308 mutex_unlock(&dsi.bus_lock); 302 up(&dsi.bus_lock);
309} 303}
310EXPORT_SYMBOL(dsi_bus_unlock); 304EXPORT_SYMBOL(dsi_bus_unlock);
311 305
306static bool dsi_bus_is_locked(void)
307{
308 return dsi.bus_lock.count == 0;
309}
310
312static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 311static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
313 int value) 312 int value)
314{ 313{
@@ -333,12 +332,6 @@ static void dsi_perf_mark_start(void)
333 dsi.perf_start_time = ktime_get(); 332 dsi.perf_start_time = ktime_get();
334} 333}
335 334
336static void dsi_perf_mark_start_auto(void)
337{
338 dsi.perf_measure_frames = 0;
339 dsi.perf_start_time_auto = ktime_get();
340}
341
342static void dsi_perf_show(const char *name) 335static void dsi_perf_show(const char *name)
343{ 336{
344 ktime_t t, setup_time, trans_time; 337 ktime_t t, setup_time, trans_time;
@@ -348,9 +341,6 @@ static void dsi_perf_show(const char *name)
348 if (!dsi_perf) 341 if (!dsi_perf)
349 return; 342 return;
350 343
351 if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED)
352 return;
353
354 t = ktime_get(); 344 t = ktime_get();
355 345
356 setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time); 346 setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time);
@@ -365,76 +355,23 @@ static void dsi_perf_show(const char *name)
365 355
366 total_us = setup_us + trans_us; 356 total_us = setup_us + trans_us;
367 357
368 total_bytes = dsi.active_update_region.w * 358 total_bytes = dsi.update_region.w *
369 dsi.active_update_region.h * 359 dsi.update_region.h *
370 dsi.active_update_region.device->ctrl.pixel_size / 8; 360 dsi.update_region.device->ctrl.pixel_size / 8;
371
372 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
373 static u32 s_total_trans_us, s_total_setup_us;
374 static u32 s_min_trans_us = 0xffffffff, s_min_setup_us;
375 static u32 s_max_trans_us, s_max_setup_us;
376 const int numframes = 100;
377 ktime_t total_time_auto;
378 u32 total_time_auto_us;
379
380 dsi.perf_measure_frames++;
381
382 if (setup_us < s_min_setup_us)
383 s_min_setup_us = setup_us;
384 361
385 if (setup_us > s_max_setup_us) 362 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
386 s_max_setup_us = setup_us; 363 "%u bytes, %u kbytes/sec\n",
387 364 name,
388 s_total_setup_us += setup_us; 365 setup_us,
389 366 trans_us,
390 if (trans_us < s_min_trans_us) 367 total_us,
391 s_min_trans_us = trans_us; 368 1000*1000 / total_us,
392 369 total_bytes,
393 if (trans_us > s_max_trans_us) 370 total_bytes * 1000 / total_us);
394 s_max_trans_us = trans_us;
395
396 s_total_trans_us += trans_us;
397
398 if (dsi.perf_measure_frames < numframes)
399 return;
400
401 total_time_auto = ktime_sub(t, dsi.perf_start_time_auto);
402 total_time_auto_us = (u32)ktime_to_us(total_time_auto);
403
404 printk(KERN_INFO "DSI(%s): %u fps, setup %u/%u/%u, "
405 "trans %u/%u/%u\n",
406 name,
407 1000 * 1000 * numframes / total_time_auto_us,
408 s_min_setup_us,
409 s_max_setup_us,
410 s_total_setup_us / numframes,
411 s_min_trans_us,
412 s_max_trans_us,
413 s_total_trans_us / numframes);
414
415 s_total_setup_us = 0;
416 s_min_setup_us = 0xffffffff;
417 s_max_setup_us = 0;
418 s_total_trans_us = 0;
419 s_min_trans_us = 0xffffffff;
420 s_max_trans_us = 0;
421 dsi_perf_mark_start_auto();
422 } else {
423 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
424 "%u bytes, %u kbytes/sec\n",
425 name,
426 setup_us,
427 trans_us,
428 total_us,
429 1000*1000 / total_us,
430 total_bytes,
431 total_bytes * 1000 / total_us);
432 }
433} 371}
434#else 372#else
435#define dsi_perf_mark_setup() 373#define dsi_perf_mark_setup()
436#define dsi_perf_mark_start() 374#define dsi_perf_mark_start()
437#define dsi_perf_mark_start_auto()
438#define dsi_perf_show(x) 375#define dsi_perf_show(x)
439#endif 376#endif
440 377
@@ -774,7 +711,7 @@ static unsigned long dsi_fclk_rate(void)
774{ 711{
775 unsigned long r; 712 unsigned long r;
776 713
777 if (dss_get_dsi_clk_source() == 0) { 714 if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) {
778 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ 715 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */
779 r = dss_clk_get_rate(DSS_CLK_FCK1); 716 r = dss_clk_get_rate(DSS_CLK_FCK1);
780 } else { 717 } else {
@@ -1227,17 +1164,19 @@ void dsi_dump_clocks(struct seq_file *s)
1227 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", 1164 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n",
1228 cinfo->dsi1_pll_fclk, 1165 cinfo->dsi1_pll_fclk,
1229 cinfo->regm3, 1166 cinfo->regm3,
1230 dss_get_dispc_clk_source() == 0 ? "off" : "on"); 1167 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
1168 "off" : "on");
1231 1169
1232 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", 1170 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n",
1233 cinfo->dsi2_pll_fclk, 1171 cinfo->dsi2_pll_fclk,
1234 cinfo->regm4, 1172 cinfo->regm4,
1235 dss_get_dsi_clk_source() == 0 ? "off" : "on"); 1173 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
1174 "off" : "on");
1236 1175
1237 seq_printf(s, "- DSI -\n"); 1176 seq_printf(s, "- DSI -\n");
1238 1177
1239 seq_printf(s, "dsi fclk source = %s\n", 1178 seq_printf(s, "dsi fclk source = %s\n",
1240 dss_get_dsi_clk_source() == 0 ? 1179 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
1241 "dss1_alwon_fclk" : "dsi2_pll_fclk"); 1180 "dss1_alwon_fclk" : "dsi2_pll_fclk");
1242 1181
1243 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); 1182 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate());
@@ -1756,29 +1695,10 @@ static int dsi_force_tx_stop_mode_io(void)
1756 return 0; 1695 return 0;
1757} 1696}
1758 1697
1759static void dsi_vc_print_status(int channel)
1760{
1761 u32 r;
1762
1763 r = dsi_read_reg(DSI_VC_CTRL(channel));
1764 DSSDBG("vc %d: TX_FIFO_NOT_EMPTY %d, BTA_EN %d, VC_BUSY %d, "
1765 "TX_FIFO_FULL %d, RX_FIFO_NOT_EMPTY %d, ",
1766 channel,
1767 FLD_GET(r, 5, 5),
1768 FLD_GET(r, 6, 6),
1769 FLD_GET(r, 15, 15),
1770 FLD_GET(r, 16, 16),
1771 FLD_GET(r, 20, 20));
1772
1773 r = dsi_read_reg(DSI_TX_FIFO_VC_EMPTINESS);
1774 DSSDBG("EMPTINESS %d\n", (r >> (8 * channel)) & 0xff);
1775}
1776
1777static int dsi_vc_enable(int channel, bool enable) 1698static int dsi_vc_enable(int channel, bool enable)
1778{ 1699{
1779 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) 1700 DSSDBG("dsi_vc_enable channel %d, enable %d\n",
1780 DSSDBG("dsi_vc_enable channel %d, enable %d\n", 1701 channel, enable);
1781 channel, enable);
1782 1702
1783 enable = enable ? 1 : 0; 1703 enable = enable ? 1 : 0;
1784 1704
@@ -1859,10 +1779,12 @@ static void dsi_vc_config_vp(int channel)
1859} 1779}
1860 1780
1861 1781
1862static void dsi_vc_enable_hs(int channel, bool enable) 1782void omapdss_dsi_vc_enable_hs(int channel, bool enable)
1863{ 1783{
1864 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); 1784 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
1865 1785
1786 WARN_ON(!dsi_bus_is_locked());
1787
1866 dsi_vc_enable(channel, 0); 1788 dsi_vc_enable(channel, 0);
1867 dsi_if_enable(0); 1789 dsi_if_enable(0);
1868 1790
@@ -1873,6 +1795,7 @@ static void dsi_vc_enable_hs(int channel, bool enable)
1873 1795
1874 dsi_force_tx_stop_mode_io(); 1796 dsi_force_tx_stop_mode_io();
1875} 1797}
1798EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
1876 1799
1877static void dsi_vc_flush_long_data(int channel) 1800static void dsi_vc_flush_long_data(int channel)
1878{ 1801{
@@ -1955,11 +1878,10 @@ static u16 dsi_vc_flush_receive_data(int channel)
1955 1878
1956static int dsi_vc_send_bta(int channel) 1879static int dsi_vc_send_bta(int channel)
1957{ 1880{
1958 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO && 1881 if (dsi.debug_write || dsi.debug_read)
1959 (dsi.debug_write || dsi.debug_read))
1960 DSSDBG("dsi_vc_send_bta %d\n", channel); 1882 DSSDBG("dsi_vc_send_bta %d\n", channel);
1961 1883
1962 WARN_ON(!mutex_is_locked(&dsi.bus_lock)); 1884 WARN_ON(!dsi_bus_is_locked());
1963 1885
1964 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ 1886 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */
1965 DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); 1887 DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
@@ -2010,10 +1932,9 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type,
2010 u32 val; 1932 u32 val;
2011 u8 data_id; 1933 u8 data_id;
2012 1934
2013 WARN_ON(!mutex_is_locked(&dsi.bus_lock)); 1935 WARN_ON(!dsi_bus_is_locked());
2014 1936
2015 /*data_id = data_type | channel << 6; */ 1937 data_id = data_type | channel << 6;
2016 data_id = data_type | dsi.vc[channel].dest_per << 6;
2017 1938
2018 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | 1939 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
2019 FLD_VAL(ecc, 31, 24); 1940 FLD_VAL(ecc, 31, 24);
@@ -2056,13 +1977,10 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
2056 1977
2057 dsi_vc_write_long_header(channel, data_type, len, ecc); 1978 dsi_vc_write_long_header(channel, data_type, len, ecc);
2058 1979
2059 /*dsi_vc_print_status(0); */
2060
2061 p = data; 1980 p = data;
2062 for (i = 0; i < len >> 2; i++) { 1981 for (i = 0; i < len >> 2; i++) {
2063 if (dsi.debug_write) 1982 if (dsi.debug_write)
2064 DSSDBG("\tsending full packet %d\n", i); 1983 DSSDBG("\tsending full packet %d\n", i);
2065 /*dsi_vc_print_status(0); */
2066 1984
2067 b1 = *p++; 1985 b1 = *p++;
2068 b2 = *p++; 1986 b2 = *p++;
@@ -2105,7 +2023,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2105 u32 r; 2023 u32 r;
2106 u8 data_id; 2024 u8 data_id;
2107 2025
2108 WARN_ON(!mutex_is_locked(&dsi.bus_lock)); 2026 WARN_ON(!dsi_bus_is_locked());
2109 2027
2110 if (dsi.debug_write) 2028 if (dsi.debug_write)
2111 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", 2029 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
@@ -2119,7 +2037,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2119 return -EINVAL; 2037 return -EINVAL;
2120 } 2038 }
2121 2039
2122 data_id = data_type | dsi.vc[channel].dest_per << 6; 2040 data_id = data_type | channel << 6;
2123 2041
2124 r = (data_id << 0) | (data << 8) | (ecc << 24); 2042 r = (data_id << 0) | (data << 8) | (ecc << 24);
2125 2043
@@ -2163,14 +2081,35 @@ int dsi_vc_dcs_write(int channel, u8 *data, int len)
2163 2081
2164 r = dsi_vc_dcs_write_nosync(channel, data, len); 2082 r = dsi_vc_dcs_write_nosync(channel, data, len);
2165 if (r) 2083 if (r)
2166 return r; 2084 goto err;
2167 2085
2168 r = dsi_vc_send_bta_sync(channel); 2086 r = dsi_vc_send_bta_sync(channel);
2087 if (r)
2088 goto err;
2169 2089
2090 return 0;
2091err:
2092 DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n",
2093 channel, data[0], len);
2170 return r; 2094 return r;
2171} 2095}
2172EXPORT_SYMBOL(dsi_vc_dcs_write); 2096EXPORT_SYMBOL(dsi_vc_dcs_write);
2173 2097
2098int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd)
2099{
2100 return dsi_vc_dcs_write(channel, &dcs_cmd, 1);
2101}
2102EXPORT_SYMBOL(dsi_vc_dcs_write_0);
2103
2104int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param)
2105{
2106 u8 buf[2];
2107 buf[0] = dcs_cmd;
2108 buf[1] = param;
2109 return dsi_vc_dcs_write(channel, buf, 2);
2110}
2111EXPORT_SYMBOL(dsi_vc_dcs_write_1);
2112
2174int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) 2113int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2175{ 2114{
2176 u32 val; 2115 u32 val;
@@ -2182,16 +2121,17 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2182 2121
2183 r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); 2122 r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0);
2184 if (r) 2123 if (r)
2185 return r; 2124 goto err;
2186 2125
2187 r = dsi_vc_send_bta_sync(channel); 2126 r = dsi_vc_send_bta_sync(channel);
2188 if (r) 2127 if (r)
2189 return r; 2128 goto err;
2190 2129
2191 /* RX_FIFO_NOT_EMPTY */ 2130 /* RX_FIFO_NOT_EMPTY */
2192 if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) { 2131 if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) {
2193 DSSERR("RX fifo empty when trying to read.\n"); 2132 DSSERR("RX fifo empty when trying to read.\n");
2194 return -EIO; 2133 r = -EIO;
2134 goto err;
2195 } 2135 }
2196 2136
2197 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 2137 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
@@ -2201,15 +2141,18 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2201 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 2141 if (dt == DSI_DT_RX_ACK_WITH_ERR) {
2202 u16 err = FLD_GET(val, 23, 8); 2142 u16 err = FLD_GET(val, 23, 8);
2203 dsi_show_rx_ack_with_err(err); 2143 dsi_show_rx_ack_with_err(err);
2204 return -EIO; 2144 r = -EIO;
2145 goto err;
2205 2146
2206 } else if (dt == DSI_DT_RX_SHORT_READ_1) { 2147 } else if (dt == DSI_DT_RX_SHORT_READ_1) {
2207 u8 data = FLD_GET(val, 15, 8); 2148 u8 data = FLD_GET(val, 15, 8);
2208 if (dsi.debug_read) 2149 if (dsi.debug_read)
2209 DSSDBG("\tDCS short response, 1 byte: %02x\n", data); 2150 DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
2210 2151
2211 if (buflen < 1) 2152 if (buflen < 1) {
2212 return -EIO; 2153 r = -EIO;
2154 goto err;
2155 }
2213 2156
2214 buf[0] = data; 2157 buf[0] = data;
2215 2158
@@ -2219,8 +2162,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2219 if (dsi.debug_read) 2162 if (dsi.debug_read)
2220 DSSDBG("\tDCS short response, 2 byte: %04x\n", data); 2163 DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
2221 2164
2222 if (buflen < 2) 2165 if (buflen < 2) {
2223 return -EIO; 2166 r = -EIO;
2167 goto err;
2168 }
2224 2169
2225 buf[0] = data & 0xff; 2170 buf[0] = data & 0xff;
2226 buf[1] = (data >> 8) & 0xff; 2171 buf[1] = (data >> 8) & 0xff;
@@ -2232,8 +2177,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2232 if (dsi.debug_read) 2177 if (dsi.debug_read)
2233 DSSDBG("\tDCS long response, len %d\n", len); 2178 DSSDBG("\tDCS long response, len %d\n", len);
2234 2179
2235 if (len > buflen) 2180 if (len > buflen) {
2236 return -EIO; 2181 r = -EIO;
2182 goto err;
2183 }
2237 2184
2238 /* two byte checksum ends the packet, not included in len */ 2185 /* two byte checksum ends the packet, not included in len */
2239 for (w = 0; w < len + 2;) { 2186 for (w = 0; w < len + 2;) {
@@ -2255,14 +2202,52 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2255 } 2202 }
2256 2203
2257 return len; 2204 return len;
2258
2259 } else { 2205 } else {
2260 DSSERR("\tunknown datatype 0x%02x\n", dt); 2206 DSSERR("\tunknown datatype 0x%02x\n", dt);
2261 return -EIO; 2207 r = -EIO;
2208 goto err;
2262 } 2209 }
2210
2211 BUG();
2212err:
2213 DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n",
2214 channel, dcs_cmd);
2215 return r;
2216
2263} 2217}
2264EXPORT_SYMBOL(dsi_vc_dcs_read); 2218EXPORT_SYMBOL(dsi_vc_dcs_read);
2265 2219
2220int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
2221{
2222 int r;
2223
2224 r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1);
2225
2226 if (r < 0)
2227 return r;
2228
2229 if (r != 1)
2230 return -EIO;
2231
2232 return 0;
2233}
2234EXPORT_SYMBOL(dsi_vc_dcs_read_1);
2235
2236int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data)
2237{
2238 int r;
2239
2240 r = dsi_vc_dcs_read(channel, dcs_cmd, (u8 *)data, 2);
2241
2242 if (r < 0)
2243 return r;
2244
2245 if (r != 2)
2246 return -EIO;
2247
2248 return 0;
2249}
2250EXPORT_SYMBOL(dsi_vc_dcs_read_2);
2266 2251
2267int dsi_vc_set_max_rx_packet_size(int channel, u16 len) 2252int dsi_vc_set_max_rx_packet_size(int channel, u16 len)
2268{ 2253{
@@ -2491,15 +2476,15 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2491 u32 r; 2476 u32 r;
2492 int buswidth = 0; 2477 int buswidth = 0;
2493 2478
2494 dsi_config_tx_fifo(DSI_FIFO_SIZE_128, 2479 dsi_config_tx_fifo(DSI_FIFO_SIZE_32,
2495 DSI_FIFO_SIZE_0, 2480 DSI_FIFO_SIZE_32,
2496 DSI_FIFO_SIZE_0, 2481 DSI_FIFO_SIZE_32,
2497 DSI_FIFO_SIZE_0); 2482 DSI_FIFO_SIZE_32);
2498 2483
2499 dsi_config_rx_fifo(DSI_FIFO_SIZE_128, 2484 dsi_config_rx_fifo(DSI_FIFO_SIZE_32,
2500 DSI_FIFO_SIZE_0, 2485 DSI_FIFO_SIZE_32,
2501 DSI_FIFO_SIZE_0, 2486 DSI_FIFO_SIZE_32,
2502 DSI_FIFO_SIZE_0); 2487 DSI_FIFO_SIZE_32);
2503 2488
2504 /* XXX what values for the timeouts? */ 2489 /* XXX what values for the timeouts? */
2505 dsi_set_stop_state_counter(1000); 2490 dsi_set_stop_state_counter(1000);
@@ -2537,12 +2522,9 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2537 dsi_write_reg(DSI_CTRL, r); 2522 dsi_write_reg(DSI_CTRL, r);
2538 2523
2539 dsi_vc_initial_config(0); 2524 dsi_vc_initial_config(0);
2540 2525 dsi_vc_initial_config(1);
2541 /* set all vc targets to peripheral 0 */ 2526 dsi_vc_initial_config(2);
2542 dsi.vc[0].dest_per = 0; 2527 dsi_vc_initial_config(3);
2543 dsi.vc[1].dest_per = 0;
2544 dsi.vc[2].dest_per = 0;
2545 dsi.vc[3].dest_per = 0;
2546 2528
2547 return 0; 2529 return 0;
2548} 2530}
@@ -2777,18 +2759,16 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2777 unsigned packet_payload; 2759 unsigned packet_payload;
2778 unsigned packet_len; 2760 unsigned packet_len;
2779 u32 l; 2761 u32 l;
2780 bool use_te_trigger; 2762 const unsigned channel = dsi.update_channel;
2781 const unsigned channel = 0;
2782 /* line buffer is 1024 x 24bits */ 2763 /* line buffer is 1024 x 24bits */
2783 /* XXX: for some reason using full buffer size causes considerable TX 2764 /* XXX: for some reason using full buffer size causes considerable TX
2784 * slowdown with update sizes that fill the whole buffer */ 2765 * slowdown with update sizes that fill the whole buffer */
2785 const unsigned line_buf_size = 1023 * 3; 2766 const unsigned line_buf_size = 1023 * 3;
2786 2767
2787 use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; 2768 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
2769 x, y, w, h);
2788 2770
2789 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) 2771 dsi_vc_config_vp(channel);
2790 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
2791 x, y, w, h);
2792 2772
2793 bytespp = dssdev->ctrl.pixel_size / 8; 2773 bytespp = dssdev->ctrl.pixel_size / 8;
2794 bytespl = w * bytespp; 2774 bytespl = w * bytespp;
@@ -2808,15 +2788,12 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2808 if (bytespf % packet_payload) 2788 if (bytespf % packet_payload)
2809 total_len += (bytespf % packet_payload) + 1; 2789 total_len += (bytespf % packet_payload) + 1;
2810 2790
2811 if (0)
2812 dsi_vc_print_status(1);
2813
2814 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ 2791 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
2815 dsi_write_reg(DSI_VC_TE(channel), l); 2792 dsi_write_reg(DSI_VC_TE(channel), l);
2816 2793
2817 dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0); 2794 dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0);
2818 2795
2819 if (use_te_trigger) 2796 if (dsi.te_enabled)
2820 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ 2797 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
2821 else 2798 else
2822 l = FLD_MOD(l, 1, 31, 31); /* TE_START */ 2799 l = FLD_MOD(l, 1, 31, 31); /* TE_START */
@@ -2830,9 +2807,14 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2830 */ 2807 */
2831 dispc_disable_sidle(); 2808 dispc_disable_sidle();
2832 2809
2810 dsi_perf_mark_start();
2811
2812 schedule_delayed_work(&dsi.framedone_timeout_work,
2813 msecs_to_jiffies(250));
2814
2833 dss_start_update(dssdev); 2815 dss_start_update(dssdev);
2834 2816
2835 if (use_te_trigger) { 2817 if (dsi.te_enabled) {
2836 /* disable LP_RX_TO, so that we can receive TE. Time to wait 2818 /* disable LP_RX_TO, so that we can receive TE. Time to wait
2837 * for TE is longer than the timer allows */ 2819 * for TE is longer than the timer allows */
2838 REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ 2820 REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
@@ -2852,110 +2834,64 @@ static void dsi_te_timeout(unsigned long arg)
2852} 2834}
2853#endif 2835#endif
2854 2836
2855static void dsi_framedone_irq_callback(void *data, u32 mask) 2837static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2856{ 2838{
2857 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and 2839 int r;
2858 * turns itself off. However, DSI still has the pixels in its buffers, 2840 const int channel = dsi.update_channel;
2859 * and is sending the data. 2841
2860 */ 2842 DSSERR("Framedone not received for 250ms!\n");
2861 2843
2862 /* SIDLEMODE back to smart-idle */ 2844 /* SIDLEMODE back to smart-idle */
2863 dispc_enable_sidle(); 2845 dispc_enable_sidle();
2864 2846
2865 dsi.framedone_received = true; 2847 if (dsi.te_enabled) {
2866 wake_up(&dsi.waitqueue); 2848 /* enable LP_RX_TO again after the TE */
2867} 2849 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2868
2869static void dsi_set_update_region(struct omap_dss_device *dssdev,
2870 u16 x, u16 y, u16 w, u16 h)
2871{
2872 spin_lock(&dsi.update_lock);
2873 if (dsi.update_region.dirty) {
2874 dsi.update_region.x = min(x, dsi.update_region.x);
2875 dsi.update_region.y = min(y, dsi.update_region.y);
2876 dsi.update_region.w = max(w, dsi.update_region.w);
2877 dsi.update_region.h = max(h, dsi.update_region.h);
2878 } else {
2879 dsi.update_region.x = x;
2880 dsi.update_region.y = y;
2881 dsi.update_region.w = w;
2882 dsi.update_region.h = h;
2883 } 2850 }
2884 2851
2885 dsi.update_region.device = dssdev; 2852 /* Send BTA after the frame. We need this for the TE to work, as TE
2886 dsi.update_region.dirty = true; 2853 * trigger is only sent for BTAs without preceding packet. Thus we need
2887 2854 * to BTA after the pixel packets so that next BTA will cause TE
2888 spin_unlock(&dsi.update_lock); 2855 * trigger.
2889 2856 *
2890} 2857 * This is not needed when TE is not in use, but we do it anyway to
2891 2858 * make sure that the transfer has been completed. It would be more
2892static int dsi_set_update_mode(struct omap_dss_device *dssdev, 2859 * optimal, but more complex, to wait only just before starting next
2893 enum omap_dss_update_mode mode) 2860 * transfer. */
2894{ 2861 r = dsi_vc_send_bta_sync(channel);
2895 int r = 0; 2862 if (r)
2896 int i; 2863 DSSERR("BTA after framedone failed\n");
2897
2898 WARN_ON(!mutex_is_locked(&dsi.bus_lock));
2899
2900 if (dsi.update_mode != mode) {
2901 dsi.update_mode = mode;
2902
2903 /* Mark the overlays dirty, and do apply(), so that we get the
2904 * overlays configured properly after update mode change. */
2905 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
2906 struct omap_overlay *ovl;
2907 ovl = omap_dss_get_overlay(i);
2908 if (ovl->manager == dssdev->manager)
2909 ovl->info_dirty = true;
2910 }
2911
2912 r = dssdev->manager->apply(dssdev->manager);
2913
2914 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE &&
2915 mode == OMAP_DSS_UPDATE_AUTO) {
2916 u16 w, h;
2917
2918 DSSDBG("starting auto update\n");
2919
2920 dssdev->get_resolution(dssdev, &w, &h);
2921
2922 dsi_set_update_region(dssdev, 0, 0, w, h);
2923
2924 dsi_perf_mark_start_auto();
2925 2864
2926 wake_up(&dsi.waitqueue); 2865 /* RX_FIFO_NOT_EMPTY */
2927 } 2866 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
2867 DSSERR("Received error during frame transfer:\n");
2868 dsi_vc_flush_receive_data(channel);
2928 } 2869 }
2929 2870
2930 return r; 2871 dsi.framedone_callback(-ETIMEDOUT, dsi.framedone_data);
2931} 2872}
2932 2873
2933static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) 2874static void dsi_framedone_irq_callback(void *data, u32 mask)
2934{ 2875{
2935 int r = 0; 2876 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and
2877 * turns itself off. However, DSI still has the pixels in its buffers,
2878 * and is sending the data.
2879 */
2936 2880
2937 if (dssdev->driver->enable_te) { 2881 /* SIDLEMODE back to smart-idle */
2938 r = dssdev->driver->enable_te(dssdev, enable); 2882 dispc_enable_sidle();
2939 /* XXX for some reason, DSI TE breaks if we don't wait here.
2940 * Panel bug? Needs more studying */
2941 msleep(100);
2942 }
2943 2883
2944 return r; 2884 schedule_work(&dsi.framedone_work);
2945} 2885}
2946 2886
2947static void dsi_handle_framedone(void) 2887static void dsi_handle_framedone(void)
2948{ 2888{
2949 int r; 2889 int r;
2950 const int channel = 0; 2890 const int channel = dsi.update_channel;
2951 bool use_te_trigger;
2952
2953 use_te_trigger = dsi.te_enabled && !dsi.use_ext_te;
2954 2891
2955 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) 2892 DSSDBG("FRAMEDONE\n");
2956 DSSDBG("FRAMEDONE\n");
2957 2893
2958 if (use_te_trigger) { 2894 if (dsi.te_enabled) {
2959 /* enable LP_RX_TO again after the TE */ 2895 /* enable LP_RX_TO again after the TE */
2960 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 2896 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2961 } 2897 }
@@ -2976,7 +2912,7 @@ static void dsi_handle_framedone(void)
2976 /* RX_FIFO_NOT_EMPTY */ 2912 /* RX_FIFO_NOT_EMPTY */
2977 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2913 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
2978 DSSERR("Received error during frame transfer:\n"); 2914 DSSERR("Received error during frame transfer:\n");
2979 dsi_vc_flush_receive_data(0); 2915 dsi_vc_flush_receive_data(channel);
2980 } 2916 }
2981 2917
2982#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC 2918#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
@@ -2984,118 +2920,79 @@ static void dsi_handle_framedone(void)
2984#endif 2920#endif
2985} 2921}
2986 2922
2987static int dsi_update_thread(void *data) 2923static void dsi_framedone_work_callback(struct work_struct *work)
2988{ 2924{
2989 unsigned long timeout; 2925 DSSDBGF();
2990 struct omap_dss_device *device;
2991 u16 x, y, w, h;
2992
2993 while (1) {
2994 bool sched;
2995
2996 wait_event_interruptible(dsi.waitqueue,
2997 dsi.update_mode == OMAP_DSS_UPDATE_AUTO ||
2998 (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
2999 dsi.update_region.dirty == true) ||
3000 kthread_should_stop());
3001
3002 if (kthread_should_stop())
3003 break;
3004
3005 dsi_bus_lock();
3006
3007 if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED ||
3008 kthread_should_stop()) {
3009 dsi_bus_unlock();
3010 break;
3011 }
3012
3013 dsi_perf_mark_setup();
3014
3015 if (dsi.update_region.dirty) {
3016 spin_lock(&dsi.update_lock);
3017 dsi.active_update_region = dsi.update_region;
3018 dsi.update_region.dirty = false;
3019 spin_unlock(&dsi.update_lock);
3020 }
3021 2926
3022 device = dsi.active_update_region.device; 2927 cancel_delayed_work_sync(&dsi.framedone_timeout_work);
3023 x = dsi.active_update_region.x;
3024 y = dsi.active_update_region.y;
3025 w = dsi.active_update_region.w;
3026 h = dsi.active_update_region.h;
3027 2928
3028 if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2929 dsi_handle_framedone();
3029 2930
3030 if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL) 2931 dsi_perf_show("DISPC");
3031 dss_setup_partial_planes(device,
3032 &x, &y, &w, &h);
3033 2932
3034 dispc_set_lcd_size(w, h); 2933 dsi.framedone_callback(0, dsi.framedone_data);
3035 } 2934}
3036 2935
3037 if (dsi.active_update_region.dirty) { 2936int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
3038 dsi.active_update_region.dirty = false; 2937 u16 *x, u16 *y, u16 *w, u16 *h)
3039 /* XXX TODO we don't need to send the coords, if they 2938{
3040 * are the same that are already programmed to the 2939 u16 dw, dh;
3041 * panel. That should speed up manual update a bit */
3042 device->driver->setup_update(device, x, y, w, h);
3043 }
3044 2940
3045 dsi_perf_mark_start(); 2941 dssdev->driver->get_resolution(dssdev, &dw, &dh);
3046 2942
3047 if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2943 if (*x > dw || *y > dh)
3048 dsi_vc_config_vp(0); 2944 return -EINVAL;
3049 2945
3050 if (dsi.te_enabled && dsi.use_ext_te) 2946 if (*x + *w > dw)
3051 device->driver->wait_for_te(device); 2947 return -EINVAL;
3052 2948
3053 dsi.framedone_received = false; 2949 if (*y + *h > dh)
2950 return -EINVAL;
3054 2951
3055 dsi_update_screen_dispc(device, x, y, w, h); 2952 if (*w == 1)
2953 return -EINVAL;
3056 2954
3057 /* wait for framedone */ 2955 if (*w == 0 || *h == 0)
3058 timeout = msecs_to_jiffies(1000); 2956 return -EINVAL;
3059 wait_event_timeout(dsi.waitqueue,
3060 dsi.framedone_received == true,
3061 timeout);
3062 2957
3063 if (!dsi.framedone_received) { 2958 dsi_perf_mark_setup();
3064 DSSERR("framedone timeout\n");
3065 DSSERR("failed update %d,%d %dx%d\n",
3066 x, y, w, h);
3067 2959
3068 dispc_enable_sidle(); 2960 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
3069 dispc_enable_lcd_out(0); 2961 dss_setup_partial_planes(dssdev, x, y, w, h);
2962 dispc_set_lcd_size(*w, *h);
2963 }
3070 2964
3071 dsi_reset_tx_fifo(0); 2965 return 0;
3072 } else { 2966}
3073 dsi_handle_framedone(); 2967EXPORT_SYMBOL(omap_dsi_prepare_update);
3074 dsi_perf_show("DISPC");
3075 }
3076 } else {
3077 dsi_update_screen_l4(device, x, y, w, h);
3078 dsi_perf_show("L4");
3079 }
3080 2968
3081 sched = atomic_read(&dsi.bus_lock.count) < 0; 2969int omap_dsi_update(struct omap_dss_device *dssdev,
2970 int channel,
2971 u16 x, u16 y, u16 w, u16 h,
2972 void (*callback)(int, void *), void *data)
2973{
2974 dsi.update_channel = channel;
3082 2975
3083 complete_all(&dsi.update_completion); 2976 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2977 dsi.framedone_callback = callback;
2978 dsi.framedone_data = data;
3084 2979
3085 dsi_bus_unlock(); 2980 dsi.update_region.x = x;
2981 dsi.update_region.y = y;
2982 dsi.update_region.w = w;
2983 dsi.update_region.h = h;
2984 dsi.update_region.device = dssdev;
3086 2985
3087 /* XXX We need to give others chance to get the bus lock. Is 2986 dsi_update_screen_dispc(dssdev, x, y, w, h);
3088 * there a better way for this? */ 2987 } else {
3089 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO && sched) 2988 dsi_update_screen_l4(dssdev, x, y, w, h);
3090 schedule_timeout_interruptible(1); 2989 dsi_perf_show("L4");
2990 callback(0, data);
3091 } 2991 }
3092 2992
3093 DSSDBG("update thread exiting\n");
3094
3095 return 0; 2993 return 0;
3096} 2994}
3097 2995EXPORT_SYMBOL(omap_dsi_update);
3098
3099 2996
3100/* Display funcs */ 2997/* Display funcs */
3101 2998
@@ -3203,7 +3100,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3203 if (r) 3100 if (r)
3204 goto err1; 3101 goto err1;
3205 3102
3206 dss_select_clk_source(true, true); 3103 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
3104 dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK);
3207 3105
3208 DSSDBG("PLL OK\n"); 3106 DSSDBG("PLL OK\n");
3209 3107
@@ -3229,25 +3127,18 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3229 3127
3230 /* enable interface */ 3128 /* enable interface */
3231 dsi_vc_enable(0, 1); 3129 dsi_vc_enable(0, 1);
3130 dsi_vc_enable(1, 1);
3131 dsi_vc_enable(2, 1);
3132 dsi_vc_enable(3, 1);
3232 dsi_if_enable(1); 3133 dsi_if_enable(1);
3233 dsi_force_tx_stop_mode_io(); 3134 dsi_force_tx_stop_mode_io();
3234 3135
3235 if (dssdev->driver->enable) {
3236 r = dssdev->driver->enable(dssdev);
3237 if (r)
3238 goto err4;
3239 }
3240
3241 /* enable high-speed after initial config */
3242 dsi_vc_enable_hs(0, 1);
3243
3244 return 0; 3136 return 0;
3245err4:
3246 dsi_if_enable(0);
3247err3: 3137err3:
3248 dsi_complexio_uninit(); 3138 dsi_complexio_uninit();
3249err2: 3139err2:
3250 dss_select_clk_source(false, false); 3140 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3141 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3251err1: 3142err1:
3252 dsi_pll_uninit(); 3143 dsi_pll_uninit();
3253err0: 3144err0:
@@ -3256,10 +3147,8 @@ err0:
3256 3147
3257static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) 3148static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3258{ 3149{
3259 if (dssdev->driver->disable) 3150 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3260 dssdev->driver->disable(dssdev); 3151 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3261
3262 dss_select_clk_source(false, false);
3263 dsi_complexio_uninit(); 3152 dsi_complexio_uninit();
3264 dsi_pll_uninit(); 3153 dsi_pll_uninit();
3265} 3154}
@@ -3280,14 +3169,15 @@ static int dsi_core_init(void)
3280 return 0; 3169 return 0;
3281} 3170}
3282 3171
3283static int dsi_display_enable(struct omap_dss_device *dssdev) 3172int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
3284{ 3173{
3285 int r = 0; 3174 int r = 0;
3286 3175
3287 DSSDBG("dsi_display_enable\n"); 3176 DSSDBG("dsi_display_enable\n");
3288 3177
3178 WARN_ON(!dsi_bus_is_locked());
3179
3289 mutex_lock(&dsi.lock); 3180 mutex_lock(&dsi.lock);
3290 dsi_bus_lock();
3291 3181
3292 r = omap_dss_start_device(dssdev); 3182 r = omap_dss_start_device(dssdev);
3293 if (r) { 3183 if (r) {
@@ -3295,100 +3185,47 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
3295 goto err0; 3185 goto err0;
3296 } 3186 }
3297 3187
3298 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
3299 DSSERR("dssdev already enabled\n");
3300 r = -EINVAL;
3301 goto err1;
3302 }
3303
3304 enable_clocks(1); 3188 enable_clocks(1);
3305 dsi_enable_pll_clock(1); 3189 dsi_enable_pll_clock(1);
3306 3190
3307 r = _dsi_reset(); 3191 r = _dsi_reset();
3308 if (r) 3192 if (r)
3309 goto err2; 3193 goto err1;
3310 3194
3311 dsi_core_init(); 3195 dsi_core_init();
3312 3196
3313 r = dsi_display_init_dispc(dssdev); 3197 r = dsi_display_init_dispc(dssdev);
3314 if (r) 3198 if (r)
3315 goto err2; 3199 goto err1;
3316 3200
3317 r = dsi_display_init_dsi(dssdev); 3201 r = dsi_display_init_dsi(dssdev);
3318 if (r) 3202 if (r)
3319 goto err3; 3203 goto err2;
3320
3321 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
3322
3323 dsi.use_ext_te = dssdev->phy.dsi.ext_te;
3324 r = dsi_set_te(dssdev, dsi.te_enabled);
3325 if (r)
3326 goto err4;
3327
3328 dsi_set_update_mode(dssdev, dsi.user_update_mode);
3329 3204
3330 dsi_bus_unlock();
3331 mutex_unlock(&dsi.lock); 3205 mutex_unlock(&dsi.lock);
3332 3206
3333 return 0; 3207 return 0;
3334 3208
3335err4:
3336
3337 dsi_display_uninit_dsi(dssdev);
3338err3:
3339 dsi_display_uninit_dispc(dssdev);
3340err2: 3209err2:
3210 dsi_display_uninit_dispc(dssdev);
3211err1:
3341 enable_clocks(0); 3212 enable_clocks(0);
3342 dsi_enable_pll_clock(0); 3213 dsi_enable_pll_clock(0);
3343err1:
3344 omap_dss_stop_device(dssdev); 3214 omap_dss_stop_device(dssdev);
3345err0: 3215err0:
3346 dsi_bus_unlock();
3347 mutex_unlock(&dsi.lock); 3216 mutex_unlock(&dsi.lock);
3348 DSSDBG("dsi_display_enable FAILED\n"); 3217 DSSDBG("dsi_display_enable FAILED\n");
3349 return r; 3218 return r;
3350} 3219}
3220EXPORT_SYMBOL(omapdss_dsi_display_enable);
3351 3221
3352static void dsi_display_disable(struct omap_dss_device *dssdev) 3222void omapdss_dsi_display_disable(struct omap_dss_device *dssdev)
3353{ 3223{
3354 DSSDBG("dsi_display_disable\n"); 3224 DSSDBG("dsi_display_disable\n");
3355 3225
3356 mutex_lock(&dsi.lock); 3226 WARN_ON(!dsi_bus_is_locked());
3357 dsi_bus_lock();
3358
3359 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
3360 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
3361 goto end;
3362
3363 dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
3364 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
3365
3366 dsi_display_uninit_dispc(dssdev);
3367
3368 dsi_display_uninit_dsi(dssdev);
3369
3370 enable_clocks(0);
3371 dsi_enable_pll_clock(0);
3372
3373 omap_dss_stop_device(dssdev);
3374end:
3375 dsi_bus_unlock();
3376 mutex_unlock(&dsi.lock);
3377}
3378
3379static int dsi_display_suspend(struct omap_dss_device *dssdev)
3380{
3381 DSSDBG("dsi_display_suspend\n");
3382 3227
3383 mutex_lock(&dsi.lock); 3228 mutex_lock(&dsi.lock);
3384 dsi_bus_lock();
3385
3386 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
3387 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
3388 goto end;
3389
3390 dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
3391 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
3392 3229
3393 dsi_display_uninit_dispc(dssdev); 3230 dsi_display_uninit_dispc(dssdev);
3394 3231
@@ -3396,312 +3233,19 @@ static int dsi_display_suspend(struct omap_dss_device *dssdev)
3396 3233
3397 enable_clocks(0); 3234 enable_clocks(0);
3398 dsi_enable_pll_clock(0); 3235 dsi_enable_pll_clock(0);
3399end:
3400 dsi_bus_unlock();
3401 mutex_unlock(&dsi.lock);
3402
3403 return 0;
3404}
3405
3406static int dsi_display_resume(struct omap_dss_device *dssdev)
3407{
3408 int r;
3409
3410 DSSDBG("dsi_display_resume\n");
3411
3412 mutex_lock(&dsi.lock);
3413 dsi_bus_lock();
3414
3415 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
3416 DSSERR("dssdev not suspended\n");
3417 r = -EINVAL;
3418 goto err0;
3419 }
3420
3421 enable_clocks(1);
3422 dsi_enable_pll_clock(1);
3423
3424 r = _dsi_reset();
3425 if (r)
3426 goto err1;
3427
3428 dsi_core_init();
3429
3430 r = dsi_display_init_dispc(dssdev);
3431 if (r)
3432 goto err1;
3433
3434 r = dsi_display_init_dsi(dssdev);
3435 if (r)
3436 goto err2;
3437
3438 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
3439
3440 r = dsi_set_te(dssdev, dsi.te_enabled);
3441 if (r)
3442 goto err2;
3443
3444 dsi_set_update_mode(dssdev, dsi.user_update_mode);
3445
3446 dsi_bus_unlock();
3447 mutex_unlock(&dsi.lock);
3448
3449 return 0;
3450
3451err2:
3452 dsi_display_uninit_dispc(dssdev);
3453err1:
3454 enable_clocks(0);
3455 dsi_enable_pll_clock(0);
3456err0:
3457 dsi_bus_unlock();
3458 mutex_unlock(&dsi.lock);
3459 DSSDBG("dsi_display_resume FAILED\n");
3460 return r;
3461}
3462
3463static int dsi_display_update(struct omap_dss_device *dssdev,
3464 u16 x, u16 y, u16 w, u16 h)
3465{
3466 int r = 0;
3467 u16 dw, dh;
3468
3469 DSSDBG("dsi_display_update(%d,%d %dx%d)\n", x, y, w, h);
3470 3236
3471 mutex_lock(&dsi.lock); 3237 omap_dss_stop_device(dssdev);
3472
3473 if (dsi.update_mode != OMAP_DSS_UPDATE_MANUAL)
3474 goto end;
3475
3476 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3477 goto end;
3478
3479 dssdev->get_resolution(dssdev, &dw, &dh);
3480
3481 if (x > dw || y > dh)
3482 goto end;
3483
3484 if (x + w > dw)
3485 w = dw - x;
3486
3487 if (y + h > dh)
3488 h = dh - y;
3489
3490 if (w == 0 || h == 0)
3491 goto end;
3492
3493 if (w == 1) {
3494 r = -EINVAL;
3495 goto end;
3496 }
3497
3498 dsi_set_update_region(dssdev, x, y, w, h);
3499
3500 wake_up(&dsi.waitqueue);
3501
3502end:
3503 mutex_unlock(&dsi.lock);
3504
3505 return r;
3506}
3507
3508static int dsi_display_sync(struct omap_dss_device *dssdev)
3509{
3510 bool wait;
3511
3512 DSSDBG("dsi_display_sync()\n");
3513
3514 mutex_lock(&dsi.lock);
3515 dsi_bus_lock();
3516
3517 if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
3518 dsi.update_region.dirty) {
3519 INIT_COMPLETION(dsi.update_completion);
3520 wait = true;
3521 } else {
3522 wait = false;
3523 }
3524
3525 dsi_bus_unlock();
3526 mutex_unlock(&dsi.lock);
3527
3528 if (wait)
3529 wait_for_completion_interruptible(&dsi.update_completion);
3530
3531 DSSDBG("dsi_display_sync() done\n");
3532 return 0;
3533}
3534
3535static int dsi_display_set_update_mode(struct omap_dss_device *dssdev,
3536 enum omap_dss_update_mode mode)
3537{
3538 int r = 0;
3539
3540 DSSDBGF("%d", mode);
3541
3542 mutex_lock(&dsi.lock);
3543 dsi_bus_lock();
3544
3545 dsi.user_update_mode = mode;
3546 r = dsi_set_update_mode(dssdev, mode);
3547 3238
3548 dsi_bus_unlock();
3549 mutex_unlock(&dsi.lock); 3239 mutex_unlock(&dsi.lock);
3550
3551 return r;
3552} 3240}
3241EXPORT_SYMBOL(omapdss_dsi_display_disable);
3553 3242
3554static enum omap_dss_update_mode dsi_display_get_update_mode( 3243int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
3555 struct omap_dss_device *dssdev)
3556{ 3244{
3557 return dsi.update_mode;
3558}
3559
3560
3561static int dsi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
3562{
3563 int r = 0;
3564
3565 DSSDBGF("%d", enable);
3566
3567 if (!dssdev->driver->enable_te)
3568 return -ENOENT;
3569
3570 dsi_bus_lock();
3571
3572 dsi.te_enabled = enable; 3245 dsi.te_enabled = enable;
3573
3574 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3575 goto end;
3576
3577 r = dsi_set_te(dssdev, enable);
3578end:
3579 dsi_bus_unlock();
3580
3581 return r;
3582}
3583
3584static int dsi_display_get_te(struct omap_dss_device *dssdev)
3585{
3586 return dsi.te_enabled;
3587}
3588
3589static int dsi_display_set_rotate(struct omap_dss_device *dssdev, u8 rotate)
3590{
3591
3592 DSSDBGF("%d", rotate);
3593
3594 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
3595 return -EINVAL;
3596
3597 dsi_bus_lock();
3598 dssdev->driver->set_rotate(dssdev, rotate);
3599 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
3600 u16 w, h;
3601 /* the display dimensions may have changed, so set a new
3602 * update region */
3603 dssdev->get_resolution(dssdev, &w, &h);
3604 dsi_set_update_region(dssdev, 0, 0, w, h);
3605 }
3606 dsi_bus_unlock();
3607
3608 return 0; 3246 return 0;
3609} 3247}
3610 3248EXPORT_SYMBOL(omapdss_dsi_enable_te);
3611static u8 dsi_display_get_rotate(struct omap_dss_device *dssdev)
3612{
3613 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
3614 return 0;
3615
3616 return dssdev->driver->get_rotate(dssdev);
3617}
3618
3619static int dsi_display_set_mirror(struct omap_dss_device *dssdev, bool mirror)
3620{
3621 DSSDBGF("%d", mirror);
3622
3623 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
3624 return -EINVAL;
3625
3626 dsi_bus_lock();
3627 dssdev->driver->set_mirror(dssdev, mirror);
3628 dsi_bus_unlock();
3629
3630 return 0;
3631}
3632
3633static bool dsi_display_get_mirror(struct omap_dss_device *dssdev)
3634{
3635 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
3636 return 0;
3637
3638 return dssdev->driver->get_mirror(dssdev);
3639}
3640
3641static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num)
3642{
3643 int r;
3644
3645 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3646 return -EIO;
3647
3648 DSSDBGF("%d", test_num);
3649
3650 dsi_bus_lock();
3651
3652 /* run test first in low speed mode */
3653 dsi_vc_enable_hs(0, 0);
3654
3655 if (dssdev->driver->run_test) {
3656 r = dssdev->driver->run_test(dssdev, test_num);
3657 if (r)
3658 goto end;
3659 }
3660
3661 /* then in high speed */
3662 dsi_vc_enable_hs(0, 1);
3663
3664 if (dssdev->driver->run_test) {
3665 r = dssdev->driver->run_test(dssdev, test_num);
3666 if (r)
3667 goto end;
3668 }
3669
3670end:
3671 dsi_vc_enable_hs(0, 1);
3672
3673 dsi_bus_unlock();
3674
3675 return r;
3676}
3677
3678static int dsi_display_memory_read(struct omap_dss_device *dssdev,
3679 void *buf, size_t size,
3680 u16 x, u16 y, u16 w, u16 h)
3681{
3682 int r;
3683
3684 DSSDBGF("");
3685
3686 if (!dssdev->driver->memory_read)
3687 return -EINVAL;
3688
3689 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3690 return -EIO;
3691
3692 dsi_bus_lock();
3693
3694 r = dssdev->driver->memory_read(dssdev, buf, size,
3695 x, y, w, h);
3696
3697 /* Memory read usually changes the update area. This will
3698 * force the next update to re-set the update area */
3699 dsi.active_update_region.dirty = true;
3700
3701 dsi_bus_unlock();
3702
3703 return r;
3704}
3705 3249
3706void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 3250void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
3707 u32 fifo_size, enum omap_burst_size *burst_size, 3251 u32 fifo_size, enum omap_burst_size *burst_size,
@@ -3720,26 +3264,6 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3720{ 3264{
3721 DSSDBG("DSI init\n"); 3265 DSSDBG("DSI init\n");
3722 3266
3723 dssdev->enable = dsi_display_enable;
3724 dssdev->disable = dsi_display_disable;
3725 dssdev->suspend = dsi_display_suspend;
3726 dssdev->resume = dsi_display_resume;
3727 dssdev->update = dsi_display_update;
3728 dssdev->sync = dsi_display_sync;
3729 dssdev->set_update_mode = dsi_display_set_update_mode;
3730 dssdev->get_update_mode = dsi_display_get_update_mode;
3731 dssdev->enable_te = dsi_display_enable_te;
3732 dssdev->get_te = dsi_display_get_te;
3733
3734 dssdev->get_rotate = dsi_display_get_rotate;
3735 dssdev->set_rotate = dsi_display_set_rotate;
3736
3737 dssdev->get_mirror = dsi_display_get_mirror;
3738 dssdev->set_mirror = dsi_display_set_mirror;
3739
3740 dssdev->run_test = dsi_display_run_test;
3741 dssdev->memory_read = dsi_display_memory_read;
3742
3743 /* XXX these should be figured out dynamically */ 3267 /* XXX these should be figured out dynamically */
3744 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 3268 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
3745 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 3269 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
@@ -3754,9 +3278,6 @@ int dsi_init(struct platform_device *pdev)
3754{ 3278{
3755 u32 rev; 3279 u32 rev;
3756 int r; 3280 int r;
3757 struct sched_param param = {
3758 .sched_priority = MAX_USER_RT_PRIO-1
3759 };
3760 3281
3761 spin_lock_init(&dsi.errors_lock); 3282 spin_lock_init(&dsi.errors_lock);
3762 dsi.errors = 0; 3283 dsi.errors = 0;
@@ -3767,31 +3288,19 @@ int dsi_init(struct platform_device *pdev)
3767#endif 3288#endif
3768 3289
3769 init_completion(&dsi.bta_completion); 3290 init_completion(&dsi.bta_completion);
3770 init_completion(&dsi.update_completion);
3771
3772 dsi.thread = kthread_create(dsi_update_thread, NULL, "dsi");
3773 if (IS_ERR(dsi.thread)) {
3774 DSSERR("cannot create kthread\n");
3775 r = PTR_ERR(dsi.thread);
3776 goto err0;
3777 }
3778 sched_setscheduler(dsi.thread, SCHED_FIFO, &param);
3779
3780 init_waitqueue_head(&dsi.waitqueue);
3781 spin_lock_init(&dsi.update_lock);
3782 3291
3783 mutex_init(&dsi.lock); 3292 mutex_init(&dsi.lock);
3784 mutex_init(&dsi.bus_lock); 3293 sema_init(&dsi.bus_lock, 1);
3294
3295 INIT_WORK(&dsi.framedone_work, dsi_framedone_work_callback);
3296 INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work,
3297 dsi_framedone_timeout_work_callback);
3785 3298
3786#ifdef DSI_CATCH_MISSING_TE 3299#ifdef DSI_CATCH_MISSING_TE
3787 init_timer(&dsi.te_timer); 3300 init_timer(&dsi.te_timer);
3788 dsi.te_timer.function = dsi_te_timeout; 3301 dsi.te_timer.function = dsi_te_timeout;
3789 dsi.te_timer.data = 0; 3302 dsi.te_timer.data = 0;
3790#endif 3303#endif
3791
3792 dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
3793 dsi.user_update_mode = OMAP_DSS_UPDATE_DISABLED;
3794
3795 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); 3304 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS);
3796 if (!dsi.base) { 3305 if (!dsi.base) {
3797 DSSERR("can't ioremap DSI\n"); 3306 DSSERR("can't ioremap DSI\n");
@@ -3799,7 +3308,7 @@ int dsi_init(struct platform_device *pdev)
3799 goto err1; 3308 goto err1;
3800 } 3309 }
3801 3310
3802 dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi"); 3311 dsi.vdds_dsi_reg = dss_get_vdds_dsi();
3803 if (IS_ERR(dsi.vdds_dsi_reg)) { 3312 if (IS_ERR(dsi.vdds_dsi_reg)) {
3804 iounmap(dsi.base); 3313 iounmap(dsi.base);
3805 DSSERR("can't get VDDS_DSI regulator\n"); 3314 DSSERR("can't get VDDS_DSI regulator\n");
@@ -3815,23 +3324,15 @@ int dsi_init(struct platform_device *pdev)
3815 3324
3816 enable_clocks(0); 3325 enable_clocks(0);
3817 3326
3818 wake_up_process(dsi.thread);
3819
3820 return 0; 3327 return 0;
3821err2: 3328err2:
3822 iounmap(dsi.base); 3329 iounmap(dsi.base);
3823err1: 3330err1:
3824 kthread_stop(dsi.thread);
3825err0:
3826 return r; 3331 return r;
3827} 3332}
3828 3333
3829void dsi_exit(void) 3334void dsi_exit(void)
3830{ 3335{
3831 kthread_stop(dsi.thread);
3832
3833 regulator_put(dsi.vdds_dsi_reg);
3834
3835 iounmap(dsi.base); 3336 iounmap(dsi.base);
3836 3337
3837 DSSDBG("omap_dsi_exit\n"); 3338 DSSDBG("omap_dsi_exit\n");
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 0a26b7d84d41..8254a4232a53 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -68,6 +68,9 @@ static struct {
68 struct dss_clock_info cache_dss_cinfo; 68 struct dss_clock_info cache_dss_cinfo;
69 struct dispc_clock_info cache_dispc_cinfo; 69 struct dispc_clock_info cache_dispc_cinfo;
70 70
71 enum dss_clk_source dsi_clk_source;
72 enum dss_clk_source dispc_clk_source;
73
71 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 74 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
72} dss; 75} dss;
73 76
@@ -247,23 +250,42 @@ void dss_dump_regs(struct seq_file *s)
247#undef DUMPREG 250#undef DUMPREG
248} 251}
249 252
250void dss_select_clk_source(bool dsi, bool dispc) 253void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
254{
255 int b;
256
257 BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK &&
258 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
259
260 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
261
262 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */
263
264 dss.dispc_clk_source = clk_src;
265}
266
267void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
251{ 268{
252 u32 r; 269 int b;
253 r = dss_read_reg(DSS_CONTROL); 270
254 r = FLD_MOD(r, dsi, 1, 1); /* DSI_CLK_SWITCH */ 271 BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK &&
255 r = FLD_MOD(r, dispc, 0, 0); /* DISPC_CLK_SWITCH */ 272 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
256 dss_write_reg(DSS_CONTROL, r); 273
274 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
275
276 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
277
278 dss.dsi_clk_source = clk_src;
257} 279}
258 280
259int dss_get_dsi_clk_source(void) 281enum dss_clk_source dss_get_dispc_clk_source(void)
260{ 282{
261 return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1); 283 return dss.dispc_clk_source;
262} 284}
263 285
264int dss_get_dispc_clk_source(void) 286enum dss_clk_source dss_get_dsi_clk_source(void)
265{ 287{
266 return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0); 288 return dss.dsi_clk_source;
267} 289}
268 290
269/* calculate clock rates using dividers in cinfo */ 291/* calculate clock rates using dividers in cinfo */
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 2bcb1245d6c2..24326a5fd292 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -119,6 +119,12 @@ enum dss_clock {
119 DSS_CLK_96M = 1 << 4, 119 DSS_CLK_96M = 1 << 4,
120}; 120};
121 121
122enum dss_clk_source {
123 DSS_SRC_DSI1_PLL_FCLK,
124 DSS_SRC_DSI2_PLL_FCLK,
125 DSS_SRC_DSS1_ALWON_FCLK,
126};
127
122struct dss_clock_info { 128struct dss_clock_info {
123 /* rates that we get with dividers below */ 129 /* rates that we get with dividers below */
124 unsigned long fck; 130 unsigned long fck;
@@ -169,6 +175,9 @@ unsigned long dss_clk_get_rate(enum dss_clock clk);
169int dss_need_ctx_restore(void); 175int dss_need_ctx_restore(void);
170void dss_dump_clocks(struct seq_file *s); 176void dss_dump_clocks(struct seq_file *s);
171struct bus_type *dss_get_bus(void); 177struct bus_type *dss_get_bus(void);
178struct regulator *dss_get_vdds_dsi(void);
179struct regulator *dss_get_vdds_sdi(void);
180struct regulator *dss_get_vdda_dac(void);
172 181
173/* display */ 182/* display */
174int dss_suspend_all_devices(void); 183int dss_suspend_all_devices(void);
@@ -216,9 +225,11 @@ void dss_sdi_init(u8 datapairs);
216int dss_sdi_enable(void); 225int dss_sdi_enable(void);
217void dss_sdi_disable(void); 226void dss_sdi_disable(void);
218 227
219void dss_select_clk_source(bool dsi, bool dispc); 228void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
220int dss_get_dsi_clk_source(void); 229void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
221int dss_get_dispc_clk_source(void); 230enum dss_clk_source dss_get_dispc_clk_source(void);
231enum dss_clk_source dss_get_dsi_clk_source(void);
232
222void dss_set_venc_output(enum omap_dss_venc_type type); 233void dss_set_venc_output(enum omap_dss_venc_type type);
223void dss_set_dac_pwrdn_bgz(bool enable); 234void dss_set_dac_pwrdn_bgz(bool enable);
224 235
@@ -261,7 +272,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
261 u32 *fifo_low, u32 *fifo_high); 272 u32 *fifo_low, u32 *fifo_high);
262 273
263/* DPI */ 274/* DPI */
264int dpi_init(void); 275int dpi_init(struct platform_device *pdev);
265void dpi_exit(void); 276void dpi_exit(void);
266int dpi_init_display(struct omap_dss_device *dssdev); 277int dpi_init_display(struct omap_dss_device *dssdev);
267 278
@@ -313,8 +324,8 @@ int dispc_setup_plane(enum omap_plane plane,
313 324
314bool dispc_go_busy(enum omap_channel channel); 325bool dispc_go_busy(enum omap_channel channel);
315void dispc_go(enum omap_channel channel); 326void dispc_go(enum omap_channel channel);
316void dispc_enable_lcd_out(bool enable); 327void dispc_enable_channel(enum omap_channel channel, bool enable);
317void dispc_enable_digit_out(bool enable); 328bool dispc_is_channel_enabled(enum omap_channel channel);
318int dispc_enable_plane(enum omap_plane plane, bool enable); 329int dispc_enable_plane(enum omap_plane plane, bool enable);
319void dispc_enable_replication(enum omap_plane plane, bool enable); 330void dispc_enable_replication(enum omap_plane plane, bool enable);
320 331
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 27d9c465c851..913142d4cab1 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -501,6 +501,19 @@ static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
501 return 0; 501 return 0;
502} 502}
503 503
504static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
505{
506 unsigned long timeout = msecs_to_jiffies(500);
507 u32 irq;
508
509 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
510 irq = DISPC_IRQ_EVSYNC_ODD;
511 else
512 irq = DISPC_IRQ_VSYNC;
513
514 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
515}
516
504static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) 517static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
505{ 518{
506 unsigned long timeout = msecs_to_jiffies(500); 519 unsigned long timeout = msecs_to_jiffies(500);
@@ -509,17 +522,18 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
509 u32 irq; 522 u32 irq;
510 int r; 523 int r;
511 int i; 524 int i;
525 struct omap_dss_device *dssdev = mgr->device;
512 526
513 if (!mgr->device) 527 if (!dssdev)
514 return 0; 528 return 0;
515 529
516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 530 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
517 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 531 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
518 channel = OMAP_DSS_CHANNEL_DIGIT; 532 channel = OMAP_DSS_CHANNEL_DIGIT;
519 } else { 533 } else {
520 if (mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 534 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
521 enum omap_dss_update_mode mode; 535 enum omap_dss_update_mode mode;
522 mode = mgr->device->get_update_mode(mgr->device); 536 mode = dssdev->driver->get_update_mode(dssdev);
523 if (mode != OMAP_DSS_UPDATE_AUTO) 537 if (mode != OMAP_DSS_UPDATE_AUTO)
524 return 0; 538 return 0;
525 539
@@ -592,7 +606,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
592 } else { 606 } else {
593 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 607 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
594 enum omap_dss_update_mode mode; 608 enum omap_dss_update_mode mode;
595 mode = dssdev->get_update_mode(dssdev); 609 mode = dssdev->driver->get_update_mode(dssdev);
596 if (mode != OMAP_DSS_UPDATE_AUTO) 610 if (mode != OMAP_DSS_UPDATE_AUTO)
597 return 0; 611 return 0;
598 612
@@ -1064,7 +1078,7 @@ void dss_start_update(struct omap_dss_device *dssdev)
1064 mc->shadow_dirty = false; 1078 mc->shadow_dirty = false;
1065 } 1079 }
1066 1080
1067 dispc_enable_lcd_out(1); 1081 dssdev->manager->enable(dssdev->manager);
1068} 1082}
1069 1083
1070static void dss_apply_irq_handler(void *data, u32 mask) 1084static void dss_apply_irq_handler(void *data, u32 mask)
@@ -1196,7 +1210,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1196 1210
1197 oc->manual_update = 1211 oc->manual_update =
1198 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && 1212 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
1199 dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; 1213 dssdev->driver->get_update_mode(dssdev) !=
1214 OMAP_DSS_UPDATE_AUTO;
1200 1215
1201 ++num_planes_enabled; 1216 ++num_planes_enabled;
1202 } 1217 }
@@ -1237,7 +1252,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1237 1252
1238 mc->manual_update = 1253 mc->manual_update =
1239 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && 1254 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
1240 dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; 1255 dssdev->driver->get_update_mode(dssdev) !=
1256 OMAP_DSS_UPDATE_AUTO;
1241 } 1257 }
1242 1258
1243 /* XXX TODO: Try to get fifomerge working. The problem is that it 1259 /* XXX TODO: Try to get fifomerge working. The problem is that it
@@ -1351,6 +1367,18 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
1351 *info = mgr->info; 1367 *info = mgr->info;
1352} 1368}
1353 1369
1370static int dss_mgr_enable(struct omap_overlay_manager *mgr)
1371{
1372 dispc_enable_channel(mgr->id, 1);
1373 return 0;
1374}
1375
1376static int dss_mgr_disable(struct omap_overlay_manager *mgr)
1377{
1378 dispc_enable_channel(mgr->id, 0);
1379 return 0;
1380}
1381
1354static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager) 1382static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
1355{ 1383{
1356 ++num_managers; 1384 ++num_managers;
@@ -1394,6 +1422,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1394 mgr->set_manager_info = &omap_dss_mgr_set_info; 1422 mgr->set_manager_info = &omap_dss_mgr_set_info;
1395 mgr->get_manager_info = &omap_dss_mgr_get_info; 1423 mgr->get_manager_info = &omap_dss_mgr_get_info;
1396 mgr->wait_for_go = &dss_mgr_wait_for_go; 1424 mgr->wait_for_go = &dss_mgr_wait_for_go;
1425 mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
1426
1427 mgr->enable = &dss_mgr_enable;
1428 mgr->disable = &dss_mgr_disable;
1397 1429
1398 mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC; 1430 mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC;
1399 1431
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index b7f9a7339842..0c5bea263ac6 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -350,7 +350,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
350 return -EINVAL; 350 return -EINVAL;
351 } 351 }
352 352
353 dssdev->get_resolution(dssdev, &dw, &dh); 353 dssdev->driver->get_resolution(dssdev, &dw, &dh);
354 354
355 DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n", 355 DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
356 ovl->id, 356 ovl->id,
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index b936495c065d..cc23f53cc62d 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -36,8 +36,6 @@
36#include <plat/display.h> 36#include <plat/display.h>
37#include "dss.h" 37#include "dss.h"
38 38
39/*#define MEASURE_PERF*/
40
41#define RFBI_BASE 0x48050800 39#define RFBI_BASE 0x48050800
42 40
43struct rfbi_reg { u16 idx; }; 41struct rfbi_reg { u16 idx; };
@@ -66,8 +64,6 @@ struct rfbi_reg { u16 idx; };
66#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090) 64#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090)
67#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094) 65#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094)
68 66
69#define RFBI_CMD_FIFO_LEN_BYTES (16 * sizeof(struct update_param))
70
71#define REG_FLD_MOD(idx, val, start, end) \ 67#define REG_FLD_MOD(idx, val, start, end) \
72 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end)) 68 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
73 69
@@ -102,7 +98,6 @@ enum update_cmd {
102 98
103static int rfbi_convert_timings(struct rfbi_timings *t); 99static int rfbi_convert_timings(struct rfbi_timings *t);
104static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 100static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
105static void process_cmd_fifo(void);
106 101
107static struct { 102static struct {
108 void __iomem *base; 103 void __iomem *base;
@@ -125,11 +120,6 @@ static struct {
125 struct completion cmd_done; 120 struct completion cmd_done;
126 atomic_t cmd_fifo_full; 121 atomic_t cmd_fifo_full;
127 atomic_t cmd_pending; 122 atomic_t cmd_pending;
128#ifdef MEASURE_PERF
129 unsigned perf_bytes;
130 ktime_t perf_setup_time;
131 ktime_t perf_start_time;
132#endif
133} rfbi; 123} rfbi;
134 124
135struct update_region { 125struct update_region {
@@ -139,16 +129,6 @@ struct update_region {
139 u16 h; 129 u16 h;
140}; 130};
141 131
142struct update_param {
143 u8 rfbi_module;
144 u8 cmd;
145
146 union {
147 struct update_region r;
148 struct completion *sync;
149 } par;
150};
151
152static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) 132static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
153{ 133{
154 __raw_writel(val, rfbi.base + idx.idx); 134 __raw_writel(val, rfbi.base + idx.idx);
@@ -321,55 +301,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
321} 301}
322EXPORT_SYMBOL(omap_rfbi_write_pixels); 302EXPORT_SYMBOL(omap_rfbi_write_pixels);
323 303
324#ifdef MEASURE_PERF
325static void perf_mark_setup(void)
326{
327 rfbi.perf_setup_time = ktime_get();
328}
329
330static void perf_mark_start(void)
331{
332 rfbi.perf_start_time = ktime_get();
333}
334
335static void perf_show(const char *name)
336{
337 ktime_t t, setup_time, trans_time;
338 u32 total_bytes;
339 u32 setup_us, trans_us, total_us;
340
341 t = ktime_get();
342
343 setup_time = ktime_sub(rfbi.perf_start_time, rfbi.perf_setup_time);
344 setup_us = (u32)ktime_to_us(setup_time);
345 if (setup_us == 0)
346 setup_us = 1;
347
348 trans_time = ktime_sub(t, rfbi.perf_start_time);
349 trans_us = (u32)ktime_to_us(trans_time);
350 if (trans_us == 0)
351 trans_us = 1;
352
353 total_us = setup_us + trans_us;
354
355 total_bytes = rfbi.perf_bytes;
356
357 DSSINFO("%s update %u us + %u us = %u us (%uHz), %u bytes, "
358 "%u kbytes/sec\n",
359 name,
360 setup_us,
361 trans_us,
362 total_us,
363 1000*1000 / total_us,
364 total_bytes,
365 total_bytes * 1000 / total_us);
366}
367#else
368#define perf_mark_setup()
369#define perf_mark_start()
370#define perf_show(x)
371#endif
372
373void rfbi_transfer_area(u16 width, u16 height, 304void rfbi_transfer_area(u16 width, u16 height,
374 void (callback)(void *data), void *data) 305 void (callback)(void *data), void *data)
375{ 306{
@@ -382,7 +313,7 @@ void rfbi_transfer_area(u16 width, u16 height,
382 313
383 dispc_set_lcd_size(width, height); 314 dispc_set_lcd_size(width, height);
384 315
385 dispc_enable_lcd_out(1); 316 dispc_enable_channel(OMAP_DSS_CHANNEL_LCD, true);
386 317
387 rfbi.framedone_callback = callback; 318 rfbi.framedone_callback = callback;
388 rfbi.framedone_callback_data = data; 319 rfbi.framedone_callback_data = data;
@@ -396,8 +327,6 @@ void rfbi_transfer_area(u16 width, u16 height,
396 if (!rfbi.te_enabled) 327 if (!rfbi.te_enabled)
397 l = FLD_MOD(l, 1, 4, 4); /* ITE */ 328 l = FLD_MOD(l, 1, 4, 4); /* ITE */
398 329
399 perf_mark_start();
400
401 rfbi_write_reg(RFBI_CONTROL, l); 330 rfbi_write_reg(RFBI_CONTROL, l);
402} 331}
403 332
@@ -407,8 +336,6 @@ static void framedone_callback(void *data, u32 mask)
407 336
408 DSSDBG("FRAMEDONE\n"); 337 DSSDBG("FRAMEDONE\n");
409 338
410 perf_show("DISPC");
411
412 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); 339 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
413 340
414 rfbi_enable_clocks(0); 341 rfbi_enable_clocks(0);
@@ -416,11 +343,10 @@ static void framedone_callback(void *data, u32 mask)
416 callback = rfbi.framedone_callback; 343 callback = rfbi.framedone_callback;
417 rfbi.framedone_callback = NULL; 344 rfbi.framedone_callback = NULL;
418 345
419 /*callback(rfbi.framedone_callback_data);*/ 346 if (callback != NULL)
347 callback(rfbi.framedone_callback_data);
420 348
421 atomic_set(&rfbi.cmd_pending, 0); 349 atomic_set(&rfbi.cmd_pending, 0);
422
423 process_cmd_fifo();
424} 350}
425 351
426#if 1 /* VERBOSE */ 352#if 1 /* VERBOSE */
@@ -937,52 +863,43 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
937} 863}
938EXPORT_SYMBOL(rfbi_configure); 864EXPORT_SYMBOL(rfbi_configure);
939 865
940static int rfbi_find_display(struct omap_dss_device *dssdev) 866int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
867 u16 *x, u16 *y, u16 *w, u16 *h)
941{ 868{
942 if (dssdev == rfbi.dssdev[0]) 869 u16 dw, dh;
943 return 0;
944 870
945 if (dssdev == rfbi.dssdev[1]) 871 dssdev->driver->get_resolution(dssdev, &dw, &dh);
946 return 1;
947 872
948 BUG(); 873 if (*x > dw || *y > dh)
949 return -1; 874 return -EINVAL;
950}
951 875
876 if (*x + *w > dw)
877 return -EINVAL;
952 878
953static void signal_fifo_waiters(void) 879 if (*y + *h > dh)
954{ 880 return -EINVAL;
955 if (atomic_read(&rfbi.cmd_fifo_full) > 0) {
956 /* DSSDBG("SIGNALING: Fifo not full for waiter!\n"); */
957 complete(&rfbi.cmd_done);
958 atomic_dec(&rfbi.cmd_fifo_full);
959 }
960}
961 881
962/* returns 1 for async op, and 0 for sync op */ 882 if (*w == 1)
963static int do_update(struct omap_dss_device *dssdev, struct update_region *upd) 883 return -EINVAL;
964{
965 u16 x = upd->x;
966 u16 y = upd->y;
967 u16 w = upd->w;
968 u16 h = upd->h;
969 884
970 perf_mark_setup(); 885 if (*w == 0 || *h == 0)
886 return -EINVAL;
971 887
972 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
973 /*dssdev->driver->enable_te(dssdev, 1); */ 889 dss_setup_partial_planes(dssdev, x, y, w, h);
974 dss_setup_partial_planes(dssdev, &x, &y, &w, &h); 890 dispc_set_lcd_size(*w, *h);
975 } 891 }
976 892
977#ifdef MEASURE_PERF 893 return 0;
978 rfbi.perf_bytes = w * h * 2; /* XXX always 16bit */ 894}
979#endif 895EXPORT_SYMBOL(omap_rfbi_prepare_update);
980
981 dssdev->driver->setup_update(dssdev, x, y, w, h);
982 896
897int omap_rfbi_update(struct omap_dss_device *dssdev,
898 u16 x, u16 y, u16 w, u16 h,
899 void (*callback)(void *), void *data)
900{
983 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 901 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
984 rfbi_transfer_area(w, h, NULL, NULL); 902 rfbi_transfer_area(w, h, callback, data);
985 return 1;
986 } else { 903 } else {
987 struct omap_overlay *ovl; 904 struct omap_overlay *ovl;
988 void __iomem *addr; 905 void __iomem *addr;
@@ -994,123 +911,12 @@ static int do_update(struct omap_dss_device *dssdev, struct update_region *upd)
994 911
995 omap_rfbi_write_pixels(addr, scr_width, x, y, w, h); 912 omap_rfbi_write_pixels(addr, scr_width, x, y, w, h);
996 913
997 perf_show("L4"); 914 callback(data);
998
999 return 0;
1000 } 915 }
1001}
1002
1003static void process_cmd_fifo(void)
1004{
1005 int len;
1006 struct update_param p;
1007 struct omap_dss_device *dssdev;
1008 unsigned long flags;
1009
1010 if (atomic_inc_return(&rfbi.cmd_pending) != 1)
1011 return;
1012
1013 while (true) {
1014 spin_lock_irqsave(&rfbi.cmd_lock, flags);
1015
1016 len = kfifo_out(&rfbi.cmd_fifo, (unsigned char *)&p,
1017 sizeof(struct update_param));
1018 if (len == 0) {
1019 DSSDBG("nothing more in fifo\n");
1020 atomic_set(&rfbi.cmd_pending, 0);
1021 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1022 break;
1023 }
1024
1025 /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/
1026
1027 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1028
1029 BUG_ON(len != sizeof(struct update_param));
1030 BUG_ON(p.rfbi_module > 1);
1031
1032 dssdev = rfbi.dssdev[p.rfbi_module];
1033
1034 if (p.cmd == RFBI_CMD_UPDATE) {
1035 if (do_update(dssdev, &p.par.r))
1036 break; /* async op */
1037 } else if (p.cmd == RFBI_CMD_SYNC) {
1038 DSSDBG("Signaling SYNC done!\n");
1039 complete(p.par.sync);
1040 } else
1041 BUG();
1042 }
1043
1044 signal_fifo_waiters();
1045}
1046 916
1047static void rfbi_push_cmd(struct update_param *p) 917 return 0;
1048{
1049 int ret;
1050
1051 while (1) {
1052 unsigned long flags;
1053 int available;
1054
1055 spin_lock_irqsave(&rfbi.cmd_lock, flags);
1056 available = RFBI_CMD_FIFO_LEN_BYTES -
1057 kfifo_len(&rfbi.cmd_fifo);
1058
1059/* DSSDBG("%d bytes left in fifo\n", available); */
1060 if (available < sizeof(struct update_param)) {
1061 DSSDBG("Going to wait because FIFO FULL..\n");
1062 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1063 atomic_inc(&rfbi.cmd_fifo_full);
1064 wait_for_completion(&rfbi.cmd_done);
1065 /*DSSDBG("Woke up because fifo not full anymore\n");*/
1066 continue;
1067 }
1068
1069 ret = kfifo_in(&rfbi.cmd_fifo, (unsigned char *)p,
1070 sizeof(struct update_param));
1071/* DSSDBG("pushed %d bytes\n", ret);*/
1072
1073 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1074
1075 BUG_ON(ret != sizeof(struct update_param));
1076
1077 break;
1078 }
1079}
1080
1081static void rfbi_push_update(int rfbi_module, int x, int y, int w, int h)
1082{
1083 struct update_param p;
1084
1085 p.rfbi_module = rfbi_module;
1086 p.cmd = RFBI_CMD_UPDATE;
1087
1088 p.par.r.x = x;
1089 p.par.r.y = y;
1090 p.par.r.w = w;
1091 p.par.r.h = h;
1092
1093 DSSDBG("RFBI pushed %d,%d %dx%d\n", x, y, w, h);
1094
1095 rfbi_push_cmd(&p);
1096
1097 process_cmd_fifo();
1098}
1099
1100static void rfbi_push_sync(int rfbi_module, struct completion *sync_comp)
1101{
1102 struct update_param p;
1103
1104 p.rfbi_module = rfbi_module;
1105 p.cmd = RFBI_CMD_SYNC;
1106 p.par.sync = sync_comp;
1107
1108 rfbi_push_cmd(&p);
1109
1110 DSSDBG("RFBI sync pushed to cmd fifo\n");
1111
1112 process_cmd_fifo();
1113} 918}
919EXPORT_SYMBOL(omap_rfbi_update);
1114 920
1115void rfbi_dump_regs(struct seq_file *s) 921void rfbi_dump_regs(struct seq_file *s)
1116{ 922{
@@ -1155,12 +961,8 @@ int rfbi_init(void)
1155{ 961{
1156 u32 rev; 962 u32 rev;
1157 u32 l; 963 u32 l;
1158 int r;
1159 964
1160 spin_lock_init(&rfbi.cmd_lock); 965 spin_lock_init(&rfbi.cmd_lock);
1161 r = kfifo_alloc(&rfbi.cmd_fifo, RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL);
1162 if (r)
1163 return r;
1164 966
1165 init_completion(&rfbi.cmd_done); 967 init_completion(&rfbi.cmd_done);
1166 atomic_set(&rfbi.cmd_fifo_full, 0); 968 atomic_set(&rfbi.cmd_fifo_full, 0);
@@ -1196,49 +998,10 @@ void rfbi_exit(void)
1196{ 998{
1197 DSSDBG("rfbi_exit\n"); 999 DSSDBG("rfbi_exit\n");
1198 1000
1199 kfifo_free(&rfbi.cmd_fifo);
1200
1201 iounmap(rfbi.base); 1001 iounmap(rfbi.base);
1202} 1002}
1203 1003
1204/* struct omap_display support */ 1004int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1205static int rfbi_display_update(struct omap_dss_device *dssdev,
1206 u16 x, u16 y, u16 w, u16 h)
1207{
1208 int rfbi_module;
1209
1210 if (w == 0 || h == 0)
1211 return 0;
1212
1213 rfbi_module = rfbi_find_display(dssdev);
1214
1215 rfbi_push_update(rfbi_module, x, y, w, h);
1216
1217 return 0;
1218}
1219
1220static int rfbi_display_sync(struct omap_dss_device *dssdev)
1221{
1222 struct completion sync_comp;
1223 int rfbi_module;
1224
1225 rfbi_module = rfbi_find_display(dssdev);
1226
1227 init_completion(&sync_comp);
1228 rfbi_push_sync(rfbi_module, &sync_comp);
1229 DSSDBG("Waiting for SYNC to happen...\n");
1230 wait_for_completion(&sync_comp);
1231 DSSDBG("Released from SYNC\n");
1232 return 0;
1233}
1234
1235static int rfbi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
1236{
1237 dssdev->driver->enable_te(dssdev, enable);
1238 return 0;
1239}
1240
1241static int rfbi_display_enable(struct omap_dss_device *dssdev)
1242{ 1005{
1243 int r; 1006 int r;
1244 1007
@@ -1269,41 +1032,25 @@ static int rfbi_display_enable(struct omap_dss_device *dssdev)
1269 &dssdev->ctrl.rfbi_timings); 1032 &dssdev->ctrl.rfbi_timings);
1270 1033
1271 1034
1272 if (dssdev->driver->enable) {
1273 r = dssdev->driver->enable(dssdev);
1274 if (r)
1275 goto err2;
1276 }
1277
1278 return 0; 1035 return 0;
1279err2:
1280 omap_dispc_unregister_isr(framedone_callback, NULL,
1281 DISPC_IRQ_FRAMEDONE);
1282err1: 1036err1:
1283 omap_dss_stop_device(dssdev); 1037 omap_dss_stop_device(dssdev);
1284err0: 1038err0:
1285 return r; 1039 return r;
1286} 1040}
1041EXPORT_SYMBOL(omapdss_rfbi_display_enable);
1287 1042
1288static void rfbi_display_disable(struct omap_dss_device *dssdev) 1043void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
1289{ 1044{
1290 dssdev->driver->disable(dssdev);
1291 omap_dispc_unregister_isr(framedone_callback, NULL, 1045 omap_dispc_unregister_isr(framedone_callback, NULL,
1292 DISPC_IRQ_FRAMEDONE); 1046 DISPC_IRQ_FRAMEDONE);
1293 omap_dss_stop_device(dssdev); 1047 omap_dss_stop_device(dssdev);
1294} 1048}
1049EXPORT_SYMBOL(omapdss_rfbi_display_disable);
1295 1050
1296int rfbi_init_display(struct omap_dss_device *dssdev) 1051int rfbi_init_display(struct omap_dss_device *dssdev)
1297{ 1052{
1298 dssdev->enable = rfbi_display_enable;
1299 dssdev->disable = rfbi_display_disable;
1300 dssdev->update = rfbi_display_update;
1301 dssdev->sync = rfbi_display_sync;
1302 dssdev->enable_te = rfbi_display_enable_te;
1303
1304 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; 1053 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
1305
1306 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 1054 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1307
1308 return 0; 1055 return 0;
1309} 1056}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index c24f307d3da1..12eb4042dd82 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -41,7 +41,7 @@ static void sdi_basic_init(void)
41 dispc_lcd_enable_signal_polarity(1); 41 dispc_lcd_enable_signal_polarity(1);
42} 42}
43 43
44static int sdi_display_enable(struct omap_dss_device *dssdev) 44int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
45{ 45{
46 struct omap_video_timings *t = &dssdev->panel.timings; 46 struct omap_video_timings *t = &dssdev->panel.timings;
47 struct dss_clock_info dss_cinfo; 47 struct dss_clock_info dss_cinfo;
@@ -57,12 +57,6 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
57 goto err0; 57 goto err0;
58 } 58 }
59 59
60 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
61 DSSERR("dssdev already enabled\n");
62 r = -EINVAL;
63 goto err1;
64 }
65
66 /* In case of skip_init sdi_init has already enabled the clocks */ 60 /* In case of skip_init sdi_init has already enabled the clocks */
67 if (!sdi.skip_init) 61 if (!sdi.skip_init)
68 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 62 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
@@ -119,7 +113,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
119 mdelay(2); 113 mdelay(2);
120 } 114 }
121 115
122 dispc_enable_lcd_out(1); 116 dssdev->manager->enable(dssdev->manager);
123 117
124 if (dssdev->driver->enable) { 118 if (dssdev->driver->enable) {
125 r = dssdev->driver->enable(dssdev); 119 r = dssdev->driver->enable(dssdev);
@@ -127,13 +121,11 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
127 goto err3; 121 goto err3;
128 } 122 }
129 123
130 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
131
132 sdi.skip_init = 0; 124 sdi.skip_init = 0;
133 125
134 return 0; 126 return 0;
135err3: 127err3:
136 dispc_enable_lcd_out(0); 128 dssdev->manager->disable(dssdev->manager);
137err2: 129err2:
138 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 130 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
139err1: 131err1:
@@ -141,120 +133,27 @@ err1:
141err0: 133err0:
142 return r; 134 return r;
143} 135}
136EXPORT_SYMBOL(omapdss_sdi_display_enable);
144 137
145static int sdi_display_resume(struct omap_dss_device *dssdev); 138void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
146
147static void sdi_display_disable(struct omap_dss_device *dssdev)
148{ 139{
149 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
150 return;
151
152 if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
153 if (sdi_display_resume(dssdev))
154 return;
155
156 if (dssdev->driver->disable) 140 if (dssdev->driver->disable)
157 dssdev->driver->disable(dssdev); 141 dssdev->driver->disable(dssdev);
158 142
159 dispc_enable_lcd_out(0); 143 dssdev->manager->disable(dssdev->manager);
160 144
161 dss_sdi_disable(); 145 dss_sdi_disable();
162 146
163 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 147 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
164 148
165 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
166
167 omap_dss_stop_device(dssdev); 149 omap_dss_stop_device(dssdev);
168} 150}
169 151EXPORT_SYMBOL(omapdss_sdi_display_disable);
170static int sdi_display_suspend(struct omap_dss_device *dssdev)
171{
172 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
173 return -EINVAL;
174
175 if (dssdev->driver->suspend)
176 dssdev->driver->suspend(dssdev);
177
178 dispc_enable_lcd_out(0);
179
180 dss_sdi_disable();
181
182 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
183
184 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
185
186 return 0;
187}
188
189static int sdi_display_resume(struct omap_dss_device *dssdev)
190{
191 int r;
192
193 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
194 return -EINVAL;
195
196 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
197
198 r = dss_sdi_enable();
199 if (r)
200 goto err;
201 mdelay(2);
202
203 dispc_enable_lcd_out(1);
204
205 if (dssdev->driver->resume)
206 dssdev->driver->resume(dssdev);
207
208 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
209
210 return 0;
211err:
212 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
213 return r;
214}
215
216static int sdi_display_set_update_mode(struct omap_dss_device *dssdev,
217 enum omap_dss_update_mode mode)
218{
219 if (mode == OMAP_DSS_UPDATE_MANUAL)
220 return -EINVAL;
221
222 if (mode == OMAP_DSS_UPDATE_DISABLED) {
223 dispc_enable_lcd_out(0);
224 sdi.update_enabled = 0;
225 } else {
226 dispc_enable_lcd_out(1);
227 sdi.update_enabled = 1;
228 }
229
230 return 0;
231}
232
233static enum omap_dss_update_mode sdi_display_get_update_mode(
234 struct omap_dss_device *dssdev)
235{
236 return sdi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
237 OMAP_DSS_UPDATE_DISABLED;
238}
239
240static void sdi_get_timings(struct omap_dss_device *dssdev,
241 struct omap_video_timings *timings)
242{
243 *timings = dssdev->panel.timings;
244}
245 152
246int sdi_init_display(struct omap_dss_device *dssdev) 153int sdi_init_display(struct omap_dss_device *dssdev)
247{ 154{
248 DSSDBG("SDI init\n"); 155 DSSDBG("SDI init\n");
249 156
250 dssdev->enable = sdi_display_enable;
251 dssdev->disable = sdi_display_disable;
252 dssdev->suspend = sdi_display_suspend;
253 dssdev->resume = sdi_display_resume;
254 dssdev->set_update_mode = sdi_display_set_update_mode;
255 dssdev->get_update_mode = sdi_display_get_update_mode;
256 dssdev->get_timings = sdi_get_timings;
257
258 return 0; 157 return 0;
259} 158}
260 159
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 749a5a0f5be4..f0ba5732d84a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -400,114 +400,6 @@ static const struct venc_config *venc_timings_to_config(
400 BUG(); 400 BUG();
401} 401}
402 402
403
404
405
406
407/* driver */
408static int venc_panel_probe(struct omap_dss_device *dssdev)
409{
410 dssdev->panel.timings = omap_dss_pal_timings;
411
412 return 0;
413}
414
415static void venc_panel_remove(struct omap_dss_device *dssdev)
416{
417}
418
419static int venc_panel_enable(struct omap_dss_device *dssdev)
420{
421 int r = 0;
422
423 /* wait couple of vsyncs until enabling the LCD */
424 msleep(50);
425
426 if (dssdev->platform_enable)
427 r = dssdev->platform_enable(dssdev);
428
429 return r;
430}
431
432static void venc_panel_disable(struct omap_dss_device *dssdev)
433{
434 if (dssdev->platform_disable)
435 dssdev->platform_disable(dssdev);
436
437 /* wait at least 5 vsyncs after disabling the LCD */
438
439 msleep(100);
440}
441
442static int venc_panel_suspend(struct omap_dss_device *dssdev)
443{
444 venc_panel_disable(dssdev);
445 return 0;
446}
447
448static int venc_panel_resume(struct omap_dss_device *dssdev)
449{
450 return venc_panel_enable(dssdev);
451}
452
453static struct omap_dss_driver venc_driver = {
454 .probe = venc_panel_probe,
455 .remove = venc_panel_remove,
456
457 .enable = venc_panel_enable,
458 .disable = venc_panel_disable,
459 .suspend = venc_panel_suspend,
460 .resume = venc_panel_resume,
461
462 .driver = {
463 .name = "venc",
464 .owner = THIS_MODULE,
465 },
466};
467/* driver end */
468
469
470
471int venc_init(struct platform_device *pdev)
472{
473 u8 rev_id;
474
475 mutex_init(&venc.venc_lock);
476
477 venc.wss_data = 0;
478
479 venc.base = ioremap(VENC_BASE, SZ_1K);
480 if (!venc.base) {
481 DSSERR("can't ioremap VENC\n");
482 return -ENOMEM;
483 }
484
485 venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac");
486 if (IS_ERR(venc.vdda_dac_reg)) {
487 iounmap(venc.base);
488 DSSERR("can't get VDDA_DAC regulator\n");
489 return PTR_ERR(venc.vdda_dac_reg);
490 }
491
492 venc_enable_clocks(1);
493
494 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
495 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
496
497 venc_enable_clocks(0);
498
499 return omap_dss_register_driver(&venc_driver);
500}
501
502void venc_exit(void)
503{
504 omap_dss_unregister_driver(&venc_driver);
505
506 regulator_put(venc.vdda_dac_reg);
507
508 iounmap(venc.base);
509}
510
511static void venc_power_on(struct omap_dss_device *dssdev) 403static void venc_power_on(struct omap_dss_device *dssdev)
512{ 404{
513 u32 l; 405 u32 l;
@@ -540,7 +432,7 @@ static void venc_power_on(struct omap_dss_device *dssdev)
540 if (dssdev->platform_enable) 432 if (dssdev->platform_enable)
541 dssdev->platform_enable(dssdev); 433 dssdev->platform_enable(dssdev);
542 434
543 dispc_enable_digit_out(1); 435 dssdev->manager->enable(dssdev->manager);
544} 436}
545 437
546static void venc_power_off(struct omap_dss_device *dssdev) 438static void venc_power_off(struct omap_dss_device *dssdev)
@@ -548,7 +440,7 @@ static void venc_power_off(struct omap_dss_device *dssdev)
548 venc_write_reg(VENC_OUTPUT_CONTROL, 0); 440 venc_write_reg(VENC_OUTPUT_CONTROL, 0);
549 dss_set_dac_pwrdn_bgz(0); 441 dss_set_dac_pwrdn_bgz(0);
550 442
551 dispc_enable_digit_out(0); 443 dssdev->manager->disable(dssdev->manager);
552 444
553 if (dssdev->platform_disable) 445 if (dssdev->platform_disable)
554 dssdev->platform_disable(dssdev); 446 dssdev->platform_disable(dssdev);
@@ -558,7 +450,23 @@ static void venc_power_off(struct omap_dss_device *dssdev)
558 venc_enable_clocks(0); 450 venc_enable_clocks(0);
559} 451}
560 452
561static int venc_enable_display(struct omap_dss_device *dssdev) 453
454
455
456
457/* driver */
458static int venc_panel_probe(struct omap_dss_device *dssdev)
459{
460 dssdev->panel.timings = omap_dss_pal_timings;
461
462 return 0;
463}
464
465static void venc_panel_remove(struct omap_dss_device *dssdev)
466{
467}
468
469static int venc_panel_enable(struct omap_dss_device *dssdev)
562{ 470{
563 int r = 0; 471 int r = 0;
564 472
@@ -568,7 +476,13 @@ static int venc_enable_display(struct omap_dss_device *dssdev)
568 476
569 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 477 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
570 r = -EINVAL; 478 r = -EINVAL;
571 goto err; 479 goto err1;
480 }
481
482 if (dssdev->platform_enable) {
483 r = dssdev->platform_enable(dssdev);
484 if (r)
485 goto err2;
572 } 486 }
573 487
574 venc_power_on(dssdev); 488 venc_power_on(dssdev);
@@ -576,13 +490,21 @@ static int venc_enable_display(struct omap_dss_device *dssdev)
576 venc.wss_data = 0; 490 venc.wss_data = 0;
577 491
578 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 492 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
579err: 493
494 /* wait couple of vsyncs until enabling the LCD */
495 msleep(50);
496
580 mutex_unlock(&venc.venc_lock); 497 mutex_unlock(&venc.venc_lock);
581 498
582 return r; 499 return r;
500err2:
501 venc_power_off(dssdev);
502err1:
503 mutex_unlock(&venc.venc_lock);
504 return r;
583} 505}
584 506
585static void venc_disable_display(struct omap_dss_device *dssdev) 507static void venc_panel_disable(struct omap_dss_device *dssdev)
586{ 508{
587 DSSDBG("venc_disable_display\n"); 509 DSSDBG("venc_disable_display\n");
588 510
@@ -599,53 +521,40 @@ static void venc_disable_display(struct omap_dss_device *dssdev)
599 521
600 venc_power_off(dssdev); 522 venc_power_off(dssdev);
601 523
524 /* wait at least 5 vsyncs after disabling the LCD */
525 msleep(100);
526
527 if (dssdev->platform_disable)
528 dssdev->platform_disable(dssdev);
529
602 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 530 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
603end: 531end:
604 mutex_unlock(&venc.venc_lock); 532 mutex_unlock(&venc.venc_lock);
605} 533}
606 534
607static int venc_display_suspend(struct omap_dss_device *dssdev) 535static int venc_panel_suspend(struct omap_dss_device *dssdev)
608{ 536{
609 int r = 0; 537 venc_panel_disable(dssdev);
610 538 return 0;
611 DSSDBG("venc_display_suspend\n");
612
613 mutex_lock(&venc.venc_lock);
614
615 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
616 r = -EINVAL;
617 goto err;
618 }
619
620 venc_power_off(dssdev);
621
622 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
623err:
624 mutex_unlock(&venc.venc_lock);
625
626 return r;
627} 539}
628 540
629static int venc_display_resume(struct omap_dss_device *dssdev) 541static int venc_panel_resume(struct omap_dss_device *dssdev)
630{ 542{
631 int r = 0; 543 return venc_panel_enable(dssdev);
632 544}
633 DSSDBG("venc_display_resume\n");
634
635 mutex_lock(&venc.venc_lock);
636
637 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
638 r = -EINVAL;
639 goto err;
640 }
641
642 venc_power_on(dssdev);
643 545
644 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 546static enum omap_dss_update_mode venc_get_update_mode(
645err: 547 struct omap_dss_device *dssdev)
646 mutex_unlock(&venc.venc_lock); 548{
549 return OMAP_DSS_UPDATE_AUTO;
550}
647 551
648 return r; 552static int venc_set_update_mode(struct omap_dss_device *dssdev,
553 enum omap_dss_update_mode mode)
554{
555 if (mode != OMAP_DSS_UPDATE_AUTO)
556 return -EINVAL;
557 return 0;
649} 558}
650 559
651static void venc_get_timings(struct omap_dss_device *dssdev, 560static void venc_get_timings(struct omap_dss_device *dssdev,
@@ -666,8 +575,8 @@ static void venc_set_timings(struct omap_dss_device *dssdev,
666 dssdev->panel.timings = *timings; 575 dssdev->panel.timings = *timings;
667 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 576 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
668 /* turn the venc off and on to get new timings to use */ 577 /* turn the venc off and on to get new timings to use */
669 venc_disable_display(dssdev); 578 venc_panel_disable(dssdev);
670 venc_enable_display(dssdev); 579 venc_panel_enable(dssdev);
671 } 580 }
672} 581}
673 582
@@ -716,30 +625,79 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
716 return 0; 625 return 0;
717} 626}
718 627
719static enum omap_dss_update_mode venc_display_get_update_mode( 628static struct omap_dss_driver venc_driver = {
720 struct omap_dss_device *dssdev) 629 .probe = venc_panel_probe,
630 .remove = venc_panel_remove,
631
632 .enable = venc_panel_enable,
633 .disable = venc_panel_disable,
634 .suspend = venc_panel_suspend,
635 .resume = venc_panel_resume,
636
637 .get_resolution = omapdss_default_get_resolution,
638 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
639
640 .set_update_mode = venc_set_update_mode,
641 .get_update_mode = venc_get_update_mode,
642
643 .get_timings = venc_get_timings,
644 .set_timings = venc_set_timings,
645 .check_timings = venc_check_timings,
646
647 .get_wss = venc_get_wss,
648 .set_wss = venc_set_wss,
649
650 .driver = {
651 .name = "venc",
652 .owner = THIS_MODULE,
653 },
654};
655/* driver end */
656
657
658
659int venc_init(struct platform_device *pdev)
721{ 660{
722 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 661 u8 rev_id;
723 return OMAP_DSS_UPDATE_AUTO; 662
724 else 663 mutex_init(&venc.venc_lock);
725 return OMAP_DSS_UPDATE_DISABLED; 664
665 venc.wss_data = 0;
666
667 venc.base = ioremap(VENC_BASE, SZ_1K);
668 if (!venc.base) {
669 DSSERR("can't ioremap VENC\n");
670 return -ENOMEM;
671 }
672
673 venc.vdda_dac_reg = dss_get_vdda_dac();
674 if (IS_ERR(venc.vdda_dac_reg)) {
675 iounmap(venc.base);
676 DSSERR("can't get VDDA_DAC regulator\n");
677 return PTR_ERR(venc.vdda_dac_reg);
678 }
679
680 venc_enable_clocks(1);
681
682 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
683 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
684
685 venc_enable_clocks(0);
686
687 return omap_dss_register_driver(&venc_driver);
688}
689
690void venc_exit(void)
691{
692 omap_dss_unregister_driver(&venc_driver);
693
694 iounmap(venc.base);
726} 695}
727 696
728int venc_init_display(struct omap_dss_device *dssdev) 697int venc_init_display(struct omap_dss_device *dssdev)
729{ 698{
730 DSSDBG("init_display\n"); 699 DSSDBG("init_display\n");
731 700
732 dssdev->enable = venc_enable_display;
733 dssdev->disable = venc_disable_display;
734 dssdev->suspend = venc_display_suspend;
735 dssdev->resume = venc_display_resume;
736 dssdev->get_timings = venc_get_timings;
737 dssdev->set_timings = venc_set_timings;
738 dssdev->check_timings = venc_check_timings;
739 dssdev->get_wss = venc_get_wss;
740 dssdev->set_wss = venc_set_wss;
741 dssdev->get_update_mode = venc_display_get_update_mode;
742
743 return 0; 701 return 0;
744} 702}
745 703
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index bb694cc52a50..43496d6c377f 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -16,16 +16,7 @@ config FB_OMAP2_DEBUG_SUPPORT
16 depends on FB_OMAP2 16 depends on FB_OMAP2
17 help 17 help
18 Support for debug output. You have to enable the actual printing 18 Support for debug output. You have to enable the actual printing
19 with debug module parameter. 19 with 'debug' module parameter.
20
21config FB_OMAP2_FORCE_AUTO_UPDATE
22 bool "Force main display to automatic update mode"
23 depends on FB_OMAP2
24 help
25 Forces main display to automatic update mode (if possible),
26 and also enables tearsync (if possible). By default
27 displays that support manual update are started in manual
28 update mode.
29 20
30config FB_OMAP2_NUM_FBS 21config FB_OMAP2_NUM_FBS
31 int "Number of framebuffers" 22 int "Number of framebuffers"
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 4c4bafdfaa43..1ffa760b8545 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -167,12 +167,12 @@ static int omapfb_update_window_nolock(struct fb_info *fbi,
167 if (w == 0 || h == 0) 167 if (w == 0 || h == 0)
168 return 0; 168 return 0;
169 169
170 display->get_resolution(display, &dw, &dh); 170 display->driver->get_resolution(display, &dw, &dh);
171 171
172 if (x + w > dw || y + h > dh) 172 if (x + w > dw || y + h > dh)
173 return -EINVAL; 173 return -EINVAL;
174 174
175 return display->update(display, x, y, w, h); 175 return display->driver->update(display, x, y, w, h);
176} 176}
177 177
178/* This function is exported for SGX driver use */ 178/* This function is exported for SGX driver use */
@@ -202,7 +202,7 @@ static int omapfb_set_update_mode(struct fb_info *fbi,
202 enum omap_dss_update_mode um; 202 enum omap_dss_update_mode um;
203 int r; 203 int r;
204 204
205 if (!display || !display->set_update_mode) 205 if (!display || !display->driver->set_update_mode)
206 return -EINVAL; 206 return -EINVAL;
207 207
208 switch (mode) { 208 switch (mode) {
@@ -222,7 +222,7 @@ static int omapfb_set_update_mode(struct fb_info *fbi,
222 return -EINVAL; 222 return -EINVAL;
223 } 223 }
224 224
225 r = display->set_update_mode(display, um); 225 r = display->driver->set_update_mode(display, um);
226 226
227 return r; 227 return r;
228} 228}
@@ -233,10 +233,15 @@ static int omapfb_get_update_mode(struct fb_info *fbi,
233 struct omap_dss_device *display = fb2display(fbi); 233 struct omap_dss_device *display = fb2display(fbi);
234 enum omap_dss_update_mode m; 234 enum omap_dss_update_mode m;
235 235
236 if (!display || !display->get_update_mode) 236 if (!display)
237 return -EINVAL; 237 return -EINVAL;
238 238
239 m = display->get_update_mode(display); 239 if (!display->driver->get_update_mode) {
240 *mode = OMAPFB_AUTO_UPDATE;
241 return 0;
242 }
243
244 m = display->driver->get_update_mode(display);
240 245
241 switch (m) { 246 switch (m) {
242 case OMAP_DSS_UPDATE_DISABLED: 247 case OMAP_DSS_UPDATE_DISABLED:
@@ -374,7 +379,7 @@ static int omapfb_memory_read(struct fb_info *fbi,
374 void *buf; 379 void *buf;
375 int r; 380 int r;
376 381
377 if (!display || !display->memory_read) 382 if (!display || !display->driver->memory_read)
378 return -ENOENT; 383 return -ENOENT;
379 384
380 if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size)) 385 if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size))
@@ -389,7 +394,7 @@ static int omapfb_memory_read(struct fb_info *fbi,
389 return -ENOMEM; 394 return -ENOMEM;
390 } 395 }
391 396
392 r = display->memory_read(display, buf, mr->buffer_size, 397 r = display->driver->memory_read(display, buf, mr->buffer_size,
393 mr->x, mr->y, mr->w, mr->h); 398 mr->x, mr->y, mr->w, mr->h);
394 399
395 if (r > 0) { 400 if (r > 0) {
@@ -483,6 +488,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
483 struct omapfb_memory_read memory_read; 488 struct omapfb_memory_read memory_read;
484 struct omapfb_vram_info vram_info; 489 struct omapfb_vram_info vram_info;
485 struct omapfb_tearsync_info tearsync_info; 490 struct omapfb_tearsync_info tearsync_info;
491 struct omapfb_display_info display_info;
486 } p; 492 } p;
487 493
488 int r = 0; 494 int r = 0;
@@ -490,18 +496,18 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
490 switch (cmd) { 496 switch (cmd) {
491 case OMAPFB_SYNC_GFX: 497 case OMAPFB_SYNC_GFX:
492 DBG("ioctl SYNC_GFX\n"); 498 DBG("ioctl SYNC_GFX\n");
493 if (!display || !display->sync) { 499 if (!display || !display->driver->sync) {
494 /* DSS1 never returns an error here, so we neither */ 500 /* DSS1 never returns an error here, so we neither */
495 /*r = -EINVAL;*/ 501 /*r = -EINVAL;*/
496 break; 502 break;
497 } 503 }
498 504
499 r = display->sync(display); 505 r = display->driver->sync(display);
500 break; 506 break;
501 507
502 case OMAPFB_UPDATE_WINDOW_OLD: 508 case OMAPFB_UPDATE_WINDOW_OLD:
503 DBG("ioctl UPDATE_WINDOW_OLD\n"); 509 DBG("ioctl UPDATE_WINDOW_OLD\n");
504 if (!display || !display->update) { 510 if (!display || !display->driver->update) {
505 r = -EINVAL; 511 r = -EINVAL;
506 break; 512 break;
507 } 513 }
@@ -519,7 +525,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
519 525
520 case OMAPFB_UPDATE_WINDOW: 526 case OMAPFB_UPDATE_WINDOW:
521 DBG("ioctl UPDATE_WINDOW\n"); 527 DBG("ioctl UPDATE_WINDOW\n");
522 if (!display || !display->update) { 528 if (!display || !display->driver->update) {
523 r = -EINVAL; 529 r = -EINVAL;
524 break; 530 break;
525 } 531 }
@@ -648,7 +654,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
648 break; 654 break;
649 } 655 }
650 656
651 r = display->wait_vsync(display); 657 r = display->manager->wait_for_vsync(display->manager);
652 break; 658 break;
653 659
654 case OMAPFB_WAITFORGO: 660 case OMAPFB_WAITFORGO:
@@ -669,12 +675,12 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
669 r = -EFAULT; 675 r = -EFAULT;
670 break; 676 break;
671 } 677 }
672 if (!display || !display->run_test) { 678 if (!display || !display->driver->run_test) {
673 r = -EINVAL; 679 r = -EINVAL;
674 break; 680 break;
675 } 681 }
676 682
677 r = display->run_test(display, p.test_num); 683 r = display->driver->run_test(display, p.test_num);
678 684
679 break; 685 break;
680 686
@@ -684,12 +690,12 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
684 r = -EFAULT; 690 r = -EFAULT;
685 break; 691 break;
686 } 692 }
687 if (!display || !display->run_test) { 693 if (!display || !display->driver->run_test) {
688 r = -EINVAL; 694 r = -EINVAL;
689 break; 695 break;
690 } 696 }
691 697
692 r = display->run_test(display, p.test_num); 698 r = display->driver->run_test(display, p.test_num);
693 699
694 break; 700 break;
695 701
@@ -731,13 +737,37 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
731 break; 737 break;
732 } 738 }
733 739
734 if (!display->enable_te) { 740 if (!display->driver->enable_te) {
735 r = -ENODEV; 741 r = -ENODEV;
736 break; 742 break;
737 } 743 }
738 744
739 r = display->enable_te(display, !!p.tearsync_info.enabled); 745 r = display->driver->enable_te(display,
746 !!p.tearsync_info.enabled);
747
748 break;
749 }
750
751 case OMAPFB_GET_DISPLAY_INFO: {
752 u16 xres, yres;
740 753
754 DBG("ioctl GET_DISPLAY_INFO\n");
755
756 if (display == NULL) {
757 r = -ENODEV;
758 break;
759 }
760
761 display->driver->get_resolution(display, &xres, &yres);
762
763 p.display_info.xres = xres;
764 p.display_info.yres = yres;
765 p.display_info.width = 0;
766 p.display_info.height = 0;
767
768 if (copy_to_user((void __user *)arg, &p.display_info,
769 sizeof(p.display_info)))
770 r = -EFAULT;
741 break; 771 break;
742 } 772 }
743 773
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index d17caef6915a..4a76917b7cc8 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -54,6 +54,8 @@ module_param_named(test, omapfb_test_pattern, bool, 0644);
54#endif 54#endif
55 55
56static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi); 56static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi);
57static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
58 struct omap_dss_device *dssdev);
57 59
58#ifdef DEBUG 60#ifdef DEBUG
59static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color) 61static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color)
@@ -152,9 +154,9 @@ static void fill_fb(struct fb_info *fbi)
152} 154}
153#endif 155#endif
154 156
155static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot) 157static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
156{ 158{
157 struct vrfb *vrfb = &ofbi->region.vrfb; 159 const struct vrfb *vrfb = &ofbi->region.vrfb;
158 unsigned offset; 160 unsigned offset;
159 161
160 switch (rot) { 162 switch (rot) {
@@ -179,7 +181,7 @@ static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot)
179 return offset; 181 return offset;
180} 182}
181 183
182static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot) 184static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
183{ 185{
184 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 186 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
185 return ofbi->region.vrfb.paddr[rot] 187 return ofbi->region.vrfb.paddr[rot]
@@ -189,7 +191,7 @@ static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot)
189 } 191 }
190} 192}
191 193
192static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi) 194static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
193{ 195{
194 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 196 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
195 return ofbi->region.vrfb.paddr[0]; 197 return ofbi->region.vrfb.paddr[0];
@@ -197,7 +199,7 @@ static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi)
197 return ofbi->region.paddr; 199 return ofbi->region.paddr;
198} 200}
199 201
200static void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi) 202static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
201{ 203{
202 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 204 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
203 return ofbi->region.vrfb.vaddr[0]; 205 return ofbi->region.vrfb.vaddr[0];
@@ -703,9 +705,9 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
703 var->width = -1; 705 var->width = -1;
704 var->grayscale = 0; 706 var->grayscale = 0;
705 707
706 if (display && display->get_timings) { 708 if (display && display->driver->get_timings) {
707 struct omap_video_timings timings; 709 struct omap_video_timings timings;
708 display->get_timings(display, &timings); 710 display->driver->get_timings(display, &timings);
709 711
710 /* pixclock in ps, the rest in pixclock */ 712 /* pixclock in ps, the rest in pixclock */
711 var->pixclock = timings.pixel_clock != 0 ? 713 var->pixclock = timings.pixel_clock != 0 ?
@@ -778,8 +780,8 @@ static int omapfb_release(struct fb_info *fbi, int user)
778 return 0; 780 return 0;
779} 781}
780 782
781static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var, 783static unsigned calc_rotation_offset_dma(const struct fb_var_screeninfo *var,
782 struct fb_fix_screeninfo *fix, int rotation) 784 const struct fb_fix_screeninfo *fix, int rotation)
783{ 785{
784 unsigned offset; 786 unsigned offset;
785 787
@@ -789,8 +791,8 @@ static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var,
789 return offset; 791 return offset;
790} 792}
791 793
792static unsigned calc_rotation_offset_vrfb(struct fb_var_screeninfo *var, 794static unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var,
793 struct fb_fix_screeninfo *fix, int rotation) 795 const struct fb_fix_screeninfo *fix, int rotation)
794{ 796{
795 unsigned offset; 797 unsigned offset;
796 798
@@ -1221,11 +1223,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1221 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) 1223 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
1222 goto exit; 1224 goto exit;
1223 1225
1224 if (display->resume) 1226 if (display->driver->resume)
1225 r = display->resume(display); 1227 r = display->driver->resume(display);
1226 1228
1227 if (r == 0 && display->get_update_mode && 1229 if (r == 0 && display->driver->get_update_mode &&
1228 display->get_update_mode(display) == 1230 display->driver->get_update_mode(display) ==
1229 OMAP_DSS_UPDATE_MANUAL) 1231 OMAP_DSS_UPDATE_MANUAL)
1230 do_update = 1; 1232 do_update = 1;
1231 1233
@@ -1240,8 +1242,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1240 if (display->state != OMAP_DSS_DISPLAY_ACTIVE) 1242 if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
1241 goto exit; 1243 goto exit;
1242 1244
1243 if (display->suspend) 1245 if (display->driver->suspend)
1244 r = display->suspend(display); 1246 r = display->driver->suspend(display);
1245 1247
1246 break; 1248 break;
1247 1249
@@ -1252,11 +1254,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1252exit: 1254exit:
1253 omapfb_unlock(fbdev); 1255 omapfb_unlock(fbdev);
1254 1256
1255 if (r == 0 && do_update && display->update) { 1257 if (r == 0 && do_update && display->driver->update) {
1256 u16 w, h; 1258 u16 w, h;
1257 display->get_resolution(display, &w, &h); 1259 display->driver->get_resolution(display, &w, &h);
1258 1260
1259 r = display->update(display, 0, 0, w, h); 1261 r = display->driver->update(display, 0, 0, w, h);
1260 } 1262 }
1261 1263
1262 return r; 1264 return r;
@@ -1404,6 +1406,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1404 unsigned long paddr) 1406 unsigned long paddr)
1405{ 1407{
1406 struct omapfb_info *ofbi = FB2OFB(fbi); 1408 struct omapfb_info *ofbi = FB2OFB(fbi);
1409 struct omapfb2_device *fbdev = ofbi->fbdev;
1407 struct omap_dss_device *display; 1410 struct omap_dss_device *display;
1408 int bytespp; 1411 int bytespp;
1409 1412
@@ -1412,7 +1415,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1412 if (!display) 1415 if (!display)
1413 return 0; 1416 return 0;
1414 1417
1415 switch (display->get_recommended_bpp(display)) { 1418 switch (omapfb_get_recommended_bpp(fbdev, display)) {
1416 case 16: 1419 case 16:
1417 bytespp = 2; 1420 bytespp = 2;
1418 break; 1421 break;
@@ -1427,7 +1430,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1427 if (!size) { 1430 if (!size) {
1428 u16 w, h; 1431 u16 w, h;
1429 1432
1430 display->get_resolution(display, &w, &h); 1433 display->driver->get_resolution(display, &w, &h);
1431 1434
1432 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 1435 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
1433 size = max(omap_vrfb_min_phys_size(w, h, bytespp), 1436 size = max(omap_vrfb_min_phys_size(w, h, bytespp),
@@ -1636,8 +1639,8 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1636 if (old_size == size && old_type == type) 1639 if (old_size == size && old_type == type)
1637 return 0; 1640 return 0;
1638 1641
1639 if (display && display->sync) 1642 if (display && display->driver->sync)
1640 display->sync(display); 1643 display->driver->sync(display);
1641 1644
1642 omapfb_free_fbmem(fbi); 1645 omapfb_free_fbmem(fbi);
1643 1646
@@ -1745,7 +1748,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1745 u16 w, h; 1748 u16 w, h;
1746 int rotation = (var->rotate + ofbi->rotation[0]) % 4; 1749 int rotation = (var->rotate + ofbi->rotation[0]) % 4;
1747 1750
1748 display->get_resolution(display, &w, &h); 1751 display->driver->get_resolution(display, &w, &h);
1749 1752
1750 if (rotation == FB_ROTATE_CW || 1753 if (rotation == FB_ROTATE_CW ||
1751 rotation == FB_ROTATE_CCW) { 1754 rotation == FB_ROTATE_CCW) {
@@ -1760,7 +1763,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1760 var->yres_virtual = var->yres; 1763 var->yres_virtual = var->yres;
1761 1764
1762 if (!var->bits_per_pixel) { 1765 if (!var->bits_per_pixel) {
1763 switch (display->get_recommended_bpp(display)) { 1766 switch (omapfb_get_recommended_bpp(fbdev, display)) {
1764 case 16: 1767 case 16:
1765 var->bits_per_pixel = 16; 1768 var->bits_per_pixel = 16;
1766 break; 1769 break;
@@ -1828,7 +1831,7 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
1828 1831
1829 for (i = 0; i < fbdev->num_displays; i++) { 1832 for (i = 0; i < fbdev->num_displays; i++) {
1830 if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED) 1833 if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED)
1831 fbdev->displays[i]->disable(fbdev->displays[i]); 1834 fbdev->displays[i]->driver->disable(fbdev->displays[i]);
1832 1835
1833 omap_dss_put_device(fbdev->displays[i]); 1836 omap_dss_put_device(fbdev->displays[i]);
1834 } 1837 }
@@ -2011,7 +2014,8 @@ static int omapfb_mode_to_timings(const char *mode_str,
2011 } 2014 }
2012} 2015}
2013 2016
2014static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str) 2017static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2018 struct omap_dss_device *display, char *mode_str)
2015{ 2019{
2016 int r; 2020 int r;
2017 u8 bpp; 2021 u8 bpp;
@@ -2021,20 +2025,37 @@ static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str)
2021 if (r) 2025 if (r)
2022 return r; 2026 return r;
2023 2027
2024 display->panel.recommended_bpp = bpp; 2028 fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display;
2029 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
2030 ++fbdev->num_bpp_overrides;
2025 2031
2026 if (!display->check_timings || !display->set_timings) 2032 if (!display->driver->check_timings || !display->driver->set_timings)
2027 return -EINVAL; 2033 return -EINVAL;
2028 2034
2029 r = display->check_timings(display, &timings); 2035 r = display->driver->check_timings(display, &timings);
2030 if (r) 2036 if (r)
2031 return r; 2037 return r;
2032 2038
2033 display->set_timings(display, &timings); 2039 display->driver->set_timings(display, &timings);
2034 2040
2035 return 0; 2041 return 0;
2036} 2042}
2037 2043
2044static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
2045 struct omap_dss_device *dssdev)
2046{
2047 int i;
2048
2049 BUG_ON(dssdev->driver->get_recommended_bpp == NULL);
2050
2051 for (i = 0; i < fbdev->num_bpp_overrides; ++i) {
2052 if (dssdev == fbdev->bpp_overrides[i].dssdev)
2053 return fbdev->bpp_overrides[i].bpp;
2054 }
2055
2056 return dssdev->driver->get_recommended_bpp(dssdev);
2057}
2058
2038static int omapfb_parse_def_modes(struct omapfb2_device *fbdev) 2059static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2039{ 2060{
2040 char *str, *options, *this_opt; 2061 char *str, *options, *this_opt;
@@ -2073,7 +2094,7 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2073 break; 2094 break;
2074 } 2095 }
2075 2096
2076 r = omapfb_set_def_mode(display, mode_str); 2097 r = omapfb_set_def_mode(fbdev, display, mode_str);
2077 if (r) 2098 if (r)
2078 break; 2099 break;
2079 } 2100 }
@@ -2111,18 +2132,23 @@ static int omapfb_probe(struct platform_device *pdev)
2111 fbdev->dev = &pdev->dev; 2132 fbdev->dev = &pdev->dev;
2112 platform_set_drvdata(pdev, fbdev); 2133 platform_set_drvdata(pdev, fbdev);
2113 2134
2135 r = 0;
2114 fbdev->num_displays = 0; 2136 fbdev->num_displays = 0;
2115 dssdev = NULL; 2137 dssdev = NULL;
2116 for_each_dss_dev(dssdev) { 2138 for_each_dss_dev(dssdev) {
2117 omap_dss_get_device(dssdev); 2139 omap_dss_get_device(dssdev);
2140
2118 if (!dssdev->driver) { 2141 if (!dssdev->driver) {
2119 dev_err(&pdev->dev, "no driver for display\n"); 2142 dev_err(&pdev->dev, "no driver for display\n");
2120 r = -EINVAL; 2143 r = -ENODEV;
2121 goto cleanup;
2122 } 2144 }
2145
2123 fbdev->displays[fbdev->num_displays++] = dssdev; 2146 fbdev->displays[fbdev->num_displays++] = dssdev;
2124 } 2147 }
2125 2148
2149 if (r)
2150 goto cleanup;
2151
2126 if (fbdev->num_displays == 0) { 2152 if (fbdev->num_displays == 0) {
2127 dev_err(&pdev->dev, "no displays\n"); 2153 dev_err(&pdev->dev, "no displays\n");
2128 r = -EINVAL; 2154 r = -EINVAL;
@@ -2167,35 +2193,28 @@ static int omapfb_probe(struct platform_device *pdev)
2167 } 2193 }
2168 2194
2169 if (def_display) { 2195 if (def_display) {
2170#ifndef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE 2196 struct omap_dss_driver *dssdrv = def_display->driver;
2171 u16 w, h; 2197
2172#endif 2198 r = def_display->driver->enable(def_display);
2173 r = def_display->enable(def_display); 2199 if (r) {
2174 if (r)
2175 dev_warn(fbdev->dev, "Failed to enable display '%s'\n", 2200 dev_warn(fbdev->dev, "Failed to enable display '%s'\n",
2176 def_display->name); 2201 def_display->name);
2202 goto cleanup;
2203 }
2177 2204
2178 /* set the update mode */
2179 if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 2205 if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2180#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE 2206 u16 w, h;
2181 if (def_display->enable_te) 2207 if (dssdrv->enable_te)
2182 def_display->enable_te(def_display, 1); 2208 dssdrv->enable_te(def_display, 1);
2183 if (def_display->set_update_mode) 2209 if (dssdrv->set_update_mode)
2184 def_display->set_update_mode(def_display, 2210 dssdrv->set_update_mode(def_display,
2185 OMAP_DSS_UPDATE_AUTO);
2186#else /* MANUAL_UPDATE */
2187 if (def_display->enable_te)
2188 def_display->enable_te(def_display, 0);
2189 if (def_display->set_update_mode)
2190 def_display->set_update_mode(def_display,
2191 OMAP_DSS_UPDATE_MANUAL); 2211 OMAP_DSS_UPDATE_MANUAL);
2192 2212
2193 def_display->get_resolution(def_display, &w, &h); 2213 dssdrv->get_resolution(def_display, &w, &h);
2194 def_display->update(def_display, 0, 0, w, h); 2214 def_display->driver->update(def_display, 0, 0, w, h);
2195#endif
2196 } else { 2215 } else {
2197 if (def_display->set_update_mode) 2216 if (dssdrv->set_update_mode)
2198 def_display->set_update_mode(def_display, 2217 dssdrv->set_update_mode(def_display,
2199 OMAP_DSS_UPDATE_AUTO); 2218 OMAP_DSS_UPDATE_AUTO);
2200 } 2219 }
2201 } 2220 }
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index f7c9c739e5ef..cd54fdbfd8bb 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -83,6 +83,12 @@ struct omapfb2_device {
83 struct omap_overlay *overlays[10]; 83 struct omap_overlay *overlays[10];
84 unsigned num_managers; 84 unsigned num_managers;
85 struct omap_overlay_manager *managers[10]; 85 struct omap_overlay_manager *managers[10];
86
87 unsigned num_bpp_overrides;
88 struct {
89 struct omap_dss_device *dssdev;
90 u8 bpp;
91 } bpp_overrides[10];
86}; 92};
87 93
88struct omapfb_colormode { 94struct omapfb_colormode {
@@ -105,6 +111,9 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev);
105 111
106int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg); 112int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
107 113
114int omapfb_update_window(struct fb_info *fbi,
115 u32 x, u32 y, u32 w, u32 h);
116
108int dss_mode_to_fb_mode(enum omap_color_mode dssmode, 117int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
109 struct fb_var_screeninfo *var); 118 struct fb_var_screeninfo *var);
110 119
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 53f8f1100e81..f9975100d56d 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -831,7 +831,7 @@ static int __devinit pvr2fb_common_init(void)
831 printk(KERN_NOTICE "fb%d: registering with SQ API\n", fb_info->node); 831 printk(KERN_NOTICE "fb%d: registering with SQ API\n", fb_info->node);
832 832
833 pvr2fb_map = sq_remap(fb_info->fix.smem_start, fb_info->fix.smem_len, 833 pvr2fb_map = sq_remap(fb_info->fix.smem_start, fb_info->fix.smem_len,
834 fb_info->fix.id, pgprot_val(PAGE_SHARED)); 834 fb_info->fix.id, PAGE_SHARED);
835 835
836 printk(KERN_NOTICE "fb%d: Mapped video memory to SQ addr 0x%lx\n", 836 printk(KERN_NOTICE "fb%d: Mapped video memory to SQ addr 0x%lx\n",
837 fb_info->node, pvr2fb_map); 837 fb_info->node, pvr2fb_map);
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index a69830d26f7f..8d7653e56df5 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -19,6 +19,7 @@
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22#include <linux/ioctl.h>
22#include <video/sh_mobile_lcdc.h> 23#include <video/sh_mobile_lcdc.h>
23#include <asm/atomic.h> 24#include <asm/atomic.h>
24 25
@@ -106,6 +107,7 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
106#define LDRCNTR_SRC 0x00010000 107#define LDRCNTR_SRC 0x00010000
107#define LDRCNTR_MRS 0x00000002 108#define LDRCNTR_MRS 0x00000002
108#define LDRCNTR_MRC 0x00000001 109#define LDRCNTR_MRC 0x00000001
110#define LDSR_MRS 0x00000100
109 111
110struct sh_mobile_lcdc_priv; 112struct sh_mobile_lcdc_priv;
111struct sh_mobile_lcdc_chan { 113struct sh_mobile_lcdc_chan {
@@ -122,8 +124,8 @@ struct sh_mobile_lcdc_chan {
122 struct scatterlist *sglist; 124 struct scatterlist *sglist;
123 unsigned long frame_end; 125 unsigned long frame_end;
124 unsigned long pan_offset; 126 unsigned long pan_offset;
125 unsigned long new_pan_offset;
126 wait_queue_head_t frame_end_wait; 127 wait_queue_head_t frame_end_wait;
128 struct completion vsync_completion;
127}; 129};
128 130
129struct sh_mobile_lcdc_priv { 131struct sh_mobile_lcdc_priv {
@@ -366,19 +368,8 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
366 } 368 }
367 369
368 /* VSYNC End */ 370 /* VSYNC End */
369 if (ldintr & LDINTR_VES) { 371 if (ldintr & LDINTR_VES)
370 unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR); 372 complete(&ch->vsync_completion);
371 /* Set the source address for the next refresh */
372 lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle +
373 ch->new_pan_offset);
374 if (lcdc_chan_is_sublcd(ch))
375 lcdc_write(ch->lcdc, _LDRCNTR,
376 ldrcntr ^ LDRCNTR_SRS);
377 else
378 lcdc_write(ch->lcdc, _LDRCNTR,
379 ldrcntr ^ LDRCNTR_MRS);
380 ch->pan_offset = ch->new_pan_offset;
381 }
382 } 373 }
383 374
384 return IRQ_HANDLED; 375 return IRQ_HANDLED;
@@ -767,25 +758,69 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
767 struct fb_info *info) 758 struct fb_info *info)
768{ 759{
769 struct sh_mobile_lcdc_chan *ch = info->par; 760 struct sh_mobile_lcdc_chan *ch = info->par;
761 struct sh_mobile_lcdc_priv *priv = ch->lcdc;
762 unsigned long ldrcntr;
763 unsigned long new_pan_offset;
764
765 new_pan_offset = (var->yoffset * info->fix.line_length) +
766 (var->xoffset * (info->var.bits_per_pixel / 8));
770 767
771 if (info->var.xoffset == var->xoffset && 768 if (new_pan_offset == ch->pan_offset)
772 info->var.yoffset == var->yoffset)
773 return 0; /* No change, do nothing */ 769 return 0; /* No change, do nothing */
774 770
775 ch->new_pan_offset = (var->yoffset * info->fix.line_length) + 771 ldrcntr = lcdc_read(priv, _LDRCNTR);
776 (var->xoffset * (info->var.bits_per_pixel / 8));
777 772
778 if (ch->new_pan_offset != ch->pan_offset) { 773 /* Set the source address for the next refresh */
779 unsigned long ldintr; 774 lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + new_pan_offset);
780 ldintr = lcdc_read(ch->lcdc, _LDINTR); 775 if (lcdc_chan_is_sublcd(ch))
781 ldintr |= LDINTR_VEE; 776 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
782 lcdc_write(ch->lcdc, _LDINTR, ldintr); 777 else
783 sh_mobile_lcdc_deferred_io_touch(info); 778 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS);
784 } 779
780 ch->pan_offset = new_pan_offset;
781
782 sh_mobile_lcdc_deferred_io_touch(info);
783
784 return 0;
785}
786
787static int sh_mobile_wait_for_vsync(struct fb_info *info)
788{
789 struct sh_mobile_lcdc_chan *ch = info->par;
790 unsigned long ldintr;
791 int ret;
792
793 /* Enable VSync End interrupt */
794 ldintr = lcdc_read(ch->lcdc, _LDINTR);
795 ldintr |= LDINTR_VEE;
796 lcdc_write(ch->lcdc, _LDINTR, ldintr);
797
798 ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion,
799 msecs_to_jiffies(100));
800 if (!ret)
801 return -ETIMEDOUT;
785 802
786 return 0; 803 return 0;
787} 804}
788 805
806static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
807 unsigned long arg)
808{
809 int retval;
810
811 switch (cmd) {
812 case FBIO_WAITFORVSYNC:
813 retval = sh_mobile_wait_for_vsync(info);
814 break;
815
816 default:
817 retval = -ENOIOCTLCMD;
818 break;
819 }
820 return retval;
821}
822
823
789static struct fb_ops sh_mobile_lcdc_ops = { 824static struct fb_ops sh_mobile_lcdc_ops = {
790 .owner = THIS_MODULE, 825 .owner = THIS_MODULE,
791 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 826 .fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -795,6 +830,7 @@ static struct fb_ops sh_mobile_lcdc_ops = {
795 .fb_copyarea = sh_mobile_lcdc_copyarea, 830 .fb_copyarea = sh_mobile_lcdc_copyarea,
796 .fb_imageblit = sh_mobile_lcdc_imageblit, 831 .fb_imageblit = sh_mobile_lcdc_imageblit,
797 .fb_pan_display = sh_mobile_fb_pan_display, 832 .fb_pan_display = sh_mobile_fb_pan_display,
833 .fb_ioctl = sh_mobile_ioctl,
798}; 834};
799 835
800static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) 836static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -962,8 +998,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
962 goto err1; 998 goto err1;
963 } 999 }
964 init_waitqueue_head(&priv->ch[i].frame_end_wait); 1000 init_waitqueue_head(&priv->ch[i].frame_end_wait);
1001 init_completion(&priv->ch[i].vsync_completion);
965 priv->ch[j].pan_offset = 0; 1002 priv->ch[j].pan_offset = 0;
966 priv->ch[j].new_pan_offset = 0;
967 1003
968 switch (pdata->ch[i].chan) { 1004 switch (pdata->ch[i].chan) {
969 case LCDC_CHAN_MAINLCD: 1005 case LCDC_CHAN_MAINLCD:
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index 18b950706cad..4cd50497264d 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -400,6 +400,7 @@ static void __devexit e3d_pci_unregister(struct pci_dev *pdev)
400 400
401static struct pci_device_id e3d_pci_table[] = { 401static struct pci_device_id e3d_pci_table[] = {
402 { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0), }, 402 { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0), },
403 { PCI_DEVICE(0x1091, 0x7a0), },
403 { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a2), }, 404 { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a2), },
404 { .vendor = PCI_VENDOR_ID_3DLABS, 405 { .vendor = PCI_VENDOR_ID_3DLABS,
405 .device = PCI_ANY_ID, 406 .device = PCI_ANY_ID,
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 4bb9a0b18950..6b52bf65f0b5 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -69,7 +69,7 @@
69#ifdef CONFIG_MAC 69#ifdef CONFIG_MAC
70/* We don't yet have functions to read the PRAM... perhaps we can 70/* We don't yet have functions to read the PRAM... perhaps we can
71 adapt them from the PPC code? */ 71 adapt them from the PPC code? */
72static int default_vmode = VMODE_640_480_67; 72static int default_vmode = VMODE_CHOOSE;
73static int default_cmode = CMODE_8; 73static int default_cmode = CMODE_8;
74#else 74#else
75static int default_vmode = VMODE_NVRAM; 75static int default_vmode = VMODE_NVRAM;
@@ -326,11 +326,11 @@ int __init valkyriefb_init(void)
326 326
327#ifdef CONFIG_MAC 327#ifdef CONFIG_MAC
328 if (!MACH_IS_MAC) 328 if (!MACH_IS_MAC)
329 return 0; 329 return -ENODEV;
330 if (!(mac_bi_data.id == MAC_MODEL_Q630 330 if (!(mac_bi_data.id == MAC_MODEL_Q630
331 /* I'm not sure about this one */ 331 /* I'm not sure about this one */
332 || mac_bi_data.id == MAC_MODEL_P588)) 332 || mac_bi_data.id == MAC_MODEL_P588))
333 return 0; 333 return -ENODEV;
334 334
335 /* Hardcoded addresses... welcome to 68k Macintosh country :-) */ 335 /* Hardcoded addresses... welcome to 68k Macintosh country :-) */
336 frame_buffer_phys = 0xf9000000; 336 frame_buffer_phys = 0xf9000000;
diff --git a/drivers/video/valkyriefb.h b/drivers/video/valkyriefb.h
index 97aaf7bb6417..d787441e5a42 100644
--- a/drivers/video/valkyriefb.h
+++ b/drivers/video/valkyriefb.h
@@ -134,15 +134,7 @@ static struct valkyrie_regvals valkyrie_reg_init_14 = {
134 { 1024, 0 }, 134 { 1024, 0 },
135 1024, 768 135 1024, 768
136}; 136};
137 137#endif /* !defined CONFIG_MAC */
138/* Register values for 800x600, 72Hz mode (11) */
139static struct valkyrie_regvals valkyrie_reg_init_11 = {
140 13,
141 { 17, 27, 3 }, /* pixel clock = 49.63MHz for V=71.66Hz */
142 { 800, 0 },
143 800, 600
144};
145#endif /* CONFIG_MAC */
146 138
147/* Register values for 832x624, 75Hz mode (13) */ 139/* Register values for 832x624, 75Hz mode (13) */
148static struct valkyrie_regvals valkyrie_reg_init_13 = { 140static struct valkyrie_regvals valkyrie_reg_init_13 = {
@@ -152,6 +144,14 @@ static struct valkyrie_regvals valkyrie_reg_init_13 = {
152 832, 624 144 832, 624
153}; 145};
154 146
147/* Register values for 800x600, 72Hz mode (11) */
148static struct valkyrie_regvals valkyrie_reg_init_11 = {
149 13,
150 { 17, 27, 3 }, /* pixel clock = 49.63MHz for V=71.66Hz */
151 { 800, 0 },
152 800, 600
153};
154
155/* Register values for 800x600, 60Hz mode (10) */ 155/* Register values for 800x600, 60Hz mode (10) */
156static struct valkyrie_regvals valkyrie_reg_init_10 = { 156static struct valkyrie_regvals valkyrie_reg_init_10 = {
157 12, 157 12,
@@ -188,24 +188,13 @@ static struct valkyrie_regvals *valkyrie_reg_init[VMODE_MAX] = {
188 NULL, 188 NULL,
189 NULL, 189 NULL,
190 &valkyrie_reg_init_10, 190 &valkyrie_reg_init_10,
191#ifdef CONFIG_MAC
192 NULL,
193 NULL,
194 &valkyrie_reg_init_13,
195 NULL,
196 NULL,
197 NULL,
198 NULL,
199#else
200 &valkyrie_reg_init_11, 191 &valkyrie_reg_init_11,
201 NULL, 192 NULL,
202 &valkyrie_reg_init_13, 193 &valkyrie_reg_init_13,
194#ifndef CONFIG_MAC
203 &valkyrie_reg_init_14, 195 &valkyrie_reg_init_14,
204 &valkyrie_reg_init_15, 196 &valkyrie_reg_init_15,
205 NULL, 197 NULL,
206 &valkyrie_reg_init_17, 198 &valkyrie_reg_init_17,
207#endif 199#endif
208 NULL,
209 NULL,
210 NULL
211}; 200};