aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig58
-rw-r--r--drivers/video/Makefile3
-rw-r--r--drivers/video/atmel_lcdfb.c6
-rw-r--r--drivers/video/aty/atyfb_base.c829
-rw-r--r--drivers/video/au1100fb.c7
-rw-r--r--drivers/video/backlight/Kconfig35
-rw-r--r--drivers/video/backlight/Makefile4
-rw-r--r--drivers/video/backlight/adp5520_bl.c377
-rw-r--r--drivers/video/backlight/adx_bl.c178
-rw-r--r--drivers/video/backlight/backlight.c42
-rw-r--r--drivers/video/backlight/corgi_lcd.c1
-rw-r--r--drivers/video/backlight/da903x_bl.c20
-rw-r--r--drivers/video/backlight/hp680_bl.c2
-rw-r--r--drivers/video/backlight/lms283gf05.c242
-rw-r--r--drivers/video/backlight/ltv350qv.c1
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c36
-rw-r--r--drivers/video/backlight/tdo24m.c1
-rw-r--r--drivers/video/backlight/tosa_lcd.c2
-rw-r--r--drivers/video/backlight/vgg2432a4.c3
-rw-r--r--drivers/video/backlight/wm831x_bl.c250
-rw-r--r--drivers/video/cfbcopyarea.c2
-rw-r--r--drivers/video/console/.gitignore2
-rw-r--r--drivers/video/console/Kconfig9
-rw-r--r--drivers/video/console/Makefile12
-rw-r--r--drivers/video/console/bitblit.c8
-rw-r--r--drivers/video/console/fbcon.c58
-rw-r--r--drivers/video/console/newport_con.c2
-rw-r--r--drivers/video/console/prom.uni11
-rw-r--r--drivers/video/console/promcon.c598
-rw-r--r--drivers/video/console/vgacon.c9
-rw-r--r--drivers/video/da8xx-fb.c890
-rw-r--r--drivers/video/ep93xx-fb.c646
-rw-r--r--drivers/video/fb_defio.c2
-rw-r--r--drivers/video/fbmem.c19
-rw-r--r--drivers/video/imxfb.c186
-rw-r--r--drivers/video/matrox/g450_pll.c209
-rw-r--r--drivers/video/matrox/g450_pll.h8
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c18
-rw-r--r--drivers/video/matrox/matroxfb_DAC1064.c614
-rw-r--r--drivers/video/matrox/matroxfb_DAC1064.h4
-rw-r--r--drivers/video/matrox/matroxfb_Ti3026.c258
-rw-r--r--drivers/video/matrox/matroxfb_accel.c129
-rw-r--r--drivers/video/matrox/matroxfb_accel.h2
-rw-r--r--drivers/video/matrox/matroxfb_base.c772
-rw-r--r--drivers/video/matrox/matroxfb_base.h80
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c160
-rw-r--r--drivers/video/matrox/matroxfb_g450.c185
-rw-r--r--drivers/video/matrox/matroxfb_g450.h8
-rw-r--r--drivers/video/matrox/matroxfb_maven.c50
-rw-r--r--drivers/video/matrox/matroxfb_misc.c288
-rw-r--r--drivers/video/matrox/matroxfb_misc.h15
-rw-r--r--drivers/video/msm/Makefile19
-rw-r--r--drivers/video/msm/mddi.c828
-rw-r--r--drivers/video/msm/mddi_client_dummy.c97
-rw-r--r--drivers/video/msm/mddi_client_nt35399.c255
-rw-r--r--drivers/video/msm/mddi_client_toshiba.c283
-rw-r--r--drivers/video/msm/mddi_hw.h305
-rw-r--r--drivers/video/msm/mdp.c538
-rw-r--r--drivers/video/msm/mdp_csc_table.h582
-rw-r--r--drivers/video/msm/mdp_hw.h621
-rw-r--r--drivers/video/msm/mdp_ppp.c750
-rw-r--r--drivers/video/msm/mdp_scale_tables.c766
-rw-r--r--drivers/video/msm/mdp_scale_tables.h38
-rw-r--r--drivers/video/msm/msm_fb.c636
-rw-r--r--drivers/video/omap/Kconfig82
-rw-r--r--drivers/video/omap/Makefile12
-rw-r--r--drivers/video/omap/blizzard.c91
-rw-r--r--drivers/video/omap/dispc.c138
-rw-r--r--drivers/video/omap/dispc.h7
-rw-r--r--drivers/video/omap/hwa742.c2
-rw-r--r--drivers/video/omap/lcd_2430sdp.c202
-rw-r--r--drivers/video/omap/lcd_ams_delta.c137
-rw-r--r--drivers/video/omap/lcd_apollon.c138
-rw-r--r--drivers/video/omap/lcd_h3.c4
-rw-r--r--drivers/video/omap/lcd_h4.c4
-rw-r--r--drivers/video/omap/lcd_inn1510.c4
-rw-r--r--drivers/video/omap/lcd_inn1610.c4
-rw-r--r--drivers/video/omap/lcd_ldp.c200
-rw-r--r--drivers/video/omap/lcd_mipid.c625
-rw-r--r--drivers/video/omap/lcd_omap2evm.c191
-rw-r--r--drivers/video/omap/lcd_omap3beagle.c130
-rw-r--r--drivers/video/omap/lcd_omap3evm.c192
-rw-r--r--drivers/video/omap/lcd_osk.c4
-rw-r--r--drivers/video/omap/lcd_overo.c179
-rw-r--r--drivers/video/omap/lcd_palmte.c4
-rw-r--r--drivers/video/omap/lcd_palmtt.c4
-rw-r--r--drivers/video/omap/lcd_palmz71.c4
-rw-r--r--drivers/video/omap/omapfb_main.c64
-rw-r--r--drivers/video/omap/rfbi.c7
-rw-r--r--drivers/video/platinumfb.c12
-rw-r--r--drivers/video/ps3fb.c2
-rw-r--r--drivers/video/pxafb.c32
-rw-r--r--drivers/video/s3c-fb.c2
-rw-r--r--drivers/video/s3c2410fb.c6
-rw-r--r--drivers/video/sa1100fb.c2
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c292
-rw-r--r--drivers/video/sis/sis_main.c4
-rw-r--r--drivers/video/sis/vstruct.h2
-rw-r--r--drivers/video/tmiofb.c2
-rw-r--r--drivers/video/uvesafb.c3
-rw-r--r--drivers/video/via/accel.c589
-rw-r--r--drivers/video/via/accel.h13
-rw-r--r--drivers/video/via/chip.h4
-rw-r--r--drivers/video/via/dvi.c6
-rw-r--r--drivers/video/via/global.c3
-rw-r--r--drivers/video/via/global.h2
-rw-r--r--drivers/video/via/hw.c474
-rw-r--r--drivers/video/via/hw.h57
-rw-r--r--drivers/video/via/ioctl.h6
-rw-r--r--drivers/video/via/lcd.c16
-rw-r--r--drivers/video/via/share.h98
-rw-r--r--drivers/video/via/via_i2c.c64
-rw-r--r--drivers/video/via/viafbdev.c1049
-rw-r--r--drivers/video/via/viafbdev.h61
-rw-r--r--drivers/video/via/viamode.c100
-rw-r--r--drivers/video/via/viamode.h141
-rw-r--r--drivers/video/via/vt1636.c4
117 files changed, 14379 insertions, 4165 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3b54b3940178..9bbb2855ea91 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -7,6 +7,8 @@ menu "Graphics support"
7 7
8source "drivers/char/agp/Kconfig" 8source "drivers/char/agp/Kconfig"
9 9
10source "drivers/gpu/vga/Kconfig"
11
10source "drivers/gpu/drm/Kconfig" 12source "drivers/gpu/drm/Kconfig"
11 13
12config VGASTATE 14config VGASTATE
@@ -935,7 +937,7 @@ config FB_S1D13XXX
935 937
936config FB_ATMEL 938config FB_ATMEL
937 tristate "AT91/AT32 LCD Controller support" 939 tristate "AT91/AT32 LCD Controller support"
938 depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32) 940 depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9G10 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || AVR32)
939 select FB_CFB_FILLRECT 941 select FB_CFB_FILLRECT
940 select FB_CFB_COPYAREA 942 select FB_CFB_COPYAREA
941 select FB_CFB_IMAGEBLIT 943 select FB_CFB_IMAGEBLIT
@@ -951,7 +953,7 @@ config FB_INTSRAM
951 953
952config FB_ATMEL_STN 954config FB_ATMEL_STN
953 bool "Use a STN display with AT91/AT32 LCD Controller" 955 bool "Use a STN display with AT91/AT32 LCD Controller"
954 depends on FB_ATMEL && MACH_AT91SAM9261EK 956 depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
955 default n 957 default n
956 help 958 help
957 Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD 959 Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
@@ -1273,26 +1275,6 @@ config FB_MATROX_MAVEN
1273 painting procedures (the secondary head does not use acceleration 1275 painting procedures (the secondary head does not use acceleration
1274 engine). 1276 engine).
1275 1277
1276config FB_MATROX_MULTIHEAD
1277 bool "Multihead support"
1278 depends on FB_MATROX
1279 ---help---
1280 Say Y here if you have more than one (supported) Matrox device in
1281 your computer and you want to use all of them for different monitors
1282 ("multihead"). If you have only one device, you should say N because
1283 the driver compiled with Y is larger and a bit slower, especially on
1284 ia32 (ix86).
1285
1286 If you said M to "Matrox unified accelerated driver" and N here, you
1287 will still be able to use several Matrox devices simultaneously:
1288 insert several instances of the module matroxfb into the kernel
1289 with insmod, supplying the parameter "dev=N" where N is 0, 1, etc.
1290 for the different Matrox devices. This method is slightly faster but
1291 uses 40 KB of kernel memory per Matrox card.
1292
1293 There is no need for enabling 'Matrox multihead support' if you have
1294 only one Matrox card in the box.
1295
1296config FB_RADEON 1278config FB_RADEON
1297 tristate "ATI Radeon display support" 1279 tristate "ATI Radeon display support"
1298 depends on FB && PCI 1280 depends on FB && PCI
@@ -1867,7 +1849,7 @@ config FB_W100
1867 1849
1868config FB_SH_MOBILE_LCDC 1850config FB_SH_MOBILE_LCDC
1869 tristate "SuperH Mobile LCDC framebuffer support" 1851 tristate "SuperH Mobile LCDC framebuffer support"
1870 depends on FB && SUPERH 1852 depends on FB && SUPERH && HAVE_CLK
1871 select FB_SYS_FILLRECT 1853 select FB_SYS_FILLRECT
1872 select FB_SYS_COPYAREA 1854 select FB_SYS_COPYAREA
1873 select FB_SYS_IMAGEBLIT 1855 select FB_SYS_IMAGEBLIT
@@ -2039,6 +2021,17 @@ config FB_SH7760
2039 and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for 2021 and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
2040 panels <= 320 pixel horizontal resolution. 2022 panels <= 320 pixel horizontal resolution.
2041 2023
2024config FB_DA8XX
2025 tristate "DA8xx/OMAP-L1xx Framebuffer support"
2026 depends on FB && ARCH_DAVINCI_DA8XX
2027 select FB_CFB_FILLRECT
2028 select FB_CFB_COPYAREA
2029 select FB_CFB_IMAGEBLIT
2030 ---help---
2031 This is the frame buffer device driver for the TI LCD controller
2032 found on DA8xx/OMAP-L1xx SoCs.
2033 If unsure, say N.
2034
2042config FB_VIRTUAL 2035config FB_VIRTUAL
2043 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 2036 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
2044 depends on FB 2037 depends on FB
@@ -2115,6 +2108,17 @@ config FB_MB862XX_LIME
2115 ---help--- 2108 ---help---
2116 Framebuffer support for Fujitsu Lime GDC on host CPU bus. 2109 Framebuffer support for Fujitsu Lime GDC on host CPU bus.
2117 2110
2111config FB_EP93XX
2112 tristate "EP93XX frame buffer support"
2113 depends on FB && ARCH_EP93XX
2114 select FB_CFB_FILLRECT
2115 select FB_CFB_COPYAREA
2116 select FB_CFB_IMAGEBLIT
2117 ---help---
2118 Framebuffer driver for the Cirrus Logic EP93XX series of processors.
2119 This driver is also available as a module. The module will be called
2120 ep93xx-fb.
2121
2118config FB_PRE_INIT_FB 2122config FB_PRE_INIT_FB
2119 bool "Don't reinitialize, use bootloader's GDC/Display configuration" 2123 bool "Don't reinitialize, use bootloader's GDC/Display configuration"
2120 depends on FB_MB862XX_LIME 2124 depends on FB_MB862XX_LIME
@@ -2122,6 +2126,14 @@ config FB_PRE_INIT_FB
2122 Select this option if display contents should be inherited as set by 2126 Select this option if display contents should be inherited as set by
2123 the bootloader. 2127 the bootloader.
2124 2128
2129config FB_MSM
2130 tristate
2131 depends on FB && ARCH_MSM
2132 select FB_CFB_FILLRECT
2133 select FB_CFB_COPYAREA
2134 select FB_CFB_IMAGEBLIT
2135 default y
2136
2125config FB_MX3 2137config FB_MX3
2126 tristate "MX3 Framebuffer support" 2138 tristate "MX3 Framebuffer support"
2127 depends on FB && MX3_IPU 2139 depends on FB && MX3_IPU
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 01a819f47371..80232e124889 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_FB_Q40) += q40fb.o
85obj-$(CONFIG_FB_TGA) += tgafb.o 85obj-$(CONFIG_FB_TGA) += tgafb.o
86obj-$(CONFIG_FB_HP300) += hpfb.o 86obj-$(CONFIG_FB_HP300) += hpfb.o
87obj-$(CONFIG_FB_G364) += g364fb.o 87obj-$(CONFIG_FB_G364) += g364fb.o
88obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o
88obj-$(CONFIG_FB_SA1100) += sa1100fb.o 89obj-$(CONFIG_FB_SA1100) += sa1100fb.o
89obj-$(CONFIG_FB_HIT) += hitfb.o 90obj-$(CONFIG_FB_HIT) += hitfb.o
90obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o 91obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o
@@ -126,6 +127,7 @@ obj-$(CONFIG_FB_OMAP) += omap/
126obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o 127obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
127obj-$(CONFIG_FB_CARMINE) += carminefb.o 128obj-$(CONFIG_FB_CARMINE) += carminefb.o
128obj-$(CONFIG_FB_MB862XX) += mb862xx/ 129obj-$(CONFIG_FB_MB862XX) += mb862xx/
130obj-$(CONFIG_FB_MSM) += msm/
129 131
130# Platform or fallback drivers go here 132# Platform or fallback drivers go here
131obj-$(CONFIG_FB_UVESA) += uvesafb.o 133obj-$(CONFIG_FB_UVESA) += uvesafb.o
@@ -136,6 +138,7 @@ obj-$(CONFIG_FB_OF) += offb.o
136obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o 138obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
137obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o 139obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o
138obj-$(CONFIG_FB_MX3) += mx3fb.o 140obj-$(CONFIG_FB_MX3) += mx3fb.o
141obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
139 142
140# the test framebuffer is last 143# the test framebuffer is last
141obj-$(CONFIG_FB_VIRTUAL) += vfb.o 144obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index da05f0801bb7..2830ffd72976 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -182,7 +182,8 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2)
182{ 182{
183 unsigned long value; 183 unsigned long value;
184 184
185 if (!(cpu_is_at91sam9261() || cpu_is_at32ap7000())) 185 if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10()
186 || cpu_is_at32ap7000()))
186 return xres; 187 return xres;
187 188
188 value = xres; 189 value = xres;
@@ -824,7 +825,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
824 info->fix = atmel_lcdfb_fix; 825 info->fix = atmel_lcdfb_fix;
825 826
826 /* Enable LCDC Clocks */ 827 /* Enable LCDC Clocks */
827 if (cpu_is_at91sam9261() || cpu_is_at32ap7000()) { 828 if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()
829 || cpu_is_at32ap7000()) {
828 sinfo->bus_clk = clk_get(dev, "hck1"); 830 sinfo->bus_clk = clk_get(dev, "hck1");
829 if (IS_ERR(sinfo->bus_clk)) { 831 if (IS_ERR(sinfo->bus_clk)) {
830 ret = PTR_ERR(sinfo->bus_clk); 832 ret = PTR_ERR(sinfo->bus_clk);
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 63d3739d43a8..913b4a47ae52 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -132,7 +132,7 @@
132#endif 132#endif
133 133
134#define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args) 134#define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args)
135#define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args) 135#define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args)
136 136
137#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \ 137#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \
138defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT) 138defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT)
@@ -188,24 +188,23 @@ u32 aty_ld_lcd(int index, const struct atyfb_par *par)
188 */ 188 */
189static void ATIReduceRatio(int *Numerator, int *Denominator) 189static void ATIReduceRatio(int *Numerator, int *Denominator)
190{ 190{
191 int Multiplier, Divider, Remainder; 191 int Multiplier, Divider, Remainder;
192 192
193 Multiplier = *Numerator; 193 Multiplier = *Numerator;
194 Divider = *Denominator; 194 Divider = *Denominator;
195 195
196 while ((Remainder = Multiplier % Divider)) 196 while ((Remainder = Multiplier % Divider)) {
197 { 197 Multiplier = Divider;
198 Multiplier = Divider; 198 Divider = Remainder;
199 Divider = Remainder; 199 }
200 }
201 200
202 *Numerator /= Divider; 201 *Numerator /= Divider;
203 *Denominator /= Divider; 202 *Denominator /= Divider;
204} 203}
205#endif 204#endif
206 /* 205/*
207 * The Hardware parameters for each card 206 * The Hardware parameters for each card
208 */ 207 */
209 208
210struct pci_mmap_map { 209struct pci_mmap_map {
211 unsigned long voff; 210 unsigned long voff;
@@ -223,17 +222,19 @@ static struct fb_fix_screeninfo atyfb_fix __devinitdata = {
223 .ypanstep = 1, 222 .ypanstep = 1,
224}; 223};
225 224
226 /* 225/*
227 * Frame buffer device API 226 * Frame buffer device API
228 */ 227 */
229 228
230static int atyfb_open(struct fb_info *info, int user); 229static int atyfb_open(struct fb_info *info, int user);
231static int atyfb_release(struct fb_info *info, int user); 230static int atyfb_release(struct fb_info *info, int user);
232static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); 231static int atyfb_check_var(struct fb_var_screeninfo *var,
232 struct fb_info *info);
233static int atyfb_set_par(struct fb_info *info); 233static int atyfb_set_par(struct fb_info *info);
234static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 234static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
235 u_int transp, struct fb_info *info); 235 u_int transp, struct fb_info *info);
236static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); 236static int atyfb_pan_display(struct fb_var_screeninfo *var,
237 struct fb_info *info);
237static int atyfb_blank(int blank, struct fb_info *info); 238static int atyfb_blank(int blank, struct fb_info *info);
238static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg); 239static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
239#ifdef __sparc__ 240#ifdef __sparc__
@@ -241,9 +242,9 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
241#endif 242#endif
242static int atyfb_sync(struct fb_info *info); 243static int atyfb_sync(struct fb_info *info);
243 244
244 /* 245/*
245 * Internal routines 246 * Internal routines
246 */ 247 */
247 248
248static int aty_init(struct fb_info *info); 249static int aty_init(struct fb_info *info);
249 250
@@ -254,8 +255,11 @@ static int store_video_par(char *videopar, unsigned char m64_num);
254static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); 255static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
255 256
256static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); 257static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
257static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc); 258static int aty_var_to_crtc(const struct fb_info *info,
258static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var); 259 const struct fb_var_screeninfo *var,
260 struct crtc *crtc);
261static int aty_crtc_to_var(const struct crtc *crtc,
262 struct fb_var_screeninfo *var);
259static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info); 263static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);
260#ifdef CONFIG_PPC 264#ifdef CONFIG_PPC
261static int read_aty_sense(const struct atyfb_par *par); 265static int read_aty_sense(const struct atyfb_par *par);
@@ -264,9 +268,9 @@ static int read_aty_sense(const struct atyfb_par *par);
264static DEFINE_MUTEX(reboot_lock); 268static DEFINE_MUTEX(reboot_lock);
265static struct fb_info *reboot_info; 269static struct fb_info *reboot_info;
266 270
267 /* 271/*
268 * Interface used by the world 272 * Interface used by the world
269 */ 273 */
270 274
271static struct fb_var_screeninfo default_var = { 275static struct fb_var_screeninfo default_var = {
272 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 276 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
@@ -452,14 +456,14 @@ static int __devinit correct_chipset(struct atyfb_par *par)
452 type = chip_id & CFG_CHIP_TYPE; 456 type = chip_id & CFG_CHIP_TYPE;
453 rev = (chip_id & CFG_CHIP_REV) >> 24; 457 rev = (chip_id & CFG_CHIP_REV) >> 24;
454 458
455 switch(par->pci_id) { 459 switch (par->pci_id) {
456#ifdef CONFIG_FB_ATY_GX 460#ifdef CONFIG_FB_ATY_GX
457 case PCI_CHIP_MACH64GX: 461 case PCI_CHIP_MACH64GX:
458 if(type != 0x00d7) 462 if (type != 0x00d7)
459 return -ENODEV; 463 return -ENODEV;
460 break; 464 break;
461 case PCI_CHIP_MACH64CX: 465 case PCI_CHIP_MACH64CX:
462 if(type != 0x0057) 466 if (type != 0x0057)
463 return -ENODEV; 467 return -ENODEV;
464 break; 468 break;
465#endif 469#endif
@@ -564,7 +568,8 @@ static char *aty_xl_ram[8] __devinitdata = {
564}; 568};
565#endif /* CONFIG_FB_ATY_CT */ 569#endif /* CONFIG_FB_ATY_CT */
566 570
567static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *par) 571static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var,
572 struct atyfb_par *par)
568{ 573{
569 u32 pixclock = var->pixclock; 574 u32 pixclock = var->pixclock;
570#ifdef CONFIG_FB_ATY_GENERIC_LCD 575#ifdef CONFIG_FB_ATY_GENERIC_LCD
@@ -572,7 +577,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *p
572 par->pll.ct.xres = 0; 577 par->pll.ct.xres = 0;
573 if (par->lcd_table != 0) { 578 if (par->lcd_table != 0) {
574 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par); 579 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par);
575 if(lcd_on_off & LCD_ON) { 580 if (lcd_on_off & LCD_ON) {
576 par->pll.ct.xres = var->xres; 581 par->pll.ct.xres = var->xres;
577 pixclock = par->lcd_pixclock; 582 pixclock = par->lcd_pixclock;
578 } 583 }
@@ -584,7 +589,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *p
584#if defined(CONFIG_PPC) 589#if defined(CONFIG_PPC)
585 590
586/* 591/*
587 * Apple monitor sense 592 * Apple monitor sense
588 */ 593 */
589 594
590static int __devinit read_aty_sense(const struct atyfb_par *par) 595static int __devinit read_aty_sense(const struct atyfb_par *par)
@@ -625,16 +630,16 @@ static int __devinit read_aty_sense(const struct atyfb_par *par)
625/* ------------------------------------------------------------------------- */ 630/* ------------------------------------------------------------------------- */
626 631
627/* 632/*
628 * CRTC programming 633 * CRTC programming
629 */ 634 */
630 635
631static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) 636static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
632{ 637{
633#ifdef CONFIG_FB_ATY_GENERIC_LCD 638#ifdef CONFIG_FB_ATY_GENERIC_LCD
634 if (par->lcd_table != 0) { 639 if (par->lcd_table != 0) {
635 if(!M64_HAS(LT_LCD_REGS)) { 640 if (!M64_HAS(LT_LCD_REGS)) {
636 crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); 641 crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
637 aty_st_le32(LCD_INDEX, crtc->lcd_index, par); 642 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
638 } 643 }
639 crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par); 644 crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par);
640 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par); 645 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
@@ -642,7 +647,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
642 647
643 /* switch to non shadow registers */ 648 /* switch to non shadow registers */
644 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & 649 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
645 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); 650 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
646 651
647 /* save stretching */ 652 /* save stretching */
648 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); 653 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
@@ -663,7 +668,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
663 if (par->lcd_table != 0) { 668 if (par->lcd_table != 0) {
664 /* switch to shadow registers */ 669 /* switch to shadow registers */
665 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | 670 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
666 SHADOW_EN | SHADOW_RW_EN, par); 671 SHADOW_EN | SHADOW_RW_EN, par);
667 672
668 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); 673 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
669 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); 674 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
@@ -680,21 +685,20 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
680#ifdef CONFIG_FB_ATY_GENERIC_LCD 685#ifdef CONFIG_FB_ATY_GENERIC_LCD
681 if (par->lcd_table != 0) { 686 if (par->lcd_table != 0) {
682 /* stop CRTC */ 687 /* stop CRTC */
683 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par); 688 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl &
689 ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
684 690
685 /* update non-shadow registers first */ 691 /* update non-shadow registers first */
686 aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par); 692 aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par);
687 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & 693 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
688 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); 694 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
689 695
690 /* temporarily disable stretching */ 696 /* temporarily disable stretching */
691 aty_st_lcd(HORZ_STRETCHING, 697 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching &
692 crtc->horz_stretching & 698 ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par);
693 ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par); 699 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching &
694 aty_st_lcd(VERT_STRETCHING, 700 ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
695 crtc->vert_stretching & 701 VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
696 ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
697 VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
698 } 702 }
699#endif 703#endif
700 /* turn off CRT */ 704 /* turn off CRT */
@@ -702,17 +706,19 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
702 706
703 DPRINTK("setting up CRTC\n"); 707 DPRINTK("setting up CRTC\n");
704 DPRINTK("set primary CRT to %ix%i %c%c composite %c\n", 708 DPRINTK("set primary CRT to %ix%i %c%c composite %c\n",
705 ((((crtc->h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->v_tot_disp>>16) & 0x7ff) + 1), 709 ((((crtc->h_tot_disp >> 16) & 0xff) + 1) << 3),
706 (crtc->h_sync_strt_wid & 0x200000)?'N':'P', (crtc->v_sync_strt_wid & 0x200000)?'N':'P', 710 (((crtc->v_tot_disp >> 16) & 0x7ff) + 1),
707 (crtc->gen_cntl & CRTC_CSYNC_EN)?'P':'N'); 711 (crtc->h_sync_strt_wid & 0x200000) ? 'N' : 'P',
708 712 (crtc->v_sync_strt_wid & 0x200000) ? 'N' : 'P',
709 DPRINTK("CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp); 713 (crtc->gen_cntl & CRTC_CSYNC_EN) ? 'P' : 'N');
710 DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid); 714
711 DPRINTK("CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp); 715 DPRINTK("CRTC_H_TOTAL_DISP: %x\n", crtc->h_tot_disp);
712 DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid); 716 DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n", crtc->h_sync_strt_wid);
717 DPRINTK("CRTC_V_TOTAL_DISP: %x\n", crtc->v_tot_disp);
718 DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n", crtc->v_sync_strt_wid);
713 DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch); 719 DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch);
714 DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline); 720 DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline);
715 DPRINTK("CRTC_GEN_CNTL: %x\n",crtc->gen_cntl); 721 DPRINTK("CRTC_GEN_CNTL: %x\n", crtc->gen_cntl);
716 722
717 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par); 723 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
718 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par); 724 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
@@ -732,16 +738,22 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
732 if (par->lcd_table != 0) { 738 if (par->lcd_table != 0) {
733 /* switch to shadow registers */ 739 /* switch to shadow registers */
734 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | 740 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
735 (SHADOW_EN | SHADOW_RW_EN), par); 741 SHADOW_EN | SHADOW_RW_EN, par);
736 742
737 DPRINTK("set shadow CRT to %ix%i %c%c\n", 743 DPRINTK("set shadow CRT to %ix%i %c%c\n",
738 ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1), 744 ((((crtc->shadow_h_tot_disp >> 16) & 0xff) + 1) << 3),
739 (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P'); 745 (((crtc->shadow_v_tot_disp >> 16) & 0x7ff) + 1),
740 746 (crtc->shadow_h_sync_strt_wid & 0x200000) ? 'N' : 'P',
741 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", crtc->shadow_h_tot_disp); 747 (crtc->shadow_v_sync_strt_wid & 0x200000) ? 'N' : 'P');
742 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", crtc->shadow_h_sync_strt_wid); 748
743 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", crtc->shadow_v_tot_disp); 749 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n",
744 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", crtc->shadow_v_sync_strt_wid); 750 crtc->shadow_h_tot_disp);
751 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n",
752 crtc->shadow_h_sync_strt_wid);
753 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n",
754 crtc->shadow_v_tot_disp);
755 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n",
756 crtc->shadow_v_sync_strt_wid);
745 757
746 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par); 758 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par);
747 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par); 759 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par);
@@ -752,16 +764,16 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
752 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl); 764 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
753 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching); 765 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching);
754 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching); 766 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching);
755 if(!M64_HAS(LT_LCD_REGS)) 767 if (!M64_HAS(LT_LCD_REGS))
756 DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch); 768 DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
757 769
758 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par); 770 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
759 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par); 771 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par);
760 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par); 772 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par);
761 if(!M64_HAS(LT_LCD_REGS)) { 773 if (!M64_HAS(LT_LCD_REGS)) {
762 aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par); 774 aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
763 aty_ld_le32(LCD_INDEX, par); 775 aty_ld_le32(LCD_INDEX, par);
764 aty_st_le32(LCD_INDEX, crtc->lcd_index, par); 776 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
765 } 777 }
766 } 778 }
767#endif /* CONFIG_FB_ATY_GENERIC_LCD */ 779#endif /* CONFIG_FB_ATY_GENERIC_LCD */
@@ -779,7 +791,8 @@ static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp)
779} 791}
780 792
781static int aty_var_to_crtc(const struct fb_info *info, 793static int aty_var_to_crtc(const struct fb_info *info,
782 const struct fb_var_screeninfo *var, struct crtc *crtc) 794 const struct fb_var_screeninfo *var,
795 struct crtc *crtc)
783{ 796{
784 struct atyfb_par *par = (struct atyfb_par *) info->par; 797 struct atyfb_par *par = (struct atyfb_par *) info->par;
785 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp; 798 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
@@ -814,34 +827,32 @@ static int aty_var_to_crtc(const struct fb_info *info,
814 if (bpp <= 8) { 827 if (bpp <= 8) {
815 bpp = 8; 828 bpp = 8;
816 pix_width = CRTC_PIX_WIDTH_8BPP; 829 pix_width = CRTC_PIX_WIDTH_8BPP;
817 dp_pix_width = 830 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP |
818 HOST_8BPP | SRC_8BPP | DST_8BPP | 831 BYTE_ORDER_LSB_TO_MSB;
819 BYTE_ORDER_LSB_TO_MSB;
820 dp_chain_mask = DP_CHAIN_8BPP; 832 dp_chain_mask = DP_CHAIN_8BPP;
821 } else if (bpp <= 15) { 833 } else if (bpp <= 15) {
822 bpp = 16; 834 bpp = 16;
823 pix_width = CRTC_PIX_WIDTH_15BPP; 835 pix_width = CRTC_PIX_WIDTH_15BPP;
824 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP | 836 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
825 BYTE_ORDER_LSB_TO_MSB; 837 BYTE_ORDER_LSB_TO_MSB;
826 dp_chain_mask = DP_CHAIN_15BPP; 838 dp_chain_mask = DP_CHAIN_15BPP;
827 } else if (bpp <= 16) { 839 } else if (bpp <= 16) {
828 bpp = 16; 840 bpp = 16;
829 pix_width = CRTC_PIX_WIDTH_16BPP; 841 pix_width = CRTC_PIX_WIDTH_16BPP;
830 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP | 842 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP |
831 BYTE_ORDER_LSB_TO_MSB; 843 BYTE_ORDER_LSB_TO_MSB;
832 dp_chain_mask = DP_CHAIN_16BPP; 844 dp_chain_mask = DP_CHAIN_16BPP;
833 } else if (bpp <= 24 && M64_HAS(INTEGRATED)) { 845 } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
834 bpp = 24; 846 bpp = 24;
835 pix_width = CRTC_PIX_WIDTH_24BPP; 847 pix_width = CRTC_PIX_WIDTH_24BPP;
836 dp_pix_width = 848 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP |
837 HOST_8BPP | SRC_8BPP | DST_8BPP | 849 BYTE_ORDER_LSB_TO_MSB;
838 BYTE_ORDER_LSB_TO_MSB;
839 dp_chain_mask = DP_CHAIN_24BPP; 850 dp_chain_mask = DP_CHAIN_24BPP;
840 } else if (bpp <= 32) { 851 } else if (bpp <= 32) {
841 bpp = 32; 852 bpp = 32;
842 pix_width = CRTC_PIX_WIDTH_32BPP; 853 pix_width = CRTC_PIX_WIDTH_32BPP;
843 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP | 854 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
844 BYTE_ORDER_LSB_TO_MSB; 855 BYTE_ORDER_LSB_TO_MSB;
845 dp_chain_mask = DP_CHAIN_32BPP; 856 dp_chain_mask = DP_CHAIN_32BPP;
846 } else 857 } else
847 FAIL("invalid bpp"); 858 FAIL("invalid bpp");
@@ -854,9 +865,9 @@ static int aty_var_to_crtc(const struct fb_info *info,
854 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; 865 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
855 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; 866 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
856 867
857 if((xres > 1600) || (yres > 1200)) { 868 if ((xres > 1600) || (yres > 1200)) {
858 FAIL("MACH64 chips are designed for max 1600x1200\n" 869 FAIL("MACH64 chips are designed for max 1600x1200\n"
859 "select anoter resolution."); 870 "select anoter resolution.");
860 } 871 }
861 h_sync_strt = h_disp + var->right_margin; 872 h_sync_strt = h_disp + var->right_margin;
862 h_sync_end = h_sync_strt + var->hsync_len; 873 h_sync_end = h_sync_strt + var->hsync_len;
@@ -869,11 +880,12 @@ static int aty_var_to_crtc(const struct fb_info *info,
869 880
870#ifdef CONFIG_FB_ATY_GENERIC_LCD 881#ifdef CONFIG_FB_ATY_GENERIC_LCD
871 if (par->lcd_table != 0) { 882 if (par->lcd_table != 0) {
872 if(!M64_HAS(LT_LCD_REGS)) { 883 if (!M64_HAS(LT_LCD_REGS)) {
873 u32 lcd_index = aty_ld_le32(LCD_INDEX, par); 884 u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
874 crtc->lcd_index = lcd_index & 885 crtc->lcd_index = lcd_index &
875 ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | LCD_SRC_SEL | CRTC2_DISPLAY_DIS); 886 ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS |
876 aty_st_le32(LCD_INDEX, lcd_index, par); 887 LCD_SRC_SEL | CRTC2_DISPLAY_DIS);
888 aty_st_le32(LCD_INDEX, lcd_index, par);
877 } 889 }
878 890
879 if (!M64_HAS(MOBIL_BUS)) 891 if (!M64_HAS(MOBIL_BUS))
@@ -888,12 +900,14 @@ static int aty_var_to_crtc(const struct fb_info *info,
888 USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN); 900 USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
889 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT; 901 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT;
890 902
891 if((crtc->lcd_gen_cntl & LCD_ON) && 903 if ((crtc->lcd_gen_cntl & LCD_ON) &&
892 ((xres > par->lcd_width) || (yres > par->lcd_height))) { 904 ((xres > par->lcd_width) || (yres > par->lcd_height))) {
893 /* We cannot display the mode on the LCD. If the CRT is enabled 905 /*
894 we can turn off the LCD. 906 * We cannot display the mode on the LCD. If the CRT is
895 If the CRT is off, it isn't a good idea to switch it on; we don't 907 * enabled we can turn off the LCD.
896 know if one is connected. So it's better to fail then. 908 * If the CRT is off, it isn't a good idea to switch it
909 * on; we don't know if one is connected. So it's better
910 * to fail then.
897 */ 911 */
898 if (crtc->lcd_gen_cntl & CRT_ON) { 912 if (crtc->lcd_gen_cntl & CRT_ON) {
899 if (!(var->activate & FB_ACTIVATE_TEST)) 913 if (!(var->activate & FB_ACTIVATE_TEST))
@@ -916,17 +930,18 @@ static int aty_var_to_crtc(const struct fb_info *info,
916 930
917 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED); 931 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED);
918 932
919 /* This is horror! When we simulate, say 640x480 on an 800x600 933 /*
920 LCD monitor, the CRTC should be programmed 800x600 values for 934 * This is horror! When we simulate, say 640x480 on an 800x600
921 the non visible part, but 640x480 for the visible part. 935 * LCD monitor, the CRTC should be programmed 800x600 values for
922 This code has been tested on a laptop with it's 1400x1050 LCD 936 * the non visible part, but 640x480 for the visible part.
923 monitor and a conventional monitor both switched on. 937 * This code has been tested on a laptop with it's 1400x1050 LCD
924 Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, 938 * monitor and a conventional monitor both switched on.
925 works with little glitches also with DOUBLESCAN modes 939 * Tested modes: 1280x1024, 1152x864, 1024x768, 800x600,
940 * works with little glitches also with DOUBLESCAN modes
926 */ 941 */
927 if (yres < par->lcd_height) { 942 if (yres < par->lcd_height) {
928 VScan = par->lcd_height / yres; 943 VScan = par->lcd_height / yres;
929 if(VScan > 1) { 944 if (VScan > 1) {
930 VScan = 2; 945 VScan = 2;
931 vmode |= FB_VMODE_DOUBLE; 946 vmode |= FB_VMODE_DOUBLE;
932 } 947 }
@@ -952,7 +967,7 @@ static int aty_var_to_crtc(const struct fb_info *info,
952 FAIL_MAX("h_disp too large", h_disp, 0xff); 967 FAIL_MAX("h_disp too large", h_disp, 0xff);
953 FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff); 968 FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff);
954 /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/ 969 /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/
955 if(h_sync_wid > 0x1f) 970 if (h_sync_wid > 0x1f)
956 h_sync_wid = 0x1f; 971 h_sync_wid = 0x1f;
957 FAIL_MAX("h_total too large", h_total, 0x1ff); 972 FAIL_MAX("h_total too large", h_total, 0x1ff);
958 973
@@ -978,7 +993,7 @@ static int aty_var_to_crtc(const struct fb_info *info,
978 FAIL_MAX("v_disp too large", v_disp, 0x7ff); 993 FAIL_MAX("v_disp too large", v_disp, 0x7ff);
979 FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff); 994 FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff);
980 /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/ 995 /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/
981 if(v_sync_wid > 0x1f) 996 if (v_sync_wid > 0x1f)
982 v_sync_wid = 0x1f; 997 v_sync_wid = 0x1f;
983 FAIL_MAX("v_total too large", v_total, 0x7ff); 998 FAIL_MAX("v_total too large", v_total, 0x7ff);
984 999
@@ -995,11 +1010,13 @@ static int aty_var_to_crtc(const struct fb_info *info,
995 ((line_length / bpp) << 22); 1010 ((line_length / bpp) << 22);
996 crtc->vline_crnt_vline = 0; 1011 crtc->vline_crnt_vline = 0;
997 1012
998 crtc->h_tot_disp = h_total | (h_disp<<16); 1013 crtc->h_tot_disp = h_total | (h_disp << 16);
999 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) | 1014 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly << 8) |
1000 ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) | (h_sync_pol<<21); 1015 ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) |
1001 crtc->v_tot_disp = v_total | (v_disp<<16); 1016 (h_sync_pol << 21);
1002 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21); 1017 crtc->v_tot_disp = v_total | (v_disp << 16);
1018 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
1019 (v_sync_pol << 21);
1003 1020
1004 /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */ 1021 /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */
1005 crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync; 1022 crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync;
@@ -1014,13 +1031,15 @@ static int aty_var_to_crtc(const struct fb_info *info,
1014#ifdef CONFIG_FB_ATY_GENERIC_LCD 1031#ifdef CONFIG_FB_ATY_GENERIC_LCD
1015 if (par->lcd_table != 0) { 1032 if (par->lcd_table != 0) {
1016 vdisplay = yres; 1033 vdisplay = yres;
1017 if(vmode & FB_VMODE_DOUBLE) 1034 if (vmode & FB_VMODE_DOUBLE)
1018 vdisplay <<= 1; 1035 vdisplay <<= 1;
1019 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); 1036 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
1020 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | 1037 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
1021 /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ 1038 /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/
1022 USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN); 1039 USE_SHADOWED_VEND |
1023 crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR/* | LOCK_8DOT*/); 1040 USE_SHADOWED_ROWCUR |
1041 SHADOW_EN | SHADOW_RW_EN);
1042 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR/* | LOCK_8DOT*/;
1024 1043
1025 /* MOBILITY M1 tested, FIXME: LT */ 1044 /* MOBILITY M1 tested, FIXME: LT */
1026 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); 1045 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
@@ -1028,28 +1047,32 @@ static int aty_var_to_crtc(const struct fb_info *info,
1028 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) & 1047 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) &
1029 ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3); 1048 ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
1030 1049
1031 crtc->horz_stretching &= 1050 crtc->horz_stretching &= ~(HORZ_STRETCH_RATIO |
1032 ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | 1051 HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
1033 HORZ_STRETCH_MODE | HORZ_STRETCH_EN); 1052 HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
1034 if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) { 1053 if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) {
1035 do { 1054 do {
1036 /* 1055 /*
1037 * The horizontal blender misbehaves when HDisplay is less than a 1056 * The horizontal blender misbehaves when
1038 * a certain threshold (440 for a 1024-wide panel). It doesn't 1057 * HDisplay is less than a certain threshold
1039 * stretch such modes enough. Use pixel replication instead of 1058 * (440 for a 1024-wide panel). It doesn't
1040 * blending to stretch modes that can be made to exactly fit the 1059 * stretch such modes enough. Use pixel
1041 * panel width. The undocumented "NoLCDBlend" option allows the 1060 * replication instead of blending to stretch
1042 * pixel-replicated mode to be slightly wider or narrower than the 1061 * modes that can be made to exactly fit the
1043 * panel width. It also causes a mode that is exactly half as wide 1062 * panel width. The undocumented "NoLCDBlend"
1044 * as the panel to be pixel-replicated, rather than blended. 1063 * option allows the pixel-replicated mode to
1045 */ 1064 * be slightly wider or narrower than the
1065 * panel width. It also causes a mode that is
1066 * exactly half as wide as the panel to be
1067 * pixel-replicated, rather than blended.
1068 */
1046 int HDisplay = xres & ~7; 1069 int HDisplay = xres & ~7;
1047 int nStretch = par->lcd_width / HDisplay; 1070 int nStretch = par->lcd_width / HDisplay;
1048 int Remainder = par->lcd_width % HDisplay; 1071 int Remainder = par->lcd_width % HDisplay;
1049 1072
1050 if ((!Remainder && ((nStretch > 2))) || 1073 if ((!Remainder && ((nStretch > 2))) ||
1051 (((HDisplay * 16) / par->lcd_width) < 7)) { 1074 (((HDisplay * 16) / par->lcd_width) < 7)) {
1052 static const char StretchLoops[] = {10, 12, 13, 15, 16}; 1075 static const char StretchLoops[] = { 10, 12, 13, 15, 16 };
1053 int horz_stretch_loop = -1, BestRemainder; 1076 int horz_stretch_loop = -1, BestRemainder;
1054 int Numerator = HDisplay, Denominator = par->lcd_width; 1077 int Numerator = HDisplay, Denominator = par->lcd_width;
1055 int Index = 5; 1078 int Index = 5;
@@ -1098,12 +1121,12 @@ static int aty_var_to_crtc(const struct fb_info *info,
1098 (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0)); 1121 (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
1099 1122
1100 if (!M64_HAS(LT_LCD_REGS) && 1123 if (!M64_HAS(LT_LCD_REGS) &&
1101 xres <= (M64_HAS(MOBIL_BUS)?1024:800)) 1124 xres <= (M64_HAS(MOBIL_BUS) ? 1024 : 800))
1102 crtc->ext_vert_stretch |= VERT_STRETCH_MODE; 1125 crtc->ext_vert_stretch |= VERT_STRETCH_MODE;
1103 } else { 1126 } else {
1104 /* 1127 /*
1105 * Don't use vertical blending if the mode is too wide or not 1128 * Don't use vertical blending if the mode is too wide
1106 * vertically stretched. 1129 * or not vertically stretched.
1107 */ 1130 */
1108 crtc->vert_stretching = 0; 1131 crtc->vert_stretching = 0;
1109 } 1132 }
@@ -1125,11 +1148,11 @@ static int aty_var_to_crtc(const struct fb_info *info,
1125 return 0; 1148 return 0;
1126} 1149}
1127 1150
1128static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var) 1151static int aty_crtc_to_var(const struct crtc *crtc,
1152 struct fb_var_screeninfo *var)
1129{ 1153{
1130 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync; 1154 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1131 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, 1155 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
1132 h_sync_pol;
1133 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync; 1156 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1134 u32 pix_width; 1157 u32 pix_width;
1135 u32 double_scan, interlace; 1158 u32 double_scan, interlace;
@@ -1161,8 +1184,8 @@ static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *va
1161 lower = v_sync_strt - v_disp; 1184 lower = v_sync_strt - v_disp;
1162 vslen = v_sync_wid; 1185 vslen = v_sync_wid;
1163 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) | 1186 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1164 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) | 1187 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1165 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0); 1188 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1166 1189
1167 switch (pix_width) { 1190 switch (pix_width) {
1168#if 0 1191#if 0
@@ -1252,20 +1275,21 @@ static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *va
1252 var->vsync_len = vslen; 1275 var->vsync_len = vslen;
1253 var->sync = sync; 1276 var->sync = sync;
1254 var->vmode = FB_VMODE_NONINTERLACED; 1277 var->vmode = FB_VMODE_NONINTERLACED;
1255 /* In double scan mode, the vertical parameters are doubled, so we need to 1278 /*
1256 half them to get the right values. 1279 * In double scan mode, the vertical parameters are doubled,
1257 In interlaced mode the values are already correct, so no correction is 1280 * so we need to halve them to get the right values.
1258 necessary. 1281 * In interlaced mode the values are already correct,
1282 * so no correction is necessary.
1259 */ 1283 */
1260 if (interlace) 1284 if (interlace)
1261 var->vmode = FB_VMODE_INTERLACED; 1285 var->vmode = FB_VMODE_INTERLACED;
1262 1286
1263 if (double_scan) { 1287 if (double_scan) {
1264 var->vmode = FB_VMODE_DOUBLE; 1288 var->vmode = FB_VMODE_DOUBLE;
1265 var->yres>>=1; 1289 var->yres >>= 1;
1266 var->upper_margin>>=1; 1290 var->upper_margin >>= 1;
1267 var->lower_margin>>=1; 1291 var->lower_margin >>= 1;
1268 var->vsync_len>>=1; 1292 var->vsync_len >>= 1;
1269 } 1293 }
1270 1294
1271 return 0; 1295 return 0;
@@ -1286,7 +1310,8 @@ static int atyfb_set_par(struct fb_info *info)
1286 if (par->asleep) 1310 if (par->asleep)
1287 return 0; 1311 return 0;
1288 1312
1289 if ((err = aty_var_to_crtc(info, var, &par->crtc))) 1313 err = aty_var_to_crtc(info, var, &par->crtc);
1314 if (err)
1290 return err; 1315 return err;
1291 1316
1292 pixclock = atyfb_get_pixclock(var, par); 1317 pixclock = atyfb_get_pixclock(var, par);
@@ -1295,7 +1320,9 @@ static int atyfb_set_par(struct fb_info *info)
1295 PRINTKE("Invalid pixclock\n"); 1320 PRINTKE("Invalid pixclock\n");
1296 return -EINVAL; 1321 return -EINVAL;
1297 } else { 1322 } else {
1298 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll))) 1323 err = par->pll_ops->var_to_pll(info, pixclock,
1324 var->bits_per_pixel, &par->pll);
1325 if (err)
1299 return err; 1326 return err;
1300 } 1327 }
1301 1328
@@ -1313,22 +1340,23 @@ static int atyfb_set_par(struct fb_info *info)
1313 wait_for_idle(par); 1340 wait_for_idle(par);
1314 1341
1315 aty_set_crtc(par, &par->crtc); 1342 aty_set_crtc(par, &par->crtc);
1316 par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel, par->accel_flags); 1343 par->dac_ops->set_dac(info, &par->pll,
1344 var->bits_per_pixel, par->accel_flags);
1317 par->pll_ops->set_pll(info, &par->pll); 1345 par->pll_ops->set_pll(info, &par->pll);
1318 1346
1319#ifdef DEBUG 1347#ifdef DEBUG
1320 if(par->pll_ops && par->pll_ops->pll_to_var) 1348 if (par->pll_ops && par->pll_ops->pll_to_var)
1321 pixclock_in_ps = par->pll_ops->pll_to_var(info, &(par->pll)); 1349 pixclock_in_ps = par->pll_ops->pll_to_var(info, &par->pll);
1322 else 1350 else
1323 pixclock_in_ps = 0; 1351 pixclock_in_ps = 0;
1324 1352
1325 if(0 == pixclock_in_ps) { 1353 if (0 == pixclock_in_ps) {
1326 PRINTKE("ALERT ops->pll_to_var get 0\n"); 1354 PRINTKE("ALERT ops->pll_to_var get 0\n");
1327 pixclock_in_ps = pixclock; 1355 pixclock_in_ps = pixclock;
1328 } 1356 }
1329 1357
1330 memset(&debug, 0, sizeof(debug)); 1358 memset(&debug, 0, sizeof(debug));
1331 if(!aty_crtc_to_var(&(par->crtc), &debug)) { 1359 if (!aty_crtc_to_var(&par->crtc, &debug)) {
1332 u32 hSync, vRefresh; 1360 u32 hSync, vRefresh;
1333 u32 h_disp, h_sync_strt, h_sync_end, h_total; 1361 u32 h_disp, h_sync_strt, h_sync_end, h_total;
1334 u32 v_disp, v_sync_strt, v_sync_end, v_total; 1362 u32 v_disp, v_sync_strt, v_sync_end, v_total;
@@ -1344,16 +1372,20 @@ static int atyfb_set_par(struct fb_info *info)
1344 1372
1345 hSync = 1000000000 / (pixclock_in_ps * h_total); 1373 hSync = 1000000000 / (pixclock_in_ps * h_total);
1346 vRefresh = (hSync * 1000) / v_total; 1374 vRefresh = (hSync * 1000) / v_total;
1347 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN) 1375 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN)
1348 vRefresh *= 2; 1376 vRefresh *= 2;
1349 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN) 1377 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1350 vRefresh /= 2; 1378 vRefresh /= 2;
1351 1379
1352 DPRINTK("atyfb_set_par\n"); 1380 DPRINTK("atyfb_set_par\n");
1353 DPRINTK(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel); 1381 DPRINTK(" Set Visible Mode to %ix%i-%i\n",
1354 DPRINTK(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n", 1382 var->xres, var->yres, var->bits_per_pixel);
1355 var->xres_virtual, var->yres_virtual, pixclock, pixclock_in_ps); 1383 DPRINTK(" Virtual resolution %ix%i, "
1356 DPRINTK(" Dot clock: %i MHz\n", 1000000 / pixclock_in_ps); 1384 "pixclock_in_ps %i (calculated %i)\n",
1385 var->xres_virtual, var->yres_virtual,
1386 pixclock, pixclock_in_ps);
1387 DPRINTK(" Dot clock: %i MHz\n",
1388 1000000 / pixclock_in_ps);
1357 DPRINTK(" Horizontal sync: %i kHz\n", hSync); 1389 DPRINTK(" Horizontal sync: %i kHz\n", hSync);
1358 DPRINTK(" Vertical refresh: %i Hz\n", vRefresh); 1390 DPRINTK(" Vertical refresh: %i Hz\n", vRefresh);
1359 DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n", 1391 DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n",
@@ -1448,7 +1480,8 @@ static int atyfb_set_par(struct fb_info *info)
1448 base = 0x2000; 1480 base = 0x2000;
1449 printk("debug atyfb: Mach64 non-shadow register values:"); 1481 printk("debug atyfb: Mach64 non-shadow register values:");
1450 for (i = 0; i < 256; i = i+4) { 1482 for (i = 0; i < 256; i = i+4) {
1451 if(i%16 == 0) printk("\ndebug atyfb: 0x%04X: ", base + i); 1483 if (i % 16 == 0)
1484 printk("\ndebug atyfb: 0x%04X: ", base + i);
1452 printk(" %08X", aty_ld_le32(i, par)); 1485 printk(" %08X", aty_ld_le32(i, par));
1453 } 1486 }
1454 printk("\n\n"); 1487 printk("\n\n");
@@ -1458,8 +1491,10 @@ static int atyfb_set_par(struct fb_info *info)
1458 base = 0x00; 1491 base = 0x00;
1459 printk("debug atyfb: Mach64 PLL register values:"); 1492 printk("debug atyfb: Mach64 PLL register values:");
1460 for (i = 0; i < 64; i++) { 1493 for (i = 0; i < 64; i++) {
1461 if(i%16 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i); 1494 if (i % 16 == 0)
1462 if(i%4 == 0) printk(" "); 1495 printk("\ndebug atyfb: 0x%02X: ", base + i);
1496 if (i % 4 == 0)
1497 printk(" ");
1463 printk("%02X", aty_ld_pll_ct(i, par)); 1498 printk("%02X", aty_ld_pll_ct(i, par));
1464 } 1499 }
1465 printk("\n\n"); 1500 printk("\n\n");
@@ -1470,19 +1505,21 @@ static int atyfb_set_par(struct fb_info *info)
1470 /* LCD registers */ 1505 /* LCD registers */
1471 base = 0x00; 1506 base = 0x00;
1472 printk("debug atyfb: LCD register values:"); 1507 printk("debug atyfb: LCD register values:");
1473 if(M64_HAS(LT_LCD_REGS)) { 1508 if (M64_HAS(LT_LCD_REGS)) {
1474 for(i = 0; i <= POWER_MANAGEMENT; i++) { 1509 for (i = 0; i <= POWER_MANAGEMENT; i++) {
1475 if(i == EXT_VERT_STRETCH) 1510 if (i == EXT_VERT_STRETCH)
1476 continue; 1511 continue;
1477 printk("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]); 1512 printk("\ndebug atyfb: 0x%04X: ",
1478 printk(" %08X", aty_ld_lcd(i, par)); 1513 lt_lcd_regs[i]);
1479 } 1514 printk(" %08X", aty_ld_lcd(i, par));
1480 1515 }
1481 } else { 1516 } else {
1482 for (i = 0; i < 64; i++) { 1517 for (i = 0; i < 64; i++) {
1483 if(i%4 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i); 1518 if (i % 4 == 0)
1484 printk(" %08X", aty_ld_lcd(i, par)); 1519 printk("\ndebug atyfb: 0x%02X: ",
1485 } 1520 base + i);
1521 printk(" %08X", aty_ld_lcd(i, par));
1522 }
1486 } 1523 }
1487 printk("\n\n"); 1524 printk("\n\n");
1488 } 1525 }
@@ -1500,9 +1537,10 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1500 union aty_pll pll; 1537 union aty_pll pll;
1501 u32 pixclock; 1538 u32 pixclock;
1502 1539
1503 memcpy(&pll, &(par->pll), sizeof(pll)); 1540 memcpy(&pll, &par->pll, sizeof(pll));
1504 1541
1505 if((err = aty_var_to_crtc(info, var, &crtc))) 1542 err = aty_var_to_crtc(info, var, &crtc);
1543 if (err)
1506 return err; 1544 return err;
1507 1545
1508 pixclock = atyfb_get_pixclock(var, par); 1546 pixclock = atyfb_get_pixclock(var, par);
@@ -1512,7 +1550,9 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1512 PRINTKE("Invalid pixclock\n"); 1550 PRINTKE("Invalid pixclock\n");
1513 return -EINVAL; 1551 return -EINVAL;
1514 } else { 1552 } else {
1515 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll))) 1553 err = par->pll_ops->var_to_pll(info, pixclock,
1554 var->bits_per_pixel, &pll);
1555 if (err)
1516 return err; 1556 return err;
1517 } 1557 }
1518 1558
@@ -1539,9 +1579,9 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
1539} 1579}
1540 1580
1541 1581
1542 /* 1582/*
1543 * Open/Release the frame buffer device 1583 * Open/Release the frame buffer device
1544 */ 1584 */
1545 1585
1546static int atyfb_open(struct fb_info *info, int user) 1586static int atyfb_open(struct fb_info *info, int user)
1547{ 1587{
@@ -1553,7 +1593,7 @@ static int atyfb_open(struct fb_info *info, int user)
1553 par->mmaped = 0; 1593 par->mmaped = 0;
1554#endif 1594#endif
1555 } 1595 }
1556 return (0); 1596 return 0;
1557} 1597}
1558 1598
1559static irqreturn_t aty_irq(int irq, void *dev_id) 1599static irqreturn_t aty_irq(int irq, void *dev_id)
@@ -1568,7 +1608,8 @@ static irqreturn_t aty_irq(int irq, void *dev_id)
1568 1608
1569 if (int_cntl & CRTC_VBLANK_INT) { 1609 if (int_cntl & CRTC_VBLANK_INT) {
1570 /* clear interrupt */ 1610 /* clear interrupt */
1571 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | CRTC_VBLANK_INT_AK, par); 1611 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) |
1612 CRTC_VBLANK_INT_AK, par);
1572 par->vblank.count++; 1613 par->vblank.count++;
1573 if (par->vblank.pan_display) { 1614 if (par->vblank.pan_display) {
1574 par->vblank.pan_display = 0; 1615 par->vblank.pan_display = 0;
@@ -1603,9 +1644,11 @@ static int aty_enable_irq(struct atyfb_par *par, int reenable)
1603 spin_lock_irq(&par->int_lock); 1644 spin_lock_irq(&par->int_lock);
1604 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; 1645 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1605 if (!(int_cntl & CRTC_VBLANK_INT_EN)) { 1646 if (!(int_cntl & CRTC_VBLANK_INT_EN)) {
1606 printk("atyfb: someone disabled IRQ [%08x]\n", int_cntl); 1647 printk("atyfb: someone disabled IRQ [%08x]\n",
1648 int_cntl);
1607 /* re-enable interrupt */ 1649 /* re-enable interrupt */
1608 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par ); 1650 aty_st_le32(CRTC_INT_CNTL, int_cntl |
1651 CRTC_VBLANK_INT_EN, par);
1609 } 1652 }
1610 spin_unlock_irq(&par->int_lock); 1653 spin_unlock_irq(&par->int_lock);
1611 } 1654 }
@@ -1625,7 +1668,7 @@ static int aty_disable_irq(struct atyfb_par *par)
1625 spin_lock_irq(&par->int_lock); 1668 spin_lock_irq(&par->int_lock);
1626 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; 1669 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1627 /* disable interrupt */ 1670 /* disable interrupt */
1628 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par ); 1671 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par);
1629 spin_unlock_irq(&par->int_lock); 1672 spin_unlock_irq(&par->int_lock);
1630 free_irq(par->irq, par); 1673 free_irq(par->irq, par);
1631 } 1674 }
@@ -1636,50 +1679,62 @@ static int aty_disable_irq(struct atyfb_par *par)
1636static int atyfb_release(struct fb_info *info, int user) 1679static int atyfb_release(struct fb_info *info, int user)
1637{ 1680{
1638 struct atyfb_par *par = (struct atyfb_par *) info->par; 1681 struct atyfb_par *par = (struct atyfb_par *) info->par;
1639 if (user) {
1640 par->open--;
1641 mdelay(1);
1642 wait_for_idle(par);
1643 if (!par->open) {
1644#ifdef __sparc__ 1682#ifdef __sparc__
1645 int was_mmaped = par->mmaped; 1683 int was_mmaped;
1684#endif
1646 1685
1647 par->mmaped = 0; 1686 if (!user)
1687 return 0;
1648 1688
1649 if (was_mmaped) { 1689 par->open--;
1650 struct fb_var_screeninfo var; 1690 mdelay(1);
1691 wait_for_idle(par);
1651 1692
1652 /* Now reset the default display config, we have no 1693 if (par->open)
1653 * idea what the program(s) which mmap'd the chip did 1694 return 0;
1654 * to the configuration, nor whether it restored it 1695
1655 * correctly. 1696#ifdef __sparc__
1656 */ 1697 was_mmaped = par->mmaped;
1657 var = default_var; 1698
1658 if (noaccel) 1699 par->mmaped = 0;
1659 var.accel_flags &= ~FB_ACCELF_TEXT; 1700
1660 else 1701 if (was_mmaped) {
1661 var.accel_flags |= FB_ACCELF_TEXT; 1702 struct fb_var_screeninfo var;
1662 if (var.yres == var.yres_virtual) { 1703
1663 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2)); 1704 /*
1664 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual; 1705 * Now reset the default display config, we have
1665 if (var.yres_virtual < var.yres) 1706 * no idea what the program(s) which mmap'd the
1666 var.yres_virtual = var.yres; 1707 * chip did to the configuration, nor whether it
1667 } 1708 * restored it correctly.
1668 } 1709 */
1669#endif 1710 var = default_var;
1670 aty_disable_irq(par); 1711 if (noaccel)
1712 var.accel_flags &= ~FB_ACCELF_TEXT;
1713 else
1714 var.accel_flags |= FB_ACCELF_TEXT;
1715 if (var.yres == var.yres_virtual) {
1716 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
1717 var.yres_virtual =
1718 ((videoram * 8) / var.bits_per_pixel) /
1719 var.xres_virtual;
1720 if (var.yres_virtual < var.yres)
1721 var.yres_virtual = var.yres;
1671 } 1722 }
1672 } 1723 }
1673 return (0); 1724#endif
1725 aty_disable_irq(par);
1726
1727 return 0;
1674} 1728}
1675 1729
1676 /* 1730/*
1677 * Pan or Wrap the Display 1731 * Pan or Wrap the Display
1678 * 1732 *
1679 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag 1733 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1680 */ 1734 */
1681 1735
1682static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 1736static int atyfb_pan_display(struct fb_var_screeninfo *var,
1737 struct fb_info *info)
1683{ 1738{
1684 struct atyfb_par *par = (struct atyfb_par *) info->par; 1739 struct atyfb_par *par = (struct atyfb_par *) info->par;
1685 u32 xres, yres, xoffset, yoffset; 1740 u32 xres, yres, xoffset, yoffset;
@@ -1690,7 +1745,8 @@ static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
1690 yres >>= 1; 1745 yres >>= 1;
1691 xoffset = (var->xoffset + 7) & ~7; 1746 xoffset = (var->xoffset + 7) & ~7;
1692 yoffset = var->yoffset; 1747 yoffset = var->yoffset;
1693 if (xoffset + xres > par->crtc.vxres || yoffset + yres > par->crtc.vyres) 1748 if (xoffset + xres > par->crtc.vxres ||
1749 yoffset + yres > par->crtc.vyres)
1694 return -EINVAL; 1750 return -EINVAL;
1695 info->var.xoffset = xoffset; 1751 info->var.xoffset = xoffset;
1696 info->var.yoffset = yoffset; 1752 info->var.yoffset = yoffset;
@@ -1727,10 +1783,10 @@ static int aty_waitforvblank(struct atyfb_par *par, u32 crtc)
1727 return ret; 1783 return ret;
1728 1784
1729 count = vbl->count; 1785 count = vbl->count;
1730 ret = wait_event_interruptible_timeout(vbl->wait, count != vbl->count, HZ/10); 1786 ret = wait_event_interruptible_timeout(vbl->wait,
1731 if (ret < 0) { 1787 count != vbl->count, HZ/10);
1788 if (ret < 0)
1732 return ret; 1789 return ret;
1733 }
1734 if (ret == 0) { 1790 if (ret == 0) {
1735 aty_enable_irq(par, 1); 1791 aty_enable_irq(par, 1);
1736 return -ETIMEDOUT; 1792 return -ETIMEDOUT;
@@ -1784,7 +1840,8 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
1784 fbtyp.fb_depth = info->var.bits_per_pixel; 1840 fbtyp.fb_depth = info->var.bits_per_pixel;
1785 fbtyp.fb_cmsize = info->cmap.len; 1841 fbtyp.fb_cmsize = info->cmap.len;
1786 fbtyp.fb_size = info->fix.smem_len; 1842 fbtyp.fb_size = info->fix.smem_len;
1787 if (copy_to_user((struct fbtype __user *) arg, &fbtyp, sizeof(fbtyp))) 1843 if (copy_to_user((struct fbtype __user *) arg, &fbtyp,
1844 sizeof(fbtyp)))
1788 return -EFAULT; 1845 return -EFAULT;
1789 break; 1846 break;
1790#endif /* __sparc__ */ 1847#endif /* __sparc__ */
@@ -1804,7 +1861,7 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
1804 case ATYIO_CLKR: 1861 case ATYIO_CLKR:
1805 if (M64_HAS(INTEGRATED)) { 1862 if (M64_HAS(INTEGRATED)) {
1806 struct atyclk clk; 1863 struct atyclk clk;
1807 union aty_pll *pll = &(par->pll); 1864 union aty_pll *pll = &par->pll;
1808 u32 dsp_config = pll->ct.dsp_config; 1865 u32 dsp_config = pll->ct.dsp_config;
1809 u32 dsp_on_off = pll->ct.dsp_on_off; 1866 u32 dsp_on_off = pll->ct.dsp_on_off;
1810 clk.ref_clk_per = par->ref_clk_per; 1867 clk.ref_clk_per = par->ref_clk_per;
@@ -1829,8 +1886,9 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
1829 case ATYIO_CLKW: 1886 case ATYIO_CLKW:
1830 if (M64_HAS(INTEGRATED)) { 1887 if (M64_HAS(INTEGRATED)) {
1831 struct atyclk clk; 1888 struct atyclk clk;
1832 union aty_pll *pll = &(par->pll); 1889 union aty_pll *pll = &par->pll;
1833 if (copy_from_user(&clk, (struct atyclk __user *) arg, sizeof(clk))) 1890 if (copy_from_user(&clk, (struct atyclk __user *) arg,
1891 sizeof(clk)))
1834 return -EFAULT; 1892 return -EFAULT;
1835 par->ref_clk_per = clk.ref_clk_per; 1893 par->ref_clk_per = clk.ref_clk_per;
1836 pll->ct.pll_ref_div = clk.pll_ref_div; 1894 pll->ct.pll_ref_div = clk.pll_ref_div;
@@ -1841,8 +1899,10 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
1841 pll->ct.vclk_fb_div = clk.vclk_fb_div; 1899 pll->ct.vclk_fb_div = clk.vclk_fb_div;
1842 pll->ct.vclk_post_div_real = clk.vclk_post_div; 1900 pll->ct.vclk_post_div_real = clk.vclk_post_div;
1843 pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) | 1901 pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
1844 ((clk.dsp_loop_latency & 0xf)<<16)| ((clk.dsp_precision & 7)<<20); 1902 ((clk.dsp_loop_latency & 0xf) << 16) |
1845 pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | ((clk.dsp_on & 0x7ff)<<16); 1903 ((clk.dsp_precision & 7) << 20);
1904 pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) |
1905 ((clk.dsp_on & 0x7ff) << 16);
1846 /*aty_calc_pll_ct(info, &pll->ct);*/ 1906 /*aty_calc_pll_ct(info, &pll->ct);*/
1847 aty_set_pll_ct(info, pll); 1907 aty_set_pll_ct(info, pll);
1848 } else 1908 } else
@@ -1913,8 +1973,7 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1913 continue; 1973 continue;
1914 1974
1915 map_size = par->mmap_map[i].size - (offset - start); 1975 map_size = par->mmap_map[i].size - (offset - start);
1916 map_offset = 1976 map_offset = par->mmap_map[i].poff + (offset - start);
1917 par->mmap_map[i].poff + (offset - start);
1918 break; 1977 break;
1919 } 1978 }
1920 if (!map_size) { 1979 if (!map_size) {
@@ -1924,8 +1983,7 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1924 if (page + map_size > size) 1983 if (page + map_size > size)
1925 map_size = size - page; 1984 map_size = size - page;
1926 1985
1927 pgprot_val(vma->vm_page_prot) &= 1986 pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask);
1928 ~(par->mmap_map[i].prot_mask);
1929 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag; 1987 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
1930 1988
1931 if (remap_pfn_range(vma, vma->vm_start + page, 1989 if (remap_pfn_range(vma, vma->vm_start + page,
@@ -2029,7 +2087,8 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2029 par->asleep = 1; 2087 par->asleep = 1;
2030 par->lock_blank = 1; 2088 par->lock_blank = 1;
2031 2089
2032 /* Because we may change PCI D state ourselves, we need to 2090 /*
2091 * Because we may change PCI D state ourselves, we need to
2033 * first save the config space content so the core can 2092 * first save the config space content so the core can
2034 * restore it properly on resume. 2093 * restore it properly on resume.
2035 */ 2094 */
@@ -2080,7 +2139,8 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
2080 2139
2081 acquire_console_sem(); 2140 acquire_console_sem();
2082 2141
2083 /* PCI state will have been restored by the core, so 2142 /*
2143 * PCI state will have been restored by the core, so
2084 * we should be in D0 now with our config space fully 2144 * we should be in D0 now with our config space fully
2085 * restored 2145 * restored
2086 */ 2146 */
@@ -2192,8 +2252,8 @@ static void aty_bl_init(struct atyfb_par *par)
2192 2252
2193 info->bl_dev = bd; 2253 info->bl_dev = bd;
2194 fb_bl_default_curve(info, 0, 2254 fb_bl_default_curve(info, 0,
2195 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, 2255 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
2196 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); 2256 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
2197 2257
2198 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 2258 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
2199 bd->props.brightness = bd->props.max_brightness; 2259 bd->props.brightness = bd->props.max_brightness;
@@ -2236,16 +2296,16 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2236 size = ARRAY_SIZE(ragepro_tbl); 2296 size = ARRAY_SIZE(ragepro_tbl);
2237 } 2297 }
2238 2298
2239 for (i=0; i < size; i++) { 2299 for (i = 0; i < size; i++) {
2240 if (xclk < refresh_tbl[i]) 2300 if (xclk < refresh_tbl[i])
2241 break; 2301 break;
2242 } 2302 }
2243 par->mem_refresh_rate = i; 2303 par->mem_refresh_rate = i;
2244} 2304}
2245 2305
2246 /* 2306/*
2247 * Initialisation 2307 * Initialisation
2248 */ 2308 */
2249 2309
2250static struct fb_info *fb_list = NULL; 2310static struct fb_info *fb_list = NULL;
2251 2311
@@ -2375,8 +2435,10 @@ static int __devinit aty_init(struct fb_info *info)
2375 } 2435 }
2376#endif 2436#endif
2377#ifdef CONFIG_PPC_PMAC 2437#ifdef CONFIG_PPC_PMAC
2378 /* The Apple iBook1 uses non-standard memory frequencies. We detect it 2438 /*
2379 * and set the frequency manually. */ 2439 * The Apple iBook1 uses non-standard memory frequencies.
2440 * We detect it and set the frequency manually.
2441 */
2380 if (machine_is_compatible("PowerBook2,1")) { 2442 if (machine_is_compatible("PowerBook2,1")) {
2381 par->pll_limits.mclk = 70; 2443 par->pll_limits.mclk = 70;
2382 par->pll_limits.xclk = 53; 2444 par->pll_limits.xclk = 53;
@@ -2421,13 +2483,14 @@ static int __devinit aty_init(struct fb_info *info)
2421 2483
2422 /* save previous video mode */ 2484 /* save previous video mode */
2423 aty_get_crtc(par, &par->saved_crtc); 2485 aty_get_crtc(par, &par->saved_crtc);
2424 if(par->pll_ops->get_pll) 2486 if (par->pll_ops->get_pll)
2425 par->pll_ops->get_pll(info, &par->saved_pll); 2487 par->pll_ops->get_pll(info, &par->saved_pll);
2426 2488
2427 par->mem_cntl = aty_ld_le32(MEM_CNTL, par); 2489 par->mem_cntl = aty_ld_le32(MEM_CNTL, par);
2428 gtb_memsize = M64_HAS(GTB_DSP); 2490 gtb_memsize = M64_HAS(GTB_DSP);
2429 if (gtb_memsize) 2491 if (gtb_memsize)
2430 switch (par->mem_cntl & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */ 2492 /* 0xF used instead of MEM_SIZE_ALIAS */
2493 switch (par->mem_cntl & 0xF) {
2431 case MEM_SIZE_512K: 2494 case MEM_SIZE_512K:
2432 info->fix.smem_len = 0x80000; 2495 info->fix.smem_len = 0x80000;
2433 break; 2496 break;
@@ -2496,8 +2559,8 @@ static int __devinit aty_init(struct fb_info *info)
2496 } 2559 }
2497 2560
2498 /* 2561 /*
2499 * Reg Block 0 (CT-compatible block) is at mmio_start 2562 * Reg Block 0 (CT-compatible block) is at mmio_start
2500 * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400 2563 * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
2501 */ 2564 */
2502 if (M64_HAS(GX)) { 2565 if (M64_HAS(GX)) {
2503 info->fix.mmio_len = 0x400; 2566 info->fix.mmio_len = 0x400;
@@ -2516,84 +2579,98 @@ static int __devinit aty_init(struct fb_info *info)
2516 } 2579 }
2517 2580
2518 PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n", 2581 PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
2519 info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20), 2582 info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len>>20),
2520 info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max, 2583 info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal,
2521 par->pll_limits.mclk, par->pll_limits.xclk); 2584 par->pll_limits.pll_max, par->pll_limits.mclk,
2585 par->pll_limits.xclk);
2522 2586
2523#if defined(DEBUG) && defined(CONFIG_FB_ATY_CT) 2587#if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
2524 if (M64_HAS(INTEGRATED)) { 2588 if (M64_HAS(INTEGRATED)) {
2525 int i; 2589 int i;
2526 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL " 2590 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL "
2527 "DSP_CONFIG DSP_ON_OFF CLOCK_CNTL\n" 2591 "EXT_MEM_CNTL CRTC_GEN_CNTL DSP_CONFIG "
2528 "debug atyfb: %08x %08x %08x %08x %08x %08x %08x %08x\n" 2592 "DSP_ON_OFF CLOCK_CNTL\n"
2593 "debug atyfb: %08x %08x %08x "
2594 "%08x %08x %08x "
2595 "%08x %08x\n"
2529 "debug atyfb: PLL", 2596 "debug atyfb: PLL",
2530 aty_ld_le32(BUS_CNTL, par), aty_ld_le32(DAC_CNTL, par), 2597 aty_ld_le32(BUS_CNTL, par),
2531 aty_ld_le32(MEM_CNTL, par), aty_ld_le32(EXT_MEM_CNTL, par), 2598 aty_ld_le32(DAC_CNTL, par),
2532 aty_ld_le32(CRTC_GEN_CNTL, par), aty_ld_le32(DSP_CONFIG, par), 2599 aty_ld_le32(MEM_CNTL, par),
2533 aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par)); 2600 aty_ld_le32(EXT_MEM_CNTL, par),
2601 aty_ld_le32(CRTC_GEN_CNTL, par),
2602 aty_ld_le32(DSP_CONFIG, par),
2603 aty_ld_le32(DSP_ON_OFF, par),
2604 aty_ld_le32(CLOCK_CNTL, par));
2534 for (i = 0; i < 40; i++) 2605 for (i = 0; i < 40; i++)
2535 printk(" %02x", aty_ld_pll_ct(i, par)); 2606 printk(" %02x", aty_ld_pll_ct(i, par));
2536 printk("\n"); 2607 printk("\n");
2537 } 2608 }
2538#endif 2609#endif
2539 if(par->pll_ops->init_pll) 2610 if (par->pll_ops->init_pll)
2540 par->pll_ops->init_pll(info, &par->pll); 2611 par->pll_ops->init_pll(info, &par->pll);
2541 if (par->pll_ops->resume_pll) 2612 if (par->pll_ops->resume_pll)
2542 par->pll_ops->resume_pll(info, &par->pll); 2613 par->pll_ops->resume_pll(info, &par->pll);
2543 2614
2544 /* 2615 /*
2545 * Last page of 8 MB (4 MB on ISA) aperture is MMIO, 2616 * Last page of 8 MB (4 MB on ISA) aperture is MMIO,
2546 * unless the auxiliary register aperture is used. 2617 * unless the auxiliary register aperture is used.
2547 */ 2618 */
2548
2549 if (!par->aux_start && 2619 if (!par->aux_start &&
2550 (info->fix.smem_len == 0x800000 || (par->bus_type == ISA && info->fix.smem_len == 0x400000))) 2620 (info->fix.smem_len == 0x800000 ||
2621 (par->bus_type == ISA && info->fix.smem_len == 0x400000)))
2551 info->fix.smem_len -= GUI_RESERVE; 2622 info->fix.smem_len -= GUI_RESERVE;
2552 2623
2553 /* 2624 /*
2554 * Disable register access through the linear aperture 2625 * Disable register access through the linear aperture
2555 * if the auxiliary aperture is used so we can access 2626 * if the auxiliary aperture is used so we can access
2556 * the full 8 MB of video RAM on 8 MB boards. 2627 * the full 8 MB of video RAM on 8 MB boards.
2557 */ 2628 */
2558 if (par->aux_start) 2629 if (par->aux_start)
2559 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par); 2630 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) |
2631 BUS_APER_REG_DIS, par);
2560 2632
2561#ifdef CONFIG_MTRR 2633#ifdef CONFIG_MTRR
2562 par->mtrr_aper = -1; 2634 par->mtrr_aper = -1;
2563 par->mtrr_reg = -1; 2635 par->mtrr_reg = -1;
2564 if (!nomtrr) { 2636 if (!nomtrr) {
2565 /* Cover the whole resource. */ 2637 /* Cover the whole resource. */
2566 par->mtrr_aper = mtrr_add(par->res_start, par->res_size, MTRR_TYPE_WRCOMB, 1); 2638 par->mtrr_aper = mtrr_add(par->res_start, par->res_size,
2567 if (par->mtrr_aper >= 0 && !par->aux_start) { 2639 MTRR_TYPE_WRCOMB, 1);
2640 if (par->mtrr_aper >= 0 && !par->aux_start) {
2568 /* Make a hole for mmio. */ 2641 /* Make a hole for mmio. */
2569 par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - GUI_RESERVE, 2642 par->mtrr_reg = mtrr_add(par->res_start + 0x800000 -
2570 GUI_RESERVE, MTRR_TYPE_UNCACHABLE, 1); 2643 GUI_RESERVE, GUI_RESERVE,
2644 MTRR_TYPE_UNCACHABLE, 1);
2571 if (par->mtrr_reg < 0) { 2645 if (par->mtrr_reg < 0) {
2572 mtrr_del(par->mtrr_aper, 0, 0); 2646 mtrr_del(par->mtrr_aper, 0, 0);
2573 par->mtrr_aper = -1; 2647 par->mtrr_aper = -1;
2574 } 2648 }
2575 } 2649 }
2576 } 2650 }
2577#endif 2651#endif
2578 2652
2579 info->fbops = &atyfb_ops; 2653 info->fbops = &atyfb_ops;
2580 info->pseudo_palette = par->pseudo_palette; 2654 info->pseudo_palette = par->pseudo_palette;
2581 info->flags = FBINFO_DEFAULT | 2655 info->flags = FBINFO_DEFAULT |
2582 FBINFO_HWACCEL_IMAGEBLIT | 2656 FBINFO_HWACCEL_IMAGEBLIT |
2583 FBINFO_HWACCEL_FILLRECT | 2657 FBINFO_HWACCEL_FILLRECT |
2584 FBINFO_HWACCEL_COPYAREA | 2658 FBINFO_HWACCEL_COPYAREA |
2585 FBINFO_HWACCEL_YPAN; 2659 FBINFO_HWACCEL_YPAN;
2586 2660
2587#ifdef CONFIG_PMAC_BACKLIGHT 2661#ifdef CONFIG_PMAC_BACKLIGHT
2588 if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { 2662 if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
2589 /* these bits let the 101 powerbook wake up from sleep -- paulus */ 2663 /*
2590 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) 2664 * these bits let the 101 powerbook
2591 | (USE_F32KHZ | TRISTATE_MEM_EN), par); 2665 * wake up from sleep -- paulus
2666 */
2667 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) |
2668 USE_F32KHZ | TRISTATE_MEM_EN, par);
2592 } else 2669 } else
2593#endif 2670#endif
2594 if (M64_HAS(MOBIL_BUS) && backlight) { 2671 if (M64_HAS(MOBIL_BUS) && backlight) {
2595#ifdef CONFIG_FB_ATY_BACKLIGHT 2672#ifdef CONFIG_FB_ATY_BACKLIGHT
2596 aty_bl_init (par); 2673 aty_bl_init(par);
2597#endif 2674#endif
2598 } 2675 }
2599 2676
@@ -2601,8 +2678,8 @@ static int __devinit aty_init(struct fb_info *info)
2601#ifdef CONFIG_PPC 2678#ifdef CONFIG_PPC
2602 if (machine_is(powermac)) { 2679 if (machine_is(powermac)) {
2603 /* 2680 /*
2604 * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it 2681 * FIXME: The NVRAM stuff should be put in a Mac-specific file,
2605 * applies to all Mac video cards 2682 * as it applies to all Mac video cards
2606 */ 2683 */
2607 if (mode) { 2684 if (mode) {
2608 if (mac_find_mode(&var, info, mode, 8)) 2685 if (mac_find_mode(&var, info, mode, 8))
@@ -2615,8 +2692,7 @@ static int __devinit aty_init(struct fb_info *info)
2615 default_vmode = VMODE_1024_768_60; 2692 default_vmode = VMODE_1024_768_60;
2616 else if (machine_is_compatible("iMac")) 2693 else if (machine_is_compatible("iMac"))
2617 default_vmode = VMODE_1024_768_75; 2694 default_vmode = VMODE_1024_768_75;
2618 else if (machine_is_compatible 2695 else if (machine_is_compatible("PowerBook2,1"))
2619 ("PowerBook2,1"))
2620 /* iBook with 800x600 LCD */ 2696 /* iBook with 800x600 LCD */
2621 default_vmode = VMODE_800_600_60; 2697 default_vmode = VMODE_800_600_60;
2622 else 2698 else
@@ -2630,7 +2706,7 @@ static int __devinit aty_init(struct fb_info *info)
2630 if (default_cmode < CMODE_8 || default_cmode > CMODE_32) 2706 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2631 default_cmode = CMODE_8; 2707 default_cmode = CMODE_8;
2632 if (!mac_vmode_to_var(default_vmode, default_cmode, 2708 if (!mac_vmode_to_var(default_vmode, default_cmode,
2633 &var)) 2709 &var))
2634 has_var = 1; 2710 has_var = 1;
2635 } 2711 }
2636 } 2712 }
@@ -2702,12 +2778,12 @@ aty_init_exit:
2702 2778
2703#ifdef CONFIG_MTRR 2779#ifdef CONFIG_MTRR
2704 if (par->mtrr_reg >= 0) { 2780 if (par->mtrr_reg >= 0) {
2705 mtrr_del(par->mtrr_reg, 0, 0); 2781 mtrr_del(par->mtrr_reg, 0, 0);
2706 par->mtrr_reg = -1; 2782 par->mtrr_reg = -1;
2707 } 2783 }
2708 if (par->mtrr_aper >= 0) { 2784 if (par->mtrr_aper >= 0) {
2709 mtrr_del(par->mtrr_aper, 0, 0); 2785 mtrr_del(par->mtrr_aper, 0, 0);
2710 par->mtrr_aper = -1; 2786 par->mtrr_aper = -1;
2711 } 2787 }
2712#endif 2788#endif
2713 return ret; 2789 return ret;
@@ -2735,18 +2811,18 @@ static int __devinit store_video_par(char *video_str, unsigned char m64_num)
2735 phys_size[m64_num] = size; 2811 phys_size[m64_num] = size;
2736 phys_guiregbase[m64_num] = guiregbase; 2812 phys_guiregbase[m64_num] = guiregbase;
2737 PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size, 2813 PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2738 guiregbase); 2814 guiregbase);
2739 return 0; 2815 return 0;
2740 2816
2741 mach64_invalid: 2817 mach64_invalid:
2742 phys_vmembase[m64_num] = 0; 2818 phys_vmembase[m64_num] = 0;
2743 return -1; 2819 return -1;
2744} 2820}
2745#endif /* CONFIG_ATARI */ 2821#endif /* CONFIG_ATARI */
2746 2822
2747 /* 2823/*
2748 * Blank the display. 2824 * Blank the display.
2749 */ 2825 */
2750 2826
2751static int atyfb_blank(int blank, struct fb_info *info) 2827static int atyfb_blank(int blank, struct fb_info *info)
2752{ 2828{
@@ -2768,20 +2844,20 @@ static int atyfb_blank(int blank, struct fb_info *info)
2768 gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); 2844 gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
2769 gen_cntl &= ~0x400004c; 2845 gen_cntl &= ~0x400004c;
2770 switch (blank) { 2846 switch (blank) {
2771 case FB_BLANK_UNBLANK: 2847 case FB_BLANK_UNBLANK:
2772 break; 2848 break;
2773 case FB_BLANK_NORMAL: 2849 case FB_BLANK_NORMAL:
2774 gen_cntl |= 0x4000040; 2850 gen_cntl |= 0x4000040;
2775 break; 2851 break;
2776 case FB_BLANK_VSYNC_SUSPEND: 2852 case FB_BLANK_VSYNC_SUSPEND:
2777 gen_cntl |= 0x4000048; 2853 gen_cntl |= 0x4000048;
2778 break; 2854 break;
2779 case FB_BLANK_HSYNC_SUSPEND: 2855 case FB_BLANK_HSYNC_SUSPEND:
2780 gen_cntl |= 0x4000044; 2856 gen_cntl |= 0x4000044;
2781 break; 2857 break;
2782 case FB_BLANK_POWERDOWN: 2858 case FB_BLANK_POWERDOWN:
2783 gen_cntl |= 0x400004c; 2859 gen_cntl |= 0x400004c;
2784 break; 2860 break;
2785 } 2861 }
2786 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); 2862 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2787 2863
@@ -2806,15 +2882,15 @@ static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
2806 aty_st_8(DAC_DATA, blue, par); 2882 aty_st_8(DAC_DATA, blue, par);
2807} 2883}
2808 2884
2809 /* 2885/*
2810 * Set a single color register. The values supplied are already 2886 * Set a single color register. The values supplied are already
2811 * rounded down to the hardware's capabilities (according to the 2887 * rounded down to the hardware's capabilities (according to the
2812 * entries in the var structure). Return != 0 for invalid regno. 2888 * entries in the var structure). Return != 0 for invalid regno.
2813 * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR 2889 * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR
2814 */ 2890 */
2815 2891
2816static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 2892static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2817 u_int transp, struct fb_info *info) 2893 u_int transp, struct fb_info *info)
2818{ 2894{
2819 struct atyfb_par *par = (struct atyfb_par *) info->par; 2895 struct atyfb_par *par = (struct atyfb_par *) info->par;
2820 int i, depth; 2896 int i, depth;
@@ -2868,16 +2944,15 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2868 if (depth == 16) { 2944 if (depth == 16) {
2869 if (regno < 32) 2945 if (regno < 32)
2870 aty_st_pal(regno << 3, red, 2946 aty_st_pal(regno << 3, red,
2871 par->palette[regno<<1].green, 2947 par->palette[regno << 1].green,
2872 blue, par); 2948 blue, par);
2873 red = par->palette[regno>>1].red; 2949 red = par->palette[regno >> 1].red;
2874 blue = par->palette[regno>>1].blue; 2950 blue = par->palette[regno >> 1].blue;
2875 regno <<= 2; 2951 regno <<= 2;
2876 } else if (depth == 15) { 2952 } else if (depth == 15) {
2877 regno <<= 3; 2953 regno <<= 3;
2878 for(i = 0; i < 8; i++) { 2954 for (i = 0; i < 8; i++)
2879 aty_st_pal(regno + i, red, green, blue, par); 2955 aty_st_pal(regno + i, red, green, blue, par);
2880 }
2881 } 2956 }
2882 } 2957 }
2883 aty_st_pal(regno, red, green, blue, par); 2958 aty_st_pal(regno, red, green, blue, par);
@@ -2890,7 +2965,8 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2890#ifdef __sparc__ 2965#ifdef __sparc__
2891 2966
2892static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, 2967static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2893 struct fb_info *info, unsigned long addr) 2968 struct fb_info *info,
2969 unsigned long addr)
2894{ 2970{
2895 struct atyfb_par *par = info->par; 2971 struct atyfb_par *par = info->par;
2896 struct device_node *dp; 2972 struct device_node *dp;
@@ -2978,7 +3054,8 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2978 j++; 3054 j++;
2979 } 3055 }
2980 3056
2981 if((ret = correct_chipset(par))) 3057 ret = correct_chipset(par);
3058 if (ret)
2982 return ret; 3059 return ret;
2983 3060
2984 if (IS_XL(pdev->device)) { 3061 if (IS_XL(pdev->device)) {
@@ -3108,28 +3185,28 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3108 u32 driv_inf_tab, sig; 3185 u32 driv_inf_tab, sig;
3109 u16 lcd_ofs; 3186 u16 lcd_ofs;
3110 3187
3111 /* To support an LCD panel, we should know it's dimensions and 3188 /*
3189 * To support an LCD panel, we should know it's dimensions and
3112 * it's desired pixel clock. 3190 * it's desired pixel clock.
3113 * There are two ways to do it: 3191 * There are two ways to do it:
3114 * - Check the startup video mode and calculate the panel 3192 * - Check the startup video mode and calculate the panel
3115 * size from it. This is unreliable. 3193 * size from it. This is unreliable.
3116 * - Read it from the driver information table in the video BIOS. 3194 * - Read it from the driver information table in the video BIOS.
3117 */ 3195 */
3118 /* Address of driver information table is at offset 0x78. */ 3196 /* Address of driver information table is at offset 0x78. */
3119 driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78)); 3197 driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78));
3120 3198
3121 /* Check for the driver information table signature. */ 3199 /* Check for the driver information table signature. */
3122 sig = (*(u32 *)driv_inf_tab); 3200 sig = *(u32 *)driv_inf_tab;
3123 if ((sig == 0x54504c24) || /* Rage LT pro */ 3201 if ((sig == 0x54504c24) || /* Rage LT pro */
3124 (sig == 0x544d5224) || /* Rage mobility */ 3202 (sig == 0x544d5224) || /* Rage mobility */
3125 (sig == 0x54435824) || /* Rage XC */ 3203 (sig == 0x54435824) || /* Rage XC */
3126 (sig == 0x544c5824)) { /* Rage XL */ 3204 (sig == 0x544c5824)) { /* Rage XL */
3127 PRINTKI("BIOS contains driver information table.\n"); 3205 PRINTKI("BIOS contains driver information table.\n");
3128 lcd_ofs = (*(u16 *)(driv_inf_tab + 10)); 3206 lcd_ofs = *(u16 *)(driv_inf_tab + 10);
3129 par->lcd_table = 0; 3207 par->lcd_table = 0;
3130 if (lcd_ofs != 0) { 3208 if (lcd_ofs != 0)
3131 par->lcd_table = bios_base + lcd_ofs; 3209 par->lcd_table = bios_base + lcd_ofs;
3132 }
3133 } 3210 }
3134 3211
3135 if (par->lcd_table != 0) { 3212 if (par->lcd_table != 0) {
@@ -3144,14 +3221,16 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3144 u16 width, height, panel_type, refresh_rates; 3221 u16 width, height, panel_type, refresh_rates;
3145 u16 *lcdmodeptr; 3222 u16 *lcdmodeptr;
3146 u32 format; 3223 u32 format;
3147 u8 lcd_refresh_rates[16] = {50,56,60,67,70,72,75,76,85,90,100,120,140,150,160,200}; 3224 u8 lcd_refresh_rates[16] = { 50, 56, 60, 67, 70, 72, 75, 76, 85,
3148 /* The most important information is the panel size at 3225 90, 100, 120, 140, 150, 160, 200 };
3226 /*
3227 * The most important information is the panel size at
3149 * offset 25 and 27, but there's some other nice information 3228 * offset 25 and 27, but there's some other nice information
3150 * which we print to the screen. 3229 * which we print to the screen.
3151 */ 3230 */
3152 id = *(u8 *)par->lcd_table; 3231 id = *(u8 *)par->lcd_table;
3153 strncpy(model,(char *)par->lcd_table+1,24); 3232 strncpy(model, (char *)par->lcd_table+1, 24);
3154 model[23]=0; 3233 model[23] = 0;
3155 3234
3156 width = par->lcd_width = *(u16 *)(par->lcd_table+25); 3235 width = par->lcd_width = *(u16 *)(par->lcd_table+25);
3157 height = par->lcd_height = *(u16 *)(par->lcd_table+27); 3236 height = par->lcd_height = *(u16 *)(par->lcd_table+27);
@@ -3164,7 +3243,7 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3164 txtdual = "dual (split) "; 3243 txtdual = "dual (split) ";
3165 else 3244 else
3166 txtdual = ""; 3245 txtdual = "";
3167 tech = (panel_type>>2) & 63; 3246 tech = (panel_type >> 2) & 63;
3168 switch (tech) { 3247 switch (tech) {
3169 case 0: 3248 case 0:
3170 txtmonitor = "passive matrix"; 3249 txtmonitor = "passive matrix";
@@ -3224,22 +3303,24 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3224 } 3303 }
3225 } 3304 }
3226 PRINTKI("%s%s %s monitor detected: %s\n", 3305 PRINTKI("%s%s %s monitor detected: %s\n",
3227 txtdual ,txtcolour, txtmonitor, model); 3306 txtdual, txtcolour, txtmonitor, model);
3228 PRINTKI(" id=%d, %dx%d pixels, %s\n", 3307 PRINTKI(" id=%d, %dx%d pixels, %s\n",
3229 id, width, height, txtformat); 3308 id, width, height, txtformat);
3230 refresh_rates_buf[0] = 0; 3309 refresh_rates_buf[0] = 0;
3231 refresh_rates = *(u16 *)(par->lcd_table+62); 3310 refresh_rates = *(u16 *)(par->lcd_table+62);
3232 m = 1; 3311 m = 1;
3233 f = 0; 3312 f = 0;
3234 for (i=0;i<16;i++) { 3313 for (i = 0; i < 16; i++) {
3235 if (refresh_rates & m) { 3314 if (refresh_rates & m) {
3236 if (f == 0) { 3315 if (f == 0) {
3237 sprintf(strbuf, "%d", lcd_refresh_rates[i]); 3316 sprintf(strbuf, "%d",
3317 lcd_refresh_rates[i]);
3238 f++; 3318 f++;
3239 } else { 3319 } else {
3240 sprintf(strbuf, ",%d", lcd_refresh_rates[i]); 3320 sprintf(strbuf, ",%d",
3321 lcd_refresh_rates[i]);
3241 } 3322 }
3242 strcat(refresh_rates_buf,strbuf); 3323 strcat(refresh_rates_buf, strbuf);
3243 } 3324 }
3244 m = m << 1; 3325 m = m << 1;
3245 } 3326 }
@@ -3247,7 +3328,8 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3247 PRINTKI(" supports refresh rates [%s], default %d Hz\n", 3328 PRINTKI(" supports refresh rates [%s], default %d Hz\n",
3248 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); 3329 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
3249 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; 3330 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
3250 /* We now need to determine the crtc parameters for the 3331 /*
3332 * We now need to determine the crtc parameters for the
3251 * LCD monitor. This is tricky, because they are not stored 3333 * LCD monitor. This is tricky, because they are not stored
3252 * individually in the BIOS. Instead, the BIOS contains a 3334 * individually in the BIOS. Instead, the BIOS contains a
3253 * table of display modes that work for this monitor. 3335 * table of display modes that work for this monitor.
@@ -3382,7 +3464,9 @@ static int __devinit init_from_bios(struct atyfb_par *par)
3382} 3464}
3383#endif /* __i386__ */ 3465#endif /* __i386__ */
3384 3466
3385static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, unsigned long addr) 3467static int __devinit atyfb_setup_generic(struct pci_dev *pdev,
3468 struct fb_info *info,
3469 unsigned long addr)
3386{ 3470{
3387 struct atyfb_par *par = info->par; 3471 struct atyfb_par *par = info->par;
3388 u16 tmp; 3472 u16 tmp;
@@ -3429,10 +3513,12 @@ static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *i
3429 goto atyfb_setup_generic_fail; 3513 goto atyfb_setup_generic_fail;
3430 } 3514 }
3431 3515
3432 if((ret = correct_chipset(par))) 3516 ret = correct_chipset(par);
3517 if (ret)
3433 goto atyfb_setup_generic_fail; 3518 goto atyfb_setup_generic_fail;
3434#ifdef __i386__ 3519#ifdef __i386__
3435 if((ret = init_from_bios(par))) 3520 ret = init_from_bios(par);
3521 if (ret)
3436 goto atyfb_setup_generic_fail; 3522 goto atyfb_setup_generic_fail;
3437#endif 3523#endif
3438 if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN)) 3524 if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN))
@@ -3457,7 +3543,8 @@ atyfb_setup_generic_fail:
3457 3543
3458#endif /* !__sparc__ */ 3544#endif /* !__sparc__ */
3459 3545
3460static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3546static int __devinit atyfb_pci_probe(struct pci_dev *pdev,
3547 const struct pci_device_id *ent)
3461{ 3548{
3462 unsigned long addr, res_start, res_size; 3549 unsigned long addr, res_start, res_size;
3463 struct fb_info *info; 3550 struct fb_info *info;
@@ -3482,10 +3569,10 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
3482 /* Reserve space */ 3569 /* Reserve space */
3483 res_start = rp->start; 3570 res_start = rp->start;
3484 res_size = rp->end - rp->start + 1; 3571 res_size = rp->end - rp->start + 1;
3485 if (!request_mem_region (res_start, res_size, "atyfb")) 3572 if (!request_mem_region(res_start, res_size, "atyfb"))
3486 return -EBUSY; 3573 return -EBUSY;
3487 3574
3488 /* Allocate framebuffer */ 3575 /* Allocate framebuffer */
3489 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev); 3576 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
3490 if (!info) { 3577 if (!info) {
3491 PRINTKE("atyfb_pci_probe() can't alloc fb_info\n"); 3578 PRINTKE("atyfb_pci_probe() can't alloc fb_info\n");
@@ -3573,7 +3660,8 @@ static int __init atyfb_atari_probe(void)
3573 for (m64_num = 0; m64_num < mach64_count; m64_num++) { 3660 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
3574 if (!phys_vmembase[m64_num] || !phys_size[m64_num] || 3661 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
3575 !phys_guiregbase[m64_num]) { 3662 !phys_guiregbase[m64_num]) {
3576 PRINTKI("phys_*[%d] parameters not set => returning early. \n", m64_num); 3663 PRINTKI("phys_*[%d] parameters not set => "
3664 "returning early. \n", m64_num);
3577 continue; 3665 continue;
3578 } 3666 }
3579 3667
@@ -3589,8 +3677,8 @@ static int __init atyfb_atari_probe(void)
3589 par->irq = (unsigned int) -1; /* something invalid */ 3677 par->irq = (unsigned int) -1; /* something invalid */
3590 3678
3591 /* 3679 /*
3592 * Map the video memory (physical address given) to somewhere in the 3680 * Map the video memory (physical address given)
3593 * kernel address space. 3681 * to somewhere in the kernel address space.
3594 */ 3682 */
3595 info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]); 3683 info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
3596 info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */ 3684 info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */
@@ -3661,12 +3749,12 @@ static void __devexit atyfb_remove(struct fb_info *info)
3661 3749
3662#ifdef CONFIG_MTRR 3750#ifdef CONFIG_MTRR
3663 if (par->mtrr_reg >= 0) { 3751 if (par->mtrr_reg >= 0) {
3664 mtrr_del(par->mtrr_reg, 0, 0); 3752 mtrr_del(par->mtrr_reg, 0, 0);
3665 par->mtrr_reg = -1; 3753 par->mtrr_reg = -1;
3666 } 3754 }
3667 if (par->mtrr_aper >= 0) { 3755 if (par->mtrr_aper >= 0) {
3668 mtrr_del(par->mtrr_aper, 0, 0); 3756 mtrr_del(par->mtrr_aper, 0, 0);
3669 par->mtrr_aper = -1; 3757 par->mtrr_aper = -1;
3670 } 3758 }
3671#endif 3759#endif
3672#ifndef __sparc__ 3760#ifndef __sparc__
@@ -3900,29 +3988,29 @@ static const struct dmi_system_id atyfb_reboot_ids[] = {
3900 3988
3901static int __init atyfb_init(void) 3989static int __init atyfb_init(void)
3902{ 3990{
3903 int err1 = 1, err2 = 1; 3991 int err1 = 1, err2 = 1;
3904#ifndef MODULE 3992#ifndef MODULE
3905 char *option = NULL; 3993 char *option = NULL;
3906 3994
3907 if (fb_get_options("atyfb", &option)) 3995 if (fb_get_options("atyfb", &option))
3908 return -ENODEV; 3996 return -ENODEV;
3909 atyfb_setup(option); 3997 atyfb_setup(option);
3910#endif 3998#endif
3911 3999
3912#ifdef CONFIG_PCI 4000#ifdef CONFIG_PCI
3913 err1 = pci_register_driver(&atyfb_driver); 4001 err1 = pci_register_driver(&atyfb_driver);
3914#endif 4002#endif
3915#ifdef CONFIG_ATARI 4003#ifdef CONFIG_ATARI
3916 err2 = atyfb_atari_probe(); 4004 err2 = atyfb_atari_probe();
3917#endif 4005#endif
3918 4006
3919 if (err1 && err2) 4007 if (err1 && err2)
3920 return -ENODEV; 4008 return -ENODEV;
3921 4009
3922 if (dmi_check_system(atyfb_reboot_ids)) 4010 if (dmi_check_system(atyfb_reboot_ids))
3923 register_reboot_notifier(&atyfb_reboot_notifier); 4011 register_reboot_notifier(&atyfb_reboot_notifier);
3924 4012
3925 return 0; 4013 return 0;
3926} 4014}
3927 4015
3928static void __exit atyfb_exit(void) 4016static void __exit atyfb_exit(void)
@@ -3951,8 +4039,7 @@ MODULE_PARM_DESC(mclk, "int: override memory clock");
3951module_param(xclk, int, 0); 4039module_param(xclk, int, 0);
3952MODULE_PARM_DESC(xclk, "int: override accelerated engine clock"); 4040MODULE_PARM_DESC(xclk, "int: override accelerated engine clock");
3953module_param(comp_sync, int, 0); 4041module_param(comp_sync, int, 0);
3954MODULE_PARM_DESC(comp_sync, 4042MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)");
3955 "Set composite sync signal to low (0) or high (1)");
3956module_param(mode, charp, 0); 4043module_param(mode, charp, 0);
3957MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); 4044MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
3958#ifdef CONFIG_MTRR 4045#ifdef CONFIG_MTRR
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 378f27745a1d..a699aab63820 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -715,8 +715,11 @@ int au1100fb_setup(char *options)
715 } 715 }
716 /* Mode option (only option that start with digit) */ 716 /* Mode option (only option that start with digit) */
717 else if (isdigit(this_opt[0])) { 717 else if (isdigit(this_opt[0])) {
718 mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL); 718 mode = kstrdup(this_opt, GFP_KERNEL);
719 strncpy(mode, this_opt, strlen(this_opt) + 1); 719 if (!mode) {
720 print_err("memory allocation failed");
721 return -ENOMEM;
722 }
720 } 723 }
721 /* Unsupported option */ 724 /* Unsupported option */
722 else { 725 else {
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index f9d19be05540..09bfa9662e4d 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -31,6 +31,13 @@ config LCD_CORGI
31 Say y here to support the LCD panels usually found on SHARP 31 Say y here to support the LCD panels usually found on SHARP
32 corgi (C7x0) and spitz (Cxx00) models. 32 corgi (C7x0) and spitz (Cxx00) models.
33 33
34config LCD_LMS283GF05
35 tristate "Samsung LMS283GF05 LCD"
36 depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
37 help
38 SPI driver for Samsung LMS283GF05. This provides basic support
39 for powering the LCD up/down through a sysfs interface.
40
34config LCD_LTV350QV 41config LCD_LTV350QV
35 tristate "Samsung LTV350QV LCD Panel" 42 tristate "Samsung LTV350QV LCD Panel"
36 depends on LCD_CLASS_DEVICE && SPI_MASTER 43 depends on LCD_CLASS_DEVICE && SPI_MASTER
@@ -110,7 +117,7 @@ config BACKLIGHT_CLASS_DEVICE
110config BACKLIGHT_ATMEL_LCDC 117config BACKLIGHT_ATMEL_LCDC
111 bool "Atmel LCDC Contrast-as-Backlight control" 118 bool "Atmel LCDC Contrast-as-Backlight control"
112 depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL 119 depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL
113 default y if MACH_SAM9261EK || MACH_SAM9263EK 120 default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK
114 help 121 help
115 This provides a backlight control internal to the Atmel LCDC 122 This provides a backlight control internal to the Atmel LCDC
116 driver. If the LCD "contrast control" on your board is wired 123 driver. If the LCD "contrast control" on your board is wired
@@ -229,3 +236,29 @@ config BACKLIGHT_SAHARA
229 help 236 help
230 If you have a Tabletkiosk Sahara Touch-iT, say y to enable the 237 If you have a Tabletkiosk Sahara Touch-iT, say y to enable the
231 backlight driver. 238 backlight driver.
239
240config BACKLIGHT_WM831X
241 tristate "WM831x PMIC Backlight Driver"
242 depends on BACKLIGHT_CLASS_DEVICE && MFD_WM831X
243 help
244 If you have a backlight driven by the ISINK and DCDC of a
245 WM831x PMIC say y to enable the backlight driver for it.
246
247config BACKLIGHT_ADX
248 tristate "Avionic Design Xanthos Backlight Driver"
249 depends on BACKLIGHT_CLASS_DEVICE && ARCH_PXA_ADX
250 default y
251 help
252 Say Y to enable the backlight driver on Avionic Design Xanthos-based
253 boards.
254
255config BACKLIGHT_ADP5520
256 tristate "Backlight Driver for ADP5520/ADP5501 using WLED"
257 depends on BACKLIGHT_CLASS_DEVICE && PMIC_ADP5520
258 help
259 If you have a LCD backlight connected to the BST/BL_SNK output of
260 ADP5520 or ADP5501, say Y here to enable this driver.
261
262 To compile this driver as a module, choose M here: the module will
263 be called adp5520_bl.
264
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 4eb178c1d684..9a405548874c 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -3,6 +3,7 @@
3obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o 3obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
4obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o 4obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
5obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o 5obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
6obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o
6obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o 7obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
7obj-$(CONFIG_LCD_ILI9320) += ili9320.o 8obj-$(CONFIG_LCD_ILI9320) += ili9320.o
8obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o 9obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
@@ -24,4 +25,7 @@ obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
24obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o 25obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
25obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o 26obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
26obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o 27obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
28obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
29obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o
30obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
27 31
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
new file mode 100644
index 000000000000..ad05da5ba3c7
--- /dev/null
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -0,0 +1,377 @@
1/*
2 * Backlight driver for Analog Devices ADP5520/ADP5501 MFD PMICs
3 *
4 * Copyright 2009 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/platform_device.h>
12#include <linux/fb.h>
13#include <linux/backlight.h>
14#include <linux/mfd/adp5520.h>
15
16struct adp5520_bl {
17 struct device *master;
18 struct adp5520_backlight_platfrom_data *pdata;
19 struct mutex lock;
20 unsigned long cached_daylight_max;
21 int id;
22 int current_brightness;
23};
24
25static int adp5520_bl_set(struct backlight_device *bl, int brightness)
26{
27 struct adp5520_bl *data = bl_get_data(bl);
28 struct device *master = data->master;
29 int ret = 0;
30
31 if (data->pdata->en_ambl_sens) {
32 if ((brightness > 0) && (brightness < ADP5020_MAX_BRIGHTNESS)) {
33 /* Disable Ambient Light auto adjust */
34 ret |= adp5520_clr_bits(master, BL_CONTROL,
35 BL_AUTO_ADJ);
36 ret |= adp5520_write(master, DAYLIGHT_MAX, brightness);
37 } else {
38 /*
39 * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust
40 * restore daylight l3 sysfs brightness
41 */
42 ret |= adp5520_write(master, DAYLIGHT_MAX,
43 data->cached_daylight_max);
44 ret |= adp5520_set_bits(master, BL_CONTROL,
45 BL_AUTO_ADJ);
46 }
47 } else {
48 ret |= adp5520_write(master, DAYLIGHT_MAX, brightness);
49 }
50
51 if (data->current_brightness && brightness == 0)
52 ret |= adp5520_set_bits(master,
53 MODE_STATUS, DIM_EN);
54 else if (data->current_brightness == 0 && brightness)
55 ret |= adp5520_clr_bits(master,
56 MODE_STATUS, DIM_EN);
57
58 if (!ret)
59 data->current_brightness = brightness;
60
61 return ret;
62}
63
64static int adp5520_bl_update_status(struct backlight_device *bl)
65{
66 int brightness = bl->props.brightness;
67 if (bl->props.power != FB_BLANK_UNBLANK)
68 brightness = 0;
69
70 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
71 brightness = 0;
72
73 return adp5520_bl_set(bl, brightness);
74}
75
76static int adp5520_bl_get_brightness(struct backlight_device *bl)
77{
78 struct adp5520_bl *data = bl_get_data(bl);
79 int error;
80 uint8_t reg_val;
81
82 error = adp5520_read(data->master, BL_VALUE, &reg_val);
83
84 return error ? data->current_brightness : reg_val;
85}
86
87static struct backlight_ops adp5520_bl_ops = {
88 .update_status = adp5520_bl_update_status,
89 .get_brightness = adp5520_bl_get_brightness,
90};
91
92static int adp5520_bl_setup(struct backlight_device *bl)
93{
94 struct adp5520_bl *data = bl_get_data(bl);
95 struct device *master = data->master;
96 struct adp5520_backlight_platfrom_data *pdata = data->pdata;
97 int ret = 0;
98
99 ret |= adp5520_write(master, DAYLIGHT_MAX, pdata->l1_daylight_max);
100 ret |= adp5520_write(master, DAYLIGHT_DIM, pdata->l1_daylight_dim);
101
102 if (pdata->en_ambl_sens) {
103 data->cached_daylight_max = pdata->l1_daylight_max;
104 ret |= adp5520_write(master, OFFICE_MAX, pdata->l2_office_max);
105 ret |= adp5520_write(master, OFFICE_DIM, pdata->l2_office_dim);
106 ret |= adp5520_write(master, DARK_MAX, pdata->l3_dark_max);
107 ret |= adp5520_write(master, DARK_DIM, pdata->l3_dark_dim);
108 ret |= adp5520_write(master, L2_TRIP, pdata->l2_trip);
109 ret |= adp5520_write(master, L2_HYS, pdata->l2_hyst);
110 ret |= adp5520_write(master, L3_TRIP, pdata->l3_trip);
111 ret |= adp5520_write(master, L3_HYS, pdata->l3_hyst);
112 ret |= adp5520_write(master, ALS_CMPR_CFG,
113 ALS_CMPR_CFG_VAL(pdata->abml_filt, L3_EN));
114 }
115
116 ret |= adp5520_write(master, BL_CONTROL,
117 BL_CTRL_VAL(pdata->fade_led_law, pdata->en_ambl_sens));
118
119 ret |= adp5520_write(master, BL_FADE, FADE_VAL(pdata->fade_in,
120 pdata->fade_out));
121
122 ret |= adp5520_set_bits(master, MODE_STATUS, BL_EN | DIM_EN);
123
124 return ret;
125}
126
127static ssize_t adp5520_show(struct device *dev, char *buf, int reg)
128{
129 struct adp5520_bl *data = dev_get_drvdata(dev);
130 int error;
131 uint8_t reg_val;
132
133 mutex_lock(&data->lock);
134 error = adp5520_read(data->master, reg, &reg_val);
135 mutex_unlock(&data->lock);
136
137 return sprintf(buf, "%u\n", reg_val);
138}
139
140static ssize_t adp5520_store(struct device *dev, const char *buf,
141 size_t count, int reg)
142{
143 struct adp5520_bl *data = dev_get_drvdata(dev);
144 unsigned long val;
145 int ret;
146
147 ret = strict_strtoul(buf, 10, &val);
148 if (ret)
149 return ret;
150
151 mutex_lock(&data->lock);
152 adp5520_write(data->master, reg, val);
153 mutex_unlock(&data->lock);
154
155 return count;
156}
157
158static ssize_t adp5520_bl_dark_max_show(struct device *dev,
159 struct device_attribute *attr, char *buf)
160{
161 return adp5520_show(dev, buf, DARK_MAX);
162}
163
164static ssize_t adp5520_bl_dark_max_store(struct device *dev,
165 struct device_attribute *attr, const char *buf, size_t count)
166{
167 return adp5520_store(dev, buf, count, DARK_MAX);
168}
169static DEVICE_ATTR(dark_max, 0664, adp5520_bl_dark_max_show,
170 adp5520_bl_dark_max_store);
171
172static ssize_t adp5520_bl_office_max_show(struct device *dev,
173 struct device_attribute *attr, char *buf)
174{
175 return adp5520_show(dev, buf, OFFICE_MAX);
176}
177
178static ssize_t adp5520_bl_office_max_store(struct device *dev,
179 struct device_attribute *attr, const char *buf, size_t count)
180{
181 return adp5520_store(dev, buf, count, OFFICE_MAX);
182}
183static DEVICE_ATTR(office_max, 0664, adp5520_bl_office_max_show,
184 adp5520_bl_office_max_store);
185
186static ssize_t adp5520_bl_daylight_max_show(struct device *dev,
187 struct device_attribute *attr, char *buf)
188{
189 return adp5520_show(dev, buf, DAYLIGHT_MAX);
190}
191
192static ssize_t adp5520_bl_daylight_max_store(struct device *dev,
193 struct device_attribute *attr, const char *buf, size_t count)
194{
195 struct adp5520_bl *data = dev_get_drvdata(dev);
196
197 strict_strtoul(buf, 10, &data->cached_daylight_max);
198 return adp5520_store(dev, buf, count, DAYLIGHT_MAX);
199}
200static DEVICE_ATTR(daylight_max, 0664, adp5520_bl_daylight_max_show,
201 adp5520_bl_daylight_max_store);
202
203static ssize_t adp5520_bl_dark_dim_show(struct device *dev,
204 struct device_attribute *attr, char *buf)
205{
206 return adp5520_show(dev, buf, DARK_DIM);
207}
208
209static ssize_t adp5520_bl_dark_dim_store(struct device *dev,
210 struct device_attribute *attr,
211 const char *buf, size_t count)
212{
213 return adp5520_store(dev, buf, count, DARK_DIM);
214}
215static DEVICE_ATTR(dark_dim, 0664, adp5520_bl_dark_dim_show,
216 adp5520_bl_dark_dim_store);
217
218static ssize_t adp5520_bl_office_dim_show(struct device *dev,
219 struct device_attribute *attr, char *buf)
220{
221 return adp5520_show(dev, buf, OFFICE_DIM);
222}
223
224static ssize_t adp5520_bl_office_dim_store(struct device *dev,
225 struct device_attribute *attr,
226 const char *buf, size_t count)
227{
228 return adp5520_store(dev, buf, count, OFFICE_DIM);
229}
230static DEVICE_ATTR(office_dim, 0664, adp5520_bl_office_dim_show,
231 adp5520_bl_office_dim_store);
232
233static ssize_t adp5520_bl_daylight_dim_show(struct device *dev,
234 struct device_attribute *attr, char *buf)
235{
236 return adp5520_show(dev, buf, DAYLIGHT_DIM);
237}
238
239static ssize_t adp5520_bl_daylight_dim_store(struct device *dev,
240 struct device_attribute *attr,
241 const char *buf, size_t count)
242{
243 return adp5520_store(dev, buf, count, DAYLIGHT_DIM);
244}
245static DEVICE_ATTR(daylight_dim, 0664, adp5520_bl_daylight_dim_show,
246 adp5520_bl_daylight_dim_store);
247
248static struct attribute *adp5520_bl_attributes[] = {
249 &dev_attr_dark_max.attr,
250 &dev_attr_dark_dim.attr,
251 &dev_attr_office_max.attr,
252 &dev_attr_office_dim.attr,
253 &dev_attr_daylight_max.attr,
254 &dev_attr_daylight_dim.attr,
255 NULL
256};
257
258static const struct attribute_group adp5520_bl_attr_group = {
259 .attrs = adp5520_bl_attributes,
260};
261
262static int __devinit adp5520_bl_probe(struct platform_device *pdev)
263{
264 struct backlight_device *bl;
265 struct adp5520_bl *data;
266 int ret = 0;
267
268 data = kzalloc(sizeof(*data), GFP_KERNEL);
269 if (data == NULL)
270 return -ENOMEM;
271
272 data->master = pdev->dev.parent;
273 data->pdata = pdev->dev.platform_data;
274
275 if (data->pdata == NULL) {
276 dev_err(&pdev->dev, "missing platform data\n");
277 kfree(data);
278 return -ENODEV;
279 }
280
281 data->id = pdev->id;
282 data->current_brightness = 0;
283
284 mutex_init(&data->lock);
285
286 bl = backlight_device_register(pdev->name, data->master,
287 data, &adp5520_bl_ops);
288 if (IS_ERR(bl)) {
289 dev_err(&pdev->dev, "failed to register backlight\n");
290 kfree(data);
291 return PTR_ERR(bl);
292 }
293
294 bl->props.max_brightness =
295 bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
296
297 if (data->pdata->en_ambl_sens)
298 ret = sysfs_create_group(&bl->dev.kobj,
299 &adp5520_bl_attr_group);
300
301 if (ret) {
302 dev_err(&pdev->dev, "failed to register sysfs\n");
303 backlight_device_unregister(bl);
304 kfree(data);
305 }
306
307 platform_set_drvdata(pdev, bl);
308 ret |= adp5520_bl_setup(bl);
309 backlight_update_status(bl);
310
311 return ret;
312}
313
314static int __devexit adp5520_bl_remove(struct platform_device *pdev)
315{
316 struct backlight_device *bl = platform_get_drvdata(pdev);
317 struct adp5520_bl *data = bl_get_data(bl);
318
319 adp5520_clr_bits(data->master, MODE_STATUS, BL_EN);
320
321 if (data->pdata->en_ambl_sens)
322 sysfs_remove_group(&bl->dev.kobj,
323 &adp5520_bl_attr_group);
324
325 backlight_device_unregister(bl);
326 kfree(data);
327
328 return 0;
329}
330
331#ifdef CONFIG_PM
332static int adp5520_bl_suspend(struct platform_device *pdev,
333 pm_message_t state)
334{
335 struct backlight_device *bl = platform_get_drvdata(pdev);
336 return adp5520_bl_set(bl, 0);
337}
338
339static int adp5520_bl_resume(struct platform_device *pdev)
340{
341 struct backlight_device *bl = platform_get_drvdata(pdev);
342
343 backlight_update_status(bl);
344 return 0;
345}
346#else
347#define adp5520_bl_suspend NULL
348#define adp5520_bl_resume NULL
349#endif
350
351static struct platform_driver adp5520_bl_driver = {
352 .driver = {
353 .name = "adp5520-backlight",
354 .owner = THIS_MODULE,
355 },
356 .probe = adp5520_bl_probe,
357 .remove = __devexit_p(adp5520_bl_remove),
358 .suspend = adp5520_bl_suspend,
359 .resume = adp5520_bl_resume,
360};
361
362static int __init adp5520_bl_init(void)
363{
364 return platform_driver_register(&adp5520_bl_driver);
365}
366module_init(adp5520_bl_init);
367
368static void __exit adp5520_bl_exit(void)
369{
370 platform_driver_unregister(&adp5520_bl_driver);
371}
372module_exit(adp5520_bl_exit);
373
374MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
375MODULE_DESCRIPTION("ADP5520(01) Backlight Driver");
376MODULE_LICENSE("GPL");
377MODULE_ALIAS("platform:adp5520-backlight");
diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c
new file mode 100644
index 000000000000..2c3bdfc620b7
--- /dev/null
+++ b/drivers/video/backlight/adx_bl.c
@@ -0,0 +1,178 @@
1/*
2 * linux/drivers/video/backlight/adx.c
3 *
4 * Copyright (C) 2009 Avionic Design GmbH
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Written by Thierry Reding <thierry.reding@avionic-design.de>
11 */
12
13#include <linux/backlight.h>
14#include <linux/fb.h>
15#include <linux/io.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18
19/* register definitions */
20#define ADX_BACKLIGHT_CONTROL 0x00
21#define ADX_BACKLIGHT_CONTROL_ENABLE (1 << 0)
22#define ADX_BACKLIGHT_BRIGHTNESS 0x08
23#define ADX_BACKLIGHT_STATUS 0x10
24#define ADX_BACKLIGHT_ERROR 0x18
25
26struct adxbl {
27 void __iomem *base;
28};
29
30static int adx_backlight_update_status(struct backlight_device *bldev)
31{
32 struct adxbl *bl = bl_get_data(bldev);
33 u32 value;
34
35 value = bldev->props.brightness;
36 writel(value, bl->base + ADX_BACKLIGHT_BRIGHTNESS);
37
38 value = readl(bl->base + ADX_BACKLIGHT_CONTROL);
39
40 if (bldev->props.state & BL_CORE_FBBLANK)
41 value &= ~ADX_BACKLIGHT_CONTROL_ENABLE;
42 else
43 value |= ADX_BACKLIGHT_CONTROL_ENABLE;
44
45 writel(value, bl->base + ADX_BACKLIGHT_CONTROL);
46
47 return 0;
48}
49
50static int adx_backlight_get_brightness(struct backlight_device *bldev)
51{
52 struct adxbl *bl = bl_get_data(bldev);
53 u32 brightness;
54
55 brightness = readl(bl->base + ADX_BACKLIGHT_BRIGHTNESS);
56 return brightness & 0xff;
57}
58
59static int adx_backlight_check_fb(struct fb_info *fb)
60{
61 return 1;
62}
63
64static struct backlight_ops adx_backlight_ops = {
65 .options = 0,
66 .update_status = adx_backlight_update_status,
67 .get_brightness = adx_backlight_get_brightness,
68 .check_fb = adx_backlight_check_fb,
69};
70
71static int __devinit adx_backlight_probe(struct platform_device *pdev)
72{
73 struct backlight_device *bldev;
74 struct resource *res;
75 struct adxbl *bl;
76 int ret = 0;
77
78 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
79 if (!res) {
80 ret = -ENXIO;
81 goto out;
82 }
83
84 res = devm_request_mem_region(&pdev->dev, res->start,
85 resource_size(res), res->name);
86 if (!res) {
87 ret = -ENXIO;
88 goto out;
89 }
90
91 bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL);
92 if (!bl) {
93 ret = -ENOMEM;
94 goto out;
95 }
96
97 bl->base = devm_ioremap_nocache(&pdev->dev, res->start,
98 resource_size(res));
99 if (!bl->base) {
100 ret = -ENXIO;
101 goto out;
102 }
103
104 bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl,
105 &adx_backlight_ops);
106 if (!bldev) {
107 ret = -ENOMEM;
108 goto out;
109 }
110
111 bldev->props.max_brightness = 0xff;
112 bldev->props.brightness = 0xff;
113 bldev->props.power = FB_BLANK_UNBLANK;
114
115 platform_set_drvdata(pdev, bldev);
116
117out:
118 return ret;
119}
120
121static int __devexit adx_backlight_remove(struct platform_device *pdev)
122{
123 struct backlight_device *bldev;
124 int ret = 0;
125
126 bldev = platform_get_drvdata(pdev);
127 bldev->props.power = FB_BLANK_UNBLANK;
128 bldev->props.brightness = 0xff;
129 backlight_update_status(bldev);
130 backlight_device_unregister(bldev);
131 platform_set_drvdata(pdev, NULL);
132
133 return ret;
134}
135
136#ifdef CONFIG_PM
137static int adx_backlight_suspend(struct platform_device *pdev,
138 pm_message_t state)
139{
140 return 0;
141}
142
143static int adx_backlight_resume(struct platform_device *pdev)
144{
145 return 0;
146}
147#else
148#define adx_backlight_suspend NULL
149#define adx_backlight_resume NULL
150#endif
151
152static struct platform_driver adx_backlight_driver = {
153 .probe = adx_backlight_probe,
154 .remove = __devexit_p(adx_backlight_remove),
155 .suspend = adx_backlight_suspend,
156 .resume = adx_backlight_resume,
157 .driver = {
158 .name = "adx-backlight",
159 .owner = THIS_MODULE,
160 },
161};
162
163static int __init adx_backlight_init(void)
164{
165 return platform_driver_register(&adx_backlight_driver);
166}
167
168static void __exit adx_backlight_exit(void)
169{
170 platform_driver_unregister(&adx_backlight_driver);
171}
172
173module_init(adx_backlight_init);
174module_exit(adx_backlight_exit);
175
176MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
177MODULE_DESCRIPTION("Avionic Design Xanthos Backlight Driver");
178MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 157057c79ca3..6615ac7fa60a 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -73,6 +73,27 @@ static inline void backlight_unregister_fb(struct backlight_device *bd)
73} 73}
74#endif /* CONFIG_FB */ 74#endif /* CONFIG_FB */
75 75
76static void backlight_generate_event(struct backlight_device *bd,
77 enum backlight_update_reason reason)
78{
79 char *envp[2];
80
81 switch (reason) {
82 case BACKLIGHT_UPDATE_SYSFS:
83 envp[0] = "SOURCE=sysfs";
84 break;
85 case BACKLIGHT_UPDATE_HOTKEY:
86 envp[0] = "SOURCE=hotkey";
87 break;
88 default:
89 envp[0] = "SOURCE=unknown";
90 break;
91 }
92 envp[1] = NULL;
93 kobject_uevent_env(&bd->dev.kobj, KOBJ_CHANGE, envp);
94 sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness");
95}
96
76static ssize_t backlight_show_power(struct device *dev, 97static ssize_t backlight_show_power(struct device *dev,
77 struct device_attribute *attr,char *buf) 98 struct device_attribute *attr,char *buf)
78{ 99{
@@ -142,6 +163,8 @@ static ssize_t backlight_store_brightness(struct device *dev,
142 } 163 }
143 mutex_unlock(&bd->ops_lock); 164 mutex_unlock(&bd->ops_lock);
144 165
166 backlight_generate_event(bd, BACKLIGHT_UPDATE_SYSFS);
167
145 return rc; 168 return rc;
146} 169}
147 170
@@ -214,6 +237,25 @@ static struct device_attribute bl_device_attributes[] = {
214}; 237};
215 238
216/** 239/**
240 * backlight_force_update - tell the backlight subsystem that hardware state
241 * has changed
242 * @bd: the backlight device to update
243 *
244 * Updates the internal state of the backlight in response to a hardware event,
245 * and generate a uevent to notify userspace
246 */
247void backlight_force_update(struct backlight_device *bd,
248 enum backlight_update_reason reason)
249{
250 mutex_lock(&bd->ops_lock);
251 if (bd->ops && bd->ops->get_brightness)
252 bd->props.brightness = bd->ops->get_brightness(bd);
253 mutex_unlock(&bd->ops_lock);
254 backlight_generate_event(bd, reason);
255}
256EXPORT_SYMBOL(backlight_force_update);
257
258/**
217 * backlight_device_register - create and register a new object of 259 * backlight_device_register - create and register a new object of
218 * backlight_device class. 260 * backlight_device class.
219 * @name: the name of the new object(must be the same as the name of the 261 * @name: the name of the new object(must be the same as the name of the
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index f8a4bb20f41a..2211a852af9c 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -639,3 +639,4 @@ module_exit(corgi_lcd_exit);
639MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00"); 639MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00");
640MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); 640MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
641MODULE_LICENSE("GPL"); 641MODULE_LICENSE("GPL");
642MODULE_ALIAS("spi:corgi-lcd");
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index 93bb4340cc64..701a1081e199 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -154,34 +154,38 @@ static int da903x_backlight_remove(struct platform_device *pdev)
154} 154}
155 155
156#ifdef CONFIG_PM 156#ifdef CONFIG_PM
157static int da903x_backlight_suspend(struct platform_device *pdev, 157static int da903x_backlight_suspend(struct device *dev)
158 pm_message_t state)
159{ 158{
159 struct platform_device *pdev = to_platform_device(dev);
160 struct backlight_device *bl = platform_get_drvdata(pdev); 160 struct backlight_device *bl = platform_get_drvdata(pdev);
161 return da903x_backlight_set(bl, 0); 161 return da903x_backlight_set(bl, 0);
162} 162}
163 163
164static int da903x_backlight_resume(struct platform_device *pdev) 164static int da903x_backlight_resume(struct device *dev)
165{ 165{
166 struct platform_device *pdev = to_platform_device(dev);
166 struct backlight_device *bl = platform_get_drvdata(pdev); 167 struct backlight_device *bl = platform_get_drvdata(pdev);
167 168
168 backlight_update_status(bl); 169 backlight_update_status(bl);
169 return 0; 170 return 0;
170} 171}
171#else 172
172#define da903x_backlight_suspend NULL 173static struct dev_pm_ops da903x_backlight_pm_ops = {
173#define da903x_backlight_resume NULL 174 .suspend = da903x_backlight_suspend,
175 .resume = da903x_backlight_resume,
176};
174#endif 177#endif
175 178
176static struct platform_driver da903x_backlight_driver = { 179static struct platform_driver da903x_backlight_driver = {
177 .driver = { 180 .driver = {
178 .name = "da903x-backlight", 181 .name = "da903x-backlight",
179 .owner = THIS_MODULE, 182 .owner = THIS_MODULE,
183#ifdef CONFIG_PM
184 .pm = &da903x_backlight_pm_ops,
185#endif
180 }, 186 },
181 .probe = da903x_backlight_probe, 187 .probe = da903x_backlight_probe,
182 .remove = da903x_backlight_remove, 188 .remove = da903x_backlight_remove,
183 .suspend = da903x_backlight_suspend,
184 .resume = da903x_backlight_resume,
185}; 189};
186 190
187static int __init da903x_backlight_init(void) 191static int __init da903x_backlight_init(void)
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 5be55a20d8c7..7fb4eefff80d 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -103,7 +103,7 @@ static struct backlight_ops hp680bl_ops = {
103 .update_status = hp680bl_set_intensity, 103 .update_status = hp680bl_set_intensity,
104}; 104};
105 105
106static int __init hp680bl_probe(struct platform_device *pdev) 106static int __devinit hp680bl_probe(struct platform_device *pdev)
107{ 107{
108 struct backlight_device *bd; 108 struct backlight_device *bd;
109 109
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c
new file mode 100644
index 000000000000..447b542a20ca
--- /dev/null
+++ b/drivers/video/backlight/lms283gf05.c
@@ -0,0 +1,242 @@
1/*
2 * lms283gf05.c -- support for Samsung LMS283GF05 LCD
3 *
4 * Copyright (c) 2009 Marek Vasut <marek.vasut@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/device.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/gpio.h>
15#include <linux/lcd.h>
16
17#include <linux/spi/spi.h>
18#include <linux/spi/lms283gf05.h>
19
20struct lms283gf05_state {
21 struct spi_device *spi;
22 struct lcd_device *ld;
23};
24
25struct lms283gf05_seq {
26 unsigned char reg;
27 unsigned short value;
28 unsigned char delay;
29};
30
31/* Magic sequences supplied by manufacturer, for details refer to datasheet */
32static struct lms283gf05_seq disp_initseq[] = {
33 /* REG, VALUE, DELAY */
34 { 0x07, 0x0000, 0 },
35 { 0x13, 0x0000, 10 },
36
37 { 0x11, 0x3004, 0 },
38 { 0x14, 0x200F, 0 },
39 { 0x10, 0x1a20, 0 },
40 { 0x13, 0x0040, 50 },
41
42 { 0x13, 0x0060, 0 },
43 { 0x13, 0x0070, 200 },
44
45 { 0x01, 0x0127, 0 },
46 { 0x02, 0x0700, 0 },
47 { 0x03, 0x1030, 0 },
48 { 0x08, 0x0208, 0 },
49 { 0x0B, 0x0620, 0 },
50 { 0x0C, 0x0110, 0 },
51 { 0x30, 0x0120, 0 },
52 { 0x31, 0x0127, 0 },
53 { 0x32, 0x0000, 0 },
54 { 0x33, 0x0503, 0 },
55 { 0x34, 0x0727, 0 },
56 { 0x35, 0x0124, 0 },
57 { 0x36, 0x0706, 0 },
58 { 0x37, 0x0701, 0 },
59 { 0x38, 0x0F00, 0 },
60 { 0x39, 0x0F00, 0 },
61 { 0x40, 0x0000, 0 },
62 { 0x41, 0x0000, 0 },
63 { 0x42, 0x013f, 0 },
64 { 0x43, 0x0000, 0 },
65 { 0x44, 0x013f, 0 },
66 { 0x45, 0x0000, 0 },
67 { 0x46, 0xef00, 0 },
68 { 0x47, 0x013f, 0 },
69 { 0x48, 0x0000, 0 },
70 { 0x07, 0x0015, 30 },
71
72 { 0x07, 0x0017, 0 },
73
74 { 0x20, 0x0000, 0 },
75 { 0x21, 0x0000, 0 },
76 { 0x22, 0x0000, 0 }
77};
78
79static struct lms283gf05_seq disp_pdwnseq[] = {
80 { 0x07, 0x0016, 30 },
81
82 { 0x07, 0x0004, 0 },
83 { 0x10, 0x0220, 20 },
84
85 { 0x13, 0x0060, 50 },
86
87 { 0x13, 0x0040, 50 },
88
89 { 0x13, 0x0000, 0 },
90 { 0x10, 0x0000, 0 }
91};
92
93
94static void lms283gf05_reset(unsigned long gpio, bool inverted)
95{
96 gpio_set_value(gpio, !inverted);
97 mdelay(100);
98 gpio_set_value(gpio, inverted);
99 mdelay(20);
100 gpio_set_value(gpio, !inverted);
101 mdelay(20);
102}
103
104static void lms283gf05_toggle(struct spi_device *spi,
105 struct lms283gf05_seq *seq, int sz)
106{
107 char buf[3];
108 int i;
109
110 for (i = 0; i < sz; i++) {
111 buf[0] = 0x74;
112 buf[1] = 0x00;
113 buf[2] = seq[i].reg;
114 spi_write(spi, buf, 3);
115
116 buf[0] = 0x76;
117 buf[1] = seq[i].value >> 8;
118 buf[2] = seq[i].value & 0xff;
119 spi_write(spi, buf, 3);
120
121 mdelay(seq[i].delay);
122 }
123}
124
125static int lms283gf05_power_set(struct lcd_device *ld, int power)
126{
127 struct lms283gf05_state *st = lcd_get_data(ld);
128 struct spi_device *spi = st->spi;
129 struct lms283gf05_pdata *pdata = spi->dev.platform_data;
130
131 if (power) {
132 if (pdata)
133 lms283gf05_reset(pdata->reset_gpio,
134 pdata->reset_inverted);
135 lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq));
136 } else {
137 lms283gf05_toggle(spi, disp_pdwnseq, ARRAY_SIZE(disp_pdwnseq));
138 if (pdata)
139 gpio_set_value(pdata->reset_gpio,
140 pdata->reset_inverted);
141 }
142
143 return 0;
144}
145
146static struct lcd_ops lms_ops = {
147 .set_power = lms283gf05_power_set,
148 .get_power = NULL,
149};
150
151static int __devinit lms283gf05_probe(struct spi_device *spi)
152{
153 struct lms283gf05_state *st;
154 struct lms283gf05_pdata *pdata = spi->dev.platform_data;
155 struct lcd_device *ld;
156 int ret = 0;
157
158 if (pdata != NULL) {
159 ret = gpio_request(pdata->reset_gpio, "LMS285GF05 RESET");
160 if (ret)
161 return ret;
162
163 ret = gpio_direction_output(pdata->reset_gpio,
164 !pdata->reset_inverted);
165 if (ret)
166 goto err;
167 }
168
169 st = kzalloc(sizeof(struct lms283gf05_state), GFP_KERNEL);
170 if (st == NULL) {
171 dev_err(&spi->dev, "No memory for device state\n");
172 ret = -ENOMEM;
173 goto err;
174 }
175
176 ld = lcd_device_register("lms283gf05", &spi->dev, st, &lms_ops);
177 if (IS_ERR(ld)) {
178 ret = PTR_ERR(ld);
179 goto err2;
180 }
181
182 st->spi = spi;
183 st->ld = ld;
184
185 dev_set_drvdata(&spi->dev, st);
186
187 /* kick in the LCD */
188 if (pdata)
189 lms283gf05_reset(pdata->reset_gpio, pdata->reset_inverted);
190 lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq));
191
192 return 0;
193
194err2:
195 kfree(st);
196err:
197 if (pdata != NULL)
198 gpio_free(pdata->reset_gpio);
199
200 return ret;
201}
202
203static int __devexit lms283gf05_remove(struct spi_device *spi)
204{
205 struct lms283gf05_state *st = dev_get_drvdata(&spi->dev);
206 struct lms283gf05_pdata *pdata = st->spi->dev.platform_data;
207
208 lcd_device_unregister(st->ld);
209
210 if (pdata != NULL)
211 gpio_free(pdata->reset_gpio);
212
213 kfree(st);
214
215 return 0;
216}
217
218static struct spi_driver lms283gf05_driver = {
219 .driver = {
220 .name = "lms283gf05",
221 .owner = THIS_MODULE,
222 },
223 .probe = lms283gf05_probe,
224 .remove = __devexit_p(lms283gf05_remove),
225};
226
227static __init int lms283gf05_init(void)
228{
229 return spi_register_driver(&lms283gf05_driver);
230}
231
232static __exit void lms283gf05_exit(void)
233{
234 spi_unregister_driver(&lms283gf05_driver);
235}
236
237module_init(lms283gf05_init);
238module_exit(lms283gf05_exit);
239
240MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
241MODULE_DESCRIPTION("LCD283GF05 LCD");
242MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index 2eb206bf73e6..4631ca8fa4a4 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -328,3 +328,4 @@ module_exit(ltv350qv_exit);
328MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); 328MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
329MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver"); 329MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver");
330MODULE_LICENSE("GPL"); 330MODULE_LICENSE("GPL");
331MODULE_ALIAS("spi:ltv350qv");
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
index 3bb4c0a50c62..9edb8d7c295f 100644
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -166,6 +166,15 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
166 }, 166 },
167 { 167 {
168 .callback = mbp_dmi_match, 168 .callback = mbp_dmi_match,
169 .ident = "MacBookAir 1,1",
170 .matches = {
171 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
172 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir1,1"),
173 },
174 .driver_data = (void *)&intel_chipset_data,
175 },
176 {
177 .callback = mbp_dmi_match,
169 .ident = "MacBook 5,1", 178 .ident = "MacBook 5,1",
170 .matches = { 179 .matches = {
171 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 180 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
@@ -175,6 +184,15 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
175 }, 184 },
176 { 185 {
177 .callback = mbp_dmi_match, 186 .callback = mbp_dmi_match,
187 .ident = "MacBook 5,2",
188 .matches = {
189 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
190 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"),
191 },
192 .driver_data = (void *)&nvidia_chipset_data,
193 },
194 {
195 .callback = mbp_dmi_match,
178 .ident = "MacBookAir 2,1", 196 .ident = "MacBookAir 2,1",
179 .matches = { 197 .matches = {
180 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 198 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
@@ -191,6 +209,24 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
191 }, 209 },
192 .driver_data = (void *)&nvidia_chipset_data, 210 .driver_data = (void *)&nvidia_chipset_data,
193 }, 211 },
212 {
213 .callback = mbp_dmi_match,
214 .ident = "MacBookPro 5,2",
215 .matches = {
216 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
217 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,2"),
218 },
219 .driver_data = (void *)&nvidia_chipset_data,
220 },
221 {
222 .callback = mbp_dmi_match,
223 .ident = "MacBookPro 5,5",
224 .matches = {
225 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
226 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,5"),
227 },
228 .driver_data = (void *)&nvidia_chipset_data,
229 },
194 { } 230 { }
195}; 231};
196 232
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c
index 51422fc4f606..bbfb502add67 100644
--- a/drivers/video/backlight/tdo24m.c
+++ b/drivers/video/backlight/tdo24m.c
@@ -472,3 +472,4 @@ module_exit(tdo24m_exit);
472MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); 472MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
473MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel"); 473MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel");
474MODULE_LICENSE("GPL"); 474MODULE_LICENSE("GPL");
475MODULE_ALIAS("spi:tdo24m");
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c
index b7fbc75a62fc..50ec17dfc517 100644
--- a/drivers/video/backlight/tosa_lcd.c
+++ b/drivers/video/backlight/tosa_lcd.c
@@ -300,4 +300,4 @@ module_exit(tosa_lcd_exit);
300MODULE_AUTHOR("Dmitry Baryshkov"); 300MODULE_AUTHOR("Dmitry Baryshkov");
301MODULE_LICENSE("GPL v2"); 301MODULE_LICENSE("GPL v2");
302MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); 302MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA");
303 303MODULE_ALIAS("spi:tosa-lcd");
diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c
index 8e653b8a6f17..b49063c831e7 100644
--- a/drivers/video/backlight/vgg2432a4.c
+++ b/drivers/video/backlight/vgg2432a4.c
@@ -280,5 +280,4 @@ module_exit(vgg2432a4_exit);
280MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>"); 280MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
281MODULE_DESCRIPTION("VGG2432A4 LCD Driver"); 281MODULE_DESCRIPTION("VGG2432A4 LCD Driver");
282MODULE_LICENSE("GPL v2"); 282MODULE_LICENSE("GPL v2");
283 283MODULE_ALIAS("spi:VGG2432A4");
284
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
new file mode 100644
index 000000000000..467bdb7efb23
--- /dev/null
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -0,0 +1,250 @@
1/*
2 * Backlight driver for Wolfson Microelectronics WM831x PMICs
3 *
4 * Copyright 2009 Wolfson Microelectonics plc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/fb.h>
15#include <linux/backlight.h>
16
17#include <linux/mfd/wm831x/core.h>
18#include <linux/mfd/wm831x/pdata.h>
19#include <linux/mfd/wm831x/regulator.h>
20
21struct wm831x_backlight_data {
22 struct wm831x *wm831x;
23 int isink_reg;
24 int current_brightness;
25};
26
27static int wm831x_backlight_set(struct backlight_device *bl, int brightness)
28{
29 struct wm831x_backlight_data *data = bl_get_data(bl);
30 struct wm831x *wm831x = data->wm831x;
31 int power_up = !data->current_brightness && brightness;
32 int power_down = data->current_brightness && !brightness;
33 int ret;
34
35 if (power_up) {
36 /* Enable the ISINK */
37 ret = wm831x_set_bits(wm831x, data->isink_reg,
38 WM831X_CS1_ENA, WM831X_CS1_ENA);
39 if (ret < 0)
40 goto err;
41
42 /* Enable the DC-DC */
43 ret = wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE,
44 WM831X_DC4_ENA, WM831X_DC4_ENA);
45 if (ret < 0)
46 goto err;
47 }
48
49 if (power_down) {
50 /* DCDC first */
51 ret = wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE,
52 WM831X_DC4_ENA, 0);
53 if (ret < 0)
54 goto err;
55
56 /* ISINK */
57 ret = wm831x_set_bits(wm831x, data->isink_reg,
58 WM831X_CS1_DRIVE | WM831X_CS1_ENA, 0);
59 if (ret < 0)
60 goto err;
61 }
62
63 /* Set the new brightness */
64 ret = wm831x_set_bits(wm831x, data->isink_reg,
65 WM831X_CS1_ISEL_MASK, brightness);
66 if (ret < 0)
67 goto err;
68
69 if (power_up) {
70 /* Drive current through the ISINK */
71 ret = wm831x_set_bits(wm831x, data->isink_reg,
72 WM831X_CS1_DRIVE, WM831X_CS1_DRIVE);
73 if (ret < 0)
74 return ret;
75 }
76
77 data->current_brightness = brightness;
78
79 return 0;
80
81err:
82 /* If we were in the middle of a power transition always shut down
83 * for safety.
84 */
85 if (power_up || power_down) {
86 wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0);
87 wm831x_set_bits(wm831x, data->isink_reg, WM831X_CS1_ENA, 0);
88 }
89
90 return ret;
91}
92
93static int wm831x_backlight_update_status(struct backlight_device *bl)
94{
95 int brightness = bl->props.brightness;
96
97 if (bl->props.power != FB_BLANK_UNBLANK)
98 brightness = 0;
99
100 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
101 brightness = 0;
102
103 if (bl->props.state & BL_CORE_SUSPENDED)
104 brightness = 0;
105
106 return wm831x_backlight_set(bl, brightness);
107}
108
109static int wm831x_backlight_get_brightness(struct backlight_device *bl)
110{
111 struct wm831x_backlight_data *data = bl_get_data(bl);
112 return data->current_brightness;
113}
114
115static struct backlight_ops wm831x_backlight_ops = {
116 .options = BL_CORE_SUSPENDRESUME,
117 .update_status = wm831x_backlight_update_status,
118 .get_brightness = wm831x_backlight_get_brightness,
119};
120
121static int wm831x_backlight_probe(struct platform_device *pdev)
122{
123 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
124 struct wm831x_pdata *wm831x_pdata;
125 struct wm831x_backlight_pdata *pdata;
126 struct wm831x_backlight_data *data;
127 struct backlight_device *bl;
128 int ret, i, max_isel, isink_reg, dcdc_cfg;
129
130 /* We need platform data */
131 if (pdev->dev.parent->platform_data) {
132 wm831x_pdata = pdev->dev.parent->platform_data;
133 pdata = wm831x_pdata->backlight;
134 } else {
135 pdata = NULL;
136 }
137
138 if (!pdata) {
139 dev_err(&pdev->dev, "No platform data supplied\n");
140 return -EINVAL;
141 }
142
143 /* Figure out the maximum current we can use */
144 for (i = 0; i < WM831X_ISINK_MAX_ISEL; i++) {
145 if (wm831x_isinkv_values[i] > pdata->max_uA)
146 break;
147 }
148
149 if (i == 0) {
150 dev_err(&pdev->dev, "Invalid max_uA: %duA\n", pdata->max_uA);
151 return -EINVAL;
152 }
153 max_isel = i - 1;
154
155 if (pdata->max_uA != wm831x_isinkv_values[max_isel])
156 dev_warn(&pdev->dev,
157 "Maximum current is %duA not %duA as requested\n",
158 wm831x_isinkv_values[max_isel], pdata->max_uA);
159
160 switch (pdata->isink) {
161 case 1:
162 isink_reg = WM831X_CURRENT_SINK_1;
163 dcdc_cfg = 0;
164 break;
165 case 2:
166 isink_reg = WM831X_CURRENT_SINK_2;
167 dcdc_cfg = WM831X_DC4_FBSRC;
168 break;
169 default:
170 dev_err(&pdev->dev, "Invalid ISINK %d\n", pdata->isink);
171 return -EINVAL;
172 }
173
174 /* Configure the ISINK to use for feedback */
175 ret = wm831x_reg_unlock(wm831x);
176 if (ret < 0)
177 return ret;
178
179 ret = wm831x_set_bits(wm831x, WM831X_DC4_CONTROL, WM831X_DC4_FBSRC,
180 dcdc_cfg);
181
182 wm831x_reg_lock(wm831x);
183 if (ret < 0)
184 return ret;
185
186 data = kzalloc(sizeof(*data), GFP_KERNEL);
187 if (data == NULL)
188 return -ENOMEM;
189
190 data->wm831x = wm831x;
191 data->current_brightness = 0;
192 data->isink_reg = isink_reg;
193
194 bl = backlight_device_register("wm831x", &pdev->dev,
195 data, &wm831x_backlight_ops);
196 if (IS_ERR(bl)) {
197 dev_err(&pdev->dev, "failed to register backlight\n");
198 kfree(data);
199 return PTR_ERR(bl);
200 }
201
202 bl->props.max_brightness = max_isel;
203 bl->props.brightness = max_isel;
204
205 platform_set_drvdata(pdev, bl);
206
207 /* Disable the DCDC if it was started so we can bootstrap */
208 wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0);
209
210
211 backlight_update_status(bl);
212
213 return 0;
214}
215
216static int wm831x_backlight_remove(struct platform_device *pdev)
217{
218 struct backlight_device *bl = platform_get_drvdata(pdev);
219 struct wm831x_backlight_data *data = bl_get_data(bl);
220
221 backlight_device_unregister(bl);
222 kfree(data);
223 return 0;
224}
225
226static struct platform_driver wm831x_backlight_driver = {
227 .driver = {
228 .name = "wm831x-backlight",
229 .owner = THIS_MODULE,
230 },
231 .probe = wm831x_backlight_probe,
232 .remove = wm831x_backlight_remove,
233};
234
235static int __init wm831x_backlight_init(void)
236{
237 return platform_driver_register(&wm831x_backlight_driver);
238}
239module_init(wm831x_backlight_init);
240
241static void __exit wm831x_backlight_exit(void)
242{
243 platform_driver_unregister(&wm831x_backlight_driver);
244}
245module_exit(wm831x_backlight_exit);
246
247MODULE_DESCRIPTION("Backlight Driver for WM831x PMICs");
248MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com");
249MODULE_LICENSE("GPL");
250MODULE_ALIAS("platform:wm831x-backlight");
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index df03f3776dcc..79e5f40e6486 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -114,7 +114,7 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
114 d0 >>= right; 114 d0 >>= right;
115 } else if (src_idx+n <= bits) { 115 } else if (src_idx+n <= bits) {
116 // Single source word 116 // Single source word
117 d0 <<= left;; 117 d0 <<= left;
118 } else { 118 } else {
119 // 2 source words 119 // 2 source words
120 d1 = FB_READL(src + 1); 120 d1 = FB_READL(src + 1);
diff --git a/drivers/video/console/.gitignore b/drivers/video/console/.gitignore
deleted file mode 100644
index 0c258b45439c..000000000000
--- a/drivers/video/console/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
1# conmakehash generated file
2promcon_tbl.c
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 2f50a80b413e..fc7d9bbb548c 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -67,16 +67,9 @@ config SGI_NEWPORT_CONSOLE
67 67
68# bool 'IODC console' CONFIG_IODC_CONSOLE 68# bool 'IODC console' CONFIG_IODC_CONSOLE
69 69
70config PROM_CONSOLE
71 bool "PROM console"
72 depends on SPARC
73 help
74 Say Y to build a console driver for Sun machines that uses the
75 terminal emulation built into their console PROMS.
76
77config DUMMY_CONSOLE 70config DUMMY_CONSOLE
78 bool 71 bool
79 depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y 72 depends on VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y
80 default y 73 default y
81 74
82config DUMMY_CONSOLE_COLUMNS 75config DUMMY_CONSOLE_COLUMNS
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index ac46cc3f6a2a..a862e9173ebe 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -22,7 +22,6 @@ font-objs += $(font-objs-y)
22 22
23obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o 23obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o
24obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o 24obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o
25obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o
26obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o 25obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o
27obj-$(CONFIG_VGA_CONSOLE) += vgacon.o 26obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
28obj-$(CONFIG_MDA_CONSOLE) += mdacon.o 27obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
@@ -40,14 +39,3 @@ obj-$(CONFIG_FB_STI) += sticore.o font.o
40ifeq ($(CONFIG_USB_SISUSBVGA_CON),y) 39ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
41obj-$(CONFIG_USB_SISUSBVGA) += font.o 40obj-$(CONFIG_USB_SISUSBVGA) += font.o
42endif 41endif
43
44# Targets that kbuild needs to know about
45targets := promcon_tbl.c
46
47quiet_cmd_conmakehash = CNMKHSH $@
48 cmd_conmakehash = scripts/conmakehash $< | \
49 sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \
50 -e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@
51
52$(obj)/promcon_tbl.c: $(src)/prom.uni
53 $(call cmd,conmakehash)
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 69864b1b3f9e..6b7c8fbc5495 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -25,7 +25,7 @@ static inline void update_attr(u8 *dst, u8 *src, int attribute,
25 struct vc_data *vc) 25 struct vc_data *vc)
26{ 26{
27 int i, offset = (vc->vc_font.height < 10) ? 1 : 2; 27 int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
28 int width = (vc->vc_font.width + 7) >> 3; 28 int width = DIV_ROUND_UP(vc->vc_font.width, 8);
29 unsigned int cellsize = vc->vc_font.height * width; 29 unsigned int cellsize = vc->vc_font.height * width;
30 u8 c; 30 u8 c;
31 31
@@ -144,7 +144,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
144 int fg, int bg) 144 int fg, int bg)
145{ 145{
146 struct fb_image image; 146 struct fb_image image;
147 u32 width = (vc->vc_font.width + 7)/8; 147 u32 width = DIV_ROUND_UP(vc->vc_font.width, 8);
148 u32 cellsize = width * vc->vc_font.height; 148 u32 cellsize = width * vc->vc_font.height;
149 u32 maxcnt = info->pixmap.size/cellsize; 149 u32 maxcnt = info->pixmap.size/cellsize;
150 u32 scan_align = info->pixmap.scan_align - 1; 150 u32 scan_align = info->pixmap.scan_align - 1;
@@ -173,7 +173,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
173 cnt = count; 173 cnt = count;
174 174
175 image.width = vc->vc_font.width * cnt; 175 image.width = vc->vc_font.width * cnt;
176 pitch = ((image.width + 7) >> 3) + scan_align; 176 pitch = DIV_ROUND_UP(image.width, 8) + scan_align;
177 pitch &= ~scan_align; 177 pitch &= ~scan_align;
178 size = pitch * image.height + buf_align; 178 size = pitch * image.height + buf_align;
179 size &= ~buf_align; 179 size &= ~buf_align;
@@ -239,7 +239,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
239 struct fb_cursor cursor; 239 struct fb_cursor cursor;
240 struct fbcon_ops *ops = info->fbcon_par; 240 struct fbcon_ops *ops = info->fbcon_par;
241 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 241 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
242 int w = (vc->vc_font.width + 7) >> 3, c; 242 int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
243 int y = real_y(ops->p, vc->vc_y); 243 int y = real_y(ops->p, vc->vc_y);
244 int attribute, use_sw = (vc->vc_cursor_type & 0x10); 244 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
245 int err = 1; 245 int err = 1;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3a44695b9c09..5a686cea23f4 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -114,6 +114,7 @@ static int last_fb_vc = MAX_NR_CONSOLES - 1;
114static int fbcon_is_default = 1; 114static int fbcon_is_default = 1;
115static int fbcon_has_exited; 115static int fbcon_has_exited;
116static int primary_device = -1; 116static int primary_device = -1;
117static int fbcon_has_console_bind;
117 118
118#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY 119#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
119static int map_override; 120static int map_override;
@@ -544,6 +545,8 @@ static int fbcon_takeover(int show_logo)
544 con2fb_map[i] = -1; 545 con2fb_map[i] = -1;
545 } 546 }
546 info_idx = -1; 547 info_idx = -1;
548 } else {
549 fbcon_has_console_bind = 1;
547 } 550 }
548 551
549 return err; 552 return err;
@@ -725,7 +728,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
725 int oldidx, int found) 728 int oldidx, int found)
726{ 729{
727 struct fbcon_ops *ops = oldinfo->fbcon_par; 730 struct fbcon_ops *ops = oldinfo->fbcon_par;
728 int err = 0; 731 int err = 0, ret;
729 732
730 if (oldinfo->fbops->fb_release && 733 if (oldinfo->fbops->fb_release &&
731 oldinfo->fbops->fb_release(oldinfo, 0)) { 734 oldinfo->fbops->fb_release(oldinfo, 0)) {
@@ -752,8 +755,14 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
752 newinfo in an undefined state. Thus, a call to 755 newinfo in an undefined state. Thus, a call to
753 fb_set_par() may be needed for the newinfo. 756 fb_set_par() may be needed for the newinfo.
754 */ 757 */
755 if (newinfo->fbops->fb_set_par) 758 if (newinfo->fbops->fb_set_par) {
756 newinfo->fbops->fb_set_par(newinfo); 759 ret = newinfo->fbops->fb_set_par(newinfo);
760
761 if (ret)
762 printk(KERN_ERR "con2fb_release_oldinfo: "
763 "detected unhandled fb_set_par error, "
764 "error code %d\n", ret);
765 }
757 } 766 }
758 767
759 return err; 768 return err;
@@ -763,11 +772,18 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
763 int unit, int show_logo) 772 int unit, int show_logo)
764{ 773{
765 struct fbcon_ops *ops = info->fbcon_par; 774 struct fbcon_ops *ops = info->fbcon_par;
775 int ret;
766 776
767 ops->currcon = fg_console; 777 ops->currcon = fg_console;
768 778
769 if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT)) 779 if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT)) {
770 info->fbops->fb_set_par(info); 780 ret = info->fbops->fb_set_par(info);
781
782 if (ret)
783 printk(KERN_ERR "con2fb_init_display: detected "
784 "unhandled fb_set_par error, "
785 "error code %d\n", ret);
786 }
771 787
772 ops->flags |= FBCON_FLAGS_INIT; 788 ops->flags |= FBCON_FLAGS_INIT;
773 ops->graphics = 0; 789 ops->graphics = 0;
@@ -1006,7 +1022,7 @@ static void fbcon_init(struct vc_data *vc, int init)
1006 struct vc_data *svc = *default_mode; 1022 struct vc_data *svc = *default_mode;
1007 struct display *t, *p = &fb_display[vc->vc_num]; 1023 struct display *t, *p = &fb_display[vc->vc_num];
1008 int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; 1024 int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256;
1009 int cap; 1025 int cap, ret;
1010 1026
1011 if (info_idx == -1 || info == NULL) 1027 if (info_idx == -1 || info == NULL)
1012 return; 1028 return;
@@ -1092,8 +1108,15 @@ static void fbcon_init(struct vc_data *vc, int init)
1092 */ 1108 */
1093 if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) { 1109 if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) {
1094 if (info->fbops->fb_set_par && 1110 if (info->fbops->fb_set_par &&
1095 !(ops->flags & FBCON_FLAGS_INIT)) 1111 !(ops->flags & FBCON_FLAGS_INIT)) {
1096 info->fbops->fb_set_par(info); 1112 ret = info->fbops->fb_set_par(info);
1113
1114 if (ret)
1115 printk(KERN_ERR "fbcon_init: detected "
1116 "unhandled fb_set_par error, "
1117 "error code %d\n", ret);
1118 }
1119
1097 ops->flags |= FBCON_FLAGS_INIT; 1120 ops->flags |= FBCON_FLAGS_INIT;
1098 } 1121 }
1099 1122
@@ -2119,7 +2142,7 @@ static int fbcon_switch(struct vc_data *vc)
2119 struct fbcon_ops *ops; 2142 struct fbcon_ops *ops;
2120 struct display *p = &fb_display[vc->vc_num]; 2143 struct display *p = &fb_display[vc->vc_num];
2121 struct fb_var_screeninfo var; 2144 struct fb_var_screeninfo var;
2122 int i, prev_console, charcnt = 256; 2145 int i, ret, prev_console, charcnt = 256;
2123 2146
2124 info = registered_fb[con2fb_map[vc->vc_num]]; 2147 info = registered_fb[con2fb_map[vc->vc_num]];
2125 ops = info->fbcon_par; 2148 ops = info->fbcon_par;
@@ -2174,8 +2197,14 @@ static int fbcon_switch(struct vc_data *vc)
2174 2197
2175 if (old_info != NULL && (old_info != info || 2198 if (old_info != NULL && (old_info != info ||
2176 info->flags & FBINFO_MISC_ALWAYS_SETPAR)) { 2199 info->flags & FBINFO_MISC_ALWAYS_SETPAR)) {
2177 if (info->fbops->fb_set_par) 2200 if (info->fbops->fb_set_par) {
2178 info->fbops->fb_set_par(info); 2201 ret = info->fbops->fb_set_par(info);
2202
2203 if (ret)
2204 printk(KERN_ERR "fbcon_switch: detected "
2205 "unhandled fb_set_par error, "
2206 "error code %d\n", ret);
2207 }
2179 2208
2180 if (old_info != info) 2209 if (old_info != info)
2181 fbcon_del_cursor_timer(old_info); 2210 fbcon_del_cursor_timer(old_info);
@@ -2923,6 +2952,10 @@ static int fbcon_unbind(void)
2923 2952
2924 ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, 2953 ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
2925 fbcon_is_default); 2954 fbcon_is_default);
2955
2956 if (!ret)
2957 fbcon_has_console_bind = 0;
2958
2926 return ret; 2959 return ret;
2927} 2960}
2928#else 2961#else
@@ -2936,6 +2969,9 @@ static int fbcon_fb_unbind(int idx)
2936{ 2969{
2937 int i, new_idx = -1, ret = 0; 2970 int i, new_idx = -1, ret = 0;
2938 2971
2972 if (!fbcon_has_console_bind)
2973 return 0;
2974
2939 for (i = first_fb_vc; i <= last_fb_vc; i++) { 2975 for (i = first_fb_vc; i <= last_fb_vc; i++) {
2940 if (con2fb_map[i] != idx && 2976 if (con2fb_map[i] != idx &&
2941 con2fb_map[i] != -1) { 2977 con2fb_map[i] != -1) {
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index d31b203bf654..3772433c49d1 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -216,7 +216,7 @@ static void newport_get_screensize(void)
216 } 216 }
217 217
218 newport_xsize = newport_ysize = 0; 218 newport_xsize = newport_ysize = 0;
219 for (i = 0; linetable[i + 1] && (i < sizeof(linetable)); i += 2) { 219 for (i = 0; i < ARRAY_SIZE(linetable) - 1 && linetable[i + 1]; i += 2) {
220 cols = 0; 220 cols = 0;
221 newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]); 221 newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]);
222 npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM | 222 npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
diff --git a/drivers/video/console/prom.uni b/drivers/video/console/prom.uni
deleted file mode 100644
index 58f9c04ed9d3..000000000000
--- a/drivers/video/console/prom.uni
+++ /dev/null
@@ -1,11 +0,0 @@
1#
2# Unicode mapping table for font in Sun PROM
3#
4#
50x20-0x7e idem
60xa0-0xff idem
7#
80x7c U+2502
90x2d U+2500
100x2b U+250c U+2510 U+2514 U+2518 U+251c U+2524 U+252c U+2534 U+253c
110xa4 U+fffd
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c
deleted file mode 100644
index ae02e4eb18e7..000000000000
--- a/drivers/video/console/promcon.c
+++ /dev/null
@@ -1,598 +0,0 @@
1/* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $
2 * Console driver utilizing PROM sun terminal emulation
3 *
4 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
5 * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
6 */
7
8#include <linux/module.h>
9#include <linux/kernel.h>
10#include <linux/errno.h>
11#include <linux/string.h>
12#include <linux/mm.h>
13#include <linux/slab.h>
14#include <linux/delay.h>
15#include <linux/console.h>
16#include <linux/vt_kern.h>
17#include <linux/selection.h>
18#include <linux/fb.h>
19#include <linux/init.h>
20#include <linux/kd.h>
21
22#include <asm/oplib.h>
23#include <asm/uaccess.h>
24
25static short pw = 80 - 1, ph = 34 - 1;
26static short px, py;
27static unsigned long promcon_uni_pagedir[2];
28
29extern u8 promfont_unicount[];
30extern u16 promfont_unitable[];
31
32#define PROMCON_COLOR 0
33
34#if PROMCON_COLOR
35#define inverted(s) ((((s) & 0x7700) == 0x0700) ? 0 : 1)
36#else
37#define inverted(s) (((s) & 0x0800) ? 1 : 0)
38#endif
39
40static __inline__ void
41promcon_puts(char *buf, int cnt)
42{
43 prom_printf("%*.*s", cnt, cnt, buf);
44}
45
46static int
47promcon_start(struct vc_data *conp, char *b)
48{
49 unsigned short *s = (unsigned short *)
50 (conp->vc_origin + py * conp->vc_size_row + (px << 1));
51 u16 cs;
52
53 cs = scr_readw(s);
54 if (px == pw) {
55 unsigned short *t = s - 1;
56 u16 ct = scr_readw(t);
57
58 if (inverted(cs) && inverted(ct))
59 return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs,
60 ct);
61 else if (inverted(cs))
62 return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs,
63 ct);
64 else if (inverted(ct))
65 return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs,
66 ct);
67 else
68 return sprintf(b, "\b%c\b\033[@%c", cs, ct);
69 }
70
71 if (inverted(cs))
72 return sprintf(b, "\033[7m%c\033[m\b", cs);
73 else
74 return sprintf(b, "%c\b", cs);
75}
76
77static int
78promcon_end(struct vc_data *conp, char *b)
79{
80 unsigned short *s = (unsigned short *)
81 (conp->vc_origin + py * conp->vc_size_row + (px << 1));
82 char *p = b;
83 u16 cs;
84
85 b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
86
87 cs = scr_readw(s);
88 if (px == pw) {
89 unsigned short *t = s - 1;
90 u16 ct = scr_readw(t);
91
92 if (inverted(cs) && inverted(ct))
93 b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct);
94 else if (inverted(cs))
95 b += sprintf(b, "\b%c\b\033[@%c", cs, ct);
96 else if (inverted(ct))
97 b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct);
98 else
99 b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct);
100 return b - p;
101 }
102
103 if (inverted(cs))
104 b += sprintf(b, "%c\b", cs);
105 else
106 b += sprintf(b, "\033[7m%c\033[m\b", cs);
107 return b - p;
108}
109
110const char *promcon_startup(void)
111{
112 const char *display_desc = "PROM";
113 int node;
114 char buf[40];
115
116 node = prom_getchild(prom_root_node);
117 node = prom_searchsiblings(node, "options");
118 if (prom_getproperty(node, "screen-#columns", buf, 40) != -1) {
119 pw = simple_strtoul(buf, NULL, 0);
120 if (pw < 10 || pw > 256)
121 pw = 80;
122 pw--;
123 }
124 if (prom_getproperty(node, "screen-#rows", buf, 40) != -1) {
125 ph = simple_strtoul(buf, NULL, 0);
126 if (ph < 10 || ph > 256)
127 ph = 34;
128 ph--;
129 }
130 promcon_puts("\033[H\033[J", 6);
131 return display_desc;
132}
133
134static void
135promcon_init_unimap(struct vc_data *conp)
136{
137 mm_segment_t old_fs = get_fs();
138 struct unipair *p, *p1;
139 u16 *q;
140 int i, j, k;
141
142 p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL);
143 if (!p) return;
144
145 q = promfont_unitable;
146 p1 = p;
147 k = 0;
148 for (i = 0; i < 256; i++)
149 for (j = promfont_unicount[i]; j; j--) {
150 p1->unicode = *q++;
151 p1->fontpos = i;
152 p1++;
153 k++;
154 }
155 set_fs(KERNEL_DS);
156 con_clear_unimap(conp, NULL);
157 con_set_unimap(conp, k, p);
158 con_protect_unimap(conp, 1);
159 set_fs(old_fs);
160 kfree(p);
161}
162
163static void
164promcon_init(struct vc_data *conp, int init)
165{
166 unsigned long p;
167
168 conp->vc_can_do_color = PROMCON_COLOR;
169 if (init) {
170 conp->vc_cols = pw + 1;
171 conp->vc_rows = ph + 1;
172 }
173 p = *conp->vc_uni_pagedir_loc;
174 if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir ||
175 !--conp->vc_uni_pagedir_loc[1])
176 con_free_unimap(conp);
177 conp->vc_uni_pagedir_loc = promcon_uni_pagedir;
178 promcon_uni_pagedir[1]++;
179 if (!promcon_uni_pagedir[0] && p) {
180 promcon_init_unimap(conp);
181 }
182 if (!init) {
183 if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1)
184 vc_resize(conp, pw + 1, ph + 1);
185 }
186}
187
188static void
189promcon_deinit(struct vc_data *conp)
190{
191 /* When closing the last console, reset video origin */
192 if (!--promcon_uni_pagedir[1])
193 con_free_unimap(conp);
194 conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir;
195 con_set_default_unimap(conp);
196}
197
198static int
199promcon_switch(struct vc_data *conp)
200{
201 return 1;
202}
203
204static unsigned short *
205promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp)
206{
207 int cnt = pw + 1;
208 int attr = -1;
209 unsigned char *b = *bp;
210
211 while (cnt--) {
212 u16 c = scr_readw(s);
213 if (attr != inverted(c)) {
214 attr = inverted(c);
215 if (attr) {
216 strcpy (b, "\033[7m");
217 b += 4;
218 } else {
219 strcpy (b, "\033[m");
220 b += 3;
221 }
222 }
223 *b++ = c;
224 s++;
225 if (b - buf >= 224) {
226 promcon_puts(buf, b - buf);
227 b = buf;
228 }
229 }
230 *bp = b;
231 return s;
232}
233
234static void
235promcon_putcs(struct vc_data *conp, const unsigned short *s,
236 int count, int y, int x)
237{
238 unsigned char buf[256], *b = buf;
239 unsigned short attr = scr_readw(s);
240 unsigned char save;
241 int i, last = 0;
242
243 if (console_blanked)
244 return;
245
246 if (count <= 0)
247 return;
248
249 b += promcon_start(conp, b);
250
251 if (x + count >= pw + 1) {
252 if (count == 1) {
253 x -= 1;
254 save = scr_readw((unsigned short *)(conp->vc_origin
255 + y * conp->vc_size_row
256 + (x << 1)));
257
258 if (px != x || py != y) {
259 b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
260 px = x;
261 py = y;
262 }
263
264 if (inverted(attr))
265 b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++));
266 else
267 b += sprintf(b, "%c", scr_readw(s++));
268
269 strcpy(b, "\b\033[@");
270 b += 4;
271
272 if (inverted(save))
273 b += sprintf(b, "\033[7m%c\033[m", save);
274 else
275 b += sprintf(b, "%c", save);
276
277 px++;
278
279 b += promcon_end(conp, b);
280 promcon_puts(buf, b - buf);
281 return;
282 } else {
283 last = 1;
284 count = pw - x - 1;
285 }
286 }
287
288 if (inverted(attr)) {
289 strcpy(b, "\033[7m");
290 b += 4;
291 }
292
293 if (px != x || py != y) {
294 b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
295 px = x;
296 py = y;
297 }
298
299 for (i = 0; i < count; i++) {
300 if (b - buf >= 224) {
301 promcon_puts(buf, b - buf);
302 b = buf;
303 }
304 *b++ = scr_readw(s++);
305 }
306
307 px += count;
308
309 if (last) {
310 save = scr_readw(s++);
311 b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save);
312 px++;
313 }
314
315 if (inverted(attr)) {
316 strcpy(b, "\033[m");
317 b += 3;
318 }
319
320 b += promcon_end(conp, b);
321 promcon_puts(buf, b - buf);
322}
323
324static void
325promcon_putc(struct vc_data *conp, int c, int y, int x)
326{
327 unsigned short s;
328
329 if (console_blanked)
330 return;
331
332 scr_writew(c, &s);
333 promcon_putcs(conp, &s, 1, y, x);
334}
335
336static void
337promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width)
338{
339 unsigned char buf[256], *b = buf;
340 int i, j;
341
342 if (console_blanked)
343 return;
344
345 b += promcon_start(conp, b);
346
347 if (!sx && width == pw + 1) {
348
349 if (!sy && height == ph + 1) {
350 strcpy(b, "\033[H\033[J");
351 b += 6;
352 b += promcon_end(conp, b);
353 promcon_puts(buf, b - buf);
354 return;
355 } else if (sy + height == ph + 1) {
356 b += sprintf(b, "\033[%dH\033[J", sy + 1);
357 b += promcon_end(conp, b);
358 promcon_puts(buf, b - buf);
359 return;
360 }
361
362 b += sprintf(b, "\033[%dH", sy + 1);
363 for (i = 1; i < height; i++) {
364 strcpy(b, "\033[K\n");
365 b += 4;
366 }
367
368 strcpy(b, "\033[K");
369 b += 3;
370
371 b += promcon_end(conp, b);
372 promcon_puts(buf, b - buf);
373 return;
374
375 } else if (sx + width == pw + 1) {
376
377 b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1);
378 for (i = 1; i < height; i++) {
379 strcpy(b, "\033[K\n");
380 b += 4;
381 }
382
383 strcpy(b, "\033[K");
384 b += 3;
385
386 b += promcon_end(conp, b);
387 promcon_puts(buf, b - buf);
388 return;
389 }
390
391 for (i = sy + 1; i <= sy + height; i++) {
392 b += sprintf(b, "\033[%d;%dH", i, sx + 1);
393 for (j = 0; j < width; j++)
394 *b++ = ' ';
395 if (b - buf + width >= 224) {
396 promcon_puts(buf, b - buf);
397 b = buf;
398 }
399 }
400
401 b += promcon_end(conp, b);
402 promcon_puts(buf, b - buf);
403}
404
405static void
406promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
407 int height, int width)
408{
409 char buf[256], *b = buf;
410
411 if (console_blanked)
412 return;
413
414 b += promcon_start(conp, b);
415 if (sy == dy && height == 1) {
416 if (dx > sx && dx + width == conp->vc_cols)
417 b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH",
418 sy + 1, sx + 1, dx - sx, py + 1, px + 1);
419 else if (dx < sx && sx + width == conp->vc_cols)
420 b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH",
421 dy + 1, dx + 1, sx - dx, py + 1, px + 1);
422
423 b += promcon_end(conp, b);
424 promcon_puts(buf, b - buf);
425 return;
426 }
427
428 /*
429 * FIXME: What to do here???
430 * Current console.c should not call it like that ever.
431 */
432 prom_printf("\033[7mFIXME: bmove not handled\033[m\n");
433}
434
435static void
436promcon_cursor(struct vc_data *conp, int mode)
437{
438 char buf[32], *b = buf;
439
440 switch (mode) {
441 case CM_ERASE:
442 break;
443
444 case CM_MOVE:
445 case CM_DRAW:
446 b += promcon_start(conp, b);
447 if (px != conp->vc_x || py != conp->vc_y) {
448 px = conp->vc_x;
449 py = conp->vc_y;
450 b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
451 }
452 promcon_puts(buf, b - buf);
453 break;
454 }
455}
456
457static int
458promcon_blank(struct vc_data *conp, int blank, int mode_switch)
459{
460 if (blank) {
461 promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);
462 return 0;
463 } else {
464 /* Let console.c redraw */
465 return 1;
466 }
467}
468
469static int
470promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
471{
472 unsigned char buf[256], *p = buf;
473 unsigned short *s;
474 int i;
475
476 if (console_blanked)
477 return 0;
478
479 p += promcon_start(conp, p);
480
481 switch (dir) {
482 case SM_UP:
483 if (b == ph + 1) {
484 p += sprintf(p, "\033[%dH\033[%dM", t + 1, count);
485 px = 0;
486 py = t;
487 p += promcon_end(conp, p);
488 promcon_puts(buf, p - buf);
489 break;
490 }
491
492 s = (unsigned short *)(conp->vc_origin
493 + (t + count) * conp->vc_size_row);
494
495 p += sprintf(p, "\033[%dH", t + 1);
496
497 for (i = t; i < b - count; i++)
498 s = promcon_repaint_line(s, buf, &p);
499
500 for (; i < b - 1; i++) {
501 strcpy(p, "\033[K\n");
502 p += 4;
503 if (p - buf >= 224) {
504 promcon_puts(buf, p - buf);
505 p = buf;
506 }
507 }
508
509 strcpy(p, "\033[K");
510 p += 3;
511
512 p += promcon_end(conp, p);
513 promcon_puts(buf, p - buf);
514 break;
515
516 case SM_DOWN:
517 if (b == ph + 1) {
518 p += sprintf(p, "\033[%dH\033[%dL", t + 1, count);
519 px = 0;
520 py = t;
521 p += promcon_end(conp, p);
522 promcon_puts(buf, p - buf);
523 break;
524 }
525
526 s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
527
528 p += sprintf(p, "\033[%dH", t + 1);
529
530 for (i = t; i < t + count; i++) {
531 strcpy(p, "\033[K\n");
532 p += 4;
533 if (p - buf >= 224) {
534 promcon_puts(buf, p - buf);
535 p = buf;
536 }
537 }
538
539 for (; i < b; i++)
540 s = promcon_repaint_line(s, buf, &p);
541
542 p += promcon_end(conp, p);
543 promcon_puts(buf, p - buf);
544 break;
545 }
546
547 return 0;
548}
549
550#if !(PROMCON_COLOR)
551static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity,
552 u8 _blink, u8 _underline, u8 _reverse, u8 _italic)
553{
554 return (_reverse) ? 0xf : 0x7;
555}
556#endif
557
558/*
559 * The console 'switch' structure for the VGA based console
560 */
561
562static int promcon_dummy(void)
563{
564 return 0;
565}
566
567#define DUMMY (void *) promcon_dummy
568
569const struct consw prom_con = {
570 .owner = THIS_MODULE,
571 .con_startup = promcon_startup,
572 .con_init = promcon_init,
573 .con_deinit = promcon_deinit,
574 .con_clear = promcon_clear,
575 .con_putc = promcon_putc,
576 .con_putcs = promcon_putcs,
577 .con_cursor = promcon_cursor,
578 .con_scroll = promcon_scroll,
579 .con_bmove = promcon_bmove,
580 .con_switch = promcon_switch,
581 .con_blank = promcon_blank,
582 .con_set_palette = DUMMY,
583 .con_scrolldelta = DUMMY,
584#if !(PROMCON_COLOR)
585 .con_build_attr = promcon_build_attr,
586#endif
587};
588
589void __init prom_con_init(void)
590{
591#ifdef CONFIG_DUMMY_CONSOLE
592 if (conswitchp == &dummy_con)
593 take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1);
594 else
595#endif
596 if (conswitchp == &prom_con)
597 promcon_init_unimap(vc_cons[fg_console].d);
598}
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 59d7d5ec17a4..da55ccaf4d55 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -180,7 +180,6 @@ static inline void vga_set_mem_top(struct vc_data *c)
180} 180}
181 181
182#ifdef CONFIG_VGACON_SOFT_SCROLLBACK 182#ifdef CONFIG_VGACON_SOFT_SCROLLBACK
183#include <linux/slab.h>
184/* software scrollback */ 183/* software scrollback */
185static void *vgacon_scrollback; 184static void *vgacon_scrollback;
186static int vgacon_scrollback_tail; 185static int vgacon_scrollback_tail;
@@ -590,12 +589,14 @@ static void vgacon_init(struct vc_data *c, int init)
590 589
591static void vgacon_deinit(struct vc_data *c) 590static void vgacon_deinit(struct vc_data *c)
592{ 591{
593 /* When closing the last console, reset video origin */ 592 /* When closing the active console, reset video origin */
594 if (!--vgacon_uni_pagedir[1]) { 593 if (CON_IS_VISIBLE(c)) {
595 c->vc_visible_origin = vga_vram_base; 594 c->vc_visible_origin = vga_vram_base;
596 vga_set_mem_top(c); 595 vga_set_mem_top(c);
597 con_free_unimap(c);
598 } 596 }
597
598 if (!--vgacon_uni_pagedir[1])
599 con_free_unimap(c);
599 c->vc_uni_pagedir_loc = &c->vc_uni_pagedir; 600 c->vc_uni_pagedir_loc = &c->vc_uni_pagedir;
600 con_set_default_unimap(c); 601 con_set_default_unimap(c);
601} 602}
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
new file mode 100644
index 000000000000..42e1005e2916
--- /dev/null
+++ b/drivers/video/da8xx-fb.c
@@ -0,0 +1,890 @@
1/*
2 * Copyright (C) 2008-2009 MontaVista Software Inc.
3 * Copyright (C) 2008-2009 Texas Instruments Inc
4 *
5 * Based on the LCD driver for TI Avalanche processors written by
6 * Ajay Singh and Shalom Hai.
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option)any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/fb.h>
25#include <linux/dma-mapping.h>
26#include <linux/device.h>
27#include <linux/platform_device.h>
28#include <linux/uaccess.h>
29#include <linux/device.h>
30#include <linux/interrupt.h>
31#include <linux/clk.h>
32#include <video/da8xx-fb.h>
33
34#define DRIVER_NAME "da8xx_lcdc"
35
36/* LCD Status Register */
37#define LCD_END_OF_FRAME0 BIT(8)
38#define LCD_FIFO_UNDERFLOW BIT(5)
39#define LCD_SYNC_LOST BIT(2)
40
41/* LCD DMA Control Register */
42#define LCD_DMA_BURST_SIZE(x) ((x) << 4)
43#define LCD_DMA_BURST_1 0x0
44#define LCD_DMA_BURST_2 0x1
45#define LCD_DMA_BURST_4 0x2
46#define LCD_DMA_BURST_8 0x3
47#define LCD_DMA_BURST_16 0x4
48#define LCD_END_OF_FRAME_INT_ENA BIT(2)
49#define LCD_DUAL_FRAME_BUFFER_ENABLE BIT(0)
50
51/* LCD Control Register */
52#define LCD_CLK_DIVISOR(x) ((x) << 8)
53#define LCD_RASTER_MODE 0x01
54
55/* LCD Raster Control Register */
56#define LCD_PALETTE_LOAD_MODE(x) ((x) << 20)
57#define PALETTE_AND_DATA 0x00
58#define PALETTE_ONLY 0x01
59
60#define LCD_MONO_8BIT_MODE BIT(9)
61#define LCD_RASTER_ORDER BIT(8)
62#define LCD_TFT_MODE BIT(7)
63#define LCD_UNDERFLOW_INT_ENA BIT(6)
64#define LCD_MONOCHROME_MODE BIT(1)
65#define LCD_RASTER_ENABLE BIT(0)
66#define LCD_TFT_ALT_ENABLE BIT(23)
67#define LCD_STN_565_ENABLE BIT(24)
68
69/* LCD Raster Timing 2 Register */
70#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
71#define LCD_AC_BIAS_FREQUENCY(x) ((x) << 8)
72#define LCD_SYNC_CTRL BIT(25)
73#define LCD_SYNC_EDGE BIT(24)
74#define LCD_INVERT_PIXEL_CLOCK BIT(22)
75#define LCD_INVERT_LINE_CLOCK BIT(21)
76#define LCD_INVERT_FRAME_CLOCK BIT(20)
77
78/* LCD Block */
79#define LCD_CTRL_REG 0x4
80#define LCD_STAT_REG 0x8
81#define LCD_RASTER_CTRL_REG 0x28
82#define LCD_RASTER_TIMING_0_REG 0x2C
83#define LCD_RASTER_TIMING_1_REG 0x30
84#define LCD_RASTER_TIMING_2_REG 0x34
85#define LCD_DMA_CTRL_REG 0x40
86#define LCD_DMA_FRM_BUF_BASE_ADDR_0_REG 0x44
87#define LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG 0x48
88
89#define WSI_TIMEOUT 50
90#define PALETTE_SIZE 256
91#define LEFT_MARGIN 64
92#define RIGHT_MARGIN 64
93#define UPPER_MARGIN 32
94#define LOWER_MARGIN 32
95
96static resource_size_t da8xx_fb_reg_base;
97static struct resource *lcdc_regs;
98
99static inline unsigned int lcdc_read(unsigned int addr)
100{
101 return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr));
102}
103
104static inline void lcdc_write(unsigned int val, unsigned int addr)
105{
106 __raw_writel(val, da8xx_fb_reg_base + (addr));
107}
108
109struct da8xx_fb_par {
110 resource_size_t p_palette_base;
111 unsigned char *v_palette_base;
112 struct clk *lcdc_clk;
113 int irq;
114 unsigned short pseudo_palette[16];
115 unsigned int databuf_sz;
116 unsigned int palette_sz;
117};
118
119/* Variable Screen Information */
120static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
121 .xoffset = 0,
122 .yoffset = 0,
123 .transp = {0, 0, 0},
124 .nonstd = 0,
125 .activate = 0,
126 .height = -1,
127 .width = -1,
128 .pixclock = 46666, /* 46us - AUO display */
129 .accel_flags = 0,
130 .left_margin = LEFT_MARGIN,
131 .right_margin = RIGHT_MARGIN,
132 .upper_margin = UPPER_MARGIN,
133 .lower_margin = LOWER_MARGIN,
134 .sync = 0,
135 .vmode = FB_VMODE_NONINTERLACED
136};
137
138static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = {
139 .id = "DA8xx FB Drv",
140 .type = FB_TYPE_PACKED_PIXELS,
141 .type_aux = 0,
142 .visual = FB_VISUAL_PSEUDOCOLOR,
143 .xpanstep = 1,
144 .ypanstep = 1,
145 .ywrapstep = 1,
146 .accel = FB_ACCEL_NONE
147};
148
149struct da8xx_panel {
150 const char name[25]; /* Full name <vendor>_<model> */
151 unsigned short width;
152 unsigned short height;
153 int hfp; /* Horizontal front porch */
154 int hbp; /* Horizontal back porch */
155 int hsw; /* Horizontal Sync Pulse Width */
156 int vfp; /* Vertical front porch */
157 int vbp; /* Vertical back porch */
158 int vsw; /* Vertical Sync Pulse Width */
159 int pxl_clk; /* Pixel clock */
160 unsigned char invert_pxl_clk; /* Invert Pixel clock */
161};
162
163static struct da8xx_panel known_lcd_panels[] = {
164 /* Sharp LCD035Q3DG01 */
165 [0] = {
166 .name = "Sharp_LCD035Q3DG01",
167 .width = 320,
168 .height = 240,
169 .hfp = 8,
170 .hbp = 6,
171 .hsw = 0,
172 .vfp = 2,
173 .vbp = 2,
174 .vsw = 0,
175 .pxl_clk = 0x10,
176 .invert_pxl_clk = 1,
177 },
178 /* Sharp LK043T1DG01 */
179 [1] = {
180 .name = "Sharp_LK043T1DG01",
181 .width = 480,
182 .height = 272,
183 .hfp = 2,
184 .hbp = 2,
185 .hsw = 41,
186 .vfp = 2,
187 .vbp = 2,
188 .vsw = 10,
189 .pxl_clk = 0x12,
190 .invert_pxl_clk = 0,
191 },
192};
193
194/* Disable the Raster Engine of the LCD Controller */
195static void lcd_disable_raster(struct da8xx_fb_par *par)
196{
197 u32 reg;
198
199 reg = lcdc_read(LCD_RASTER_CTRL_REG);
200 if (reg & LCD_RASTER_ENABLE)
201 lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
202}
203
204static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
205{
206 u32 tmp = par->p_palette_base + par->databuf_sz - 4;
207 u32 reg;
208
209 /* Update the databuf in the hw. */
210 lcdc_write(par->p_palette_base, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
211 lcdc_write(tmp, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
212
213 /* Start the DMA. */
214 reg = lcdc_read(LCD_RASTER_CTRL_REG);
215 reg &= ~(3 << 20);
216 if (load_mode == LOAD_DATA)
217 reg |= LCD_PALETTE_LOAD_MODE(PALETTE_AND_DATA);
218 else if (load_mode == LOAD_PALETTE)
219 reg |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
220
221 lcdc_write(reg, LCD_RASTER_CTRL_REG);
222}
223
224/* Configure the Burst Size of DMA */
225static int lcd_cfg_dma(int burst_size)
226{
227 u32 reg;
228
229 reg = lcdc_read(LCD_DMA_CTRL_REG) & 0x00000001;
230 switch (burst_size) {
231 case 1:
232 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_1);
233 break;
234 case 2:
235 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_2);
236 break;
237 case 4:
238 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_4);
239 break;
240 case 8:
241 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
242 break;
243 case 16:
244 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
245 break;
246 default:
247 return -EINVAL;
248 }
249 lcdc_write(reg, LCD_DMA_CTRL_REG);
250
251 return 0;
252}
253
254static void lcd_cfg_ac_bias(int period, int transitions_per_int)
255{
256 u32 reg;
257
258 /* Set the AC Bias Period and Number of Transisitons per Interrupt */
259 reg = lcdc_read(LCD_RASTER_TIMING_2_REG) & 0xFFF00000;
260 reg |= LCD_AC_BIAS_FREQUENCY(period) |
261 LCD_AC_BIAS_TRANSITIONS_PER_INT(transitions_per_int);
262 lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
263}
264
265static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width,
266 int front_porch)
267{
268 u32 reg;
269
270 reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf;
271 reg |= ((back_porch & 0xff) << 24)
272 | ((front_porch & 0xff) << 16)
273 | ((pulse_width & 0x3f) << 10);
274 lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
275}
276
277static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
278 int front_porch)
279{
280 u32 reg;
281
282 reg = lcdc_read(LCD_RASTER_TIMING_1_REG) & 0x3ff;
283 reg |= ((back_porch & 0xff) << 24)
284 | ((front_porch & 0xff) << 16)
285 | ((pulse_width & 0x3f) << 10);
286 lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
287}
288
289static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
290{
291 u32 reg;
292
293 reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
294 LCD_MONO_8BIT_MODE |
295 LCD_MONOCHROME_MODE);
296
297 switch (cfg->p_disp_panel->panel_shade) {
298 case MONOCHROME:
299 reg |= LCD_MONOCHROME_MODE;
300 if (cfg->mono_8bit_mode)
301 reg |= LCD_MONO_8BIT_MODE;
302 break;
303 case COLOR_ACTIVE:
304 reg |= LCD_TFT_MODE;
305 if (cfg->tft_alt_mode)
306 reg |= LCD_TFT_ALT_ENABLE;
307 break;
308
309 case COLOR_PASSIVE:
310 if (cfg->stn_565_mode)
311 reg |= LCD_STN_565_ENABLE;
312 break;
313
314 default:
315 return -EINVAL;
316 }
317
318 /* enable additional interrupts here */
319 reg |= LCD_UNDERFLOW_INT_ENA;
320
321 lcdc_write(reg, LCD_RASTER_CTRL_REG);
322
323 reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
324
325 if (cfg->sync_ctrl)
326 reg |= LCD_SYNC_CTRL;
327 else
328 reg &= ~LCD_SYNC_CTRL;
329
330 if (cfg->sync_edge)
331 reg |= LCD_SYNC_EDGE;
332 else
333 reg &= ~LCD_SYNC_EDGE;
334
335 if (cfg->invert_line_clock)
336 reg |= LCD_INVERT_LINE_CLOCK;
337 else
338 reg &= ~LCD_INVERT_LINE_CLOCK;
339
340 if (cfg->invert_frm_clock)
341 reg |= LCD_INVERT_FRAME_CLOCK;
342 else
343 reg &= ~LCD_INVERT_FRAME_CLOCK;
344
345 lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
346
347 return 0;
348}
349
350static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
351 u32 bpp, u32 raster_order)
352{
353 u32 bpl, reg;
354
355 /* Disable Dual Frame Buffer. */
356 reg = lcdc_read(LCD_DMA_CTRL_REG);
357 lcdc_write(reg & ~LCD_DUAL_FRAME_BUFFER_ENABLE,
358 LCD_DMA_CTRL_REG);
359 /* Set the Panel Width */
360 /* Pixels per line = (PPL + 1)*16 */
361 /*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/
362 width &= 0x3f0;
363 reg = lcdc_read(LCD_RASTER_TIMING_0_REG);
364 reg &= 0xfffffc00;
365 reg |= ((width >> 4) - 1) << 4;
366 lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
367
368 /* Set the Panel Height */
369 reg = lcdc_read(LCD_RASTER_TIMING_1_REG);
370 reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
371 lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
372
373 /* Set the Raster Order of the Frame Buffer */
374 reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
375 if (raster_order)
376 reg |= LCD_RASTER_ORDER;
377 lcdc_write(reg, LCD_RASTER_CTRL_REG);
378
379 switch (bpp) {
380 case 1:
381 case 2:
382 case 4:
383 case 16:
384 par->palette_sz = 16 * 2;
385 break;
386
387 case 8:
388 par->palette_sz = 256 * 2;
389 break;
390
391 default:
392 return -EINVAL;
393 }
394
395 bpl = width * bpp / 8;
396 par->databuf_sz = height * bpl + par->palette_sz;
397
398 return 0;
399}
400
401static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
402 unsigned blue, unsigned transp,
403 struct fb_info *info)
404{
405 struct da8xx_fb_par *par = info->par;
406 unsigned short *palette = (unsigned short *)par->v_palette_base;
407 u_short pal;
408
409 if (regno > 255)
410 return 1;
411
412 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
413 return 1;
414
415 if (info->var.bits_per_pixel == 8) {
416 red >>= 4;
417 green >>= 8;
418 blue >>= 12;
419
420 pal = (red & 0x0f00);
421 pal |= (green & 0x00f0);
422 pal |= (blue & 0x000f);
423
424 palette[regno] = pal;
425
426 } else if ((info->var.bits_per_pixel == 16) && regno < 16) {
427 red >>= (16 - info->var.red.length);
428 red <<= info->var.red.offset;
429
430 green >>= (16 - info->var.green.length);
431 green <<= info->var.green.offset;
432
433 blue >>= (16 - info->var.blue.length);
434 blue <<= info->var.blue.offset;
435
436 par->pseudo_palette[regno] = red | green | blue;
437
438 palette[0] = 0x4000;
439 }
440
441 return 0;
442}
443
444static void lcd_reset(struct da8xx_fb_par *par)
445{
446 /* Disable the Raster if previously Enabled */
447 if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE)
448 lcd_disable_raster(par);
449
450 /* DMA has to be disabled */
451 lcdc_write(0, LCD_DMA_CTRL_REG);
452 lcdc_write(0, LCD_RASTER_CTRL_REG);
453}
454
455static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
456 struct da8xx_panel *panel)
457{
458 u32 bpp;
459 int ret = 0;
460
461 lcd_reset(par);
462
463 /* Configure the LCD clock divisor. */
464 lcdc_write(LCD_CLK_DIVISOR(panel->pxl_clk) |
465 (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
466
467 if (panel->invert_pxl_clk)
468 lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
469 LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
470 else
471 lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) &
472 ~LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
473
474 /* Configure the DMA burst size. */
475 ret = lcd_cfg_dma(cfg->dma_burst_sz);
476 if (ret < 0)
477 return ret;
478
479 /* Configure the AC bias properties. */
480 lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
481
482 /* Configure the vertical and horizontal sync properties. */
483 lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp);
484 lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp);
485
486 /* Configure for disply */
487 ret = lcd_cfg_display(cfg);
488 if (ret < 0)
489 return ret;
490
491 if (QVGA != cfg->p_disp_panel->panel_type)
492 return -EINVAL;
493
494 if (cfg->bpp <= cfg->p_disp_panel->max_bpp &&
495 cfg->bpp >= cfg->p_disp_panel->min_bpp)
496 bpp = cfg->bpp;
497 else
498 bpp = cfg->p_disp_panel->max_bpp;
499 if (bpp == 12)
500 bpp = 16;
501 ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width,
502 (unsigned int)panel->height, bpp,
503 cfg->raster_order);
504 if (ret < 0)
505 return ret;
506
507 /* Configure FDD */
508 lcdc_write((lcdc_read(LCD_RASTER_CTRL_REG) & 0xfff00fff) |
509 (cfg->fdd << 12), LCD_RASTER_CTRL_REG);
510
511 return 0;
512}
513
514static irqreturn_t lcdc_irq_handler(int irq, void *arg)
515{
516 u32 stat = lcdc_read(LCD_STAT_REG);
517 u32 reg;
518
519 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
520 reg = lcdc_read(LCD_RASTER_CTRL_REG);
521 lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
522 lcdc_write(stat, LCD_STAT_REG);
523 lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
524 } else
525 lcdc_write(stat, LCD_STAT_REG);
526
527 return IRQ_HANDLED;
528}
529
530static int fb_check_var(struct fb_var_screeninfo *var,
531 struct fb_info *info)
532{
533 int err = 0;
534
535 switch (var->bits_per_pixel) {
536 case 1:
537 case 8:
538 var->red.offset = 0;
539 var->red.length = 8;
540 var->green.offset = 0;
541 var->green.length = 8;
542 var->blue.offset = 0;
543 var->blue.length = 8;
544 var->transp.offset = 0;
545 var->transp.length = 0;
546 break;
547 case 4:
548 var->red.offset = 0;
549 var->red.length = 4;
550 var->green.offset = 0;
551 var->green.length = 4;
552 var->blue.offset = 0;
553 var->blue.length = 4;
554 var->transp.offset = 0;
555 var->transp.length = 0;
556 break;
557 case 16: /* RGB 565 */
558 var->red.offset = 0;
559 var->red.length = 5;
560 var->green.offset = 5;
561 var->green.length = 6;
562 var->blue.offset = 11;
563 var->blue.length = 5;
564 var->transp.offset = 0;
565 var->transp.length = 0;
566 break;
567 default:
568 err = -EINVAL;
569 }
570
571 var->red.msb_right = 0;
572 var->green.msb_right = 0;
573 var->blue.msb_right = 0;
574 var->transp.msb_right = 0;
575 return err;
576}
577
578static int __devexit fb_remove(struct platform_device *dev)
579{
580 struct fb_info *info = dev_get_drvdata(&dev->dev);
581
582 if (info) {
583 struct da8xx_fb_par *par = info->par;
584
585 if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE)
586 lcd_disable_raster(par);
587 lcdc_write(0, LCD_RASTER_CTRL_REG);
588
589 /* disable DMA */
590 lcdc_write(0, LCD_DMA_CTRL_REG);
591
592 unregister_framebuffer(info);
593 fb_dealloc_cmap(&info->cmap);
594 dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
595 info->screen_base,
596 info->fix.smem_start);
597 free_irq(par->irq, par);
598 clk_disable(par->lcdc_clk);
599 clk_put(par->lcdc_clk);
600 framebuffer_release(info);
601 iounmap((void __iomem *)da8xx_fb_reg_base);
602 release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
603
604 }
605 return 0;
606}
607
608static int fb_ioctl(struct fb_info *info, unsigned int cmd,
609 unsigned long arg)
610{
611 struct lcd_sync_arg sync_arg;
612
613 switch (cmd) {
614 case FBIOGET_CONTRAST:
615 case FBIOPUT_CONTRAST:
616 case FBIGET_BRIGHTNESS:
617 case FBIPUT_BRIGHTNESS:
618 case FBIGET_COLOR:
619 case FBIPUT_COLOR:
620 return -ENOTTY;
621 case FBIPUT_HSYNC:
622 if (copy_from_user(&sync_arg, (char *)arg,
623 sizeof(struct lcd_sync_arg)))
624 return -EFAULT;
625 lcd_cfg_horizontal_sync(sync_arg.back_porch,
626 sync_arg.pulse_width,
627 sync_arg.front_porch);
628 break;
629 case FBIPUT_VSYNC:
630 if (copy_from_user(&sync_arg, (char *)arg,
631 sizeof(struct lcd_sync_arg)))
632 return -EFAULT;
633 lcd_cfg_vertical_sync(sync_arg.back_porch,
634 sync_arg.pulse_width,
635 sync_arg.front_porch);
636 break;
637 default:
638 return -EINVAL;
639 }
640 return 0;
641}
642
643static struct fb_ops da8xx_fb_ops = {
644 .owner = THIS_MODULE,
645 .fb_check_var = fb_check_var,
646 .fb_setcolreg = fb_setcolreg,
647 .fb_ioctl = fb_ioctl,
648 .fb_fillrect = cfb_fillrect,
649 .fb_copyarea = cfb_copyarea,
650 .fb_imageblit = cfb_imageblit,
651};
652
653static int __init fb_probe(struct platform_device *device)
654{
655 struct da8xx_lcdc_platform_data *fb_pdata =
656 device->dev.platform_data;
657 struct lcd_ctrl_config *lcd_cfg;
658 struct da8xx_panel *lcdc_info;
659 struct fb_info *da8xx_fb_info;
660 struct clk *fb_clk = NULL;
661 struct da8xx_fb_par *par;
662 resource_size_t len;
663 int ret, i;
664
665 if (fb_pdata == NULL) {
666 dev_err(&device->dev, "Can not get platform data\n");
667 return -ENOENT;
668 }
669
670 lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
671 if (!lcdc_regs) {
672 dev_err(&device->dev,
673 "Can not get memory resource for LCD controller\n");
674 return -ENOENT;
675 }
676
677 len = resource_size(lcdc_regs);
678
679 lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name);
680 if (!lcdc_regs)
681 return -EBUSY;
682
683 da8xx_fb_reg_base = (resource_size_t)ioremap(lcdc_regs->start, len);
684 if (!da8xx_fb_reg_base) {
685 ret = -EBUSY;
686 goto err_request_mem;
687 }
688
689 fb_clk = clk_get(&device->dev, NULL);
690 if (IS_ERR(fb_clk)) {
691 dev_err(&device->dev, "Can not get device clock\n");
692 ret = -ENODEV;
693 goto err_ioremap;
694 }
695 ret = clk_enable(fb_clk);
696 if (ret)
697 goto err_clk_put;
698
699 for (i = 0, lcdc_info = known_lcd_panels;
700 i < ARRAY_SIZE(known_lcd_panels);
701 i++, lcdc_info++) {
702 if (strcmp(fb_pdata->type, lcdc_info->name) == 0)
703 break;
704 }
705
706 if (i == ARRAY_SIZE(known_lcd_panels)) {
707 dev_err(&device->dev, "GLCD: No valid panel found\n");
708 ret = ENODEV;
709 goto err_clk_disable;
710 } else
711 dev_info(&device->dev, "GLCD: Found %s panel\n",
712 fb_pdata->type);
713
714 lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
715
716 da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
717 &device->dev);
718 if (!da8xx_fb_info) {
719 dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
720 ret = -ENOMEM;
721 goto err_clk_disable;
722 }
723
724 par = da8xx_fb_info->par;
725
726 if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {
727 dev_err(&device->dev, "lcd_init failed\n");
728 ret = -EFAULT;
729 goto err_release_fb;
730 }
731
732 /* allocate frame buffer */
733 da8xx_fb_info->screen_base = dma_alloc_coherent(NULL,
734 par->databuf_sz + PAGE_SIZE,
735 (resource_size_t *)
736 &da8xx_fb_info->fix.smem_start,
737 GFP_KERNEL | GFP_DMA);
738
739 if (!da8xx_fb_info->screen_base) {
740 dev_err(&device->dev,
741 "GLCD: kmalloc for frame buffer failed\n");
742 ret = -EINVAL;
743 goto err_release_fb;
744 }
745
746 /* move palette base pointer by (PAGE_SIZE - palette_sz) bytes */
747 par->v_palette_base = da8xx_fb_info->screen_base +
748 (PAGE_SIZE - par->palette_sz);
749 par->p_palette_base = da8xx_fb_info->fix.smem_start +
750 (PAGE_SIZE - par->palette_sz);
751
752 /* the rest of the frame buffer is pixel data */
753 da8xx_fb_fix.smem_start = par->p_palette_base + par->palette_sz;
754 da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz;
755 da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8;
756
757 par->lcdc_clk = fb_clk;
758
759 par->irq = platform_get_irq(device, 0);
760 if (par->irq < 0) {
761 ret = -ENOENT;
762 goto err_release_fb_mem;
763 }
764
765 ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
766 if (ret)
767 goto err_release_fb_mem;
768
769 /* Initialize par */
770 da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
771
772 da8xx_fb_var.xres = lcdc_info->width;
773 da8xx_fb_var.xres_virtual = lcdc_info->width;
774
775 da8xx_fb_var.yres = lcdc_info->height;
776 da8xx_fb_var.yres_virtual = lcdc_info->height;
777
778 da8xx_fb_var.grayscale =
779 lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0;
780 da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
781
782 da8xx_fb_var.hsync_len = lcdc_info->hsw;
783 da8xx_fb_var.vsync_len = lcdc_info->vsw;
784
785 /* Initialize fbinfo */
786 da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
787 da8xx_fb_info->fix = da8xx_fb_fix;
788 da8xx_fb_info->var = da8xx_fb_var;
789 da8xx_fb_info->fbops = &da8xx_fb_ops;
790 da8xx_fb_info->pseudo_palette = par->pseudo_palette;
791
792 ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
793 if (ret)
794 goto err_free_irq;
795
796 /* First palette_sz byte of the frame buffer is the palette */
797 da8xx_fb_info->cmap.len = par->palette_sz;
798
799 /* Flush the buffer to the screen. */
800 lcd_blit(LOAD_DATA, par);
801
802 /* initialize var_screeninfo */
803 da8xx_fb_var.activate = FB_ACTIVATE_FORCE;
804 fb_set_var(da8xx_fb_info, &da8xx_fb_var);
805
806 dev_set_drvdata(&device->dev, da8xx_fb_info);
807 /* Register the Frame Buffer */
808 if (register_framebuffer(da8xx_fb_info) < 0) {
809 dev_err(&device->dev,
810 "GLCD: Frame Buffer Registration Failed!\n");
811 ret = -EINVAL;
812 goto err_dealloc_cmap;
813 }
814
815 /* enable raster engine */
816 lcdc_write(lcdc_read(LCD_RASTER_CTRL_REG) |
817 LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
818
819 return 0;
820
821err_dealloc_cmap:
822 fb_dealloc_cmap(&da8xx_fb_info->cmap);
823
824err_free_irq:
825 free_irq(par->irq, par);
826
827err_release_fb_mem:
828 dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
829 da8xx_fb_info->screen_base,
830 da8xx_fb_info->fix.smem_start);
831
832err_release_fb:
833 framebuffer_release(da8xx_fb_info);
834
835err_clk_disable:
836 clk_disable(fb_clk);
837
838err_clk_put:
839 clk_put(fb_clk);
840
841err_ioremap:
842 iounmap((void __iomem *)da8xx_fb_reg_base);
843
844err_request_mem:
845 release_mem_region(lcdc_regs->start, len);
846
847 return ret;
848}
849
850#ifdef CONFIG_PM
851static int fb_suspend(struct platform_device *dev, pm_message_t state)
852{
853 return -EBUSY;
854}
855static int fb_resume(struct platform_device *dev)
856{
857 return -EBUSY;
858}
859#else
860#define fb_suspend NULL
861#define fb_resume NULL
862#endif
863
864static struct platform_driver da8xx_fb_driver = {
865 .probe = fb_probe,
866 .remove = fb_remove,
867 .suspend = fb_suspend,
868 .resume = fb_resume,
869 .driver = {
870 .name = DRIVER_NAME,
871 .owner = THIS_MODULE,
872 },
873};
874
875static int __init da8xx_fb_init(void)
876{
877 return platform_driver_register(&da8xx_fb_driver);
878}
879
880static void __exit da8xx_fb_cleanup(void)
881{
882 platform_driver_unregister(&da8xx_fb_driver);
883}
884
885module_init(da8xx_fb_init);
886module_exit(da8xx_fb_cleanup);
887
888MODULE_DESCRIPTION("Framebuffer driver for TI da8xx/omap-l1xx");
889MODULE_AUTHOR("Texas Instruments");
890MODULE_LICENSE("GPL");
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
new file mode 100644
index 000000000000..bd9d46f95291
--- /dev/null
+++ b/drivers/video/ep93xx-fb.c
@@ -0,0 +1,646 @@
1/*
2 * linux/drivers/video/ep93xx-fb.c
3 *
4 * Framebuffer support for the EP93xx series.
5 *
6 * Copyright (C) 2007 Bluewater Systems Ltd
7 * Author: Ryan Mallon <ryan@bluewatersys.com>
8 *
9 * Copyright (c) 2009 H Hartley Sweeten <hsweeten@visionengravers.com>
10 *
11 * Based on the Cirrus Logic ep93xxfb driver, and various other ep93xxfb
12 * drivers.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/platform_device.h>
21#include <linux/dma-mapping.h>
22#include <linux/clk.h>
23#include <linux/fb.h>
24
25#include <mach/fb.h>
26
27/* Vertical Frame Timing Registers */
28#define EP93XXFB_VLINES_TOTAL 0x0000 /* SW locked */
29#define EP93XXFB_VSYNC 0x0004 /* SW locked */
30#define EP93XXFB_VACTIVE 0x0008 /* SW locked */
31#define EP93XXFB_VBLANK 0x0228 /* SW locked */
32#define EP93XXFB_VCLK 0x000c /* SW locked */
33
34/* Horizontal Frame Timing Registers */
35#define EP93XXFB_HCLKS_TOTAL 0x0010 /* SW locked */
36#define EP93XXFB_HSYNC 0x0014 /* SW locked */
37#define EP93XXFB_HACTIVE 0x0018 /* SW locked */
38#define EP93XXFB_HBLANK 0x022c /* SW locked */
39#define EP93XXFB_HCLK 0x001c /* SW locked */
40
41/* Frame Buffer Memory Configuration Registers */
42#define EP93XXFB_SCREEN_PAGE 0x0028
43#define EP93XXFB_SCREEN_HPAGE 0x002c
44#define EP93XXFB_SCREEN_LINES 0x0030
45#define EP93XXFB_LINE_LENGTH 0x0034
46#define EP93XXFB_VLINE_STEP 0x0038
47#define EP93XXFB_LINE_CARRY 0x003c /* SW locked */
48#define EP93XXFB_EOL_OFFSET 0x0230
49
50/* Other Video Registers */
51#define EP93XXFB_BRIGHTNESS 0x0020
52#define EP93XXFB_ATTRIBS 0x0024 /* SW locked */
53#define EP93XXFB_SWLOCK 0x007c /* SW locked */
54#define EP93XXFB_AC_RATE 0x0214
55#define EP93XXFB_FIFO_LEVEL 0x0234
56#define EP93XXFB_PIXELMODE 0x0054
57#define EP93XXFB_PIXELMODE_32BPP (0x7 << 0)
58#define EP93XXFB_PIXELMODE_24BPP (0x6 << 0)
59#define EP93XXFB_PIXELMODE_16BPP (0x4 << 0)
60#define EP93XXFB_PIXELMODE_8BPP (0x2 << 0)
61#define EP93XXFB_PIXELMODE_SHIFT_1P_24B (0x0 << 3)
62#define EP93XXFB_PIXELMODE_SHIFT_1P_18B (0x1 << 3)
63#define EP93XXFB_PIXELMODE_COLOR_LUT (0x0 << 10)
64#define EP93XXFB_PIXELMODE_COLOR_888 (0x4 << 10)
65#define EP93XXFB_PIXELMODE_COLOR_555 (0x5 << 10)
66#define EP93XXFB_PARL_IF_OUT 0x0058
67#define EP93XXFB_PARL_IF_IN 0x005c
68
69/* Blink Control Registers */
70#define EP93XXFB_BLINK_RATE 0x0040
71#define EP93XXFB_BLINK_MASK 0x0044
72#define EP93XXFB_BLINK_PATTRN 0x0048
73#define EP93XXFB_PATTRN_MASK 0x004c
74#define EP93XXFB_BKGRND_OFFSET 0x0050
75
76/* Hardware Cursor Registers */
77#define EP93XXFB_CURSOR_ADR_START 0x0060
78#define EP93XXFB_CURSOR_ADR_RESET 0x0064
79#define EP93XXFB_CURSOR_SIZE 0x0068
80#define EP93XXFB_CURSOR_COLOR1 0x006c
81#define EP93XXFB_CURSOR_COLOR2 0x0070
82#define EP93XXFB_CURSOR_BLINK_COLOR1 0x021c
83#define EP93XXFB_CURSOR_BLINK_COLOR2 0x0220
84#define EP93XXFB_CURSOR_XY_LOC 0x0074
85#define EP93XXFB_CURSOR_DSCAN_HY_LOC 0x0078
86#define EP93XXFB_CURSOR_BLINK_RATE_CTRL 0x0224
87
88/* LUT Registers */
89#define EP93XXFB_GRY_SCL_LUTR 0x0080
90#define EP93XXFB_GRY_SCL_LUTG 0x0280
91#define EP93XXFB_GRY_SCL_LUTB 0x0300
92#define EP93XXFB_LUT_SW_CONTROL 0x0218
93#define EP93XXFB_LUT_SW_CONTROL_SWTCH (1 << 0)
94#define EP93XXFB_LUT_SW_CONTROL_SSTAT (1 << 1)
95#define EP93XXFB_COLOR_LUT 0x0400
96
97/* Video Signature Registers */
98#define EP93XXFB_VID_SIG_RSLT_VAL 0x0200
99#define EP93XXFB_VID_SIG_CTRL 0x0204
100#define EP93XXFB_VSIG 0x0208
101#define EP93XXFB_HSIG 0x020c
102#define EP93XXFB_SIG_CLR_STR 0x0210
103
104/* Minimum / Maximum resolutions supported */
105#define EP93XXFB_MIN_XRES 64
106#define EP93XXFB_MIN_YRES 64
107#define EP93XXFB_MAX_XRES 1024
108#define EP93XXFB_MAX_YRES 768
109
110struct ep93xx_fbi {
111 struct ep93xxfb_mach_info *mach_info;
112 struct clk *clk;
113 struct resource *res;
114 void __iomem *mmio_base;
115 unsigned int pseudo_palette[256];
116};
117
118static int check_screenpage_bug = 1;
119module_param(check_screenpage_bug, int, 0644);
120MODULE_PARM_DESC(check_screenpage_bug,
121 "Check for bit 27 screen page bug. Default = 1");
122
123static inline unsigned int ep93xxfb_readl(struct ep93xx_fbi *fbi,
124 unsigned int off)
125{
126 return __raw_readl(fbi->mmio_base + off);
127}
128
129static inline void ep93xxfb_writel(struct ep93xx_fbi *fbi,
130 unsigned int val, unsigned int off)
131{
132 __raw_writel(val, fbi->mmio_base + off);
133}
134
135/*
136 * Write to one of the locked raster registers.
137 */
138static inline void ep93xxfb_out_locked(struct ep93xx_fbi *fbi,
139 unsigned int val, unsigned int reg)
140{
141 /*
142 * We don't need a lock or delay here since the raster register
143 * block will remain unlocked until the next access.
144 */
145 ep93xxfb_writel(fbi, 0xaa, EP93XXFB_SWLOCK);
146 ep93xxfb_writel(fbi, val, reg);
147}
148
149static void ep93xxfb_set_video_attribs(struct fb_info *info)
150{
151 struct ep93xx_fbi *fbi = info->par;
152 unsigned int attribs;
153
154 attribs = EP93XXFB_ENABLE;
155 attribs |= fbi->mach_info->flags;
156 ep93xxfb_out_locked(fbi, attribs, EP93XXFB_ATTRIBS);
157}
158
159static int ep93xxfb_set_pixelmode(struct fb_info *info)
160{
161 struct ep93xx_fbi *fbi = info->par;
162 unsigned int val;
163
164 info->var.transp.offset = 0;
165 info->var.transp.length = 0;
166
167 switch (info->var.bits_per_pixel) {
168 case 8:
169 val = EP93XXFB_PIXELMODE_8BPP | EP93XXFB_PIXELMODE_COLOR_LUT |
170 EP93XXFB_PIXELMODE_SHIFT_1P_18B;
171
172 info->var.red.offset = 0;
173 info->var.red.length = 8;
174 info->var.green.offset = 0;
175 info->var.green.length = 8;
176 info->var.blue.offset = 0;
177 info->var.blue.length = 8;
178 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
179 break;
180
181 case 16:
182 val = EP93XXFB_PIXELMODE_16BPP | EP93XXFB_PIXELMODE_COLOR_555 |
183 EP93XXFB_PIXELMODE_SHIFT_1P_18B;
184
185 info->var.red.offset = 11;
186 info->var.red.length = 5;
187 info->var.green.offset = 5;
188 info->var.green.length = 6;
189 info->var.blue.offset = 0;
190 info->var.blue.length = 5;
191 info->fix.visual = FB_VISUAL_TRUECOLOR;
192 break;
193
194 case 24:
195 val = EP93XXFB_PIXELMODE_24BPP | EP93XXFB_PIXELMODE_COLOR_888 |
196 EP93XXFB_PIXELMODE_SHIFT_1P_24B;
197
198 info->var.red.offset = 16;
199 info->var.red.length = 8;
200 info->var.green.offset = 8;
201 info->var.green.length = 8;
202 info->var.blue.offset = 0;
203 info->var.blue.length = 8;
204 info->fix.visual = FB_VISUAL_TRUECOLOR;
205 break;
206
207 case 32:
208 val = EP93XXFB_PIXELMODE_32BPP | EP93XXFB_PIXELMODE_COLOR_888 |
209 EP93XXFB_PIXELMODE_SHIFT_1P_24B;
210
211 info->var.red.offset = 16;
212 info->var.red.length = 8;
213 info->var.green.offset = 8;
214 info->var.green.length = 8;
215 info->var.blue.offset = 0;
216 info->var.blue.length = 8;
217 info->fix.visual = FB_VISUAL_TRUECOLOR;
218 break;
219
220 default:
221 return -EINVAL;
222 }
223
224 ep93xxfb_writel(fbi, val, EP93XXFB_PIXELMODE);
225 return 0;
226}
227
228static void ep93xxfb_set_timing(struct fb_info *info)
229{
230 struct ep93xx_fbi *fbi = info->par;
231 unsigned int vlines_total, hclks_total, start, stop;
232
233 vlines_total = info->var.yres + info->var.upper_margin +
234 info->var.lower_margin + info->var.vsync_len - 1;
235
236 hclks_total = info->var.xres + info->var.left_margin +
237 info->var.right_margin + info->var.hsync_len - 1;
238
239 ep93xxfb_out_locked(fbi, vlines_total, EP93XXFB_VLINES_TOTAL);
240 ep93xxfb_out_locked(fbi, hclks_total, EP93XXFB_HCLKS_TOTAL);
241
242 start = vlines_total;
243 stop = vlines_total - info->var.vsync_len;
244 ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VSYNC);
245
246 start = vlines_total - info->var.vsync_len - info->var.upper_margin;
247 stop = info->var.lower_margin - 1;
248 ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VBLANK);
249 ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VACTIVE);
250
251 start = vlines_total;
252 stop = vlines_total + 1;
253 ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VCLK);
254
255 start = hclks_total;
256 stop = hclks_total - info->var.hsync_len;
257 ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HSYNC);
258
259 start = hclks_total - info->var.hsync_len - info->var.left_margin;
260 stop = info->var.right_margin - 1;
261 ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HBLANK);
262 ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HACTIVE);
263
264 start = hclks_total;
265 stop = hclks_total;
266 ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HCLK);
267
268 ep93xxfb_out_locked(fbi, 0x0, EP93XXFB_LINE_CARRY);
269}
270
271static int ep93xxfb_set_par(struct fb_info *info)
272{
273 struct ep93xx_fbi *fbi = info->par;
274
275 clk_set_rate(fbi->clk, 1000 * PICOS2KHZ(info->var.pixclock));
276
277 ep93xxfb_set_timing(info);
278
279 info->fix.line_length = info->var.xres_virtual *
280 info->var.bits_per_pixel / 8;
281
282 ep93xxfb_writel(fbi, info->fix.smem_start, EP93XXFB_SCREEN_PAGE);
283 ep93xxfb_writel(fbi, info->var.yres - 1, EP93XXFB_SCREEN_LINES);
284 ep93xxfb_writel(fbi, ((info->var.xres * info->var.bits_per_pixel)
285 / 32) - 1, EP93XXFB_LINE_LENGTH);
286 ep93xxfb_writel(fbi, info->fix.line_length / 4, EP93XXFB_VLINE_STEP);
287 ep93xxfb_set_video_attribs(info);
288 return 0;
289}
290
291static int ep93xxfb_check_var(struct fb_var_screeninfo *var,
292 struct fb_info *info)
293{
294 int err;
295
296 err = ep93xxfb_set_pixelmode(info);
297 if (err)
298 return err;
299
300 var->xres = max_t(unsigned int, var->xres, EP93XXFB_MIN_XRES);
301 var->xres = min_t(unsigned int, var->xres, EP93XXFB_MAX_XRES);
302 var->xres_virtual = max(var->xres_virtual, var->xres);
303
304 var->yres = max_t(unsigned int, var->yres, EP93XXFB_MIN_YRES);
305 var->yres = min_t(unsigned int, var->yres, EP93XXFB_MAX_YRES);
306 var->yres_virtual = max(var->yres_virtual, var->yres);
307
308 return 0;
309}
310
311static int ep93xxfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
312{
313 unsigned int offset = vma->vm_pgoff << PAGE_SHIFT;
314
315 if (offset < info->fix.smem_len) {
316 return dma_mmap_writecombine(info->dev, vma, info->screen_base,
317 info->fix.smem_start,
318 info->fix.smem_len);
319 }
320
321 return -EINVAL;
322}
323
324static int ep93xxfb_blank(int blank_mode, struct fb_info *info)
325{
326 struct ep93xx_fbi *fbi = info->par;
327 unsigned int attribs = ep93xxfb_readl(fbi, EP93XXFB_ATTRIBS);
328
329 if (blank_mode) {
330 if (fbi->mach_info->blank)
331 fbi->mach_info->blank(blank_mode, info);
332 ep93xxfb_out_locked(fbi, attribs & ~EP93XXFB_ENABLE,
333 EP93XXFB_ATTRIBS);
334 clk_disable(fbi->clk);
335 } else {
336 clk_enable(fbi->clk);
337 ep93xxfb_out_locked(fbi, attribs | EP93XXFB_ENABLE,
338 EP93XXFB_ATTRIBS);
339 if (fbi->mach_info->blank)
340 fbi->mach_info->blank(blank_mode, info);
341 }
342
343 return 0;
344}
345
346static inline int ep93xxfb_convert_color(int val, int width)
347{
348 return ((val << width) + 0x7fff - val) >> 16;
349}
350
351static int ep93xxfb_setcolreg(unsigned int regno, unsigned int red,
352 unsigned int green, unsigned int blue,
353 unsigned int transp, struct fb_info *info)
354{
355 struct ep93xx_fbi *fbi = info->par;
356 unsigned int *pal = info->pseudo_palette;
357 unsigned int ctrl, i, rgb, lut_current, lut_stat;
358
359 switch (info->fix.visual) {
360 case FB_VISUAL_PSEUDOCOLOR:
361 rgb = ((red & 0xff00) << 8) | (green & 0xff00) |
362 ((blue & 0xff00) >> 8);
363
364 pal[regno] = rgb;
365 ep93xxfb_writel(fbi, rgb, (EP93XXFB_COLOR_LUT + (regno << 2)));
366 ctrl = ep93xxfb_readl(fbi, EP93XXFB_LUT_SW_CONTROL);
367 lut_stat = !!(ctrl & EP93XXFB_LUT_SW_CONTROL_SSTAT);
368 lut_current = !!(ctrl & EP93XXFB_LUT_SW_CONTROL_SWTCH);
369
370 if (lut_stat == lut_current) {
371 for (i = 0; i < 256; i++) {
372 ep93xxfb_writel(fbi, pal[i],
373 EP93XXFB_COLOR_LUT + (i << 2));
374 }
375
376 ep93xxfb_writel(fbi,
377 ctrl ^ EP93XXFB_LUT_SW_CONTROL_SWTCH,
378 EP93XXFB_LUT_SW_CONTROL);
379 }
380 break;
381
382 case FB_VISUAL_TRUECOLOR:
383 if (regno > 16)
384 return 1;
385
386 red = ep93xxfb_convert_color(red, info->var.red.length);
387 green = ep93xxfb_convert_color(green, info->var.green.length);
388 blue = ep93xxfb_convert_color(blue, info->var.blue.length);
389 transp = ep93xxfb_convert_color(transp,
390 info->var.transp.length);
391
392 pal[regno] = (red << info->var.red.offset) |
393 (green << info->var.green.offset) |
394 (blue << info->var.blue.offset) |
395 (transp << info->var.transp.offset);
396 break;
397
398 default:
399 return 1;
400 }
401
402 return 0;
403}
404
405static struct fb_ops ep93xxfb_ops = {
406 .owner = THIS_MODULE,
407 .fb_check_var = ep93xxfb_check_var,
408 .fb_set_par = ep93xxfb_set_par,
409 .fb_blank = ep93xxfb_blank,
410 .fb_fillrect = cfb_fillrect,
411 .fb_copyarea = cfb_copyarea,
412 .fb_imageblit = cfb_imageblit,
413 .fb_setcolreg = ep93xxfb_setcolreg,
414 .fb_mmap = ep93xxfb_mmap,
415};
416
417static int __init ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info)
418{
419 int i, fb_size = 0;
420
421 if (mach_info->num_modes == EP93XXFB_USE_MODEDB) {
422 fb_size = EP93XXFB_MAX_XRES * EP93XXFB_MAX_YRES *
423 mach_info->bpp / 8;
424 } else {
425 for (i = 0; i < mach_info->num_modes; i++) {
426 const struct fb_videomode *mode;
427 int size;
428
429 mode = &mach_info->modes[i];
430 size = mode->xres * mode->yres * mach_info->bpp / 8;
431 if (size > fb_size)
432 fb_size = size;
433 }
434 }
435
436 return fb_size;
437}
438
439static int __init ep93xxfb_alloc_videomem(struct fb_info *info)
440{
441 struct ep93xx_fbi *fbi = info->par;
442 char __iomem *virt_addr;
443 dma_addr_t phys_addr;
444 unsigned int fb_size;
445
446 fb_size = ep93xxfb_calc_fbsize(fbi->mach_info);
447 virt_addr = dma_alloc_writecombine(info->dev, fb_size,
448 &phys_addr, GFP_KERNEL);
449 if (!virt_addr)
450 return -ENOMEM;
451
452 /*
453 * There is a bug in the ep93xx framebuffer which causes problems
454 * if bit 27 of the physical address is set.
455 * See: http://marc.info/?l=linux-arm-kernel&m=110061245502000&w=2
456 * There does not seem to be any offical errata for this, but I
457 * have confirmed the problem exists on my hardware (ep9315) at
458 * least.
459 */
460 if (check_screenpage_bug && phys_addr & (1 << 27)) {
461 dev_err(info->dev, "ep93xx framebuffer bug. phys addr (0x%x) "
462 "has bit 27 set: cannot init framebuffer\n",
463 phys_addr);
464
465 dma_free_coherent(info->dev, fb_size, virt_addr, phys_addr);
466 return -ENOMEM;
467 }
468
469 info->fix.smem_start = phys_addr;
470 info->fix.smem_len = fb_size;
471 info->screen_base = virt_addr;
472
473 return 0;
474}
475
476static void ep93xxfb_dealloc_videomem(struct fb_info *info)
477{
478 if (info->screen_base)
479 dma_free_coherent(info->dev, info->fix.smem_len,
480 info->screen_base, info->fix.smem_start);
481}
482
483static int __init ep93xxfb_probe(struct platform_device *pdev)
484{
485 struct ep93xxfb_mach_info *mach_info = pdev->dev.platform_data;
486 struct fb_info *info;
487 struct ep93xx_fbi *fbi;
488 struct resource *res;
489 char *video_mode;
490 int err;
491
492 if (!mach_info)
493 return -EINVAL;
494
495 info = framebuffer_alloc(sizeof(struct ep93xx_fbi), &pdev->dev);
496 if (!info)
497 return -ENOMEM;
498
499 info->dev = &pdev->dev;
500 platform_set_drvdata(pdev, info);
501 fbi = info->par;
502 fbi->mach_info = mach_info;
503
504 err = fb_alloc_cmap(&info->cmap, 256, 0);
505 if (err)
506 goto failed;
507
508 err = ep93xxfb_alloc_videomem(info);
509 if (err)
510 goto failed;
511
512 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
513 if (!res) {
514 err = -ENXIO;
515 goto failed;
516 }
517
518 res = request_mem_region(res->start, resource_size(res), pdev->name);
519 if (!res) {
520 err = -EBUSY;
521 goto failed;
522 }
523
524 fbi->res = res;
525 fbi->mmio_base = ioremap(res->start, resource_size(res));
526 if (!fbi->mmio_base) {
527 err = -ENXIO;
528 goto failed;
529 }
530
531 strcpy(info->fix.id, pdev->name);
532 info->fbops = &ep93xxfb_ops;
533 info->fix.type = FB_TYPE_PACKED_PIXELS;
534 info->fix.accel = FB_ACCEL_NONE;
535 info->var.activate = FB_ACTIVATE_NOW;
536 info->var.vmode = FB_VMODE_NONINTERLACED;
537 info->flags = FBINFO_DEFAULT;
538 info->node = -1;
539 info->state = FBINFO_STATE_RUNNING;
540 info->pseudo_palette = &fbi->pseudo_palette;
541
542 fb_get_options("ep93xx-fb", &video_mode);
543 err = fb_find_mode(&info->var, info, video_mode,
544 fbi->mach_info->modes, fbi->mach_info->num_modes,
545 fbi->mach_info->default_mode, fbi->mach_info->bpp);
546 if (err == 0) {
547 dev_err(info->dev, "No suitable video mode found\n");
548 err = -EINVAL;
549 goto failed;
550 }
551
552 if (mach_info->setup) {
553 err = mach_info->setup(pdev);
554 if (err)
555 return err;
556 }
557
558 err = ep93xxfb_check_var(&info->var, info);
559 if (err)
560 goto failed;
561
562 fbi->clk = clk_get(info->dev, NULL);
563 if (IS_ERR(fbi->clk)) {
564 err = PTR_ERR(fbi->clk);
565 fbi->clk = NULL;
566 goto failed;
567 }
568
569 ep93xxfb_set_par(info);
570 clk_enable(fbi->clk);
571
572 err = register_framebuffer(info);
573 if (err)
574 goto failed;
575
576 dev_info(info->dev, "registered. Mode = %dx%d-%d\n",
577 info->var.xres, info->var.yres, info->var.bits_per_pixel);
578 return 0;
579
580failed:
581 if (fbi->clk)
582 clk_put(fbi->clk);
583 if (fbi->mmio_base)
584 iounmap(fbi->mmio_base);
585 if (fbi->res)
586 release_mem_region(fbi->res->start, resource_size(fbi->res));
587 ep93xxfb_dealloc_videomem(info);
588 if (&info->cmap)
589 fb_dealloc_cmap(&info->cmap);
590 if (fbi->mach_info->teardown)
591 fbi->mach_info->teardown(pdev);
592 kfree(info);
593 platform_set_drvdata(pdev, NULL);
594
595 return err;
596}
597
598static int ep93xxfb_remove(struct platform_device *pdev)
599{
600 struct fb_info *info = platform_get_drvdata(pdev);
601 struct ep93xx_fbi *fbi = info->par;
602
603 unregister_framebuffer(info);
604 clk_disable(fbi->clk);
605 clk_put(fbi->clk);
606 iounmap(fbi->mmio_base);
607 release_mem_region(fbi->res->start, resource_size(fbi->res));
608 ep93xxfb_dealloc_videomem(info);
609 fb_dealloc_cmap(&info->cmap);
610
611 if (fbi->mach_info->teardown)
612 fbi->mach_info->teardown(pdev);
613
614 kfree(info);
615 platform_set_drvdata(pdev, NULL);
616
617 return 0;
618}
619
620static struct platform_driver ep93xxfb_driver = {
621 .probe = ep93xxfb_probe,
622 .remove = ep93xxfb_remove,
623 .driver = {
624 .name = "ep93xx-fb",
625 .owner = THIS_MODULE,
626 },
627};
628
629static int __devinit ep93xxfb_init(void)
630{
631 return platform_driver_register(&ep93xxfb_driver);
632}
633
634static void __exit ep93xxfb_exit(void)
635{
636 platform_driver_unregister(&ep93xxfb_driver);
637}
638
639module_init(ep93xxfb_init);
640module_exit(ep93xxfb_exit);
641
642MODULE_DESCRIPTION("EP93XX Framebuffer Driver");
643MODULE_ALIAS("platform:ep93xx-fb");
644MODULE_AUTHOR("Ryan Mallon <ryan&bluewatersys.com>, "
645 "H Hartley Sweeten <hsweeten@visionengravers.com");
646MODULE_LICENSE("GPL");
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 0a7a6679ee6e..c27ab1ed9604 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -125,7 +125,7 @@ page_already_added:
125 return 0; 125 return 0;
126} 126}
127 127
128static struct vm_operations_struct fb_deferred_io_vm_ops = { 128static const struct vm_operations_struct fb_deferred_io_vm_ops = {
129 .fault = fb_deferred_io_fault, 129 .fault = fb_deferred_io_fault,
130 .page_mkwrite = fb_deferred_io_mkwrite, 130 .page_mkwrite = fb_deferred_io_mkwrite,
131}; 131};
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 750c71f141f4..99bbd282ce63 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -871,8 +871,8 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
871 err = -EINVAL; 871 err = -EINVAL;
872 872
873 if (err || !info->fbops->fb_pan_display || 873 if (err || !info->fbops->fb_pan_display ||
874 var->yoffset + yres > info->var.yres_virtual || 874 var->yoffset > info->var.yres_virtual - yres ||
875 var->xoffset + info->var.xres > info->var.xres_virtual) 875 var->xoffset > info->var.xres_virtual - info->var.xres)
876 return -EINVAL; 876 return -EINVAL;
877 877
878 if ((err = info->fbops->fb_pan_display(var, info))) 878 if ((err = info->fbops->fb_pan_display(var, info)))
@@ -954,6 +954,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
954 goto done; 954 goto done;
955 955
956 if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { 956 if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
957 struct fb_var_screeninfo old_var;
957 struct fb_videomode mode; 958 struct fb_videomode mode;
958 959
959 if (info->fbops->fb_get_caps) { 960 if (info->fbops->fb_get_caps) {
@@ -963,10 +964,20 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
963 goto done; 964 goto done;
964 } 965 }
965 966
967 old_var = info->var;
966 info->var = *var; 968 info->var = *var;
967 969
968 if (info->fbops->fb_set_par) 970 if (info->fbops->fb_set_par) {
969 info->fbops->fb_set_par(info); 971 ret = info->fbops->fb_set_par(info);
972
973 if (ret) {
974 info->var = old_var;
975 printk(KERN_WARNING "detected "
976 "fb_set_par error, "
977 "error code: %d\n", ret);
978 goto done;
979 }
980 }
970 981
971 fb_pan_display(info, &info->var); 982 fb_pan_display(info, &info->var);
972 fb_set_cmap(&info->cmap, info); 983 fb_set_cmap(&info->cmap, info);
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 15a0ee6d8e23..66358fa825f3 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -33,6 +33,7 @@
33#include <linux/math64.h> 33#include <linux/math64.h>
34 34
35#include <mach/imxfb.h> 35#include <mach/imxfb.h>
36#include <mach/hardware.h>
36 37
37/* 38/*
38 * Complain if VAR is out of range. 39 * Complain if VAR is out of range.
@@ -129,6 +130,10 @@
129#define LCDISR_EOF (1<<1) 130#define LCDISR_EOF (1<<1)
130#define LCDISR_BOF (1<<0) 131#define LCDISR_BOF (1<<0)
131 132
133/* Used fb-mode. Can be set on kernel command line, therefore file-static. */
134static const char *fb_mode;
135
136
132/* 137/*
133 * These are the bitfields for each 138 * These are the bitfields for each
134 * display depth that we support. 139 * display depth that we support.
@@ -145,10 +150,6 @@ struct imxfb_info {
145 void __iomem *regs; 150 void __iomem *regs;
146 struct clk *clk; 151 struct clk *clk;
147 152
148 u_int max_bpp;
149 u_int max_xres;
150 u_int max_yres;
151
152 /* 153 /*
153 * These are the addresses we mapped 154 * These are the addresses we mapped
154 * the framebuffer memory region to. 155 * the framebuffer memory region to.
@@ -172,6 +173,9 @@ struct imxfb_info {
172 cmap_static:1, 173 cmap_static:1,
173 unused:30; 174 unused:30;
174 175
176 struct imx_fb_videomode *mode;
177 int num_modes;
178
175 void (*lcd_power)(int); 179 void (*lcd_power)(int);
176 void (*backlight_power)(int); 180 void (*backlight_power)(int);
177}; 181};
@@ -298,6 +302,18 @@ static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
298 return ret; 302 return ret;
299} 303}
300 304
305static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
306{
307 struct imx_fb_videomode *m;
308 int i;
309
310 for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) {
311 if (!strcmp(m->mode.name, fb_mode))
312 return m;
313 }
314 return NULL;
315}
316
301/* 317/*
302 * imxfb_check_var(): 318 * imxfb_check_var():
303 * Round up in the following order: bits_per_pixel, xres, 319 * Round up in the following order: bits_per_pixel, xres,
@@ -308,35 +324,81 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
308{ 324{
309 struct imxfb_info *fbi = info->par; 325 struct imxfb_info *fbi = info->par;
310 struct imxfb_rgb *rgb; 326 struct imxfb_rgb *rgb;
327 const struct imx_fb_videomode *imxfb_mode;
328 unsigned long lcd_clk;
329 unsigned long long tmp;
330 u32 pcr = 0;
311 331
312 if (var->xres < MIN_XRES) 332 if (var->xres < MIN_XRES)
313 var->xres = MIN_XRES; 333 var->xres = MIN_XRES;
314 if (var->yres < MIN_YRES) 334 if (var->yres < MIN_YRES)
315 var->yres = MIN_YRES; 335 var->yres = MIN_YRES;
316 if (var->xres > fbi->max_xres) 336
317 var->xres = fbi->max_xres; 337 imxfb_mode = imxfb_find_mode(fbi);
318 if (var->yres > fbi->max_yres) 338 if (!imxfb_mode)
319 var->yres = fbi->max_yres; 339 return -EINVAL;
320 var->xres_virtual = max(var->xres_virtual, var->xres); 340
321 var->yres_virtual = max(var->yres_virtual, var->yres); 341 var->xres = imxfb_mode->mode.xres;
342 var->yres = imxfb_mode->mode.yres;
343 var->bits_per_pixel = imxfb_mode->bpp;
344 var->pixclock = imxfb_mode->mode.pixclock;
345 var->hsync_len = imxfb_mode->mode.hsync_len;
346 var->left_margin = imxfb_mode->mode.left_margin;
347 var->right_margin = imxfb_mode->mode.right_margin;
348 var->vsync_len = imxfb_mode->mode.vsync_len;
349 var->upper_margin = imxfb_mode->mode.upper_margin;
350 var->lower_margin = imxfb_mode->mode.lower_margin;
351 var->sync = imxfb_mode->mode.sync;
352 var->xres_virtual = max(var->xres_virtual, var->xres);
353 var->yres_virtual = max(var->yres_virtual, var->yres);
322 354
323 pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); 355 pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
356
357 lcd_clk = clk_get_rate(fbi->clk);
358
359 tmp = var->pixclock * (unsigned long long)lcd_clk;
360
361 do_div(tmp, 1000000);
362
363 if (do_div(tmp, 1000000) > 500000)
364 tmp++;
365
366 pcr = (unsigned int)tmp;
367
368 if (--pcr > 0x3F) {
369 pcr = 0x3F;
370 printk(KERN_WARNING "Must limit pixel clock to %luHz\n",
371 lcd_clk / pcr);
372 }
373
324 switch (var->bits_per_pixel) { 374 switch (var->bits_per_pixel) {
325 case 32: 375 case 32:
376 pcr |= PCR_BPIX_18;
326 rgb = &def_rgb_18; 377 rgb = &def_rgb_18;
327 break; 378 break;
328 case 16: 379 case 16:
329 default: 380 default:
330 if (fbi->pcr & PCR_TFT) 381 if (cpu_is_mx1())
382 pcr |= PCR_BPIX_12;
383 else
384 pcr |= PCR_BPIX_16;
385
386 if (imxfb_mode->pcr & PCR_TFT)
331 rgb = &def_rgb_16_tft; 387 rgb = &def_rgb_16_tft;
332 else 388 else
333 rgb = &def_rgb_16_stn; 389 rgb = &def_rgb_16_stn;
334 break; 390 break;
335 case 8: 391 case 8:
392 pcr |= PCR_BPIX_8;
336 rgb = &def_rgb_8; 393 rgb = &def_rgb_8;
337 break; 394 break;
338 } 395 }
339 396
397 /* add sync polarities */
398 pcr |= imxfb_mode->pcr & ~(0x3f | (7 << 25));
399
400 fbi->pcr = pcr;
401
340 /* 402 /*
341 * Copy the RGB parameters for this display 403 * Copy the RGB parameters for this display
342 * from the machine specific parameters. 404 * from the machine specific parameters.
@@ -393,10 +455,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
393 455
394 writel(fbi->screen_dma, fbi->regs + LCDC_SSA); 456 writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
395 457
396 /* physical screen start address */
397 writel(VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4),
398 fbi->regs + LCDC_VPW);
399
400 /* panning offset 0 (0 pixel offset) */ 458 /* panning offset 0 (0 pixel offset) */
401 writel(0x00000000, fbi->regs + LCDC_POS); 459 writel(0x00000000, fbi->regs + LCDC_POS);
402 460
@@ -468,8 +526,6 @@ static struct fb_ops imxfb_ops = {
468static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) 526static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
469{ 527{
470 struct imxfb_info *fbi = info->par; 528 struct imxfb_info *fbi = info->par;
471 unsigned int pcr, lcd_clk;
472 unsigned long long tmp;
473 529
474 pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", 530 pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
475 var->xres, var->hsync_len, 531 var->xres, var->hsync_len,
@@ -505,6 +561,10 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
505 info->fix.id, var->lower_margin); 561 info->fix.id, var->lower_margin);
506#endif 562#endif
507 563
564 /* physical screen start address */
565 writel(VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4),
566 fbi->regs + LCDC_VPW);
567
508 writel(HCR_H_WIDTH(var->hsync_len - 1) | 568 writel(HCR_H_WIDTH(var->hsync_len - 1) |
509 HCR_H_WAIT_1(var->right_margin - 1) | 569 HCR_H_WAIT_1(var->right_margin - 1) |
510 HCR_H_WAIT_2(var->left_margin - 3), 570 HCR_H_WAIT_2(var->left_margin - 3),
@@ -518,22 +578,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
518 writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres), 578 writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres),
519 fbi->regs + LCDC_SIZE); 579 fbi->regs + LCDC_SIZE);
520 580
521 lcd_clk = clk_get_rate(fbi->clk); 581 writel(fbi->pcr, fbi->regs + LCDC_PCR);
522 tmp = var->pixclock * (unsigned long long)lcd_clk;
523 do_div(tmp, 1000000);
524 if (do_div(tmp, 1000000) > 500000)
525 tmp++;
526 pcr = (unsigned int)tmp;
527 if (--pcr > 0x3F) {
528 pcr = 0x3F;
529 printk(KERN_WARNING "Must limit pixel clock to %uHz\n",
530 lcd_clk / pcr);
531 }
532
533 /* add sync polarities */
534 pcr |= fbi->pcr & ~0x3F;
535
536 writel(pcr, fbi->regs + LCDC_PCR);
537 writel(fbi->pwmr, fbi->regs + LCDC_PWMR); 582 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
538 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); 583 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
539 writel(fbi->dmacr, fbi->regs + LCDC_DMACR); 584 writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
@@ -575,6 +620,8 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
575 struct imx_fb_platform_data *pdata = pdev->dev.platform_data; 620 struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
576 struct fb_info *info = dev_get_drvdata(&pdev->dev); 621 struct fb_info *info = dev_get_drvdata(&pdev->dev);
577 struct imxfb_info *fbi = info->par; 622 struct imxfb_info *fbi = info->par;
623 struct imx_fb_videomode *m;
624 int i;
578 625
579 pr_debug("%s\n",__func__); 626 pr_debug("%s\n",__func__);
580 627
@@ -603,35 +650,18 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
603 info->fbops = &imxfb_ops; 650 info->fbops = &imxfb_ops;
604 info->flags = FBINFO_FLAG_DEFAULT | 651 info->flags = FBINFO_FLAG_DEFAULT |
605 FBINFO_READS_FAST; 652 FBINFO_READS_FAST;
606
607 fbi->max_xres = pdata->xres;
608 info->var.xres = pdata->xres;
609 info->var.xres_virtual = pdata->xres;
610 fbi->max_yres = pdata->yres;
611 info->var.yres = pdata->yres;
612 info->var.yres_virtual = pdata->yres;
613 fbi->max_bpp = pdata->bpp;
614 info->var.bits_per_pixel = pdata->bpp;
615 info->var.nonstd = pdata->nonstd;
616 info->var.pixclock = pdata->pixclock;
617 info->var.hsync_len = pdata->hsync_len;
618 info->var.left_margin = pdata->left_margin;
619 info->var.right_margin = pdata->right_margin;
620 info->var.vsync_len = pdata->vsync_len;
621 info->var.upper_margin = pdata->upper_margin;
622 info->var.lower_margin = pdata->lower_margin;
623 info->var.sync = pdata->sync;
624 info->var.grayscale = pdata->cmap_greyscale; 653 info->var.grayscale = pdata->cmap_greyscale;
625 fbi->cmap_inverse = pdata->cmap_inverse; 654 fbi->cmap_inverse = pdata->cmap_inverse;
626 fbi->cmap_static = pdata->cmap_static; 655 fbi->cmap_static = pdata->cmap_static;
627 fbi->pcr = pdata->pcr;
628 fbi->lscr1 = pdata->lscr1; 656 fbi->lscr1 = pdata->lscr1;
629 fbi->dmacr = pdata->dmacr; 657 fbi->dmacr = pdata->dmacr;
630 fbi->pwmr = pdata->pwmr; 658 fbi->pwmr = pdata->pwmr;
631 fbi->lcd_power = pdata->lcd_power; 659 fbi->lcd_power = pdata->lcd_power;
632 fbi->backlight_power = pdata->backlight_power; 660 fbi->backlight_power = pdata->backlight_power;
633 info->fix.smem_len = fbi->max_xres * fbi->max_yres * 661
634 fbi->max_bpp / 8; 662 for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++)
663 info->fix.smem_len = max_t(size_t, info->fix.smem_len,
664 m->mode.xres * m->mode.yres * m->bpp / 8);
635 665
636 return 0; 666 return 0;
637} 667}
@@ -642,9 +672,9 @@ static int __init imxfb_probe(struct platform_device *pdev)
642 struct fb_info *info; 672 struct fb_info *info;
643 struct imx_fb_platform_data *pdata; 673 struct imx_fb_platform_data *pdata;
644 struct resource *res; 674 struct resource *res;
645 int ret; 675 int ret, i;
646 676
647 printk("i.MX Framebuffer driver\n"); 677 dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
648 678
649 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 679 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
650 if (!res) 680 if (!res)
@@ -662,6 +692,9 @@ static int __init imxfb_probe(struct platform_device *pdev)
662 692
663 fbi = info->par; 693 fbi = info->par;
664 694
695 if (!fb_mode)
696 fb_mode = pdata->mode[0].mode.name;
697
665 platform_set_drvdata(pdev, info); 698 platform_set_drvdata(pdev, info);
666 699
667 ret = imxfb_init_fbinfo(pdev); 700 ret = imxfb_init_fbinfo(pdev);
@@ -677,14 +710,14 @@ static int __init imxfb_probe(struct platform_device *pdev)
677 710
678 fbi->clk = clk_get(&pdev->dev, NULL); 711 fbi->clk = clk_get(&pdev->dev, NULL);
679 if (IS_ERR(fbi->clk)) { 712 if (IS_ERR(fbi->clk)) {
680 ret = PTR_ERR(fbi->clk);; 713 ret = PTR_ERR(fbi->clk);
681 dev_err(&pdev->dev, "unable to get clock: %d\n", ret); 714 dev_err(&pdev->dev, "unable to get clock: %d\n", ret);
682 goto failed_getclock; 715 goto failed_getclock;
683 } 716 }
684 717
685 fbi->regs = ioremap(res->start, resource_size(res)); 718 fbi->regs = ioremap(res->start, resource_size(res));
686 if (fbi->regs == NULL) { 719 if (fbi->regs == NULL) {
687 printk(KERN_ERR"Cannot map frame buffer registers\n"); 720 dev_err(&pdev->dev, "Cannot map frame buffer registers\n");
688 goto failed_ioremap; 721 goto failed_ioremap;
689 } 722 }
690 723
@@ -719,6 +752,13 @@ static int __init imxfb_probe(struct platform_device *pdev)
719 goto failed_platform_init; 752 goto failed_platform_init;
720 } 753 }
721 754
755 fbi->mode = pdata->mode;
756 fbi->num_modes = pdata->num_modes;
757
758 INIT_LIST_HEAD(&info->modelist);
759 for (i = 0; i < pdata->num_modes; i++)
760 fb_add_videomode(&pdata->mode[i].mode, &info->modelist);
761
722 /* 762 /*
723 * This makes sure that our colour bitfield 763 * This makes sure that our colour bitfield
724 * descriptors are correctly initialised. 764 * descriptors are correctly initialised.
@@ -754,7 +794,7 @@ failed_map:
754failed_getclock: 794failed_getclock:
755 iounmap(fbi->regs); 795 iounmap(fbi->regs);
756failed_ioremap: 796failed_ioremap:
757 release_mem_region(res->start, res->end - res->start); 797 release_mem_region(res->start, resource_size(res));
758failed_req: 798failed_req:
759 kfree(info->pseudo_palette); 799 kfree(info->pseudo_palette);
760failed_init: 800failed_init:
@@ -785,7 +825,7 @@ static int __devexit imxfb_remove(struct platform_device *pdev)
785 framebuffer_release(info); 825 framebuffer_release(info);
786 826
787 iounmap(fbi->regs); 827 iounmap(fbi->regs);
788 release_mem_region(res->start, res->end - res->start + 1); 828 release_mem_region(res->start, resource_size(res));
789 clk_disable(fbi->clk); 829 clk_disable(fbi->clk);
790 clk_put(fbi->clk); 830 clk_put(fbi->clk);
791 831
@@ -811,8 +851,34 @@ static struct platform_driver imxfb_driver = {
811 }, 851 },
812}; 852};
813 853
854static int imxfb_setup(void)
855{
856#ifndef MODULE
857 char *opt, *options = NULL;
858
859 if (fb_get_options("imxfb", &options))
860 return -ENODEV;
861
862 if (!options || !*options)
863 return 0;
864
865 while ((opt = strsep(&options, ",")) != NULL) {
866 if (!*opt)
867 continue;
868 else
869 fb_mode = opt;
870 }
871#endif
872 return 0;
873}
874
814int __init imxfb_init(void) 875int __init imxfb_init(void)
815{ 876{
877 int ret = imxfb_setup();
878
879 if (ret < 0)
880 return ret;
881
816 return platform_driver_probe(&imxfb_driver, imxfb_probe); 882 return platform_driver_probe(&imxfb_driver, imxfb_probe);
817} 883}
818 884
diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c
index d42346e7fdda..09f6e045d5be 100644
--- a/drivers/video/matrox/g450_pll.c
+++ b/drivers/video/matrox/g450_pll.c
@@ -25,16 +25,19 @@ static inline unsigned int g450_f2vco(unsigned char p, unsigned int fin) {
25 return (p & 0x40) ? fin : fin << ((p & 3) + 1); 25 return (p & 0x40) ? fin : fin << ((p & 3) + 1);
26} 26}
27 27
28static unsigned int g450_mnp2vco(CPMINFO unsigned int mnp) { 28static unsigned int g450_mnp2vco(const struct matrox_fb_info *minfo,
29 unsigned int mnp)
30{
29 unsigned int m, n; 31 unsigned int m, n;
30 32
31 m = ((mnp >> 16) & 0x0FF) + 1; 33 m = ((mnp >> 16) & 0x0FF) + 1;
32 n = ((mnp >> 7) & 0x1FE) + 4; 34 n = ((mnp >> 7) & 0x1FE) + 4;
33 return (ACCESS_FBINFO(features).pll.ref_freq * n + (m >> 1)) / m; 35 return (minfo->features.pll.ref_freq * n + (m >> 1)) / m;
34} 36}
35 37
36unsigned int g450_mnp2f(CPMINFO unsigned int mnp) { 38unsigned int g450_mnp2f(const struct matrox_fb_info *minfo, unsigned int mnp)
37 return g450_vco2f(mnp, g450_mnp2vco(PMINFO mnp)); 39{
40 return g450_vco2f(mnp, g450_mnp2vco(minfo, mnp));
38} 41}
39 42
40static inline unsigned int pll_freq_delta(unsigned int f1, unsigned int f2) { 43static inline unsigned int pll_freq_delta(unsigned int f1, unsigned int f2) {
@@ -49,7 +52,10 @@ static inline unsigned int pll_freq_delta(unsigned int f1, unsigned int f2) {
49#define NO_MORE_MNP 0x01FFFFFF 52#define NO_MORE_MNP 0x01FFFFFF
50#define G450_MNP_FREQBITS (0xFFFFFF43) /* do not mask high byte so we'll catch NO_MORE_MNP */ 53#define G450_MNP_FREQBITS (0xFFFFFF43) /* do not mask high byte so we'll catch NO_MORE_MNP */
51 54
52static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, unsigned int* fvco, unsigned int mnp) { 55static unsigned int g450_nextpll(const struct matrox_fb_info *minfo,
56 const struct matrox_pll_limits *pi,
57 unsigned int *fvco, unsigned int mnp)
58{
53 unsigned int m, n, p; 59 unsigned int m, n, p;
54 unsigned int tvco = *fvco; 60 unsigned int tvco = *fvco;
55 61
@@ -90,12 +96,15 @@ static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, uns
90 } else { 96 } else {
91 m--; 97 m--;
92 } 98 }
93 n = ((tvco * (m+1) + ACCESS_FBINFO(features).pll.ref_freq) / (ACCESS_FBINFO(features).pll.ref_freq * 2)) - 2; 99 n = ((tvco * (m+1) + minfo->features.pll.ref_freq) / (minfo->features.pll.ref_freq * 2)) - 2;
94 } while (n < 0x03 || n > 0x7A); 100 } while (n < 0x03 || n > 0x7A);
95 return (m << 16) | (n << 8) | p; 101 return (m << 16) | (n << 8) | p;
96} 102}
97 103
98static unsigned int g450_firstpll(CPMINFO const struct matrox_pll_limits* pi, unsigned int* vco, unsigned int fout) { 104static unsigned int g450_firstpll(const struct matrox_fb_info *minfo,
105 const struct matrox_pll_limits *pi,
106 unsigned int *vco, unsigned int fout)
107{
99 unsigned int p; 108 unsigned int p;
100 unsigned int vcomax; 109 unsigned int vcomax;
101 110
@@ -121,88 +130,94 @@ static unsigned int g450_firstpll(CPMINFO const struct matrox_pll_limits* pi, un
121 } 130 }
122 *vco = tvco; 131 *vco = tvco;
123 } 132 }
124 return g450_nextpll(PMINFO pi, vco, 0xFF0000 | p); 133 return g450_nextpll(minfo, pi, vco, 0xFF0000 | p);
125} 134}
126 135
127static inline unsigned int g450_setpll(CPMINFO unsigned int mnp, unsigned int pll) { 136static inline unsigned int g450_setpll(const struct matrox_fb_info *minfo,
137 unsigned int mnp, unsigned int pll)
138{
128 switch (pll) { 139 switch (pll) {
129 case M_PIXEL_PLL_A: 140 case M_PIXEL_PLL_A:
130 matroxfb_DAC_out(PMINFO M1064_XPIXPLLAM, mnp >> 16); 141 matroxfb_DAC_out(minfo, M1064_XPIXPLLAM, mnp >> 16);
131 matroxfb_DAC_out(PMINFO M1064_XPIXPLLAN, mnp >> 8); 142 matroxfb_DAC_out(minfo, M1064_XPIXPLLAN, mnp >> 8);
132 matroxfb_DAC_out(PMINFO M1064_XPIXPLLAP, mnp); 143 matroxfb_DAC_out(minfo, M1064_XPIXPLLAP, mnp);
133 return M1064_XPIXPLLSTAT; 144 return M1064_XPIXPLLSTAT;
134 145
135 case M_PIXEL_PLL_B: 146 case M_PIXEL_PLL_B:
136 matroxfb_DAC_out(PMINFO M1064_XPIXPLLBM, mnp >> 16); 147 matroxfb_DAC_out(minfo, M1064_XPIXPLLBM, mnp >> 16);
137 matroxfb_DAC_out(PMINFO M1064_XPIXPLLBN, mnp >> 8); 148 matroxfb_DAC_out(minfo, M1064_XPIXPLLBN, mnp >> 8);
138 matroxfb_DAC_out(PMINFO M1064_XPIXPLLBP, mnp); 149 matroxfb_DAC_out(minfo, M1064_XPIXPLLBP, mnp);
139 return M1064_XPIXPLLSTAT; 150 return M1064_XPIXPLLSTAT;
140 151
141 case M_PIXEL_PLL_C: 152 case M_PIXEL_PLL_C:
142 matroxfb_DAC_out(PMINFO M1064_XPIXPLLCM, mnp >> 16); 153 matroxfb_DAC_out(minfo, M1064_XPIXPLLCM, mnp >> 16);
143 matroxfb_DAC_out(PMINFO M1064_XPIXPLLCN, mnp >> 8); 154 matroxfb_DAC_out(minfo, M1064_XPIXPLLCN, mnp >> 8);
144 matroxfb_DAC_out(PMINFO M1064_XPIXPLLCP, mnp); 155 matroxfb_DAC_out(minfo, M1064_XPIXPLLCP, mnp);
145 return M1064_XPIXPLLSTAT; 156 return M1064_XPIXPLLSTAT;
146 157
147 case M_SYSTEM_PLL: 158 case M_SYSTEM_PLL:
148 matroxfb_DAC_out(PMINFO DAC1064_XSYSPLLM, mnp >> 16); 159 matroxfb_DAC_out(minfo, DAC1064_XSYSPLLM, mnp >> 16);
149 matroxfb_DAC_out(PMINFO DAC1064_XSYSPLLN, mnp >> 8); 160 matroxfb_DAC_out(minfo, DAC1064_XSYSPLLN, mnp >> 8);
150 matroxfb_DAC_out(PMINFO DAC1064_XSYSPLLP, mnp); 161 matroxfb_DAC_out(minfo, DAC1064_XSYSPLLP, mnp);
151 return DAC1064_XSYSPLLSTAT; 162 return DAC1064_XSYSPLLSTAT;
152 163
153 case M_VIDEO_PLL: 164 case M_VIDEO_PLL:
154 matroxfb_DAC_out(PMINFO M1064_XVIDPLLM, mnp >> 16); 165 matroxfb_DAC_out(minfo, M1064_XVIDPLLM, mnp >> 16);
155 matroxfb_DAC_out(PMINFO M1064_XVIDPLLN, mnp >> 8); 166 matroxfb_DAC_out(minfo, M1064_XVIDPLLN, mnp >> 8);
156 matroxfb_DAC_out(PMINFO M1064_XVIDPLLP, mnp); 167 matroxfb_DAC_out(minfo, M1064_XVIDPLLP, mnp);
157 return M1064_XVIDPLLSTAT; 168 return M1064_XVIDPLLSTAT;
158 } 169 }
159 return 0; 170 return 0;
160} 171}
161 172
162static inline unsigned int g450_cmppll(CPMINFO unsigned int mnp, unsigned int pll) { 173static inline unsigned int g450_cmppll(const struct matrox_fb_info *minfo,
174 unsigned int mnp, unsigned int pll)
175{
163 unsigned char m = mnp >> 16; 176 unsigned char m = mnp >> 16;
164 unsigned char n = mnp >> 8; 177 unsigned char n = mnp >> 8;
165 unsigned char p = mnp; 178 unsigned char p = mnp;
166 179
167 switch (pll) { 180 switch (pll) {
168 case M_PIXEL_PLL_A: 181 case M_PIXEL_PLL_A:
169 return (matroxfb_DAC_in(PMINFO M1064_XPIXPLLAM) != m || 182 return (matroxfb_DAC_in(minfo, M1064_XPIXPLLAM) != m ||
170 matroxfb_DAC_in(PMINFO M1064_XPIXPLLAN) != n || 183 matroxfb_DAC_in(minfo, M1064_XPIXPLLAN) != n ||
171 matroxfb_DAC_in(PMINFO M1064_XPIXPLLAP) != p); 184 matroxfb_DAC_in(minfo, M1064_XPIXPLLAP) != p);
172 185
173 case M_PIXEL_PLL_B: 186 case M_PIXEL_PLL_B:
174 return (matroxfb_DAC_in(PMINFO M1064_XPIXPLLBM) != m || 187 return (matroxfb_DAC_in(minfo, M1064_XPIXPLLBM) != m ||
175 matroxfb_DAC_in(PMINFO M1064_XPIXPLLBN) != n || 188 matroxfb_DAC_in(minfo, M1064_XPIXPLLBN) != n ||
176 matroxfb_DAC_in(PMINFO M1064_XPIXPLLBP) != p); 189 matroxfb_DAC_in(minfo, M1064_XPIXPLLBP) != p);
177 190
178 case M_PIXEL_PLL_C: 191 case M_PIXEL_PLL_C:
179 return (matroxfb_DAC_in(PMINFO M1064_XPIXPLLCM) != m || 192 return (matroxfb_DAC_in(minfo, M1064_XPIXPLLCM) != m ||
180 matroxfb_DAC_in(PMINFO M1064_XPIXPLLCN) != n || 193 matroxfb_DAC_in(minfo, M1064_XPIXPLLCN) != n ||
181 matroxfb_DAC_in(PMINFO M1064_XPIXPLLCP) != p); 194 matroxfb_DAC_in(minfo, M1064_XPIXPLLCP) != p);
182 195
183 case M_SYSTEM_PLL: 196 case M_SYSTEM_PLL:
184 return (matroxfb_DAC_in(PMINFO DAC1064_XSYSPLLM) != m || 197 return (matroxfb_DAC_in(minfo, DAC1064_XSYSPLLM) != m ||
185 matroxfb_DAC_in(PMINFO DAC1064_XSYSPLLN) != n || 198 matroxfb_DAC_in(minfo, DAC1064_XSYSPLLN) != n ||
186 matroxfb_DAC_in(PMINFO DAC1064_XSYSPLLP) != p); 199 matroxfb_DAC_in(minfo, DAC1064_XSYSPLLP) != p);
187 200
188 case M_VIDEO_PLL: 201 case M_VIDEO_PLL:
189 return (matroxfb_DAC_in(PMINFO M1064_XVIDPLLM) != m || 202 return (matroxfb_DAC_in(minfo, M1064_XVIDPLLM) != m ||
190 matroxfb_DAC_in(PMINFO M1064_XVIDPLLN) != n || 203 matroxfb_DAC_in(minfo, M1064_XVIDPLLN) != n ||
191 matroxfb_DAC_in(PMINFO M1064_XVIDPLLP) != p); 204 matroxfb_DAC_in(minfo, M1064_XVIDPLLP) != p);
192 } 205 }
193 return 1; 206 return 1;
194} 207}
195 208
196static inline int g450_isplllocked(CPMINFO unsigned int regidx) { 209static inline int g450_isplllocked(const struct matrox_fb_info *minfo,
210 unsigned int regidx)
211{
197 unsigned int j; 212 unsigned int j;
198 213
199 for (j = 0; j < 1000; j++) { 214 for (j = 0; j < 1000; j++) {
200 if (matroxfb_DAC_in(PMINFO regidx) & 0x40) { 215 if (matroxfb_DAC_in(minfo, regidx) & 0x40) {
201 unsigned int r = 0; 216 unsigned int r = 0;
202 int i; 217 int i;
203 218
204 for (i = 0; i < 100; i++) { 219 for (i = 0; i < 100; i++) {
205 r += matroxfb_DAC_in(PMINFO regidx) & 0x40; 220 r += matroxfb_DAC_in(minfo, regidx) & 0x40;
206 } 221 }
207 return r >= (90 * 0x40); 222 return r >= (90 * 0x40);
208 } 223 }
@@ -211,8 +226,10 @@ static inline int g450_isplllocked(CPMINFO unsigned int regidx) {
211 return 0; 226 return 0;
212} 227}
213 228
214static int g450_testpll(CPMINFO unsigned int mnp, unsigned int pll) { 229static int g450_testpll(const struct matrox_fb_info *minfo, unsigned int mnp,
215 return g450_isplllocked(PMINFO g450_setpll(PMINFO mnp, pll)); 230 unsigned int pll)
231{
232 return g450_isplllocked(minfo, g450_setpll(minfo, mnp, pll));
216} 233}
217 234
218static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsigned int pll) { 235static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsigned int pll) {
@@ -225,13 +242,19 @@ static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsi
225 } 242 }
226} 243}
227 244
228void matroxfb_g450_setpll_cond(WPMINFO unsigned int mnp, unsigned int pll) { 245void matroxfb_g450_setpll_cond(struct matrox_fb_info *minfo, unsigned int mnp,
229 if (g450_cmppll(PMINFO mnp, pll)) { 246 unsigned int pll)
230 g450_setpll(PMINFO mnp, pll); 247{
248 if (g450_cmppll(minfo, mnp, pll)) {
249 g450_setpll(minfo, mnp, pll);
231 } 250 }
232} 251}
233 252
234static inline unsigned int g450_findworkingpll(WPMINFO unsigned int pll, unsigned int* mnparray, unsigned int mnpcount) { 253static inline unsigned int g450_findworkingpll(struct matrox_fb_info *minfo,
254 unsigned int pll,
255 unsigned int *mnparray,
256 unsigned int mnpcount)
257{
235 unsigned int found = 0; 258 unsigned int found = 0;
236 unsigned int idx; 259 unsigned int idx;
237 unsigned int mnpfound = mnparray[0]; 260 unsigned int mnpfound = mnparray[0];
@@ -255,22 +278,22 @@ static inline unsigned int g450_findworkingpll(WPMINFO unsigned int pll, unsigne
255 while (sptr >= sarray) { 278 while (sptr >= sarray) {
256 unsigned int mnp = *sptr--; 279 unsigned int mnp = *sptr--;
257 280
258 if (g450_testpll(PMINFO mnp - 0x0300, pll) && 281 if (g450_testpll(minfo, mnp - 0x0300, pll) &&
259 g450_testpll(PMINFO mnp + 0x0300, pll) && 282 g450_testpll(minfo, mnp + 0x0300, pll) &&
260 g450_testpll(PMINFO mnp - 0x0200, pll) && 283 g450_testpll(minfo, mnp - 0x0200, pll) &&
261 g450_testpll(PMINFO mnp + 0x0200, pll) && 284 g450_testpll(minfo, mnp + 0x0200, pll) &&
262 g450_testpll(PMINFO mnp - 0x0100, pll) && 285 g450_testpll(minfo, mnp - 0x0100, pll) &&
263 g450_testpll(PMINFO mnp + 0x0100, pll)) { 286 g450_testpll(minfo, mnp + 0x0100, pll)) {
264 if (g450_testpll(PMINFO mnp, pll)) { 287 if (g450_testpll(minfo, mnp, pll)) {
265 return mnp; 288 return mnp;
266 } 289 }
267 } else if (!found && g450_testpll(PMINFO mnp, pll)) { 290 } else if (!found && g450_testpll(minfo, mnp, pll)) {
268 mnpfound = mnp; 291 mnpfound = mnp;
269 found = 1; 292 found = 1;
270 } 293 }
271 } 294 }
272 } 295 }
273 g450_setpll(PMINFO mnpfound, pll); 296 g450_setpll(minfo, mnpfound, pll);
274 return mnpfound; 297 return mnpfound;
275} 298}
276 299
@@ -283,7 +306,9 @@ static void g450_addcache(struct matrox_pll_cache* ci, unsigned int mnp_key, uns
283 ci->data[0].mnp_value = mnp_value; 306 ci->data[0].mnp_value = mnp_value;
284} 307}
285 308
286static int g450_checkcache(WPMINFO struct matrox_pll_cache* ci, unsigned int mnp_key) { 309static int g450_checkcache(struct matrox_fb_info *minfo,
310 struct matrox_pll_cache *ci, unsigned int mnp_key)
311{
287 unsigned int i; 312 unsigned int i;
288 313
289 mnp_key &= G450_MNP_FREQBITS; 314 mnp_key &= G450_MNP_FREQBITS;
@@ -303,8 +328,10 @@ static int g450_checkcache(WPMINFO struct matrox_pll_cache* ci, unsigned int mnp
303 return NO_MORE_MNP; 328 return NO_MORE_MNP;
304} 329}
305 330
306static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, 331static int __g450_setclk(struct matrox_fb_info *minfo, unsigned int fout,
307 unsigned int* mnparray, unsigned int* deltaarray) { 332 unsigned int pll, unsigned int *mnparray,
333 unsigned int *deltaarray)
334{
308 unsigned int mnpcount; 335 unsigned int mnpcount;
309 unsigned int pixel_vco; 336 unsigned int pixel_vco;
310 const struct matrox_pll_limits* pi; 337 const struct matrox_pll_limits* pi;
@@ -321,19 +348,19 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
321 348
322 matroxfb_DAC_lock_irqsave(flags); 349 matroxfb_DAC_lock_irqsave(flags);
323 350
324 xpwrctrl = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL); 351 xpwrctrl = matroxfb_DAC_in(minfo, M1064_XPWRCTRL);
325 matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN); 352 matroxfb_DAC_out(minfo, M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN);
326 mga_outb(M_SEQ_INDEX, M_SEQ1); 353 mga_outb(M_SEQ_INDEX, M_SEQ1);
327 mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF); 354 mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF);
328 tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL); 355 tmp = matroxfb_DAC_in(minfo, M1064_XPIXCLKCTRL);
329 tmp |= M1064_XPIXCLKCTRL_DIS; 356 tmp |= M1064_XPIXCLKCTRL_DIS;
330 if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) { 357 if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) {
331 tmp |= M1064_XPIXCLKCTRL_PLL_UP; 358 tmp |= M1064_XPIXCLKCTRL_PLL_UP;
332 } 359 }
333 matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp); 360 matroxfb_DAC_out(minfo, M1064_XPIXCLKCTRL, tmp);
334 /* DVI PLL preferred for frequencies up to 361 /* DVI PLL preferred for frequencies up to
335 panel link max, standard PLL otherwise */ 362 panel link max, standard PLL otherwise */
336 if (fout >= MINFO->max_pixel_clock_panellink) 363 if (fout >= minfo->max_pixel_clock_panellink)
337 tmp = 0; 364 tmp = 0;
338 else tmp = 365 else tmp =
339 M1064_XDVICLKCTRL_DVIDATAPATHSEL | 366 M1064_XDVICLKCTRL_DVIDATAPATHSEL |
@@ -341,8 +368,8 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
341 M1064_XDVICLKCTRL_C1DVICLKEN | 368 M1064_XDVICLKCTRL_C1DVICLKEN |
342 M1064_XDVICLKCTRL_DVILOOPCTL | 369 M1064_XDVICLKCTRL_DVILOOPCTL |
343 M1064_XDVICLKCTRL_P1LOOPBWDTCTL; 370 M1064_XDVICLKCTRL_P1LOOPBWDTCTL;
344 matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL,tmp); 371 matroxfb_DAC_out(minfo, M1064_XDVICLKCTRL, tmp);
345 matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, 372 matroxfb_DAC_out(minfo, M1064_XPWRCTRL,
346 xpwrctrl); 373 xpwrctrl);
347 374
348 matroxfb_DAC_unlock_irqrestore(flags); 375 matroxfb_DAC_unlock_irqrestore(flags);
@@ -363,20 +390,20 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
363 } 390 }
364 mga_outb(M_MISC_REG, misc); 391 mga_outb(M_MISC_REG, misc);
365 } 392 }
366 pi = &ACCESS_FBINFO(limits.pixel); 393 pi = &minfo->limits.pixel;
367 ci = &ACCESS_FBINFO(cache.pixel); 394 ci = &minfo->cache.pixel;
368 break; 395 break;
369 case M_SYSTEM_PLL: 396 case M_SYSTEM_PLL:
370 { 397 {
371 u_int32_t opt; 398 u_int32_t opt;
372 399
373 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, &opt); 400 pci_read_config_dword(minfo->pcidev, PCI_OPTION_REG, &opt);
374 if (!(opt & 0x20)) { 401 if (!(opt & 0x20)) {
375 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, opt | 0x20); 402 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, opt | 0x20);
376 } 403 }
377 } 404 }
378 pi = &ACCESS_FBINFO(limits.system); 405 pi = &minfo->limits.system;
379 ci = &ACCESS_FBINFO(cache.system); 406 ci = &minfo->cache.system;
380 break; 407 break;
381 case M_VIDEO_PLL: 408 case M_VIDEO_PLL:
382 { 409 {
@@ -385,18 +412,18 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
385 unsigned long flags; 412 unsigned long flags;
386 413
387 matroxfb_DAC_lock_irqsave(flags); 414 matroxfb_DAC_lock_irqsave(flags);
388 tmp = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL); 415 tmp = matroxfb_DAC_in(minfo, M1064_XPWRCTRL);
389 if (!(tmp & 2)) { 416 if (!(tmp & 2)) {
390 matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, tmp | 2); 417 matroxfb_DAC_out(minfo, M1064_XPWRCTRL, tmp | 2);
391 } 418 }
392 419
393 mnp = matroxfb_DAC_in(PMINFO M1064_XPIXPLLCM) << 16; 420 mnp = matroxfb_DAC_in(minfo, M1064_XPIXPLLCM) << 16;
394 mnp |= matroxfb_DAC_in(PMINFO M1064_XPIXPLLCN) << 8; 421 mnp |= matroxfb_DAC_in(minfo, M1064_XPIXPLLCN) << 8;
395 pixel_vco = g450_mnp2vco(PMINFO mnp); 422 pixel_vco = g450_mnp2vco(minfo, mnp);
396 matroxfb_DAC_unlock_irqrestore(flags); 423 matroxfb_DAC_unlock_irqrestore(flags);
397 } 424 }
398 pi = &ACCESS_FBINFO(limits.video); 425 pi = &minfo->limits.video;
399 ci = &ACCESS_FBINFO(cache.video); 426 ci = &minfo->cache.video;
400 break; 427 break;
401 default: 428 default:
402 return -EINVAL; 429 return -EINVAL;
@@ -407,12 +434,12 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
407 unsigned int mnp; 434 unsigned int mnp;
408 unsigned int xvco; 435 unsigned int xvco;
409 436
410 for(mnp = g450_firstpll(PMINFO pi, &xvco, fout); mnp != NO_MORE_MNP; mnp = g450_nextpll(PMINFO pi, &xvco, mnp)) { 437 for (mnp = g450_firstpll(minfo, pi, &xvco, fout); mnp != NO_MORE_MNP; mnp = g450_nextpll(minfo, pi, &xvco, mnp)) {
411 unsigned int idx; 438 unsigned int idx;
412 unsigned int vco; 439 unsigned int vco;
413 unsigned int delta; 440 unsigned int delta;
414 441
415 vco = g450_mnp2vco(PMINFO mnp); 442 vco = g450_mnp2vco(minfo, mnp);
416#if 0 443#if 0
417 if (pll == M_VIDEO_PLL) { 444 if (pll == M_VIDEO_PLL) {
418 unsigned int big, small; 445 unsigned int big, small;
@@ -444,7 +471,7 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
444 * (freqs near VCOmin aren't as stable) 471 * (freqs near VCOmin aren't as stable)
445 */ 472 */
446 if (delta == deltaarray[idx-1] 473 if (delta == deltaarray[idx-1]
447 && vco != g450_mnp2vco(PMINFO mnparray[idx-1]) 474 && vco != g450_mnp2vco(minfo, mnparray[idx-1])
448 && vco < (pi->vcomin * 17 / 16)) { 475 && vco < (pi->vcomin * 17 / 16)) {
449 break; 476 break;
450 } 477 }
@@ -468,14 +495,14 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
468 unsigned int mnp; 495 unsigned int mnp;
469 496
470 matroxfb_DAC_lock_irqsave(flags); 497 matroxfb_DAC_lock_irqsave(flags);
471 mnp = g450_checkcache(PMINFO ci, mnparray[0]); 498 mnp = g450_checkcache(minfo, ci, mnparray[0]);
472 if (mnp != NO_MORE_MNP) { 499 if (mnp != NO_MORE_MNP) {
473 matroxfb_g450_setpll_cond(PMINFO mnp, pll); 500 matroxfb_g450_setpll_cond(minfo, mnp, pll);
474 } else { 501 } else {
475 mnp = g450_findworkingpll(PMINFO pll, mnparray, mnpcount); 502 mnp = g450_findworkingpll(minfo, pll, mnparray, mnpcount);
476 g450_addcache(ci, mnparray[0], mnp); 503 g450_addcache(ci, mnparray[0], mnp);
477 } 504 }
478 updatehwstate_clk(&ACCESS_FBINFO(hw), mnp, pll); 505 updatehwstate_clk(&minfo->hw, mnp, pll);
479 matroxfb_DAC_unlock_irqrestore(flags); 506 matroxfb_DAC_unlock_irqrestore(flags);
480 return mnp; 507 return mnp;
481 } 508 }
@@ -485,14 +512,16 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
485 * Currently there is 5(p) * 10(m) = 50 possible values. */ 512 * Currently there is 5(p) * 10(m) = 50 possible values. */
486#define MNP_TABLE_SIZE 64 513#define MNP_TABLE_SIZE 64
487 514
488int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll) { 515int matroxfb_g450_setclk(struct matrox_fb_info *minfo, unsigned int fout,
516 unsigned int pll)
517{
489 unsigned int* arr; 518 unsigned int* arr;
490 519
491 arr = kmalloc(sizeof(*arr) * MNP_TABLE_SIZE * 2, GFP_KERNEL); 520 arr = kmalloc(sizeof(*arr) * MNP_TABLE_SIZE * 2, GFP_KERNEL);
492 if (arr) { 521 if (arr) {
493 int r; 522 int r;
494 523
495 r = __g450_setclk(PMINFO fout, pll, arr, arr + MNP_TABLE_SIZE); 524 r = __g450_setclk(minfo, fout, pll, arr, arr + MNP_TABLE_SIZE);
496 kfree(arr); 525 kfree(arr);
497 return r; 526 return r;
498 } 527 }
diff --git a/drivers/video/matrox/g450_pll.h b/drivers/video/matrox/g450_pll.h
index c17ed74501e9..aac615d18440 100644
--- a/drivers/video/matrox/g450_pll.h
+++ b/drivers/video/matrox/g450_pll.h
@@ -3,8 +3,10 @@
3 3
4#include "matroxfb_base.h" 4#include "matroxfb_base.h"
5 5
6int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll); 6int matroxfb_g450_setclk(struct matrox_fb_info *minfo, unsigned int fout,
7unsigned int g450_mnp2f(CPMINFO unsigned int mnp); 7 unsigned int pll);
8void matroxfb_g450_setpll_cond(WPMINFO unsigned int mnp, unsigned int pll); 8unsigned int g450_mnp2f(const struct matrox_fb_info *minfo, unsigned int mnp);
9void matroxfb_g450_setpll_cond(struct matrox_fb_info *minfo, unsigned int mnp,
10 unsigned int pll);
9 11
10#endif /* __G450_PLL_H__ */ 12#endif /* __G450_PLL_H__ */
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index c14e3e2212b3..f3728ab262f8 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -41,7 +41,7 @@ static int matroxfb_read_gpio(struct matrox_fb_info* minfo) {
41 int v; 41 int v;
42 42
43 matroxfb_DAC_lock_irqsave(flags); 43 matroxfb_DAC_lock_irqsave(flags);
44 v = matroxfb_DAC_in(PMINFO DAC_XGENIODATA); 44 v = matroxfb_DAC_in(minfo, DAC_XGENIODATA);
45 matroxfb_DAC_unlock_irqrestore(flags); 45 matroxfb_DAC_unlock_irqrestore(flags);
46 return v; 46 return v;
47} 47}
@@ -51,10 +51,10 @@ static void matroxfb_set_gpio(struct matrox_fb_info* minfo, int mask, int val) {
51 int v; 51 int v;
52 52
53 matroxfb_DAC_lock_irqsave(flags); 53 matroxfb_DAC_lock_irqsave(flags);
54 v = (matroxfb_DAC_in(PMINFO DAC_XGENIOCTRL) & mask) | val; 54 v = (matroxfb_DAC_in(minfo, DAC_XGENIOCTRL) & mask) | val;
55 matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, v); 55 matroxfb_DAC_out(minfo, DAC_XGENIOCTRL, v);
56 /* We must reset GENIODATA very often... XFree plays with this register */ 56 /* We must reset GENIODATA very often... XFree plays with this register */
57 matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0x00); 57 matroxfb_DAC_out(minfo, DAC_XGENIODATA, 0x00);
58 matroxfb_DAC_unlock_irqrestore(flags); 58 matroxfb_DAC_unlock_irqrestore(flags);
59} 59}
60 60
@@ -112,7 +112,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
112 i2c_set_adapdata(&b->adapter, b); 112 i2c_set_adapdata(&b->adapter, b);
113 b->adapter.class = class; 113 b->adapter.class = class;
114 b->adapter.algo_data = &b->bac; 114 b->adapter.algo_data = &b->bac;
115 b->adapter.dev.parent = &ACCESS_FBINFO(pcidev)->dev; 115 b->adapter.dev.parent = &minfo->pcidev->dev;
116 b->bac = matrox_i2c_algo_template; 116 b->bac = matrox_i2c_algo_template;
117 b->bac.data = b; 117 b->bac.data = b;
118 err = i2c_bit_add_bus(&b->adapter); 118 err = i2c_bit_add_bus(&b->adapter);
@@ -149,11 +149,11 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
149 return NULL; 149 return NULL;
150 150
151 matroxfb_DAC_lock_irqsave(flags); 151 matroxfb_DAC_lock_irqsave(flags);
152 matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0xFF); 152 matroxfb_DAC_out(minfo, DAC_XGENIODATA, 0xFF);
153 matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, 0x00); 153 matroxfb_DAC_out(minfo, DAC_XGENIOCTRL, 0x00);
154 matroxfb_DAC_unlock_irqrestore(flags); 154 matroxfb_DAC_unlock_irqrestore(flags);
155 155
156 switch (ACCESS_FBINFO(chip)) { 156 switch (minfo->chip) {
157 case MGA_2064: 157 case MGA_2064:
158 case MGA_2164: 158 case MGA_2164:
159 err = i2c_bus_reg(&m2info->ddc1, minfo, 159 err = i2c_bus_reg(&m2info->ddc1, minfo,
@@ -168,7 +168,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
168 } 168 }
169 if (err) 169 if (err)
170 goto fail_ddc1; 170 goto fail_ddc1;
171 if (ACCESS_FBINFO(devflags.dualhead)) { 171 if (minfo->devflags.dualhead) {
172 err = i2c_bus_reg(&m2info->ddc2, minfo, 172 err = i2c_bus_reg(&m2info->ddc2, minfo,
173 DDC2_DATA, DDC2_CLK, 173 DDC2_DATA, DDC2_CLK,
174 "DDC:fb%u #1", I2C_CLASS_DDC); 174 "DDC:fb%u #1", I2C_CLASS_DDC);
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c
index a74e5da17aa0..f9fa0fd00292 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.c
+++ b/drivers/video/matrox/matroxfb_DAC1064.c
@@ -33,7 +33,11 @@
33#define DAC1064_OPT_MDIV2 0x00 33#define DAC1064_OPT_MDIV2 0x00
34#define DAC1064_OPT_RESERVED 0x10 34#define DAC1064_OPT_RESERVED 0x10
35 35
36static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) { 36static void DAC1064_calcclock(const struct matrox_fb_info *minfo,
37 unsigned int freq, unsigned int fmax,
38 unsigned int *in, unsigned int *feed,
39 unsigned int *post)
40{
37 unsigned int fvco; 41 unsigned int fvco;
38 unsigned int p; 42 unsigned int p;
39 43
@@ -41,7 +45,7 @@ static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsi
41 45
42 /* only for devices older than G450 */ 46 /* only for devices older than G450 */
43 47
44 fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p); 48 fvco = PLL_calcclock(minfo, freq, fmax, in, feed, &p);
45 49
46 p = (1 << p) - 1; 50 p = (1 << p) - 1;
47 if (fvco <= 100000) 51 if (fvco <= 100000)
@@ -80,32 +84,35 @@ static const unsigned char MGA1064_DAC[] = {
80 0x00, 84 0x00,
81 0x00, 0x00, 0xFF, 0xFF}; 85 0x00, 0x00, 0xFF, 0xFF};
82 86
83static void DAC1064_setpclk(WPMINFO unsigned long fout) { 87static void DAC1064_setpclk(struct matrox_fb_info *minfo, unsigned long fout)
88{
84 unsigned int m, n, p; 89 unsigned int m, n, p;
85 90
86 DBG(__func__) 91 DBG(__func__)
87 92
88 DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p); 93 DAC1064_calcclock(minfo, fout, minfo->max_pixel_clock, &m, &n, &p);
89 ACCESS_FBINFO(hw).DACclk[0] = m; 94 minfo->hw.DACclk[0] = m;
90 ACCESS_FBINFO(hw).DACclk[1] = n; 95 minfo->hw.DACclk[1] = n;
91 ACCESS_FBINFO(hw).DACclk[2] = p; 96 minfo->hw.DACclk[2] = p;
92} 97}
93 98
94static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) { 99static void DAC1064_setmclk(struct matrox_fb_info *minfo, int oscinfo,
100 unsigned long fmem)
101{
95 u_int32_t mx; 102 u_int32_t mx;
96 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 103 struct matrox_hw_state *hw = &minfo->hw;
97 104
98 DBG(__func__) 105 DBG(__func__)
99 106
100 if (ACCESS_FBINFO(devflags.noinit)) { 107 if (minfo->devflags.noinit) {
101 /* read MCLK and give up... */ 108 /* read MCLK and give up... */
102 hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM); 109 hw->DACclk[3] = inDAC1064(minfo, DAC1064_XSYSPLLM);
103 hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN); 110 hw->DACclk[4] = inDAC1064(minfo, DAC1064_XSYSPLLN);
104 hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP); 111 hw->DACclk[5] = inDAC1064(minfo, DAC1064_XSYSPLLP);
105 return; 112 return;
106 } 113 }
107 mx = hw->MXoptionReg | 0x00000004; 114 mx = hw->MXoptionReg | 0x00000004;
108 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); 115 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
109 mx &= ~0x000000BB; 116 mx &= ~0x000000BB;
110 if (oscinfo & DAC1064_OPT_GDIV1) 117 if (oscinfo & DAC1064_OPT_GDIV1)
111 mx |= 0x00000008; 118 mx |= 0x00000008;
@@ -120,9 +127,9 @@ static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) {
120 127
121 /* powerup system PLL, select PCI clock */ 128 /* powerup system PLL, select PCI clock */
122 mx |= 0x00000020; 129 mx |= 0x00000020;
123 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); 130 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
124 mx &= ~0x00000004; 131 mx &= ~0x00000004;
125 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); 132 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
126 133
127 /* !!! you must not access device if MCLK is not running !!! 134 /* !!! you must not access device if MCLK is not running !!!
128 Doing so cause immediate PCI lockup :-( Maybe they should 135 Doing so cause immediate PCI lockup :-( Maybe they should
@@ -131,12 +138,12 @@ static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) {
131 perfect... */ 138 perfect... */
132 /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not 139 /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
133 select PLL... because of PLL can be stopped at this time) */ 140 select PLL... because of PLL can be stopped at this time) */
134 DAC1064_calcclock(PMINFO fmem, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p); 141 DAC1064_calcclock(minfo, fmem, minfo->max_pixel_clock, &m, &n, &p);
135 outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3] = m); 142 outDAC1064(minfo, DAC1064_XSYSPLLM, hw->DACclk[3] = m);
136 outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4] = n); 143 outDAC1064(minfo, DAC1064_XSYSPLLN, hw->DACclk[4] = n);
137 outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5] = p); 144 outDAC1064(minfo, DAC1064_XSYSPLLP, hw->DACclk[5] = p);
138 for (clk = 65536; clk; --clk) { 145 for (clk = 65536; clk; --clk) {
139 if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT) & 0x40) 146 if (inDAC1064(minfo, DAC1064_XSYSPLLSTAT) & 0x40)
140 break; 147 break;
141 } 148 }
142 if (!clk) 149 if (!clk)
@@ -147,29 +154,30 @@ static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) {
147 /* select specified system clock source */ 154 /* select specified system clock source */
148 mx |= oscinfo & DAC1064_OPT_SCLK_MASK; 155 mx |= oscinfo & DAC1064_OPT_SCLK_MASK;
149 } 156 }
150 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); 157 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
151 mx &= ~0x00000004; 158 mx &= ~0x00000004;
152 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx); 159 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
153 hw->MXoptionReg = mx; 160 hw->MXoptionReg = mx;
154} 161}
155 162
156#ifdef CONFIG_FB_MATROX_G 163#ifdef CONFIG_FB_MATROX_G
157static void g450_set_plls(WPMINFO2) { 164static void g450_set_plls(struct matrox_fb_info *minfo)
165{
158 u_int32_t c2_ctl; 166 u_int32_t c2_ctl;
159 unsigned int pxc; 167 unsigned int pxc;
160 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 168 struct matrox_hw_state *hw = &minfo->hw;
161 int pixelmnp; 169 int pixelmnp;
162 int videomnp; 170 int videomnp;
163 171
164 c2_ctl = hw->crtc2.ctl & ~0x4007; /* Clear PLL + enable for CRTC2 */ 172 c2_ctl = hw->crtc2.ctl & ~0x4007; /* Clear PLL + enable for CRTC2 */
165 c2_ctl |= 0x0001; /* Enable CRTC2 */ 173 c2_ctl |= 0x0001; /* Enable CRTC2 */
166 hw->DACreg[POS1064_XPWRCTRL] &= ~0x02; /* Stop VIDEO PLL */ 174 hw->DACreg[POS1064_XPWRCTRL] &= ~0x02; /* Stop VIDEO PLL */
167 pixelmnp = ACCESS_FBINFO(crtc1).mnp; 175 pixelmnp = minfo->crtc1.mnp;
168 videomnp = ACCESS_FBINFO(crtc2).mnp; 176 videomnp = minfo->crtc2.mnp;
169 if (videomnp < 0) { 177 if (videomnp < 0) {
170 c2_ctl &= ~0x0001; /* Disable CRTC2 */ 178 c2_ctl &= ~0x0001; /* Disable CRTC2 */
171 hw->DACreg[POS1064_XPWRCTRL] &= ~0x10; /* Powerdown CRTC2 */ 179 hw->DACreg[POS1064_XPWRCTRL] &= ~0x10; /* Powerdown CRTC2 */
172 } else if (ACCESS_FBINFO(crtc2).pixclock == ACCESS_FBINFO(features).pll.ref_freq) { 180 } else if (minfo->crtc2.pixclock == minfo->features.pll.ref_freq) {
173 c2_ctl |= 0x4002; /* Use reference directly */ 181 c2_ctl |= 0x4002; /* Use reference directly */
174 } else if (videomnp == pixelmnp) { 182 } else if (videomnp == pixelmnp) {
175 c2_ctl |= 0x0004; /* Use pixel PLL */ 183 c2_ctl |= 0x0004; /* Use pixel PLL */
@@ -184,27 +192,27 @@ static void g450_set_plls(WPMINFO2) {
184 c2_ctl |= 0x0006; /* Use video PLL */ 192 c2_ctl |= 0x0006; /* Use video PLL */
185 hw->DACreg[POS1064_XPWRCTRL] |= 0x02; 193 hw->DACreg[POS1064_XPWRCTRL] |= 0x02;
186 194
187 outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]); 195 outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
188 matroxfb_g450_setpll_cond(PMINFO videomnp, M_VIDEO_PLL); 196 matroxfb_g450_setpll_cond(minfo, videomnp, M_VIDEO_PLL);
189 } 197 }
190 198
191 hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP; 199 hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP;
192 if (pixelmnp >= 0) { 200 if (pixelmnp >= 0) {
193 hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP; 201 hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP;
194 202
195 outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]); 203 outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
196 matroxfb_g450_setpll_cond(PMINFO pixelmnp, M_PIXEL_PLL_C); 204 matroxfb_g450_setpll_cond(minfo, pixelmnp, M_PIXEL_PLL_C);
197 } 205 }
198 if (c2_ctl != hw->crtc2.ctl) { 206 if (c2_ctl != hw->crtc2.ctl) {
199 hw->crtc2.ctl = c2_ctl; 207 hw->crtc2.ctl = c2_ctl;
200 mga_outl(0x3C10, c2_ctl); 208 mga_outl(0x3C10, c2_ctl);
201 } 209 }
202 210
203 pxc = ACCESS_FBINFO(crtc1).pixclock; 211 pxc = minfo->crtc1.pixclock;
204 if (pxc == 0 || ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC2) { 212 if (pxc == 0 || minfo->outputs[2].src == MATROXFB_SRC_CRTC2) {
205 pxc = ACCESS_FBINFO(crtc2).pixclock; 213 pxc = minfo->crtc2.pixclock;
206 } 214 }
207 if (ACCESS_FBINFO(chip) == MGA_G550) { 215 if (minfo->chip == MGA_G550) {
208 if (pxc < 45000) { 216 if (pxc < 45000) {
209 hw->DACreg[POS1064_XPANMODE] = 0x00; /* 0-50 */ 217 hw->DACreg[POS1064_XPANMODE] = 0x00; /* 0-50 */
210 } else if (pxc < 55000) { 218 } else if (pxc < 55000) {
@@ -245,18 +253,19 @@ static void g450_set_plls(WPMINFO2) {
245} 253}
246#endif 254#endif
247 255
248void DAC1064_global_init(WPMINFO2) { 256void DAC1064_global_init(struct matrox_fb_info *minfo)
249 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 257{
258 struct matrox_hw_state *hw = &minfo->hw;
250 259
251 hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK; 260 hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
252 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN; 261 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
253 hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL; 262 hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
254#ifdef CONFIG_FB_MATROX_G 263#ifdef CONFIG_FB_MATROX_G
255 if (ACCESS_FBINFO(devflags.g450dac)) { 264 if (minfo->devflags.g450dac) {
256 hw->DACreg[POS1064_XPWRCTRL] = 0x1F; /* powerup everything */ 265 hw->DACreg[POS1064_XPWRCTRL] = 0x1F; /* powerup everything */
257 hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */ 266 hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */
258 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN; 267 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
259 switch (ACCESS_FBINFO(outputs[0]).src) { 268 switch (minfo->outputs[0].src) {
260 case MATROXFB_SRC_CRTC1: 269 case MATROXFB_SRC_CRTC1:
261 case MATROXFB_SRC_CRTC2: 270 case MATROXFB_SRC_CRTC2:
262 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01; /* enable output; CRTC1/2 selection is in CRTC2 ctl */ 271 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01; /* enable output; CRTC1/2 selection is in CRTC2 ctl */
@@ -265,12 +274,12 @@ void DAC1064_global_init(WPMINFO2) {
265 hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN; 274 hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN;
266 break; 275 break;
267 } 276 }
268 switch (ACCESS_FBINFO(outputs[1]).src) { 277 switch (minfo->outputs[1].src) {
269 case MATROXFB_SRC_CRTC1: 278 case MATROXFB_SRC_CRTC1:
270 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x04; 279 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x04;
271 break; 280 break;
272 case MATROXFB_SRC_CRTC2: 281 case MATROXFB_SRC_CRTC2:
273 if (ACCESS_FBINFO(outputs[1]).mode == MATROXFB_OUTPUT_MODE_MONITOR) { 282 if (minfo->outputs[1].mode == MATROXFB_OUTPUT_MODE_MONITOR) {
274 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x08; 283 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x08;
275 } else { 284 } else {
276 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x0C; 285 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x0C;
@@ -280,7 +289,7 @@ void DAC1064_global_init(WPMINFO2) {
280 hw->DACreg[POS1064_XPWRCTRL] &= ~0x01; /* Poweroff DAC2 */ 289 hw->DACreg[POS1064_XPWRCTRL] &= ~0x01; /* Poweroff DAC2 */
281 break; 290 break;
282 } 291 }
283 switch (ACCESS_FBINFO(outputs[2]).src) { 292 switch (minfo->outputs[2].src) {
284 case MATROXFB_SRC_CRTC1: 293 case MATROXFB_SRC_CRTC1:
285 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x20; 294 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x20;
286 break; 295 break;
@@ -299,55 +308,57 @@ void DAC1064_global_init(WPMINFO2) {
299 break; 308 break;
300 } 309 }
301 /* Now set timming related variables... */ 310 /* Now set timming related variables... */
302 g450_set_plls(PMINFO2); 311 g450_set_plls(minfo);
303 } else 312 } else
304#endif 313#endif
305 { 314 {
306 if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1) { 315 if (minfo->outputs[1].src == MATROXFB_SRC_CRTC1) {
307 hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT; 316 hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
308 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12; 317 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
309 } else if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) { 318 } else if (minfo->outputs[1].src == MATROXFB_SRC_CRTC2) {
310 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12; 319 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;
311 } else if (ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1) 320 } else if (minfo->outputs[2].src == MATROXFB_SRC_CRTC1)
312 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12; 321 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12;
313 else 322 else
314 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS; 323 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS;
315 324
316 if (ACCESS_FBINFO(outputs[0]).src != MATROXFB_SRC_NONE) 325 if (minfo->outputs[0].src != MATROXFB_SRC_NONE)
317 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN; 326 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
318 } 327 }
319} 328}
320 329
321void DAC1064_global_restore(WPMINFO2) { 330void DAC1064_global_restore(struct matrox_fb_info *minfo)
322 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 331{
323 332 struct matrox_hw_state *hw = &minfo->hw;
324 outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]); 333
325 outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]); 334 outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
326 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) { 335 outDAC1064(minfo, M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
327 outDAC1064(PMINFO 0x20, 0x04); 336 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) {
328 outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type)); 337 outDAC1064(minfo, 0x20, 0x04);
329 if (ACCESS_FBINFO(devflags.g450dac)) { 338 outDAC1064(minfo, 0x1F, minfo->devflags.dfp_type);
330 outDAC1064(PMINFO M1064_XSYNCCTRL, 0xCC); 339 if (minfo->devflags.g450dac) {
331 outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]); 340 outDAC1064(minfo, M1064_XSYNCCTRL, 0xCC);
332 outDAC1064(PMINFO M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]); 341 outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
333 outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]); 342 outDAC1064(minfo, M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]);
343 outDAC1064(minfo, M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);
334 } 344 }
335 } 345 }
336} 346}
337 347
338static int DAC1064_init_1(WPMINFO struct my_timming* m) { 348static int DAC1064_init_1(struct matrox_fb_info *minfo, struct my_timming *m)
339 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 349{
350 struct matrox_hw_state *hw = &minfo->hw;
340 351
341 DBG(__func__) 352 DBG(__func__)
342 353
343 memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs)); 354 memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
344 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { 355 switch (minfo->fbcon.var.bits_per_pixel) {
345 /* case 4: not supported by MGA1064 DAC */ 356 /* case 4: not supported by MGA1064 DAC */
346 case 8: 357 case 8:
347 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; 358 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
348 break; 359 break;
349 case 16: 360 case 16:
350 if (ACCESS_FBINFO(fbcon).var.green.length == 5) 361 if (minfo->fbcon.var.green.length == 5)
351 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; 362 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
352 else 363 else
353 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; 364 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
@@ -361,22 +372,23 @@ static int DAC1064_init_1(WPMINFO struct my_timming* m) {
361 default: 372 default:
362 return 1; /* unsupported depth */ 373 return 1; /* unsupported depth */
363 } 374 }
364 hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl); 375 hw->DACreg[POS1064_XVREFCTRL] = minfo->features.DAC1064.xvrefctrl;
365 hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK; 376 hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
366 hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN; 377 hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
367 hw->DACreg[POS1064_XCURADDL] = 0; 378 hw->DACreg[POS1064_XCURADDL] = 0;
368 hw->DACreg[POS1064_XCURADDH] = 0; 379 hw->DACreg[POS1064_XCURADDH] = 0;
369 380
370 DAC1064_global_init(PMINFO2); 381 DAC1064_global_init(minfo);
371 return 0; 382 return 0;
372} 383}
373 384
374static int DAC1064_init_2(WPMINFO struct my_timming* m) { 385static int DAC1064_init_2(struct matrox_fb_info *minfo, struct my_timming *m)
375 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 386{
387 struct matrox_hw_state *hw = &minfo->hw;
376 388
377 DBG(__func__) 389 DBG(__func__)
378 390
379 if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 16) { /* 256 entries */ 391 if (minfo->fbcon.var.bits_per_pixel > 16) { /* 256 entries */
380 int i; 392 int i;
381 393
382 for (i = 0; i < 256; i++) { 394 for (i = 0; i < 256; i++) {
@@ -384,8 +396,8 @@ static int DAC1064_init_2(WPMINFO struct my_timming* m) {
384 hw->DACpal[i * 3 + 1] = i; 396 hw->DACpal[i * 3 + 1] = i;
385 hw->DACpal[i * 3 + 2] = i; 397 hw->DACpal[i * 3 + 2] = i;
386 } 398 }
387 } else if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 8) { 399 } else if (minfo->fbcon.var.bits_per_pixel > 8) {
388 if (ACCESS_FBINFO(fbcon).var.green.length == 5) { /* 0..31, 128..159 */ 400 if (minfo->fbcon.var.green.length == 5) { /* 0..31, 128..159 */
389 int i; 401 int i;
390 402
391 for (i = 0; i < 32; i++) { 403 for (i = 0; i < 32; i++) {
@@ -413,8 +425,9 @@ static int DAC1064_init_2(WPMINFO struct my_timming* m) {
413 return 0; 425 return 0;
414} 426}
415 427
416static void DAC1064_restore_1(WPMINFO2) { 428static void DAC1064_restore_1(struct matrox_fb_info *minfo)
417 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 429{
430 struct matrox_hw_state *hw = &minfo->hw;
418 431
419 CRITFLAGS 432 CRITFLAGS
420 433
@@ -422,28 +435,29 @@ static void DAC1064_restore_1(WPMINFO2) {
422 435
423 CRITBEGIN 436 CRITBEGIN
424 437
425 if ((inDAC1064(PMINFO DAC1064_XSYSPLLM) != hw->DACclk[3]) || 438 if ((inDAC1064(minfo, DAC1064_XSYSPLLM) != hw->DACclk[3]) ||
426 (inDAC1064(PMINFO DAC1064_XSYSPLLN) != hw->DACclk[4]) || 439 (inDAC1064(minfo, DAC1064_XSYSPLLN) != hw->DACclk[4]) ||
427 (inDAC1064(PMINFO DAC1064_XSYSPLLP) != hw->DACclk[5])) { 440 (inDAC1064(minfo, DAC1064_XSYSPLLP) != hw->DACclk[5])) {
428 outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]); 441 outDAC1064(minfo, DAC1064_XSYSPLLM, hw->DACclk[3]);
429 outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]); 442 outDAC1064(minfo, DAC1064_XSYSPLLN, hw->DACclk[4]);
430 outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]); 443 outDAC1064(minfo, DAC1064_XSYSPLLP, hw->DACclk[5]);
431 } 444 }
432 { 445 {
433 unsigned int i; 446 unsigned int i;
434 447
435 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { 448 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
436 if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL)) 449 if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL))
437 outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]); 450 outDAC1064(minfo, MGA1064_DAC_regs[i], hw->DACreg[i]);
438 } 451 }
439 } 452 }
440 453
441 DAC1064_global_restore(PMINFO2); 454 DAC1064_global_restore(minfo);
442 455
443 CRITEND 456 CRITEND
444}; 457};
445 458
446static void DAC1064_restore_2(WPMINFO2) { 459static void DAC1064_restore_2(struct matrox_fb_info *minfo)
460{
447#ifdef DEBUG 461#ifdef DEBUG
448 unsigned int i; 462 unsigned int i;
449#endif 463#endif
@@ -453,12 +467,12 @@ static void DAC1064_restore_2(WPMINFO2) {
453#ifdef DEBUG 467#ifdef DEBUG
454 dprintk(KERN_DEBUG "DAC1064regs "); 468 dprintk(KERN_DEBUG "DAC1064regs ");
455 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { 469 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
456 dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]); 470 dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], minfo->hw.DACreg[i]);
457 if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... "); 471 if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... ");
458 } 472 }
459 dprintk(KERN_DEBUG "DAC1064clk "); 473 dprintk(KERN_DEBUG "DAC1064clk ");
460 for (i = 0; i < 6; i++) 474 for (i = 0; i < 6; i++)
461 dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]); 475 dprintk("C%02X=%02X ", i, minfo->hw.DACclk[i]);
462 dprintk("\n"); 476 dprintk("\n");
463#endif 477#endif
464} 478}
@@ -470,14 +484,14 @@ static int m1064_compute(void* out, struct my_timming* m) {
470 int tmout; 484 int tmout;
471 CRITFLAGS 485 CRITFLAGS
472 486
473 DAC1064_setpclk(PMINFO m->pixclock); 487 DAC1064_setpclk(minfo, m->pixclock);
474 488
475 CRITBEGIN 489 CRITBEGIN
476 490
477 for (i = 0; i < 3; i++) 491 for (i = 0; i < 3; i++)
478 outDAC1064(PMINFO M1064_XPIXPLLCM + i, ACCESS_FBINFO(hw).DACclk[i]); 492 outDAC1064(minfo, M1064_XPIXPLLCM + i, minfo->hw.DACclk[i]);
479 for (tmout = 500000; tmout; tmout--) { 493 for (tmout = 500000; tmout; tmout--) {
480 if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40) 494 if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)
481 break; 495 break;
482 udelay(10); 496 udelay(10);
483 }; 497 };
@@ -500,9 +514,9 @@ static struct matrox_altout m1064 = {
500static int g450_compute(void* out, struct my_timming* m) { 514static int g450_compute(void* out, struct my_timming* m) {
501#define minfo ((struct matrox_fb_info*)out) 515#define minfo ((struct matrox_fb_info*)out)
502 if (m->mnp < 0) { 516 if (m->mnp < 0) {
503 m->mnp = matroxfb_g450_setclk(PMINFO m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); 517 m->mnp = matroxfb_g450_setclk(minfo, m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
504 if (m->mnp >= 0) { 518 if (m->mnp >= 0) {
505 m->pixclock = g450_mnp2f(PMINFO m->mnp); 519 m->pixclock = g450_mnp2f(minfo, m->mnp);
506 } 520 }
507 } 521 }
508#undef minfo 522#undef minfo
@@ -518,13 +532,14 @@ static struct matrox_altout g450out = {
518#endif /* NEED_DAC1064 */ 532#endif /* NEED_DAC1064 */
519 533
520#ifdef CONFIG_FB_MATROX_MYSTIQUE 534#ifdef CONFIG_FB_MATROX_MYSTIQUE
521static int MGA1064_init(WPMINFO struct my_timming* m) { 535static int MGA1064_init(struct matrox_fb_info *minfo, struct my_timming *m)
522 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 536{
537 struct matrox_hw_state *hw = &minfo->hw;
523 538
524 DBG(__func__) 539 DBG(__func__)
525 540
526 if (DAC1064_init_1(PMINFO m)) return 1; 541 if (DAC1064_init_1(minfo, m)) return 1;
527 if (matroxfb_vgaHWinit(PMINFO m)) return 1; 542 if (matroxfb_vgaHWinit(minfo, m)) return 1;
528 543
529 hw->MiscOutReg = 0xCB; 544 hw->MiscOutReg = 0xCB;
530 if (m->sync & FB_SYNC_HOR_HIGH_ACT) 545 if (m->sync & FB_SYNC_HOR_HIGH_ACT)
@@ -534,20 +549,21 @@ static int MGA1064_init(WPMINFO struct my_timming* m) {
534 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ 549 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
535 hw->CRTCEXT[3] |= 0x40; 550 hw->CRTCEXT[3] |= 0x40;
536 551
537 if (DAC1064_init_2(PMINFO m)) return 1; 552 if (DAC1064_init_2(minfo, m)) return 1;
538 return 0; 553 return 0;
539} 554}
540#endif 555#endif
541 556
542#ifdef CONFIG_FB_MATROX_G 557#ifdef CONFIG_FB_MATROX_G
543static int MGAG100_init(WPMINFO struct my_timming* m) { 558static int MGAG100_init(struct matrox_fb_info *minfo, struct my_timming *m)
544 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 559{
560 struct matrox_hw_state *hw = &minfo->hw;
545 561
546 DBG(__func__) 562 DBG(__func__)
547 563
548 if (DAC1064_init_1(PMINFO m)) return 1; 564 if (DAC1064_init_1(minfo, m)) return 1;
549 hw->MXoptionReg &= ~0x2000; 565 hw->MXoptionReg &= ~0x2000;
550 if (matroxfb_vgaHWinit(PMINFO m)) return 1; 566 if (matroxfb_vgaHWinit(minfo, m)) return 1;
551 567
552 hw->MiscOutReg = 0xEF; 568 hw->MiscOutReg = 0xEF;
553 if (m->sync & FB_SYNC_HOR_HIGH_ACT) 569 if (m->sync & FB_SYNC_HOR_HIGH_ACT)
@@ -557,27 +573,28 @@ static int MGAG100_init(WPMINFO struct my_timming* m) {
557 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ 573 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
558 hw->CRTCEXT[3] |= 0x40; 574 hw->CRTCEXT[3] |= 0x40;
559 575
560 if (DAC1064_init_2(PMINFO m)) return 1; 576 if (DAC1064_init_2(minfo, m)) return 1;
561 return 0; 577 return 0;
562} 578}
563#endif /* G */ 579#endif /* G */
564 580
565#ifdef CONFIG_FB_MATROX_MYSTIQUE 581#ifdef CONFIG_FB_MATROX_MYSTIQUE
566static void MGA1064_ramdac_init(WPMINFO2) { 582static void MGA1064_ramdac_init(struct matrox_fb_info *minfo)
583{
567 584
568 DBG(__func__) 585 DBG(__func__)
569 586
570 /* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */ 587 /* minfo->features.DAC1064.vco_freq_min = 120000; */
571 ACCESS_FBINFO(features.pll.vco_freq_min) = 62000; 588 minfo->features.pll.vco_freq_min = 62000;
572 ACCESS_FBINFO(features.pll.ref_freq) = 14318; 589 minfo->features.pll.ref_freq = 14318;
573 ACCESS_FBINFO(features.pll.feed_div_min) = 100; 590 minfo->features.pll.feed_div_min = 100;
574 ACCESS_FBINFO(features.pll.feed_div_max) = 127; 591 minfo->features.pll.feed_div_max = 127;
575 ACCESS_FBINFO(features.pll.in_div_min) = 1; 592 minfo->features.pll.in_div_min = 1;
576 ACCESS_FBINFO(features.pll.in_div_max) = 31; 593 minfo->features.pll.in_div_max = 31;
577 ACCESS_FBINFO(features.pll.post_shift_max) = 3; 594 minfo->features.pll.post_shift_max = 3;
578 ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL; 595 minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_EXTERNAL;
579 /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */ 596 /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
580 DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333); 597 DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
581} 598}
582#endif 599#endif
583 600
@@ -589,23 +606,25 @@ static int x7AF4 = 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
589static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */ 606static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
590#endif 607#endif
591 608
592static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p) { 609static void MGAG100_progPixClock(const struct matrox_fb_info *minfo, int flags,
610 int m, int n, int p)
611{
593 int reg; 612 int reg;
594 int selClk; 613 int selClk;
595 int clk; 614 int clk;
596 615
597 DBG(__func__) 616 DBG(__func__)
598 617
599 outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS | 618 outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS |
600 M1064_XPIXCLKCTRL_PLL_UP); 619 M1064_XPIXCLKCTRL_PLL_UP);
601 switch (flags & 3) { 620 switch (flags & 3) {
602 case 0: reg = M1064_XPIXPLLAM; break; 621 case 0: reg = M1064_XPIXPLLAM; break;
603 case 1: reg = M1064_XPIXPLLBM; break; 622 case 1: reg = M1064_XPIXPLLBM; break;
604 default: reg = M1064_XPIXPLLCM; break; 623 default: reg = M1064_XPIXPLLCM; break;
605 } 624 }
606 outDAC1064(PMINFO reg++, m); 625 outDAC1064(minfo, reg++, m);
607 outDAC1064(PMINFO reg++, n); 626 outDAC1064(minfo, reg++, n);
608 outDAC1064(PMINFO reg, p); 627 outDAC1064(minfo, reg, p);
609 selClk = mga_inb(M_MISC_REG_READ) & ~0xC; 628 selClk = mga_inb(M_MISC_REG_READ) & ~0xC;
610 /* there should be flags & 0x03 & case 0/1/else */ 629 /* there should be flags & 0x03 & case 0/1/else */
611 /* and we should first select source and after that we should wait for PLL */ 630 /* and we should first select source and after that we should wait for PLL */
@@ -617,61 +636,64 @@ static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p) {
617 } 636 }
618 mga_outb(M_MISC_REG, selClk); 637 mga_outb(M_MISC_REG, selClk);
619 for (clk = 500000; clk; clk--) { 638 for (clk = 500000; clk; clk--) {
620 if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40) 639 if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)
621 break; 640 break;
622 udelay(10); 641 udelay(10);
623 }; 642 };
624 if (!clk) 643 if (!clk)
625 printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A'); 644 printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
626 selClk = inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK; 645 selClk = inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
627 switch (flags & 0x0C) { 646 switch (flags & 0x0C) {
628 case 0x00: selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break; 647 case 0x00: selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break;
629 case 0x04: selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break; 648 case 0x04: selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break;
630 default: selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break; 649 default: selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break;
631 } 650 }
632 outDAC1064(PMINFO M1064_XPIXCLKCTRL, selClk); 651 outDAC1064(minfo, M1064_XPIXCLKCTRL, selClk);
633 outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS); 652 outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
634} 653}
635 654
636static void MGAG100_setPixClock(CPMINFO int flags, int freq) { 655static void MGAG100_setPixClock(const struct matrox_fb_info *minfo, int flags,
656 int freq)
657{
637 unsigned int m, n, p; 658 unsigned int m, n, p;
638 659
639 DBG(__func__) 660 DBG(__func__)
640 661
641 DAC1064_calcclock(PMINFO freq, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p); 662 DAC1064_calcclock(minfo, freq, minfo->max_pixel_clock, &m, &n, &p);
642 MGAG100_progPixClock(PMINFO flags, m, n, p); 663 MGAG100_progPixClock(minfo, flags, m, n, p);
643} 664}
644#endif 665#endif
645 666
646#ifdef CONFIG_FB_MATROX_MYSTIQUE 667#ifdef CONFIG_FB_MATROX_MYSTIQUE
647static int MGA1064_preinit(WPMINFO2) { 668static int MGA1064_preinit(struct matrox_fb_info *minfo)
669{
648 static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960, 670 static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960,
649 1024, 1152, 1280, 1600, 1664, 1920, 671 1024, 1152, 1280, 1600, 1664, 1920,
650 2048, 0}; 672 2048, 0};
651 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 673 struct matrox_hw_state *hw = &minfo->hw;
652 674
653 DBG(__func__) 675 DBG(__func__)
654 676
655 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ 677 /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
656 ACCESS_FBINFO(capable.text) = 1; 678 minfo->capable.text = 1;
657 ACCESS_FBINFO(capable.vxres) = vxres_mystique; 679 minfo->capable.vxres = vxres_mystique;
658 680
659 ACCESS_FBINFO(outputs[0]).output = &m1064; 681 minfo->outputs[0].output = &m1064;
660 ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src; 682 minfo->outputs[0].src = minfo->outputs[0].default_src;
661 ACCESS_FBINFO(outputs[0]).data = MINFO; 683 minfo->outputs[0].data = minfo;
662 ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 684 minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR;
663 685
664 if (ACCESS_FBINFO(devflags.noinit)) 686 if (minfo->devflags.noinit)
665 return 0; /* do not modify settings */ 687 return 0; /* do not modify settings */
666 hw->MXoptionReg &= 0xC0000100; 688 hw->MXoptionReg &= 0xC0000100;
667 hw->MXoptionReg |= 0x00094E20; 689 hw->MXoptionReg |= 0x00094E20;
668 if (ACCESS_FBINFO(devflags.novga)) 690 if (minfo->devflags.novga)
669 hw->MXoptionReg &= ~0x00000100; 691 hw->MXoptionReg &= ~0x00000100;
670 if (ACCESS_FBINFO(devflags.nobios)) 692 if (minfo->devflags.nobios)
671 hw->MXoptionReg &= ~0x40000000; 693 hw->MXoptionReg &= ~0x40000000;
672 if (ACCESS_FBINFO(devflags.nopciretry)) 694 if (minfo->devflags.nopciretry)
673 hw->MXoptionReg |= 0x20000000; 695 hw->MXoptionReg |= 0x20000000;
674 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 696 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
675 mga_setr(M_SEQ_INDEX, 0x01, 0x20); 697 mga_setr(M_SEQ_INDEX, 0x01, 0x20);
676 mga_outl(M_CTLWTST, 0x00000000); 698 mga_outl(M_CTLWTST, 0x00000000);
677 udelay(200); 699 udelay(200);
@@ -681,101 +703,105 @@ static int MGA1064_preinit(WPMINFO2) {
681 return 0; 703 return 0;
682} 704}
683 705
684static void MGA1064_reset(WPMINFO2) { 706static void MGA1064_reset(struct matrox_fb_info *minfo)
707{
685 708
686 DBG(__func__); 709 DBG(__func__);
687 710
688 MGA1064_ramdac_init(PMINFO2); 711 MGA1064_ramdac_init(minfo);
689} 712}
690#endif 713#endif
691 714
692#ifdef CONFIG_FB_MATROX_G 715#ifdef CONFIG_FB_MATROX_G
693static void g450_mclk_init(WPMINFO2) { 716static void g450_mclk_init(struct matrox_fb_info *minfo)
717{
694 /* switch all clocks to PCI source */ 718 /* switch all clocks to PCI source */
695 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4); 719 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4);
696 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3 & ~0x00300C03); 720 pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3 & ~0x00300C03);
697 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); 721 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
698 722
699 if (((ACCESS_FBINFO(values).reg.opt3 & 0x000003) == 0x000003) || 723 if (((minfo->values.reg.opt3 & 0x000003) == 0x000003) ||
700 ((ACCESS_FBINFO(values).reg.opt3 & 0x000C00) == 0x000C00) || 724 ((minfo->values.reg.opt3 & 0x000C00) == 0x000C00) ||
701 ((ACCESS_FBINFO(values).reg.opt3 & 0x300000) == 0x300000)) { 725 ((minfo->values.reg.opt3 & 0x300000) == 0x300000)) {
702 matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.video), M_VIDEO_PLL); 726 matroxfb_g450_setclk(minfo, minfo->values.pll.video, M_VIDEO_PLL);
703 } else { 727 } else {
704 unsigned long flags; 728 unsigned long flags;
705 unsigned int pwr; 729 unsigned int pwr;
706 730
707 matroxfb_DAC_lock_irqsave(flags); 731 matroxfb_DAC_lock_irqsave(flags);
708 pwr = inDAC1064(PMINFO M1064_XPWRCTRL) & ~0x02; 732 pwr = inDAC1064(minfo, M1064_XPWRCTRL) & ~0x02;
709 outDAC1064(PMINFO M1064_XPWRCTRL, pwr); 733 outDAC1064(minfo, M1064_XPWRCTRL, pwr);
710 matroxfb_DAC_unlock_irqrestore(flags); 734 matroxfb_DAC_unlock_irqrestore(flags);
711 } 735 }
712 matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.system), M_SYSTEM_PLL); 736 matroxfb_g450_setclk(minfo, minfo->values.pll.system, M_SYSTEM_PLL);
713 737
714 /* switch clocks to their real PLL source(s) */ 738 /* switch clocks to their real PLL source(s) */
715 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4); 739 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4);
716 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3); 740 pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3);
717 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); 741 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
718 742
719} 743}
720 744
721static void g450_memory_init(WPMINFO2) { 745static void g450_memory_init(struct matrox_fb_info *minfo)
746{
722 /* disable memory refresh */ 747 /* disable memory refresh */
723 ACCESS_FBINFO(hw).MXoptionReg &= ~0x001F8000; 748 minfo->hw.MXoptionReg &= ~0x001F8000;
724 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); 749 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
725 750
726 /* set memory interface parameters */ 751 /* set memory interface parameters */
727 ACCESS_FBINFO(hw).MXoptionReg &= ~0x00207E00; 752 minfo->hw.MXoptionReg &= ~0x00207E00;
728 ACCESS_FBINFO(hw).MXoptionReg |= 0x00207E00 & ACCESS_FBINFO(values).reg.opt; 753 minfo->hw.MXoptionReg |= 0x00207E00 & minfo->values.reg.opt;
729 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); 754 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
730 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ACCESS_FBINFO(values).reg.opt2); 755 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, minfo->values.reg.opt2);
731 756
732 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst); 757 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
733 758
734 /* first set up memory interface with disabled memory interface clocks */ 759 /* first set up memory interface with disabled memory interface clocks */
735 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc & ~0x80000000U); 760 pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc & ~0x80000000U);
736 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); 761 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
737 mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess); 762 mga_outl(M_MACCESS, minfo->values.reg.maccess);
738 /* start memory clocks */ 763 /* start memory clocks */
739 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc | 0x80000000U); 764 pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc | 0x80000000U);
740 765
741 udelay(200); 766 udelay(200);
742 767
743 if (ACCESS_FBINFO(values).memory.ddr && (!ACCESS_FBINFO(values).memory.emrswen || !ACCESS_FBINFO(values).memory.dll)) { 768 if (minfo->values.memory.ddr && (!minfo->values.memory.emrswen || !minfo->values.memory.dll)) {
744 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk & ~0x1000); 769 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk & ~0x1000);
745 } 770 }
746 mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess | 0x8000); 771 mga_outl(M_MACCESS, minfo->values.reg.maccess | 0x8000);
747 772
748 udelay(200); 773 udelay(200);
749 774
750 ACCESS_FBINFO(hw).MXoptionReg |= 0x001F8000 & ACCESS_FBINFO(values).reg.opt; 775 minfo->hw.MXoptionReg |= 0x001F8000 & minfo->values.reg.opt;
751 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); 776 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
752 777
753 /* value is written to memory chips only if old != new */ 778 /* value is written to memory chips only if old != new */
754 mga_outl(M_PLNWT, 0); 779 mga_outl(M_PLNWT, 0);
755 mga_outl(M_PLNWT, ~0); 780 mga_outl(M_PLNWT, ~0);
756 781
757 if (ACCESS_FBINFO(values).reg.mctlwtst != ACCESS_FBINFO(values).reg.mctlwtst_core) { 782 if (minfo->values.reg.mctlwtst != minfo->values.reg.mctlwtst_core) {
758 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst_core); 783 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst_core);
759 } 784 }
760 785
761} 786}
762 787
763static void g450_preinit(WPMINFO2) { 788static void g450_preinit(struct matrox_fb_info *minfo)
789{
764 u_int32_t c2ctl; 790 u_int32_t c2ctl;
765 u_int8_t curctl; 791 u_int8_t curctl;
766 u_int8_t c1ctl; 792 u_int8_t c1ctl;
767 793
768 /* ACCESS_FBINFO(hw).MXoptionReg = minfo->values.reg.opt; */ 794 /* minfo->hw.MXoptionReg = minfo->values.reg.opt; */
769 ACCESS_FBINFO(hw).MXoptionReg &= 0xC0000100; 795 minfo->hw.MXoptionReg &= 0xC0000100;
770 ACCESS_FBINFO(hw).MXoptionReg |= 0x00000020; 796 minfo->hw.MXoptionReg |= 0x00000020;
771 if (ACCESS_FBINFO(devflags.novga)) 797 if (minfo->devflags.novga)
772 ACCESS_FBINFO(hw).MXoptionReg &= ~0x00000100; 798 minfo->hw.MXoptionReg &= ~0x00000100;
773 if (ACCESS_FBINFO(devflags.nobios)) 799 if (minfo->devflags.nobios)
774 ACCESS_FBINFO(hw).MXoptionReg &= ~0x40000000; 800 minfo->hw.MXoptionReg &= ~0x40000000;
775 if (ACCESS_FBINFO(devflags.nopciretry)) 801 if (minfo->devflags.nopciretry)
776 ACCESS_FBINFO(hw).MXoptionReg |= 0x20000000; 802 minfo->hw.MXoptionReg |= 0x20000000;
777 ACCESS_FBINFO(hw).MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x03400040; 803 minfo->hw.MXoptionReg |= minfo->values.reg.opt & 0x03400040;
778 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); 804 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
779 805
780 /* Init system clocks */ 806 /* Init system clocks */
781 807
@@ -783,24 +809,24 @@ static void g450_preinit(WPMINFO2) {
783 c2ctl = mga_inl(M_C2CTL); 809 c2ctl = mga_inl(M_C2CTL);
784 mga_outl(M_C2CTL, c2ctl & ~1); 810 mga_outl(M_C2CTL, c2ctl & ~1);
785 /* stop cursor */ 811 /* stop cursor */
786 curctl = inDAC1064(PMINFO M1064_XCURCTRL); 812 curctl = inDAC1064(minfo, M1064_XCURCTRL);
787 outDAC1064(PMINFO M1064_XCURCTRL, 0); 813 outDAC1064(minfo, M1064_XCURCTRL, 0);
788 /* stop crtc1 */ 814 /* stop crtc1 */
789 c1ctl = mga_readr(M_SEQ_INDEX, 1); 815 c1ctl = mga_readr(M_SEQ_INDEX, 1);
790 mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20); 816 mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20);
791 817
792 g450_mclk_init(PMINFO2); 818 g450_mclk_init(minfo);
793 g450_memory_init(PMINFO2); 819 g450_memory_init(minfo);
794 820
795 /* set legacy VGA clock sources for DOSEmu or VMware... */ 821 /* set legacy VGA clock sources for DOSEmu or VMware... */
796 matroxfb_g450_setclk(PMINFO 25175, M_PIXEL_PLL_A); 822 matroxfb_g450_setclk(minfo, 25175, M_PIXEL_PLL_A);
797 matroxfb_g450_setclk(PMINFO 28322, M_PIXEL_PLL_B); 823 matroxfb_g450_setclk(minfo, 28322, M_PIXEL_PLL_B);
798 824
799 /* restore crtc1 */ 825 /* restore crtc1 */
800 mga_setr(M_SEQ_INDEX, 1, c1ctl); 826 mga_setr(M_SEQ_INDEX, 1, c1ctl);
801 827
802 /* restore cursor */ 828 /* restore cursor */
803 outDAC1064(PMINFO M1064_XCURCTRL, curctl); 829 outDAC1064(minfo, M1064_XCURCTRL, curctl);
804 830
805 /* restore crtc2 */ 831 /* restore crtc2 */
806 mga_outl(M_C2CTL, c2ctl); 832 mga_outl(M_C2CTL, c2ctl);
@@ -808,11 +834,12 @@ static void g450_preinit(WPMINFO2) {
808 return; 834 return;
809} 835}
810 836
811static int MGAG100_preinit(WPMINFO2) { 837static int MGAG100_preinit(struct matrox_fb_info *minfo)
838{
812 static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960, 839 static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960,
813 1024, 1152, 1280, 1600, 1664, 1920, 840 1024, 1152, 1280, 1600, 1664, 1920,
814 2048, 0}; 841 2048, 0};
815 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 842 struct matrox_hw_state *hw = &minfo->hw;
816 843
817 u_int32_t reg50; 844 u_int32_t reg50;
818#if 0 845#if 0
@@ -822,68 +849,68 @@ static int MGAG100_preinit(WPMINFO2) {
822 DBG(__func__) 849 DBG(__func__)
823 850
824 /* there are some instabilities if in_div > 19 && vco < 61000 */ 851 /* there are some instabilities if in_div > 19 && vco < 61000 */
825 if (ACCESS_FBINFO(devflags.g450dac)) { 852 if (minfo->devflags.g450dac) {
826 ACCESS_FBINFO(features.pll.vco_freq_min) = 130000; /* my sample: >118 */ 853 minfo->features.pll.vco_freq_min = 130000; /* my sample: >118 */
827 } else { 854 } else {
828 ACCESS_FBINFO(features.pll.vco_freq_min) = 62000; 855 minfo->features.pll.vco_freq_min = 62000;
829 } 856 }
830 if (!ACCESS_FBINFO(features.pll.ref_freq)) { 857 if (!minfo->features.pll.ref_freq) {
831 ACCESS_FBINFO(features.pll.ref_freq) = 27000; 858 minfo->features.pll.ref_freq = 27000;
832 } 859 }
833 ACCESS_FBINFO(features.pll.feed_div_min) = 7; 860 minfo->features.pll.feed_div_min = 7;
834 ACCESS_FBINFO(features.pll.feed_div_max) = 127; 861 minfo->features.pll.feed_div_max = 127;
835 ACCESS_FBINFO(features.pll.in_div_min) = 1; 862 minfo->features.pll.in_div_min = 1;
836 ACCESS_FBINFO(features.pll.in_div_max) = 31; 863 minfo->features.pll.in_div_max = 31;
837 ACCESS_FBINFO(features.pll.post_shift_max) = 3; 864 minfo->features.pll.post_shift_max = 3;
838 ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT; 865 minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_G100_DEFAULT;
839 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ 866 /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
840 ACCESS_FBINFO(capable.text) = 1; 867 minfo->capable.text = 1;
841 ACCESS_FBINFO(capable.vxres) = vxres_g100; 868 minfo->capable.vxres = vxres_g100;
842 ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100 869 minfo->capable.plnwt = minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100
843 ? ACCESS_FBINFO(devflags.sgram) : 1; 870 ? minfo->devflags.sgram : 1;
844 871
845#ifdef CONFIG_FB_MATROX_G 872#ifdef CONFIG_FB_MATROX_G
846 if (ACCESS_FBINFO(devflags.g450dac)) { 873 if (minfo->devflags.g450dac) {
847 ACCESS_FBINFO(outputs[0]).output = &g450out; 874 minfo->outputs[0].output = &g450out;
848 } else 875 } else
849#endif 876#endif
850 { 877 {
851 ACCESS_FBINFO(outputs[0]).output = &m1064; 878 minfo->outputs[0].output = &m1064;
852 } 879 }
853 ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src; 880 minfo->outputs[0].src = minfo->outputs[0].default_src;
854 ACCESS_FBINFO(outputs[0]).data = MINFO; 881 minfo->outputs[0].data = minfo;
855 ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 882 minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR;
856 883
857 if (ACCESS_FBINFO(devflags.g450dac)) { 884 if (minfo->devflags.g450dac) {
858 /* we must do this always, BIOS does not do it for us 885 /* we must do this always, BIOS does not do it for us
859 and accelerator dies without it */ 886 and accelerator dies without it */
860 mga_outl(0x1C0C, 0); 887 mga_outl(0x1C0C, 0);
861 } 888 }
862 if (ACCESS_FBINFO(devflags.noinit)) 889 if (minfo->devflags.noinit)
863 return 0; 890 return 0;
864 if (ACCESS_FBINFO(devflags.g450dac)) { 891 if (minfo->devflags.g450dac) {
865 g450_preinit(PMINFO2); 892 g450_preinit(minfo);
866 return 0; 893 return 0;
867 } 894 }
868 hw->MXoptionReg &= 0xC0000100; 895 hw->MXoptionReg &= 0xC0000100;
869 hw->MXoptionReg |= 0x00000020; 896 hw->MXoptionReg |= 0x00000020;
870 if (ACCESS_FBINFO(devflags.novga)) 897 if (minfo->devflags.novga)
871 hw->MXoptionReg &= ~0x00000100; 898 hw->MXoptionReg &= ~0x00000100;
872 if (ACCESS_FBINFO(devflags.nobios)) 899 if (minfo->devflags.nobios)
873 hw->MXoptionReg &= ~0x40000000; 900 hw->MXoptionReg &= ~0x40000000;
874 if (ACCESS_FBINFO(devflags.nopciretry)) 901 if (minfo->devflags.nopciretry)
875 hw->MXoptionReg |= 0x20000000; 902 hw->MXoptionReg |= 0x20000000;
876 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 903 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
877 DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333); 904 DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
878 905
879 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) { 906 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100) {
880 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50); 907 pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, &reg50);
881 reg50 &= ~0x3000; 908 reg50 &= ~0x3000;
882 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50); 909 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
883 910
884 hw->MXoptionReg |= 0x1080; 911 hw->MXoptionReg |= 0x1080;
885 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 912 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
886 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst); 913 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
887 udelay(100); 914 udelay(100);
888 mga_outb(0x1C05, 0x00); 915 mga_outb(0x1C05, 0x00);
889 mga_outb(0x1C05, 0x80); 916 mga_outb(0x1C05, 0x80);
@@ -893,68 +920,69 @@ static int MGAG100_preinit(WPMINFO2) {
893 udelay(100); 920 udelay(100);
894 reg50 &= ~0xFF; 921 reg50 &= ~0xFF;
895 reg50 |= 0x07; 922 reg50 |= 0x07;
896 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50); 923 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
897 /* it should help with G100 */ 924 /* it should help with G100 */
898 mga_outb(M_GRAPHICS_INDEX, 6); 925 mga_outb(M_GRAPHICS_INDEX, 6);
899 mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4); 926 mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
900 mga_setr(M_EXTVGA_INDEX, 0x03, 0x81); 927 mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
901 mga_setr(M_EXTVGA_INDEX, 0x04, 0x00); 928 mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
902 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA); 929 mga_writeb(minfo->video.vbase, 0x0000, 0xAA);
903 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55); 930 mga_writeb(minfo->video.vbase, 0x0800, 0x55);
904 mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55); 931 mga_writeb(minfo->video.vbase, 0x4000, 0x55);
905#if 0 932#if 0
906 if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) { 933 if (mga_readb(minfo->video.vbase, 0x0000) != 0xAA) {
907 hw->MXoptionReg &= ~0x1000; 934 hw->MXoptionReg &= ~0x1000;
908 } 935 }
909#endif 936#endif
910 hw->MXoptionReg |= 0x00078020; 937 hw->MXoptionReg |= 0x00078020;
911 } else if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) { 938 } else if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG200) {
912 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50); 939 pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, &reg50);
913 reg50 &= ~0x3000; 940 reg50 &= ~0x3000;
914 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50); 941 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
915 942
916 if (ACCESS_FBINFO(devflags.memtype) == -1) 943 if (minfo->devflags.memtype == -1)
917 hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00; 944 hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00;
918 else 945 else
919 hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10; 946 hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10;
920 if (ACCESS_FBINFO(devflags.sgram)) 947 if (minfo->devflags.sgram)
921 hw->MXoptionReg |= 0x4000; 948 hw->MXoptionReg |= 0x4000;
922 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst); 949 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
923 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); 950 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
924 udelay(200); 951 udelay(200);
925 mga_outl(M_MACCESS, 0x00000000); 952 mga_outl(M_MACCESS, 0x00000000);
926 mga_outl(M_MACCESS, 0x00008000); 953 mga_outl(M_MACCESS, 0x00008000);
927 udelay(100); 954 udelay(100);
928 mga_outw(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); 955 mga_outw(M_MEMRDBK, minfo->values.reg.memrdbk);
929 hw->MXoptionReg |= 0x00078020; 956 hw->MXoptionReg |= 0x00078020;
930 } else { 957 } else {
931 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50); 958 pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, &reg50);
932 reg50 &= ~0x00000100; 959 reg50 &= ~0x00000100;
933 reg50 |= 0x00000000; 960 reg50 |= 0x00000000;
934 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50); 961 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
935 962
936 if (ACCESS_FBINFO(devflags.memtype) == -1) 963 if (minfo->devflags.memtype == -1)
937 hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00; 964 hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00;
938 else 965 else
939 hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10; 966 hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10;
940 if (ACCESS_FBINFO(devflags.sgram)) 967 if (minfo->devflags.sgram)
941 hw->MXoptionReg |= 0x4000; 968 hw->MXoptionReg |= 0x4000;
942 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst); 969 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
943 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); 970 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
944 udelay(200); 971 udelay(200);
945 mga_outl(M_MACCESS, 0x00000000); 972 mga_outl(M_MACCESS, 0x00000000);
946 mga_outl(M_MACCESS, 0x00008000); 973 mga_outl(M_MACCESS, 0x00008000);
947 udelay(100); 974 udelay(100);
948 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk); 975 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
949 hw->MXoptionReg |= 0x00040020; 976 hw->MXoptionReg |= 0x00040020;
950 } 977 }
951 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 978 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
952 return 0; 979 return 0;
953} 980}
954 981
955static void MGAG100_reset(WPMINFO2) { 982static void MGAG100_reset(struct matrox_fb_info *minfo)
983{
956 u_int8_t b; 984 u_int8_t b;
957 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 985 struct matrox_hw_state *hw = &minfo->hw;
958 986
959 DBG(__func__) 987 DBG(__func__)
960 988
@@ -964,54 +992,55 @@ static void MGAG100_reset(WPMINFO2) {
964 992
965 find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */ 993 find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
966 pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b); 994 pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
967 if (b == ACCESS_FBINFO(pcidev)->bus->number) { 995 if (b == minfo->pcidev->bus->number) {
968 pci_write_config_byte(ibm, PCI_COMMAND+1, 0); /* disable back-to-back & SERR */ 996 pci_write_config_byte(ibm, PCI_COMMAND+1, 0); /* disable back-to-back & SERR */
969 pci_write_config_byte(ibm, 0x41, 0xF4); /* ??? */ 997 pci_write_config_byte(ibm, 0x41, 0xF4); /* ??? */
970 pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0); /* ??? */ 998 pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0); /* ??? */
971 pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */ 999 pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */
972 } 1000 }
973#endif 1001#endif
974 if (!ACCESS_FBINFO(devflags.noinit)) { 1002 if (!minfo->devflags.noinit) {
975 if (x7AF4 & 8) { 1003 if (x7AF4 & 8) {
976 hw->MXoptionReg |= 0x40; /* FIXME... */ 1004 hw->MXoptionReg |= 0x40; /* FIXME... */
977 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 1005 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
978 } 1006 }
979 mga_setr(M_EXTVGA_INDEX, 0x06, 0x00); 1007 mga_setr(M_EXTVGA_INDEX, 0x06, 0x00);
980 } 1008 }
981 } 1009 }
982 if (ACCESS_FBINFO(devflags.g450dac)) { 1010 if (minfo->devflags.g450dac) {
983 /* either leave MCLK as is... or they were set in preinit */ 1011 /* either leave MCLK as is... or they were set in preinit */
984 hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM); 1012 hw->DACclk[3] = inDAC1064(minfo, DAC1064_XSYSPLLM);
985 hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN); 1013 hw->DACclk[4] = inDAC1064(minfo, DAC1064_XSYSPLLN);
986 hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP); 1014 hw->DACclk[5] = inDAC1064(minfo, DAC1064_XSYSPLLP);
987 } else { 1015 } else {
988 DAC1064_setmclk(PMINFO DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333); 1016 DAC1064_setmclk(minfo, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
989 } 1017 }
990 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) { 1018 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) {
991 if (ACCESS_FBINFO(devflags.dfp_type) == -1) { 1019 if (minfo->devflags.dfp_type == -1) {
992 ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F); 1020 minfo->devflags.dfp_type = inDAC1064(minfo, 0x1F);
993 } 1021 }
994 } 1022 }
995 if (ACCESS_FBINFO(devflags.noinit)) 1023 if (minfo->devflags.noinit)
996 return; 1024 return;
997 if (ACCESS_FBINFO(devflags.g450dac)) { 1025 if (minfo->devflags.g450dac) {
998 } else { 1026 } else {
999 MGAG100_setPixClock(PMINFO 4, 25175); 1027 MGAG100_setPixClock(minfo, 4, 25175);
1000 MGAG100_setPixClock(PMINFO 5, 28322); 1028 MGAG100_setPixClock(minfo, 5, 28322);
1001 if (x7AF4 & 0x10) { 1029 if (x7AF4 & 0x10) {
1002 b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1; 1030 b = inDAC1064(minfo, M1064_XGENIODATA) & ~1;
1003 outDAC1064(PMINFO M1064_XGENIODATA, b); 1031 outDAC1064(minfo, M1064_XGENIODATA, b);
1004 b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1; 1032 b = inDAC1064(minfo, M1064_XGENIOCTRL) | 1;
1005 outDAC1064(PMINFO M1064_XGENIOCTRL, b); 1033 outDAC1064(minfo, M1064_XGENIOCTRL, b);
1006 } 1034 }
1007 } 1035 }
1008} 1036}
1009#endif 1037#endif
1010 1038
1011#ifdef CONFIG_FB_MATROX_MYSTIQUE 1039#ifdef CONFIG_FB_MATROX_MYSTIQUE
1012static void MGA1064_restore(WPMINFO2) { 1040static void MGA1064_restore(struct matrox_fb_info *minfo)
1041{
1013 int i; 1042 int i;
1014 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 1043 struct matrox_hw_state *hw = &minfo->hw;
1015 1044
1016 CRITFLAGS 1045 CRITFLAGS
1017 1046
@@ -1019,25 +1048,26 @@ static void MGA1064_restore(WPMINFO2) {
1019 1048
1020 CRITBEGIN 1049 CRITBEGIN
1021 1050
1022 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 1051 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
1023 mga_outb(M_IEN, 0x00); 1052 mga_outb(M_IEN, 0x00);
1024 mga_outb(M_CACHEFLUSH, 0x00); 1053 mga_outb(M_CACHEFLUSH, 0x00);
1025 1054
1026 CRITEND 1055 CRITEND
1027 1056
1028 DAC1064_restore_1(PMINFO2); 1057 DAC1064_restore_1(minfo);
1029 matroxfb_vgaHWrestore(PMINFO2); 1058 matroxfb_vgaHWrestore(minfo);
1030 ACCESS_FBINFO(crtc1.panpos) = -1; 1059 minfo->crtc1.panpos = -1;
1031 for (i = 0; i < 6; i++) 1060 for (i = 0; i < 6; i++)
1032 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); 1061 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1033 DAC1064_restore_2(PMINFO2); 1062 DAC1064_restore_2(minfo);
1034} 1063}
1035#endif 1064#endif
1036 1065
1037#ifdef CONFIG_FB_MATROX_G 1066#ifdef CONFIG_FB_MATROX_G
1038static void MGAG100_restore(WPMINFO2) { 1067static void MGAG100_restore(struct matrox_fb_info *minfo)
1068{
1039 int i; 1069 int i;
1040 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 1070 struct matrox_hw_state *hw = &minfo->hw;
1041 1071
1042 CRITFLAGS 1072 CRITFLAGS
1043 1073
@@ -1045,19 +1075,17 @@ static void MGAG100_restore(WPMINFO2) {
1045 1075
1046 CRITBEGIN 1076 CRITBEGIN
1047 1077
1048 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 1078 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
1049 CRITEND 1079 CRITEND
1050 1080
1051 DAC1064_restore_1(PMINFO2); 1081 DAC1064_restore_1(minfo);
1052 matroxfb_vgaHWrestore(PMINFO2); 1082 matroxfb_vgaHWrestore(minfo);
1053#ifdef CONFIG_FB_MATROX_32MB 1083 if (minfo->devflags.support32MB)
1054 if (ACCESS_FBINFO(devflags.support32MB))
1055 mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]); 1084 mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
1056#endif 1085 minfo->crtc1.panpos = -1;
1057 ACCESS_FBINFO(crtc1.panpos) = -1;
1058 for (i = 0; i < 6; i++) 1086 for (i = 0; i < 6; i++)
1059 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); 1087 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1060 DAC1064_restore_2(PMINFO2); 1088 DAC1064_restore_2(minfo);
1061} 1089}
1062#endif 1090#endif
1063 1091
diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h
index 7a98ce8043d7..c6ed7801efe2 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.h
+++ b/drivers/video/matrox/matroxfb_DAC1064.h
@@ -11,8 +11,8 @@ extern struct matrox_switch matrox_mystique;
11extern struct matrox_switch matrox_G100; 11extern struct matrox_switch matrox_G100;
12#endif 12#endif
13#ifdef NEED_DAC1064 13#ifdef NEED_DAC1064
14void DAC1064_global_init(WPMINFO2); 14void DAC1064_global_init(struct matrox_fb_info *minfo);
15void DAC1064_global_restore(WPMINFO2); 15void DAC1064_global_restore(struct matrox_fb_info *minfo);
16#endif 16#endif
17 17
18#define M1064_INDEX 0x00 18#define M1064_INDEX 0x00
diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c
index 4e825112a601..835aaaae6b96 100644
--- a/drivers/video/matrox/matroxfb_Ti3026.c
+++ b/drivers/video/matrox/matroxfb_Ti3026.c
@@ -279,27 +279,31 @@ static const unsigned char MGADACbpp32[] =
279 TVP3026_XCOLKEYCTRL_ZOOM1, 279 TVP3026_XCOLKEYCTRL_ZOOM1,
280 0x00, 0x00, TVP3026_XCURCTRL_DIS }; 280 0x00, 0x00, TVP3026_XCURCTRL_DIS };
281 281
282static int Ti3026_calcclock(CPMINFO unsigned int freq, unsigned int fmax, int* in, int* feed, int* post) { 282static int Ti3026_calcclock(const struct matrox_fb_info *minfo,
283 unsigned int freq, unsigned int fmax, int *in,
284 int *feed, int *post)
285{
283 unsigned int fvco; 286 unsigned int fvco;
284 unsigned int lin, lfeed, lpost; 287 unsigned int lin, lfeed, lpost;
285 288
286 DBG(__func__) 289 DBG(__func__)
287 290
288 fvco = PLL_calcclock(PMINFO freq, fmax, &lin, &lfeed, &lpost); 291 fvco = PLL_calcclock(minfo, freq, fmax, &lin, &lfeed, &lpost);
289 fvco >>= (*post = lpost); 292 fvco >>= (*post = lpost);
290 *in = 64 - lin; 293 *in = 64 - lin;
291 *feed = 64 - lfeed; 294 *feed = 64 - lfeed;
292 return fvco; 295 return fvco;
293} 296}
294 297
295static int Ti3026_setpclk(WPMINFO int clk) { 298static int Ti3026_setpclk(struct matrox_fb_info *minfo, int clk)
299{
296 unsigned int f_pll; 300 unsigned int f_pll;
297 unsigned int pixfeed, pixin, pixpost; 301 unsigned int pixfeed, pixin, pixpost;
298 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 302 struct matrox_hw_state *hw = &minfo->hw;
299 303
300 DBG(__func__) 304 DBG(__func__)
301 305
302 f_pll = Ti3026_calcclock(PMINFO clk, ACCESS_FBINFO(max_pixel_clock), &pixin, &pixfeed, &pixpost); 306 f_pll = Ti3026_calcclock(minfo, clk, minfo->max_pixel_clock, &pixin, &pixfeed, &pixpost);
303 307
304 hw->DACclk[0] = pixin | 0xC0; 308 hw->DACclk[0] = pixin | 0xC0;
305 hw->DACclk[1] = pixfeed; 309 hw->DACclk[1] = pixfeed;
@@ -309,9 +313,9 @@ static int Ti3026_setpclk(WPMINFO int clk) {
309 unsigned int loopfeed, loopin, looppost, loopdiv, z; 313 unsigned int loopfeed, loopin, looppost, loopdiv, z;
310 unsigned int Bpp; 314 unsigned int Bpp;
311 315
312 Bpp = ACCESS_FBINFO(curr.final_bppShift); 316 Bpp = minfo->curr.final_bppShift;
313 317
314 if (ACCESS_FBINFO(fbcon).var.bits_per_pixel == 24) { 318 if (minfo->fbcon.var.bits_per_pixel == 24) {
315 loopfeed = 3; /* set lm to any possible value */ 319 loopfeed = 3; /* set lm to any possible value */
316 loopin = 3 * 32 / Bpp; 320 loopin = 3 * 32 / Bpp;
317 } else { 321 } else {
@@ -330,18 +334,18 @@ static int Ti3026_setpclk(WPMINFO int clk) {
330 looppost = 3; 334 looppost = 3;
331 loopdiv = z/16; 335 loopdiv = z/16;
332 } 336 }
333 if (ACCESS_FBINFO(fbcon).var.bits_per_pixel == 24) { 337 if (minfo->fbcon.var.bits_per_pixel == 24) {
334 hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0; 338 hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
335 hw->DACclk[4] = (65 - loopfeed) | 0x80; 339 hw->DACclk[4] = (65 - loopfeed) | 0x80;
336 if (ACCESS_FBINFO(accel.ramdac_rev) > 0x20) { 340 if (minfo->accel.ramdac_rev > 0x20) {
337 if (isInterleave(MINFO)) 341 if (isInterleave(minfo))
338 hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3; 342 hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3;
339 else { 343 else {
340 hw->DACclk[4] &= ~0xC0; 344 hw->DACclk[4] &= ~0xC0;
341 hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3; 345 hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3;
342 } 346 }
343 } else { 347 } else {
344 if (isInterleave(MINFO)) 348 if (isInterleave(minfo))
345 ; /* default... */ 349 ; /* default... */
346 else { 350 else {
347 hw->DACclk[4] ^= 0xC0; /* change from 0x80 to 0x40 */ 351 hw->DACclk[4] ^= 0xC0; /* change from 0x80 to 0x40 */
@@ -349,7 +353,7 @@ static int Ti3026_setpclk(WPMINFO int clk) {
349 } 353 }
350 } 354 }
351 hw->DACclk[5] = looppost | 0xF8; 355 hw->DACclk[5] = looppost | 0xF8;
352 if (ACCESS_FBINFO(devflags.mga_24bpp_fix)) 356 if (minfo->devflags.mga_24bpp_fix)
353 hw->DACclk[5] ^= 0x40; 357 hw->DACclk[5] ^= 0x40;
354 } else { 358 } else {
355 hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0; 359 hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
@@ -361,14 +365,15 @@ static int Ti3026_setpclk(WPMINFO int clk) {
361 return 0; 365 return 0;
362} 366}
363 367
364static int Ti3026_init(WPMINFO struct my_timming* m) { 368static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m)
365 u_int8_t muxctrl = isInterleave(MINFO) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT; 369{
366 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 370 u_int8_t muxctrl = isInterleave(minfo) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT;
371 struct matrox_hw_state *hw = &minfo->hw;
367 372
368 DBG(__func__) 373 DBG(__func__)
369 374
370 memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg)); 375 memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg));
371 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { 376 switch (minfo->fbcon.var.bits_per_pixel) {
372 case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1; /* or _8_1, they are same */ 377 case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1; /* or _8_1, they are same */
373 hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR; 378 hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
374 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT; 379 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT;
@@ -383,7 +388,7 @@ static int Ti3026_init(WPMINFO struct my_timming* m) {
383 break; 388 break;
384 case 16: 389 case 16:
385 /* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */ 390 /* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */
386 hw->DACreg[POS3026_XTRUECOLORCTRL] = (ACCESS_FBINFO(fbcon).var.green.length == 5)? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555 ) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565); 391 hw->DACreg[POS3026_XTRUECOLORCTRL] = (minfo->fbcon.var.green.length == 5) ? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565);
387 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT; 392 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT;
388 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2; 393 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2;
389 break; 394 break;
@@ -400,7 +405,7 @@ static int Ti3026_init(WPMINFO struct my_timming* m) {
400 default: 405 default:
401 return 1; /* TODO: failed */ 406 return 1; /* TODO: failed */
402 } 407 }
403 if (matroxfb_vgaHWinit(PMINFO m)) return 1; 408 if (matroxfb_vgaHWinit(minfo, m)) return 1;
404 409
405 /* set SYNC */ 410 /* set SYNC */
406 hw->MiscOutReg = 0xCB; 411 hw->MiscOutReg = 0xCB;
@@ -412,9 +417,9 @@ static int Ti3026_init(WPMINFO struct my_timming* m) {
412 hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_SYNC_ON_GREEN; 417 hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_SYNC_ON_GREEN;
413 418
414 /* set DELAY */ 419 /* set DELAY */
415 if (ACCESS_FBINFO(video.len) < 0x400000) 420 if (minfo->video.len < 0x400000)
416 hw->CRTCEXT[3] |= 0x08; 421 hw->CRTCEXT[3] |= 0x08;
417 else if (ACCESS_FBINFO(video.len) > 0x400000) 422 else if (minfo->video.len > 0x400000)
418 hw->CRTCEXT[3] |= 0x10; 423 hw->CRTCEXT[3] |= 0x10;
419 424
420 /* set HWCURSOR */ 425 /* set HWCURSOR */
@@ -426,14 +431,15 @@ static int Ti3026_init(WPMINFO struct my_timming* m) {
426 431
427 /* set interleaving */ 432 /* set interleaving */
428 hw->MXoptionReg &= ~0x00001000; 433 hw->MXoptionReg &= ~0x00001000;
429 if (isInterleave(MINFO)) hw->MXoptionReg |= 0x00001000; 434 if (isInterleave(minfo)) hw->MXoptionReg |= 0x00001000;
430 435
431 /* set DAC */ 436 /* set DAC */
432 Ti3026_setpclk(PMINFO m->pixclock); 437 Ti3026_setpclk(minfo, m->pixclock);
433 return 0; 438 return 0;
434} 439}
435 440
436static void ti3026_setMCLK(WPMINFO int fout){ 441static void ti3026_setMCLK(struct matrox_fb_info *minfo, int fout)
442{
437 unsigned int f_pll; 443 unsigned int f_pll;
438 unsigned int pclk_m, pclk_n, pclk_p; 444 unsigned int pclk_m, pclk_n, pclk_p;
439 unsigned int mclk_m, mclk_n, mclk_p; 445 unsigned int mclk_m, mclk_n, mclk_p;
@@ -442,29 +448,29 @@ static void ti3026_setMCLK(WPMINFO int fout){
442 448
443 DBG(__func__) 449 DBG(__func__)
444 450
445 f_pll = Ti3026_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &mclk_n, &mclk_m, &mclk_p); 451 f_pll = Ti3026_calcclock(minfo, fout, minfo->max_pixel_clock, &mclk_n, &mclk_m, &mclk_p);
446 452
447 /* save pclk */ 453 /* save pclk */
448 outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC); 454 outTi3026(minfo, TVP3026_XPLLADDR, 0xFC);
449 pclk_n = inTi3026(PMINFO TVP3026_XPIXPLLDATA); 455 pclk_n = inTi3026(minfo, TVP3026_XPIXPLLDATA);
450 outTi3026(PMINFO TVP3026_XPLLADDR, 0xFD); 456 outTi3026(minfo, TVP3026_XPLLADDR, 0xFD);
451 pclk_m = inTi3026(PMINFO TVP3026_XPIXPLLDATA); 457 pclk_m = inTi3026(minfo, TVP3026_XPIXPLLDATA);
452 outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE); 458 outTi3026(minfo, TVP3026_XPLLADDR, 0xFE);
453 pclk_p = inTi3026(PMINFO TVP3026_XPIXPLLDATA); 459 pclk_p = inTi3026(minfo, TVP3026_XPIXPLLDATA);
454 460
455 /* stop pclk */ 461 /* stop pclk */
456 outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE); 462 outTi3026(minfo, TVP3026_XPLLADDR, 0xFE);
457 outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00); 463 outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00);
458 464
459 /* set pclk to new mclk */ 465 /* set pclk to new mclk */
460 outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC); 466 outTi3026(minfo, TVP3026_XPLLADDR, 0xFC);
461 outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_n | 0xC0); 467 outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_n | 0xC0);
462 outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_m); 468 outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_m);
463 outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_p | 0xB0); 469 outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_p | 0xB0);
464 470
465 /* wait for PLL to lock */ 471 /* wait for PLL to lock */
466 for (tmout = 500000; tmout; tmout--) { 472 for (tmout = 500000; tmout; tmout--) {
467 if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40) 473 if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40)
468 break; 474 break;
469 udelay(10); 475 udelay(10);
470 }; 476 };
@@ -472,23 +478,23 @@ static void ti3026_setMCLK(WPMINFO int fout){
472 printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n"); 478 printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n");
473 479
474 /* output pclk on mclk pin */ 480 /* output pclk on mclk pin */
475 mclk_ctl = inTi3026(PMINFO TVP3026_XMEMPLLCTRL); 481 mclk_ctl = inTi3026(minfo, TVP3026_XMEMPLLCTRL);
476 outTi3026(PMINFO TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7); 482 outTi3026(minfo, TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7);
477 outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4); 483 outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4);
478 484
479 /* stop MCLK */ 485 /* stop MCLK */
480 outTi3026(PMINFO TVP3026_XPLLADDR, 0xFB); 486 outTi3026(minfo, TVP3026_XPLLADDR, 0xFB);
481 outTi3026(PMINFO TVP3026_XMEMPLLDATA, 0x00); 487 outTi3026(minfo, TVP3026_XMEMPLLDATA, 0x00);
482 488
483 /* set mclk to new freq */ 489 /* set mclk to new freq */
484 outTi3026(PMINFO TVP3026_XPLLADDR, 0xF3); 490 outTi3026(minfo, TVP3026_XPLLADDR, 0xF3);
485 outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_n | 0xC0); 491 outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_n | 0xC0);
486 outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_m); 492 outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_m);
487 outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_p | 0xB0); 493 outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_p | 0xB0);
488 494
489 /* wait for PLL to lock */ 495 /* wait for PLL to lock */
490 for (tmout = 500000; tmout; tmout--) { 496 for (tmout = 500000; tmout; tmout--) {
491 if (inTi3026(PMINFO TVP3026_XMEMPLLDATA) & 0x40) 497 if (inTi3026(minfo, TVP3026_XMEMPLLDATA) & 0x40)
492 break; 498 break;
493 udelay(10); 499 udelay(10);
494 } 500 }
@@ -496,7 +502,7 @@ static void ti3026_setMCLK(WPMINFO int fout){
496 printk(KERN_ERR "matroxfb: Memory PLL not locked after 5 secs\n"); 502 printk(KERN_ERR "matroxfb: Memory PLL not locked after 5 secs\n");
497 503
498 f_pll = f_pll * 333 / (10000 << mclk_p); 504 f_pll = f_pll * 333 / (10000 << mclk_p);
499 if (isMilleniumII(MINFO)) { 505 if (isMilleniumII(minfo)) {
500 rfhcnt = (f_pll - 128) / 256; 506 rfhcnt = (f_pll - 128) / 256;
501 if (rfhcnt > 15) 507 if (rfhcnt > 15)
502 rfhcnt = 15; 508 rfhcnt = 15;
@@ -505,26 +511,26 @@ static void ti3026_setMCLK(WPMINFO int fout){
505 if (rfhcnt > 15) 511 if (rfhcnt > 15)
506 rfhcnt = 0; 512 rfhcnt = 0;
507 } 513 }
508 ACCESS_FBINFO(hw).MXoptionReg = (ACCESS_FBINFO(hw).MXoptionReg & ~0x000F0000) | (rfhcnt << 16); 514 minfo->hw.MXoptionReg = (minfo->hw.MXoptionReg & ~0x000F0000) | (rfhcnt << 16);
509 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); 515 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
510 516
511 /* output MCLK to MCLK pin */ 517 /* output MCLK to MCLK pin */
512 outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL); 518 outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
513 outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4); 519 outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4);
514 520
515 /* stop PCLK */ 521 /* stop PCLK */
516 outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE); 522 outTi3026(minfo, TVP3026_XPLLADDR, 0xFE);
517 outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00); 523 outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00);
518 524
519 /* restore pclk */ 525 /* restore pclk */
520 outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC); 526 outTi3026(minfo, TVP3026_XPLLADDR, 0xFC);
521 outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_n); 527 outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_n);
522 outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_m); 528 outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_m);
523 outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_p); 529 outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_p);
524 530
525 /* wait for PLL to lock */ 531 /* wait for PLL to lock */
526 for (tmout = 500000; tmout; tmout--) { 532 for (tmout = 500000; tmout; tmout--) {
527 if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40) 533 if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40)
528 break; 534 break;
529 udelay(10); 535 udelay(10);
530 } 536 }
@@ -532,26 +538,27 @@ static void ti3026_setMCLK(WPMINFO int fout){
532 printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n"); 538 printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
533} 539}
534 540
535static void ti3026_ramdac_init(WPMINFO2) { 541static void ti3026_ramdac_init(struct matrox_fb_info *minfo)
536 542{
537 DBG(__func__) 543 DBG(__func__)
538 544
539 ACCESS_FBINFO(features.pll.vco_freq_min) = 110000; 545 minfo->features.pll.vco_freq_min = 110000;
540 ACCESS_FBINFO(features.pll.ref_freq) = 114545; 546 minfo->features.pll.ref_freq = 114545;
541 ACCESS_FBINFO(features.pll.feed_div_min) = 2; 547 minfo->features.pll.feed_div_min = 2;
542 ACCESS_FBINFO(features.pll.feed_div_max) = 24; 548 minfo->features.pll.feed_div_max = 24;
543 ACCESS_FBINFO(features.pll.in_div_min) = 2; 549 minfo->features.pll.in_div_min = 2;
544 ACCESS_FBINFO(features.pll.in_div_max) = 63; 550 minfo->features.pll.in_div_max = 63;
545 ACCESS_FBINFO(features.pll.post_shift_max) = 3; 551 minfo->features.pll.post_shift_max = 3;
546 if (ACCESS_FBINFO(devflags.noinit)) 552 if (minfo->devflags.noinit)
547 return; 553 return;
548 ti3026_setMCLK(PMINFO 60000); 554 ti3026_setMCLK(minfo, 60000);
549} 555}
550 556
551static void Ti3026_restore(WPMINFO2) { 557static void Ti3026_restore(struct matrox_fb_info *minfo)
558{
552 int i; 559 int i;
553 unsigned char progdac[6]; 560 unsigned char progdac[6];
554 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 561 struct matrox_hw_state *hw = &minfo->hw;
555 CRITFLAGS 562 CRITFLAGS
556 563
557 DBG(__func__) 564 DBG(__func__)
@@ -565,31 +572,31 @@ static void Ti3026_restore(WPMINFO2) {
565 572
566 CRITBEGIN 573 CRITBEGIN
567 574
568 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 575 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
569 576
570 CRITEND 577 CRITEND
571 578
572 matroxfb_vgaHWrestore(PMINFO2); 579 matroxfb_vgaHWrestore(minfo);
573 580
574 CRITBEGIN 581 CRITBEGIN
575 582
576 ACCESS_FBINFO(crtc1.panpos) = -1; 583 minfo->crtc1.panpos = -1;
577 for (i = 0; i < 6; i++) 584 for (i = 0; i < 6; i++)
578 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); 585 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
579 586
580 for (i = 0; i < 21; i++) { 587 for (i = 0; i < 21; i++) {
581 outTi3026(PMINFO DACseq[i], hw->DACreg[i]); 588 outTi3026(minfo, DACseq[i], hw->DACreg[i]);
582 } 589 }
583 590
584 outTi3026(PMINFO TVP3026_XPLLADDR, 0x00); 591 outTi3026(minfo, TVP3026_XPLLADDR, 0x00);
585 progdac[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA); 592 progdac[0] = inTi3026(minfo, TVP3026_XPIXPLLDATA);
586 progdac[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA); 593 progdac[3] = inTi3026(minfo, TVP3026_XLOOPPLLDATA);
587 outTi3026(PMINFO TVP3026_XPLLADDR, 0x15); 594 outTi3026(minfo, TVP3026_XPLLADDR, 0x15);
588 progdac[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA); 595 progdac[1] = inTi3026(minfo, TVP3026_XPIXPLLDATA);
589 progdac[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA); 596 progdac[4] = inTi3026(minfo, TVP3026_XLOOPPLLDATA);
590 outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A); 597 outTi3026(minfo, TVP3026_XPLLADDR, 0x2A);
591 progdac[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA); 598 progdac[2] = inTi3026(minfo, TVP3026_XPIXPLLDATA);
592 progdac[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA); 599 progdac[5] = inTi3026(minfo, TVP3026_XLOOPPLLDATA);
593 600
594 CRITEND 601 CRITEND
595 if (memcmp(hw->DACclk, progdac, 6)) { 602 if (memcmp(hw->DACclk, progdac, 6)) {
@@ -598,20 +605,20 @@ static void Ti3026_restore(WPMINFO2) {
598 /* Maybe even we should call schedule() ? */ 605 /* Maybe even we should call schedule() ? */
599 606
600 CRITBEGIN 607 CRITBEGIN
601 outTi3026(PMINFO TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]); 608 outTi3026(minfo, TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]);
602 outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A); 609 outTi3026(minfo, TVP3026_XPLLADDR, 0x2A);
603 outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0); 610 outTi3026(minfo, TVP3026_XLOOPPLLDATA, 0);
604 outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0); 611 outTi3026(minfo, TVP3026_XPIXPLLDATA, 0);
605 612
606 outTi3026(PMINFO TVP3026_XPLLADDR, 0x00); 613 outTi3026(minfo, TVP3026_XPLLADDR, 0x00);
607 for (i = 0; i < 3; i++) 614 for (i = 0; i < 3; i++)
608 outTi3026(PMINFO TVP3026_XPIXPLLDATA, hw->DACclk[i]); 615 outTi3026(minfo, TVP3026_XPIXPLLDATA, hw->DACclk[i]);
609 /* wait for PLL only if PLL clock requested (always for PowerMode, never for VGA) */ 616 /* wait for PLL only if PLL clock requested (always for PowerMode, never for VGA) */
610 if (hw->MiscOutReg & 0x08) { 617 if (hw->MiscOutReg & 0x08) {
611 int tmout; 618 int tmout;
612 outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F); 619 outTi3026(minfo, TVP3026_XPLLADDR, 0x3F);
613 for (tmout = 500000; tmout; --tmout) { 620 for (tmout = 500000; tmout; --tmout) {
614 if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40) 621 if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40)
615 break; 622 break;
616 udelay(10); 623 udelay(10);
617 } 624 }
@@ -624,18 +631,18 @@ static void Ti3026_restore(WPMINFO2) {
624 dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout); 631 dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout);
625 CRITBEGIN 632 CRITBEGIN
626 } 633 }
627 outTi3026(PMINFO TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]); 634 outTi3026(minfo, TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]);
628 outTi3026(PMINFO TVP3026_XPLLADDR, 0x00); 635 outTi3026(minfo, TVP3026_XPLLADDR, 0x00);
629 for (i = 3; i < 6; i++) 636 for (i = 3; i < 6; i++)
630 outTi3026(PMINFO TVP3026_XLOOPPLLDATA, hw->DACclk[i]); 637 outTi3026(minfo, TVP3026_XLOOPPLLDATA, hw->DACclk[i]);
631 CRITEND 638 CRITEND
632 if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) { 639 if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) {
633 int tmout; 640 int tmout;
634 641
635 CRITBEGIN 642 CRITBEGIN
636 outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F); 643 outTi3026(minfo, TVP3026_XPLLADDR, 0x3F);
637 for (tmout = 500000; tmout; --tmout) { 644 for (tmout = 500000; tmout; --tmout) {
638 if (inTi3026(PMINFO TVP3026_XLOOPPLLDATA) & 0x40) 645 if (inTi3026(minfo, TVP3026_XLOOPPLLDATA) & 0x40)
639 break; 646 break;
640 udelay(10); 647 udelay(10);
641 } 648 }
@@ -660,65 +667,66 @@ static void Ti3026_restore(WPMINFO2) {
660#endif 667#endif
661} 668}
662 669
663static void Ti3026_reset(WPMINFO2) { 670static void Ti3026_reset(struct matrox_fb_info *minfo)
664 671{
665 DBG(__func__) 672 DBG(__func__)
666 673
667 ti3026_ramdac_init(PMINFO2); 674 ti3026_ramdac_init(minfo);
668} 675}
669 676
670static struct matrox_altout ti3026_output = { 677static struct matrox_altout ti3026_output = {
671 .name = "Primary output", 678 .name = "Primary output",
672}; 679};
673 680
674static int Ti3026_preinit(WPMINFO2) { 681static int Ti3026_preinit(struct matrox_fb_info *minfo)
682{
675 static const int vxres_mill2[] = { 512, 640, 768, 800, 832, 960, 683 static const int vxres_mill2[] = { 512, 640, 768, 800, 832, 960,
676 1024, 1152, 1280, 1600, 1664, 1920, 684 1024, 1152, 1280, 1600, 1664, 1920,
677 2048, 0}; 685 2048, 0};
678 static const int vxres_mill1[] = { 640, 768, 800, 960, 686 static const int vxres_mill1[] = { 640, 768, 800, 960,
679 1024, 1152, 1280, 1600, 1920, 687 1024, 1152, 1280, 1600, 1920,
680 2048, 0}; 688 2048, 0};
681 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); 689 struct matrox_hw_state *hw = &minfo->hw;
682 690
683 DBG(__func__) 691 DBG(__func__)
684 692
685 ACCESS_FBINFO(millenium) = 1; 693 minfo->millenium = 1;
686 ACCESS_FBINFO(milleniumII) = (ACCESS_FBINFO(pcidev)->device != PCI_DEVICE_ID_MATROX_MIL); 694 minfo->milleniumII = (minfo->pcidev->device != PCI_DEVICE_ID_MATROX_MIL);
687 ACCESS_FBINFO(capable.cfb4) = 1; 695 minfo->capable.cfb4 = 1;
688 ACCESS_FBINFO(capable.text) = 1; /* isMilleniumII(MINFO); */ 696 minfo->capable.text = 1; /* isMilleniumII(minfo); */
689 ACCESS_FBINFO(capable.vxres) = isMilleniumII(MINFO)?vxres_mill2:vxres_mill1; 697 minfo->capable.vxres = isMilleniumII(minfo) ? vxres_mill2 : vxres_mill1;
690 698
691 ACCESS_FBINFO(outputs[0]).data = MINFO; 699 minfo->outputs[0].data = minfo;
692 ACCESS_FBINFO(outputs[0]).output = &ti3026_output; 700 minfo->outputs[0].output = &ti3026_output;
693 ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src; 701 minfo->outputs[0].src = minfo->outputs[0].default_src;
694 ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 702 minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR;
695 703
696 if (ACCESS_FBINFO(devflags.noinit)) 704 if (minfo->devflags.noinit)
697 return 0; 705 return 0;
698 /* preserve VGA I/O, BIOS and PPC */ 706 /* preserve VGA I/O, BIOS and PPC */
699 hw->MXoptionReg &= 0xC0000100; 707 hw->MXoptionReg &= 0xC0000100;
700 hw->MXoptionReg |= 0x002C0000; 708 hw->MXoptionReg |= 0x002C0000;
701 if (ACCESS_FBINFO(devflags.novga)) 709 if (minfo->devflags.novga)
702 hw->MXoptionReg &= ~0x00000100; 710 hw->MXoptionReg &= ~0x00000100;
703 if (ACCESS_FBINFO(devflags.nobios)) 711 if (minfo->devflags.nobios)
704 hw->MXoptionReg &= ~0x40000000; 712 hw->MXoptionReg &= ~0x40000000;
705 if (ACCESS_FBINFO(devflags.nopciretry)) 713 if (minfo->devflags.nopciretry)
706 hw->MXoptionReg |= 0x20000000; 714 hw->MXoptionReg |= 0x20000000;
707 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 715 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
708 716
709 ACCESS_FBINFO(accel.ramdac_rev) = inTi3026(PMINFO TVP3026_XSILICONREV); 717 minfo->accel.ramdac_rev = inTi3026(minfo, TVP3026_XSILICONREV);
710 718
711 outTi3026(PMINFO TVP3026_XCLKCTRL, TVP3026_XCLKCTRL_SRC_CLK0VGA | TVP3026_XCLKCTRL_CLKSTOPPED); 719 outTi3026(minfo, TVP3026_XCLKCTRL, TVP3026_XCLKCTRL_SRC_CLK0VGA | TVP3026_XCLKCTRL_CLKSTOPPED);
712 outTi3026(PMINFO TVP3026_XTRUECOLORCTRL, TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR); 720 outTi3026(minfo, TVP3026_XTRUECOLORCTRL, TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR);
713 outTi3026(PMINFO TVP3026_XMUXCTRL, TVP3026_XMUXCTRL_VGA); 721 outTi3026(minfo, TVP3026_XMUXCTRL, TVP3026_XMUXCTRL_VGA);
714 722
715 outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A); 723 outTi3026(minfo, TVP3026_XPLLADDR, 0x2A);
716 outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0x00); 724 outTi3026(minfo, TVP3026_XLOOPPLLDATA, 0x00);
717 outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00); 725 outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00);
718 726
719 mga_outb(M_MISC_REG, 0x67); 727 mga_outb(M_MISC_REG, 0x67);
720 728
721 outTi3026(PMINFO TVP3026_XMEMPLLCTRL, TVP3026_XMEMPLLCTRL_STROBEMKC4 | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL); 729 outTi3026(minfo, TVP3026_XMEMPLLCTRL, TVP3026_XMEMPLLCTRL_STROBEMKC4 | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
722 730
723 mga_outl(M_RESET, 1); 731 mga_outl(M_RESET, 1);
724 udelay(250); 732 udelay(250);
diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c
index 9c3aeee1cc4f..8335a6fe303e 100644
--- a/drivers/video/matrox/matroxfb_accel.c
+++ b/drivers/video/matrox/matroxfb_accel.c
@@ -81,7 +81,7 @@
81#include "matroxfb_Ti3026.h" 81#include "matroxfb_Ti3026.h"
82#include "matroxfb_misc.h" 82#include "matroxfb_misc.h"
83 83
84#define curr_ydstorg(x) ACCESS_FBINFO2(x, curr.ydstorg.pixels) 84#define curr_ydstorg(x) ((x)->curr.ydstorg.pixels)
85 85
86#define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l)) 86#define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l))
87 87
@@ -107,7 +107,8 @@ static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* imag
107static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect); 107static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect);
108static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area); 108static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area);
109 109
110void matrox_cfbX_init(WPMINFO2) { 110void matrox_cfbX_init(struct matrox_fb_info *minfo)
111{
111 u_int32_t maccess; 112 u_int32_t maccess;
112 u_int32_t mpitch; 113 u_int32_t mpitch;
113 u_int32_t mopmode; 114 u_int32_t mopmode;
@@ -115,59 +116,59 @@ void matrox_cfbX_init(WPMINFO2) {
115 116
116 DBG(__func__) 117 DBG(__func__)
117 118
118 mpitch = ACCESS_FBINFO(fbcon).var.xres_virtual; 119 mpitch = minfo->fbcon.var.xres_virtual;
119 120
120 ACCESS_FBINFO(fbops).fb_copyarea = cfb_copyarea; 121 minfo->fbops.fb_copyarea = cfb_copyarea;
121 ACCESS_FBINFO(fbops).fb_fillrect = cfb_fillrect; 122 minfo->fbops.fb_fillrect = cfb_fillrect;
122 ACCESS_FBINFO(fbops).fb_imageblit = cfb_imageblit; 123 minfo->fbops.fb_imageblit = cfb_imageblit;
123 ACCESS_FBINFO(fbops).fb_cursor = NULL; 124 minfo->fbops.fb_cursor = NULL;
124 125
125 accel = (ACCESS_FBINFO(fbcon).var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT; 126 accel = (minfo->fbcon.var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT;
126 127
127 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { 128 switch (minfo->fbcon.var.bits_per_pixel) {
128 case 4: maccess = 0x00000000; /* accelerate as 8bpp video */ 129 case 4: maccess = 0x00000000; /* accelerate as 8bpp video */
129 mpitch = (mpitch >> 1) | 0x8000; /* disable linearization */ 130 mpitch = (mpitch >> 1) | 0x8000; /* disable linearization */
130 mopmode = M_OPMODE_4BPP; 131 mopmode = M_OPMODE_4BPP;
131 matrox_cfb4_pal(ACCESS_FBINFO(cmap)); 132 matrox_cfb4_pal(minfo->cmap);
132 if (accel && !(mpitch & 1)) { 133 if (accel && !(mpitch & 1)) {
133 ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_cfb4_copyarea; 134 minfo->fbops.fb_copyarea = matroxfb_cfb4_copyarea;
134 ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_cfb4_fillrect; 135 minfo->fbops.fb_fillrect = matroxfb_cfb4_fillrect;
135 } 136 }
136 break; 137 break;
137 case 8: maccess = 0x00000000; 138 case 8: maccess = 0x00000000;
138 mopmode = M_OPMODE_8BPP; 139 mopmode = M_OPMODE_8BPP;
139 matrox_cfb8_pal(ACCESS_FBINFO(cmap)); 140 matrox_cfb8_pal(minfo->cmap);
140 if (accel) { 141 if (accel) {
141 ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_copyarea; 142 minfo->fbops.fb_copyarea = matroxfb_copyarea;
142 ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_fillrect; 143 minfo->fbops.fb_fillrect = matroxfb_fillrect;
143 ACCESS_FBINFO(fbops).fb_imageblit = matroxfb_imageblit; 144 minfo->fbops.fb_imageblit = matroxfb_imageblit;
144 } 145 }
145 break; 146 break;
146 case 16: if (ACCESS_FBINFO(fbcon).var.green.length == 5) 147 case 16: if (minfo->fbcon.var.green.length == 5)
147 maccess = 0xC0000001; 148 maccess = 0xC0000001;
148 else 149 else
149 maccess = 0x40000001; 150 maccess = 0x40000001;
150 mopmode = M_OPMODE_16BPP; 151 mopmode = M_OPMODE_16BPP;
151 if (accel) { 152 if (accel) {
152 ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_copyarea; 153 minfo->fbops.fb_copyarea = matroxfb_copyarea;
153 ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_fillrect; 154 minfo->fbops.fb_fillrect = matroxfb_fillrect;
154 ACCESS_FBINFO(fbops).fb_imageblit = matroxfb_imageblit; 155 minfo->fbops.fb_imageblit = matroxfb_imageblit;
155 } 156 }
156 break; 157 break;
157 case 24: maccess = 0x00000003; 158 case 24: maccess = 0x00000003;
158 mopmode = M_OPMODE_24BPP; 159 mopmode = M_OPMODE_24BPP;
159 if (accel) { 160 if (accel) {
160 ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_copyarea; 161 minfo->fbops.fb_copyarea = matroxfb_copyarea;
161 ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_fillrect; 162 minfo->fbops.fb_fillrect = matroxfb_fillrect;
162 ACCESS_FBINFO(fbops).fb_imageblit = matroxfb_imageblit; 163 minfo->fbops.fb_imageblit = matroxfb_imageblit;
163 } 164 }
164 break; 165 break;
165 case 32: maccess = 0x00000002; 166 case 32: maccess = 0x00000002;
166 mopmode = M_OPMODE_32BPP; 167 mopmode = M_OPMODE_32BPP;
167 if (accel) { 168 if (accel) {
168 ACCESS_FBINFO(fbops).fb_copyarea = matroxfb_copyarea; 169 minfo->fbops.fb_copyarea = matroxfb_copyarea;
169 ACCESS_FBINFO(fbops).fb_fillrect = matroxfb_fillrect; 170 minfo->fbops.fb_fillrect = matroxfb_fillrect;
170 ACCESS_FBINFO(fbops).fb_imageblit = matroxfb_imageblit; 171 minfo->fbops.fb_imageblit = matroxfb_imageblit;
171 } 172 }
172 break; 173 break;
173 default: maccess = 0x00000000; 174 default: maccess = 0x00000000;
@@ -176,10 +177,10 @@ void matrox_cfbX_init(WPMINFO2) {
176 } 177 }
177 mga_fifo(8); 178 mga_fifo(8);
178 mga_outl(M_PITCH, mpitch); 179 mga_outl(M_PITCH, mpitch);
179 mga_outl(M_YDSTORG, curr_ydstorg(MINFO)); 180 mga_outl(M_YDSTORG, curr_ydstorg(minfo));
180 if (ACCESS_FBINFO(capable.plnwt)) 181 if (minfo->capable.plnwt)
181 mga_outl(M_PLNWT, -1); 182 mga_outl(M_PLNWT, -1);
182 if (ACCESS_FBINFO(capable.srcorg)) { 183 if (minfo->capable.srcorg) {
183 mga_outl(M_SRCORG, 0); 184 mga_outl(M_SRCORG, 0);
184 mga_outl(M_DSTORG, 0); 185 mga_outl(M_DSTORG, 0);
185 } 186 }
@@ -188,14 +189,16 @@ void matrox_cfbX_init(WPMINFO2) {
188 mga_outl(M_YTOP, 0); 189 mga_outl(M_YTOP, 0);
189 mga_outl(M_YBOT, 0x01FFFFFF); 190 mga_outl(M_YBOT, 0x01FFFFFF);
190 mga_outl(M_MACCESS, maccess); 191 mga_outl(M_MACCESS, maccess);
191 ACCESS_FBINFO(accel.m_dwg_rect) = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO; 192 minfo->accel.m_dwg_rect = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;
192 if (isMilleniumII(MINFO)) ACCESS_FBINFO(accel.m_dwg_rect) |= M_DWG_TRANSC; 193 if (isMilleniumII(minfo)) minfo->accel.m_dwg_rect |= M_DWG_TRANSC;
193 ACCESS_FBINFO(accel.m_opmode) = mopmode; 194 minfo->accel.m_opmode = mopmode;
194} 195}
195 196
196EXPORT_SYMBOL(matrox_cfbX_init); 197EXPORT_SYMBOL(matrox_cfbX_init);
197 198
198static void matrox_accel_bmove(WPMINFO int vxres, int sy, int sx, int dy, int dx, int height, int width) { 199static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
200 int sx, int dy, int dx, int height, int width)
201{
199 int start, end; 202 int start, end;
200 CRITFLAGS 203 CRITFLAGS
201 204
@@ -209,7 +212,7 @@ static void matrox_accel_bmove(WPMINFO int vxres, int sy, int sx, int dy, int dx
209 M_DWG_BFCOL | M_DWG_REPLACE); 212 M_DWG_BFCOL | M_DWG_REPLACE);
210 mga_outl(M_AR5, vxres); 213 mga_outl(M_AR5, vxres);
211 width--; 214 width--;
212 start = sy*vxres+sx+curr_ydstorg(MINFO); 215 start = sy*vxres+sx+curr_ydstorg(minfo);
213 end = start+width; 216 end = start+width;
214 } else { 217 } else {
215 mga_fifo(3); 218 mga_fifo(3);
@@ -217,7 +220,7 @@ static void matrox_accel_bmove(WPMINFO int vxres, int sy, int sx, int dy, int dx
217 mga_outl(M_SGN, 5); 220 mga_outl(M_SGN, 5);
218 mga_outl(M_AR5, -vxres); 221 mga_outl(M_AR5, -vxres);
219 width--; 222 width--;
220 end = (sy+height-1)*vxres+sx+curr_ydstorg(MINFO); 223 end = (sy+height-1)*vxres+sx+curr_ydstorg(minfo);
221 start = end+width; 224 start = end+width;
222 dy += height-1; 225 dy += height-1;
223 } 226 }
@@ -231,7 +234,10 @@ static void matrox_accel_bmove(WPMINFO int vxres, int sy, int sx, int dy, int dx
231 CRITEND 234 CRITEND
232} 235}
233 236
234static void matrox_accel_bmove_lin(WPMINFO int vxres, int sy, int sx, int dy, int dx, int height, int width) { 237static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,
238 int sy, int sx, int dy, int dx, int height,
239 int width)
240{
235 int start, end; 241 int start, end;
236 CRITFLAGS 242 CRITFLAGS
237 243
@@ -245,7 +251,7 @@ static void matrox_accel_bmove_lin(WPMINFO int vxres, int sy, int sx, int dy, in
245 M_DWG_BFCOL | M_DWG_REPLACE); 251 M_DWG_BFCOL | M_DWG_REPLACE);
246 mga_outl(M_AR5, vxres); 252 mga_outl(M_AR5, vxres);
247 width--; 253 width--;
248 start = sy*vxres+sx+curr_ydstorg(MINFO); 254 start = sy*vxres+sx+curr_ydstorg(minfo);
249 end = start+width; 255 end = start+width;
250 } else { 256 } else {
251 mga_fifo(3); 257 mga_fifo(3);
@@ -253,7 +259,7 @@ static void matrox_accel_bmove_lin(WPMINFO int vxres, int sy, int sx, int dy, in
253 mga_outl(M_SGN, 5); 259 mga_outl(M_SGN, 5);
254 mga_outl(M_AR5, -vxres); 260 mga_outl(M_AR5, -vxres);
255 width--; 261 width--;
256 end = (sy+height-1)*vxres+sx+curr_ydstorg(MINFO); 262 end = (sy+height-1)*vxres+sx+curr_ydstorg(minfo);
257 start = end+width; 263 start = end+width;
258 dy += height-1; 264 dy += height-1;
259 } 265 }
@@ -269,22 +275,23 @@ static void matrox_accel_bmove_lin(WPMINFO int vxres, int sy, int sx, int dy, in
269} 275}
270 276
271static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area) { 277static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area) {
272 MINFO_FROM_INFO(info); 278 struct matrox_fb_info *minfo = info2minfo(info);
273 279
274 if ((area->sx | area->dx | area->width) & 1) 280 if ((area->sx | area->dx | area->width) & 1)
275 cfb_copyarea(info, area); 281 cfb_copyarea(info, area);
276 else 282 else
277 matrox_accel_bmove_lin(PMINFO ACCESS_FBINFO(fbcon.var.xres_virtual) >> 1, area->sy, area->sx >> 1, area->dy, area->dx >> 1, area->height, area->width >> 1); 283 matrox_accel_bmove_lin(minfo, minfo->fbcon.var.xres_virtual >> 1, area->sy, area->sx >> 1, area->dy, area->dx >> 1, area->height, area->width >> 1);
278} 284}
279 285
280static void matroxfb_copyarea(struct fb_info* info, const struct fb_copyarea* area) { 286static void matroxfb_copyarea(struct fb_info* info, const struct fb_copyarea* area) {
281 MINFO_FROM_INFO(info); 287 struct matrox_fb_info *minfo = info2minfo(info);
282 288
283 matrox_accel_bmove(PMINFO ACCESS_FBINFO(fbcon.var.xres_virtual), area->sy, area->sx, area->dy, area->dx, area->height, area->width); 289 matrox_accel_bmove(minfo, minfo->fbcon.var.xres_virtual, area->sy, area->sx, area->dy, area->dx, area->height, area->width);
284} 290}
285 291
286static void matroxfb_accel_clear(WPMINFO u_int32_t color, int sy, int sx, int height, 292static void matroxfb_accel_clear(struct matrox_fb_info *minfo, u_int32_t color,
287 int width) { 293 int sy, int sx, int height, int width)
294{
288 CRITFLAGS 295 CRITFLAGS
289 296
290 DBG(__func__) 297 DBG(__func__)
@@ -292,7 +299,7 @@ static void matroxfb_accel_clear(WPMINFO u_int32_t color, int sy, int sx, int he
292 CRITBEGIN 299 CRITBEGIN
293 300
294 mga_fifo(5); 301 mga_fifo(5);
295 mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE); 302 mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE);
296 mga_outl(M_FCOL, color); 303 mga_outl(M_FCOL, color);
297 mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx); 304 mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
298 mga_ydstlen(sy, height); 305 mga_ydstlen(sy, height);
@@ -302,16 +309,18 @@ static void matroxfb_accel_clear(WPMINFO u_int32_t color, int sy, int sx, int he
302} 309}
303 310
304static void matroxfb_fillrect(struct fb_info* info, const struct fb_fillrect* rect) { 311static void matroxfb_fillrect(struct fb_info* info, const struct fb_fillrect* rect) {
305 MINFO_FROM_INFO(info); 312 struct matrox_fb_info *minfo = info2minfo(info);
306 313
307 switch (rect->rop) { 314 switch (rect->rop) {
308 case ROP_COPY: 315 case ROP_COPY:
309 matroxfb_accel_clear(PMINFO ((u_int32_t*)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width); 316 matroxfb_accel_clear(minfo, ((u_int32_t *)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width);
310 break; 317 break;
311 } 318 }
312} 319}
313 320
314static void matroxfb_cfb4_clear(WPMINFO u_int32_t bgx, int sy, int sx, int height, int width) { 321static void matroxfb_cfb4_clear(struct matrox_fb_info *minfo, u_int32_t bgx,
322 int sy, int sx, int height, int width)
323{
315 int whattodo; 324 int whattodo;
316 CRITFLAGS 325 CRITFLAGS
317 326
@@ -333,16 +342,16 @@ static void matroxfb_cfb4_clear(WPMINFO u_int32_t bgx, int sy, int sx, int heigh
333 sx >>= 1; 342 sx >>= 1;
334 if (width) { 343 if (width) {
335 mga_fifo(5); 344 mga_fifo(5);
336 mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE2); 345 mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE2);
337 mga_outl(M_FCOL, bgx); 346 mga_outl(M_FCOL, bgx);
338 mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx); 347 mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
339 mga_outl(M_YDST, sy * ACCESS_FBINFO(fbcon).var.xres_virtual >> 6); 348 mga_outl(M_YDST, sy * minfo->fbcon.var.xres_virtual >> 6);
340 mga_outl(M_LEN | M_EXEC, height); 349 mga_outl(M_LEN | M_EXEC, height);
341 WaitTillIdle(); 350 WaitTillIdle();
342 } 351 }
343 if (whattodo) { 352 if (whattodo) {
344 u_int32_t step = ACCESS_FBINFO(fbcon).var.xres_virtual >> 1; 353 u_int32_t step = minfo->fbcon.var.xres_virtual >> 1;
345 vaddr_t vbase = ACCESS_FBINFO(video.vbase); 354 vaddr_t vbase = minfo->video.vbase;
346 if (whattodo & 1) { 355 if (whattodo & 1) {
347 unsigned int uaddr = sy * step + sx - 1; 356 unsigned int uaddr = sy * step + sx - 1;
348 u_int32_t loop; 357 u_int32_t loop;
@@ -367,17 +376,19 @@ static void matroxfb_cfb4_clear(WPMINFO u_int32_t bgx, int sy, int sx, int heigh
367} 376}
368 377
369static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect) { 378static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect) {
370 MINFO_FROM_INFO(info); 379 struct matrox_fb_info *minfo = info2minfo(info);
371 380
372 switch (rect->rop) { 381 switch (rect->rop) {
373 case ROP_COPY: 382 case ROP_COPY:
374 matroxfb_cfb4_clear(PMINFO ((u_int32_t*)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width); 383 matroxfb_cfb4_clear(minfo, ((u_int32_t *)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width);
375 break; 384 break;
376 } 385 }
377} 386}
378 387
379static void matroxfb_1bpp_imageblit(WPMINFO u_int32_t fgx, u_int32_t bgx, 388static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx,
380 const u_int8_t* chardata, int width, int height, int yy, int xx) { 389 u_int32_t bgx, const u_int8_t *chardata,
390 int width, int height, int yy, int xx)
391{
381 u_int32_t step; 392 u_int32_t step;
382 u_int32_t ydstlen; 393 u_int32_t ydstlen;
383 u_int32_t xlen; 394 u_int32_t xlen;
@@ -412,7 +423,7 @@ static void matroxfb_1bpp_imageblit(WPMINFO u_int32_t fgx, u_int32_t bgx,
412 mga_outl(M_FCOL, fgx); 423 mga_outl(M_FCOL, fgx);
413 mga_outl(M_BCOL, bgx); 424 mga_outl(M_BCOL, bgx);
414 fxbndry = ((xx + width - 1) << 16) | xx; 425 fxbndry = ((xx + width - 1) << 16) | xx;
415 mmio = ACCESS_FBINFO(mmio.vbase); 426 mmio = minfo->mmio.vbase;
416 427
417 mga_fifo(6); 428 mga_fifo(6);
418 mga_writel(mmio, M_FXBNDRY, fxbndry); 429 mga_writel(mmio, M_FXBNDRY, fxbndry);
@@ -467,7 +478,7 @@ static void matroxfb_1bpp_imageblit(WPMINFO u_int32_t fgx, u_int32_t bgx,
467 478
468 479
469static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* image) { 480static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* image) {
470 MINFO_FROM_INFO(info); 481 struct matrox_fb_info *minfo = info2minfo(info);
471 482
472 DBG_HEAVY(__func__); 483 DBG_HEAVY(__func__);
473 484
@@ -476,7 +487,7 @@ static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* imag
476 487
477 fgx = ((u_int32_t*)info->pseudo_palette)[image->fg_color]; 488 fgx = ((u_int32_t*)info->pseudo_palette)[image->fg_color];
478 bgx = ((u_int32_t*)info->pseudo_palette)[image->bg_color]; 489 bgx = ((u_int32_t*)info->pseudo_palette)[image->bg_color];
479 matroxfb_1bpp_imageblit(PMINFO fgx, bgx, image->data, image->width, image->height, image->dy, image->dx); 490 matroxfb_1bpp_imageblit(minfo, fgx, bgx, image->data, image->width, image->height, image->dy, image->dx);
480 } else { 491 } else {
481 /* Danger! image->depth is useless: logo painting code always 492 /* Danger! image->depth is useless: logo painting code always
482 passes framebuffer color depth here, although logo data are 493 passes framebuffer color depth here, although logo data are
diff --git a/drivers/video/matrox/matroxfb_accel.h b/drivers/video/matrox/matroxfb_accel.h
index f40c314b4c30..1e418e62c22d 100644
--- a/drivers/video/matrox/matroxfb_accel.h
+++ b/drivers/video/matrox/matroxfb_accel.h
@@ -3,6 +3,6 @@
3 3
4#include "matroxfb_base.h" 4#include "matroxfb_base.h"
5 5
6void matrox_cfbX_init(WPMINFO2); 6void matrox_cfbX_init(struct matrox_fb_info *minfo);
7 7
8#endif 8#endif
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 0c1049b308bf..7064fb4427b6 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -154,21 +154,22 @@ static struct fb_var_screeninfo vesafb_defined = {
154 154
155 155
156/* --------------------------------------------------------------------- */ 156/* --------------------------------------------------------------------- */
157static void update_crtc2(WPMINFO unsigned int pos) { 157static void update_crtc2(struct matrox_fb_info *minfo, unsigned int pos)
158 struct matroxfb_dh_fb_info* info = ACCESS_FBINFO(crtc2.info); 158{
159 struct matroxfb_dh_fb_info *info = minfo->crtc2.info;
159 160
160 /* Make sure that displays are compatible */ 161 /* Make sure that displays are compatible */
161 if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel) 162 if (info && (info->fbcon.var.bits_per_pixel == minfo->fbcon.var.bits_per_pixel)
162 && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual) 163 && (info->fbcon.var.xres_virtual == minfo->fbcon.var.xres_virtual)
163 && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length) 164 && (info->fbcon.var.green.length == minfo->fbcon.var.green.length)
164 ) { 165 ) {
165 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { 166 switch (minfo->fbcon.var.bits_per_pixel) {
166 case 16: 167 case 16:
167 case 32: 168 case 32:
168 pos = pos * 8; 169 pos = pos * 8;
169 if (info->interlaced) { 170 if (info->interlaced) {
170 mga_outl(0x3C2C, pos); 171 mga_outl(0x3C2C, pos);
171 mga_outl(0x3C28, pos + ACCESS_FBINFO(fbcon).var.xres_virtual * ACCESS_FBINFO(fbcon).var.bits_per_pixel / 8); 172 mga_outl(0x3C28, pos + minfo->fbcon.var.xres_virtual * minfo->fbcon.var.bits_per_pixel / 8);
172 } else { 173 } else {
173 mga_outl(0x3C28, pos); 174 mga_outl(0x3C28, pos);
174 } 175 }
@@ -177,17 +178,18 @@ static void update_crtc2(WPMINFO unsigned int pos) {
177 } 178 }
178} 179}
179 180
180static void matroxfb_crtc1_panpos(WPMINFO2) { 181static void matroxfb_crtc1_panpos(struct matrox_fb_info *minfo)
181 if (ACCESS_FBINFO(crtc1.panpos) >= 0) { 182{
183 if (minfo->crtc1.panpos >= 0) {
182 unsigned long flags; 184 unsigned long flags;
183 int panpos; 185 int panpos;
184 186
185 matroxfb_DAC_lock_irqsave(flags); 187 matroxfb_DAC_lock_irqsave(flags);
186 panpos = ACCESS_FBINFO(crtc1.panpos); 188 panpos = minfo->crtc1.panpos;
187 if (panpos >= 0) { 189 if (panpos >= 0) {
188 unsigned int extvga_reg; 190 unsigned int extvga_reg;
189 191
190 ACCESS_FBINFO(crtc1.panpos) = -1; /* No update pending anymore */ 192 minfo->crtc1.panpos = -1; /* No update pending anymore */
191 extvga_reg = mga_inb(M_EXTVGA_INDEX); 193 extvga_reg = mga_inb(M_EXTVGA_INDEX);
192 mga_setr(M_EXTVGA_INDEX, 0x00, panpos); 194 mga_setr(M_EXTVGA_INDEX, 0x00, panpos);
193 if (extvga_reg != 0x00) { 195 if (extvga_reg != 0x00) {
@@ -202,39 +204,39 @@ static irqreturn_t matrox_irq(int irq, void *dev_id)
202{ 204{
203 u_int32_t status; 205 u_int32_t status;
204 int handled = 0; 206 int handled = 0;
205 207 struct matrox_fb_info *minfo = dev_id;
206 MINFO_FROM(dev_id);
207 208
208 status = mga_inl(M_STATUS); 209 status = mga_inl(M_STATUS);
209 210
210 if (status & 0x20) { 211 if (status & 0x20) {
211 mga_outl(M_ICLEAR, 0x20); 212 mga_outl(M_ICLEAR, 0x20);
212 ACCESS_FBINFO(crtc1.vsync.cnt)++; 213 minfo->crtc1.vsync.cnt++;
213 matroxfb_crtc1_panpos(PMINFO2); 214 matroxfb_crtc1_panpos(minfo);
214 wake_up_interruptible(&ACCESS_FBINFO(crtc1.vsync.wait)); 215 wake_up_interruptible(&minfo->crtc1.vsync.wait);
215 handled = 1; 216 handled = 1;
216 } 217 }
217 if (status & 0x200) { 218 if (status & 0x200) {
218 mga_outl(M_ICLEAR, 0x200); 219 mga_outl(M_ICLEAR, 0x200);
219 ACCESS_FBINFO(crtc2.vsync.cnt)++; 220 minfo->crtc2.vsync.cnt++;
220 wake_up_interruptible(&ACCESS_FBINFO(crtc2.vsync.wait)); 221 wake_up_interruptible(&minfo->crtc2.vsync.wait);
221 handled = 1; 222 handled = 1;
222 } 223 }
223 return IRQ_RETVAL(handled); 224 return IRQ_RETVAL(handled);
224} 225}
225 226
226int matroxfb_enable_irq(WPMINFO int reenable) { 227int matroxfb_enable_irq(struct matrox_fb_info *minfo, int reenable)
228{
227 u_int32_t bm; 229 u_int32_t bm;
228 230
229 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) 231 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400)
230 bm = 0x220; 232 bm = 0x220;
231 else 233 else
232 bm = 0x020; 234 bm = 0x020;
233 235
234 if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) { 236 if (!test_and_set_bit(0, &minfo->irq_flags)) {
235 if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq, 237 if (request_irq(minfo->pcidev->irq, matrox_irq,
236 IRQF_SHARED, "matroxfb", MINFO)) { 238 IRQF_SHARED, "matroxfb", minfo)) {
237 clear_bit(0, &ACCESS_FBINFO(irq_flags)); 239 clear_bit(0, &minfo->irq_flags);
238 return -EINVAL; 240 return -EINVAL;
239 } 241 }
240 /* Clear any pending field interrupts */ 242 /* Clear any pending field interrupts */
@@ -252,37 +254,39 @@ int matroxfb_enable_irq(WPMINFO int reenable) {
252 return 0; 254 return 0;
253} 255}
254 256
255static void matroxfb_disable_irq(WPMINFO2) { 257static void matroxfb_disable_irq(struct matrox_fb_info *minfo)
256 if (test_and_clear_bit(0, &ACCESS_FBINFO(irq_flags))) { 258{
259 if (test_and_clear_bit(0, &minfo->irq_flags)) {
257 /* Flush pending pan-at-vbl request... */ 260 /* Flush pending pan-at-vbl request... */
258 matroxfb_crtc1_panpos(PMINFO2); 261 matroxfb_crtc1_panpos(minfo);
259 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) 262 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400)
260 mga_outl(M_IEN, mga_inl(M_IEN) & ~0x220); 263 mga_outl(M_IEN, mga_inl(M_IEN) & ~0x220);
261 else 264 else
262 mga_outl(M_IEN, mga_inl(M_IEN) & ~0x20); 265 mga_outl(M_IEN, mga_inl(M_IEN) & ~0x20);
263 free_irq(ACCESS_FBINFO(pcidev)->irq, MINFO); 266 free_irq(minfo->pcidev->irq, minfo);
264 } 267 }
265} 268}
266 269
267int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { 270int matroxfb_wait_for_sync(struct matrox_fb_info *minfo, u_int32_t crtc)
271{
268 struct matrox_vsync *vs; 272 struct matrox_vsync *vs;
269 unsigned int cnt; 273 unsigned int cnt;
270 int ret; 274 int ret;
271 275
272 switch (crtc) { 276 switch (crtc) {
273 case 0: 277 case 0:
274 vs = &ACCESS_FBINFO(crtc1.vsync); 278 vs = &minfo->crtc1.vsync;
275 break; 279 break;
276 case 1: 280 case 1:
277 if (ACCESS_FBINFO(devflags.accelerator) != FB_ACCEL_MATROX_MGAG400) { 281 if (minfo->devflags.accelerator != FB_ACCEL_MATROX_MGAG400) {
278 return -ENODEV; 282 return -ENODEV;
279 } 283 }
280 vs = &ACCESS_FBINFO(crtc2.vsync); 284 vs = &minfo->crtc2.vsync;
281 break; 285 break;
282 default: 286 default:
283 return -ENODEV; 287 return -ENODEV;
284 } 288 }
285 ret = matroxfb_enable_irq(PMINFO 0); 289 ret = matroxfb_enable_irq(minfo, 0);
286 if (ret) { 290 if (ret) {
287 return ret; 291 return ret;
288 } 292 }
@@ -293,7 +297,7 @@ int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {
293 return ret; 297 return ret;
294 } 298 }
295 if (ret == 0) { 299 if (ret == 0) {
296 matroxfb_enable_irq(PMINFO 1); 300 matroxfb_enable_irq(minfo, 1);
297 return -ETIMEDOUT; 301 return -ETIMEDOUT;
298 } 302 }
299 return 0; 303 return 0;
@@ -301,12 +305,12 @@ int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {
301 305
302/* --------------------------------------------------------------------- */ 306/* --------------------------------------------------------------------- */
303 307
304static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) { 308static void matrox_pan_var(struct matrox_fb_info *minfo,
309 struct fb_var_screeninfo *var)
310{
305 unsigned int pos; 311 unsigned int pos;
306 unsigned short p0, p1, p2; 312 unsigned short p0, p1, p2;
307#ifdef CONFIG_FB_MATROX_32MB
308 unsigned int p3; 313 unsigned int p3;
309#endif
310 int vbl; 314 int vbl;
311 unsigned long flags; 315 unsigned long flags;
312 316
@@ -314,47 +318,44 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
314 318
315 DBG(__func__) 319 DBG(__func__)
316 320
317 if (ACCESS_FBINFO(dead)) 321 if (minfo->dead)
318 return; 322 return;
319 323
320 ACCESS_FBINFO(fbcon).var.xoffset = var->xoffset; 324 minfo->fbcon.var.xoffset = var->xoffset;
321 ACCESS_FBINFO(fbcon).var.yoffset = var->yoffset; 325 minfo->fbcon.var.yoffset = var->yoffset;
322 pos = (ACCESS_FBINFO(fbcon).var.yoffset * ACCESS_FBINFO(fbcon).var.xres_virtual + ACCESS_FBINFO(fbcon).var.xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32; 326 pos = (minfo->fbcon.var.yoffset * minfo->fbcon.var.xres_virtual + minfo->fbcon.var.xoffset) * minfo->curr.final_bppShift / 32;
323 pos += ACCESS_FBINFO(curr.ydstorg.chunks); 327 pos += minfo->curr.ydstorg.chunks;
324 p0 = ACCESS_FBINFO(hw).CRTC[0x0D] = pos & 0xFF; 328 p0 = minfo->hw.CRTC[0x0D] = pos & 0xFF;
325 p1 = ACCESS_FBINFO(hw).CRTC[0x0C] = (pos & 0xFF00) >> 8; 329 p1 = minfo->hw.CRTC[0x0C] = (pos & 0xFF00) >> 8;
326 p2 = ACCESS_FBINFO(hw).CRTCEXT[0] = (ACCESS_FBINFO(hw).CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40); 330 p2 = minfo->hw.CRTCEXT[0] = (minfo->hw.CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
327#ifdef CONFIG_FB_MATROX_32MB 331 p3 = minfo->hw.CRTCEXT[8] = pos >> 21;
328 p3 = ACCESS_FBINFO(hw).CRTCEXT[8] = pos >> 21;
329#endif
330 332
331 /* FB_ACTIVATE_VBL and we can acquire interrupts? Honor FB_ACTIVATE_VBL then... */ 333 /* FB_ACTIVATE_VBL and we can acquire interrupts? Honor FB_ACTIVATE_VBL then... */
332 vbl = (var->activate & FB_ACTIVATE_VBL) && (matroxfb_enable_irq(PMINFO 0) == 0); 334 vbl = (var->activate & FB_ACTIVATE_VBL) && (matroxfb_enable_irq(minfo, 0) == 0);
333 335
334 CRITBEGIN 336 CRITBEGIN
335 337
336 matroxfb_DAC_lock_irqsave(flags); 338 matroxfb_DAC_lock_irqsave(flags);
337 mga_setr(M_CRTC_INDEX, 0x0D, p0); 339 mga_setr(M_CRTC_INDEX, 0x0D, p0);
338 mga_setr(M_CRTC_INDEX, 0x0C, p1); 340 mga_setr(M_CRTC_INDEX, 0x0C, p1);
339#ifdef CONFIG_FB_MATROX_32MB 341 if (minfo->devflags.support32MB)
340 if (ACCESS_FBINFO(devflags.support32MB))
341 mga_setr(M_EXTVGA_INDEX, 0x08, p3); 342 mga_setr(M_EXTVGA_INDEX, 0x08, p3);
342#endif
343 if (vbl) { 343 if (vbl) {
344 ACCESS_FBINFO(crtc1.panpos) = p2; 344 minfo->crtc1.panpos = p2;
345 } else { 345 } else {
346 /* Abort any pending change */ 346 /* Abort any pending change */
347 ACCESS_FBINFO(crtc1.panpos) = -1; 347 minfo->crtc1.panpos = -1;
348 mga_setr(M_EXTVGA_INDEX, 0x00, p2); 348 mga_setr(M_EXTVGA_INDEX, 0x00, p2);
349 } 349 }
350 matroxfb_DAC_unlock_irqrestore(flags); 350 matroxfb_DAC_unlock_irqrestore(flags);
351 351
352 update_crtc2(PMINFO pos); 352 update_crtc2(minfo, pos);
353 353
354 CRITEND 354 CRITEND
355} 355}
356 356
357static void matroxfb_remove(WPMINFO int dummy) { 357static void matroxfb_remove(struct matrox_fb_info *minfo, int dummy)
358{
358 /* Currently we are holding big kernel lock on all dead & usecount updates. 359 /* Currently we are holding big kernel lock on all dead & usecount updates.
359 * Destroy everything after all users release it. Especially do not unregister 360 * Destroy everything after all users release it. Especially do not unregister
360 * framebuffer and iounmap memory, neither fbmem nor fbcon-cfb* does not check 361 * framebuffer and iounmap memory, neither fbmem nor fbcon-cfb* does not check
@@ -363,25 +364,23 @@ static void matroxfb_remove(WPMINFO int dummy) {
363 * write data without causing too much damage... 364 * write data without causing too much damage...
364 */ 365 */
365 366
366 ACCESS_FBINFO(dead) = 1; 367 minfo->dead = 1;
367 if (ACCESS_FBINFO(usecount)) { 368 if (minfo->usecount) {
368 /* destroy it later */ 369 /* destroy it later */
369 return; 370 return;
370 } 371 }
371 matroxfb_unregister_device(MINFO); 372 matroxfb_unregister_device(minfo);
372 unregister_framebuffer(&ACCESS_FBINFO(fbcon)); 373 unregister_framebuffer(&minfo->fbcon);
373 matroxfb_g450_shutdown(PMINFO2); 374 matroxfb_g450_shutdown(minfo);
374#ifdef CONFIG_MTRR 375#ifdef CONFIG_MTRR
375 if (ACCESS_FBINFO(mtrr.vram_valid)) 376 if (minfo->mtrr.vram_valid)
376 mtrr_del(ACCESS_FBINFO(mtrr.vram), ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len)); 377 mtrr_del(minfo->mtrr.vram, minfo->video.base, minfo->video.len);
377#endif 378#endif
378 mga_iounmap(ACCESS_FBINFO(mmio.vbase)); 379 mga_iounmap(minfo->mmio.vbase);
379 mga_iounmap(ACCESS_FBINFO(video.vbase)); 380 mga_iounmap(minfo->video.vbase);
380 release_mem_region(ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len_maximum)); 381 release_mem_region(minfo->video.base, minfo->video.len_maximum);
381 release_mem_region(ACCESS_FBINFO(mmio.base), 16384); 382 release_mem_region(minfo->mmio.base, 16384);
382#ifdef CONFIG_FB_MATROX_MULTIHEAD
383 kfree(minfo); 383 kfree(minfo);
384#endif
385} 384}
386 385
387 /* 386 /*
@@ -390,48 +389,50 @@ static void matroxfb_remove(WPMINFO int dummy) {
390 389
391static int matroxfb_open(struct fb_info *info, int user) 390static int matroxfb_open(struct fb_info *info, int user)
392{ 391{
393 MINFO_FROM_INFO(info); 392 struct matrox_fb_info *minfo = info2minfo(info);
394 393
395 DBG_LOOP(__func__) 394 DBG_LOOP(__func__)
396 395
397 if (ACCESS_FBINFO(dead)) { 396 if (minfo->dead) {
398 return -ENXIO; 397 return -ENXIO;
399 } 398 }
400 ACCESS_FBINFO(usecount)++; 399 minfo->usecount++;
401 if (user) { 400 if (user) {
402 ACCESS_FBINFO(userusecount)++; 401 minfo->userusecount++;
403 } 402 }
404 return(0); 403 return(0);
405} 404}
406 405
407static int matroxfb_release(struct fb_info *info, int user) 406static int matroxfb_release(struct fb_info *info, int user)
408{ 407{
409 MINFO_FROM_INFO(info); 408 struct matrox_fb_info *minfo = info2minfo(info);
410 409
411 DBG_LOOP(__func__) 410 DBG_LOOP(__func__)
412 411
413 if (user) { 412 if (user) {
414 if (0 == --ACCESS_FBINFO(userusecount)) { 413 if (0 == --minfo->userusecount) {
415 matroxfb_disable_irq(PMINFO2); 414 matroxfb_disable_irq(minfo);
416 } 415 }
417 } 416 }
418 if (!(--ACCESS_FBINFO(usecount)) && ACCESS_FBINFO(dead)) { 417 if (!(--minfo->usecount) && minfo->dead) {
419 matroxfb_remove(PMINFO 0); 418 matroxfb_remove(minfo, 0);
420 } 419 }
421 return(0); 420 return(0);
422} 421}
423 422
424static int matroxfb_pan_display(struct fb_var_screeninfo *var, 423static int matroxfb_pan_display(struct fb_var_screeninfo *var,
425 struct fb_info* info) { 424 struct fb_info* info) {
426 MINFO_FROM_INFO(info); 425 struct matrox_fb_info *minfo = info2minfo(info);
427 426
428 DBG(__func__) 427 DBG(__func__)
429 428
430 matrox_pan_var(PMINFO var); 429 matrox_pan_var(minfo, var);
431 return 0; 430 return 0;
432} 431}
433 432
434static int matroxfb_get_final_bppShift(CPMINFO int bpp) { 433static int matroxfb_get_final_bppShift(const struct matrox_fb_info *minfo,
434 int bpp)
435{
435 int bppshft2; 436 int bppshft2;
436 437
437 DBG(__func__) 438 DBG(__func__)
@@ -440,14 +441,16 @@ static int matroxfb_get_final_bppShift(CPMINFO int bpp) {
440 if (!bppshft2) { 441 if (!bppshft2) {
441 return 8; 442 return 8;
442 } 443 }
443 if (isInterleave(MINFO)) 444 if (isInterleave(minfo))
444 bppshft2 >>= 1; 445 bppshft2 >>= 1;
445 if (ACCESS_FBINFO(devflags.video64bits)) 446 if (minfo->devflags.video64bits)
446 bppshft2 >>= 1; 447 bppshft2 >>= 1;
447 return bppshft2; 448 return bppshft2;
448} 449}
449 450
450static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) { 451static int matroxfb_test_and_set_rounding(const struct matrox_fb_info *minfo,
452 int xres, int bpp)
453{
451 int over; 454 int over;
452 int rounding; 455 int rounding;
453 456
@@ -465,11 +468,11 @@ static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) {
465 break; 468 break;
466 default: rounding = 16; 469 default: rounding = 16;
467 /* on G400, 16 really does not work */ 470 /* on G400, 16 really does not work */
468 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) 471 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400)
469 rounding = 32; 472 rounding = 32;
470 break; 473 break;
471 } 474 }
472 if (isInterleave(MINFO)) { 475 if (isInterleave(minfo)) {
473 rounding *= 2; 476 rounding *= 2;
474 } 477 }
475 over = xres % rounding; 478 over = xres % rounding;
@@ -478,7 +481,9 @@ static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) {
478 return xres; 481 return xres;
479} 482}
480 483
481static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) { 484static int matroxfb_pitch_adjust(const struct matrox_fb_info *minfo, int xres,
485 int bpp)
486{
482 const int* width; 487 const int* width;
483 int xres_new; 488 int xres_new;
484 489
@@ -486,18 +491,18 @@ static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) {
486 491
487 if (!bpp) return xres; 492 if (!bpp) return xres;
488 493
489 width = ACCESS_FBINFO(capable.vxres); 494 width = minfo->capable.vxres;
490 495
491 if (ACCESS_FBINFO(devflags.precise_width)) { 496 if (minfo->devflags.precise_width) {
492 while (*width) { 497 while (*width) {
493 if ((*width >= xres) && (matroxfb_test_and_set_rounding(PMINFO *width, bpp) == *width)) { 498 if ((*width >= xres) && (matroxfb_test_and_set_rounding(minfo, *width, bpp) == *width)) {
494 break; 499 break;
495 } 500 }
496 width++; 501 width++;
497 } 502 }
498 xres_new = *width; 503 xres_new = *width;
499 } else { 504 } else {
500 xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp); 505 xres_new = matroxfb_test_and_set_rounding(minfo, xres, bpp);
501 } 506 }
502 return xres_new; 507 return xres_new;
503} 508}
@@ -524,7 +529,10 @@ static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) {
524 return 16; /* return something reasonable... or panic()? */ 529 return 16; /* return something reasonable... or panic()? */
525} 530}
526 531
527static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visual, int *video_cmap_len, unsigned int* ydstorg) { 532static int matroxfb_decode_var(const struct matrox_fb_info *minfo,
533 struct fb_var_screeninfo *var, int *visual,
534 int *video_cmap_len, unsigned int* ydstorg)
535{
528 struct RGBT { 536 struct RGBT {
529 unsigned char bpp; 537 unsigned char bpp;
530 struct { 538 struct {
@@ -551,7 +559,7 @@ static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visua
551 DBG(__func__) 559 DBG(__func__)
552 560
553 switch (bpp) { 561 switch (bpp) {
554 case 4: if (!ACCESS_FBINFO(capable.cfb4)) return -EINVAL; 562 case 4: if (!minfo->capable.cfb4) return -EINVAL;
555 break; 563 break;
556 case 8: break; 564 case 8: break;
557 case 16: break; 565 case 16: break;
@@ -560,13 +568,13 @@ static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visua
560 default: return -EINVAL; 568 default: return -EINVAL;
561 } 569 }
562 *ydstorg = 0; 570 *ydstorg = 0;
563 vramlen = ACCESS_FBINFO(video.len_usable); 571 vramlen = minfo->video.len_usable;
564 if (var->yres_virtual < var->yres) 572 if (var->yres_virtual < var->yres)
565 var->yres_virtual = var->yres; 573 var->yres_virtual = var->yres;
566 if (var->xres_virtual < var->xres) 574 if (var->xres_virtual < var->xres)
567 var->xres_virtual = var->xres; 575 var->xres_virtual = var->xres;
568 576
569 var->xres_virtual = matroxfb_pitch_adjust(PMINFO var->xres_virtual, bpp); 577 var->xres_virtual = matroxfb_pitch_adjust(minfo, var->xres_virtual, bpp);
570 memlen = var->xres_virtual * bpp * var->yres_virtual / 8; 578 memlen = var->xres_virtual * bpp * var->yres_virtual / 8;
571 if (memlen > vramlen) { 579 if (memlen > vramlen) {
572 var->yres_virtual = vramlen * 8 / (var->xres_virtual * bpp); 580 var->yres_virtual = vramlen * 8 / (var->xres_virtual * bpp);
@@ -575,7 +583,7 @@ static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visua
575 /* There is hardware bug that no line can cross 4MB boundary */ 583 /* There is hardware bug that no line can cross 4MB boundary */
576 /* give up for CFB24, it is impossible to easy workaround it */ 584 /* give up for CFB24, it is impossible to easy workaround it */
577 /* for other try to do something */ 585 /* for other try to do something */
578 if (!ACCESS_FBINFO(capable.cross4MB) && (memlen > 0x400000)) { 586 if (!minfo->capable.cross4MB && (memlen > 0x400000)) {
579 if (bpp == 24) { 587 if (bpp == 24) {
580 /* sorry */ 588 /* sorry */
581 } else { 589 } else {
@@ -644,9 +652,7 @@ static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
644 unsigned blue, unsigned transp, 652 unsigned blue, unsigned transp,
645 struct fb_info *fb_info) 653 struct fb_info *fb_info)
646{ 654{
647#ifdef CONFIG_FB_MATROX_MULTIHEAD
648 struct matrox_fb_info* minfo = container_of(fb_info, struct matrox_fb_info, fbcon); 655 struct matrox_fb_info* minfo = container_of(fb_info, struct matrox_fb_info, fbcon);
649#endif
650 656
651 DBG(__func__) 657 DBG(__func__)
652 658
@@ -657,20 +663,20 @@ static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
657 * != 0 for invalid regno. 663 * != 0 for invalid regno.
658 */ 664 */
659 665
660 if (regno >= ACCESS_FBINFO(curr.cmap_len)) 666 if (regno >= minfo->curr.cmap_len)
661 return 1; 667 return 1;
662 668
663 if (ACCESS_FBINFO(fbcon).var.grayscale) { 669 if (minfo->fbcon.var.grayscale) {
664 /* gray = 0.30*R + 0.59*G + 0.11*B */ 670 /* gray = 0.30*R + 0.59*G + 0.11*B */
665 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; 671 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
666 } 672 }
667 673
668 red = CNVT_TOHW(red, ACCESS_FBINFO(fbcon).var.red.length); 674 red = CNVT_TOHW(red, minfo->fbcon.var.red.length);
669 green = CNVT_TOHW(green, ACCESS_FBINFO(fbcon).var.green.length); 675 green = CNVT_TOHW(green, minfo->fbcon.var.green.length);
670 blue = CNVT_TOHW(blue, ACCESS_FBINFO(fbcon).var.blue.length); 676 blue = CNVT_TOHW(blue, minfo->fbcon.var.blue.length);
671 transp = CNVT_TOHW(transp, ACCESS_FBINFO(fbcon).var.transp.length); 677 transp = CNVT_TOHW(transp, minfo->fbcon.var.transp.length);
672 678
673 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { 679 switch (minfo->fbcon.var.bits_per_pixel) {
674 case 4: 680 case 4:
675 case 8: 681 case 8:
676 mga_outb(M_DAC_REG, regno); 682 mga_outb(M_DAC_REG, regno);
@@ -683,30 +689,30 @@ static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
683 break; 689 break;
684 { 690 {
685 u_int16_t col = 691 u_int16_t col =
686 (red << ACCESS_FBINFO(fbcon).var.red.offset) | 692 (red << minfo->fbcon.var.red.offset) |
687 (green << ACCESS_FBINFO(fbcon).var.green.offset) | 693 (green << minfo->fbcon.var.green.offset) |
688 (blue << ACCESS_FBINFO(fbcon).var.blue.offset) | 694 (blue << minfo->fbcon.var.blue.offset) |
689 (transp << ACCESS_FBINFO(fbcon).var.transp.offset); /* for 1:5:5:5 */ 695 (transp << minfo->fbcon.var.transp.offset); /* for 1:5:5:5 */
690 ACCESS_FBINFO(cmap[regno]) = col | (col << 16); 696 minfo->cmap[regno] = col | (col << 16);
691 } 697 }
692 break; 698 break;
693 case 24: 699 case 24:
694 case 32: 700 case 32:
695 if (regno >= 16) 701 if (regno >= 16)
696 break; 702 break;
697 ACCESS_FBINFO(cmap[regno]) = 703 minfo->cmap[regno] =
698 (red << ACCESS_FBINFO(fbcon).var.red.offset) | 704 (red << minfo->fbcon.var.red.offset) |
699 (green << ACCESS_FBINFO(fbcon).var.green.offset) | 705 (green << minfo->fbcon.var.green.offset) |
700 (blue << ACCESS_FBINFO(fbcon).var.blue.offset) | 706 (blue << minfo->fbcon.var.blue.offset) |
701 (transp << ACCESS_FBINFO(fbcon).var.transp.offset); /* 8:8:8:8 */ 707 (transp << minfo->fbcon.var.transp.offset); /* 8:8:8:8 */
702 break; 708 break;
703 } 709 }
704 return 0; 710 return 0;
705} 711}
706 712
707static void matroxfb_init_fix(WPMINFO2) 713static void matroxfb_init_fix(struct matrox_fb_info *minfo)
708{ 714{
709 struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; 715 struct fb_fix_screeninfo *fix = &minfo->fbcon.fix;
710 DBG(__func__) 716 DBG(__func__)
711 717
712 strcpy(fix->id,"MATROX"); 718 strcpy(fix->id,"MATROX");
@@ -714,20 +720,20 @@ static void matroxfb_init_fix(WPMINFO2)
714 fix->xpanstep = 8; /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */ 720 fix->xpanstep = 8; /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */
715 fix->ypanstep = 1; 721 fix->ypanstep = 1;
716 fix->ywrapstep = 0; 722 fix->ywrapstep = 0;
717 fix->mmio_start = ACCESS_FBINFO(mmio.base); 723 fix->mmio_start = minfo->mmio.base;
718 fix->mmio_len = ACCESS_FBINFO(mmio.len); 724 fix->mmio_len = minfo->mmio.len;
719 fix->accel = ACCESS_FBINFO(devflags.accelerator); 725 fix->accel = minfo->devflags.accelerator;
720} 726}
721 727
722static void matroxfb_update_fix(WPMINFO2) 728static void matroxfb_update_fix(struct matrox_fb_info *minfo)
723{ 729{
724 struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; 730 struct fb_fix_screeninfo *fix = &minfo->fbcon.fix;
725 DBG(__func__) 731 DBG(__func__)
726 732
727 mutex_lock(&ACCESS_FBINFO(fbcon).mm_lock); 733 mutex_lock(&minfo->fbcon.mm_lock);
728 fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes); 734 fix->smem_start = minfo->video.base + minfo->curr.ydstorg.bytes;
729 fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes); 735 fix->smem_len = minfo->video.len_usable - minfo->curr.ydstorg.bytes;
730 mutex_unlock(&ACCESS_FBINFO(fbcon).mm_lock); 736 mutex_unlock(&minfo->fbcon.mm_lock);
731} 737}
732 738
733static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 739static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -736,12 +742,12 @@ static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf
736 int visual; 742 int visual;
737 int cmap_len; 743 int cmap_len;
738 unsigned int ydstorg; 744 unsigned int ydstorg;
739 MINFO_FROM_INFO(info); 745 struct matrox_fb_info *minfo = info2minfo(info);
740 746
741 if (ACCESS_FBINFO(dead)) { 747 if (minfo->dead) {
742 return -ENXIO; 748 return -ENXIO;
743 } 749 }
744 if ((err = matroxfb_decode_var(PMINFO var, &visual, &cmap_len, &ydstorg)) != 0) 750 if ((err = matroxfb_decode_var(minfo, var, &visual, &cmap_len, &ydstorg)) != 0)
745 return err; 751 return err;
746 return 0; 752 return 0;
747} 753}
@@ -753,35 +759,35 @@ static int matroxfb_set_par(struct fb_info *info)
753 int cmap_len; 759 int cmap_len;
754 unsigned int ydstorg; 760 unsigned int ydstorg;
755 struct fb_var_screeninfo *var; 761 struct fb_var_screeninfo *var;
756 MINFO_FROM_INFO(info); 762 struct matrox_fb_info *minfo = info2minfo(info);
757 763
758 DBG(__func__) 764 DBG(__func__)
759 765
760 if (ACCESS_FBINFO(dead)) { 766 if (minfo->dead) {
761 return -ENXIO; 767 return -ENXIO;
762 } 768 }
763 769
764 var = &info->var; 770 var = &info->var;
765 if ((err = matroxfb_decode_var(PMINFO var, &visual, &cmap_len, &ydstorg)) != 0) 771 if ((err = matroxfb_decode_var(minfo, var, &visual, &cmap_len, &ydstorg)) != 0)
766 return err; 772 return err;
767 ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)) + ydstorg; 773 minfo->fbcon.screen_base = vaddr_va(minfo->video.vbase) + ydstorg;
768 matroxfb_update_fix(PMINFO2); 774 matroxfb_update_fix(minfo);
769 ACCESS_FBINFO(fbcon).fix.visual = visual; 775 minfo->fbcon.fix.visual = visual;
770 ACCESS_FBINFO(fbcon).fix.type = FB_TYPE_PACKED_PIXELS; 776 minfo->fbcon.fix.type = FB_TYPE_PACKED_PIXELS;
771 ACCESS_FBINFO(fbcon).fix.type_aux = 0; 777 minfo->fbcon.fix.type_aux = 0;
772 ACCESS_FBINFO(fbcon).fix.line_length = (var->xres_virtual * var->bits_per_pixel) >> 3; 778 minfo->fbcon.fix.line_length = (var->xres_virtual * var->bits_per_pixel) >> 3;
773 { 779 {
774 unsigned int pos; 780 unsigned int pos;
775 781
776 ACCESS_FBINFO(curr.cmap_len) = cmap_len; 782 minfo->curr.cmap_len = cmap_len;
777 ydstorg += ACCESS_FBINFO(devflags.ydstorg); 783 ydstorg += minfo->devflags.ydstorg;
778 ACCESS_FBINFO(curr.ydstorg.bytes) = ydstorg; 784 minfo->curr.ydstorg.bytes = ydstorg;
779 ACCESS_FBINFO(curr.ydstorg.chunks) = ydstorg >> (isInterleave(MINFO)?3:2); 785 minfo->curr.ydstorg.chunks = ydstorg >> (isInterleave(minfo) ? 3 : 2);
780 if (var->bits_per_pixel == 4) 786 if (var->bits_per_pixel == 4)
781 ACCESS_FBINFO(curr.ydstorg.pixels) = ydstorg; 787 minfo->curr.ydstorg.pixels = ydstorg;
782 else 788 else
783 ACCESS_FBINFO(curr.ydstorg.pixels) = (ydstorg * 8) / var->bits_per_pixel; 789 minfo->curr.ydstorg.pixels = (ydstorg * 8) / var->bits_per_pixel;
784 ACCESS_FBINFO(curr.final_bppShift) = matroxfb_get_final_bppShift(PMINFO var->bits_per_pixel); 790 minfo->curr.final_bppShift = matroxfb_get_final_bppShift(minfo, var->bits_per_pixel);
785 { struct my_timming mt; 791 { struct my_timming mt;
786 struct matrox_hw_state* hw; 792 struct matrox_hw_state* hw;
787 int out; 793 int out;
@@ -797,54 +803,55 @@ static int matroxfb_set_par(struct fb_info *info)
797 default: mt.delay = 31 + 8; break; 803 default: mt.delay = 31 + 8; break;
798 } 804 }
799 805
800 hw = &ACCESS_FBINFO(hw); 806 hw = &minfo->hw;
801 807
802 down_read(&ACCESS_FBINFO(altout).lock); 808 down_read(&minfo->altout.lock);
803 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { 809 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
804 if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 && 810 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC1 &&
805 ACCESS_FBINFO(outputs[out]).output->compute) { 811 minfo->outputs[out].output->compute) {
806 ACCESS_FBINFO(outputs[out]).output->compute(ACCESS_FBINFO(outputs[out]).data, &mt); 812 minfo->outputs[out].output->compute(minfo->outputs[out].data, &mt);
807 } 813 }
808 } 814 }
809 up_read(&ACCESS_FBINFO(altout).lock); 815 up_read(&minfo->altout.lock);
810 ACCESS_FBINFO(crtc1).pixclock = mt.pixclock; 816 minfo->crtc1.pixclock = mt.pixclock;
811 ACCESS_FBINFO(crtc1).mnp = mt.mnp; 817 minfo->crtc1.mnp = mt.mnp;
812 ACCESS_FBINFO(hw_switch->init(PMINFO &mt)); 818 minfo->hw_switch->init(minfo, &mt);
813 pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32; 819 pos = (var->yoffset * var->xres_virtual + var->xoffset) * minfo->curr.final_bppShift / 32;
814 pos += ACCESS_FBINFO(curr.ydstorg.chunks); 820 pos += minfo->curr.ydstorg.chunks;
815 821
816 hw->CRTC[0x0D] = pos & 0xFF; 822 hw->CRTC[0x0D] = pos & 0xFF;
817 hw->CRTC[0x0C] = (pos & 0xFF00) >> 8; 823 hw->CRTC[0x0C] = (pos & 0xFF00) >> 8;
818 hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40); 824 hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
819 hw->CRTCEXT[8] = pos >> 21; 825 hw->CRTCEXT[8] = pos >> 21;
820 ACCESS_FBINFO(hw_switch->restore(PMINFO2)); 826 minfo->hw_switch->restore(minfo);
821 update_crtc2(PMINFO pos); 827 update_crtc2(minfo, pos);
822 down_read(&ACCESS_FBINFO(altout).lock); 828 down_read(&minfo->altout.lock);
823 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { 829 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
824 if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 && 830 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC1 &&
825 ACCESS_FBINFO(outputs[out]).output->program) { 831 minfo->outputs[out].output->program) {
826 ACCESS_FBINFO(outputs[out]).output->program(ACCESS_FBINFO(outputs[out]).data); 832 minfo->outputs[out].output->program(minfo->outputs[out].data);
827 } 833 }
828 } 834 }
829 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { 835 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
830 if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 && 836 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC1 &&
831 ACCESS_FBINFO(outputs[out]).output->start) { 837 minfo->outputs[out].output->start) {
832 ACCESS_FBINFO(outputs[out]).output->start(ACCESS_FBINFO(outputs[out]).data); 838 minfo->outputs[out].output->start(minfo->outputs[out].data);
833 } 839 }
834 } 840 }
835 up_read(&ACCESS_FBINFO(altout).lock); 841 up_read(&minfo->altout.lock);
836 matrox_cfbX_init(PMINFO2); 842 matrox_cfbX_init(minfo);
837 } 843 }
838 } 844 }
839 ACCESS_FBINFO(initialized) = 1; 845 minfo->initialized = 1;
840 return 0; 846 return 0;
841} 847}
842 848
843static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank) 849static int matroxfb_get_vblank(struct matrox_fb_info *minfo,
850 struct fb_vblank *vblank)
844{ 851{
845 unsigned int sts1; 852 unsigned int sts1;
846 853
847 matroxfb_enable_irq(PMINFO 0); 854 matroxfb_enable_irq(minfo, 0);
848 memset(vblank, 0, sizeof(*vblank)); 855 memset(vblank, 0, sizeof(*vblank));
849 vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC | 856 vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC |
850 FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK; 857 FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK;
@@ -857,13 +864,13 @@ static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank)
857 vblank->flags |= FB_VBLANK_HBLANKING; 864 vblank->flags |= FB_VBLANK_HBLANKING;
858 if (sts1 & 8) 865 if (sts1 & 8)
859 vblank->flags |= FB_VBLANK_VSYNCING; 866 vblank->flags |= FB_VBLANK_VSYNCING;
860 if (vblank->vcount >= ACCESS_FBINFO(fbcon).var.yres) 867 if (vblank->vcount >= minfo->fbcon.var.yres)
861 vblank->flags |= FB_VBLANK_VBLANKING; 868 vblank->flags |= FB_VBLANK_VBLANKING;
862 if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { 869 if (test_bit(0, &minfo->irq_flags)) {
863 vblank->flags |= FB_VBLANK_HAVE_COUNT; 870 vblank->flags |= FB_VBLANK_HAVE_COUNT;
864 /* Only one writer, aligned int value... 871 /* Only one writer, aligned int value...
865 it should work without lock and without atomic_t */ 872 it should work without lock and without atomic_t */
866 vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt; 873 vblank->count = minfo->crtc1.vsync.cnt;
867 } 874 }
868 return 0; 875 return 0;
869} 876}
@@ -876,11 +883,11 @@ static int matroxfb_ioctl(struct fb_info *info,
876 unsigned int cmd, unsigned long arg) 883 unsigned int cmd, unsigned long arg)
877{ 884{
878 void __user *argp = (void __user *)arg; 885 void __user *argp = (void __user *)arg;
879 MINFO_FROM_INFO(info); 886 struct matrox_fb_info *minfo = info2minfo(info);
880 887
881 DBG(__func__) 888 DBG(__func__)
882 889
883 if (ACCESS_FBINFO(dead)) { 890 if (minfo->dead) {
884 return -ENXIO; 891 return -ENXIO;
885 } 892 }
886 893
@@ -890,7 +897,7 @@ static int matroxfb_ioctl(struct fb_info *info,
890 struct fb_vblank vblank; 897 struct fb_vblank vblank;
891 int err; 898 int err;
892 899
893 err = matroxfb_get_vblank(PMINFO &vblank); 900 err = matroxfb_get_vblank(minfo, &vblank);
894 if (err) 901 if (err)
895 return err; 902 return err;
896 if (copy_to_user(argp, &vblank, sizeof(vblank))) 903 if (copy_to_user(argp, &vblank, sizeof(vblank)))
@@ -904,7 +911,7 @@ static int matroxfb_ioctl(struct fb_info *info,
904 if (get_user(crt, (u_int32_t __user *)arg)) 911 if (get_user(crt, (u_int32_t __user *)arg))
905 return -EFAULT; 912 return -EFAULT;
906 913
907 return matroxfb_wait_for_sync(PMINFO crt); 914 return matroxfb_wait_for_sync(minfo, crt);
908 } 915 }
909 case MATROXFB_SET_OUTPUT_MODE: 916 case MATROXFB_SET_OUTPUT_MODE:
910 { 917 {
@@ -916,8 +923,8 @@ static int matroxfb_ioctl(struct fb_info *info,
916 return -EFAULT; 923 return -EFAULT;
917 if (mom.output >= MATROXFB_MAX_OUTPUTS) 924 if (mom.output >= MATROXFB_MAX_OUTPUTS)
918 return -ENXIO; 925 return -ENXIO;
919 down_read(&ACCESS_FBINFO(altout.lock)); 926 down_read(&minfo->altout.lock);
920 oproc = ACCESS_FBINFO(outputs[mom.output]).output; 927 oproc = minfo->outputs[mom.output].output;
921 if (!oproc) { 928 if (!oproc) {
922 val = -ENXIO; 929 val = -ENXIO;
923 } else if (!oproc->verifymode) { 930 } else if (!oproc->verifymode) {
@@ -927,18 +934,18 @@ static int matroxfb_ioctl(struct fb_info *info,
927 val = -EINVAL; 934 val = -EINVAL;
928 } 935 }
929 } else { 936 } else {
930 val = oproc->verifymode(ACCESS_FBINFO(outputs[mom.output]).data, mom.mode); 937 val = oproc->verifymode(minfo->outputs[mom.output].data, mom.mode);
931 } 938 }
932 if (!val) { 939 if (!val) {
933 if (ACCESS_FBINFO(outputs[mom.output]).mode != mom.mode) { 940 if (minfo->outputs[mom.output].mode != mom.mode) {
934 ACCESS_FBINFO(outputs[mom.output]).mode = mom.mode; 941 minfo->outputs[mom.output].mode = mom.mode;
935 val = 1; 942 val = 1;
936 } 943 }
937 } 944 }
938 up_read(&ACCESS_FBINFO(altout.lock)); 945 up_read(&minfo->altout.lock);
939 if (val != 1) 946 if (val != 1)
940 return val; 947 return val;
941 switch (ACCESS_FBINFO(outputs[mom.output]).src) { 948 switch (minfo->outputs[mom.output].src) {
942 case MATROXFB_SRC_CRTC1: 949 case MATROXFB_SRC_CRTC1:
943 matroxfb_set_par(info); 950 matroxfb_set_par(info);
944 break; 951 break;
@@ -946,11 +953,11 @@ static int matroxfb_ioctl(struct fb_info *info,
946 { 953 {
947 struct matroxfb_dh_fb_info* crtc2; 954 struct matroxfb_dh_fb_info* crtc2;
948 955
949 down_read(&ACCESS_FBINFO(crtc2.lock)); 956 down_read(&minfo->crtc2.lock);
950 crtc2 = ACCESS_FBINFO(crtc2.info); 957 crtc2 = minfo->crtc2.info;
951 if (crtc2) 958 if (crtc2)
952 crtc2->fbcon.fbops->fb_set_par(&crtc2->fbcon); 959 crtc2->fbcon.fbops->fb_set_par(&crtc2->fbcon);
953 up_read(&ACCESS_FBINFO(crtc2.lock)); 960 up_read(&minfo->crtc2.lock);
954 } 961 }
955 break; 962 break;
956 } 963 }
@@ -966,15 +973,15 @@ static int matroxfb_ioctl(struct fb_info *info,
966 return -EFAULT; 973 return -EFAULT;
967 if (mom.output >= MATROXFB_MAX_OUTPUTS) 974 if (mom.output >= MATROXFB_MAX_OUTPUTS)
968 return -ENXIO; 975 return -ENXIO;
969 down_read(&ACCESS_FBINFO(altout.lock)); 976 down_read(&minfo->altout.lock);
970 oproc = ACCESS_FBINFO(outputs[mom.output]).output; 977 oproc = minfo->outputs[mom.output].output;
971 if (!oproc) { 978 if (!oproc) {
972 val = -ENXIO; 979 val = -ENXIO;
973 } else { 980 } else {
974 mom.mode = ACCESS_FBINFO(outputs[mom.output]).mode; 981 mom.mode = minfo->outputs[mom.output].mode;
975 val = 0; 982 val = 0;
976 } 983 }
977 up_read(&ACCESS_FBINFO(altout.lock)); 984 up_read(&minfo->altout.lock);
978 if (val) 985 if (val)
979 return val; 986 return val;
980 if (copy_to_user(argp, &mom, sizeof(mom))) 987 if (copy_to_user(argp, &mom, sizeof(mom)))
@@ -993,9 +1000,9 @@ static int matroxfb_ioctl(struct fb_info *info,
993 if (tmp & (1 << i)) { 1000 if (tmp & (1 << i)) {
994 if (i >= MATROXFB_MAX_OUTPUTS) 1001 if (i >= MATROXFB_MAX_OUTPUTS)
995 return -ENXIO; 1002 return -ENXIO;
996 if (!ACCESS_FBINFO(outputs[i]).output) 1003 if (!minfo->outputs[i].output)
997 return -ENXIO; 1004 return -ENXIO;
998 switch (ACCESS_FBINFO(outputs[i]).src) { 1005 switch (minfo->outputs[i].src) {
999 case MATROXFB_SRC_NONE: 1006 case MATROXFB_SRC_NONE:
1000 case MATROXFB_SRC_CRTC1: 1007 case MATROXFB_SRC_CRTC1:
1001 break; 1008 break;
@@ -1004,12 +1011,12 @@ static int matroxfb_ioctl(struct fb_info *info,
1004 } 1011 }
1005 } 1012 }
1006 } 1013 }
1007 if (ACCESS_FBINFO(devflags.panellink)) { 1014 if (minfo->devflags.panellink) {
1008 if (tmp & MATROXFB_OUTPUT_CONN_DFP) { 1015 if (tmp & MATROXFB_OUTPUT_CONN_DFP) {
1009 if (tmp & MATROXFB_OUTPUT_CONN_SECONDARY) 1016 if (tmp & MATROXFB_OUTPUT_CONN_SECONDARY)
1010 return -EINVAL; 1017 return -EINVAL;
1011 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { 1018 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1012 if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC2) { 1019 if (minfo->outputs[i].src == MATROXFB_SRC_CRTC2) {
1013 return -EBUSY; 1020 return -EBUSY;
1014 } 1021 }
1015 } 1022 }
@@ -1018,13 +1025,13 @@ static int matroxfb_ioctl(struct fb_info *info,
1018 changes = 0; 1025 changes = 0;
1019 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { 1026 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1020 if (tmp & (1 << i)) { 1027 if (tmp & (1 << i)) {
1021 if (ACCESS_FBINFO(outputs[i]).src != MATROXFB_SRC_CRTC1) { 1028 if (minfo->outputs[i].src != MATROXFB_SRC_CRTC1) {
1022 changes = 1; 1029 changes = 1;
1023 ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_CRTC1; 1030 minfo->outputs[i].src = MATROXFB_SRC_CRTC1;
1024 } 1031 }
1025 } else if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) { 1032 } else if (minfo->outputs[i].src == MATROXFB_SRC_CRTC1) {
1026 changes = 1; 1033 changes = 1;
1027 ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_NONE; 1034 minfo->outputs[i].src = MATROXFB_SRC_NONE;
1028 } 1035 }
1029 } 1036 }
1030 if (!changes) 1037 if (!changes)
@@ -1038,7 +1045,7 @@ static int matroxfb_ioctl(struct fb_info *info,
1038 int i; 1045 int i;
1039 1046
1040 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { 1047 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1041 if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) { 1048 if (minfo->outputs[i].src == MATROXFB_SRC_CRTC1) {
1042 conn |= 1 << i; 1049 conn |= 1 << i;
1043 } 1050 }
1044 } 1051 }
@@ -1052,8 +1059,8 @@ static int matroxfb_ioctl(struct fb_info *info,
1052 int i; 1059 int i;
1053 1060
1054 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { 1061 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1055 if (ACCESS_FBINFO(outputs[i]).output) { 1062 if (minfo->outputs[i].output) {
1056 switch (ACCESS_FBINFO(outputs[i]).src) { 1063 switch (minfo->outputs[i].src) {
1057 case MATROXFB_SRC_NONE: 1064 case MATROXFB_SRC_NONE:
1058 case MATROXFB_SRC_CRTC1: 1065 case MATROXFB_SRC_CRTC1:
1059 conn |= 1 << i; 1066 conn |= 1 << i;
@@ -1061,7 +1068,7 @@ static int matroxfb_ioctl(struct fb_info *info,
1061 } 1068 }
1062 } 1069 }
1063 } 1070 }
1064 if (ACCESS_FBINFO(devflags.panellink)) { 1071 if (minfo->devflags.panellink) {
1065 if (conn & MATROXFB_OUTPUT_CONN_DFP) 1072 if (conn & MATROXFB_OUTPUT_CONN_DFP)
1066 conn &= ~MATROXFB_OUTPUT_CONN_SECONDARY; 1073 conn &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
1067 if (conn & MATROXFB_OUTPUT_CONN_SECONDARY) 1074 if (conn & MATROXFB_OUTPUT_CONN_SECONDARY)
@@ -1077,7 +1084,7 @@ static int matroxfb_ioctl(struct fb_info *info,
1077 int i; 1084 int i;
1078 1085
1079 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { 1086 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1080 if (ACCESS_FBINFO(outputs[i]).output) { 1087 if (minfo->outputs[i].output) {
1081 conn |= 1 << i; 1088 conn |= 1 << i;
1082 } 1089 }
1083 } 1090 }
@@ -1092,7 +1099,7 @@ static int matroxfb_ioctl(struct fb_info *info,
1092 memset(&r, 0, sizeof(r)); 1099 memset(&r, 0, sizeof(r));
1093 strcpy(r.driver, "matroxfb"); 1100 strcpy(r.driver, "matroxfb");
1094 strcpy(r.card, "Matrox"); 1101 strcpy(r.card, "Matrox");
1095 sprintf(r.bus_info, "PCI:%s", pci_name(ACCESS_FBINFO(pcidev))); 1102 sprintf(r.bus_info, "PCI:%s", pci_name(minfo->pcidev));
1096 r.version = KERNEL_VERSION(1,0,0); 1103 r.version = KERNEL_VERSION(1,0,0);
1097 r.capabilities = V4L2_CAP_VIDEO_OUTPUT; 1104 r.capabilities = V4L2_CAP_VIDEO_OUTPUT;
1098 if (copy_to_user(argp, &r, sizeof(r))) 1105 if (copy_to_user(argp, &r, sizeof(r)))
@@ -1108,15 +1115,15 @@ static int matroxfb_ioctl(struct fb_info *info,
1108 if (copy_from_user(&qctrl, argp, sizeof(qctrl))) 1115 if (copy_from_user(&qctrl, argp, sizeof(qctrl)))
1109 return -EFAULT; 1116 return -EFAULT;
1110 1117
1111 down_read(&ACCESS_FBINFO(altout).lock); 1118 down_read(&minfo->altout.lock);
1112 if (!ACCESS_FBINFO(outputs[1]).output) { 1119 if (!minfo->outputs[1].output) {
1113 err = -ENXIO; 1120 err = -ENXIO;
1114 } else if (ACCESS_FBINFO(outputs[1]).output->getqueryctrl) { 1121 } else if (minfo->outputs[1].output->getqueryctrl) {
1115 err = ACCESS_FBINFO(outputs[1]).output->getqueryctrl(ACCESS_FBINFO(outputs[1]).data, &qctrl); 1122 err = minfo->outputs[1].output->getqueryctrl(minfo->outputs[1].data, &qctrl);
1116 } else { 1123 } else {
1117 err = -EINVAL; 1124 err = -EINVAL;
1118 } 1125 }
1119 up_read(&ACCESS_FBINFO(altout).lock); 1126 up_read(&minfo->altout.lock);
1120 if (err >= 0 && 1127 if (err >= 0 &&
1121 copy_to_user(argp, &qctrl, sizeof(qctrl))) 1128 copy_to_user(argp, &qctrl, sizeof(qctrl)))
1122 return -EFAULT; 1129 return -EFAULT;
@@ -1130,15 +1137,15 @@ static int matroxfb_ioctl(struct fb_info *info,
1130 if (copy_from_user(&ctrl, argp, sizeof(ctrl))) 1137 if (copy_from_user(&ctrl, argp, sizeof(ctrl)))
1131 return -EFAULT; 1138 return -EFAULT;
1132 1139
1133 down_read(&ACCESS_FBINFO(altout).lock); 1140 down_read(&minfo->altout.lock);
1134 if (!ACCESS_FBINFO(outputs[1]).output) { 1141 if (!minfo->outputs[1].output) {
1135 err = -ENXIO; 1142 err = -ENXIO;
1136 } else if (ACCESS_FBINFO(outputs[1]).output->getctrl) { 1143 } else if (minfo->outputs[1].output->getctrl) {
1137 err = ACCESS_FBINFO(outputs[1]).output->getctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); 1144 err = minfo->outputs[1].output->getctrl(minfo->outputs[1].data, &ctrl);
1138 } else { 1145 } else {
1139 err = -EINVAL; 1146 err = -EINVAL;
1140 } 1147 }
1141 up_read(&ACCESS_FBINFO(altout).lock); 1148 up_read(&minfo->altout.lock);
1142 if (err >= 0 && 1149 if (err >= 0 &&
1143 copy_to_user(argp, &ctrl, sizeof(ctrl))) 1150 copy_to_user(argp, &ctrl, sizeof(ctrl)))
1144 return -EFAULT; 1151 return -EFAULT;
@@ -1153,15 +1160,15 @@ static int matroxfb_ioctl(struct fb_info *info,
1153 if (copy_from_user(&ctrl, argp, sizeof(ctrl))) 1160 if (copy_from_user(&ctrl, argp, sizeof(ctrl)))
1154 return -EFAULT; 1161 return -EFAULT;
1155 1162
1156 down_read(&ACCESS_FBINFO(altout).lock); 1163 down_read(&minfo->altout.lock);
1157 if (!ACCESS_FBINFO(outputs[1]).output) { 1164 if (!minfo->outputs[1].output) {
1158 err = -ENXIO; 1165 err = -ENXIO;
1159 } else if (ACCESS_FBINFO(outputs[1]).output->setctrl) { 1166 } else if (minfo->outputs[1].output->setctrl) {
1160 err = ACCESS_FBINFO(outputs[1]).output->setctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); 1167 err = minfo->outputs[1].output->setctrl(minfo->outputs[1].data, &ctrl);
1161 } else { 1168 } else {
1162 err = -EINVAL; 1169 err = -EINVAL;
1163 } 1170 }
1164 up_read(&ACCESS_FBINFO(altout).lock); 1171 up_read(&minfo->altout.lock);
1165 return err; 1172 return err;
1166 } 1173 }
1167 } 1174 }
@@ -1175,11 +1182,11 @@ static int matroxfb_blank(int blank, struct fb_info *info)
1175 int seq; 1182 int seq;
1176 int crtc; 1183 int crtc;
1177 CRITFLAGS 1184 CRITFLAGS
1178 MINFO_FROM_INFO(info); 1185 struct matrox_fb_info *minfo = info2minfo(info);
1179 1186
1180 DBG(__func__) 1187 DBG(__func__)
1181 1188
1182 if (ACCESS_FBINFO(dead)) 1189 if (minfo->dead)
1183 return 1; 1190 return 1;
1184 1191
1185 switch (blank) { 1192 switch (blank) {
@@ -1281,7 +1288,9 @@ static char outputs[8]; /* "matrox:outputs:xxx" */
1281static char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */ 1288static char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */
1282#endif 1289#endif
1283 1290
1284static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSize){ 1291static int matroxfb_getmemory(struct matrox_fb_info *minfo,
1292 unsigned int maxSize, unsigned int *realSize)
1293{
1285 vaddr_t vm; 1294 vaddr_t vm;
1286 unsigned int offs; 1295 unsigned int offs;
1287 unsigned int offs2; 1296 unsigned int offs2;
@@ -1291,7 +1300,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
1291 1300
1292 DBG(__func__) 1301 DBG(__func__)
1293 1302
1294 vm = ACCESS_FBINFO(video.vbase); 1303 vm = minfo->video.vbase;
1295 maxSize &= ~0x1FFFFF; /* must be X*2MB (really it must be 2 or X*4MB) */ 1304 maxSize &= ~0x1FFFFF; /* must be X*2MB (really it must be 2 or X*4MB) */
1296 /* at least 2MB */ 1305 /* at least 2MB */
1297 if (maxSize < 0x0200000) return 0; 1306 if (maxSize < 0x0200000) return 0;
@@ -1323,7 +1332,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
1323 1332
1324 *realSize = offs - 0x100000; 1333 *realSize = offs - 0x100000;
1325#ifdef CONFIG_FB_MATROX_MILLENIUM 1334#ifdef CONFIG_FB_MATROX_MILLENIUM
1326 ACCESS_FBINFO(interleave) = !(!isMillenium(MINFO) || ((offs - 0x100000) & 0x3FFFFF)); 1335 minfo->interleave = !(!isMillenium(minfo) || ((offs - 0x100000) & 0x3FFFFF));
1327#endif 1336#endif
1328 return 1; 1337 return 1;
1329} 1338}
@@ -1345,13 +1354,9 @@ static struct video_board vbMystique = {0x0800000, 0x0800000, FB_ACCEL_MATROX_M
1345#ifdef CONFIG_FB_MATROX_G 1354#ifdef CONFIG_FB_MATROX_G
1346static struct video_board vbG100 = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100}; 1355static struct video_board vbG100 = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100};
1347static struct video_board vbG200 = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100}; 1356static struct video_board vbG200 = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100};
1348#ifdef CONFIG_FB_MATROX_32MB
1349/* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for 1357/* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for
1350 whole 32MB */ 1358 whole 32MB */
1351static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100}; 1359static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100};
1352#else
1353static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100};
1354#endif
1355#endif 1360#endif
1356 1361
1357#define DEVF_VIDEO64BIT 0x0001 1362#define DEVF_VIDEO64BIT 0x0001
@@ -1558,16 +1563,17 @@ static struct fb_videomode defaultmode = {
1558 1563
1559static int hotplug = 0; 1564static int hotplug = 0;
1560 1565
1561static void setDefaultOutputs(WPMINFO2) { 1566static void setDefaultOutputs(struct matrox_fb_info *minfo)
1567{
1562 unsigned int i; 1568 unsigned int i;
1563 const char* ptr; 1569 const char* ptr;
1564 1570
1565 ACCESS_FBINFO(outputs[0]).default_src = MATROXFB_SRC_CRTC1; 1571 minfo->outputs[0].default_src = MATROXFB_SRC_CRTC1;
1566 if (ACCESS_FBINFO(devflags.g450dac)) { 1572 if (minfo->devflags.g450dac) {
1567 ACCESS_FBINFO(outputs[1]).default_src = MATROXFB_SRC_CRTC1; 1573 minfo->outputs[1].default_src = MATROXFB_SRC_CRTC1;
1568 ACCESS_FBINFO(outputs[2]).default_src = MATROXFB_SRC_CRTC1; 1574 minfo->outputs[2].default_src = MATROXFB_SRC_CRTC1;
1569 } else if (dfp) { 1575 } else if (dfp) {
1570 ACCESS_FBINFO(outputs[2]).default_src = MATROXFB_SRC_CRTC1; 1576 minfo->outputs[2].default_src = MATROXFB_SRC_CRTC1;
1571 } 1577 }
1572 ptr = outputs; 1578 ptr = outputs;
1573 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { 1579 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
@@ -1577,11 +1583,11 @@ static void setDefaultOutputs(WPMINFO2) {
1577 break; 1583 break;
1578 } 1584 }
1579 if (c == '0') { 1585 if (c == '0') {
1580 ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_NONE; 1586 minfo->outputs[i].default_src = MATROXFB_SRC_NONE;
1581 } else if (c == '1') { 1587 } else if (c == '1') {
1582 ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_CRTC1; 1588 minfo->outputs[i].default_src = MATROXFB_SRC_CRTC1;
1583 } else if (c == '2' && ACCESS_FBINFO(devflags.crtc2)) { 1589 } else if (c == '2' && minfo->devflags.crtc2) {
1584 ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_CRTC2; 1590 minfo->outputs[i].default_src = MATROXFB_SRC_CRTC2;
1585 } else { 1591 } else {
1586 printk(KERN_ERR "matroxfb: Unknown outputs setting\n"); 1592 printk(KERN_ERR "matroxfb: Unknown outputs setting\n");
1587 break; 1593 break;
@@ -1591,7 +1597,8 @@ static void setDefaultOutputs(WPMINFO2) {
1591 outputs[0] = 0; 1597 outputs[0] = 0;
1592} 1598}
1593 1599
1594static int initMatrox2(WPMINFO struct board* b){ 1600static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
1601{
1595 unsigned long ctrlptr_phys = 0; 1602 unsigned long ctrlptr_phys = 0;
1596 unsigned long video_base_phys = 0; 1603 unsigned long video_base_phys = 0;
1597 unsigned int memsize; 1604 unsigned int memsize;
@@ -1607,58 +1614,56 @@ static int initMatrox2(WPMINFO struct board* b){
1607 /* set default values... */ 1614 /* set default values... */
1608 vesafb_defined.accel_flags = FB_ACCELF_TEXT; 1615 vesafb_defined.accel_flags = FB_ACCELF_TEXT;
1609 1616
1610 ACCESS_FBINFO(hw_switch) = b->base->lowlevel; 1617 minfo->hw_switch = b->base->lowlevel;
1611 ACCESS_FBINFO(devflags.accelerator) = b->base->accelID; 1618 minfo->devflags.accelerator = b->base->accelID;
1612 ACCESS_FBINFO(max_pixel_clock) = b->maxclk; 1619 minfo->max_pixel_clock = b->maxclk;
1613 1620
1614 printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name); 1621 printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name);
1615 ACCESS_FBINFO(capable.plnwt) = 1; 1622 minfo->capable.plnwt = 1;
1616 ACCESS_FBINFO(chip) = b->chip; 1623 minfo->chip = b->chip;
1617 ACCESS_FBINFO(capable.srcorg) = b->flags & DEVF_SRCORG; 1624 minfo->capable.srcorg = b->flags & DEVF_SRCORG;
1618 ACCESS_FBINFO(devflags.video64bits) = b->flags & DEVF_VIDEO64BIT; 1625 minfo->devflags.video64bits = b->flags & DEVF_VIDEO64BIT;
1619 if (b->flags & DEVF_TEXT4B) { 1626 if (b->flags & DEVF_TEXT4B) {
1620 ACCESS_FBINFO(devflags.vgastep) = 4; 1627 minfo->devflags.vgastep = 4;
1621 ACCESS_FBINFO(devflags.textmode) = 4; 1628 minfo->devflags.textmode = 4;
1622 ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16; 1629 minfo->devflags.text_type_aux = FB_AUX_TEXT_MGA_STEP16;
1623 } else if (b->flags & DEVF_TEXT16B) { 1630 } else if (b->flags & DEVF_TEXT16B) {
1624 ACCESS_FBINFO(devflags.vgastep) = 16; 1631 minfo->devflags.vgastep = 16;
1625 ACCESS_FBINFO(devflags.textmode) = 1; 1632 minfo->devflags.textmode = 1;
1626 ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16; 1633 minfo->devflags.text_type_aux = FB_AUX_TEXT_MGA_STEP16;
1627 } else { 1634 } else {
1628 ACCESS_FBINFO(devflags.vgastep) = 8; 1635 minfo->devflags.vgastep = 8;
1629 ACCESS_FBINFO(devflags.textmode) = 1; 1636 minfo->devflags.textmode = 1;
1630 ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP8; 1637 minfo->devflags.text_type_aux = FB_AUX_TEXT_MGA_STEP8;
1631 } 1638 }
1632#ifdef CONFIG_FB_MATROX_32MB 1639 minfo->devflags.support32MB = (b->flags & DEVF_SUPPORT32MB) != 0;
1633 ACCESS_FBINFO(devflags.support32MB) = (b->flags & DEVF_SUPPORT32MB) != 0; 1640 minfo->devflags.precise_width = !(b->flags & DEVF_ANY_VXRES);
1634#endif 1641 minfo->devflags.crtc2 = (b->flags & DEVF_CRTC2) != 0;
1635 ACCESS_FBINFO(devflags.precise_width) = !(b->flags & DEVF_ANY_VXRES); 1642 minfo->devflags.maven_capable = (b->flags & DEVF_MAVEN_CAPABLE) != 0;
1636 ACCESS_FBINFO(devflags.crtc2) = (b->flags & DEVF_CRTC2) != 0; 1643 minfo->devflags.dualhead = (b->flags & DEVF_DUALHEAD) != 0;
1637 ACCESS_FBINFO(devflags.maven_capable) = (b->flags & DEVF_MAVEN_CAPABLE) != 0; 1644 minfo->devflags.dfp_type = dfp_type;
1638 ACCESS_FBINFO(devflags.dualhead) = (b->flags & DEVF_DUALHEAD) != 0; 1645 minfo->devflags.g450dac = (b->flags & DEVF_G450DAC) != 0;
1639 ACCESS_FBINFO(devflags.dfp_type) = dfp_type; 1646 minfo->devflags.textstep = minfo->devflags.vgastep * minfo->devflags.textmode;
1640 ACCESS_FBINFO(devflags.g450dac) = (b->flags & DEVF_G450DAC) != 0; 1647 minfo->devflags.textvram = 65536 / minfo->devflags.textmode;
1641 ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode); 1648 setDefaultOutputs(minfo);
1642 ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode);
1643 setDefaultOutputs(PMINFO2);
1644 if (b->flags & DEVF_PANELLINK_CAPABLE) { 1649 if (b->flags & DEVF_PANELLINK_CAPABLE) {
1645 ACCESS_FBINFO(outputs[2]).data = MINFO; 1650 minfo->outputs[2].data = minfo;
1646 ACCESS_FBINFO(outputs[2]).output = &panellink_output; 1651 minfo->outputs[2].output = &panellink_output;
1647 ACCESS_FBINFO(outputs[2]).src = ACCESS_FBINFO(outputs[2]).default_src; 1652 minfo->outputs[2].src = minfo->outputs[2].default_src;
1648 ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 1653 minfo->outputs[2].mode = MATROXFB_OUTPUT_MODE_MONITOR;
1649 ACCESS_FBINFO(devflags.panellink) = 1; 1654 minfo->devflags.panellink = 1;
1650 } 1655 }
1651 1656
1652 if (ACCESS_FBINFO(capable.cross4MB) < 0) 1657 if (minfo->capable.cross4MB < 0)
1653 ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB; 1658 minfo->capable.cross4MB = b->flags & DEVF_CROSS4MB;
1654 if (b->flags & DEVF_SWAPS) { 1659 if (b->flags & DEVF_SWAPS) {
1655 ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); 1660 ctrlptr_phys = pci_resource_start(minfo->pcidev, 1);
1656 video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); 1661 video_base_phys = pci_resource_start(minfo->pcidev, 0);
1657 ACCESS_FBINFO(devflags.fbResource) = PCI_BASE_ADDRESS_0; 1662 minfo->devflags.fbResource = PCI_BASE_ADDRESS_0;
1658 } else { 1663 } else {
1659 ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); 1664 ctrlptr_phys = pci_resource_start(minfo->pcidev, 0);
1660 video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); 1665 video_base_phys = pci_resource_start(minfo->pcidev, 1);
1661 ACCESS_FBINFO(devflags.fbResource) = PCI_BASE_ADDRESS_1; 1666 minfo->devflags.fbResource = PCI_BASE_ADDRESS_1;
1662 } 1667 }
1663 err = -EINVAL; 1668 err = -EINVAL;
1664 if (!ctrlptr_phys) { 1669 if (!ctrlptr_phys) {
@@ -1676,7 +1681,7 @@ static int initMatrox2(WPMINFO struct board* b){
1676 if (!request_mem_region(video_base_phys, memsize, "matroxfb FB")) { 1681 if (!request_mem_region(video_base_phys, memsize, "matroxfb FB")) {
1677 goto failCtrlMR; 1682 goto failCtrlMR;
1678 } 1683 }
1679 ACCESS_FBINFO(video.len_maximum) = memsize; 1684 minfo->video.len_maximum = memsize;
1680 /* convert mem (autodetect k, M) */ 1685 /* convert mem (autodetect k, M) */
1681 if (mem < 1024) mem *= 1024; 1686 if (mem < 1024) mem *= 1024;
1682 if (mem < 0x00100000) mem *= 1024; 1687 if (mem < 0x00100000) mem *= 1024;
@@ -1684,14 +1689,14 @@ static int initMatrox2(WPMINFO struct board* b){
1684 if (mem && (mem < memsize)) 1689 if (mem && (mem < memsize))
1685 memsize = mem; 1690 memsize = mem;
1686 err = -ENOMEM; 1691 err = -ENOMEM;
1687 if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &ACCESS_FBINFO(mmio.vbase))) { 1692 if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &minfo->mmio.vbase)) {
1688 printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys); 1693 printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys);
1689 goto failVideoMR; 1694 goto failVideoMR;
1690 } 1695 }
1691 ACCESS_FBINFO(mmio.base) = ctrlptr_phys; 1696 minfo->mmio.base = ctrlptr_phys;
1692 ACCESS_FBINFO(mmio.len) = 16384; 1697 minfo->mmio.len = 16384;
1693 ACCESS_FBINFO(video.base) = video_base_phys; 1698 minfo->video.base = video_base_phys;
1694 if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) { 1699 if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &minfo->video.vbase)) {
1695 printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n", 1700 printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n",
1696 video_base_phys, memsize); 1701 video_base_phys, memsize);
1697 goto failCtrlIO; 1702 goto failCtrlIO;
@@ -1700,63 +1705,63 @@ static int initMatrox2(WPMINFO struct board* b){
1700 u_int32_t cmd; 1705 u_int32_t cmd;
1701 u_int32_t mga_option; 1706 u_int32_t mga_option;
1702 1707
1703 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, &mga_option); 1708 pci_read_config_dword(minfo->pcidev, PCI_OPTION_REG, &mga_option);
1704 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd); 1709 pci_read_config_dword(minfo->pcidev, PCI_COMMAND, &cmd);
1705 mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ 1710 mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */
1706 mga_option |= MX_OPTION_BSWAP; 1711 mga_option |= MX_OPTION_BSWAP;
1707 /* disable palette snooping */ 1712 /* disable palette snooping */
1708 cmd &= ~PCI_COMMAND_VGA_PALETTE; 1713 cmd &= ~PCI_COMMAND_VGA_PALETTE;
1709 if (pci_dev_present(intel_82437)) { 1714 if (pci_dev_present(intel_82437)) {
1710 if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) { 1715 if (!(mga_option & 0x20000000) && !minfo->devflags.nopciretry) {
1711 printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); 1716 printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n");
1712 } 1717 }
1713 mga_option |= 0x20000000; 1718 mga_option |= 0x20000000;
1714 ACCESS_FBINFO(devflags.nopciretry) = 1; 1719 minfo->devflags.nopciretry = 1;
1715 } 1720 }
1716 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, cmd); 1721 pci_write_config_dword(minfo->pcidev, PCI_COMMAND, cmd);
1717 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mga_option); 1722 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mga_option);
1718 ACCESS_FBINFO(hw).MXoptionReg = mga_option; 1723 minfo->hw.MXoptionReg = mga_option;
1719 1724
1720 /* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */ 1725 /* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */
1721 /* maybe preinit() candidate, but it is same... for all devices... at this time... */ 1726 /* maybe preinit() candidate, but it is same... for all devices... at this time... */
1722 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MGA_INDEX, 0x00003C00); 1727 pci_write_config_dword(minfo->pcidev, PCI_MGA_INDEX, 0x00003C00);
1723 } 1728 }
1724 1729
1725 err = -ENXIO; 1730 err = -ENXIO;
1726 matroxfb_read_pins(PMINFO2); 1731 matroxfb_read_pins(minfo);
1727 if (ACCESS_FBINFO(hw_switch)->preinit(PMINFO2)) { 1732 if (minfo->hw_switch->preinit(minfo)) {
1728 goto failVideoIO; 1733 goto failVideoIO;
1729 } 1734 }
1730 1735
1731 err = -ENOMEM; 1736 err = -ENOMEM;
1732 if (!matroxfb_getmemory(PMINFO memsize, &ACCESS_FBINFO(video.len)) || !ACCESS_FBINFO(video.len)) { 1737 if (!matroxfb_getmemory(minfo, memsize, &minfo->video.len) || !minfo->video.len) {
1733 printk(KERN_ERR "matroxfb: cannot determine memory size\n"); 1738 printk(KERN_ERR "matroxfb: cannot determine memory size\n");
1734 goto failVideoIO; 1739 goto failVideoIO;
1735 } 1740 }
1736 ACCESS_FBINFO(devflags.ydstorg) = 0; 1741 minfo->devflags.ydstorg = 0;
1737 1742
1738 ACCESS_FBINFO(video.base) = video_base_phys; 1743 minfo->video.base = video_base_phys;
1739 ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len); 1744 minfo->video.len_usable = minfo->video.len;
1740 if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable) 1745 if (minfo->video.len_usable > b->base->maxdisplayable)
1741 ACCESS_FBINFO(video.len_usable) = b->base->maxdisplayable; 1746 minfo->video.len_usable = b->base->maxdisplayable;
1742#ifdef CONFIG_MTRR 1747#ifdef CONFIG_MTRR
1743 if (mtrr) { 1748 if (mtrr) {
1744 ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1); 1749 minfo->mtrr.vram = mtrr_add(video_base_phys, minfo->video.len, MTRR_TYPE_WRCOMB, 1);
1745 ACCESS_FBINFO(mtrr.vram_valid) = 1; 1750 minfo->mtrr.vram_valid = 1;
1746 printk(KERN_INFO "matroxfb: MTRR's turned on\n"); 1751 printk(KERN_INFO "matroxfb: MTRR's turned on\n");
1747 } 1752 }
1748#endif /* CONFIG_MTRR */ 1753#endif /* CONFIG_MTRR */
1749 1754
1750 if (!ACCESS_FBINFO(devflags.novga)) 1755 if (!minfo->devflags.novga)
1751 request_region(0x3C0, 32, "matrox"); 1756 request_region(0x3C0, 32, "matrox");
1752 matroxfb_g450_connect(PMINFO2); 1757 matroxfb_g450_connect(minfo);
1753 ACCESS_FBINFO(hw_switch->reset(PMINFO2)); 1758 minfo->hw_switch->reset(minfo);
1754 1759
1755 ACCESS_FBINFO(fbcon.monspecs.hfmin) = 0; 1760 minfo->fbcon.monspecs.hfmin = 0;
1756 ACCESS_FBINFO(fbcon.monspecs.hfmax) = fh; 1761 minfo->fbcon.monspecs.hfmax = fh;
1757 ACCESS_FBINFO(fbcon.monspecs.vfmin) = 0; 1762 minfo->fbcon.monspecs.vfmin = 0;
1758 ACCESS_FBINFO(fbcon.monspecs.vfmax) = fv; 1763 minfo->fbcon.monspecs.vfmax = fv;
1759 ACCESS_FBINFO(fbcon.monspecs.dpms) = 0; /* TBD */ 1764 minfo->fbcon.monspecs.dpms = 0; /* TBD */
1760 1765
1761 /* static settings */ 1766 /* static settings */
1762 vesafb_defined.red = colors[depth-1].red; 1767 vesafb_defined.red = colors[depth-1].red;
@@ -1768,24 +1773,24 @@ static int initMatrox2(WPMINFO struct board* b){
1768 if (noaccel) 1773 if (noaccel)
1769 vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT; 1774 vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT;
1770 1775
1771 ACCESS_FBINFO(fbops) = matroxfb_ops; 1776 minfo->fbops = matroxfb_ops;
1772 ACCESS_FBINFO(fbcon.fbops) = &ACCESS_FBINFO(fbops); 1777 minfo->fbcon.fbops = &minfo->fbops;
1773 ACCESS_FBINFO(fbcon.pseudo_palette) = ACCESS_FBINFO(cmap); 1778 minfo->fbcon.pseudo_palette = minfo->cmap;
1774 /* after __init time we are like module... no logo */ 1779 /* after __init time we are like module... no logo */
1775 ACCESS_FBINFO(fbcon.flags) = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT; 1780 minfo->fbcon.flags = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT;
1776 ACCESS_FBINFO(fbcon.flags) |= FBINFO_PARTIAL_PAN_OK | /* Prefer panning for scroll under MC viewer/edit */ 1781 minfo->fbcon.flags |= FBINFO_PARTIAL_PAN_OK | /* Prefer panning for scroll under MC viewer/edit */
1777 FBINFO_HWACCEL_COPYAREA | /* We have hw-assisted bmove */ 1782 FBINFO_HWACCEL_COPYAREA | /* We have hw-assisted bmove */
1778 FBINFO_HWACCEL_FILLRECT | /* And fillrect */ 1783 FBINFO_HWACCEL_FILLRECT | /* And fillrect */
1779 FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */ 1784 FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */
1780 FBINFO_HWACCEL_XPAN | /* And we support both horizontal */ 1785 FBINFO_HWACCEL_XPAN | /* And we support both horizontal */
1781 FBINFO_HWACCEL_YPAN; /* And vertical panning */ 1786 FBINFO_HWACCEL_YPAN; /* And vertical panning */
1782 ACCESS_FBINFO(video.len_usable) &= PAGE_MASK; 1787 minfo->video.len_usable &= PAGE_MASK;
1783 fb_alloc_cmap(&ACCESS_FBINFO(fbcon.cmap), 256, 1); 1788 fb_alloc_cmap(&minfo->fbcon.cmap, 256, 1);
1784 1789
1785#ifndef MODULE 1790#ifndef MODULE
1786 /* mode database is marked __init!!! */ 1791 /* mode database is marked __init!!! */
1787 if (!hotplug) { 1792 if (!hotplug) {
1788 fb_find_mode(&vesafb_defined, &ACCESS_FBINFO(fbcon), videomode[0]?videomode:NULL, 1793 fb_find_mode(&vesafb_defined, &minfo->fbcon, videomode[0] ? videomode : NULL,
1789 NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel); 1794 NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel);
1790 } 1795 }
1791#endif /* !MODULE */ 1796#endif /* !MODULE */
@@ -1874,52 +1879,52 @@ static int initMatrox2(WPMINFO struct board* b){
1874 vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough 1879 vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough
1875 to yres_virtual * xres_virtual < 2^32 */ 1880 to yres_virtual * xres_virtual < 2^32 */
1876 } 1881 }
1877 matroxfb_init_fix(PMINFO2); 1882 matroxfb_init_fix(minfo);
1878 ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)); 1883 minfo->fbcon.screen_base = vaddr_va(minfo->video.vbase);
1879 /* Normalize values (namely yres_virtual) */ 1884 /* Normalize values (namely yres_virtual) */
1880 matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon)); 1885 matroxfb_check_var(&vesafb_defined, &minfo->fbcon);
1881 /* And put it into "current" var. Do NOT program hardware yet, or we'll not take over 1886 /* And put it into "current" var. Do NOT program hardware yet, or we'll not take over
1882 * vgacon correctly. fbcon_startup will call fb_set_par for us, WITHOUT check_var, 1887 * vgacon correctly. fbcon_startup will call fb_set_par for us, WITHOUT check_var,
1883 * and unfortunately it will do it BEFORE vgacon contents is saved, so it won't work 1888 * and unfortunately it will do it BEFORE vgacon contents is saved, so it won't work
1884 * anyway. But we at least tried... */ 1889 * anyway. But we at least tried... */
1885 ACCESS_FBINFO(fbcon.var) = vesafb_defined; 1890 minfo->fbcon.var = vesafb_defined;
1886 err = -EINVAL; 1891 err = -EINVAL;
1887 1892
1888 printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n", 1893 printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n",
1889 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, 1894 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel,
1890 vesafb_defined.xres_virtual, vesafb_defined.yres_virtual); 1895 vesafb_defined.xres_virtual, vesafb_defined.yres_virtual);
1891 printk(KERN_INFO "matroxfb: framebuffer at 0x%lX, mapped to 0x%p, size %d\n", 1896 printk(KERN_INFO "matroxfb: framebuffer at 0x%lX, mapped to 0x%p, size %d\n",
1892 ACCESS_FBINFO(video.base), vaddr_va(ACCESS_FBINFO(video.vbase)), ACCESS_FBINFO(video.len)); 1897 minfo->video.base, vaddr_va(minfo->video.vbase), minfo->video.len);
1893 1898
1894/* We do not have to set currcon to 0... register_framebuffer do it for us on first console 1899/* We do not have to set currcon to 0... register_framebuffer do it for us on first console
1895 * and we do not want currcon == 0 for subsequent framebuffers */ 1900 * and we do not want currcon == 0 for subsequent framebuffers */
1896 1901
1897 ACCESS_FBINFO(fbcon).device = &ACCESS_FBINFO(pcidev)->dev; 1902 minfo->fbcon.device = &minfo->pcidev->dev;
1898 if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) { 1903 if (register_framebuffer(&minfo->fbcon) < 0) {
1899 goto failVideoIO; 1904 goto failVideoIO;
1900 } 1905 }
1901 printk("fb%d: %s frame buffer device\n", 1906 printk("fb%d: %s frame buffer device\n",
1902 ACCESS_FBINFO(fbcon.node), ACCESS_FBINFO(fbcon.fix.id)); 1907 minfo->fbcon.node, minfo->fbcon.fix.id);
1903 1908
1904 /* there is no console on this fb... but we have to initialize hardware 1909 /* there is no console on this fb... but we have to initialize hardware
1905 * until someone tells me what is proper thing to do */ 1910 * until someone tells me what is proper thing to do */
1906 if (!ACCESS_FBINFO(initialized)) { 1911 if (!minfo->initialized) {
1907 printk(KERN_INFO "fb%d: initializing hardware\n", 1912 printk(KERN_INFO "fb%d: initializing hardware\n",
1908 ACCESS_FBINFO(fbcon.node)); 1913 minfo->fbcon.node);
1909 /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var 1914 /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var
1910 * already before, so register_framebuffer works correctly. */ 1915 * already before, so register_framebuffer works correctly. */
1911 vesafb_defined.activate |= FB_ACTIVATE_FORCE; 1916 vesafb_defined.activate |= FB_ACTIVATE_FORCE;
1912 fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); 1917 fb_set_var(&minfo->fbcon, &vesafb_defined);
1913 } 1918 }
1914 1919
1915 return 0; 1920 return 0;
1916failVideoIO:; 1921failVideoIO:;
1917 matroxfb_g450_shutdown(PMINFO2); 1922 matroxfb_g450_shutdown(minfo);
1918 mga_iounmap(ACCESS_FBINFO(video.vbase)); 1923 mga_iounmap(minfo->video.vbase);
1919failCtrlIO:; 1924failCtrlIO:;
1920 mga_iounmap(ACCESS_FBINFO(mmio.vbase)); 1925 mga_iounmap(minfo->mmio.vbase);
1921failVideoMR:; 1926failVideoMR:;
1922 release_mem_region(video_base_phys, ACCESS_FBINFO(video.len_maximum)); 1927 release_mem_region(video_base_phys, minfo->video.len_maximum);
1923failCtrlMR:; 1928failCtrlMR:;
1924 release_mem_region(ctrlptr_phys, 16384); 1929 release_mem_region(ctrlptr_phys, 16384);
1925fail:; 1930fail:;
@@ -1975,7 +1980,7 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv) {
1975static void matroxfb_register_device(struct matrox_fb_info* minfo) { 1980static void matroxfb_register_device(struct matrox_fb_info* minfo) {
1976 struct matroxfb_driver* drv; 1981 struct matroxfb_driver* drv;
1977 int i = 0; 1982 int i = 0;
1978 list_add(&ACCESS_FBINFO(next_fb), &matroxfb_list); 1983 list_add(&minfo->next_fb, &matroxfb_list);
1979 for (drv = matroxfb_driver_l(matroxfb_driver_list.next); 1984 for (drv = matroxfb_driver_l(matroxfb_driver_list.next);
1980 drv != matroxfb_driver_l(&matroxfb_driver_list); 1985 drv != matroxfb_driver_l(&matroxfb_driver_list);
1981 drv = matroxfb_driver_l(drv->node.next)) { 1986 drv = matroxfb_driver_l(drv->node.next)) {
@@ -1995,7 +2000,7 @@ static void matroxfb_register_device(struct matrox_fb_info* minfo) {
1995static void matroxfb_unregister_device(struct matrox_fb_info* minfo) { 2000static void matroxfb_unregister_device(struct matrox_fb_info* minfo) {
1996 int i; 2001 int i;
1997 2002
1998 list_del(&ACCESS_FBINFO(next_fb)); 2003 list_del(&minfo->next_fb);
1999 for (i = 0; i < minfo->drivers_count; i++) { 2004 for (i = 0; i < minfo->drivers_count; i++) {
2000 struct matroxfb_driver* drv = minfo->drivers[i]; 2005 struct matroxfb_driver* drv = minfo->drivers[i];
2001 2006
@@ -2011,9 +2016,6 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
2011 struct matrox_fb_info* minfo; 2016 struct matrox_fb_info* minfo;
2012 int err; 2017 int err;
2013 u_int32_t cmd; 2018 u_int32_t cmd;
2014#ifndef CONFIG_FB_MATROX_MULTIHEAD
2015 static int registered = 0;
2016#endif
2017 DBG(__func__) 2019 DBG(__func__)
2018 2020
2019 svid = pdev->subsystem_vendor; 2021 svid = pdev->subsystem_vendor;
@@ -2037,68 +2039,57 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
2037 return -1; 2039 return -1;
2038 } 2040 }
2039 2041
2040#ifdef CONFIG_FB_MATROX_MULTIHEAD
2041 minfo = kmalloc(sizeof(*minfo), GFP_KERNEL); 2042 minfo = kmalloc(sizeof(*minfo), GFP_KERNEL);
2042 if (!minfo) 2043 if (!minfo)
2043 return -1; 2044 return -1;
2044#else 2045 memset(minfo, 0, sizeof(*minfo));
2045 if (registered) /* singlehead driver... */
2046 return -1;
2047 minfo = &matroxfb_global_mxinfo;
2048#endif
2049 memset(MINFO, 0, sizeof(*MINFO));
2050 2046
2051 ACCESS_FBINFO(pcidev) = pdev; 2047 minfo->pcidev = pdev;
2052 ACCESS_FBINFO(dead) = 0; 2048 minfo->dead = 0;
2053 ACCESS_FBINFO(usecount) = 0; 2049 minfo->usecount = 0;
2054 ACCESS_FBINFO(userusecount) = 0; 2050 minfo->userusecount = 0;
2055 2051
2056 pci_set_drvdata(pdev, MINFO); 2052 pci_set_drvdata(pdev, minfo);
2057 /* DEVFLAGS */ 2053 /* DEVFLAGS */
2058 ACCESS_FBINFO(devflags.memtype) = memtype; 2054 minfo->devflags.memtype = memtype;
2059 if (memtype != -1) 2055 if (memtype != -1)
2060 noinit = 0; 2056 noinit = 0;
2061 if (cmd & PCI_COMMAND_MEMORY) { 2057 if (cmd & PCI_COMMAND_MEMORY) {
2062 ACCESS_FBINFO(devflags.novga) = novga; 2058 minfo->devflags.novga = novga;
2063 ACCESS_FBINFO(devflags.nobios) = nobios; 2059 minfo->devflags.nobios = nobios;
2064 ACCESS_FBINFO(devflags.noinit) = noinit; 2060 minfo->devflags.noinit = noinit;
2065 /* subsequent heads always needs initialization and must not enable BIOS */ 2061 /* subsequent heads always needs initialization and must not enable BIOS */
2066 novga = 1; 2062 novga = 1;
2067 nobios = 1; 2063 nobios = 1;
2068 noinit = 0; 2064 noinit = 0;
2069 } else { 2065 } else {
2070 ACCESS_FBINFO(devflags.novga) = 1; 2066 minfo->devflags.novga = 1;
2071 ACCESS_FBINFO(devflags.nobios) = 1; 2067 minfo->devflags.nobios = 1;
2072 ACCESS_FBINFO(devflags.noinit) = 0; 2068 minfo->devflags.noinit = 0;
2073 } 2069 }
2074 2070
2075 ACCESS_FBINFO(devflags.nopciretry) = no_pci_retry; 2071 minfo->devflags.nopciretry = no_pci_retry;
2076 ACCESS_FBINFO(devflags.mga_24bpp_fix) = inv24; 2072 minfo->devflags.mga_24bpp_fix = inv24;
2077 ACCESS_FBINFO(devflags.precise_width) = option_precise_width; 2073 minfo->devflags.precise_width = option_precise_width;
2078 ACCESS_FBINFO(devflags.sgram) = sgram; 2074 minfo->devflags.sgram = sgram;
2079 ACCESS_FBINFO(capable.cross4MB) = cross4MB; 2075 minfo->capable.cross4MB = cross4MB;
2080 2076
2081 spin_lock_init(&ACCESS_FBINFO(lock.DAC)); 2077 spin_lock_init(&minfo->lock.DAC);
2082 spin_lock_init(&ACCESS_FBINFO(lock.accel)); 2078 spin_lock_init(&minfo->lock.accel);
2083 init_rwsem(&ACCESS_FBINFO(crtc2.lock)); 2079 init_rwsem(&minfo->crtc2.lock);
2084 init_rwsem(&ACCESS_FBINFO(altout.lock)); 2080 init_rwsem(&minfo->altout.lock);
2085 mutex_init(&ACCESS_FBINFO(fbcon).mm_lock); 2081 mutex_init(&minfo->fbcon.mm_lock);
2086 ACCESS_FBINFO(irq_flags) = 0; 2082 minfo->irq_flags = 0;
2087 init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait)); 2083 init_waitqueue_head(&minfo->crtc1.vsync.wait);
2088 init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait)); 2084 init_waitqueue_head(&minfo->crtc2.vsync.wait);
2089 ACCESS_FBINFO(crtc1.panpos) = -1; 2085 minfo->crtc1.panpos = -1;
2090 2086
2091 err = initMatrox2(PMINFO b); 2087 err = initMatrox2(minfo, b);
2092 if (!err) { 2088 if (!err) {
2093#ifndef CONFIG_FB_MATROX_MULTIHEAD 2089 matroxfb_register_device(minfo);
2094 registered = 1;
2095#endif
2096 matroxfb_register_device(MINFO);
2097 return 0; 2090 return 0;
2098 } 2091 }
2099#ifdef CONFIG_FB_MATROX_MULTIHEAD
2100 kfree(minfo); 2092 kfree(minfo);
2101#endif
2102 return -1; 2093 return -1;
2103} 2094}
2104 2095
@@ -2106,7 +2097,7 @@ static void pci_remove_matrox(struct pci_dev* pdev) {
2106 struct matrox_fb_info* minfo; 2097 struct matrox_fb_info* minfo;
2107 2098
2108 minfo = pci_get_drvdata(pdev); 2099 minfo = pci_get_drvdata(pdev);
2109 matroxfb_remove(PMINFO 1); 2100 matroxfb_remove(minfo, 1);
2110} 2101}
2111 2102
2112static struct pci_device_id matroxfb_devices[] = { 2103static struct pci_device_id matroxfb_devices[] = {
@@ -2510,13 +2501,8 @@ module_param(inv24, int, 0);
2510MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)"); 2501MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)");
2511module_param(inverse, int, 0); 2502module_param(inverse, int, 0);
2512MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)"); 2503MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)");
2513#ifdef CONFIG_FB_MATROX_MULTIHEAD
2514module_param(dev, int, 0); 2504module_param(dev, int, 0);
2515MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)"); 2505MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)");
2516#else
2517module_param(dev, int, 0);
2518MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=first working)");
2519#endif
2520module_param(vesa, int, 0); 2506module_param(vesa, int, 0);
2521MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)"); 2507MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)");
2522module_param(xres, int, 0); 2508module_param(xres, int, 0);
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index 95883236c0cd..f3a4e15672d9 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -54,9 +54,6 @@
54#include "../macmodes.h" 54#include "../macmodes.h"
55#endif 55#endif
56 56
57/* always compile support for 32MB... It cost almost nothing */
58#define CONFIG_FB_MATROX_32MB
59
60#ifdef MATROXFB_DEBUG 57#ifdef MATROXFB_DEBUG
61 58
62#define DEBUG 59#define DEBUG
@@ -464,9 +461,7 @@ struct matrox_fb_info {
464 int nopciretry; 461 int nopciretry;
465 int noinit; 462 int noinit;
466 int sgram; 463 int sgram;
467#ifdef CONFIG_FB_MATROX_32MB
468 int support32MB; 464 int support32MB;
469#endif
470 465
471 int accelerator; 466 int accelerator;
472 int text_type_aux; 467 int text_type_aux;
@@ -524,47 +519,11 @@ struct matrox_fb_info {
524 519
525#define info2minfo(info) container_of(info, struct matrox_fb_info, fbcon) 520#define info2minfo(info) container_of(info, struct matrox_fb_info, fbcon)
526 521
527#ifdef CONFIG_FB_MATROX_MULTIHEAD
528#define ACCESS_FBINFO2(info, x) (info->x)
529#define ACCESS_FBINFO(x) ACCESS_FBINFO2(minfo,x)
530
531#define MINFO minfo
532
533#define WPMINFO2 struct matrox_fb_info* minfo
534#define WPMINFO WPMINFO2 ,
535#define CPMINFO2 const struct matrox_fb_info* minfo
536#define CPMINFO CPMINFO2 ,
537#define PMINFO2 minfo
538#define PMINFO PMINFO2 ,
539
540#define MINFO_FROM(x) struct matrox_fb_info* minfo = x
541#else
542
543extern struct matrox_fb_info matroxfb_global_mxinfo;
544
545#define ACCESS_FBINFO(x) (matroxfb_global_mxinfo.x)
546#define ACCESS_FBINFO2(info, x) (matroxfb_global_mxinfo.x)
547
548#define MINFO (&matroxfb_global_mxinfo)
549
550#define WPMINFO2 void
551#define WPMINFO
552#define CPMINFO2 void
553#define CPMINFO
554#define PMINFO2
555#define PMINFO
556
557#define MINFO_FROM(x)
558
559#endif
560
561#define MINFO_FROM_INFO(x) MINFO_FROM(info2minfo(x))
562
563struct matrox_switch { 522struct matrox_switch {
564 int (*preinit)(WPMINFO2); 523 int (*preinit)(struct matrox_fb_info *minfo);
565 void (*reset)(WPMINFO2); 524 void (*reset)(struct matrox_fb_info *minfo);
566 int (*init)(WPMINFO struct my_timming*); 525 int (*init)(struct matrox_fb_info *minfo, struct my_timming*);
567 void (*restore)(WPMINFO2); 526 void (*restore)(struct matrox_fb_info *minfo);
568}; 527};
569 528
570struct matroxfb_driver { 529struct matroxfb_driver {
@@ -727,11 +686,11 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv);
727#endif 686#endif
728#endif 687#endif
729 688
730#define mga_inb(addr) mga_readb(ACCESS_FBINFO(mmio.vbase), (addr)) 689#define mga_inb(addr) mga_readb(minfo->mmio.vbase, (addr))
731#define mga_inl(addr) mga_readl(ACCESS_FBINFO(mmio.vbase), (addr)) 690#define mga_inl(addr) mga_readl(minfo->mmio.vbase, (addr))
732#define mga_outb(addr,val) mga_writeb(ACCESS_FBINFO(mmio.vbase), (addr), (val)) 691#define mga_outb(addr,val) mga_writeb(minfo->mmio.vbase, (addr), (val))
733#define mga_outw(addr,val) mga_writew(ACCESS_FBINFO(mmio.vbase), (addr), (val)) 692#define mga_outw(addr,val) mga_writew(minfo->mmio.vbase, (addr), (val))
734#define mga_outl(addr,val) mga_writel(ACCESS_FBINFO(mmio.vbase), (addr), (val)) 693#define mga_outl(addr,val) mga_writel(minfo->mmio.vbase, (addr), (val))
735#define mga_readr(port,idx) (mga_outb((port),(idx)), mga_inb((port)+1)) 694#define mga_readr(port,idx) (mga_outb((port),(idx)), mga_inb((port)+1))
736#define mga_setr(addr,port,val) mga_outw(addr, ((val)<<8) | (port)) 695#define mga_setr(addr,port,val) mga_outw(addr, ((val)<<8) | (port))
737 696
@@ -750,19 +709,20 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv);
750#define isMilleniumII(x) (0) 709#define isMilleniumII(x) (0)
751#endif 710#endif
752 711
753#define matroxfb_DAC_lock() spin_lock(&ACCESS_FBINFO(lock.DAC)) 712#define matroxfb_DAC_lock() spin_lock(&minfo->lock.DAC)
754#define matroxfb_DAC_unlock() spin_unlock(&ACCESS_FBINFO(lock.DAC)) 713#define matroxfb_DAC_unlock() spin_unlock(&minfo->lock.DAC)
755#define matroxfb_DAC_lock_irqsave(flags) spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC),flags) 714#define matroxfb_DAC_lock_irqsave(flags) spin_lock_irqsave(&minfo->lock.DAC, flags)
756#define matroxfb_DAC_unlock_irqrestore(flags) spin_unlock_irqrestore(&ACCESS_FBINFO(lock.DAC),flags) 715#define matroxfb_DAC_unlock_irqrestore(flags) spin_unlock_irqrestore(&minfo->lock.DAC, flags)
757extern void matroxfb_DAC_out(CPMINFO int reg, int val); 716extern void matroxfb_DAC_out(const struct matrox_fb_info *minfo, int reg,
758extern int matroxfb_DAC_in(CPMINFO int reg); 717 int val);
718extern int matroxfb_DAC_in(const struct matrox_fb_info *minfo, int reg);
759extern void matroxfb_var2my(struct fb_var_screeninfo* fvsi, struct my_timming* mt); 719extern void matroxfb_var2my(struct fb_var_screeninfo* fvsi, struct my_timming* mt);
760extern int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc); 720extern int matroxfb_wait_for_sync(struct matrox_fb_info *minfo, u_int32_t crtc);
761extern int matroxfb_enable_irq(WPMINFO int reenable); 721extern int matroxfb_enable_irq(struct matrox_fb_info *minfo, int reenable);
762 722
763#ifdef MATROXFB_USE_SPINLOCKS 723#ifdef MATROXFB_USE_SPINLOCKS
764#define CRITBEGIN spin_lock_irqsave(&ACCESS_FBINFO(lock.accel), critflags); 724#define CRITBEGIN spin_lock_irqsave(&minfo->lock.accel, critflags);
765#define CRITEND spin_unlock_irqrestore(&ACCESS_FBINFO(lock.accel), critflags); 725#define CRITEND spin_unlock_irqrestore(&minfo->lock.accel, critflags);
766#define CRITFLAGS unsigned long critflags; 726#define CRITFLAGS unsigned long critflags;
767#else 727#else
768#define CRITBEGIN 728#define CRITBEGIN
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index ebcb5c6b4962..78414baa5a54 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -65,7 +65,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
65 unsigned int pos) { 65 unsigned int pos) {
66 u_int32_t tmp; 66 u_int32_t tmp;
67 u_int32_t datactl; 67 u_int32_t datactl;
68 MINFO_FROM(m2info->primary_dev); 68 struct matrox_fb_info *minfo = m2info->primary_dev;
69 69
70 switch (mode) { 70 switch (mode) {
71 case 15: 71 case 15:
@@ -81,11 +81,11 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
81 } 81 }
82 tmp |= 0x00000001; /* enable CRTC2 */ 82 tmp |= 0x00000001; /* enable CRTC2 */
83 datactl = 0; 83 datactl = 0;
84 if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) { 84 if (minfo->outputs[1].src == MATROXFB_SRC_CRTC2) {
85 if (ACCESS_FBINFO(devflags.g450dac)) { 85 if (minfo->devflags.g450dac) {
86 tmp |= 0x00000006; /* source from secondary pixel PLL */ 86 tmp |= 0x00000006; /* source from secondary pixel PLL */
87 /* no vidrst when in monitor mode */ 87 /* no vidrst when in monitor mode */
88 if (ACCESS_FBINFO(outputs[1]).mode != MATROXFB_OUTPUT_MODE_MONITOR) { 88 if (minfo->outputs[1].mode != MATROXFB_OUTPUT_MODE_MONITOR) {
89 tmp |= 0xC0001000; /* Enable H/V vidrst */ 89 tmp |= 0xC0001000; /* Enable H/V vidrst */
90 } 90 }
91 } else { 91 } else {
@@ -93,11 +93,11 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
93 tmp |= 0xC0000000; /* enable vvidrst & hvidrst */ 93 tmp |= 0xC0000000; /* enable vvidrst & hvidrst */
94 /* MGA TVO is our clock source */ 94 /* MGA TVO is our clock source */
95 } 95 }
96 } else if (ACCESS_FBINFO(outputs[0]).src == MATROXFB_SRC_CRTC2) { 96 } else if (minfo->outputs[0].src == MATROXFB_SRC_CRTC2) {
97 tmp |= 0x00000004; /* source from pixclock */ 97 tmp |= 0x00000004; /* source from pixclock */
98 /* PIXPLL is our clock source */ 98 /* PIXPLL is our clock source */
99 } 99 }
100 if (ACCESS_FBINFO(outputs[0]).src == MATROXFB_SRC_CRTC2) { 100 if (minfo->outputs[0].src == MATROXFB_SRC_CRTC2) {
101 tmp |= 0x00100000; /* connect CRTC2 to DAC */ 101 tmp |= 0x00100000; /* connect CRTC2 to DAC */
102 } 102 }
103 if (mt->interlaced) { 103 if (mt->interlaced) {
@@ -146,7 +146,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
146 } 146 }
147 } 147 }
148 mga_outl(0x3C10, tmp); 148 mga_outl(0x3C10, tmp);
149 ACCESS_FBINFO(hw).crtc2.ctl = tmp; 149 minfo->hw.crtc2.ctl = tmp;
150 150
151 tmp = mt->VDisplay << 16; /* line compare */ 151 tmp = mt->VDisplay << 16; /* line compare */
152 if (mt->sync & FB_SYNC_HOR_HIGH_ACT) 152 if (mt->sync & FB_SYNC_HOR_HIGH_ACT)
@@ -157,10 +157,10 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
157} 157}
158 158
159static void matroxfb_dh_disable(struct matroxfb_dh_fb_info* m2info) { 159static void matroxfb_dh_disable(struct matroxfb_dh_fb_info* m2info) {
160 MINFO_FROM(m2info->primary_dev); 160 struct matrox_fb_info *minfo = m2info->primary_dev;
161 161
162 mga_outl(0x3C10, 0x00000004); /* disable CRTC2, CRTC1->DAC1, PLL as clock source */ 162 mga_outl(0x3C10, 0x00000004); /* disable CRTC2, CRTC1->DAC1, PLL as clock source */
163 ACCESS_FBINFO(hw).crtc2.ctl = 0x00000004; 163 minfo->hw.crtc2.ctl = 0x00000004;
164} 164}
165 165
166static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info, 166static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info,
@@ -168,7 +168,7 @@ static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info,
168 unsigned int pos; 168 unsigned int pos;
169 unsigned int linelen; 169 unsigned int linelen;
170 unsigned int pixelsize; 170 unsigned int pixelsize;
171 MINFO_FROM(m2info->primary_dev); 171 struct matrox_fb_info *minfo = m2info->primary_dev;
172 172
173 m2info->fbcon.var.xoffset = var->xoffset; 173 m2info->fbcon.var.xoffset = var->xoffset;
174 m2info->fbcon.var.yoffset = var->yoffset; 174 m2info->fbcon.var.yoffset = var->yoffset;
@@ -260,15 +260,15 @@ static int matroxfb_dh_decode_var(struct matroxfb_dh_fb_info* m2info,
260 260
261static int matroxfb_dh_open(struct fb_info* info, int user) { 261static int matroxfb_dh_open(struct fb_info* info, int user) {
262#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon)) 262#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
263 MINFO_FROM(m2info->primary_dev); 263 struct matrox_fb_info *minfo = m2info->primary_dev;
264 264
265 if (MINFO) { 265 if (minfo) {
266 int err; 266 int err;
267 267
268 if (ACCESS_FBINFO(dead)) { 268 if (minfo->dead) {
269 return -ENXIO; 269 return -ENXIO;
270 } 270 }
271 err = ACCESS_FBINFO(fbops).fb_open(&ACCESS_FBINFO(fbcon), user); 271 err = minfo->fbops.fb_open(&minfo->fbcon, user);
272 if (err) { 272 if (err) {
273 return err; 273 return err;
274 } 274 }
@@ -280,10 +280,10 @@ static int matroxfb_dh_open(struct fb_info* info, int user) {
280static int matroxfb_dh_release(struct fb_info* info, int user) { 280static int matroxfb_dh_release(struct fb_info* info, int user) {
281#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon)) 281#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
282 int err = 0; 282 int err = 0;
283 MINFO_FROM(m2info->primary_dev); 283 struct matrox_fb_info *minfo = m2info->primary_dev;
284 284
285 if (MINFO) { 285 if (minfo) {
286 err = ACCESS_FBINFO(fbops).fb_release(&ACCESS_FBINFO(fbcon), user); 286 err = minfo->fbops.fb_release(&minfo->fbcon, user);
287 } 287 }
288 return err; 288 return err;
289#undef m2info 289#undef m2info
@@ -326,7 +326,7 @@ static int matroxfb_dh_set_par(struct fb_info* info) {
326 int mode; 326 int mode;
327 int err; 327 int err;
328 struct fb_var_screeninfo* var = &info->var; 328 struct fb_var_screeninfo* var = &info->var;
329 MINFO_FROM(m2info->primary_dev); 329 struct matrox_fb_info *minfo = m2info->primary_dev;
330 330
331 if ((err = matroxfb_dh_decode_var(m2info, var, &visual, &cmap_len, &mode)) != 0) 331 if ((err = matroxfb_dh_decode_var(m2info, var, &visual, &cmap_len, &mode)) != 0)
332 return err; 332 return err;
@@ -352,39 +352,39 @@ static int matroxfb_dh_set_par(struct fb_info* info) {
352 pos = (m2info->fbcon.var.yoffset * m2info->fbcon.var.xres_virtual + m2info->fbcon.var.xoffset) * m2info->fbcon.var.bits_per_pixel >> 3; 352 pos = (m2info->fbcon.var.yoffset * m2info->fbcon.var.xres_virtual + m2info->fbcon.var.xoffset) * m2info->fbcon.var.bits_per_pixel >> 3;
353 pos += m2info->video.offbase; 353 pos += m2info->video.offbase;
354 cnt = 0; 354 cnt = 0;
355 down_read(&ACCESS_FBINFO(altout).lock); 355 down_read(&minfo->altout.lock);
356 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { 356 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
357 if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2) { 357 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2) {
358 cnt++; 358 cnt++;
359 if (ACCESS_FBINFO(outputs[out]).output->compute) { 359 if (minfo->outputs[out].output->compute) {
360 ACCESS_FBINFO(outputs[out]).output->compute(ACCESS_FBINFO(outputs[out]).data, &mt); 360 minfo->outputs[out].output->compute(minfo->outputs[out].data, &mt);
361 } 361 }
362 } 362 }
363 } 363 }
364 ACCESS_FBINFO(crtc2).pixclock = mt.pixclock; 364 minfo->crtc2.pixclock = mt.pixclock;
365 ACCESS_FBINFO(crtc2).mnp = mt.mnp; 365 minfo->crtc2.mnp = mt.mnp;
366 up_read(&ACCESS_FBINFO(altout).lock); 366 up_read(&minfo->altout.lock);
367 if (cnt) { 367 if (cnt) {
368 matroxfb_dh_restore(m2info, &mt, mode, pos); 368 matroxfb_dh_restore(m2info, &mt, mode, pos);
369 } else { 369 } else {
370 matroxfb_dh_disable(m2info); 370 matroxfb_dh_disable(m2info);
371 } 371 }
372 DAC1064_global_init(PMINFO2); 372 DAC1064_global_init(minfo);
373 DAC1064_global_restore(PMINFO2); 373 DAC1064_global_restore(minfo);
374 down_read(&ACCESS_FBINFO(altout).lock); 374 down_read(&minfo->altout.lock);
375 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { 375 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
376 if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2 && 376 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2 &&
377 ACCESS_FBINFO(outputs[out]).output->program) { 377 minfo->outputs[out].output->program) {
378 ACCESS_FBINFO(outputs[out]).output->program(ACCESS_FBINFO(outputs[out]).data); 378 minfo->outputs[out].output->program(minfo->outputs[out].data);
379 } 379 }
380 } 380 }
381 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { 381 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
382 if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2 && 382 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2 &&
383 ACCESS_FBINFO(outputs[out]).output->start) { 383 minfo->outputs[out].output->start) {
384 ACCESS_FBINFO(outputs[out]).output->start(ACCESS_FBINFO(outputs[out]).data); 384 minfo->outputs[out].output->start(minfo->outputs[out].data);
385 } 385 }
386 } 386 }
387 up_read(&ACCESS_FBINFO(altout).lock); 387 up_read(&minfo->altout.lock);
388 } 388 }
389 m2info->initialized = 1; 389 m2info->initialized = 1;
390 return 0; 390 return 0;
@@ -399,9 +399,9 @@ static int matroxfb_dh_pan_display(struct fb_var_screeninfo* var, struct fb_info
399} 399}
400 400
401static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, struct fb_vblank* vblank) { 401static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, struct fb_vblank* vblank) {
402 MINFO_FROM(m2info->primary_dev); 402 struct matrox_fb_info *minfo = m2info->primary_dev;
403 403
404 matroxfb_enable_irq(PMINFO 0); 404 matroxfb_enable_irq(minfo, 0);
405 memset(vblank, 0, sizeof(*vblank)); 405 memset(vblank, 0, sizeof(*vblank));
406 vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VBLANK; 406 vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VBLANK;
407 /* mask out reserved bits + field number (odd/even) */ 407 /* mask out reserved bits + field number (odd/even) */
@@ -409,11 +409,11 @@ static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, stru
409 /* compatibility stuff */ 409 /* compatibility stuff */
410 if (vblank->vcount >= m2info->fbcon.var.yres) 410 if (vblank->vcount >= m2info->fbcon.var.yres)
411 vblank->flags |= FB_VBLANK_VBLANKING; 411 vblank->flags |= FB_VBLANK_VBLANKING;
412 if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { 412 if (test_bit(0, &minfo->irq_flags)) {
413 vblank->flags |= FB_VBLANK_HAVE_COUNT; 413 vblank->flags |= FB_VBLANK_HAVE_COUNT;
414 /* Only one writer, aligned int value... 414 /* Only one writer, aligned int value...
415 it should work without lock and without atomic_t */ 415 it should work without lock and without atomic_t */
416 vblank->count = ACCESS_FBINFO(crtc2).vsync.cnt; 416 vblank->count = minfo->crtc2.vsync.cnt;
417 } 417 }
418 return 0; 418 return 0;
419} 419}
@@ -423,7 +423,7 @@ static int matroxfb_dh_ioctl(struct fb_info *info,
423 unsigned long arg) 423 unsigned long arg)
424{ 424{
425#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon)) 425#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
426 MINFO_FROM(m2info->primary_dev); 426 struct matrox_fb_info *minfo = m2info->primary_dev;
427 427
428 DBG(__func__) 428 DBG(__func__)
429 429
@@ -449,13 +449,13 @@ static int matroxfb_dh_ioctl(struct fb_info *info,
449 449
450 if (crt != 0) 450 if (crt != 0)
451 return -ENODEV; 451 return -ENODEV;
452 return matroxfb_wait_for_sync(PMINFO 1); 452 return matroxfb_wait_for_sync(minfo, 1);
453 } 453 }
454 case MATROXFB_SET_OUTPUT_MODE: 454 case MATROXFB_SET_OUTPUT_MODE:
455 case MATROXFB_GET_OUTPUT_MODE: 455 case MATROXFB_GET_OUTPUT_MODE:
456 case MATROXFB_GET_ALL_OUTPUTS: 456 case MATROXFB_GET_ALL_OUTPUTS:
457 { 457 {
458 return ACCESS_FBINFO(fbcon.fbops)->fb_ioctl(&ACCESS_FBINFO(fbcon), cmd, arg); 458 return minfo->fbcon.fbops->fb_ioctl(&minfo->fbcon, cmd, arg);
459 } 459 }
460 case MATROXFB_SET_OUTPUT_CONNECTION: 460 case MATROXFB_SET_OUTPUT_CONNECTION:
461 { 461 {
@@ -469,9 +469,9 @@ static int matroxfb_dh_ioctl(struct fb_info *info,
469 if (tmp & (1 << out)) { 469 if (tmp & (1 << out)) {
470 if (out >= MATROXFB_MAX_OUTPUTS) 470 if (out >= MATROXFB_MAX_OUTPUTS)
471 return -ENXIO; 471 return -ENXIO;
472 if (!ACCESS_FBINFO(outputs[out]).output) 472 if (!minfo->outputs[out].output)
473 return -ENXIO; 473 return -ENXIO;
474 switch (ACCESS_FBINFO(outputs[out]).src) { 474 switch (minfo->outputs[out].src) {
475 case MATROXFB_SRC_NONE: 475 case MATROXFB_SRC_NONE:
476 case MATROXFB_SRC_CRTC2: 476 case MATROXFB_SRC_CRTC2:
477 break; 477 break;
@@ -480,22 +480,22 @@ static int matroxfb_dh_ioctl(struct fb_info *info,
480 } 480 }
481 } 481 }
482 } 482 }
483 if (ACCESS_FBINFO(devflags.panellink)) { 483 if (minfo->devflags.panellink) {
484 if (tmp & MATROXFB_OUTPUT_CONN_DFP) 484 if (tmp & MATROXFB_OUTPUT_CONN_DFP)
485 return -EINVAL; 485 return -EINVAL;
486 if ((ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1) && tmp) 486 if ((minfo->outputs[2].src == MATROXFB_SRC_CRTC1) && tmp)
487 return -EBUSY; 487 return -EBUSY;
488 } 488 }
489 changes = 0; 489 changes = 0;
490 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { 490 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
491 if (tmp & (1 << out)) { 491 if (tmp & (1 << out)) {
492 if (ACCESS_FBINFO(outputs[out]).src != MATROXFB_SRC_CRTC2) { 492 if (minfo->outputs[out].src != MATROXFB_SRC_CRTC2) {
493 changes = 1; 493 changes = 1;
494 ACCESS_FBINFO(outputs[out]).src = MATROXFB_SRC_CRTC2; 494 minfo->outputs[out].src = MATROXFB_SRC_CRTC2;
495 } 495 }
496 } else if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2) { 496 } else if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2) {
497 changes = 1; 497 changes = 1;
498 ACCESS_FBINFO(outputs[out]).src = MATROXFB_SRC_NONE; 498 minfo->outputs[out].src = MATROXFB_SRC_NONE;
499 } 499 }
500 } 500 }
501 if (!changes) 501 if (!changes)
@@ -509,7 +509,7 @@ static int matroxfb_dh_ioctl(struct fb_info *info,
509 int out; 509 int out;
510 510
511 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { 511 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
512 if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2) { 512 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2) {
513 conn |= 1 << out; 513 conn |= 1 << out;
514 } 514 }
515 } 515 }
@@ -523,8 +523,8 @@ static int matroxfb_dh_ioctl(struct fb_info *info,
523 int out; 523 int out;
524 524
525 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { 525 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
526 if (ACCESS_FBINFO(outputs[out]).output) { 526 if (minfo->outputs[out].output) {
527 switch (ACCESS_FBINFO(outputs[out]).src) { 527 switch (minfo->outputs[out].src) {
528 case MATROXFB_SRC_NONE: 528 case MATROXFB_SRC_NONE:
529 case MATROXFB_SRC_CRTC2: 529 case MATROXFB_SRC_CRTC2:
530 tmp |= 1 << out; 530 tmp |= 1 << out;
@@ -532,9 +532,9 @@ static int matroxfb_dh_ioctl(struct fb_info *info,
532 } 532 }
533 } 533 }
534 } 534 }
535 if (ACCESS_FBINFO(devflags.panellink)) { 535 if (minfo->devflags.panellink) {
536 tmp &= ~MATROXFB_OUTPUT_CONN_DFP; 536 tmp &= ~MATROXFB_OUTPUT_CONN_DFP;
537 if (ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1) { 537 if (minfo->outputs[2].src == MATROXFB_SRC_CRTC1) {
538 tmp = 0; 538 tmp = 0;
539 } 539 }
540 } 540 }
@@ -595,7 +595,9 @@ static struct fb_var_screeninfo matroxfb_dh_defined = {
595 0, {0,0,0,0,0} 595 0, {0,0,0,0,0}
596}; 596};
597 597
598static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) { 598static int matroxfb_dh_regit(const struct matrox_fb_info *minfo,
599 struct matroxfb_dh_fb_info *m2info)
600{
599#define minfo (m2info->primary_dev) 601#define minfo (m2info->primary_dev)
600 void* oldcrtc2; 602 void* oldcrtc2;
601 603
@@ -611,21 +613,21 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) {
611 if (mem < 64*1024) 613 if (mem < 64*1024)
612 mem *= 1024; 614 mem *= 1024;
613 mem &= ~0x00000FFF; /* PAGE_MASK? */ 615 mem &= ~0x00000FFF; /* PAGE_MASK? */
614 if (ACCESS_FBINFO(video.len_usable) + mem <= ACCESS_FBINFO(video.len)) 616 if (minfo->video.len_usable + mem <= minfo->video.len)
615 m2info->video.offbase = ACCESS_FBINFO(video.len) - mem; 617 m2info->video.offbase = minfo->video.len - mem;
616 else if (ACCESS_FBINFO(video.len) < mem) { 618 else if (minfo->video.len < mem) {
617 return -ENOMEM; 619 return -ENOMEM;
618 } else { /* check yres on first head... */ 620 } else { /* check yres on first head... */
619 m2info->video.borrowed = mem; 621 m2info->video.borrowed = mem;
620 ACCESS_FBINFO(video.len_usable) -= mem; 622 minfo->video.len_usable -= mem;
621 m2info->video.offbase = ACCESS_FBINFO(video.len_usable); 623 m2info->video.offbase = minfo->video.len_usable;
622 } 624 }
623 m2info->video.base = ACCESS_FBINFO(video.base) + m2info->video.offbase; 625 m2info->video.base = minfo->video.base + m2info->video.offbase;
624 m2info->video.len = m2info->video.len_usable = m2info->video.len_maximum = mem; 626 m2info->video.len = m2info->video.len_usable = m2info->video.len_maximum = mem;
625 m2info->video.vbase.vaddr = vaddr_va(ACCESS_FBINFO(video.vbase)) + m2info->video.offbase; 627 m2info->video.vbase.vaddr = vaddr_va(minfo->video.vbase) + m2info->video.offbase;
626 m2info->mmio.base = ACCESS_FBINFO(mmio.base); 628 m2info->mmio.base = minfo->mmio.base;
627 m2info->mmio.vbase = ACCESS_FBINFO(mmio.vbase); 629 m2info->mmio.vbase = minfo->mmio.vbase;
628 m2info->mmio.len = ACCESS_FBINFO(mmio.len); 630 m2info->mmio.len = minfo->mmio.len;
629 631
630 matroxfb_dh_init_fix(m2info); 632 matroxfb_dh_init_fix(m2info);
631 if (register_framebuffer(&m2info->fbcon)) { 633 if (register_framebuffer(&m2info->fbcon)) {
@@ -633,10 +635,10 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) {
633 } 635 }
634 if (!m2info->initialized) 636 if (!m2info->initialized)
635 fb_set_var(&m2info->fbcon, &matroxfb_dh_defined); 637 fb_set_var(&m2info->fbcon, &matroxfb_dh_defined);
636 down_write(&ACCESS_FBINFO(crtc2.lock)); 638 down_write(&minfo->crtc2.lock);
637 oldcrtc2 = ACCESS_FBINFO(crtc2.info); 639 oldcrtc2 = minfo->crtc2.info;
638 ACCESS_FBINFO(crtc2.info) = m2info; 640 minfo->crtc2.info = m2info;
639 up_write(&ACCESS_FBINFO(crtc2.lock)); 641 up_write(&minfo->crtc2.lock);
640 if (oldcrtc2) { 642 if (oldcrtc2) {
641 printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p\n", 643 printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p\n",
642 oldcrtc2); 644 oldcrtc2);
@@ -649,12 +651,12 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) {
649 651
650static int matroxfb_dh_registerfb(struct matroxfb_dh_fb_info* m2info) { 652static int matroxfb_dh_registerfb(struct matroxfb_dh_fb_info* m2info) {
651#define minfo (m2info->primary_dev) 653#define minfo (m2info->primary_dev)
652 if (matroxfb_dh_regit(PMINFO m2info)) { 654 if (matroxfb_dh_regit(minfo, m2info)) {
653 printk(KERN_ERR "matroxfb_crtc2: secondary head failed to register\n"); 655 printk(KERN_ERR "matroxfb_crtc2: secondary head failed to register\n");
654 return -1; 656 return -1;
655 } 657 }
656 printk(KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n", 658 printk(KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n",
657 ACCESS_FBINFO(fbcon.node), m2info->fbcon.node); 659 minfo->fbcon.node, m2info->fbcon.node);
658 m2info->fbcon_registered = 1; 660 m2info->fbcon_registered = 1;
659 return 0; 661 return 0;
660#undef minfo 662#undef minfo
@@ -666,11 +668,11 @@ static void matroxfb_dh_deregisterfb(struct matroxfb_dh_fb_info* m2info) {
666 int id; 668 int id;
667 struct matroxfb_dh_fb_info* crtc2; 669 struct matroxfb_dh_fb_info* crtc2;
668 670
669 down_write(&ACCESS_FBINFO(crtc2.lock)); 671 down_write(&minfo->crtc2.lock);
670 crtc2 = ACCESS_FBINFO(crtc2.info); 672 crtc2 = minfo->crtc2.info;
671 if (crtc2 == m2info) 673 if (crtc2 == m2info)
672 ACCESS_FBINFO(crtc2.info) = NULL; 674 minfo->crtc2.info = NULL;
673 up_write(&ACCESS_FBINFO(crtc2.lock)); 675 up_write(&minfo->crtc2.lock);
674 if (crtc2 != m2info) { 676 if (crtc2 != m2info) {
675 printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p\n", 677 printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p\n",
676 crtc2, m2info); 678 crtc2, m2info);
@@ -680,7 +682,7 @@ static void matroxfb_dh_deregisterfb(struct matroxfb_dh_fb_info* m2info) {
680 id = m2info->fbcon.node; 682 id = m2info->fbcon.node;
681 unregister_framebuffer(&m2info->fbcon); 683 unregister_framebuffer(&m2info->fbcon);
682 /* return memory back to primary head */ 684 /* return memory back to primary head */
683 ACCESS_FBINFO(video.len_usable) += m2info->video.borrowed; 685 minfo->video.len_usable += m2info->video.borrowed;
684 printk(KERN_INFO "matroxfb_crtc2: fb%u unregistered\n", id); 686 printk(KERN_INFO "matroxfb_crtc2: fb%u unregistered\n", id);
685 m2info->fbcon_registered = 0; 687 m2info->fbcon_registered = 0;
686 } 688 }
@@ -691,14 +693,14 @@ static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) {
691 struct matroxfb_dh_fb_info* m2info; 693 struct matroxfb_dh_fb_info* m2info;
692 694
693 /* hardware is CRTC2 incapable... */ 695 /* hardware is CRTC2 incapable... */
694 if (!ACCESS_FBINFO(devflags.crtc2)) 696 if (!minfo->devflags.crtc2)
695 return NULL; 697 return NULL;
696 m2info = kzalloc(sizeof(*m2info), GFP_KERNEL); 698 m2info = kzalloc(sizeof(*m2info), GFP_KERNEL);
697 if (!m2info) { 699 if (!m2info) {
698 printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n"); 700 printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n");
699 return NULL; 701 return NULL;
700 } 702 }
701 m2info->primary_dev = MINFO; 703 m2info->primary_dev = minfo;
702 if (matroxfb_dh_registerfb(m2info)) { 704 if (matroxfb_dh_registerfb(m2info)) {
703 kfree(m2info); 705 kfree(m2info);
704 printk(KERN_ERR "matroxfb_crtc2: CRTC2 framebuffer failed to register\n"); 706 printk(KERN_ERR "matroxfb_crtc2: CRTC2 framebuffer failed to register\n");
diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c
index 6209a761f674..cff0546ea6fd 100644
--- a/drivers/video/matrox/matroxfb_g450.c
+++ b/drivers/video/matrox/matroxfb_g450.c
@@ -80,52 +80,59 @@ static int get_ctrl_id(__u32 v4l2_id) {
80 return -EINVAL; 80 return -EINVAL;
81} 81}
82 82
83static inline int* get_ctrl_ptr(WPMINFO unsigned int idx) { 83static inline int *get_ctrl_ptr(struct matrox_fb_info *minfo, unsigned int idx)
84 return (int*)((char*)MINFO + g450_controls[idx].control); 84{
85 return (int*)((char*)minfo + g450_controls[idx].control);
85} 86}
86 87
87static void tvo_fill_defaults(WPMINFO2) { 88static void tvo_fill_defaults(struct matrox_fb_info *minfo)
89{
88 unsigned int i; 90 unsigned int i;
89 91
90 for (i = 0; i < G450CTRLS; i++) { 92 for (i = 0; i < G450CTRLS; i++) {
91 *get_ctrl_ptr(PMINFO i) = g450_controls[i].desc.default_value; 93 *get_ctrl_ptr(minfo, i) = g450_controls[i].desc.default_value;
92 } 94 }
93} 95}
94 96
95static int cve2_get_reg(WPMINFO int reg) { 97static int cve2_get_reg(struct matrox_fb_info *minfo, int reg)
98{
96 unsigned long flags; 99 unsigned long flags;
97 int val; 100 int val;
98 101
99 matroxfb_DAC_lock_irqsave(flags); 102 matroxfb_DAC_lock_irqsave(flags);
100 matroxfb_DAC_out(PMINFO 0x87, reg); 103 matroxfb_DAC_out(minfo, 0x87, reg);
101 val = matroxfb_DAC_in(PMINFO 0x88); 104 val = matroxfb_DAC_in(minfo, 0x88);
102 matroxfb_DAC_unlock_irqrestore(flags); 105 matroxfb_DAC_unlock_irqrestore(flags);
103 return val; 106 return val;
104} 107}
105 108
106static void cve2_set_reg(WPMINFO int reg, int val) { 109static void cve2_set_reg(struct matrox_fb_info *minfo, int reg, int val)
110{
107 unsigned long flags; 111 unsigned long flags;
108 112
109 matroxfb_DAC_lock_irqsave(flags); 113 matroxfb_DAC_lock_irqsave(flags);
110 matroxfb_DAC_out(PMINFO 0x87, reg); 114 matroxfb_DAC_out(minfo, 0x87, reg);
111 matroxfb_DAC_out(PMINFO 0x88, val); 115 matroxfb_DAC_out(minfo, 0x88, val);
112 matroxfb_DAC_unlock_irqrestore(flags); 116 matroxfb_DAC_unlock_irqrestore(flags);
113} 117}
114 118
115static void cve2_set_reg10(WPMINFO int reg, int val) { 119static void cve2_set_reg10(struct matrox_fb_info *minfo, int reg, int val)
120{
116 unsigned long flags; 121 unsigned long flags;
117 122
118 matroxfb_DAC_lock_irqsave(flags); 123 matroxfb_DAC_lock_irqsave(flags);
119 matroxfb_DAC_out(PMINFO 0x87, reg); 124 matroxfb_DAC_out(minfo, 0x87, reg);
120 matroxfb_DAC_out(PMINFO 0x88, val >> 2); 125 matroxfb_DAC_out(minfo, 0x88, val >> 2);
121 matroxfb_DAC_out(PMINFO 0x87, reg + 1); 126 matroxfb_DAC_out(minfo, 0x87, reg + 1);
122 matroxfb_DAC_out(PMINFO 0x88, val & 3); 127 matroxfb_DAC_out(minfo, 0x88, val & 3);
123 matroxfb_DAC_unlock_irqrestore(flags); 128 matroxfb_DAC_unlock_irqrestore(flags);
124} 129}
125 130
126static void g450_compute_bwlevel(CPMINFO int *bl, int *wl) { 131static void g450_compute_bwlevel(const struct matrox_fb_info *minfo, int *bl,
127 const int b = ACCESS_FBINFO(altout.tvo_params.brightness) + BLMIN; 132 int *wl)
128 const int c = ACCESS_FBINFO(altout.tvo_params.contrast); 133{
134 const int b = minfo->altout.tvo_params.brightness + BLMIN;
135 const int c = minfo->altout.tvo_params.contrast;
129 136
130 *bl = max(b - c, BLMIN); 137 *bl = max(b - c, BLMIN);
131 *wl = min(b + c, WLMAX); 138 *wl = min(b + c, WLMAX);
@@ -154,7 +161,7 @@ static int g450_query_ctrl(void* md, struct v4l2_queryctrl *p) {
154 161
155static int g450_set_ctrl(void* md, struct v4l2_control *p) { 162static int g450_set_ctrl(void* md, struct v4l2_control *p) {
156 int i; 163 int i;
157 MINFO_FROM(md); 164 struct matrox_fb_info *minfo = md;
158 165
159 i = get_ctrl_id(p->id); 166 i = get_ctrl_id(p->id);
160 if (i < 0) return -EINVAL; 167 if (i < 0) return -EINVAL;
@@ -162,7 +169,7 @@ static int g450_set_ctrl(void* md, struct v4l2_control *p) {
162 /* 169 /*
163 * Check if changed. 170 * Check if changed.
164 */ 171 */
165 if (p->value == *get_ctrl_ptr(PMINFO i)) return 0; 172 if (p->value == *get_ctrl_ptr(minfo, i)) return 0;
166 173
167 /* 174 /*
168 * Check limits. 175 * Check limits.
@@ -173,31 +180,31 @@ static int g450_set_ctrl(void* md, struct v4l2_control *p) {
173 /* 180 /*
174 * Store new value. 181 * Store new value.
175 */ 182 */
176 *get_ctrl_ptr(PMINFO i) = p->value; 183 *get_ctrl_ptr(minfo, i) = p->value;
177 184
178 switch (p->id) { 185 switch (p->id) {
179 case V4L2_CID_BRIGHTNESS: 186 case V4L2_CID_BRIGHTNESS:
180 case V4L2_CID_CONTRAST: 187 case V4L2_CID_CONTRAST:
181 { 188 {
182 int blacklevel, whitelevel; 189 int blacklevel, whitelevel;
183 g450_compute_bwlevel(PMINFO &blacklevel, &whitelevel); 190 g450_compute_bwlevel(minfo, &blacklevel, &whitelevel);
184 cve2_set_reg10(PMINFO 0x0e, blacklevel); 191 cve2_set_reg10(minfo, 0x0e, blacklevel);
185 cve2_set_reg10(PMINFO 0x1e, whitelevel); 192 cve2_set_reg10(minfo, 0x1e, whitelevel);
186 } 193 }
187 break; 194 break;
188 case V4L2_CID_SATURATION: 195 case V4L2_CID_SATURATION:
189 cve2_set_reg(PMINFO 0x20, p->value); 196 cve2_set_reg(minfo, 0x20, p->value);
190 cve2_set_reg(PMINFO 0x22, p->value); 197 cve2_set_reg(minfo, 0x22, p->value);
191 break; 198 break;
192 case V4L2_CID_HUE: 199 case V4L2_CID_HUE:
193 cve2_set_reg(PMINFO 0x25, p->value); 200 cve2_set_reg(minfo, 0x25, p->value);
194 break; 201 break;
195 case MATROXFB_CID_TESTOUT: 202 case MATROXFB_CID_TESTOUT:
196 { 203 {
197 unsigned char val = cve2_get_reg (PMINFO 0x05); 204 unsigned char val = cve2_get_reg(minfo, 0x05);
198 if (p->value) val |= 0x02; 205 if (p->value) val |= 0x02;
199 else val &= ~0x02; 206 else val &= ~0x02;
200 cve2_set_reg(PMINFO 0x05, val); 207 cve2_set_reg(minfo, 0x05, val);
201 } 208 }
202 break; 209 break;
203 } 210 }
@@ -208,11 +215,11 @@ static int g450_set_ctrl(void* md, struct v4l2_control *p) {
208 215
209static int g450_get_ctrl(void* md, struct v4l2_control *p) { 216static int g450_get_ctrl(void* md, struct v4l2_control *p) {
210 int i; 217 int i;
211 MINFO_FROM(md); 218 struct matrox_fb_info *minfo = md;
212 219
213 i = get_ctrl_id(p->id); 220 i = get_ctrl_id(p->id);
214 if (i < 0) return -EINVAL; 221 if (i < 0) return -EINVAL;
215 p->value = *get_ctrl_ptr(PMINFO i); 222 p->value = *get_ctrl_ptr(minfo, i);
216 return 0; 223 return 0;
217} 224}
218 225
@@ -226,7 +233,9 @@ struct output_desc {
226 unsigned int v_total; 233 unsigned int v_total;
227}; 234};
228 235
229static void computeRegs(WPMINFO struct mavenregs* r, struct my_timming* mt, const struct output_desc* outd) { 236static void computeRegs(struct matrox_fb_info *minfo, struct mavenregs *r,
237 struct my_timming *mt, const struct output_desc *outd)
238{
230 u_int32_t chromasc; 239 u_int32_t chromasc;
231 u_int32_t hlen; 240 u_int32_t hlen;
232 u_int32_t hsl; 241 u_int32_t hsl;
@@ -251,10 +260,10 @@ static void computeRegs(WPMINFO struct mavenregs* r, struct my_timming* mt, cons
251 260
252 dprintk(KERN_DEBUG "Want %u kHz pixclock\n", (unsigned int)piic); 261 dprintk(KERN_DEBUG "Want %u kHz pixclock\n", (unsigned int)piic);
253 262
254 mnp = matroxfb_g450_setclk(PMINFO piic, M_VIDEO_PLL); 263 mnp = matroxfb_g450_setclk(minfo, piic, M_VIDEO_PLL);
255 264
256 mt->mnp = mnp; 265 mt->mnp = mnp;
257 mt->pixclock = g450_mnp2f(PMINFO mnp); 266 mt->pixclock = g450_mnp2f(minfo, mnp);
258 267
259 dprintk(KERN_DEBUG "MNP=%08X\n", mnp); 268 dprintk(KERN_DEBUG "MNP=%08X\n", mnp);
260 269
@@ -490,65 +499,67 @@ static void cve2_init_TVdata(int norm, struct mavenregs* data, const struct outp
490 return; 499 return;
491} 500}
492 501
493#define LR(x) cve2_set_reg(PMINFO (x), m->regs[(x)]) 502#define LR(x) cve2_set_reg(minfo, (x), m->regs[(x)])
494static void cve2_init_TV(WPMINFO const struct mavenregs* m) { 503static void cve2_init_TV(struct matrox_fb_info *minfo,
504 const struct mavenregs *m)
505{
495 int i; 506 int i;
496 507
497 LR(0x80); 508 LR(0x80);
498 LR(0x82); LR(0x83); 509 LR(0x82); LR(0x83);
499 LR(0x84); LR(0x85); 510 LR(0x84); LR(0x85);
500 511
501 cve2_set_reg(PMINFO 0x3E, 0x01); 512 cve2_set_reg(minfo, 0x3E, 0x01);
502 513
503 for (i = 0; i < 0x3E; i++) { 514 for (i = 0; i < 0x3E; i++) {
504 LR(i); 515 LR(i);
505 } 516 }
506 cve2_set_reg(PMINFO 0x3E, 0x00); 517 cve2_set_reg(minfo, 0x3E, 0x00);
507} 518}
508 519
509static int matroxfb_g450_compute(void* md, struct my_timming* mt) { 520static int matroxfb_g450_compute(void* md, struct my_timming* mt) {
510 MINFO_FROM(md); 521 struct matrox_fb_info *minfo = md;
511 522
512 dprintk(KERN_DEBUG "Computing, mode=%u\n", ACCESS_FBINFO(outputs[1]).mode); 523 dprintk(KERN_DEBUG "Computing, mode=%u\n", minfo->outputs[1].mode);
513 524
514 if (mt->crtc == MATROXFB_SRC_CRTC2 && 525 if (mt->crtc == MATROXFB_SRC_CRTC2 &&
515 ACCESS_FBINFO(outputs[1]).mode != MATROXFB_OUTPUT_MODE_MONITOR) { 526 minfo->outputs[1].mode != MATROXFB_OUTPUT_MODE_MONITOR) {
516 const struct output_desc* outd; 527 const struct output_desc* outd;
517 528
518 cve2_init_TVdata(ACCESS_FBINFO(outputs[1]).mode, &ACCESS_FBINFO(hw).maven, &outd); 529 cve2_init_TVdata(minfo->outputs[1].mode, &minfo->hw.maven, &outd);
519 { 530 {
520 int blacklevel, whitelevel; 531 int blacklevel, whitelevel;
521 g450_compute_bwlevel(PMINFO &blacklevel, &whitelevel); 532 g450_compute_bwlevel(minfo, &blacklevel, &whitelevel);
522 ACCESS_FBINFO(hw).maven.regs[0x0E] = blacklevel >> 2; 533 minfo->hw.maven.regs[0x0E] = blacklevel >> 2;
523 ACCESS_FBINFO(hw).maven.regs[0x0F] = blacklevel & 3; 534 minfo->hw.maven.regs[0x0F] = blacklevel & 3;
524 ACCESS_FBINFO(hw).maven.regs[0x1E] = whitelevel >> 2; 535 minfo->hw.maven.regs[0x1E] = whitelevel >> 2;
525 ACCESS_FBINFO(hw).maven.regs[0x1F] = whitelevel & 3; 536 minfo->hw.maven.regs[0x1F] = whitelevel & 3;
526 537
527 ACCESS_FBINFO(hw).maven.regs[0x20] = 538 minfo->hw.maven.regs[0x20] =
528 ACCESS_FBINFO(hw).maven.regs[0x22] = ACCESS_FBINFO(altout.tvo_params.saturation); 539 minfo->hw.maven.regs[0x22] = minfo->altout.tvo_params.saturation;
529 540
530 ACCESS_FBINFO(hw).maven.regs[0x25] = ACCESS_FBINFO(altout.tvo_params.hue); 541 minfo->hw.maven.regs[0x25] = minfo->altout.tvo_params.hue;
531 542
532 if (ACCESS_FBINFO(altout.tvo_params.testout)) { 543 if (minfo->altout.tvo_params.testout) {
533 ACCESS_FBINFO(hw).maven.regs[0x05] |= 0x02; 544 minfo->hw.maven.regs[0x05] |= 0x02;
534 } 545 }
535 } 546 }
536 computeRegs(PMINFO &ACCESS_FBINFO(hw).maven, mt, outd); 547 computeRegs(minfo, &minfo->hw.maven, mt, outd);
537 } else if (mt->mnp < 0) { 548 } else if (mt->mnp < 0) {
538 /* We must program clocks before CRTC2, otherwise interlaced mode 549 /* We must program clocks before CRTC2, otherwise interlaced mode
539 startup may fail */ 550 startup may fail */
540 mt->mnp = matroxfb_g450_setclk(PMINFO mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); 551 mt->mnp = matroxfb_g450_setclk(minfo, mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
541 mt->pixclock = g450_mnp2f(PMINFO mt->mnp); 552 mt->pixclock = g450_mnp2f(minfo, mt->mnp);
542 } 553 }
543 dprintk(KERN_DEBUG "Pixclock = %u\n", mt->pixclock); 554 dprintk(KERN_DEBUG "Pixclock = %u\n", mt->pixclock);
544 return 0; 555 return 0;
545} 556}
546 557
547static int matroxfb_g450_program(void* md) { 558static int matroxfb_g450_program(void* md) {
548 MINFO_FROM(md); 559 struct matrox_fb_info *minfo = md;
549 560
550 if (ACCESS_FBINFO(outputs[1]).mode != MATROXFB_OUTPUT_MODE_MONITOR) { 561 if (minfo->outputs[1].mode != MATROXFB_OUTPUT_MODE_MONITOR) {
551 cve2_init_TV(PMINFO &ACCESS_FBINFO(hw).maven); 562 cve2_init_TV(minfo, &minfo->hw.maven);
552 } 563 }
553 return 0; 564 return 0;
554} 565}
@@ -564,11 +575,11 @@ static int matroxfb_g450_verify_mode(void* md, u_int32_t arg) {
564} 575}
565 576
566static int g450_dvi_compute(void* md, struct my_timming* mt) { 577static int g450_dvi_compute(void* md, struct my_timming* mt) {
567 MINFO_FROM(md); 578 struct matrox_fb_info *minfo = md;
568 579
569 if (mt->mnp < 0) { 580 if (mt->mnp < 0) {
570 mt->mnp = matroxfb_g450_setclk(PMINFO mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); 581 mt->mnp = matroxfb_g450_setclk(minfo, mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
571 mt->pixclock = g450_mnp2f(PMINFO mt->mnp); 582 mt->pixclock = g450_mnp2f(minfo, mt->mnp);
572 } 583 }
573 return 0; 584 return 0;
574} 585}
@@ -588,34 +599,36 @@ static struct matrox_altout matroxfb_g450_dvi = {
588 .compute = g450_dvi_compute, 599 .compute = g450_dvi_compute,
589}; 600};
590 601
591void matroxfb_g450_connect(WPMINFO2) { 602void matroxfb_g450_connect(struct matrox_fb_info *minfo)
592 if (ACCESS_FBINFO(devflags.g450dac)) { 603{
593 down_write(&ACCESS_FBINFO(altout.lock)); 604 if (minfo->devflags.g450dac) {
594 tvo_fill_defaults(PMINFO2); 605 down_write(&minfo->altout.lock);
595 ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src; 606 tvo_fill_defaults(minfo);
596 ACCESS_FBINFO(outputs[1]).data = MINFO; 607 minfo->outputs[1].src = minfo->outputs[1].default_src;
597 ACCESS_FBINFO(outputs[1]).output = &matroxfb_g450_altout; 608 minfo->outputs[1].data = minfo;
598 ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 609 minfo->outputs[1].output = &matroxfb_g450_altout;
599 ACCESS_FBINFO(outputs[2]).src = ACCESS_FBINFO(outputs[2]).default_src; 610 minfo->outputs[1].mode = MATROXFB_OUTPUT_MODE_MONITOR;
600 ACCESS_FBINFO(outputs[2]).data = MINFO; 611 minfo->outputs[2].src = minfo->outputs[2].default_src;
601 ACCESS_FBINFO(outputs[2]).output = &matroxfb_g450_dvi; 612 minfo->outputs[2].data = minfo;
602 ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 613 minfo->outputs[2].output = &matroxfb_g450_dvi;
603 up_write(&ACCESS_FBINFO(altout.lock)); 614 minfo->outputs[2].mode = MATROXFB_OUTPUT_MODE_MONITOR;
615 up_write(&minfo->altout.lock);
604 } 616 }
605} 617}
606 618
607void matroxfb_g450_shutdown(WPMINFO2) { 619void matroxfb_g450_shutdown(struct matrox_fb_info *minfo)
608 if (ACCESS_FBINFO(devflags.g450dac)) { 620{
609 down_write(&ACCESS_FBINFO(altout.lock)); 621 if (minfo->devflags.g450dac) {
610 ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_NONE; 622 down_write(&minfo->altout.lock);
611 ACCESS_FBINFO(outputs[1]).output = NULL; 623 minfo->outputs[1].src = MATROXFB_SRC_NONE;
612 ACCESS_FBINFO(outputs[1]).data = NULL; 624 minfo->outputs[1].output = NULL;
613 ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 625 minfo->outputs[1].data = NULL;
614 ACCESS_FBINFO(outputs[2]).src = MATROXFB_SRC_NONE; 626 minfo->outputs[1].mode = MATROXFB_OUTPUT_MODE_MONITOR;
615 ACCESS_FBINFO(outputs[2]).output = NULL; 627 minfo->outputs[2].src = MATROXFB_SRC_NONE;
616 ACCESS_FBINFO(outputs[2]).data = NULL; 628 minfo->outputs[2].output = NULL;
617 ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 629 minfo->outputs[2].data = NULL;
618 up_write(&ACCESS_FBINFO(altout.lock)); 630 minfo->outputs[2].mode = MATROXFB_OUTPUT_MODE_MONITOR;
631 up_write(&minfo->altout.lock);
619 } 632 }
620} 633}
621 634
diff --git a/drivers/video/matrox/matroxfb_g450.h b/drivers/video/matrox/matroxfb_g450.h
index a0822a6033e5..3a3e654444b8 100644
--- a/drivers/video/matrox/matroxfb_g450.h
+++ b/drivers/video/matrox/matroxfb_g450.h
@@ -4,11 +4,11 @@
4#include "matroxfb_base.h" 4#include "matroxfb_base.h"
5 5
6#ifdef CONFIG_FB_MATROX_G 6#ifdef CONFIG_FB_MATROX_G
7void matroxfb_g450_connect(WPMINFO2); 7void matroxfb_g450_connect(struct matrox_fb_info *minfo);
8void matroxfb_g450_shutdown(WPMINFO2); 8void matroxfb_g450_shutdown(struct matrox_fb_info *minfo);
9#else 9#else
10static inline void matroxfb_g450_connect(WPMINFO2) { }; 10static inline void matroxfb_g450_connect(struct matrox_fb_info *minfo) { };
11static inline void matroxfb_g450_shutdown(WPMINFO2) { }; 11static inline void matroxfb_g450_shutdown(struct matrox_fb_info *minfo) { };
12#endif 12#endif
13 13
14#endif /* __MATROXFB_G450_H__ */ 14#endif /* __MATROXFB_G450_H__ */
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index 042408a8c631..91af9159111f 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -458,9 +458,9 @@ static void maven_init_TVdata(const struct maven_data* md, struct mavenregs* dat
458 0x00, /* 3E written multiple times */ 458 0x00, /* 3E written multiple times */
459 0x00, /* never written */ 459 0x00, /* never written */
460 }, MATROXFB_OUTPUT_MODE_NTSC, 525, 60 }; 460 }, MATROXFB_OUTPUT_MODE_NTSC, 525, 60 };
461 MINFO_FROM(md->primary_head); 461 struct matrox_fb_info *minfo = md->primary_head;
462 462
463 if (ACCESS_FBINFO(outputs[1]).mode == MATROXFB_OUTPUT_MODE_PAL) 463 if (minfo->outputs[1].mode == MATROXFB_OUTPUT_MODE_PAL)
464 *data = palregs; 464 *data = palregs;
465 else 465 else
466 *data = ntscregs; 466 *data = ntscregs;
@@ -496,11 +496,11 @@ static void maven_init_TVdata(const struct maven_data* md, struct mavenregs* dat
496 /* Set saturation */ 496 /* Set saturation */
497 { 497 {
498 data->regs[0x20] = 498 data->regs[0x20] =
499 data->regs[0x22] = ACCESS_FBINFO(altout.tvo_params.saturation); 499 data->regs[0x22] = minfo->altout.tvo_params.saturation;
500 } 500 }
501 501
502 /* Set HUE */ 502 /* Set HUE */
503 data->regs[0x25] = ACCESS_FBINFO(altout.tvo_params.hue); 503 data->regs[0x25] = minfo->altout.tvo_params.hue;
504 return; 504 return;
505} 505}
506 506
@@ -741,9 +741,9 @@ static inline int maven_compute_timming(struct maven_data* md,
741 struct mavenregs* m) { 741 struct mavenregs* m) {
742 unsigned int tmpi; 742 unsigned int tmpi;
743 unsigned int a, bv, c; 743 unsigned int a, bv, c;
744 MINFO_FROM(md->primary_head); 744 struct matrox_fb_info *minfo = md->primary_head;
745 745
746 m->mode = ACCESS_FBINFO(outputs[1]).mode; 746 m->mode = minfo->outputs[1].mode;
747 if (m->mode != MATROXFB_OUTPUT_MODE_MONITOR) { 747 if (m->mode != MATROXFB_OUTPUT_MODE_MONITOR) {
748 unsigned int lmargin; 748 unsigned int lmargin;
749 unsigned int umargin; 749 unsigned int umargin;
@@ -1132,7 +1132,7 @@ static int maven_get_control (struct maven_data* md,
1132static int maven_out_compute(void* md, struct my_timming* mt) { 1132static int maven_out_compute(void* md, struct my_timming* mt) {
1133#define mdinfo ((struct maven_data*)md) 1133#define mdinfo ((struct maven_data*)md)
1134#define minfo (mdinfo->primary_head) 1134#define minfo (mdinfo->primary_head)
1135 return maven_compute_timming(md, mt, &ACCESS_FBINFO(hw).maven); 1135 return maven_compute_timming(md, mt, &minfo->hw.maven);
1136#undef minfo 1136#undef minfo
1137#undef mdinfo 1137#undef mdinfo
1138} 1138}
@@ -1140,7 +1140,7 @@ static int maven_out_compute(void* md, struct my_timming* mt) {
1140static int maven_out_program(void* md) { 1140static int maven_out_program(void* md) {
1141#define mdinfo ((struct maven_data*)md) 1141#define mdinfo ((struct maven_data*)md)
1142#define minfo (mdinfo->primary_head) 1142#define minfo (mdinfo->primary_head)
1143 return maven_program_timming(md, &ACCESS_FBINFO(hw).maven); 1143 return maven_program_timming(md, &minfo->hw.maven);
1144#undef minfo 1144#undef minfo
1145#undef mdinfo 1145#undef mdinfo
1146} 1146}
@@ -1184,16 +1184,18 @@ static struct matrox_altout maven_altout = {
1184 1184
1185static int maven_init_client(struct i2c_client* clnt) { 1185static int maven_init_client(struct i2c_client* clnt) {
1186 struct maven_data* md = i2c_get_clientdata(clnt); 1186 struct maven_data* md = i2c_get_clientdata(clnt);
1187 MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo); 1187 struct matrox_fb_info *minfo = container_of(clnt->adapter,
1188 struct i2c_bit_adapter,
1189 adapter)->minfo;
1188 1190
1189 md->primary_head = MINFO; 1191 md->primary_head = minfo;
1190 md->client = clnt; 1192 md->client = clnt;
1191 down_write(&ACCESS_FBINFO(altout.lock)); 1193 down_write(&minfo->altout.lock);
1192 ACCESS_FBINFO(outputs[1]).output = &maven_altout; 1194 minfo->outputs[1].output = &maven_altout;
1193 ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src; 1195 minfo->outputs[1].src = minfo->outputs[1].default_src;
1194 ACCESS_FBINFO(outputs[1]).data = md; 1196 minfo->outputs[1].data = md;
1195 ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 1197 minfo->outputs[1].mode = MATROXFB_OUTPUT_MODE_MONITOR;
1196 up_write(&ACCESS_FBINFO(altout.lock)); 1198 up_write(&minfo->altout.lock);
1197 if (maven_get_reg(clnt, 0xB2) < 0x14) { 1199 if (maven_get_reg(clnt, 0xB2) < 0x14) {
1198 md->version = MGATVO_B; 1200 md->version = MGATVO_B;
1199 /* Tweak some things for this old chip */ 1201 /* Tweak some things for this old chip */
@@ -1218,14 +1220,14 @@ static int maven_shutdown_client(struct i2c_client* clnt) {
1218 struct maven_data* md = i2c_get_clientdata(clnt); 1220 struct maven_data* md = i2c_get_clientdata(clnt);
1219 1221
1220 if (md->primary_head) { 1222 if (md->primary_head) {
1221 MINFO_FROM(md->primary_head); 1223 struct matrox_fb_info *minfo = md->primary_head;
1222 1224
1223 down_write(&ACCESS_FBINFO(altout.lock)); 1225 down_write(&minfo->altout.lock);
1224 ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_NONE; 1226 minfo->outputs[1].src = MATROXFB_SRC_NONE;
1225 ACCESS_FBINFO(outputs[1]).output = NULL; 1227 minfo->outputs[1].output = NULL;
1226 ACCESS_FBINFO(outputs[1]).data = NULL; 1228 minfo->outputs[1].data = NULL;
1227 ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 1229 minfo->outputs[1].mode = MATROXFB_OUTPUT_MODE_MONITOR;
1228 up_write(&ACCESS_FBINFO(altout.lock)); 1230 up_write(&minfo->altout.lock);
1229 md->primary_head = NULL; 1231 md->primary_head = NULL;
1230 } 1232 }
1231 return 0; 1233 return 0;
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c
index 5b5f072fc1a8..9948ca2a3046 100644
--- a/drivers/video/matrox/matroxfb_misc.c
+++ b/drivers/video/matrox/matroxfb_misc.c
@@ -89,13 +89,15 @@
89#include <linux/interrupt.h> 89#include <linux/interrupt.h>
90#include <linux/matroxfb.h> 90#include <linux/matroxfb.h>
91 91
92void matroxfb_DAC_out(CPMINFO int reg, int val) { 92void matroxfb_DAC_out(const struct matrox_fb_info *minfo, int reg, int val)
93{
93 DBG_REG(__func__) 94 DBG_REG(__func__)
94 mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg); 95 mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg);
95 mga_outb(M_RAMDAC_BASE+M_X_DATAREG, val); 96 mga_outb(M_RAMDAC_BASE+M_X_DATAREG, val);
96} 97}
97 98
98int matroxfb_DAC_in(CPMINFO int reg) { 99int matroxfb_DAC_in(const struct matrox_fb_info *minfo, int reg)
100{
99 DBG_REG(__func__) 101 DBG_REG(__func__)
100 mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg); 102 mga_outb(M_RAMDAC_BASE+M_X_INDEX, reg);
101 return mga_inb(M_RAMDAC_BASE+M_X_DATAREG); 103 return mga_inb(M_RAMDAC_BASE+M_X_DATAREG);
@@ -184,13 +186,14 @@ int matroxfb_PLL_calcclock(const struct matrox_pll_features* pll, unsigned int f
184 return bestvco; 186 return bestvco;
185} 187}
186 188
187int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { 189int matroxfb_vgaHWinit(struct matrox_fb_info *minfo, struct my_timming *m)
190{
188 unsigned int hd, hs, he, hbe, ht; 191 unsigned int hd, hs, he, hbe, ht;
189 unsigned int vd, vs, ve, vt, lc; 192 unsigned int vd, vs, ve, vt, lc;
190 unsigned int wd; 193 unsigned int wd;
191 unsigned int divider; 194 unsigned int divider;
192 int i; 195 int i;
193 struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw); 196 struct matrox_hw_state * const hw = &minfo->hw;
194 197
195 DBG(__func__) 198 DBG(__func__)
196 199
@@ -240,7 +243,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) {
240 /* standard timmings are in 8pixels, but for interleaved we cannot */ 243 /* standard timmings are in 8pixels, but for interleaved we cannot */
241 /* do it for 4bpp (because of (4bpp >> 1(interleaved))/4 == 0) */ 244 /* do it for 4bpp (because of (4bpp >> 1(interleaved))/4 == 0) */
242 /* using 16 or more pixels per unit can save us */ 245 /* using 16 or more pixels per unit can save us */
243 divider = ACCESS_FBINFO(curr.final_bppShift); 246 divider = minfo->curr.final_bppShift;
244 while (divider & 3) { 247 while (divider & 3) {
245 hd >>= 1; 248 hd >>= 1;
246 hs >>= 1; 249 hs >>= 1;
@@ -270,7 +273,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) {
270 if (((ht & 0x07) == 0x06) || ((ht & 0x0F) == 0x04)) 273 if (((ht & 0x07) == 0x06) || ((ht & 0x0F) == 0x04))
271 ht++; 274 ht++;
272 hbe = ht; 275 hbe = ht;
273 wd = ACCESS_FBINFO(fbcon).var.xres_virtual * ACCESS_FBINFO(curr.final_bppShift) / 64; 276 wd = minfo->fbcon.var.xres_virtual * minfo->curr.final_bppShift / 64;
274 277
275 hw->CRTCEXT[0] = 0; 278 hw->CRTCEXT[0] = 0;
276 hw->CRTCEXT[5] = 0; 279 hw->CRTCEXT[5] = 0;
@@ -287,7 +290,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) {
287 ((hs & 0x100) >> 6) | /* sync start */ 290 ((hs & 0x100) >> 6) | /* sync start */
288 (hbe & 0x040); /* end hor. blanking */ 291 (hbe & 0x040); /* end hor. blanking */
289 /* FIXME: Enable vidrst only on G400, and only if TV-out is used */ 292 /* FIXME: Enable vidrst only on G400, and only if TV-out is used */
290 if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1) 293 if (minfo->outputs[1].src == MATROXFB_SRC_CRTC1)
291 hw->CRTCEXT[1] |= 0x88; /* enable horizontal and vertical vidrst */ 294 hw->CRTCEXT[1] |= 0x88; /* enable horizontal and vertical vidrst */
292 hw->CRTCEXT[2] = ((vt & 0xC00) >> 10) | 295 hw->CRTCEXT[2] = ((vt & 0xC00) >> 10) |
293 ((vd & 0x400) >> 8) | /* disp end */ 296 ((vd & 0x400) >> 8) | /* disp end */
@@ -331,9 +334,10 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) {
331 return 0; 334 return 0;
332}; 335};
333 336
334void matroxfb_vgaHWrestore(WPMINFO2) { 337void matroxfb_vgaHWrestore(struct matrox_fb_info *minfo)
338{
335 int i; 339 int i;
336 struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw); 340 struct matrox_hw_state * const hw = &minfo->hw;
337 CRITFLAGS 341 CRITFLAGS
338 342
339 DBG(__func__) 343 DBG(__func__)
@@ -522,7 +526,9 @@ static void parse_bios(unsigned char __iomem* vbios, struct matrox_bios* bd) {
522#endif 526#endif
523} 527}
524 528
525static int parse_pins1(WPMINFO const struct matrox_bios* bd) { 529static int parse_pins1(struct matrox_fb_info *minfo,
530 const struct matrox_bios *bd)
531{
526 unsigned int maxdac; 532 unsigned int maxdac;
527 533
528 switch (bd->pins[22]) { 534 switch (bd->pins[22]) {
@@ -533,173 +539,188 @@ static int parse_pins1(WPMINFO const struct matrox_bios* bd) {
533 if (get_unaligned_le16(bd->pins + 24)) { 539 if (get_unaligned_le16(bd->pins + 24)) {
534 maxdac = get_unaligned_le16(bd->pins + 24) * 10; 540 maxdac = get_unaligned_le16(bd->pins + 24) * 10;
535 } 541 }
536 MINFO->limits.pixel.vcomax = maxdac; 542 minfo->limits.pixel.vcomax = maxdac;
537 MINFO->values.pll.system = get_unaligned_le16(bd->pins + 28) ? 543 minfo->values.pll.system = get_unaligned_le16(bd->pins + 28) ?
538 get_unaligned_le16(bd->pins + 28) * 10 : 50000; 544 get_unaligned_le16(bd->pins + 28) * 10 : 50000;
539 /* ignore 4MB, 8MB, module clocks */ 545 /* ignore 4MB, 8MB, module clocks */
540 MINFO->features.pll.ref_freq = 14318; 546 minfo->features.pll.ref_freq = 14318;
541 MINFO->values.reg.mctlwtst = 0x00030101; 547 minfo->values.reg.mctlwtst = 0x00030101;
542 return 0; 548 return 0;
543} 549}
544 550
545static void default_pins1(WPMINFO2) { 551static void default_pins1(struct matrox_fb_info *minfo)
552{
546 /* Millennium */ 553 /* Millennium */
547 MINFO->limits.pixel.vcomax = 220000; 554 minfo->limits.pixel.vcomax = 220000;
548 MINFO->values.pll.system = 50000; 555 minfo->values.pll.system = 50000;
549 MINFO->features.pll.ref_freq = 14318; 556 minfo->features.pll.ref_freq = 14318;
550 MINFO->values.reg.mctlwtst = 0x00030101; 557 minfo->values.reg.mctlwtst = 0x00030101;
551} 558}
552 559
553static int parse_pins2(WPMINFO const struct matrox_bios* bd) { 560static int parse_pins2(struct matrox_fb_info *minfo,
554 MINFO->limits.pixel.vcomax = 561 const struct matrox_bios *bd)
555 MINFO->limits.system.vcomax = (bd->pins[41] == 0xFF) ? 230000 : ((bd->pins[41] + 100) * 1000); 562{
556 MINFO->values.reg.mctlwtst = ((bd->pins[51] & 0x01) ? 0x00000001 : 0) | 563 minfo->limits.pixel.vcomax =
564 minfo->limits.system.vcomax = (bd->pins[41] == 0xFF) ? 230000 : ((bd->pins[41] + 100) * 1000);
565 minfo->values.reg.mctlwtst = ((bd->pins[51] & 0x01) ? 0x00000001 : 0) |
557 ((bd->pins[51] & 0x02) ? 0x00000100 : 0) | 566 ((bd->pins[51] & 0x02) ? 0x00000100 : 0) |
558 ((bd->pins[51] & 0x04) ? 0x00010000 : 0) | 567 ((bd->pins[51] & 0x04) ? 0x00010000 : 0) |
559 ((bd->pins[51] & 0x08) ? 0x00020000 : 0); 568 ((bd->pins[51] & 0x08) ? 0x00020000 : 0);
560 MINFO->values.pll.system = (bd->pins[43] == 0xFF) ? 50000 : ((bd->pins[43] + 100) * 1000); 569 minfo->values.pll.system = (bd->pins[43] == 0xFF) ? 50000 : ((bd->pins[43] + 100) * 1000);
561 MINFO->features.pll.ref_freq = 14318; 570 minfo->features.pll.ref_freq = 14318;
562 return 0; 571 return 0;
563} 572}
564 573
565static void default_pins2(WPMINFO2) { 574static void default_pins2(struct matrox_fb_info *minfo)
575{
566 /* Millennium II, Mystique */ 576 /* Millennium II, Mystique */
567 MINFO->limits.pixel.vcomax = 577 minfo->limits.pixel.vcomax =
568 MINFO->limits.system.vcomax = 230000; 578 minfo->limits.system.vcomax = 230000;
569 MINFO->values.reg.mctlwtst = 0x00030101; 579 minfo->values.reg.mctlwtst = 0x00030101;
570 MINFO->values.pll.system = 50000; 580 minfo->values.pll.system = 50000;
571 MINFO->features.pll.ref_freq = 14318; 581 minfo->features.pll.ref_freq = 14318;
572} 582}
573 583
574static int parse_pins3(WPMINFO const struct matrox_bios* bd) { 584static int parse_pins3(struct matrox_fb_info *minfo,
575 MINFO->limits.pixel.vcomax = 585 const struct matrox_bios *bd)
576 MINFO->limits.system.vcomax = (bd->pins[36] == 0xFF) ? 230000 : ((bd->pins[36] + 100) * 1000); 586{
577 MINFO->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 48) == 0xFFFFFFFF ? 587 minfo->limits.pixel.vcomax =
588 minfo->limits.system.vcomax = (bd->pins[36] == 0xFF) ? 230000 : ((bd->pins[36] + 100) * 1000);
589 minfo->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 48) == 0xFFFFFFFF ?
578 0x01250A21 : get_unaligned_le32(bd->pins + 48); 590 0x01250A21 : get_unaligned_le32(bd->pins + 48);
579 /* memory config */ 591 /* memory config */
580 MINFO->values.reg.memrdbk = ((bd->pins[57] << 21) & 0x1E000000) | 592 minfo->values.reg.memrdbk = ((bd->pins[57] << 21) & 0x1E000000) |
581 ((bd->pins[57] << 22) & 0x00C00000) | 593 ((bd->pins[57] << 22) & 0x00C00000) |
582 ((bd->pins[56] << 1) & 0x000001E0) | 594 ((bd->pins[56] << 1) & 0x000001E0) |
583 ( bd->pins[56] & 0x0000000F); 595 ( bd->pins[56] & 0x0000000F);
584 MINFO->values.reg.opt = (bd->pins[54] & 7) << 10; 596 minfo->values.reg.opt = (bd->pins[54] & 7) << 10;
585 MINFO->values.reg.opt2 = bd->pins[58] << 12; 597 minfo->values.reg.opt2 = bd->pins[58] << 12;
586 MINFO->features.pll.ref_freq = (bd->pins[52] & 0x20) ? 14318 : 27000; 598 minfo->features.pll.ref_freq = (bd->pins[52] & 0x20) ? 14318 : 27000;
587 return 0; 599 return 0;
588} 600}
589 601
590static void default_pins3(WPMINFO2) { 602static void default_pins3(struct matrox_fb_info *minfo)
603{
591 /* G100, G200 */ 604 /* G100, G200 */
592 MINFO->limits.pixel.vcomax = 605 minfo->limits.pixel.vcomax =
593 MINFO->limits.system.vcomax = 230000; 606 minfo->limits.system.vcomax = 230000;
594 MINFO->values.reg.mctlwtst = 0x01250A21; 607 minfo->values.reg.mctlwtst = 0x01250A21;
595 MINFO->values.reg.memrdbk = 0x00000000; 608 minfo->values.reg.memrdbk = 0x00000000;
596 MINFO->values.reg.opt = 0x00000C00; 609 minfo->values.reg.opt = 0x00000C00;
597 MINFO->values.reg.opt2 = 0x00000000; 610 minfo->values.reg.opt2 = 0x00000000;
598 MINFO->features.pll.ref_freq = 27000; 611 minfo->features.pll.ref_freq = 27000;
599} 612}
600 613
601static int parse_pins4(WPMINFO const struct matrox_bios* bd) { 614static int parse_pins4(struct matrox_fb_info *minfo,
602 MINFO->limits.pixel.vcomax = (bd->pins[ 39] == 0xFF) ? 230000 : bd->pins[ 39] * 4000; 615 const struct matrox_bios *bd)
603 MINFO->limits.system.vcomax = (bd->pins[ 38] == 0xFF) ? MINFO->limits.pixel.vcomax : bd->pins[ 38] * 4000; 616{
604 MINFO->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 71); 617 minfo->limits.pixel.vcomax = (bd->pins[ 39] == 0xFF) ? 230000 : bd->pins[ 39] * 4000;
605 MINFO->values.reg.memrdbk = ((bd->pins[87] << 21) & 0x1E000000) | 618 minfo->limits.system.vcomax = (bd->pins[ 38] == 0xFF) ? minfo->limits.pixel.vcomax : bd->pins[ 38] * 4000;
619 minfo->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 71);
620 minfo->values.reg.memrdbk = ((bd->pins[87] << 21) & 0x1E000000) |
606 ((bd->pins[87] << 22) & 0x00C00000) | 621 ((bd->pins[87] << 22) & 0x00C00000) |
607 ((bd->pins[86] << 1) & 0x000001E0) | 622 ((bd->pins[86] << 1) & 0x000001E0) |
608 ( bd->pins[86] & 0x0000000F); 623 ( bd->pins[86] & 0x0000000F);
609 MINFO->values.reg.opt = ((bd->pins[53] << 15) & 0x00400000) | 624 minfo->values.reg.opt = ((bd->pins[53] << 15) & 0x00400000) |
610 ((bd->pins[53] << 22) & 0x10000000) | 625 ((bd->pins[53] << 22) & 0x10000000) |
611 ((bd->pins[53] << 7) & 0x00001C00); 626 ((bd->pins[53] << 7) & 0x00001C00);
612 MINFO->values.reg.opt3 = get_unaligned_le32(bd->pins + 67); 627 minfo->values.reg.opt3 = get_unaligned_le32(bd->pins + 67);
613 MINFO->values.pll.system = (bd->pins[ 65] == 0xFF) ? 200000 : bd->pins[ 65] * 4000; 628 minfo->values.pll.system = (bd->pins[ 65] == 0xFF) ? 200000 : bd->pins[ 65] * 4000;
614 MINFO->features.pll.ref_freq = (bd->pins[ 92] & 0x01) ? 14318 : 27000; 629 minfo->features.pll.ref_freq = (bd->pins[ 92] & 0x01) ? 14318 : 27000;
615 return 0; 630 return 0;
616} 631}
617 632
618static void default_pins4(WPMINFO2) { 633static void default_pins4(struct matrox_fb_info *minfo)
634{
619 /* G400 */ 635 /* G400 */
620 MINFO->limits.pixel.vcomax = 636 minfo->limits.pixel.vcomax =
621 MINFO->limits.system.vcomax = 252000; 637 minfo->limits.system.vcomax = 252000;
622 MINFO->values.reg.mctlwtst = 0x04A450A1; 638 minfo->values.reg.mctlwtst = 0x04A450A1;
623 MINFO->values.reg.memrdbk = 0x000000E7; 639 minfo->values.reg.memrdbk = 0x000000E7;
624 MINFO->values.reg.opt = 0x10000400; 640 minfo->values.reg.opt = 0x10000400;
625 MINFO->values.reg.opt3 = 0x0190A419; 641 minfo->values.reg.opt3 = 0x0190A419;
626 MINFO->values.pll.system = 200000; 642 minfo->values.pll.system = 200000;
627 MINFO->features.pll.ref_freq = 27000; 643 minfo->features.pll.ref_freq = 27000;
628} 644}
629 645
630static int parse_pins5(WPMINFO const struct matrox_bios* bd) { 646static int parse_pins5(struct matrox_fb_info *minfo,
647 const struct matrox_bios *bd)
648{
631 unsigned int mult; 649 unsigned int mult;
632 650
633 mult = bd->pins[4]?8000:6000; 651 mult = bd->pins[4]?8000:6000;
634 652
635 MINFO->limits.pixel.vcomax = (bd->pins[ 38] == 0xFF) ? 600000 : bd->pins[ 38] * mult; 653 minfo->limits.pixel.vcomax = (bd->pins[ 38] == 0xFF) ? 600000 : bd->pins[ 38] * mult;
636 MINFO->limits.system.vcomax = (bd->pins[ 36] == 0xFF) ? MINFO->limits.pixel.vcomax : bd->pins[ 36] * mult; 654 minfo->limits.system.vcomax = (bd->pins[ 36] == 0xFF) ? minfo->limits.pixel.vcomax : bd->pins[ 36] * mult;
637 MINFO->limits.video.vcomax = (bd->pins[ 37] == 0xFF) ? MINFO->limits.system.vcomax : bd->pins[ 37] * mult; 655 minfo->limits.video.vcomax = (bd->pins[ 37] == 0xFF) ? minfo->limits.system.vcomax : bd->pins[ 37] * mult;
638 MINFO->limits.pixel.vcomin = (bd->pins[123] == 0xFF) ? 256000 : bd->pins[123] * mult; 656 minfo->limits.pixel.vcomin = (bd->pins[123] == 0xFF) ? 256000 : bd->pins[123] * mult;
639 MINFO->limits.system.vcomin = (bd->pins[121] == 0xFF) ? MINFO->limits.pixel.vcomin : bd->pins[121] * mult; 657 minfo->limits.system.vcomin = (bd->pins[121] == 0xFF) ? minfo->limits.pixel.vcomin : bd->pins[121] * mult;
640 MINFO->limits.video.vcomin = (bd->pins[122] == 0xFF) ? MINFO->limits.system.vcomin : bd->pins[122] * mult; 658 minfo->limits.video.vcomin = (bd->pins[122] == 0xFF) ? minfo->limits.system.vcomin : bd->pins[122] * mult;
641 MINFO->values.pll.system = 659 minfo->values.pll.system =
642 MINFO->values.pll.video = (bd->pins[ 92] == 0xFF) ? 284000 : bd->pins[ 92] * 4000; 660 minfo->values.pll.video = (bd->pins[ 92] == 0xFF) ? 284000 : bd->pins[ 92] * 4000;
643 MINFO->values.reg.opt = get_unaligned_le32(bd->pins + 48); 661 minfo->values.reg.opt = get_unaligned_le32(bd->pins + 48);
644 MINFO->values.reg.opt2 = get_unaligned_le32(bd->pins + 52); 662 minfo->values.reg.opt2 = get_unaligned_le32(bd->pins + 52);
645 MINFO->values.reg.opt3 = get_unaligned_le32(bd->pins + 94); 663 minfo->values.reg.opt3 = get_unaligned_le32(bd->pins + 94);
646 MINFO->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 98); 664 minfo->values.reg.mctlwtst = get_unaligned_le32(bd->pins + 98);
647 MINFO->values.reg.memmisc = get_unaligned_le32(bd->pins + 102); 665 minfo->values.reg.memmisc = get_unaligned_le32(bd->pins + 102);
648 MINFO->values.reg.memrdbk = get_unaligned_le32(bd->pins + 106); 666 minfo->values.reg.memrdbk = get_unaligned_le32(bd->pins + 106);
649 MINFO->features.pll.ref_freq = (bd->pins[110] & 0x01) ? 14318 : 27000; 667 minfo->features.pll.ref_freq = (bd->pins[110] & 0x01) ? 14318 : 27000;
650 MINFO->values.memory.ddr = (bd->pins[114] & 0x60) == 0x20; 668 minfo->values.memory.ddr = (bd->pins[114] & 0x60) == 0x20;
651 MINFO->values.memory.dll = (bd->pins[115] & 0x02) != 0; 669 minfo->values.memory.dll = (bd->pins[115] & 0x02) != 0;
652 MINFO->values.memory.emrswen = (bd->pins[115] & 0x01) != 0; 670 minfo->values.memory.emrswen = (bd->pins[115] & 0x01) != 0;
653 MINFO->values.reg.maccess = MINFO->values.memory.emrswen ? 0x00004000 : 0x00000000; 671 minfo->values.reg.maccess = minfo->values.memory.emrswen ? 0x00004000 : 0x00000000;
654 if (bd->pins[115] & 4) { 672 if (bd->pins[115] & 4) {
655 MINFO->values.reg.mctlwtst_core = MINFO->values.reg.mctlwtst; 673 minfo->values.reg.mctlwtst_core = minfo->values.reg.mctlwtst;
656 } else { 674 } else {
657 u_int32_t wtst_xlat[] = { 0, 1, 5, 6, 7, 5, 2, 3 }; 675 u_int32_t wtst_xlat[] = { 0, 1, 5, 6, 7, 5, 2, 3 };
658 MINFO->values.reg.mctlwtst_core = (MINFO->values.reg.mctlwtst & ~7) | 676 minfo->values.reg.mctlwtst_core = (minfo->values.reg.mctlwtst & ~7) |
659 wtst_xlat[MINFO->values.reg.mctlwtst & 7]; 677 wtst_xlat[minfo->values.reg.mctlwtst & 7];
660 } 678 }
661 MINFO->max_pixel_clock_panellink = bd->pins[47] * 4000; 679 minfo->max_pixel_clock_panellink = bd->pins[47] * 4000;
662 return 0; 680 return 0;
663} 681}
664 682
665static void default_pins5(WPMINFO2) { 683static void default_pins5(struct matrox_fb_info *minfo)
684{
666 /* Mine 16MB G450 with SDRAM DDR */ 685 /* Mine 16MB G450 with SDRAM DDR */
667 MINFO->limits.pixel.vcomax = 686 minfo->limits.pixel.vcomax =
668 MINFO->limits.system.vcomax = 687 minfo->limits.system.vcomax =
669 MINFO->limits.video.vcomax = 600000; 688 minfo->limits.video.vcomax = 600000;
670 MINFO->limits.pixel.vcomin = 689 minfo->limits.pixel.vcomin =
671 MINFO->limits.system.vcomin = 690 minfo->limits.system.vcomin =
672 MINFO->limits.video.vcomin = 256000; 691 minfo->limits.video.vcomin = 256000;
673 MINFO->values.pll.system = 692 minfo->values.pll.system =
674 MINFO->values.pll.video = 284000; 693 minfo->values.pll.video = 284000;
675 MINFO->values.reg.opt = 0x404A1160; 694 minfo->values.reg.opt = 0x404A1160;
676 MINFO->values.reg.opt2 = 0x0000AC00; 695 minfo->values.reg.opt2 = 0x0000AC00;
677 MINFO->values.reg.opt3 = 0x0090A409; 696 minfo->values.reg.opt3 = 0x0090A409;
678 MINFO->values.reg.mctlwtst_core = 697 minfo->values.reg.mctlwtst_core =
679 MINFO->values.reg.mctlwtst = 0x0C81462B; 698 minfo->values.reg.mctlwtst = 0x0C81462B;
680 MINFO->values.reg.memmisc = 0x80000004; 699 minfo->values.reg.memmisc = 0x80000004;
681 MINFO->values.reg.memrdbk = 0x01001103; 700 minfo->values.reg.memrdbk = 0x01001103;
682 MINFO->features.pll.ref_freq = 27000; 701 minfo->features.pll.ref_freq = 27000;
683 MINFO->values.memory.ddr = 1; 702 minfo->values.memory.ddr = 1;
684 MINFO->values.memory.dll = 1; 703 minfo->values.memory.dll = 1;
685 MINFO->values.memory.emrswen = 1; 704 minfo->values.memory.emrswen = 1;
686 MINFO->values.reg.maccess = 0x00004000; 705 minfo->values.reg.maccess = 0x00004000;
687} 706}
688 707
689static int matroxfb_set_limits(WPMINFO const struct matrox_bios* bd) { 708static int matroxfb_set_limits(struct matrox_fb_info *minfo,
709 const struct matrox_bios *bd)
710{
690 unsigned int pins_version; 711 unsigned int pins_version;
691 static const unsigned int pinslen[] = { 64, 64, 64, 128, 128 }; 712 static const unsigned int pinslen[] = { 64, 64, 64, 128, 128 };
692 713
693 switch (ACCESS_FBINFO(chip)) { 714 switch (minfo->chip) {
694 case MGA_2064: default_pins1(PMINFO2); break; 715 case MGA_2064: default_pins1(minfo); break;
695 case MGA_2164: 716 case MGA_2164:
696 case MGA_1064: 717 case MGA_1064:
697 case MGA_1164: default_pins2(PMINFO2); break; 718 case MGA_1164: default_pins2(minfo); break;
698 case MGA_G100: 719 case MGA_G100:
699 case MGA_G200: default_pins3(PMINFO2); break; 720 case MGA_G200: default_pins3(minfo); break;
700 case MGA_G400: default_pins4(PMINFO2); break; 721 case MGA_G400: default_pins4(minfo); break;
701 case MGA_G450: 722 case MGA_G450:
702 case MGA_G550: default_pins5(PMINFO2); break; 723 case MGA_G550: default_pins5(minfo); break;
703 } 724 }
704 if (!bd->bios_valid) { 725 if (!bd->bios_valid) {
705 printk(KERN_INFO "matroxfb: Your Matrox device does not have BIOS\n"); 726 printk(KERN_INFO "matroxfb: Your Matrox device does not have BIOS\n");
@@ -724,38 +745,39 @@ static int matroxfb_set_limits(WPMINFO const struct matrox_bios* bd) {
724 } 745 }
725 switch (pins_version) { 746 switch (pins_version) {
726 case 1: 747 case 1:
727 return parse_pins1(PMINFO bd); 748 return parse_pins1(minfo, bd);
728 case 2: 749 case 2:
729 return parse_pins2(PMINFO bd); 750 return parse_pins2(minfo, bd);
730 case 3: 751 case 3:
731 return parse_pins3(PMINFO bd); 752 return parse_pins3(minfo, bd);
732 case 4: 753 case 4:
733 return parse_pins4(PMINFO bd); 754 return parse_pins4(minfo, bd);
734 case 5: 755 case 5:
735 return parse_pins5(PMINFO bd); 756 return parse_pins5(minfo, bd);
736 default: 757 default:
737 printk(KERN_DEBUG "matroxfb: Powerup info version %u is not yet supported\n", pins_version); 758 printk(KERN_DEBUG "matroxfb: Powerup info version %u is not yet supported\n", pins_version);
738 return -1; 759 return -1;
739 } 760 }
740} 761}
741 762
742void matroxfb_read_pins(WPMINFO2) { 763void matroxfb_read_pins(struct matrox_fb_info *minfo)
764{
743 u32 opt; 765 u32 opt;
744 u32 biosbase; 766 u32 biosbase;
745 u32 fbbase; 767 u32 fbbase;
746 struct pci_dev* pdev = ACCESS_FBINFO(pcidev); 768 struct pci_dev *pdev = minfo->pcidev;
747 769
748 memset(&ACCESS_FBINFO(bios), 0, sizeof(ACCESS_FBINFO(bios))); 770 memset(&minfo->bios, 0, sizeof(minfo->bios));
749 pci_read_config_dword(pdev, PCI_OPTION_REG, &opt); 771 pci_read_config_dword(pdev, PCI_OPTION_REG, &opt);
750 pci_write_config_dword(pdev, PCI_OPTION_REG, opt | PCI_OPTION_ENABLE_ROM); 772 pci_write_config_dword(pdev, PCI_OPTION_REG, opt | PCI_OPTION_ENABLE_ROM);
751 pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &biosbase); 773 pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &biosbase);
752 pci_read_config_dword(pdev, ACCESS_FBINFO(devflags.fbResource), &fbbase); 774 pci_read_config_dword(pdev, minfo->devflags.fbResource, &fbbase);
753 pci_write_config_dword(pdev, PCI_ROM_ADDRESS, (fbbase & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE); 775 pci_write_config_dword(pdev, PCI_ROM_ADDRESS, (fbbase & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
754 parse_bios(vaddr_va(ACCESS_FBINFO(video).vbase), &ACCESS_FBINFO(bios)); 776 parse_bios(vaddr_va(minfo->video.vbase), &minfo->bios);
755 pci_write_config_dword(pdev, PCI_ROM_ADDRESS, biosbase); 777 pci_write_config_dword(pdev, PCI_ROM_ADDRESS, biosbase);
756 pci_write_config_dword(pdev, PCI_OPTION_REG, opt); 778 pci_write_config_dword(pdev, PCI_OPTION_REG, opt);
757#ifdef CONFIG_X86 779#ifdef CONFIG_X86
758 if (!ACCESS_FBINFO(bios).bios_valid) { 780 if (!minfo->bios.bios_valid) {
759 unsigned char __iomem* b; 781 unsigned char __iomem* b;
760 782
761 b = ioremap(0x000C0000, 65536); 783 b = ioremap(0x000C0000, 65536);
@@ -769,25 +791,21 @@ void matroxfb_read_pins(WPMINFO2) {
769 printk(KERN_INFO "matroxfb: Legacy BIOS is for %04X:%04X, while this device is %04X:%04X\n", 791 printk(KERN_INFO "matroxfb: Legacy BIOS is for %04X:%04X, while this device is %04X:%04X\n",
770 ven, dev, pdev->vendor, pdev->device); 792 ven, dev, pdev->vendor, pdev->device);
771 } else { 793 } else {
772 parse_bios(b, &ACCESS_FBINFO(bios)); 794 parse_bios(b, &minfo->bios);
773 } 795 }
774 iounmap(b); 796 iounmap(b);
775 } 797 }
776 } 798 }
777#endif 799#endif
778 matroxfb_set_limits(PMINFO &ACCESS_FBINFO(bios)); 800 matroxfb_set_limits(minfo, &minfo->bios);
779 printk(KERN_INFO "PInS memtype = %u\n", 801 printk(KERN_INFO "PInS memtype = %u\n",
780 (ACCESS_FBINFO(values).reg.opt & 0x1C00) >> 10); 802 (minfo->values.reg.opt & 0x1C00) >> 10);
781} 803}
782 804
783EXPORT_SYMBOL(matroxfb_DAC_in); 805EXPORT_SYMBOL(matroxfb_DAC_in);
784EXPORT_SYMBOL(matroxfb_DAC_out); 806EXPORT_SYMBOL(matroxfb_DAC_out);
785EXPORT_SYMBOL(matroxfb_var2my); 807EXPORT_SYMBOL(matroxfb_var2my);
786EXPORT_SYMBOL(matroxfb_PLL_calcclock); 808EXPORT_SYMBOL(matroxfb_PLL_calcclock);
787#ifndef CONFIG_FB_MATROX_MULTIHEAD
788struct matrox_fb_info matroxfb_global_mxinfo;
789EXPORT_SYMBOL(matroxfb_global_mxinfo);
790#endif
791EXPORT_SYMBOL(matroxfb_vgaHWinit); /* DAC1064, Ti3026 */ 809EXPORT_SYMBOL(matroxfb_vgaHWinit); /* DAC1064, Ti3026 */
792EXPORT_SYMBOL(matroxfb_vgaHWrestore); /* DAC1064, Ti3026 */ 810EXPORT_SYMBOL(matroxfb_vgaHWrestore); /* DAC1064, Ti3026 */
793EXPORT_SYMBOL(matroxfb_read_pins); 811EXPORT_SYMBOL(matroxfb_read_pins);
diff --git a/drivers/video/matrox/matroxfb_misc.h b/drivers/video/matrox/matroxfb_misc.h
index cb62cc0ead96..351c823f1f74 100644
--- a/drivers/video/matrox/matroxfb_misc.h
+++ b/drivers/video/matrox/matroxfb_misc.h
@@ -6,13 +6,16 @@
6/* also for modules */ 6/* also for modules */
7int matroxfb_PLL_calcclock(const struct matrox_pll_features* pll, unsigned int freq, unsigned int fmax, 7int matroxfb_PLL_calcclock(const struct matrox_pll_features* pll, unsigned int freq, unsigned int fmax,
8 unsigned int* in, unsigned int* feed, unsigned int* post); 8 unsigned int* in, unsigned int* feed, unsigned int* post);
9static inline int PLL_calcclock(CPMINFO unsigned int freq, unsigned int fmax, 9static inline int PLL_calcclock(const struct matrox_fb_info *minfo,
10 unsigned int* in, unsigned int* feed, unsigned int* post) { 10 unsigned int freq, unsigned int fmax,
11 return matroxfb_PLL_calcclock(&ACCESS_FBINFO(features.pll), freq, fmax, in, feed, post); 11 unsigned int *in, unsigned int *feed,
12 unsigned int *post)
13{
14 return matroxfb_PLL_calcclock(&minfo->features.pll, freq, fmax, in, feed, post);
12} 15}
13 16
14int matroxfb_vgaHWinit(WPMINFO struct my_timming* m); 17int matroxfb_vgaHWinit(struct matrox_fb_info *minfo, struct my_timming* m);
15void matroxfb_vgaHWrestore(WPMINFO2); 18void matroxfb_vgaHWrestore(struct matrox_fb_info *minfo);
16void matroxfb_read_pins(WPMINFO2); 19void matroxfb_read_pins(struct matrox_fb_info *minfo);
17 20
18#endif /* __MATROXFB_MISC_H__ */ 21#endif /* __MATROXFB_MISC_H__ */
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
new file mode 100644
index 000000000000..802d6ae523fb
--- /dev/null
+++ b/drivers/video/msm/Makefile
@@ -0,0 +1,19 @@
1
2# core framebuffer
3#
4obj-y := msm_fb.o
5
6# MDP DMA/PPP engine
7#
8obj-y += mdp.o mdp_scale_tables.o mdp_ppp.o
9
10# MDDI interface
11#
12obj-y += mddi.o
13
14# MDDI client/panel drivers
15#
16obj-y += mddi_client_dummy.o
17obj-y += mddi_client_toshiba.o
18obj-y += mddi_client_nt35399.o
19
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
new file mode 100644
index 000000000000..f2de5a1acd6d
--- /dev/null
+++ b/drivers/video/msm/mddi.c
@@ -0,0 +1,828 @@
1/*
2 * MSM MDDI Transport
3 *
4 * Copyright (C) 2007 Google Incorporated
5 * Copyright (C) 2007 QUALCOMM Incorporated
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/dma-mapping.h>
21#include <linux/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/delay.h>
24#include <linux/spinlock.h>
25#include <linux/clk.h>
26#include <linux/io.h>
27#include <mach/msm_iomap.h>
28#include <mach/irqs.h>
29#include <mach/board.h>
30#include <linux/delay.h>
31
32#include <mach/msm_fb.h>
33#include "mddi_hw.h"
34
35#define FLAG_DISABLE_HIBERNATION 0x0001
36#define FLAG_HAVE_CAPS 0x0002
37#define FLAG_HAS_VSYNC_IRQ 0x0004
38#define FLAG_HAVE_STATUS 0x0008
39
40#define CMD_GET_CLIENT_CAP 0x0601
41#define CMD_GET_CLIENT_STATUS 0x0602
42
43union mddi_rev {
44 unsigned char raw[MDDI_REV_BUFFER_SIZE];
45 struct mddi_rev_packet hdr;
46 struct mddi_client_status status;
47 struct mddi_client_caps caps;
48 struct mddi_register_access reg;
49};
50
51struct reg_read_info {
52 struct completion done;
53 uint32_t reg;
54 uint32_t status;
55 uint32_t result;
56};
57
58struct mddi_info {
59 uint16_t flags;
60 uint16_t version;
61 char __iomem *base;
62 int irq;
63 struct clk *clk;
64 struct msm_mddi_client_data client_data;
65
66 /* buffer for rev encap packets */
67 void *rev_data;
68 dma_addr_t rev_addr;
69 struct mddi_llentry *reg_write_data;
70 dma_addr_t reg_write_addr;
71 struct mddi_llentry *reg_read_data;
72 dma_addr_t reg_read_addr;
73 size_t rev_data_curr;
74
75 spinlock_t int_lock;
76 uint32_t int_enable;
77 uint32_t got_int;
78 wait_queue_head_t int_wait;
79
80 struct mutex reg_write_lock;
81 struct mutex reg_read_lock;
82 struct reg_read_info *reg_read;
83
84 struct mddi_client_caps caps;
85 struct mddi_client_status status;
86
87 void (*power_client)(struct msm_mddi_client_data *, int);
88
89 /* client device published to bind us to the
90 * appropriate mddi_client driver
91 */
92 char client_name[20];
93
94 struct platform_device client_pdev;
95};
96
97static void mddi_init_rev_encap(struct mddi_info *mddi);
98
99#define mddi_readl(r) readl(mddi->base + (MDDI_##r))
100#define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r))
101
102void mddi_activate_link(struct msm_mddi_client_data *cdata)
103{
104 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
105 client_data);
106
107 mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
108}
109
110static void mddi_handle_link_list_done(struct mddi_info *mddi)
111{
112}
113
114static void mddi_reset_rev_encap_ptr(struct mddi_info *mddi)
115{
116 printk(KERN_INFO "mddi: resetting rev ptr\n");
117 mddi->rev_data_curr = 0;
118 mddi_writel(mddi->rev_addr, REV_PTR);
119 mddi_writel(mddi->rev_addr, REV_PTR);
120 mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
121}
122
123static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev)
124{
125 int i;
126 struct reg_read_info *ri;
127
128 if ((rev->hdr.length <= MDDI_REV_BUFFER_SIZE - 2) &&
129 (rev->hdr.length >= sizeof(struct mddi_rev_packet) - 2)) {
130
131 switch (rev->hdr.type) {
132 case TYPE_CLIENT_CAPS:
133 memcpy(&mddi->caps, &rev->caps,
134 sizeof(struct mddi_client_caps));
135 mddi->flags |= FLAG_HAVE_CAPS;
136 wake_up(&mddi->int_wait);
137 break;
138 case TYPE_CLIENT_STATUS:
139 memcpy(&mddi->status, &rev->status,
140 sizeof(struct mddi_client_status));
141 mddi->flags |= FLAG_HAVE_STATUS;
142 wake_up(&mddi->int_wait);
143 break;
144 case TYPE_REGISTER_ACCESS:
145 ri = mddi->reg_read;
146 if (ri == 0) {
147 printk(KERN_INFO "rev: got reg %x = %x without "
148 " pending read\n",
149 rev->reg.register_address,
150 rev->reg.register_data_list);
151 break;
152 }
153 if (ri->reg != rev->reg.register_address) {
154 printk(KERN_INFO "rev: got reg %x = %x for "
155 "wrong register, expected "
156 "%x\n",
157 rev->reg.register_address,
158 rev->reg.register_data_list, ri->reg);
159 break;
160 }
161 mddi->reg_read = NULL;
162 ri->status = 0;
163 ri->result = rev->reg.register_data_list;
164 complete(&ri->done);
165 break;
166 default:
167 printk(KERN_INFO "rev: unknown reverse packet: "
168 "len=%04x type=%04x CURR_REV_PTR=%x\n",
169 rev->hdr.length, rev->hdr.type,
170 mddi_readl(CURR_REV_PTR));
171 for (i = 0; i < rev->hdr.length + 2; i++) {
172 if ((i % 16) == 0)
173 printk(KERN_INFO "\n");
174 printk(KERN_INFO " %02x", rev->raw[i]);
175 }
176 printk(KERN_INFO "\n");
177 mddi_reset_rev_encap_ptr(mddi);
178 }
179 } else {
180 printk(KERN_INFO "bad rev length, %d, CURR_REV_PTR %x\n",
181 rev->hdr.length, mddi_readl(CURR_REV_PTR));
182 mddi_reset_rev_encap_ptr(mddi);
183 }
184}
185
186static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);
187
188static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
189{
190 union mddi_rev *rev = mddi->rev_data;
191 uint32_t rev_data_count;
192 uint32_t rev_crc_err_count;
193 int i;
194 struct reg_read_info *ri;
195 size_t prev_offset;
196 uint16_t length;
197
198 union mddi_rev *crev = mddi->rev_data + mddi->rev_data_curr;
199
200 /* clear the interrupt */
201 mddi_writel(MDDI_INT_REV_DATA_AVAIL, INT);
202 rev_data_count = mddi_readl(REV_PKT_CNT);
203 rev_crc_err_count = mddi_readl(REV_CRC_ERR);
204 if (rev_data_count > 1)
205 printk(KERN_INFO "rev_data_count %d\n", rev_data_count);
206
207 if (rev_crc_err_count) {
208 printk(KERN_INFO "rev_crc_err_count %d, INT %x\n",
209 rev_crc_err_count, mddi_readl(INT));
210 ri = mddi->reg_read;
211 if (ri == 0) {
212 printk(KERN_INFO "rev: got crc error without pending "
213 "read\n");
214 } else {
215 mddi->reg_read = NULL;
216 ri->status = -EIO;
217 ri->result = -1;
218 complete(&ri->done);
219 }
220 }
221
222 if (rev_data_count == 0)
223 return;
224
225 prev_offset = mddi->rev_data_curr;
226
227 length = *((uint8_t *)mddi->rev_data + mddi->rev_data_curr);
228 mddi->rev_data_curr++;
229 if (mddi->rev_data_curr == MDDI_REV_BUFFER_SIZE)
230 mddi->rev_data_curr = 0;
231 length += *((uint8_t *)mddi->rev_data + mddi->rev_data_curr) << 8;
232 mddi->rev_data_curr += 1 + length;
233 if (mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE)
234 mddi->rev_data_curr =
235 mddi->rev_data_curr % MDDI_REV_BUFFER_SIZE;
236
237 if (length > MDDI_REV_BUFFER_SIZE - 2) {
238 printk(KERN_INFO "mddi: rev data length greater than buffer"
239 "size\n");
240 mddi_reset_rev_encap_ptr(mddi);
241 return;
242 }
243
244 if (prev_offset + 2 + length >= MDDI_REV_BUFFER_SIZE) {
245 union mddi_rev tmprev;
246 size_t rem = MDDI_REV_BUFFER_SIZE - prev_offset;
247 memcpy(&tmprev.raw[0], mddi->rev_data + prev_offset, rem);
248 memcpy(&tmprev.raw[rem], mddi->rev_data, 2 + length - rem);
249 mddi_handle_rev_data(mddi, &tmprev);
250 } else {
251 mddi_handle_rev_data(mddi, crev);
252 }
253
254 if (prev_offset < MDDI_REV_BUFFER_SIZE / 2 &&
255 mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE / 2) {
256 mddi_writel(mddi->rev_addr, REV_PTR);
257 }
258}
259
260static irqreturn_t mddi_isr(int irq, void *data)
261{
262 struct msm_mddi_client_data *cdata = data;
263 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
264 client_data);
265 uint32_t active, status;
266
267 spin_lock(&mddi->int_lock);
268
269 active = mddi_readl(INT);
270 status = mddi_readl(STAT);
271
272 mddi_writel(active, INT);
273
274 /* ignore any interrupts we have disabled */
275 active &= mddi->int_enable;
276
277 mddi->got_int |= active;
278 wake_up(&mddi->int_wait);
279
280 if (active & MDDI_INT_PRI_LINK_LIST_DONE) {
281 mddi->int_enable &= (~MDDI_INT_PRI_LINK_LIST_DONE);
282 mddi_handle_link_list_done(mddi);
283 }
284 if (active & MDDI_INT_REV_DATA_AVAIL)
285 mddi_handle_rev_data_avail(mddi);
286
287 if (active & ~MDDI_INT_NEED_CLEAR)
288 mddi->int_enable &= ~(active & ~MDDI_INT_NEED_CLEAR);
289
290 if (active & MDDI_INT_LINK_ACTIVE) {
291 mddi->int_enable &= (~MDDI_INT_LINK_ACTIVE);
292 mddi->int_enable |= MDDI_INT_IN_HIBERNATION;
293 }
294
295 if (active & MDDI_INT_IN_HIBERNATION) {
296 mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION);
297 mddi->int_enable |= MDDI_INT_LINK_ACTIVE;
298 }
299
300 mddi_writel(mddi->int_enable, INTEN);
301 spin_unlock(&mddi->int_lock);
302
303 return IRQ_HANDLED;
304}
305
306static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
307 uint32_t intmask, int timeout)
308{
309 unsigned long irq_flags;
310
311 spin_lock_irqsave(&mddi->int_lock, irq_flags);
312 mddi->got_int &= ~intmask;
313 mddi->int_enable |= intmask;
314 mddi_writel(mddi->int_enable, INTEN);
315 spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
316 return wait_event_timeout(mddi->int_wait, mddi->got_int & intmask,
317 timeout);
318}
319
320static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask)
321{
322 if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0)
323 printk(KERN_INFO KERN_ERR "mddi_wait_interrupt %d, timeout "
324 "waiting for %x, INT = %x, STAT = %x gotint = %x\n",
325 current->pid, intmask, mddi_readl(INT), mddi_readl(STAT),
326 mddi->got_int);
327}
328
329static void mddi_init_rev_encap(struct mddi_info *mddi)
330{
331 memset(mddi->rev_data, 0xee, MDDI_REV_BUFFER_SIZE);
332 mddi_writel(mddi->rev_addr, REV_PTR);
333 mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
334 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
335}
336
337void mddi_set_auto_hibernate(struct msm_mddi_client_data *cdata, int on)
338{
339 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
340 client_data);
341 mddi_writel(MDDI_CMD_POWERDOWN, CMD);
342 mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION);
343 mddi_writel(MDDI_CMD_HIBERNATE | !!on, CMD);
344 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
345}
346
347
348static uint16_t mddi_init_registers(struct mddi_info *mddi)
349{
350 mddi_writel(0x0001, VERSION);
351 mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS);
352 mddi_writel(0x0003, SPM); /* subframes per media */
353 mddi_writel(0x0005, TA1_LEN);
354 mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN);
355 mddi_writel(0x0096, DRIVE_HI);
356 /* 0x32 normal, 0x50 for Toshiba display */
357 mddi_writel(0x0050, DRIVE_LO);
358 mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */
359 mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV);
360
361 mddi_writel(MDDI_REV_BUFFER_SIZE, REV_SIZE);
362 mddi_writel(MDDI_MAX_REV_PKT_SIZE, REV_ENCAP_SZ);
363
364 /* disable periodic rev encap */
365 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP, CMD);
366 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
367
368 if (mddi_readl(PAD_CTL) == 0) {
369 /* If we are turning on band gap, need to wait 5us before
370 * turning on the rest of the PAD */
371 mddi_writel(0x08000, PAD_CTL);
372 udelay(5);
373 }
374
375 /* Recommendation from PAD hw team */
376 mddi_writel(0xa850f, PAD_CTL);
377
378
379 /* Need an even number for counts */
380 mddi_writel(0x60006, DRIVER_START_CNT);
381
382 mddi_set_auto_hibernate(&mddi->client_data, 0);
383
384 mddi_writel(MDDI_CMD_DISP_IGNORE, CMD);
385 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
386
387 mddi_init_rev_encap(mddi);
388 return mddi_readl(CORE_VER) & 0xffff;
389}
390
391static void mddi_suspend(struct msm_mddi_client_data *cdata)
392{
393 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
394 client_data);
395 /* turn off the client */
396 if (mddi->power_client)
397 mddi->power_client(&mddi->client_data, 0);
398 /* turn off the link */
399 mddi_writel(MDDI_CMD_RESET, CMD);
400 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
401 /* turn off the clock */
402 clk_disable(mddi->clk);
403}
404
405static void mddi_resume(struct msm_mddi_client_data *cdata)
406{
407 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
408 client_data);
409 mddi_set_auto_hibernate(&mddi->client_data, 0);
410 /* turn on the client */
411 if (mddi->power_client)
412 mddi->power_client(&mddi->client_data, 1);
413 /* turn on the clock */
414 clk_enable(mddi->clk);
415 /* set up the local registers */
416 mddi->rev_data_curr = 0;
417 mddi_init_registers(mddi);
418 mddi_writel(mddi->int_enable, INTEN);
419 mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
420 mddi_writel(MDDI_CMD_SEND_RTD, CMD);
421 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
422 mddi_set_auto_hibernate(&mddi->client_data, 1);
423}
424
425static int __init mddi_get_client_caps(struct mddi_info *mddi)
426{
427 int i, j;
428
429 /* clear any stale interrupts */
430 mddi_writel(0xffffffff, INT);
431
432 mddi->int_enable = MDDI_INT_LINK_ACTIVE |
433 MDDI_INT_IN_HIBERNATION |
434 MDDI_INT_PRI_LINK_LIST_DONE |
435 MDDI_INT_REV_DATA_AVAIL |
436 MDDI_INT_REV_OVERFLOW |
437 MDDI_INT_REV_OVERWRITE |
438 MDDI_INT_RTD_FAILURE;
439 mddi_writel(mddi->int_enable, INTEN);
440
441 mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
442 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
443
444 for (j = 0; j < 3; j++) {
445 /* the toshiba vga panel does not respond to get
446 * caps unless you SEND_RTD, but the first SEND_RTD
447 * will fail...
448 */
449 for (i = 0; i < 4; i++) {
450 uint32_t stat;
451
452 mddi_writel(MDDI_CMD_SEND_RTD, CMD);
453 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
454 stat = mddi_readl(STAT);
455 printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, "
456 "rtd val %x\n", mddi_readl(INT), stat,
457 mddi_readl(RTD_VAL));
458 if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0)
459 break;
460 msleep(1);
461 }
462
463 mddi_writel(CMD_GET_CLIENT_CAP, CMD);
464 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
465 wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS,
466 HZ / 100);
467
468 if (mddi->flags & FLAG_HAVE_CAPS)
469 break;
470 printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for "
471 "caps\n");
472 }
473 return mddi->flags & FLAG_HAVE_CAPS;
474}
475
476/* link must be active when this is called */
477int mddi_check_status(struct mddi_info *mddi)
478{
479 int ret = -1, retry = 3;
480 mutex_lock(&mddi->reg_read_lock);
481 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
482 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
483
484 do {
485 mddi->flags &= ~FLAG_HAVE_STATUS;
486 mddi_writel(CMD_GET_CLIENT_STATUS, CMD);
487 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
488 wait_event_timeout(mddi->int_wait,
489 mddi->flags & FLAG_HAVE_STATUS,
490 HZ / 100);
491
492 if (mddi->flags & FLAG_HAVE_STATUS) {
493 if (mddi->status.crc_error_count)
494 printk(KERN_INFO "mddi status: crc_error "
495 "count: %d\n",
496 mddi->status.crc_error_count);
497 else
498 ret = 0;
499 break;
500 } else
501 printk(KERN_INFO "mddi status: failed to get client "
502 "status\n");
503 mddi_writel(MDDI_CMD_SEND_RTD, CMD);
504 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
505 } while (--retry);
506
507 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
508 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
509 mutex_unlock(&mddi->reg_read_lock);
510 return ret;
511}
512
513
514void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val,
515 uint32_t reg)
516{
517 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
518 client_data);
519 struct mddi_llentry *ll;
520 struct mddi_register_access *ra;
521
522 mutex_lock(&mddi->reg_write_lock);
523
524 ll = mddi->reg_write_data;
525
526 ra = &(ll->u.r);
527 ra->length = 14 + 4;
528 ra->type = TYPE_REGISTER_ACCESS;
529 ra->client_id = 0;
530 ra->read_write_info = MDDI_WRITE | 1;
531 ra->crc16 = 0;
532
533 ra->register_address = reg;
534 ra->register_data_list = val;
535
536 ll->flags = 1;
537 ll->header_count = 14;
538 ll->data_count = 4;
539 ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry,
540 u.r.register_data_list);
541 ll->next = 0;
542 ll->reserved = 0;
543
544 mddi_writel(mddi->reg_write_addr, PRI_PTR);
545
546 mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
547 mutex_unlock(&mddi->reg_write_lock);
548}
549
550uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
551{
552 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
553 client_data);
554 struct mddi_llentry *ll;
555 struct mddi_register_access *ra;
556 struct reg_read_info ri;
557 unsigned s;
558 int retry_count = 2;
559 unsigned long irq_flags;
560
561 mutex_lock(&mddi->reg_read_lock);
562
563 ll = mddi->reg_read_data;
564
565 ra = &(ll->u.r);
566 ra->length = 14;
567 ra->type = TYPE_REGISTER_ACCESS;
568 ra->client_id = 0;
569 ra->read_write_info = MDDI_READ | 1;
570 ra->crc16 = 0;
571
572 ra->register_address = reg;
573
574 ll->flags = 0x11;
575 ll->header_count = 14;
576 ll->data_count = 0;
577 ll->data = 0;
578 ll->next = 0;
579 ll->reserved = 0;
580
581 s = mddi_readl(STAT);
582
583 ri.reg = reg;
584 ri.status = -1;
585
586 do {
587 init_completion(&ri.done);
588 mddi->reg_read = &ri;
589 mddi_writel(mddi->reg_read_addr, PRI_PTR);
590
591 mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
592
593 /* Enable Periodic Reverse Encapsulation. */
594 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
595 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
596 if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 &&
597 !ri.done.done) {
598 printk(KERN_INFO "mddi_remote_read(%x) timeout "
599 "(%d %d %d)\n",
600 reg, ri.status, ri.result, ri.done.done);
601 spin_lock_irqsave(&mddi->int_lock, irq_flags);
602 mddi->reg_read = NULL;
603 spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
604 ri.status = -1;
605 ri.result = -1;
606 }
607 if (ri.status == 0)
608 break;
609
610 mddi_writel(MDDI_CMD_SEND_RTD, CMD);
611 mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
612 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
613 printk(KERN_INFO "mddi_remote_read: failed, sent "
614 "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x "
615 "curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT),
616 mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR));
617 } while (retry_count-- > 0);
618 /* Disable Periodic Reverse Encapsulation. */
619 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
620 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
621 mddi->reg_read = NULL;
622 mutex_unlock(&mddi->reg_read_lock);
623 return ri.result;
624}
625
626static struct mddi_info mddi_info[2];
627
628static int __init mddi_clk_setup(struct platform_device *pdev,
629 struct mddi_info *mddi,
630 unsigned long clk_rate)
631{
632 int ret;
633
634 /* set up the clocks */
635 mddi->clk = clk_get(&pdev->dev, "mddi_clk");
636 if (IS_ERR(mddi->clk)) {
637 printk(KERN_INFO "mddi: failed to get clock\n");
638 return PTR_ERR(mddi->clk);
639 }
640 ret = clk_enable(mddi->clk);
641 if (ret)
642 goto fail;
643 ret = clk_set_rate(mddi->clk, clk_rate);
644 if (ret)
645 goto fail;
646 return 0;
647
648fail:
649 clk_put(mddi->clk);
650 return ret;
651}
652
653static int __init mddi_rev_data_setup(struct mddi_info *mddi)
654{
655 void *dma;
656 dma_addr_t dma_addr;
657
658 /* set up dma buffer */
659 dma = dma_alloc_coherent(NULL, 0x1000, &dma_addr, GFP_KERNEL);
660 if (dma == 0)
661 return -ENOMEM;
662 mddi->rev_data = dma;
663 mddi->rev_data_curr = 0;
664 mddi->rev_addr = dma_addr;
665 mddi->reg_write_data = dma + MDDI_REV_BUFFER_SIZE;
666 mddi->reg_write_addr = dma_addr + MDDI_REV_BUFFER_SIZE;
667 mddi->reg_read_data = mddi->reg_write_data + 1;
668 mddi->reg_read_addr = mddi->reg_write_addr +
669 sizeof(*mddi->reg_write_data);
670 return 0;
671}
672
673static int __init mddi_probe(struct platform_device *pdev)
674{
675 struct msm_mddi_platform_data *pdata = pdev->dev.platform_data;
676 struct mddi_info *mddi = &mddi_info[pdev->id];
677 struct resource *resource;
678 int ret, i;
679
680 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
681 if (!resource) {
682 printk(KERN_ERR "mddi: no associated mem resource!\n");
683 return -ENOMEM;
684 }
685 mddi->base = ioremap(resource->start, resource->end - resource->start);
686 if (!mddi->base) {
687 printk(KERN_ERR "mddi: failed to remap base!\n");
688 ret = -EINVAL;
689 goto error_ioremap;
690 }
691 resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
692 if (!resource) {
693 printk(KERN_ERR "mddi: no associated irq resource!\n");
694 ret = -EINVAL;
695 goto error_get_irq_resource;
696 }
697 mddi->irq = resource->start;
698 printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base,
699 mddi->irq);
700 mddi->power_client = pdata->power_client;
701
702 mutex_init(&mddi->reg_write_lock);
703 mutex_init(&mddi->reg_read_lock);
704 spin_lock_init(&mddi->int_lock);
705 init_waitqueue_head(&mddi->int_wait);
706
707 ret = mddi_clk_setup(pdev, mddi, pdata->clk_rate);
708 if (ret) {
709 printk(KERN_ERR "mddi: failed to setup clock!\n");
710 goto error_clk_setup;
711 }
712
713 ret = mddi_rev_data_setup(mddi);
714 if (ret) {
715 printk(KERN_ERR "mddi: failed to setup rev data!\n");
716 goto error_rev_data;
717 }
718
719 mddi->int_enable = 0;
720 mddi_writel(mddi->int_enable, INTEN);
721 ret = request_irq(mddi->irq, mddi_isr, IRQF_DISABLED, "mddi",
722 &mddi->client_data);
723 if (ret) {
724 printk(KERN_ERR "mddi: failed to request enable irq!\n");
725 goto error_request_irq;
726 }
727
728 /* turn on the mddi client bridge chip */
729 if (mddi->power_client)
730 mddi->power_client(&mddi->client_data, 1);
731
732 /* initialize the mddi registers */
733 mddi_set_auto_hibernate(&mddi->client_data, 0);
734 mddi_writel(MDDI_CMD_RESET, CMD);
735 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
736 mddi->version = mddi_init_registers(mddi);
737 if (mddi->version < 0x20) {
738 printk(KERN_ERR "mddi: unsupported version 0x%x\n",
739 mddi->version);
740 ret = -ENODEV;
741 goto error_mddi_version;
742 }
743
744 /* read the capabilities off the client */
745 if (!mddi_get_client_caps(mddi)) {
746 printk(KERN_INFO "mddi: no client found\n");
747 /* power down the panel */
748 mddi_writel(MDDI_CMD_POWERDOWN, CMD);
749 printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
750 msleep(100);
751 printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
752 return 0;
753 }
754 mddi_set_auto_hibernate(&mddi->client_data, 1);
755
756 if (mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 0)
757 pdata->fixup(&mddi->caps.Mfr_Name, &mddi->caps.Product_Code);
758
759 mddi->client_pdev.id = 0;
760 for (i = 0; i < pdata->num_clients; i++) {
761 if (pdata->client_platform_data[i].product_id ==
762 (mddi->caps.Mfr_Name << 16 | mddi->caps.Product_Code)) {
763 mddi->client_data.private_client_data =
764 pdata->client_platform_data[i].client_data;
765 mddi->client_pdev.name =
766 pdata->client_platform_data[i].name;
767 mddi->client_pdev.id =
768 pdata->client_platform_data[i].id;
769 /* XXX: possibly set clock */
770 break;
771 }
772 }
773
774 if (i >= pdata->num_clients)
775 mddi->client_pdev.name = "mddi_c_dummy";
776 printk(KERN_INFO "mddi: registering panel %s\n",
777 mddi->client_pdev.name);
778
779 mddi->client_data.suspend = mddi_suspend;
780 mddi->client_data.resume = mddi_resume;
781 mddi->client_data.activate_link = mddi_activate_link;
782 mddi->client_data.remote_write = mddi_remote_write;
783 mddi->client_data.remote_read = mddi_remote_read;
784 mddi->client_data.auto_hibernate = mddi_set_auto_hibernate;
785 mddi->client_data.fb_resource = pdata->fb_resource;
786 if (pdev->id == 0)
787 mddi->client_data.interface_type = MSM_MDDI_PMDH_INTERFACE;
788 else if (pdev->id == 1)
789 mddi->client_data.interface_type = MSM_MDDI_EMDH_INTERFACE;
790 else {
791 printk(KERN_ERR "mddi: can not determine interface %d!\n",
792 pdev->id);
793 ret = -EINVAL;
794 goto error_mddi_interface;
795 }
796
797 mddi->client_pdev.dev.platform_data = &mddi->client_data;
798 printk(KERN_INFO "mddi: publish: %s\n", mddi->client_name);
799 platform_device_register(&mddi->client_pdev);
800 return 0;
801
802error_mddi_interface:
803error_mddi_version:
804 free_irq(mddi->irq, 0);
805error_request_irq:
806 dma_free_coherent(NULL, 0x1000, mddi->rev_data, mddi->rev_addr);
807error_rev_data:
808error_clk_setup:
809error_get_irq_resource:
810 iounmap(mddi->base);
811error_ioremap:
812
813 printk(KERN_INFO "mddi: mddi_init() failed (%d)\n", ret);
814 return ret;
815}
816
817
818static struct platform_driver mddi_driver = {
819 .probe = mddi_probe,
820 .driver = { .name = "msm_mddi" },
821};
822
823static int __init _mddi_init(void)
824{
825 return platform_driver_register(&mddi_driver);
826}
827
828module_init(_mddi_init);
diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/msm/mddi_client_dummy.c
new file mode 100644
index 000000000000..ebbae87885b6
--- /dev/null
+++ b/drivers/video/msm/mddi_client_dummy.c
@@ -0,0 +1,97 @@
1/* drivers/video/msm_fb/mddi_client_dummy.c
2 *
3 * Support for "dummy" mddi client devices which require no
4 * special initialization code.
5 *
6 * Copyright (C) 2007 Google Incorporated
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/platform_device.h>
21
22#include <mach/msm_fb.h>
23
24struct panel_info {
25 struct platform_device pdev;
26 struct msm_panel_data panel_data;
27};
28
29static int mddi_dummy_suspend(struct msm_panel_data *panel_data)
30{
31 return 0;
32}
33
34static int mddi_dummy_resume(struct msm_panel_data *panel_data)
35{
36 return 0;
37}
38
39static int mddi_dummy_blank(struct msm_panel_data *panel_data)
40{
41 return 0;
42}
43
44static int mddi_dummy_unblank(struct msm_panel_data *panel_data)
45{
46 return 0;
47}
48
49static int mddi_dummy_probe(struct platform_device *pdev)
50{
51 struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
52 struct panel_info *panel =
53 kzalloc(sizeof(struct panel_info), GFP_KERNEL);
54 int ret;
55 if (!panel)
56 return -ENOMEM;
57 platform_set_drvdata(pdev, panel);
58 panel->panel_data.suspend = mddi_dummy_suspend;
59 panel->panel_data.resume = mddi_dummy_resume;
60 panel->panel_data.blank = mddi_dummy_blank;
61 panel->panel_data.unblank = mddi_dummy_unblank;
62 panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
63 panel->pdev.name = "msm_panel";
64 panel->pdev.id = pdev->id;
65 platform_device_add_resources(&panel->pdev,
66 client_data->fb_resource, 1);
67 panel->panel_data.fb_data = client_data->private_client_data;
68 panel->pdev.dev.platform_data = &panel->panel_data;
69 ret = platform_device_register(&panel->pdev);
70 if (ret) {
71 kfree(panel);
72 return ret;
73 }
74 return 0;
75}
76
77static int mddi_dummy_remove(struct platform_device *pdev)
78{
79 struct panel_info *panel = platform_get_drvdata(pdev);
80 kfree(panel);
81 return 0;
82}
83
84static struct platform_driver mddi_client_dummy = {
85 .probe = mddi_dummy_probe,
86 .remove = mddi_dummy_remove,
87 .driver = { .name = "mddi_c_dummy" },
88};
89
90static int __init mddi_client_dummy_init(void)
91{
92 platform_driver_register(&mddi_client_dummy);
93 return 0;
94}
95
96module_init(mddi_client_dummy_init);
97
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
new file mode 100644
index 000000000000..9c78050ac799
--- /dev/null
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -0,0 +1,255 @@
1/* drivers/video/msm_fb/mddi_client_nt35399.c
2 *
3 * Support for Novatek NT35399 MDDI client of Sapphire
4 *
5 * Copyright (C) 2008 HTC Incorporated
6 * Author: Solomon Chiu (solomon_chiu@htc.com)
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h>
22#include <linux/gpio.h>
23#include <mach/msm_fb.h>
24
25static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
26
27struct panel_info {
28 struct msm_mddi_client_data *client_data;
29 struct platform_device pdev;
30 struct msm_panel_data panel_data;
31 struct msmfb_callback *fb_callback;
32 struct work_struct panel_work;
33 struct workqueue_struct *fb_wq;
34 int nt35399_got_int;
35};
36
37static void
38nt35399_request_vsync(struct msm_panel_data *panel_data,
39 struct msmfb_callback *callback)
40{
41 struct panel_info *panel = container_of(panel_data, struct panel_info,
42 panel_data);
43 struct msm_mddi_client_data *client_data = panel->client_data;
44
45 panel->fb_callback = callback;
46 if (panel->nt35399_got_int) {
47 panel->nt35399_got_int = 0;
48 client_data->activate_link(client_data); /* clears interrupt */
49 }
50}
51
52static void nt35399_wait_vsync(struct msm_panel_data *panel_data)
53{
54 struct panel_info *panel = container_of(panel_data, struct panel_info,
55 panel_data);
56 struct msm_mddi_client_data *client_data = panel->client_data;
57
58 if (panel->nt35399_got_int) {
59 panel->nt35399_got_int = 0;
60 client_data->activate_link(client_data); /* clears interrupt */
61 }
62
63 if (wait_event_timeout(nt35399_vsync_wait, panel->nt35399_got_int,
64 HZ/2) == 0)
65 printk(KERN_ERR "timeout waiting for VSYNC\n");
66
67 panel->nt35399_got_int = 0;
68 /* interrupt clears when screen dma starts */
69}
70
71static int nt35399_suspend(struct msm_panel_data *panel_data)
72{
73 struct panel_info *panel = container_of(panel_data, struct panel_info,
74 panel_data);
75 struct msm_mddi_client_data *client_data = panel->client_data;
76
77 struct msm_mddi_bridge_platform_data *bridge_data =
78 client_data->private_client_data;
79 int ret;
80
81 ret = bridge_data->uninit(bridge_data, client_data);
82 if (ret) {
83 printk(KERN_INFO "mddi nt35399 client: non zero return from "
84 "uninit\n");
85 return ret;
86 }
87 client_data->suspend(client_data);
88 return 0;
89}
90
91static int nt35399_resume(struct msm_panel_data *panel_data)
92{
93 struct panel_info *panel = container_of(panel_data, struct panel_info,
94 panel_data);
95 struct msm_mddi_client_data *client_data = panel->client_data;
96
97 struct msm_mddi_bridge_platform_data *bridge_data =
98 client_data->private_client_data;
99 int ret;
100
101 client_data->resume(client_data);
102 ret = bridge_data->init(bridge_data, client_data);
103 if (ret)
104 return ret;
105 return 0;
106}
107
108static int nt35399_blank(struct msm_panel_data *panel_data)
109{
110 struct panel_info *panel = container_of(panel_data, struct panel_info,
111 panel_data);
112 struct msm_mddi_client_data *client_data = panel->client_data;
113 struct msm_mddi_bridge_platform_data *bridge_data =
114 client_data->private_client_data;
115
116 return bridge_data->blank(bridge_data, client_data);
117}
118
119static int nt35399_unblank(struct msm_panel_data *panel_data)
120{
121 struct panel_info *panel = container_of(panel_data, struct panel_info,
122 panel_data);
123 struct msm_mddi_client_data *client_data = panel->client_data;
124 struct msm_mddi_bridge_platform_data *bridge_data =
125 client_data->private_client_data;
126
127 return bridge_data->unblank(bridge_data, client_data);
128}
129
130irqreturn_t nt35399_vsync_interrupt(int irq, void *data)
131{
132 struct panel_info *panel = data;
133
134 panel->nt35399_got_int = 1;
135
136 if (panel->fb_callback) {
137 panel->fb_callback->func(panel->fb_callback);
138 panel->fb_callback = NULL;
139 }
140
141 wake_up(&nt35399_vsync_wait);
142
143 return IRQ_HANDLED;
144}
145
146static int setup_vsync(struct panel_info *panel, int init)
147{
148 int ret;
149 int gpio = 97;
150 unsigned int irq;
151
152 if (!init) {
153 ret = 0;
154 goto uninit;
155 }
156 ret = gpio_request(gpio, "vsync");
157 if (ret)
158 goto err_request_gpio_failed;
159
160 ret = gpio_direction_input(gpio);
161 if (ret)
162 goto err_gpio_direction_input_failed;
163
164 ret = irq = gpio_to_irq(gpio);
165 if (ret < 0)
166 goto err_get_irq_num_failed;
167
168 ret = request_irq(irq, nt35399_vsync_interrupt, IRQF_TRIGGER_RISING,
169 "vsync", panel);
170 if (ret)
171 goto err_request_irq_failed;
172
173 printk(KERN_INFO "vsync on gpio %d now %d\n",
174 gpio, gpio_get_value(gpio));
175 return 0;
176
177uninit:
178 free_irq(gpio_to_irq(gpio), panel->client_data);
179err_request_irq_failed:
180err_get_irq_num_failed:
181err_gpio_direction_input_failed:
182 gpio_free(gpio);
183err_request_gpio_failed:
184 return ret;
185}
186
187static int mddi_nt35399_probe(struct platform_device *pdev)
188{
189 struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
190 struct msm_mddi_bridge_platform_data *bridge_data =
191 client_data->private_client_data;
192
193 int ret;
194
195 struct panel_info *panel = kzalloc(sizeof(struct panel_info),
196 GFP_KERNEL);
197
198 printk(KERN_DEBUG "%s: enter.\n", __func__);
199
200 if (!panel)
201 return -ENOMEM;
202 platform_set_drvdata(pdev, panel);
203
204 ret = setup_vsync(panel, 1);
205 if (ret) {
206 dev_err(&pdev->dev, "mddi_nt35399_setup_vsync failed\n");
207 return ret;
208 }
209
210 panel->client_data = client_data;
211 panel->panel_data.suspend = nt35399_suspend;
212 panel->panel_data.resume = nt35399_resume;
213 panel->panel_data.wait_vsync = nt35399_wait_vsync;
214 panel->panel_data.request_vsync = nt35399_request_vsync;
215 panel->panel_data.blank = nt35399_blank;
216 panel->panel_data.unblank = nt35399_unblank;
217 panel->panel_data.fb_data = &bridge_data->fb_data;
218 panel->panel_data.caps = 0;
219
220 panel->pdev.name = "msm_panel";
221 panel->pdev.id = pdev->id;
222 panel->pdev.resource = client_data->fb_resource;
223 panel->pdev.num_resources = 1;
224 panel->pdev.dev.platform_data = &panel->panel_data;
225
226 if (bridge_data->init)
227 bridge_data->init(bridge_data, client_data);
228
229 platform_device_register(&panel->pdev);
230
231 return 0;
232}
233
234static int mddi_nt35399_remove(struct platform_device *pdev)
235{
236 struct panel_info *panel = platform_get_drvdata(pdev);
237
238 setup_vsync(panel, 0);
239 kfree(panel);
240 return 0;
241}
242
243static struct platform_driver mddi_client_0bda_8a47 = {
244 .probe = mddi_nt35399_probe,
245 .remove = mddi_nt35399_remove,
246 .driver = { .name = "mddi_c_0bda_8a47" },
247};
248
249static int __init mddi_client_nt35399_init(void)
250{
251 return platform_driver_register(&mddi_client_0bda_8a47);
252}
253
254module_init(mddi_client_nt35399_init);
255
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c
new file mode 100644
index 000000000000..80d0f5fdf0b1
--- /dev/null
+++ b/drivers/video/msm/mddi_client_toshiba.c
@@ -0,0 +1,283 @@
1/* drivers/video/msm_fb/mddi_client_toshiba.c
2 *
3 * Support for Toshiba TC358720XBG mddi client devices which require no
4 * special initialization code.
5 *
6 * Copyright (C) 2007 Google Incorporated
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h>
22#include <linux/gpio.h>
23#include <mach/msm_fb.h>
24
25
26#define LCD_CONTROL_BLOCK_BASE 0x110000
27#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
28#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
29#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
30#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
31#define VPOS (LCD_CONTROL_BLOCK_BASE|0xC0)
32#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
33#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
34#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
35#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
36
37#define BASE5 0x150000
38#define BASE6 0x160000
39#define BASE7 0x170000
40
41#define GPIOIEV (BASE5 + 0x10)
42#define GPIOIE (BASE5 + 0x14)
43#define GPIORIS (BASE5 + 0x18)
44#define GPIOMIS (BASE5 + 0x1C)
45#define GPIOIC (BASE5 + 0x20)
46
47#define INTMASK (BASE6 + 0x0C)
48#define INTMASK_VWAKEOUT (1U << 0)
49#define INTMASK_VWAKEOUT_ACTIVE_LOW (1U << 8)
50#define GPIOSEL (BASE7 + 0x00)
51#define GPIOSEL_VWAKEINT (1U << 0)
52
53static DECLARE_WAIT_QUEUE_HEAD(toshiba_vsync_wait);
54
55struct panel_info {
56 struct msm_mddi_client_data *client_data;
57 struct platform_device pdev;
58 struct msm_panel_data panel_data;
59 struct msmfb_callback *toshiba_callback;
60 int toshiba_got_int;
61};
62
63
64static void toshiba_request_vsync(struct msm_panel_data *panel_data,
65 struct msmfb_callback *callback)
66{
67 struct panel_info *panel = container_of(panel_data, struct panel_info,
68 panel_data);
69 struct msm_mddi_client_data *client_data = panel->client_data;
70
71 panel->toshiba_callback = callback;
72 if (panel->toshiba_got_int) {
73 panel->toshiba_got_int = 0;
74 client_data->activate_link(client_data);
75 }
76}
77
78static void toshiba_clear_vsync(struct msm_panel_data *panel_data)
79{
80 struct panel_info *panel = container_of(panel_data, struct panel_info,
81 panel_data);
82 struct msm_mddi_client_data *client_data = panel->client_data;
83
84 client_data->activate_link(client_data);
85}
86
87static void toshiba_wait_vsync(struct msm_panel_data *panel_data)
88{
89 struct panel_info *panel = container_of(panel_data, struct panel_info,
90 panel_data);
91 struct msm_mddi_client_data *client_data = panel->client_data;
92
93 if (panel->toshiba_got_int) {
94 panel->toshiba_got_int = 0;
95 client_data->activate_link(client_data); /* clears interrupt */
96 }
97 if (wait_event_timeout(toshiba_vsync_wait, panel->toshiba_got_int,
98 HZ/2) == 0)
99 printk(KERN_ERR "timeout waiting for VSYNC\n");
100 panel->toshiba_got_int = 0;
101 /* interrupt clears when screen dma starts */
102}
103
104static int toshiba_suspend(struct msm_panel_data *panel_data)
105{
106 struct panel_info *panel = container_of(panel_data, struct panel_info,
107 panel_data);
108 struct msm_mddi_client_data *client_data = panel->client_data;
109
110 struct msm_mddi_bridge_platform_data *bridge_data =
111 client_data->private_client_data;
112 int ret;
113
114 ret = bridge_data->uninit(bridge_data, client_data);
115 if (ret) {
116 printk(KERN_INFO "mddi toshiba client: non zero return from "
117 "uninit\n");
118 return ret;
119 }
120 client_data->suspend(client_data);
121 return 0;
122}
123
124static int toshiba_resume(struct msm_panel_data *panel_data)
125{
126 struct panel_info *panel = container_of(panel_data, struct panel_info,
127 panel_data);
128 struct msm_mddi_client_data *client_data = panel->client_data;
129
130 struct msm_mddi_bridge_platform_data *bridge_data =
131 client_data->private_client_data;
132 int ret;
133
134 client_data->resume(client_data);
135 ret = bridge_data->init(bridge_data, client_data);
136 if (ret)
137 return ret;
138 return 0;
139}
140
141static int toshiba_blank(struct msm_panel_data *panel_data)
142{
143 struct panel_info *panel = container_of(panel_data, struct panel_info,
144 panel_data);
145 struct msm_mddi_client_data *client_data = panel->client_data;
146 struct msm_mddi_bridge_platform_data *bridge_data =
147 client_data->private_client_data;
148
149 return bridge_data->blank(bridge_data, client_data);
150}
151
152static int toshiba_unblank(struct msm_panel_data *panel_data)
153{
154 struct panel_info *panel = container_of(panel_data, struct panel_info,
155 panel_data);
156 struct msm_mddi_client_data *client_data = panel->client_data;
157 struct msm_mddi_bridge_platform_data *bridge_data =
158 client_data->private_client_data;
159
160 return bridge_data->unblank(bridge_data, client_data);
161}
162
163irqreturn_t toshiba_vsync_interrupt(int irq, void *data)
164{
165 struct panel_info *panel = data;
166
167 panel->toshiba_got_int = 1;
168 if (panel->toshiba_callback) {
169 panel->toshiba_callback->func(panel->toshiba_callback);
170 panel->toshiba_callback = 0;
171 }
172 wake_up(&toshiba_vsync_wait);
173 return IRQ_HANDLED;
174}
175
176static int setup_vsync(struct panel_info *panel,
177 int init)
178{
179 int ret;
180 int gpio = 97;
181 unsigned int irq;
182
183 if (!init) {
184 ret = 0;
185 goto uninit;
186 }
187 ret = gpio_request(gpio, "vsync");
188 if (ret)
189 goto err_request_gpio_failed;
190
191 ret = gpio_direction_input(gpio);
192 if (ret)
193 goto err_gpio_direction_input_failed;
194
195 ret = irq = gpio_to_irq(gpio);
196 if (ret < 0)
197 goto err_get_irq_num_failed;
198
199 ret = request_irq(irq, toshiba_vsync_interrupt, IRQF_TRIGGER_RISING,
200 "vsync", panel);
201 if (ret)
202 goto err_request_irq_failed;
203 printk(KERN_INFO "vsync on gpio %d now %d\n",
204 gpio, gpio_get_value(gpio));
205 return 0;
206
207uninit:
208 free_irq(gpio_to_irq(gpio), panel);
209err_request_irq_failed:
210err_get_irq_num_failed:
211err_gpio_direction_input_failed:
212 gpio_free(gpio);
213err_request_gpio_failed:
214 return ret;
215}
216
217static int mddi_toshiba_probe(struct platform_device *pdev)
218{
219 int ret;
220 struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
221 struct msm_mddi_bridge_platform_data *bridge_data =
222 client_data->private_client_data;
223 struct panel_info *panel =
224 kzalloc(sizeof(struct panel_info), GFP_KERNEL);
225 if (!panel)
226 return -ENOMEM;
227 platform_set_drvdata(pdev, panel);
228
229 /* mddi_remote_write(mddi, 0, WAKEUP); */
230 client_data->remote_write(client_data, GPIOSEL_VWAKEINT, GPIOSEL);
231 client_data->remote_write(client_data, INTMASK_VWAKEOUT, INTMASK);
232
233 ret = setup_vsync(panel, 1);
234 if (ret) {
235 dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n");
236 return ret;
237 }
238
239 panel->client_data = client_data;
240 panel->panel_data.suspend = toshiba_suspend;
241 panel->panel_data.resume = toshiba_resume;
242 panel->panel_data.wait_vsync = toshiba_wait_vsync;
243 panel->panel_data.request_vsync = toshiba_request_vsync;
244 panel->panel_data.clear_vsync = toshiba_clear_vsync;
245 panel->panel_data.blank = toshiba_blank;
246 panel->panel_data.unblank = toshiba_unblank;
247 panel->panel_data.fb_data = &bridge_data->fb_data;
248 panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
249
250 panel->pdev.name = "msm_panel";
251 panel->pdev.id = pdev->id;
252 panel->pdev.resource = client_data->fb_resource;
253 panel->pdev.num_resources = 1;
254 panel->pdev.dev.platform_data = &panel->panel_data;
255 bridge_data->init(bridge_data, client_data);
256 platform_device_register(&panel->pdev);
257
258 return 0;
259}
260
261static int mddi_toshiba_remove(struct platform_device *pdev)
262{
263 struct panel_info *panel = platform_get_drvdata(pdev);
264
265 setup_vsync(panel, 0);
266 kfree(panel);
267 return 0;
268}
269
270static struct platform_driver mddi_client_d263_0000 = {
271 .probe = mddi_toshiba_probe,
272 .remove = mddi_toshiba_remove,
273 .driver = { .name = "mddi_c_d263_0000" },
274};
275
276static int __init mddi_client_toshiba_init(void)
277{
278 platform_driver_register(&mddi_client_d263_0000);
279 return 0;
280}
281
282module_init(mddi_client_toshiba_init);
283
diff --git a/drivers/video/msm/mddi_hw.h b/drivers/video/msm/mddi_hw.h
new file mode 100644
index 000000000000..45cc01fc1e7f
--- /dev/null
+++ b/drivers/video/msm/mddi_hw.h
@@ -0,0 +1,305 @@
1/* drivers/video/msm_fb/mddi_hw.h
2 *
3 * MSM MDDI Hardware Registers and Structures
4 *
5 * Copyright (C) 2007 QUALCOMM Incorporated
6 * Copyright (C) 2007 Google Incorporated
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#ifndef _MDDI_HW_H_
19#define _MDDI_HW_H_
20
21#include <linux/types.h>
22
23#define MDDI_CMD 0x0000
24#define MDDI_VERSION 0x0004
25#define MDDI_PRI_PTR 0x0008
26#define MDDI_SEC_PTR 0x000c
27#define MDDI_BPS 0x0010
28#define MDDI_SPM 0x0014
29#define MDDI_INT 0x0018
30#define MDDI_INTEN 0x001c
31#define MDDI_REV_PTR 0x0020
32#define MDDI_REV_SIZE 0x0024
33#define MDDI_STAT 0x0028
34#define MDDI_REV_RATE_DIV 0x002c
35#define MDDI_REV_CRC_ERR 0x0030
36#define MDDI_TA1_LEN 0x0034
37#define MDDI_TA2_LEN 0x0038
38#define MDDI_TEST_BUS 0x003c
39#define MDDI_TEST 0x0040
40#define MDDI_REV_PKT_CNT 0x0044
41#define MDDI_DRIVE_HI 0x0048
42#define MDDI_DRIVE_LO 0x004c
43#define MDDI_DISP_WAKE 0x0050
44#define MDDI_REV_ENCAP_SZ 0x0054
45#define MDDI_RTD_VAL 0x0058
46#define MDDI_PAD_CTL 0x0068
47#define MDDI_DRIVER_START_CNT 0x006c
48#define MDDI_NEXT_PRI_PTR 0x0070
49#define MDDI_NEXT_SEC_PTR 0x0074
50#define MDDI_MISR_CTL 0x0078
51#define MDDI_MISR_DATA 0x007c
52#define MDDI_SF_CNT 0x0080
53#define MDDI_MF_CNT 0x0084
54#define MDDI_CURR_REV_PTR 0x0088
55#define MDDI_CORE_VER 0x008c
56
57#define MDDI_INT_PRI_PTR_READ 0x0001
58#define MDDI_INT_SEC_PTR_READ 0x0002
59#define MDDI_INT_REV_DATA_AVAIL 0x0004
60#define MDDI_INT_DISP_REQ 0x0008
61#define MDDI_INT_PRI_UNDERFLOW 0x0010
62#define MDDI_INT_SEC_UNDERFLOW 0x0020
63#define MDDI_INT_REV_OVERFLOW 0x0040
64#define MDDI_INT_CRC_ERROR 0x0080
65#define MDDI_INT_MDDI_IN 0x0100
66#define MDDI_INT_PRI_OVERWRITE 0x0200
67#define MDDI_INT_SEC_OVERWRITE 0x0400
68#define MDDI_INT_REV_OVERWRITE 0x0800
69#define MDDI_INT_DMA_FAILURE 0x1000
70#define MDDI_INT_LINK_ACTIVE 0x2000
71#define MDDI_INT_IN_HIBERNATION 0x4000
72#define MDDI_INT_PRI_LINK_LIST_DONE 0x8000
73#define MDDI_INT_SEC_LINK_LIST_DONE 0x10000
74#define MDDI_INT_NO_CMD_PKTS_PEND 0x20000
75#define MDDI_INT_RTD_FAILURE 0x40000
76#define MDDI_INT_REV_PKT_RECEIVED 0x80000
77#define MDDI_INT_REV_PKTS_AVAIL 0x100000
78
79#define MDDI_INT_NEED_CLEAR ( \
80 MDDI_INT_REV_DATA_AVAIL | \
81 MDDI_INT_PRI_UNDERFLOW | \
82 MDDI_INT_SEC_UNDERFLOW | \
83 MDDI_INT_REV_OVERFLOW | \
84 MDDI_INT_CRC_ERROR | \
85 MDDI_INT_REV_PKT_RECEIVED)
86
87
88#define MDDI_STAT_LINK_ACTIVE 0x0001
89#define MDDI_STAT_NEW_REV_PTR 0x0002
90#define MDDI_STAT_NEW_PRI_PTR 0x0004
91#define MDDI_STAT_NEW_SEC_PTR 0x0008
92#define MDDI_STAT_IN_HIBERNATION 0x0010
93#define MDDI_STAT_PRI_LINK_LIST_DONE 0x0020
94#define MDDI_STAT_SEC_LINK_LIST_DONE 0x0040
95#define MDDI_STAT_PENDING_TIMING_PKT 0x0080
96#define MDDI_STAT_PENDING_REV_ENCAP 0x0100
97#define MDDI_STAT_PENDING_POWERDOWN 0x0200
98#define MDDI_STAT_RTD_MEAS_FAIL 0x0800
99#define MDDI_STAT_CLIENT_WAKEUP_REQ 0x1000
100
101
102#define MDDI_CMD_POWERDOWN 0x0100
103#define MDDI_CMD_POWERUP 0x0200
104#define MDDI_CMD_HIBERNATE 0x0300
105#define MDDI_CMD_RESET 0x0400
106#define MDDI_CMD_DISP_IGNORE 0x0501
107#define MDDI_CMD_DISP_LISTEN 0x0500
108#define MDDI_CMD_SEND_REV_ENCAP 0x0600
109#define MDDI_CMD_GET_CLIENT_CAP 0x0601
110#define MDDI_CMD_GET_CLIENT_STATUS 0x0602
111#define MDDI_CMD_SEND_RTD 0x0700
112#define MDDI_CMD_LINK_ACTIVE 0x0900
113#define MDDI_CMD_PERIODIC_REV_ENCAP 0x0A00
114#define MDDI_CMD_FORCE_NEW_REV_PTR 0x0C00
115
116
117
118#define MDDI_VIDEO_REV_PKT_SIZE 0x40
119#define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE 0x60
120#define MDDI_MAX_REV_PKT_SIZE 0x60
121
122/* #define MDDI_REV_BUFFER_SIZE 128 */
123#define MDDI_REV_BUFFER_SIZE (MDDI_MAX_REV_PKT_SIZE * 4)
124
125/* MDP sends 256 pixel packets, so lower value hibernates more without
126 * significantly increasing latency of waiting for next subframe */
127#define MDDI_HOST_BYTES_PER_SUBFRAME 0x3C00
128#define MDDI_HOST_TA2_LEN 0x000c
129#define MDDI_HOST_REV_RATE_DIV 0x0002
130
131
132struct __attribute__((packed)) mddi_rev_packet {
133 uint16_t length;
134 uint16_t type;
135 uint16_t client_id;
136};
137
138struct __attribute__((packed)) mddi_client_status {
139 uint16_t length;
140 uint16_t type;
141 uint16_t client_id;
142 uint16_t reverse_link_request; /* bytes needed in rev encap message */
143 uint8_t crc_error_count;
144 uint8_t capability_change;
145 uint16_t graphics_busy_flags;
146 uint16_t crc16;
147};
148
149struct __attribute__((packed)) mddi_client_caps {
150 uint16_t length; /* length, exclusive of this field */
151 uint16_t type; /* 66 */
152 uint16_t client_id;
153
154 uint16_t Protocol_Version;
155 uint16_t Minimum_Protocol_Version;
156 uint16_t Data_Rate_Capability;
157 uint8_t Interface_Type_Capability;
158 uint8_t Number_of_Alt_Displays;
159 uint16_t PostCal_Data_Rate;
160 uint16_t Bitmap_Width;
161 uint16_t Bitmap_Height;
162 uint16_t Display_Window_Width;
163 uint16_t Display_Window_Height;
164 uint32_t Color_Map_Size;
165 uint16_t Color_Map_RGB_Width;
166 uint16_t RGB_Capability;
167 uint8_t Monochrome_Capability;
168 uint8_t Reserved_1;
169 uint16_t Y_Cb_Cr_Capability;
170 uint16_t Bayer_Capability;
171 uint16_t Alpha_Cursor_Image_Planes;
172 uint32_t Client_Feature_Capability_Indicators;
173 uint8_t Maximum_Video_Frame_Rate_Capability;
174 uint8_t Minimum_Video_Frame_Rate_Capability;
175 uint16_t Minimum_Sub_frame_Rate;
176 uint16_t Audio_Buffer_Depth;
177 uint16_t Audio_Channel_Capability;
178 uint16_t Audio_Sample_Rate_Capability;
179 uint8_t Audio_Sample_Resolution;
180 uint8_t Mic_Audio_Sample_Resolution;
181 uint16_t Mic_Sample_Rate_Capability;
182 uint8_t Keyboard_Data_Format;
183 uint8_t pointing_device_data_format;
184 uint16_t content_protection_type;
185 uint16_t Mfr_Name;
186 uint16_t Product_Code;
187 uint16_t Reserved_3;
188 uint32_t Serial_Number;
189 uint8_t Week_of_Manufacture;
190 uint8_t Year_of_Manufacture;
191
192 uint16_t crc16;
193} mddi_client_capability_type;
194
195
196struct __attribute__((packed)) mddi_video_stream {
197 uint16_t length;
198 uint16_t type; /* 16 */
199 uint16_t client_id; /* 0 */
200
201 uint16_t video_data_format_descriptor;
202/* format of each pixel in the Pixel Data in the present stream in the
203 * present packet.
204 * If bits [15:13] = 000 monochrome
205 * If bits [15:13] = 001 color pixels (palette).
206 * If bits [15:13] = 010 color pixels in raw RGB
207 * If bits [15:13] = 011 data in 4:2:2 Y Cb Cr format
208 * If bits [15:13] = 100 Bayer pixels
209 */
210
211 uint16_t pixel_data_attributes;
212/* interpreted as follows:
213 * Bits [1:0] = 11 pixel data is displayed to both eyes
214 * Bits [1:0] = 10 pixel data is routed to the left eye only.
215 * Bits [1:0] = 01 pixel data is routed to the right eye only.
216 * Bits [1:0] = 00 pixel data is routed to the alternate display.
217 * Bit 2 is 0 Pixel Data is in the standard progressive format.
218 * Bit 2 is 1 Pixel Data is in interlace format.
219 * Bit 3 is 0 Pixel Data is in the standard progressive format.
220 * Bit 3 is 1 Pixel Data is in alternate pixel format.
221 * Bit 4 is 0 Pixel Data is to or from the display frame buffer.
222 * Bit 4 is 1 Pixel Data is to or from the camera.
223 * Bit 5 is 0 pixel data contains the next consecutive row of pixels.
224 * Bit 5 is 1 X Left Edge, Y Top Edge, X Right Edge, Y Bottom Edge,
225 * X Start, and Y Start parameters are not defined and
226 * shall be ignored by the client.
227 * Bits [7:6] = 01 Pixel data is written to the offline image buffer.
228 * Bits [7:6] = 00 Pixel data is written to the buffer to refresh display.
229 * Bits [7:6] = 11 Pixel data is written to all image buffers.
230 * Bits [7:6] = 10 Invalid. Reserved for future use.
231 * Bits 8 through 11 alternate display number.
232 * Bits 12 through 14 are reserved for future use and shall be set to zero.
233 * Bit 15 is 1 the row of pixels is the last row of pixels in a frame.
234 */
235
236 uint16_t x_left_edge;
237 uint16_t y_top_edge;
238 /* X,Y coordinate of the top left edge of the screen window */
239
240 uint16_t x_right_edge;
241 uint16_t y_bottom_edge;
242 /* X,Y coordinate of the bottom right edge of the window being
243 * updated. */
244
245 uint16_t x_start;
246 uint16_t y_start;
247 /* (X Start, Y Start) is the first pixel in the Pixel Data field
248 * below. */
249
250 uint16_t pixel_count;
251 /* number of pixels in the Pixel Data field below. */
252
253 uint16_t parameter_CRC;
254 /* 16-bit CRC of all bytes from the Packet Length to the Pixel Count. */
255
256 uint16_t reserved;
257 /* 16-bit variable to make structure align on 4 byte boundary */
258};
259
260#define TYPE_VIDEO_STREAM 16
261#define TYPE_CLIENT_CAPS 66
262#define TYPE_REGISTER_ACCESS 146
263#define TYPE_CLIENT_STATUS 70
264
265struct __attribute__((packed)) mddi_register_access {
266 uint16_t length;
267 uint16_t type; /* 146 */
268 uint16_t client_id;
269
270 uint16_t read_write_info;
271 /* Bits 13:0 a 14-bit unsigned integer that specifies the number of
272 * 32-bit Register Data List items to be transferred in the
273 * Register Data List field.
274 * Bits[15:14] = 00 Write to register(s);
275 * Bits[15:14] = 10 Read from register(s);
276 * Bits[15:14] = 11 Response to a Read.
277 * Bits[15:14] = 01 this value is reserved for future use. */
278#define MDDI_WRITE (0 << 14)
279#define MDDI_READ (2 << 14)
280#define MDDI_READ_RESP (3 << 14)
281
282 uint32_t register_address;
283 /* the register address that is to be written to or read from. */
284
285 uint16_t crc16;
286
287 uint32_t register_data_list;
288 /* list of 4-byte register data values for/from client registers */
289};
290
291struct __attribute__((packed)) mddi_llentry {
292 uint16_t flags;
293 uint16_t header_count;
294 uint16_t data_count;
295 dma_addr_t data; /* 32 bit */
296 struct mddi_llentry *next;
297 uint16_t reserved;
298 union {
299 struct mddi_video_stream v;
300 struct mddi_register_access r;
301 uint32_t _[12];
302 } u;
303};
304
305#endif
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
new file mode 100644
index 000000000000..99636a2b20f2
--- /dev/null
+++ b/drivers/video/msm/mdp.c
@@ -0,0 +1,538 @@
1/* drivers/video/msm_fb/mdp.c
2 *
3 * MSM MDP Interface (used by framebuffer core)
4 *
5 * Copyright (C) 2007 QUALCOMM Incorporated
6 * Copyright (C) 2007 Google Incorporated
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/kernel.h>
19#include <linux/fb.h>
20#include <linux/msm_mdp.h>
21#include <linux/interrupt.h>
22#include <linux/wait.h>
23#include <linux/clk.h>
24#include <linux/file.h>
25#ifdef CONFIG_ANDROID_PMEM
26#include <linux/android_pmem.h>
27#endif
28#include <linux/major.h>
29
30#include <mach/msm_iomap.h>
31#include <mach/msm_fb.h>
32#include <linux/platform_device.h>
33
34#include "mdp_hw.h"
35
36struct class *mdp_class;
37
38#define MDP_CMD_DEBUG_ACCESS_BASE (0x10000)
39
40static uint16_t mdp_default_ccs[] = {
41 0x254, 0x000, 0x331, 0x254, 0xF38, 0xE61, 0x254, 0x409, 0x000,
42 0x010, 0x080, 0x080
43};
44
45static DECLARE_WAIT_QUEUE_HEAD(mdp_dma2_waitqueue);
46static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue);
47static struct msmfb_callback *dma_callback;
48static struct clk *clk;
49static unsigned int mdp_irq_mask;
50static DEFINE_SPINLOCK(mdp_lock);
51DEFINE_MUTEX(mdp_mutex);
52
53static int enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
54{
55 unsigned long irq_flags;
56 int ret = 0;
57
58 BUG_ON(!mask);
59
60 spin_lock_irqsave(&mdp_lock, irq_flags);
61 /* if the mask bits are already set return an error, this interrupt
62 * is already enabled */
63 if (mdp_irq_mask & mask) {
64 printk(KERN_ERR "mdp irq already on already on %x %x\n",
65 mdp_irq_mask, mask);
66 ret = -1;
67 }
68 /* if the mdp irq is not already enabled enable it */
69 if (!mdp_irq_mask) {
70 if (clk)
71 clk_enable(clk);
72 enable_irq(mdp->irq);
73 }
74
75 /* update the irq mask to reflect the fact that the interrupt is
76 * enabled */
77 mdp_irq_mask |= mask;
78 spin_unlock_irqrestore(&mdp_lock, irq_flags);
79 return ret;
80}
81
82static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
83{
84 /* this interrupt is already disabled! */
85 if (!(mdp_irq_mask & mask)) {
86 printk(KERN_ERR "mdp irq already off %x %x\n",
87 mdp_irq_mask, mask);
88 return -1;
89 }
90 /* update the irq mask to reflect the fact that the interrupt is
91 * disabled */
92 mdp_irq_mask &= ~(mask);
93 /* if no one is waiting on the interrupt, disable it */
94 if (!mdp_irq_mask) {
95 disable_irq(mdp->irq);
96 if (clk)
97 clk_disable(clk);
98 }
99 return 0;
100}
101
102static int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
103{
104 unsigned long irq_flags;
105 int ret;
106
107 spin_lock_irqsave(&mdp_lock, irq_flags);
108 ret = locked_disable_mdp_irq(mdp, mask);
109 spin_unlock_irqrestore(&mdp_lock, irq_flags);
110 return ret;
111}
112
113static irqreturn_t mdp_isr(int irq, void *data)
114{
115 uint32_t status;
116 unsigned long irq_flags;
117 struct mdp_info *mdp = data;
118
119 spin_lock_irqsave(&mdp_lock, irq_flags);
120
121 status = mdp_readl(mdp, MDP_INTR_STATUS);
122 mdp_writel(mdp, status, MDP_INTR_CLEAR);
123
124 status &= mdp_irq_mask;
125 if (status & DL0_DMA2_TERM_DONE) {
126 if (dma_callback) {
127 dma_callback->func(dma_callback);
128 dma_callback = NULL;
129 }
130 wake_up(&mdp_dma2_waitqueue);
131 }
132
133 if (status & DL0_ROI_DONE)
134 wake_up(&mdp_ppp_waitqueue);
135
136 if (status)
137 locked_disable_mdp_irq(mdp, status);
138
139 spin_unlock_irqrestore(&mdp_lock, irq_flags);
140 return IRQ_HANDLED;
141}
142
143static uint32_t mdp_check_mask(uint32_t mask)
144{
145 uint32_t ret;
146 unsigned long irq_flags;
147
148 spin_lock_irqsave(&mdp_lock, irq_flags);
149 ret = mdp_irq_mask & mask;
150 spin_unlock_irqrestore(&mdp_lock, irq_flags);
151 return ret;
152}
153
154static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq)
155{
156 int ret = 0;
157 unsigned long irq_flags;
158
159 wait_event_timeout(*wq, !mdp_check_mask(mask), HZ);
160
161 spin_lock_irqsave(&mdp_lock, irq_flags);
162 if (mdp_irq_mask & mask) {
163 locked_disable_mdp_irq(mdp, mask);
164 printk(KERN_WARNING "timeout waiting for mdp to complete %x\n",
165 mask);
166 ret = -ETIMEDOUT;
167 }
168 spin_unlock_irqrestore(&mdp_lock, irq_flags);
169
170 return ret;
171}
172
173void mdp_dma_wait(struct mdp_device *mdp_dev)
174{
175#define MDP_MAX_TIMEOUTS 20
176 static int timeout_count;
177 struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
178
179 if (mdp_wait(mdp, DL0_DMA2_TERM_DONE, &mdp_dma2_waitqueue) == -ETIMEDOUT)
180 timeout_count++;
181 else
182 timeout_count = 0;
183
184 if (timeout_count > MDP_MAX_TIMEOUTS) {
185 printk(KERN_ERR "mdp: dma failed %d times, somethings wrong!\n",
186 MDP_MAX_TIMEOUTS);
187 BUG();
188 }
189}
190
191static int mdp_ppp_wait(struct mdp_info *mdp)
192{
193 return mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue);
194}
195
196void mdp_dma_to_mddi(struct mdp_info *mdp, uint32_t addr, uint32_t stride,
197 uint32_t width, uint32_t height, uint32_t x, uint32_t y,
198 struct msmfb_callback *callback)
199{
200 uint32_t dma2_cfg;
201 uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */
202
203 if (enable_mdp_irq(mdp, DL0_DMA2_TERM_DONE)) {
204 printk(KERN_ERR "mdp_dma_to_mddi: busy\n");
205 return;
206 }
207
208 dma_callback = callback;
209
210 dma2_cfg = DMA_PACK_TIGHT |
211 DMA_PACK_ALIGN_LSB |
212 DMA_PACK_PATTERN_RGB |
213 DMA_OUT_SEL_AHB |
214 DMA_IBUF_NONCONTIGUOUS;
215
216 dma2_cfg |= DMA_IBUF_FORMAT_RGB565;
217
218 dma2_cfg |= DMA_OUT_SEL_MDDI;
219
220 dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
221
222 dma2_cfg |= DMA_DITHER_EN;
223
224 /* setup size, address, and stride */
225 mdp_writel(mdp, (height << 16) | (width),
226 MDP_CMD_DEBUG_ACCESS_BASE + 0x0184);
227 mdp_writel(mdp, addr, MDP_CMD_DEBUG_ACCESS_BASE + 0x0188);
228 mdp_writel(mdp, stride, MDP_CMD_DEBUG_ACCESS_BASE + 0x018C);
229
230 /* 666 18BPP */
231 dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
232
233 /* set y & x offset and MDDI transaction parameters */
234 mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194);
235 mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0);
236 mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM,
237 MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4);
238
239 mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180);
240
241 /* start DMA2 */
242 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044);
243}
244
245void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride,
246 uint32_t width, uint32_t height, uint32_t x, uint32_t y,
247 struct msmfb_callback *callback, int interface)
248{
249 struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
250
251 if (interface == MSM_MDDI_PMDH_INTERFACE) {
252 mdp_dma_to_mddi(mdp, addr, stride, width, height, x, y,
253 callback);
254 }
255}
256
257int get_img(struct mdp_img *img, struct fb_info *info,
258 unsigned long *start, unsigned long *len,
259 struct file **filep)
260{
261 int put_needed, ret = 0;
262 struct file *file;
263 unsigned long vstart;
264
265#ifdef CONFIG_ANDROID_PMEM
266 if (!get_pmem_file(img->memory_id, start, &vstart, len, filep))
267 return 0;
268#endif
269
270 file = fget_light(img->memory_id, &put_needed);
271 if (file == NULL)
272 return -1;
273
274 if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
275 *start = info->fix.smem_start;
276 *len = info->fix.smem_len;
277 } else
278 ret = -1;
279 fput_light(file, put_needed);
280
281 return ret;
282}
283
284void put_img(struct file *src_file, struct file *dst_file)
285{
286#ifdef CONFIG_ANDROID_PMEM
287 if (src_file)
288 put_pmem_file(src_file);
289 if (dst_file)
290 put_pmem_file(dst_file);
291#endif
292}
293
294int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
295 struct mdp_blit_req *req)
296{
297 int ret;
298 unsigned long src_start = 0, src_len = 0, dst_start = 0, dst_len = 0;
299 struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
300 struct file *src_file = 0, *dst_file = 0;
301
302 /* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */
303 if (unlikely(req->src_rect.h == 0 ||
304 req->src_rect.w == 0)) {
305 printk(KERN_ERR "mpd_ppp: src img of zero size!\n");
306 return -EINVAL;
307 }
308 if (unlikely(req->dst_rect.h == 0 ||
309 req->dst_rect.w == 0))
310 return -EINVAL;
311
312 /* do this first so that if this fails, the caller can always
313 * safely call put_img */
314 if (unlikely(get_img(&req->src, fb, &src_start, &src_len, &src_file))) {
315 printk(KERN_ERR "mpd_ppp: could not retrieve src image from "
316 "memory\n");
317 return -EINVAL;
318 }
319
320 if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) {
321 printk(KERN_ERR "mpd_ppp: could not retrieve dst image from "
322 "memory\n");
323#ifdef CONFIG_ANDROID_PMEM
324 put_pmem_file(src_file);
325#endif
326 return -EINVAL;
327 }
328 mutex_lock(&mdp_mutex);
329
330 /* transp_masking unimplemented */
331 req->transp_mask = MDP_TRANSP_NOP;
332 if (unlikely((req->transp_mask != MDP_TRANSP_NOP ||
333 req->alpha != MDP_ALPHA_NOP ||
334 HAS_ALPHA(req->src.format)) &&
335 (req->flags & MDP_ROT_90 &&
336 req->dst_rect.w <= 16 && req->dst_rect.h >= 16))) {
337 int i;
338 unsigned int tiles = req->dst_rect.h / 16;
339 unsigned int remainder = req->dst_rect.h % 16;
340 req->src_rect.w = 16*req->src_rect.w / req->dst_rect.h;
341 req->dst_rect.h = 16;
342 for (i = 0; i < tiles; i++) {
343 enable_mdp_irq(mdp, DL0_ROI_DONE);
344 ret = mdp_ppp_blit(mdp, req, src_file, src_start,
345 src_len, dst_file, dst_start,
346 dst_len);
347 if (ret)
348 goto err_bad_blit;
349 ret = mdp_ppp_wait(mdp);
350 if (ret)
351 goto err_wait_failed;
352 req->dst_rect.y += 16;
353 req->src_rect.x += req->src_rect.w;
354 }
355 if (!remainder)
356 goto end;
357 req->src_rect.w = remainder*req->src_rect.w / req->dst_rect.h;
358 req->dst_rect.h = remainder;
359 }
360 enable_mdp_irq(mdp, DL0_ROI_DONE);
361 ret = mdp_ppp_blit(mdp, req, src_file, src_start, src_len, dst_file,
362 dst_start,
363 dst_len);
364 if (ret)
365 goto err_bad_blit;
366 ret = mdp_ppp_wait(mdp);
367 if (ret)
368 goto err_wait_failed;
369end:
370 put_img(src_file, dst_file);
371 mutex_unlock(&mdp_mutex);
372 return 0;
373err_bad_blit:
374 disable_mdp_irq(mdp, DL0_ROI_DONE);
375err_wait_failed:
376 put_img(src_file, dst_file);
377 mutex_unlock(&mdp_mutex);
378 return ret;
379}
380
381void mdp_set_grp_disp(struct mdp_device *mdp_dev, unsigned disp_id)
382{
383 struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
384
385 disp_id &= 0xf;
386 mdp_writel(mdp, disp_id, MDP_FULL_BYPASS_WORD43);
387}
388
389int register_mdp_client(struct class_interface *cint)
390{
391 if (!mdp_class) {
392 pr_err("mdp: no mdp_class when registering mdp client\n");
393 return -ENODEV;
394 }
395 cint->class = mdp_class;
396 return class_interface_register(cint);
397}
398
399#include "mdp_csc_table.h"
400#include "mdp_scale_tables.h"
401
402int mdp_probe(struct platform_device *pdev)
403{
404 struct resource *resource;
405 int ret;
406 int n;
407 struct mdp_info *mdp;
408
409 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
410 if (!resource) {
411 pr_err("mdp: can not get mdp mem resource!\n");
412 return -ENOMEM;
413 }
414
415 mdp = kzalloc(sizeof(struct mdp_info), GFP_KERNEL);
416 if (!mdp)
417 return -ENOMEM;
418
419 mdp->irq = platform_get_irq(pdev, 0);
420 if (mdp->irq < 0) {
421 pr_err("mdp: can not get mdp irq\n");
422 ret = mdp->irq;
423 goto error_get_irq;
424 }
425
426 mdp->base = ioremap(resource->start,
427 resource->end - resource->start);
428 if (mdp->base == 0) {
429 printk(KERN_ERR "msmfb: cannot allocate mdp regs!\n");
430 ret = -ENOMEM;
431 goto error_ioremap;
432 }
433
434 mdp->mdp_dev.dma = mdp_dma;
435 mdp->mdp_dev.dma_wait = mdp_dma_wait;
436 mdp->mdp_dev.blit = mdp_blit;
437 mdp->mdp_dev.set_grp_disp = mdp_set_grp_disp;
438
439 clk = clk_get(&pdev->dev, "mdp_clk");
440 if (IS_ERR(clk)) {
441 printk(KERN_INFO "mdp: failed to get mdp clk");
442 return PTR_ERR(clk);
443 }
444
445 ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
446 if (ret)
447 goto error_request_irq;
448 disable_irq(mdp->irq);
449 mdp_irq_mask = 0;
450
451 /* debug interface write access */
452 mdp_writel(mdp, 1, 0x60);
453
454 mdp_writel(mdp, MDP_ANY_INTR_MASK, MDP_INTR_ENABLE);
455 mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE);
456
457 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8);
458 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc);
459
460 for (n = 0; n < ARRAY_SIZE(csc_table); n++)
461 mdp_writel(mdp, csc_table[n].val, csc_table[n].reg);
462
463 /* clear up unused fg/main registers */
464 /* comp.plane 2&3 ystride */
465 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120);
466
467 /* unpacked pattern */
468 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c);
469 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130);
470 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134);
471 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158);
472 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c);
473 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160);
474 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170);
475 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174);
476 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c);
477
478 /* comp.plane 2 & 3 */
479 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114);
480 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118);
481
482 /* clear unused bg registers */
483 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8);
484 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0);
485 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc);
486 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
487 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);
488
489 for (n = 0; n < ARRAY_SIZE(mdp_upscale_table); n++)
490 mdp_writel(mdp, mdp_upscale_table[n].val,
491 mdp_upscale_table[n].reg);
492
493 for (n = 0; n < 9; n++)
494 mdp_writel(mdp, mdp_default_ccs[n], 0x40440 + 4 * n);
495 mdp_writel(mdp, mdp_default_ccs[9], 0x40500 + 4 * 0);
496 mdp_writel(mdp, mdp_default_ccs[10], 0x40500 + 4 * 0);
497 mdp_writel(mdp, mdp_default_ccs[11], 0x40500 + 4 * 0);
498
499 /* register mdp device */
500 mdp->mdp_dev.dev.parent = &pdev->dev;
501 mdp->mdp_dev.dev.class = mdp_class;
502 snprintf(mdp->mdp_dev.dev.bus_id, BUS_ID_SIZE, "mdp%d", pdev->id);
503
504 /* if you can remove the platform device you'd have to implement
505 * this:
506 mdp_dev.release = mdp_class; */
507
508 ret = device_register(&mdp->mdp_dev.dev);
509 if (ret)
510 goto error_device_register;
511 return 0;
512
513error_device_register:
514 free_irq(mdp->irq, mdp);
515error_request_irq:
516 iounmap(mdp->base);
517error_get_irq:
518error_ioremap:
519 kfree(mdp);
520 return ret;
521}
522
523static struct platform_driver msm_mdp_driver = {
524 .probe = mdp_probe,
525 .driver = {.name = "msm_mdp"},
526};
527
528static int __init mdp_init(void)
529{
530 mdp_class = class_create(THIS_MODULE, "msm_mdp");
531 if (IS_ERR(mdp_class)) {
532 printk(KERN_ERR "Error creating mdp class\n");
533 return PTR_ERR(mdp_class);
534 }
535 return platform_driver_register(&msm_mdp_driver);
536}
537
538subsys_initcall(mdp_init);
diff --git a/drivers/video/msm/mdp_csc_table.h b/drivers/video/msm/mdp_csc_table.h
new file mode 100644
index 000000000000..d1cde30ead52
--- /dev/null
+++ b/drivers/video/msm/mdp_csc_table.h
@@ -0,0 +1,582 @@
1/* drivers/video/msm_fb/mdp_csc_table.h
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16static struct {
17 uint32_t reg;
18 uint32_t val;
19} csc_table[] = {
20 { 0x40400, 0x83 },
21 { 0x40404, 0x102 },
22 { 0x40408, 0x32 },
23 { 0x4040c, 0xffffffb5 },
24 { 0x40410, 0xffffff6c },
25 { 0x40414, 0xe1 },
26 { 0x40418, 0xe1 },
27 { 0x4041c, 0xffffff45 },
28 { 0x40420, 0xffffffdc },
29 { 0x40440, 0x254 },
30 { 0x40444, 0x0 },
31 { 0x40448, 0x331 },
32 { 0x4044c, 0x254 },
33 { 0x40450, 0xffffff38 },
34 { 0x40454, 0xfffffe61 },
35 { 0x40458, 0x254 },
36 { 0x4045c, 0x409 },
37 { 0x40460, 0x0 },
38 { 0x40480, 0x5d },
39 { 0x40484, 0x13a },
40 { 0x40488, 0x20 },
41 { 0x4048c, 0xffffffcd },
42 { 0x40490, 0xffffff54 },
43 { 0x40494, 0xe1 },
44 { 0x40498, 0xe1 },
45 { 0x4049c, 0xffffff35 },
46 { 0x404a0, 0xffffffec },
47 { 0x404c0, 0x254 },
48 { 0x404c4, 0x0 },
49 { 0x404c8, 0x396 },
50 { 0x404cc, 0x254 },
51 { 0x404d0, 0xffffff94 },
52 { 0x404d4, 0xfffffef0 },
53 { 0x404d8, 0x254 },
54 { 0x404dc, 0x43a },
55 { 0x404e0, 0x0 },
56 { 0x40500, 0x10 },
57 { 0x40504, 0x80 },
58 { 0x40508, 0x80 },
59 { 0x40540, 0x10 },
60 { 0x40544, 0x80 },
61 { 0x40548, 0x80 },
62 { 0x40580, 0x10 },
63 { 0x40584, 0xeb },
64 { 0x40588, 0x10 },
65 { 0x4058c, 0xf0 },
66 { 0x405c0, 0x10 },
67 { 0x405c4, 0xeb },
68 { 0x405c8, 0x10 },
69 { 0x405cc, 0xf0 },
70 { 0x40800, 0x0 },
71 { 0x40804, 0x151515 },
72 { 0x40808, 0x1d1d1d },
73 { 0x4080c, 0x232323 },
74 { 0x40810, 0x272727 },
75 { 0x40814, 0x2b2b2b },
76 { 0x40818, 0x2f2f2f },
77 { 0x4081c, 0x333333 },
78 { 0x40820, 0x363636 },
79 { 0x40824, 0x393939 },
80 { 0x40828, 0x3b3b3b },
81 { 0x4082c, 0x3e3e3e },
82 { 0x40830, 0x404040 },
83 { 0x40834, 0x434343 },
84 { 0x40838, 0x454545 },
85 { 0x4083c, 0x474747 },
86 { 0x40840, 0x494949 },
87 { 0x40844, 0x4b4b4b },
88 { 0x40848, 0x4d4d4d },
89 { 0x4084c, 0x4f4f4f },
90 { 0x40850, 0x515151 },
91 { 0x40854, 0x535353 },
92 { 0x40858, 0x555555 },
93 { 0x4085c, 0x565656 },
94 { 0x40860, 0x585858 },
95 { 0x40864, 0x5a5a5a },
96 { 0x40868, 0x5b5b5b },
97 { 0x4086c, 0x5d5d5d },
98 { 0x40870, 0x5e5e5e },
99 { 0x40874, 0x606060 },
100 { 0x40878, 0x616161 },
101 { 0x4087c, 0x636363 },
102 { 0x40880, 0x646464 },
103 { 0x40884, 0x666666 },
104 { 0x40888, 0x676767 },
105 { 0x4088c, 0x686868 },
106 { 0x40890, 0x6a6a6a },
107 { 0x40894, 0x6b6b6b },
108 { 0x40898, 0x6c6c6c },
109 { 0x4089c, 0x6e6e6e },
110 { 0x408a0, 0x6f6f6f },
111 { 0x408a4, 0x707070 },
112 { 0x408a8, 0x717171 },
113 { 0x408ac, 0x727272 },
114 { 0x408b0, 0x747474 },
115 { 0x408b4, 0x757575 },
116 { 0x408b8, 0x767676 },
117 { 0x408bc, 0x777777 },
118 { 0x408c0, 0x787878 },
119 { 0x408c4, 0x797979 },
120 { 0x408c8, 0x7a7a7a },
121 { 0x408cc, 0x7c7c7c },
122 { 0x408d0, 0x7d7d7d },
123 { 0x408d4, 0x7e7e7e },
124 { 0x408d8, 0x7f7f7f },
125 { 0x408dc, 0x808080 },
126 { 0x408e0, 0x818181 },
127 { 0x408e4, 0x828282 },
128 { 0x408e8, 0x838383 },
129 { 0x408ec, 0x848484 },
130 { 0x408f0, 0x858585 },
131 { 0x408f4, 0x868686 },
132 { 0x408f8, 0x878787 },
133 { 0x408fc, 0x888888 },
134 { 0x40900, 0x898989 },
135 { 0x40904, 0x8a8a8a },
136 { 0x40908, 0x8b8b8b },
137 { 0x4090c, 0x8c8c8c },
138 { 0x40910, 0x8d8d8d },
139 { 0x40914, 0x8e8e8e },
140 { 0x40918, 0x8f8f8f },
141 { 0x4091c, 0x8f8f8f },
142 { 0x40920, 0x909090 },
143 { 0x40924, 0x919191 },
144 { 0x40928, 0x929292 },
145 { 0x4092c, 0x939393 },
146 { 0x40930, 0x949494 },
147 { 0x40934, 0x959595 },
148 { 0x40938, 0x969696 },
149 { 0x4093c, 0x969696 },
150 { 0x40940, 0x979797 },
151 { 0x40944, 0x989898 },
152 { 0x40948, 0x999999 },
153 { 0x4094c, 0x9a9a9a },
154 { 0x40950, 0x9b9b9b },
155 { 0x40954, 0x9c9c9c },
156 { 0x40958, 0x9c9c9c },
157 { 0x4095c, 0x9d9d9d },
158 { 0x40960, 0x9e9e9e },
159 { 0x40964, 0x9f9f9f },
160 { 0x40968, 0xa0a0a0 },
161 { 0x4096c, 0xa0a0a0 },
162 { 0x40970, 0xa1a1a1 },
163 { 0x40974, 0xa2a2a2 },
164 { 0x40978, 0xa3a3a3 },
165 { 0x4097c, 0xa4a4a4 },
166 { 0x40980, 0xa4a4a4 },
167 { 0x40984, 0xa5a5a5 },
168 { 0x40988, 0xa6a6a6 },
169 { 0x4098c, 0xa7a7a7 },
170 { 0x40990, 0xa7a7a7 },
171 { 0x40994, 0xa8a8a8 },
172 { 0x40998, 0xa9a9a9 },
173 { 0x4099c, 0xaaaaaa },
174 { 0x409a0, 0xaaaaaa },
175 { 0x409a4, 0xababab },
176 { 0x409a8, 0xacacac },
177 { 0x409ac, 0xadadad },
178 { 0x409b0, 0xadadad },
179 { 0x409b4, 0xaeaeae },
180 { 0x409b8, 0xafafaf },
181 { 0x409bc, 0xafafaf },
182 { 0x409c0, 0xb0b0b0 },
183 { 0x409c4, 0xb1b1b1 },
184 { 0x409c8, 0xb2b2b2 },
185 { 0x409cc, 0xb2b2b2 },
186 { 0x409d0, 0xb3b3b3 },
187 { 0x409d4, 0xb4b4b4 },
188 { 0x409d8, 0xb4b4b4 },
189 { 0x409dc, 0xb5b5b5 },
190 { 0x409e0, 0xb6b6b6 },
191 { 0x409e4, 0xb6b6b6 },
192 { 0x409e8, 0xb7b7b7 },
193 { 0x409ec, 0xb8b8b8 },
194 { 0x409f0, 0xb8b8b8 },
195 { 0x409f4, 0xb9b9b9 },
196 { 0x409f8, 0xbababa },
197 { 0x409fc, 0xbababa },
198 { 0x40a00, 0xbbbbbb },
199 { 0x40a04, 0xbcbcbc },
200 { 0x40a08, 0xbcbcbc },
201 { 0x40a0c, 0xbdbdbd },
202 { 0x40a10, 0xbebebe },
203 { 0x40a14, 0xbebebe },
204 { 0x40a18, 0xbfbfbf },
205 { 0x40a1c, 0xc0c0c0 },
206 { 0x40a20, 0xc0c0c0 },
207 { 0x40a24, 0xc1c1c1 },
208 { 0x40a28, 0xc1c1c1 },
209 { 0x40a2c, 0xc2c2c2 },
210 { 0x40a30, 0xc3c3c3 },
211 { 0x40a34, 0xc3c3c3 },
212 { 0x40a38, 0xc4c4c4 },
213 { 0x40a3c, 0xc5c5c5 },
214 { 0x40a40, 0xc5c5c5 },
215 { 0x40a44, 0xc6c6c6 },
216 { 0x40a48, 0xc6c6c6 },
217 { 0x40a4c, 0xc7c7c7 },
218 { 0x40a50, 0xc8c8c8 },
219 { 0x40a54, 0xc8c8c8 },
220 { 0x40a58, 0xc9c9c9 },
221 { 0x40a5c, 0xc9c9c9 },
222 { 0x40a60, 0xcacaca },
223 { 0x40a64, 0xcbcbcb },
224 { 0x40a68, 0xcbcbcb },
225 { 0x40a6c, 0xcccccc },
226 { 0x40a70, 0xcccccc },
227 { 0x40a74, 0xcdcdcd },
228 { 0x40a78, 0xcecece },
229 { 0x40a7c, 0xcecece },
230 { 0x40a80, 0xcfcfcf },
231 { 0x40a84, 0xcfcfcf },
232 { 0x40a88, 0xd0d0d0 },
233 { 0x40a8c, 0xd0d0d0 },
234 { 0x40a90, 0xd1d1d1 },
235 { 0x40a94, 0xd2d2d2 },
236 { 0x40a98, 0xd2d2d2 },
237 { 0x40a9c, 0xd3d3d3 },
238 { 0x40aa0, 0xd3d3d3 },
239 { 0x40aa4, 0xd4d4d4 },
240 { 0x40aa8, 0xd4d4d4 },
241 { 0x40aac, 0xd5d5d5 },
242 { 0x40ab0, 0xd6d6d6 },
243 { 0x40ab4, 0xd6d6d6 },
244 { 0x40ab8, 0xd7d7d7 },
245 { 0x40abc, 0xd7d7d7 },
246 { 0x40ac0, 0xd8d8d8 },
247 { 0x40ac4, 0xd8d8d8 },
248 { 0x40ac8, 0xd9d9d9 },
249 { 0x40acc, 0xd9d9d9 },
250 { 0x40ad0, 0xdadada },
251 { 0x40ad4, 0xdbdbdb },
252 { 0x40ad8, 0xdbdbdb },
253 { 0x40adc, 0xdcdcdc },
254 { 0x40ae0, 0xdcdcdc },
255 { 0x40ae4, 0xdddddd },
256 { 0x40ae8, 0xdddddd },
257 { 0x40aec, 0xdedede },
258 { 0x40af0, 0xdedede },
259 { 0x40af4, 0xdfdfdf },
260 { 0x40af8, 0xdfdfdf },
261 { 0x40afc, 0xe0e0e0 },
262 { 0x40b00, 0xe0e0e0 },
263 { 0x40b04, 0xe1e1e1 },
264 { 0x40b08, 0xe1e1e1 },
265 { 0x40b0c, 0xe2e2e2 },
266 { 0x40b10, 0xe3e3e3 },
267 { 0x40b14, 0xe3e3e3 },
268 { 0x40b18, 0xe4e4e4 },
269 { 0x40b1c, 0xe4e4e4 },
270 { 0x40b20, 0xe5e5e5 },
271 { 0x40b24, 0xe5e5e5 },
272 { 0x40b28, 0xe6e6e6 },
273 { 0x40b2c, 0xe6e6e6 },
274 { 0x40b30, 0xe7e7e7 },
275 { 0x40b34, 0xe7e7e7 },
276 { 0x40b38, 0xe8e8e8 },
277 { 0x40b3c, 0xe8e8e8 },
278 { 0x40b40, 0xe9e9e9 },
279 { 0x40b44, 0xe9e9e9 },
280 { 0x40b48, 0xeaeaea },
281 { 0x40b4c, 0xeaeaea },
282 { 0x40b50, 0xebebeb },
283 { 0x40b54, 0xebebeb },
284 { 0x40b58, 0xececec },
285 { 0x40b5c, 0xececec },
286 { 0x40b60, 0xededed },
287 { 0x40b64, 0xededed },
288 { 0x40b68, 0xeeeeee },
289 { 0x40b6c, 0xeeeeee },
290 { 0x40b70, 0xefefef },
291 { 0x40b74, 0xefefef },
292 { 0x40b78, 0xf0f0f0 },
293 { 0x40b7c, 0xf0f0f0 },
294 { 0x40b80, 0xf1f1f1 },
295 { 0x40b84, 0xf1f1f1 },
296 { 0x40b88, 0xf2f2f2 },
297 { 0x40b8c, 0xf2f2f2 },
298 { 0x40b90, 0xf2f2f2 },
299 { 0x40b94, 0xf3f3f3 },
300 { 0x40b98, 0xf3f3f3 },
301 { 0x40b9c, 0xf4f4f4 },
302 { 0x40ba0, 0xf4f4f4 },
303 { 0x40ba4, 0xf5f5f5 },
304 { 0x40ba8, 0xf5f5f5 },
305 { 0x40bac, 0xf6f6f6 },
306 { 0x40bb0, 0xf6f6f6 },
307 { 0x40bb4, 0xf7f7f7 },
308 { 0x40bb8, 0xf7f7f7 },
309 { 0x40bbc, 0xf8f8f8 },
310 { 0x40bc0, 0xf8f8f8 },
311 { 0x40bc4, 0xf9f9f9 },
312 { 0x40bc8, 0xf9f9f9 },
313 { 0x40bcc, 0xfafafa },
314 { 0x40bd0, 0xfafafa },
315 { 0x40bd4, 0xfafafa },
316 { 0x40bd8, 0xfbfbfb },
317 { 0x40bdc, 0xfbfbfb },
318 { 0x40be0, 0xfcfcfc },
319 { 0x40be4, 0xfcfcfc },
320 { 0x40be8, 0xfdfdfd },
321 { 0x40bec, 0xfdfdfd },
322 { 0x40bf0, 0xfefefe },
323 { 0x40bf4, 0xfefefe },
324 { 0x40bf8, 0xffffff },
325 { 0x40bfc, 0xffffff },
326 { 0x40c00, 0x0 },
327 { 0x40c04, 0x0 },
328 { 0x40c08, 0x0 },
329 { 0x40c0c, 0x0 },
330 { 0x40c10, 0x0 },
331 { 0x40c14, 0x0 },
332 { 0x40c18, 0x0 },
333 { 0x40c1c, 0x0 },
334 { 0x40c20, 0x0 },
335 { 0x40c24, 0x0 },
336 { 0x40c28, 0x0 },
337 { 0x40c2c, 0x0 },
338 { 0x40c30, 0x0 },
339 { 0x40c34, 0x0 },
340 { 0x40c38, 0x0 },
341 { 0x40c3c, 0x0 },
342 { 0x40c40, 0x10101 },
343 { 0x40c44, 0x10101 },
344 { 0x40c48, 0x10101 },
345 { 0x40c4c, 0x10101 },
346 { 0x40c50, 0x10101 },
347 { 0x40c54, 0x10101 },
348 { 0x40c58, 0x10101 },
349 { 0x40c5c, 0x10101 },
350 { 0x40c60, 0x10101 },
351 { 0x40c64, 0x10101 },
352 { 0x40c68, 0x20202 },
353 { 0x40c6c, 0x20202 },
354 { 0x40c70, 0x20202 },
355 { 0x40c74, 0x20202 },
356 { 0x40c78, 0x20202 },
357 { 0x40c7c, 0x20202 },
358 { 0x40c80, 0x30303 },
359 { 0x40c84, 0x30303 },
360 { 0x40c88, 0x30303 },
361 { 0x40c8c, 0x30303 },
362 { 0x40c90, 0x30303 },
363 { 0x40c94, 0x40404 },
364 { 0x40c98, 0x40404 },
365 { 0x40c9c, 0x40404 },
366 { 0x40ca0, 0x40404 },
367 { 0x40ca4, 0x40404 },
368 { 0x40ca8, 0x50505 },
369 { 0x40cac, 0x50505 },
370 { 0x40cb0, 0x50505 },
371 { 0x40cb4, 0x50505 },
372 { 0x40cb8, 0x60606 },
373 { 0x40cbc, 0x60606 },
374 { 0x40cc0, 0x60606 },
375 { 0x40cc4, 0x70707 },
376 { 0x40cc8, 0x70707 },
377 { 0x40ccc, 0x70707 },
378 { 0x40cd0, 0x70707 },
379 { 0x40cd4, 0x80808 },
380 { 0x40cd8, 0x80808 },
381 { 0x40cdc, 0x80808 },
382 { 0x40ce0, 0x90909 },
383 { 0x40ce4, 0x90909 },
384 { 0x40ce8, 0xa0a0a },
385 { 0x40cec, 0xa0a0a },
386 { 0x40cf0, 0xa0a0a },
387 { 0x40cf4, 0xb0b0b },
388 { 0x40cf8, 0xb0b0b },
389 { 0x40cfc, 0xb0b0b },
390 { 0x40d00, 0xc0c0c },
391 { 0x40d04, 0xc0c0c },
392 { 0x40d08, 0xd0d0d },
393 { 0x40d0c, 0xd0d0d },
394 { 0x40d10, 0xe0e0e },
395 { 0x40d14, 0xe0e0e },
396 { 0x40d18, 0xe0e0e },
397 { 0x40d1c, 0xf0f0f },
398 { 0x40d20, 0xf0f0f },
399 { 0x40d24, 0x101010 },
400 { 0x40d28, 0x101010 },
401 { 0x40d2c, 0x111111 },
402 { 0x40d30, 0x111111 },
403 { 0x40d34, 0x121212 },
404 { 0x40d38, 0x121212 },
405 { 0x40d3c, 0x131313 },
406 { 0x40d40, 0x131313 },
407 { 0x40d44, 0x141414 },
408 { 0x40d48, 0x151515 },
409 { 0x40d4c, 0x151515 },
410 { 0x40d50, 0x161616 },
411 { 0x40d54, 0x161616 },
412 { 0x40d58, 0x171717 },
413 { 0x40d5c, 0x171717 },
414 { 0x40d60, 0x181818 },
415 { 0x40d64, 0x191919 },
416 { 0x40d68, 0x191919 },
417 { 0x40d6c, 0x1a1a1a },
418 { 0x40d70, 0x1b1b1b },
419 { 0x40d74, 0x1b1b1b },
420 { 0x40d78, 0x1c1c1c },
421 { 0x40d7c, 0x1c1c1c },
422 { 0x40d80, 0x1d1d1d },
423 { 0x40d84, 0x1e1e1e },
424 { 0x40d88, 0x1f1f1f },
425 { 0x40d8c, 0x1f1f1f },
426 { 0x40d90, 0x202020 },
427 { 0x40d94, 0x212121 },
428 { 0x40d98, 0x212121 },
429 { 0x40d9c, 0x222222 },
430 { 0x40da0, 0x232323 },
431 { 0x40da4, 0x242424 },
432 { 0x40da8, 0x242424 },
433 { 0x40dac, 0x252525 },
434 { 0x40db0, 0x262626 },
435 { 0x40db4, 0x272727 },
436 { 0x40db8, 0x272727 },
437 { 0x40dbc, 0x282828 },
438 { 0x40dc0, 0x292929 },
439 { 0x40dc4, 0x2a2a2a },
440 { 0x40dc8, 0x2b2b2b },
441 { 0x40dcc, 0x2c2c2c },
442 { 0x40dd0, 0x2c2c2c },
443 { 0x40dd4, 0x2d2d2d },
444 { 0x40dd8, 0x2e2e2e },
445 { 0x40ddc, 0x2f2f2f },
446 { 0x40de0, 0x303030 },
447 { 0x40de4, 0x313131 },
448 { 0x40de8, 0x323232 },
449 { 0x40dec, 0x333333 },
450 { 0x40df0, 0x333333 },
451 { 0x40df4, 0x343434 },
452 { 0x40df8, 0x353535 },
453 { 0x40dfc, 0x363636 },
454 { 0x40e00, 0x373737 },
455 { 0x40e04, 0x383838 },
456 { 0x40e08, 0x393939 },
457 { 0x40e0c, 0x3a3a3a },
458 { 0x40e10, 0x3b3b3b },
459 { 0x40e14, 0x3c3c3c },
460 { 0x40e18, 0x3d3d3d },
461 { 0x40e1c, 0x3e3e3e },
462 { 0x40e20, 0x3f3f3f },
463 { 0x40e24, 0x404040 },
464 { 0x40e28, 0x414141 },
465 { 0x40e2c, 0x424242 },
466 { 0x40e30, 0x434343 },
467 { 0x40e34, 0x444444 },
468 { 0x40e38, 0x464646 },
469 { 0x40e3c, 0x474747 },
470 { 0x40e40, 0x484848 },
471 { 0x40e44, 0x494949 },
472 { 0x40e48, 0x4a4a4a },
473 { 0x40e4c, 0x4b4b4b },
474 { 0x40e50, 0x4c4c4c },
475 { 0x40e54, 0x4d4d4d },
476 { 0x40e58, 0x4f4f4f },
477 { 0x40e5c, 0x505050 },
478 { 0x40e60, 0x515151 },
479 { 0x40e64, 0x525252 },
480 { 0x40e68, 0x535353 },
481 { 0x40e6c, 0x545454 },
482 { 0x40e70, 0x565656 },
483 { 0x40e74, 0x575757 },
484 { 0x40e78, 0x585858 },
485 { 0x40e7c, 0x595959 },
486 { 0x40e80, 0x5b5b5b },
487 { 0x40e84, 0x5c5c5c },
488 { 0x40e88, 0x5d5d5d },
489 { 0x40e8c, 0x5e5e5e },
490 { 0x40e90, 0x606060 },
491 { 0x40e94, 0x616161 },
492 { 0x40e98, 0x626262 },
493 { 0x40e9c, 0x646464 },
494 { 0x40ea0, 0x656565 },
495 { 0x40ea4, 0x666666 },
496 { 0x40ea8, 0x686868 },
497 { 0x40eac, 0x696969 },
498 { 0x40eb0, 0x6a6a6a },
499 { 0x40eb4, 0x6c6c6c },
500 { 0x40eb8, 0x6d6d6d },
501 { 0x40ebc, 0x6f6f6f },
502 { 0x40ec0, 0x707070 },
503 { 0x40ec4, 0x717171 },
504 { 0x40ec8, 0x737373 },
505 { 0x40ecc, 0x747474 },
506 { 0x40ed0, 0x767676 },
507 { 0x40ed4, 0x777777 },
508 { 0x40ed8, 0x797979 },
509 { 0x40edc, 0x7a7a7a },
510 { 0x40ee0, 0x7c7c7c },
511 { 0x40ee4, 0x7d7d7d },
512 { 0x40ee8, 0x7f7f7f },
513 { 0x40eec, 0x808080 },
514 { 0x40ef0, 0x828282 },
515 { 0x40ef4, 0x838383 },
516 { 0x40ef8, 0x858585 },
517 { 0x40efc, 0x868686 },
518 { 0x40f00, 0x888888 },
519 { 0x40f04, 0x898989 },
520 { 0x40f08, 0x8b8b8b },
521 { 0x40f0c, 0x8d8d8d },
522 { 0x40f10, 0x8e8e8e },
523 { 0x40f14, 0x909090 },
524 { 0x40f18, 0x919191 },
525 { 0x40f1c, 0x939393 },
526 { 0x40f20, 0x959595 },
527 { 0x40f24, 0x969696 },
528 { 0x40f28, 0x989898 },
529 { 0x40f2c, 0x9a9a9a },
530 { 0x40f30, 0x9b9b9b },
531 { 0x40f34, 0x9d9d9d },
532 { 0x40f38, 0x9f9f9f },
533 { 0x40f3c, 0xa1a1a1 },
534 { 0x40f40, 0xa2a2a2 },
535 { 0x40f44, 0xa4a4a4 },
536 { 0x40f48, 0xa6a6a6 },
537 { 0x40f4c, 0xa7a7a7 },
538 { 0x40f50, 0xa9a9a9 },
539 { 0x40f54, 0xababab },
540 { 0x40f58, 0xadadad },
541 { 0x40f5c, 0xafafaf },
542 { 0x40f60, 0xb0b0b0 },
543 { 0x40f64, 0xb2b2b2 },
544 { 0x40f68, 0xb4b4b4 },
545 { 0x40f6c, 0xb6b6b6 },
546 { 0x40f70, 0xb8b8b8 },
547 { 0x40f74, 0xbababa },
548 { 0x40f78, 0xbbbbbb },
549 { 0x40f7c, 0xbdbdbd },
550 { 0x40f80, 0xbfbfbf },
551 { 0x40f84, 0xc1c1c1 },
552 { 0x40f88, 0xc3c3c3 },
553 { 0x40f8c, 0xc5c5c5 },
554 { 0x40f90, 0xc7c7c7 },
555 { 0x40f94, 0xc9c9c9 },
556 { 0x40f98, 0xcbcbcb },
557 { 0x40f9c, 0xcdcdcd },
558 { 0x40fa0, 0xcfcfcf },
559 { 0x40fa4, 0xd1d1d1 },
560 { 0x40fa8, 0xd3d3d3 },
561 { 0x40fac, 0xd5d5d5 },
562 { 0x40fb0, 0xd7d7d7 },
563 { 0x40fb4, 0xd9d9d9 },
564 { 0x40fb8, 0xdbdbdb },
565 { 0x40fbc, 0xdddddd },
566 { 0x40fc0, 0xdfdfdf },
567 { 0x40fc4, 0xe1e1e1 },
568 { 0x40fc8, 0xe3e3e3 },
569 { 0x40fcc, 0xe5e5e5 },
570 { 0x40fd0, 0xe7e7e7 },
571 { 0x40fd4, 0xe9e9e9 },
572 { 0x40fd8, 0xebebeb },
573 { 0x40fdc, 0xeeeeee },
574 { 0x40fe0, 0xf0f0f0 },
575 { 0x40fe4, 0xf2f2f2 },
576 { 0x40fe8, 0xf4f4f4 },
577 { 0x40fec, 0xf6f6f6 },
578 { 0x40ff0, 0xf8f8f8 },
579 { 0x40ff4, 0xfbfbfb },
580 { 0x40ff8, 0xfdfdfd },
581 { 0x40ffc, 0xffffff },
582};
diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h
new file mode 100644
index 000000000000..4e3deb4e592b
--- /dev/null
+++ b/drivers/video/msm/mdp_hw.h
@@ -0,0 +1,621 @@
1/* drivers/video/msm_fb/mdp_hw.h
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15#ifndef _MDP_HW_H_
16#define _MDP_HW_H_
17
18#include <mach/msm_iomap.h>
19#include <mach/msm_fb.h>
20
21struct mdp_info {
22 struct mdp_device mdp_dev;
23 char * __iomem base;
24 int irq;
25};
26struct mdp_blit_req;
27struct mdp_device;
28int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
29 struct file *src_file, unsigned long src_start,
30 unsigned long src_len, struct file *dst_file,
31 unsigned long dst_start, unsigned long dst_len);
32#define mdp_writel(mdp, value, offset) writel(value, mdp->base + offset)
33#define mdp_readl(mdp, offset) readl(mdp->base + offset)
34
35#define MDP_SYNC_CONFIG_0 (0x00000)
36#define MDP_SYNC_CONFIG_1 (0x00004)
37#define MDP_SYNC_CONFIG_2 (0x00008)
38#define MDP_SYNC_STATUS_0 (0x0000c)
39#define MDP_SYNC_STATUS_1 (0x00010)
40#define MDP_SYNC_STATUS_2 (0x00014)
41#define MDP_SYNC_THRESH_0 (0x00018)
42#define MDP_SYNC_THRESH_1 (0x0001c)
43#define MDP_INTR_ENABLE (0x00020)
44#define MDP_INTR_STATUS (0x00024)
45#define MDP_INTR_CLEAR (0x00028)
46#define MDP_DISPLAY0_START (0x00030)
47#define MDP_DISPLAY1_START (0x00034)
48#define MDP_DISPLAY_STATUS (0x00038)
49#define MDP_EBI2_LCD0 (0x0003c)
50#define MDP_EBI2_LCD1 (0x00040)
51#define MDP_DISPLAY0_ADDR (0x00054)
52#define MDP_DISPLAY1_ADDR (0x00058)
53#define MDP_EBI2_PORTMAP_MODE (0x0005c)
54#define MDP_MODE (0x00060)
55#define MDP_TV_OUT_STATUS (0x00064)
56#define MDP_HW_VERSION (0x00070)
57#define MDP_SW_RESET (0x00074)
58#define MDP_AXI_ERROR_MASTER_STOP (0x00078)
59#define MDP_SEL_CLK_OR_HCLK_TEST_BUS (0x0007c)
60#define MDP_PRIMARY_VSYNC_OUT_CTRL (0x00080)
61#define MDP_SECONDARY_VSYNC_OUT_CTRL (0x00084)
62#define MDP_EXTERNAL_VSYNC_OUT_CTRL (0x00088)
63#define MDP_VSYNC_CTRL (0x0008c)
64#define MDP_CGC_EN (0x00100)
65#define MDP_CMD_STATUS (0x10008)
66#define MDP_PROFILE_EN (0x10010)
67#define MDP_PROFILE_COUNT (0x10014)
68#define MDP_DMA_START (0x10044)
69#define MDP_FULL_BYPASS_WORD0 (0x10100)
70#define MDP_FULL_BYPASS_WORD1 (0x10104)
71#define MDP_COMMAND_CONFIG (0x10104)
72#define MDP_FULL_BYPASS_WORD2 (0x10108)
73#define MDP_FULL_BYPASS_WORD3 (0x1010c)
74#define MDP_FULL_BYPASS_WORD4 (0x10110)
75#define MDP_FULL_BYPASS_WORD6 (0x10118)
76#define MDP_FULL_BYPASS_WORD7 (0x1011c)
77#define MDP_FULL_BYPASS_WORD8 (0x10120)
78#define MDP_FULL_BYPASS_WORD9 (0x10124)
79#define MDP_PPP_SOURCE_CONFIG (0x10124)
80#define MDP_FULL_BYPASS_WORD10 (0x10128)
81#define MDP_FULL_BYPASS_WORD11 (0x1012c)
82#define MDP_FULL_BYPASS_WORD12 (0x10130)
83#define MDP_FULL_BYPASS_WORD13 (0x10134)
84#define MDP_FULL_BYPASS_WORD14 (0x10138)
85#define MDP_PPP_OPERATION_CONFIG (0x10138)
86#define MDP_FULL_BYPASS_WORD15 (0x1013c)
87#define MDP_FULL_BYPASS_WORD16 (0x10140)
88#define MDP_FULL_BYPASS_WORD17 (0x10144)
89#define MDP_FULL_BYPASS_WORD18 (0x10148)
90#define MDP_FULL_BYPASS_WORD19 (0x1014c)
91#define MDP_FULL_BYPASS_WORD20 (0x10150)
92#define MDP_PPP_DESTINATION_CONFIG (0x10150)
93#define MDP_FULL_BYPASS_WORD21 (0x10154)
94#define MDP_FULL_BYPASS_WORD22 (0x10158)
95#define MDP_FULL_BYPASS_WORD23 (0x1015c)
96#define MDP_FULL_BYPASS_WORD24 (0x10160)
97#define MDP_FULL_BYPASS_WORD25 (0x10164)
98#define MDP_FULL_BYPASS_WORD26 (0x10168)
99#define MDP_FULL_BYPASS_WORD27 (0x1016c)
100#define MDP_FULL_BYPASS_WORD29 (0x10174)
101#define MDP_FULL_BYPASS_WORD30 (0x10178)
102#define MDP_FULL_BYPASS_WORD31 (0x1017c)
103#define MDP_FULL_BYPASS_WORD32 (0x10180)
104#define MDP_DMA_CONFIG (0x10180)
105#define MDP_FULL_BYPASS_WORD33 (0x10184)
106#define MDP_FULL_BYPASS_WORD34 (0x10188)
107#define MDP_FULL_BYPASS_WORD35 (0x1018c)
108#define MDP_FULL_BYPASS_WORD37 (0x10194)
109#define MDP_FULL_BYPASS_WORD39 (0x1019c)
110#define MDP_FULL_BYPASS_WORD40 (0x101a0)
111#define MDP_FULL_BYPASS_WORD41 (0x101a4)
112#define MDP_FULL_BYPASS_WORD43 (0x101ac)
113#define MDP_FULL_BYPASS_WORD46 (0x101b8)
114#define MDP_FULL_BYPASS_WORD47 (0x101bc)
115#define MDP_FULL_BYPASS_WORD48 (0x101c0)
116#define MDP_FULL_BYPASS_WORD49 (0x101c4)
117#define MDP_FULL_BYPASS_WORD50 (0x101c8)
118#define MDP_FULL_BYPASS_WORD51 (0x101cc)
119#define MDP_FULL_BYPASS_WORD52 (0x101d0)
120#define MDP_FULL_BYPASS_WORD53 (0x101d4)
121#define MDP_FULL_BYPASS_WORD54 (0x101d8)
122#define MDP_FULL_BYPASS_WORD55 (0x101dc)
123#define MDP_FULL_BYPASS_WORD56 (0x101e0)
124#define MDP_FULL_BYPASS_WORD57 (0x101e4)
125#define MDP_FULL_BYPASS_WORD58 (0x101e8)
126#define MDP_FULL_BYPASS_WORD59 (0x101ec)
127#define MDP_FULL_BYPASS_WORD60 (0x101f0)
128#define MDP_VSYNC_THRESHOLD (0x101f0)
129#define MDP_FULL_BYPASS_WORD61 (0x101f4)
130#define MDP_FULL_BYPASS_WORD62 (0x101f8)
131#define MDP_FULL_BYPASS_WORD63 (0x101fc)
132#define MDP_TFETCH_TEST_MODE (0x20004)
133#define MDP_TFETCH_STATUS (0x20008)
134#define MDP_TFETCH_TILE_COUNT (0x20010)
135#define MDP_TFETCH_FETCH_COUNT (0x20014)
136#define MDP_TFETCH_CONSTANT_COLOR (0x20040)
137#define MDP_CSC_BYPASS (0x40004)
138#define MDP_SCALE_COEFF_LSB (0x5fffc)
139#define MDP_TV_OUT_CTL (0xc0000)
140#define MDP_TV_OUT_FIR_COEFF (0xc0004)
141#define MDP_TV_OUT_BUF_ADDR (0xc0008)
142#define MDP_TV_OUT_CC_DATA (0xc000c)
143#define MDP_TV_OUT_SOBEL (0xc0010)
144#define MDP_TV_OUT_Y_CLAMP (0xc0018)
145#define MDP_TV_OUT_CB_CLAMP (0xc001c)
146#define MDP_TV_OUT_CR_CLAMP (0xc0020)
147#define MDP_TEST_MODE_CLK (0xd0000)
148#define MDP_TEST_MISR_RESET_CLK (0xd0004)
149#define MDP_TEST_EXPORT_MISR_CLK (0xd0008)
150#define MDP_TEST_MISR_CURR_VAL_CLK (0xd000c)
151#define MDP_TEST_MODE_HCLK (0xd0100)
152#define MDP_TEST_MISR_RESET_HCLK (0xd0104)
153#define MDP_TEST_EXPORT_MISR_HCLK (0xd0108)
154#define MDP_TEST_MISR_CURR_VAL_HCLK (0xd010c)
155#define MDP_TEST_MODE_DCLK (0xd0200)
156#define MDP_TEST_MISR_RESET_DCLK (0xd0204)
157#define MDP_TEST_EXPORT_MISR_DCLK (0xd0208)
158#define MDP_TEST_MISR_CURR_VAL_DCLK (0xd020c)
159#define MDP_TEST_CAPTURED_DCLK (0xd0210)
160#define MDP_TEST_MISR_CAPT_VAL_DCLK (0xd0214)
161#define MDP_LCDC_CTL (0xe0000)
162#define MDP_LCDC_HSYNC_CTL (0xe0004)
163#define MDP_LCDC_VSYNC_CTL (0xe0008)
164#define MDP_LCDC_ACTIVE_HCTL (0xe000c)
165#define MDP_LCDC_ACTIVE_VCTL (0xe0010)
166#define MDP_LCDC_BORDER_CLR (0xe0014)
167#define MDP_LCDC_H_BLANK (0xe0018)
168#define MDP_LCDC_V_BLANK (0xe001c)
169#define MDP_LCDC_UNDERFLOW_CLR (0xe0020)
170#define MDP_LCDC_HSYNC_SKEW (0xe0024)
171#define MDP_LCDC_TEST_CTL (0xe0028)
172#define MDP_LCDC_LINE_IRQ (0xe002c)
173#define MDP_LCDC_CTL_POLARITY (0xe0030)
174#define MDP_LCDC_DMA_CONFIG (0xe1000)
175#define MDP_LCDC_DMA_SIZE (0xe1004)
176#define MDP_LCDC_DMA_IBUF_ADDR (0xe1008)
177#define MDP_LCDC_DMA_IBUF_Y_STRIDE (0xe100c)
178
179
180#define MDP_DMA2_TERM 0x1
181#define MDP_DMA3_TERM 0x2
182#define MDP_PPP_TERM 0x3
183
184/* MDP_INTR_ENABLE */
185#define DL0_ROI_DONE (1<<0)
186#define DL1_ROI_DONE (1<<1)
187#define DL0_DMA2_TERM_DONE (1<<2)
188#define DL1_DMA2_TERM_DONE (1<<3)
189#define DL0_PPP_TERM_DONE (1<<4)
190#define DL1_PPP_TERM_DONE (1<<5)
191#define TV_OUT_DMA3_DONE (1<<6)
192#define TV_ENC_UNDERRUN (1<<7)
193#define DL0_FETCH_DONE (1<<11)
194#define DL1_FETCH_DONE (1<<12)
195
196#define MDP_PPP_BUSY_STATUS (DL0_ROI_DONE| \
197 DL1_ROI_DONE| \
198 DL0_PPP_TERM_DONE| \
199 DL1_PPP_TERM_DONE)
200
201#define MDP_ANY_INTR_MASK (DL0_ROI_DONE| \
202 DL1_ROI_DONE| \
203 DL0_DMA2_TERM_DONE| \
204 DL1_DMA2_TERM_DONE| \
205 DL0_PPP_TERM_DONE| \
206 DL1_PPP_TERM_DONE| \
207 DL0_FETCH_DONE| \
208 DL1_FETCH_DONE| \
209 TV_ENC_UNDERRUN)
210
211#define MDP_TOP_LUMA 16
212#define MDP_TOP_CHROMA 0
213#define MDP_BOTTOM_LUMA 19
214#define MDP_BOTTOM_CHROMA 3
215#define MDP_LEFT_LUMA 22
216#define MDP_LEFT_CHROMA 6
217#define MDP_RIGHT_LUMA 25
218#define MDP_RIGHT_CHROMA 9
219
220#define CLR_G 0x0
221#define CLR_B 0x1
222#define CLR_R 0x2
223#define CLR_ALPHA 0x3
224
225#define CLR_Y CLR_G
226#define CLR_CB CLR_B
227#define CLR_CR CLR_R
228
229/* from lsb to msb */
230#define MDP_GET_PACK_PATTERN(a, x, y, z, bit) \
231 (((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z))
232
233/* MDP_SYNC_CONFIG_0/1/2 */
234#define MDP_SYNCFG_HGT_LOC 22
235#define MDP_SYNCFG_VSYNC_EXT_EN (1<<21)
236#define MDP_SYNCFG_VSYNC_INT_EN (1<<20)
237
238/* MDP_SYNC_THRESH_0 */
239#define MDP_PRIM_BELOW_LOC 0
240#define MDP_PRIM_ABOVE_LOC 8
241
242/* MDP_{PRIMARY,SECONDARY,EXTERNAL}_VSYNC_OUT_CRL */
243#define VSYNC_PULSE_EN (1<<31)
244#define VSYNC_PULSE_INV (1<<30)
245
246/* MDP_VSYNC_CTRL */
247#define DISP0_VSYNC_MAP_VSYNC0 0
248#define DISP0_VSYNC_MAP_VSYNC1 (1<<0)
249#define DISP0_VSYNC_MAP_VSYNC2 ((1<<0)|(1<<1))
250
251#define DISP1_VSYNC_MAP_VSYNC0 0
252#define DISP1_VSYNC_MAP_VSYNC1 (1<<2)
253#define DISP1_VSYNC_MAP_VSYNC2 ((1<<2)|(1<<3))
254
255#define PRIMARY_LCD_SYNC_EN (1<<4)
256#define PRIMARY_LCD_SYNC_DISABLE 0
257
258#define SECONDARY_LCD_SYNC_EN (1<<5)
259#define SECONDARY_LCD_SYNC_DISABLE 0
260
261#define EXTERNAL_LCD_SYNC_EN (1<<6)
262#define EXTERNAL_LCD_SYNC_DISABLE 0
263
264/* MDP_VSYNC_THRESHOLD / MDP_FULL_BYPASS_WORD60 */
265#define VSYNC_THRESHOLD_ABOVE_LOC 0
266#define VSYNC_THRESHOLD_BELOW_LOC 16
267#define VSYNC_ANTI_TEAR_EN (1<<31)
268
269/* MDP_COMMAND_CONFIG / MDP_FULL_BYPASS_WORD1 */
270#define MDP_CMD_DBGBUS_EN (1<<0)
271
272/* MDP_PPP_SOURCE_CONFIG / MDP_FULL_BYPASS_WORD9&53 */
273#define PPP_SRC_C0G_8BIT ((1<<1)|(1<<0))
274#define PPP_SRC_C1B_8BIT ((1<<3)|(1<<2))
275#define PPP_SRC_C2R_8BIT ((1<<5)|(1<<4))
276#define PPP_SRC_C3A_8BIT ((1<<7)|(1<<6))
277
278#define PPP_SRC_C0G_6BIT (1<<1)
279#define PPP_SRC_C1B_6BIT (1<<3)
280#define PPP_SRC_C2R_6BIT (1<<5)
281
282#define PPP_SRC_C0G_5BIT (1<<0)
283#define PPP_SRC_C1B_5BIT (1<<2)
284#define PPP_SRC_C2R_5BIT (1<<4)
285
286#define PPP_SRC_C3ALPHA_EN (1<<8)
287
288#define PPP_SRC_BPP_1BYTES 0
289#define PPP_SRC_BPP_2BYTES (1<<9)
290#define PPP_SRC_BPP_3BYTES (1<<10)
291#define PPP_SRC_BPP_4BYTES ((1<<10)|(1<<9))
292
293#define PPP_SRC_BPP_ROI_ODD_X (1<<11)
294#define PPP_SRC_BPP_ROI_ODD_Y (1<<12)
295#define PPP_SRC_INTERLVD_2COMPONENTS (1<<13)
296#define PPP_SRC_INTERLVD_3COMPONENTS (1<<14)
297#define PPP_SRC_INTERLVD_4COMPONENTS ((1<<14)|(1<<13))
298
299
300/* RGB666 unpack format
301** TIGHT means R6+G6+B6 together
302** LOOSE means R6+2 +G6+2+ B6+2 (with MSB)
303** or 2+R6 +2+G6 +2+B6 (with LSB)
304*/
305#define PPP_SRC_PACK_TIGHT (1<<17)
306#define PPP_SRC_PACK_LOOSE 0
307#define PPP_SRC_PACK_ALIGN_LSB 0
308#define PPP_SRC_PACK_ALIGN_MSB (1<<18)
309
310#define PPP_SRC_PLANE_INTERLVD 0
311#define PPP_SRC_PLANE_PSEUDOPLNR (1<<20)
312
313#define PPP_SRC_WMV9_MODE (1<<21)
314
315/* MDP_PPP_OPERATION_CONFIG / MDP_FULL_BYPASS_WORD14 */
316#define PPP_OP_SCALE_X_ON (1<<0)
317#define PPP_OP_SCALE_Y_ON (1<<1)
318
319#define PPP_OP_CONVERT_RGB2YCBCR 0
320#define PPP_OP_CONVERT_YCBCR2RGB (1<<2)
321#define PPP_OP_CONVERT_ON (1<<3)
322
323#define PPP_OP_CONVERT_MATRIX_PRIMARY 0
324#define PPP_OP_CONVERT_MATRIX_SECONDARY (1<<4)
325
326#define PPP_OP_LUT_C0_ON (1<<5)
327#define PPP_OP_LUT_C1_ON (1<<6)
328#define PPP_OP_LUT_C2_ON (1<<7)
329
330/* rotate or blend enable */
331#define PPP_OP_ROT_ON (1<<8)
332
333#define PPP_OP_ROT_90 (1<<9)
334#define PPP_OP_FLIP_LR (1<<10)
335#define PPP_OP_FLIP_UD (1<<11)
336
337#define PPP_OP_BLEND_ON (1<<12)
338
339#define PPP_OP_BLEND_SRCPIXEL_ALPHA 0
340#define PPP_OP_BLEND_DSTPIXEL_ALPHA (1<<13)
341#define PPP_OP_BLEND_CONSTANT_ALPHA (1<<14)
342#define PPP_OP_BLEND_SRCPIXEL_TRANSP ((1<<13)|(1<<14))
343
344#define PPP_OP_BLEND_ALPHA_BLEND_NORMAL 0
345#define PPP_OP_BLEND_ALPHA_BLEND_REVERSE (1<<15)
346
347#define PPP_OP_DITHER_EN (1<<16)
348
349#define PPP_OP_COLOR_SPACE_RGB 0
350#define PPP_OP_COLOR_SPACE_YCBCR (1<<17)
351
352#define PPP_OP_SRC_CHROMA_RGB 0
353#define PPP_OP_SRC_CHROMA_H2V1 (1<<18)
354#define PPP_OP_SRC_CHROMA_H1V2 (1<<19)
355#define PPP_OP_SRC_CHROMA_420 ((1<<18)|(1<<19))
356#define PPP_OP_SRC_CHROMA_COSITE 0
357#define PPP_OP_SRC_CHROMA_OFFSITE (1<<20)
358
359#define PPP_OP_DST_CHROMA_RGB 0
360#define PPP_OP_DST_CHROMA_H2V1 (1<<21)
361#define PPP_OP_DST_CHROMA_H1V2 (1<<22)
362#define PPP_OP_DST_CHROMA_420 ((1<<21)|(1<<22))
363#define PPP_OP_DST_CHROMA_COSITE 0
364#define PPP_OP_DST_CHROMA_OFFSITE (1<<23)
365
366#define PPP_BLEND_ALPHA_TRANSP (1<<24)
367
368#define PPP_OP_BG_CHROMA_RGB 0
369#define PPP_OP_BG_CHROMA_H2V1 (1<<25)
370#define PPP_OP_BG_CHROMA_H1V2 (1<<26)
371#define PPP_OP_BG_CHROMA_420 ((1<<25)|(1<<26))
372#define PPP_OP_BG_CHROMA_SITE_COSITE 0
373#define PPP_OP_BG_CHROMA_SITE_OFFSITE (1<<27)
374
375/* MDP_PPP_DESTINATION_CONFIG / MDP_FULL_BYPASS_WORD20 */
376#define PPP_DST_C0G_8BIT ((1<<0)|(1<<1))
377#define PPP_DST_C1B_8BIT ((1<<3)|(1<<2))
378#define PPP_DST_C2R_8BIT ((1<<5)|(1<<4))
379#define PPP_DST_C3A_8BIT ((1<<7)|(1<<6))
380
381#define PPP_DST_C0G_6BIT (1<<1)
382#define PPP_DST_C1B_6BIT (1<<3)
383#define PPP_DST_C2R_6BIT (1<<5)
384
385#define PPP_DST_C0G_5BIT (1<<0)
386#define PPP_DST_C1B_5BIT (1<<2)
387#define PPP_DST_C2R_5BIT (1<<4)
388
389#define PPP_DST_C3A_8BIT ((1<<7)|(1<<6))
390#define PPP_DST_C3ALPHA_EN (1<<8)
391
392#define PPP_DST_INTERLVD_2COMPONENTS (1<<9)
393#define PPP_DST_INTERLVD_3COMPONENTS (1<<10)
394#define PPP_DST_INTERLVD_4COMPONENTS ((1<<10)|(1<<9))
395#define PPP_DST_INTERLVD_6COMPONENTS ((1<<11)|(1<<9))
396
397#define PPP_DST_PACK_LOOSE 0
398#define PPP_DST_PACK_TIGHT (1<<13)
399#define PPP_DST_PACK_ALIGN_LSB 0
400#define PPP_DST_PACK_ALIGN_MSB (1<<14)
401
402#define PPP_DST_OUT_SEL_AXI 0
403#define PPP_DST_OUT_SEL_MDDI (1<<15)
404
405#define PPP_DST_BPP_2BYTES (1<<16)
406#define PPP_DST_BPP_3BYTES (1<<17)
407#define PPP_DST_BPP_4BYTES ((1<<17)|(1<<16))
408
409#define PPP_DST_PLANE_INTERLVD 0
410#define PPP_DST_PLANE_PLANAR (1<<18)
411#define PPP_DST_PLANE_PSEUDOPLNR (1<<19)
412
413#define PPP_DST_TO_TV (1<<20)
414
415#define PPP_DST_MDDI_PRIMARY 0
416#define PPP_DST_MDDI_SECONDARY (1<<21)
417#define PPP_DST_MDDI_EXTERNAL (1<<22)
418
419/* image configurations by image type */
420#define PPP_CFG_MDP_RGB_565(dir) (PPP_##dir##_C2R_5BIT | \
421 PPP_##dir##_C0G_6BIT | \
422 PPP_##dir##_C1B_5BIT | \
423 PPP_##dir##_BPP_2BYTES | \
424 PPP_##dir##_INTERLVD_3COMPONENTS | \
425 PPP_##dir##_PACK_TIGHT | \
426 PPP_##dir##_PACK_ALIGN_LSB | \
427 PPP_##dir##_PLANE_INTERLVD)
428
429#define PPP_CFG_MDP_RGB_888(dir) (PPP_##dir##_C2R_8BIT | \
430 PPP_##dir##_C0G_8BIT | \
431 PPP_##dir##_C1B_8BIT | \
432 PPP_##dir##_BPP_3BYTES | \
433 PPP_##dir##_INTERLVD_3COMPONENTS | \
434 PPP_##dir##_PACK_TIGHT | \
435 PPP_##dir##_PACK_ALIGN_LSB | \
436 PPP_##dir##_PLANE_INTERLVD)
437
438#define PPP_CFG_MDP_ARGB_8888(dir) (PPP_##dir##_C2R_8BIT | \
439 PPP_##dir##_C0G_8BIT | \
440 PPP_##dir##_C1B_8BIT | \
441 PPP_##dir##_C3A_8BIT | \
442 PPP_##dir##_C3ALPHA_EN | \
443 PPP_##dir##_BPP_4BYTES | \
444 PPP_##dir##_INTERLVD_4COMPONENTS | \
445 PPP_##dir##_PACK_TIGHT | \
446 PPP_##dir##_PACK_ALIGN_LSB | \
447 PPP_##dir##_PLANE_INTERLVD)
448
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)
451#define PPP_CFG_MDP_BGRA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
452
453#define PPP_CFG_MDP_Y_CBCR_H2V2(dir) (PPP_##dir##_C2R_8BIT | \
454 PPP_##dir##_C0G_8BIT | \
455 PPP_##dir##_C1B_8BIT | \
456 PPP_##dir##_C3A_8BIT | \
457 PPP_##dir##_BPP_2BYTES | \
458 PPP_##dir##_INTERLVD_2COMPONENTS | \
459 PPP_##dir##_PACK_TIGHT | \
460 PPP_##dir##_PACK_ALIGN_LSB | \
461 PPP_##dir##_PLANE_PSEUDOPLNR)
462
463#define PPP_CFG_MDP_Y_CRCB_H2V2(dir) PPP_CFG_MDP_Y_CBCR_H2V2(dir)
464
465#define PPP_CFG_MDP_YCRYCB_H2V1(dir) (PPP_##dir##_C2R_8BIT | \
466 PPP_##dir##_C0G_8BIT | \
467 PPP_##dir##_C1B_8BIT | \
468 PPP_##dir##_C3A_8BIT | \
469 PPP_##dir##_BPP_2BYTES | \
470 PPP_##dir##_INTERLVD_4COMPONENTS | \
471 PPP_##dir##_PACK_TIGHT | \
472 PPP_##dir##_PACK_ALIGN_LSB |\
473 PPP_##dir##_PLANE_INTERLVD)
474
475#define PPP_CFG_MDP_Y_CBCR_H2V1(dir) (PPP_##dir##_C2R_8BIT | \
476 PPP_##dir##_C0G_8BIT | \
477 PPP_##dir##_C1B_8BIT | \
478 PPP_##dir##_C3A_8BIT | \
479 PPP_##dir##_BPP_2BYTES | \
480 PPP_##dir##_INTERLVD_2COMPONENTS | \
481 PPP_##dir##_PACK_TIGHT | \
482 PPP_##dir##_PACK_ALIGN_LSB | \
483 PPP_##dir##_PLANE_PSEUDOPLNR)
484
485#define PPP_CFG_MDP_Y_CRCB_H2V1(dir) PPP_CFG_MDP_Y_CBCR_H2V1(dir)
486
487#define PPP_PACK_PATTERN_MDP_RGB_565 \
488 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_XRGB_8888 \
491 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8)
492#define PPP_PACK_PATTERN_MDP_ARGB_8888 PPP_PACK_PATTERN_MDP_XRGB_8888
493#define PPP_PACK_PATTERN_MDP_RGBA_8888 \
494 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8)
495#define PPP_PACK_PATTERN_MDP_BGRA_8888 \
496 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8)
497#define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 \
498 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
500#define PPP_PACK_PATTERN_MDP_Y_CRCB_H2V1 \
501 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8)
502#define PPP_PACK_PATTERN_MDP_Y_CRCB_H2V2 PPP_PACK_PATTERN_MDP_Y_CRCB_H2V1
503#define PPP_PACK_PATTERN_MDP_YCRYCB_H2V1 \
504 MDP_GET_PACK_PATTERN(CLR_Y, CLR_R, CLR_Y, CLR_B, 8)
505
506#define PPP_CHROMA_SAMP_MDP_RGB_565(dir) PPP_OP_##dir##_CHROMA_RGB
507#define PPP_CHROMA_SAMP_MDP_RGB_888(dir) PPP_OP_##dir##_CHROMA_RGB
508#define PPP_CHROMA_SAMP_MDP_XRGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB
509#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
511#define PPP_CHROMA_SAMP_MDP_BGRA_8888(dir) PPP_OP_##dir##_CHROMA_RGB
512#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
514#define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
515#define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V2(dir) PPP_OP_##dir##_CHROMA_420
516#define PPP_CHROMA_SAMP_MDP_YCRYCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
517
518/* Helpful array generation macros */
519#define PPP_ARRAY0(name) \
520 [MDP_RGB_565] = PPP_##name##_MDP_RGB_565,\
521 [MDP_RGB_888] = PPP_##name##_MDP_RGB_888,\
522 [MDP_XRGB_8888] = PPP_##name##_MDP_XRGB_8888,\
523 [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888,\
524 [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888,\
525 [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888,\
526 [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1,\
527 [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2,\
528 [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1,\
529 [MDP_Y_CRCB_H2V2] = PPP_##name##_MDP_Y_CRCB_H2V2,\
530 [MDP_YCRYCB_H2V1] = PPP_##name##_MDP_YCRYCB_H2V1
531
532#define PPP_ARRAY1(name, dir) \
533 [MDP_RGB_565] = PPP_##name##_MDP_RGB_565(dir),\
534 [MDP_RGB_888] = PPP_##name##_MDP_RGB_888(dir),\
535 [MDP_XRGB_8888] = PPP_##name##_MDP_XRGB_8888(dir),\
536 [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888(dir),\
537 [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888(dir),\
538 [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888(dir),\
539 [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1(dir),\
540 [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2(dir),\
541 [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1(dir),\
542 [MDP_Y_CRCB_H2V2] = PPP_##name##_MDP_Y_CRCB_H2V2(dir),\
543 [MDP_YCRYCB_H2V1] = PPP_##name##_MDP_YCRYCB_H2V1(dir)
544
545#define IS_YCRCB(img) ((img == MDP_Y_CRCB_H2V2) | (img == MDP_Y_CBCR_H2V2) | \
546 (img == MDP_Y_CRCB_H2V1) | (img == MDP_Y_CBCR_H2V1) | \
547 (img == MDP_YCRYCB_H2V1))
548#define IS_RGB(img) ((img == MDP_RGB_565) | (img == MDP_RGB_888) | \
549 (img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \
550 (img == MDP_XRGB_8888) | (img == MDP_BGRA_8888))
551#define HAS_ALPHA(img) ((img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \
552 (img == MDP_BGRA_8888))
553
554#define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \
555 (img == MDP_Y_CBCR_H2V2) | \
556 (img == MDP_Y_CRCB_H2V1) | \
557 (img == MDP_Y_CBCR_H2V1))
558
559/* Mappings from addr to purpose */
560#define PPP_ADDR_SRC_ROI MDP_FULL_BYPASS_WORD2
561#define PPP_ADDR_SRC0 MDP_FULL_BYPASS_WORD3
562#define PPP_ADDR_SRC1 MDP_FULL_BYPASS_WORD4
563#define PPP_ADDR_SRC_YSTRIDE MDP_FULL_BYPASS_WORD7
564#define PPP_ADDR_SRC_CFG MDP_FULL_BYPASS_WORD9
565#define PPP_ADDR_SRC_PACK_PATTERN MDP_FULL_BYPASS_WORD10
566#define PPP_ADDR_OPERATION MDP_FULL_BYPASS_WORD14
567#define PPP_ADDR_PHASEX_INIT MDP_FULL_BYPASS_WORD15
568#define PPP_ADDR_PHASEY_INIT MDP_FULL_BYPASS_WORD16
569#define PPP_ADDR_PHASEX_STEP MDP_FULL_BYPASS_WORD17
570#define PPP_ADDR_PHASEY_STEP MDP_FULL_BYPASS_WORD18
571#define PPP_ADDR_ALPHA_TRANSP MDP_FULL_BYPASS_WORD19
572#define PPP_ADDR_DST_CFG MDP_FULL_BYPASS_WORD20
573#define PPP_ADDR_DST_PACK_PATTERN MDP_FULL_BYPASS_WORD21
574#define PPP_ADDR_DST_ROI MDP_FULL_BYPASS_WORD25
575#define PPP_ADDR_DST0 MDP_FULL_BYPASS_WORD26
576#define PPP_ADDR_DST1 MDP_FULL_BYPASS_WORD27
577#define PPP_ADDR_DST_YSTRIDE MDP_FULL_BYPASS_WORD30
578#define PPP_ADDR_EDGE MDP_FULL_BYPASS_WORD46
579#define PPP_ADDR_BG0 MDP_FULL_BYPASS_WORD48
580#define PPP_ADDR_BG1 MDP_FULL_BYPASS_WORD49
581#define PPP_ADDR_BG_YSTRIDE MDP_FULL_BYPASS_WORD51
582#define PPP_ADDR_BG_CFG MDP_FULL_BYPASS_WORD53
583#define PPP_ADDR_BG_PACK_PATTERN MDP_FULL_BYPASS_WORD54
584
585/* MDP_DMA_CONFIG / MDP_FULL_BYPASS_WORD32 */
586#define DMA_DSTC0G_6BITS (1<<1)
587#define DMA_DSTC1B_6BITS (1<<3)
588#define DMA_DSTC2R_6BITS (1<<5)
589#define DMA_DSTC0G_5BITS (1<<0)
590#define DMA_DSTC1B_5BITS (1<<2)
591#define DMA_DSTC2R_5BITS (1<<4)
592
593#define DMA_PACK_TIGHT (1<<6)
594#define DMA_PACK_LOOSE 0
595#define DMA_PACK_ALIGN_LSB 0
596#define DMA_PACK_ALIGN_MSB (1<<7)
597#define DMA_PACK_PATTERN_RGB \
598 (MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8)
599
600#define DMA_OUT_SEL_AHB 0
601#define DMA_OUT_SEL_MDDI (1<<14)
602#define DMA_AHBM_LCD_SEL_PRIMARY 0
603#define DMA_AHBM_LCD_SEL_SECONDARY (1<<15)
604#define DMA_IBUF_C3ALPHA_EN (1<<16)
605#define DMA_DITHER_EN (1<<17)
606
607#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
608#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY (1<<18)
609#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL (1<<19)
610
611#define DMA_IBUF_FORMAT_RGB565 (1<<20)
612#define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 0
613
614#define DMA_IBUF_NONCONTIGUOUS (1<<21)
615
616/* MDDI REGISTER ? */
617#define MDDI_VDO_PACKET_DESC 0x5666
618#define MDDI_VDO_PACKET_PRIM 0xC3
619#define MDDI_VDO_PACKET_SECD 0xC0
620
621#endif
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
new file mode 100644
index 000000000000..ba2c4673b648
--- /dev/null
+++ b/drivers/video/msm/mdp_ppp.c
@@ -0,0 +1,750 @@
1/* drivers/video/msm/mdp_ppp.c
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15#include <linux/fb.h>
16#include <linux/file.h>
17#include <linux/delay.h>
18#include <linux/msm_mdp.h>
19#include <linux/android_pmem.h>
20#include <mach/msm_fb.h>
21
22#include "mdp_hw.h"
23#include "mdp_scale_tables.h"
24
25#define DLOG(x...) do {} while (0)
26
27#define MDP_DOWNSCALE_BLUR (MDP_DOWNSCALE_MAX + 1)
28static int downscale_y_table = MDP_DOWNSCALE_MAX;
29static int downscale_x_table = MDP_DOWNSCALE_MAX;
30
31struct mdp_regs {
32 uint32_t src0;
33 uint32_t src1;
34 uint32_t dst0;
35 uint32_t dst1;
36 uint32_t src_cfg;
37 uint32_t dst_cfg;
38 uint32_t src_pack;
39 uint32_t dst_pack;
40 uint32_t src_rect;
41 uint32_t dst_rect;
42 uint32_t src_ystride;
43 uint32_t dst_ystride;
44 uint32_t op;
45 uint32_t src_bpp;
46 uint32_t dst_bpp;
47 uint32_t edge;
48 uint32_t phasex_init;
49 uint32_t phasey_init;
50 uint32_t phasex_step;
51 uint32_t phasey_step;
52};
53
54static uint32_t pack_pattern[] = {
55 PPP_ARRAY0(PACK_PATTERN)
56};
57
58static uint32_t src_img_cfg[] = {
59 PPP_ARRAY1(CFG, SRC)
60};
61
62static uint32_t dst_img_cfg[] = {
63 PPP_ARRAY1(CFG, DST)
64};
65
66static uint32_t bytes_per_pixel[] = {
67 [MDP_RGB_565] = 2,
68 [MDP_RGB_888] = 3,
69 [MDP_XRGB_8888] = 4,
70 [MDP_ARGB_8888] = 4,
71 [MDP_RGBA_8888] = 4,
72 [MDP_BGRA_8888] = 4,
73 [MDP_Y_CBCR_H2V1] = 1,
74 [MDP_Y_CBCR_H2V2] = 1,
75 [MDP_Y_CRCB_H2V1] = 1,
76 [MDP_Y_CRCB_H2V2] = 1,
77 [MDP_YCRYCB_H2V1] = 2
78};
79
80static uint32_t dst_op_chroma[] = {
81 PPP_ARRAY1(CHROMA_SAMP, DST)
82};
83
84static uint32_t src_op_chroma[] = {
85 PPP_ARRAY1(CHROMA_SAMP, SRC)
86};
87
88static uint32_t bg_op_chroma[] = {
89 PPP_ARRAY1(CHROMA_SAMP, BG)
90};
91
92static void rotate_dst_addr_x(struct mdp_blit_req *req, struct mdp_regs *regs)
93{
94 regs->dst0 += (req->dst_rect.w -
95 min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp;
96 regs->dst1 += (req->dst_rect.w -
97 min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp;
98}
99
100static void rotate_dst_addr_y(struct mdp_blit_req *req, struct mdp_regs *regs)
101{
102 regs->dst0 += (req->dst_rect.h -
103 min((uint32_t)16, req->dst_rect.h)) *
104 regs->dst_ystride;
105 regs->dst1 += (req->dst_rect.h -
106 min((uint32_t)16, req->dst_rect.h)) *
107 regs->dst_ystride;
108}
109
110static void blit_rotate(struct mdp_blit_req *req,
111 struct mdp_regs *regs)
112{
113 if (req->flags == MDP_ROT_NOP)
114 return;
115
116 regs->op |= PPP_OP_ROT_ON;
117 if ((req->flags & MDP_ROT_90 || req->flags & MDP_FLIP_LR) &&
118 !(req->flags & MDP_ROT_90 && req->flags & MDP_FLIP_LR))
119 rotate_dst_addr_x(req, regs);
120 if (req->flags & MDP_ROT_90)
121 regs->op |= PPP_OP_ROT_90;
122 if (req->flags & MDP_FLIP_UD) {
123 regs->op |= PPP_OP_FLIP_UD;
124 rotate_dst_addr_y(req, regs);
125 }
126 if (req->flags & MDP_FLIP_LR)
127 regs->op |= PPP_OP_FLIP_LR;
128}
129
130static void blit_convert(struct mdp_blit_req *req, struct mdp_regs *regs)
131{
132 if (req->src.format == req->dst.format)
133 return;
134 if (IS_RGB(req->src.format) && IS_YCRCB(req->dst.format)) {
135 regs->op |= PPP_OP_CONVERT_RGB2YCBCR | PPP_OP_CONVERT_ON;
136 } else if (IS_YCRCB(req->src.format) && IS_RGB(req->dst.format)) {
137 regs->op |= PPP_OP_CONVERT_YCBCR2RGB | PPP_OP_CONVERT_ON;
138 if (req->dst.format == MDP_RGB_565)
139 regs->op |= PPP_OP_CONVERT_MATRIX_SECONDARY;
140 }
141}
142
143#define GET_BIT_RANGE(value, high, low) \
144 (((1 << (high - low + 1)) - 1) & (value >> low))
145static uint32_t transp_convert(struct mdp_blit_req *req)
146{
147 uint32_t transp = 0;
148 if (req->src.format == MDP_RGB_565) {
149 /* pad each value to 8 bits by copying the high bits into the
150 * low end, convert RGB to RBG by switching low 2 components */
151 transp |= ((GET_BIT_RANGE(req->transp_mask, 15, 11) << 3) |
152 (GET_BIT_RANGE(req->transp_mask, 15, 13))) << 16;
153
154 transp |= ((GET_BIT_RANGE(req->transp_mask, 4, 0) << 3) |
155 (GET_BIT_RANGE(req->transp_mask, 4, 2))) << 8;
156
157 transp |= (GET_BIT_RANGE(req->transp_mask, 10, 5) << 2) |
158 (GET_BIT_RANGE(req->transp_mask, 10, 9));
159 } else {
160 /* convert RGB to RBG */
161 transp |= (GET_BIT_RANGE(req->transp_mask, 15, 8)) |
162 (GET_BIT_RANGE(req->transp_mask, 23, 16) << 16) |
163 (GET_BIT_RANGE(req->transp_mask, 7, 0) << 8);
164 }
165 return transp;
166}
167#undef GET_BIT_RANGE
168
169static void blit_blend(struct mdp_blit_req *req, struct mdp_regs *regs)
170{
171 /* TRANSP BLEND */
172 if (req->transp_mask != MDP_TRANSP_NOP) {
173 req->transp_mask = transp_convert(req);
174 if (req->alpha != MDP_ALPHA_NOP) {
175 /* use blended transparancy mode
176 * pixel = (src == transp) ? dst : blend
177 * blend is combo of blend_eq_sel and
178 * blend_alpha_sel */
179 regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
180 PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
181 PPP_OP_BLEND_CONSTANT_ALPHA |
182 PPP_BLEND_ALPHA_TRANSP;
183 } else {
184 /* simple transparancy mode
185 * pixel = (src == transp) ? dst : src */
186 regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
187 PPP_OP_BLEND_SRCPIXEL_TRANSP;
188 }
189 }
190
191 req->alpha &= 0xff;
192 /* ALPHA BLEND */
193 if (HAS_ALPHA(req->src.format)) {
194 regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
195 PPP_OP_BLEND_SRCPIXEL_ALPHA;
196 } else if (req->alpha < MDP_ALPHA_NOP) {
197 /* just blend by alpha */
198 regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
199 PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
200 PPP_OP_BLEND_CONSTANT_ALPHA;
201 }
202
203 regs->op |= bg_op_chroma[req->dst.format];
204}
205
206#define ONE_HALF (1LL << 32)
207#define ONE (1LL << 33)
208#define TWO (2LL << 33)
209#define THREE (3LL << 33)
210#define FRAC_MASK (ONE - 1)
211#define INT_MASK (~FRAC_MASK)
212
213static int scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t origin,
214 uint32_t *phase_init, uint32_t *phase_step)
215{
216 /* to improve precicsion calculations are done in U31.33 and converted
217 * to U3.29 at the end */
218 int64_t k1, k2, k3, k4, tmp;
219 uint64_t n, d, os, os_p, od, od_p, oreq;
220 unsigned rpa = 0;
221 int64_t ip64, delta;
222
223 if (dim_out % 3 == 0)
224 rpa = !(dim_in % (dim_out / 3));
225
226 n = ((uint64_t)dim_out) << 34;
227 d = dim_in;
228 if (!d)
229 return -1;
230 do_div(n, d);
231 k3 = (n + 1) >> 1;
232 if ((k3 >> 4) < (1LL << 27) || (k3 >> 4) > (1LL << 31)) {
233 DLOG("crap bad scale\n");
234 return -1;
235 }
236 n = ((uint64_t)dim_in) << 34;
237 d = (uint64_t)dim_out;
238 if (!d)
239 return -1;
240 do_div(n, d);
241 k1 = (n + 1) >> 1;
242 k2 = (k1 - ONE) >> 1;
243
244 *phase_init = (int)(k2 >> 4);
245 k4 = (k3 - ONE) >> 1;
246
247 if (rpa) {
248 os = ((uint64_t)origin << 33) - ONE_HALF;
249 tmp = (dim_out * os) + ONE_HALF;
250 if (!dim_in)
251 return -1;
252 do_div(tmp, dim_in);
253 od = tmp - ONE_HALF;
254 } else {
255 os = ((uint64_t)origin << 1) - 1;
256 od = (((k3 * os) >> 1) + k4);
257 }
258
259 od_p = od & INT_MASK;
260 if (od_p != od)
261 od_p += ONE;
262
263 if (rpa) {
264 tmp = (dim_in * od_p) + ONE_HALF;
265 if (!dim_in)
266 return -1;
267 do_div(tmp, dim_in);
268 os_p = tmp - ONE_HALF;
269 } else {
270 os_p = ((k1 * (od_p >> 33)) + k2);
271 }
272
273 oreq = (os_p & INT_MASK) - ONE;
274
275 ip64 = os_p - oreq;
276 delta = ((int64_t)(origin) << 33) - oreq;
277 ip64 -= delta;
278 /* limit to valid range before the left shift */
279 delta = (ip64 & (1LL << 63)) ? 4 : -4;
280 delta <<= 33;
281 while (abs((int)(ip64 >> 33)) > 4)
282 ip64 += delta;
283 *phase_init = (int)(ip64 >> 4);
284 *phase_step = (uint32_t)(k1 >> 4);
285 return 0;
286}
287
288static void load_scale_table(const struct mdp_info *mdp,
289 struct mdp_table_entry *table, int len)
290{
291 int i;
292 for (i = 0; i < len; i++)
293 mdp_writel(mdp, table[i].val, table[i].reg);
294}
295
296enum {
297IMG_LEFT,
298IMG_RIGHT,
299IMG_TOP,
300IMG_BOTTOM,
301};
302
303static void get_edge_info(uint32_t src, uint32_t src_coord, uint32_t dst,
304 uint32_t *interp1, uint32_t *interp2,
305 uint32_t *repeat1, uint32_t *repeat2) {
306 if (src > 3 * dst) {
307 *interp1 = 0;
308 *interp2 = src - 1;
309 *repeat1 = 0;
310 *repeat2 = 0;
311 } else if (src == 3 * dst) {
312 *interp1 = 0;
313 *interp2 = src;
314 *repeat1 = 0;
315 *repeat2 = 1;
316 } else if (src > dst && src < 3 * dst) {
317 *interp1 = -1;
318 *interp2 = src;
319 *repeat1 = 1;
320 *repeat2 = 1;
321 } else if (src == dst) {
322 *interp1 = -1;
323 *interp2 = src + 1;
324 *repeat1 = 1;
325 *repeat2 = 2;
326 } else {
327 *interp1 = -2;
328 *interp2 = src + 1;
329 *repeat1 = 2;
330 *repeat2 = 2;
331 }
332 *interp1 += src_coord;
333 *interp2 += src_coord;
334}
335
336static int get_edge_cond(struct mdp_blit_req *req, struct mdp_regs *regs)
337{
338 int32_t luma_interp[4];
339 int32_t luma_repeat[4];
340 int32_t chroma_interp[4];
341 int32_t chroma_bound[4];
342 int32_t chroma_repeat[4];
343 uint32_t dst_w, dst_h;
344
345 memset(&luma_interp, 0, sizeof(int32_t) * 4);
346 memset(&luma_repeat, 0, sizeof(int32_t) * 4);
347 memset(&chroma_interp, 0, sizeof(int32_t) * 4);
348 memset(&chroma_bound, 0, sizeof(int32_t) * 4);
349 memset(&chroma_repeat, 0, sizeof(int32_t) * 4);
350 regs->edge = 0;
351
352 if (req->flags & MDP_ROT_90) {
353 dst_w = req->dst_rect.h;
354 dst_h = req->dst_rect.w;
355 } else {
356 dst_w = req->dst_rect.w;
357 dst_h = req->dst_rect.h;
358 }
359
360 if (regs->op & (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON)) {
361 get_edge_info(req->src_rect.h, req->src_rect.y, dst_h,
362 &luma_interp[IMG_TOP], &luma_interp[IMG_BOTTOM],
363 &luma_repeat[IMG_TOP], &luma_repeat[IMG_BOTTOM]);
364 get_edge_info(req->src_rect.w, req->src_rect.x, dst_w,
365 &luma_interp[IMG_LEFT], &luma_interp[IMG_RIGHT],
366 &luma_repeat[IMG_LEFT], &luma_repeat[IMG_RIGHT]);
367 } else {
368 luma_interp[IMG_LEFT] = req->src_rect.x;
369 luma_interp[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
370 luma_interp[IMG_TOP] = req->src_rect.y;
371 luma_interp[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
372 luma_repeat[IMG_LEFT] = 0;
373 luma_repeat[IMG_TOP] = 0;
374 luma_repeat[IMG_RIGHT] = 0;
375 luma_repeat[IMG_BOTTOM] = 0;
376 }
377
378 chroma_interp[IMG_LEFT] = luma_interp[IMG_LEFT];
379 chroma_interp[IMG_RIGHT] = luma_interp[IMG_RIGHT];
380 chroma_interp[IMG_TOP] = luma_interp[IMG_TOP];
381 chroma_interp[IMG_BOTTOM] = luma_interp[IMG_BOTTOM];
382
383 chroma_bound[IMG_LEFT] = req->src_rect.x;
384 chroma_bound[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
385 chroma_bound[IMG_TOP] = req->src_rect.y;
386 chroma_bound[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
387
388 if (IS_YCRCB(req->src.format)) {
389 chroma_interp[IMG_LEFT] = chroma_interp[IMG_LEFT] >> 1;
390 chroma_interp[IMG_RIGHT] = (chroma_interp[IMG_RIGHT] + 1) >> 1;
391
392 chroma_bound[IMG_LEFT] = chroma_bound[IMG_LEFT] >> 1;
393 chroma_bound[IMG_RIGHT] = chroma_bound[IMG_RIGHT] >> 1;
394 }
395
396 if (req->src.format == MDP_Y_CBCR_H2V2 ||
397 req->src.format == MDP_Y_CRCB_H2V2) {
398 chroma_interp[IMG_TOP] = (chroma_interp[IMG_TOP] - 1) >> 1;
399 chroma_interp[IMG_BOTTOM] = (chroma_interp[IMG_BOTTOM] + 1)
400 >> 1;
401 chroma_bound[IMG_TOP] = (chroma_bound[IMG_TOP] + 1) >> 1;
402 chroma_bound[IMG_BOTTOM] = chroma_bound[IMG_BOTTOM] >> 1;
403 }
404
405 chroma_repeat[IMG_LEFT] = chroma_bound[IMG_LEFT] -
406 chroma_interp[IMG_LEFT];
407 chroma_repeat[IMG_RIGHT] = chroma_interp[IMG_RIGHT] -
408 chroma_bound[IMG_RIGHT];
409 chroma_repeat[IMG_TOP] = chroma_bound[IMG_TOP] -
410 chroma_interp[IMG_TOP];
411 chroma_repeat[IMG_BOTTOM] = chroma_interp[IMG_BOTTOM] -
412 chroma_bound[IMG_BOTTOM];
413
414 if (chroma_repeat[IMG_LEFT] < 0 || chroma_repeat[IMG_LEFT] > 3 ||
415 chroma_repeat[IMG_RIGHT] < 0 || chroma_repeat[IMG_RIGHT] > 3 ||
416 chroma_repeat[IMG_TOP] < 0 || chroma_repeat[IMG_TOP] > 3 ||
417 chroma_repeat[IMG_BOTTOM] < 0 || chroma_repeat[IMG_BOTTOM] > 3 ||
418 luma_repeat[IMG_LEFT] < 0 || luma_repeat[IMG_LEFT] > 3 ||
419 luma_repeat[IMG_RIGHT] < 0 || luma_repeat[IMG_RIGHT] > 3 ||
420 luma_repeat[IMG_TOP] < 0 || luma_repeat[IMG_TOP] > 3 ||
421 luma_repeat[IMG_BOTTOM] < 0 || luma_repeat[IMG_BOTTOM] > 3)
422 return -1;
423
424 regs->edge |= (chroma_repeat[IMG_LEFT] & 3) << MDP_LEFT_CHROMA;
425 regs->edge |= (chroma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_CHROMA;
426 regs->edge |= (chroma_repeat[IMG_TOP] & 3) << MDP_TOP_CHROMA;
427 regs->edge |= (chroma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_CHROMA;
428 regs->edge |= (luma_repeat[IMG_LEFT] & 3) << MDP_LEFT_LUMA;
429 regs->edge |= (luma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_LUMA;
430 regs->edge |= (luma_repeat[IMG_TOP] & 3) << MDP_TOP_LUMA;
431 regs->edge |= (luma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_LUMA;
432 return 0;
433}
434
435static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req,
436 struct mdp_regs *regs)
437{
438 uint32_t phase_init_x, phase_init_y, phase_step_x, phase_step_y;
439 uint32_t scale_factor_x, scale_factor_y;
440 uint32_t downscale;
441 uint32_t dst_w, dst_h;
442
443 if (req->flags & MDP_ROT_90) {
444 dst_w = req->dst_rect.h;
445 dst_h = req->dst_rect.w;
446 } else {
447 dst_w = req->dst_rect.w;
448 dst_h = req->dst_rect.h;
449 }
450 if ((req->src_rect.w == dst_w) && (req->src_rect.h == dst_h) &&
451 !(req->flags & MDP_BLUR)) {
452 regs->phasex_init = 0;
453 regs->phasey_init = 0;
454 regs->phasex_step = 0;
455 regs->phasey_step = 0;
456 return 0;
457 }
458
459 if (scale_params(req->src_rect.w, dst_w, 1, &phase_init_x,
460 &phase_step_x) ||
461 scale_params(req->src_rect.h, dst_h, 1, &phase_init_y,
462 &phase_step_y))
463 return -1;
464
465 scale_factor_x = (dst_w * 10) / req->src_rect.w;
466 scale_factor_y = (dst_h * 10) / req->src_rect.h;
467
468 if (scale_factor_x > 8)
469 downscale = MDP_DOWNSCALE_PT8TO1;
470 else if (scale_factor_x > 6)
471 downscale = MDP_DOWNSCALE_PT6TOPT8;
472 else if (scale_factor_x > 4)
473 downscale = MDP_DOWNSCALE_PT4TOPT6;
474 else
475 downscale = MDP_DOWNSCALE_PT2TOPT4;
476 if (downscale != downscale_x_table) {
477 load_scale_table(mdp, mdp_downscale_x_table[downscale], 64);
478 downscale_x_table = downscale;
479 }
480
481 if (scale_factor_y > 8)
482 downscale = MDP_DOWNSCALE_PT8TO1;
483 else if (scale_factor_y > 6)
484 downscale = MDP_DOWNSCALE_PT6TOPT8;
485 else if (scale_factor_y > 4)
486 downscale = MDP_DOWNSCALE_PT4TOPT6;
487 else
488 downscale = MDP_DOWNSCALE_PT2TOPT4;
489 if (downscale != downscale_y_table) {
490 load_scale_table(mdp, mdp_downscale_y_table[downscale], 64);
491 downscale_y_table = downscale;
492 }
493
494 regs->phasex_init = phase_init_x;
495 regs->phasey_init = phase_init_y;
496 regs->phasex_step = phase_step_x;
497 regs->phasey_step = phase_step_y;
498 regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
499 return 0;
500
501}
502
503static void blit_blur(const struct mdp_info *mdp, struct mdp_blit_req *req,
504 struct mdp_regs *regs)
505{
506 if (!(req->flags & MDP_BLUR))
507 return;
508
509 if (!(downscale_x_table == MDP_DOWNSCALE_BLUR &&
510 downscale_y_table == MDP_DOWNSCALE_BLUR)) {
511 load_scale_table(mdp, mdp_gaussian_blur_table, 128);
512 downscale_x_table = MDP_DOWNSCALE_BLUR;
513 downscale_y_table = MDP_DOWNSCALE_BLUR;
514 }
515
516 regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
517}
518
519
520#define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
521
522#define Y_TO_CRCB_RATIO(format) \
523 ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\
524 (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1)
525
526static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp,
527 uint32_t *len0, uint32_t *len1)
528{
529 *len0 = IMG_LEN(rect->h, img->width, rect->w, bpp);
530 if (IS_PSEUDOPLNR(img->format))
531 *len1 = *len0/Y_TO_CRCB_RATIO(img->format);
532 else
533 *len1 = 0;
534}
535
536static int valid_src_dst(unsigned long src_start, unsigned long src_len,
537 unsigned long dst_start, unsigned long dst_len,
538 struct mdp_blit_req *req, struct mdp_regs *regs)
539{
540 unsigned long src_min_ok = src_start;
541 unsigned long src_max_ok = src_start + src_len;
542 unsigned long dst_min_ok = dst_start;
543 unsigned long dst_max_ok = dst_start + dst_len;
544 uint32_t src0_len, src1_len, dst0_len, dst1_len;
545 get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len,
546 &src1_len);
547 get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len,
548 &dst1_len);
549
550 if (regs->src0 < src_min_ok || regs->src0 > src_max_ok ||
551 regs->src0 + src0_len > src_max_ok) {
552 DLOG("invalid_src %x %x %lx %lx\n", regs->src0,
553 src0_len, src_min_ok, src_max_ok);
554 return 0;
555 }
556 if (regs->src_cfg & PPP_SRC_PLANE_PSEUDOPLNR) {
557 if (regs->src1 < src_min_ok || regs->src1 > src_max_ok ||
558 regs->src1 + src1_len > src_max_ok) {
559 DLOG("invalid_src1");
560 return 0;
561 }
562 }
563 if (regs->dst0 < dst_min_ok || regs->dst0 > dst_max_ok ||
564 regs->dst0 + dst0_len > dst_max_ok) {
565 DLOG("invalid_dst");
566 return 0;
567 }
568 if (regs->dst_cfg & PPP_SRC_PLANE_PSEUDOPLNR) {
569 if (regs->dst1 < dst_min_ok || regs->dst1 > dst_max_ok ||
570 regs->dst1 + dst1_len > dst_max_ok) {
571 DLOG("invalid_dst1");
572 return 0;
573 }
574 }
575 return 1;
576}
577
578
579static void flush_imgs(struct mdp_blit_req *req, struct mdp_regs *regs,
580 struct file *src_file, struct file *dst_file)
581{
582#ifdef CONFIG_ANDROID_PMEM
583 uint32_t src0_len, src1_len, dst0_len, dst1_len;
584
585 /* flush src images to memory before dma to mdp */
586 get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len,
587 &src1_len);
588 flush_pmem_file(src_file, req->src.offset, src0_len);
589 if (IS_PSEUDOPLNR(req->src.format))
590 flush_pmem_file(src_file, req->src.offset + src0_len,
591 src1_len);
592
593 /* flush dst images */
594 get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len,
595 &dst1_len);
596 flush_pmem_file(dst_file, req->dst.offset, dst0_len);
597 if (IS_PSEUDOPLNR(req->dst.format))
598 flush_pmem_file(dst_file, req->dst.offset + dst0_len,
599 dst1_len);
600#endif
601}
602
603static void get_chroma_addr(struct mdp_img *img, struct mdp_rect *rect,
604 uint32_t base, uint32_t bpp, uint32_t cfg,
605 uint32_t *addr, uint32_t *ystride)
606{
607 uint32_t compress_v = Y_TO_CRCB_RATIO(img->format);
608 uint32_t compress_h = 2;
609 uint32_t offset;
610
611 if (IS_PSEUDOPLNR(img->format)) {
612 offset = (rect->x / compress_h) * compress_h;
613 offset += rect->y == 0 ? 0 :
614 ((rect->y + 1) / compress_v) * img->width;
615 *addr = base + (img->width * img->height * bpp);
616 *addr += offset * bpp;
617 *ystride |= *ystride << 16;
618 } else {
619 *addr = 0;
620 }
621}
622
623static int send_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
624 struct mdp_regs *regs, struct file *src_file,
625 struct file *dst_file)
626{
627 mdp_writel(mdp, 1, 0x060);
628 mdp_writel(mdp, regs->src_rect, PPP_ADDR_SRC_ROI);
629 mdp_writel(mdp, regs->src0, PPP_ADDR_SRC0);
630 mdp_writel(mdp, regs->src1, PPP_ADDR_SRC1);
631 mdp_writel(mdp, regs->src_ystride, PPP_ADDR_SRC_YSTRIDE);
632 mdp_writel(mdp, regs->src_cfg, PPP_ADDR_SRC_CFG);
633 mdp_writel(mdp, regs->src_pack, PPP_ADDR_SRC_PACK_PATTERN);
634
635 mdp_writel(mdp, regs->op, PPP_ADDR_OPERATION);
636 mdp_writel(mdp, regs->phasex_init, PPP_ADDR_PHASEX_INIT);
637 mdp_writel(mdp, regs->phasey_init, PPP_ADDR_PHASEY_INIT);
638 mdp_writel(mdp, regs->phasex_step, PPP_ADDR_PHASEX_STEP);
639 mdp_writel(mdp, regs->phasey_step, PPP_ADDR_PHASEY_STEP);
640
641 mdp_writel(mdp, (req->alpha << 24) | (req->transp_mask & 0xffffff),
642 PPP_ADDR_ALPHA_TRANSP);
643
644 mdp_writel(mdp, regs->dst_cfg, PPP_ADDR_DST_CFG);
645 mdp_writel(mdp, regs->dst_pack, PPP_ADDR_DST_PACK_PATTERN);
646 mdp_writel(mdp, regs->dst_rect, PPP_ADDR_DST_ROI);
647 mdp_writel(mdp, regs->dst0, PPP_ADDR_DST0);
648 mdp_writel(mdp, regs->dst1, PPP_ADDR_DST1);
649 mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_DST_YSTRIDE);
650
651 mdp_writel(mdp, regs->edge, PPP_ADDR_EDGE);
652 if (regs->op & PPP_OP_BLEND_ON) {
653 mdp_writel(mdp, regs->dst0, PPP_ADDR_BG0);
654 mdp_writel(mdp, regs->dst1, PPP_ADDR_BG1);
655 mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_BG_YSTRIDE);
656 mdp_writel(mdp, src_img_cfg[req->dst.format], PPP_ADDR_BG_CFG);
657 mdp_writel(mdp, pack_pattern[req->dst.format],
658 PPP_ADDR_BG_PACK_PATTERN);
659 }
660 flush_imgs(req, regs, src_file, dst_file);
661 mdp_writel(mdp, 0x1000, MDP_DISPLAY0_START);
662 return 0;
663}
664
665int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
666 struct file *src_file, unsigned long src_start, unsigned long src_len,
667 struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
668{
669 struct mdp_regs regs = {0};
670
671 if (unlikely(req->src.format >= MDP_IMGTYPE_LIMIT ||
672 req->dst.format >= MDP_IMGTYPE_LIMIT)) {
673 printk(KERN_ERR "mpd_ppp: img is of wrong format\n");
674 return -EINVAL;
675 }
676
677 if (unlikely(req->src_rect.x > req->src.width ||
678 req->src_rect.y > req->src.height ||
679 req->dst_rect.x > req->dst.width ||
680 req->dst_rect.y > req->dst.height)) {
681 printk(KERN_ERR "mpd_ppp: img rect is outside of img!\n");
682 return -EINVAL;
683 }
684
685 /* set the src image configuration */
686 regs.src_cfg = src_img_cfg[req->src.format];
687 regs.src_cfg |= (req->src_rect.x & 0x1) ? PPP_SRC_BPP_ROI_ODD_X : 0;
688 regs.src_cfg |= (req->src_rect.y & 0x1) ? PPP_SRC_BPP_ROI_ODD_Y : 0;
689 regs.src_rect = (req->src_rect.h << 16) | req->src_rect.w;
690 regs.src_pack = pack_pattern[req->src.format];
691
692 /* set the dest image configuration */
693 regs.dst_cfg = dst_img_cfg[req->dst.format] | PPP_DST_OUT_SEL_AXI;
694 regs.dst_rect = (req->dst_rect.h << 16) | req->dst_rect.w;
695 regs.dst_pack = pack_pattern[req->dst.format];
696
697 /* set src, bpp, start pixel and ystride */
698 regs.src_bpp = bytes_per_pixel[req->src.format];
699 regs.src0 = src_start + req->src.offset;
700 regs.src_ystride = req->src.width * regs.src_bpp;
701 get_chroma_addr(&req->src, &req->src_rect, regs.src0, regs.src_bpp,
702 regs.src_cfg, &regs.src1, &regs.src_ystride);
703 regs.src0 += (req->src_rect.x + (req->src_rect.y * req->src.width)) *
704 regs.src_bpp;
705
706 /* set dst, bpp, start pixel and ystride */
707 regs.dst_bpp = bytes_per_pixel[req->dst.format];
708 regs.dst0 = dst_start + req->dst.offset;
709 regs.dst_ystride = req->dst.width * regs.dst_bpp;
710 get_chroma_addr(&req->dst, &req->dst_rect, regs.dst0, regs.dst_bpp,
711 regs.dst_cfg, &regs.dst1, &regs.dst_ystride);
712 regs.dst0 += (req->dst_rect.x + (req->dst_rect.y * req->dst.width)) *
713 regs.dst_bpp;
714
715 if (!valid_src_dst(src_start, src_len, dst_start, dst_len, req,
716 &regs)) {
717 printk(KERN_ERR "mpd_ppp: final src or dst location is "
718 "invalid, are you trying to make an image too large "
719 "or to place it outside the screen?\n");
720 return -EINVAL;
721 }
722
723 /* set up operation register */
724 regs.op = 0;
725 blit_rotate(req, &regs);
726 blit_convert(req, &regs);
727 if (req->flags & MDP_DITHER)
728 regs.op |= PPP_OP_DITHER_EN;
729 blit_blend(req, &regs);
730 if (blit_scale(mdp, req, &regs)) {
731 printk(KERN_ERR "mpd_ppp: error computing scale for img.\n");
732 return -EINVAL;
733 }
734 blit_blur(mdp, req, &regs);
735 regs.op |= dst_op_chroma[req->dst.format] |
736 src_op_chroma[req->src.format];
737
738 /* if the image is YCRYCB, the x and w must be even */
739 if (unlikely(req->src.format == MDP_YCRYCB_H2V1)) {
740 req->src_rect.x = req->src_rect.x & (~0x1);
741 req->src_rect.w = req->src_rect.w & (~0x1);
742 req->dst_rect.x = req->dst_rect.x & (~0x1);
743 req->dst_rect.w = req->dst_rect.w & (~0x1);
744 }
745 if (get_edge_cond(req, &regs))
746 return -EINVAL;
747
748 send_blit(mdp, req, &regs, src_file, dst_file);
749 return 0;
750}
diff --git a/drivers/video/msm/mdp_scale_tables.c b/drivers/video/msm/mdp_scale_tables.c
new file mode 100644
index 000000000000..604783b2e17c
--- /dev/null
+++ b/drivers/video/msm/mdp_scale_tables.c
@@ -0,0 +1,766 @@
1/* drivers/video/msm_fb/mdp_scale_tables.c
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include "mdp_scale_tables.h"
17#include "mdp_hw.h"
18
19struct mdp_table_entry mdp_upscale_table[] = {
20 { 0x5fffc, 0x0 },
21 { 0x50200, 0x7fc00000 },
22 { 0x5fffc, 0xff80000d },
23 { 0x50204, 0x7ec003f9 },
24 { 0x5fffc, 0xfec0001c },
25 { 0x50208, 0x7d4003f3 },
26 { 0x5fffc, 0xfe40002b },
27 { 0x5020c, 0x7b8003ed },
28 { 0x5fffc, 0xfd80003c },
29 { 0x50210, 0x794003e8 },
30 { 0x5fffc, 0xfcc0004d },
31 { 0x50214, 0x76c003e4 },
32 { 0x5fffc, 0xfc40005f },
33 { 0x50218, 0x73c003e0 },
34 { 0x5fffc, 0xfb800071 },
35 { 0x5021c, 0x708003de },
36 { 0x5fffc, 0xfac00085 },
37 { 0x50220, 0x6d0003db },
38 { 0x5fffc, 0xfa000098 },
39 { 0x50224, 0x698003d9 },
40 { 0x5fffc, 0xf98000ac },
41 { 0x50228, 0x654003d8 },
42 { 0x5fffc, 0xf8c000c1 },
43 { 0x5022c, 0x610003d7 },
44 { 0x5fffc, 0xf84000d5 },
45 { 0x50230, 0x5c8003d7 },
46 { 0x5fffc, 0xf7c000e9 },
47 { 0x50234, 0x580003d7 },
48 { 0x5fffc, 0xf74000fd },
49 { 0x50238, 0x534003d8 },
50 { 0x5fffc, 0xf6c00112 },
51 { 0x5023c, 0x4e8003d8 },
52 { 0x5fffc, 0xf6800126 },
53 { 0x50240, 0x494003da },
54 { 0x5fffc, 0xf600013a },
55 { 0x50244, 0x448003db },
56 { 0x5fffc, 0xf600014d },
57 { 0x50248, 0x3f4003dd },
58 { 0x5fffc, 0xf5c00160 },
59 { 0x5024c, 0x3a4003df },
60 { 0x5fffc, 0xf5c00172 },
61 { 0x50250, 0x354003e1 },
62 { 0x5fffc, 0xf5c00184 },
63 { 0x50254, 0x304003e3 },
64 { 0x5fffc, 0xf6000195 },
65 { 0x50258, 0x2b0003e6 },
66 { 0x5fffc, 0xf64001a6 },
67 { 0x5025c, 0x260003e8 },
68 { 0x5fffc, 0xf6c001b4 },
69 { 0x50260, 0x214003eb },
70 { 0x5fffc, 0xf78001c2 },
71 { 0x50264, 0x1c4003ee },
72 { 0x5fffc, 0xf80001cf },
73 { 0x50268, 0x17c003f1 },
74 { 0x5fffc, 0xf90001db },
75 { 0x5026c, 0x134003f3 },
76 { 0x5fffc, 0xfa0001e5 },
77 { 0x50270, 0xf0003f6 },
78 { 0x5fffc, 0xfb4001ee },
79 { 0x50274, 0xac003f9 },
80 { 0x5fffc, 0xfcc001f5 },
81 { 0x50278, 0x70003fb },
82 { 0x5fffc, 0xfe4001fb },
83 { 0x5027c, 0x34003fe },
84};
85
86static struct mdp_table_entry mdp_downscale_x_table_PT2TOPT4[] = {
87 { 0x5fffc, 0x740008c },
88 { 0x50280, 0x33800088 },
89 { 0x5fffc, 0x800008e },
90 { 0x50284, 0x33400084 },
91 { 0x5fffc, 0x8400092 },
92 { 0x50288, 0x33000080 },
93 { 0x5fffc, 0x9000094 },
94 { 0x5028c, 0x3300007b },
95 { 0x5fffc, 0x9c00098 },
96 { 0x50290, 0x32400077 },
97 { 0x5fffc, 0xa40009b },
98 { 0x50294, 0x32000073 },
99 { 0x5fffc, 0xb00009d },
100 { 0x50298, 0x31c0006f },
101 { 0x5fffc, 0xbc000a0 },
102 { 0x5029c, 0x3140006b },
103 { 0x5fffc, 0xc8000a2 },
104 { 0x502a0, 0x31000067 },
105 { 0x5fffc, 0xd8000a5 },
106 { 0x502a4, 0x30800062 },
107 { 0x5fffc, 0xe4000a8 },
108 { 0x502a8, 0x2fc0005f },
109 { 0x5fffc, 0xec000aa },
110 { 0x502ac, 0x2fc0005b },
111 { 0x5fffc, 0xf8000ad },
112 { 0x502b0, 0x2f400057 },
113 { 0x5fffc, 0x108000b0 },
114 { 0x502b4, 0x2e400054 },
115 { 0x5fffc, 0x114000b2 },
116 { 0x502b8, 0x2e000050 },
117 { 0x5fffc, 0x124000b4 },
118 { 0x502bc, 0x2d80004c },
119 { 0x5fffc, 0x130000b6 },
120 { 0x502c0, 0x2d000049 },
121 { 0x5fffc, 0x140000b8 },
122 { 0x502c4, 0x2c800045 },
123 { 0x5fffc, 0x150000b9 },
124 { 0x502c8, 0x2c000042 },
125 { 0x5fffc, 0x15c000bd },
126 { 0x502cc, 0x2b40003e },
127 { 0x5fffc, 0x16c000bf },
128 { 0x502d0, 0x2a80003b },
129 { 0x5fffc, 0x17c000bf },
130 { 0x502d4, 0x2a000039 },
131 { 0x5fffc, 0x188000c2 },
132 { 0x502d8, 0x29400036 },
133 { 0x5fffc, 0x19c000c4 },
134 { 0x502dc, 0x28800032 },
135 { 0x5fffc, 0x1ac000c5 },
136 { 0x502e0, 0x2800002f },
137 { 0x5fffc, 0x1bc000c7 },
138 { 0x502e4, 0x2740002c },
139 { 0x5fffc, 0x1cc000c8 },
140 { 0x502e8, 0x26c00029 },
141 { 0x5fffc, 0x1dc000c9 },
142 { 0x502ec, 0x26000027 },
143 { 0x5fffc, 0x1ec000cc },
144 { 0x502f0, 0x25000024 },
145 { 0x5fffc, 0x200000cc },
146 { 0x502f4, 0x24800021 },
147 { 0x5fffc, 0x210000cd },
148 { 0x502f8, 0x23800020 },
149 { 0x5fffc, 0x220000ce },
150 { 0x502fc, 0x2300001d },
151};
152
153static struct mdp_table_entry mdp_downscale_x_table_PT4TOPT6[] = {
154 { 0x5fffc, 0x740008c },
155 { 0x50280, 0x33800088 },
156 { 0x5fffc, 0x800008e },
157 { 0x50284, 0x33400084 },
158 { 0x5fffc, 0x8400092 },
159 { 0x50288, 0x33000080 },
160 { 0x5fffc, 0x9000094 },
161 { 0x5028c, 0x3300007b },
162 { 0x5fffc, 0x9c00098 },
163 { 0x50290, 0x32400077 },
164 { 0x5fffc, 0xa40009b },
165 { 0x50294, 0x32000073 },
166 { 0x5fffc, 0xb00009d },
167 { 0x50298, 0x31c0006f },
168 { 0x5fffc, 0xbc000a0 },
169 { 0x5029c, 0x3140006b },
170 { 0x5fffc, 0xc8000a2 },
171 { 0x502a0, 0x31000067 },
172 { 0x5fffc, 0xd8000a5 },
173 { 0x502a4, 0x30800062 },
174 { 0x5fffc, 0xe4000a8 },
175 { 0x502a8, 0x2fc0005f },
176 { 0x5fffc, 0xec000aa },
177 { 0x502ac, 0x2fc0005b },
178 { 0x5fffc, 0xf8000ad },
179 { 0x502b0, 0x2f400057 },
180 { 0x5fffc, 0x108000b0 },
181 { 0x502b4, 0x2e400054 },
182 { 0x5fffc, 0x114000b2 },
183 { 0x502b8, 0x2e000050 },
184 { 0x5fffc, 0x124000b4 },
185 { 0x502bc, 0x2d80004c },
186 { 0x5fffc, 0x130000b6 },
187 { 0x502c0, 0x2d000049 },
188 { 0x5fffc, 0x140000b8 },
189 { 0x502c4, 0x2c800045 },
190 { 0x5fffc, 0x150000b9 },
191 { 0x502c8, 0x2c000042 },
192 { 0x5fffc, 0x15c000bd },
193 { 0x502cc, 0x2b40003e },
194 { 0x5fffc, 0x16c000bf },
195 { 0x502d0, 0x2a80003b },
196 { 0x5fffc, 0x17c000bf },
197 { 0x502d4, 0x2a000039 },
198 { 0x5fffc, 0x188000c2 },
199 { 0x502d8, 0x29400036 },
200 { 0x5fffc, 0x19c000c4 },
201 { 0x502dc, 0x28800032 },
202 { 0x5fffc, 0x1ac000c5 },
203 { 0x502e0, 0x2800002f },
204 { 0x5fffc, 0x1bc000c7 },
205 { 0x502e4, 0x2740002c },
206 { 0x5fffc, 0x1cc000c8 },
207 { 0x502e8, 0x26c00029 },
208 { 0x5fffc, 0x1dc000c9 },
209 { 0x502ec, 0x26000027 },
210 { 0x5fffc, 0x1ec000cc },
211 { 0x502f0, 0x25000024 },
212 { 0x5fffc, 0x200000cc },
213 { 0x502f4, 0x24800021 },
214 { 0x5fffc, 0x210000cd },
215 { 0x502f8, 0x23800020 },
216 { 0x5fffc, 0x220000ce },
217 { 0x502fc, 0x2300001d },
218};
219
220static struct mdp_table_entry mdp_downscale_x_table_PT6TOPT8[] = {
221 { 0x5fffc, 0xfe000070 },
222 { 0x50280, 0x4bc00068 },
223 { 0x5fffc, 0xfe000078 },
224 { 0x50284, 0x4bc00060 },
225 { 0x5fffc, 0xfe000080 },
226 { 0x50288, 0x4b800059 },
227 { 0x5fffc, 0xfe000089 },
228 { 0x5028c, 0x4b000052 },
229 { 0x5fffc, 0xfe400091 },
230 { 0x50290, 0x4a80004b },
231 { 0x5fffc, 0xfe40009a },
232 { 0x50294, 0x4a000044 },
233 { 0x5fffc, 0xfe8000a3 },
234 { 0x50298, 0x4940003d },
235 { 0x5fffc, 0xfec000ac },
236 { 0x5029c, 0x48400037 },
237 { 0x5fffc, 0xff0000b4 },
238 { 0x502a0, 0x47800031 },
239 { 0x5fffc, 0xff8000bd },
240 { 0x502a4, 0x4640002b },
241 { 0x5fffc, 0xc5 },
242 { 0x502a8, 0x45000026 },
243 { 0x5fffc, 0x8000ce },
244 { 0x502ac, 0x43800021 },
245 { 0x5fffc, 0x10000d6 },
246 { 0x502b0, 0x4240001c },
247 { 0x5fffc, 0x18000df },
248 { 0x502b4, 0x40800018 },
249 { 0x5fffc, 0x24000e6 },
250 { 0x502b8, 0x3f000014 },
251 { 0x5fffc, 0x30000ee },
252 { 0x502bc, 0x3d400010 },
253 { 0x5fffc, 0x40000f5 },
254 { 0x502c0, 0x3b80000c },
255 { 0x5fffc, 0x50000fc },
256 { 0x502c4, 0x39800009 },
257 { 0x5fffc, 0x6000102 },
258 { 0x502c8, 0x37c00006 },
259 { 0x5fffc, 0x7000109 },
260 { 0x502cc, 0x35800004 },
261 { 0x5fffc, 0x840010e },
262 { 0x502d0, 0x33800002 },
263 { 0x5fffc, 0x9800114 },
264 { 0x502d4, 0x31400000 },
265 { 0x5fffc, 0xac00119 },
266 { 0x502d8, 0x2f4003fe },
267 { 0x5fffc, 0xc40011e },
268 { 0x502dc, 0x2d0003fc },
269 { 0x5fffc, 0xdc00121 },
270 { 0x502e0, 0x2b0003fb },
271 { 0x5fffc, 0xf400125 },
272 { 0x502e4, 0x28c003fa },
273 { 0x5fffc, 0x11000128 },
274 { 0x502e8, 0x268003f9 },
275 { 0x5fffc, 0x12c0012a },
276 { 0x502ec, 0x244003f9 },
277 { 0x5fffc, 0x1480012c },
278 { 0x502f0, 0x224003f8 },
279 { 0x5fffc, 0x1640012e },
280 { 0x502f4, 0x200003f8 },
281 { 0x5fffc, 0x1800012f },
282 { 0x502f8, 0x1e0003f8 },
283 { 0x5fffc, 0x1a00012f },
284 { 0x502fc, 0x1c0003f8 },
285};
286
287static struct mdp_table_entry mdp_downscale_x_table_PT8TO1[] = {
288 { 0x5fffc, 0x0 },
289 { 0x50280, 0x7fc00000 },
290 { 0x5fffc, 0xff80000d },
291 { 0x50284, 0x7ec003f9 },
292 { 0x5fffc, 0xfec0001c },
293 { 0x50288, 0x7d4003f3 },
294 { 0x5fffc, 0xfe40002b },
295 { 0x5028c, 0x7b8003ed },
296 { 0x5fffc, 0xfd80003c },
297 { 0x50290, 0x794003e8 },
298 { 0x5fffc, 0xfcc0004d },
299 { 0x50294, 0x76c003e4 },
300 { 0x5fffc, 0xfc40005f },
301 { 0x50298, 0x73c003e0 },
302 { 0x5fffc, 0xfb800071 },
303 { 0x5029c, 0x708003de },
304 { 0x5fffc, 0xfac00085 },
305 { 0x502a0, 0x6d0003db },
306 { 0x5fffc, 0xfa000098 },
307 { 0x502a4, 0x698003d9 },
308 { 0x5fffc, 0xf98000ac },
309 { 0x502a8, 0x654003d8 },
310 { 0x5fffc, 0xf8c000c1 },
311 { 0x502ac, 0x610003d7 },
312 { 0x5fffc, 0xf84000d5 },
313 { 0x502b0, 0x5c8003d7 },
314 { 0x5fffc, 0xf7c000e9 },
315 { 0x502b4, 0x580003d7 },
316 { 0x5fffc, 0xf74000fd },
317 { 0x502b8, 0x534003d8 },
318 { 0x5fffc, 0xf6c00112 },
319 { 0x502bc, 0x4e8003d8 },
320 { 0x5fffc, 0xf6800126 },
321 { 0x502c0, 0x494003da },
322 { 0x5fffc, 0xf600013a },
323 { 0x502c4, 0x448003db },
324 { 0x5fffc, 0xf600014d },
325 { 0x502c8, 0x3f4003dd },
326 { 0x5fffc, 0xf5c00160 },
327 { 0x502cc, 0x3a4003df },
328 { 0x5fffc, 0xf5c00172 },
329 { 0x502d0, 0x354003e1 },
330 { 0x5fffc, 0xf5c00184 },
331 { 0x502d4, 0x304003e3 },
332 { 0x5fffc, 0xf6000195 },
333 { 0x502d8, 0x2b0003e6 },
334 { 0x5fffc, 0xf64001a6 },
335 { 0x502dc, 0x260003e8 },
336 { 0x5fffc, 0xf6c001b4 },
337 { 0x502e0, 0x214003eb },
338 { 0x5fffc, 0xf78001c2 },
339 { 0x502e4, 0x1c4003ee },
340 { 0x5fffc, 0xf80001cf },
341 { 0x502e8, 0x17c003f1 },
342 { 0x5fffc, 0xf90001db },
343 { 0x502ec, 0x134003f3 },
344 { 0x5fffc, 0xfa0001e5 },
345 { 0x502f0, 0xf0003f6 },
346 { 0x5fffc, 0xfb4001ee },
347 { 0x502f4, 0xac003f9 },
348 { 0x5fffc, 0xfcc001f5 },
349 { 0x502f8, 0x70003fb },
350 { 0x5fffc, 0xfe4001fb },
351 { 0x502fc, 0x34003fe },
352};
353
354struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX] = {
355 [MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_x_table_PT2TOPT4,
356 [MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_x_table_PT4TOPT6,
357 [MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_x_table_PT6TOPT8,
358 [MDP_DOWNSCALE_PT8TO1] = mdp_downscale_x_table_PT8TO1,
359};
360
361static struct mdp_table_entry mdp_downscale_y_table_PT2TOPT4[] = {
362 { 0x5fffc, 0x740008c },
363 { 0x50300, 0x33800088 },
364 { 0x5fffc, 0x800008e },
365 { 0x50304, 0x33400084 },
366 { 0x5fffc, 0x8400092 },
367 { 0x50308, 0x33000080 },
368 { 0x5fffc, 0x9000094 },
369 { 0x5030c, 0x3300007b },
370 { 0x5fffc, 0x9c00098 },
371 { 0x50310, 0x32400077 },
372 { 0x5fffc, 0xa40009b },
373 { 0x50314, 0x32000073 },
374 { 0x5fffc, 0xb00009d },
375 { 0x50318, 0x31c0006f },
376 { 0x5fffc, 0xbc000a0 },
377 { 0x5031c, 0x3140006b },
378 { 0x5fffc, 0xc8000a2 },
379 { 0x50320, 0x31000067 },
380 { 0x5fffc, 0xd8000a5 },
381 { 0x50324, 0x30800062 },
382 { 0x5fffc, 0xe4000a8 },
383 { 0x50328, 0x2fc0005f },
384 { 0x5fffc, 0xec000aa },
385 { 0x5032c, 0x2fc0005b },
386 { 0x5fffc, 0xf8000ad },
387 { 0x50330, 0x2f400057 },
388 { 0x5fffc, 0x108000b0 },
389 { 0x50334, 0x2e400054 },
390 { 0x5fffc, 0x114000b2 },
391 { 0x50338, 0x2e000050 },
392 { 0x5fffc, 0x124000b4 },
393 { 0x5033c, 0x2d80004c },
394 { 0x5fffc, 0x130000b6 },
395 { 0x50340, 0x2d000049 },
396 { 0x5fffc, 0x140000b8 },
397 { 0x50344, 0x2c800045 },
398 { 0x5fffc, 0x150000b9 },
399 { 0x50348, 0x2c000042 },
400 { 0x5fffc, 0x15c000bd },
401 { 0x5034c, 0x2b40003e },
402 { 0x5fffc, 0x16c000bf },
403 { 0x50350, 0x2a80003b },
404 { 0x5fffc, 0x17c000bf },
405 { 0x50354, 0x2a000039 },
406 { 0x5fffc, 0x188000c2 },
407 { 0x50358, 0x29400036 },
408 { 0x5fffc, 0x19c000c4 },
409 { 0x5035c, 0x28800032 },
410 { 0x5fffc, 0x1ac000c5 },
411 { 0x50360, 0x2800002f },
412 { 0x5fffc, 0x1bc000c7 },
413 { 0x50364, 0x2740002c },
414 { 0x5fffc, 0x1cc000c8 },
415 { 0x50368, 0x26c00029 },
416 { 0x5fffc, 0x1dc000c9 },
417 { 0x5036c, 0x26000027 },
418 { 0x5fffc, 0x1ec000cc },
419 { 0x50370, 0x25000024 },
420 { 0x5fffc, 0x200000cc },
421 { 0x50374, 0x24800021 },
422 { 0x5fffc, 0x210000cd },
423 { 0x50378, 0x23800020 },
424 { 0x5fffc, 0x220000ce },
425 { 0x5037c, 0x2300001d },
426};
427
428static struct mdp_table_entry mdp_downscale_y_table_PT4TOPT6[] = {
429 { 0x5fffc, 0x740008c },
430 { 0x50300, 0x33800088 },
431 { 0x5fffc, 0x800008e },
432 { 0x50304, 0x33400084 },
433 { 0x5fffc, 0x8400092 },
434 { 0x50308, 0x33000080 },
435 { 0x5fffc, 0x9000094 },
436 { 0x5030c, 0x3300007b },
437 { 0x5fffc, 0x9c00098 },
438 { 0x50310, 0x32400077 },
439 { 0x5fffc, 0xa40009b },
440 { 0x50314, 0x32000073 },
441 { 0x5fffc, 0xb00009d },
442 { 0x50318, 0x31c0006f },
443 { 0x5fffc, 0xbc000a0 },
444 { 0x5031c, 0x3140006b },
445 { 0x5fffc, 0xc8000a2 },
446 { 0x50320, 0x31000067 },
447 { 0x5fffc, 0xd8000a5 },
448 { 0x50324, 0x30800062 },
449 { 0x5fffc, 0xe4000a8 },
450 { 0x50328, 0x2fc0005f },
451 { 0x5fffc, 0xec000aa },
452 { 0x5032c, 0x2fc0005b },
453 { 0x5fffc, 0xf8000ad },
454 { 0x50330, 0x2f400057 },
455 { 0x5fffc, 0x108000b0 },
456 { 0x50334, 0x2e400054 },
457 { 0x5fffc, 0x114000b2 },
458 { 0x50338, 0x2e000050 },
459 { 0x5fffc, 0x124000b4 },
460 { 0x5033c, 0x2d80004c },
461 { 0x5fffc, 0x130000b6 },
462 { 0x50340, 0x2d000049 },
463 { 0x5fffc, 0x140000b8 },
464 { 0x50344, 0x2c800045 },
465 { 0x5fffc, 0x150000b9 },
466 { 0x50348, 0x2c000042 },
467 { 0x5fffc, 0x15c000bd },
468 { 0x5034c, 0x2b40003e },
469 { 0x5fffc, 0x16c000bf },
470 { 0x50350, 0x2a80003b },
471 { 0x5fffc, 0x17c000bf },
472 { 0x50354, 0x2a000039 },
473 { 0x5fffc, 0x188000c2 },
474 { 0x50358, 0x29400036 },
475 { 0x5fffc, 0x19c000c4 },
476 { 0x5035c, 0x28800032 },
477 { 0x5fffc, 0x1ac000c5 },
478 { 0x50360, 0x2800002f },
479 { 0x5fffc, 0x1bc000c7 },
480 { 0x50364, 0x2740002c },
481 { 0x5fffc, 0x1cc000c8 },
482 { 0x50368, 0x26c00029 },
483 { 0x5fffc, 0x1dc000c9 },
484 { 0x5036c, 0x26000027 },
485 { 0x5fffc, 0x1ec000cc },
486 { 0x50370, 0x25000024 },
487 { 0x5fffc, 0x200000cc },
488 { 0x50374, 0x24800021 },
489 { 0x5fffc, 0x210000cd },
490 { 0x50378, 0x23800020 },
491 { 0x5fffc, 0x220000ce },
492 { 0x5037c, 0x2300001d },
493};
494
495static struct mdp_table_entry mdp_downscale_y_table_PT6TOPT8[] = {
496 { 0x5fffc, 0xfe000070 },
497 { 0x50300, 0x4bc00068 },
498 { 0x5fffc, 0xfe000078 },
499 { 0x50304, 0x4bc00060 },
500 { 0x5fffc, 0xfe000080 },
501 { 0x50308, 0x4b800059 },
502 { 0x5fffc, 0xfe000089 },
503 { 0x5030c, 0x4b000052 },
504 { 0x5fffc, 0xfe400091 },
505 { 0x50310, 0x4a80004b },
506 { 0x5fffc, 0xfe40009a },
507 { 0x50314, 0x4a000044 },
508 { 0x5fffc, 0xfe8000a3 },
509 { 0x50318, 0x4940003d },
510 { 0x5fffc, 0xfec000ac },
511 { 0x5031c, 0x48400037 },
512 { 0x5fffc, 0xff0000b4 },
513 { 0x50320, 0x47800031 },
514 { 0x5fffc, 0xff8000bd },
515 { 0x50324, 0x4640002b },
516 { 0x5fffc, 0xc5 },
517 { 0x50328, 0x45000026 },
518 { 0x5fffc, 0x8000ce },
519 { 0x5032c, 0x43800021 },
520 { 0x5fffc, 0x10000d6 },
521 { 0x50330, 0x4240001c },
522 { 0x5fffc, 0x18000df },
523 { 0x50334, 0x40800018 },
524 { 0x5fffc, 0x24000e6 },
525 { 0x50338, 0x3f000014 },
526 { 0x5fffc, 0x30000ee },
527 { 0x5033c, 0x3d400010 },
528 { 0x5fffc, 0x40000f5 },
529 { 0x50340, 0x3b80000c },
530 { 0x5fffc, 0x50000fc },
531 { 0x50344, 0x39800009 },
532 { 0x5fffc, 0x6000102 },
533 { 0x50348, 0x37c00006 },
534 { 0x5fffc, 0x7000109 },
535 { 0x5034c, 0x35800004 },
536 { 0x5fffc, 0x840010e },
537 { 0x50350, 0x33800002 },
538 { 0x5fffc, 0x9800114 },
539 { 0x50354, 0x31400000 },
540 { 0x5fffc, 0xac00119 },
541 { 0x50358, 0x2f4003fe },
542 { 0x5fffc, 0xc40011e },
543 { 0x5035c, 0x2d0003fc },
544 { 0x5fffc, 0xdc00121 },
545 { 0x50360, 0x2b0003fb },
546 { 0x5fffc, 0xf400125 },
547 { 0x50364, 0x28c003fa },
548 { 0x5fffc, 0x11000128 },
549 { 0x50368, 0x268003f9 },
550 { 0x5fffc, 0x12c0012a },
551 { 0x5036c, 0x244003f9 },
552 { 0x5fffc, 0x1480012c },
553 { 0x50370, 0x224003f8 },
554 { 0x5fffc, 0x1640012e },
555 { 0x50374, 0x200003f8 },
556 { 0x5fffc, 0x1800012f },
557 { 0x50378, 0x1e0003f8 },
558 { 0x5fffc, 0x1a00012f },
559 { 0x5037c, 0x1c0003f8 },
560};
561
562static struct mdp_table_entry mdp_downscale_y_table_PT8TO1[] = {
563 { 0x5fffc, 0x0 },
564 { 0x50300, 0x7fc00000 },
565 { 0x5fffc, 0xff80000d },
566 { 0x50304, 0x7ec003f9 },
567 { 0x5fffc, 0xfec0001c },
568 { 0x50308, 0x7d4003f3 },
569 { 0x5fffc, 0xfe40002b },
570 { 0x5030c, 0x7b8003ed },
571 { 0x5fffc, 0xfd80003c },
572 { 0x50310, 0x794003e8 },
573 { 0x5fffc, 0xfcc0004d },
574 { 0x50314, 0x76c003e4 },
575 { 0x5fffc, 0xfc40005f },
576 { 0x50318, 0x73c003e0 },
577 { 0x5fffc, 0xfb800071 },
578 { 0x5031c, 0x708003de },
579 { 0x5fffc, 0xfac00085 },
580 { 0x50320, 0x6d0003db },
581 { 0x5fffc, 0xfa000098 },
582 { 0x50324, 0x698003d9 },
583 { 0x5fffc, 0xf98000ac },
584 { 0x50328, 0x654003d8 },
585 { 0x5fffc, 0xf8c000c1 },
586 { 0x5032c, 0x610003d7 },
587 { 0x5fffc, 0xf84000d5 },
588 { 0x50330, 0x5c8003d7 },
589 { 0x5fffc, 0xf7c000e9 },
590 { 0x50334, 0x580003d7 },
591 { 0x5fffc, 0xf74000fd },
592 { 0x50338, 0x534003d8 },
593 { 0x5fffc, 0xf6c00112 },
594 { 0x5033c, 0x4e8003d8 },
595 { 0x5fffc, 0xf6800126 },
596 { 0x50340, 0x494003da },
597 { 0x5fffc, 0xf600013a },
598 { 0x50344, 0x448003db },
599 { 0x5fffc, 0xf600014d },
600 { 0x50348, 0x3f4003dd },
601 { 0x5fffc, 0xf5c00160 },
602 { 0x5034c, 0x3a4003df },
603 { 0x5fffc, 0xf5c00172 },
604 { 0x50350, 0x354003e1 },
605 { 0x5fffc, 0xf5c00184 },
606 { 0x50354, 0x304003e3 },
607 { 0x5fffc, 0xf6000195 },
608 { 0x50358, 0x2b0003e6 },
609 { 0x5fffc, 0xf64001a6 },
610 { 0x5035c, 0x260003e8 },
611 { 0x5fffc, 0xf6c001b4 },
612 { 0x50360, 0x214003eb },
613 { 0x5fffc, 0xf78001c2 },
614 { 0x50364, 0x1c4003ee },
615 { 0x5fffc, 0xf80001cf },
616 { 0x50368, 0x17c003f1 },
617 { 0x5fffc, 0xf90001db },
618 { 0x5036c, 0x134003f3 },
619 { 0x5fffc, 0xfa0001e5 },
620 { 0x50370, 0xf0003f6 },
621 { 0x5fffc, 0xfb4001ee },
622 { 0x50374, 0xac003f9 },
623 { 0x5fffc, 0xfcc001f5 },
624 { 0x50378, 0x70003fb },
625 { 0x5fffc, 0xfe4001fb },
626 { 0x5037c, 0x34003fe },
627};
628
629struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX] = {
630 [MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_y_table_PT2TOPT4,
631 [MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_y_table_PT4TOPT6,
632 [MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_y_table_PT6TOPT8,
633 [MDP_DOWNSCALE_PT8TO1] = mdp_downscale_y_table_PT8TO1,
634};
635
636struct mdp_table_entry mdp_gaussian_blur_table[] = {
637 /* max variance */
638 { 0x5fffc, 0x20000080 },
639 { 0x50280, 0x20000080 },
640 { 0x5fffc, 0x20000080 },
641 { 0x50284, 0x20000080 },
642 { 0x5fffc, 0x20000080 },
643 { 0x50288, 0x20000080 },
644 { 0x5fffc, 0x20000080 },
645 { 0x5028c, 0x20000080 },
646 { 0x5fffc, 0x20000080 },
647 { 0x50290, 0x20000080 },
648 { 0x5fffc, 0x20000080 },
649 { 0x50294, 0x20000080 },
650 { 0x5fffc, 0x20000080 },
651 { 0x50298, 0x20000080 },
652 { 0x5fffc, 0x20000080 },
653 { 0x5029c, 0x20000080 },
654 { 0x5fffc, 0x20000080 },
655 { 0x502a0, 0x20000080 },
656 { 0x5fffc, 0x20000080 },
657 { 0x502a4, 0x20000080 },
658 { 0x5fffc, 0x20000080 },
659 { 0x502a8, 0x20000080 },
660 { 0x5fffc, 0x20000080 },
661 { 0x502ac, 0x20000080 },
662 { 0x5fffc, 0x20000080 },
663 { 0x502b0, 0x20000080 },
664 { 0x5fffc, 0x20000080 },
665 { 0x502b4, 0x20000080 },
666 { 0x5fffc, 0x20000080 },
667 { 0x502b8, 0x20000080 },
668 { 0x5fffc, 0x20000080 },
669 { 0x502bc, 0x20000080 },
670 { 0x5fffc, 0x20000080 },
671 { 0x502c0, 0x20000080 },
672 { 0x5fffc, 0x20000080 },
673 { 0x502c4, 0x20000080 },
674 { 0x5fffc, 0x20000080 },
675 { 0x502c8, 0x20000080 },
676 { 0x5fffc, 0x20000080 },
677 { 0x502cc, 0x20000080 },
678 { 0x5fffc, 0x20000080 },
679 { 0x502d0, 0x20000080 },
680 { 0x5fffc, 0x20000080 },
681 { 0x502d4, 0x20000080 },
682 { 0x5fffc, 0x20000080 },
683 { 0x502d8, 0x20000080 },
684 { 0x5fffc, 0x20000080 },
685 { 0x502dc, 0x20000080 },
686 { 0x5fffc, 0x20000080 },
687 { 0x502e0, 0x20000080 },
688 { 0x5fffc, 0x20000080 },
689 { 0x502e4, 0x20000080 },
690 { 0x5fffc, 0x20000080 },
691 { 0x502e8, 0x20000080 },
692 { 0x5fffc, 0x20000080 },
693 { 0x502ec, 0x20000080 },
694 { 0x5fffc, 0x20000080 },
695 { 0x502f0, 0x20000080 },
696 { 0x5fffc, 0x20000080 },
697 { 0x502f4, 0x20000080 },
698 { 0x5fffc, 0x20000080 },
699 { 0x502f8, 0x20000080 },
700 { 0x5fffc, 0x20000080 },
701 { 0x502fc, 0x20000080 },
702 { 0x5fffc, 0x20000080 },
703 { 0x50300, 0x20000080 },
704 { 0x5fffc, 0x20000080 },
705 { 0x50304, 0x20000080 },
706 { 0x5fffc, 0x20000080 },
707 { 0x50308, 0x20000080 },
708 { 0x5fffc, 0x20000080 },
709 { 0x5030c, 0x20000080 },
710 { 0x5fffc, 0x20000080 },
711 { 0x50310, 0x20000080 },
712 { 0x5fffc, 0x20000080 },
713 { 0x50314, 0x20000080 },
714 { 0x5fffc, 0x20000080 },
715 { 0x50318, 0x20000080 },
716 { 0x5fffc, 0x20000080 },
717 { 0x5031c, 0x20000080 },
718 { 0x5fffc, 0x20000080 },
719 { 0x50320, 0x20000080 },
720 { 0x5fffc, 0x20000080 },
721 { 0x50324, 0x20000080 },
722 { 0x5fffc, 0x20000080 },
723 { 0x50328, 0x20000080 },
724 { 0x5fffc, 0x20000080 },
725 { 0x5032c, 0x20000080 },
726 { 0x5fffc, 0x20000080 },
727 { 0x50330, 0x20000080 },
728 { 0x5fffc, 0x20000080 },
729 { 0x50334, 0x20000080 },
730 { 0x5fffc, 0x20000080 },
731 { 0x50338, 0x20000080 },
732 { 0x5fffc, 0x20000080 },
733 { 0x5033c, 0x20000080 },
734 { 0x5fffc, 0x20000080 },
735 { 0x50340, 0x20000080 },
736 { 0x5fffc, 0x20000080 },
737 { 0x50344, 0x20000080 },
738 { 0x5fffc, 0x20000080 },
739 { 0x50348, 0x20000080 },
740 { 0x5fffc, 0x20000080 },
741 { 0x5034c, 0x20000080 },
742 { 0x5fffc, 0x20000080 },
743 { 0x50350, 0x20000080 },
744 { 0x5fffc, 0x20000080 },
745 { 0x50354, 0x20000080 },
746 { 0x5fffc, 0x20000080 },
747 { 0x50358, 0x20000080 },
748 { 0x5fffc, 0x20000080 },
749 { 0x5035c, 0x20000080 },
750 { 0x5fffc, 0x20000080 },
751 { 0x50360, 0x20000080 },
752 { 0x5fffc, 0x20000080 },
753 { 0x50364, 0x20000080 },
754 { 0x5fffc, 0x20000080 },
755 { 0x50368, 0x20000080 },
756 { 0x5fffc, 0x20000080 },
757 { 0x5036c, 0x20000080 },
758 { 0x5fffc, 0x20000080 },
759 { 0x50370, 0x20000080 },
760 { 0x5fffc, 0x20000080 },
761 { 0x50374, 0x20000080 },
762 { 0x5fffc, 0x20000080 },
763 { 0x50378, 0x20000080 },
764 { 0x5fffc, 0x20000080 },
765 { 0x5037c, 0x20000080 },
766};
diff --git a/drivers/video/msm/mdp_scale_tables.h b/drivers/video/msm/mdp_scale_tables.h
new file mode 100644
index 000000000000..34077b1af603
--- /dev/null
+++ b/drivers/video/msm/mdp_scale_tables.h
@@ -0,0 +1,38 @@
1/* drivers/video/msm_fb/mdp_scale_tables.h
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15#ifndef _MDP_SCALE_TABLES_H_
16#define _MDP_SCALE_TABLES_H_
17
18#include <linux/types.h>
19struct mdp_table_entry {
20 uint32_t reg;
21 uint32_t val;
22};
23
24extern struct mdp_table_entry mdp_upscale_table[64];
25
26enum {
27 MDP_DOWNSCALE_PT2TOPT4,
28 MDP_DOWNSCALE_PT4TOPT6,
29 MDP_DOWNSCALE_PT6TOPT8,
30 MDP_DOWNSCALE_PT8TO1,
31 MDP_DOWNSCALE_MAX,
32};
33
34extern struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX];
35extern struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX];
36extern struct mdp_table_entry mdp_gaussian_blur_table[];
37
38#endif
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
new file mode 100644
index 000000000000..49101dda45ee
--- /dev/null
+++ b/drivers/video/msm/msm_fb.c
@@ -0,0 +1,636 @@
1/* drivers/video/msm/msm_fb.c
2 *
3 * Core MSM framebuffer driver.
4 *
5 * Copyright (C) 2007 Google Incorporated
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/platform_device.h>
18#include <linux/module.h>
19#include <linux/fb.h>
20#include <linux/delay.h>
21
22#include <linux/freezer.h>
23#include <linux/wait.h>
24#include <linux/msm_mdp.h>
25#include <linux/io.h>
26#include <linux/uaccess.h>
27#include <mach/msm_fb.h>
28#include <mach/board.h>
29#include <linux/workqueue.h>
30#include <linux/clk.h>
31#include <linux/debugfs.h>
32#include <linux/dma-mapping.h>
33
34#define PRINT_FPS 0
35#define PRINT_BLIT_TIME 0
36
37#define SLEEPING 0x4
38#define UPDATING 0x3
39#define FULL_UPDATE_DONE 0x2
40#define WAKING 0x1
41#define AWAKE 0x0
42
43#define NONE 0
44#define SUSPEND_RESUME 0x1
45#define FPS 0x2
46#define BLIT_TIME 0x4
47#define SHOW_UPDATES 0x8
48
49#define DLOG(mask, fmt, args...) \
50do { \
51 if (msmfb_debug_mask & mask) \
52 printk(KERN_INFO "msmfb: "fmt, ##args); \
53} while (0)
54
55static int msmfb_debug_mask;
56module_param_named(msmfb_debug_mask, msmfb_debug_mask, int,
57 S_IRUGO | S_IWUSR | S_IWGRP);
58
59struct mdp_device *mdp;
60
61struct msmfb_info {
62 struct fb_info *fb;
63 struct msm_panel_data *panel;
64 int xres;
65 int yres;
66 unsigned output_format;
67 unsigned yoffset;
68 unsigned frame_requested;
69 unsigned frame_done;
70 int sleeping;
71 unsigned update_frame;
72 struct {
73 int left;
74 int top;
75 int eright; /* exclusive */
76 int ebottom; /* exclusive */
77 } update_info;
78 char *black;
79
80 spinlock_t update_lock;
81 struct mutex panel_init_lock;
82 wait_queue_head_t frame_wq;
83 struct workqueue_struct *resume_workqueue;
84 struct work_struct resume_work;
85 struct msmfb_callback dma_callback;
86 struct msmfb_callback vsync_callback;
87 struct hrtimer fake_vsync;
88 ktime_t vsync_request_time;
89};
90
91static int msmfb_open(struct fb_info *info, int user)
92{
93 return 0;
94}
95
96static int msmfb_release(struct fb_info *info, int user)
97{
98 return 0;
99}
100
101/* Called from dma interrupt handler, must not sleep */
102static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback)
103{
104 unsigned long irq_flags;
105 struct msmfb_info *msmfb = container_of(callback, struct msmfb_info,
106 dma_callback);
107
108 spin_lock_irqsave(&msmfb->update_lock, irq_flags);
109 msmfb->frame_done = msmfb->frame_requested;
110 if (msmfb->sleeping == UPDATING &&
111 msmfb->frame_done == msmfb->update_frame) {
112 DLOG(SUSPEND_RESUME, "full update completed\n");
113 queue_work(msmfb->resume_workqueue, &msmfb->resume_work);
114 }
115 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
116 wake_up(&msmfb->frame_wq);
117}
118
119static int msmfb_start_dma(struct msmfb_info *msmfb)
120{
121 uint32_t x, y, w, h;
122 unsigned addr;
123 unsigned long irq_flags;
124 uint32_t yoffset;
125 s64 time_since_request;
126 struct msm_panel_data *panel = msmfb->panel;
127
128 spin_lock_irqsave(&msmfb->update_lock, irq_flags);
129 time_since_request = ktime_to_ns(ktime_sub(ktime_get(),
130 msmfb->vsync_request_time));
131 if (time_since_request > 20 * NSEC_PER_MSEC) {
132 uint32_t us;
133 us = do_div(time_since_request, NSEC_PER_MSEC) / NSEC_PER_USEC;
134 printk(KERN_WARNING "msmfb_start_dma %lld.%03u ms after vsync "
135 "request\n", time_since_request, us);
136 }
137 if (msmfb->frame_done == msmfb->frame_requested) {
138 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
139 return -1;
140 }
141 if (msmfb->sleeping == SLEEPING) {
142 DLOG(SUSPEND_RESUME, "tried to start dma while asleep\n");
143 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
144 return -1;
145 }
146 x = msmfb->update_info.left;
147 y = msmfb->update_info.top;
148 w = msmfb->update_info.eright - x;
149 h = msmfb->update_info.ebottom - y;
150 yoffset = msmfb->yoffset;
151 msmfb->update_info.left = msmfb->xres + 1;
152 msmfb->update_info.top = msmfb->yres + 1;
153 msmfb->update_info.eright = 0;
154 msmfb->update_info.ebottom = 0;
155 if (unlikely(w > msmfb->xres || h > msmfb->yres ||
156 w == 0 || h == 0)) {
157 printk(KERN_INFO "invalid update: %d %d %d "
158 "%d\n", x, y, w, h);
159 msmfb->frame_done = msmfb->frame_requested;
160 goto error;
161 }
162 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
163
164 addr = ((msmfb->xres * (yoffset + y) + x) * 2);
165 mdp->dma(mdp, addr + msmfb->fb->fix.smem_start,
166 msmfb->xres * 2, w, h, x, y, &msmfb->dma_callback,
167 panel->interface_type);
168 return 0;
169error:
170 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
171 /* some clients need to clear their vsync interrupt */
172 if (panel->clear_vsync)
173 panel->clear_vsync(panel);
174 wake_up(&msmfb->frame_wq);
175 return 0;
176}
177
178/* Called from esync interrupt handler, must not sleep */
179static void msmfb_handle_vsync_interrupt(struct msmfb_callback *callback)
180{
181 struct msmfb_info *msmfb = container_of(callback, struct msmfb_info,
182 vsync_callback);
183 msmfb_start_dma(msmfb);
184}
185
186static enum hrtimer_restart msmfb_fake_vsync(struct hrtimer *timer)
187{
188 struct msmfb_info *msmfb = container_of(timer, struct msmfb_info,
189 fake_vsync);
190 msmfb_start_dma(msmfb);
191 return HRTIMER_NORESTART;
192}
193
194static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top,
195 uint32_t eright, uint32_t ebottom,
196 uint32_t yoffset, int pan_display)
197{
198 struct msmfb_info *msmfb = info->par;
199 struct msm_panel_data *panel = msmfb->panel;
200 unsigned long irq_flags;
201 int sleeping;
202 int retry = 1;
203
204 DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n",
205 left, top, eright, ebottom, yoffset, pan_display);
206restart:
207 spin_lock_irqsave(&msmfb->update_lock, irq_flags);
208
209 /* if we are sleeping, on a pan_display wait 10ms (to throttle back
210 * drawing otherwise return */
211 if (msmfb->sleeping == SLEEPING) {
212 DLOG(SUSPEND_RESUME, "drawing while asleep\n");
213 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
214 if (pan_display)
215 wait_event_interruptible_timeout(msmfb->frame_wq,
216 msmfb->sleeping != SLEEPING, HZ/10);
217 return;
218 }
219
220 sleeping = msmfb->sleeping;
221 /* on a full update, if the last frame has not completed, wait for it */
222 if (pan_display && (msmfb->frame_requested != msmfb->frame_done ||
223 sleeping == UPDATING)) {
224 int ret;
225 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
226 ret = wait_event_interruptible_timeout(msmfb->frame_wq,
227 msmfb->frame_done == msmfb->frame_requested &&
228 msmfb->sleeping != UPDATING, 5 * HZ);
229 if (ret <= 0 && (msmfb->frame_requested != msmfb->frame_done ||
230 msmfb->sleeping == UPDATING)) {
231 if (retry && panel->request_vsync &&
232 (sleeping == AWAKE)) {
233 panel->request_vsync(panel,
234 &msmfb->vsync_callback);
235 retry = 0;
236 printk(KERN_WARNING "msmfb_pan_display timeout "
237 "rerequest vsync\n");
238 } else {
239 printk(KERN_WARNING "msmfb_pan_display timeout "
240 "waiting for frame start, %d %d\n",
241 msmfb->frame_requested,
242 msmfb->frame_done);
243 return;
244 }
245 }
246 goto restart;
247 }
248
249
250 msmfb->frame_requested++;
251 /* if necessary, update the y offset, if this is the
252 * first full update on resume, set the sleeping state */
253 if (pan_display) {
254 msmfb->yoffset = yoffset;
255 if (left == 0 && top == 0 && eright == info->var.xres &&
256 ebottom == info->var.yres) {
257 if (sleeping == WAKING) {
258 msmfb->update_frame = msmfb->frame_requested;
259 DLOG(SUSPEND_RESUME, "full update starting\n");
260 msmfb->sleeping = UPDATING;
261 }
262 }
263 }
264
265 /* set the update request */
266 if (left < msmfb->update_info.left)
267 msmfb->update_info.left = left;
268 if (top < msmfb->update_info.top)
269 msmfb->update_info.top = top;
270 if (eright > msmfb->update_info.eright)
271 msmfb->update_info.eright = eright;
272 if (ebottom > msmfb->update_info.ebottom)
273 msmfb->update_info.ebottom = ebottom;
274 DLOG(SHOW_UPDATES, "update queued %d %d %d %d %d\n",
275 msmfb->update_info.left, msmfb->update_info.top,
276 msmfb->update_info.eright, msmfb->update_info.ebottom,
277 msmfb->yoffset);
278 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
279
280 /* if the panel is all the way on wait for vsync, otherwise sleep
281 * for 16 ms (long enough for the dma to panel) and then begin dma */
282 msmfb->vsync_request_time = ktime_get();
283 if (panel->request_vsync && (sleeping == AWAKE)) {
284 panel->request_vsync(panel, &msmfb->vsync_callback);
285 } else {
286 if (!hrtimer_active(&msmfb->fake_vsync)) {
287 hrtimer_start(&msmfb->fake_vsync,
288 ktime_set(0, NSEC_PER_SEC/60),
289 HRTIMER_MODE_REL);
290 }
291 }
292}
293
294static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top,
295 uint32_t eright, uint32_t ebottom)
296{
297 msmfb_pan_update(info, left, top, eright, ebottom, 0, 0);
298}
299
300static void power_on_panel(struct work_struct *work)
301{
302 struct msmfb_info *msmfb =
303 container_of(work, struct msmfb_info, resume_work);
304 struct msm_panel_data *panel = msmfb->panel;
305 unsigned long irq_flags;
306
307 mutex_lock(&msmfb->panel_init_lock);
308 DLOG(SUSPEND_RESUME, "turning on panel\n");
309 if (msmfb->sleeping == UPDATING) {
310 if (panel->unblank(panel)) {
311 printk(KERN_INFO "msmfb: panel unblank failed,"
312 "not starting drawing\n");
313 goto error;
314 }
315 spin_lock_irqsave(&msmfb->update_lock, irq_flags);
316 msmfb->sleeping = AWAKE;
317 wake_up(&msmfb->frame_wq);
318 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
319 }
320error:
321 mutex_unlock(&msmfb->panel_init_lock);
322}
323
324
325static int msmfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
326{
327 if ((var->xres != info->var.xres) ||
328 (var->yres != info->var.yres) ||
329 (var->xres_virtual != info->var.xres_virtual) ||
330 (var->yres_virtual != info->var.yres_virtual) ||
331 (var->xoffset != info->var.xoffset) ||
332 (var->bits_per_pixel != info->var.bits_per_pixel) ||
333 (var->grayscale != info->var.grayscale))
334 return -EINVAL;
335 return 0;
336}
337
338int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
339{
340 struct msmfb_info *msmfb = info->par;
341 struct msm_panel_data *panel = msmfb->panel;
342
343 /* "UPDT" */
344 if ((panel->caps & MSMFB_CAP_PARTIAL_UPDATES) &&
345 (var->reserved[0] == 0x54445055)) {
346 msmfb_pan_update(info, var->reserved[1] & 0xffff,
347 var->reserved[1] >> 16,
348 var->reserved[2] & 0xffff,
349 var->reserved[2] >> 16, var->yoffset, 1);
350 } else {
351 msmfb_pan_update(info, 0, 0, info->var.xres, info->var.yres,
352 var->yoffset, 1);
353 }
354 return 0;
355}
356
357static void msmfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
358{
359 cfb_fillrect(p, rect);
360 msmfb_update(p, rect->dx, rect->dy, rect->dx + rect->width,
361 rect->dy + rect->height);
362}
363
364static void msmfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
365{
366 cfb_copyarea(p, area);
367 msmfb_update(p, area->dx, area->dy, area->dx + area->width,
368 area->dy + area->height);
369}
370
371static void msmfb_imageblit(struct fb_info *p, const struct fb_image *image)
372{
373 cfb_imageblit(p, image);
374 msmfb_update(p, image->dx, image->dy, image->dx + image->width,
375 image->dy + image->height);
376}
377
378
379static int msmfb_blit(struct fb_info *info,
380 void __user *p)
381{
382 struct mdp_blit_req req;
383 struct mdp_blit_req_list req_list;
384 int i;
385 int ret;
386
387 if (copy_from_user(&req_list, p, sizeof(req_list)))
388 return -EFAULT;
389
390 for (i = 0; i < req_list.count; i++) {
391 struct mdp_blit_req_list *list =
392 (struct mdp_blit_req_list *)p;
393 if (copy_from_user(&req, &list->req[i], sizeof(req)))
394 return -EFAULT;
395 ret = mdp->blit(mdp, info, &req);
396 if (ret)
397 return ret;
398 }
399 return 0;
400}
401
402
403DEFINE_MUTEX(mdp_ppp_lock);
404
405static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg)
406{
407 void __user *argp = (void __user *)arg;
408 int ret;
409
410 switch (cmd) {
411 case MSMFB_GRP_DISP:
412 mdp->set_grp_disp(mdp, arg);
413 break;
414 case MSMFB_BLIT:
415 ret = msmfb_blit(p, argp);
416 if (ret)
417 return ret;
418 break;
419 default:
420 printk(KERN_INFO "msmfb unknown ioctl: %d\n", cmd);
421 return -EINVAL;
422 }
423 return 0;
424}
425
426static struct fb_ops msmfb_ops = {
427 .owner = THIS_MODULE,
428 .fb_open = msmfb_open,
429 .fb_release = msmfb_release,
430 .fb_check_var = msmfb_check_var,
431 .fb_pan_display = msmfb_pan_display,
432 .fb_fillrect = msmfb_fillrect,
433 .fb_copyarea = msmfb_copyarea,
434 .fb_imageblit = msmfb_imageblit,
435 .fb_ioctl = msmfb_ioctl,
436};
437
438static unsigned PP[16];
439
440
441
442#define BITS_PER_PIXEL 16
443
444static void setup_fb_info(struct msmfb_info *msmfb)
445{
446 struct fb_info *fb_info = msmfb->fb;
447 int r;
448
449 /* finish setting up the fb_info struct */
450 strncpy(fb_info->fix.id, "msmfb", 16);
451 fb_info->fix.ypanstep = 1;
452
453 fb_info->fbops = &msmfb_ops;
454 fb_info->flags = FBINFO_DEFAULT;
455
456 fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
457 fb_info->fix.visual = FB_VISUAL_TRUECOLOR;
458 fb_info->fix.line_length = msmfb->xres * 2;
459
460 fb_info->var.xres = msmfb->xres;
461 fb_info->var.yres = msmfb->yres;
462 fb_info->var.width = msmfb->panel->fb_data->width;
463 fb_info->var.height = msmfb->panel->fb_data->height;
464 fb_info->var.xres_virtual = msmfb->xres;
465 fb_info->var.yres_virtual = msmfb->yres * 2;
466 fb_info->var.bits_per_pixel = BITS_PER_PIXEL;
467 fb_info->var.accel_flags = 0;
468
469 fb_info->var.yoffset = 0;
470
471 if (msmfb->panel->caps & MSMFB_CAP_PARTIAL_UPDATES) {
472 fb_info->var.reserved[0] = 0x54445055;
473 fb_info->var.reserved[1] = 0;
474 fb_info->var.reserved[2] = (uint16_t)msmfb->xres |
475 ((uint32_t)msmfb->yres << 16);
476 }
477
478 fb_info->var.red.offset = 11;
479 fb_info->var.red.length = 5;
480 fb_info->var.red.msb_right = 0;
481 fb_info->var.green.offset = 5;
482 fb_info->var.green.length = 6;
483 fb_info->var.green.msb_right = 0;
484 fb_info->var.blue.offset = 0;
485 fb_info->var.blue.length = 5;
486 fb_info->var.blue.msb_right = 0;
487
488 r = fb_alloc_cmap(&fb_info->cmap, 16, 0);
489 fb_info->pseudo_palette = PP;
490
491 PP[0] = 0;
492 for (r = 1; r < 16; r++)
493 PP[r] = 0xffffffff;
494}
495
496static int setup_fbmem(struct msmfb_info *msmfb, struct platform_device *pdev)
497{
498 struct fb_info *fb = msmfb->fb;
499 struct resource *resource;
500 unsigned long size = msmfb->xres * msmfb->yres *
501 (BITS_PER_PIXEL >> 3) * 2;
502 unsigned char *fbram;
503
504 /* board file might have attached a resource describing an fb */
505 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
506 if (!resource)
507 return -EINVAL;
508
509 /* check the resource is large enough to fit the fb */
510 if (resource->end - resource->start < size) {
511 printk(KERN_ERR "allocated resource is too small for "
512 "fb\n");
513 return -ENOMEM;
514 }
515 fb->fix.smem_start = resource->start;
516 fb->fix.smem_len = resource->end - resource->start;
517 fbram = ioremap(resource->start,
518 resource->end - resource->start);
519 if (fbram == 0) {
520 printk(KERN_ERR "msmfb: cannot allocate fbram!\n");
521 return -ENOMEM;
522 }
523 fb->screen_base = fbram;
524 return 0;
525}
526
527static int msmfb_probe(struct platform_device *pdev)
528{
529 struct fb_info *fb;
530 struct msmfb_info *msmfb;
531 struct msm_panel_data *panel = pdev->dev.platform_data;
532 int ret;
533
534 if (!panel) {
535 pr_err("msmfb_probe: no platform data\n");
536 return -EINVAL;
537 }
538 if (!panel->fb_data) {
539 pr_err("msmfb_probe: no fb_data\n");
540 return -EINVAL;
541 }
542
543 fb = framebuffer_alloc(sizeof(struct msmfb_info), &pdev->dev);
544 if (!fb)
545 return -ENOMEM;
546 msmfb = fb->par;
547 msmfb->fb = fb;
548 msmfb->panel = panel;
549 msmfb->xres = panel->fb_data->xres;
550 msmfb->yres = panel->fb_data->yres;
551
552 ret = setup_fbmem(msmfb, pdev);
553 if (ret)
554 goto error_setup_fbmem;
555
556 setup_fb_info(msmfb);
557
558 spin_lock_init(&msmfb->update_lock);
559 mutex_init(&msmfb->panel_init_lock);
560 init_waitqueue_head(&msmfb->frame_wq);
561 msmfb->resume_workqueue = create_workqueue("panel_on");
562 if (msmfb->resume_workqueue == NULL) {
563 printk(KERN_ERR "failed to create panel_on workqueue\n");
564 ret = -ENOMEM;
565 goto error_create_workqueue;
566 }
567 INIT_WORK(&msmfb->resume_work, power_on_panel);
568 msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres,
569 GFP_KERNEL);
570
571 printk(KERN_INFO "msmfb_probe() installing %d x %d panel\n",
572 msmfb->xres, msmfb->yres);
573
574 msmfb->dma_callback.func = msmfb_handle_dma_interrupt;
575 msmfb->vsync_callback.func = msmfb_handle_vsync_interrupt;
576 hrtimer_init(&msmfb->fake_vsync, CLOCK_MONOTONIC,
577 HRTIMER_MODE_REL);
578
579
580 msmfb->fake_vsync.function = msmfb_fake_vsync;
581
582 ret = register_framebuffer(fb);
583 if (ret)
584 goto error_register_framebuffer;
585
586 msmfb->sleeping = WAKING;
587
588 return 0;
589
590error_register_framebuffer:
591 destroy_workqueue(msmfb->resume_workqueue);
592error_create_workqueue:
593 iounmap(fb->screen_base);
594error_setup_fbmem:
595 framebuffer_release(msmfb->fb);
596 return ret;
597}
598
599static struct platform_driver msm_panel_driver = {
600 /* need to write remove */
601 .probe = msmfb_probe,
602 .driver = {.name = "msm_panel"},
603};
604
605
606static int msmfb_add_mdp_device(struct device *dev,
607 struct class_interface *class_intf)
608{
609 /* might need locking if mulitple mdp devices */
610 if (mdp)
611 return 0;
612 mdp = container_of(dev, struct mdp_device, dev);
613 return platform_driver_register(&msm_panel_driver);
614}
615
616static void msmfb_remove_mdp_device(struct device *dev,
617 struct class_interface *class_intf)
618{
619 /* might need locking if mulitple mdp devices */
620 if (dev != &mdp->dev)
621 return;
622 platform_driver_unregister(&msm_panel_driver);
623 mdp = NULL;
624}
625
626static struct class_interface msm_fb_interface = {
627 .add_dev = &msmfb_add_mdp_device,
628 .remove_dev = &msmfb_remove_mdp_device,
629};
630
631static int __init msmfb_init(void)
632{
633 return register_mdp_client(&msm_fb_interface);
634}
635
636module_init(msmfb_init);
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 44408850e2eb..551e3e9c4cbe 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -7,6 +7,69 @@ config FB_OMAP
7 help 7 help
8 Frame buffer driver for OMAP based boards. 8 Frame buffer driver for OMAP based boards.
9 9
10config FB_OMAP_LCD_VGA
11 bool "Use LCD in VGA mode"
12 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP
13
14choice
15 depends on FB_OMAP && MACH_OVERO
16 prompt "Screen resolution"
17 default FB_OMAP_079M3R
18 help
19 Selected desired screen resolution
20
21config FB_OMAP_031M3R
22 boolean "640 x 480 @ 60 Hz Reduced blanking"
23
24config FB_OMAP_048M3R
25 boolean "800 x 600 @ 60 Hz Reduced blanking"
26
27config FB_OMAP_079M3R
28 boolean "1024 x 768 @ 60 Hz Reduced blanking"
29
30config FB_OMAP_092M9R
31 boolean "1280 x 720 @ 60 Hz Reduced blanking"
32
33endchoice
34
35config FB_OMAP_LCDC_EXTERNAL
36 bool "External LCD controller support"
37 depends on FB_OMAP
38 help
39 Say Y here, if you want to have support for boards with an
40 external LCD controller connected to the SoSSI/RFBI interface.
41
42config FB_OMAP_LCDC_HWA742
43 bool "Epson HWA742 LCD controller support"
44 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
45 help
46 Say Y here if you want to have support for the external
47 Epson HWA742 LCD controller.
48
49config FB_OMAP_LCDC_BLIZZARD
50 bool "Epson Blizzard LCD controller support"
51 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
52 help
53 Say Y here if you want to have support for the external
54 Epson Blizzard LCD controller.
55
56config FB_OMAP_MANUAL_UPDATE
57 bool "Default to manual update mode"
58 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
59 help
60 Say Y here, if your user-space applications are capable of
61 notifying the frame buffer driver when a change has occured in
62 the frame buffer content and thus a reload of the image data to
63 the external frame buffer is required. If unsure, say N.
64
65config FB_OMAP_LCD_MIPID
66 bool "MIPI DBI-C/DCS compatible LCD support"
67 depends on FB_OMAP && SPI_MASTER
68 help
69 Say Y here if you want to have support for LCDs compatible with
70 the Mobile Industry Processor Interface DBI-C/DCS
71 specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3)
72
10config FB_OMAP_BOOTLOADER_INIT 73config FB_OMAP_BOOTLOADER_INIT
11 bool "Check bootloader initialization" 74 bool "Check bootloader initialization"
12 depends on FB_OMAP 75 depends on FB_OMAP
@@ -36,23 +99,4 @@ config FB_OMAP_DMA_TUNE
36 answer yes. Answer no if you have a dedicated video 99 answer yes. Answer no if you have a dedicated video
37 memory, or don't use any of the accelerated features. 100 memory, or don't use any of the accelerated features.
38 101
39config FB_OMAP_LCDC_EXTERNAL
40 bool "External LCD controller support"
41 depends on FB_OMAP
42 help
43 Say Y here, if you want to have support for boards with an
44 external LCD controller connected to the SoSSI/RFBI interface.
45
46config FB_OMAP_LCDC_HWA742
47 bool "Epson HWA742 LCD controller support"
48 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
49 help
50 Say Y here if you want to have support for the external
51 Epson HWA742 LCD controller.
52 102
53config FB_OMAP_LCDC_BLIZZARD
54 bool "Epson Blizzard LCD controller support"
55 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
56 help
57 Say Y here if you want to have support for the external
58 Epson Blizzard LCD controller.
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index ed13889c1162..b63b198d1f03 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -8,6 +8,7 @@ objs-yy := omapfb_main.o
8 8
9objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o 9objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o
10objs-y$(CONFIG_ARCH_OMAP2) += dispc.o 10objs-y$(CONFIG_ARCH_OMAP2) += dispc.o
11objs-y$(CONFIG_ARCH_OMAP3) += dispc.o
11 12
12objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o 13objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o
13objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o 14objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o
@@ -15,6 +16,7 @@ objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o
15objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o 16objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
16objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o 17objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
17 18
19objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
18objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o 20objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o
19objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o 21objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o
20objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o 22objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o
@@ -24,5 +26,15 @@ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o
24objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o 26objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
25objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o 27objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
26 28
29objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
30objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o
31objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o
32objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o
33objs-y$(CONFIG_MACH_OMAP2EVM) += lcd_omap2evm.o
34objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o
35objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o
36objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
37objs-y$(CONFIG_MACH_OVERO) += lcd_overo.o
38
27omapfb-objs := $(objs-yy) 39omapfb-objs := $(objs-yy)
28 40
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index 9dfcf39d3367..d5e59556f9e2 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -44,6 +44,7 @@
44#define BLIZZARD_CLK_SRC 0x0e 44#define BLIZZARD_CLK_SRC 0x0e
45#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10 45#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
46#define BLIZZARD_MEM_BANK0_STATUS 0x14 46#define BLIZZARD_MEM_BANK0_STATUS 0x14
47#define BLIZZARD_PANEL_CONFIGURATION 0x28
47#define BLIZZARD_HDISP 0x2a 48#define BLIZZARD_HDISP 0x2a
48#define BLIZZARD_HNDP 0x2c 49#define BLIZZARD_HNDP 0x2c
49#define BLIZZARD_VDISP0 0x2e 50#define BLIZZARD_VDISP0 0x2e
@@ -162,6 +163,10 @@ struct blizzard_struct {
162 int vid_scaled; 163 int vid_scaled;
163 int last_color_mode; 164 int last_color_mode;
164 int zoom_on; 165 int zoom_on;
166 int zoom_area_gx1;
167 int zoom_area_gx2;
168 int zoom_area_gy1;
169 int zoom_area_gy2;
165 int screen_width; 170 int screen_width;
166 int screen_height; 171 int screen_height;
167 unsigned te_connected:1; 172 unsigned te_connected:1;
@@ -513,6 +518,13 @@ static int do_full_screen_update(struct blizzard_request *req)
513 return REQ_PENDING; 518 return REQ_PENDING;
514} 519}
515 520
521static int check_1d_intersect(int a1, int a2, int b1, int b2)
522{
523 if (a2 <= b1 || b2 <= a1)
524 return 0;
525 return 1;
526}
527
516/* Setup all planes with an overlapping area with the update window. */ 528/* Setup all planes with an overlapping area with the update window. */
517static int do_partial_update(struct blizzard_request *req, int plane, 529static int do_partial_update(struct blizzard_request *req, int plane,
518 int x, int y, int w, int h, 530 int x, int y, int w, int h,
@@ -525,6 +537,7 @@ static int do_partial_update(struct blizzard_request *req, int plane,
525 int color_mode; 537 int color_mode;
526 int flags; 538 int flags;
527 int zoom_off; 539 int zoom_off;
540 int have_zoom_for_this_update = 0;
528 541
529 /* Global coordinates, relative to pixel 0,0 of the LCD */ 542 /* Global coordinates, relative to pixel 0,0 of the LCD */
530 gx1 = x + blizzard.plane[plane].pos_x; 543 gx1 = x + blizzard.plane[plane].pos_x;
@@ -544,10 +557,6 @@ static int do_partial_update(struct blizzard_request *req, int plane,
544 gx2_out = gx1_out + w_out; 557 gx2_out = gx1_out + w_out;
545 gy2_out = gy1_out + h_out; 558 gy2_out = gy1_out + h_out;
546 } 559 }
547 zoom_off = blizzard.zoom_on && gx1 == 0 && gy1 == 0 &&
548 w == blizzard.screen_width && h == blizzard.screen_height;
549 blizzard.zoom_on = (!zoom_off && blizzard.zoom_on) ||
550 (w < w_out || h < h_out);
551 560
552 for (i = 0; i < OMAPFB_PLANE_NUM; i++) { 561 for (i = 0; i < OMAPFB_PLANE_NUM; i++) {
553 struct plane_info *p = &blizzard.plane[i]; 562 struct plane_info *p = &blizzard.plane[i];
@@ -653,8 +662,49 @@ static int do_partial_update(struct blizzard_request *req, int plane,
653 else 662 else
654 disable_tearsync(); 663 disable_tearsync();
655 664
665 if ((gx2_out - gx1_out) != (gx2 - gx1) ||
666 (gy2_out - gy1_out) != (gy2 - gy1))
667 have_zoom_for_this_update = 1;
668
669 /* 'background' type of screen update (as opposed to 'destructive')
670 can be used to disable scaling if scaling is active */
671 zoom_off = blizzard.zoom_on && !have_zoom_for_this_update &&
672 (gx1_out == 0) && (gx2_out == blizzard.screen_width) &&
673 (gy1_out == 0) && (gy2_out == blizzard.screen_height) &&
674 (gx1 == 0) && (gy1 == 0);
675
676 if (blizzard.zoom_on && !have_zoom_for_this_update && !zoom_off &&
677 check_1d_intersect(blizzard.zoom_area_gx1, blizzard.zoom_area_gx2,
678 gx1_out, gx2_out) &&
679 check_1d_intersect(blizzard.zoom_area_gy1, blizzard.zoom_area_gy2,
680 gy1_out, gy2_out)) {
681 /* Previous screen update was using scaling, current update
682 * is not using it. Additionally, current screen update is
683 * going to overlap with the scaled area. Scaling needs to be
684 * disabled in order to avoid 'magnifying glass' effect.
685 * Dummy setup of background window can be used for this.
686 */
687 set_window_regs(0, 0, blizzard.screen_width,
688 blizzard.screen_height,
689 0, 0, blizzard.screen_width,
690 blizzard.screen_height,
691 BLIZZARD_COLOR_RGB565, 1, flags);
692 blizzard.zoom_on = 0;
693 }
694
695 /* remember scaling settings if we have scaled update */
696 if (have_zoom_for_this_update) {
697 blizzard.zoom_on = 1;
698 blizzard.zoom_area_gx1 = gx1_out;
699 blizzard.zoom_area_gx2 = gx2_out;
700 blizzard.zoom_area_gy1 = gy1_out;
701 blizzard.zoom_area_gy2 = gy2_out;
702 }
703
656 set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out, 704 set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out,
657 color_mode, zoom_off, flags); 705 color_mode, zoom_off, flags);
706 if (zoom_off)
707 blizzard.zoom_on = 0;
658 708
659 blizzard.extif->set_bits_per_cycle(16); 709 blizzard.extif->set_bits_per_cycle(16);
660 /* set_window_regs has left the register index at the right 710 /* set_window_regs has left the register index at the right
@@ -908,6 +958,35 @@ static int blizzard_set_scale(int plane, int orig_w, int orig_h,
908 return 0; 958 return 0;
909} 959}
910 960
961static int blizzard_set_rotate(int angle)
962{
963 u32 l;
964
965 l = blizzard_read_reg(BLIZZARD_PANEL_CONFIGURATION);
966 l &= ~0x03;
967
968 switch (angle) {
969 case 0:
970 l = l | 0x00;
971 break;
972 case 90:
973 l = l | 0x03;
974 break;
975 case 180:
976 l = l | 0x02;
977 break;
978 case 270:
979 l = l | 0x01;
980 break;
981 default:
982 return -EINVAL;
983 }
984
985 blizzard_write_reg(BLIZZARD_PANEL_CONFIGURATION, l);
986
987 return 0;
988}
989
911static int blizzard_enable_plane(int plane, int enable) 990static int blizzard_enable_plane(int plane, int enable)
912{ 991{
913 if (enable) 992 if (enable)
@@ -1285,7 +1364,8 @@ static void blizzard_get_caps(int plane, struct omapfb_caps *caps)
1285 caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE | 1364 caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE |
1286 OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE | 1365 OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE |
1287 OMAPFB_CAPS_WINDOW_SCALE | 1366 OMAPFB_CAPS_WINDOW_SCALE |
1288 OMAPFB_CAPS_WINDOW_OVERLAY; 1367 OMAPFB_CAPS_WINDOW_OVERLAY |
1368 OMAPFB_CAPS_WINDOW_ROTATE;
1289 if (blizzard.te_connected) 1369 if (blizzard.te_connected)
1290 caps->ctrl |= OMAPFB_CAPS_TEARSYNC; 1370 caps->ctrl |= OMAPFB_CAPS_TEARSYNC;
1291 caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) | 1371 caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) |
@@ -1560,6 +1640,7 @@ struct lcd_ctrl blizzard_ctrl = {
1560 .setup_plane = blizzard_setup_plane, 1640 .setup_plane = blizzard_setup_plane,
1561 .set_scale = blizzard_set_scale, 1641 .set_scale = blizzard_set_scale,
1562 .enable_plane = blizzard_enable_plane, 1642 .enable_plane = blizzard_enable_plane,
1643 .set_rotate = blizzard_set_rotate,
1563 .update_window = blizzard_update_window_async, 1644 .update_window = blizzard_update_window_async,
1564 .sync = blizzard_sync, 1645 .sync = blizzard_sync,
1565 .suspend = blizzard_suspend, 1646 .suspend = blizzard_suspend,
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 148cbcc39602..f16e42154229 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -155,6 +155,8 @@ struct resmap {
155 unsigned long *map; 155 unsigned long *map;
156}; 156};
157 157
158#define MAX_IRQ_HANDLERS 4
159
158static struct { 160static struct {
159 void __iomem *base; 161 void __iomem *base;
160 162
@@ -167,9 +169,11 @@ static struct {
167 169
168 int ext_mode; 170 int ext_mode;
169 171
170 unsigned long enabled_irqs; 172 struct {
171 void (*irq_callback)(void *); 173 u32 irq_mask;
172 void *irq_callback_data; 174 void (*callback)(void *);
175 void *data;
176 } irq_handlers[MAX_IRQ_HANDLERS];
173 struct completion frame_done; 177 struct completion frame_done;
174 178
175 int fir_hinc[OMAPFB_PLANE_NUM]; 179 int fir_hinc[OMAPFB_PLANE_NUM];
@@ -212,9 +216,9 @@ static void enable_rfbi_mode(int enable)
212 dispc_write_reg(DISPC_CONTROL, l); 216 dispc_write_reg(DISPC_CONTROL, l);
213 217
214 /* Set bypass mode in RFBI module */ 218 /* Set bypass mode in RFBI module */
215 l = __raw_readl(IO_ADDRESS(RFBI_CONTROL)); 219 l = __raw_readl(OMAP2_IO_ADDRESS(RFBI_CONTROL));
216 l |= enable ? 0 : (1 << 1); 220 l |= enable ? 0 : (1 << 1);
217 __raw_writel(l, IO_ADDRESS(RFBI_CONTROL)); 221 __raw_writel(l, OMAP2_IO_ADDRESS(RFBI_CONTROL));
218} 222}
219 223
220static void set_lcd_data_lines(int data_lines) 224static void set_lcd_data_lines(int data_lines)
@@ -286,7 +290,7 @@ static void setup_plane_fifo(int plane, int ext_mode)
286 BUG_ON(plane > 2); 290 BUG_ON(plane > 2);
287 291
288 l = dispc_read_reg(fsz_reg[plane]); 292 l = dispc_read_reg(fsz_reg[plane]);
289 l &= FLD_MASK(0, 9); 293 l &= FLD_MASK(0, 11);
290 if (ext_mode) { 294 if (ext_mode) {
291 low = l * 3 / 4; 295 low = l * 3 / 4;
292 high = l; 296 high = l;
@@ -294,7 +298,7 @@ static void setup_plane_fifo(int plane, int ext_mode)
294 low = l / 4; 298 low = l / 4;
295 high = l * 3 / 4; 299 high = l * 3 / 4;
296 } 300 }
297 MOD_REG_FLD(ftrs_reg[plane], FLD_MASK(16, 9) | FLD_MASK(0, 9), 301 MOD_REG_FLD(ftrs_reg[plane], FLD_MASK(16, 12) | FLD_MASK(0, 12),
298 (high << 16) | low); 302 (high << 16) | low);
299} 303}
300 304
@@ -809,57 +813,74 @@ static void set_lcd_timings(void)
809 panel->pixel_clock = fck / lck_div / pck_div / 1000; 813 panel->pixel_clock = fck / lck_div / pck_div / 1000;
810} 814}
811 815
812int omap_dispc_request_irq(void (*callback)(void *data), void *data) 816static void recalc_irq_mask(void)
813{ 817{
814 int r = 0; 818 int i;
819 unsigned long irq_mask = DISPC_IRQ_MASK_ERROR;
815 820
816 BUG_ON(callback == NULL); 821 for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
822 if (!dispc.irq_handlers[i].callback)
823 continue;
817 824
818 if (dispc.irq_callback) 825 irq_mask |= dispc.irq_handlers[i].irq_mask;
819 r = -EBUSY;
820 else {
821 dispc.irq_callback = callback;
822 dispc.irq_callback_data = data;
823 } 826 }
824 827
825 return r;
826}
827EXPORT_SYMBOL(omap_dispc_request_irq);
828
829void omap_dispc_enable_irqs(int irq_mask)
830{
831 enable_lcd_clocks(1); 828 enable_lcd_clocks(1);
832 dispc.enabled_irqs = irq_mask;
833 irq_mask |= DISPC_IRQ_MASK_ERROR;
834 MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask); 829 MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask);
835 enable_lcd_clocks(0); 830 enable_lcd_clocks(0);
836} 831}
837EXPORT_SYMBOL(omap_dispc_enable_irqs);
838 832
839void omap_dispc_disable_irqs(int irq_mask) 833int omap_dispc_request_irq(unsigned long irq_mask, void (*callback)(void *data),
834 void *data)
840{ 835{
841 enable_lcd_clocks(1); 836 int i;
842 dispc.enabled_irqs &= ~irq_mask; 837
843 irq_mask &= ~DISPC_IRQ_MASK_ERROR; 838 BUG_ON(callback == NULL);
844 MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask); 839
845 enable_lcd_clocks(0); 840 for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
841 if (dispc.irq_handlers[i].callback)
842 continue;
843
844 dispc.irq_handlers[i].irq_mask = irq_mask;
845 dispc.irq_handlers[i].callback = callback;
846 dispc.irq_handlers[i].data = data;
847 recalc_irq_mask();
848
849 return 0;
850 }
851
852 return -EBUSY;
846} 853}
847EXPORT_SYMBOL(omap_dispc_disable_irqs); 854EXPORT_SYMBOL(omap_dispc_request_irq);
848 855
849void omap_dispc_free_irq(void) 856void omap_dispc_free_irq(unsigned long irq_mask, void (*callback)(void *data),
857 void *data)
850{ 858{
851 enable_lcd_clocks(1); 859 int i;
852 omap_dispc_disable_irqs(DISPC_IRQ_MASK_ALL); 860
853 dispc.irq_callback = NULL; 861 for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
854 dispc.irq_callback_data = NULL; 862 if (dispc.irq_handlers[i].callback == callback &&
855 enable_lcd_clocks(0); 863 dispc.irq_handlers[i].data == data) {
864 dispc.irq_handlers[i].irq_mask = 0;
865 dispc.irq_handlers[i].callback = NULL;
866 dispc.irq_handlers[i].data = NULL;
867 recalc_irq_mask();
868 return;
869 }
870 }
871
872 BUG();
856} 873}
857EXPORT_SYMBOL(omap_dispc_free_irq); 874EXPORT_SYMBOL(omap_dispc_free_irq);
858 875
859static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) 876static irqreturn_t omap_dispc_irq_handler(int irq, void *dev)
860{ 877{
861 u32 stat = dispc_read_reg(DISPC_IRQSTATUS); 878 u32 stat;
879 int i = 0;
880
881 enable_lcd_clocks(1);
862 882
883 stat = dispc_read_reg(DISPC_IRQSTATUS);
863 if (stat & DISPC_IRQ_FRAMEMASK) 884 if (stat & DISPC_IRQ_FRAMEMASK)
864 complete(&dispc.frame_done); 885 complete(&dispc.frame_done);
865 886
@@ -870,11 +891,17 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev)
870 } 891 }
871 } 892 }
872 893
873 if ((stat & dispc.enabled_irqs) && dispc.irq_callback) 894 for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
874 dispc.irq_callback(dispc.irq_callback_data); 895 if (unlikely(dispc.irq_handlers[i].callback &&
896 (stat & dispc.irq_handlers[i].irq_mask)))
897 dispc.irq_handlers[i].callback(
898 dispc.irq_handlers[i].data);
899 }
875 900
876 dispc_write_reg(DISPC_IRQSTATUS, stat); 901 dispc_write_reg(DISPC_IRQSTATUS, stat);
877 902
903 enable_lcd_clocks(0);
904
878 return IRQ_HANDLED; 905 return IRQ_HANDLED;
879} 906}
880 907
@@ -913,18 +940,13 @@ static void put_dss_clocks(void)
913 940
914static void enable_lcd_clocks(int enable) 941static void enable_lcd_clocks(int enable)
915{ 942{
916 if (enable) 943 if (enable) {
944 clk_enable(dispc.dss_ick);
917 clk_enable(dispc.dss1_fck); 945 clk_enable(dispc.dss1_fck);
918 else 946 } else {
919 clk_disable(dispc.dss1_fck); 947 clk_disable(dispc.dss1_fck);
920}
921
922static void enable_interface_clocks(int enable)
923{
924 if (enable)
925 clk_enable(dispc.dss_ick);
926 else
927 clk_disable(dispc.dss_ick); 948 clk_disable(dispc.dss_ick);
949 }
928} 950}
929 951
930static void enable_digit_clocks(int enable) 952static void enable_digit_clocks(int enable)
@@ -1013,7 +1035,7 @@ static void mmap_user_close(struct vm_area_struct *vma)
1013 atomic_dec(&dispc.map_count[plane]); 1035 atomic_dec(&dispc.map_count[plane]);
1014} 1036}
1015 1037
1016static struct vm_operations_struct mmap_user_ops = { 1038static const struct vm_operations_struct mmap_user_ops = {
1017 .open = mmap_user_open, 1039 .open = mmap_user_open,
1018 .close = mmap_user_close, 1040 .close = mmap_user_close,
1019}; 1041};
@@ -1365,7 +1387,6 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
1365 if ((r = get_dss_clocks()) < 0) 1387 if ((r = get_dss_clocks()) < 0)
1366 goto fail0; 1388 goto fail0;
1367 1389
1368 enable_interface_clocks(1);
1369 enable_lcd_clocks(1); 1390 enable_lcd_clocks(1);
1370 1391
1371#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT 1392#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
@@ -1396,10 +1417,10 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
1396 enable_digit_clocks(0); 1417 enable_digit_clocks(0);
1397 } 1418 }
1398 1419
1399 /* Enable smart idle and autoidle */ 1420 /* Enable smart standby/idle, autoidle and wakeup */
1400 l = dispc_read_reg(DISPC_CONTROL); 1421 l = dispc_read_reg(DISPC_SYSCONFIG);
1401 l &= ~((3 << 12) | (3 << 3)); 1422 l &= ~((3 << 12) | (3 << 3));
1402 l |= (2 << 12) | (2 << 3) | (1 << 0); 1423 l |= (2 << 12) | (2 << 3) | (1 << 2) | (1 << 0);
1403 dispc_write_reg(DISPC_SYSCONFIG, l); 1424 dispc_write_reg(DISPC_SYSCONFIG, l);
1404 omap_writel(1 << 0, DSS_BASE + DSS_SYSCONFIG); 1425 omap_writel(1 << 0, DSS_BASE + DSS_SYSCONFIG);
1405 1426
@@ -1409,10 +1430,9 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
1409 dispc_write_reg(DISPC_CONFIG, l); 1430 dispc_write_reg(DISPC_CONFIG, l);
1410 1431
1411 l = dispc_read_reg(DISPC_IRQSTATUS); 1432 l = dispc_read_reg(DISPC_IRQSTATUS);
1412 dispc_write_reg(l, DISPC_IRQSTATUS); 1433 dispc_write_reg(DISPC_IRQSTATUS, l);
1413 1434
1414 /* Enable those that we handle always */ 1435 recalc_irq_mask();
1415 omap_dispc_enable_irqs(DISPC_IRQ_FRAMEMASK);
1416 1436
1417 if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler, 1437 if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler,
1418 0, MODULE_NAME, fbdev)) < 0) { 1438 0, MODULE_NAME, fbdev)) < 0) {
@@ -1421,7 +1441,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
1421 } 1441 }
1422 1442
1423 /* L3 firewall setting: enable access to OCM RAM */ 1443 /* L3 firewall setting: enable access to OCM RAM */
1424 __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0)); 1444 __raw_writel(0x402000b0, OMAP2_IO_ADDRESS(0x680050a0));
1425 1445
1426 if ((r = alloc_palette_ram()) < 0) 1446 if ((r = alloc_palette_ram()) < 0)
1427 goto fail2; 1447 goto fail2;
@@ -1469,7 +1489,6 @@ fail2:
1469 free_irq(INT_24XX_DSS_IRQ, fbdev); 1489 free_irq(INT_24XX_DSS_IRQ, fbdev);
1470fail1: 1490fail1:
1471 enable_lcd_clocks(0); 1491 enable_lcd_clocks(0);
1472 enable_interface_clocks(0);
1473 put_dss_clocks(); 1492 put_dss_clocks();
1474fail0: 1493fail0:
1475 iounmap(dispc.base); 1494 iounmap(dispc.base);
@@ -1487,7 +1506,6 @@ static void omap_dispc_cleanup(void)
1487 cleanup_fbmem(); 1506 cleanup_fbmem();
1488 free_palette_ram(); 1507 free_palette_ram();
1489 free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); 1508 free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
1490 enable_interface_clocks(0);
1491 put_dss_clocks(); 1509 put_dss_clocks();
1492 iounmap(dispc.base); 1510 iounmap(dispc.base);
1493} 1511}
diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h
index ef720a78f6d5..c15ea77f0604 100644
--- a/drivers/video/omap/dispc.h
+++ b/drivers/video/omap/dispc.h
@@ -37,9 +37,10 @@ extern void omap_dispc_set_lcd_size(int width, int height);
37extern void omap_dispc_enable_lcd_out(int enable); 37extern void omap_dispc_enable_lcd_out(int enable);
38extern void omap_dispc_enable_digit_out(int enable); 38extern void omap_dispc_enable_digit_out(int enable);
39 39
40extern int omap_dispc_request_irq(void (*callback)(void *data), void *data); 40extern int omap_dispc_request_irq(unsigned long irq_mask,
41extern void omap_dispc_free_irq(void); 41 void (*callback)(void *data), void *data);
42extern void omap_dispc_free_irq(unsigned long irq_mask,
43 void (*callback)(void *data), void *data);
42 44
43extern const struct lcd_ctrl omap2_int_ctrl; 45extern const struct lcd_ctrl omap2_int_ctrl;
44
45#endif 46#endif
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 5d4f34887a22..ca51583ec98a 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -131,7 +131,7 @@ struct {
131 131
132 struct omapfb_device *fbdev; 132 struct omapfb_device *fbdev;
133 struct lcd_ctrl_extif *extif; 133 struct lcd_ctrl_extif *extif;
134 struct lcd_ctrl *int_ctrl; 134 const struct lcd_ctrl *int_ctrl;
135 135
136 struct clk *sys_ck; 136 struct clk *sys_ck;
137} hwa742; 137} hwa742;
diff --git a/drivers/video/omap/lcd_2430sdp.c b/drivers/video/omap/lcd_2430sdp.c
new file mode 100644
index 000000000000..393712b6f369
--- /dev/null
+++ b/drivers/video/omap/lcd_2430sdp.c
@@ -0,0 +1,202 @@
1/*
2 * LCD panel support for the TI 2430SDP board
3 *
4 * Copyright (C) 2007 MontaVista
5 * Author: Hunyue Yau <hyau@mvista.com>
6 *
7 * Derived from drivers/video/omap/lcd-apollon.c
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 as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/delay.h>
27#include <linux/gpio.h>
28#include <linux/i2c/twl4030.h>
29
30#include <mach/mux.h>
31#include <mach/omapfb.h>
32#include <asm/mach-types.h>
33
34#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91
35#define SDP2430_LCD_PANEL_ENABLE_GPIO 154
36#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 24
37#define SDP3430_LCD_PANEL_ENABLE_GPIO 28
38
39static unsigned backlight_gpio;
40static unsigned enable_gpio;
41
42#define LCD_PIXCLOCK_MAX 5400 /* freq 5.4 MHz */
43#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
44#define ENABLE_VAUX2_DEDICATED 0x09
45#define ENABLE_VAUX2_DEV_GRP 0x20
46#define ENABLE_VAUX3_DEDICATED 0x03
47#define ENABLE_VAUX3_DEV_GRP 0x20
48
49#define ENABLE_VPLL2_DEDICATED 0x05
50#define ENABLE_VPLL2_DEV_GRP 0xE0
51#define TWL4030_VPLL2_DEV_GRP 0x33
52#define TWL4030_VPLL2_DEDICATED 0x36
53
54#define t2_out(c, r, v) twl4030_i2c_write_u8(c, r, v)
55
56
57static int sdp2430_panel_init(struct lcd_panel *panel,
58 struct omapfb_device *fbdev)
59{
60 if (machine_is_omap_3430sdp()) {
61 enable_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO;
62 backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
63 } else {
64 enable_gpio = SDP2430_LCD_PANEL_ENABLE_GPIO;
65 backlight_gpio = SDP2430_LCD_PANEL_BACKLIGHT_GPIO;
66 }
67
68 gpio_request(enable_gpio, "LCD enable"); /* LCD panel */
69 gpio_request(backlight_gpio, "LCD bl"); /* LCD backlight */
70 gpio_direction_output(enable_gpio, 0);
71 gpio_direction_output(backlight_gpio, 0);
72
73 return 0;
74}
75
76static void sdp2430_panel_cleanup(struct lcd_panel *panel)
77{
78 gpio_free(backlight_gpio);
79 gpio_free(enable_gpio);
80}
81
82static int sdp2430_panel_enable(struct lcd_panel *panel)
83{
84 u8 ded_val, ded_reg;
85 u8 grp_val, grp_reg;
86
87 if (machine_is_omap_3430sdp()) {
88 ded_reg = TWL4030_VAUX3_DEDICATED;
89 ded_val = ENABLE_VAUX3_DEDICATED;
90 grp_reg = TWL4030_VAUX3_DEV_GRP;
91 grp_val = ENABLE_VAUX3_DEV_GRP;
92
93 if (omap_rev() > OMAP3430_REV_ES1_0) {
94 t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
95 TWL4030_VPLL2_DEDICATED);
96 t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
97 TWL4030_VPLL2_DEV_GRP);
98 }
99 } else {
100 ded_reg = TWL4030_VAUX2_DEDICATED;
101 ded_val = ENABLE_VAUX2_DEDICATED;
102 grp_reg = TWL4030_VAUX2_DEV_GRP;
103 grp_val = ENABLE_VAUX2_DEV_GRP;
104 }
105
106 gpio_set_value(enable_gpio, 1);
107 gpio_set_value(backlight_gpio, 1);
108
109 if (0 != t2_out(PM_RECEIVER, ded_val, ded_reg))
110 return -EIO;
111 if (0 != t2_out(PM_RECEIVER, grp_val, grp_reg))
112 return -EIO;
113
114 return 0;
115}
116
117static void sdp2430_panel_disable(struct lcd_panel *panel)
118{
119 gpio_set_value(enable_gpio, 0);
120 gpio_set_value(backlight_gpio, 0);
121 if (omap_rev() > OMAP3430_REV_ES1_0) {
122 t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
123 t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
124 msleep(4);
125 }
126}
127
128static unsigned long sdp2430_panel_get_caps(struct lcd_panel *panel)
129{
130 return 0;
131}
132
133struct lcd_panel sdp2430_panel = {
134 .name = "sdp2430",
135 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
136 OMAP_LCDC_INV_HSYNC,
137
138 .bpp = 16,
139 .data_lines = 16,
140 .x_res = 240,
141 .y_res = 320,
142 .hsw = 3, /* hsync_len (4) - 1 */
143 .hfp = 3, /* right_margin (4) - 1 */
144 .hbp = 39, /* left_margin (40) - 1 */
145 .vsw = 1, /* vsync_len (2) - 1 */
146 .vfp = 2, /* lower_margin */
147 .vbp = 7, /* upper_margin (8) - 1 */
148
149 .pixel_clock = LCD_PIXCLOCK_MAX,
150
151 .init = sdp2430_panel_init,
152 .cleanup = sdp2430_panel_cleanup,
153 .enable = sdp2430_panel_enable,
154 .disable = sdp2430_panel_disable,
155 .get_caps = sdp2430_panel_get_caps,
156};
157
158static int sdp2430_panel_probe(struct platform_device *pdev)
159{
160 omapfb_register_panel(&sdp2430_panel);
161 return 0;
162}
163
164static int sdp2430_panel_remove(struct platform_device *pdev)
165{
166 return 0;
167}
168
169static int sdp2430_panel_suspend(struct platform_device *pdev,
170 pm_message_t mesg)
171{
172 return 0;
173}
174
175static int sdp2430_panel_resume(struct platform_device *pdev)
176{
177 return 0;
178}
179
180struct platform_driver sdp2430_panel_driver = {
181 .probe = sdp2430_panel_probe,
182 .remove = sdp2430_panel_remove,
183 .suspend = sdp2430_panel_suspend,
184 .resume = sdp2430_panel_resume,
185 .driver = {
186 .name = "sdp2430_lcd",
187 .owner = THIS_MODULE,
188 },
189};
190
191static int __init sdp2430_panel_drv_init(void)
192{
193 return platform_driver_register(&sdp2430_panel_driver);
194}
195
196static void __exit sdp2430_panel_drv_exit(void)
197{
198 platform_driver_unregister(&sdp2430_panel_driver);
199}
200
201module_init(sdp2430_panel_drv_init);
202module_exit(sdp2430_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
new file mode 100644
index 000000000000..1f7439955e02
--- /dev/null
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -0,0 +1,137 @@
1/*
2 * Based on drivers/video/omap/lcd_inn1510.c
3 *
4 * LCD panel support for the Amstrad E3 (Delta) videophone.
5 *
6 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
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/module.h>
24#include <linux/platform_device.h>
25#include <linux/io.h>
26#include <linux/delay.h>
27
28#include <mach/board-ams-delta.h>
29#include <mach/hardware.h>
30#include <mach/omapfb.h>
31
32#define AMS_DELTA_DEFAULT_CONTRAST 112
33
34static int ams_delta_panel_init(struct lcd_panel *panel,
35 struct omapfb_device *fbdev)
36{
37 return 0;
38}
39
40static void ams_delta_panel_cleanup(struct lcd_panel *panel)
41{
42}
43
44static int ams_delta_panel_enable(struct lcd_panel *panel)
45{
46 ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP,
47 AMS_DELTA_LATCH2_LCD_NDISP);
48 ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN,
49 AMS_DELTA_LATCH2_LCD_VBLEN);
50
51 omap_writeb(1, OMAP_PWL_CLK_ENABLE);
52 omap_writeb(AMS_DELTA_DEFAULT_CONTRAST, OMAP_PWL_ENABLE);
53
54 return 0;
55}
56
57static void ams_delta_panel_disable(struct lcd_panel *panel)
58{
59 ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, 0);
60 ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP, 0);
61}
62
63static unsigned long ams_delta_panel_get_caps(struct lcd_panel *panel)
64{
65 return 0;
66}
67
68static struct lcd_panel ams_delta_panel = {
69 .name = "ams-delta",
70 .config = 0,
71
72 .bpp = 12,
73 .data_lines = 16,
74 .x_res = 480,
75 .y_res = 320,
76 .pixel_clock = 4687,
77 .hsw = 3,
78 .hfp = 1,
79 .hbp = 1,
80 .vsw = 1,
81 .vfp = 0,
82 .vbp = 0,
83 .pcd = 0,
84 .acb = 37,
85
86 .init = ams_delta_panel_init,
87 .cleanup = ams_delta_panel_cleanup,
88 .enable = ams_delta_panel_enable,
89 .disable = ams_delta_panel_disable,
90 .get_caps = ams_delta_panel_get_caps,
91};
92
93static int ams_delta_panel_probe(struct platform_device *pdev)
94{
95 omapfb_register_panel(&ams_delta_panel);
96 return 0;
97}
98
99static int ams_delta_panel_remove(struct platform_device *pdev)
100{
101 return 0;
102}
103
104static int ams_delta_panel_suspend(struct platform_device *pdev,
105 pm_message_t mesg)
106{
107 return 0;
108}
109
110static int ams_delta_panel_resume(struct platform_device *pdev)
111{
112 return 0;
113}
114
115struct platform_driver ams_delta_panel_driver = {
116 .probe = ams_delta_panel_probe,
117 .remove = ams_delta_panel_remove,
118 .suspend = ams_delta_panel_suspend,
119 .resume = ams_delta_panel_resume,
120 .driver = {
121 .name = "lcd_ams_delta",
122 .owner = THIS_MODULE,
123 },
124};
125
126static int ams_delta_panel_drv_init(void)
127{
128 return platform_driver_register(&ams_delta_panel_driver);
129}
130
131static void ams_delta_panel_drv_cleanup(void)
132{
133 platform_driver_unregister(&ams_delta_panel_driver);
134}
135
136module_init(ams_delta_panel_drv_init);
137module_exit(ams_delta_panel_drv_cleanup);
diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c
new file mode 100644
index 000000000000..626ae3a532ff
--- /dev/null
+++ b/drivers/video/omap/lcd_apollon.c
@@ -0,0 +1,138 @@
1/*
2 * LCD panel support for the Samsung OMAP2 Apollon board
3 *
4 * Copyright (C) 2005,2006 Samsung Electronics
5 * Author: Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * Derived from drivers/video/omap/lcd-h4.c
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 as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26
27#include <mach/gpio.h>
28#include <mach/mux.h>
29#include <mach/omapfb.h>
30
31/* #define USE_35INCH_LCD 1 */
32
33static int apollon_panel_init(struct lcd_panel *panel,
34 struct omapfb_device *fbdev)
35{
36 /* configure LCD PWR_EN */
37 omap_cfg_reg(M21_242X_GPIO11);
38 return 0;
39}
40
41static void apollon_panel_cleanup(struct lcd_panel *panel)
42{
43}
44
45static int apollon_panel_enable(struct lcd_panel *panel)
46{
47 return 0;
48}
49
50static void apollon_panel_disable(struct lcd_panel *panel)
51{
52}
53
54static unsigned long apollon_panel_get_caps(struct lcd_panel *panel)
55{
56 return 0;
57}
58
59struct lcd_panel apollon_panel = {
60 .name = "apollon",
61 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
62 OMAP_LCDC_INV_HSYNC,
63
64 .bpp = 16,
65 .data_lines = 18,
66#ifdef USE_35INCH_LCD
67 .x_res = 240,
68 .y_res = 320,
69 .hsw = 2,
70 .hfp = 3,
71 .hbp = 9,
72 .vsw = 4,
73 .vfp = 3,
74 .vbp = 5,
75#else
76 .x_res = 480,
77 .y_res = 272,
78 .hsw = 41,
79 .hfp = 2,
80 .hbp = 2,
81 .vsw = 10,
82 .vfp = 2,
83 .vbp = 2,
84#endif
85 .pixel_clock = 6250,
86
87 .init = apollon_panel_init,
88 .cleanup = apollon_panel_cleanup,
89 .enable = apollon_panel_enable,
90 .disable = apollon_panel_disable,
91 .get_caps = apollon_panel_get_caps,
92};
93
94static int apollon_panel_probe(struct platform_device *pdev)
95{
96 omapfb_register_panel(&apollon_panel);
97 return 0;
98}
99
100static int apollon_panel_remove(struct platform_device *pdev)
101{
102 return 0;
103}
104
105static int apollon_panel_suspend(struct platform_device *pdev,
106 pm_message_t mesg)
107{
108 return 0;
109}
110
111static int apollon_panel_resume(struct platform_device *pdev)
112{
113 return 0;
114}
115
116struct platform_driver apollon_panel_driver = {
117 .probe = apollon_panel_probe,
118 .remove = apollon_panel_remove,
119 .suspend = apollon_panel_suspend,
120 .resume = apollon_panel_resume,
121 .driver = {
122 .name = "apollon_lcd",
123 .owner = THIS_MODULE,
124 },
125};
126
127static int __init apollon_panel_drv_init(void)
128{
129 return platform_driver_register(&apollon_panel_driver);
130}
131
132static void __exit apollon_panel_drv_exit(void)
133{
134 platform_driver_unregister(&apollon_panel_driver);
135}
136
137module_init(apollon_panel_drv_init);
138module_exit(apollon_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c
index 2486237ebba5..417ae5efa8bb 100644
--- a/drivers/video/omap/lcd_h3.c
+++ b/drivers/video/omap/lcd_h3.c
@@ -124,12 +124,12 @@ struct platform_driver h3_panel_driver = {
124 }, 124 },
125}; 125};
126 126
127static int h3_panel_drv_init(void) 127static int __init h3_panel_drv_init(void)
128{ 128{
129 return platform_driver_register(&h3_panel_driver); 129 return platform_driver_register(&h3_panel_driver);
130} 130}
131 131
132static void h3_panel_drv_cleanup(void) 132static void __exit h3_panel_drv_cleanup(void)
133{ 133{
134 platform_driver_unregister(&h3_panel_driver); 134 platform_driver_unregister(&h3_panel_driver);
135} 135}
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c
index 6ff56430341b..0c398bda7601 100644
--- a/drivers/video/omap/lcd_h4.c
+++ b/drivers/video/omap/lcd_h4.c
@@ -102,12 +102,12 @@ static struct platform_driver h4_panel_driver = {
102 }, 102 },
103}; 103};
104 104
105static int h4_panel_drv_init(void) 105static int __init h4_panel_drv_init(void)
106{ 106{
107 return platform_driver_register(&h4_panel_driver); 107 return platform_driver_register(&h4_panel_driver);
108} 108}
109 109
110static void h4_panel_drv_cleanup(void) 110static void __exit h4_panel_drv_cleanup(void)
111{ 111{
112 platform_driver_unregister(&h4_panel_driver); 112 platform_driver_unregister(&h4_panel_driver);
113} 113}
diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c
index 6953ed4b5820..cdbd8bb607be 100644
--- a/drivers/video/omap/lcd_inn1510.c
+++ b/drivers/video/omap/lcd_inn1510.c
@@ -109,12 +109,12 @@ struct platform_driver innovator1510_panel_driver = {
109 }, 109 },
110}; 110};
111 111
112static int innovator1510_panel_drv_init(void) 112static int __init innovator1510_panel_drv_init(void)
113{ 113{
114 return platform_driver_register(&innovator1510_panel_driver); 114 return platform_driver_register(&innovator1510_panel_driver);
115} 115}
116 116
117static void innovator1510_panel_drv_cleanup(void) 117static void __exit innovator1510_panel_drv_cleanup(void)
118{ 118{
119 platform_driver_unregister(&innovator1510_panel_driver); 119 platform_driver_unregister(&innovator1510_panel_driver);
120} 120}
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
index 4c4f7ee6d733..268f7f808a4e 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/omap/lcd_inn1610.c
@@ -133,12 +133,12 @@ struct platform_driver innovator1610_panel_driver = {
133 }, 133 },
134}; 134};
135 135
136static int innovator1610_panel_drv_init(void) 136static int __init innovator1610_panel_drv_init(void)
137{ 137{
138 return platform_driver_register(&innovator1610_panel_driver); 138 return platform_driver_register(&innovator1610_panel_driver);
139} 139}
140 140
141static void innovator1610_panel_drv_cleanup(void) 141static void __exit innovator1610_panel_drv_cleanup(void)
142{ 142{
143 platform_driver_unregister(&innovator1610_panel_driver); 143 platform_driver_unregister(&innovator1610_panel_driver);
144} 144}
diff --git a/drivers/video/omap/lcd_ldp.c b/drivers/video/omap/lcd_ldp.c
new file mode 100644
index 000000000000..dbfe8974fb94
--- /dev/null
+++ b/drivers/video/omap/lcd_ldp.c
@@ -0,0 +1,200 @@
1/*
2 * LCD panel support for the TI LDP board
3 *
4 * Copyright (C) 2007 WindRiver
5 * Author: Stanley Miao <stanley.miao@windriver.com>
6 *
7 * Derived from drivers/video/omap/lcd-2430sdp.c
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 as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/delay.h>
27#include <linux/i2c/twl4030.h>
28
29#include <mach/gpio.h>
30#include <mach/mux.h>
31#include <mach/omapfb.h>
32#include <asm/mach-types.h>
33
34#define LCD_PANEL_BACKLIGHT_GPIO (15 + OMAP_MAX_GPIO_LINES)
35#define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES)
36
37#define LCD_PANEL_RESET_GPIO 55
38#define LCD_PANEL_QVGA_GPIO 56
39
40#ifdef CONFIG_FB_OMAP_LCD_VGA
41#define LCD_XRES 480
42#define LCD_YRES 640
43#define LCD_PIXCLOCK_MAX 41700
44#else
45#define LCD_XRES 240
46#define LCD_YRES 320
47#define LCD_PIXCLOCK_MAX 185186
48#endif
49
50#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
51#define ENABLE_VAUX2_DEDICATED 0x09
52#define ENABLE_VAUX2_DEV_GRP 0x20
53#define ENABLE_VAUX3_DEDICATED 0x03
54#define ENABLE_VAUX3_DEV_GRP 0x20
55
56#define ENABLE_VPLL2_DEDICATED 0x05
57#define ENABLE_VPLL2_DEV_GRP 0xE0
58#define TWL4030_VPLL2_DEV_GRP 0x33
59#define TWL4030_VPLL2_DEDICATED 0x36
60
61#define t2_out(c, r, v) twl4030_i2c_write_u8(c, r, v)
62
63
64static int ldp_panel_init(struct lcd_panel *panel,
65 struct omapfb_device *fbdev)
66{
67 gpio_request(LCD_PANEL_RESET_GPIO, "lcd reset");
68 gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga");
69 gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd panel");
70 gpio_request(LCD_PANEL_BACKLIGHT_GPIO, "lcd backlight");
71
72 gpio_direction_output(LCD_PANEL_QVGA_GPIO, 0);
73 gpio_direction_output(LCD_PANEL_RESET_GPIO, 0);
74 gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
75 gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
76
77#ifdef CONFIG_FB_OMAP_LCD_VGA
78 gpio_set_value(LCD_PANEL_QVGA_GPIO, 0);
79#else
80 gpio_set_value(LCD_PANEL_QVGA_GPIO, 1);
81#endif
82 gpio_set_value(LCD_PANEL_RESET_GPIO, 1);
83
84 return 0;
85}
86
87static void ldp_panel_cleanup(struct lcd_panel *panel)
88{
89 gpio_free(LCD_PANEL_BACKLIGHT_GPIO);
90 gpio_free(LCD_PANEL_ENABLE_GPIO);
91 gpio_free(LCD_PANEL_QVGA_GPIO);
92 gpio_free(LCD_PANEL_RESET_GPIO);
93}
94
95static int ldp_panel_enable(struct lcd_panel *panel)
96{
97 if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
98 TWL4030_VPLL2_DEDICATED))
99 return -EIO;
100 if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
101 TWL4030_VPLL2_DEV_GRP))
102 return -EIO;
103
104 gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
105 gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 1);
106
107 if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEDICATED,
108 TWL4030_VAUX3_DEDICATED))
109 return -EIO;
110 if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEV_GRP,
111 TWL4030_VAUX3_DEV_GRP))
112 return -EIO;
113
114 return 0;
115}
116
117static void ldp_panel_disable(struct lcd_panel *panel)
118{
119 gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
120 gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
121
122 t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
123 t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
124 msleep(4);
125}
126
127static unsigned long ldp_panel_get_caps(struct lcd_panel *panel)
128{
129 return 0;
130}
131
132struct lcd_panel ldp_panel = {
133 .name = "ldp",
134 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
135 OMAP_LCDC_INV_HSYNC,
136
137 .bpp = 16,
138 .data_lines = 18,
139 .x_res = LCD_XRES,
140 .y_res = LCD_YRES,
141 .hsw = 3, /* hsync_len (4) - 1 */
142 .hfp = 3, /* right_margin (4) - 1 */
143 .hbp = 39, /* left_margin (40) - 1 */
144 .vsw = 1, /* vsync_len (2) - 1 */
145 .vfp = 2, /* lower_margin */
146 .vbp = 7, /* upper_margin (8) - 1 */
147
148 .pixel_clock = LCD_PIXCLOCK_MAX,
149
150 .init = ldp_panel_init,
151 .cleanup = ldp_panel_cleanup,
152 .enable = ldp_panel_enable,
153 .disable = ldp_panel_disable,
154 .get_caps = ldp_panel_get_caps,
155};
156
157static int ldp_panel_probe(struct platform_device *pdev)
158{
159 omapfb_register_panel(&ldp_panel);
160 return 0;
161}
162
163static int ldp_panel_remove(struct platform_device *pdev)
164{
165 return 0;
166}
167
168static int ldp_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
169{
170 return 0;
171}
172
173static int ldp_panel_resume(struct platform_device *pdev)
174{
175 return 0;
176}
177
178struct platform_driver ldp_panel_driver = {
179 .probe = ldp_panel_probe,
180 .remove = ldp_panel_remove,
181 .suspend = ldp_panel_suspend,
182 .resume = ldp_panel_resume,
183 .driver = {
184 .name = "ldp_lcd",
185 .owner = THIS_MODULE,
186 },
187};
188
189static int __init ldp_panel_drv_init(void)
190{
191 return platform_driver_register(&ldp_panel_driver);
192}
193
194static void __exit ldp_panel_drv_exit(void)
195{
196 platform_driver_unregister(&ldp_panel_driver);
197}
198
199module_init(ldp_panel_drv_init);
200module_exit(ldp_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c
new file mode 100644
index 000000000000..918ee8934196
--- /dev/null
+++ b/drivers/video/omap/lcd_mipid.c
@@ -0,0 +1,625 @@
1/*
2 * LCD driver for MIPI DBI-C / DCS compatible LCDs
3 *
4 * Copyright (C) 2006 Nokia Corporation
5 * Author: Imre Deak <imre.deak@nokia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#include <linux/device.h>
22#include <linux/delay.h>
23#include <linux/workqueue.h>
24#include <linux/spi/spi.h>
25
26#include <mach/omapfb.h>
27#include <mach/lcd_mipid.h>
28
29#define MIPID_MODULE_NAME "lcd_mipid"
30
31#define MIPID_CMD_READ_DISP_ID 0x04
32#define MIPID_CMD_READ_RED 0x06
33#define MIPID_CMD_READ_GREEN 0x07
34#define MIPID_CMD_READ_BLUE 0x08
35#define MIPID_CMD_READ_DISP_STATUS 0x09
36#define MIPID_CMD_RDDSDR 0x0F
37#define MIPID_CMD_SLEEP_IN 0x10
38#define MIPID_CMD_SLEEP_OUT 0x11
39#define MIPID_CMD_DISP_OFF 0x28
40#define MIPID_CMD_DISP_ON 0x29
41
42#define MIPID_ESD_CHECK_PERIOD msecs_to_jiffies(5000)
43
44#define to_mipid_device(p) container_of(p, struct mipid_device, \
45 panel)
46struct mipid_device {
47 int enabled;
48 int revision;
49 unsigned int saved_bklight_level;
50 unsigned long hw_guard_end; /* next value of jiffies
51 when we can issue the
52 next sleep in/out command */
53 unsigned long hw_guard_wait; /* max guard time in jiffies */
54
55 struct omapfb_device *fbdev;
56 struct spi_device *spi;
57 struct mutex mutex;
58 struct lcd_panel panel;
59
60 struct workqueue_struct *esd_wq;
61 struct delayed_work esd_work;
62 void (*esd_check)(struct mipid_device *m);
63};
64
65static void mipid_transfer(struct mipid_device *md, int cmd, const u8 *wbuf,
66 int wlen, u8 *rbuf, int rlen)
67{
68 struct spi_message m;
69 struct spi_transfer *x, xfer[4];
70 u16 w;
71 int r;
72
73 BUG_ON(md->spi == NULL);
74
75 spi_message_init(&m);
76
77 memset(xfer, 0, sizeof(xfer));
78 x = &xfer[0];
79
80 cmd &= 0xff;
81 x->tx_buf = &cmd;
82 x->bits_per_word = 9;
83 x->len = 2;
84 spi_message_add_tail(x, &m);
85
86 if (wlen) {
87 x++;
88 x->tx_buf = wbuf;
89 x->len = wlen;
90 x->bits_per_word = 9;
91 spi_message_add_tail(x, &m);
92 }
93
94 if (rlen) {
95 x++;
96 x->rx_buf = &w;
97 x->len = 1;
98 spi_message_add_tail(x, &m);
99
100 if (rlen > 1) {
101 /* Arrange for the extra clock before the first
102 * data bit.
103 */
104 x->bits_per_word = 9;
105 x->len = 2;
106
107 x++;
108 x->rx_buf = &rbuf[1];
109 x->len = rlen - 1;
110 spi_message_add_tail(x, &m);
111 }
112 }
113
114 r = spi_sync(md->spi, &m);
115 if (r < 0)
116 dev_dbg(&md->spi->dev, "spi_sync %d\n", r);
117
118 if (rlen)
119 rbuf[0] = w & 0xff;
120}
121
122static inline void mipid_cmd(struct mipid_device *md, int cmd)
123{
124 mipid_transfer(md, cmd, NULL, 0, NULL, 0);
125}
126
127static inline void mipid_write(struct mipid_device *md,
128 int reg, const u8 *buf, int len)
129{
130 mipid_transfer(md, reg, buf, len, NULL, 0);
131}
132
133static inline void mipid_read(struct mipid_device *md,
134 int reg, u8 *buf, int len)
135{
136 mipid_transfer(md, reg, NULL, 0, buf, len);
137}
138
139static void set_data_lines(struct mipid_device *md, int data_lines)
140{
141 u16 par;
142
143 switch (data_lines) {
144 case 16:
145 par = 0x150;
146 break;
147 case 18:
148 par = 0x160;
149 break;
150 case 24:
151 par = 0x170;
152 break;
153 }
154 mipid_write(md, 0x3a, (u8 *)&par, 2);
155}
156
157static void send_init_string(struct mipid_device *md)
158{
159 u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
160
161 mipid_write(md, 0xc2, (u8 *)initpar, sizeof(initpar));
162 set_data_lines(md, md->panel.data_lines);
163}
164
165static void hw_guard_start(struct mipid_device *md, int guard_msec)
166{
167 md->hw_guard_wait = msecs_to_jiffies(guard_msec);
168 md->hw_guard_end = jiffies + md->hw_guard_wait;
169}
170
171static void hw_guard_wait(struct mipid_device *md)
172{
173 unsigned long wait = md->hw_guard_end - jiffies;
174
175 if ((long)wait > 0 && wait <= md->hw_guard_wait) {
176 set_current_state(TASK_UNINTERRUPTIBLE);
177 schedule_timeout(wait);
178 }
179}
180
181static void set_sleep_mode(struct mipid_device *md, int on)
182{
183 int cmd, sleep_time = 50;
184
185 if (on)
186 cmd = MIPID_CMD_SLEEP_IN;
187 else
188 cmd = MIPID_CMD_SLEEP_OUT;
189 hw_guard_wait(md);
190 mipid_cmd(md, cmd);
191 hw_guard_start(md, 120);
192 /*
193 * When we enable the panel, it seems we _have_ to sleep
194 * 120 ms before sending the init string. When disabling the
195 * panel we'll sleep for the duration of 2 frames, so that the
196 * controller can still provide the PCLK,HS,VS signals.
197 */
198 if (!on)
199 sleep_time = 120;
200 msleep(sleep_time);
201}
202
203static void set_display_state(struct mipid_device *md, int enabled)
204{
205 int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF;
206
207 mipid_cmd(md, cmd);
208}
209
210static int mipid_set_bklight_level(struct lcd_panel *panel, unsigned int level)
211{
212 struct mipid_device *md = to_mipid_device(panel);
213 struct mipid_platform_data *pd = md->spi->dev.platform_data;
214
215 if (pd->get_bklight_max == NULL || pd->set_bklight_level == NULL)
216 return -ENODEV;
217 if (level > pd->get_bklight_max(pd))
218 return -EINVAL;
219 if (!md->enabled) {
220 md->saved_bklight_level = level;
221 return 0;
222 }
223 pd->set_bklight_level(pd, level);
224
225 return 0;
226}
227
228static unsigned int mipid_get_bklight_level(struct lcd_panel *panel)
229{
230 struct mipid_device *md = to_mipid_device(panel);
231 struct mipid_platform_data *pd = md->spi->dev.platform_data;
232
233 if (pd->get_bklight_level == NULL)
234 return -ENODEV;
235 return pd->get_bklight_level(pd);
236}
237
238static unsigned int mipid_get_bklight_max(struct lcd_panel *panel)
239{
240 struct mipid_device *md = to_mipid_device(panel);
241 struct mipid_platform_data *pd = md->spi->dev.platform_data;
242
243 if (pd->get_bklight_max == NULL)
244 return -ENODEV;
245
246 return pd->get_bklight_max(pd);
247}
248
249static unsigned long mipid_get_caps(struct lcd_panel *panel)
250{
251 return OMAPFB_CAPS_SET_BACKLIGHT;
252}
253
254static u16 read_first_pixel(struct mipid_device *md)
255{
256 u16 pixel;
257 u8 red, green, blue;
258
259 mutex_lock(&md->mutex);
260 mipid_read(md, MIPID_CMD_READ_RED, &red, 1);
261 mipid_read(md, MIPID_CMD_READ_GREEN, &green, 1);
262 mipid_read(md, MIPID_CMD_READ_BLUE, &blue, 1);
263 mutex_unlock(&md->mutex);
264
265 switch (md->panel.data_lines) {
266 case 16:
267 pixel = ((red >> 1) << 11) | (green << 5) | (blue >> 1);
268 break;
269 case 24:
270 /* 24 bit -> 16 bit */
271 pixel = ((red >> 3) << 11) | ((green >> 2) << 5) |
272 (blue >> 3);
273 break;
274 default:
275 pixel = 0;
276 BUG();
277 }
278
279 return pixel;
280}
281
282static int mipid_run_test(struct lcd_panel *panel, int test_num)
283{
284 struct mipid_device *md = to_mipid_device(panel);
285 static const u16 test_values[4] = {
286 0x0000, 0xffff, 0xaaaa, 0x5555,
287 };
288 int i;
289
290 if (test_num != MIPID_TEST_RGB_LINES)
291 return MIPID_TEST_INVALID;
292
293 for (i = 0; i < ARRAY_SIZE(test_values); i++) {
294 int delay;
295 unsigned long tmo;
296
297 omapfb_write_first_pixel(md->fbdev, test_values[i]);
298 tmo = jiffies + msecs_to_jiffies(100);
299 delay = 25;
300 while (1) {
301 u16 pixel;
302
303 msleep(delay);
304 pixel = read_first_pixel(md);
305 if (pixel == test_values[i])
306 break;
307 if (time_after(jiffies, tmo)) {
308 dev_err(&md->spi->dev,
309 "MIPI LCD RGB I/F test failed: "
310 "expecting %04x, got %04x\n",
311 test_values[i], pixel);
312 return MIPID_TEST_FAILED;
313 }
314 delay = 10;
315 }
316 }
317
318 return 0;
319}
320
321static void ls041y3_esd_recover(struct mipid_device *md)
322{
323 dev_err(&md->spi->dev, "performing LCD ESD recovery\n");
324 set_sleep_mode(md, 1);
325 set_sleep_mode(md, 0);
326}
327
328static void ls041y3_esd_check_mode1(struct mipid_device *md)
329{
330 u8 state1, state2;
331
332 mipid_read(md, MIPID_CMD_RDDSDR, &state1, 1);
333 set_sleep_mode(md, 0);
334 mipid_read(md, MIPID_CMD_RDDSDR, &state2, 1);
335 dev_dbg(&md->spi->dev, "ESD mode 1 state1 %02x state2 %02x\n",
336 state1, state2);
337 /* Each sleep out command will trigger a self diagnostic and flip
338 * Bit6 if the test passes.
339 */
340 if (!((state1 ^ state2) & (1 << 6)))
341 ls041y3_esd_recover(md);
342}
343
344static void ls041y3_esd_check_mode2(struct mipid_device *md)
345{
346 int i;
347 u8 rbuf[2];
348 static const struct {
349 int cmd;
350 int wlen;
351 u16 wbuf[3];
352 } *rd, rd_ctrl[7] = {
353 { 0xb0, 4, { 0x0101, 0x01fe, } },
354 { 0xb1, 4, { 0x01de, 0x0121, } },
355 { 0xc2, 4, { 0x0100, 0x0100, } },
356 { 0xbd, 2, { 0x0100, } },
357 { 0xc2, 4, { 0x01fc, 0x0103, } },
358 { 0xb4, 0, },
359 { 0x00, 0, },
360 };
361
362 rd = rd_ctrl;
363 for (i = 0; i < 3; i++, rd++)
364 mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen);
365
366 udelay(10);
367 mipid_read(md, rd->cmd, rbuf, 2);
368 rd++;
369
370 for (i = 0; i < 3; i++, rd++) {
371 udelay(10);
372 mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen);
373 }
374
375 dev_dbg(&md->spi->dev, "ESD mode 2 state %02x\n", rbuf[1]);
376 if (rbuf[1] == 0x00)
377 ls041y3_esd_recover(md);
378}
379
380static void ls041y3_esd_check(struct mipid_device *md)
381{
382 ls041y3_esd_check_mode1(md);
383 if (md->revision >= 0x88)
384 ls041y3_esd_check_mode2(md);
385}
386
387static void mipid_esd_start_check(struct mipid_device *md)
388{
389 if (md->esd_check != NULL)
390 queue_delayed_work(md->esd_wq, &md->esd_work,
391 MIPID_ESD_CHECK_PERIOD);
392}
393
394static void mipid_esd_stop_check(struct mipid_device *md)
395{
396 if (md->esd_check != NULL)
397 cancel_rearming_delayed_workqueue(md->esd_wq, &md->esd_work);
398}
399
400static void mipid_esd_work(struct work_struct *work)
401{
402 struct mipid_device *md = container_of(work, struct mipid_device,
403 esd_work.work);
404
405 mutex_lock(&md->mutex);
406 md->esd_check(md);
407 mutex_unlock(&md->mutex);
408 mipid_esd_start_check(md);
409}
410
411static int mipid_enable(struct lcd_panel *panel)
412{
413 struct mipid_device *md = to_mipid_device(panel);
414
415 mutex_lock(&md->mutex);
416
417 if (md->enabled) {
418 mutex_unlock(&md->mutex);
419 return 0;
420 }
421 set_sleep_mode(md, 0);
422 md->enabled = 1;
423 send_init_string(md);
424 set_display_state(md, 1);
425 mipid_set_bklight_level(panel, md->saved_bklight_level);
426 mipid_esd_start_check(md);
427
428 mutex_unlock(&md->mutex);
429 return 0;
430}
431
432static void mipid_disable(struct lcd_panel *panel)
433{
434 struct mipid_device *md = to_mipid_device(panel);
435
436 /*
437 * A final ESD work might be called before returning,
438 * so do this without holding the lock.
439 */
440 mipid_esd_stop_check(md);
441 mutex_lock(&md->mutex);
442
443 if (!md->enabled) {
444 mutex_unlock(&md->mutex);
445 return;
446 }
447 md->saved_bklight_level = mipid_get_bklight_level(panel);
448 mipid_set_bklight_level(panel, 0);
449 set_display_state(md, 0);
450 set_sleep_mode(md, 1);
451 md->enabled = 0;
452
453 mutex_unlock(&md->mutex);
454}
455
456static int panel_enabled(struct mipid_device *md)
457{
458 u32 disp_status;
459 int enabled;
460
461 mipid_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4);
462 disp_status = __be32_to_cpu(disp_status);
463 enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10));
464 dev_dbg(&md->spi->dev,
465 "LCD panel %senabled by bootloader (status 0x%04x)\n",
466 enabled ? "" : "not ", disp_status);
467 return enabled;
468}
469
470static int mipid_init(struct lcd_panel *panel,
471 struct omapfb_device *fbdev)
472{
473 struct mipid_device *md = to_mipid_device(panel);
474
475 md->fbdev = fbdev;
476 md->esd_wq = create_singlethread_workqueue("mipid_esd");
477 if (md->esd_wq == NULL) {
478 dev_err(&md->spi->dev, "can't create ESD workqueue\n");
479 return -ENOMEM;
480 }
481 INIT_DELAYED_WORK(&md->esd_work, mipid_esd_work);
482 mutex_init(&md->mutex);
483
484 md->enabled = panel_enabled(md);
485
486 if (md->enabled)
487 mipid_esd_start_check(md);
488 else
489 md->saved_bklight_level = mipid_get_bklight_level(panel);
490
491 return 0;
492}
493
494static void mipid_cleanup(struct lcd_panel *panel)
495{
496 struct mipid_device *md = to_mipid_device(panel);
497
498 if (md->enabled)
499 mipid_esd_stop_check(md);
500 destroy_workqueue(md->esd_wq);
501}
502
503static struct lcd_panel mipid_panel = {
504 .config = OMAP_LCDC_PANEL_TFT,
505
506 .bpp = 16,
507 .x_res = 800,
508 .y_res = 480,
509 .pixel_clock = 21940,
510 .hsw = 50,
511 .hfp = 20,
512 .hbp = 15,
513 .vsw = 2,
514 .vfp = 1,
515 .vbp = 3,
516
517 .init = mipid_init,
518 .cleanup = mipid_cleanup,
519 .enable = mipid_enable,
520 .disable = mipid_disable,
521 .get_caps = mipid_get_caps,
522 .set_bklight_level = mipid_set_bklight_level,
523 .get_bklight_level = mipid_get_bklight_level,
524 .get_bklight_max = mipid_get_bklight_max,
525 .run_test = mipid_run_test,
526};
527
528static int mipid_detect(struct mipid_device *md)
529{
530 struct mipid_platform_data *pdata;
531 u8 display_id[3];
532
533 pdata = md->spi->dev.platform_data;
534 if (pdata == NULL) {
535 dev_err(&md->spi->dev, "missing platform data\n");
536 return -ENOENT;
537 }
538
539 mipid_read(md, MIPID_CMD_READ_DISP_ID, display_id, 3);
540 dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n",
541 display_id[0], display_id[1], display_id[2]);
542
543 switch (display_id[0]) {
544 case 0x45:
545 md->panel.name = "lph8923";
546 break;
547 case 0x83:
548 md->panel.name = "ls041y3";
549 md->esd_check = ls041y3_esd_check;
550 break;
551 default:
552 md->panel.name = "unknown";
553 dev_err(&md->spi->dev, "invalid display ID\n");
554 return -ENODEV;
555 }
556
557 md->revision = display_id[1];
558 md->panel.data_lines = pdata->data_lines;
559 pr_info("omapfb: %s rev %02x LCD detected, %d data lines\n",
560 md->panel.name, md->revision, md->panel.data_lines);
561
562 return 0;
563}
564
565static int mipid_spi_probe(struct spi_device *spi)
566{
567 struct mipid_device *md;
568 int r;
569
570 md = kzalloc(sizeof(*md), GFP_KERNEL);
571 if (md == NULL) {
572 dev_err(&spi->dev, "out of memory\n");
573 return -ENOMEM;
574 }
575
576 spi->mode = SPI_MODE_0;
577 md->spi = spi;
578 dev_set_drvdata(&spi->dev, md);
579 md->panel = mipid_panel;
580
581 r = mipid_detect(md);
582 if (r < 0)
583 return r;
584
585 omapfb_register_panel(&md->panel);
586
587 return 0;
588}
589
590static int mipid_spi_remove(struct spi_device *spi)
591{
592 struct mipid_device *md = dev_get_drvdata(&spi->dev);
593
594 mipid_disable(&md->panel);
595 kfree(md);
596
597 return 0;
598}
599
600static struct spi_driver mipid_spi_driver = {
601 .driver = {
602 .name = MIPID_MODULE_NAME,
603 .bus = &spi_bus_type,
604 .owner = THIS_MODULE,
605 },
606 .probe = mipid_spi_probe,
607 .remove = __devexit_p(mipid_spi_remove),
608};
609
610static int mipid_drv_init(void)
611{
612 spi_register_driver(&mipid_spi_driver);
613
614 return 0;
615}
616module_init(mipid_drv_init);
617
618static void mipid_drv_cleanup(void)
619{
620 spi_unregister_driver(&mipid_spi_driver);
621}
622module_exit(mipid_drv_cleanup);
623
624MODULE_DESCRIPTION("MIPI display driver");
625MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap/lcd_omap2evm.c b/drivers/video/omap/lcd_omap2evm.c
new file mode 100644
index 000000000000..7a2bbe2ecec3
--- /dev/null
+++ b/drivers/video/omap/lcd_omap2evm.c
@@ -0,0 +1,191 @@
1/*
2 * LCD panel support for the MISTRAL OMAP2EVM board
3 *
4 * Author: Arun C <arunedarath@mistralsolutions.com>
5 *
6 * Derived from drivers/video/omap/lcd_omap3evm.c
7 * Derived from drivers/video/omap/lcd-apollon.c
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 as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/gpio.h>
27#include <linux/i2c/twl4030.h>
28
29#include <mach/mux.h>
30#include <mach/omapfb.h>
31#include <asm/mach-types.h>
32
33#define LCD_PANEL_ENABLE_GPIO 154
34#define LCD_PANEL_LR 128
35#define LCD_PANEL_UD 129
36#define LCD_PANEL_INI 152
37#define LCD_PANEL_QVGA 148
38#define LCD_PANEL_RESB 153
39
40#define TWL_LED_LEDEN 0x00
41#define TWL_PWMA_PWMAON 0x00
42#define TWL_PWMA_PWMAOFF 0x01
43
44static unsigned int bklight_level;
45
46static int omap2evm_panel_init(struct lcd_panel *panel,
47 struct omapfb_device *fbdev)
48{
49 gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable");
50 gpio_request(LCD_PANEL_LR, "LCD lr");
51 gpio_request(LCD_PANEL_UD, "LCD ud");
52 gpio_request(LCD_PANEL_INI, "LCD ini");
53 gpio_request(LCD_PANEL_QVGA, "LCD qvga");
54 gpio_request(LCD_PANEL_RESB, "LCD resb");
55
56 gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
57 gpio_direction_output(LCD_PANEL_RESB, 1);
58 gpio_direction_output(LCD_PANEL_INI, 1);
59 gpio_direction_output(LCD_PANEL_QVGA, 0);
60 gpio_direction_output(LCD_PANEL_LR, 1);
61 gpio_direction_output(LCD_PANEL_UD, 1);
62
63 twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
64 twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
65 twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
66 bklight_level = 100;
67
68 return 0;
69}
70
71static void omap2evm_panel_cleanup(struct lcd_panel *panel)
72{
73 gpio_free(LCD_PANEL_RESB);
74 gpio_free(LCD_PANEL_QVGA);
75 gpio_free(LCD_PANEL_INI);
76 gpio_free(LCD_PANEL_UD);
77 gpio_free(LCD_PANEL_LR);
78 gpio_free(LCD_PANEL_ENABLE_GPIO);
79}
80
81static int omap2evm_panel_enable(struct lcd_panel *panel)
82{
83 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
84 return 0;
85}
86
87static void omap2evm_panel_disable(struct lcd_panel *panel)
88{
89 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
90}
91
92static unsigned long omap2evm_panel_get_caps(struct lcd_panel *panel)
93{
94 return 0;
95}
96
97static int omap2evm_bklight_setlevel(struct lcd_panel *panel,
98 unsigned int level)
99{
100 u8 c;
101 if ((level >= 0) && (level <= 100)) {
102 c = (125 * (100 - level)) / 100 + 2;
103 twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF);
104 bklight_level = level;
105 }
106 return 0;
107}
108
109static unsigned int omap2evm_bklight_getlevel(struct lcd_panel *panel)
110{
111 return bklight_level;
112}
113
114static unsigned int omap2evm_bklight_getmaxlevel(struct lcd_panel *panel)
115{
116 return 100;
117}
118
119struct lcd_panel omap2evm_panel = {
120 .name = "omap2evm",
121 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
122 OMAP_LCDC_INV_HSYNC,
123
124 .bpp = 16,
125 .data_lines = 18,
126 .x_res = 480,
127 .y_res = 640,
128 .hsw = 3,
129 .hfp = 0,
130 .hbp = 28,
131 .vsw = 2,
132 .vfp = 1,
133 .vbp = 0,
134
135 .pixel_clock = 20000,
136
137 .init = omap2evm_panel_init,
138 .cleanup = omap2evm_panel_cleanup,
139 .enable = omap2evm_panel_enable,
140 .disable = omap2evm_panel_disable,
141 .get_caps = omap2evm_panel_get_caps,
142 .set_bklight_level = omap2evm_bklight_setlevel,
143 .get_bklight_level = omap2evm_bklight_getlevel,
144 .get_bklight_max = omap2evm_bklight_getmaxlevel,
145};
146
147static int omap2evm_panel_probe(struct platform_device *pdev)
148{
149 omapfb_register_panel(&omap2evm_panel);
150 return 0;
151}
152
153static int omap2evm_panel_remove(struct platform_device *pdev)
154{
155 return 0;
156}
157
158static int omap2evm_panel_suspend(struct platform_device *pdev,
159 pm_message_t mesg)
160{
161 return 0;
162}
163
164static int omap2evm_panel_resume(struct platform_device *pdev)
165{
166 return 0;
167}
168
169struct platform_driver omap2evm_panel_driver = {
170 .probe = omap2evm_panel_probe,
171 .remove = omap2evm_panel_remove,
172 .suspend = omap2evm_panel_suspend,
173 .resume = omap2evm_panel_resume,
174 .driver = {
175 .name = "omap2evm_lcd",
176 .owner = THIS_MODULE,
177 },
178};
179
180static int __init omap2evm_panel_drv_init(void)
181{
182 return platform_driver_register(&omap2evm_panel_driver);
183}
184
185static void __exit omap2evm_panel_drv_exit(void)
186{
187 platform_driver_unregister(&omap2evm_panel_driver);
188}
189
190module_init(omap2evm_panel_drv_init);
191module_exit(omap2evm_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
new file mode 100644
index 000000000000..4011910123bf
--- /dev/null
+++ b/drivers/video/omap/lcd_omap3beagle.c
@@ -0,0 +1,130 @@
1/*
2 * LCD panel support for the TI OMAP3 Beagle board
3 *
4 * Author: Koen Kooi <koen@openembedded.org>
5 *
6 * Derived from drivers/video/omap/lcd-omap3evm.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/module.h>
24#include <linux/platform_device.h>
25#include <linux/gpio.h>
26#include <linux/i2c/twl4030.h>
27
28#include <mach/mux.h>
29#include <mach/omapfb.h>
30#include <asm/mach-types.h>
31
32#define LCD_PANEL_ENABLE_GPIO 170
33
34static int omap3beagle_panel_init(struct lcd_panel *panel,
35 struct omapfb_device *fbdev)
36{
37 gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable");
38 return 0;
39}
40
41static void omap3beagle_panel_cleanup(struct lcd_panel *panel)
42{
43 gpio_free(LCD_PANEL_ENABLE_GPIO);
44}
45
46static int omap3beagle_panel_enable(struct lcd_panel *panel)
47{
48 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
49 return 0;
50}
51
52static void omap3beagle_panel_disable(struct lcd_panel *panel)
53{
54 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
55}
56
57static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
58{
59 return 0;
60}
61
62struct lcd_panel omap3beagle_panel = {
63 .name = "omap3beagle",
64 .config = OMAP_LCDC_PANEL_TFT,
65
66 .bpp = 16,
67 .data_lines = 24,
68 .x_res = 1024,
69 .y_res = 768,
70 .hsw = 3, /* hsync_len (4) - 1 */
71 .hfp = 3, /* right_margin (4) - 1 */
72 .hbp = 39, /* left_margin (40) - 1 */
73 .vsw = 1, /* vsync_len (2) - 1 */
74 .vfp = 2, /* lower_margin */
75 .vbp = 7, /* upper_margin (8) - 1 */
76
77 .pixel_clock = 64000,
78
79 .init = omap3beagle_panel_init,
80 .cleanup = omap3beagle_panel_cleanup,
81 .enable = omap3beagle_panel_enable,
82 .disable = omap3beagle_panel_disable,
83 .get_caps = omap3beagle_panel_get_caps,
84};
85
86static int omap3beagle_panel_probe(struct platform_device *pdev)
87{
88 omapfb_register_panel(&omap3beagle_panel);
89 return 0;
90}
91
92static int omap3beagle_panel_remove(struct platform_device *pdev)
93{
94 return 0;
95}
96
97static int omap3beagle_panel_suspend(struct platform_device *pdev,
98 pm_message_t mesg)
99{
100 return 0;
101}
102
103static int omap3beagle_panel_resume(struct platform_device *pdev)
104{
105 return 0;
106}
107
108struct platform_driver omap3beagle_panel_driver = {
109 .probe = omap3beagle_panel_probe,
110 .remove = omap3beagle_panel_remove,
111 .suspend = omap3beagle_panel_suspend,
112 .resume = omap3beagle_panel_resume,
113 .driver = {
114 .name = "omap3beagle_lcd",
115 .owner = THIS_MODULE,
116 },
117};
118
119static int __init omap3beagle_panel_drv_init(void)
120{
121 return platform_driver_register(&omap3beagle_panel_driver);
122}
123
124static void __exit omap3beagle_panel_drv_exit(void)
125{
126 platform_driver_unregister(&omap3beagle_panel_driver);
127}
128
129module_init(omap3beagle_panel_drv_init);
130module_exit(omap3beagle_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_omap3evm.c b/drivers/video/omap/lcd_omap3evm.c
new file mode 100644
index 000000000000..b6a4c2c57a2f
--- /dev/null
+++ b/drivers/video/omap/lcd_omap3evm.c
@@ -0,0 +1,192 @@
1/*
2 * LCD panel support for the TI OMAP3 EVM board
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * Derived from drivers/video/omap/lcd-apollon.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/module.h>
24#include <linux/platform_device.h>
25#include <linux/gpio.h>
26#include <linux/i2c/twl4030.h>
27
28#include <mach/mux.h>
29#include <mach/omapfb.h>
30#include <asm/mach-types.h>
31
32#define LCD_PANEL_ENABLE_GPIO 153
33#define LCD_PANEL_LR 2
34#define LCD_PANEL_UD 3
35#define LCD_PANEL_INI 152
36#define LCD_PANEL_QVGA 154
37#define LCD_PANEL_RESB 155
38
39#define ENABLE_VDAC_DEDICATED 0x03
40#define ENABLE_VDAC_DEV_GRP 0x20
41#define ENABLE_VPLL2_DEDICATED 0x05
42#define ENABLE_VPLL2_DEV_GRP 0xE0
43
44#define TWL_LED_LEDEN 0x00
45#define TWL_PWMA_PWMAON 0x00
46#define TWL_PWMA_PWMAOFF 0x01
47
48static unsigned int bklight_level;
49
50static int omap3evm_panel_init(struct lcd_panel *panel,
51 struct omapfb_device *fbdev)
52{
53 gpio_request(LCD_PANEL_LR, "LCD lr");
54 gpio_request(LCD_PANEL_UD, "LCD ud");
55 gpio_request(LCD_PANEL_INI, "LCD ini");
56 gpio_request(LCD_PANEL_RESB, "LCD resb");
57 gpio_request(LCD_PANEL_QVGA, "LCD qvga");
58
59 gpio_direction_output(LCD_PANEL_RESB, 1);
60 gpio_direction_output(LCD_PANEL_INI, 1);
61 gpio_direction_output(LCD_PANEL_QVGA, 0);
62 gpio_direction_output(LCD_PANEL_LR, 1);
63 gpio_direction_output(LCD_PANEL_UD, 1);
64
65 twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
66 twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
67 twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
68 bklight_level = 100;
69
70 return 0;
71}
72
73static void omap3evm_panel_cleanup(struct lcd_panel *panel)
74{
75 gpio_free(LCD_PANEL_QVGA);
76 gpio_free(LCD_PANEL_RESB);
77 gpio_free(LCD_PANEL_INI);
78 gpio_free(LCD_PANEL_UD);
79 gpio_free(LCD_PANEL_LR);
80}
81
82static int omap3evm_panel_enable(struct lcd_panel *panel)
83{
84 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
85 return 0;
86}
87
88static void omap3evm_panel_disable(struct lcd_panel *panel)
89{
90 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
91}
92
93static unsigned long omap3evm_panel_get_caps(struct lcd_panel *panel)
94{
95 return 0;
96}
97
98static int omap3evm_bklight_setlevel(struct lcd_panel *panel,
99 unsigned int level)
100{
101 u8 c;
102 if ((level >= 0) && (level <= 100)) {
103 c = (125 * (100 - level)) / 100 + 2;
104 twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF);
105 bklight_level = level;
106 }
107 return 0;
108}
109
110static unsigned int omap3evm_bklight_getlevel(struct lcd_panel *panel)
111{
112 return bklight_level;
113}
114
115static unsigned int omap3evm_bklight_getmaxlevel(struct lcd_panel *panel)
116{
117 return 100;
118}
119
120struct lcd_panel omap3evm_panel = {
121 .name = "omap3evm",
122 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
123 OMAP_LCDC_INV_HSYNC,
124
125 .bpp = 16,
126 .data_lines = 18,
127 .x_res = 480,
128 .y_res = 640,
129 .hsw = 3, /* hsync_len (4) - 1 */
130 .hfp = 3, /* right_margin (4) - 1 */
131 .hbp = 39, /* left_margin (40) - 1 */
132 .vsw = 1, /* vsync_len (2) - 1 */
133 .vfp = 2, /* lower_margin */
134 .vbp = 7, /* upper_margin (8) - 1 */
135
136 .pixel_clock = 26000,
137
138 .init = omap3evm_panel_init,
139 .cleanup = omap3evm_panel_cleanup,
140 .enable = omap3evm_panel_enable,
141 .disable = omap3evm_panel_disable,
142 .get_caps = omap3evm_panel_get_caps,
143 .set_bklight_level = omap3evm_bklight_setlevel,
144 .get_bklight_level = omap3evm_bklight_getlevel,
145 .get_bklight_max = omap3evm_bklight_getmaxlevel,
146};
147
148static int omap3evm_panel_probe(struct platform_device *pdev)
149{
150 omapfb_register_panel(&omap3evm_panel);
151 return 0;
152}
153
154static int omap3evm_panel_remove(struct platform_device *pdev)
155{
156 return 0;
157}
158
159static int omap3evm_panel_suspend(struct platform_device *pdev,
160 pm_message_t mesg)
161{
162 return 0;
163}
164
165static int omap3evm_panel_resume(struct platform_device *pdev)
166{
167 return 0;
168}
169
170struct platform_driver omap3evm_panel_driver = {
171 .probe = omap3evm_panel_probe,
172 .remove = omap3evm_panel_remove,
173 .suspend = omap3evm_panel_suspend,
174 .resume = omap3evm_panel_resume,
175 .driver = {
176 .name = "omap3evm_lcd",
177 .owner = THIS_MODULE,
178 },
179};
180
181static int __init omap3evm_panel_drv_init(void)
182{
183 return platform_driver_register(&omap3evm_panel_driver);
184}
185
186static void __exit omap3evm_panel_drv_exit(void)
187{
188 platform_driver_unregister(&omap3evm_panel_driver);
189}
190
191module_init(omap3evm_panel_drv_init);
192module_exit(omap3evm_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
index 379c96d36da5..b3fa88bc6269 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/omap/lcd_osk.c
@@ -127,12 +127,12 @@ struct platform_driver osk_panel_driver = {
127 }, 127 },
128}; 128};
129 129
130static int osk_panel_drv_init(void) 130static int __init osk_panel_drv_init(void)
131{ 131{
132 return platform_driver_register(&osk_panel_driver); 132 return platform_driver_register(&osk_panel_driver);
133} 133}
134 134
135static void osk_panel_drv_cleanup(void) 135static void __exit osk_panel_drv_cleanup(void)
136{ 136{
137 platform_driver_unregister(&osk_panel_driver); 137 platform_driver_unregister(&osk_panel_driver);
138} 138}
diff --git a/drivers/video/omap/lcd_overo.c b/drivers/video/omap/lcd_overo.c
new file mode 100644
index 000000000000..2bc5c9268e5e
--- /dev/null
+++ b/drivers/video/omap/lcd_overo.c
@@ -0,0 +1,179 @@
1/*
2 * LCD panel support for the Gumstix Overo
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 as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <linux/i2c/twl4030.h>
25
26#include <mach/gpio.h>
27#include <mach/mux.h>
28#include <mach/omapfb.h>
29#include <asm/mach-types.h>
30
31#define LCD_ENABLE 144
32
33static int overo_panel_init(struct lcd_panel *panel,
34 struct omapfb_device *fbdev)
35{
36 if ((gpio_request(LCD_ENABLE, "LCD_ENABLE") == 0) &&
37 (gpio_direction_output(LCD_ENABLE, 1) == 0))
38 gpio_export(LCD_ENABLE, 0);
39 else
40 printk(KERN_ERR "could not obtain gpio for LCD_ENABLE\n");
41
42 return 0;
43}
44
45static void overo_panel_cleanup(struct lcd_panel *panel)
46{
47 gpio_free(LCD_ENABLE);
48}
49
50static int overo_panel_enable(struct lcd_panel *panel)
51{
52 gpio_set_value(LCD_ENABLE, 1);
53 return 0;
54}
55
56static void overo_panel_disable(struct lcd_panel *panel)
57{
58 gpio_set_value(LCD_ENABLE, 0);
59}
60
61static unsigned long overo_panel_get_caps(struct lcd_panel *panel)
62{
63 return 0;
64}
65
66struct lcd_panel overo_panel = {
67 .name = "overo",
68 .config = OMAP_LCDC_PANEL_TFT,
69 .bpp = 16,
70 .data_lines = 24,
71
72#if defined CONFIG_FB_OMAP_031M3R
73
74 /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
75 .x_res = 640,
76 .y_res = 480,
77 .hfp = 48,
78 .hsw = 32,
79 .hbp = 80,
80 .vfp = 3,
81 .vsw = 4,
82 .vbp = 7,
83 .pixel_clock = 23500,
84
85#elif defined CONFIG_FB_OMAP_048M3R
86
87 /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */
88 .x_res = 800,
89 .y_res = 600,
90 .hfp = 48,
91 .hsw = 32,
92 .hbp = 80,
93 .vfp = 3,
94 .vsw = 4,
95 .vbp = 11,
96 .pixel_clock = 35500,
97
98#elif defined CONFIG_FB_OMAP_079M3R
99
100 /* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
101 .x_res = 1024,
102 .y_res = 768,
103 .hfp = 48,
104 .hsw = 32,
105 .hbp = 80,
106 .vfp = 3,
107 .vsw = 4,
108 .vbp = 15,
109 .pixel_clock = 56000,
110
111#elif defined CONFIG_FB_OMAP_092M9R
112
113 /* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.92M9-R */
114 .x_res = 1280,
115 .y_res = 720,
116 .hfp = 48,
117 .hsw = 32,
118 .hbp = 80,
119 .vfp = 3,
120 .vsw = 5,
121 .vbp = 13,
122 .pixel_clock = 64000,
123
124#else
125
126 /* use 640 x 480 if no config option */
127 /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
128 .x_res = 640,
129 .y_res = 480,
130 .hfp = 48,
131 .hsw = 32,
132 .hbp = 80,
133 .vfp = 3,
134 .vsw = 4,
135 .vbp = 7,
136 .pixel_clock = 23500,
137
138#endif
139
140 .init = overo_panel_init,
141 .cleanup = overo_panel_cleanup,
142 .enable = overo_panel_enable,
143 .disable = overo_panel_disable,
144 .get_caps = overo_panel_get_caps,
145};
146
147static int overo_panel_probe(struct platform_device *pdev)
148{
149 omapfb_register_panel(&overo_panel);
150 return 0;
151}
152
153static int overo_panel_remove(struct platform_device *pdev)
154{
155 /* omapfb does not have unregister_panel */
156 return 0;
157}
158
159static struct platform_driver overo_panel_driver = {
160 .probe = overo_panel_probe,
161 .remove = overo_panel_remove,
162 .driver = {
163 .name = "overo_lcd",
164 .owner = THIS_MODULE,
165 },
166};
167
168static int __init overo_panel_drv_init(void)
169{
170 return platform_driver_register(&overo_panel_driver);
171}
172
173static void __exit overo_panel_drv_exit(void)
174{
175 platform_driver_unregister(&overo_panel_driver);
176}
177
178module_init(overo_panel_drv_init);
179module_exit(overo_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c
index 218317366e6e..4bf3c79f3cc7 100644
--- a/drivers/video/omap/lcd_palmte.c
+++ b/drivers/video/omap/lcd_palmte.c
@@ -108,12 +108,12 @@ struct platform_driver palmte_panel_driver = {
108 }, 108 },
109}; 109};
110 110
111static int palmte_panel_drv_init(void) 111static int __init palmte_panel_drv_init(void)
112{ 112{
113 return platform_driver_register(&palmte_panel_driver); 113 return platform_driver_register(&palmte_panel_driver);
114} 114}
115 115
116static void palmte_panel_drv_cleanup(void) 116static void __exit palmte_panel_drv_cleanup(void)
117{ 117{
118 platform_driver_unregister(&palmte_panel_driver); 118 platform_driver_unregister(&palmte_panel_driver);
119} 119}
diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/omap/lcd_palmtt.c
index 57b0f6cf6a5a..48ea1f9f2cbf 100644
--- a/drivers/video/omap/lcd_palmtt.c
+++ b/drivers/video/omap/lcd_palmtt.c
@@ -113,12 +113,12 @@ struct platform_driver palmtt_panel_driver = {
113 }, 113 },
114}; 114};
115 115
116static int palmtt_panel_drv_init(void) 116static int __init palmtt_panel_drv_init(void)
117{ 117{
118 return platform_driver_register(&palmtt_panel_driver); 118 return platform_driver_register(&palmtt_panel_driver);
119} 119}
120 120
121static void palmtt_panel_drv_cleanup(void) 121static void __exit palmtt_panel_drv_cleanup(void)
122{ 122{
123 platform_driver_unregister(&palmtt_panel_driver); 123 platform_driver_unregister(&palmtt_panel_driver);
124} 124}
diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/omap/lcd_palmz71.c
index d33d78b11723..0697d29b4d3b 100644
--- a/drivers/video/omap/lcd_palmz71.c
+++ b/drivers/video/omap/lcd_palmz71.c
@@ -109,12 +109,12 @@ struct platform_driver palmz71_panel_driver = {
109 }, 109 },
110}; 110};
111 111
112static int palmz71_panel_drv_init(void) 112static int __init palmz71_panel_drv_init(void)
113{ 113{
114 return platform_driver_register(&palmz71_panel_driver); 114 return platform_driver_register(&palmz71_panel_driver);
115} 115}
116 116
117static void palmz71_panel_drv_cleanup(void) 117static void __exit palmz71_panel_drv_cleanup(void)
118{ 118{
119 platform_driver_unregister(&palmz71_panel_driver); 119 platform_driver_unregister(&palmz71_panel_driver);
120} 120}
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 8862233d57b6..125e605b8c68 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -67,6 +67,7 @@ static struct caps_table_struct ctrl_caps[] = {
67 { OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE, "pixel double window" }, 67 { OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE, "pixel double window" },
68 { OMAPFB_CAPS_WINDOW_SCALE, "scale window" }, 68 { OMAPFB_CAPS_WINDOW_SCALE, "scale window" },
69 { OMAPFB_CAPS_WINDOW_OVERLAY, "overlay window" }, 69 { OMAPFB_CAPS_WINDOW_OVERLAY, "overlay window" },
70 { OMAPFB_CAPS_WINDOW_ROTATE, "rotate window" },
70 { OMAPFB_CAPS_SET_BACKLIGHT, "backlight setting" }, 71 { OMAPFB_CAPS_SET_BACKLIGHT, "backlight setting" },
71}; 72};
72 73
@@ -215,6 +216,15 @@ static int ctrl_change_mode(struct fb_info *fbi)
215 offset, var->xres_virtual, 216 offset, var->xres_virtual,
216 plane->info.pos_x, plane->info.pos_y, 217 plane->info.pos_x, plane->info.pos_y,
217 var->xres, var->yres, plane->color_mode); 218 var->xres, var->yres, plane->color_mode);
219 if (r < 0)
220 return r;
221
222 if (fbdev->ctrl->set_rotate != NULL) {
223 r = fbdev->ctrl->set_rotate(var->rotate);
224 if (r < 0)
225 return r;
226 }
227
218 if (fbdev->ctrl->set_scale != NULL) 228 if (fbdev->ctrl->set_scale != NULL)
219 r = fbdev->ctrl->set_scale(plane->idx, 229 r = fbdev->ctrl->set_scale(plane->idx,
220 var->xres, var->yres, 230 var->xres, var->yres,
@@ -554,7 +564,6 @@ static int set_fb_var(struct fb_info *fbi,
554 var->xoffset = var->xres_virtual - var->xres; 564 var->xoffset = var->xres_virtual - var->xres;
555 if (var->yres + var->yoffset > var->yres_virtual) 565 if (var->yres + var->yoffset > var->yres_virtual)
556 var->yoffset = var->yres_virtual - var->yres; 566 var->yoffset = var->yres_virtual - var->yres;
557 line_size = var->xres * bpp / 8;
558 567
559 if (plane->color_mode == OMAPFB_COLOR_RGB444) { 568 if (plane->color_mode == OMAPFB_COLOR_RGB444) {
560 var->red.offset = 8; var->red.length = 4; 569 var->red.offset = 8; var->red.length = 4;
@@ -600,7 +609,7 @@ static void omapfb_rotate(struct fb_info *fbi, int rotate)
600 struct omapfb_device *fbdev = plane->fbdev; 609 struct omapfb_device *fbdev = plane->fbdev;
601 610
602 omapfb_rqueue_lock(fbdev); 611 omapfb_rqueue_lock(fbdev);
603 if (cpu_is_omap15xx() && rotate != fbi->var.rotate) { 612 if (rotate != fbi->var.rotate) {
604 struct fb_var_screeninfo *new_var = &fbdev->new_var; 613 struct fb_var_screeninfo *new_var = &fbdev->new_var;
605 614
606 memcpy(new_var, &fbi->var, sizeof(*new_var)); 615 memcpy(new_var, &fbi->var, sizeof(*new_var));
@@ -707,28 +716,42 @@ int omapfb_update_window_async(struct fb_info *fbi,
707 void (*callback)(void *), 716 void (*callback)(void *),
708 void *callback_data) 717 void *callback_data)
709{ 718{
719 int xres, yres;
710 struct omapfb_plane_struct *plane = fbi->par; 720 struct omapfb_plane_struct *plane = fbi->par;
711 struct omapfb_device *fbdev = plane->fbdev; 721 struct omapfb_device *fbdev = plane->fbdev;
712 struct fb_var_screeninfo *var; 722 struct fb_var_screeninfo *var = &fbi->var;
723
724 switch (var->rotate) {
725 case 0:
726 case 180:
727 xres = fbdev->panel->x_res;
728 yres = fbdev->panel->y_res;
729 break;
730 case 90:
731 case 270:
732 xres = fbdev->panel->y_res;
733 yres = fbdev->panel->x_res;
734 break;
735 default:
736 return -EINVAL;
737 }
713 738
714 var = &fbi->var; 739 if (win->x >= xres || win->y >= yres ||
715 if (win->x >= var->xres || win->y >= var->yres || 740 win->out_x > xres || win->out_y > yres)
716 win->out_x > var->xres || win->out_y >= var->yres)
717 return -EINVAL; 741 return -EINVAL;
718 742
719 if (!fbdev->ctrl->update_window || 743 if (!fbdev->ctrl->update_window ||
720 fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE) 744 fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE)
721 return -ENODEV; 745 return -ENODEV;
722 746
723 if (win->x + win->width >= var->xres) 747 if (win->x + win->width > xres)
724 win->width = var->xres - win->x; 748 win->width = xres - win->x;
725 if (win->y + win->height >= var->yres) 749 if (win->y + win->height > yres)
726 win->height = var->yres - win->y; 750 win->height = yres - win->y;
727 /* The out sizes should be cropped to the LCD size */ 751 if (win->out_x + win->out_width > xres)
728 if (win->out_x + win->out_width > fbdev->panel->x_res) 752 win->out_width = xres - win->out_x;
729 win->out_width = fbdev->panel->x_res - win->out_x; 753 if (win->out_y + win->out_height > yres)
730 if (win->out_y + win->out_height > fbdev->panel->y_res) 754 win->out_height = yres - win->out_y;
731 win->out_height = fbdev->panel->y_res - win->out_y;
732 if (!win->width || !win->height || !win->out_width || !win->out_height) 755 if (!win->width || !win->height || !win->out_width || !win->out_height)
733 return 0; 756 return 0;
734 757
@@ -1699,8 +1722,8 @@ static int omapfb_do_probe(struct platform_device *pdev,
1699 1722
1700 pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); 1723 pr_info("omapfb: configured for panel %s\n", fbdev->panel->name);
1701 1724
1702 def_vxres = def_vxres ? : fbdev->panel->x_res; 1725 def_vxres = def_vxres ? def_vxres : fbdev->panel->x_res;
1703 def_vyres = def_vyres ? : fbdev->panel->y_res; 1726 def_vyres = def_vyres ? def_vyres : fbdev->panel->y_res;
1704 1727
1705 init_state++; 1728 init_state++;
1706 1729
@@ -1822,8 +1845,8 @@ static int omapfb_suspend(struct platform_device *pdev, pm_message_t mesg)
1822{ 1845{
1823 struct omapfb_device *fbdev = platform_get_drvdata(pdev); 1846 struct omapfb_device *fbdev = platform_get_drvdata(pdev);
1824 1847
1825 omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]); 1848 if (fbdev != NULL)
1826 1849 omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]);
1827 return 0; 1850 return 0;
1828} 1851}
1829 1852
@@ -1832,7 +1855,8 @@ static int omapfb_resume(struct platform_device *pdev)
1832{ 1855{
1833 struct omapfb_device *fbdev = platform_get_drvdata(pdev); 1856 struct omapfb_device *fbdev = platform_get_drvdata(pdev);
1834 1857
1835 omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]); 1858 if (fbdev != NULL)
1859 omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]);
1836 return 0; 1860 return 0;
1837} 1861}
1838 1862
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
index 9332d6ca6456..ee01e84e19c1 100644
--- a/drivers/video/omap/rfbi.c
+++ b/drivers/video/omap/rfbi.c
@@ -57,6 +57,7 @@
57 57
58#define DISPC_BASE 0x48050400 58#define DISPC_BASE 0x48050400
59#define DISPC_CONTROL 0x0040 59#define DISPC_CONTROL 0x0040
60#define DISPC_IRQ_FRAMEMASK 0x0001
60 61
61static struct { 62static struct {
62 void __iomem *base; 63 void __iomem *base;
@@ -553,7 +554,9 @@ static int rfbi_init(struct omapfb_device *fbdev)
553 l = (0x01 << 2); 554 l = (0x01 << 2);
554 rfbi_write_reg(RFBI_CONTROL, l); 555 rfbi_write_reg(RFBI_CONTROL, l);
555 556
556 if ((r = omap_dispc_request_irq(rfbi_dma_callback, NULL)) < 0) { 557 r = omap_dispc_request_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback,
558 NULL);
559 if (r < 0) {
557 dev_err(fbdev->dev, "can't get DISPC irq\n"); 560 dev_err(fbdev->dev, "can't get DISPC irq\n");
558 rfbi_enable_clocks(0); 561 rfbi_enable_clocks(0);
559 return r; 562 return r;
@@ -570,7 +573,7 @@ static int rfbi_init(struct omapfb_device *fbdev)
570 573
571static void rfbi_cleanup(void) 574static void rfbi_cleanup(void)
572{ 575{
573 omap_dispc_free_irq(); 576 omap_dispc_free_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback, NULL);
574 rfbi_put_clocks(); 577 rfbi_put_clocks();
575 iounmap(rfbi.base); 578 iounmap(rfbi.base);
576} 579}
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index bacfabd9ce16..0a366d86f08e 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -223,10 +223,14 @@ static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
223 223
224static inline int platinum_vram_reqd(int video_mode, int color_mode) 224static inline int platinum_vram_reqd(int video_mode, int color_mode)
225{ 225{
226 return vmode_attrs[video_mode-1].vres * 226 int baseval = vmode_attrs[video_mode-1].hres * (1<<color_mode);
227 (vmode_attrs[video_mode-1].hres * (1<<color_mode) + 227
228 ((video_mode == VMODE_832_624_75) && 228 if ((video_mode == VMODE_832_624_75) && (color_mode > CMODE_8))
229 (color_mode > CMODE_8)) ? 0x10 : 0x20) + 0x1000; 229 baseval += 0x10;
230 else
231 baseval += 0x20;
232
233 return vmode_attrs[video_mode-1].vres * baseval + 0x1000;
230} 234}
231 235
232#define STORE_D2(a, d) { \ 236#define STORE_D2(a, d) { \
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index c0af638fe702..9c0144ee7ae5 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -32,7 +32,7 @@
32#include <linux/init.h> 32#include <linux/init.h>
33 33
34#include <asm/abs_addr.h> 34#include <asm/abs_addr.h>
35#include <asm/iommu.h> 35#include <asm/cell-regs.h>
36#include <asm/lv1call.h> 36#include <asm/lv1call.h>
37#include <asm/ps3av.h> 37#include <asm/ps3av.h>
38#include <asm/ps3fb.h> 38#include <asm/ps3fb.h>
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 6506117c134b..1820c4a24434 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1638,24 +1638,26 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data)
1638 * Power management hooks. Note that we won't be called from IRQ context, 1638 * Power management hooks. Note that we won't be called from IRQ context,
1639 * unlike the blank functions above, so we may sleep. 1639 * unlike the blank functions above, so we may sleep.
1640 */ 1640 */
1641static int pxafb_suspend(struct platform_device *dev, pm_message_t state) 1641static int pxafb_suspend(struct device *dev)
1642{ 1642{
1643 struct pxafb_info *fbi = platform_get_drvdata(dev); 1643 struct pxafb_info *fbi = dev_get_drvdata(dev);
1644 1644
1645 set_ctrlr_state(fbi, C_DISABLE_PM); 1645 set_ctrlr_state(fbi, C_DISABLE_PM);
1646 return 0; 1646 return 0;
1647} 1647}
1648 1648
1649static int pxafb_resume(struct platform_device *dev) 1649static int pxafb_resume(struct device *dev)
1650{ 1650{
1651 struct pxafb_info *fbi = platform_get_drvdata(dev); 1651 struct pxafb_info *fbi = dev_get_drvdata(dev);
1652 1652
1653 set_ctrlr_state(fbi, C_ENABLE_PM); 1653 set_ctrlr_state(fbi, C_ENABLE_PM);
1654 return 0; 1654 return 0;
1655} 1655}
1656#else 1656
1657#define pxafb_suspend NULL 1657static struct dev_pm_ops pxafb_pm_ops = {
1658#define pxafb_resume NULL 1658 .suspend = pxafb_suspend,
1659 .resume = pxafb_resume,
1660};
1659#endif 1661#endif
1660 1662
1661static int __devinit pxafb_init_video_memory(struct pxafb_info *fbi) 1663static int __devinit pxafb_init_video_memory(struct pxafb_info *fbi)
@@ -2081,6 +2083,9 @@ static int __devinit pxafb_probe(struct platform_device *dev)
2081 goto failed; 2083 goto failed;
2082 } 2084 }
2083 2085
2086 if (cpu_is_pxa3xx() && inf->acceleration_enabled)
2087 fbi->fb.fix.accel = FB_ACCEL_PXA3XX;
2088
2084 fbi->backlight_power = inf->pxafb_backlight_power; 2089 fbi->backlight_power = inf->pxafb_backlight_power;
2085 fbi->lcd_power = inf->pxafb_lcd_power; 2090 fbi->lcd_power = inf->pxafb_lcd_power;
2086 2091
@@ -2091,14 +2096,14 @@ static int __devinit pxafb_probe(struct platform_device *dev)
2091 goto failed_fbi; 2096 goto failed_fbi;
2092 } 2097 }
2093 2098
2094 r = request_mem_region(r->start, r->end - r->start + 1, dev->name); 2099 r = request_mem_region(r->start, resource_size(r), dev->name);
2095 if (r == NULL) { 2100 if (r == NULL) {
2096 dev_err(&dev->dev, "failed to request I/O memory\n"); 2101 dev_err(&dev->dev, "failed to request I/O memory\n");
2097 ret = -EBUSY; 2102 ret = -EBUSY;
2098 goto failed_fbi; 2103 goto failed_fbi;
2099 } 2104 }
2100 2105
2101 fbi->mmio_base = ioremap(r->start, r->end - r->start + 1); 2106 fbi->mmio_base = ioremap(r->start, resource_size(r));
2102 if (fbi->mmio_base == NULL) { 2107 if (fbi->mmio_base == NULL) {
2103 dev_err(&dev->dev, "failed to map I/O memory\n"); 2108 dev_err(&dev->dev, "failed to map I/O memory\n");
2104 ret = -EBUSY; 2109 ret = -EBUSY;
@@ -2197,7 +2202,7 @@ failed_free_dma:
2197failed_free_io: 2202failed_free_io:
2198 iounmap(fbi->mmio_base); 2203 iounmap(fbi->mmio_base);
2199failed_free_res: 2204failed_free_res:
2200 release_mem_region(r->start, r->end - r->start + 1); 2205 release_mem_region(r->start, resource_size(r));
2201failed_fbi: 2206failed_fbi:
2202 clk_put(fbi->clk); 2207 clk_put(fbi->clk);
2203 platform_set_drvdata(dev, NULL); 2208 platform_set_drvdata(dev, NULL);
@@ -2237,7 +2242,7 @@ static int __devexit pxafb_remove(struct platform_device *dev)
2237 iounmap(fbi->mmio_base); 2242 iounmap(fbi->mmio_base);
2238 2243
2239 r = platform_get_resource(dev, IORESOURCE_MEM, 0); 2244 r = platform_get_resource(dev, IORESOURCE_MEM, 0);
2240 release_mem_region(r->start, r->end - r->start + 1); 2245 release_mem_region(r->start, resource_size(r));
2241 2246
2242 clk_put(fbi->clk); 2247 clk_put(fbi->clk);
2243 kfree(fbi); 2248 kfree(fbi);
@@ -2248,11 +2253,12 @@ static int __devexit pxafb_remove(struct platform_device *dev)
2248static struct platform_driver pxafb_driver = { 2253static struct platform_driver pxafb_driver = {
2249 .probe = pxafb_probe, 2254 .probe = pxafb_probe,
2250 .remove = __devexit_p(pxafb_remove), 2255 .remove = __devexit_p(pxafb_remove),
2251 .suspend = pxafb_suspend,
2252 .resume = pxafb_resume,
2253 .driver = { 2256 .driver = {
2254 .owner = THIS_MODULE, 2257 .owner = THIS_MODULE,
2255 .name = "pxa2xx-fb", 2258 .name = "pxa2xx-fb",
2259#ifdef CONFIG_PM
2260 .pm = &pxafb_pm_ops,
2261#endif
2256 }, 2262 },
2257}; 2263};
2258 2264
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 5a72083dc67c..adf9632c6b1f 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -1036,7 +1036,7 @@ static int s3c_fb_resume(struct platform_device *pdev)
1036 1036
1037static struct platform_driver s3c_fb_driver = { 1037static struct platform_driver s3c_fb_driver = {
1038 .probe = s3c_fb_probe, 1038 .probe = s3c_fb_probe,
1039 .remove = s3c_fb_remove, 1039 .remove = __devexit_p(s3c_fb_remove),
1040 .suspend = s3c_fb_suspend, 1040 .suspend = s3c_fb_suspend,
1041 .resume = s3c_fb_resume, 1041 .resume = s3c_fb_resume,
1042 .driver = { 1042 .driver = {
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 7da0027e2409..aac661225c78 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -369,7 +369,9 @@ static void s3c2410fb_activate_var(struct fb_info *info)
369 void __iomem *regs = fbi->io; 369 void __iomem *regs = fbi->io;
370 int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT; 370 int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT;
371 struct fb_var_screeninfo *var = &info->var; 371 struct fb_var_screeninfo *var = &info->var;
372 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock) / 2; 372 int clkdiv;
373
374 clkdiv = DIV_ROUND_UP(s3c2410fb_calc_pixclk(fbi, var->pixclock), 2);
373 375
374 dprintk("%s: var->xres = %d\n", __func__, var->xres); 376 dprintk("%s: var->xres = %d\n", __func__, var->xres);
375 dprintk("%s: var->yres = %d\n", __func__, var->yres); 377 dprintk("%s: var->yres = %d\n", __func__, var->yres);
@@ -1119,7 +1121,7 @@ int __init s3c2410fb_init(void)
1119 int ret = platform_driver_register(&s3c2410fb_driver); 1121 int ret = platform_driver_register(&s3c2410fb_driver);
1120 1122
1121 if (ret == 0) 1123 if (ret == 0)
1122 ret = platform_driver_register(&s3c2412fb_driver);; 1124 ret = platform_driver_register(&s3c2412fb_driver);
1123 1125
1124 return ret; 1126 return ret;
1125} 1127}
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 10ddad8e17d6..cdaa873a6054 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -66,7 +66,7 @@
66 * - FrameBuffer memory is now allocated at run-time when the 66 * - FrameBuffer memory is now allocated at run-time when the
67 * driver is initialized. 67 * driver is initialized.
68 * 68 *
69 * 2000/04/10: Nicolas Pitre <nico@cam.org> 69 * 2000/04/10: Nicolas Pitre <nico@fluxnic.net>
70 * - Big cleanup for dynamic selection of machine type at run time. 70 * - Big cleanup for dynamic selection of machine type at run time.
71 * 71 *
72 * 2000/07/19: Jamey Hicks <jamey@crl.dec.com> 72 * 2000/07/19: Jamey Hicks <jamey@crl.dec.com>
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 07f22b625632..3ad5157f9899 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -14,6 +14,7 @@
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/fb.h> 15#include <linux/fb.h>
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/pm_runtime.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
@@ -22,35 +23,8 @@
22#include <asm/atomic.h> 23#include <asm/atomic.h>
23 24
24#define PALETTE_NR 16 25#define PALETTE_NR 16
25 26#define SIDE_B_OFFSET 0x1000
26struct sh_mobile_lcdc_priv; 27#define MIRROR_OFFSET 0x2000
27struct sh_mobile_lcdc_chan {
28 struct sh_mobile_lcdc_priv *lcdc;
29 unsigned long *reg_offs;
30 unsigned long ldmt1r_value;
31 unsigned long enabled; /* ME and SE in LDCNT2R */
32 struct sh_mobile_lcdc_chan_cfg cfg;
33 u32 pseudo_palette[PALETTE_NR];
34 struct fb_info *info;
35 dma_addr_t dma_handle;
36 struct fb_deferred_io defio;
37 struct scatterlist *sglist;
38 unsigned long frame_end;
39 wait_queue_head_t frame_end_wait;
40};
41
42struct sh_mobile_lcdc_priv {
43 void __iomem *base;
44 int irq;
45#ifdef CONFIG_HAVE_CLK
46 atomic_t clk_usecnt;
47 struct clk *dot_clk;
48 struct clk *clk;
49#endif
50 unsigned long lddckr;
51 struct sh_mobile_lcdc_chan ch[2];
52 int started;
53};
54 28
55/* shared registers */ 29/* shared registers */
56#define _LDDCKR 0x410 30#define _LDDCKR 0x410
@@ -59,17 +33,30 @@ struct sh_mobile_lcdc_priv {
59#define _LDSR 0x46c 33#define _LDSR 0x46c
60#define _LDCNT1R 0x470 34#define _LDCNT1R 0x470
61#define _LDCNT2R 0x474 35#define _LDCNT2R 0x474
36#define _LDRCNTR 0x478
62#define _LDDDSR 0x47c 37#define _LDDDSR 0x47c
63#define _LDDWD0R 0x800 38#define _LDDWD0R 0x800
64#define _LDDRDR 0x840 39#define _LDDRDR 0x840
65#define _LDDWAR 0x900 40#define _LDDWAR 0x900
66#define _LDDRAR 0x904 41#define _LDDRAR 0x904
67 42
43/* shared registers and their order for context save/restore */
44static int lcdc_shared_regs[] = {
45 _LDDCKR,
46 _LDDCKSTPR,
47 _LDINTR,
48 _LDDDSR,
49 _LDCNT1R,
50 _LDCNT2R,
51};
52#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
53
68/* per-channel registers */ 54/* per-channel registers */
69enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, 55enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
70 LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR }; 56 LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
57 NR_CH_REGS };
71 58
72static unsigned long lcdc_offs_mainlcd[] = { 59static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
73 [LDDCKPAT1R] = 0x400, 60 [LDDCKPAT1R] = 0x400,
74 [LDDCKPAT2R] = 0x404, 61 [LDDCKPAT2R] = 0x404,
75 [LDMT1R] = 0x418, 62 [LDMT1R] = 0x418,
@@ -87,7 +74,7 @@ static unsigned long lcdc_offs_mainlcd[] = {
87 [LDPMR] = 0x460, 74 [LDPMR] = 0x460,
88}; 75};
89 76
90static unsigned long lcdc_offs_sublcd[] = { 77static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
91 [LDDCKPAT1R] = 0x408, 78 [LDDCKPAT1R] = 0x408,
92 [LDDCKPAT2R] = 0x40c, 79 [LDDCKPAT2R] = 0x40c,
93 [LDMT1R] = 0x600, 80 [LDMT1R] = 0x600,
@@ -110,12 +97,80 @@ static unsigned long lcdc_offs_sublcd[] = {
110#define DISPLAY_BEU 0x00000008 97#define DISPLAY_BEU 0x00000008
111#define LCDC_ENABLE 0x00000001 98#define LCDC_ENABLE 0x00000001
112#define LDINTR_FE 0x00000400 99#define LDINTR_FE 0x00000400
100#define LDINTR_VSE 0x00000200
101#define LDINTR_VEE 0x00000100
113#define LDINTR_FS 0x00000004 102#define LDINTR_FS 0x00000004
103#define LDINTR_VSS 0x00000002
104#define LDINTR_VES 0x00000001
105#define LDRCNTR_SRS 0x00020000
106#define LDRCNTR_SRC 0x00010000
107#define LDRCNTR_MRS 0x00000002
108#define LDRCNTR_MRC 0x00000001
109
110struct sh_mobile_lcdc_priv;
111struct sh_mobile_lcdc_chan {
112 struct sh_mobile_lcdc_priv *lcdc;
113 unsigned long *reg_offs;
114 unsigned long ldmt1r_value;
115 unsigned long enabled; /* ME and SE in LDCNT2R */
116 struct sh_mobile_lcdc_chan_cfg cfg;
117 u32 pseudo_palette[PALETTE_NR];
118 unsigned long saved_ch_regs[NR_CH_REGS];
119 struct fb_info *info;
120 dma_addr_t dma_handle;
121 struct fb_deferred_io defio;
122 struct scatterlist *sglist;
123 unsigned long frame_end;
124 unsigned long pan_offset;
125 unsigned long new_pan_offset;
126 wait_queue_head_t frame_end_wait;
127};
128
129struct sh_mobile_lcdc_priv {
130 void __iomem *base;
131 int irq;
132 atomic_t hw_usecnt;
133 struct device *dev;
134 struct clk *dot_clk;
135 unsigned long lddckr;
136 struct sh_mobile_lcdc_chan ch[2];
137 unsigned long saved_shared_regs[NR_SHARED_REGS];
138 int started;
139};
140
141static bool banked(int reg_nr)
142{
143 switch (reg_nr) {
144 case LDMT1R:
145 case LDMT2R:
146 case LDMT3R:
147 case LDDFR:
148 case LDSM1R:
149 case LDSA1R:
150 case LDMLSR:
151 case LDHCNR:
152 case LDHSYNR:
153 case LDVLNR:
154 case LDVSYNR:
155 return true;
156 }
157 return false;
158}
114 159
115static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, 160static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
116 int reg_nr, unsigned long data) 161 int reg_nr, unsigned long data)
117{ 162{
118 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]); 163 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]);
164 if (banked(reg_nr))
165 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
166 SIDE_B_OFFSET);
167}
168
169static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan,
170 int reg_nr, unsigned long data)
171{
172 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
173 MIRROR_OFFSET);
119} 174}
120 175
121static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan, 176static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
@@ -156,6 +211,7 @@ static void lcdc_sys_write_index(void *handle, unsigned long data)
156 lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000); 211 lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000);
157 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); 212 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
158 lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 213 lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
214 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
159} 215}
160 216
161static void lcdc_sys_write_data(void *handle, unsigned long data) 217static void lcdc_sys_write_data(void *handle, unsigned long data)
@@ -165,6 +221,7 @@ static void lcdc_sys_write_data(void *handle, unsigned long data)
165 lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000); 221 lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000);
166 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); 222 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
167 lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 223 lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
224 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
168} 225}
169 226
170static unsigned long lcdc_sys_read_data(void *handle) 227static unsigned long lcdc_sys_read_data(void *handle)
@@ -175,8 +232,9 @@ static unsigned long lcdc_sys_read_data(void *handle)
175 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); 232 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
176 lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 233 lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
177 udelay(1); 234 udelay(1);
235 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
178 236
179 return lcdc_read(ch->lcdc, _LDDRDR) & 0xffff; 237 return lcdc_read(ch->lcdc, _LDDRDR) & 0x3ffff;
180} 238}
181 239
182struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = { 240struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
@@ -185,11 +243,10 @@ struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
185 lcdc_sys_read_data, 243 lcdc_sys_read_data,
186}; 244};
187 245
188#ifdef CONFIG_HAVE_CLK
189static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) 246static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
190{ 247{
191 if (atomic_inc_and_test(&priv->clk_usecnt)) { 248 if (atomic_inc_and_test(&priv->hw_usecnt)) {
192 clk_enable(priv->clk); 249 pm_runtime_get_sync(priv->dev);
193 if (priv->dot_clk) 250 if (priv->dot_clk)
194 clk_enable(priv->dot_clk); 251 clk_enable(priv->dot_clk);
195 } 252 }
@@ -197,16 +254,12 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
197 254
198static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) 255static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
199{ 256{
200 if (atomic_sub_return(1, &priv->clk_usecnt) == -1) { 257 if (atomic_sub_return(1, &priv->hw_usecnt) == -1) {
201 if (priv->dot_clk) 258 if (priv->dot_clk)
202 clk_disable(priv->dot_clk); 259 clk_disable(priv->dot_clk);
203 clk_disable(priv->clk); 260 pm_runtime_put(priv->dev);
204 } 261 }
205} 262}
206#else
207static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {}
208static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {}
209#endif
210 263
211static int sh_mobile_lcdc_sginit(struct fb_info *info, 264static int sh_mobile_lcdc_sginit(struct fb_info *info,
212 struct list_head *pagelist) 265 struct list_head *pagelist)
@@ -255,30 +308,52 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
255 struct sh_mobile_lcdc_priv *priv = data; 308 struct sh_mobile_lcdc_priv *priv = data;
256 struct sh_mobile_lcdc_chan *ch; 309 struct sh_mobile_lcdc_chan *ch;
257 unsigned long tmp; 310 unsigned long tmp;
311 unsigned long ldintr;
258 int is_sub; 312 int is_sub;
259 int k; 313 int k;
260 314
261 /* acknowledge interrupt */ 315 /* acknowledge interrupt */
262 tmp = lcdc_read(priv, _LDINTR); 316 ldintr = tmp = lcdc_read(priv, _LDINTR);
263 tmp &= 0xffffff00; /* mask in high 24 bits */ 317 /*
264 tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */ 318 * disable further VSYNC End IRQs, preserve all other enabled IRQs,
319 * write 0 to bits 0-6 to ack all triggered IRQs.
320 */
321 tmp &= 0xffffff00 & ~LDINTR_VEE;
265 lcdc_write(priv, _LDINTR, tmp); 322 lcdc_write(priv, _LDINTR, tmp);
266 323
267 /* figure out if this interrupt is for main or sub lcd */ 324 /* figure out if this interrupt is for main or sub lcd */
268 is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0; 325 is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0;
269 326
270 /* wake up channel and disable clocks*/ 327 /* wake up channel and disable clocks */
271 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 328 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
272 ch = &priv->ch[k]; 329 ch = &priv->ch[k];
273 330
274 if (!ch->enabled) 331 if (!ch->enabled)
275 continue; 332 continue;
276 333
277 if (is_sub == lcdc_chan_is_sublcd(ch)) { 334 /* Frame Start */
278 ch->frame_end = 1; 335 if (ldintr & LDINTR_FS) {
279 wake_up(&ch->frame_end_wait); 336 if (is_sub == lcdc_chan_is_sublcd(ch)) {
337 ch->frame_end = 1;
338 wake_up(&ch->frame_end_wait);
280 339
281 sh_mobile_lcdc_clk_off(priv); 340 sh_mobile_lcdc_clk_off(priv);
341 }
342 }
343
344 /* VSYNC End */
345 if (ldintr & LDINTR_VES) {
346 unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR);
347 /* Set the source address for the next refresh */
348 lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle +
349 ch->new_pan_offset);
350 if (lcdc_chan_is_sublcd(ch))
351 lcdc_write(ch->lcdc, _LDRCNTR,
352 ldrcntr ^ LDRCNTR_SRS);
353 else
354 lcdc_write(ch->lcdc, _LDRCNTR,
355 ldrcntr ^ LDRCNTR_MRS);
356 ch->pan_offset = ch->new_pan_offset;
282 } 357 }
283 } 358 }
284 359
@@ -520,7 +595,6 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
520 board_cfg = &ch->cfg.board_cfg; 595 board_cfg = &ch->cfg.board_cfg;
521 if (board_cfg->display_off) 596 if (board_cfg->display_off)
522 board_cfg->display_off(board_cfg->board_data); 597 board_cfg->display_off(board_cfg->board_data);
523
524 } 598 }
525 599
526 /* stop the lcdc */ 600 /* stop the lcdc */
@@ -579,9 +653,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
579 int clock_source, 653 int clock_source,
580 struct sh_mobile_lcdc_priv *priv) 654 struct sh_mobile_lcdc_priv *priv)
581{ 655{
582#ifdef CONFIG_HAVE_CLK
583 char clk_name[8];
584#endif
585 char *str; 656 char *str;
586 int icksel; 657 int icksel;
587 658
@@ -595,25 +666,21 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
595 666
596 priv->lddckr = icksel << 16; 667 priv->lddckr = icksel << 16;
597 668
598#ifdef CONFIG_HAVE_CLK
599 atomic_set(&priv->clk_usecnt, -1);
600 snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id);
601 priv->clk = clk_get(&pdev->dev, clk_name);
602 if (IS_ERR(priv->clk)) {
603 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
604 return PTR_ERR(priv->clk);
605 }
606
607 if (str) { 669 if (str) {
608 priv->dot_clk = clk_get(&pdev->dev, str); 670 priv->dot_clk = clk_get(&pdev->dev, str);
609 if (IS_ERR(priv->dot_clk)) { 671 if (IS_ERR(priv->dot_clk)) {
610 dev_err(&pdev->dev, "cannot get dot clock %s\n", str); 672 dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
611 clk_put(priv->clk);
612 return PTR_ERR(priv->dot_clk); 673 return PTR_ERR(priv->dot_clk);
613 } 674 }
614 } 675 }
615#endif 676 atomic_set(&priv->hw_usecnt, -1);
616 677
678 /* Runtime PM support involves two step for this driver:
679 * 1) Enable Runtime PM
680 * 2) Force Runtime PM Resume since hardware is accessed from probe()
681 */
682 pm_runtime_enable(priv->dev);
683 pm_runtime_resume(priv->dev);
617 return 0; 684 return 0;
618} 685}
619 686
@@ -646,6 +713,9 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix = {
646 .type = FB_TYPE_PACKED_PIXELS, 713 .type = FB_TYPE_PACKED_PIXELS,
647 .visual = FB_VISUAL_TRUECOLOR, 714 .visual = FB_VISUAL_TRUECOLOR,
648 .accel = FB_ACCEL_NONE, 715 .accel = FB_ACCEL_NONE,
716 .xpanstep = 0,
717 .ypanstep = 1,
718 .ywrapstep = 0,
649}; 719};
650 720
651static void sh_mobile_lcdc_fillrect(struct fb_info *info, 721static void sh_mobile_lcdc_fillrect(struct fb_info *info,
@@ -669,13 +739,38 @@ static void sh_mobile_lcdc_imageblit(struct fb_info *info,
669 sh_mobile_lcdc_deferred_io_touch(info); 739 sh_mobile_lcdc_deferred_io_touch(info);
670} 740}
671 741
742static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
743 struct fb_info *info)
744{
745 struct sh_mobile_lcdc_chan *ch = info->par;
746
747 if (info->var.xoffset == var->xoffset &&
748 info->var.yoffset == var->yoffset)
749 return 0; /* No change, do nothing */
750
751 ch->new_pan_offset = (var->yoffset * info->fix.line_length) +
752 (var->xoffset * (info->var.bits_per_pixel / 8));
753
754 if (ch->new_pan_offset != ch->pan_offset) {
755 unsigned long ldintr;
756 ldintr = lcdc_read(ch->lcdc, _LDINTR);
757 ldintr |= LDINTR_VEE;
758 lcdc_write(ch->lcdc, _LDINTR, ldintr);
759 sh_mobile_lcdc_deferred_io_touch(info);
760 }
761
762 return 0;
763}
764
672static struct fb_ops sh_mobile_lcdc_ops = { 765static struct fb_ops sh_mobile_lcdc_ops = {
766 .owner = THIS_MODULE,
673 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 767 .fb_setcolreg = sh_mobile_lcdc_setcolreg,
674 .fb_read = fb_sys_read, 768 .fb_read = fb_sys_read,
675 .fb_write = fb_sys_write, 769 .fb_write = fb_sys_write,
676 .fb_fillrect = sh_mobile_lcdc_fillrect, 770 .fb_fillrect = sh_mobile_lcdc_fillrect,
677 .fb_copyarea = sh_mobile_lcdc_copyarea, 771 .fb_copyarea = sh_mobile_lcdc_copyarea,
678 .fb_imageblit = sh_mobile_lcdc_imageblit, 772 .fb_imageblit = sh_mobile_lcdc_imageblit,
773 .fb_pan_display = sh_mobile_fb_pan_display,
679}; 774};
680 775
681static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) 776static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -731,9 +826,59 @@ static int sh_mobile_lcdc_resume(struct device *dev)
731 return sh_mobile_lcdc_start(platform_get_drvdata(pdev)); 826 return sh_mobile_lcdc_start(platform_get_drvdata(pdev));
732} 827}
733 828
829static int sh_mobile_lcdc_runtime_suspend(struct device *dev)
830{
831 struct platform_device *pdev = to_platform_device(dev);
832 struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
833 struct sh_mobile_lcdc_chan *ch;
834 int k, n;
835
836 /* save per-channel registers */
837 for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
838 ch = &p->ch[k];
839 if (!ch->enabled)
840 continue;
841 for (n = 0; n < NR_CH_REGS; n++)
842 ch->saved_ch_regs[n] = lcdc_read_chan(ch, n);
843 }
844
845 /* save shared registers */
846 for (n = 0; n < NR_SHARED_REGS; n++)
847 p->saved_shared_regs[n] = lcdc_read(p, lcdc_shared_regs[n]);
848
849 /* turn off LCDC hardware */
850 lcdc_write(p, _LDCNT1R, 0);
851 return 0;
852}
853
854static int sh_mobile_lcdc_runtime_resume(struct device *dev)
855{
856 struct platform_device *pdev = to_platform_device(dev);
857 struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
858 struct sh_mobile_lcdc_chan *ch;
859 int k, n;
860
861 /* restore per-channel registers */
862 for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
863 ch = &p->ch[k];
864 if (!ch->enabled)
865 continue;
866 for (n = 0; n < NR_CH_REGS; n++)
867 lcdc_write_chan(ch, n, ch->saved_ch_regs[n]);
868 }
869
870 /* restore shared registers */
871 for (n = 0; n < NR_SHARED_REGS; n++)
872 lcdc_write(p, lcdc_shared_regs[n], p->saved_shared_regs[n]);
873
874 return 0;
875}
876
734static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { 877static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
735 .suspend = sh_mobile_lcdc_suspend, 878 .suspend = sh_mobile_lcdc_suspend,
736 .resume = sh_mobile_lcdc_resume, 879 .resume = sh_mobile_lcdc_resume,
880 .runtime_suspend = sh_mobile_lcdc_runtime_suspend,
881 .runtime_resume = sh_mobile_lcdc_runtime_resume,
737}; 882};
738 883
739static int sh_mobile_lcdc_remove(struct platform_device *pdev); 884static int sh_mobile_lcdc_remove(struct platform_device *pdev);
@@ -778,6 +923,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
778 } 923 }
779 924
780 priv->irq = i; 925 priv->irq = i;
926 priv->dev = &pdev->dev;
781 platform_set_drvdata(pdev, priv); 927 platform_set_drvdata(pdev, priv);
782 pdata = pdev->dev.platform_data; 928 pdata = pdev->dev.platform_data;
783 929
@@ -792,6 +938,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
792 goto err1; 938 goto err1;
793 } 939 }
794 init_waitqueue_head(&priv->ch[i].frame_end_wait); 940 init_waitqueue_head(&priv->ch[i].frame_end_wait);
941 priv->ch[j].pan_offset = 0;
942 priv->ch[j].new_pan_offset = 0;
795 943
796 switch (pdata->ch[i].chan) { 944 switch (pdata->ch[i].chan) {
797 case LCDC_CHAN_MAINLCD: 945 case LCDC_CHAN_MAINLCD:
@@ -834,7 +982,9 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
834 info = priv->ch[i].info; 982 info = priv->ch[i].info;
835 info->fbops = &sh_mobile_lcdc_ops; 983 info->fbops = &sh_mobile_lcdc_ops;
836 info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres; 984 info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
837 info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres; 985 info->var.yres = cfg->lcd_cfg.yres;
986 /* Default Y virtual resolution is 2x panel size */
987 info->var.yres_virtual = info->var.yres * 2;
838 info->var.width = cfg->lcd_size_cfg.width; 988 info->var.width = cfg->lcd_size_cfg.width;
839 info->var.height = cfg->lcd_size_cfg.height; 989 info->var.height = cfg->lcd_size_cfg.height;
840 info->var.activate = FB_ACTIVATE_NOW; 990 info->var.activate = FB_ACTIVATE_NOW;
@@ -844,7 +994,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
844 994
845 info->fix = sh_mobile_lcdc_fix; 995 info->fix = sh_mobile_lcdc_fix;
846 info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8); 996 info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8);
847 info->fix.smem_len = info->fix.line_length * cfg->lcd_cfg.yres; 997 info->fix.smem_len = info->fix.line_length *
998 info->var.yres_virtual;
848 999
849 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, 1000 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
850 &priv->ch[i].dma_handle, GFP_KERNEL); 1001 &priv->ch[i].dma_handle, GFP_KERNEL);
@@ -947,11 +1098,10 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
947 framebuffer_release(info); 1098 framebuffer_release(info);
948 } 1099 }
949 1100
950#ifdef CONFIG_HAVE_CLK
951 if (priv->dot_clk) 1101 if (priv->dot_clk)
952 clk_put(priv->dot_clk); 1102 clk_put(priv->dot_clk);
953 clk_put(priv->clk); 1103
954#endif 1104 pm_runtime_disable(priv->dev);
955 1105
956 if (priv->base) 1106 if (priv->base)
957 iounmap(priv->base); 1107 iounmap(priv->base);
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 4a067f0d0ceb..a4e05e4d7501 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -698,8 +698,8 @@ sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int
698 rate, sisfb_vrate[i].refresh); 698 rate, sisfb_vrate[i].refresh);
699 ivideo->rate_idx = sisfb_vrate[i].idx; 699 ivideo->rate_idx = sisfb_vrate[i].idx;
700 ivideo->refresh_rate = sisfb_vrate[i].refresh; 700 ivideo->refresh_rate = sisfb_vrate[i].refresh;
701 } else if(((rate - sisfb_vrate[i-1].refresh) <= 2) 701 } else if((sisfb_vrate[i].idx != 1) &&
702 && (sisfb_vrate[i].idx != 1)) { 702 ((rate - sisfb_vrate[i-1].refresh) <= 2)) {
703 DPRINTK("sisfb: Adjusting rate from %d down to %d\n", 703 DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
704 rate, sisfb_vrate[i-1].refresh); 704 rate, sisfb_vrate[i-1].refresh);
705 ivideo->rate_idx = sisfb_vrate[i-1].idx; 705 ivideo->rate_idx = sisfb_vrate[i-1].idx;
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
index 705c85360526..bef4aae388d0 100644
--- a/drivers/video/sis/vstruct.h
+++ b/drivers/video/sis/vstruct.h
@@ -342,7 +342,7 @@ struct SiS_Private
342 unsigned short SiS_RY4COE; 342 unsigned short SiS_RY4COE;
343 unsigned short SiS_LCDHDES; 343 unsigned short SiS_LCDHDES;
344 unsigned short SiS_LCDVDES; 344 unsigned short SiS_LCDVDES;
345 unsigned short SiS_DDC_Port; 345 SISIOADDRESS SiS_DDC_Port;
346 unsigned short SiS_DDC_Index; 346 unsigned short SiS_DDC_Index;
347 unsigned short SiS_DDC_Data; 347 unsigned short SiS_DDC_Data;
348 unsigned short SiS_DDC_NData; 348 unsigned short SiS_DDC_NData;
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index a1eb0862255b..6913fe168c25 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -974,7 +974,7 @@ static int tmiofb_resume(struct platform_device *dev)
974{ 974{
975 struct fb_info *info = platform_get_drvdata(dev); 975 struct fb_info *info = platform_get_drvdata(dev);
976 struct mfd_cell *cell = dev->dev.platform_data; 976 struct mfd_cell *cell = dev->dev.platform_data;
977 int retval; 977 int retval = 0;
978 978
979 acquire_console_sem(); 979 acquire_console_sem();
980 980
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index ca5b4643a401..e98baf6916b8 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -67,9 +67,8 @@ static DEFINE_MUTEX(uvfb_lock);
67 * find the kernel part of the task struct, copy the registers and 67 * find the kernel part of the task struct, copy the registers and
68 * the buffer contents and then complete the task. 68 * the buffer contents and then complete the task.
69 */ 69 */
70static void uvesafb_cn_callback(void *data) 70static void uvesafb_cn_callback(struct cn_msg *msg)
71{ 71{
72 struct cn_msg *msg = data;
73 struct uvesafb_task *utask; 72 struct uvesafb_task *utask;
74 struct uvesafb_ktask *task; 73 struct uvesafb_ktask *task;
75 74
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index 45c54bfe99bb..9d4f3a49ba4a 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -20,229 +20,430 @@
20 */ 20 */
21#include "global.h" 21#include "global.h"
22 22
23void viafb_init_accel(void) 23static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
24 u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
25 u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
26 u32 fg_color, u32 bg_color, u8 fill_rop)
24{ 27{
25 viaparinfo->fbmem_free -= CURSOR_SIZE; 28 u32 ge_cmd = 0, tmp, i;
26 viaparinfo->cursor_start = viaparinfo->fbmem_free;
27 viaparinfo->fbmem_used += CURSOR_SIZE;
28 29
29 /* Reverse 8*1024 memory space for cursor image */ 30 if (!op || op > 3) {
30 viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE); 31 printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op);
31 viaparinfo->VQ_start = viaparinfo->fbmem_free; 32 return -EINVAL;
32 viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1; 33 }
33 viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); }
34
35void viafb_init_2d_engine(void)
36{
37 u32 dwVQStartAddr, dwVQEndAddr;
38 u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
39
40 /* init 2D engine regs to reset 2D engine */
41 writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE);
42 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
43 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS);
44 writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION);
45 writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR);
46 writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR);
47 writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR);
48 writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL);
49 writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR);
50 writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET);
51 writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL);
52 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
53 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
54 writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH);
55 writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1);
56
57 /* Init AGP and VQ regs */
58 switch (viaparinfo->chip_info->gfx_chip_name) {
59 case UNICHROME_K8M890:
60 case UNICHROME_P4M900:
61 writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET);
62 writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
63 writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
64 break;
65 34
66 default: 35 if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) {
67 writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET); 36 if (src_x < dst_x) {
68 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 37 ge_cmd |= 0x00008000;
69 writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE); 38 src_x += width - 1;
70 writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 39 dst_x += width - 1;
71 writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 40 }
72 writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 41 if (src_y < dst_y) {
73 writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 42 ge_cmd |= 0x00004000;
74 writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 43 src_y += height - 1;
75 writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 44 dst_y += height - 1;
76 45 }
77 writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET);
78 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
79 break;
80 } 46 }
81 if (viaparinfo->VQ_start != 0) { 47
82 /* Enable VQ */ 48 if (op == VIA_BITBLT_FILL) {
83 dwVQStartAddr = viaparinfo->VQ_start; 49 switch (fill_rop) {
84 dwVQEndAddr = viaparinfo->VQ_end; 50 case 0x00: /* blackness */
85 51 case 0x5A: /* pattern inversion */
86 dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF); 52 case 0xF0: /* pattern copy */
87 dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF); 53 case 0xFF: /* whiteness */
88 dwVQStartEndH = 0x52000000 |
89 ((dwVQStartAddr & 0xFF000000) >> 24) |
90 ((dwVQEndAddr & 0xFF000000) >> 16);
91 dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
92 switch (viaparinfo->chip_info->gfx_chip_name) {
93 case UNICHROME_K8M890:
94 case UNICHROME_P4M900:
95 dwVQStartL |= 0x20000000;
96 dwVQEndL |= 0x20000000;
97 dwVQStartEndH |= 0x20000000;
98 dwVQLen |= 0x20000000;
99 break; 54 break;
100 default: 55 default:
101 break; 56 printk(KERN_WARNING "hw_bitblt_1: Invalid fill rop: "
57 "%u\n", fill_rop);
58 return -EINVAL;
102 } 59 }
60 }
103 61
104 switch (viaparinfo->chip_info->gfx_chip_name) { 62 switch (dst_bpp) {
105 case UNICHROME_K8M890: 63 case 8:
106 case UNICHROME_P4M900: 64 tmp = 0x00000000;
107 writel(0x00100000, 65 break;
108 viaparinfo->io_virt + VIA_REG_CR_TRANSET); 66 case 16:
109 writel(dwVQStartEndH, 67 tmp = 0x00000100;
110 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 68 break;
111 writel(dwVQStartL, 69 case 32:
112 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 70 tmp = 0x00000300;
113 writel(dwVQEndL, 71 break;
114 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 72 default:
115 writel(dwVQLen, 73 printk(KERN_WARNING "hw_bitblt_1: Unsupported bpp %d\n",
116 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 74 dst_bpp);
117 writel(0x74301001, 75 return -EINVAL;
118 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 76 }
119 writel(0x00000000, 77 writel(tmp, engine + 0x04);
120 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 78
121 break; 79 if (op != VIA_BITBLT_FILL) {
122 default: 80 if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000)
123 writel(0x00FE0000, 81 || src_y & 0xFFFFF000) {
124 viaparinfo->io_virt + VIA_REG_TRANSET); 82 printk(KERN_WARNING "hw_bitblt_1: Unsupported source "
125 writel(0x080003FE, 83 "x/y %d %d\n", src_x, src_y);
126 viaparinfo->io_virt + VIA_REG_TRANSPACE); 84 return -EINVAL;
127 writel(0x0A00027C,
128 viaparinfo->io_virt + VIA_REG_TRANSPACE);
129 writel(0x0B000260,
130 viaparinfo->io_virt + VIA_REG_TRANSPACE);
131 writel(0x0C000274,
132 viaparinfo->io_virt + VIA_REG_TRANSPACE);
133 writel(0x0D000264,
134 viaparinfo->io_virt + VIA_REG_TRANSPACE);
135 writel(0x0E000000,
136 viaparinfo->io_virt + VIA_REG_TRANSPACE);
137 writel(0x0F000020,
138 viaparinfo->io_virt + VIA_REG_TRANSPACE);
139 writel(0x1000027E,
140 viaparinfo->io_virt + VIA_REG_TRANSPACE);
141 writel(0x110002FE,
142 viaparinfo->io_virt + VIA_REG_TRANSPACE);
143 writel(0x200F0060,
144 viaparinfo->io_virt + VIA_REG_TRANSPACE);
145
146 writel(0x00000006,
147 viaparinfo->io_virt + VIA_REG_TRANSPACE);
148 writel(0x40008C0F,
149 viaparinfo->io_virt + VIA_REG_TRANSPACE);
150 writel(0x44000000,
151 viaparinfo->io_virt + VIA_REG_TRANSPACE);
152 writel(0x45080C04,
153 viaparinfo->io_virt + VIA_REG_TRANSPACE);
154 writel(0x46800408,
155 viaparinfo->io_virt + VIA_REG_TRANSPACE);
156
157 writel(dwVQStartEndH,
158 viaparinfo->io_virt + VIA_REG_TRANSPACE);
159 writel(dwVQStartL,
160 viaparinfo->io_virt + VIA_REG_TRANSPACE);
161 writel(dwVQEndL,
162 viaparinfo->io_virt + VIA_REG_TRANSPACE);
163 writel(dwVQLen,
164 viaparinfo->io_virt + VIA_REG_TRANSPACE);
165 break;
166 } 85 }
167 } else { 86 tmp = src_x | (src_y << 16);
168 /* Disable VQ */ 87 writel(tmp, engine + 0x08);
169 switch (viaparinfo->chip_info->gfx_chip_name) { 88 }
170 case UNICHROME_K8M890: 89
171 case UNICHROME_P4M900: 90 if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) {
172 writel(0x00100000, 91 printk(KERN_WARNING "hw_bitblt_1: Unsupported destination x/y "
173 viaparinfo->io_virt + VIA_REG_CR_TRANSET); 92 "%d %d\n", dst_x, dst_y);
174 writel(0x74301000, 93 return -EINVAL;
175 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 94 }
176 break; 95 tmp = dst_x | (dst_y << 16);
177 default: 96 writel(tmp, engine + 0x0C);
178 writel(0x00FE0000, 97
179 viaparinfo->io_virt + VIA_REG_TRANSET); 98 if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) {
180 writel(0x00000004, 99 printk(KERN_WARNING "hw_bitblt_1: Unsupported width/height "
181 viaparinfo->io_virt + VIA_REG_TRANSPACE); 100 "%d %d\n", width, height);
182 writel(0x40008C0F, 101 return -EINVAL;
183 viaparinfo->io_virt + VIA_REG_TRANSPACE); 102 }
184 writel(0x44000000, 103 tmp = (width - 1) | ((height - 1) << 16);
185 viaparinfo->io_virt + VIA_REG_TRANSPACE); 104 writel(tmp, engine + 0x10);
186 writel(0x45080C04, 105
187 viaparinfo->io_virt + VIA_REG_TRANSPACE); 106 if (op != VIA_BITBLT_COLOR)
188 writel(0x46800408, 107 writel(fg_color, engine + 0x18);
189 viaparinfo->io_virt + VIA_REG_TRANSPACE); 108
190 break; 109 if (op == VIA_BITBLT_MONO)
110 writel(bg_color, engine + 0x1C);
111
112 if (op != VIA_BITBLT_FILL) {
113 tmp = src_mem ? 0 : src_addr;
114 if (dst_addr & 0xE0000007) {
115 printk(KERN_WARNING "hw_bitblt_1: Unsupported source "
116 "address %X\n", tmp);
117 return -EINVAL;
191 } 118 }
119 tmp >>= 3;
120 writel(tmp, engine + 0x30);
121 }
122
123 if (dst_addr & 0xE0000007) {
124 printk(KERN_WARNING "hw_bitblt_1: Unsupported destination "
125 "address %X\n", dst_addr);
126 return -EINVAL;
192 } 127 }
128 tmp = dst_addr >> 3;
129 writel(tmp, engine + 0x34);
193 130
194 viafb_set_2d_color_depth(viaparinfo->bpp); 131 if (op == VIA_BITBLT_FILL)
132 tmp = 0;
133 else
134 tmp = src_pitch;
135 if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) {
136 printk(KERN_WARNING "hw_bitblt_1: Unsupported pitch %X %X\n",
137 tmp, dst_pitch);
138 return -EINVAL;
139 }
140 tmp = (tmp >> 3) | (dst_pitch << (16 - 3));
141 writel(tmp, engine + 0x38);
142
143 if (op == VIA_BITBLT_FILL)
144 ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
145 else {
146 ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
147 if (src_mem)
148 ge_cmd |= 0x00000040;
149 if (op == VIA_BITBLT_MONO)
150 ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
151 else
152 ge_cmd |= 0x00000001;
153 }
154 writel(ge_cmd, engine);
195 155
196 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); 156 if (op == VIA_BITBLT_FILL || !src_mem)
197 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE); 157 return 0;
198 158
199 writel(VIA_PITCH_ENABLE | 159 tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) +
200 (((viaparinfo->hres * 160 3) >> 2;
201 viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres * 161
202 viaparinfo-> 162 for (i = 0; i < tmp; i++)
203 bpp >> 3) >> 3) << 16)), 163 writel(src_mem[i], engine + VIA_MMIO_BLTBASE);
204 viaparinfo->io_virt + VIA_REG_PITCH); 164
165 return 0;
205} 166}
206 167
207void viafb_set_2d_color_depth(int bpp) 168static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
169 u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
170 u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
171 u32 fg_color, u32 bg_color, u8 fill_rop)
208{ 172{
209 u32 dwGEMode; 173 u32 ge_cmd = 0, tmp, i;
174
175 if (!op || op > 3) {
176 printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op);
177 return -EINVAL;
178 }
210 179
211 dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF; 180 if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) {
181 if (src_x < dst_x) {
182 ge_cmd |= 0x00008000;
183 src_x += width - 1;
184 dst_x += width - 1;
185 }
186 if (src_y < dst_y) {
187 ge_cmd |= 0x00004000;
188 src_y += height - 1;
189 dst_y += height - 1;
190 }
191 }
212 192
213 switch (bpp) { 193 if (op == VIA_BITBLT_FILL) {
194 switch (fill_rop) {
195 case 0x00: /* blackness */
196 case 0x5A: /* pattern inversion */
197 case 0xF0: /* pattern copy */
198 case 0xFF: /* whiteness */
199 break;
200 default:
201 printk(KERN_WARNING "hw_bitblt_2: Invalid fill rop: "
202 "%u\n", fill_rop);
203 return -EINVAL;
204 }
205 }
206
207 switch (dst_bpp) {
208 case 8:
209 tmp = 0x00000000;
210 break;
214 case 16: 211 case 16:
215 dwGEMode |= VIA_GEM_16bpp; 212 tmp = 0x00000100;
216 break; 213 break;
217 case 32: 214 case 32:
218 dwGEMode |= VIA_GEM_32bpp; 215 tmp = 0x00000300;
219 break; 216 break;
220 default: 217 default:
221 dwGEMode |= VIA_GEM_8bpp; 218 printk(KERN_WARNING "hw_bitblt_2: Unsupported bpp %d\n",
222 break; 219 dst_bpp);
220 return -EINVAL;
221 }
222 writel(tmp, engine + 0x04);
223
224 if (op == VIA_BITBLT_FILL)
225 tmp = 0;
226 else
227 tmp = src_pitch;
228 if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) {
229 printk(KERN_WARNING "hw_bitblt_2: Unsupported pitch %X %X\n",
230 tmp, dst_pitch);
231 return -EINVAL;
232 }
233 tmp = (tmp >> 3) | (dst_pitch << (16 - 3));
234 writel(tmp, engine + 0x08);
235
236 if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) {
237 printk(KERN_WARNING "hw_bitblt_2: Unsupported width/height "
238 "%d %d\n", width, height);
239 return -EINVAL;
240 }
241 tmp = (width - 1) | ((height - 1) << 16);
242 writel(tmp, engine + 0x0C);
243
244 if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) {
245 printk(KERN_WARNING "hw_bitblt_2: Unsupported destination x/y "
246 "%d %d\n", dst_x, dst_y);
247 return -EINVAL;
248 }
249 tmp = dst_x | (dst_y << 16);
250 writel(tmp, engine + 0x10);
251
252 if (dst_addr & 0xE0000007) {
253 printk(KERN_WARNING "hw_bitblt_2: Unsupported destination "
254 "address %X\n", dst_addr);
255 return -EINVAL;
256 }
257 tmp = dst_addr >> 3;
258 writel(tmp, engine + 0x14);
259
260 if (op != VIA_BITBLT_FILL) {
261 if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000)
262 || src_y & 0xFFFFF000) {
263 printk(KERN_WARNING "hw_bitblt_2: Unsupported source "
264 "x/y %d %d\n", src_x, src_y);
265 return -EINVAL;
266 }
267 tmp = src_x | (src_y << 16);
268 writel(tmp, engine + 0x18);
269
270 tmp = src_mem ? 0 : src_addr;
271 if (dst_addr & 0xE0000007) {
272 printk(KERN_WARNING "hw_bitblt_2: Unsupported source "
273 "address %X\n", tmp);
274 return -EINVAL;
275 }
276 tmp >>= 3;
277 writel(tmp, engine + 0x1C);
223 } 278 }
224 279
225 /* Set BPP and Pitch */ 280 if (op != VIA_BITBLT_COLOR)
226 writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE); 281 writel(fg_color, engine + 0x4C);
282
283 if (op == VIA_BITBLT_MONO)
284 writel(bg_color, engine + 0x50);
285
286 if (op == VIA_BITBLT_FILL)
287 ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
288 else {
289 ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
290 if (src_mem)
291 ge_cmd |= 0x00000040;
292 if (op == VIA_BITBLT_MONO)
293 ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
294 else
295 ge_cmd |= 0x00000001;
296 }
297 writel(ge_cmd, engine);
298
299 if (op == VIA_BITBLT_FILL || !src_mem)
300 return 0;
301
302 tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) +
303 3) >> 2;
304
305 for (i = 0; i < tmp; i++)
306 writel(src_mem[i], engine + VIA_MMIO_BLTBASE);
307
308 return 0;
227} 309}
228 310
229void viafb_hw_cursor_init(void) 311int viafb_init_engine(struct fb_info *info)
230{ 312{
313 struct viafb_par *viapar = info->par;
314 void __iomem *engine;
315 u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high,
316 vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name;
317
318 engine = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
319 viapar->shared->engine_mmio = engine;
320 if (!engine) {
321 printk(KERN_WARNING "viafb_init_accel: ioremap failed, "
322 "hardware acceleration disabled\n");
323 return -ENOMEM;
324 }
325
326 switch (chip_name) {
327 case UNICHROME_CLE266:
328 case UNICHROME_K400:
329 case UNICHROME_K800:
330 case UNICHROME_PM800:
331 case UNICHROME_CN700:
332 case UNICHROME_CX700:
333 case UNICHROME_CN750:
334 case UNICHROME_K8M890:
335 case UNICHROME_P4M890:
336 case UNICHROME_P4M900:
337 viapar->shared->hw_bitblt = hw_bitblt_1;
338 break;
339 case UNICHROME_VX800:
340 case UNICHROME_VX855:
341 viapar->shared->hw_bitblt = hw_bitblt_2;
342 break;
343 default:
344 viapar->shared->hw_bitblt = NULL;
345 }
346
347 viapar->fbmem_free -= CURSOR_SIZE;
348 viapar->shared->cursor_vram_addr = viapar->fbmem_free;
349 viapar->fbmem_used += CURSOR_SIZE;
350
351 viapar->fbmem_free -= VQ_SIZE;
352 viapar->shared->vq_vram_addr = viapar->fbmem_free;
353 viapar->fbmem_used += VQ_SIZE;
354
355 /* Init AGP and VQ regs */
356 switch (chip_name) {
357 case UNICHROME_K8M890:
358 case UNICHROME_P4M900:
359 writel(0x00100000, engine + VIA_REG_CR_TRANSET);
360 writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE);
361 writel(0x02000000, engine + VIA_REG_CR_TRANSPACE);
362 break;
363
364 default:
365 writel(0x00100000, engine + VIA_REG_TRANSET);
366 writel(0x00000000, engine + VIA_REG_TRANSPACE);
367 writel(0x00333004, engine + VIA_REG_TRANSPACE);
368 writel(0x60000000, engine + VIA_REG_TRANSPACE);
369 writel(0x61000000, engine + VIA_REG_TRANSPACE);
370 writel(0x62000000, engine + VIA_REG_TRANSPACE);
371 writel(0x63000000, engine + VIA_REG_TRANSPACE);
372 writel(0x64000000, engine + VIA_REG_TRANSPACE);
373 writel(0x7D000000, engine + VIA_REG_TRANSPACE);
374
375 writel(0xFE020000, engine + VIA_REG_TRANSET);
376 writel(0x00000000, engine + VIA_REG_TRANSPACE);
377 break;
378 }
379
380 /* Enable VQ */
381 vq_start_addr = viapar->shared->vq_vram_addr;
382 vq_end_addr = viapar->shared->vq_vram_addr + VQ_SIZE - 1;
383
384 vq_start_low = 0x50000000 | (vq_start_addr & 0xFFFFFF);
385 vq_end_low = 0x51000000 | (vq_end_addr & 0xFFFFFF);
386 vq_high = 0x52000000 | ((vq_start_addr & 0xFF000000) >> 24) |
387 ((vq_end_addr & 0xFF000000) >> 16);
388 vq_len = 0x53000000 | (VQ_SIZE >> 3);
389
390 switch (chip_name) {
391 case UNICHROME_K8M890:
392 case UNICHROME_P4M900:
393 vq_start_low |= 0x20000000;
394 vq_end_low |= 0x20000000;
395 vq_high |= 0x20000000;
396 vq_len |= 0x20000000;
397
398 writel(0x00100000, engine + VIA_REG_CR_TRANSET);
399 writel(vq_high, engine + VIA_REG_CR_TRANSPACE);
400 writel(vq_start_low, engine + VIA_REG_CR_TRANSPACE);
401 writel(vq_end_low, engine + VIA_REG_CR_TRANSPACE);
402 writel(vq_len, engine + VIA_REG_CR_TRANSPACE);
403 writel(0x74301001, engine + VIA_REG_CR_TRANSPACE);
404 writel(0x00000000, engine + VIA_REG_CR_TRANSPACE);
405 break;
406 default:
407 writel(0x00FE0000, engine + VIA_REG_TRANSET);
408 writel(0x080003FE, engine + VIA_REG_TRANSPACE);
409 writel(0x0A00027C, engine + VIA_REG_TRANSPACE);
410 writel(0x0B000260, engine + VIA_REG_TRANSPACE);
411 writel(0x0C000274, engine + VIA_REG_TRANSPACE);
412 writel(0x0D000264, engine + VIA_REG_TRANSPACE);
413 writel(0x0E000000, engine + VIA_REG_TRANSPACE);
414 writel(0x0F000020, engine + VIA_REG_TRANSPACE);
415 writel(0x1000027E, engine + VIA_REG_TRANSPACE);
416 writel(0x110002FE, engine + VIA_REG_TRANSPACE);
417 writel(0x200F0060, engine + VIA_REG_TRANSPACE);
418
419 writel(0x00000006, engine + VIA_REG_TRANSPACE);
420 writel(0x40008C0F, engine + VIA_REG_TRANSPACE);
421 writel(0x44000000, engine + VIA_REG_TRANSPACE);
422 writel(0x45080C04, engine + VIA_REG_TRANSPACE);
423 writel(0x46800408, engine + VIA_REG_TRANSPACE);
424
425 writel(vq_high, engine + VIA_REG_TRANSPACE);
426 writel(vq_start_low, engine + VIA_REG_TRANSPACE);
427 writel(vq_end_low, engine + VIA_REG_TRANSPACE);
428 writel(vq_len, engine + VIA_REG_TRANSPACE);
429 break;
430 }
431
231 /* Set Cursor Image Base Address */ 432 /* Set Cursor Image Base Address */
232 writel(viaparinfo->cursor_start, 433 writel(viapar->shared->cursor_vram_addr, engine + VIA_REG_CURSOR_MODE);
233 viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 434 writel(0x0, engine + VIA_REG_CURSOR_POS);
234 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS); 435 writel(0x0, engine + VIA_REG_CURSOR_ORG);
235 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); 436 writel(0x0, engine + VIA_REG_CURSOR_BG);
236 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG); 437 writel(0x0, engine + VIA_REG_CURSOR_FG);
237 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG); 438 return 0;
238} 439}
239 440
240void viafb_show_hw_cursor(struct fb_info *info, int Status) 441void viafb_show_hw_cursor(struct fb_info *info, int Status)
241{ 442{
242 u32 temp; 443 struct viafb_par *viapar = info->par;
243 u32 iga_path = ((struct viafb_par *)(info->par))->iga_path; 444 u32 temp, iga_path = viapar->iga_path;
244 445
245 temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 446 temp = readl(viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE);
246 switch (Status) { 447 switch (Status) {
247 case HW_Cursor_ON: 448 case HW_Cursor_ON:
248 temp |= 0x1; 449 temp |= 0x1;
@@ -259,25 +460,27 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status)
259 default: 460 default:
260 temp &= 0x7FFFFFFF; 461 temp &= 0x7FFFFFFF;
261 } 462 }
262 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 463 writel(temp, viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE);
263} 464}
264 465
265int viafb_wait_engine_idle(void) 466void viafb_wait_engine_idle(struct fb_info *info)
266{ 467{
468 struct viafb_par *viapar = info->par;
267 int loop = 0; 469 int loop = 0;
268 470
269 while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) & 471 while (!(readl(viapar->shared->engine_mmio + VIA_REG_STATUS) &
270 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { 472 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
271 loop++; 473 loop++;
272 cpu_relax(); 474 cpu_relax();
273 } 475 }
274 476
275 while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) & 477 while ((readl(viapar->shared->engine_mmio + VIA_REG_STATUS) &
276 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && 478 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
277 (loop < MAXLOOP)) { 479 (loop < MAXLOOP)) {
278 loop++; 480 loop++;
279 cpu_relax(); 481 cpu_relax();
280 } 482 }
281 483
282 return loop >= MAXLOOP; 484 if (loop >= MAXLOOP)
485 printk(KERN_ERR "viafb_wait_engine_idle: not syncing\n");
283} 486}
diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h
index 29bf854e8ccf..615c84ad0f01 100644
--- a/drivers/video/via/accel.h
+++ b/drivers/video/via/accel.h
@@ -159,11 +159,12 @@
159 159
160#define MAXLOOP 0xFFFFFF 160#define MAXLOOP 0xFFFFFF
161 161
162void viafb_init_accel(void); 162#define VIA_BITBLT_COLOR 1
163void viafb_init_2d_engine(void); 163#define VIA_BITBLT_MONO 2
164void set_2d_color_depth(int); 164#define VIA_BITBLT_FILL 3
165void viafb_hw_cursor_init(void); 165
166void viafb_show_hw_cursor(struct fb_info *info, int Status); int 166int viafb_init_engine(struct fb_info *info);
167viafb_wait_engine_idle(void); void viafb_set_2d_color_depth(int bpp); 167void viafb_show_hw_cursor(struct fb_info *info, int Status);
168void viafb_wait_engine_idle(struct fb_info *info);
168 169
169#endif /* __ACCEL_H__ */ 170#endif /* __ACCEL_H__ */
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index dde95edc387a..474f428aea92 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -68,6 +68,9 @@
68#define UNICHROME_VX800 11 68#define UNICHROME_VX800 11
69#define UNICHROME_VX800_DID 0x1122 69#define UNICHROME_VX800_DID 0x1122
70 70
71#define UNICHROME_VX855 12
72#define UNICHROME_VX855_DID 0x5122
73
71/**************************************************/ 74/**************************************************/
72/* Definition TMDS Trasmitter Information */ 75/* Definition TMDS Trasmitter Information */
73/**************************************************/ 76/**************************************************/
@@ -122,7 +125,6 @@ struct lvds_chip_information {
122struct chip_information { 125struct chip_information {
123 int gfx_chip_name; 126 int gfx_chip_name;
124 int gfx_chip_revision; 127 int gfx_chip_revision;
125 int chip_on_slot;
126 struct tmds_chip_information tmds_chip_info; 128 struct tmds_chip_information tmds_chip_info;
127 struct lvds_chip_information lvds_chip_info; 129 struct lvds_chip_information lvds_chip_info;
128 struct lvds_chip_information lvds_chip_info2; 130 struct lvds_chip_information lvds_chip_info2;
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index d6965447ca69..c5c32b6b6e6c 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -160,7 +160,7 @@ int viafb_tmds_trasmitter_identify(void)
160 160
161static void tmds_register_write(int index, u8 data) 161static void tmds_register_write(int index, u8 data)
162{ 162{
163 viaparinfo->i2c_stuff.i2c_port = 163 viaparinfo->shared->i2c_stuff.i2c_port =
164 viaparinfo->chip_info->tmds_chip_info.i2c_port; 164 viaparinfo->chip_info->tmds_chip_info.i2c_port;
165 165
166 viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info. 166 viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
@@ -172,7 +172,7 @@ static int tmds_register_read(int index)
172{ 172{
173 u8 data; 173 u8 data;
174 174
175 viaparinfo->i2c_stuff.i2c_port = 175 viaparinfo->shared->i2c_stuff.i2c_port =
176 viaparinfo->chip_info->tmds_chip_info.i2c_port; 176 viaparinfo->chip_info->tmds_chip_info.i2c_port;
177 viafb_i2c_readbyte((u8) viaparinfo->chip_info-> 177 viafb_i2c_readbyte((u8) viaparinfo->chip_info->
178 tmds_chip_info.tmds_chip_slave_addr, 178 tmds_chip_info.tmds_chip_slave_addr,
@@ -182,7 +182,7 @@ static int tmds_register_read(int index)
182 182
183static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) 183static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
184{ 184{
185 viaparinfo->i2c_stuff.i2c_port = 185 viaparinfo->shared->i2c_stuff.i2c_port =
186 viaparinfo->chip_info->tmds_chip_info.i2c_port; 186 viaparinfo->chip_info->tmds_chip_info.i2c_port;
187 viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info. 187 viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info.
188 tmds_chip_slave_addr, (u8) index, buff, buff_len); 188 tmds_chip_slave_addr, (u8) index, buff, buff_len);
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c
index 468be2425af3..b675cdbb03ad 100644
--- a/drivers/video/via/global.c
+++ b/drivers/video/via/global.c
@@ -32,7 +32,6 @@ int viafb_lcd_dsp_method = LCD_EXPANDSION;
32int viafb_lcd_mode = LCD_OPENLDI; 32int viafb_lcd_mode = LCD_OPENLDI;
33int viafb_bpp = 32; 33int viafb_bpp = 32;
34int viafb_bpp1 = 32; 34int viafb_bpp1 = 32;
35int viafb_accel = 1;
36int viafb_CRT_ON = 1; 35int viafb_CRT_ON = 1;
37int viafb_DVI_ON; 36int viafb_DVI_ON;
38int viafb_LCD_ON ; 37int viafb_LCD_ON ;
@@ -46,13 +45,11 @@ int viafb_hotplug_refresh = 60;
46unsigned int viafb_second_offset; 45unsigned int viafb_second_offset;
47int viafb_second_size; 46int viafb_second_size;
48int viafb_primary_dev = None_Device; 47int viafb_primary_dev = None_Device;
49void __iomem *viafb_FB_MM;
50unsigned int viafb_second_xres = 640; 48unsigned int viafb_second_xres = 640;
51unsigned int viafb_second_yres = 480; 49unsigned int viafb_second_yres = 480;
52unsigned int viafb_second_virtual_xres; 50unsigned int viafb_second_virtual_xres;
53unsigned int viafb_second_virtual_yres; 51unsigned int viafb_second_virtual_yres;
54int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1; 52int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
55struct fb_cursor viacursor;
56struct fb_info *viafbinfo; 53struct fb_info *viafbinfo;
57struct fb_info *viafbinfo1; 54struct fb_info *viafbinfo1;
58struct viafb_par *viaparinfo; 55struct viafb_par *viaparinfo;
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
index 7543d5f7e309..d69d0ca99c2f 100644
--- a/drivers/video/via/global.h
+++ b/drivers/video/via/global.h
@@ -77,8 +77,6 @@ extern int viafb_hotplug_Yres;
77extern int viafb_hotplug_bpp; 77extern int viafb_hotplug_bpp;
78extern int viafb_hotplug_refresh; 78extern int viafb_hotplug_refresh;
79extern int viafb_primary_dev; 79extern int viafb_primary_dev;
80extern void __iomem *viafb_FB_MM;
81extern struct fb_cursor viacursor;
82 80
83extern unsigned int viafb_second_xres; 81extern unsigned int viafb_second_xres;
84extern unsigned int viafb_second_yres; 82extern unsigned int viafb_second_yres;
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index c8960003f47d..3e083ff67ae2 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -21,125 +21,143 @@
21 21
22#include "global.h" 22#include "global.h"
23 23
24static const struct pci_device_id_info pciidlist[] = {
25 {PCI_VIA_VENDOR_ID, UNICHROME_CLE266_DID, UNICHROME_CLE266},
26 {PCI_VIA_VENDOR_ID, UNICHROME_PM800_DID, UNICHROME_PM800},
27 {PCI_VIA_VENDOR_ID, UNICHROME_K400_DID, UNICHROME_K400},
28 {PCI_VIA_VENDOR_ID, UNICHROME_K800_DID, UNICHROME_K800},
29 {PCI_VIA_VENDOR_ID, UNICHROME_CN700_DID, UNICHROME_CN700},
30 {PCI_VIA_VENDOR_ID, UNICHROME_P4M890_DID, UNICHROME_P4M890},
31 {PCI_VIA_VENDOR_ID, UNICHROME_K8M890_DID, UNICHROME_K8M890},
32 {PCI_VIA_VENDOR_ID, UNICHROME_CX700_DID, UNICHROME_CX700},
33 {PCI_VIA_VENDOR_ID, UNICHROME_P4M900_DID, UNICHROME_P4M900},
34 {PCI_VIA_VENDOR_ID, UNICHROME_CN750_DID, UNICHROME_CN750},
35 {PCI_VIA_VENDOR_ID, UNICHROME_VX800_DID, UNICHROME_VX800},
36 {0, 0, 0}
37};
38
39struct offset offset_reg = {
40 /* IGA1 Offset Register */
41 {IGA1_OFFSET_REG_NUM, {{CR13, 0, 7}, {CR35, 5, 7} } },
42 /* IGA2 Offset Register */
43 {IGA2_OFFSET_REG_NUM, {{CR66, 0, 7}, {CR67, 0, 1} } }
44};
45
46static struct pll_map pll_value[] = { 24static struct pll_map pll_value[] = {
47 {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M}, 25 {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M,
48 {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M}, 26 CX700_25_175M, VX855_25_175M},
49 {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, CX700_26_880M}, 27 {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M,
50 {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, CX700_31_490M}, 28 CX700_29_581M, VX855_29_581M},
51 {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, CX700_31_500M}, 29 {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M,
52 {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, CX700_31_728M}, 30 CX700_26_880M, VX855_26_880M},
53 {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, CX700_32_668M}, 31 {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M,
54 {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, CX700_36_000M}, 32 CX700_31_490M, VX855_31_490M},
55 {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, CX700_40_000M}, 33 {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M,
56 {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, CX700_41_291M}, 34 CX700_31_500M, VX855_31_500M},
57 {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, CX700_43_163M}, 35 {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M,
58 {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, CX700_45_250M}, 36 CX700_31_728M, VX855_31_728M},
59 {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, CX700_46_000M}, 37 {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M,
60 {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, CX700_46_996M}, 38 CX700_32_668M, VX855_32_668M},
61 {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, CX700_48_000M}, 39 {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M,
62 {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, CX700_48_875M}, 40 CX700_36_000M, VX855_36_000M},
63 {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, CX700_49_500M}, 41 {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M,
64 {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, CX700_52_406M}, 42 CX700_40_000M, VX855_40_000M},
65 {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, CX700_52_977M}, 43 {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M,
66 {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, CX700_56_250M}, 44 CX700_41_291M, VX855_41_291M},
67 {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, CX700_60_466M}, 45 {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M,
68 {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, CX700_61_500M}, 46 CX700_43_163M, VX855_43_163M},
69 {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, CX700_65_000M}, 47 {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M,
70 {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, CX700_65_178M}, 48 CX700_45_250M, VX855_45_250M},
71 {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, CX700_66_750M}, 49 {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M,
72 {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, CX700_68_179M}, 50 CX700_46_000M, VX855_46_000M},
73 {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, CX700_69_924M}, 51 {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M,
74 {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, CX700_70_159M}, 52 CX700_46_996M, VX855_46_996M},
75 {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, CX700_72_000M}, 53 {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M,
76 {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, CX700_78_750M}, 54 CX700_48_000M, VX855_48_000M},
77 {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, CX700_80_136M}, 55 {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M,
78 {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, CX700_83_375M}, 56 CX700_48_875M, VX855_48_875M},
79 {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, CX700_83_950M}, 57 {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M,
80 {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, CX700_84_750M}, 58 CX700_49_500M, VX855_49_500M},
81 {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, CX700_85_860M}, 59 {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M,
82 {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, CX700_88_750M}, 60 CX700_52_406M, VX855_52_406M},
83 {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, CX700_94_500M}, 61 {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M,
84 {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, CX700_97_750M}, 62 CX700_52_977M, VX855_52_977M},
63 {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M,
64 CX700_56_250M, VX855_56_250M},
65 {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M,
66 CX700_60_466M, VX855_60_466M},
67 {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M,
68 CX700_61_500M, VX855_61_500M},
69 {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M,
70 CX700_65_000M, VX855_65_000M},
71 {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M,
72 CX700_65_178M, VX855_65_178M},
73 {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M,
74 CX700_66_750M, VX855_66_750M},
75 {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M,
76 CX700_68_179M, VX855_68_179M},
77 {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M,
78 CX700_69_924M, VX855_69_924M},
79 {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M,
80 CX700_70_159M, VX855_70_159M},
81 {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M,
82 CX700_72_000M, VX855_72_000M},
83 {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M,
84 CX700_78_750M, VX855_78_750M},
85 {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M,
86 CX700_80_136M, VX855_80_136M},
87 {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M,
88 CX700_83_375M, VX855_83_375M},
89 {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M,
90 CX700_83_950M, VX855_83_950M},
91 {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M,
92 CX700_84_750M, VX855_84_750M},
93 {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M,
94 CX700_85_860M, VX855_85_860M},
95 {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M,
96 CX700_88_750M, VX855_88_750M},
97 {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M,
98 CX700_94_500M, VX855_94_500M},
99 {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M,
100 CX700_97_750M, VX855_97_750M},
85 {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M, 101 {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M,
86 CX700_101_000M}, 102 CX700_101_000M, VX855_101_000M},
87 {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M, 103 {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M,
88 CX700_106_500M}, 104 CX700_106_500M, VX855_106_500M},
89 {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M, 105 {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M,
90 CX700_108_000M}, 106 CX700_108_000M, VX855_108_000M},
91 {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M, 107 {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M,
92 CX700_113_309M}, 108 CX700_113_309M, VX855_113_309M},
93 {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M, 109 {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M,
94 CX700_118_840M}, 110 CX700_118_840M, VX855_118_840M},
95 {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M, 111 {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M,
96 CX700_119_000M}, 112 CX700_119_000M, VX855_119_000M},
97 {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M, 113 {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M,
98 CX700_121_750M}, 114 CX700_121_750M, 0},
99 {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M, 115 {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M,
100 CX700_125_104M}, 116 CX700_125_104M, 0},
101 {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M, 117 {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M,
102 CX700_133_308M}, 118 CX700_133_308M, 0},
103 {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M, 119 {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M,
104 CX700_135_000M}, 120 CX700_135_000M, VX855_135_000M},
105 {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M, 121 {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M,
106 CX700_136_700M}, 122 CX700_136_700M, VX855_136_700M},
107 {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M, 123 {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M,
108 CX700_138_400M}, 124 CX700_138_400M, VX855_138_400M},
109 {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M, 125 {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M,
110 CX700_146_760M}, 126 CX700_146_760M, VX855_146_760M},
111 {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M, 127 {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M,
112 CX700_153_920M}, 128 CX700_153_920M, VX855_153_920M},
113 {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M, 129 {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M,
114 CX700_156_000M}, 130 CX700_156_000M, VX855_156_000M},
115 {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M, 131 {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M,
116 CX700_157_500M}, 132 CX700_157_500M, VX855_157_500M},
117 {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M, 133 {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M,
118 CX700_162_000M}, 134 CX700_162_000M, VX855_162_000M},
119 {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M, 135 {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M,
120 CX700_187_000M}, 136 CX700_187_000M, VX855_187_000M},
121 {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M, 137 {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M,
122 CX700_193_295M}, 138 CX700_193_295M, VX855_193_295M},
123 {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M, 139 {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M,
124 CX700_202_500M}, 140 CX700_202_500M, VX855_202_500M},
125 {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M, 141 {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M,
126 CX700_204_000M}, 142 CX700_204_000M, VX855_204_000M},
127 {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M, 143 {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M,
128 CX700_218_500M}, 144 CX700_218_500M, VX855_218_500M},
129 {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M, 145 {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M,
130 CX700_234_000M}, 146 CX700_234_000M, VX855_234_000M},
131 {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M, 147 {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M,
132 CX700_267_250M}, 148 CX700_267_250M, VX855_267_250M},
133 {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M, 149 {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M,
134 CX700_297_500M}, 150 CX700_297_500M, VX855_297_500M},
135 {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, CX700_74_481M}, 151 {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M,
152 CX700_74_481M, VX855_74_481M},
136 {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M, 153 {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M,
137 CX700_172_798M}, 154 CX700_172_798M, VX855_172_798M},
138 {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M, 155 {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M,
139 CX700_122_614M}, 156 CX700_122_614M, VX855_122_614M},
140 {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, CX700_74_270M}, 157 {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M,
158 CX700_74_270M, 0},
141 {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M, 159 {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M,
142 CX700_148_500M} 160 CX700_148_500M, VX855_148_500M}
143}; 161};
144 162
145static struct fifo_depth_select display_fifo_depth_reg = { 163static struct fifo_depth_select display_fifo_depth_reg = {
@@ -508,7 +526,8 @@ static void set_dvi_output_path(int set_iga, int output_interface);
508static void set_lcd_output_path(int set_iga, int output_interface); 526static void set_lcd_output_path(int set_iga, int output_interface);
509static int search_mode_setting(int ModeInfoIndex); 527static int search_mode_setting(int ModeInfoIndex);
510static void load_fix_bit_crtc_reg(void); 528static void load_fix_bit_crtc_reg(void);
511static void init_gfx_chip_info(void); 529static void init_gfx_chip_info(struct pci_dev *pdev,
530 const struct pci_device_id *pdi);
512static void init_tmds_chip_info(void); 531static void init_tmds_chip_info(void);
513static void init_lvds_chip_info(void); 532static void init_lvds_chip_info(void);
514static void device_screen_off(void); 533static void device_screen_off(void);
@@ -518,7 +537,6 @@ static void device_off(void);
518static void device_on(void); 537static void device_on(void);
519static void enable_second_display_channel(void); 538static void enable_second_display_channel(void);
520static void disable_second_display_channel(void); 539static void disable_second_display_channel(void);
521static int get_fb_size_from_pci(void);
522 540
523void viafb_write_reg(u8 index, u16 io_port, u8 data) 541void viafb_write_reg(u8 index, u16 io_port, u8 data)
524{ 542{
@@ -629,70 +647,43 @@ void viafb_set_iga_path(void)
629 } 647 }
630} 648}
631 649
632void viafb_set_start_addr(void) 650void viafb_set_primary_address(u32 addr)
633{ 651{
634 unsigned long offset = 0, tmp = 0, size = 0; 652 DEBUG_MSG(KERN_DEBUG "viafb_set_primary_address(0x%08X)\n", addr);
635 unsigned long length; 653 viafb_write_reg(CR0D, VIACR, addr & 0xFF);
636 654 viafb_write_reg(CR0C, VIACR, (addr >> 8) & 0xFF);
637 DEBUG_MSG(KERN_INFO "viafb_set_start_addr!\n"); 655 viafb_write_reg(CR34, VIACR, (addr >> 16) & 0xFF);
638 viafb_unlock_crt(); 656 viafb_write_reg_mask(CR48, VIACR, (addr >> 24) & 0x1F, 0x1F);
639 /* update starting address of IGA1 */ 657}
640 viafb_write_reg(CR0C, VIACR, 0x00); /*initial starting address */
641 viafb_write_reg(CR0D, VIACR, 0x00);
642 viafb_write_reg(CR34, VIACR, 0x00);
643 viafb_write_reg_mask(CR48, VIACR, 0x00, 0x1F);
644
645 if (viafb_dual_fb) {
646 viaparinfo->iga_path = IGA1;
647 viaparinfo1->iga_path = IGA2;
648 }
649
650 if (viafb_SAMM_ON == 1) {
651 if (!viafb_dual_fb) {
652 if (viafb_second_size)
653 size = viafb_second_size * 1024 * 1024;
654 else
655 size = 8 * 1024 * 1024;
656 } else {
657 658
658 size = viaparinfo1->memsize; 659void viafb_set_secondary_address(u32 addr)
659 } 660{
660 offset = viafb_second_offset; 661 DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_address(0x%08X)\n", addr);
661 DEBUG_MSG(KERN_INFO 662 /* secondary display supports only quadword aligned memory */
662 "viafb_second_size=%lx, second start_adddress=%lx\n", 663 viafb_write_reg_mask(CR62, VIACR, (addr >> 2) & 0xFE, 0xFE);
663 size, offset); 664 viafb_write_reg(CR63, VIACR, (addr >> 10) & 0xFF);
664 } 665 viafb_write_reg(CR64, VIACR, (addr >> 18) & 0xFF);
665 if (viafb_SAMM_ON == 1) { 666 viafb_write_reg_mask(CRA3, VIACR, (addr >> 26) & 0x07, 0x07);
666 offset = offset >> 3; 667}
667
668 tmp = viafb_read_reg(VIACR, 0x62) & 0x01;
669 tmp |= (offset & 0x7F) << 1;
670 viafb_write_reg(CR62, VIACR, tmp);
671 viafb_write_reg(CR63, VIACR, ((offset & 0x7F80) >> 7));
672 viafb_write_reg(CR64, VIACR, ((offset & 0x7F8000) >> 15));
673 viafb_write_reg(CRA3, VIACR, ((offset & 0x3800000) >> 23));
674 } else {
675 /* update starting address */
676 viafb_write_reg(CR62, VIACR, 0x00);
677 viafb_write_reg(CR63, VIACR, 0x00);
678 viafb_write_reg(CR64, VIACR, 0x00);
679 viafb_write_reg(CRA3, VIACR, 0x00);
680 }
681 668
682 if (viafb_SAMM_ON == 1) { 669void viafb_set_primary_pitch(u32 pitch)
683 if (viafb_accel) { 670{
684 if (!viafb_dual_fb) 671 DEBUG_MSG(KERN_DEBUG "viafb_set_primary_pitch(0x%08X)\n", pitch);
685 length = size - viaparinfo->fbmem_used; 672 /* spec does not say that first adapter skips 3 bits but old
686 else 673 * code did it and seems to be reasonable in analogy to 2nd adapter
687 length = size - viaparinfo1->fbmem_used; 674 */
688 } else 675 pitch = pitch >> 3;
689 length = size; 676 viafb_write_reg(0x13, VIACR, pitch & 0xFF);
690 offset = (unsigned long)(void *)viafb_FB_MM + 677 viafb_write_reg_mask(0x35, VIACR, (pitch >> (8 - 5)) & 0xE0, 0xE0);
691 viafb_second_offset; 678}
692 memset((void *)offset, 0, length);
693 }
694 679
695 viafb_lock_crt(); 680void viafb_set_secondary_pitch(u32 pitch)
681{
682 DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_pitch(0x%08X)\n", pitch);
683 pitch = pitch >> 3;
684 viafb_write_reg(0x66, VIACR, pitch & 0xFF);
685 viafb_write_reg_mask(0x67, VIACR, (pitch >> 8) & 0x03, 0x03);
686 viafb_write_reg_mask(0x71, VIACR, (pitch >> (10 - 7)) & 0x80, 0x80);
696} 687}
697 688
698void viafb_set_output_path(int device, int set_iga, int output_interface) 689void viafb_set_output_path(int device, int set_iga, int output_interface)
@@ -1123,30 +1114,6 @@ void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
1123 } 1114 }
1124} 1115}
1125 1116
1126void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga)
1127{
1128 int reg_value;
1129 int viafb_load_reg_num;
1130 struct io_register *reg;
1131
1132 switch (set_iga) {
1133 case IGA1_IGA2:
1134 case IGA1:
1135 reg_value = IGA1_OFFSET_FORMULA(h_addr, bpp_byte);
1136 viafb_load_reg_num = offset_reg.iga1_offset_reg.reg_num;
1137 reg = offset_reg.iga1_offset_reg.reg;
1138 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1139 if (set_iga == IGA1)
1140 break;
1141 case IGA2:
1142 reg_value = IGA2_OFFSET_FORMULA(h_addr, bpp_byte);
1143 viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
1144 reg = offset_reg.iga2_offset_reg.reg;
1145 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1146 break;
1147 }
1148}
1149
1150void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga) 1117void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
1151{ 1118{
1152 int reg_value; 1119 int reg_value;
@@ -1277,6 +1244,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1277 VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; 1244 VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1278 } 1245 }
1279 1246
1247 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
1248 iga1_fifo_max_depth = VX855_IGA1_FIFO_MAX_DEPTH;
1249 iga1_fifo_threshold = VX855_IGA1_FIFO_THRESHOLD;
1250 iga1_fifo_high_threshold =
1251 VX855_IGA1_FIFO_HIGH_THRESHOLD;
1252 iga1_display_queue_expire_num =
1253 VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1254 }
1255
1280 /* Set Display FIFO Depath Select */ 1256 /* Set Display FIFO Depath Select */
1281 reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth); 1257 reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
1282 viafb_load_reg_num = 1258 viafb_load_reg_num =
@@ -1408,6 +1384,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1408 VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; 1384 VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1409 } 1385 }
1410 1386
1387 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
1388 iga2_fifo_max_depth = VX855_IGA2_FIFO_MAX_DEPTH;
1389 iga2_fifo_threshold = VX855_IGA2_FIFO_THRESHOLD;
1390 iga2_fifo_high_threshold =
1391 VX855_IGA2_FIFO_HIGH_THRESHOLD;
1392 iga2_display_queue_expire_num =
1393 VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1394 }
1395
1411 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { 1396 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1412 /* Set Display FIFO Depath Select */ 1397 /* Set Display FIFO Depath Select */
1413 reg_value = 1398 reg_value =
@@ -1496,6 +1481,8 @@ u32 viafb_get_clk_value(int clk)
1496 case UNICHROME_P4M900: 1481 case UNICHROME_P4M900:
1497 case UNICHROME_VX800: 1482 case UNICHROME_VX800:
1498 return pll_value[i].cx700_pll; 1483 return pll_value[i].cx700_pll;
1484 case UNICHROME_VX855:
1485 return pll_value[i].vx855_pll;
1499 } 1486 }
1500 } 1487 }
1501 } 1488 }
@@ -1529,6 +1516,7 @@ void viafb_set_vclock(u32 CLK, int set_iga)
1529 case UNICHROME_P4M890: 1516 case UNICHROME_P4M890:
1530 case UNICHROME_P4M900: 1517 case UNICHROME_P4M900:
1531 case UNICHROME_VX800: 1518 case UNICHROME_VX800:
1519 case UNICHROME_VX855:
1532 viafb_write_reg(SR44, VIASR, CLK / 0x10000); 1520 viafb_write_reg(SR44, VIASR, CLK / 0x10000);
1533 DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000); 1521 DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000);
1534 viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100); 1522 viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100);
@@ -1557,6 +1545,7 @@ void viafb_set_vclock(u32 CLK, int set_iga)
1557 case UNICHROME_P4M890: 1545 case UNICHROME_P4M890:
1558 case UNICHROME_P4M900: 1546 case UNICHROME_P4M900:
1559 case UNICHROME_VX800: 1547 case UNICHROME_VX800:
1548 case UNICHROME_VX855:
1560 viafb_write_reg(SR4A, VIASR, CLK / 0x10000); 1549 viafb_write_reg(SR4A, VIASR, CLK / 0x10000);
1561 viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100); 1550 viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100);
1562 viafb_write_reg(SR4C, VIASR, CLK % 0x100); 1551 viafb_write_reg(SR4C, VIASR, CLK % 0x100);
@@ -1916,7 +1905,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
1916 load_fix_bit_crtc_reg(); 1905 load_fix_bit_crtc_reg();
1917 viafb_lock_crt(); 1906 viafb_lock_crt();
1918 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); 1907 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1919 viafb_load_offset_reg(h_addr, bpp_byte, set_iga);
1920 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); 1908 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
1921 1909
1922 /* load FIFO */ 1910 /* load FIFO */
@@ -1933,9 +1921,10 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
1933 1921
1934} 1922}
1935 1923
1936void viafb_init_chip_info(void) 1924void viafb_init_chip_info(struct pci_dev *pdev,
1925 const struct pci_device_id *pdi)
1937{ 1926{
1938 init_gfx_chip_info(); 1927 init_gfx_chip_info(pdev, pdi);
1939 init_tmds_chip_info(); 1928 init_tmds_chip_info();
1940 init_lvds_chip_info(); 1929 init_lvds_chip_info();
1941 1930
@@ -2008,24 +1997,12 @@ void viafb_update_device_setting(int hres, int vres,
2008 } 1997 }
2009} 1998}
2010 1999
2011static void init_gfx_chip_info(void) 2000static void init_gfx_chip_info(struct pci_dev *pdev,
2001 const struct pci_device_id *pdi)
2012{ 2002{
2013 struct pci_dev *pdev = NULL;
2014 u32 i;
2015 u8 tmp; 2003 u8 tmp;
2016 2004
2017 /* Indentify GFX Chip Name */ 2005 viaparinfo->chip_info->gfx_chip_name = pdi->driver_data;
2018 for (i = 0; pciidlist[i].vendor != 0; i++) {
2019 pdev = pci_get_device(pciidlist[i].vendor,
2020 pciidlist[i].device, 0);
2021 if (pdev)
2022 break;
2023 }
2024
2025 if (!pciidlist[i].vendor)
2026 return ;
2027
2028 viaparinfo->chip_info->gfx_chip_name = pciidlist[i].chip_index;
2029 2006
2030 /* Check revision of CLE266 Chip */ 2007 /* Check revision of CLE266 Chip */
2031 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 2008 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
@@ -2056,8 +2033,6 @@ static void init_gfx_chip_info(void)
2056 CX700_REVISION_700; 2033 CX700_REVISION_700;
2057 } 2034 }
2058 } 2035 }
2059
2060 pci_dev_put(pdev);
2061} 2036}
2062 2037
2063static void init_tmds_chip_info(void) 2038static void init_tmds_chip_info(void)
@@ -2271,11 +2246,12 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
2271 break; 2246 break;
2272 2247
2273 case UNICHROME_CX700: 2248 case UNICHROME_CX700:
2274 viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
2275
2276 case UNICHROME_VX800: 2249 case UNICHROME_VX800:
2277 viafb_write_regx(VX800_ModeXregs, NUM_TOTAL_VX800_ModeXregs); 2250 viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
2251 break;
2278 2252
2253 case UNICHROME_VX855:
2254 viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs);
2279 break; 2255 break;
2280 } 2256 }
2281 2257
@@ -2291,7 +2267,8 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
2291 outb(VPIT.SR[i - 1], VIASR + 1); 2267 outb(VPIT.SR[i - 1], VIASR + 1);
2292 } 2268 }
2293 2269
2294 viafb_set_start_addr(); 2270 viafb_set_primary_address(0);
2271 viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
2295 viafb_set_iga_path(); 2272 viafb_set_iga_path();
2296 2273
2297 /* Write CRTC */ 2274 /* Write CRTC */
@@ -2371,6 +2348,9 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
2371 } 2348 }
2372 } 2349 }
2373 2350
2351 viafb_set_primary_pitch(viafbinfo->fix.line_length);
2352 viafb_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
2353 : viafbinfo->fix.line_length);
2374 /* Update Refresh Rate Setting */ 2354 /* Update Refresh Rate Setting */
2375 2355
2376 /* Clear On Screen */ 2356 /* Clear On Screen */
@@ -2545,38 +2525,6 @@ void viafb_crt_enable(void)
2545 viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4); 2525 viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4);
2546} 2526}
2547 2527
2548void viafb_get_mmio_info(unsigned long *mmio_base,
2549 unsigned long *mmio_len)
2550{
2551 struct pci_dev *pdev = NULL;
2552 u32 vendor, device;
2553 u32 i;
2554
2555 for (i = 0; pciidlist[i].vendor != 0; i++)
2556 if (viaparinfo->chip_info->gfx_chip_name ==
2557 pciidlist[i].chip_index)
2558 break;
2559
2560 if (!pciidlist[i].vendor)
2561 return ;
2562
2563 vendor = pciidlist[i].vendor;
2564 device = pciidlist[i].device;
2565
2566 pdev = pci_get_device(vendor, device, NULL);
2567
2568 if (!pdev) {
2569 *mmio_base = 0;
2570 *mmio_len = 0;
2571 return ;
2572 }
2573
2574 *mmio_base = pci_resource_start(pdev, 1);
2575 *mmio_len = pci_resource_len(pdev, 1);
2576
2577 pci_dev_put(pdev);
2578}
2579
2580static void enable_second_display_channel(void) 2528static void enable_second_display_channel(void)
2581{ 2529{
2582 /* to enable second display channel. */ 2530 /* to enable second display channel. */
@@ -2593,44 +2541,7 @@ static void disable_second_display_channel(void)
2593 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); 2541 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2594} 2542}
2595 2543
2596void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len) 2544int viafb_get_fb_size_from_pci(void)
2597{
2598 struct pci_dev *pdev = NULL;
2599 u32 vendor, device;
2600 u32 i;
2601
2602 for (i = 0; pciidlist[i].vendor != 0; i++)
2603 if (viaparinfo->chip_info->gfx_chip_name ==
2604 pciidlist[i].chip_index)
2605 break;
2606
2607 if (!pciidlist[i].vendor)
2608 return ;
2609
2610 vendor = pciidlist[i].vendor;
2611 device = pciidlist[i].device;
2612
2613 pdev = pci_get_device(vendor, device, NULL);
2614
2615 if (!pdev) {
2616 *fb_base = viafb_read_reg(VIASR, SR30) << 24;
2617 *fb_len = viafb_get_memsize();
2618 DEBUG_MSG(KERN_INFO "Get FB info from SR30!\n");
2619 DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
2620 DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
2621 return ;
2622 }
2623
2624 *fb_base = (unsigned int)pci_resource_start(pdev, 0);
2625 *fb_len = get_fb_size_from_pci();
2626 DEBUG_MSG(KERN_INFO "Get FB info from PCI system!\n");
2627 DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
2628 DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
2629
2630 pci_dev_put(pdev);
2631}
2632
2633static int get_fb_size_from_pci(void)
2634{ 2545{
2635 unsigned long configid, deviceid, FBSize = 0; 2546 unsigned long configid, deviceid, FBSize = 0;
2636 int VideoMemSize; 2547 int VideoMemSize;
@@ -2656,6 +2567,7 @@ static int get_fb_size_from_pci(void)
2656 case P4M890_FUNCTION3: 2567 case P4M890_FUNCTION3:
2657 case P4M900_FUNCTION3: 2568 case P4M900_FUNCTION3:
2658 case VX800_FUNCTION3: 2569 case VX800_FUNCTION3:
2570 case VX855_FUNCTION3:
2659 /*case CN750_FUNCTION3: */ 2571 /*case CN750_FUNCTION3: */
2660 outl(configid + 0xA0, (unsigned long)0xCF8); 2572 outl(configid + 0xA0, (unsigned long)0xCF8);
2661 FBSize = inl((unsigned long)0xCFC); 2573 FBSize = inl((unsigned long)0xCFC);
@@ -2719,6 +2631,10 @@ static int get_fb_size_from_pci(void)
2719 VideoMemSize = (256 << 20); /*256M */ 2631 VideoMemSize = (256 << 20); /*256M */
2720 break; 2632 break;
2721 2633
2634 case 0x00007000: /* Only on VX855/875 */
2635 VideoMemSize = (512 << 20); /*512M */
2636 break;
2637
2722 default: 2638 default:
2723 VideoMemSize = (32 << 20); /*32M */ 2639 VideoMemSize = (32 << 20); /*32M */
2724 break; 2640 break;
@@ -2788,24 +2704,6 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2788 } 2704 }
2789} 2705}
2790 2706
2791void viafb_memory_pitch_patch(struct fb_info *info)
2792{
2793 if (info->var.xres != info->var.xres_virtual) {
2794 viafb_load_offset_reg(info->var.xres_virtual,
2795 info->var.bits_per_pixel >> 3, IGA1);
2796
2797 if (viafb_SAMM_ON) {
2798 viafb_load_offset_reg(viafb_second_virtual_xres,
2799 viafb_bpp1 >> 3,
2800 IGA2);
2801 } else {
2802 viafb_load_offset_reg(info->var.xres_virtual,
2803 info->var.bits_per_pixel >> 3, IGA2);
2804 }
2805
2806 }
2807}
2808
2809/*According var's xres, yres fill var's other timing information*/ 2707/*According var's xres, yres fill var's other timing information*/
2810void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 2708void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
2811 int mode_index) 2709 int mode_index)
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 6ff38fa8569a..b874d952b446 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -147,14 +147,8 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */
147/* location: {CR5F,0,4} */ 147/* location: {CR5F,0,4} */
148#define IGA2_VER_SYNC_END_REG_NUM 1 148#define IGA2_VER_SYNC_END_REG_NUM 1
149 149
150/* Define Offset and Fetch Count Register*/ 150/* Define Fetch Count Register*/
151 151
152/* location: {CR13,0,7},{CR35,5,7} */
153#define IGA1_OFFSET_REG_NUM 2
154/* 8 bytes alignment. */
155#define IGA1_OFFSER_ALIGN_BYTE 8
156/* x: H resolution, y: color depth */
157#define IGA1_OFFSET_FORMULA(x, y) ((x*y)/IGA1_OFFSER_ALIGN_BYTE)
158/* location: {SR1C,0,7},{SR1D,0,1} */ 152/* location: {SR1C,0,7},{SR1D,0,1} */
159#define IGA1_FETCH_COUNT_REG_NUM 2 153#define IGA1_FETCH_COUNT_REG_NUM 2
160/* 16 bytes alignment. */ 154/* 16 bytes alignment. */
@@ -164,11 +158,6 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */
164#define IGA1_FETCH_COUNT_FORMULA(x, y) \ 158#define IGA1_FETCH_COUNT_FORMULA(x, y) \
165 (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE) 159 (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE)
166 160
167/* location: {CR66,0,7},{CR67,0,1} */
168#define IGA2_OFFSET_REG_NUM 2
169#define IGA2_OFFSET_ALIGN_BYTE 8
170/* x: H resolution, y: color depth */
171#define IGA2_OFFSET_FORMULA(x, y) ((x*y)/IGA2_OFFSET_ALIGN_BYTE)
172/* location: {CR65,0,7},{CR67,2,3} */ 161/* location: {CR65,0,7},{CR67,2,3} */
173#define IGA2_FETCH_COUNT_REG_NUM 2 162#define IGA2_FETCH_COUNT_REG_NUM 2
174#define IGA2_FETCH_COUNT_ALIGN_BYTE 16 163#define IGA2_FETCH_COUNT_ALIGN_BYTE 16
@@ -335,6 +324,17 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */
335/* location: {CR94,0,6} */ 324/* location: {CR94,0,6} */
336#define VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 325#define VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
337 326
327/* For VT3409 */
328#define VX855_IGA1_FIFO_MAX_DEPTH 400
329#define VX855_IGA1_FIFO_THRESHOLD 320
330#define VX855_IGA1_FIFO_HIGH_THRESHOLD 320
331#define VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 160
332
333#define VX855_IGA2_FIFO_MAX_DEPTH 200
334#define VX855_IGA2_FIFO_THRESHOLD 160
335#define VX855_IGA2_FIFO_HIGH_THRESHOLD 160
336#define VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 320
337
338#define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1 338#define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1
339#define IGA1_FIFO_THRESHOLD_REG_NUM 2 339#define IGA1_FIFO_THRESHOLD_REG_NUM 2
340#define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2 340#define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2
@@ -617,23 +617,6 @@ struct iga2_ver_sync_end {
617 struct io_register reg[IGA2_VER_SYNC_END_REG_NUM]; 617 struct io_register reg[IGA2_VER_SYNC_END_REG_NUM];
618}; 618};
619 619
620/* IGA1 Offset Register */
621struct iga1_offset {
622 int reg_num;
623 struct io_register reg[IGA1_OFFSET_REG_NUM];
624};
625
626/* IGA2 Offset Register */
627struct iga2_offset {
628 int reg_num;
629 struct io_register reg[IGA2_OFFSET_REG_NUM];
630};
631
632struct offset {
633 struct iga1_offset iga1_offset_reg;
634 struct iga2_offset iga2_offset_reg;
635};
636
637/* IGA1 Fetch Count Register */ 620/* IGA1 Fetch Count Register */
638struct iga1_fetch_count { 621struct iga1_fetch_count {
639 int reg_num; 622 int reg_num;
@@ -716,6 +699,7 @@ struct pll_map {
716 u32 cle266_pll; 699 u32 cle266_pll;
717 u32 k800_pll; 700 u32 k800_pll;
718 u32 cx700_pll; 701 u32 cx700_pll;
702 u32 vx855_pll;
719}; 703};
720 704
721struct rgbLUT { 705struct rgbLUT {
@@ -860,6 +844,8 @@ struct iga2_crtc_timing {
860#define P4M900_FUNCTION3 0x3364 844#define P4M900_FUNCTION3 0x3364
861/* VT3353 chipset*/ 845/* VT3353 chipset*/
862#define VX800_FUNCTION3 0x3353 846#define VX800_FUNCTION3 0x3353
847/* VT3409 chipset*/
848#define VX855_FUNCTION3 0x3409
863 849
864#define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value) 850#define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value)
865 851
@@ -883,7 +869,6 @@ extern int viafb_dual_fb;
883extern int viafb_LCD2_ON; 869extern int viafb_LCD2_ON;
884extern int viafb_LCD_ON; 870extern int viafb_LCD_ON;
885extern int viafb_DVI_ON; 871extern int viafb_DVI_ON;
886extern int viafb_accel;
887extern int viafb_hotplug; 872extern int viafb_hotplug;
888 873
889void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask); 874void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
@@ -904,7 +889,6 @@ void viafb_write_reg(u8 index, u16 io_port, u8 data);
904u8 viafb_read_reg(int io_port, u8 index); 889u8 viafb_read_reg(int io_port, u8 index);
905void viafb_lock_crt(void); 890void viafb_lock_crt(void);
906void viafb_unlock_crt(void); 891void viafb_unlock_crt(void);
907void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga);
908void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); 892void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
909void viafb_write_regx(struct io_reg RegTable[], int ItemNum); 893void viafb_write_regx(struct io_reg RegTable[], int ItemNum);
910struct VideoModeTable *viafb_get_modetbl_pointer(int Index); 894struct VideoModeTable *viafb_get_modetbl_pointer(int Index);
@@ -917,17 +901,20 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
917int viafb_setmode(int vmode_index, int hor_res, int ver_res, 901int viafb_setmode(int vmode_index, int hor_res, int ver_res,
918 int video_bpp, int vmode_index1, int hor_res1, 902 int video_bpp, int vmode_index1, int hor_res1,
919 int ver_res1, int video_bpp1); 903 int ver_res1, int video_bpp1);
920void viafb_init_chip_info(void); 904void viafb_init_chip_info(struct pci_dev *pdev,
905 const struct pci_device_id *pdi);
921void viafb_init_dac(int set_iga); 906void viafb_init_dac(int set_iga);
922int viafb_get_pixclock(int hres, int vres, int vmode_refresh); 907int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
923int viafb_get_refresh(int hres, int vres, u32 float_refresh); 908int viafb_get_refresh(int hres, int vres, u32 float_refresh);
924void viafb_update_device_setting(int hres, int vres, int bpp, 909void viafb_update_device_setting(int hres, int vres, int bpp,
925 int vmode_refresh, int flag); 910 int vmode_refresh, int flag);
926void viafb_get_mmio_info(unsigned long *mmio_base,
927 unsigned long *mmio_len);
928 911
912int viafb_get_fb_size_from_pci(void);
929void viafb_set_iga_path(void); 913void viafb_set_iga_path(void);
930void viafb_set_start_addr(void); 914void viafb_set_primary_address(u32 addr);
915void viafb_set_secondary_address(u32 addr);
916void viafb_set_primary_pitch(u32 pitch);
917void viafb_set_secondary_pitch(u32 pitch);
931void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); 918void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len);
932 919
933#endif /* __HW_H__ */ 920#endif /* __HW_H__ */
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h
index 842fe30b9868..de899807eade 100644
--- a/drivers/video/via/ioctl.h
+++ b/drivers/video/via/ioctl.h
@@ -50,8 +50,6 @@
50#define VIAFB_GET_GAMMA_LUT 0x56494124 50#define VIAFB_GET_GAMMA_LUT 0x56494124
51#define VIAFB_SET_GAMMA_LUT 0x56494125 51#define VIAFB_SET_GAMMA_LUT 0x56494125
52#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126 52#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126
53#define VIAFB_SET_VIDEO_DEVICE 0x56494127
54#define VIAFB_GET_VIDEO_DEVICE 0x56494128
55#define VIAFB_SET_SECOND_MODE 0x56494129 53#define VIAFB_SET_SECOND_MODE 0x56494129
56#define VIAFB_SYNC_SURFACE 0x56494130 54#define VIAFB_SYNC_SURFACE 0x56494130
57#define VIAFB_GET_DRIVER_CAPS 0x56494131 55#define VIAFB_GET_DRIVER_CAPS 0x56494131
@@ -179,9 +177,7 @@ struct viafb_ioctl_setting {
179 unsigned short second_dev_bpp; 177 unsigned short second_dev_bpp;
180 /* Indicate which device are primary display device. */ 178 /* Indicate which device are primary display device. */
181 unsigned int primary_device; 179 unsigned int primary_device;
182 /* Indicate which device will show video. only valid in duoview mode */ 180 unsigned int struct_reserved[35];
183 unsigned int video_device_status;
184 unsigned int struct_reserved[34];
185 struct viafb_ioctl_lcd_attribute lcd_attributes; 181 struct viafb_ioctl_lcd_attribute lcd_attributes;
186}; 182};
187 183
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 78c6b3387947..e3e597f937a5 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -207,13 +207,13 @@ static bool lvds_identify_integratedlvds(void)
207 207
208int viafb_lvds_trasmitter_identify(void) 208int viafb_lvds_trasmitter_identify(void)
209{ 209{
210 viaparinfo->i2c_stuff.i2c_port = I2CPORTINDEX; 210 viaparinfo->shared->i2c_stuff.i2c_port = I2CPORTINDEX;
211 if (viafb_lvds_identify_vt1636()) { 211 if (viafb_lvds_identify_vt1636()) {
212 viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX; 212 viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX;
213 DEBUG_MSG(KERN_INFO 213 DEBUG_MSG(KERN_INFO
214 "Found VIA VT1636 LVDS on port i2c 0x31 \n"); 214 "Found VIA VT1636 LVDS on port i2c 0x31 \n");
215 } else { 215 } else {
216 viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX; 216 viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX;
217 if (viafb_lvds_identify_vt1636()) { 217 if (viafb_lvds_identify_vt1636()) {
218 viaparinfo->chip_info->lvds_chip_info.i2c_port = 218 viaparinfo->chip_info->lvds_chip_info.i2c_port =
219 GPIOPORTINDEX; 219 GPIOPORTINDEX;
@@ -470,7 +470,7 @@ static int lvds_register_read(int index)
470{ 470{
471 u8 data; 471 u8 data;
472 472
473 viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX; 473 viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX;
474 viafb_i2c_readbyte((u8) viaparinfo->chip_info-> 474 viafb_i2c_readbyte((u8) viaparinfo->chip_info->
475 lvds_chip_info.lvds_chip_slave_addr, 475 lvds_chip_info.lvds_chip_slave_addr,
476 (u8) index, &data); 476 (u8) index, &data);
@@ -952,13 +952,10 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
952 int video_index = plvds_setting_info->lcd_panel_size; 952 int video_index = plvds_setting_info->lcd_panel_size;
953 int set_iga = plvds_setting_info->iga_path; 953 int set_iga = plvds_setting_info->iga_path;
954 int mode_bpp = plvds_setting_info->bpp; 954 int mode_bpp = plvds_setting_info->bpp;
955 int viafb_load_reg_num = 0;
956 int reg_value = 0;
957 int set_hres, set_vres; 955 int set_hres, set_vres;
958 int panel_hres, panel_vres; 956 int panel_hres, panel_vres;
959 u32 pll_D_N; 957 u32 pll_D_N;
960 int offset; 958 int offset;
961 struct io_register *reg = NULL;
962 struct display_timing mode_crt_reg, panel_crt_reg; 959 struct display_timing mode_crt_reg, panel_crt_reg;
963 struct crt_mode_table *panel_crt_table = NULL; 960 struct crt_mode_table *panel_crt_table = NULL;
964 struct VideoModeTable *vmode_tbl = NULL; 961 struct VideoModeTable *vmode_tbl = NULL;
@@ -1038,16 +1035,11 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
1038 } 1035 }
1039 1036
1040 /* Offset for simultaneous */ 1037 /* Offset for simultaneous */
1041 reg_value = offset; 1038 viafb_set_secondary_pitch(offset << 3);
1042 viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
1043 reg = offset_reg.iga2_offset_reg.reg;
1044 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1045 DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n"); 1039 DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n");
1046 viafb_load_fetch_count_reg(set_hres, 4, IGA2); 1040 viafb_load_fetch_count_reg(set_hres, 4, IGA2);
1047 /* Fetch count for simultaneous */ 1041 /* Fetch count for simultaneous */
1048 } else { /* SAMM */ 1042 } else { /* SAMM */
1049 /* Offset for IGA2 only */
1050 viafb_load_offset_reg(set_hres, mode_bpp / 8, set_iga);
1051 /* Fetch count for IGA2 only */ 1043 /* Fetch count for IGA2 only */
1052 viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); 1044 viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
1053 1045
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 2e1254da9c8c..7cd03e2a1275 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -167,6 +167,10 @@
167#define SR4B 0x4B 167#define SR4B 0x4B
168#define SR4C 0x4C 168#define SR4C 0x4C
169#define SR52 0x52 169#define SR52 0x52
170#define SR57 0x57
171#define SR58 0x58
172#define SR59 0x59
173#define SR5D 0x5D
170#define SR5E 0x5E 174#define SR5E 0x5E
171#define SR65 0x65 175#define SR65 0x65
172 176
@@ -966,6 +970,100 @@
966#define CX700_297_500M 0x00CE0403 970#define CX700_297_500M 0x00CE0403
967#define CX700_122_614M 0x00870802 971#define CX700_122_614M 0x00870802
968 972
973/* PLL for VX855 */
974#define VX855_22_000M 0x007B1005
975#define VX855_25_175M 0x008D1005
976#define VX855_26_719M 0x00961005
977#define VX855_26_880M 0x00961005
978#define VX855_27_000M 0x00971005
979#define VX855_29_581M 0x00A51005
980#define VX855_29_829M 0x00641003
981#define VX855_31_490M 0x00B01005
982#define VX855_31_500M 0x00B01005
983#define VX855_31_728M 0x008E1004
984#define VX855_32_668M 0x00921004
985#define VX855_36_000M 0x00A11004
986#define VX855_40_000M 0x00700C05
987#define VX855_41_291M 0x00730C05
988#define VX855_43_163M 0x00790C05
989#define VX855_45_250M 0x007F0C05 /* 45.46MHz */
990#define VX855_46_000M 0x00670C04
991#define VX855_46_996M 0x00690C04
992#define VX855_48_000M 0x00860C05
993#define VX855_48_875M 0x00890C05
994#define VX855_49_500M 0x00530C03
995#define VX855_52_406M 0x00580C03
996#define VX855_52_977M 0x00940C05
997#define VX855_56_250M 0x009D0C05
998#define VX855_60_466M 0x00A90C05
999#define VX855_61_500M 0x00AC0C05
1000#define VX855_65_000M 0x006D0C03
1001#define VX855_65_178M 0x00B60C05
1002#define VX855_66_750M 0x00700C03 /*67.116MHz */
1003#define VX855_67_295M 0x00BC0C05
1004#define VX855_68_179M 0x00BF0C05
1005#define VX855_68_369M 0x00BF0C05
1006#define VX855_69_924M 0x00C30C05
1007#define VX855_70_159M 0x00C30C05
1008#define VX855_72_000M 0x00A10C04
1009#define VX855_73_023M 0x00CC0C05
1010#define VX855_74_481M 0x00D10C05
1011#define VX855_78_750M 0x006E0805
1012#define VX855_79_466M 0x006F0805
1013#define VX855_80_136M 0x00700805
1014#define VX855_81_627M 0x00720805
1015#define VX855_83_375M 0x00750805
1016#define VX855_83_527M 0x00750805
1017#define VX855_83_950M 0x00750805
1018#define VX855_84_537M 0x00760805
1019#define VX855_84_750M 0x00760805 /* 84.537Mhz */
1020#define VX855_85_500M 0x00760805 /* 85.909080 MHz*/
1021#define VX855_85_860M 0x00760805
1022#define VX855_85_909M 0x00760805
1023#define VX855_88_750M 0x007C0805
1024#define VX855_89_489M 0x007D0805
1025#define VX855_94_500M 0x00840805
1026#define VX855_96_648M 0x00870805
1027#define VX855_97_750M 0x00890805
1028#define VX855_101_000M 0x008D0805
1029#define VX855_106_500M 0x00950805
1030#define VX855_108_000M 0x00970805
1031#define VX855_110_125M 0x00990805
1032#define VX855_112_000M 0x009D0805
1033#define VX855_113_309M 0x009F0805
1034#define VX855_115_000M 0x00A10805
1035#define VX855_118_840M 0x00A60805
1036#define VX855_119_000M 0x00A70805
1037#define VX855_121_750M 0x00AA0805 /* 121.704MHz */
1038#define VX855_122_614M 0x00AC0805
1039#define VX855_126_266M 0x00B10805
1040#define VX855_130_250M 0x00B60805 /* 130.250 */
1041#define VX855_135_000M 0x00BD0805
1042#define VX855_136_700M 0x00BF0805
1043#define VX855_137_750M 0x00C10805
1044#define VX855_138_400M 0x00C20805
1045#define VX855_144_300M 0x00CA0805
1046#define VX855_146_760M 0x00CE0805
1047#define VX855_148_500M 0x00D00805
1048#define VX855_153_920M 0x00540402
1049#define VX855_156_000M 0x006C0405
1050#define VX855_156_867M 0x006E0405
1051#define VX855_157_500M 0x006E0405
1052#define VX855_162_000M 0x00710405
1053#define VX855_172_798M 0x00790405
1054#define VX855_187_000M 0x00830405
1055#define VX855_193_295M 0x00870405
1056#define VX855_202_500M 0x008E0405
1057#define VX855_204_000M 0x008F0405
1058#define VX855_218_500M 0x00990405
1059#define VX855_229_500M 0x00A10405
1060#define VX855_234_000M 0x00A40405
1061#define VX855_267_250M 0x00BB0405
1062#define VX855_297_500M 0x00D00405
1063#define VX855_339_500M 0x00770005
1064#define VX855_340_772M 0x00770005
1065
1066
969/* Definition CRTC Timing Index */ 1067/* Definition CRTC Timing Index */
970#define H_TOTAL_INDEX 0 1068#define H_TOTAL_INDEX 0
971#define H_ADDR_INDEX 1 1069#define H_ADDR_INDEX 1
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index 0f3ed4eb236d..15543e968248 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -97,7 +97,7 @@ int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata)
97 mm1[0] = index; 97 mm1[0] = index;
98 msgs[0].len = 1; msgs[1].len = 1; 98 msgs[0].len = 1; msgs[1].len = 1;
99 msgs[0].buf = mm1; msgs[1].buf = pdata; 99 msgs[0].buf = mm1; msgs[1].buf = pdata;
100 i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2); 100 i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2);
101 101
102 return 0; 102 return 0;
103} 103}
@@ -111,7 +111,7 @@ int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data)
111 msgs.addr = slave_addr / 2; 111 msgs.addr = slave_addr / 2;
112 msgs.len = 2; 112 msgs.len = 2;
113 msgs.buf = msg; 113 msgs.buf = msg;
114 return i2c_transfer(&viaparinfo->i2c_stuff.adapter, &msgs, 1); 114 return i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, &msgs, 1);
115} 115}
116 116
117int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) 117int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len)
@@ -125,53 +125,53 @@ int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len)
125 mm1[0] = index; 125 mm1[0] = index;
126 msgs[0].len = 1; msgs[1].len = buff_len; 126 msgs[0].len = 1; msgs[1].len = buff_len;
127 msgs[0].buf = mm1; msgs[1].buf = buff; 127 msgs[0].buf = mm1; msgs[1].buf = buff;
128 i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2); 128 i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2);
129 return 0; 129 return 0;
130} 130}
131 131
132int viafb_create_i2c_bus(void *viapar) 132int viafb_create_i2c_bus(void *viapar)
133{ 133{
134 int ret; 134 int ret;
135 struct viafb_par *par = (struct viafb_par *)viapar; 135 struct via_i2c_stuff *i2c_stuff =
136 136 &((struct viafb_par *)viapar)->shared->i2c_stuff;
137 strcpy(par->i2c_stuff.adapter.name, "via_i2c"); 137
138 par->i2c_stuff.i2c_port = 0x0; 138 strcpy(i2c_stuff->adapter.name, "via_i2c");
139 par->i2c_stuff.adapter.owner = THIS_MODULE; 139 i2c_stuff->i2c_port = 0x0;
140 par->i2c_stuff.adapter.id = 0x01FFFF; 140 i2c_stuff->adapter.owner = THIS_MODULE;
141 par->i2c_stuff.adapter.class = 0; 141 i2c_stuff->adapter.id = 0x01FFFF;
142 par->i2c_stuff.adapter.algo_data = &par->i2c_stuff.algo; 142 i2c_stuff->adapter.class = 0;
143 par->i2c_stuff.adapter.dev.parent = NULL; 143 i2c_stuff->adapter.algo_data = &i2c_stuff->algo;
144 par->i2c_stuff.algo.setsda = via_i2c_setsda; 144 i2c_stuff->adapter.dev.parent = NULL;
145 par->i2c_stuff.algo.setscl = via_i2c_setscl; 145 i2c_stuff->algo.setsda = via_i2c_setsda;
146 par->i2c_stuff.algo.getsda = via_i2c_getsda; 146 i2c_stuff->algo.setscl = via_i2c_setscl;
147 par->i2c_stuff.algo.getscl = via_i2c_getscl; 147 i2c_stuff->algo.getsda = via_i2c_getsda;
148 par->i2c_stuff.algo.udelay = 40; 148 i2c_stuff->algo.getscl = via_i2c_getscl;
149 par->i2c_stuff.algo.timeout = 20; 149 i2c_stuff->algo.udelay = 40;
150 par->i2c_stuff.algo.data = &par->i2c_stuff; 150 i2c_stuff->algo.timeout = 20;
151 151 i2c_stuff->algo.data = i2c_stuff;
152 i2c_set_adapdata(&par->i2c_stuff.adapter, &par->i2c_stuff); 152
153 i2c_set_adapdata(&i2c_stuff->adapter, i2c_stuff);
153 154
154 /* Raise SCL and SDA */ 155 /* Raise SCL and SDA */
155 par->i2c_stuff.i2c_port = I2CPORTINDEX; 156 i2c_stuff->i2c_port = I2CPORTINDEX;
156 via_i2c_setsda(&par->i2c_stuff, 1); 157 via_i2c_setsda(i2c_stuff, 1);
157 via_i2c_setscl(&par->i2c_stuff, 1); 158 via_i2c_setscl(i2c_stuff, 1);
158 159
159 par->i2c_stuff.i2c_port = GPIOPORTINDEX; 160 i2c_stuff->i2c_port = GPIOPORTINDEX;
160 via_i2c_setsda(&par->i2c_stuff, 1); 161 via_i2c_setsda(i2c_stuff, 1);
161 via_i2c_setscl(&par->i2c_stuff, 1); 162 via_i2c_setscl(i2c_stuff, 1);
162 udelay(20); 163 udelay(20);
163 164
164 ret = i2c_bit_add_bus(&par->i2c_stuff.adapter); 165 ret = i2c_bit_add_bus(&i2c_stuff->adapter);
165 if (ret == 0) 166 if (ret == 0)
166 DEBUG_MSG("I2C bus %s registered.\n", 167 DEBUG_MSG("I2C bus %s registered.\n", i2c_stuff->adapter.name);
167 par->i2c_stuff.adapter.name);
168 else 168 else
169 DEBUG_MSG("Failed to register I2C bus %s.\n", 169 DEBUG_MSG("Failed to register I2C bus %s.\n",
170 par->i2c_stuff.adapter.name); 170 i2c_stuff->adapter.name);
171 return ret; 171 return ret;
172} 172}
173 173
174void viafb_delete_i2c_buss(void *par) 174void viafb_delete_i2c_buss(void *par)
175{ 175{
176 i2c_del_adapter(&((struct viafb_par *)par)->i2c_stuff.adapter); 176 i2c_del_adapter(&((struct viafb_par *)par)->shared->i2c_stuff.adapter);
177} 177}
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 72833f3334b5..56ec696e8afa 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -20,11 +20,12 @@
20 */ 20 */
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/seq_file.h>
24#include <linux/stat.h>
23#define _MASTER_FILE 25#define _MASTER_FILE
24 26
25#include "global.h" 27#include "global.h"
26 28
27static int MAX_CURS = 32;
28static struct fb_var_screeninfo default_var; 29static struct fb_var_screeninfo default_var;
29static char *viafb_name = "Via"; 30static char *viafb_name = "Via";
30static u32 pseudo_pal[17]; 31static u32 pseudo_pal[17];
@@ -33,12 +34,11 @@ static u32 pseudo_pal[17];
33static char *viafb_mode = "640x480"; 34static char *viafb_mode = "640x480";
34static char *viafb_mode1 = "640x480"; 35static char *viafb_mode1 = "640x480";
35 36
37static int viafb_accel = 1;
38
36/* Added for specifying active devices.*/ 39/* Added for specifying active devices.*/
37char *viafb_active_dev = ""; 40char *viafb_active_dev = "";
38 41
39/* Added for specifying video on devices.*/
40char *viafb_video_dev = "";
41
42/*Added for specify lcd output port*/ 42/*Added for specify lcd output port*/
43char *viafb_lcd_port = ""; 43char *viafb_lcd_port = "";
44char *viafb_dvi_port = ""; 44char *viafb_dvi_port = "";
@@ -50,71 +50,20 @@ static void apply_second_mode_setting(struct fb_var_screeninfo
50 *sec_var); 50 *sec_var);
51static void retrieve_device_setting(struct viafb_ioctl_setting 51static void retrieve_device_setting(struct viafb_ioctl_setting
52 *setting_info); 52 *setting_info);
53static void viafb_set_video_device(u32 video_dev_info);
54static void viafb_get_video_device(u32 *video_dev_info);
55
56/* Mode information */
57static const struct viafb_modeinfo viafb_modentry[] = {
58 {480, 640, VIA_RES_480X640},
59 {640, 480, VIA_RES_640X480},
60 {800, 480, VIA_RES_800X480},
61 {800, 600, VIA_RES_800X600},
62 {1024, 768, VIA_RES_1024X768},
63 {1152, 864, VIA_RES_1152X864},
64 {1280, 1024, VIA_RES_1280X1024},
65 {1600, 1200, VIA_RES_1600X1200},
66 {1440, 1050, VIA_RES_1440X1050},
67 {1280, 768, VIA_RES_1280X768,},
68 {1280, 800, VIA_RES_1280X800},
69 {1280, 960, VIA_RES_1280X960},
70 {1920, 1440, VIA_RES_1920X1440},
71 {848, 480, VIA_RES_848X480},
72 {1400, 1050, VIA_RES_1400X1050},
73 {720, 480, VIA_RES_720X480},
74 {720, 576, VIA_RES_720X576},
75 {1024, 512, VIA_RES_1024X512},
76 {1024, 576, VIA_RES_1024X576},
77 {1024, 600, VIA_RES_1024X600},
78 {1280, 720, VIA_RES_1280X720},
79 {1920, 1080, VIA_RES_1920X1080},
80 {1366, 768, VIA_RES_1368X768},
81 {1680, 1050, VIA_RES_1680X1050},
82 {960, 600, VIA_RES_960X600},
83 {1000, 600, VIA_RES_1000X600},
84 {1024, 576, VIA_RES_1024X576},
85 {1024, 600, VIA_RES_1024X600},
86 {1088, 612, VIA_RES_1088X612},
87 {1152, 720, VIA_RES_1152X720},
88 {1200, 720, VIA_RES_1200X720},
89 {1280, 600, VIA_RES_1280X600},
90 {1360, 768, VIA_RES_1360X768},
91 {1440, 900, VIA_RES_1440X900},
92 {1600, 900, VIA_RES_1600X900},
93 {1600, 1024, VIA_RES_1600X1024},
94 {1792, 1344, VIA_RES_1792X1344},
95 {1856, 1392, VIA_RES_1856X1392},
96 {1920, 1200, VIA_RES_1920X1200},
97 {2048, 1536, VIA_RES_2048X1536},
98 {0, 0, VIA_RES_INVALID}
99};
100 53
101static struct fb_ops viafb_ops; 54static struct fb_ops viafb_ops;
102 55
103static int viafb_update_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
104{
105 struct viafb_par *ppar;
106 ppar = info->par;
107
108 DEBUG_MSG(KERN_INFO "viafb_update_fix!\n");
109 56
110 fix->visual = 57static void viafb_update_fix(struct fb_info *info)
111 ppar->bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 58{
112 fix->line_length = ppar->linelength; 59 u32 bpp = info->var.bits_per_pixel;
113 60
114 return 0; 61 info->fix.visual =
62 bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
63 info->fix.line_length =
64 ((info->var.xres_virtual + 7) & ~7) * bpp / 8;
115} 65}
116 66
117
118static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, 67static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
119 struct viafb_par *viaparinfo) 68 struct viafb_par *viaparinfo)
120{ 69{
@@ -123,8 +72,6 @@ static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
123 72
124 fix->smem_start = viaparinfo->fbmem; 73 fix->smem_start = viaparinfo->fbmem;
125 fix->smem_len = viaparinfo->fbmem_free; 74 fix->smem_len = viaparinfo->fbmem_free;
126 fix->mmio_start = viaparinfo->mmio_base;
127 fix->mmio_len = viaparinfo->mmio_len;
128 75
129 fix->type = FB_TYPE_PACKED_PIXELS; 76 fix->type = FB_TYPE_PACKED_PIXELS;
130 fix->type_aux = 0; 77 fix->type_aux = 0;
@@ -147,28 +94,12 @@ static int viafb_release(struct fb_info *info, int user)
147 return 0; 94 return 0;
148} 95}
149 96
150static void viafb_update_viafb_par(struct fb_info *info)
151{
152 struct viafb_par *ppar;
153
154 ppar = info->par;
155 ppar->bpp = info->var.bits_per_pixel;
156 ppar->linelength = ((info->var.xres_virtual + 7) & ~7) * ppar->bpp / 8;
157 ppar->hres = info->var.xres;
158 ppar->vres = info->var.yres;
159 ppar->xoffset = info->var.xoffset;
160 ppar->yoffset = info->var.yoffset;
161}
162
163static int viafb_check_var(struct fb_var_screeninfo *var, 97static int viafb_check_var(struct fb_var_screeninfo *var,
164 struct fb_info *info) 98 struct fb_info *info)
165{ 99{
166 int vmode_index, htotal, vtotal; 100 int vmode_index, htotal, vtotal;
167 struct viafb_par *ppar; 101 struct viafb_par *ppar = info->par;
168 u32 long_refresh; 102 u32 long_refresh;
169 struct viafb_par *p_viafb_par;
170 ppar = info->par;
171
172 103
173 DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); 104 DEBUG_MSG(KERN_INFO "viafb_check_var!\n");
174 /* Sanity check */ 105 /* Sanity check */
@@ -212,23 +143,21 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
212 143
213 /* Adjust var according to our driver's own table */ 144 /* Adjust var according to our driver's own table */
214 viafb_fill_var_timing_info(var, viafb_refresh, vmode_index); 145 viafb_fill_var_timing_info(var, viafb_refresh, vmode_index);
215 146 if (info->var.accel_flags & FB_ACCELF_TEXT &&
216 /* This is indeed a patch for VT3353 */ 147 !ppar->shared->engine_mmio)
217 if (!info->par) 148 info->var.accel_flags = 0;
218 return -1;
219 p_viafb_par = (struct viafb_par *)info->par;
220 if (p_viafb_par->chip_info->gfx_chip_name == UNICHROME_VX800)
221 var->accel_flags = 0;
222 149
223 return 0; 150 return 0;
224} 151}
225 152
226static int viafb_set_par(struct fb_info *info) 153static int viafb_set_par(struct fb_info *info)
227{ 154{
155 struct viafb_par *viapar = info->par;
228 int vmode_index; 156 int vmode_index;
229 int vmode_index1 = 0; 157 int vmode_index1 = 0;
230 DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); 158 DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
231 159
160 viapar->depth = fb_get_color_depth(&info->var, &info->fix);
232 viafb_update_device_setting(info->var.xres, info->var.yres, 161 viafb_update_device_setting(info->var.xres, info->var.yres,
233 info->var.bits_per_pixel, viafb_refresh, 0); 162 info->var.bits_per_pixel, viafb_refresh, 0);
234 163
@@ -252,21 +181,12 @@ static int viafb_set_par(struct fb_info *info)
252 info->var.bits_per_pixel, vmode_index1, 181 info->var.bits_per_pixel, vmode_index1,
253 viafb_second_xres, viafb_second_yres, viafb_bpp1); 182 viafb_second_xres, viafb_second_yres, viafb_bpp1);
254 183
255 /*We should set memory offset according virtual_x */ 184 viafb_update_fix(info);
256 /*Fix me:put this function into viafb_setmode */
257 viafb_memory_pitch_patch(info);
258
259 /* Update ***fb_par information */
260 viafb_update_viafb_par(info);
261
262 /* Update other fixed information */
263 viafb_update_fix(&info->fix, info);
264 viafb_bpp = info->var.bits_per_pixel; 185 viafb_bpp = info->var.bits_per_pixel;
265 /* Update viafb_accel, it is necessary to our 2D accelerate */ 186 if (info->var.accel_flags & FB_ACCELF_TEXT)
266 viafb_accel = info->var.accel_flags; 187 info->flags &= ~FBINFO_HWACCEL_DISABLED;
267 188 else
268 if (viafb_accel) 189 info->flags |= FBINFO_HWACCEL_DISABLED;
269 viafb_set_2d_color_depth(info->var.bits_per_pixel);
270 } 190 }
271 191
272 return 0; 192 return 0;
@@ -503,12 +423,7 @@ static int viafb_pan_display(struct fb_var_screeninfo *var,
503 var->bits_per_pixel / 16; 423 var->bits_per_pixel / 16;
504 424
505 DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset); 425 DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset);
506 426 viafb_set_primary_address(offset);
507 viafb_write_reg_mask(0x48, 0x3d4, ((offset >> 24) & 0x3), 0x3);
508 viafb_write_reg_mask(0x34, 0x3d4, ((offset >> 16) & 0xff), 0xff);
509 viafb_write_reg_mask(0x0c, 0x3d4, ((offset >> 8) & 0xff), 0xff);
510 viafb_write_reg_mask(0x0d, 0x3d4, (offset & 0xff), 0xff);
511
512 return 0; 427 return 0;
513} 428}
514 429
@@ -560,7 +475,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
560 475
561 u32 __user *argp = (u32 __user *) arg; 476 u32 __user *argp = (u32 __user *) arg;
562 u32 gpu32; 477 u32 gpu32;
563 u32 video_dev_info = 0;
564 478
565 DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); 479 DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd);
566 memset(&u, 0, sizeof(u)); 480 memset(&u, 0, sizeof(u));
@@ -792,15 +706,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
792 if (put_user(state_info, argp)) 706 if (put_user(state_info, argp))
793 return -EFAULT; 707 return -EFAULT;
794 break; 708 break;
795 case VIAFB_SET_VIDEO_DEVICE:
796 get_user(video_dev_info, argp);
797 viafb_set_video_device(video_dev_info);
798 break;
799 case VIAFB_GET_VIDEO_DEVICE:
800 viafb_get_video_device(&video_dev_info);
801 if (put_user(video_dev_info, argp))
802 return -EFAULT;
803 break;
804 case VIAFB_SYNC_SURFACE: 709 case VIAFB_SYNC_SURFACE:
805 DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n"); 710 DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n");
806 break; 711 break;
@@ -866,10 +771,12 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
866static void viafb_fillrect(struct fb_info *info, 771static void viafb_fillrect(struct fb_info *info,
867 const struct fb_fillrect *rect) 772 const struct fb_fillrect *rect)
868{ 773{
869 u32 col = 0, rop = 0; 774 struct viafb_par *viapar = info->par;
870 int pitch; 775 struct viafb_shared *shared = viapar->shared;
776 u32 fg_color;
777 u8 rop;
871 778
872 if (!viafb_accel) { 779 if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) {
873 cfb_fillrect(info, rect); 780 cfb_fillrect(info, rect);
874 return; 781 return;
875 } 782 }
@@ -877,68 +784,31 @@ static void viafb_fillrect(struct fb_info *info,
877 if (!rect->width || !rect->height) 784 if (!rect->width || !rect->height)
878 return; 785 return;
879 786
880 switch (rect->rop) { 787 if (info->fix.visual == FB_VISUAL_TRUECOLOR)
881 case ROP_XOR: 788 fg_color = ((u32 *)info->pseudo_palette)[rect->color];
789 else
790 fg_color = rect->color;
791
792 if (rect->rop == ROP_XOR)
882 rop = 0x5A; 793 rop = 0x5A;
883 break; 794 else
884 case ROP_COPY:
885 default:
886 rop = 0xF0; 795 rop = 0xF0;
887 break;
888 }
889
890 switch (info->var.bits_per_pixel) {
891 case 8:
892 col = rect->color;
893 break;
894 case 16:
895 col = ((u32 *) (info->pseudo_palette))[rect->color];
896 break;
897 case 32:
898 col = ((u32 *) (info->pseudo_palette))[rect->color];
899 break;
900 }
901
902 /* BitBlt Source Address */
903 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
904 /* Source Base Address */
905 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
906 /* Destination Base Address */
907 writel(((unsigned long) (info->screen_base) -
908 (unsigned long) viafb_FB_MM) >> 3,
909 viaparinfo->io_virt + VIA_REG_DSTBASE);
910 /* Pitch */
911 pitch = (info->var.xres_virtual + 7) & ~7;
912 writel(VIA_PITCH_ENABLE |
913 (((pitch *
914 info->var.bits_per_pixel >> 3) >> 3) |
915 (((pitch * info->
916 var.bits_per_pixel >> 3) >> 3) << 16)),
917 viaparinfo->io_virt + VIA_REG_PITCH);
918 /* BitBlt Destination Address */
919 writel(((rect->dy << 16) | rect->dx),
920 viaparinfo->io_virt + VIA_REG_DSTPOS);
921 /* Dimension: width & height */
922 writel((((rect->height - 1) << 16) | (rect->width - 1)),
923 viaparinfo->io_virt + VIA_REG_DIMENSION);
924 /* Forground color or Destination color */
925 writel(col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
926 /* GE Command */
927 writel((0x01 | 0x2000 | (rop << 24)),
928 viaparinfo->io_virt + VIA_REG_GECMD);
929 796
797 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n");
798 if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_FILL,
799 rect->width, rect->height, info->var.bits_per_pixel,
800 viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy,
801 NULL, 0, 0, 0, 0, fg_color, 0, rop))
802 cfb_fillrect(info, rect);
930} 803}
931 804
932static void viafb_copyarea(struct fb_info *info, 805static void viafb_copyarea(struct fb_info *info,
933 const struct fb_copyarea *area) 806 const struct fb_copyarea *area)
934{ 807{
935 u32 dy = area->dy, sy = area->sy, direction = 0x0; 808 struct viafb_par *viapar = info->par;
936 u32 sx = area->sx, dx = area->dx, width = area->width; 809 struct viafb_shared *shared = viapar->shared;
937 int pitch;
938
939 DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n");
940 810
941 if (!viafb_accel) { 811 if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) {
942 cfb_copyarea(info, area); 812 cfb_copyarea(info, area);
943 return; 813 return;
944 } 814 }
@@ -946,263 +816,148 @@ static void viafb_copyarea(struct fb_info *info,
946 if (!area->width || !area->height) 816 if (!area->width || !area->height)
947 return; 817 return;
948 818
949 if (sy < dy) { 819 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n");
950 dy += area->height - 1; 820 if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_COLOR,
951 sy += area->height - 1; 821 area->width, area->height, info->var.bits_per_pixel,
952 direction |= 0x4000; 822 viapar->vram_addr, info->fix.line_length, area->dx, area->dy,
953 } 823 NULL, viapar->vram_addr, info->fix.line_length,
954 824 area->sx, area->sy, 0, 0, 0))
955 if (sx < dx) { 825 cfb_copyarea(info, area);
956 dx += width - 1;
957 sx += width - 1;
958 direction |= 0x8000;
959 }
960
961 /* Source Base Address */
962 writel(((unsigned long) (info->screen_base) -
963 (unsigned long) viafb_FB_MM) >> 3,
964 viaparinfo->io_virt + VIA_REG_SRCBASE);
965 /* Destination Base Address */
966 writel(((unsigned long) (info->screen_base) -
967 (unsigned long) viafb_FB_MM) >> 3,
968 viaparinfo->io_virt + VIA_REG_DSTBASE);
969 /* Pitch */
970 pitch = (info->var.xres_virtual + 7) & ~7;
971 /* VIA_PITCH_ENABLE can be omitted now. */
972 writel(VIA_PITCH_ENABLE |
973 (((pitch *
974 info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
975 info->var.
976 bits_per_pixel
977 >> 3) >> 3)
978 << 16)),
979 viaparinfo->io_virt + VIA_REG_PITCH);
980 /* BitBlt Source Address */
981 writel(((sy << 16) | sx), viaparinfo->io_virt + VIA_REG_SRCPOS);
982 /* BitBlt Destination Address */
983 writel(((dy << 16) | dx), viaparinfo->io_virt + VIA_REG_DSTPOS);
984 /* Dimension: width & height */
985 writel((((area->height - 1) << 16) | (area->width - 1)),
986 viaparinfo->io_virt + VIA_REG_DIMENSION);
987 /* GE Command */
988 writel((0x01 | direction | (0xCC << 24)),
989 viaparinfo->io_virt + VIA_REG_GECMD);
990
991} 826}
992 827
993static void viafb_imageblit(struct fb_info *info, 828static void viafb_imageblit(struct fb_info *info,
994 const struct fb_image *image) 829 const struct fb_image *image)
995{ 830{
996 u32 size, bg_col = 0, fg_col = 0, *udata; 831 struct viafb_par *viapar = info->par;
997 int i; 832 struct viafb_shared *shared = viapar->shared;
998 int pitch; 833 u32 fg_color = 0, bg_color = 0;
834 u8 op;
999 835
1000 if (!viafb_accel) { 836 if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt ||
837 (image->depth != 1 && image->depth != viapar->depth)) {
1001 cfb_imageblit(info, image); 838 cfb_imageblit(info, image);
1002 return; 839 return;
1003 } 840 }
1004 841
1005 udata = (u32 *) image->data; 842 if (image->depth == 1) {
1006 843 op = VIA_BITBLT_MONO;
1007 switch (info->var.bits_per_pixel) { 844 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1008 case 8: 845 fg_color =
1009 bg_col = image->bg_color; 846 ((u32 *)info->pseudo_palette)[image->fg_color];
1010 fg_col = image->fg_color; 847 bg_color =
1011 break; 848 ((u32 *)info->pseudo_palette)[image->bg_color];
1012 case 16: 849 } else {
1013 bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; 850 fg_color = image->fg_color;
1014 fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; 851 bg_color = image->bg_color;
1015 break; 852 }
1016 case 32: 853 } else
1017 bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; 854 op = VIA_BITBLT_COLOR;
1018 fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];
1019 break;
1020 }
1021 size = image->width * image->height;
1022
1023 /* Source Base Address */
1024 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
1025 /* Destination Base Address */
1026 writel(((unsigned long) (info->screen_base) -
1027 (unsigned long) viafb_FB_MM) >> 3,
1028 viaparinfo->io_virt + VIA_REG_DSTBASE);
1029 /* Pitch */
1030 pitch = (info->var.xres_virtual + 7) & ~7;
1031 writel(VIA_PITCH_ENABLE |
1032 (((pitch *
1033 info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
1034 info->var.
1035 bits_per_pixel
1036 >> 3) >> 3)
1037 << 16)),
1038 viaparinfo->io_virt + VIA_REG_PITCH);
1039 /* BitBlt Source Address */
1040 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
1041 /* BitBlt Destination Address */
1042 writel(((image->dy << 16) | image->dx),
1043 viaparinfo->io_virt + VIA_REG_DSTPOS);
1044 /* Dimension: width & height */
1045 writel((((image->height - 1) << 16) | (image->width - 1)),
1046 viaparinfo->io_virt + VIA_REG_DIMENSION);
1047 /* fb color */
1048 writel(fg_col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
1049 /* bg color */
1050 writel(bg_col, viaparinfo->io_virt + VIA_REG_BGCOLOR);
1051 /* GE Command */
1052 writel(0xCC020142, viaparinfo->io_virt + VIA_REG_GECMD);
1053
1054 for (i = 0; i < size / 4; i++) {
1055 writel(*udata, viaparinfo->io_virt + VIA_MMIO_BLTBASE);
1056 udata++;
1057 }
1058 855
856 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n");
857 if (shared->hw_bitblt(shared->engine_mmio, op,
858 image->width, image->height, info->var.bits_per_pixel,
859 viapar->vram_addr, info->fix.line_length, image->dx, image->dy,
860 (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0))
861 cfb_imageblit(info, image);
1059} 862}
1060 863
1061static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) 864static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1062{ 865{
1063 u32 temp, xx, yy, bg_col = 0, fg_col = 0; 866 struct viafb_par *viapar = info->par;
1064 int i, j = 0; 867 void __iomem *engine = viapar->shared->engine_mmio;
1065 static int hw_cursor; 868 u32 temp, xx, yy, bg_color = 0, fg_color = 0,
1066 struct viafb_par *p_viafb_par; 869 chip_name = viapar->shared->chip_info.gfx_chip_name;
1067 870 int i, j = 0, cur_size = 64;
1068 if (viafb_accel)
1069 hw_cursor = 1;
1070
1071 if (!viafb_accel) {
1072 if (hw_cursor) {
1073 viafb_show_hw_cursor(info, HW_Cursor_OFF);
1074 hw_cursor = 0;
1075 }
1076 return -ENODEV;
1077 }
1078 871
1079 if ((((struct viafb_par *)(info->par))->iga_path == IGA2) 872 if (info->flags & FBINFO_HWACCEL_DISABLED || info != viafbinfo)
1080 && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266))
1081 return -ENODEV; 873 return -ENODEV;
1082 874
1083 /* When duoview and using lcd , use soft cursor */ 875 if (chip_name == UNICHROME_CLE266 && viapar->iga_path == IGA2)
1084 if (viafb_LCD_ON || ((struct viafb_par *)(info->par))->duoview)
1085 return -ENODEV; 876 return -ENODEV;
1086 877
1087 viafb_show_hw_cursor(info, HW_Cursor_OFF); 878 viafb_show_hw_cursor(info, HW_Cursor_OFF);
1088 viacursor = *cursor;
1089 879
1090 if (cursor->set & FB_CUR_SETHOT) { 880 if (cursor->set & FB_CUR_SETHOT) {
1091 viacursor.hot = cursor->hot; 881 temp = (cursor->hot.x << 16) + cursor->hot.y;
1092 temp = ((viacursor.hot.x) << 16) + viacursor.hot.y; 882 writel(temp, engine + VIA_REG_CURSOR_ORG);
1093 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
1094 } 883 }
1095 884
1096 if (cursor->set & FB_CUR_SETPOS) { 885 if (cursor->set & FB_CUR_SETPOS) {
1097 viacursor.image.dx = cursor->image.dx;
1098 viacursor.image.dy = cursor->image.dy;
1099 yy = cursor->image.dy - info->var.yoffset; 886 yy = cursor->image.dy - info->var.yoffset;
1100 xx = cursor->image.dx - info->var.xoffset; 887 xx = cursor->image.dx - info->var.xoffset;
1101 temp = yy & 0xFFFF; 888 temp = yy & 0xFFFF;
1102 temp |= (xx << 16); 889 temp |= (xx << 16);
1103 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_POS); 890 writel(temp, engine + VIA_REG_CURSOR_POS);
1104 } 891 }
1105 892
1106 if (cursor->set & FB_CUR_SETSIZE) { 893 if (cursor->image.width <= 32 && cursor->image.height <= 32)
1107 temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 894 cur_size = 32;
895 else if (cursor->image.width <= 64 && cursor->image.height <= 64)
896 cur_size = 64;
897 else {
898 printk(KERN_WARNING "viafb_cursor: The cursor is too large "
899 "%dx%d", cursor->image.width, cursor->image.height);
900 return -ENXIO;
901 }
1108 902
1109 if ((cursor->image.width <= 32) 903 if (cursor->set & FB_CUR_SETSIZE) {
1110 && (cursor->image.height <= 32)) { 904 temp = readl(engine + VIA_REG_CURSOR_MODE);
1111 MAX_CURS = 32; 905 if (cur_size == 32)
1112 temp |= 0x2; 906 temp |= 0x2;
1113 } else if ((cursor->image.width <= 64) 907 else
1114 && (cursor->image.height <= 64)) { 908 temp &= ~0x2;
1115 MAX_CURS = 64;
1116 temp &= 0xFFFFFFFD;
1117 } else {
1118 DEBUG_MSG(KERN_INFO
1119 "The cursor image is biger than 64x64 bits...\n");
1120 return -ENXIO;
1121 }
1122 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
1123 909
1124 viacursor.image.height = cursor->image.height; 910 writel(temp, engine + VIA_REG_CURSOR_MODE);
1125 viacursor.image.width = cursor->image.width;
1126 } 911 }
1127 912
1128 if (cursor->set & FB_CUR_SETCMAP) { 913 if (cursor->set & FB_CUR_SETCMAP) {
1129 viacursor.image.fg_color = cursor->image.fg_color; 914 fg_color = cursor->image.fg_color;
1130 viacursor.image.bg_color = cursor->image.bg_color; 915 bg_color = cursor->image.bg_color;
1131 916 if (chip_name == UNICHROME_CX700 ||
1132 switch (info->var.bits_per_pixel) { 917 chip_name == UNICHROME_VX800 ||
1133 case 8: 918 chip_name == UNICHROME_VX855) {
1134 case 16: 919 fg_color =
1135 case 32: 920 ((info->cmap.red[fg_color] & 0xFFC0) << 14) |
1136 bg_col = 921 ((info->cmap.green[fg_color] & 0xFFC0) << 4) |
1137 (0xFF << 24) | 922 ((info->cmap.blue[fg_color] & 0xFFC0) >> 6);
1138 (((info->cmap.red)[viacursor.image.bg_color] & 923 bg_color =
1139 0xFF00) << 8) | 924 ((info->cmap.red[bg_color] & 0xFFC0) << 14) |
1140 ((info->cmap.green)[viacursor.image.bg_color] & 925 ((info->cmap.green[bg_color] & 0xFFC0) << 4) |
1141 0xFF00) | 926 ((info->cmap.blue[bg_color] & 0xFFC0) >> 6);
1142 (((info->cmap.blue)[viacursor.image.bg_color] & 927 } else {
1143 0xFF00) >> 8); 928 fg_color =
1144 fg_col = 929 ((info->cmap.red[fg_color] & 0xFF00) << 8) |
1145 (0xFF << 24) | 930 (info->cmap.green[fg_color] & 0xFF00) |
1146 (((info->cmap.red)[viacursor.image.fg_color] & 931 ((info->cmap.blue[fg_color] & 0xFF00) >> 8);
1147 0xFF00) << 8) | 932 bg_color =
1148 ((info->cmap.green)[viacursor.image.fg_color] & 933 ((info->cmap.red[bg_color] & 0xFF00) << 8) |
1149 0xFF00) | 934 (info->cmap.green[bg_color] & 0xFF00) |
1150 (((info->cmap.blue)[viacursor.image.fg_color] & 935 ((info->cmap.blue[bg_color] & 0xFF00) >> 8);
1151 0xFF00) >> 8);
1152 break;
1153 default:
1154 return 0;
1155 }
1156
1157 /* This is indeed a patch for VT3324/VT3353 */
1158 if (!info->par)
1159 return 0;
1160 p_viafb_par = (struct viafb_par *)info->par;
1161
1162 if ((p_viafb_par->chip_info->gfx_chip_name ==
1163 UNICHROME_CX700) ||
1164 ((p_viafb_par->chip_info->gfx_chip_name ==
1165 UNICHROME_VX800))) {
1166 bg_col =
1167 (((info->cmap.red)[viacursor.image.bg_color] &
1168 0xFFC0) << 14) |
1169 (((info->cmap.green)[viacursor.image.bg_color] &
1170 0xFFC0) << 4) |
1171 (((info->cmap.blue)[viacursor.image.bg_color] &
1172 0xFFC0) >> 6);
1173 fg_col =
1174 (((info->cmap.red)[viacursor.image.fg_color] &
1175 0xFFC0) << 14) |
1176 (((info->cmap.green)[viacursor.image.fg_color] &
1177 0xFFC0) << 4) |
1178 (((info->cmap.blue)[viacursor.image.fg_color] &
1179 0xFFC0) >> 6);
1180 } 936 }
1181 937
1182 writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG); 938 writel(bg_color, engine + VIA_REG_CURSOR_BG);
1183 writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG); 939 writel(fg_color, engine + VIA_REG_CURSOR_FG);
1184 } 940 }
1185 941
1186 if (cursor->set & FB_CUR_SETSHAPE) { 942 if (cursor->set & FB_CUR_SETSHAPE) {
1187 struct { 943 struct {
1188 u8 data[CURSOR_SIZE / 8]; 944 u8 data[CURSOR_SIZE];
1189 u32 bak[CURSOR_SIZE / 32]; 945 u32 bak[CURSOR_SIZE / 4];
1190 } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); 946 } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC);
1191 int size = 947 int size = ((cursor->image.width + 7) >> 3) *
1192 ((viacursor.image.width + 7) >> 3) * 948 cursor->image.height;
1193 viacursor.image.height;
1194 949
1195 if (cr_data == NULL) 950 if (!cr_data)
1196 goto out; 951 return -ENOMEM;
1197 952
1198 if (MAX_CURS == 32) { 953 if (cur_size == 32) {
1199 for (i = 0; i < (CURSOR_SIZE / 32); i++) { 954 for (i = 0; i < (CURSOR_SIZE / 4); i++) {
1200 cr_data->bak[i] = 0x0; 955 cr_data->bak[i] = 0x0;
1201 cr_data->bak[i + 1] = 0xFFFFFFFF; 956 cr_data->bak[i + 1] = 0xFFFFFFFF;
1202 i += 1; 957 i += 1;
1203 } 958 }
1204 } else if (MAX_CURS == 64) { 959 } else {
1205 for (i = 0; i < (CURSOR_SIZE / 32); i++) { 960 for (i = 0; i < (CURSOR_SIZE / 4); i++) {
1206 cr_data->bak[i] = 0x0; 961 cr_data->bak[i] = 0x0;
1207 cr_data->bak[i + 1] = 0x0; 962 cr_data->bak[i + 1] = 0x0;
1208 cr_data->bak[i + 2] = 0xFFFFFFFF; 963 cr_data->bak[i + 2] = 0xFFFFFFFF;
@@ -1211,27 +966,27 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1211 } 966 }
1212 } 967 }
1213 968
1214 switch (viacursor.rop) { 969 switch (cursor->rop) {
1215 case ROP_XOR: 970 case ROP_XOR:
1216 for (i = 0; i < size; i++) 971 for (i = 0; i < size; i++)
1217 cr_data->data[i] = viacursor.mask[i]; 972 cr_data->data[i] = cursor->mask[i];
1218 break; 973 break;
1219 case ROP_COPY: 974 case ROP_COPY:
1220 975
1221 for (i = 0; i < size; i++) 976 for (i = 0; i < size; i++)
1222 cr_data->data[i] = viacursor.mask[i]; 977 cr_data->data[i] = cursor->mask[i];
1223 break; 978 break;
1224 default: 979 default:
1225 break; 980 break;
1226 } 981 }
1227 982
1228 if (MAX_CURS == 32) { 983 if (cur_size == 32) {
1229 for (i = 0; i < size; i++) { 984 for (i = 0; i < size; i++) {
1230 cr_data->bak[j] = (u32) cr_data->data[i]; 985 cr_data->bak[j] = (u32) cr_data->data[i];
1231 cr_data->bak[j + 1] = ~cr_data->bak[j]; 986 cr_data->bak[j + 1] = ~cr_data->bak[j];
1232 j += 2; 987 j += 2;
1233 } 988 }
1234 } else if (MAX_CURS == 64) { 989 } else {
1235 for (i = 0; i < size; i++) { 990 for (i = 0; i < size; i++) {
1236 cr_data->bak[j] = (u32) cr_data->data[i]; 991 cr_data->bak[j] = (u32) cr_data->data[i];
1237 cr_data->bak[j + 1] = 0x0; 992 cr_data->bak[j + 1] = 0x0;
@@ -1241,14 +996,12 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1241 } 996 }
1242 } 997 }
1243 998
1244 memcpy(((struct viafb_par *)(info->par))->fbmem_virt + 999 memcpy_toio(viafbinfo->screen_base + viapar->shared->
1245 ((struct viafb_par *)(info->par))->cursor_start, 1000 cursor_vram_addr, cr_data->bak, CURSOR_SIZE);
1246 cr_data->bak, CURSOR_SIZE);
1247out:
1248 kfree(cr_data); 1001 kfree(cr_data);
1249 } 1002 }
1250 1003
1251 if (viacursor.enable) 1004 if (cursor->enable)
1252 viafb_show_hw_cursor(info, HW_Cursor_ON); 1005 viafb_show_hw_cursor(info, HW_Cursor_ON);
1253 1006
1254 return 0; 1007 return 0;
@@ -1256,8 +1009,8 @@ out:
1256 1009
1257static int viafb_sync(struct fb_info *info) 1010static int viafb_sync(struct fb_info *info)
1258{ 1011{
1259 if (viafb_accel) 1012 if (!(info->flags & FBINFO_HWACCEL_DISABLED))
1260 viafb_wait_engine_idle(); 1013 viafb_wait_engine_idle(info);
1261 return 0; 1014 return 0;
1262} 1015}
1263 1016
@@ -1266,12 +1019,16 @@ int viafb_get_mode_index(int hres, int vres)
1266 u32 i; 1019 u32 i;
1267 DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n"); 1020 DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n");
1268 1021
1269 for (i = 0; viafb_modentry[i].mode_index != VIA_RES_INVALID; i++) 1022 for (i = 0; i < NUM_TOTAL_MODETABLE; i++)
1270 if (viafb_modentry[i].xres == hres && 1023 if (CLE266Modes[i].mode_array &&
1271 viafb_modentry[i].yres == vres) 1024 CLE266Modes[i].crtc[0].crtc.hor_addr == hres &&
1025 CLE266Modes[i].crtc[0].crtc.ver_addr == vres)
1272 break; 1026 break;
1273 1027
1274 return viafb_modentry[i].mode_index; 1028 if (i == NUM_TOTAL_MODETABLE)
1029 return VIA_RES_INVALID;
1030
1031 return CLE266Modes[i].ModeIndex;
1275} 1032}
1276 1033
1277static void check_available_device_to_enable(int device_id) 1034static void check_available_device_to_enable(int device_id)
@@ -1375,36 +1132,11 @@ static void viafb_set_device(struct device_t active_dev)
1375 viafb_SAMM_ON = active_dev.samm; 1132 viafb_SAMM_ON = active_dev.samm;
1376 viafb_primary_dev = active_dev.primary_dev; 1133 viafb_primary_dev = active_dev.primary_dev;
1377 1134
1378 viafb_set_start_addr(); 1135 viafb_set_primary_address(0);
1136 viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
1379 viafb_set_iga_path(); 1137 viafb_set_iga_path();
1380} 1138}
1381 1139
1382static void viafb_set_video_device(u32 video_dev_info)
1383{
1384 viaparinfo->video_on_crt = STATE_OFF;
1385 viaparinfo->video_on_dvi = STATE_OFF;
1386 viaparinfo->video_on_lcd = STATE_OFF;
1387
1388 /* Check available device to enable: */
1389 if ((video_dev_info & CRT_Device) == CRT_Device)
1390 viaparinfo->video_on_crt = STATE_ON;
1391 else if ((video_dev_info & DVI_Device) == DVI_Device)
1392 viaparinfo->video_on_dvi = STATE_ON;
1393 else if ((video_dev_info & LCD_Device) == LCD_Device)
1394 viaparinfo->video_on_lcd = STATE_ON;
1395}
1396
1397static void viafb_get_video_device(u32 *video_dev_info)
1398{
1399 *video_dev_info = None_Device;
1400 if (viaparinfo->video_on_crt == STATE_ON)
1401 *video_dev_info |= CRT_Device;
1402 else if (viaparinfo->video_on_dvi == STATE_ON)
1403 *video_dev_info |= DVI_Device;
1404 else if (viaparinfo->video_on_lcd == STATE_ON)
1405 *video_dev_info |= LCD_Device;
1406}
1407
1408static int get_primary_device(void) 1140static int get_primary_device(void)
1409{ 1141{
1410 int primary_device = 0; 1142 int primary_device = 0;
@@ -1446,18 +1178,6 @@ static int get_primary_device(void)
1446 return primary_device; 1178 return primary_device;
1447} 1179}
1448 1180
1449static u8 is_duoview(void)
1450{
1451 if (0 == viafb_SAMM_ON) {
1452 if (viafb_LCD_ON + viafb_LCD2_ON +
1453 viafb_DVI_ON + viafb_CRT_ON == 2)
1454 return true;
1455 return false;
1456 } else {
1457 return false;
1458 }
1459}
1460
1461static void apply_second_mode_setting(struct fb_var_screeninfo 1181static void apply_second_mode_setting(struct fb_var_screeninfo
1462 *sec_var) 1182 *sec_var)
1463{ 1183{
@@ -1559,14 +1279,13 @@ static int apply_device_setting(struct viafb_ioctl_setting setting_info,
1559 if (viafb_SAMM_ON) 1279 if (viafb_SAMM_ON)
1560 viafb_primary_dev = setting_info.primary_device; 1280 viafb_primary_dev = setting_info.primary_device;
1561 1281
1562 viafb_set_start_addr(); 1282 viafb_set_primary_address(0);
1283 viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
1563 viafb_set_iga_path(); 1284 viafb_set_iga_path();
1564 } 1285 }
1565 need_set_mode = 1; 1286 need_set_mode = 1;
1566 } 1287 }
1567 1288
1568 viaparinfo->duoview = is_duoview();
1569
1570 if (!need_set_mode) { 1289 if (!need_set_mode) {
1571 ; 1290 ;
1572 } else { 1291 } else {
@@ -1589,18 +1308,6 @@ static void retrieve_device_setting(struct viafb_ioctl_setting
1589 setting_info->device_status |= LCD_Device; 1308 setting_info->device_status |= LCD_Device;
1590 if (viafb_LCD2_ON == 1) 1309 if (viafb_LCD2_ON == 1)
1591 setting_info->device_status |= LCD2_Device; 1310 setting_info->device_status |= LCD2_Device;
1592 if ((viaparinfo->video_on_crt == 1) && (viafb_CRT_ON == 1)) {
1593 setting_info->video_device_status =
1594 viaparinfo->crt_setting_info->iga_path;
1595 } else if ((viaparinfo->video_on_dvi == 1) && (viafb_DVI_ON == 1)) {
1596 setting_info->video_device_status =
1597 viaparinfo->tmds_setting_info->iga_path;
1598 } else if ((viaparinfo->video_on_lcd == 1) && (viafb_LCD_ON == 1)) {
1599 setting_info->video_device_status =
1600 viaparinfo->lvds_setting_info->iga_path;
1601 } else {
1602 setting_info->video_device_status = 0;
1603 }
1604 1311
1605 setting_info->samm_status = viafb_SAMM_ON; 1312 setting_info->samm_status = viafb_SAMM_ON;
1606 setting_info->primary_device = get_primary_device(); 1313 setting_info->primary_device = get_primary_device();
@@ -1687,25 +1394,6 @@ static void parse_active_dev(void)
1687 viafb_CRT_ON = STATE_ON; 1394 viafb_CRT_ON = STATE_ON;
1688 viafb_SAMM_ON = STATE_OFF; 1395 viafb_SAMM_ON = STATE_OFF;
1689 } 1396 }
1690 viaparinfo->duoview = is_duoview();
1691}
1692
1693static void parse_video_dev(void)
1694{
1695 viaparinfo->video_on_crt = STATE_OFF;
1696 viaparinfo->video_on_dvi = STATE_OFF;
1697 viaparinfo->video_on_lcd = STATE_OFF;
1698
1699 if (!strncmp(viafb_video_dev, "CRT", 3)) {
1700 /* Video on CRT */
1701 viaparinfo->video_on_crt = STATE_ON;
1702 } else if (!strncmp(viafb_video_dev, "DVI", 3)) {
1703 /* Video on DVI */
1704 viaparinfo->video_on_dvi = STATE_ON;
1705 } else if (!strncmp(viafb_video_dev, "LCD", 3)) {
1706 /* Video on LCD */
1707 viaparinfo->video_on_lcd = STATE_ON;
1708 }
1709} 1397}
1710 1398
1711static int parse_port(char *opt_str, int *output_interface) 1399static int parse_port(char *opt_str, int *output_interface)
@@ -1754,10 +1442,8 @@ static void parse_dvi_port(void)
1754 * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], 1442 * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2],
1755 * CR9B, SR65, CR97, CR99 1443 * CR9B, SR65, CR97, CR99
1756 */ 1444 */
1757static int viafb_dvp0_proc_read(char *buf, char **start, off_t offset, 1445static int viafb_dvp0_proc_show(struct seq_file *m, void *v)
1758int count, int *eof, void *data)
1759{ 1446{
1760 int len = 0;
1761 u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0; 1447 u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0;
1762 dvp0_data_dri = 1448 dvp0_data_dri =
1763 (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 | 1449 (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 |
@@ -1766,13 +1452,17 @@ int count, int *eof, void *data)
1766 (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 | 1452 (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 |
1767 (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2; 1453 (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2;
1768 dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f; 1454 dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f;
1769 len += 1455 seq_printf(m, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri);
1770 sprintf(buf + len, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri); 1456 return 0;
1771 *eof = 1; /*Inform kernel end of data */
1772 return len;
1773} 1457}
1774static int viafb_dvp0_proc_write(struct file *file, 1458
1775 const char __user *buffer, unsigned long count, void *data) 1459static int viafb_dvp0_proc_open(struct inode *inode, struct file *file)
1460{
1461 return single_open(file, viafb_dvp0_proc_show, NULL);
1462}
1463
1464static ssize_t viafb_dvp0_proc_write(struct file *file,
1465 const char __user *buffer, size_t count, loff_t *pos)
1776{ 1466{
1777 char buf[20], *value, *pbuf; 1467 char buf[20], *value, *pbuf;
1778 u8 reg_val = 0; 1468 u8 reg_val = 0;
@@ -1816,21 +1506,33 @@ static int viafb_dvp0_proc_write(struct file *file,
1816 } 1506 }
1817 return count; 1507 return count;
1818} 1508}
1819static int viafb_dvp1_proc_read(char *buf, char **start, off_t offset, 1509
1820 int count, int *eof, void *data) 1510static const struct file_operations viafb_dvp0_proc_fops = {
1511 .owner = THIS_MODULE,
1512 .open = viafb_dvp0_proc_open,
1513 .read = seq_read,
1514 .llseek = seq_lseek,
1515 .release = single_release,
1516 .write = viafb_dvp0_proc_write,
1517};
1518
1519static int viafb_dvp1_proc_show(struct seq_file *m, void *v)
1821{ 1520{
1822 int len = 0;
1823 u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0; 1521 u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0;
1824 dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f; 1522 dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f;
1825 dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2; 1523 dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2;
1826 dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03; 1524 dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03;
1827 len += 1525 seq_printf(m, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri);
1828 sprintf(buf + len, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri); 1526 return 0;
1829 *eof = 1; /*Inform kernel end of data */
1830 return len;
1831} 1527}
1832static int viafb_dvp1_proc_write(struct file *file, 1528
1833 const char __user *buffer, unsigned long count, void *data) 1529static int viafb_dvp1_proc_open(struct inode *inode, struct file *file)
1530{
1531 return single_open(file, viafb_dvp1_proc_show, NULL);
1532}
1533
1534static ssize_t viafb_dvp1_proc_write(struct file *file,
1535 const char __user *buffer, size_t count, loff_t *pos)
1834{ 1536{
1835 char buf[20], *value, *pbuf; 1537 char buf[20], *value, *pbuf;
1836 u8 reg_val = 0; 1538 u8 reg_val = 0;
@@ -1869,18 +1571,30 @@ static int viafb_dvp1_proc_write(struct file *file,
1869 return count; 1571 return count;
1870} 1572}
1871 1573
1872static int viafb_dfph_proc_read(char *buf, char **start, off_t offset, 1574static const struct file_operations viafb_dvp1_proc_fops = {
1873 int count, int *eof, void *data) 1575 .owner = THIS_MODULE,
1576 .open = viafb_dvp1_proc_open,
1577 .read = seq_read,
1578 .llseek = seq_lseek,
1579 .release = single_release,
1580 .write = viafb_dvp1_proc_write,
1581};
1582
1583static int viafb_dfph_proc_show(struct seq_file *m, void *v)
1874{ 1584{
1875 int len = 0;
1876 u8 dfp_high = 0; 1585 u8 dfp_high = 0;
1877 dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f; 1586 dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f;
1878 len += sprintf(buf + len, "%x\n", dfp_high); 1587 seq_printf(m, "%x\n", dfp_high);
1879 *eof = 1; /*Inform kernel end of data */ 1588 return 0;
1880 return len;
1881} 1589}
1882static int viafb_dfph_proc_write(struct file *file, 1590
1883 const char __user *buffer, unsigned long count, void *data) 1591static int viafb_dfph_proc_open(struct inode *inode, struct file *file)
1592{
1593 return single_open(file, viafb_dfph_proc_show, NULL);
1594}
1595
1596static ssize_t viafb_dfph_proc_write(struct file *file,
1597 const char __user *buffer, size_t count, loff_t *pos)
1884{ 1598{
1885 char buf[20]; 1599 char buf[20];
1886 u8 reg_val = 0; 1600 u8 reg_val = 0;
@@ -1895,18 +1609,31 @@ static int viafb_dfph_proc_write(struct file *file,
1895 viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f); 1609 viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f);
1896 return count; 1610 return count;
1897} 1611}
1898static int viafb_dfpl_proc_read(char *buf, char **start, off_t offset, 1612
1899 int count, int *eof, void *data) 1613static const struct file_operations viafb_dfph_proc_fops = {
1614 .owner = THIS_MODULE,
1615 .open = viafb_dfph_proc_open,
1616 .read = seq_read,
1617 .llseek = seq_lseek,
1618 .release = single_release,
1619 .write = viafb_dfph_proc_write,
1620};
1621
1622static int viafb_dfpl_proc_show(struct seq_file *m, void *v)
1900{ 1623{
1901 int len = 0;
1902 u8 dfp_low = 0; 1624 u8 dfp_low = 0;
1903 dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f; 1625 dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f;
1904 len += sprintf(buf + len, "%x\n", dfp_low); 1626 seq_printf(m, "%x\n", dfp_low);
1905 *eof = 1; /*Inform kernel end of data */ 1627 return 0;
1906 return len;
1907} 1628}
1908static int viafb_dfpl_proc_write(struct file *file, 1629
1909 const char __user *buffer, unsigned long count, void *data) 1630static int viafb_dfpl_proc_open(struct inode *inode, struct file *file)
1631{
1632 return single_open(file, viafb_dfpl_proc_show, NULL);
1633}
1634
1635static ssize_t viafb_dfpl_proc_write(struct file *file,
1636 const char __user *buffer, size_t count, loff_t *pos)
1910{ 1637{
1911 char buf[20]; 1638 char buf[20];
1912 u8 reg_val = 0; 1639 u8 reg_val = 0;
@@ -1921,10 +1648,18 @@ static int viafb_dfpl_proc_write(struct file *file,
1921 viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f); 1648 viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f);
1922 return count; 1649 return count;
1923} 1650}
1924static int viafb_vt1636_proc_read(char *buf, char **start, 1651
1925 off_t offset, int count, int *eof, void *data) 1652static const struct file_operations viafb_dfpl_proc_fops = {
1653 .owner = THIS_MODULE,
1654 .open = viafb_dfpl_proc_open,
1655 .read = seq_read,
1656 .llseek = seq_lseek,
1657 .release = single_release,
1658 .write = viafb_dfpl_proc_write,
1659};
1660
1661static int viafb_vt1636_proc_show(struct seq_file *m, void *v)
1926{ 1662{
1927 int len = 0;
1928 u8 vt1636_08 = 0, vt1636_09 = 0; 1663 u8 vt1636_08 = 0, vt1636_09 = 0;
1929 switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 1664 switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
1930 case VT1636_LVDS: 1665 case VT1636_LVDS:
@@ -1934,7 +1669,7 @@ static int viafb_vt1636_proc_read(char *buf, char **start,
1934 vt1636_09 = 1669 vt1636_09 =
1935 viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, 1670 viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info,
1936 &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f; 1671 &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f;
1937 len += sprintf(buf + len, "%x %x\n", vt1636_08, vt1636_09); 1672 seq_printf(m, "%x %x\n", vt1636_08, vt1636_09);
1938 break; 1673 break;
1939 default: 1674 default:
1940 break; 1675 break;
@@ -1947,16 +1682,21 @@ static int viafb_vt1636_proc_read(char *buf, char **start,
1947 vt1636_09 = 1682 vt1636_09 =
1948 viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, 1683 viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2,
1949 &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f; 1684 &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f;
1950 len += sprintf(buf + len, " %x %x\n", vt1636_08, vt1636_09); 1685 seq_printf(m, " %x %x\n", vt1636_08, vt1636_09);
1951 break; 1686 break;
1952 default: 1687 default:
1953 break; 1688 break;
1954 } 1689 }
1955 *eof = 1; /*Inform kernel end of data */ 1690 return 0;
1956 return len;
1957} 1691}
1958static int viafb_vt1636_proc_write(struct file *file, 1692
1959 const char __user *buffer, unsigned long count, void *data) 1693static int viafb_vt1636_proc_open(struct inode *inode, struct file *file)
1694{
1695 return single_open(file, viafb_vt1636_proc_show, NULL);
1696}
1697
1698static ssize_t viafb_vt1636_proc_write(struct file *file,
1699 const char __user *buffer, size_t count, loff_t *pos)
1960{ 1700{
1961 char buf[30], *value, *pbuf; 1701 char buf[30], *value, *pbuf;
1962 struct IODATA reg_val; 1702 struct IODATA reg_val;
@@ -2045,39 +1785,27 @@ static int viafb_vt1636_proc_write(struct file *file,
2045 return count; 1785 return count;
2046} 1786}
2047 1787
1788static const struct file_operations viafb_vt1636_proc_fops = {
1789 .owner = THIS_MODULE,
1790 .open = viafb_vt1636_proc_open,
1791 .read = seq_read,
1792 .llseek = seq_lseek,
1793 .release = single_release,
1794 .write = viafb_vt1636_proc_write,
1795};
1796
2048static void viafb_init_proc(struct proc_dir_entry **viafb_entry) 1797static void viafb_init_proc(struct proc_dir_entry **viafb_entry)
2049{ 1798{
2050 struct proc_dir_entry *entry;
2051 *viafb_entry = proc_mkdir("viafb", NULL); 1799 *viafb_entry = proc_mkdir("viafb", NULL);
2052 if (viafb_entry) { 1800 if (viafb_entry) {
2053 entry = create_proc_entry("dvp0", 0, *viafb_entry); 1801 proc_create("dvp0", 0, *viafb_entry, &viafb_dvp0_proc_fops);
2054 if (entry) { 1802 proc_create("dvp1", 0, *viafb_entry, &viafb_dvp1_proc_fops);
2055 entry->read_proc = viafb_dvp0_proc_read; 1803 proc_create("dfph", 0, *viafb_entry, &viafb_dfph_proc_fops);
2056 entry->write_proc = viafb_dvp0_proc_write; 1804 proc_create("dfpl", 0, *viafb_entry, &viafb_dfpl_proc_fops);
2057 }
2058 entry = create_proc_entry("dvp1", 0, *viafb_entry);
2059 if (entry) {
2060 entry->read_proc = viafb_dvp1_proc_read;
2061 entry->write_proc = viafb_dvp1_proc_write;
2062 }
2063 entry = create_proc_entry("dfph", 0, *viafb_entry);
2064 if (entry) {
2065 entry->read_proc = viafb_dfph_proc_read;
2066 entry->write_proc = viafb_dfph_proc_write;
2067 }
2068 entry = create_proc_entry("dfpl", 0, *viafb_entry);
2069 if (entry) {
2070 entry->read_proc = viafb_dfpl_proc_read;
2071 entry->write_proc = viafb_dfpl_proc_write;
2072 }
2073 if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info. 1805 if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info.
2074 lvds_chip_name || VT1636_LVDS == 1806 lvds_chip_name || VT1636_LVDS ==
2075 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { 1807 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
2076 entry = create_proc_entry("vt1636", 0, *viafb_entry); 1808 proc_create("vt1636", 0, *viafb_entry, &viafb_vt1636_proc_fops);
2077 if (entry) {
2078 entry->read_proc = viafb_vt1636_proc_read;
2079 entry->write_proc = viafb_vt1636_proc_write;
2080 }
2081 } 1809 }
2082 1810
2083 } 1811 }
@@ -2094,51 +1822,61 @@ static void viafb_remove_proc(struct proc_dir_entry *viafb_entry)
2094 remove_proc_entry("viafb", NULL); 1822 remove_proc_entry("viafb", NULL);
2095} 1823}
2096 1824
2097static int __devinit via_pci_probe(void) 1825static void parse_mode(const char *str, u32 *xres, u32 *yres)
2098{ 1826{
2099 unsigned long default_xres, default_yres; 1827 char *ptr;
2100 char *tmpc, *tmpm; 1828
2101 char *tmpc_sec, *tmpm_sec; 1829 *xres = simple_strtoul(str, &ptr, 10);
1830 if (ptr[0] != 'x')
1831 goto out_default;
1832
1833 *yres = simple_strtoul(&ptr[1], &ptr, 10);
1834 if (ptr[0])
1835 goto out_default;
1836
1837 return;
1838
1839out_default:
1840 printk(KERN_WARNING "viafb received invalid mode string: %s\n", str);
1841 *xres = 640;
1842 *yres = 480;
1843}
1844
1845static int __devinit via_pci_probe(struct pci_dev *pdev,
1846 const struct pci_device_id *ent)
1847{
1848 u32 default_xres, default_yres;
2102 int vmode_index; 1849 int vmode_index;
2103 u32 tmds_length, lvds_length, crt_length, chip_length, viafb_par_length; 1850 u32 viafb_par_length;
2104 1851
2105 DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); 1852 DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");
2106 1853
2107 viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8); 1854 viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8);
2108 tmds_length = ALIGN(sizeof(struct tmds_setting_information),
2109 BITS_PER_LONG/8);
2110 lvds_length = ALIGN(sizeof(struct lvds_setting_information),
2111 BITS_PER_LONG/8);
2112 crt_length = ALIGN(sizeof(struct lvds_setting_information),
2113 BITS_PER_LONG/8);
2114 chip_length = ALIGN(sizeof(struct chip_information), BITS_PER_LONG/8);
2115 1855
2116 /* Allocate fb_info and ***_par here, also including some other needed 1856 /* Allocate fb_info and ***_par here, also including some other needed
2117 * variables 1857 * variables
2118 */ 1858 */
2119 viafbinfo = framebuffer_alloc(viafb_par_length + 2 * lvds_length + 1859 viafbinfo = framebuffer_alloc(viafb_par_length +
2120 tmds_length + crt_length + chip_length, NULL); 1860 ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8),
1861 &pdev->dev);
2121 if (!viafbinfo) { 1862 if (!viafbinfo) {
2122 printk(KERN_ERR"Could not allocate memory for viafb_info.\n"); 1863 printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
2123 return -ENODEV; 1864 return -ENODEV;
2124 } 1865 }
2125 1866
2126 viaparinfo = (struct viafb_par *)viafbinfo->par; 1867 viaparinfo = (struct viafb_par *)viafbinfo->par;
2127 viaparinfo->tmds_setting_info = (struct tmds_setting_information *) 1868 viaparinfo->shared = viafbinfo->par + viafb_par_length;
2128 ((unsigned long)viaparinfo + viafb_par_length); 1869 viaparinfo->vram_addr = 0;
2129 viaparinfo->lvds_setting_info = (struct lvds_setting_information *) 1870 viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info;
2130 ((unsigned long)viaparinfo->tmds_setting_info + tmds_length); 1871 viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info;
2131 viaparinfo->lvds_setting_info2 = (struct lvds_setting_information *) 1872 viaparinfo->lvds_setting_info2 =
2132 ((unsigned long)viaparinfo->lvds_setting_info + lvds_length); 1873 &viaparinfo->shared->lvds_setting_info2;
2133 viaparinfo->crt_setting_info = (struct crt_setting_information *) 1874 viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info;
2134 ((unsigned long)viaparinfo->lvds_setting_info2 + lvds_length); 1875 viaparinfo->chip_info = &viaparinfo->shared->chip_info;
2135 viaparinfo->chip_info = (struct chip_information *)
2136 ((unsigned long)viaparinfo->crt_setting_info + crt_length);
2137 1876
2138 if (viafb_dual_fb) 1877 if (viafb_dual_fb)
2139 viafb_SAMM_ON = 1; 1878 viafb_SAMM_ON = 1;
2140 parse_active_dev(); 1879 parse_active_dev();
2141 parse_video_dev();
2142 parse_lcd_port(); 1880 parse_lcd_port();
2143 parse_dvi_port(); 1881 parse_dvi_port();
2144 1882
@@ -2149,32 +1887,32 @@ static int __devinit via_pci_probe(void)
2149 /* Set up I2C bus stuff */ 1887 /* Set up I2C bus stuff */
2150 viafb_create_i2c_bus(viaparinfo); 1888 viafb_create_i2c_bus(viaparinfo);
2151 1889
2152 viafb_init_chip_info(); 1890 viafb_init_chip_info(pdev, ent);
2153 viafb_get_fb_info(&viaparinfo->fbmem, &viaparinfo->memsize); 1891 viaparinfo->fbmem = pci_resource_start(pdev, 0);
1892 viaparinfo->memsize = viafb_get_fb_size_from_pci();
2154 viaparinfo->fbmem_free = viaparinfo->memsize; 1893 viaparinfo->fbmem_free = viaparinfo->memsize;
2155 viaparinfo->fbmem_used = 0; 1894 viaparinfo->fbmem_used = 0;
2156 viaparinfo->fbmem_virt = ioremap_nocache(viaparinfo->fbmem, 1895 viafbinfo->screen_base = ioremap_nocache(viaparinfo->fbmem,
2157 viaparinfo->memsize); 1896 viaparinfo->memsize);
2158 viafbinfo->screen_base = (char *)viaparinfo->fbmem_virt; 1897 if (!viafbinfo->screen_base) {
2159
2160 if (!viaparinfo->fbmem_virt) {
2161 printk(KERN_INFO "ioremap failed\n"); 1898 printk(KERN_INFO "ioremap failed\n");
2162 return -1; 1899 return -ENOMEM;
2163 } 1900 }
2164 1901
2165 viafb_get_mmio_info(&viaparinfo->mmio_base, &viaparinfo->mmio_len); 1902 viafbinfo->fix.mmio_start = pci_resource_start(pdev, 1);
2166 viaparinfo->io_virt = ioremap_nocache(viaparinfo->mmio_base, 1903 viafbinfo->fix.mmio_len = pci_resource_len(pdev, 1);
2167 viaparinfo->mmio_len);
2168
2169 viafbinfo->node = 0; 1904 viafbinfo->node = 0;
2170 viafbinfo->fbops = &viafb_ops; 1905 viafbinfo->fbops = &viafb_ops;
2171 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1906 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
2172 1907
2173 viafbinfo->pseudo_palette = pseudo_pal; 1908 viafbinfo->pseudo_palette = pseudo_pal;
2174 if (viafb_accel) { 1909 if (viafb_accel && !viafb_init_engine(viafbinfo)) {
2175 viafb_init_accel(); 1910 viafbinfo->flags |= FBINFO_HWACCEL_COPYAREA |
2176 viafb_init_2d_engine(); 1911 FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT;
2177 viafb_hw_cursor_init(); 1912 default_var.accel_flags = FB_ACCELF_TEXT;
1913 } else {
1914 viafbinfo->flags |= FBINFO_HWACCEL_DISABLED;
1915 default_var.accel_flags = 0;
2178 } 1916 }
2179 1917
2180 if (viafb_second_size && (viafb_second_size < 8)) { 1918 if (viafb_second_size && (viafb_second_size < 8)) {
@@ -2186,27 +1924,14 @@ static int __devinit via_pci_probe(void)
2186 viafb_second_size * 1024 * 1024; 1924 viafb_second_size * 1024 * 1024;
2187 } 1925 }
2188 1926
2189 viafb_FB_MM = viaparinfo->fbmem_virt; 1927 parse_mode(viafb_mode, &default_xres, &default_yres);
2190 tmpm = viafb_mode;
2191 tmpc = strsep(&tmpm, "x");
2192 strict_strtoul(tmpc, 0, &default_xres);
2193 strict_strtoul(tmpm, 0, &default_yres);
2194
2195 vmode_index = viafb_get_mode_index(default_xres, default_yres); 1928 vmode_index = viafb_get_mode_index(default_xres, default_yres);
2196 DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index); 1929 DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index);
2197 1930
2198 if (viafb_SAMM_ON == 1) { 1931 if (viafb_SAMM_ON == 1) {
2199 if (strcmp(viafb_mode, viafb_mode1)) { 1932 parse_mode(viafb_mode1, &viafb_second_xres,
2200 tmpm_sec = viafb_mode1; 1933 &viafb_second_yres);
2201 tmpc_sec = strsep(&tmpm_sec, "x"); 1934
2202 strict_strtoul(tmpc_sec, 0,
2203 (unsigned long *)&viafb_second_xres);
2204 strict_strtoul(tmpm_sec, 0,
2205 (unsigned long *)&viafb_second_yres);
2206 } else {
2207 viafb_second_xres = default_xres;
2208 viafb_second_yres = default_yres;
2209 }
2210 if (0 == viafb_second_virtual_xres) { 1935 if (0 == viafb_second_virtual_xres) {
2211 switch (viafb_second_xres) { 1936 switch (viafb_second_xres) {
2212 case 1400: 1937 case 1400:
@@ -2256,18 +1981,9 @@ static int __devinit via_pci_probe(void)
2256 default_var.lower_margin = 4; 1981 default_var.lower_margin = 4;
2257 default_var.hsync_len = default_var.left_margin; 1982 default_var.hsync_len = default_var.left_margin;
2258 default_var.vsync_len = 4; 1983 default_var.vsync_len = 4;
2259 default_var.accel_flags = 0;
2260
2261 if (viafb_accel) {
2262 viafbinfo->flags |=
2263 (FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
2264 FBINFO_HWACCEL_IMAGEBLIT);
2265 default_var.accel_flags |= FB_ACCELF_TEXT;
2266 } else
2267 viafbinfo->flags |= FBINFO_HWACCEL_DISABLED;
2268 1984
2269 if (viafb_dual_fb) { 1985 if (viafb_dual_fb) {
2270 viafbinfo1 = framebuffer_alloc(viafb_par_length, NULL); 1986 viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev);
2271 if (!viafbinfo1) { 1987 if (!viafbinfo1) {
2272 printk(KERN_ERR 1988 printk(KERN_ERR
2273 "allocate the second framebuffer struct error\n"); 1989 "allocate the second framebuffer struct error\n");
@@ -2276,11 +1992,10 @@ static int __devinit via_pci_probe(void)
2276 } 1992 }
2277 viaparinfo1 = viafbinfo1->par; 1993 viaparinfo1 = viafbinfo1->par;
2278 memcpy(viaparinfo1, viaparinfo, viafb_par_length); 1994 memcpy(viaparinfo1, viaparinfo, viafb_par_length);
1995 viaparinfo1->vram_addr = viafb_second_offset;
2279 viaparinfo1->memsize = viaparinfo->memsize - 1996 viaparinfo1->memsize = viaparinfo->memsize -
2280 viafb_second_offset; 1997 viafb_second_offset;
2281 viaparinfo->memsize = viafb_second_offset; 1998 viaparinfo->memsize = viafb_second_offset;
2282 viaparinfo1->fbmem_virt = viaparinfo->fbmem_virt +
2283 viafb_second_offset;
2284 viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset; 1999 viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset;
2285 2000
2286 viaparinfo1->fbmem_used = viaparinfo->fbmem_used; 2001 viaparinfo1->fbmem_used = viaparinfo->fbmem_used;
@@ -2288,20 +2003,13 @@ static int __devinit via_pci_probe(void)
2288 viaparinfo1->fbmem_used; 2003 viaparinfo1->fbmem_used;
2289 viaparinfo->fbmem_free = viaparinfo->memsize; 2004 viaparinfo->fbmem_free = viaparinfo->memsize;
2290 viaparinfo->fbmem_used = 0; 2005 viaparinfo->fbmem_used = 0;
2291 if (viafb_accel) {
2292 viaparinfo1->cursor_start =
2293 viaparinfo->cursor_start - viafb_second_offset;
2294 viaparinfo1->VQ_start = viaparinfo->VQ_start -
2295 viafb_second_offset;
2296 viaparinfo1->VQ_end = viaparinfo->VQ_end -
2297 viafb_second_offset;
2298 }
2299 2006
2007 viaparinfo->iga_path = IGA1;
2008 viaparinfo1->iga_path = IGA2;
2300 memcpy(viafbinfo1, viafbinfo, sizeof(struct fb_info)); 2009 memcpy(viafbinfo1, viafbinfo, sizeof(struct fb_info));
2010 viafbinfo1->par = viaparinfo1;
2301 viafbinfo1->screen_base = viafbinfo->screen_base + 2011 viafbinfo1->screen_base = viafbinfo->screen_base +
2302 viafb_second_offset; 2012 viafb_second_offset;
2303 viafbinfo1->fix.smem_start = viaparinfo1->fbmem;
2304 viafbinfo1->fix.smem_len = viaparinfo1->fbmem_free;
2305 2013
2306 default_var.xres = viafb_second_xres; 2014 default_var.xres = viafb_second_xres;
2307 default_var.yres = viafb_second_yres; 2015 default_var.yres = viafb_second_yres;
@@ -2323,15 +2031,17 @@ static int __devinit via_pci_probe(void)
2323 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1); 2031 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1);
2324 viafb_check_var(&default_var, viafbinfo1); 2032 viafb_check_var(&default_var, viafbinfo1);
2325 viafbinfo1->var = default_var; 2033 viafbinfo1->var = default_var;
2326 viafb_update_viafb_par(viafbinfo); 2034 viafb_update_fix(viafbinfo1);
2327 viafb_update_fix(&viafbinfo1->fix, viafbinfo1); 2035 viaparinfo1->depth = fb_get_color_depth(&viafbinfo1->var,
2036 &viafbinfo1->fix);
2328 } 2037 }
2329 2038
2330 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); 2039 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
2331 viafb_check_var(&default_var, viafbinfo); 2040 viafb_check_var(&default_var, viafbinfo);
2332 viafbinfo->var = default_var; 2041 viafbinfo->var = default_var;
2333 viafb_update_viafb_par(viafbinfo); 2042 viafb_update_fix(viafbinfo);
2334 viafb_update_fix(&viafbinfo->fix, viafbinfo); 2043 viaparinfo->depth = fb_get_color_depth(&viafbinfo->var,
2044 &viafbinfo->fix);
2335 default_var.activate = FB_ACTIVATE_NOW; 2045 default_var.activate = FB_ACTIVATE_NOW;
2336 fb_alloc_cmap(&viafbinfo->cmap, 256, 0); 2046 fb_alloc_cmap(&viafbinfo->cmap, 256, 0);
2337 2047
@@ -2353,20 +2063,20 @@ static int __devinit via_pci_probe(void)
2353 viafbinfo->node, viafbinfo->fix.id, default_var.xres, 2063 viafbinfo->node, viafbinfo->fix.id, default_var.xres,
2354 default_var.yres, default_var.bits_per_pixel); 2064 default_var.yres, default_var.bits_per_pixel);
2355 2065
2356 viafb_init_proc(&viaparinfo->proc_entry); 2066 viafb_init_proc(&viaparinfo->shared->proc_entry);
2357 viafb_init_dac(IGA2); 2067 viafb_init_dac(IGA2);
2358 return 0; 2068 return 0;
2359} 2069}
2360 2070
2361static void __devexit via_pci_remove(void) 2071static void __devexit via_pci_remove(struct pci_dev *pdev)
2362{ 2072{
2363 DEBUG_MSG(KERN_INFO "via_pci_remove!\n"); 2073 DEBUG_MSG(KERN_INFO "via_pci_remove!\n");
2364 fb_dealloc_cmap(&viafbinfo->cmap); 2074 fb_dealloc_cmap(&viafbinfo->cmap);
2365 unregister_framebuffer(viafbinfo); 2075 unregister_framebuffer(viafbinfo);
2366 if (viafb_dual_fb) 2076 if (viafb_dual_fb)
2367 unregister_framebuffer(viafbinfo1); 2077 unregister_framebuffer(viafbinfo1);
2368 iounmap((void *)viaparinfo->fbmem_virt); 2078 iounmap((void *)viafbinfo->screen_base);
2369 iounmap(viaparinfo->io_virt); 2079 iounmap(viaparinfo->shared->engine_mmio);
2370 2080
2371 viafb_delete_i2c_buss(viaparinfo); 2081 viafb_delete_i2c_buss(viaparinfo);
2372 2082
@@ -2374,7 +2084,7 @@ static void __devexit via_pci_remove(void)
2374 if (viafb_dual_fb) 2084 if (viafb_dual_fb)
2375 framebuffer_release(viafbinfo1); 2085 framebuffer_release(viafbinfo1);
2376 2086
2377 viafb_remove_proc(viaparinfo->proc_entry); 2087 viafb_remove_proc(viaparinfo->shared->proc_entry);
2378} 2088}
2379 2089
2380#ifndef MODULE 2090#ifndef MODULE
@@ -2441,8 +2151,6 @@ static int __init viafb_setup(char *options)
2441 else if (!strncmp(this_opt, "viafb_lcd_mode=", 15)) 2151 else if (!strncmp(this_opt, "viafb_lcd_mode=", 15))
2442 strict_strtoul(this_opt + 15, 0, 2152 strict_strtoul(this_opt + 15, 0,
2443 (unsigned long *)&viafb_lcd_mode); 2153 (unsigned long *)&viafb_lcd_mode);
2444 else if (!strncmp(this_opt, "viafb_video_dev=", 16))
2445 viafb_video_dev = kstrdup(this_opt + 16, GFP_KERNEL);
2446 else if (!strncmp(this_opt, "viafb_lcd_port=", 15)) 2154 else if (!strncmp(this_opt, "viafb_lcd_port=", 15))
2447 viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL); 2155 viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL);
2448 else if (!strncmp(this_opt, "viafb_dvi_port=", 15)) 2156 else if (!strncmp(this_opt, "viafb_dvi_port=", 15))
@@ -2452,6 +2160,40 @@ static int __init viafb_setup(char *options)
2452} 2160}
2453#endif 2161#endif
2454 2162
2163static struct pci_device_id viafb_pci_table[] __devinitdata = {
2164 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID),
2165 .driver_data = UNICHROME_CLE266 },
2166 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID),
2167 .driver_data = UNICHROME_PM800 },
2168 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
2169 .driver_data = UNICHROME_K400 },
2170 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID),
2171 .driver_data = UNICHROME_K800 },
2172 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID),
2173 .driver_data = UNICHROME_CN700 },
2174 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
2175 .driver_data = UNICHROME_K8M890 },
2176 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID),
2177 .driver_data = UNICHROME_CX700 },
2178 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
2179 .driver_data = UNICHROME_P4M900 },
2180 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID),
2181 .driver_data = UNICHROME_CN750 },
2182 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID),
2183 .driver_data = UNICHROME_VX800 },
2184 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
2185 .driver_data = UNICHROME_VX855 },
2186 { }
2187};
2188MODULE_DEVICE_TABLE(pci, viafb_pci_table);
2189
2190static struct pci_driver viafb_driver = {
2191 .name = "viafb",
2192 .id_table = viafb_pci_table,
2193 .probe = via_pci_probe,
2194 .remove = __devexit_p(via_pci_remove),
2195};
2196
2455static int __init viafb_init(void) 2197static int __init viafb_init(void)
2456{ 2198{
2457#ifndef MODULE 2199#ifndef MODULE
@@ -2463,13 +2205,13 @@ static int __init viafb_init(void)
2463 printk(KERN_INFO 2205 printk(KERN_INFO
2464 "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", 2206 "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n",
2465 VERSION_MAJOR, VERSION_MINOR); 2207 VERSION_MAJOR, VERSION_MINOR);
2466 return via_pci_probe(); 2208 return pci_register_driver(&viafb_driver);
2467} 2209}
2468 2210
2469static void __exit viafb_exit(void) 2211static void __exit viafb_exit(void)
2470{ 2212{
2471 DEBUG_MSG(KERN_INFO "viafb_exit!\n"); 2213 DEBUG_MSG(KERN_INFO "viafb_exit!\n");
2472 via_pci_remove(); 2214 pci_unregister_driver(&viafb_driver);
2473} 2215}
2474 2216
2475static struct fb_ops viafb_ops = { 2217static struct fb_ops viafb_ops = {
@@ -2494,82 +2236,79 @@ module_init(viafb_init);
2494module_exit(viafb_exit); 2236module_exit(viafb_exit);
2495 2237
2496#ifdef MODULE 2238#ifdef MODULE
2497module_param(viafb_memsize, int, 0); 2239module_param(viafb_memsize, int, S_IRUSR);
2498 2240
2499module_param(viafb_mode, charp, 0); 2241module_param(viafb_mode, charp, S_IRUSR);
2500MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)"); 2242MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)");
2501 2243
2502module_param(viafb_mode1, charp, 0); 2244module_param(viafb_mode1, charp, S_IRUSR);
2503MODULE_PARM_DESC(viafb_mode1, "Set resolution (default=640x480)"); 2245MODULE_PARM_DESC(viafb_mode1, "Set resolution (default=640x480)");
2504 2246
2505module_param(viafb_bpp, int, 0); 2247module_param(viafb_bpp, int, S_IRUSR);
2506MODULE_PARM_DESC(viafb_bpp, "Set color depth (default=32bpp)"); 2248MODULE_PARM_DESC(viafb_bpp, "Set color depth (default=32bpp)");
2507 2249
2508module_param(viafb_bpp1, int, 0); 2250module_param(viafb_bpp1, int, S_IRUSR);
2509MODULE_PARM_DESC(viafb_bpp1, "Set color depth (default=32bpp)"); 2251MODULE_PARM_DESC(viafb_bpp1, "Set color depth (default=32bpp)");
2510 2252
2511module_param(viafb_refresh, int, 0); 2253module_param(viafb_refresh, int, S_IRUSR);
2512MODULE_PARM_DESC(viafb_refresh, 2254MODULE_PARM_DESC(viafb_refresh,
2513 "Set CRT viafb_refresh rate (default = 60)"); 2255 "Set CRT viafb_refresh rate (default = 60)");
2514 2256
2515module_param(viafb_refresh1, int, 0); 2257module_param(viafb_refresh1, int, S_IRUSR);
2516MODULE_PARM_DESC(viafb_refresh1, 2258MODULE_PARM_DESC(viafb_refresh1,
2517 "Set CRT refresh rate (default = 60)"); 2259 "Set CRT refresh rate (default = 60)");
2518 2260
2519module_param(viafb_lcd_panel_id, int, 0); 2261module_param(viafb_lcd_panel_id, int, S_IRUSR);
2520MODULE_PARM_DESC(viafb_lcd_panel_id, 2262MODULE_PARM_DESC(viafb_lcd_panel_id,
2521 "Set Flat Panel type(Default=1024x768)"); 2263 "Set Flat Panel type(Default=1024x768)");
2522 2264
2523module_param(viafb_lcd_dsp_method, int, 0); 2265module_param(viafb_lcd_dsp_method, int, S_IRUSR);
2524MODULE_PARM_DESC(viafb_lcd_dsp_method, 2266MODULE_PARM_DESC(viafb_lcd_dsp_method,
2525 "Set Flat Panel display scaling method.(Default=Expandsion)"); 2267 "Set Flat Panel display scaling method.(Default=Expandsion)");
2526 2268
2527module_param(viafb_SAMM_ON, int, 0); 2269module_param(viafb_SAMM_ON, int, S_IRUSR);
2528MODULE_PARM_DESC(viafb_SAMM_ON, 2270MODULE_PARM_DESC(viafb_SAMM_ON,
2529 "Turn on/off flag of SAMM(Default=OFF)"); 2271 "Turn on/off flag of SAMM(Default=OFF)");
2530 2272
2531module_param(viafb_accel, int, 0); 2273module_param(viafb_accel, int, S_IRUSR);
2532MODULE_PARM_DESC(viafb_accel, 2274MODULE_PARM_DESC(viafb_accel,
2533 "Set 2D Hardware Acceleration.(Default = OFF)"); 2275 "Set 2D Hardware Acceleration: 0 = OFF, 1 = ON (default)");
2534 2276
2535module_param(viafb_active_dev, charp, 0); 2277module_param(viafb_active_dev, charp, S_IRUSR);
2536MODULE_PARM_DESC(viafb_active_dev, "Specify active devices."); 2278MODULE_PARM_DESC(viafb_active_dev, "Specify active devices.");
2537 2279
2538module_param(viafb_display_hardware_layout, int, 0); 2280module_param(viafb_display_hardware_layout, int, S_IRUSR);
2539MODULE_PARM_DESC(viafb_display_hardware_layout, 2281MODULE_PARM_DESC(viafb_display_hardware_layout,
2540 "Display Hardware Layout (LCD Only, DVI Only...,etc)"); 2282 "Display Hardware Layout (LCD Only, DVI Only...,etc)");
2541 2283
2542module_param(viafb_second_size, int, 0); 2284module_param(viafb_second_size, int, S_IRUSR);
2543MODULE_PARM_DESC(viafb_second_size, 2285MODULE_PARM_DESC(viafb_second_size,
2544 "Set secondary device memory size"); 2286 "Set secondary device memory size");
2545 2287
2546module_param(viafb_dual_fb, int, 0); 2288module_param(viafb_dual_fb, int, S_IRUSR);
2547MODULE_PARM_DESC(viafb_dual_fb, 2289MODULE_PARM_DESC(viafb_dual_fb,
2548 "Turn on/off flag of dual framebuffer devices.(Default = OFF)"); 2290 "Turn on/off flag of dual framebuffer devices.(Default = OFF)");
2549 2291
2550module_param(viafb_platform_epia_dvi, int, 0); 2292module_param(viafb_platform_epia_dvi, int, S_IRUSR);
2551MODULE_PARM_DESC(viafb_platform_epia_dvi, 2293MODULE_PARM_DESC(viafb_platform_epia_dvi,
2552 "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)"); 2294 "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)");
2553 2295
2554module_param(viafb_device_lcd_dualedge, int, 0); 2296module_param(viafb_device_lcd_dualedge, int, S_IRUSR);
2555MODULE_PARM_DESC(viafb_device_lcd_dualedge, 2297MODULE_PARM_DESC(viafb_device_lcd_dualedge,
2556 "Turn on/off flag of dual edge panel.(Default = OFF)"); 2298 "Turn on/off flag of dual edge panel.(Default = OFF)");
2557 2299
2558module_param(viafb_bus_width, int, 0); 2300module_param(viafb_bus_width, int, S_IRUSR);
2559MODULE_PARM_DESC(viafb_bus_width, 2301MODULE_PARM_DESC(viafb_bus_width,
2560 "Set bus width of panel.(Default = 12)"); 2302 "Set bus width of panel.(Default = 12)");
2561 2303
2562module_param(viafb_lcd_mode, int, 0); 2304module_param(viafb_lcd_mode, int, S_IRUSR);
2563MODULE_PARM_DESC(viafb_lcd_mode, 2305MODULE_PARM_DESC(viafb_lcd_mode,
2564 "Set Flat Panel mode(Default=OPENLDI)"); 2306 "Set Flat Panel mode(Default=OPENLDI)");
2565 2307
2566module_param(viafb_video_dev, charp, 0); 2308module_param(viafb_lcd_port, charp, S_IRUSR);
2567MODULE_PARM_DESC(viafb_video_dev, "Specify video devices.");
2568
2569module_param(viafb_lcd_port, charp, 0);
2570MODULE_PARM_DESC(viafb_lcd_port, "Specify LCD output port."); 2309MODULE_PARM_DESC(viafb_lcd_port, "Specify LCD output port.");
2571 2310
2572module_param(viafb_dvi_port, charp, 0); 2311module_param(viafb_dvi_port, charp, S_IRUSR);
2573MODULE_PARM_DESC(viafb_dvi_port, "Specify DVI output port."); 2312MODULE_PARM_DESC(viafb_dvi_port, "Specify DVI output port.");
2574 2313
2575MODULE_LICENSE("GPL"); 2314MODULE_LICENSE("GPL");
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index 227b000feb38..0c94d2441922 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -37,51 +37,50 @@
37#define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */ 37#define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */
38#define VERSION_MINOR 4 38#define VERSION_MINOR 4
39 39
40struct viafb_shared {
41 struct proc_dir_entry *proc_entry; /*viafb proc entry */
42
43 /* I2C stuff */
44 struct via_i2c_stuff i2c_stuff;
45
46 /* All the information will be needed to set engine */
47 struct tmds_setting_information tmds_setting_info;
48 struct crt_setting_information crt_setting_info;
49 struct lvds_setting_information lvds_setting_info;
50 struct lvds_setting_information lvds_setting_info2;
51 struct chip_information chip_info;
52
53 /* hardware acceleration stuff */
54 void __iomem *engine_mmio;
55 u32 cursor_vram_addr;
56 u32 vq_vram_addr; /* virtual queue address in video ram */
57 int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height,
58 u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
59 u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
60 u32 fg_color, u32 bg_color, u8 fill_rop);
61};
62
40struct viafb_par { 63struct viafb_par {
41 int bpp; 64 u8 depth;
42 int hres; 65 u32 vram_addr;
43 int vres; 66
44 int linelength;
45 u32 xoffset;
46 u32 yoffset;
47
48 void __iomem *fbmem_virt; /*framebuffer virtual memory address */
49 void __iomem *io_virt; /*iospace virtual memory address */
50 unsigned int fbmem; /*framebuffer physical memory address */ 67 unsigned int fbmem; /*framebuffer physical memory address */
51 unsigned int memsize; /*size of fbmem */ 68 unsigned int memsize; /*size of fbmem */
52 unsigned int io; /*io space address */
53 unsigned long mmio_base; /*mmio base address */
54 unsigned long mmio_len; /*mmio base length */
55 u32 fbmem_free; /* Free FB memory */ 69 u32 fbmem_free; /* Free FB memory */
56 u32 fbmem_used; /* Use FB memory size */ 70 u32 fbmem_used; /* Use FB memory size */
57 u32 cursor_start; /* Cursor Start Address */
58 u32 VQ_start; /* Virtual Queue Start Address */
59 u32 VQ_end; /* Virtual Queue End Address */
60 u32 iga_path; 71 u32 iga_path;
61 struct proc_dir_entry *proc_entry; /*viafb proc entry */
62 u8 duoview; /*Is working in duoview mode? */
63 72
64 /* I2C stuff */ 73 struct viafb_shared *shared;
65 struct via_i2c_stuff i2c_stuff;
66 74
67 /* All the information will be needed to set engine */ 75 /* All the information will be needed to set engine */
76 /* depreciated, use the ones in shared directly */
68 struct tmds_setting_information *tmds_setting_info; 77 struct tmds_setting_information *tmds_setting_info;
69 struct crt_setting_information *crt_setting_info; 78 struct crt_setting_information *crt_setting_info;
70 struct lvds_setting_information *lvds_setting_info; 79 struct lvds_setting_information *lvds_setting_info;
71 struct lvds_setting_information *lvds_setting_info2; 80 struct lvds_setting_information *lvds_setting_info2;
72 struct chip_information *chip_info; 81 struct chip_information *chip_info;
73
74 /* some information related to video playing */
75 int video_on_crt;
76 int video_on_dvi;
77 int video_on_lcd;
78
79};
80struct viafb_modeinfo {
81 u32 xres;
82 u32 yres;
83 int mode_index;
84}; 82};
83
85extern unsigned int viafb_second_virtual_yres; 84extern unsigned int viafb_second_virtual_yres;
86extern unsigned int viafb_second_virtual_xres; 85extern unsigned int viafb_second_virtual_xres;
87extern unsigned int viafb_second_offset; 86extern unsigned int viafb_second_offset;
@@ -91,14 +90,12 @@ extern int viafb_dual_fb;
91extern int viafb_LCD2_ON; 90extern int viafb_LCD2_ON;
92extern int viafb_LCD_ON; 91extern int viafb_LCD_ON;
93extern int viafb_DVI_ON; 92extern int viafb_DVI_ON;
94extern int viafb_accel;
95extern int viafb_hotplug; 93extern int viafb_hotplug;
96extern int viafb_memsize; 94extern int viafb_memsize;
97 95
98extern int strict_strtoul(const char *cp, unsigned int base, 96extern int strict_strtoul(const char *cp, unsigned int base,
99 unsigned long *res); 97 unsigned long *res);
100 98
101void viafb_memory_pitch_patch(struct fb_info *info);
102void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 99void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
103 int mode_index); 100 int mode_index);
104int viafb_get_mode_index(int hres, int vres); 101int viafb_get_mode_index(int hres, int vres);
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
index 6dcf583a837d..b74f8a67923c 100644
--- a/drivers/video/via/viamode.c
+++ b/drivers/video/via/viamode.c
@@ -100,12 +100,8 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
100{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ 100{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
101{VIACR, CR32, 0xFF, 0x00}, 101{VIACR, CR32, 0xFF, 0x00},
102{VIACR, CR33, 0xFF, 0x00}, 102{VIACR, CR33, 0xFF, 0x00},
103{VIACR, CR34, 0xFF, 0x00},
104{VIACR, CR35, 0xFF, 0x00}, 103{VIACR, CR35, 0xFF, 0x00},
105{VIACR, CR36, 0x08, 0x00}, 104{VIACR, CR36, 0x08, 0x00},
106{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
107{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
108{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
109{VIACR, CR69, 0xFF, 0x00}, 105{VIACR, CR69, 0xFF, 0x00},
110{VIACR, CR6A, 0xFF, 0x40}, 106{VIACR, CR6A, 0xFF, 0x40},
111{VIACR, CR6B, 0xFF, 0x00}, 107{VIACR, CR6B, 0xFF, 0x00},
@@ -159,16 +155,12 @@ struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
159{VIASR, CR30, 0xFF, 0x04}, 155{VIASR, CR30, 0xFF, 0x04},
160{VIACR, CR32, 0xFF, 0x00}, 156{VIACR, CR32, 0xFF, 0x00},
161{VIACR, CR33, 0x7F, 0x00}, 157{VIACR, CR33, 0x7F, 0x00},
162{VIACR, CR34, 0xFF, 0x00},
163{VIACR, CR35, 0xFF, 0x00}, 158{VIACR, CR35, 0xFF, 0x00},
164{VIACR, CR36, 0xFF, 0x31}, 159{VIACR, CR36, 0xFF, 0x31},
165{VIACR, CR41, 0xFF, 0x80}, 160{VIACR, CR41, 0xFF, 0x80},
166{VIACR, CR42, 0xFF, 0x00}, 161{VIACR, CR42, 0xFF, 0x00},
167{VIACR, CR55, 0x80, 0x00}, 162{VIACR, CR55, 0x80, 0x00},
168{VIACR, CR5D, 0x80, 0x00}, /*Horizontal Retrace Start bit[11] should be 0*/ 163{VIACR, CR5D, 0x80, 0x00}, /*Horizontal Retrace Start bit[11] should be 0*/
169{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
170{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
171{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
172{VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ 164{VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */
173{VIACR, CR69, 0xFF, 0x00}, 165{VIACR, CR69, 0xFF, 0x00},
174{VIACR, CR6A, 0xFD, 0x40}, 166{VIACR, CR6A, 0xFD, 0x40},
@@ -233,9 +225,6 @@ struct io_reg KM400_ModeXregs[] = {
233 {VIACR, CR55, 0x80, 0x00}, 225 {VIACR, CR55, 0x80, 0x00},
234 {VIACR, CR5D, 0x80, 0x00}, 226 {VIACR, CR5D, 0x80, 0x00},
235 {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */ 227 {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */
236 {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
237 {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
238 {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
239 {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ 228 {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */
240 {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */ 229 {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */
241 {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ 230 {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
@@ -285,14 +274,9 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
285{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ 274{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
286{VIACR, CR32, 0xFF, 0x00}, 275{VIACR, CR32, 0xFF, 0x00},
287{VIACR, CR33, 0xFF, 0x00}, 276{VIACR, CR33, 0xFF, 0x00},
288{VIACR, CR34, 0xFF, 0x00},
289{VIACR, CR35, 0xFF, 0x00}, 277{VIACR, CR35, 0xFF, 0x00},
290{VIACR, CR36, 0x08, 0x00}, 278{VIACR, CR36, 0x08, 0x00},
291{VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */ 279{VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */
292{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
293{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
294{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
295{VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */
296{VIACR, CR69, 0xFF, 0x00}, 280{VIACR, CR69, 0xFF, 0x00},
297{VIACR, CR6A, 0xFF, 0x40}, 281{VIACR, CR6A, 0xFF, 0x40},
298{VIACR, CR6B, 0xFF, 0x00}, 282{VIACR, CR6B, 0xFF, 0x00},
@@ -325,69 +309,61 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
325{VIACR, CR96, 0xFF, 0x00}, 309{VIACR, CR96, 0xFF, 0x00},
326{VIACR, CR97, 0xFF, 0x00}, 310{VIACR, CR97, 0xFF, 0x00},
327{VIACR, CR99, 0xFF, 0x00}, 311{VIACR, CR99, 0xFF, 0x00},
328{VIACR, CR9B, 0xFF, 0x00}, 312{VIACR, CR9B, 0xFF, 0x00}
329{VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */
330}; 313};
331 314
332/* For VT3353: Common Setting for Video Mode */ 315struct io_reg VX855_ModeXregs[] = {
333struct io_reg VX800_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, 316{VIASR, SR10, 0xFF, 0x01},
334{VIASR, SR15, 0x02, 0x02}, 317{VIASR, SR15, 0x02, 0x02},
335{VIASR, SR16, 0xBF, 0x08}, 318{VIASR, SR16, 0xBF, 0x08},
336{VIASR, SR17, 0xFF, 0x1F}, 319{VIASR, SR17, 0xFF, 0x1F},
337{VIASR, SR18, 0xFF, 0x4E}, 320{VIASR, SR18, 0xFF, 0x4E},
338{VIASR, SR1A, 0xFB, 0x08}, 321{VIASR, SR1A, 0xFB, 0x08},
339{VIASR, SR1B, 0xFF, 0xF0}, 322{VIASR, SR1B, 0xFF, 0xF0},
340{VIASR, SR1E, 0xFF, 0x01}, 323{VIASR, SR1E, 0x07, 0x01},
341{VIASR, SR2A, 0xFF, 0x00}, 324{VIASR, SR2A, 0xF0, 0x00},
325{VIASR, SR58, 0xFF, 0x00},
326{VIASR, SR59, 0xFF, 0x00},
342{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ 327{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */
328{VIACR, CR09, 0xFF, 0x00}, /* Initial CR09=0*/
329{VIACR, CR11, 0x8F, 0x00}, /* IGA1 initial Vertical end */
330{VIACR, CR17, 0x7F, 0x00}, /* IGA1 CRT Mode control init */
343{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ 331{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
344{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ 332{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
345{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ 333{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
346{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ 334{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
347{VIACR, CR32, 0xFF, 0x00}, 335{VIACR, CR32, 0xFF, 0x00},
348{VIACR, CR33, 0xFF, 0x00}, 336{VIACR, CR33, 0x7F, 0x00},
349{VIACR, CR34, 0xFF, 0x00},
350{VIACR, CR35, 0xFF, 0x00}, 337{VIACR, CR35, 0xFF, 0x00},
351{VIACR, CR36, 0x08, 0x00}, 338{VIACR, CR36, 0x08, 0x00},
352{VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */
353{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
354{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
355{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
356{VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */
357{VIACR, CR69, 0xFF, 0x00}, 339{VIACR, CR69, 0xFF, 0x00},
358{VIACR, CR6A, 0xFF, 0x40}, 340{VIACR, CR6A, 0xFD, 0x60},
359{VIACR, CR6B, 0xFF, 0x00}, 341{VIACR, CR6B, 0xFF, 0x00},
360{VIACR, CR6C, 0xFF, 0x00}, 342{VIACR, CR6C, 0xFF, 0x00},
361{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ 343{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
362{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ 344{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
363{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ 345{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
364{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ 346{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
365{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ 347{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
366{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ 348{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
367{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ 349{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
368{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ 350{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
369{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ 351{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
370{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ 352{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
371{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ 353{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
372{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ 354{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
373{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ 355{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
374{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ 356{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
375{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 357{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
376{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 358{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
377{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ 359{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
378{VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */ 360{VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */
379{VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */ 361{VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */
380{VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */
381{VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */
382{VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */
383{VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */
384{VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */
385{VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */
386{VIACR, CR96, 0xFF, 0x00}, 362{VIACR, CR96, 0xFF, 0x00},
387{VIACR, CR97, 0xFF, 0x00}, 363{VIACR, CR97, 0xFF, 0x00},
388{VIACR, CR99, 0xFF, 0x00}, 364{VIACR, CR99, 0xFF, 0x00},
389{VIACR, CR9B, 0xFF, 0x00}, 365{VIACR, CR9B, 0xFF, 0x00},
390{VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */ 366{VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */
391}; 367};
392 368
393/* Video Mode Table */ 369/* Video Mode Table */
@@ -401,7 +377,6 @@ struct io_reg CLE266_ModeXregs[] = { {VIASR, SR1E, 0xF0, 0x00},
401{VIASR, SR1A, 0xFB, 0x08}, 377{VIASR, SR1A, 0xFB, 0x08},
402 378
403{VIACR, CR32, 0xFF, 0x00}, 379{VIACR, CR32, 0xFF, 0x00},
404{VIACR, CR34, 0xFF, 0x00},
405{VIACR, CR35, 0xFF, 0x00}, 380{VIACR, CR35, 0xFF, 0x00},
406{VIACR, CR36, 0x08, 0x00}, 381{VIACR, CR36, 0x08, 0x00},
407{VIACR, CR6A, 0xFF, 0x80}, 382{VIACR, CR6A, 0xFF, 0x80},
@@ -1084,3 +1059,14 @@ struct VideoModeTable CEA_HDMI_Modes[] = {
1084 {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)}, 1059 {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)},
1085 {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} 1060 {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
1086}; 1061};
1062
1063int NUM_TOTAL_RES_MAP_REFRESH = ARRAY_SIZE(res_map_refresh_tbl);
1064int NUM_TOTAL_CEA_MODES = ARRAY_SIZE(CEA_HDMI_Modes);
1065int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs);
1066int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs);
1067int NUM_TOTAL_KM400_ModeXregs = ARRAY_SIZE(KM400_ModeXregs);
1068int NUM_TOTAL_CX700_ModeXregs = ARRAY_SIZE(CX700_ModeXregs);
1069int NUM_TOTAL_VX855_ModeXregs = ARRAY_SIZE(VX855_ModeXregs);
1070int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs);
1071int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table);
1072int NUM_TOTAL_MODETABLE = ARRAY_SIZE(CLE266Modes);
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h
index 1a5de50a23a2..a9d6554fabdf 100644
--- a/drivers/video/via/viamode.h
+++ b/drivers/video/via/viamode.h
@@ -50,128 +50,35 @@ struct res_map_refresh {
50 int vmode_refresh; 50 int vmode_refresh;
51}; 51};
52 52
53#define NUM_TOTAL_RES_MAP_REFRESH ARRAY_SIZE(res_map_refresh_tbl) 53extern int NUM_TOTAL_RES_MAP_REFRESH;
54#define NUM_TOTAL_CEA_MODES ARRAY_SIZE(CEA_HDMI_Modes) 54extern int NUM_TOTAL_CEA_MODES;
55#define NUM_TOTAL_CN400_ModeXregs ARRAY_SIZE(CN400_ModeXregs) 55extern int NUM_TOTAL_CN400_ModeXregs;
56#define NUM_TOTAL_CN700_ModeXregs ARRAY_SIZE(CN700_ModeXregs) 56extern int NUM_TOTAL_CN700_ModeXregs;
57#define NUM_TOTAL_KM400_ModeXregs ARRAY_SIZE(KM400_ModeXregs) 57extern int NUM_TOTAL_KM400_ModeXregs;
58#define NUM_TOTAL_CX700_ModeXregs ARRAY_SIZE(CX700_ModeXregs) 58extern int NUM_TOTAL_CX700_ModeXregs;
59#define NUM_TOTAL_VX800_ModeXregs ARRAY_SIZE(VX800_ModeXregs) 59extern int NUM_TOTAL_VX855_ModeXregs;
60#define NUM_TOTAL_CLE266_ModeXregs ARRAY_SIZE(CLE266_ModeXregs) 60extern int NUM_TOTAL_CLE266_ModeXregs;
61#define NUM_TOTAL_PATCH_MODE ARRAY_SIZE(res_patch_table) 61extern int NUM_TOTAL_PATCH_MODE;
62#define NUM_TOTAL_MODETABLE ARRAY_SIZE(CLE266Modes) 62extern int NUM_TOTAL_MODETABLE;
63 63
64/********************/ 64/********************/
65/* Mode Table */ 65/* Mode Table */
66/********************/ 66/********************/
67 67
68/* 480x640 */ 68extern struct VideoModeTable CLE266Modes[];
69extern struct crt_mode_table CRTM480x640[1]; 69extern struct crt_mode_table CEAM1280x720[];
70/* 640x480*/ 70extern struct crt_mode_table CEAM1920x1080[];
71extern struct crt_mode_table CRTM640x480[5]; 71extern struct VideoModeTable CEA_HDMI_Modes[];
72/*720x480 (GTF)*/
73extern struct crt_mode_table CRTM720x480[1];
74/*720x576 (GTF)*/
75extern struct crt_mode_table CRTM720x576[1];
76/* 800x480 (CVT) */
77extern struct crt_mode_table CRTM800x480[1];
78/* 800x600*/
79extern struct crt_mode_table CRTM800x600[5];
80/* 848x480 (CVT) */
81extern struct crt_mode_table CRTM848x480[1];
82/*856x480 (GTF) convert to 852x480*/
83extern struct crt_mode_table CRTM852x480[1];
84/*1024x512 (GTF)*/
85extern struct crt_mode_table CRTM1024x512[1];
86/* 1024x600*/
87extern struct crt_mode_table CRTM1024x600[1];
88/* 1024x768*/
89extern struct crt_mode_table CRTM1024x768[4];
90/* 1152x864*/
91extern struct crt_mode_table CRTM1152x864[1];
92/* 1280x720 (HDMI 720P)*/
93extern struct crt_mode_table CRTM1280x720[2];
94/*1280x768 (GTF)*/
95extern struct crt_mode_table CRTM1280x768[2];
96/* 1280x800 (CVT) */
97extern struct crt_mode_table CRTM1280x800[1];
98/*1280x960*/
99extern struct crt_mode_table CRTM1280x960[1];
100/* 1280x1024*/
101extern struct crt_mode_table CRTM1280x1024[3];
102/* 1368x768 (GTF) */
103extern struct crt_mode_table CRTM1368x768[1];
104/*1440x1050 (GTF)*/
105extern struct crt_mode_table CRTM1440x1050[1];
106/* 1600x1200*/
107extern struct crt_mode_table CRTM1600x1200[2];
108/* 1680x1050 (CVT) */
109extern struct crt_mode_table CRTM1680x1050[2];
110/* 1680x1050 (CVT Reduce Blanking) */
111extern struct crt_mode_table CRTM1680x1050_RB[1];
112/* 1920x1080 (CVT)*/
113extern struct crt_mode_table CRTM1920x1080[1];
114/* 1920x1080 (CVT with Reduce Blanking) */
115extern struct crt_mode_table CRTM1920x1080_RB[1];
116/* 1920x1440*/
117extern struct crt_mode_table CRTM1920x1440[2];
118/* 1400x1050 (CVT) */
119extern struct crt_mode_table CRTM1400x1050[2];
120/* 1400x1050 (CVT Reduce Blanking) */
121extern struct crt_mode_table CRTM1400x1050_RB[1];
122/* 960x600 (CVT) */
123extern struct crt_mode_table CRTM960x600[1];
124/* 1000x600 (GTF) */
125extern struct crt_mode_table CRTM1000x600[1];
126/* 1024x576 (GTF) */
127extern struct crt_mode_table CRTM1024x576[1];
128/* 1088x612 (CVT) */
129extern struct crt_mode_table CRTM1088x612[1];
130/* 1152x720 (CVT) */
131extern struct crt_mode_table CRTM1152x720[1];
132/* 1200x720 (GTF) */
133extern struct crt_mode_table CRTM1200x720[1];
134/* 1280x600 (GTF) */
135extern struct crt_mode_table CRTM1280x600[1];
136/* 1360x768 (CVT) */
137extern struct crt_mode_table CRTM1360x768[1];
138/* 1360x768 (CVT Reduce Blanking) */
139extern struct crt_mode_table CRTM1360x768_RB[1];
140/* 1366x768 (GTF) */
141extern struct crt_mode_table CRTM1366x768[2];
142/* 1440x900 (CVT) */
143extern struct crt_mode_table CRTM1440x900[2];
144/* 1440x900 (CVT Reduce Blanking) */
145extern struct crt_mode_table CRTM1440x900_RB[1];
146/* 1600x900 (CVT) */
147extern struct crt_mode_table CRTM1600x900[1];
148/* 1600x900 (CVT Reduce Blanking) */
149extern struct crt_mode_table CRTM1600x900_RB[1];
150/* 1600x1024 (GTF) */
151extern struct crt_mode_table CRTM1600x1024[1];
152/* 1792x1344 (DMT) */
153extern struct crt_mode_table CRTM1792x1344[1];
154/* 1856x1392 (DMT) */
155extern struct crt_mode_table CRTM1856x1392[1];
156/* 1920x1200 (CVT) */
157extern struct crt_mode_table CRTM1920x1200[1];
158/* 1920x1200 (CVT with Reduce Blanking) */
159extern struct crt_mode_table CRTM1920x1200_RB[1];
160/* 2048x1536 (CVT) */
161extern struct crt_mode_table CRTM2048x1536[1];
162extern struct VideoModeTable CLE266Modes[47];
163extern struct crt_mode_table CEAM1280x720[1];
164extern struct crt_mode_table CEAM1920x1080[1];
165extern struct VideoModeTable CEA_HDMI_Modes[2];
166 72
167extern struct res_map_refresh res_map_refresh_tbl[61]; 73extern struct res_map_refresh res_map_refresh_tbl[];
168extern struct io_reg CN400_ModeXregs[52]; 74extern struct io_reg CN400_ModeXregs[];
169extern struct io_reg CN700_ModeXregs[66]; 75extern struct io_reg CN700_ModeXregs[];
170extern struct io_reg KM400_ModeXregs[55]; 76extern struct io_reg KM400_ModeXregs[];
171extern struct io_reg CX700_ModeXregs[58]; 77extern struct io_reg CX700_ModeXregs[];
172extern struct io_reg VX800_ModeXregs[58]; 78extern struct io_reg VX800_ModeXregs[];
173extern struct io_reg CLE266_ModeXregs[32]; 79extern struct io_reg VX855_ModeXregs[];
174extern struct io_reg PM1024x768[2]; 80extern struct io_reg CLE266_ModeXregs[];
175extern struct patch_table res_patch_table[1]; 81extern struct io_reg PM1024x768[];
82extern struct patch_table res_patch_table[];
176extern struct VPITTable VPIT; 83extern struct VPITTable VPIT;
177#endif /* __VIAMODE_H__ */ 84#endif /* __VIAMODE_H__ */
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c
index 322a9f993550..a6b37494e79a 100644
--- a/drivers/video/via/vt1636.c
+++ b/drivers/video/via/vt1636.c
@@ -27,7 +27,7 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
27{ 27{
28 u8 data; 28 u8 data;
29 29
30 viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; 30 viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
31 viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data); 31 viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data);
32 32
33 return data; 33 return data;
@@ -39,7 +39,7 @@ void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
39{ 39{
40 int index, data; 40 int index, data;
41 41
42 viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; 42 viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
43 43
44 index = io_data.Index; 44 index = io_data.Index;
45 data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, 45 data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,