aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2007-05-23 16:57:48 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-23 23:14:13 -0400
commit2686ba894bfedcacbe1b5197c574f3f1e66f2fda (patch)
tree3354af4c554dfc74260795ce7c9a459fbafbc0e5
parent11d1a62c596023991e860f1814aacb12a5169aa9 (diff)
pm3fb: various fixes
- fix 16-bit RGBA 4444 and 5551 modes (use fbset -rgba to set them) - kill wmb() after each register write by PM3_SLOW_WRITE_REG - kill inaccurate comments (leftovers from skeletonfb.c) - kill PCI class restriction, now it is more general and shorter - white spaces and other minor fixes and source reducing Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Antonino Daplas <adaplas@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/video/pm3fb.c333
1 files changed, 152 insertions, 181 deletions
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index c77a1a1fd46..616a0c08e30 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -52,11 +52,6 @@
52static char *mode_option __devinitdata; 52static char *mode_option __devinitdata;
53 53
54/* 54/*
55 * If your driver supports multiple boards, you should make the
56 * below data types arrays, or allocate them dynamically (using kmalloc()).
57 */
58
59/*
60 * This structure defines the hardware state of the graphics card. Normally 55 * This structure defines the hardware state of the graphics card. Normally
61 * you place this in a header file in linux/include/video. This file usually 56 * you place this in a header file in linux/include/video. This file usually
62 * also includes register information. That allows other driver subsystems 57 * also includes register information. That allows other driver subsystems
@@ -67,7 +62,7 @@ struct pm3_par {
67 unsigned char __iomem *v_regs;/* virtual address of p_regs */ 62 unsigned char __iomem *v_regs;/* virtual address of p_regs */
68 u32 video; /* video flags before blanking */ 63 u32 video; /* video flags before blanking */
69 u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */ 64 u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */
70 u32 palette[16]; 65 u32 palette[16];
71}; 66};
72 67
73/* 68/*
@@ -104,36 +99,28 @@ static inline void PM3_WAIT(struct pm3_par *par, u32 n)
104 while (PM3_READ_REG(par, PM3InFIFOSpace) < n); 99 while (PM3_READ_REG(par, PM3InFIFOSpace) < n);
105} 100}
106 101
107static inline void PM3_SLOW_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
108{
109 if (par->v_regs) {
110 mb();
111 PM3_WAIT(par, 1);
112 wmb();
113 PM3_WRITE_REG(par, off, v);
114 }
115}
116
117static inline void PM3_SET_INDEX(struct pm3_par *par, unsigned index)
118{
119 PM3_SLOW_WRITE_REG(par, PM3RD_IndexHigh, (index >> 8) & 0xff);
120 PM3_SLOW_WRITE_REG(par, PM3RD_IndexLow, index & 0xff);
121}
122
123static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v) 102static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
124{ 103{
125 PM3_SET_INDEX(par, r); 104 PM3_WAIT(par, 3);
105 PM3_WRITE_REG(par, PM3RD_IndexHigh, (r >> 8) & 0xff);
106 PM3_WRITE_REG(par, PM3RD_IndexLow, r & 0xff);
126 wmb(); 107 wmb();
127 PM3_WRITE_REG(par, PM3RD_IndexedData, v); 108 PM3_WRITE_REG(par, PM3RD_IndexedData, v);
109 wmb();
128} 110}
129 111
130static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno, 112static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno,
131 unsigned char r, unsigned char g, unsigned char b) 113 unsigned char r, unsigned char g, unsigned char b)
132{ 114{
133 PM3_SLOW_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno); 115 PM3_WAIT(par, 4);
134 PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, r); 116 PM3_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
135 PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, g); 117 wmb();
136 PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, b); 118 PM3_WRITE_REG(par, PM3RD_PaletteData, r);
119 wmb();
120 PM3_WRITE_REG(par, PM3RD_PaletteData, g);
121 wmb();
122 PM3_WRITE_REG(par, PM3RD_PaletteData, b);
123 wmb();
137} 124}
138 125
139static void pm3fb_clear_colormap(struct pm3_par *par, 126static void pm3fb_clear_colormap(struct pm3_par *par,
@@ -141,7 +128,7 @@ static void pm3fb_clear_colormap(struct pm3_par *par,
141{ 128{
142 int i; 129 int i;
143 130
144 for (i = 0; i < 256 ; i++) /* fill color map with white */ 131 for (i = 0; i < 256 ; i++)
145 pm3fb_set_color(par, i, r, g, b); 132 pm3fb_set_color(par, i, r, g, b);
146 133
147} 134}
@@ -175,19 +162,26 @@ static void pm3fb_calculate_clock(unsigned long reqclock,
175 } 162 }
176} 163}
177 164
178static inline int pm3fb_shift_bpp(unsigned long depth, int v) 165static inline int pm3fb_depth(const struct fb_var_screeninfo *var)
179{ 166{
180 switch (depth) { 167 if ( var->bits_per_pixel == 16 )
168 return var->red.length + var->green.length
169 + var->blue.length;
170
171 return var->bits_per_pixel;
172}
173
174static inline int pm3fb_shift_bpp(unsigned bpp, int v)
175{
176 switch (bpp) {
181 case 8: 177 case 8:
182 return (v >> 4); 178 return (v >> 4);
183 case 12:
184 case 15:
185 case 16: 179 case 16:
186 return (v >> 3); 180 return (v >> 3);
187 case 32: 181 case 32:
188 return (v >> 2); 182 return (v >> 2);
189 } 183 }
190 DPRINTK("Unsupported depth %ld\n", depth); 184 DPRINTK("Unsupported depth %u\n", bpp);
191 return 0; 185 return 0;
192} 186}
193 187
@@ -206,56 +200,50 @@ static void pm3fb_write_mode(struct fb_info *info)
206 const u32 vbend = vsend + info->var.upper_margin; 200 const u32 vbend = vsend + info->var.upper_margin;
207 const u32 vtotal = info->var.yres + vbend; 201 const u32 vtotal = info->var.yres + vbend;
208 const u32 width = (info->var.xres_virtual + 7) & ~7; 202 const u32 width = (info->var.xres_virtual + 7) & ~7;
209 203 const unsigned bpp = info->var.bits_per_pixel;
210 PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff); 204
211 PM3_SLOW_WRITE_REG(par, PM3Aperture0, 0x00000000); 205 PM3_WAIT(par, 20);
212 PM3_SLOW_WRITE_REG(par, PM3Aperture1, 0x00000000); 206 PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);
213 PM3_SLOW_WRITE_REG(par, PM3FIFODis, 0x00000007); 207 PM3_WRITE_REG(par, PM3Aperture0, 0x00000000);
214 208 PM3_WRITE_REG(par, PM3Aperture1, 0x00000000);
215 PM3_SLOW_WRITE_REG(par, PM3HTotal, 209 PM3_WRITE_REG(par, PM3FIFODis, 0x00000007);
216 pm3fb_shift_bpp(info->var.bits_per_pixel, 210
217 htotal - 1)); 211 PM3_WRITE_REG(par, PM3HTotal,
218 PM3_SLOW_WRITE_REG(par, PM3HsEnd, 212 pm3fb_shift_bpp(bpp, htotal - 1));
219 pm3fb_shift_bpp(info->var.bits_per_pixel, 213 PM3_WRITE_REG(par, PM3HsEnd,
220 hsend)); 214 pm3fb_shift_bpp(bpp, hsend));
221 PM3_SLOW_WRITE_REG(par, PM3HsStart, 215 PM3_WRITE_REG(par, PM3HsStart,
222 pm3fb_shift_bpp(info->var.bits_per_pixel, 216 pm3fb_shift_bpp(bpp, hsstart));
223 hsstart)); 217 PM3_WRITE_REG(par, PM3HbEnd,
224 PM3_SLOW_WRITE_REG(par, PM3HbEnd, 218 pm3fb_shift_bpp(bpp, hbend));
225 pm3fb_shift_bpp(info->var.bits_per_pixel, 219 PM3_WRITE_REG(par, PM3HgEnd,
226 hbend)); 220 pm3fb_shift_bpp(bpp, hbend));
227 PM3_SLOW_WRITE_REG(par, PM3HgEnd, 221 PM3_WRITE_REG(par, PM3ScreenStride,
228 pm3fb_shift_bpp(info->var.bits_per_pixel, 222 pm3fb_shift_bpp(bpp, width));
229 hbend)); 223 PM3_WRITE_REG(par, PM3VTotal, vtotal - 1);
230 PM3_SLOW_WRITE_REG(par, PM3ScreenStride, 224 PM3_WRITE_REG(par, PM3VsEnd, vsend - 1);
231 pm3fb_shift_bpp(info->var.bits_per_pixel, 225 PM3_WRITE_REG(par, PM3VsStart, vsstart - 1);
232 width)); 226 PM3_WRITE_REG(par, PM3VbEnd, vbend);
233 PM3_SLOW_WRITE_REG(par, PM3VTotal, vtotal - 1); 227
234 PM3_SLOW_WRITE_REG(par, PM3VsEnd, vsend - 1); 228 switch (bpp) {
235 PM3_SLOW_WRITE_REG(par, PM3VsStart, vsstart - 1);
236 PM3_SLOW_WRITE_REG(par, PM3VbEnd, vbend);
237
238 switch (info->var.bits_per_pixel) {
239 case 8: 229 case 8:
240 PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, 230 PM3_WRITE_REG(par, PM3ByAperture1Mode,
241 PM3ByApertureMode_PIXELSIZE_8BIT); 231 PM3ByApertureMode_PIXELSIZE_8BIT);
242 PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, 232 PM3_WRITE_REG(par, PM3ByAperture2Mode,
243 PM3ByApertureMode_PIXELSIZE_8BIT); 233 PM3ByApertureMode_PIXELSIZE_8BIT);
244 break; 234 break;
245 235
246 case 12:
247 case 15:
248 case 16: 236 case 16:
249#ifndef __BIG_ENDIAN 237#ifndef __BIG_ENDIAN
250 PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, 238 PM3_WRITE_REG(par, PM3ByAperture1Mode,
251 PM3ByApertureMode_PIXELSIZE_16BIT); 239 PM3ByApertureMode_PIXELSIZE_16BIT);
252 PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, 240 PM3_WRITE_REG(par, PM3ByAperture2Mode,
253 PM3ByApertureMode_PIXELSIZE_16BIT); 241 PM3ByApertureMode_PIXELSIZE_16BIT);
254#else 242#else
255 PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, 243 PM3_WRITE_REG(par, PM3ByAperture1Mode,
256 PM3ByApertureMode_PIXELSIZE_16BIT | 244 PM3ByApertureMode_PIXELSIZE_16BIT |
257 PM3ByApertureMode_BYTESWAP_BADC); 245 PM3ByApertureMode_BYTESWAP_BADC);
258 PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, 246 PM3_WRITE_REG(par, PM3ByAperture2Mode,
259 PM3ByApertureMode_PIXELSIZE_16BIT | 247 PM3ByApertureMode_PIXELSIZE_16BIT |
260 PM3ByApertureMode_BYTESWAP_BADC); 248 PM3ByApertureMode_BYTESWAP_BADC);
261#endif /* ! __BIG_ENDIAN */ 249#endif /* ! __BIG_ENDIAN */
@@ -263,23 +251,22 @@ static void pm3fb_write_mode(struct fb_info *info)
263 251
264 case 32: 252 case 32:
265#ifndef __BIG_ENDIAN 253#ifndef __BIG_ENDIAN
266 PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, 254 PM3_WRITE_REG(par, PM3ByAperture1Mode,
267 PM3ByApertureMode_PIXELSIZE_32BIT); 255 PM3ByApertureMode_PIXELSIZE_32BIT);
268 PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, 256 PM3_WRITE_REG(par, PM3ByAperture2Mode,
269 PM3ByApertureMode_PIXELSIZE_32BIT); 257 PM3ByApertureMode_PIXELSIZE_32BIT);
270#else 258#else
271 PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, 259 PM3_WRITE_REG(par, PM3ByAperture1Mode,
272 PM3ByApertureMode_PIXELSIZE_32BIT | 260 PM3ByApertureMode_PIXELSIZE_32BIT |
273 PM3ByApertureMode_BYTESWAP_DCBA); 261 PM3ByApertureMode_BYTESWAP_DCBA);
274 PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, 262 PM3_WRITE_REG(par, PM3ByAperture2Mode,
275 PM3ByApertureMode_PIXELSIZE_32BIT | 263 PM3ByApertureMode_PIXELSIZE_32BIT |
276 PM3ByApertureMode_BYTESWAP_DCBA); 264 PM3ByApertureMode_BYTESWAP_DCBA);
277#endif /* ! __BIG_ENDIAN */ 265#endif /* ! __BIG_ENDIAN */
278 break; 266 break;
279 267
280 default: 268 default:
281 DPRINTK("Unsupported depth %d\n", 269 DPRINTK("Unsupported depth %d\n", bpp);
282 info->var.bits_per_pixel);
283 break; 270 break;
284 } 271 }
285 272
@@ -296,14 +283,15 @@ static void pm3fb_write_mode(struct fb_info *info)
296 PM3VideoControl_VSYNC_MASK); 283 PM3VideoControl_VSYNC_MASK);
297 video |= PM3VideoControl_HSYNC_ACTIVE_HIGH | 284 video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
298 PM3VideoControl_VSYNC_ACTIVE_HIGH; 285 PM3VideoControl_VSYNC_ACTIVE_HIGH;
299 PM3_SLOW_WRITE_REG(par, PM3VideoControl, video); 286 PM3_WRITE_REG(par, PM3VideoControl, video);
300 } 287 }
301 PM3_SLOW_WRITE_REG(par, PM3VClkCtl, 288 PM3_WRITE_REG(par, PM3VClkCtl,
302 (PM3_READ_REG(par, PM3VClkCtl) & 0xFFFFFFFC)); 289 (PM3_READ_REG(par, PM3VClkCtl) & 0xFFFFFFFC));
303 PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base); 290 PM3_WRITE_REG(par, PM3ScreenBase, par->base);
304 PM3_SLOW_WRITE_REG(par, PM3ChipConfig, 291 PM3_WRITE_REG(par, PM3ChipConfig,
305 (PM3_READ_REG(par, PM3ChipConfig) & 0xFFFFFFFD)); 292 (PM3_READ_REG(par, PM3ChipConfig) & 0xFFFFFFFD));
306 293
294 wmb();
307 { 295 {
308 unsigned char uninitialized_var(m); /* ClkPreScale */ 296 unsigned char uninitialized_var(m); /* ClkPreScale */
309 unsigned char uninitialized_var(n); /* ClkFeedBackScale */ 297 unsigned char uninitialized_var(n); /* ClkFeedBackScale */
@@ -337,7 +325,7 @@ static void pm3fb_write_mode(struct fb_info *info)
337 325
338 PM3_WRITE_DAC_REG(par, PM3RD_DACControl, 0x00); 326 PM3_WRITE_DAC_REG(par, PM3RD_DACControl, 0x00);
339 327
340 switch (info->var.bits_per_pixel) { 328 switch (pm3fb_depth(&info->var)) {
341 case 8: 329 case 8:
342 PM3_WRITE_DAC_REG(par, PM3RD_PixelSize, 330 PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
343 PM3RD_PixelSize_8_BIT_PIXELS); 331 PM3RD_PixelSize_8_BIT_PIXELS);
@@ -393,57 +381,44 @@ static void pm3fb_write_mode(struct fb_info *info)
393 * hardware independent functions 381 * hardware independent functions
394 */ 382 */
395int pm3fb_init(void); 383int pm3fb_init(void);
396int pm3fb_setup(char*);
397 384
398static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 385static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
399{ 386{
400 u32 lpitch; 387 u32 lpitch;
388 unsigned bpp = var->red.length + var->green.length
389 + var->blue.length + var->transp.length;
401 390
402 var->transp.offset = 0; 391 if ( bpp != var->bits_per_pixel ) {
403 var->transp.length = 0; 392 /* set predefined mode for bits_per_pixel settings */
404 switch(var->bits_per_pixel) { 393
405 case 8: 394 switch(var->bits_per_pixel) {
406 var->red.length = var->green.length = var->blue.length = 8; 395 case 8:
407 var->red.offset = var->green.offset = var->blue.offset = 0; 396 var->red.length = var->green.length = var->blue.length = 8;
408 break; 397 var->red.offset = var->green.offset = var->blue.offset = 0;
409 case 12: 398 var->transp.offset = 0;
410 var->red.offset = 8; 399 var->transp.length = 0;
411 var->red.length = 4; 400 break;
412 var->green.offset = 4; 401 case 16:
413 var->green.length = 4; 402 var->red.length = var->blue.length = 5;
414 var->blue.offset = 0; 403 var->green.length = 6;
415 var->blue.length = 4; 404 var->transp.length = 0;
416 var->transp.offset = 12; 405 break;
417 var->transp.length = 4; 406 case 32:
418 case 15: 407 var->red.length = var->green.length = var->blue.length = 8;
419 var->red.offset = 10; 408 var->transp.length = 8;
420 var->red.length = 5; 409 break;
421 var->green.offset = 5; 410 default:
422 var->green.length = 5; 411 DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
423 var->blue.offset = 0; 412 return -EINVAL;
424 var->blue.length = 5; 413 }
425 var->transp.offset = 15; 414 }
426 var->transp.length = 1; 415 /* it is assumed BGRA order */
427 break; 416 if (var->bits_per_pixel > 8 )
428 case 16: 417 {
429 var->red.offset = 11; 418 var->blue.offset = 0;
430 var->red.length = 5; 419 var->green.offset = var->blue.length;
431 var->green.offset = 5; 420 var->red.offset = var->green.offset + var->green.length;
432 var->green.length = 6; 421 var->transp.offset = var->red.offset + var->red.length;
433 var->blue.offset = 0;
434 var->blue.length = 5;
435 break;
436 case 32:
437 var->transp.offset = 24;
438 var->transp.length = 8;
439 var->red.offset = 16;
440 var->green.offset = 8;
441 var->blue.offset = 0;
442 var->red.length = var->green.length = var->blue.length = 8;
443 break;
444 default:
445 DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
446 return -EINVAL;
447 } 422 }
448 var->height = var->width = -1; 423 var->height = var->width = -1;
449 424
@@ -502,10 +477,9 @@ static int pm3fb_set_par(struct fb_info *info)
502{ 477{
503 struct pm3_par *par = info->par; 478 struct pm3_par *par = info->par;
504 const u32 xres = (info->var.xres + 31) & ~31; 479 const u32 xres = (info->var.xres + 31) & ~31;
505 const int depth = (info->var.bits_per_pixel + 7) & ~7; 480 const unsigned bpp = info->var.bits_per_pixel;
506 481
507 par->base = pm3fb_shift_bpp(info->var.bits_per_pixel, 482 par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres)
508 (info->var.yoffset * xres)
509 + info->var.xoffset); 483 + info->var.xoffset);
510 par->video = 0; 484 par->video = 0;
511 485
@@ -530,12 +504,10 @@ static int pm3fb_set_par(struct fb_info *info)
530 par->video |= PM3VideoControl_DISABLE; 504 par->video |= PM3VideoControl_DISABLE;
531 DPRINTK("PM3Video disabled\n"); 505 DPRINTK("PM3Video disabled\n");
532 } 506 }
533 switch (depth) { 507 switch (bpp) {
534 case 8: 508 case 8:
535 par->video |= PM3VideoControl_PIXELSIZE_8BIT; 509 par->video |= PM3VideoControl_PIXELSIZE_8BIT;
536 break; 510 break;
537 case 12:
538 case 15:
539 case 16: 511 case 16:
540 par->video |= PM3VideoControl_PIXELSIZE_16BIT; 512 par->video |= PM3VideoControl_PIXELSIZE_16BIT;
541 break; 513 break;
@@ -548,9 +520,9 @@ static int pm3fb_set_par(struct fb_info *info)
548 } 520 }
549 521
550 info->fix.visual = 522 info->fix.visual =
551 (depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 523 (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
552 info->fix.line_length = ((info->var.xres_virtual + 7) & ~7) 524 info->fix.line_length = ((info->var.xres_virtual + 7) & ~7)
553 * depth / 8; 525 * bpp / 8;
554 526
555/* pm3fb_clear_memory(info, 0);*/ 527/* pm3fb_clear_memory(info, 0);*/
556 pm3fb_clear_colormap(par, 0, 0, 0); 528 pm3fb_clear_colormap(par, 0, 0, 0);
@@ -580,8 +552,8 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
580 * var->{color}.length contains length of bitfield 552 * var->{color}.length contains length of bitfield
581 * {hardwarespecific} contains width of DAC 553 * {hardwarespecific} contains width of DAC
582 * pseudo_palette[X] is programmed to (X << red.offset) | 554 * pseudo_palette[X] is programmed to (X << red.offset) |
583 * (X << green.offset) | 555 * (X << green.offset) |
584 * (X << blue.offset) 556 * (X << blue.offset)
585 * RAMDAC[X] is programmed to (red, green, blue) 557 * RAMDAC[X] is programmed to (red, green, blue)
586 * color depth = SUM(var->{color}.length) 558 * color depth = SUM(var->{color}.length)
587 * 559 *
@@ -621,7 +593,6 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
621 case 8: 593 case 8:
622 break; 594 break;
623 case 16: 595 case 16:
624 case 24:
625 case 32: 596 case 32:
626 ((u32*)(info->pseudo_palette))[regno] = v; 597 ((u32*)(info->pseudo_palette))[regno] = v;
627 break; 598 break;
@@ -643,7 +614,8 @@ static int pm3fb_pan_display(struct fb_var_screeninfo *var,
643 par->base = pm3fb_shift_bpp(var->bits_per_pixel, 614 par->base = pm3fb_shift_bpp(var->bits_per_pixel,
644 (var->yoffset * xres) 615 (var->yoffset * xres)
645 + var->xoffset); 616 + var->xoffset);
646 PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base); 617 PM3_WAIT(par, 1);
618 PM3_WRITE_REG(par, PM3ScreenBase, par->base);
647 return 0; 619 return 0;
648} 620}
649 621
@@ -665,31 +637,31 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
665 637
666 switch (blank_mode) { 638 switch (blank_mode) {
667 case FB_BLANK_UNBLANK: 639 case FB_BLANK_UNBLANK:
668 video = video | PM3VideoControl_ENABLE; 640 video |= PM3VideoControl_ENABLE;
669 break; 641 break;
670 case FB_BLANK_NORMAL: /* FIXME */ 642 case FB_BLANK_NORMAL:
671 video = video & ~(PM3VideoControl_ENABLE); 643 video &= ~(PM3VideoControl_ENABLE);
672 break; 644 break;
673 case FB_BLANK_HSYNC_SUSPEND: 645 case FB_BLANK_HSYNC_SUSPEND:
674 video = video & ~(PM3VideoControl_HSYNC_MASK | 646 video &= ~(PM3VideoControl_HSYNC_MASK |
675 PM3VideoControl_BLANK_ACTIVE_LOW); 647 PM3VideoControl_BLANK_ACTIVE_LOW);
676 break; 648 break;
677 case FB_BLANK_VSYNC_SUSPEND: 649 case FB_BLANK_VSYNC_SUSPEND:
678 video = video & ~(PM3VideoControl_VSYNC_MASK | 650 video &= ~(PM3VideoControl_VSYNC_MASK |
679 PM3VideoControl_BLANK_ACTIVE_LOW); 651 PM3VideoControl_BLANK_ACTIVE_LOW);
680 break; 652 break;
681 case FB_BLANK_POWERDOWN: 653 case FB_BLANK_POWERDOWN:
682 video = video & ~(PM3VideoControl_HSYNC_MASK | 654 video &= ~(PM3VideoControl_HSYNC_MASK |
683 PM3VideoControl_VSYNC_MASK | 655 PM3VideoControl_VSYNC_MASK |
684 PM3VideoControl_BLANK_ACTIVE_LOW); 656 PM3VideoControl_BLANK_ACTIVE_LOW);
685 break; 657 break;
686 default: 658 default:
687 DPRINTK("Unsupported blanking %d\n", blank_mode); 659 DPRINTK("Unsupported blanking %d\n", blank_mode);
688 return 1; 660 return 1;
689 } 661 }
690 662
691 PM3_SLOW_WRITE_REG(par,PM3VideoControl, video); 663 PM3_WAIT(par, 1);
692 664 PM3_WRITE_REG(par,PM3VideoControl, video);
693 return 0; 665 return 0;
694} 666}
695 667
@@ -703,9 +675,9 @@ static struct fb_ops pm3fb_ops = {
703 .fb_set_par = pm3fb_set_par, 675 .fb_set_par = pm3fb_set_par,
704 .fb_setcolreg = pm3fb_setcolreg, 676 .fb_setcolreg = pm3fb_setcolreg,
705 .fb_pan_display = pm3fb_pan_display, 677 .fb_pan_display = pm3fb_pan_display,
706 .fb_fillrect = cfb_fillrect, /* Needed !!! */ 678 .fb_fillrect = cfb_fillrect,
707 .fb_copyarea = cfb_copyarea, /* Needed !!! */ 679 .fb_copyarea = cfb_copyarea,
708 .fb_imageblit = cfb_imageblit, /* Needed !!! */ 680 .fb_imageblit = cfb_imageblit,
709 .fb_blank = pm3fb_blank, 681 .fb_blank = pm3fb_blank,
710}; 682};
711 683
@@ -722,7 +694,7 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
722 unsigned long memsize = 0, tempBypass, i, temp1, temp2; 694 unsigned long memsize = 0, tempBypass, i, temp1, temp2;
723 unsigned char __iomem *screen_mem; 695 unsigned char __iomem *screen_mem;
724 696
725 pm3fb_fix.smem_len = 64 * 1024 * 1024; /* request full aperture size */ 697 pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */
726 /* Linear frame buffer - request region and map it. */ 698 /* Linear frame buffer - request region and map it. */
727 if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len, 699 if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len,
728 "pm3fb smem")) { 700 "pm3fb smem")) {
@@ -744,7 +716,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
744 716
745 DPRINTK("PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass); 717 DPRINTK("PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);
746 718
747 PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF); 719 PM3_WAIT(par, 1);
720 PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
748 721
749 /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */ 722 /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
750 for (i = 0; i < 32; i++) { 723 for (i = 0; i < 32; i++) {
@@ -765,10 +738,9 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
765 if (memsize + 1 == i) { 738 if (memsize + 1 == i) {
766 for (i = 0; i < 32; i++) { 739 for (i = 0; i < 32; i++) {
767 /* Clear first 32MB ; 0 is 0, no need to byteswap */ 740 /* Clear first 32MB ; 0 is 0, no need to byteswap */
768 writel(0x0000000, 741 writel(0x0000000, (screen_mem + (i * 1048576)));
769 (screen_mem + (i * 1048576)));
770 mb();
771 } 742 }
743 wmb();
772 744
773 for (i = 32; i < 64; i++) { 745 for (i = 32; i < 64; i++) {
774 fb_writel(i * 0x00345678, 746 fb_writel(i * 0x00345678,
@@ -787,7 +759,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
787 } 759 }
788 DPRINTK("Second detect pass got %ld MB\n", memsize + 1); 760 DPRINTK("Second detect pass got %ld MB\n", memsize + 1);
789 761
790 PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass); 762 PM3_WAIT(par, 1);
763 PM3_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);
791 764
792 iounmap(screen_mem); 765 iounmap(screen_mem);
793 release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len); 766 release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
@@ -890,7 +863,6 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
890 goto err_exit_both; 863 goto err_exit_both;
891 } 864 }
892 865
893 /* This has to been done !!! */
894 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { 866 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
895 retval = -ENOMEM; 867 retval = -ENOMEM;
896 goto err_exit_both; 868 goto err_exit_both;
@@ -907,7 +879,7 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
907 } 879 }
908 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, 880 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
909 info->fix.id); 881 info->fix.id);
910 pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */ 882 pci_set_drvdata(dev, info);
911 return 0; 883 return 0;
912 884
913 err_exit_all: 885 err_exit_all:
@@ -949,8 +921,7 @@ static void __devexit pm3fb_remove(struct pci_dev *dev)
949 921
950static struct pci_device_id pm3fb_id_table[] = { 922static struct pci_device_id pm3fb_id_table[] = {
951 { PCI_VENDOR_ID_3DLABS, 0x0a, 923 { PCI_VENDOR_ID_3DLABS, 0x0a,
952 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, 924 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
953 0xff0000, 0 },
954 { 0, } 925 { 0, }
955}; 926};
956 927
@@ -964,6 +935,22 @@ static struct pci_driver pm3fb_driver = {
964 935
965MODULE_DEVICE_TABLE(pci, pm3fb_id_table); 936MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
966 937
938#ifndef MODULE
939 /*
940 * Setup
941 */
942
943/*
944 * Only necessary if your driver takes special options,
945 * otherwise we fall back on the generic fb_setup().
946 */
947static int __init pm3fb_setup(char *options)
948{
949 /* Parse user speficied options (`video=pm3fb:') */
950 return 0;
951}
952#endif /* MODULE */
953
967int __init pm3fb_init(void) 954int __init pm3fb_init(void)
968{ 955{
969 /* 956 /*
@@ -985,22 +972,6 @@ static void __exit pm3fb_exit(void)
985 pci_unregister_driver(&pm3fb_driver); 972 pci_unregister_driver(&pm3fb_driver);
986} 973}
987 974
988#ifndef MODULE
989 /*
990 * Setup
991 */
992
993/*
994 * Only necessary if your driver takes special options,
995 * otherwise we fall back on the generic fb_setup().
996 */
997int __init pm3fb_setup(char *options)
998{
999 /* Parse user speficied options (`video=pm3fb:') */
1000 return 0;
1001}
1002#endif /* MODULE */
1003
1004module_init(pm3fb_init); 975module_init(pm3fb_init);
1005module_exit(pm3fb_exit); 976module_exit(pm3fb_exit);
1006 977