1/* 2 * linux/drivers/video/igafb.c -- Frame buffer device for IGA 1682 3 * 4 * Copyright (C) 1998 Vladimir Roganov and Gleb Raiko 5 * 6 * This driver is partly based on the Frame buffer device for ATI Mach64 7 * and partially on VESA-related code. 8 * 9 * Copyright (C) 1997-1998 Geert Uytterhoeven 10 * Copyright (C) 1998 Bernd Harries 11 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) 12 * 13 * This file is subject to the terms and conditions of the GNU General Public 14 * License. See the file COPYING in the main directory of this archive for 15 * more details. 16 */ 17 18/****************************************************************************** 19 20 TODO: 21 Despite of IGA Card has advanced graphic acceleration, 22 initial version is almost dummy and does not support it. 23 Support for video modes and acceleration must be added 24 together with accelerated X-Windows driver implementation. 25 26 Most important thing at this moment is that we have working 27 JavaEngine1 console & X with new console interface. 28 29******************************************************************************/ 30 31#include <linux/module.h> 32#include <linux/kernel.h> 33#include <linux/errno.h> 34#include <linux/string.h> 35#include <linux/mm.h> 36#include <linux/slab.h> 37#include <linux/vmalloc.h> 38#include <linux/delay.h> 39#include <linux/interrupt.h> 40#include <linux/fb.h> 41#include <linux/init.h> 42#include <linux/pci.h> 43#include <linux/nvram.h> 44 45#include <asm/io.h> 46 47#ifdef CONFIG_SPARC 48#include <asm/prom.h> 49#include <asm/pcic.h> 50#endif 51 52#include <video/iga.h> 53 54struct pci_mmap_map { 55 unsigned long voff; 56 unsigned long poff; 57 unsigned long size; 58 unsigned long prot_flag; 59 unsigned long prot_mask; 60}; 61 62struct iga_par { 63 struct pci_mmap_map *mmap_map; 64 unsigned long frame_buffer_phys; 65 unsigned long io_base; 66}; 67 68struct fb_info fb_info; 69 70struct fb_fix_screeninfo igafb_fix __initdata = { 71 .id = "IGA 1682", 72 .type = FB_TYPE_PACKED_PIXELS, 73 .mmio_len = 1000 74}; 75 76struct fb_var_screeninfo default_var = { 77 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 78 .xres = 640, 79 .yres = 480, 80 .xres_virtual = 640, 81 .yres_virtual = 480, 82 .bits_per_pixel = 8, 83 .red = {0, 8, 0 }, 84 .green = {0, 8, 0 }, 85 .blue = {0, 8, 0 }, 86 .height = -1, 87 .width = -1, 88 .accel_flags = FB_ACCEL_NONE, 89 .pixclock = 39722, 90 .left_margin = 48, 91 .right_margin = 16, 92 .upper_margin = 33, 93 .lower_margin = 10, 94 .hsync_len = 96, 95 .vsync_len = 2, 96 .vmode = FB_VMODE_NONINTERLACED 97}; 98 99#ifdef CONFIG_SPARC 100struct fb_var_screeninfo default_var_1024x768 __initdata = { 101 /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */ 102 .xres = 1024, 103 .yres = 768, 104 .xres_virtual = 1024, 105 .yres_virtual = 768, 106 .bits_per_pixel = 8, 107 .red = {0, 8, 0 }, 108 .green = {0, 8, 0 }, 109 .blue = {0, 8, 0 }, 110 .height = -1, 111 .width = -1, 112 .accel_flags = FB_ACCEL_NONE, 113 .pixclock = 12699, 114 .left_margin = 176, 115 .right_margin = 16, 116 .upper_margin = 28, 117 .lower_margin = 1, 118 .hsync_len = 96, 119 .vsync_len = 3, 120 .vmode = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 121}; 122 123struct fb_var_screeninfo default_var_1152x900 __initdata = { 124 /* 1152x900, 76 Hz, Non-Interlaced (110.0 MHz dotclock) */ 125 .xres = 1152, 126 .yres = 900, 127 .xres_virtual = 1152, 128 .yres_virtual = 900, 129 .bits_per_pixel = 8, 130 .red = { 0, 8, 0 }, 131 .green = { 0, 8, 0 }, 132 .blue = { 0, 8, 0 }, 133 .height = -1, 134 .width = -1, 135 .accel_flags = FB_ACCEL_NONE, 136 .pixclock = 9091, 137 .left_margin = 234, 138 .right_margin = 24, 139 .upper_margin = 34, 140 .lower_margin = 3, 141 .hsync_len = 100, 142 .vsync_len = 3, 143 .vmode = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 144}; 145 146struct fb_var_screeninfo default_var_1280x1024 __initdata = { 147 /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */ 148 .xres = 1280, 149 .yres = 1024, 150 .xres_virtual = 1280, 151 .yres_virtual = 1024, 152 .bits_per_pixel = 8, 153 .red = {0, 8, 0 }, 154 .green = {0, 8, 0 }, 155 .blue = {0, 8, 0 }, 156 .height = -1, 157 .width = -1, 158 .accel_flags = 0, 159 .pixclock = 7408, 160 .left_margin = 248, 161 .right_margin = 16, 162 .upper_margin = 38, 163 .lower_margin = 1, 164 .hsync_len = 144, 165 .vsync_len = 3, 166 .vmode = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 167}; 168 169/* 170 * Memory-mapped I/O functions for Sparc PCI 171 * 172 * On sparc we happen to access I/O with memory mapped functions too. 173 */ 174#define pci_inb(par, reg) readb(par->io_base+(reg)) 175#define pci_outb(par, val, reg) writeb(val, par->io_base+(reg)) 176 177static inline unsigned int iga_inb(struct iga_par *par, unsigned int reg, 178 unsigned int idx) 179{ 180 pci_outb(par, idx, reg); 181 return pci_inb(par, reg + 1); 182} 183 184static inline void iga_outb(struct iga_par *par, unsigned char val, 185 unsigned int reg, unsigned int idx ) 186{ 187 pci_outb(par, idx, reg); 188 pci_outb(par, val, reg+1); 189} 190 191#endif /* CONFIG_SPARC */ 192 193/* 194 * Very important functionality for the JavaEngine1 computer: 195 * make screen border black (usign special IGA registers) 196 */ 197static void iga_blank_border(struct iga_par *par) 198{ 199 int i; 200 /* 201 * This does not work as it was designed because the overscan 202 * color is looked up in the palette. Therefore, under X11 203 * overscan changes color. 204 */ 205 for (i=0; i < 3; i++) 206 iga_outb(par, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i); 207} 208 209#ifdef CONFIG_SPARC 210static int igafb_mmap(struct fb_info *info, 211 struct vm_area_struct *vma) 212{ 213 struct iga_par *par = (struct iga_par *)info->par; 214 unsigned int size, page, map_size = 0; 215 unsigned long map_offset = 0; 216 int i; 217 218 if (!par->mmap_map) 219 return -ENXIO; 220 221 size = vma->vm_end - vma->vm_start; 222 223 /* Each page, see which map applies */ 224 for (page = 0; page < size; ) { 225 map_size = 0; 226 for (i = 0; par->mmap_map[i].size; i++) { 227 unsigned long start = par->mmap_map[i].voff; 228 unsigned long end = start + par->mmap_map[i].size; 229 unsigned long offset = (vma->vm_pgoff << PAGE_SHIFT) + page; 230 231 if (start > offset) 232 continue; 233 if (offset >= end) 234 continue; 235 236 map_size = par->mmap_map[i].size - (offset - start); 237 map_offset = par->mmap_map[i].poff + (offset - start); 238 break; 239 } 240 if (!map_size) { 241 page += PAGE_SIZE; 242 continue; 243 } 244 if (page + map_size > size) 245 map_size = size - page; 246 247 pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask); 248 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag; 249 250 if (remap_pfn_range(vma, vma->vm_start + page, 251 map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot)) 252 return -EAGAIN; 253 254 page += map_size; 255 } 256 257 if (!map_size) 258 return -EINVAL; 259 260 vma->vm_flags |= VM_IO; 261 return 0; 262} 263#endif /* CONFIG_SPARC */ 264 265static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green, 266 unsigned blue, unsigned transp, 267 struct fb_info *info) 268{ 269 /* 270 * Set a single color register. The values supplied are 271 * already rounded down to the hardware's capabilities 272 * (according to the entries in the `var' structure). Return 273 * != 0 for invalid regno. 274 */ 275 struct iga_par *par = (struct iga_par *)info->par; 276 277 if (regno >= info->cmap.len) 278 return 1; 279 280 pci_outb(par, regno, DAC_W_INDEX); 281 pci_outb(par, red, DAC_DATA); 282 pci_outb(par, green, DAC_DATA); 283 pci_outb(par, blue, DAC_DATA); 284 285 if (regno < 16) { 286 switch (info->var.bits_per_pixel) { 287 case 16: 288 ((u16*)(info->pseudo_palette))[regno] = 289 (regno << 10) | (regno << 5) | regno; 290 break; 291 case 24: 292 ((u32*)(info->pseudo_palette))[regno] = 293 (regno << 16) | (regno << 8) | regno; 294 break; 295 case 32: 296 { int i; 297 i = (regno << 8) | regno; 298 ((u32*)(info->pseudo_palette))[regno] = (i << 16) | i; 299 } 300 break; 301 } 302 } 303 return 0; 304} 305 306/* 307 * Framebuffer option structure 308 */ 309static struct fb_ops igafb_ops = { 310 .owner = THIS_MODULE, 311 .fb_setcolreg = igafb_setcolreg, 312 .fb_fillrect = cfb_fillrect, 313 .fb_copyarea = cfb_copyarea, 314 .fb_imageblit = cfb_imageblit, 315#ifdef CONFIG_SPARC 316 .fb_mmap = igafb_mmap, 317#endif 318}; 319 320static int __init iga_init(struct fb_info *info, struct iga_par *par) 321{ 322 char vramsz = iga_inb(par, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL) 323 & MEM_SIZE_ALIAS; 324 int video_cmap_len; 325 326 switch (vramsz) { 327 case MEM_SIZE_1M: 328 info->fix.smem_len = 0x100000; 329 break; 330 case MEM_SIZE_2M: 331 info->fix.smem_len = 0x200000; 332 break; 333 case MEM_SIZE_4M: 334 case MEM_SIZE_RESERVED: 335 info->fix.smem_len = 0x400000; 336 break; 337 } 338 339 if (info->var.bits_per_pixel > 8) 340 video_cmap_len = 16; 341 else 342 video_cmap_len = 256; 343 344 info->fbops = &igafb_ops; 345 info->flags = FBINFO_DEFAULT; 346 347 fb_alloc_cmap(&info->cmap, video_cmap_len, 0); 348 349 if (register_framebuffer(info) < 0) 350 return 0; 351 352 printk("fb%d: %s frame buffer device at 0x%08lx [%dMB VRAM]\n", 353 info->node, info->fix.id, 354 par->frame_buffer_phys, info->fix.smem_len >> 20); 355 356 iga_blank_border(par); 357 return 1; 358} 359 360int __init igafb_init(void) 361{ 362 struct fb_info *info; 363 struct pci_dev *pdev; 364 struct iga_par *par; 365 unsigned long addr; 366 int size, iga2000 = 0; 367 368 if (fb_get_options("igafb", NULL)) 369 return -ENODEV; 370 371 /* Do not attach when we have a serial console. */ 372 if (!con_is_present()) 373 return -ENXIO; 374 375 pdev = pci_get_device(PCI_VENDOR_ID_INTERG, 376 PCI_DEVICE_ID_INTERG_1682, 0); 377 if (pdev == NULL) { 378 pdev = pci_get_device(PCI_VENDOR_ID_INTERG, 0x2000, 0); 379 if(pdev == NULL) { 380 return -ENXIO; 381 } 382 iga2000 = 1; 383 } 384 /* We leak a reference here but as it cannot be unloaded this is 385 fine. If you write unload code remember to free it in unload */ 386 387 size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16; 388 389 info = kzalloc(size, GFP_ATOMIC); 390 if (!info) { 391 printk("igafb_init: can't alloc fb_info\n"); 392 return -ENOMEM; 393 } 394 395 par = (struct iga_par *) (info + 1); 396 397 398 if ((addr = pdev->resource[0].start) == 0) { 399 printk("igafb_init: no memory start\n"); 400 kfree(info); 401 return -ENXIO; 402 } 403 404 if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) { 405 printk("igafb_init: can't remap %lx[2M]\n", addr); 406 kfree(info); 407 return -ENXIO; 408 } 409 410 par->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK; 411 412#ifdef CONFIG_SPARC 413 /* 414 * The following is sparc specific and this is why: 415 * 416 * IGS2000 has its I/O memory mapped and we want 417 * to generate memory cycles on PCI, e.g. do ioremap(), 418 * then readb/writeb() as in Documentation/IO-mapping.txt. 419 * 420 * IGS1682 is more traditional, it responds to PCI I/O 421 * cycles, so we want to access it with inb()/outb(). 422 * 423 * On sparc, PCIC converts CPU memory access within 424 * phys window 0x3000xxxx into PCI I/O cycles. Therefore 425 * we may use readb/writeb to access them with IGS1682. 426 * 427 * We do not take io_base_phys from resource[n].start 428 * on IGS1682 because that chip is BROKEN. It does not 429 * have a base register for I/O. We just "know" what its 430 * I/O addresses are. 431 */ 432 if (iga2000) { 433 igafb_fix.mmio_start = par->frame_buffer_phys | 0x00800000; 434 } else { 435 igafb_fix.mmio_start = 0x30000000; 436 } 437 if ((par->io_base = (int) ioremap(igafb_fix.mmio_start, igafb_fix.smem_len)) == 0) { 438 printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start); 439 iounmap((void *)info->screen_base); 440 kfree(info); 441 return -ENXIO; 442 } 443 444 /* 445 * Figure mmap addresses from PCI config space. 446 * We need two regions: for video memory and for I/O ports. 447 * Later one can add region for video coprocessor registers. 448 * However, mmap routine loops until size != 0, so we put 449 * one additional region with size == 0. 450 */ 451 452 par->mmap_map = kzalloc(4 * sizeof(*par->mmap_map), GFP_ATOMIC); 453 if (!par->mmap_map) { 454 printk("igafb_init: can't alloc mmap_map\n"); 455 iounmap((void *)par->io_base); 456 iounmap(info->screen_base); 457 kfree(info); 458 return -ENOMEM; 459 } 460 461 /* 462 * Set default vmode and cmode from PROM properties. 463 */ 464 { 465 struct device_node *dp = pci_device_to_OF_node(pdev); 466 int node = dp->node; 467 int width = prom_getintdefault(node, "width", 1024); 468 int height = prom_getintdefault(node, "height", 768); 469 int depth = prom_getintdefault(node, "depth", 8); 470 switch (width) { 471 case 1024: 472 if (height == 768) 473 default_var = default_var_1024x768; 474 break; 475 case 1152: 476 if (height == 900) 477 default_var = default_var_1152x900; 478 break; 479 case 1280: 480 if (height == 1024) 481 default_var = default_var_1280x1024; 482 break; 483 default: 484 break; 485 } 486 487 switch (depth) { 488 case 8: 489 default_var.bits_per_pixel = 8; 490 break; 491 case 16: 492 default_var.bits_per_pixel = 16; 493 break; 494 case 24: 495 default_var.bits_per_pixel = 24; 496 break; 497 case 32: 498 default_var.bits_per_pixel = 32; 499 break; 500 default: 501 break; 502 } 503 } 504 505#endif 506 igafb_fix.smem_start = (unsigned long) info->screen_base; 507 igafb_fix.line_length = default_var.xres*(default_var.bits_per_pixel/8); 508 igafb_fix.visual = default_var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; 509 510 info->var = default_var; 511 info->fix = igafb_fix; 512 info->pseudo_palette = (void *)(par + 1); 513 info->device = &pdev->dev; 514 515 if (!iga_init(info, par)) { 516 iounmap((void *)par->io_base); 517 iounmap(info->screen_base); 518 kfree(par->mmap_map); 519 kfree(info); 520 } 521 522#ifdef CONFIG_SPARC 523 /* 524 * Add /dev/fb mmap values. 525 */ 526 527 /* First region is for video memory */ 528 par->mmap_map[0].voff = 0x0; 529 par->mmap_map[0].poff = par->frame_buffer_phys & PAGE_MASK; 530 par->mmap_map[0].size = info->fix.smem_len & PAGE_MASK; 531 par->mmap_map[0].prot_mask = SRMMU_CACHE; 532 par->mmap_map[0].prot_flag = SRMMU_WRITE; 533 534 /* Second region is for I/O ports */ 535 par->mmap_map[1].voff = par->frame_buffer_phys & PAGE_MASK; 536 par->mmap_map[1].poff = info->fix.smem_start & PAGE_MASK; 537 par->mmap_map[1].size = PAGE_SIZE * 2; /* X wants 2 pages */ 538 par->mmap_map[1].prot_mask = SRMMU_CACHE; 539 par->mmap_map[1].prot_flag = SRMMU_WRITE; 540#endif /* CONFIG_SPARC */ 541 542 return 0; 543} 544 545int __init igafb_setup(char *options) 546{ 547 char *this_opt; 548 549 if (!options || !*options) 550 return 0; 551 552 while ((this_opt = strsep(&options, ",")) != NULL) { 553 } 554 return 0; 555} 556 557module_init(igafb_init); 558MODULE_LICENSE("GPL"); 559static struct pci_device_id igafb_pci_tbl[] __devinitdata = { 560 { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682, 561 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 562 { } 563}; 564 565MODULE_DEVICE_TABLE(pci, igafb_pci_tbl); 566