GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / video / igafb.c
blob6d9b99fd0b2e9816fcb879679b9efbe33a0bd641
1 /*
2 * linux/drivers/video/igafb.c -- Frame buffer device for IGA 1682
4 * Copyright (C) 1998 Vladimir Roganov and Gleb Raiko
6 * This driver is partly based on the Frame buffer device for ATI Mach64
7 * and partially on VESA-related code.
9 * Copyright (C) 1997-1998 Geert Uytterhoeven
10 * Copyright (C) 1998 Bernd Harries
11 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
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.
18 /******************************************************************************
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.
26 Most important thing at this moment is that we have working
27 JavaEngine1 console & X with new console interface.
29 ******************************************************************************/
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>
45 #include <asm/io.h>
47 #ifdef CONFIG_SPARC
48 #include <asm/prom.h>
49 #include <asm/pcic.h>
50 #endif
52 #include <video/iga.h>
54 struct 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;
62 struct iga_par {
63 struct pci_mmap_map *mmap_map;
64 unsigned long frame_buffer_phys;
65 unsigned long io_base;
68 struct fb_info fb_info;
70 struct fb_fix_screeninfo igafb_fix __initdata = {
71 .id = "IGA 1682",
72 .type = FB_TYPE_PACKED_PIXELS,
73 .mmio_len = 1000
76 struct 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
99 #ifdef CONFIG_SPARC
100 struct 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
123 struct 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
146 struct 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
170 * Memory-mapped I/O functions for Sparc PCI
172 * On sparc we happen to access I/O with memory mapped functions too.
174 #define pci_inb(par, reg) readb(par->io_base+(reg))
175 #define pci_outb(par, val, reg) writeb(val, par->io_base+(reg))
177 static inline unsigned int iga_inb(struct iga_par *par, unsigned int reg,
178 unsigned int idx)
180 pci_outb(par, idx, reg);
181 return pci_inb(par, reg + 1);
184 static inline void iga_outb(struct iga_par *par, unsigned char val,
185 unsigned int reg, unsigned int idx )
187 pci_outb(par, idx, reg);
188 pci_outb(par, val, reg+1);
191 #endif /* CONFIG_SPARC */
194 * Very important functionality for the JavaEngine1 computer:
195 * make screen border black (usign special IGA registers)
197 static void iga_blank_border(struct iga_par *par)
199 int i;
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.
205 for (i=0; i < 3; i++)
206 iga_outb(par, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
209 #ifdef CONFIG_SPARC
210 static int igafb_mmap(struct fb_info *info,
211 struct vm_area_struct *vma)
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;
218 if (!par->mmap_map)
219 return -ENXIO;
221 size = vma->vm_end - vma->vm_start;
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;
231 if (start > offset)
232 continue;
233 if (offset >= end)
234 continue;
236 map_size = par->mmap_map[i].size - (offset - start);
237 map_offset = par->mmap_map[i].poff + (offset - start);
238 break;
240 if (!map_size) {
241 page += PAGE_SIZE;
242 continue;
244 if (page + map_size > size)
245 map_size = size - page;
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;
250 if (remap_pfn_range(vma, vma->vm_start + page,
251 map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
252 return -EAGAIN;
254 page += map_size;
257 if (!map_size)
258 return -EINVAL;
260 vma->vm_flags |= VM_IO;
261 return 0;
263 #endif /* CONFIG_SPARC */
265 static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green,
266 unsigned blue, unsigned transp,
267 struct fb_info *info)
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.
275 struct iga_par *par = (struct iga_par *)info->par;
277 if (regno >= info->cmap.len)
278 return 1;
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);
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;
300 break;
303 return 0;
307 * Framebuffer option structure
309 static 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
320 static int __init iga_init(struct fb_info *info, struct iga_par *par)
322 char vramsz = iga_inb(par, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL)
323 & MEM_SIZE_ALIAS;
324 int video_cmap_len;
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;
339 if (info->var.bits_per_pixel > 8)
340 video_cmap_len = 16;
341 else
342 video_cmap_len = 256;
344 info->fbops = &igafb_ops;
345 info->flags = FBINFO_DEFAULT;
347 fb_alloc_cmap(&info->cmap, video_cmap_len, 0);
349 if (register_framebuffer(info) < 0)
350 return 0;
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);
356 iga_blank_border(par);
357 return 1;
360 static int __init igafb_init(void)
362 struct fb_info *info;
363 struct pci_dev *pdev;
364 struct iga_par *par;
365 unsigned long addr;
366 int size, iga2000 = 0;
368 if (fb_get_options("igafb", NULL))
369 return -ENODEV;
371 pdev = pci_get_device(PCI_VENDOR_ID_INTERG,
372 PCI_DEVICE_ID_INTERG_1682, 0);
373 if (pdev == NULL) {
374 pdev = pci_get_device(PCI_VENDOR_ID_INTERG, 0x2000, 0);
375 if(pdev == NULL) {
376 return -ENXIO;
378 iga2000 = 1;
380 /* We leak a reference here but as it cannot be unloaded this is
381 fine. If you write unload code remember to free it in unload */
383 size = sizeof(struct iga_par) + sizeof(u32)*16;
385 info = framebuffer_alloc(size, &pdev->dev);
386 if (!info) {
387 printk("igafb_init: can't alloc fb_info\n");
388 pci_dev_put(pdev);
389 return -ENOMEM;
392 par = info->par;
394 if ((addr = pdev->resource[0].start) == 0) {
395 printk("igafb_init: no memory start\n");
396 kfree(info);
397 pci_dev_put(pdev);
398 return -ENXIO;
401 if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) {
402 printk("igafb_init: can't remap %lx[2M]\n", addr);
403 kfree(info);
404 pci_dev_put(pdev);
405 return -ENXIO;
408 par->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
410 #ifdef CONFIG_SPARC
412 * The following is sparc specific and this is why:
414 * IGS2000 has its I/O memory mapped and we want
415 * to generate memory cycles on PCI, e.g. do ioremap(),
416 * then readb/writeb() as in Documentation/IO-mapping.txt.
418 * IGS1682 is more traditional, it responds to PCI I/O
419 * cycles, so we want to access it with inb()/outb().
421 * On sparc, PCIC converts CPU memory access within
422 * phys window 0x3000xxxx into PCI I/O cycles. Therefore
423 * we may use readb/writeb to access them with IGS1682.
425 * We do not take io_base_phys from resource[n].start
426 * on IGS1682 because that chip is BROKEN. It does not
427 * have a base register for I/O. We just "know" what its
428 * I/O addresses are.
430 if (iga2000) {
431 igafb_fix.mmio_start = par->frame_buffer_phys | 0x00800000;
432 } else {
433 igafb_fix.mmio_start = 0x30000000;
435 if ((par->io_base = (int) ioremap(igafb_fix.mmio_start, igafb_fix.smem_len)) == 0) {
436 printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start);
437 iounmap((void *)info->screen_base);
438 kfree(info);
439 pci_dev_put(pdev);
440 return -ENXIO;
444 * Figure mmap addresses from PCI config space.
445 * We need two regions: for video memory and for I/O ports.
446 * Later one can add region for video coprocessor registers.
447 * However, mmap routine loops until size != 0, so we put
448 * one additional region with size == 0.
451 par->mmap_map = kzalloc(4 * sizeof(*par->mmap_map), GFP_ATOMIC);
452 if (!par->mmap_map) {
453 printk("igafb_init: can't alloc mmap_map\n");
454 iounmap((void *)par->io_base);
455 iounmap(info->screen_base);
456 kfree(info);
457 pci_dev_put(pdev);
458 return -ENOMEM;
462 * Set default vmode and cmode from PROM properties.
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;
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;
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;
510 info->var = default_var;
511 info->fix = igafb_fix;
512 info->pseudo_palette = (void *)(par + 1);
514 if (!iga_init(info, par)) {
515 iounmap((void *)par->io_base);
516 iounmap(info->screen_base);
517 kfree(par->mmap_map);
518 kfree(info);
519 return -ENODEV;
522 #ifdef CONFIG_SPARC
524 * Add /dev/fb mmap values.
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;
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 */
542 return 0;
545 static int __init igafb_setup(char *options)
547 char *this_opt;
549 if (!options || !*options)
550 return 0;
552 while ((this_opt = strsep(&options, ",")) != NULL) {
554 return 0;
557 module_init(igafb_init);
558 MODULE_LICENSE("GPL");
559 static 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},
565 MODULE_DEVICE_TABLE(pci, igafb_pci_tbl);