[SPARC]: Convert all FB SBUS drivers to of_driver framework.

Signed-off-by: David S. Miller <davem@davemloft.net>

authored by David S. Miller and committed by David S. Miller 50312ce9 3ca9fab4

+1208 -1178
+98 -119
drivers/video/bw2.c
··· 1 /* bw2.c: BWTWO frame buffer driver 2 * 3 - * Copyright (C) 2003 David S. Miller (davem@redhat.com) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) ··· 19 #include <linux/mm.h> 20 21 #include <asm/io.h> 22 - #include <asm/sbus.h> 23 #include <asm/oplib.h> 24 #include <asm/fbio.h> 25 - 26 - #ifdef CONFIG_SPARC32 27 - #include <asm/sun4paddr.h> 28 - #endif 29 30 #include "sbuslib.h" 31 ··· 56 #define BWTWO_REGISTER_OFFSET 0x400000 57 58 struct bt_regs { 59 - volatile u32 addr; 60 - volatile u32 color_map; 61 - volatile u32 control; 62 - volatile u32 cursor; 63 }; 64 65 struct bw2_regs { 66 struct bt_regs cmap; 67 - volatile u8 control; 68 - volatile u8 status; 69 - volatile u8 cursor_start; 70 - volatile u8 cursor_end; 71 - volatile u8 h_blank_start; 72 - volatile u8 h_blank_end; 73 - volatile u8 h_sync_start; 74 - volatile u8 h_sync_end; 75 - volatile u8 comp_sync_end; 76 - volatile u8 v_blank_start_high; 77 - volatile u8 v_blank_start_low; 78 - volatile u8 v_blank_end; 79 - volatile u8 v_sync_start; 80 - volatile u8 v_sync_end; 81 - volatile u8 xfer_holdoff_start; 82 - volatile u8 xfer_holdoff_end; 83 }; 84 85 /* Status Register Constants */ ··· 114 #define BW2_FLAG_BLANKED 0x00000001 115 116 unsigned long physbase; 117 unsigned long fbsize; 118 - 119 - struct sbus_dev *sdev; 120 }; 121 122 /** ··· 170 171 return sbusfb_mmap_helper(bw2_mmap_map, 172 par->physbase, par->fbsize, 173 - (par->sdev ? 174 - par->sdev->reg_addrs[0].which_io : 175 - 0), 176 vma); 177 } 178 ··· 282 struct all_info { 283 struct fb_info info; 284 struct bw2_par par; 285 - struct list_head list; 286 }; 287 - static LIST_HEAD(bw2_list); 288 289 - static void bw2_init_one(struct sbus_dev *sdev) 290 { 291 struct all_info *all; 292 - struct resource *resp; 293 - #ifdef CONFIG_SUN4 294 - struct resource res; 295 - #endif 296 - int linebytes; 297 298 - all = kmalloc(sizeof(*all), GFP_KERNEL); 299 - if (!all) { 300 - printk(KERN_ERR "bw2: Cannot allocate memory.\n"); 301 - return; 302 - } 303 - memset(all, 0, sizeof(*all)); 304 - 305 - INIT_LIST_HEAD(&all->list); 306 307 spin_lock_init(&all->par.lock); 308 - all->par.sdev = sdev; 309 310 - #ifdef CONFIG_SUN4 311 - if (!sdev) { 312 - all->par.physbase = sun4_bwtwo_physaddr; 313 - res.start = sun4_bwtwo_physaddr; 314 - res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1; 315 - res.flags = IORESOURCE_IO; 316 - resp = &res; 317 - all->info.var.xres = all->info.var.xres_virtual = 1152; 318 - all->info.var.yres = all->info.var.yres_virtual = 900; 319 - all->info.var.bits_per_pixel = 1; 320 - linebytes = 1152 / 8; 321 - } else 322 - #else 323 - { 324 - BUG_ON(!sdev); 325 - all->par.physbase = sdev->reg_addrs[0].phys_addr; 326 - resp = &sdev->resource[0]; 327 - sbusfb_fill_var(&all->info.var, (sdev ? sdev->prom_node : 0), 1); 328 - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 329 - all->info.var.xres); 330 - } 331 - #endif 332 all->info.var.red.length = all->info.var.green.length = 333 all->info.var.blue.length = all->info.var.bits_per_pixel; 334 all->info.var.red.offset = all->info.var.green.offset = 335 all->info.var.blue.offset = 0; 336 337 - all->par.regs = sbus_ioremap(resp, BWTWO_REGISTER_OFFSET, 338 - sizeof(struct bw2_regs), "bw2 regs"); 339 340 - if (sdev && !prom_getbool(sdev->prom_node, "width")) 341 bw2_do_default_mode(&all->par, &all->info, &linebytes); 342 343 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 344 345 all->info.flags = FBINFO_DEFAULT; 346 all->info.fbops = &bw2_ops; 347 - #if defined(CONFIG_SPARC32) 348 - if (sdev) 349 - all->info.screen_base = (char __iomem *) 350 - prom_getintdefault(sdev->prom_node, "address", 0); 351 - #endif 352 - if (!all->info.screen_base) 353 - all->info.screen_base = 354 - sbus_ioremap(resp, 0, all->par.fbsize, "bw2 ram"); 355 all->info.par = &all->par; 356 357 bw2_blank(0, &all->info); 358 359 bw2_init_fix(&all->info, linebytes); 360 361 - if (register_framebuffer(&all->info) < 0) { 362 - printk(KERN_ERR "bw2: Could not register framebuffer.\n"); 363 kfree(all); 364 - return; 365 } 366 367 - list_add(&all->list, &bw2_list); 368 369 - printk("bw2: bwtwo at %lx:%lx\n", 370 - (long) (sdev ? sdev->reg_addrs[0].which_io : 0), 371 - (long) all->par.physbase); 372 } 373 374 - int __init bw2_init(void) 375 { 376 - struct sbus_bus *sbus; 377 - struct sbus_dev *sdev; 378 379 if (fb_get_options("bw2fb", NULL)) 380 return -ENODEV; 381 382 - #ifdef CONFIG_SUN4 383 - bw2_init_one(NULL); 384 - #endif 385 - for_all_sbusdev(sdev, sbus) { 386 - if (!strcmp(sdev->prom_name, "bwtwo")) 387 - bw2_init_one(sdev); 388 - } 389 - 390 - return 0; 391 } 392 393 - void __exit bw2_exit(void) 394 { 395 - struct list_head *pos, *tmp; 396 - 397 - list_for_each_safe(pos, tmp, &bw2_list) { 398 - struct all_info *all = list_entry(pos, typeof(*all), list); 399 - 400 - unregister_framebuffer(&all->info); 401 - kfree(all); 402 - } 403 } 404 405 - int __init 406 - bw2_setup(char *arg) 407 - { 408 - /* No cmdline options yet... */ 409 - return 0; 410 - } 411 412 module_init(bw2_init); 413 - 414 - #ifdef MODULE 415 module_exit(bw2_exit); 416 - #endif 417 418 MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets"); 419 - MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 420 MODULE_LICENSE("GPL");
··· 1 /* bw2.c: BWTWO frame buffer driver 2 * 3 + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) ··· 19 #include <linux/mm.h> 20 21 #include <asm/io.h> 22 #include <asm/oplib.h> 23 + #include <asm/prom.h> 24 + #include <asm/of_device.h> 25 #include <asm/fbio.h> 26 27 #include "sbuslib.h" 28 ··· 59 #define BWTWO_REGISTER_OFFSET 0x400000 60 61 struct bt_regs { 62 + u32 addr; 63 + u32 color_map; 64 + u32 control; 65 + u32 cursor; 66 }; 67 68 struct bw2_regs { 69 struct bt_regs cmap; 70 + u8 control; 71 + u8 status; 72 + u8 cursor_start; 73 + u8 cursor_end; 74 + u8 h_blank_start; 75 + u8 h_blank_end; 76 + u8 h_sync_start; 77 + u8 h_sync_end; 78 + u8 comp_sync_end; 79 + u8 v_blank_start_high; 80 + u8 v_blank_start_low; 81 + u8 v_blank_end; 82 + u8 v_sync_start; 83 + u8 v_sync_end; 84 + u8 xfer_holdoff_start; 85 + u8 xfer_holdoff_end; 86 }; 87 88 /* Status Register Constants */ ··· 117 #define BW2_FLAG_BLANKED 0x00000001 118 119 unsigned long physbase; 120 + unsigned long which_io; 121 unsigned long fbsize; 122 }; 123 124 /** ··· 174 175 return sbusfb_mmap_helper(bw2_mmap_map, 176 par->physbase, par->fbsize, 177 + par->which_io, 178 vma); 179 } 180 ··· 288 struct all_info { 289 struct fb_info info; 290 struct bw2_par par; 291 }; 292 293 + static int __devinit bw2_init_one(struct of_device *op) 294 { 295 + struct device_node *dp = op->node; 296 struct all_info *all; 297 + int linebytes, err; 298 299 + all = kzalloc(sizeof(*all), GFP_KERNEL); 300 + if (!all) 301 + return -ENOMEM; 302 303 spin_lock_init(&all->par.lock); 304 305 + all->par.physbase = op->resource[0].start; 306 + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; 307 + 308 + sbusfb_fill_var(&all->info.var, dp->node, 1); 309 + linebytes = of_getintprop_default(dp, "linebytes", 310 + all->info.var.xres); 311 + 312 all->info.var.red.length = all->info.var.green.length = 313 all->info.var.blue.length = all->info.var.bits_per_pixel; 314 all->info.var.red.offset = all->info.var.green.offset = 315 all->info.var.blue.offset = 0; 316 317 + all->par.regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET, 318 + sizeof(struct bw2_regs), "bw2 regs"); 319 320 + if (!of_find_property(dp, "width", NULL)) 321 bw2_do_default_mode(&all->par, &all->info, &linebytes); 322 323 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 324 325 all->info.flags = FBINFO_DEFAULT; 326 all->info.fbops = &bw2_ops; 327 + 328 + all->info.screen_base = 329 + sbus_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram"); 330 all->info.par = &all->par; 331 332 bw2_blank(0, &all->info); 333 334 bw2_init_fix(&all->info, linebytes); 335 336 + err= register_framebuffer(&all->info); 337 + if (err < 0) { 338 + of_iounmap(all->par.regs, sizeof(struct bw2_regs)); 339 + of_iounmap(all->info.screen_base, all->par.fbsize); 340 kfree(all); 341 + return err; 342 } 343 344 + dev_set_drvdata(&op->dev, all); 345 346 + printk("%s: bwtwo at %lx:%lx\n", 347 + dp->full_name, 348 + all->par.which_io, all->par.physbase); 349 + 350 + return 0; 351 } 352 353 + static int __devinit bw2_probe(struct of_device *dev, const struct of_device_id *match) 354 { 355 + struct of_device *op = to_of_device(&dev->dev); 356 357 + return bw2_init_one(op); 358 + } 359 + 360 + static int __devexit bw2_remove(struct of_device *dev) 361 + { 362 + struct all_info *all = dev_get_drvdata(&dev->dev); 363 + 364 + unregister_framebuffer(&all->info); 365 + 366 + of_iounmap(all->par.regs, sizeof(struct bw2_regs)); 367 + of_iounmap(all->info.screen_base, all->par.fbsize); 368 + 369 + kfree(all); 370 + 371 + dev_set_drvdata(&dev->dev, NULL); 372 + 373 + return 0; 374 + } 375 + 376 + static struct of_device_id bw2_match[] = { 377 + { 378 + .name = "bwtwo", 379 + }, 380 + {}, 381 + }; 382 + MODULE_DEVICE_TABLE(of, bw2_match); 383 + 384 + static struct of_platform_driver bw2_driver = { 385 + .name = "bw2", 386 + .match_table = bw2_match, 387 + .probe = bw2_probe, 388 + .remove = __devexit_p(bw2_remove), 389 + }; 390 + 391 + static int __init bw2_init(void) 392 + { 393 if (fb_get_options("bw2fb", NULL)) 394 return -ENODEV; 395 396 + return of_register_driver(&bw2_driver, &of_bus_type); 397 } 398 399 + static void __exit bw2_exit(void) 400 { 401 + return of_unregister_driver(&bw2_driver); 402 } 403 404 405 module_init(bw2_init); 406 module_exit(bw2_exit); 407 408 MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets"); 409 + MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 410 + MODULE_VERSION("2.0"); 411 MODULE_LICENSE("GPL");
+156 -176
drivers/video/cg14.c
··· 1 /* cg14.c: CGFOURTEEN frame buffer driver 2 * 3 - * Copyright (C) 2003 David S. Miller (davem@redhat.com) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * ··· 18 #include <linux/mm.h> 19 20 #include <asm/io.h> 21 - #include <asm/sbus.h> 22 - #include <asm/oplib.h> 23 #include <asm/fbio.h> 24 25 #include "sbuslib.h" ··· 99 #define CG14_MCR_PIXMODE_32 3 100 101 struct cg14_regs{ 102 - volatile u8 mcr; /* Master Control Reg */ 103 - volatile u8 ppr; /* Packed Pixel Reg */ 104 - volatile u8 tms[2]; /* Test Mode Status Regs */ 105 - volatile u8 msr; /* Master Status Reg */ 106 - volatile u8 fsr; /* Fault Status Reg */ 107 - volatile u8 rev; /* Revision & Impl */ 108 - volatile u8 ccr; /* Clock Control Reg */ 109 - volatile u32 tmr; /* Test Mode Read Back */ 110 - volatile u8 mod; /* Monitor Operation Data Reg */ 111 - volatile u8 acr; /* Aux Control */ 112 u8 xxx0[6]; 113 - volatile u16 hct; /* Hor Counter */ 114 - volatile u16 vct; /* Vert Counter */ 115 - volatile u16 hbs; /* Hor Blank Start */ 116 - volatile u16 hbc; /* Hor Blank Clear */ 117 - volatile u16 hss; /* Hor Sync Start */ 118 - volatile u16 hsc; /* Hor Sync Clear */ 119 - volatile u16 csc; /* Composite Sync Clear */ 120 - volatile u16 vbs; /* Vert Blank Start */ 121 - volatile u16 vbc; /* Vert Blank Clear */ 122 - volatile u16 vss; /* Vert Sync Start */ 123 - volatile u16 vsc; /* Vert Sync Clear */ 124 - volatile u16 xcs; 125 - volatile u16 xcc; 126 - volatile u16 fsa; /* Fault Status Address */ 127 - volatile u16 adr; /* Address Registers */ 128 u8 xxx1[0xce]; 129 - volatile u8 pcg[0x100]; /* Pixel Clock Generator */ 130 - volatile u32 vbr; /* Frame Base Row */ 131 - volatile u32 vmcr; /* VBC Master Control */ 132 - volatile u32 vcr; /* VBC refresh */ 133 - volatile u32 vca; /* VBC Config */ 134 }; 135 136 #define CG14_CCR_ENABLE 0x04 137 #define CG14_CCR_SELECT 0x02 /* HW/Full screen */ 138 139 struct cg14_cursor { 140 - volatile u32 cpl0[32]; /* Enable plane 0 */ 141 - volatile u32 cpl1[32]; /* Color selection plane */ 142 - volatile u8 ccr; /* Cursor Control Reg */ 143 u8 xxx0[3]; 144 - volatile u16 cursx; /* Cursor x,y position */ 145 - volatile u16 cursy; /* Cursor x,y position */ 146 - volatile u32 color0; 147 - volatile u32 color1; 148 u32 xxx1[0x1bc]; 149 - volatile u32 cpl0i[32]; /* Enable plane 0 autoinc */ 150 - volatile u32 cpl1i[32]; /* Color selection autoinc */ 151 }; 152 153 struct cg14_dac { 154 - volatile u8 addr; /* Address Register */ 155 u8 xxx0[255]; 156 - volatile u8 glut; /* Gamma table */ 157 u8 xxx1[255]; 158 - volatile u8 select; /* Register Select */ 159 u8 xxx2[255]; 160 - volatile u8 mode; /* Mode Register */ 161 }; 162 163 struct cg14_xlut{ 164 - volatile u8 x_xlut [256]; 165 - volatile u8 x_xlutd [256]; 166 u8 xxx0[0x600]; 167 - volatile u8 x_xlut_inc [256]; 168 - volatile u8 x_xlutd_inc [256]; 169 }; 170 171 /* Color look up table (clut) */ ··· 204 205 int mode; 206 int ramsize; 207 - struct sbus_dev *sdev; 208 }; 209 210 static void __cg14_reset(struct cg14_par *par) ··· 354 * Initialisation 355 */ 356 357 - static void cg14_init_fix(struct fb_info *info, int linebytes) 358 { 359 - struct cg14_par *par = (struct cg14_par *)info->par; 360 - const char *name; 361 - 362 - name = "cgfourteen"; 363 - if (par->sdev) 364 - name = par->sdev->prom_name; 365 366 strlcpy(info->fix.id, name, sizeof(info->fix.id)); 367 ··· 450 struct all_info { 451 struct fb_info info; 452 struct cg14_par par; 453 - struct list_head list; 454 }; 455 - static LIST_HEAD(cg14_list); 456 457 - static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node) 458 { 459 struct all_info *all; 460 - unsigned long phys, rphys; 461 - u32 bases[6]; 462 - int is_8mb, linebytes, i; 463 464 - if (!sdev) { 465 - if (prom_getproperty(node, "address", 466 - (char *) &bases[0], sizeof(bases)) <= 0 467 - || !bases[0]) { 468 - printk(KERN_ERR "cg14: Device is not mapped.\n"); 469 - return; 470 - } 471 - if (__get_iospace(bases[0]) != __get_iospace(bases[1])) { 472 - printk(KERN_ERR "cg14: I/O spaces don't match.\n"); 473 - return; 474 - } 475 - } 476 - 477 - all = kmalloc(sizeof(*all), GFP_KERNEL); 478 - if (!all) { 479 - printk(KERN_ERR "cg14: Cannot allocate memory.\n"); 480 - return; 481 - } 482 - memset(all, 0, sizeof(*all)); 483 - 484 - INIT_LIST_HEAD(&all->list); 485 486 spin_lock_init(&all->par.lock); 487 488 - sbusfb_fill_var(&all->info.var, node, 8); 489 all->info.var.red.length = 8; 490 all->info.var.green.length = 8; 491 all->info.var.blue.length = 8; 492 493 - linebytes = prom_getintdefault(node, "linebytes", 494 - all->info.var.xres); 495 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 496 497 - all->par.sdev = sdev; 498 - if (sdev) { 499 - rphys = sdev->reg_addrs[0].phys_addr; 500 - all->par.physbase = phys = sdev->reg_addrs[1].phys_addr; 501 - all->par.iospace = sdev->reg_addrs[0].which_io; 502 - 503 - all->par.regs = sbus_ioremap(&sdev->resource[0], 0, 504 - sizeof(struct cg14_regs), 505 - "cg14 regs"); 506 - all->par.clut = sbus_ioremap(&sdev->resource[0], CG14_CLUT1, 507 - sizeof(struct cg14_clut), 508 - "cg14 clut"); 509 - all->par.cursor = sbus_ioremap(&sdev->resource[0], CG14_CURSORREGS, 510 - sizeof(struct cg14_cursor), 511 - "cg14 cursor"); 512 - all->info.screen_base = sbus_ioremap(&sdev->resource[1], 0, 513 - all->par.fbsize, "cg14 ram"); 514 } else { 515 - rphys = __get_phys(bases[0]); 516 - all->par.physbase = phys = __get_phys(bases[1]); 517 - all->par.iospace = __get_iospace(bases[0]); 518 - all->par.regs = (struct cg14_regs __iomem *)(unsigned long)bases[0]; 519 - all->par.clut = (struct cg14_clut __iomem *)((unsigned long)bases[0] + 520 - CG14_CLUT1); 521 - all->par.cursor = 522 - (struct cg14_cursor __iomem *)((unsigned long)bases[0] + 523 - CG14_CURSORREGS); 524 - 525 - all->info.screen_base = (char __iomem *)(unsigned long)bases[1]; 526 } 527 528 - prom_getproperty(node, "reg", (char *) &bases[0], sizeof(bases)); 529 - is_8mb = (bases[5] == 0x800000); 530 531 - if (sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)) { 532 - extern void __cg14_mmap_sized_wrongly(void); 533 534 - __cg14_mmap_sized_wrongly(); 535 - } 536 537 - memcpy(&all->par.mmap_map, &__cg14_mmap_map, sizeof(all->par.mmap_map)); 538 for (i = 0; i < CG14_MMAP_ENTRIES; i++) { 539 struct sbus_mmap_map *map = &all->par.mmap_map[i]; 540 541 if (!map->size) 542 break; 543 if (map->poff & 0x80000000) 544 - map->poff = (map->poff & 0x7fffffff) + rphys - phys; 545 if (is_8mb && 546 map->size >= 0x100000 && 547 map->size <= 0x400000) ··· 541 __cg14_reset(&all->par); 542 543 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 544 - printk(KERN_ERR "cg14: Could not allocate color map.\n"); 545 kfree(all); 546 - return; 547 } 548 fb_set_cmap(&all->info.cmap, &all->info); 549 550 - cg14_init_fix(&all->info, linebytes); 551 552 - if (register_framebuffer(&all->info) < 0) { 553 - printk(KERN_ERR "cg14: Could not register framebuffer.\n"); 554 fb_dealloc_cmap(&all->info.cmap); 555 kfree(all); 556 - return; 557 } 558 559 - list_add(&all->list, &cg14_list); 560 561 - printk("cg14: cgfourteen at %lx:%lx, %dMB\n", 562 - all->par.iospace, all->par.physbase, all->par.ramsize >> 20); 563 564 } 565 566 int __init cg14_init(void) 567 { 568 - struct sbus_bus *sbus; 569 - struct sbus_dev *sdev; 570 - 571 if (fb_get_options("cg14fb", NULL)) 572 return -ENODEV; 573 574 - #ifdef CONFIG_SPARC32 575 - { 576 - int root, node; 577 - 578 - root = prom_getchild(prom_root_node); 579 - root = prom_searchsiblings(root, "obio"); 580 - if (root) { 581 - node = prom_searchsiblings(prom_getchild(root), 582 - "cgfourteen"); 583 - if (node) 584 - cg14_init_one(NULL, node, root); 585 - } 586 - } 587 - #endif 588 - for_all_sbusdev(sdev, sbus) { 589 - if (!strcmp(sdev->prom_name, "cgfourteen")) 590 - cg14_init_one(sdev, sdev->prom_node, sbus->prom_node); 591 - } 592 - 593 - return 0; 594 } 595 596 void __exit cg14_exit(void) 597 { 598 - struct list_head *pos, *tmp; 599 - 600 - list_for_each_safe(pos, tmp, &cg14_list) { 601 - struct all_info *all = list_entry(pos, typeof(*all), list); 602 - 603 - unregister_framebuffer(&all->info); 604 - fb_dealloc_cmap(&all->info.cmap); 605 - kfree(all); 606 - } 607 - } 608 - 609 - int __init 610 - cg14_setup(char *arg) 611 - { 612 - /* No cmdline options yet... */ 613 - return 0; 614 } 615 616 module_init(cg14_init); 617 - 618 - #ifdef MODULE 619 module_exit(cg14_exit); 620 - #endif 621 622 MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets"); 623 - MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 624 MODULE_LICENSE("GPL");
··· 1 /* cg14.c: CGFOURTEEN frame buffer driver 2 * 3 + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * ··· 18 #include <linux/mm.h> 19 20 #include <asm/io.h> 21 + #include <asm/prom.h> 22 + #include <asm/of_device.h> 23 #include <asm/fbio.h> 24 25 #include "sbuslib.h" ··· 99 #define CG14_MCR_PIXMODE_32 3 100 101 struct cg14_regs{ 102 + u8 mcr; /* Master Control Reg */ 103 + u8 ppr; /* Packed Pixel Reg */ 104 + u8 tms[2]; /* Test Mode Status Regs */ 105 + u8 msr; /* Master Status Reg */ 106 + u8 fsr; /* Fault Status Reg */ 107 + u8 rev; /* Revision & Impl */ 108 + u8 ccr; /* Clock Control Reg */ 109 + u32 tmr; /* Test Mode Read Back */ 110 + u8 mod; /* Monitor Operation Data Reg */ 111 + u8 acr; /* Aux Control */ 112 u8 xxx0[6]; 113 + u16 hct; /* Hor Counter */ 114 + u16 vct; /* Vert Counter */ 115 + u16 hbs; /* Hor Blank Start */ 116 + u16 hbc; /* Hor Blank Clear */ 117 + u16 hss; /* Hor Sync Start */ 118 + u16 hsc; /* Hor Sync Clear */ 119 + u16 csc; /* Composite Sync Clear */ 120 + u16 vbs; /* Vert Blank Start */ 121 + u16 vbc; /* Vert Blank Clear */ 122 + u16 vss; /* Vert Sync Start */ 123 + u16 vsc; /* Vert Sync Clear */ 124 + u16 xcs; 125 + u16 xcc; 126 + u16 fsa; /* Fault Status Address */ 127 + u16 adr; /* Address Registers */ 128 u8 xxx1[0xce]; 129 + u8 pcg[0x100]; /* Pixel Clock Generator */ 130 + u32 vbr; /* Frame Base Row */ 131 + u32 vmcr; /* VBC Master Control */ 132 + u32 vcr; /* VBC refresh */ 133 + u32 vca; /* VBC Config */ 134 }; 135 136 #define CG14_CCR_ENABLE 0x04 137 #define CG14_CCR_SELECT 0x02 /* HW/Full screen */ 138 139 struct cg14_cursor { 140 + u32 cpl0[32]; /* Enable plane 0 */ 141 + u32 cpl1[32]; /* Color selection plane */ 142 + u8 ccr; /* Cursor Control Reg */ 143 u8 xxx0[3]; 144 + u16 cursx; /* Cursor x,y position */ 145 + u16 cursy; /* Cursor x,y position */ 146 + u32 color0; 147 + u32 color1; 148 u32 xxx1[0x1bc]; 149 + u32 cpl0i[32]; /* Enable plane 0 autoinc */ 150 + u32 cpl1i[32]; /* Color selection autoinc */ 151 }; 152 153 struct cg14_dac { 154 + u8 addr; /* Address Register */ 155 u8 xxx0[255]; 156 + u8 glut; /* Gamma table */ 157 u8 xxx1[255]; 158 + u8 select; /* Register Select */ 159 u8 xxx2[255]; 160 + u8 mode; /* Mode Register */ 161 }; 162 163 struct cg14_xlut{ 164 + u8 x_xlut [256]; 165 + u8 x_xlutd [256]; 166 u8 xxx0[0x600]; 167 + u8 x_xlut_inc [256]; 168 + u8 x_xlutd_inc [256]; 169 }; 170 171 /* Color look up table (clut) */ ··· 204 205 int mode; 206 int ramsize; 207 }; 208 209 static void __cg14_reset(struct cg14_par *par) ··· 355 * Initialisation 356 */ 357 358 + static void cg14_init_fix(struct fb_info *info, int linebytes, struct device_node *dp) 359 { 360 + const char *name = dp->name; 361 362 strlcpy(info->fix.id, name, sizeof(info->fix.id)); 363 ··· 456 struct all_info { 457 struct fb_info info; 458 struct cg14_par par; 459 }; 460 461 + static void cg14_unmap_regs(struct all_info *all) 462 { 463 + if (all->par.regs) 464 + of_iounmap(all->par.regs, sizeof(struct cg14_regs)); 465 + if (all->par.clut) 466 + of_iounmap(all->par.clut, sizeof(struct cg14_clut)); 467 + if (all->par.cursor) 468 + of_iounmap(all->par.cursor, sizeof(struct cg14_cursor)); 469 + if (all->info.screen_base) 470 + of_iounmap(all->info.screen_base, all->par.fbsize); 471 + } 472 + 473 + static int __devinit cg14_init_one(struct of_device *op) 474 + { 475 + struct device_node *dp = op->node; 476 struct all_info *all; 477 + int is_8mb, linebytes, i, err; 478 479 + all = kzalloc(sizeof(*all), GFP_KERNEL); 480 + if (!all) 481 + return -ENOMEM; 482 483 spin_lock_init(&all->par.lock); 484 485 + sbusfb_fill_var(&all->info.var, dp->node, 8); 486 all->info.var.red.length = 8; 487 all->info.var.green.length = 8; 488 all->info.var.blue.length = 8; 489 490 + linebytes = of_getintprop_default(dp, "linebytes", 491 + all->info.var.xres); 492 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 493 494 + if (!strcmp(dp->parent->name, "sbus") || 495 + !strcmp(dp->parent->name, "sbi")) { 496 + all->par.physbase = op->resource[0].start; 497 + all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; 498 } else { 499 + all->par.physbase = op->resource[1].start; 500 + all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; 501 } 502 503 + all->par.regs = of_ioremap(&op->resource[0], 0, 504 + sizeof(struct cg14_regs), "cg14 regs"); 505 + all->par.clut = of_ioremap(&op->resource[0], CG14_CLUT1, 506 + sizeof(struct cg14_clut), "cg14 clut"); 507 + all->par.cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS, 508 + sizeof(struct cg14_cursor), "cg14 cursor"); 509 510 + all->info.screen_base = of_ioremap(&op->resource[1], 0, 511 + all->par.fbsize, "cg14 ram"); 512 513 + if (!all->par.regs || !all->par.clut || !all->par.cursor || 514 + !all->info.screen_base) 515 + cg14_unmap_regs(all); 516 + 517 + is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) == 518 + (8 * 1024 * 1024)); 519 + 520 + BUILD_BUG_ON(sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)); 521 522 + memcpy(&all->par.mmap_map, &__cg14_mmap_map, 523 + sizeof(all->par.mmap_map)); 524 + 525 for (i = 0; i < CG14_MMAP_ENTRIES; i++) { 526 struct sbus_mmap_map *map = &all->par.mmap_map[i]; 527 528 if (!map->size) 529 break; 530 if (map->poff & 0x80000000) 531 + map->poff = (map->poff & 0x7fffffff) + 532 + (op->resource[0].start - 533 + op->resource[1].start); 534 if (is_8mb && 535 map->size >= 0x100000 && 536 map->size <= 0x400000) ··· 564 __cg14_reset(&all->par); 565 566 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 567 + cg14_unmap_regs(all); 568 kfree(all); 569 + return -ENOMEM; 570 } 571 fb_set_cmap(&all->info.cmap, &all->info); 572 573 + cg14_init_fix(&all->info, linebytes, dp); 574 575 + err = register_framebuffer(&all->info); 576 + if (err < 0) { 577 fb_dealloc_cmap(&all->info.cmap); 578 + cg14_unmap_regs(all); 579 kfree(all); 580 + return err; 581 } 582 583 + dev_set_drvdata(&op->dev, all); 584 585 + printk("%s: cgfourteen at %lx:%lx, %dMB\n", 586 + dp->full_name, 587 + all->par.iospace, all->par.physbase, 588 + all->par.ramsize >> 20); 589 590 + return 0; 591 } 592 + 593 + static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id *match) 594 + { 595 + struct of_device *op = to_of_device(&dev->dev); 596 + 597 + return cg14_init_one(op); 598 + } 599 + 600 + static int __devexit cg14_remove(struct of_device *dev) 601 + { 602 + struct all_info *all = dev_get_drvdata(&dev->dev); 603 + 604 + unregister_framebuffer(&all->info); 605 + fb_dealloc_cmap(&all->info.cmap); 606 + 607 + cg14_unmap_regs(all); 608 + 609 + kfree(all); 610 + 611 + dev_set_drvdata(&dev->dev, NULL); 612 + 613 + return 0; 614 + } 615 + 616 + static struct of_device_id cg14_match[] = { 617 + { 618 + .name = "cgfourteen", 619 + }, 620 + {}, 621 + }; 622 + MODULE_DEVICE_TABLE(of, cg14_match); 623 + 624 + static struct of_platform_driver cg14_driver = { 625 + .name = "cg14", 626 + .match_table = cg14_match, 627 + .probe = cg14_probe, 628 + .remove = __devexit_p(cg14_remove), 629 + }; 630 631 int __init cg14_init(void) 632 { 633 if (fb_get_options("cg14fb", NULL)) 634 return -ENODEV; 635 636 + return of_register_driver(&cg14_driver, &of_bus_type); 637 } 638 639 void __exit cg14_exit(void) 640 { 641 + of_unregister_driver(&cg14_driver); 642 } 643 644 module_init(cg14_init); 645 module_exit(cg14_exit); 646 647 MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets"); 648 + MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 649 + MODULE_VERSION("2.0"); 650 MODULE_LICENSE("GPL");
+115 -110
drivers/video/cg3.c
··· 1 /* cg3.c: CGTHREE frame buffer driver 2 * 3 - * Copyright (C) 2003 David S. Miller (davem@redhat.com) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) ··· 19 #include <linux/mm.h> 20 21 #include <asm/io.h> 22 - #include <asm/sbus.h> 23 #include <asm/oplib.h> 24 #include <asm/fbio.h> 25 26 #include "sbuslib.h" ··· 81 }; 82 83 struct bt_regs { 84 - volatile u32 addr; 85 - volatile u32 color_map; 86 - volatile u32 control; 87 - volatile u32 cursor; 88 }; 89 90 struct cg3_regs { 91 struct bt_regs cmap; 92 - volatile u8 control; 93 - volatile u8 status; 94 - volatile u8 cursor_start; 95 - volatile u8 cursor_end; 96 - volatile u8 h_blank_start; 97 - volatile u8 h_blank_end; 98 - volatile u8 h_sync_start; 99 - volatile u8 h_sync_end; 100 - volatile u8 comp_sync_end; 101 - volatile u8 v_blank_start_high; 102 - volatile u8 v_blank_start_low; 103 - volatile u8 v_blank_end; 104 - volatile u8 v_sync_start; 105 - volatile u8 v_sync_end; 106 - volatile u8 xfer_holdoff_start; 107 - volatile u8 xfer_holdoff_end; 108 }; 109 110 /* Offset of interesting structures in the OBIO space */ ··· 121 #define CG3_FLAG_RDI 0x00000002 122 123 unsigned long physbase; 124 unsigned long fbsize; 125 - 126 - struct sbus_dev *sdev; 127 }; 128 129 /** ··· 235 236 return sbusfb_mmap_helper(cg3_mmap_map, 237 par->physbase, par->fbsize, 238 - par->sdev->reg_addrs[0].which_io, 239 vma); 240 } 241 ··· 252 */ 253 254 static void 255 - cg3_init_fix(struct fb_info *info, int linebytes) 256 { 257 - struct cg3_par *par = (struct cg3_par *)info->par; 258 - 259 - strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id)); 260 261 info->fix.type = FB_TYPE_PACKED_PIXELS; 262 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ··· 265 } 266 267 static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var, 268 - struct sbus_dev *sdev) 269 { 270 - char buffer[40]; 271 char *p; 272 int ww, hh; 273 274 - *buffer = 0; 275 - prom_getstring(sdev->prom_node, "params", buffer, sizeof(buffer)); 276 - if (*buffer) { 277 - ww = simple_strtoul(buffer, &p, 10); 278 if (ww && *p == 'x') { 279 hh = simple_strtoul(p + 1, &p, 10); 280 if (hh && *p == '-') { ··· 345 sbus_writeb(p[1], regp); 346 } 347 for (p = cg3_dacvals; *p; p += 2) { 348 - volatile u8 __iomem *regp; 349 350 - regp = (volatile u8 __iomem *)&par->regs->cmap.addr; 351 sbus_writeb(p[0], regp); 352 - regp = (volatile u8 __iomem *)&par->regs->cmap.control; 353 sbus_writeb(p[1], regp); 354 } 355 } ··· 357 struct all_info { 358 struct fb_info info; 359 struct cg3_par par; 360 - struct list_head list; 361 }; 362 - static LIST_HEAD(cg3_list); 363 364 - static void cg3_init_one(struct sbus_dev *sdev) 365 { 366 struct all_info *all; 367 - int linebytes; 368 369 - all = kmalloc(sizeof(*all), GFP_KERNEL); 370 - if (!all) { 371 - printk(KERN_ERR "cg3: Cannot allocate memory.\n"); 372 - return; 373 - } 374 - memset(all, 0, sizeof(*all)); 375 - 376 - INIT_LIST_HEAD(&all->list); 377 378 spin_lock_init(&all->par.lock); 379 - all->par.sdev = sdev; 380 381 - all->par.physbase = sdev->reg_addrs[0].phys_addr; 382 383 - sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); 384 all->info.var.red.length = 8; 385 all->info.var.green.length = 8; 386 all->info.var.blue.length = 8; 387 - if (!strcmp(sdev->prom_name, "cgRDI")) 388 all->par.flags |= CG3_FLAG_RDI; 389 if (all->par.flags & CG3_FLAG_RDI) 390 - cg3_rdi_maybe_fixup_var(&all->info.var, sdev); 391 392 - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 393 - all->info.var.xres); 394 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 395 396 - all->par.regs = sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET, 397 - sizeof(struct cg3_regs), "cg3 regs"); 398 399 all->info.flags = FBINFO_DEFAULT; 400 all->info.fbops = &cg3_ops; 401 - #ifdef CONFIG_SPARC32 402 - all->info.screen_base = (char __iomem *) 403 - prom_getintdefault(sdev->prom_node, "address", 0); 404 - #endif 405 - if (!all->info.screen_base) 406 - all->info.screen_base = 407 - sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET, 408 - all->par.fbsize, "cg3 ram"); 409 all->info.par = &all->par; 410 411 cg3_blank(0, &all->info); 412 413 - if (!prom_getbool(sdev->prom_node, "width")) 414 cg3_do_default_mode(&all->par); 415 416 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 417 - printk(KERN_ERR "cg3: Could not allocate color map.\n"); 418 kfree(all); 419 - return; 420 } 421 fb_set_cmap(&all->info.cmap, &all->info); 422 423 - cg3_init_fix(&all->info, linebytes); 424 425 - if (register_framebuffer(&all->info) < 0) { 426 - printk(KERN_ERR "cg3: Could not register framebuffer.\n"); 427 fb_dealloc_cmap(&all->info.cmap); 428 kfree(all); 429 - return; 430 } 431 432 - list_add(&all->list, &cg3_list); 433 434 - printk("cg3: %s at %lx:%lx\n", 435 - sdev->prom_name, 436 - (long) sdev->reg_addrs[0].which_io, 437 - (long) sdev->reg_addrs[0].phys_addr); 438 } 439 440 - int __init cg3_init(void) 441 { 442 - struct sbus_bus *sbus; 443 - struct sbus_dev *sdev; 444 445 if (fb_get_options("cg3fb", NULL)) 446 return -ENODEV; 447 448 - for_all_sbusdev(sdev, sbus) { 449 - if (!strcmp(sdev->prom_name, "cgthree") || 450 - !strcmp(sdev->prom_name, "cgRDI")) 451 - cg3_init_one(sdev); 452 - } 453 - 454 - return 0; 455 } 456 457 - void __exit cg3_exit(void) 458 { 459 - struct list_head *pos, *tmp; 460 - 461 - list_for_each_safe(pos, tmp, &cg3_list) { 462 - struct all_info *all = list_entry(pos, typeof(*all), list); 463 - 464 - unregister_framebuffer(&all->info); 465 - fb_dealloc_cmap(&all->info.cmap); 466 - kfree(all); 467 - } 468 - } 469 - 470 - int __init 471 - cg3_setup(char *arg) 472 - { 473 - /* No cmdline options yet... */ 474 - return 0; 475 } 476 477 module_init(cg3_init); 478 - 479 - #ifdef MODULE 480 module_exit(cg3_exit); 481 - #endif 482 483 MODULE_DESCRIPTION("framebuffer driver for CGthree chipsets"); 484 - MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 485 MODULE_LICENSE("GPL");
··· 1 /* cg3.c: CGTHREE frame buffer driver 2 * 3 + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) ··· 19 #include <linux/mm.h> 20 21 #include <asm/io.h> 22 #include <asm/oplib.h> 23 + #include <asm/prom.h> 24 + #include <asm/of_device.h> 25 #include <asm/fbio.h> 26 27 #include "sbuslib.h" ··· 80 }; 81 82 struct bt_regs { 83 + u32 addr; 84 + u32 color_map; 85 + u32 control; 86 + u32 cursor; 87 }; 88 89 struct cg3_regs { 90 struct bt_regs cmap; 91 + u8 control; 92 + u8 status; 93 + u8 cursor_start; 94 + u8 cursor_end; 95 + u8 h_blank_start; 96 + u8 h_blank_end; 97 + u8 h_sync_start; 98 + u8 h_sync_end; 99 + u8 comp_sync_end; 100 + u8 v_blank_start_high; 101 + u8 v_blank_start_low; 102 + u8 v_blank_end; 103 + u8 v_sync_start; 104 + u8 v_sync_end; 105 + u8 xfer_holdoff_start; 106 + u8 xfer_holdoff_end; 107 }; 108 109 /* Offset of interesting structures in the OBIO space */ ··· 120 #define CG3_FLAG_RDI 0x00000002 121 122 unsigned long physbase; 123 + unsigned long which_io; 124 unsigned long fbsize; 125 }; 126 127 /** ··· 235 236 return sbusfb_mmap_helper(cg3_mmap_map, 237 par->physbase, par->fbsize, 238 + par->which_io, 239 vma); 240 } 241 ··· 252 */ 253 254 static void 255 + cg3_init_fix(struct fb_info *info, int linebytes, struct device_node *dp) 256 { 257 + strlcpy(info->fix.id, dp->name, sizeof(info->fix.id)); 258 259 info->fix.type = FB_TYPE_PACKED_PIXELS; 260 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ··· 267 } 268 269 static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var, 270 + struct device_node *dp) 271 { 272 + char *params; 273 char *p; 274 int ww, hh; 275 276 + params = of_get_property(dp, "params", NULL); 277 + if (params) { 278 + ww = simple_strtoul(params, &p, 10); 279 if (ww && *p == 'x') { 280 hh = simple_strtoul(p + 1, &p, 10); 281 if (hh && *p == '-') { ··· 348 sbus_writeb(p[1], regp); 349 } 350 for (p = cg3_dacvals; *p; p += 2) { 351 + u8 __iomem *regp; 352 353 + regp = (u8 __iomem *)&par->regs->cmap.addr; 354 sbus_writeb(p[0], regp); 355 + regp = (u8 __iomem *)&par->regs->cmap.control; 356 sbus_writeb(p[1], regp); 357 } 358 } ··· 360 struct all_info { 361 struct fb_info info; 362 struct cg3_par par; 363 }; 364 365 + static int __devinit cg3_init_one(struct of_device *op) 366 { 367 + struct device_node *dp = op->node; 368 struct all_info *all; 369 + int linebytes, err; 370 371 + all = kzalloc(sizeof(*all), GFP_KERNEL); 372 + if (!all) 373 + return -ENOMEM; 374 375 spin_lock_init(&all->par.lock); 376 377 + all->par.physbase = op->resource[0].start; 378 + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; 379 380 + sbusfb_fill_var(&all->info.var, dp->node, 8); 381 all->info.var.red.length = 8; 382 all->info.var.green.length = 8; 383 all->info.var.blue.length = 8; 384 + if (!strcmp(dp->name, "cgRDI")) 385 all->par.flags |= CG3_FLAG_RDI; 386 if (all->par.flags & CG3_FLAG_RDI) 387 + cg3_rdi_maybe_fixup_var(&all->info.var, dp); 388 389 + linebytes = of_getintprop_default(dp, "linebytes", 390 + all->info.var.xres); 391 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 392 393 + all->par.regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET, 394 + sizeof(struct cg3_regs), "cg3 regs"); 395 396 all->info.flags = FBINFO_DEFAULT; 397 all->info.fbops = &cg3_ops; 398 + all->info.screen_base = 399 + of_ioremap(&op->resource[0], CG3_RAM_OFFSET, 400 + all->par.fbsize, "cg3 ram"); 401 all->info.par = &all->par; 402 403 cg3_blank(0, &all->info); 404 405 + if (!of_find_property(dp, "width", NULL)) 406 cg3_do_default_mode(&all->par); 407 408 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 409 + of_iounmap(all->par.regs, sizeof(struct cg3_regs)); 410 + of_iounmap(all->info.screen_base, all->par.fbsize); 411 kfree(all); 412 + return -ENOMEM; 413 } 414 fb_set_cmap(&all->info.cmap, &all->info); 415 416 + cg3_init_fix(&all->info, linebytes, dp); 417 418 + err = register_framebuffer(&all->info); 419 + if (err < 0) { 420 fb_dealloc_cmap(&all->info.cmap); 421 + of_iounmap(all->par.regs, sizeof(struct cg3_regs)); 422 + of_iounmap(all->info.screen_base, all->par.fbsize); 423 kfree(all); 424 + return err; 425 } 426 427 + dev_set_drvdata(&op->dev, all); 428 429 + printk("%s: cg3 at %lx:%lx\n", 430 + dp->full_name, all->par.which_io, all->par.physbase); 431 + 432 + return 0; 433 } 434 435 + static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id *match) 436 { 437 + struct of_device *op = to_of_device(&dev->dev); 438 439 + return cg3_init_one(op); 440 + } 441 + 442 + static int __devexit cg3_remove(struct of_device *dev) 443 + { 444 + struct all_info *all = dev_get_drvdata(&dev->dev); 445 + 446 + unregister_framebuffer(&all->info); 447 + fb_dealloc_cmap(&all->info.cmap); 448 + 449 + of_iounmap(all->par.regs, sizeof(struct cg3_regs)); 450 + of_iounmap(all->info.screen_base, all->par.fbsize); 451 + 452 + kfree(all); 453 + 454 + dev_set_drvdata(&dev->dev, NULL); 455 + 456 + return 0; 457 + } 458 + 459 + static struct of_device_id cg3_match[] = { 460 + { 461 + .name = "cgthree", 462 + }, 463 + { 464 + .name = "cgRDI", 465 + }, 466 + {}, 467 + }; 468 + MODULE_DEVICE_TABLE(of, cg3_match); 469 + 470 + static struct of_platform_driver cg3_driver = { 471 + .name = "cg3", 472 + .match_table = cg3_match, 473 + .probe = cg3_probe, 474 + .remove = __devexit_p(cg3_remove), 475 + }; 476 + 477 + static int __init cg3_init(void) 478 + { 479 if (fb_get_options("cg3fb", NULL)) 480 return -ENODEV; 481 482 + return of_register_driver(&cg3_driver, &of_bus_type); 483 } 484 485 + static void __exit cg3_exit(void) 486 { 487 + of_unregister_driver(&cg3_driver); 488 } 489 490 module_init(cg3_init); 491 module_exit(cg3_exit); 492 493 MODULE_DESCRIPTION("framebuffer driver for CGthree chipsets"); 494 + MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 495 + MODULE_VERSION("2.0"); 496 MODULE_LICENSE("GPL");
+187 -158
drivers/video/cg6.c
··· 1 /* cg6.c: CGSIX (GX, GXplus, TGX) frame buffer driver 2 * 3 - * Copyright (C) 2003 David S. Miller (davem@redhat.com) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) ··· 19 #include <linux/mm.h> 20 21 #include <asm/io.h> 22 - #include <asm/sbus.h> 23 - #include <asm/oplib.h> 24 #include <asm/fbio.h> 25 26 #include "sbuslib.h" ··· 164 165 /* The contents are unknown */ 166 struct cg6_tec { 167 - volatile int tec_matrix; 168 - volatile int tec_clip; 169 - volatile int tec_vdc; 170 }; 171 172 struct cg6_thc { 173 - uint thc_pad0[512]; 174 - volatile uint thc_hs; /* hsync timing */ 175 - volatile uint thc_hsdvs; 176 - volatile uint thc_hd; 177 - volatile uint thc_vs; /* vsync timing */ 178 - volatile uint thc_vd; 179 - volatile uint thc_refresh; 180 - volatile uint thc_misc; 181 - uint thc_pad1[56]; 182 - volatile uint thc_cursxy; /* cursor x,y position (16 bits each) */ 183 - volatile uint thc_cursmask[32]; /* cursor mask bits */ 184 - volatile uint thc_cursbits[32]; /* what to show where mask enabled */ 185 }; 186 187 struct cg6_fbc { 188 - u32 xxx0[1]; 189 - volatile u32 mode; 190 - volatile u32 clip; 191 - u32 xxx1[1]; 192 - volatile u32 s; 193 - volatile u32 draw; 194 - volatile u32 blit; 195 - volatile u32 font; 196 - u32 xxx2[24]; 197 - volatile u32 x0, y0, z0, color0; 198 - volatile u32 x1, y1, z1, color1; 199 - volatile u32 x2, y2, z2, color2; 200 - volatile u32 x3, y3, z3, color3; 201 - volatile u32 offx, offy; 202 - u32 xxx3[2]; 203 - volatile u32 incx, incy; 204 - u32 xxx4[2]; 205 - volatile u32 clipminx, clipminy; 206 - u32 xxx5[2]; 207 - volatile u32 clipmaxx, clipmaxy; 208 - u32 xxx6[2]; 209 - volatile u32 fg; 210 - volatile u32 bg; 211 - volatile u32 alu; 212 - volatile u32 pm; 213 - volatile u32 pixelm; 214 - u32 xxx7[2]; 215 - volatile u32 patalign; 216 - volatile u32 pattern[8]; 217 - u32 xxx8[432]; 218 - volatile u32 apointx, apointy, apointz; 219 - u32 xxx9[1]; 220 - volatile u32 rpointx, rpointy, rpointz; 221 - u32 xxx10[5]; 222 - volatile u32 pointr, pointg, pointb, pointa; 223 - volatile u32 alinex, aliney, alinez; 224 - u32 xxx11[1]; 225 - volatile u32 rlinex, rliney, rlinez; 226 - u32 xxx12[5]; 227 - volatile u32 liner, lineg, lineb, linea; 228 - volatile u32 atrix, atriy, atriz; 229 - u32 xxx13[1]; 230 - volatile u32 rtrix, rtriy, rtriz; 231 - u32 xxx14[5]; 232 - volatile u32 trir, trig, trib, tria; 233 - volatile u32 aquadx, aquady, aquadz; 234 - u32 xxx15[1]; 235 - volatile u32 rquadx, rquady, rquadz; 236 - u32 xxx16[5]; 237 - volatile u32 quadr, quadg, quadb, quada; 238 - volatile u32 arectx, arecty, arectz; 239 - u32 xxx17[1]; 240 - volatile u32 rrectx, rrecty, rrectz; 241 - u32 xxx18[5]; 242 - volatile u32 rectr, rectg, rectb, recta; 243 }; 244 245 struct bt_regs { 246 - volatile u32 addr; 247 - volatile u32 color_map; 248 - volatile u32 control; 249 - volatile u32 cursor; 250 }; 251 252 struct cg6_par { ··· 255 struct cg6_fbc __iomem *fbc; 256 struct cg6_thc __iomem *thc; 257 struct cg6_tec __iomem *tec; 258 - volatile u32 __iomem *fhc; 259 260 u32 flags; 261 #define CG6_FLAG_BLANKED 0x00000001 262 263 unsigned long physbase; 264 unsigned long fbsize; 265 - 266 - struct sbus_dev *sdev; 267 }; 268 269 static int cg6_sync(struct fb_info *info) ··· 528 529 return sbusfb_mmap_helper(cg6_mmap_map, 530 par->physbase, par->fbsize, 531 - par->sdev->reg_addrs[0].which_io, 532 - vma); 533 } 534 535 static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) ··· 656 struct all_info { 657 struct fb_info info; 658 struct cg6_par par; 659 - struct list_head list; 660 }; 661 - static LIST_HEAD(cg6_list); 662 663 - static void cg6_init_one(struct sbus_dev *sdev) 664 { 665 struct all_info *all; 666 - int linebytes; 667 668 - all = kmalloc(sizeof(*all), GFP_KERNEL); 669 - if (!all) { 670 - printk(KERN_ERR "cg6: Cannot allocate memory.\n"); 671 - return; 672 - } 673 - memset(all, 0, sizeof(*all)); 674 - 675 - INIT_LIST_HEAD(&all->list); 676 677 spin_lock_init(&all->par.lock); 678 - all->par.sdev = sdev; 679 680 - all->par.physbase = sdev->reg_addrs[0].phys_addr; 681 682 - sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); 683 all->info.var.red.length = 8; 684 all->info.var.green.length = 8; 685 all->info.var.blue.length = 8; 686 687 - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 688 - all->info.var.xres); 689 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 690 - if (prom_getbool(sdev->prom_node, "dblbuf")) 691 all->par.fbsize *= 4; 692 693 - all->par.fbc = sbus_ioremap(&sdev->resource[0], CG6_FBC_OFFSET, 694 - 4096, "cgsix fbc"); 695 - all->par.tec = sbus_ioremap(&sdev->resource[0], CG6_TEC_OFFSET, 696 - sizeof(struct cg6_tec), "cgsix tec"); 697 - all->par.thc = sbus_ioremap(&sdev->resource[0], CG6_THC_OFFSET, 698 - sizeof(struct cg6_thc), "cgsix thc"); 699 - all->par.bt = sbus_ioremap(&sdev->resource[0], CG6_BROOKTREE_OFFSET, 700 - sizeof(struct bt_regs), "cgsix dac"); 701 - all->par.fhc = sbus_ioremap(&sdev->resource[0], CG6_FHC_OFFSET, 702 - sizeof(u32), "cgsix fhc"); 703 704 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT | 705 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; 706 all->info.fbops = &cg6_ops; 707 - #ifdef CONFIG_SPARC32 708 - all->info.screen_base = (char __iomem *) 709 - prom_getintdefault(sdev->prom_node, "address", 0); 710 - #endif 711 - if (!all->info.screen_base) 712 - all->info.screen_base = 713 - sbus_ioremap(&sdev->resource[0], CG6_RAM_OFFSET, 714 - all->par.fbsize, "cgsix ram"); 715 all->info.par = &all->par; 716 717 all->info.var.accel_flags = FB_ACCELF_TEXT; ··· 734 cg6_blank(0, &all->info); 735 736 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 737 - printk(KERN_ERR "cg6: Could not allocate color map.\n"); 738 kfree(all); 739 - return; 740 } 741 742 fb_set_cmap(&all->info.cmap, &all->info); 743 cg6_init_fix(&all->info, linebytes); 744 745 - if (register_framebuffer(&all->info) < 0) { 746 - printk(KERN_ERR "cg6: Could not register framebuffer.\n"); 747 fb_dealloc_cmap(&all->info.cmap); 748 kfree(all); 749 - return; 750 } 751 752 - list_add(&all->list, &cg6_list); 753 754 - printk("cg6: CGsix [%s] at %lx:%lx\n", 755 all->info.fix.id, 756 - (long) sdev->reg_addrs[0].which_io, 757 - (long) sdev->reg_addrs[0].phys_addr); 758 } 759 760 - int __init cg6_init(void) 761 { 762 - struct sbus_bus *sbus; 763 - struct sbus_dev *sdev; 764 765 if (fb_get_options("cg6fb", NULL)) 766 return -ENODEV; 767 768 - for_all_sbusdev(sdev, sbus) { 769 - if (!strcmp(sdev->prom_name, "cgsix") || 770 - !strcmp(sdev->prom_name, "cgthree+")) 771 - cg6_init_one(sdev); 772 - } 773 - 774 - return 0; 775 } 776 777 - void __exit cg6_exit(void) 778 { 779 - struct list_head *pos, *tmp; 780 - 781 - list_for_each_safe(pos, tmp, &cg6_list) { 782 - struct all_info *all = list_entry(pos, typeof(*all), list); 783 - 784 - unregister_framebuffer(&all->info); 785 - fb_dealloc_cmap(&all->info.cmap); 786 - kfree(all); 787 - } 788 - } 789 - 790 - int __init 791 - cg6_setup(char *arg) 792 - { 793 - /* No cmdline options yet... */ 794 - return 0; 795 } 796 797 module_init(cg6_init); 798 - 799 - #ifdef MODULE 800 module_exit(cg6_exit); 801 - #endif 802 803 MODULE_DESCRIPTION("framebuffer driver for CGsix chipsets"); 804 - MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 805 MODULE_LICENSE("GPL");
··· 1 /* cg6.c: CGSIX (GX, GXplus, TGX) frame buffer driver 2 * 3 + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) ··· 19 #include <linux/mm.h> 20 21 #include <asm/io.h> 22 + #include <asm/prom.h> 23 + #include <asm/of_device.h> 24 #include <asm/fbio.h> 25 26 #include "sbuslib.h" ··· 164 165 /* The contents are unknown */ 166 struct cg6_tec { 167 + int tec_matrix; 168 + int tec_clip; 169 + int tec_vdc; 170 }; 171 172 struct cg6_thc { 173 + u32 thc_pad0[512]; 174 + u32 thc_hs; /* hsync timing */ 175 + u32 thc_hsdvs; 176 + u32 thc_hd; 177 + u32 thc_vs; /* vsync timing */ 178 + u32 thc_vd; 179 + u32 thc_refresh; 180 + u32 thc_misc; 181 + u32 thc_pad1[56]; 182 + u32 thc_cursxy; /* cursor x,y position (16 bits each) */ 183 + u32 thc_cursmask[32]; /* cursor mask bits */ 184 + u32 thc_cursbits[32]; /* what to show where mask enabled */ 185 }; 186 187 struct cg6_fbc { 188 + u32 xxx0[1]; 189 + u32 mode; 190 + u32 clip; 191 + u32 xxx1[1]; 192 + u32 s; 193 + u32 draw; 194 + u32 blit; 195 + u32 font; 196 + u32 xxx2[24]; 197 + u32 x0, y0, z0, color0; 198 + u32 x1, y1, z1, color1; 199 + u32 x2, y2, z2, color2; 200 + u32 x3, y3, z3, color3; 201 + u32 offx, offy; 202 + u32 xxx3[2]; 203 + u32 incx, incy; 204 + u32 xxx4[2]; 205 + u32 clipminx, clipminy; 206 + u32 xxx5[2]; 207 + u32 clipmaxx, clipmaxy; 208 + u32 xxx6[2]; 209 + u32 fg; 210 + u32 bg; 211 + u32 alu; 212 + u32 pm; 213 + u32 pixelm; 214 + u32 xxx7[2]; 215 + u32 patalign; 216 + u32 pattern[8]; 217 + u32 xxx8[432]; 218 + u32 apointx, apointy, apointz; 219 + u32 xxx9[1]; 220 + u32 rpointx, rpointy, rpointz; 221 + u32 xxx10[5]; 222 + u32 pointr, pointg, pointb, pointa; 223 + u32 alinex, aliney, alinez; 224 + u32 xxx11[1]; 225 + u32 rlinex, rliney, rlinez; 226 + u32 xxx12[5]; 227 + u32 liner, lineg, lineb, linea; 228 + u32 atrix, atriy, atriz; 229 + u32 xxx13[1]; 230 + u32 rtrix, rtriy, rtriz; 231 + u32 xxx14[5]; 232 + u32 trir, trig, trib, tria; 233 + u32 aquadx, aquady, aquadz; 234 + u32 xxx15[1]; 235 + u32 rquadx, rquady, rquadz; 236 + u32 xxx16[5]; 237 + u32 quadr, quadg, quadb, quada; 238 + u32 arectx, arecty, arectz; 239 + u32 xxx17[1]; 240 + u32 rrectx, rrecty, rrectz; 241 + u32 xxx18[5]; 242 + u32 rectr, rectg, rectb, recta; 243 }; 244 245 struct bt_regs { 246 + u32 addr; 247 + u32 color_map; 248 + u32 control; 249 + u32 cursor; 250 }; 251 252 struct cg6_par { ··· 255 struct cg6_fbc __iomem *fbc; 256 struct cg6_thc __iomem *thc; 257 struct cg6_tec __iomem *tec; 258 + u32 __iomem *fhc; 259 260 u32 flags; 261 #define CG6_FLAG_BLANKED 0x00000001 262 263 unsigned long physbase; 264 + unsigned long which_io; 265 unsigned long fbsize; 266 }; 267 268 static int cg6_sync(struct fb_info *info) ··· 529 530 return sbusfb_mmap_helper(cg6_mmap_map, 531 par->physbase, par->fbsize, 532 + par->which_io, vma); 533 } 534 535 static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) ··· 658 struct all_info { 659 struct fb_info info; 660 struct cg6_par par; 661 }; 662 663 + static void cg6_unmap_regs(struct all_info *all) 664 { 665 + if (all->par.fbc) 666 + of_iounmap(all->par.fbc, 4096); 667 + if (all->par.tec) 668 + of_iounmap(all->par.tec, sizeof(struct cg6_tec)); 669 + if (all->par.thc) 670 + of_iounmap(all->par.thc, sizeof(struct cg6_thc)); 671 + if (all->par.bt) 672 + of_iounmap(all->par.bt, sizeof(struct bt_regs)); 673 + if (all->par.fhc) 674 + of_iounmap(all->par.fhc, sizeof(u32)); 675 + 676 + if (all->info.screen_base) 677 + of_iounmap(all->info.screen_base, all->par.fbsize); 678 + } 679 + 680 + static int __devinit cg6_init_one(struct of_device *op) 681 + { 682 + struct device_node *dp = op->node; 683 struct all_info *all; 684 + int linebytes, err; 685 686 + all = kzalloc(sizeof(*all), GFP_KERNEL); 687 + if (!all) 688 + return -ENOMEM; 689 690 spin_lock_init(&all->par.lock); 691 692 + all->par.physbase = op->resource[0].start; 693 + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; 694 695 + sbusfb_fill_var(&all->info.var, dp->node, 8); 696 all->info.var.red.length = 8; 697 all->info.var.green.length = 8; 698 all->info.var.blue.length = 8; 699 700 + linebytes = of_getintprop_default(dp, "linebytes", 701 + all->info.var.xres); 702 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 703 + if (of_find_property(dp, "dblbuf", NULL)) 704 all->par.fbsize *= 4; 705 706 + all->par.fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET, 707 + 4096, "cgsix fbc"); 708 + all->par.tec = of_ioremap(&op->resource[0], CG6_TEC_OFFSET, 709 + sizeof(struct cg6_tec), "cgsix tec"); 710 + all->par.thc = of_ioremap(&op->resource[0], CG6_THC_OFFSET, 711 + sizeof(struct cg6_thc), "cgsix thc"); 712 + all->par.bt = of_ioremap(&op->resource[0], CG6_BROOKTREE_OFFSET, 713 + sizeof(struct bt_regs), "cgsix dac"); 714 + all->par.fhc = of_ioremap(&op->resource[0], CG6_FHC_OFFSET, 715 + sizeof(u32), "cgsix fhc"); 716 717 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT | 718 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; 719 all->info.fbops = &cg6_ops; 720 + 721 + all->info.screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET, 722 + all->par.fbsize, "cgsix ram"); 723 + if (!all->par.fbc || !all->par.tec || !all->par.thc || 724 + !all->par.bt || !all->par.fhc || !all->info.screen_base) { 725 + cg6_unmap_regs(all); 726 + kfree(all); 727 + return -ENOMEM; 728 + } 729 + 730 all->info.par = &all->par; 731 732 all->info.var.accel_flags = FB_ACCELF_TEXT; ··· 723 cg6_blank(0, &all->info); 724 725 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 726 + cg6_unmap_regs(all); 727 kfree(all); 728 + return -ENOMEM; 729 } 730 731 fb_set_cmap(&all->info.cmap, &all->info); 732 cg6_init_fix(&all->info, linebytes); 733 734 + err = register_framebuffer(&all->info); 735 + if (err < 0) { 736 + cg6_unmap_regs(all); 737 fb_dealloc_cmap(&all->info.cmap); 738 kfree(all); 739 + return err; 740 } 741 742 + dev_set_drvdata(&op->dev, all); 743 744 + printk("%s: CGsix [%s] at %lx:%lx\n", 745 + dp->full_name, 746 all->info.fix.id, 747 + all->par.which_io, all->par.physbase); 748 + 749 + return 0; 750 } 751 752 + static int __devinit cg6_probe(struct of_device *dev, const struct of_device_id *match) 753 { 754 + struct of_device *op = to_of_device(&dev->dev); 755 756 + return cg6_init_one(op); 757 + } 758 + 759 + static int __devexit cg6_remove(struct of_device *dev) 760 + { 761 + struct all_info *all = dev_get_drvdata(&dev->dev); 762 + 763 + unregister_framebuffer(&all->info); 764 + fb_dealloc_cmap(&all->info.cmap); 765 + 766 + cg6_unmap_regs(all); 767 + 768 + kfree(all); 769 + 770 + dev_set_drvdata(&dev->dev, NULL); 771 + 772 + return 0; 773 + } 774 + 775 + static struct of_device_id cg6_match[] = { 776 + { 777 + .name = "cgsix", 778 + }, 779 + { 780 + .name = "cgthree+", 781 + }, 782 + {}, 783 + }; 784 + MODULE_DEVICE_TABLE(of, cg6_match); 785 + 786 + static struct of_platform_driver cg6_driver = { 787 + .name = "cg6", 788 + .match_table = cg6_match, 789 + .probe = cg6_probe, 790 + .remove = __devexit_p(cg6_remove), 791 + }; 792 + 793 + static int __init cg6_init(void) 794 + { 795 if (fb_get_options("cg6fb", NULL)) 796 return -ENODEV; 797 798 + return of_register_driver(&cg6_driver, &of_bus_type); 799 } 800 801 + static void __exit cg6_exit(void) 802 { 803 + of_unregister_driver(&cg6_driver); 804 } 805 806 module_init(cg6_init); 807 module_exit(cg6_exit); 808 809 MODULE_DESCRIPTION("framebuffer driver for CGsix chipsets"); 810 + MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 811 + MODULE_VERSION("2.0"); 812 MODULE_LICENSE("GPL");
+222 -254
drivers/video/ffb.c
··· 1 /* ffb.c: Creator/Elite3D frame buffer driver 2 * 3 - * Copyright (C) 2003 David S. Miller (davem@redhat.com) 4 * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz) 5 * 6 * Driver layout based loosely on tgafb.c, see that file for credits. ··· 19 20 #include <asm/io.h> 21 #include <asm/upa.h> 22 - #include <asm/oplib.h> 23 #include <asm/fbio.h> 24 25 #include "sbuslib.h" ··· 185 186 struct ffb_fbc { 187 /* Next vertex registers */ 188 - u32 xxx1[3]; 189 - volatile u32 alpha; 190 - volatile u32 red; 191 - volatile u32 green; 192 - volatile u32 blue; 193 - volatile u32 depth; 194 - volatile u32 y; 195 - volatile u32 x; 196 - u32 xxx2[2]; 197 - volatile u32 ryf; 198 - volatile u32 rxf; 199 - u32 xxx3[2]; 200 201 - volatile u32 dmyf; 202 - volatile u32 dmxf; 203 - u32 xxx4[2]; 204 - volatile u32 ebyi; 205 - volatile u32 ebxi; 206 - u32 xxx5[2]; 207 - volatile u32 by; 208 - volatile u32 bx; 209 - u32 dy; 210 - u32 dx; 211 - volatile u32 bh; 212 - volatile u32 bw; 213 - u32 xxx6[2]; 214 215 - u32 xxx7[32]; 216 217 /* Setup unit vertex state register */ 218 - volatile u32 suvtx; 219 - u32 xxx8[63]; 220 221 /* Control registers */ 222 - volatile u32 ppc; 223 - volatile u32 wid; 224 - volatile u32 fg; 225 - volatile u32 bg; 226 - volatile u32 consty; 227 - volatile u32 constz; 228 - volatile u32 xclip; 229 - volatile u32 dcss; 230 - volatile u32 vclipmin; 231 - volatile u32 vclipmax; 232 - volatile u32 vclipzmin; 233 - volatile u32 vclipzmax; 234 - volatile u32 dcsf; 235 - volatile u32 dcsb; 236 - volatile u32 dczf; 237 - volatile u32 dczb; 238 239 - u32 xxx9; 240 - volatile u32 blendc; 241 - volatile u32 blendc1; 242 - volatile u32 blendc2; 243 - volatile u32 fbramitc; 244 - volatile u32 fbc; 245 - volatile u32 rop; 246 - volatile u32 cmp; 247 - volatile u32 matchab; 248 - volatile u32 matchc; 249 - volatile u32 magnab; 250 - volatile u32 magnc; 251 - volatile u32 fbcfg0; 252 - volatile u32 fbcfg1; 253 - volatile u32 fbcfg2; 254 - volatile u32 fbcfg3; 255 256 - u32 ppcfg; 257 - volatile u32 pick; 258 - volatile u32 fillmode; 259 - volatile u32 fbramwac; 260 - volatile u32 pmask; 261 - volatile u32 xpmask; 262 - volatile u32 ypmask; 263 - volatile u32 zpmask; 264 - volatile u32 clip0min; 265 - volatile u32 clip0max; 266 - volatile u32 clip1min; 267 - volatile u32 clip1max; 268 - volatile u32 clip2min; 269 - volatile u32 clip2max; 270 - volatile u32 clip3min; 271 - volatile u32 clip3max; 272 273 /* New 3dRAM III support regs */ 274 - volatile u32 rawblend2; 275 - volatile u32 rawpreblend; 276 - volatile u32 rawstencil; 277 - volatile u32 rawstencilctl; 278 - volatile u32 threedram1; 279 - volatile u32 threedram2; 280 - volatile u32 passin; 281 - volatile u32 rawclrdepth; 282 - volatile u32 rawpmask; 283 - volatile u32 rawcsrc; 284 - volatile u32 rawmatch; 285 - volatile u32 rawmagn; 286 - volatile u32 rawropblend; 287 - volatile u32 rawcmp; 288 - volatile u32 rawwac; 289 - volatile u32 fbramid; 290 291 - volatile u32 drawop; 292 - u32 xxx10[2]; 293 - volatile u32 fontlpat; 294 - u32 xxx11; 295 - volatile u32 fontxy; 296 - volatile u32 fontw; 297 - volatile u32 fontinc; 298 - volatile u32 font; 299 - u32 xxx12[3]; 300 - volatile u32 blend2; 301 - volatile u32 preblend; 302 - volatile u32 stencil; 303 - volatile u32 stencilctl; 304 305 - u32 xxx13[4]; 306 - volatile u32 dcss1; 307 - volatile u32 dcss2; 308 - volatile u32 dcss3; 309 - volatile u32 widpmask; 310 - volatile u32 dcs2; 311 - volatile u32 dcs3; 312 - volatile u32 dcs4; 313 - u32 xxx14; 314 - volatile u32 dcd2; 315 - volatile u32 dcd3; 316 - volatile u32 dcd4; 317 - u32 xxx15; 318 319 - volatile u32 pattern[32]; 320 321 - u32 xxx16[256]; 322 323 - volatile u32 devid; 324 - u32 xxx17[63]; 325 326 - volatile u32 ucsr; 327 - u32 xxx18[31]; 328 329 - volatile u32 mer; 330 }; 331 332 struct ffb_dac { 333 - volatile u32 type; 334 - volatile u32 value; 335 - volatile u32 type2; 336 - volatile u32 value2; 337 }; 338 339 struct ffb_par { 340 spinlock_t lock; 341 - struct ffb_fbc *fbc; 342 - struct ffb_dac *dac; 343 344 u32 flags; 345 #define FFB_FLAG_AFB 0x00000001 ··· 354 unsigned long physbase; 355 unsigned long fbsize; 356 357 - char name[64]; 358 - int prom_node; 359 - int prom_parent_node; 360 int dac_rev; 361 int board_type; 362 }; 363 364 static void FFBFifo(struct ffb_par *par, int n) 365 { 366 - struct ffb_fbc *fbc; 367 int cache = par->fifo_cache; 368 369 if (cache - n < 0) { ··· 373 374 static void FFBWait(struct ffb_par *par) 375 { 376 - struct ffb_fbc *fbc; 377 int limit = 10000; 378 379 fbc = par->fbc; ··· 406 407 static void ffb_switch_from_graph(struct ffb_par *par) 408 { 409 - struct ffb_fbc *fbc = par->fbc; 410 - struct ffb_dac *dac = par->dac; 411 unsigned long flags; 412 413 spin_lock_irqsave(&par->lock, flags); ··· 460 static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 461 { 462 struct ffb_par *par = (struct ffb_par *) info->par; 463 - struct ffb_fbc *fbc = par->fbc; 464 unsigned long flags; 465 u32 fg; 466 ··· 503 ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 504 { 505 struct ffb_par *par = (struct ffb_par *) info->par; 506 - struct ffb_fbc *fbc = par->fbc; 507 unsigned long flags; 508 509 if (area->dx != area->sx || ··· 539 static void ffb_imageblit(struct fb_info *info, const struct fb_image *image) 540 { 541 struct ffb_par *par = (struct ffb_par *) info->par; 542 - struct ffb_fbc *fbc = par->fbc; 543 const u8 *data = image->data; 544 unsigned long flags; 545 u32 fg, bg, xy; ··· 662 ffb_blank(int blank, struct fb_info *info) 663 { 664 struct ffb_par *par = (struct ffb_par *) info->par; 665 - struct ffb_dac *dac = par->dac; 666 unsigned long flags; 667 u32 tmp; 668 ··· 881 info->fix.accel = FB_ACCEL_SUN_CREATOR; 882 } 883 884 - static int ffb_apply_upa_parent_ranges(int parent, 885 - struct linux_prom64_registers *regs) 886 - { 887 - struct linux_prom64_ranges ranges[PROMREG_MAX]; 888 - char name[128]; 889 - int len, i; 890 - 891 - prom_getproperty(parent, "name", name, sizeof(name)); 892 - if (strcmp(name, "upa") != 0) 893 - return 0; 894 - 895 - len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges)); 896 - if (len <= 0) 897 - return 1; 898 - 899 - len /= sizeof(struct linux_prom64_ranges); 900 - for (i = 0; i < len; i++) { 901 - struct linux_prom64_ranges *rng = &ranges[i]; 902 - u64 phys_addr = regs->phys_addr; 903 - 904 - if (phys_addr >= rng->ot_child_base && 905 - phys_addr < (rng->ot_child_base + rng->or_size)) { 906 - regs->phys_addr -= rng->ot_child_base; 907 - regs->phys_addr += rng->ot_parent_base; 908 - return 0; 909 - } 910 - } 911 - 912 - return 1; 913 - } 914 - 915 struct all_info { 916 struct fb_info info; 917 struct ffb_par par; 918 u32 pseudo_palette[256]; 919 - struct list_head list; 920 }; 921 - static LIST_HEAD(ffb_list); 922 923 - static void ffb_init_one(int node, int parent) 924 { 925 - struct linux_prom64_registers regs[2*PROMREG_MAX]; 926 - struct ffb_fbc *fbc; 927 - struct ffb_dac *dac; 928 struct all_info *all; 929 930 - if (prom_getproperty(node, "reg", (void *) regs, sizeof(regs)) <= 0) { 931 - printk("ffb: Cannot get reg device node property.\n"); 932 - return; 933 - } 934 - 935 - if (ffb_apply_upa_parent_ranges(parent, &regs[0])) { 936 - printk("ffb: Cannot apply parent ranges to regs.\n"); 937 - return; 938 - } 939 - 940 - all = kmalloc(sizeof(*all), GFP_KERNEL); 941 - if (!all) { 942 - printk(KERN_ERR "ffb: Cannot allocate memory.\n"); 943 - return; 944 - } 945 - memset(all, 0, sizeof(*all)); 946 - 947 - INIT_LIST_HEAD(&all->list); 948 949 spin_lock_init(&all->par.lock); 950 - all->par.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF); 951 - all->par.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF); 952 all->par.rop_cache = FFB_ROP_NEW; 953 - all->par.physbase = regs[0].phys_addr; 954 - all->par.prom_node = node; 955 - all->par.prom_parent_node = parent; 956 957 /* Don't mention copyarea, so SCROLL_REDRAW is always 958 * used. It is the fastest on this chip. ··· 930 all->info.par = &all->par; 931 all->info.pseudo_palette = all->pseudo_palette; 932 933 - sbusfb_fill_var(&all->info.var, all->par.prom_node, 32); 934 all->par.fbsize = PAGE_ALIGN(all->info.var.xres * 935 all->info.var.yres * 936 4); ··· 938 939 all->info.var.accel_flags = FB_ACCELF_TEXT; 940 941 - prom_getstring(node, "name", all->par.name, sizeof(all->par.name)); 942 - if (!strcmp(all->par.name, "SUNW,afb")) 943 all->par.flags |= FFB_FLAG_AFB; 944 945 - all->par.board_type = prom_getintdefault(node, "board_type", 0); 946 947 fbc = all->par.fbc; 948 - if((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) 949 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr); 950 951 ffb_switch_from_graph(&all->par); ··· 969 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 970 printk(KERN_ERR "ffb: Could not allocate color map.\n"); 971 kfree(all); 972 - return; 973 } 974 975 ffb_init_fix(&all->info); 976 977 - if (register_framebuffer(&all->info) < 0) { 978 printk(KERN_ERR "ffb: Could not register framebuffer.\n"); 979 fb_dealloc_cmap(&all->info.cmap); 980 kfree(all); 981 - return; 982 } 983 984 - list_add(&all->list, &ffb_list); 985 986 - printk("ffb: %s at %016lx type %d DAC %d\n", 987 ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"), 988 - regs[0].phys_addr, all->par.board_type, all->par.dac_rev); 989 } 990 991 - static void ffb_scan_siblings(int root) 992 { 993 - int node, child; 994 995 - child = prom_getchild(root); 996 - for (node = prom_searchsiblings(child, "SUNW,ffb"); node; 997 - node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb")) 998 - ffb_init_one(node, root); 999 - for (node = prom_searchsiblings(child, "SUNW,afb"); node; 1000 - node = prom_searchsiblings(prom_getsibling(node), "SUNW,afb")) 1001 - ffb_init_one(node, root); 1002 } 1003 1004 int __init ffb_init(void) 1005 { 1006 - int root; 1007 - 1008 if (fb_get_options("ffb", NULL)) 1009 return -ENODEV; 1010 1011 - ffb_scan_siblings(prom_root_node); 1012 - 1013 - root = prom_getchild(prom_root_node); 1014 - for (root = prom_searchsiblings(root, "upa"); root; 1015 - root = prom_searchsiblings(prom_getsibling(root), "upa")) 1016 - ffb_scan_siblings(root); 1017 - 1018 - return 0; 1019 } 1020 1021 void __exit ffb_exit(void) 1022 { 1023 - struct list_head *pos, *tmp; 1024 - 1025 - list_for_each_safe(pos, tmp, &ffb_list) { 1026 - struct all_info *all = list_entry(pos, typeof(*all), list); 1027 - 1028 - unregister_framebuffer(&all->info); 1029 - fb_dealloc_cmap(&all->info.cmap); 1030 - kfree(all); 1031 - } 1032 - } 1033 - 1034 - int __init 1035 - ffb_setup(char *arg) 1036 - { 1037 - /* No cmdline options yet... */ 1038 - return 0; 1039 } 1040 1041 module_init(ffb_init); 1042 - 1043 - #ifdef MODULE 1044 module_exit(ffb_exit); 1045 - #endif 1046 1047 MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets"); 1048 - MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 1049 MODULE_LICENSE("GPL");
··· 1 /* ffb.c: Creator/Elite3D frame buffer driver 2 * 3 + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) 4 * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz) 5 * 6 * Driver layout based loosely on tgafb.c, see that file for credits. ··· 19 20 #include <asm/io.h> 21 #include <asm/upa.h> 22 + #include <asm/prom.h> 23 + #include <asm/of_device.h> 24 #include <asm/fbio.h> 25 26 #include "sbuslib.h" ··· 184 185 struct ffb_fbc { 186 /* Next vertex registers */ 187 + u32 xxx1[3]; 188 + u32 alpha; 189 + u32 red; 190 + u32 green; 191 + u32 blue; 192 + u32 depth; 193 + u32 y; 194 + u32 x; 195 + u32 xxx2[2]; 196 + u32 ryf; 197 + u32 rxf; 198 + u32 xxx3[2]; 199 200 + u32 dmyf; 201 + u32 dmxf; 202 + u32 xxx4[2]; 203 + u32 ebyi; 204 + u32 ebxi; 205 + u32 xxx5[2]; 206 + u32 by; 207 + u32 bx; 208 + u32 dy; 209 + u32 dx; 210 + u32 bh; 211 + u32 bw; 212 + u32 xxx6[2]; 213 214 + u32 xxx7[32]; 215 216 /* Setup unit vertex state register */ 217 + u32 suvtx; 218 + u32 xxx8[63]; 219 220 /* Control registers */ 221 + u32 ppc; 222 + u32 wid; 223 + u32 fg; 224 + u32 bg; 225 + u32 consty; 226 + u32 constz; 227 + u32 xclip; 228 + u32 dcss; 229 + u32 vclipmin; 230 + u32 vclipmax; 231 + u32 vclipzmin; 232 + u32 vclipzmax; 233 + u32 dcsf; 234 + u32 dcsb; 235 + u32 dczf; 236 + u32 dczb; 237 238 + u32 xxx9; 239 + u32 blendc; 240 + u32 blendc1; 241 + u32 blendc2; 242 + u32 fbramitc; 243 + u32 fbc; 244 + u32 rop; 245 + u32 cmp; 246 + u32 matchab; 247 + u32 matchc; 248 + u32 magnab; 249 + u32 magnc; 250 + u32 fbcfg0; 251 + u32 fbcfg1; 252 + u32 fbcfg2; 253 + u32 fbcfg3; 254 255 + u32 ppcfg; 256 + u32 pick; 257 + u32 fillmode; 258 + u32 fbramwac; 259 + u32 pmask; 260 + u32 xpmask; 261 + u32 ypmask; 262 + u32 zpmask; 263 + u32 clip0min; 264 + u32 clip0max; 265 + u32 clip1min; 266 + u32 clip1max; 267 + u32 clip2min; 268 + u32 clip2max; 269 + u32 clip3min; 270 + u32 clip3max; 271 272 /* New 3dRAM III support regs */ 273 + u32 rawblend2; 274 + u32 rawpreblend; 275 + u32 rawstencil; 276 + u32 rawstencilctl; 277 + u32 threedram1; 278 + u32 threedram2; 279 + u32 passin; 280 + u32 rawclrdepth; 281 + u32 rawpmask; 282 + u32 rawcsrc; 283 + u32 rawmatch; 284 + u32 rawmagn; 285 + u32 rawropblend; 286 + u32 rawcmp; 287 + u32 rawwac; 288 + u32 fbramid; 289 290 + u32 drawop; 291 + u32 xxx10[2]; 292 + u32 fontlpat; 293 + u32 xxx11; 294 + u32 fontxy; 295 + u32 fontw; 296 + u32 fontinc; 297 + u32 font; 298 + u32 xxx12[3]; 299 + u32 blend2; 300 + u32 preblend; 301 + u32 stencil; 302 + u32 stencilctl; 303 304 + u32 xxx13[4]; 305 + u32 dcss1; 306 + u32 dcss2; 307 + u32 dcss3; 308 + u32 widpmask; 309 + u32 dcs2; 310 + u32 dcs3; 311 + u32 dcs4; 312 + u32 xxx14; 313 + u32 dcd2; 314 + u32 dcd3; 315 + u32 dcd4; 316 + u32 xxx15; 317 318 + u32 pattern[32]; 319 320 + u32 xxx16[256]; 321 322 + u32 devid; 323 + u32 xxx17[63]; 324 325 + u32 ucsr; 326 + u32 xxx18[31]; 327 328 + u32 mer; 329 }; 330 331 struct ffb_dac { 332 + u32 type; 333 + u32 value; 334 + u32 type2; 335 + u32 value2; 336 }; 337 338 struct ffb_par { 339 spinlock_t lock; 340 + struct ffb_fbc __iomem *fbc; 341 + struct ffb_dac __iomem *dac; 342 343 u32 flags; 344 #define FFB_FLAG_AFB 0x00000001 ··· 353 unsigned long physbase; 354 unsigned long fbsize; 355 356 int dac_rev; 357 int board_type; 358 }; 359 360 static void FFBFifo(struct ffb_par *par, int n) 361 { 362 + struct ffb_fbc __iomem *fbc; 363 int cache = par->fifo_cache; 364 365 if (cache - n < 0) { ··· 375 376 static void FFBWait(struct ffb_par *par) 377 { 378 + struct ffb_fbc __iomem *fbc; 379 int limit = 10000; 380 381 fbc = par->fbc; ··· 408 409 static void ffb_switch_from_graph(struct ffb_par *par) 410 { 411 + struct ffb_fbc __iomem *fbc = par->fbc; 412 + struct ffb_dac __iomem *dac = par->dac; 413 unsigned long flags; 414 415 spin_lock_irqsave(&par->lock, flags); ··· 462 static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 463 { 464 struct ffb_par *par = (struct ffb_par *) info->par; 465 + struct ffb_fbc __iomem *fbc = par->fbc; 466 unsigned long flags; 467 u32 fg; 468 ··· 505 ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 506 { 507 struct ffb_par *par = (struct ffb_par *) info->par; 508 + struct ffb_fbc __iomem *fbc = par->fbc; 509 unsigned long flags; 510 511 if (area->dx != area->sx || ··· 541 static void ffb_imageblit(struct fb_info *info, const struct fb_image *image) 542 { 543 struct ffb_par *par = (struct ffb_par *) info->par; 544 + struct ffb_fbc __iomem *fbc = par->fbc; 545 const u8 *data = image->data; 546 unsigned long flags; 547 u32 fg, bg, xy; ··· 664 ffb_blank(int blank, struct fb_info *info) 665 { 666 struct ffb_par *par = (struct ffb_par *) info->par; 667 + struct ffb_dac __iomem *dac = par->dac; 668 unsigned long flags; 669 u32 tmp; 670 ··· 883 info->fix.accel = FB_ACCEL_SUN_CREATOR; 884 } 885 886 struct all_info { 887 struct fb_info info; 888 struct ffb_par par; 889 u32 pseudo_palette[256]; 890 }; 891 892 + static int ffb_init_one(struct of_device *op) 893 { 894 + struct device_node *dp = op->node; 895 + struct ffb_fbc __iomem *fbc; 896 + struct ffb_dac __iomem *dac; 897 struct all_info *all; 898 + int err; 899 900 + all = kzalloc(sizeof(*all), GFP_KERNEL); 901 + if (!all) 902 + return -ENOMEM; 903 904 spin_lock_init(&all->par.lock); 905 + all->par.fbc = of_ioremap(&op->resource[2], 0, 906 + sizeof(struct ffb_fbc), "ffb fbc"); 907 + if (!all->par.fbc) { 908 + kfree(all); 909 + return -ENOMEM; 910 + } 911 + 912 + all->par.dac = of_ioremap(&op->resource[1], 0, 913 + sizeof(struct ffb_dac), "ffb dac"); 914 + if (!all->par.dac) { 915 + of_iounmap(all->par.fbc, sizeof(struct ffb_fbc)); 916 + kfree(all); 917 + return -ENOMEM; 918 + } 919 + 920 all->par.rop_cache = FFB_ROP_NEW; 921 + all->par.physbase = op->resource[0].start; 922 923 /* Don't mention copyarea, so SCROLL_REDRAW is always 924 * used. It is the fastest on this chip. ··· 968 all->info.par = &all->par; 969 all->info.pseudo_palette = all->pseudo_palette; 970 971 + sbusfb_fill_var(&all->info.var, dp->node, 32); 972 all->par.fbsize = PAGE_ALIGN(all->info.var.xres * 973 all->info.var.yres * 974 4); ··· 976 977 all->info.var.accel_flags = FB_ACCELF_TEXT; 978 979 + if (!strcmp(dp->name, "SUNW,afb")) 980 all->par.flags |= FFB_FLAG_AFB; 981 982 + all->par.board_type = of_getintprop_default(dp, "board_type", 0); 983 984 fbc = all->par.fbc; 985 + if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) 986 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr); 987 988 ffb_switch_from_graph(&all->par); ··· 1008 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 1009 printk(KERN_ERR "ffb: Could not allocate color map.\n"); 1010 kfree(all); 1011 + return -ENOMEM; 1012 } 1013 1014 ffb_init_fix(&all->info); 1015 1016 + err = register_framebuffer(&all->info); 1017 + if (err < 0) { 1018 printk(KERN_ERR "ffb: Could not register framebuffer.\n"); 1019 fb_dealloc_cmap(&all->info.cmap); 1020 kfree(all); 1021 + return err; 1022 } 1023 1024 + dev_set_drvdata(&op->dev, all); 1025 1026 + printk("%s: %s at %016lx, type %d, DAC revision %d\n", 1027 + dp->full_name, 1028 ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"), 1029 + all->par.physbase, all->par.board_type, all->par.dac_rev); 1030 + 1031 + return 0; 1032 } 1033 1034 + static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id *match) 1035 { 1036 + struct of_device *op = to_of_device(&dev->dev); 1037 1038 + return ffb_init_one(op); 1039 } 1040 + 1041 + static int __devexit ffb_remove(struct of_device *dev) 1042 + { 1043 + struct all_info *all = dev_get_drvdata(&dev->dev); 1044 + 1045 + unregister_framebuffer(&all->info); 1046 + fb_dealloc_cmap(&all->info.cmap); 1047 + 1048 + of_iounmap(all->par.fbc, sizeof(struct ffb_fbc)); 1049 + of_iounmap(all->par.dac, sizeof(struct ffb_dac)); 1050 + 1051 + kfree(all); 1052 + 1053 + dev_set_drvdata(&dev->dev, NULL); 1054 + 1055 + return 0; 1056 + } 1057 + 1058 + static struct of_device_id ffb_match[] = { 1059 + { 1060 + .name = "SUNW,ffb", 1061 + }, 1062 + { 1063 + .name = "SUNW,afb", 1064 + }, 1065 + {}, 1066 + }; 1067 + MODULE_DEVICE_TABLE(of, ffb_match); 1068 + 1069 + static struct of_platform_driver ffb_driver = { 1070 + .name = "ffb", 1071 + .match_table = ffb_match, 1072 + .probe = ffb_probe, 1073 + .remove = __devexit_p(ffb_remove), 1074 + }; 1075 1076 int __init ffb_init(void) 1077 { 1078 if (fb_get_options("ffb", NULL)) 1079 return -ENODEV; 1080 1081 + return of_register_driver(&ffb_driver, &of_bus_type); 1082 } 1083 1084 void __exit ffb_exit(void) 1085 { 1086 + of_unregister_driver(&ffb_driver); 1087 } 1088 1089 module_init(ffb_init); 1090 module_exit(ffb_exit); 1091 1092 MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets"); 1093 + MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 1094 + MODULE_VERSION("2.0"); 1095 MODULE_LICENSE("GPL");
+164 -138
drivers/video/leo.c
··· 1 /* leo.c: LEO frame buffer driver 2 * 3 - * Copyright (C) 2003 David S. Miller (davem@redhat.com) 4 * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz) 6 * ··· 18 #include <linux/mm.h> 19 20 #include <asm/io.h> 21 - #include <asm/sbus.h> 22 - #include <asm/oplib.h> 23 #include <asm/fbio.h> 24 25 #include "sbuslib.h" ··· 80 81 struct leo_cursor { 82 u8 xxx0[16]; 83 - volatile u32 cur_type; 84 - volatile u32 cur_misc; 85 - volatile u32 cur_cursxy; 86 - volatile u32 cur_data; 87 }; 88 89 #define LEO_KRN_TYPE_CLUT0 0x00001000 ··· 99 #define LEO_KRN_CSR_UNK2 0x00000001 100 101 struct leo_lx_krn { 102 - volatile u32 krn_type; 103 - volatile u32 krn_csr; 104 - volatile u32 krn_value; 105 }; 106 107 struct leo_lc_ss0_krn { 108 - volatile u32 misc; 109 u8 xxx0[0x800-4]; 110 - volatile u32 rev; 111 }; 112 113 struct leo_lc_ss0_usr { 114 - volatile u32 csr; 115 - volatile u32 addrspace; 116 - volatile u32 fontmsk; 117 - volatile u32 fontt; 118 - volatile u32 extent; 119 - volatile u32 src; 120 u32 dst; 121 - volatile u32 copy; 122 - volatile u32 fill; 123 }; 124 125 struct leo_lc_ss1_krn { ··· 132 133 struct leo_ld { 134 u8 xxx0[0xe00]; 135 - volatile u32 csr; 136 - volatile u32 wid; 137 - volatile u32 wmask; 138 - volatile u32 widclip; 139 - volatile u32 vclipmin; 140 - volatile u32 vclipmax; 141 - volatile u32 pickmin; /* SS1 only */ 142 - volatile u32 pickmax; /* SS1 only */ 143 - volatile u32 fg; 144 - volatile u32 bg; 145 - volatile u32 src; /* Copy/Scroll (SS0 only) */ 146 - volatile u32 dst; /* Copy/Scroll/Fill (SS0 only) */ 147 - volatile u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ 148 u32 xxx1[3]; 149 - volatile u32 setsem; /* SS1 only */ 150 - volatile u32 clrsem; /* SS1 only */ 151 - volatile u32 clrpick; /* SS1 only */ 152 - volatile u32 clrdat; /* SS1 only */ 153 - volatile u32 alpha; /* SS1 only */ 154 u8 xxx2[0x2c]; 155 - volatile u32 winbg; 156 - volatile u32 planemask; 157 - volatile u32 rop; 158 - volatile u32 z; 159 - volatile u32 dczf; /* SS1 only */ 160 - volatile u32 dczb; /* SS1 only */ 161 - volatile u32 dcs; /* SS1 only */ 162 - volatile u32 dczs; /* SS1 only */ 163 - volatile u32 pickfb; /* SS1 only */ 164 - volatile u32 pickbb; /* SS1 only */ 165 - volatile u32 dcfc; /* SS1 only */ 166 - volatile u32 forcecol; /* SS1 only */ 167 - volatile u32 door[8]; /* SS1 only */ 168 - volatile u32 pick[5]; /* SS1 only */ 169 }; 170 171 #define LEO_SS1_MISC_ENABLE 0x00000001 172 #define LEO_SS1_MISC_STEREO 0x00000002 173 struct leo_ld_ss1 { 174 - u8 xxx0[0xef4]; 175 - volatile u32 ss1_misc; 176 }; 177 178 struct leo_ld_gbl { ··· 193 #define LEO_FLAG_BLANKED 0x00000001 194 195 unsigned long physbase; 196 unsigned long fbsize; 197 - 198 - struct sbus_dev *sdev; 199 }; 200 201 static void leo_wait(struct leo_lx_krn __iomem *lx_krn) ··· 367 368 return sbusfb_mmap_helper(leo_mmap_map, 369 par->physbase, par->fbsize, 370 - par->sdev->reg_addrs[0].which_io, 371 - vma); 372 } 373 374 static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) ··· 383 */ 384 385 static void 386 - leo_init_fix(struct fb_info *info) 387 { 388 - struct leo_par *par = (struct leo_par *)info->par; 389 - 390 - strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id)); 391 392 info->fix.type = FB_TYPE_PACKED_PIXELS; 393 info->fix.visual = FB_VISUAL_TRUECOLOR; ··· 528 struct all_info { 529 struct fb_info info; 530 struct leo_par par; 531 - struct list_head list; 532 }; 533 - static LIST_HEAD(leo_list); 534 535 - static void leo_init_one(struct sbus_dev *sdev) 536 { 537 struct all_info *all; 538 - int linebytes; 539 540 - all = kmalloc(sizeof(*all), GFP_KERNEL); 541 - if (!all) { 542 - printk(KERN_ERR "leo: Cannot allocate memory.\n"); 543 - return; 544 - } 545 - memset(all, 0, sizeof(*all)); 546 - 547 - INIT_LIST_HEAD(&all->list); 548 549 spin_lock_init(&all->par.lock); 550 - all->par.sdev = sdev; 551 552 - all->par.physbase = sdev->reg_addrs[0].phys_addr; 553 554 - sbusfb_fill_var(&all->info.var, sdev->prom_node, 32); 555 leo_fixup_var_rgb(&all->info.var); 556 557 - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 558 - all->info.var.xres); 559 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 560 561 - #ifdef CONFIG_SPARC32 562 - all->info.screen_base = (char __iomem *) 563 - prom_getintdefault(sdev->prom_node, "address", 0); 564 - #endif 565 - if (!all->info.screen_base) 566 - all->info.screen_base = 567 - sbus_ioremap(&sdev->resource[0], LEO_OFF_SS0, 568 - 0x800000, "leo ram"); 569 - 570 all->par.lc_ss0_usr = 571 - sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR, 572 - 0x1000, "leolc ss0usr"); 573 all->par.ld_ss0 = 574 - sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0, 575 - 0x1000, "leold ss0"); 576 all->par.ld_ss1 = 577 - sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1, 578 - 0x1000, "leold ss1"); 579 all->par.lx_krn = 580 - sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN, 581 - 0x1000, "leolx krn"); 582 all->par.cursor = 583 - sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR, 584 - sizeof(struct leo_cursor), "leolx cursor"); 585 586 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 587 all->info.fbops = &leo_ops; ··· 607 leo_blank(0, &all->info); 608 609 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 610 - printk(KERN_ERR "leo: Could not allocate color map.\n"); 611 kfree(all); 612 - return; 613 } 614 615 - leo_init_fix(&all->info); 616 617 - if (register_framebuffer(&all->info) < 0) { 618 - printk(KERN_ERR "leo: Could not register framebuffer.\n"); 619 fb_dealloc_cmap(&all->info.cmap); 620 kfree(all); 621 - return; 622 } 623 624 - list_add(&all->list, &leo_list); 625 626 - printk("leo: %s at %lx:%lx\n", 627 - sdev->prom_name, 628 - (long) sdev->reg_addrs[0].which_io, 629 - (long) sdev->reg_addrs[0].phys_addr); 630 } 631 632 - int __init leo_init(void) 633 { 634 - struct sbus_bus *sbus; 635 - struct sbus_dev *sdev; 636 637 if (fb_get_options("leofb", NULL)) 638 return -ENODEV; 639 640 - for_all_sbusdev(sdev, sbus) { 641 - if (!strcmp(sdev->prom_name, "leo")) 642 - leo_init_one(sdev); 643 - } 644 - 645 - return 0; 646 } 647 648 - void __exit leo_exit(void) 649 { 650 - struct list_head *pos, *tmp; 651 - 652 - list_for_each_safe(pos, tmp, &leo_list) { 653 - struct all_info *all = list_entry(pos, typeof(*all), list); 654 - 655 - unregister_framebuffer(&all->info); 656 - fb_dealloc_cmap(&all->info.cmap); 657 - kfree(all); 658 - } 659 - } 660 - 661 - int __init 662 - leo_setup(char *arg) 663 - { 664 - /* No cmdline options yet... */ 665 - return 0; 666 } 667 668 module_init(leo_init); 669 - #ifdef MODULE 670 module_exit(leo_exit); 671 - #endif 672 673 MODULE_DESCRIPTION("framebuffer driver for LEO chipsets"); 674 - MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 675 MODULE_LICENSE("GPL");
··· 1 /* leo.c: LEO frame buffer driver 2 * 3 + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) 4 * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz) 6 * ··· 18 #include <linux/mm.h> 19 20 #include <asm/io.h> 21 + #include <asm/prom.h> 22 + #include <asm/of_device.h> 23 #include <asm/fbio.h> 24 25 #include "sbuslib.h" ··· 80 81 struct leo_cursor { 82 u8 xxx0[16]; 83 + u32 cur_type; 84 + u32 cur_misc; 85 + u32 cur_cursxy; 86 + u32 cur_data; 87 }; 88 89 #define LEO_KRN_TYPE_CLUT0 0x00001000 ··· 99 #define LEO_KRN_CSR_UNK2 0x00000001 100 101 struct leo_lx_krn { 102 + u32 krn_type; 103 + u32 krn_csr; 104 + u32 krn_value; 105 }; 106 107 struct leo_lc_ss0_krn { 108 + u32 misc; 109 u8 xxx0[0x800-4]; 110 + u32 rev; 111 }; 112 113 struct leo_lc_ss0_usr { 114 + u32 csr; 115 + u32 addrspace; 116 + u32 fontmsk; 117 + u32 fontt; 118 + u32 extent; 119 + u32 src; 120 u32 dst; 121 + u32 copy; 122 + u32 fill; 123 }; 124 125 struct leo_lc_ss1_krn { ··· 132 133 struct leo_ld { 134 u8 xxx0[0xe00]; 135 + u32 csr; 136 + u32 wid; 137 + u32 wmask; 138 + u32 widclip; 139 + u32 vclipmin; 140 + u32 vclipmax; 141 + u32 pickmin; /* SS1 only */ 142 + u32 pickmax; /* SS1 only */ 143 + u32 fg; 144 + u32 bg; 145 + u32 src; /* Copy/Scroll (SS0 only) */ 146 + u32 dst; /* Copy/Scroll/Fill (SS0 only) */ 147 + u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ 148 u32 xxx1[3]; 149 + u32 setsem; /* SS1 only */ 150 + u32 clrsem; /* SS1 only */ 151 + u32 clrpick; /* SS1 only */ 152 + u32 clrdat; /* SS1 only */ 153 + u32 alpha; /* SS1 only */ 154 u8 xxx2[0x2c]; 155 + u32 winbg; 156 + u32 planemask; 157 + u32 rop; 158 + u32 z; 159 + u32 dczf; /* SS1 only */ 160 + u32 dczb; /* SS1 only */ 161 + u32 dcs; /* SS1 only */ 162 + u32 dczs; /* SS1 only */ 163 + u32 pickfb; /* SS1 only */ 164 + u32 pickbb; /* SS1 only */ 165 + u32 dcfc; /* SS1 only */ 166 + u32 forcecol; /* SS1 only */ 167 + u32 door[8]; /* SS1 only */ 168 + u32 pick[5]; /* SS1 only */ 169 }; 170 171 #define LEO_SS1_MISC_ENABLE 0x00000001 172 #define LEO_SS1_MISC_STEREO 0x00000002 173 struct leo_ld_ss1 { 174 + u8 xxx0[0xef4]; 175 + u32 ss1_misc; 176 }; 177 178 struct leo_ld_gbl { ··· 193 #define LEO_FLAG_BLANKED 0x00000001 194 195 unsigned long physbase; 196 + unsigned long which_io; 197 unsigned long fbsize; 198 }; 199 200 static void leo_wait(struct leo_lx_krn __iomem *lx_krn) ··· 368 369 return sbusfb_mmap_helper(leo_mmap_map, 370 par->physbase, par->fbsize, 371 + par->which_io, vma); 372 } 373 374 static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) ··· 385 */ 386 387 static void 388 + leo_init_fix(struct fb_info *info, struct device_node *dp) 389 { 390 + strlcpy(info->fix.id, dp->name, sizeof(info->fix.id)); 391 392 info->fix.type = FB_TYPE_PACKED_PIXELS; 393 info->fix.visual = FB_VISUAL_TRUECOLOR; ··· 532 struct all_info { 533 struct fb_info info; 534 struct leo_par par; 535 }; 536 537 + static void leo_unmap_regs(struct all_info *all) 538 { 539 + if (all->par.lc_ss0_usr) 540 + of_iounmap(all->par.lc_ss0_usr, 0x1000); 541 + if (all->par.ld_ss0) 542 + of_iounmap(all->par.ld_ss0, 0x1000); 543 + if (all->par.ld_ss1) 544 + of_iounmap(all->par.ld_ss1, 0x1000); 545 + if (all->par.lx_krn) 546 + of_iounmap(all->par.lx_krn, 0x1000); 547 + if (all->par.cursor) 548 + of_iounmap(all->par.cursor, sizeof(struct leo_cursor)); 549 + if (all->info.screen_base) 550 + of_iounmap(all->info.screen_base, 0x800000); 551 + } 552 + 553 + static int __devinit leo_init_one(struct of_device *op) 554 + { 555 + struct device_node *dp = op->node; 556 struct all_info *all; 557 + int linebytes, err; 558 559 + all = kzalloc(sizeof(*all), GFP_KERNEL); 560 + if (!all) 561 + return -ENOMEM; 562 563 spin_lock_init(&all->par.lock); 564 565 + all->par.physbase = op->resource[0].start; 566 + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; 567 568 + sbusfb_fill_var(&all->info.var, dp->node, 32); 569 leo_fixup_var_rgb(&all->info.var); 570 571 + linebytes = of_getintprop_default(dp, "linebytes", 572 + all->info.var.xres); 573 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 574 575 all->par.lc_ss0_usr = 576 + of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR, 577 + 0x1000, "leolc ss0usr"); 578 all->par.ld_ss0 = 579 + of_ioremap(&op->resource[0], LEO_OFF_LD_SS0, 580 + 0x1000, "leold ss0"); 581 all->par.ld_ss1 = 582 + of_ioremap(&op->resource[0], LEO_OFF_LD_SS1, 583 + 0x1000, "leold ss1"); 584 all->par.lx_krn = 585 + of_ioremap(&op->resource[0], LEO_OFF_LX_KRN, 586 + 0x1000, "leolx krn"); 587 all->par.cursor = 588 + of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR, 589 + sizeof(struct leo_cursor), "leolx cursor"); 590 + all->info.screen_base = 591 + of_ioremap(&op->resource[0], LEO_OFF_SS0, 592 + 0x800000, "leo ram"); 593 + if (!all->par.lc_ss0_usr || 594 + !all->par.ld_ss0 || 595 + !all->par.ld_ss1 || 596 + !all->par.lx_krn || 597 + !all->par.cursor || 598 + !all->info.screen_base) { 599 + leo_unmap_regs(all); 600 + kfree(all); 601 + return -ENOMEM; 602 + } 603 604 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 605 all->info.fbops = &leo_ops; ··· 597 leo_blank(0, &all->info); 598 599 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 600 + leo_unmap_regs(all); 601 kfree(all); 602 + return -ENOMEM;; 603 } 604 605 + leo_init_fix(&all->info, dp); 606 607 + err = register_framebuffer(&all->info); 608 + if (err < 0) { 609 fb_dealloc_cmap(&all->info.cmap); 610 + leo_unmap_regs(all); 611 kfree(all); 612 + return err; 613 } 614 615 + dev_set_drvdata(&op->dev, all); 616 617 + printk("%s: leo at %lx:%lx\n", 618 + dp->full_name, 619 + all->par.which_io, all->par.physbase); 620 + 621 + return 0; 622 } 623 624 + static int __devinit leo_probe(struct of_device *dev, const struct of_device_id *match) 625 { 626 + struct of_device *op = to_of_device(&dev->dev); 627 628 + return leo_init_one(op); 629 + } 630 + 631 + static int __devexit leo_remove(struct of_device *dev) 632 + { 633 + struct all_info *all = dev_get_drvdata(&dev->dev); 634 + 635 + unregister_framebuffer(&all->info); 636 + fb_dealloc_cmap(&all->info.cmap); 637 + 638 + leo_unmap_regs(all); 639 + 640 + kfree(all); 641 + 642 + dev_set_drvdata(&dev->dev, NULL); 643 + 644 + return 0; 645 + } 646 + 647 + static struct of_device_id leo_match[] = { 648 + { 649 + .name = "leo", 650 + }, 651 + {}, 652 + }; 653 + MODULE_DEVICE_TABLE(of, leo_match); 654 + 655 + static struct of_platform_driver leo_driver = { 656 + .name = "leo", 657 + .match_table = leo_match, 658 + .probe = leo_probe, 659 + .remove = __devexit_p(leo_remove), 660 + }; 661 + 662 + static int __init leo_init(void) 663 + { 664 if (fb_get_options("leofb", NULL)) 665 return -ENODEV; 666 667 + return of_register_driver(&leo_driver, &of_bus_type); 668 } 669 670 + static void __exit leo_exit(void) 671 { 672 + of_unregister_driver(&leo_driver); 673 } 674 675 module_init(leo_init); 676 module_exit(leo_exit); 677 678 MODULE_DESCRIPTION("framebuffer driver for LEO chipsets"); 679 + MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 680 + MODULE_VERSION("2.0"); 681 MODULE_LICENSE("GPL");
+135 -124
drivers/video/p9100.c
··· 1 /* p9100.c: P9100 frame buffer driver 2 * 3 - * Copyright (C) 2003 David S. Miller (davem@redhat.com) 4 * Copyright 1999 Derrick J Brashear (shadow@dementia.org) 5 * 6 * Driver layout based loosely on tgafb.c, see that file for credits. ··· 17 #include <linux/mm.h> 18 19 #include <asm/io.h> 20 - #include <asm/sbus.h> 21 - #include <asm/oplib.h> 22 #include <asm/fbio.h> 23 24 #include "sbuslib.h" ··· 72 73 struct p9100_regs { 74 /* Registers for the system control */ 75 - volatile u32 sys_base; 76 - volatile u32 sys_config; 77 - volatile u32 sys_intr; 78 - volatile u32 sys_int_ena; 79 - volatile u32 sys_alt_rd; 80 - volatile u32 sys_alt_wr; 81 - volatile u32 sys_xxx[58]; 82 83 /* Registers for the video control */ 84 - volatile u32 vid_base; 85 - volatile u32 vid_hcnt; 86 - volatile u32 vid_htotal; 87 - volatile u32 vid_hsync_rise; 88 - volatile u32 vid_hblank_rise; 89 - volatile u32 vid_hblank_fall; 90 - volatile u32 vid_hcnt_preload; 91 - volatile u32 vid_vcnt; 92 - volatile u32 vid_vlen; 93 - volatile u32 vid_vsync_rise; 94 - volatile u32 vid_vblank_rise; 95 - volatile u32 vid_vblank_fall; 96 - volatile u32 vid_vcnt_preload; 97 - volatile u32 vid_screenpaint_addr; 98 - volatile u32 vid_screenpaint_timectl1; 99 - volatile u32 vid_screenpaint_qsfcnt; 100 - volatile u32 vid_screenpaint_timectl2; 101 - volatile u32 vid_xxx[15]; 102 103 /* Registers for the video control */ 104 - volatile u32 vram_base; 105 - volatile u32 vram_memcfg; 106 - volatile u32 vram_refresh_pd; 107 - volatile u32 vram_refresh_cnt; 108 - volatile u32 vram_raslo_max; 109 - volatile u32 vram_raslo_cur; 110 - volatile u32 pwrup_cfg; 111 - volatile u32 vram_xxx[25]; 112 113 /* Registers for IBM RGB528 Palette */ 114 - volatile u32 ramdac_cmap_wridx; 115 - volatile u32 ramdac_palette_data; 116 - volatile u32 ramdac_pixel_mask; 117 - volatile u32 ramdac_palette_rdaddr; 118 - volatile u32 ramdac_idx_lo; 119 - volatile u32 ramdac_idx_hi; 120 - volatile u32 ramdac_idx_data; 121 - volatile u32 ramdac_idx_ctl; 122 - volatile u32 ramdac_xxx[1784]; 123 }; 124 125 struct p9100_cmd_parameng { 126 - volatile u32 parameng_status; 127 - volatile u32 parameng_bltcmd; 128 - volatile u32 parameng_quadcmd; 129 }; 130 131 struct p9100_par { ··· 136 #define P9100_FLAG_BLANKED 0x00000001 137 138 unsigned long physbase; 139 unsigned long fbsize; 140 - 141 - struct sbus_dev *sdev; 142 }; 143 144 /** ··· 226 227 return sbusfb_mmap_helper(p9100_mmap_map, 228 par->physbase, par->fbsize, 229 - par->sdev->reg_addrs[0].which_io, 230 - vma); 231 } 232 233 static int p9100_ioctl(struct fb_info *info, unsigned int cmd, ··· 243 * Initialisation 244 */ 245 246 - static void 247 - p9100_init_fix(struct fb_info *info, int linebytes) 248 { 249 - struct p9100_par *par = (struct p9100_par *)info->par; 250 - 251 - strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id)); 252 253 info->fix.type = FB_TYPE_PACKED_PIXELS; 254 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ··· 258 struct all_info { 259 struct fb_info info; 260 struct p9100_par par; 261 - struct list_head list; 262 }; 263 - static LIST_HEAD(p9100_list); 264 265 - static void p9100_init_one(struct sbus_dev *sdev) 266 { 267 struct all_info *all; 268 - int linebytes; 269 270 - all = kmalloc(sizeof(*all), GFP_KERNEL); 271 - if (!all) { 272 - printk(KERN_ERR "p9100: Cannot allocate memory.\n"); 273 - return; 274 - } 275 - memset(all, 0, sizeof(*all)); 276 - 277 - INIT_LIST_HEAD(&all->list); 278 279 spin_lock_init(&all->par.lock); 280 - all->par.sdev = sdev; 281 282 /* This is the framebuffer and the only resource apps can mmap. */ 283 - all->par.physbase = sdev->reg_addrs[2].phys_addr; 284 285 - sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); 286 all->info.var.red.length = 8; 287 all->info.var.green.length = 8; 288 all->info.var.blue.length = 8; 289 290 - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 291 - all->info.var.xres); 292 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 293 294 - all->par.regs = sbus_ioremap(&sdev->resource[0], 0, 295 - sizeof(struct p9100_regs), "p9100 regs"); 296 297 all->info.flags = FBINFO_DEFAULT; 298 all->info.fbops = &p9100_ops; 299 - #ifdef CONFIG_SPARC32 300 - all->info.screen_base = (char __iomem *) 301 - prom_getintdefault(sdev->prom_node, "address", 0); 302 - #endif 303 - if (!all->info.screen_base) 304 - all->info.screen_base = sbus_ioremap(&sdev->resource[2], 0, 305 - all->par.fbsize, "p9100 ram"); 306 all->info.par = &all->par; 307 308 p9100_blank(0, &all->info); 309 310 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 311 - printk(KERN_ERR "p9100: Could not allocate color map.\n"); 312 kfree(all); 313 - return; 314 } 315 316 - p9100_init_fix(&all->info, linebytes); 317 318 - if (register_framebuffer(&all->info) < 0) { 319 - printk(KERN_ERR "p9100: Could not register framebuffer.\n"); 320 fb_dealloc_cmap(&all->info.cmap); 321 kfree(all); 322 - return; 323 } 324 fb_set_cmap(&all->info.cmap, &all->info); 325 326 - list_add(&all->list, &p9100_list); 327 328 - printk("p9100: %s at %lx:%lx\n", 329 - sdev->prom_name, 330 - (long) sdev->reg_addrs[0].which_io, 331 - (long) sdev->reg_addrs[0].phys_addr); 332 } 333 334 - int __init p9100_init(void) 335 { 336 - struct sbus_bus *sbus; 337 - struct sbus_dev *sdev; 338 339 if (fb_get_options("p9100fb", NULL)) 340 return -ENODEV; 341 342 - for_all_sbusdev(sdev, sbus) { 343 - if (!strcmp(sdev->prom_name, "p9100")) 344 - p9100_init_one(sdev); 345 - } 346 - 347 - return 0; 348 } 349 350 - void __exit p9100_exit(void) 351 { 352 - struct list_head *pos, *tmp; 353 - 354 - list_for_each_safe(pos, tmp, &p9100_list) { 355 - struct all_info *all = list_entry(pos, typeof(*all), list); 356 - 357 - unregister_framebuffer(&all->info); 358 - fb_dealloc_cmap(&all->info.cmap); 359 - kfree(all); 360 - } 361 - } 362 - 363 - int __init 364 - p9100_setup(char *arg) 365 - { 366 - /* No cmdline options yet... */ 367 - return 0; 368 } 369 370 module_init(p9100_init); 371 - 372 - #ifdef MODULE 373 module_exit(p9100_exit); 374 - #endif 375 376 MODULE_DESCRIPTION("framebuffer driver for P9100 chipsets"); 377 - MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 378 MODULE_LICENSE("GPL");
··· 1 /* p9100.c: P9100 frame buffer driver 2 * 3 + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) 4 * Copyright 1999 Derrick J Brashear (shadow@dementia.org) 5 * 6 * Driver layout based loosely on tgafb.c, see that file for credits. ··· 17 #include <linux/mm.h> 18 19 #include <asm/io.h> 20 + #include <asm/prom.h> 21 + #include <asm/of_device.h> 22 #include <asm/fbio.h> 23 24 #include "sbuslib.h" ··· 72 73 struct p9100_regs { 74 /* Registers for the system control */ 75 + u32 sys_base; 76 + u32 sys_config; 77 + u32 sys_intr; 78 + u32 sys_int_ena; 79 + u32 sys_alt_rd; 80 + u32 sys_alt_wr; 81 + u32 sys_xxx[58]; 82 83 /* Registers for the video control */ 84 + u32 vid_base; 85 + u32 vid_hcnt; 86 + u32 vid_htotal; 87 + u32 vid_hsync_rise; 88 + u32 vid_hblank_rise; 89 + u32 vid_hblank_fall; 90 + u32 vid_hcnt_preload; 91 + u32 vid_vcnt; 92 + u32 vid_vlen; 93 + u32 vid_vsync_rise; 94 + u32 vid_vblank_rise; 95 + u32 vid_vblank_fall; 96 + u32 vid_vcnt_preload; 97 + u32 vid_screenpaint_addr; 98 + u32 vid_screenpaint_timectl1; 99 + u32 vid_screenpaint_qsfcnt; 100 + u32 vid_screenpaint_timectl2; 101 + u32 vid_xxx[15]; 102 103 /* Registers for the video control */ 104 + u32 vram_base; 105 + u32 vram_memcfg; 106 + u32 vram_refresh_pd; 107 + u32 vram_refresh_cnt; 108 + u32 vram_raslo_max; 109 + u32 vram_raslo_cur; 110 + u32 pwrup_cfg; 111 + u32 vram_xxx[25]; 112 113 /* Registers for IBM RGB528 Palette */ 114 + u32 ramdac_cmap_wridx; 115 + u32 ramdac_palette_data; 116 + u32 ramdac_pixel_mask; 117 + u32 ramdac_palette_rdaddr; 118 + u32 ramdac_idx_lo; 119 + u32 ramdac_idx_hi; 120 + u32 ramdac_idx_data; 121 + u32 ramdac_idx_ctl; 122 + u32 ramdac_xxx[1784]; 123 }; 124 125 struct p9100_cmd_parameng { 126 + u32 parameng_status; 127 + u32 parameng_bltcmd; 128 + u32 parameng_quadcmd; 129 }; 130 131 struct p9100_par { ··· 136 #define P9100_FLAG_BLANKED 0x00000001 137 138 unsigned long physbase; 139 + unsigned long which_io; 140 unsigned long fbsize; 141 }; 142 143 /** ··· 227 228 return sbusfb_mmap_helper(p9100_mmap_map, 229 par->physbase, par->fbsize, 230 + par->which_io, vma); 231 } 232 233 static int p9100_ioctl(struct fb_info *info, unsigned int cmd, ··· 245 * Initialisation 246 */ 247 248 + static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_node *dp) 249 { 250 + strlcpy(info->fix.id, dp->name, sizeof(info->fix.id)); 251 252 info->fix.type = FB_TYPE_PACKED_PIXELS; 253 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ··· 263 struct all_info { 264 struct fb_info info; 265 struct p9100_par par; 266 }; 267 268 + static int __devinit p9100_init_one(struct of_device *op) 269 { 270 + struct device_node *dp = op->node; 271 struct all_info *all; 272 + int linebytes, err; 273 274 + all = kzalloc(sizeof(*all), GFP_KERNEL); 275 + if (!all) 276 + return -ENOMEM; 277 278 spin_lock_init(&all->par.lock); 279 280 /* This is the framebuffer and the only resource apps can mmap. */ 281 + all->par.physbase = op->resource[2].start; 282 + all->par.which_io = op->resource[2].flags & IORESOURCE_BITS; 283 284 + sbusfb_fill_var(&all->info.var, dp->node, 8); 285 all->info.var.red.length = 8; 286 all->info.var.green.length = 8; 287 all->info.var.blue.length = 8; 288 289 + linebytes = of_getintprop_default(dp, "linebytes", 290 + all->info.var.xres); 291 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 292 293 + all->par.regs = of_ioremap(&op->resource[0], 0, 294 + sizeof(struct p9100_regs), "p9100 regs"); 295 + if (!all->par.regs) { 296 + kfree(all); 297 + return -ENOMEM; 298 + } 299 300 all->info.flags = FBINFO_DEFAULT; 301 all->info.fbops = &p9100_ops; 302 + all->info.screen_base = of_ioremap(&op->resource[2], 0, 303 + all->par.fbsize, "p9100 ram"); 304 + if (!all->info.screen_base) { 305 + of_iounmap(all->par.regs, sizeof(struct p9100_regs)); 306 + kfree(all); 307 + return -ENOMEM; 308 + } 309 all->info.par = &all->par; 310 311 p9100_blank(0, &all->info); 312 313 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 314 + of_iounmap(all->par.regs, sizeof(struct p9100_regs)); 315 + of_iounmap(all->info.screen_base, all->par.fbsize); 316 kfree(all); 317 + return -ENOMEM; 318 } 319 320 + p9100_init_fix(&all->info, linebytes, dp); 321 322 + err = register_framebuffer(&all->info); 323 + if (err < 0) { 324 fb_dealloc_cmap(&all->info.cmap); 325 + of_iounmap(all->par.regs, sizeof(struct p9100_regs)); 326 + of_iounmap(all->info.screen_base, all->par.fbsize); 327 kfree(all); 328 + return err; 329 } 330 fb_set_cmap(&all->info.cmap, &all->info); 331 332 + dev_set_drvdata(&op->dev, all); 333 334 + printk("%s: p9100 at %lx:%lx\n", 335 + dp->full_name, 336 + all->par.which_io, all->par.physbase); 337 + 338 + return 0; 339 } 340 341 + static int __devinit p9100_probe(struct of_device *dev, const struct of_device_id *match) 342 { 343 + struct of_device *op = to_of_device(&dev->dev); 344 345 + return p9100_init_one(op); 346 + } 347 + 348 + static int __devexit p9100_remove(struct of_device *dev) 349 + { 350 + struct all_info *all = dev_get_drvdata(&dev->dev); 351 + 352 + unregister_framebuffer(&all->info); 353 + fb_dealloc_cmap(&all->info.cmap); 354 + 355 + of_iounmap(all->par.regs, sizeof(struct p9100_regs)); 356 + of_iounmap(all->info.screen_base, all->par.fbsize); 357 + 358 + kfree(all); 359 + 360 + dev_set_drvdata(&dev->dev, NULL); 361 + 362 + return 0; 363 + } 364 + 365 + static struct of_device_id p9100_match[] = { 366 + { 367 + .name = "p9100", 368 + }, 369 + {}, 370 + }; 371 + MODULE_DEVICE_TABLE(of, p9100_match); 372 + 373 + static struct of_platform_driver p9100_driver = { 374 + .name = "p9100", 375 + .match_table = p9100_match, 376 + .probe = p9100_probe, 377 + .remove = __devexit_p(p9100_remove), 378 + }; 379 + 380 + static int __init p9100_init(void) 381 + { 382 if (fb_get_options("p9100fb", NULL)) 383 return -ENODEV; 384 385 + return of_register_driver(&p9100_driver, &of_bus_type); 386 } 387 388 + static void __exit p9100_exit(void) 389 { 390 + of_unregister_driver(&p9100_driver); 391 } 392 393 module_init(p9100_init); 394 module_exit(p9100_exit); 395 396 MODULE_DESCRIPTION("framebuffer driver for P9100 chipsets"); 397 + MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 398 + MODULE_VERSION("2.0"); 399 MODULE_LICENSE("GPL");
+131 -99
drivers/video/tcx.c
··· 1 /* tcx.c: TCX frame buffer driver 2 * 3 - * Copyright (C) 2003 David S. Miller (davem@redhat.com) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) ··· 19 #include <linux/mm.h> 20 21 #include <asm/io.h> 22 - #include <asm/sbus.h> 23 - #include <asm/oplib.h> 24 #include <asm/fbio.h> 25 26 #include "sbuslib.h" ··· 77 78 /* The contents are unknown */ 79 struct tcx_tec { 80 - volatile u32 tec_matrix; 81 - volatile u32 tec_clip; 82 - volatile u32 tec_vdc; 83 }; 84 85 struct tcx_thc { 86 - volatile u32 thc_rev; 87 u32 thc_pad0[511]; 88 - volatile u32 thc_hs; /* hsync timing */ 89 - volatile u32 thc_hsdvs; 90 - volatile u32 thc_hd; 91 - volatile u32 thc_vs; /* vsync timing */ 92 - volatile u32 thc_vd; 93 - volatile u32 thc_refresh; 94 - volatile u32 thc_misc; 95 u32 thc_pad1[56]; 96 - volatile u32 thc_cursxy; /* cursor x,y position (16 bits each) */ 97 - volatile u32 thc_cursmask[32]; /* cursor mask bits */ 98 - volatile u32 thc_cursbits[32]; /* what to show where mask enabled */ 99 }; 100 101 struct bt_regs { 102 - volatile u32 addr; 103 - volatile u32 color_map; 104 - volatile u32 control; 105 - volatile u32 cursor; 106 }; 107 108 #define TCX_MMAP_ENTRIES 14 ··· 112 struct bt_regs __iomem *bt; 113 struct tcx_thc __iomem *thc; 114 struct tcx_tec __iomem *tec; 115 - volatile u32 __iomem *cplane; 116 117 u32 flags; 118 #define TCX_FLAG_BLANKED 0x00000001 119 120 unsigned long physbase; 121 unsigned long fbsize; 122 123 struct sbus_mmap_map mmap_map[TCX_MMAP_ENTRIES]; 124 int lowdepth; 125 - 126 - struct sbus_dev *sdev; 127 }; 128 129 /* Reset control plane so that WID is 8-bit plane. */ 130 static void __tcx_set_control_plane (struct tcx_par *par) 131 { 132 - volatile u32 __iomem *p, *pend; 133 134 if (par->lowdepth) 135 return; ··· 306 307 return sbusfb_mmap_helper(par->mmap_map, 308 par->physbase, par->fbsize, 309 - par->sdev->reg_addrs[0].which_io, 310 - vma); 311 } 312 313 static int tcx_ioctl(struct fb_info *info, unsigned int cmd, ··· 348 struct all_info { 349 struct fb_info info; 350 struct tcx_par par; 351 - struct list_head list; 352 }; 353 - static LIST_HEAD(tcx_list); 354 355 - static void tcx_init_one(struct sbus_dev *sdev) 356 { 357 struct all_info *all; 358 - int linebytes, i; 359 360 - all = kmalloc(sizeof(*all), GFP_KERNEL); 361 - if (!all) { 362 - printk(KERN_ERR "tcx: Cannot allocate memory.\n"); 363 - return; 364 - } 365 - memset(all, 0, sizeof(*all)); 366 - 367 - INIT_LIST_HEAD(&all->list); 368 369 spin_lock_init(&all->par.lock); 370 - all->par.sdev = sdev; 371 372 - all->par.lowdepth = prom_getbool(sdev->prom_node, "tcx-8-bit"); 373 374 - sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); 375 all->info.var.red.length = 8; 376 all->info.var.green.length = 8; 377 all->info.var.blue.length = 8; 378 379 - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 380 - all->info.var.xres); 381 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 382 383 - all->par.tec = sbus_ioremap(&sdev->resource[7], 0, 384 - sizeof(struct tcx_tec), "tcx tec"); 385 - all->par.thc = sbus_ioremap(&sdev->resource[9], 0, 386 - sizeof(struct tcx_thc), "tcx thc"); 387 - all->par.bt = sbus_ioremap(&sdev->resource[8], 0, 388 - sizeof(struct bt_regs), "tcx dac"); 389 memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map)); 390 if (!all->par.lowdepth) { 391 - all->par.cplane = sbus_ioremap(&sdev->resource[4], 0, 392 - all->par.fbsize * sizeof(u32), "tcx cplane"); 393 } else { 394 all->par.mmap_map[1].size = SBUS_MMAP_EMPTY; 395 all->par.mmap_map[4].size = SBUS_MMAP_EMPTY; ··· 421 } 422 423 all->par.physbase = 0; 424 for (i = 0; i < TCX_MMAP_ENTRIES; i++) { 425 int j; 426 ··· 439 j = i; 440 break; 441 }; 442 - all->par.mmap_map[i].poff = sdev->reg_addrs[j].phys_addr; 443 } 444 445 all->info.flags = FBINFO_DEFAULT; 446 all->info.fbops = &tcx_ops; 447 - #ifdef CONFIG_SPARC32 448 - all->info.screen_base = (char __iomem *) 449 - prom_getintdefault(sdev->prom_node, "address", 0); 450 - #endif 451 - if (!all->info.screen_base) 452 - all->info.screen_base = sbus_ioremap(&sdev->resource[0], 0, 453 - all->par.fbsize, "tcx ram"); 454 all->info.par = &all->par; 455 456 /* Initialize brooktree DAC. */ ··· 461 tcx_blank(FB_BLANK_UNBLANK, &all->info); 462 463 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 464 - printk(KERN_ERR "tcx: Could not allocate color map.\n"); 465 kfree(all); 466 - return; 467 } 468 469 fb_set_cmap(&all->info.cmap, &all->info); 470 tcx_init_fix(&all->info, linebytes); 471 472 - if (register_framebuffer(&all->info) < 0) { 473 - printk(KERN_ERR "tcx: Could not register framebuffer.\n"); 474 fb_dealloc_cmap(&all->info.cmap); 475 kfree(all); 476 - return; 477 } 478 479 - list_add(&all->list, &tcx_list); 480 481 - printk("tcx: %s at %lx:%lx, %s\n", 482 - sdev->prom_name, 483 - (long) sdev->reg_addrs[0].which_io, 484 - (long) sdev->reg_addrs[0].phys_addr, 485 all->par.lowdepth ? "8-bit only" : "24-bit depth"); 486 } 487 488 int __init tcx_init(void) 489 { 490 - struct sbus_bus *sbus; 491 - struct sbus_dev *sdev; 492 - 493 if (fb_get_options("tcxfb", NULL)) 494 return -ENODEV; 495 496 - for_all_sbusdev(sdev, sbus) { 497 - if (!strcmp(sdev->prom_name, "SUNW,tcx")) 498 - tcx_init_one(sdev); 499 - } 500 - 501 - return 0; 502 } 503 504 void __exit tcx_exit(void) 505 { 506 - struct list_head *pos, *tmp; 507 - 508 - list_for_each_safe(pos, tmp, &tcx_list) { 509 - struct all_info *all = list_entry(pos, typeof(*all), list); 510 - 511 - unregister_framebuffer(&all->info); 512 - fb_dealloc_cmap(&all->info.cmap); 513 - kfree(all); 514 - } 515 - } 516 - 517 - int __init 518 - tcx_setup(char *arg) 519 - { 520 - /* No cmdline options yet... */ 521 - return 0; 522 } 523 524 module_init(tcx_init); 525 - 526 - #ifdef MODULE 527 module_exit(tcx_exit); 528 - #endif 529 530 MODULE_DESCRIPTION("framebuffer driver for TCX chipsets"); 531 - MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 532 MODULE_LICENSE("GPL");
··· 1 /* tcx.c: TCX frame buffer driver 2 * 3 + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) ··· 19 #include <linux/mm.h> 20 21 #include <asm/io.h> 22 + #include <asm/prom.h> 23 + #include <asm/of_device.h> 24 #include <asm/fbio.h> 25 26 #include "sbuslib.h" ··· 77 78 /* The contents are unknown */ 79 struct tcx_tec { 80 + u32 tec_matrix; 81 + u32 tec_clip; 82 + u32 tec_vdc; 83 }; 84 85 struct tcx_thc { 86 + u32 thc_rev; 87 u32 thc_pad0[511]; 88 + u32 thc_hs; /* hsync timing */ 89 + u32 thc_hsdvs; 90 + u32 thc_hd; 91 + u32 thc_vs; /* vsync timing */ 92 + u32 thc_vd; 93 + u32 thc_refresh; 94 + u32 thc_misc; 95 u32 thc_pad1[56]; 96 + u32 thc_cursxy; /* cursor x,y position (16 bits each) */ 97 + u32 thc_cursmask[32]; /* cursor mask bits */ 98 + u32 thc_cursbits[32]; /* what to show where mask enabled */ 99 }; 100 101 struct bt_regs { 102 + u32 addr; 103 + u32 color_map; 104 + u32 control; 105 + u32 cursor; 106 }; 107 108 #define TCX_MMAP_ENTRIES 14 ··· 112 struct bt_regs __iomem *bt; 113 struct tcx_thc __iomem *thc; 114 struct tcx_tec __iomem *tec; 115 + u32 __iomem *cplane; 116 117 u32 flags; 118 #define TCX_FLAG_BLANKED 0x00000001 119 120 unsigned long physbase; 121 + unsigned long which_io; 122 unsigned long fbsize; 123 124 struct sbus_mmap_map mmap_map[TCX_MMAP_ENTRIES]; 125 int lowdepth; 126 }; 127 128 /* Reset control plane so that WID is 8-bit plane. */ 129 static void __tcx_set_control_plane (struct tcx_par *par) 130 { 131 + u32 __iomem *p, *pend; 132 133 if (par->lowdepth) 134 return; ··· 307 308 return sbusfb_mmap_helper(par->mmap_map, 309 par->physbase, par->fbsize, 310 + par->which_io, vma); 311 } 312 313 static int tcx_ioctl(struct fb_info *info, unsigned int cmd, ··· 350 struct all_info { 351 struct fb_info info; 352 struct tcx_par par; 353 }; 354 355 + static void tcx_unmap_regs(struct all_info *all) 356 { 357 + if (all->par.tec) 358 + of_iounmap(all->par.tec, sizeof(struct tcx_tec)); 359 + if (all->par.thc) 360 + of_iounmap(all->par.thc, sizeof(struct tcx_thc)); 361 + if (all->par.bt) 362 + of_iounmap(all->par.bt, sizeof(struct bt_regs)); 363 + if (all->par.cplane) 364 + of_iounmap(all->par.cplane, all->par.fbsize * sizeof(u32)); 365 + if (all->info.screen_base) 366 + of_iounmap(all->info.screen_base, all->par.fbsize); 367 + } 368 + 369 + static int __devinit tcx_init_one(struct of_device *op) 370 + { 371 + struct device_node *dp = op->node; 372 struct all_info *all; 373 + int linebytes, i, err; 374 375 + all = kzalloc(sizeof(*all), GFP_KERNEL); 376 + if (!all) 377 + return -ENOMEM; 378 379 spin_lock_init(&all->par.lock); 380 381 + all->par.lowdepth = 382 + (of_find_property(dp, "tcx-8-bit", NULL) != NULL); 383 384 + sbusfb_fill_var(&all->info.var, dp->node, 8); 385 all->info.var.red.length = 8; 386 all->info.var.green.length = 8; 387 all->info.var.blue.length = 8; 388 389 + linebytes = of_getintprop_default(dp, "linebytes", 390 + all->info.var.xres); 391 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 392 393 + all->par.tec = of_ioremap(&op->resource[7], 0, 394 + sizeof(struct tcx_tec), "tcx tec"); 395 + all->par.thc = of_ioremap(&op->resource[9], 0, 396 + sizeof(struct tcx_thc), "tcx thc"); 397 + all->par.bt = of_ioremap(&op->resource[8], 0, 398 + sizeof(struct bt_regs), "tcx dac"); 399 + all->info.screen_base = of_ioremap(&op->resource[0], 0, 400 + all->par.fbsize, "tcx ram"); 401 + if (!all->par.tec || !all->par.thc || 402 + !all->par.bt || !all->info.screen_base) { 403 + tcx_unmap_regs(all); 404 + kfree(all); 405 + return -ENOMEM; 406 + } 407 + 408 memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map)); 409 if (!all->par.lowdepth) { 410 + all->par.cplane = of_ioremap(&op->resource[4], 0, 411 + all->par.fbsize * sizeof(u32), 412 + "tcx cplane"); 413 + if (!all->par.cplane) { 414 + tcx_unmap_regs(all); 415 + kfree(all); 416 + return -ENOMEM; 417 + } 418 } else { 419 all->par.mmap_map[1].size = SBUS_MMAP_EMPTY; 420 all->par.mmap_map[4].size = SBUS_MMAP_EMPTY; ··· 400 } 401 402 all->par.physbase = 0; 403 + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; 404 + 405 for (i = 0; i < TCX_MMAP_ENTRIES; i++) { 406 int j; 407 ··· 416 j = i; 417 break; 418 }; 419 + all->par.mmap_map[i].poff = op->resource[j].start; 420 } 421 422 all->info.flags = FBINFO_DEFAULT; 423 all->info.fbops = &tcx_ops; 424 all->info.par = &all->par; 425 426 /* Initialize brooktree DAC. */ ··· 445 tcx_blank(FB_BLANK_UNBLANK, &all->info); 446 447 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 448 + tcx_unmap_regs(all); 449 kfree(all); 450 + return -ENOMEM; 451 } 452 453 fb_set_cmap(&all->info.cmap, &all->info); 454 tcx_init_fix(&all->info, linebytes); 455 456 + err = register_framebuffer(&all->info); 457 + if (err < 0) { 458 fb_dealloc_cmap(&all->info.cmap); 459 + tcx_unmap_regs(all); 460 kfree(all); 461 + return err; 462 } 463 464 + dev_set_drvdata(&op->dev, all); 465 466 + printk("%s: TCX at %lx:%lx, %s\n", 467 + dp->full_name, 468 + all->par.which_io, 469 + op->resource[0].start, 470 all->par.lowdepth ? "8-bit only" : "24-bit depth"); 471 + 472 + return 0; 473 } 474 + 475 + static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match) 476 + { 477 + struct of_device *op = to_of_device(&dev->dev); 478 + 479 + return tcx_init_one(op); 480 + } 481 + 482 + static int __devexit tcx_remove(struct of_device *dev) 483 + { 484 + struct all_info *all = dev_get_drvdata(&dev->dev); 485 + 486 + unregister_framebuffer(&all->info); 487 + fb_dealloc_cmap(&all->info.cmap); 488 + 489 + tcx_unmap_regs(all); 490 + 491 + kfree(all); 492 + 493 + dev_set_drvdata(&dev->dev, NULL); 494 + 495 + return 0; 496 + } 497 + 498 + static struct of_device_id tcx_match[] = { 499 + { 500 + .name = "SUNW,tcx", 501 + }, 502 + {}, 503 + }; 504 + MODULE_DEVICE_TABLE(of, tcx_match); 505 + 506 + static struct of_platform_driver tcx_driver = { 507 + .name = "tcx", 508 + .match_table = tcx_match, 509 + .probe = tcx_probe, 510 + .remove = __devexit_p(tcx_remove), 511 + }; 512 513 int __init tcx_init(void) 514 { 515 if (fb_get_options("tcxfb", NULL)) 516 return -ENODEV; 517 518 + return of_register_driver(&tcx_driver, &of_bus_type); 519 } 520 521 void __exit tcx_exit(void) 522 { 523 + of_unregister_driver(&tcx_driver); 524 } 525 526 module_init(tcx_init); 527 module_exit(tcx_exit); 528 529 MODULE_DESCRIPTION("framebuffer driver for TCX chipsets"); 530 + MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 531 + MODULE_VERSION("2.0"); 532 MODULE_LICENSE("GPL");