diff options
Diffstat (limited to 'drivers/video/platinumfb.c')
| -rw-r--r-- | drivers/video/platinumfb.c | 98 |
1 files changed, 54 insertions, 44 deletions
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index ca4082ae5a18..335e37465559 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c | |||
| @@ -69,6 +69,8 @@ struct fb_info_platinum { | |||
| 69 | unsigned long total_vram; | 69 | unsigned long total_vram; |
| 70 | int clktype; | 70 | int clktype; |
| 71 | int dactype; | 71 | int dactype; |
| 72 | |||
| 73 | struct resource rsrc_fb, rsrc_reg; | ||
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | /* | 76 | /* |
| @@ -97,9 +99,6 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var, | |||
| 97 | * Interface used by the world | 99 | * Interface used by the world |
| 98 | */ | 100 | */ |
| 99 | 101 | ||
| 100 | int platinumfb_init(void); | ||
| 101 | int platinumfb_setup(char*); | ||
| 102 | |||
| 103 | static struct fb_ops platinumfb_ops = { | 102 | static struct fb_ops platinumfb_ops = { |
| 104 | .owner = THIS_MODULE, | 103 | .owner = THIS_MODULE, |
| 105 | .fb_check_var = platinumfb_check_var, | 104 | .fb_check_var = platinumfb_check_var, |
| @@ -138,13 +137,15 @@ static int platinumfb_set_par (struct fb_info *info) | |||
| 138 | 137 | ||
| 139 | init = platinum_reg_init[pinfo->vmode-1]; | 138 | init = platinum_reg_init[pinfo->vmode-1]; |
| 140 | 139 | ||
| 141 | if (pinfo->vmode == 13 && pinfo->cmode > 0) | 140 | if ((pinfo->vmode == VMODE_832_624_75) && (pinfo->cmode > CMODE_8)) |
| 142 | offset = 0x10; | 141 | offset = 0x10; |
| 142 | |||
| 143 | info->screen_base = pinfo->frame_buffer + init->fb_offset + offset; | 143 | info->screen_base = pinfo->frame_buffer + init->fb_offset + offset; |
| 144 | info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset; | 144 | info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset; |
| 145 | info->fix.visual = (pinfo->cmode == CMODE_8) ? | 145 | info->fix.visual = (pinfo->cmode == CMODE_8) ? |
| 146 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; | 146 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; |
| 147 | info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<<pinfo->cmode) + offset; | 147 | info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<<pinfo->cmode) |
| 148 | + offset; | ||
| 148 | printk("line_length: %x\n", info->fix.line_length); | 149 | printk("line_length: %x\n", info->fix.line_length); |
| 149 | return 0; | 150 | return 0; |
| 150 | } | 151 | } |
| @@ -221,7 +222,9 @@ static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
| 221 | static inline int platinum_vram_reqd(int video_mode, int color_mode) | 222 | static inline int platinum_vram_reqd(int video_mode, int color_mode) |
| 222 | { | 223 | { |
| 223 | return vmode_attrs[video_mode-1].vres * | 224 | return vmode_attrs[video_mode-1].vres * |
| 224 | (vmode_attrs[video_mode-1].hres * (1<<color_mode) + 0x20) +0x1000; | 225 | (vmode_attrs[video_mode-1].hres * (1<<color_mode) + |
| 226 | ((video_mode == VMODE_832_624_75) && | ||
| 227 | (color_mode > CMODE_8)) ? 0x10 : 0x20) + 0x1000; | ||
| 225 | } | 228 | } |
| 226 | 229 | ||
| 227 | #define STORE_D2(a, d) { \ | 230 | #define STORE_D2(a, d) { \ |
| @@ -481,7 +484,7 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var, | |||
| 481 | /* | 484 | /* |
| 482 | * Parse user speficied options (`video=platinumfb:') | 485 | * Parse user speficied options (`video=platinumfb:') |
| 483 | */ | 486 | */ |
| 484 | int __init platinumfb_setup(char *options) | 487 | static int __init platinumfb_setup(char *options) |
| 485 | { | 488 | { |
| 486 | char *this_opt; | 489 | char *this_opt; |
| 487 | 490 | ||
| @@ -522,19 +525,15 @@ int __init platinumfb_setup(char *options) | |||
| 522 | #define invalidate_cache(addr) | 525 | #define invalidate_cache(addr) |
| 523 | #endif | 526 | #endif |
| 524 | 527 | ||
| 525 | static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match) | 528 | static int __devinit platinumfb_probe(struct of_device* odev, |
| 529 | const struct of_device_id *match) | ||
| 526 | { | 530 | { |
| 527 | struct device_node *dp = odev->node; | 531 | struct device_node *dp = odev->node; |
| 528 | struct fb_info *info; | 532 | struct fb_info *info; |
| 529 | struct fb_info_platinum *pinfo; | 533 | struct fb_info_platinum *pinfo; |
| 530 | unsigned long addr, size; | ||
| 531 | volatile __u8 *fbuffer; | 534 | volatile __u8 *fbuffer; |
| 532 | int i, bank0, bank1, bank2, bank3, rc; | 535 | int bank0, bank1, bank2, bank3, rc; |
| 533 | 536 | ||
| 534 | if (dp->n_addrs != 2) { | ||
| 535 | printk(KERN_ERR "expecting 2 address for platinum (got %d)", dp->n_addrs); | ||
| 536 | return -ENXIO; | ||
| 537 | } | ||
| 538 | printk(KERN_INFO "platinumfb: Found Apple Platinum video hardware\n"); | 537 | printk(KERN_INFO "platinumfb: Found Apple Platinum video hardware\n"); |
| 539 | 538 | ||
| 540 | info = framebuffer_alloc(sizeof(*pinfo), &odev->dev); | 539 | info = framebuffer_alloc(sizeof(*pinfo), &odev->dev); |
| @@ -542,26 +541,39 @@ static int __devinit platinumfb_probe(struct of_device* odev, const struct of_de | |||
| 542 | return -ENOMEM; | 541 | return -ENOMEM; |
| 543 | pinfo = info->par; | 542 | pinfo = info->par; |
| 544 | 543 | ||
| 545 | /* Map in frame buffer and registers */ | 544 | if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) || |
| 546 | for (i = 0; i < dp->n_addrs; ++i) { | 545 | of_address_to_resource(dp, 1, &pinfo->rsrc_fb)) { |
| 547 | addr = dp->addrs[i].address; | 546 | printk(KERN_ERR "platinumfb: Can't get resources\n"); |
| 548 | size = dp->addrs[i].size; | 547 | framebuffer_release(info); |
| 549 | /* Let's assume we can request either all or nothing */ | 548 | return -ENXIO; |
| 550 | if (!request_mem_region(addr, size, "platinumfb")) { | ||
| 551 | framebuffer_release(info); | ||
| 552 | return -ENXIO; | ||
| 553 | } | ||
| 554 | if (size >= 0x400000) { | ||
| 555 | /* frame buffer - map only 4MB */ | ||
| 556 | pinfo->frame_buffer_phys = addr; | ||
| 557 | pinfo->frame_buffer = __ioremap(addr, 0x400000, _PAGE_WRITETHRU); | ||
| 558 | pinfo->base_frame_buffer = pinfo->frame_buffer; | ||
| 559 | } else { | ||
| 560 | /* registers */ | ||
| 561 | pinfo->platinum_regs_phys = addr; | ||
| 562 | pinfo->platinum_regs = ioremap(addr, size); | ||
| 563 | } | ||
| 564 | } | 549 | } |
| 550 | if (!request_mem_region(pinfo->rsrc_reg.start, | ||
| 551 | pinfo->rsrc_reg.start - | ||
| 552 | pinfo->rsrc_reg.end + 1, | ||
| 553 | "platinumfb registers")) { | ||
| 554 | framebuffer_release(info); | ||
| 555 | return -ENXIO; | ||
| 556 | } | ||
| 557 | if (!request_mem_region(pinfo->rsrc_fb.start, | ||
| 558 | pinfo->rsrc_fb.start | ||
| 559 | - pinfo->rsrc_fb.end + 1, | ||
| 560 | "platinumfb framebuffer")) { | ||
| 561 | release_mem_region(pinfo->rsrc_reg.start, | ||
| 562 | pinfo->rsrc_reg.end - | ||
| 563 | pinfo->rsrc_reg.start + 1); | ||
| 564 | framebuffer_release(info); | ||
| 565 | return -ENXIO; | ||
| 566 | } | ||
| 567 | |||
| 568 | /* frame buffer - map only 4MB */ | ||
| 569 | pinfo->frame_buffer_phys = pinfo->rsrc_fb.start; | ||
| 570 | pinfo->frame_buffer = __ioremap(pinfo->rsrc_fb.start, 0x400000, | ||
| 571 | _PAGE_WRITETHRU); | ||
| 572 | pinfo->base_frame_buffer = pinfo->frame_buffer; | ||
| 573 | |||
| 574 | /* registers */ | ||
| 575 | pinfo->platinum_regs_phys = pinfo->rsrc_reg.start; | ||
| 576 | pinfo->platinum_regs = ioremap(pinfo->rsrc_reg.start, 0x1000); | ||
| 565 | 577 | ||
| 566 | pinfo->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */ | 578 | pinfo->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */ |
| 567 | request_mem_region(pinfo->cmap_regs_phys, 0x1000, "platinumfb cmap"); | 579 | request_mem_region(pinfo->cmap_regs_phys, 0x1000, "platinumfb cmap"); |
| @@ -624,18 +636,16 @@ static int __devexit platinumfb_remove(struct of_device* odev) | |||
| 624 | { | 636 | { |
| 625 | struct fb_info *info = dev_get_drvdata(&odev->dev); | 637 | struct fb_info *info = dev_get_drvdata(&odev->dev); |
| 626 | struct fb_info_platinum *pinfo = info->par; | 638 | struct fb_info_platinum *pinfo = info->par; |
| 627 | struct device_node *dp = odev->node; | ||
| 628 | unsigned long addr, size; | ||
| 629 | int i; | ||
| 630 | 639 | ||
| 631 | unregister_framebuffer (info); | 640 | unregister_framebuffer (info); |
| 632 | 641 | ||
| 633 | /* Unmap frame buffer and registers */ | 642 | /* Unmap frame buffer and registers */ |
| 634 | for (i = 0; i < dp->n_addrs; ++i) { | 643 | release_mem_region(pinfo->rsrc_fb.start, |
| 635 | addr = dp->addrs[i].address; | 644 | pinfo->rsrc_fb.end - |
| 636 | size = dp->addrs[i].size; | 645 | pinfo->rsrc_fb.start + 1); |
| 637 | release_mem_region(addr, size); | 646 | release_mem_region(pinfo->rsrc_reg.start, |
| 638 | } | 647 | pinfo->rsrc_reg.end - |
| 648 | pinfo->rsrc_reg.start + 1); | ||
| 639 | iounmap(pinfo->frame_buffer); | 649 | iounmap(pinfo->frame_buffer); |
| 640 | iounmap(pinfo->platinum_regs); | 650 | iounmap(pinfo->platinum_regs); |
| 641 | release_mem_region(pinfo->cmap_regs_phys, 0x1000); | 651 | release_mem_region(pinfo->cmap_regs_phys, 0x1000); |
| @@ -662,7 +672,7 @@ static struct of_platform_driver platinum_driver = | |||
| 662 | .remove = platinumfb_remove, | 672 | .remove = platinumfb_remove, |
| 663 | }; | 673 | }; |
| 664 | 674 | ||
| 665 | int __init platinumfb_init(void) | 675 | static int __init platinumfb_init(void) |
| 666 | { | 676 | { |
| 667 | #ifndef MODULE | 677 | #ifndef MODULE |
| 668 | char *option = NULL; | 678 | char *option = NULL; |
| @@ -676,7 +686,7 @@ int __init platinumfb_init(void) | |||
| 676 | return 0; | 686 | return 0; |
| 677 | } | 687 | } |
| 678 | 688 | ||
| 679 | void __exit platinumfb_exit(void) | 689 | static void __exit platinumfb_exit(void) |
| 680 | { | 690 | { |
| 681 | of_unregister_driver(&platinum_driver); | 691 | of_unregister_driver(&platinum_driver); |
| 682 | } | 692 | } |
