diff options
Diffstat (limited to 'drivers/video/s1d13xxxfb.c')
| -rw-r--r-- | drivers/video/s1d13xxxfb.c | 341 |
1 files changed, 308 insertions, 33 deletions
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index 0726aecf3b7e..0deb0a8867b7 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * | 2 | * |
| 3 | * (c) 2004 Simtec Electronics | 3 | * (c) 2004 Simtec Electronics |
| 4 | * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org> | 4 | * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org> |
| 5 | * (c) 2009 Kristoffer Ericson <kristoffer.ericson@gmail.com> | ||
| 5 | * | 6 | * |
| 6 | * Driver for Epson S1D13xxx series framebuffer chips | 7 | * Driver for Epson S1D13xxx series framebuffer chips |
| 7 | * | 8 | * |
| @@ -10,18 +11,10 @@ | |||
| 10 | * linux/drivers/video/epson1355fb.c | 11 | * linux/drivers/video/epson1355fb.c |
| 11 | * linux/drivers/video/epson/s1d13xxxfb.c (2.4 driver by Epson) | 12 | * linux/drivers/video/epson/s1d13xxxfb.c (2.4 driver by Epson) |
| 12 | * | 13 | * |
| 13 | * Note, currently only tested on S1D13806 with 16bit CRT. | ||
| 14 | * As such, this driver might still contain some hardcoded bits relating to | ||
| 15 | * S1D13806. | ||
| 16 | * Making it work on other S1D13XXX chips should merely be a matter of adding | ||
| 17 | * a few switch()s, some missing glue here and there maybe, and split header | ||
| 18 | * files. | ||
| 19 | * | ||
| 20 | * TODO: - handle dual screen display (CRT and LCD at the same time). | 14 | * TODO: - handle dual screen display (CRT and LCD at the same time). |
| 21 | * - check_var(), mode change, etc. | 15 | * - check_var(), mode change, etc. |
| 22 | * - PM untested. | 16 | * - probably not SMP safe :) |
| 23 | * - Accelerated interfaces. | 17 | * - support all bitblt operations on all cards |
| 24 | * - Probably not SMP safe :) | ||
| 25 | * | 18 | * |
| 26 | * This file is subject to the terms and conditions of the GNU General Public | 19 | * This file is subject to the terms and conditions of the GNU General Public |
| 27 | * License. See the file COPYING in the main directory of this archive for | 20 | * License. See the file COPYING in the main directory of this archive for |
| @@ -31,19 +24,24 @@ | |||
| 31 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 32 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
| 33 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
| 34 | |||
| 35 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| 36 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
| 37 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
| 38 | #include <linux/mman.h> | 30 | #include <linux/mman.h> |
| 39 | #include <linux/fb.h> | 31 | #include <linux/fb.h> |
| 32 | #include <linux/spinlock_types.h> | ||
| 33 | #include <linux/spinlock.h> | ||
| 40 | 34 | ||
| 41 | #include <asm/io.h> | 35 | #include <asm/io.h> |
| 42 | 36 | ||
| 43 | #include <video/s1d13xxxfb.h> | 37 | #include <video/s1d13xxxfb.h> |
| 44 | 38 | ||
| 45 | #define PFX "s1d13xxxfb: " | 39 | #define PFX "s1d13xxxfb: " |
| 40 | #define BLIT "s1d13xxxfb_bitblt: " | ||
| 46 | 41 | ||
| 42 | /* | ||
| 43 | * set this to enable debugging on general functions | ||
| 44 | */ | ||
| 47 | #if 0 | 45 | #if 0 |
| 48 | #define dbg(fmt, args...) do { printk(KERN_INFO fmt, ## args); } while(0) | 46 | #define dbg(fmt, args...) do { printk(KERN_INFO fmt, ## args); } while(0) |
| 49 | #else | 47 | #else |
| @@ -51,7 +49,21 @@ | |||
| 51 | #endif | 49 | #endif |
| 52 | 50 | ||
| 53 | /* | 51 | /* |
| 54 | * List of card production ids | 52 | * set this to enable debugging on 2D acceleration |
| 53 | */ | ||
| 54 | #if 0 | ||
| 55 | #define dbg_blit(fmt, args...) do { printk(KERN_INFO BLIT fmt, ## args); } while (0) | ||
| 56 | #else | ||
| 57 | #define dbg_blit(fmt, args...) do { } while (0) | ||
| 58 | #endif | ||
| 59 | |||
| 60 | /* | ||
| 61 | * we make sure only one bitblt operation is running | ||
| 62 | */ | ||
| 63 | static DEFINE_SPINLOCK(s1d13xxxfb_bitblt_lock); | ||
| 64 | |||
| 65 | /* | ||
| 66 | * list of card production ids | ||
| 55 | */ | 67 | */ |
| 56 | static const int s1d13xxxfb_prod_ids[] = { | 68 | static const int s1d13xxxfb_prod_ids[] = { |
| 57 | S1D13505_PROD_ID, | 69 | S1D13505_PROD_ID, |
| @@ -69,7 +81,7 @@ static const char *s1d13xxxfb_prod_names[] = { | |||
| 69 | }; | 81 | }; |
| 70 | 82 | ||
| 71 | /* | 83 | /* |
| 72 | * Here we define the default struct fb_fix_screeninfo | 84 | * here we define the default struct fb_fix_screeninfo |
| 73 | */ | 85 | */ |
| 74 | static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = { | 86 | static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = { |
| 75 | .id = S1D_FBID, | 87 | .id = S1D_FBID, |
| @@ -145,8 +157,10 @@ crt_enable(struct s1d13xxxfb_par *par, int enable) | |||
| 145 | s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, mode); | 157 | s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, mode); |
| 146 | } | 158 | } |
| 147 | 159 | ||
| 148 | /* framebuffer control routines */ | ||
| 149 | 160 | ||
| 161 | /************************************************************* | ||
| 162 | framebuffer control functions | ||
| 163 | *************************************************************/ | ||
| 150 | static inline void | 164 | static inline void |
| 151 | s1d13xxxfb_setup_pseudocolour(struct fb_info *info) | 165 | s1d13xxxfb_setup_pseudocolour(struct fb_info *info) |
| 152 | { | 166 | { |
| @@ -242,13 +256,13 @@ s1d13xxxfb_set_par(struct fb_info *info) | |||
| 242 | } | 256 | } |
| 243 | 257 | ||
| 244 | /** | 258 | /** |
| 245 | * s1d13xxxfb_setcolreg - sets a color register. | 259 | * s1d13xxxfb_setcolreg - sets a color register. |
| 246 | * @regno: Which register in the CLUT we are programming | 260 | * @regno: Which register in the CLUT we are programming |
| 247 | * @red: The red value which can be up to 16 bits wide | 261 | * @red: The red value which can be up to 16 bits wide |
| 248 | * @green: The green value which can be up to 16 bits wide | 262 | * @green: The green value which can be up to 16 bits wide |
| 249 | * @blue: The blue value which can be up to 16 bits wide. | 263 | * @blue: The blue value which can be up to 16 bits wide. |
| 250 | * @transp: If supported the alpha value which can be up to 16 bits wide. | 264 | * @transp: If supported the alpha value which can be up to 16 bits wide. |
| 251 | * @info: frame buffer info structure | 265 | * @info: frame buffer info structure |
| 252 | * | 266 | * |
| 253 | * Returns negative errno on error, or zero on success. | 267 | * Returns negative errno on error, or zero on success. |
| 254 | */ | 268 | */ |
| @@ -351,15 +365,15 @@ s1d13xxxfb_blank(int blank_mode, struct fb_info *info) | |||
| 351 | } | 365 | } |
| 352 | 366 | ||
| 353 | /** | 367 | /** |
| 354 | * s1d13xxxfb_pan_display - Pans the display. | 368 | * s1d13xxxfb_pan_display - Pans the display. |
| 355 | * @var: frame buffer variable screen structure | 369 | * @var: frame buffer variable screen structure |
| 356 | * @info: frame buffer structure that represents a single frame buffer | 370 | * @info: frame buffer structure that represents a single frame buffer |
| 357 | * | 371 | * |
| 358 | * Pan (or wrap, depending on the `vmode' field) the display using the | 372 | * Pan (or wrap, depending on the `vmode' field) the display using the |
| 359 | * `yoffset' field of the `var' structure (`xoffset' not yet supported). | 373 | * `yoffset' field of the `var' structure (`xoffset' not yet supported). |
| 360 | * If the values don't fit, return -EINVAL. | 374 | * If the values don't fit, return -EINVAL. |
| 361 | * | 375 | * |
| 362 | * Returns negative errno on error, or zero on success. | 376 | * Returns negative errno on error, or zero on success. |
| 363 | */ | 377 | */ |
| 364 | static int | 378 | static int |
| 365 | s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | 379 | s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) |
| @@ -390,8 +404,259 @@ s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | |||
| 390 | return 0; | 404 | return 0; |
| 391 | } | 405 | } |
| 392 | 406 | ||
| 393 | /* framebuffer information structures */ | 407 | /************************************************************ |
| 408 | functions to handle bitblt acceleration | ||
| 409 | ************************************************************/ | ||
| 410 | |||
| 411 | /** | ||
| 412 | * bltbit_wait_bitset - waits for change in register value | ||
| 413 | * @info : framebuffer structure | ||
| 414 | * @bit : value expected in register | ||
| 415 | * @timeout : ... | ||
| 416 | * | ||
| 417 | * waits until value changes INTO bit | ||
| 418 | */ | ||
| 419 | static u8 | ||
| 420 | bltbit_wait_bitset(struct fb_info *info, u8 bit, int timeout) | ||
| 421 | { | ||
| 422 | while (!(s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0) & bit)) { | ||
| 423 | udelay(10); | ||
| 424 | if (!--timeout) { | ||
| 425 | dbg_blit("wait_bitset timeout\n"); | ||
| 426 | break; | ||
| 427 | } | ||
| 428 | } | ||
| 429 | |||
| 430 | return timeout; | ||
| 431 | } | ||
| 432 | |||
| 433 | /** | ||
| 434 | * bltbit_wait_bitclear - waits for change in register value | ||
| 435 | * @info : frambuffer structure | ||
| 436 | * @bit : value currently in register | ||
| 437 | * @timeout : ... | ||
| 438 | * | ||
| 439 | * waits until value changes FROM bit | ||
| 440 | * | ||
| 441 | */ | ||
| 442 | static u8 | ||
| 443 | bltbit_wait_bitclear(struct fb_info *info, u8 bit, int timeout) | ||
| 444 | { | ||
| 445 | while (s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0) & bit) { | ||
| 446 | udelay(10); | ||
| 447 | if (!--timeout) { | ||
| 448 | dbg_blit("wait_bitclear timeout\n"); | ||
| 449 | break; | ||
| 450 | } | ||
| 451 | } | ||
| 452 | |||
| 453 | return timeout; | ||
| 454 | } | ||
| 455 | |||
| 456 | /** | ||
| 457 | * bltbit_fifo_status - checks the current status of the fifo | ||
| 458 | * @info : framebuffer structure | ||
| 459 | * | ||
| 460 | * returns number of free words in buffer | ||
| 461 | */ | ||
| 462 | static u8 | ||
| 463 | bltbit_fifo_status(struct fb_info *info) | ||
| 464 | { | ||
| 465 | u8 status; | ||
| 394 | 466 | ||
| 467 | status = s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0); | ||
| 468 | |||
| 469 | /* its empty so room for 16 words */ | ||
| 470 | if (status & BBLT_FIFO_EMPTY) | ||
| 471 | return 16; | ||
| 472 | |||
| 473 | /* its full so we dont want to add */ | ||
| 474 | if (status & BBLT_FIFO_FULL) | ||
| 475 | return 0; | ||
| 476 | |||
| 477 | /* its atleast half full but we can add one atleast */ | ||
| 478 | if (status & BBLT_FIFO_NOT_FULL) | ||
| 479 | return 1; | ||
| 480 | |||
| 481 | return 0; | ||
| 482 | } | ||
| 483 | |||
| 484 | /* | ||
| 485 | * s1d13xxxfb_bitblt_copyarea - accelerated copyarea function | ||
| 486 | * @info : framebuffer structure | ||
| 487 | * @area : fb_copyarea structure | ||
| 488 | * | ||
| 489 | * supports (atleast) S1D13506 | ||
| 490 | * | ||
| 491 | */ | ||
| 492 | static void | ||
| 493 | s1d13xxxfb_bitblt_copyarea(struct fb_info *info, const struct fb_copyarea *area) | ||
| 494 | { | ||
| 495 | u32 dst, src; | ||
| 496 | u32 stride; | ||
| 497 | u16 reverse = 0; | ||
| 498 | u16 sx = area->sx, sy = area->sy; | ||
| 499 | u16 dx = area->dx, dy = area->dy; | ||
| 500 | u16 width = area->width, height = area->height; | ||
| 501 | u16 bpp; | ||
| 502 | |||
| 503 | spin_lock(&s1d13xxxfb_bitblt_lock); | ||
| 504 | |||
| 505 | /* bytes per xres line */ | ||
| 506 | bpp = (info->var.bits_per_pixel >> 3); | ||
| 507 | stride = bpp * info->var.xres; | ||
| 508 | |||
| 509 | /* reverse, calculate the last pixel in rectangle */ | ||
| 510 | if ((dy > sy) || ((dy == sy) && (dx >= sx))) { | ||
| 511 | dst = (((dy + height - 1) * stride) + (bpp * (dx + width - 1))); | ||
| 512 | src = (((sy + height - 1) * stride) + (bpp * (sx + width - 1))); | ||
| 513 | reverse = 1; | ||
| 514 | /* not reverse, calculate the first pixel in rectangle */ | ||
| 515 | } else { /* (y * xres) + (bpp * x) */ | ||
| 516 | dst = (dy * stride) + (bpp * dx); | ||
| 517 | src = (sy * stride) + (bpp * sx); | ||
| 518 | } | ||
| 519 | |||
| 520 | /* set source adress */ | ||
| 521 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START0, (src & 0xff)); | ||
| 522 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START1, (src >> 8) & 0x00ff); | ||
| 523 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START2, (src >> 16) & 0x00ff); | ||
| 524 | |||
| 525 | /* set destination adress */ | ||
| 526 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dst & 0xff)); | ||
| 527 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, (dst >> 8) & 0x00ff); | ||
| 528 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, (dst >> 16) & 0x00ff); | ||
| 529 | |||
| 530 | /* program height and width */ | ||
| 531 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH0, (width & 0xff) - 1); | ||
| 532 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH1, (width >> 8)); | ||
| 533 | |||
| 534 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT0, (height & 0xff) - 1); | ||
| 535 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT1, (height >> 8)); | ||
| 536 | |||
| 537 | /* negative direction ROP */ | ||
| 538 | if (reverse == 1) { | ||
| 539 | dbg_blit("(copyarea) negative rop\n"); | ||
| 540 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, 0x03); | ||
| 541 | } else /* positive direction ROP */ { | ||
| 542 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, 0x02); | ||
| 543 | dbg_blit("(copyarea) positive rop\n"); | ||
| 544 | } | ||
| 545 | |||
| 546 | /* set for rectangel mode and not linear */ | ||
| 547 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x0); | ||
| 548 | |||
| 549 | /* setup the bpp 1 = 16bpp, 0 = 8bpp*/ | ||
| 550 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL1, (bpp >> 1)); | ||
| 551 | |||
| 552 | /* set words per xres */ | ||
| 553 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF0, (stride >> 1) & 0xff); | ||
| 554 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF1, (stride >> 9)); | ||
| 555 | |||
| 556 | dbg_blit("(copyarea) dx=%d, dy=%d\n", dx, dy); | ||
| 557 | dbg_blit("(copyarea) sx=%d, sy=%d\n", sx, sy); | ||
| 558 | dbg_blit("(copyarea) width=%d, height=%d\n", width - 1, height - 1); | ||
| 559 | dbg_blit("(copyarea) stride=%d\n", stride); | ||
| 560 | dbg_blit("(copyarea) bpp=%d=0x0%d, mem_offset1=%d, mem_offset2=%d\n", bpp, (bpp >> 1), | ||
| 561 | (stride >> 1) & 0xff, stride >> 9); | ||
| 562 | |||
| 563 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CC_EXP, 0x0c); | ||
| 564 | |||
| 565 | /* initialize the engine */ | ||
| 566 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x80); | ||
| 567 | |||
| 568 | /* wait to complete */ | ||
| 569 | bltbit_wait_bitclear(info, 0x80, 8000); | ||
| 570 | |||
| 571 | spin_unlock(&s1d13xxxfb_bitblt_lock); | ||
| 572 | } | ||
| 573 | |||
| 574 | /** | ||
| 575 | * | ||
| 576 | * s1d13xxxfb_bitblt_solidfill - accelerated solidfill function | ||
| 577 | * @info : framebuffer structure | ||
| 578 | * @rect : fb_fillrect structure | ||
| 579 | * | ||
| 580 | * supports (atleast 13506) | ||
| 581 | * | ||
| 582 | **/ | ||
| 583 | static void | ||
| 584 | s1d13xxxfb_bitblt_solidfill(struct fb_info *info, const struct fb_fillrect *rect) | ||
| 585 | { | ||
| 586 | u32 screen_stride, dest; | ||
| 587 | u32 fg; | ||
| 588 | u16 bpp = (info->var.bits_per_pixel >> 3); | ||
| 589 | |||
| 590 | /* grab spinlock */ | ||
| 591 | spin_lock(&s1d13xxxfb_bitblt_lock); | ||
| 592 | |||
| 593 | /* bytes per x width */ | ||
| 594 | screen_stride = (bpp * info->var.xres); | ||
| 595 | |||
| 596 | /* bytes to starting point */ | ||
| 597 | dest = ((rect->dy * screen_stride) + (bpp * rect->dx)); | ||
| 598 | |||
| 599 | dbg_blit("(solidfill) dx=%d, dy=%d, stride=%d, dest=%d\n" | ||
| 600 | "(solidfill) : rect_width=%d, rect_height=%d\n", | ||
| 601 | rect->dx, rect->dy, screen_stride, dest, | ||
| 602 | rect->width - 1, rect->height - 1); | ||
| 603 | |||
| 604 | dbg_blit("(solidfill) : xres=%d, yres=%d, bpp=%d\n", | ||
| 605 | info->var.xres, info->var.yres, | ||
| 606 | info->var.bits_per_pixel); | ||
| 607 | dbg_blit("(solidfill) : rop=%d\n", rect->rop); | ||
| 608 | |||
| 609 | /* We split the destination into the three registers */ | ||
| 610 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dest & 0x00ff)); | ||
| 611 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, ((dest >> 8) & 0x00ff)); | ||
| 612 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, ((dest >> 16) & 0x00ff)); | ||
| 613 | |||
| 614 | /* give information regarding rectangel width */ | ||
| 615 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH0, ((rect->width) & 0x00ff) - 1); | ||
| 616 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH1, (rect->width >> 8)); | ||
| 617 | |||
| 618 | /* give information regarding rectangel height */ | ||
| 619 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT0, ((rect->height) & 0x00ff) - 1); | ||
| 620 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT1, (rect->height >> 8)); | ||
| 621 | |||
| 622 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
| 623 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | ||
| 624 | fg = ((u32 *)info->pseudo_palette)[rect->color]; | ||
| 625 | dbg_blit("(solidfill) truecolor/directcolor\n"); | ||
| 626 | dbg_blit("(solidfill) pseudo_palette[%d] = %d\n", rect->color, fg); | ||
| 627 | } else { | ||
| 628 | fg = rect->color; | ||
| 629 | dbg_blit("(solidfill) color = %d\n", rect->color); | ||
| 630 | } | ||
| 631 | |||
| 632 | /* set foreground color */ | ||
| 633 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_FGC0, (fg & 0xff)); | ||
| 634 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_FGC1, (fg >> 8) & 0xff); | ||
| 635 | |||
| 636 | /* set rectangual region of memory (rectangle and not linear) */ | ||
| 637 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x0); | ||
| 638 | |||
| 639 | /* set operation mode SOLID_FILL */ | ||
| 640 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, BBLT_SOLID_FILL); | ||
| 641 | |||
| 642 | /* set bits per pixel (1 = 16bpp, 0 = 8bpp) */ | ||
| 643 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL1, (info->var.bits_per_pixel >> 4)); | ||
| 644 | |||
| 645 | /* set the memory offset for the bblt in word sizes */ | ||
| 646 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF0, (screen_stride >> 1) & 0x00ff); | ||
| 647 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF1, (screen_stride >> 9)); | ||
| 648 | |||
| 649 | /* and away we go.... */ | ||
| 650 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x80); | ||
| 651 | |||
| 652 | /* wait until its done */ | ||
| 653 | bltbit_wait_bitclear(info, 0x80, 8000); | ||
| 654 | |||
| 655 | /* let others play */ | ||
| 656 | spin_unlock(&s1d13xxxfb_bitblt_lock); | ||
| 657 | } | ||
| 658 | |||
| 659 | /* framebuffer information structures */ | ||
| 395 | static struct fb_ops s1d13xxxfb_fbops = { | 660 | static struct fb_ops s1d13xxxfb_fbops = { |
| 396 | .owner = THIS_MODULE, | 661 | .owner = THIS_MODULE, |
| 397 | .fb_set_par = s1d13xxxfb_set_par, | 662 | .fb_set_par = s1d13xxxfb_set_par, |
| @@ -400,7 +665,7 @@ static struct fb_ops s1d13xxxfb_fbops = { | |||
| 400 | 665 | ||
| 401 | .fb_pan_display = s1d13xxxfb_pan_display, | 666 | .fb_pan_display = s1d13xxxfb_pan_display, |
| 402 | 667 | ||
| 403 | /* to be replaced by any acceleration we can */ | 668 | /* gets replaced at chip detection time */ |
| 404 | .fb_fillrect = cfb_fillrect, | 669 | .fb_fillrect = cfb_fillrect, |
| 405 | .fb_copyarea = cfb_copyarea, | 670 | .fb_copyarea = cfb_copyarea, |
| 406 | .fb_imageblit = cfb_imageblit, | 671 | .fb_imageblit = cfb_imageblit, |
| @@ -412,9 +677,9 @@ static int s1d13xxxfb_width_tab[2][4] __devinitdata = { | |||
| 412 | }; | 677 | }; |
| 413 | 678 | ||
| 414 | /** | 679 | /** |
| 415 | * s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to | 680 | * s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to |
| 416 | * hardware setup. | 681 | * hardware setup. |
| 417 | * @info: frame buffer structure | 682 | * @info: frame buffer structure |
| 418 | * | 683 | * |
| 419 | * We setup the framebuffer structures according to the current | 684 | * We setup the framebuffer structures according to the current |
| 420 | * hardware setup. On some machines, the BIOS will have filled | 685 | * hardware setup. On some machines, the BIOS will have filled |
| @@ -569,7 +834,6 @@ s1d13xxxfb_probe(struct platform_device *pdev) | |||
| 569 | if (pdata && pdata->platform_init_video) | 834 | if (pdata && pdata->platform_init_video) |
| 570 | pdata->platform_init_video(); | 835 | pdata->platform_init_video(); |
| 571 | 836 | ||
| 572 | |||
| 573 | if (pdev->num_resources != 2) { | 837 | if (pdev->num_resources != 2) { |
| 574 | dev_err(&pdev->dev, "invalid num_resources: %i\n", | 838 | dev_err(&pdev->dev, "invalid num_resources: %i\n", |
| 575 | pdev->num_resources); | 839 | pdev->num_resources); |
| @@ -655,16 +919,27 @@ s1d13xxxfb_probe(struct platform_device *pdev) | |||
| 655 | 919 | ||
| 656 | info->fix = s1d13xxxfb_fix; | 920 | info->fix = s1d13xxxfb_fix; |
| 657 | info->fix.mmio_start = pdev->resource[1].start; | 921 | info->fix.mmio_start = pdev->resource[1].start; |
| 658 | info->fix.mmio_len = pdev->resource[1].end - pdev->resource[1].start +1; | 922 | info->fix.mmio_len = pdev->resource[1].end - pdev->resource[1].start + 1; |
| 659 | info->fix.smem_start = pdev->resource[0].start; | 923 | info->fix.smem_start = pdev->resource[0].start; |
| 660 | info->fix.smem_len = pdev->resource[0].end - pdev->resource[0].start +1; | 924 | info->fix.smem_len = pdev->resource[0].end - pdev->resource[0].start + 1; |
| 661 | 925 | ||
| 662 | printk(KERN_INFO PFX "regs mapped at 0x%p, fb %d KiB mapped at 0x%p\n", | 926 | printk(KERN_INFO PFX "regs mapped at 0x%p, fb %d KiB mapped at 0x%p\n", |
| 663 | default_par->regs, info->fix.smem_len / 1024, info->screen_base); | 927 | default_par->regs, info->fix.smem_len / 1024, info->screen_base); |
| 664 | 928 | ||
| 665 | info->par = default_par; | 929 | info->par = default_par; |
| 666 | info->fbops = &s1d13xxxfb_fbops; | ||
| 667 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 930 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; |
| 931 | info->fbops = &s1d13xxxfb_fbops; | ||
| 932 | |||
| 933 | switch(prod_id) { | ||
| 934 | case S1D13506_PROD_ID: /* activate acceleration */ | ||
| 935 | s1d13xxxfb_fbops.fb_fillrect = s1d13xxxfb_bitblt_solidfill; | ||
| 936 | s1d13xxxfb_fbops.fb_copyarea = s1d13xxxfb_bitblt_copyarea; | ||
| 937 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | | ||
| 938 | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; | ||
| 939 | break; | ||
| 940 | default: | ||
| 941 | break; | ||
| 942 | } | ||
| 668 | 943 | ||
| 669 | /* perform "manual" chip initialization, if needed */ | 944 | /* perform "manual" chip initialization, if needed */ |
| 670 | if (pdata && pdata->initregs) | 945 | if (pdata && pdata->initregs) |
