aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig102
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/amba-clcd.c105
-rw-r--r--drivers/video/arkfb.c160
-rw-r--r--drivers/video/atmel_lcdfb.c32
-rw-r--r--drivers/video/aty/aty128fb.c1
-rw-r--r--drivers/video/aty/atyfb_base.c1
-rw-r--r--drivers/video/aty/radeon_backlight.c1
-rw-r--r--drivers/video/aty/radeon_base.c2
-rw-r--r--drivers/video/aty/radeon_i2c.c3
-rw-r--r--drivers/video/backlight/88pm860x_bl.c35
-rw-r--r--drivers/video/backlight/Kconfig18
-rw-r--r--drivers/video/backlight/Makefile3
-rw-r--r--drivers/video/backlight/adp5520_bl.c1
-rw-r--r--drivers/video/backlight/adp8860_bl.c1
-rw-r--r--drivers/video/backlight/adx_bl.c1
-rw-r--r--drivers/video/backlight/apple_bl.c241
-rw-r--r--drivers/video/backlight/atmel-pwm-bl.c1
-rw-r--r--drivers/video/backlight/backlight.c24
-rw-r--r--drivers/video/backlight/corgi_lcd.c1
-rw-r--r--drivers/video/backlight/cr_bllcd.c1
-rw-r--r--drivers/video/backlight/da903x_bl.c1
-rw-r--r--drivers/video/backlight/ep93xx_bl.c1
-rw-r--r--drivers/video/backlight/generic_bl.c1
-rw-r--r--drivers/video/backlight/hp680_bl.c1
-rw-r--r--drivers/video/backlight/jornada720_bl.c5
-rw-r--r--drivers/video/backlight/jornada720_lcd.c4
-rw-r--r--drivers/video/backlight/kb3886_bl.c1
-rw-r--r--drivers/video/backlight/ld9040.c819
-rw-r--r--drivers/video/backlight/ld9040_gamma.h200
-rw-r--r--drivers/video/backlight/locomolcd.c1
-rw-r--r--drivers/video/backlight/max8925_bl.c1
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c400
-rw-r--r--drivers/video/backlight/omap1_bl.c1
-rw-r--r--drivers/video/backlight/pcf50633-backlight.c1
-rw-r--r--drivers/video/backlight/progear_bl.c1
-rw-r--r--drivers/video/backlight/pwm_bl.c12
-rw-r--r--drivers/video/backlight/s6e63m0.c1
-rw-r--r--drivers/video/backlight/tosa_bl.c1
-rw-r--r--drivers/video/backlight/wm831x_bl.c1
-rw-r--r--drivers/video/bf54x-lq043fb.c1
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c1
-rw-r--r--drivers/video/bw2.c8
-rw-r--r--drivers/video/cg14.c9
-rw-r--r--drivers/video/cg3.c9
-rw-r--r--drivers/video/cg6.c10
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/console/tileblit.c2
-rw-r--r--drivers/video/cyber2000fb.c263
-rw-r--r--drivers/video/cyber2000fb.h16
-rw-r--r--drivers/video/edid.h4
-rw-r--r--drivers/video/fb-puv3.c846
-rw-r--r--drivers/video/ffb.c11
-rw-r--r--drivers/video/fsl-diu-fb.c9
-rw-r--r--drivers/video/hecubafb.c2
-rw-r--r--drivers/video/hpfb.c6
-rw-r--r--drivers/video/imxfb.c1
-rw-r--r--drivers/video/intelfb/Makefile5
-rw-r--r--drivers/video/leo.c9
-rw-r--r--drivers/video/matrox/matroxfb_base.c9
-rw-r--r--drivers/video/mb862xx/mb862xxfb.c9
-rw-r--r--drivers/video/metronomefb.c2
-rw-r--r--drivers/video/msm/mdp_hw.h11
-rw-r--r--drivers/video/msm/mdp_ppp.c1
-rw-r--r--drivers/video/msm/msm_fb.c27
-rw-r--r--drivers/video/mxsfb.c919
-rw-r--r--drivers/video/nvidia/nv_backlight.c1
-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-acx565akm.c1
-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-sharp-ls037v7dw01.c1
-rw-r--r--drivers/video/omap2/displays/panel-taal.c125
-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/p9100.c8
-rw-r--r--drivers/video/platinumfb.c9
-rw-r--r--drivers/video/riva/fbdev.c1
-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.c223
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h4
-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/sunxvr1000.c9
-rw-r--r--drivers/video/svgalib.c175
-rw-r--r--drivers/video/tcx.c10
-rw-r--r--drivers/video/tmiofb.c28
-rw-r--r--drivers/video/uvesafb.c51
-rw-r--r--drivers/video/vermilion/vermilion.c3
-rw-r--r--drivers/video/vesafb.c44
-rw-r--r--drivers/video/via/chip.h9
-rw-r--r--drivers/video/via/dvi.c4
-rw-r--r--drivers/video/via/hw.c772
-rw-r--r--drivers/video/via/hw.h2
-rw-r--r--drivers/video/via/lcd.c83
-rw-r--r--drivers/video/via/share.h141
-rw-r--r--drivers/video/via/tblDPASetting.c23
-rw-r--r--drivers/video/via/tblDPASetting.h2
-rw-r--r--drivers/video/via/via_i2c.c3
-rw-r--r--drivers/video/via/viafbdev.c6
-rw-r--r--drivers/video/via/viafbdev.h3
-rw-r--r--drivers/video/via/viamode.c507
-rw-r--r--drivers/video/via/viamode.h9
-rw-r--r--drivers/video/via/vt1636.c43
-rw-r--r--drivers/video/vt8623fb.c157
-rw-r--r--drivers/video/xilinxfb.c11
133 files changed, 9900 insertions, 3536 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6bafb51bb437..e6a8d8c0101d 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -322,69 +322,6 @@ config FB_ARMCLCD
322 here and read <file:Documentation/kbuild/modules.txt>. The module 322 here and read <file:Documentation/kbuild/modules.txt>. The module
323 will be called amba-clcd. 323 will be called amba-clcd.
324 324
325choice
326
327 depends on FB_ARMCLCD && (ARCH_LH7A40X || ARCH_LH7952X)
328 prompt "LCD Panel"
329 default FB_ARMCLCD_SHARP_LQ035Q7DB02
330
331config FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
332 bool "LogicPD LCD 3.5\" QVGA w/HRTFT IC"
333 help
334 This is an implementation of the Sharp LQ035Q7DB02, a 3.5"
335 color QVGA, HRTFT panel. The LogicPD device includes
336 an integrated HRTFT controller IC.
337 The native resolution is 240x320.
338
339config FB_ARMCLCD_SHARP_LQ057Q3DC02
340 bool "LogicPD LCD 5.7\" QVGA"
341 help
342 This is an implementation of the Sharp LQ057Q3DC02, a 5.7"
343 color QVGA, TFT panel. The LogicPD device includes an
344 The native resolution is 320x240.
345
346config FB_ARMCLCD_SHARP_LQ64D343
347 bool "LogicPD LCD 6.4\" VGA"
348 help
349 This is an implementation of the Sharp LQ64D343, a 6.4"
350 color VGA, TFT panel. The LogicPD device includes an
351 The native resolution is 640x480.
352
353config FB_ARMCLCD_SHARP_LQ10D368
354 bool "LogicPD LCD 10.4\" VGA"
355 help
356 This is an implementation of the Sharp LQ10D368, a 10.4"
357 color VGA, TFT panel. The LogicPD device includes an
358 The native resolution is 640x480.
359
360
361config FB_ARMCLCD_SHARP_LQ121S1DG41
362 bool "LogicPD LCD 12.1\" SVGA"
363 help
364 This is an implementation of the Sharp LQ121S1DG41, a 12.1"
365 color SVGA, TFT panel. The LogicPD device includes an
366 The native resolution is 800x600.
367
368 This panel requires a clock rate may be an integer fraction
369 of the base LCDCLK frequency. The driver will select the
370 highest frequency available that is lower than the maximum
371 allowed. The panel may flicker if the clock rate is
372 slower than the recommended minimum.
373
374config FB_ARMCLCD_AUO_A070VW01_WIDE
375 bool "AU Optronics A070VW01 LCD 7.0\" WIDE"
376 help
377 This is an implementation of the AU Optronics, a 7.0"
378 WIDE Color. The native resolution is 234x480.
379
380config FB_ARMCLCD_HITACHI
381 bool "Hitachi Wide Screen 800x480"
382 help
383 This is an implementation of the Hitachi 800x480.
384
385endchoice
386
387
388config FB_ACORN 325config FB_ACORN
389 bool "Acorn VIDC support" 326 bool "Acorn VIDC support"
390 depends on (FB = y) && ARM && ARCH_ACORN 327 depends on (FB = y) && ARM && ARCH_ACORN
@@ -439,6 +376,24 @@ config FB_CYBER2000
439 Say Y if you have a NetWinder or a graphics card containing this 376 Say Y if you have a NetWinder or a graphics card containing this
440 device, otherwise say N. 377 device, otherwise say N.
441 378
379config FB_CYBER2000_DDC
380 bool "DDC for CyberPro support"
381 depends on FB_CYBER2000
382 select FB_DDC
383 default y
384 help
385 Say Y here if you want DDC support for your CyberPro graphics
386 card. This is only I2C bus support, driver does not use EDID.
387
388config FB_CYBER2000_I2C
389 bool "CyberPro 2000/2010/5000 I2C support"
390 depends on FB_CYBER2000 && I2C && ARCH_NETWINDER
391 select I2C_ALGOBIT
392 help
393 Enable support for the I2C video decoder interface on the
394 Integraphics CyberPro 20x0 and 5000 VGA chips. This is used
395 on the Netwinder machines for the SAA7111 video capture.
396
442config FB_APOLLO 397config FB_APOLLO
443 bool 398 bool
444 depends on (FB = y) && APOLLO 399 depends on (FB = y) && APOLLO
@@ -2005,6 +1960,7 @@ config FB_SH_MOBILE_LCDC
2005 select FB_SYS_IMAGEBLIT 1960 select FB_SYS_IMAGEBLIT
2006 select FB_SYS_FOPS 1961 select FB_SYS_FOPS
2007 select FB_DEFERRED_IO 1962 select FB_DEFERRED_IO
1963 select FB_BACKLIGHT
2008 select SH_MIPI_DSI if SH_LCD_MIPI_DSI 1964 select SH_MIPI_DSI if SH_LCD_MIPI_DSI
2009 ---help--- 1965 ---help---
2010 Frame buffer driver for the on-chip SH-Mobile LCD controller. 1966 Frame buffer driver for the on-chip SH-Mobile LCD controller.
@@ -2365,6 +2321,26 @@ config FB_JZ4740
2365 help 2321 help
2366 Framebuffer support for the JZ4740 SoC. 2322 Framebuffer support for the JZ4740 SoC.
2367 2323
2324config FB_MXS
2325 tristate "MXS LCD framebuffer support"
2326 depends on FB && ARCH_MXS
2327 select FB_CFB_FILLRECT
2328 select FB_CFB_COPYAREA
2329 select FB_CFB_IMAGEBLIT
2330 help
2331 Framebuffer support for the MXS SoC.
2332
2333config FB_PUV3_UNIGFX
2334 tristate "PKUnity v3 Unigfx framebuffer support"
2335 depends on FB && UNICORE32 && ARCH_PUV3
2336 select FB_SYS_FILLRECT
2337 select FB_SYS_COPYAREA
2338 select FB_SYS_IMAGEBLIT
2339 select FB_SYS_FOPS
2340 help
2341 Choose this option if you want to use the Unigfx device as a
2342 framebuffer device. Without the support of PCI & AGP.
2343
2368source "drivers/video/omap/Kconfig" 2344source "drivers/video/omap/Kconfig"
2369source "drivers/video/omap2/Kconfig" 2345source "drivers/video/omap2/Kconfig"
2370 2346
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 8c8fabdff9d0..2ea44b6625fe 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -139,6 +139,7 @@ obj-$(CONFIG_FB_MB862XX) += mb862xx/
139obj-$(CONFIG_FB_MSM) += msm/ 139obj-$(CONFIG_FB_MSM) += msm/
140obj-$(CONFIG_FB_NUC900) += nuc900fb.o 140obj-$(CONFIG_FB_NUC900) += nuc900fb.o
141obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o 141obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
142obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
142 143
143# Platform or fallback drivers go here 144# Platform or fallback drivers go here
144obj-$(CONFIG_FB_UVESA) += uvesafb.o 145obj-$(CONFIG_FB_UVESA) += uvesafb.o
@@ -153,6 +154,7 @@ obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o
153obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o 154obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o
154obj-$(CONFIG_FB_MX3) += mx3fb.o 155obj-$(CONFIG_FB_MX3) += mx3fb.o
155obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o 156obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
157obj-$(CONFIG_FB_MXS) += mxsfb.o
156 158
157# the test framebuffer is last 159# the test framebuffer is last
158obj-$(CONFIG_FB_VIRTUAL) += vfb.o 160obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 1c2c68356ea7..5fc983c5b92c 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -120,8 +120,23 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
120static int 120static int
121clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) 121clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
122{ 122{
123 u32 caps;
123 int ret = 0; 124 int ret = 0;
124 125
126 if (fb->panel->caps && fb->board->caps)
127 caps = fb->panel->caps & fb->board->caps;
128 else {
129 /* Old way of specifying what can be used */
130 caps = fb->panel->cntl & CNTL_BGR ?
131 CLCD_CAP_BGR : CLCD_CAP_RGB;
132 /* But mask out 444 modes as they weren't supported */
133 caps &= ~CLCD_CAP_444;
134 }
135
136 /* Only TFT panels can do RGB888/BGR888 */
137 if (!(fb->panel->cntl & CNTL_LCDTFT))
138 caps &= ~CLCD_CAP_888;
139
125 memset(&var->transp, 0, sizeof(var->transp)); 140 memset(&var->transp, 0, sizeof(var->transp));
126 141
127 var->red.msb_right = 0; 142 var->red.msb_right = 0;
@@ -133,6 +148,13 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
133 case 2: 148 case 2:
134 case 4: 149 case 4:
135 case 8: 150 case 8:
151 /* If we can't do 5551, reject */
152 caps &= CLCD_CAP_5551;
153 if (!caps) {
154 ret = -EINVAL;
155 break;
156 }
157
136 var->red.length = var->bits_per_pixel; 158 var->red.length = var->bits_per_pixel;
137 var->red.offset = 0; 159 var->red.offset = 0;
138 var->green.length = var->bits_per_pixel; 160 var->green.length = var->bits_per_pixel;
@@ -140,23 +162,61 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
140 var->blue.length = var->bits_per_pixel; 162 var->blue.length = var->bits_per_pixel;
141 var->blue.offset = 0; 163 var->blue.offset = 0;
142 break; 164 break;
165
143 case 16: 166 case 16:
144 var->red.length = 5; 167 /* If we can't do 444, 5551 or 565, reject */
145 var->blue.length = 5; 168 if (!(caps & (CLCD_CAP_444 | CLCD_CAP_5551 | CLCD_CAP_565))) {
169 ret = -EINVAL;
170 break;
171 }
172
146 /* 173 /*
147 * Green length can be 5 or 6 depending whether 174 * Green length can be 4, 5 or 6 depending whether
148 * we're operating in RGB555 or RGB565 mode. 175 * we're operating in 444, 5551 or 565 mode.
149 */ 176 */
150 if (var->green.length != 5 && var->green.length != 6) 177 if (var->green.length == 4 && caps & CLCD_CAP_444)
151 var->green.length = 6; 178 caps &= CLCD_CAP_444;
179 if (var->green.length == 5 && caps & CLCD_CAP_5551)
180 caps &= CLCD_CAP_5551;
181 else if (var->green.length == 6 && caps & CLCD_CAP_565)
182 caps &= CLCD_CAP_565;
183 else {
184 /*
185 * PL110 officially only supports RGB555,
186 * but may be wired up to allow RGB565.
187 */
188 if (caps & CLCD_CAP_565) {
189 var->green.length = 6;
190 caps &= CLCD_CAP_565;
191 } else if (caps & CLCD_CAP_5551) {
192 var->green.length = 5;
193 caps &= CLCD_CAP_5551;
194 } else {
195 var->green.length = 4;
196 caps &= CLCD_CAP_444;
197 }
198 }
199
200 if (var->green.length >= 5) {
201 var->red.length = 5;
202 var->blue.length = 5;
203 } else {
204 var->red.length = 4;
205 var->blue.length = 4;
206 }
152 break; 207 break;
153 case 32: 208 case 32:
154 if (fb->panel->cntl & CNTL_LCDTFT) { 209 /* If we can't do 888, reject */
155 var->red.length = 8; 210 caps &= CLCD_CAP_888;
156 var->green.length = 8; 211 if (!caps) {
157 var->blue.length = 8; 212 ret = -EINVAL;
158 break; 213 break;
159 } 214 }
215
216 var->red.length = 8;
217 var->green.length = 8;
218 var->blue.length = 8;
219 break;
160 default: 220 default:
161 ret = -EINVAL; 221 ret = -EINVAL;
162 break; 222 break;
@@ -168,7 +228,20 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
168 * the bitfield length defined above. 228 * the bitfield length defined above.
169 */ 229 */
170 if (ret == 0 && var->bits_per_pixel >= 16) { 230 if (ret == 0 && var->bits_per_pixel >= 16) {
171 if (fb->panel->cntl & CNTL_BGR) { 231 bool bgr, rgb;
232
233 bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0;
234 rgb = caps & CLCD_CAP_RGB && var->red.offset == 0;
235
236 if (!bgr && !rgb)
237 /*
238 * The requested format was not possible, try just
239 * our capabilities. One of BGR or RGB must be
240 * supported.
241 */
242 bgr = caps & CLCD_CAP_BGR;
243
244 if (bgr) {
172 var->blue.offset = 0; 245 var->blue.offset = 0;
173 var->green.offset = var->blue.offset + var->blue.length; 246 var->green.offset = var->blue.offset + var->blue.length;
174 var->red.offset = var->green.offset + var->green.length; 247 var->red.offset = var->green.offset + var->green.length;
@@ -443,8 +516,8 @@ static int clcdfb_register(struct clcd_fb *fb)
443 516
444 fb_set_var(&fb->fb, &fb->fb.var); 517 fb_set_var(&fb->fb, &fb->fb.var);
445 518
446 printk(KERN_INFO "CLCD: %s hardware, %s display\n", 519 dev_info(&fb->dev->dev, "%s hardware, %s display\n",
447 fb->board->name, fb->panel->mode.name); 520 fb->board->name, fb->panel->mode.name);
448 521
449 ret = register_framebuffer(&fb->fb); 522 ret = register_framebuffer(&fb->fb);
450 if (ret == 0) 523 if (ret == 0)
@@ -461,7 +534,7 @@ static int clcdfb_register(struct clcd_fb *fb)
461 return ret; 534 return ret;
462} 535}
463 536
464static int clcdfb_probe(struct amba_device *dev, struct amba_id *id) 537static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
465{ 538{
466 struct clcd_board *board = dev->dev.platform_data; 539 struct clcd_board *board = dev->dev.platform_data;
467 struct clcd_fb *fb; 540 struct clcd_fb *fb;
@@ -486,6 +559,10 @@ static int clcdfb_probe(struct amba_device *dev, struct amba_id *id)
486 fb->dev = dev; 559 fb->dev = dev;
487 fb->board = board; 560 fb->board = board;
488 561
562 dev_info(&fb->dev->dev, "PL%03x rev%u at 0x%08llx\n",
563 amba_part(dev), amba_rev(dev),
564 (unsigned long long)dev->res.start);
565
489 ret = fb->board->setup(fb); 566 ret = fb->board->setup(fb);
490 if (ret) 567 if (ret)
491 goto free_fb; 568 goto free_fb;
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 bac163450216..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
@@ -127,6 +127,7 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo)
127 return; 127 return;
128 128
129 memset(&props, 0, sizeof(struct backlight_properties)); 129 memset(&props, 0, sizeof(struct backlight_properties));
130 props.type = BACKLIGHT_RAW;
130 props.max_brightness = 0xff; 131 props.max_brightness = 0xff;
131 bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo, 132 bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo,
132 &atmel_lcdc_bl_ops, &props); 133 &atmel_lcdc_bl_ops, &props);
@@ -163,6 +164,10 @@ static void exit_backlight(struct atmel_lcdfb_info *sinfo)
163 164
164static void init_contrast(struct atmel_lcdfb_info *sinfo) 165static void init_contrast(struct atmel_lcdfb_info *sinfo)
165{ 166{
167 /* contrast pwm can be 'inverted' */
168 if (sinfo->lcdcon_pol_negative)
169 contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
170
166 /* have some default contrast/backlight settings */ 171 /* have some default contrast/backlight settings */
167 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); 172 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
168 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); 173 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
@@ -710,11 +715,35 @@ static int atmel_lcdfb_pan_display(struct fb_var_screeninfo *var,
710 return 0; 715 return 0;
711} 716}
712 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
713static struct fb_ops atmel_lcdfb_ops = { 741static struct fb_ops atmel_lcdfb_ops = {
714 .owner = THIS_MODULE, 742 .owner = THIS_MODULE,
715 .fb_check_var = atmel_lcdfb_check_var, 743 .fb_check_var = atmel_lcdfb_check_var,
716 .fb_set_par = atmel_lcdfb_set_par, 744 .fb_set_par = atmel_lcdfb_set_par,
717 .fb_setcolreg = atmel_lcdfb_setcolreg, 745 .fb_setcolreg = atmel_lcdfb_setcolreg,
746 .fb_blank = atmel_lcdfb_blank,
718 .fb_pan_display = atmel_lcdfb_pan_display, 747 .fb_pan_display = atmel_lcdfb_pan_display,
719 .fb_fillrect = cfb_fillrect, 748 .fb_fillrect = cfb_fillrect,
720 .fb_copyarea = cfb_copyarea, 749 .fb_copyarea = cfb_copyarea,
@@ -816,6 +845,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
816 sinfo->guard_time = pdata_sinfo->guard_time; 845 sinfo->guard_time = pdata_sinfo->guard_time;
817 sinfo->smem_len = pdata_sinfo->smem_len; 846 sinfo->smem_len = pdata_sinfo->smem_len;
818 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;
819 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode; 849 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
820 } else { 850 } else {
821 dev_err(dev, "cannot get default configuration\n"); 851 dev_err(dev, "cannot get default configuration\n");
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 4cb6a576c567..b0b2ac335347 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1818,6 +1818,7 @@ static void aty128_bl_init(struct aty128fb_par *par)
1818 snprintf(name, sizeof(name), "aty128bl%d", info->node); 1818 snprintf(name, sizeof(name), "aty128bl%d", info->node);
1819 1819
1820 memset(&props, 0, sizeof(struct backlight_properties)); 1820 memset(&props, 0, sizeof(struct backlight_properties));
1821 props.type = BACKLIGHT_RAW;
1821 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 1822 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
1822 bd = backlight_device_register(name, info->dev, par, &aty128_bl_data, 1823 bd = backlight_device_register(name, info->dev, par, &aty128_bl_data,
1823 &props); 1824 &props);
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 94e293fce1d2..d437b3daf1f5 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2241,6 +2241,7 @@ static void aty_bl_init(struct atyfb_par *par)
2241 snprintf(name, sizeof(name), "atybl%d", info->node); 2241 snprintf(name, sizeof(name), "atybl%d", info->node);
2242 2242
2243 memset(&props, 0, sizeof(struct backlight_properties)); 2243 memset(&props, 0, sizeof(struct backlight_properties));
2244 props.type = BACKLIGHT_RAW;
2244 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 2245 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
2245 bd = backlight_device_register(name, info->dev, par, &aty_bl_data, 2246 bd = backlight_device_register(name, info->dev, par, &aty_bl_data,
2246 &props); 2247 &props);
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 9b811ddbce83..db572df7e1ef 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -158,6 +158,7 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
158 snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node); 158 snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
159 159
160 memset(&props, 0, sizeof(struct backlight_properties)); 160 memset(&props, 0, sizeof(struct backlight_properties));
161 props.type = BACKLIGHT_RAW;
161 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 162 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
162 bd = backlight_device_register(name, rinfo->info->dev, pdata, 163 bd = backlight_device_register(name, rinfo->info->dev, pdata,
163 &radeon_bl_data, &props); 164 &radeon_bl_data, &props);
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/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index b224396b86d5..c8b520e9a11a 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -12,11 +12,12 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/slab.h>
15#include <linux/fb.h> 16#include <linux/fb.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/backlight.h> 18#include <linux/backlight.h>
19#include <linux/mfd/core.h>
18#include <linux/mfd/88pm860x.h> 20#include <linux/mfd/88pm860x.h>
19#include <linux/slab.h>
20 21
21#define MAX_BRIGHTNESS (0xFF) 22#define MAX_BRIGHTNESS (0xFF)
22#define MIN_BRIGHTNESS (0) 23#define MIN_BRIGHTNESS (0)
@@ -161,32 +162,13 @@ static const struct backlight_ops pm860x_backlight_ops = {
161 .get_brightness = pm860x_backlight_get_brightness, 162 .get_brightness = pm860x_backlight_get_brightness,
162}; 163};
163 164
164static int __check_device(struct pm860x_backlight_pdata *pdata, char *name)
165{
166 struct pm860x_backlight_pdata *p = pdata;
167 int ret = -EINVAL;
168
169 while (p && p->id) {
170 if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0))
171 break;
172
173 if (!strncmp(name, pm860x_backlight_name[p->flags],
174 MFD_NAME_SIZE)) {
175 ret = (int)p->flags;
176 break;
177 }
178 p++;
179 }
180 return ret;
181}
182
183static int pm860x_backlight_probe(struct platform_device *pdev) 165static int pm860x_backlight_probe(struct platform_device *pdev)
184{ 166{
185 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 167 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
186 struct pm860x_platform_data *pm860x_pdata;
187 struct pm860x_backlight_pdata *pdata = NULL; 168 struct pm860x_backlight_pdata *pdata = NULL;
188 struct pm860x_backlight_data *data; 169 struct pm860x_backlight_data *data;
189 struct backlight_device *bl; 170 struct backlight_device *bl;
171 struct mfd_cell *cell;
190 struct resource *res; 172 struct resource *res;
191 struct backlight_properties props; 173 struct backlight_properties props;
192 unsigned char value; 174 unsigned char value;
@@ -199,10 +181,10 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
199 return -EINVAL; 181 return -EINVAL;
200 } 182 }
201 183
202 if (pdev->dev.parent->platform_data) { 184 cell = pdev->dev.platform_data;
203 pm860x_pdata = pdev->dev.parent->platform_data; 185 if (cell == NULL)
204 pdata = pm860x_pdata->backlight; 186 return -ENODEV;
205 } 187 pdata = cell->mfd_data;
206 if (pdata == NULL) { 188 if (pdata == NULL) {
207 dev_err(&pdev->dev, "platform data isn't assigned to " 189 dev_err(&pdev->dev, "platform data isn't assigned to "
208 "backlight\n"); 190 "backlight\n");
@@ -219,7 +201,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
219 data->current_brightness = MAX_BRIGHTNESS; 201 data->current_brightness = MAX_BRIGHTNESS;
220 data->pwm = pdata->pwm; 202 data->pwm = pdata->pwm;
221 data->iset = pdata->iset; 203 data->iset = pdata->iset;
222 data->port = __check_device(pdata, name); 204 data->port = pdata->flags;
223 if (data->port < 0) { 205 if (data->port < 0) {
224 dev_err(&pdev->dev, "wrong platform data is assigned"); 206 dev_err(&pdev->dev, "wrong platform data is assigned");
225 kfree(data); 207 kfree(data);
@@ -227,6 +209,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
227 } 209 }
228 210
229 memset(&props, 0, sizeof(struct backlight_properties)); 211 memset(&props, 0, sizeof(struct backlight_properties));
212 props.type = BACKLIGHT_RAW;
230 props.max_brightness = MAX_BRIGHTNESS; 213 props.max_brightness = MAX_BRIGHTNESS;
231 bl = backlight_device_register(name, &pdev->dev, data, 214 bl = backlight_device_register(name, &pdev->dev, data,
232 &pm860x_backlight_ops, &props); 215 &pm860x_backlight_ops, &props);
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index e54a337227ea..0c9373bedd1f 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -109,6 +109,14 @@ config LCD_S6E63M0
109 If you have an S6E63M0 LCD Panel, say Y to enable its 109 If you have an S6E63M0 LCD Panel, say Y to enable its
110 LCD control driver. 110 LCD control driver.
111 111
112config LCD_LD9040
113 tristate "LD9040 AMOLED LCD Driver"
114 depends on SPI && BACKLIGHT_CLASS_DEVICE
115 default n
116 help
117 If you have an LD9040 Panel, say Y to enable its
118 control driver.
119
112endif # LCD_CLASS_DEVICE 120endif # LCD_CLASS_DEVICE
113 121
114# 122#
@@ -236,12 +244,12 @@ config BACKLIGHT_MAX8925
236 If you have a LCD backlight connected to the WLED output of MAX8925 244 If you have a LCD backlight connected to the WLED output of MAX8925
237 WLED output, say Y here to enable this driver. 245 WLED output, say Y here to enable this driver.
238 246
239config BACKLIGHT_MBP_NVIDIA 247config BACKLIGHT_APPLE
240 tristate "MacBook Pro Nvidia Backlight Driver" 248 tristate "Apple Backlight Driver"
241 depends on X86 249 depends on X86 && ACPI
242 help 250 help
243 If you have an Apple Macbook Pro with Nvidia graphics hardware say Y 251 If you have an Intel-based Apple say Y to enable a driver for its
244 to enable a driver for its backlight 252 backlight.
245 253
246config BACKLIGHT_TOSA 254config BACKLIGHT_TOSA
247 tristate "Sharp SL-6000 Backlight Driver" 255 tristate "Sharp SL-6000 Backlight Driver"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 44c0f81ad85d..b9ca8490df87 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
12obj-$(CONFIG_LCD_TDO24M) += tdo24m.o 12obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
13obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o 13obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
14obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o 14obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o
15obj-$(CONFIG_LCD_LD9040) += ld9040.o
15 16
16obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 17obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
17obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o 18obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
@@ -26,7 +27,7 @@ obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
26obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o 27obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
27obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o 28obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
28obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o 29obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
29obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o 30obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
30obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o 31obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
31obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o 32obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
32obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o 33obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index 9f436e014f85..af3119707dbf 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -303,6 +303,7 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
303 mutex_init(&data->lock); 303 mutex_init(&data->lock);
304 304
305 memset(&props, 0, sizeof(struct backlight_properties)); 305 memset(&props, 0, sizeof(struct backlight_properties));
306 props.type = BACKLIGHT_RAW;
306 props.max_brightness = ADP5020_MAX_BRIGHTNESS; 307 props.max_brightness = ADP5020_MAX_BRIGHTNESS;
307 bl = backlight_device_register(pdev->name, data->master, data, 308 bl = backlight_device_register(pdev->name, data->master, data,
308 &adp5520_bl_ops, &props); 309 &adp5520_bl_ops, &props);
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 734c650a47c4..d2a96a421ffd 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -709,6 +709,7 @@ static int __devinit adp8860_probe(struct i2c_client *client,
709 i2c_set_clientdata(client, data); 709 i2c_set_clientdata(client, data);
710 710
711 memset(&props, 0, sizeof(props)); 711 memset(&props, 0, sizeof(props));
712 props.type = BACKLIGHT_RAW;
712 props.max_brightness = ADP8860_MAX_BRIGHTNESS; 713 props.max_brightness = ADP8860_MAX_BRIGHTNESS;
713 714
714 mutex_init(&data->lock); 715 mutex_init(&data->lock);
diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c
index fe9af129c5dd..c861c41af442 100644
--- a/drivers/video/backlight/adx_bl.c
+++ b/drivers/video/backlight/adx_bl.c
@@ -104,6 +104,7 @@ static int __devinit adx_backlight_probe(struct platform_device *pdev)
104 } 104 }
105 105
106 memset(&props, 0, sizeof(struct backlight_properties)); 106 memset(&props, 0, sizeof(struct backlight_properties));
107 props.type = BACKLIGHT_RAW;
107 props.max_brightness = 0xff; 108 props.max_brightness = 0xff;
108 bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, 109 bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
109 bl, &adx_backlight_ops, &props); 110 bl, &adx_backlight_ops, &props);
diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c
new file mode 100644
index 000000000000..be98d152b7fd
--- /dev/null
+++ b/drivers/video/backlight/apple_bl.c
@@ -0,0 +1,241 @@
1/*
2 * Backlight Driver for Intel-based Apples
3 *
4 * Copyright (c) Red Hat <mjg@redhat.com>
5 * Based on code from Pommed:
6 * Copyright (C) 2006 Nicolas Boichat <nicolas @boichat.ch>
7 * Copyright (C) 2006 Felipe Alfaro Solana <felipe_alfaro @linuxmail.org>
8 * Copyright (C) 2007 Julien BLACHE <jb@jblache.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This driver triggers SMIs which cause the firmware to change the
15 * backlight brightness. This is icky in many ways, but it's impractical to
16 * get at the firmware code in order to figure out what it's actually doing.
17 */
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/backlight.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/pci.h>
26#include <linux/acpi.h>
27
28static struct backlight_device *apple_backlight_device;
29
30struct hw_data {
31 /* I/O resource to allocate. */
32 unsigned long iostart;
33 unsigned long iolen;
34 /* Backlight operations structure. */
35 const struct backlight_ops backlight_ops;
36 void (*set_brightness)(int);
37};
38
39static const struct hw_data *hw_data;
40
41#define DRIVER "apple_backlight: "
42
43/* Module parameters. */
44static int debug;
45module_param_named(debug, debug, int, 0644);
46MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
47
48/*
49 * Implementation for machines with Intel chipset.
50 */
51static void intel_chipset_set_brightness(int intensity)
52{
53 outb(0x04 | (intensity << 4), 0xb3);
54 outb(0xbf, 0xb2);
55}
56
57static int intel_chipset_send_intensity(struct backlight_device *bd)
58{
59 int intensity = bd->props.brightness;
60
61 if (debug)
62 printk(KERN_DEBUG DRIVER "setting brightness to %d\n",
63 intensity);
64
65 intel_chipset_set_brightness(intensity);
66 return 0;
67}
68
69static int intel_chipset_get_intensity(struct backlight_device *bd)
70{
71 int intensity;
72
73 outb(0x03, 0xb3);
74 outb(0xbf, 0xb2);
75 intensity = inb(0xb3) >> 4;
76
77 if (debug)
78 printk(KERN_DEBUG DRIVER "read brightness of %d\n",
79 intensity);
80
81 return intensity;
82}
83
84static const struct hw_data intel_chipset_data = {
85 .iostart = 0xb2,
86 .iolen = 2,
87 .backlight_ops = {
88 .options = BL_CORE_SUSPENDRESUME,
89 .get_brightness = intel_chipset_get_intensity,
90 .update_status = intel_chipset_send_intensity,
91 },
92 .set_brightness = intel_chipset_set_brightness,
93};
94
95/*
96 * Implementation for machines with Nvidia chipset.
97 */
98static void nvidia_chipset_set_brightness(int intensity)
99{
100 outb(0x04 | (intensity << 4), 0x52f);
101 outb(0xbf, 0x52e);
102}
103
104static int nvidia_chipset_send_intensity(struct backlight_device *bd)
105{
106 int intensity = bd->props.brightness;
107
108 if (debug)
109 printk(KERN_DEBUG DRIVER "setting brightness to %d\n",
110 intensity);
111
112 nvidia_chipset_set_brightness(intensity);
113 return 0;
114}
115
116static int nvidia_chipset_get_intensity(struct backlight_device *bd)
117{
118 int intensity;
119
120 outb(0x03, 0x52f);
121 outb(0xbf, 0x52e);
122 intensity = inb(0x52f) >> 4;
123
124 if (debug)
125 printk(KERN_DEBUG DRIVER "read brightness of %d\n",
126 intensity);
127
128 return intensity;
129}
130
131static const struct hw_data nvidia_chipset_data = {
132 .iostart = 0x52e,
133 .iolen = 2,
134 .backlight_ops = {
135 .options = BL_CORE_SUSPENDRESUME,
136 .get_brightness = nvidia_chipset_get_intensity,
137 .update_status = nvidia_chipset_send_intensity
138 },
139 .set_brightness = nvidia_chipset_set_brightness,
140};
141
142static int __devinit apple_bl_add(struct acpi_device *dev)
143{
144 struct backlight_properties props;
145 struct pci_dev *host;
146 int intensity;
147
148 host = pci_get_bus_and_slot(0, 0);
149
150 if (!host) {
151 printk(KERN_ERR DRIVER "unable to find PCI host\n");
152 return -ENODEV;
153 }
154
155 if (host->vendor == PCI_VENDOR_ID_INTEL)
156 hw_data = &intel_chipset_data;
157 else if (host->vendor == PCI_VENDOR_ID_NVIDIA)
158 hw_data = &nvidia_chipset_data;
159
160 pci_dev_put(host);
161
162 if (!hw_data) {
163 printk(KERN_ERR DRIVER "unknown hardware\n");
164 return -ENODEV;
165 }
166
167 /* Check that the hardware responds - this may not work under EFI */
168
169 intensity = hw_data->backlight_ops.get_brightness(NULL);
170
171 if (!intensity) {
172 hw_data->set_brightness(1);
173 if (!hw_data->backlight_ops.get_brightness(NULL))
174 return -ENODEV;
175
176 hw_data->set_brightness(0);
177 }
178
179 if (!request_region(hw_data->iostart, hw_data->iolen,
180 "Apple backlight"))
181 return -ENXIO;
182
183 memset(&props, 0, sizeof(struct backlight_properties));
184 props.type = BACKLIGHT_PLATFORM;
185 props.max_brightness = 15;
186 apple_backlight_device = backlight_device_register("apple_backlight",
187 NULL, NULL, &hw_data->backlight_ops, &props);
188
189 if (IS_ERR(apple_backlight_device)) {
190 release_region(hw_data->iostart, hw_data->iolen);
191 return PTR_ERR(apple_backlight_device);
192 }
193
194 apple_backlight_device->props.brightness =
195 hw_data->backlight_ops.get_brightness(apple_backlight_device);
196 backlight_update_status(apple_backlight_device);
197
198 return 0;
199}
200
201static int __devexit apple_bl_remove(struct acpi_device *dev, int type)
202{
203 backlight_device_unregister(apple_backlight_device);
204
205 release_region(hw_data->iostart, hw_data->iolen);
206 hw_data = NULL;
207 return 0;
208}
209
210static const struct acpi_device_id apple_bl_ids[] = {
211 {"APP0002", 0},
212 {"", 0},
213};
214
215static struct acpi_driver apple_bl_driver = {
216 .name = "Apple backlight",
217 .ids = apple_bl_ids,
218 .ops = {
219 .add = apple_bl_add,
220 .remove = apple_bl_remove,
221 },
222};
223
224static int __init apple_bl_init(void)
225{
226 return acpi_bus_register_driver(&apple_bl_driver);
227}
228
229static void __exit apple_bl_exit(void)
230{
231 acpi_bus_unregister_driver(&apple_bl_driver);
232}
233
234module_init(apple_bl_init);
235module_exit(apple_bl_exit);
236
237MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
238MODULE_DESCRIPTION("Apple Backlight Driver");
239MODULE_LICENSE("GPL");
240MODULE_DEVICE_TABLE(acpi, apple_bl_ids);
241MODULE_ALIAS("mbp_nvidia_bl");
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index e6a66dab088c..0443a4f71858 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -168,6 +168,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
168 } 168 }
169 169
170 memset(&props, 0, sizeof(struct backlight_properties)); 170 memset(&props, 0, sizeof(struct backlight_properties));
171 props.type = BACKLIGHT_RAW;
171 props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; 172 props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
172 bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl, 173 bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl,
173 &atmel_pwm_bl_ops, &props); 174 &atmel_pwm_bl_ops, &props);
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 08703299ef61..80d292fb92d8 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -19,6 +19,12 @@
19#include <asm/backlight.h> 19#include <asm/backlight.h>
20#endif 20#endif
21 21
22static const char const *backlight_types[] = {
23 [BACKLIGHT_RAW] = "raw",
24 [BACKLIGHT_PLATFORM] = "platform",
25 [BACKLIGHT_FIRMWARE] = "firmware",
26};
27
22#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ 28#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
23 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)) 29 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
24/* This callback gets called when something important happens inside a 30/* This callback gets called when something important happens inside a
@@ -169,6 +175,14 @@ static ssize_t backlight_store_brightness(struct device *dev,
169 return rc; 175 return rc;
170} 176}
171 177
178static ssize_t backlight_show_type(struct device *dev,
179 struct device_attribute *attr, char *buf)
180{
181 struct backlight_device *bd = to_backlight_device(dev);
182
183 return sprintf(buf, "%s\n", backlight_types[bd->props.type]);
184}
185
172static ssize_t backlight_show_max_brightness(struct device *dev, 186static ssize_t backlight_show_max_brightness(struct device *dev,
173 struct device_attribute *attr, char *buf) 187 struct device_attribute *attr, char *buf)
174{ 188{
@@ -234,6 +248,7 @@ static struct device_attribute bl_device_attributes[] = {
234 __ATTR(actual_brightness, 0444, backlight_show_actual_brightness, 248 __ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
235 NULL), 249 NULL),
236 __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), 250 __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
251 __ATTR(type, 0444, backlight_show_type, NULL),
237 __ATTR_NULL, 252 __ATTR_NULL,
238}; 253};
239 254
@@ -292,9 +307,16 @@ struct backlight_device *backlight_device_register(const char *name,
292 dev_set_drvdata(&new_bd->dev, devdata); 307 dev_set_drvdata(&new_bd->dev, devdata);
293 308
294 /* Set default properties */ 309 /* Set default properties */
295 if (props) 310 if (props) {
296 memcpy(&new_bd->props, props, 311 memcpy(&new_bd->props, props,
297 sizeof(struct backlight_properties)); 312 sizeof(struct backlight_properties));
313 if (props->type <= 0 || props->type >= BACKLIGHT_TYPE_MAX) {
314 WARN(1, "%s: invalid backlight type", name);
315 new_bd->props.type = BACKLIGHT_RAW;
316 }
317 } else {
318 new_bd->props.type = BACKLIGHT_RAW;
319 }
298 320
299 rc = device_register(&new_bd->dev); 321 rc = device_register(&new_bd->dev);
300 if (rc) { 322 if (rc) {
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index 1e71c35083bb..af6098396fe6 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -562,6 +562,7 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi)
562 lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA; 562 lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA;
563 563
564 memset(&props, 0, sizeof(struct backlight_properties)); 564 memset(&props, 0, sizeof(struct backlight_properties));
565 props.type = BACKLIGHT_RAW;
565 props.max_brightness = pdata->max_intensity; 566 props.max_brightness = pdata->max_intensity;
566 lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd, 567 lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd,
567 &corgi_bl_ops, &props); 568 &corgi_bl_ops, &props);
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index 397d15eb1ea8..6c8c54041fae 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -193,6 +193,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
193 } 193 }
194 194
195 memset(&props, 0, sizeof(struct backlight_properties)); 195 memset(&props, 0, sizeof(struct backlight_properties));
196 props.type = BACKLIGHT_RAW;
196 bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL, 197 bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL,
197 &cr_backlight_ops, &props); 198 &cr_backlight_ops, &props);
198 if (IS_ERR(bdp)) { 199 if (IS_ERR(bdp)) {
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index 87659ed79bd7..62043f12a5a4 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -136,6 +136,7 @@ static int da903x_backlight_probe(struct platform_device *pdev)
136 da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2, 136 da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2,
137 DA9034_WLED_ISET(pdata->output_current)); 137 DA9034_WLED_ISET(pdata->output_current));
138 138
139 props.type = BACKLIGHT_RAW;
139 props.max_brightness = max_brightness; 140 props.max_brightness = max_brightness;
140 bl = backlight_device_register(pdev->name, data->da903x_dev, data, 141 bl = backlight_device_register(pdev->name, data->da903x_dev, data,
141 &da903x_backlight_ops, &props); 142 &da903x_backlight_ops, &props);
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c
index b0cc49184803..9f1e389d51d2 100644
--- a/drivers/video/backlight/ep93xx_bl.c
+++ b/drivers/video/backlight/ep93xx_bl.c
@@ -87,6 +87,7 @@ static int __init ep93xxbl_probe(struct platform_device *dev)
87 ep93xxbl->mmio = EP93XX_RASTER_BRIGHTNESS; 87 ep93xxbl->mmio = EP93XX_RASTER_BRIGHTNESS;
88 88
89 memset(&props, 0, sizeof(struct backlight_properties)); 89 memset(&props, 0, sizeof(struct backlight_properties));
90 props.type = BACKLIGHT_RAW;
90 props.max_brightness = EP93XX_MAX_BRIGHT; 91 props.max_brightness = EP93XX_MAX_BRIGHT;
91 bl = backlight_device_register(dev->name, &dev->dev, ep93xxbl, 92 bl = backlight_device_register(dev->name, &dev->dev, ep93xxbl,
92 &ep93xxbl_ops, &props); 93 &ep93xxbl_ops, &props);
diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c
index 312ca619735d..8c6befd65a33 100644
--- a/drivers/video/backlight/generic_bl.c
+++ b/drivers/video/backlight/generic_bl.c
@@ -91,6 +91,7 @@ static int genericbl_probe(struct platform_device *pdev)
91 name = machinfo->name; 91 name = machinfo->name;
92 92
93 memset(&props, 0, sizeof(struct backlight_properties)); 93 memset(&props, 0, sizeof(struct backlight_properties));
94 props.type = BACKLIGHT_RAW;
94 props.max_brightness = machinfo->max_intensity; 95 props.max_brightness = machinfo->max_intensity;
95 bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops, 96 bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops,
96 &props); 97 &props);
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 267d23f8d645..38aa00272141 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -109,6 +109,7 @@ static int __devinit hp680bl_probe(struct platform_device *pdev)
109 struct backlight_device *bd; 109 struct backlight_device *bd;
110 110
111 memset(&props, 0, sizeof(struct backlight_properties)); 111 memset(&props, 0, sizeof(struct backlight_properties));
112 props.type = BACKLIGHT_RAW;
112 props.max_brightness = HP680_MAX_INTENSITY; 113 props.max_brightness = HP680_MAX_INTENSITY;
113 bd = backlight_device_register("hp680-bl", &pdev->dev, NULL, 114 bd = backlight_device_register("hp680-bl", &pdev->dev, NULL,
114 &hp680bl_ops, &props); 115 &hp680bl_ops, &props);
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
index 2f177b3a4885..de65d80159be 100644
--- a/drivers/video/backlight/jornada720_bl.c
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -106,6 +106,7 @@ static int jornada_bl_probe(struct platform_device *pdev)
106 struct backlight_device *bd; 106 struct backlight_device *bd;
107 107
108 memset(&props, 0, sizeof(struct backlight_properties)); 108 memset(&props, 0, sizeof(struct backlight_properties));
109 props.type = BACKLIGHT_RAW;
109 props.max_brightness = BL_MAX_BRIGHT; 110 props.max_brightness = BL_MAX_BRIGHT;
110 bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, 111 bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL,
111 &jornada_bl_ops, &props); 112 &jornada_bl_ops, &props);
@@ -146,12 +147,12 @@ static struct platform_driver jornada_bl_driver = {
146 }, 147 },
147}; 148};
148 149
149int __init jornada_bl_init(void) 150static int __init jornada_bl_init(void)
150{ 151{
151 return platform_driver_register(&jornada_bl_driver); 152 return platform_driver_register(&jornada_bl_driver);
152} 153}
153 154
154void __exit jornada_bl_exit(void) 155static void __exit jornada_bl_exit(void)
155{ 156{
156 platform_driver_unregister(&jornada_bl_driver); 157 platform_driver_unregister(&jornada_bl_driver);
157} 158}
diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c
index cbbb167fd268..d2ff658b4144 100644
--- a/drivers/video/backlight/jornada720_lcd.c
+++ b/drivers/video/backlight/jornada720_lcd.c
@@ -135,12 +135,12 @@ static struct platform_driver jornada_lcd_driver = {
135 }, 135 },
136}; 136};
137 137
138int __init jornada_lcd_init(void) 138static int __init jornada_lcd_init(void)
139{ 139{
140 return platform_driver_register(&jornada_lcd_driver); 140 return platform_driver_register(&jornada_lcd_driver);
141} 141}
142 142
143void __exit jornada_lcd_exit(void) 143static void __exit jornada_lcd_exit(void)
144{ 144{
145 platform_driver_unregister(&jornada_lcd_driver); 145 platform_driver_unregister(&jornada_lcd_driver);
146} 146}
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c
index f439a8632287..72dd5556a35b 100644
--- a/drivers/video/backlight/kb3886_bl.c
+++ b/drivers/video/backlight/kb3886_bl.c
@@ -149,6 +149,7 @@ static int kb3886bl_probe(struct platform_device *pdev)
149 machinfo->limit_mask = -1; 149 machinfo->limit_mask = -1;
150 150
151 memset(&props, 0, sizeof(struct backlight_properties)); 151 memset(&props, 0, sizeof(struct backlight_properties));
152 props.type = BACKLIGHT_RAW;
152 props.max_brightness = machinfo->max_intensity; 153 props.max_brightness = machinfo->max_intensity;
153 kb3886_backlight_device = backlight_device_register("kb3886-bl", 154 kb3886_backlight_device = backlight_device_register("kb3886-bl",
154 &pdev->dev, NULL, 155 &pdev->dev, NULL,
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c
new file mode 100644
index 000000000000..7281b2506a67
--- /dev/null
+++ b/drivers/video/backlight/ld9040.c
@@ -0,0 +1,819 @@
1/*
2 * ld9040 AMOLED LCD panel driver.
3 *
4 * Copyright (c) 2011 Samsung Electronics
5 * Author: Donghwa Lee <dh09.lee@samsung.com>
6 * Derived from drivers/video/backlight/s6e63m0.c
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23#include <linux/wait.h>
24#include <linux/fb.h>
25#include <linux/delay.h>
26#include <linux/gpio.h>
27#include <linux/spi/spi.h>
28#include <linux/irq.h>
29#include <linux/interrupt.h>
30#include <linux/kernel.h>
31#include <linux/lcd.h>
32#include <linux/backlight.h>
33
34#include "ld9040_gamma.h"
35
36#define SLEEPMSEC 0x1000
37#define ENDDEF 0x2000
38#define DEFMASK 0xFF00
39#define COMMAND_ONLY 0xFE
40#define DATA_ONLY 0xFF
41
42#define MIN_BRIGHTNESS 0
43#define MAX_BRIGHTNESS 24
44#define power_is_on(pwr) ((pwr) <= FB_BLANK_NORMAL)
45
46struct ld9040 {
47 struct device *dev;
48 struct spi_device *spi;
49 unsigned int power;
50 unsigned int current_brightness;
51
52 struct lcd_device *ld;
53 struct backlight_device *bd;
54 struct lcd_platform_data *lcd_pd;
55};
56
57static const unsigned short seq_swreset[] = {
58 0x01, COMMAND_ONLY,
59 ENDDEF, 0x00
60};
61
62static const unsigned short seq_user_setting[] = {
63 0xF0, 0x5A,
64
65 DATA_ONLY, 0x5A,
66 ENDDEF, 0x00
67};
68
69static const unsigned short seq_elvss_on[] = {
70 0xB1, 0x0D,
71
72 DATA_ONLY, 0x00,
73 DATA_ONLY, 0x16,
74 ENDDEF, 0x00
75};
76
77static const unsigned short seq_gtcon[] = {
78 0xF7, 0x09,
79
80 DATA_ONLY, 0x00,
81 DATA_ONLY, 0x00,
82 ENDDEF, 0x00
83};
84
85static const unsigned short seq_panel_condition[] = {
86 0xF8, 0x05,
87
88 DATA_ONLY, 0x65,
89 DATA_ONLY, 0x96,
90 DATA_ONLY, 0x71,
91 DATA_ONLY, 0x7D,
92 DATA_ONLY, 0x19,
93 DATA_ONLY, 0x3B,
94 DATA_ONLY, 0x0D,
95 DATA_ONLY, 0x19,
96 DATA_ONLY, 0x7E,
97 DATA_ONLY, 0x0D,
98 DATA_ONLY, 0xE2,
99 DATA_ONLY, 0x00,
100 DATA_ONLY, 0x00,
101 DATA_ONLY, 0x7E,
102 DATA_ONLY, 0x7D,
103 DATA_ONLY, 0x07,
104 DATA_ONLY, 0x07,
105 DATA_ONLY, 0x20,
106 DATA_ONLY, 0x20,
107 DATA_ONLY, 0x20,
108 DATA_ONLY, 0x02,
109 DATA_ONLY, 0x02,
110 ENDDEF, 0x00
111};
112
113static const unsigned short seq_gamma_set1[] = {
114 0xF9, 0x00,
115
116 DATA_ONLY, 0xA7,
117 DATA_ONLY, 0xB4,
118 DATA_ONLY, 0xAE,
119 DATA_ONLY, 0xBF,
120 DATA_ONLY, 0x00,
121 DATA_ONLY, 0x91,
122 DATA_ONLY, 0x00,
123 DATA_ONLY, 0xB2,
124 DATA_ONLY, 0xB4,
125 DATA_ONLY, 0xAA,
126 DATA_ONLY, 0xBB,
127 DATA_ONLY, 0x00,
128 DATA_ONLY, 0xAC,
129 DATA_ONLY, 0x00,
130 DATA_ONLY, 0xB3,
131 DATA_ONLY, 0xB1,
132 DATA_ONLY, 0xAA,
133 DATA_ONLY, 0xBC,
134 DATA_ONLY, 0x00,
135 DATA_ONLY, 0xB3,
136 ENDDEF, 0x00
137};
138
139static const unsigned short seq_gamma_ctrl[] = {
140 0xFB, 0x02,
141
142 DATA_ONLY, 0x5A,
143 ENDDEF, 0x00
144};
145
146static const unsigned short seq_gamma_start[] = {
147 0xF9, COMMAND_ONLY,
148
149 ENDDEF, 0x00
150};
151
152static const unsigned short seq_apon[] = {
153 0xF3, 0x00,
154
155 DATA_ONLY, 0x00,
156 DATA_ONLY, 0x00,
157 DATA_ONLY, 0x0A,
158 DATA_ONLY, 0x02,
159 ENDDEF, 0x00
160};
161
162static const unsigned short seq_display_ctrl[] = {
163 0xF2, 0x02,
164
165 DATA_ONLY, 0x08,
166 DATA_ONLY, 0x08,
167 DATA_ONLY, 0x10,
168 DATA_ONLY, 0x10,
169 ENDDEF, 0x00
170};
171
172static const unsigned short seq_manual_pwr[] = {
173 0xB0, 0x04,
174 ENDDEF, 0x00
175};
176
177static const unsigned short seq_pwr_ctrl[] = {
178 0xF4, 0x0A,
179
180 DATA_ONLY, 0x87,
181 DATA_ONLY, 0x25,
182 DATA_ONLY, 0x6A,
183 DATA_ONLY, 0x44,
184 DATA_ONLY, 0x02,
185 DATA_ONLY, 0x88,
186 ENDDEF, 0x00
187};
188
189static const unsigned short seq_sleep_out[] = {
190 0x11, COMMAND_ONLY,
191 ENDDEF, 0x00
192};
193
194static const unsigned short seq_sleep_in[] = {
195 0x10, COMMAND_ONLY,
196 ENDDEF, 0x00
197};
198
199static const unsigned short seq_display_on[] = {
200 0x29, COMMAND_ONLY,
201 ENDDEF, 0x00
202};
203
204static const unsigned short seq_display_off[] = {
205 0x28, COMMAND_ONLY,
206 ENDDEF, 0x00
207};
208
209static const unsigned short seq_vci1_1st_en[] = {
210 0xF3, 0x10,
211
212 DATA_ONLY, 0x00,
213 DATA_ONLY, 0x00,
214 DATA_ONLY, 0x00,
215 DATA_ONLY, 0x02,
216 ENDDEF, 0x00
217};
218
219static const unsigned short seq_vl1_en[] = {
220 0xF3, 0x11,
221
222 DATA_ONLY, 0x00,
223 DATA_ONLY, 0x00,
224 DATA_ONLY, 0x00,
225 DATA_ONLY, 0x02,
226 ENDDEF, 0x00
227};
228
229static const unsigned short seq_vl2_en[] = {
230 0xF3, 0x13,
231
232 DATA_ONLY, 0x00,
233 DATA_ONLY, 0x00,
234 DATA_ONLY, 0x00,
235 DATA_ONLY, 0x02,
236 ENDDEF, 0x00
237};
238
239static const unsigned short seq_vci1_2nd_en[] = {
240 0xF3, 0x33,
241
242 DATA_ONLY, 0x00,
243 DATA_ONLY, 0x00,
244 DATA_ONLY, 0x00,
245 DATA_ONLY, 0x02,
246 ENDDEF, 0x00
247};
248
249static const unsigned short seq_vl3_en[] = {
250 0xF3, 0x37,
251
252 DATA_ONLY, 0x00,
253 DATA_ONLY, 0x00,
254 DATA_ONLY, 0x00,
255 DATA_ONLY, 0x02,
256 ENDDEF, 0x00
257};
258
259static const unsigned short seq_vreg1_amp_en[] = {
260 0xF3, 0x37,
261
262 DATA_ONLY, 0x01,
263 DATA_ONLY, 0x00,
264 DATA_ONLY, 0x00,
265 DATA_ONLY, 0x02,
266 ENDDEF, 0x00
267};
268
269static const unsigned short seq_vgh_amp_en[] = {
270 0xF3, 0x37,
271
272 DATA_ONLY, 0x11,
273 DATA_ONLY, 0x00,
274 DATA_ONLY, 0x00,
275 DATA_ONLY, 0x02,
276 ENDDEF, 0x00
277};
278
279static const unsigned short seq_vgl_amp_en[] = {
280 0xF3, 0x37,
281
282 DATA_ONLY, 0x31,
283 DATA_ONLY, 0x00,
284 DATA_ONLY, 0x00,
285 DATA_ONLY, 0x02,
286 ENDDEF, 0x00
287};
288
289static const unsigned short seq_vmos_amp_en[] = {
290 0xF3, 0x37,
291
292 DATA_ONLY, 0xB1,
293 DATA_ONLY, 0x00,
294 DATA_ONLY, 0x00,
295 DATA_ONLY, 0x03,
296 ENDDEF, 0x00
297};
298
299static const unsigned short seq_vint_amp_en[] = {
300 0xF3, 0x37,
301
302 DATA_ONLY, 0xF1,
303 /* DATA_ONLY, 0x71, VMOS/VBL/VBH not used */
304 DATA_ONLY, 0x00,
305 DATA_ONLY, 0x00,
306 DATA_ONLY, 0x03,
307 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
308 ENDDEF, 0x00
309};
310
311static const unsigned short seq_vbh_amp_en[] = {
312 0xF3, 0x37,
313
314 DATA_ONLY, 0xF9,
315 DATA_ONLY, 0x00,
316 DATA_ONLY, 0x00,
317 DATA_ONLY, 0x03,
318 ENDDEF, 0x00
319};
320
321static const unsigned short seq_vbl_amp_en[] = {
322 0xF3, 0x37,
323
324 DATA_ONLY, 0xFD,
325 DATA_ONLY, 0x00,
326 DATA_ONLY, 0x00,
327 DATA_ONLY, 0x03,
328 ENDDEF, 0x00
329};
330
331static const unsigned short seq_gam_amp_en[] = {
332 0xF3, 0x37,
333
334 DATA_ONLY, 0xFF,
335 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
336 DATA_ONLY, 0x00,
337 DATA_ONLY, 0x00,
338 DATA_ONLY, 0x03,
339 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
340 ENDDEF, 0x00
341};
342
343static const unsigned short seq_sd_amp_en[] = {
344 0xF3, 0x37,
345
346 DATA_ONLY, 0xFF,
347 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
348 DATA_ONLY, 0x80,
349 DATA_ONLY, 0x00,
350 DATA_ONLY, 0x03,
351 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
352 ENDDEF, 0x00
353};
354
355static const unsigned short seq_gls_en[] = {
356 0xF3, 0x37,
357
358 DATA_ONLY, 0xFF,
359 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
360 DATA_ONLY, 0x81,
361 DATA_ONLY, 0x00,
362 DATA_ONLY, 0x03,
363 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
364 ENDDEF, 0x00
365};
366
367static const unsigned short seq_els_en[] = {
368 0xF3, 0x37,
369
370 DATA_ONLY, 0xFF,
371 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
372 DATA_ONLY, 0x83,
373 DATA_ONLY, 0x00,
374 DATA_ONLY, 0x03,
375 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
376 ENDDEF, 0x00
377};
378
379static const unsigned short seq_el_on[] = {
380 0xF3, 0x37,
381
382 DATA_ONLY, 0xFF,
383 /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
384 DATA_ONLY, 0x87,
385 DATA_ONLY, 0x00,
386 DATA_ONLY, 0x03,
387 /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
388 ENDDEF, 0x00
389};
390
391static int ld9040_spi_write_byte(struct ld9040 *lcd, int addr, int data)
392{
393 u16 buf[1];
394 struct spi_message msg;
395
396 struct spi_transfer xfer = {
397 .len = 2,
398 .tx_buf = buf,
399 };
400
401 buf[0] = (addr << 8) | data;
402
403 spi_message_init(&msg);
404 spi_message_add_tail(&xfer, &msg);
405
406 return spi_sync(lcd->spi, &msg);
407}
408
409static int ld9040_spi_write(struct ld9040 *lcd, unsigned char address,
410 unsigned char command)
411{
412 int ret = 0;
413
414 if (address != DATA_ONLY)
415 ret = ld9040_spi_write_byte(lcd, 0x0, address);
416 if (command != COMMAND_ONLY)
417 ret = ld9040_spi_write_byte(lcd, 0x1, command);
418
419 return ret;
420}
421
422static int ld9040_panel_send_sequence(struct ld9040 *lcd,
423 const unsigned short *wbuf)
424{
425 int ret = 0, i = 0;
426
427 while ((wbuf[i] & DEFMASK) != ENDDEF) {
428 if ((wbuf[i] & DEFMASK) != SLEEPMSEC) {
429 ret = ld9040_spi_write(lcd, wbuf[i], wbuf[i+1]);
430 if (ret)
431 break;
432 } else
433 udelay(wbuf[i+1]*1000);
434 i += 2;
435 }
436
437 return ret;
438}
439
440static int _ld9040_gamma_ctl(struct ld9040 *lcd, const unsigned int *gamma)
441{
442 unsigned int i = 0;
443 int ret = 0;
444
445 /* start gamma table updating. */
446 ret = ld9040_panel_send_sequence(lcd, seq_gamma_start);
447 if (ret) {
448 dev_err(lcd->dev, "failed to disable gamma table updating.\n");
449 goto gamma_err;
450 }
451
452 for (i = 0 ; i < GAMMA_TABLE_COUNT; i++) {
453 ret = ld9040_spi_write(lcd, DATA_ONLY, gamma[i]);
454 if (ret) {
455 dev_err(lcd->dev, "failed to set gamma table.\n");
456 goto gamma_err;
457 }
458 }
459
460 /* update gamma table. */
461 ret = ld9040_panel_send_sequence(lcd, seq_gamma_ctrl);
462 if (ret)
463 dev_err(lcd->dev, "failed to update gamma table.\n");
464
465gamma_err:
466 return ret;
467}
468
469static int ld9040_gamma_ctl(struct ld9040 *lcd, int gamma)
470{
471 int ret = 0;
472
473 ret = _ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
474
475 return ret;
476}
477
478
479static int ld9040_ldi_init(struct ld9040 *lcd)
480{
481 int ret, i;
482 static const unsigned short *init_seq[] = {
483 seq_user_setting,
484 seq_panel_condition,
485 seq_display_ctrl,
486 seq_manual_pwr,
487 seq_elvss_on,
488 seq_gtcon,
489 seq_gamma_set1,
490 seq_gamma_ctrl,
491 seq_sleep_out,
492 };
493
494 for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
495 ret = ld9040_panel_send_sequence(lcd, init_seq[i]);
496 /* workaround: minimum delay time for transferring CMD */
497 udelay(300);
498 if (ret)
499 break;
500 }
501
502 return ret;
503}
504
505static int ld9040_ldi_enable(struct ld9040 *lcd)
506{
507 int ret = 0;
508
509 ret = ld9040_panel_send_sequence(lcd, seq_display_on);
510
511 return ret;
512}
513
514static int ld9040_ldi_disable(struct ld9040 *lcd)
515{
516 int ret;
517
518 ret = ld9040_panel_send_sequence(lcd, seq_display_off);
519 ret = ld9040_panel_send_sequence(lcd, seq_sleep_in);
520
521 return ret;
522}
523
524static int ld9040_power_on(struct ld9040 *lcd)
525{
526 int ret = 0;
527 struct lcd_platform_data *pd = NULL;
528 pd = lcd->lcd_pd;
529 if (!pd) {
530 dev_err(lcd->dev, "platform data is NULL.\n");
531 return -EFAULT;
532 }
533
534 if (!pd->power_on) {
535 dev_err(lcd->dev, "power_on is NULL.\n");
536 return -EFAULT;
537 } else {
538 pd->power_on(lcd->ld, 1);
539 mdelay(pd->power_on_delay);
540 }
541
542 if (!pd->reset) {
543 dev_err(lcd->dev, "reset is NULL.\n");
544 return -EFAULT;
545 } else {
546 pd->reset(lcd->ld);
547 mdelay(pd->reset_delay);
548 }
549
550 ret = ld9040_ldi_init(lcd);
551 if (ret) {
552 dev_err(lcd->dev, "failed to initialize ldi.\n");
553 return ret;
554 }
555
556 ret = ld9040_ldi_enable(lcd);
557 if (ret) {
558 dev_err(lcd->dev, "failed to enable ldi.\n");
559 return ret;
560 }
561
562 return 0;
563}
564
565static int ld9040_power_off(struct ld9040 *lcd)
566{
567 int ret = 0;
568 struct lcd_platform_data *pd = NULL;
569
570 pd = lcd->lcd_pd;
571 if (!pd) {
572 dev_err(lcd->dev, "platform data is NULL.\n");
573 return -EFAULT;
574 }
575
576 ret = ld9040_ldi_disable(lcd);
577 if (ret) {
578 dev_err(lcd->dev, "lcd setting failed.\n");
579 return -EIO;
580 }
581
582 mdelay(pd->power_off_delay);
583
584 if (!pd->power_on) {
585 dev_err(lcd->dev, "power_on is NULL.\n");
586 return -EFAULT;
587 } else
588 pd->power_on(lcd->ld, 0);
589
590 return 0;
591}
592
593static int ld9040_power(struct ld9040 *lcd, int power)
594{
595 int ret = 0;
596
597 if (power_is_on(power) && !power_is_on(lcd->power))
598 ret = ld9040_power_on(lcd);
599 else if (!power_is_on(power) && power_is_on(lcd->power))
600 ret = ld9040_power_off(lcd);
601
602 if (!ret)
603 lcd->power = power;
604
605 return ret;
606}
607
608static int ld9040_set_power(struct lcd_device *ld, int power)
609{
610 struct ld9040 *lcd = lcd_get_data(ld);
611
612 if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
613 power != FB_BLANK_NORMAL) {
614 dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
615 return -EINVAL;
616 }
617
618 return ld9040_power(lcd, power);
619}
620
621static int ld9040_get_power(struct lcd_device *ld)
622{
623 struct ld9040 *lcd = lcd_get_data(ld);
624
625 return lcd->power;
626}
627
628static int ld9040_get_brightness(struct backlight_device *bd)
629{
630 return bd->props.brightness;
631}
632
633static int ld9040_set_brightness(struct backlight_device *bd)
634{
635 int ret = 0, brightness = bd->props.brightness;
636 struct ld9040 *lcd = bl_get_data(bd);
637
638 if (brightness < MIN_BRIGHTNESS ||
639 brightness > bd->props.max_brightness) {
640 dev_err(&bd->dev, "lcd brightness should be %d to %d.\n",
641 MIN_BRIGHTNESS, MAX_BRIGHTNESS);
642 return -EINVAL;
643 }
644
645 ret = ld9040_gamma_ctl(lcd, bd->props.brightness);
646 if (ret) {
647 dev_err(&bd->dev, "lcd brightness setting failed.\n");
648 return -EIO;
649 }
650
651 return ret;
652}
653
654static struct lcd_ops ld9040_lcd_ops = {
655 .set_power = ld9040_set_power,
656 .get_power = ld9040_get_power,
657};
658
659static const struct backlight_ops ld9040_backlight_ops = {
660 .get_brightness = ld9040_get_brightness,
661 .update_status = ld9040_set_brightness,
662};
663
664
665static int ld9040_probe(struct spi_device *spi)
666{
667 int ret = 0;
668 struct ld9040 *lcd = NULL;
669 struct lcd_device *ld = NULL;
670 struct backlight_device *bd = NULL;
671
672 lcd = kzalloc(sizeof(struct ld9040), GFP_KERNEL);
673 if (!lcd)
674 return -ENOMEM;
675
676 /* ld9040 lcd panel uses 3-wire 9bits SPI Mode. */
677 spi->bits_per_word = 9;
678
679 ret = spi_setup(spi);
680 if (ret < 0) {
681 dev_err(&spi->dev, "spi setup failed.\n");
682 goto out_free_lcd;
683 }
684
685 lcd->spi = spi;
686 lcd->dev = &spi->dev;
687
688 lcd->lcd_pd = spi->dev.platform_data;
689 if (!lcd->lcd_pd) {
690 dev_err(&spi->dev, "platform data is NULL.\n");
691 goto out_free_lcd;
692 }
693
694 ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops);
695 if (IS_ERR(ld)) {
696 ret = PTR_ERR(ld);
697 goto out_free_lcd;
698 }
699
700 lcd->ld = ld;
701
702 bd = backlight_device_register("ld9040-bl", &spi->dev,
703 lcd, &ld9040_backlight_ops, NULL);
704 if (IS_ERR(ld)) {
705 ret = PTR_ERR(ld);
706 goto out_free_lcd;
707 }
708
709 bd->props.max_brightness = MAX_BRIGHTNESS;
710 bd->props.brightness = MAX_BRIGHTNESS;
711 lcd->bd = bd;
712
713 /*
714 * if lcd panel was on from bootloader like u-boot then
715 * do not lcd on.
716 */
717 if (!lcd->lcd_pd->lcd_enabled) {
718 /*
719 * if lcd panel was off from bootloader then
720 * current lcd status is powerdown and then
721 * it enables lcd panel.
722 */
723 lcd->power = FB_BLANK_POWERDOWN;
724
725 ld9040_power(lcd, FB_BLANK_UNBLANK);
726 } else
727 lcd->power = FB_BLANK_UNBLANK;
728
729 dev_set_drvdata(&spi->dev, lcd);
730
731 dev_info(&spi->dev, "ld9040 panel driver has been probed.\n");
732 return 0;
733
734out_free_lcd:
735 kfree(lcd);
736 return ret;
737}
738
739static int __devexit ld9040_remove(struct spi_device *spi)
740{
741 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
742
743 ld9040_power(lcd, FB_BLANK_POWERDOWN);
744 lcd_device_unregister(lcd->ld);
745 kfree(lcd);
746
747 return 0;
748}
749
750#if defined(CONFIG_PM)
751static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
752{
753 int ret = 0;
754 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
755
756 dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
757
758 /*
759 * when lcd panel is suspend, lcd panel becomes off
760 * regardless of status.
761 */
762 ret = ld9040_power(lcd, FB_BLANK_POWERDOWN);
763
764 return ret;
765}
766
767static int ld9040_resume(struct spi_device *spi)
768{
769 int ret = 0;
770 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
771
772 lcd->power = FB_BLANK_POWERDOWN;
773
774 ret = ld9040_power(lcd, FB_BLANK_UNBLANK);
775
776 return ret;
777}
778#else
779#define ld9040_suspend NULL
780#define ld9040_resume NULL
781#endif
782
783/* Power down all displays on reboot, poweroff or halt. */
784static void ld9040_shutdown(struct spi_device *spi)
785{
786 struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
787
788 ld9040_power(lcd, FB_BLANK_POWERDOWN);
789}
790
791static struct spi_driver ld9040_driver = {
792 .driver = {
793 .name = "ld9040",
794 .bus = &spi_bus_type,
795 .owner = THIS_MODULE,
796 },
797 .probe = ld9040_probe,
798 .remove = __devexit_p(ld9040_remove),
799 .shutdown = ld9040_shutdown,
800 .suspend = ld9040_suspend,
801 .resume = ld9040_resume,
802};
803
804static int __init ld9040_init(void)
805{
806 return spi_register_driver(&ld9040_driver);
807}
808
809static void __exit ld9040_exit(void)
810{
811 spi_unregister_driver(&ld9040_driver);
812}
813
814module_init(ld9040_init);
815module_exit(ld9040_exit);
816
817MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
818MODULE_DESCRIPTION("ld9040 LCD Driver");
819MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/ld9040_gamma.h b/drivers/video/backlight/ld9040_gamma.h
new file mode 100644
index 000000000000..038d9c86ec03
--- /dev/null
+++ b/drivers/video/backlight/ld9040_gamma.h
@@ -0,0 +1,200 @@
1/*
2 * Gamma level definitions.
3 *
4 * Copyright (c) 2011 Samsung Electronics
5 * InKi Dae <inki.dae@samsung.com>
6 * Donghwa Lee <dh09.lee@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef _LD9040_BRIGHTNESS_H
14#define _LD9040_BRIGHTNESS_H
15
16#define MAX_GAMMA_LEVEL 25
17#define GAMMA_TABLE_COUNT 21
18
19/* gamma value: 2.2 */
20static const unsigned int ld9040_22_300[] = {
21 0x00, 0xa7, 0xb4, 0xae, 0xbf, 0x00, 0x91,
22 0x00, 0xb2, 0xb4, 0xaa, 0xbb, 0x00, 0xac,
23 0x00, 0xb3, 0xb1, 0xaa, 0xbc, 0x00, 0xb3
24};
25
26static const unsigned int ld9040_22_290[] = {
27 0x00, 0xa9, 0xb7, 0xae, 0xbd, 0x00, 0x89,
28 0x00, 0xb7, 0xb6, 0xa8, 0xba, 0x00, 0xa4,
29 0x00, 0xb1, 0xb4, 0xaa, 0xbb, 0x00, 0xaa
30};
31
32static const unsigned int ld9040_22_280[] = {
33 0x00, 0xa9, 0xb6, 0xad, 0xbf, 0x00, 0x86,
34 0x00, 0xb8, 0xb5, 0xa8, 0xbc, 0x00, 0xa0,
35 0x00, 0xb3, 0xb3, 0xa9, 0xbc, 0x00, 0xa7
36};
37
38static const unsigned int ld9040_22_270[] = {
39 0x00, 0xa8, 0xb8, 0xae, 0xbe, 0x00, 0x84,
40 0x00, 0xb9, 0xb7, 0xa8, 0xbc, 0x00, 0x9d,
41 0x00, 0xb2, 0xb5, 0xaa, 0xbc, 0x00, 0xa4
42
43};
44static const unsigned int ld9040_22_260[] = {
45 0x00, 0xa4, 0xb8, 0xb0, 0xbf, 0x00, 0x80,
46 0x00, 0xb8, 0xb6, 0xaa, 0xbc, 0x00, 0x9a,
47 0x00, 0xb0, 0xb5, 0xab, 0xbd, 0x00, 0xa0
48};
49
50static const unsigned int ld9040_22_250[] = {
51 0x00, 0xa4, 0xb9, 0xaf, 0xc1, 0x00, 0x7d,
52 0x00, 0xb9, 0xb6, 0xaa, 0xbb, 0x00, 0x97,
53 0x00, 0xb1, 0xb5, 0xaa, 0xbf, 0x00, 0x9d
54};
55
56static const unsigned int ld9040_22_240[] = {
57 0x00, 0xa2, 0xb9, 0xaf, 0xc2, 0x00, 0x7a,
58 0x00, 0xb9, 0xb7, 0xaa, 0xbd, 0x00, 0x94,
59 0x00, 0xb0, 0xb5, 0xab, 0xbf, 0x00, 0x9a
60};
61
62static const unsigned int ld9040_22_230[] = {
63 0x00, 0xa0, 0xb9, 0xaf, 0xc3, 0x00, 0x77,
64 0x00, 0xb9, 0xb7, 0xab, 0xbe, 0x00, 0x90,
65 0x00, 0xb0, 0xb6, 0xab, 0xbf, 0x00, 0x97
66};
67
68static const unsigned int ld9040_22_220[] = {
69 0x00, 0x9e, 0xba, 0xb0, 0xc2, 0x00, 0x75,
70 0x00, 0xb9, 0xb8, 0xab, 0xbe, 0x00, 0x8e,
71 0x00, 0xb0, 0xb6, 0xac, 0xbf, 0x00, 0x94
72};
73
74static const unsigned int ld9040_22_210[] = {
75 0x00, 0x9c, 0xb9, 0xb0, 0xc4, 0x00, 0x72,
76 0x00, 0xb8, 0xb8, 0xac, 0xbf, 0x00, 0x8a,
77 0x00, 0xb0, 0xb6, 0xac, 0xc0, 0x00, 0x91
78};
79
80static const unsigned int ld9040_22_200[] = {
81 0x00, 0x9a, 0xba, 0xb1, 0xc4, 0x00, 0x6f,
82 0x00, 0xb8, 0xb8, 0xad, 0xc0, 0x00, 0x86,
83 0x00, 0xb0, 0xb7, 0xad, 0xc0, 0x00, 0x8d
84};
85
86static const unsigned int ld9040_22_190[] = {
87 0x00, 0x97, 0xba, 0xb2, 0xc5, 0x00, 0x6c,
88 0x00, 0xb8, 0xb8, 0xae, 0xc1, 0x00, 0x82,
89 0x00, 0xb0, 0xb6, 0xae, 0xc2, 0x00, 0x89
90};
91
92static const unsigned int ld9040_22_180[] = {
93 0x00, 0x93, 0xba, 0xb3, 0xc5, 0x00, 0x69,
94 0x00, 0xb8, 0xb9, 0xae, 0xc1, 0x00, 0x7f,
95 0x00, 0xb0, 0xb6, 0xae, 0xc3, 0x00, 0x85
96};
97
98static const unsigned int ld9040_22_170[] = {
99 0x00, 0x8b, 0xb9, 0xb3, 0xc7, 0x00, 0x65,
100 0x00, 0xb7, 0xb8, 0xaf, 0xc3, 0x00, 0x7a,
101 0x00, 0x80, 0xb6, 0xae, 0xc4, 0x00, 0x81
102};
103
104static const unsigned int ld9040_22_160[] = {
105 0x00, 0x89, 0xba, 0xb3, 0xc8, 0x00, 0x62,
106 0x00, 0xb6, 0xba, 0xaf, 0xc3, 0x00, 0x76,
107 0x00, 0xaf, 0xb7, 0xae, 0xc4, 0x00, 0x7e
108};
109
110static const unsigned int ld9040_22_150[] = {
111 0x00, 0x82, 0xba, 0xb4, 0xc7, 0x00, 0x5f,
112 0x00, 0xb5, 0xba, 0xb0, 0xc3, 0x00, 0x72,
113 0x00, 0xae, 0xb8, 0xb0, 0xc3, 0x00, 0x7a
114};
115
116static const unsigned int ld9040_22_140[] = {
117 0x00, 0x7b, 0xbb, 0xb4, 0xc8, 0x00, 0x5b,
118 0x00, 0xb5, 0xba, 0xb1, 0xc4, 0x00, 0x6e,
119 0x00, 0xae, 0xb9, 0xb0, 0xc5, 0x00, 0x75
120};
121
122static const unsigned int ld9040_22_130[] = {
123 0x00, 0x71, 0xbb, 0xb5, 0xc8, 0x00, 0x57,
124 0x00, 0xb5, 0xbb, 0xb0, 0xc5, 0x00, 0x6a,
125 0x00, 0xae, 0xb9, 0xb1, 0xc6, 0x00, 0x70
126};
127
128static const unsigned int ld9040_22_120[] = {
129 0x00, 0x47, 0xba, 0xb6, 0xca, 0x00, 0x53,
130 0x00, 0xb5, 0xbb, 0xb3, 0xc6, 0x00, 0x65,
131 0x00, 0xae, 0xb8, 0xb3, 0xc7, 0x00, 0x6c
132};
133
134static const unsigned int ld9040_22_110[] = {
135 0x00, 0x13, 0xbb, 0xb7, 0xca, 0x00, 0x4f,
136 0x00, 0xb4, 0xbb, 0xb3, 0xc7, 0x00, 0x60,
137 0x00, 0xad, 0xb8, 0xb4, 0xc7, 0x00, 0x67
138};
139
140static const unsigned int ld9040_22_100[] = {
141 0x00, 0x13, 0xba, 0xb8, 0xcb, 0x00, 0x4b,
142 0x00, 0xb3, 0xbc, 0xb4, 0xc7, 0x00, 0x5c,
143 0x00, 0xac, 0xb8, 0xb4, 0xc8, 0x00, 0x62
144};
145
146static const unsigned int ld9040_22_90[] = {
147 0x00, 0x13, 0xb9, 0xb8, 0xcd, 0x00, 0x46,
148 0x00, 0xb1, 0xbc, 0xb5, 0xc8, 0x00, 0x56,
149 0x00, 0xaa, 0xb8, 0xb4, 0xc9, 0x00, 0x5d
150};
151
152static const unsigned int ld9040_22_80[] = {
153 0x00, 0x13, 0xba, 0xb9, 0xcd, 0x00, 0x41,
154 0x00, 0xb0, 0xbe, 0xb5, 0xc9, 0x00, 0x51,
155 0x00, 0xa9, 0xb9, 0xb5, 0xca, 0x00, 0x57
156};
157
158static const unsigned int ld9040_22_70[] = {
159 0x00, 0x13, 0xb9, 0xb9, 0xd0, 0x00, 0x3c,
160 0x00, 0xaf, 0xbf, 0xb6, 0xcb, 0x00, 0x4b,
161 0x00, 0xa8, 0xb9, 0xb5, 0xcc, 0x00, 0x52
162};
163
164static const unsigned int ld9040_22_50[] = {
165 0x00, 0x13, 0xb2, 0xba, 0xd2, 0x00, 0x30,
166 0x00, 0xaf, 0xc0, 0xb8, 0xcd, 0x00, 0x3d,
167 0x00, 0xa8, 0xb8, 0xb7, 0xcd, 0x00, 0x44
168};
169
170struct ld9040_gamma {
171 unsigned int *gamma_22_table[MAX_GAMMA_LEVEL];
172} gamma_table = {
173 .gamma_22_table[0] = (unsigned int *)&ld9040_22_50,
174 .gamma_22_table[1] = (unsigned int *)&ld9040_22_70,
175 .gamma_22_table[2] = (unsigned int *)&ld9040_22_80,
176 .gamma_22_table[3] = (unsigned int *)&ld9040_22_90,
177 .gamma_22_table[4] = (unsigned int *)&ld9040_22_100,
178 .gamma_22_table[5] = (unsigned int *)&ld9040_22_110,
179 .gamma_22_table[6] = (unsigned int *)&ld9040_22_120,
180 .gamma_22_table[7] = (unsigned int *)&ld9040_22_130,
181 .gamma_22_table[8] = (unsigned int *)&ld9040_22_140,
182 .gamma_22_table[9] = (unsigned int *)&ld9040_22_150,
183 .gamma_22_table[10] = (unsigned int *)&ld9040_22_160,
184 .gamma_22_table[11] = (unsigned int *)&ld9040_22_170,
185 .gamma_22_table[12] = (unsigned int *)&ld9040_22_180,
186 .gamma_22_table[13] = (unsigned int *)&ld9040_22_190,
187 .gamma_22_table[14] = (unsigned int *)&ld9040_22_200,
188 .gamma_22_table[15] = (unsigned int *)&ld9040_22_210,
189 .gamma_22_table[16] = (unsigned int *)&ld9040_22_220,
190 .gamma_22_table[17] = (unsigned int *)&ld9040_22_230,
191 .gamma_22_table[18] = (unsigned int *)&ld9040_22_240,
192 .gamma_22_table[19] = (unsigned int *)&ld9040_22_250,
193 .gamma_22_table[20] = (unsigned int *)&ld9040_22_260,
194 .gamma_22_table[21] = (unsigned int *)&ld9040_22_270,
195 .gamma_22_table[22] = (unsigned int *)&ld9040_22_280,
196 .gamma_22_table[23] = (unsigned int *)&ld9040_22_290,
197 .gamma_22_table[24] = (unsigned int *)&ld9040_22_300,
198};
199
200#endif
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index d2f59015d517..bbca3127071e 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -184,6 +184,7 @@ static int locomolcd_probe(struct locomo_dev *ldev)
184 local_irq_restore(flags); 184 local_irq_restore(flags);
185 185
186 memset(&props, 0, sizeof(struct backlight_properties)); 186 memset(&props, 0, sizeof(struct backlight_properties));
187 props.type = BACKLIGHT_RAW;
187 props.max_brightness = 4; 188 props.max_brightness = 4;
188 locomolcd_bl_device = backlight_device_register("locomo-bl", 189 locomolcd_bl_device = backlight_device_register("locomo-bl",
189 &ldev->dev, NULL, 190 &ldev->dev, NULL,
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index 209acc105cbc..07e8e273ced0 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -136,6 +136,7 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
136 data->current_brightness = 0; 136 data->current_brightness = 0;
137 137
138 memset(&props, 0, sizeof(struct backlight_properties)); 138 memset(&props, 0, sizeof(struct backlight_properties));
139 props.type = BACKLIGHT_RAW;
139 props.max_brightness = MAX_BRIGHTNESS; 140 props.max_brightness = MAX_BRIGHTNESS;
140 bl = backlight_device_register(name, &pdev->dev, data, 141 bl = backlight_device_register(name, &pdev->dev, data,
141 &max8925_backlight_ops, &props); 142 &max8925_backlight_ops, &props);
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
deleted file mode 100644
index 1485f7345f49..000000000000
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ /dev/null
@@ -1,400 +0,0 @@
1/*
2 * Backlight Driver for Nvidia 8600 in Macbook Pro
3 *
4 * Copyright (c) Red Hat <mjg@redhat.com>
5 * Based on code from Pommed:
6 * Copyright (C) 2006 Nicolas Boichat <nicolas @boichat.ch>
7 * Copyright (C) 2006 Felipe Alfaro Solana <felipe_alfaro @linuxmail.org>
8 * Copyright (C) 2007 Julien BLACHE <jb@jblache.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This driver triggers SMIs which cause the firmware to change the
15 * backlight brightness. This is icky in many ways, but it's impractical to
16 * get at the firmware code in order to figure out what it's actually doing.
17 */
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/backlight.h>
24#include <linux/err.h>
25#include <linux/dmi.h>
26#include <linux/io.h>
27
28static struct backlight_device *mbp_backlight_device;
29
30/* Structure to be passed to the DMI_MATCH function. */
31struct dmi_match_data {
32 /* I/O resource to allocate. */
33 unsigned long iostart;
34 unsigned long iolen;
35 /* Backlight operations structure. */
36 const struct backlight_ops backlight_ops;
37};
38
39/* Module parameters. */
40static int debug;
41module_param_named(debug, debug, int, 0644);
42MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
43
44/*
45 * Implementation for MacBooks with Intel chipset.
46 */
47static int intel_chipset_send_intensity(struct backlight_device *bd)
48{
49 int intensity = bd->props.brightness;
50
51 if (debug)
52 printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
53 intensity);
54
55 outb(0x04 | (intensity << 4), 0xb3);
56 outb(0xbf, 0xb2);
57 return 0;
58}
59
60static int intel_chipset_get_intensity(struct backlight_device *bd)
61{
62 int intensity;
63
64 outb(0x03, 0xb3);
65 outb(0xbf, 0xb2);
66 intensity = inb(0xb3) >> 4;
67
68 if (debug)
69 printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
70 intensity);
71
72 return intensity;
73}
74
75static const struct dmi_match_data intel_chipset_data = {
76 .iostart = 0xb2,
77 .iolen = 2,
78 .backlight_ops = {
79 .options = BL_CORE_SUSPENDRESUME,
80 .get_brightness = intel_chipset_get_intensity,
81 .update_status = intel_chipset_send_intensity,
82 }
83};
84
85/*
86 * Implementation for MacBooks with Nvidia chipset.
87 */
88static int nvidia_chipset_send_intensity(struct backlight_device *bd)
89{
90 int intensity = bd->props.brightness;
91
92 if (debug)
93 printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
94 intensity);
95
96 outb(0x04 | (intensity << 4), 0x52f);
97 outb(0xbf, 0x52e);
98 return 0;
99}
100
101static int nvidia_chipset_get_intensity(struct backlight_device *bd)
102{
103 int intensity;
104
105 outb(0x03, 0x52f);
106 outb(0xbf, 0x52e);
107 intensity = inb(0x52f) >> 4;
108
109 if (debug)
110 printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
111 intensity);
112
113 return intensity;
114}
115
116static const struct dmi_match_data nvidia_chipset_data = {
117 .iostart = 0x52e,
118 .iolen = 2,
119 .backlight_ops = {
120 .options = BL_CORE_SUSPENDRESUME,
121 .get_brightness = nvidia_chipset_get_intensity,
122 .update_status = nvidia_chipset_send_intensity
123 }
124};
125
126/*
127 * DMI matching.
128 */
129static /* const */ struct dmi_match_data *driver_data;
130
131static int mbp_dmi_match(const struct dmi_system_id *id)
132{
133 driver_data = id->driver_data;
134
135 printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident);
136 return 1;
137}
138
139static const struct dmi_system_id __initdata mbp_device_table[] = {
140 {
141 .callback = mbp_dmi_match,
142 .ident = "MacBook 1,1",
143 .matches = {
144 DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."),
145 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
146 },
147 .driver_data = (void *)&intel_chipset_data,
148 },
149 {
150 .callback = mbp_dmi_match,
151 .ident = "MacBook 2,1",
152 .matches = {
153 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
154 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"),
155 },
156 .driver_data = (void *)&intel_chipset_data,
157 },
158 {
159 .callback = mbp_dmi_match,
160 .ident = "MacBook 3,1",
161 .matches = {
162 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
163 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"),
164 },
165 .driver_data = (void *)&intel_chipset_data,
166 },
167 {
168 .callback = mbp_dmi_match,
169 .ident = "MacBook 4,1",
170 .matches = {
171 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
172 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"),
173 },
174 .driver_data = (void *)&intel_chipset_data,
175 },
176 {
177 .callback = mbp_dmi_match,
178 .ident = "MacBook 4,2",
179 .matches = {
180 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
181 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"),
182 },
183 .driver_data = (void *)&intel_chipset_data,
184 },
185 {
186 .callback = mbp_dmi_match,
187 .ident = "MacBookPro 1,1",
188 .matches = {
189 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
190 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"),
191 },
192 .driver_data = (void *)&intel_chipset_data,
193 },
194 {
195 .callback = mbp_dmi_match,
196 .ident = "MacBookPro 1,2",
197 .matches = {
198 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
199 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,2"),
200 },
201 .driver_data = (void *)&intel_chipset_data,
202 },
203 {
204 .callback = mbp_dmi_match,
205 .ident = "MacBookPro 2,1",
206 .matches = {
207 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
208 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,1"),
209 },
210 .driver_data = (void *)&intel_chipset_data,
211 },
212 {
213 .callback = mbp_dmi_match,
214 .ident = "MacBookPro 2,2",
215 .matches = {
216 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
217 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"),
218 },
219 .driver_data = (void *)&intel_chipset_data,
220 },
221 {
222 .callback = mbp_dmi_match,
223 .ident = "MacBookPro 3,1",
224 .matches = {
225 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
226 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
227 },
228 .driver_data = (void *)&intel_chipset_data,
229 },
230 {
231 .callback = mbp_dmi_match,
232 .ident = "MacBookPro 3,2",
233 .matches = {
234 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
235 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"),
236 },
237 .driver_data = (void *)&intel_chipset_data,
238 },
239 {
240 .callback = mbp_dmi_match,
241 .ident = "MacBookPro 4,1",
242 .matches = {
243 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
244 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"),
245 },
246 .driver_data = (void *)&intel_chipset_data,
247 },
248 {
249 .callback = mbp_dmi_match,
250 .ident = "MacBookAir 1,1",
251 .matches = {
252 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
253 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir1,1"),
254 },
255 .driver_data = (void *)&intel_chipset_data,
256 },
257 {
258 .callback = mbp_dmi_match,
259 .ident = "MacBook 5,1",
260 .matches = {
261 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
262 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,1"),
263 },
264 .driver_data = (void *)&nvidia_chipset_data,
265 },
266 {
267 .callback = mbp_dmi_match,
268 .ident = "MacBook 5,2",
269 .matches = {
270 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
271 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"),
272 },
273 .driver_data = (void *)&nvidia_chipset_data,
274 },
275 {
276 .callback = mbp_dmi_match,
277 .ident = "MacBook 6,1",
278 .matches = {
279 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
280 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook6,1"),
281 },
282 .driver_data = (void *)&nvidia_chipset_data,
283 },
284 {
285 .callback = mbp_dmi_match,
286 .ident = "MacBookAir 2,1",
287 .matches = {
288 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
289 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2,1"),
290 },
291 .driver_data = (void *)&nvidia_chipset_data,
292 },
293 {
294 .callback = mbp_dmi_match,
295 .ident = "MacBookPro 5,1",
296 .matches = {
297 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
298 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"),
299 },
300 .driver_data = (void *)&nvidia_chipset_data,
301 },
302 {
303 .callback = mbp_dmi_match,
304 .ident = "MacBookPro 5,2",
305 .matches = {
306 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
307 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,2"),
308 },
309 .driver_data = (void *)&nvidia_chipset_data,
310 },
311 {
312 .callback = mbp_dmi_match,
313 .ident = "MacBookPro 5,3",
314 .matches = {
315 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
316 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3"),
317 },
318 .driver_data = (void *)&nvidia_chipset_data,
319 },
320 {
321 .callback = mbp_dmi_match,
322 .ident = "MacBookPro 5,4",
323 .matches = {
324 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
325 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4"),
326 },
327 .driver_data = (void *)&nvidia_chipset_data,
328 },
329 {
330 .callback = mbp_dmi_match,
331 .ident = "MacBookPro 5,5",
332 .matches = {
333 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
334 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,5"),
335 },
336 .driver_data = (void *)&nvidia_chipset_data,
337 },
338 {
339 .callback = mbp_dmi_match,
340 .ident = "MacBookAir 3,1",
341 .matches = {
342 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
343 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,1"),
344 },
345 .driver_data = (void *)&nvidia_chipset_data,
346 },
347 {
348 .callback = mbp_dmi_match,
349 .ident = "MacBookAir 3,2",
350 .matches = {
351 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
352 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,2"),
353 },
354 .driver_data = (void *)&nvidia_chipset_data,
355 },
356 { }
357};
358
359static int __init mbp_init(void)
360{
361 struct backlight_properties props;
362 if (!dmi_check_system(mbp_device_table))
363 return -ENODEV;
364
365 if (!request_region(driver_data->iostart, driver_data->iolen,
366 "Macbook Pro backlight"))
367 return -ENXIO;
368
369 memset(&props, 0, sizeof(struct backlight_properties));
370 props.max_brightness = 15;
371 mbp_backlight_device = backlight_device_register("mbp_backlight", NULL,
372 NULL,
373 &driver_data->backlight_ops,
374 &props);
375 if (IS_ERR(mbp_backlight_device)) {
376 release_region(driver_data->iostart, driver_data->iolen);
377 return PTR_ERR(mbp_backlight_device);
378 }
379
380 mbp_backlight_device->props.brightness =
381 driver_data->backlight_ops.get_brightness(mbp_backlight_device);
382 backlight_update_status(mbp_backlight_device);
383
384 return 0;
385}
386
387static void __exit mbp_exit(void)
388{
389 backlight_device_unregister(mbp_backlight_device);
390
391 release_region(driver_data->iostart, driver_data->iolen);
392}
393
394module_init(mbp_init);
395module_exit(mbp_exit);
396
397MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
398MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver");
399MODULE_LICENSE("GPL");
400MODULE_DEVICE_TABLE(dmi, mbp_device_table);
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index d3bc56296c8d..08d26a72394c 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -146,6 +146,7 @@ static int omapbl_probe(struct platform_device *pdev)
146 return -ENOMEM; 146 return -ENOMEM;
147 147
148 memset(&props, 0, sizeof(struct backlight_properties)); 148 memset(&props, 0, sizeof(struct backlight_properties));
149 props.type = BACKLIGHT_RAW;
149 props.max_brightness = OMAPBL_MAX_INTENSITY; 150 props.max_brightness = OMAPBL_MAX_INTENSITY;
150 dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops, 151 dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
151 &props); 152 &props);
diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c
index 3c424f7efdcc..ef5628d60563 100644
--- a/drivers/video/backlight/pcf50633-backlight.c
+++ b/drivers/video/backlight/pcf50633-backlight.c
@@ -112,6 +112,7 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
112 if (!pcf_bl) 112 if (!pcf_bl)
113 return -ENOMEM; 113 return -ENOMEM;
114 114
115 bl_props.type = BACKLIGHT_RAW;
115 bl_props.max_brightness = 0x3f; 116 bl_props.max_brightness = 0x3f;
116 bl_props.power = FB_BLANK_UNBLANK; 117 bl_props.power = FB_BLANK_UNBLANK;
117 118
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
index 809278c90738..6af183d6465e 100644
--- a/drivers/video/backlight/progear_bl.c
+++ b/drivers/video/backlight/progear_bl.c
@@ -84,6 +84,7 @@ static int progearbl_probe(struct platform_device *pdev)
84 pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20); 84 pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
85 85
86 memset(&props, 0, sizeof(struct backlight_properties)); 86 memset(&props, 0, sizeof(struct backlight_properties));
87 props.type = BACKLIGHT_RAW;
87 props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; 88 props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
88 progear_backlight_device = backlight_device_register("progear-bl", 89 progear_backlight_device = backlight_device_register("progear-bl",
89 &pdev->dev, NULL, 90 &pdev->dev, NULL,
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 21866ec69656..b8f38ec6eb18 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -28,6 +28,7 @@ struct pwm_bl_data {
28 unsigned int lth_brightness; 28 unsigned int lth_brightness;
29 int (*notify)(struct device *, 29 int (*notify)(struct device *,
30 int brightness); 30 int brightness);
31 int (*check_fb)(struct device *, struct fb_info *);
31}; 32};
32 33
33static int pwm_backlight_update_status(struct backlight_device *bl) 34static int pwm_backlight_update_status(struct backlight_device *bl)
@@ -62,9 +63,18 @@ static int pwm_backlight_get_brightness(struct backlight_device *bl)
62 return bl->props.brightness; 63 return bl->props.brightness;
63} 64}
64 65
66static int pwm_backlight_check_fb(struct backlight_device *bl,
67 struct fb_info *info)
68{
69 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
70
71 return !pb->check_fb || pb->check_fb(pb->dev, info);
72}
73
65static const struct backlight_ops pwm_backlight_ops = { 74static const struct backlight_ops pwm_backlight_ops = {
66 .update_status = pwm_backlight_update_status, 75 .update_status = pwm_backlight_update_status,
67 .get_brightness = pwm_backlight_get_brightness, 76 .get_brightness = pwm_backlight_get_brightness,
77 .check_fb = pwm_backlight_check_fb,
68}; 78};
69 79
70static int pwm_backlight_probe(struct platform_device *pdev) 80static int pwm_backlight_probe(struct platform_device *pdev)
@@ -95,6 +105,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
95 105
96 pb->period = data->pwm_period_ns; 106 pb->period = data->pwm_period_ns;
97 pb->notify = data->notify; 107 pb->notify = data->notify;
108 pb->check_fb = data->check_fb;
98 pb->lth_brightness = data->lth_brightness * 109 pb->lth_brightness = data->lth_brightness *
99 (data->pwm_period_ns / data->max_brightness); 110 (data->pwm_period_ns / data->max_brightness);
100 pb->dev = &pdev->dev; 111 pb->dev = &pdev->dev;
@@ -108,6 +119,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
108 dev_dbg(&pdev->dev, "got pwm for backlight\n"); 119 dev_dbg(&pdev->dev, "got pwm for backlight\n");
109 120
110 memset(&props, 0, sizeof(struct backlight_properties)); 121 memset(&props, 0, sizeof(struct backlight_properties));
122 props.type = BACKLIGHT_RAW;
111 props.max_brightness = data->max_brightness; 123 props.max_brightness = data->max_brightness;
112 bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb, 124 bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
113 &pwm_backlight_ops, &props); 125 &pwm_backlight_ops, &props);
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c
index 5927db0da999..322040f686c2 100644
--- a/drivers/video/backlight/s6e63m0.c
+++ b/drivers/video/backlight/s6e63m0.c
@@ -778,6 +778,7 @@ static int __devinit s6e63m0_probe(struct spi_device *spi)
778 778
779 bd->props.max_brightness = MAX_BRIGHTNESS; 779 bd->props.max_brightness = MAX_BRIGHTNESS;
780 bd->props.brightness = MAX_BRIGHTNESS; 780 bd->props.brightness = MAX_BRIGHTNESS;
781 bd->props.type = BACKLIGHT_RAW;
781 lcd->bd = bd; 782 lcd->bd = bd;
782 783
783 /* 784 /*
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index 2a04b382ec48..425a7365470b 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -102,6 +102,7 @@ static int __devinit tosa_bl_probe(struct i2c_client *client,
102 data->i2c = client; 102 data->i2c = client;
103 103
104 memset(&props, 0, sizeof(struct backlight_properties)); 104 memset(&props, 0, sizeof(struct backlight_properties));
105 props.type = BACKLIGHT_RAW;
105 props.max_brightness = 512 - 1; 106 props.max_brightness = 512 - 1;
106 data->bl = backlight_device_register("tosa-bl", &client->dev, data, 107 data->bl = backlight_device_register("tosa-bl", &client->dev, data,
107 &bl_ops, &props); 108 &bl_ops, &props);
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
index 08fd87f3aecc..d4c6eb248ff9 100644
--- a/drivers/video/backlight/wm831x_bl.c
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -193,6 +193,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
193 data->current_brightness = 0; 193 data->current_brightness = 0;
194 data->isink_reg = isink_reg; 194 data->isink_reg = isink_reg;
195 195
196 props.type = BACKLIGHT_RAW;
196 props.max_brightness = max_isel; 197 props.max_brightness = max_isel;
197 bl = backlight_device_register("wm831x", &pdev->dev, data, 198 bl = backlight_device_register("wm831x", &pdev->dev, data,
198 &wm831x_backlight_ops, &props); 199 &wm831x_backlight_ops, &props);
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index e7d0f525041e..2464b910b590 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -649,6 +649,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
649 } 649 }
650#ifndef NO_BL_SUPPORT 650#ifndef NO_BL_SUPPORT
651 memset(&props, 0, sizeof(struct backlight_properties)); 651 memset(&props, 0, sizeof(struct backlight_properties));
652 props.type = BACKLIGHT_RAW;
652 props.max_brightness = 255; 653 props.max_brightness = 255;
653 bl_dev = backlight_device_register("bf54x-bl", NULL, NULL, 654 bl_dev = backlight_device_register("bf54x-bl", NULL, NULL,
654 &bfin_lq043fb_bl_ops, &props); 655 &bfin_lq043fb_bl_ops, &props);
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 3cf77676947c..d8de29f0dd8d 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -545,6 +545,7 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
545 } 545 }
546#ifndef NO_BL_SUPPORT 546#ifndef NO_BL_SUPPORT
547 memset(&props, 0, sizeof(struct backlight_properties)); 547 memset(&props, 0, sizeof(struct backlight_properties));
548 props.type = BACKLIGHT_RAW;
548 props.max_brightness = 255; 549 props.max_brightness = 255;
549 bl_dev = backlight_device_register("bf52x-bl", NULL, NULL, 550 bl_dev = backlight_device_register("bf52x-bl", NULL, NULL,
550 &bfin_lq043fb_bl_ops, &props); 551 &bfin_lq043fb_bl_ops, &props);
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 4dc13467281d..7ba74cd4be61 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -273,7 +273,7 @@ static int __devinit bw2_do_default_mode(struct bw2_par *par,
273 return 0; 273 return 0;
274} 274}
275 275
276static int __devinit bw2_probe(struct platform_device *op, const struct of_device_id *match) 276static int __devinit bw2_probe(struct platform_device *op)
277{ 277{
278 struct device_node *dp = op->dev.of_node; 278 struct device_node *dp = op->dev.of_node;
279 struct fb_info *info; 279 struct fb_info *info;
@@ -375,7 +375,7 @@ static const struct of_device_id bw2_match[] = {
375}; 375};
376MODULE_DEVICE_TABLE(of, bw2_match); 376MODULE_DEVICE_TABLE(of, bw2_match);
377 377
378static struct of_platform_driver bw2_driver = { 378static struct platform_driver bw2_driver = {
379 .driver = { 379 .driver = {
380 .name = "bw2", 380 .name = "bw2",
381 .owner = THIS_MODULE, 381 .owner = THIS_MODULE,
@@ -390,12 +390,12 @@ static int __init bw2_init(void)
390 if (fb_get_options("bw2fb", NULL)) 390 if (fb_get_options("bw2fb", NULL))
391 return -ENODEV; 391 return -ENODEV;
392 392
393 return of_register_platform_driver(&bw2_driver); 393 return platform_driver_register(&bw2_driver);
394} 394}
395 395
396static void __exit bw2_exit(void) 396static void __exit bw2_exit(void)
397{ 397{
398 of_unregister_platform_driver(&bw2_driver); 398 platform_driver_unregister(&bw2_driver);
399} 399}
400 400
401module_init(bw2_init); 401module_init(bw2_init);
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 24249535ac86..f18895006627 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -463,7 +463,7 @@ static void cg14_unmap_regs(struct platform_device *op, struct fb_info *info,
463 info->screen_base, info->fix.smem_len); 463 info->screen_base, info->fix.smem_len);
464} 464}
465 465
466static int __devinit cg14_probe(struct platform_device *op, const struct of_device_id *match) 466static int __devinit cg14_probe(struct platform_device *op)
467{ 467{
468 struct device_node *dp = op->dev.of_node; 468 struct device_node *dp = op->dev.of_node;
469 struct fb_info *info; 469 struct fb_info *info;
@@ -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;
@@ -595,7 +596,7 @@ static const struct of_device_id cg14_match[] = {
595}; 596};
596MODULE_DEVICE_TABLE(of, cg14_match); 597MODULE_DEVICE_TABLE(of, cg14_match);
597 598
598static struct of_platform_driver cg14_driver = { 599static struct platform_driver cg14_driver = {
599 .driver = { 600 .driver = {
600 .name = "cg14", 601 .name = "cg14",
601 .owner = THIS_MODULE, 602 .owner = THIS_MODULE,
@@ -610,12 +611,12 @@ static int __init cg14_init(void)
610 if (fb_get_options("cg14fb", NULL)) 611 if (fb_get_options("cg14fb", NULL))
611 return -ENODEV; 612 return -ENODEV;
612 613
613 return of_register_platform_driver(&cg14_driver); 614 return platform_driver_register(&cg14_driver);
614} 615}
615 616
616static void __exit cg14_exit(void) 617static void __exit cg14_exit(void)
617{ 618{
618 of_unregister_platform_driver(&cg14_driver); 619 platform_driver_unregister(&cg14_driver);
619} 620}
620 621
621module_init(cg14_init); 622module_init(cg14_init);
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 09c0c3c42482..f927a7b1a8d4 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -346,8 +346,7 @@ static int __devinit cg3_do_default_mode(struct cg3_par *par)
346 return 0; 346 return 0;
347} 347}
348 348
349static int __devinit cg3_probe(struct platform_device *op, 349static int __devinit cg3_probe(struct platform_device *op)
350 const struct of_device_id *match)
351{ 350{
352 struct device_node *dp = op->dev.of_node; 351 struct device_node *dp = op->dev.of_node;
353 struct fb_info *info; 352 struct fb_info *info;
@@ -462,7 +461,7 @@ static const struct of_device_id cg3_match[] = {
462}; 461};
463MODULE_DEVICE_TABLE(of, cg3_match); 462MODULE_DEVICE_TABLE(of, cg3_match);
464 463
465static struct of_platform_driver cg3_driver = { 464static struct platform_driver cg3_driver = {
466 .driver = { 465 .driver = {
467 .name = "cg3", 466 .name = "cg3",
468 .owner = THIS_MODULE, 467 .owner = THIS_MODULE,
@@ -477,12 +476,12 @@ static int __init cg3_init(void)
477 if (fb_get_options("cg3fb", NULL)) 476 if (fb_get_options("cg3fb", NULL))
478 return -ENODEV; 477 return -ENODEV;
479 478
480 return of_register_platform_driver(&cg3_driver); 479 return platform_driver_register(&cg3_driver);
481} 480}
482 481
483static void __exit cg3_exit(void) 482static void __exit cg3_exit(void)
484{ 483{
485 of_unregister_platform_driver(&cg3_driver); 484 platform_driver_unregister(&cg3_driver);
486} 485}
487 486
488module_init(cg3_init); 487module_init(cg3_init);
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 2b5a97058b08..179e96cdb323 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -737,8 +737,7 @@ static void cg6_unmap_regs(struct platform_device *op, struct fb_info *info,
737 info->fix.smem_len); 737 info->fix.smem_len);
738} 738}
739 739
740static int __devinit cg6_probe(struct platform_device *op, 740static int __devinit cg6_probe(struct platform_device *op)
741 const struct of_device_id *match)
742{ 741{
743 struct device_node *dp = op->dev.of_node; 742 struct device_node *dp = op->dev.of_node;
744 struct fb_info *info; 743 struct fb_info *info;
@@ -822,6 +821,7 @@ out_dealloc_cmap:
822 821
823out_unmap_regs: 822out_unmap_regs:
824 cg6_unmap_regs(op, info, par); 823 cg6_unmap_regs(op, info, par);
824 framebuffer_release(info);
825 825
826out_err: 826out_err:
827 return err; 827 return err;
@@ -855,7 +855,7 @@ static const struct of_device_id cg6_match[] = {
855}; 855};
856MODULE_DEVICE_TABLE(of, cg6_match); 856MODULE_DEVICE_TABLE(of, cg6_match);
857 857
858static struct of_platform_driver cg6_driver = { 858static struct platform_driver cg6_driver = {
859 .driver = { 859 .driver = {
860 .name = "cg6", 860 .name = "cg6",
861 .owner = THIS_MODULE, 861 .owner = THIS_MODULE,
@@ -870,12 +870,12 @@ static int __init cg6_init(void)
870 if (fb_get_options("cg6fb", NULL)) 870 if (fb_get_options("cg6fb", NULL))
871 return -ENODEV; 871 return -ENODEV;
872 872
873 return of_register_platform_driver(&cg6_driver); 873 return platform_driver_register(&cg6_driver);
874} 874}
875 875
876static void __exit cg6_exit(void) 876static void __exit cg6_exit(void)
877{ 877{
878 of_unregister_platform_driver(&cg6_driver); 878 platform_driver_unregister(&cg6_driver);
879} 879}
880 880
881module_init(cg6_init); 881module_init(cg6_init);
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/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 0c1afd13ddd3..850380795b05 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -47,6 +47,8 @@
47#include <linux/pci.h> 47#include <linux/pci.h>
48#include <linux/init.h> 48#include <linux/init.h>
49#include <linux/io.h> 49#include <linux/io.h>
50#include <linux/i2c.h>
51#include <linux/i2c-algo-bit.h>
50 52
51#include <asm/pgtable.h> 53#include <asm/pgtable.h>
52#include <asm/system.h> 54#include <asm/system.h>
@@ -61,10 +63,10 @@ struct cfb_info {
61 struct fb_info fb; 63 struct fb_info fb;
62 struct display_switch *dispsw; 64 struct display_switch *dispsw;
63 struct display *display; 65 struct display *display;
64 struct pci_dev *dev;
65 unsigned char __iomem *region; 66 unsigned char __iomem *region;
66 unsigned char __iomem *regs; 67 unsigned char __iomem *regs;
67 u_int id; 68 u_int id;
69 u_int irq;
68 int func_use_count; 70 int func_use_count;
69 u_long ref_ps; 71 u_long ref_ps;
70 72
@@ -88,6 +90,19 @@ struct cfb_info {
88 u_char ramdac_powerdown; 90 u_char ramdac_powerdown;
89 91
90 u32 pseudo_palette[16]; 92 u32 pseudo_palette[16];
93
94 spinlock_t reg_b0_lock;
95
96#ifdef CONFIG_FB_CYBER2000_DDC
97 bool ddc_registered;
98 struct i2c_adapter ddc_adapter;
99 struct i2c_algo_bit_data ddc_algo;
100#endif
101
102#ifdef CONFIG_FB_CYBER2000_I2C
103 struct i2c_adapter i2c_adapter;
104 struct i2c_algo_bit_data i2c_algo;
105#endif
91}; 106};
92 107
93static char *default_font = "Acorn8x8"; 108static char *default_font = "Acorn8x8";
@@ -494,6 +509,7 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
494 cyber2000_attrw(0x14, 0x00, cfb); 509 cyber2000_attrw(0x14, 0x00, cfb);
495 510
496 /* PLL registers */ 511 /* PLL registers */
512 spin_lock(&cfb->reg_b0_lock);
497 cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb); 513 cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb);
498 cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb); 514 cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
499 cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb); 515 cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb);
@@ -501,6 +517,7 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
501 cyber2000_grphw(0x90, 0x01, cfb); 517 cyber2000_grphw(0x90, 0x01, cfb);
502 cyber2000_grphw(0xb9, 0x80, cfb); 518 cyber2000_grphw(0xb9, 0x80, cfb);
503 cyber2000_grphw(0xb9, 0x00, cfb); 519 cyber2000_grphw(0xb9, 0x00, cfb);
520 spin_unlock(&cfb->reg_b0_lock);
504 521
505 cfb->ramdac_ctrl = hw->ramdac; 522 cfb->ramdac_ctrl = hw->ramdac;
506 cyber2000fb_write_ramdac_ctrl(cfb); 523 cyber2000fb_write_ramdac_ctrl(cfb);
@@ -681,9 +698,9 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
681 * pll_ps_calc = best_div1 / (ref_ps * best_mult) 698 * pll_ps_calc = best_div1 / (ref_ps * best_mult)
682 */ 699 */
683 best_diff = 0x7fffffff; 700 best_diff = 0x7fffffff;
684 best_mult = 32; 701 best_mult = 2;
685 best_div1 = 255; 702 best_div1 = 32;
686 for (t_div1 = 32; t_div1 > 1; t_div1 -= 1) { 703 for (t_div1 = 2; t_div1 < 32; t_div1 += 1) {
687 u_int rr, t_mult, t_pll_ps; 704 u_int rr, t_mult, t_pll_ps;
688 int diff; 705 int diff;
689 706
@@ -1105,24 +1122,22 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb)
1105} 1122}
1106EXPORT_SYMBOL(cyber2000fb_disable_extregs); 1123EXPORT_SYMBOL(cyber2000fb_disable_extregs);
1107 1124
1108void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
1109{
1110 memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo));
1111}
1112EXPORT_SYMBOL(cyber2000fb_get_fb_var);
1113
1114/* 1125/*
1115 * Attach a capture/tv driver to the core CyberX0X0 driver. 1126 * Attach a capture/tv driver to the core CyberX0X0 driver.
1116 */ 1127 */
1117int cyber2000fb_attach(struct cyberpro_info *info, int idx) 1128int cyber2000fb_attach(struct cyberpro_info *info, int idx)
1118{ 1129{
1119 if (int_cfb_info != NULL) { 1130 if (int_cfb_info != NULL) {
1120 info->dev = int_cfb_info->dev; 1131 info->dev = int_cfb_info->fb.device;
1132#ifdef CONFIG_FB_CYBER2000_I2C
1133 info->i2c = &int_cfb_info->i2c_adapter;
1134#else
1135 info->i2c = NULL;
1136#endif
1121 info->regs = int_cfb_info->regs; 1137 info->regs = int_cfb_info->regs;
1138 info->irq = int_cfb_info->irq;
1122 info->fb = int_cfb_info->fb.screen_base; 1139 info->fb = int_cfb_info->fb.screen_base;
1123 info->fb_size = int_cfb_info->fb.fix.smem_len; 1140 info->fb_size = int_cfb_info->fb.fix.smem_len;
1124 info->enable_extregs = cyber2000fb_enable_extregs;
1125 info->disable_extregs = cyber2000fb_disable_extregs;
1126 info->info = int_cfb_info; 1141 info->info = int_cfb_info;
1127 1142
1128 strlcpy(info->dev_name, int_cfb_info->fb.fix.id, 1143 strlcpy(info->dev_name, int_cfb_info->fb.fix.id,
@@ -1141,6 +1156,183 @@ void cyber2000fb_detach(int idx)
1141} 1156}
1142EXPORT_SYMBOL(cyber2000fb_detach); 1157EXPORT_SYMBOL(cyber2000fb_detach);
1143 1158
1159#ifdef CONFIG_FB_CYBER2000_DDC
1160
1161#define DDC_REG 0xb0
1162#define DDC_SCL_OUT (1 << 0)
1163#define DDC_SDA_OUT (1 << 4)
1164#define DDC_SCL_IN (1 << 2)
1165#define DDC_SDA_IN (1 << 6)
1166
1167static void cyber2000fb_enable_ddc(struct cfb_info *cfb)
1168{
1169 spin_lock(&cfb->reg_b0_lock);
1170 cyber2000fb_writew(0x1bf, 0x3ce, cfb);
1171}
1172
1173static void cyber2000fb_disable_ddc(struct cfb_info *cfb)
1174{
1175 cyber2000fb_writew(0x0bf, 0x3ce, cfb);
1176 spin_unlock(&cfb->reg_b0_lock);
1177}
1178
1179
1180static void cyber2000fb_ddc_setscl(void *data, int val)
1181{
1182 struct cfb_info *cfb = data;
1183 unsigned char reg;
1184
1185 cyber2000fb_enable_ddc(cfb);
1186 reg = cyber2000_grphr(DDC_REG, cfb);
1187 if (!val) /* bit is inverted */
1188 reg |= DDC_SCL_OUT;
1189 else
1190 reg &= ~DDC_SCL_OUT;
1191 cyber2000_grphw(DDC_REG, reg, cfb);
1192 cyber2000fb_disable_ddc(cfb);
1193}
1194
1195static void cyber2000fb_ddc_setsda(void *data, int val)
1196{
1197 struct cfb_info *cfb = data;
1198 unsigned char reg;
1199
1200 cyber2000fb_enable_ddc(cfb);
1201 reg = cyber2000_grphr(DDC_REG, cfb);
1202 if (!val) /* bit is inverted */
1203 reg |= DDC_SDA_OUT;
1204 else
1205 reg &= ~DDC_SDA_OUT;
1206 cyber2000_grphw(DDC_REG, reg, cfb);
1207 cyber2000fb_disable_ddc(cfb);
1208}
1209
1210static int cyber2000fb_ddc_getscl(void *data)
1211{
1212 struct cfb_info *cfb = data;
1213 int retval;
1214
1215 cyber2000fb_enable_ddc(cfb);
1216 retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SCL_IN);
1217 cyber2000fb_disable_ddc(cfb);
1218
1219 return retval;
1220}
1221
1222static int cyber2000fb_ddc_getsda(void *data)
1223{
1224 struct cfb_info *cfb = data;
1225 int retval;
1226
1227 cyber2000fb_enable_ddc(cfb);
1228 retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SDA_IN);
1229 cyber2000fb_disable_ddc(cfb);
1230
1231 return retval;
1232}
1233
1234static int __devinit cyber2000fb_setup_ddc_bus(struct cfb_info *cfb)
1235{
1236 strlcpy(cfb->ddc_adapter.name, cfb->fb.fix.id,
1237 sizeof(cfb->ddc_adapter.name));
1238 cfb->ddc_adapter.owner = THIS_MODULE;
1239 cfb->ddc_adapter.class = I2C_CLASS_DDC;
1240 cfb->ddc_adapter.algo_data = &cfb->ddc_algo;
1241 cfb->ddc_adapter.dev.parent = cfb->fb.device;
1242 cfb->ddc_algo.setsda = cyber2000fb_ddc_setsda;
1243 cfb->ddc_algo.setscl = cyber2000fb_ddc_setscl;
1244 cfb->ddc_algo.getsda = cyber2000fb_ddc_getsda;
1245 cfb->ddc_algo.getscl = cyber2000fb_ddc_getscl;
1246 cfb->ddc_algo.udelay = 10;
1247 cfb->ddc_algo.timeout = 20;
1248 cfb->ddc_algo.data = cfb;
1249
1250 i2c_set_adapdata(&cfb->ddc_adapter, cfb);
1251
1252 return i2c_bit_add_bus(&cfb->ddc_adapter);
1253}
1254#endif /* CONFIG_FB_CYBER2000_DDC */
1255
1256#ifdef CONFIG_FB_CYBER2000_I2C
1257static void cyber2000fb_i2c_setsda(void *data, int state)
1258{
1259 struct cfb_info *cfb = data;
1260 unsigned int latch2;
1261
1262 spin_lock(&cfb->reg_b0_lock);
1263 latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
1264 latch2 &= EXT_LATCH2_I2C_CLKEN;
1265 if (state)
1266 latch2 |= EXT_LATCH2_I2C_DATEN;
1267 cyber2000_grphw(EXT_LATCH2, latch2, cfb);
1268 spin_unlock(&cfb->reg_b0_lock);
1269}
1270
1271static void cyber2000fb_i2c_setscl(void *data, int state)
1272{
1273 struct cfb_info *cfb = data;
1274 unsigned int latch2;
1275
1276 spin_lock(&cfb->reg_b0_lock);
1277 latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
1278 latch2 &= EXT_LATCH2_I2C_DATEN;
1279 if (state)
1280 latch2 |= EXT_LATCH2_I2C_CLKEN;
1281 cyber2000_grphw(EXT_LATCH2, latch2, cfb);
1282 spin_unlock(&cfb->reg_b0_lock);
1283}
1284
1285static int cyber2000fb_i2c_getsda(void *data)
1286{
1287 struct cfb_info *cfb = data;
1288 int ret;
1289
1290 spin_lock(&cfb->reg_b0_lock);
1291 ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_DAT);
1292 spin_unlock(&cfb->reg_b0_lock);
1293
1294 return ret;
1295}
1296
1297static int cyber2000fb_i2c_getscl(void *data)
1298{
1299 struct cfb_info *cfb = data;
1300 int ret;
1301
1302 spin_lock(&cfb->reg_b0_lock);
1303 ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_CLK);
1304 spin_unlock(&cfb->reg_b0_lock);
1305
1306 return ret;
1307}
1308
1309static int __devinit cyber2000fb_i2c_register(struct cfb_info *cfb)
1310{
1311 strlcpy(cfb->i2c_adapter.name, cfb->fb.fix.id,
1312 sizeof(cfb->i2c_adapter.name));
1313 cfb->i2c_adapter.owner = THIS_MODULE;
1314 cfb->i2c_adapter.algo_data = &cfb->i2c_algo;
1315 cfb->i2c_adapter.dev.parent = cfb->fb.device;
1316 cfb->i2c_algo.setsda = cyber2000fb_i2c_setsda;
1317 cfb->i2c_algo.setscl = cyber2000fb_i2c_setscl;
1318 cfb->i2c_algo.getsda = cyber2000fb_i2c_getsda;
1319 cfb->i2c_algo.getscl = cyber2000fb_i2c_getscl;
1320 cfb->i2c_algo.udelay = 5;
1321 cfb->i2c_algo.timeout = msecs_to_jiffies(100);
1322 cfb->i2c_algo.data = cfb;
1323
1324 return i2c_bit_add_bus(&cfb->i2c_adapter);
1325}
1326
1327static void cyber2000fb_i2c_unregister(struct cfb_info *cfb)
1328{
1329 i2c_del_adapter(&cfb->i2c_adapter);
1330}
1331#else
1332#define cyber2000fb_i2c_register(cfb) (0)
1333#define cyber2000fb_i2c_unregister(cfb) do { } while (0)
1334#endif
1335
1144/* 1336/*
1145 * These parameters give 1337 * These parameters give
1146 * 640x480, hsync 31.5kHz, vsync 60Hz 1338 * 640x480, hsync 31.5kHz, vsync 60Hz
@@ -1275,6 +1467,8 @@ static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id,
1275 cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1467 cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1276 cfb->fb.pseudo_palette = cfb->pseudo_palette; 1468 cfb->fb.pseudo_palette = cfb->pseudo_palette;
1277 1469
1470 spin_lock_init(&cfb->reg_b0_lock);
1471
1278 fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0); 1472 fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
1279 1473
1280 return cfb; 1474 return cfb;
@@ -1369,6 +1563,11 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
1369 cfb->fb.fix.mmio_len = MMIO_SIZE; 1563 cfb->fb.fix.mmio_len = MMIO_SIZE;
1370 cfb->fb.screen_base = cfb->region; 1564 cfb->fb.screen_base = cfb->region;
1371 1565
1566#ifdef CONFIG_FB_CYBER2000_DDC
1567 if (cyber2000fb_setup_ddc_bus(cfb) == 0)
1568 cfb->ddc_registered = true;
1569#endif
1570
1372 err = -EINVAL; 1571 err = -EINVAL;
1373 if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0, 1572 if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
1374 &cyber2000fb_default_mode, 8)) { 1573 &cyber2000fb_default_mode, 8)) {
@@ -1401,14 +1600,32 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
1401 cfb->fb.var.xres, cfb->fb.var.yres, 1600 cfb->fb.var.xres, cfb->fb.var.yres,
1402 h_sync / 1000, h_sync % 1000, v_sync); 1601 h_sync / 1000, h_sync % 1000, v_sync);
1403 1602
1404 if (cfb->dev) 1603 err = cyber2000fb_i2c_register(cfb);
1405 cfb->fb.device = &cfb->dev->dev; 1604 if (err)
1605 goto failed;
1606
1406 err = register_framebuffer(&cfb->fb); 1607 err = register_framebuffer(&cfb->fb);
1608 if (err)
1609 cyber2000fb_i2c_unregister(cfb);
1407 1610
1408failed: 1611failed:
1612#ifdef CONFIG_FB_CYBER2000_DDC
1613 if (err && cfb->ddc_registered)
1614 i2c_del_adapter(&cfb->ddc_adapter);
1615#endif
1409 return err; 1616 return err;
1410} 1617}
1411 1618
1619static void __devexit cyberpro_common_remove(struct cfb_info *cfb)
1620{
1621 unregister_framebuffer(&cfb->fb);
1622#ifdef CONFIG_FB_CYBER2000_DDC
1623 if (cfb->ddc_registered)
1624 i2c_del_adapter(&cfb->ddc_adapter);
1625#endif
1626 cyber2000fb_i2c_unregister(cfb);
1627}
1628
1412static void cyberpro_common_resume(struct cfb_info *cfb) 1629static void cyberpro_common_resume(struct cfb_info *cfb)
1413{ 1630{
1414 cyberpro_init_hw(cfb); 1631 cyberpro_init_hw(cfb);
@@ -1442,12 +1659,13 @@ static int __devinit cyberpro_vl_probe(void)
1442 if (!cfb) 1659 if (!cfb)
1443 goto failed_release; 1660 goto failed_release;
1444 1661
1445 cfb->dev = NULL; 1662 cfb->irq = -1;
1446 cfb->region = ioremap(FB_START, FB_SIZE); 1663 cfb->region = ioremap(FB_START, FB_SIZE);
1447 if (!cfb->region) 1664 if (!cfb->region)
1448 goto failed_ioremap; 1665 goto failed_ioremap;
1449 1666
1450 cfb->regs = cfb->region + MMIO_OFFSET; 1667 cfb->regs = cfb->region + MMIO_OFFSET;
1668 cfb->fb.device = NULL;
1451 cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET; 1669 cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET;
1452 cfb->fb.fix.smem_start = FB_START; 1670 cfb->fb.fix.smem_start = FB_START;
1453 1671
@@ -1585,12 +1803,13 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1585 if (err) 1803 if (err)
1586 goto failed_regions; 1804 goto failed_regions;
1587 1805
1588 cfb->dev = dev; 1806 cfb->irq = dev->irq;
1589 cfb->region = pci_ioremap_bar(dev, 0); 1807 cfb->region = pci_ioremap_bar(dev, 0);
1590 if (!cfb->region) 1808 if (!cfb->region)
1591 goto failed_ioremap; 1809 goto failed_ioremap;
1592 1810
1593 cfb->regs = cfb->region + MMIO_OFFSET; 1811 cfb->regs = cfb->region + MMIO_OFFSET;
1812 cfb->fb.device = &dev->dev;
1594 cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET; 1813 cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
1595 cfb->fb.fix.smem_start = pci_resource_start(dev, 0); 1814 cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
1596 1815
@@ -1648,15 +1867,7 @@ static void __devexit cyberpro_pci_remove(struct pci_dev *dev)
1648 struct cfb_info *cfb = pci_get_drvdata(dev); 1867 struct cfb_info *cfb = pci_get_drvdata(dev);
1649 1868
1650 if (cfb) { 1869 if (cfb) {
1651 /* 1870 cyberpro_common_remove(cfb);
1652 * If unregister_framebuffer fails, then
1653 * we will be leaving hooks that could cause
1654 * oopsen laying around.
1655 */
1656 if (unregister_framebuffer(&cfb->fb))
1657 printk(KERN_WARNING "%s: danger Will Robinson, "
1658 "danger danger! Oopsen imminent!\n",
1659 cfb->fb.fix.id);
1660 iounmap(cfb->region); 1871 iounmap(cfb->region);
1661 cyberpro_free_fb_info(cfb); 1872 cyberpro_free_fb_info(cfb);
1662 1873
diff --git a/drivers/video/cyber2000fb.h b/drivers/video/cyber2000fb.h
index de4fc43e51c1..bad69102e774 100644
--- a/drivers/video/cyber2000fb.h
+++ b/drivers/video/cyber2000fb.h
@@ -464,12 +464,14 @@ static void debug_printf(char *fmt, ...)
464struct cfb_info; 464struct cfb_info;
465 465
466struct cyberpro_info { 466struct cyberpro_info {
467 struct pci_dev *dev; 467 struct device *dev;
468 struct i2c_adapter *i2c;
468 unsigned char __iomem *regs; 469 unsigned char __iomem *regs;
469 char __iomem *fb; 470 char __iomem *fb;
470 char dev_name[32]; 471 char dev_name[32];
471 unsigned int fb_size; 472 unsigned int fb_size;
472 unsigned int chip_id; 473 unsigned int chip_id;
474 unsigned int irq;
473 475
474 /* 476 /*
475 * The following is a pointer to be passed into the 477 * The following is a pointer to be passed into the
@@ -478,15 +480,6 @@ struct cyberpro_info {
478 * is within this structure. 480 * is within this structure.
479 */ 481 */
480 struct cfb_info *info; 482 struct cfb_info *info;
481
482 /*
483 * Use these to enable the BM or TV registers. In an SMP
484 * environment, these two function pointers should only be
485 * called from the module_init() or module_exit()
486 * functions.
487 */
488 void (*enable_extregs)(struct cfb_info *);
489 void (*disable_extregs)(struct cfb_info *);
490}; 483};
491 484
492#define ID_IGA_1682 0 485#define ID_IGA_1682 0
@@ -494,8 +487,6 @@ struct cyberpro_info {
494#define ID_CYBERPRO_2010 2 487#define ID_CYBERPRO_2010 2
495#define ID_CYBERPRO_5000 3 488#define ID_CYBERPRO_5000 3
496 489
497struct fb_var_screeninfo;
498
499/* 490/*
500 * Note! Writing to the Cyber20x0 registers from an interrupt 491 * Note! Writing to the Cyber20x0 registers from an interrupt
501 * routine is definitely a bad idea atm. 492 * routine is definitely a bad idea atm.
@@ -504,4 +495,3 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx);
504void cyber2000fb_detach(int idx); 495void cyber2000fb_detach(int idx);
505void cyber2000fb_enable_extregs(struct cfb_info *cfb); 496void cyber2000fb_enable_extregs(struct cfb_info *cfb);
506void cyber2000fb_disable_extregs(struct cfb_info *cfb); 497void cyber2000fb_disable_extregs(struct cfb_info *cfb);
507void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var);
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/fb-puv3.c b/drivers/video/fb-puv3.c
new file mode 100644
index 000000000000..dbd2dc4745d1
--- /dev/null
+++ b/drivers/video/fb-puv3.c
@@ -0,0 +1,846 @@
1/*
2 * Frame Buffer Driver for PKUnity-v3 Unigfx
3 * Code specific to PKUnity SoC and UniCore ISA
4 *
5 * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
6 * Copyright (C) 2001-2010 Guan Xuetao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/vmalloc.h>
17#include <linux/platform_device.h>
18#include <linux/clk.h>
19#include <linux/fb.h>
20#include <linux/init.h>
21#include <linux/console.h>
22
23#include <asm/sizes.h>
24#include <mach/hardware.h>
25
26/* Platform_data reserved for unifb registers. */
27#define UNIFB_REGS_NUM 10
28/* RAM reserved for the frame buffer. */
29#define UNIFB_MEMSIZE (SZ_4M) /* 4 MB for 1024*768*32b */
30
31/*
32 * cause UNIGFX don not have EDID
33 * all the modes are organized as follow
34 */
35static const struct fb_videomode unifb_modes[] = {
36 /* 0 640x480-60 VESA */
37 { "640x480@60", 60, 640, 480, 25175000, 48, 16, 34, 10, 96, 1,
38 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
39 /* 1 640x480-75 VESA */
40 { "640x480@75", 75, 640, 480, 31500000, 120, 16, 18, 1, 64, 1,
41 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
42 /* 2 800x600-60 VESA */
43 { "800x600@60", 60, 800, 600, 40000000, 88, 40, 26, 1, 128, 1,
44 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
45 /* 3 800x600-75 VESA */
46 { "800x600@75", 75, 800, 600, 49500000, 160, 16, 23, 1, 80, 1,
47 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
48 /* 4 1024x768-60 VESA */
49 { "1024x768@60", 60, 1024, 768, 65000000, 160, 24, 34, 3, 136, 1,
50 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
51 /* 5 1024x768-75 VESA */
52 { "1024x768@75", 75, 1024, 768, 78750000, 176, 16, 30, 1, 96, 1,
53 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
54 /* 6 1280x960-60 VESA */
55 { "1280x960@60", 60, 1280, 960, 108000000, 312, 96, 38, 1, 112, 1,
56 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
57 /* 7 1440x900-60 VESA */
58 { "1440x900@60", 60, 1440, 900, 106500000, 232, 80, 30, 3, 152, 1,
59 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
60 /* 8 FIXME 9 1024x600-60 VESA UNTESTED */
61 { "1024x600@60", 60, 1024, 600, 50650000, 160, 24, 26, 1, 136, 1,
62 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
63 /* 9 FIXME 10 1024x600-75 VESA UNTESTED */
64 { "1024x600@75", 75, 1024, 600, 61500000, 176, 16, 23, 1, 96, 1,
65 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
66 /* 10 FIXME 11 1366x768-60 VESA UNTESTED */
67 { "1366x768@60", 60, 1366, 768, 85500000, 256, 58, 18, 1, 112, 3,
68 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
69};
70
71static struct fb_var_screeninfo unifb_default = {
72 .xres = 640,
73 .yres = 480,
74 .xres_virtual = 640,
75 .yres_virtual = 480,
76 .bits_per_pixel = 16,
77 .red = { 11, 5, 0 },
78 .green = { 5, 6, 0 },
79 .blue = { 0, 5, 0 },
80 .activate = FB_ACTIVATE_NOW,
81 .height = -1,
82 .width = -1,
83 .pixclock = 25175000,
84 .left_margin = 48,
85 .right_margin = 16,
86 .upper_margin = 33,
87 .lower_margin = 10,
88 .hsync_len = 96,
89 .vsync_len = 2,
90 .vmode = FB_VMODE_NONINTERLACED,
91};
92
93static struct fb_fix_screeninfo unifb_fix = {
94 .id = "UNIGFX FB",
95 .type = FB_TYPE_PACKED_PIXELS,
96 .visual = FB_VISUAL_TRUECOLOR,
97 .xpanstep = 1,
98 .ypanstep = 1,
99 .ywrapstep = 1,
100 .accel = FB_ACCEL_NONE,
101};
102
103static void unifb_sync(struct fb_info *info)
104{
105 /* TODO: may, this can be replaced by interrupt */
106 int cnt;
107
108 for (cnt = 0; cnt < 0x10000000; cnt++) {
109 if (readl(UGE_COMMAND) & 0x1000000)
110 return;
111 }
112
113 if (cnt > 0x8000000)
114 dev_warn(info->device, "Warning: UniGFX GE time out ...\n");
115}
116
117static void unifb_prim_fillrect(struct fb_info *info,
118 const struct fb_fillrect *region)
119{
120 int awidth = region->width;
121 int aheight = region->height;
122 int m_iBpp = info->var.bits_per_pixel;
123 int screen_width = info->var.xres;
124 int src_sel = 1; /* from fg_color */
125 int pat_sel = 1;
126 int src_x0 = 0;
127 int dst_x0 = region->dx;
128 int src_y0 = 0;
129 int dst_y0 = region->dy;
130 int rop_alpha_sel = 0;
131 int rop_alpha_code = 0xCC;
132 int x_dir = 1;
133 int y_dir = 1;
134 int alpha_r = 0;
135 int alpha_sel = 0;
136 int dst_pitch = screen_width * (m_iBpp / 8);
137 int dst_offset = dst_y0 * dst_pitch + dst_x0 * (m_iBpp / 8);
138 int src_pitch = screen_width * (m_iBpp / 8);
139 int src_offset = src_y0 * src_pitch + src_x0 * (m_iBpp / 8);
140 unsigned int command = 0;
141 int clip_region = 0;
142 int clip_en = 0;
143 int tp_en = 0;
144 int fg_color = 0;
145 int bottom = info->var.yres - 1;
146 int right = info->var.xres - 1;
147 int top = 0;
148
149 bottom = (bottom << 16) | right;
150 command = (rop_alpha_sel << 26) | (pat_sel << 18) | (src_sel << 16)
151 | (x_dir << 20) | (y_dir << 21) | (command << 24)
152 | (clip_region << 23) | (clip_en << 22) | (tp_en << 27);
153 src_pitch = (dst_pitch << 16) | src_pitch;
154 awidth = awidth | (aheight << 16);
155 alpha_r = ((rop_alpha_code & 0xff) << 8) | (alpha_r & 0xff)
156 | (alpha_sel << 16);
157 src_x0 = (src_x0 & 0x1fff) | ((src_y0 & 0x1fff) << 16);
158 dst_x0 = (dst_x0 & 0x1fff) | ((dst_y0 & 0x1fff) << 16);
159 fg_color = region->color;
160
161 unifb_sync(info);
162
163 writel(((u32 *)(info->pseudo_palette))[fg_color], UGE_FCOLOR);
164 writel(0, UGE_BCOLOR);
165 writel(src_pitch, UGE_PITCH);
166 writel(src_offset, UGE_SRCSTART);
167 writel(dst_offset, UGE_DSTSTART);
168 writel(awidth, UGE_WIDHEIGHT);
169 writel(top, UGE_CLIP0);
170 writel(bottom, UGE_CLIP1);
171 writel(alpha_r, UGE_ROPALPHA);
172 writel(src_x0, UGE_SRCXY);
173 writel(dst_x0, UGE_DSTXY);
174 writel(command, UGE_COMMAND);
175}
176
177static void unifb_fillrect(struct fb_info *info,
178 const struct fb_fillrect *region)
179{
180 struct fb_fillrect modded;
181 int vxres, vyres;
182
183 if (info->flags & FBINFO_HWACCEL_DISABLED) {
184 sys_fillrect(info, region);
185 return;
186 }
187
188 vxres = info->var.xres_virtual;
189 vyres = info->var.yres_virtual;
190
191 memcpy(&modded, region, sizeof(struct fb_fillrect));
192
193 if (!modded.width || !modded.height ||
194 modded.dx >= vxres || modded.dy >= vyres)
195 return;
196
197 if (modded.dx + modded.width > vxres)
198 modded.width = vxres - modded.dx;
199 if (modded.dy + modded.height > vyres)
200 modded.height = vyres - modded.dy;
201
202 unifb_prim_fillrect(info, &modded);
203}
204
205static void unifb_prim_copyarea(struct fb_info *info,
206 const struct fb_copyarea *area)
207{
208 int awidth = area->width;
209 int aheight = area->height;
210 int m_iBpp = info->var.bits_per_pixel;
211 int screen_width = info->var.xres;
212 int src_sel = 2; /* from mem */
213 int pat_sel = 0;
214 int src_x0 = area->sx;
215 int dst_x0 = area->dx;
216 int src_y0 = area->sy;
217 int dst_y0 = area->dy;
218
219 int rop_alpha_sel = 0;
220 int rop_alpha_code = 0xCC;
221 int x_dir = 1;
222 int y_dir = 1;
223
224 int alpha_r = 0;
225 int alpha_sel = 0;
226 int dst_pitch = screen_width * (m_iBpp / 8);
227 int dst_offset = dst_y0 * dst_pitch + dst_x0 * (m_iBpp / 8);
228 int src_pitch = screen_width * (m_iBpp / 8);
229 int src_offset = src_y0 * src_pitch + src_x0 * (m_iBpp / 8);
230 unsigned int command = 0;
231 int clip_region = 0;
232 int clip_en = 1;
233 int tp_en = 0;
234 int top = 0;
235 int bottom = info->var.yres;
236 int right = info->var.xres;
237 int fg_color = 0;
238 int bg_color = 0;
239
240 if (src_x0 < 0)
241 src_x0 = 0;
242 if (src_y0 < 0)
243 src_y0 = 0;
244
245 if (src_y0 - dst_y0 > 0) {
246 y_dir = 1;
247 } else {
248 y_dir = 0;
249 src_offset = (src_y0 + aheight) * src_pitch +
250 src_x0 * (m_iBpp / 8);
251 dst_offset = (dst_y0 + aheight) * dst_pitch +
252 dst_x0 * (m_iBpp / 8);
253 src_y0 += aheight;
254 dst_y0 += aheight;
255 }
256
257 command = (rop_alpha_sel << 26) | (pat_sel << 18) | (src_sel << 16) |
258 (x_dir << 20) | (y_dir << 21) | (command << 24) |
259 (clip_region << 23) | (clip_en << 22) | (tp_en << 27);
260 src_pitch = (dst_pitch << 16) | src_pitch;
261 awidth = awidth | (aheight << 16);
262 alpha_r = ((rop_alpha_code & 0xff) << 8) | (alpha_r & 0xff) |
263 (alpha_sel << 16);
264 src_x0 = (src_x0 & 0x1fff) | ((src_y0 & 0x1fff) << 16);
265 dst_x0 = (dst_x0 & 0x1fff) | ((dst_y0 & 0x1fff) << 16);
266 bottom = (bottom << 16) | right;
267
268 unifb_sync(info);
269
270 writel(src_pitch, UGE_PITCH);
271 writel(src_offset, UGE_SRCSTART);
272 writel(dst_offset, UGE_DSTSTART);
273 writel(awidth, UGE_WIDHEIGHT);
274 writel(top, UGE_CLIP0);
275 writel(bottom, UGE_CLIP1);
276 writel(bg_color, UGE_BCOLOR);
277 writel(fg_color, UGE_FCOLOR);
278 writel(alpha_r, UGE_ROPALPHA);
279 writel(src_x0, UGE_SRCXY);
280 writel(dst_x0, UGE_DSTXY);
281 writel(command, UGE_COMMAND);
282}
283
284static void unifb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
285{
286 struct fb_copyarea modded;
287 u32 vxres, vyres;
288 modded.sx = area->sx;
289 modded.sy = area->sy;
290 modded.dx = area->dx;
291 modded.dy = area->dy;
292 modded.width = area->width;
293 modded.height = area->height;
294
295 if (info->flags & FBINFO_HWACCEL_DISABLED) {
296 sys_copyarea(info, area);
297 return;
298 }
299
300 vxres = info->var.xres_virtual;
301 vyres = info->var.yres_virtual;
302
303 if (!modded.width || !modded.height ||
304 modded.sx >= vxres || modded.sy >= vyres ||
305 modded.dx >= vxres || modded.dy >= vyres)
306 return;
307
308 if (modded.sx + modded.width > vxres)
309 modded.width = vxres - modded.sx;
310 if (modded.dx + modded.width > vxres)
311 modded.width = vxres - modded.dx;
312 if (modded.sy + modded.height > vyres)
313 modded.height = vyres - modded.sy;
314 if (modded.dy + modded.height > vyres)
315 modded.height = vyres - modded.dy;
316
317 unifb_prim_copyarea(info, &modded);
318}
319
320static void unifb_imageblit(struct fb_info *info, const struct fb_image *image)
321{
322 sys_imageblit(info, image);
323}
324
325static u_long get_line_length(int xres_virtual, int bpp)
326{
327 u_long length;
328
329 length = xres_virtual * bpp;
330 length = (length + 31) & ~31;
331 length >>= 3;
332 return length;
333}
334
335/*
336 * Setting the video mode has been split into two parts.
337 * First part, xxxfb_check_var, must not write anything
338 * to hardware, it should only verify and adjust var.
339 * This means it doesn't alter par but it does use hardware
340 * data from it to check this var.
341 */
342static int unifb_check_var(struct fb_var_screeninfo *var,
343 struct fb_info *info)
344{
345 u_long line_length;
346
347 /*
348 * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
349 * as FB_VMODE_SMOOTH_XPAN is only used internally
350 */
351
352 if (var->vmode & FB_VMODE_CONUPDATE) {
353 var->vmode |= FB_VMODE_YWRAP;
354 var->xoffset = info->var.xoffset;
355 var->yoffset = info->var.yoffset;
356 }
357
358 /*
359 * Some very basic checks
360 */
361 if (!var->xres)
362 var->xres = 1;
363 if (!var->yres)
364 var->yres = 1;
365 if (var->xres > var->xres_virtual)
366 var->xres_virtual = var->xres;
367 if (var->yres > var->yres_virtual)
368 var->yres_virtual = var->yres;
369 if (var->bits_per_pixel <= 1)
370 var->bits_per_pixel = 1;
371 else if (var->bits_per_pixel <= 8)
372 var->bits_per_pixel = 8;
373 else if (var->bits_per_pixel <= 16)
374 var->bits_per_pixel = 16;
375 else if (var->bits_per_pixel <= 24)
376 var->bits_per_pixel = 24;
377 else if (var->bits_per_pixel <= 32)
378 var->bits_per_pixel = 32;
379 else
380 return -EINVAL;
381
382 if (var->xres_virtual < var->xoffset + var->xres)
383 var->xres_virtual = var->xoffset + var->xres;
384 if (var->yres_virtual < var->yoffset + var->yres)
385 var->yres_virtual = var->yoffset + var->yres;
386
387 /*
388 * Memory limit
389 */
390 line_length =
391 get_line_length(var->xres_virtual, var->bits_per_pixel);
392 if (line_length * var->yres_virtual > UNIFB_MEMSIZE)
393 return -ENOMEM;
394
395 /*
396 * Now that we checked it we alter var. The reason being is that the
397 * video mode passed in might not work but slight changes to it might
398 * make it work. This way we let the user know what is acceptable.
399 */
400 switch (var->bits_per_pixel) {
401 case 1:
402 case 8:
403 var->red.offset = 0;
404 var->red.length = 8;
405 var->green.offset = 0;
406 var->green.length = 8;
407 var->blue.offset = 0;
408 var->blue.length = 8;
409 var->transp.offset = 0;
410 var->transp.length = 0;
411 break;
412 case 16: /* RGBA 5551 */
413 if (var->transp.length) {
414 var->red.offset = 0;
415 var->red.length = 5;
416 var->green.offset = 5;
417 var->green.length = 5;
418 var->blue.offset = 10;
419 var->blue.length = 5;
420 var->transp.offset = 15;
421 var->transp.length = 1;
422 } else { /* RGB 565 */
423 var->red.offset = 11;
424 var->red.length = 5;
425 var->green.offset = 5;
426 var->green.length = 6;
427 var->blue.offset = 0;
428 var->blue.length = 5;
429 var->transp.offset = 0;
430 var->transp.length = 0;
431 }
432 break;
433 case 24: /* RGB 888 */
434 var->red.offset = 0;
435 var->red.length = 8;
436 var->green.offset = 8;
437 var->green.length = 8;
438 var->blue.offset = 16;
439 var->blue.length = 8;
440 var->transp.offset = 0;
441 var->transp.length = 0;
442 break;
443 case 32: /* RGBA 8888 */
444 var->red.offset = 16;
445 var->red.length = 8;
446 var->green.offset = 8;
447 var->green.length = 8;
448 var->blue.offset = 0;
449 var->blue.length = 8;
450 var->transp.offset = 24;
451 var->transp.length = 8;
452 break;
453 }
454 var->red.msb_right = 0;
455 var->green.msb_right = 0;
456 var->blue.msb_right = 0;
457 var->transp.msb_right = 0;
458
459 return 0;
460}
461
462/*
463 * This routine actually sets the video mode. It's in here where we
464 * the hardware state info->par and fix which can be affected by the
465 * change in par. For this driver it doesn't do much.
466 */
467static int unifb_set_par(struct fb_info *info)
468{
469 int hTotal, vTotal, hSyncStart, hSyncEnd, vSyncStart, vSyncEnd;
470 int format;
471
472#ifdef CONFIG_PUV3_PM
473 struct clk *clk_vga;
474 u32 pixclk = 0;
475 int i;
476
477 for (i = 0; i <= 10; i++) {
478 if (info->var.xres == unifb_modes[i].xres
479 && info->var.yres == unifb_modes[i].yres
480 && info->var.upper_margin == unifb_modes[i].upper_margin
481 && info->var.lower_margin == unifb_modes[i].lower_margin
482 && info->var.left_margin == unifb_modes[i].left_margin
483 && info->var.right_margin == unifb_modes[i].right_margin
484 && info->var.hsync_len == unifb_modes[i].hsync_len
485 && info->var.vsync_len == unifb_modes[i].vsync_len) {
486 pixclk = unifb_modes[i].pixclock;
487 break;
488 }
489 }
490
491 /* set clock rate */
492 clk_vga = clk_get(info->device, "VGA_CLK");
493 if (clk_vga == ERR_PTR(-ENOENT))
494 return -ENOENT;
495
496 if (pixclk != 0) {
497 if (clk_set_rate(clk_vga, pixclk)) { /* set clock failed */
498 info->fix = unifb_fix;
499 info->var = unifb_default;
500 if (clk_set_rate(clk_vga, unifb_default.pixclock))
501 return -EINVAL;
502 }
503 }
504#endif
505
506 info->fix.line_length = get_line_length(info->var.xres_virtual,
507 info->var.bits_per_pixel);
508
509 hSyncStart = info->var.xres + info->var.right_margin;
510 hSyncEnd = hSyncStart + info->var.hsync_len;
511 hTotal = hSyncEnd + info->var.left_margin;
512
513 vSyncStart = info->var.yres + info->var.lower_margin;
514 vSyncEnd = vSyncStart + info->var.vsync_len;
515 vTotal = vSyncEnd + info->var.upper_margin;
516
517 switch (info->var.bits_per_pixel) {
518 case 8:
519 format = UDE_CFG_DST8;
520 break;
521 case 16:
522 format = UDE_CFG_DST16;
523 break;
524 case 24:
525 format = UDE_CFG_DST24;
526 break;
527 case 32:
528 format = UDE_CFG_DST32;
529 break;
530 default:
531 return -EINVAL;
532 }
533
534 writel(PKUNITY_UNIGFX_MMAP_BASE, UDE_FSA);
535 writel(info->var.yres, UDE_LS);
536 writel(get_line_length(info->var.xres,
537 info->var.bits_per_pixel) >> 3, UDE_PS);
538 /* >> 3 for hardware required. */
539 writel((hTotal << 16) | (info->var.xres), UDE_HAT);
540 writel(((hTotal - 1) << 16) | (info->var.xres - 1), UDE_HBT);
541 writel(((hSyncEnd - 1) << 16) | (hSyncStart - 1), UDE_HST);
542 writel((vTotal << 16) | (info->var.yres), UDE_VAT);
543 writel(((vTotal - 1) << 16) | (info->var.yres - 1), UDE_VBT);
544 writel(((vSyncEnd - 1) << 16) | (vSyncStart - 1), UDE_VST);
545 writel(UDE_CFG_GDEN_ENABLE | UDE_CFG_TIMEUP_ENABLE
546 | format | 0xC0000001, UDE_CFG);
547
548 return 0;
549}
550
551/*
552 * Set a single color register. The values supplied are already
553 * rounded down to the hardware's capabilities (according to the
554 * entries in the var structure). Return != 0 for invalid regno.
555 */
556static int unifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
557 u_int transp, struct fb_info *info)
558{
559 if (regno >= 256) /* no. of hw registers */
560 return 1;
561
562 /* grayscale works only partially under directcolor */
563 if (info->var.grayscale) {
564 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
565 red = green = blue =
566 (red * 77 + green * 151 + blue * 28) >> 8;
567 }
568
569#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
570 switch (info->fix.visual) {
571 case FB_VISUAL_TRUECOLOR:
572 case FB_VISUAL_PSEUDOCOLOR:
573 red = CNVT_TOHW(red, info->var.red.length);
574 green = CNVT_TOHW(green, info->var.green.length);
575 blue = CNVT_TOHW(blue, info->var.blue.length);
576 transp = CNVT_TOHW(transp, info->var.transp.length);
577 break;
578 case FB_VISUAL_DIRECTCOLOR:
579 red = CNVT_TOHW(red, 8); /* expect 8 bit DAC */
580 green = CNVT_TOHW(green, 8);
581 blue = CNVT_TOHW(blue, 8);
582 /* hey, there is bug in transp handling... */
583 transp = CNVT_TOHW(transp, 8);
584 break;
585 }
586#undef CNVT_TOHW
587 /* Truecolor has hardware independent palette */
588 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
589 u32 v;
590
591 if (regno >= 16)
592 return 1;
593
594 v = (red << info->var.red.offset) |
595 (green << info->var.green.offset) |
596 (blue << info->var.blue.offset) |
597 (transp << info->var.transp.offset);
598 switch (info->var.bits_per_pixel) {
599 case 8:
600 break;
601 case 16:
602 case 24:
603 case 32:
604 ((u32 *) (info->pseudo_palette))[regno] = v;
605 break;
606 default:
607 return 1;
608 }
609 return 0;
610 }
611 return 0;
612}
613
614/*
615 * Pan or Wrap the Display
616 *
617 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
618 */
619static int unifb_pan_display(struct fb_var_screeninfo *var,
620 struct fb_info *info)
621{
622 if (var->vmode & FB_VMODE_YWRAP) {
623 if (var->yoffset < 0
624 || var->yoffset >= info->var.yres_virtual
625 || var->xoffset)
626 return -EINVAL;
627 } else {
628 if (var->xoffset + var->xres > info->var.xres_virtual ||
629 var->yoffset + var->yres > info->var.yres_virtual)
630 return -EINVAL;
631 }
632 info->var.xoffset = var->xoffset;
633 info->var.yoffset = var->yoffset;
634 if (var->vmode & FB_VMODE_YWRAP)
635 info->var.vmode |= FB_VMODE_YWRAP;
636 else
637 info->var.vmode &= ~FB_VMODE_YWRAP;
638 return 0;
639}
640
641int unifb_mmap(struct fb_info *info,
642 struct vm_area_struct *vma)
643{
644 unsigned long size = vma->vm_end - vma->vm_start;
645 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
646 unsigned long pos = info->fix.smem_start + offset;
647
648 if (offset + size > info->fix.smem_len)
649 return -EINVAL;
650
651 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
652
653 if (io_remap_pfn_range(vma, vma->vm_start, pos >> PAGE_SHIFT, size,
654 vma->vm_page_prot))
655 return -EAGAIN;
656
657 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
658 return 0;
659
660}
661
662static struct fb_ops unifb_ops = {
663 .fb_read = fb_sys_read,
664 .fb_write = fb_sys_write,
665 .fb_check_var = unifb_check_var,
666 .fb_set_par = unifb_set_par,
667 .fb_setcolreg = unifb_setcolreg,
668 .fb_pan_display = unifb_pan_display,
669 .fb_fillrect = unifb_fillrect,
670 .fb_copyarea = unifb_copyarea,
671 .fb_imageblit = unifb_imageblit,
672 .fb_mmap = unifb_mmap,
673};
674
675/*
676 * Initialisation
677 */
678static int unifb_probe(struct platform_device *dev)
679{
680 struct fb_info *info;
681 u32 unifb_regs[UNIFB_REGS_NUM];
682 int retval = -ENOMEM;
683 struct resource *iomem, *mapmem;
684
685 info = framebuffer_alloc(sizeof(u32)*256, &dev->dev);
686 if (!info)
687 goto err;
688
689 info->screen_base = (char __iomem *)KUSER_UNIGFX_BASE;
690 info->fbops = &unifb_ops;
691
692 retval = fb_find_mode(&info->var, info, NULL,
693 unifb_modes, 10, &unifb_modes[0], 16);
694
695 if (!retval || (retval == 4))
696 info->var = unifb_default;
697
698 iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
699 unifb_fix.mmio_start = iomem->start;
700
701 mapmem = platform_get_resource(dev, IORESOURCE_MEM, 1);
702 unifb_fix.smem_start = mapmem->start;
703 unifb_fix.smem_len = UNIFB_MEMSIZE;
704
705 info->fix = unifb_fix;
706 info->pseudo_palette = info->par;
707 info->par = NULL;
708 info->flags = FBINFO_FLAG_DEFAULT;
709#ifdef FB_ACCEL_PUV3_UNIGFX
710 info->fix.accel = FB_ACCEL_PUV3_UNIGFX;
711#endif
712
713 retval = fb_alloc_cmap(&info->cmap, 256, 0);
714 if (retval < 0)
715 goto err1;
716
717 retval = register_framebuffer(info);
718 if (retval < 0)
719 goto err2;
720 platform_set_drvdata(dev, info);
721 platform_device_add_data(dev, unifb_regs, sizeof(u32) * UNIFB_REGS_NUM);
722
723 printk(KERN_INFO
724 "fb%d: Virtual frame buffer device, using %dM of video memory\n",
725 info->node, UNIFB_MEMSIZE >> 20);
726 return 0;
727err2:
728 fb_dealloc_cmap(&info->cmap);
729err1:
730 framebuffer_release(info);
731err:
732 return retval;
733}
734
735static int unifb_remove(struct platform_device *dev)
736{
737 struct fb_info *info = platform_get_drvdata(dev);
738
739 if (info) {
740 unregister_framebuffer(info);
741 fb_dealloc_cmap(&info->cmap);
742 framebuffer_release(info);
743 }
744 return 0;
745}
746
747#ifdef CONFIG_PM
748static int unifb_resume(struct platform_device *dev)
749{
750 int rc = 0;
751 u32 *unifb_regs = dev->dev.platform_data;
752
753 if (dev->dev.power.power_state.event == PM_EVENT_ON)
754 return 0;
755
756 console_lock();
757
758 if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
759 writel(unifb_regs[0], UDE_FSA);
760 writel(unifb_regs[1], UDE_LS);
761 writel(unifb_regs[2], UDE_PS);
762 writel(unifb_regs[3], UDE_HAT);
763 writel(unifb_regs[4], UDE_HBT);
764 writel(unifb_regs[5], UDE_HST);
765 writel(unifb_regs[6], UDE_VAT);
766 writel(unifb_regs[7], UDE_VBT);
767 writel(unifb_regs[8], UDE_VST);
768 writel(unifb_regs[9], UDE_CFG);
769 }
770 dev->dev.power.power_state = PMSG_ON;
771
772 console_unlock();
773
774 return rc;
775}
776
777static int unifb_suspend(struct platform_device *dev, pm_message_t mesg)
778{
779 u32 *unifb_regs = dev->dev.platform_data;
780
781 unifb_regs[0] = readl(UDE_FSA);
782 unifb_regs[1] = readl(UDE_LS);
783 unifb_regs[2] = readl(UDE_PS);
784 unifb_regs[3] = readl(UDE_HAT);
785 unifb_regs[4] = readl(UDE_HBT);
786 unifb_regs[5] = readl(UDE_HST);
787 unifb_regs[6] = readl(UDE_VAT);
788 unifb_regs[7] = readl(UDE_VBT);
789 unifb_regs[8] = readl(UDE_VST);
790 unifb_regs[9] = readl(UDE_CFG);
791
792 if (mesg.event == dev->dev.power.power_state.event)
793 return 0;
794
795 switch (mesg.event) {
796 case PM_EVENT_FREEZE: /* about to take snapshot */
797 case PM_EVENT_PRETHAW: /* before restoring snapshot */
798 goto done;
799 }
800
801 console_lock();
802
803 /* do nothing... */
804
805 console_unlock();
806
807done:
808 dev->dev.power.power_state = mesg;
809
810 return 0;
811}
812#else
813#define unifb_resume NULL
814#define unifb_suspend NULL
815#endif
816
817static struct platform_driver unifb_driver = {
818 .probe = unifb_probe,
819 .remove = unifb_remove,
820 .resume = unifb_resume,
821 .suspend = unifb_suspend,
822 .driver = {
823 .name = "PKUnity-v3-UNIGFX",
824 },
825};
826
827static int __init unifb_init(void)
828{
829#ifndef MODULE
830 if (fb_get_options("unifb", NULL))
831 return -ENODEV;
832#endif
833
834 return platform_driver_register(&unifb_driver);
835}
836
837module_init(unifb_init);
838
839static void __exit unifb_exit(void)
840{
841 platform_driver_unregister(&unifb_driver);
842}
843
844module_exit(unifb_exit);
845
846MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 6739b2af3bc0..14102a3f70f5 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -893,8 +893,7 @@ static void ffb_init_fix(struct fb_info *info)
893 info->fix.accel = FB_ACCEL_SUN_CREATOR; 893 info->fix.accel = FB_ACCEL_SUN_CREATOR;
894} 894}
895 895
896static int __devinit ffb_probe(struct platform_device *op, 896static int __devinit ffb_probe(struct platform_device *op)
897 const struct of_device_id *match)
898{ 897{
899 struct device_node *dp = op->dev.of_node; 898 struct device_node *dp = op->dev.of_node;
900 struct ffb_fbc __iomem *fbc; 899 struct ffb_fbc __iomem *fbc;
@@ -1011,7 +1010,7 @@ out_dealloc_cmap:
1011 fb_dealloc_cmap(&info->cmap); 1010 fb_dealloc_cmap(&info->cmap);
1012 1011
1013out_unmap_dac: 1012out_unmap_dac:
1014 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1013 of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
1015 1014
1016out_unmap_fbc: 1015out_unmap_fbc:
1017 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1016 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
@@ -1052,7 +1051,7 @@ static const struct of_device_id ffb_match[] = {
1052}; 1051};
1053MODULE_DEVICE_TABLE(of, ffb_match); 1052MODULE_DEVICE_TABLE(of, ffb_match);
1054 1053
1055static struct of_platform_driver ffb_driver = { 1054static struct platform_driver ffb_driver = {
1056 .driver = { 1055 .driver = {
1057 .name = "ffb", 1056 .name = "ffb",
1058 .owner = THIS_MODULE, 1057 .owner = THIS_MODULE,
@@ -1067,12 +1066,12 @@ static int __init ffb_init(void)
1067 if (fb_get_options("ffb", NULL)) 1066 if (fb_get_options("ffb", NULL))
1068 return -ENODEV; 1067 return -ENODEV;
1069 1068
1070 return of_register_platform_driver(&ffb_driver); 1069 return platform_driver_register(&ffb_driver);
1071} 1070}
1072 1071
1073static void __exit ffb_exit(void) 1072static void __exit ffb_exit(void)
1074{ 1073{
1075 of_unregister_platform_driver(&ffb_driver); 1074 platform_driver_unregister(&ffb_driver);
1076} 1075}
1077 1076
1078module_init(ffb_init); 1077module_init(ffb_init);
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 8bbbf08fa3ce..9048f87fa8c1 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1487,8 +1487,7 @@ static ssize_t show_monitor(struct device *device,
1487 return diu_ops.show_monitor_port(machine_data->monitor_port, buf); 1487 return diu_ops.show_monitor_port(machine_data->monitor_port, buf);
1488} 1488}
1489 1489
1490static int __devinit fsl_diu_probe(struct platform_device *ofdev, 1490static int __devinit fsl_diu_probe(struct platform_device *ofdev)
1491 const struct of_device_id *match)
1492{ 1491{
1493 struct device_node *np = ofdev->dev.of_node; 1492 struct device_node *np = ofdev->dev.of_node;
1494 struct mfb_info *mfbi; 1493 struct mfb_info *mfbi;
@@ -1735,7 +1734,7 @@ static struct of_device_id fsl_diu_match[] = {
1735}; 1734};
1736MODULE_DEVICE_TABLE(of, fsl_diu_match); 1735MODULE_DEVICE_TABLE(of, fsl_diu_match);
1737 1736
1738static struct of_platform_driver fsl_diu_driver = { 1737static struct platform_driver fsl_diu_driver = {
1739 .driver = { 1738 .driver = {
1740 .name = "fsl_diu", 1739 .name = "fsl_diu",
1741 .owner = THIS_MODULE, 1740 .owner = THIS_MODULE,
@@ -1797,7 +1796,7 @@ static int __init fsl_diu_init(void)
1797 if (!coherence_data) 1796 if (!coherence_data)
1798 return -ENOMEM; 1797 return -ENOMEM;
1799#endif 1798#endif
1800 ret = of_register_platform_driver(&fsl_diu_driver); 1799 ret = platform_driver_register(&fsl_diu_driver);
1801 if (ret) { 1800 if (ret) {
1802 printk(KERN_ERR 1801 printk(KERN_ERR
1803 "fsl-diu: failed to register platform driver\n"); 1802 "fsl-diu: failed to register platform driver\n");
@@ -1811,7 +1810,7 @@ static int __init fsl_diu_init(void)
1811 1810
1812static void __exit fsl_diu_exit(void) 1811static void __exit fsl_diu_exit(void)
1813{ 1812{
1814 of_unregister_platform_driver(&fsl_diu_driver); 1813 platform_driver_unregister(&fsl_diu_driver);
1815#if defined(CONFIG_NOT_COHERENT_CACHE) 1814#if defined(CONFIG_NOT_COHERENT_CACHE)
1816 vfree(coherence_data); 1815 vfree(coherence_data);
1817#endif 1816#endif
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/imxfb.c b/drivers/video/imxfb.c
index 69bd4a581d4a..ef72cb483834 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -499,6 +499,7 @@ static void imxfb_init_backlight(struct imxfb_info *fbi)
499 499
500 memset(&props, 0, sizeof(struct backlight_properties)); 500 memset(&props, 0, sizeof(struct backlight_properties));
501 props.max_brightness = 0xff; 501 props.max_brightness = 0xff;
502 props.type = BACKLIGHT_RAW;
502 writel(fbi->pwmr, fbi->regs + LCDC_PWMR); 503 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
503 504
504 bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi, 505 bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi,
diff --git a/drivers/video/intelfb/Makefile b/drivers/video/intelfb/Makefile
index 6c782d3ae1be..f7d631ebee8e 100644
--- a/drivers/video/intelfb/Makefile
+++ b/drivers/video/intelfb/Makefile
@@ -4,7 +4,4 @@ intelfb-y := intelfbdrv.o intelfbhw.o
4intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o 4intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o
5intelfb-objs := $(intelfb-y) 5intelfb-objs := $(intelfb-y)
6 6
7ifdef CONFIG_FB_INTEL_DEBUG 7ccflags-$(CONFIG_FB_INTEL_DEBUG) := -DDEBUG -DREGDUMP
8#EXTRA_CFLAGS += -DDEBUG -DVERBOSE -DREGDUMP
9EXTRA_CFLAGS += -DDEBUG -DREGDUMP
10endif
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index b599e5e36ced..9e946e2c1da9 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -547,8 +547,7 @@ static void leo_unmap_regs(struct platform_device *op, struct fb_info *info,
547 of_iounmap(&op->resource[0], info->screen_base, 0x800000); 547 of_iounmap(&op->resource[0], info->screen_base, 0x800000);
548} 548}
549 549
550static int __devinit leo_probe(struct platform_device *op, 550static int __devinit leo_probe(struct platform_device *op)
551 const struct of_device_id *match)
552{ 551{
553 struct device_node *dp = op->dev.of_node; 552 struct device_node *dp = op->dev.of_node;
554 struct fb_info *info; 553 struct fb_info *info;
@@ -662,7 +661,7 @@ static const struct of_device_id leo_match[] = {
662}; 661};
663MODULE_DEVICE_TABLE(of, leo_match); 662MODULE_DEVICE_TABLE(of, leo_match);
664 663
665static struct of_platform_driver leo_driver = { 664static struct platform_driver leo_driver = {
666 .driver = { 665 .driver = {
667 .name = "leo", 666 .name = "leo",
668 .owner = THIS_MODULE, 667 .owner = THIS_MODULE,
@@ -677,12 +676,12 @@ static int __init leo_init(void)
677 if (fb_get_options("leofb", NULL)) 676 if (fb_get_options("leofb", NULL))
678 return -ENODEV; 677 return -ENODEV;
679 678
680 return of_register_platform_driver(&leo_driver); 679 return platform_driver_register(&leo_driver);
681} 680}
682 681
683static void __exit leo_exit(void) 682static void __exit leo_exit(void)
684{ 683{
685 of_unregister_platform_driver(&leo_driver); 684 platform_driver_unregister(&leo_driver);
686} 685}
687 686
688module_init(leo_init); 687module_init(leo_init);
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 8c9dbac9dc1b..5ce6fa6e59f0 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -1458,13 +1458,6 @@ static struct board {
1458 MGA_G100, 1458 MGA_G100,
1459 &vbG100, 1459 &vbG100,
1460 "MGA-G100 (AGP)"}, 1460 "MGA-G100 (AGP)"},
1461 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI, 0xFF,
1462 0, 0,
1463 DEVF_G200,
1464 230000,
1465 MGA_G200,
1466 &vbG200,
1467 "MGA-G200eV (PCI)"},
1468 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF, 1461 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF,
1469 0, 0, 1462 0, 0,
1470 DEVF_G200, 1463 DEVF_G200,
@@ -2116,8 +2109,6 @@ static struct pci_device_id matroxfb_devices[] = {
2116 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2109 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2117 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 2110 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP,
2118 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2111 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2119 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI,
2120 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2121 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 2112 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI,
2122 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2113 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2123 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 2114 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP,
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c
index b1c4374cf940..c76e663a6cd4 100644
--- a/drivers/video/mb862xx/mb862xxfb.c
+++ b/drivers/video/mb862xx/mb862xxfb.c
@@ -550,8 +550,7 @@ static int mb862xx_gdc_init(struct mb862xxfb_par *par)
550 return 0; 550 return 0;
551} 551}
552 552
553static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev, 553static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev)
554 const struct of_device_id *id)
555{ 554{
556 struct device_node *np = ofdev->dev.of_node; 555 struct device_node *np = ofdev->dev.of_node;
557 struct device *dev = &ofdev->dev; 556 struct device *dev = &ofdev->dev;
@@ -717,7 +716,7 @@ static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = {
717 { /* end */ } 716 { /* end */ }
718}; 717};
719 718
720static struct of_platform_driver of_platform_mb862xxfb_driver = { 719static struct platform_driver of_platform_mb862xxfb_driver = {
721 .driver = { 720 .driver = {
722 .name = DRV_NAME, 721 .name = DRV_NAME,
723 .owner = THIS_MODULE, 722 .owner = THIS_MODULE,
@@ -1038,7 +1037,7 @@ static int __devinit mb862xxfb_init(void)
1038 int ret = -ENODEV; 1037 int ret = -ENODEV;
1039 1038
1040#if defined(CONFIG_FB_MB862XX_LIME) 1039#if defined(CONFIG_FB_MB862XX_LIME)
1041 ret = of_register_platform_driver(&of_platform_mb862xxfb_driver); 1040 ret = platform_driver_register(&of_platform_mb862xxfb_driver);
1042#endif 1041#endif
1043#if defined(CONFIG_FB_MB862XX_PCI_GDC) 1042#if defined(CONFIG_FB_MB862XX_PCI_GDC)
1044 ret = pci_register_driver(&mb862xxfb_pci_driver); 1043 ret = pci_register_driver(&mb862xxfb_pci_driver);
@@ -1049,7 +1048,7 @@ static int __devinit mb862xxfb_init(void)
1049static void __exit mb862xxfb_exit(void) 1048static void __exit mb862xxfb_exit(void)
1050{ 1049{
1051#if defined(CONFIG_FB_MB862XX_LIME) 1050#if defined(CONFIG_FB_MB862XX_LIME)
1052 of_unregister_platform_driver(&of_platform_mb862xxfb_driver); 1051 platform_driver_unregister(&of_platform_mb862xxfb_driver);
1053#endif 1052#endif
1054#if defined(CONFIG_FB_MB862XX_PCI_GDC) 1053#if defined(CONFIG_FB_MB862XX_PCI_GDC)
1055 pci_unregister_driver(&mb862xxfb_pci_driver); 1054 pci_unregister_driver(&mb862xxfb_pci_driver);
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/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h
index 4e3deb4e592b..d80477415caa 100644
--- a/drivers/video/msm/mdp_hw.h
+++ b/drivers/video/msm/mdp_hw.h
@@ -449,6 +449,7 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
449#define PPP_CFG_MDP_XRGB_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) 449#define PPP_CFG_MDP_XRGB_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
450#define PPP_CFG_MDP_RGBA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) 450#define PPP_CFG_MDP_RGBA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
451#define PPP_CFG_MDP_BGRA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir) 451#define PPP_CFG_MDP_BGRA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
452#define PPP_CFG_MDP_RGBX_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
452 453
453#define PPP_CFG_MDP_Y_CBCR_H2V2(dir) (PPP_##dir##_C2R_8BIT | \ 454#define PPP_CFG_MDP_Y_CBCR_H2V2(dir) (PPP_##dir##_C2R_8BIT | \
454 PPP_##dir##_C0G_8BIT | \ 455 PPP_##dir##_C0G_8BIT | \
@@ -488,12 +489,14 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
488 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8) 489 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8)
489#define PPP_PACK_PATTERN_MDP_RGB_888 PPP_PACK_PATTERN_MDP_RGB_565 490#define PPP_PACK_PATTERN_MDP_RGB_888 PPP_PACK_PATTERN_MDP_RGB_565
490#define PPP_PACK_PATTERN_MDP_XRGB_8888 \ 491#define PPP_PACK_PATTERN_MDP_XRGB_8888 \
491 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8) 492 MDP_GET_PACK_PATTERN(CLR_B, CLR_G, CLR_R, CLR_ALPHA, 8)
492#define PPP_PACK_PATTERN_MDP_ARGB_8888 PPP_PACK_PATTERN_MDP_XRGB_8888 493#define PPP_PACK_PATTERN_MDP_ARGB_8888 PPP_PACK_PATTERN_MDP_XRGB_8888
493#define PPP_PACK_PATTERN_MDP_RGBA_8888 \ 494#define PPP_PACK_PATTERN_MDP_RGBA_8888 \
494 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8) 495 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8)
495#define PPP_PACK_PATTERN_MDP_BGRA_8888 \ 496#define PPP_PACK_PATTERN_MDP_BGRA_8888 \
496 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8) 497 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8)
498#define PPP_PACK_PATTERN_MDP_RGBX_8888 \
499 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8)
497#define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 \ 500#define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 \
498 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8) 501 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8)
499#define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V2 PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 502#define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V2 PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1
@@ -509,6 +512,7 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
509#define PPP_CHROMA_SAMP_MDP_ARGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB 512#define PPP_CHROMA_SAMP_MDP_ARGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB
510#define PPP_CHROMA_SAMP_MDP_RGBA_8888(dir) PPP_OP_##dir##_CHROMA_RGB 513#define PPP_CHROMA_SAMP_MDP_RGBA_8888(dir) PPP_OP_##dir##_CHROMA_RGB
511#define PPP_CHROMA_SAMP_MDP_BGRA_8888(dir) PPP_OP_##dir##_CHROMA_RGB 514#define PPP_CHROMA_SAMP_MDP_BGRA_8888(dir) PPP_OP_##dir##_CHROMA_RGB
515#define PPP_CHROMA_SAMP_MDP_RGBX_8888(dir) PPP_OP_##dir##_CHROMA_RGB
512#define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1 516#define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
513#define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V2(dir) PPP_OP_##dir##_CHROMA_420 517#define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V2(dir) PPP_OP_##dir##_CHROMA_420
514#define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1 518#define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
@@ -523,6 +527,7 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
523 [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888,\ 527 [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888,\
524 [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888,\ 528 [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888,\
525 [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888,\ 529 [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888,\
530 [MDP_RGBX_8888] = PPP_##name##_MDP_RGBX_8888,\
526 [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1,\ 531 [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1,\
527 [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2,\ 532 [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2,\
528 [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1,\ 533 [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1,\
@@ -536,6 +541,7 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
536 [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888(dir),\ 541 [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888(dir),\
537 [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888(dir),\ 542 [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888(dir),\
538 [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888(dir),\ 543 [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888(dir),\
544 [MDP_RGBX_8888] = PPP_##name##_MDP_RGBX_8888(dir),\
539 [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1(dir),\ 545 [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1(dir),\
540 [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2(dir),\ 546 [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2(dir),\
541 [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1(dir),\ 547 [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1(dir),\
@@ -547,7 +553,8 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
547 (img == MDP_YCRYCB_H2V1)) 553 (img == MDP_YCRYCB_H2V1))
548#define IS_RGB(img) ((img == MDP_RGB_565) | (img == MDP_RGB_888) | \ 554#define IS_RGB(img) ((img == MDP_RGB_565) | (img == MDP_RGB_888) | \
549 (img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \ 555 (img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \
550 (img == MDP_XRGB_8888) | (img == MDP_BGRA_8888)) 556 (img == MDP_XRGB_8888) | (img == MDP_BGRA_8888) | \
557 (img == MDP_RGBX_8888))
551#define HAS_ALPHA(img) ((img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \ 558#define HAS_ALPHA(img) ((img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \
552 (img == MDP_BGRA_8888)) 559 (img == MDP_BGRA_8888))
553 560
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index 4ff001f4cbbd..2b6564e8bfea 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -69,6 +69,7 @@ static uint32_t bytes_per_pixel[] = {
69 [MDP_ARGB_8888] = 4, 69 [MDP_ARGB_8888] = 4,
70 [MDP_RGBA_8888] = 4, 70 [MDP_RGBA_8888] = 4,
71 [MDP_BGRA_8888] = 4, 71 [MDP_BGRA_8888] = 4,
72 [MDP_RGBX_8888] = 4,
72 [MDP_Y_CBCR_H2V1] = 1, 73 [MDP_Y_CBCR_H2V1] = 1,
73 [MDP_Y_CBCR_H2V2] = 1, 74 [MDP_Y_CBCR_H2V2] = 1,
74 [MDP_Y_CRCB_H2V1] = 1, 75 [MDP_Y_CRCB_H2V1] = 1,
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index debe5933fd2e..ec351309e607 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -81,7 +81,6 @@ struct msmfb_info {
81 spinlock_t update_lock; 81 spinlock_t update_lock;
82 struct mutex panel_init_lock; 82 struct mutex panel_init_lock;
83 wait_queue_head_t frame_wq; 83 wait_queue_head_t frame_wq;
84 struct workqueue_struct *resume_workqueue;
85 struct work_struct resume_work; 84 struct work_struct resume_work;
86 struct msmfb_callback dma_callback; 85 struct msmfb_callback dma_callback;
87 struct msmfb_callback vsync_callback; 86 struct msmfb_callback vsync_callback;
@@ -111,7 +110,7 @@ static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback)
111 if (msmfb->sleeping == UPDATING && 110 if (msmfb->sleeping == UPDATING &&
112 msmfb->frame_done == msmfb->update_frame) { 111 msmfb->frame_done == msmfb->update_frame) {
113 DLOG(SUSPEND_RESUME, "full update completed\n"); 112 DLOG(SUSPEND_RESUME, "full update completed\n");
114 queue_work(msmfb->resume_workqueue, &msmfb->resume_work); 113 schedule_work(&msmfb->resume_work);
115 } 114 }
116 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); 115 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
117 wake_up(&msmfb->frame_wq); 116 wake_up(&msmfb->frame_wq);
@@ -220,8 +219,8 @@ restart:
220 219
221 sleeping = msmfb->sleeping; 220 sleeping = msmfb->sleeping;
222 /* on a full update, if the last frame has not completed, wait for it */ 221 /* on a full update, if the last frame has not completed, wait for it */
223 if (pan_display && (msmfb->frame_requested != msmfb->frame_done || 222 if ((pan_display && msmfb->frame_requested != msmfb->frame_done) ||
224 sleeping == UPDATING)) { 223 sleeping == UPDATING) {
225 int ret; 224 int ret;
226 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); 225 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
227 ret = wait_event_interruptible_timeout(msmfb->frame_wq, 226 ret = wait_event_interruptible_timeout(msmfb->frame_wq,
@@ -470,6 +469,18 @@ static void setup_fb_info(struct msmfb_info *msmfb)
470 fb_info->var.yoffset = 0; 469 fb_info->var.yoffset = 0;
471 470
472 if (msmfb->panel->caps & MSMFB_CAP_PARTIAL_UPDATES) { 471 if (msmfb->panel->caps & MSMFB_CAP_PARTIAL_UPDATES) {
472 /*
473 * Set the param in the fixed screen, so userspace can't
474 * change it. This will be used to check for the
475 * capability.
476 */
477 fb_info->fix.reserved[0] = 0x5444;
478 fb_info->fix.reserved[1] = 0x5055;
479
480 /*
481 * This preloads the value so that if userspace doesn't
482 * change it, it will be a full update
483 */
473 fb_info->var.reserved[0] = 0x54445055; 484 fb_info->var.reserved[0] = 0x54445055;
474 fb_info->var.reserved[1] = 0; 485 fb_info->var.reserved[1] = 0;
475 fb_info->var.reserved[2] = (uint16_t)msmfb->xres | 486 fb_info->var.reserved[2] = (uint16_t)msmfb->xres |
@@ -559,12 +570,6 @@ static int msmfb_probe(struct platform_device *pdev)
559 spin_lock_init(&msmfb->update_lock); 570 spin_lock_init(&msmfb->update_lock);
560 mutex_init(&msmfb->panel_init_lock); 571 mutex_init(&msmfb->panel_init_lock);
561 init_waitqueue_head(&msmfb->frame_wq); 572 init_waitqueue_head(&msmfb->frame_wq);
562 msmfb->resume_workqueue = create_workqueue("panel_on");
563 if (msmfb->resume_workqueue == NULL) {
564 printk(KERN_ERR "failed to create panel_on workqueue\n");
565 ret = -ENOMEM;
566 goto error_create_workqueue;
567 }
568 INIT_WORK(&msmfb->resume_work, power_on_panel); 573 INIT_WORK(&msmfb->resume_work, power_on_panel);
569 msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres, 574 msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres,
570 GFP_KERNEL); 575 GFP_KERNEL);
@@ -589,8 +594,6 @@ static int msmfb_probe(struct platform_device *pdev)
589 return 0; 594 return 0;
590 595
591error_register_framebuffer: 596error_register_framebuffer:
592 destroy_workqueue(msmfb->resume_workqueue);
593error_create_workqueue:
594 iounmap(fb->screen_base); 597 iounmap(fb->screen_base);
595error_setup_fbmem: 598error_setup_fbmem:
596 framebuffer_release(msmfb->fb); 599 framebuffer_release(msmfb->fb);
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
new file mode 100644
index 000000000000..7d0284882984
--- /dev/null
+++ b/drivers/video/mxsfb.c
@@ -0,0 +1,919 @@
1/*
2 * Copyright (C) 2010 Juergen Beisert, Pengutronix
3 *
4 * This code is based on:
5 * Author: Vitaly Wool <vital@embeddedalley.com>
6 *
7 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
8 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#define DRIVER_NAME "mxsfb"
21
22/**
23 * @file
24 * @brief LCDIF driver for i.MX23 and i.MX28
25 *
26 * The LCDIF support four modes of operation
27 * - MPU interface (to drive smart displays) -> not supported yet
28 * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
29 * - Dotclock interface (to drive LC displays with RGB data and sync signals)
30 * - DVI (to drive ITU-R BT656) -> not supported yet
31 *
32 * This driver depends on a correct setup of the pins used for this purpose
33 * (platform specific).
34 *
35 * For the developer: Don't forget to set the data bus width to the display
36 * in the imx_fb_videomode structure. You will else end up with ugly colours.
37 * If you fight against jitter you can vary the clock delay. This is a feature
38 * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give
39 * the required value in the imx_fb_videomode structure.
40 */
41
42#include <linux/kernel.h>
43#include <linux/platform_device.h>
44#include <linux/clk.h>
45#include <linux/dma-mapping.h>
46#include <linux/io.h>
47#include <mach/mxsfb.h>
48
49#define REG_SET 4
50#define REG_CLR 8
51
52#define LCDC_CTRL 0x00
53#define LCDC_CTRL1 0x10
54#define LCDC_V4_CTRL2 0x20
55#define LCDC_V3_TRANSFER_COUNT 0x20
56#define LCDC_V4_TRANSFER_COUNT 0x30
57#define LCDC_V4_CUR_BUF 0x40
58#define LCDC_V4_NEXT_BUF 0x50
59#define LCDC_V3_CUR_BUF 0x30
60#define LCDC_V3_NEXT_BUF 0x40
61#define LCDC_TIMING 0x60
62#define LCDC_VDCTRL0 0x70
63#define LCDC_VDCTRL1 0x80
64#define LCDC_VDCTRL2 0x90
65#define LCDC_VDCTRL3 0xa0
66#define LCDC_VDCTRL4 0xb0
67#define LCDC_DVICTRL0 0xc0
68#define LCDC_DVICTRL1 0xd0
69#define LCDC_DVICTRL2 0xe0
70#define LCDC_DVICTRL3 0xf0
71#define LCDC_DVICTRL4 0x100
72#define LCDC_V4_DATA 0x180
73#define LCDC_V3_DATA 0x1b0
74#define LCDC_V4_DEBUG0 0x1d0
75#define LCDC_V3_DEBUG0 0x1f0
76
77#define CTRL_SFTRST (1 << 31)
78#define CTRL_CLKGATE (1 << 30)
79#define CTRL_BYPASS_COUNT (1 << 19)
80#define CTRL_VSYNC_MODE (1 << 18)
81#define CTRL_DOTCLK_MODE (1 << 17)
82#define CTRL_DATA_SELECT (1 << 16)
83#define CTRL_SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
84#define CTRL_GET_BUS_WIDTH(x) (((x) >> 10) & 0x3)
85#define CTRL_SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
86#define CTRL_GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
87#define CTRL_MASTER (1 << 5)
88#define CTRL_DF16 (1 << 3)
89#define CTRL_DF18 (1 << 2)
90#define CTRL_DF24 (1 << 1)
91#define CTRL_RUN (1 << 0)
92
93#define CTRL1_FIFO_CLEAR (1 << 21)
94#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
95#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
96
97#define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)
98#define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)
99#define TRANSFER_COUNT_SET_HCOUNT(x) ((x) & 0xffff)
100#define TRANSFER_COUNT_GET_HCOUNT(x) ((x) & 0xffff)
101
102
103#define VDCTRL0_ENABLE_PRESENT (1 << 28)
104#define VDCTRL0_VSYNC_ACT_HIGH (1 << 27)
105#define VDCTRL0_HSYNC_ACT_HIGH (1 << 26)
106#define VDCTRL0_DOTCLK_ACT_FAILING (1 << 25)
107#define VDCTRL0_ENABLE_ACT_HIGH (1 << 24)
108#define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
109#define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
110#define VDCTRL0_HALF_LINE (1 << 19)
111#define VDCTRL0_HALF_LINE_MODE (1 << 18)
112#define VDCTRL0_SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
113#define VDCTRL0_GET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
114
115#define VDCTRL2_SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
116#define VDCTRL2_GET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
117
118#define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
119#define VDCTRL3_VSYNC_ONLY (1 << 28)
120#define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
121#define GET_HOR_WAIT_CNT(x) (((x) >> 16) & 0xfff)
122#define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
123#define GET_VERT_WAIT_CNT(x) ((x) & 0xffff)
124
125#define VDCTRL4_SET_DOTCLK_DLY(x) (((x) & 0x7) << 29) /* v4 only */
126#define VDCTRL4_GET_DOTCLK_DLY(x) (((x) >> 29) & 0x7) /* v4 only */
127#define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
128#define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
129
130#define DEBUG0_HSYNC (1 < 26)
131#define DEBUG0_VSYNC (1 < 25)
132
133#define MIN_XRES 120
134#define MIN_YRES 120
135
136#define RED 0
137#define GREEN 1
138#define BLUE 2
139#define TRANSP 3
140
141enum mxsfb_devtype {
142 MXSFB_V3,
143 MXSFB_V4,
144};
145
146/* CPU dependent register offsets */
147struct mxsfb_devdata {
148 unsigned transfer_count;
149 unsigned cur_buf;
150 unsigned next_buf;
151 unsigned debug0;
152 unsigned hs_wdth_mask;
153 unsigned hs_wdth_shift;
154 unsigned ipversion;
155};
156
157struct mxsfb_info {
158 struct fb_info fb_info;
159 struct platform_device *pdev;
160 struct clk *clk;
161 void __iomem *base; /* registers */
162 unsigned allocated_size;
163 int enabled;
164 unsigned ld_intf_width;
165 unsigned dotclk_delay;
166 const struct mxsfb_devdata *devdata;
167 int mapped;
168};
169
170#define mxsfb_is_v3(host) (host->devdata->ipversion == 3)
171#define mxsfb_is_v4(host) (host->devdata->ipversion == 4)
172
173static const struct mxsfb_devdata mxsfb_devdata[] = {
174 [MXSFB_V3] = {
175 .transfer_count = LCDC_V3_TRANSFER_COUNT,
176 .cur_buf = LCDC_V3_CUR_BUF,
177 .next_buf = LCDC_V3_NEXT_BUF,
178 .debug0 = LCDC_V3_DEBUG0,
179 .hs_wdth_mask = 0xff,
180 .hs_wdth_shift = 24,
181 .ipversion = 3,
182 },
183 [MXSFB_V4] = {
184 .transfer_count = LCDC_V4_TRANSFER_COUNT,
185 .cur_buf = LCDC_V4_CUR_BUF,
186 .next_buf = LCDC_V4_NEXT_BUF,
187 .debug0 = LCDC_V4_DEBUG0,
188 .hs_wdth_mask = 0x3fff,
189 .hs_wdth_shift = 18,
190 .ipversion = 4,
191 },
192};
193
194#define to_imxfb_host(x) (container_of(x, struct mxsfb_info, fb_info))
195
196/* mask and shift depends on architecture */
197static inline u32 set_hsync_pulse_width(struct mxsfb_info *host, unsigned val)
198{
199 return (val & host->devdata->hs_wdth_mask) <<
200 host->devdata->hs_wdth_shift;
201}
202
203static inline u32 get_hsync_pulse_width(struct mxsfb_info *host, unsigned val)
204{
205 return (val >> host->devdata->hs_wdth_shift) &
206 host->devdata->hs_wdth_mask;
207}
208
209static const struct fb_bitfield def_rgb565[] = {
210 [RED] = {
211 .offset = 11,
212 .length = 5,
213 },
214 [GREEN] = {
215 .offset = 5,
216 .length = 6,
217 },
218 [BLUE] = {
219 .offset = 0,
220 .length = 5,
221 },
222 [TRANSP] = { /* no support for transparency */
223 .length = 0,
224 }
225};
226
227static const struct fb_bitfield def_rgb666[] = {
228 [RED] = {
229 .offset = 16,
230 .length = 6,
231 },
232 [GREEN] = {
233 .offset = 8,
234 .length = 6,
235 },
236 [BLUE] = {
237 .offset = 0,
238 .length = 6,
239 },
240 [TRANSP] = { /* no support for transparency */
241 .length = 0,
242 }
243};
244
245static const struct fb_bitfield def_rgb888[] = {
246 [RED] = {
247 .offset = 16,
248 .length = 8,
249 },
250 [GREEN] = {
251 .offset = 8,
252 .length = 8,
253 },
254 [BLUE] = {
255 .offset = 0,
256 .length = 8,
257 },
258 [TRANSP] = { /* no support for transparency */
259 .length = 0,
260 }
261};
262
263static inline unsigned chan_to_field(unsigned chan, struct fb_bitfield *bf)
264{
265 chan &= 0xffff;
266 chan >>= 16 - bf->length;
267 return chan << bf->offset;
268}
269
270static int mxsfb_check_var(struct fb_var_screeninfo *var,
271 struct fb_info *fb_info)
272{
273 struct mxsfb_info *host = to_imxfb_host(fb_info);
274 const struct fb_bitfield *rgb = NULL;
275
276 if (var->xres < MIN_XRES)
277 var->xres = MIN_XRES;
278 if (var->yres < MIN_YRES)
279 var->yres = MIN_YRES;
280
281 var->xres_virtual = var->xres;
282
283 var->yres_virtual = var->yres;
284
285 switch (var->bits_per_pixel) {
286 case 16:
287 /* always expect RGB 565 */
288 rgb = def_rgb565;
289 break;
290 case 32:
291 switch (host->ld_intf_width) {
292 case STMLCDIF_8BIT:
293 pr_debug("Unsupported LCD bus width mapping\n");
294 break;
295 case STMLCDIF_16BIT:
296 case STMLCDIF_18BIT:
297 /* 24 bit to 18 bit mapping */
298 rgb = def_rgb666;
299 break;
300 case STMLCDIF_24BIT:
301 /* real 24 bit */
302 rgb = def_rgb888;
303 break;
304 }
305 break;
306 default:
307 pr_debug("Unsupported colour depth: %u\n", var->bits_per_pixel);
308 return -EINVAL;
309 }
310
311 /*
312 * Copy the RGB parameters for this display
313 * from the machine specific parameters.
314 */
315 var->red = rgb[RED];
316 var->green = rgb[GREEN];
317 var->blue = rgb[BLUE];
318 var->transp = rgb[TRANSP];
319
320 return 0;
321}
322
323static void mxsfb_enable_controller(struct fb_info *fb_info)
324{
325 struct mxsfb_info *host = to_imxfb_host(fb_info);
326 u32 reg;
327
328 dev_dbg(&host->pdev->dev, "%s\n", __func__);
329
330 clk_enable(host->clk);
331 clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
332
333 /* if it was disabled, re-enable the mode again */
334 writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET);
335
336 /* enable the SYNC signals first, then the DMA engine */
337 reg = readl(host->base + LCDC_VDCTRL4);
338 reg |= VDCTRL4_SYNC_SIGNALS_ON;
339 writel(reg, host->base + LCDC_VDCTRL4);
340
341 writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET);
342
343 host->enabled = 1;
344}
345
346static void mxsfb_disable_controller(struct fb_info *fb_info)
347{
348 struct mxsfb_info *host = to_imxfb_host(fb_info);
349 unsigned loop;
350 u32 reg;
351
352 dev_dbg(&host->pdev->dev, "%s\n", __func__);
353
354 /*
355 * Even if we disable the controller here, it will still continue
356 * until its FIFOs are running out of data
357 */
358 writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_CLR);
359
360 loop = 1000;
361 while (loop) {
362 reg = readl(host->base + LCDC_CTRL);
363 if (!(reg & CTRL_RUN))
364 break;
365 loop--;
366 }
367
368 writel(VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4 + REG_CLR);
369
370 clk_disable(host->clk);
371
372 host->enabled = 0;
373}
374
375static int mxsfb_set_par(struct fb_info *fb_info)
376{
377 struct mxsfb_info *host = to_imxfb_host(fb_info);
378 u32 ctrl, vdctrl0, vdctrl4;
379 int line_size, fb_size;
380 int reenable = 0;
381
382 line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
383 fb_size = fb_info->var.yres_virtual * line_size;
384
385 if (fb_size > fb_info->fix.smem_len)
386 return -ENOMEM;
387
388 fb_info->fix.line_length = line_size;
389
390 /*
391 * It seems, you can't re-program the controller if it is still running.
392 * This may lead into shifted pictures (FIFO issue?).
393 * So, first stop the controller and drain its FIFOs
394 */
395 if (host->enabled) {
396 reenable = 1;
397 mxsfb_disable_controller(fb_info);
398 }
399
400 /* clear the FIFOs */
401 writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
402
403 ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER |
404 CTRL_SET_BUS_WIDTH(host->ld_intf_width);;
405
406 switch (fb_info->var.bits_per_pixel) {
407 case 16:
408 dev_dbg(&host->pdev->dev, "Setting up RGB565 mode\n");
409 ctrl |= CTRL_SET_WORD_LENGTH(0);
410 writel(CTRL1_SET_BYTE_PACKAGING(0xf), host->base + LCDC_CTRL1);
411 break;
412 case 32:
413 dev_dbg(&host->pdev->dev, "Setting up RGB888/666 mode\n");
414 ctrl |= CTRL_SET_WORD_LENGTH(3);
415 switch (host->ld_intf_width) {
416 case STMLCDIF_8BIT:
417 dev_dbg(&host->pdev->dev,
418 "Unsupported LCD bus width mapping\n");
419 return -EINVAL;
420 case STMLCDIF_16BIT:
421 case STMLCDIF_18BIT:
422 /* 24 bit to 18 bit mapping */
423 ctrl |= CTRL_DF24; /* ignore the upper 2 bits in
424 * each colour component
425 */
426 break;
427 case STMLCDIF_24BIT:
428 /* real 24 bit */
429 break;
430 }
431 /* do not use packed pixels = one pixel per word instead */
432 writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1);
433 break;
434 default:
435 dev_dbg(&host->pdev->dev, "Unhandled color depth of %u\n",
436 fb_info->var.bits_per_pixel);
437 return -EINVAL;
438 }
439
440 writel(ctrl, host->base + LCDC_CTRL);
441
442 writel(TRANSFER_COUNT_SET_VCOUNT(fb_info->var.yres) |
443 TRANSFER_COUNT_SET_HCOUNT(fb_info->var.xres),
444 host->base + host->devdata->transfer_count);
445
446 vdctrl0 = VDCTRL0_ENABLE_PRESENT | /* always in DOTCLOCK mode */
447 VDCTRL0_VSYNC_PERIOD_UNIT |
448 VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
449 VDCTRL0_SET_VSYNC_PULSE_WIDTH(fb_info->var.vsync_len);
450 if (fb_info->var.sync & FB_SYNC_HOR_HIGH_ACT)
451 vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
452 if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT)
453 vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
454 if (fb_info->var.sync & FB_SYNC_DATA_ENABLE_HIGH_ACT)
455 vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
456 if (fb_info->var.sync & FB_SYNC_DOTCLK_FAILING_ACT)
457 vdctrl0 |= VDCTRL0_DOTCLK_ACT_FAILING;
458
459 writel(vdctrl0, host->base + LCDC_VDCTRL0);
460
461 /* frame length in lines */
462 writel(fb_info->var.upper_margin + fb_info->var.vsync_len +
463 fb_info->var.lower_margin + fb_info->var.yres,
464 host->base + LCDC_VDCTRL1);
465
466 /* line length in units of clocks or pixels */
467 writel(set_hsync_pulse_width(host, fb_info->var.hsync_len) |
468 VDCTRL2_SET_HSYNC_PERIOD(fb_info->var.left_margin +
469 fb_info->var.hsync_len + fb_info->var.right_margin +
470 fb_info->var.xres),
471 host->base + LCDC_VDCTRL2);
472
473 writel(SET_HOR_WAIT_CNT(fb_info->var.left_margin +
474 fb_info->var.hsync_len) |
475 SET_VERT_WAIT_CNT(fb_info->var.upper_margin +
476 fb_info->var.vsync_len),
477 host->base + LCDC_VDCTRL3);
478
479 vdctrl4 = SET_DOTCLK_H_VALID_DATA_CNT(fb_info->var.xres);
480 if (mxsfb_is_v4(host))
481 vdctrl4 |= VDCTRL4_SET_DOTCLK_DLY(host->dotclk_delay);
482 writel(vdctrl4, host->base + LCDC_VDCTRL4);
483
484 writel(fb_info->fix.smem_start +
485 fb_info->fix.line_length * fb_info->var.yoffset,
486 host->base + host->devdata->next_buf);
487
488 if (reenable)
489 mxsfb_enable_controller(fb_info);
490
491 return 0;
492}
493
494static int mxsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
495 u_int transp, struct fb_info *fb_info)
496{
497 unsigned int val;
498 int ret = -EINVAL;
499
500 /*
501 * If greyscale is true, then we convert the RGB value
502 * to greyscale no matter what visual we are using.
503 */
504 if (fb_info->var.grayscale)
505 red = green = blue = (19595 * red + 38470 * green +
506 7471 * blue) >> 16;
507
508 switch (fb_info->fix.visual) {
509 case FB_VISUAL_TRUECOLOR:
510 /*
511 * 12 or 16-bit True Colour. We encode the RGB value
512 * according to the RGB bitfield information.
513 */
514 if (regno < 16) {
515 u32 *pal = fb_info->pseudo_palette;
516
517 val = chan_to_field(red, &fb_info->var.red);
518 val |= chan_to_field(green, &fb_info->var.green);
519 val |= chan_to_field(blue, &fb_info->var.blue);
520
521 pal[regno] = val;
522 ret = 0;
523 }
524 break;
525
526 case FB_VISUAL_STATIC_PSEUDOCOLOR:
527 case FB_VISUAL_PSEUDOCOLOR:
528 break;
529 }
530
531 return ret;
532}
533
534static int mxsfb_blank(int blank, struct fb_info *fb_info)
535{
536 struct mxsfb_info *host = to_imxfb_host(fb_info);
537
538 switch (blank) {
539 case FB_BLANK_POWERDOWN:
540 case FB_BLANK_VSYNC_SUSPEND:
541 case FB_BLANK_HSYNC_SUSPEND:
542 case FB_BLANK_NORMAL:
543 if (host->enabled)
544 mxsfb_disable_controller(fb_info);
545 break;
546
547 case FB_BLANK_UNBLANK:
548 if (!host->enabled)
549 mxsfb_enable_controller(fb_info);
550 break;
551 }
552 return 0;
553}
554
555static int mxsfb_pan_display(struct fb_var_screeninfo *var,
556 struct fb_info *fb_info)
557{
558 struct mxsfb_info *host = to_imxfb_host(fb_info);
559 unsigned offset;
560
561 if (var->xoffset != 0)
562 return -EINVAL;
563
564 offset = fb_info->fix.line_length * var->yoffset;
565
566 /* update on next VSYNC */
567 writel(fb_info->fix.smem_start + offset,
568 host->base + host->devdata->next_buf);
569
570 return 0;
571}
572
573static struct fb_ops mxsfb_ops = {
574 .owner = THIS_MODULE,
575 .fb_check_var = mxsfb_check_var,
576 .fb_set_par = mxsfb_set_par,
577 .fb_setcolreg = mxsfb_setcolreg,
578 .fb_blank = mxsfb_blank,
579 .fb_pan_display = mxsfb_pan_display,
580 .fb_fillrect = cfb_fillrect,
581 .fb_copyarea = cfb_copyarea,
582 .fb_imageblit = cfb_imageblit,
583};
584
585static int __devinit mxsfb_restore_mode(struct mxsfb_info *host)
586{
587 struct fb_info *fb_info = &host->fb_info;
588 unsigned line_count;
589 unsigned period;
590 unsigned long pa, fbsize;
591 int bits_per_pixel, ofs;
592 u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl;
593 struct fb_videomode vmode;
594
595 /* Only restore the mode when the controller is running */
596 ctrl = readl(host->base + LCDC_CTRL);
597 if (!(ctrl & CTRL_RUN))
598 return -EINVAL;
599
600 vdctrl0 = readl(host->base + LCDC_VDCTRL0);
601 vdctrl2 = readl(host->base + LCDC_VDCTRL2);
602 vdctrl3 = readl(host->base + LCDC_VDCTRL3);
603 vdctrl4 = readl(host->base + LCDC_VDCTRL4);
604
605 transfer_count = readl(host->base + host->devdata->transfer_count);
606
607 vmode.xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count);
608 vmode.yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count);
609
610 switch (CTRL_GET_WORD_LENGTH(ctrl)) {
611 case 0:
612 bits_per_pixel = 16;
613 break;
614 case 3:
615 bits_per_pixel = 32;
616 case 1:
617 default:
618 return -EINVAL;
619 }
620
621 fb_info->var.bits_per_pixel = bits_per_pixel;
622
623 vmode.pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U);
624 vmode.hsync_len = get_hsync_pulse_width(host, vdctrl2);
625 vmode.left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode.hsync_len;
626 vmode.right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) - vmode.hsync_len -
627 vmode.left_margin - vmode.xres;
628 vmode.vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0);
629 period = readl(host->base + LCDC_VDCTRL1);
630 vmode.upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode.vsync_len;
631 vmode.lower_margin = period - vmode.vsync_len - vmode.upper_margin - vmode.yres;
632
633 vmode.vmode = FB_VMODE_NONINTERLACED;
634
635 vmode.sync = 0;
636 if (vdctrl0 & VDCTRL0_HSYNC_ACT_HIGH)
637 vmode.sync |= FB_SYNC_HOR_HIGH_ACT;
638 if (vdctrl0 & VDCTRL0_VSYNC_ACT_HIGH)
639 vmode.sync |= FB_SYNC_VERT_HIGH_ACT;
640
641 pr_debug("Reconstructed video mode:\n");
642 pr_debug("%dx%d, hsync: %u left: %u, right: %u, vsync: %u, upper: %u, lower: %u\n",
643 vmode.xres, vmode.yres,
644 vmode.hsync_len, vmode.left_margin, vmode.right_margin,
645 vmode.vsync_len, vmode.upper_margin, vmode.lower_margin);
646 pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode.pixclock));
647
648 fb_add_videomode(&vmode, &fb_info->modelist);
649
650 host->ld_intf_width = CTRL_GET_BUS_WIDTH(ctrl);
651 host->dotclk_delay = VDCTRL4_GET_DOTCLK_DLY(vdctrl4);
652
653 fb_info->fix.line_length = vmode.xres * (bits_per_pixel >> 3);
654
655 pa = readl(host->base + host->devdata->cur_buf);
656 fbsize = fb_info->fix.line_length * vmode.yres;
657 if (pa < fb_info->fix.smem_start)
658 return -EINVAL;
659 if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len)
660 return -EINVAL;
661 ofs = pa - fb_info->fix.smem_start;
662 if (ofs) {
663 memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize);
664 writel(fb_info->fix.smem_start, host->base + host->devdata->next_buf);
665 }
666
667 line_count = fb_info->fix.smem_len / fb_info->fix.line_length;
668 fb_info->fix.ypanstep = 1;
669
670 clk_enable(host->clk);
671 host->enabled = 1;
672
673 return 0;
674}
675
676static int __devinit mxsfb_init_fbinfo(struct mxsfb_info *host)
677{
678 struct fb_info *fb_info = &host->fb_info;
679 struct fb_var_screeninfo *var = &fb_info->var;
680 struct mxsfb_platform_data *pdata = host->pdev->dev.platform_data;
681 dma_addr_t fb_phys;
682 void *fb_virt;
683 unsigned fb_size = pdata->fb_size;
684
685 fb_info->fbops = &mxsfb_ops;
686 fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
687 strlcpy(fb_info->fix.id, "mxs", sizeof(fb_info->fix.id));
688 fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
689 fb_info->fix.ypanstep = 1;
690 fb_info->fix.visual = FB_VISUAL_TRUECOLOR,
691 fb_info->fix.accel = FB_ACCEL_NONE;
692
693 var->bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16;
694 var->nonstd = 0;
695 var->activate = FB_ACTIVATE_NOW;
696 var->accel_flags = 0;
697 var->vmode = FB_VMODE_NONINTERLACED;
698
699 host->dotclk_delay = pdata->dotclk_delay;
700 host->ld_intf_width = pdata->ld_intf_width;
701
702 /* Memory allocation for framebuffer */
703 if (pdata->fb_phys) {
704 if (!fb_size)
705 return -EINVAL;
706
707 fb_phys = pdata->fb_phys;
708
709 if (!request_mem_region(fb_phys, fb_size, host->pdev->name))
710 return -ENOMEM;
711
712 fb_virt = ioremap(fb_phys, fb_size);
713 if (!fb_virt) {
714 release_mem_region(fb_phys, fb_size);
715 return -ENOMEM;
716 }
717 host->mapped = 1;
718 } else {
719 if (!fb_size)
720 fb_size = SZ_2M; /* default */
721 fb_virt = alloc_pages_exact(fb_size, GFP_DMA);
722 if (!fb_virt)
723 return -ENOMEM;
724
725 fb_phys = virt_to_phys(fb_virt);
726 }
727
728 fb_info->fix.smem_start = fb_phys;
729 fb_info->screen_base = fb_virt;
730 fb_info->screen_size = fb_info->fix.smem_len = fb_size;
731
732 if (mxsfb_restore_mode(host))
733 memset(fb_virt, 0, fb_size);
734
735 return 0;
736}
737
738static void __devexit mxsfb_free_videomem(struct mxsfb_info *host)
739{
740 struct fb_info *fb_info = &host->fb_info;
741
742 if (host->mapped) {
743 iounmap(fb_info->screen_base);
744 release_mem_region(fb_info->fix.smem_start,
745 fb_info->screen_size);
746 } else {
747 free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
748 }
749}
750
751static int __devinit mxsfb_probe(struct platform_device *pdev)
752{
753 struct mxsfb_platform_data *pdata = pdev->dev.platform_data;
754 struct resource *res;
755 struct mxsfb_info *host;
756 struct fb_info *fb_info;
757 struct fb_modelist *modelist;
758 int i, ret;
759
760 if (!pdata) {
761 dev_err(&pdev->dev, "No platformdata. Giving up\n");
762 return -ENODEV;
763 }
764
765 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
766 if (!res) {
767 dev_err(&pdev->dev, "Cannot get memory IO resource\n");
768 return -ENODEV;
769 }
770
771 if (!request_mem_region(res->start, resource_size(res), pdev->name))
772 return -EBUSY;
773
774 fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev);
775 if (!fb_info) {
776 dev_err(&pdev->dev, "Failed to allocate fbdev\n");
777 ret = -ENOMEM;
778 goto error_alloc_info;
779 }
780
781 host = to_imxfb_host(fb_info);
782
783 host->base = ioremap(res->start, resource_size(res));
784 if (!host->base) {
785 dev_err(&pdev->dev, "ioremap failed\n");
786 ret = -ENOMEM;
787 goto error_ioremap;
788 }
789
790 host->pdev = pdev;
791 platform_set_drvdata(pdev, host);
792
793 host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data];
794
795 host->clk = clk_get(&host->pdev->dev, NULL);
796 if (IS_ERR(host->clk)) {
797 ret = PTR_ERR(host->clk);
798 goto error_getclock;
799 }
800
801 fb_info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
802 if (!fb_info->pseudo_palette) {
803 ret = -ENOMEM;
804 goto error_pseudo_pallette;
805 }
806
807 INIT_LIST_HEAD(&fb_info->modelist);
808
809 ret = mxsfb_init_fbinfo(host);
810 if (ret != 0)
811 goto error_init_fb;
812
813 for (i = 0; i < pdata->mode_count; i++)
814 fb_add_videomode(&pdata->mode_list[i], &fb_info->modelist);
815
816 modelist = list_first_entry(&fb_info->modelist,
817 struct fb_modelist, list);
818 fb_videomode_to_var(&fb_info->var, &modelist->mode);
819
820 /* init the color fields */
821 mxsfb_check_var(&fb_info->var, fb_info);
822
823 platform_set_drvdata(pdev, fb_info);
824
825 ret = register_framebuffer(fb_info);
826 if (ret != 0) {
827 dev_err(&pdev->dev,"Failed to register framebuffer\n");
828 goto error_register;
829 }
830
831 if (!host->enabled) {
832 writel(0, host->base + LCDC_CTRL);
833 mxsfb_set_par(fb_info);
834 mxsfb_enable_controller(fb_info);
835 }
836
837 dev_info(&pdev->dev, "initialized\n");
838
839 return 0;
840
841error_register:
842 if (host->enabled)
843 clk_disable(host->clk);
844 fb_destroy_modelist(&fb_info->modelist);
845error_init_fb:
846 kfree(fb_info->pseudo_palette);
847error_pseudo_pallette:
848 clk_put(host->clk);
849error_getclock:
850 iounmap(host->base);
851error_ioremap:
852 framebuffer_release(fb_info);
853error_alloc_info:
854 release_mem_region(res->start, resource_size(res));
855
856 return ret;
857}
858
859static int __devexit mxsfb_remove(struct platform_device *pdev)
860{
861 struct fb_info *fb_info = platform_get_drvdata(pdev);
862 struct mxsfb_info *host = to_imxfb_host(fb_info);
863 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
864
865 if (host->enabled)
866 mxsfb_disable_controller(fb_info);
867
868 unregister_framebuffer(fb_info);
869 kfree(fb_info->pseudo_palette);
870 mxsfb_free_videomem(host);
871 iounmap(host->base);
872 clk_put(host->clk);
873
874 framebuffer_release(fb_info);
875 release_mem_region(res->start, resource_size(res));
876
877 platform_set_drvdata(pdev, NULL);
878
879 return 0;
880}
881
882static struct platform_device_id mxsfb_devtype[] = {
883 {
884 .name = "imx23-fb",
885 .driver_data = MXSFB_V3,
886 }, {
887 .name = "imx28-fb",
888 .driver_data = MXSFB_V4,
889 }, {
890 /* sentinel */
891 }
892};
893MODULE_DEVICE_TABLE(platform, mxsfb_devtype);
894
895static struct platform_driver mxsfb_driver = {
896 .probe = mxsfb_probe,
897 .remove = __devexit_p(mxsfb_remove),
898 .id_table = mxsfb_devtype,
899 .driver = {
900 .name = DRIVER_NAME,
901 },
902};
903
904static int __init mxsfb_init(void)
905{
906 return platform_driver_register(&mxsfb_driver);
907}
908
909static void __exit mxsfb_exit(void)
910{
911 platform_driver_unregister(&mxsfb_driver);
912}
913
914module_init(mxsfb_init);
915module_exit(mxsfb_exit);
916
917MODULE_DESCRIPTION("Freescale mxs framebuffer driver");
918MODULE_AUTHOR("Sascha Hauer, Pengutronix");
919MODULE_LICENSE("GPL");
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index 6aac6d1b937b..8471008aa6ff 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -111,6 +111,7 @@ void nvidia_bl_init(struct nvidia_par *par)
111 snprintf(name, sizeof(name), "nvidiabl%d", info->node); 111 snprintf(name, sizeof(name), "nvidiabl%d", info->node);
112 112
113 memset(&props, 0, sizeof(struct backlight_properties)); 113 memset(&props, 0, sizeof(struct backlight_properties));
114 props.type = BACKLIGHT_RAW;
114 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 115 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
115 bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops, 116 bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops,
116 &props); 117 &props);
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-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index e77310653207..7e04c921aa2a 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -534,6 +534,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
534 534
535 props.fb_blank = FB_BLANK_UNBLANK; 535 props.fb_blank = FB_BLANK_UNBLANK;
536 props.power = FB_BLANK_UNBLANK; 536 props.power = FB_BLANK_UNBLANK;
537 props.type = BACKLIGHT_RAW;
537 538
538 bldev = backlight_device_register("acx565akm", &md->spi->dev, 539 bldev = backlight_device_register("acx565akm", &md->spi->dev,
539 md, &acx565akm_bl_ops, &props); 540 md, &acx565akm_bl_ops, &props);
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-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index 9a138f650e05..d2b35d2df2a6 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -99,6 +99,7 @@ static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
99 99
100 memset(&props, 0, sizeof(struct backlight_properties)); 100 memset(&props, 0, sizeof(struct backlight_properties));
101 props.max_brightness = dssdev->max_backlight_level; 101 props.max_brightness = dssdev->max_backlight_level;
102 props.type = BACKLIGHT_RAW;
102 103
103 bl = backlight_device_register("sharp-ls", &dssdev->dev, dssdev, 104 bl = backlight_device_register("sharp-ls", &dssdev->dev, dssdev,
104 &sharp_ls_bl_ops, &props); 105 &sharp_ls_bl_ops, &props);
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 61026f96ad20..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
@@ -729,6 +732,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
729 props.max_brightness = 255; 732 props.max_brightness = 255;
730 else 733 else
731 props.max_brightness = 127; 734 props.max_brightness = 127;
735
736 props.type = BACKLIGHT_RAW;
732 bldev = backlight_device_register("taal", &dssdev->dev, dssdev, 737 bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
733 &taal_bl_ops, &props); 738 &taal_bl_ops, &props);
734 if (IS_ERR(bldev)) { 739 if (IS_ERR(bldev)) {
@@ -774,14 +779,29 @@ static int taal_probe(struct omap_dss_device *dssdev)
774 dev_dbg(&dssdev->dev, "Using GPIO TE\n"); 779 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
775 } 780 }
776 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
777 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); 794 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
778 if (r) { 795 if (r) {
779 dev_err(&dssdev->dev, "failed to create sysfs files\n"); 796 dev_err(&dssdev->dev, "failed to create sysfs files\n");
780 goto err_sysfs; 797 goto err_vc_id;
781 } 798 }
782 799
783 return 0; 800 return 0;
784err_sysfs: 801
802err_vc_id:
803 omap_dsi_release_vc(dssdev, td->channel);
804err_req_vc:
785 if (panel_data->use_ext_te) 805 if (panel_data->use_ext_te)
786 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev); 806 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
787err_irq: 807err_irq:
@@ -808,6 +828,7 @@ static void taal_remove(struct omap_dss_device *dssdev)
808 dev_dbg(&dssdev->dev, "remove\n"); 828 dev_dbg(&dssdev->dev, "remove\n");
809 829
810 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);
811 832
812 if (panel_data->use_ext_te) { 833 if (panel_data->use_ext_te) {
813 int gpio = panel_data->ext_te_gpio; 834 int gpio = panel_data->ext_te_gpio;
@@ -846,13 +867,13 @@ static int taal_power_on(struct omap_dss_device *dssdev)
846 867
847 taal_hw_reset(dssdev); 868 taal_hw_reset(dssdev);
848 869
849 omapdss_dsi_vc_enable_hs(TCH, false); 870 omapdss_dsi_vc_enable_hs(td->channel, false);
850 871
851 r = taal_sleep_out(td); 872 r = taal_sleep_out(td);
852 if (r) 873 if (r)
853 goto err; 874 goto err;
854 875
855 r = taal_get_id(&id1, &id2, &id3); 876 r = taal_get_id(td, &id1, &id2, &id3);
856 if (r) 877 if (r)
857 goto err; 878 goto err;
858 879
@@ -861,30 +882,30 @@ static int taal_power_on(struct omap_dss_device *dssdev)
861 (id2 == 0x00 || id2 == 0xff || id2 == 0x81)) 882 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
862 td->cabc_broken = true; 883 td->cabc_broken = true;
863 884
864 r = taal_dcs_write_1(DCS_BRIGHTNESS, 0xff); 885 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
865 if (r) 886 if (r)
866 goto err; 887 goto err;
867 888
868 r = taal_dcs_write_1(DCS_CTRL_DISPLAY, 889 r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
869 (1<<2) | (1<<5)); /* BL | BCTRL */ 890 (1<<2) | (1<<5)); /* BL | BCTRL */
870 if (r) 891 if (r)
871 goto err; 892 goto err;
872 893
873 r = taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ 894 r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
874 if (r) 895 if (r)
875 goto err; 896 goto err;
876 897
877 r = taal_set_addr_mode(td->rotate, td->mirror); 898 r = taal_set_addr_mode(td, td->rotate, td->mirror);
878 if (r) 899 if (r)
879 goto err; 900 goto err;
880 901
881 if (!td->cabc_broken) { 902 if (!td->cabc_broken) {
882 r = taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode); 903 r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
883 if (r) 904 if (r)
884 goto err; 905 goto err;
885 } 906 }
886 907
887 r = taal_dcs_write_0(DCS_DISPLAY_ON); 908 r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
888 if (r) 909 if (r)
889 goto err; 910 goto err;
890 911
@@ -903,7 +924,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
903 td->intro_printed = true; 924 td->intro_printed = true;
904 } 925 }
905 926
906 omapdss_dsi_vc_enable_hs(TCH, true); 927 omapdss_dsi_vc_enable_hs(td->channel, true);
907 928
908 return 0; 929 return 0;
909err: 930err:
@@ -921,7 +942,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
921 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 942 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
922 int r; 943 int r;
923 944
924 r = taal_dcs_write_0(DCS_DISPLAY_OFF); 945 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
925 if (!r) { 946 if (!r) {
926 r = taal_sleep_in(td); 947 r = taal_sleep_in(td);
927 /* HACK: wait a bit so that the message goes through */ 948 /* HACK: wait a bit so that the message goes through */
@@ -1089,7 +1110,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
1089 if (old) { 1110 if (old) {
1090 cancel_delayed_work(&td->te_timeout_work); 1111 cancel_delayed_work(&td->te_timeout_work);
1091 1112
1092 r = omap_dsi_update(dssdev, TCH, 1113 r = omap_dsi_update(dssdev, td->channel,
1093 td->update_region.x, 1114 td->update_region.x,
1094 td->update_region.y, 1115 td->update_region.y,
1095 td->update_region.w, 1116 td->update_region.w,
@@ -1139,7 +1160,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1139 if (r) 1160 if (r)
1140 goto err; 1161 goto err;
1141 1162
1142 r = taal_set_update_window(x, y, w, h); 1163 r = taal_set_update_window(td, x, y, w, h);
1143 if (r) 1164 if (r)
1144 goto err; 1165 goto err;
1145 1166
@@ -1153,7 +1174,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1153 msecs_to_jiffies(250)); 1174 msecs_to_jiffies(250));
1154 atomic_set(&td->do_update, 1); 1175 atomic_set(&td->do_update, 1);
1155 } else { 1176 } else {
1156 r = omap_dsi_update(dssdev, TCH, x, y, w, h, 1177 r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
1157 taal_framedone_cb, dssdev); 1178 taal_framedone_cb, dssdev);
1158 if (r) 1179 if (r)
1159 goto err; 1180 goto err;
@@ -1191,9 +1212,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1191 int r; 1212 int r;
1192 1213
1193 if (enable) 1214 if (enable)
1194 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1215 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1195 else 1216 else
1196 r = taal_dcs_write_0(DCS_TEAR_OFF); 1217 r = taal_dcs_write_0(td, DCS_TEAR_OFF);
1197 1218
1198 if (!panel_data->use_ext_te) 1219 if (!panel_data->use_ext_te)
1199 omapdss_dsi_enable_te(dssdev, enable); 1220 omapdss_dsi_enable_te(dssdev, enable);
@@ -1263,7 +1284,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1263 dsi_bus_lock(); 1284 dsi_bus_lock();
1264 1285
1265 if (td->enabled) { 1286 if (td->enabled) {
1266 r = taal_set_addr_mode(rotate, td->mirror); 1287 r = taal_set_addr_mode(td, rotate, td->mirror);
1267 if (r) 1288 if (r)
1268 goto err; 1289 goto err;
1269 } 1290 }
@@ -1306,7 +1327,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1306 1327
1307 dsi_bus_lock(); 1328 dsi_bus_lock();
1308 if (td->enabled) { 1329 if (td->enabled) {
1309 r = taal_set_addr_mode(td->rotate, enable); 1330 r = taal_set_addr_mode(td, td->rotate, enable);
1310 if (r) 1331 if (r)
1311 goto err; 1332 goto err;
1312 } 1333 }
@@ -1350,13 +1371,13 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1350 1371
1351 dsi_bus_lock(); 1372 dsi_bus_lock();
1352 1373
1353 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 1374 r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1354 if (r) 1375 if (r)
1355 goto err2; 1376 goto err2;
1356 r = taal_dcs_read_1(DCS_GET_ID2, &id2); 1377 r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
1357 if (r) 1378 if (r)
1358 goto err2; 1379 goto err2;
1359 r = taal_dcs_read_1(DCS_GET_ID3, &id3); 1380 r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
1360 if (r) 1381 if (r)
1361 goto err2; 1382 goto err2;
1362 1383
@@ -1404,9 +1425,9 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1404 else 1425 else
1405 plen = 2; 1426 plen = 2;
1406 1427
1407 taal_set_update_window(x, y, w, h); 1428 taal_set_update_window(td, x, y, w, h);
1408 1429
1409 r = dsi_vc_set_max_rx_packet_size(TCH, plen); 1430 r = dsi_vc_set_max_rx_packet_size(td->channel, plen);
1410 if (r) 1431 if (r)
1411 goto err2; 1432 goto err2;
1412 1433
@@ -1414,7 +1435,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1414 u8 dcs_cmd = first ? 0x2e : 0x3e; 1435 u8 dcs_cmd = first ? 0x2e : 0x3e;
1415 first = 0; 1436 first = 0;
1416 1437
1417 r = dsi_vc_dcs_read(TCH, dcs_cmd, 1438 r = dsi_vc_dcs_read(td->channel, dcs_cmd,
1418 buf + buf_used, size - buf_used); 1439 buf + buf_used, size - buf_used);
1419 1440
1420 if (r < 0) { 1441 if (r < 0) {
@@ -1440,7 +1461,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1440 r = buf_used; 1461 r = buf_used;
1441 1462
1442err3: 1463err3:
1443 dsi_vc_set_max_rx_packet_size(TCH, 1); 1464 dsi_vc_set_max_rx_packet_size(td->channel, 1);
1444err2: 1465err2:
1445 dsi_bus_unlock(); 1466 dsi_bus_unlock();
1446err1: 1467err1:
@@ -1466,7 +1487,7 @@ static void taal_esd_work(struct work_struct *work)
1466 1487
1467 dsi_bus_lock(); 1488 dsi_bus_lock();
1468 1489
1469 r = taal_dcs_read_1(DCS_RDDSDR, &state1); 1490 r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
1470 if (r) { 1491 if (r) {
1471 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1492 dev_err(&dssdev->dev, "failed to read Taal status\n");
1472 goto err; 1493 goto err;
@@ -1479,7 +1500,7 @@ static void taal_esd_work(struct work_struct *work)
1479 goto err; 1500 goto err;
1480 } 1501 }
1481 1502
1482 r = taal_dcs_read_1(DCS_RDDSDR, &state2); 1503 r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
1483 if (r) { 1504 if (r) {
1484 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1505 dev_err(&dssdev->dev, "failed to read Taal status\n");
1485 goto err; 1506 goto err;
@@ -1495,7 +1516,7 @@ static void taal_esd_work(struct work_struct *work)
1495 /* 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
1496 * to re-enable TE after self diagnostics */ 1517 * to re-enable TE after self diagnostics */
1497 if (td->te_enabled && panel_data->use_ext_te) { 1518 if (td->te_enabled && panel_data->use_ext_te) {
1498 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1519 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1499 if (r) 1520 if (r)
1500 goto err; 1521 goto err;
1501 } 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/p9100.c b/drivers/video/p9100.c
index b6c3fc2db632..d57cc58c5168 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -249,7 +249,7 @@ static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_no
249 info->fix.accel = FB_ACCEL_SUN_CGTHREE; 249 info->fix.accel = FB_ACCEL_SUN_CGTHREE;
250} 250}
251 251
252static int __devinit p9100_probe(struct platform_device *op, const struct of_device_id *match) 252static int __devinit p9100_probe(struct platform_device *op)
253{ 253{
254 struct device_node *dp = op->dev.of_node; 254 struct device_node *dp = op->dev.of_node;
255 struct fb_info *info; 255 struct fb_info *info;
@@ -352,7 +352,7 @@ static const struct of_device_id p9100_match[] = {
352}; 352};
353MODULE_DEVICE_TABLE(of, p9100_match); 353MODULE_DEVICE_TABLE(of, p9100_match);
354 354
355static struct of_platform_driver p9100_driver = { 355static struct platform_driver p9100_driver = {
356 .driver = { 356 .driver = {
357 .name = "p9100", 357 .name = "p9100",
358 .owner = THIS_MODULE, 358 .owner = THIS_MODULE,
@@ -367,12 +367,12 @@ static int __init p9100_init(void)
367 if (fb_get_options("p9100fb", NULL)) 367 if (fb_get_options("p9100fb", NULL))
368 return -ENODEV; 368 return -ENODEV;
369 369
370 return of_register_platform_driver(&p9100_driver); 370 return platform_driver_register(&p9100_driver);
371} 371}
372 372
373static void __exit p9100_exit(void) 373static void __exit p9100_exit(void)
374{ 374{
375 of_unregister_platform_driver(&p9100_driver); 375 platform_driver_unregister(&p9100_driver);
376} 376}
377 377
378module_init(p9100_init); 378module_init(p9100_init);
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index a50e1977b316..ef532d9d3c99 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -533,8 +533,7 @@ static int __init platinumfb_setup(char *options)
533#define invalidate_cache(addr) 533#define invalidate_cache(addr)
534#endif 534#endif
535 535
536static int __devinit platinumfb_probe(struct platform_device* odev, 536static int __devinit platinumfb_probe(struct platform_device* odev)
537 const struct of_device_id *match)
538{ 537{
539 struct device_node *dp = odev->dev.of_node; 538 struct device_node *dp = odev->dev.of_node;
540 struct fb_info *info; 539 struct fb_info *info;
@@ -677,7 +676,7 @@ static struct of_device_id platinumfb_match[] =
677 {}, 676 {},
678}; 677};
679 678
680static struct of_platform_driver platinum_driver = 679static struct platform_driver platinum_driver =
681{ 680{
682 .driver = { 681 .driver = {
683 .name = "platinumfb", 682 .name = "platinumfb",
@@ -697,14 +696,14 @@ static int __init platinumfb_init(void)
697 return -ENODEV; 696 return -ENODEV;
698 platinumfb_setup(option); 697 platinumfb_setup(option);
699#endif 698#endif
700 of_register_platform_driver(&platinum_driver); 699 platform_driver_register(&platinum_driver);
701 700
702 return 0; 701 return 0;
703} 702}
704 703
705static void __exit platinumfb_exit(void) 704static void __exit platinumfb_exit(void)
706{ 705{
707 of_unregister_platform_driver(&platinum_driver); 706 platform_driver_unregister(&platinum_driver);
708} 707}
709 708
710MODULE_LICENSE("GPL"); 709MODULE_LICENSE("GPL");
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index da388186d617..d8ab7be4fd6b 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -355,6 +355,7 @@ static void riva_bl_init(struct riva_par *par)
355 snprintf(name, sizeof(name), "rivabl%d", info->node); 355 snprintf(name, sizeof(name), "rivabl%d", info->node);
356 356
357 memset(&props, 0, sizeof(struct backlight_properties)); 357 memset(&props, 0, sizeof(struct backlight_properties));
358 props.type = BACKLIGHT_RAW;
358 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 359 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
359 bd = backlight_device_register(name, info->dev, par, &riva_bl_ops, 360 bd = backlight_device_register(name, info->dev, par, &riva_bl_ops,
360 &props); 361 &props);
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 bf12e53aed5c..757665bc500f 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -21,6 +21,8 @@
21#include <linux/ioctl.h> 21#include <linux/ioctl.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/console.h> 23#include <linux/console.h>
24#include <linux/backlight.h>
25#include <linux/gpio.h>
24#include <video/sh_mobile_lcdc.h> 26#include <video/sh_mobile_lcdc.h>
25#include <asm/atomic.h> 27#include <asm/atomic.h>
26 28
@@ -67,6 +69,7 @@ static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
67 [LDSM1R] = 0x428, 69 [LDSM1R] = 0x428,
68 [LDSM2R] = 0x42c, 70 [LDSM2R] = 0x42c,
69 [LDSA1R] = 0x430, 71 [LDSA1R] = 0x430,
72 [LDSA2R] = 0x434,
70 [LDMLSR] = 0x438, 73 [LDMLSR] = 0x438,
71 [LDHCNR] = 0x448, 74 [LDHCNR] = 0x448,
72 [LDHSYNR] = 0x44c, 75 [LDHSYNR] = 0x44c,
@@ -151,6 +154,7 @@ static bool banked(int reg_nr)
151 case LDDFR: 154 case LDDFR:
152 case LDSM1R: 155 case LDSM1R:
153 case LDSA1R: 156 case LDSA1R:
157 case LDSA2R:
154 case LDMLSR: 158 case LDMLSR:
155 case LDHCNR: 159 case LDHCNR:
156 case LDHSYNR: 160 case LDHSYNR:
@@ -463,6 +467,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
463 struct sh_mobile_lcdc_board_cfg *board_cfg; 467 struct sh_mobile_lcdc_board_cfg *board_cfg;
464 unsigned long tmp; 468 unsigned long tmp;
465 int bpp = 0; 469 int bpp = 0;
470 unsigned long ldddsr;
466 int k, m; 471 int k, m;
467 int ret = 0; 472 int ret = 0;
468 473
@@ -541,16 +546,21 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
541 } 546 }
542 547
543 /* word and long word swap */ 548 /* word and long word swap */
544 switch (bpp) { 549 ldddsr = lcdc_read(priv, _LDDDSR);
545 case 16: 550 if (priv->ch[0].info->var.nonstd)
546 lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6); 551 lcdc_write(priv, _LDDDSR, ldddsr | 7);
547 break; 552 else {
548 case 24: 553 switch (bpp) {
549 lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 7); 554 case 16:
550 break; 555 lcdc_write(priv, _LDDDSR, ldddsr | 6);
551 case 32: 556 break;
552 lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 4); 557 case 24:
553 break; 558 lcdc_write(priv, _LDDDSR, ldddsr | 7);
559 break;
560 case 32:
561 lcdc_write(priv, _LDDDSR, ldddsr | 4);
562 break;
563 }
554 } 564 }
555 565
556 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 566 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
@@ -561,21 +571,40 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
561 571
562 /* set bpp format in PKF[4:0] */ 572 /* set bpp format in PKF[4:0] */
563 tmp = lcdc_read_chan(ch, LDDFR); 573 tmp = lcdc_read_chan(ch, LDDFR);
564 tmp &= ~0x0001001f; 574 tmp &= ~0x0003031f;
565 switch (ch->info->var.bits_per_pixel) { 575 if (ch->info->var.nonstd) {
566 case 16: 576 tmp |= (ch->info->var.nonstd << 16);
567 tmp |= 0x03; 577 switch (ch->info->var.bits_per_pixel) {
568 break; 578 case 12:
569 case 24: 579 break;
570 tmp |= 0x0b; 580 case 16:
571 break; 581 tmp |= (0x1 << 8);
572 case 32: 582 break;
573 break; 583 case 24:
584 tmp |= (0x2 << 8);
585 break;
586 }
587 } else {
588 switch (ch->info->var.bits_per_pixel) {
589 case 16:
590 tmp |= 0x03;
591 break;
592 case 24:
593 tmp |= 0x0b;
594 break;
595 case 32:
596 break;
597 }
574 } 598 }
575 lcdc_write_chan(ch, LDDFR, tmp); 599 lcdc_write_chan(ch, LDDFR, tmp);
576 600
577 /* point out our frame buffer */ 601 /* point out our frame buffer */
578 lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start); 602 lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start);
603 if (ch->info->var.nonstd)
604 lcdc_write_chan(ch, LDSA2R,
605 ch->info->fix.smem_start +
606 ch->info->var.xres *
607 ch->info->var.yres_virtual);
579 608
580 /* set line size */ 609 /* set line size */
581 lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length); 610 lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length);
@@ -618,6 +647,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
618 board_cfg->display_on(board_cfg->board_data, ch->info); 647 board_cfg->display_on(board_cfg->board_data, ch->info);
619 module_put(board_cfg->owner); 648 module_put(board_cfg->owner);
620 } 649 }
650
651 if (ch->bl) {
652 ch->bl->props.power = FB_BLANK_UNBLANK;
653 backlight_update_status(ch->bl);
654 }
621 } 655 }
622 656
623 return 0; 657 return 0;
@@ -648,6 +682,11 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
648 sh_mobile_lcdc_clk_on(priv); 682 sh_mobile_lcdc_clk_on(priv);
649 } 683 }
650 684
685 if (ch->bl) {
686 ch->bl->props.power = FB_BLANK_POWERDOWN;
687 backlight_update_status(ch->bl);
688 }
689
651 board_cfg = &ch->cfg.board_cfg; 690 board_cfg = &ch->cfg.board_cfg;
652 if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 691 if (try_module_get(board_cfg->owner) && board_cfg->display_off) {
653 board_cfg->display_off(board_cfg->board_data); 692 board_cfg->display_off(board_cfg->board_data);
@@ -804,9 +843,15 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
804 struct sh_mobile_lcdc_priv *priv = ch->lcdc; 843 struct sh_mobile_lcdc_priv *priv = ch->lcdc;
805 unsigned long ldrcntr; 844 unsigned long ldrcntr;
806 unsigned long new_pan_offset; 845 unsigned long new_pan_offset;
846 unsigned long base_addr_y, base_addr_c;
847 unsigned long c_offset;
807 848
808 new_pan_offset = (var->yoffset * info->fix.line_length) + 849 if (!var->nonstd)
809 (var->xoffset * (info->var.bits_per_pixel / 8)); 850 new_pan_offset = (var->yoffset * info->fix.line_length) +
851 (var->xoffset * (info->var.bits_per_pixel / 8));
852 else
853 new_pan_offset = (var->yoffset * info->fix.line_length) +
854 (var->xoffset);
810 855
811 if (new_pan_offset == ch->pan_offset) 856 if (new_pan_offset == ch->pan_offset)
812 return 0; /* No change, do nothing */ 857 return 0; /* No change, do nothing */
@@ -814,7 +859,26 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
814 ldrcntr = lcdc_read(priv, _LDRCNTR); 859 ldrcntr = lcdc_read(priv, _LDRCNTR);
815 860
816 /* Set the source address for the next refresh */ 861 /* Set the source address for the next refresh */
817 lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + new_pan_offset); 862 base_addr_y = ch->dma_handle + new_pan_offset;
863 if (var->nonstd) {
864 /* Set y offset */
865 c_offset = (var->yoffset *
866 info->fix.line_length *
867 (info->var.bits_per_pixel - 8)) / 8;
868 base_addr_c = ch->dma_handle + var->xres * var->yres_virtual +
869 c_offset;
870 /* Set x offset */
871 if (info->var.bits_per_pixel == 24)
872 base_addr_c += 2 * var->xoffset;
873 else
874 base_addr_c += var->xoffset;
875 } else
876 base_addr_c = 0;
877
878 lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y);
879 if (base_addr_c)
880 lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c);
881
818 if (lcdc_chan_is_sublcd(ch)) 882 if (lcdc_chan_is_sublcd(ch))
819 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS); 883 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
820 else 884 else
@@ -885,7 +949,10 @@ static void sh_mobile_fb_reconfig(struct fb_info *info)
885 /* Couldn't reconfigure, hopefully, can continue as before */ 949 /* Couldn't reconfigure, hopefully, can continue as before */
886 return; 950 return;
887 951
888 info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8); 952 if (info->var.nonstd)
953 info->fix.line_length = mode1.xres;
954 else
955 info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8);
889 956
890 /* 957 /*
891 * fb_set_var() calls the notifier change internally, only if 958 * fb_set_var() calls the notifier change internally, only if
@@ -980,8 +1047,81 @@ static struct fb_ops sh_mobile_lcdc_ops = {
980 .fb_check_var = sh_mobile_check_var, 1047 .fb_check_var = sh_mobile_check_var,
981}; 1048};
982 1049
983static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) 1050static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
1051{
1052 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
1053 struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
1054 int brightness = bdev->props.brightness;
1055
1056 if (bdev->props.power != FB_BLANK_UNBLANK ||
1057 bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
1058 brightness = 0;
1059
1060 return cfg->set_brightness(cfg->board_data, brightness);
1061}
1062
1063static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
984{ 1064{
1065 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
1066 struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
1067
1068 return cfg->get_brightness(cfg->board_data);
1069}
1070
1071static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
1072 struct fb_info *info)
1073{
1074 return (info->bl_dev == bdev);
1075}
1076
1077static struct backlight_ops sh_mobile_lcdc_bl_ops = {
1078 .options = BL_CORE_SUSPENDRESUME,
1079 .update_status = sh_mobile_lcdc_update_bl,
1080 .get_brightness = sh_mobile_lcdc_get_brightness,
1081 .check_fb = sh_mobile_lcdc_check_fb,
1082};
1083
1084static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
1085 struct sh_mobile_lcdc_chan *ch)
1086{
1087 struct backlight_device *bl;
1088
1089 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch,
1090 &sh_mobile_lcdc_bl_ops, NULL);
1091 if (IS_ERR(bl)) {
1092 dev_err(parent, "unable to register backlight device: %ld\n",
1093 PTR_ERR(bl));
1094 return NULL;
1095 }
1096
1097 bl->props.max_brightness = ch->cfg.bl_info.max_brightness;
1098 bl->props.brightness = bl->props.max_brightness;
1099 backlight_update_status(bl);
1100
1101 return bl;
1102}
1103
1104static void sh_mobile_lcdc_bl_remove(struct backlight_device *bdev)
1105{
1106 backlight_device_unregister(bdev);
1107}
1108
1109static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp,
1110 int nonstd)
1111{
1112 if (nonstd) {
1113 switch (bpp) {
1114 case 12:
1115 case 16:
1116 case 24:
1117 var->bits_per_pixel = bpp;
1118 var->nonstd = nonstd;
1119 return 0;
1120 default:
1121 return -EINVAL;
1122 }
1123 }
1124
985 switch (bpp) { 1125 switch (bpp) {
986 case 16: /* PKF[4:0] = 00011 - RGB 565 */ 1126 case 16: /* PKF[4:0] = 00011 - RGB 565 */
987 var->red.offset = 11; 1127 var->red.offset = 11;
@@ -1198,6 +1338,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1198 init_completion(&ch->vsync_completion); 1338 init_completion(&ch->vsync_completion);
1199 ch->pan_offset = 0; 1339 ch->pan_offset = 0;
1200 1340
1341 /* probe the backlight is there is one defined */
1342 if (ch->cfg.bl_info.max_brightness)
1343 ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch);
1344
1201 switch (pdata->ch[i].chan) { 1345 switch (pdata->ch[i].chan) {
1202 case LCDC_CHAN_MAINLCD: 1346 case LCDC_CHAN_MAINLCD:
1203 ch->enabled = 1 << 1; 1347 ch->enabled = 1 << 1;
@@ -1260,6 +1404,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1260 k < cfg->num_cfg && lcd_cfg; 1404 k < cfg->num_cfg && lcd_cfg;
1261 k++, lcd_cfg++) { 1405 k++, lcd_cfg++) {
1262 unsigned long size = lcd_cfg->yres * lcd_cfg->xres; 1406 unsigned long size = lcd_cfg->yres * lcd_cfg->xres;
1407 /* NV12 buffers must have even number of lines */
1408 if ((cfg->nonstd) && cfg->bpp == 12 &&
1409 (lcd_cfg->yres & 0x1)) {
1410 dev_err(&pdev->dev, "yres must be multiple of 2"
1411 " for YCbCr420 mode.\n");
1412 error = -EINVAL;
1413 goto err1;
1414 }
1263 1415
1264 if (size > max_size) { 1416 if (size > max_size) {
1265 max_cfg = lcd_cfg; 1417 max_cfg = lcd_cfg;
@@ -1274,7 +1426,11 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1274 max_cfg->xres, max_cfg->yres); 1426 max_cfg->xres, max_cfg->yres);
1275 1427
1276 info->fix = sh_mobile_lcdc_fix; 1428 info->fix = sh_mobile_lcdc_fix;
1277 info->fix.smem_len = max_size * (cfg->bpp / 8) * 2; 1429 info->fix.smem_len = max_size * 2 * cfg->bpp / 8;
1430
1431 /* Only pan in 2 line steps for NV12 */
1432 if (cfg->nonstd && cfg->bpp == 12)
1433 info->fix.ypanstep = 2;
1278 1434
1279 if (!mode) { 1435 if (!mode) {
1280 mode = &default_720p; 1436 mode = &default_720p;
@@ -1292,7 +1448,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1292 var->yres_virtual = var->yres * 2; 1448 var->yres_virtual = var->yres * 2;
1293 var->activate = FB_ACTIVATE_NOW; 1449 var->activate = FB_ACTIVATE_NOW;
1294 1450
1295 error = sh_mobile_lcdc_set_bpp(var, cfg->bpp); 1451 error = sh_mobile_lcdc_set_bpp(var, cfg->bpp, cfg->nonstd);
1296 if (error) 1452 if (error)
1297 break; 1453 break;
1298 1454
@@ -1316,7 +1472,11 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1316 } 1472 }
1317 1473
1318 info->fix.smem_start = ch->dma_handle; 1474 info->fix.smem_start = ch->dma_handle;
1319 info->fix.line_length = var->xres * (cfg->bpp / 8); 1475 if (var->nonstd)
1476 info->fix.line_length = var->xres;
1477 else
1478 info->fix.line_length = var->xres * (cfg->bpp / 8);
1479
1320 info->screen_base = buf; 1480 info->screen_base = buf;
1321 info->device = &pdev->dev; 1481 info->device = &pdev->dev;
1322 ch->display_var = *var; 1482 ch->display_var = *var;
@@ -1345,6 +1505,8 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1345 } 1505 }
1346 } 1506 }
1347 1507
1508 info->bl_dev = ch->bl;
1509
1348 error = register_framebuffer(info); 1510 error = register_framebuffer(info);
1349 if (error < 0) 1511 if (error < 0)
1350 goto err1; 1512 goto err1;
@@ -1404,6 +1566,11 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
1404 framebuffer_release(info); 1566 framebuffer_release(info);
1405 } 1567 }
1406 1568
1569 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
1570 if (priv->ch[i].bl)
1571 sh_mobile_lcdc_bl_remove(priv->ch[i].bl);
1572 }
1573
1407 if (priv->dot_clk) 1574 if (priv->dot_clk)
1408 clk_put(priv->dot_clk); 1575 clk_put(priv->dot_clk);
1409 1576
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index 9ecee2fba1d7..4635eed63eee 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -8,7 +8,7 @@
8 8
9/* per-channel registers */ 9/* per-channel registers */
10enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, 10enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
11 LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR, 11 LDSM2R, LDSA1R, LDSA2R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
12 LDHAJR, 12 LDHAJR,
13 NR_CH_REGS }; 13 NR_CH_REGS };
14 14
@@ -16,6 +16,7 @@ enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
16 16
17struct sh_mobile_lcdc_priv; 17struct sh_mobile_lcdc_priv;
18struct fb_info; 18struct fb_info;
19struct backlight_device;
19 20
20struct sh_mobile_lcdc_chan { 21struct sh_mobile_lcdc_chan {
21 struct sh_mobile_lcdc_priv *lcdc; 22 struct sh_mobile_lcdc_priv *lcdc;
@@ -26,6 +27,7 @@ struct sh_mobile_lcdc_chan {
26 u32 pseudo_palette[PALETTE_NR]; 27 u32 pseudo_palette[PALETTE_NR];
27 unsigned long saved_ch_regs[NR_CH_REGS]; 28 unsigned long saved_ch_regs[NR_CH_REGS];
28 struct fb_info *info; 29 struct fb_info *info;
30 struct backlight_device *bl;
29 dma_addr_t dma_handle; 31 dma_addr_t dma_handle;
30 struct fb_deferred_io defio; 32 struct fb_deferred_io defio;
31 struct scatterlist *sglist; 33 struct scatterlist *sglist;
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/sunxvr1000.c b/drivers/video/sunxvr1000.c
index 5dbe06af2226..b7f27acaf817 100644
--- a/drivers/video/sunxvr1000.c
+++ b/drivers/video/sunxvr1000.c
@@ -111,8 +111,7 @@ static int __devinit gfb_set_fbinfo(struct gfb_info *gp)
111 return 0; 111 return 0;
112} 112}
113 113
114static int __devinit gfb_probe(struct platform_device *op, 114static int __devinit gfb_probe(struct platform_device *op)
115 const struct of_device_id *match)
116{ 115{
117 struct device_node *dp = op->dev.of_node; 116 struct device_node *dp = op->dev.of_node;
118 struct fb_info *info; 117 struct fb_info *info;
@@ -198,7 +197,7 @@ static const struct of_device_id gfb_match[] = {
198}; 197};
199MODULE_DEVICE_TABLE(of, ffb_match); 198MODULE_DEVICE_TABLE(of, ffb_match);
200 199
201static struct of_platform_driver gfb_driver = { 200static struct platform_driver gfb_driver = {
202 .probe = gfb_probe, 201 .probe = gfb_probe,
203 .remove = __devexit_p(gfb_remove), 202 .remove = __devexit_p(gfb_remove),
204 .driver = { 203 .driver = {
@@ -213,12 +212,12 @@ static int __init gfb_init(void)
213 if (fb_get_options("gfb", NULL)) 212 if (fb_get_options("gfb", NULL))
214 return -ENODEV; 213 return -ENODEV;
215 214
216 return of_register_platform_driver(&gfb_driver); 215 return platform_driver_register(&gfb_driver);
217} 216}
218 217
219static void __exit gfb_exit(void) 218static void __exit gfb_exit(void)
220{ 219{
221 of_unregister_platform_driver(&gfb_driver); 220 platform_driver_unregister(&gfb_driver);
222} 221}
223 222
224module_init(gfb_init); 223module_init(gfb_init);
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 77ad27955cf0..07c66e946634 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -362,8 +362,7 @@ static void tcx_unmap_regs(struct platform_device *op, struct fb_info *info,
362 info->screen_base, info->fix.smem_len); 362 info->screen_base, info->fix.smem_len);
363} 363}
364 364
365static int __devinit tcx_probe(struct platform_device *op, 365static int __devinit tcx_probe(struct platform_device *op)
366 const struct of_device_id *match)
367{ 366{
368 struct device_node *dp = op->dev.of_node; 367 struct device_node *dp = op->dev.of_node;
369 struct fb_info *info; 368 struct fb_info *info;
@@ -481,6 +480,7 @@ out_dealloc_cmap:
481 480
482out_unmap_regs: 481out_unmap_regs:
483 tcx_unmap_regs(op, info, par); 482 tcx_unmap_regs(op, info, par);
483 framebuffer_release(info);
484 484
485out_err: 485out_err:
486 return err; 486 return err;
@@ -511,7 +511,7 @@ static const struct of_device_id tcx_match[] = {
511}; 511};
512MODULE_DEVICE_TABLE(of, tcx_match); 512MODULE_DEVICE_TABLE(of, tcx_match);
513 513
514static struct of_platform_driver tcx_driver = { 514static struct platform_driver tcx_driver = {
515 .driver = { 515 .driver = {
516 .name = "tcx", 516 .name = "tcx",
517 .owner = THIS_MODULE, 517 .owner = THIS_MODULE,
@@ -526,12 +526,12 @@ static int __init tcx_init(void)
526 if (fb_get_options("tcxfb", NULL)) 526 if (fb_get_options("tcxfb", NULL))
527 return -ENODEV; 527 return -ENODEV;
528 528
529 return of_register_platform_driver(&tcx_driver); 529 return platform_driver_register(&tcx_driver);
530} 530}
531 531
532static void __exit tcx_exit(void) 532static void __exit tcx_exit(void)
533{ 533{
534 of_unregister_platform_driver(&tcx_driver); 534 platform_driver_unregister(&tcx_driver);
535} 535}
536 536
537module_init(tcx_init); 537module_init(tcx_init);
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index dfef88c803d4..9710bf8caeae 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -250,8 +250,7 @@ static irqreturn_t tmiofb_irq(int irq, void *__info)
250 */ 250 */
251static int tmiofb_hw_stop(struct platform_device *dev) 251static int tmiofb_hw_stop(struct platform_device *dev)
252{ 252{
253 struct mfd_cell *cell = dev->dev.platform_data; 253 struct tmio_fb_data *data = mfd_get_data(dev);
254 struct tmio_fb_data *data = cell->driver_data;
255 struct fb_info *info = platform_get_drvdata(dev); 254 struct fb_info *info = platform_get_drvdata(dev);
256 struct tmiofb_par *par = info->par; 255 struct tmiofb_par *par = info->par;
257 256
@@ -268,7 +267,7 @@ static int tmiofb_hw_stop(struct platform_device *dev)
268 */ 267 */
269static int tmiofb_hw_init(struct platform_device *dev) 268static int tmiofb_hw_init(struct platform_device *dev)
270{ 269{
271 struct mfd_cell *cell = dev->dev.platform_data; 270 const struct mfd_cell *cell = mfd_get_cell(dev);
272 struct fb_info *info = platform_get_drvdata(dev); 271 struct fb_info *info = platform_get_drvdata(dev);
273 struct tmiofb_par *par = info->par; 272 struct tmiofb_par *par = info->par;
274 const struct resource *nlcr = &cell->resources[0]; 273 const struct resource *nlcr = &cell->resources[0];
@@ -312,8 +311,7 @@ static int tmiofb_hw_init(struct platform_device *dev)
312 */ 311 */
313static void tmiofb_hw_mode(struct platform_device *dev) 312static void tmiofb_hw_mode(struct platform_device *dev)
314{ 313{
315 struct mfd_cell *cell = dev->dev.platform_data; 314 struct tmio_fb_data *data = mfd_get_data(dev);
316 struct tmio_fb_data *data = cell->driver_data;
317 struct fb_info *info = platform_get_drvdata(dev); 315 struct fb_info *info = platform_get_drvdata(dev);
318 struct fb_videomode *mode = info->mode; 316 struct fb_videomode *mode = info->mode;
319 struct tmiofb_par *par = info->par; 317 struct tmiofb_par *par = info->par;
@@ -559,9 +557,8 @@ static int tmiofb_ioctl(struct fb_info *fbi,
559static struct fb_videomode * 557static struct fb_videomode *
560tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) 558tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
561{ 559{
562 struct mfd_cell *cell = 560 struct tmio_fb_data *data =
563 info->device->platform_data; 561 mfd_get_data(to_platform_device(info->device));
564 struct tmio_fb_data *data = cell->driver_data;
565 struct fb_videomode *best = NULL; 562 struct fb_videomode *best = NULL;
566 int i; 563 int i;
567 564
@@ -581,9 +578,8 @@ static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
581{ 578{
582 579
583 struct fb_videomode *mode; 580 struct fb_videomode *mode;
584 struct mfd_cell *cell = 581 struct tmio_fb_data *data =
585 info->device->platform_data; 582 mfd_get_data(to_platform_device(info->device));
586 struct tmio_fb_data *data = cell->driver_data;
587 583
588 mode = tmiofb_find_mode(info, var); 584 mode = tmiofb_find_mode(info, var);
589 if (!mode || var->bits_per_pixel > 16) 585 if (!mode || var->bits_per_pixel > 16)
@@ -683,8 +679,8 @@ static struct fb_ops tmiofb_ops = {
683 679
684static int __devinit tmiofb_probe(struct platform_device *dev) 680static int __devinit tmiofb_probe(struct platform_device *dev)
685{ 681{
686 struct mfd_cell *cell = dev->dev.platform_data; 682 const struct mfd_cell *cell = mfd_get_cell(dev);
687 struct tmio_fb_data *data = cell->driver_data; 683 struct tmio_fb_data *data = mfd_get_data(dev);
688 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1); 684 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
689 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0); 685 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
690 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2); 686 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
@@ -811,7 +807,7 @@ err_ioremap_ccr:
811 807
812static int __devexit tmiofb_remove(struct platform_device *dev) 808static int __devexit tmiofb_remove(struct platform_device *dev)
813{ 809{
814 struct mfd_cell *cell = dev->dev.platform_data; 810 const struct mfd_cell *cell = mfd_get_cell(dev);
815 struct fb_info *info = platform_get_drvdata(dev); 811 struct fb_info *info = platform_get_drvdata(dev);
816 int irq = platform_get_irq(dev, 0); 812 int irq = platform_get_irq(dev, 0);
817 struct tmiofb_par *par; 813 struct tmiofb_par *par;
@@ -941,7 +937,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
941#ifdef CONFIG_FB_TMIO_ACCELL 937#ifdef CONFIG_FB_TMIO_ACCELL
942 struct tmiofb_par *par = info->par; 938 struct tmiofb_par *par = info->par;
943#endif 939#endif
944 struct mfd_cell *cell = dev->dev.platform_data; 940 const struct mfd_cell *cell = mfd_get_cell(dev);
945 int retval = 0; 941 int retval = 0;
946 942
947 console_lock(); 943 console_lock();
@@ -973,7 +969,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
973static int tmiofb_resume(struct platform_device *dev) 969static int tmiofb_resume(struct platform_device *dev)
974{ 970{
975 struct fb_info *info = platform_get_drvdata(dev); 971 struct fb_info *info = platform_get_drvdata(dev);
976 struct mfd_cell *cell = dev->dev.platform_data; 972 const struct mfd_cell *cell = mfd_get_cell(dev);
977 int retval = 0; 973 int retval = 0;
978 974
979 console_lock(); 975 console_lock();
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 52ec0959d462..7f8472cc993b 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -73,7 +73,7 @@ static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *ns
73 struct uvesafb_task *utask; 73 struct uvesafb_task *utask;
74 struct uvesafb_ktask *task; 74 struct uvesafb_ktask *task;
75 75
76 if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) 76 if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
77 return; 77 return;
78 78
79 if (msg->seq >= UVESAFB_TASKS_MAX) 79 if (msg->seq >= UVESAFB_TASKS_MAX)
@@ -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/via/chip.h b/drivers/video/via/chip.h
index 48f1342897bd..781f3aa66b42 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -110,16 +110,13 @@
110struct tmds_chip_information { 110struct tmds_chip_information {
111 int tmds_chip_name; 111 int tmds_chip_name;
112 int tmds_chip_slave_addr; 112 int tmds_chip_slave_addr;
113 int data_mode;
114 int output_interface; 113 int output_interface;
115 int i2c_port; 114 int i2c_port;
116 int device_type;
117}; 115};
118 116
119struct lvds_chip_information { 117struct lvds_chip_information {
120 int lvds_chip_name; 118 int lvds_chip_name;
121 int lvds_chip_slave_addr; 119 int lvds_chip_slave_addr;
122 int data_mode;
123 int output_interface; 120 int output_interface;
124 int i2c_port; 121 int i2c_port;
125}; 122};
@@ -142,9 +139,6 @@ struct chip_information {
142 139
143struct crt_setting_information { 140struct crt_setting_information {
144 int iga_path; 141 int iga_path;
145 int h_active;
146 int v_active;
147 int bpp;
148 int refresh_rate; 142 int refresh_rate;
149}; 143};
150 144
@@ -162,8 +156,6 @@ struct lvds_setting_information {
162 int h_active; 156 int h_active;
163 int v_active; 157 int v_active;
164 int bpp; 158 int bpp;
165 int refresh_rate;
166 int lcd_panel_id;
167 int lcd_panel_hres; 159 int lcd_panel_hres;
168 int lcd_panel_vres; 160 int lcd_panel_vres;
169 int display_method; 161 int display_method;
@@ -188,7 +180,6 @@ struct GFX_DPA_SETTING {
188}; 180};
189 181
190struct VT1636_DPA_SETTING { 182struct VT1636_DPA_SETTING {
191 int PanelSizeID;
192 u8 CLK_SEL_ST1; 183 u8 CLK_SEL_ST1;
193 u8 CLK_SEL_ST2; 184 u8 CLK_SEL_ST2;
194}; 185};
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index 84e21b39dd0b..41ca198b5098 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -195,7 +195,9 @@ void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
195 struct crt_mode_table *pDviTiming; 195 struct crt_mode_table *pDviTiming;
196 unsigned long desirePixelClock, maxPixelClock; 196 unsigned long desirePixelClock, maxPixelClock;
197 pDviTiming = mode->crtc; 197 pDviTiming = mode->crtc;
198 desirePixelClock = pDviTiming->clk / 1000000; 198 desirePixelClock = pDviTiming->refresh_rate
199 * pDviTiming->crtc.hor_total * pDviTiming->crtc.ver_total
200 / 1000000;
199 maxPixelClock = (unsigned long)viaparinfo-> 201 maxPixelClock = (unsigned long)viaparinfo->
200 tmds_setting_info->max_pixel_clock; 202 tmds_setting_info->max_pixel_clock;
201 203
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 36d73f940d8b..5728fd76bc11 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -22,342 +22,290 @@
22#include <linux/via-core.h> 22#include <linux/via-core.h>
23#include "global.h" 23#include "global.h"
24 24
25static struct pll_map pll_value[] = { 25static struct pll_config cle266_pll_config[] = {
26 {25175000, 26 {19, 4, 0},
27 {99, 7, 3}, 27 {26, 5, 0},
28 {85, 3, 4}, /* ignoring bit difference: 0x00008000 */ 28 {28, 5, 0},
29 {141, 5, 4}, 29 {31, 5, 0},
30 {141, 5, 4} }, 30 {33, 5, 0},
31 {29581000, 31 {55, 5, 0},
32 {33, 4, 2}, 32 {102, 5, 0},
33 {66, 2, 4}, /* ignoring bit difference: 0x00808000 */ 33 {53, 6, 0},
34 {166, 5, 4}, /* ignoring bit difference: 0x00008000 */ 34 {92, 6, 0},
35 {165, 5, 4} }, 35 {98, 6, 0},
36 {26880000, 36 {112, 6, 0},
37 {15, 4, 1}, 37 {41, 7, 0},
38 {30, 2, 3}, /* ignoring bit difference: 0x00808000 */ 38 {60, 7, 0},
39 {150, 5, 4}, 39 {99, 7, 0},
40 {150, 5, 4} }, 40 {100, 7, 0},
41 {31500000, 41 {83, 8, 0},
42 {53, 3, 3}, /* ignoring bit difference: 0x00008000 */ 42 {86, 8, 0},
43 {141, 4, 4}, /* ignoring bit difference: 0x00008000 */ 43 {108, 8, 0},
44 {176, 5, 4}, 44 {87, 9, 0},
45 {176, 5, 4} }, 45 {118, 9, 0},
46 {31728000, 46 {95, 12, 0},
47 {31, 7, 1}, 47 {115, 12, 0},
48 {177, 5, 4}, /* ignoring bit difference: 0x00008000 */ 48 {108, 13, 0},
49 {177, 5, 4}, 49 {83, 17, 0},
50 {142, 4, 4} }, 50 {67, 20, 0},
51 {32688000, 51 {86, 20, 0},
52 {73, 4, 3}, 52 {98, 20, 0},
53 {146, 4, 4}, /* ignoring bit difference: 0x00008000 */ 53 {121, 24, 0},
54 {183, 5, 4}, 54 {99, 29, 0},
55 {146, 4, 4} }, 55 {33, 3, 1},
56 {36000000, 56 {15, 4, 1},
57 {101, 5, 3}, /* ignoring bit difference: 0x00008000 */ 57 {23, 4, 1},
58 {161, 4, 4}, /* ignoring bit difference: 0x00008000 */ 58 {37, 5, 1},
59 {202, 5, 4}, 59 {83, 5, 1},
60 {161, 4, 4} }, 60 {85, 5, 1},
61 {40000000, 61 {94, 5, 1},
62 {89, 4, 3}, 62 {103, 5, 1},
63 {89, 4, 3}, /* ignoring bit difference: 0x00008000 */ 63 {109, 5, 1},
64 {112, 5, 3}, 64 {113, 5, 1},
65 {112, 5, 3} }, 65 {121, 5, 1},
66 {41291000, 66 {82, 6, 1},
67 {23, 4, 1}, 67 {31, 7, 1},
68 {69, 3, 3}, /* ignoring bit difference: 0x00008000 */ 68 {55, 7, 1},
69 {115, 5, 3}, 69 {84, 7, 1},
70 {115, 5, 3} }, 70 {83, 8, 1},
71 {43163000, 71 {76, 9, 1},
72 {121, 5, 3}, 72 {127, 9, 1},
73 {121, 5, 3}, /* ignoring bit difference: 0x00008000 */ 73 {33, 4, 2},
74 {121, 5, 3}, 74 {75, 4, 2},
75 {121, 5, 3} }, 75 {119, 4, 2},
76 {45250000, 76 {121, 4, 2},
77 {127, 5, 3}, 77 {91, 5, 2},
78 {127, 5, 3}, /* ignoring bit difference: 0x00808000 */ 78 {118, 5, 2},
79 {127, 5, 3}, 79 {83, 6, 2},
80 {127, 5, 3} }, 80 {109, 6, 2},
81 {46000000, 81 {90, 7, 2},
82 {90, 7, 2}, 82 {93, 2, 3},
83 {103, 4, 3}, /* ignoring bit difference: 0x00008000 */ 83 {53, 3, 3},
84 {129, 5, 3}, 84 {73, 4, 3},
85 {103, 4, 3} }, 85 {89, 4, 3},
86 {46996000, 86 {105, 4, 3},
87 {105, 4, 3}, /* ignoring bit difference: 0x00008000 */ 87 {117, 4, 3},
88 {131, 5, 3}, /* ignoring bit difference: 0x00808000 */ 88 {101, 5, 3},
89 {131, 5, 3}, /* ignoring bit difference: 0x00808000 */ 89 {121, 5, 3},
90 {105, 4, 3} }, 90 {127, 5, 3},
91 {48000000, 91 {99, 7, 3}
92 {67, 20, 0}, 92};
93 {134, 5, 3}, /* ignoring bit difference: 0x00808000 */ 93
94 {134, 5, 3}, 94static struct pll_config k800_pll_config[] = {
95 {134, 5, 3} }, 95 {22, 2, 0},
96 {48875000, 96 {28, 3, 0},
97 {99, 29, 0}, 97 {81, 3, 1},
98 {82, 3, 3}, /* ignoring bit difference: 0x00808000 */ 98 {85, 3, 1},
99 {82, 3, 3}, /* ignoring bit difference: 0x00808000 */ 99 {98, 3, 1},
100 {137, 5, 3} }, 100 {112, 3, 1},
101 {49500000, 101 {86, 4, 1},
102 {83, 6, 2}, 102 {166, 4, 1},
103 {83, 3, 3}, /* ignoring bit difference: 0x00008000 */ 103 {109, 5, 1},
104 {138, 5, 3}, 104 {113, 5, 1},
105 {83, 3, 3} }, 105 {121, 5, 1},
106 {52406000, 106 {131, 5, 1},
107 {117, 4, 3}, 107 {143, 5, 1},
108 {117, 4, 3}, /* ignoring bit difference: 0x00008000 */ 108 {153, 5, 1},
109 {117, 4, 3}, 109 {66, 3, 2},
110 {88, 3, 3} }, 110 {68, 3, 2},
111 {52977000, 111 {95, 3, 2},
112 {37, 5, 1}, 112 {106, 3, 2},
113 {148, 5, 3}, /* ignoring bit difference: 0x00808000 */ 113 {116, 3, 2},
114 {148, 5, 3}, 114 {93, 4, 2},
115 {148, 5, 3} }, 115 {119, 4, 2},
116 {56250000, 116 {121, 4, 2},
117 {55, 7, 1}, /* ignoring bit difference: 0x00008000 */ 117 {133, 4, 2},
118 {126, 4, 3}, /* ignoring bit difference: 0x00008000 */ 118 {137, 4, 2},
119 {157, 5, 3}, 119 {117, 5, 2},
120 {157, 5, 3} }, 120 {118, 5, 2},
121 {57275000, 121 {120, 5, 2},
122 {0, 0, 0}, 122 {124, 5, 2},
123 {2, 2, 0}, 123 {132, 5, 2},
124 {2, 2, 0}, 124 {137, 5, 2},
125 {157, 5, 3} }, /* ignoring bit difference: 0x00808000 */ 125 {141, 5, 2},
126 {60466000, 126 {166, 5, 2},
127 {76, 9, 1}, 127 {170, 5, 2},
128 {169, 5, 3}, /* ignoring bit difference: 0x00808000 */ 128 {191, 5, 2},
129 {169, 5, 3}, /* FIXED: old = {72, 2, 3} */ 129 {206, 5, 2},
130 {169, 5, 3} }, 130 {208, 5, 2},
131 {61500000, 131 {30, 2, 3},
132 {86, 20, 0}, 132 {69, 3, 3},
133 {172, 5, 3}, /* ignoring bit difference: 0x00808000 */ 133 {82, 3, 3},
134 {172, 5, 3}, 134 {83, 3, 3},
135 {172, 5, 3} }, 135 {109, 3, 3},
136 {65000000, 136 {114, 3, 3},
137 {109, 6, 2}, /* ignoring bit difference: 0x00008000 */ 137 {125, 3, 3},
138 {109, 3, 3}, /* ignoring bit difference: 0x00008000 */ 138 {89, 4, 3},
139 {109, 3, 3}, 139 {103, 4, 3},
140 {109, 3, 3} }, 140 {117, 4, 3},
141 {65178000, 141 {126, 4, 3},
142 {91, 5, 2}, 142 {150, 4, 3},
143 {182, 5, 3}, /* ignoring bit difference: 0x00808000 */ 143 {161, 4, 3},
144 {109, 3, 3}, 144 {121, 5, 3},
145 {182, 5, 3} }, 145 {127, 5, 3},
146 {66750000, 146 {131, 5, 3},
147 {75, 4, 2}, 147 {134, 5, 3},
148 {150, 4, 3}, /* ignoring bit difference: 0x00808000 */ 148 {148, 5, 3},
149 {150, 4, 3}, 149 {169, 5, 3},
150 {112, 3, 3} }, 150 {172, 5, 3},
151 {68179000, 151 {182, 5, 3},
152 {19, 4, 0}, 152 {195, 5, 3},
153 {114, 3, 3}, /* ignoring bit difference: 0x00008000 */ 153 {196, 5, 3},
154 {190, 5, 3}, 154 {208, 5, 3},
155 {191, 5, 3} }, 155 {66, 2, 4},
156 {69924000, 156 {85, 3, 4},
157 {83, 17, 0}, 157 {141, 4, 4},
158 {195, 5, 3}, /* ignoring bit difference: 0x00808000 */ 158 {146, 4, 4},
159 {195, 5, 3}, 159 {161, 4, 4},
160 {195, 5, 3} }, 160 {177, 5, 4}
161 {70159000, 161};
162 {98, 20, 0}, 162
163 {196, 5, 3}, /* ignoring bit difference: 0x00808000 */ 163static struct pll_config cx700_pll_config[] = {
164 {196, 5, 3}, 164 {98, 3, 1},
165 {195, 5, 3} }, 165 {86, 4, 1},
166 {72000000, 166 {109, 5, 1},
167 {121, 24, 0}, 167 {110, 5, 1},
168 {161, 4, 3}, /* ignoring bit difference: 0x00808000 */ 168 {113, 5, 1},
169 {161, 4, 3}, 169 {121, 5, 1},
170 {161, 4, 3} }, 170 {131, 5, 1},
171 {78750000, 171 {135, 5, 1},
172 {33, 3, 1}, 172 {142, 5, 1},
173 {66, 3, 2}, /* ignoring bit difference: 0x00008000 */ 173 {143, 5, 1},
174 {110, 5, 2}, 174 {153, 5, 1},
175 {110, 5, 2} }, 175 {187, 5, 1},
176 {80136000, 176 {208, 5, 1},
177 {28, 5, 0}, 177 {68, 2, 2},
178 {68, 3, 2}, /* ignoring bit difference: 0x00008000 */ 178 {95, 3, 2},
179 {112, 5, 2}, 179 {116, 3, 2},
180 {112, 5, 2} }, 180 {93, 4, 2},
181 {83375000, 181 {119, 4, 2},
182 {93, 2, 3}, 182 {133, 4, 2},
183 {93, 4, 2}, /* ignoring bit difference: 0x00800000 */ 183 {137, 4, 2},
184 {93, 4, 2}, /* ignoring bit difference: 0x00800000 */ 184 {151, 4, 2},
185 {117, 5, 2} }, 185 {166, 4, 2},
186 {83950000, 186 {110, 5, 2},
187 {41, 7, 0}, 187 {112, 5, 2},
188 {117, 5, 2}, /* ignoring bit difference: 0x00008000 */ 188 {117, 5, 2},
189 {117, 5, 2}, 189 {118, 5, 2},
190 {117, 5, 2} }, 190 {120, 5, 2},
191 {84750000, 191 {132, 5, 2},
192 {118, 5, 2}, 192 {137, 5, 2},
193 {118, 5, 2}, /* ignoring bit difference: 0x00808000 */ 193 {141, 5, 2},
194 {118, 5, 2}, 194 {151, 5, 2},
195 {118, 5, 2} }, 195 {166, 5, 2},
196 {85860000, 196 {175, 5, 2},
197 {84, 7, 1}, 197 {191, 5, 2},
198 {120, 5, 2}, /* ignoring bit difference: 0x00808000 */ 198 {206, 5, 2},
199 {120, 5, 2}, 199 {174, 7, 2},
200 {118, 5, 2} }, 200 {82, 3, 3},
201 {88750000, 201 {109, 3, 3},
202 {31, 5, 0}, 202 {117, 4, 3},
203 {124, 5, 2}, /* ignoring bit difference: 0x00808000 */ 203 {150, 4, 3},
204 {174, 7, 2}, /* ignoring bit difference: 0x00808000 */ 204 {161, 4, 3},
205 {124, 5, 2} }, 205 {112, 5, 3},
206 {94500000, 206 {115, 5, 3},
207 {33, 5, 0}, 207 {121, 5, 3},
208 {132, 5, 2}, /* ignoring bit difference: 0x00008000 */ 208 {127, 5, 3},
209 {132, 5, 2}, 209 {129, 5, 3},
210 {132, 5, 2} }, 210 {131, 5, 3},
211 {97750000, 211 {134, 5, 3},
212 {82, 6, 1}, 212 {138, 5, 3},
213 {137, 5, 2}, /* ignoring bit difference: 0x00808000 */ 213 {148, 5, 3},
214 {137, 5, 2}, 214 {157, 5, 3},
215 {137, 5, 2} }, 215 {169, 5, 3},
216 {101000000, 216 {172, 5, 3},
217 {127, 9, 1}, 217 {190, 5, 3},
218 {141, 5, 2}, /* ignoring bit difference: 0x00808000 */ 218 {195, 5, 3},
219 {141, 5, 2}, 219 {196, 5, 3},
220 {141, 5, 2} }, 220 {208, 5, 3},
221 {106500000, 221 {141, 5, 4},
222 {119, 4, 2}, 222 {150, 5, 4},
223 {119, 4, 2}, /* ignoring bit difference: 0x00808000 */ 223 {166, 5, 4},
224 {119, 4, 2}, 224 {176, 5, 4},
225 {149, 5, 2} }, 225 {177, 5, 4},
226 {108000000, 226 {183, 5, 4},
227 {121, 4, 2}, 227 {202, 5, 4}
228 {121, 4, 2}, /* ignoring bit difference: 0x00808000 */ 228};
229 {151, 5, 2}, 229
230 {151, 5, 2} }, 230static struct pll_config vx855_pll_config[] = {
231 {113309000, 231 {86, 4, 1},
232 {95, 12, 0}, 232 {108, 5, 1},
233 {95, 3, 2}, /* ignoring bit difference: 0x00808000 */ 233 {110, 5, 1},
234 {95, 3, 2}, 234 {113, 5, 1},
235 {159, 5, 2} }, 235 {121, 5, 1},
236 {118840000, 236 {131, 5, 1},
237 {83, 5, 1}, 237 {135, 5, 1},
238 {166, 5, 2}, /* ignoring bit difference: 0x00808000 */ 238 {142, 5, 1},
239 {166, 5, 2}, 239 {143, 5, 1},
240 {166, 5, 2} }, 240 {153, 5, 1},
241 {119000000, 241 {164, 5, 1},
242 {108, 13, 0}, 242 {187, 5, 1},
243 {133, 4, 2}, /* ignoring bit difference: 0x00808000 */ 243 {208, 5, 1},
244 {133, 4, 2}, 244 {110, 5, 2},
245 {167, 5, 2} }, 245 {112, 5, 2},
246 {121750000, 246 {117, 5, 2},
247 {85, 5, 1}, 247 {118, 5, 2},
248 {170, 5, 2}, /* ignoring bit difference: 0x00808000 */ 248 {124, 5, 2},
249 {68, 2, 2}, 249 {132, 5, 2},
250 {0, 0, 0} }, 250 {137, 5, 2},
251 {125104000, 251 {141, 5, 2},
252 {53, 6, 0}, /* ignoring bit difference: 0x00008000 */ 252 {149, 5, 2},
253 {106, 3, 2}, /* ignoring bit difference: 0x00008000 */ 253 {151, 5, 2},
254 {175, 5, 2}, 254 {159, 5, 2},
255 {0, 0, 0} }, 255 {166, 5, 2},
256 {135000000, 256 {167, 5, 2},
257 {94, 5, 1}, 257 {172, 5, 2},
258 {28, 3, 0}, /* ignoring bit difference: 0x00804000 */ 258 {189, 5, 2},
259 {151, 4, 2}, 259 {191, 5, 2},
260 {189, 5, 2} }, 260 {194, 5, 2},
261 {136700000, 261 {206, 5, 2},
262 {115, 12, 0}, 262 {208, 5, 2},
263 {191, 5, 2}, /* ignoring bit difference: 0x00808000 */ 263 {83, 3, 3},
264 {191, 5, 2}, 264 {88, 3, 3},
265 {191, 5, 2} }, 265 {109, 3, 3},
266 {138400000, 266 {112, 3, 3},
267 {87, 9, 0}, 267 {103, 4, 3},
268 {116, 3, 2}, /* ignoring bit difference: 0x00808000 */ 268 {105, 4, 3},
269 {116, 3, 2}, 269 {161, 4, 3},
270 {194, 5, 2} }, 270 {112, 5, 3},
271 {146760000, 271 {115, 5, 3},
272 {103, 5, 1}, 272 {121, 5, 3},
273 {206, 5, 2}, /* ignoring bit difference: 0x00808000 */ 273 {127, 5, 3},
274 {206, 5, 2}, 274 {134, 5, 3},
275 {206, 5, 2} }, 275 {137, 5, 3},
276 {153920000, 276 {148, 5, 3},
277 {86, 8, 0}, 277 {157, 5, 3},
278 {86, 4, 1}, /* ignoring bit difference: 0x00808000 */ 278 {169, 5, 3},
279 {86, 4, 1}, 279 {172, 5, 3},
280 {86, 4, 1} }, /* FIXED: old = {84, 2, 1} */ 280 {182, 5, 3},
281 {156000000, 281 {191, 5, 3},
282 {109, 5, 1}, 282 {195, 5, 3},
283 {109, 5, 1}, /* ignoring bit difference: 0x00808000 */ 283 {209, 5, 3},
284 {109, 5, 1}, 284 {142, 4, 4},
285 {108, 5, 1} }, 285 {146, 4, 4},
286 {157500000, 286 {161, 4, 4},
287 {55, 5, 0}, /* ignoring bit difference: 0x00008000 */ 287 {141, 5, 4},
288 {22, 2, 0}, /* ignoring bit difference: 0x00802000 */ 288 {150, 5, 4},
289 {110, 5, 1}, 289 {165, 5, 4},
290 {110, 5, 1} }, 290 {176, 5, 4}
291 {162000000, 291};
292 {113, 5, 1}, 292
293 {113, 5, 1}, /* ignoring bit difference: 0x00808000 */ 293/* according to VIA Technologies these values are based on experiment */
294 {113, 5, 1}, 294static struct io_reg scaling_parameters[] = {
295 {113, 5, 1} }, 295 {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
296 {187000000, 296 {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
297 {118, 9, 0}, 297 {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
298 {131, 5, 1}, /* ignoring bit difference: 0x00808000 */ 298 {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
299 {131, 5, 1}, 299 {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
300 {131, 5, 1} }, 300 {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
301 {193295000, 301 {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
302 {108, 8, 0}, 302 {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
303 {81, 3, 1}, /* ignoring bit difference: 0x00808000 */ 303 {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
304 {135, 5, 1}, 304 {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
305 {135, 5, 1} }, 305 {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
306 {202500000, 306 {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
307 {99, 7, 0}, 307 {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
308 {85, 3, 1}, /* ignoring bit difference: 0x00808000 */ 308 {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
309 {142, 5, 1},
310 {142, 5, 1} },
311 {204000000,
312 {100, 7, 0},
313 {143, 5, 1}, /* ignoring bit difference: 0x00808000 */
314 {143, 5, 1},
315 {143, 5, 1} },
316 {218500000,
317 {92, 6, 0},
318 {153, 5, 1}, /* ignoring bit difference: 0x00808000 */
319 {153, 5, 1},
320 {153, 5, 1} },
321 {234000000,
322 {98, 6, 0},
323 {98, 3, 1}, /* ignoring bit difference: 0x00008000 */
324 {98, 3, 1},
325 {164, 5, 1} },
326 {267250000,
327 {112, 6, 0},
328 {112, 3, 1}, /* ignoring bit difference: 0x00808000 */
329 {187, 5, 1},
330 {187, 5, 1} },
331 {297500000,
332 {102, 5, 0}, /* ignoring bit difference: 0x00008000 */
333 {166, 4, 1}, /* ignoring bit difference: 0x00008000 */
334 {208, 5, 1},
335 {208, 5, 1} },
336 {74481000,
337 {26, 5, 0},
338 {125, 3, 3}, /* ignoring bit difference: 0x00808000 */
339 {208, 5, 3},
340 {209, 5, 3} },
341 {172798000,
342 {121, 5, 1},
343 {121, 5, 1}, /* ignoring bit difference: 0x00808000 */
344 {121, 5, 1},
345 {121, 5, 1} },
346 {122614000,
347 {60, 7, 0},
348 {137, 4, 2}, /* ignoring bit difference: 0x00808000 */
349 {137, 4, 2},
350 {172, 5, 2} },
351 {74270000,
352 {83, 8, 1},
353 {208, 5, 3},
354 {208, 5, 3},
355 {0, 0, 0} },
356 {148500000,
357 {83, 8, 0},
358 {208, 5, 2},
359 {166, 4, 2},
360 {208, 5, 2} }
361}; 309};
362 310
363static struct fifo_depth_select display_fifo_depth_reg = { 311static struct fifo_depth_select display_fifo_depth_reg = {
@@ -751,7 +699,7 @@ void viafb_unlock_crt(void)
751 viafb_write_reg_mask(CR47, VIACR, 0, BIT0); 699 viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
752} 700}
753 701
754void write_dac_reg(u8 index, u8 r, u8 g, u8 b) 702static void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
755{ 703{
756 outb(index, LUT_INDEX_WRITE); 704 outb(index, LUT_INDEX_WRITE);
757 outb(r, LUT_DATA); 705 outb(r, LUT_DATA);
@@ -1674,43 +1622,63 @@ static u32 vx855_encode_pll(struct pll_config pll)
1674 | pll.multiplier; 1622 | pll.multiplier;
1675} 1623}
1676 1624
1677u32 viafb_get_clk_value(int clk) 1625static inline u32 get_pll_internal_frequency(u32 ref_freq,
1626 struct pll_config pll)
1678{ 1627{
1679 u32 value = 0; 1628 return ref_freq / pll.divisor * pll.multiplier;
1680 int i = 0; 1629}
1681 1630
1682 while (i < NUM_TOTAL_PLL_TABLE && clk != pll_value[i].clk) 1631static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll)
1683 i++; 1632{
1633 return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift;
1634}
1684 1635
1685 if (i == NUM_TOTAL_PLL_TABLE) { 1636static struct pll_config get_pll_config(struct pll_config *config, int size,
1686 printk(KERN_WARNING "viafb_get_clk_value: PLL lookup failed!"); 1637 int clk)
1687 } else { 1638{
1688 switch (viaparinfo->chip_info->gfx_chip_name) { 1639 struct pll_config best = config[0];
1689 case UNICHROME_CLE266: 1640 const u32 f0 = 14318180; /* X1 frequency */
1690 case UNICHROME_K400: 1641 int i;
1691 value = cle266_encode_pll(pll_value[i].cle266_pll);
1692 break;
1693 1642
1694 case UNICHROME_K800: 1643 for (i = 1; i < size; i++) {
1695 case UNICHROME_PM800: 1644 if (abs(get_pll_output_frequency(f0, config[i]) - clk)
1696 case UNICHROME_CN700: 1645 < abs(get_pll_output_frequency(f0, best) - clk))
1697 value = k800_encode_pll(pll_value[i].k800_pll); 1646 best = config[i];
1698 break; 1647 }
1699 1648
1700 case UNICHROME_CX700: 1649 return best;
1701 case UNICHROME_CN750: 1650}
1702 case UNICHROME_K8M890:
1703 case UNICHROME_P4M890:
1704 case UNICHROME_P4M900:
1705 case UNICHROME_VX800:
1706 value = k800_encode_pll(pll_value[i].cx700_pll);
1707 break;
1708 1651
1709 case UNICHROME_VX855: 1652u32 viafb_get_clk_value(int clk)
1710 case UNICHROME_VX900: 1653{
1711 value = vx855_encode_pll(pll_value[i].vx855_pll); 1654 u32 value = 0;
1712 break; 1655
1713 } 1656 switch (viaparinfo->chip_info->gfx_chip_name) {
1657 case UNICHROME_CLE266:
1658 case UNICHROME_K400:
1659 value = cle266_encode_pll(get_pll_config(cle266_pll_config,
1660 ARRAY_SIZE(cle266_pll_config), clk));
1661 break;
1662 case UNICHROME_K800:
1663 case UNICHROME_PM800:
1664 case UNICHROME_CN700:
1665 value = k800_encode_pll(get_pll_config(k800_pll_config,
1666 ARRAY_SIZE(k800_pll_config), clk));
1667 break;
1668 case UNICHROME_CX700:
1669 case UNICHROME_CN750:
1670 case UNICHROME_K8M890:
1671 case UNICHROME_P4M890:
1672 case UNICHROME_P4M900:
1673 case UNICHROME_VX800:
1674 value = k800_encode_pll(get_pll_config(cx700_pll_config,
1675 ARRAY_SIZE(cx700_pll_config), clk));
1676 break;
1677 case UNICHROME_VX855:
1678 case UNICHROME_VX900:
1679 value = vx855_encode_pll(get_pll_config(vx855_pll_config,
1680 ARRAY_SIZE(vx855_pll_config), clk));
1681 break;
1714 } 1682 }
1715 1683
1716 return value; 1684 return value;
@@ -2034,7 +2002,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2034 int i; 2002 int i;
2035 int index = 0; 2003 int index = 0;
2036 int h_addr, v_addr; 2004 int h_addr, v_addr;
2037 u32 pll_D_N; 2005 u32 pll_D_N, clock;
2038 2006
2039 for (i = 0; i < video_mode->mode_array; i++) { 2007 for (i = 0; i < video_mode->mode_array; i++) {
2040 index = i; 2008 index = i;
@@ -2087,7 +2055,9 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2087 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) 2055 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
2088 viafb_load_FIFO_reg(set_iga, h_addr, v_addr); 2056 viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
2089 2057
2090 pll_D_N = viafb_get_clk_value(crt_table[index].clk); 2058 clock = crt_reg.hor_total * crt_reg.ver_total
2059 * crt_table[index].refresh_rate;
2060 pll_D_N = viafb_get_clk_value(clock);
2091 DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); 2061 DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
2092 viafb_set_vclock(pll_D_N, set_iga); 2062 viafb_set_vclock(pll_D_N, set_iga);
2093 2063
@@ -2117,9 +2087,6 @@ void viafb_update_device_setting(int hres, int vres,
2117 int bpp, int vmode_refresh, int flag) 2087 int bpp, int vmode_refresh, int flag)
2118{ 2088{
2119 if (flag == 0) { 2089 if (flag == 0) {
2120 viaparinfo->crt_setting_info->h_active = hres;
2121 viaparinfo->crt_setting_info->v_active = vres;
2122 viaparinfo->crt_setting_info->bpp = bpp;
2123 viaparinfo->crt_setting_info->refresh_rate = 2090 viaparinfo->crt_setting_info->refresh_rate =
2124 vmode_refresh; 2091 vmode_refresh;
2125 2092
@@ -2129,13 +2096,9 @@ void viafb_update_device_setting(int hres, int vres,
2129 viaparinfo->lvds_setting_info->h_active = hres; 2096 viaparinfo->lvds_setting_info->h_active = hres;
2130 viaparinfo->lvds_setting_info->v_active = vres; 2097 viaparinfo->lvds_setting_info->v_active = vres;
2131 viaparinfo->lvds_setting_info->bpp = bpp; 2098 viaparinfo->lvds_setting_info->bpp = bpp;
2132 viaparinfo->lvds_setting_info->refresh_rate =
2133 vmode_refresh;
2134 viaparinfo->lvds_setting_info2->h_active = hres; 2099 viaparinfo->lvds_setting_info2->h_active = hres;
2135 viaparinfo->lvds_setting_info2->v_active = vres; 2100 viaparinfo->lvds_setting_info2->v_active = vres;
2136 viaparinfo->lvds_setting_info2->bpp = bpp; 2101 viaparinfo->lvds_setting_info2->bpp = bpp;
2137 viaparinfo->lvds_setting_info2->refresh_rate =
2138 vmode_refresh;
2139 } else { 2102 } else {
2140 2103
2141 if (viaparinfo->tmds_setting_info->iga_path == IGA2) { 2104 if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
@@ -2147,15 +2110,11 @@ void viafb_update_device_setting(int hres, int vres,
2147 viaparinfo->lvds_setting_info->h_active = hres; 2110 viaparinfo->lvds_setting_info->h_active = hres;
2148 viaparinfo->lvds_setting_info->v_active = vres; 2111 viaparinfo->lvds_setting_info->v_active = vres;
2149 viaparinfo->lvds_setting_info->bpp = bpp; 2112 viaparinfo->lvds_setting_info->bpp = bpp;
2150 viaparinfo->lvds_setting_info->refresh_rate =
2151 vmode_refresh;
2152 } 2113 }
2153 if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) { 2114 if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
2154 viaparinfo->lvds_setting_info2->h_active = hres; 2115 viaparinfo->lvds_setting_info2->h_active = hres;
2155 viaparinfo->lvds_setting_info2->v_active = vres; 2116 viaparinfo->lvds_setting_info2->v_active = vres;
2156 viaparinfo->lvds_setting_info2->bpp = bpp; 2117 viaparinfo->lvds_setting_info2->bpp = bpp;
2157 viaparinfo->lvds_setting_info2->refresh_rate =
2158 vmode_refresh;
2159 } 2118 }
2160 } 2119 }
2161} 2120}
@@ -2430,6 +2389,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2430 break; 2389 break;
2431 } 2390 }
2432 2391
2392 viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
2433 device_off(); 2393 device_off();
2434 via_set_state(devices, VIA_STATE_OFF); 2394 via_set_state(devices, VIA_STATE_OFF);
2435 2395
@@ -2608,35 +2568,43 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2608int viafb_get_pixclock(int hres, int vres, int vmode_refresh) 2568int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
2609{ 2569{
2610 int i; 2570 int i;
2571 struct crt_mode_table *best;
2572 struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2573
2574 if (!vmode)
2575 return RES_640X480_60HZ_PIXCLOCK;
2611 2576
2612 for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) { 2577 best = &vmode->crtc[0];
2613 if ((hres == res_map_refresh_tbl[i].hres) 2578 for (i = 1; i < vmode->mode_array; i++) {
2614 && (vres == res_map_refresh_tbl[i].vres) 2579 if (abs(vmode->crtc[i].refresh_rate - vmode_refresh)
2615 && (vmode_refresh == res_map_refresh_tbl[i].vmode_refresh)) 2580 < abs(best->refresh_rate - vmode_refresh))
2616 return res_map_refresh_tbl[i].pixclock; 2581 best = &vmode->crtc[i];
2617 } 2582 }
2618 return RES_640X480_60HZ_PIXCLOCK;
2619 2583
2584 return 1000000000 / (best->crtc.hor_total * best->crtc.ver_total)
2585 * 1000 / best->refresh_rate;
2620} 2586}
2621 2587
2622int viafb_get_refresh(int hres, int vres, u32 long_refresh) 2588int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2623{ 2589{
2624#define REFRESH_TOLERANCE 3 2590 int i;
2625 int i, nearest = -1, diff = REFRESH_TOLERANCE; 2591 struct crt_mode_table *best;
2626 for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) { 2592 struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2627 if ((hres == res_map_refresh_tbl[i].hres) 2593
2628 && (vres == res_map_refresh_tbl[i].vres) 2594 if (!vmode)
2629 && (diff > (abs(long_refresh - 2595 return 60;
2630 res_map_refresh_tbl[i].vmode_refresh)))) { 2596
2631 diff = abs(long_refresh - res_map_refresh_tbl[i]. 2597 best = &vmode->crtc[0];
2632 vmode_refresh); 2598 for (i = 1; i < vmode->mode_array; i++) {
2633 nearest = i; 2599 if (abs(vmode->crtc[i].refresh_rate - long_refresh)
2634 } 2600 < abs(best->refresh_rate - long_refresh))
2601 best = &vmode->crtc[i];
2635 } 2602 }
2636#undef REFRESH_TOLERANCE 2603
2637 if (nearest > 0) 2604 if (abs(best->refresh_rate - long_refresh) > 3)
2638 return res_map_refresh_tbl[nearest].vmode_refresh; 2605 return 60;
2639 return 60; 2606
2607 return best->refresh_rate;
2640} 2608}
2641 2609
2642static void device_off(void) 2610static void device_off(void)
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 668d534542ef..7295263299f7 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -893,8 +893,6 @@ struct iga2_crtc_timing {
893/* VT3410 chipset*/ 893/* VT3410 chipset*/
894#define VX900_FUNCTION3 0x3410 894#define VX900_FUNCTION3 0x3410
895 895
896#define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value)
897
898struct IODATA { 896struct IODATA {
899 u8 Index; 897 u8 Index;
900 u8 Mask; 898 u8 Mask;
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 3425c3969806..64bc7e763103 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -26,10 +26,12 @@
26 26
27/* CLE266 Software Power Sequence */ 27/* CLE266 Software Power Sequence */
28/* {Mask}, {Data}, {Delay} */ 28/* {Mask}, {Data}, {Delay} */
29int PowerSequenceOn[3][3] = { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, 29static const int PowerSequenceOn[3][3] = {
30 {0x19, 0x1FE, 0x01} }; 30 {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01}
31int PowerSequenceOff[3][3] = { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, 31};
32 {0xD2, 0x19, 0x01} }; 32static const int PowerSequenceOff[3][3] = {
33 {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01}
34};
33 35
34static struct _lcd_scaling_factor lcd_scaling_factor = { 36static struct _lcd_scaling_factor lcd_scaling_factor = {
35 /* LCD Horizontal Scaling Factor Register */ 37 /* LCD Horizontal Scaling Factor Register */
@@ -95,8 +97,6 @@ void __devinit viafb_init_lcd_size(void)
95 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); 97 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
96 98
97 fp_id_to_vindex(viafb_lcd_panel_id); 99 fp_id_to_vindex(viafb_lcd_panel_id);
98 viaparinfo->lvds_setting_info2->lcd_panel_id =
99 viaparinfo->lvds_setting_info->lcd_panel_id;
100 viaparinfo->lvds_setting_info2->lcd_panel_hres = 100 viaparinfo->lvds_setting_info2->lcd_panel_hres =
101 viaparinfo->lvds_setting_info->lcd_panel_hres; 101 viaparinfo->lvds_setting_info->lcd_panel_hres;
102 viaparinfo->lvds_setting_info2->lcd_panel_vres = 102 viaparinfo->lvds_setting_info2->lcd_panel_vres =
@@ -203,176 +203,132 @@ static void __devinit fp_id_to_vindex(int panel_id)
203 case 0x0: 203 case 0x0:
204 viaparinfo->lvds_setting_info->lcd_panel_hres = 640; 204 viaparinfo->lvds_setting_info->lcd_panel_hres = 640;
205 viaparinfo->lvds_setting_info->lcd_panel_vres = 480; 205 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
206 viaparinfo->lvds_setting_info->lcd_panel_id =
207 LCD_PANEL_ID0_640X480;
208 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 206 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
209 viaparinfo->lvds_setting_info->LCDDithering = 1; 207 viaparinfo->lvds_setting_info->LCDDithering = 1;
210 break; 208 break;
211 case 0x1: 209 case 0x1:
212 viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 210 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
213 viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 211 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
214 viaparinfo->lvds_setting_info->lcd_panel_id =
215 LCD_PANEL_ID1_800X600;
216 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 212 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
217 viaparinfo->lvds_setting_info->LCDDithering = 1; 213 viaparinfo->lvds_setting_info->LCDDithering = 1;
218 break; 214 break;
219 case 0x2: 215 case 0x2:
220 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 216 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
221 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 217 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
222 viaparinfo->lvds_setting_info->lcd_panel_id =
223 LCD_PANEL_ID2_1024X768;
224 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 218 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
225 viaparinfo->lvds_setting_info->LCDDithering = 1; 219 viaparinfo->lvds_setting_info->LCDDithering = 1;
226 break; 220 break;
227 case 0x3: 221 case 0x3:
228 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 222 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
229 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 223 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
230 viaparinfo->lvds_setting_info->lcd_panel_id =
231 LCD_PANEL_ID3_1280X768;
232 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 224 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
233 viaparinfo->lvds_setting_info->LCDDithering = 1; 225 viaparinfo->lvds_setting_info->LCDDithering = 1;
234 break; 226 break;
235 case 0x4: 227 case 0x4:
236 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 228 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
237 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; 229 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
238 viaparinfo->lvds_setting_info->lcd_panel_id =
239 LCD_PANEL_ID4_1280X1024;
240 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 230 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
241 viaparinfo->lvds_setting_info->LCDDithering = 1; 231 viaparinfo->lvds_setting_info->LCDDithering = 1;
242 break; 232 break;
243 case 0x5: 233 case 0x5:
244 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; 234 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
245 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; 235 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
246 viaparinfo->lvds_setting_info->lcd_panel_id =
247 LCD_PANEL_ID5_1400X1050;
248 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 236 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
249 viaparinfo->lvds_setting_info->LCDDithering = 1; 237 viaparinfo->lvds_setting_info->LCDDithering = 1;
250 break; 238 break;
251 case 0x6: 239 case 0x6:
252 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; 240 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
253 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; 241 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
254 viaparinfo->lvds_setting_info->lcd_panel_id =
255 LCD_PANEL_ID6_1600X1200;
256 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 242 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
257 viaparinfo->lvds_setting_info->LCDDithering = 1; 243 viaparinfo->lvds_setting_info->LCDDithering = 1;
258 break; 244 break;
259 case 0x8: 245 case 0x8:
260 viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 246 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
261 viaparinfo->lvds_setting_info->lcd_panel_vres = 480; 247 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
262 viaparinfo->lvds_setting_info->lcd_panel_id =
263 LCD_PANEL_IDA_800X480;
264 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 248 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
265 viaparinfo->lvds_setting_info->LCDDithering = 1; 249 viaparinfo->lvds_setting_info->LCDDithering = 1;
266 break; 250 break;
267 case 0x9: 251 case 0x9:
268 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 252 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
269 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 253 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
270 viaparinfo->lvds_setting_info->lcd_panel_id =
271 LCD_PANEL_ID2_1024X768;
272 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 254 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
273 viaparinfo->lvds_setting_info->LCDDithering = 1; 255 viaparinfo->lvds_setting_info->LCDDithering = 1;
274 break; 256 break;
275 case 0xA: 257 case 0xA:
276 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 258 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
277 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 259 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
278 viaparinfo->lvds_setting_info->lcd_panel_id =
279 LCD_PANEL_ID2_1024X768;
280 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 260 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
281 viaparinfo->lvds_setting_info->LCDDithering = 0; 261 viaparinfo->lvds_setting_info->LCDDithering = 0;
282 break; 262 break;
283 case 0xB: 263 case 0xB:
284 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 264 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
285 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 265 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
286 viaparinfo->lvds_setting_info->lcd_panel_id =
287 LCD_PANEL_ID2_1024X768;
288 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 266 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
289 viaparinfo->lvds_setting_info->LCDDithering = 0; 267 viaparinfo->lvds_setting_info->LCDDithering = 0;
290 break; 268 break;
291 case 0xC: 269 case 0xC:
292 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 270 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
293 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 271 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
294 viaparinfo->lvds_setting_info->lcd_panel_id =
295 LCD_PANEL_ID3_1280X768;
296 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 272 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
297 viaparinfo->lvds_setting_info->LCDDithering = 0; 273 viaparinfo->lvds_setting_info->LCDDithering = 0;
298 break; 274 break;
299 case 0xD: 275 case 0xD:
300 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 276 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
301 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; 277 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
302 viaparinfo->lvds_setting_info->lcd_panel_id =
303 LCD_PANEL_ID4_1280X1024;
304 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 278 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
305 viaparinfo->lvds_setting_info->LCDDithering = 0; 279 viaparinfo->lvds_setting_info->LCDDithering = 0;
306 break; 280 break;
307 case 0xE: 281 case 0xE:
308 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; 282 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
309 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; 283 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
310 viaparinfo->lvds_setting_info->lcd_panel_id =
311 LCD_PANEL_ID5_1400X1050;
312 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 284 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
313 viaparinfo->lvds_setting_info->LCDDithering = 0; 285 viaparinfo->lvds_setting_info->LCDDithering = 0;
314 break; 286 break;
315 case 0xF: 287 case 0xF:
316 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; 288 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
317 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; 289 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
318 viaparinfo->lvds_setting_info->lcd_panel_id =
319 LCD_PANEL_ID6_1600X1200;
320 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 290 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
321 viaparinfo->lvds_setting_info->LCDDithering = 0; 291 viaparinfo->lvds_setting_info->LCDDithering = 0;
322 break; 292 break;
323 case 0x10: 293 case 0x10:
324 viaparinfo->lvds_setting_info->lcd_panel_hres = 1366; 294 viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
325 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 295 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
326 viaparinfo->lvds_setting_info->lcd_panel_id =
327 LCD_PANEL_ID7_1366X768;
328 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 296 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
329 viaparinfo->lvds_setting_info->LCDDithering = 0; 297 viaparinfo->lvds_setting_info->LCDDithering = 0;
330 break; 298 break;
331 case 0x11: 299 case 0x11:
332 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 300 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
333 viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 301 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
334 viaparinfo->lvds_setting_info->lcd_panel_id =
335 LCD_PANEL_ID8_1024X600;
336 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 302 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
337 viaparinfo->lvds_setting_info->LCDDithering = 1; 303 viaparinfo->lvds_setting_info->LCDDithering = 1;
338 break; 304 break;
339 case 0x12: 305 case 0x12:
340 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 306 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
341 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 307 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
342 viaparinfo->lvds_setting_info->lcd_panel_id =
343 LCD_PANEL_ID3_1280X768;
344 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 308 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
345 viaparinfo->lvds_setting_info->LCDDithering = 1; 309 viaparinfo->lvds_setting_info->LCDDithering = 1;
346 break; 310 break;
347 case 0x13: 311 case 0x13:
348 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 312 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
349 viaparinfo->lvds_setting_info->lcd_panel_vres = 800; 313 viaparinfo->lvds_setting_info->lcd_panel_vres = 800;
350 viaparinfo->lvds_setting_info->lcd_panel_id =
351 LCD_PANEL_ID9_1280X800;
352 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 314 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
353 viaparinfo->lvds_setting_info->LCDDithering = 1; 315 viaparinfo->lvds_setting_info->LCDDithering = 1;
354 break; 316 break;
355 case 0x14: 317 case 0x14:
356 viaparinfo->lvds_setting_info->lcd_panel_hres = 1360; 318 viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
357 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 319 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
358 viaparinfo->lvds_setting_info->lcd_panel_id =
359 LCD_PANEL_IDB_1360X768;
360 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 320 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
361 viaparinfo->lvds_setting_info->LCDDithering = 0; 321 viaparinfo->lvds_setting_info->LCDDithering = 0;
362 break; 322 break;
363 case 0x15: 323 case 0x15:
364 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 324 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
365 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 325 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
366 viaparinfo->lvds_setting_info->lcd_panel_id =
367 LCD_PANEL_ID3_1280X768;
368 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 326 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
369 viaparinfo->lvds_setting_info->LCDDithering = 0; 327 viaparinfo->lvds_setting_info->LCDDithering = 0;
370 break; 328 break;
371 case 0x16: 329 case 0x16:
372 viaparinfo->lvds_setting_info->lcd_panel_hres = 480; 330 viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
373 viaparinfo->lvds_setting_info->lcd_panel_vres = 640; 331 viaparinfo->lvds_setting_info->lcd_panel_vres = 640;
374 viaparinfo->lvds_setting_info->lcd_panel_id =
375 LCD_PANEL_IDC_480X640;
376 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 332 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
377 viaparinfo->lvds_setting_info->LCDDithering = 1; 333 viaparinfo->lvds_setting_info->LCDDithering = 1;
378 break; 334 break;
@@ -380,16 +336,12 @@ static void __devinit fp_id_to_vindex(int panel_id)
380 /* OLPC XO-1.5 panel */ 336 /* OLPC XO-1.5 panel */
381 viaparinfo->lvds_setting_info->lcd_panel_hres = 1200; 337 viaparinfo->lvds_setting_info->lcd_panel_hres = 1200;
382 viaparinfo->lvds_setting_info->lcd_panel_vres = 900; 338 viaparinfo->lvds_setting_info->lcd_panel_vres = 900;
383 viaparinfo->lvds_setting_info->lcd_panel_id =
384 LCD_PANEL_IDD_1200X900;
385 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 339 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
386 viaparinfo->lvds_setting_info->LCDDithering = 0; 340 viaparinfo->lvds_setting_info->LCDDithering = 0;
387 break; 341 break;
388 default: 342 default:
389 viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 343 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
390 viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 344 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
391 viaparinfo->lvds_setting_info->lcd_panel_id =
392 LCD_PANEL_ID1_800X600;
393 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 345 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
394 viaparinfo->lvds_setting_info->LCDDithering = 1; 346 viaparinfo->lvds_setting_info->LCDDithering = 1;
395 } 347 }
@@ -610,7 +562,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
610 int set_vres = plvds_setting_info->v_active; 562 int set_vres = plvds_setting_info->v_active;
611 int panel_hres = plvds_setting_info->lcd_panel_hres; 563 int panel_hres = plvds_setting_info->lcd_panel_hres;
612 int panel_vres = plvds_setting_info->lcd_panel_vres; 564 int panel_vres = plvds_setting_info->lcd_panel_vres;
613 u32 pll_D_N; 565 u32 pll_D_N, clock;
614 struct display_timing mode_crt_reg, panel_crt_reg; 566 struct display_timing mode_crt_reg, panel_crt_reg;
615 struct crt_mode_table *panel_crt_table = NULL; 567 struct crt_mode_table *panel_crt_table = NULL;
616 struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, 568 struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres,
@@ -625,7 +577,9 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
625 DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n"); 577 DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
626 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) 578 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
627 viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info); 579 viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
628 plvds_setting_info->vclk = panel_crt_table->clk; 580 clock = panel_crt_reg.hor_total * panel_crt_reg.ver_total
581 * panel_crt_table->refresh_rate;
582 plvds_setting_info->vclk = clock;
629 if (set_iga == IGA1) { 583 if (set_iga == IGA1) {
630 /* IGA1 doesn't have LCD scaling, so set it as centering. */ 584 /* IGA1 doesn't have LCD scaling, so set it as centering. */
631 viafb_load_crtc_timing(lcd_centering_timging 585 viafb_load_crtc_timing(lcd_centering_timging
@@ -660,7 +614,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
660 614
661 fill_lcd_format(); 615 fill_lcd_format();
662 616
663 pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk); 617 pll_D_N = viafb_get_clk_value(clock);
664 DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); 618 DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N);
665 viafb_set_vclock(pll_D_N, set_iga); 619 viafb_set_vclock(pll_D_N, set_iga);
666 lcd_patch_skew(plvds_setting_info, plvds_chip_info); 620 lcd_patch_skew(plvds_setting_info, plvds_chip_info);
@@ -1064,34 +1018,33 @@ static struct display_timing lcd_centering_timging(struct display_timing
1064 1018
1065bool viafb_lcd_get_mobile_state(bool *mobile) 1019bool viafb_lcd_get_mobile_state(bool *mobile)
1066{ 1020{
1067 unsigned char *romptr, *tableptr; 1021 unsigned char __iomem *romptr, *tableptr, *biosptr;
1068 u8 core_base; 1022 u8 core_base;
1069 unsigned char *biosptr;
1070 /* Rom address */ 1023 /* Rom address */
1071 u32 romaddr = 0x000C0000; 1024 const u32 romaddr = 0x000C0000;
1072 u16 start_pattern = 0; 1025 u16 start_pattern;
1073 1026
1074 biosptr = ioremap(romaddr, 0x10000); 1027 biosptr = ioremap(romaddr, 0x10000);
1028 start_pattern = readw(biosptr);
1075 1029
1076 memcpy(&start_pattern, biosptr, 2);
1077 /* Compare pattern */ 1030 /* Compare pattern */
1078 if (start_pattern == 0xAA55) { 1031 if (start_pattern == 0xAA55) {
1079 /* Get the start of Table */ 1032 /* Get the start of Table */
1080 /* 0x1B means BIOS offset position */ 1033 /* 0x1B means BIOS offset position */
1081 romptr = biosptr + 0x1B; 1034 romptr = biosptr + 0x1B;
1082 tableptr = biosptr + *((u16 *) romptr); 1035 tableptr = biosptr + readw(romptr);
1083 1036
1084 /* Get the start of biosver structure */ 1037 /* Get the start of biosver structure */
1085 /* 18 means BIOS version position. */ 1038 /* 18 means BIOS version position. */
1086 romptr = tableptr + 18; 1039 romptr = tableptr + 18;
1087 romptr = biosptr + *((u16 *) romptr); 1040 romptr = biosptr + readw(romptr);
1088 1041
1089 /* The offset should be 44, but the 1042 /* The offset should be 44, but the
1090 actual image is less three char. */ 1043 actual image is less three char. */
1091 /* pRom += 44; */ 1044 /* pRom += 44; */
1092 romptr += 41; 1045 romptr += 41;
1093 1046
1094 core_base = *romptr++; 1047 core_base = readb(romptr);
1095 1048
1096 if (core_base & 0x8) 1049 if (core_base & 0x8)
1097 *mobile = false; 1050 *mobile = false;
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 2cbe1031b421..4b7831f0d012 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -627,77 +627,6 @@
627#define M2048x1536_R60_HSP NEGATIVE 627#define M2048x1536_R60_HSP NEGATIVE
628#define M2048x1536_R60_VSP POSITIVE 628#define M2048x1536_R60_VSP POSITIVE
629 629
630/* define PLL index: */
631#define CLK_25_175M 25175000
632#define CLK_26_880M 26880000
633#define CLK_29_581M 29581000
634#define CLK_31_500M 31500000
635#define CLK_31_728M 31728000
636#define CLK_32_668M 32688000
637#define CLK_36_000M 36000000
638#define CLK_40_000M 40000000
639#define CLK_41_291M 41291000
640#define CLK_43_163M 43163000
641#define CLK_45_250M 45250000 /* 45.46MHz */
642#define CLK_46_000M 46000000
643#define CLK_46_996M 46996000
644#define CLK_48_000M 48000000
645#define CLK_48_875M 48875000
646#define CLK_49_500M 49500000
647#define CLK_52_406M 52406000
648#define CLK_52_977M 52977000
649#define CLK_56_250M 56250000
650#define CLK_57_275M 57275000
651#define CLK_60_466M 60466000
652#define CLK_61_500M 61500000
653#define CLK_65_000M 65000000
654#define CLK_65_178M 65178000
655#define CLK_66_750M 66750000 /* 67.116MHz */
656#define CLK_68_179M 68179000
657#define CLK_69_924M 69924000
658#define CLK_70_159M 70159000
659#define CLK_72_000M 72000000
660#define CLK_74_270M 74270000
661#define CLK_78_750M 78750000
662#define CLK_80_136M 80136000
663#define CLK_83_375M 83375000
664#define CLK_83_950M 83950000
665#define CLK_84_750M 84750000 /* 84.537Mhz */
666#define CLK_85_860M 85860000
667#define CLK_88_750M 88750000
668#define CLK_94_500M 94500000
669#define CLK_97_750M 97750000
670#define CLK_101_000M 101000000
671#define CLK_106_500M 106500000
672#define CLK_108_000M 108000000
673#define CLK_113_309M 113309000
674#define CLK_118_840M 118840000
675#define CLK_119_000M 119000000
676#define CLK_121_750M 121750000 /* 121.704MHz */
677#define CLK_125_104M 125104000
678#define CLK_135_000M 135000000
679#define CLK_136_700M 136700000
680#define CLK_138_400M 138400000
681#define CLK_146_760M 146760000
682#define CLK_148_500M 148500000
683
684#define CLK_153_920M 153920000
685#define CLK_156_000M 156000000
686#define CLK_157_500M 157500000
687#define CLK_162_000M 162000000
688#define CLK_187_000M 187000000
689#define CLK_193_295M 193295000
690#define CLK_202_500M 202500000
691#define CLK_204_000M 204000000
692#define CLK_218_500M 218500000
693#define CLK_234_000M 234000000
694#define CLK_267_250M 267250000
695#define CLK_297_500M 297500000
696#define CLK_74_481M 74481000
697#define CLK_172_798M 172798000
698#define CLK_122_614M 122614000
699
700
701/* Definition CRTC Timing Index */ 630/* Definition CRTC Timing Index */
702#define H_TOTAL_INDEX 0 631#define H_TOTAL_INDEX 0
703#define H_ADDR_INDEX 1 632#define H_ADDR_INDEX 1
@@ -722,76 +651,7 @@
722 651
723/* Definition Video Mode Pixel Clock (picoseconds) 652/* Definition Video Mode Pixel Clock (picoseconds)
724*/ 653*/
725#define RES_480X640_60HZ_PIXCLOCK 39722
726#define RES_640X480_60HZ_PIXCLOCK 39722 654#define RES_640X480_60HZ_PIXCLOCK 39722
727#define RES_640X480_75HZ_PIXCLOCK 31747
728#define RES_640X480_85HZ_PIXCLOCK 27777
729#define RES_640X480_100HZ_PIXCLOCK 23168
730#define RES_640X480_120HZ_PIXCLOCK 19081
731#define RES_720X480_60HZ_PIXCLOCK 37020
732#define RES_720X576_60HZ_PIXCLOCK 30611
733#define RES_800X600_60HZ_PIXCLOCK 25000
734#define RES_800X600_75HZ_PIXCLOCK 20203
735#define RES_800X600_85HZ_PIXCLOCK 17777
736#define RES_800X600_100HZ_PIXCLOCK 14667
737#define RES_800X600_120HZ_PIXCLOCK 11912
738#define RES_800X480_60HZ_PIXCLOCK 33805
739#define RES_848X480_60HZ_PIXCLOCK 31756
740#define RES_856X480_60HZ_PIXCLOCK 31518
741#define RES_1024X512_60HZ_PIXCLOCK 24218
742#define RES_1024X600_60HZ_PIXCLOCK 20460
743#define RES_1024X768_60HZ_PIXCLOCK 15385
744#define RES_1024X768_75HZ_PIXCLOCK 12699
745#define RES_1024X768_85HZ_PIXCLOCK 10582
746#define RES_1024X768_100HZ_PIXCLOCK 8825
747#define RES_1152X864_75HZ_PIXCLOCK 9259
748#define RES_1280X768_60HZ_PIXCLOCK 12480
749#define RES_1280X800_60HZ_PIXCLOCK 11994
750#define RES_1280X960_60HZ_PIXCLOCK 9259
751#define RES_1280X1024_60HZ_PIXCLOCK 9260
752#define RES_1280X1024_75HZ_PIXCLOCK 7408
753#define RES_1280X768_85HZ_PIXCLOCK 6349
754#define RES_1440X1050_60HZ_PIXCLOCK 7993
755#define RES_1600X1200_60HZ_PIXCLOCK 6172
756#define RES_1600X1200_75HZ_PIXCLOCK 4938
757#define RES_1280X720_60HZ_PIXCLOCK 13426
758#define RES_1200X900_60HZ_PIXCLOCK 17459
759#define RES_1920X1080_60HZ_PIXCLOCK 5787
760#define RES_1400X1050_60HZ_PIXCLOCK 8214
761#define RES_1400X1050_75HZ_PIXCLOCK 6410
762#define RES_1368X768_60HZ_PIXCLOCK 11647
763#define RES_960X600_60HZ_PIXCLOCK 22099
764#define RES_1000X600_60HZ_PIXCLOCK 20834
765#define RES_1024X576_60HZ_PIXCLOCK 21278
766#define RES_1088X612_60HZ_PIXCLOCK 18877
767#define RES_1152X720_60HZ_PIXCLOCK 14981
768#define RES_1200X720_60HZ_PIXCLOCK 14253
769#define RES_1280X600_60HZ_PIXCLOCK 16260
770#define RES_1280X720_50HZ_PIXCLOCK 16538
771#define RES_1280X768_50HZ_PIXCLOCK 15342
772#define RES_1366X768_50HZ_PIXCLOCK 14301
773#define RES_1366X768_60HZ_PIXCLOCK 11646
774#define RES_1360X768_60HZ_PIXCLOCK 11799
775#define RES_1440X900_60HZ_PIXCLOCK 9390
776#define RES_1440X900_75HZ_PIXCLOCK 7315
777#define RES_1600X900_60HZ_PIXCLOCK 8415
778#define RES_1600X1024_60HZ_PIXCLOCK 7315
779#define RES_1680X1050_60HZ_PIXCLOCK 6814
780#define RES_1680X1050_75HZ_PIXCLOCK 5348
781#define RES_1792X1344_60HZ_PIXCLOCK 4902
782#define RES_1856X1392_60HZ_PIXCLOCK 4577
783#define RES_1920X1200_60HZ_PIXCLOCK 5173
784#define RES_1920X1440_60HZ_PIXCLOCK 4274
785#define RES_1920X1440_75HZ_PIXCLOCK 3367
786#define RES_2048X1536_60HZ_PIXCLOCK 3742
787
788#define RES_1360X768_RB_60HZ_PIXCLOCK 13889
789#define RES_1400X1050_RB_60HZ_PIXCLOCK 9901
790#define RES_1440X900_RB_60HZ_PIXCLOCK 11268
791#define RES_1600X900_RB_60HZ_PIXCLOCK 10230
792#define RES_1680X1050_RB_60HZ_PIXCLOCK 8403
793#define RES_1920X1080_RB_60HZ_PIXCLOCK 7225
794#define RES_1920X1200_RB_60HZ_PIXCLOCK 6497
795 655
796/* LCD display method 656/* LCD display method
797*/ 657*/
@@ -822,7 +682,6 @@ struct display_timing {
822 682
823struct crt_mode_table { 683struct crt_mode_table {
824 int refresh_rate; 684 int refresh_rate;
825 unsigned long clk;
826 int h_sync_polarity; 685 int h_sync_polarity;
827 int v_sync_polarity; 686 int v_sync_polarity;
828 struct display_timing crtc; 687 struct display_timing crtc;
diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/via/tblDPASetting.c
index 0c4c8cc712f4..73bb554e7c1e 100644
--- a/drivers/video/via/tblDPASetting.c
+++ b/drivers/video/via/tblDPASetting.c
@@ -20,17 +20,6 @@
20 */ 20 */
21 21
22#include "global.h" 22#include "global.h"
23/* For VT3324: */
24struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[] = {
25 /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */
26 {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */
27 {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */
28 {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */
29 {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */
30 {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */
31 {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */
32 {LCD_PANEL_ID6_1600X1200, 0x0B, 0x03} /* For 1600x1200 */
33};
34 23
35struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = { 24struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = {
36/* ClkRange, DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, 25/* ClkRange, DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
@@ -57,18 +46,6 @@ struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = {
57 0x00}, 46 0x00},
58}; 47};
59 48
60/* For VT3327: */
61struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[] = {
62 /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */
63 {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */
64 {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */
65 {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */
66 {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */
67 {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */
68 {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */
69 {LCD_PANEL_ID6_1600X1200, 0x00, 0x00} /* For 1600x1200 */
70};
71
72struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[] = { 49struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[] = {
73/* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, 50/* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
74 DVP1Driving, DFPHigh, DFPLow */ 51 DVP1Driving, DFPHigh, DFPLow */
diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/via/tblDPASetting.h
index b065a83481d3..6db61519cb5d 100644
--- a/drivers/video/via/tblDPASetting.h
+++ b/drivers/video/via/tblDPASetting.h
@@ -38,9 +38,7 @@ enum DPA_RANGE {
38 DPA_CLK_RANGE_150M 38 DPA_CLK_RANGE_150M
39}; 39};
40 40
41extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[7];
42extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[6]; 41extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[6];
43extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[7];
44extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[]; 42extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[];
45extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[6]; 43extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[6];
46 44
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index 3844b558b7bd..78f1405dbab7 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -32,7 +32,7 @@
32 */ 32 */
33#define VIAFB_NUM_I2C 5 33#define VIAFB_NUM_I2C 5
34static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C]; 34static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C];
35struct viafb_dev *i2c_vdev; /* Passed in from core */ 35static struct viafb_dev *i2c_vdev; /* Passed in from core */
36 36
37static void via_i2c_setscl(void *data, int state) 37static void via_i2c_setscl(void *data, int state)
38{ 38{
@@ -209,7 +209,6 @@ static int create_i2c_bus(struct i2c_adapter *adapter,
209 sprintf(adapter->name, "viafb i2c io_port idx 0x%02x", 209 sprintf(adapter->name, "viafb i2c io_port idx 0x%02x",
210 adap_cfg->ioport_index); 210 adap_cfg->ioport_index);
211 adapter->owner = THIS_MODULE; 211 adapter->owner = THIS_MODULE;
212 adapter->id = 0x01FFFF;
213 adapter->class = I2C_CLASS_DDC; 212 adapter->class = I2C_CLASS_DDC;
214 adapter->algo_data = algo; 213 adapter->algo_data = algo;
215 if (pdev) 214 if (pdev)
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 4e66349e4366..f555b891cc72 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -43,11 +43,11 @@ static int viafb_second_size;
43static int viafb_accel = 1; 43static int viafb_accel = 1;
44 44
45/* Added for specifying active devices.*/ 45/* Added for specifying active devices.*/
46char *viafb_active_dev; 46static char *viafb_active_dev;
47 47
48/*Added for specify lcd output port*/ 48/*Added for specify lcd output port*/
49char *viafb_lcd_port = ""; 49static char *viafb_lcd_port = "";
50char *viafb_dvi_port = ""; 50static char *viafb_dvi_port = "";
51 51
52static void retrieve_device_setting(struct viafb_ioctl_setting 52static void retrieve_device_setting(struct viafb_ioctl_setting
53 *setting_info); 53 *setting_info);
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index d66f963e930e..137996dc547e 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -94,9 +94,6 @@ extern int viafb_LCD_ON;
94extern int viafb_DVI_ON; 94extern int viafb_DVI_ON;
95extern int viafb_hotplug; 95extern int viafb_hotplug;
96 96
97extern int strict_strtoul(const char *cp, unsigned int base,
98 unsigned long *res);
99
100u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information 97u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
101 *plvds_setting_info, struct lvds_chip_information 98 *plvds_setting_info, struct lvds_chip_information
102 *plvds_chip_info, u8 index); 99 *plvds_chip_info, u8 index);
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
index 2dbad3c0f679..8c5bc41ff6a4 100644
--- a/drivers/video/via/viamode.c
+++ b/drivers/video/via/viamode.c
@@ -21,72 +21,6 @@
21 21
22#include <linux/via-core.h> 22#include <linux/via-core.h>
23#include "global.h" 23#include "global.h"
24struct res_map_refresh res_map_refresh_tbl[] = {
25/*hres, vres, vclock, vmode_refresh*/
26 {480, 640, RES_480X640_60HZ_PIXCLOCK, 60},
27 {640, 480, RES_640X480_60HZ_PIXCLOCK, 60},
28 {640, 480, RES_640X480_75HZ_PIXCLOCK, 75},
29 {640, 480, RES_640X480_85HZ_PIXCLOCK, 85},
30 {640, 480, RES_640X480_100HZ_PIXCLOCK, 100},
31 {640, 480, RES_640X480_120HZ_PIXCLOCK, 120},
32 {720, 480, RES_720X480_60HZ_PIXCLOCK, 60},
33 {720, 576, RES_720X576_60HZ_PIXCLOCK, 60},
34 {800, 480, RES_800X480_60HZ_PIXCLOCK, 60},
35 {800, 600, RES_800X600_60HZ_PIXCLOCK, 60},
36 {800, 600, RES_800X600_75HZ_PIXCLOCK, 75},
37 {800, 600, RES_800X600_85HZ_PIXCLOCK, 85},
38 {800, 600, RES_800X600_100HZ_PIXCLOCK, 100},
39 {800, 600, RES_800X600_120HZ_PIXCLOCK, 120},
40 {848, 480, RES_848X480_60HZ_PIXCLOCK, 60},
41 {856, 480, RES_856X480_60HZ_PIXCLOCK, 60},
42 {1024, 512, RES_1024X512_60HZ_PIXCLOCK, 60},
43 {1024, 600, RES_1024X600_60HZ_PIXCLOCK, 60},
44 {1024, 768, RES_1024X768_60HZ_PIXCLOCK, 60},
45 {1024, 768, RES_1024X768_75HZ_PIXCLOCK, 75},
46 {1024, 768, RES_1024X768_85HZ_PIXCLOCK, 85},
47 {1024, 768, RES_1024X768_100HZ_PIXCLOCK, 100},
48/* {1152,864, RES_1152X864_70HZ_PIXCLOCK, 70},*/
49 {1152, 864, RES_1152X864_75HZ_PIXCLOCK, 75},
50 {1280, 768, RES_1280X768_60HZ_PIXCLOCK, 60},
51 {1280, 800, RES_1280X800_60HZ_PIXCLOCK, 60},
52 {1280, 960, RES_1280X960_60HZ_PIXCLOCK, 60},
53 {1280, 1024, RES_1280X1024_60HZ_PIXCLOCK, 60},
54 {1280, 1024, RES_1280X1024_75HZ_PIXCLOCK, 75},
55 {1280, 1024, RES_1280X768_85HZ_PIXCLOCK, 85},
56 {1440, 1050, RES_1440X1050_60HZ_PIXCLOCK, 60},
57 {1600, 1200, RES_1600X1200_60HZ_PIXCLOCK, 60},
58 {1600, 1200, RES_1600X1200_75HZ_PIXCLOCK, 75},
59 {1280, 720, RES_1280X720_60HZ_PIXCLOCK, 60},
60 {1920, 1080, RES_1920X1080_60HZ_PIXCLOCK, 60},
61 {1400, 1050, RES_1400X1050_60HZ_PIXCLOCK, 60},
62 {1400, 1050, RES_1400X1050_75HZ_PIXCLOCK, 75},
63 {1368, 768, RES_1368X768_60HZ_PIXCLOCK, 60},
64 {960, 600, RES_960X600_60HZ_PIXCLOCK, 60},
65 {1000, 600, RES_1000X600_60HZ_PIXCLOCK, 60},
66 {1024, 576, RES_1024X576_60HZ_PIXCLOCK, 60},
67 {1088, 612, RES_1088X612_60HZ_PIXCLOCK, 60},
68 {1152, 720, RES_1152X720_60HZ_PIXCLOCK, 60},
69 {1200, 720, RES_1200X720_60HZ_PIXCLOCK, 60},
70 {1200, 900, RES_1200X900_60HZ_PIXCLOCK, 60},
71 {1280, 600, RES_1280X600_60HZ_PIXCLOCK, 60},
72 {1280, 720, RES_1280X720_50HZ_PIXCLOCK, 50},
73 {1280, 768, RES_1280X768_50HZ_PIXCLOCK, 50},
74 {1360, 768, RES_1360X768_60HZ_PIXCLOCK, 60},
75 {1366, 768, RES_1366X768_50HZ_PIXCLOCK, 50},
76 {1366, 768, RES_1366X768_60HZ_PIXCLOCK, 60},
77 {1440, 900, RES_1440X900_60HZ_PIXCLOCK, 60},
78 {1440, 900, RES_1440X900_75HZ_PIXCLOCK, 75},
79 {1600, 900, RES_1600X900_60HZ_PIXCLOCK, 60},
80 {1600, 1024, RES_1600X1024_60HZ_PIXCLOCK, 60},
81 {1680, 1050, RES_1680X1050_60HZ_PIXCLOCK, 60},
82 {1680, 1050, RES_1680X1050_75HZ_PIXCLOCK, 75},
83 {1792, 1344, RES_1792X1344_60HZ_PIXCLOCK, 60},
84 {1856, 1392, RES_1856X1392_60HZ_PIXCLOCK, 60},
85 {1920, 1200, RES_1920X1200_60HZ_PIXCLOCK, 60},
86 {1920, 1440, RES_1920X1440_60HZ_PIXCLOCK, 60},
87 {1920, 1440, RES_1920X1440_75HZ_PIXCLOCK, 75},
88 {2048, 1536, RES_2048X1536_60HZ_PIXCLOCK, 60}
89};
90 24
91struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, 25struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
92{VIASR, SR15, 0x02, 0x02}, 26{VIASR, SR15, 0x02, 0x02},
@@ -108,20 +42,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
108{VIACR, CR6A, 0xFF, 0x40}, 42{VIACR, CR6A, 0xFF, 0x40},
109{VIACR, CR6B, 0xFF, 0x00}, 43{VIACR, CR6B, 0xFF, 0x00},
110{VIACR, CR6C, 0xFF, 0x00}, 44{VIACR, CR6C, 0xFF, 0x00},
111{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
112{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
113{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
114{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
115{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
116{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
117{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
118{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
119{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
120{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
121{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
122{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
123{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
124{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
125{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 45{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
126{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 46{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
127{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ 47{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
@@ -172,20 +92,6 @@ struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
172{VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */ 92{VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */
173{VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */ 93{VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */
174{VIACR, CR9F, 0x03, 0x00}, /* LCD scaling Factor */ 94{VIACR, CR9F, 0x03, 0x00}, /* LCD scaling Factor */
175{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
176{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
177{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
178{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
179{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
180{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
181{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
182{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
183{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
184{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
185{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
186{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
187{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
188{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
189{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 95{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
190{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 96{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
191{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ 97{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
@@ -229,20 +135,6 @@ struct io_reg KM400_ModeXregs[] = {
229 {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */ 135 {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */
230 {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ 136 {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */
231 {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */ 137 {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */
232 {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
233 {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
234 {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
235 {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
236 {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
237 {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
238 {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
239 {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
240 {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
241 {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
242 {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
243 {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
244 {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
245 {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
246 {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 138 {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
247 {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 139 {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
248 {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ 140 {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
@@ -283,20 +175,6 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
283{VIACR, CR6A, 0xFF, 0x40}, 175{VIACR, CR6A, 0xFF, 0x40},
284{VIACR, CR6B, 0xFF, 0x00}, 176{VIACR, CR6B, 0xFF, 0x00},
285{VIACR, CR6C, 0xFF, 0x00}, 177{VIACR, CR6C, 0xFF, 0x00},
286{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
287{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
288{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
289{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
290{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
291{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
292{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
293{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
294{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
295{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
296{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
297{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
298{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
299{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
300{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 178{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
301{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 179{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
302{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ 180{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
@@ -342,20 +220,6 @@ struct io_reg VX855_ModeXregs[] = {
342{VIACR, CR6A, 0xFD, 0x60}, 220{VIACR, CR6A, 0xFD, 0x60},
343{VIACR, CR6B, 0xFF, 0x00}, 221{VIACR, CR6B, 0xFF, 0x00},
344{VIACR, CR6C, 0xFF, 0x00}, 222{VIACR, CR6C, 0xFF, 0x00},
345{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
346{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
347{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
348{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
349{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
350{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
351{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
352{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
353{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
354{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
355{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
356{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
357{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
358{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
359{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 223{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
360{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 224{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
361{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ 225{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
@@ -390,21 +254,6 @@ struct io_reg CLE266_ModeXregs[] = { {VIASR, SR1E, 0xF0, 0x00},
390{VIAGR, GR20, 0xFF, 0x00}, 254{VIAGR, GR20, 0xFF, 0x00},
391{VIAGR, GR21, 0xFF, 0x00}, 255{VIAGR, GR21, 0xFF, 0x00},
392{VIAGR, GR22, 0xFF, 0x00}, 256{VIAGR, GR22, 0xFF, 0x00},
393 /* LCD Parameters */
394{VIACR, CR7A, 0xFF, 0x01}, /* LCD Parameter 1 */
395{VIACR, CR7B, 0xFF, 0x02}, /* LCD Parameter 2 */
396{VIACR, CR7C, 0xFF, 0x03}, /* LCD Parameter 3 */
397{VIACR, CR7D, 0xFF, 0x04}, /* LCD Parameter 4 */
398{VIACR, CR7E, 0xFF, 0x07}, /* LCD Parameter 5 */
399{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Parameter 6 */
400{VIACR, CR80, 0xFF, 0x0D}, /* LCD Parameter 7 */
401{VIACR, CR81, 0xFF, 0x13}, /* LCD Parameter 8 */
402{VIACR, CR82, 0xFF, 0x16}, /* LCD Parameter 9 */
403{VIACR, CR83, 0xFF, 0x19}, /* LCD Parameter 10 */
404{VIACR, CR84, 0xFF, 0x1C}, /* LCD Parameter 11 */
405{VIACR, CR85, 0xFF, 0x1D}, /* LCD Parameter 12 */
406{VIACR, CR86, 0xFF, 0x1E}, /* LCD Parameter 13 */
407{VIACR, CR87, 0xFF, 0x1F}, /* LCD Parameter 14 */
408 257
409}; 258};
410 259
@@ -443,328 +292,321 @@ struct VPITTable VPIT = {
443/********************/ 292/********************/
444 293
445/* 480x640 */ 294/* 480x640 */
446struct crt_mode_table CRTM480x640[] = { 295static struct crt_mode_table CRTM480x640[] = {
447 /* r_rate, vclk, hsp, vsp */ 296 /* r_rate, hsp, vsp */
448 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 297 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
449 {REFRESH_60, CLK_25_175M, M480X640_R60_HSP, M480X640_R60_VSP, 298 {REFRESH_60, M480X640_R60_HSP, M480X640_R60_VSP,
450 {624, 480, 480, 144, 504, 48, 663, 640, 640, 23, 641, 3} } /* GTF*/ 299 {624, 480, 480, 144, 504, 48, 663, 640, 640, 23, 641, 3} } /* GTF*/
451}; 300};
452 301
453/* 640x480*/ 302/* 640x480*/
454struct crt_mode_table CRTM640x480[] = { 303static struct crt_mode_table CRTM640x480[] = {
455 /*r_rate,vclk,hsp,vsp */ 304 /*r_rate,hsp,vsp */
456 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 305 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
457 {REFRESH_60, CLK_25_175M, M640X480_R60_HSP, M640X480_R60_VSP, 306 {REFRESH_60, M640X480_R60_HSP, M640X480_R60_VSP,
458 {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} }, 307 {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} },
459 {REFRESH_75, CLK_31_500M, M640X480_R75_HSP, M640X480_R75_VSP, 308 {REFRESH_75, M640X480_R75_HSP, M640X480_R75_VSP,
460 {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} }, 309 {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} },
461 {REFRESH_85, CLK_36_000M, M640X480_R85_HSP, M640X480_R85_VSP, 310 {REFRESH_85, M640X480_R85_HSP, M640X480_R85_VSP,
462 {832, 640, 640, 192, 696, 56, 509, 480, 480, 29, 481, 3} }, 311 {832, 640, 640, 192, 696, 56, 509, 480, 480, 29, 481, 3} },
463 {REFRESH_100, CLK_43_163M, M640X480_R100_HSP, M640X480_R100_VSP, 312 {REFRESH_100, M640X480_R100_HSP, M640X480_R100_VSP,
464 {848, 640, 640, 208, 680, 64, 509, 480, 480, 29, 481, 3} }, /*GTF*/ 313 {848, 640, 640, 208, 680, 64, 509, 480, 480, 29, 481, 3} }, /*GTF*/
465 {REFRESH_120, CLK_52_406M, M640X480_R120_HSP, 314 {REFRESH_120, M640X480_R120_HSP, M640X480_R120_VSP,
466 M640X480_R120_VSP, 315 {848, 640, 640, 208, 680, 64, 515, 480, 480, 35, 481, 3} } /*GTF*/
467 {848, 640, 640, 208, 680, 64, 515, 480, 480, 35, 481,
468 3} } /*GTF*/
469}; 316};
470 317
471/*720x480 (GTF)*/ 318/*720x480 (GTF)*/
472struct crt_mode_table CRTM720x480[] = { 319static struct crt_mode_table CRTM720x480[] = {
473 /*r_rate,vclk,hsp,vsp */ 320 /*r_rate,hsp,vsp */
474 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 321 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
475 {REFRESH_60, CLK_26_880M, M720X480_R60_HSP, M720X480_R60_VSP, 322 {REFRESH_60, M720X480_R60_HSP, M720X480_R60_VSP,
476 {896, 720, 720, 176, 736, 72, 497, 480, 480, 17, 481, 3} } 323 {896, 720, 720, 176, 736, 72, 497, 480, 480, 17, 481, 3} }
477 324
478}; 325};
479 326
480/*720x576 (GTF)*/ 327/*720x576 (GTF)*/
481struct crt_mode_table CRTM720x576[] = { 328static struct crt_mode_table CRTM720x576[] = {
482 /*r_rate,vclk,hsp,vsp */ 329 /*r_rate,hsp,vsp */
483 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 330 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
484 {REFRESH_60, CLK_32_668M, M720X576_R60_HSP, M720X576_R60_VSP, 331 {REFRESH_60, M720X576_R60_HSP, M720X576_R60_VSP,
485 {912, 720, 720, 192, 744, 72, 597, 576, 576, 21, 577, 3} } 332 {912, 720, 720, 192, 744, 72, 597, 576, 576, 21, 577, 3} }
486}; 333};
487 334
488/* 800x480 (CVT) */ 335/* 800x480 (CVT) */
489struct crt_mode_table CRTM800x480[] = { 336static struct crt_mode_table CRTM800x480[] = {
490 /* r_rate, vclk, hsp, vsp */ 337 /* r_rate, hsp, vsp */
491 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 338 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
492 {REFRESH_60, CLK_29_581M, M800X480_R60_HSP, M800X480_R60_VSP, 339 {REFRESH_60, M800X480_R60_HSP, M800X480_R60_VSP,
493 {992, 800, 800, 192, 824, 72, 500, 480, 480, 20, 483, 7} } 340 {992, 800, 800, 192, 824, 72, 500, 480, 480, 20, 483, 7} }
494}; 341};
495 342
496/* 800x600*/ 343/* 800x600*/
497struct crt_mode_table CRTM800x600[] = { 344static struct crt_mode_table CRTM800x600[] = {
498 /*r_rate,vclk,hsp,vsp */ 345 /*r_rate,hsp,vsp */
499 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 346 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
500 {REFRESH_60, CLK_40_000M, M800X600_R60_HSP, M800X600_R60_VSP, 347 {REFRESH_60, M800X600_R60_HSP, M800X600_R60_VSP,
501 {1056, 800, 800, 256, 840, 128, 628, 600, 600, 28, 601, 4} }, 348 {1056, 800, 800, 256, 840, 128, 628, 600, 600, 28, 601, 4} },
502 {REFRESH_75, CLK_49_500M, M800X600_R75_HSP, M800X600_R75_VSP, 349 {REFRESH_75, M800X600_R75_HSP, M800X600_R75_VSP,
503 {1056, 800, 800, 256, 816, 80, 625, 600, 600, 25, 601, 3} }, 350 {1056, 800, 800, 256, 816, 80, 625, 600, 600, 25, 601, 3} },
504 {REFRESH_85, CLK_56_250M, M800X600_R85_HSP, M800X600_R85_VSP, 351 {REFRESH_85, M800X600_R85_HSP, M800X600_R85_VSP,
505 {1048, 800, 800, 248, 832, 64, 631, 600, 600, 31, 601, 3} }, 352 {1048, 800, 800, 248, 832, 64, 631, 600, 600, 31, 601, 3} },
506 {REFRESH_100, CLK_68_179M, M800X600_R100_HSP, M800X600_R100_VSP, 353 {REFRESH_100, M800X600_R100_HSP, M800X600_R100_VSP,
507 {1072, 800, 800, 272, 848, 88, 636, 600, 600, 36, 601, 3} }, 354 {1072, 800, 800, 272, 848, 88, 636, 600, 600, 36, 601, 3} },
508 {REFRESH_120, CLK_83_950M, M800X600_R120_HSP, 355 {REFRESH_120, M800X600_R120_HSP, M800X600_R120_VSP,
509 M800X600_R120_VSP, 356 {1088, 800, 800, 288, 856, 88, 643, 600, 600, 43, 601, 3} }
510 {1088, 800, 800, 288, 856, 88, 643, 600, 600, 43, 601,
511 3} }
512}; 357};
513 358
514/* 848x480 (CVT) */ 359/* 848x480 (CVT) */
515struct crt_mode_table CRTM848x480[] = { 360static struct crt_mode_table CRTM848x480[] = {
516 /* r_rate, vclk, hsp, vsp */ 361 /* r_rate, hsp, vsp */
517 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 362 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
518 {REFRESH_60, CLK_31_500M, M848X480_R60_HSP, M848X480_R60_VSP, 363 {REFRESH_60, M848X480_R60_HSP, M848X480_R60_VSP,
519 {1056, 848, 848, 208, 872, 80, 500, 480, 480, 20, 483, 5} } 364 {1056, 848, 848, 208, 872, 80, 500, 480, 480, 20, 483, 5} }
520}; 365};
521 366
522/*856x480 (GTF) convert to 852x480*/ 367/*856x480 (GTF) convert to 852x480*/
523struct crt_mode_table CRTM852x480[] = { 368static struct crt_mode_table CRTM852x480[] = {
524 /*r_rate,vclk,hsp,vsp */ 369 /*r_rate,hsp,vsp */
525 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 370 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
526 {REFRESH_60, CLK_31_728M, M852X480_R60_HSP, M852X480_R60_VSP, 371 {REFRESH_60, M852X480_R60_HSP, M852X480_R60_VSP,
527 {1064, 856, 856, 208, 872, 88, 497, 480, 480, 17, 481, 3} } 372 {1064, 856, 856, 208, 872, 88, 497, 480, 480, 17, 481, 3} }
528}; 373};
529 374
530/*1024x512 (GTF)*/ 375/*1024x512 (GTF)*/
531struct crt_mode_table CRTM1024x512[] = { 376static struct crt_mode_table CRTM1024x512[] = {
532 /*r_rate,vclk,hsp,vsp */ 377 /*r_rate,hsp,vsp */
533 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 378 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
534 {REFRESH_60, CLK_41_291M, M1024X512_R60_HSP, M1024X512_R60_VSP, 379 {REFRESH_60, M1024X512_R60_HSP, M1024X512_R60_VSP,
535 {1296, 1024, 1024, 272, 1056, 104, 531, 512, 512, 19, 513, 3} } 380 {1296, 1024, 1024, 272, 1056, 104, 531, 512, 512, 19, 513, 3} }
536 381
537}; 382};
538 383
539/* 1024x600*/ 384/* 1024x600*/
540struct crt_mode_table CRTM1024x600[] = { 385static struct crt_mode_table CRTM1024x600[] = {
541 /*r_rate,vclk,hsp,vsp */ 386 /*r_rate,hsp,vsp */
542 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 387 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
543 {REFRESH_60, CLK_48_875M, M1024X600_R60_HSP, M1024X600_R60_VSP, 388 {REFRESH_60, M1024X600_R60_HSP, M1024X600_R60_VSP,
544 {1312, 1024, 1024, 288, 1064, 104, 622, 600, 600, 22, 601, 3} }, 389 {1312, 1024, 1024, 288, 1064, 104, 622, 600, 600, 22, 601, 3} },
545}; 390};
546 391
547/* 1024x768*/ 392/* 1024x768*/
548struct crt_mode_table CRTM1024x768[] = { 393static struct crt_mode_table CRTM1024x768[] = {
549 /*r_rate,vclk,hsp,vsp */ 394 /*r_rate,hsp,vsp */
550 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 395 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
551 {REFRESH_60, CLK_65_000M, M1024X768_R60_HSP, M1024X768_R60_VSP, 396 {REFRESH_60, M1024X768_R60_HSP, M1024X768_R60_VSP,
552 {1344, 1024, 1024, 320, 1048, 136, 806, 768, 768, 38, 771, 6} }, 397 {1344, 1024, 1024, 320, 1048, 136, 806, 768, 768, 38, 771, 6} },
553 {REFRESH_75, CLK_78_750M, M1024X768_R75_HSP, M1024X768_R75_VSP, 398 {REFRESH_75, M1024X768_R75_HSP, M1024X768_R75_VSP,
554 {1312, 1024, 1024, 288, 1040, 96, 800, 768, 768, 32, 769, 3} }, 399 {1312, 1024, 1024, 288, 1040, 96, 800, 768, 768, 32, 769, 3} },
555 {REFRESH_85, CLK_94_500M, M1024X768_R85_HSP, M1024X768_R85_VSP, 400 {REFRESH_85, M1024X768_R85_HSP, M1024X768_R85_VSP,
556 {1376, 1024, 1024, 352, 1072, 96, 808, 768, 768, 40, 769, 3} }, 401 {1376, 1024, 1024, 352, 1072, 96, 808, 768, 768, 40, 769, 3} },
557 {REFRESH_100, CLK_113_309M, M1024X768_R100_HSP, M1024X768_R100_VSP, 402 {REFRESH_100, M1024X768_R100_HSP, M1024X768_R100_VSP,
558 {1392, 1024, 1024, 368, 1096, 112, 814, 768, 768, 46, 769, 3} } 403 {1392, 1024, 1024, 368, 1096, 112, 814, 768, 768, 46, 769, 3} }
559}; 404};
560 405
561/* 1152x864*/ 406/* 1152x864*/
562struct crt_mode_table CRTM1152x864[] = { 407static struct crt_mode_table CRTM1152x864[] = {
563 /*r_rate,vclk,hsp,vsp */ 408 /*r_rate,hsp,vsp */
564 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 409 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
565 {REFRESH_75, CLK_108_000M, M1152X864_R75_HSP, M1152X864_R75_VSP, 410 {REFRESH_75, M1152X864_R75_HSP, M1152X864_R75_VSP,
566 {1600, 1152, 1152, 448, 1216, 128, 900, 864, 864, 36, 865, 3} } 411 {1600, 1152, 1152, 448, 1216, 128, 900, 864, 864, 36, 865, 3} }
567 412
568}; 413};
569 414
570/* 1280x720 (HDMI 720P)*/ 415/* 1280x720 (HDMI 720P)*/
571struct crt_mode_table CRTM1280x720[] = { 416static struct crt_mode_table CRTM1280x720[] = {
572 /*r_rate,vclk,hsp,vsp */ 417 /*r_rate,hsp,vsp */
573 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 418 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
574 {REFRESH_60, CLK_74_481M, M1280X720_R60_HSP, M1280X720_R60_VSP, 419 {REFRESH_60, M1280X720_R60_HSP, M1280X720_R60_VSP,
575 {1648, 1280, 1280, 368, 1392, 40, 750, 720, 720, 30, 725, 5} }, 420 {1648, 1280, 1280, 368, 1392, 40, 750, 720, 720, 30, 725, 5} },
576 {REFRESH_50, CLK_60_466M, M1280X720_R50_HSP, M1280X720_R50_VSP, 421 {REFRESH_50, M1280X720_R50_HSP, M1280X720_R50_VSP,
577 {1632, 1280, 1280, 352, 1328, 128, 741, 720, 720, 21, 721, 3} } 422 {1632, 1280, 1280, 352, 1328, 128, 741, 720, 720, 21, 721, 3} }
578}; 423};
579 424
580/*1280x768 (GTF)*/ 425/*1280x768 (GTF)*/
581struct crt_mode_table CRTM1280x768[] = { 426static struct crt_mode_table CRTM1280x768[] = {
582 /*r_rate,vclk,hsp,vsp */ 427 /*r_rate,hsp,vsp */
583 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 428 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
584 {REFRESH_60, CLK_80_136M, M1280X768_R60_HSP, M1280X768_R60_VSP, 429 {REFRESH_60, M1280X768_R60_HSP, M1280X768_R60_VSP,
585 {1680, 1280, 1280, 400, 1344, 136, 795, 768, 768, 27, 769, 3} }, 430 {1680, 1280, 1280, 400, 1344, 136, 795, 768, 768, 27, 769, 3} },
586 {REFRESH_50, CLK_65_178M, M1280X768_R50_HSP, M1280X768_R50_VSP, 431 {REFRESH_50, M1280X768_R50_HSP, M1280X768_R50_VSP,
587 {1648, 1280, 1280, 368, 1336, 128, 791, 768, 768, 23, 769, 3} } 432 {1648, 1280, 1280, 368, 1336, 128, 791, 768, 768, 23, 769, 3} }
588}; 433};
589 434
590/* 1280x800 (CVT) */ 435/* 1280x800 (CVT) */
591struct crt_mode_table CRTM1280x800[] = { 436static struct crt_mode_table CRTM1280x800[] = {
592 /* r_rate, vclk, hsp, vsp */ 437 /* r_rate, hsp, vsp */
593 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 438 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
594 {REFRESH_60, CLK_83_375M, M1280X800_R60_HSP, M1280X800_R60_VSP, 439 {REFRESH_60, M1280X800_R60_HSP, M1280X800_R60_VSP,
595 {1680, 1280, 1280, 400, 1352, 128, 831, 800, 800, 31, 803, 6} } 440 {1680, 1280, 1280, 400, 1352, 128, 831, 800, 800, 31, 803, 6} }
596}; 441};
597 442
598/*1280x960*/ 443/*1280x960*/
599struct crt_mode_table CRTM1280x960[] = { 444static struct crt_mode_table CRTM1280x960[] = {
600 /*r_rate,vclk,hsp,vsp */ 445 /*r_rate,hsp,vsp */
601 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 446 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
602 {REFRESH_60, CLK_108_000M, M1280X960_R60_HSP, M1280X960_R60_VSP, 447 {REFRESH_60, M1280X960_R60_HSP, M1280X960_R60_VSP,
603 {1800, 1280, 1280, 520, 1376, 112, 1000, 960, 960, 40, 961, 3} } 448 {1800, 1280, 1280, 520, 1376, 112, 1000, 960, 960, 40, 961, 3} }
604}; 449};
605 450
606/* 1280x1024*/ 451/* 1280x1024*/
607struct crt_mode_table CRTM1280x1024[] = { 452static struct crt_mode_table CRTM1280x1024[] = {
608 /*r_rate,vclk,,hsp,vsp */ 453 /*r_rate,hsp,vsp */
609 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 454 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
610 {REFRESH_60, CLK_108_000M, M1280X1024_R60_HSP, M1280X1024_R60_VSP, 455 {REFRESH_60, M1280X1024_R60_HSP, M1280X1024_R60_VSP,
611 {1688, 1280, 1280, 408, 1328, 112, 1066, 1024, 1024, 42, 1025, 456 {1688, 1280, 1280, 408, 1328, 112, 1066, 1024, 1024, 42, 1025,
612 3} }, 457 3} },
613 {REFRESH_75, CLK_135_000M, M1280X1024_R75_HSP, M1280X1024_R75_VSP, 458 {REFRESH_75, M1280X1024_R75_HSP, M1280X1024_R75_VSP,
614 {1688, 1280, 1280, 408, 1296, 144, 1066, 1024, 1024, 42, 1025, 459 {1688, 1280, 1280, 408, 1296, 144, 1066, 1024, 1024, 42, 1025,
615 3} }, 460 3} },
616 {REFRESH_85, CLK_157_500M, M1280X1024_R85_HSP, M1280X1024_R85_VSP, 461 {REFRESH_85, M1280X1024_R85_HSP, M1280X1024_R85_VSP,
617 {1728, 1280, 1280, 448, 1344, 160, 1072, 1024, 1024, 48, 1025, 3} } 462 {1728, 1280, 1280, 448, 1344, 160, 1072, 1024, 1024, 48, 1025, 3} }
618}; 463};
619 464
620/* 1368x768 (GTF) */ 465/* 1368x768 (GTF) */
621struct crt_mode_table CRTM1368x768[] = { 466static struct crt_mode_table CRTM1368x768[] = {
622 /* r_rate, vclk, hsp, vsp */ 467 /* r_rate, hsp, vsp */
623 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 468 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
624 {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP, 469 {REFRESH_60, M1368X768_R60_HSP, M1368X768_R60_VSP,
625 {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} } 470 {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} }
626}; 471};
627 472
628/*1440x1050 (GTF)*/ 473/*1440x1050 (GTF)*/
629struct crt_mode_table CRTM1440x1050[] = { 474static struct crt_mode_table CRTM1440x1050[] = {
630 /*r_rate,vclk,hsp,vsp */ 475 /*r_rate,hsp,vsp */
631 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 476 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
632 {REFRESH_60, CLK_125_104M, M1440X1050_R60_HSP, M1440X1050_R60_VSP, 477 {REFRESH_60, M1440X1050_R60_HSP, M1440X1050_R60_VSP,
633 {1936, 1440, 1440, 496, 1536, 152, 1077, 1040, 1040, 37, 1041, 3} } 478 {1936, 1440, 1440, 496, 1536, 152, 1077, 1040, 1040, 37, 1041, 3} }
634}; 479};
635 480
636/* 1600x1200*/ 481/* 1600x1200*/
637struct crt_mode_table CRTM1600x1200[] = { 482static struct crt_mode_table CRTM1600x1200[] = {
638 /*r_rate,vclk,hsp,vsp */ 483 /*r_rate,hsp,vsp */
639 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 484 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
640 {REFRESH_60, CLK_162_000M, M1600X1200_R60_HSP, M1600X1200_R60_VSP, 485 {REFRESH_60, M1600X1200_R60_HSP, M1600X1200_R60_VSP,
641 {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, 486 {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201,
642 3} }, 487 3} },
643 {REFRESH_75, CLK_202_500M, M1600X1200_R75_HSP, M1600X1200_R75_VSP, 488 {REFRESH_75, M1600X1200_R75_HSP, M1600X1200_R75_VSP,
644 {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, 3} } 489 {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, 3} }
645 490
646}; 491};
647 492
648/* 1680x1050 (CVT) */ 493/* 1680x1050 (CVT) */
649struct crt_mode_table CRTM1680x1050[] = { 494static struct crt_mode_table CRTM1680x1050[] = {
650 /* r_rate, vclk, hsp, vsp */ 495 /* r_rate, hsp, vsp */
651 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 496 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
652 {REFRESH_60, CLK_146_760M, M1680x1050_R60_HSP, M1680x1050_R60_VSP, 497 {REFRESH_60, M1680x1050_R60_HSP, M1680x1050_R60_VSP,
653 {2240, 1680, 1680, 560, 1784, 176, 1089, 1050, 1050, 39, 1053, 498 {2240, 1680, 1680, 560, 1784, 176, 1089, 1050, 1050, 39, 1053,
654 6} }, 499 6} },
655 {REFRESH_75, CLK_187_000M, M1680x1050_R75_HSP, M1680x1050_R75_VSP, 500 {REFRESH_75, M1680x1050_R75_HSP, M1680x1050_R75_VSP,
656 {2272, 1680, 1680, 592, 1800, 176, 1099, 1050, 1050, 49, 1053, 6} } 501 {2272, 1680, 1680, 592, 1800, 176, 1099, 1050, 1050, 49, 1053, 6} }
657}; 502};
658 503
659/* 1680x1050 (CVT Reduce Blanking) */ 504/* 1680x1050 (CVT Reduce Blanking) */
660struct crt_mode_table CRTM1680x1050_RB[] = { 505static struct crt_mode_table CRTM1680x1050_RB[] = {
661 /* r_rate, vclk, hsp, vsp */ 506 /* r_rate, hsp, vsp */
662 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 507 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
663 {REFRESH_60, CLK_119_000M, M1680x1050_RB_R60_HSP, 508 {REFRESH_60, M1680x1050_RB_R60_HSP, M1680x1050_RB_R60_VSP,
664 M1680x1050_RB_R60_VSP,
665 {1840, 1680, 1680, 160, 1728, 32, 1080, 1050, 1050, 30, 1053, 6} } 509 {1840, 1680, 1680, 160, 1728, 32, 1080, 1050, 1050, 30, 1053, 6} }
666}; 510};
667 511
668/* 1920x1080 (CVT)*/ 512/* 1920x1080 (CVT)*/
669struct crt_mode_table CRTM1920x1080[] = { 513static struct crt_mode_table CRTM1920x1080[] = {
670 /*r_rate,vclk,hsp,vsp */ 514 /*r_rate,hsp,vsp */
671 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 515 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
672 {REFRESH_60, CLK_172_798M, M1920X1080_R60_HSP, M1920X1080_R60_VSP, 516 {REFRESH_60, M1920X1080_R60_HSP, M1920X1080_R60_VSP,
673 {2576, 1920, 1920, 656, 2048, 200, 1120, 1080, 1080, 40, 1083, 5} } 517 {2576, 1920, 1920, 656, 2048, 200, 1120, 1080, 1080, 40, 1083, 5} }
674}; 518};
675 519
676/* 1920x1080 (CVT with Reduce Blanking) */ 520/* 1920x1080 (CVT with Reduce Blanking) */
677struct crt_mode_table CRTM1920x1080_RB[] = { 521static struct crt_mode_table CRTM1920x1080_RB[] = {
678 /* r_rate, vclk, hsp, vsp */ 522 /* r_rate, hsp, vsp */
679 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 523 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
680 {REFRESH_60, CLK_138_400M, M1920X1080_RB_R60_HSP, 524 {REFRESH_60, M1920X1080_RB_R60_HSP, M1920X1080_RB_R60_VSP,
681 M1920X1080_RB_R60_VSP,
682 {2080, 1920, 1920, 160, 1968, 32, 1111, 1080, 1080, 31, 1083, 5} } 525 {2080, 1920, 1920, 160, 1968, 32, 1111, 1080, 1080, 31, 1083, 5} }
683}; 526};
684 527
685/* 1920x1440*/ 528/* 1920x1440*/
686struct crt_mode_table CRTM1920x1440[] = { 529static struct crt_mode_table CRTM1920x1440[] = {
687 /*r_rate,vclk,hsp,vsp */ 530 /*r_rate,hsp,vsp */
688 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 531 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
689 {REFRESH_60, CLK_234_000M, M1920X1440_R60_HSP, M1920X1440_R60_VSP, 532 {REFRESH_60, M1920X1440_R60_HSP, M1920X1440_R60_VSP,
690 {2600, 1920, 1920, 680, 2048, 208, 1500, 1440, 1440, 60, 1441, 533 {2600, 1920, 1920, 680, 2048, 208, 1500, 1440, 1440, 60, 1441,
691 3} }, 534 3} },
692 {REFRESH_75, CLK_297_500M, M1920X1440_R75_HSP, M1920X1440_R75_VSP, 535 {REFRESH_75, M1920X1440_R75_HSP, M1920X1440_R75_VSP,
693 {2640, 1920, 1920, 720, 2064, 224, 1500, 1440, 1440, 60, 1441, 3} } 536 {2640, 1920, 1920, 720, 2064, 224, 1500, 1440, 1440, 60, 1441, 3} }
694}; 537};
695 538
696/* 1400x1050 (CVT) */ 539/* 1400x1050 (CVT) */
697struct crt_mode_table CRTM1400x1050[] = { 540static struct crt_mode_table CRTM1400x1050[] = {
698 /* r_rate, vclk, hsp, vsp */ 541 /* r_rate, hsp, vsp */
699 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 542 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
700 {REFRESH_60, CLK_121_750M, M1400X1050_R60_HSP, M1400X1050_R60_VSP, 543 {REFRESH_60, M1400X1050_R60_HSP, M1400X1050_R60_VSP,
701 {1864, 1400, 1400, 464, 1488, 144, 1089, 1050, 1050, 39, 1053, 544 {1864, 1400, 1400, 464, 1488, 144, 1089, 1050, 1050, 39, 1053,
702 4} }, 545 4} },
703 {REFRESH_75, CLK_156_000M, M1400X1050_R75_HSP, M1400X1050_R75_VSP, 546 {REFRESH_75, M1400X1050_R75_HSP, M1400X1050_R75_VSP,
704 {1896, 1400, 1400, 496, 1504, 144, 1099, 1050, 1050, 49, 1053, 4} } 547 {1896, 1400, 1400, 496, 1504, 144, 1099, 1050, 1050, 49, 1053, 4} }
705}; 548};
706 549
707/* 1400x1050 (CVT Reduce Blanking) */ 550/* 1400x1050 (CVT Reduce Blanking) */
708struct crt_mode_table CRTM1400x1050_RB[] = { 551static struct crt_mode_table CRTM1400x1050_RB[] = {
709 /* r_rate, vclk, hsp, vsp */ 552 /* r_rate, hsp, vsp */
710 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 553 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
711 {REFRESH_60, CLK_101_000M, M1400X1050_RB_R60_HSP, 554 {REFRESH_60, M1400X1050_RB_R60_HSP, M1400X1050_RB_R60_VSP,
712 M1400X1050_RB_R60_VSP,
713 {1560, 1400, 1400, 160, 1448, 32, 1080, 1050, 1050, 30, 1053, 4} } 555 {1560, 1400, 1400, 160, 1448, 32, 1080, 1050, 1050, 30, 1053, 4} }
714}; 556};
715 557
716/* 960x600 (CVT) */ 558/* 960x600 (CVT) */
717struct crt_mode_table CRTM960x600[] = { 559static struct crt_mode_table CRTM960x600[] = {
718 /* r_rate, vclk, hsp, vsp */ 560 /* r_rate, hsp, vsp */
719 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 561 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
720 {REFRESH_60, CLK_45_250M, M960X600_R60_HSP, M960X600_R60_VSP, 562 {REFRESH_60, M960X600_R60_HSP, M960X600_R60_VSP,
721 {1216, 960, 960, 256, 992, 96, 624, 600, 600, 24, 603, 6} } 563 {1216, 960, 960, 256, 992, 96, 624, 600, 600, 24, 603, 6} }
722}; 564};
723 565
724/* 1000x600 (GTF) */ 566/* 1000x600 (GTF) */
725struct crt_mode_table CRTM1000x600[] = { 567static struct crt_mode_table CRTM1000x600[] = {
726 /* r_rate, vclk, hsp, vsp */ 568 /* r_rate, hsp, vsp */
727 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 569 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
728 {REFRESH_60, CLK_48_000M, M1000X600_R60_HSP, M1000X600_R60_VSP, 570 {REFRESH_60, M1000X600_R60_HSP, M1000X600_R60_VSP,
729 {1288, 1000, 1000, 288, 1040, 104, 622, 600, 600, 22, 601, 3} } 571 {1288, 1000, 1000, 288, 1040, 104, 622, 600, 600, 22, 601, 3} }
730}; 572};
731 573
732/* 1024x576 (GTF) */ 574/* 1024x576 (GTF) */
733struct crt_mode_table CRTM1024x576[] = { 575static struct crt_mode_table CRTM1024x576[] = {
734 /* r_rate, vclk, hsp, vsp */ 576 /* r_rate, hsp, vsp */
735 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 577 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
736 {REFRESH_60, CLK_46_996M, M1024X576_R60_HSP, M1024X576_R60_VSP, 578 {REFRESH_60, M1024X576_R60_HSP, M1024X576_R60_VSP,
737 {1312, 1024, 1024, 288, 1064, 104, 597, 576, 576, 21, 577, 3} } 579 {1312, 1024, 1024, 288, 1064, 104, 597, 576, 576, 21, 577, 3} }
738}; 580};
739 581
740/* 1088x612 (CVT) */ 582/* 1088x612 (CVT) */
741struct crt_mode_table CRTM1088x612[] = { 583static struct crt_mode_table CRTM1088x612[] = {
742 /* r_rate, vclk, hsp, vsp */ 584 /* r_rate, hsp, vsp */
743 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 585 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
744 {REFRESH_60, CLK_52_977M, M1088X612_R60_HSP, M1088X612_R60_VSP, 586 {REFRESH_60, M1088X612_R60_HSP, M1088X612_R60_VSP,
745 {1392, 1088, 1088, 304, 1136, 104, 636, 612, 612, 24, 615, 5} } 587 {1392, 1088, 1088, 304, 1136, 104, 636, 612, 612, 24, 615, 5} }
746}; 588};
747 589
748/* 1152x720 (CVT) */ 590/* 1152x720 (CVT) */
749struct crt_mode_table CRTM1152x720[] = { 591static struct crt_mode_table CRTM1152x720[] = {
750 /* r_rate, vclk, hsp, vsp */ 592 /* r_rate, hsp, vsp */
751 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 593 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
752 {REFRESH_60, CLK_66_750M, M1152X720_R60_HSP, M1152X720_R60_VSP, 594 {REFRESH_60, M1152X720_R60_HSP, M1152X720_R60_VSP,
753 {1488, 1152, 1152, 336, 1208, 112, 748, 720, 720, 28, 723, 6} } 595 {1488, 1152, 1152, 336, 1208, 112, 748, 720, 720, 28, 723, 6} }
754}; 596};
755 597
756/* 1200x720 (GTF) */ 598/* 1200x720 (GTF) */
757struct crt_mode_table CRTM1200x720[] = { 599static struct crt_mode_table CRTM1200x720[] = {
758 /* r_rate, vclk, hsp, vsp */ 600 /* r_rate, hsp, vsp */
759 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 601 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
760 {REFRESH_60, CLK_70_159M, M1200X720_R60_HSP, M1200X720_R60_VSP, 602 {REFRESH_60, M1200X720_R60_HSP, M1200X720_R60_VSP,
761 {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} } 603 {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} }
762}; 604};
763 605
764/* 1200x900 (DCON) */ 606/* 1200x900 (DCON) */
765struct crt_mode_table DCON1200x900[] = { 607static struct crt_mode_table DCON1200x900[] = {
766 /* r_rate, vclk, hsp, vsp */ 608 /* r_rate, hsp, vsp */
767 {REFRESH_60, CLK_57_275M, M1200X900_R60_HSP, M1200X900_R60_VSP, 609 {REFRESH_60, M1200X900_R60_HSP, M1200X900_R60_VSP,
768 /* The correct htotal is 1240, but this doesn't raster on VX855. */ 610 /* The correct htotal is 1240, but this doesn't raster on VX855. */
769 /* Via suggested changing to a multiple of 16, hence 1264. */ 611 /* Via suggested changing to a multiple of 16, hence 1264. */
770 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 612 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
@@ -772,126 +614,122 @@ struct crt_mode_table DCON1200x900[] = {
772}; 614};
773 615
774/* 1280x600 (GTF) */ 616/* 1280x600 (GTF) */
775struct crt_mode_table CRTM1280x600[] = { 617static struct crt_mode_table CRTM1280x600[] = {
776 /* r_rate, vclk, hsp, vsp */ 618 /* r_rate, hsp, vsp */
777 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 619 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
778 {REFRESH_60, CLK_61_500M, M1280x600_R60_HSP, M1280x600_R60_VSP, 620 {REFRESH_60, M1280x600_R60_HSP, M1280x600_R60_VSP,
779 {1648, 1280, 1280, 368, 1336, 128, 622, 600, 600, 22, 601, 3} } 621 {1648, 1280, 1280, 368, 1336, 128, 622, 600, 600, 22, 601, 3} }
780}; 622};
781 623
782/* 1360x768 (CVT) */ 624/* 1360x768 (CVT) */
783struct crt_mode_table CRTM1360x768[] = { 625static struct crt_mode_table CRTM1360x768[] = {
784 /* r_rate, vclk, hsp, vsp */ 626 /* r_rate, hsp, vsp */
785 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 627 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
786 {REFRESH_60, CLK_84_750M, M1360X768_R60_HSP, M1360X768_R60_VSP, 628 {REFRESH_60, M1360X768_R60_HSP, M1360X768_R60_VSP,
787 {1776, 1360, 1360, 416, 1432, 136, 798, 768, 768, 30, 771, 5} } 629 {1776, 1360, 1360, 416, 1432, 136, 798, 768, 768, 30, 771, 5} }
788}; 630};
789 631
790/* 1360x768 (CVT Reduce Blanking) */ 632/* 1360x768 (CVT Reduce Blanking) */
791struct crt_mode_table CRTM1360x768_RB[] = { 633static struct crt_mode_table CRTM1360x768_RB[] = {
792 /* r_rate, vclk, hsp, vsp */ 634 /* r_rate, hsp, vsp */
793 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 635 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
794 {REFRESH_60, CLK_72_000M, M1360X768_RB_R60_HSP, 636 {REFRESH_60, M1360X768_RB_R60_HSP, M1360X768_RB_R60_VSP,
795 M1360X768_RB_R60_VSP,
796 {1520, 1360, 1360, 160, 1408, 32, 790, 768, 768, 22, 771, 5} } 637 {1520, 1360, 1360, 160, 1408, 32, 790, 768, 768, 22, 771, 5} }
797}; 638};
798 639
799/* 1366x768 (GTF) */ 640/* 1366x768 (GTF) */
800struct crt_mode_table CRTM1366x768[] = { 641static struct crt_mode_table CRTM1366x768[] = {
801 /* r_rate, vclk, hsp, vsp */ 642 /* r_rate, hsp, vsp */
802 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 643 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
803 {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP, 644 {REFRESH_60, M1368X768_R60_HSP, M1368X768_R60_VSP,
804 {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} }, 645 {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} },
805 {REFRESH_50, CLK_69_924M, M1368X768_R50_HSP, M1368X768_R50_VSP, 646 {REFRESH_50, M1368X768_R50_HSP, M1368X768_R50_VSP,
806 {1768, 1368, 1368, 400, 1424, 144, 791, 768, 768, 23, 769, 3} } 647 {1768, 1368, 1368, 400, 1424, 144, 791, 768, 768, 23, 769, 3} }
807}; 648};
808 649
809/* 1440x900 (CVT) */ 650/* 1440x900 (CVT) */
810struct crt_mode_table CRTM1440x900[] = { 651static struct crt_mode_table CRTM1440x900[] = {
811 /* r_rate, vclk, hsp, vsp */ 652 /* r_rate, hsp, vsp */
812 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 653 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
813 {REFRESH_60, CLK_106_500M, M1440X900_R60_HSP, M1440X900_R60_VSP, 654 {REFRESH_60, M1440X900_R60_HSP, M1440X900_R60_VSP,
814 {1904, 1440, 1440, 464, 1520, 152, 934, 900, 900, 34, 903, 6} }, 655 {1904, 1440, 1440, 464, 1520, 152, 934, 900, 900, 34, 903, 6} },
815 {REFRESH_75, CLK_136_700M, M1440X900_R75_HSP, M1440X900_R75_VSP, 656 {REFRESH_75, M1440X900_R75_HSP, M1440X900_R75_VSP,
816 {1936, 1440, 1440, 496, 1536, 152, 942, 900, 900, 42, 903, 6} } 657 {1936, 1440, 1440, 496, 1536, 152, 942, 900, 900, 42, 903, 6} }
817}; 658};
818 659
819/* 1440x900 (CVT Reduce Blanking) */ 660/* 1440x900 (CVT Reduce Blanking) */
820struct crt_mode_table CRTM1440x900_RB[] = { 661static struct crt_mode_table CRTM1440x900_RB[] = {
821 /* r_rate, vclk, hsp, vsp */ 662 /* r_rate, hsp, vsp */
822 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 663 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
823 {REFRESH_60, CLK_88_750M, M1440X900_RB_R60_HSP, 664 {REFRESH_60, M1440X900_RB_R60_HSP, M1440X900_RB_R60_VSP,
824 M1440X900_RB_R60_VSP,
825 {1600, 1440, 1440, 160, 1488, 32, 926, 900, 900, 26, 903, 6} } 665 {1600, 1440, 1440, 160, 1488, 32, 926, 900, 900, 26, 903, 6} }
826}; 666};
827 667
828/* 1600x900 (CVT) */ 668/* 1600x900 (CVT) */
829struct crt_mode_table CRTM1600x900[] = { 669static struct crt_mode_table CRTM1600x900[] = {
830 /* r_rate, vclk, hsp, vsp */ 670 /* r_rate, hsp, vsp */
831 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 671 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
832 {REFRESH_60, CLK_118_840M, M1600X900_R60_HSP, M1600X900_R60_VSP, 672 {REFRESH_60, M1600X900_R60_HSP, M1600X900_R60_VSP,
833 {2112, 1600, 1600, 512, 1688, 168, 934, 900, 900, 34, 903, 5} } 673 {2112, 1600, 1600, 512, 1688, 168, 934, 900, 900, 34, 903, 5} }
834}; 674};
835 675
836/* 1600x900 (CVT Reduce Blanking) */ 676/* 1600x900 (CVT Reduce Blanking) */
837struct crt_mode_table CRTM1600x900_RB[] = { 677static struct crt_mode_table CRTM1600x900_RB[] = {
838 /* r_rate, vclk, hsp, vsp */ 678 /* r_rate, hsp, vsp */
839 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 679 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
840 {REFRESH_60, CLK_97_750M, M1600X900_RB_R60_HSP, 680 {REFRESH_60, M1600X900_RB_R60_HSP, M1600X900_RB_R60_VSP,
841 M1600X900_RB_R60_VSP,
842 {1760, 1600, 1600, 160, 1648, 32, 926, 900, 900, 26, 903, 5} } 681 {1760, 1600, 1600, 160, 1648, 32, 926, 900, 900, 26, 903, 5} }
843}; 682};
844 683
845/* 1600x1024 (GTF) */ 684/* 1600x1024 (GTF) */
846struct crt_mode_table CRTM1600x1024[] = { 685static struct crt_mode_table CRTM1600x1024[] = {
847 /* r_rate, vclk, hsp, vsp */ 686 /* r_rate, hsp, vsp */
848 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 687 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
849 {REFRESH_60, CLK_136_700M, M1600X1024_R60_HSP, M1600X1024_R60_VSP, 688 {REFRESH_60, M1600X1024_R60_HSP, M1600X1024_R60_VSP,
850 {2144, 1600, 1600, 544, 1704, 168, 1060, 1024, 1024, 36, 1025, 3} } 689 {2144, 1600, 1600, 544, 1704, 168, 1060, 1024, 1024, 36, 1025, 3} }
851}; 690};
852 691
853/* 1792x1344 (DMT) */ 692/* 1792x1344 (DMT) */
854struct crt_mode_table CRTM1792x1344[] = { 693static struct crt_mode_table CRTM1792x1344[] = {
855 /* r_rate, vclk, hsp, vsp */ 694 /* r_rate, hsp, vsp */
856 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 695 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
857 {REFRESH_60, CLK_204_000M, M1792x1344_R60_HSP, M1792x1344_R60_VSP, 696 {REFRESH_60, M1792x1344_R60_HSP, M1792x1344_R60_VSP,
858 {2448, 1792, 1792, 656, 1920, 200, 1394, 1344, 1344, 50, 1345, 3} } 697 {2448, 1792, 1792, 656, 1920, 200, 1394, 1344, 1344, 50, 1345, 3} }
859}; 698};
860 699
861/* 1856x1392 (DMT) */ 700/* 1856x1392 (DMT) */
862struct crt_mode_table CRTM1856x1392[] = { 701static struct crt_mode_table CRTM1856x1392[] = {
863 /* r_rate, vclk, hsp, vsp */ 702 /* r_rate, hsp, vsp */
864 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 703 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
865 {REFRESH_60, CLK_218_500M, M1856x1392_R60_HSP, M1856x1392_R60_VSP, 704 {REFRESH_60, M1856x1392_R60_HSP, M1856x1392_R60_VSP,
866 {2528, 1856, 1856, 672, 1952, 224, 1439, 1392, 1392, 47, 1393, 3} } 705 {2528, 1856, 1856, 672, 1952, 224, 1439, 1392, 1392, 47, 1393, 3} }
867}; 706};
868 707
869/* 1920x1200 (CVT) */ 708/* 1920x1200 (CVT) */
870struct crt_mode_table CRTM1920x1200[] = { 709static struct crt_mode_table CRTM1920x1200[] = {
871 /* r_rate, vclk, hsp, vsp */ 710 /* r_rate, hsp, vsp */
872 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 711 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
873 {REFRESH_60, CLK_193_295M, M1920X1200_R60_HSP, M1920X1200_R60_VSP, 712 {REFRESH_60, M1920X1200_R60_HSP, M1920X1200_R60_VSP,
874 {2592, 1920, 1920, 672, 2056, 200, 1245, 1200, 1200, 45, 1203, 6} } 713 {2592, 1920, 1920, 672, 2056, 200, 1245, 1200, 1200, 45, 1203, 6} }
875}; 714};
876 715
877/* 1920x1200 (CVT with Reduce Blanking) */ 716/* 1920x1200 (CVT with Reduce Blanking) */
878struct crt_mode_table CRTM1920x1200_RB[] = { 717static struct crt_mode_table CRTM1920x1200_RB[] = {
879 /* r_rate, vclk, hsp, vsp */ 718 /* r_rate, hsp, vsp */
880 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 719 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
881 {REFRESH_60, CLK_153_920M, M1920X1200_RB_R60_HSP, 720 {REFRESH_60, M1920X1200_RB_R60_HSP, M1920X1200_RB_R60_VSP,
882 M1920X1200_RB_R60_VSP,
883 {2080, 1920, 1920, 160, 1968, 32, 1235, 1200, 1200, 35, 1203, 6} } 721 {2080, 1920, 1920, 160, 1968, 32, 1235, 1200, 1200, 35, 1203, 6} }
884}; 722};
885 723
886/* 2048x1536 (CVT) */ 724/* 2048x1536 (CVT) */
887struct crt_mode_table CRTM2048x1536[] = { 725static struct crt_mode_table CRTM2048x1536[] = {
888 /* r_rate, vclk, hsp, vsp */ 726 /* r_rate, hsp, vsp */
889 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 727 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
890 {REFRESH_60, CLK_267_250M, M2048x1536_R60_HSP, M2048x1536_R60_VSP, 728 {REFRESH_60, M2048x1536_R60_HSP, M2048x1536_R60_VSP,
891 {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} } 729 {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} }
892}; 730};
893 731
894struct VideoModeTable viafb_modes[] = { 732static struct VideoModeTable viafb_modes[] = {
895 /* Display : 480x640 (GTF) */ 733 /* Display : 480x640 (GTF) */
896 {CRTM480x640, ARRAY_SIZE(CRTM480x640)}, 734 {CRTM480x640, ARRAY_SIZE(CRTM480x640)},
897 735
@@ -1016,7 +854,7 @@ struct VideoModeTable viafb_modes[] = {
1016 {CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)} 854 {CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)}
1017}; 855};
1018 856
1019struct VideoModeTable viafb_rb_modes[] = { 857static struct VideoModeTable viafb_rb_modes[] = {
1020 /* Display : 1360x768 (CVT Reduce Blanking) */ 858 /* Display : 1360x768 (CVT Reduce Blanking) */
1021 {CRTM1360x768_RB, ARRAY_SIZE(CRTM1360x768_RB)}, 859 {CRTM1360x768_RB, ARRAY_SIZE(CRTM1360x768_RB)},
1022 860
@@ -1040,14 +878,12 @@ struct VideoModeTable viafb_rb_modes[] = {
1040}; 878};
1041 879
1042struct crt_mode_table CEAM1280x720[] = { 880struct crt_mode_table CEAM1280x720[] = {
1043 {REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP, 881 {REFRESH_60, M1280X720_CEA_R60_HSP, M1280X720_CEA_R60_VSP,
1044 M1280X720_CEA_R60_VSP,
1045 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 882 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
1046 {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} } 883 {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} }
1047}; 884};
1048struct crt_mode_table CEAM1920x1080[] = { 885struct crt_mode_table CEAM1920x1080[] = {
1049 {REFRESH_60, CLK_148_500M, M1920X1080_CEA_R60_HSP, 886 {REFRESH_60, M1920X1080_CEA_R60_HSP, M1920X1080_CEA_R60_VSP,
1050 M1920X1080_CEA_R60_VSP,
1051 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 887 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
1052 {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} } 888 {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} }
1053}; 889};
@@ -1057,7 +893,6 @@ struct VideoModeTable CEA_HDMI_Modes[] = {
1057 {CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} 893 {CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
1058}; 894};
1059 895
1060int NUM_TOTAL_RES_MAP_REFRESH = ARRAY_SIZE(res_map_refresh_tbl);
1061int NUM_TOTAL_CEA_MODES = ARRAY_SIZE(CEA_HDMI_Modes); 896int NUM_TOTAL_CEA_MODES = ARRAY_SIZE(CEA_HDMI_Modes);
1062int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs); 897int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs);
1063int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs); 898int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs);
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h
index 5b1ced86514b..8a67ea1b5ef0 100644
--- a/drivers/video/via/viamode.h
+++ b/drivers/video/via/viamode.h
@@ -41,14 +41,6 @@ struct patch_table {
41 struct io_reg *io_reg_table; 41 struct io_reg *io_reg_table;
42}; 42};
43 43
44struct res_map_refresh {
45 int hres;
46 int vres;
47 int pixclock;
48 int vmode_refresh;
49};
50
51extern int NUM_TOTAL_RES_MAP_REFRESH;
52extern int NUM_TOTAL_CEA_MODES; 44extern int NUM_TOTAL_CEA_MODES;
53extern int NUM_TOTAL_CN400_ModeXregs; 45extern int NUM_TOTAL_CN400_ModeXregs;
54extern int NUM_TOTAL_CN700_ModeXregs; 46extern int NUM_TOTAL_CN700_ModeXregs;
@@ -66,7 +58,6 @@ extern struct crt_mode_table CEAM1280x720[];
66extern struct crt_mode_table CEAM1920x1080[]; 58extern struct crt_mode_table CEAM1920x1080[];
67extern struct VideoModeTable CEA_HDMI_Modes[]; 59extern struct VideoModeTable CEA_HDMI_Modes[];
68 60
69extern struct res_map_refresh res_map_refresh_tbl[];
70extern struct io_reg CN400_ModeXregs[]; 61extern struct io_reg CN400_ModeXregs[];
71extern struct io_reg CN700_ModeXregs[]; 62extern struct io_reg CN700_ModeXregs[];
72extern struct io_reg KM400_ModeXregs[]; 63extern struct io_reg KM400_ModeXregs[];
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c
index 60e4192c2b34..ee2903b472cf 100644
--- a/drivers/video/via/vt1636.c
+++ b/drivers/video/via/vt1636.c
@@ -167,22 +167,6 @@ static int get_clk_range_index(u32 Clk)
167 return DPA_CLK_RANGE_150M; 167 return DPA_CLK_RANGE_150M;
168} 168}
169 169
170static int get_lvds_dpa_setting_index(int panel_size_id,
171 struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
172 int tbl_size)
173{
174 int i;
175
176 for (i = 0; i < tbl_size; i++) {
177 if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
178 return i;
179
180 p_vt1636_dpasetting_tbl++;
181 }
182
183 return 0;
184}
185
186static void set_dpa_vt1636(struct lvds_setting_information 170static void set_dpa_vt1636(struct lvds_setting_information
187 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, 171 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
188 struct VT1636_DPA_SETTING *p_vt1636_dpa_setting) 172 struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
@@ -206,7 +190,9 @@ void viafb_vt1636_patch_skew_on_vt3324(
206 struct lvds_setting_information *plvds_setting_info, 190 struct lvds_setting_information *plvds_setting_info,
207 struct lvds_chip_information *plvds_chip_info) 191 struct lvds_chip_information *plvds_chip_info)
208{ 192{
209 int index, size; 193 struct VT1636_DPA_SETTING dpa = {0x00, 0x00}, dpa_16x12 = {0x0B, 0x03},
194 *pdpa;
195 int index;
210 196
211 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n"); 197 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
212 198
@@ -216,19 +202,21 @@ void viafb_vt1636_patch_skew_on_vt3324(
216 &GFX_DPA_SETTING_TBL_VT3324[index]); 202 &GFX_DPA_SETTING_TBL_VT3324[index]);
217 203
218 /* LVDS Transmitter DPA settings: */ 204 /* LVDS Transmitter DPA settings: */
219 size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324); 205 if (plvds_setting_info->lcd_panel_hres == 1600 &&
220 index = 206 plvds_setting_info->lcd_panel_vres == 1200)
221 get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id, 207 pdpa = &dpa_16x12;
222 VT1636_DPA_SETTING_TBL_VT3324, size); 208 else
223 set_dpa_vt1636(plvds_setting_info, plvds_chip_info, 209 pdpa = &dpa;
224 &VT1636_DPA_SETTING_TBL_VT3324[index]); 210
211 set_dpa_vt1636(plvds_setting_info, plvds_chip_info, pdpa);
225} 212}
226 213
227void viafb_vt1636_patch_skew_on_vt3327( 214void viafb_vt1636_patch_skew_on_vt3327(
228 struct lvds_setting_information *plvds_setting_info, 215 struct lvds_setting_information *plvds_setting_info,
229 struct lvds_chip_information *plvds_chip_info) 216 struct lvds_chip_information *plvds_chip_info)
230{ 217{
231 int index, size; 218 struct VT1636_DPA_SETTING dpa = {0x00, 0x00};
219 int index;
232 220
233 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n"); 221 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
234 222
@@ -238,12 +226,7 @@ void viafb_vt1636_patch_skew_on_vt3327(
238 &GFX_DPA_SETTING_TBL_VT3327[index]); 226 &GFX_DPA_SETTING_TBL_VT3327[index]);
239 227
240 /* LVDS Transmitter DPA settings: */ 228 /* LVDS Transmitter DPA settings: */
241 size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327); 229 set_dpa_vt1636(plvds_setting_info, plvds_chip_info, &dpa);
242 index =
243 get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
244 VT1636_DPA_SETTING_TBL_VT3327, size);
245 set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
246 &VT1636_DPA_SETTING_TBL_VT3327[index]);
247} 230}
248 231
249void viafb_vt1636_patch_skew_on_vt3364( 232void viafb_vt1636_patch_skew_on_vt3364(
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;
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index 68bd23476c64..77dea015ff69 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -404,8 +404,7 @@ static int xilinxfb_release(struct device *dev)
404 * OF bus binding 404 * OF bus binding
405 */ 405 */
406 406
407static int __devinit 407static int __devinit xilinxfb_of_probe(struct platform_device *op)
408xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match)
409{ 408{
410 const u32 *prop; 409 const u32 *prop;
411 u32 *p; 410 u32 *p;
@@ -418,8 +417,6 @@ xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match)
418 /* Copy with the default pdata (not a ptr reference!) */ 417 /* Copy with the default pdata (not a ptr reference!) */
419 pdata = xilinx_fb_default_pdata; 418 pdata = xilinx_fb_default_pdata;
420 419
421 dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match);
422
423 /* Allocate the driver data region */ 420 /* Allocate the driver data region */
424 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); 421 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
425 if (!drvdata) { 422 if (!drvdata) {
@@ -505,7 +502,7 @@ static struct of_device_id xilinxfb_of_match[] __devinitdata = {
505}; 502};
506MODULE_DEVICE_TABLE(of, xilinxfb_of_match); 503MODULE_DEVICE_TABLE(of, xilinxfb_of_match);
507 504
508static struct of_platform_driver xilinxfb_of_driver = { 505static struct platform_driver xilinxfb_of_driver = {
509 .probe = xilinxfb_of_probe, 506 .probe = xilinxfb_of_probe,
510 .remove = __devexit_p(xilinxfb_of_remove), 507 .remove = __devexit_p(xilinxfb_of_remove),
511 .driver = { 508 .driver = {
@@ -523,13 +520,13 @@ static struct of_platform_driver xilinxfb_of_driver = {
523static int __init 520static int __init
524xilinxfb_init(void) 521xilinxfb_init(void)
525{ 522{
526 return of_register_platform_driver(&xilinxfb_of_driver); 523 return platform_driver_register(&xilinxfb_of_driver);
527} 524}
528 525
529static void __exit 526static void __exit
530xilinxfb_cleanup(void) 527xilinxfb_cleanup(void)
531{ 528{
532 of_unregister_platform_driver(&xilinxfb_of_driver); 529 platform_driver_unregister(&xilinxfb_of_driver);
533} 530}
534 531
535module_init(xilinxfb_init); 532module_init(xilinxfb_init);