diff options
-rw-r--r-- | drivers/video/pm2fb.c | 350 |
1 files changed, 155 insertions, 195 deletions
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index c3abb951db59..25431257e286 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * and additional input from James Simmon's port of Hannu Mallat's tdfx | 11 | * and additional input from James Simmon's port of Hannu Mallat's tdfx |
12 | * driver. | 12 | * driver. |
13 | * | 13 | * |
14 | * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86. I | 14 | * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86. I |
15 | * have no access to other pm2fb implementations. Sparc (and thus | 15 | * have no access to other pm2fb implementations. Sparc (and thus |
16 | * hopefully other big-endian) devices now work, thanks to a lot of | 16 | * hopefully other big-endian) devices now work, thanks to a lot of |
17 | * testing work by Ron Murray. I have no access to CVision hardware, | 17 | * testing work by Ron Murray. I have no access to CVision hardware, |
@@ -146,56 +146,35 @@ static struct fb_var_screeninfo pm2fb_var __devinitdata = { | |||
146 | * Utility functions | 146 | * Utility functions |
147 | */ | 147 | */ |
148 | 148 | ||
149 | static inline u32 RD32(unsigned char __iomem *base, s32 off) | ||
150 | { | ||
151 | return fb_readl(base + off); | ||
152 | } | ||
153 | |||
154 | static inline void WR32(unsigned char __iomem *base, s32 off, u32 v) | ||
155 | { | ||
156 | fb_writel(v, base + off); | ||
157 | } | ||
158 | |||
159 | static inline u32 pm2_RD(struct pm2fb_par* p, s32 off) | 149 | static inline u32 pm2_RD(struct pm2fb_par* p, s32 off) |
160 | { | 150 | { |
161 | return RD32(p->v_regs, off); | 151 | return fb_readl(p->v_regs + off); |
162 | } | 152 | } |
163 | 153 | ||
164 | static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v) | 154 | static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v) |
165 | { | 155 | { |
166 | WR32(p->v_regs, off, v); | 156 | fb_writel(v, p->v_regs + off); |
167 | } | 157 | } |
168 | 158 | ||
169 | static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx) | 159 | static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx) |
170 | { | 160 | { |
171 | int index = PM2R_RD_INDEXED_DATA; | 161 | pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx); |
172 | switch (p->type) { | ||
173 | case PM2_TYPE_PERMEDIA2: | ||
174 | pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx); | ||
175 | break; | ||
176 | case PM2_TYPE_PERMEDIA2V: | ||
177 | pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff); | ||
178 | index = PM2VR_RD_INDEXED_DATA; | ||
179 | break; | ||
180 | } | ||
181 | mb(); | 162 | mb(); |
182 | return pm2_RD(p, index); | 163 | return pm2_RD(p, PM2R_RD_INDEXED_DATA); |
164 | } | ||
165 | |||
166 | static inline u32 pm2v_RDAC_RD(struct pm2fb_par* p, s32 idx) | ||
167 | { | ||
168 | pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff); | ||
169 | mb(); | ||
170 | return pm2_RD(p, PM2VR_RD_INDEXED_DATA); | ||
183 | } | 171 | } |
184 | 172 | ||
185 | static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) | 173 | static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) |
186 | { | 174 | { |
187 | int index = PM2R_RD_INDEXED_DATA; | 175 | pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx); |
188 | switch (p->type) { | ||
189 | case PM2_TYPE_PERMEDIA2: | ||
190 | pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx); | ||
191 | break; | ||
192 | case PM2_TYPE_PERMEDIA2V: | ||
193 | pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff); | ||
194 | index = PM2VR_RD_INDEXED_DATA; | ||
195 | break; | ||
196 | } | ||
197 | wmb(); | 176 | wmb(); |
198 | pm2_WR(p, index, v); | 177 | pm2_WR(p, PM2R_RD_INDEXED_DATA, v); |
199 | wmb(); | 178 | wmb(); |
200 | } | 179 | } |
201 | 180 | ||
@@ -212,7 +191,7 @@ static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) | |||
212 | #else | 191 | #else |
213 | static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a) | 192 | static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a) |
214 | { | 193 | { |
215 | while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a ); | 194 | while(pm2_RD(p, PM2R_IN_FIFO_SPACE) < a); |
216 | mb(); | 195 | mb(); |
217 | } | 196 | } |
218 | #endif | 197 | #endif |
@@ -249,7 +228,7 @@ static u32 partprod(u32 xres) | |||
249 | 228 | ||
250 | for (i = 0; pp_table[i].width && pp_table[i].width != xres; i++) | 229 | for (i = 0; pp_table[i].width && pp_table[i].width != xres; i++) |
251 | ; | 230 | ; |
252 | if ( pp_table[i].width == 0 ) | 231 | if (pp_table[i].width == 0) |
253 | DPRINTK("invalid width %u\n", xres); | 232 | DPRINTK("invalid width %u\n", xres); |
254 | return pp_table[i].pp; | 233 | return pp_table[i].pp; |
255 | } | 234 | } |
@@ -257,20 +236,17 @@ static u32 partprod(u32 xres) | |||
257 | static u32 to3264(u32 timing, int bpp, int is64) | 236 | static u32 to3264(u32 timing, int bpp, int is64) |
258 | { | 237 | { |
259 | switch (bpp) { | 238 | switch (bpp) { |
239 | case 24: | ||
240 | timing *= 3; | ||
260 | case 8: | 241 | case 8: |
261 | timing >>= 2 + is64; | 242 | timing >>= 1; |
262 | break; | ||
263 | case 16: | 243 | case 16: |
264 | timing >>= 1 + is64; | 244 | timing >>= 1; |
265 | break; | ||
266 | case 24: | ||
267 | timing = (timing * 3) >> (2 + is64); | ||
268 | break; | ||
269 | case 32: | 245 | case 32: |
270 | if (is64) | ||
271 | timing >>= 1; | ||
272 | break; | 246 | break; |
273 | } | 247 | } |
248 | if (is64) | ||
249 | timing >>= 1; | ||
274 | return timing; | 250 | return timing; |
275 | } | 251 | } |
276 | 252 | ||
@@ -289,13 +265,13 @@ static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn, | |||
289 | for (m = 2; m; m++) { | 265 | for (m = 2; m; m++) { |
290 | f = PM2_REFERENCE_CLOCK * m / n; | 266 | f = PM2_REFERENCE_CLOCK * m / n; |
291 | if (f >= 150000 && f <= 300000) { | 267 | if (f >= 150000 && f <= 300000) { |
292 | for ( p = 0; p < 5; p++, f >>= 1) { | 268 | for (p = 0; p < 5; p++, f >>= 1) { |
293 | curr = ( clk > f ) ? clk - f : f - clk; | 269 | curr = (clk > f) ? clk - f : f - clk; |
294 | if ( curr < delta ) { | 270 | if (curr < delta) { |
295 | delta=curr; | 271 | delta = curr; |
296 | *mm=m; | 272 | *mm = m; |
297 | *nn=n; | 273 | *nn = n; |
298 | *pp=p; | 274 | *pp = p; |
299 | } | 275 | } |
300 | } | 276 | } |
301 | } | 277 | } |
@@ -313,15 +289,15 @@ static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn, | |||
313 | s32 delta = 1000; | 289 | s32 delta = 1000; |
314 | 290 | ||
315 | *mm = *nn = *pp = 0; | 291 | *mm = *nn = *pp = 0; |
316 | for ( m = 1; m < 128; m++) { | 292 | for (m = 1; m < 128; m++) { |
317 | for (n = 2 * m + 1; n; n++) { | 293 | for (n = 2 * m + 1; n; n++) { |
318 | for ( p = 0; p < 2; p++) { | 294 | for (p = 0; p < 2; p++) { |
319 | f = ( PM2_REFERENCE_CLOCK >> ( p + 1 )) * n / m; | 295 | f = (PM2_REFERENCE_CLOCK >> (p + 1)) * n / m; |
320 | if ( clk > f - delta && clk < f + delta ) { | 296 | if (clk > f - delta && clk < f + delta) { |
321 | delta = ( clk > f ) ? clk - f : f - clk; | 297 | delta = (clk > f) ? clk - f : f - clk; |
322 | *mm=m; | 298 | *mm = m; |
323 | *nn=n; | 299 | *nn = n; |
324 | *pp=p; | 300 | *pp = p; |
325 | } | 301 | } |
326 | } | 302 | } |
327 | } | 303 | } |
@@ -329,7 +305,7 @@ static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn, | |||
329 | } | 305 | } |
330 | 306 | ||
331 | static void clear_palette(struct pm2fb_par* p) { | 307 | static void clear_palette(struct pm2fb_par* p) { |
332 | int i=256; | 308 | int i = 256; |
333 | 309 | ||
334 | WAIT_FIFO(p, 1); | 310 | WAIT_FIFO(p, 1); |
335 | pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, 0); | 311 | pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, 0); |
@@ -369,7 +345,7 @@ static void reset_config(struct pm2fb_par* p) | |||
369 | { | 345 | { |
370 | WAIT_FIFO(p, 52); | 346 | WAIT_FIFO(p, 52); |
371 | pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG) & | 347 | pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG) & |
372 | ~(PM2F_VGA_ENABLE|PM2F_VGA_FIXED)); | 348 | ~(PM2F_VGA_ENABLE | PM2F_VGA_FIXED)); |
373 | pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L)); | 349 | pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L)); |
374 | pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L)); | 350 | pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L)); |
375 | pm2_WR(p, PM2R_FIFO_CONTROL, 0); | 351 | pm2_WR(p, PM2R_FIFO_CONTROL, 0); |
@@ -409,16 +385,21 @@ static void reset_config(struct pm2fb_par* p) | |||
409 | pm2_RDAC_WR(p, PM2I_RD_MODE_CONTROL, 0); /* no overlay */ | 385 | pm2_RDAC_WR(p, PM2I_RD_MODE_CONTROL, 0); /* no overlay */ |
410 | pm2_RDAC_WR(p, PM2I_RD_CURSOR_CONTROL, 0); | 386 | pm2_RDAC_WR(p, PM2I_RD_CURSOR_CONTROL, 0); |
411 | pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, PM2F_RD_PALETTE_WIDTH_8); | 387 | pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, PM2F_RD_PALETTE_WIDTH_8); |
388 | pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0); | ||
389 | pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0); | ||
390 | pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0); | ||
391 | pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0); | ||
392 | pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0); | ||
412 | break; | 393 | break; |
413 | case PM2_TYPE_PERMEDIA2V: | 394 | case PM2_TYPE_PERMEDIA2V: |
414 | pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1); /* 8bit */ | 395 | pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1); /* 8bit */ |
396 | pm2v_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0); | ||
397 | pm2v_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0); | ||
398 | pm2v_RDAC_WR(p, PM2I_RD_RED_KEY, 0); | ||
399 | pm2v_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0); | ||
400 | pm2v_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0); | ||
415 | break; | 401 | break; |
416 | } | 402 | } |
417 | pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0); | ||
418 | pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0); | ||
419 | pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0); | ||
420 | pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0); | ||
421 | pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0); | ||
422 | } | 403 | } |
423 | 404 | ||
424 | static void set_aperture(struct pm2fb_par* p, u32 depth) | 405 | static void set_aperture(struct pm2fb_par* p, u32 depth) |
@@ -428,7 +409,7 @@ static void set_aperture(struct pm2fb_par* p, u32 depth) | |||
428 | * hosts, the on-chip aperture settings are used where | 409 | * hosts, the on-chip aperture settings are used where |
429 | * possible to translate from host to card byte order. | 410 | * possible to translate from host to card byte order. |
430 | */ | 411 | */ |
431 | WAIT_FIFO(p, 4); | 412 | WAIT_FIFO(p, 2); |
432 | #ifdef __LITTLE_ENDIAN | 413 | #ifdef __LITTLE_ENDIAN |
433 | pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD); | 414 | pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD); |
434 | #else | 415 | #else |
@@ -476,7 +457,7 @@ static void set_memclock(struct pm2fb_par* par, u32 clk) | |||
476 | switch (par->type) { | 457 | switch (par->type) { |
477 | case PM2_TYPE_PERMEDIA2V: | 458 | case PM2_TYPE_PERMEDIA2V: |
478 | pm2v_mnp(clk/2, &m, &n, &p); | 459 | pm2v_mnp(clk/2, &m, &n, &p); |
479 | WAIT_FIFO(par, 8); | 460 | WAIT_FIFO(par, 12); |
480 | pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8); | 461 | pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8); |
481 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0); | 462 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0); |
482 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m); | 463 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m); |
@@ -484,10 +465,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk) | |||
484 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p); | 465 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p); |
485 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1); | 466 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1); |
486 | rmb(); | 467 | rmb(); |
487 | for (i = 256; | 468 | for (i = 256; i; i--) |
488 | i && !(pm2_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2); | 469 | if (pm2v_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2) |
489 | i--) | 470 | break; |
490 | ; | ||
491 | pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0); | 471 | pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0); |
492 | break; | 472 | break; |
493 | case PM2_TYPE_PERMEDIA2: | 473 | case PM2_TYPE_PERMEDIA2: |
@@ -499,10 +479,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk) | |||
499 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p); | 479 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p); |
500 | pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS); | 480 | pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS); |
501 | rmb(); | 481 | rmb(); |
502 | for (i = 256; | 482 | for (i = 256; i; i--) |
503 | i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED); | 483 | if (pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED) |
504 | i--) | 484 | break; |
505 | ; | ||
506 | break; | 485 | break; |
507 | } | 486 | } |
508 | } | 487 | } |
@@ -515,17 +494,16 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk) | |||
515 | switch (par->type) { | 494 | switch (par->type) { |
516 | case PM2_TYPE_PERMEDIA2: | 495 | case PM2_TYPE_PERMEDIA2: |
517 | pm2_mnp(clk, &m, &n, &p); | 496 | pm2_mnp(clk, &m, &n, &p); |
518 | WAIT_FIFO(par, 8); | 497 | WAIT_FIFO(par, 10); |
519 | pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0); | 498 | pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0); |
520 | pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m); | 499 | pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m); |
521 | pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n); | 500 | pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n); |
522 | pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p); | 501 | pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p); |
523 | pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS); | 502 | pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS); |
524 | rmb(); | 503 | rmb(); |
525 | for (i = 256; | 504 | for (i = 256; i; i--) |
526 | i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED); | 505 | if (pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED) |
527 | i--) | 506 | break; |
528 | ; | ||
529 | break; | 507 | break; |
530 | case PM2_TYPE_PERMEDIA2V: | 508 | case PM2_TYPE_PERMEDIA2V: |
531 | pm2v_mnp(clk/2, &m, &n, &p); | 509 | pm2v_mnp(clk/2, &m, &n, &p); |
@@ -541,9 +519,7 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk) | |||
541 | 519 | ||
542 | static void set_video(struct pm2fb_par* p, u32 video) { | 520 | static void set_video(struct pm2fb_par* p, u32 video) { |
543 | u32 tmp; | 521 | u32 tmp; |
544 | u32 vsync; | 522 | u32 vsync = video; |
545 | |||
546 | vsync = video; | ||
547 | 523 | ||
548 | DPRINTK("video = 0x%x\n", video); | 524 | DPRINTK("video = 0x%x\n", video); |
549 | 525 | ||
@@ -553,8 +529,8 @@ static void set_video(struct pm2fb_par* p, u32 video) { | |||
553 | * driver may well. So always set +hsync/+vsync and then set | 529 | * driver may well. So always set +hsync/+vsync and then set |
554 | * the RAMDAC to invert the sync if necessary. | 530 | * the RAMDAC to invert the sync if necessary. |
555 | */ | 531 | */ |
556 | vsync &= ~(PM2F_HSYNC_MASK|PM2F_VSYNC_MASK); | 532 | vsync &= ~(PM2F_HSYNC_MASK | PM2F_VSYNC_MASK); |
557 | vsync |= PM2F_HSYNC_ACT_HIGH|PM2F_VSYNC_ACT_HIGH; | 533 | vsync |= PM2F_HSYNC_ACT_HIGH | PM2F_VSYNC_ACT_HIGH; |
558 | 534 | ||
559 | WAIT_FIFO(p, 5); | 535 | WAIT_FIFO(p, 5); |
560 | pm2_WR(p, PM2R_VIDEO_CONTROL, vsync); | 536 | pm2_WR(p, PM2R_VIDEO_CONTROL, vsync); |
@@ -581,10 +557,6 @@ static void set_video(struct pm2fb_par* p, u32 video) { | |||
581 | } | 557 | } |
582 | 558 | ||
583 | /* | 559 | /* |
584 | * | ||
585 | */ | ||
586 | |||
587 | /** | ||
588 | * pm2fb_check_var - Optional function. Validates a var passed in. | 560 | * pm2fb_check_var - Optional function. Validates a var passed in. |
589 | * @var: frame buffer variable screen structure | 561 | * @var: frame buffer variable screen structure |
590 | * @info: frame buffer structure that represents a single frame buffer | 562 | * @info: frame buffer structure that represents a single frame buffer |
@@ -625,7 +597,7 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
625 | } | 597 | } |
626 | 598 | ||
627 | var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */ | 599 | var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */ |
628 | lpitch = var->xres * ((var->bits_per_pixel + 7)>>3); | 600 | lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3); |
629 | 601 | ||
630 | if (var->xres < 320 || var->xres > 1600) { | 602 | if (var->xres < 320 || var->xres > 1600) { |
631 | DPRINTK("width not supported: %u\n", var->xres); | 603 | DPRINTK("width not supported: %u\n", var->xres); |
@@ -702,7 +674,9 @@ static int pm2fb_set_par(struct fb_info *info) | |||
702 | { | 674 | { |
703 | struct pm2fb_par *par = info->par; | 675 | struct pm2fb_par *par = info->par; |
704 | u32 pixclock; | 676 | u32 pixclock; |
705 | u32 width, height, depth; | 677 | u32 width = (info->var.xres_virtual + 7) & ~7; |
678 | u32 height = info->var.yres_virtual; | ||
679 | u32 depth = (info->var.bits_per_pixel + 7) & ~7; | ||
706 | u32 hsstart, hsend, hbend, htotal; | 680 | u32 hsstart, hsend, hbend, htotal; |
707 | u32 vsstart, vsend, vbend, vtotal; | 681 | u32 vsstart, vsend, vbend, vtotal; |
708 | u32 stride; | 682 | u32 stride; |
@@ -712,22 +686,18 @@ static int pm2fb_set_par(struct fb_info *info) | |||
712 | u32 txtmap = 0; | 686 | u32 txtmap = 0; |
713 | u32 pixsize = 0; | 687 | u32 pixsize = 0; |
714 | u32 clrformat = 0; | 688 | u32 clrformat = 0; |
715 | u32 xres; | 689 | u32 xres = (info->var.xres + 31) & ~31; |
716 | int data64; | 690 | int data64; |
717 | 691 | ||
718 | reset_card(par); | 692 | reset_card(par); |
719 | reset_config(par); | 693 | reset_config(par); |
720 | clear_palette(par); | 694 | clear_palette(par); |
721 | if ( par->memclock ) | 695 | if (par->memclock) |
722 | set_memclock(par, par->memclock); | 696 | set_memclock(par, par->memclock); |
723 | 697 | ||
724 | width = (info->var.xres_virtual + 7) & ~7; | ||
725 | height = info->var.yres_virtual; | ||
726 | depth = (info->var.bits_per_pixel + 7) & ~7; | ||
727 | depth = (depth > 32) ? 32 : depth; | 698 | depth = (depth > 32) ? 32 : depth; |
728 | data64 = depth > 8 || par->type == PM2_TYPE_PERMEDIA2V; | 699 | data64 = depth > 8 || par->type == PM2_TYPE_PERMEDIA2V; |
729 | 700 | ||
730 | xres = (info->var.xres + 31) & ~31; | ||
731 | pixclock = PICOS2KHZ(info->var.pixclock); | 701 | pixclock = PICOS2KHZ(info->var.pixclock); |
732 | if (pixclock > PM2_MAX_PIXCLOCK) { | 702 | if (pixclock > PM2_MAX_PIXCLOCK) { |
733 | DPRINTK("pixclock too high (%uKHz)\n", pixclock); | 703 | DPRINTK("pixclock too high (%uKHz)\n", pixclock); |
@@ -767,13 +737,13 @@ static int pm2fb_set_par(struct fb_info *info) | |||
767 | } | 737 | } |
768 | else | 738 | else |
769 | video |= PM2F_VSYNC_ACT_LOW; | 739 | video |= PM2F_VSYNC_ACT_LOW; |
770 | if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_INTERLACED) { | 740 | if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { |
771 | DPRINTK("interlaced not supported\n"); | 741 | DPRINTK("interlaced not supported\n"); |
772 | return -EINVAL; | 742 | return -EINVAL; |
773 | } | 743 | } |
774 | if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE) | 744 | if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) |
775 | video |= PM2F_LINE_DOUBLE; | 745 | video |= PM2F_LINE_DOUBLE; |
776 | if ((info->var.activate & FB_ACTIVATE_MASK)==FB_ACTIVATE_NOW) | 746 | if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) |
777 | video |= PM2F_VIDEO_ENABLE; | 747 | video |= PM2F_VIDEO_ENABLE; |
778 | par->video = video; | 748 | par->video = video; |
779 | 749 | ||
@@ -794,8 +764,6 @@ static int pm2fb_set_par(struct fb_info *info) | |||
794 | 764 | ||
795 | mb(); | 765 | mb(); |
796 | WAIT_FIFO(par, 19); | 766 | WAIT_FIFO(par, 19); |
797 | pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL, | ||
798 | ( depth == 8 ) ? 0 : PM2F_COLOR_KEY_TEST_OFF); | ||
799 | switch (depth) { | 767 | switch (depth) { |
800 | case 8: | 768 | case 8: |
801 | pm2_WR(par, PM2R_FB_READ_PIXEL, 0); | 769 | pm2_WR(par, PM2R_FB_READ_PIXEL, 0); |
@@ -845,14 +813,18 @@ static int pm2fb_set_par(struct fb_info *info) | |||
845 | pm2_WR(par, PM2R_SCREEN_BASE, base); | 813 | pm2_WR(par, PM2R_SCREEN_BASE, base); |
846 | wmb(); | 814 | wmb(); |
847 | set_video(par, video); | 815 | set_video(par, video); |
848 | WAIT_FIFO(par, 4); | 816 | WAIT_FIFO(par, 6); |
849 | switch (par->type) { | 817 | switch (par->type) { |
850 | case PM2_TYPE_PERMEDIA2: | 818 | case PM2_TYPE_PERMEDIA2: |
851 | pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE, clrmode); | 819 | pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE, clrmode); |
820 | pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL, | ||
821 | (depth == 8) ? 0 : PM2F_COLOR_KEY_TEST_OFF); | ||
852 | break; | 822 | break; |
853 | case PM2_TYPE_PERMEDIA2V: | 823 | case PM2_TYPE_PERMEDIA2V: |
854 | pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize); | 824 | pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize); |
855 | pm2v_RDAC_WR(par, PM2VI_RD_COLOR_FORMAT, clrformat); | 825 | pm2v_RDAC_WR(par, PM2VI_RD_COLOR_FORMAT, clrformat); |
826 | pm2v_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL, | ||
827 | (depth == 8) ? 0 : PM2F_COLOR_KEY_TEST_OFF); | ||
856 | break; | 828 | break; |
857 | } | 829 | } |
858 | set_pixclock(par, pixclock); | 830 | set_pixclock(par, pixclock); |
@@ -983,11 +955,9 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var, | |||
983 | { | 955 | { |
984 | struct pm2fb_par *p = info->par; | 956 | struct pm2fb_par *p = info->par; |
985 | u32 base; | 957 | u32 base; |
986 | u32 depth; | 958 | u32 depth = (var->bits_per_pixel + 7) & ~7; |
987 | u32 xres; | 959 | u32 xres = (var->xres + 31) & ~31; |
988 | 960 | ||
989 | xres = (var->xres + 31) & ~31; | ||
990 | depth = (var->bits_per_pixel + 7) & ~7; | ||
991 | depth = (depth > 32) ? 32 : depth; | 961 | depth = (depth > 32) ? 32 : depth; |
992 | base = to3264(var->yoffset * xres + var->xoffset, depth, 1); | 962 | base = to3264(var->yoffset * xres + var->xoffset, depth, 1); |
993 | WAIT_FIFO(p, 1); | 963 | WAIT_FIFO(p, 1); |
@@ -1029,11 +999,11 @@ static int pm2fb_blank(int blank_mode, struct fb_info *info) | |||
1029 | break; | 999 | break; |
1030 | case FB_BLANK_VSYNC_SUSPEND: | 1000 | case FB_BLANK_VSYNC_SUSPEND: |
1031 | /* VSync: Off */ | 1001 | /* VSync: Off */ |
1032 | video &= ~(PM2F_VSYNC_MASK | PM2F_BLANK_LOW ); | 1002 | video &= ~(PM2F_VSYNC_MASK | PM2F_BLANK_LOW); |
1033 | break; | 1003 | break; |
1034 | case FB_BLANK_HSYNC_SUSPEND: | 1004 | case FB_BLANK_HSYNC_SUSPEND: |
1035 | /* HSync: Off */ | 1005 | /* HSync: Off */ |
1036 | video &= ~(PM2F_HSYNC_MASK | PM2F_BLANK_LOW ); | 1006 | video &= ~(PM2F_HSYNC_MASK | PM2F_BLANK_LOW); |
1037 | break; | 1007 | break; |
1038 | case FB_BLANK_POWERDOWN: | 1008 | case FB_BLANK_POWERDOWN: |
1039 | /* HSync: Off, VSync: Off */ | 1009 | /* HSync: Off, VSync: Off */ |
@@ -1060,37 +1030,10 @@ static int pm2fb_sync(struct fb_info *info) | |||
1060 | return 0; | 1030 | return 0; |
1061 | } | 1031 | } |
1062 | 1032 | ||
1063 | /* | ||
1064 | * block operation. copy=0: rectangle fill, copy=1: rectangle copy. | ||
1065 | */ | ||
1066 | static void pm2fb_block_op(struct fb_info* info, int copy, | ||
1067 | s32 xsrc, s32 ysrc, | ||
1068 | s32 x, s32 y, s32 w, s32 h, | ||
1069 | u32 color) { | ||
1070 | struct pm2fb_par *par = info->par; | ||
1071 | |||
1072 | if (!w || !h) | ||
1073 | return; | ||
1074 | WAIT_FIFO(par, 5); | ||
1075 | pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE | | ||
1076 | PM2F_CONFIG_FB_READ_SOURCE_ENABLE); | ||
1077 | if (copy) | ||
1078 | pm2_WR(par, PM2R_FB_SOURCE_DELTA, | ||
1079 | ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff)); | ||
1080 | else | ||
1081 | pm2_WR(par, PM2R_FB_BLOCK_COLOR, color); | ||
1082 | pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (y << 16) | x); | ||
1083 | pm2_WR(par, PM2R_RECTANGLE_SIZE, (h << 16) | w); | ||
1084 | wmb(); | ||
1085 | pm2_WR(par, PM2R_RENDER, PM2F_RENDER_RECTANGLE | | ||
1086 | (x<xsrc ? PM2F_INCREASE_X : 0) | | ||
1087 | (y<ysrc ? PM2F_INCREASE_Y : 0) | | ||
1088 | (copy ? 0 : PM2F_RENDER_FASTFILL)); | ||
1089 | } | ||
1090 | |||
1091 | static void pm2fb_fillrect (struct fb_info *info, | 1033 | static void pm2fb_fillrect (struct fb_info *info, |
1092 | const struct fb_fillrect *region) | 1034 | const struct fb_fillrect *region) |
1093 | { | 1035 | { |
1036 | struct pm2fb_par *par = info->par; | ||
1094 | struct fb_fillrect modded; | 1037 | struct fb_fillrect modded; |
1095 | int vxres, vyres; | 1038 | int vxres, vyres; |
1096 | u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? | 1039 | u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? |
@@ -1109,31 +1052,39 @@ static void pm2fb_fillrect (struct fb_info *info, | |||
1109 | 1052 | ||
1110 | memcpy(&modded, region, sizeof(struct fb_fillrect)); | 1053 | memcpy(&modded, region, sizeof(struct fb_fillrect)); |
1111 | 1054 | ||
1112 | if(!modded.width || !modded.height || | 1055 | if (!modded.width || !modded.height || |
1113 | modded.dx >= vxres || modded.dy >= vyres) | 1056 | modded.dx >= vxres || modded.dy >= vyres) |
1114 | return; | 1057 | return; |
1115 | 1058 | ||
1116 | if(modded.dx + modded.width > vxres) | 1059 | if (modded.dx + modded.width > vxres) |
1117 | modded.width = vxres - modded.dx; | 1060 | modded.width = vxres - modded.dx; |
1118 | if(modded.dy + modded.height > vyres) | 1061 | if (modded.dy + modded.height > vyres) |
1119 | modded.height = vyres - modded.dy; | 1062 | modded.height = vyres - modded.dy; |
1120 | 1063 | ||
1121 | if(info->var.bits_per_pixel == 8) | 1064 | if (info->var.bits_per_pixel == 8) |
1122 | color |= color << 8; | 1065 | color |= color << 8; |
1123 | if(info->var.bits_per_pixel <= 16) | 1066 | if (info->var.bits_per_pixel <= 16) |
1124 | color |= color << 16; | 1067 | color |= color << 16; |
1125 | 1068 | ||
1126 | if(info->var.bits_per_pixel != 24) | 1069 | WAIT_FIFO(par, 3); |
1127 | pm2fb_block_op(info, 0, 0, 0, | 1070 | pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE); |
1128 | modded.dx, modded.dy, | 1071 | pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (modded.dy << 16) | modded.dx); |
1129 | modded.width, modded.height, color); | 1072 | pm2_WR(par, PM2R_RECTANGLE_SIZE, (modded.height << 16) | modded.width); |
1130 | else | 1073 | if (info->var.bits_per_pixel != 24) { |
1074 | WAIT_FIFO(par, 2); | ||
1075 | pm2_WR(par, PM2R_FB_BLOCK_COLOR, color); | ||
1076 | wmb(); | ||
1077 | pm2_WR(par, PM2R_RENDER, | ||
1078 | PM2F_RENDER_RECTANGLE | PM2F_RENDER_FASTFILL); | ||
1079 | } else { | ||
1131 | cfb_fillrect(info, region); | 1080 | cfb_fillrect(info, region); |
1081 | } | ||
1132 | } | 1082 | } |
1133 | 1083 | ||
1134 | static void pm2fb_copyarea(struct fb_info *info, | 1084 | static void pm2fb_copyarea(struct fb_info *info, |
1135 | const struct fb_copyarea *area) | 1085 | const struct fb_copyarea *area) |
1136 | { | 1086 | { |
1087 | struct pm2fb_par *par = info->par; | ||
1137 | struct fb_copyarea modded; | 1088 | struct fb_copyarea modded; |
1138 | u32 vxres, vyres; | 1089 | u32 vxres, vyres; |
1139 | 1090 | ||
@@ -1149,23 +1100,32 @@ static void pm2fb_copyarea(struct fb_info *info, | |||
1149 | vxres = info->var.xres_virtual; | 1100 | vxres = info->var.xres_virtual; |
1150 | vyres = info->var.yres_virtual; | 1101 | vyres = info->var.yres_virtual; |
1151 | 1102 | ||
1152 | if(!modded.width || !modded.height || | 1103 | if (!modded.width || !modded.height || |
1153 | modded.sx >= vxres || modded.sy >= vyres || | 1104 | modded.sx >= vxres || modded.sy >= vyres || |
1154 | modded.dx >= vxres || modded.dy >= vyres) | 1105 | modded.dx >= vxres || modded.dy >= vyres) |
1155 | return; | 1106 | return; |
1156 | 1107 | ||
1157 | if(modded.sx + modded.width > vxres) | 1108 | if (modded.sx + modded.width > vxres) |
1158 | modded.width = vxres - modded.sx; | 1109 | modded.width = vxres - modded.sx; |
1159 | if(modded.dx + modded.width > vxres) | 1110 | if (modded.dx + modded.width > vxres) |
1160 | modded.width = vxres - modded.dx; | 1111 | modded.width = vxres - modded.dx; |
1161 | if(modded.sy + modded.height > vyres) | 1112 | if (modded.sy + modded.height > vyres) |
1162 | modded.height = vyres - modded.sy; | 1113 | modded.height = vyres - modded.sy; |
1163 | if(modded.dy + modded.height > vyres) | 1114 | if (modded.dy + modded.height > vyres) |
1164 | modded.height = vyres - modded.dy; | 1115 | modded.height = vyres - modded.dy; |
1165 | 1116 | ||
1166 | pm2fb_block_op(info, 1, modded.sx, modded.sy, | 1117 | WAIT_FIFO(par, 5); |
1167 | modded.dx, modded.dy, | 1118 | pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE | |
1168 | modded.width, modded.height, 0); | 1119 | PM2F_CONFIG_FB_READ_SOURCE_ENABLE); |
1120 | pm2_WR(par, PM2R_FB_SOURCE_DELTA, | ||
1121 | ((modded.sy-modded.dy) & 0xfff) << 16 | | ||
1122 | ((modded.sx-modded.dx) & 0xfff)); | ||
1123 | pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (modded.dy << 16) | modded.dx); | ||
1124 | pm2_WR(par, PM2R_RECTANGLE_SIZE, (modded.height << 16) | modded.width); | ||
1125 | wmb(); | ||
1126 | pm2_WR(par, PM2R_RENDER, PM2F_RENDER_RECTANGLE | | ||
1127 | (modded.dx<modded.sx ? PM2F_INCREASE_X : 0) | | ||
1128 | (modded.dy<modded.sy ? PM2F_INCREASE_Y : 0)); | ||
1169 | } | 1129 | } |
1170 | 1130 | ||
1171 | static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image) | 1131 | static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image) |
@@ -1183,15 +1143,15 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1183 | return; | 1143 | return; |
1184 | } | 1144 | } |
1185 | switch (info->fix.visual) { | 1145 | switch (info->fix.visual) { |
1186 | case FB_VISUAL_PSEUDOCOLOR: | 1146 | case FB_VISUAL_PSEUDOCOLOR: |
1187 | fgx = image->fg_color; | 1147 | fgx = image->fg_color; |
1188 | bgx = image->bg_color; | 1148 | bgx = image->bg_color; |
1189 | break; | 1149 | break; |
1190 | case FB_VISUAL_TRUECOLOR: | 1150 | case FB_VISUAL_TRUECOLOR: |
1191 | default: | 1151 | default: |
1192 | fgx = par->palette[image->fg_color]; | 1152 | fgx = par->palette[image->fg_color]; |
1193 | bgx = par->palette[image->bg_color]; | 1153 | bgx = par->palette[image->bg_color]; |
1194 | break; | 1154 | break; |
1195 | } | 1155 | } |
1196 | if (info->var.bits_per_pixel == 8) { | 1156 | if (info->var.bits_per_pixel == 8) { |
1197 | fgx |= fgx << 8; | 1157 | fgx |= fgx << 8; |
@@ -1211,7 +1171,7 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1211 | ((image->dx + image->width) & 0x0fff)); | 1171 | ((image->dx + image->width) & 0x0fff)); |
1212 | pm2_WR(par, PM2R_SCISSOR_MODE, 1); | 1172 | pm2_WR(par, PM2R_SCISSOR_MODE, 1); |
1213 | /* GXcopy & UNIT_ENABLE */ | 1173 | /* GXcopy & UNIT_ENABLE */ |
1214 | pm2_WR(par, PM2R_LOGICAL_OP_MODE, (0x3 << 1) | 1 ); | 1174 | pm2_WR(par, PM2R_LOGICAL_OP_MODE, (0x3 << 1) | 1); |
1215 | pm2_WR(par, PM2R_RECTANGLE_ORIGIN, | 1175 | pm2_WR(par, PM2R_RECTANGLE_ORIGIN, |
1216 | ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff)); | 1176 | ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff)); |
1217 | pm2_WR(par, PM2R_RECTANGLE_SIZE, | 1177 | pm2_WR(par, PM2R_RECTANGLE_SIZE, |
@@ -1223,10 +1183,10 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1223 | pm2_WR(par, PM2R_CONSTANT_COLOR, bgx); | 1183 | pm2_WR(par, PM2R_CONSTANT_COLOR, bgx); |
1224 | pm2_WR(par, PM2R_RENDER, | 1184 | pm2_WR(par, PM2R_RENDER, |
1225 | PM2F_RENDER_RECTANGLE | | 1185 | PM2F_RENDER_RECTANGLE | |
1226 | PM2F_INCREASE_X | PM2F_INCREASE_Y ); | 1186 | PM2F_INCREASE_X | PM2F_INCREASE_Y); |
1227 | /* BitMapPackEachScanline & invert bits and byte order*/ | 1187 | /* BitMapPackEachScanline & invert bits and byte order*/ |
1228 | /* force background */ | 1188 | /* force background */ |
1229 | pm2_WR(par, PM2R_RASTERIZER_MODE, (1<<9) | 1 | (3<<7)); | 1189 | pm2_WR(par, PM2R_RASTERIZER_MODE, (1 << 9) | 1 | (3 << 7)); |
1230 | pm2_WR(par, PM2R_CONSTANT_COLOR, fgx); | 1190 | pm2_WR(par, PM2R_CONSTANT_COLOR, fgx); |
1231 | pm2_WR(par, PM2R_RENDER, | 1191 | pm2_WR(par, PM2R_RENDER, |
1232 | PM2F_RENDER_RECTANGLE | | 1192 | PM2F_RENDER_RECTANGLE | |
@@ -1239,9 +1199,9 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1239 | pm2_WR(par, PM2R_RENDER, | 1199 | pm2_WR(par, PM2R_RENDER, |
1240 | PM2F_RENDER_RECTANGLE | | 1200 | PM2F_RENDER_RECTANGLE | |
1241 | PM2F_RENDER_FASTFILL | | 1201 | PM2F_RENDER_FASTFILL | |
1242 | PM2F_INCREASE_X | PM2F_INCREASE_Y ); | 1202 | PM2F_INCREASE_X | PM2F_INCREASE_Y); |
1243 | /* invert bits and byte order*/ | 1203 | /* invert bits and byte order*/ |
1244 | pm2_WR(par, PM2R_RASTERIZER_MODE, 1 | (3<<7) ); | 1204 | pm2_WR(par, PM2R_RASTERIZER_MODE, 1 | (3 << 7)); |
1245 | pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx); | 1205 | pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx); |
1246 | pm2_WR(par, PM2R_RENDER, | 1206 | pm2_WR(par, PM2R_RENDER, |
1247 | PM2F_RENDER_RECTANGLE | | 1207 | PM2F_RENDER_RECTANGLE | |
@@ -1306,13 +1266,13 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1306 | int err, err_retval = -ENXIO; | 1266 | int err, err_retval = -ENXIO; |
1307 | 1267 | ||
1308 | err = pci_enable_device(pdev); | 1268 | err = pci_enable_device(pdev); |
1309 | if ( err ) { | 1269 | if (err) { |
1310 | printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err); | 1270 | printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err); |
1311 | return err; | 1271 | return err; |
1312 | } | 1272 | } |
1313 | 1273 | ||
1314 | info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev); | 1274 | info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev); |
1315 | if ( !info ) | 1275 | if (!info) |
1316 | return -ENOMEM; | 1276 | return -ENOMEM; |
1317 | default_par = info->par; | 1277 | default_par = info->par; |
1318 | 1278 | ||
@@ -1345,14 +1305,14 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1345 | DPRINTK("Register base at 0x%lx\n", pm2fb_fix.mmio_start); | 1305 | DPRINTK("Register base at 0x%lx\n", pm2fb_fix.mmio_start); |
1346 | 1306 | ||
1347 | /* Registers - request region and map it. */ | 1307 | /* Registers - request region and map it. */ |
1348 | if ( !request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len, | 1308 | if (!request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len, |
1349 | "pm2fb regbase") ) { | 1309 | "pm2fb regbase")) { |
1350 | printk(KERN_WARNING "pm2fb: Can't reserve regbase.\n"); | 1310 | printk(KERN_WARNING "pm2fb: Can't reserve regbase.\n"); |
1351 | goto err_exit_neither; | 1311 | goto err_exit_neither; |
1352 | } | 1312 | } |
1353 | default_par->v_regs = | 1313 | default_par->v_regs = |
1354 | ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); | 1314 | ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); |
1355 | if ( !default_par->v_regs ) { | 1315 | if (!default_par->v_regs) { |
1356 | printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n", | 1316 | printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n", |
1357 | pm2fb_fix.id); | 1317 | pm2fb_fix.id); |
1358 | release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); | 1318 | release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); |
@@ -1367,13 +1327,13 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1367 | default_par->mem_control, default_par->boot_address, | 1327 | default_par->mem_control, default_par->boot_address, |
1368 | default_par->mem_config); | 1328 | default_par->mem_config); |
1369 | 1329 | ||
1370 | if(default_par->mem_control == 0 && | 1330 | if (default_par->mem_control == 0 && |
1371 | default_par->boot_address == 0x31 && | 1331 | default_par->boot_address == 0x31 && |
1372 | default_par->mem_config == 0x259fffff) { | 1332 | default_par->mem_config == 0x259fffff) { |
1373 | default_par->memclock = CVPPC_MEMCLOCK; | 1333 | default_par->memclock = CVPPC_MEMCLOCK; |
1374 | default_par->mem_control=0; | 1334 | default_par->mem_control = 0; |
1375 | default_par->boot_address=0x20; | 1335 | default_par->boot_address = 0x20; |
1376 | default_par->mem_config=0xe6002021; | 1336 | default_par->mem_config = 0xe6002021; |
1377 | if (pdev->subsystem_vendor == 0x1048 && | 1337 | if (pdev->subsystem_vendor == 0x1048 && |
1378 | pdev->subsystem_device == 0x0a31) { | 1338 | pdev->subsystem_device == 0x0a31) { |
1379 | DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", | 1339 | DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", |
@@ -1381,7 +1341,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1381 | DPRINTK("We have not been initialized by VGA BIOS " | 1341 | DPRINTK("We have not been initialized by VGA BIOS " |
1382 | "and are running on an Elsa Winner 2000 Office\n"); | 1342 | "and are running on an Elsa Winner 2000 Office\n"); |
1383 | DPRINTK("Initializing card timings manually...\n"); | 1343 | DPRINTK("Initializing card timings manually...\n"); |
1384 | default_par->memclock=70000; | 1344 | default_par->memclock = 70000; |
1385 | } | 1345 | } |
1386 | if (pdev->subsystem_vendor == 0x3d3d && | 1346 | if (pdev->subsystem_vendor == 0x3d3d && |
1387 | pdev->subsystem_device == 0x0100) { | 1347 | pdev->subsystem_device == 0x0100) { |
@@ -1390,36 +1350,36 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1390 | DPRINTK("We have not been initialized by VGA BIOS " | 1350 | DPRINTK("We have not been initialized by VGA BIOS " |
1391 | "and are running on an 3dlabs reference board\n"); | 1351 | "and are running on an 3dlabs reference board\n"); |
1392 | DPRINTK("Initializing card timings manually...\n"); | 1352 | DPRINTK("Initializing card timings manually...\n"); |
1393 | default_par->memclock=74894; | 1353 | default_par->memclock = 74894; |
1394 | } | 1354 | } |
1395 | } | 1355 | } |
1396 | 1356 | ||
1397 | /* Now work out how big lfb is going to be. */ | 1357 | /* Now work out how big lfb is going to be. */ |
1398 | switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) { | 1358 | switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) { |
1399 | case PM2F_MEM_BANKS_1: | 1359 | case PM2F_MEM_BANKS_1: |
1400 | pm2fb_fix.smem_len=0x200000; | 1360 | pm2fb_fix.smem_len = 0x200000; |
1401 | break; | 1361 | break; |
1402 | case PM2F_MEM_BANKS_2: | 1362 | case PM2F_MEM_BANKS_2: |
1403 | pm2fb_fix.smem_len=0x400000; | 1363 | pm2fb_fix.smem_len = 0x400000; |
1404 | break; | 1364 | break; |
1405 | case PM2F_MEM_BANKS_3: | 1365 | case PM2F_MEM_BANKS_3: |
1406 | pm2fb_fix.smem_len=0x600000; | 1366 | pm2fb_fix.smem_len = 0x600000; |
1407 | break; | 1367 | break; |
1408 | case PM2F_MEM_BANKS_4: | 1368 | case PM2F_MEM_BANKS_4: |
1409 | pm2fb_fix.smem_len=0x800000; | 1369 | pm2fb_fix.smem_len = 0x800000; |
1410 | break; | 1370 | break; |
1411 | } | 1371 | } |
1412 | pm2fb_fix.smem_start = pci_resource_start(pdev, 1); | 1372 | pm2fb_fix.smem_start = pci_resource_start(pdev, 1); |
1413 | 1373 | ||
1414 | /* Linear frame buffer - request region and map it. */ | 1374 | /* Linear frame buffer - request region and map it. */ |
1415 | if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len, | 1375 | if (!request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len, |
1416 | "pm2fb smem") ) { | 1376 | "pm2fb smem")) { |
1417 | printk(KERN_WARNING "pm2fb: Can't reserve smem.\n"); | 1377 | printk(KERN_WARNING "pm2fb: Can't reserve smem.\n"); |
1418 | goto err_exit_mmio; | 1378 | goto err_exit_mmio; |
1419 | } | 1379 | } |
1420 | info->screen_base = | 1380 | info->screen_base = |
1421 | ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len); | 1381 | ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len); |
1422 | if ( !info->screen_base ) { | 1382 | if (!info->screen_base) { |
1423 | printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n"); | 1383 | printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n"); |
1424 | release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); | 1384 | release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); |
1425 | goto err_exit_mmio; | 1385 | goto err_exit_mmio; |
@@ -1571,9 +1531,9 @@ static int __init pm2fb_setup(char *options) | |||
1571 | while ((this_opt = strsep(&options, ",")) != NULL) { | 1531 | while ((this_opt = strsep(&options, ",")) != NULL) { |
1572 | if (!*this_opt) | 1532 | if (!*this_opt) |
1573 | continue; | 1533 | continue; |
1574 | if(!strcmp(this_opt, "lowhsync")) { | 1534 | if (!strcmp(this_opt, "lowhsync")) { |
1575 | lowhsync = 1; | 1535 | lowhsync = 1; |
1576 | } else if(!strcmp(this_opt, "lowvsync")) { | 1536 | } else if (!strcmp(this_opt, "lowvsync")) { |
1577 | lowvsync = 1; | 1537 | lowvsync = 1; |
1578 | #ifdef CONFIG_MTRR | 1538 | #ifdef CONFIG_MTRR |
1579 | } else if (!strncmp(this_opt, "nomtrr", 6)) { | 1539 | } else if (!strncmp(this_opt, "nomtrr", 6)) { |