aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/imxfb.c19
-rw-r--r--drivers/video/omap/lcd_apollon.c3
-rw-r--r--drivers/video/omap2/displays/panel-taal.c567
-rw-r--r--drivers/video/omap2/displays/panel-toppoly-tdo35s.c8
-rw-r--r--drivers/video/omap2/dss/dispc.c16
-rw-r--r--drivers/video/omap2/dss/display.c4
-rw-r--r--drivers/video/omap2/dss/dsi.c463
-rw-r--r--drivers/video/omap2/dss/dss.c6
-rw-r--r--drivers/video/omap2/dss/dss.h11
-rw-r--r--drivers/video/omap2/dss/manager.c204
-rw-r--r--drivers/video/omap2/dss/overlay.c2
-rw-r--r--drivers/video/omap2/dss/rfbi.c2
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c188
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c229
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c70
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h29
-rw-r--r--drivers/video/via/chip.h1
-rw-r--r--drivers/video/via/hw.c587
-rw-r--r--drivers/video/via/hw.h14
-rw-r--r--drivers/video/via/ioctl.h3
-rw-r--r--drivers/video/via/lcd.c117
-rw-r--r--drivers/video/via/lcd.h5
-rw-r--r--drivers/video/via/share.h309
-rw-r--r--drivers/video/via/via-core.c22
-rw-r--r--drivers/video/via/via-gpio.c2
-rw-r--r--drivers/video/via/viafbdev.c284
-rw-r--r--drivers/video/w100fb.c4
29 files changed, 1688 insertions, 1485 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index bbeee4ba2488..a1e9406b5afa 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1505,7 +1505,7 @@ config FB_SIS_315
1505 1505
1506config FB_VIA 1506config FB_VIA
1507 tristate "VIA UniChrome (Pro) and Chrome9 display support" 1507 tristate "VIA UniChrome (Pro) and Chrome9 display support"
1508 depends on FB && PCI 1508 depends on FB && PCI && X86
1509 select FB_CFB_FILLRECT 1509 select FB_CFB_FILLRECT
1510 select FB_CFB_COPYAREA 1510 select FB_CFB_COPYAREA
1511 select FB_CFB_IMAGEBLIT 1511 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 8e8f18d29d7a..5a35f22372b9 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@ menu "Console display driver support"
6 6
7config VGA_CONSOLE 7config VGA_CONSOLE
8 bool "VGA text console" if EMBEDDED || !X86 8 bool "VGA text console" if EMBEDDED || !X86
9 depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE && !SUPERH && !BLACKFIN && !AVR32 && !MN10300 9 depends on !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !SUPERH && !BLACKFIN && !AVR32 && !MN10300 && (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER)
10 default y 10 default y
11 help 11 help
12 Saying Y here will allow you to use Linux in text mode through a 12 Saying Y here will allow you to use Linux in text mode through a
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 43f0639b1c10..5c363d026f64 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -40,6 +40,12 @@
40 */ 40 */
41#define DEBUG_VAR 1 41#define DEBUG_VAR 1
42 42
43#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
44 (defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) && \
45 defined(CONFIG_FB_IMX_MODULE))
46#define PWMR_BACKLIGHT_AVAILABLE
47#endif
48
43#define DRIVER_NAME "imx-fb" 49#define DRIVER_NAME "imx-fb"
44 50
45#define LCDC_SSA 0x00 51#define LCDC_SSA 0x00
@@ -175,7 +181,9 @@ struct imxfb_info {
175 181
176 struct imx_fb_videomode *mode; 182 struct imx_fb_videomode *mode;
177 int num_modes; 183 int num_modes;
184#ifdef PWMR_BACKLIGHT_AVAILABLE
178 struct backlight_device *bl; 185 struct backlight_device *bl;
186#endif
179 187
180 void (*lcd_power)(int); 188 void (*lcd_power)(int);
181 void (*backlight_power)(int); 189 void (*backlight_power)(int);
@@ -450,8 +458,7 @@ static int imxfb_set_par(struct fb_info *info)
450 return 0; 458 return 0;
451} 459}
452 460
453 461#ifdef PWMR_BACKLIGHT_AVAILABLE
454
455static int imxfb_bl_get_brightness(struct backlight_device *bl) 462static int imxfb_bl_get_brightness(struct backlight_device *bl)
456{ 463{
457 struct imxfb_info *fbi = bl_get_data(bl); 464 struct imxfb_info *fbi = bl_get_data(bl);
@@ -516,6 +523,7 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
516 if (fbi->bl) 523 if (fbi->bl)
517 backlight_device_unregister(fbi->bl); 524 backlight_device_unregister(fbi->bl);
518} 525}
526#endif
519 527
520static void imxfb_enable_controller(struct imxfb_info *fbi) 528static void imxfb_enable_controller(struct imxfb_info *fbi)
521{ 529{
@@ -647,6 +655,9 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
647 fbi->regs + LCDC_SIZE); 655 fbi->regs + LCDC_SIZE);
648 656
649 writel(fbi->pcr, fbi->regs + LCDC_PCR); 657 writel(fbi->pcr, fbi->regs + LCDC_PCR);
658#ifndef PWMR_BACKLIGHT_AVAILABLE
659 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
660#endif
650 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); 661 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
651 writel(fbi->dmacr, fbi->regs + LCDC_DMACR); 662 writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
652 663
@@ -847,7 +858,9 @@ static int __init imxfb_probe(struct platform_device *pdev)
847 858
848 imxfb_enable_controller(fbi); 859 imxfb_enable_controller(fbi);
849 fbi->pdev = pdev; 860 fbi->pdev = pdev;
861#ifdef PWMR_BACKLIGHT_AVAILABLE
850 imxfb_init_backlight(fbi); 862 imxfb_init_backlight(fbi);
863#endif
851 864
852 return 0; 865 return 0;
853 866
@@ -885,7 +898,9 @@ static int __devexit imxfb_remove(struct platform_device *pdev)
885 898
886 imxfb_disable_controller(fbi); 899 imxfb_disable_controller(fbi);
887 900
901#ifdef PWMR_BACKLIGHT_AVAILABLE
888 imxfb_exit_backlight(fbi); 902 imxfb_exit_backlight(fbi);
903#endif
889 unregister_framebuffer(info); 904 unregister_framebuffer(info);
890 905
891 pdata = pdev->dev.platform_data; 906 pdata = pdev->dev.platform_data;
diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c
index 2be94eb3bbf5..10459d8bd9a0 100644
--- a/drivers/video/omap/lcd_apollon.c
+++ b/drivers/video/omap/lcd_apollon.c
@@ -25,7 +25,6 @@
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26 26
27#include <mach/gpio.h> 27#include <mach/gpio.h>
28#include <plat/mux.h>
29 28
30#include "omapfb.h" 29#include "omapfb.h"
31 30
@@ -34,8 +33,6 @@
34static int apollon_panel_init(struct lcd_panel *panel, 33static int apollon_panel_init(struct lcd_panel *panel,
35 struct omapfb_device *fbdev) 34 struct omapfb_device *fbdev)
36{ 35{
37 /* configure LCD PWR_EN */
38 omap_cfg_reg(M21_242X_GPIO11);
39 return 0; 36 return 0;
40} 37}
41 38
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index aaf5d308a046..e1c765d11419 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -28,12 +28,13 @@
28#include <linux/fb.h> 28#include <linux/fb.h>
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/gpio.h> 30#include <linux/gpio.h>
31#include <linux/completion.h>
32#include <linux/workqueue.h> 31#include <linux/workqueue.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/regulator/consumer.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35 35
36#include <plat/display.h> 36#include <plat/display.h>
37#include <plat/nokia-dsi-panel.h>
37 38
38/* DSI Virtual channel. Hardcoded for now. */ 39/* DSI Virtual channel. Hardcoded for now. */
39#define TCH 0 40#define TCH 0
@@ -62,11 +63,136 @@
62#define DCS_GET_ID2 0xdb 63#define DCS_GET_ID2 0xdb
63#define DCS_GET_ID3 0xdc 64#define DCS_GET_ID3 0xdc
64 65
65/* #define TAAL_USE_ESD_CHECK */
66#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000) 66#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000)
67 67
68static irqreturn_t taal_te_isr(int irq, void *data);
69static void taal_te_timeout_work_callback(struct work_struct *work);
68static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); 70static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
69 71
72struct panel_regulator {
73 struct regulator *regulator;
74 const char *name;
75 int min_uV;
76 int max_uV;
77};
78
79static void free_regulators(struct panel_regulator *regulators, int n)
80{
81 int i;
82
83 for (i = 0; i < n; i++) {
84 /* disable/put in reverse order */
85 regulator_disable(regulators[n - i - 1].regulator);
86 regulator_put(regulators[n - i - 1].regulator);
87 }
88}
89
90static int init_regulators(struct omap_dss_device *dssdev,
91 struct panel_regulator *regulators, int n)
92{
93 int r, i, v;
94
95 for (i = 0; i < n; i++) {
96 struct regulator *reg;
97
98 reg = regulator_get(&dssdev->dev, regulators[i].name);
99 if (IS_ERR(reg)) {
100 dev_err(&dssdev->dev, "failed to get regulator %s\n",
101 regulators[i].name);
102 r = PTR_ERR(reg);
103 goto err;
104 }
105
106 /* FIXME: better handling of fixed vs. variable regulators */
107 v = regulator_get_voltage(reg);
108 if (v < regulators[i].min_uV || v > regulators[i].max_uV) {
109 r = regulator_set_voltage(reg, regulators[i].min_uV,
110 regulators[i].max_uV);
111 if (r) {
112 dev_err(&dssdev->dev,
113 "failed to set regulator %s voltage\n",
114 regulators[i].name);
115 regulator_put(reg);
116 goto err;
117 }
118 }
119
120 r = regulator_enable(reg);
121 if (r) {
122 dev_err(&dssdev->dev, "failed to enable regulator %s\n",
123 regulators[i].name);
124 regulator_put(reg);
125 goto err;
126 }
127
128 regulators[i].regulator = reg;
129 }
130
131 return 0;
132
133err:
134 free_regulators(regulators, i);
135
136 return r;
137}
138
139/**
140 * struct panel_config - panel configuration
141 * @name: panel name
142 * @type: panel type
143 * @timings: panel resolution
144 * @sleep: various panel specific delays, passed to msleep() if non-zero
145 * @reset_sequence: reset sequence timings, passed to udelay() if non-zero
146 * @regulators: array of panel regulators
147 * @num_regulators: number of regulators in the array
148 */
149struct panel_config {
150 const char *name;
151 int type;
152
153 struct omap_video_timings timings;
154
155 struct {
156 unsigned int sleep_in;
157 unsigned int sleep_out;
158 unsigned int hw_reset;
159 unsigned int enable_te;
160 } sleep;
161
162 struct {
163 unsigned int high;
164 unsigned int low;
165 } reset_sequence;
166
167 struct panel_regulator *regulators;
168 int num_regulators;
169};
170
171enum {
172 PANEL_TAAL,
173};
174
175static struct panel_config panel_configs[] = {
176 {
177 .name = "taal",
178 .type = PANEL_TAAL,
179 .timings = {
180 .x_res = 864,
181 .y_res = 480,
182 },
183 .sleep = {
184 .sleep_in = 5,
185 .sleep_out = 5,
186 .hw_reset = 5,
187 .enable_te = 100, /* possible panel bug */
188 },
189 .reset_sequence = {
190 .high = 10,
191 .low = 10,
192 },
193 },
194};
195
70struct taal_data { 196struct taal_data {
71 struct mutex lock; 197 struct mutex lock;
72 198
@@ -84,8 +210,15 @@ struct taal_data {
84 bool mirror; 210 bool mirror;
85 211
86 bool te_enabled; 212 bool te_enabled;
87 bool use_ext_te; 213
88 struct completion te_completion; 214 atomic_t do_update;
215 struct {
216 u16 x;
217 u16 y;
218 u16 w;
219 u16 h;
220 } update_region;
221 struct delayed_work te_timeout_work;
89 222
90 bool use_dsi_bl; 223 bool use_dsi_bl;
91 224
@@ -96,8 +229,16 @@ struct taal_data {
96 229
97 struct workqueue_struct *esd_wq; 230 struct workqueue_struct *esd_wq;
98 struct delayed_work esd_work; 231 struct delayed_work esd_work;
232
233 struct panel_config *panel_config;
99}; 234};
100 235
236static inline struct nokia_dsi_panel_data
237*get_panel_data(const struct omap_dss_device *dssdev)
238{
239 return (struct nokia_dsi_panel_data *) dssdev->data;
240}
241
101static void taal_esd_work(struct work_struct *work); 242static void taal_esd_work(struct work_struct *work);
102 243
103static void hw_guard_start(struct taal_data *td, int guard_msec) 244static void hw_guard_start(struct taal_data *td, int guard_msec)
@@ -159,7 +300,8 @@ static int taal_sleep_in(struct taal_data *td)
159 300
160 hw_guard_start(td, 120); 301 hw_guard_start(td, 120);
161 302
162 msleep(5); 303 if (td->panel_config->sleep.sleep_in)
304 msleep(td->panel_config->sleep.sleep_in);
163 305
164 return 0; 306 return 0;
165} 307}
@@ -176,7 +318,8 @@ static int taal_sleep_out(struct taal_data *td)
176 318
177 hw_guard_start(td, 120); 319 hw_guard_start(td, 120);
178 320
179 msleep(5); 321 if (td->panel_config->sleep.sleep_out)
322 msleep(td->panel_config->sleep.sleep_out);
180 323
181 return 0; 324 return 0;
182} 325}
@@ -279,6 +422,7 @@ static int taal_bl_update_status(struct backlight_device *dev)
279{ 422{
280 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev); 423 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
281 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 424 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
425 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
282 int r; 426 int r;
283 int level; 427 int level;
284 428
@@ -290,24 +434,26 @@ static int taal_bl_update_status(struct backlight_device *dev)
290 434
291 dev_dbg(&dssdev->dev, "update brightness to %d\n", level); 435 dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
292 436
437 mutex_lock(&td->lock);
438
293 if (td->use_dsi_bl) { 439 if (td->use_dsi_bl) {
294 if (td->enabled) { 440 if (td->enabled) {
295 dsi_bus_lock(); 441 dsi_bus_lock();
296 r = taal_dcs_write_1(DCS_BRIGHTNESS, level); 442 r = taal_dcs_write_1(DCS_BRIGHTNESS, level);
297 dsi_bus_unlock(); 443 dsi_bus_unlock();
298 if (r) 444 } else {
299 return r; 445 r = 0;
300 } 446 }
301 } else { 447 } else {
302 if (!dssdev->set_backlight) 448 if (!panel_data->set_backlight)
303 return -EINVAL; 449 r = -EINVAL;
304 450 else
305 r = dssdev->set_backlight(dssdev, level); 451 r = panel_data->set_backlight(dssdev, level);
306 if (r)
307 return r;
308 } 452 }
309 453
310 return 0; 454 mutex_unlock(&td->lock);
455
456 return r;
311} 457}
312 458
313static int taal_bl_get_intensity(struct backlight_device *dev) 459static int taal_bl_get_intensity(struct backlight_device *dev)
@@ -344,16 +490,6 @@ static void taal_get_resolution(struct omap_dss_device *dssdev,
344 } 490 }
345} 491}
346 492
347static irqreturn_t taal_te_isr(int irq, void *data)
348{
349 struct omap_dss_device *dssdev = data;
350 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
351
352 complete_all(&td->te_completion);
353
354 return IRQ_HANDLED;
355}
356
357static ssize_t taal_num_errors_show(struct device *dev, 493static ssize_t taal_num_errors_show(struct device *dev,
358 struct device_attribute *attr, char *buf) 494 struct device_attribute *attr, char *buf)
359{ 495{
@@ -362,6 +498,8 @@ static ssize_t taal_num_errors_show(struct device *dev,
362 u8 errors; 498 u8 errors;
363 int r; 499 int r;
364 500
501 mutex_lock(&td->lock);
502
365 if (td->enabled) { 503 if (td->enabled) {
366 dsi_bus_lock(); 504 dsi_bus_lock();
367 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors); 505 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors);
@@ -370,6 +508,8 @@ static ssize_t taal_num_errors_show(struct device *dev,
370 r = -ENODEV; 508 r = -ENODEV;
371 } 509 }
372 510
511 mutex_unlock(&td->lock);
512
373 if (r) 513 if (r)
374 return r; 514 return r;
375 515
@@ -384,6 +524,8 @@ static ssize_t taal_hw_revision_show(struct device *dev,
384 u8 id1, id2, id3; 524 u8 id1, id2, id3;
385 int r; 525 int r;
386 526
527 mutex_lock(&td->lock);
528
387 if (td->enabled) { 529 if (td->enabled) {
388 dsi_bus_lock(); 530 dsi_bus_lock();
389 r = taal_get_id(&id1, &id2, &id3); 531 r = taal_get_id(&id1, &id2, &id3);
@@ -392,6 +534,8 @@ static ssize_t taal_hw_revision_show(struct device *dev,
392 r = -ENODEV; 534 r = -ENODEV;
393 } 535 }
394 536
537 mutex_unlock(&td->lock);
538
395 if (r) 539 if (r)
396 return r; 540 return r;
397 541
@@ -441,6 +585,8 @@ static ssize_t store_cabc_mode(struct device *dev,
441 if (i == ARRAY_SIZE(cabc_modes)) 585 if (i == ARRAY_SIZE(cabc_modes))
442 return -EINVAL; 586 return -EINVAL;
443 587
588 mutex_lock(&td->lock);
589
444 if (td->enabled) { 590 if (td->enabled) {
445 dsi_bus_lock(); 591 dsi_bus_lock();
446 if (!td->cabc_broken) 592 if (!td->cabc_broken)
@@ -450,6 +596,8 @@ static ssize_t store_cabc_mode(struct device *dev,
450 596
451 td->cabc_mode = i; 597 td->cabc_mode = i;
452 598
599 mutex_unlock(&td->lock);
600
453 return count; 601 return count;
454} 602}
455 603
@@ -488,47 +636,93 @@ static struct attribute_group taal_attr_group = {
488 .attrs = taal_attrs, 636 .attrs = taal_attrs,
489}; 637};
490 638
639static void taal_hw_reset(struct omap_dss_device *dssdev)
640{
641 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
642 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
643
644 if (panel_data->reset_gpio == -1)
645 return;
646
647 gpio_set_value(panel_data->reset_gpio, 1);
648 if (td->panel_config->reset_sequence.high)
649 udelay(td->panel_config->reset_sequence.high);
650 /* reset the panel */
651 gpio_set_value(panel_data->reset_gpio, 0);
652 /* assert reset */
653 if (td->panel_config->reset_sequence.low)
654 udelay(td->panel_config->reset_sequence.low);
655 gpio_set_value(panel_data->reset_gpio, 1);
656 /* wait after releasing reset */
657 if (td->panel_config->sleep.hw_reset)
658 msleep(td->panel_config->sleep.hw_reset);
659}
660
491static int taal_probe(struct omap_dss_device *dssdev) 661static int taal_probe(struct omap_dss_device *dssdev)
492{ 662{
493 struct backlight_properties props; 663 struct backlight_properties props;
494 struct taal_data *td; 664 struct taal_data *td;
495 struct backlight_device *bldev; 665 struct backlight_device *bldev;
496 int r; 666 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
497 667 struct panel_config *panel_config = NULL;
498 const struct omap_video_timings taal_panel_timings = { 668 int r, i;
499 .x_res = 864,
500 .y_res = 480,
501 };
502 669
503 dev_dbg(&dssdev->dev, "probe\n"); 670 dev_dbg(&dssdev->dev, "probe\n");
504 671
672 if (!panel_data || !panel_data->name) {
673 r = -EINVAL;
674 goto err;
675 }
676
677 for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
678 if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
679 panel_config = &panel_configs[i];
680 break;
681 }
682 }
683
684 if (!panel_config) {
685 r = -EINVAL;
686 goto err;
687 }
688
505 dssdev->panel.config = OMAP_DSS_LCD_TFT; 689 dssdev->panel.config = OMAP_DSS_LCD_TFT;
506 dssdev->panel.timings = taal_panel_timings; 690 dssdev->panel.timings = panel_config->timings;
507 dssdev->ctrl.pixel_size = 24; 691 dssdev->ctrl.pixel_size = 24;
508 692
509 td = kzalloc(sizeof(*td), GFP_KERNEL); 693 td = kzalloc(sizeof(*td), GFP_KERNEL);
510 if (!td) { 694 if (!td) {
511 r = -ENOMEM; 695 r = -ENOMEM;
512 goto err0; 696 goto err;
513 } 697 }
514 td->dssdev = dssdev; 698 td->dssdev = dssdev;
699 td->panel_config = panel_config;
515 700
516 mutex_init(&td->lock); 701 mutex_init(&td->lock);
517 702
703 atomic_set(&td->do_update, 0);
704
705 r = init_regulators(dssdev, panel_config->regulators,
706 panel_config->num_regulators);
707 if (r)
708 goto err_reg;
709
518 td->esd_wq = create_singlethread_workqueue("taal_esd"); 710 td->esd_wq = create_singlethread_workqueue("taal_esd");
519 if (td->esd_wq == NULL) { 711 if (td->esd_wq == NULL) {
520 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); 712 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
521 r = -ENOMEM; 713 r = -ENOMEM;
522 goto err1; 714 goto err_wq;
523 } 715 }
524 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); 716 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
525 717
526 dev_set_drvdata(&dssdev->dev, td); 718 dev_set_drvdata(&dssdev->dev, td);
527 719
720 taal_hw_reset(dssdev);
721
528 /* if no platform set_backlight() defined, presume DSI backlight 722 /* if no platform set_backlight() defined, presume DSI backlight
529 * control */ 723 * control */
530 memset(&props, 0, sizeof(struct backlight_properties)); 724 memset(&props, 0, sizeof(struct backlight_properties));
531 if (!dssdev->set_backlight) 725 if (!panel_data->set_backlight)
532 td->use_dsi_bl = true; 726 td->use_dsi_bl = true;
533 727
534 if (td->use_dsi_bl) 728 if (td->use_dsi_bl)
@@ -539,7 +733,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
539 &taal_bl_ops, &props); 733 &taal_bl_ops, &props);
540 if (IS_ERR(bldev)) { 734 if (IS_ERR(bldev)) {
541 r = PTR_ERR(bldev); 735 r = PTR_ERR(bldev);
542 goto err2; 736 goto err_bl;
543 } 737 }
544 738
545 td->bldev = bldev; 739 td->bldev = bldev;
@@ -553,13 +747,13 @@ static int taal_probe(struct omap_dss_device *dssdev)
553 747
554 taal_bl_update_status(bldev); 748 taal_bl_update_status(bldev);
555 749
556 if (dssdev->phy.dsi.ext_te) { 750 if (panel_data->use_ext_te) {
557 int gpio = dssdev->phy.dsi.ext_te_gpio; 751 int gpio = panel_data->ext_te_gpio;
558 752
559 r = gpio_request(gpio, "taal irq"); 753 r = gpio_request(gpio, "taal irq");
560 if (r) { 754 if (r) {
561 dev_err(&dssdev->dev, "GPIO request failed\n"); 755 dev_err(&dssdev->dev, "GPIO request failed\n");
562 goto err3; 756 goto err_gpio;
563 } 757 }
564 758
565 gpio_direction_input(gpio); 759 gpio_direction_input(gpio);
@@ -571,49 +765,52 @@ static int taal_probe(struct omap_dss_device *dssdev)
571 if (r) { 765 if (r) {
572 dev_err(&dssdev->dev, "IRQ request failed\n"); 766 dev_err(&dssdev->dev, "IRQ request failed\n");
573 gpio_free(gpio); 767 gpio_free(gpio);
574 goto err3; 768 goto err_irq;
575 } 769 }
576 770
577 init_completion(&td->te_completion); 771 INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
772 taal_te_timeout_work_callback);
578 773
579 td->use_ext_te = true; 774 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
580 } 775 }
581 776
582 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); 777 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
583 if (r) { 778 if (r) {
584 dev_err(&dssdev->dev, "failed to create sysfs files\n"); 779 dev_err(&dssdev->dev, "failed to create sysfs files\n");
585 goto err4; 780 goto err_sysfs;
586 } 781 }
587 782
588 return 0; 783 return 0;
589err4: 784err_sysfs:
590 if (td->use_ext_te) { 785 if (panel_data->use_ext_te)
591 int gpio = dssdev->phy.dsi.ext_te_gpio; 786 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
592 free_irq(gpio_to_irq(gpio), dssdev); 787err_irq:
593 gpio_free(gpio); 788 if (panel_data->use_ext_te)
594 } 789 gpio_free(panel_data->ext_te_gpio);
595err3: 790err_gpio:
596 backlight_device_unregister(bldev); 791 backlight_device_unregister(bldev);
597err2: 792err_bl:
598 cancel_delayed_work_sync(&td->esd_work);
599 destroy_workqueue(td->esd_wq); 793 destroy_workqueue(td->esd_wq);
600err1: 794err_wq:
795 free_regulators(panel_config->regulators, panel_config->num_regulators);
796err_reg:
601 kfree(td); 797 kfree(td);
602err0: 798err:
603 return r; 799 return r;
604} 800}
605 801
606static void taal_remove(struct omap_dss_device *dssdev) 802static void taal_remove(struct omap_dss_device *dssdev)
607{ 803{
608 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 804 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
805 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
609 struct backlight_device *bldev; 806 struct backlight_device *bldev;
610 807
611 dev_dbg(&dssdev->dev, "remove\n"); 808 dev_dbg(&dssdev->dev, "remove\n");
612 809
613 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); 810 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
614 811
615 if (td->use_ext_te) { 812 if (panel_data->use_ext_te) {
616 int gpio = dssdev->phy.dsi.ext_te_gpio; 813 int gpio = panel_data->ext_te_gpio;
617 free_irq(gpio_to_irq(gpio), dssdev); 814 free_irq(gpio_to_irq(gpio), dssdev);
618 gpio_free(gpio); 815 gpio_free(gpio);
619 } 816 }
@@ -623,9 +820,15 @@ static void taal_remove(struct omap_dss_device *dssdev)
623 taal_bl_update_status(bldev); 820 taal_bl_update_status(bldev);
624 backlight_device_unregister(bldev); 821 backlight_device_unregister(bldev);
625 822
626 cancel_delayed_work_sync(&td->esd_work); 823 cancel_delayed_work(&td->esd_work);
627 destroy_workqueue(td->esd_wq); 824 destroy_workqueue(td->esd_wq);
628 825
826 /* reset, to be sure that the panel is in a valid state */
827 taal_hw_reset(dssdev);
828
829 free_regulators(td->panel_config->regulators,
830 td->panel_config->num_regulators);
831
629 kfree(td); 832 kfree(td);
630} 833}
631 834
@@ -635,23 +838,14 @@ static int taal_power_on(struct omap_dss_device *dssdev)
635 u8 id1, id2, id3; 838 u8 id1, id2, id3;
636 int r; 839 int r;
637 840
638 if (dssdev->platform_enable) {
639 r = dssdev->platform_enable(dssdev);
640 if (r)
641 return r;
642 }
643
644 /* it seems we have to wait a bit until taal is ready */
645 msleep(5);
646
647 dsi_bus_lock();
648
649 r = omapdss_dsi_display_enable(dssdev); 841 r = omapdss_dsi_display_enable(dssdev);
650 if (r) { 842 if (r) {
651 dev_err(&dssdev->dev, "failed to enable DSI\n"); 843 dev_err(&dssdev->dev, "failed to enable DSI\n");
652 goto err0; 844 goto err0;
653 } 845 }
654 846
847 taal_hw_reset(dssdev);
848
655 omapdss_dsi_vc_enable_hs(TCH, false); 849 omapdss_dsi_vc_enable_hs(TCH, false);
656 850
657 r = taal_sleep_out(td); 851 r = taal_sleep_out(td);
@@ -662,34 +856,47 @@ static int taal_power_on(struct omap_dss_device *dssdev)
662 if (r) 856 if (r)
663 goto err; 857 goto err;
664 858
665 /* on early revisions CABC is broken */ 859 /* on early Taal revisions CABC is broken */
666 if (id2 == 0x00 || id2 == 0xff || id2 == 0x81) 860 if (td->panel_config->type == PANEL_TAAL &&
861 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
667 td->cabc_broken = true; 862 td->cabc_broken = true;
668 863
669 taal_dcs_write_1(DCS_BRIGHTNESS, 0xff); 864 r = taal_dcs_write_1(DCS_BRIGHTNESS, 0xff);
670 taal_dcs_write_1(DCS_CTRL_DISPLAY, (1<<2) | (1<<5)); /* BL | BCTRL */ 865 if (r)
866 goto err;
867
868 r = taal_dcs_write_1(DCS_CTRL_DISPLAY,
869 (1<<2) | (1<<5)); /* BL | BCTRL */
870 if (r)
871 goto err;
872
873 r = taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
874 if (r)
875 goto err;
671 876
672 taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ 877 r = taal_set_addr_mode(td->rotate, td->mirror);
878 if (r)
879 goto err;
673 880
674 taal_set_addr_mode(td->rotate, td->mirror); 881 if (!td->cabc_broken) {
675 if (!td->cabc_broken) 882 r = taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode);
676 taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode); 883 if (r)
884 goto err;
885 }
677 886
678 taal_dcs_write_0(DCS_DISPLAY_ON); 887 r = taal_dcs_write_0(DCS_DISPLAY_ON);
888 if (r)
889 goto err;
679 890
680 r = _taal_enable_te(dssdev, td->te_enabled); 891 r = _taal_enable_te(dssdev, td->te_enabled);
681 if (r) 892 if (r)
682 goto err; 893 goto err;
683 894
684#ifdef TAAL_USE_ESD_CHECK
685 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
686#endif
687
688 td->enabled = 1; 895 td->enabled = 1;
689 896
690 if (!td->intro_printed) { 897 if (!td->intro_printed) {
691 dev_info(&dssdev->dev, "revision %02x.%02x.%02x\n", 898 dev_info(&dssdev->dev, "%s panel revision %02x.%02x.%02x\n",
692 id1, id2, id3); 899 td->panel_config->name, id1, id2, id3);
693 if (td->cabc_broken) 900 if (td->cabc_broken)
694 dev_info(&dssdev->dev, 901 dev_info(&dssdev->dev,
695 "old Taal version, CABC disabled\n"); 902 "old Taal version, CABC disabled\n");
@@ -698,46 +905,44 @@ static int taal_power_on(struct omap_dss_device *dssdev)
698 905
699 omapdss_dsi_vc_enable_hs(TCH, true); 906 omapdss_dsi_vc_enable_hs(TCH, true);
700 907
701 dsi_bus_unlock();
702
703 return 0; 908 return 0;
704err: 909err:
910 dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n");
911
912 taal_hw_reset(dssdev);
913
705 omapdss_dsi_display_disable(dssdev); 914 omapdss_dsi_display_disable(dssdev);
706err0: 915err0:
707 dsi_bus_unlock();
708 if (dssdev->platform_disable)
709 dssdev->platform_disable(dssdev);
710
711 return r; 916 return r;
712} 917}
713 918
714static void taal_power_off(struct omap_dss_device *dssdev) 919static void taal_power_off(struct omap_dss_device *dssdev)
715{ 920{
716 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 921 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
922 int r;
717 923
718 dsi_bus_lock(); 924 r = taal_dcs_write_0(DCS_DISPLAY_OFF);
719 925 if (!r) {
720 cancel_delayed_work(&td->esd_work); 926 r = taal_sleep_in(td);
721 927 /* HACK: wait a bit so that the message goes through */
722 taal_dcs_write_0(DCS_DISPLAY_OFF); 928 msleep(10);
723 taal_sleep_in(td); 929 }
724 930
725 /* wait a bit so that the message goes through */ 931 if (r) {
726 msleep(10); 932 dev_err(&dssdev->dev,
933 "error disabling panel, issuing HW reset\n");
934 taal_hw_reset(dssdev);
935 }
727 936
728 omapdss_dsi_display_disable(dssdev); 937 omapdss_dsi_display_disable(dssdev);
729 938
730 if (dssdev->platform_disable)
731 dssdev->platform_disable(dssdev);
732
733 td->enabled = 0; 939 td->enabled = 0;
734
735 dsi_bus_unlock();
736} 940}
737 941
738static int taal_enable(struct omap_dss_device *dssdev) 942static int taal_enable(struct omap_dss_device *dssdev)
739{ 943{
740 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 944 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
945 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
741 int r; 946 int r;
742 947
743 dev_dbg(&dssdev->dev, "enable\n"); 948 dev_dbg(&dssdev->dev, "enable\n");
@@ -749,10 +954,19 @@ static int taal_enable(struct omap_dss_device *dssdev)
749 goto err; 954 goto err;
750 } 955 }
751 956
957 dsi_bus_lock();
958
752 r = taal_power_on(dssdev); 959 r = taal_power_on(dssdev);
960
961 dsi_bus_unlock();
962
753 if (r) 963 if (r)
754 goto err; 964 goto err;
755 965
966 if (panel_data->use_esd_check)
967 queue_delayed_work(td->esd_wq, &td->esd_work,
968 TAAL_ESD_CHECK_PERIOD);
969
756 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 970 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
757 971
758 mutex_unlock(&td->lock); 972 mutex_unlock(&td->lock);
@@ -772,9 +986,15 @@ static void taal_disable(struct omap_dss_device *dssdev)
772 986
773 mutex_lock(&td->lock); 987 mutex_lock(&td->lock);
774 988
989 cancel_delayed_work(&td->esd_work);
990
991 dsi_bus_lock();
992
775 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 993 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
776 taal_power_off(dssdev); 994 taal_power_off(dssdev);
777 995
996 dsi_bus_unlock();
997
778 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 998 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
779 999
780 mutex_unlock(&td->lock); 1000 mutex_unlock(&td->lock);
@@ -794,7 +1014,14 @@ static int taal_suspend(struct omap_dss_device *dssdev)
794 goto err; 1014 goto err;
795 } 1015 }
796 1016
1017 cancel_delayed_work(&td->esd_work);
1018
1019 dsi_bus_lock();
1020
797 taal_power_off(dssdev); 1021 taal_power_off(dssdev);
1022
1023 dsi_bus_unlock();
1024
798 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 1025 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
799 1026
800 mutex_unlock(&td->lock); 1027 mutex_unlock(&td->lock);
@@ -808,6 +1035,7 @@ err:
808static int taal_resume(struct omap_dss_device *dssdev) 1035static int taal_resume(struct omap_dss_device *dssdev)
809{ 1036{
810 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1037 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1038 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
811 int r; 1039 int r;
812 1040
813 dev_dbg(&dssdev->dev, "resume\n"); 1041 dev_dbg(&dssdev->dev, "resume\n");
@@ -819,8 +1047,20 @@ static int taal_resume(struct omap_dss_device *dssdev)
819 goto err; 1047 goto err;
820 } 1048 }
821 1049
1050 dsi_bus_lock();
1051
822 r = taal_power_on(dssdev); 1052 r = taal_power_on(dssdev);
823 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 1053
1054 dsi_bus_unlock();
1055
1056 if (r) {
1057 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1058 } else {
1059 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1060 if (panel_data->use_esd_check)
1061 queue_delayed_work(td->esd_wq, &td->esd_work,
1062 TAAL_ESD_CHECK_PERIOD);
1063 }
824 1064
825 mutex_unlock(&td->lock); 1065 mutex_unlock(&td->lock);
826 1066
@@ -837,10 +1077,52 @@ static void taal_framedone_cb(int err, void *data)
837 dsi_bus_unlock(); 1077 dsi_bus_unlock();
838} 1078}
839 1079
1080static irqreturn_t taal_te_isr(int irq, void *data)
1081{
1082 struct omap_dss_device *dssdev = data;
1083 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1084 int old;
1085 int r;
1086
1087 old = atomic_cmpxchg(&td->do_update, 1, 0);
1088
1089 if (old) {
1090 cancel_delayed_work(&td->te_timeout_work);
1091
1092 r = omap_dsi_update(dssdev, TCH,
1093 td->update_region.x,
1094 td->update_region.y,
1095 td->update_region.w,
1096 td->update_region.h,
1097 taal_framedone_cb, dssdev);
1098 if (r)
1099 goto err;
1100 }
1101
1102 return IRQ_HANDLED;
1103err:
1104 dev_err(&dssdev->dev, "start update failed\n");
1105 dsi_bus_unlock();
1106 return IRQ_HANDLED;
1107}
1108
1109static void taal_te_timeout_work_callback(struct work_struct *work)
1110{
1111 struct taal_data *td = container_of(work, struct taal_data,
1112 te_timeout_work.work);
1113 struct omap_dss_device *dssdev = td->dssdev;
1114
1115 dev_err(&dssdev->dev, "TE not received for 250ms!\n");
1116
1117 atomic_set(&td->do_update, 0);
1118 dsi_bus_unlock();
1119}
1120
840static int taal_update(struct omap_dss_device *dssdev, 1121static int taal_update(struct omap_dss_device *dssdev,
841 u16 x, u16 y, u16 w, u16 h) 1122 u16 x, u16 y, u16 w, u16 h)
842{ 1123{
843 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1124 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1125 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
844 int r; 1126 int r;
845 1127
846 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); 1128 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
@@ -853,7 +1135,7 @@ static int taal_update(struct omap_dss_device *dssdev,
853 goto err; 1135 goto err;
854 } 1136 }
855 1137
856 r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h); 1138 r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h, true);
857 if (r) 1139 if (r)
858 goto err; 1140 goto err;
859 1141
@@ -861,10 +1143,21 @@ static int taal_update(struct omap_dss_device *dssdev,
861 if (r) 1143 if (r)
862 goto err; 1144 goto err;
863 1145
864 r = omap_dsi_update(dssdev, TCH, x, y, w, h, 1146 if (td->te_enabled && panel_data->use_ext_te) {
865 taal_framedone_cb, dssdev); 1147 td->update_region.x = x;
866 if (r) 1148 td->update_region.y = y;
867 goto err; 1149 td->update_region.w = w;
1150 td->update_region.h = h;
1151 barrier();
1152 schedule_delayed_work(&td->te_timeout_work,
1153 msecs_to_jiffies(250));
1154 atomic_set(&td->do_update, 1);
1155 } else {
1156 r = omap_dsi_update(dssdev, TCH, x, y, w, h,
1157 taal_framedone_cb, dssdev);
1158 if (r)
1159 goto err;
1160 }
868 1161
869 /* note: no bus_unlock here. unlock is in framedone_cb */ 1162 /* note: no bus_unlock here. unlock is in framedone_cb */
870 mutex_unlock(&td->lock); 1163 mutex_unlock(&td->lock);
@@ -894,20 +1187,19 @@ static int taal_sync(struct omap_dss_device *dssdev)
894static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) 1187static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
895{ 1188{
896 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1189 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1190 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
897 int r; 1191 int r;
898 1192
899 td->te_enabled = enable;
900
901 if (enable) 1193 if (enable)
902 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1194 r = taal_dcs_write_1(DCS_TEAR_ON, 0);
903 else 1195 else
904 r = taal_dcs_write_0(DCS_TEAR_OFF); 1196 r = taal_dcs_write_0(DCS_TEAR_OFF);
905 1197
906 omapdss_dsi_enable_te(dssdev, enable); 1198 if (!panel_data->use_ext_te)
1199 omapdss_dsi_enable_te(dssdev, enable);
907 1200
908 /* XXX for some reason, DSI TE breaks if we don't wait here. 1201 if (td->panel_config->sleep.enable_te)
909 * Panel bug? Needs more studying */ 1202 msleep(td->panel_config->sleep.enable_te);
910 msleep(100);
911 1203
912 return r; 1204 return r;
913} 1205}
@@ -918,10 +1210,26 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
918 int r; 1210 int r;
919 1211
920 mutex_lock(&td->lock); 1212 mutex_lock(&td->lock);
1213
1214 if (td->te_enabled == enable)
1215 goto end;
1216
921 dsi_bus_lock(); 1217 dsi_bus_lock();
922 1218
923 r = _taal_enable_te(dssdev, enable); 1219 if (td->enabled) {
1220 r = _taal_enable_te(dssdev, enable);
1221 if (r)
1222 goto err;
1223 }
1224
1225 td->te_enabled = enable;
1226
1227 dsi_bus_unlock();
1228end:
1229 mutex_unlock(&td->lock);
924 1230
1231 return 0;
1232err:
925 dsi_bus_unlock(); 1233 dsi_bus_unlock();
926 mutex_unlock(&td->lock); 1234 mutex_unlock(&td->lock);
927 1235
@@ -948,6 +1256,10 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
948 dev_dbg(&dssdev->dev, "rotate %d\n", rotate); 1256 dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
949 1257
950 mutex_lock(&td->lock); 1258 mutex_lock(&td->lock);
1259
1260 if (td->rotate == rotate)
1261 goto end;
1262
951 dsi_bus_lock(); 1263 dsi_bus_lock();
952 1264
953 if (td->enabled) { 1265 if (td->enabled) {
@@ -959,6 +1271,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
959 td->rotate = rotate; 1271 td->rotate = rotate;
960 1272
961 dsi_bus_unlock(); 1273 dsi_bus_unlock();
1274end:
962 mutex_unlock(&td->lock); 1275 mutex_unlock(&td->lock);
963 return 0; 1276 return 0;
964err: 1277err:
@@ -987,6 +1300,10 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
987 dev_dbg(&dssdev->dev, "mirror %d\n", enable); 1300 dev_dbg(&dssdev->dev, "mirror %d\n", enable);
988 1301
989 mutex_lock(&td->lock); 1302 mutex_lock(&td->lock);
1303
1304 if (td->mirror == enable)
1305 goto end;
1306
990 dsi_bus_lock(); 1307 dsi_bus_lock();
991 if (td->enabled) { 1308 if (td->enabled) {
992 r = taal_set_addr_mode(td->rotate, enable); 1309 r = taal_set_addr_mode(td->rotate, enable);
@@ -997,6 +1314,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
997 td->mirror = enable; 1314 td->mirror = enable;
998 1315
999 dsi_bus_unlock(); 1316 dsi_bus_unlock();
1317end:
1000 mutex_unlock(&td->lock); 1318 mutex_unlock(&td->lock);
1001 return 0; 1319 return 0;
1002err: 1320err:
@@ -1024,23 +1342,30 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1024 int r; 1342 int r;
1025 1343
1026 mutex_lock(&td->lock); 1344 mutex_lock(&td->lock);
1345
1346 if (!td->enabled) {
1347 r = -ENODEV;
1348 goto err1;
1349 }
1350
1027 dsi_bus_lock(); 1351 dsi_bus_lock();
1028 1352
1029 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 1353 r = taal_dcs_read_1(DCS_GET_ID1, &id1);
1030 if (r) 1354 if (r)
1031 goto err; 1355 goto err2;
1032 r = taal_dcs_read_1(DCS_GET_ID2, &id2); 1356 r = taal_dcs_read_1(DCS_GET_ID2, &id2);
1033 if (r) 1357 if (r)
1034 goto err; 1358 goto err2;
1035 r = taal_dcs_read_1(DCS_GET_ID3, &id3); 1359 r = taal_dcs_read_1(DCS_GET_ID3, &id3);
1036 if (r) 1360 if (r)
1037 goto err; 1361 goto err2;
1038 1362
1039 dsi_bus_unlock(); 1363 dsi_bus_unlock();
1040 mutex_unlock(&td->lock); 1364 mutex_unlock(&td->lock);
1041 return 0; 1365 return 0;
1042err: 1366err2:
1043 dsi_bus_unlock(); 1367 dsi_bus_unlock();
1368err1:
1044 mutex_unlock(&td->lock); 1369 mutex_unlock(&td->lock);
1045 return r; 1370 return r;
1046} 1371}
@@ -1128,6 +1453,7 @@ static void taal_esd_work(struct work_struct *work)
1128 struct taal_data *td = container_of(work, struct taal_data, 1453 struct taal_data *td = container_of(work, struct taal_data,
1129 esd_work.work); 1454 esd_work.work);
1130 struct omap_dss_device *dssdev = td->dssdev; 1455 struct omap_dss_device *dssdev = td->dssdev;
1456 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1131 u8 state1, state2; 1457 u8 state1, state2;
1132 int r; 1458 int r;
1133 1459
@@ -1168,7 +1494,7 @@ static void taal_esd_work(struct work_struct *work)
1168 } 1494 }
1169 /* Self-diagnostics result is also shown on TE GPIO line. We need 1495 /* Self-diagnostics result is also shown on TE GPIO line. We need
1170 * to re-enable TE after self diagnostics */ 1496 * to re-enable TE after self diagnostics */
1171 if (td->use_ext_te && td->te_enabled) { 1497 if (td->te_enabled && panel_data->use_ext_te) {
1172 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1498 r = taal_dcs_write_1(DCS_TEAR_ON, 0);
1173 if (r) 1499 if (r)
1174 goto err; 1500 goto err;
@@ -1184,6 +1510,7 @@ err:
1184 dev_err(&dssdev->dev, "performing LCD reset\n"); 1510 dev_err(&dssdev->dev, "performing LCD reset\n");
1185 1511
1186 taal_power_off(dssdev); 1512 taal_power_off(dssdev);
1513 taal_hw_reset(dssdev);
1187 taal_power_on(dssdev); 1514 taal_power_on(dssdev);
1188 1515
1189 dsi_bus_unlock(); 1516 dsi_bus_unlock();
diff --git a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
index fa434ca6e4b7..e320e67d06f3 100644
--- a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
+++ b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
@@ -73,8 +73,12 @@ static void toppoly_tdo_panel_power_off(struct omap_dss_device *dssdev)
73 73
74static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev) 74static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev)
75{ 75{
76 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | 76 dssdev->panel.config = OMAP_DSS_LCD_TFT |
77 OMAP_DSS_LCD_IHS; 77 OMAP_DSS_LCD_IVS |
78 OMAP_DSS_LCD_IHS |
79 OMAP_DSS_LCD_IPC |
80 OMAP_DSS_LCD_ONOFF;
81
78 dssdev->panel.timings = toppoly_tdo_panel_timings; 82 dssdev->panel.timings = toppoly_tdo_panel_timings;
79 83
80 return 0; 84 return 0;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index e777e352dbcd..5ecdc0004094 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -31,6 +31,7 @@
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/hardirq.h>
34 35
35#include <plat/sram.h> 36#include <plat/sram.h>
36#include <plat/clock.h> 37#include <plat/clock.h>
@@ -335,7 +336,7 @@ void dispc_save_context(void)
335void dispc_restore_context(void) 336void dispc_restore_context(void)
336{ 337{
337 RR(SYSCONFIG); 338 RR(SYSCONFIG);
338 RR(IRQENABLE); 339 /*RR(IRQENABLE);*/
339 /*RR(CONTROL);*/ 340 /*RR(CONTROL);*/
340 RR(CONFIG); 341 RR(CONFIG);
341 RR(DEFAULT_COLOR0); 342 RR(DEFAULT_COLOR0);
@@ -472,6 +473,15 @@ void dispc_restore_context(void)
472 473
473 /* enable last, because LCD & DIGIT enable are here */ 474 /* enable last, because LCD & DIGIT enable are here */
474 RR(CONTROL); 475 RR(CONTROL);
476
477 /* clear spurious SYNC_LOST_DIGIT interrupts */
478 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
479
480 /*
481 * enable last so IRQs won't trigger before
482 * the context is fully restored
483 */
484 RR(IRQENABLE);
475} 485}
476 486
477#undef SR 487#undef SR
@@ -3019,7 +3029,7 @@ void dispc_fake_vsync_irq(void)
3019 u32 irqstatus = DISPC_IRQ_VSYNC; 3029 u32 irqstatus = DISPC_IRQ_VSYNC;
3020 int i; 3030 int i;
3021 3031
3022 local_irq_disable(); 3032 WARN_ON(!in_interrupt());
3023 3033
3024 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { 3034 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
3025 struct omap_dispc_isr_data *isr_data; 3035 struct omap_dispc_isr_data *isr_data;
@@ -3031,8 +3041,6 @@ void dispc_fake_vsync_irq(void)
3031 if (isr_data->mask & irqstatus) 3041 if (isr_data->mask & irqstatus)
3032 isr_data->isr(isr_data->arg, irqstatus); 3042 isr_data->isr(isr_data->arg, irqstatus);
3033 } 3043 }
3034
3035 local_irq_enable();
3036} 3044}
3037#endif 3045#endif
3038 3046
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index ef8c8529dda2..22dd7a474f79 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -82,6 +82,9 @@ static ssize_t display_upd_mode_store(struct device *dev,
82 int val, r; 82 int val, r;
83 enum omap_dss_update_mode mode; 83 enum omap_dss_update_mode mode;
84 84
85 if (!dssdev->driver->set_update_mode)
86 return -EINVAL;
87
85 val = simple_strtoul(buf, NULL, 10); 88 val = simple_strtoul(buf, NULL, 10);
86 89
87 switch (val) { 90 switch (val) {
@@ -343,7 +346,6 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
343 case OMAP_DISPLAY_TYPE_VENC: 346 case OMAP_DISPLAY_TYPE_VENC:
344 case OMAP_DISPLAY_TYPE_SDI: 347 case OMAP_DISPLAY_TYPE_SDI:
345 return 24; 348 return 24;
346 return 24;
347 default: 349 default:
348 BUG(); 350 BUG();
349 } 351 }
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 3af207b2bde3..b3fa3a7db911 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -165,6 +165,14 @@ struct dsi_reg { u16 idx; };
165#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25) 165#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25)
166#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30) 166#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30)
167#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31) 167#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31)
168#define DSI_CIO_IRQ_ERROR_MASK \
169 (DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \
170 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \
171 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRCONTROL1 | \
172 DSI_CIO_IRQ_ERRCONTROL2 | DSI_CIO_IRQ_ERRCONTROL3 | \
173 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \
174 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \
175 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3)
168 176
169#define DSI_DT_DCS_SHORT_WRITE_0 0x05 177#define DSI_DT_DCS_SHORT_WRITE_0 0x05
170#define DSI_DT_DCS_SHORT_WRITE_1 0x15 178#define DSI_DT_DCS_SHORT_WRITE_1 0x15
@@ -232,13 +240,15 @@ static struct
232 unsigned pll_locked; 240 unsigned pll_locked;
233 241
234 struct completion bta_completion; 242 struct completion bta_completion;
243 void (*bta_callback)(void);
235 244
236 int update_channel; 245 int update_channel;
237 struct dsi_update_region update_region; 246 struct dsi_update_region update_region;
238 247
239 bool te_enabled; 248 bool te_enabled;
240 249
241 struct work_struct framedone_work; 250 struct workqueue_struct *workqueue;
251
242 void (*framedone_callback)(int, void *); 252 void (*framedone_callback)(int, void *);
243 void *framedone_data; 253 void *framedone_data;
244 254
@@ -509,9 +519,13 @@ void dsi_irq_handler(void)
509 dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); 519 dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]);
510#endif 520#endif
511 521
512 if (vcstatus & DSI_VC_IRQ_BTA) 522 if (vcstatus & DSI_VC_IRQ_BTA) {
513 complete(&dsi.bta_completion); 523 complete(&dsi.bta_completion);
514 524
525 if (dsi.bta_callback)
526 dsi.bta_callback();
527 }
528
515 if (vcstatus & DSI_VC_IRQ_ERROR_MASK) { 529 if (vcstatus & DSI_VC_IRQ_ERROR_MASK) {
516 DSSERR("DSI VC(%d) error, vc irqstatus %x\n", 530 DSSERR("DSI VC(%d) error, vc irqstatus %x\n",
517 i, vcstatus); 531 i, vcstatus);
@@ -536,8 +550,12 @@ void dsi_irq_handler(void)
536 /* flush posted write */ 550 /* flush posted write */
537 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 551 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
538 552
539 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); 553 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) {
540 print_irq_status_cio(ciostatus); 554 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus);
555 print_irq_status_cio(ciostatus);
556 } else if (debug_irq) {
557 print_irq_status_cio(ciostatus);
558 }
541 } 559 }
542 560
543 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); 561 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
@@ -584,11 +602,8 @@ static void _dsi_initialize_irq(void)
584 for (i = 0; i < 4; ++i) 602 for (i = 0; i < 4; ++i)
585 dsi_write_reg(DSI_VC_IRQENABLE(i), l); 603 dsi_write_reg(DSI_VC_IRQENABLE(i), l);
586 604
587 /* XXX zonda responds incorrectly, causing control error: 605 l = DSI_CIO_IRQ_ERROR_MASK;
588 Exit from LP-ESC mode to LP11 uses wrong transition states on the 606 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, l);
589 data lines LP0 and LN0. */
590 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE,
591 -1 & (~DSI_CIO_IRQ_ERRCONTROL2));
592} 607}
593 608
594static u32 dsi_get_errors(void) 609static u32 dsi_get_errors(void)
@@ -1098,6 +1113,7 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1098 if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) { 1113 if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) {
1099 DSSERR("PLL not coming out of reset.\n"); 1114 DSSERR("PLL not coming out of reset.\n");
1100 r = -ENODEV; 1115 r = -ENODEV;
1116 dispc_pck_free_enable(0);
1101 goto err1; 1117 goto err1;
1102 } 1118 }
1103 1119
@@ -1740,42 +1756,52 @@ static void dsi_vc_initial_config(int channel)
1740 dsi.vc[channel].mode = DSI_VC_MODE_L4; 1756 dsi.vc[channel].mode = DSI_VC_MODE_L4;
1741} 1757}
1742 1758
1743static void dsi_vc_config_l4(int channel) 1759static int dsi_vc_config_l4(int channel)
1744{ 1760{
1745 if (dsi.vc[channel].mode == DSI_VC_MODE_L4) 1761 if (dsi.vc[channel].mode == DSI_VC_MODE_L4)
1746 return; 1762 return 0;
1747 1763
1748 DSSDBGF("%d", channel); 1764 DSSDBGF("%d", channel);
1749 1765
1750 dsi_vc_enable(channel, 0); 1766 dsi_vc_enable(channel, 0);
1751 1767
1752 if (REG_GET(DSI_VC_CTRL(channel), 15, 15)) /* VC_BUSY */ 1768 /* VC_BUSY */
1769 if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) {
1753 DSSERR("vc(%d) busy when trying to config for L4\n", channel); 1770 DSSERR("vc(%d) busy when trying to config for L4\n", channel);
1771 return -EIO;
1772 }
1754 1773
1755 REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */ 1774 REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
1756 1775
1757 dsi_vc_enable(channel, 1); 1776 dsi_vc_enable(channel, 1);
1758 1777
1759 dsi.vc[channel].mode = DSI_VC_MODE_L4; 1778 dsi.vc[channel].mode = DSI_VC_MODE_L4;
1779
1780 return 0;
1760} 1781}
1761 1782
1762static void dsi_vc_config_vp(int channel) 1783static int dsi_vc_config_vp(int channel)
1763{ 1784{
1764 if (dsi.vc[channel].mode == DSI_VC_MODE_VP) 1785 if (dsi.vc[channel].mode == DSI_VC_MODE_VP)
1765 return; 1786 return 0;
1766 1787
1767 DSSDBGF("%d", channel); 1788 DSSDBGF("%d", channel);
1768 1789
1769 dsi_vc_enable(channel, 0); 1790 dsi_vc_enable(channel, 0);
1770 1791
1771 if (REG_GET(DSI_VC_CTRL(channel), 15, 15)) /* VC_BUSY */ 1792 /* VC_BUSY */
1793 if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) {
1772 DSSERR("vc(%d) busy when trying to config for VP\n", channel); 1794 DSSERR("vc(%d) busy when trying to config for VP\n", channel);
1795 return -EIO;
1796 }
1773 1797
1774 REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */ 1798 REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */
1775 1799
1776 dsi_vc_enable(channel, 1); 1800 dsi_vc_enable(channel, 1);
1777 1801
1778 dsi.vc[channel].mode = DSI_VC_MODE_VP; 1802 dsi.vc[channel].mode = DSI_VC_MODE_VP;
1803
1804 return 0;
1779} 1805}
1780 1806
1781 1807
@@ -1854,19 +1880,19 @@ static u16 dsi_vc_flush_receive_data(int channel)
1854 u32 val; 1880 u32 val;
1855 u8 dt; 1881 u8 dt;
1856 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 1882 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
1857 DSSDBG("\trawval %#08x\n", val); 1883 DSSERR("\trawval %#08x\n", val);
1858 dt = FLD_GET(val, 5, 0); 1884 dt = FLD_GET(val, 5, 0);
1859 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 1885 if (dt == DSI_DT_RX_ACK_WITH_ERR) {
1860 u16 err = FLD_GET(val, 23, 8); 1886 u16 err = FLD_GET(val, 23, 8);
1861 dsi_show_rx_ack_with_err(err); 1887 dsi_show_rx_ack_with_err(err);
1862 } else if (dt == DSI_DT_RX_SHORT_READ_1) { 1888 } else if (dt == DSI_DT_RX_SHORT_READ_1) {
1863 DSSDBG("\tDCS short response, 1 byte: %#x\n", 1889 DSSERR("\tDCS short response, 1 byte: %#x\n",
1864 FLD_GET(val, 23, 8)); 1890 FLD_GET(val, 23, 8));
1865 } else if (dt == DSI_DT_RX_SHORT_READ_2) { 1891 } else if (dt == DSI_DT_RX_SHORT_READ_2) {
1866 DSSDBG("\tDCS short response, 2 byte: %#x\n", 1892 DSSERR("\tDCS short response, 2 byte: %#x\n",
1867 FLD_GET(val, 23, 8)); 1893 FLD_GET(val, 23, 8));
1868 } else if (dt == DSI_DT_RX_DCS_LONG_READ) { 1894 } else if (dt == DSI_DT_RX_DCS_LONG_READ) {
1869 DSSDBG("\tDCS long response, len %d\n", 1895 DSSERR("\tDCS long response, len %d\n",
1870 FLD_GET(val, 23, 8)); 1896 FLD_GET(val, 23, 8));
1871 dsi_vc_flush_long_data(channel); 1897 dsi_vc_flush_long_data(channel);
1872 } else { 1898 } else {
@@ -2087,6 +2113,13 @@ int dsi_vc_dcs_write(int channel, u8 *data, int len)
2087 if (r) 2113 if (r)
2088 goto err; 2114 goto err;
2089 2115
2116 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */
2117 DSSERR("rx fifo not empty after write, dumping data:\n");
2118 dsi_vc_flush_receive_data(channel);
2119 r = -EIO;
2120 goto err;
2121 }
2122
2090 return 0; 2123 return 0;
2091err: 2124err:
2092 DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n", 2125 DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n",
@@ -2233,11 +2266,12 @@ int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
2233} 2266}
2234EXPORT_SYMBOL(dsi_vc_dcs_read_1); 2267EXPORT_SYMBOL(dsi_vc_dcs_read_1);
2235 2268
2236int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data) 2269int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2)
2237{ 2270{
2271 u8 buf[2];
2238 int r; 2272 int r;
2239 2273
2240 r = dsi_vc_dcs_read(channel, dcs_cmd, (u8 *)data, 2); 2274 r = dsi_vc_dcs_read(channel, dcs_cmd, buf, 2);
2241 2275
2242 if (r < 0) 2276 if (r < 0)
2243 return r; 2277 return r;
@@ -2245,231 +2279,122 @@ int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data)
2245 if (r != 2) 2279 if (r != 2)
2246 return -EIO; 2280 return -EIO;
2247 2281
2282 *data1 = buf[0];
2283 *data2 = buf[1];
2284
2248 return 0; 2285 return 0;
2249} 2286}
2250EXPORT_SYMBOL(dsi_vc_dcs_read_2); 2287EXPORT_SYMBOL(dsi_vc_dcs_read_2);
2251 2288
2252int dsi_vc_set_max_rx_packet_size(int channel, u16 len) 2289int dsi_vc_set_max_rx_packet_size(int channel, u16 len)
2253{ 2290{
2254 int r; 2291 return dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
2255 r = dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
2256 len, 0); 2292 len, 0);
2257
2258 if (r)
2259 return r;
2260
2261 r = dsi_vc_send_bta_sync(channel);
2262
2263 return r;
2264} 2293}
2265EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); 2294EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
2266 2295
2267static void dsi_set_lp_rx_timeout(unsigned long ns) 2296static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16)
2268{ 2297{
2269 u32 r;
2270 unsigned x4, x16;
2271 unsigned long fck; 2298 unsigned long fck;
2272 unsigned long ticks; 2299 unsigned long total_ticks;
2300 u32 r;
2273 2301
2274 /* ticks in DSI_FCK */ 2302 BUG_ON(ticks > 0x1fff);
2275 2303
2304 /* ticks in DSI_FCK */
2276 fck = dsi_fclk_rate(); 2305 fck = dsi_fclk_rate();
2277 ticks = (fck / 1000 / 1000) * ns / 1000;
2278 x4 = 0;
2279 x16 = 0;
2280
2281 if (ticks > 0x1fff) {
2282 ticks = (fck / 1000 / 1000) * ns / 1000 / 4;
2283 x4 = 1;
2284 x16 = 0;
2285 }
2286
2287 if (ticks > 0x1fff) {
2288 ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
2289 x4 = 0;
2290 x16 = 1;
2291 }
2292
2293 if (ticks > 0x1fff) {
2294 ticks = (fck / 1000 / 1000) * ns / 1000 / (4 * 16);
2295 x4 = 1;
2296 x16 = 1;
2297 }
2298
2299 if (ticks > 0x1fff) {
2300 DSSWARN("LP_TX_TO over limit, setting it to max\n");
2301 ticks = 0x1fff;
2302 x4 = 1;
2303 x16 = 1;
2304 }
2305 2306
2306 r = dsi_read_reg(DSI_TIMING2); 2307 r = dsi_read_reg(DSI_TIMING2);
2307 r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */ 2308 r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */
2308 r = FLD_MOD(r, x16, 14, 14); /* LP_RX_TO_X16 */ 2309 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* LP_RX_TO_X16 */
2309 r = FLD_MOD(r, x4, 13, 13); /* LP_RX_TO_X4 */ 2310 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* LP_RX_TO_X4 */
2310 r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */ 2311 r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */
2311 dsi_write_reg(DSI_TIMING2, r); 2312 dsi_write_reg(DSI_TIMING2, r);
2312 2313
2313 DSSDBG("LP_RX_TO %lu ns (%#lx ticks%s%s)\n", 2314 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2314 (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) / 2315
2315 (fck / 1000 / 1000), 2316 DSSDBG("LP_RX_TO %lu ticks (%#x%s%s) = %lu ns\n",
2316 ticks, x4 ? " x4" : "", x16 ? " x16" : ""); 2317 total_ticks,
2318 ticks, x4 ? " x4" : "", x16 ? " x16" : "",
2319 (total_ticks * 1000) / (fck / 1000 / 1000));
2317} 2320}
2318 2321
2319static void dsi_set_ta_timeout(unsigned long ns) 2322static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16)
2320{ 2323{
2321 u32 r;
2322 unsigned x8, x16;
2323 unsigned long fck; 2324 unsigned long fck;
2324 unsigned long ticks; 2325 unsigned long total_ticks;
2326 u32 r;
2327
2328 BUG_ON(ticks > 0x1fff);
2325 2329
2326 /* ticks in DSI_FCK */ 2330 /* ticks in DSI_FCK */
2327 fck = dsi_fclk_rate(); 2331 fck = dsi_fclk_rate();
2328 ticks = (fck / 1000 / 1000) * ns / 1000;
2329 x8 = 0;
2330 x16 = 0;
2331
2332 if (ticks > 0x1fff) {
2333 ticks = (fck / 1000 / 1000) * ns / 1000 / 8;
2334 x8 = 1;
2335 x16 = 0;
2336 }
2337
2338 if (ticks > 0x1fff) {
2339 ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
2340 x8 = 0;
2341 x16 = 1;
2342 }
2343
2344 if (ticks > 0x1fff) {
2345 ticks = (fck / 1000 / 1000) * ns / 1000 / (8 * 16);
2346 x8 = 1;
2347 x16 = 1;
2348 }
2349
2350 if (ticks > 0x1fff) {
2351 DSSWARN("TA_TO over limit, setting it to max\n");
2352 ticks = 0x1fff;
2353 x8 = 1;
2354 x16 = 1;
2355 }
2356 2332
2357 r = dsi_read_reg(DSI_TIMING1); 2333 r = dsi_read_reg(DSI_TIMING1);
2358 r = FLD_MOD(r, 1, 31, 31); /* TA_TO */ 2334 r = FLD_MOD(r, 1, 31, 31); /* TA_TO */
2359 r = FLD_MOD(r, x16, 30, 30); /* TA_TO_X16 */ 2335 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */
2360 r = FLD_MOD(r, x8, 29, 29); /* TA_TO_X8 */ 2336 r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */
2361 r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */ 2337 r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */
2362 dsi_write_reg(DSI_TIMING1, r); 2338 dsi_write_reg(DSI_TIMING1, r);
2363 2339
2364 DSSDBG("TA_TO %lu ns (%#lx ticks%s%s)\n", 2340 total_ticks = ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1);
2365 (ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1) * 1000) / 2341
2366 (fck / 1000 / 1000), 2342 DSSDBG("TA_TO %lu ticks (%#x%s%s) = %lu ns\n",
2367 ticks, x8 ? " x8" : "", x16 ? " x16" : ""); 2343 total_ticks,
2344 ticks, x8 ? " x8" : "", x16 ? " x16" : "",
2345 (total_ticks * 1000) / (fck / 1000 / 1000));
2368} 2346}
2369 2347
2370static void dsi_set_stop_state_counter(unsigned long ns) 2348static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16)
2371{ 2349{
2372 u32 r;
2373 unsigned x4, x16;
2374 unsigned long fck; 2350 unsigned long fck;
2375 unsigned long ticks; 2351 unsigned long total_ticks;
2352 u32 r;
2376 2353
2377 /* ticks in DSI_FCK */ 2354 BUG_ON(ticks > 0x1fff);
2378 2355
2356 /* ticks in DSI_FCK */
2379 fck = dsi_fclk_rate(); 2357 fck = dsi_fclk_rate();
2380 ticks = (fck / 1000 / 1000) * ns / 1000;
2381 x4 = 0;
2382 x16 = 0;
2383
2384 if (ticks > 0x1fff) {
2385 ticks = (fck / 1000 / 1000) * ns / 1000 / 4;
2386 x4 = 1;
2387 x16 = 0;
2388 }
2389
2390 if (ticks > 0x1fff) {
2391 ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
2392 x4 = 0;
2393 x16 = 1;
2394 }
2395
2396 if (ticks > 0x1fff) {
2397 ticks = (fck / 1000 / 1000) * ns / 1000 / (4 * 16);
2398 x4 = 1;
2399 x16 = 1;
2400 }
2401
2402 if (ticks > 0x1fff) {
2403 DSSWARN("STOP_STATE_COUNTER_IO over limit, "
2404 "setting it to max\n");
2405 ticks = 0x1fff;
2406 x4 = 1;
2407 x16 = 1;
2408 }
2409 2358
2410 r = dsi_read_reg(DSI_TIMING1); 2359 r = dsi_read_reg(DSI_TIMING1);
2411 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ 2360 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
2412 r = FLD_MOD(r, x16, 14, 14); /* STOP_STATE_X16_IO */ 2361 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* STOP_STATE_X16_IO */
2413 r = FLD_MOD(r, x4, 13, 13); /* STOP_STATE_X4_IO */ 2362 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* STOP_STATE_X4_IO */
2414 r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */ 2363 r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */
2415 dsi_write_reg(DSI_TIMING1, r); 2364 dsi_write_reg(DSI_TIMING1, r);
2416 2365
2417 DSSDBG("STOP_STATE_COUNTER %lu ns (%#lx ticks%s%s)\n", 2366 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2418 (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) / 2367
2419 (fck / 1000 / 1000), 2368 DSSDBG("STOP_STATE_COUNTER %lu ticks (%#x%s%s) = %lu ns\n",
2420 ticks, x4 ? " x4" : "", x16 ? " x16" : ""); 2369 total_ticks,
2370 ticks, x4 ? " x4" : "", x16 ? " x16" : "",
2371 (total_ticks * 1000) / (fck / 1000 / 1000));
2421} 2372}
2422 2373
2423static void dsi_set_hs_tx_timeout(unsigned long ns) 2374static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16)
2424{ 2375{
2425 u32 r;
2426 unsigned x4, x16;
2427 unsigned long fck; 2376 unsigned long fck;
2428 unsigned long ticks; 2377 unsigned long total_ticks;
2378 u32 r;
2429 2379
2430 /* ticks in TxByteClkHS */ 2380 BUG_ON(ticks > 0x1fff);
2431 2381
2382 /* ticks in TxByteClkHS */
2432 fck = dsi_get_txbyteclkhs(); 2383 fck = dsi_get_txbyteclkhs();
2433 ticks = (fck / 1000 / 1000) * ns / 1000;
2434 x4 = 0;
2435 x16 = 0;
2436
2437 if (ticks > 0x1fff) {
2438 ticks = (fck / 1000 / 1000) * ns / 1000 / 4;
2439 x4 = 1;
2440 x16 = 0;
2441 }
2442
2443 if (ticks > 0x1fff) {
2444 ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
2445 x4 = 0;
2446 x16 = 1;
2447 }
2448
2449 if (ticks > 0x1fff) {
2450 ticks = (fck / 1000 / 1000) * ns / 1000 / (4 * 16);
2451 x4 = 1;
2452 x16 = 1;
2453 }
2454
2455 if (ticks > 0x1fff) {
2456 DSSWARN("HS_TX_TO over limit, setting it to max\n");
2457 ticks = 0x1fff;
2458 x4 = 1;
2459 x16 = 1;
2460 }
2461 2384
2462 r = dsi_read_reg(DSI_TIMING2); 2385 r = dsi_read_reg(DSI_TIMING2);
2463 r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */ 2386 r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */
2464 r = FLD_MOD(r, x16, 30, 30); /* HS_TX_TO_X16 */ 2387 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* HS_TX_TO_X16 */
2465 r = FLD_MOD(r, x4, 29, 29); /* HS_TX_TO_X8 (4 really) */ 2388 r = FLD_MOD(r, x4 ? 1 : 0, 29, 29); /* HS_TX_TO_X8 (4 really) */
2466 r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */ 2389 r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */
2467 dsi_write_reg(DSI_TIMING2, r); 2390 dsi_write_reg(DSI_TIMING2, r);
2468 2391
2469 DSSDBG("HS_TX_TO %lu ns (%#lx ticks%s%s)\n", 2392 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2470 (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) / 2393
2471 (fck / 1000 / 1000), 2394 DSSDBG("HS_TX_TO %lu ticks (%#x%s%s) = %lu ns\n",
2472 ticks, x4 ? " x4" : "", x16 ? " x16" : ""); 2395 total_ticks,
2396 ticks, x4 ? " x4" : "", x16 ? " x16" : "",
2397 (total_ticks * 1000) / (fck / 1000 / 1000));
2473} 2398}
2474static int dsi_proto_config(struct omap_dss_device *dssdev) 2399static int dsi_proto_config(struct omap_dss_device *dssdev)
2475{ 2400{
@@ -2487,10 +2412,10 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2487 DSI_FIFO_SIZE_32); 2412 DSI_FIFO_SIZE_32);
2488 2413
2489 /* XXX what values for the timeouts? */ 2414 /* XXX what values for the timeouts? */
2490 dsi_set_stop_state_counter(1000); 2415 dsi_set_stop_state_counter(0x1000, false, false);
2491 dsi_set_ta_timeout(6400000); 2416 dsi_set_ta_timeout(0x1fff, true, true);
2492 dsi_set_lp_rx_timeout(48000); 2417 dsi_set_lp_rx_timeout(0x1fff, true, true);
2493 dsi_set_hs_tx_timeout(1000000); 2418 dsi_set_hs_tx_timeout(0x1fff, true, true);
2494 2419
2495 switch (dssdev->ctrl.pixel_size) { 2420 switch (dssdev->ctrl.pixel_size) {
2496 case 16: 2421 case 16:
@@ -2759,6 +2684,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2759 unsigned packet_payload; 2684 unsigned packet_payload;
2760 unsigned packet_len; 2685 unsigned packet_len;
2761 u32 l; 2686 u32 l;
2687 int r;
2762 const unsigned channel = dsi.update_channel; 2688 const unsigned channel = dsi.update_channel;
2763 /* line buffer is 1024 x 24bits */ 2689 /* line buffer is 1024 x 24bits */
2764 /* XXX: for some reason using full buffer size causes considerable TX 2690 /* XXX: for some reason using full buffer size causes considerable TX
@@ -2809,8 +2735,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2809 2735
2810 dsi_perf_mark_start(); 2736 dsi_perf_mark_start();
2811 2737
2812 schedule_delayed_work(&dsi.framedone_timeout_work, 2738 r = queue_delayed_work(dsi.workqueue, &dsi.framedone_timeout_work,
2813 msecs_to_jiffies(250)); 2739 msecs_to_jiffies(250));
2740 BUG_ON(r == 0);
2814 2741
2815 dss_start_update(dssdev); 2742 dss_start_update(dssdev);
2816 2743
@@ -2834,62 +2761,70 @@ static void dsi_te_timeout(unsigned long arg)
2834} 2761}
2835#endif 2762#endif
2836 2763
2837static void dsi_framedone_timeout_work_callback(struct work_struct *work) 2764static void dsi_handle_framedone(int error)
2838{ 2765{
2839 int r;
2840 const int channel = dsi.update_channel; 2766 const int channel = dsi.update_channel;
2841 2767
2842 DSSERR("Framedone not received for 250ms!\n"); 2768 cancel_delayed_work(&dsi.framedone_timeout_work);
2769
2770 dsi_vc_disable_bta_irq(channel);
2843 2771
2844 /* SIDLEMODE back to smart-idle */ 2772 /* SIDLEMODE back to smart-idle */
2845 dispc_enable_sidle(); 2773 dispc_enable_sidle();
2846 2774
2775 dsi.bta_callback = NULL;
2776
2847 if (dsi.te_enabled) { 2777 if (dsi.te_enabled) {
2848 /* enable LP_RX_TO again after the TE */ 2778 /* enable LP_RX_TO again after the TE */
2849 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 2779 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2850 } 2780 }
2851 2781
2852 /* Send BTA after the frame. We need this for the TE to work, as TE
2853 * trigger is only sent for BTAs without preceding packet. Thus we need
2854 * to BTA after the pixel packets so that next BTA will cause TE
2855 * trigger.
2856 *
2857 * This is not needed when TE is not in use, but we do it anyway to
2858 * make sure that the transfer has been completed. It would be more
2859 * optimal, but more complex, to wait only just before starting next
2860 * transfer. */
2861 r = dsi_vc_send_bta_sync(channel);
2862 if (r)
2863 DSSERR("BTA after framedone failed\n");
2864
2865 /* RX_FIFO_NOT_EMPTY */ 2782 /* RX_FIFO_NOT_EMPTY */
2866 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2783 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
2867 DSSERR("Received error during frame transfer:\n"); 2784 DSSERR("Received error during frame transfer:\n");
2868 dsi_vc_flush_receive_data(channel); 2785 dsi_vc_flush_receive_data(channel);
2786 if (!error)
2787 error = -EIO;
2869 } 2788 }
2870 2789
2871 dsi.framedone_callback(-ETIMEDOUT, dsi.framedone_data); 2790 dsi.framedone_callback(error, dsi.framedone_data);
2791
2792 if (!error)
2793 dsi_perf_show("DISPC");
2872} 2794}
2873 2795
2874static void dsi_framedone_irq_callback(void *data, u32 mask) 2796static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2875{ 2797{
2876 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and 2798 /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after
2877 * turns itself off. However, DSI still has the pixels in its buffers, 2799 * 250ms which would conflict with this timeout work. What should be
2878 * and is sending the data. 2800 * done is first cancel the transfer on the HW, and then cancel the
2879 */ 2801 * possibly scheduled framedone work. However, cancelling the transfer
2802 * on the HW is buggy, and would probably require resetting the whole
2803 * DSI */
2880 2804
2881 /* SIDLEMODE back to smart-idle */ 2805 DSSERR("Framedone not received for 250ms!\n");
2882 dispc_enable_sidle();
2883 2806
2884 schedule_work(&dsi.framedone_work); 2807 dsi_handle_framedone(-ETIMEDOUT);
2885} 2808}
2886 2809
2887static void dsi_handle_framedone(void) 2810static void dsi_framedone_bta_callback(void)
2811{
2812 dsi_handle_framedone(0);
2813
2814#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
2815 dispc_fake_vsync_irq();
2816#endif
2817}
2818
2819static void dsi_framedone_irq_callback(void *data, u32 mask)
2888{ 2820{
2889 int r;
2890 const int channel = dsi.update_channel; 2821 const int channel = dsi.update_channel;
2822 int r;
2891 2823
2892 DSSDBG("FRAMEDONE\n"); 2824 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and
2825 * turns itself off. However, DSI still has the pixels in its buffers,
2826 * and is sending the data.
2827 */
2893 2828
2894 if (dsi.te_enabled) { 2829 if (dsi.te_enabled) {
2895 /* enable LP_RX_TO again after the TE */ 2830 /* enable LP_RX_TO again after the TE */
@@ -2904,37 +2839,30 @@ static void dsi_handle_framedone(void)
2904 * This is not needed when TE is not in use, but we do it anyway to 2839 * This is not needed when TE is not in use, but we do it anyway to
2905 * make sure that the transfer has been completed. It would be more 2840 * make sure that the transfer has been completed. It would be more
2906 * optimal, but more complex, to wait only just before starting next 2841 * optimal, but more complex, to wait only just before starting next
2907 * transfer. */ 2842 * transfer.
2908 r = dsi_vc_send_bta_sync(channel); 2843 *
2909 if (r) 2844 * Also, as there's no interrupt telling when the transfer has been
2910 DSSERR("BTA after framedone failed\n"); 2845 * done and the channel could be reconfigured, the only way is to
2911 2846 * busyloop until TE_SIZE is zero. With BTA we can do this
2912 /* RX_FIFO_NOT_EMPTY */ 2847 * asynchronously.
2913 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2848 * */
2914 DSSERR("Received error during frame transfer:\n");
2915 dsi_vc_flush_receive_data(channel);
2916 }
2917
2918#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
2919 dispc_fake_vsync_irq();
2920#endif
2921}
2922
2923static void dsi_framedone_work_callback(struct work_struct *work)
2924{
2925 DSSDBGF();
2926 2849
2927 cancel_delayed_work_sync(&dsi.framedone_timeout_work); 2850 dsi.bta_callback = dsi_framedone_bta_callback;
2928 2851
2929 dsi_handle_framedone(); 2852 barrier();
2930 2853
2931 dsi_perf_show("DISPC"); 2854 dsi_vc_enable_bta_irq(channel);
2932 2855
2933 dsi.framedone_callback(0, dsi.framedone_data); 2856 r = dsi_vc_send_bta(channel);
2857 if (r) {
2858 DSSERR("BTA after framedone failed\n");
2859 dsi_handle_framedone(-EIO);
2860 }
2934} 2861}
2935 2862
2936int omap_dsi_prepare_update(struct omap_dss_device *dssdev, 2863int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
2937 u16 *x, u16 *y, u16 *w, u16 *h) 2864 u16 *x, u16 *y, u16 *w, u16 *h,
2865 bool enlarge_update_area)
2938{ 2866{
2939 u16 dw, dh; 2867 u16 dw, dh;
2940 2868
@@ -2958,7 +2886,8 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
2958 dsi_perf_mark_setup(); 2886 dsi_perf_mark_setup();
2959 2887
2960 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2961 dss_setup_partial_planes(dssdev, x, y, w, h); 2889 dss_setup_partial_planes(dssdev, x, y, w, h,
2890 enlarge_update_area);
2962 dispc_set_lcd_size(*w, *h); 2891 dispc_set_lcd_size(*w, *h);
2963 } 2892 }
2964 2893
@@ -2973,6 +2902,12 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
2973{ 2902{
2974 dsi.update_channel = channel; 2903 dsi.update_channel = channel;
2975 2904
2905 /* OMAP DSS cannot send updates of odd widths.
2906 * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON
2907 * here to make sure we catch erroneous updates. Otherwise we'll only
2908 * see rather obscure HW error happening, as DSS halts. */
2909 BUG_ON(x % 2 == 1);
2910
2976 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2911 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2977 dsi.framedone_callback = callback; 2912 dsi.framedone_callback = callback;
2978 dsi.framedone_data = data; 2913 dsi.framedone_data = data;
@@ -2985,7 +2920,12 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
2985 2920
2986 dsi_update_screen_dispc(dssdev, x, y, w, h); 2921 dsi_update_screen_dispc(dssdev, x, y, w, h);
2987 } else { 2922 } else {
2988 dsi_update_screen_l4(dssdev, x, y, w, h); 2923 int r;
2924
2925 r = dsi_update_screen_l4(dssdev, x, y, w, h);
2926 if (r)
2927 return r;
2928
2989 dsi_perf_show("L4"); 2929 dsi_perf_show("L4");
2990 callback(0, data); 2930 callback(0, data);
2991 } 2931 }
@@ -3048,8 +2988,10 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
3048 cinfo.regm3 = dssdev->phy.dsi.div.regm3; 2988 cinfo.regm3 = dssdev->phy.dsi.div.regm3;
3049 cinfo.regm4 = dssdev->phy.dsi.div.regm4; 2989 cinfo.regm4 = dssdev->phy.dsi.div.regm4;
3050 r = dsi_calc_clock_rates(&cinfo); 2990 r = dsi_calc_clock_rates(&cinfo);
3051 if (r) 2991 if (r) {
2992 DSSERR("Failed to calc dsi clocks\n");
3052 return r; 2993 return r;
2994 }
3053 2995
3054 r = dsi_pll_set_clock_div(&cinfo); 2996 r = dsi_pll_set_clock_div(&cinfo);
3055 if (r) { 2997 if (r) {
@@ -3147,6 +3089,13 @@ err0:
3147 3089
3148static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) 3090static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3149{ 3091{
3092 /* disable interface */
3093 dsi_if_enable(0);
3094 dsi_vc_enable(0, 0);
3095 dsi_vc_enable(1, 0);
3096 dsi_vc_enable(2, 0);
3097 dsi_vc_enable(3, 0);
3098
3150 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3099 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3151 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3100 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3152 dsi_complexio_uninit(); 3101 dsi_complexio_uninit();
@@ -3257,7 +3206,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
3257 burst_size_bytes = 16 * 32 / 8; 3206 burst_size_bytes = 16 * 32 / 8;
3258 3207
3259 *fifo_high = fifo_size - burst_size_bytes; 3208 *fifo_high = fifo_size - burst_size_bytes;
3260 *fifo_low = fifo_size - burst_size_bytes * 8; 3209 *fifo_low = fifo_size - burst_size_bytes * 2;
3261} 3210}
3262 3211
3263int dsi_init_display(struct omap_dss_device *dssdev) 3212int dsi_init_display(struct omap_dss_device *dssdev)
@@ -3274,6 +3223,18 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3274 return 0; 3223 return 0;
3275} 3224}
3276 3225
3226void dsi_wait_dsi1_pll_active(void)
3227{
3228 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1)
3229 DSSERR("DSI1 PLL clock not active\n");
3230}
3231
3232void dsi_wait_dsi2_pll_active(void)
3233{
3234 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1)
3235 DSSERR("DSI2 PLL clock not active\n");
3236}
3237
3277int dsi_init(struct platform_device *pdev) 3238int dsi_init(struct platform_device *pdev)
3278{ 3239{
3279 u32 rev; 3240 u32 rev;
@@ -3292,7 +3253,10 @@ int dsi_init(struct platform_device *pdev)
3292 mutex_init(&dsi.lock); 3253 mutex_init(&dsi.lock);
3293 sema_init(&dsi.bus_lock, 1); 3254 sema_init(&dsi.bus_lock, 1);
3294 3255
3295 INIT_WORK(&dsi.framedone_work, dsi_framedone_work_callback); 3256 dsi.workqueue = create_singlethread_workqueue("dsi");
3257 if (dsi.workqueue == NULL)
3258 return -ENOMEM;
3259
3296 INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work, 3260 INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work,
3297 dsi_framedone_timeout_work_callback); 3261 dsi_framedone_timeout_work_callback);
3298 3262
@@ -3328,6 +3292,7 @@ int dsi_init(struct platform_device *pdev)
3328err2: 3292err2:
3329 iounmap(dsi.base); 3293 iounmap(dsi.base);
3330err1: 3294err1:
3295 destroy_workqueue(dsi.workqueue);
3331 return r; 3296 return r;
3332} 3297}
3333 3298
@@ -3335,6 +3300,8 @@ void dsi_exit(void)
3335{ 3300{
3336 iounmap(dsi.base); 3301 iounmap(dsi.base);
3337 3302
3303 destroy_workqueue(dsi.workqueue);
3304
3338 DSSDBG("omap_dsi_exit\n"); 3305 DSSDBG("omap_dsi_exit\n");
3339} 3306}
3340 3307
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 24b18258654f..77c3621c9171 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -265,6 +265,9 @@ void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
265 265
266 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; 266 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
267 267
268 if (clk_src == DSS_SRC_DSI1_PLL_FCLK)
269 dsi_wait_dsi1_pll_active();
270
268 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ 271 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */
269 272
270 dss.dispc_clk_source = clk_src; 273 dss.dispc_clk_source = clk_src;
@@ -279,6 +282,9 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
279 282
280 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; 283 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
281 284
285 if (clk_src == DSS_SRC_DSI2_PLL_FCLK)
286 dsi_wait_dsi2_pll_active();
287
282 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ 288 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
283 289
284 dss.dsi_clk_source = clk_src; 290 dss.dsi_clk_source = clk_src;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 786f433fd571..5c7940d5f282 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -199,7 +199,8 @@ int dss_init_overlay_managers(struct platform_device *pdev);
199void dss_uninit_overlay_managers(struct platform_device *pdev); 199void dss_uninit_overlay_managers(struct platform_device *pdev);
200int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); 200int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
201void dss_setup_partial_planes(struct omap_dss_device *dssdev, 201void dss_setup_partial_planes(struct omap_dss_device *dssdev,
202 u16 *x, u16 *y, u16 *w, u16 *h); 202 u16 *x, u16 *y, u16 *w, u16 *h,
203 bool enlarge_update_area);
203void dss_start_update(struct omap_dss_device *dssdev); 204void dss_start_update(struct omap_dss_device *dssdev);
204 205
205/* overlay */ 206/* overlay */
@@ -281,6 +282,8 @@ void dsi_pll_uninit(void);
281void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 282void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
282 u32 fifo_size, enum omap_burst_size *burst_size, 283 u32 fifo_size, enum omap_burst_size *burst_size,
283 u32 *fifo_low, u32 *fifo_high); 284 u32 *fifo_low, u32 *fifo_high);
285void dsi_wait_dsi1_pll_active(void);
286void dsi_wait_dsi2_pll_active(void);
284#else 287#else
285static inline int dsi_init(struct platform_device *pdev) 288static inline int dsi_init(struct platform_device *pdev)
286{ 289{
@@ -289,6 +292,12 @@ static inline int dsi_init(struct platform_device *pdev)
289static inline void dsi_exit(void) 292static inline void dsi_exit(void)
290{ 293{
291} 294}
295static inline void dsi_wait_dsi1_pll_active(void)
296{
297}
298static inline void dsi_wait_dsi2_pll_active(void)
299{
300}
292#endif 301#endif
293 302
294/* DPI */ 303/* DPI */
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 9e1fbe531bf0..6a649ab5539e 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -440,6 +440,10 @@ struct manager_cache_data {
440 440
441 /* manual update region */ 441 /* manual update region */
442 u16 x, y, w, h; 442 u16 x, y, w, h;
443
444 /* enlarge the update area if the update area contains scaled
445 * overlays */
446 bool enlarge_update_area;
443}; 447};
444 448
445static struct { 449static struct {
@@ -525,7 +529,7 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
525 int i; 529 int i;
526 struct omap_dss_device *dssdev = mgr->device; 530 struct omap_dss_device *dssdev = mgr->device;
527 531
528 if (!dssdev) 532 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
529 return 0; 533 return 0;
530 534
531 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 535 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
@@ -596,11 +600,14 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
596 int r; 600 int r;
597 int i; 601 int i;
598 602
599 if (!ovl->manager || !ovl->manager->device) 603 if (!ovl->manager)
600 return 0; 604 return 0;
601 605
602 dssdev = ovl->manager->device; 606 dssdev = ovl->manager->device;
603 607
608 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
609 return 0;
610
604 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 611 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
605 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 612 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
606 channel = OMAP_DSS_CHANNEL_DIGIT; 613 channel = OMAP_DSS_CHANNEL_DIGIT;
@@ -718,6 +725,7 @@ static int configure_overlay(enum omap_plane plane)
718 u16 x, y, w, h; 725 u16 x, y, w, h;
719 u32 paddr; 726 u32 paddr;
720 int r; 727 int r;
728 u16 orig_w, orig_h, orig_outw, orig_outh;
721 729
722 DSSDBGF("%d", plane); 730 DSSDBGF("%d", plane);
723 731
@@ -738,8 +746,16 @@ static int configure_overlay(enum omap_plane plane)
738 outh = c->out_height == 0 ? c->height : c->out_height; 746 outh = c->out_height == 0 ? c->height : c->out_height;
739 paddr = c->paddr; 747 paddr = c->paddr;
740 748
749 orig_w = w;
750 orig_h = h;
751 orig_outw = outw;
752 orig_outh = outh;
753
741 if (c->manual_update && mc->do_manual_update) { 754 if (c->manual_update && mc->do_manual_update) {
742 unsigned bpp; 755 unsigned bpp;
756 unsigned scale_x_m = w, scale_x_d = outw;
757 unsigned scale_y_m = h, scale_y_d = outh;
758
743 /* If the overlay is outside the update region, disable it */ 759 /* If the overlay is outside the update region, disable it */
744 if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h, 760 if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h,
745 x, y, outw, outh)) { 761 x, y, outw, outh)) {
@@ -770,38 +786,47 @@ static int configure_overlay(enum omap_plane plane)
770 BUG(); 786 BUG();
771 } 787 }
772 788
773 if (dispc_is_overlay_scaled(c)) { 789 if (mc->x > c->pos_x) {
774 /* If the overlay is scaled, the update area has 790 x = 0;
775 * already been enlarged to cover the whole overlay. We 791 outw -= (mc->x - c->pos_x);
776 * only need to adjust x/y here */ 792 paddr += (mc->x - c->pos_x) *
777 x = c->pos_x - mc->x; 793 scale_x_m / scale_x_d * bpp / 8;
778 y = c->pos_y - mc->y;
779 } else { 794 } else {
780 if (mc->x > c->pos_x) { 795 x = c->pos_x - mc->x;
781 x = 0; 796 }
782 w -= (mc->x - c->pos_x);
783 paddr += (mc->x - c->pos_x) * bpp / 8;
784 } else {
785 x = c->pos_x - mc->x;
786 }
787
788 if (mc->y > c->pos_y) {
789 y = 0;
790 h -= (mc->y - c->pos_y);
791 paddr += (mc->y - c->pos_y) * c->screen_width *
792 bpp / 8;
793 } else {
794 y = c->pos_y - mc->y;
795 }
796
797 if (mc->w < (x+w))
798 w -= (x+w) - (mc->w);
799 797
800 if (mc->h < (y+h)) 798 if (mc->y > c->pos_y) {
801 h -= (y+h) - (mc->h); 799 y = 0;
800 outh -= (mc->y - c->pos_y);
801 paddr += (mc->y - c->pos_y) *
802 scale_y_m / scale_y_d *
803 c->screen_width * bpp / 8;
804 } else {
805 y = c->pos_y - mc->y;
806 }
802 807
803 outw = w; 808 if (mc->w < (x + outw))
804 outh = h; 809 outw -= (x + outw) - (mc->w);
810
811 if (mc->h < (y + outh))
812 outh -= (y + outh) - (mc->h);
813
814 w = w * outw / orig_outw;
815 h = h * outh / orig_outh;
816
817 /* YUV mode overlay's input width has to be even and the
818 * algorithm above may adjust the width to be odd.
819 *
820 * Here we adjust the width if needed, preferring to increase
821 * the width if the original width was bigger.
822 */
823 if ((w & 1) &&
824 (c->color_mode == OMAP_DSS_COLOR_YUV2 ||
825 c->color_mode == OMAP_DSS_COLOR_UYVY)) {
826 if (orig_w > w)
827 w += 1;
828 else
829 w -= 1;
805 } 830 }
806 } 831 }
807 832
@@ -960,7 +985,7 @@ static void make_even(u16 *x, u16 *w)
960/* Configure dispc for partial update. Return possibly modified update 985/* Configure dispc for partial update. Return possibly modified update
961 * area */ 986 * area */
962void dss_setup_partial_planes(struct omap_dss_device *dssdev, 987void dss_setup_partial_planes(struct omap_dss_device *dssdev,
963 u16 *xi, u16 *yi, u16 *wi, u16 *hi) 988 u16 *xi, u16 *yi, u16 *wi, u16 *hi, bool enlarge_update_area)
964{ 989{
965 struct overlay_cache_data *oc; 990 struct overlay_cache_data *oc;
966 struct manager_cache_data *mc; 991 struct manager_cache_data *mc;
@@ -969,6 +994,7 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
969 int i; 994 int i;
970 u16 x, y, w, h; 995 u16 x, y, w, h;
971 unsigned long flags; 996 unsigned long flags;
997 bool area_changed;
972 998
973 x = *xi; 999 x = *xi;
974 y = *yi; 1000 y = *yi;
@@ -989,73 +1015,91 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
989 1015
990 spin_lock_irqsave(&dss_cache.lock, flags); 1016 spin_lock_irqsave(&dss_cache.lock, flags);
991 1017
992 /* We need to show the whole overlay if it is scaled. So look for 1018 /*
993 * those, and make the update area larger if found. 1019 * Execute the outer loop until the inner loop has completed
994 * Also mark the overlay cache dirty */ 1020 * once without increasing the update area. This will ensure that
995 for (i = 0; i < num_ovls; ++i) { 1021 * all scaled overlays end up completely within the update area.
996 unsigned x1, y1, x2, y2; 1022 */
997 unsigned outw, outh; 1023 do {
1024 area_changed = false;
998 1025
999 oc = &dss_cache.overlay_cache[i]; 1026 /* We need to show the whole overlay if it is scaled. So look
1027 * for those, and make the update area larger if found.
1028 * Also mark the overlay cache dirty */
1029 for (i = 0; i < num_ovls; ++i) {
1030 unsigned x1, y1, x2, y2;
1031 unsigned outw, outh;
1000 1032
1001 if (oc->channel != mgr->id) 1033 oc = &dss_cache.overlay_cache[i];
1002 continue;
1003 1034
1004 oc->dirty = true; 1035 if (oc->channel != mgr->id)
1036 continue;
1005 1037
1006 if (!oc->enabled) 1038 oc->dirty = true;
1007 continue;
1008 1039
1009 if (!dispc_is_overlay_scaled(oc)) 1040 if (!enlarge_update_area)
1010 continue; 1041 continue;
1011 1042
1012 outw = oc->out_width == 0 ? oc->width : oc->out_width; 1043 if (!oc->enabled)
1013 outh = oc->out_height == 0 ? oc->height : oc->out_height; 1044 continue;
1014 1045
1015 /* is the overlay outside the update region? */ 1046 if (!dispc_is_overlay_scaled(oc))
1016 if (!rectangle_intersects(x, y, w, h, 1047 continue;
1017 oc->pos_x, oc->pos_y,
1018 outw, outh))
1019 continue;
1020 1048
1021 /* if the overlay totally inside the update region? */ 1049 outw = oc->out_width == 0 ?
1022 if (rectangle_subset(oc->pos_x, oc->pos_y, outw, outh, 1050 oc->width : oc->out_width;
1023 x, y, w, h)) 1051 outh = oc->out_height == 0 ?
1024 continue; 1052 oc->height : oc->out_height;
1053
1054 /* is the overlay outside the update region? */
1055 if (!rectangle_intersects(x, y, w, h,
1056 oc->pos_x, oc->pos_y,
1057 outw, outh))
1058 continue;
1025 1059
1026 if (x > oc->pos_x) 1060 /* if the overlay totally inside the update region? */
1027 x1 = oc->pos_x; 1061 if (rectangle_subset(oc->pos_x, oc->pos_y, outw, outh,
1028 else 1062 x, y, w, h))
1029 x1 = x; 1063 continue;
1030 1064
1031 if (y > oc->pos_y) 1065 if (x > oc->pos_x)
1032 y1 = oc->pos_y; 1066 x1 = oc->pos_x;
1033 else 1067 else
1034 y1 = y; 1068 x1 = x;
1035 1069
1036 if ((x + w) < (oc->pos_x + outw)) 1070 if (y > oc->pos_y)
1037 x2 = oc->pos_x + outw; 1071 y1 = oc->pos_y;
1038 else 1072 else
1039 x2 = x + w; 1073 y1 = y;
1040 1074
1041 if ((y + h) < (oc->pos_y + outh)) 1075 if ((x + w) < (oc->pos_x + outw))
1042 y2 = oc->pos_y + outh; 1076 x2 = oc->pos_x + outw;
1043 else 1077 else
1044 y2 = y + h; 1078 x2 = x + w;
1045 1079
1046 x = x1; 1080 if ((y + h) < (oc->pos_y + outh))
1047 y = y1; 1081 y2 = oc->pos_y + outh;
1048 w = x2 - x1; 1082 else
1049 h = y2 - y1; 1083 y2 = y + h;
1050 1084
1051 make_even(&x, &w); 1085 x = x1;
1086 y = y1;
1087 w = x2 - x1;
1088 h = y2 - y1;
1052 1089
1053 DSSDBG("changing upd area due to ovl(%d) scaling %d,%d %dx%d\n", 1090 make_even(&x, &w);
1091
1092 DSSDBG("changing upd area due to ovl(%d) "
1093 "scaling %d,%d %dx%d\n",
1054 i, x, y, w, h); 1094 i, x, y, w, h);
1055 } 1095
1096 area_changed = true;
1097 }
1098 } while (area_changed);
1056 1099
1057 mc = &dss_cache.manager_cache[mgr->id]; 1100 mc = &dss_cache.manager_cache[mgr->id];
1058 mc->do_manual_update = true; 1101 mc->do_manual_update = true;
1102 mc->enlarge_update_area = enlarge_update_area;
1059 mc->x = x; 1103 mc->x = x;
1060 mc->y = y; 1104 mc->y = y;
1061 mc->w = w; 1105 mc->w = w;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 82336583adef..244dca81a399 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -65,7 +65,7 @@ static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
65 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { 65 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
66 mgr = omap_dss_get_overlay_manager(i); 66 mgr = omap_dss_get_overlay_manager(i);
67 67
68 if (strncmp(buf, mgr->name, len) == 0) 68 if (sysfs_streq(buf, mgr->name))
69 break; 69 break;
70 70
71 mgr = NULL; 71 mgr = NULL;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index cc23f53cc62d..bbe62464e92d 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -886,7 +886,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
886 return -EINVAL; 886 return -EINVAL;
887 887
888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
889 dss_setup_partial_planes(dssdev, x, y, w, h); 889 dss_setup_partial_planes(dssdev, x, y, w, h, true);
890 dispc_set_lcd_size(*w, *h); 890 dispc_set_lcd_size(*w, *h);
891 } 891 }
892 892
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 9c7361871d78..6f435450987e 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -34,12 +34,37 @@
34 34
35#include "omapfb.h" 35#include "omapfb.h"
36 36
37static u8 get_mem_idx(struct omapfb_info *ofbi)
38{
39 if (ofbi->id == ofbi->region->id)
40 return 0;
41
42 return OMAPFB_MEM_IDX_ENABLED | ofbi->region->id;
43}
44
45static struct omapfb2_mem_region *get_mem_region(struct omapfb_info *ofbi,
46 u8 mem_idx)
47{
48 struct omapfb2_device *fbdev = ofbi->fbdev;
49
50 if (mem_idx & OMAPFB_MEM_IDX_ENABLED)
51 mem_idx &= OMAPFB_MEM_IDX_MASK;
52 else
53 mem_idx = ofbi->id;
54
55 if (mem_idx >= fbdev->num_fbs)
56 return NULL;
57
58 return &fbdev->regions[mem_idx];
59}
60
37static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) 61static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
38{ 62{
39 struct omapfb_info *ofbi = FB2OFB(fbi); 63 struct omapfb_info *ofbi = FB2OFB(fbi);
40 struct omapfb2_device *fbdev = ofbi->fbdev; 64 struct omapfb2_device *fbdev = ofbi->fbdev;
41 struct omap_overlay *ovl; 65 struct omap_overlay *ovl;
42 struct omap_overlay_info info; 66 struct omap_overlay_info old_info;
67 struct omapfb2_mem_region *old_rg, *new_rg;
43 int r = 0; 68 int r = 0;
44 69
45 DBG("omapfb_setup_plane\n"); 70 DBG("omapfb_setup_plane\n");
@@ -52,36 +77,106 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
52 /* XXX uses only the first overlay */ 77 /* XXX uses only the first overlay */
53 ovl = ofbi->overlays[0]; 78 ovl = ofbi->overlays[0];
54 79
55 if (pi->enabled && !ofbi->region.size) { 80 old_rg = ofbi->region;
81 new_rg = get_mem_region(ofbi, pi->mem_idx);
82 if (!new_rg) {
83 r = -EINVAL;
84 goto out;
85 }
86
87 /* Take the locks in a specific order to keep lockdep happy */
88 if (old_rg->id < new_rg->id) {
89 omapfb_get_mem_region(old_rg);
90 omapfb_get_mem_region(new_rg);
91 } else if (new_rg->id < old_rg->id) {
92 omapfb_get_mem_region(new_rg);
93 omapfb_get_mem_region(old_rg);
94 } else
95 omapfb_get_mem_region(old_rg);
96
97 if (pi->enabled && !new_rg->size) {
56 /* 98 /*
57 * This plane's memory was freed, can't enable it 99 * This plane's memory was freed, can't enable it
58 * until it's reallocated. 100 * until it's reallocated.
59 */ 101 */
60 r = -EINVAL; 102 r = -EINVAL;
61 goto out; 103 goto put_mem;
62 } 104 }
63 105
64 ovl->get_overlay_info(ovl, &info); 106 ovl->get_overlay_info(ovl, &old_info);
65 107
66 info.pos_x = pi->pos_x; 108 if (old_rg != new_rg) {
67 info.pos_y = pi->pos_y; 109 ofbi->region = new_rg;
68 info.out_width = pi->out_width; 110 set_fb_fix(fbi);
69 info.out_height = pi->out_height; 111 }
70 info.enabled = pi->enabled;
71 112
72 r = ovl->set_overlay_info(ovl, &info); 113 if (pi->enabled) {
73 if (r) 114 struct omap_overlay_info info;
74 goto out;
75 115
76 if (ovl->manager) { 116 r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
77 r = ovl->manager->apply(ovl->manager); 117 pi->out_width, pi->out_height);
78 if (r) 118 if (r)
79 goto out; 119 goto undo;
120
121 ovl->get_overlay_info(ovl, &info);
122
123 if (!info.enabled) {
124 info.enabled = pi->enabled;
125 r = ovl->set_overlay_info(ovl, &info);
126 if (r)
127 goto undo;
128 }
129 } else {
130 struct omap_overlay_info info;
131
132 ovl->get_overlay_info(ovl, &info);
133
134 info.enabled = pi->enabled;
135 info.pos_x = pi->pos_x;
136 info.pos_y = pi->pos_y;
137 info.out_width = pi->out_width;
138 info.out_height = pi->out_height;
139
140 r = ovl->set_overlay_info(ovl, &info);
141 if (r)
142 goto undo;
80 } 143 }
81 144
82out: 145 if (ovl->manager)
83 if (r) 146 ovl->manager->apply(ovl->manager);
84 dev_err(fbdev->dev, "setup_plane failed\n"); 147
148 /* Release the locks in a specific order to keep lockdep happy */
149 if (old_rg->id > new_rg->id) {
150 omapfb_put_mem_region(old_rg);
151 omapfb_put_mem_region(new_rg);
152 } else if (new_rg->id > old_rg->id) {
153 omapfb_put_mem_region(new_rg);
154 omapfb_put_mem_region(old_rg);
155 } else
156 omapfb_put_mem_region(old_rg);
157
158 return 0;
159
160 undo:
161 if (old_rg != new_rg) {
162 ofbi->region = old_rg;
163 set_fb_fix(fbi);
164 }
165
166 ovl->set_overlay_info(ovl, &old_info);
167 put_mem:
168 /* Release the locks in a specific order to keep lockdep happy */
169 if (old_rg->id > new_rg->id) {
170 omapfb_put_mem_region(old_rg);
171 omapfb_put_mem_region(new_rg);
172 } else if (new_rg->id > old_rg->id) {
173 omapfb_put_mem_region(new_rg);
174 omapfb_put_mem_region(old_rg);
175 } else
176 omapfb_put_mem_region(old_rg);
177 out:
178 dev_err(fbdev->dev, "setup_plane failed\n");
179
85 return r; 180 return r;
86} 181}
87 182
@@ -92,8 +187,8 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
92 if (ofbi->num_overlays != 1) { 187 if (ofbi->num_overlays != 1) {
93 memset(pi, 0, sizeof(*pi)); 188 memset(pi, 0, sizeof(*pi));
94 } else { 189 } else {
95 struct omap_overlay_info *ovli;
96 struct omap_overlay *ovl; 190 struct omap_overlay *ovl;
191 struct omap_overlay_info *ovli;
97 192
98 ovl = ofbi->overlays[0]; 193 ovl = ofbi->overlays[0];
99 ovli = &ovl->info; 194 ovli = &ovl->info;
@@ -103,6 +198,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
103 pi->enabled = ovli->enabled; 198 pi->enabled = ovli->enabled;
104 pi->channel_out = 0; /* xxx */ 199 pi->channel_out = 0; /* xxx */
105 pi->mirror = 0; 200 pi->mirror = 0;
201 pi->mem_idx = get_mem_idx(ofbi);
106 pi->out_width = ovli->out_width; 202 pi->out_width = ovli->out_width;
107 pi->out_height = ovli->out_height; 203 pi->out_height = ovli->out_height;
108 } 204 }
@@ -115,7 +211,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
115 struct omapfb_info *ofbi = FB2OFB(fbi); 211 struct omapfb_info *ofbi = FB2OFB(fbi);
116 struct omapfb2_device *fbdev = ofbi->fbdev; 212 struct omapfb2_device *fbdev = ofbi->fbdev;
117 struct omapfb2_mem_region *rg; 213 struct omapfb2_mem_region *rg;
118 int r, i; 214 int r = 0, i;
119 size_t size; 215 size_t size;
120 216
121 if (mi->type > OMAPFB_MEMTYPE_MAX) 217 if (mi->type > OMAPFB_MEMTYPE_MAX)
@@ -123,22 +219,44 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
123 219
124 size = PAGE_ALIGN(mi->size); 220 size = PAGE_ALIGN(mi->size);
125 221
126 rg = &ofbi->region; 222 rg = ofbi->region;
127 223
128 for (i = 0; i < ofbi->num_overlays; i++) { 224 down_write_nested(&rg->lock, rg->id);
129 if (ofbi->overlays[i]->info.enabled) 225 atomic_inc(&rg->lock_count);
130 return -EBUSY; 226
227 if (atomic_read(&rg->map_count)) {
228 r = -EBUSY;
229 goto out;
230 }
231
232 for (i = 0; i < fbdev->num_fbs; i++) {
233 struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
234 int j;
235
236 if (ofbi2->region != rg)
237 continue;
238
239 for (j = 0; j < ofbi2->num_overlays; j++) {
240 if (ofbi2->overlays[j]->info.enabled) {
241 r = -EBUSY;
242 goto out;
243 }
244 }
131 } 245 }
132 246
133 if (rg->size != size || rg->type != mi->type) { 247 if (rg->size != size || rg->type != mi->type) {
134 r = omapfb_realloc_fbmem(fbi, size, mi->type); 248 r = omapfb_realloc_fbmem(fbi, size, mi->type);
135 if (r) { 249 if (r) {
136 dev_err(fbdev->dev, "realloc fbmem failed\n"); 250 dev_err(fbdev->dev, "realloc fbmem failed\n");
137 return r; 251 goto out;
138 } 252 }
139 } 253 }
140 254
141 return 0; 255 out:
256 atomic_dec(&rg->lock_count);
257 up_write(&rg->lock);
258
259 return r;
142} 260}
143 261
144static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) 262static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
@@ -146,12 +264,14 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
146 struct omapfb_info *ofbi = FB2OFB(fbi); 264 struct omapfb_info *ofbi = FB2OFB(fbi);
147 struct omapfb2_mem_region *rg; 265 struct omapfb2_mem_region *rg;
148 266
149 rg = &ofbi->region; 267 rg = omapfb_get_mem_region(ofbi->region);
150 memset(mi, 0, sizeof(*mi)); 268 memset(mi, 0, sizeof(*mi));
151 269
152 mi->size = rg->size; 270 mi->size = rg->size;
153 mi->type = rg->type; 271 mi->type = rg->type;
154 272
273 omapfb_put_mem_region(rg);
274
155 return 0; 275 return 0;
156} 276}
157 277
@@ -490,6 +610,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
490 struct omapfb_vram_info vram_info; 610 struct omapfb_vram_info vram_info;
491 struct omapfb_tearsync_info tearsync_info; 611 struct omapfb_tearsync_info tearsync_info;
492 struct omapfb_display_info display_info; 612 struct omapfb_display_info display_info;
613 u32 crt;
493 } p; 614 } p;
494 615
495 int r = 0; 616 int r = 0;
@@ -648,6 +769,17 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
648 r = -EFAULT; 769 r = -EFAULT;
649 break; 770 break;
650 771
772 case FBIO_WAITFORVSYNC:
773 if (get_user(p.crt, (__u32 __user *)arg)) {
774 r = -EFAULT;
775 break;
776 }
777 if (p.crt != 0) {
778 r = -ENODEV;
779 break;
780 }
781 /* FALLTHROUGH */
782
651 case OMAPFB_WAITFORVSYNC: 783 case OMAPFB_WAITFORVSYNC:
652 DBG("ioctl WAITFORVSYNC\n"); 784 DBG("ioctl WAITFORVSYNC\n");
653 if (!display) { 785 if (!display) {
@@ -738,7 +870,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
738 break; 870 break;
739 } 871 }
740 872
741 if (!display->driver->enable_te) { 873 if (!display || !display->driver->enable_te) {
742 r = -ENODEV; 874 r = -ENODEV;
743 break; 875 break;
744 } 876 }
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 4b4506da96da..04034d410d6d 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -157,7 +157,7 @@ static void fill_fb(struct fb_info *fbi)
157 157
158static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot) 158static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
159{ 159{
160 const struct vrfb *vrfb = &ofbi->region.vrfb; 160 const struct vrfb *vrfb = &ofbi->region->vrfb;
161 unsigned offset; 161 unsigned offset;
162 162
163 switch (rot) { 163 switch (rot) {
@@ -185,27 +185,27 @@ static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
185static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot) 185static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
186{ 186{
187 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 187 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
188 return ofbi->region.vrfb.paddr[rot] 188 return ofbi->region->vrfb.paddr[rot]
189 + omapfb_get_vrfb_offset(ofbi, rot); 189 + omapfb_get_vrfb_offset(ofbi, rot);
190 } else { 190 } else {
191 return ofbi->region.paddr; 191 return ofbi->region->paddr;
192 } 192 }
193} 193}
194 194
195static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi) 195static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
196{ 196{
197 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 197 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
198 return ofbi->region.vrfb.paddr[0]; 198 return ofbi->region->vrfb.paddr[0];
199 else 199 else
200 return ofbi->region.paddr; 200 return ofbi->region->paddr;
201} 201}
202 202
203static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi) 203static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
204{ 204{
205 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 205 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
206 return ofbi->region.vrfb.vaddr[0]; 206 return ofbi->region->vrfb.vaddr[0];
207 else 207 else
208 return ofbi->region.vaddr; 208 return ofbi->region->vaddr;
209} 209}
210 210
211static struct omapfb_colormode omapfb_colormodes[] = { 211static struct omapfb_colormode omapfb_colormodes[] = {
@@ -450,7 +450,7 @@ static int check_vrfb_fb_size(unsigned long region_size,
450static int check_fb_size(const struct omapfb_info *ofbi, 450static int check_fb_size(const struct omapfb_info *ofbi,
451 struct fb_var_screeninfo *var) 451 struct fb_var_screeninfo *var)
452{ 452{
453 unsigned long max_frame_size = ofbi->region.size; 453 unsigned long max_frame_size = ofbi->region->size;
454 int bytespp = var->bits_per_pixel >> 3; 454 int bytespp = var->bits_per_pixel >> 3;
455 unsigned long line_size = var->xres_virtual * bytespp; 455 unsigned long line_size = var->xres_virtual * bytespp;
456 456
@@ -497,7 +497,7 @@ static int check_fb_size(const struct omapfb_info *ofbi,
497static int setup_vrfb_rotation(struct fb_info *fbi) 497static int setup_vrfb_rotation(struct fb_info *fbi)
498{ 498{
499 struct omapfb_info *ofbi = FB2OFB(fbi); 499 struct omapfb_info *ofbi = FB2OFB(fbi);
500 struct omapfb2_mem_region *rg = &ofbi->region; 500 struct omapfb2_mem_region *rg = ofbi->region;
501 struct vrfb *vrfb = &rg->vrfb; 501 struct vrfb *vrfb = &rg->vrfb;
502 struct fb_var_screeninfo *var = &fbi->var; 502 struct fb_var_screeninfo *var = &fbi->var;
503 struct fb_fix_screeninfo *fix = &fbi->fix; 503 struct fb_fix_screeninfo *fix = &fbi->fix;
@@ -558,9 +558,9 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
558 return r; 558 return r;
559 559
560 /* used by open/write in fbmem.c */ 560 /* used by open/write in fbmem.c */
561 fbi->screen_base = ofbi->region.vrfb.vaddr[0]; 561 fbi->screen_base = ofbi->region->vrfb.vaddr[0];
562 562
563 fix->smem_start = ofbi->region.vrfb.paddr[0]; 563 fix->smem_start = ofbi->region->vrfb.paddr[0];
564 564
565 switch (var->nonstd) { 565 switch (var->nonstd) {
566 case OMAPFB_COLOR_YUV422: 566 case OMAPFB_COLOR_YUV422:
@@ -599,7 +599,7 @@ void set_fb_fix(struct fb_info *fbi)
599 struct fb_fix_screeninfo *fix = &fbi->fix; 599 struct fb_fix_screeninfo *fix = &fbi->fix;
600 struct fb_var_screeninfo *var = &fbi->var; 600 struct fb_var_screeninfo *var = &fbi->var;
601 struct omapfb_info *ofbi = FB2OFB(fbi); 601 struct omapfb_info *ofbi = FB2OFB(fbi);
602 struct omapfb2_mem_region *rg = &ofbi->region; 602 struct omapfb2_mem_region *rg = ofbi->region;
603 603
604 DBG("set_fb_fix\n"); 604 DBG("set_fb_fix\n");
605 605
@@ -668,8 +668,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
668 668
669 DBG("check_fb_var %d\n", ofbi->id); 669 DBG("check_fb_var %d\n", ofbi->id);
670 670
671 if (ofbi->region.size == 0) 671 WARN_ON(!atomic_read(&ofbi->region->lock_count));
672 return 0;
673 672
674 r = fb_mode_to_dss_mode(var, &mode); 673 r = fb_mode_to_dss_mode(var, &mode);
675 if (r) { 674 if (r) {
@@ -684,13 +683,14 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
684 } 683 }
685 } 684 }
686 685
687 if (var->rotate < 0 || var->rotate > 3) 686 if (var->rotate > 3)
688 return -EINVAL; 687 return -EINVAL;
689 688
690 if (check_fb_res_bounds(var)) 689 if (check_fb_res_bounds(var))
691 return -EINVAL; 690 return -EINVAL;
692 691
693 if (check_fb_size(ofbi, var)) 692 /* When no memory is allocated ignore the size check */
693 if (ofbi->region->size != 0 && check_fb_size(ofbi, var))
694 return -EINVAL; 694 return -EINVAL;
695 695
696 if (var->xres + var->xoffset > var->xres_virtual) 696 if (var->xres + var->xoffset > var->xres_virtual)
@@ -822,9 +822,43 @@ static unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var,
822 return offset; 822 return offset;
823} 823}
824 824
825static void omapfb_calc_addr(const struct omapfb_info *ofbi,
826 const struct fb_var_screeninfo *var,
827 const struct fb_fix_screeninfo *fix,
828 int rotation, u32 *paddr, void __iomem **vaddr)
829{
830 u32 data_start_p;
831 void __iomem *data_start_v;
832 int offset;
833
834 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
835 data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation);
836 data_start_v = NULL;
837 } else {
838 data_start_p = omapfb_get_region_paddr(ofbi);
839 data_start_v = omapfb_get_region_vaddr(ofbi);
840 }
841
842 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
843 offset = calc_rotation_offset_vrfb(var, fix, rotation);
844 else
845 offset = calc_rotation_offset_dma(var, fix, rotation);
846
847 data_start_p += offset;
848 data_start_v += offset;
849
850 if (offset)
851 DBG("offset %d, %d = %d\n",
852 var->xoffset, var->yoffset, offset);
853
854 DBG("paddr %x, vaddr %p\n", data_start_p, data_start_v);
855
856 *paddr = data_start_p;
857 *vaddr = data_start_v;
858}
825 859
826/* setup overlay according to the fb */ 860/* setup overlay according to the fb */
827static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, 861int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
828 u16 posx, u16 posy, u16 outw, u16 outh) 862 u16 posx, u16 posy, u16 outw, u16 outh)
829{ 863{
830 int r = 0; 864 int r = 0;
@@ -832,9 +866,8 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
832 struct fb_var_screeninfo *var = &fbi->var; 866 struct fb_var_screeninfo *var = &fbi->var;
833 struct fb_fix_screeninfo *fix = &fbi->fix; 867 struct fb_fix_screeninfo *fix = &fbi->fix;
834 enum omap_color_mode mode = 0; 868 enum omap_color_mode mode = 0;
835 int offset; 869 u32 data_start_p = 0;
836 u32 data_start_p; 870 void __iomem *data_start_v = NULL;
837 void __iomem *data_start_v;
838 struct omap_overlay_info info; 871 struct omap_overlay_info info;
839 int xres, yres; 872 int xres, yres;
840 int screen_width; 873 int screen_width;
@@ -842,6 +875,8 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
842 int rotation = var->rotate; 875 int rotation = var->rotate;
843 int i; 876 int i;
844 877
878 WARN_ON(!atomic_read(&ofbi->region->lock_count));
879
845 for (i = 0; i < ofbi->num_overlays; i++) { 880 for (i = 0; i < ofbi->num_overlays; i++) {
846 if (ovl != ofbi->overlays[i]) 881 if (ovl != ofbi->overlays[i])
847 continue; 882 continue;
@@ -861,28 +896,9 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
861 yres = var->yres; 896 yres = var->yres;
862 } 897 }
863 898
864 899 if (ofbi->region->size)
865 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 900 omapfb_calc_addr(ofbi, var, fix, rotation,
866 data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation); 901 &data_start_p, &data_start_v);
867 data_start_v = NULL;
868 } else {
869 data_start_p = omapfb_get_region_paddr(ofbi);
870 data_start_v = omapfb_get_region_vaddr(ofbi);
871 }
872
873 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
874 offset = calc_rotation_offset_vrfb(var, fix, rotation);
875 else
876 offset = calc_rotation_offset_dma(var, fix, rotation);
877
878 data_start_p += offset;
879 data_start_v += offset;
880
881 if (offset)
882 DBG("offset %d, %d = %d\n",
883 var->xoffset, var->yoffset, offset);
884
885 DBG("paddr %x, vaddr %p\n", data_start_p, data_start_v);
886 902
887 r = fb_mode_to_dss_mode(var, &mode); 903 r = fb_mode_to_dss_mode(var, &mode);
888 if (r) { 904 if (r) {
@@ -954,12 +970,14 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
954 fill_fb(fbi); 970 fill_fb(fbi);
955#endif 971#endif
956 972
973 WARN_ON(!atomic_read(&ofbi->region->lock_count));
974
957 for (i = 0; i < ofbi->num_overlays; i++) { 975 for (i = 0; i < ofbi->num_overlays; i++) {
958 ovl = ofbi->overlays[i]; 976 ovl = ofbi->overlays[i];
959 977
960 DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id); 978 DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id);
961 979
962 if (ofbi->region.size == 0) { 980 if (ofbi->region->size == 0) {
963 /* the fb is not available. disable the overlay */ 981 /* the fb is not available. disable the overlay */
964 omapfb_overlay_enable(ovl, 0); 982 omapfb_overlay_enable(ovl, 0);
965 if (!init && ovl->manager) 983 if (!init && ovl->manager)
@@ -1007,36 +1025,48 @@ err:
1007 * DO NOT MODIFY PAR */ 1025 * DO NOT MODIFY PAR */
1008static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) 1026static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
1009{ 1027{
1028 struct omapfb_info *ofbi = FB2OFB(fbi);
1010 int r; 1029 int r;
1011 1030
1012 DBG("check_var(%d)\n", FB2OFB(fbi)->id); 1031 DBG("check_var(%d)\n", FB2OFB(fbi)->id);
1013 1032
1033 omapfb_get_mem_region(ofbi->region);
1034
1014 r = check_fb_var(fbi, var); 1035 r = check_fb_var(fbi, var);
1015 1036
1037 omapfb_put_mem_region(ofbi->region);
1038
1016 return r; 1039 return r;
1017} 1040}
1018 1041
1019/* set the video mode according to info->var */ 1042/* set the video mode according to info->var */
1020static int omapfb_set_par(struct fb_info *fbi) 1043static int omapfb_set_par(struct fb_info *fbi)
1021{ 1044{
1045 struct omapfb_info *ofbi = FB2OFB(fbi);
1022 int r; 1046 int r;
1023 1047
1024 DBG("set_par(%d)\n", FB2OFB(fbi)->id); 1048 DBG("set_par(%d)\n", FB2OFB(fbi)->id);
1025 1049
1050 omapfb_get_mem_region(ofbi->region);
1051
1026 set_fb_fix(fbi); 1052 set_fb_fix(fbi);
1027 1053
1028 r = setup_vrfb_rotation(fbi); 1054 r = setup_vrfb_rotation(fbi);
1029 if (r) 1055 if (r)
1030 return r; 1056 goto out;
1031 1057
1032 r = omapfb_apply_changes(fbi, 0); 1058 r = omapfb_apply_changes(fbi, 0);
1033 1059
1060 out:
1061 omapfb_put_mem_region(ofbi->region);
1062
1034 return r; 1063 return r;
1035} 1064}
1036 1065
1037static int omapfb_pan_display(struct fb_var_screeninfo *var, 1066static int omapfb_pan_display(struct fb_var_screeninfo *var,
1038 struct fb_info *fbi) 1067 struct fb_info *fbi)
1039{ 1068{
1069 struct omapfb_info *ofbi = FB2OFB(fbi);
1040 struct fb_var_screeninfo new_var; 1070 struct fb_var_screeninfo new_var;
1041 int r; 1071 int r;
1042 1072
@@ -1052,23 +1082,31 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
1052 1082
1053 fbi->var = new_var; 1083 fbi->var = new_var;
1054 1084
1085 omapfb_get_mem_region(ofbi->region);
1086
1055 r = omapfb_apply_changes(fbi, 0); 1087 r = omapfb_apply_changes(fbi, 0);
1056 1088
1089 omapfb_put_mem_region(ofbi->region);
1090
1057 return r; 1091 return r;
1058} 1092}
1059 1093
1060static void mmap_user_open(struct vm_area_struct *vma) 1094static void mmap_user_open(struct vm_area_struct *vma)
1061{ 1095{
1062 struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; 1096 struct omapfb2_mem_region *rg = vma->vm_private_data;
1063 1097
1064 atomic_inc(&ofbi->map_count); 1098 omapfb_get_mem_region(rg);
1099 atomic_inc(&rg->map_count);
1100 omapfb_put_mem_region(rg);
1065} 1101}
1066 1102
1067static void mmap_user_close(struct vm_area_struct *vma) 1103static void mmap_user_close(struct vm_area_struct *vma)
1068{ 1104{
1069 struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; 1105 struct omapfb2_mem_region *rg = vma->vm_private_data;
1070 1106
1071 atomic_dec(&ofbi->map_count); 1107 omapfb_get_mem_region(rg);
1108 atomic_dec(&rg->map_count);
1109 omapfb_put_mem_region(rg);
1072} 1110}
1073 1111
1074static struct vm_operations_struct mmap_user_ops = { 1112static struct vm_operations_struct mmap_user_ops = {
@@ -1080,9 +1118,11 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1080{ 1118{
1081 struct omapfb_info *ofbi = FB2OFB(fbi); 1119 struct omapfb_info *ofbi = FB2OFB(fbi);
1082 struct fb_fix_screeninfo *fix = &fbi->fix; 1120 struct fb_fix_screeninfo *fix = &fbi->fix;
1121 struct omapfb2_mem_region *rg;
1083 unsigned long off; 1122 unsigned long off;
1084 unsigned long start; 1123 unsigned long start;
1085 u32 len; 1124 u32 len;
1125 int r = -EINVAL;
1086 1126
1087 if (vma->vm_end - vma->vm_start == 0) 1127 if (vma->vm_end - vma->vm_start == 0)
1088 return 0; 1128 return 0;
@@ -1090,12 +1130,14 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1090 return -EINVAL; 1130 return -EINVAL;
1091 off = vma->vm_pgoff << PAGE_SHIFT; 1131 off = vma->vm_pgoff << PAGE_SHIFT;
1092 1132
1133 rg = omapfb_get_mem_region(ofbi->region);
1134
1093 start = omapfb_get_region_paddr(ofbi); 1135 start = omapfb_get_region_paddr(ofbi);
1094 len = fix->smem_len; 1136 len = fix->smem_len;
1095 if (off >= len) 1137 if (off >= len)
1096 return -EINVAL; 1138 goto error;
1097 if ((vma->vm_end - vma->vm_start + off) > len) 1139 if ((vma->vm_end - vma->vm_start + off) > len)
1098 return -EINVAL; 1140 goto error;
1099 1141
1100 off += start; 1142 off += start;
1101 1143
@@ -1105,13 +1147,25 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1105 vma->vm_flags |= VM_IO | VM_RESERVED; 1147 vma->vm_flags |= VM_IO | VM_RESERVED;
1106 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 1148 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
1107 vma->vm_ops = &mmap_user_ops; 1149 vma->vm_ops = &mmap_user_ops;
1108 vma->vm_private_data = ofbi; 1150 vma->vm_private_data = rg;
1109 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, 1151 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
1110 vma->vm_end - vma->vm_start, vma->vm_page_prot)) 1152 vma->vm_end - vma->vm_start,
1111 return -EAGAIN; 1153 vma->vm_page_prot)) {
1154 r = -EAGAIN;
1155 goto error;
1156 }
1157
1112 /* vm_ops.open won't be called for mmap itself. */ 1158 /* vm_ops.open won't be called for mmap itself. */
1113 atomic_inc(&ofbi->map_count); 1159 atomic_inc(&rg->map_count);
1160
1161 omapfb_put_mem_region(rg);
1162
1114 return 0; 1163 return 0;
1164
1165 error:
1166 omapfb_put_mem_region(ofbi->region);
1167
1168 return r;
1115} 1169}
1116 1170
1117/* Store a single color palette entry into a pseudo palette or the hardware 1171/* Store a single color palette entry into a pseudo palette or the hardware
@@ -1154,11 +1208,6 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green,
1154 if (r != 0) 1208 if (r != 0)
1155 break; 1209 break;
1156 1210
1157 if (regno < 0) {
1158 r = -EINVAL;
1159 break;
1160 }
1161
1162 if (regno < 16) { 1211 if (regno < 16) {
1163 u16 pal; 1212 u16 pal;
1164 pal = ((red >> (16 - var->red.length)) << 1213 pal = ((red >> (16 - var->red.length)) <<
@@ -1217,6 +1266,9 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1217 int do_update = 0; 1266 int do_update = 0;
1218 int r = 0; 1267 int r = 0;
1219 1268
1269 if (!display)
1270 return -EINVAL;
1271
1220 omapfb_lock(fbdev); 1272 omapfb_lock(fbdev);
1221 1273
1222 switch (blank) { 1274 switch (blank) {
@@ -1300,7 +1352,9 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
1300 struct omapfb2_device *fbdev = ofbi->fbdev; 1352 struct omapfb2_device *fbdev = ofbi->fbdev;
1301 struct omapfb2_mem_region *rg; 1353 struct omapfb2_mem_region *rg;
1302 1354
1303 rg = &ofbi->region; 1355 rg = ofbi->region;
1356
1357 WARN_ON(atomic_read(&rg->map_count));
1304 1358
1305 if (rg->paddr) 1359 if (rg->paddr)
1306 if (omap_vram_free(rg->paddr, rg->size)) 1360 if (omap_vram_free(rg->paddr, rg->size))
@@ -1355,8 +1409,15 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1355 void __iomem *vaddr; 1409 void __iomem *vaddr;
1356 int r; 1410 int r;
1357 1411
1358 rg = &ofbi->region; 1412 rg = ofbi->region;
1359 memset(rg, 0, sizeof(*rg)); 1413
1414 rg->paddr = 0;
1415 rg->vaddr = NULL;
1416 memset(&rg->vrfb, 0, sizeof rg->vrfb);
1417 rg->size = 0;
1418 rg->type = 0;
1419 rg->alloc = false;
1420 rg->map = false;
1360 1421
1361 size = PAGE_ALIGN(size); 1422 size = PAGE_ALIGN(size);
1362 1423
@@ -1609,7 +1670,7 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
1609 for (i = 0; i < fbdev->num_fbs; i++) { 1670 for (i = 0; i < fbdev->num_fbs; i++) {
1610 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); 1671 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
1611 struct omapfb2_mem_region *rg; 1672 struct omapfb2_mem_region *rg;
1612 rg = &ofbi->region; 1673 rg = ofbi->region;
1613 1674
1614 DBG("region%d phys %08x virt %p size=%lu\n", 1675 DBG("region%d phys %08x virt %p size=%lu\n",
1615 i, 1676 i,
@@ -1626,7 +1687,7 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1626 struct omapfb_info *ofbi = FB2OFB(fbi); 1687 struct omapfb_info *ofbi = FB2OFB(fbi);
1627 struct omapfb2_device *fbdev = ofbi->fbdev; 1688 struct omapfb2_device *fbdev = ofbi->fbdev;
1628 struct omap_dss_device *display = fb2display(fbi); 1689 struct omap_dss_device *display = fb2display(fbi);
1629 struct omapfb2_mem_region *rg = &ofbi->region; 1690 struct omapfb2_mem_region *rg = ofbi->region;
1630 unsigned long old_size = rg->size; 1691 unsigned long old_size = rg->size;
1631 unsigned long old_paddr = rg->paddr; 1692 unsigned long old_paddr = rg->paddr;
1632 int old_type = rg->type; 1693 int old_type = rg->type;
@@ -1709,7 +1770,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1709 fbi->flags = FBINFO_FLAG_DEFAULT; 1770 fbi->flags = FBINFO_FLAG_DEFAULT;
1710 fbi->pseudo_palette = fbdev->pseudo_palette; 1771 fbi->pseudo_palette = fbdev->pseudo_palette;
1711 1772
1712 if (ofbi->region.size == 0) { 1773 if (ofbi->region->size == 0) {
1713 clear_fb_info(fbi); 1774 clear_fb_info(fbi);
1714 return 0; 1775 return 0;
1715 } 1776 }
@@ -1871,6 +1932,10 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1871 ofbi->fbdev = fbdev; 1932 ofbi->fbdev = fbdev;
1872 ofbi->id = i; 1933 ofbi->id = i;
1873 1934
1935 ofbi->region = &fbdev->regions[i];
1936 ofbi->region->id = i;
1937 init_rwsem(&ofbi->region->lock);
1938
1874 /* assign these early, so that fb alloc can use them */ 1939 /* assign these early, so that fb alloc can use them */
1875 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : 1940 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
1876 OMAP_DSS_ROT_DMA; 1941 OMAP_DSS_ROT_DMA;
@@ -1900,7 +1965,13 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1900 1965
1901 /* setup fb_infos */ 1966 /* setup fb_infos */
1902 for (i = 0; i < fbdev->num_fbs; i++) { 1967 for (i = 0; i < fbdev->num_fbs; i++) {
1903 r = omapfb_fb_init(fbdev, fbdev->fbs[i]); 1968 struct fb_info *fbi = fbdev->fbs[i];
1969 struct omapfb_info *ofbi = FB2OFB(fbi);
1970
1971 omapfb_get_mem_region(ofbi->region);
1972 r = omapfb_fb_init(fbdev, fbi);
1973 omapfb_put_mem_region(ofbi->region);
1974
1904 if (r) { 1975 if (r) {
1905 dev_err(fbdev->dev, "failed to setup fb_info\n"); 1976 dev_err(fbdev->dev, "failed to setup fb_info\n");
1906 return r; 1977 return r;
@@ -1921,20 +1992,19 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1921 DBG("framebuffers registered\n"); 1992 DBG("framebuffers registered\n");
1922 1993
1923 for (i = 0; i < fbdev->num_fbs; i++) { 1994 for (i = 0; i < fbdev->num_fbs; i++) {
1924 r = omapfb_apply_changes(fbdev->fbs[i], 1); 1995 struct fb_info *fbi = fbdev->fbs[i];
1996 struct omapfb_info *ofbi = FB2OFB(fbi);
1997
1998 omapfb_get_mem_region(ofbi->region);
1999 r = omapfb_apply_changes(fbi, 1);
2000 omapfb_put_mem_region(ofbi->region);
2001
1925 if (r) { 2002 if (r) {
1926 dev_err(fbdev->dev, "failed to change mode\n"); 2003 dev_err(fbdev->dev, "failed to change mode\n");
1927 return r; 2004 return r;
1928 } 2005 }
1929 } 2006 }
1930 2007
1931 DBG("create sysfs for fbs\n");
1932 r = omapfb_create_sysfs(fbdev);
1933 if (r) {
1934 dev_err(fbdev->dev, "failed to create sysfs entries\n");
1935 return r;
1936 }
1937
1938 /* Enable fb0 */ 2008 /* Enable fb0 */
1939 if (fbdev->num_fbs > 0) { 2009 if (fbdev->num_fbs > 0) {
1940 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]); 2010 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]);
@@ -1968,11 +2038,11 @@ static int omapfb_mode_to_timings(const char *mode_str,
1968#ifdef CONFIG_OMAP2_DSS_VENC 2038#ifdef CONFIG_OMAP2_DSS_VENC
1969 if (strcmp(mode_str, "pal") == 0) { 2039 if (strcmp(mode_str, "pal") == 0) {
1970 *timings = omap_dss_pal_timings; 2040 *timings = omap_dss_pal_timings;
1971 *bpp = 0; 2041 *bpp = 24;
1972 return 0; 2042 return 0;
1973 } else if (strcmp(mode_str, "ntsc") == 0) { 2043 } else if (strcmp(mode_str, "ntsc") == 0) {
1974 *timings = omap_dss_ntsc_timings; 2044 *timings = omap_dss_ntsc_timings;
1975 *bpp = 0; 2045 *bpp = 24;
1976 return 0; 2046 return 0;
1977 } 2047 }
1978#endif 2048#endif
@@ -2220,6 +2290,13 @@ static int omapfb_probe(struct platform_device *pdev)
2220 } 2290 }
2221 } 2291 }
2222 2292
2293 DBG("create sysfs for fbs\n");
2294 r = omapfb_create_sysfs(fbdev);
2295 if (r) {
2296 dev_err(fbdev->dev, "failed to create sysfs entries\n");
2297 goto cleanup;
2298 }
2299
2223 return 0; 2300 return 0;
2224 2301
2225cleanup: 2302cleanup:
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 5179219128bd..6f9c72cd6bb0 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -49,6 +49,7 @@ static ssize_t store_rotate_type(struct device *dev,
49{ 49{
50 struct fb_info *fbi = dev_get_drvdata(dev); 50 struct fb_info *fbi = dev_get_drvdata(dev);
51 struct omapfb_info *ofbi = FB2OFB(fbi); 51 struct omapfb_info *ofbi = FB2OFB(fbi);
52 struct omapfb2_mem_region *rg;
52 enum omap_dss_rotation_type rot_type; 53 enum omap_dss_rotation_type rot_type;
53 int r; 54 int r;
54 55
@@ -64,9 +65,11 @@ static ssize_t store_rotate_type(struct device *dev,
64 if (rot_type == ofbi->rotation_type) 65 if (rot_type == ofbi->rotation_type)
65 goto out; 66 goto out;
66 67
67 if (ofbi->region.size) { 68 rg = omapfb_get_mem_region(ofbi->region);
69
70 if (rg->size) {
68 r = -EBUSY; 71 r = -EBUSY;
69 goto out; 72 goto put_region;
70 } 73 }
71 74
72 ofbi->rotation_type = rot_type; 75 ofbi->rotation_type = rot_type;
@@ -75,6 +78,8 @@ static ssize_t store_rotate_type(struct device *dev,
75 * Since the VRAM for this FB is not allocated at the moment we don't 78 * Since the VRAM for this FB is not allocated at the moment we don't
76 * need to do any further parameter checking at this point. 79 * need to do any further parameter checking at this point.
77 */ 80 */
81put_region:
82 omapfb_put_mem_region(rg);
78out: 83out:
79 unlock_fb_info(fbi); 84 unlock_fb_info(fbi);
80 85
@@ -97,7 +102,7 @@ static ssize_t store_mirror(struct device *dev,
97{ 102{
98 struct fb_info *fbi = dev_get_drvdata(dev); 103 struct fb_info *fbi = dev_get_drvdata(dev);
99 struct omapfb_info *ofbi = FB2OFB(fbi); 104 struct omapfb_info *ofbi = FB2OFB(fbi);
100 bool mirror; 105 unsigned long mirror;
101 int r; 106 int r;
102 struct fb_var_screeninfo new_var; 107 struct fb_var_screeninfo new_var;
103 108
@@ -111,6 +116,8 @@ static ssize_t store_mirror(struct device *dev,
111 116
112 ofbi->mirror = mirror; 117 ofbi->mirror = mirror;
113 118
119 omapfb_get_mem_region(ofbi->region);
120
114 memcpy(&new_var, &fbi->var, sizeof(new_var)); 121 memcpy(&new_var, &fbi->var, sizeof(new_var));
115 r = check_fb_var(fbi, &new_var); 122 r = check_fb_var(fbi, &new_var);
116 if (r) 123 if (r)
@@ -125,6 +132,8 @@ static ssize_t store_mirror(struct device *dev,
125 132
126 r = count; 133 r = count;
127out: 134out:
135 omapfb_put_mem_region(ofbi->region);
136
128 unlock_fb_info(fbi); 137 unlock_fb_info(fbi);
129 138
130 return r; 139 return r;
@@ -263,11 +272,15 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
263 272
264 DBG("detaching %d\n", ofbi->overlays[i]->id); 273 DBG("detaching %d\n", ofbi->overlays[i]->id);
265 274
275 omapfb_get_mem_region(ofbi->region);
276
266 omapfb_overlay_enable(ovl, 0); 277 omapfb_overlay_enable(ovl, 0);
267 278
268 if (ovl->manager) 279 if (ovl->manager)
269 ovl->manager->apply(ovl->manager); 280 ovl->manager->apply(ovl->manager);
270 281
282 omapfb_put_mem_region(ofbi->region);
283
271 for (t = i + 1; t < ofbi->num_overlays; t++) { 284 for (t = i + 1; t < ofbi->num_overlays; t++) {
272 ofbi->rotation[t-1] = ofbi->rotation[t]; 285 ofbi->rotation[t-1] = ofbi->rotation[t];
273 ofbi->overlays[t-1] = ofbi->overlays[t]; 286 ofbi->overlays[t-1] = ofbi->overlays[t];
@@ -300,7 +313,12 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
300 } 313 }
301 314
302 if (added) { 315 if (added) {
316 omapfb_get_mem_region(ofbi->region);
317
303 r = omapfb_apply_changes(fbi, 0); 318 r = omapfb_apply_changes(fbi, 0);
319
320 omapfb_put_mem_region(ofbi->region);
321
304 if (r) 322 if (r)
305 goto out; 323 goto out;
306 } 324 }
@@ -388,7 +406,12 @@ static ssize_t store_overlays_rotate(struct device *dev,
388 for (i = 0; i < num_ovls; ++i) 406 for (i = 0; i < num_ovls; ++i)
389 ofbi->rotation[i] = rotation[i]; 407 ofbi->rotation[i] = rotation[i];
390 408
409 omapfb_get_mem_region(ofbi->region);
410
391 r = omapfb_apply_changes(fbi, 0); 411 r = omapfb_apply_changes(fbi, 0);
412
413 omapfb_put_mem_region(ofbi->region);
414
392 if (r) 415 if (r)
393 goto out; 416 goto out;
394 417
@@ -408,7 +431,7 @@ static ssize_t show_size(struct device *dev,
408 struct fb_info *fbi = dev_get_drvdata(dev); 431 struct fb_info *fbi = dev_get_drvdata(dev);
409 struct omapfb_info *ofbi = FB2OFB(fbi); 432 struct omapfb_info *ofbi = FB2OFB(fbi);
410 433
411 return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size); 434 return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
412} 435}
413 436
414static ssize_t store_size(struct device *dev, struct device_attribute *attr, 437static ssize_t store_size(struct device *dev, struct device_attribute *attr,
@@ -416,6 +439,8 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
416{ 439{
417 struct fb_info *fbi = dev_get_drvdata(dev); 440 struct fb_info *fbi = dev_get_drvdata(dev);
418 struct omapfb_info *ofbi = FB2OFB(fbi); 441 struct omapfb_info *ofbi = FB2OFB(fbi);
442 struct omapfb2_device *fbdev = ofbi->fbdev;
443 struct omapfb2_mem_region *rg;
419 unsigned long size; 444 unsigned long size;
420 int r; 445 int r;
421 int i; 446 int i;
@@ -425,15 +450,33 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
425 if (!lock_fb_info(fbi)) 450 if (!lock_fb_info(fbi))
426 return -ENODEV; 451 return -ENODEV;
427 452
428 for (i = 0; i < ofbi->num_overlays; i++) { 453 rg = ofbi->region;
429 if (ofbi->overlays[i]->info.enabled) { 454
430 r = -EBUSY; 455 down_write_nested(&rg->lock, rg->id);
431 goto out; 456 atomic_inc(&rg->lock_count);
457
458 if (atomic_read(&rg->map_count)) {
459 r = -EBUSY;
460 goto out;
461 }
462
463 for (i = 0; i < fbdev->num_fbs; i++) {
464 struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
465 int j;
466
467 if (ofbi2->region != rg)
468 continue;
469
470 for (j = 0; j < ofbi2->num_overlays; j++) {
471 if (ofbi2->overlays[j]->info.enabled) {
472 r = -EBUSY;
473 goto out;
474 }
432 } 475 }
433 } 476 }
434 477
435 if (size != ofbi->region.size) { 478 if (size != ofbi->region->size) {
436 r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type); 479 r = omapfb_realloc_fbmem(fbi, size, ofbi->region->type);
437 if (r) { 480 if (r) {
438 dev_err(dev, "realloc fbmem failed\n"); 481 dev_err(dev, "realloc fbmem failed\n");
439 goto out; 482 goto out;
@@ -442,6 +485,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
442 485
443 r = count; 486 r = count;
444out: 487out:
488 atomic_dec(&rg->lock_count);
489 up_write(&rg->lock);
490
445 unlock_fb_info(fbi); 491 unlock_fb_info(fbi);
446 492
447 return r; 493 return r;
@@ -453,7 +499,7 @@ static ssize_t show_phys(struct device *dev,
453 struct fb_info *fbi = dev_get_drvdata(dev); 499 struct fb_info *fbi = dev_get_drvdata(dev);
454 struct omapfb_info *ofbi = FB2OFB(fbi); 500 struct omapfb_info *ofbi = FB2OFB(fbi);
455 501
456 return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr); 502 return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
457} 503}
458 504
459static ssize_t show_virt(struct device *dev, 505static ssize_t show_virt(struct device *dev,
@@ -462,7 +508,7 @@ static ssize_t show_virt(struct device *dev,
462 struct fb_info *fbi = dev_get_drvdata(dev); 508 struct fb_info *fbi = dev_get_drvdata(dev);
463 struct omapfb_info *ofbi = FB2OFB(fbi); 509 struct omapfb_info *ofbi = FB2OFB(fbi);
464 510
465 return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr); 511 return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr);
466} 512}
467 513
468static struct device_attribute omapfb_attrs[] = { 514static struct device_attribute omapfb_attrs[] = {
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index cd54fdbfd8bb..1305fc9880ba 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -27,6 +27,8 @@
27#define DEBUG 27#define DEBUG
28#endif 28#endif
29 29
30#include <linux/rwsem.h>
31
30#include <plat/display.h> 32#include <plat/display.h>
31 33
32#ifdef DEBUG 34#ifdef DEBUG
@@ -44,6 +46,7 @@ extern unsigned int omapfb_debug;
44#define OMAPFB_MAX_OVL_PER_FB 3 46#define OMAPFB_MAX_OVL_PER_FB 3
45 47
46struct omapfb2_mem_region { 48struct omapfb2_mem_region {
49 int id;
47 u32 paddr; 50 u32 paddr;
48 void __iomem *vaddr; 51 void __iomem *vaddr;
49 struct vrfb vrfb; 52 struct vrfb vrfb;
@@ -51,13 +54,15 @@ struct omapfb2_mem_region {
51 u8 type; /* OMAPFB_PLANE_MEM_* */ 54 u8 type; /* OMAPFB_PLANE_MEM_* */
52 bool alloc; /* allocated by the driver */ 55 bool alloc; /* allocated by the driver */
53 bool map; /* kernel mapped by the driver */ 56 bool map; /* kernel mapped by the driver */
57 atomic_t map_count;
58 struct rw_semaphore lock;
59 atomic_t lock_count;
54}; 60};
55 61
56/* appended to fb_info */ 62/* appended to fb_info */
57struct omapfb_info { 63struct omapfb_info {
58 int id; 64 int id;
59 struct omapfb2_mem_region region; 65 struct omapfb2_mem_region *region;
60 atomic_t map_count;
61 int num_overlays; 66 int num_overlays;
62 struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB]; 67 struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB];
63 struct omapfb2_device *fbdev; 68 struct omapfb2_device *fbdev;
@@ -76,6 +81,7 @@ struct omapfb2_device {
76 81
77 unsigned num_fbs; 82 unsigned num_fbs;
78 struct fb_info *fbs[10]; 83 struct fb_info *fbs[10];
84 struct omapfb2_mem_region regions[10];
79 85
80 unsigned num_displays; 86 unsigned num_displays;
81 struct omap_dss_device *displays[10]; 87 struct omap_dss_device *displays[10];
@@ -117,6 +123,9 @@ int omapfb_update_window(struct fb_info *fbi,
117int dss_mode_to_fb_mode(enum omap_color_mode dssmode, 123int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
118 struct fb_var_screeninfo *var); 124 struct fb_var_screeninfo *var);
119 125
126int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
127 u16 posx, u16 posy, u16 outw, u16 outh);
128
120/* find the display connected to this fb, if any */ 129/* find the display connected to this fb, if any */
121static inline struct omap_dss_device *fb2display(struct fb_info *fbi) 130static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
122{ 131{
@@ -148,8 +157,24 @@ static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
148 struct omap_overlay_info info; 157 struct omap_overlay_info info;
149 158
150 ovl->get_overlay_info(ovl, &info); 159 ovl->get_overlay_info(ovl, &info);
160 if (info.enabled == enable)
161 return 0;
151 info.enabled = enable; 162 info.enabled = enable;
152 return ovl->set_overlay_info(ovl, &info); 163 return ovl->set_overlay_info(ovl, &info);
153} 164}
154 165
166static inline struct omapfb2_mem_region *
167omapfb_get_mem_region(struct omapfb2_mem_region *rg)
168{
169 down_read_nested(&rg->lock, rg->id);
170 atomic_inc(&rg->lock_count);
171 return rg;
172}
173
174static inline void omapfb_put_mem_region(struct omapfb2_mem_region *rg)
175{
176 atomic_dec(&rg->lock_count);
177 up_read(&rg->lock);
178}
179
155#endif 180#endif
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index d9b6e06e0700..ef1f3de2e052 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -160,7 +160,6 @@ struct lvds_setting_information {
160 int v_active; 160 int v_active;
161 int bpp; 161 int bpp;
162 int refresh_rate; 162 int refresh_rate;
163 int get_lcd_size_method;
164 int lcd_panel_id; 163 int lcd_panel_id;
165 int lcd_panel_hres; 164 int lcd_panel_hres;
166 int lcd_panel_vres; 165 int lcd_panel_vres;
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index b996803ae2c1..7dcb4d5bb9c3 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -23,143 +23,341 @@
23#include "global.h" 23#include "global.h"
24 24
25static struct pll_map pll_value[] = { 25static struct pll_map pll_value[] = {
26 {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, 26 {25175000,
27 CX700_25_175M, VX855_25_175M}, 27 {99, 7, 3},
28 {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, 28 {85, 3, 4}, /* ignoring bit difference: 0x00008000 */
29 CX700_29_581M, VX855_29_581M}, 29 {141, 5, 4},
30 {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, 30 {141, 5, 4} },
31 CX700_26_880M, VX855_26_880M}, 31 {29581000,
32 {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, 32 {33, 4, 2},
33 CX700_31_490M, VX855_31_490M}, 33 {66, 2, 4}, /* ignoring bit difference: 0x00808000 */
34 {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, 34 {166, 5, 4}, /* ignoring bit difference: 0x00008000 */
35 CX700_31_500M, VX855_31_500M}, 35 {165, 5, 4} },
36 {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, 36 {26880000,
37 CX700_31_728M, VX855_31_728M}, 37 {15, 4, 1},
38 {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, 38 {30, 2, 3}, /* ignoring bit difference: 0x00808000 */
39 CX700_32_668M, VX855_32_668M}, 39 {150, 5, 4},
40 {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, 40 {150, 5, 4} },
41 CX700_36_000M, VX855_36_000M}, 41 {31500000,
42 {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, 42 {53, 3, 3}, /* ignoring bit difference: 0x00008000 */
43 CX700_40_000M, VX855_40_000M}, 43 {141, 4, 4}, /* ignoring bit difference: 0x00008000 */
44 {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, 44 {176, 5, 4},
45 CX700_41_291M, VX855_41_291M}, 45 {176, 5, 4} },
46 {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, 46 {31728000,
47 CX700_43_163M, VX855_43_163M}, 47 {31, 7, 1},
48 {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, 48 {177, 5, 4}, /* ignoring bit difference: 0x00008000 */
49 CX700_45_250M, VX855_45_250M}, 49 {177, 5, 4},
50 {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, 50 {142, 4, 4} },
51 CX700_46_000M, VX855_46_000M}, 51 {32688000,
52 {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, 52 {73, 4, 3},
53 CX700_46_996M, VX855_46_996M}, 53 {146, 4, 4}, /* ignoring bit difference: 0x00008000 */
54 {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, 54 {183, 5, 4},
55 CX700_48_000M, VX855_48_000M}, 55 {146, 4, 4} },
56 {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, 56 {36000000,
57 CX700_48_875M, VX855_48_875M}, 57 {101, 5, 3}, /* ignoring bit difference: 0x00008000 */
58 {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, 58 {161, 4, 4}, /* ignoring bit difference: 0x00008000 */
59 CX700_49_500M, VX855_49_500M}, 59 {202, 5, 4},
60 {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, 60 {161, 4, 4} },
61 CX700_52_406M, VX855_52_406M}, 61 {40000000,
62 {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, 62 {89, 4, 3},
63 CX700_52_977M, VX855_52_977M}, 63 {89, 4, 3}, /* ignoring bit difference: 0x00008000 */
64 {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, 64 {112, 5, 3},
65 CX700_56_250M, VX855_56_250M}, 65 {112, 5, 3} },
66 {CLK_57_275M, 0, 0, 0, VX855_57_275M}, 66 {41291000,
67 {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, 67 {23, 4, 1},
68 CX700_60_466M, VX855_60_466M}, 68 {69, 3, 3}, /* ignoring bit difference: 0x00008000 */
69 {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, 69 {115, 5, 3},
70 CX700_61_500M, VX855_61_500M}, 70 {115, 5, 3} },
71 {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, 71 {43163000,
72 CX700_65_000M, VX855_65_000M}, 72 {121, 5, 3},
73 {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, 73 {121, 5, 3}, /* ignoring bit difference: 0x00008000 */
74 CX700_65_178M, VX855_65_178M}, 74 {121, 5, 3},
75 {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, 75 {121, 5, 3} },
76 CX700_66_750M, VX855_66_750M}, 76 {45250000,
77 {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, 77 {127, 5, 3},
78 CX700_68_179M, VX855_68_179M}, 78 {127, 5, 3}, /* ignoring bit difference: 0x00808000 */
79 {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, 79 {127, 5, 3},
80 CX700_69_924M, VX855_69_924M}, 80 {127, 5, 3} },
81 {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, 81 {46000000,
82 CX700_70_159M, VX855_70_159M}, 82 {90, 7, 2},
83 {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, 83 {103, 4, 3}, /* ignoring bit difference: 0x00008000 */
84 CX700_72_000M, VX855_72_000M}, 84 {129, 5, 3},
85 {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, 85 {103, 4, 3} },
86 CX700_78_750M, VX855_78_750M}, 86 {46996000,
87 {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, 87 {105, 4, 3}, /* ignoring bit difference: 0x00008000 */
88 CX700_80_136M, VX855_80_136M}, 88 {131, 5, 3}, /* ignoring bit difference: 0x00808000 */
89 {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, 89 {131, 5, 3}, /* ignoring bit difference: 0x00808000 */
90 CX700_83_375M, VX855_83_375M}, 90 {105, 4, 3} },
91 {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, 91 {48000000,
92 CX700_83_950M, VX855_83_950M}, 92 {67, 20, 0},
93 {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, 93 {134, 5, 3}, /* ignoring bit difference: 0x00808000 */
94 CX700_84_750M, VX855_84_750M}, 94 {134, 5, 3},
95 {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, 95 {134, 5, 3} },
96 CX700_85_860M, VX855_85_860M}, 96 {48875000,
97 {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, 97 {99, 29, 0},
98 CX700_88_750M, VX855_88_750M}, 98 {82, 3, 3}, /* ignoring bit difference: 0x00808000 */
99 {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, 99 {82, 3, 3}, /* ignoring bit difference: 0x00808000 */
100 CX700_94_500M, VX855_94_500M}, 100 {137, 5, 3} },
101 {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, 101 {49500000,
102 CX700_97_750M, VX855_97_750M}, 102 {83, 6, 2},
103 {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M, 103 {83, 3, 3}, /* ignoring bit difference: 0x00008000 */
104 CX700_101_000M, VX855_101_000M}, 104 {138, 5, 3},
105 {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M, 105 {83, 3, 3} },
106 CX700_106_500M, VX855_106_500M}, 106 {52406000,
107 {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M, 107 {117, 4, 3},
108 CX700_108_000M, VX855_108_000M}, 108 {117, 4, 3}, /* ignoring bit difference: 0x00008000 */
109 {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M, 109 {117, 4, 3},
110 CX700_113_309M, VX855_113_309M}, 110 {88, 3, 3} },
111 {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M, 111 {52977000,
112 CX700_118_840M, VX855_118_840M}, 112 {37, 5, 1},
113 {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M, 113 {148, 5, 3}, /* ignoring bit difference: 0x00808000 */
114 CX700_119_000M, VX855_119_000M}, 114 {148, 5, 3},
115 {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M, 115 {148, 5, 3} },
116 CX700_121_750M, 0}, 116 {56250000,
117 {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M, 117 {55, 7, 1}, /* ignoring bit difference: 0x00008000 */
118 CX700_125_104M, 0}, 118 {126, 4, 3}, /* ignoring bit difference: 0x00008000 */
119 {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M, 119 {157, 5, 3},
120 CX700_133_308M, 0}, 120 {157, 5, 3} },
121 {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M, 121 {57275000,
122 CX700_135_000M, VX855_135_000M}, 122 {0, 0, 0},
123 {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M, 123 {2, 2, 0},
124 CX700_136_700M, VX855_136_700M}, 124 {2, 2, 0},
125 {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M, 125 {157, 5, 3} }, /* ignoring bit difference: 0x00808000 */
126 CX700_138_400M, VX855_138_400M}, 126 {60466000,
127 {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M, 127 {76, 9, 1},
128 CX700_146_760M, VX855_146_760M}, 128 {169, 5, 3}, /* ignoring bit difference: 0x00808000 */
129 {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M, 129 {169, 5, 3}, /* FIXED: old = {72, 2, 3} */
130 CX700_153_920M, VX855_153_920M}, 130 {169, 5, 3} },
131 {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M, 131 {61500000,
132 CX700_156_000M, VX855_156_000M}, 132 {86, 20, 0},
133 {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M, 133 {172, 5, 3}, /* ignoring bit difference: 0x00808000 */
134 CX700_157_500M, VX855_157_500M}, 134 {172, 5, 3},
135 {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M, 135 {172, 5, 3} },
136 CX700_162_000M, VX855_162_000M}, 136 {65000000,
137 {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M, 137 {109, 6, 2}, /* ignoring bit difference: 0x00008000 */
138 CX700_187_000M, VX855_187_000M}, 138 {109, 3, 3}, /* ignoring bit difference: 0x00008000 */
139 {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M, 139 {109, 3, 3},
140 CX700_193_295M, VX855_193_295M}, 140 {109, 3, 3} },
141 {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M, 141 {65178000,
142 CX700_202_500M, VX855_202_500M}, 142 {91, 5, 2},
143 {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M, 143 {182, 5, 3}, /* ignoring bit difference: 0x00808000 */
144 CX700_204_000M, VX855_204_000M}, 144 {109, 3, 3},
145 {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M, 145 {182, 5, 3} },
146 CX700_218_500M, VX855_218_500M}, 146 {66750000,
147 {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M, 147 {75, 4, 2},
148 CX700_234_000M, VX855_234_000M}, 148 {150, 4, 3}, /* ignoring bit difference: 0x00808000 */
149 {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M, 149 {150, 4, 3},
150 CX700_267_250M, VX855_267_250M}, 150 {112, 3, 3} },
151 {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M, 151 {68179000,
152 CX700_297_500M, VX855_297_500M}, 152 {19, 4, 0},
153 {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, 153 {114, 3, 3}, /* ignoring bit difference: 0x00008000 */
154 CX700_74_481M, VX855_74_481M}, 154 {190, 5, 3},
155 {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M, 155 {191, 5, 3} },
156 CX700_172_798M, VX855_172_798M}, 156 {69924000,
157 {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M, 157 {83, 17, 0},
158 CX700_122_614M, VX855_122_614M}, 158 {195, 5, 3}, /* ignoring bit difference: 0x00808000 */
159 {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, 159 {195, 5, 3},
160 CX700_74_270M, 0}, 160 {195, 5, 3} },
161 {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M, 161 {70159000,
162 CX700_148_500M, VX855_148_500M} 162 {98, 20, 0},
163 {196, 5, 3}, /* ignoring bit difference: 0x00808000 */
164 {196, 5, 3},
165 {195, 5, 3} },
166 {72000000,
167 {121, 24, 0},
168 {161, 4, 3}, /* ignoring bit difference: 0x00808000 */
169 {161, 4, 3},
170 {161, 4, 3} },
171 {78750000,
172 {33, 3, 1},
173 {66, 3, 2}, /* ignoring bit difference: 0x00008000 */
174 {110, 5, 2},
175 {110, 5, 2} },
176 {80136000,
177 {28, 5, 0},
178 {68, 3, 2}, /* ignoring bit difference: 0x00008000 */
179 {112, 5, 2},
180 {112, 5, 2} },
181 {83375000,
182 {93, 2, 3},
183 {93, 4, 2}, /* ignoring bit difference: 0x00800000 */
184 {93, 4, 2}, /* ignoring bit difference: 0x00800000 */
185 {117, 5, 2} },
186 {83950000,
187 {41, 7, 0},
188 {117, 5, 2}, /* ignoring bit difference: 0x00008000 */
189 {117, 5, 2},
190 {117, 5, 2} },
191 {84750000,
192 {118, 5, 2},
193 {118, 5, 2}, /* ignoring bit difference: 0x00808000 */
194 {118, 5, 2},
195 {118, 5, 2} },
196 {85860000,
197 {84, 7, 1},
198 {120, 5, 2}, /* ignoring bit difference: 0x00808000 */
199 {120, 5, 2},
200 {118, 5, 2} },
201 {88750000,
202 {31, 5, 0},
203 {124, 5, 2}, /* ignoring bit difference: 0x00808000 */
204 {174, 7, 2}, /* ignoring bit difference: 0x00808000 */
205 {124, 5, 2} },
206 {94500000,
207 {33, 5, 0},
208 {132, 5, 2}, /* ignoring bit difference: 0x00008000 */
209 {132, 5, 2},
210 {132, 5, 2} },
211 {97750000,
212 {82, 6, 1},
213 {137, 5, 2}, /* ignoring bit difference: 0x00808000 */
214 {137, 5, 2},
215 {137, 5, 2} },
216 {101000000,
217 {127, 9, 1},
218 {141, 5, 2}, /* ignoring bit difference: 0x00808000 */
219 {141, 5, 2},
220 {141, 5, 2} },
221 {106500000,
222 {119, 4, 2},
223 {119, 4, 2}, /* ignoring bit difference: 0x00808000 */
224 {119, 4, 2},
225 {149, 5, 2} },
226 {108000000,
227 {121, 4, 2},
228 {121, 4, 2}, /* ignoring bit difference: 0x00808000 */
229 {151, 5, 2},
230 {151, 5, 2} },
231 {113309000,
232 {95, 12, 0},
233 {95, 3, 2}, /* ignoring bit difference: 0x00808000 */
234 {95, 3, 2},
235 {159, 5, 2} },
236 {118840000,
237 {83, 5, 1},
238 {166, 5, 2}, /* ignoring bit difference: 0x00808000 */
239 {166, 5, 2},
240 {166, 5, 2} },
241 {119000000,
242 {108, 13, 0},
243 {133, 4, 2}, /* ignoring bit difference: 0x00808000 */
244 {133, 4, 2},
245 {167, 5, 2} },
246 {121750000,
247 {85, 5, 1},
248 {170, 5, 2}, /* ignoring bit difference: 0x00808000 */
249 {68, 2, 2},
250 {0, 0, 0} },
251 {125104000,
252 {53, 6, 0}, /* ignoring bit difference: 0x00008000 */
253 {106, 3, 2}, /* ignoring bit difference: 0x00008000 */
254 {175, 5, 2},
255 {0, 0, 0} },
256 {135000000,
257 {94, 5, 1},
258 {28, 3, 0}, /* ignoring bit difference: 0x00804000 */
259 {151, 4, 2},
260 {189, 5, 2} },
261 {136700000,
262 {115, 12, 0},
263 {191, 5, 2}, /* ignoring bit difference: 0x00808000 */
264 {191, 5, 2},
265 {191, 5, 2} },
266 {138400000,
267 {87, 9, 0},
268 {116, 3, 2}, /* ignoring bit difference: 0x00808000 */
269 {116, 3, 2},
270 {194, 5, 2} },
271 {146760000,
272 {103, 5, 1},
273 {206, 5, 2}, /* ignoring bit difference: 0x00808000 */
274 {206, 5, 2},
275 {206, 5, 2} },
276 {153920000,
277 {86, 8, 0},
278 {86, 4, 1}, /* ignoring bit difference: 0x00808000 */
279 {86, 4, 1},
280 {86, 4, 1} }, /* FIXED: old = {84, 2, 1} */
281 {156000000,
282 {109, 5, 1},
283 {109, 5, 1}, /* ignoring bit difference: 0x00808000 */
284 {109, 5, 1},
285 {108, 5, 1} },
286 {157500000,
287 {55, 5, 0}, /* ignoring bit difference: 0x00008000 */
288 {22, 2, 0}, /* ignoring bit difference: 0x00802000 */
289 {110, 5, 1},
290 {110, 5, 1} },
291 {162000000,
292 {113, 5, 1},
293 {113, 5, 1}, /* ignoring bit difference: 0x00808000 */
294 {113, 5, 1},
295 {113, 5, 1} },
296 {187000000,
297 {118, 9, 0},
298 {131, 5, 1}, /* ignoring bit difference: 0x00808000 */
299 {131, 5, 1},
300 {131, 5, 1} },
301 {193295000,
302 {108, 8, 0},
303 {81, 3, 1}, /* ignoring bit difference: 0x00808000 */
304 {135, 5, 1},
305 {135, 5, 1} },
306 {202500000,
307 {99, 7, 0},
308 {85, 3, 1}, /* ignoring bit difference: 0x00808000 */
309 {142, 5, 1},
310 {142, 5, 1} },
311 {204000000,
312 {100, 7, 0},
313 {143, 5, 1}, /* ignoring bit difference: 0x00808000 */
314 {143, 5, 1},
315 {143, 5, 1} },
316 {218500000,
317 {92, 6, 0},
318 {153, 5, 1}, /* ignoring bit difference: 0x00808000 */
319 {153, 5, 1},
320 {153, 5, 1} },
321 {234000000,
322 {98, 6, 0},
323 {98, 3, 1}, /* ignoring bit difference: 0x00008000 */
324 {98, 3, 1},
325 {164, 5, 1} },
326 {267250000,
327 {112, 6, 0},
328 {112, 3, 1}, /* ignoring bit difference: 0x00808000 */
329 {187, 5, 1},
330 {187, 5, 1} },
331 {297500000,
332 {102, 5, 0}, /* ignoring bit difference: 0x00008000 */
333 {166, 4, 1}, /* ignoring bit difference: 0x00008000 */
334 {208, 5, 1},
335 {208, 5, 1} },
336 {74481000,
337 {26, 5, 0},
338 {125, 3, 3}, /* ignoring bit difference: 0x00808000 */
339 {208, 5, 3},
340 {209, 5, 3} },
341 {172798000,
342 {121, 5, 1},
343 {121, 5, 1}, /* ignoring bit difference: 0x00808000 */
344 {121, 5, 1},
345 {121, 5, 1} },
346 {122614000,
347 {60, 7, 0},
348 {137, 4, 2}, /* ignoring bit difference: 0x00808000 */
349 {137, 4, 2},
350 {172, 5, 2} },
351 {74270000,
352 {83, 8, 1},
353 {208, 5, 3},
354 {208, 5, 3},
355 {0, 0, 0} },
356 {148500000,
357 {83, 8, 0},
358 {208, 5, 2},
359 {166, 4, 2},
360 {208, 5, 2} }
163}; 361};
164 362
165static struct fifo_depth_select display_fifo_depth_reg = { 363static struct fifo_depth_select display_fifo_depth_reg = {
@@ -1360,40 +1558,70 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1360 1558
1361} 1559}
1362 1560
1561static u32 cle266_encode_pll(struct pll_config pll)
1562{
1563 return (pll.multiplier << 8)
1564 | (pll.rshift << 6)
1565 | pll.divisor;
1566}
1567
1568static u32 k800_encode_pll(struct pll_config pll)
1569{
1570 return ((pll.divisor - 2) << 16)
1571 | (pll.rshift << 10)
1572 | (pll.multiplier - 2);
1573}
1574
1575static u32 vx855_encode_pll(struct pll_config pll)
1576{
1577 return (pll.divisor << 16)
1578 | (pll.rshift << 10)
1579 | pll.multiplier;
1580}
1581
1363u32 viafb_get_clk_value(int clk) 1582u32 viafb_get_clk_value(int clk)
1364{ 1583{
1365 int i; 1584 u32 value = 0;
1585 int i = 0;
1366 1586
1367 for (i = 0; i < NUM_TOTAL_PLL_TABLE; i++) { 1587 while (i < NUM_TOTAL_PLL_TABLE && clk != pll_value[i].clk)
1368 if (clk == pll_value[i].clk) { 1588 i++;
1369 switch (viaparinfo->chip_info->gfx_chip_name) { 1589
1370 case UNICHROME_CLE266: 1590 if (i == NUM_TOTAL_PLL_TABLE) {
1371 case UNICHROME_K400: 1591 printk(KERN_WARNING "viafb_get_clk_value: PLL lookup failed!");
1372 return pll_value[i].cle266_pll; 1592 } else {
1373 1593 switch (viaparinfo->chip_info->gfx_chip_name) {
1374 case UNICHROME_K800: 1594 case UNICHROME_CLE266:
1375 case UNICHROME_PM800: 1595 case UNICHROME_K400:
1376 case UNICHROME_CN700: 1596 value = cle266_encode_pll(pll_value[i].cle266_pll);
1377 return pll_value[i].k800_pll; 1597 break;
1378 1598
1379 case UNICHROME_CX700: 1599 case UNICHROME_K800:
1380 case UNICHROME_K8M890: 1600 case UNICHROME_PM800:
1381 case UNICHROME_P4M890: 1601 case UNICHROME_CN700:
1382 case UNICHROME_P4M900: 1602 value = k800_encode_pll(pll_value[i].k800_pll);
1383 case UNICHROME_VX800: 1603 break;
1384 return pll_value[i].cx700_pll; 1604
1385 case UNICHROME_VX855: 1605 case UNICHROME_CX700:
1386 return pll_value[i].vx855_pll; 1606 case UNICHROME_CN750:
1387 } 1607 case UNICHROME_K8M890:
1608 case UNICHROME_P4M890:
1609 case UNICHROME_P4M900:
1610 case UNICHROME_VX800:
1611 value = k800_encode_pll(pll_value[i].cx700_pll);
1612 break;
1613
1614 case UNICHROME_VX855:
1615 value = vx855_encode_pll(pll_value[i].vx855_pll);
1616 break;
1388 } 1617 }
1389 } 1618 }
1390 1619
1391 DEBUG_MSG(KERN_INFO "Can't find match PLL value\n\n"); 1620 return value;
1392 return 0;
1393} 1621}
1394 1622
1395/* Set VCLK*/ 1623/* Set VCLK*/
1396void viafb_set_vclock(u32 CLK, int set_iga) 1624void viafb_set_vclock(u32 clk, int set_iga)
1397{ 1625{
1398 /* H.W. Reset : ON */ 1626 /* H.W. Reset : ON */
1399 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); 1627 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
@@ -1403,26 +1631,23 @@ void viafb_set_vclock(u32 CLK, int set_iga)
1403 switch (viaparinfo->chip_info->gfx_chip_name) { 1631 switch (viaparinfo->chip_info->gfx_chip_name) {
1404 case UNICHROME_CLE266: 1632 case UNICHROME_CLE266:
1405 case UNICHROME_K400: 1633 case UNICHROME_K400:
1406 viafb_write_reg(SR46, VIASR, CLK / 0x100); 1634 via_write_reg(VIASR, SR46, (clk & 0x00FF));
1407 viafb_write_reg(SR47, VIASR, CLK % 0x100); 1635 via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8);
1408 break; 1636 break;
1409 1637
1410 case UNICHROME_K800: 1638 case UNICHROME_K800:
1411 case UNICHROME_PM800: 1639 case UNICHROME_PM800:
1412 case UNICHROME_CN700: 1640 case UNICHROME_CN700:
1413 case UNICHROME_CX700: 1641 case UNICHROME_CX700:
1642 case UNICHROME_CN750:
1414 case UNICHROME_K8M890: 1643 case UNICHROME_K8M890:
1415 case UNICHROME_P4M890: 1644 case UNICHROME_P4M890:
1416 case UNICHROME_P4M900: 1645 case UNICHROME_P4M900:
1417 case UNICHROME_VX800: 1646 case UNICHROME_VX800:
1418 case UNICHROME_VX855: 1647 case UNICHROME_VX855:
1419 viafb_write_reg(SR44, VIASR, CLK / 0x10000); 1648 via_write_reg(VIASR, SR44, (clk & 0x0000FF));
1420 DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000); 1649 via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8);
1421 viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100); 1650 via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16);
1422 DEBUG_MSG(KERN_INFO "\nSR45=%x",
1423 (CLK & 0xFFFF) / 0x100);
1424 viafb_write_reg(SR46, VIASR, CLK % 0x100);
1425 DEBUG_MSG(KERN_INFO "\nSR46=%x", CLK % 0x100);
1426 break; 1651 break;
1427 } 1652 }
1428 } 1653 }
@@ -1432,22 +1657,23 @@ void viafb_set_vclock(u32 CLK, int set_iga)
1432 switch (viaparinfo->chip_info->gfx_chip_name) { 1657 switch (viaparinfo->chip_info->gfx_chip_name) {
1433 case UNICHROME_CLE266: 1658 case UNICHROME_CLE266:
1434 case UNICHROME_K400: 1659 case UNICHROME_K400:
1435 viafb_write_reg(SR44, VIASR, CLK / 0x100); 1660 via_write_reg(VIASR, SR44, (clk & 0x00FF));
1436 viafb_write_reg(SR45, VIASR, CLK % 0x100); 1661 via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8);
1437 break; 1662 break;
1438 1663
1439 case UNICHROME_K800: 1664 case UNICHROME_K800:
1440 case UNICHROME_PM800: 1665 case UNICHROME_PM800:
1441 case UNICHROME_CN700: 1666 case UNICHROME_CN700:
1442 case UNICHROME_CX700: 1667 case UNICHROME_CX700:
1668 case UNICHROME_CN750:
1443 case UNICHROME_K8M890: 1669 case UNICHROME_K8M890:
1444 case UNICHROME_P4M890: 1670 case UNICHROME_P4M890:
1445 case UNICHROME_P4M900: 1671 case UNICHROME_P4M900:
1446 case UNICHROME_VX800: 1672 case UNICHROME_VX800:
1447 case UNICHROME_VX855: 1673 case UNICHROME_VX855:
1448 viafb_write_reg(SR4A, VIASR, CLK / 0x10000); 1674 via_write_reg(VIASR, SR4A, (clk & 0x0000FF));
1449 viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100); 1675 via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8);
1450 viafb_write_reg(SR4C, VIASR, CLK % 0x100); 1676 via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16);
1451 break; 1677 break;
1452 } 1678 }
1453 } 1679 }
@@ -1791,8 +2017,6 @@ void viafb_init_chip_info(int chip_type)
1791 viafb_set_iga_path(); 2017 viafb_set_iga_path();
1792 2018
1793 viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method; 2019 viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
1794 viaparinfo->lvds_setting_info->get_lcd_size_method =
1795 GET_LCD_SIZE_BY_USER_SETTING;
1796 viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode; 2020 viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
1797 viaparinfo->lvds_setting_info2->display_method = 2021 viaparinfo->lvds_setting_info2->display_method =
1798 viaparinfo->lvds_setting_info->display_method; 2022 viaparinfo->lvds_setting_info->display_method;
@@ -1946,13 +2170,6 @@ static void init_tmds_chip_info(void)
1946 2170
1947static void init_lvds_chip_info(void) 2171static void init_lvds_chip_info(void)
1948{ 2172{
1949 if (viafb_lcd_panel_id > LCD_PANEL_ID_MAXIMUM)
1950 viaparinfo->lvds_setting_info->get_lcd_size_method =
1951 GET_LCD_SIZE_BY_VGA_BIOS;
1952 else
1953 viaparinfo->lvds_setting_info->get_lcd_size_method =
1954 GET_LCD_SIZE_BY_USER_SETTING;
1955
1956 viafb_lvds_trasmitter_identify(); 2173 viafb_lvds_trasmitter_identify();
1957 viafb_init_lcd_size(); 2174 viafb_init_lcd_size();
1958 viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info, 2175 viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index a109de379816..c44399895294 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -700,12 +700,18 @@ struct _lcd_scaling_factor {
700 struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; 700 struct _lcd_ver_scaling_factor lcd_ver_scaling_factor;
701}; 701};
702 702
703struct pll_config {
704 u16 multiplier;
705 u8 divisor;
706 u8 rshift;
707};
708
703struct pll_map { 709struct pll_map {
704 u32 clk; 710 u32 clk;
705 u32 cle266_pll; 711 struct pll_config cle266_pll;
706 u32 k800_pll; 712 struct pll_config k800_pll;
707 u32 cx700_pll; 713 struct pll_config cx700_pll;
708 u32 vx855_pll; 714 struct pll_config vx855_pll;
709}; 715};
710 716
711struct rgbLUT { 717struct rgbLUT {
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h
index c430fa23008a..6010d10b59e8 100644
--- a/drivers/video/via/ioctl.h
+++ b/drivers/video/via/ioctl.h
@@ -35,11 +35,9 @@
35#define VIAFB_GET_SAMM_INFO 0x56494107 /* 'VIA\07' */ 35#define VIAFB_GET_SAMM_INFO 0x56494107 /* 'VIA\07' */
36#define VIAFB_TURN_ON_OUTPUT_DEVICE 0x56494108 /* 'VIA\08' */ 36#define VIAFB_TURN_ON_OUTPUT_DEVICE 0x56494108 /* 'VIA\08' */
37#define VIAFB_TURN_OFF_OUTPUT_DEVICE 0x56494109 /* 'VIA\09' */ 37#define VIAFB_TURN_OFF_OUTPUT_DEVICE 0x56494109 /* 'VIA\09' */
38#define VIAFB_SET_DEVICE 0x5649410A
39#define VIAFB_GET_DEVICE 0x5649410B 38#define VIAFB_GET_DEVICE 0x5649410B
40#define VIAFB_GET_DRIVER_VERSION 0x56494112 /* 'VIA\12' */ 39#define VIAFB_GET_DRIVER_VERSION 0x56494112 /* 'VIA\12' */
41#define VIAFB_GET_CHIP_INFO 0x56494113 /* 'VIA\13' */ 40#define VIAFB_GET_CHIP_INFO 0x56494113 /* 'VIA\13' */
42#define VIAFB_SET_DEVICE_INFO 0x56494114
43#define VIAFB_GET_DEVICE_INFO 0x56494115 41#define VIAFB_GET_DEVICE_INFO 0x56494115
44 42
45#define VIAFB_GET_DEVICE_SUPPORT 0x56494118 43#define VIAFB_GET_DEVICE_SUPPORT 0x56494118
@@ -50,7 +48,6 @@
50#define VIAFB_GET_GAMMA_LUT 0x56494124 48#define VIAFB_GET_GAMMA_LUT 0x56494124
51#define VIAFB_SET_GAMMA_LUT 0x56494125 49#define VIAFB_SET_GAMMA_LUT 0x56494125
52#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126 50#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126
53#define VIAFB_SET_SECOND_MODE 0x56494129
54#define VIAFB_SYNC_SURFACE 0x56494130 51#define VIAFB_SYNC_SURFACE 0x56494130
55#define VIAFB_GET_DRIVER_CAPS 0x56494131 52#define VIAFB_GET_DRIVER_CAPS 0x56494131
56#define VIAFB_GET_IGA_SCALING_INFO 0x56494132 53#define VIAFB_GET_IGA_SCALING_INFO 0x56494132
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 2ab0f156439a..fc25ae30c5f6 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -75,8 +75,6 @@ static void check_diport_of_integrated_lvds(
75static struct display_timing lcd_centering_timging(struct display_timing 75static struct display_timing lcd_centering_timging(struct display_timing
76 mode_crt_reg, 76 mode_crt_reg,
77 struct display_timing panel_crt_reg); 77 struct display_timing panel_crt_reg);
78static void viafb_load_scaling_factor_for_p4m900(int set_hres,
79 int set_vres, int panel_hres, int panel_vres);
80 78
81static int check_lvds_chip(int device_id_subaddr, int device_id) 79static int check_lvds_chip(int device_id_subaddr, int device_id)
82{ 80{
@@ -89,33 +87,8 @@ static int check_lvds_chip(int device_id_subaddr, int device_id)
89void viafb_init_lcd_size(void) 87void viafb_init_lcd_size(void)
90{ 88{
91 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); 89 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
92 DEBUG_MSG(KERN_INFO
93 "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n",
94 viaparinfo->lvds_setting_info->get_lcd_size_method);
95 90
96 switch (viaparinfo->lvds_setting_info->get_lcd_size_method) { 91 fp_id_to_vindex(viafb_lcd_panel_id);
97 case GET_LCD_SIZE_BY_SYSTEM_BIOS:
98 break;
99 case GET_LCD_SZIE_BY_HW_STRAPPING:
100 break;
101 case GET_LCD_SIZE_BY_VGA_BIOS:
102 DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n");
103 fp_id_to_vindex(viafb_lcd_panel_id);
104 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
105 viaparinfo->lvds_setting_info->lcd_panel_id);
106 break;
107 case GET_LCD_SIZE_BY_USER_SETTING:
108 DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n");
109 fp_id_to_vindex(viafb_lcd_panel_id);
110 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
111 viaparinfo->lvds_setting_info->lcd_panel_id);
112 break;
113 default:
114 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n");
115 viaparinfo->lvds_setting_info->lcd_panel_id =
116 LCD_PANEL_ID1_800X600;
117 fp_id_to_vindex(LCD_PANEL_ID1_800X600);
118 }
119 viaparinfo->lvds_setting_info2->lcd_panel_id = 92 viaparinfo->lvds_setting_info2->lcd_panel_id =
120 viaparinfo->lvds_setting_info->lcd_panel_id; 93 viaparinfo->lvds_setting_info->lcd_panel_id;
121 viaparinfo->lvds_setting_info2->lcd_panel_hres = 94 viaparinfo->lvds_setting_info2->lcd_panel_hres =
@@ -437,14 +410,9 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
437 410
438 /* LCD Scaling Enable */ 411 /* LCD Scaling Enable */
439 viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2); 412 viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
440 if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
441 viafb_load_scaling_factor_for_p4m900(set_hres, set_vres,
442 panel_hres, panel_vres);
443 return;
444 }
445 413
446 /* Check if expansion for horizontal */ 414 /* Check if expansion for horizontal */
447 if (set_hres != panel_hres) { 415 if (set_hres < panel_hres) {
448 /* Load Horizontal Scaling Factor */ 416 /* Load Horizontal Scaling Factor */
449 switch (viaparinfo->chip_info->gfx_chip_name) { 417 switch (viaparinfo->chip_info->gfx_chip_name) {
450 case UNICHROME_CLE266: 418 case UNICHROME_CLE266:
@@ -464,6 +432,10 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
464 case UNICHROME_CX700: 432 case UNICHROME_CX700:
465 case UNICHROME_K8M890: 433 case UNICHROME_K8M890:
466 case UNICHROME_P4M890: 434 case UNICHROME_P4M890:
435 case UNICHROME_P4M900:
436 case UNICHROME_CN750:
437 case UNICHROME_VX800:
438 case UNICHROME_VX855:
467 reg_value = 439 reg_value =
468 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); 440 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
469 /* Horizontal scaling enabled */ 441 /* Horizontal scaling enabled */
@@ -483,7 +455,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
483 } 455 }
484 456
485 /* Check if expansion for vertical */ 457 /* Check if expansion for vertical */
486 if (set_vres != panel_vres) { 458 if (set_vres < panel_vres) {
487 /* Load Vertical Scaling Factor */ 459 /* Load Vertical Scaling Factor */
488 switch (viaparinfo->chip_info->gfx_chip_name) { 460 switch (viaparinfo->chip_info->gfx_chip_name) {
489 case UNICHROME_CLE266: 461 case UNICHROME_CLE266:
@@ -503,6 +475,10 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
503 case UNICHROME_CX700: 475 case UNICHROME_CX700:
504 case UNICHROME_K8M890: 476 case UNICHROME_K8M890:
505 case UNICHROME_P4M890: 477 case UNICHROME_P4M890:
478 case UNICHROME_P4M900:
479 case UNICHROME_CN750:
480 case UNICHROME_VX800:
481 case UNICHROME_VX855:
506 reg_value = 482 reg_value =
507 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); 483 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
508 /* Vertical scaling enabled */ 484 /* Vertical scaling enabled */
@@ -648,9 +624,8 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
648 (mode_crt_reg, panel_crt_reg), IGA1); 624 (mode_crt_reg, panel_crt_reg), IGA1);
649 } else { 625 } else {
650 /* Expansion */ 626 /* Expansion */
651 if ((plvds_setting_info->display_method == 627 if (plvds_setting_info->display_method == LCD_EXPANDSION
652 LCD_EXPANDSION) & ((set_hres != panel_hres) 628 && (set_hres < panel_hres || set_vres < panel_vres)) {
653 || (set_vres != panel_vres))) {
654 /* expansion timing IGA2 loaded panel set timing*/ 629 /* expansion timing IGA2 loaded panel set timing*/
655 viafb_load_crtc_timing(panel_crt_reg, IGA2); 630 viafb_load_crtc_timing(panel_crt_reg, IGA2);
656 DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n"); 631 DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
@@ -1139,69 +1114,3 @@ bool viafb_lcd_get_mobile_state(bool *mobile)
1139 return false; 1114 return false;
1140 } 1115 }
1141} 1116}
1142
1143static void viafb_load_scaling_factor_for_p4m900(int set_hres,
1144 int set_vres, int panel_hres, int panel_vres)
1145{
1146 int h_scaling_factor;
1147 int v_scaling_factor;
1148 u8 cra2 = 0;
1149 u8 cr77 = 0;
1150 u8 cr78 = 0;
1151 u8 cr79 = 0;
1152 u8 cr9f = 0;
1153 /* Check if expansion for horizontal */
1154 if (set_hres < panel_hres) {
1155 /* Load Horizontal Scaling Factor */
1156
1157 /* For VIA_K8M800 or later chipsets. */
1158 h_scaling_factor =
1159 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
1160 /* HSCaleFactor[1:0] at CR9F[1:0] */
1161 cr9f = h_scaling_factor & 0x0003;
1162 /* HSCaleFactor[9:2] at CR77[7:0] */
1163 cr77 = (h_scaling_factor & 0x03FC) >> 2;
1164 /* HSCaleFactor[11:10] at CR79[5:4] */
1165 cr79 = (h_scaling_factor & 0x0C00) >> 10;
1166 cr79 <<= 4;
1167
1168 /* Horizontal scaling enabled */
1169 cra2 = 0xC0;
1170
1171 DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n",
1172 h_scaling_factor);
1173 } else {
1174 /* Horizontal scaling disabled */
1175 cra2 = 0x00;
1176 }
1177
1178 /* Check if expansion for vertical */
1179 if (set_vres < panel_vres) {
1180 /* Load Vertical Scaling Factor */
1181
1182 /* For VIA_K8M800 or later chipsets. */
1183 v_scaling_factor =
1184 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
1185
1186 /* Vertical scaling enabled */
1187 cra2 |= 0x08;
1188 /* VSCaleFactor[0] at CR79[3] */
1189 cr79 |= ((v_scaling_factor & 0x0001) << 3);
1190 /* VSCaleFactor[8:1] at CR78[7:0] */
1191 cr78 |= (v_scaling_factor & 0x01FE) >> 1;
1192 /* VSCaleFactor[10:9] at CR79[7:6] */
1193 cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6;
1194
1195 DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n",
1196 v_scaling_factor);
1197 } else {
1198 /* Vertical scaling disabled */
1199 cra2 |= 0x00;
1200 }
1201
1202 viafb_write_reg_mask(CRA2, VIACR, cra2, BIT3 + BIT6 + BIT7);
1203 viafb_write_reg_mask(CR77, VIACR, cr77, 0xFF);
1204 viafb_write_reg_mask(CR78, VIACR, cr78, 0xFF);
1205 viafb_write_reg_mask(CR79, VIACR, cr79, 0xF8);
1206 viafb_write_reg_mask(CR9F, VIACR, cr9f, BIT0 + BIT1);
1207}
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
index 9762ec62b495..b348efc360b8 100644
--- a/drivers/video/via/lcd.h
+++ b/drivers/video/via/lcd.h
@@ -28,11 +28,6 @@
28#define VT3271_DEVICE_ID_REG 0x02 28#define VT3271_DEVICE_ID_REG 0x02
29#define VT3271_DEVICE_ID 0x71 29#define VT3271_DEVICE_ID 0x71
30 30
31#define GET_LCD_SIZE_BY_SYSTEM_BIOS 0x01
32#define GET_LCD_SIZE_BY_VGA_BIOS 0x02
33#define GET_LCD_SZIE_BY_HW_STRAPPING 0x03
34#define GET_LCD_SIZE_BY_USER_SETTING 0x04
35
36/* Definition DVI Panel ID*/ 31/* Definition DVI Panel ID*/
37/* Resolution: 640x480, Channel: single, Dithering: Enable */ 32/* Resolution: 640x480, Channel: single, Dithering: Enable */
38#define LCD_PANEL_ID0_640X480 0x00 33#define LCD_PANEL_ID0_640X480 0x00
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 7f0de7f006ad..2cbe1031b421 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -631,7 +631,6 @@
631#define CLK_25_175M 25175000 631#define CLK_25_175M 25175000
632#define CLK_26_880M 26880000 632#define CLK_26_880M 26880000
633#define CLK_29_581M 29581000 633#define CLK_29_581M 29581000
634#define CLK_31_490M 31490000
635#define CLK_31_500M 31500000 634#define CLK_31_500M 31500000
636#define CLK_31_728M 31728000 635#define CLK_31_728M 31728000
637#define CLK_32_668M 32688000 636#define CLK_32_668M 32688000
@@ -676,7 +675,6 @@
676#define CLK_119_000M 119000000 675#define CLK_119_000M 119000000
677#define CLK_121_750M 121750000 /* 121.704MHz */ 676#define CLK_121_750M 121750000 /* 121.704MHz */
678#define CLK_125_104M 125104000 677#define CLK_125_104M 125104000
679#define CLK_133_308M 133308000
680#define CLK_135_000M 135000000 678#define CLK_135_000M 135000000
681#define CLK_136_700M 136700000 679#define CLK_136_700M 136700000
682#define CLK_138_400M 138400000 680#define CLK_138_400M 138400000
@@ -699,313 +697,6 @@
699#define CLK_172_798M 172798000 697#define CLK_172_798M 172798000
700#define CLK_122_614M 122614000 698#define CLK_122_614M 122614000
701 699
702/* CLE266 PLL value
703*/
704#define CLE266_PLL_25_175M 0x0000C763
705#define CLE266_PLL_26_880M 0x0000440F
706#define CLE266_PLL_29_581M 0x00008421
707#define CLE266_PLL_31_490M 0x00004721
708#define CLE266_PLL_31_500M 0x0000C3B5
709#define CLE266_PLL_31_728M 0x0000471F
710#define CLE266_PLL_32_668M 0x0000C449
711#define CLE266_PLL_36_000M 0x0000C5E5
712#define CLE266_PLL_40_000M 0x0000C459
713#define CLE266_PLL_41_291M 0x00004417
714#define CLE266_PLL_43_163M 0x0000C579
715#define CLE266_PLL_45_250M 0x0000C57F /* 45.46MHz */
716#define CLE266_PLL_46_000M 0x0000875A
717#define CLE266_PLL_46_996M 0x0000C4E9
718#define CLE266_PLL_48_000M 0x00001443
719#define CLE266_PLL_48_875M 0x00001D63
720#define CLE266_PLL_49_500M 0x00008653
721#define CLE266_PLL_52_406M 0x0000C475
722#define CLE266_PLL_52_977M 0x00004525
723#define CLE266_PLL_56_250M 0x000047B7
724#define CLE266_PLL_60_466M 0x0000494C
725#define CLE266_PLL_61_500M 0x00001456
726#define CLE266_PLL_65_000M 0x000086ED
727#define CLE266_PLL_65_178M 0x0000855B
728#define CLE266_PLL_66_750M 0x0000844B /* 67.116MHz */
729#define CLE266_PLL_68_179M 0x00000413
730#define CLE266_PLL_69_924M 0x00001153
731#define CLE266_PLL_70_159M 0x00001462
732#define CLE266_PLL_72_000M 0x00001879
733#define CLE266_PLL_74_270M 0x00004853
734#define CLE266_PLL_78_750M 0x00004321
735#define CLE266_PLL_80_136M 0x0000051C
736#define CLE266_PLL_83_375M 0x0000C25D
737#define CLE266_PLL_83_950M 0x00000729
738#define CLE266_PLL_84_750M 0x00008576 /* 84.537MHz */
739#define CLE266_PLL_85_860M 0x00004754
740#define CLE266_PLL_88_750M 0x0000051F
741#define CLE266_PLL_94_500M 0x00000521
742#define CLE266_PLL_97_750M 0x00004652
743#define CLE266_PLL_101_000M 0x0000497F
744#define CLE266_PLL_106_500M 0x00008477 /* 106.491463 MHz */
745#define CLE266_PLL_108_000M 0x00008479
746#define CLE266_PLL_113_309M 0x00000C5F
747#define CLE266_PLL_118_840M 0x00004553
748#define CLE266_PLL_119_000M 0x00000D6C
749#define CLE266_PLL_121_750M 0x00004555 /* 121.704MHz */
750#define CLE266_PLL_125_104M 0x000006B5
751#define CLE266_PLL_133_308M 0x0000465F
752#define CLE266_PLL_135_000M 0x0000455E
753#define CLE266_PLL_136_700M 0x00000C73
754#define CLE266_PLL_138_400M 0x00000957
755#define CLE266_PLL_146_760M 0x00004567
756#define CLE266_PLL_148_500M 0x00000853
757#define CLE266_PLL_153_920M 0x00000856
758#define CLE266_PLL_156_000M 0x0000456D
759#define CLE266_PLL_157_500M 0x000005B7
760#define CLE266_PLL_162_000M 0x00004571
761#define CLE266_PLL_187_000M 0x00000976
762#define CLE266_PLL_193_295M 0x0000086C
763#define CLE266_PLL_202_500M 0x00000763
764#define CLE266_PLL_204_000M 0x00000764
765#define CLE266_PLL_218_500M 0x0000065C
766#define CLE266_PLL_234_000M 0x00000662
767#define CLE266_PLL_267_250M 0x00000670
768#define CLE266_PLL_297_500M 0x000005E6
769#define CLE266_PLL_74_481M 0x0000051A
770#define CLE266_PLL_172_798M 0x00004579
771#define CLE266_PLL_122_614M 0x0000073C
772
773/* K800 PLL value
774*/
775#define K800_PLL_25_175M 0x00539001
776#define K800_PLL_26_880M 0x001C8C80
777#define K800_PLL_29_581M 0x00409080
778#define K800_PLL_31_490M 0x006F9001
779#define K800_PLL_31_500M 0x008B9002
780#define K800_PLL_31_728M 0x00AF9003
781#define K800_PLL_32_668M 0x00909002
782#define K800_PLL_36_000M 0x009F9002
783#define K800_PLL_40_000M 0x00578C02
784#define K800_PLL_41_291M 0x00438C01
785#define K800_PLL_43_163M 0x00778C03
786#define K800_PLL_45_250M 0x007D8C83 /* 45.46MHz */
787#define K800_PLL_46_000M 0x00658C02
788#define K800_PLL_46_996M 0x00818C83
789#define K800_PLL_48_000M 0x00848C83
790#define K800_PLL_48_875M 0x00508C81
791#define K800_PLL_49_500M 0x00518C01
792#define K800_PLL_52_406M 0x00738C02
793#define K800_PLL_52_977M 0x00928C83
794#define K800_PLL_56_250M 0x007C8C02
795#define K800_PLL_60_466M 0x00A78C83
796#define K800_PLL_61_500M 0x00AA8C83
797#define K800_PLL_65_000M 0x006B8C01
798#define K800_PLL_65_178M 0x00B48C83
799#define K800_PLL_66_750M 0x00948C82 /* 67.116MHz */
800#define K800_PLL_68_179M 0x00708C01
801#define K800_PLL_69_924M 0x00C18C83
802#define K800_PLL_70_159M 0x00C28C83
803#define K800_PLL_72_000M 0x009F8C82
804#define K800_PLL_74_270M 0x00ce0c03
805#define K800_PLL_78_750M 0x00408801
806#define K800_PLL_80_136M 0x00428801
807#define K800_PLL_83_375M 0x005B0882
808#define K800_PLL_83_950M 0x00738803
809#define K800_PLL_84_750M 0x00748883 /* 84.477MHz */
810#define K800_PLL_85_860M 0x00768883
811#define K800_PLL_88_750M 0x007A8883
812#define K800_PLL_94_500M 0x00828803
813#define K800_PLL_97_750M 0x00878883
814#define K800_PLL_101_000M 0x008B8883
815#define K800_PLL_106_500M 0x00758882 /* 106.491463 MHz */
816#define K800_PLL_108_000M 0x00778882
817#define K800_PLL_113_309M 0x005D8881
818#define K800_PLL_118_840M 0x00A48883
819#define K800_PLL_119_000M 0x00838882
820#define K800_PLL_121_750M 0x00A88883 /* 121.704MHz */
821#define K800_PLL_125_104M 0x00688801
822#define K800_PLL_133_308M 0x005D8801
823#define K800_PLL_135_000M 0x001A4081
824#define K800_PLL_136_700M 0x00BD8883
825#define K800_PLL_138_400M 0x00728881
826#define K800_PLL_146_760M 0x00CC8883
827#define K800_PLL_148_500M 0x00ce0803
828#define K800_PLL_153_920M 0x00548482
829#define K800_PLL_156_000M 0x006B8483
830#define K800_PLL_157_500M 0x00142080
831#define K800_PLL_162_000M 0x006F8483
832#define K800_PLL_187_000M 0x00818483
833#define K800_PLL_193_295M 0x004F8481
834#define K800_PLL_202_500M 0x00538481
835#define K800_PLL_204_000M 0x008D8483
836#define K800_PLL_218_500M 0x00978483
837#define K800_PLL_234_000M 0x00608401
838#define K800_PLL_267_250M 0x006E8481
839#define K800_PLL_297_500M 0x00A48402
840#define K800_PLL_74_481M 0x007B8C81
841#define K800_PLL_172_798M 0x00778483
842#define K800_PLL_122_614M 0x00878882
843
844/* PLL for VT3324 */
845#define CX700_25_175M 0x008B1003
846#define CX700_26_719M 0x00931003
847#define CX700_26_880M 0x00941003
848#define CX700_29_581M 0x00A49003
849#define CX700_31_490M 0x00AE1003
850#define CX700_31_500M 0x00AE1003
851#define CX700_31_728M 0x00AF1003
852#define CX700_32_668M 0x00B51003
853#define CX700_36_000M 0x00C81003
854#define CX700_40_000M 0x006E0C03
855#define CX700_41_291M 0x00710C03
856#define CX700_43_163M 0x00770C03
857#define CX700_45_250M 0x007D0C03 /* 45.46MHz */
858#define CX700_46_000M 0x007F0C03
859#define CX700_46_996M 0x00818C83
860#define CX700_48_000M 0x00840C03
861#define CX700_48_875M 0x00508C81
862#define CX700_49_500M 0x00880C03
863#define CX700_52_406M 0x00730C02
864#define CX700_52_977M 0x00920C03
865#define CX700_56_250M 0x009B0C03
866#define CX700_60_466M 0x00460C00
867#define CX700_61_500M 0x00AA0C03
868#define CX700_65_000M 0x006B0C01
869#define CX700_65_178M 0x006B0C01
870#define CX700_66_750M 0x00940C02 /*67.116MHz */
871#define CX700_68_179M 0x00BC0C03
872#define CX700_69_924M 0x00C10C03
873#define CX700_70_159M 0x00C20C03
874#define CX700_72_000M 0x009F0C02
875#define CX700_74_270M 0x00CE0C03
876#define CX700_74_481M 0x00CE0C03
877#define CX700_78_750M 0x006C0803
878#define CX700_80_136M 0x006E0803
879#define CX700_83_375M 0x005B0882
880#define CX700_83_950M 0x00730803
881#define CX700_84_750M 0x00740803 /* 84.537Mhz */
882#define CX700_85_860M 0x00760803
883#define CX700_88_750M 0x00AC8885
884#define CX700_94_500M 0x00820803
885#define CX700_97_750M 0x00870803
886#define CX700_101_000M 0x008B0803
887#define CX700_106_500M 0x00750802
888#define CX700_108_000M 0x00950803
889#define CX700_113_309M 0x005D0801
890#define CX700_118_840M 0x00A40803
891#define CX700_119_000M 0x00830802
892#define CX700_121_750M 0x00420800 /* 121.704MHz */
893#define CX700_125_104M 0x00AD0803
894#define CX700_133_308M 0x00930802
895#define CX700_135_000M 0x00950802
896#define CX700_136_700M 0x00BD0803
897#define CX700_138_400M 0x00720801
898#define CX700_146_760M 0x00CC0803
899#define CX700_148_500M 0x00a40802
900#define CX700_153_920M 0x00540402
901#define CX700_156_000M 0x006B0403
902#define CX700_157_500M 0x006C0403
903#define CX700_162_000M 0x006F0403
904#define CX700_172_798M 0x00770403
905#define CX700_187_000M 0x00810403
906#define CX700_193_295M 0x00850403
907#define CX700_202_500M 0x008C0403
908#define CX700_204_000M 0x008D0403
909#define CX700_218_500M 0x00970403
910#define CX700_234_000M 0x00600401
911#define CX700_267_250M 0x00B90403
912#define CX700_297_500M 0x00CE0403
913#define CX700_122_614M 0x00870802
914
915/* PLL for VX855 */
916#define VX855_22_000M 0x007B1005
917#define VX855_25_175M 0x008D1005
918#define VX855_26_719M 0x00961005
919#define VX855_26_880M 0x00961005
920#define VX855_27_000M 0x00971005
921#define VX855_29_581M 0x00A51005
922#define VX855_29_829M 0x00641003
923#define VX855_31_490M 0x00B01005
924#define VX855_31_500M 0x00B01005
925#define VX855_31_728M 0x008E1004
926#define VX855_32_668M 0x00921004
927#define VX855_36_000M 0x00A11004
928#define VX855_40_000M 0x00700C05
929#define VX855_41_291M 0x00730C05
930#define VX855_43_163M 0x00790C05
931#define VX855_45_250M 0x007F0C05 /* 45.46MHz */
932#define VX855_46_000M 0x00670C04
933#define VX855_46_996M 0x00690C04
934#define VX855_48_000M 0x00860C05
935#define VX855_48_875M 0x00890C05
936#define VX855_49_500M 0x00530C03
937#define VX855_52_406M 0x00580C03
938#define VX855_52_977M 0x00940C05
939#define VX855_56_250M 0x009D0C05
940#define VX855_57_275M 0x009D8C85 /* Used by XO panel */
941#define VX855_60_466M 0x00A90C05
942#define VX855_61_500M 0x00AC0C05
943#define VX855_65_000M 0x006D0C03
944#define VX855_65_178M 0x00B60C05
945#define VX855_66_750M 0x00700C03 /*67.116MHz */
946#define VX855_67_295M 0x00BC0C05
947#define VX855_68_179M 0x00BF0C05
948#define VX855_68_369M 0x00BF0C05
949#define VX855_69_924M 0x00C30C05
950#define VX855_70_159M 0x00C30C05
951#define VX855_72_000M 0x00A10C04
952#define VX855_73_023M 0x00CC0C05
953#define VX855_74_481M 0x00D10C05
954#define VX855_78_750M 0x006E0805
955#define VX855_79_466M 0x006F0805
956#define VX855_80_136M 0x00700805
957#define VX855_81_627M 0x00720805
958#define VX855_83_375M 0x00750805
959#define VX855_83_527M 0x00750805
960#define VX855_83_950M 0x00750805
961#define VX855_84_537M 0x00760805
962#define VX855_84_750M 0x00760805 /* 84.537Mhz */
963#define VX855_85_500M 0x00760805 /* 85.909080 MHz*/
964#define VX855_85_860M 0x00760805
965#define VX855_85_909M 0x00760805
966#define VX855_88_750M 0x007C0805
967#define VX855_89_489M 0x007D0805
968#define VX855_94_500M 0x00840805
969#define VX855_96_648M 0x00870805
970#define VX855_97_750M 0x00890805
971#define VX855_101_000M 0x008D0805
972#define VX855_106_500M 0x00950805
973#define VX855_108_000M 0x00970805
974#define VX855_110_125M 0x00990805
975#define VX855_112_000M 0x009D0805
976#define VX855_113_309M 0x009F0805
977#define VX855_115_000M 0x00A10805
978#define VX855_118_840M 0x00A60805
979#define VX855_119_000M 0x00A70805
980#define VX855_121_750M 0x00AA0805 /* 121.704MHz */
981#define VX855_122_614M 0x00AC0805
982#define VX855_126_266M 0x00B10805
983#define VX855_130_250M 0x00B60805 /* 130.250 */
984#define VX855_135_000M 0x00BD0805
985#define VX855_136_700M 0x00BF0805
986#define VX855_137_750M 0x00C10805
987#define VX855_138_400M 0x00C20805
988#define VX855_144_300M 0x00CA0805
989#define VX855_146_760M 0x00CE0805
990#define VX855_148_500M 0x00D00805
991#define VX855_153_920M 0x00540402
992#define VX855_156_000M 0x006C0405
993#define VX855_156_867M 0x006E0405
994#define VX855_157_500M 0x006E0405
995#define VX855_162_000M 0x00710405
996#define VX855_172_798M 0x00790405
997#define VX855_187_000M 0x00830405
998#define VX855_193_295M 0x00870405
999#define VX855_202_500M 0x008E0405
1000#define VX855_204_000M 0x008F0405
1001#define VX855_218_500M 0x00990405
1002#define VX855_229_500M 0x00A10405
1003#define VX855_234_000M 0x00A40405
1004#define VX855_267_250M 0x00BB0405
1005#define VX855_297_500M 0x00D00405
1006#define VX855_339_500M 0x00770005
1007#define VX855_340_772M 0x00770005
1008
1009 700
1010/* Definition CRTC Timing Index */ 701/* Definition CRTC Timing Index */
1011#define H_TOTAL_INDEX 0 702#define H_TOTAL_INDEX 0
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c
index e8cfe8392110..66f403033111 100644
--- a/drivers/video/via/via-core.c
+++ b/drivers/video/via/via-core.c
@@ -64,7 +64,7 @@ static inline int viafb_mmio_read(int reg)
64 */ 64 */
65static u32 viafb_enabled_ints; 65static u32 viafb_enabled_ints;
66 66
67static void viafb_int_init(void) 67static void __devinit viafb_int_init(void)
68{ 68{
69 viafb_enabled_ints = 0; 69 viafb_enabled_ints = 0;
70 70
@@ -489,7 +489,7 @@ out_unmap:
489 return ret; 489 return ret;
490} 490}
491 491
492static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev) 492static void via_pci_teardown_mmio(struct viafb_dev *vdev)
493{ 493{
494 iounmap(vdev->fbmem); 494 iounmap(vdev->fbmem);
495 iounmap(vdev->engine_mmio); 495 iounmap(vdev->engine_mmio);
@@ -548,7 +548,7 @@ static int __devinit via_setup_subdevs(struct viafb_dev *vdev)
548 return 0; 548 return 0;
549} 549}
550 550
551static void __devexit via_teardown_subdevs(void) 551static void via_teardown_subdevs(void)
552{ 552{
553 int i; 553 int i;
554 554
@@ -613,22 +613,24 @@ static void __devexit via_pci_remove(struct pci_dev *pdev)
613static struct pci_device_id via_pci_table[] __devinitdata = { 613static struct pci_device_id via_pci_table[] __devinitdata = {
614 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID), 614 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID),
615 .driver_data = UNICHROME_CLE266 }, 615 .driver_data = UNICHROME_CLE266 },
616 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID),
617 .driver_data = UNICHROME_PM800 },
618 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID), 616 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
619 .driver_data = UNICHROME_K400 }, 617 .driver_data = UNICHROME_K400 },
620 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID), 618 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID),
621 .driver_data = UNICHROME_K800 }, 619 .driver_data = UNICHROME_K800 },
622 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID), 620 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID),
621 .driver_data = UNICHROME_PM800 },
622 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN700_DID),
623 .driver_data = UNICHROME_CN700 }, 623 .driver_data = UNICHROME_CN700 },
624 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
625 .driver_data = UNICHROME_K8M890 },
626 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID), 624 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID),
627 .driver_data = UNICHROME_CX700 }, 625 .driver_data = UNICHROME_CX700 },
628 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
629 .driver_data = UNICHROME_P4M900 },
630 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID), 626 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID),
631 .driver_data = UNICHROME_CN750 }, 627 .driver_data = UNICHROME_CN750 },
628 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
629 .driver_data = UNICHROME_K8M890 },
630 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID),
631 .driver_data = UNICHROME_P4M890 },
632 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
633 .driver_data = UNICHROME_P4M900 },
632 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID), 634 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID),
633 .driver_data = UNICHROME_VX800 }, 635 .driver_data = UNICHROME_VX800 },
634 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), 636 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
diff --git a/drivers/video/via/via-gpio.c b/drivers/video/via/via-gpio.c
index 595516aea691..39acb37e7a1d 100644
--- a/drivers/video/via/via-gpio.c
+++ b/drivers/video/via/via-gpio.c
@@ -73,7 +73,7 @@ struct viafb_gpio_cfg {
73 struct gpio_chip gpio_chip; 73 struct gpio_chip gpio_chip;
74 struct viafb_dev *vdev; 74 struct viafb_dev *vdev;
75 struct viafb_gpio *active_gpios[VIAFB_NUM_GPIOS]; 75 struct viafb_gpio *active_gpios[VIAFB_NUM_GPIOS];
76 char *gpio_names[VIAFB_NUM_GPIOS]; 76 const char *gpio_names[VIAFB_NUM_GPIOS];
77}; 77};
78 78
79/* 79/*
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 1082541358f0..bdd0e4130f4e 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -49,11 +49,6 @@ char *viafb_active_dev;
49char *viafb_lcd_port = ""; 49char *viafb_lcd_port = "";
50char *viafb_dvi_port = ""; 50char *viafb_dvi_port = "";
51 51
52static void viafb_set_device(struct device_t active_dev);
53static int apply_device_setting(struct viafb_ioctl_setting setting_info,
54 struct fb_info *info);
55static void apply_second_mode_setting(struct fb_var_screeninfo
56 *sec_var);
57static void retrieve_device_setting(struct viafb_ioctl_setting 52static void retrieve_device_setting(struct viafb_ioctl_setting
58 *setting_info); 53 *setting_info);
59static int viafb_pan_display(struct fb_var_screeninfo *var, 54static int viafb_pan_display(struct fb_var_screeninfo *var,
@@ -221,9 +216,9 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
221 216
222 /* Adjust var according to our driver's own table */ 217 /* Adjust var according to our driver's own table */
223 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); 218 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry);
224 if (info->var.accel_flags & FB_ACCELF_TEXT && 219 if (var->accel_flags & FB_ACCELF_TEXT &&
225 !ppar->shared->vdev->engine_mmio) 220 !ppar->shared->vdev->engine_mmio)
226 info->var.accel_flags = 0; 221 var->accel_flags = 0;
227 222
228 return 0; 223 return 0;
229} 224}
@@ -234,6 +229,7 @@ static int viafb_set_par(struct fb_info *info)
234 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL; 229 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
235 DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); 230 DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
236 231
232 viafb_update_fix(info);
237 viapar->depth = fb_get_color_depth(&info->var, &info->fix); 233 viapar->depth = fb_get_color_depth(&info->var, &info->fix);
238 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres, 234 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
239 viafbinfo->var.bits_per_pixel, viafb_refresh, 0); 235 viafbinfo->var.bits_per_pixel, viafb_refresh, 0);
@@ -257,7 +253,6 @@ static int viafb_set_par(struct fb_info *info)
257 } 253 }
258 254
259 if (vmode_entry) { 255 if (vmode_entry) {
260 viafb_update_fix(info);
261 if (viafb_dual_fb && viapar->iga_path == IGA2) 256 if (viafb_dual_fb && viapar->iga_path == IGA2)
262 viafb_bpp1 = info->var.bits_per_pixel; 257 viafb_bpp1 = info->var.bits_per_pixel;
263 else 258 else
@@ -478,13 +473,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
478 if (gpu32 & LCD_Device) 473 if (gpu32 & LCD_Device)
479 viafb_lcd_disable(); 474 viafb_lcd_disable();
480 break; 475 break;
481 case VIAFB_SET_DEVICE:
482 if (copy_from_user(&u.active_dev, (void *)argp,
483 sizeof(u.active_dev)))
484 return -EFAULT;
485 viafb_set_device(u.active_dev);
486 viafb_set_par(info);
487 break;
488 case VIAFB_GET_DEVICE: 476 case VIAFB_GET_DEVICE:
489 u.active_dev.crt = viafb_CRT_ON; 477 u.active_dev.crt = viafb_CRT_ON;
490 u.active_dev.dvi = viafb_DVI_ON; 478 u.active_dev.dvi = viafb_DVI_ON;
@@ -527,21 +515,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
527 515
528 break; 516 break;
529 517
530 case VIAFB_SET_DEVICE_INFO:
531 if (copy_from_user(&u.viafb_setting,
532 argp, sizeof(u.viafb_setting)))
533 return -EFAULT;
534 if (apply_device_setting(u.viafb_setting, info) < 0)
535 return -EINVAL;
536
537 break;
538
539 case VIAFB_SET_SECOND_MODE:
540 if (copy_from_user(&u.sec_var, argp, sizeof(u.sec_var)))
541 return -EFAULT;
542 apply_second_mode_setting(&u.sec_var);
543 break;
544
545 case VIAFB_GET_DEVICE_INFO: 518 case VIAFB_GET_DEVICE_INFO:
546 519
547 retrieve_device_setting(&u.viafb_setting); 520 retrieve_device_setting(&u.viafb_setting);
@@ -913,112 +886,6 @@ static int viafb_sync(struct fb_info *info)
913 return 0; 886 return 0;
914} 887}
915 888
916static void check_available_device_to_enable(int device_id)
917{
918 int device_num = 0;
919
920 /* Initialize: */
921 viafb_CRT_ON = STATE_OFF;
922 viafb_DVI_ON = STATE_OFF;
923 viafb_LCD_ON = STATE_OFF;
924 viafb_LCD2_ON = STATE_OFF;
925 viafb_DeviceStatus = None_Device;
926
927 if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
928 viafb_CRT_ON = STATE_ON;
929 device_num++;
930 viafb_DeviceStatus |= CRT_Device;
931 }
932
933 if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
934 viafb_DVI_ON = STATE_ON;
935 device_num++;
936 viafb_DeviceStatus |= DVI_Device;
937 }
938
939 if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
940 viafb_LCD_ON = STATE_ON;
941 device_num++;
942 viafb_DeviceStatus |= LCD_Device;
943 }
944
945 if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
946 viafb_LCD2_ON = STATE_ON;
947 device_num++;
948 viafb_DeviceStatus |= LCD2_Device;
949 }
950
951 if (viafb_DeviceStatus == None_Device) {
952 /* Use CRT as default active device: */
953 viafb_CRT_ON = STATE_ON;
954 viafb_DeviceStatus = CRT_Device;
955 }
956 DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus);
957}
958
959static void viafb_set_device(struct device_t active_dev)
960{
961 /* Check available device to enable: */
962 int device_id = None_Device;
963 if (active_dev.crt)
964 device_id |= CRT_Device;
965 if (active_dev.dvi)
966 device_id |= DVI_Device;
967 if (active_dev.lcd)
968 device_id |= LCD_Device;
969
970 check_available_device_to_enable(device_id);
971
972 /* Check property of LCD: */
973 if (viafb_LCD_ON) {
974 if (active_dev.lcd_dsp_cent) {
975 viaparinfo->lvds_setting_info->display_method =
976 viafb_lcd_dsp_method = LCD_CENTERING;
977 } else {
978 viaparinfo->lvds_setting_info->display_method =
979 viafb_lcd_dsp_method = LCD_EXPANDSION;
980 }
981
982 if (active_dev.lcd_mode == LCD_SPWG) {
983 viaparinfo->lvds_setting_info->lcd_mode =
984 viafb_lcd_mode = LCD_SPWG;
985 } else {
986 viaparinfo->lvds_setting_info->lcd_mode =
987 viafb_lcd_mode = LCD_OPENLDI;
988 }
989
990 if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) {
991 viafb_lcd_panel_id = active_dev.lcd_panel_id;
992 viafb_init_lcd_size();
993 }
994 }
995
996 /* Check property of mode: */
997 if (!active_dev.xres1)
998 viafb_second_xres = 640;
999 else
1000 viafb_second_xres = active_dev.xres1;
1001 if (!active_dev.yres1)
1002 viafb_second_yres = 480;
1003 else
1004 viafb_second_yres = active_dev.yres1;
1005 if (active_dev.bpp != 0)
1006 viafb_bpp = active_dev.bpp;
1007 if (active_dev.bpp1 != 0)
1008 viafb_bpp1 = active_dev.bpp1;
1009 if (active_dev.refresh != 0)
1010 viafb_refresh = active_dev.refresh;
1011 if (active_dev.refresh1 != 0)
1012 viafb_refresh1 = active_dev.refresh1;
1013 if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON))
1014 viafb_SAMM_ON = active_dev.samm;
1015 viafb_primary_dev = active_dev.primary_dev;
1016
1017 via_set_primary_address(0);
1018 via_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
1019 viafb_set_iga_path();
1020}
1021
1022static int get_primary_device(void) 889static int get_primary_device(void)
1023{ 890{
1024 int primary_device = 0; 891 int primary_device = 0;
@@ -1060,124 +927,6 @@ static int get_primary_device(void)
1060 return primary_device; 927 return primary_device;
1061} 928}
1062 929
1063static void apply_second_mode_setting(struct fb_var_screeninfo
1064 *sec_var)
1065{
1066 u32 htotal, vtotal, long_refresh;
1067
1068 htotal = sec_var->xres + sec_var->left_margin +
1069 sec_var->right_margin + sec_var->hsync_len;
1070 vtotal = sec_var->yres + sec_var->upper_margin +
1071 sec_var->lower_margin + sec_var->vsync_len;
1072 if ((sec_var->xres_virtual * (sec_var->bits_per_pixel >> 3)) & 0x1F) {
1073 /*Is 32 bytes alignment? */
1074 /*32 pixel alignment */
1075 sec_var->xres_virtual = (sec_var->xres_virtual + 31) & ~31;
1076 }
1077
1078 htotal = sec_var->xres + sec_var->left_margin +
1079 sec_var->right_margin + sec_var->hsync_len;
1080 vtotal = sec_var->yres + sec_var->upper_margin +
1081 sec_var->lower_margin + sec_var->vsync_len;
1082 long_refresh = 1000000000UL / sec_var->pixclock * 1000;
1083 long_refresh /= (htotal * vtotal);
1084
1085 viafb_second_xres = sec_var->xres;
1086 viafb_second_yres = sec_var->yres;
1087 viafb_second_virtual_xres = sec_var->xres_virtual;
1088 viafb_second_virtual_yres = sec_var->yres_virtual;
1089 viafb_bpp1 = sec_var->bits_per_pixel;
1090 viafb_refresh1 = viafb_get_refresh(sec_var->xres, sec_var->yres,
1091 long_refresh);
1092}
1093
1094static int apply_device_setting(struct viafb_ioctl_setting setting_info,
1095 struct fb_info *info)
1096{
1097 int need_set_mode = 0;
1098 DEBUG_MSG(KERN_INFO "apply_device_setting\n");
1099
1100 if (setting_info.device_flag) {
1101 need_set_mode = 1;
1102 check_available_device_to_enable(setting_info.device_status);
1103 }
1104
1105 /* Unlock LCD's operation according to LCD flag
1106 and check if the setting value is valid. */
1107 /* If the value is valid, apply the new setting value to the device. */
1108 if (viafb_LCD_ON) {
1109 if (setting_info.lcd_operation_flag & OP_LCD_CENTERING) {
1110 need_set_mode = 1;
1111 if (setting_info.lcd_attributes.display_center) {
1112 /* Centering */
1113 viaparinfo->lvds_setting_info->display_method =
1114 LCD_CENTERING;
1115 viafb_lcd_dsp_method = LCD_CENTERING;
1116 viaparinfo->lvds_setting_info2->display_method =
1117 viafb_lcd_dsp_method = LCD_CENTERING;
1118 } else {
1119 /* expandsion */
1120 viaparinfo->lvds_setting_info->display_method =
1121 LCD_EXPANDSION;
1122 viafb_lcd_dsp_method = LCD_EXPANDSION;
1123 viaparinfo->lvds_setting_info2->display_method =
1124 LCD_EXPANDSION;
1125 viafb_lcd_dsp_method = LCD_EXPANDSION;
1126 }
1127 }
1128
1129 if (setting_info.lcd_operation_flag & OP_LCD_MODE) {
1130 need_set_mode = 1;
1131 if (setting_info.lcd_attributes.lcd_mode ==
1132 LCD_SPWG) {
1133 viaparinfo->lvds_setting_info->lcd_mode =
1134 viafb_lcd_mode = LCD_SPWG;
1135 } else {
1136 viaparinfo->lvds_setting_info->lcd_mode =
1137 viafb_lcd_mode = LCD_OPENLDI;
1138 }
1139 viaparinfo->lvds_setting_info2->lcd_mode =
1140 viaparinfo->lvds_setting_info->lcd_mode;
1141 }
1142
1143 if (setting_info.lcd_operation_flag & OP_LCD_PANEL_ID) {
1144 need_set_mode = 1;
1145 if (setting_info.lcd_attributes.panel_id <=
1146 LCD_PANEL_ID_MAXIMUM) {
1147 viafb_lcd_panel_id =
1148 setting_info.lcd_attributes.panel_id;
1149 viafb_init_lcd_size();
1150 }
1151 }
1152 }
1153
1154 if (0 != (setting_info.samm_status & OP_SAMM)) {
1155 setting_info.samm_status =
1156 setting_info.samm_status & (~OP_SAMM);
1157 if (setting_info.samm_status == 0
1158 || setting_info.samm_status == 1) {
1159 viafb_SAMM_ON = setting_info.samm_status;
1160
1161 if (viafb_SAMM_ON)
1162 viafb_primary_dev = setting_info.primary_device;
1163
1164 via_set_primary_address(0);
1165 via_set_secondary_address(viafb_SAMM_ON ?
1166 viafb_second_offset : 0);
1167 viafb_set_iga_path();
1168 }
1169 need_set_mode = 1;
1170 }
1171
1172 if (!need_set_mode) {
1173 ;
1174 } else {
1175 viafb_set_iga_path();
1176 viafb_set_par(info);
1177 }
1178 return true;
1179}
1180
1181static void retrieve_device_setting(struct viafb_ioctl_setting 930static void retrieve_device_setting(struct viafb_ioctl_setting
1182 *setting_info) 931 *setting_info)
1183{ 932{
@@ -1776,10 +1525,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1776 parse_lcd_port(); 1525 parse_lcd_port();
1777 parse_dvi_port(); 1526 parse_dvi_port();
1778 1527
1779 /* for dual-fb must viafb_SAMM_ON=1 and viafb_dual_fb=1 */
1780 if (!viafb_SAMM_ON)
1781 viafb_dual_fb = 0;
1782
1783 viafb_init_chip_info(vdev->chip_type); 1528 viafb_init_chip_info(vdev->chip_type);
1784 /* 1529 /*
1785 * The framebuffer will have been successfully mapped by 1530 * The framebuffer will have been successfully mapped by
@@ -1823,30 +1568,13 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1823 parse_mode(viafb_mode1, &viafb_second_xres, 1568 parse_mode(viafb_mode1, &viafb_second_xres,
1824 &viafb_second_yres); 1569 &viafb_second_yres);
1825 1570
1826 if (0 == viafb_second_virtual_xres) { 1571 viafb_second_virtual_xres = viafb_second_xres;
1827 switch (viafb_second_xres) { 1572 viafb_second_virtual_yres = viafb_second_yres;
1828 case 1400:
1829 viafb_second_virtual_xres = 1408;
1830 break;
1831 default:
1832 viafb_second_virtual_xres = viafb_second_xres;
1833 break;
1834 }
1835 }
1836 if (0 == viafb_second_virtual_yres)
1837 viafb_second_virtual_yres = viafb_second_yres;
1838 } 1573 }
1839 1574
1840 default_var.xres = default_xres; 1575 default_var.xres = default_xres;
1841 default_var.yres = default_yres; 1576 default_var.yres = default_yres;
1842 switch (default_xres) { 1577 default_var.xres_virtual = default_xres;
1843 case 1400:
1844 default_var.xres_virtual = 1408;
1845 break;
1846 default:
1847 default_var.xres_virtual = default_xres;
1848 break;
1849 }
1850 default_var.yres_virtual = default_yres; 1578 default_var.yres_virtual = default_yres;
1851 default_var.bits_per_pixel = viafb_bpp; 1579 default_var.bits_per_pixel = viafb_bpp;
1852 default_var.pixclock = 1580 default_var.pixclock =
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index e66b8b19ce5d..d8b12c32e3ef 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -858,9 +858,9 @@ unsigned long w100fb_gpio_read(int port)
858void w100fb_gpio_write(int port, unsigned long value) 858void w100fb_gpio_write(int port, unsigned long value)
859{ 859{
860 if (port==W100_GPIO_PORT_A) 860 if (port==W100_GPIO_PORT_A)
861 value = writel(value, remapped_regs + mmGPIO_DATA); 861 writel(value, remapped_regs + mmGPIO_DATA);
862 else 862 else
863 value = writel(value, remapped_regs + mmGPIO_DATA2); 863 writel(value, remapped_regs + mmGPIO_DATA2);
864} 864}
865EXPORT_SYMBOL(w100fb_gpio_read); 865EXPORT_SYMBOL(w100fb_gpio_read);
866EXPORT_SYMBOL(w100fb_gpio_write); 866EXPORT_SYMBOL(w100fb_gpio_write);