Commit ed5a35acbb48d512332a53565e6341c65eecfa29

Authored by Russell King
1 parent e8b8f5ef90

VIDEO: cyberpro: pci_request_regions needs a persistent name

Don't pass a name pointer from the kernel stack, it will not survive
and will result in corrupted /proc/iomem output.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Showing 1 changed file with 6 additions and 6 deletions Inline Diff

drivers/video/cyber2000fb.c
1 /* 1 /*
2 * linux/drivers/video/cyber2000fb.c 2 * linux/drivers/video/cyber2000fb.c
3 * 3 *
4 * Copyright (C) 1998-2002 Russell King 4 * Copyright (C) 1998-2002 Russell King
5 * 5 *
6 * MIPS and 50xx clock support 6 * MIPS and 50xx clock support
7 * Copyright (C) 2001 Bradley D. LaRonde <brad@ltc.com> 7 * Copyright (C) 2001 Bradley D. LaRonde <brad@ltc.com>
8 * 8 *
9 * 32 bit support, text color and panning fixes for modes != 8 bit 9 * 32 bit support, text color and panning fixes for modes != 8 bit
10 * Copyright (C) 2002 Denis Oliver Kropp <dok@directfb.org> 10 * Copyright (C) 2002 Denis Oliver Kropp <dok@directfb.org>
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
15 * 15 *
16 * Integraphics CyberPro 2000, 2010 and 5000 frame buffer device 16 * Integraphics CyberPro 2000, 2010 and 5000 frame buffer device
17 * 17 *
18 * Based on cyberfb.c. 18 * Based on cyberfb.c.
19 * 19 *
20 * Note that we now use the new fbcon fix, var and cmap scheme. We do 20 * Note that we now use the new fbcon fix, var and cmap scheme. We do
21 * still have to check which console is the currently displayed one 21 * still have to check which console is the currently displayed one
22 * however, especially for the colourmap stuff. 22 * however, especially for the colourmap stuff.
23 * 23 *
24 * We also use the new hotplug PCI subsystem. I'm not sure if there 24 * We also use the new hotplug PCI subsystem. I'm not sure if there
25 * are any such cards, but I'm erring on the side of caution. We don't 25 * are any such cards, but I'm erring on the side of caution. We don't
26 * want to go pop just because someone does have one. 26 * want to go pop just because someone does have one.
27 * 27 *
28 * Note that this doesn't work fully in the case of multiple CyberPro 28 * Note that this doesn't work fully in the case of multiple CyberPro
29 * cards with grabbers. We currently can only attach to the first 29 * cards with grabbers. We currently can only attach to the first
30 * CyberPro card found. 30 * CyberPro card found.
31 * 31 *
32 * When we're in truecolour mode, we power down the LUT RAM as a power 32 * When we're in truecolour mode, we power down the LUT RAM as a power
33 * saving feature. Also, when we enter any of the powersaving modes 33 * saving feature. Also, when we enter any of the powersaving modes
34 * (except soft blanking) we power down the RAMDACs. This saves about 34 * (except soft blanking) we power down the RAMDACs. This saves about
35 * 1W, which is roughly 8% of the power consumption of a NetWinder 35 * 1W, which is roughly 8% of the power consumption of a NetWinder
36 * (which, incidentally, is about the same saving as a 2.5in hard disk 36 * (which, incidentally, is about the same saving as a 2.5in hard disk
37 * entering standby mode.) 37 * entering standby mode.)
38 */ 38 */
39 #include <linux/module.h> 39 #include <linux/module.h>
40 #include <linux/kernel.h> 40 #include <linux/kernel.h>
41 #include <linux/errno.h> 41 #include <linux/errno.h>
42 #include <linux/string.h> 42 #include <linux/string.h>
43 #include <linux/mm.h> 43 #include <linux/mm.h>
44 #include <linux/slab.h> 44 #include <linux/slab.h>
45 #include <linux/delay.h> 45 #include <linux/delay.h>
46 #include <linux/fb.h> 46 #include <linux/fb.h>
47 #include <linux/pci.h> 47 #include <linux/pci.h>
48 #include <linux/init.h> 48 #include <linux/init.h>
49 #include <linux/io.h> 49 #include <linux/io.h>
50 50
51 #include <asm/pgtable.h> 51 #include <asm/pgtable.h>
52 #include <asm/system.h> 52 #include <asm/system.h>
53 53
54 #ifdef __arm__ 54 #ifdef __arm__
55 #include <asm/mach-types.h> 55 #include <asm/mach-types.h>
56 #endif 56 #endif
57 57
58 #include "cyber2000fb.h" 58 #include "cyber2000fb.h"
59 59
60 struct cfb_info { 60 struct cfb_info {
61 struct fb_info fb; 61 struct fb_info fb;
62 struct display_switch *dispsw; 62 struct display_switch *dispsw;
63 struct display *display; 63 struct display *display;
64 struct pci_dev *dev; 64 struct pci_dev *dev;
65 unsigned char __iomem *region; 65 unsigned char __iomem *region;
66 unsigned char __iomem *regs; 66 unsigned char __iomem *regs;
67 u_int id; 67 u_int id;
68 int func_use_count; 68 int func_use_count;
69 u_long ref_ps; 69 u_long ref_ps;
70 70
71 /* 71 /*
72 * Clock divisors 72 * Clock divisors
73 */ 73 */
74 u_int divisors[4]; 74 u_int divisors[4];
75 75
76 struct { 76 struct {
77 u8 red, green, blue; 77 u8 red, green, blue;
78 } palette[NR_PALETTE]; 78 } palette[NR_PALETTE];
79 79
80 u_char mem_ctl1; 80 u_char mem_ctl1;
81 u_char mem_ctl2; 81 u_char mem_ctl2;
82 u_char mclk_mult; 82 u_char mclk_mult;
83 u_char mclk_div; 83 u_char mclk_div;
84 /* 84 /*
85 * RAMDAC control register is both of these or'ed together 85 * RAMDAC control register is both of these or'ed together
86 */ 86 */
87 u_char ramdac_ctrl; 87 u_char ramdac_ctrl;
88 u_char ramdac_powerdown; 88 u_char ramdac_powerdown;
89 89
90 u32 pseudo_palette[16]; 90 u32 pseudo_palette[16];
91 }; 91 };
92 92
93 static char *default_font = "Acorn8x8"; 93 static char *default_font = "Acorn8x8";
94 module_param(default_font, charp, 0); 94 module_param(default_font, charp, 0);
95 MODULE_PARM_DESC(default_font, "Default font name"); 95 MODULE_PARM_DESC(default_font, "Default font name");
96 96
97 /* 97 /*
98 * Our access methods. 98 * Our access methods.
99 */ 99 */
100 #define cyber2000fb_writel(val, reg, cfb) writel(val, (cfb)->regs + (reg)) 100 #define cyber2000fb_writel(val, reg, cfb) writel(val, (cfb)->regs + (reg))
101 #define cyber2000fb_writew(val, reg, cfb) writew(val, (cfb)->regs + (reg)) 101 #define cyber2000fb_writew(val, reg, cfb) writew(val, (cfb)->regs + (reg))
102 #define cyber2000fb_writeb(val, reg, cfb) writeb(val, (cfb)->regs + (reg)) 102 #define cyber2000fb_writeb(val, reg, cfb) writeb(val, (cfb)->regs + (reg))
103 103
104 #define cyber2000fb_readb(reg, cfb) readb((cfb)->regs + (reg)) 104 #define cyber2000fb_readb(reg, cfb) readb((cfb)->regs + (reg))
105 105
106 static inline void 106 static inline void
107 cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb) 107 cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
108 { 108 {
109 cyber2000fb_writew((reg & 255) | val << 8, 0x3d4, cfb); 109 cyber2000fb_writew((reg & 255) | val << 8, 0x3d4, cfb);
110 } 110 }
111 111
112 static inline void 112 static inline void
113 cyber2000_grphw(unsigned int reg, unsigned int val, struct cfb_info *cfb) 113 cyber2000_grphw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
114 { 114 {
115 cyber2000fb_writew((reg & 255) | val << 8, 0x3ce, cfb); 115 cyber2000fb_writew((reg & 255) | val << 8, 0x3ce, cfb);
116 } 116 }
117 117
118 static inline unsigned int 118 static inline unsigned int
119 cyber2000_grphr(unsigned int reg, struct cfb_info *cfb) 119 cyber2000_grphr(unsigned int reg, struct cfb_info *cfb)
120 { 120 {
121 cyber2000fb_writeb(reg, 0x3ce, cfb); 121 cyber2000fb_writeb(reg, 0x3ce, cfb);
122 return cyber2000fb_readb(0x3cf, cfb); 122 return cyber2000fb_readb(0x3cf, cfb);
123 } 123 }
124 124
125 static inline void 125 static inline void
126 cyber2000_attrw(unsigned int reg, unsigned int val, struct cfb_info *cfb) 126 cyber2000_attrw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
127 { 127 {
128 cyber2000fb_readb(0x3da, cfb); 128 cyber2000fb_readb(0x3da, cfb);
129 cyber2000fb_writeb(reg, 0x3c0, cfb); 129 cyber2000fb_writeb(reg, 0x3c0, cfb);
130 cyber2000fb_readb(0x3c1, cfb); 130 cyber2000fb_readb(0x3c1, cfb);
131 cyber2000fb_writeb(val, 0x3c0, cfb); 131 cyber2000fb_writeb(val, 0x3c0, cfb);
132 } 132 }
133 133
134 static inline void 134 static inline void
135 cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb) 135 cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
136 { 136 {
137 cyber2000fb_writew((reg & 255) | val << 8, 0x3c4, cfb); 137 cyber2000fb_writew((reg & 255) | val << 8, 0x3c4, cfb);
138 } 138 }
139 139
140 /* -------------------- Hardware specific routines ------------------------- */ 140 /* -------------------- Hardware specific routines ------------------------- */
141 141
142 /* 142 /*
143 * Hardware Cyber2000 Acceleration 143 * Hardware Cyber2000 Acceleration
144 */ 144 */
145 static void 145 static void
146 cyber2000fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 146 cyber2000fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
147 { 147 {
148 struct cfb_info *cfb = (struct cfb_info *)info; 148 struct cfb_info *cfb = (struct cfb_info *)info;
149 unsigned long dst, col; 149 unsigned long dst, col;
150 150
151 if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) { 151 if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
152 cfb_fillrect(info, rect); 152 cfb_fillrect(info, rect);
153 return; 153 return;
154 } 154 }
155 155
156 cyber2000fb_writeb(0, CO_REG_CONTROL, cfb); 156 cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
157 cyber2000fb_writew(rect->width - 1, CO_REG_PIXWIDTH, cfb); 157 cyber2000fb_writew(rect->width - 1, CO_REG_PIXWIDTH, cfb);
158 cyber2000fb_writew(rect->height - 1, CO_REG_PIXHEIGHT, cfb); 158 cyber2000fb_writew(rect->height - 1, CO_REG_PIXHEIGHT, cfb);
159 159
160 col = rect->color; 160 col = rect->color;
161 if (cfb->fb.var.bits_per_pixel > 8) 161 if (cfb->fb.var.bits_per_pixel > 8)
162 col = ((u32 *)cfb->fb.pseudo_palette)[col]; 162 col = ((u32 *)cfb->fb.pseudo_palette)[col];
163 cyber2000fb_writel(col, CO_REG_FGCOLOUR, cfb); 163 cyber2000fb_writel(col, CO_REG_FGCOLOUR, cfb);
164 164
165 dst = rect->dx + rect->dy * cfb->fb.var.xres_virtual; 165 dst = rect->dx + rect->dy * cfb->fb.var.xres_virtual;
166 if (cfb->fb.var.bits_per_pixel == 24) { 166 if (cfb->fb.var.bits_per_pixel == 24) {
167 cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb); 167 cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
168 dst *= 3; 168 dst *= 3;
169 } 169 }
170 170
171 cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb); 171 cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
172 cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb); 172 cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
173 cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb); 173 cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb);
174 cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb); 174 cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb);
175 } 175 }
176 176
177 static void 177 static void
178 cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) 178 cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
179 { 179 {
180 struct cfb_info *cfb = (struct cfb_info *)info; 180 struct cfb_info *cfb = (struct cfb_info *)info;
181 unsigned int cmd = CO_CMD_L_PATTERN_FGCOL; 181 unsigned int cmd = CO_CMD_L_PATTERN_FGCOL;
182 unsigned long src, dst; 182 unsigned long src, dst;
183 183
184 if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) { 184 if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
185 cfb_copyarea(info, region); 185 cfb_copyarea(info, region);
186 return; 186 return;
187 } 187 }
188 188
189 cyber2000fb_writeb(0, CO_REG_CONTROL, cfb); 189 cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
190 cyber2000fb_writew(region->width - 1, CO_REG_PIXWIDTH, cfb); 190 cyber2000fb_writew(region->width - 1, CO_REG_PIXWIDTH, cfb);
191 cyber2000fb_writew(region->height - 1, CO_REG_PIXHEIGHT, cfb); 191 cyber2000fb_writew(region->height - 1, CO_REG_PIXHEIGHT, cfb);
192 192
193 src = region->sx + region->sy * cfb->fb.var.xres_virtual; 193 src = region->sx + region->sy * cfb->fb.var.xres_virtual;
194 dst = region->dx + region->dy * cfb->fb.var.xres_virtual; 194 dst = region->dx + region->dy * cfb->fb.var.xres_virtual;
195 195
196 if (region->sx < region->dx) { 196 if (region->sx < region->dx) {
197 src += region->width - 1; 197 src += region->width - 1;
198 dst += region->width - 1; 198 dst += region->width - 1;
199 cmd |= CO_CMD_L_INC_LEFT; 199 cmd |= CO_CMD_L_INC_LEFT;
200 } 200 }
201 201
202 if (region->sy < region->dy) { 202 if (region->sy < region->dy) {
203 src += (region->height - 1) * cfb->fb.var.xres_virtual; 203 src += (region->height - 1) * cfb->fb.var.xres_virtual;
204 dst += (region->height - 1) * cfb->fb.var.xres_virtual; 204 dst += (region->height - 1) * cfb->fb.var.xres_virtual;
205 cmd |= CO_CMD_L_INC_UP; 205 cmd |= CO_CMD_L_INC_UP;
206 } 206 }
207 207
208 if (cfb->fb.var.bits_per_pixel == 24) { 208 if (cfb->fb.var.bits_per_pixel == 24) {
209 cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb); 209 cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
210 src *= 3; 210 src *= 3;
211 dst *= 3; 211 dst *= 3;
212 } 212 }
213 cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb); 213 cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb);
214 cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb); 214 cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
215 cyber2000fb_writew(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb); 215 cyber2000fb_writew(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
216 cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb); 216 cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb);
217 cyber2000fb_writew(CO_CMD_H_FGSRCMAP | CO_CMD_H_BLITTER, 217 cyber2000fb_writew(CO_CMD_H_FGSRCMAP | CO_CMD_H_BLITTER,
218 CO_REG_CMD_H, cfb); 218 CO_REG_CMD_H, cfb);
219 } 219 }
220 220
221 static void 221 static void
222 cyber2000fb_imageblit(struct fb_info *info, const struct fb_image *image) 222 cyber2000fb_imageblit(struct fb_info *info, const struct fb_image *image)
223 { 223 {
224 cfb_imageblit(info, image); 224 cfb_imageblit(info, image);
225 return; 225 return;
226 } 226 }
227 227
228 static int cyber2000fb_sync(struct fb_info *info) 228 static int cyber2000fb_sync(struct fb_info *info)
229 { 229 {
230 struct cfb_info *cfb = (struct cfb_info *)info; 230 struct cfb_info *cfb = (struct cfb_info *)info;
231 int count = 100000; 231 int count = 100000;
232 232
233 if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) 233 if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT))
234 return 0; 234 return 0;
235 235
236 while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) { 236 while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) {
237 if (!count--) { 237 if (!count--) {
238 debug_printf("accel_wait timed out\n"); 238 debug_printf("accel_wait timed out\n");
239 cyber2000fb_writeb(0, CO_REG_CONTROL, cfb); 239 cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
240 break; 240 break;
241 } 241 }
242 udelay(1); 242 udelay(1);
243 } 243 }
244 return 0; 244 return 0;
245 } 245 }
246 246
247 /* 247 /*
248 * =========================================================================== 248 * ===========================================================================
249 */ 249 */
250 250
251 static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf) 251 static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf)
252 { 252 {
253 u_int mask = (1 << bf->length) - 1; 253 u_int mask = (1 << bf->length) - 1;
254 254
255 return (val >> (16 - bf->length) & mask) << bf->offset; 255 return (val >> (16 - bf->length) & mask) << bf->offset;
256 } 256 }
257 257
258 /* 258 /*
259 * Set a single color register. Return != 0 for invalid regno. 259 * Set a single color register. Return != 0 for invalid regno.
260 */ 260 */
261 static int 261 static int
262 cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 262 cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
263 u_int transp, struct fb_info *info) 263 u_int transp, struct fb_info *info)
264 { 264 {
265 struct cfb_info *cfb = (struct cfb_info *)info; 265 struct cfb_info *cfb = (struct cfb_info *)info;
266 struct fb_var_screeninfo *var = &cfb->fb.var; 266 struct fb_var_screeninfo *var = &cfb->fb.var;
267 u32 pseudo_val; 267 u32 pseudo_val;
268 int ret = 1; 268 int ret = 1;
269 269
270 switch (cfb->fb.fix.visual) { 270 switch (cfb->fb.fix.visual) {
271 default: 271 default:
272 return 1; 272 return 1;
273 273
274 /* 274 /*
275 * Pseudocolour: 275 * Pseudocolour:
276 * 8 8 276 * 8 8
277 * pixel --/--+--/--> red lut --> red dac 277 * pixel --/--+--/--> red lut --> red dac
278 * | 8 278 * | 8
279 * +--/--> green lut --> green dac 279 * +--/--> green lut --> green dac
280 * | 8 280 * | 8
281 * +--/--> blue lut --> blue dac 281 * +--/--> blue lut --> blue dac
282 */ 282 */
283 case FB_VISUAL_PSEUDOCOLOR: 283 case FB_VISUAL_PSEUDOCOLOR:
284 if (regno >= NR_PALETTE) 284 if (regno >= NR_PALETTE)
285 return 1; 285 return 1;
286 286
287 red >>= 8; 287 red >>= 8;
288 green >>= 8; 288 green >>= 8;
289 blue >>= 8; 289 blue >>= 8;
290 290
291 cfb->palette[regno].red = red; 291 cfb->palette[regno].red = red;
292 cfb->palette[regno].green = green; 292 cfb->palette[regno].green = green;
293 cfb->palette[regno].blue = blue; 293 cfb->palette[regno].blue = blue;
294 294
295 cyber2000fb_writeb(regno, 0x3c8, cfb); 295 cyber2000fb_writeb(regno, 0x3c8, cfb);
296 cyber2000fb_writeb(red, 0x3c9, cfb); 296 cyber2000fb_writeb(red, 0x3c9, cfb);
297 cyber2000fb_writeb(green, 0x3c9, cfb); 297 cyber2000fb_writeb(green, 0x3c9, cfb);
298 cyber2000fb_writeb(blue, 0x3c9, cfb); 298 cyber2000fb_writeb(blue, 0x3c9, cfb);
299 return 0; 299 return 0;
300 300
301 /* 301 /*
302 * Direct colour: 302 * Direct colour:
303 * n rl 303 * n rl
304 * pixel --/--+--/--> red lut --> red dac 304 * pixel --/--+--/--> red lut --> red dac
305 * | gl 305 * | gl
306 * +--/--> green lut --> green dac 306 * +--/--> green lut --> green dac
307 * | bl 307 * | bl
308 * +--/--> blue lut --> blue dac 308 * +--/--> blue lut --> blue dac
309 * n = bpp, rl = red length, gl = green length, bl = blue length 309 * n = bpp, rl = red length, gl = green length, bl = blue length
310 */ 310 */
311 case FB_VISUAL_DIRECTCOLOR: 311 case FB_VISUAL_DIRECTCOLOR:
312 red >>= 8; 312 red >>= 8;
313 green >>= 8; 313 green >>= 8;
314 blue >>= 8; 314 blue >>= 8;
315 315
316 if (var->green.length == 6 && regno < 64) { 316 if (var->green.length == 6 && regno < 64) {
317 cfb->palette[regno << 2].green = green; 317 cfb->palette[regno << 2].green = green;
318 318
319 /* 319 /*
320 * The 6 bits of the green component are applied 320 * The 6 bits of the green component are applied
321 * to the high 6 bits of the LUT. 321 * to the high 6 bits of the LUT.
322 */ 322 */
323 cyber2000fb_writeb(regno << 2, 0x3c8, cfb); 323 cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
324 cyber2000fb_writeb(cfb->palette[regno >> 1].red, 324 cyber2000fb_writeb(cfb->palette[regno >> 1].red,
325 0x3c9, cfb); 325 0x3c9, cfb);
326 cyber2000fb_writeb(green, 0x3c9, cfb); 326 cyber2000fb_writeb(green, 0x3c9, cfb);
327 cyber2000fb_writeb(cfb->palette[regno >> 1].blue, 327 cyber2000fb_writeb(cfb->palette[regno >> 1].blue,
328 0x3c9, cfb); 328 0x3c9, cfb);
329 329
330 green = cfb->palette[regno << 3].green; 330 green = cfb->palette[regno << 3].green;
331 331
332 ret = 0; 332 ret = 0;
333 } 333 }
334 334
335 if (var->green.length >= 5 && regno < 32) { 335 if (var->green.length >= 5 && regno < 32) {
336 cfb->palette[regno << 3].red = red; 336 cfb->palette[regno << 3].red = red;
337 cfb->palette[regno << 3].green = green; 337 cfb->palette[regno << 3].green = green;
338 cfb->palette[regno << 3].blue = blue; 338 cfb->palette[regno << 3].blue = blue;
339 339
340 /* 340 /*
341 * The 5 bits of each colour component are 341 * The 5 bits of each colour component are
342 * applied to the high 5 bits of the LUT. 342 * applied to the high 5 bits of the LUT.
343 */ 343 */
344 cyber2000fb_writeb(regno << 3, 0x3c8, cfb); 344 cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
345 cyber2000fb_writeb(red, 0x3c9, cfb); 345 cyber2000fb_writeb(red, 0x3c9, cfb);
346 cyber2000fb_writeb(green, 0x3c9, cfb); 346 cyber2000fb_writeb(green, 0x3c9, cfb);
347 cyber2000fb_writeb(blue, 0x3c9, cfb); 347 cyber2000fb_writeb(blue, 0x3c9, cfb);
348 ret = 0; 348 ret = 0;
349 } 349 }
350 350
351 if (var->green.length == 4 && regno < 16) { 351 if (var->green.length == 4 && regno < 16) {
352 cfb->palette[regno << 4].red = red; 352 cfb->palette[regno << 4].red = red;
353 cfb->palette[regno << 4].green = green; 353 cfb->palette[regno << 4].green = green;
354 cfb->palette[regno << 4].blue = blue; 354 cfb->palette[regno << 4].blue = blue;
355 355
356 /* 356 /*
357 * The 5 bits of each colour component are 357 * The 5 bits of each colour component are
358 * applied to the high 5 bits of the LUT. 358 * applied to the high 5 bits of the LUT.
359 */ 359 */
360 cyber2000fb_writeb(regno << 4, 0x3c8, cfb); 360 cyber2000fb_writeb(regno << 4, 0x3c8, cfb);
361 cyber2000fb_writeb(red, 0x3c9, cfb); 361 cyber2000fb_writeb(red, 0x3c9, cfb);
362 cyber2000fb_writeb(green, 0x3c9, cfb); 362 cyber2000fb_writeb(green, 0x3c9, cfb);
363 cyber2000fb_writeb(blue, 0x3c9, cfb); 363 cyber2000fb_writeb(blue, 0x3c9, cfb);
364 ret = 0; 364 ret = 0;
365 } 365 }
366 366
367 /* 367 /*
368 * Since this is only used for the first 16 colours, we 368 * Since this is only used for the first 16 colours, we
369 * don't have to care about overflowing for regno >= 32 369 * don't have to care about overflowing for regno >= 32
370 */ 370 */
371 pseudo_val = regno << var->red.offset | 371 pseudo_val = regno << var->red.offset |
372 regno << var->green.offset | 372 regno << var->green.offset |
373 regno << var->blue.offset; 373 regno << var->blue.offset;
374 break; 374 break;
375 375
376 /* 376 /*
377 * True colour: 377 * True colour:
378 * n rl 378 * n rl
379 * pixel --/--+--/--> red dac 379 * pixel --/--+--/--> red dac
380 * | gl 380 * | gl
381 * +--/--> green dac 381 * +--/--> green dac
382 * | bl 382 * | bl
383 * +--/--> blue dac 383 * +--/--> blue dac
384 * n = bpp, rl = red length, gl = green length, bl = blue length 384 * n = bpp, rl = red length, gl = green length, bl = blue length
385 */ 385 */
386 case FB_VISUAL_TRUECOLOR: 386 case FB_VISUAL_TRUECOLOR:
387 pseudo_val = convert_bitfield(transp ^ 0xffff, &var->transp); 387 pseudo_val = convert_bitfield(transp ^ 0xffff, &var->transp);
388 pseudo_val |= convert_bitfield(red, &var->red); 388 pseudo_val |= convert_bitfield(red, &var->red);
389 pseudo_val |= convert_bitfield(green, &var->green); 389 pseudo_val |= convert_bitfield(green, &var->green);
390 pseudo_val |= convert_bitfield(blue, &var->blue); 390 pseudo_val |= convert_bitfield(blue, &var->blue);
391 break; 391 break;
392 } 392 }
393 393
394 /* 394 /*
395 * Now set our pseudo palette for the CFB16/24/32 drivers. 395 * Now set our pseudo palette for the CFB16/24/32 drivers.
396 */ 396 */
397 if (regno < 16) 397 if (regno < 16)
398 ((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val; 398 ((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
399 399
400 return ret; 400 return ret;
401 } 401 }
402 402
403 struct par_info { 403 struct par_info {
404 /* 404 /*
405 * Hardware 405 * Hardware
406 */ 406 */
407 u_char clock_mult; 407 u_char clock_mult;
408 u_char clock_div; 408 u_char clock_div;
409 u_char extseqmisc; 409 u_char extseqmisc;
410 u_char co_pixfmt; 410 u_char co_pixfmt;
411 u_char crtc_ofl; 411 u_char crtc_ofl;
412 u_char crtc[19]; 412 u_char crtc[19];
413 u_int width; 413 u_int width;
414 u_int pitch; 414 u_int pitch;
415 u_int fetch; 415 u_int fetch;
416 416
417 /* 417 /*
418 * Other 418 * Other
419 */ 419 */
420 u_char ramdac; 420 u_char ramdac;
421 }; 421 };
422 422
423 static const u_char crtc_idx[] = { 423 static const u_char crtc_idx[] = {
424 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 424 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
425 0x08, 0x09, 425 0x08, 0x09,
426 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 426 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18
427 }; 427 };
428 428
429 static void cyber2000fb_write_ramdac_ctrl(struct cfb_info *cfb) 429 static void cyber2000fb_write_ramdac_ctrl(struct cfb_info *cfb)
430 { 430 {
431 unsigned int i; 431 unsigned int i;
432 unsigned int val = cfb->ramdac_ctrl | cfb->ramdac_powerdown; 432 unsigned int val = cfb->ramdac_ctrl | cfb->ramdac_powerdown;
433 433
434 cyber2000fb_writeb(0x56, 0x3ce, cfb); 434 cyber2000fb_writeb(0x56, 0x3ce, cfb);
435 i = cyber2000fb_readb(0x3cf, cfb); 435 i = cyber2000fb_readb(0x3cf, cfb);
436 cyber2000fb_writeb(i | 4, 0x3cf, cfb); 436 cyber2000fb_writeb(i | 4, 0x3cf, cfb);
437 cyber2000fb_writeb(val, 0x3c6, cfb); 437 cyber2000fb_writeb(val, 0x3c6, cfb);
438 cyber2000fb_writeb(i, 0x3cf, cfb); 438 cyber2000fb_writeb(i, 0x3cf, cfb);
439 } 439 }
440 440
441 static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw) 441 static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
442 { 442 {
443 u_int i; 443 u_int i;
444 444
445 /* 445 /*
446 * Blank palette 446 * Blank palette
447 */ 447 */
448 for (i = 0; i < NR_PALETTE; i++) { 448 for (i = 0; i < NR_PALETTE; i++) {
449 cyber2000fb_writeb(i, 0x3c8, cfb); 449 cyber2000fb_writeb(i, 0x3c8, cfb);
450 cyber2000fb_writeb(0, 0x3c9, cfb); 450 cyber2000fb_writeb(0, 0x3c9, cfb);
451 cyber2000fb_writeb(0, 0x3c9, cfb); 451 cyber2000fb_writeb(0, 0x3c9, cfb);
452 cyber2000fb_writeb(0, 0x3c9, cfb); 452 cyber2000fb_writeb(0, 0x3c9, cfb);
453 } 453 }
454 454
455 cyber2000fb_writeb(0xef, 0x3c2, cfb); 455 cyber2000fb_writeb(0xef, 0x3c2, cfb);
456 cyber2000_crtcw(0x11, 0x0b, cfb); 456 cyber2000_crtcw(0x11, 0x0b, cfb);
457 cyber2000_attrw(0x11, 0x00, cfb); 457 cyber2000_attrw(0x11, 0x00, cfb);
458 458
459 cyber2000_seqw(0x00, 0x01, cfb); 459 cyber2000_seqw(0x00, 0x01, cfb);
460 cyber2000_seqw(0x01, 0x01, cfb); 460 cyber2000_seqw(0x01, 0x01, cfb);
461 cyber2000_seqw(0x02, 0x0f, cfb); 461 cyber2000_seqw(0x02, 0x0f, cfb);
462 cyber2000_seqw(0x03, 0x00, cfb); 462 cyber2000_seqw(0x03, 0x00, cfb);
463 cyber2000_seqw(0x04, 0x0e, cfb); 463 cyber2000_seqw(0x04, 0x0e, cfb);
464 cyber2000_seqw(0x00, 0x03, cfb); 464 cyber2000_seqw(0x00, 0x03, cfb);
465 465
466 for (i = 0; i < sizeof(crtc_idx); i++) 466 for (i = 0; i < sizeof(crtc_idx); i++)
467 cyber2000_crtcw(crtc_idx[i], hw->crtc[i], cfb); 467 cyber2000_crtcw(crtc_idx[i], hw->crtc[i], cfb);
468 468
469 for (i = 0x0a; i < 0x10; i++) 469 for (i = 0x0a; i < 0x10; i++)
470 cyber2000_crtcw(i, 0, cfb); 470 cyber2000_crtcw(i, 0, cfb);
471 471
472 cyber2000_grphw(EXT_CRT_VRTOFL, hw->crtc_ofl, cfb); 472 cyber2000_grphw(EXT_CRT_VRTOFL, hw->crtc_ofl, cfb);
473 cyber2000_grphw(0x00, 0x00, cfb); 473 cyber2000_grphw(0x00, 0x00, cfb);
474 cyber2000_grphw(0x01, 0x00, cfb); 474 cyber2000_grphw(0x01, 0x00, cfb);
475 cyber2000_grphw(0x02, 0x00, cfb); 475 cyber2000_grphw(0x02, 0x00, cfb);
476 cyber2000_grphw(0x03, 0x00, cfb); 476 cyber2000_grphw(0x03, 0x00, cfb);
477 cyber2000_grphw(0x04, 0x00, cfb); 477 cyber2000_grphw(0x04, 0x00, cfb);
478 cyber2000_grphw(0x05, 0x60, cfb); 478 cyber2000_grphw(0x05, 0x60, cfb);
479 cyber2000_grphw(0x06, 0x05, cfb); 479 cyber2000_grphw(0x06, 0x05, cfb);
480 cyber2000_grphw(0x07, 0x0f, cfb); 480 cyber2000_grphw(0x07, 0x0f, cfb);
481 cyber2000_grphw(0x08, 0xff, cfb); 481 cyber2000_grphw(0x08, 0xff, cfb);
482 482
483 /* Attribute controller registers */ 483 /* Attribute controller registers */
484 for (i = 0; i < 16; i++) 484 for (i = 0; i < 16; i++)
485 cyber2000_attrw(i, i, cfb); 485 cyber2000_attrw(i, i, cfb);
486 486
487 cyber2000_attrw(0x10, 0x01, cfb); 487 cyber2000_attrw(0x10, 0x01, cfb);
488 cyber2000_attrw(0x11, 0x00, cfb); 488 cyber2000_attrw(0x11, 0x00, cfb);
489 cyber2000_attrw(0x12, 0x0f, cfb); 489 cyber2000_attrw(0x12, 0x0f, cfb);
490 cyber2000_attrw(0x13, 0x00, cfb); 490 cyber2000_attrw(0x13, 0x00, cfb);
491 cyber2000_attrw(0x14, 0x00, cfb); 491 cyber2000_attrw(0x14, 0x00, cfb);
492 492
493 /* PLL registers */ 493 /* PLL registers */
494 cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb); 494 cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb);
495 cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb); 495 cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
496 cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb); 496 cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb);
497 cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb); 497 cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb);
498 cyber2000_grphw(0x90, 0x01, cfb); 498 cyber2000_grphw(0x90, 0x01, cfb);
499 cyber2000_grphw(0xb9, 0x80, cfb); 499 cyber2000_grphw(0xb9, 0x80, cfb);
500 cyber2000_grphw(0xb9, 0x00, cfb); 500 cyber2000_grphw(0xb9, 0x00, cfb);
501 501
502 cfb->ramdac_ctrl = hw->ramdac; 502 cfb->ramdac_ctrl = hw->ramdac;
503 cyber2000fb_write_ramdac_ctrl(cfb); 503 cyber2000fb_write_ramdac_ctrl(cfb);
504 504
505 cyber2000fb_writeb(0x20, 0x3c0, cfb); 505 cyber2000fb_writeb(0x20, 0x3c0, cfb);
506 cyber2000fb_writeb(0xff, 0x3c6, cfb); 506 cyber2000fb_writeb(0xff, 0x3c6, cfb);
507 507
508 cyber2000_grphw(0x14, hw->fetch, cfb); 508 cyber2000_grphw(0x14, hw->fetch, cfb);
509 cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) | 509 cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) |
510 ((hw->pitch >> 4) & 0x30), cfb); 510 ((hw->pitch >> 4) & 0x30), cfb);
511 cyber2000_grphw(EXT_SEQ_MISC, hw->extseqmisc, cfb); 511 cyber2000_grphw(EXT_SEQ_MISC, hw->extseqmisc, cfb);
512 512
513 /* 513 /*
514 * Set up accelerator registers 514 * Set up accelerator registers
515 */ 515 */
516 cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb); 516 cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb);
517 cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb); 517 cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb);
518 cyber2000fb_writeb(hw->co_pixfmt, CO_REG_PIXFMT, cfb); 518 cyber2000fb_writeb(hw->co_pixfmt, CO_REG_PIXFMT, cfb);
519 } 519 }
520 520
521 static inline int 521 static inline int
522 cyber2000fb_update_start(struct cfb_info *cfb, struct fb_var_screeninfo *var) 522 cyber2000fb_update_start(struct cfb_info *cfb, struct fb_var_screeninfo *var)
523 { 523 {
524 u_int base = var->yoffset * var->xres_virtual + var->xoffset; 524 u_int base = var->yoffset * var->xres_virtual + var->xoffset;
525 525
526 base *= var->bits_per_pixel; 526 base *= var->bits_per_pixel;
527 527
528 /* 528 /*
529 * Convert to bytes and shift two extra bits because DAC 529 * Convert to bytes and shift two extra bits because DAC
530 * can only start on 4 byte aligned data. 530 * can only start on 4 byte aligned data.
531 */ 531 */
532 base >>= 5; 532 base >>= 5;
533 533
534 if (base >= 1 << 20) 534 if (base >= 1 << 20)
535 return -EINVAL; 535 return -EINVAL;
536 536
537 cyber2000_grphw(0x10, base >> 16 | 0x10, cfb); 537 cyber2000_grphw(0x10, base >> 16 | 0x10, cfb);
538 cyber2000_crtcw(0x0c, base >> 8, cfb); 538 cyber2000_crtcw(0x0c, base >> 8, cfb);
539 cyber2000_crtcw(0x0d, base, cfb); 539 cyber2000_crtcw(0x0d, base, cfb);
540 540
541 return 0; 541 return 0;
542 } 542 }
543 543
544 static int 544 static int
545 cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb, 545 cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
546 struct fb_var_screeninfo *var) 546 struct fb_var_screeninfo *var)
547 { 547 {
548 u_int Htotal, Hblankend, Hsyncend; 548 u_int Htotal, Hblankend, Hsyncend;
549 u_int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend; 549 u_int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend;
550 #define ENCODE_BIT(v, b1, m, b2) ((((v) >> (b1)) & (m)) << (b2)) 550 #define ENCODE_BIT(v, b1, m, b2) ((((v) >> (b1)) & (m)) << (b2))
551 551
552 hw->crtc[13] = hw->pitch; 552 hw->crtc[13] = hw->pitch;
553 hw->crtc[17] = 0xe3; 553 hw->crtc[17] = 0xe3;
554 hw->crtc[14] = 0; 554 hw->crtc[14] = 0;
555 hw->crtc[8] = 0; 555 hw->crtc[8] = 0;
556 556
557 Htotal = var->xres + var->right_margin + 557 Htotal = var->xres + var->right_margin +
558 var->hsync_len + var->left_margin; 558 var->hsync_len + var->left_margin;
559 559
560 if (Htotal > 2080) 560 if (Htotal > 2080)
561 return -EINVAL; 561 return -EINVAL;
562 562
563 hw->crtc[0] = (Htotal >> 3) - 5; 563 hw->crtc[0] = (Htotal >> 3) - 5;
564 hw->crtc[1] = (var->xres >> 3) - 1; 564 hw->crtc[1] = (var->xres >> 3) - 1;
565 hw->crtc[2] = var->xres >> 3; 565 hw->crtc[2] = var->xres >> 3;
566 hw->crtc[4] = (var->xres + var->right_margin) >> 3; 566 hw->crtc[4] = (var->xres + var->right_margin) >> 3;
567 567
568 Hblankend = (Htotal - 4 * 8) >> 3; 568 Hblankend = (Htotal - 4 * 8) >> 3;
569 569
570 hw->crtc[3] = ENCODE_BIT(Hblankend, 0, 0x1f, 0) | 570 hw->crtc[3] = ENCODE_BIT(Hblankend, 0, 0x1f, 0) |
571 ENCODE_BIT(1, 0, 0x01, 7); 571 ENCODE_BIT(1, 0, 0x01, 7);
572 572
573 Hsyncend = (var->xres + var->right_margin + var->hsync_len) >> 3; 573 Hsyncend = (var->xres + var->right_margin + var->hsync_len) >> 3;
574 574
575 hw->crtc[5] = ENCODE_BIT(Hsyncend, 0, 0x1f, 0) | 575 hw->crtc[5] = ENCODE_BIT(Hsyncend, 0, 0x1f, 0) |
576 ENCODE_BIT(Hblankend, 5, 0x01, 7); 576 ENCODE_BIT(Hblankend, 5, 0x01, 7);
577 577
578 Vdispend = var->yres - 1; 578 Vdispend = var->yres - 1;
579 Vsyncstart = var->yres + var->lower_margin; 579 Vsyncstart = var->yres + var->lower_margin;
580 Vsyncend = var->yres + var->lower_margin + var->vsync_len; 580 Vsyncend = var->yres + var->lower_margin + var->vsync_len;
581 Vtotal = var->yres + var->lower_margin + var->vsync_len + 581 Vtotal = var->yres + var->lower_margin + var->vsync_len +
582 var->upper_margin - 2; 582 var->upper_margin - 2;
583 583
584 if (Vtotal > 2047) 584 if (Vtotal > 2047)
585 return -EINVAL; 585 return -EINVAL;
586 586
587 Vblankstart = var->yres + 6; 587 Vblankstart = var->yres + 6;
588 Vblankend = Vtotal - 10; 588 Vblankend = Vtotal - 10;
589 589
590 hw->crtc[6] = Vtotal; 590 hw->crtc[6] = Vtotal;
591 hw->crtc[7] = ENCODE_BIT(Vtotal, 8, 0x01, 0) | 591 hw->crtc[7] = ENCODE_BIT(Vtotal, 8, 0x01, 0) |
592 ENCODE_BIT(Vdispend, 8, 0x01, 1) | 592 ENCODE_BIT(Vdispend, 8, 0x01, 1) |
593 ENCODE_BIT(Vsyncstart, 8, 0x01, 2) | 593 ENCODE_BIT(Vsyncstart, 8, 0x01, 2) |
594 ENCODE_BIT(Vblankstart, 8, 0x01, 3) | 594 ENCODE_BIT(Vblankstart, 8, 0x01, 3) |
595 ENCODE_BIT(1, 0, 0x01, 4) | 595 ENCODE_BIT(1, 0, 0x01, 4) |
596 ENCODE_BIT(Vtotal, 9, 0x01, 5) | 596 ENCODE_BIT(Vtotal, 9, 0x01, 5) |
597 ENCODE_BIT(Vdispend, 9, 0x01, 6) | 597 ENCODE_BIT(Vdispend, 9, 0x01, 6) |
598 ENCODE_BIT(Vsyncstart, 9, 0x01, 7); 598 ENCODE_BIT(Vsyncstart, 9, 0x01, 7);
599 hw->crtc[9] = ENCODE_BIT(0, 0, 0x1f, 0) | 599 hw->crtc[9] = ENCODE_BIT(0, 0, 0x1f, 0) |
600 ENCODE_BIT(Vblankstart, 9, 0x01, 5) | 600 ENCODE_BIT(Vblankstart, 9, 0x01, 5) |
601 ENCODE_BIT(1, 0, 0x01, 6); 601 ENCODE_BIT(1, 0, 0x01, 6);
602 hw->crtc[10] = Vsyncstart; 602 hw->crtc[10] = Vsyncstart;
603 hw->crtc[11] = ENCODE_BIT(Vsyncend, 0, 0x0f, 0) | 603 hw->crtc[11] = ENCODE_BIT(Vsyncend, 0, 0x0f, 0) |
604 ENCODE_BIT(1, 0, 0x01, 7); 604 ENCODE_BIT(1, 0, 0x01, 7);
605 hw->crtc[12] = Vdispend; 605 hw->crtc[12] = Vdispend;
606 hw->crtc[15] = Vblankstart; 606 hw->crtc[15] = Vblankstart;
607 hw->crtc[16] = Vblankend; 607 hw->crtc[16] = Vblankend;
608 hw->crtc[18] = 0xff; 608 hw->crtc[18] = 0xff;
609 609
610 /* 610 /*
611 * overflow - graphics reg 0x11 611 * overflow - graphics reg 0x11
612 * 0=VTOTAL:10 1=VDEND:10 2=VRSTART:10 3=VBSTART:10 612 * 0=VTOTAL:10 1=VDEND:10 2=VRSTART:10 3=VBSTART:10
613 * 4=LINECOMP:10 5-IVIDEO 6=FIXCNT 613 * 4=LINECOMP:10 5-IVIDEO 6=FIXCNT
614 */ 614 */
615 hw->crtc_ofl = 615 hw->crtc_ofl =
616 ENCODE_BIT(Vtotal, 10, 0x01, 0) | 616 ENCODE_BIT(Vtotal, 10, 0x01, 0) |
617 ENCODE_BIT(Vdispend, 10, 0x01, 1) | 617 ENCODE_BIT(Vdispend, 10, 0x01, 1) |
618 ENCODE_BIT(Vsyncstart, 10, 0x01, 2) | 618 ENCODE_BIT(Vsyncstart, 10, 0x01, 2) |
619 ENCODE_BIT(Vblankstart, 10, 0x01, 3) | 619 ENCODE_BIT(Vblankstart, 10, 0x01, 3) |
620 EXT_CRT_VRTOFL_LINECOMP10; 620 EXT_CRT_VRTOFL_LINECOMP10;
621 621
622 /* woody: set the interlaced bit... */ 622 /* woody: set the interlaced bit... */
623 /* FIXME: what about doublescan? */ 623 /* FIXME: what about doublescan? */
624 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) 624 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
625 hw->crtc_ofl |= EXT_CRT_VRTOFL_INTERLACE; 625 hw->crtc_ofl |= EXT_CRT_VRTOFL_INTERLACE;
626 626
627 return 0; 627 return 0;
628 } 628 }
629 629
630 /* 630 /*
631 * The following was discovered by a good monitor, bit twiddling, theorising 631 * The following was discovered by a good monitor, bit twiddling, theorising
632 * and but mostly luck. Strangely, it looks like everyone elses' PLL! 632 * and but mostly luck. Strangely, it looks like everyone elses' PLL!
633 * 633 *
634 * Clock registers: 634 * Clock registers:
635 * fclock = fpll / div2 635 * fclock = fpll / div2
636 * fpll = fref * mult / div1 636 * fpll = fref * mult / div1
637 * where: 637 * where:
638 * fref = 14.318MHz (69842ps) 638 * fref = 14.318MHz (69842ps)
639 * mult = reg0xb0.7:0 639 * mult = reg0xb0.7:0
640 * div1 = (reg0xb1.5:0 + 1) 640 * div1 = (reg0xb1.5:0 + 1)
641 * div2 = 2^(reg0xb1.7:6) 641 * div2 = 2^(reg0xb1.7:6)
642 * fpll should be between 115 and 260 MHz 642 * fpll should be between 115 and 260 MHz
643 * (8696ps and 3846ps) 643 * (8696ps and 3846ps)
644 */ 644 */
645 static int 645 static int
646 cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb, 646 cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
647 struct fb_var_screeninfo *var) 647 struct fb_var_screeninfo *var)
648 { 648 {
649 u_long pll_ps = var->pixclock; 649 u_long pll_ps = var->pixclock;
650 const u_long ref_ps = cfb->ref_ps; 650 const u_long ref_ps = cfb->ref_ps;
651 u_int div2, t_div1, best_div1, best_mult; 651 u_int div2, t_div1, best_div1, best_mult;
652 int best_diff; 652 int best_diff;
653 int vco; 653 int vco;
654 654
655 /* 655 /*
656 * Step 1: 656 * Step 1:
657 * find div2 such that 115MHz < fpll < 260MHz 657 * find div2 such that 115MHz < fpll < 260MHz
658 * and 0 <= div2 < 4 658 * and 0 <= div2 < 4
659 */ 659 */
660 for (div2 = 0; div2 < 4; div2++) { 660 for (div2 = 0; div2 < 4; div2++) {
661 u_long new_pll; 661 u_long new_pll;
662 662
663 new_pll = pll_ps / cfb->divisors[div2]; 663 new_pll = pll_ps / cfb->divisors[div2];
664 if (8696 > new_pll && new_pll > 3846) { 664 if (8696 > new_pll && new_pll > 3846) {
665 pll_ps = new_pll; 665 pll_ps = new_pll;
666 break; 666 break;
667 } 667 }
668 } 668 }
669 669
670 if (div2 == 4) 670 if (div2 == 4)
671 return -EINVAL; 671 return -EINVAL;
672 672
673 /* 673 /*
674 * Step 2: 674 * Step 2:
675 * Given pll_ps and ref_ps, find: 675 * Given pll_ps and ref_ps, find:
676 * pll_ps * 0.995 < pll_ps_calc < pll_ps * 1.005 676 * pll_ps * 0.995 < pll_ps_calc < pll_ps * 1.005
677 * where { 1 < best_div1 < 32, 1 < best_mult < 256 } 677 * where { 1 < best_div1 < 32, 1 < best_mult < 256 }
678 * pll_ps_calc = best_div1 / (ref_ps * best_mult) 678 * pll_ps_calc = best_div1 / (ref_ps * best_mult)
679 */ 679 */
680 best_diff = 0x7fffffff; 680 best_diff = 0x7fffffff;
681 best_mult = 32; 681 best_mult = 32;
682 best_div1 = 255; 682 best_div1 = 255;
683 for (t_div1 = 32; t_div1 > 1; t_div1 -= 1) { 683 for (t_div1 = 32; t_div1 > 1; t_div1 -= 1) {
684 u_int rr, t_mult, t_pll_ps; 684 u_int rr, t_mult, t_pll_ps;
685 int diff; 685 int diff;
686 686
687 /* 687 /*
688 * Find the multiplier for this divisor 688 * Find the multiplier for this divisor
689 */ 689 */
690 rr = ref_ps * t_div1; 690 rr = ref_ps * t_div1;
691 t_mult = (rr + pll_ps / 2) / pll_ps; 691 t_mult = (rr + pll_ps / 2) / pll_ps;
692 692
693 /* 693 /*
694 * Is the multiplier within the correct range? 694 * Is the multiplier within the correct range?
695 */ 695 */
696 if (t_mult > 256 || t_mult < 2) 696 if (t_mult > 256 || t_mult < 2)
697 continue; 697 continue;
698 698
699 /* 699 /*
700 * Calculate the actual clock period from this multiplier 700 * Calculate the actual clock period from this multiplier
701 * and divisor, and estimate the error. 701 * and divisor, and estimate the error.
702 */ 702 */
703 t_pll_ps = (rr + t_mult / 2) / t_mult; 703 t_pll_ps = (rr + t_mult / 2) / t_mult;
704 diff = pll_ps - t_pll_ps; 704 diff = pll_ps - t_pll_ps;
705 if (diff < 0) 705 if (diff < 0)
706 diff = -diff; 706 diff = -diff;
707 707
708 if (diff < best_diff) { 708 if (diff < best_diff) {
709 best_diff = diff; 709 best_diff = diff;
710 best_mult = t_mult; 710 best_mult = t_mult;
711 best_div1 = t_div1; 711 best_div1 = t_div1;
712 } 712 }
713 713
714 /* 714 /*
715 * If we hit an exact value, there is no point in continuing. 715 * If we hit an exact value, there is no point in continuing.
716 */ 716 */
717 if (diff == 0) 717 if (diff == 0)
718 break; 718 break;
719 } 719 }
720 720
721 /* 721 /*
722 * Step 3: 722 * Step 3:
723 * combine values 723 * combine values
724 */ 724 */
725 hw->clock_mult = best_mult - 1; 725 hw->clock_mult = best_mult - 1;
726 hw->clock_div = div2 << 6 | (best_div1 - 1); 726 hw->clock_div = div2 << 6 | (best_div1 - 1);
727 727
728 vco = ref_ps * best_div1 / best_mult; 728 vco = ref_ps * best_div1 / best_mult;
729 if ((ref_ps == 40690) && (vco < 5556)) 729 if ((ref_ps == 40690) && (vco < 5556))
730 /* Set VFSEL when VCO > 180MHz (5.556 ps). */ 730 /* Set VFSEL when VCO > 180MHz (5.556 ps). */
731 hw->clock_div |= EXT_DCLK_DIV_VFSEL; 731 hw->clock_div |= EXT_DCLK_DIV_VFSEL;
732 732
733 return 0; 733 return 0;
734 } 734 }
735 735
736 /* 736 /*
737 * Set the User Defined Part of the Display 737 * Set the User Defined Part of the Display
738 */ 738 */
739 static int 739 static int
740 cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 740 cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
741 { 741 {
742 struct cfb_info *cfb = (struct cfb_info *)info; 742 struct cfb_info *cfb = (struct cfb_info *)info;
743 struct par_info hw; 743 struct par_info hw;
744 unsigned int mem; 744 unsigned int mem;
745 int err; 745 int err;
746 746
747 var->transp.msb_right = 0; 747 var->transp.msb_right = 0;
748 var->red.msb_right = 0; 748 var->red.msb_right = 0;
749 var->green.msb_right = 0; 749 var->green.msb_right = 0;
750 var->blue.msb_right = 0; 750 var->blue.msb_right = 0;
751 var->transp.offset = 0; 751 var->transp.offset = 0;
752 var->transp.length = 0; 752 var->transp.length = 0;
753 753
754 switch (var->bits_per_pixel) { 754 switch (var->bits_per_pixel) {
755 case 8: /* PSEUDOCOLOUR, 256 */ 755 case 8: /* PSEUDOCOLOUR, 256 */
756 var->red.offset = 0; 756 var->red.offset = 0;
757 var->red.length = 8; 757 var->red.length = 8;
758 var->green.offset = 0; 758 var->green.offset = 0;
759 var->green.length = 8; 759 var->green.length = 8;
760 var->blue.offset = 0; 760 var->blue.offset = 0;
761 var->blue.length = 8; 761 var->blue.length = 8;
762 break; 762 break;
763 763
764 case 16:/* DIRECTCOLOUR, 64k or 32k */ 764 case 16:/* DIRECTCOLOUR, 64k or 32k */
765 switch (var->green.length) { 765 switch (var->green.length) {
766 case 6: /* RGB565, 64k */ 766 case 6: /* RGB565, 64k */
767 var->red.offset = 11; 767 var->red.offset = 11;
768 var->red.length = 5; 768 var->red.length = 5;
769 var->green.offset = 5; 769 var->green.offset = 5;
770 var->green.length = 6; 770 var->green.length = 6;
771 var->blue.offset = 0; 771 var->blue.offset = 0;
772 var->blue.length = 5; 772 var->blue.length = 5;
773 break; 773 break;
774 774
775 default: 775 default:
776 case 5: /* RGB555, 32k */ 776 case 5: /* RGB555, 32k */
777 var->red.offset = 10; 777 var->red.offset = 10;
778 var->red.length = 5; 778 var->red.length = 5;
779 var->green.offset = 5; 779 var->green.offset = 5;
780 var->green.length = 5; 780 var->green.length = 5;
781 var->blue.offset = 0; 781 var->blue.offset = 0;
782 var->blue.length = 5; 782 var->blue.length = 5;
783 break; 783 break;
784 784
785 case 4: /* RGB444, 4k + transparency? */ 785 case 4: /* RGB444, 4k + transparency? */
786 var->transp.offset = 12; 786 var->transp.offset = 12;
787 var->transp.length = 4; 787 var->transp.length = 4;
788 var->red.offset = 8; 788 var->red.offset = 8;
789 var->red.length = 4; 789 var->red.length = 4;
790 var->green.offset = 4; 790 var->green.offset = 4;
791 var->green.length = 4; 791 var->green.length = 4;
792 var->blue.offset = 0; 792 var->blue.offset = 0;
793 var->blue.length = 4; 793 var->blue.length = 4;
794 break; 794 break;
795 } 795 }
796 break; 796 break;
797 797
798 case 24:/* TRUECOLOUR, 16m */ 798 case 24:/* TRUECOLOUR, 16m */
799 var->red.offset = 16; 799 var->red.offset = 16;
800 var->red.length = 8; 800 var->red.length = 8;
801 var->green.offset = 8; 801 var->green.offset = 8;
802 var->green.length = 8; 802 var->green.length = 8;
803 var->blue.offset = 0; 803 var->blue.offset = 0;
804 var->blue.length = 8; 804 var->blue.length = 8;
805 break; 805 break;
806 806
807 case 32:/* TRUECOLOUR, 16m */ 807 case 32:/* TRUECOLOUR, 16m */
808 var->transp.offset = 24; 808 var->transp.offset = 24;
809 var->transp.length = 8; 809 var->transp.length = 8;
810 var->red.offset = 16; 810 var->red.offset = 16;
811 var->red.length = 8; 811 var->red.length = 8;
812 var->green.offset = 8; 812 var->green.offset = 8;
813 var->green.length = 8; 813 var->green.length = 8;
814 var->blue.offset = 0; 814 var->blue.offset = 0;
815 var->blue.length = 8; 815 var->blue.length = 8;
816 break; 816 break;
817 817
818 default: 818 default:
819 return -EINVAL; 819 return -EINVAL;
820 } 820 }
821 821
822 mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8); 822 mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8);
823 if (mem > cfb->fb.fix.smem_len) 823 if (mem > cfb->fb.fix.smem_len)
824 var->yres_virtual = cfb->fb.fix.smem_len * 8 / 824 var->yres_virtual = cfb->fb.fix.smem_len * 8 /
825 (var->bits_per_pixel * var->xres_virtual); 825 (var->bits_per_pixel * var->xres_virtual);
826 826
827 if (var->yres > var->yres_virtual) 827 if (var->yres > var->yres_virtual)
828 var->yres = var->yres_virtual; 828 var->yres = var->yres_virtual;
829 if (var->xres > var->xres_virtual) 829 if (var->xres > var->xres_virtual)
830 var->xres = var->xres_virtual; 830 var->xres = var->xres_virtual;
831 831
832 err = cyber2000fb_decode_clock(&hw, cfb, var); 832 err = cyber2000fb_decode_clock(&hw, cfb, var);
833 if (err) 833 if (err)
834 return err; 834 return err;
835 835
836 err = cyber2000fb_decode_crtc(&hw, cfb, var); 836 err = cyber2000fb_decode_crtc(&hw, cfb, var);
837 if (err) 837 if (err)
838 return err; 838 return err;
839 839
840 return 0; 840 return 0;
841 } 841 }
842 842
843 static int cyber2000fb_set_par(struct fb_info *info) 843 static int cyber2000fb_set_par(struct fb_info *info)
844 { 844 {
845 struct cfb_info *cfb = (struct cfb_info *)info; 845 struct cfb_info *cfb = (struct cfb_info *)info;
846 struct fb_var_screeninfo *var = &cfb->fb.var; 846 struct fb_var_screeninfo *var = &cfb->fb.var;
847 struct par_info hw; 847 struct par_info hw;
848 unsigned int mem; 848 unsigned int mem;
849 849
850 hw.width = var->xres_virtual; 850 hw.width = var->xres_virtual;
851 hw.ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT; 851 hw.ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT;
852 852
853 switch (var->bits_per_pixel) { 853 switch (var->bits_per_pixel) {
854 case 8: 854 case 8:
855 hw.co_pixfmt = CO_PIXFMT_8BPP; 855 hw.co_pixfmt = CO_PIXFMT_8BPP;
856 hw.pitch = hw.width >> 3; 856 hw.pitch = hw.width >> 3;
857 hw.extseqmisc = EXT_SEQ_MISC_8; 857 hw.extseqmisc = EXT_SEQ_MISC_8;
858 break; 858 break;
859 859
860 case 16: 860 case 16:
861 hw.co_pixfmt = CO_PIXFMT_16BPP; 861 hw.co_pixfmt = CO_PIXFMT_16BPP;
862 hw.pitch = hw.width >> 2; 862 hw.pitch = hw.width >> 2;
863 863
864 switch (var->green.length) { 864 switch (var->green.length) {
865 case 6: /* RGB565, 64k */ 865 case 6: /* RGB565, 64k */
866 hw.extseqmisc = EXT_SEQ_MISC_16_RGB565; 866 hw.extseqmisc = EXT_SEQ_MISC_16_RGB565;
867 break; 867 break;
868 case 5: /* RGB555, 32k */ 868 case 5: /* RGB555, 32k */
869 hw.extseqmisc = EXT_SEQ_MISC_16_RGB555; 869 hw.extseqmisc = EXT_SEQ_MISC_16_RGB555;
870 break; 870 break;
871 case 4: /* RGB444, 4k + transparency? */ 871 case 4: /* RGB444, 4k + transparency? */
872 hw.extseqmisc = EXT_SEQ_MISC_16_RGB444; 872 hw.extseqmisc = EXT_SEQ_MISC_16_RGB444;
873 break; 873 break;
874 default: 874 default:
875 BUG(); 875 BUG();
876 } 876 }
877 break; 877 break;
878 878
879 case 24:/* TRUECOLOUR, 16m */ 879 case 24:/* TRUECOLOUR, 16m */
880 hw.co_pixfmt = CO_PIXFMT_24BPP; 880 hw.co_pixfmt = CO_PIXFMT_24BPP;
881 hw.width *= 3; 881 hw.width *= 3;
882 hw.pitch = hw.width >> 3; 882 hw.pitch = hw.width >> 3;
883 hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN); 883 hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
884 hw.extseqmisc = EXT_SEQ_MISC_24_RGB888; 884 hw.extseqmisc = EXT_SEQ_MISC_24_RGB888;
885 break; 885 break;
886 886
887 case 32:/* TRUECOLOUR, 16m */ 887 case 32:/* TRUECOLOUR, 16m */
888 hw.co_pixfmt = CO_PIXFMT_32BPP; 888 hw.co_pixfmt = CO_PIXFMT_32BPP;
889 hw.pitch = hw.width >> 1; 889 hw.pitch = hw.width >> 1;
890 hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN); 890 hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
891 hw.extseqmisc = EXT_SEQ_MISC_32; 891 hw.extseqmisc = EXT_SEQ_MISC_32;
892 break; 892 break;
893 893
894 default: 894 default:
895 BUG(); 895 BUG();
896 } 896 }
897 897
898 /* 898 /*
899 * Sigh, this is absolutely disgusting, but caused by 899 * Sigh, this is absolutely disgusting, but caused by
900 * the way the fbcon developers want to separate out 900 * the way the fbcon developers want to separate out
901 * the "checking" and the "setting" of the video mode. 901 * the "checking" and the "setting" of the video mode.
902 * 902 *
903 * If the mode is not suitable for the hardware here, 903 * If the mode is not suitable for the hardware here,
904 * we can't prevent it being set by returning an error. 904 * we can't prevent it being set by returning an error.
905 * 905 *
906 * In theory, since NetWinders contain just one VGA card, 906 * In theory, since NetWinders contain just one VGA card,
907 * we should never end up hitting this problem. 907 * we should never end up hitting this problem.
908 */ 908 */
909 BUG_ON(cyber2000fb_decode_clock(&hw, cfb, var) != 0); 909 BUG_ON(cyber2000fb_decode_clock(&hw, cfb, var) != 0);
910 BUG_ON(cyber2000fb_decode_crtc(&hw, cfb, var) != 0); 910 BUG_ON(cyber2000fb_decode_crtc(&hw, cfb, var) != 0);
911 911
912 hw.width -= 1; 912 hw.width -= 1;
913 hw.fetch = hw.pitch; 913 hw.fetch = hw.pitch;
914 if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT)) 914 if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT))
915 hw.fetch <<= 1; 915 hw.fetch <<= 1;
916 hw.fetch += 1; 916 hw.fetch += 1;
917 917
918 cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; 918 cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
919 919
920 /* 920 /*
921 * Same here - if the size of the video mode exceeds the 921 * Same here - if the size of the video mode exceeds the
922 * available RAM, we can't prevent this mode being set. 922 * available RAM, we can't prevent this mode being set.
923 * 923 *
924 * In theory, since NetWinders contain just one VGA card, 924 * In theory, since NetWinders contain just one VGA card,
925 * we should never end up hitting this problem. 925 * we should never end up hitting this problem.
926 */ 926 */
927 mem = cfb->fb.fix.line_length * var->yres_virtual; 927 mem = cfb->fb.fix.line_length * var->yres_virtual;
928 BUG_ON(mem > cfb->fb.fix.smem_len); 928 BUG_ON(mem > cfb->fb.fix.smem_len);
929 929
930 /* 930 /*
931 * 8bpp displays are always pseudo colour. 16bpp and above 931 * 8bpp displays are always pseudo colour. 16bpp and above
932 * are direct colour or true colour, depending on whether 932 * are direct colour or true colour, depending on whether
933 * the RAMDAC palettes are bypassed. (Direct colour has 933 * the RAMDAC palettes are bypassed. (Direct colour has
934 * palettes, true colour does not.) 934 * palettes, true colour does not.)
935 */ 935 */
936 if (var->bits_per_pixel == 8) 936 if (var->bits_per_pixel == 8)
937 cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; 937 cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
938 else if (hw.ramdac & RAMDAC_BYPASS) 938 else if (hw.ramdac & RAMDAC_BYPASS)
939 cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; 939 cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
940 else 940 else
941 cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR; 941 cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
942 942
943 cyber2000fb_set_timing(cfb, &hw); 943 cyber2000fb_set_timing(cfb, &hw);
944 cyber2000fb_update_start(cfb, var); 944 cyber2000fb_update_start(cfb, var);
945 945
946 return 0; 946 return 0;
947 } 947 }
948 948
949 /* 949 /*
950 * Pan or Wrap the Display 950 * Pan or Wrap the Display
951 */ 951 */
952 static int 952 static int
953 cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 953 cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
954 { 954 {
955 struct cfb_info *cfb = (struct cfb_info *)info; 955 struct cfb_info *cfb = (struct cfb_info *)info;
956 956
957 if (cyber2000fb_update_start(cfb, var)) 957 if (cyber2000fb_update_start(cfb, var))
958 return -EINVAL; 958 return -EINVAL;
959 959
960 cfb->fb.var.xoffset = var->xoffset; 960 cfb->fb.var.xoffset = var->xoffset;
961 cfb->fb.var.yoffset = var->yoffset; 961 cfb->fb.var.yoffset = var->yoffset;
962 962
963 if (var->vmode & FB_VMODE_YWRAP) { 963 if (var->vmode & FB_VMODE_YWRAP) {
964 cfb->fb.var.vmode |= FB_VMODE_YWRAP; 964 cfb->fb.var.vmode |= FB_VMODE_YWRAP;
965 } else { 965 } else {
966 cfb->fb.var.vmode &= ~FB_VMODE_YWRAP; 966 cfb->fb.var.vmode &= ~FB_VMODE_YWRAP;
967 } 967 }
968 968
969 return 0; 969 return 0;
970 } 970 }
971 971
972 /* 972 /*
973 * (Un)Blank the display. 973 * (Un)Blank the display.
974 * 974 *
975 * Blank the screen if blank_mode != 0, else unblank. If 975 * Blank the screen if blank_mode != 0, else unblank. If
976 * blank == NULL then the caller blanks by setting the CLUT 976 * blank == NULL then the caller blanks by setting the CLUT
977 * (Color Look Up Table) to all black. Return 0 if blanking 977 * (Color Look Up Table) to all black. Return 0 if blanking
978 * succeeded, != 0 if un-/blanking failed due to e.g. a 978 * succeeded, != 0 if un-/blanking failed due to e.g. a
979 * video mode which doesn't support it. Implements VESA 979 * video mode which doesn't support it. Implements VESA
980 * suspend and powerdown modes on hardware that supports 980 * suspend and powerdown modes on hardware that supports
981 * disabling hsync/vsync: 981 * disabling hsync/vsync:
982 * blank_mode == 2: suspend vsync 982 * blank_mode == 2: suspend vsync
983 * blank_mode == 3: suspend hsync 983 * blank_mode == 3: suspend hsync
984 * blank_mode == 4: powerdown 984 * blank_mode == 4: powerdown
985 * 985 *
986 * wms...Enable VESA DMPS compatible powerdown mode 986 * wms...Enable VESA DMPS compatible powerdown mode
987 * run "setterm -powersave powerdown" to take advantage 987 * run "setterm -powersave powerdown" to take advantage
988 */ 988 */
989 static int cyber2000fb_blank(int blank, struct fb_info *info) 989 static int cyber2000fb_blank(int blank, struct fb_info *info)
990 { 990 {
991 struct cfb_info *cfb = (struct cfb_info *)info; 991 struct cfb_info *cfb = (struct cfb_info *)info;
992 unsigned int sync = 0; 992 unsigned int sync = 0;
993 int i; 993 int i;
994 994
995 switch (blank) { 995 switch (blank) {
996 case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */ 996 case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */
997 sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_0; 997 sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_0;
998 break; 998 break;
999 case FB_BLANK_HSYNC_SUSPEND: /* hsync off */ 999 case FB_BLANK_HSYNC_SUSPEND: /* hsync off */
1000 sync = EXT_SYNC_CTL_VS_NORMAL | EXT_SYNC_CTL_HS_0; 1000 sync = EXT_SYNC_CTL_VS_NORMAL | EXT_SYNC_CTL_HS_0;
1001 break; 1001 break;
1002 case FB_BLANK_VSYNC_SUSPEND: /* vsync off */ 1002 case FB_BLANK_VSYNC_SUSPEND: /* vsync off */
1003 sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_NORMAL; 1003 sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_NORMAL;
1004 break; 1004 break;
1005 case FB_BLANK_NORMAL: /* soft blank */ 1005 case FB_BLANK_NORMAL: /* soft blank */
1006 default: /* unblank */ 1006 default: /* unblank */
1007 break; 1007 break;
1008 } 1008 }
1009 1009
1010 cyber2000_grphw(EXT_SYNC_CTL, sync, cfb); 1010 cyber2000_grphw(EXT_SYNC_CTL, sync, cfb);
1011 1011
1012 if (blank <= 1) { 1012 if (blank <= 1) {
1013 /* turn on ramdacs */ 1013 /* turn on ramdacs */
1014 cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS | 1014 cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS |
1015 RAMDAC_RAMPWRDN); 1015 RAMDAC_RAMPWRDN);
1016 cyber2000fb_write_ramdac_ctrl(cfb); 1016 cyber2000fb_write_ramdac_ctrl(cfb);
1017 } 1017 }
1018 1018
1019 /* 1019 /*
1020 * Soft blank/unblank the display. 1020 * Soft blank/unblank the display.
1021 */ 1021 */
1022 if (blank) { /* soft blank */ 1022 if (blank) { /* soft blank */
1023 for (i = 0; i < NR_PALETTE; i++) { 1023 for (i = 0; i < NR_PALETTE; i++) {
1024 cyber2000fb_writeb(i, 0x3c8, cfb); 1024 cyber2000fb_writeb(i, 0x3c8, cfb);
1025 cyber2000fb_writeb(0, 0x3c9, cfb); 1025 cyber2000fb_writeb(0, 0x3c9, cfb);
1026 cyber2000fb_writeb(0, 0x3c9, cfb); 1026 cyber2000fb_writeb(0, 0x3c9, cfb);
1027 cyber2000fb_writeb(0, 0x3c9, cfb); 1027 cyber2000fb_writeb(0, 0x3c9, cfb);
1028 } 1028 }
1029 } else { /* unblank */ 1029 } else { /* unblank */
1030 for (i = 0; i < NR_PALETTE; i++) { 1030 for (i = 0; i < NR_PALETTE; i++) {
1031 cyber2000fb_writeb(i, 0x3c8, cfb); 1031 cyber2000fb_writeb(i, 0x3c8, cfb);
1032 cyber2000fb_writeb(cfb->palette[i].red, 0x3c9, cfb); 1032 cyber2000fb_writeb(cfb->palette[i].red, 0x3c9, cfb);
1033 cyber2000fb_writeb(cfb->palette[i].green, 0x3c9, cfb); 1033 cyber2000fb_writeb(cfb->palette[i].green, 0x3c9, cfb);
1034 cyber2000fb_writeb(cfb->palette[i].blue, 0x3c9, cfb); 1034 cyber2000fb_writeb(cfb->palette[i].blue, 0x3c9, cfb);
1035 } 1035 }
1036 } 1036 }
1037 1037
1038 if (blank >= 2) { 1038 if (blank >= 2) {
1039 /* turn off ramdacs */ 1039 /* turn off ramdacs */
1040 cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS | 1040 cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS |
1041 RAMDAC_RAMPWRDN; 1041 RAMDAC_RAMPWRDN;
1042 cyber2000fb_write_ramdac_ctrl(cfb); 1042 cyber2000fb_write_ramdac_ctrl(cfb);
1043 } 1043 }
1044 1044
1045 return 0; 1045 return 0;
1046 } 1046 }
1047 1047
1048 static struct fb_ops cyber2000fb_ops = { 1048 static struct fb_ops cyber2000fb_ops = {
1049 .owner = THIS_MODULE, 1049 .owner = THIS_MODULE,
1050 .fb_check_var = cyber2000fb_check_var, 1050 .fb_check_var = cyber2000fb_check_var,
1051 .fb_set_par = cyber2000fb_set_par, 1051 .fb_set_par = cyber2000fb_set_par,
1052 .fb_setcolreg = cyber2000fb_setcolreg, 1052 .fb_setcolreg = cyber2000fb_setcolreg,
1053 .fb_blank = cyber2000fb_blank, 1053 .fb_blank = cyber2000fb_blank,
1054 .fb_pan_display = cyber2000fb_pan_display, 1054 .fb_pan_display = cyber2000fb_pan_display,
1055 .fb_fillrect = cyber2000fb_fillrect, 1055 .fb_fillrect = cyber2000fb_fillrect,
1056 .fb_copyarea = cyber2000fb_copyarea, 1056 .fb_copyarea = cyber2000fb_copyarea,
1057 .fb_imageblit = cyber2000fb_imageblit, 1057 .fb_imageblit = cyber2000fb_imageblit,
1058 .fb_sync = cyber2000fb_sync, 1058 .fb_sync = cyber2000fb_sync,
1059 }; 1059 };
1060 1060
1061 /* 1061 /*
1062 * This is the only "static" reference to the internal data structures 1062 * This is the only "static" reference to the internal data structures
1063 * of this driver. It is here solely at the moment to support the other 1063 * of this driver. It is here solely at the moment to support the other
1064 * CyberPro modules external to this driver. 1064 * CyberPro modules external to this driver.
1065 */ 1065 */
1066 static struct cfb_info *int_cfb_info; 1066 static struct cfb_info *int_cfb_info;
1067 1067
1068 /* 1068 /*
1069 * Enable access to the extended registers 1069 * Enable access to the extended registers
1070 */ 1070 */
1071 void cyber2000fb_enable_extregs(struct cfb_info *cfb) 1071 void cyber2000fb_enable_extregs(struct cfb_info *cfb)
1072 { 1072 {
1073 cfb->func_use_count += 1; 1073 cfb->func_use_count += 1;
1074 1074
1075 if (cfb->func_use_count == 1) { 1075 if (cfb->func_use_count == 1) {
1076 int old; 1076 int old;
1077 1077
1078 old = cyber2000_grphr(EXT_FUNC_CTL, cfb); 1078 old = cyber2000_grphr(EXT_FUNC_CTL, cfb);
1079 old |= EXT_FUNC_CTL_EXTREGENBL; 1079 old |= EXT_FUNC_CTL_EXTREGENBL;
1080 cyber2000_grphw(EXT_FUNC_CTL, old, cfb); 1080 cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
1081 } 1081 }
1082 } 1082 }
1083 EXPORT_SYMBOL(cyber2000fb_enable_extregs); 1083 EXPORT_SYMBOL(cyber2000fb_enable_extregs);
1084 1084
1085 /* 1085 /*
1086 * Disable access to the extended registers 1086 * Disable access to the extended registers
1087 */ 1087 */
1088 void cyber2000fb_disable_extregs(struct cfb_info *cfb) 1088 void cyber2000fb_disable_extregs(struct cfb_info *cfb)
1089 { 1089 {
1090 if (cfb->func_use_count == 1) { 1090 if (cfb->func_use_count == 1) {
1091 int old; 1091 int old;
1092 1092
1093 old = cyber2000_grphr(EXT_FUNC_CTL, cfb); 1093 old = cyber2000_grphr(EXT_FUNC_CTL, cfb);
1094 old &= ~EXT_FUNC_CTL_EXTREGENBL; 1094 old &= ~EXT_FUNC_CTL_EXTREGENBL;
1095 cyber2000_grphw(EXT_FUNC_CTL, old, cfb); 1095 cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
1096 } 1096 }
1097 1097
1098 if (cfb->func_use_count == 0) 1098 if (cfb->func_use_count == 0)
1099 printk(KERN_ERR "disable_extregs: count = 0\n"); 1099 printk(KERN_ERR "disable_extregs: count = 0\n");
1100 else 1100 else
1101 cfb->func_use_count -= 1; 1101 cfb->func_use_count -= 1;
1102 } 1102 }
1103 EXPORT_SYMBOL(cyber2000fb_disable_extregs); 1103 EXPORT_SYMBOL(cyber2000fb_disable_extregs);
1104 1104
1105 void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var) 1105 void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
1106 { 1106 {
1107 memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo)); 1107 memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo));
1108 } 1108 }
1109 EXPORT_SYMBOL(cyber2000fb_get_fb_var); 1109 EXPORT_SYMBOL(cyber2000fb_get_fb_var);
1110 1110
1111 /* 1111 /*
1112 * Attach a capture/tv driver to the core CyberX0X0 driver. 1112 * Attach a capture/tv driver to the core CyberX0X0 driver.
1113 */ 1113 */
1114 int cyber2000fb_attach(struct cyberpro_info *info, int idx) 1114 int cyber2000fb_attach(struct cyberpro_info *info, int idx)
1115 { 1115 {
1116 if (int_cfb_info != NULL) { 1116 if (int_cfb_info != NULL) {
1117 info->dev = int_cfb_info->dev; 1117 info->dev = int_cfb_info->dev;
1118 info->regs = int_cfb_info->regs; 1118 info->regs = int_cfb_info->regs;
1119 info->fb = int_cfb_info->fb.screen_base; 1119 info->fb = int_cfb_info->fb.screen_base;
1120 info->fb_size = int_cfb_info->fb.fix.smem_len; 1120 info->fb_size = int_cfb_info->fb.fix.smem_len;
1121 info->enable_extregs = cyber2000fb_enable_extregs; 1121 info->enable_extregs = cyber2000fb_enable_extregs;
1122 info->disable_extregs = cyber2000fb_disable_extregs; 1122 info->disable_extregs = cyber2000fb_disable_extregs;
1123 info->info = int_cfb_info; 1123 info->info = int_cfb_info;
1124 1124
1125 strlcpy(info->dev_name, int_cfb_info->fb.fix.id, 1125 strlcpy(info->dev_name, int_cfb_info->fb.fix.id,
1126 sizeof(info->dev_name)); 1126 sizeof(info->dev_name));
1127 } 1127 }
1128 1128
1129 return int_cfb_info != NULL; 1129 return int_cfb_info != NULL;
1130 } 1130 }
1131 EXPORT_SYMBOL(cyber2000fb_attach); 1131 EXPORT_SYMBOL(cyber2000fb_attach);
1132 1132
1133 /* 1133 /*
1134 * Detach a capture/tv driver from the core CyberX0X0 driver. 1134 * Detach a capture/tv driver from the core CyberX0X0 driver.
1135 */ 1135 */
1136 void cyber2000fb_detach(int idx) 1136 void cyber2000fb_detach(int idx)
1137 { 1137 {
1138 } 1138 }
1139 EXPORT_SYMBOL(cyber2000fb_detach); 1139 EXPORT_SYMBOL(cyber2000fb_detach);
1140 1140
1141 /* 1141 /*
1142 * These parameters give 1142 * These parameters give
1143 * 640x480, hsync 31.5kHz, vsync 60Hz 1143 * 640x480, hsync 31.5kHz, vsync 60Hz
1144 */ 1144 */
1145 static struct fb_videomode __devinitdata cyber2000fb_default_mode = { 1145 static struct fb_videomode __devinitdata cyber2000fb_default_mode = {
1146 .refresh = 60, 1146 .refresh = 60,
1147 .xres = 640, 1147 .xres = 640,
1148 .yres = 480, 1148 .yres = 480,
1149 .pixclock = 39722, 1149 .pixclock = 39722,
1150 .left_margin = 56, 1150 .left_margin = 56,
1151 .right_margin = 16, 1151 .right_margin = 16,
1152 .upper_margin = 34, 1152 .upper_margin = 34,
1153 .lower_margin = 9, 1153 .lower_margin = 9,
1154 .hsync_len = 88, 1154 .hsync_len = 88,
1155 .vsync_len = 2, 1155 .vsync_len = 2,
1156 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1156 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
1157 .vmode = FB_VMODE_NONINTERLACED 1157 .vmode = FB_VMODE_NONINTERLACED
1158 }; 1158 };
1159 1159
1160 static char igs_regs[] = { 1160 static char igs_regs[] = {
1161 EXT_CRT_IRQ, 0, 1161 EXT_CRT_IRQ, 0,
1162 EXT_CRT_TEST, 0, 1162 EXT_CRT_TEST, 0,
1163 EXT_SYNC_CTL, 0, 1163 EXT_SYNC_CTL, 0,
1164 EXT_SEG_WRITE_PTR, 0, 1164 EXT_SEG_WRITE_PTR, 0,
1165 EXT_SEG_READ_PTR, 0, 1165 EXT_SEG_READ_PTR, 0,
1166 EXT_BIU_MISC, EXT_BIU_MISC_LIN_ENABLE | 1166 EXT_BIU_MISC, EXT_BIU_MISC_LIN_ENABLE |
1167 EXT_BIU_MISC_COP_ENABLE | 1167 EXT_BIU_MISC_COP_ENABLE |
1168 EXT_BIU_MISC_COP_BFC, 1168 EXT_BIU_MISC_COP_BFC,
1169 EXT_FUNC_CTL, 0, 1169 EXT_FUNC_CTL, 0,
1170 CURS_H_START, 0, 1170 CURS_H_START, 0,
1171 CURS_H_START + 1, 0, 1171 CURS_H_START + 1, 0,
1172 CURS_H_PRESET, 0, 1172 CURS_H_PRESET, 0,
1173 CURS_V_START, 0, 1173 CURS_V_START, 0,
1174 CURS_V_START + 1, 0, 1174 CURS_V_START + 1, 0,
1175 CURS_V_PRESET, 0, 1175 CURS_V_PRESET, 0,
1176 CURS_CTL, 0, 1176 CURS_CTL, 0,
1177 EXT_ATTRIB_CTL, EXT_ATTRIB_CTL_EXT, 1177 EXT_ATTRIB_CTL, EXT_ATTRIB_CTL_EXT,
1178 EXT_OVERSCAN_RED, 0, 1178 EXT_OVERSCAN_RED, 0,
1179 EXT_OVERSCAN_GREEN, 0, 1179 EXT_OVERSCAN_GREEN, 0,
1180 EXT_OVERSCAN_BLUE, 0, 1180 EXT_OVERSCAN_BLUE, 0,
1181 1181
1182 /* some of these are questionable when we have a BIOS */ 1182 /* some of these are questionable when we have a BIOS */
1183 EXT_MEM_CTL0, EXT_MEM_CTL0_7CLK | 1183 EXT_MEM_CTL0, EXT_MEM_CTL0_7CLK |
1184 EXT_MEM_CTL0_RAS_1 | 1184 EXT_MEM_CTL0_RAS_1 |
1185 EXT_MEM_CTL0_MULTCAS, 1185 EXT_MEM_CTL0_MULTCAS,
1186 EXT_HIDDEN_CTL1, 0x30, 1186 EXT_HIDDEN_CTL1, 0x30,
1187 EXT_FIFO_CTL, 0x0b, 1187 EXT_FIFO_CTL, 0x0b,
1188 EXT_FIFO_CTL + 1, 0x17, 1188 EXT_FIFO_CTL + 1, 0x17,
1189 0x76, 0x00, 1189 0x76, 0x00,
1190 EXT_HIDDEN_CTL4, 0xc8 1190 EXT_HIDDEN_CTL4, 0xc8
1191 }; 1191 };
1192 1192
1193 /* 1193 /*
1194 * Initialise the CyberPro hardware. On the CyberPro5XXXX, 1194 * Initialise the CyberPro hardware. On the CyberPro5XXXX,
1195 * ensure that we're using the correct PLL (5XXX's may be 1195 * ensure that we're using the correct PLL (5XXX's may be
1196 * programmed to use an additional set of PLLs.) 1196 * programmed to use an additional set of PLLs.)
1197 */ 1197 */
1198 static void cyberpro_init_hw(struct cfb_info *cfb) 1198 static void cyberpro_init_hw(struct cfb_info *cfb)
1199 { 1199 {
1200 int i; 1200 int i;
1201 1201
1202 for (i = 0; i < sizeof(igs_regs); i += 2) 1202 for (i = 0; i < sizeof(igs_regs); i += 2)
1203 cyber2000_grphw(igs_regs[i], igs_regs[i + 1], cfb); 1203 cyber2000_grphw(igs_regs[i], igs_regs[i + 1], cfb);
1204 1204
1205 if (cfb->id == ID_CYBERPRO_5000) { 1205 if (cfb->id == ID_CYBERPRO_5000) {
1206 unsigned char val; 1206 unsigned char val;
1207 cyber2000fb_writeb(0xba, 0x3ce, cfb); 1207 cyber2000fb_writeb(0xba, 0x3ce, cfb);
1208 val = cyber2000fb_readb(0x3cf, cfb) & 0x80; 1208 val = cyber2000fb_readb(0x3cf, cfb) & 0x80;
1209 cyber2000fb_writeb(val, 0x3cf, cfb); 1209 cyber2000fb_writeb(val, 0x3cf, cfb);
1210 } 1210 }
1211 } 1211 }
1212 1212
1213 static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id, 1213 static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id,
1214 char *name) 1214 char *name)
1215 { 1215 {
1216 struct cfb_info *cfb; 1216 struct cfb_info *cfb;
1217 1217
1218 cfb = kzalloc(sizeof(struct cfb_info), GFP_KERNEL); 1218 cfb = kzalloc(sizeof(struct cfb_info), GFP_KERNEL);
1219 if (!cfb) 1219 if (!cfb)
1220 return NULL; 1220 return NULL;
1221 1221
1222 1222
1223 cfb->id = id; 1223 cfb->id = id;
1224 1224
1225 if (id == ID_CYBERPRO_5000) 1225 if (id == ID_CYBERPRO_5000)
1226 cfb->ref_ps = 40690; /* 24.576 MHz */ 1226 cfb->ref_ps = 40690; /* 24.576 MHz */
1227 else 1227 else
1228 cfb->ref_ps = 69842; /* 14.31818 MHz (69841?) */ 1228 cfb->ref_ps = 69842; /* 14.31818 MHz (69841?) */
1229 1229
1230 cfb->divisors[0] = 1; 1230 cfb->divisors[0] = 1;
1231 cfb->divisors[1] = 2; 1231 cfb->divisors[1] = 2;
1232 cfb->divisors[2] = 4; 1232 cfb->divisors[2] = 4;
1233 1233
1234 if (id == ID_CYBERPRO_2000) 1234 if (id == ID_CYBERPRO_2000)
1235 cfb->divisors[3] = 8; 1235 cfb->divisors[3] = 8;
1236 else 1236 else
1237 cfb->divisors[3] = 6; 1237 cfb->divisors[3] = 6;
1238 1238
1239 strcpy(cfb->fb.fix.id, name); 1239 strcpy(cfb->fb.fix.id, name);
1240 1240
1241 cfb->fb.fix.type = FB_TYPE_PACKED_PIXELS; 1241 cfb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
1242 cfb->fb.fix.type_aux = 0; 1242 cfb->fb.fix.type_aux = 0;
1243 cfb->fb.fix.xpanstep = 0; 1243 cfb->fb.fix.xpanstep = 0;
1244 cfb->fb.fix.ypanstep = 1; 1244 cfb->fb.fix.ypanstep = 1;
1245 cfb->fb.fix.ywrapstep = 0; 1245 cfb->fb.fix.ywrapstep = 0;
1246 1246
1247 switch (id) { 1247 switch (id) {
1248 case ID_IGA_1682: 1248 case ID_IGA_1682:
1249 cfb->fb.fix.accel = 0; 1249 cfb->fb.fix.accel = 0;
1250 break; 1250 break;
1251 1251
1252 case ID_CYBERPRO_2000: 1252 case ID_CYBERPRO_2000:
1253 cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2000; 1253 cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2000;
1254 break; 1254 break;
1255 1255
1256 case ID_CYBERPRO_2010: 1256 case ID_CYBERPRO_2010:
1257 cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2010; 1257 cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2010;
1258 break; 1258 break;
1259 1259
1260 case ID_CYBERPRO_5000: 1260 case ID_CYBERPRO_5000:
1261 cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER5000; 1261 cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER5000;
1262 break; 1262 break;
1263 } 1263 }
1264 1264
1265 cfb->fb.var.nonstd = 0; 1265 cfb->fb.var.nonstd = 0;
1266 cfb->fb.var.activate = FB_ACTIVATE_NOW; 1266 cfb->fb.var.activate = FB_ACTIVATE_NOW;
1267 cfb->fb.var.height = -1; 1267 cfb->fb.var.height = -1;
1268 cfb->fb.var.width = -1; 1268 cfb->fb.var.width = -1;
1269 cfb->fb.var.accel_flags = FB_ACCELF_TEXT; 1269 cfb->fb.var.accel_flags = FB_ACCELF_TEXT;
1270 1270
1271 cfb->fb.fbops = &cyber2000fb_ops; 1271 cfb->fb.fbops = &cyber2000fb_ops;
1272 cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1272 cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1273 cfb->fb.pseudo_palette = cfb->pseudo_palette; 1273 cfb->fb.pseudo_palette = cfb->pseudo_palette;
1274 1274
1275 fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0); 1275 fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
1276 1276
1277 return cfb; 1277 return cfb;
1278 } 1278 }
1279 1279
1280 static void cyberpro_free_fb_info(struct cfb_info *cfb) 1280 static void cyberpro_free_fb_info(struct cfb_info *cfb)
1281 { 1281 {
1282 if (cfb) { 1282 if (cfb) {
1283 /* 1283 /*
1284 * Free the colourmap 1284 * Free the colourmap
1285 */ 1285 */
1286 fb_alloc_cmap(&cfb->fb.cmap, 0, 0); 1286 fb_alloc_cmap(&cfb->fb.cmap, 0, 0);
1287 1287
1288 kfree(cfb); 1288 kfree(cfb);
1289 } 1289 }
1290 } 1290 }
1291 1291
1292 /* 1292 /*
1293 * Parse Cyber2000fb options. Usage: 1293 * Parse Cyber2000fb options. Usage:
1294 * video=cyber2000:font:fontname 1294 * video=cyber2000:font:fontname
1295 */ 1295 */
1296 #ifndef MODULE 1296 #ifndef MODULE
1297 static int cyber2000fb_setup(char *options) 1297 static int cyber2000fb_setup(char *options)
1298 { 1298 {
1299 char *opt; 1299 char *opt;
1300 1300
1301 if (!options || !*options) 1301 if (!options || !*options)
1302 return 0; 1302 return 0;
1303 1303
1304 while ((opt = strsep(&options, ",")) != NULL) { 1304 while ((opt = strsep(&options, ",")) != NULL) {
1305 if (!*opt) 1305 if (!*opt)
1306 continue; 1306 continue;
1307 1307
1308 if (strncmp(opt, "font:", 5) == 0) { 1308 if (strncmp(opt, "font:", 5) == 0) {
1309 static char default_font_storage[40]; 1309 static char default_font_storage[40];
1310 1310
1311 strlcpy(default_font_storage, opt + 5, 1311 strlcpy(default_font_storage, opt + 5,
1312 sizeof(default_font_storage)); 1312 sizeof(default_font_storage));
1313 default_font = default_font_storage; 1313 default_font = default_font_storage;
1314 continue; 1314 continue;
1315 } 1315 }
1316 1316
1317 printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n", opt); 1317 printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n", opt);
1318 } 1318 }
1319 return 0; 1319 return 0;
1320 } 1320 }
1321 #endif /* MODULE */ 1321 #endif /* MODULE */
1322 1322
1323 /* 1323 /*
1324 * The CyberPro chips can be placed on many different bus types. 1324 * The CyberPro chips can be placed on many different bus types.
1325 * This probe function is common to all bus types. The bus-specific 1325 * This probe function is common to all bus types. The bus-specific
1326 * probe function is expected to have: 1326 * probe function is expected to have:
1327 * - enabled access to the linear memory region 1327 * - enabled access to the linear memory region
1328 * - memory mapped access to the registers 1328 * - memory mapped access to the registers
1329 * - initialised mem_ctl1 and mem_ctl2 appropriately. 1329 * - initialised mem_ctl1 and mem_ctl2 appropriately.
1330 */ 1330 */
1331 static int __devinit cyberpro_common_probe(struct cfb_info *cfb) 1331 static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
1332 { 1332 {
1333 u_long smem_size; 1333 u_long smem_size;
1334 u_int h_sync, v_sync; 1334 u_int h_sync, v_sync;
1335 int err; 1335 int err;
1336 1336
1337 cyberpro_init_hw(cfb); 1337 cyberpro_init_hw(cfb);
1338 1338
1339 /* 1339 /*
1340 * Get the video RAM size and width from the VGA register. 1340 * Get the video RAM size and width from the VGA register.
1341 * This should have been already initialised by the BIOS, 1341 * This should have been already initialised by the BIOS,
1342 * but if it's garbage, claim default 1MB VRAM (woody) 1342 * but if it's garbage, claim default 1MB VRAM (woody)
1343 */ 1343 */
1344 cfb->mem_ctl1 = cyber2000_grphr(EXT_MEM_CTL1, cfb); 1344 cfb->mem_ctl1 = cyber2000_grphr(EXT_MEM_CTL1, cfb);
1345 cfb->mem_ctl2 = cyber2000_grphr(EXT_MEM_CTL2, cfb); 1345 cfb->mem_ctl2 = cyber2000_grphr(EXT_MEM_CTL2, cfb);
1346 1346
1347 /* 1347 /*
1348 * Determine the size of the memory. 1348 * Determine the size of the memory.
1349 */ 1349 */
1350 switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) { 1350 switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) {
1351 case MEM_CTL2_SIZE_4MB: 1351 case MEM_CTL2_SIZE_4MB:
1352 smem_size = 0x00400000; 1352 smem_size = 0x00400000;
1353 break; 1353 break;
1354 case MEM_CTL2_SIZE_2MB: 1354 case MEM_CTL2_SIZE_2MB:
1355 smem_size = 0x00200000; 1355 smem_size = 0x00200000;
1356 break; 1356 break;
1357 case MEM_CTL2_SIZE_1MB: 1357 case MEM_CTL2_SIZE_1MB:
1358 smem_size = 0x00100000; 1358 smem_size = 0x00100000;
1359 break; 1359 break;
1360 default: 1360 default:
1361 smem_size = 0x00100000; 1361 smem_size = 0x00100000;
1362 break; 1362 break;
1363 } 1363 }
1364 1364
1365 cfb->fb.fix.smem_len = smem_size; 1365 cfb->fb.fix.smem_len = smem_size;
1366 cfb->fb.fix.mmio_len = MMIO_SIZE; 1366 cfb->fb.fix.mmio_len = MMIO_SIZE;
1367 cfb->fb.screen_base = cfb->region; 1367 cfb->fb.screen_base = cfb->region;
1368 1368
1369 err = -EINVAL; 1369 err = -EINVAL;
1370 if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0, 1370 if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
1371 &cyber2000fb_default_mode, 8)) { 1371 &cyber2000fb_default_mode, 8)) {
1372 printk(KERN_ERR "%s: no valid mode found\n", cfb->fb.fix.id); 1372 printk(KERN_ERR "%s: no valid mode found\n", cfb->fb.fix.id);
1373 goto failed; 1373 goto failed;
1374 } 1374 }
1375 1375
1376 cfb->fb.var.yres_virtual = cfb->fb.fix.smem_len * 8 / 1376 cfb->fb.var.yres_virtual = cfb->fb.fix.smem_len * 8 /
1377 (cfb->fb.var.bits_per_pixel * cfb->fb.var.xres_virtual); 1377 (cfb->fb.var.bits_per_pixel * cfb->fb.var.xres_virtual);
1378 1378
1379 if (cfb->fb.var.yres_virtual < cfb->fb.var.yres) 1379 if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
1380 cfb->fb.var.yres_virtual = cfb->fb.var.yres; 1380 cfb->fb.var.yres_virtual = cfb->fb.var.yres;
1381 1381
1382 /* fb_set_var(&cfb->fb.var, -1, &cfb->fb); */ 1382 /* fb_set_var(&cfb->fb.var, -1, &cfb->fb); */
1383 1383
1384 /* 1384 /*
1385 * Calculate the hsync and vsync frequencies. Note that 1385 * Calculate the hsync and vsync frequencies. Note that
1386 * we split the 1e12 constant up so that we can preserve 1386 * we split the 1e12 constant up so that we can preserve
1387 * the precision and fit the results into 32-bit registers. 1387 * the precision and fit the results into 32-bit registers.
1388 * (1953125000 * 512 = 1e12) 1388 * (1953125000 * 512 = 1e12)
1389 */ 1389 */
1390 h_sync = 1953125000 / cfb->fb.var.pixclock; 1390 h_sync = 1953125000 / cfb->fb.var.pixclock;
1391 h_sync = h_sync * 512 / (cfb->fb.var.xres + cfb->fb.var.left_margin + 1391 h_sync = h_sync * 512 / (cfb->fb.var.xres + cfb->fb.var.left_margin +
1392 cfb->fb.var.right_margin + cfb->fb.var.hsync_len); 1392 cfb->fb.var.right_margin + cfb->fb.var.hsync_len);
1393 v_sync = h_sync / (cfb->fb.var.yres + cfb->fb.var.upper_margin + 1393 v_sync = h_sync / (cfb->fb.var.yres + cfb->fb.var.upper_margin +
1394 cfb->fb.var.lower_margin + cfb->fb.var.vsync_len); 1394 cfb->fb.var.lower_margin + cfb->fb.var.vsync_len);
1395 1395
1396 printk(KERN_INFO "%s: %dKiB VRAM, using %dx%d, %d.%03dkHz, %dHz\n", 1396 printk(KERN_INFO "%s: %dKiB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
1397 cfb->fb.fix.id, cfb->fb.fix.smem_len >> 10, 1397 cfb->fb.fix.id, cfb->fb.fix.smem_len >> 10,
1398 cfb->fb.var.xres, cfb->fb.var.yres, 1398 cfb->fb.var.xres, cfb->fb.var.yres,
1399 h_sync / 1000, h_sync % 1000, v_sync); 1399 h_sync / 1000, h_sync % 1000, v_sync);
1400 1400
1401 if (cfb->dev) 1401 if (cfb->dev)
1402 cfb->fb.device = &cfb->dev->dev; 1402 cfb->fb.device = &cfb->dev->dev;
1403 err = register_framebuffer(&cfb->fb); 1403 err = register_framebuffer(&cfb->fb);
1404 1404
1405 failed: 1405 failed:
1406 return err; 1406 return err;
1407 } 1407 }
1408 1408
1409 static void cyberpro_common_resume(struct cfb_info *cfb) 1409 static void cyberpro_common_resume(struct cfb_info *cfb)
1410 { 1410 {
1411 cyberpro_init_hw(cfb); 1411 cyberpro_init_hw(cfb);
1412 1412
1413 /* 1413 /*
1414 * Reprogram the MEM_CTL1 and MEM_CTL2 registers 1414 * Reprogram the MEM_CTL1 and MEM_CTL2 registers
1415 */ 1415 */
1416 cyber2000_grphw(EXT_MEM_CTL1, cfb->mem_ctl1, cfb); 1416 cyber2000_grphw(EXT_MEM_CTL1, cfb->mem_ctl1, cfb);
1417 cyber2000_grphw(EXT_MEM_CTL2, cfb->mem_ctl2, cfb); 1417 cyber2000_grphw(EXT_MEM_CTL2, cfb->mem_ctl2, cfb);
1418 1418
1419 /* 1419 /*
1420 * Restore the old video mode and the palette. 1420 * Restore the old video mode and the palette.
1421 * We also need to tell fbcon to redraw the console. 1421 * We also need to tell fbcon to redraw the console.
1422 */ 1422 */
1423 cyber2000fb_set_par(&cfb->fb); 1423 cyber2000fb_set_par(&cfb->fb);
1424 } 1424 }
1425 1425
1426 #ifdef CONFIG_ARCH_SHARK 1426 #ifdef CONFIG_ARCH_SHARK
1427 1427
1428 #include <mach/framebuffer.h> 1428 #include <mach/framebuffer.h>
1429 1429
1430 static int __devinit cyberpro_vl_probe(void) 1430 static int __devinit cyberpro_vl_probe(void)
1431 { 1431 {
1432 struct cfb_info *cfb; 1432 struct cfb_info *cfb;
1433 int err = -ENOMEM; 1433 int err = -ENOMEM;
1434 1434
1435 if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010")) 1435 if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010"))
1436 return err; 1436 return err;
1437 1437
1438 cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010"); 1438 cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010");
1439 if (!cfb) 1439 if (!cfb)
1440 goto failed_release; 1440 goto failed_release;
1441 1441
1442 cfb->dev = NULL; 1442 cfb->dev = NULL;
1443 cfb->region = ioremap(FB_START, FB_SIZE); 1443 cfb->region = ioremap(FB_START, FB_SIZE);
1444 if (!cfb->region) 1444 if (!cfb->region)
1445 goto failed_ioremap; 1445 goto failed_ioremap;
1446 1446
1447 cfb->regs = cfb->region + MMIO_OFFSET; 1447 cfb->regs = cfb->region + MMIO_OFFSET;
1448 cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET; 1448 cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET;
1449 cfb->fb.fix.smem_start = FB_START; 1449 cfb->fb.fix.smem_start = FB_START;
1450 1450
1451 /* 1451 /*
1452 * Bring up the hardware. This is expected to enable access 1452 * Bring up the hardware. This is expected to enable access
1453 * to the linear memory region, and allow access to the memory 1453 * to the linear memory region, and allow access to the memory
1454 * mapped registers. Also, mem_ctl1 and mem_ctl2 must be 1454 * mapped registers. Also, mem_ctl1 and mem_ctl2 must be
1455 * initialised. 1455 * initialised.
1456 */ 1456 */
1457 cyber2000fb_writeb(0x18, 0x46e8, cfb); 1457 cyber2000fb_writeb(0x18, 0x46e8, cfb);
1458 cyber2000fb_writeb(0x01, 0x102, cfb); 1458 cyber2000fb_writeb(0x01, 0x102, cfb);
1459 cyber2000fb_writeb(0x08, 0x46e8, cfb); 1459 cyber2000fb_writeb(0x08, 0x46e8, cfb);
1460 cyber2000fb_writeb(EXT_BIU_MISC, 0x3ce, cfb); 1460 cyber2000fb_writeb(EXT_BIU_MISC, 0x3ce, cfb);
1461 cyber2000fb_writeb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf, cfb); 1461 cyber2000fb_writeb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf, cfb);
1462 1462
1463 cfb->mclk_mult = 0xdb; 1463 cfb->mclk_mult = 0xdb;
1464 cfb->mclk_div = 0x54; 1464 cfb->mclk_div = 0x54;
1465 1465
1466 err = cyberpro_common_probe(cfb); 1466 err = cyberpro_common_probe(cfb);
1467 if (err) 1467 if (err)
1468 goto failed; 1468 goto failed;
1469 1469
1470 if (int_cfb_info == NULL) 1470 if (int_cfb_info == NULL)
1471 int_cfb_info = cfb; 1471 int_cfb_info = cfb;
1472 1472
1473 return 0; 1473 return 0;
1474 1474
1475 failed: 1475 failed:
1476 iounmap(cfb->region); 1476 iounmap(cfb->region);
1477 failed_ioremap: 1477 failed_ioremap:
1478 cyberpro_free_fb_info(cfb); 1478 cyberpro_free_fb_info(cfb);
1479 failed_release: 1479 failed_release:
1480 release_mem_region(FB_START, FB_SIZE); 1480 release_mem_region(FB_START, FB_SIZE);
1481 1481
1482 return err; 1482 return err;
1483 } 1483 }
1484 #endif /* CONFIG_ARCH_SHARK */ 1484 #endif /* CONFIG_ARCH_SHARK */
1485 1485
1486 /* 1486 /*
1487 * PCI specific support. 1487 * PCI specific support.
1488 */ 1488 */
1489 #ifdef CONFIG_PCI 1489 #ifdef CONFIG_PCI
1490 /* 1490 /*
1491 * We need to wake up the CyberPro, and make sure its in linear memory 1491 * We need to wake up the CyberPro, and make sure its in linear memory
1492 * mode. Unfortunately, this is specific to the platform and card that 1492 * mode. Unfortunately, this is specific to the platform and card that
1493 * we are running on. 1493 * we are running on.
1494 * 1494 *
1495 * On x86 and ARM, should we be initialising the CyberPro first via the 1495 * On x86 and ARM, should we be initialising the CyberPro first via the
1496 * IO registers, and then the MMIO registers to catch all cases? Can we 1496 * IO registers, and then the MMIO registers to catch all cases? Can we
1497 * end up in the situation where the chip is in MMIO mode, but not awake 1497 * end up in the situation where the chip is in MMIO mode, but not awake
1498 * on an x86 system? 1498 * on an x86 system?
1499 */ 1499 */
1500 static int cyberpro_pci_enable_mmio(struct cfb_info *cfb) 1500 static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
1501 { 1501 {
1502 unsigned char val; 1502 unsigned char val;
1503 1503
1504 #if defined(__sparc_v9__) 1504 #if defined(__sparc_v9__)
1505 #error "You lose, consult DaveM." 1505 #error "You lose, consult DaveM."
1506 #elif defined(__sparc__) 1506 #elif defined(__sparc__)
1507 /* 1507 /*
1508 * SPARC does not have an "outb" instruction, so we generate 1508 * SPARC does not have an "outb" instruction, so we generate
1509 * I/O cycles storing into a reserved memory space at 1509 * I/O cycles storing into a reserved memory space at
1510 * physical address 0x3000000 1510 * physical address 0x3000000
1511 */ 1511 */
1512 unsigned char __iomem *iop; 1512 unsigned char __iomem *iop;
1513 1513
1514 iop = ioremap(0x3000000, 0x5000); 1514 iop = ioremap(0x3000000, 0x5000);
1515 if (iop == NULL) { 1515 if (iop == NULL) {
1516 printk(KERN_ERR "iga5000: cannot map I/O\n"); 1516 printk(KERN_ERR "iga5000: cannot map I/O\n");
1517 return -ENOMEM; 1517 return -ENOMEM;
1518 } 1518 }
1519 1519
1520 writeb(0x18, iop + 0x46e8); 1520 writeb(0x18, iop + 0x46e8);
1521 writeb(0x01, iop + 0x102); 1521 writeb(0x01, iop + 0x102);
1522 writeb(0x08, iop + 0x46e8); 1522 writeb(0x08, iop + 0x46e8);
1523 writeb(EXT_BIU_MISC, iop + 0x3ce); 1523 writeb(EXT_BIU_MISC, iop + 0x3ce);
1524 writeb(EXT_BIU_MISC_LIN_ENABLE, iop + 0x3cf); 1524 writeb(EXT_BIU_MISC_LIN_ENABLE, iop + 0x3cf);
1525 1525
1526 iounmap(iop); 1526 iounmap(iop);
1527 #else 1527 #else
1528 /* 1528 /*
1529 * Most other machine types are "normal", so 1529 * Most other machine types are "normal", so
1530 * we use the standard IO-based wakeup. 1530 * we use the standard IO-based wakeup.
1531 */ 1531 */
1532 outb(0x18, 0x46e8); 1532 outb(0x18, 0x46e8);
1533 outb(0x01, 0x102); 1533 outb(0x01, 0x102);
1534 outb(0x08, 0x46e8); 1534 outb(0x08, 0x46e8);
1535 outb(EXT_BIU_MISC, 0x3ce); 1535 outb(EXT_BIU_MISC, 0x3ce);
1536 outb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf); 1536 outb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf);
1537 #endif 1537 #endif
1538 1538
1539 /* 1539 /*
1540 * Allow the CyberPro to accept PCI burst accesses 1540 * Allow the CyberPro to accept PCI burst accesses
1541 */ 1541 */
1542 if (cfb->id == ID_CYBERPRO_2010) { 1542 if (cfb->id == ID_CYBERPRO_2010) {
1543 printk(KERN_INFO "%s: NOT enabling PCI bursts\n", 1543 printk(KERN_INFO "%s: NOT enabling PCI bursts\n",
1544 cfb->fb.fix.id); 1544 cfb->fb.fix.id);
1545 } else { 1545 } else {
1546 val = cyber2000_grphr(EXT_BUS_CTL, cfb); 1546 val = cyber2000_grphr(EXT_BUS_CTL, cfb);
1547 if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) { 1547 if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
1548 printk(KERN_INFO "%s: enabling PCI bursts\n", 1548 printk(KERN_INFO "%s: enabling PCI bursts\n",
1549 cfb->fb.fix.id); 1549 cfb->fb.fix.id);
1550 1550
1551 val |= EXT_BUS_CTL_PCIBURST_WRITE; 1551 val |= EXT_BUS_CTL_PCIBURST_WRITE;
1552 1552
1553 if (cfb->id == ID_CYBERPRO_5000) 1553 if (cfb->id == ID_CYBERPRO_5000)
1554 val |= EXT_BUS_CTL_PCIBURST_READ; 1554 val |= EXT_BUS_CTL_PCIBURST_READ;
1555 1555
1556 cyber2000_grphw(EXT_BUS_CTL, val, cfb); 1556 cyber2000_grphw(EXT_BUS_CTL, val, cfb);
1557 } 1557 }
1558 } 1558 }
1559 1559
1560 return 0; 1560 return 0;
1561 } 1561 }
1562 1562
1563 static int __devinit 1563 static int __devinit
1564 cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 1564 cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1565 { 1565 {
1566 struct cfb_info *cfb; 1566 struct cfb_info *cfb;
1567 char name[16]; 1567 char name[16];
1568 int err; 1568 int err;
1569 1569
1570 sprintf(name, "CyberPro%4X", id->device); 1570 sprintf(name, "CyberPro%4X", id->device);
1571 1571
1572 err = pci_enable_device(dev); 1572 err = pci_enable_device(dev);
1573 if (err) 1573 if (err)
1574 return err; 1574 return err;
1575 1575
1576 err = pci_request_regions(dev, name);
1577 if (err)
1578 return err;
1579
1580 err = -ENOMEM; 1576 err = -ENOMEM;
1581 cfb = cyberpro_alloc_fb_info(id->driver_data, name); 1577 cfb = cyberpro_alloc_fb_info(id->driver_data, name);
1582 if (!cfb) 1578 if (!cfb)
1583 goto failed_release; 1579 goto failed_release;
1584 1580
1581 err = pci_request_regions(dev, cfb->fb.fix.id);
1582 if (err)
1583 goto failed_regions;
1584
1585 cfb->dev = dev; 1585 cfb->dev = dev;
1586 cfb->region = pci_ioremap_bar(dev, 0); 1586 cfb->region = pci_ioremap_bar(dev, 0);
1587 if (!cfb->region) 1587 if (!cfb->region)
1588 goto failed_ioremap; 1588 goto failed_ioremap;
1589 1589
1590 cfb->regs = cfb->region + MMIO_OFFSET; 1590 cfb->regs = cfb->region + MMIO_OFFSET;
1591 cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET; 1591 cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
1592 cfb->fb.fix.smem_start = pci_resource_start(dev, 0); 1592 cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
1593 1593
1594 /* 1594 /*
1595 * Bring up the hardware. This is expected to enable access 1595 * Bring up the hardware. This is expected to enable access
1596 * to the linear memory region, and allow access to the memory 1596 * to the linear memory region, and allow access to the memory
1597 * mapped registers. Also, mem_ctl1 and mem_ctl2 must be 1597 * mapped registers. Also, mem_ctl1 and mem_ctl2 must be
1598 * initialised. 1598 * initialised.
1599 */ 1599 */
1600 err = cyberpro_pci_enable_mmio(cfb); 1600 err = cyberpro_pci_enable_mmio(cfb);
1601 if (err) 1601 if (err)
1602 goto failed; 1602 goto failed;
1603 1603
1604 /* 1604 /*
1605 * Use MCLK from BIOS. FIXME: what about hotplug? 1605 * Use MCLK from BIOS. FIXME: what about hotplug?
1606 */ 1606 */
1607 cfb->mclk_mult = cyber2000_grphr(EXT_MCLK_MULT, cfb); 1607 cfb->mclk_mult = cyber2000_grphr(EXT_MCLK_MULT, cfb);
1608 cfb->mclk_div = cyber2000_grphr(EXT_MCLK_DIV, cfb); 1608 cfb->mclk_div = cyber2000_grphr(EXT_MCLK_DIV, cfb);
1609 1609
1610 #ifdef __arm__ 1610 #ifdef __arm__
1611 /* 1611 /*
1612 * MCLK on the NetWinder and the Shark is fixed at 75MHz 1612 * MCLK on the NetWinder and the Shark is fixed at 75MHz
1613 */ 1613 */
1614 if (machine_is_netwinder()) { 1614 if (machine_is_netwinder()) {
1615 cfb->mclk_mult = 0xdb; 1615 cfb->mclk_mult = 0xdb;
1616 cfb->mclk_div = 0x54; 1616 cfb->mclk_div = 0x54;
1617 } 1617 }
1618 #endif 1618 #endif
1619 1619
1620 err = cyberpro_common_probe(cfb); 1620 err = cyberpro_common_probe(cfb);
1621 if (err) 1621 if (err)
1622 goto failed; 1622 goto failed;
1623 1623
1624 /* 1624 /*
1625 * Our driver data 1625 * Our driver data
1626 */ 1626 */
1627 pci_set_drvdata(dev, cfb); 1627 pci_set_drvdata(dev, cfb);
1628 if (int_cfb_info == NULL) 1628 if (int_cfb_info == NULL)
1629 int_cfb_info = cfb; 1629 int_cfb_info = cfb;
1630 1630
1631 return 0; 1631 return 0;
1632 1632
1633 failed: 1633 failed:
1634 iounmap(cfb->region); 1634 iounmap(cfb->region);
1635 failed_ioremap: 1635 failed_ioremap:
1636 pci_release_regions(dev);
1637 failed_regions:
1636 cyberpro_free_fb_info(cfb); 1638 cyberpro_free_fb_info(cfb);
1637 failed_release: 1639 failed_release:
1638 pci_release_regions(dev);
1639
1640 return err; 1640 return err;
1641 } 1641 }
1642 1642
1643 static void __devexit cyberpro_pci_remove(struct pci_dev *dev) 1643 static void __devexit cyberpro_pci_remove(struct pci_dev *dev)
1644 { 1644 {
1645 struct cfb_info *cfb = pci_get_drvdata(dev); 1645 struct cfb_info *cfb = pci_get_drvdata(dev);
1646 1646
1647 if (cfb) { 1647 if (cfb) {
1648 /* 1648 /*
1649 * If unregister_framebuffer fails, then 1649 * If unregister_framebuffer fails, then
1650 * we will be leaving hooks that could cause 1650 * we will be leaving hooks that could cause
1651 * oopsen laying around. 1651 * oopsen laying around.
1652 */ 1652 */
1653 if (unregister_framebuffer(&cfb->fb)) 1653 if (unregister_framebuffer(&cfb->fb))
1654 printk(KERN_WARNING "%s: danger Will Robinson, " 1654 printk(KERN_WARNING "%s: danger Will Robinson, "
1655 "danger danger! Oopsen imminent!\n", 1655 "danger danger! Oopsen imminent!\n",
1656 cfb->fb.fix.id); 1656 cfb->fb.fix.id);
1657 iounmap(cfb->region); 1657 iounmap(cfb->region);
1658 cyberpro_free_fb_info(cfb); 1658 cyberpro_free_fb_info(cfb);
1659 1659
1660 /* 1660 /*
1661 * Ensure that the driver data is no longer 1661 * Ensure that the driver data is no longer
1662 * valid. 1662 * valid.
1663 */ 1663 */
1664 pci_set_drvdata(dev, NULL); 1664 pci_set_drvdata(dev, NULL);
1665 if (cfb == int_cfb_info) 1665 if (cfb == int_cfb_info)
1666 int_cfb_info = NULL; 1666 int_cfb_info = NULL;
1667 1667
1668 pci_release_regions(dev); 1668 pci_release_regions(dev);
1669 } 1669 }
1670 } 1670 }
1671 1671
1672 static int cyberpro_pci_suspend(struct pci_dev *dev, pm_message_t state) 1672 static int cyberpro_pci_suspend(struct pci_dev *dev, pm_message_t state)
1673 { 1673 {
1674 return 0; 1674 return 0;
1675 } 1675 }
1676 1676
1677 /* 1677 /*
1678 * Re-initialise the CyberPro hardware 1678 * Re-initialise the CyberPro hardware
1679 */ 1679 */
1680 static int cyberpro_pci_resume(struct pci_dev *dev) 1680 static int cyberpro_pci_resume(struct pci_dev *dev)
1681 { 1681 {
1682 struct cfb_info *cfb = pci_get_drvdata(dev); 1682 struct cfb_info *cfb = pci_get_drvdata(dev);
1683 1683
1684 if (cfb) { 1684 if (cfb) {
1685 cyberpro_pci_enable_mmio(cfb); 1685 cyberpro_pci_enable_mmio(cfb);
1686 cyberpro_common_resume(cfb); 1686 cyberpro_common_resume(cfb);
1687 } 1687 }
1688 1688
1689 return 0; 1689 return 0;
1690 } 1690 }
1691 1691
1692 static struct pci_device_id cyberpro_pci_table[] = { 1692 static struct pci_device_id cyberpro_pci_table[] = {
1693 /* Not yet 1693 /* Not yet
1694 * { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682, 1694 * { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
1695 * PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 }, 1695 * PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
1696 */ 1696 */
1697 { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000, 1697 { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
1698 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 }, 1698 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },
1699 { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010, 1699 { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
1700 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2010 }, 1700 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2010 },
1701 { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000, 1701 { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000,
1702 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_5000 }, 1702 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_5000 },
1703 { 0, } 1703 { 0, }
1704 }; 1704 };
1705 1705
1706 MODULE_DEVICE_TABLE(pci, cyberpro_pci_table); 1706 MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);
1707 1707
1708 static struct pci_driver cyberpro_driver = { 1708 static struct pci_driver cyberpro_driver = {
1709 .name = "CyberPro", 1709 .name = "CyberPro",
1710 .probe = cyberpro_pci_probe, 1710 .probe = cyberpro_pci_probe,
1711 .remove = __devexit_p(cyberpro_pci_remove), 1711 .remove = __devexit_p(cyberpro_pci_remove),
1712 .suspend = cyberpro_pci_suspend, 1712 .suspend = cyberpro_pci_suspend,
1713 .resume = cyberpro_pci_resume, 1713 .resume = cyberpro_pci_resume,
1714 .id_table = cyberpro_pci_table 1714 .id_table = cyberpro_pci_table
1715 }; 1715 };
1716 #endif 1716 #endif
1717 1717
1718 /* 1718 /*
1719 * I don't think we can use the "module_init" stuff here because 1719 * I don't think we can use the "module_init" stuff here because
1720 * the fbcon stuff may not be initialised yet. Hence the #ifdef 1720 * the fbcon stuff may not be initialised yet. Hence the #ifdef
1721 * around module_init. 1721 * around module_init.
1722 * 1722 *
1723 * Tony: "module_init" is now required 1723 * Tony: "module_init" is now required
1724 */ 1724 */
1725 static int __init cyber2000fb_init(void) 1725 static int __init cyber2000fb_init(void)
1726 { 1726 {
1727 int ret = -1, err; 1727 int ret = -1, err;
1728 1728
1729 #ifndef MODULE 1729 #ifndef MODULE
1730 char *option = NULL; 1730 char *option = NULL;
1731 1731
1732 if (fb_get_options("cyber2000fb", &option)) 1732 if (fb_get_options("cyber2000fb", &option))
1733 return -ENODEV; 1733 return -ENODEV;
1734 cyber2000fb_setup(option); 1734 cyber2000fb_setup(option);
1735 #endif 1735 #endif
1736 1736
1737 #ifdef CONFIG_ARCH_SHARK 1737 #ifdef CONFIG_ARCH_SHARK
1738 err = cyberpro_vl_probe(); 1738 err = cyberpro_vl_probe();
1739 if (!err) 1739 if (!err)
1740 ret = 0; 1740 ret = 0;
1741 #endif 1741 #endif
1742 #ifdef CONFIG_PCI 1742 #ifdef CONFIG_PCI
1743 err = pci_register_driver(&cyberpro_driver); 1743 err = pci_register_driver(&cyberpro_driver);
1744 if (!err) 1744 if (!err)
1745 ret = 0; 1745 ret = 0;
1746 #endif 1746 #endif
1747 1747
1748 return ret ? err : 0; 1748 return ret ? err : 0;
1749 } 1749 }
1750 module_init(cyber2000fb_init); 1750 module_init(cyber2000fb_init);
1751 1751
1752 #ifndef CONFIG_ARCH_SHARK 1752 #ifndef CONFIG_ARCH_SHARK
1753 static void __exit cyberpro_exit(void) 1753 static void __exit cyberpro_exit(void)
1754 { 1754 {
1755 pci_unregister_driver(&cyberpro_driver); 1755 pci_unregister_driver(&cyberpro_driver);
1756 } 1756 }
1757 module_exit(cyberpro_exit); 1757 module_exit(cyberpro_exit);