diff options
Diffstat (limited to 'drivers/video/pm3fb.c')
-rw-r--r-- | drivers/video/pm3fb.c | 333 |
1 files changed, 152 insertions, 181 deletions
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index c77a1a1fd46b..616a0c08e30c 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c | |||
@@ -52,11 +52,6 @@ | |||
52 | static char *mode_option __devinitdata; | 52 | static 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 | ||
107 | static 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 | |||
117 | static 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 | |||
123 | static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v) | 102 | static 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 | ||
130 | static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno, | 112 | static 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 | ||
139 | static void pm3fb_clear_colormap(struct pm3_par *par, | 126 | static 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 | ||
178 | static inline int pm3fb_shift_bpp(unsigned long depth, int v) | 165 | static 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 | |||
174 | static 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 | */ |
395 | int pm3fb_init(void); | 383 | int pm3fb_init(void); |
396 | int pm3fb_setup(char*); | ||
397 | 384 | ||
398 | static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 385 | static 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 | ||
950 | static struct pci_device_id pm3fb_id_table[] = { | 922 | static 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 | ||
965 | MODULE_DEVICE_TABLE(pci, pm3fb_id_table); | 936 | MODULE_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 | */ | ||
947 | static int __init pm3fb_setup(char *options) | ||
948 | { | ||
949 | /* Parse user speficied options (`video=pm3fb:') */ | ||
950 | return 0; | ||
951 | } | ||
952 | #endif /* MODULE */ | ||
953 | |||
967 | int __init pm3fb_init(void) | 954 | int __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 | */ | ||
997 | int __init pm3fb_setup(char *options) | ||
998 | { | ||
999 | /* Parse user speficied options (`video=pm3fb:') */ | ||
1000 | return 0; | ||
1001 | } | ||
1002 | #endif /* MODULE */ | ||
1003 | |||
1004 | module_init(pm3fb_init); | 975 | module_init(pm3fb_init); |
1005 | module_exit(pm3fb_exit); | 976 | module_exit(pm3fb_exit); |
1006 | 977 | ||