📄 igafb.c
字号:
/* * linux/drivers/video/igafb.c -- Frame buffer device for IGA 1682 * * Copyright (C) 1998 Vladimir Roganov and Gleb Raiko * * This driver is partly based on the Frame buffer device for ATI Mach64 * and partially on VESA-related code. * * Copyright (C) 1997-1998 Geert Uytterhoeven * Copyright (C) 1998 Bernd Harries * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive for * more details. *//****************************************************************************** TODO: Despite of IGA Card has advanced graphic acceleration, initial version is almost dummy and does not support it. Support for video modes and acceleration must be added together with accelerated X-Windows driver implementation. Most important thing at this moment is that we have working JavaEngine1 console & X with new console interface.******************************************************************************/#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/nvram.h>#include <asm/io.h>#ifdef CONFIG_SPARC#include <asm/prom.h>#include <asm/pcic.h>#endif#include <video/iga.h>struct pci_mmap_map { unsigned long voff; unsigned long poff; unsigned long size; unsigned long prot_flag; unsigned long prot_mask;};struct iga_par { struct pci_mmap_map *mmap_map; unsigned long frame_buffer_phys; unsigned long io_base;};struct fb_info fb_info;struct fb_fix_screeninfo igafb_fix __initdata = { .id = "IGA 1682", .type = FB_TYPE_PACKED_PIXELS, .mmio_len = 1000};struct fb_var_screeninfo default_var = { /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ .xres = 640, .yres = 480, .xres_virtual = 640, .yres_virtual = 480, .bits_per_pixel = 8, .red = {0, 8, 0 }, .green = {0, 8, 0 }, .blue = {0, 8, 0 }, .height = -1, .width = -1, .accel_flags = FB_ACCEL_NONE, .pixclock = 39722, .left_margin = 48, .right_margin = 16, .upper_margin = 33, .lower_margin = 10, .hsync_len = 96, .vsync_len = 2, .vmode = FB_VMODE_NONINTERLACED};#ifdef CONFIG_SPARCstruct fb_var_screeninfo default_var_1024x768 __initdata = { /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */ .xres = 1024, .yres = 768, .xres_virtual = 1024, .yres_virtual = 768, .bits_per_pixel = 8, .red = {0, 8, 0 }, .green = {0, 8, 0 }, .blue = {0, 8, 0 }, .height = -1, .width = -1, .accel_flags = FB_ACCEL_NONE, .pixclock = 12699, .left_margin = 176, .right_margin = 16, .upper_margin = 28, .lower_margin = 1, .hsync_len = 96, .vsync_len = 3, .vmode = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED};struct fb_var_screeninfo default_var_1152x900 __initdata = { /* 1152x900, 76 Hz, Non-Interlaced (110.0 MHz dotclock) */ .xres = 1152, .yres = 900, .xres_virtual = 1152, .yres_virtual = 900, .bits_per_pixel = 8, .red = { 0, 8, 0 }, .green = { 0, 8, 0 }, .blue = { 0, 8, 0 }, .height = -1, .width = -1, .accel_flags = FB_ACCEL_NONE, .pixclock = 9091, .left_margin = 234, .right_margin = 24, .upper_margin = 34, .lower_margin = 3, .hsync_len = 100, .vsync_len = 3, .vmode = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED};struct fb_var_screeninfo default_var_1280x1024 __initdata = { /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */ .xres = 1280, .yres = 1024, .xres_virtual = 1280, .yres_virtual = 1024, .bits_per_pixel = 8, .red = {0, 8, 0 }, .green = {0, 8, 0 }, .blue = {0, 8, 0 }, .height = -1, .width = -1, .accel_flags = 0, .pixclock = 7408, .left_margin = 248, .right_margin = 16, .upper_margin = 38, .lower_margin = 1, .hsync_len = 144, .vsync_len = 3, .vmode = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED};/* * Memory-mapped I/O functions for Sparc PCI * * On sparc we happen to access I/O with memory mapped functions too. */ #define pci_inb(par, reg) readb(par->io_base+(reg))#define pci_outb(par, val, reg) writeb(val, par->io_base+(reg))static inline unsigned int iga_inb(struct iga_par *par, unsigned int reg, unsigned int idx){ pci_outb(par, idx, reg); return pci_inb(par, reg + 1);}static inline void iga_outb(struct iga_par *par, unsigned char val, unsigned int reg, unsigned int idx ){ pci_outb(par, idx, reg); pci_outb(par, val, reg+1);}#endif /* CONFIG_SPARC *//* * Very important functionality for the JavaEngine1 computer: * make screen border black (usign special IGA registers) */static void iga_blank_border(struct iga_par *par){ int i;#if 0 /* * PROM does this for us, so keep this code as a reminder * about required read from 0x3DA and writing of 0x20 in the end. */ (void) pci_inb(par, 0x3DA); /* required for every access */ pci_outb(par, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL); (void) pci_inb(par, IGA_ATTR_CTL+1); pci_outb(par, 0x38, IGA_ATTR_CTL); pci_outb(par, 0x20, IGA_ATTR_CTL); /* re-enable visual */#endif /* * This does not work as it was designed because the overscan * color is looked up in the palette. Therefore, under X11 * overscan changes color. */ for (i=0; i < 3; i++) iga_outb(par, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);}#ifdef CONFIG_SPARCstatic int igafb_mmap(struct fb_info *info, struct vm_area_struct *vma){ struct iga_par *par = (struct iga_par *)info->par; unsigned int size, page, map_size = 0; unsigned long map_offset = 0; int i; if (!par->mmap_map) return -ENXIO; size = vma->vm_end - vma->vm_start; /* Each page, see which map applies */ for (page = 0; page < size; ) { map_size = 0; for (i = 0; par->mmap_map[i].size; i++) { unsigned long start = par->mmap_map[i].voff; unsigned long end = start + par->mmap_map[i].size; unsigned long offset = (vma->vm_pgoff << PAGE_SHIFT) + page; if (start > offset) continue; if (offset >= end) continue; map_size = par->mmap_map[i].size - (offset - start); map_offset = par->mmap_map[i].poff + (offset - start); break; } if (!map_size) { page += PAGE_SIZE; continue; } if (page + map_size > size) map_size = size - page; pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask); pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag; if (remap_pfn_range(vma, vma->vm_start + page, map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot)) return -EAGAIN; page += map_size; } if (!map_size) return -EINVAL; vma->vm_flags |= VM_IO; return 0;}#endif /* CONFIG_SPARC */static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info){ /* * Set a single color register. The values supplied are * already rounded down to the hardware's capabilities * (according to the entries in the `var' structure). Return * != 0 for invalid regno. */ struct iga_par *par = (struct iga_par *)info->par; if (regno >= info->cmap.len) return 1; pci_outb(par, regno, DAC_W_INDEX);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -