aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 10:56:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 10:56:52 -0400
commit4cc4d24efce4672f9b0e7fa27963770ae602998f (patch)
treee69e7209db5500164eedb82c46ea657499b72287 /drivers
parentb81a618dcd3ea99de292dbe624f41ca68f464376 (diff)
parent56be1416453c31d32f984328b5193489ab63ffcf (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6: (140 commits) MAINTAINERS: de-orphan fbdev. MAINTAINERS: Add file pattern for fb dt bindings. video: Move sm501fb devicetree binding documentation to a better place. fbcon: fix situation where fbcon gets deinitialised and can't reinit. video, sm501: add OF binding to support SM501 video, sm501: add edid and commandline support video, sm501: add I/O functions for use on powerpc video: Fix EDID macros H_SYNC_WIDTH and H_SYNC_OFFSET fbcon: Bugfix soft cursor detection in Tile Blitting video: add missing framebuffer_release in error path video: metronomefb: add __devexit_p around reference to metronomefb_remove video: hecubafb: add __devexit_p around reference to hecubafb_remove drivers:video:aty:radeon_base Fix typo occationally to occasionally atmel_lcdfb: add fb_blank function atmel_lcdfb: implement inverted contrast pwm video: s3c-fb: return proper error if clk_get fails uvesafb,vesafb: create WC or WB PAT-entries video: ffb: fix ffb_probe error path radeonfb: Let hwmon driver probe the "monid" I2C bus fbdev: sh_mobile_lcdc: checking NULL instead of IS_ERR() ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c2
-rw-r--r--drivers/mfd/sm501.c134
-rw-r--r--drivers/video/arkfb.c160
-rw-r--r--drivers/video/atmel_lcdfb.c31
-rw-r--r--drivers/video/aty/radeon_base.c2
-rw-r--r--drivers/video/aty/radeon_i2c.c3
-rw-r--r--drivers/video/cg14.c1
-rw-r--r--drivers/video/cg6.c1
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/console/tileblit.c2
-rw-r--r--drivers/video/edid.h4
-rw-r--r--drivers/video/ffb.c2
-rw-r--r--drivers/video/hecubafb.c2
-rw-r--r--drivers/video/hpfb.c6
-rw-r--r--drivers/video/metronomefb.c2
-rw-r--r--drivers/video/omap/Kconfig7
-rw-r--r--drivers/video/omap/blizzard.c3
-rw-r--r--drivers/video/omap/hwa742.c3
-rw-r--r--drivers/video/omap2/displays/Kconfig6
-rw-r--r--drivers/video/omap2/displays/Makefile1
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c25
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c279
-rw-r--r--drivers/video/omap2/displays/panel-taal.c123
-rw-r--r--drivers/video/omap2/dss/Kconfig14
-rw-r--r--drivers/video/omap2/dss/Makefile2
-rw-r--r--drivers/video/omap2/dss/core.c480
-rw-r--r--drivers/video/omap2/dss/dispc.c335
-rw-r--r--drivers/video/omap2/dss/display.c35
-rw-r--r--drivers/video/omap2/dss/dpi.c45
-rw-r--r--drivers/video/omap2/dss/dsi.c967
-rw-r--r--drivers/video/omap2/dss/dss.c763
-rw-r--r--drivers/video/omap2/dss/dss.h153
-rw-r--r--drivers/video/omap2/dss/dss_features.c163
-rw-r--r--drivers/video/omap2/dss/dss_features.h27
-rw-r--r--drivers/video/omap2/dss/hdmi.c1332
-rw-r--r--drivers/video/omap2/dss/hdmi.h415
-rw-r--r--drivers/video/omap2/dss/hdmi_omap4_panel.c222
-rw-r--r--drivers/video/omap2/dss/manager.c13
-rw-r--r--drivers/video/omap2/dss/overlay.c10
-rw-r--r--drivers/video/omap2/dss/rfbi.c128
-rw-r--r--drivers/video/omap2/dss/sdi.c62
-rw-r--r--drivers/video/omap2/dss/venc.c128
-rw-r--r--drivers/video/omap2/omapfb/Kconfig6
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c23
-rw-r--r--drivers/video/s3c-fb.c1
-rw-r--r--drivers/video/s3fb.c341
-rw-r--r--drivers/video/sh7760fb.c4
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c5
-rw-r--r--drivers/video/sis/sis.h1
-rw-r--r--drivers/video/sis/sis_main.c315
-rw-r--r--drivers/video/sis/vgatypes.h1
-rw-r--r--drivers/video/sm501fb.c275
-rw-r--r--drivers/video/svgalib.c175
-rw-r--r--drivers/video/tcx.c1
-rw-r--r--drivers/video/uvesafb.c49
-rw-r--r--drivers/video/vermilion/vermilion.c3
-rw-r--r--drivers/video/vesafb.c44
-rw-r--r--drivers/video/vt8623fb.c157
58 files changed, 5614 insertions, 1884 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 66c9af1b3d96..41a5d48e657b 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -889,7 +889,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
889 } 889 }
890 890
891 if (rdev->flags & RADEON_IS_MOBILITY) { 891 if (rdev->flags & RADEON_IS_MOBILITY) {
892 /* A temporal workaround for the occational blanking on certain laptop panels. 892 /* A temporal workaround for the occasional blanking on certain laptop panels.
893 This appears to related to the PLL divider registers (fail to lock?). 893 This appears to related to the PLL divider registers (fail to lock?).
894 It occurs even when all dividers are the same with their old settings. 894 It occurs even when all dividers are the same with their old settings.
895 In this case we really don't need to fiddle with PLL registers. 895 In this case we really don't need to fiddle with PLL registers.
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 5de3a760ea1e..df3702c1756d 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -133,10 +133,10 @@ static unsigned long decode_div(unsigned long pll2, unsigned long val,
133 133
134static void sm501_dump_clk(struct sm501_devdata *sm) 134static void sm501_dump_clk(struct sm501_devdata *sm)
135{ 135{
136 unsigned long misct = readl(sm->regs + SM501_MISC_TIMING); 136 unsigned long misct = smc501_readl(sm->regs + SM501_MISC_TIMING);
137 unsigned long pm0 = readl(sm->regs + SM501_POWER_MODE_0_CLOCK); 137 unsigned long pm0 = smc501_readl(sm->regs + SM501_POWER_MODE_0_CLOCK);
138 unsigned long pm1 = readl(sm->regs + SM501_POWER_MODE_1_CLOCK); 138 unsigned long pm1 = smc501_readl(sm->regs + SM501_POWER_MODE_1_CLOCK);
139 unsigned long pmc = readl(sm->regs + SM501_POWER_MODE_CONTROL); 139 unsigned long pmc = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
140 unsigned long sdclk0, sdclk1; 140 unsigned long sdclk0, sdclk1;
141 unsigned long pll2 = 0; 141 unsigned long pll2 = 0;
142 142
@@ -193,29 +193,29 @@ static void sm501_dump_regs(struct sm501_devdata *sm)
193 void __iomem *regs = sm->regs; 193 void __iomem *regs = sm->regs;
194 194
195 dev_info(sm->dev, "System Control %08x\n", 195 dev_info(sm->dev, "System Control %08x\n",
196 readl(regs + SM501_SYSTEM_CONTROL)); 196 smc501_readl(regs + SM501_SYSTEM_CONTROL));
197 dev_info(sm->dev, "Misc Control %08x\n", 197 dev_info(sm->dev, "Misc Control %08x\n",
198 readl(regs + SM501_MISC_CONTROL)); 198 smc501_readl(regs + SM501_MISC_CONTROL));
199 dev_info(sm->dev, "GPIO Control Low %08x\n", 199 dev_info(sm->dev, "GPIO Control Low %08x\n",
200 readl(regs + SM501_GPIO31_0_CONTROL)); 200 smc501_readl(regs + SM501_GPIO31_0_CONTROL));
201 dev_info(sm->dev, "GPIO Control Hi %08x\n", 201 dev_info(sm->dev, "GPIO Control Hi %08x\n",
202 readl(regs + SM501_GPIO63_32_CONTROL)); 202 smc501_readl(regs + SM501_GPIO63_32_CONTROL));
203 dev_info(sm->dev, "DRAM Control %08x\n", 203 dev_info(sm->dev, "DRAM Control %08x\n",
204 readl(regs + SM501_DRAM_CONTROL)); 204 smc501_readl(regs + SM501_DRAM_CONTROL));
205 dev_info(sm->dev, "Arbitration Ctrl %08x\n", 205 dev_info(sm->dev, "Arbitration Ctrl %08x\n",
206 readl(regs + SM501_ARBTRTN_CONTROL)); 206 smc501_readl(regs + SM501_ARBTRTN_CONTROL));
207 dev_info(sm->dev, "Misc Timing %08x\n", 207 dev_info(sm->dev, "Misc Timing %08x\n",
208 readl(regs + SM501_MISC_TIMING)); 208 smc501_readl(regs + SM501_MISC_TIMING));
209} 209}
210 210
211static void sm501_dump_gate(struct sm501_devdata *sm) 211static void sm501_dump_gate(struct sm501_devdata *sm)
212{ 212{
213 dev_info(sm->dev, "CurrentGate %08x\n", 213 dev_info(sm->dev, "CurrentGate %08x\n",
214 readl(sm->regs + SM501_CURRENT_GATE)); 214 smc501_readl(sm->regs + SM501_CURRENT_GATE));
215 dev_info(sm->dev, "CurrentClock %08x\n", 215 dev_info(sm->dev, "CurrentClock %08x\n",
216 readl(sm->regs + SM501_CURRENT_CLOCK)); 216 smc501_readl(sm->regs + SM501_CURRENT_CLOCK));
217 dev_info(sm->dev, "PowerModeControl %08x\n", 217 dev_info(sm->dev, "PowerModeControl %08x\n",
218 readl(sm->regs + SM501_POWER_MODE_CONTROL)); 218 smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL));
219} 219}
220 220
221#else 221#else
@@ -231,7 +231,7 @@ static inline void sm501_dump_clk(struct sm501_devdata *sm) { }
231 231
232static void sm501_sync_regs(struct sm501_devdata *sm) 232static void sm501_sync_regs(struct sm501_devdata *sm)
233{ 233{
234 readl(sm->regs); 234 smc501_readl(sm->regs);
235} 235}
236 236
237static inline void sm501_mdelay(struct sm501_devdata *sm, unsigned int delay) 237static inline void sm501_mdelay(struct sm501_devdata *sm, unsigned int delay)
@@ -261,11 +261,11 @@ int sm501_misc_control(struct device *dev,
261 261
262 spin_lock_irqsave(&sm->reg_lock, save); 262 spin_lock_irqsave(&sm->reg_lock, save);
263 263
264 misc = readl(sm->regs + SM501_MISC_CONTROL); 264 misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
265 to = (misc & ~clear) | set; 265 to = (misc & ~clear) | set;
266 266
267 if (to != misc) { 267 if (to != misc) {
268 writel(to, sm->regs + SM501_MISC_CONTROL); 268 smc501_writel(to, sm->regs + SM501_MISC_CONTROL);
269 sm501_sync_regs(sm); 269 sm501_sync_regs(sm);
270 270
271 dev_dbg(sm->dev, "MISC_CONTROL %08lx\n", misc); 271 dev_dbg(sm->dev, "MISC_CONTROL %08lx\n", misc);
@@ -294,11 +294,11 @@ unsigned long sm501_modify_reg(struct device *dev,
294 294
295 spin_lock_irqsave(&sm->reg_lock, save); 295 spin_lock_irqsave(&sm->reg_lock, save);
296 296
297 data = readl(sm->regs + reg); 297 data = smc501_readl(sm->regs + reg);
298 data |= set; 298 data |= set;
299 data &= ~clear; 299 data &= ~clear;
300 300
301 writel(data, sm->regs + reg); 301 smc501_writel(data, sm->regs + reg);
302 sm501_sync_regs(sm); 302 sm501_sync_regs(sm);
303 303
304 spin_unlock_irqrestore(&sm->reg_lock, save); 304 spin_unlock_irqrestore(&sm->reg_lock, save);
@@ -322,9 +322,9 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
322 322
323 mutex_lock(&sm->clock_lock); 323 mutex_lock(&sm->clock_lock);
324 324
325 mode = readl(sm->regs + SM501_POWER_MODE_CONTROL); 325 mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
326 gate = readl(sm->regs + SM501_CURRENT_GATE); 326 gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
327 clock = readl(sm->regs + SM501_CURRENT_CLOCK); 327 clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
328 328
329 mode &= 3; /* get current power mode */ 329 mode &= 3; /* get current power mode */
330 330
@@ -356,14 +356,14 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
356 356
357 switch (mode) { 357 switch (mode) {
358 case 1: 358 case 1:
359 writel(gate, sm->regs + SM501_POWER_MODE_0_GATE); 359 smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
360 writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK); 360 smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
361 mode = 0; 361 mode = 0;
362 break; 362 break;
363 case 2: 363 case 2:
364 case 0: 364 case 0:
365 writel(gate, sm->regs + SM501_POWER_MODE_1_GATE); 365 smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
366 writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK); 366 smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
367 mode = 1; 367 mode = 1;
368 break; 368 break;
369 369
@@ -372,7 +372,7 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
372 goto already; 372 goto already;
373 } 373 }
374 374
375 writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); 375 smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
376 sm501_sync_regs(sm); 376 sm501_sync_regs(sm);
377 377
378 dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n", 378 dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
@@ -519,9 +519,9 @@ unsigned long sm501_set_clock(struct device *dev,
519 unsigned long req_freq) 519 unsigned long req_freq)
520{ 520{
521 struct sm501_devdata *sm = dev_get_drvdata(dev); 521 struct sm501_devdata *sm = dev_get_drvdata(dev);
522 unsigned long mode = readl(sm->regs + SM501_POWER_MODE_CONTROL); 522 unsigned long mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
523 unsigned long gate = readl(sm->regs + SM501_CURRENT_GATE); 523 unsigned long gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
524 unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK); 524 unsigned long clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
525 unsigned char reg; 525 unsigned char reg;
526 unsigned int pll_reg = 0; 526 unsigned int pll_reg = 0;
527 unsigned long sm501_freq; /* the actual frequency achieved */ 527 unsigned long sm501_freq; /* the actual frequency achieved */
@@ -592,9 +592,9 @@ unsigned long sm501_set_clock(struct device *dev,
592 592
593 mutex_lock(&sm->clock_lock); 593 mutex_lock(&sm->clock_lock);
594 594
595 mode = readl(sm->regs + SM501_POWER_MODE_CONTROL); 595 mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
596 gate = readl(sm->regs + SM501_CURRENT_GATE); 596 gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
597 clock = readl(sm->regs + SM501_CURRENT_CLOCK); 597 clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
598 598
599 clock = clock & ~(0xFF << clksrc); 599 clock = clock & ~(0xFF << clksrc);
600 clock |= reg<<clksrc; 600 clock |= reg<<clksrc;
@@ -603,14 +603,14 @@ unsigned long sm501_set_clock(struct device *dev,
603 603
604 switch (mode) { 604 switch (mode) {
605 case 1: 605 case 1:
606 writel(gate, sm->regs + SM501_POWER_MODE_0_GATE); 606 smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
607 writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK); 607 smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
608 mode = 0; 608 mode = 0;
609 break; 609 break;
610 case 2: 610 case 2:
611 case 0: 611 case 0:
612 writel(gate, sm->regs + SM501_POWER_MODE_1_GATE); 612 smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
613 writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK); 613 smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
614 mode = 1; 614 mode = 1;
615 break; 615 break;
616 616
@@ -619,10 +619,11 @@ unsigned long sm501_set_clock(struct device *dev,
619 return -1; 619 return -1;
620 } 620 }
621 621
622 writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); 622 smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
623 623
624 if (pll_reg) 624 if (pll_reg)
625 writel(pll_reg, sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL); 625 smc501_writel(pll_reg,
626 sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
626 627
627 sm501_sync_regs(sm); 628 sm501_sync_regs(sm);
628 629
@@ -902,7 +903,7 @@ static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset)
902 struct sm501_gpio_chip *smgpio = to_sm501_gpio(chip); 903 struct sm501_gpio_chip *smgpio = to_sm501_gpio(chip);
903 unsigned long result; 904 unsigned long result;
904 905
905 result = readl(smgpio->regbase + SM501_GPIO_DATA_LOW); 906 result = smc501_readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
906 result >>= offset; 907 result >>= offset;
907 908
908 return result & 1UL; 909 return result & 1UL;
@@ -915,13 +916,13 @@ static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip,
915 916
916 /* check and modify if this pin is not set as gpio. */ 917 /* check and modify if this pin is not set as gpio. */
917 918
918 if (readl(smchip->control) & bit) { 919 if (smc501_readl(smchip->control) & bit) {
919 dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev, 920 dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev,
920 "changing mode of gpio, bit %08lx\n", bit); 921 "changing mode of gpio, bit %08lx\n", bit);
921 922
922 ctrl = readl(smchip->control); 923 ctrl = smc501_readl(smchip->control);
923 ctrl &= ~bit; 924 ctrl &= ~bit;
924 writel(ctrl, smchip->control); 925 smc501_writel(ctrl, smchip->control);
925 926
926 sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio)); 927 sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio));
927 } 928 }
@@ -942,10 +943,10 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
942 943
943 spin_lock_irqsave(&smgpio->lock, save); 944 spin_lock_irqsave(&smgpio->lock, save);
944 945
945 val = readl(regs + SM501_GPIO_DATA_LOW) & ~bit; 946 val = smc501_readl(regs + SM501_GPIO_DATA_LOW) & ~bit;
946 if (value) 947 if (value)
947 val |= bit; 948 val |= bit;
948 writel(val, regs); 949 smc501_writel(val, regs);
949 950
950 sm501_sync_regs(sm501_gpio_to_dev(smgpio)); 951 sm501_sync_regs(sm501_gpio_to_dev(smgpio));
951 sm501_gpio_ensure_gpio(smchip, bit); 952 sm501_gpio_ensure_gpio(smchip, bit);
@@ -967,8 +968,8 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
967 968
968 spin_lock_irqsave(&smgpio->lock, save); 969 spin_lock_irqsave(&smgpio->lock, save);
969 970
970 ddr = readl(regs + SM501_GPIO_DDR_LOW); 971 ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
971 writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW); 972 smc501_writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
972 973
973 sm501_sync_regs(sm501_gpio_to_dev(smgpio)); 974 sm501_sync_regs(sm501_gpio_to_dev(smgpio));
974 sm501_gpio_ensure_gpio(smchip, bit); 975 sm501_gpio_ensure_gpio(smchip, bit);
@@ -994,18 +995,18 @@ static int sm501_gpio_output(struct gpio_chip *chip,
994 995
995 spin_lock_irqsave(&smgpio->lock, save); 996 spin_lock_irqsave(&smgpio->lock, save);
996 997
997 val = readl(regs + SM501_GPIO_DATA_LOW); 998 val = smc501_readl(regs + SM501_GPIO_DATA_LOW);
998 if (value) 999 if (value)
999 val |= bit; 1000 val |= bit;
1000 else 1001 else
1001 val &= ~bit; 1002 val &= ~bit;
1002 writel(val, regs); 1003 smc501_writel(val, regs);
1003 1004
1004 ddr = readl(regs + SM501_GPIO_DDR_LOW); 1005 ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
1005 writel(ddr | bit, regs + SM501_GPIO_DDR_LOW); 1006 smc501_writel(ddr | bit, regs + SM501_GPIO_DDR_LOW);
1006 1007
1007 sm501_sync_regs(sm501_gpio_to_dev(smgpio)); 1008 sm501_sync_regs(sm501_gpio_to_dev(smgpio));
1008 writel(val, regs + SM501_GPIO_DATA_LOW); 1009 smc501_writel(val, regs + SM501_GPIO_DATA_LOW);
1009 1010
1010 sm501_sync_regs(sm501_gpio_to_dev(smgpio)); 1011 sm501_sync_regs(sm501_gpio_to_dev(smgpio));
1011 spin_unlock_irqrestore(&smgpio->lock, save); 1012 spin_unlock_irqrestore(&smgpio->lock, save);
@@ -1231,7 +1232,7 @@ static ssize_t sm501_dbg_regs(struct device *dev,
1231 1232
1232 for (reg = 0x00; reg < 0x70; reg += 4) { 1233 for (reg = 0x00; reg < 0x70; reg += 4) {
1233 ret = sprintf(ptr, "%08x = %08x\n", 1234 ret = sprintf(ptr, "%08x = %08x\n",
1234 reg, readl(sm->regs + reg)); 1235 reg, smc501_readl(sm->regs + reg));
1235 ptr += ret; 1236 ptr += ret;
1236 } 1237 }
1237 1238
@@ -1255,10 +1256,10 @@ static inline void sm501_init_reg(struct sm501_devdata *sm,
1255{ 1256{
1256 unsigned long tmp; 1257 unsigned long tmp;
1257 1258
1258 tmp = readl(sm->regs + reg); 1259 tmp = smc501_readl(sm->regs + reg);
1259 tmp &= ~r->mask; 1260 tmp &= ~r->mask;
1260 tmp |= r->set; 1261 tmp |= r->set;
1261 writel(tmp, sm->regs + reg); 1262 smc501_writel(tmp, sm->regs + reg);
1262} 1263}
1263 1264
1264/* sm501_init_regs 1265/* sm501_init_regs
@@ -1299,7 +1300,7 @@ static void sm501_init_regs(struct sm501_devdata *sm,
1299 1300
1300static int sm501_check_clocks(struct sm501_devdata *sm) 1301static int sm501_check_clocks(struct sm501_devdata *sm)
1301{ 1302{
1302 unsigned long pwrmode = readl(sm->regs + SM501_CURRENT_CLOCK); 1303 unsigned long pwrmode = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
1303 unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC); 1304 unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC);
1304 unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC); 1305 unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC);
1305 1306
@@ -1334,7 +1335,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
1334 1335
1335 INIT_LIST_HEAD(&sm->devices); 1336 INIT_LIST_HEAD(&sm->devices);
1336 1337
1337 devid = readl(sm->regs + SM501_DEVICEID); 1338 devid = smc501_readl(sm->regs + SM501_DEVICEID);
1338 1339
1339 if ((devid & SM501_DEVICEID_IDMASK) != SM501_DEVICEID_SM501) { 1340 if ((devid & SM501_DEVICEID_IDMASK) != SM501_DEVICEID_SM501) {
1340 dev_err(sm->dev, "incorrect device id %08lx\n", devid); 1341 dev_err(sm->dev, "incorrect device id %08lx\n", devid);
@@ -1342,9 +1343,9 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
1342 } 1343 }
1343 1344
1344 /* disable irqs */ 1345 /* disable irqs */
1345 writel(0, sm->regs + SM501_IRQ_MASK); 1346 smc501_writel(0, sm->regs + SM501_IRQ_MASK);
1346 1347
1347 dramctrl = readl(sm->regs + SM501_DRAM_CONTROL); 1348 dramctrl = smc501_readl(sm->regs + SM501_DRAM_CONTROL);
1348 mem_avail = sm501_mem_local[(dramctrl >> 13) & 0x7]; 1349 mem_avail = sm501_mem_local[(dramctrl >> 13) & 0x7];
1349 1350
1350 dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n", 1351 dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n",
@@ -1376,7 +1377,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
1376 sm501_register_gpio(sm); 1377 sm501_register_gpio(sm);
1377 } 1378 }
1378 1379
1379 if (pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) { 1380 if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
1380 if (!sm501_gpio_isregistered(sm)) 1381 if (!sm501_gpio_isregistered(sm))
1381 dev_err(sm->dev, "no gpio available for i2c gpio.\n"); 1382 dev_err(sm->dev, "no gpio available for i2c gpio.\n");
1382 else 1383 else
@@ -1421,6 +1422,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev)
1421 1422
1422 sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1); 1423 sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
1423 sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0); 1424 sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
1425
1424 if (sm->io_res == NULL || sm->mem_res == NULL) { 1426 if (sm->io_res == NULL || sm->mem_res == NULL) {
1425 dev_err(&dev->dev, "failed to get IO resource\n"); 1427 dev_err(&dev->dev, "failed to get IO resource\n");
1426 ret = -ENOENT; 1428 ret = -ENOENT;
@@ -1489,7 +1491,7 @@ static int sm501_plat_suspend(struct platform_device *pdev, pm_message_t state)
1489 struct sm501_devdata *sm = platform_get_drvdata(pdev); 1491 struct sm501_devdata *sm = platform_get_drvdata(pdev);
1490 1492
1491 sm->in_suspend = 1; 1493 sm->in_suspend = 1;
1492 sm->pm_misc = readl(sm->regs + SM501_MISC_CONTROL); 1494 sm->pm_misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
1493 1495
1494 sm501_dump_regs(sm); 1496 sm501_dump_regs(sm);
1495 1497
@@ -1513,9 +1515,9 @@ static int sm501_plat_resume(struct platform_device *pdev)
1513 1515
1514 /* check to see if we are in the same state as when suspended */ 1516 /* check to see if we are in the same state as when suspended */
1515 1517
1516 if (readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) { 1518 if (smc501_readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) {
1517 dev_info(sm->dev, "SM501_MISC_CONTROL changed over sleep\n"); 1519 dev_info(sm->dev, "SM501_MISC_CONTROL changed over sleep\n");
1518 writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL); 1520 smc501_writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL);
1519 1521
1520 /* our suspend causes the controller state to change, 1522 /* our suspend causes the controller state to change,
1521 * either by something attempting setup, power loss, 1523 * either by something attempting setup, power loss,
@@ -1734,10 +1736,16 @@ static struct pci_driver sm501_pci_driver = {
1734 1736
1735MODULE_ALIAS("platform:sm501"); 1737MODULE_ALIAS("platform:sm501");
1736 1738
1739static struct of_device_id __devinitdata of_sm501_match_tbl[] = {
1740 { .compatible = "smi,sm501", },
1741 { /* end */ }
1742};
1743
1737static struct platform_driver sm501_plat_driver = { 1744static struct platform_driver sm501_plat_driver = {
1738 .driver = { 1745 .driver = {
1739 .name = "sm501", 1746 .name = "sm501",
1740 .owner = THIS_MODULE, 1747 .owner = THIS_MODULE,
1748 .of_match_table = of_sm501_match_tbl,
1741 }, 1749 },
1742 .probe = sm501_plat_probe, 1750 .probe = sm501_plat_probe,
1743 .remove = sm501_plat_remove, 1751 .remove = sm501_plat_remove,
diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c
index 391ac939f011..8686429cbdf0 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/arkfb.c
@@ -158,12 +158,19 @@ static void arkfb_settile(struct fb_info *info, struct fb_tilemap *map)
158 } 158 }
159} 159}
160 160
161static void arkfb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
162{
163 struct arkfb_info *par = info->par;
164
165 svga_tilecursor(par->state.vgabase, info, cursor);
166}
167
161static struct fb_tile_ops arkfb_tile_ops = { 168static struct fb_tile_ops arkfb_tile_ops = {
162 .fb_settile = arkfb_settile, 169 .fb_settile = arkfb_settile,
163 .fb_tilecopy = svga_tilecopy, 170 .fb_tilecopy = svga_tilecopy,
164 .fb_tilefill = svga_tilefill, 171 .fb_tilefill = svga_tilefill,
165 .fb_tileblit = svga_tileblit, 172 .fb_tileblit = svga_tileblit,
166 .fb_tilecursor = svga_tilecursor, 173 .fb_tilecursor = arkfb_tilecursor,
167 .fb_get_tilemax = svga_get_tilemax, 174 .fb_get_tilemax = svga_get_tilemax,
168}; 175};
169 176
@@ -466,32 +473,40 @@ static unsigned short dac_regs[4] = {0x3c8, 0x3c9, 0x3c6, 0x3c7};
466 473
467static void ark_dac_read_regs(void *data, u8 *code, int count) 474static void ark_dac_read_regs(void *data, u8 *code, int count)
468{ 475{
469 u8 regval = vga_rseq(NULL, 0x1C); 476 struct fb_info *info = data;
477 struct arkfb_info *par;
478 u8 regval;
470 479
480 par = info->par;
481 regval = vga_rseq(par->state.vgabase, 0x1C);
471 while (count != 0) 482 while (count != 0)
472 { 483 {
473 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0)); 484 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
474 code[1] = vga_r(NULL, dac_regs[code[0] & 3]); 485 code[1] = vga_r(par->state.vgabase, dac_regs[code[0] & 3]);
475 count--; 486 count--;
476 code += 2; 487 code += 2;
477 } 488 }
478 489
479 vga_wseq(NULL, 0x1C, regval); 490 vga_wseq(par->state.vgabase, 0x1C, regval);
480} 491}
481 492
482static void ark_dac_write_regs(void *data, u8 *code, int count) 493static void ark_dac_write_regs(void *data, u8 *code, int count)
483{ 494{
484 u8 regval = vga_rseq(NULL, 0x1C); 495 struct fb_info *info = data;
496 struct arkfb_info *par;
497 u8 regval;
485 498
499 par = info->par;
500 regval = vga_rseq(par->state.vgabase, 0x1C);
486 while (count != 0) 501 while (count != 0)
487 { 502 {
488 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0)); 503 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
489 vga_w(NULL, dac_regs[code[0] & 3], code[1]); 504 vga_w(par->state.vgabase, dac_regs[code[0] & 3], code[1]);
490 count--; 505 count--;
491 code += 2; 506 code += 2;
492 } 507 }
493 508
494 vga_wseq(NULL, 0x1C, regval); 509 vga_wseq(par->state.vgabase, 0x1C, regval);
495} 510}
496 511
497 512
@@ -507,8 +522,8 @@ static void ark_set_pixclock(struct fb_info *info, u32 pixclock)
507 } 522 }
508 523
509 /* Set VGA misc register */ 524 /* Set VGA misc register */
510 regval = vga_r(NULL, VGA_MIS_R); 525 regval = vga_r(par->state.vgabase, VGA_MIS_R);
511 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 526 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
512} 527}
513 528
514 529
@@ -520,7 +535,10 @@ static int arkfb_open(struct fb_info *info, int user)
520 535
521 mutex_lock(&(par->open_lock)); 536 mutex_lock(&(par->open_lock));
522 if (par->ref_count == 0) { 537 if (par->ref_count == 0) {
538 void __iomem *vgabase = par->state.vgabase;
539
523 memset(&(par->state), 0, sizeof(struct vgastate)); 540 memset(&(par->state), 0, sizeof(struct vgastate));
541 par->state.vgabase = vgabase;
524 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 542 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
525 par->state.num_crtc = 0x60; 543 par->state.num_crtc = 0x60;
526 par->state.num_seq = 0x30; 544 par->state.num_seq = 0x30;
@@ -646,50 +664,50 @@ static int arkfb_set_par(struct fb_info *info)
646 info->var.activate = FB_ACTIVATE_NOW; 664 info->var.activate = FB_ACTIVATE_NOW;
647 665
648 /* Unlock registers */ 666 /* Unlock registers */
649 svga_wcrt_mask(0x11, 0x00, 0x80); 667 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
650 668
651 /* Blank screen and turn off sync */ 669 /* Blank screen and turn off sync */
652 svga_wseq_mask(0x01, 0x20, 0x20); 670 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
653 svga_wcrt_mask(0x17, 0x00, 0x80); 671 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
654 672
655 /* Set default values */ 673 /* Set default values */
656 svga_set_default_gfx_regs(); 674 svga_set_default_gfx_regs(par->state.vgabase);
657 svga_set_default_atc_regs(); 675 svga_set_default_atc_regs(par->state.vgabase);
658 svga_set_default_seq_regs(); 676 svga_set_default_seq_regs(par->state.vgabase);
659 svga_set_default_crt_regs(); 677 svga_set_default_crt_regs(par->state.vgabase);
660 svga_wcrt_multi(ark_line_compare_regs, 0xFFFFFFFF); 678 svga_wcrt_multi(par->state.vgabase, ark_line_compare_regs, 0xFFFFFFFF);
661 svga_wcrt_multi(ark_start_address_regs, 0); 679 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, 0);
662 680
663 /* ARK specific initialization */ 681 /* ARK specific initialization */
664 svga_wseq_mask(0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */ 682 svga_wseq_mask(par->state.vgabase, 0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */
665 svga_wseq_mask(0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */ 683 svga_wseq_mask(par->state.vgabase, 0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */
666 684
667 vga_wseq(NULL, 0x13, info->fix.smem_start >> 16); 685 vga_wseq(par->state.vgabase, 0x13, info->fix.smem_start >> 16);
668 vga_wseq(NULL, 0x14, info->fix.smem_start >> 24); 686 vga_wseq(par->state.vgabase, 0x14, info->fix.smem_start >> 24);
669 vga_wseq(NULL, 0x15, 0); 687 vga_wseq(par->state.vgabase, 0x15, 0);
670 vga_wseq(NULL, 0x16, 0); 688 vga_wseq(par->state.vgabase, 0x16, 0);
671 689
672 /* Set the FIFO threshold register */ 690 /* Set the FIFO threshold register */
673 /* It is fascinating way to store 5-bit value in 8-bit register */ 691 /* It is fascinating way to store 5-bit value in 8-bit register */
674 regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1; 692 regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1;
675 vga_wseq(NULL, 0x18, regval); 693 vga_wseq(par->state.vgabase, 0x18, regval);
676 694
677 /* Set the offset register */ 695 /* Set the offset register */
678 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 696 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
679 svga_wcrt_multi(ark_offset_regs, offset_value); 697 svga_wcrt_multi(par->state.vgabase, ark_offset_regs, offset_value);
680 698
681 /* fix for hi-res textmode */ 699 /* fix for hi-res textmode */
682 svga_wcrt_mask(0x40, 0x08, 0x08); 700 svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08);
683 701
684 if (info->var.vmode & FB_VMODE_DOUBLE) 702 if (info->var.vmode & FB_VMODE_DOUBLE)
685 svga_wcrt_mask(0x09, 0x80, 0x80); 703 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
686 else 704 else
687 svga_wcrt_mask(0x09, 0x00, 0x80); 705 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
688 706
689 if (info->var.vmode & FB_VMODE_INTERLACED) 707 if (info->var.vmode & FB_VMODE_INTERLACED)
690 svga_wcrt_mask(0x44, 0x04, 0x04); 708 svga_wcrt_mask(par->state.vgabase, 0x44, 0x04, 0x04);
691 else 709 else
692 svga_wcrt_mask(0x44, 0x00, 0x04); 710 svga_wcrt_mask(par->state.vgabase, 0x44, 0x00, 0x04);
693 711
694 hmul = 1; 712 hmul = 1;
695 hdiv = 1; 713 hdiv = 1;
@@ -699,40 +717,40 @@ static int arkfb_set_par(struct fb_info *info)
699 switch (mode) { 717 switch (mode) {
700 case 0: 718 case 0:
701 pr_debug("fb%d: text mode\n", info->node); 719 pr_debug("fb%d: text mode\n", info->node);
702 svga_set_textmode_vga_regs(); 720 svga_set_textmode_vga_regs(par->state.vgabase);
703 721
704 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 722 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
705 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 723 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
706 dac_set_mode(par->dac, DAC_PSEUDO8_8); 724 dac_set_mode(par->dac, DAC_PSEUDO8_8);
707 725
708 break; 726 break;
709 case 1: 727 case 1:
710 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 728 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
711 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 729 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
712 730
713 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 731 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
714 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 732 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
715 dac_set_mode(par->dac, DAC_PSEUDO8_8); 733 dac_set_mode(par->dac, DAC_PSEUDO8_8);
716 break; 734 break;
717 case 2: 735 case 2:
718 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 736 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
719 737
720 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 738 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
721 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 739 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
722 dac_set_mode(par->dac, DAC_PSEUDO8_8); 740 dac_set_mode(par->dac, DAC_PSEUDO8_8);
723 break; 741 break;
724 case 3: 742 case 3:
725 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 743 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
726 744
727 vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode */ 745 vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode */
728 746
729 if (info->var.pixclock > 20000) { 747 if (info->var.pixclock > 20000) {
730 pr_debug("fb%d: not using multiplex\n", info->node); 748 pr_debug("fb%d: not using multiplex\n", info->node);
731 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 749 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
732 dac_set_mode(par->dac, DAC_PSEUDO8_8); 750 dac_set_mode(par->dac, DAC_PSEUDO8_8);
733 } else { 751 } else {
734 pr_debug("fb%d: using multiplex\n", info->node); 752 pr_debug("fb%d: using multiplex\n", info->node);
735 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 753 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
736 dac_set_mode(par->dac, DAC_PSEUDO8_16); 754 dac_set_mode(par->dac, DAC_PSEUDO8_16);
737 hdiv = 2; 755 hdiv = 2;
738 } 756 }
@@ -740,22 +758,22 @@ static int arkfb_set_par(struct fb_info *info)
740 case 4: 758 case 4:
741 pr_debug("fb%d: 5/5/5 truecolor\n", info->node); 759 pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
742 760
743 vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */ 761 vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
744 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 762 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
745 dac_set_mode(par->dac, DAC_RGB1555_16); 763 dac_set_mode(par->dac, DAC_RGB1555_16);
746 break; 764 break;
747 case 5: 765 case 5:
748 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 766 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
749 767
750 vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */ 768 vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
751 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 769 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
752 dac_set_mode(par->dac, DAC_RGB0565_16); 770 dac_set_mode(par->dac, DAC_RGB0565_16);
753 break; 771 break;
754 case 6: 772 case 6:
755 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 773 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
756 774
757 vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode ??? */ 775 vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode ??? */
758 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 776 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
759 dac_set_mode(par->dac, DAC_RGB0888_16); 777 dac_set_mode(par->dac, DAC_RGB0888_16);
760 hmul = 3; 778 hmul = 3;
761 hdiv = 2; 779 hdiv = 2;
@@ -763,8 +781,8 @@ static int arkfb_set_par(struct fb_info *info)
763 case 7: 781 case 7:
764 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); 782 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
765 783
766 vga_wseq(NULL, 0x11, 0x1E); /* 32bpp accel mode */ 784 vga_wseq(par->state.vgabase, 0x11, 0x1E); /* 32bpp accel mode */
767 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 785 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
768 dac_set_mode(par->dac, DAC_RGB8888_16); 786 dac_set_mode(par->dac, DAC_RGB8888_16);
769 hmul = 2; 787 hmul = 2;
770 break; 788 break;
@@ -774,7 +792,7 @@ static int arkfb_set_par(struct fb_info *info)
774 } 792 }
775 793
776 ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul); 794 ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
777 svga_set_timings(&ark_timing_regs, &(info->var), hmul, hdiv, 795 svga_set_timings(par->state.vgabase, &ark_timing_regs, &(info->var), hmul, hdiv,
778 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 796 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
779 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, 797 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
780 hmul, info->node); 798 hmul, info->node);
@@ -782,12 +800,12 @@ static int arkfb_set_par(struct fb_info *info)
782 /* Set interlaced mode start/end register */ 800 /* Set interlaced mode start/end register */
783 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 801 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
784 value = ((value * hmul / hdiv) / 8) - 5; 802 value = ((value * hmul / hdiv) / 8) - 5;
785 vga_wcrt(NULL, 0x42, (value + 1) / 2); 803 vga_wcrt(par->state.vgabase, 0x42, (value + 1) / 2);
786 804
787 memset_io(info->screen_base, 0x00, screen_size); 805 memset_io(info->screen_base, 0x00, screen_size);
788 /* Device and screen back on */ 806 /* Device and screen back on */
789 svga_wcrt_mask(0x17, 0x80, 0x80); 807 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
790 svga_wseq_mask(0x01, 0x00, 0x20); 808 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
791 809
792 return 0; 810 return 0;
793} 811}
@@ -857,23 +875,25 @@ static int arkfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
857 875
858static int arkfb_blank(int blank_mode, struct fb_info *info) 876static int arkfb_blank(int blank_mode, struct fb_info *info)
859{ 877{
878 struct arkfb_info *par = info->par;
879
860 switch (blank_mode) { 880 switch (blank_mode) {
861 case FB_BLANK_UNBLANK: 881 case FB_BLANK_UNBLANK:
862 pr_debug("fb%d: unblank\n", info->node); 882 pr_debug("fb%d: unblank\n", info->node);
863 svga_wseq_mask(0x01, 0x00, 0x20); 883 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
864 svga_wcrt_mask(0x17, 0x80, 0x80); 884 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
865 break; 885 break;
866 case FB_BLANK_NORMAL: 886 case FB_BLANK_NORMAL:
867 pr_debug("fb%d: blank\n", info->node); 887 pr_debug("fb%d: blank\n", info->node);
868 svga_wseq_mask(0x01, 0x20, 0x20); 888 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
869 svga_wcrt_mask(0x17, 0x80, 0x80); 889 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
870 break; 890 break;
871 case FB_BLANK_POWERDOWN: 891 case FB_BLANK_POWERDOWN:
872 case FB_BLANK_HSYNC_SUSPEND: 892 case FB_BLANK_HSYNC_SUSPEND:
873 case FB_BLANK_VSYNC_SUSPEND: 893 case FB_BLANK_VSYNC_SUSPEND:
874 pr_debug("fb%d: sync down\n", info->node); 894 pr_debug("fb%d: sync down\n", info->node);
875 svga_wseq_mask(0x01, 0x20, 0x20); 895 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
876 svga_wcrt_mask(0x17, 0x00, 0x80); 896 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
877 break; 897 break;
878 } 898 }
879 return 0; 899 return 0;
@@ -884,6 +904,7 @@ static int arkfb_blank(int blank_mode, struct fb_info *info)
884 904
885static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 905static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
886{ 906{
907 struct arkfb_info *par = info->par;
887 unsigned int offset; 908 unsigned int offset;
888 909
889 /* Calculate the offset */ 910 /* Calculate the offset */
@@ -897,7 +918,7 @@ static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
897 } 918 }
898 919
899 /* Set the offset */ 920 /* Set the offset */
900 svga_wcrt_multi(ark_start_address_regs, offset); 921 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, offset);
901 922
902 return 0; 923 return 0;
903} 924}
@@ -930,6 +951,8 @@ static struct fb_ops arkfb_ops = {
930/* PCI probe */ 951/* PCI probe */
931static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 952static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
932{ 953{
954 struct pci_bus_region bus_reg;
955 struct resource vga_res;
933 struct fb_info *info; 956 struct fb_info *info;
934 struct arkfb_info *par; 957 struct arkfb_info *par;
935 int rc; 958 int rc;
@@ -985,8 +1008,17 @@ static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_
985 goto err_iomap; 1008 goto err_iomap;
986 } 1009 }
987 1010
1011 bus_reg.start = 0;
1012 bus_reg.end = 64 * 1024;
1013
1014 vga_res.flags = IORESOURCE_IO;
1015
1016 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
1017
1018 par->state.vgabase = (void __iomem *) vga_res.start;
1019
988 /* FIXME get memsize */ 1020 /* FIXME get memsize */
989 regval = vga_rseq(NULL, 0x10); 1021 regval = vga_rseq(par->state.vgabase, 0x10);
990 info->screen_size = (1 << (regval >> 6)) << 20; 1022 info->screen_size = (1 << (regval >> 6)) << 20;
991 info->fix.smem_len = info->screen_size; 1023 info->fix.smem_len = info->screen_size;
992 1024
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 4b4e8dadd6b2..ccecf9974587 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -68,7 +68,7 @@ static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
68} 68}
69#endif 69#endif
70 70
71static const u32 contrast_ctr = ATMEL_LCDC_PS_DIV8 71static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8
72 | ATMEL_LCDC_POL_POSITIVE 72 | ATMEL_LCDC_POL_POSITIVE
73 | ATMEL_LCDC_ENA_PWMENABLE; 73 | ATMEL_LCDC_ENA_PWMENABLE;
74 74
@@ -164,6 +164,10 @@ static void exit_backlight(struct atmel_lcdfb_info *sinfo)
164 164
165static void init_contrast(struct atmel_lcdfb_info *sinfo) 165static void init_contrast(struct atmel_lcdfb_info *sinfo)
166{ 166{
167 /* contrast pwm can be 'inverted' */
168 if (sinfo->lcdcon_pol_negative)
169 contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
170
167 /* have some default contrast/backlight settings */ 171 /* have some default contrast/backlight settings */
168 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); 172 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
169 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); 173 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
@@ -711,11 +715,35 @@ static int atmel_lcdfb_pan_display(struct fb_var_screeninfo *var,
711 return 0; 715 return 0;
712} 716}
713 717
718static int atmel_lcdfb_blank(int blank_mode, struct fb_info *info)
719{
720 struct atmel_lcdfb_info *sinfo = info->par;
721
722 switch (blank_mode) {
723 case FB_BLANK_UNBLANK:
724 case FB_BLANK_NORMAL:
725 atmel_lcdfb_start(sinfo);
726 break;
727 case FB_BLANK_VSYNC_SUSPEND:
728 case FB_BLANK_HSYNC_SUSPEND:
729 break;
730 case FB_BLANK_POWERDOWN:
731 atmel_lcdfb_stop(sinfo);
732 break;
733 default:
734 return -EINVAL;
735 }
736
737 /* let fbcon do a soft blank for us */
738 return ((blank_mode == FB_BLANK_NORMAL) ? 1 : 0);
739}
740
714static struct fb_ops atmel_lcdfb_ops = { 741static struct fb_ops atmel_lcdfb_ops = {
715 .owner = THIS_MODULE, 742 .owner = THIS_MODULE,
716 .fb_check_var = atmel_lcdfb_check_var, 743 .fb_check_var = atmel_lcdfb_check_var,
717 .fb_set_par = atmel_lcdfb_set_par, 744 .fb_set_par = atmel_lcdfb_set_par,
718 .fb_setcolreg = atmel_lcdfb_setcolreg, 745 .fb_setcolreg = atmel_lcdfb_setcolreg,
746 .fb_blank = atmel_lcdfb_blank,
719 .fb_pan_display = atmel_lcdfb_pan_display, 747 .fb_pan_display = atmel_lcdfb_pan_display,
720 .fb_fillrect = cfb_fillrect, 748 .fb_fillrect = cfb_fillrect,
721 .fb_copyarea = cfb_copyarea, 749 .fb_copyarea = cfb_copyarea,
@@ -817,6 +845,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
817 sinfo->guard_time = pdata_sinfo->guard_time; 845 sinfo->guard_time = pdata_sinfo->guard_time;
818 sinfo->smem_len = pdata_sinfo->smem_len; 846 sinfo->smem_len = pdata_sinfo->smem_len;
819 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight; 847 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
848 sinfo->lcdcon_pol_negative = pdata_sinfo->lcdcon_pol_negative;
820 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode; 849 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
821 } else { 850 } else {
822 dev_err(dev, "cannot get default configuration\n"); 851 dev_err(dev, "cannot get default configuration\n");
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 3c1e13ed1cba..32f8cf6200a7 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1248,7 +1248,7 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
1248 1248
1249 /* Workaround from XFree */ 1249 /* Workaround from XFree */
1250 if (rinfo->is_mobility) { 1250 if (rinfo->is_mobility) {
1251 /* A temporal workaround for the occational blanking on certain laptop 1251 /* A temporal workaround for the occasional blanking on certain laptop
1252 * panels. This appears to related to the PLL divider registers 1252 * panels. This appears to related to the PLL divider registers
1253 * (fail to lock?). It occurs even when all dividers are the same 1253 * (fail to lock?). It occurs even when all dividers are the same
1254 * with their old settings. In this case we really don't need to 1254 * with their old settings. In this case we really don't need to
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 78d1f4cd1fe0..ab1d0fd76316 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -100,6 +100,9 @@ void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
100{ 100{
101 rinfo->i2c[0].rinfo = rinfo; 101 rinfo->i2c[0].rinfo = rinfo;
102 rinfo->i2c[0].ddc_reg = GPIO_MONID; 102 rinfo->i2c[0].ddc_reg = GPIO_MONID;
103#ifndef CONFIG_PPC
104 rinfo->i2c[0].adapter.class = I2C_CLASS_HWMON;
105#endif
103 radeon_setup_i2c_bus(&rinfo->i2c[0], "monid"); 106 radeon_setup_i2c_bus(&rinfo->i2c[0], "monid");
104 107
105 rinfo->i2c[1].rinfo = rinfo; 108 rinfo->i2c[1].rinfo = rinfo;
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index e2c85b0db632..f18895006627 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -565,6 +565,7 @@ out_dealloc_cmap:
565 565
566out_unmap_regs: 566out_unmap_regs:
567 cg14_unmap_regs(op, info, par); 567 cg14_unmap_regs(op, info, par);
568 framebuffer_release(info);
568 569
569out_err: 570out_err:
570 return err; 571 return err;
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 4ffad90bde42..179e96cdb323 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -821,6 +821,7 @@ out_dealloc_cmap:
821 821
822out_unmap_regs: 822out_unmap_regs:
823 cg6_unmap_regs(op, info, par); 823 cg6_unmap_regs(op, info, par);
824 framebuffer_release(info);
824 825
825out_err: 826out_err:
826 return err; 827 return err;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 9c092b8d64e6..c58393402da2 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -823,10 +823,10 @@ static int set_con2fb_map(int unit, int newidx, int user)
823 if (oldidx == newidx) 823 if (oldidx == newidx)
824 return 0; 824 return 0;
825 825
826 if (!info || fbcon_has_exited) 826 if (!info)
827 return -EINVAL; 827 return -EINVAL;
828 828
829 if (!err && !search_for_mapped_con()) { 829 if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
830 info_idx = newidx; 830 info_idx = newidx;
831 return fbcon_takeover(0); 831 return fbcon_takeover(0);
832 } 832 }
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 0056a41e5c35..15e8e1a89c45 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -83,7 +83,7 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
83 int softback_lines, int fg, int bg) 83 int softback_lines, int fg, int bg)
84{ 84{
85 struct fb_tilecursor cursor; 85 struct fb_tilecursor cursor;
86 int use_sw = (vc->vc_cursor_type & 0x01); 86 int use_sw = (vc->vc_cursor_type & 0x10);
87 87
88 cursor.sx = vc->vc_x; 88 cursor.sx = vc->vc_x;
89 cursor.sy = vc->vc_y; 89 cursor.sy = vc->vc_y;
diff --git a/drivers/video/edid.h b/drivers/video/edid.h
index bd89fb3be8c2..d03a232d90b2 100644
--- a/drivers/video/edid.h
+++ b/drivers/video/edid.h
@@ -101,8 +101,8 @@
101#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO ) 101#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO )
102#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO ) 102#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO )
103 103
104#define H_SYNC_WIDTH COMBINE_HI_4LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO ) 104#define H_SYNC_WIDTH COMBINE_HI_8LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO )
105#define H_SYNC_OFFSET COMBINE_HI_4LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO ) 105#define H_SYNC_OFFSET COMBINE_HI_8LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO )
106 106
107#define H_SIZE_LO (unsigned)block[ 12 ] 107#define H_SIZE_LO (unsigned)block[ 12 ]
108#define V_SIZE_LO (unsigned)block[ 13 ] 108#define V_SIZE_LO (unsigned)block[ 13 ]
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 910c5e6f6702..14102a3f70f5 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -1010,7 +1010,7 @@ out_dealloc_cmap:
1010 fb_dealloc_cmap(&info->cmap); 1010 fb_dealloc_cmap(&info->cmap);
1011 1011
1012out_unmap_dac: 1012out_unmap_dac:
1013 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1013 of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
1014 1014
1015out_unmap_fbc: 1015out_unmap_fbc:
1016 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1016 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index c77bcc6ab463..1b94643ecbcf 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -299,7 +299,7 @@ static int __devexit hecubafb_remove(struct platform_device *dev)
299 299
300static struct platform_driver hecubafb_driver = { 300static struct platform_driver hecubafb_driver = {
301 .probe = hecubafb_probe, 301 .probe = hecubafb_probe,
302 .remove = hecubafb_remove, 302 .remove = __devexit_p(hecubafb_remove),
303 .driver = { 303 .driver = {
304 .owner = THIS_MODULE, 304 .owner = THIS_MODULE,
305 .name = "hecubafb", 305 .name = "hecubafb",
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index c8e280f1bb0b..ebf8495ff198 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -321,11 +321,11 @@ static int __devinit hpfb_dio_probe(struct dio_dev * d, const struct dio_device_
321 unsigned long paddr, vaddr; 321 unsigned long paddr, vaddr;
322 322
323 paddr = d->resource.start; 323 paddr = d->resource.start;
324 if (!request_mem_region(d->resource.start, d->resource.end - d->resource.start, d->name)) 324 if (!request_mem_region(d->resource.start, resource_size(&d->resource), d->name))
325 return -EBUSY; 325 return -EBUSY;
326 326
327 if (d->scode >= DIOII_SCBASE) { 327 if (d->scode >= DIOII_SCBASE) {
328 vaddr = (unsigned long)ioremap(paddr, d->resource.end - d->resource.start); 328 vaddr = (unsigned long)ioremap(paddr, resource_size(&d->resource));
329 } else { 329 } else {
330 vaddr = paddr + DIO_VIRADDRBASE; 330 vaddr = paddr + DIO_VIRADDRBASE;
331 } 331 }
@@ -344,7 +344,7 @@ static void __devexit hpfb_remove_one(struct dio_dev *d)
344 unregister_framebuffer(&fb_info); 344 unregister_framebuffer(&fb_info);
345 if (d->scode >= DIOII_SCBASE) 345 if (d->scode >= DIOII_SCBASE)
346 iounmap((void *)fb_regs); 346 iounmap((void *)fb_regs);
347 release_mem_region(d->resource.start, d->resource.end - d->resource.start); 347 release_mem_region(d->resource.start, resource_size(&d->resource));
348} 348}
349 349
350static struct dio_device_id hpfb_dio_tbl[] = { 350static struct dio_device_id hpfb_dio_tbl[] = {
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
index 63ed3b72b01c..ed64edfd2c43 100644
--- a/drivers/video/metronomefb.c
+++ b/drivers/video/metronomefb.c
@@ -765,7 +765,7 @@ static int __devexit metronomefb_remove(struct platform_device *dev)
765 765
766static struct platform_driver metronomefb_driver = { 766static struct platform_driver metronomefb_driver = {
767 .probe = metronomefb_probe, 767 .probe = metronomefb_probe,
768 .remove = metronomefb_remove, 768 .remove = __devexit_p(metronomefb_remove),
769 .driver = { 769 .driver = {
770 .owner = THIS_MODULE, 770 .owner = THIS_MODULE,
771 .name = "metronomefb", 771 .name = "metronomefb",
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 083c8fe53e24..15e7f1912af9 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -5,13 +5,18 @@ config FB_OMAP
5 select FB_CFB_FILLRECT 5 select FB_CFB_FILLRECT
6 select FB_CFB_COPYAREA 6 select FB_CFB_COPYAREA
7 select FB_CFB_IMAGEBLIT 7 select FB_CFB_IMAGEBLIT
8 select TWL4030_CORE if MACH_OMAP_2430SDP
8 help 9 help
9 Frame buffer driver for OMAP based boards. 10 Frame buffer driver for OMAP based boards.
10 11
11config FB_OMAP_LCD_VGA 12config FB_OMAP_LCD_VGA
12 bool "Use LCD in VGA mode" 13 bool "Use LCD in VGA mode"
13 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP 14 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP
14 15 help
16 Set LCD resolution as VGA (640 X 480).
17 Default resolution without this option is QVGA(320 X 240).
18 Please take a look at drivers/video/omap/lcd_ldp.c file
19 for lcd driver code.
15choice 20choice
16 depends on FB_OMAP && MACH_OVERO 21 depends on FB_OMAP && MACH_OVERO
17 prompt "Screen resolution" 22 prompt "Screen resolution"
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index 87785c215a52..c0504a8a5079 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -397,8 +397,7 @@ static inline void free_req(struct blizzard_request *req)
397 397
398 spin_lock_irqsave(&blizzard.req_lock, flags); 398 spin_lock_irqsave(&blizzard.req_lock, flags);
399 399
400 list_del(&req->entry); 400 list_move(&req->entry, &blizzard.free_req_list);
401 list_add(&req->entry, &blizzard.free_req_list);
402 if (!(req->flags & REQ_FROM_IRQ_POOL)) 401 if (!(req->flags & REQ_FROM_IRQ_POOL))
403 up(&blizzard.req_sema); 402 up(&blizzard.req_sema);
404 403
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 0016f77cd13f..084aa0ac562b 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -269,8 +269,7 @@ static inline void free_req(struct hwa742_request *req)
269 269
270 spin_lock_irqsave(&hwa742.req_lock, flags); 270 spin_lock_irqsave(&hwa742.req_lock, flags);
271 271
272 list_del(&req->entry); 272 list_move(&req->entry, &hwa742.free_req_list);
273 list_add(&req->entry, &hwa742.free_req_list);
274 if (!(req->flags & REQ_FROM_IRQ_POOL)) 273 if (!(req->flags & REQ_FROM_IRQ_POOL))
275 up(&hwa742.req_sema); 274 up(&hwa742.req_sema);
276 275
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 940cab394c2e..d18ad6b2372a 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -9,6 +9,12 @@ config PANEL_GENERIC_DPI
9 Supports LCD Panel used in TI SDP3430 and EVM boards, 9 Supports LCD Panel used in TI SDP3430 and EVM boards,
10 OMAP3517 EVM boards and CM-T35. 10 OMAP3517 EVM boards and CM-T35.
11 11
12config PANEL_LGPHILIPS_LB035Q02
13 tristate "LG.Philips LB035Q02 LCD Panel"
14 depends on OMAP2_DSS && SPI
15 help
16 LCD Panel used on the Gumstix Overo Palo35
17
12config PANEL_SHARP_LS037V7DW01 18config PANEL_SHARP_LS037V7DW01
13 tristate "Sharp LS037V7DW01 LCD Panel" 19 tristate "Sharp LS037V7DW01 LCD Panel"
14 depends on OMAP2_DSS 20 depends on OMAP2_DSS
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index 861f0255ec6b..0f601ab3abf4 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o 1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
2obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 3obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
3obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o 4obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
4 5
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 07eb30ee59c8..4a9b9ff59467 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -156,6 +156,31 @@ static struct panel_config generic_dpi_panels[] = {
156 .power_off_delay = 0, 156 .power_off_delay = 0,
157 .name = "toppoly_tdo35s", 157 .name = "toppoly_tdo35s",
158 }, 158 },
159
160 /* Samsung LTE430WQ-F0C */
161 {
162 {
163 .x_res = 480,
164 .y_res = 272,
165
166 .pixel_clock = 9200,
167
168 .hfp = 8,
169 .hsw = 41,
170 .hbp = 45 - 41,
171
172 .vfp = 4,
173 .vsw = 10,
174 .vbp = 12 - 10,
175 },
176 .acbi = 0x0,
177 .acb = 0x0,
178 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
179 OMAP_DSS_LCD_IHS,
180 .power_on_delay = 0,
181 .power_off_delay = 0,
182 .name = "samsung_lte430wq_f0c",
183 },
159}; 184};
160 185
161struct panel_drv_data { 186struct panel_drv_data {
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
new file mode 100644
index 000000000000..271324db2436
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -0,0 +1,279 @@
1/*
2 * LCD panel driver for LG.Philips LB035Q02
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/spi/spi.h>
22#include <linux/mutex.h>
23
24#include <plat/display.h>
25
26struct lb035q02_data {
27 struct mutex lock;
28};
29
30static struct omap_video_timings lb035q02_timings = {
31 .x_res = 320,
32 .y_res = 240,
33
34 .pixel_clock = 6500,
35
36 .hsw = 2,
37 .hfp = 20,
38 .hbp = 68,
39
40 .vsw = 2,
41 .vfp = 4,
42 .vbp = 18,
43};
44
45static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
46{
47 int r;
48
49 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
50 return 0;
51
52 r = omapdss_dpi_display_enable(dssdev);
53 if (r)
54 goto err0;
55
56 if (dssdev->platform_enable) {
57 r = dssdev->platform_enable(dssdev);
58 if (r)
59 goto err1;
60 }
61
62 return 0;
63err1:
64 omapdss_dpi_display_disable(dssdev);
65err0:
66 return r;
67}
68
69static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
70{
71 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
72 return;
73
74 if (dssdev->platform_disable)
75 dssdev->platform_disable(dssdev);
76
77 omapdss_dpi_display_disable(dssdev);
78}
79
80static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
81{
82 struct lb035q02_data *ld;
83 int r;
84
85 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
86 OMAP_DSS_LCD_IHS;
87 dssdev->panel.timings = lb035q02_timings;
88
89 ld = kzalloc(sizeof(*ld), GFP_KERNEL);
90 if (!ld) {
91 r = -ENOMEM;
92 goto err;
93 }
94 mutex_init(&ld->lock);
95 dev_set_drvdata(&dssdev->dev, ld);
96 return 0;
97err:
98 return r;
99}
100
101static void lb035q02_panel_remove(struct omap_dss_device *dssdev)
102{
103 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
104
105 kfree(ld);
106}
107
108static int lb035q02_panel_enable(struct omap_dss_device *dssdev)
109{
110 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
111 int r;
112
113 mutex_lock(&ld->lock);
114
115 r = lb035q02_panel_power_on(dssdev);
116 if (r)
117 goto err;
118 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
119
120 mutex_unlock(&ld->lock);
121 return 0;
122err:
123 mutex_unlock(&ld->lock);
124 return r;
125}
126
127static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
128{
129 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
130
131 mutex_lock(&ld->lock);
132
133 lb035q02_panel_power_off(dssdev);
134 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
135
136 mutex_unlock(&ld->lock);
137}
138
139static int lb035q02_panel_suspend(struct omap_dss_device *dssdev)
140{
141 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
142
143 mutex_lock(&ld->lock);
144
145 lb035q02_panel_power_off(dssdev);
146 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
147
148 mutex_unlock(&ld->lock);
149 return 0;
150}
151
152static int lb035q02_panel_resume(struct omap_dss_device *dssdev)
153{
154 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
155 int r;
156
157 mutex_lock(&ld->lock);
158
159 r = lb035q02_panel_power_on(dssdev);
160 if (r)
161 goto err;
162 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
163
164 mutex_unlock(&ld->lock);
165 return 0;
166err:
167 mutex_unlock(&ld->lock);
168 return r;
169}
170
171static struct omap_dss_driver lb035q02_driver = {
172 .probe = lb035q02_panel_probe,
173 .remove = lb035q02_panel_remove,
174
175 .enable = lb035q02_panel_enable,
176 .disable = lb035q02_panel_disable,
177 .suspend = lb035q02_panel_suspend,
178 .resume = lb035q02_panel_resume,
179
180 .driver = {
181 .name = "lgphilips_lb035q02_panel",
182 .owner = THIS_MODULE,
183 },
184};
185
186static int lb035q02_write_reg(struct spi_device *spi, u8 reg, u16 val)
187{
188 struct spi_message msg;
189 struct spi_transfer index_xfer = {
190 .len = 3,
191 .cs_change = 1,
192 };
193 struct spi_transfer value_xfer = {
194 .len = 3,
195 };
196 u8 buffer[16];
197
198 spi_message_init(&msg);
199
200 /* register index */
201 buffer[0] = 0x70;
202 buffer[1] = 0x00;
203 buffer[2] = reg & 0x7f;
204 index_xfer.tx_buf = buffer;
205 spi_message_add_tail(&index_xfer, &msg);
206
207 /* register value */
208 buffer[4] = 0x72;
209 buffer[5] = val >> 8;
210 buffer[6] = val;
211 value_xfer.tx_buf = buffer + 4;
212 spi_message_add_tail(&value_xfer, &msg);
213
214 return spi_sync(spi, &msg);
215}
216
217static void init_lb035q02_panel(struct spi_device *spi)
218{
219 /* Init sequence from page 28 of the lb035q02 spec */
220 lb035q02_write_reg(spi, 0x01, 0x6300);
221 lb035q02_write_reg(spi, 0x02, 0x0200);
222 lb035q02_write_reg(spi, 0x03, 0x0177);
223 lb035q02_write_reg(spi, 0x04, 0x04c7);
224 lb035q02_write_reg(spi, 0x05, 0xffc0);
225 lb035q02_write_reg(spi, 0x06, 0xe806);
226 lb035q02_write_reg(spi, 0x0a, 0x4008);
227 lb035q02_write_reg(spi, 0x0b, 0x0000);
228 lb035q02_write_reg(spi, 0x0d, 0x0030);
229 lb035q02_write_reg(spi, 0x0e, 0x2800);
230 lb035q02_write_reg(spi, 0x0f, 0x0000);
231 lb035q02_write_reg(spi, 0x16, 0x9f80);
232 lb035q02_write_reg(spi, 0x17, 0x0a0f);
233 lb035q02_write_reg(spi, 0x1e, 0x00c1);
234 lb035q02_write_reg(spi, 0x30, 0x0300);
235 lb035q02_write_reg(spi, 0x31, 0x0007);
236 lb035q02_write_reg(spi, 0x32, 0x0000);
237 lb035q02_write_reg(spi, 0x33, 0x0000);
238 lb035q02_write_reg(spi, 0x34, 0x0707);
239 lb035q02_write_reg(spi, 0x35, 0x0004);
240 lb035q02_write_reg(spi, 0x36, 0x0302);
241 lb035q02_write_reg(spi, 0x37, 0x0202);
242 lb035q02_write_reg(spi, 0x3a, 0x0a0d);
243 lb035q02_write_reg(spi, 0x3b, 0x0806);
244}
245
246static int __devinit lb035q02_panel_spi_probe(struct spi_device *spi)
247{
248 init_lb035q02_panel(spi);
249 return omap_dss_register_driver(&lb035q02_driver);
250}
251
252static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi)
253{
254 omap_dss_unregister_driver(&lb035q02_driver);
255 return 0;
256}
257
258static struct spi_driver lb035q02_spi_driver = {
259 .driver = {
260 .name = "lgphilips_lb035q02_panel-spi",
261 .owner = THIS_MODULE,
262 },
263 .probe = lb035q02_panel_spi_probe,
264 .remove = __devexit_p(lb035q02_panel_spi_remove),
265};
266
267static int __init lb035q02_panel_drv_init(void)
268{
269 return spi_register_driver(&lb035q02_spi_driver);
270}
271
272static void __exit lb035q02_panel_drv_exit(void)
273{
274 spi_unregister_driver(&lb035q02_spi_driver);
275}
276
277module_init(lb035q02_panel_drv_init);
278module_exit(lb035q02_panel_drv_exit);
279MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index c74e8b778ba1..adc9900458e1 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -218,6 +218,8 @@ struct taal_data {
218 u16 w; 218 u16 w;
219 u16 h; 219 u16 h;
220 } update_region; 220 } update_region;
221 int channel;
222
221 struct delayed_work te_timeout_work; 223 struct delayed_work te_timeout_work;
222 224
223 bool use_dsi_bl; 225 bool use_dsi_bl;
@@ -257,12 +259,12 @@ static void hw_guard_wait(struct taal_data *td)
257 } 259 }
258} 260}
259 261
260static int taal_dcs_read_1(u8 dcs_cmd, u8 *data) 262static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
261{ 263{
262 int r; 264 int r;
263 u8 buf[1]; 265 u8 buf[1];
264 266
265 r = dsi_vc_dcs_read(TCH, dcs_cmd, buf, 1); 267 r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1);
266 268
267 if (r < 0) 269 if (r < 0)
268 return r; 270 return r;
@@ -272,17 +274,17 @@ static int taal_dcs_read_1(u8 dcs_cmd, u8 *data)
272 return 0; 274 return 0;
273} 275}
274 276
275static int taal_dcs_write_0(u8 dcs_cmd) 277static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
276{ 278{
277 return dsi_vc_dcs_write(TCH, &dcs_cmd, 1); 279 return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1);
278} 280}
279 281
280static int taal_dcs_write_1(u8 dcs_cmd, u8 param) 282static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
281{ 283{
282 u8 buf[2]; 284 u8 buf[2];
283 buf[0] = dcs_cmd; 285 buf[0] = dcs_cmd;
284 buf[1] = param; 286 buf[1] = param;
285 return dsi_vc_dcs_write(TCH, buf, 2); 287 return dsi_vc_dcs_write(td->channel, buf, 2);
286} 288}
287 289
288static int taal_sleep_in(struct taal_data *td) 290static int taal_sleep_in(struct taal_data *td)
@@ -294,7 +296,7 @@ static int taal_sleep_in(struct taal_data *td)
294 hw_guard_wait(td); 296 hw_guard_wait(td);
295 297
296 cmd = DCS_SLEEP_IN; 298 cmd = DCS_SLEEP_IN;
297 r = dsi_vc_dcs_write_nosync(TCH, &cmd, 1); 299 r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1);
298 if (r) 300 if (r)
299 return r; 301 return r;
300 302
@@ -312,7 +314,7 @@ static int taal_sleep_out(struct taal_data *td)
312 314
313 hw_guard_wait(td); 315 hw_guard_wait(td);
314 316
315 r = taal_dcs_write_0(DCS_SLEEP_OUT); 317 r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
316 if (r) 318 if (r)
317 return r; 319 return r;
318 320
@@ -324,30 +326,30 @@ static int taal_sleep_out(struct taal_data *td)
324 return 0; 326 return 0;
325} 327}
326 328
327static int taal_get_id(u8 *id1, u8 *id2, u8 *id3) 329static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
328{ 330{
329 int r; 331 int r;
330 332
331 r = taal_dcs_read_1(DCS_GET_ID1, id1); 333 r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
332 if (r) 334 if (r)
333 return r; 335 return r;
334 r = taal_dcs_read_1(DCS_GET_ID2, id2); 336 r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
335 if (r) 337 if (r)
336 return r; 338 return r;
337 r = taal_dcs_read_1(DCS_GET_ID3, id3); 339 r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
338 if (r) 340 if (r)
339 return r; 341 return r;
340 342
341 return 0; 343 return 0;
342} 344}
343 345
344static int taal_set_addr_mode(u8 rotate, bool mirror) 346static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
345{ 347{
346 int r; 348 int r;
347 u8 mode; 349 u8 mode;
348 int b5, b6, b7; 350 int b5, b6, b7;
349 351
350 r = taal_dcs_read_1(DCS_READ_MADCTL, &mode); 352 r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
351 if (r) 353 if (r)
352 return r; 354 return r;
353 355
@@ -381,10 +383,11 @@ static int taal_set_addr_mode(u8 rotate, bool mirror)
381 mode &= ~((1<<7) | (1<<6) | (1<<5)); 383 mode &= ~((1<<7) | (1<<6) | (1<<5));
382 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5); 384 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
383 385
384 return taal_dcs_write_1(DCS_MEM_ACC_CTRL, mode); 386 return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
385} 387}
386 388
387static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h) 389static int taal_set_update_window(struct taal_data *td,
390 u16 x, u16 y, u16 w, u16 h)
388{ 391{
389 int r; 392 int r;
390 u16 x1 = x; 393 u16 x1 = x;
@@ -399,7 +402,7 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
399 buf[3] = (x2 >> 8) & 0xff; 402 buf[3] = (x2 >> 8) & 0xff;
400 buf[4] = (x2 >> 0) & 0xff; 403 buf[4] = (x2 >> 0) & 0xff;
401 404
402 r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); 405 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
403 if (r) 406 if (r)
404 return r; 407 return r;
405 408
@@ -409,11 +412,11 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
409 buf[3] = (y2 >> 8) & 0xff; 412 buf[3] = (y2 >> 8) & 0xff;
410 buf[4] = (y2 >> 0) & 0xff; 413 buf[4] = (y2 >> 0) & 0xff;
411 414
412 r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); 415 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
413 if (r) 416 if (r)
414 return r; 417 return r;
415 418
416 dsi_vc_send_bta_sync(TCH); 419 dsi_vc_send_bta_sync(td->channel);
417 420
418 return r; 421 return r;
419} 422}
@@ -439,7 +442,7 @@ static int taal_bl_update_status(struct backlight_device *dev)
439 if (td->use_dsi_bl) { 442 if (td->use_dsi_bl) {
440 if (td->enabled) { 443 if (td->enabled) {
441 dsi_bus_lock(); 444 dsi_bus_lock();
442 r = taal_dcs_write_1(DCS_BRIGHTNESS, level); 445 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
443 dsi_bus_unlock(); 446 dsi_bus_unlock();
444 } else { 447 } else {
445 r = 0; 448 r = 0;
@@ -502,7 +505,7 @@ static ssize_t taal_num_errors_show(struct device *dev,
502 505
503 if (td->enabled) { 506 if (td->enabled) {
504 dsi_bus_lock(); 507 dsi_bus_lock();
505 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors); 508 r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
506 dsi_bus_unlock(); 509 dsi_bus_unlock();
507 } else { 510 } else {
508 r = -ENODEV; 511 r = -ENODEV;
@@ -528,7 +531,7 @@ static ssize_t taal_hw_revision_show(struct device *dev,
528 531
529 if (td->enabled) { 532 if (td->enabled) {
530 dsi_bus_lock(); 533 dsi_bus_lock();
531 r = taal_get_id(&id1, &id2, &id3); 534 r = taal_get_id(td, &id1, &id2, &id3);
532 dsi_bus_unlock(); 535 dsi_bus_unlock();
533 } else { 536 } else {
534 r = -ENODEV; 537 r = -ENODEV;
@@ -590,7 +593,7 @@ static ssize_t store_cabc_mode(struct device *dev,
590 if (td->enabled) { 593 if (td->enabled) {
591 dsi_bus_lock(); 594 dsi_bus_lock();
592 if (!td->cabc_broken) 595 if (!td->cabc_broken)
593 taal_dcs_write_1(DCS_WRITE_CABC, i); 596 taal_dcs_write_1(td, DCS_WRITE_CABC, i);
594 dsi_bus_unlock(); 597 dsi_bus_unlock();
595 } 598 }
596 599
@@ -776,14 +779,29 @@ static int taal_probe(struct omap_dss_device *dssdev)
776 dev_dbg(&dssdev->dev, "Using GPIO TE\n"); 779 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
777 } 780 }
778 781
782 r = omap_dsi_request_vc(dssdev, &td->channel);
783 if (r) {
784 dev_err(&dssdev->dev, "failed to get virtual channel\n");
785 goto err_req_vc;
786 }
787
788 r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
789 if (r) {
790 dev_err(&dssdev->dev, "failed to set VC_ID\n");
791 goto err_vc_id;
792 }
793
779 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); 794 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
780 if (r) { 795 if (r) {
781 dev_err(&dssdev->dev, "failed to create sysfs files\n"); 796 dev_err(&dssdev->dev, "failed to create sysfs files\n");
782 goto err_sysfs; 797 goto err_vc_id;
783 } 798 }
784 799
785 return 0; 800 return 0;
786err_sysfs: 801
802err_vc_id:
803 omap_dsi_release_vc(dssdev, td->channel);
804err_req_vc:
787 if (panel_data->use_ext_te) 805 if (panel_data->use_ext_te)
788 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev); 806 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
789err_irq: 807err_irq:
@@ -810,6 +828,7 @@ static void taal_remove(struct omap_dss_device *dssdev)
810 dev_dbg(&dssdev->dev, "remove\n"); 828 dev_dbg(&dssdev->dev, "remove\n");
811 829
812 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); 830 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
831 omap_dsi_release_vc(dssdev, td->channel);
813 832
814 if (panel_data->use_ext_te) { 833 if (panel_data->use_ext_te) {
815 int gpio = panel_data->ext_te_gpio; 834 int gpio = panel_data->ext_te_gpio;
@@ -848,13 +867,13 @@ static int taal_power_on(struct omap_dss_device *dssdev)
848 867
849 taal_hw_reset(dssdev); 868 taal_hw_reset(dssdev);
850 869
851 omapdss_dsi_vc_enable_hs(TCH, false); 870 omapdss_dsi_vc_enable_hs(td->channel, false);
852 871
853 r = taal_sleep_out(td); 872 r = taal_sleep_out(td);
854 if (r) 873 if (r)
855 goto err; 874 goto err;
856 875
857 r = taal_get_id(&id1, &id2, &id3); 876 r = taal_get_id(td, &id1, &id2, &id3);
858 if (r) 877 if (r)
859 goto err; 878 goto err;
860 879
@@ -863,30 +882,30 @@ static int taal_power_on(struct omap_dss_device *dssdev)
863 (id2 == 0x00 || id2 == 0xff || id2 == 0x81)) 882 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
864 td->cabc_broken = true; 883 td->cabc_broken = true;
865 884
866 r = taal_dcs_write_1(DCS_BRIGHTNESS, 0xff); 885 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
867 if (r) 886 if (r)
868 goto err; 887 goto err;
869 888
870 r = taal_dcs_write_1(DCS_CTRL_DISPLAY, 889 r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
871 (1<<2) | (1<<5)); /* BL | BCTRL */ 890 (1<<2) | (1<<5)); /* BL | BCTRL */
872 if (r) 891 if (r)
873 goto err; 892 goto err;
874 893
875 r = taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ 894 r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
876 if (r) 895 if (r)
877 goto err; 896 goto err;
878 897
879 r = taal_set_addr_mode(td->rotate, td->mirror); 898 r = taal_set_addr_mode(td, td->rotate, td->mirror);
880 if (r) 899 if (r)
881 goto err; 900 goto err;
882 901
883 if (!td->cabc_broken) { 902 if (!td->cabc_broken) {
884 r = taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode); 903 r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
885 if (r) 904 if (r)
886 goto err; 905 goto err;
887 } 906 }
888 907
889 r = taal_dcs_write_0(DCS_DISPLAY_ON); 908 r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
890 if (r) 909 if (r)
891 goto err; 910 goto err;
892 911
@@ -905,7 +924,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
905 td->intro_printed = true; 924 td->intro_printed = true;
906 } 925 }
907 926
908 omapdss_dsi_vc_enable_hs(TCH, true); 927 omapdss_dsi_vc_enable_hs(td->channel, true);
909 928
910 return 0; 929 return 0;
911err: 930err:
@@ -923,7 +942,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
923 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 942 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
924 int r; 943 int r;
925 944
926 r = taal_dcs_write_0(DCS_DISPLAY_OFF); 945 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
927 if (!r) { 946 if (!r) {
928 r = taal_sleep_in(td); 947 r = taal_sleep_in(td);
929 /* HACK: wait a bit so that the message goes through */ 948 /* HACK: wait a bit so that the message goes through */
@@ -1091,7 +1110,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
1091 if (old) { 1110 if (old) {
1092 cancel_delayed_work(&td->te_timeout_work); 1111 cancel_delayed_work(&td->te_timeout_work);
1093 1112
1094 r = omap_dsi_update(dssdev, TCH, 1113 r = omap_dsi_update(dssdev, td->channel,
1095 td->update_region.x, 1114 td->update_region.x,
1096 td->update_region.y, 1115 td->update_region.y,
1097 td->update_region.w, 1116 td->update_region.w,
@@ -1141,7 +1160,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1141 if (r) 1160 if (r)
1142 goto err; 1161 goto err;
1143 1162
1144 r = taal_set_update_window(x, y, w, h); 1163 r = taal_set_update_window(td, x, y, w, h);
1145 if (r) 1164 if (r)
1146 goto err; 1165 goto err;
1147 1166
@@ -1155,7 +1174,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1155 msecs_to_jiffies(250)); 1174 msecs_to_jiffies(250));
1156 atomic_set(&td->do_update, 1); 1175 atomic_set(&td->do_update, 1);
1157 } else { 1176 } else {
1158 r = omap_dsi_update(dssdev, TCH, x, y, w, h, 1177 r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
1159 taal_framedone_cb, dssdev); 1178 taal_framedone_cb, dssdev);
1160 if (r) 1179 if (r)
1161 goto err; 1180 goto err;
@@ -1193,9 +1212,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1193 int r; 1212 int r;
1194 1213
1195 if (enable) 1214 if (enable)
1196 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1215 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1197 else 1216 else
1198 r = taal_dcs_write_0(DCS_TEAR_OFF); 1217 r = taal_dcs_write_0(td, DCS_TEAR_OFF);
1199 1218
1200 if (!panel_data->use_ext_te) 1219 if (!panel_data->use_ext_te)
1201 omapdss_dsi_enable_te(dssdev, enable); 1220 omapdss_dsi_enable_te(dssdev, enable);
@@ -1265,7 +1284,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1265 dsi_bus_lock(); 1284 dsi_bus_lock();
1266 1285
1267 if (td->enabled) { 1286 if (td->enabled) {
1268 r = taal_set_addr_mode(rotate, td->mirror); 1287 r = taal_set_addr_mode(td, rotate, td->mirror);
1269 if (r) 1288 if (r)
1270 goto err; 1289 goto err;
1271 } 1290 }
@@ -1308,7 +1327,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1308 1327
1309 dsi_bus_lock(); 1328 dsi_bus_lock();
1310 if (td->enabled) { 1329 if (td->enabled) {
1311 r = taal_set_addr_mode(td->rotate, enable); 1330 r = taal_set_addr_mode(td, td->rotate, enable);
1312 if (r) 1331 if (r)
1313 goto err; 1332 goto err;
1314 } 1333 }
@@ -1352,13 +1371,13 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1352 1371
1353 dsi_bus_lock(); 1372 dsi_bus_lock();
1354 1373
1355 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 1374 r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1356 if (r) 1375 if (r)
1357 goto err2; 1376 goto err2;
1358 r = taal_dcs_read_1(DCS_GET_ID2, &id2); 1377 r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
1359 if (r) 1378 if (r)
1360 goto err2; 1379 goto err2;
1361 r = taal_dcs_read_1(DCS_GET_ID3, &id3); 1380 r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
1362 if (r) 1381 if (r)
1363 goto err2; 1382 goto err2;
1364 1383
@@ -1406,9 +1425,9 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1406 else 1425 else
1407 plen = 2; 1426 plen = 2;
1408 1427
1409 taal_set_update_window(x, y, w, h); 1428 taal_set_update_window(td, x, y, w, h);
1410 1429
1411 r = dsi_vc_set_max_rx_packet_size(TCH, plen); 1430 r = dsi_vc_set_max_rx_packet_size(td->channel, plen);
1412 if (r) 1431 if (r)
1413 goto err2; 1432 goto err2;
1414 1433
@@ -1416,7 +1435,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1416 u8 dcs_cmd = first ? 0x2e : 0x3e; 1435 u8 dcs_cmd = first ? 0x2e : 0x3e;
1417 first = 0; 1436 first = 0;
1418 1437
1419 r = dsi_vc_dcs_read(TCH, dcs_cmd, 1438 r = dsi_vc_dcs_read(td->channel, dcs_cmd,
1420 buf + buf_used, size - buf_used); 1439 buf + buf_used, size - buf_used);
1421 1440
1422 if (r < 0) { 1441 if (r < 0) {
@@ -1442,7 +1461,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1442 r = buf_used; 1461 r = buf_used;
1443 1462
1444err3: 1463err3:
1445 dsi_vc_set_max_rx_packet_size(TCH, 1); 1464 dsi_vc_set_max_rx_packet_size(td->channel, 1);
1446err2: 1465err2:
1447 dsi_bus_unlock(); 1466 dsi_bus_unlock();
1448err1: 1467err1:
@@ -1468,7 +1487,7 @@ static void taal_esd_work(struct work_struct *work)
1468 1487
1469 dsi_bus_lock(); 1488 dsi_bus_lock();
1470 1489
1471 r = taal_dcs_read_1(DCS_RDDSDR, &state1); 1490 r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
1472 if (r) { 1491 if (r) {
1473 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1492 dev_err(&dssdev->dev, "failed to read Taal status\n");
1474 goto err; 1493 goto err;
@@ -1481,7 +1500,7 @@ static void taal_esd_work(struct work_struct *work)
1481 goto err; 1500 goto err;
1482 } 1501 }
1483 1502
1484 r = taal_dcs_read_1(DCS_RDDSDR, &state2); 1503 r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
1485 if (r) { 1504 if (r) {
1486 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1505 dev_err(&dssdev->dev, "failed to read Taal status\n");
1487 goto err; 1506 goto err;
@@ -1497,7 +1516,7 @@ static void taal_esd_work(struct work_struct *work)
1497 /* Self-diagnostics result is also shown on TE GPIO line. We need 1516 /* Self-diagnostics result is also shown on TE GPIO line. We need
1498 * to re-enable TE after self diagnostics */ 1517 * to re-enable TE after self diagnostics */
1499 if (td->te_enabled && panel_data->use_ext_te) { 1518 if (td->te_enabled && panel_data->use_ext_te) {
1500 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1519 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1501 if (r) 1520 if (r)
1502 goto err; 1521 goto err;
1503 } 1522 }
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 43b64403eaa4..bfc5da0e9700 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,8 +1,8 @@
1menuconfig OMAP2_DSS 1menuconfig OMAP2_DSS
2 tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)" 2 tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
3 depends on ARCH_OMAP2 || ARCH_OMAP3 3 depends on ARCH_OMAP2PLUS
4 help 4 help
5 OMAP2/3 Display Subsystem support. 5 OMAP2+ Display Subsystem support.
6 6
7if OMAP2_DSS 7if OMAP2_DSS
8 8
@@ -60,6 +60,14 @@ config OMAP2_DSS_VENC
60 help 60 help
61 OMAP Video Encoder support for S-Video and composite TV-out. 61 OMAP Video Encoder support for S-Video and composite TV-out.
62 62
63config OMAP4_DSS_HDMI
64 bool "HDMI support"
65 depends on ARCH_OMAP4
66 default y
67 help
68 HDMI Interface. This adds the High Definition Multimedia Interface.
69 See http://www.hdmi.org/ for HDMI specification.
70
63config OMAP2_DSS_SDI 71config OMAP2_DSS_SDI
64 bool "SDI support" 72 bool "SDI support"
65 depends on ARCH_OMAP3 73 depends on ARCH_OMAP3
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 7db17b5e570c..10d9d3bb3e24 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -5,3 +5,5 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o 5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o 6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
8omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
9 hdmi_omap4_panel.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 8e89f6049280..1aa2ed1e786e 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -34,332 +34,26 @@
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35 35
36#include <plat/display.h> 36#include <plat/display.h>
37#include <plat/clock.h>
38 37
39#include "dss.h" 38#include "dss.h"
40#include "dss_features.h" 39#include "dss_features.h"
41 40
42static struct { 41static struct {
43 struct platform_device *pdev; 42 struct platform_device *pdev;
44 int ctx_id;
45
46 struct clk *dss_ick;
47 struct clk *dss1_fck;
48 struct clk *dss2_fck;
49 struct clk *dss_54m_fck;
50 struct clk *dss_96m_fck;
51 unsigned num_clks_enabled;
52 43
53 struct regulator *vdds_dsi_reg; 44 struct regulator *vdds_dsi_reg;
54 struct regulator *vdds_sdi_reg; 45 struct regulator *vdds_sdi_reg;
55 struct regulator *vdda_dac_reg;
56} core; 46} core;
57 47
58static void dss_clk_enable_all_no_ctx(void);
59static void dss_clk_disable_all_no_ctx(void);
60static void dss_clk_enable_no_ctx(enum dss_clock clks);
61static void dss_clk_disable_no_ctx(enum dss_clock clks);
62
63static char *def_disp_name; 48static char *def_disp_name;
64module_param_named(def_disp, def_disp_name, charp, 0); 49module_param_named(def_disp, def_disp_name, charp, 0);
65MODULE_PARM_DESC(def_disp_name, "default display name"); 50MODULE_PARM_DESC(def_disp, "default display name");
66 51
67#ifdef DEBUG 52#ifdef DEBUG
68unsigned int dss_debug; 53unsigned int dss_debug;
69module_param_named(debug, dss_debug, bool, 0644); 54module_param_named(debug, dss_debug, bool, 0644);
70#endif 55#endif
71 56
72/* CONTEXT */
73static int dss_get_ctx_id(void)
74{
75 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
76 int r;
77
78 if (!pdata->get_last_off_on_transaction_id)
79 return 0;
80 r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
81 if (r < 0) {
82 dev_err(&core.pdev->dev, "getting transaction ID failed, "
83 "will force context restore\n");
84 r = -1;
85 }
86 return r;
87}
88
89int dss_need_ctx_restore(void)
90{
91 int id = dss_get_ctx_id();
92
93 if (id < 0 || id != core.ctx_id) {
94 DSSDBG("ctx id %d -> id %d\n",
95 core.ctx_id, id);
96 core.ctx_id = id;
97 return 1;
98 } else {
99 return 0;
100 }
101}
102
103static void save_all_ctx(void)
104{
105 DSSDBG("save context\n");
106
107 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
108
109 dss_save_context();
110 dispc_save_context();
111#ifdef CONFIG_OMAP2_DSS_DSI
112 dsi_save_context();
113#endif
114
115 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
116}
117
118static void restore_all_ctx(void)
119{
120 DSSDBG("restore context\n");
121
122 dss_clk_enable_all_no_ctx();
123
124 dss_restore_context();
125 dispc_restore_context();
126#ifdef CONFIG_OMAP2_DSS_DSI
127 dsi_restore_context();
128#endif
129
130 dss_clk_disable_all_no_ctx();
131}
132
133#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
134/* CLOCKS */
135static void core_dump_clocks(struct seq_file *s)
136{
137 int i;
138 struct clk *clocks[5] = {
139 core.dss_ick,
140 core.dss1_fck,
141 core.dss2_fck,
142 core.dss_54m_fck,
143 core.dss_96m_fck
144 };
145
146 seq_printf(s, "- CORE -\n");
147
148 seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
149
150 for (i = 0; i < 5; i++) {
151 if (!clocks[i])
152 continue;
153 seq_printf(s, "%-15s\t%lu\t%d\n",
154 clocks[i]->name,
155 clk_get_rate(clocks[i]),
156 clocks[i]->usecount);
157 }
158}
159#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
160
161static int dss_get_clock(struct clk **clock, const char *clk_name)
162{
163 struct clk *clk;
164
165 clk = clk_get(&core.pdev->dev, clk_name);
166
167 if (IS_ERR(clk)) {
168 DSSERR("can't get clock %s", clk_name);
169 return PTR_ERR(clk);
170 }
171
172 *clock = clk;
173
174 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
175
176 return 0;
177}
178
179static int dss_get_clocks(void)
180{
181 int r;
182
183 core.dss_ick = NULL;
184 core.dss1_fck = NULL;
185 core.dss2_fck = NULL;
186 core.dss_54m_fck = NULL;
187 core.dss_96m_fck = NULL;
188
189 r = dss_get_clock(&core.dss_ick, "ick");
190 if (r)
191 goto err;
192
193 r = dss_get_clock(&core.dss1_fck, "dss1_fck");
194 if (r)
195 goto err;
196
197 r = dss_get_clock(&core.dss2_fck, "dss2_fck");
198 if (r)
199 goto err;
200
201 r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
202 if (r)
203 goto err;
204
205 r = dss_get_clock(&core.dss_96m_fck, "video_fck");
206 if (r)
207 goto err;
208
209 return 0;
210
211err:
212 if (core.dss_ick)
213 clk_put(core.dss_ick);
214 if (core.dss1_fck)
215 clk_put(core.dss1_fck);
216 if (core.dss2_fck)
217 clk_put(core.dss2_fck);
218 if (core.dss_54m_fck)
219 clk_put(core.dss_54m_fck);
220 if (core.dss_96m_fck)
221 clk_put(core.dss_96m_fck);
222
223 return r;
224}
225
226static void dss_put_clocks(void)
227{
228 if (core.dss_96m_fck)
229 clk_put(core.dss_96m_fck);
230 clk_put(core.dss_54m_fck);
231 clk_put(core.dss1_fck);
232 clk_put(core.dss2_fck);
233 clk_put(core.dss_ick);
234}
235
236unsigned long dss_clk_get_rate(enum dss_clock clk)
237{
238 switch (clk) {
239 case DSS_CLK_ICK:
240 return clk_get_rate(core.dss_ick);
241 case DSS_CLK_FCK1:
242 return clk_get_rate(core.dss1_fck);
243 case DSS_CLK_FCK2:
244 return clk_get_rate(core.dss2_fck);
245 case DSS_CLK_54M:
246 return clk_get_rate(core.dss_54m_fck);
247 case DSS_CLK_96M:
248 return clk_get_rate(core.dss_96m_fck);
249 }
250
251 BUG();
252 return 0;
253}
254
255static unsigned count_clk_bits(enum dss_clock clks)
256{
257 unsigned num_clks = 0;
258
259 if (clks & DSS_CLK_ICK)
260 ++num_clks;
261 if (clks & DSS_CLK_FCK1)
262 ++num_clks;
263 if (clks & DSS_CLK_FCK2)
264 ++num_clks;
265 if (clks & DSS_CLK_54M)
266 ++num_clks;
267 if (clks & DSS_CLK_96M)
268 ++num_clks;
269
270 return num_clks;
271}
272
273static void dss_clk_enable_no_ctx(enum dss_clock clks)
274{
275 unsigned num_clks = count_clk_bits(clks);
276
277 if (clks & DSS_CLK_ICK)
278 clk_enable(core.dss_ick);
279 if (clks & DSS_CLK_FCK1)
280 clk_enable(core.dss1_fck);
281 if (clks & DSS_CLK_FCK2)
282 clk_enable(core.dss2_fck);
283 if (clks & DSS_CLK_54M)
284 clk_enable(core.dss_54m_fck);
285 if (clks & DSS_CLK_96M)
286 clk_enable(core.dss_96m_fck);
287
288 core.num_clks_enabled += num_clks;
289}
290
291void dss_clk_enable(enum dss_clock clks)
292{
293 bool check_ctx = core.num_clks_enabled == 0;
294
295 dss_clk_enable_no_ctx(clks);
296
297 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
298 restore_all_ctx();
299}
300
301static void dss_clk_disable_no_ctx(enum dss_clock clks)
302{
303 unsigned num_clks = count_clk_bits(clks);
304
305 if (clks & DSS_CLK_ICK)
306 clk_disable(core.dss_ick);
307 if (clks & DSS_CLK_FCK1)
308 clk_disable(core.dss1_fck);
309 if (clks & DSS_CLK_FCK2)
310 clk_disable(core.dss2_fck);
311 if (clks & DSS_CLK_54M)
312 clk_disable(core.dss_54m_fck);
313 if (clks & DSS_CLK_96M)
314 clk_disable(core.dss_96m_fck);
315
316 core.num_clks_enabled -= num_clks;
317}
318
319void dss_clk_disable(enum dss_clock clks)
320{
321 if (cpu_is_omap34xx()) {
322 unsigned num_clks = count_clk_bits(clks);
323
324 BUG_ON(core.num_clks_enabled < num_clks);
325
326 if (core.num_clks_enabled == num_clks)
327 save_all_ctx();
328 }
329
330 dss_clk_disable_no_ctx(clks);
331}
332
333static void dss_clk_enable_all_no_ctx(void)
334{
335 enum dss_clock clks;
336
337 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
338 if (cpu_is_omap34xx())
339 clks |= DSS_CLK_96M;
340 dss_clk_enable_no_ctx(clks);
341}
342
343static void dss_clk_disable_all_no_ctx(void)
344{
345 enum dss_clock clks;
346
347 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
348 if (cpu_is_omap34xx())
349 clks |= DSS_CLK_96M;
350 dss_clk_disable_no_ctx(clks);
351}
352
353static void dss_clk_disable_all(void)
354{
355 enum dss_clock clks;
356
357 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
358 if (cpu_is_omap34xx())
359 clks |= DSS_CLK_96M;
360 dss_clk_disable(clks);
361}
362
363/* REGULATORS */ 57/* REGULATORS */
364 58
365struct regulator *dss_get_vdds_dsi(void) 59struct regulator *dss_get_vdds_dsi(void)
@@ -390,32 +84,7 @@ struct regulator *dss_get_vdds_sdi(void)
390 return reg; 84 return reg;
391} 85}
392 86
393struct regulator *dss_get_vdda_dac(void)
394{
395 struct regulator *reg;
396
397 if (core.vdda_dac_reg != NULL)
398 return core.vdda_dac_reg;
399
400 reg = regulator_get(&core.pdev->dev, "vdda_dac");
401 if (!IS_ERR(reg))
402 core.vdda_dac_reg = reg;
403
404 return reg;
405}
406
407/* DEBUGFS */
408#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 87#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
409static void dss_debug_dump_clocks(struct seq_file *s)
410{
411 core_dump_clocks(s);
412 dss_dump_clocks(s);
413 dispc_dump_clocks(s);
414#ifdef CONFIG_OMAP2_DSS_DSI
415 dsi_dump_clocks(s);
416#endif
417}
418
419static int dss_debug_show(struct seq_file *s, void *unused) 88static int dss_debug_show(struct seq_file *s, void *unused)
420{ 89{
421 void (*func)(struct seq_file *) = s->private; 90 void (*func)(struct seq_file *) = s->private;
@@ -497,7 +166,6 @@ static inline void dss_uninitialize_debugfs(void)
497static int omap_dss_probe(struct platform_device *pdev) 166static int omap_dss_probe(struct platform_device *pdev)
498{ 167{
499 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 168 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
500 int skip_init = 0;
501 int r; 169 int r;
502 int i; 170 int i;
503 171
@@ -508,63 +176,43 @@ static int omap_dss_probe(struct platform_device *pdev)
508 dss_init_overlay_managers(pdev); 176 dss_init_overlay_managers(pdev);
509 dss_init_overlays(pdev); 177 dss_init_overlays(pdev);
510 178
511 r = dss_get_clocks(); 179 r = dss_init_platform_driver();
512 if (r)
513 goto err_clocks;
514
515 dss_clk_enable_all_no_ctx();
516
517 core.ctx_id = dss_get_ctx_id();
518 DSSDBG("initial ctx id %u\n", core.ctx_id);
519
520#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
521 /* DISPC_CONTROL */
522 if (omap_readl(0x48050440) & 1) /* LCD enabled? */
523 skip_init = 1;
524#endif
525
526 r = dss_init(skip_init);
527 if (r) { 180 if (r) {
528 DSSERR("Failed to initialize DSS\n"); 181 DSSERR("Failed to initialize DSS platform driver\n");
529 goto err_dss; 182 goto err_dss;
530 } 183 }
531 184
532 r = rfbi_init(); 185 /* keep clocks enabled to prevent context saves/restores during init */
533 if (r) { 186 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
534 DSSERR("Failed to initialize rfbi\n");
535 goto err_rfbi;
536 }
537 187
538 r = dpi_init(pdev); 188 r = rfbi_init_platform_driver();
539 if (r) { 189 if (r) {
540 DSSERR("Failed to initialize dpi\n"); 190 DSSERR("Failed to initialize rfbi platform driver\n");
541 goto err_dpi; 191 goto err_rfbi;
542 } 192 }
543 193
544 r = dispc_init(); 194 r = dispc_init_platform_driver();
545 if (r) { 195 if (r) {
546 DSSERR("Failed to initialize dispc\n"); 196 DSSERR("Failed to initialize dispc platform driver\n");
547 goto err_dispc; 197 goto err_dispc;
548 } 198 }
549 199
550 r = venc_init(pdev); 200 r = venc_init_platform_driver();
551 if (r) { 201 if (r) {
552 DSSERR("Failed to initialize venc\n"); 202 DSSERR("Failed to initialize venc platform driver\n");
553 goto err_venc; 203 goto err_venc;
554 } 204 }
555 205
556 if (cpu_is_omap34xx()) { 206 r = dsi_init_platform_driver();
557 r = sdi_init(skip_init); 207 if (r) {
558 if (r) { 208 DSSERR("Failed to initialize DSI platform driver\n");
559 DSSERR("Failed to initialize SDI\n"); 209 goto err_dsi;
560 goto err_sdi; 210 }
561 }
562 211
563 r = dsi_init(pdev); 212 r = hdmi_init_platform_driver();
564 if (r) { 213 if (r) {
565 DSSERR("Failed to initialize DSI\n"); 214 DSSERR("Failed to initialize hdmi\n");
566 goto err_dsi; 215 goto err_hdmi;
567 }
568 } 216 }
569 217
570 r = dss_initialize_debugfs(); 218 r = dss_initialize_debugfs();
@@ -589,32 +237,25 @@ static int omap_dss_probe(struct platform_device *pdev)
589 pdata->default_device = dssdev; 237 pdata->default_device = dssdev;
590 } 238 }
591 239
592 dss_clk_disable_all(); 240 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
593 241
594 return 0; 242 return 0;
595 243
596err_register: 244err_register:
597 dss_uninitialize_debugfs(); 245 dss_uninitialize_debugfs();
598err_debugfs: 246err_debugfs:
599 if (cpu_is_omap34xx()) 247 hdmi_uninit_platform_driver();
600 dsi_exit(); 248err_hdmi:
249 dsi_uninit_platform_driver();
601err_dsi: 250err_dsi:
602 if (cpu_is_omap34xx()) 251 venc_uninit_platform_driver();
603 sdi_exit();
604err_sdi:
605 venc_exit();
606err_venc: 252err_venc:
607 dispc_exit(); 253 dispc_uninit_platform_driver();
608err_dispc: 254err_dispc:
609 dpi_exit(); 255 rfbi_uninit_platform_driver();
610err_dpi:
611 rfbi_exit();
612err_rfbi: 256err_rfbi:
613 dss_exit(); 257 dss_uninit_platform_driver();
614err_dss: 258err_dss:
615 dss_clk_disable_all_no_ctx();
616 dss_put_clocks();
617err_clocks:
618 259
619 return r; 260 return r;
620} 261}
@@ -623,61 +264,15 @@ static int omap_dss_remove(struct platform_device *pdev)
623{ 264{
624 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 265 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
625 int i; 266 int i;
626 int c;
627 267
628 dss_uninitialize_debugfs(); 268 dss_uninitialize_debugfs();
629 269
630 venc_exit(); 270 venc_uninit_platform_driver();
631 dispc_exit(); 271 dispc_uninit_platform_driver();
632 dpi_exit(); 272 rfbi_uninit_platform_driver();
633 rfbi_exit(); 273 dsi_uninit_platform_driver();
634 if (cpu_is_omap34xx()) { 274 hdmi_uninit_platform_driver();
635 dsi_exit(); 275 dss_uninit_platform_driver();
636 sdi_exit();
637 }
638
639 dss_exit();
640
641 /* these should be removed at some point */
642 c = core.dss_ick->usecount;
643 if (c > 0) {
644 DSSERR("warning: dss_ick usecount %d, disabling\n", c);
645 while (c-- > 0)
646 clk_disable(core.dss_ick);
647 }
648
649 c = core.dss1_fck->usecount;
650 if (c > 0) {
651 DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
652 while (c-- > 0)
653 clk_disable(core.dss1_fck);
654 }
655
656 c = core.dss2_fck->usecount;
657 if (c > 0) {
658 DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
659 while (c-- > 0)
660 clk_disable(core.dss2_fck);
661 }
662
663 c = core.dss_54m_fck->usecount;
664 if (c > 0) {
665 DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
666 while (c-- > 0)
667 clk_disable(core.dss_54m_fck);
668 }
669
670 if (core.dss_96m_fck) {
671 c = core.dss_96m_fck->usecount;
672 if (c > 0) {
673 DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
674 c);
675 while (c-- > 0)
676 clk_disable(core.dss_96m_fck);
677 }
678 }
679
680 dss_put_clocks();
681 276
682 dss_uninit_overlays(pdev); 277 dss_uninit_overlays(pdev);
683 dss_uninit_overlay_managers(pdev); 278 dss_uninit_overlay_managers(pdev);
@@ -965,11 +560,6 @@ static void __exit omap_dss_exit(void)
965 core.vdds_sdi_reg = NULL; 560 core.vdds_sdi_reg = NULL;
966 } 561 }
967 562
968 if (core.vdda_dac_reg != NULL) {
969 regulator_put(core.vdda_dac_reg);
970 core.vdda_dac_reg = NULL;
971 }
972
973 platform_driver_unregister(&omap_dss_driver); 563 platform_driver_unregister(&omap_dss_driver);
974 564
975 omap_dss_bus_unregister(); 565 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 9f8c69f16e61..7804779c9da1 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -32,6 +32,7 @@
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#include <linux/hardirq.h>
35#include <linux/interrupt.h>
35 36
36#include <plat/sram.h> 37#include <plat/sram.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
@@ -42,8 +43,6 @@
42#include "dss_features.h" 43#include "dss_features.h"
43 44
44/* DISPC */ 45/* DISPC */
45#define DISPC_BASE 0x48050400
46
47#define DISPC_SZ_REGS SZ_4K 46#define DISPC_SZ_REGS SZ_4K
48 47
49struct dispc_reg { u16 idx; }; 48struct dispc_reg { u16 idx; };
@@ -74,7 +73,7 @@ struct dispc_reg { u16 idx; };
74#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400) 73#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
75#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404) 74#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
76#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408) 75#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408)
77#define DISPC_DIVISOR(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C) 76#define DISPC_DIVISORo(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
78#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074) 77#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
79#define DISPC_SIZE_DIG DISPC_REG(0x0078) 78#define DISPC_SIZE_DIG DISPC_REG(0x0078)
80#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC) 79#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
@@ -129,6 +128,7 @@ struct dispc_reg { u16 idx; };
129 128
130#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04) 129#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
131 130
131#define DISPC_DIVISOR DISPC_REG(0x0804)
132 132
133#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ 133#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
134 DISPC_IRQ_OCP_ERR | \ 134 DISPC_IRQ_OCP_ERR | \
@@ -178,7 +178,9 @@ struct dispc_irq_stats {
178}; 178};
179 179
180static struct { 180static struct {
181 struct platform_device *pdev;
181 void __iomem *base; 182 void __iomem *base;
183 int irq;
182 184
183 u32 fifo_size[3]; 185 u32 fifo_size[3];
184 186
@@ -230,7 +232,7 @@ void dispc_save_context(void)
230 SR(TIMING_H(0)); 232 SR(TIMING_H(0));
231 SR(TIMING_V(0)); 233 SR(TIMING_V(0));
232 SR(POL_FREQ(0)); 234 SR(POL_FREQ(0));
233 SR(DIVISOR(0)); 235 SR(DIVISORo(0));
234 SR(GLOBAL_ALPHA); 236 SR(GLOBAL_ALPHA);
235 SR(SIZE_DIG); 237 SR(SIZE_DIG);
236 SR(SIZE_LCD(0)); 238 SR(SIZE_LCD(0));
@@ -242,7 +244,7 @@ void dispc_save_context(void)
242 SR(TIMING_H(2)); 244 SR(TIMING_H(2));
243 SR(TIMING_V(2)); 245 SR(TIMING_V(2));
244 SR(POL_FREQ(2)); 246 SR(POL_FREQ(2));
245 SR(DIVISOR(2)); 247 SR(DIVISORo(2));
246 SR(CONFIG2); 248 SR(CONFIG2);
247 } 249 }
248 250
@@ -373,6 +375,9 @@ void dispc_save_context(void)
373 SR(VID_FIR_COEF_V(1, 7)); 375 SR(VID_FIR_COEF_V(1, 7));
374 376
375 SR(VID_PRELOAD(1)); 377 SR(VID_PRELOAD(1));
378
379 if (dss_has_feature(FEAT_CORE_CLK_DIV))
380 SR(DIVISOR);
376} 381}
377 382
378void dispc_restore_context(void) 383void dispc_restore_context(void)
@@ -389,7 +394,7 @@ void dispc_restore_context(void)
389 RR(TIMING_H(0)); 394 RR(TIMING_H(0));
390 RR(TIMING_V(0)); 395 RR(TIMING_V(0));
391 RR(POL_FREQ(0)); 396 RR(POL_FREQ(0));
392 RR(DIVISOR(0)); 397 RR(DIVISORo(0));
393 RR(GLOBAL_ALPHA); 398 RR(GLOBAL_ALPHA);
394 RR(SIZE_DIG); 399 RR(SIZE_DIG);
395 RR(SIZE_LCD(0)); 400 RR(SIZE_LCD(0));
@@ -400,7 +405,7 @@ void dispc_restore_context(void)
400 RR(TIMING_H(2)); 405 RR(TIMING_H(2));
401 RR(TIMING_V(2)); 406 RR(TIMING_V(2));
402 RR(POL_FREQ(2)); 407 RR(POL_FREQ(2));
403 RR(DIVISOR(2)); 408 RR(DIVISORo(2));
404 RR(CONFIG2); 409 RR(CONFIG2);
405 } 410 }
406 411
@@ -532,6 +537,9 @@ void dispc_restore_context(void)
532 537
533 RR(VID_PRELOAD(1)); 538 RR(VID_PRELOAD(1));
534 539
540 if (dss_has_feature(FEAT_CORE_CLK_DIV))
541 RR(DIVISOR);
542
535 /* enable last, because LCD & DIGIT enable are here */ 543 /* enable last, because LCD & DIGIT enable are here */
536 RR(CONTROL); 544 RR(CONTROL);
537 if (dss_has_feature(FEAT_MGR_LCD2)) 545 if (dss_has_feature(FEAT_MGR_LCD2))
@@ -552,9 +560,9 @@ void dispc_restore_context(void)
552static inline void enable_clocks(bool enable) 560static inline void enable_clocks(bool enable)
553{ 561{
554 if (enable) 562 if (enable)
555 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 563 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
556 else 564 else
557 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 565 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
558} 566}
559 567
560bool dispc_go_busy(enum omap_channel channel) 568bool dispc_go_busy(enum omap_channel channel)
@@ -1000,6 +1008,20 @@ void dispc_set_burst_size(enum omap_plane plane,
1000 enable_clocks(0); 1008 enable_clocks(0);
1001} 1009}
1002 1010
1011void dispc_enable_gamma_table(bool enable)
1012{
1013 /*
1014 * This is partially implemented to support only disabling of
1015 * the gamma table.
1016 */
1017 if (enable) {
1018 DSSWARN("Gamma table enabling for TV not yet supported");
1019 return;
1020 }
1021
1022 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
1023}
1024
1003static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) 1025static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
1004{ 1026{
1005 u32 val; 1027 u32 val;
@@ -1129,10 +1151,16 @@ static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
1129 u32 val; 1151 u32 val;
1130 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0), 1152 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0),
1131 DISPC_VID_ACCU0(1) }; 1153 DISPC_VID_ACCU0(1) };
1154 u8 hor_start, hor_end, vert_start, vert_end;
1132 1155
1133 BUG_ON(plane == OMAP_DSS_GFX); 1156 BUG_ON(plane == OMAP_DSS_GFX);
1134 1157
1135 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1158 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1159 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1160
1161 val = FLD_VAL(vaccu, vert_start, vert_end) |
1162 FLD_VAL(haccu, hor_start, hor_end);
1163
1136 dispc_write_reg(ac0_reg[plane-1], val); 1164 dispc_write_reg(ac0_reg[plane-1], val);
1137} 1165}
1138 1166
@@ -1141,10 +1169,16 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
1141 u32 val; 1169 u32 val;
1142 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0), 1170 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0),
1143 DISPC_VID_ACCU1(1) }; 1171 DISPC_VID_ACCU1(1) };
1172 u8 hor_start, hor_end, vert_start, vert_end;
1144 1173
1145 BUG_ON(plane == OMAP_DSS_GFX); 1174 BUG_ON(plane == OMAP_DSS_GFX);
1146 1175
1147 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1176 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1177 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1178
1179 val = FLD_VAL(vaccu, vert_start, vert_end) |
1180 FLD_VAL(haccu, hor_start, hor_end);
1181
1148 dispc_write_reg(ac1_reg[plane-1], val); 1182 dispc_write_reg(ac1_reg[plane-1], val);
1149} 1183}
1150 1184
@@ -1182,16 +1216,25 @@ static void _dispc_set_scaling(enum omap_plane plane,
1182 _dispc_set_fir(plane, fir_hinc, fir_vinc); 1216 _dispc_set_fir(plane, fir_hinc, fir_vinc);
1183 1217
1184 l = dispc_read_reg(dispc_reg_att[plane]); 1218 l = dispc_read_reg(dispc_reg_att[plane]);
1185 l &= ~((0x0f << 5) | (0x3 << 21));
1186 1219
1220 /* RESIZEENABLE and VERTICALTAPS */
1221 l &= ~((0x3 << 5) | (0x1 << 21));
1187 l |= fir_hinc ? (1 << 5) : 0; 1222 l |= fir_hinc ? (1 << 5) : 0;
1188 l |= fir_vinc ? (1 << 6) : 0; 1223 l |= fir_vinc ? (1 << 6) : 0;
1224 l |= five_taps ? (1 << 21) : 0;
1189 1225
1190 l |= hscaleup ? 0 : (1 << 7); 1226 /* VRESIZECONF and HRESIZECONF */
1191 l |= vscaleup ? 0 : (1 << 8); 1227 if (dss_has_feature(FEAT_RESIZECONF)) {
1228 l &= ~(0x3 << 7);
1229 l |= hscaleup ? 0 : (1 << 7);
1230 l |= vscaleup ? 0 : (1 << 8);
1231 }
1192 1232
1193 l |= five_taps ? (1 << 21) : 0; 1233 /* LINEBUFFERSPLIT */
1194 l |= five_taps ? (1 << 22) : 0; 1234 if (dss_has_feature(FEAT_LINEBUFFERSPLIT)) {
1235 l &= ~(0x1 << 22);
1236 l |= five_taps ? (1 << 22) : 0;
1237 }
1195 1238
1196 dispc_write_reg(dispc_reg_att[plane], l); 1239 dispc_write_reg(dispc_reg_att[plane], l);
1197 1240
@@ -1215,9 +1258,11 @@ static void _dispc_set_scaling(enum omap_plane plane,
1215static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1258static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1216 bool mirroring, enum omap_color_mode color_mode) 1259 bool mirroring, enum omap_color_mode color_mode)
1217{ 1260{
1261 bool row_repeat = false;
1262 int vidrot = 0;
1263
1218 if (color_mode == OMAP_DSS_COLOR_YUV2 || 1264 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1219 color_mode == OMAP_DSS_COLOR_UYVY) { 1265 color_mode == OMAP_DSS_COLOR_UYVY) {
1220 int vidrot = 0;
1221 1266
1222 if (mirroring) { 1267 if (mirroring) {
1223 switch (rotation) { 1268 switch (rotation) {
@@ -1251,16 +1296,15 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1251 } 1296 }
1252 } 1297 }
1253 1298
1254 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
1255
1256 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270) 1299 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270)
1257 REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18); 1300 row_repeat = true;
1258 else 1301 else
1259 REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18); 1302 row_repeat = false;
1260 } else {
1261 REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
1262 REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
1263 } 1303 }
1304
1305 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
1306 if (dss_has_feature(FEAT_ROWREPEATENABLE))
1307 REG_FLD_MOD(dispc_reg_att[plane], row_repeat ? 1 : 0, 18, 18);
1264} 1308}
1265 1309
1266static int color_mode_to_bpp(enum omap_color_mode color_mode) 1310static int color_mode_to_bpp(enum omap_color_mode color_mode)
@@ -2293,7 +2337,7 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2293 BUG_ON(pck_div < 2); 2337 BUG_ON(pck_div < 2);
2294 2338
2295 enable_clocks(1); 2339 enable_clocks(1);
2296 dispc_write_reg(DISPC_DIVISOR(channel), 2340 dispc_write_reg(DISPC_DIVISORo(channel),
2297 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2341 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2298 enable_clocks(0); 2342 enable_clocks(0);
2299} 2343}
@@ -2302,7 +2346,7 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
2302 int *pck_div) 2346 int *pck_div)
2303{ 2347{
2304 u32 l; 2348 u32 l;
2305 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2349 l = dispc_read_reg(DISPC_DIVISORo(channel));
2306 *lck_div = FLD_GET(l, 23, 16); 2350 *lck_div = FLD_GET(l, 23, 16);
2307 *pck_div = FLD_GET(l, 7, 0); 2351 *pck_div = FLD_GET(l, 7, 0);
2308} 2352}
@@ -2311,14 +2355,17 @@ unsigned long dispc_fclk_rate(void)
2311{ 2355{
2312 unsigned long r = 0; 2356 unsigned long r = 0;
2313 2357
2314 if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) 2358 switch (dss_get_dispc_clk_source()) {
2315 r = dss_clk_get_rate(DSS_CLK_FCK1); 2359 case DSS_CLK_SRC_FCK:
2316 else 2360 r = dss_clk_get_rate(DSS_CLK_FCK);
2317#ifdef CONFIG_OMAP2_DSS_DSI 2361 break;
2318 r = dsi_get_dsi1_pll_rate(); 2362 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2319#else 2363 r = dsi_get_pll_hsdiv_dispc_rate();
2320 BUG(); 2364 break;
2321#endif 2365 default:
2366 BUG();
2367 }
2368
2322 return r; 2369 return r;
2323} 2370}
2324 2371
@@ -2328,47 +2375,72 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
2328 unsigned long r; 2375 unsigned long r;
2329 u32 l; 2376 u32 l;
2330 2377
2331 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2378 l = dispc_read_reg(DISPC_DIVISORo(channel));
2332 2379
2333 lcd = FLD_GET(l, 23, 16); 2380 lcd = FLD_GET(l, 23, 16);
2334 2381
2335 r = dispc_fclk_rate(); 2382 switch (dss_get_lcd_clk_source(channel)) {
2383 case DSS_CLK_SRC_FCK:
2384 r = dss_clk_get_rate(DSS_CLK_FCK);
2385 break;
2386 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2387 r = dsi_get_pll_hsdiv_dispc_rate();
2388 break;
2389 default:
2390 BUG();
2391 }
2336 2392
2337 return r / lcd; 2393 return r / lcd;
2338} 2394}
2339 2395
2340unsigned long dispc_pclk_rate(enum omap_channel channel) 2396unsigned long dispc_pclk_rate(enum omap_channel channel)
2341{ 2397{
2342 int lcd, pcd; 2398 int pcd;
2343 unsigned long r; 2399 unsigned long r;
2344 u32 l; 2400 u32 l;
2345 2401
2346 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2402 l = dispc_read_reg(DISPC_DIVISORo(channel));
2347 2403
2348 lcd = FLD_GET(l, 23, 16);
2349 pcd = FLD_GET(l, 7, 0); 2404 pcd = FLD_GET(l, 7, 0);
2350 2405
2351 r = dispc_fclk_rate(); 2406 r = dispc_lclk_rate(channel);
2352 2407
2353 return r / lcd / pcd; 2408 return r / pcd;
2354} 2409}
2355 2410
2356void dispc_dump_clocks(struct seq_file *s) 2411void dispc_dump_clocks(struct seq_file *s)
2357{ 2412{
2358 int lcd, pcd; 2413 int lcd, pcd;
2414 u32 l;
2415 enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2416 enum dss_clk_source lcd_clk_src;
2359 2417
2360 enable_clocks(1); 2418 enable_clocks(1);
2361 2419
2362 seq_printf(s, "- DISPC -\n"); 2420 seq_printf(s, "- DISPC -\n");
2363 2421
2364 seq_printf(s, "dispc fclk source = %s\n", 2422 seq_printf(s, "dispc fclk source = %s (%s)\n",
2365 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 2423 dss_get_generic_clk_source_name(dispc_clk_src),
2366 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2424 dss_feat_get_clk_source_name(dispc_clk_src));
2367 2425
2368 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2426 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
2369 2427
2428 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
2429 seq_printf(s, "- DISPC-CORE-CLK -\n");
2430 l = dispc_read_reg(DISPC_DIVISOR);
2431 lcd = FLD_GET(l, 23, 16);
2432
2433 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2434 (dispc_fclk_rate()/lcd), lcd);
2435 }
2370 seq_printf(s, "- LCD1 -\n"); 2436 seq_printf(s, "- LCD1 -\n");
2371 2437
2438 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD);
2439
2440 seq_printf(s, "lcd1_clk source = %s (%s)\n",
2441 dss_get_generic_clk_source_name(lcd_clk_src),
2442 dss_feat_get_clk_source_name(lcd_clk_src));
2443
2372 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); 2444 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2373 2445
2374 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2446 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
@@ -2378,6 +2450,12 @@ void dispc_dump_clocks(struct seq_file *s)
2378 if (dss_has_feature(FEAT_MGR_LCD2)) { 2450 if (dss_has_feature(FEAT_MGR_LCD2)) {
2379 seq_printf(s, "- LCD2 -\n"); 2451 seq_printf(s, "- LCD2 -\n");
2380 2452
2453 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2);
2454
2455 seq_printf(s, "lcd2_clk source = %s (%s)\n",
2456 dss_get_generic_clk_source_name(lcd_clk_src),
2457 dss_feat_get_clk_source_name(lcd_clk_src));
2458
2381 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); 2459 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
2382 2460
2383 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2461 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
@@ -2440,7 +2518,7 @@ void dispc_dump_regs(struct seq_file *s)
2440{ 2518{
2441#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) 2519#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
2442 2520
2443 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 2521 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
2444 2522
2445 DUMPREG(DISPC_REVISION); 2523 DUMPREG(DISPC_REVISION);
2446 DUMPREG(DISPC_SYSCONFIG); 2524 DUMPREG(DISPC_SYSCONFIG);
@@ -2459,7 +2537,7 @@ void dispc_dump_regs(struct seq_file *s)
2459 DUMPREG(DISPC_TIMING_H(0)); 2537 DUMPREG(DISPC_TIMING_H(0));
2460 DUMPREG(DISPC_TIMING_V(0)); 2538 DUMPREG(DISPC_TIMING_V(0));
2461 DUMPREG(DISPC_POL_FREQ(0)); 2539 DUMPREG(DISPC_POL_FREQ(0));
2462 DUMPREG(DISPC_DIVISOR(0)); 2540 DUMPREG(DISPC_DIVISORo(0));
2463 DUMPREG(DISPC_GLOBAL_ALPHA); 2541 DUMPREG(DISPC_GLOBAL_ALPHA);
2464 DUMPREG(DISPC_SIZE_DIG); 2542 DUMPREG(DISPC_SIZE_DIG);
2465 DUMPREG(DISPC_SIZE_LCD(0)); 2543 DUMPREG(DISPC_SIZE_LCD(0));
@@ -2471,7 +2549,7 @@ void dispc_dump_regs(struct seq_file *s)
2471 DUMPREG(DISPC_TIMING_H(2)); 2549 DUMPREG(DISPC_TIMING_H(2));
2472 DUMPREG(DISPC_TIMING_V(2)); 2550 DUMPREG(DISPC_TIMING_V(2));
2473 DUMPREG(DISPC_POL_FREQ(2)); 2551 DUMPREG(DISPC_POL_FREQ(2));
2474 DUMPREG(DISPC_DIVISOR(2)); 2552 DUMPREG(DISPC_DIVISORo(2));
2475 DUMPREG(DISPC_SIZE_LCD(2)); 2553 DUMPREG(DISPC_SIZE_LCD(2));
2476 } 2554 }
2477 2555
@@ -2597,7 +2675,7 @@ void dispc_dump_regs(struct seq_file *s)
2597 DUMPREG(DISPC_VID_PRELOAD(0)); 2675 DUMPREG(DISPC_VID_PRELOAD(0));
2598 DUMPREG(DISPC_VID_PRELOAD(1)); 2676 DUMPREG(DISPC_VID_PRELOAD(1));
2599 2677
2600 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 2678 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
2601#undef DUMPREG 2679#undef DUMPREG
2602} 2680}
2603 2681
@@ -2713,8 +2791,8 @@ int dispc_get_clock_div(enum omap_channel channel,
2713 2791
2714 fck = dispc_fclk_rate(); 2792 fck = dispc_fclk_rate();
2715 2793
2716 cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16); 2794 cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16);
2717 cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0); 2795 cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0);
2718 2796
2719 cinfo->lck = fck / cinfo->lck_div; 2797 cinfo->lck = fck / cinfo->lck_div;
2720 cinfo->pck = cinfo->lck / cinfo->pck_div; 2798 cinfo->pck = cinfo->lck / cinfo->pck_div;
@@ -2791,6 +2869,9 @@ int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
2791 break; 2869 break;
2792 } 2870 }
2793 2871
2872 if (ret)
2873 goto err;
2874
2794 _omap_dispc_set_irqs(); 2875 _omap_dispc_set_irqs();
2795 2876
2796 spin_unlock_irqrestore(&dispc.irq_lock, flags); 2877 spin_unlock_irqrestore(&dispc.irq_lock, flags);
@@ -2866,10 +2947,10 @@ static void print_irq_status(u32 status)
2866 * but we presume they are on because we got an IRQ. However, 2947 * but we presume they are on because we got an IRQ. However,
2867 * an irq handler may turn the clocks off, so we may not have 2948 * an irq handler may turn the clocks off, so we may not have
2868 * clock later in the function. */ 2949 * clock later in the function. */
2869void dispc_irq_handler(void) 2950static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
2870{ 2951{
2871 int i; 2952 int i;
2872 u32 irqstatus; 2953 u32 irqstatus, irqenable;
2873 u32 handledirqs = 0; 2954 u32 handledirqs = 0;
2874 u32 unhandled_errors; 2955 u32 unhandled_errors;
2875 struct omap_dispc_isr_data *isr_data; 2956 struct omap_dispc_isr_data *isr_data;
@@ -2878,6 +2959,13 @@ void dispc_irq_handler(void)
2878 spin_lock(&dispc.irq_lock); 2959 spin_lock(&dispc.irq_lock);
2879 2960
2880 irqstatus = dispc_read_reg(DISPC_IRQSTATUS); 2961 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
2962 irqenable = dispc_read_reg(DISPC_IRQENABLE);
2963
2964 /* IRQ is not for us */
2965 if (!(irqstatus & irqenable)) {
2966 spin_unlock(&dispc.irq_lock);
2967 return IRQ_NONE;
2968 }
2881 2969
2882#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 2970#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2883 spin_lock(&dispc.irq_stats_lock); 2971 spin_lock(&dispc.irq_stats_lock);
@@ -2929,6 +3017,8 @@ void dispc_irq_handler(void)
2929 } 3017 }
2930 3018
2931 spin_unlock(&dispc.irq_lock); 3019 spin_unlock(&dispc.irq_lock);
3020
3021 return IRQ_HANDLED;
2932} 3022}
2933 3023
2934static void dispc_error_worker(struct work_struct *work) 3024static void dispc_error_worker(struct work_struct *work)
@@ -3253,6 +3343,15 @@ static void _omap_dispc_initial_config(void)
3253 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */ 3343 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */
3254 dispc_write_reg(DISPC_SYSCONFIG, l); 3344 dispc_write_reg(DISPC_SYSCONFIG, l);
3255 3345
3346 /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
3347 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
3348 l = dispc_read_reg(DISPC_DIVISOR);
3349 /* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
3350 l = FLD_MOD(l, 1, 0, 0);
3351 l = FLD_MOD(l, 1, 23, 16);
3352 dispc_write_reg(DISPC_DIVISOR, l);
3353 }
3354
3256 /* FUNCGATED */ 3355 /* FUNCGATED */
3257 if (dss_has_feature(FEAT_FUNCGATED)) 3356 if (dss_has_feature(FEAT_FUNCGATED))
3258 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); 3357 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
@@ -3269,47 +3368,6 @@ static void _omap_dispc_initial_config(void)
3269 dispc_read_plane_fifo_sizes(); 3368 dispc_read_plane_fifo_sizes();
3270} 3369}
3271 3370
3272int dispc_init(void)
3273{
3274 u32 rev;
3275
3276 spin_lock_init(&dispc.irq_lock);
3277
3278#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3279 spin_lock_init(&dispc.irq_stats_lock);
3280 dispc.irq_stats.last_reset = jiffies;
3281#endif
3282
3283 INIT_WORK(&dispc.error_work, dispc_error_worker);
3284
3285 dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
3286 if (!dispc.base) {
3287 DSSERR("can't ioremap DISPC\n");
3288 return -ENOMEM;
3289 }
3290
3291 enable_clocks(1);
3292
3293 _omap_dispc_initial_config();
3294
3295 _omap_dispc_initialize_irq();
3296
3297 dispc_save_context();
3298
3299 rev = dispc_read_reg(DISPC_REVISION);
3300 printk(KERN_INFO "OMAP DISPC rev %d.%d\n",
3301 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3302
3303 enable_clocks(0);
3304
3305 return 0;
3306}
3307
3308void dispc_exit(void)
3309{
3310 iounmap(dispc.base);
3311}
3312
3313int dispc_enable_plane(enum omap_plane plane, bool enable) 3371int dispc_enable_plane(enum omap_plane plane, bool enable)
3314{ 3372{
3315 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); 3373 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -3359,3 +3417,94 @@ int dispc_setup_plane(enum omap_plane plane,
3359 3417
3360 return r; 3418 return r;
3361} 3419}
3420
3421/* DISPC HW IP initialisation */
3422static int omap_dispchw_probe(struct platform_device *pdev)
3423{
3424 u32 rev;
3425 int r = 0;
3426 struct resource *dispc_mem;
3427
3428 dispc.pdev = pdev;
3429
3430 spin_lock_init(&dispc.irq_lock);
3431
3432#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3433 spin_lock_init(&dispc.irq_stats_lock);
3434 dispc.irq_stats.last_reset = jiffies;
3435#endif
3436
3437 INIT_WORK(&dispc.error_work, dispc_error_worker);
3438
3439 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3440 if (!dispc_mem) {
3441 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3442 r = -EINVAL;
3443 goto fail0;
3444 }
3445 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
3446 if (!dispc.base) {
3447 DSSERR("can't ioremap DISPC\n");
3448 r = -ENOMEM;
3449 goto fail0;
3450 }
3451 dispc.irq = platform_get_irq(dispc.pdev, 0);
3452 if (dispc.irq < 0) {
3453 DSSERR("platform_get_irq failed\n");
3454 r = -ENODEV;
3455 goto fail1;
3456 }
3457
3458 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
3459 "OMAP DISPC", dispc.pdev);
3460 if (r < 0) {
3461 DSSERR("request_irq failed\n");
3462 goto fail1;
3463 }
3464
3465 enable_clocks(1);
3466
3467 _omap_dispc_initial_config();
3468
3469 _omap_dispc_initialize_irq();
3470
3471 dispc_save_context();
3472
3473 rev = dispc_read_reg(DISPC_REVISION);
3474 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
3475 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3476
3477 enable_clocks(0);
3478
3479 return 0;
3480fail1:
3481 iounmap(dispc.base);
3482fail0:
3483 return r;
3484}
3485
3486static int omap_dispchw_remove(struct platform_device *pdev)
3487{
3488 free_irq(dispc.irq, dispc.pdev);
3489 iounmap(dispc.base);
3490 return 0;
3491}
3492
3493static struct platform_driver omap_dispchw_driver = {
3494 .probe = omap_dispchw_probe,
3495 .remove = omap_dispchw_remove,
3496 .driver = {
3497 .name = "omapdss_dispc",
3498 .owner = THIS_MODULE,
3499 },
3500};
3501
3502int dispc_init_platform_driver(void)
3503{
3504 return platform_driver_register(&omap_dispchw_driver);
3505}
3506
3507void dispc_uninit_platform_driver(void)
3508{
3509 return platform_driver_unregister(&omap_dispchw_driver);
3510}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 22dd7a474f79..a85a6f38b40c 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -25,14 +25,11 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/list.h>
29#include <linux/platform_device.h> 28#include <linux/platform_device.h>
30 29
31#include <plat/display.h> 30#include <plat/display.h>
32#include "dss.h" 31#include "dss.h"
33 32
34static LIST_HEAD(display_list);
35
36static ssize_t display_enabled_show(struct device *dev, 33static ssize_t display_enabled_show(struct device *dev,
37 struct device_attribute *attr, char *buf) 34 struct device_attribute *attr, char *buf)
38{ 35{
@@ -345,6 +342,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
345 return 16; 342 return 16;
346 case OMAP_DISPLAY_TYPE_VENC: 343 case OMAP_DISPLAY_TYPE_VENC:
347 case OMAP_DISPLAY_TYPE_SDI: 344 case OMAP_DISPLAY_TYPE_SDI:
345 case OMAP_DISPLAY_TYPE_HDMI:
348 return 24; 346 return 24;
349 default: 347 default:
350 BUG(); 348 BUG();
@@ -371,6 +369,7 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
371 case OMAP_DISPLAY_TYPE_DPI: 369 case OMAP_DISPLAY_TYPE_DPI:
372 bpp = dssdev->phy.dpi.data_lines; 370 bpp = dssdev->phy.dpi.data_lines;
373 break; 371 break;
372 case OMAP_DISPLAY_TYPE_HDMI:
374 case OMAP_DISPLAY_TYPE_VENC: 373 case OMAP_DISPLAY_TYPE_VENC:
375 case OMAP_DISPLAY_TYPE_SDI: 374 case OMAP_DISPLAY_TYPE_SDI:
376 bpp = 24; 375 bpp = 24;
@@ -396,29 +395,6 @@ void dss_init_device(struct platform_device *pdev,
396 switch (dssdev->type) { 395 switch (dssdev->type) {
397#ifdef CONFIG_OMAP2_DSS_DPI 396#ifdef CONFIG_OMAP2_DSS_DPI
398 case OMAP_DISPLAY_TYPE_DPI: 397 case OMAP_DISPLAY_TYPE_DPI:
399#endif
400#ifdef CONFIG_OMAP2_DSS_RFBI
401 case OMAP_DISPLAY_TYPE_DBI:
402#endif
403#ifdef CONFIG_OMAP2_DSS_SDI
404 case OMAP_DISPLAY_TYPE_SDI:
405#endif
406#ifdef CONFIG_OMAP2_DSS_DSI
407 case OMAP_DISPLAY_TYPE_DSI:
408#endif
409#ifdef CONFIG_OMAP2_DSS_VENC
410 case OMAP_DISPLAY_TYPE_VENC:
411#endif
412 break;
413 default:
414 DSSERR("Support for display '%s' not compiled in.\n",
415 dssdev->name);
416 return;
417 }
418
419 switch (dssdev->type) {
420#ifdef CONFIG_OMAP2_DSS_DPI
421 case OMAP_DISPLAY_TYPE_DPI:
422 r = dpi_init_display(dssdev); 398 r = dpi_init_display(dssdev);
423 break; 399 break;
424#endif 400#endif
@@ -442,8 +418,13 @@ void dss_init_device(struct platform_device *pdev,
442 r = dsi_init_display(dssdev); 418 r = dsi_init_display(dssdev);
443 break; 419 break;
444#endif 420#endif
421 case OMAP_DISPLAY_TYPE_HDMI:
422 r = hdmi_init_display(dssdev);
423 break;
445 default: 424 default:
446 BUG(); 425 DSSERR("Support for display '%s' not compiled in.\n",
426 dssdev->name);
427 return;
447 } 428 }
448 429
449 if (r) { 430 if (r) {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 75fb0a515430..2d3ca4ca4a05 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -57,13 +57,13 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
57 if (r) 57 if (r)
58 return r; 58 return r;
59 59
60 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 60 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
61 61
62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
63 if (r) 63 if (r)
64 return r; 64 return r;
65 65
66 *fck = dsi_cinfo.dsi1_pll_fclk; 66 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
67 *lck_div = dispc_cinfo.lck_div; 67 *lck_div = dispc_cinfo.lck_div;
68 *pck_div = dispc_cinfo.pck_div; 68 *pck_div = dispc_cinfo.pck_div;
69 69
@@ -107,7 +107,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
107 bool is_tft; 107 bool is_tft;
108 int r = 0; 108 int r = 0;
109 109
110 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 110 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
111 111
112 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 112 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
113 dssdev->panel.acbi, dssdev->panel.acb); 113 dssdev->panel.acbi, dssdev->panel.acb);
@@ -137,7 +137,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
137 dispc_set_lcd_timings(dssdev->manager->id, t); 137 dispc_set_lcd_timings(dssdev->manager->id, t);
138 138
139err0: 139err0:
140 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 140 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
141 return r; 141 return r;
142} 142}
143 143
@@ -173,14 +173,14 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
173 goto err1; 173 goto err1;
174 } 174 }
175 175
176 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 176 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
177 177
178 r = dpi_basic_init(dssdev); 178 r = dpi_basic_init(dssdev);
179 if (r) 179 if (r)
180 goto err2; 180 goto err2;
181 181
182#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 182#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
183 dss_clk_enable(DSS_CLK_FCK2); 183 dss_clk_enable(DSS_CLK_SYSCK);
184 r = dsi_pll_init(dssdev, 0, 1); 184 r = dsi_pll_init(dssdev, 0, 1);
185 if (r) 185 if (r)
186 goto err3; 186 goto err3;
@@ -199,10 +199,10 @@ err4:
199#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 199#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
200 dsi_pll_uninit(); 200 dsi_pll_uninit();
201err3: 201err3:
202 dss_clk_disable(DSS_CLK_FCK2); 202 dss_clk_disable(DSS_CLK_SYSCK);
203#endif 203#endif
204err2: 204err2:
205 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 205 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
206 if (cpu_is_omap34xx()) 206 if (cpu_is_omap34xx())
207 regulator_disable(dpi.vdds_dsi_reg); 207 regulator_disable(dpi.vdds_dsi_reg);
208err1: 208err1:
@@ -217,12 +217,12 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
217 dssdev->manager->disable(dssdev->manager); 217 dssdev->manager->disable(dssdev->manager);
218 218
219#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 219#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
220 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 220 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
221 dsi_pll_uninit(); 221 dsi_pll_uninit();
222 dss_clk_disable(DSS_CLK_FCK2); 222 dss_clk_disable(DSS_CLK_SYSCK);
223#endif 223#endif
224 224
225 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 225 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
226 226
227 if (cpu_is_omap34xx()) 227 if (cpu_is_omap34xx())
228 regulator_disable(dpi.vdds_dsi_reg); 228 regulator_disable(dpi.vdds_dsi_reg);
@@ -271,7 +271,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
271 if (r) 271 if (r)
272 return r; 272 return r;
273 273
274 fck = dsi_cinfo.dsi1_pll_fclk; 274 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
275 lck_div = dispc_cinfo.lck_div; 275 lck_div = dispc_cinfo.lck_div;
276 pck_div = dispc_cinfo.pck_div; 276 pck_div = dispc_cinfo.pck_div;
277 } 277 }
@@ -303,22 +303,27 @@ int dpi_init_display(struct omap_dss_device *dssdev)
303{ 303{
304 DSSDBG("init_display\n"); 304 DSSDBG("init_display\n");
305 305
306 return 0; 306 if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
307} 307 struct regulator *vdds_dsi;
308 308
309int dpi_init(struct platform_device *pdev) 309 vdds_dsi = dss_get_vdds_dsi();
310{ 310
311 if (cpu_is_omap34xx()) { 311 if (IS_ERR(vdds_dsi)) {
312 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
313 if (IS_ERR(dpi.vdds_dsi_reg)) {
314 DSSERR("can't get VDDS_DSI regulator\n"); 312 DSSERR("can't get VDDS_DSI regulator\n");
315 return PTR_ERR(dpi.vdds_dsi_reg); 313 return PTR_ERR(vdds_dsi);
316 } 314 }
315
316 dpi.vdds_dsi_reg = vdds_dsi;
317 } 317 }
318 318
319 return 0; 319 return 0;
320} 320}
321 321
322int dpi_init(void)
323{
324 return 0;
325}
326
322void dpi_exit(void) 327void dpi_exit(void)
323{ 328{
324} 329}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index ddf3a0560822..0a7f1a47f8e3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -38,12 +38,11 @@
38#include <plat/clock.h> 38#include <plat/clock.h>
39 39
40#include "dss.h" 40#include "dss.h"
41#include "dss_features.h"
41 42
42/*#define VERBOSE_IRQ*/ 43/*#define VERBOSE_IRQ*/
43#define DSI_CATCH_MISSING_TE 44#define DSI_CATCH_MISSING_TE
44 45
45#define DSI_BASE 0x4804FC00
46
47struct dsi_reg { u16 idx; }; 46struct dsi_reg { u16 idx; };
48 47
49#define DSI_REG(idx) ((const struct dsi_reg) { idx }) 48#define DSI_REG(idx) ((const struct dsi_reg) { idx })
@@ -186,13 +185,15 @@ struct dsi_reg { u16 idx; };
186#define DSI_DT_RX_SHORT_READ_1 0x21 185#define DSI_DT_RX_SHORT_READ_1 0x21
187#define DSI_DT_RX_SHORT_READ_2 0x22 186#define DSI_DT_RX_SHORT_READ_2 0x22
188 187
189#define FINT_MAX 2100000 188typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
190#define FINT_MIN 750000 189
191#define REGN_MAX (1 << 7) 190#define DSI_MAX_NR_ISRS 2
192#define REGM_MAX ((1 << 11) - 1) 191
193#define REGM3_MAX (1 << 4) 192struct dsi_isr_data {
194#define REGM4_MAX (1 << 4) 193 omap_dsi_isr_t isr;
195#define LP_DIV_MAX ((1 << 13) - 1) 194 void *arg;
195 u32 mask;
196};
196 197
197enum fifo_size { 198enum fifo_size {
198 DSI_FIFO_SIZE_0 = 0, 199 DSI_FIFO_SIZE_0 = 0,
@@ -220,9 +221,17 @@ struct dsi_irq_stats {
220 unsigned cio_irqs[32]; 221 unsigned cio_irqs[32];
221}; 222};
222 223
224struct dsi_isr_tables {
225 struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
226 struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
227 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
228};
229
223static struct 230static struct
224{ 231{
232 struct platform_device *pdev;
225 void __iomem *base; 233 void __iomem *base;
234 int irq;
226 235
227 struct dsi_clock_info current_cinfo; 236 struct dsi_clock_info current_cinfo;
228 237
@@ -232,6 +241,7 @@ static struct
232 enum dsi_vc_mode mode; 241 enum dsi_vc_mode mode;
233 struct omap_dss_device *dssdev; 242 struct omap_dss_device *dssdev;
234 enum fifo_size fifo_size; 243 enum fifo_size fifo_size;
244 int vc_id;
235 } vc[4]; 245 } vc[4];
236 246
237 struct mutex lock; 247 struct mutex lock;
@@ -239,8 +249,10 @@ static struct
239 249
240 unsigned pll_locked; 250 unsigned pll_locked;
241 251
242 struct completion bta_completion; 252 spinlock_t irq_lock;
243 void (*bta_callback)(void); 253 struct dsi_isr_tables isr_tables;
254 /* space for a copy used by the interrupt handler */
255 struct dsi_isr_tables isr_tables_copy;
244 256
245 int update_channel; 257 int update_channel;
246 struct dsi_update_region update_region; 258 struct dsi_update_region update_region;
@@ -275,6 +287,11 @@ static struct
275 spinlock_t irq_stats_lock; 287 spinlock_t irq_stats_lock;
276 struct dsi_irq_stats irq_stats; 288 struct dsi_irq_stats irq_stats;
277#endif 289#endif
290 /* DSI PLL Parameter Ranges */
291 unsigned long regm_max, regn_max;
292 unsigned long regm_dispc_max, regm_dsi_max;
293 unsigned long fint_min, fint_max;
294 unsigned long lpdiv_max;
278} dsi; 295} dsi;
279 296
280#ifdef DEBUG 297#ifdef DEBUG
@@ -318,6 +335,11 @@ static bool dsi_bus_is_locked(void)
318 return dsi.bus_lock.count == 0; 335 return dsi.bus_lock.count == 0;
319} 336}
320 337
338static void dsi_completion_handler(void *data, u32 mask)
339{
340 complete((struct completion *)data);
341}
342
321static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 343static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
322 int value) 344 int value)
323{ 345{
@@ -387,6 +409,9 @@ static void dsi_perf_show(const char *name)
387 409
388static void print_irq_status(u32 status) 410static void print_irq_status(u32 status)
389{ 411{
412 if (status == 0)
413 return;
414
390#ifndef VERBOSE_IRQ 415#ifndef VERBOSE_IRQ
391 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0) 416 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
392 return; 417 return;
@@ -422,6 +447,9 @@ static void print_irq_status(u32 status)
422 447
423static void print_irq_status_vc(int channel, u32 status) 448static void print_irq_status_vc(int channel, u32 status)
424{ 449{
450 if (status == 0)
451 return;
452
425#ifndef VERBOSE_IRQ 453#ifndef VERBOSE_IRQ
426 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0) 454 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
427 return; 455 return;
@@ -448,6 +476,9 @@ static void print_irq_status_vc(int channel, u32 status)
448 476
449static void print_irq_status_cio(u32 status) 477static void print_irq_status_cio(u32 status)
450{ 478{
479 if (status == 0)
480 return;
481
451 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status); 482 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status);
452 483
453#define PIS(x) \ 484#define PIS(x) \
@@ -478,22 +509,33 @@ static void print_irq_status_cio(u32 status)
478 printk("\n"); 509 printk("\n");
479} 510}
480 511
481static int debug_irq; 512#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
482 513static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
483/* called from dss */
484void dsi_irq_handler(void)
485{ 514{
486 u32 irqstatus, vcstatus, ciostatus;
487 int i; 515 int i;
488 516
489 irqstatus = dsi_read_reg(DSI_IRQSTATUS);
490
491#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
492 spin_lock(&dsi.irq_stats_lock); 517 spin_lock(&dsi.irq_stats_lock);
518
493 dsi.irq_stats.irq_count++; 519 dsi.irq_stats.irq_count++;
494 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); 520 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs);
521
522 for (i = 0; i < 4; ++i)
523 dss_collect_irq_stats(vcstatus[i], dsi.irq_stats.vc_irqs[i]);
524
525 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
526
527 spin_unlock(&dsi.irq_stats_lock);
528}
529#else
530#define dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus)
495#endif 531#endif
496 532
533static int debug_irq;
534
535static void dsi_handle_irq_errors(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
536{
537 int i;
538
497 if (irqstatus & DSI_IRQ_ERROR_MASK) { 539 if (irqstatus & DSI_IRQ_ERROR_MASK) {
498 DSSERR("DSI error, irqstatus %x\n", irqstatus); 540 DSSERR("DSI error, irqstatus %x\n", irqstatus);
499 print_irq_status(irqstatus); 541 print_irq_status(irqstatus);
@@ -504,37 +546,88 @@ void dsi_irq_handler(void)
504 print_irq_status(irqstatus); 546 print_irq_status(irqstatus);
505 } 547 }
506 548
507#ifdef DSI_CATCH_MISSING_TE 549 for (i = 0; i < 4; ++i) {
508 if (irqstatus & DSI_IRQ_TE_TRIGGER) 550 if (vcstatus[i] & DSI_VC_IRQ_ERROR_MASK) {
509 del_timer(&dsi.te_timer); 551 DSSERR("DSI VC(%d) error, vc irqstatus %x\n",
510#endif 552 i, vcstatus[i]);
553 print_irq_status_vc(i, vcstatus[i]);
554 } else if (debug_irq) {
555 print_irq_status_vc(i, vcstatus[i]);
556 }
557 }
558
559 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) {
560 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus);
561 print_irq_status_cio(ciostatus);
562 } else if (debug_irq) {
563 print_irq_status_cio(ciostatus);
564 }
565}
566
567static void dsi_call_isrs(struct dsi_isr_data *isr_array,
568 unsigned isr_array_size, u32 irqstatus)
569{
570 struct dsi_isr_data *isr_data;
571 int i;
572
573 for (i = 0; i < isr_array_size; i++) {
574 isr_data = &isr_array[i];
575 if (isr_data->isr && isr_data->mask & irqstatus)
576 isr_data->isr(isr_data->arg, irqstatus);
577 }
578}
579
580static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables,
581 u32 irqstatus, u32 *vcstatus, u32 ciostatus)
582{
583 int i;
584
585 dsi_call_isrs(isr_tables->isr_table,
586 ARRAY_SIZE(isr_tables->isr_table),
587 irqstatus);
511 588
512 for (i = 0; i < 4; ++i) { 589 for (i = 0; i < 4; ++i) {
513 if ((irqstatus & (1<<i)) == 0) 590 if (vcstatus[i] == 0)
514 continue; 591 continue;
592 dsi_call_isrs(isr_tables->isr_table_vc[i],
593 ARRAY_SIZE(isr_tables->isr_table_vc[i]),
594 vcstatus[i]);
595 }
515 596
516 vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 597 if (ciostatus != 0)
598 dsi_call_isrs(isr_tables->isr_table_cio,
599 ARRAY_SIZE(isr_tables->isr_table_cio),
600 ciostatus);
601}
517 602
518#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 603static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
519 dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); 604{
520#endif 605 u32 irqstatus, vcstatus[4], ciostatus;
606 int i;
521 607
522 if (vcstatus & DSI_VC_IRQ_BTA) { 608 spin_lock(&dsi.irq_lock);
523 complete(&dsi.bta_completion);
524 609
525 if (dsi.bta_callback) 610 irqstatus = dsi_read_reg(DSI_IRQSTATUS);
526 dsi.bta_callback();
527 }
528 611
529 if (vcstatus & DSI_VC_IRQ_ERROR_MASK) { 612 /* IRQ is not for us */
530 DSSERR("DSI VC(%d) error, vc irqstatus %x\n", 613 if (!irqstatus) {
531 i, vcstatus); 614 spin_unlock(&dsi.irq_lock);
532 print_irq_status_vc(i, vcstatus); 615 return IRQ_NONE;
533 } else if (debug_irq) { 616 }
534 print_irq_status_vc(i, vcstatus); 617
618 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
619 /* flush posted write */
620 dsi_read_reg(DSI_IRQSTATUS);
621
622 for (i = 0; i < 4; ++i) {
623 if ((irqstatus & (1 << i)) == 0) {
624 vcstatus[i] = 0;
625 continue;
535 } 626 }
536 627
537 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus); 628 vcstatus[i] = dsi_read_reg(DSI_VC_IRQSTATUS(i));
629
630 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus[i]);
538 /* flush posted write */ 631 /* flush posted write */
539 dsi_read_reg(DSI_VC_IRQSTATUS(i)); 632 dsi_read_reg(DSI_VC_IRQSTATUS(i));
540 } 633 }
@@ -542,117 +635,307 @@ void dsi_irq_handler(void)
542 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { 635 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
543 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 636 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
544 637
545#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
546 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
547#endif
548
549 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); 638 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
550 /* flush posted write */ 639 /* flush posted write */
551 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 640 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
641 } else {
642 ciostatus = 0;
643 }
552 644
553 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) { 645#ifdef DSI_CATCH_MISSING_TE
554 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); 646 if (irqstatus & DSI_IRQ_TE_TRIGGER)
555 print_irq_status_cio(ciostatus); 647 del_timer(&dsi.te_timer);
556 } else if (debug_irq) { 648#endif
557 print_irq_status_cio(ciostatus); 649
558 } 650 /* make a copy and unlock, so that isrs can unregister
651 * themselves */
652 memcpy(&dsi.isr_tables_copy, &dsi.isr_tables, sizeof(dsi.isr_tables));
653
654 spin_unlock(&dsi.irq_lock);
655
656 dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus);
657
658 dsi_handle_irq_errors(irqstatus, vcstatus, ciostatus);
659
660 dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus);
661
662 return IRQ_HANDLED;
663}
664
665/* dsi.irq_lock has to be locked by the caller */
666static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array,
667 unsigned isr_array_size, u32 default_mask,
668 const struct dsi_reg enable_reg,
669 const struct dsi_reg status_reg)
670{
671 struct dsi_isr_data *isr_data;
672 u32 mask;
673 u32 old_mask;
674 int i;
675
676 mask = default_mask;
677
678 for (i = 0; i < isr_array_size; i++) {
679 isr_data = &isr_array[i];
680
681 if (isr_data->isr == NULL)
682 continue;
683
684 mask |= isr_data->mask;
559 } 685 }
560 686
561 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); 687 old_mask = dsi_read_reg(enable_reg);
562 /* flush posted write */ 688 /* clear the irqstatus for newly enabled irqs */
563 dsi_read_reg(DSI_IRQSTATUS); 689 dsi_write_reg(status_reg, (mask ^ old_mask) & mask);
690 dsi_write_reg(enable_reg, mask);
564 691
565#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 692 /* flush posted writes */
566 spin_unlock(&dsi.irq_stats_lock); 693 dsi_read_reg(enable_reg);
694 dsi_read_reg(status_reg);
695}
696
697/* dsi.irq_lock has to be locked by the caller */
698static void _omap_dsi_set_irqs(void)
699{
700 u32 mask = DSI_IRQ_ERROR_MASK;
701#ifdef DSI_CATCH_MISSING_TE
702 mask |= DSI_IRQ_TE_TRIGGER;
567#endif 703#endif
704 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table,
705 ARRAY_SIZE(dsi.isr_tables.isr_table), mask,
706 DSI_IRQENABLE, DSI_IRQSTATUS);
707}
708
709/* dsi.irq_lock has to be locked by the caller */
710static void _omap_dsi_set_irqs_vc(int vc)
711{
712 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_vc[vc],
713 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]),
714 DSI_VC_IRQ_ERROR_MASK,
715 DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc));
568} 716}
569 717
718/* dsi.irq_lock has to be locked by the caller */
719static void _omap_dsi_set_irqs_cio(void)
720{
721 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_cio,
722 ARRAY_SIZE(dsi.isr_tables.isr_table_cio),
723 DSI_CIO_IRQ_ERROR_MASK,
724 DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS);
725}
570 726
571static void _dsi_initialize_irq(void) 727static void _dsi_initialize_irq(void)
572{ 728{
573 u32 l; 729 unsigned long flags;
730 int vc;
731
732 spin_lock_irqsave(&dsi.irq_lock, flags);
733
734 memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables));
735
736 _omap_dsi_set_irqs();
737 for (vc = 0; vc < 4; ++vc)
738 _omap_dsi_set_irqs_vc(vc);
739 _omap_dsi_set_irqs_cio();
740
741 spin_unlock_irqrestore(&dsi.irq_lock, flags);
742}
743
744static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
745 struct dsi_isr_data *isr_array, unsigned isr_array_size)
746{
747 struct dsi_isr_data *isr_data;
748 int free_idx;
574 int i; 749 int i;
575 750
576 /* disable all interrupts */ 751 BUG_ON(isr == NULL);
577 dsi_write_reg(DSI_IRQENABLE, 0);
578 for (i = 0; i < 4; ++i)
579 dsi_write_reg(DSI_VC_IRQENABLE(i), 0);
580 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, 0);
581 752
582 /* clear interrupt status */ 753 /* check for duplicate entry and find a free slot */
583 l = dsi_read_reg(DSI_IRQSTATUS); 754 free_idx = -1;
584 dsi_write_reg(DSI_IRQSTATUS, l & ~DSI_IRQ_CHANNEL_MASK); 755 for (i = 0; i < isr_array_size; i++) {
756 isr_data = &isr_array[i];
585 757
586 for (i = 0; i < 4; ++i) { 758 if (isr_data->isr == isr && isr_data->arg == arg &&
587 l = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 759 isr_data->mask == mask) {
588 dsi_write_reg(DSI_VC_IRQSTATUS(i), l); 760 return -EINVAL;
761 }
762
763 if (isr_data->isr == NULL && free_idx == -1)
764 free_idx = i;
589 } 765 }
590 766
591 l = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 767 if (free_idx == -1)
592 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, l); 768 return -EBUSY;
593 769
594 /* enable error irqs */ 770 isr_data = &isr_array[free_idx];
595 l = DSI_IRQ_ERROR_MASK; 771 isr_data->isr = isr;
596#ifdef DSI_CATCH_MISSING_TE 772 isr_data->arg = arg;
597 l |= DSI_IRQ_TE_TRIGGER; 773 isr_data->mask = mask;
598#endif
599 dsi_write_reg(DSI_IRQENABLE, l);
600 774
601 l = DSI_VC_IRQ_ERROR_MASK; 775 return 0;
602 for (i = 0; i < 4; ++i) 776}
603 dsi_write_reg(DSI_VC_IRQENABLE(i), l); 777
778static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
779 struct dsi_isr_data *isr_array, unsigned isr_array_size)
780{
781 struct dsi_isr_data *isr_data;
782 int i;
783
784 for (i = 0; i < isr_array_size; i++) {
785 isr_data = &isr_array[i];
786 if (isr_data->isr != isr || isr_data->arg != arg ||
787 isr_data->mask != mask)
788 continue;
789
790 isr_data->isr = NULL;
791 isr_data->arg = NULL;
792 isr_data->mask = 0;
793
794 return 0;
795 }
604 796
605 l = DSI_CIO_IRQ_ERROR_MASK; 797 return -EINVAL;
606 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, l);
607} 798}
608 799
609static u32 dsi_get_errors(void) 800static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
610{ 801{
611 unsigned long flags; 802 unsigned long flags;
612 u32 e; 803 int r;
613 spin_lock_irqsave(&dsi.errors_lock, flags); 804
614 e = dsi.errors; 805 spin_lock_irqsave(&dsi.irq_lock, flags);
615 dsi.errors = 0; 806
616 spin_unlock_irqrestore(&dsi.errors_lock, flags); 807 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table,
617 return e; 808 ARRAY_SIZE(dsi.isr_tables.isr_table));
809
810 if (r == 0)
811 _omap_dsi_set_irqs();
812
813 spin_unlock_irqrestore(&dsi.irq_lock, flags);
814
815 return r;
618} 816}
619 817
620static void dsi_vc_enable_bta_irq(int channel) 818static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
621{ 819{
622 u32 l; 820 unsigned long flags;
821 int r;
822
823 spin_lock_irqsave(&dsi.irq_lock, flags);
824
825 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table,
826 ARRAY_SIZE(dsi.isr_tables.isr_table));
827
828 if (r == 0)
829 _omap_dsi_set_irqs();
623 830
624 dsi_write_reg(DSI_VC_IRQSTATUS(channel), DSI_VC_IRQ_BTA); 831 spin_unlock_irqrestore(&dsi.irq_lock, flags);
625 832
626 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 833 return r;
627 l |= DSI_VC_IRQ_BTA;
628 dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
629} 834}
630 835
631static void dsi_vc_disable_bta_irq(int channel) 836static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
837 u32 mask)
632{ 838{
633 u32 l; 839 unsigned long flags;
840 int r;
841
842 spin_lock_irqsave(&dsi.irq_lock, flags);
843
844 r = _dsi_register_isr(isr, arg, mask,
845 dsi.isr_tables.isr_table_vc[channel],
846 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
847
848 if (r == 0)
849 _omap_dsi_set_irqs_vc(channel);
850
851 spin_unlock_irqrestore(&dsi.irq_lock, flags);
852
853 return r;
854}
855
856static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
857 u32 mask)
858{
859 unsigned long flags;
860 int r;
861
862 spin_lock_irqsave(&dsi.irq_lock, flags);
863
864 r = _dsi_unregister_isr(isr, arg, mask,
865 dsi.isr_tables.isr_table_vc[channel],
866 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
867
868 if (r == 0)
869 _omap_dsi_set_irqs_vc(channel);
870
871 spin_unlock_irqrestore(&dsi.irq_lock, flags);
872
873 return r;
874}
875
876static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
877{
878 unsigned long flags;
879 int r;
880
881 spin_lock_irqsave(&dsi.irq_lock, flags);
882
883 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
884 ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
885
886 if (r == 0)
887 _omap_dsi_set_irqs_cio();
888
889 spin_unlock_irqrestore(&dsi.irq_lock, flags);
890
891 return r;
892}
893
894static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
895{
896 unsigned long flags;
897 int r;
898
899 spin_lock_irqsave(&dsi.irq_lock, flags);
900
901 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
902 ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
903
904 if (r == 0)
905 _omap_dsi_set_irqs_cio();
906
907 spin_unlock_irqrestore(&dsi.irq_lock, flags);
634 908
635 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 909 return r;
636 l &= ~DSI_VC_IRQ_BTA;
637 dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
638} 910}
639 911
640/* DSI func clock. this could also be DSI2_PLL_FCLK */ 912static u32 dsi_get_errors(void)
913{
914 unsigned long flags;
915 u32 e;
916 spin_lock_irqsave(&dsi.errors_lock, flags);
917 e = dsi.errors;
918 dsi.errors = 0;
919 spin_unlock_irqrestore(&dsi.errors_lock, flags);
920 return e;
921}
922
923/* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */
641static inline void enable_clocks(bool enable) 924static inline void enable_clocks(bool enable)
642{ 925{
643 if (enable) 926 if (enable)
644 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 927 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
645 else 928 else
646 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 929 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
647} 930}
648 931
649/* source clock for DSI PLL. this could also be PCLKFREE */ 932/* source clock for DSI PLL. this could also be PCLKFREE */
650static inline void dsi_enable_pll_clock(bool enable) 933static inline void dsi_enable_pll_clock(bool enable)
651{ 934{
652 if (enable) 935 if (enable)
653 dss_clk_enable(DSS_CLK_FCK2); 936 dss_clk_enable(DSS_CLK_SYSCK);
654 else 937 else
655 dss_clk_disable(DSS_CLK_FCK2); 938 dss_clk_disable(DSS_CLK_SYSCK);
656 939
657 if (enable && dsi.pll_locked) { 940 if (enable && dsi.pll_locked) {
658 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) 941 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1)
@@ -707,14 +990,14 @@ static inline int dsi_if_enable(bool enable)
707 return 0; 990 return 0;
708} 991}
709 992
710unsigned long dsi_get_dsi1_pll_rate(void) 993unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
711{ 994{
712 return dsi.current_cinfo.dsi1_pll_fclk; 995 return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk;
713} 996}
714 997
715static unsigned long dsi_get_dsi2_pll_rate(void) 998static unsigned long dsi_get_pll_hsdiv_dsi_rate(void)
716{ 999{
717 return dsi.current_cinfo.dsi2_pll_fclk; 1000 return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk;
718} 1001}
719 1002
720static unsigned long dsi_get_txbyteclkhs(void) 1003static unsigned long dsi_get_txbyteclkhs(void)
@@ -726,12 +1009,12 @@ static unsigned long dsi_fclk_rate(void)
726{ 1009{
727 unsigned long r; 1010 unsigned long r;
728 1011
729 if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) { 1012 if (dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK) {
730 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ 1013 /* DSI FCLK source is DSS_CLK_FCK */
731 r = dss_clk_get_rate(DSS_CLK_FCK1); 1014 r = dss_clk_get_rate(DSS_CLK_FCK);
732 } else { 1015 } else {
733 /* DSI FCLK source is DSI2_PLL_FCLK */ 1016 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */
734 r = dsi_get_dsi2_pll_rate(); 1017 r = dsi_get_pll_hsdiv_dsi_rate();
735 } 1018 }
736 1019
737 return r; 1020 return r;
@@ -745,7 +1028,7 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
745 1028
746 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div; 1029 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div;
747 1030
748 if (lp_clk_div == 0 || lp_clk_div > LP_DIV_MAX) 1031 if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max)
749 return -EINVAL; 1032 return -EINVAL;
750 1033
751 dsi_fclk = dsi_fclk_rate(); 1034 dsi_fclk = dsi_fclk_rate();
@@ -795,22 +1078,22 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
795static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, 1078static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
796 struct dsi_clock_info *cinfo) 1079 struct dsi_clock_info *cinfo)
797{ 1080{
798 if (cinfo->regn == 0 || cinfo->regn > REGN_MAX) 1081 if (cinfo->regn == 0 || cinfo->regn > dsi.regn_max)
799 return -EINVAL; 1082 return -EINVAL;
800 1083
801 if (cinfo->regm == 0 || cinfo->regm > REGM_MAX) 1084 if (cinfo->regm == 0 || cinfo->regm > dsi.regm_max)
802 return -EINVAL; 1085 return -EINVAL;
803 1086
804 if (cinfo->regm3 > REGM3_MAX) 1087 if (cinfo->regm_dispc > dsi.regm_dispc_max)
805 return -EINVAL; 1088 return -EINVAL;
806 1089
807 if (cinfo->regm4 > REGM4_MAX) 1090 if (cinfo->regm_dsi > dsi.regm_dsi_max)
808 return -EINVAL; 1091 return -EINVAL;
809 1092
810 if (cinfo->use_dss2_fck) { 1093 if (cinfo->use_sys_clk) {
811 cinfo->clkin = dss_clk_get_rate(DSS_CLK_FCK2); 1094 cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK);
812 /* XXX it is unclear if highfreq should be used 1095 /* XXX it is unclear if highfreq should be used
813 * with DSS2_FCK source also */ 1096 * with DSS_SYS_CLK source also */
814 cinfo->highfreq = 0; 1097 cinfo->highfreq = 0;
815 } else { 1098 } else {
816 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id); 1099 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id);
@@ -823,7 +1106,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
823 1106
824 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); 1107 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
825 1108
826 if (cinfo->fint > FINT_MAX || cinfo->fint < FINT_MIN) 1109 if (cinfo->fint > dsi.fint_max || cinfo->fint < dsi.fint_min)
827 return -EINVAL; 1110 return -EINVAL;
828 1111
829 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; 1112 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
@@ -831,15 +1114,17 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
831 if (cinfo->clkin4ddr > 1800 * 1000 * 1000) 1114 if (cinfo->clkin4ddr > 1800 * 1000 * 1000)
832 return -EINVAL; 1115 return -EINVAL;
833 1116
834 if (cinfo->regm3 > 0) 1117 if (cinfo->regm_dispc > 0)
835 cinfo->dsi1_pll_fclk = cinfo->clkin4ddr / cinfo->regm3; 1118 cinfo->dsi_pll_hsdiv_dispc_clk =
1119 cinfo->clkin4ddr / cinfo->regm_dispc;
836 else 1120 else
837 cinfo->dsi1_pll_fclk = 0; 1121 cinfo->dsi_pll_hsdiv_dispc_clk = 0;
838 1122
839 if (cinfo->regm4 > 0) 1123 if (cinfo->regm_dsi > 0)
840 cinfo->dsi2_pll_fclk = cinfo->clkin4ddr / cinfo->regm4; 1124 cinfo->dsi_pll_hsdiv_dsi_clk =
1125 cinfo->clkin4ddr / cinfo->regm_dsi;
841 else 1126 else
842 cinfo->dsi2_pll_fclk = 0; 1127 cinfo->dsi_pll_hsdiv_dsi_clk = 0;
843 1128
844 return 0; 1129 return 0;
845} 1130}
@@ -852,23 +1137,25 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
852 struct dispc_clock_info best_dispc; 1137 struct dispc_clock_info best_dispc;
853 int min_fck_per_pck; 1138 int min_fck_per_pck;
854 int match = 0; 1139 int match = 0;
855 unsigned long dss_clk_fck2; 1140 unsigned long dss_sys_clk, max_dss_fck;
1141
1142 dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK);
856 1143
857 dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2); 1144 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
858 1145
859 if (req_pck == dsi.cache_req_pck && 1146 if (req_pck == dsi.cache_req_pck &&
860 dsi.cache_cinfo.clkin == dss_clk_fck2) { 1147 dsi.cache_cinfo.clkin == dss_sys_clk) {
861 DSSDBG("DSI clock info found from cache\n"); 1148 DSSDBG("DSI clock info found from cache\n");
862 *dsi_cinfo = dsi.cache_cinfo; 1149 *dsi_cinfo = dsi.cache_cinfo;
863 dispc_find_clk_divs(is_tft, req_pck, dsi_cinfo->dsi1_pll_fclk, 1150 dispc_find_clk_divs(is_tft, req_pck,
864 dispc_cinfo); 1151 dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo);
865 return 0; 1152 return 0;
866 } 1153 }
867 1154
868 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 1155 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
869 1156
870 if (min_fck_per_pck && 1157 if (min_fck_per_pck &&
871 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 1158 req_pck * min_fck_per_pck > max_dss_fck) {
872 DSSERR("Requested pixel clock not possible with the current " 1159 DSSERR("Requested pixel clock not possible with the current "
873 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 1160 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
874 "the constraint off.\n"); 1161 "the constraint off.\n");
@@ -882,24 +1169,24 @@ retry:
882 memset(&best_dispc, 0, sizeof(best_dispc)); 1169 memset(&best_dispc, 0, sizeof(best_dispc));
883 1170
884 memset(&cur, 0, sizeof(cur)); 1171 memset(&cur, 0, sizeof(cur));
885 cur.clkin = dss_clk_fck2; 1172 cur.clkin = dss_sys_clk;
886 cur.use_dss2_fck = 1; 1173 cur.use_sys_clk = 1;
887 cur.highfreq = 0; 1174 cur.highfreq = 0;
888 1175
889 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ 1176 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
890 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ 1177 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
891 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ 1178 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
892 for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) { 1179 for (cur.regn = 1; cur.regn < dsi.regn_max; ++cur.regn) {
893 if (cur.highfreq == 0) 1180 if (cur.highfreq == 0)
894 cur.fint = cur.clkin / cur.regn; 1181 cur.fint = cur.clkin / cur.regn;
895 else 1182 else
896 cur.fint = cur.clkin / (2 * cur.regn); 1183 cur.fint = cur.clkin / (2 * cur.regn);
897 1184
898 if (cur.fint > FINT_MAX || cur.fint < FINT_MIN) 1185 if (cur.fint > dsi.fint_max || cur.fint < dsi.fint_min)
899 continue; 1186 continue;
900 1187
901 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ 1188 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
902 for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) { 1189 for (cur.regm = 1; cur.regm < dsi.regm_max; ++cur.regm) {
903 unsigned long a, b; 1190 unsigned long a, b;
904 1191
905 a = 2 * cur.regm * (cur.clkin/1000); 1192 a = 2 * cur.regm * (cur.clkin/1000);
@@ -909,30 +1196,32 @@ retry:
909 if (cur.clkin4ddr > 1800 * 1000 * 1000) 1196 if (cur.clkin4ddr > 1800 * 1000 * 1000)
910 break; 1197 break;
911 1198
912 /* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3 < 173MHz */ 1199 /* dsi_pll_hsdiv_dispc_clk(MHz) =
913 for (cur.regm3 = 1; cur.regm3 < REGM3_MAX; 1200 * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */
914 ++cur.regm3) { 1201 for (cur.regm_dispc = 1; cur.regm_dispc < dsi.regm_dispc_max;
1202 ++cur.regm_dispc) {
915 struct dispc_clock_info cur_dispc; 1203 struct dispc_clock_info cur_dispc;
916 cur.dsi1_pll_fclk = cur.clkin4ddr / cur.regm3; 1204 cur.dsi_pll_hsdiv_dispc_clk =
1205 cur.clkin4ddr / cur.regm_dispc;
917 1206
918 /* this will narrow down the search a bit, 1207 /* this will narrow down the search a bit,
919 * but still give pixclocks below what was 1208 * but still give pixclocks below what was
920 * requested */ 1209 * requested */
921 if (cur.dsi1_pll_fclk < req_pck) 1210 if (cur.dsi_pll_hsdiv_dispc_clk < req_pck)
922 break; 1211 break;
923 1212
924 if (cur.dsi1_pll_fclk > DISPC_MAX_FCK) 1213 if (cur.dsi_pll_hsdiv_dispc_clk > max_dss_fck)
925 continue; 1214 continue;
926 1215
927 if (min_fck_per_pck && 1216 if (min_fck_per_pck &&
928 cur.dsi1_pll_fclk < 1217 cur.dsi_pll_hsdiv_dispc_clk <
929 req_pck * min_fck_per_pck) 1218 req_pck * min_fck_per_pck)
930 continue; 1219 continue;
931 1220
932 match = 1; 1221 match = 1;
933 1222
934 dispc_find_clk_divs(is_tft, req_pck, 1223 dispc_find_clk_divs(is_tft, req_pck,
935 cur.dsi1_pll_fclk, 1224 cur.dsi_pll_hsdiv_dispc_clk,
936 &cur_dispc); 1225 &cur_dispc);
937 1226
938 if (abs(cur_dispc.pck - req_pck) < 1227 if (abs(cur_dispc.pck - req_pck) <
@@ -961,9 +1250,9 @@ found:
961 return -EINVAL; 1250 return -EINVAL;
962 } 1251 }
963 1252
964 /* DSI2_PLL_FCLK (regm4) is not used */ 1253 /* dsi_pll_hsdiv_dsi_clk (regm_dsi) is not used */
965 best.regm4 = 0; 1254 best.regm_dsi = 0;
966 best.dsi2_pll_fclk = 0; 1255 best.dsi_pll_hsdiv_dsi_clk = 0;
967 1256
968 if (dsi_cinfo) 1257 if (dsi_cinfo)
969 *dsi_cinfo = best; 1258 *dsi_cinfo = best;
@@ -982,23 +1271,27 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
982 int r = 0; 1271 int r = 0;
983 u32 l; 1272 u32 l;
984 int f; 1273 int f;
1274 u8 regn_start, regn_end, regm_start, regm_end;
1275 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
985 1276
986 DSSDBGF(); 1277 DSSDBGF();
987 1278
988 dsi.current_cinfo.fint = cinfo->fint; 1279 dsi.current_cinfo.fint = cinfo->fint;
989 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; 1280 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr;
990 dsi.current_cinfo.dsi1_pll_fclk = cinfo->dsi1_pll_fclk; 1281 dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk =
991 dsi.current_cinfo.dsi2_pll_fclk = cinfo->dsi2_pll_fclk; 1282 cinfo->dsi_pll_hsdiv_dispc_clk;
1283 dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk =
1284 cinfo->dsi_pll_hsdiv_dsi_clk;
992 1285
993 dsi.current_cinfo.regn = cinfo->regn; 1286 dsi.current_cinfo.regn = cinfo->regn;
994 dsi.current_cinfo.regm = cinfo->regm; 1287 dsi.current_cinfo.regm = cinfo->regm;
995 dsi.current_cinfo.regm3 = cinfo->regm3; 1288 dsi.current_cinfo.regm_dispc = cinfo->regm_dispc;
996 dsi.current_cinfo.regm4 = cinfo->regm4; 1289 dsi.current_cinfo.regm_dsi = cinfo->regm_dsi;
997 1290
998 DSSDBG("DSI Fint %ld\n", cinfo->fint); 1291 DSSDBG("DSI Fint %ld\n", cinfo->fint);
999 1292
1000 DSSDBG("clkin (%s) rate %ld, highfreq %d\n", 1293 DSSDBG("clkin (%s) rate %ld, highfreq %d\n",
1001 cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree", 1294 cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree",
1002 cinfo->clkin, 1295 cinfo->clkin,
1003 cinfo->highfreq); 1296 cinfo->highfreq);
1004 1297
@@ -1015,24 +1308,39 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1015 1308
1016 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); 1309 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
1017 1310
1018 DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n", 1311 DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc,
1019 cinfo->regm3, cinfo->dsi1_pll_fclk); 1312 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1020 DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n", 1313 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1021 cinfo->regm4, cinfo->dsi2_pll_fclk); 1314 cinfo->dsi_pll_hsdiv_dispc_clk);
1315 DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi,
1316 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1317 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1318 cinfo->dsi_pll_hsdiv_dsi_clk);
1319
1320 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, &regn_start, &regn_end);
1321 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, &regm_start, &regm_end);
1322 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, &regm_dispc_start,
1323 &regm_dispc_end);
1324 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start,
1325 &regm_dsi_end);
1022 1326
1023 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ 1327 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */
1024 1328
1025 l = dsi_read_reg(DSI_PLL_CONFIGURATION1); 1329 l = dsi_read_reg(DSI_PLL_CONFIGURATION1);
1026 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ 1330 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
1027 l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */ 1331 /* DSI_PLL_REGN */
1028 l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */ 1332 l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
1029 l = FLD_MOD(l, cinfo->regm3 > 0 ? cinfo->regm3 - 1 : 0, 1333 /* DSI_PLL_REGM */
1030 22, 19); /* DSI_CLOCK_DIV */ 1334 l = FLD_MOD(l, cinfo->regm, regm_start, regm_end);
1031 l = FLD_MOD(l, cinfo->regm4 > 0 ? cinfo->regm4 - 1 : 0, 1335 /* DSI_CLOCK_DIV */
1032 26, 23); /* DSIPROTO_CLOCK_DIV */ 1336 l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0,
1337 regm_dispc_start, regm_dispc_end);
1338 /* DSIPROTO_CLOCK_DIV */
1339 l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
1340 regm_dsi_start, regm_dsi_end);
1033 dsi_write_reg(DSI_PLL_CONFIGURATION1, l); 1341 dsi_write_reg(DSI_PLL_CONFIGURATION1, l);
1034 1342
1035 BUG_ON(cinfo->fint < 750000 || cinfo->fint > 2100000); 1343 BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max);
1036 if (cinfo->fint < 1000000) 1344 if (cinfo->fint < 1000000)
1037 f = 0x3; 1345 f = 0x3;
1038 else if (cinfo->fint < 1250000) 1346 else if (cinfo->fint < 1250000)
@@ -1046,7 +1354,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1046 1354
1047 l = dsi_read_reg(DSI_PLL_CONFIGURATION2); 1355 l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
1048 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ 1356 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */
1049 l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1, 1357 l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1,
1050 11, 11); /* DSI_PLL_CLKSEL */ 1358 11, 11); /* DSI_PLL_CLKSEL */
1051 l = FLD_MOD(l, cinfo->highfreq, 1359 l = FLD_MOD(l, cinfo->highfreq,
1052 12, 12); /* DSI_PLL_HIGHFREQ */ 1360 12, 12); /* DSI_PLL_HIGHFREQ */
@@ -1101,6 +1409,26 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1101 1409
1102 DSSDBG("PLL init\n"); 1410 DSSDBG("PLL init\n");
1103 1411
1412#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
1413 /*
1414 * HACK: this is just a quick hack to get the USE_DSI_PLL
1415 * option working. USE_DSI_PLL is itself a big hack, and
1416 * should be removed.
1417 */
1418 if (dsi.vdds_dsi_reg == NULL) {
1419 struct regulator *vdds_dsi;
1420
1421 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
1422
1423 if (IS_ERR(vdds_dsi)) {
1424 DSSERR("can't get VDDS_DSI regulator\n");
1425 return PTR_ERR(vdds_dsi);
1426 }
1427
1428 dsi.vdds_dsi_reg = vdds_dsi;
1429 }
1430#endif
1431
1104 enable_clocks(1); 1432 enable_clocks(1);
1105 dsi_enable_pll_clock(1); 1433 dsi_enable_pll_clock(1);
1106 1434
@@ -1162,6 +1490,10 @@ void dsi_dump_clocks(struct seq_file *s)
1162{ 1490{
1163 int clksel; 1491 int clksel;
1164 struct dsi_clock_info *cinfo = &dsi.current_cinfo; 1492 struct dsi_clock_info *cinfo = &dsi.current_cinfo;
1493 enum dss_clk_source dispc_clk_src, dsi_clk_src;
1494
1495 dispc_clk_src = dss_get_dispc_clk_source();
1496 dsi_clk_src = dss_get_dsi_clk_source();
1165 1497
1166 enable_clocks(1); 1498 enable_clocks(1);
1167 1499
@@ -1171,30 +1503,34 @@ void dsi_dump_clocks(struct seq_file *s)
1171 1503
1172 seq_printf(s, "dsi pll source = %s\n", 1504 seq_printf(s, "dsi pll source = %s\n",
1173 clksel == 0 ? 1505 clksel == 0 ?
1174 "dss2_alwon_fclk" : "pclkfree"); 1506 "dss_sys_clk" : "pclkfree");
1175 1507
1176 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); 1508 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
1177 1509
1178 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n", 1510 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n",
1179 cinfo->clkin4ddr, cinfo->regm); 1511 cinfo->clkin4ddr, cinfo->regm);
1180 1512
1181 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", 1513 seq_printf(s, "%s (%s)\t%-16luregm_dispc %u\t(%s)\n",
1182 cinfo->dsi1_pll_fclk, 1514 dss_get_generic_clk_source_name(dispc_clk_src),
1183 cinfo->regm3, 1515 dss_feat_get_clk_source_name(dispc_clk_src),
1184 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1516 cinfo->dsi_pll_hsdiv_dispc_clk,
1517 cinfo->regm_dispc,
1518 dispc_clk_src == DSS_CLK_SRC_FCK ?
1185 "off" : "on"); 1519 "off" : "on");
1186 1520
1187 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", 1521 seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n",
1188 cinfo->dsi2_pll_fclk, 1522 dss_get_generic_clk_source_name(dsi_clk_src),
1189 cinfo->regm4, 1523 dss_feat_get_clk_source_name(dsi_clk_src),
1190 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1524 cinfo->dsi_pll_hsdiv_dsi_clk,
1525 cinfo->regm_dsi,
1526 dsi_clk_src == DSS_CLK_SRC_FCK ?
1191 "off" : "on"); 1527 "off" : "on");
1192 1528
1193 seq_printf(s, "- DSI -\n"); 1529 seq_printf(s, "- DSI -\n");
1194 1530
1195 seq_printf(s, "dsi fclk source = %s\n", 1531 seq_printf(s, "dsi fclk source = %s (%s)\n",
1196 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1532 dss_get_generic_clk_source_name(dsi_clk_src),
1197 "dss1_alwon_fclk" : "dsi2_pll_fclk"); 1533 dss_feat_get_clk_source_name(dsi_clk_src));
1198 1534
1199 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); 1535 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate());
1200 1536
@@ -1306,7 +1642,7 @@ void dsi_dump_regs(struct seq_file *s)
1306{ 1642{
1307#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) 1643#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
1308 1644
1309 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1645 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1310 1646
1311 DUMPREG(DSI_REVISION); 1647 DUMPREG(DSI_REVISION);
1312 DUMPREG(DSI_SYSCONFIG); 1648 DUMPREG(DSI_SYSCONFIG);
@@ -1378,7 +1714,7 @@ void dsi_dump_regs(struct seq_file *s)
1378 DUMPREG(DSI_PLL_CONFIGURATION1); 1714 DUMPREG(DSI_PLL_CONFIGURATION1);
1379 DUMPREG(DSI_PLL_CONFIGURATION2); 1715 DUMPREG(DSI_PLL_CONFIGURATION2);
1380 1716
1381 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1717 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1382#undef DUMPREG 1718#undef DUMPREG
1383} 1719}
1384 1720
@@ -1622,20 +1958,6 @@ static int _dsi_reset(void)
1622 return _dsi_wait_reset(); 1958 return _dsi_wait_reset();
1623} 1959}
1624 1960
1625static void dsi_reset_tx_fifo(int channel)
1626{
1627 u32 mask;
1628 u32 l;
1629
1630 /* set fifosize of the channel to 0, then return the old size */
1631 l = dsi_read_reg(DSI_TX_FIFO_VC_SIZE);
1632
1633 mask = FLD_MASK((8 * channel) + 7, (8 * channel) + 4);
1634 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l & ~mask);
1635
1636 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l);
1637}
1638
1639static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, 1961static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
1640 enum fifo_size size3, enum fifo_size size4) 1962 enum fifo_size size3, enum fifo_size size4)
1641{ 1963{
@@ -1753,8 +2075,6 @@ static void dsi_vc_initial_config(int channel)
1753 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ 2075 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
1754 2076
1755 dsi_write_reg(DSI_VC_CTRL(channel), r); 2077 dsi_write_reg(DSI_VC_CTRL(channel), r);
1756
1757 dsi.vc[channel].mode = DSI_VC_MODE_L4;
1758} 2078}
1759 2079
1760static int dsi_vc_config_l4(int channel) 2080static int dsi_vc_config_l4(int channel)
@@ -1922,33 +2242,44 @@ static int dsi_vc_send_bta(int channel)
1922 2242
1923int dsi_vc_send_bta_sync(int channel) 2243int dsi_vc_send_bta_sync(int channel)
1924{ 2244{
2245 DECLARE_COMPLETION_ONSTACK(completion);
1925 int r = 0; 2246 int r = 0;
1926 u32 err; 2247 u32 err;
1927 2248
1928 INIT_COMPLETION(dsi.bta_completion); 2249 r = dsi_register_isr_vc(channel, dsi_completion_handler,
2250 &completion, DSI_VC_IRQ_BTA);
2251 if (r)
2252 goto err0;
1929 2253
1930 dsi_vc_enable_bta_irq(channel); 2254 r = dsi_register_isr(dsi_completion_handler, &completion,
2255 DSI_IRQ_ERROR_MASK);
2256 if (r)
2257 goto err1;
1931 2258
1932 r = dsi_vc_send_bta(channel); 2259 r = dsi_vc_send_bta(channel);
1933 if (r) 2260 if (r)
1934 goto err; 2261 goto err2;
1935 2262
1936 if (wait_for_completion_timeout(&dsi.bta_completion, 2263 if (wait_for_completion_timeout(&completion,
1937 msecs_to_jiffies(500)) == 0) { 2264 msecs_to_jiffies(500)) == 0) {
1938 DSSERR("Failed to receive BTA\n"); 2265 DSSERR("Failed to receive BTA\n");
1939 r = -EIO; 2266 r = -EIO;
1940 goto err; 2267 goto err2;
1941 } 2268 }
1942 2269
1943 err = dsi_get_errors(); 2270 err = dsi_get_errors();
1944 if (err) { 2271 if (err) {
1945 DSSERR("Error while sending BTA: %x\n", err); 2272 DSSERR("Error while sending BTA: %x\n", err);
1946 r = -EIO; 2273 r = -EIO;
1947 goto err; 2274 goto err2;
1948 } 2275 }
1949err: 2276err2:
1950 dsi_vc_disable_bta_irq(channel); 2277 dsi_unregister_isr(dsi_completion_handler, &completion,
1951 2278 DSI_IRQ_ERROR_MASK);
2279err1:
2280 dsi_unregister_isr_vc(channel, dsi_completion_handler,
2281 &completion, DSI_VC_IRQ_BTA);
2282err0:
1952 return r; 2283 return r;
1953} 2284}
1954EXPORT_SYMBOL(dsi_vc_send_bta_sync); 2285EXPORT_SYMBOL(dsi_vc_send_bta_sync);
@@ -1961,7 +2292,7 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type,
1961 2292
1962 WARN_ON(!dsi_bus_is_locked()); 2293 WARN_ON(!dsi_bus_is_locked());
1963 2294
1964 data_id = data_type | channel << 6; 2295 data_id = data_type | dsi.vc[channel].vc_id << 6;
1965 2296
1966 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | 2297 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
1967 FLD_VAL(ecc, 31, 24); 2298 FLD_VAL(ecc, 31, 24);
@@ -2064,7 +2395,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2064 return -EINVAL; 2395 return -EINVAL;
2065 } 2396 }
2066 2397
2067 data_id = data_type | channel << 6; 2398 data_id = data_type | dsi.vc[channel].vc_id << 6;
2068 2399
2069 r = (data_id << 0) | (data << 8) | (ecc << 24); 2400 r = (data_id << 0) | (data << 8) | (ecc << 24);
2070 2401
@@ -2762,19 +3093,20 @@ static void dsi_te_timeout(unsigned long arg)
2762} 3093}
2763#endif 3094#endif
2764 3095
3096static void dsi_framedone_bta_callback(void *data, u32 mask);
3097
2765static void dsi_handle_framedone(int error) 3098static void dsi_handle_framedone(int error)
2766{ 3099{
2767 const int channel = dsi.update_channel; 3100 const int channel = dsi.update_channel;
2768 3101
2769 cancel_delayed_work(&dsi.framedone_timeout_work); 3102 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback,
3103 NULL, DSI_VC_IRQ_BTA);
2770 3104
2771 dsi_vc_disable_bta_irq(channel); 3105 cancel_delayed_work(&dsi.framedone_timeout_work);
2772 3106
2773 /* SIDLEMODE back to smart-idle */ 3107 /* SIDLEMODE back to smart-idle */
2774 dispc_enable_sidle(); 3108 dispc_enable_sidle();
2775 3109
2776 dsi.bta_callback = NULL;
2777
2778 if (dsi.te_enabled) { 3110 if (dsi.te_enabled) {
2779 /* enable LP_RX_TO again after the TE */ 3111 /* enable LP_RX_TO again after the TE */
2780 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 3112 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
@@ -2808,7 +3140,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2808 dsi_handle_framedone(-ETIMEDOUT); 3140 dsi_handle_framedone(-ETIMEDOUT);
2809} 3141}
2810 3142
2811static void dsi_framedone_bta_callback(void) 3143static void dsi_framedone_bta_callback(void *data, u32 mask)
2812{ 3144{
2813 dsi_handle_framedone(0); 3145 dsi_handle_framedone(0);
2814 3146
@@ -2848,15 +3180,19 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
2848 * asynchronously. 3180 * asynchronously.
2849 * */ 3181 * */
2850 3182
2851 dsi.bta_callback = dsi_framedone_bta_callback; 3183 r = dsi_register_isr_vc(channel, dsi_framedone_bta_callback,
2852 3184 NULL, DSI_VC_IRQ_BTA);
2853 barrier(); 3185 if (r) {
2854 3186 DSSERR("Failed to register BTA ISR\n");
2855 dsi_vc_enable_bta_irq(channel); 3187 dsi_handle_framedone(-EIO);
3188 return;
3189 }
2856 3190
2857 r = dsi_vc_send_bta(channel); 3191 r = dsi_vc_send_bta(channel);
2858 if (r) { 3192 if (r) {
2859 DSSERR("BTA after framedone failed\n"); 3193 DSSERR("BTA after framedone failed\n");
3194 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback,
3195 NULL, DSI_VC_IRQ_BTA);
2860 dsi_handle_framedone(-EIO); 3196 dsi_handle_framedone(-EIO);
2861 } 3197 }
2862} 3198}
@@ -2984,12 +3320,12 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
2984 struct dsi_clock_info cinfo; 3320 struct dsi_clock_info cinfo;
2985 int r; 3321 int r;
2986 3322
2987 /* we always use DSS2_FCK as input clock */ 3323 /* we always use DSS_CLK_SYSCK as input clock */
2988 cinfo.use_dss2_fck = true; 3324 cinfo.use_sys_clk = true;
2989 cinfo.regn = dssdev->phy.dsi.div.regn; 3325 cinfo.regn = dssdev->phy.dsi.div.regn;
2990 cinfo.regm = dssdev->phy.dsi.div.regm; 3326 cinfo.regm = dssdev->phy.dsi.div.regm;
2991 cinfo.regm3 = dssdev->phy.dsi.div.regm3; 3327 cinfo.regm_dispc = dssdev->phy.dsi.div.regm_dispc;
2992 cinfo.regm4 = dssdev->phy.dsi.div.regm4; 3328 cinfo.regm_dsi = dssdev->phy.dsi.div.regm_dsi;
2993 r = dsi_calc_clock_rates(dssdev, &cinfo); 3329 r = dsi_calc_clock_rates(dssdev, &cinfo);
2994 if (r) { 3330 if (r) {
2995 DSSERR("Failed to calc dsi clocks\n"); 3331 DSSERR("Failed to calc dsi clocks\n");
@@ -3011,7 +3347,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3011 int r; 3347 int r;
3012 unsigned long long fck; 3348 unsigned long long fck;
3013 3349
3014 fck = dsi_get_dsi1_pll_rate(); 3350 fck = dsi_get_pll_hsdiv_dispc_rate();
3015 3351
3016 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div; 3352 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div;
3017 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div; 3353 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div;
@@ -3045,8 +3381,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3045 if (r) 3381 if (r)
3046 goto err1; 3382 goto err1;
3047 3383
3048 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 3384 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
3049 dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK); 3385 dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI);
3050 3386
3051 DSSDBG("PLL OK\n"); 3387 DSSDBG("PLL OK\n");
3052 3388
@@ -3082,8 +3418,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3082err3: 3418err3:
3083 dsi_complexio_uninit(); 3419 dsi_complexio_uninit();
3084err2: 3420err2:
3085 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3421 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
3086 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3422 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK);
3087err1: 3423err1:
3088 dsi_pll_uninit(); 3424 dsi_pll_uninit();
3089err0: 3425err0:
@@ -3099,8 +3435,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3099 dsi_vc_enable(2, 0); 3435 dsi_vc_enable(2, 0);
3100 dsi_vc_enable(3, 0); 3436 dsi_vc_enable(3, 0);
3101 3437
3102 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3438 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
3103 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3439 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK);
3104 dsi_complexio_uninit(); 3440 dsi_complexio_uninit();
3105 dsi_pll_uninit(); 3441 dsi_pll_uninit();
3106} 3442}
@@ -3220,29 +3556,107 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3220 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 3556 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
3221 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 3557 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
3222 3558
3223 dsi.vc[0].dssdev = dssdev; 3559 if (dsi.vdds_dsi_reg == NULL) {
3224 dsi.vc[1].dssdev = dssdev; 3560 struct regulator *vdds_dsi;
3561
3562 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
3563
3564 if (IS_ERR(vdds_dsi)) {
3565 DSSERR("can't get VDDS_DSI regulator\n");
3566 return PTR_ERR(vdds_dsi);
3567 }
3568
3569 dsi.vdds_dsi_reg = vdds_dsi;
3570 }
3225 3571
3226 return 0; 3572 return 0;
3227} 3573}
3228 3574
3229void dsi_wait_dsi1_pll_active(void) 3575int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
3576{
3577 int i;
3578
3579 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
3580 if (!dsi.vc[i].dssdev) {
3581 dsi.vc[i].dssdev = dssdev;
3582 *channel = i;
3583 return 0;
3584 }
3585 }
3586
3587 DSSERR("cannot get VC for display %s", dssdev->name);
3588 return -ENOSPC;
3589}
3590EXPORT_SYMBOL(omap_dsi_request_vc);
3591
3592int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
3593{
3594 if (vc_id < 0 || vc_id > 3) {
3595 DSSERR("VC ID out of range\n");
3596 return -EINVAL;
3597 }
3598
3599 if (channel < 0 || channel > 3) {
3600 DSSERR("Virtual Channel out of range\n");
3601 return -EINVAL;
3602 }
3603
3604 if (dsi.vc[channel].dssdev != dssdev) {
3605 DSSERR("Virtual Channel not allocated to display %s\n",
3606 dssdev->name);
3607 return -EINVAL;
3608 }
3609
3610 dsi.vc[channel].vc_id = vc_id;
3611
3612 return 0;
3613}
3614EXPORT_SYMBOL(omap_dsi_set_vc_id);
3615
3616void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
3617{
3618 if ((channel >= 0 && channel <= 3) &&
3619 dsi.vc[channel].dssdev == dssdev) {
3620 dsi.vc[channel].dssdev = NULL;
3621 dsi.vc[channel].vc_id = 0;
3622 }
3623}
3624EXPORT_SYMBOL(omap_dsi_release_vc);
3625
3626void dsi_wait_pll_hsdiv_dispc_active(void)
3230{ 3627{
3231 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) 3628 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1)
3232 DSSERR("DSI1 PLL clock not active\n"); 3629 DSSERR("%s (%s) not active\n",
3630 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
3631 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC));
3233} 3632}
3234 3633
3235void dsi_wait_dsi2_pll_active(void) 3634void dsi_wait_pll_hsdiv_dsi_active(void)
3236{ 3635{
3237 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) 3636 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1)
3238 DSSERR("DSI2 PLL clock not active\n"); 3637 DSSERR("%s (%s) not active\n",
3638 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
3639 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
3640}
3641
3642static void dsi_calc_clock_param_ranges(void)
3643{
3644 dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
3645 dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
3646 dsi.regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
3647 dsi.regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
3648 dsi.fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
3649 dsi.fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
3650 dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
3239} 3651}
3240 3652
3241int dsi_init(struct platform_device *pdev) 3653static int dsi_init(struct platform_device *pdev)
3242{ 3654{
3243 u32 rev; 3655 u32 rev;
3244 int r; 3656 int r, i;
3657 struct resource *dsi_mem;
3245 3658
3659 spin_lock_init(&dsi.irq_lock);
3246 spin_lock_init(&dsi.errors_lock); 3660 spin_lock_init(&dsi.errors_lock);
3247 dsi.errors = 0; 3661 dsi.errors = 0;
3248 3662
@@ -3251,8 +3665,6 @@ int dsi_init(struct platform_device *pdev)
3251 dsi.irq_stats.last_reset = jiffies; 3665 dsi.irq_stats.last_reset = jiffies;
3252#endif 3666#endif
3253 3667
3254 init_completion(&dsi.bta_completion);
3255
3256 mutex_init(&dsi.lock); 3668 mutex_init(&dsi.lock);
3257 sema_init(&dsi.bus_lock, 1); 3669 sema_init(&dsi.bus_lock, 1);
3258 3670
@@ -3268,24 +3680,45 @@ int dsi_init(struct platform_device *pdev)
3268 dsi.te_timer.function = dsi_te_timeout; 3680 dsi.te_timer.function = dsi_te_timeout;
3269 dsi.te_timer.data = 0; 3681 dsi.te_timer.data = 0;
3270#endif 3682#endif
3271 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); 3683 dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0);
3684 if (!dsi_mem) {
3685 DSSERR("can't get IORESOURCE_MEM DSI\n");
3686 r = -EINVAL;
3687 goto err1;
3688 }
3689 dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem));
3272 if (!dsi.base) { 3690 if (!dsi.base) {
3273 DSSERR("can't ioremap DSI\n"); 3691 DSSERR("can't ioremap DSI\n");
3274 r = -ENOMEM; 3692 r = -ENOMEM;
3275 goto err1; 3693 goto err1;
3276 } 3694 }
3695 dsi.irq = platform_get_irq(dsi.pdev, 0);
3696 if (dsi.irq < 0) {
3697 DSSERR("platform_get_irq failed\n");
3698 r = -ENODEV;
3699 goto err2;
3700 }
3277 3701
3278 dsi.vdds_dsi_reg = dss_get_vdds_dsi(); 3702 r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED,
3279 if (IS_ERR(dsi.vdds_dsi_reg)) { 3703 "OMAP DSI1", dsi.pdev);
3280 DSSERR("can't get VDDS_DSI regulator\n"); 3704 if (r < 0) {
3281 r = PTR_ERR(dsi.vdds_dsi_reg); 3705 DSSERR("request_irq failed\n");
3282 goto err2; 3706 goto err2;
3283 } 3707 }
3284 3708
3709 /* DSI VCs initialization */
3710 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
3711 dsi.vc[i].mode = DSI_VC_MODE_L4;
3712 dsi.vc[i].dssdev = NULL;
3713 dsi.vc[i].vc_id = 0;
3714 }
3715
3716 dsi_calc_clock_param_ranges();
3717
3285 enable_clocks(1); 3718 enable_clocks(1);
3286 3719
3287 rev = dsi_read_reg(DSI_REVISION); 3720 rev = dsi_read_reg(DSI_REVISION);
3288 printk(KERN_INFO "OMAP DSI rev %d.%d\n", 3721 dev_dbg(&pdev->dev, "OMAP DSI rev %d.%d\n",
3289 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 3722 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3290 3723
3291 enable_clocks(0); 3724 enable_clocks(0);
@@ -3298,8 +3731,14 @@ err1:
3298 return r; 3731 return r;
3299} 3732}
3300 3733
3301void dsi_exit(void) 3734static void dsi_exit(void)
3302{ 3735{
3736 if (dsi.vdds_dsi_reg != NULL) {
3737 regulator_put(dsi.vdds_dsi_reg);
3738 dsi.vdds_dsi_reg = NULL;
3739 }
3740
3741 free_irq(dsi.irq, dsi.pdev);
3303 iounmap(dsi.base); 3742 iounmap(dsi.base);
3304 3743
3305 destroy_workqueue(dsi.workqueue); 3744 destroy_workqueue(dsi.workqueue);
@@ -3307,3 +3746,41 @@ void dsi_exit(void)
3307 DSSDBG("omap_dsi_exit\n"); 3746 DSSDBG("omap_dsi_exit\n");
3308} 3747}
3309 3748
3749/* DSI1 HW IP initialisation */
3750static int omap_dsi1hw_probe(struct platform_device *pdev)
3751{
3752 int r;
3753 dsi.pdev = pdev;
3754 r = dsi_init(pdev);
3755 if (r) {
3756 DSSERR("Failed to initialize DSI\n");
3757 goto err_dsi;
3758 }
3759err_dsi:
3760 return r;
3761}
3762
3763static int omap_dsi1hw_remove(struct platform_device *pdev)
3764{
3765 dsi_exit();
3766 return 0;
3767}
3768
3769static struct platform_driver omap_dsi1hw_driver = {
3770 .probe = omap_dsi1hw_probe,
3771 .remove = omap_dsi1hw_remove,
3772 .driver = {
3773 .name = "omapdss_dsi1",
3774 .owner = THIS_MODULE,
3775 },
3776};
3777
3778int dsi_init_platform_driver(void)
3779{
3780 return platform_driver_register(&omap_dsi1hw_driver);
3781}
3782
3783void dsi_uninit_platform_driver(void)
3784{
3785 return platform_driver_unregister(&omap_dsi1hw_driver);
3786}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 77c3621c9171..3f1fee63c678 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -26,14 +26,13 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/seq_file.h> 29#include <linux/seq_file.h>
31#include <linux/clk.h> 30#include <linux/clk.h>
32 31
33#include <plat/display.h> 32#include <plat/display.h>
33#include <plat/clock.h>
34#include "dss.h" 34#include "dss.h"
35 35#include "dss_features.h"
36#define DSS_BASE 0x48050000
37 36
38#define DSS_SZ_REGS SZ_512 37#define DSS_SZ_REGS SZ_512
39 38
@@ -59,9 +58,17 @@ struct dss_reg {
59 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) 58 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
60 59
61static struct { 60static struct {
61 struct platform_device *pdev;
62 void __iomem *base; 62 void __iomem *base;
63 int ctx_id;
63 64
64 struct clk *dpll4_m4_ck; 65 struct clk *dpll4_m4_ck;
66 struct clk *dss_ick;
67 struct clk *dss_fck;
68 struct clk *dss_sys_clk;
69 struct clk *dss_tv_fck;
70 struct clk *dss_video_fck;
71 unsigned num_clks_enabled;
65 72
66 unsigned long cache_req_pck; 73 unsigned long cache_req_pck;
67 unsigned long cache_prate; 74 unsigned long cache_prate;
@@ -70,10 +77,22 @@ static struct {
70 77
71 enum dss_clk_source dsi_clk_source; 78 enum dss_clk_source dsi_clk_source;
72 enum dss_clk_source dispc_clk_source; 79 enum dss_clk_source dispc_clk_source;
80 enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
73 81
74 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 82 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
75} dss; 83} dss;
76 84
85static const char * const dss_generic_clk_source_names[] = {
86 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
87 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
88 [DSS_CLK_SRC_FCK] = "DSS_FCK",
89};
90
91static void dss_clk_enable_all_no_ctx(void);
92static void dss_clk_disable_all_no_ctx(void);
93static void dss_clk_enable_no_ctx(enum dss_clock clks);
94static void dss_clk_disable_no_ctx(enum dss_clock clks);
95
77static int _omap_dss_wait_reset(void); 96static int _omap_dss_wait_reset(void);
78 97
79static inline void dss_write_reg(const struct dss_reg idx, u32 val) 98static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -99,10 +118,11 @@ void dss_save_context(void)
99 SR(SYSCONFIG); 118 SR(SYSCONFIG);
100 SR(CONTROL); 119 SR(CONTROL);
101 120
102#ifdef CONFIG_OMAP2_DSS_SDI 121 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
103 SR(SDI_CONTROL); 122 OMAP_DISPLAY_TYPE_SDI) {
104 SR(PLL_CONTROL); 123 SR(SDI_CONTROL);
105#endif 124 SR(PLL_CONTROL);
125 }
106} 126}
107 127
108void dss_restore_context(void) 128void dss_restore_context(void)
@@ -113,10 +133,11 @@ void dss_restore_context(void)
113 RR(SYSCONFIG); 133 RR(SYSCONFIG);
114 RR(CONTROL); 134 RR(CONTROL);
115 135
116#ifdef CONFIG_OMAP2_DSS_SDI 136 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
117 RR(SDI_CONTROL); 137 OMAP_DISPLAY_TYPE_SDI) {
118 RR(PLL_CONTROL); 138 RR(SDI_CONTROL);
119#endif 139 RR(PLL_CONTROL);
140 }
120} 141}
121 142
122#undef SR 143#undef SR
@@ -209,66 +230,96 @@ void dss_sdi_disable(void)
209 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ 230 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
210} 231}
211 232
233const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src)
234{
235 return dss_generic_clk_source_names[clk_src];
236}
237
212void dss_dump_clocks(struct seq_file *s) 238void dss_dump_clocks(struct seq_file *s)
213{ 239{
214 unsigned long dpll4_ck_rate; 240 unsigned long dpll4_ck_rate;
215 unsigned long dpll4_m4_ck_rate; 241 unsigned long dpll4_m4_ck_rate;
242 const char *fclk_name, *fclk_real_name;
243 unsigned long fclk_rate;
216 244
217 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 245 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
218
219 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
220 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
221 246
222 seq_printf(s, "- DSS -\n"); 247 seq_printf(s, "- DSS -\n");
223 248
224 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); 249 fclk_name = dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK);
250 fclk_real_name = dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK);
251 fclk_rate = dss_clk_get_rate(DSS_CLK_FCK);
225 252
226 if (cpu_is_omap3630()) 253 if (dss.dpll4_m4_ck) {
227 seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", 254 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
228 dpll4_ck_rate, 255 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
229 dpll4_ck_rate / dpll4_m4_ck_rate, 256
230 dss_clk_get_rate(DSS_CLK_FCK1)); 257 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
231 else
232 seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n",
233 dpll4_ck_rate,
234 dpll4_ck_rate / dpll4_m4_ck_rate,
235 dss_clk_get_rate(DSS_CLK_FCK1));
236 258
237 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 259 if (cpu_is_omap3630() || cpu_is_omap44xx())
260 seq_printf(s, "%s (%s) = %lu / %lu = %lu\n",
261 fclk_name, fclk_real_name,
262 dpll4_ck_rate,
263 dpll4_ck_rate / dpll4_m4_ck_rate,
264 fclk_rate);
265 else
266 seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
267 fclk_name, fclk_real_name,
268 dpll4_ck_rate,
269 dpll4_ck_rate / dpll4_m4_ck_rate,
270 fclk_rate);
271 } else {
272 seq_printf(s, "%s (%s) = %lu\n",
273 fclk_name, fclk_real_name,
274 fclk_rate);
275 }
276
277 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
238} 278}
239 279
240void dss_dump_regs(struct seq_file *s) 280void dss_dump_regs(struct seq_file *s)
241{ 281{
242#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) 282#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
243 283
244 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 284 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
245 285
246 DUMPREG(DSS_REVISION); 286 DUMPREG(DSS_REVISION);
247 DUMPREG(DSS_SYSCONFIG); 287 DUMPREG(DSS_SYSCONFIG);
248 DUMPREG(DSS_SYSSTATUS); 288 DUMPREG(DSS_SYSSTATUS);
249 DUMPREG(DSS_IRQSTATUS); 289 DUMPREG(DSS_IRQSTATUS);
250 DUMPREG(DSS_CONTROL); 290 DUMPREG(DSS_CONTROL);
251 DUMPREG(DSS_SDI_CONTROL);
252 DUMPREG(DSS_PLL_CONTROL);
253 DUMPREG(DSS_SDI_STATUS);
254 291
255 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 292 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
293 OMAP_DISPLAY_TYPE_SDI) {
294 DUMPREG(DSS_SDI_CONTROL);
295 DUMPREG(DSS_PLL_CONTROL);
296 DUMPREG(DSS_SDI_STATUS);
297 }
298
299 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
256#undef DUMPREG 300#undef DUMPREG
257} 301}
258 302
259void dss_select_dispc_clk_source(enum dss_clk_source clk_src) 303void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
260{ 304{
261 int b; 305 int b;
306 u8 start, end;
307
308 switch (clk_src) {
309 case DSS_CLK_SRC_FCK:
310 b = 0;
311 break;
312 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
313 b = 1;
314 dsi_wait_pll_hsdiv_dispc_active();
315 break;
316 default:
317 BUG();
318 }
262 319
263 BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && 320 dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
264 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
265
266 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
267
268 if (clk_src == DSS_SRC_DSI1_PLL_FCLK)
269 dsi_wait_dsi1_pll_active();
270 321
271 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ 322 REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
272 323
273 dss.dispc_clk_source = clk_src; 324 dss.dispc_clk_source = clk_src;
274} 325}
@@ -277,19 +328,51 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
277{ 328{
278 int b; 329 int b;
279 330
280 BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && 331 switch (clk_src) {
281 clk_src != DSS_SRC_DSS1_ALWON_FCLK); 332 case DSS_CLK_SRC_FCK:
282 333 b = 0;
283 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; 334 break;
284 335 case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
285 if (clk_src == DSS_SRC_DSI2_PLL_FCLK) 336 b = 1;
286 dsi_wait_dsi2_pll_active(); 337 dsi_wait_pll_hsdiv_dsi_active();
338 break;
339 default:
340 BUG();
341 }
287 342
288 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ 343 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
289 344
290 dss.dsi_clk_source = clk_src; 345 dss.dsi_clk_source = clk_src;
291} 346}
292 347
348void dss_select_lcd_clk_source(enum omap_channel channel,
349 enum dss_clk_source clk_src)
350{
351 int b, ix, pos;
352
353 if (!dss_has_feature(FEAT_LCD_CLK_SRC))
354 return;
355
356 switch (clk_src) {
357 case DSS_CLK_SRC_FCK:
358 b = 0;
359 break;
360 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
361 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
362 b = 1;
363 dsi_wait_pll_hsdiv_dispc_active();
364 break;
365 default:
366 BUG();
367 }
368
369 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12;
370 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
371
372 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
373 dss.lcd_clk_source[ix] = clk_src;
374}
375
293enum dss_clk_source dss_get_dispc_clk_source(void) 376enum dss_clk_source dss_get_dispc_clk_source(void)
294{ 377{
295 return dss.dispc_clk_source; 378 return dss.dispc_clk_source;
@@ -300,34 +383,52 @@ enum dss_clk_source dss_get_dsi_clk_source(void)
300 return dss.dsi_clk_source; 383 return dss.dsi_clk_source;
301} 384}
302 385
386enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
387{
388 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
389 return dss.lcd_clk_source[ix];
390}
391
303/* calculate clock rates using dividers in cinfo */ 392/* calculate clock rates using dividers in cinfo */
304int dss_calc_clock_rates(struct dss_clock_info *cinfo) 393int dss_calc_clock_rates(struct dss_clock_info *cinfo)
305{ 394{
306 unsigned long prate; 395 if (dss.dpll4_m4_ck) {
396 unsigned long prate;
397 u16 fck_div_max = 16;
307 398
308 if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) || 399 if (cpu_is_omap3630() || cpu_is_omap44xx())
309 cinfo->fck_div == 0) 400 fck_div_max = 32;
310 return -EINVAL; 401
402 if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
403 return -EINVAL;
311 404
312 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 405 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
313 406
314 cinfo->fck = prate / cinfo->fck_div; 407 cinfo->fck = prate / cinfo->fck_div;
408 } else {
409 if (cinfo->fck_div != 0)
410 return -EINVAL;
411 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
412 }
315 413
316 return 0; 414 return 0;
317} 415}
318 416
319int dss_set_clock_div(struct dss_clock_info *cinfo) 417int dss_set_clock_div(struct dss_clock_info *cinfo)
320{ 418{
321 unsigned long prate; 419 if (dss.dpll4_m4_ck) {
322 int r; 420 unsigned long prate;
421 int r;
323 422
324 if (cpu_is_omap34xx()) {
325 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 423 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
326 DSSDBG("dpll4_m4 = %ld\n", prate); 424 DSSDBG("dpll4_m4 = %ld\n", prate);
327 425
328 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div); 426 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
329 if (r) 427 if (r)
330 return r; 428 return r;
429 } else {
430 if (cinfo->fck_div != 0)
431 return -EINVAL;
331 } 432 }
332 433
333 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); 434 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
@@ -337,12 +438,14 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
337 438
338int dss_get_clock_div(struct dss_clock_info *cinfo) 439int dss_get_clock_div(struct dss_clock_info *cinfo)
339{ 440{
340 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1); 441 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
341 442
342 if (cpu_is_omap34xx()) { 443 if (dss.dpll4_m4_ck) {
343 unsigned long prate; 444 unsigned long prate;
445
344 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 446 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
345 if (cpu_is_omap3630()) 447
448 if (cpu_is_omap3630() || cpu_is_omap44xx())
346 cinfo->fck_div = prate / (cinfo->fck); 449 cinfo->fck_div = prate / (cinfo->fck);
347 else 450 else
348 cinfo->fck_div = prate / (cinfo->fck / 2); 451 cinfo->fck_div = prate / (cinfo->fck / 2);
@@ -355,7 +458,7 @@ int dss_get_clock_div(struct dss_clock_info *cinfo)
355 458
356unsigned long dss_get_dpll4_rate(void) 459unsigned long dss_get_dpll4_rate(void)
357{ 460{
358 if (cpu_is_omap34xx()) 461 if (dss.dpll4_m4_ck)
359 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 462 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
360 else 463 else
361 return 0; 464 return 0;
@@ -369,16 +472,18 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
369 struct dss_clock_info best_dss; 472 struct dss_clock_info best_dss;
370 struct dispc_clock_info best_dispc; 473 struct dispc_clock_info best_dispc;
371 474
372 unsigned long fck; 475 unsigned long fck, max_dss_fck;
373 476
374 u16 fck_div; 477 u16 fck_div, fck_div_max = 16;
375 478
376 int match = 0; 479 int match = 0;
377 int min_fck_per_pck; 480 int min_fck_per_pck;
378 481
379 prate = dss_get_dpll4_rate(); 482 prate = dss_get_dpll4_rate();
380 483
381 fck = dss_clk_get_rate(DSS_CLK_FCK1); 484 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
485
486 fck = dss_clk_get_rate(DSS_CLK_FCK);
382 if (req_pck == dss.cache_req_pck && 487 if (req_pck == dss.cache_req_pck &&
383 ((cpu_is_omap34xx() && prate == dss.cache_prate) || 488 ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
384 dss.cache_dss_cinfo.fck == fck)) { 489 dss.cache_dss_cinfo.fck == fck)) {
@@ -391,7 +496,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
391 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 496 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
392 497
393 if (min_fck_per_pck && 498 if (min_fck_per_pck &&
394 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 499 req_pck * min_fck_per_pck > max_dss_fck) {
395 DSSERR("Requested pixel clock not possible with the current " 500 DSSERR("Requested pixel clock not possible with the current "
396 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 501 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
397 "the constraint off.\n"); 502 "the constraint off.\n");
@@ -402,10 +507,10 @@ retry:
402 memset(&best_dss, 0, sizeof(best_dss)); 507 memset(&best_dss, 0, sizeof(best_dss));
403 memset(&best_dispc, 0, sizeof(best_dispc)); 508 memset(&best_dispc, 0, sizeof(best_dispc));
404 509
405 if (cpu_is_omap24xx()) { 510 if (dss.dpll4_m4_ck == NULL) {
406 struct dispc_clock_info cur_dispc; 511 struct dispc_clock_info cur_dispc;
407 /* XXX can we change the clock on omap2? */ 512 /* XXX can we change the clock on omap2? */
408 fck = dss_clk_get_rate(DSS_CLK_FCK1); 513 fck = dss_clk_get_rate(DSS_CLK_FCK);
409 fck_div = 1; 514 fck_div = 1;
410 515
411 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 516 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
@@ -417,17 +522,19 @@ retry:
417 best_dispc = cur_dispc; 522 best_dispc = cur_dispc;
418 523
419 goto found; 524 goto found;
420 } else if (cpu_is_omap34xx()) { 525 } else {
421 for (fck_div = (cpu_is_omap3630() ? 32 : 16); 526 if (cpu_is_omap3630() || cpu_is_omap44xx())
422 fck_div > 0; --fck_div) { 527 fck_div_max = 32;
528
529 for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
423 struct dispc_clock_info cur_dispc; 530 struct dispc_clock_info cur_dispc;
424 531
425 if (cpu_is_omap3630()) 532 if (fck_div_max == 32)
426 fck = prate / fck_div; 533 fck = prate / fck_div;
427 else 534 else
428 fck = prate / fck_div * 2; 535 fck = prate / fck_div * 2;
429 536
430 if (fck > DISPC_MAX_FCK) 537 if (fck > max_dss_fck)
431 continue; 538 continue;
432 539
433 if (min_fck_per_pck && 540 if (min_fck_per_pck &&
@@ -450,8 +557,6 @@ retry:
450 goto found; 557 goto found;
451 } 558 }
452 } 559 }
453 } else {
454 BUG();
455 } 560 }
456 561
457found: 562found:
@@ -482,31 +587,6 @@ found:
482 return 0; 587 return 0;
483} 588}
484 589
485
486
487static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
488{
489 dispc_irq_handler();
490
491 return IRQ_HANDLED;
492}
493
494static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
495{
496 u32 irqstatus;
497
498 irqstatus = dss_read_reg(DSS_IRQSTATUS);
499
500 if (irqstatus & (1<<0)) /* DISPC_IRQ */
501 dispc_irq_handler();
502#ifdef CONFIG_OMAP2_DSS_DSI
503 if (irqstatus & (1<<1)) /* DSI_IRQ */
504 dsi_irq_handler();
505#endif
506
507 return IRQ_HANDLED;
508}
509
510static int _omap_dss_wait_reset(void) 590static int _omap_dss_wait_reset(void)
511{ 591{
512 int t = 0; 592 int t = 0;
@@ -549,34 +629,45 @@ void dss_set_dac_pwrdn_bgz(bool enable)
549 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ 629 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
550} 630}
551 631
552int dss_init(bool skip_init) 632void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
633{
634 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
635}
636
637static int dss_init(void)
553{ 638{
554 int r; 639 int r;
555 u32 rev; 640 u32 rev;
641 struct resource *dss_mem;
642 struct clk *dpll4_m4_ck;
556 643
557 dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); 644 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
645 if (!dss_mem) {
646 DSSERR("can't get IORESOURCE_MEM DSS\n");
647 r = -EINVAL;
648 goto fail0;
649 }
650 dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
558 if (!dss.base) { 651 if (!dss.base) {
559 DSSERR("can't ioremap DSS\n"); 652 DSSERR("can't ioremap DSS\n");
560 r = -ENOMEM; 653 r = -ENOMEM;
561 goto fail0; 654 goto fail0;
562 } 655 }
563 656
564 if (!skip_init) { 657 /* disable LCD and DIGIT output. This seems to fix the synclost
565 /* disable LCD and DIGIT output. This seems to fix the synclost 658 * problem that we get, if the bootloader starts the DSS and
566 * problem that we get, if the bootloader starts the DSS and 659 * the kernel resets it */
567 * the kernel resets it */ 660 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
568 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
569 661
570 /* We need to wait here a bit, otherwise we sometimes start to 662 /* We need to wait here a bit, otherwise we sometimes start to
571 * get synclost errors, and after that only power cycle will 663 * get synclost errors, and after that only power cycle will
572 * restore DSS functionality. I have no idea why this happens. 664 * restore DSS functionality. I have no idea why this happens.
573 * And we have to wait _before_ resetting the DSS, but after 665 * And we have to wait _before_ resetting the DSS, but after
574 * enabling clocks. 666 * enabling clocks.
575 */ 667 */
576 msleep(50); 668 msleep(50);
577 669
578 _omap_dss_reset(); 670 _omap_dss_reset();
579 }
580 671
581 /* autoidle */ 672 /* autoidle */
582 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); 673 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
@@ -589,29 +680,30 @@ int dss_init(bool skip_init)
589 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ 680 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
590 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ 681 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
591#endif 682#endif
592
593 r = request_irq(INT_24XX_DSS_IRQ,
594 cpu_is_omap24xx()
595 ? dss_irq_handler_omap2
596 : dss_irq_handler_omap3,
597 0, "OMAP DSS", NULL);
598
599 if (r < 0) {
600 DSSERR("omap2 dss: request_irq failed\n");
601 goto fail1;
602 }
603
604 if (cpu_is_omap34xx()) { 683 if (cpu_is_omap34xx()) {
605 dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); 684 dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
606 if (IS_ERR(dss.dpll4_m4_ck)) { 685 if (IS_ERR(dpll4_m4_ck)) {
607 DSSERR("Failed to get dpll4_m4_ck\n"); 686 DSSERR("Failed to get dpll4_m4_ck\n");
608 r = PTR_ERR(dss.dpll4_m4_ck); 687 r = PTR_ERR(dpll4_m4_ck);
609 goto fail2; 688 goto fail1;
610 } 689 }
690 } else if (cpu_is_omap44xx()) {
691 dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck");
692 if (IS_ERR(dpll4_m4_ck)) {
693 DSSERR("Failed to get dpll4_m4_ck\n");
694 r = PTR_ERR(dpll4_m4_ck);
695 goto fail1;
696 }
697 } else { /* omap24xx */
698 dpll4_m4_ck = NULL;
611 } 699 }
612 700
613 dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 701 dss.dpll4_m4_ck = dpll4_m4_ck;
614 dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 702
703 dss.dsi_clk_source = DSS_CLK_SRC_FCK;
704 dss.dispc_clk_source = DSS_CLK_SRC_FCK;
705 dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
706 dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
615 707
616 dss_save_context(); 708 dss_save_context();
617 709
@@ -621,21 +713,416 @@ int dss_init(bool skip_init)
621 713
622 return 0; 714 return 0;
623 715
624fail2:
625 free_irq(INT_24XX_DSS_IRQ, NULL);
626fail1: 716fail1:
627 iounmap(dss.base); 717 iounmap(dss.base);
628fail0: 718fail0:
629 return r; 719 return r;
630} 720}
631 721
632void dss_exit(void) 722static void dss_exit(void)
633{ 723{
634 if (cpu_is_omap34xx()) 724 if (dss.dpll4_m4_ck)
635 clk_put(dss.dpll4_m4_ck); 725 clk_put(dss.dpll4_m4_ck);
636 726
637 free_irq(INT_24XX_DSS_IRQ, NULL);
638
639 iounmap(dss.base); 727 iounmap(dss.base);
640} 728}
641 729
730/* CONTEXT */
731static int dss_get_ctx_id(void)
732{
733 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
734 int r;
735
736 if (!pdata->board_data->get_last_off_on_transaction_id)
737 return 0;
738 r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
739 if (r < 0) {
740 dev_err(&dss.pdev->dev, "getting transaction ID failed, "
741 "will force context restore\n");
742 r = -1;
743 }
744 return r;
745}
746
747int dss_need_ctx_restore(void)
748{
749 int id = dss_get_ctx_id();
750
751 if (id < 0 || id != dss.ctx_id) {
752 DSSDBG("ctx id %d -> id %d\n",
753 dss.ctx_id, id);
754 dss.ctx_id = id;
755 return 1;
756 } else {
757 return 0;
758 }
759}
760
761static void save_all_ctx(void)
762{
763 DSSDBG("save context\n");
764
765 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
766
767 dss_save_context();
768 dispc_save_context();
769#ifdef CONFIG_OMAP2_DSS_DSI
770 dsi_save_context();
771#endif
772
773 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
774}
775
776static void restore_all_ctx(void)
777{
778 DSSDBG("restore context\n");
779
780 dss_clk_enable_all_no_ctx();
781
782 dss_restore_context();
783 dispc_restore_context();
784#ifdef CONFIG_OMAP2_DSS_DSI
785 dsi_restore_context();
786#endif
787
788 dss_clk_disable_all_no_ctx();
789}
790
791static int dss_get_clock(struct clk **clock, const char *clk_name)
792{
793 struct clk *clk;
794
795 clk = clk_get(&dss.pdev->dev, clk_name);
796
797 if (IS_ERR(clk)) {
798 DSSERR("can't get clock %s", clk_name);
799 return PTR_ERR(clk);
800 }
801
802 *clock = clk;
803
804 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
805
806 return 0;
807}
808
809static int dss_get_clocks(void)
810{
811 int r;
812 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
813
814 dss.dss_ick = NULL;
815 dss.dss_fck = NULL;
816 dss.dss_sys_clk = NULL;
817 dss.dss_tv_fck = NULL;
818 dss.dss_video_fck = NULL;
819
820 r = dss_get_clock(&dss.dss_ick, "ick");
821 if (r)
822 goto err;
823
824 r = dss_get_clock(&dss.dss_fck, "fck");
825 if (r)
826 goto err;
827
828 if (!pdata->opt_clock_available) {
829 r = -ENODEV;
830 goto err;
831 }
832
833 if (pdata->opt_clock_available("sys_clk")) {
834 r = dss_get_clock(&dss.dss_sys_clk, "sys_clk");
835 if (r)
836 goto err;
837 }
838
839 if (pdata->opt_clock_available("tv_clk")) {
840 r = dss_get_clock(&dss.dss_tv_fck, "tv_clk");
841 if (r)
842 goto err;
843 }
844
845 if (pdata->opt_clock_available("video_clk")) {
846 r = dss_get_clock(&dss.dss_video_fck, "video_clk");
847 if (r)
848 goto err;
849 }
850
851 return 0;
852
853err:
854 if (dss.dss_ick)
855 clk_put(dss.dss_ick);
856 if (dss.dss_fck)
857 clk_put(dss.dss_fck);
858 if (dss.dss_sys_clk)
859 clk_put(dss.dss_sys_clk);
860 if (dss.dss_tv_fck)
861 clk_put(dss.dss_tv_fck);
862 if (dss.dss_video_fck)
863 clk_put(dss.dss_video_fck);
864
865 return r;
866}
867
868static void dss_put_clocks(void)
869{
870 if (dss.dss_video_fck)
871 clk_put(dss.dss_video_fck);
872 if (dss.dss_tv_fck)
873 clk_put(dss.dss_tv_fck);
874 if (dss.dss_sys_clk)
875 clk_put(dss.dss_sys_clk);
876 clk_put(dss.dss_fck);
877 clk_put(dss.dss_ick);
878}
879
880unsigned long dss_clk_get_rate(enum dss_clock clk)
881{
882 switch (clk) {
883 case DSS_CLK_ICK:
884 return clk_get_rate(dss.dss_ick);
885 case DSS_CLK_FCK:
886 return clk_get_rate(dss.dss_fck);
887 case DSS_CLK_SYSCK:
888 return clk_get_rate(dss.dss_sys_clk);
889 case DSS_CLK_TVFCK:
890 return clk_get_rate(dss.dss_tv_fck);
891 case DSS_CLK_VIDFCK:
892 return clk_get_rate(dss.dss_video_fck);
893 }
894
895 BUG();
896 return 0;
897}
898
899static unsigned count_clk_bits(enum dss_clock clks)
900{
901 unsigned num_clks = 0;
902
903 if (clks & DSS_CLK_ICK)
904 ++num_clks;
905 if (clks & DSS_CLK_FCK)
906 ++num_clks;
907 if (clks & DSS_CLK_SYSCK)
908 ++num_clks;
909 if (clks & DSS_CLK_TVFCK)
910 ++num_clks;
911 if (clks & DSS_CLK_VIDFCK)
912 ++num_clks;
913
914 return num_clks;
915}
916
917static void dss_clk_enable_no_ctx(enum dss_clock clks)
918{
919 unsigned num_clks = count_clk_bits(clks);
920
921 if (clks & DSS_CLK_ICK)
922 clk_enable(dss.dss_ick);
923 if (clks & DSS_CLK_FCK)
924 clk_enable(dss.dss_fck);
925 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
926 clk_enable(dss.dss_sys_clk);
927 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
928 clk_enable(dss.dss_tv_fck);
929 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
930 clk_enable(dss.dss_video_fck);
931
932 dss.num_clks_enabled += num_clks;
933}
934
935void dss_clk_enable(enum dss_clock clks)
936{
937 bool check_ctx = dss.num_clks_enabled == 0;
938
939 dss_clk_enable_no_ctx(clks);
940
941 /*
942 * HACK: On omap4 the registers may not be accessible right after
943 * enabling the clocks. At some point this will be handled by
944 * pm_runtime, but for the time begin this should make things work.
945 */
946 if (cpu_is_omap44xx() && check_ctx)
947 udelay(10);
948
949 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
950 restore_all_ctx();
951}
952
953static void dss_clk_disable_no_ctx(enum dss_clock clks)
954{
955 unsigned num_clks = count_clk_bits(clks);
956
957 if (clks & DSS_CLK_ICK)
958 clk_disable(dss.dss_ick);
959 if (clks & DSS_CLK_FCK)
960 clk_disable(dss.dss_fck);
961 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
962 clk_disable(dss.dss_sys_clk);
963 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
964 clk_disable(dss.dss_tv_fck);
965 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
966 clk_disable(dss.dss_video_fck);
967
968 dss.num_clks_enabled -= num_clks;
969}
970
971void dss_clk_disable(enum dss_clock clks)
972{
973 if (cpu_is_omap34xx()) {
974 unsigned num_clks = count_clk_bits(clks);
975
976 BUG_ON(dss.num_clks_enabled < num_clks);
977
978 if (dss.num_clks_enabled == num_clks)
979 save_all_ctx();
980 }
981
982 dss_clk_disable_no_ctx(clks);
983}
984
985static void dss_clk_enable_all_no_ctx(void)
986{
987 enum dss_clock clks;
988
989 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
990 if (cpu_is_omap34xx())
991 clks |= DSS_CLK_VIDFCK;
992 dss_clk_enable_no_ctx(clks);
993}
994
995static void dss_clk_disable_all_no_ctx(void)
996{
997 enum dss_clock clks;
998
999 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
1000 if (cpu_is_omap34xx())
1001 clks |= DSS_CLK_VIDFCK;
1002 dss_clk_disable_no_ctx(clks);
1003}
1004
1005#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1006/* CLOCKS */
1007static void core_dump_clocks(struct seq_file *s)
1008{
1009 int i;
1010 struct clk *clocks[5] = {
1011 dss.dss_ick,
1012 dss.dss_fck,
1013 dss.dss_sys_clk,
1014 dss.dss_tv_fck,
1015 dss.dss_video_fck
1016 };
1017
1018 seq_printf(s, "- CORE -\n");
1019
1020 seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
1021
1022 for (i = 0; i < 5; i++) {
1023 if (!clocks[i])
1024 continue;
1025 seq_printf(s, "%-15s\t%lu\t%d\n",
1026 clocks[i]->name,
1027 clk_get_rate(clocks[i]),
1028 clocks[i]->usecount);
1029 }
1030}
1031#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
1032
1033/* DEBUGFS */
1034#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1035void dss_debug_dump_clocks(struct seq_file *s)
1036{
1037 core_dump_clocks(s);
1038 dss_dump_clocks(s);
1039 dispc_dump_clocks(s);
1040#ifdef CONFIG_OMAP2_DSS_DSI
1041 dsi_dump_clocks(s);
1042#endif
1043}
1044#endif
1045
1046
1047/* DSS HW IP initialisation */
1048static int omap_dsshw_probe(struct platform_device *pdev)
1049{
1050 int r;
1051
1052 dss.pdev = pdev;
1053
1054 r = dss_get_clocks();
1055 if (r)
1056 goto err_clocks;
1057
1058 dss_clk_enable_all_no_ctx();
1059
1060 dss.ctx_id = dss_get_ctx_id();
1061 DSSDBG("initial ctx id %u\n", dss.ctx_id);
1062
1063 r = dss_init();
1064 if (r) {
1065 DSSERR("Failed to initialize DSS\n");
1066 goto err_dss;
1067 }
1068
1069 r = dpi_init();
1070 if (r) {
1071 DSSERR("Failed to initialize DPI\n");
1072 goto err_dpi;
1073 }
1074
1075 r = sdi_init();
1076 if (r) {
1077 DSSERR("Failed to initialize SDI\n");
1078 goto err_sdi;
1079 }
1080
1081 dss_clk_disable_all_no_ctx();
1082 return 0;
1083err_sdi:
1084 dpi_exit();
1085err_dpi:
1086 dss_exit();
1087err_dss:
1088 dss_clk_disable_all_no_ctx();
1089 dss_put_clocks();
1090err_clocks:
1091 return r;
1092}
1093
1094static int omap_dsshw_remove(struct platform_device *pdev)
1095{
1096
1097 dss_exit();
1098
1099 /*
1100 * As part of hwmod changes, DSS is not the only controller of dss
1101 * clocks; hwmod framework itself will also enable clocks during hwmod
1102 * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
1103 * need to disable clocks if their usecounts > 1.
1104 */
1105 WARN_ON(dss.num_clks_enabled > 0);
1106
1107 dss_put_clocks();
1108 return 0;
1109}
1110
1111static struct platform_driver omap_dsshw_driver = {
1112 .probe = omap_dsshw_probe,
1113 .remove = omap_dsshw_remove,
1114 .driver = {
1115 .name = "omapdss_dss",
1116 .owner = THIS_MODULE,
1117 },
1118};
1119
1120int dss_init_platform_driver(void)
1121{
1122 return platform_driver_register(&omap_dsshw_driver);
1123}
1124
1125void dss_uninit_platform_driver(void)
1126{
1127 return platform_driver_unregister(&omap_dsshw_driver);
1128}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index b394951120ac..c2f582bb19c0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -97,8 +97,6 @@ extern unsigned int dss_debug;
97#define FLD_MOD(orig, val, start, end) \ 97#define FLD_MOD(orig, val, start, end) \
98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) 98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
99 99
100#define DISPC_MAX_FCK 173000000
101
102enum omap_burst_size { 100enum omap_burst_size {
103 OMAP_DSS_BURST_4x32 = 0, 101 OMAP_DSS_BURST_4x32 = 0,
104 OMAP_DSS_BURST_8x32 = 1, 102 OMAP_DSS_BURST_8x32 = 1,
@@ -112,17 +110,25 @@ enum omap_parallel_interface_mode {
112}; 110};
113 111
114enum dss_clock { 112enum dss_clock {
115 DSS_CLK_ICK = 1 << 0, 113 DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */
116 DSS_CLK_FCK1 = 1 << 1, 114 DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */
117 DSS_CLK_FCK2 = 1 << 2, 115 DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */
118 DSS_CLK_54M = 1 << 3, 116 DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */
119 DSS_CLK_96M = 1 << 4, 117 DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
120}; 118};
121 119
122enum dss_clk_source { 120enum dss_clk_source {
123 DSS_SRC_DSI1_PLL_FCLK, 121 DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
124 DSS_SRC_DSI2_PLL_FCLK, 122 * OMAP4: PLL1_CLK1 */
125 DSS_SRC_DSS1_ALWON_FCLK, 123 DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
124 * OMAP4: PLL1_CLK2 */
125 DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK
126 * OMAP4: DSS_FCLK */
127};
128
129enum dss_hdmi_venc_clk_source_select {
130 DSS_VENC_TV_CLK = 0,
131 DSS_HDMI_M_PCLK = 1,
126}; 132};
127 133
128struct dss_clock_info { 134struct dss_clock_info {
@@ -148,36 +154,42 @@ struct dsi_clock_info {
148 unsigned long fint; 154 unsigned long fint;
149 unsigned long clkin4ddr; 155 unsigned long clkin4ddr;
150 unsigned long clkin; 156 unsigned long clkin;
151 unsigned long dsi1_pll_fclk; 157 unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
152 unsigned long dsi2_pll_fclk; 158 * OMAP4: PLLx_CLK1 */
153 159 unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
160 * OMAP4: PLLx_CLK2 */
154 unsigned long lp_clk; 161 unsigned long lp_clk;
155 162
156 /* dividers */ 163 /* dividers */
157 u16 regn; 164 u16 regn;
158 u16 regm; 165 u16 regm;
159 u16 regm3; 166 u16 regm_dispc; /* OMAP3: REGM3
160 u16 regm4; 167 * OMAP4: REGM4 */
161 168 u16 regm_dsi; /* OMAP3: REGM4
169 * OMAP4: REGM5 */
162 u16 lp_clk_div; 170 u16 lp_clk_div;
163 171
164 u8 highfreq; 172 u8 highfreq;
165 bool use_dss2_fck; 173 bool use_sys_clk;
174};
175
176/* HDMI PLL structure */
177struct hdmi_pll_info {
178 u16 regn;
179 u16 regm;
180 u32 regmf;
181 u16 regm2;
182 u16 regsd;
183 u16 dcofreq;
166}; 184};
167 185
168struct seq_file; 186struct seq_file;
169struct platform_device; 187struct platform_device;
170 188
171/* core */ 189/* core */
172void dss_clk_enable(enum dss_clock clks);
173void dss_clk_disable(enum dss_clock clks);
174unsigned long dss_clk_get_rate(enum dss_clock clk);
175int dss_need_ctx_restore(void);
176void dss_dump_clocks(struct seq_file *s);
177struct bus_type *dss_get_bus(void); 190struct bus_type *dss_get_bus(void);
178struct regulator *dss_get_vdds_dsi(void); 191struct regulator *dss_get_vdds_dsi(void);
179struct regulator *dss_get_vdds_sdi(void); 192struct regulator *dss_get_vdds_sdi(void);
180struct regulator *dss_get_vdda_dac(void);
181 193
182/* display */ 194/* display */
183int dss_suspend_all_devices(void); 195int dss_suspend_all_devices(void);
@@ -214,13 +226,23 @@ void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
214void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); 226void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
215 227
216/* DSS */ 228/* DSS */
217int dss_init(bool skip_init); 229int dss_init_platform_driver(void);
218void dss_exit(void); 230void dss_uninit_platform_driver(void);
219 231
232void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
220void dss_save_context(void); 233void dss_save_context(void);
221void dss_restore_context(void); 234void dss_restore_context(void);
235void dss_clk_enable(enum dss_clock clks);
236void dss_clk_disable(enum dss_clock clks);
237unsigned long dss_clk_get_rate(enum dss_clock clk);
238int dss_need_ctx_restore(void);
239const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src);
240void dss_dump_clocks(struct seq_file *s);
222 241
223void dss_dump_regs(struct seq_file *s); 242void dss_dump_regs(struct seq_file *s);
243#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
244void dss_debug_dump_clocks(struct seq_file *s);
245#endif
224 246
225void dss_sdi_init(u8 datapairs); 247void dss_sdi_init(u8 datapairs);
226int dss_sdi_enable(void); 248int dss_sdi_enable(void);
@@ -228,8 +250,11 @@ void dss_sdi_disable(void);
228 250
229void dss_select_dispc_clk_source(enum dss_clk_source clk_src); 251void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
230void dss_select_dsi_clk_source(enum dss_clk_source clk_src); 252void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
253void dss_select_lcd_clk_source(enum omap_channel channel,
254 enum dss_clk_source clk_src);
231enum dss_clk_source dss_get_dispc_clk_source(void); 255enum dss_clk_source dss_get_dispc_clk_source(void);
232enum dss_clk_source dss_get_dsi_clk_source(void); 256enum dss_clk_source dss_get_dsi_clk_source(void);
257enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
233 258
234void dss_set_venc_output(enum omap_dss_venc_type type); 259void dss_set_venc_output(enum omap_dss_venc_type type);
235void dss_set_dac_pwrdn_bgz(bool enable); 260void dss_set_dac_pwrdn_bgz(bool enable);
@@ -244,11 +269,11 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
244 269
245/* SDI */ 270/* SDI */
246#ifdef CONFIG_OMAP2_DSS_SDI 271#ifdef CONFIG_OMAP2_DSS_SDI
247int sdi_init(bool skip_init); 272int sdi_init(void);
248void sdi_exit(void); 273void sdi_exit(void);
249int sdi_init_display(struct omap_dss_device *display); 274int sdi_init_display(struct omap_dss_device *display);
250#else 275#else
251static inline int sdi_init(bool skip_init) 276static inline int sdi_init(void)
252{ 277{
253 return 0; 278 return 0;
254} 279}
@@ -259,8 +284,8 @@ static inline void sdi_exit(void)
259 284
260/* DSI */ 285/* DSI */
261#ifdef CONFIG_OMAP2_DSS_DSI 286#ifdef CONFIG_OMAP2_DSS_DSI
262int dsi_init(struct platform_device *pdev); 287int dsi_init_platform_driver(void);
263void dsi_exit(void); 288void dsi_uninit_platform_driver(void);
264 289
265void dsi_dump_clocks(struct seq_file *s); 290void dsi_dump_clocks(struct seq_file *s);
266void dsi_dump_irqs(struct seq_file *s); 291void dsi_dump_irqs(struct seq_file *s);
@@ -271,7 +296,7 @@ void dsi_restore_context(void);
271 296
272int dsi_init_display(struct omap_dss_device *display); 297int dsi_init_display(struct omap_dss_device *display);
273void dsi_irq_handler(void); 298void dsi_irq_handler(void);
274unsigned long dsi_get_dsi1_pll_rate(void); 299unsigned long dsi_get_pll_hsdiv_dispc_rate(void);
275int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); 300int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo);
276int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, 301int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
277 struct dsi_clock_info *cinfo, 302 struct dsi_clock_info *cinfo,
@@ -282,31 +307,36 @@ void dsi_pll_uninit(void);
282void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 307void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
283 u32 fifo_size, enum omap_burst_size *burst_size, 308 u32 fifo_size, enum omap_burst_size *burst_size,
284 u32 *fifo_low, u32 *fifo_high); 309 u32 *fifo_low, u32 *fifo_high);
285void dsi_wait_dsi1_pll_active(void); 310void dsi_wait_pll_hsdiv_dispc_active(void);
286void dsi_wait_dsi2_pll_active(void); 311void dsi_wait_pll_hsdiv_dsi_active(void);
287#else 312#else
288static inline int dsi_init(struct platform_device *pdev) 313static inline int dsi_init_platform_driver(void)
289{ 314{
290 return 0; 315 return 0;
291} 316}
292static inline void dsi_exit(void) 317static inline void dsi_uninit_platform_driver(void)
293{ 318{
294} 319}
295static inline void dsi_wait_dsi1_pll_active(void) 320static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
296{ 321{
322 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
323 return 0;
297} 324}
298static inline void dsi_wait_dsi2_pll_active(void) 325static inline void dsi_wait_pll_hsdiv_dispc_active(void)
326{
327}
328static inline void dsi_wait_pll_hsdiv_dsi_active(void)
299{ 329{
300} 330}
301#endif 331#endif
302 332
303/* DPI */ 333/* DPI */
304#ifdef CONFIG_OMAP2_DSS_DPI 334#ifdef CONFIG_OMAP2_DSS_DPI
305int dpi_init(struct platform_device *pdev); 335int dpi_init(void);
306void dpi_exit(void); 336void dpi_exit(void);
307int dpi_init_display(struct omap_dss_device *dssdev); 337int dpi_init_display(struct omap_dss_device *dssdev);
308#else 338#else
309static inline int dpi_init(struct platform_device *pdev) 339static inline int dpi_init(void)
310{ 340{
311 return 0; 341 return 0;
312} 342}
@@ -316,8 +346,8 @@ static inline void dpi_exit(void)
316#endif 346#endif
317 347
318/* DISPC */ 348/* DISPC */
319int dispc_init(void); 349int dispc_init_platform_driver(void);
320void dispc_exit(void); 350void dispc_uninit_platform_driver(void);
321void dispc_dump_clocks(struct seq_file *s); 351void dispc_dump_clocks(struct seq_file *s);
322void dispc_dump_irqs(struct seq_file *s); 352void dispc_dump_irqs(struct seq_file *s);
323void dispc_dump_regs(struct seq_file *s); 353void dispc_dump_regs(struct seq_file *s);
@@ -350,6 +380,7 @@ void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
350void dispc_set_channel_out(enum omap_plane plane, 380void dispc_set_channel_out(enum omap_plane plane,
351 enum omap_channel channel_out); 381 enum omap_channel channel_out);
352 382
383void dispc_enable_gamma_table(bool enable);
353int dispc_setup_plane(enum omap_plane plane, 384int dispc_setup_plane(enum omap_plane plane,
354 u32 paddr, u16 screen_width, 385 u32 paddr, u16 screen_width,
355 u16 pos_x, u16 pos_y, 386 u16 pos_x, u16 pos_y,
@@ -409,24 +440,50 @@ int dispc_get_clock_div(enum omap_channel channel,
409 440
410/* VENC */ 441/* VENC */
411#ifdef CONFIG_OMAP2_DSS_VENC 442#ifdef CONFIG_OMAP2_DSS_VENC
412int venc_init(struct platform_device *pdev); 443int venc_init_platform_driver(void);
413void venc_exit(void); 444void venc_uninit_platform_driver(void);
414void venc_dump_regs(struct seq_file *s); 445void venc_dump_regs(struct seq_file *s);
415int venc_init_display(struct omap_dss_device *display); 446int venc_init_display(struct omap_dss_device *display);
416#else 447#else
417static inline int venc_init(struct platform_device *pdev) 448static inline int venc_init_platform_driver(void)
449{
450 return 0;
451}
452static inline void venc_uninit_platform_driver(void)
453{
454}
455#endif
456
457/* HDMI */
458#ifdef CONFIG_OMAP4_DSS_HDMI
459int hdmi_init_platform_driver(void);
460void hdmi_uninit_platform_driver(void);
461int hdmi_init_display(struct omap_dss_device *dssdev);
462#else
463static inline int hdmi_init_display(struct omap_dss_device *dssdev)
464{
465 return 0;
466}
467static inline int hdmi_init_platform_driver(void)
418{ 468{
419 return 0; 469 return 0;
420} 470}
421static inline void venc_exit(void) 471static inline void hdmi_uninit_platform_driver(void)
422{ 472{
423} 473}
424#endif 474#endif
475int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
476void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
477void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
478int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
479 struct omap_video_timings *timings);
480int hdmi_panel_init(void);
481void hdmi_panel_exit(void);
425 482
426/* RFBI */ 483/* RFBI */
427#ifdef CONFIG_OMAP2_DSS_RFBI 484#ifdef CONFIG_OMAP2_DSS_RFBI
428int rfbi_init(void); 485int rfbi_init_platform_driver(void);
429void rfbi_exit(void); 486void rfbi_uninit_platform_driver(void);
430void rfbi_dump_regs(struct seq_file *s); 487void rfbi_dump_regs(struct seq_file *s);
431 488
432int rfbi_configure(int rfbi_module, int bpp, int lines); 489int rfbi_configure(int rfbi_module, int bpp, int lines);
@@ -437,11 +494,11 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
437unsigned long rfbi_get_max_tx_rate(void); 494unsigned long rfbi_get_max_tx_rate(void);
438int rfbi_init_display(struct omap_dss_device *display); 495int rfbi_init_display(struct omap_dss_device *display);
439#else 496#else
440static inline int rfbi_init(void) 497static inline int rfbi_init_platform_driver(void)
441{ 498{
442 return 0; 499 return 0;
443} 500}
444static inline void rfbi_exit(void) 501static inline void rfbi_uninit_platform_driver(void)
445{ 502{
446} 503}
447#endif 504#endif
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index cf3ef696e141..aa1622241d0d 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -25,14 +25,18 @@
25#include <plat/display.h> 25#include <plat/display.h>
26#include <plat/cpu.h> 26#include <plat/cpu.h>
27 27
28#include "dss.h"
28#include "dss_features.h" 29#include "dss_features.h"
29 30
30/* Defines a generic omap register field */ 31/* Defines a generic omap register field */
31struct dss_reg_field { 32struct dss_reg_field {
32 enum dss_feat_reg_field id;
33 u8 start, end; 33 u8 start, end;
34}; 34};
35 35
36struct dss_param_range {
37 int min, max;
38};
39
36struct omap_dss_features { 40struct omap_dss_features {
37 const struct dss_reg_field *reg_fields; 41 const struct dss_reg_field *reg_fields;
38 const int num_reg_fields; 42 const int num_reg_fields;
@@ -43,29 +47,68 @@ struct omap_dss_features {
43 const int num_ovls; 47 const int num_ovls;
44 const enum omap_display_type *supported_displays; 48 const enum omap_display_type *supported_displays;
45 const enum omap_color_mode *supported_color_modes; 49 const enum omap_color_mode *supported_color_modes;
50 const char * const *clksrc_names;
51 const struct dss_param_range *dss_params;
46}; 52};
47 53
48/* This struct is assigned to one of the below during initialization */ 54/* This struct is assigned to one of the below during initialization */
49static struct omap_dss_features *omap_current_dss_features; 55static struct omap_dss_features *omap_current_dss_features;
50 56
51static const struct dss_reg_field omap2_dss_reg_fields[] = { 57static const struct dss_reg_field omap2_dss_reg_fields[] = {
52 { FEAT_REG_FIRHINC, 11, 0 }, 58 [FEAT_REG_FIRHINC] = { 11, 0 },
53 { FEAT_REG_FIRVINC, 27, 16 }, 59 [FEAT_REG_FIRVINC] = { 27, 16 },
54 { FEAT_REG_FIFOLOWTHRESHOLD, 8, 0 }, 60 [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
55 { FEAT_REG_FIFOHIGHTHRESHOLD, 24, 16 }, 61 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
56 { FEAT_REG_FIFOSIZE, 8, 0 }, 62 [FEAT_REG_FIFOSIZE] = { 8, 0 },
63 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
64 [FEAT_REG_VERTICALACCU] = { 25, 16 },
65 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
66 [FEAT_REG_DSIPLL_REGN] = { 0, 0 },
67 [FEAT_REG_DSIPLL_REGM] = { 0, 0 },
68 [FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
69 [FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
57}; 70};
58 71
59static const struct dss_reg_field omap3_dss_reg_fields[] = { 72static const struct dss_reg_field omap3_dss_reg_fields[] = {
60 { FEAT_REG_FIRHINC, 12, 0 }, 73 [FEAT_REG_FIRHINC] = { 12, 0 },
61 { FEAT_REG_FIRVINC, 28, 16 }, 74 [FEAT_REG_FIRVINC] = { 28, 16 },
62 { FEAT_REG_FIFOLOWTHRESHOLD, 11, 0 }, 75 [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
63 { FEAT_REG_FIFOHIGHTHRESHOLD, 27, 16 }, 76 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
64 { FEAT_REG_FIFOSIZE, 10, 0 }, 77 [FEAT_REG_FIFOSIZE] = { 10, 0 },
78 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
79 [FEAT_REG_VERTICALACCU] = { 25, 16 },
80 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
81 [FEAT_REG_DSIPLL_REGN] = { 7, 1 },
82 [FEAT_REG_DSIPLL_REGM] = { 18, 8 },
83 [FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
84 [FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
85};
86
87static const struct dss_reg_field omap4_dss_reg_fields[] = {
88 [FEAT_REG_FIRHINC] = { 12, 0 },
89 [FEAT_REG_FIRVINC] = { 28, 16 },
90 [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
91 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
92 [FEAT_REG_FIFOSIZE] = { 15, 0 },
93 [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
94 [FEAT_REG_VERTICALACCU] = { 26, 16 },
95 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
96 [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
97 [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
98 [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
99 [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
65}; 100};
66 101
67static const enum omap_display_type omap2_dss_supported_displays[] = { 102static const enum omap_display_type omap2_dss_supported_displays[] = {
68 /* OMAP_DSS_CHANNEL_LCD */ 103 /* OMAP_DSS_CHANNEL_LCD */
104 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
105
106 /* OMAP_DSS_CHANNEL_DIGIT */
107 OMAP_DISPLAY_TYPE_VENC,
108};
109
110static const enum omap_display_type omap3430_dss_supported_displays[] = {
111 /* OMAP_DSS_CHANNEL_LCD */
69 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 112 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
70 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, 113 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI,
71 114
@@ -73,10 +116,10 @@ static const enum omap_display_type omap2_dss_supported_displays[] = {
73 OMAP_DISPLAY_TYPE_VENC, 116 OMAP_DISPLAY_TYPE_VENC,
74}; 117};
75 118
76static const enum omap_display_type omap3_dss_supported_displays[] = { 119static const enum omap_display_type omap3630_dss_supported_displays[] = {
77 /* OMAP_DSS_CHANNEL_LCD */ 120 /* OMAP_DSS_CHANNEL_LCD */
78 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 121 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
79 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, 122 OMAP_DISPLAY_TYPE_DSI,
80 123
81 /* OMAP_DSS_CHANNEL_DIGIT */ 124 /* OMAP_DSS_CHANNEL_DIGIT */
82 OMAP_DISPLAY_TYPE_VENC, 125 OMAP_DISPLAY_TYPE_VENC,
@@ -87,7 +130,7 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
87 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, 130 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
88 131
89 /* OMAP_DSS_CHANNEL_DIGIT */ 132 /* OMAP_DSS_CHANNEL_DIGIT */
90 OMAP_DISPLAY_TYPE_VENC, 133 OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
91 134
92 /* OMAP_DSS_CHANNEL_LCD2 */ 135 /* OMAP_DSS_CHANNEL_LCD2 */
93 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 136 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
@@ -134,6 +177,54 @@ static const enum omap_color_mode omap3_dss_supported_color_modes[] = {
134 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, 177 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
135}; 178};
136 179
180static const char * const omap2_dss_clk_source_names[] = {
181 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
182 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
183 [DSS_CLK_SRC_FCK] = "DSS_FCLK1",
184};
185
186static const char * const omap3_dss_clk_source_names[] = {
187 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
188 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
189 [DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
190};
191
192static const char * const omap4_dss_clk_source_names[] = {
193 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
194 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
195 [DSS_CLK_SRC_FCK] = "DSS_FCLK",
196};
197
198static const struct dss_param_range omap2_dss_param_range[] = {
199 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
200 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
201 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
202 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
203 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
204 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
205 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
206};
207
208static const struct dss_param_range omap3_dss_param_range[] = {
209 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
210 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
211 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
212 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
213 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
214 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
215 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
216};
217
218static const struct dss_param_range omap4_dss_param_range[] = {
219 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
220 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
221 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
222 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
223 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
224 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
225 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
226};
227
137/* OMAP2 DSS Features */ 228/* OMAP2 DSS Features */
138static struct omap_dss_features omap2_dss_features = { 229static struct omap_dss_features omap2_dss_features = {
139 .reg_fields = omap2_dss_reg_fields, 230 .reg_fields = omap2_dss_reg_fields,
@@ -141,12 +232,15 @@ static struct omap_dss_features omap2_dss_features = {
141 232
142 .has_feature = 233 .has_feature =
143 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | 234 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL |
144 FEAT_PCKFREEENABLE | FEAT_FUNCGATED, 235 FEAT_PCKFREEENABLE | FEAT_FUNCGATED |
236 FEAT_ROWREPEATENABLE | FEAT_RESIZECONF,
145 237
146 .num_mgrs = 2, 238 .num_mgrs = 2,
147 .num_ovls = 3, 239 .num_ovls = 3,
148 .supported_displays = omap2_dss_supported_displays, 240 .supported_displays = omap2_dss_supported_displays,
149 .supported_color_modes = omap2_dss_supported_color_modes, 241 .supported_color_modes = omap2_dss_supported_color_modes,
242 .clksrc_names = omap2_dss_clk_source_names,
243 .dss_params = omap2_dss_param_range,
150}; 244};
151 245
152/* OMAP3 DSS Features */ 246/* OMAP3 DSS Features */
@@ -157,12 +251,15 @@ static struct omap_dss_features omap3430_dss_features = {
157 .has_feature = 251 .has_feature =
158 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 252 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
159 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 253 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
160 FEAT_FUNCGATED, 254 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
255 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF,
161 256
162 .num_mgrs = 2, 257 .num_mgrs = 2,
163 .num_ovls = 3, 258 .num_ovls = 3,
164 .supported_displays = omap3_dss_supported_displays, 259 .supported_displays = omap3430_dss_supported_displays,
165 .supported_color_modes = omap3_dss_supported_color_modes, 260 .supported_color_modes = omap3_dss_supported_color_modes,
261 .clksrc_names = omap3_dss_clk_source_names,
262 .dss_params = omap3_dss_param_range,
166}; 263};
167 264
168static struct omap_dss_features omap3630_dss_features = { 265static struct omap_dss_features omap3630_dss_features = {
@@ -172,27 +269,34 @@ static struct omap_dss_features omap3630_dss_features = {
172 .has_feature = 269 .has_feature =
173 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 270 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
174 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 271 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
175 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED, 272 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
273 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
274 FEAT_RESIZECONF,
176 275
177 .num_mgrs = 2, 276 .num_mgrs = 2,
178 .num_ovls = 3, 277 .num_ovls = 3,
179 .supported_displays = omap3_dss_supported_displays, 278 .supported_displays = omap3630_dss_supported_displays,
180 .supported_color_modes = omap3_dss_supported_color_modes, 279 .supported_color_modes = omap3_dss_supported_color_modes,
280 .clksrc_names = omap3_dss_clk_source_names,
281 .dss_params = omap3_dss_param_range,
181}; 282};
182 283
183/* OMAP4 DSS Features */ 284/* OMAP4 DSS Features */
184static struct omap_dss_features omap4_dss_features = { 285static struct omap_dss_features omap4_dss_features = {
185 .reg_fields = omap3_dss_reg_fields, 286 .reg_fields = omap4_dss_reg_fields,
186 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 287 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
187 288
188 .has_feature = 289 .has_feature =
189 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | 290 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
190 FEAT_MGR_LCD2, 291 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
292 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC,
191 293
192 .num_mgrs = 3, 294 .num_mgrs = 3,
193 .num_ovls = 3, 295 .num_ovls = 3,
194 .supported_displays = omap4_dss_supported_displays, 296 .supported_displays = omap4_dss_supported_displays,
195 .supported_color_modes = omap3_dss_supported_color_modes, 297 .supported_color_modes = omap3_dss_supported_color_modes,
298 .clksrc_names = omap4_dss_clk_source_names,
299 .dss_params = omap4_dss_param_range,
196}; 300};
197 301
198/* Functions returning values related to a DSS feature */ 302/* Functions returning values related to a DSS feature */
@@ -206,6 +310,16 @@ int dss_feat_get_num_ovls(void)
206 return omap_current_dss_features->num_ovls; 310 return omap_current_dss_features->num_ovls;
207} 311}
208 312
313unsigned long dss_feat_get_param_min(enum dss_range_param param)
314{
315 return omap_current_dss_features->dss_params[param].min;
316}
317
318unsigned long dss_feat_get_param_max(enum dss_range_param param)
319{
320 return omap_current_dss_features->dss_params[param].max;
321}
322
209enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel) 323enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel)
210{ 324{
211 return omap_current_dss_features->supported_displays[channel]; 325 return omap_current_dss_features->supported_displays[channel];
@@ -223,6 +337,11 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
223 color_mode; 337 color_mode;
224} 338}
225 339
340const char *dss_feat_get_clk_source_name(enum dss_clk_source id)
341{
342 return omap_current_dss_features->clksrc_names[id];
343}
344
226/* DSS has_feature check */ 345/* DSS has_feature check */
227bool dss_has_feature(enum dss_feat_id id) 346bool dss_has_feature(enum dss_feat_id id)
228{ 347{
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index b9c70be92588..12e9c4ef0dec 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -22,6 +22,7 @@
22 22
23#define MAX_DSS_MANAGERS 3 23#define MAX_DSS_MANAGERS 3
24#define MAX_DSS_OVERLAYS 3 24#define MAX_DSS_OVERLAYS 3
25#define MAX_DSS_LCD_MANAGERS 2
25 26
26/* DSS has feature id */ 27/* DSS has feature id */
27enum dss_feat_id { 28enum dss_feat_id {
@@ -33,6 +34,12 @@ enum dss_feat_id {
33 FEAT_PCKFREEENABLE = 1 << 5, 34 FEAT_PCKFREEENABLE = 1 << 5,
34 FEAT_FUNCGATED = 1 << 6, 35 FEAT_FUNCGATED = 1 << 6,
35 FEAT_MGR_LCD2 = 1 << 7, 36 FEAT_MGR_LCD2 = 1 << 7,
37 FEAT_LINEBUFFERSPLIT = 1 << 8,
38 FEAT_ROWREPEATENABLE = 1 << 9,
39 FEAT_RESIZECONF = 1 << 10,
40 /* Independent core clk divider */
41 FEAT_CORE_CLK_DIV = 1 << 11,
42 FEAT_LCD_CLK_SRC = 1 << 12,
36}; 43};
37 44
38/* DSS register field id */ 45/* DSS register field id */
@@ -42,15 +49,35 @@ enum dss_feat_reg_field {
42 FEAT_REG_FIFOHIGHTHRESHOLD, 49 FEAT_REG_FIFOHIGHTHRESHOLD,
43 FEAT_REG_FIFOLOWTHRESHOLD, 50 FEAT_REG_FIFOLOWTHRESHOLD,
44 FEAT_REG_FIFOSIZE, 51 FEAT_REG_FIFOSIZE,
52 FEAT_REG_HORIZONTALACCU,
53 FEAT_REG_VERTICALACCU,
54 FEAT_REG_DISPC_CLK_SWITCH,
55 FEAT_REG_DSIPLL_REGN,
56 FEAT_REG_DSIPLL_REGM,
57 FEAT_REG_DSIPLL_REGM_DISPC,
58 FEAT_REG_DSIPLL_REGM_DSI,
59};
60
61enum dss_range_param {
62 FEAT_PARAM_DSS_FCK,
63 FEAT_PARAM_DSIPLL_REGN,
64 FEAT_PARAM_DSIPLL_REGM,
65 FEAT_PARAM_DSIPLL_REGM_DISPC,
66 FEAT_PARAM_DSIPLL_REGM_DSI,
67 FEAT_PARAM_DSIPLL_FINT,
68 FEAT_PARAM_DSIPLL_LPDIV,
45}; 69};
46 70
47/* DSS Feature Functions */ 71/* DSS Feature Functions */
48int dss_feat_get_num_mgrs(void); 72int dss_feat_get_num_mgrs(void);
49int dss_feat_get_num_ovls(void); 73int dss_feat_get_num_ovls(void);
74unsigned long dss_feat_get_param_min(enum dss_range_param param);
75unsigned long dss_feat_get_param_max(enum dss_range_param param);
50enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); 76enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
51enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); 77enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
52bool dss_feat_color_mode_supported(enum omap_plane plane, 78bool dss_feat_color_mode_supported(enum omap_plane plane,
53 enum omap_color_mode color_mode); 79 enum omap_color_mode color_mode);
80const char *dss_feat_get_clk_source_name(enum dss_clk_source id);
54 81
55bool dss_has_feature(enum dss_feat_id id); 82bool dss_has_feature(enum dss_feat_id id);
56void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 83void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
new file mode 100644
index 000000000000..0d44f070ef36
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -0,0 +1,1332 @@
1/*
2 * hdmi.c
3 *
4 * HDMI interface DSS driver setting for TI's OMAP4 family of processor.
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
6 * Authors: Yong Zhi
7 * Mythri pk <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#define DSS_SUBSYS_NAME "HDMI"
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/interrupt.h>
29#include <linux/mutex.h>
30#include <linux/delay.h>
31#include <linux/string.h>
32#include <plat/display.h>
33
34#include "dss.h"
35#include "hdmi.h"
36
37static struct {
38 struct mutex lock;
39 struct omap_display_platform_data *pdata;
40 struct platform_device *pdev;
41 void __iomem *base_wp; /* HDMI wrapper */
42 int code;
43 int mode;
44 u8 edid[HDMI_EDID_MAX_LENGTH];
45 u8 edid_set;
46 bool custom_set;
47 struct hdmi_config cfg;
48} hdmi;
49
50/*
51 * Logic for the below structure :
52 * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
53 * There is a correspondence between CEA/VESA timing and code, please
54 * refer to section 6.3 in HDMI 1.3 specification for timing code.
55 *
56 * In the below structure, cea_vesa_timings corresponds to all OMAP4
57 * supported CEA and VESA timing values.code_cea corresponds to the CEA
58 * code, It is used to get the timing from cea_vesa_timing array.Similarly
59 * with code_vesa. Code_index is used for back mapping, that is once EDID
60 * is read from the TV, EDID is parsed to find the timing values and then
61 * map it to corresponding CEA or VESA index.
62 */
63
64static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
65 { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0},
66 { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1},
67 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1},
68 { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0},
69 { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0},
70 { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0},
71 { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0},
72 { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1},
73 { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1},
74 { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1},
75 { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0},
76 { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0},
77 { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1},
78 { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0},
79 { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1},
80 /* VESA From Here */
81 { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
82 { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
83 { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
84 { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
85 { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
86 { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1},
87 { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
88 { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
89 { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
90 { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
91 { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
92 { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
93 { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
94 { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
95 { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
96 { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
97 { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
98 { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
99 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
100};
101
102/*
103 * This is a static mapping array which maps the timing values
104 * with corresponding CEA / VESA code
105 */
106static const int code_index[OMAP_HDMI_TIMINGS_NB] = {
107 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
108 /* <--15 CEA 17--> vesa*/
109 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
110 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
111};
112
113/*
114 * This is reverse static mapping which maps the CEA / VESA code
115 * to the corresponding timing values
116 */
117static const int code_cea[39] = {
118 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1,
119 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1,
120 7, 6, 6, -1, -1, -1, -1, -1, -1, 11,
121 11, 12, 14, -1, -1, 13, 13, 4, 4
122};
123
124static const int code_vesa[85] = {
125 -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
126 -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
127 -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
128 -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
129 -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
130 -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
131 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
132 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
133 -1, 27, 28, -1, 33};
134
135static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
136
137static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
138{
139 __raw_writel(val, hdmi.base_wp + idx.idx);
140}
141
142static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
143{
144 return __raw_readl(hdmi.base_wp + idx.idx);
145}
146
147static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
148 int b2, int b1, u32 val)
149{
150 u32 t = 0;
151 while (val != REG_GET(idx, b2, b1)) {
152 udelay(1);
153 if (t++ > 10000)
154 return !val;
155 }
156 return val;
157}
158
159int hdmi_init_display(struct omap_dss_device *dssdev)
160{
161 DSSDBG("init_display\n");
162
163 return 0;
164}
165
166static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
167 struct hdmi_pll_info *fmt, u16 sd)
168{
169 u32 r;
170
171 /* PLL start always use manual mode */
172 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
173
174 r = hdmi_read_reg(PLLCTRL_CFG1);
175 r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
176 r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */
177
178 hdmi_write_reg(PLLCTRL_CFG1, r);
179
180 r = hdmi_read_reg(PLLCTRL_CFG2);
181
182 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
183 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
184 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
185
186 if (dcofreq) {
187 /* divider programming for frequency beyond 1000Mhz */
188 REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
189 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
190 } else {
191 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
192 }
193
194 hdmi_write_reg(PLLCTRL_CFG2, r);
195
196 r = hdmi_read_reg(PLLCTRL_CFG4);
197 r = FLD_MOD(r, fmt->regm2, 24, 18);
198 r = FLD_MOD(r, fmt->regmf, 17, 0);
199
200 hdmi_write_reg(PLLCTRL_CFG4, r);
201
202 /* go now */
203 REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
204
205 /* wait for bit change */
206 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
207 DSSERR("PLL GO bit not set\n");
208 return -ETIMEDOUT;
209 }
210
211 /* Wait till the lock bit is set in PLL status */
212 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
213 DSSWARN("cannot lock PLL\n");
214 DSSWARN("CFG1 0x%x\n",
215 hdmi_read_reg(PLLCTRL_CFG1));
216 DSSWARN("CFG2 0x%x\n",
217 hdmi_read_reg(PLLCTRL_CFG2));
218 DSSWARN("CFG4 0x%x\n",
219 hdmi_read_reg(PLLCTRL_CFG4));
220 return -ETIMEDOUT;
221 }
222
223 DSSDBG("PLL locked!\n");
224
225 return 0;
226}
227
228/* PHY_PWR_CMD */
229static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val)
230{
231 /* Command for power control of HDMI PHY */
232 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
233
234 /* Status of the power control of HDMI PHY */
235 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
236 DSSERR("Failed to set PHY power mode to %d\n", val);
237 return -ETIMEDOUT;
238 }
239
240 return 0;
241}
242
243/* PLL_PWR_CMD */
244static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val)
245{
246 /* Command for power control of HDMI PLL */
247 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
248
249 /* wait till PHY_PWR_STATUS is set */
250 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
251 DSSERR("Failed to set PHY_PWR_STATUS\n");
252 return -ETIMEDOUT;
253 }
254
255 return 0;
256}
257
258static int hdmi_pll_reset(void)
259{
260 /* SYSRESET controlled by power FSM */
261 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
262
263 /* READ 0x0 reset is in progress */
264 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
265 DSSERR("Failed to sysreset PLL\n");
266 return -ETIMEDOUT;
267 }
268
269 return 0;
270}
271
272static int hdmi_phy_init(void)
273{
274 u16 r = 0;
275
276 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON);
277 if (r)
278 return r;
279
280 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON);
281 if (r)
282 return r;
283
284 /*
285 * Read address 0 in order to get the SCP reset done completed
286 * Dummy access performed to make sure reset is done
287 */
288 hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
289
290 /*
291 * Write to phy address 0 to configure the clock
292 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
293 */
294 REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
295
296 /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
297 hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
298
299 /* Setup max LDO voltage */
300 REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
301
302 /* Write to phy address 3 to change the polarity control */
303 REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
304
305 return 0;
306}
307
308static int hdmi_wait_softreset(void)
309{
310 /* reset W1 */
311 REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
312
313 /* wait till SOFTRESET == 0 */
314 if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
315 DSSERR("sysconfig reset failed\n");
316 return -ETIMEDOUT;
317 }
318
319 return 0;
320}
321
322static int hdmi_pll_program(struct hdmi_pll_info *fmt)
323{
324 u16 r = 0;
325 enum hdmi_clk_refsel refsel;
326
327 /* wait for wrapper reset */
328 r = hdmi_wait_softreset();
329 if (r)
330 return r;
331
332 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
333 if (r)
334 return r;
335
336 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
337 if (r)
338 return r;
339
340 r = hdmi_pll_reset();
341 if (r)
342 return r;
343
344 refsel = HDMI_REFSEL_SYSCLK;
345
346 r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
347 if (r)
348 return r;
349
350 return 0;
351}
352
353static void hdmi_phy_off(void)
354{
355 hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
356}
357
358static int hdmi_core_ddc_edid(u8 *pedid, int ext)
359{
360 u32 i, j;
361 char checksum = 0;
362 u32 offset = 0;
363
364 /* Turn on CLK for DDC */
365 REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
366
367 /*
368 * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
369 * right shifted values( The behavior is not consistent and seen only
370 * with some TV's)
371 */
372 usleep_range(800, 1000);
373
374 if (!ext) {
375 /* Clk SCL Devices */
376 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
377
378 /* HDMI_CORE_DDC_STATUS_IN_PROG */
379 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
380 4, 4, 0) != 0) {
381 DSSERR("Failed to program DDC\n");
382 return -ETIMEDOUT;
383 }
384
385 /* Clear FIFO */
386 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
387
388 /* HDMI_CORE_DDC_STATUS_IN_PROG */
389 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
390 4, 4, 0) != 0) {
391 DSSERR("Failed to program DDC\n");
392 return -ETIMEDOUT;
393 }
394
395 } else {
396 if (ext % 2 != 0)
397 offset = 0x80;
398 }
399
400 /* Load Segment Address Register */
401 REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
402
403 /* Load Slave Address Register */
404 REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
405
406 /* Load Offset Address Register */
407 REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
408
409 /* Load Byte Count */
410 REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
411 REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
412
413 /* Set DDC_CMD */
414 if (ext)
415 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
416 else
417 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
418
419 /* HDMI_CORE_DDC_STATUS_BUS_LOW */
420 if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
421 DSSWARN("I2C Bus Low?\n");
422 return -EIO;
423 }
424 /* HDMI_CORE_DDC_STATUS_NO_ACK */
425 if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
426 DSSWARN("I2C No Ack\n");
427 return -EIO;
428 }
429
430 i = ext * 128;
431 j = 0;
432 while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
433 (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
434 j < 128) {
435
436 if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
437 /* FIFO not empty */
438 pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0);
439 j++;
440 }
441 }
442
443 for (j = 0; j < 128; j++)
444 checksum += pedid[j];
445
446 if (checksum != 0) {
447 DSSERR("E-EDID checksum failed!!\n");
448 return -EIO;
449 }
450
451 return 0;
452}
453
454static int read_edid(u8 *pedid, u16 max_length)
455{
456 int r = 0, n = 0, i = 0;
457 int max_ext_blocks = (max_length / 128) - 1;
458
459 r = hdmi_core_ddc_edid(pedid, 0);
460 if (r) {
461 return r;
462 } else {
463 n = pedid[0x7e];
464
465 /*
466 * README: need to comply with max_length set by the caller.
467 * Better implementation should be to allocate necessary
468 * memory to store EDID according to nb_block field found
469 * in first block
470 */
471 if (n > max_ext_blocks)
472 n = max_ext_blocks;
473
474 for (i = 1; i <= n; i++) {
475 r = hdmi_core_ddc_edid(pedid, i);
476 if (r)
477 return r;
478 }
479 }
480 return 0;
481}
482
483static int get_timings_index(void)
484{
485 int code;
486
487 if (hdmi.mode == 0)
488 code = code_vesa[hdmi.code];
489 else
490 code = code_cea[hdmi.code];
491
492 if (code == -1) {
493 /* HDMI code 4 corresponds to 640 * 480 VGA */
494 hdmi.code = 4;
495 /* DVI mode 1 corresponds to HDMI 0 to DVI */
496 hdmi.mode = HDMI_DVI;
497
498 code = code_vesa[hdmi.code];
499 }
500 return code;
501}
502
503static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
504{
505 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
506 int timing_vsync = 0, timing_hsync = 0;
507 struct omap_video_timings temp;
508 struct hdmi_cm cm = {-1};
509 DSSDBG("hdmi_get_code\n");
510
511 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
512 temp = cea_vesa_timings[i].timings;
513 if ((temp.pixel_clock == timing->pixel_clock) &&
514 (temp.x_res == timing->x_res) &&
515 (temp.y_res == timing->y_res)) {
516
517 temp_hsync = temp.hfp + temp.hsw + temp.hbp;
518 timing_hsync = timing->hfp + timing->hsw + timing->hbp;
519 temp_vsync = temp.vfp + temp.vsw + temp.vbp;
520 timing_vsync = timing->vfp + timing->vsw + timing->vbp;
521
522 DSSDBG("temp_hsync = %d , temp_vsync = %d"
523 "timing_hsync = %d, timing_vsync = %d\n",
524 temp_hsync, temp_hsync,
525 timing_hsync, timing_vsync);
526
527 if ((temp_hsync == timing_hsync) &&
528 (temp_vsync == timing_vsync)) {
529 code = i;
530 cm.code = code_index[i];
531 if (code < 14)
532 cm.mode = HDMI_HDMI;
533 else
534 cm.mode = HDMI_DVI;
535 DSSDBG("Hdmi_code = %d mode = %d\n",
536 cm.code, cm.mode);
537 break;
538 }
539 }
540 }
541
542 return cm;
543}
544
545static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
546 struct omap_video_timings *timings)
547{
548 /* X and Y resolution */
549 timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
550 edid[current_descriptor_addrs + 2]);
551 timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
552 edid[current_descriptor_addrs + 5]);
553
554 timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
555 edid[current_descriptor_addrs]);
556
557 timings->pixel_clock = 10 * timings->pixel_clock;
558
559 /* HORIZONTAL FRONT PORCH */
560 timings->hfp = edid[current_descriptor_addrs + 8] |
561 ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
562 /* HORIZONTAL SYNC WIDTH */
563 timings->hsw = edid[current_descriptor_addrs + 9] |
564 ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
565 /* HORIZONTAL BACK PORCH */
566 timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
567 edid[current_descriptor_addrs + 3]) -
568 (timings->hfp + timings->hsw);
569 /* VERTICAL FRONT PORCH */
570 timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
571 ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
572 /* VERTICAL SYNC WIDTH */
573 timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
574 ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
575 /* VERTICAL BACK PORCH */
576 timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
577 edid[current_descriptor_addrs + 6]) -
578 (timings->vfp + timings->vsw);
579
580}
581
582/* Description : This function gets the resolution information from EDID */
583static void get_edid_timing_data(u8 *edid)
584{
585 u8 count;
586 u16 current_descriptor_addrs;
587 struct hdmi_cm cm;
588 struct omap_video_timings edid_timings;
589
590 /* seach block 0, there are 4 DTDs arranged in priority order */
591 for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
592 current_descriptor_addrs =
593 EDID_DESCRIPTOR_BLOCK0_ADDRESS +
594 count * EDID_TIMING_DESCRIPTOR_SIZE;
595 get_horz_vert_timing_info(current_descriptor_addrs,
596 edid, &edid_timings);
597 cm = hdmi_get_code(&edid_timings);
598 DSSDBG("Block0[%d] value matches code = %d , mode = %d\n",
599 count, cm.code, cm.mode);
600 if (cm.code == -1) {
601 continue;
602 } else {
603 hdmi.code = cm.code;
604 hdmi.mode = cm.mode;
605 DSSDBG("code = %d , mode = %d\n",
606 hdmi.code, hdmi.mode);
607 return;
608 }
609 }
610 if (edid[0x7e] != 0x00) {
611 for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
612 count++) {
613 current_descriptor_addrs =
614 EDID_DESCRIPTOR_BLOCK1_ADDRESS +
615 count * EDID_TIMING_DESCRIPTOR_SIZE;
616 get_horz_vert_timing_info(current_descriptor_addrs,
617 edid, &edid_timings);
618 cm = hdmi_get_code(&edid_timings);
619 DSSDBG("Block1[%d] value matches code = %d, mode = %d",
620 count, cm.code, cm.mode);
621 if (cm.code == -1) {
622 continue;
623 } else {
624 hdmi.code = cm.code;
625 hdmi.mode = cm.mode;
626 DSSDBG("code = %d , mode = %d\n",
627 hdmi.code, hdmi.mode);
628 return;
629 }
630 }
631 }
632
633 DSSINFO("no valid timing found , falling back to VGA\n");
634 hdmi.code = 4; /* setting default value of 640 480 VGA */
635 hdmi.mode = HDMI_DVI;
636}
637
638static void hdmi_read_edid(struct omap_video_timings *dp)
639{
640 int ret = 0, code;
641
642 memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
643
644 if (!hdmi.edid_set)
645 ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH);
646
647 if (!ret) {
648 if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
649 /* search for timings of default resolution */
650 get_edid_timing_data(hdmi.edid);
651 hdmi.edid_set = true;
652 }
653 } else {
654 DSSWARN("failed to read E-EDID\n");
655 }
656
657 if (!hdmi.edid_set) {
658 DSSINFO("fallback to VGA\n");
659 hdmi.code = 4; /* setting default value of 640 480 VGA */
660 hdmi.mode = HDMI_DVI;
661 }
662
663 code = get_timings_index();
664
665 *dp = cea_vesa_timings[code].timings;
666}
667
668static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
669 struct hdmi_core_infoframe_avi *avi_cfg,
670 struct hdmi_core_packet_enable_repeat *repeat_cfg)
671{
672 DSSDBG("Enter hdmi_core_init\n");
673
674 /* video core */
675 video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
676 video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
677 video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
678 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
679 video_cfg->hdmi_dvi = HDMI_DVI;
680 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
681
682 /* info frame */
683 avi_cfg->db1_format = 0;
684 avi_cfg->db1_active_info = 0;
685 avi_cfg->db1_bar_info_dv = 0;
686 avi_cfg->db1_scan_info = 0;
687 avi_cfg->db2_colorimetry = 0;
688 avi_cfg->db2_aspect_ratio = 0;
689 avi_cfg->db2_active_fmt_ar = 0;
690 avi_cfg->db3_itc = 0;
691 avi_cfg->db3_ec = 0;
692 avi_cfg->db3_q_range = 0;
693 avi_cfg->db3_nup_scaling = 0;
694 avi_cfg->db4_videocode = 0;
695 avi_cfg->db5_pixel_repeat = 0;
696 avi_cfg->db6_7_line_eoftop = 0 ;
697 avi_cfg->db8_9_line_sofbottom = 0;
698 avi_cfg->db10_11_pixel_eofleft = 0;
699 avi_cfg->db12_13_pixel_sofright = 0;
700
701 /* packet enable and repeat */
702 repeat_cfg->audio_pkt = 0;
703 repeat_cfg->audio_pkt_repeat = 0;
704 repeat_cfg->avi_infoframe = 0;
705 repeat_cfg->avi_infoframe_repeat = 0;
706 repeat_cfg->gen_cntrl_pkt = 0;
707 repeat_cfg->gen_cntrl_pkt_repeat = 0;
708 repeat_cfg->generic_pkt = 0;
709 repeat_cfg->generic_pkt_repeat = 0;
710}
711
712static void hdmi_core_powerdown_disable(void)
713{
714 DSSDBG("Enter hdmi_core_powerdown_disable\n");
715 REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
716}
717
718static void hdmi_core_swreset_release(void)
719{
720 DSSDBG("Enter hdmi_core_swreset_release\n");
721 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
722}
723
724static void hdmi_core_swreset_assert(void)
725{
726 DSSDBG("Enter hdmi_core_swreset_assert\n");
727 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
728}
729
730/* DSS_HDMI_CORE_VIDEO_CONFIG */
731static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
732{
733 u32 r = 0;
734
735 /* sys_ctrl1 default configuration not tunable */
736 r = hdmi_read_reg(HDMI_CORE_CTRL1);
737 r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
738 r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
739 r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
740 r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
741 hdmi_write_reg(HDMI_CORE_CTRL1, r);
742
743 REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
744
745 /* Vid_Mode */
746 r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
747
748 /* dither truncation configuration */
749 if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
750 r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
751 r = FLD_MOD(r, 1, 5, 5);
752 } else {
753 r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
754 r = FLD_MOD(r, 0, 5, 5);
755 }
756 hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
757
758 /* HDMI_Ctrl */
759 r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
760 r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
761 r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
762 r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
763 hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
764
765 /* TMDS_CTRL */
766 REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
767 cfg->tclk_sel_clkmult, 6, 5);
768}
769
770static void hdmi_core_aux_infoframe_avi_config(
771 struct hdmi_core_infoframe_avi info_avi)
772{
773 u32 val;
774 char sum = 0, checksum = 0;
775
776 sum += 0x82 + 0x002 + 0x00D;
777 hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
778 hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
779 hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
780
781 val = (info_avi.db1_format << 5) |
782 (info_avi.db1_active_info << 4) |
783 (info_avi.db1_bar_info_dv << 2) |
784 (info_avi.db1_scan_info);
785 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
786 sum += val;
787
788 val = (info_avi.db2_colorimetry << 6) |
789 (info_avi.db2_aspect_ratio << 4) |
790 (info_avi.db2_active_fmt_ar);
791 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
792 sum += val;
793
794 val = (info_avi.db3_itc << 7) |
795 (info_avi.db3_ec << 4) |
796 (info_avi.db3_q_range << 2) |
797 (info_avi.db3_nup_scaling);
798 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
799 sum += val;
800
801 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
802 sum += info_avi.db4_videocode;
803
804 val = info_avi.db5_pixel_repeat;
805 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
806 sum += val;
807
808 val = info_avi.db6_7_line_eoftop & 0x00FF;
809 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
810 sum += val;
811
812 val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
813 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
814 sum += val;
815
816 val = info_avi.db8_9_line_sofbottom & 0x00FF;
817 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
818 sum += val;
819
820 val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
821 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
822 sum += val;
823
824 val = info_avi.db10_11_pixel_eofleft & 0x00FF;
825 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
826 sum += val;
827
828 val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
829 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
830 sum += val;
831
832 val = info_avi.db12_13_pixel_sofright & 0x00FF;
833 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
834 sum += val;
835
836 val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
837 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
838 sum += val;
839
840 checksum = 0x100 - sum;
841 hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
842}
843
844static void hdmi_core_av_packet_config(
845 struct hdmi_core_packet_enable_repeat repeat_cfg)
846{
847 /* enable/repeat the infoframe */
848 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
849 (repeat_cfg.audio_pkt << 5) |
850 (repeat_cfg.audio_pkt_repeat << 4) |
851 (repeat_cfg.avi_infoframe << 1) |
852 (repeat_cfg.avi_infoframe_repeat));
853
854 /* enable/repeat the packet */
855 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
856 (repeat_cfg.gen_cntrl_pkt << 3) |
857 (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
858 (repeat_cfg.generic_pkt << 1) |
859 (repeat_cfg.generic_pkt_repeat));
860}
861
862static void hdmi_wp_init(struct omap_video_timings *timings,
863 struct hdmi_video_format *video_fmt,
864 struct hdmi_video_interface *video_int)
865{
866 DSSDBG("Enter hdmi_wp_init\n");
867
868 timings->hbp = 0;
869 timings->hfp = 0;
870 timings->hsw = 0;
871 timings->vbp = 0;
872 timings->vfp = 0;
873 timings->vsw = 0;
874
875 video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
876 video_fmt->y_res = 0;
877 video_fmt->x_res = 0;
878
879 video_int->vsp = 0;
880 video_int->hsp = 0;
881
882 video_int->interlacing = 0;
883 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
884
885}
886
887static void hdmi_wp_video_start(bool start)
888{
889 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31);
890}
891
892static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
893 struct omap_video_timings *timings, struct hdmi_config *param)
894{
895 DSSDBG("Enter hdmi_wp_video_init_format\n");
896
897 video_fmt->y_res = param->timings.timings.y_res;
898 video_fmt->x_res = param->timings.timings.x_res;
899
900 timings->hbp = param->timings.timings.hbp;
901 timings->hfp = param->timings.timings.hfp;
902 timings->hsw = param->timings.timings.hsw;
903 timings->vbp = param->timings.timings.vbp;
904 timings->vfp = param->timings.timings.vfp;
905 timings->vsw = param->timings.timings.vsw;
906}
907
908static void hdmi_wp_video_config_format(
909 struct hdmi_video_format *video_fmt)
910{
911 u32 l = 0;
912
913 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
914
915 l |= FLD_VAL(video_fmt->y_res, 31, 16);
916 l |= FLD_VAL(video_fmt->x_res, 15, 0);
917 hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
918}
919
920static void hdmi_wp_video_config_interface(
921 struct hdmi_video_interface *video_int)
922{
923 u32 r;
924 DSSDBG("Enter hdmi_wp_video_config_interface\n");
925
926 r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
927 r = FLD_MOD(r, video_int->vsp, 7, 7);
928 r = FLD_MOD(r, video_int->hsp, 6, 6);
929 r = FLD_MOD(r, video_int->interlacing, 3, 3);
930 r = FLD_MOD(r, video_int->tm, 1, 0);
931 hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
932}
933
934static void hdmi_wp_video_config_timing(
935 struct omap_video_timings *timings)
936{
937 u32 timing_h = 0;
938 u32 timing_v = 0;
939
940 DSSDBG("Enter hdmi_wp_video_config_timing\n");
941
942 timing_h |= FLD_VAL(timings->hbp, 31, 20);
943 timing_h |= FLD_VAL(timings->hfp, 19, 8);
944 timing_h |= FLD_VAL(timings->hsw, 7, 0);
945 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
946
947 timing_v |= FLD_VAL(timings->vbp, 31, 20);
948 timing_v |= FLD_VAL(timings->vfp, 19, 8);
949 timing_v |= FLD_VAL(timings->vsw, 7, 0);
950 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
951}
952
953static void hdmi_basic_configure(struct hdmi_config *cfg)
954{
955 /* HDMI */
956 struct omap_video_timings video_timing;
957 struct hdmi_video_format video_format;
958 struct hdmi_video_interface video_interface;
959 /* HDMI core */
960 struct hdmi_core_infoframe_avi avi_cfg;
961 struct hdmi_core_video_config v_core_cfg;
962 struct hdmi_core_packet_enable_repeat repeat_cfg;
963
964 hdmi_wp_init(&video_timing, &video_format,
965 &video_interface);
966
967 hdmi_core_init(&v_core_cfg,
968 &avi_cfg,
969 &repeat_cfg);
970
971 hdmi_wp_video_init_format(&video_format,
972 &video_timing, cfg);
973
974 hdmi_wp_video_config_timing(&video_timing);
975
976 /* video config */
977 video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
978
979 hdmi_wp_video_config_format(&video_format);
980
981 video_interface.vsp = cfg->timings.vsync_pol;
982 video_interface.hsp = cfg->timings.hsync_pol;
983 video_interface.interlacing = cfg->interlace;
984 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
985
986 hdmi_wp_video_config_interface(&video_interface);
987
988 /*
989 * configure core video part
990 * set software reset in the core
991 */
992 hdmi_core_swreset_assert();
993
994 /* power down off */
995 hdmi_core_powerdown_disable();
996
997 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
998 v_core_cfg.hdmi_dvi = cfg->cm.mode;
999
1000 hdmi_core_video_config(&v_core_cfg);
1001
1002 /* release software reset in the core */
1003 hdmi_core_swreset_release();
1004
1005 /*
1006 * configure packet
1007 * info frame video see doc CEA861-D page 65
1008 */
1009 avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
1010 avi_cfg.db1_active_info =
1011 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
1012 avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
1013 avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
1014 avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
1015 avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
1016 avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
1017 avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
1018 avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
1019 avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
1020 avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
1021 avi_cfg.db4_videocode = cfg->cm.code;
1022 avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
1023 avi_cfg.db6_7_line_eoftop = 0;
1024 avi_cfg.db8_9_line_sofbottom = 0;
1025 avi_cfg.db10_11_pixel_eofleft = 0;
1026 avi_cfg.db12_13_pixel_sofright = 0;
1027
1028 hdmi_core_aux_infoframe_avi_config(avi_cfg);
1029
1030 /* enable/repeat the infoframe */
1031 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
1032 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
1033 /* wakeup */
1034 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
1035 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
1036 hdmi_core_av_packet_config(repeat_cfg);
1037}
1038
1039static void update_hdmi_timings(struct hdmi_config *cfg,
1040 struct omap_video_timings *timings, int code)
1041{
1042 cfg->timings.timings.x_res = timings->x_res;
1043 cfg->timings.timings.y_res = timings->y_res;
1044 cfg->timings.timings.hbp = timings->hbp;
1045 cfg->timings.timings.hfp = timings->hfp;
1046 cfg->timings.timings.hsw = timings->hsw;
1047 cfg->timings.timings.vbp = timings->vbp;
1048 cfg->timings.timings.vfp = timings->vfp;
1049 cfg->timings.timings.vsw = timings->vsw;
1050 cfg->timings.timings.pixel_clock = timings->pixel_clock;
1051 cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
1052 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
1053}
1054
1055static void hdmi_compute_pll(unsigned long clkin, int phy,
1056 int n, struct hdmi_pll_info *pi)
1057{
1058 unsigned long refclk;
1059 u32 mf;
1060
1061 /*
1062 * Input clock is predivided by N + 1
1063 * out put of which is reference clk
1064 */
1065 refclk = clkin / (n + 1);
1066 pi->regn = n;
1067
1068 /*
1069 * multiplier is pixel_clk/ref_clk
1070 * Multiplying by 100 to avoid fractional part removal
1071 */
1072 pi->regm = (phy * 100/(refclk))/100;
1073 pi->regm2 = 1;
1074
1075 /*
1076 * fractional multiplier is remainder of the difference between
1077 * multiplier and actual phy(required pixel clock thus should be
1078 * multiplied by 2^18(262144) divided by the reference clock
1079 */
1080 mf = (phy - pi->regm * refclk) * 262144;
1081 pi->regmf = mf/(refclk);
1082
1083 /*
1084 * Dcofreq should be set to 1 if required pixel clock
1085 * is greater than 1000MHz
1086 */
1087 pi->dcofreq = phy > 1000 * 100;
1088 pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10;
1089
1090 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
1091 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
1092}
1093
1094static void hdmi_enable_clocks(int enable)
1095{
1096 if (enable)
1097 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
1098 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1099 else
1100 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
1101 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1102}
1103
1104static int hdmi_power_on(struct omap_dss_device *dssdev)
1105{
1106 int r, code = 0;
1107 struct hdmi_pll_info pll_data;
1108 struct omap_video_timings *p;
1109 int clkin, n, phy;
1110
1111 hdmi_enable_clocks(1);
1112
1113 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1114
1115 p = &dssdev->panel.timings;
1116
1117 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
1118 dssdev->panel.timings.x_res,
1119 dssdev->panel.timings.y_res);
1120
1121 if (!hdmi.custom_set) {
1122 DSSDBG("Read EDID as no EDID is not set on poweron\n");
1123 hdmi_read_edid(p);
1124 }
1125 code = get_timings_index();
1126 dssdev->panel.timings = cea_vesa_timings[code].timings;
1127 update_hdmi_timings(&hdmi.cfg, p, code);
1128
1129 clkin = 3840; /* 38.4 MHz */
1130 n = 15; /* this is a constant for our math */
1131 phy = p->pixel_clock;
1132
1133 hdmi_compute_pll(clkin, phy, n, &pll_data);
1134
1135 hdmi_wp_video_start(0);
1136
1137 /* config the PLL and PHY first */
1138 r = hdmi_pll_program(&pll_data);
1139 if (r) {
1140 DSSDBG("Failed to lock PLL\n");
1141 goto err;
1142 }
1143
1144 r = hdmi_phy_init();
1145 if (r) {
1146 DSSDBG("Failed to start PHY\n");
1147 goto err;
1148 }
1149
1150 hdmi.cfg.cm.mode = hdmi.mode;
1151 hdmi.cfg.cm.code = hdmi.code;
1152 hdmi_basic_configure(&hdmi.cfg);
1153
1154 /* Make selection of HDMI in DSS */
1155 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
1156
1157 /* Select the dispc clock source as PRCM clock, to ensure that it is not
1158 * DSI PLL source as the clock selected by DSI PLL might not be
1159 * sufficient for the resolution selected / that can be changed
1160 * dynamically by user. This can be moved to single location , say
1161 * Boardfile.
1162 */
1163 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
1164
1165 /* bypass TV gamma table */
1166 dispc_enable_gamma_table(0);
1167
1168 /* tv size */
1169 dispc_set_digit_size(dssdev->panel.timings.x_res,
1170 dssdev->panel.timings.y_res);
1171
1172 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
1173
1174 hdmi_wp_video_start(1);
1175
1176 return 0;
1177err:
1178 hdmi_enable_clocks(0);
1179 return -EIO;
1180}
1181
1182static void hdmi_power_off(struct omap_dss_device *dssdev)
1183{
1184 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1185
1186 hdmi_wp_video_start(0);
1187 hdmi_phy_off();
1188 hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
1189 hdmi_enable_clocks(0);
1190
1191 hdmi.edid_set = 0;
1192}
1193
1194int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
1195 struct omap_video_timings *timings)
1196{
1197 struct hdmi_cm cm;
1198
1199 cm = hdmi_get_code(timings);
1200 if (cm.code == -1) {
1201 DSSERR("Invalid timing entered\n");
1202 return -EINVAL;
1203 }
1204
1205 return 0;
1206
1207}
1208
1209void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
1210{
1211 struct hdmi_cm cm;
1212
1213 hdmi.custom_set = 1;
1214 cm = hdmi_get_code(&dssdev->panel.timings);
1215 hdmi.code = cm.code;
1216 hdmi.mode = cm.mode;
1217 omapdss_hdmi_display_enable(dssdev);
1218 hdmi.custom_set = 0;
1219}
1220
1221int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
1222{
1223 int r = 0;
1224
1225 DSSDBG("ENTER hdmi_display_enable\n");
1226
1227 mutex_lock(&hdmi.lock);
1228
1229 r = omap_dss_start_device(dssdev);
1230 if (r) {
1231 DSSERR("failed to start device\n");
1232 goto err0;
1233 }
1234
1235 if (dssdev->platform_enable) {
1236 r = dssdev->platform_enable(dssdev);
1237 if (r) {
1238 DSSERR("failed to enable GPIO's\n");
1239 goto err1;
1240 }
1241 }
1242
1243 r = hdmi_power_on(dssdev);
1244 if (r) {
1245 DSSERR("failed to power on device\n");
1246 goto err2;
1247 }
1248
1249 mutex_unlock(&hdmi.lock);
1250 return 0;
1251
1252err2:
1253 if (dssdev->platform_disable)
1254 dssdev->platform_disable(dssdev);
1255err1:
1256 omap_dss_stop_device(dssdev);
1257err0:
1258 mutex_unlock(&hdmi.lock);
1259 return r;
1260}
1261
1262void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
1263{
1264 DSSDBG("Enter hdmi_display_disable\n");
1265
1266 mutex_lock(&hdmi.lock);
1267
1268 hdmi_power_off(dssdev);
1269
1270 if (dssdev->platform_disable)
1271 dssdev->platform_disable(dssdev);
1272
1273 omap_dss_stop_device(dssdev);
1274
1275 mutex_unlock(&hdmi.lock);
1276}
1277
1278/* HDMI HW IP initialisation */
1279static int omapdss_hdmihw_probe(struct platform_device *pdev)
1280{
1281 struct resource *hdmi_mem;
1282
1283 hdmi.pdata = pdev->dev.platform_data;
1284 hdmi.pdev = pdev;
1285
1286 mutex_init(&hdmi.lock);
1287
1288 hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1289 if (!hdmi_mem) {
1290 DSSERR("can't get IORESOURCE_MEM HDMI\n");
1291 return -EINVAL;
1292 }
1293
1294 /* Base address taken from platform */
1295 hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem));
1296 if (!hdmi.base_wp) {
1297 DSSERR("can't ioremap WP\n");
1298 return -ENOMEM;
1299 }
1300
1301 hdmi_panel_init();
1302
1303 return 0;
1304}
1305
1306static int omapdss_hdmihw_remove(struct platform_device *pdev)
1307{
1308 hdmi_panel_exit();
1309
1310 iounmap(hdmi.base_wp);
1311
1312 return 0;
1313}
1314
1315static struct platform_driver omapdss_hdmihw_driver = {
1316 .probe = omapdss_hdmihw_probe,
1317 .remove = omapdss_hdmihw_remove,
1318 .driver = {
1319 .name = "omapdss_hdmi",
1320 .owner = THIS_MODULE,
1321 },
1322};
1323
1324int hdmi_init_platform_driver(void)
1325{
1326 return platform_driver_register(&omapdss_hdmihw_driver);
1327}
1328
1329void hdmi_uninit_platform_driver(void)
1330{
1331 return platform_driver_unregister(&omapdss_hdmihw_driver);
1332}
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
new file mode 100644
index 000000000000..9887ab96da3c
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -0,0 +1,415 @@
1/*
2 * hdmi.h
3 *
4 * HDMI driver definition for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef _OMAP4_DSS_HDMI_H_
22#define _OMAP4_DSS_HDMI_H_
23
24#include <linux/string.h>
25#include <plat/display.h>
26
27#define HDMI_WP 0x0
28#define HDMI_CORE_SYS 0x400
29#define HDMI_CORE_AV 0x900
30#define HDMI_PLLCTRL 0x200
31#define HDMI_PHY 0x300
32
33struct hdmi_reg { u16 idx; };
34
35#define HDMI_REG(idx) ((const struct hdmi_reg) { idx })
36
37/* HDMI Wrapper */
38#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx)
39
40#define HDMI_WP_REVISION HDMI_WP_REG(0x0)
41#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10)
42#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24)
43#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28)
44#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40)
45#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C)
46#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50)
47#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60)
48#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
49#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
50#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
51
52/* HDMI IP Core System */
53#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
54
55#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0)
56#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8)
57#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC)
58#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10)
59#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14)
60#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20)
61#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24)
62#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124)
63#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128)
64#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0)
65#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4)
66#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8)
67#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC)
68#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0)
69#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4)
70#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208)
71#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8)
72#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC)
73#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0)
74#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8)
75#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC)
76#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0)
77#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4)
78#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1
79#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1
80#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1
81#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1
82
83/* HDMI DDC E-DID */
84#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC)
85#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8)
86#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4)
87#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC)
88#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0)
89#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4)
90#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0)
91#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8)
92
93/* HDMI IP Core Audio Video */
94#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx)
95
96#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
97#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
98#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
99#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
100#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
101#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
102#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
103#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
104#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110)
105#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
106#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
107#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
108#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
109#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
110#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
111#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
112#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380)
113#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
114#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4)
115#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8)
116#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC)
117#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10)
118#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14)
119#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18)
120#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C)
121#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20)
122#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24)
123#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28)
124#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C)
125#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50)
126#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54)
127#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60)
128#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64)
129#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C)
130#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70)
131#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74)
132#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78)
133#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C)
134#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80)
135#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84)
136#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88)
137#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C)
138#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90)
139#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
140#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0)
141#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC)
142#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0)
143#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4)
144#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0)
145#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
146#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
147#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
148#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
149#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
150#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
151#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
152#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180)
153#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
154#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
155#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
156#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
157#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
158#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
159#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C)
160#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C)
161#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC)
162#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4
163#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4
164#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4
165#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4
166
167/* PLL */
168#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx)
169
170#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0)
171#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4)
172#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8)
173#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC)
174#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10)
175#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14)
176#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20)
177
178/* HDMI PHY */
179#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx)
180
181#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0)
182#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4)
183#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8)
184#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC)
185
186/* HDMI EDID Length */
187#define HDMI_EDID_MAX_LENGTH 256
188#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
189#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
190#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
191#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
192#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
193
194#define OMAP_HDMI_TIMINGS_NB 34
195
196#define REG_FLD_MOD(idx, val, start, end) \
197 hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
198#define REG_GET(idx, start, end) \
199 FLD_GET(hdmi_read_reg(idx), start, end)
200
201/* HDMI timing structure */
202struct hdmi_timings {
203 struct omap_video_timings timings;
204 int vsync_pol;
205 int hsync_pol;
206};
207
208enum hdmi_phy_pwr {
209 HDMI_PHYPWRCMD_OFF = 0,
210 HDMI_PHYPWRCMD_LDOON = 1,
211 HDMI_PHYPWRCMD_TXON = 2
212};
213
214enum hdmi_pll_pwr {
215 HDMI_PLLPWRCMD_ALLOFF = 0,
216 HDMI_PLLPWRCMD_PLLONLY = 1,
217 HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
218 HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
219};
220
221enum hdmi_clk_refsel {
222 HDMI_REFSEL_PCLK = 0,
223 HDMI_REFSEL_REF1 = 1,
224 HDMI_REFSEL_REF2 = 2,
225 HDMI_REFSEL_SYSCLK = 3
226};
227
228enum hdmi_core_inputbus_width {
229 HDMI_INPUT_8BIT = 0,
230 HDMI_INPUT_10BIT = 1,
231 HDMI_INPUT_12BIT = 2
232};
233
234enum hdmi_core_dither_trunc {
235 HDMI_OUTPUTTRUNCATION_8BIT = 0,
236 HDMI_OUTPUTTRUNCATION_10BIT = 1,
237 HDMI_OUTPUTTRUNCATION_12BIT = 2,
238 HDMI_OUTPUTDITHER_8BIT = 3,
239 HDMI_OUTPUTDITHER_10BIT = 4,
240 HDMI_OUTPUTDITHER_12BIT = 5
241};
242
243enum hdmi_core_deepcolor_ed {
244 HDMI_DEEPCOLORPACKECTDISABLE = 0,
245 HDMI_DEEPCOLORPACKECTENABLE = 1
246};
247
248enum hdmi_core_packet_mode {
249 HDMI_PACKETMODERESERVEDVALUE = 0,
250 HDMI_PACKETMODE24BITPERPIXEL = 4,
251 HDMI_PACKETMODE30BITPERPIXEL = 5,
252 HDMI_PACKETMODE36BITPERPIXEL = 6,
253 HDMI_PACKETMODE48BITPERPIXEL = 7
254};
255
256enum hdmi_core_hdmi_dvi {
257 HDMI_DVI = 0,
258 HDMI_HDMI = 1
259};
260
261enum hdmi_core_tclkselclkmult {
262 HDMI_FPLL05IDCK = 0,
263 HDMI_FPLL10IDCK = 1,
264 HDMI_FPLL20IDCK = 2,
265 HDMI_FPLL40IDCK = 3
266};
267
268enum hdmi_core_packet_ctrl {
269 HDMI_PACKETENABLE = 1,
270 HDMI_PACKETDISABLE = 0,
271 HDMI_PACKETREPEATON = 1,
272 HDMI_PACKETREPEATOFF = 0
273};
274
275/* INFOFRAME_AVI_ definitions */
276enum hdmi_core_infoframe {
277 HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
278 HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
279 HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
280 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
281 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
282 HDMI_INFOFRAME_AVI_DB1B_NO = 0,
283 HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
284 HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
285 HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
286 HDMI_INFOFRAME_AVI_DB1S_0 = 0,
287 HDMI_INFOFRAME_AVI_DB1S_1 = 1,
288 HDMI_INFOFRAME_AVI_DB1S_2 = 2,
289 HDMI_INFOFRAME_AVI_DB2C_NO = 0,
290 HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
291 HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
292 HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
293 HDMI_INFOFRAME_AVI_DB2M_NO = 0,
294 HDMI_INFOFRAME_AVI_DB2M_43 = 1,
295 HDMI_INFOFRAME_AVI_DB2M_169 = 2,
296 HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
297 HDMI_INFOFRAME_AVI_DB2R_43 = 9,
298 HDMI_INFOFRAME_AVI_DB2R_169 = 10,
299 HDMI_INFOFRAME_AVI_DB2R_149 = 11,
300 HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
301 HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
302 HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
303 HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
304 HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
305 HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
306 HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
307 HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
308 HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
309 HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
310 HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
311 HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
312 HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
313 HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
314 HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
315 HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
316 HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
317 HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
318 HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
319 HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
320 HDMI_INFOFRAME_AVI_DB5PR_10 = 9
321};
322
323enum hdmi_packing_mode {
324 HDMI_PACK_10b_RGB_YUV444 = 0,
325 HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
326 HDMI_PACK_20b_YUV422 = 2,
327 HDMI_PACK_ALREADYPACKED = 7
328};
329
330struct hdmi_core_video_config {
331 enum hdmi_core_inputbus_width ip_bus_width;
332 enum hdmi_core_dither_trunc op_dither_truc;
333 enum hdmi_core_deepcolor_ed deep_color_pkt;
334 enum hdmi_core_packet_mode pkt_mode;
335 enum hdmi_core_hdmi_dvi hdmi_dvi;
336 enum hdmi_core_tclkselclkmult tclk_sel_clkmult;
337};
338
339/*
340 * Refer to section 8.2 in HDMI 1.3 specification for
341 * details about infoframe databytes
342 */
343struct hdmi_core_infoframe_avi {
344 u8 db1_format;
345 /* Y0, Y1 rgb,yCbCr */
346 u8 db1_active_info;
347 /* A0 Active information Present */
348 u8 db1_bar_info_dv;
349 /* B0, B1 Bar info data valid */
350 u8 db1_scan_info;
351 /* S0, S1 scan information */
352 u8 db2_colorimetry;
353 /* C0, C1 colorimetry */
354 u8 db2_aspect_ratio;
355 /* M0, M1 Aspect ratio (4:3, 16:9) */
356 u8 db2_active_fmt_ar;
357 /* R0...R3 Active format aspect ratio */
358 u8 db3_itc;
359 /* ITC IT content. */
360 u8 db3_ec;
361 /* EC0, EC1, EC2 Extended colorimetry */
362 u8 db3_q_range;
363 /* Q1, Q0 Quantization range */
364 u8 db3_nup_scaling;
365 /* SC1, SC0 Non-uniform picture scaling */
366 u8 db4_videocode;
367 /* VIC0..6 Video format identification */
368 u8 db5_pixel_repeat;
369 /* PR0..PR3 Pixel repetition factor */
370 u16 db6_7_line_eoftop;
371 /* Line number end of top bar */
372 u16 db8_9_line_sofbottom;
373 /* Line number start of bottom bar */
374 u16 db10_11_pixel_eofleft;
375 /* Pixel number end of left bar */
376 u16 db12_13_pixel_sofright;
377 /* Pixel number start of right bar */
378};
379
380struct hdmi_core_packet_enable_repeat {
381 u32 audio_pkt;
382 u32 audio_pkt_repeat;
383 u32 avi_infoframe;
384 u32 avi_infoframe_repeat;
385 u32 gen_cntrl_pkt;
386 u32 gen_cntrl_pkt_repeat;
387 u32 generic_pkt;
388 u32 generic_pkt_repeat;
389};
390
391struct hdmi_video_format {
392 enum hdmi_packing_mode packing_mode;
393 u32 y_res; /* Line per panel */
394 u32 x_res; /* pixel per line */
395};
396
397struct hdmi_video_interface {
398 int vsp; /* Vsync polarity */
399 int hsp; /* Hsync polarity */
400 int interlacing;
401 int tm; /* Timing mode */
402};
403
404struct hdmi_cm {
405 int code;
406 int mode;
407};
408
409struct hdmi_config {
410 struct hdmi_timings timings;
411 u16 interlace;
412 struct hdmi_cm cm;
413};
414
415#endif
diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c
new file mode 100644
index 000000000000..ffb5de94131f
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c
@@ -0,0 +1,222 @@
1/*
2 * hdmi_omap4_panel.c
3 *
4 * HDMI library support functions for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 * Authors: Mythri P k <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/kernel.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/mutex.h>
26#include <linux/module.h>
27#include <plat/display.h>
28
29#include "dss.h"
30
31static struct {
32 struct mutex hdmi_lock;
33} hdmi;
34
35
36static int hdmi_panel_probe(struct omap_dss_device *dssdev)
37{
38 DSSDBG("ENTER hdmi_panel_probe\n");
39
40 dssdev->panel.config = OMAP_DSS_LCD_TFT |
41 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
42
43 /*
44 * Initialize the timings to 640 * 480
45 * This is only for framebuffer update not for TV timing setting
46 * Setting TV timing will be done only on enable
47 */
48 dssdev->panel.timings.x_res = 640;
49 dssdev->panel.timings.y_res = 480;
50
51 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
52 dssdev->panel.timings.x_res,
53 dssdev->panel.timings.y_res);
54 return 0;
55}
56
57static void hdmi_panel_remove(struct omap_dss_device *dssdev)
58{
59
60}
61
62static int hdmi_panel_enable(struct omap_dss_device *dssdev)
63{
64 int r = 0;
65 DSSDBG("ENTER hdmi_panel_enable\n");
66
67 mutex_lock(&hdmi.hdmi_lock);
68
69 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
70 r = -EINVAL;
71 goto err;
72 }
73
74 r = omapdss_hdmi_display_enable(dssdev);
75 if (r) {
76 DSSERR("failed to power on\n");
77 goto err;
78 }
79
80 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
81
82err:
83 mutex_unlock(&hdmi.hdmi_lock);
84
85 return r;
86}
87
88static void hdmi_panel_disable(struct omap_dss_device *dssdev)
89{
90 mutex_lock(&hdmi.hdmi_lock);
91
92 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
93 omapdss_hdmi_display_disable(dssdev);
94
95 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
96
97 mutex_unlock(&hdmi.hdmi_lock);
98}
99
100static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
101{
102 int r = 0;
103
104 mutex_lock(&hdmi.hdmi_lock);
105
106 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
107 r = -EINVAL;
108 goto err;
109 }
110
111 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
112
113 omapdss_hdmi_display_disable(dssdev);
114
115err:
116 mutex_unlock(&hdmi.hdmi_lock);
117
118 return r;
119}
120
121static int hdmi_panel_resume(struct omap_dss_device *dssdev)
122{
123 int r = 0;
124
125 mutex_lock(&hdmi.hdmi_lock);
126
127 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
128 r = -EINVAL;
129 goto err;
130 }
131
132 r = omapdss_hdmi_display_enable(dssdev);
133 if (r) {
134 DSSERR("failed to power on\n");
135 goto err;
136 }
137
138 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
139
140err:
141 mutex_unlock(&hdmi.hdmi_lock);
142
143 return r;
144}
145
146static void hdmi_get_timings(struct omap_dss_device *dssdev,
147 struct omap_video_timings *timings)
148{
149 mutex_lock(&hdmi.hdmi_lock);
150
151 *timings = dssdev->panel.timings;
152
153 mutex_unlock(&hdmi.hdmi_lock);
154}
155
156static void hdmi_set_timings(struct omap_dss_device *dssdev,
157 struct omap_video_timings *timings)
158{
159 DSSDBG("hdmi_set_timings\n");
160
161 mutex_lock(&hdmi.hdmi_lock);
162
163 dssdev->panel.timings = *timings;
164
165 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
166 /* turn the hdmi off and on to get new timings to use */
167 omapdss_hdmi_display_disable(dssdev);
168 omapdss_hdmi_display_set_timing(dssdev);
169 }
170
171 mutex_unlock(&hdmi.hdmi_lock);
172}
173
174static int hdmi_check_timings(struct omap_dss_device *dssdev,
175 struct omap_video_timings *timings)
176{
177 int r = 0;
178
179 DSSDBG("hdmi_check_timings\n");
180
181 mutex_lock(&hdmi.hdmi_lock);
182
183 r = omapdss_hdmi_display_check_timing(dssdev, timings);
184 if (r) {
185 DSSERR("Timing cannot be applied\n");
186 goto err;
187 }
188err:
189 mutex_unlock(&hdmi.hdmi_lock);
190 return r;
191}
192
193static struct omap_dss_driver hdmi_driver = {
194 .probe = hdmi_panel_probe,
195 .remove = hdmi_panel_remove,
196 .enable = hdmi_panel_enable,
197 .disable = hdmi_panel_disable,
198 .suspend = hdmi_panel_suspend,
199 .resume = hdmi_panel_resume,
200 .get_timings = hdmi_get_timings,
201 .set_timings = hdmi_set_timings,
202 .check_timings = hdmi_check_timings,
203 .driver = {
204 .name = "hdmi_panel",
205 .owner = THIS_MODULE,
206 },
207};
208
209int hdmi_panel_init(void)
210{
211 mutex_init(&hdmi.hdmi_lock);
212
213 omap_dss_register_driver(&hdmi_driver);
214
215 return 0;
216}
217
218void hdmi_panel_exit(void)
219{
220 omap_dss_unregister_driver(&hdmi_driver);
221
222}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 172d4e697309..bcd37ec86952 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -515,6 +515,8 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
515 515
516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
517 irq = DISPC_IRQ_EVSYNC_ODD; 517 irq = DISPC_IRQ_EVSYNC_ODD;
518 } else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) {
519 irq = DISPC_IRQ_EVSYNC_EVEN;
518 } else { 520 } else {
519 if (mgr->id == OMAP_DSS_CHANNEL_LCD) 521 if (mgr->id == OMAP_DSS_CHANNEL_LCD)
520 irq = DISPC_IRQ_VSYNC; 522 irq = DISPC_IRQ_VSYNC;
@@ -536,7 +538,8 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
536 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 538 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
537 return 0; 539 return 0;
538 540
539 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 541 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
542 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
540 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 543 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
541 } else { 544 } else {
542 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 545 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -613,7 +616,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
613 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 616 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
614 return 0; 617 return 0;
615 618
616 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 619 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
620 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
617 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 621 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
618 } else { 622 } else {
619 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 623 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -1377,6 +1381,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1377 case OMAP_DISPLAY_TYPE_DBI: 1381 case OMAP_DISPLAY_TYPE_DBI:
1378 case OMAP_DISPLAY_TYPE_SDI: 1382 case OMAP_DISPLAY_TYPE_SDI:
1379 case OMAP_DISPLAY_TYPE_VENC: 1383 case OMAP_DISPLAY_TYPE_VENC:
1384 case OMAP_DISPLAY_TYPE_HDMI:
1380 default_get_overlay_fifo_thresholds(ovl->id, size, 1385 default_get_overlay_fifo_thresholds(ovl->id, size,
1381 &oc->burst_size, &oc->fifo_low, 1386 &oc->burst_size, &oc->fifo_low,
1382 &oc->fifo_high); 1387 &oc->fifo_high);
@@ -1394,7 +1399,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1394 } 1399 }
1395 1400
1396 r = 0; 1401 r = 0;
1397 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1402 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1398 if (!dss_cache.irq_enabled) { 1403 if (!dss_cache.irq_enabled) {
1399 u32 mask; 1404 u32 mask;
1400 1405
@@ -1407,7 +1412,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1407 dss_cache.irq_enabled = true; 1412 dss_cache.irq_enabled = true;
1408 } 1413 }
1409 configure_dispc(); 1414 configure_dispc();
1410 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1415 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1411 1416
1412 spin_unlock_irqrestore(&dss_cache.lock, flags); 1417 spin_unlock_irqrestore(&dss_cache.lock, flags);
1413 1418
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 456efef03c20..f1aca6d04011 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -490,7 +490,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
490 490
491 ovl->manager = mgr; 491 ovl->manager = mgr;
492 492
493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
494 /* XXX: on manual update display, in auto update mode, a bug happens 494 /* XXX: on manual update display, in auto update mode, a bug happens
495 * here. When an overlay is first enabled on LCD, then it's disabled, 495 * here. When an overlay is first enabled on LCD, then it's disabled,
496 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT 496 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT
@@ -499,7 +499,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
499 * but I don't understand how or why. */ 499 * but I don't understand how or why. */
500 msleep(40); 500 msleep(40);
501 dispc_set_channel_out(ovl->id, mgr->id); 501 dispc_set_channel_out(ovl->id, mgr->id);
502 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 502 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
503 503
504 return 0; 504 return 0;
505} 505}
@@ -679,7 +679,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
679 lcd2_mgr->set_device(lcd2_mgr, dssdev); 679 lcd2_mgr->set_device(lcd2_mgr, dssdev);
680 mgr = lcd2_mgr; 680 mgr = lcd2_mgr;
681 } 681 }
682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { 682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
683 && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
683 if (!lcd_mgr->device || force) { 684 if (!lcd_mgr->device || force) {
684 if (lcd_mgr->device) 685 if (lcd_mgr->device)
685 lcd_mgr->unset_device(lcd_mgr); 686 lcd_mgr->unset_device(lcd_mgr);
@@ -688,7 +689,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
688 } 689 }
689 } 690 }
690 691
691 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 692 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
693 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
692 if (!tv_mgr->device || force) { 694 if (!tv_mgr->device || force) {
693 if (tv_mgr->device) 695 if (tv_mgr->device)
694 tv_mgr->unset_device(tv_mgr); 696 tv_mgr->unset_device(tv_mgr);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 10a2ffe02882..5ea17f49c611 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -36,8 +36,6 @@
36#include <plat/display.h> 36#include <plat/display.h>
37#include "dss.h" 37#include "dss.h"
38 38
39#define RFBI_BASE 0x48050800
40
41struct rfbi_reg { u16 idx; }; 39struct rfbi_reg { u16 idx; };
42 40
43#define RFBI_REG(idx) ((const struct rfbi_reg) { idx }) 41#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
@@ -100,6 +98,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t);
100static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 98static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
101 99
102static struct { 100static struct {
101 struct platform_device *pdev;
103 void __iomem *base; 102 void __iomem *base;
104 103
105 unsigned long l4_khz; 104 unsigned long l4_khz;
@@ -142,9 +141,9 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
142static void rfbi_enable_clocks(bool enable) 141static void rfbi_enable_clocks(bool enable)
143{ 142{
144 if (enable) 143 if (enable)
145 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 144 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
146 else 145 else
147 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 146 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
148} 147}
149 148
150void omap_rfbi_write_command(const void *buf, u32 len) 149void omap_rfbi_write_command(const void *buf, u32 len)
@@ -497,7 +496,7 @@ unsigned long rfbi_get_max_tx_rate(void)
497 }; 496 };
498 497
499 l4_rate = rfbi.l4_khz / 1000; 498 l4_rate = rfbi.l4_khz / 1000;
500 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000; 499 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000;
501 500
502 for (i = 0; i < ARRAY_SIZE(ftab); i++) { 501 for (i = 0; i < ARRAY_SIZE(ftab); i++) {
503 /* Use a window instead of an exact match, to account 502 /* Use a window instead of an exact match, to account
@@ -922,7 +921,7 @@ void rfbi_dump_regs(struct seq_file *s)
922{ 921{
923#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) 922#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
924 923
925 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 924 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
926 925
927 DUMPREG(RFBI_REVISION); 926 DUMPREG(RFBI_REVISION);
928 DUMPREG(RFBI_SYSCONFIG); 927 DUMPREG(RFBI_SYSCONFIG);
@@ -953,54 +952,10 @@ void rfbi_dump_regs(struct seq_file *s)
953 DUMPREG(RFBI_VSYNC_WIDTH); 952 DUMPREG(RFBI_VSYNC_WIDTH);
954 DUMPREG(RFBI_HSYNC_WIDTH); 953 DUMPREG(RFBI_HSYNC_WIDTH);
955 954
956 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 955 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
957#undef DUMPREG 956#undef DUMPREG
958} 957}
959 958
960int rfbi_init(void)
961{
962 u32 rev;
963 u32 l;
964
965 spin_lock_init(&rfbi.cmd_lock);
966
967 init_completion(&rfbi.cmd_done);
968 atomic_set(&rfbi.cmd_fifo_full, 0);
969 atomic_set(&rfbi.cmd_pending, 0);
970
971 rfbi.base = ioremap(RFBI_BASE, SZ_256);
972 if (!rfbi.base) {
973 DSSERR("can't ioremap RFBI\n");
974 return -ENOMEM;
975 }
976
977 rfbi_enable_clocks(1);
978
979 msleep(10);
980
981 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
982
983 /* Enable autoidle and smart-idle */
984 l = rfbi_read_reg(RFBI_SYSCONFIG);
985 l |= (1 << 0) | (2 << 3);
986 rfbi_write_reg(RFBI_SYSCONFIG, l);
987
988 rev = rfbi_read_reg(RFBI_REVISION);
989 printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
990 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
991
992 rfbi_enable_clocks(0);
993
994 return 0;
995}
996
997void rfbi_exit(void)
998{
999 DSSDBG("rfbi_exit\n");
1000
1001 iounmap(rfbi.base);
1002}
1003
1004int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 959int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1005{ 960{
1006 int r; 961 int r;
@@ -1056,3 +1011,74 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
1056 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 1011 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1057 return 0; 1012 return 0;
1058} 1013}
1014
1015/* RFBI HW IP initialisation */
1016static int omap_rfbihw_probe(struct platform_device *pdev)
1017{
1018 u32 rev;
1019 u32 l;
1020 struct resource *rfbi_mem;
1021
1022 rfbi.pdev = pdev;
1023
1024 spin_lock_init(&rfbi.cmd_lock);
1025
1026 init_completion(&rfbi.cmd_done);
1027 atomic_set(&rfbi.cmd_fifo_full, 0);
1028 atomic_set(&rfbi.cmd_pending, 0);
1029
1030 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
1031 if (!rfbi_mem) {
1032 DSSERR("can't get IORESOURCE_MEM RFBI\n");
1033 return -EINVAL;
1034 }
1035 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
1036 if (!rfbi.base) {
1037 DSSERR("can't ioremap RFBI\n");
1038 return -ENOMEM;
1039 }
1040
1041 rfbi_enable_clocks(1);
1042
1043 msleep(10);
1044
1045 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
1046
1047 /* Enable autoidle and smart-idle */
1048 l = rfbi_read_reg(RFBI_SYSCONFIG);
1049 l |= (1 << 0) | (2 << 3);
1050 rfbi_write_reg(RFBI_SYSCONFIG, l);
1051
1052 rev = rfbi_read_reg(RFBI_REVISION);
1053 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
1054 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1055
1056 rfbi_enable_clocks(0);
1057
1058 return 0;
1059}
1060
1061static int omap_rfbihw_remove(struct platform_device *pdev)
1062{
1063 iounmap(rfbi.base);
1064 return 0;
1065}
1066
1067static struct platform_driver omap_rfbihw_driver = {
1068 .probe = omap_rfbihw_probe,
1069 .remove = omap_rfbihw_remove,
1070 .driver = {
1071 .name = "omapdss_rfbi",
1072 .owner = THIS_MODULE,
1073 },
1074};
1075
1076int rfbi_init_platform_driver(void)
1077{
1078 return platform_driver_register(&omap_rfbihw_driver);
1079}
1080
1081void rfbi_uninit_platform_driver(void)
1082{
1083 return platform_driver_unregister(&omap_rfbihw_driver);
1084}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index b64adf7dfc88..54a53e648180 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -30,7 +30,6 @@
30#include "dss.h" 30#include "dss.h"
31 31
32static struct { 32static struct {
33 bool skip_init;
34 bool update_enabled; 33 bool update_enabled;
35 struct regulator *vdds_sdi_reg; 34 struct regulator *vdds_sdi_reg;
36} sdi; 35} sdi;
@@ -68,9 +67,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
68 if (r) 67 if (r)
69 goto err1; 68 goto err1;
70 69
71 /* In case of skip_init sdi_init has already enabled the clocks */ 70 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
72 if (!sdi.skip_init)
73 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
74 71
75 sdi_basic_init(dssdev); 72 sdi_basic_init(dssdev);
76 73
@@ -80,14 +77,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
80 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 77 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
81 dssdev->panel.acbi, dssdev->panel.acb); 78 dssdev->panel.acbi, dssdev->panel.acb);
82 79
83 if (!sdi.skip_init) { 80 r = dss_calc_clock_div(1, t->pixel_clock * 1000,
84 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 81 &dss_cinfo, &dispc_cinfo);
85 &dss_cinfo, &dispc_cinfo);
86 } else {
87 r = dss_get_clock_div(&dss_cinfo);
88 r = dispc_get_clock_div(dssdev->manager->id, &dispc_cinfo);
89 }
90
91 if (r) 82 if (r)
92 goto err2; 83 goto err2;
93 84
@@ -116,21 +107,17 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
116 if (r) 107 if (r)
117 goto err2; 108 goto err2;
118 109
119 if (!sdi.skip_init) { 110 dss_sdi_init(dssdev->phy.sdi.datapairs);
120 dss_sdi_init(dssdev->phy.sdi.datapairs); 111 r = dss_sdi_enable();
121 r = dss_sdi_enable(); 112 if (r)
122 if (r) 113 goto err1;
123 goto err1; 114 mdelay(2);
124 mdelay(2);
125 }
126 115
127 dssdev->manager->enable(dssdev->manager); 116 dssdev->manager->enable(dssdev->manager);
128 117
129 sdi.skip_init = 0;
130
131 return 0; 118 return 0;
132err2: 119err2:
133 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 120 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
134 regulator_disable(sdi.vdds_sdi_reg); 121 regulator_disable(sdi.vdds_sdi_reg);
135err1: 122err1:
136 omap_dss_stop_device(dssdev); 123 omap_dss_stop_device(dssdev);
@@ -145,7 +132,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
145 132
146 dss_sdi_disable(); 133 dss_sdi_disable();
147 134
148 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 135 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
149 136
150 regulator_disable(sdi.vdds_sdi_reg); 137 regulator_disable(sdi.vdds_sdi_reg);
151 138
@@ -157,25 +144,24 @@ int sdi_init_display(struct omap_dss_device *dssdev)
157{ 144{
158 DSSDBG("SDI init\n"); 145 DSSDBG("SDI init\n");
159 146
147 if (sdi.vdds_sdi_reg == NULL) {
148 struct regulator *vdds_sdi;
149
150 vdds_sdi = dss_get_vdds_sdi();
151
152 if (IS_ERR(vdds_sdi)) {
153 DSSERR("can't get VDDS_SDI regulator\n");
154 return PTR_ERR(vdds_sdi);
155 }
156
157 sdi.vdds_sdi_reg = vdds_sdi;
158 }
159
160 return 0; 160 return 0;
161} 161}
162 162
163int sdi_init(bool skip_init) 163int sdi_init(void)
164{ 164{
165 /* we store this for first display enable, then clear it */
166 sdi.skip_init = skip_init;
167
168 sdi.vdds_sdi_reg = dss_get_vdds_sdi();
169 if (IS_ERR(sdi.vdds_sdi_reg)) {
170 DSSERR("can't get VDDS_SDI regulator\n");
171 return PTR_ERR(sdi.vdds_sdi_reg);
172 }
173 /*
174 * Enable clocks already here, otherwise there would be a toggle
175 * of them until sdi_display_enable is called.
176 */
177 if (skip_init)
178 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
179 return 0; 165 return 0;
180} 166}
181 167
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index eff35050e28a..8e35a5bae429 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -39,8 +39,6 @@
39 39
40#include "dss.h" 40#include "dss.h"
41 41
42#define VENC_BASE 0x48050C00
43
44/* Venc registers */ 42/* Venc registers */
45#define VENC_REV_ID 0x00 43#define VENC_REV_ID 0x00
46#define VENC_STATUS 0x04 44#define VENC_STATUS 0x04
@@ -289,6 +287,7 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
289EXPORT_SYMBOL(omap_dss_ntsc_timings); 287EXPORT_SYMBOL(omap_dss_ntsc_timings);
290 288
291static struct { 289static struct {
290 struct platform_device *pdev;
292 void __iomem *base; 291 void __iomem *base;
293 struct mutex venc_lock; 292 struct mutex venc_lock;
294 u32 wss_data; 293 u32 wss_data;
@@ -381,11 +380,11 @@ static void venc_reset(void)
381static void venc_enable_clocks(int enable) 380static void venc_enable_clocks(int enable)
382{ 381{
383 if (enable) 382 if (enable)
384 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 383 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
385 DSS_CLK_96M); 384 DSS_CLK_VIDFCK);
386 else 385 else
387 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 386 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
388 DSS_CLK_96M); 387 DSS_CLK_VIDFCK);
389} 388}
390 389
391static const struct venc_config *venc_timings_to_config( 390static const struct venc_config *venc_timings_to_config(
@@ -641,50 +640,23 @@ static struct omap_dss_driver venc_driver = {
641}; 640};
642/* driver end */ 641/* driver end */
643 642
644 643int venc_init_display(struct omap_dss_device *dssdev)
645
646int venc_init(struct platform_device *pdev)
647{ 644{
648 u8 rev_id; 645 DSSDBG("init_display\n");
649 646
650 mutex_init(&venc.venc_lock); 647 if (venc.vdda_dac_reg == NULL) {
648 struct regulator *vdda_dac;
651 649
652 venc.wss_data = 0; 650 vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac");
653 651
654 venc.base = ioremap(VENC_BASE, SZ_1K); 652 if (IS_ERR(vdda_dac)) {
655 if (!venc.base) { 653 DSSERR("can't get VDDA_DAC regulator\n");
656 DSSERR("can't ioremap VENC\n"); 654 return PTR_ERR(vdda_dac);
657 return -ENOMEM; 655 }
658 }
659 656
660 venc.vdda_dac_reg = dss_get_vdda_dac(); 657 venc.vdda_dac_reg = vdda_dac;
661 if (IS_ERR(venc.vdda_dac_reg)) {
662 iounmap(venc.base);
663 DSSERR("can't get VDDA_DAC regulator\n");
664 return PTR_ERR(venc.vdda_dac_reg);
665 } 658 }
666 659
667 venc_enable_clocks(1);
668
669 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
670 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
671
672 venc_enable_clocks(0);
673
674 return omap_dss_register_driver(&venc_driver);
675}
676
677void venc_exit(void)
678{
679 omap_dss_unregister_driver(&venc_driver);
680
681 iounmap(venc.base);
682}
683
684int venc_init_display(struct omap_dss_device *dssdev)
685{
686 DSSDBG("init_display\n");
687
688 return 0; 660 return 0;
689} 661}
690 662
@@ -740,3 +712,73 @@ void venc_dump_regs(struct seq_file *s)
740 712
741#undef DUMPREG 713#undef DUMPREG
742} 714}
715
716/* VENC HW IP initialisation */
717static int omap_venchw_probe(struct platform_device *pdev)
718{
719 u8 rev_id;
720 struct resource *venc_mem;
721
722 venc.pdev = pdev;
723
724 mutex_init(&venc.venc_lock);
725
726 venc.wss_data = 0;
727
728 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
729 if (!venc_mem) {
730 DSSERR("can't get IORESOURCE_MEM VENC\n");
731 return -EINVAL;
732 }
733 venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
734 if (!venc.base) {
735 DSSERR("can't ioremap VENC\n");
736 return -ENOMEM;
737 }
738
739 venc_enable_clocks(1);
740
741 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
742 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
743
744 venc_enable_clocks(0);
745
746 return omap_dss_register_driver(&venc_driver);
747}
748
749static int omap_venchw_remove(struct platform_device *pdev)
750{
751 if (venc.vdda_dac_reg != NULL) {
752 regulator_put(venc.vdda_dac_reg);
753 venc.vdda_dac_reg = NULL;
754 }
755 omap_dss_unregister_driver(&venc_driver);
756
757 iounmap(venc.base);
758 return 0;
759}
760
761static struct platform_driver omap_venchw_driver = {
762 .probe = omap_venchw_probe,
763 .remove = omap_venchw_remove,
764 .driver = {
765 .name = "omapdss_venc",
766 .owner = THIS_MODULE,
767 },
768};
769
770int venc_init_platform_driver(void)
771{
772 if (cpu_is_omap44xx())
773 return 0;
774
775 return platform_driver_register(&omap_venchw_driver);
776}
777
778void venc_uninit_platform_driver(void)
779{
780 if (cpu_is_omap44xx())
781 return;
782
783 return platform_driver_unregister(&omap_venchw_driver);
784}
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index 65149b22cf37..aa33386c81ff 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -1,5 +1,5 @@
1menuconfig FB_OMAP2 1menuconfig FB_OMAP2
2 tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)" 2 tristate "OMAP2+ frame buffer support (EXPERIMENTAL)"
3 depends on FB && OMAP2_DSS 3 depends on FB && OMAP2_DSS
4 4
5 select OMAP2_VRAM 5 select OMAP2_VRAM
@@ -8,10 +8,10 @@ menuconfig FB_OMAP2
8 select FB_CFB_COPYAREA 8 select FB_CFB_COPYAREA
9 select FB_CFB_IMAGEBLIT 9 select FB_CFB_IMAGEBLIT
10 help 10 help
11 Frame buffer driver for OMAP2/3 based boards. 11 Frame buffer driver for OMAP2+ based boards.
12 12
13config FB_OMAP2_DEBUG_SUPPORT 13config FB_OMAP2_DEBUG_SUPPORT
14 bool "Debug support for OMAP2/3 FB" 14 bool "Debug support for OMAP2+ FB"
15 default y 15 default y
16 depends on FB_OMAP2 16 depends on FB_OMAP2
17 help 17 help
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 4fdab8e9c496..505ec6672049 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2090,7 +2090,7 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2090{ 2090{
2091 int r; 2091 int r;
2092 u8 bpp; 2092 u8 bpp;
2093 struct omap_video_timings timings; 2093 struct omap_video_timings timings, temp_timings;
2094 2094
2095 r = omapfb_mode_to_timings(mode_str, &timings, &bpp); 2095 r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
2096 if (r) 2096 if (r)
@@ -2100,14 +2100,23 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2100 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; 2100 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
2101 ++fbdev->num_bpp_overrides; 2101 ++fbdev->num_bpp_overrides;
2102 2102
2103 if (!display->driver->check_timings || !display->driver->set_timings) 2103 if (display->driver->check_timings) {
2104 return -EINVAL; 2104 r = display->driver->check_timings(display, &timings);
2105 if (r)
2106 return r;
2107 } else {
2108 /* If check_timings is not present compare xres and yres */
2109 if (display->driver->get_timings) {
2110 display->driver->get_timings(display, &temp_timings);
2105 2111
2106 r = display->driver->check_timings(display, &timings); 2112 if (temp_timings.x_res != timings.x_res ||
2107 if (r) 2113 temp_timings.y_res != timings.y_res)
2108 return r; 2114 return -EINVAL;
2115 }
2116 }
2109 2117
2110 display->driver->set_timings(display, &timings); 2118 if (display->driver->set_timings)
2119 display->driver->set_timings(display, &timings);
2111 2120
2112 return 0; 2121 return 0;
2113} 2122}
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 83ce9a04d872..6817d187d46e 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -1340,6 +1340,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1340 sfb->bus_clk = clk_get(dev, "lcd"); 1340 sfb->bus_clk = clk_get(dev, "lcd");
1341 if (IS_ERR(sfb->bus_clk)) { 1341 if (IS_ERR(sfb->bus_clk)) {
1342 dev_err(dev, "failed to get bus clock\n"); 1342 dev_err(dev, "failed to get bus clock\n");
1343 ret = PTR_ERR(sfb->bus_clk);
1343 goto err_sfb; 1344 goto err_sfb;
1344 } 1345 }
1345 1346
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 75738a928610..ddedad9cd069 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -64,6 +64,8 @@ static const struct svga_fb_format s3fb_formats[] = {
64 64
65static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, 65static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
66 35000, 240000, 14318}; 66 35000, 240000, 14318};
67static const struct svga_pll s3_trio3d_pll = {3, 129, 3, 31, 0, 4,
68 230000, 460000, 14318};
67 69
68static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; 70static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
69 71
@@ -72,7 +74,8 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
72 "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge", 74 "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge",
73 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", 75 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX",
74 "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P", 76 "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P",
75 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X"}; 77 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X",
78 "S3 Trio3D"};
76 79
77#define CHIP_UNKNOWN 0x00 80#define CHIP_UNKNOWN 0x00
78#define CHIP_732_TRIO32 0x01 81#define CHIP_732_TRIO32 0x01
@@ -93,6 +96,7 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
93#define CHIP_360_TRIO3D_1X 0x10 96#define CHIP_360_TRIO3D_1X 0x10
94#define CHIP_362_TRIO3D_2X 0x11 97#define CHIP_362_TRIO3D_2X 0x11
95#define CHIP_368_TRIO3D_2X 0x12 98#define CHIP_368_TRIO3D_2X 0x12
99#define CHIP_365_TRIO3D 0x13
96 100
97#define CHIP_XXX_TRIO 0x80 101#define CHIP_XXX_TRIO 0x80
98#define CHIP_XXX_TRIO64V2_DXGX 0x81 102#define CHIP_XXX_TRIO64V2_DXGX 0x81
@@ -119,9 +123,11 @@ static const struct vga_regset s3_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07,
119static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END}; 123static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END};
120 124
121static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END}; 125static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END};
122static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END}; 126static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x69, 0, 4}, VGA_REGSET_END};
123static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ 127static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */
124 128
129static const struct vga_regset s3_dtpc_regs[] = {{0x3B, 0, 7}, {0x5D, 6, 6}, VGA_REGSET_END};
130
125static const struct svga_timing_regs s3_timing_regs = { 131static const struct svga_timing_regs s3_timing_regs = {
126 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs, 132 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs,
127 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs, 133 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs,
@@ -188,12 +194,19 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
188 } 194 }
189} 195}
190 196
197static void s3fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
198{
199 struct s3fb_info *par = info->par;
200
201 svga_tilecursor(par->state.vgabase, info, cursor);
202}
203
191static struct fb_tile_ops s3fb_tile_ops = { 204static struct fb_tile_ops s3fb_tile_ops = {
192 .fb_settile = svga_settile, 205 .fb_settile = svga_settile,
193 .fb_tilecopy = svga_tilecopy, 206 .fb_tilecopy = svga_tilecopy,
194 .fb_tilefill = svga_tilefill, 207 .fb_tilefill = svga_tilefill,
195 .fb_tileblit = svga_tileblit, 208 .fb_tileblit = svga_tileblit,
196 .fb_tilecursor = svga_tilecursor, 209 .fb_tilecursor = s3fb_tilecursor,
197 .fb_get_tilemax = svga_get_tilemax, 210 .fb_get_tilemax = svga_get_tilemax,
198}; 211};
199 212
@@ -202,7 +215,7 @@ static struct fb_tile_ops s3fb_fast_tile_ops = {
202 .fb_tilecopy = svga_tilecopy, 215 .fb_tilecopy = svga_tilecopy,
203 .fb_tilefill = svga_tilefill, 216 .fb_tilefill = svga_tilefill,
204 .fb_tileblit = svga_tileblit, 217 .fb_tileblit = svga_tileblit,
205 .fb_tilecursor = svga_tilecursor, 218 .fb_tilecursor = s3fb_tilecursor,
206 .fb_get_tilemax = svga_get_tilemax, 219 .fb_get_tilemax = svga_get_tilemax,
207}; 220};
208 221
@@ -334,33 +347,34 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
334 u8 regval; 347 u8 regval;
335 int rv; 348 int rv;
336 349
337 rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node); 350 rv = svga_compute_pll((par->chip == CHIP_365_TRIO3D) ? &s3_trio3d_pll : &s3_pll,
351 1000000000 / pixclock, &m, &n, &r, info->node);
338 if (rv < 0) { 352 if (rv < 0) {
339 printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); 353 printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
340 return; 354 return;
341 } 355 }
342 356
343 /* Set VGA misc register */ 357 /* Set VGA misc register */
344 regval = vga_r(NULL, VGA_MIS_R); 358 regval = vga_r(par->state.vgabase, VGA_MIS_R);
345 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 359 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
346 360
347 /* Set S3 clock registers */ 361 /* Set S3 clock registers */
348 if (par->chip == CHIP_360_TRIO3D_1X || 362 if (par->chip == CHIP_360_TRIO3D_1X ||
349 par->chip == CHIP_362_TRIO3D_2X || 363 par->chip == CHIP_362_TRIO3D_2X ||
350 par->chip == CHIP_368_TRIO3D_2X) { 364 par->chip == CHIP_368_TRIO3D_2X) {
351 vga_wseq(NULL, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ 365 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */
352 vga_wseq(NULL, 0x29, r >> 2); /* remaining highest bit of r */ 366 vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */
353 } else 367 } else
354 vga_wseq(NULL, 0x12, (n - 2) | (r << 5)); 368 vga_wseq(par->state.vgabase, 0x12, (n - 2) | (r << 5));
355 vga_wseq(NULL, 0x13, m - 2); 369 vga_wseq(par->state.vgabase, 0x13, m - 2);
356 370
357 udelay(1000); 371 udelay(1000);
358 372
359 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */ 373 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */
360 regval = vga_rseq (NULL, 0x15); /* | 0x80; */ 374 regval = vga_rseq (par->state.vgabase, 0x15); /* | 0x80; */
361 vga_wseq(NULL, 0x15, regval & ~(1<<5)); 375 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
362 vga_wseq(NULL, 0x15, regval | (1<<5)); 376 vga_wseq(par->state.vgabase, 0x15, regval | (1<<5));
363 vga_wseq(NULL, 0x15, regval & ~(1<<5)); 377 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
364} 378}
365 379
366 380
@@ -372,7 +386,10 @@ static int s3fb_open(struct fb_info *info, int user)
372 386
373 mutex_lock(&(par->open_lock)); 387 mutex_lock(&(par->open_lock));
374 if (par->ref_count == 0) { 388 if (par->ref_count == 0) {
389 void __iomem *vgabase = par->state.vgabase;
390
375 memset(&(par->state), 0, sizeof(struct vgastate)); 391 memset(&(par->state), 0, sizeof(struct vgastate));
392 par->state.vgabase = vgabase;
376 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 393 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
377 par->state.num_crtc = 0x70; 394 par->state.num_crtc = 0x70;
378 par->state.num_seq = 0x20; 395 par->state.num_seq = 0x20;
@@ -470,6 +487,7 @@ static int s3fb_set_par(struct fb_info *info)
470 struct s3fb_info *par = info->par; 487 struct s3fb_info *par = info->par;
471 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; 488 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes;
472 u32 bpp = info->var.bits_per_pixel; 489 u32 bpp = info->var.bits_per_pixel;
490 u32 htotal, hsstart;
473 491
474 if (bpp != 0) { 492 if (bpp != 0) {
475 info->fix.ypanstep = 1; 493 info->fix.ypanstep = 1;
@@ -504,99 +522,112 @@ static int s3fb_set_par(struct fb_info *info)
504 info->var.activate = FB_ACTIVATE_NOW; 522 info->var.activate = FB_ACTIVATE_NOW;
505 523
506 /* Unlock registers */ 524 /* Unlock registers */
507 vga_wcrt(NULL, 0x38, 0x48); 525 vga_wcrt(par->state.vgabase, 0x38, 0x48);
508 vga_wcrt(NULL, 0x39, 0xA5); 526 vga_wcrt(par->state.vgabase, 0x39, 0xA5);
509 vga_wseq(NULL, 0x08, 0x06); 527 vga_wseq(par->state.vgabase, 0x08, 0x06);
510 svga_wcrt_mask(0x11, 0x00, 0x80); 528 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
511 529
512 /* Blank screen and turn off sync */ 530 /* Blank screen and turn off sync */
513 svga_wseq_mask(0x01, 0x20, 0x20); 531 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
514 svga_wcrt_mask(0x17, 0x00, 0x80); 532 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
515 533
516 /* Set default values */ 534 /* Set default values */
517 svga_set_default_gfx_regs(); 535 svga_set_default_gfx_regs(par->state.vgabase);
518 svga_set_default_atc_regs(); 536 svga_set_default_atc_regs(par->state.vgabase);
519 svga_set_default_seq_regs(); 537 svga_set_default_seq_regs(par->state.vgabase);
520 svga_set_default_crt_regs(); 538 svga_set_default_crt_regs(par->state.vgabase);
521 svga_wcrt_multi(s3_line_compare_regs, 0xFFFFFFFF); 539 svga_wcrt_multi(par->state.vgabase, s3_line_compare_regs, 0xFFFFFFFF);
522 svga_wcrt_multi(s3_start_address_regs, 0); 540 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, 0);
523 541
524 /* S3 specific initialization */ 542 /* S3 specific initialization */
525 svga_wcrt_mask(0x58, 0x10, 0x10); /* enable linear framebuffer */ 543 svga_wcrt_mask(par->state.vgabase, 0x58, 0x10, 0x10); /* enable linear framebuffer */
526 svga_wcrt_mask(0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */ 544 svga_wcrt_mask(par->state.vgabase, 0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */
527 545
528/* svga_wcrt_mask(0x33, 0x08, 0x08); */ /* DDR ? */ 546/* svga_wcrt_mask(par->state.vgabase, 0x33, 0x08, 0x08); */ /* DDR ? */
529/* svga_wcrt_mask(0x43, 0x01, 0x01); */ /* DDR ? */ 547/* svga_wcrt_mask(par->state.vgabase, 0x43, 0x01, 0x01); */ /* DDR ? */
530 svga_wcrt_mask(0x33, 0x00, 0x08); /* no DDR ? */ 548 svga_wcrt_mask(par->state.vgabase, 0x33, 0x00, 0x08); /* no DDR ? */
531 svga_wcrt_mask(0x43, 0x00, 0x01); /* no DDR ? */ 549 svga_wcrt_mask(par->state.vgabase, 0x43, 0x00, 0x01); /* no DDR ? */
532 550
533 svga_wcrt_mask(0x5D, 0x00, 0x28); /* Clear strange HSlen bits */ 551 svga_wcrt_mask(par->state.vgabase, 0x5D, 0x00, 0x28); /* Clear strange HSlen bits */
534 552
535/* svga_wcrt_mask(0x58, 0x03, 0x03); */ 553/* svga_wcrt_mask(par->state.vgabase, 0x58, 0x03, 0x03); */
536 554
537/* svga_wcrt_mask(0x53, 0x12, 0x13); */ /* enable MMIO */ 555/* svga_wcrt_mask(par->state.vgabase, 0x53, 0x12, 0x13); */ /* enable MMIO */
538/* svga_wcrt_mask(0x40, 0x08, 0x08); */ /* enable write buffer */ 556/* svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08); */ /* enable write buffer */
539 557
540 558
541 /* Set the offset register */ 559 /* Set the offset register */
542 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 560 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
543 svga_wcrt_multi(s3_offset_regs, offset_value); 561 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value);
544 562
545 if (par->chip != CHIP_360_TRIO3D_1X && 563 if (par->chip != CHIP_360_TRIO3D_1X &&
546 par->chip != CHIP_362_TRIO3D_2X && 564 par->chip != CHIP_362_TRIO3D_2X &&
547 par->chip != CHIP_368_TRIO3D_2X) { 565 par->chip != CHIP_368_TRIO3D_2X) {
548 vga_wcrt(NULL, 0x54, 0x18); /* M parameter */ 566 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */
549 vga_wcrt(NULL, 0x60, 0xff); /* N parameter */ 567 vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */
550 vga_wcrt(NULL, 0x61, 0xff); /* L parameter */ 568 vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */
551 vga_wcrt(NULL, 0x62, 0xff); /* L parameter */ 569 vga_wcrt(par->state.vgabase, 0x62, 0xff); /* L parameter */
552 } 570 }
553 571
554 vga_wcrt(NULL, 0x3A, 0x35); 572 vga_wcrt(par->state.vgabase, 0x3A, 0x35);
555 svga_wattr(0x33, 0x00); 573 svga_wattr(par->state.vgabase, 0x33, 0x00);
556 574
557 if (info->var.vmode & FB_VMODE_DOUBLE) 575 if (info->var.vmode & FB_VMODE_DOUBLE)
558 svga_wcrt_mask(0x09, 0x80, 0x80); 576 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
559 else 577 else
560 svga_wcrt_mask(0x09, 0x00, 0x80); 578 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
561 579
562 if (info->var.vmode & FB_VMODE_INTERLACED) 580 if (info->var.vmode & FB_VMODE_INTERLACED)
563 svga_wcrt_mask(0x42, 0x20, 0x20); 581 svga_wcrt_mask(par->state.vgabase, 0x42, 0x20, 0x20);
564 else 582 else
565 svga_wcrt_mask(0x42, 0x00, 0x20); 583 svga_wcrt_mask(par->state.vgabase, 0x42, 0x00, 0x20);
566 584
567 /* Disable hardware graphics cursor */ 585 /* Disable hardware graphics cursor */
568 svga_wcrt_mask(0x45, 0x00, 0x01); 586 svga_wcrt_mask(par->state.vgabase, 0x45, 0x00, 0x01);
569 /* Disable Streams engine */ 587 /* Disable Streams engine */
570 svga_wcrt_mask(0x67, 0x00, 0x0C); 588 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0x0C);
571 589
572 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix)); 590 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix));
573 591
574 /* S3 virge DX hack */ 592 /* S3 virge DX hack */
575 if (par->chip == CHIP_375_VIRGE_DX) { 593 if (par->chip == CHIP_375_VIRGE_DX) {
576 vga_wcrt(NULL, 0x86, 0x80); 594 vga_wcrt(par->state.vgabase, 0x86, 0x80);
577 vga_wcrt(NULL, 0x90, 0x00); 595 vga_wcrt(par->state.vgabase, 0x90, 0x00);
578 } 596 }
579 597
580 /* S3 virge VX hack */ 598 /* S3 virge VX hack */
581 if (par->chip == CHIP_988_VIRGE_VX) { 599 if (par->chip == CHIP_988_VIRGE_VX) {
582 vga_wcrt(NULL, 0x50, 0x00); 600 vga_wcrt(par->state.vgabase, 0x50, 0x00);
583 vga_wcrt(NULL, 0x67, 0x50); 601 vga_wcrt(par->state.vgabase, 0x67, 0x50);
584 602
585 vga_wcrt(NULL, 0x63, (mode <= 2) ? 0x90 : 0x09); 603 vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
586 vga_wcrt(NULL, 0x66, 0x90); 604 vga_wcrt(par->state.vgabase, 0x66, 0x90);
587 } 605 }
588 606
589 if (par->chip == CHIP_360_TRIO3D_1X || 607 if (par->chip == CHIP_360_TRIO3D_1X ||
590 par->chip == CHIP_362_TRIO3D_2X || 608 par->chip == CHIP_362_TRIO3D_2X ||
591 par->chip == CHIP_368_TRIO3D_2X) { 609 par->chip == CHIP_368_TRIO3D_2X ||
610 par->chip == CHIP_365_TRIO3D ||
611 par->chip == CHIP_375_VIRGE_DX ||
612 par->chip == CHIP_385_VIRGE_GX) {
592 dbytes = info->var.xres * ((bpp+7)/8); 613 dbytes = info->var.xres * ((bpp+7)/8);
593 vga_wcrt(NULL, 0x91, (dbytes + 7) / 8); 614 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8);
594 vga_wcrt(NULL, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); 615 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80);
595 616
596 vga_wcrt(NULL, 0x66, 0x81); 617 vga_wcrt(par->state.vgabase, 0x66, 0x81);
597 } 618 }
598 619
599 svga_wcrt_mask(0x31, 0x00, 0x40); 620 if (par->chip == CHIP_356_VIRGE_GX2 ||
621 par->chip == CHIP_357_VIRGE_GX2P ||
622 par->chip == CHIP_359_VIRGE_GX2P ||
623 par->chip == CHIP_360_TRIO3D_1X ||
624 par->chip == CHIP_362_TRIO3D_2X ||
625 par->chip == CHIP_368_TRIO3D_2X)
626 vga_wcrt(par->state.vgabase, 0x34, 0x00);
627 else /* enable Data Transfer Position Control (DTPC) */
628 vga_wcrt(par->state.vgabase, 0x34, 0x10);
629
630 svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40);
600 multiplex = 0; 631 multiplex = 0;
601 hmul = 1; 632 hmul = 1;
602 633
@@ -604,51 +635,51 @@ static int s3fb_set_par(struct fb_info *info)
604 switch (mode) { 635 switch (mode) {
605 case 0: 636 case 0:
606 pr_debug("fb%d: text mode\n", info->node); 637 pr_debug("fb%d: text mode\n", info->node);
607 svga_set_textmode_vga_regs(); 638 svga_set_textmode_vga_regs(par->state.vgabase);
608 639
609 /* Set additional registers like in 8-bit mode */ 640 /* Set additional registers like in 8-bit mode */
610 svga_wcrt_mask(0x50, 0x00, 0x30); 641 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
611 svga_wcrt_mask(0x67, 0x00, 0xF0); 642 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
612 643
613 /* Disable enhanced mode */ 644 /* Disable enhanced mode */
614 svga_wcrt_mask(0x3A, 0x00, 0x30); 645 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
615 646
616 if (fasttext) { 647 if (fasttext) {
617 pr_debug("fb%d: high speed text mode set\n", info->node); 648 pr_debug("fb%d: high speed text mode set\n", info->node);
618 svga_wcrt_mask(0x31, 0x40, 0x40); 649 svga_wcrt_mask(par->state.vgabase, 0x31, 0x40, 0x40);
619 } 650 }
620 break; 651 break;
621 case 1: 652 case 1:
622 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 653 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
623 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 654 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
624 655
625 /* Set additional registers like in 8-bit mode */ 656 /* Set additional registers like in 8-bit mode */
626 svga_wcrt_mask(0x50, 0x00, 0x30); 657 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
627 svga_wcrt_mask(0x67, 0x00, 0xF0); 658 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
628 659
629 /* disable enhanced mode */ 660 /* disable enhanced mode */
630 svga_wcrt_mask(0x3A, 0x00, 0x30); 661 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
631 break; 662 break;
632 case 2: 663 case 2:
633 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 664 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
634 665
635 /* Set additional registers like in 8-bit mode */ 666 /* Set additional registers like in 8-bit mode */
636 svga_wcrt_mask(0x50, 0x00, 0x30); 667 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
637 svga_wcrt_mask(0x67, 0x00, 0xF0); 668 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
638 669
639 /* disable enhanced mode */ 670 /* disable enhanced mode */
640 svga_wcrt_mask(0x3A, 0x00, 0x30); 671 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
641 break; 672 break;
642 case 3: 673 case 3:
643 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 674 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
644 svga_wcrt_mask(0x50, 0x00, 0x30); 675 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
645 if (info->var.pixclock > 20000 || 676 if (info->var.pixclock > 20000 ||
646 par->chip == CHIP_360_TRIO3D_1X || 677 par->chip == CHIP_360_TRIO3D_1X ||
647 par->chip == CHIP_362_TRIO3D_2X || 678 par->chip == CHIP_362_TRIO3D_2X ||
648 par->chip == CHIP_368_TRIO3D_2X) 679 par->chip == CHIP_368_TRIO3D_2X)
649 svga_wcrt_mask(0x67, 0x00, 0xF0); 680 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
650 else { 681 else {
651 svga_wcrt_mask(0x67, 0x10, 0xF0); 682 svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0);
652 multiplex = 1; 683 multiplex = 1;
653 } 684 }
654 break; 685 break;
@@ -656,12 +687,21 @@ static int s3fb_set_par(struct fb_info *info)
656 pr_debug("fb%d: 5/5/5 truecolor\n", info->node); 687 pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
657 if (par->chip == CHIP_988_VIRGE_VX) { 688 if (par->chip == CHIP_988_VIRGE_VX) {
658 if (info->var.pixclock > 20000) 689 if (info->var.pixclock > 20000)
659 svga_wcrt_mask(0x67, 0x20, 0xF0); 690 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
660 else 691 else
661 svga_wcrt_mask(0x67, 0x30, 0xF0); 692 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
693 } else if (par->chip == CHIP_365_TRIO3D) {
694 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
695 if (info->var.pixclock > 8695) {
696 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
697 hmul = 2;
698 } else {
699 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
700 multiplex = 1;
701 }
662 } else { 702 } else {
663 svga_wcrt_mask(0x50, 0x10, 0x30); 703 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
664 svga_wcrt_mask(0x67, 0x30, 0xF0); 704 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
665 if (par->chip != CHIP_360_TRIO3D_1X && 705 if (par->chip != CHIP_360_TRIO3D_1X &&
666 par->chip != CHIP_362_TRIO3D_2X && 706 par->chip != CHIP_362_TRIO3D_2X &&
667 par->chip != CHIP_368_TRIO3D_2X) 707 par->chip != CHIP_368_TRIO3D_2X)
@@ -672,12 +712,21 @@ static int s3fb_set_par(struct fb_info *info)
672 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 712 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
673 if (par->chip == CHIP_988_VIRGE_VX) { 713 if (par->chip == CHIP_988_VIRGE_VX) {
674 if (info->var.pixclock > 20000) 714 if (info->var.pixclock > 20000)
675 svga_wcrt_mask(0x67, 0x40, 0xF0); 715 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
676 else 716 else
677 svga_wcrt_mask(0x67, 0x50, 0xF0); 717 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
718 } else if (par->chip == CHIP_365_TRIO3D) {
719 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
720 if (info->var.pixclock > 8695) {
721 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
722 hmul = 2;
723 } else {
724 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
725 multiplex = 1;
726 }
678 } else { 727 } else {
679 svga_wcrt_mask(0x50, 0x10, 0x30); 728 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
680 svga_wcrt_mask(0x67, 0x50, 0xF0); 729 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
681 if (par->chip != CHIP_360_TRIO3D_1X && 730 if (par->chip != CHIP_360_TRIO3D_1X &&
682 par->chip != CHIP_362_TRIO3D_2X && 731 par->chip != CHIP_362_TRIO3D_2X &&
683 par->chip != CHIP_368_TRIO3D_2X) 732 par->chip != CHIP_368_TRIO3D_2X)
@@ -687,12 +736,12 @@ static int s3fb_set_par(struct fb_info *info)
687 case 6: 736 case 6:
688 /* VIRGE VX case */ 737 /* VIRGE VX case */
689 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 738 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
690 svga_wcrt_mask(0x67, 0xD0, 0xF0); 739 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
691 break; 740 break;
692 case 7: 741 case 7:
693 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); 742 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
694 svga_wcrt_mask(0x50, 0x30, 0x30); 743 svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30);
695 svga_wcrt_mask(0x67, 0xD0, 0xF0); 744 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
696 break; 745 break;
697 default: 746 default:
698 printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node); 747 printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node);
@@ -700,25 +749,30 @@ static int s3fb_set_par(struct fb_info *info)
700 } 749 }
701 750
702 if (par->chip != CHIP_988_VIRGE_VX) { 751 if (par->chip != CHIP_988_VIRGE_VX) {
703 svga_wseq_mask(0x15, multiplex ? 0x10 : 0x00, 0x10); 752 svga_wseq_mask(par->state.vgabase, 0x15, multiplex ? 0x10 : 0x00, 0x10);
704 svga_wseq_mask(0x18, multiplex ? 0x80 : 0x00, 0x80); 753 svga_wseq_mask(par->state.vgabase, 0x18, multiplex ? 0x80 : 0x00, 0x80);
705 } 754 }
706 755
707 s3_set_pixclock(info, info->var.pixclock); 756 s3_set_pixclock(info, info->var.pixclock);
708 svga_set_timings(&s3_timing_regs, &(info->var), hmul, 1, 757 svga_set_timings(par->state.vgabase, &s3_timing_regs, &(info->var), hmul, 1,
709 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 758 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
710 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, 759 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
711 hmul, info->node); 760 hmul, info->node);
712 761
713 /* Set interlaced mode start/end register */ 762 /* Set interlaced mode start/end register */
714 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 763 htotal = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
715 value = ((value * hmul) / 8) - 5; 764 htotal = ((htotal * hmul) / 8) - 5;
716 vga_wcrt(NULL, 0x3C, (value + 1) / 2); 765 vga_wcrt(par->state.vgabase, 0x3C, (htotal + 1) / 2);
766
767 /* Set Data Transfer Position */
768 hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8;
769 value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1);
770 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
717 771
718 memset_io(info->screen_base, 0x00, screen_size); 772 memset_io(info->screen_base, 0x00, screen_size);
719 /* Device and screen back on */ 773 /* Device and screen back on */
720 svga_wcrt_mask(0x17, 0x80, 0x80); 774 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
721 svga_wseq_mask(0x01, 0x00, 0x20); 775 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
722 776
723 return 0; 777 return 0;
724} 778}
@@ -788,31 +842,33 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
788 842
789static int s3fb_blank(int blank_mode, struct fb_info *info) 843static int s3fb_blank(int blank_mode, struct fb_info *info)
790{ 844{
845 struct s3fb_info *par = info->par;
846
791 switch (blank_mode) { 847 switch (blank_mode) {
792 case FB_BLANK_UNBLANK: 848 case FB_BLANK_UNBLANK:
793 pr_debug("fb%d: unblank\n", info->node); 849 pr_debug("fb%d: unblank\n", info->node);
794 svga_wcrt_mask(0x56, 0x00, 0x06); 850 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
795 svga_wseq_mask(0x01, 0x00, 0x20); 851 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
796 break; 852 break;
797 case FB_BLANK_NORMAL: 853 case FB_BLANK_NORMAL:
798 pr_debug("fb%d: blank\n", info->node); 854 pr_debug("fb%d: blank\n", info->node);
799 svga_wcrt_mask(0x56, 0x00, 0x06); 855 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
800 svga_wseq_mask(0x01, 0x20, 0x20); 856 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
801 break; 857 break;
802 case FB_BLANK_HSYNC_SUSPEND: 858 case FB_BLANK_HSYNC_SUSPEND:
803 pr_debug("fb%d: hsync\n", info->node); 859 pr_debug("fb%d: hsync\n", info->node);
804 svga_wcrt_mask(0x56, 0x02, 0x06); 860 svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06);
805 svga_wseq_mask(0x01, 0x20, 0x20); 861 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
806 break; 862 break;
807 case FB_BLANK_VSYNC_SUSPEND: 863 case FB_BLANK_VSYNC_SUSPEND:
808 pr_debug("fb%d: vsync\n", info->node); 864 pr_debug("fb%d: vsync\n", info->node);
809 svga_wcrt_mask(0x56, 0x04, 0x06); 865 svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06);
810 svga_wseq_mask(0x01, 0x20, 0x20); 866 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
811 break; 867 break;
812 case FB_BLANK_POWERDOWN: 868 case FB_BLANK_POWERDOWN:
813 pr_debug("fb%d: sync down\n", info->node); 869 pr_debug("fb%d: sync down\n", info->node);
814 svga_wcrt_mask(0x56, 0x06, 0x06); 870 svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06);
815 svga_wseq_mask(0x01, 0x20, 0x20); 871 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
816 break; 872 break;
817 } 873 }
818 874
@@ -822,8 +878,9 @@ static int s3fb_blank(int blank_mode, struct fb_info *info)
822 878
823/* Pan the display */ 879/* Pan the display */
824 880
825static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { 881static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
826 882{
883 struct s3fb_info *par = info->par;
827 unsigned int offset; 884 unsigned int offset;
828 885
829 /* Calculate the offset */ 886 /* Calculate the offset */
@@ -837,7 +894,7 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
837 } 894 }
838 895
839 /* Set the offset */ 896 /* Set the offset */
840 svga_wcrt_multi(s3_start_address_regs, offset); 897 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, offset);
841 898
842 return 0; 899 return 0;
843} 900}
@@ -863,12 +920,14 @@ static struct fb_ops s3fb_ops = {
863 920
864/* ------------------------------------------------------------------------- */ 921/* ------------------------------------------------------------------------- */
865 922
866static int __devinit s3_identification(int chip) 923static int __devinit s3_identification(struct s3fb_info *par)
867{ 924{
925 int chip = par->chip;
926
868 if (chip == CHIP_XXX_TRIO) { 927 if (chip == CHIP_XXX_TRIO) {
869 u8 cr30 = vga_rcrt(NULL, 0x30); 928 u8 cr30 = vga_rcrt(par->state.vgabase, 0x30);
870 u8 cr2e = vga_rcrt(NULL, 0x2e); 929 u8 cr2e = vga_rcrt(par->state.vgabase, 0x2e);
871 u8 cr2f = vga_rcrt(NULL, 0x2f); 930 u8 cr2f = vga_rcrt(par->state.vgabase, 0x2f);
872 931
873 if ((cr30 == 0xE0) || (cr30 == 0xE1)) { 932 if ((cr30 == 0xE0) || (cr30 == 0xE1)) {
874 if (cr2e == 0x10) 933 if (cr2e == 0x10)
@@ -883,7 +942,7 @@ static int __devinit s3_identification(int chip)
883 } 942 }
884 943
885 if (chip == CHIP_XXX_TRIO64V2_DXGX) { 944 if (chip == CHIP_XXX_TRIO64V2_DXGX) {
886 u8 cr6f = vga_rcrt(NULL, 0x6f); 945 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
887 946
888 if (! (cr6f & 0x01)) 947 if (! (cr6f & 0x01))
889 return CHIP_775_TRIO64V2_DX; 948 return CHIP_775_TRIO64V2_DX;
@@ -892,7 +951,7 @@ static int __devinit s3_identification(int chip)
892 } 951 }
893 952
894 if (chip == CHIP_XXX_VIRGE_DXGX) { 953 if (chip == CHIP_XXX_VIRGE_DXGX) {
895 u8 cr6f = vga_rcrt(NULL, 0x6f); 954 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
896 955
897 if (! (cr6f & 0x01)) 956 if (! (cr6f & 0x01))
898 return CHIP_375_VIRGE_DX; 957 return CHIP_375_VIRGE_DX;
@@ -901,7 +960,7 @@ static int __devinit s3_identification(int chip)
901 } 960 }
902 961
903 if (chip == CHIP_36X_TRIO3D_1X_2X) { 962 if (chip == CHIP_36X_TRIO3D_1X_2X) {
904 switch (vga_rcrt(NULL, 0x2f)) { 963 switch (vga_rcrt(par->state.vgabase, 0x2f)) {
905 case 0x00: 964 case 0x00:
906 return CHIP_360_TRIO3D_1X; 965 return CHIP_360_TRIO3D_1X;
907 case 0x01: 966 case 0x01:
@@ -919,6 +978,8 @@ static int __devinit s3_identification(int chip)
919 978
920static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 979static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
921{ 980{
981 struct pci_bus_region bus_reg;
982 struct resource vga_res;
922 struct fb_info *info; 983 struct fb_info *info;
923 struct s3fb_info *par; 984 struct s3fb_info *par;
924 int rc; 985 int rc;
@@ -968,31 +1029,42 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
968 goto err_iomap; 1029 goto err_iomap;
969 } 1030 }
970 1031
1032 bus_reg.start = 0;
1033 bus_reg.end = 64 * 1024;
1034
1035 vga_res.flags = IORESOURCE_IO;
1036
1037 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
1038
1039 par->state.vgabase = (void __iomem *) vga_res.start;
1040
971 /* Unlock regs */ 1041 /* Unlock regs */
972 cr38 = vga_rcrt(NULL, 0x38); 1042 cr38 = vga_rcrt(par->state.vgabase, 0x38);
973 cr39 = vga_rcrt(NULL, 0x39); 1043 cr39 = vga_rcrt(par->state.vgabase, 0x39);
974 vga_wseq(NULL, 0x08, 0x06); 1044 vga_wseq(par->state.vgabase, 0x08, 0x06);
975 vga_wcrt(NULL, 0x38, 0x48); 1045 vga_wcrt(par->state.vgabase, 0x38, 0x48);
976 vga_wcrt(NULL, 0x39, 0xA5); 1046 vga_wcrt(par->state.vgabase, 0x39, 0xA5);
977 1047
978 /* Identify chip type */ 1048 /* Identify chip type */
979 par->chip = id->driver_data & CHIP_MASK; 1049 par->chip = id->driver_data & CHIP_MASK;
980 par->rev = vga_rcrt(NULL, 0x2f); 1050 par->rev = vga_rcrt(par->state.vgabase, 0x2f);
981 if (par->chip & CHIP_UNDECIDED_FLAG) 1051 if (par->chip & CHIP_UNDECIDED_FLAG)
982 par->chip = s3_identification(par->chip); 1052 par->chip = s3_identification(par);
983 1053
984 /* Find how many physical memory there is on card */ 1054 /* Find how many physical memory there is on card */
985 /* 0x36 register is accessible even if other registers are locked */ 1055 /* 0x36 register is accessible even if other registers are locked */
986 regval = vga_rcrt(NULL, 0x36); 1056 regval = vga_rcrt(par->state.vgabase, 0x36);
987 if (par->chip == CHIP_360_TRIO3D_1X || 1057 if (par->chip == CHIP_360_TRIO3D_1X ||
988 par->chip == CHIP_362_TRIO3D_2X || 1058 par->chip == CHIP_362_TRIO3D_2X ||
989 par->chip == CHIP_368_TRIO3D_2X) { 1059 par->chip == CHIP_368_TRIO3D_2X ||
1060 par->chip == CHIP_365_TRIO3D) {
990 switch ((regval & 0xE0) >> 5) { 1061 switch ((regval & 0xE0) >> 5) {
991 case 0: /* 8MB -- only 4MB usable for display */ 1062 case 0: /* 8MB -- only 4MB usable for display */
992 case 1: /* 4MB with 32-bit bus */ 1063 case 1: /* 4MB with 32-bit bus */
993 case 2: /* 4MB */ 1064 case 2: /* 4MB */
994 info->screen_size = 4 << 20; 1065 info->screen_size = 4 << 20;
995 break; 1066 break;
1067 case 4: /* 2MB on 365 Trio3D */
996 case 6: /* 2MB */ 1068 case 6: /* 2MB */
997 info->screen_size = 2 << 20; 1069 info->screen_size = 2 << 20;
998 break; 1070 break;
@@ -1002,13 +1074,13 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1002 info->fix.smem_len = info->screen_size; 1074 info->fix.smem_len = info->screen_size;
1003 1075
1004 /* Find MCLK frequency */ 1076 /* Find MCLK frequency */
1005 regval = vga_rseq(NULL, 0x10); 1077 regval = vga_rseq(par->state.vgabase, 0x10);
1006 par->mclk_freq = ((vga_rseq(NULL, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2); 1078 par->mclk_freq = ((vga_rseq(par->state.vgabase, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2);
1007 par->mclk_freq = par->mclk_freq >> (regval >> 5); 1079 par->mclk_freq = par->mclk_freq >> (regval >> 5);
1008 1080
1009 /* Restore locks */ 1081 /* Restore locks */
1010 vga_wcrt(NULL, 0x38, cr38); 1082 vga_wcrt(par->state.vgabase, 0x38, cr38);
1011 vga_wcrt(NULL, 0x39, cr39); 1083 vga_wcrt(par->state.vgabase, 0x39, cr39);
1012 1084
1013 strcpy(info->fix.id, s3_names [par->chip]); 1085 strcpy(info->fix.id, s3_names [par->chip]);
1014 info->fix.mmio_start = 0; 1086 info->fix.mmio_start = 0;
@@ -1027,6 +1099,14 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1027 goto err_find_mode; 1099 goto err_find_mode;
1028 } 1100 }
1029 1101
1102 /* maximize virtual vertical size for fast scrolling */
1103 info->var.yres_virtual = info->fix.smem_len * 8 /
1104 (info->var.bits_per_pixel * info->var.xres_virtual);
1105 if (info->var.yres_virtual < info->var.yres) {
1106 dev_err(info->device, "virtual vertical size smaller than real\n");
1107 goto err_find_mode;
1108 }
1109
1030 rc = fb_alloc_cmap(&info->cmap, 256, 0); 1110 rc = fb_alloc_cmap(&info->cmap, 256, 0);
1031 if (rc < 0) { 1111 if (rc < 0) {
1032 dev_err(info->device, "cannot allocate colormap\n"); 1112 dev_err(info->device, "cannot allocate colormap\n");
@@ -1044,8 +1124,8 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1044 1124
1045 if (par->chip == CHIP_UNKNOWN) 1125 if (par->chip == CHIP_UNKNOWN)
1046 printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n", 1126 printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n",
1047 info->node, vga_rcrt(NULL, 0x2d), vga_rcrt(NULL, 0x2e), 1127 info->node, vga_rcrt(par->state.vgabase, 0x2d), vga_rcrt(par->state.vgabase, 0x2e),
1048 vga_rcrt(NULL, 0x2f), vga_rcrt(NULL, 0x30)); 1128 vga_rcrt(par->state.vgabase, 0x2f), vga_rcrt(par->state.vgabase, 0x30));
1049 1129
1050 /* Record a reference to the driver data */ 1130 /* Record a reference to the driver data */
1051 pci_set_drvdata(dev, info); 1131 pci_set_drvdata(dev, info);
@@ -1192,6 +1272,7 @@ static struct pci_device_id s3_devices[] __devinitdata = {
1192 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P}, 1272 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P},
1193 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, 1273 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
1194 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, 1274 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X},
1275 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D},
1195 1276
1196 {0, 0, 0, 0, 0, 0, 0} 1277 {0, 0, 0, 0, 0, 0, 0}
1197}; 1278};
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index bea38fce2470..8fe19582c460 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -459,14 +459,14 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev)
459 } 459 }
460 460
461 par->ioarea = request_mem_region(res->start, 461 par->ioarea = request_mem_region(res->start,
462 (res->end - res->start), pdev->name); 462 resource_size(res), pdev->name);
463 if (!par->ioarea) { 463 if (!par->ioarea) {
464 dev_err(&pdev->dev, "mmio area busy\n"); 464 dev_err(&pdev->dev, "mmio area busy\n");
465 ret = -EBUSY; 465 ret = -EBUSY;
466 goto out_fb; 466 goto out_fb;
467 } 467 }
468 468
469 par->base = ioremap_nocache(res->start, res->end - res->start + 1); 469 par->base = ioremap_nocache(res->start, resource_size(res));
470 if (!par->base) { 470 if (!par->base) {
471 dev_err(&pdev->dev, "cannot remap\n"); 471 dev_err(&pdev->dev, "cannot remap\n");
472 ret = -ENODEV; 472 ret = -ENODEV;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index bf2629f83f40..757665bc500f 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1088,8 +1088,9 @@ static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
1088 1088
1089 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch, 1089 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch,
1090 &sh_mobile_lcdc_bl_ops, NULL); 1090 &sh_mobile_lcdc_bl_ops, NULL);
1091 if (!bl) { 1091 if (IS_ERR(bl)) {
1092 dev_err(parent, "unable to register backlight device\n"); 1092 dev_err(parent, "unable to register backlight device: %ld\n",
1093 PTR_ERR(bl));
1093 return NULL; 1094 return NULL;
1094 } 1095 }
1095 1096
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index eac7a01925f3..1987f1b7212f 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -495,6 +495,7 @@ struct sis_video_info {
495 unsigned int refresh_rate; 495 unsigned int refresh_rate;
496 496
497 unsigned int chip; 497 unsigned int chip;
498 unsigned int chip_real_id;
498 u8 revision_id; 499 u8 revision_id;
499 int sisvga_enabled; /* PCI device was enabled */ 500 int sisvga_enabled; /* PCI device was enabled */
500 501
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2fb8c5a660fb..75259845933d 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4563,6 +4563,11 @@ sisfb_post_sis315330(struct pci_dev *pdev)
4563} 4563}
4564#endif 4564#endif
4565 4565
4566static inline int sisfb_xgi_is21(struct sis_video_info *ivideo)
4567{
4568 return ivideo->chip_real_id == XGI_21;
4569}
4570
4566static void __devinit 4571static void __devinit
4567sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay) 4572sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
4568{ 4573{
@@ -4627,11 +4632,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
4627 return 1; 4632 return 1;
4628} 4633}
4629 4634
4630static void __devinit 4635static int __devinit
4631sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) 4636sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4632{ 4637{
4633 unsigned int buswidth, ranksize, channelab, mapsize; 4638 unsigned int buswidth, ranksize, channelab, mapsize;
4634 int i, j, k, l; 4639 int i, j, k, l, status;
4635 u8 reg, sr14; 4640 u8 reg, sr14;
4636 static const u8 dramsr13[12 * 5] = { 4641 static const u8 dramsr13[12 * 5] = {
4637 0x02, 0x0e, 0x0b, 0x80, 0x5d, 4642 0x02, 0x0e, 0x0b, 0x80, 0x5d,
@@ -4673,7 +4678,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4673 SiS_SetReg(SISSR, 0x13, 0x35); 4678 SiS_SetReg(SISSR, 0x13, 0x35);
4674 SiS_SetReg(SISSR, 0x14, 0x41); 4679 SiS_SetReg(SISSR, 0x14, 0x41);
4675 /* TODO */ 4680 /* TODO */
4676 return; 4681 return -ENOMEM;
4677 } 4682 }
4678 4683
4679 /* Non-interleaving */ 4684 /* Non-interleaving */
@@ -4835,6 +4840,7 @@ bail_out:
4835 4840
4836 j = (ivideo->chip == XGI_20) ? 5 : 9; 4841 j = (ivideo->chip == XGI_20) ? 5 : 9;
4837 k = (ivideo->chip == XGI_20) ? 12 : 4; 4842 k = (ivideo->chip == XGI_20) ? 12 : 4;
4843 status = -EIO;
4838 4844
4839 for(i = 0; i < k; i++) { 4845 for(i = 0; i < k; i++) {
4840 4846
@@ -4868,11 +4874,15 @@ bail_out:
4868 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0)); 4874 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
4869 sisfb_post_xgi_delay(ivideo, 1); 4875 sisfb_post_xgi_delay(ivideo, 1);
4870 4876
4871 if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) 4877 if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) {
4878 status = 0;
4872 break; 4879 break;
4880 }
4873 } 4881 }
4874 4882
4875 iounmap(ivideo->video_vbase); 4883 iounmap(ivideo->video_vbase);
4884
4885 return status;
4876} 4886}
4877 4887
4878static void __devinit 4888static void __devinit
@@ -4931,6 +4941,175 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
4931 sisfb_post_xgi_delay(ivideo, 0x43); 4941 sisfb_post_xgi_delay(ivideo, 0x43);
4932} 4942}
4933 4943
4944static void __devinit
4945sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
4946{
4947 unsigned char *bios = ivideo->bios_abase;
4948 u8 v1;
4949
4950 SiS_SetReg(SISSR, 0x28, 0x64);
4951 SiS_SetReg(SISSR, 0x29, 0x63);
4952 sisfb_post_xgi_delay(ivideo, 15);
4953 SiS_SetReg(SISSR, 0x18, 0x00);
4954 SiS_SetReg(SISSR, 0x19, 0x20);
4955 SiS_SetReg(SISSR, 0x16, 0x00);
4956 SiS_SetReg(SISSR, 0x16, 0x80);
4957 SiS_SetReg(SISSR, 0x18, 0xc5);
4958 SiS_SetReg(SISSR, 0x19, 0x23);
4959 SiS_SetReg(SISSR, 0x16, 0x00);
4960 SiS_SetReg(SISSR, 0x16, 0x80);
4961 sisfb_post_xgi_delay(ivideo, 1);
4962 SiS_SetReg(SISCR, 0x97, 0x11);
4963 sisfb_post_xgi_setclocks(ivideo, regb);
4964 sisfb_post_xgi_delay(ivideo, 0x46);
4965 SiS_SetReg(SISSR, 0x18, 0xc5);
4966 SiS_SetReg(SISSR, 0x19, 0x23);
4967 SiS_SetReg(SISSR, 0x16, 0x00);
4968 SiS_SetReg(SISSR, 0x16, 0x80);
4969 sisfb_post_xgi_delay(ivideo, 1);
4970 SiS_SetReg(SISSR, 0x1b, 0x04);
4971 sisfb_post_xgi_delay(ivideo, 1);
4972 SiS_SetReg(SISSR, 0x1b, 0x00);
4973 sisfb_post_xgi_delay(ivideo, 1);
4974 v1 = 0x31;
4975 if (ivideo->haveXGIROM) {
4976 v1 = bios[0xf0];
4977 }
4978 SiS_SetReg(SISSR, 0x18, v1);
4979 SiS_SetReg(SISSR, 0x19, 0x06);
4980 SiS_SetReg(SISSR, 0x16, 0x04);
4981 SiS_SetReg(SISSR, 0x16, 0x84);
4982 sisfb_post_xgi_delay(ivideo, 1);
4983}
4984
4985static void __devinit
4986sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
4987{
4988 sisfb_post_xgi_setclocks(ivideo, 1);
4989
4990 SiS_SetReg(SISCR, 0x97, 0x11);
4991 sisfb_post_xgi_delay(ivideo, 0x46);
4992
4993 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS2 */
4994 SiS_SetReg(SISSR, 0x19, 0x80);
4995 SiS_SetReg(SISSR, 0x16, 0x05);
4996 SiS_SetReg(SISSR, 0x16, 0x85);
4997
4998 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS3 */
4999 SiS_SetReg(SISSR, 0x19, 0xc0);
5000 SiS_SetReg(SISSR, 0x16, 0x05);
5001 SiS_SetReg(SISSR, 0x16, 0x85);
5002
5003 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS1 */
5004 SiS_SetReg(SISSR, 0x19, 0x40);
5005 SiS_SetReg(SISSR, 0x16, 0x05);
5006 SiS_SetReg(SISSR, 0x16, 0x85);
5007
5008 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
5009 SiS_SetReg(SISSR, 0x19, 0x02);
5010 SiS_SetReg(SISSR, 0x16, 0x05);
5011 SiS_SetReg(SISSR, 0x16, 0x85);
5012 sisfb_post_xgi_delay(ivideo, 1);
5013
5014 SiS_SetReg(SISSR, 0x1b, 0x04);
5015 sisfb_post_xgi_delay(ivideo, 1);
5016
5017 SiS_SetReg(SISSR, 0x1b, 0x00);
5018 sisfb_post_xgi_delay(ivideo, 1);
5019
5020 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
5021 SiS_SetReg(SISSR, 0x19, 0x00);
5022 SiS_SetReg(SISSR, 0x16, 0x05);
5023 SiS_SetReg(SISSR, 0x16, 0x85);
5024 sisfb_post_xgi_delay(ivideo, 1);
5025}
5026
5027static void __devinit
5028sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
5029{
5030 unsigned char *bios = ivideo->bios_abase;
5031 static const u8 cs158[8] = {
5032 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
5033 };
5034 static const u8 cs160[8] = {
5035 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
5036 };
5037 static const u8 cs168[8] = {
5038 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
5039 };
5040 u8 reg;
5041 u8 v1;
5042 u8 v2;
5043 u8 v3;
5044
5045 SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */
5046 SiS_SetReg(SISCR, 0x82, 0x77);
5047 SiS_SetReg(SISCR, 0x86, 0x00);
5048 reg = SiS_GetReg(SISCR, 0x86);
5049 SiS_SetReg(SISCR, 0x86, 0x88);
5050 reg = SiS_GetReg(SISCR, 0x86);
5051 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5052 if (ivideo->haveXGIROM) {
5053 v1 = bios[regb + 0x168];
5054 v2 = bios[regb + 0x160];
5055 v3 = bios[regb + 0x158];
5056 }
5057 SiS_SetReg(SISCR, 0x86, v1);
5058 SiS_SetReg(SISCR, 0x82, 0x77);
5059 SiS_SetReg(SISCR, 0x85, 0x00);
5060 reg = SiS_GetReg(SISCR, 0x85);
5061 SiS_SetReg(SISCR, 0x85, 0x88);
5062 reg = SiS_GetReg(SISCR, 0x85);
5063 SiS_SetReg(SISCR, 0x85, v2);
5064 SiS_SetReg(SISCR, 0x82, v3);
5065 SiS_SetReg(SISCR, 0x98, 0x01);
5066 SiS_SetReg(SISCR, 0x9a, 0x02);
5067 if (sisfb_xgi_is21(ivideo))
5068 sisfb_post_xgi_ddr2_mrs_xg21(ivideo);
5069 else
5070 sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
5071}
5072
5073static u8 __devinit
5074sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
5075{
5076 unsigned char *bios = ivideo->bios_abase;
5077 u8 ramtype;
5078 u8 reg;
5079 u8 v1;
5080
5081 ramtype = 0x00; v1 = 0x10;
5082 if (ivideo->haveXGIROM) {
5083 ramtype = bios[0x62];
5084 v1 = bios[0x1d2];
5085 }
5086 if (!(ramtype & 0x80)) {
5087 if (sisfb_xgi_is21(ivideo)) {
5088 SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */
5089 SiS_SetRegOR(SISCR, 0x4a, 0x80); /* GPIOH EN */
5090 reg = SiS_GetReg(SISCR, 0x48);
5091 SiS_SetRegOR(SISCR, 0xb4, 0x02);
5092 ramtype = reg & 0x01; /* GPIOH */
5093 } else if (ivideo->chip == XGI_20) {
5094 SiS_SetReg(SISCR, 0x97, v1);
5095 reg = SiS_GetReg(SISCR, 0x97);
5096 if (reg & 0x10) {
5097 ramtype = (reg & 0x01) << 1;
5098 }
5099 } else {
5100 reg = SiS_GetReg(SISSR, 0x39);
5101 ramtype = reg & 0x02;
5102 if (!(ramtype)) {
5103 reg = SiS_GetReg(SISSR, 0x3a);
5104 ramtype = (reg >> 1) & 0x01;
5105 }
5106 }
5107 }
5108 ramtype &= 0x07;
5109
5110 return ramtype;
5111}
5112
4934static int __devinit 5113static int __devinit
4935sisfb_post_xgi(struct pci_dev *pdev) 5114sisfb_post_xgi(struct pci_dev *pdev)
4936{ 5115{
@@ -5213,9 +5392,23 @@ sisfb_post_xgi(struct pci_dev *pdev)
5213 SiS_SetReg(SISCR, 0x77, v1); 5392 SiS_SetReg(SISCR, 0x77, v1);
5214 } 5393 }
5215 5394
5216 /* RAM type */ 5395 /* RAM type:
5217 5396 *
5218 regb = 0; /* ! */ 5397 * 0 == DDR1, 1 == DDR2, 2..7 == reserved?
5398 *
5399 * The code seems to written so that regb should equal ramtype,
5400 * however, so far it has been hardcoded to 0. Enable other values only
5401 * on XGI Z9, as it passes the POST, and add a warning for others.
5402 */
5403 ramtype = sisfb_post_xgi_ramtype(ivideo);
5404 if (!sisfb_xgi_is21(ivideo) && ramtype) {
5405 dev_warn(&pdev->dev,
5406 "RAM type something else than expected: %d\n",
5407 ramtype);
5408 regb = 0;
5409 } else {
5410 regb = ramtype;
5411 }
5219 5412
5220 v1 = 0xff; 5413 v1 = 0xff;
5221 if(ivideo->haveXGIROM) { 5414 if(ivideo->haveXGIROM) {
@@ -5367,7 +5560,10 @@ sisfb_post_xgi(struct pci_dev *pdev)
5367 } 5560 }
5368 } 5561 }
5369 5562
5370 SiS_SetReg(SISSR, 0x17, 0x00); 5563 if (regb == 1)
5564 SiS_SetReg(SISSR, 0x17, 0x80); /* DDR2 */
5565 else
5566 SiS_SetReg(SISSR, 0x17, 0x00); /* DDR1 */
5371 SiS_SetReg(SISSR, 0x1a, 0x87); 5567 SiS_SetReg(SISSR, 0x1a, 0x87);
5372 5568
5373 if(ivideo->chip == XGI_20) { 5569 if(ivideo->chip == XGI_20) {
@@ -5375,31 +5571,6 @@ sisfb_post_xgi(struct pci_dev *pdev)
5375 SiS_SetReg(SISSR, 0x1c, 0x00); 5571 SiS_SetReg(SISSR, 0x1c, 0x00);
5376 } 5572 }
5377 5573
5378 ramtype = 0x00; v1 = 0x10;
5379 if(ivideo->haveXGIROM) {
5380 ramtype = bios[0x62];
5381 v1 = bios[0x1d2];
5382 }
5383 if(!(ramtype & 0x80)) {
5384 if(ivideo->chip == XGI_20) {
5385 SiS_SetReg(SISCR, 0x97, v1);
5386 reg = SiS_GetReg(SISCR, 0x97);
5387 if(reg & 0x10) {
5388 ramtype = (reg & 0x01) << 1;
5389 }
5390 } else {
5391 reg = SiS_GetReg(SISSR, 0x39);
5392 ramtype = reg & 0x02;
5393 if(!(ramtype)) {
5394 reg = SiS_GetReg(SISSR, 0x3a);
5395 ramtype = (reg >> 1) & 0x01;
5396 }
5397 }
5398 }
5399 ramtype &= 0x07;
5400
5401 regb = 0; /* ! */
5402
5403 switch(ramtype) { 5574 switch(ramtype) {
5404 case 0: 5575 case 0:
5405 sisfb_post_xgi_setclocks(ivideo, regb); 5576 sisfb_post_xgi_setclocks(ivideo, regb);
@@ -5485,61 +5656,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
5485 SiS_SetReg(SISSR, 0x1b, 0x00); 5656 SiS_SetReg(SISSR, 0x1b, 0x00);
5486 break; 5657 break;
5487 case 1: 5658 case 1:
5488 SiS_SetReg(SISCR, 0x82, 0x77); 5659 sisfb_post_xgi_ddr2(ivideo, regb);
5489 SiS_SetReg(SISCR, 0x86, 0x00);
5490 reg = SiS_GetReg(SISCR, 0x86);
5491 SiS_SetReg(SISCR, 0x86, 0x88);
5492 reg = SiS_GetReg(SISCR, 0x86);
5493 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5494 if(ivideo->haveXGIROM) {
5495 v1 = bios[regb + 0x168];
5496 v2 = bios[regb + 0x160];
5497 v3 = bios[regb + 0x158];
5498 }
5499 SiS_SetReg(SISCR, 0x86, v1);
5500 SiS_SetReg(SISCR, 0x82, 0x77);
5501 SiS_SetReg(SISCR, 0x85, 0x00);
5502 reg = SiS_GetReg(SISCR, 0x85);
5503 SiS_SetReg(SISCR, 0x85, 0x88);
5504 reg = SiS_GetReg(SISCR, 0x85);
5505 SiS_SetReg(SISCR, 0x85, v2);
5506 SiS_SetReg(SISCR, 0x82, v3);
5507 SiS_SetReg(SISCR, 0x98, 0x01);
5508 SiS_SetReg(SISCR, 0x9a, 0x02);
5509
5510 SiS_SetReg(SISSR, 0x28, 0x64);
5511 SiS_SetReg(SISSR, 0x29, 0x63);
5512 sisfb_post_xgi_delay(ivideo, 15);
5513 SiS_SetReg(SISSR, 0x18, 0x00);
5514 SiS_SetReg(SISSR, 0x19, 0x20);
5515 SiS_SetReg(SISSR, 0x16, 0x00);
5516 SiS_SetReg(SISSR, 0x16, 0x80);
5517 SiS_SetReg(SISSR, 0x18, 0xc5);
5518 SiS_SetReg(SISSR, 0x19, 0x23);
5519 SiS_SetReg(SISSR, 0x16, 0x00);
5520 SiS_SetReg(SISSR, 0x16, 0x80);
5521 sisfb_post_xgi_delay(ivideo, 1);
5522 SiS_SetReg(SISCR, 0x97, 0x11);
5523 sisfb_post_xgi_setclocks(ivideo, regb);
5524 sisfb_post_xgi_delay(ivideo, 0x46);
5525 SiS_SetReg(SISSR, 0x18, 0xc5);
5526 SiS_SetReg(SISSR, 0x19, 0x23);
5527 SiS_SetReg(SISSR, 0x16, 0x00);
5528 SiS_SetReg(SISSR, 0x16, 0x80);
5529 sisfb_post_xgi_delay(ivideo, 1);
5530 SiS_SetReg(SISSR, 0x1b, 0x04);
5531 sisfb_post_xgi_delay(ivideo, 1);
5532 SiS_SetReg(SISSR, 0x1b, 0x00);
5533 sisfb_post_xgi_delay(ivideo, 1);
5534 v1 = 0x31;
5535 if(ivideo->haveXGIROM) {
5536 v1 = bios[0xf0];
5537 }
5538 SiS_SetReg(SISSR, 0x18, v1);
5539 SiS_SetReg(SISSR, 0x19, 0x06);
5540 SiS_SetReg(SISSR, 0x16, 0x04);
5541 SiS_SetReg(SISSR, 0x16, 0x84);
5542 sisfb_post_xgi_delay(ivideo, 1);
5543 break; 5660 break;
5544 default: 5661 default:
5545 sisfb_post_xgi_setclocks(ivideo, regb); 5662 sisfb_post_xgi_setclocks(ivideo, regb);
@@ -5648,6 +5765,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
5648 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]); 5765 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
5649 5766
5650 } else { 5767 } else {
5768 int err;
5651 5769
5652 /* Set default mode, don't clear screen */ 5770 /* Set default mode, don't clear screen */
5653 ivideo->SiS_Pr.SiS_UseOEM = false; 5771 ivideo->SiS_Pr.SiS_UseOEM = false;
@@ -5661,10 +5779,16 @@ sisfb_post_xgi(struct pci_dev *pdev)
5661 5779
5662 /* Disable read-cache */ 5780 /* Disable read-cache */
5663 SiS_SetRegAND(SISSR, 0x21, 0xdf); 5781 SiS_SetRegAND(SISSR, 0x21, 0xdf);
5664 sisfb_post_xgi_ramsize(ivideo); 5782 err = sisfb_post_xgi_ramsize(ivideo);
5665 /* Enable read-cache */ 5783 /* Enable read-cache */
5666 SiS_SetRegOR(SISSR, 0x21, 0x20); 5784 SiS_SetRegOR(SISSR, 0x21, 0x20);
5667 5785
5786 if (err) {
5787 dev_err(&pdev->dev,
5788 "%s: RAM size detection failed: %d\n",
5789 __func__, err);
5790 return 0;
5791 }
5668 } 5792 }
5669 5793
5670#if 0 5794#if 0
@@ -5777,6 +5901,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5777#endif 5901#endif
5778 5902
5779 ivideo->chip = chipinfo->chip; 5903 ivideo->chip = chipinfo->chip;
5904 ivideo->chip_real_id = chipinfo->chip;
5780 ivideo->sisvga_engine = chipinfo->vgaengine; 5905 ivideo->sisvga_engine = chipinfo->vgaengine;
5781 ivideo->hwcursor_size = chipinfo->hwcursor_size; 5906 ivideo->hwcursor_size = chipinfo->hwcursor_size;
5782 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable; 5907 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
@@ -6010,6 +6135,18 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
6010 sisfb_detect_custom_timing(ivideo); 6135 sisfb_detect_custom_timing(ivideo);
6011 } 6136 }
6012 6137
6138#ifdef CONFIG_FB_SIS_315
6139 if (ivideo->chip == XGI_20) {
6140 /* Check if our Z7 chip is actually Z9 */
6141 SiS_SetRegOR(SISCR, 0x4a, 0x40); /* GPIOG EN */
6142 reg = SiS_GetReg(SISCR, 0x48);
6143 if (reg & 0x02) { /* GPIOG */
6144 ivideo->chip_real_id = XGI_21;
6145 dev_info(&pdev->dev, "Z9 detected\n");
6146 }
6147 }
6148#endif
6149
6013 /* POST card in case this has not been done by the BIOS */ 6150 /* POST card in case this has not been done by the BIOS */
6014 if( (!ivideo->sisvga_enabled) 6151 if( (!ivideo->sisvga_enabled)
6015#if !defined(__i386__) && !defined(__x86_64__) 6152#if !defined(__i386__) && !defined(__x86_64__)
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 12c0dfaf2518..e3f9976cfef0 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -87,6 +87,7 @@ typedef enum _SIS_CHIP_TYPE {
87 SIS_341, 87 SIS_341,
88 SIS_342, 88 SIS_342,
89 XGI_20 = 75, 89 XGI_20 = 75,
90 XGI_21,
90 XGI_40, 91 XGI_40,
91 MAX_SIS_CHIP 92 MAX_SIS_CHIP
92} SIS_CHIP_TYPE; 93} SIS_CHIP_TYPE;
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index bcb44a594ebc..46d1a64fe80d 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -41,6 +41,26 @@
41#include <linux/sm501.h> 41#include <linux/sm501.h>
42#include <linux/sm501-regs.h> 42#include <linux/sm501-regs.h>
43 43
44#include "edid.h"
45
46static char *fb_mode = "640x480-16@60";
47static unsigned long default_bpp = 16;
48
49static struct fb_videomode __devinitdata sm501_default_mode = {
50 .refresh = 60,
51 .xres = 640,
52 .yres = 480,
53 .pixclock = 20833,
54 .left_margin = 142,
55 .right_margin = 13,
56 .upper_margin = 21,
57 .lower_margin = 1,
58 .hsync_len = 69,
59 .vsync_len = 3,
60 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
61 .vmode = FB_VMODE_NONINTERLACED
62};
63
44#define NR_PALETTE 256 64#define NR_PALETTE 256
45 65
46enum sm501_controller { 66enum sm501_controller {
@@ -77,6 +97,7 @@ struct sm501fb_info {
77 void __iomem *regs2d; /* 2d remapped registers */ 97 void __iomem *regs2d; /* 2d remapped registers */
78 void __iomem *fbmem; /* remapped framebuffer */ 98 void __iomem *fbmem; /* remapped framebuffer */
79 size_t fbmem_len; /* length of remapped region */ 99 size_t fbmem_len; /* length of remapped region */
100 u8 *edid_data;
80}; 101};
81 102
82/* per-framebuffer private data */ 103/* per-framebuffer private data */
@@ -117,7 +138,7 @@ static inline int v_total(struct fb_var_screeninfo *var)
117 138
118static inline void sm501fb_sync_regs(struct sm501fb_info *info) 139static inline void sm501fb_sync_regs(struct sm501fb_info *info)
119{ 140{
120 readl(info->regs); 141 smc501_readl(info->regs);
121} 142}
122 143
123/* sm501_alloc_mem 144/* sm501_alloc_mem
@@ -262,7 +283,7 @@ static void sm501fb_setup_gamma(struct sm501fb_info *fbi,
262 283
263 /* set gamma values */ 284 /* set gamma values */
264 for (offset = 0; offset < 256 * 4; offset += 4) { 285 for (offset = 0; offset < 256 * 4; offset += 4) {
265 writel(value, fbi->regs + palette + offset); 286 smc501_writel(value, fbi->regs + palette + offset);
266 value += 0x010101; /* Advance RGB by 1,1,1.*/ 287 value += 0x010101; /* Advance RGB by 1,1,1.*/
267 } 288 }
268} 289}
@@ -476,7 +497,8 @@ static int sm501fb_set_par_common(struct fb_info *info,
476 497
477 /* set start of framebuffer to the screen */ 498 /* set start of framebuffer to the screen */
478 499
479 writel(par->screen.sm_addr | SM501_ADDR_FLIP, fbi->regs + head_addr); 500 smc501_writel(par->screen.sm_addr | SM501_ADDR_FLIP,
501 fbi->regs + head_addr);
480 502
481 /* program CRT clock */ 503 /* program CRT clock */
482 504
@@ -519,7 +541,7 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
519 reg = info->fix.line_length; 541 reg = info->fix.line_length;
520 reg |= ((var->xres * var->bits_per_pixel)/8) << 16; 542 reg |= ((var->xres * var->bits_per_pixel)/8) << 16;
521 543
522 writel(reg, fbi->regs + (par->head == HEAD_CRT ? 544 smc501_writel(reg, fbi->regs + (par->head == HEAD_CRT ?
523 SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET)); 545 SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET));
524 546
525 /* program horizontal total */ 547 /* program horizontal total */
@@ -527,27 +549,27 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
527 reg = (h_total(var) - 1) << 16; 549 reg = (h_total(var) - 1) << 16;
528 reg |= (var->xres - 1); 550 reg |= (var->xres - 1);
529 551
530 writel(reg, base + SM501_OFF_DC_H_TOT); 552 smc501_writel(reg, base + SM501_OFF_DC_H_TOT);
531 553
532 /* program horizontal sync */ 554 /* program horizontal sync */
533 555
534 reg = var->hsync_len << 16; 556 reg = var->hsync_len << 16;
535 reg |= var->xres + var->right_margin - 1; 557 reg |= var->xres + var->right_margin - 1;
536 558
537 writel(reg, base + SM501_OFF_DC_H_SYNC); 559 smc501_writel(reg, base + SM501_OFF_DC_H_SYNC);
538 560
539 /* program vertical total */ 561 /* program vertical total */
540 562
541 reg = (v_total(var) - 1) << 16; 563 reg = (v_total(var) - 1) << 16;
542 reg |= (var->yres - 1); 564 reg |= (var->yres - 1);
543 565
544 writel(reg, base + SM501_OFF_DC_V_TOT); 566 smc501_writel(reg, base + SM501_OFF_DC_V_TOT);
545 567
546 /* program vertical sync */ 568 /* program vertical sync */
547 reg = var->vsync_len << 16; 569 reg = var->vsync_len << 16;
548 reg |= var->yres + var->lower_margin - 1; 570 reg |= var->yres + var->lower_margin - 1;
549 571
550 writel(reg, base + SM501_OFF_DC_V_SYNC); 572 smc501_writel(reg, base + SM501_OFF_DC_V_SYNC);
551} 573}
552 574
553/* sm501fb_pan_crt 575/* sm501fb_pan_crt
@@ -566,15 +588,15 @@ static int sm501fb_pan_crt(struct fb_var_screeninfo *var,
566 588
567 xoffs = var->xoffset * bytes_pixel; 589 xoffs = var->xoffset * bytes_pixel;
568 590
569 reg = readl(fbi->regs + SM501_DC_CRT_CONTROL); 591 reg = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
570 592
571 reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK; 593 reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK;
572 reg |= ((xoffs & 15) / bytes_pixel) << 4; 594 reg |= ((xoffs & 15) / bytes_pixel) << 4;
573 writel(reg, fbi->regs + SM501_DC_CRT_CONTROL); 595 smc501_writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
574 596
575 reg = (par->screen.sm_addr + xoffs + 597 reg = (par->screen.sm_addr + xoffs +
576 var->yoffset * info->fix.line_length); 598 var->yoffset * info->fix.line_length);
577 writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR); 599 smc501_writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
578 600
579 sm501fb_sync_regs(fbi); 601 sm501fb_sync_regs(fbi);
580 return 0; 602 return 0;
@@ -593,10 +615,10 @@ static int sm501fb_pan_pnl(struct fb_var_screeninfo *var,
593 unsigned long reg; 615 unsigned long reg;
594 616
595 reg = var->xoffset | (var->xres_virtual << 16); 617 reg = var->xoffset | (var->xres_virtual << 16);
596 writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH); 618 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
597 619
598 reg = var->yoffset | (var->yres_virtual << 16); 620 reg = var->yoffset | (var->yres_virtual << 16);
599 writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT); 621 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
600 622
601 sm501fb_sync_regs(fbi); 623 sm501fb_sync_regs(fbi);
602 return 0; 624 return 0;
@@ -622,7 +644,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
622 /* enable CRT DAC - note 0 is on!*/ 644 /* enable CRT DAC - note 0 is on!*/
623 sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER); 645 sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER);
624 646
625 control = readl(fbi->regs + SM501_DC_CRT_CONTROL); 647 control = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
626 648
627 control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK | 649 control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK |
628 SM501_DC_CRT_CONTROL_GAMMA | 650 SM501_DC_CRT_CONTROL_GAMMA |
@@ -684,7 +706,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
684 out_update: 706 out_update:
685 dev_dbg(fbi->dev, "new control is %08lx\n", control); 707 dev_dbg(fbi->dev, "new control is %08lx\n", control);
686 708
687 writel(control, fbi->regs + SM501_DC_CRT_CONTROL); 709 smc501_writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
688 sm501fb_sync_regs(fbi); 710 sm501fb_sync_regs(fbi);
689 711
690 return 0; 712 return 0;
@@ -696,18 +718,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
696 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL; 718 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL;
697 struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl; 719 struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl;
698 720
699 control = readl(ctrl_reg); 721 control = smc501_readl(ctrl_reg);
700 722
701 if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) { 723 if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) {
702 /* enable panel power */ 724 /* enable panel power */
703 725
704 control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */ 726 control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */
705 writel(control, ctrl_reg); 727 smc501_writel(control, ctrl_reg);
706 sm501fb_sync_regs(fbi); 728 sm501fb_sync_regs(fbi);
707 mdelay(10); 729 mdelay(10);
708 730
709 control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */ 731 control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */
710 writel(control, ctrl_reg); 732 smc501_writel(control, ctrl_reg);
711 sm501fb_sync_regs(fbi); 733 sm501fb_sync_regs(fbi);
712 mdelay(10); 734 mdelay(10);
713 735
@@ -719,7 +741,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
719 else 741 else
720 control |= SM501_DC_PANEL_CONTROL_BIAS; 742 control |= SM501_DC_PANEL_CONTROL_BIAS;
721 743
722 writel(control, ctrl_reg); 744 smc501_writel(control, ctrl_reg);
723 sm501fb_sync_regs(fbi); 745 sm501fb_sync_regs(fbi);
724 mdelay(10); 746 mdelay(10);
725 } 747 }
@@ -730,7 +752,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
730 else 752 else
731 control |= SM501_DC_PANEL_CONTROL_FPEN; 753 control |= SM501_DC_PANEL_CONTROL_FPEN;
732 754
733 writel(control, ctrl_reg); 755 smc501_writel(control, ctrl_reg);
734 sm501fb_sync_regs(fbi); 756 sm501fb_sync_regs(fbi);
735 mdelay(10); 757 mdelay(10);
736 } 758 }
@@ -742,7 +764,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
742 else 764 else
743 control &= ~SM501_DC_PANEL_CONTROL_FPEN; 765 control &= ~SM501_DC_PANEL_CONTROL_FPEN;
744 766
745 writel(control, ctrl_reg); 767 smc501_writel(control, ctrl_reg);
746 sm501fb_sync_regs(fbi); 768 sm501fb_sync_regs(fbi);
747 mdelay(10); 769 mdelay(10);
748 } 770 }
@@ -753,18 +775,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
753 else 775 else
754 control &= ~SM501_DC_PANEL_CONTROL_BIAS; 776 control &= ~SM501_DC_PANEL_CONTROL_BIAS;
755 777
756 writel(control, ctrl_reg); 778 smc501_writel(control, ctrl_reg);
757 sm501fb_sync_regs(fbi); 779 sm501fb_sync_regs(fbi);
758 mdelay(10); 780 mdelay(10);
759 } 781 }
760 782
761 control &= ~SM501_DC_PANEL_CONTROL_DATA; 783 control &= ~SM501_DC_PANEL_CONTROL_DATA;
762 writel(control, ctrl_reg); 784 smc501_writel(control, ctrl_reg);
763 sm501fb_sync_regs(fbi); 785 sm501fb_sync_regs(fbi);
764 mdelay(10); 786 mdelay(10);
765 787
766 control &= ~SM501_DC_PANEL_CONTROL_VDD; 788 control &= ~SM501_DC_PANEL_CONTROL_VDD;
767 writel(control, ctrl_reg); 789 smc501_writel(control, ctrl_reg);
768 sm501fb_sync_regs(fbi); 790 sm501fb_sync_regs(fbi);
769 mdelay(10); 791 mdelay(10);
770 } 792 }
@@ -799,7 +821,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
799 821
800 /* update control register */ 822 /* update control register */
801 823
802 control = readl(fbi->regs + SM501_DC_PANEL_CONTROL); 824 control = smc501_readl(fbi->regs + SM501_DC_PANEL_CONTROL);
803 control &= (SM501_DC_PANEL_CONTROL_GAMMA | 825 control &= (SM501_DC_PANEL_CONTROL_GAMMA |
804 SM501_DC_PANEL_CONTROL_VDD | 826 SM501_DC_PANEL_CONTROL_VDD |
805 SM501_DC_PANEL_CONTROL_DATA | 827 SM501_DC_PANEL_CONTROL_DATA |
@@ -833,16 +855,16 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
833 BUG(); 855 BUG();
834 } 856 }
835 857
836 writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL); 858 smc501_writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
837 859
838 /* panel plane top left and bottom right location */ 860 /* panel plane top left and bottom right location */
839 861
840 writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC); 862 smc501_writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
841 863
842 reg = var->xres - 1; 864 reg = var->xres - 1;
843 reg |= (var->yres - 1) << 16; 865 reg |= (var->yres - 1) << 16;
844 866
845 writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC); 867 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
846 868
847 /* program panel control register */ 869 /* program panel control register */
848 870
@@ -855,7 +877,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
855 if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0) 877 if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0)
856 control |= SM501_DC_PANEL_CONTROL_VSP; 878 control |= SM501_DC_PANEL_CONTROL_VSP;
857 879
858 writel(control, fbi->regs + SM501_DC_PANEL_CONTROL); 880 smc501_writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
859 sm501fb_sync_regs(fbi); 881 sm501fb_sync_regs(fbi);
860 882
861 /* ensure the panel interface is not tristated at this point */ 883 /* ensure the panel interface is not tristated at this point */
@@ -924,7 +946,7 @@ static int sm501fb_setcolreg(unsigned regno,
924 val |= (green >> 8) << 8; 946 val |= (green >> 8) << 8;
925 val |= blue >> 8; 947 val |= blue >> 8;
926 948
927 writel(val, base + (regno * 4)); 949 smc501_writel(val, base + (regno * 4));
928 } 950 }
929 951
930 break; 952 break;
@@ -980,7 +1002,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
980 1002
981 dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info); 1003 dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info);
982 1004
983 ctrl = readl(fbi->regs + SM501_DC_CRT_CONTROL); 1005 ctrl = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
984 1006
985 switch (blank_mode) { 1007 switch (blank_mode) {
986 case FB_BLANK_POWERDOWN: 1008 case FB_BLANK_POWERDOWN:
@@ -1004,7 +1026,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
1004 1026
1005 } 1027 }
1006 1028
1007 writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL); 1029 smc501_writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
1008 sm501fb_sync_regs(fbi); 1030 sm501fb_sync_regs(fbi);
1009 1031
1010 return 0; 1032 return 0;
@@ -1041,12 +1063,14 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1041 if (cursor->image.depth > 1) 1063 if (cursor->image.depth > 1)
1042 return -EINVAL; 1064 return -EINVAL;
1043 1065
1044 hwc_addr = readl(base + SM501_OFF_HWC_ADDR); 1066 hwc_addr = smc501_readl(base + SM501_OFF_HWC_ADDR);
1045 1067
1046 if (cursor->enable) 1068 if (cursor->enable)
1047 writel(hwc_addr | SM501_HWC_EN, base + SM501_OFF_HWC_ADDR); 1069 smc501_writel(hwc_addr | SM501_HWC_EN,
1070 base + SM501_OFF_HWC_ADDR);
1048 else 1071 else
1049 writel(hwc_addr & ~SM501_HWC_EN, base + SM501_OFF_HWC_ADDR); 1072 smc501_writel(hwc_addr & ~SM501_HWC_EN,
1073 base + SM501_OFF_HWC_ADDR);
1050 1074
1051 /* set data */ 1075 /* set data */
1052 if (cursor->set & FB_CUR_SETPOS) { 1076 if (cursor->set & FB_CUR_SETPOS) {
@@ -1060,7 +1084,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1060 1084
1061 //y += cursor->image.height; 1085 //y += cursor->image.height;
1062 1086
1063 writel(x | (y << 16), base + SM501_OFF_HWC_LOC); 1087 smc501_writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
1064 } 1088 }
1065 1089
1066 if (cursor->set & FB_CUR_SETCMAP) { 1090 if (cursor->set & FB_CUR_SETCMAP) {
@@ -1080,8 +1104,8 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1080 1104
1081 dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg); 1105 dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
1082 1106
1083 writel(bg, base + SM501_OFF_HWC_COLOR_1_2); 1107 smc501_writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
1084 writel(fg, base + SM501_OFF_HWC_COLOR_3); 1108 smc501_writel(fg, base + SM501_OFF_HWC_COLOR_3);
1085 } 1109 }
1086 1110
1087 if (cursor->set & FB_CUR_SETSIZE || 1111 if (cursor->set & FB_CUR_SETSIZE ||
@@ -1102,7 +1126,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1102 __func__, cursor->image.width, cursor->image.height); 1126 __func__, cursor->image.width, cursor->image.height);
1103 1127
1104 for (op = 0; op < (64*64*2)/8; op+=4) 1128 for (op = 0; op < (64*64*2)/8; op+=4)
1105 writel(0x0, dst + op); 1129 smc501_writel(0x0, dst + op);
1106 1130
1107 for (y = 0; y < cursor->image.height; y++) { 1131 for (y = 0; y < cursor->image.height; y++) {
1108 for (x = 0; x < cursor->image.width; x++) { 1132 for (x = 0; x < cursor->image.width; x++) {
@@ -1141,7 +1165,7 @@ static ssize_t sm501fb_crtsrc_show(struct device *dev,
1141 struct sm501fb_info *info = dev_get_drvdata(dev); 1165 struct sm501fb_info *info = dev_get_drvdata(dev);
1142 unsigned long ctrl; 1166 unsigned long ctrl;
1143 1167
1144 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1168 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1145 ctrl &= SM501_DC_CRT_CONTROL_SEL; 1169 ctrl &= SM501_DC_CRT_CONTROL_SEL;
1146 1170
1147 return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel"); 1171 return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel");
@@ -1172,7 +1196,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
1172 1196
1173 dev_info(dev, "setting crt source to head %d\n", head); 1197 dev_info(dev, "setting crt source to head %d\n", head);
1174 1198
1175 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1199 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1176 1200
1177 if (head == HEAD_CRT) { 1201 if (head == HEAD_CRT) {
1178 ctrl |= SM501_DC_CRT_CONTROL_SEL; 1202 ctrl |= SM501_DC_CRT_CONTROL_SEL;
@@ -1184,7 +1208,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
1184 ctrl &= ~SM501_DC_CRT_CONTROL_TE; 1208 ctrl &= ~SM501_DC_CRT_CONTROL_TE;
1185 } 1209 }
1186 1210
1187 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1211 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1188 sm501fb_sync_regs(info); 1212 sm501fb_sync_regs(info);
1189 1213
1190 return len; 1214 return len;
@@ -1205,7 +1229,8 @@ static int sm501fb_show_regs(struct sm501fb_info *info, char *ptr,
1205 unsigned int reg; 1229 unsigned int reg;
1206 1230
1207 for (reg = start; reg < (len + start); reg += 4) 1231 for (reg = start; reg < (len + start); reg += 4)
1208 ptr += sprintf(ptr, "%08x = %08x\n", reg, readl(mem + reg)); 1232 ptr += sprintf(ptr, "%08x = %08x\n", reg,
1233 smc501_readl(mem + reg));
1209 1234
1210 return ptr - buf; 1235 return ptr - buf;
1211} 1236}
@@ -1257,7 +1282,7 @@ static int sm501fb_sync(struct fb_info *info)
1257 1282
1258 /* wait for the 2d engine to be ready */ 1283 /* wait for the 2d engine to be ready */
1259 while ((count > 0) && 1284 while ((count > 0) &&
1260 (readl(fbi->regs + SM501_SYSTEM_CONTROL) & 1285 (smc501_readl(fbi->regs + SM501_SYSTEM_CONTROL) &
1261 SM501_SYSCTRL_2D_ENGINE_STATUS) != 0) 1286 SM501_SYSCTRL_2D_ENGINE_STATUS) != 0)
1262 count--; 1287 count--;
1263 1288
@@ -1312,45 +1337,46 @@ static void sm501fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
1312 return; 1337 return;
1313 1338
1314 /* set the base addresses */ 1339 /* set the base addresses */
1315 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); 1340 smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
1316 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); 1341 smc501_writel(par->screen.sm_addr,
1342 fbi->regs2d + SM501_2D_DESTINATION_BASE);
1317 1343
1318 /* set the window width */ 1344 /* set the window width */
1319 writel((info->var.xres << 16) | info->var.xres, 1345 smc501_writel((info->var.xres << 16) | info->var.xres,
1320 fbi->regs2d + SM501_2D_WINDOW_WIDTH); 1346 fbi->regs2d + SM501_2D_WINDOW_WIDTH);
1321 1347
1322 /* set window stride */ 1348 /* set window stride */
1323 writel((info->var.xres_virtual << 16) | info->var.xres_virtual, 1349 smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
1324 fbi->regs2d + SM501_2D_PITCH); 1350 fbi->regs2d + SM501_2D_PITCH);
1325 1351
1326 /* set data format */ 1352 /* set data format */
1327 switch (info->var.bits_per_pixel) { 1353 switch (info->var.bits_per_pixel) {
1328 case 8: 1354 case 8:
1329 writel(0, fbi->regs2d + SM501_2D_STRETCH); 1355 smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
1330 break; 1356 break;
1331 case 16: 1357 case 16:
1332 writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); 1358 smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
1333 break; 1359 break;
1334 case 32: 1360 case 32:
1335 writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); 1361 smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
1336 break; 1362 break;
1337 } 1363 }
1338 1364
1339 /* 2d compare mask */ 1365 /* 2d compare mask */
1340 writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); 1366 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
1341 1367
1342 /* 2d mask */ 1368 /* 2d mask */
1343 writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); 1369 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
1344 1370
1345 /* source and destination x y */ 1371 /* source and destination x y */
1346 writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE); 1372 smc501_writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
1347 writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION); 1373 smc501_writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
1348 1374
1349 /* w/h */ 1375 /* w/h */
1350 writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); 1376 smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
1351 1377
1352 /* do area move */ 1378 /* do area move */
1353 writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL); 1379 smc501_writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
1354} 1380}
1355 1381
1356static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 1382static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
@@ -1372,47 +1398,49 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec
1372 return; 1398 return;
1373 1399
1374 /* set the base addresses */ 1400 /* set the base addresses */
1375 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); 1401 smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
1376 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); 1402 smc501_writel(par->screen.sm_addr,
1403 fbi->regs2d + SM501_2D_DESTINATION_BASE);
1377 1404
1378 /* set the window width */ 1405 /* set the window width */
1379 writel((info->var.xres << 16) | info->var.xres, 1406 smc501_writel((info->var.xres << 16) | info->var.xres,
1380 fbi->regs2d + SM501_2D_WINDOW_WIDTH); 1407 fbi->regs2d + SM501_2D_WINDOW_WIDTH);
1381 1408
1382 /* set window stride */ 1409 /* set window stride */
1383 writel((info->var.xres_virtual << 16) | info->var.xres_virtual, 1410 smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
1384 fbi->regs2d + SM501_2D_PITCH); 1411 fbi->regs2d + SM501_2D_PITCH);
1385 1412
1386 /* set data format */ 1413 /* set data format */
1387 switch (info->var.bits_per_pixel) { 1414 switch (info->var.bits_per_pixel) {
1388 case 8: 1415 case 8:
1389 writel(0, fbi->regs2d + SM501_2D_STRETCH); 1416 smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
1390 break; 1417 break;
1391 case 16: 1418 case 16:
1392 writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); 1419 smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
1393 break; 1420 break;
1394 case 32: 1421 case 32:
1395 writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); 1422 smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
1396 break; 1423 break;
1397 } 1424 }
1398 1425
1399 /* 2d compare mask */ 1426 /* 2d compare mask */
1400 writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); 1427 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
1401 1428
1402 /* 2d mask */ 1429 /* 2d mask */
1403 writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); 1430 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
1404 1431
1405 /* colour */ 1432 /* colour */
1406 writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND); 1433 smc501_writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
1407 1434
1408 /* x y */ 1435 /* x y */
1409 writel((rect->dx << 16) | rect->dy, fbi->regs2d + SM501_2D_DESTINATION); 1436 smc501_writel((rect->dx << 16) | rect->dy,
1437 fbi->regs2d + SM501_2D_DESTINATION);
1410 1438
1411 /* w/h */ 1439 /* w/h */
1412 writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); 1440 smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
1413 1441
1414 /* do rectangle fill */ 1442 /* do rectangle fill */
1415 writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL); 1443 smc501_writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
1416} 1444}
1417 1445
1418 1446
@@ -1470,11 +1498,12 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
1470 1498
1471 /* initialise the colour registers */ 1499 /* initialise the colour registers */
1472 1500
1473 writel(par->cursor.sm_addr, par->cursor_regs + SM501_OFF_HWC_ADDR); 1501 smc501_writel(par->cursor.sm_addr,
1502 par->cursor_regs + SM501_OFF_HWC_ADDR);
1474 1503
1475 writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC); 1504 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
1476 writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2); 1505 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
1477 writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3); 1506 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
1478 sm501fb_sync_regs(info); 1507 sm501fb_sync_regs(info);
1479 1508
1480 return 0; 1509 return 0;
@@ -1581,7 +1610,7 @@ static int sm501fb_start(struct sm501fb_info *info,
1581 1610
1582 /* clear palette ram - undefined at power on */ 1611 /* clear palette ram - undefined at power on */
1583 for (k = 0; k < (256 * 3); k++) 1612 for (k = 0; k < (256 * 3); k++)
1584 writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4)); 1613 smc501_writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
1585 1614
1586 /* enable display controller */ 1615 /* enable display controller */
1587 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); 1616 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1);
@@ -1649,20 +1678,20 @@ static int sm501fb_init_fb(struct fb_info *fb,
1649 switch (head) { 1678 switch (head) {
1650 case HEAD_CRT: 1679 case HEAD_CRT:
1651 pd = info->pdata->fb_crt; 1680 pd = info->pdata->fb_crt;
1652 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1681 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1653 enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0; 1682 enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0;
1654 1683
1655 /* ensure we set the correct source register */ 1684 /* ensure we set the correct source register */
1656 if (info->pdata->fb_route != SM501_FB_CRT_PANEL) { 1685 if (info->pdata->fb_route != SM501_FB_CRT_PANEL) {
1657 ctrl |= SM501_DC_CRT_CONTROL_SEL; 1686 ctrl |= SM501_DC_CRT_CONTROL_SEL;
1658 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1687 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1659 } 1688 }
1660 1689
1661 break; 1690 break;
1662 1691
1663 case HEAD_PANEL: 1692 case HEAD_PANEL:
1664 pd = info->pdata->fb_pnl; 1693 pd = info->pdata->fb_pnl;
1665 ctrl = readl(info->regs + SM501_DC_PANEL_CONTROL); 1694 ctrl = smc501_readl(info->regs + SM501_DC_PANEL_CONTROL);
1666 enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0; 1695 enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0;
1667 break; 1696 break;
1668 1697
@@ -1680,7 +1709,7 @@ static int sm501fb_init_fb(struct fb_info *fb,
1680 1709
1681 if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) { 1710 if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) {
1682 ctrl &= ~SM501_DC_CRT_CONTROL_SEL; 1711 ctrl &= ~SM501_DC_CRT_CONTROL_SEL;
1683 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1712 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1684 enable = 0; 1713 enable = 0;
1685 } 1714 }
1686 1715
@@ -1700,6 +1729,15 @@ static int sm501fb_init_fb(struct fb_info *fb,
1700 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 1729 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1701 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; 1730 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
1702 1731
1732#if defined(CONFIG_OF)
1733#ifdef __BIG_ENDIAN
1734 if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
1735 fb->flags |= FBINFO_FOREIGN_ENDIAN;
1736#else
1737 if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
1738 fb->flags |= FBINFO_FOREIGN_ENDIAN;
1739#endif
1740#endif
1703 /* fixed data */ 1741 /* fixed data */
1704 1742
1705 fb->fix.type = FB_TYPE_PACKED_PIXELS; 1743 fb->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -1717,9 +1755,16 @@ static int sm501fb_init_fb(struct fb_info *fb,
1717 fb->var.vmode = FB_VMODE_NONINTERLACED; 1755 fb->var.vmode = FB_VMODE_NONINTERLACED;
1718 fb->var.bits_per_pixel = 16; 1756 fb->var.bits_per_pixel = 16;
1719 1757
1758 if (info->edid_data) {
1759 /* Now build modedb from EDID */
1760 fb_edid_to_monspecs(info->edid_data, &fb->monspecs);
1761 fb_videomode_to_modelist(fb->monspecs.modedb,
1762 fb->monspecs.modedb_len,
1763 &fb->modelist);
1764 }
1765
1720 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) { 1766 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) {
1721 /* TODO read the mode from the current display */ 1767 /* TODO read the mode from the current display */
1722
1723 } else { 1768 } else {
1724 if (pd->def_mode) { 1769 if (pd->def_mode) {
1725 dev_info(info->dev, "using supplied mode\n"); 1770 dev_info(info->dev, "using supplied mode\n");
@@ -1729,12 +1774,37 @@ static int sm501fb_init_fb(struct fb_info *fb,
1729 fb->var.xres_virtual = fb->var.xres; 1774 fb->var.xres_virtual = fb->var.xres;
1730 fb->var.yres_virtual = fb->var.yres; 1775 fb->var.yres_virtual = fb->var.yres;
1731 } else { 1776 } else {
1732 ret = fb_find_mode(&fb->var, fb, 1777 if (info->edid_data) {
1778 ret = fb_find_mode(&fb->var, fb, fb_mode,
1779 fb->monspecs.modedb,
1780 fb->monspecs.modedb_len,
1781 &sm501_default_mode, default_bpp);
1782 /* edid_data is no longer needed, free it */
1783 kfree(info->edid_data);
1784 } else {
1785 ret = fb_find_mode(&fb->var, fb,
1733 NULL, NULL, 0, NULL, 8); 1786 NULL, NULL, 0, NULL, 8);
1787 }
1734 1788
1735 if (ret == 0 || ret == 4) { 1789 switch (ret) {
1736 dev_err(info->dev, 1790 case 1:
1737 "failed to get initial mode\n"); 1791 dev_info(info->dev, "using mode specified in "
1792 "@mode\n");
1793 break;
1794 case 2:
1795 dev_info(info->dev, "using mode specified in "
1796 "@mode with ignored refresh rate\n");
1797 break;
1798 case 3:
1799 dev_info(info->dev, "using mode default "
1800 "mode\n");
1801 break;
1802 case 4:
1803 dev_info(info->dev, "using mode from list\n");
1804 break;
1805 default:
1806 dev_info(info->dev, "ret = %d\n", ret);
1807 dev_info(info->dev, "failed to find mode\n");
1738 return -EINVAL; 1808 return -EINVAL;
1739 } 1809 }
1740 } 1810 }
@@ -1875,8 +1945,32 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
1875 } 1945 }
1876 1946
1877 if (info->pdata == NULL) { 1947 if (info->pdata == NULL) {
1878 dev_info(dev, "using default configuration data\n"); 1948 int found = 0;
1949#if defined(CONFIG_OF)
1950 struct device_node *np = pdev->dev.parent->of_node;
1951 const u8 *prop;
1952 const char *cp;
1953 int len;
1954
1879 info->pdata = &sm501fb_def_pdata; 1955 info->pdata = &sm501fb_def_pdata;
1956 if (np) {
1957 /* Get EDID */
1958 cp = of_get_property(np, "mode", &len);
1959 if (cp)
1960 strcpy(fb_mode, cp);
1961 prop = of_get_property(np, "edid", &len);
1962 if (prop && len == EDID_LENGTH) {
1963 info->edid_data = kmemdup(prop, EDID_LENGTH,
1964 GFP_KERNEL);
1965 if (info->edid_data)
1966 found = 1;
1967 }
1968 }
1969#endif
1970 if (!found) {
1971 dev_info(dev, "using default configuration data\n");
1972 info->pdata = &sm501fb_def_pdata;
1973 }
1880 } 1974 }
1881 1975
1882 /* probe for the presence of each panel */ 1976 /* probe for the presence of each panel */
@@ -2085,7 +2179,7 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
2085 struct sm501fb_info *info = platform_get_drvdata(pdev); 2179 struct sm501fb_info *info = platform_get_drvdata(pdev);
2086 2180
2087 /* store crt control to resume with */ 2181 /* store crt control to resume with */
2088 info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 2182 info->pm_crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
2089 2183
2090 sm501fb_suspend_fb(info, HEAD_CRT); 2184 sm501fb_suspend_fb(info, HEAD_CRT);
2091 sm501fb_suspend_fb(info, HEAD_PANEL); 2185 sm501fb_suspend_fb(info, HEAD_PANEL);
@@ -2109,10 +2203,10 @@ static int sm501fb_resume(struct platform_device *pdev)
2109 2203
2110 /* restore the items we want to be saved for crt control */ 2204 /* restore the items we want to be saved for crt control */
2111 2205
2112 crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 2206 crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
2113 crt_ctrl &= ~SM501_CRT_CTRL_SAVE; 2207 crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
2114 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE; 2208 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
2115 writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL); 2209 smc501_writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
2116 2210
2117 sm501fb_resume_fb(info, HEAD_CRT); 2211 sm501fb_resume_fb(info, HEAD_CRT);
2118 sm501fb_resume_fb(info, HEAD_PANEL); 2212 sm501fb_resume_fb(info, HEAD_PANEL);
@@ -2149,6 +2243,11 @@ static void __exit sm501fb_cleanup(void)
2149module_init(sm501fb_init); 2243module_init(sm501fb_init);
2150module_exit(sm501fb_cleanup); 2244module_exit(sm501fb_cleanup);
2151 2245
2246module_param_named(mode, fb_mode, charp, 0);
2247MODULE_PARM_DESC(mode,
2248 "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
2249module_param_named(bpp, default_bpp, ulong, 0);
2250MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
2152MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); 2251MODULE_AUTHOR("Ben Dooks, Vincent Sanders");
2153MODULE_DESCRIPTION("SM501 Framebuffer driver"); 2252MODULE_DESCRIPTION("SM501 Framebuffer driver");
2154MODULE_LICENSE("GPL v2"); 2253MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index fdb45674e2f6..33df9ec91795 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -20,12 +20,12 @@
20 20
21 21
22/* Write a CRT register value spread across multiple registers */ 22/* Write a CRT register value spread across multiple registers */
23void svga_wcrt_multi(const struct vga_regset *regset, u32 value) { 23void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
24 24{
25 u8 regval, bitval, bitnum; 25 u8 regval, bitval, bitnum;
26 26
27 while (regset->regnum != VGA_REGSET_END_VAL) { 27 while (regset->regnum != VGA_REGSET_END_VAL) {
28 regval = vga_rcrt(NULL, regset->regnum); 28 regval = vga_rcrt(regbase, regset->regnum);
29 bitnum = regset->lowbit; 29 bitnum = regset->lowbit;
30 while (bitnum <= regset->highbit) { 30 while (bitnum <= regset->highbit) {
31 bitval = 1 << bitnum; 31 bitval = 1 << bitnum;
@@ -34,18 +34,18 @@ void svga_wcrt_multi(const struct vga_regset *regset, u32 value) {
34 bitnum ++; 34 bitnum ++;
35 value = value >> 1; 35 value = value >> 1;
36 } 36 }
37 vga_wcrt(NULL, regset->regnum, regval); 37 vga_wcrt(regbase, regset->regnum, regval);
38 regset ++; 38 regset ++;
39 } 39 }
40} 40}
41 41
42/* Write a sequencer register value spread across multiple registers */ 42/* Write a sequencer register value spread across multiple registers */
43void svga_wseq_multi(const struct vga_regset *regset, u32 value) { 43void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
44 44{
45 u8 regval, bitval, bitnum; 45 u8 regval, bitval, bitnum;
46 46
47 while (regset->regnum != VGA_REGSET_END_VAL) { 47 while (regset->regnum != VGA_REGSET_END_VAL) {
48 regval = vga_rseq(NULL, regset->regnum); 48 regval = vga_rseq(regbase, regset->regnum);
49 bitnum = regset->lowbit; 49 bitnum = regset->lowbit;
50 while (bitnum <= regset->highbit) { 50 while (bitnum <= regset->highbit) {
51 bitval = 1 << bitnum; 51 bitval = 1 << bitnum;
@@ -54,7 +54,7 @@ void svga_wseq_multi(const struct vga_regset *regset, u32 value) {
54 bitnum ++; 54 bitnum ++;
55 value = value >> 1; 55 value = value >> 1;
56 } 56 }
57 vga_wseq(NULL, regset->regnum, regval); 57 vga_wseq(regbase, regset->regnum, regval);
58 regset ++; 58 regset ++;
59 } 59 }
60} 60}
@@ -75,95 +75,95 @@ static unsigned int svga_regset_size(const struct vga_regset *regset)
75 75
76 76
77/* Set graphics controller registers to sane values */ 77/* Set graphics controller registers to sane values */
78void svga_set_default_gfx_regs(void) 78void svga_set_default_gfx_regs(void __iomem *regbase)
79{ 79{
80 /* All standard GFX registers (GR00 - GR08) */ 80 /* All standard GFX registers (GR00 - GR08) */
81 vga_wgfx(NULL, VGA_GFX_SR_VALUE, 0x00); 81 vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0x00);
82 vga_wgfx(NULL, VGA_GFX_SR_ENABLE, 0x00); 82 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0x00);
83 vga_wgfx(NULL, VGA_GFX_COMPARE_VALUE, 0x00); 83 vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0x00);
84 vga_wgfx(NULL, VGA_GFX_DATA_ROTATE, 0x00); 84 vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0x00);
85 vga_wgfx(NULL, VGA_GFX_PLANE_READ, 0x00); 85 vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0x00);
86 vga_wgfx(NULL, VGA_GFX_MODE, 0x00); 86 vga_wgfx(regbase, VGA_GFX_MODE, 0x00);
87/* vga_wgfx(NULL, VGA_GFX_MODE, 0x20); */ 87/* vga_wgfx(regbase, VGA_GFX_MODE, 0x20); */
88/* vga_wgfx(NULL, VGA_GFX_MODE, 0x40); */ 88/* vga_wgfx(regbase, VGA_GFX_MODE, 0x40); */
89 vga_wgfx(NULL, VGA_GFX_MISC, 0x05); 89 vga_wgfx(regbase, VGA_GFX_MISC, 0x05);
90/* vga_wgfx(NULL, VGA_GFX_MISC, 0x01); */ 90/* vga_wgfx(regbase, VGA_GFX_MISC, 0x01); */
91 vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x0F); 91 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x0F);
92 vga_wgfx(NULL, VGA_GFX_BIT_MASK, 0xFF); 92 vga_wgfx(regbase, VGA_GFX_BIT_MASK, 0xFF);
93} 93}
94 94
95/* Set attribute controller registers to sane values */ 95/* Set attribute controller registers to sane values */
96void svga_set_default_atc_regs(void) 96void svga_set_default_atc_regs(void __iomem *regbase)
97{ 97{
98 u8 count; 98 u8 count;
99 99
100 vga_r(NULL, 0x3DA); 100 vga_r(regbase, 0x3DA);
101 vga_w(NULL, VGA_ATT_W, 0x00); 101 vga_w(regbase, VGA_ATT_W, 0x00);
102 102
103 /* All standard ATC registers (AR00 - AR14) */ 103 /* All standard ATC registers (AR00 - AR14) */
104 for (count = 0; count <= 0xF; count ++) 104 for (count = 0; count <= 0xF; count ++)
105 svga_wattr(count, count); 105 svga_wattr(regbase, count, count);
106 106
107 svga_wattr(VGA_ATC_MODE, 0x01); 107 svga_wattr(regbase, VGA_ATC_MODE, 0x01);
108/* svga_wattr(VGA_ATC_MODE, 0x41); */ 108/* svga_wattr(regbase, VGA_ATC_MODE, 0x41); */
109 svga_wattr(VGA_ATC_OVERSCAN, 0x00); 109 svga_wattr(regbase, VGA_ATC_OVERSCAN, 0x00);
110 svga_wattr(VGA_ATC_PLANE_ENABLE, 0x0F); 110 svga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 0x0F);
111 svga_wattr(VGA_ATC_PEL, 0x00); 111 svga_wattr(regbase, VGA_ATC_PEL, 0x00);
112 svga_wattr(VGA_ATC_COLOR_PAGE, 0x00); 112 svga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0x00);
113 113
114 vga_r(NULL, 0x3DA); 114 vga_r(regbase, 0x3DA);
115 vga_w(NULL, VGA_ATT_W, 0x20); 115 vga_w(regbase, VGA_ATT_W, 0x20);
116} 116}
117 117
118/* Set sequencer registers to sane values */ 118/* Set sequencer registers to sane values */
119void svga_set_default_seq_regs(void) 119void svga_set_default_seq_regs(void __iomem *regbase)
120{ 120{
121 /* Standard sequencer registers (SR01 - SR04), SR00 is not set */ 121 /* Standard sequencer registers (SR01 - SR04), SR00 is not set */
122 vga_wseq(NULL, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS); 122 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS);
123 vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES); 123 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES);
124 vga_wseq(NULL, VGA_SEQ_CHARACTER_MAP, 0x00); 124 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
125/* vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */ 125/* vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */
126 vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE); 126 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE);
127} 127}
128 128
129/* Set CRTC registers to sane values */ 129/* Set CRTC registers to sane values */
130void svga_set_default_crt_regs(void) 130void svga_set_default_crt_regs(void __iomem *regbase)
131{ 131{
132 /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */ 132 /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */
133 svga_wcrt_mask(0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */ 133 svga_wcrt_mask(regbase, 0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */
134 vga_wcrt(NULL, VGA_CRTC_PRESET_ROW, 0); 134 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
135 svga_wcrt_mask(VGA_CRTC_MAX_SCAN, 0, 0x1F); 135 svga_wcrt_mask(regbase, VGA_CRTC_MAX_SCAN, 0, 0x1F);
136 vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0); 136 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
137 vga_wcrt(NULL, VGA_CRTC_MODE, 0xE3); 137 vga_wcrt(regbase, VGA_CRTC_MODE, 0xE3);
138} 138}
139 139
140void svga_set_textmode_vga_regs(void) 140void svga_set_textmode_vga_regs(void __iomem *regbase)
141{ 141{
142 /* svga_wseq_mask(0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */ 142 /* svga_wseq_mask(regbase, 0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */
143 vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM); 143 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM);
144 vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, 0x03); 144 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x03);
145 145
146 vga_wcrt(NULL, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */ 146 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */
147 vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0x1f); 147 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0x1f);
148 svga_wcrt_mask(VGA_CRTC_MODE, 0x23, 0x7f); 148 svga_wcrt_mask(regbase, VGA_CRTC_MODE, 0x23, 0x7f);
149 149
150 vga_wcrt(NULL, VGA_CRTC_CURSOR_START, 0x0d); 150 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0x0d);
151 vga_wcrt(NULL, VGA_CRTC_CURSOR_END, 0x0e); 151 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 0x0e);
152 vga_wcrt(NULL, VGA_CRTC_CURSOR_HI, 0x00); 152 vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0x00);
153 vga_wcrt(NULL, VGA_CRTC_CURSOR_LO, 0x00); 153 vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0x00);
154 154
155 vga_wgfx(NULL, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */ 155 vga_wgfx(regbase, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */
156 vga_wgfx(NULL, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */ 156 vga_wgfx(regbase, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */
157 vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x00); 157 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x00);
158 158
159 vga_r(NULL, 0x3DA); 159 vga_r(regbase, 0x3DA);
160 vga_w(NULL, VGA_ATT_W, 0x00); 160 vga_w(regbase, VGA_ATT_W, 0x00);
161 161
162 svga_wattr(0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */ 162 svga_wattr(regbase, 0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */
163 svga_wattr(0x13, 0x08); /* Horizontal Pixel Panning Register */ 163 svga_wattr(regbase, 0x13, 0x08); /* Horizontal Pixel Panning Register */
164 164
165 vga_r(NULL, 0x3DA); 165 vga_r(regbase, 0x3DA);
166 vga_w(NULL, VGA_ATT_W, 0x20); 166 vga_w(regbase, VGA_ATT_W, 0x20);
167} 167}
168 168
169#if 0 169#if 0
@@ -299,7 +299,7 @@ void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
299} 299}
300 300
301/* Set cursor in text (tileblit) mode */ 301/* Set cursor in text (tileblit) mode */
302void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor) 302void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tilecursor *cursor)
303{ 303{
304 u8 cs = 0x0d; 304 u8 cs = 0x0d;
305 u8 ce = 0x0e; 305 u8 ce = 0x0e;
@@ -310,7 +310,7 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
310 if (! cursor -> mode) 310 if (! cursor -> mode)
311 return; 311 return;
312 312
313 svga_wcrt_mask(0x0A, 0x20, 0x20); /* disable cursor */ 313 svga_wcrt_mask(regbase, 0x0A, 0x20, 0x20); /* disable cursor */
314 314
315 if (cursor -> shape == FB_TILE_CURSOR_NONE) 315 if (cursor -> shape == FB_TILE_CURSOR_NONE)
316 return; 316 return;
@@ -334,11 +334,11 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
334 } 334 }
335 335
336 /* set cursor position */ 336 /* set cursor position */
337 vga_wcrt(NULL, 0x0E, pos >> 8); 337 vga_wcrt(regbase, 0x0E, pos >> 8);
338 vga_wcrt(NULL, 0x0F, pos & 0xFF); 338 vga_wcrt(regbase, 0x0F, pos & 0xFF);
339 339
340 vga_wcrt(NULL, 0x0B, ce); /* set cursor end */ 340 vga_wcrt(regbase, 0x0B, ce); /* set cursor end */
341 vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */ 341 vga_wcrt(regbase, 0x0A, cs); /* set cursor start and enable it */
342} 342}
343 343
344int svga_get_tilemax(struct fb_info *info) 344int svga_get_tilemax(struct fb_info *info)
@@ -507,8 +507,9 @@ int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screenin
507} 507}
508 508
509/* Set CRT timing registers */ 509/* Set CRT timing registers */
510void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, 510void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm,
511 u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node) 511 struct fb_var_screeninfo *var,
512 u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node)
512{ 513{
513 u8 regval; 514 u8 regval;
514 u32 value; 515 u32 value;
@@ -516,66 +517,66 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
516 value = var->xres + var->left_margin + var->right_margin + var->hsync_len; 517 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
517 value = (value * hmul) / hdiv; 518 value = (value * hmul) / hdiv;
518 pr_debug("fb%d: horizontal total : %d\n", node, value); 519 pr_debug("fb%d: horizontal total : %d\n", node, value);
519 svga_wcrt_multi(tm->h_total_regs, (value / 8) - 5); 520 svga_wcrt_multi(regbase, tm->h_total_regs, (value / 8) - 5);
520 521
521 value = var->xres; 522 value = var->xres;
522 value = (value * hmul) / hdiv; 523 value = (value * hmul) / hdiv;
523 pr_debug("fb%d: horizontal display : %d\n", node, value); 524 pr_debug("fb%d: horizontal display : %d\n", node, value);
524 svga_wcrt_multi(tm->h_display_regs, (value / 8) - 1); 525 svga_wcrt_multi(regbase, tm->h_display_regs, (value / 8) - 1);
525 526
526 value = var->xres; 527 value = var->xres;
527 value = (value * hmul) / hdiv; 528 value = (value * hmul) / hdiv;
528 pr_debug("fb%d: horizontal blank start: %d\n", node, value); 529 pr_debug("fb%d: horizontal blank start: %d\n", node, value);
529 svga_wcrt_multi(tm->h_blank_start_regs, (value / 8) - 1 + hborder); 530 svga_wcrt_multi(regbase, tm->h_blank_start_regs, (value / 8) - 1 + hborder);
530 531
531 value = var->xres + var->left_margin + var->right_margin + var->hsync_len; 532 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
532 value = (value * hmul) / hdiv; 533 value = (value * hmul) / hdiv;
533 pr_debug("fb%d: horizontal blank end : %d\n", node, value); 534 pr_debug("fb%d: horizontal blank end : %d\n", node, value);
534 svga_wcrt_multi(tm->h_blank_end_regs, (value / 8) - 1 - hborder); 535 svga_wcrt_multi(regbase, tm->h_blank_end_regs, (value / 8) - 1 - hborder);
535 536
536 value = var->xres + var->right_margin; 537 value = var->xres + var->right_margin;
537 value = (value * hmul) / hdiv; 538 value = (value * hmul) / hdiv;
538 pr_debug("fb%d: horizontal sync start : %d\n", node, value); 539 pr_debug("fb%d: horizontal sync start : %d\n", node, value);
539 svga_wcrt_multi(tm->h_sync_start_regs, (value / 8)); 540 svga_wcrt_multi(regbase, tm->h_sync_start_regs, (value / 8));
540 541
541 value = var->xres + var->right_margin + var->hsync_len; 542 value = var->xres + var->right_margin + var->hsync_len;
542 value = (value * hmul) / hdiv; 543 value = (value * hmul) / hdiv;
543 pr_debug("fb%d: horizontal sync end : %d\n", node, value); 544 pr_debug("fb%d: horizontal sync end : %d\n", node, value);
544 svga_wcrt_multi(tm->h_sync_end_regs, (value / 8)); 545 svga_wcrt_multi(regbase, tm->h_sync_end_regs, (value / 8));
545 546
546 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; 547 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
547 value = (value * vmul) / vdiv; 548 value = (value * vmul) / vdiv;
548 pr_debug("fb%d: vertical total : %d\n", node, value); 549 pr_debug("fb%d: vertical total : %d\n", node, value);
549 svga_wcrt_multi(tm->v_total_regs, value - 2); 550 svga_wcrt_multi(regbase, tm->v_total_regs, value - 2);
550 551
551 value = var->yres; 552 value = var->yres;
552 value = (value * vmul) / vdiv; 553 value = (value * vmul) / vdiv;
553 pr_debug("fb%d: vertical display : %d\n", node, value); 554 pr_debug("fb%d: vertical display : %d\n", node, value);
554 svga_wcrt_multi(tm->v_display_regs, value - 1); 555 svga_wcrt_multi(regbase, tm->v_display_regs, value - 1);
555 556
556 value = var->yres; 557 value = var->yres;
557 value = (value * vmul) / vdiv; 558 value = (value * vmul) / vdiv;
558 pr_debug("fb%d: vertical blank start : %d\n", node, value); 559 pr_debug("fb%d: vertical blank start : %d\n", node, value);
559 svga_wcrt_multi(tm->v_blank_start_regs, value); 560 svga_wcrt_multi(regbase, tm->v_blank_start_regs, value);
560 561
561 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; 562 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
562 value = (value * vmul) / vdiv; 563 value = (value * vmul) / vdiv;
563 pr_debug("fb%d: vertical blank end : %d\n", node, value); 564 pr_debug("fb%d: vertical blank end : %d\n", node, value);
564 svga_wcrt_multi(tm->v_blank_end_regs, value - 2); 565 svga_wcrt_multi(regbase, tm->v_blank_end_regs, value - 2);
565 566
566 value = var->yres + var->lower_margin; 567 value = var->yres + var->lower_margin;
567 value = (value * vmul) / vdiv; 568 value = (value * vmul) / vdiv;
568 pr_debug("fb%d: vertical sync start : %d\n", node, value); 569 pr_debug("fb%d: vertical sync start : %d\n", node, value);
569 svga_wcrt_multi(tm->v_sync_start_regs, value); 570 svga_wcrt_multi(regbase, tm->v_sync_start_regs, value);
570 571
571 value = var->yres + var->lower_margin + var->vsync_len; 572 value = var->yres + var->lower_margin + var->vsync_len;
572 value = (value * vmul) / vdiv; 573 value = (value * vmul) / vdiv;
573 pr_debug("fb%d: vertical sync end : %d\n", node, value); 574 pr_debug("fb%d: vertical sync end : %d\n", node, value);
574 svga_wcrt_multi(tm->v_sync_end_regs, value); 575 svga_wcrt_multi(regbase, tm->v_sync_end_regs, value);
575 576
576 /* Set horizontal and vertical sync pulse polarity in misc register */ 577 /* Set horizontal and vertical sync pulse polarity in misc register */
577 578
578 regval = vga_r(NULL, VGA_MIS_R); 579 regval = vga_r(regbase, VGA_MIS_R);
579 if (var->sync & FB_SYNC_HOR_HIGH_ACT) { 580 if (var->sync & FB_SYNC_HOR_HIGH_ACT) {
580 pr_debug("fb%d: positive horizontal sync\n", node); 581 pr_debug("fb%d: positive horizontal sync\n", node);
581 regval = regval & ~0x80; 582 regval = regval & ~0x80;
@@ -590,7 +591,7 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
590 pr_debug("fb%d: negative vertical sync\n\n", node); 591 pr_debug("fb%d: negative vertical sync\n\n", node);
591 regval = regval | 0x40; 592 regval = regval | 0x40;
592 } 593 }
593 vga_w(NULL, VGA_MIS_W, regval); 594 vga_w(regbase, VGA_MIS_W, regval);
594} 595}
595 596
596 597
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 855b71993f61..07c66e946634 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -480,6 +480,7 @@ out_dealloc_cmap:
480 480
481out_unmap_regs: 481out_unmap_regs:
482 tcx_unmap_regs(op, info, par); 482 tcx_unmap_regs(op, info, par);
483 framebuffer_release(info);
483 484
484out_err: 485out_err:
485 return err; 486 return err;
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 5180a215d781..7f8472cc993b 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -1552,8 +1552,7 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
1552 int rc; 1552 int rc;
1553 1553
1554 /* Find the largest power-of-two */ 1554 /* Find the largest power-of-two */
1555 while (temp_size & (temp_size - 1)) 1555 temp_size = roundup_pow_of_two(temp_size);
1556 temp_size &= (temp_size - 1);
1557 1556
1558 /* Try and find a power of two to add */ 1557 /* Try and find a power of two to add */
1559 do { 1558 do {
@@ -1566,6 +1565,28 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
1566#endif /* CONFIG_MTRR */ 1565#endif /* CONFIG_MTRR */
1567} 1566}
1568 1567
1568static void __devinit uvesafb_ioremap(struct fb_info *info)
1569{
1570#ifdef CONFIG_X86
1571 switch (mtrr) {
1572 case 1: /* uncachable */
1573 info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
1574 break;
1575 case 2: /* write-back */
1576 info->screen_base = ioremap_cache(info->fix.smem_start, info->fix.smem_len);
1577 break;
1578 case 3: /* write-combining */
1579 info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
1580 break;
1581 case 4: /* write-through */
1582 default:
1583 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1584 break;
1585 }
1586#else
1587 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1588#endif /* CONFIG_X86 */
1589}
1569 1590
1570static ssize_t uvesafb_show_vbe_ver(struct device *dev, 1591static ssize_t uvesafb_show_vbe_ver(struct device *dev,
1571 struct device_attribute *attr, char *buf) 1592 struct device_attribute *attr, char *buf)
@@ -1736,15 +1757,22 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1736 1757
1737 uvesafb_init_info(info, mode); 1758 uvesafb_init_info(info, mode);
1738 1759
1760 if (!request_region(0x3c0, 32, "uvesafb")) {
1761 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1762 err = -EIO;
1763 goto out_mode;
1764 }
1765
1739 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len, 1766 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
1740 "uvesafb")) { 1767 "uvesafb")) {
1741 printk(KERN_ERR "uvesafb: cannot reserve video memory at " 1768 printk(KERN_ERR "uvesafb: cannot reserve video memory at "
1742 "0x%lx\n", info->fix.smem_start); 1769 "0x%lx\n", info->fix.smem_start);
1743 err = -EIO; 1770 err = -EIO;
1744 goto out_mode; 1771 goto out_reg;
1745 } 1772 }
1746 1773
1747 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); 1774 uvesafb_init_mtrr(info);
1775 uvesafb_ioremap(info);
1748 1776
1749 if (!info->screen_base) { 1777 if (!info->screen_base) {
1750 printk(KERN_ERR 1778 printk(KERN_ERR
@@ -1755,20 +1783,13 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1755 goto out_mem; 1783 goto out_mem;
1756 } 1784 }
1757 1785
1758 if (!request_region(0x3c0, 32, "uvesafb")) {
1759 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1760 err = -EIO;
1761 goto out_unmap;
1762 }
1763
1764 uvesafb_init_mtrr(info);
1765 platform_set_drvdata(dev, info); 1786 platform_set_drvdata(dev, info);
1766 1787
1767 if (register_framebuffer(info) < 0) { 1788 if (register_framebuffer(info) < 0) {
1768 printk(KERN_ERR 1789 printk(KERN_ERR
1769 "uvesafb: failed to register framebuffer device\n"); 1790 "uvesafb: failed to register framebuffer device\n");
1770 err = -EINVAL; 1791 err = -EINVAL;
1771 goto out_reg; 1792 goto out_unmap;
1772 } 1793 }
1773 1794
1774 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, " 1795 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
@@ -1785,12 +1806,12 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1785 1806
1786 return 0; 1807 return 0;
1787 1808
1788out_reg:
1789 release_region(0x3c0, 32);
1790out_unmap: 1809out_unmap:
1791 iounmap(info->screen_base); 1810 iounmap(info->screen_base);
1792out_mem: 1811out_mem:
1793 release_mem_region(info->fix.smem_start, info->fix.smem_len); 1812 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1813out_reg:
1814 release_region(0x3c0, 32);
1794out_mode: 1815out_mode:
1795 if (!list_empty(&info->modelist)) 1816 if (!list_empty(&info->modelist))
1796 fb_destroy_modelist(&info->modelist); 1817 fb_destroy_modelist(&info->modelist);
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 931a567f9aff..970e43d13f52 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -891,8 +891,7 @@ static int vmlfb_set_par(struct fb_info *info)
891 int ret; 891 int ret;
892 892
893 mutex_lock(&vml_mutex); 893 mutex_lock(&vml_mutex);
894 list_del(&vinfo->head); 894 list_move(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
895 list_add(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
896 ret = vmlfb_set_par_locked(vinfo); 895 ret = vmlfb_set_par_locked(vinfo);
897 896
898 mutex_unlock(&vml_mutex); 897 mutex_unlock(&vml_mutex);
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 6a069d047914..a99bbe86db13 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -303,19 +303,6 @@ static int __init vesafb_probe(struct platform_device *dev)
303 info->apertures->ranges[0].base = screen_info.lfb_base; 303 info->apertures->ranges[0].base = screen_info.lfb_base;
304 info->apertures->ranges[0].size = size_total; 304 info->apertures->ranges[0].size = size_total;
305 305
306 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
307 if (!info->screen_base) {
308 printk(KERN_ERR
309 "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
310 vesafb_fix.smem_len, vesafb_fix.smem_start);
311 err = -EIO;
312 goto err;
313 }
314
315 printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
316 "using %dk, total %dk\n",
317 vesafb_fix.smem_start, info->screen_base,
318 size_remap/1024, size_total/1024);
319 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", 306 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
320 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); 307 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
321 308
@@ -438,8 +425,7 @@ static int __init vesafb_probe(struct platform_device *dev)
438 int rc; 425 int rc;
439 426
440 /* Find the largest power-of-two */ 427 /* Find the largest power-of-two */
441 while (temp_size & (temp_size - 1)) 428 temp_size = roundup_pow_of_two(temp_size);
442 temp_size &= (temp_size - 1);
443 429
444 /* Try and find a power of two to add */ 430 /* Try and find a power of two to add */
445 do { 431 do {
@@ -451,6 +437,34 @@ static int __init vesafb_probe(struct platform_device *dev)
451 } 437 }
452#endif 438#endif
453 439
440 switch (mtrr) {
441 case 1: /* uncachable */
442 info->screen_base = ioremap_nocache(vesafb_fix.smem_start, vesafb_fix.smem_len);
443 break;
444 case 2: /* write-back */
445 info->screen_base = ioremap_cache(vesafb_fix.smem_start, vesafb_fix.smem_len);
446 break;
447 case 3: /* write-combining */
448 info->screen_base = ioremap_wc(vesafb_fix.smem_start, vesafb_fix.smem_len);
449 break;
450 case 4: /* write-through */
451 default:
452 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
453 break;
454 }
455 if (!info->screen_base) {
456 printk(KERN_ERR
457 "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
458 vesafb_fix.smem_len, vesafb_fix.smem_start);
459 err = -EIO;
460 goto err;
461 }
462
463 printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
464 "using %dk, total %dk\n",
465 vesafb_fix.smem_start, info->screen_base,
466 size_remap/1024, size_total/1024);
467
454 info->fbops = &vesafb_ops; 468 info->fbops = &vesafb_ops;
455 info->var = vesafb_defined; 469 info->var = vesafb_defined;
456 info->fix = vesafb_fix; 470 info->fix = vesafb_fix;
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index a2965ab92cfb..f9b3e3dc2421 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -121,13 +121,19 @@ MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, d
121 121
122/* ------------------------------------------------------------------------- */ 122/* ------------------------------------------------------------------------- */
123 123
124static void vt8623fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
125{
126 struct vt8623fb_info *par = info->par;
127
128 svga_tilecursor(par->state.vgabase, info, cursor);
129}
124 130
125static struct fb_tile_ops vt8623fb_tile_ops = { 131static struct fb_tile_ops vt8623fb_tile_ops = {
126 .fb_settile = svga_settile, 132 .fb_settile = svga_settile,
127 .fb_tilecopy = svga_tilecopy, 133 .fb_tilecopy = svga_tilecopy,
128 .fb_tilefill = svga_tilefill, 134 .fb_tilefill = svga_tilefill,
129 .fb_tileblit = svga_tileblit, 135 .fb_tileblit = svga_tileblit,
130 .fb_tilecursor = svga_tilecursor, 136 .fb_tilecursor = vt8623fb_tilecursor,
131 .fb_get_tilemax = svga_get_tilemax, 137 .fb_get_tilemax = svga_get_tilemax,
132}; 138};
133 139
@@ -253,6 +259,7 @@ static void vt8623fb_fillrect(struct fb_info *info, const struct fb_fillrect *re
253 259
254static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock) 260static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
255{ 261{
262 struct vt8623fb_info *par = info->par;
256 u16 m, n, r; 263 u16 m, n, r;
257 u8 regval; 264 u8 regval;
258 int rv; 265 int rv;
@@ -264,18 +271,18 @@ static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
264 } 271 }
265 272
266 /* Set VGA misc register */ 273 /* Set VGA misc register */
267 regval = vga_r(NULL, VGA_MIS_R); 274 regval = vga_r(par->state.vgabase, VGA_MIS_R);
268 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 275 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
269 276
270 /* Set clock registers */ 277 /* Set clock registers */
271 vga_wseq(NULL, 0x46, (n | (r << 6))); 278 vga_wseq(par->state.vgabase, 0x46, (n | (r << 6)));
272 vga_wseq(NULL, 0x47, m); 279 vga_wseq(par->state.vgabase, 0x47, m);
273 280
274 udelay(1000); 281 udelay(1000);
275 282
276 /* PLL reset */ 283 /* PLL reset */
277 svga_wseq_mask(0x40, 0x02, 0x02); 284 svga_wseq_mask(par->state.vgabase, 0x40, 0x02, 0x02);
278 svga_wseq_mask(0x40, 0x00, 0x02); 285 svga_wseq_mask(par->state.vgabase, 0x40, 0x00, 0x02);
279} 286}
280 287
281 288
@@ -285,7 +292,10 @@ static int vt8623fb_open(struct fb_info *info, int user)
285 292
286 mutex_lock(&(par->open_lock)); 293 mutex_lock(&(par->open_lock));
287 if (par->ref_count == 0) { 294 if (par->ref_count == 0) {
295 void __iomem *vgabase = par->state.vgabase;
296
288 memset(&(par->state), 0, sizeof(struct vgastate)); 297 memset(&(par->state), 0, sizeof(struct vgastate));
298 par->state.vgabase = vgabase;
289 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 299 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
290 par->state.num_crtc = 0xA2; 300 par->state.num_crtc = 0xA2;
291 par->state.num_seq = 0x50; 301 par->state.num_seq = 0x50;
@@ -373,6 +383,7 @@ static int vt8623fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf
373static int vt8623fb_set_par(struct fb_info *info) 383static int vt8623fb_set_par(struct fb_info *info)
374{ 384{
375 u32 mode, offset_value, fetch_value, screen_size; 385 u32 mode, offset_value, fetch_value, screen_size;
386 struct vt8623fb_info *par = info->par;
376 u32 bpp = info->var.bits_per_pixel; 387 u32 bpp = info->var.bits_per_pixel;
377 388
378 if (bpp != 0) { 389 if (bpp != 0) {
@@ -414,82 +425,82 @@ static int vt8623fb_set_par(struct fb_info *info)
414 info->var.activate = FB_ACTIVATE_NOW; 425 info->var.activate = FB_ACTIVATE_NOW;
415 426
416 /* Unlock registers */ 427 /* Unlock registers */
417 svga_wseq_mask(0x10, 0x01, 0x01); 428 svga_wseq_mask(par->state.vgabase, 0x10, 0x01, 0x01);
418 svga_wcrt_mask(0x11, 0x00, 0x80); 429 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
419 svga_wcrt_mask(0x47, 0x00, 0x01); 430 svga_wcrt_mask(par->state.vgabase, 0x47, 0x00, 0x01);
420 431
421 /* Device, screen and sync off */ 432 /* Device, screen and sync off */
422 svga_wseq_mask(0x01, 0x20, 0x20); 433 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
423 svga_wcrt_mask(0x36, 0x30, 0x30); 434 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
424 svga_wcrt_mask(0x17, 0x00, 0x80); 435 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
425 436
426 /* Set default values */ 437 /* Set default values */
427 svga_set_default_gfx_regs(); 438 svga_set_default_gfx_regs(par->state.vgabase);
428 svga_set_default_atc_regs(); 439 svga_set_default_atc_regs(par->state.vgabase);
429 svga_set_default_seq_regs(); 440 svga_set_default_seq_regs(par->state.vgabase);
430 svga_set_default_crt_regs(); 441 svga_set_default_crt_regs(par->state.vgabase);
431 svga_wcrt_multi(vt8623_line_compare_regs, 0xFFFFFFFF); 442 svga_wcrt_multi(par->state.vgabase, vt8623_line_compare_regs, 0xFFFFFFFF);
432 svga_wcrt_multi(vt8623_start_address_regs, 0); 443 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, 0);
433 444
434 svga_wcrt_multi(vt8623_offset_regs, offset_value); 445 svga_wcrt_multi(par->state.vgabase, vt8623_offset_regs, offset_value);
435 svga_wseq_multi(vt8623_fetch_count_regs, fetch_value); 446 svga_wseq_multi(par->state.vgabase, vt8623_fetch_count_regs, fetch_value);
436 447
437 /* Clear H/V Skew */ 448 /* Clear H/V Skew */
438 svga_wcrt_mask(0x03, 0x00, 0x60); 449 svga_wcrt_mask(par->state.vgabase, 0x03, 0x00, 0x60);
439 svga_wcrt_mask(0x05, 0x00, 0x60); 450 svga_wcrt_mask(par->state.vgabase, 0x05, 0x00, 0x60);
440 451
441 if (info->var.vmode & FB_VMODE_DOUBLE) 452 if (info->var.vmode & FB_VMODE_DOUBLE)
442 svga_wcrt_mask(0x09, 0x80, 0x80); 453 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
443 else 454 else
444 svga_wcrt_mask(0x09, 0x00, 0x80); 455 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
445 456
446 svga_wseq_mask(0x1E, 0xF0, 0xF0); // DI/DVP bus 457 svga_wseq_mask(par->state.vgabase, 0x1E, 0xF0, 0xF0); // DI/DVP bus
447 svga_wseq_mask(0x2A, 0x0F, 0x0F); // DI/DVP bus 458 svga_wseq_mask(par->state.vgabase, 0x2A, 0x0F, 0x0F); // DI/DVP bus
448 svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read threshold 459 svga_wseq_mask(par->state.vgabase, 0x16, 0x08, 0xBF); // FIFO read threshold
449 vga_wseq(NULL, 0x17, 0x1F); // FIFO depth 460 vga_wseq(par->state.vgabase, 0x17, 0x1F); // FIFO depth
450 vga_wseq(NULL, 0x18, 0x4E); 461 vga_wseq(par->state.vgabase, 0x18, 0x4E);
451 svga_wseq_mask(0x1A, 0x08, 0x08); // enable MMIO ? 462 svga_wseq_mask(par->state.vgabase, 0x1A, 0x08, 0x08); // enable MMIO ?
452 463
453 vga_wcrt(NULL, 0x32, 0x00); 464 vga_wcrt(par->state.vgabase, 0x32, 0x00);
454 vga_wcrt(NULL, 0x34, 0x00); 465 vga_wcrt(par->state.vgabase, 0x34, 0x00);
455 vga_wcrt(NULL, 0x6A, 0x80); 466 vga_wcrt(par->state.vgabase, 0x6A, 0x80);
456 vga_wcrt(NULL, 0x6A, 0xC0); 467 vga_wcrt(par->state.vgabase, 0x6A, 0xC0);
457 468
458 vga_wgfx(NULL, 0x20, 0x00); 469 vga_wgfx(par->state.vgabase, 0x20, 0x00);
459 vga_wgfx(NULL, 0x21, 0x00); 470 vga_wgfx(par->state.vgabase, 0x21, 0x00);
460 vga_wgfx(NULL, 0x22, 0x00); 471 vga_wgfx(par->state.vgabase, 0x22, 0x00);
461 472
462 /* Set SR15 according to number of bits per pixel */ 473 /* Set SR15 according to number of bits per pixel */
463 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix)); 474 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix));
464 switch (mode) { 475 switch (mode) {
465 case 0: 476 case 0:
466 pr_debug("fb%d: text mode\n", info->node); 477 pr_debug("fb%d: text mode\n", info->node);
467 svga_set_textmode_vga_regs(); 478 svga_set_textmode_vga_regs(par->state.vgabase);
468 svga_wseq_mask(0x15, 0x00, 0xFE); 479 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
469 svga_wcrt_mask(0x11, 0x60, 0x70); 480 svga_wcrt_mask(par->state.vgabase, 0x11, 0x60, 0x70);
470 break; 481 break;
471 case 1: 482 case 1:
472 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 483 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
473 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 484 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
474 svga_wseq_mask(0x15, 0x20, 0xFE); 485 svga_wseq_mask(par->state.vgabase, 0x15, 0x20, 0xFE);
475 svga_wcrt_mask(0x11, 0x00, 0x70); 486 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
476 break; 487 break;
477 case 2: 488 case 2:
478 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 489 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
479 svga_wseq_mask(0x15, 0x00, 0xFE); 490 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
480 svga_wcrt_mask(0x11, 0x00, 0x70); 491 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
481 break; 492 break;
482 case 3: 493 case 3:
483 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 494 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
484 svga_wseq_mask(0x15, 0x22, 0xFE); 495 svga_wseq_mask(par->state.vgabase, 0x15, 0x22, 0xFE);
485 break; 496 break;
486 case 4: 497 case 4:
487 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 498 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
488 svga_wseq_mask(0x15, 0xB6, 0xFE); 499 svga_wseq_mask(par->state.vgabase, 0x15, 0xB6, 0xFE);
489 break; 500 break;
490 case 5: 501 case 5:
491 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 502 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
492 svga_wseq_mask(0x15, 0xAE, 0xFE); 503 svga_wseq_mask(par->state.vgabase, 0x15, 0xAE, 0xFE);
493 break; 504 break;
494 default: 505 default:
495 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n"); 506 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n");
@@ -497,16 +508,16 @@ static int vt8623fb_set_par(struct fb_info *info)
497 } 508 }
498 509
499 vt8623_set_pixclock(info, info->var.pixclock); 510 vt8623_set_pixclock(info, info->var.pixclock);
500 svga_set_timings(&vt8623_timing_regs, &(info->var), 1, 1, 511 svga_set_timings(par->state.vgabase, &vt8623_timing_regs, &(info->var), 1, 1,
501 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1, 512 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1,
502 1, info->node); 513 1, info->node);
503 514
504 memset_io(info->screen_base, 0x00, screen_size); 515 memset_io(info->screen_base, 0x00, screen_size);
505 516
506 /* Device and screen back on */ 517 /* Device and screen back on */
507 svga_wcrt_mask(0x17, 0x80, 0x80); 518 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
508 svga_wcrt_mask(0x36, 0x00, 0x30); 519 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
509 svga_wseq_mask(0x01, 0x00, 0x20); 520 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
510 521
511 return 0; 522 return 0;
512} 523}
@@ -569,31 +580,33 @@ static int vt8623fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
569 580
570static int vt8623fb_blank(int blank_mode, struct fb_info *info) 581static int vt8623fb_blank(int blank_mode, struct fb_info *info)
571{ 582{
583 struct vt8623fb_info *par = info->par;
584
572 switch (blank_mode) { 585 switch (blank_mode) {
573 case FB_BLANK_UNBLANK: 586 case FB_BLANK_UNBLANK:
574 pr_debug("fb%d: unblank\n", info->node); 587 pr_debug("fb%d: unblank\n", info->node);
575 svga_wcrt_mask(0x36, 0x00, 0x30); 588 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
576 svga_wseq_mask(0x01, 0x00, 0x20); 589 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
577 break; 590 break;
578 case FB_BLANK_NORMAL: 591 case FB_BLANK_NORMAL:
579 pr_debug("fb%d: blank\n", info->node); 592 pr_debug("fb%d: blank\n", info->node);
580 svga_wcrt_mask(0x36, 0x00, 0x30); 593 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
581 svga_wseq_mask(0x01, 0x20, 0x20); 594 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
582 break; 595 break;
583 case FB_BLANK_HSYNC_SUSPEND: 596 case FB_BLANK_HSYNC_SUSPEND:
584 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node); 597 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node);
585 svga_wcrt_mask(0x36, 0x10, 0x30); 598 svga_wcrt_mask(par->state.vgabase, 0x36, 0x10, 0x30);
586 svga_wseq_mask(0x01, 0x20, 0x20); 599 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
587 break; 600 break;
588 case FB_BLANK_VSYNC_SUSPEND: 601 case FB_BLANK_VSYNC_SUSPEND:
589 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node); 602 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node);
590 svga_wcrt_mask(0x36, 0x20, 0x30); 603 svga_wcrt_mask(par->state.vgabase, 0x36, 0x20, 0x30);
591 svga_wseq_mask(0x01, 0x20, 0x20); 604 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
592 break; 605 break;
593 case FB_BLANK_POWERDOWN: 606 case FB_BLANK_POWERDOWN:
594 pr_debug("fb%d: DPMS off (no sync)\n", info->node); 607 pr_debug("fb%d: DPMS off (no sync)\n", info->node);
595 svga_wcrt_mask(0x36, 0x30, 0x30); 608 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
596 svga_wseq_mask(0x01, 0x20, 0x20); 609 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
597 break; 610 break;
598 } 611 }
599 612
@@ -603,6 +616,7 @@ static int vt8623fb_blank(int blank_mode, struct fb_info *info)
603 616
604static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 617static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
605{ 618{
619 struct vt8623fb_info *par = info->par;
606 unsigned int offset; 620 unsigned int offset;
607 621
608 /* Calculate the offset */ 622 /* Calculate the offset */
@@ -616,7 +630,7 @@ static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *i
616 } 630 }
617 631
618 /* Set the offset */ 632 /* Set the offset */
619 svga_wcrt_multi(vt8623_start_address_regs, offset); 633 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, offset);
620 634
621 return 0; 635 return 0;
622} 636}
@@ -647,6 +661,8 @@ static struct fb_ops vt8623fb_ops = {
647 661
648static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 662static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
649{ 663{
664 struct pci_bus_region bus_reg;
665 struct resource vga_res;
650 struct fb_info *info; 666 struct fb_info *info;
651 struct vt8623fb_info *par; 667 struct vt8623fb_info *par;
652 unsigned int memsize1, memsize2; 668 unsigned int memsize1, memsize2;
@@ -705,9 +721,18 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
705 goto err_iomap_2; 721 goto err_iomap_2;
706 } 722 }
707 723
724 bus_reg.start = 0;
725 bus_reg.end = 64 * 1024;
726
727 vga_res.flags = IORESOURCE_IO;
728
729 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
730
731 par->state.vgabase = (void __iomem *) vga_res.start;
732
708 /* Find how many physical memory there is on card */ 733 /* Find how many physical memory there is on card */
709 memsize1 = (vga_rseq(NULL, 0x34) + 1) >> 1; 734 memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1;
710 memsize2 = vga_rseq(NULL, 0x39) << 2; 735 memsize2 = vga_rseq(par->state.vgabase, 0x39) << 2;
711 736
712 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2)) 737 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2))
713 info->screen_size = memsize1 << 20; 738 info->screen_size = memsize1 << 20;