cirrusfb.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,329 行 · 第 1/5 页
C
2,329 行
/* * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets * * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com> * * Contributors (thanks, all!) * * David Eger: * Overhaul for Linux 2.6 * * Jeff Rugen: * Major contributions; Motorola PowerStack (PPC and PCI) support, * GD54xx, 1280x1024 mode support, change MCLK based on VCLK. * * Geert Uytterhoeven: * Excellent code review. * * Lars Hecking: * Amiga updates and testing. * * Original cirrusfb author: Frank Neumann * * Based on retz3fb.c and cirrusfb.c: * Copyright (C) 1997 Jes Sorensen * Copyright (C) 1996 Frank Neumann * *************************************************************** * * Format this code with GNU indent '-kr -i8 -pcs' options. * * 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. * */#define CIRRUSFB_VERSION "2.0-pre2"#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/selection.h>#include <asm/pgtable.h>#ifdef CONFIG_ZORRO#include <linux/zorro.h>#endif#ifdef CONFIG_PCI#include <linux/pci.h>#endif#ifdef CONFIG_AMIGA#include <asm/amigahw.h>#endif#ifdef CONFIG_PPC_PREP#include <asm/processor.h>#define isPReP (_machine == _MACH_prep)#else#define isPReP 0#endif#include "video/vga.h"#include "video/cirrus.h"/***************************************************************** * * debugging and utility macros * *//* enable debug output? *//* #define CIRRUSFB_DEBUG 1 *//* disable runtime assertions? *//* #define CIRRUSFB_NDEBUG *//* debug output */#ifdef CIRRUSFB_DEBUG#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)#else#define DPRINTK(fmt, args...)#endif/* debugging assertions */#ifndef CIRRUSFB_NDEBUG#define assert(expr) \ if(!(expr)) { \ printk( "Assertion failed! %s,%s,%s,line=%d\n",\ #expr,__FILE__,__FUNCTION__,__LINE__); \ }#else#define assert(expr)#endif#ifdef TRUE#undef TRUE#endif#ifdef FALSE#undef FALSE#endif#define TRUE 1#define FALSE 0#define MB_ (1024*1024)#define KB_ (1024)#define MAX_NUM_BOARDS 7/***************************************************************** * * chipset information * *//* board types */typedef enum { BT_NONE = 0, BT_SD64, BT_PICCOLO, BT_PICASSO, BT_SPECTRUM, BT_PICASSO4, /* GD5446 */ BT_ALPINE, /* GD543x/4x */ BT_GD5480, BT_LAGUNA, /* GD546x */} cirrusfb_board_t;/* * per-board-type information, used for enumerating and abstracting * chip-specific information * NOTE: MUST be in the same order as cirrusfb_board_t in order to * use direct indexing on this array * NOTE: '__initdata' cannot be used as some of this info * is required at runtime. Maybe separate into an init-only and * a run-time table? */static const struct cirrusfb_board_info_rec { char *name; /* ASCII name of chipset */ long maxclock[5]; /* maximum video clock */ /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */ unsigned init_sr07 : 1; /* init SR07 during init_vgachip() */ unsigned init_sr1f : 1; /* write SR1F during init_vgachip() */ unsigned scrn_start_bit19 : 1; /* construct bit 19 of screen start address */ /* initial SR07 value, then for each mode */ unsigned char sr07; unsigned char sr07_1bpp; unsigned char sr07_1bpp_mux; unsigned char sr07_8bpp; unsigned char sr07_8bpp_mux; unsigned char sr1f; /* SR1F VGA initial register value */} cirrusfb_board_info[] = { [BT_SD64] = { .name = "CL SD64", .maxclock = { /* guess */ /* the SD64/P4 have a higher max. videoclock */ 140000, 140000, 140000, 140000, 140000, }, .init_sr07 = TRUE, .init_sr1f = TRUE, .scrn_start_bit19 = TRUE, .sr07 = 0xF0, .sr07_1bpp = 0xF0, .sr07_8bpp = 0xF1, .sr1f = 0x20 }, [BT_PICCOLO] = { .name = "CL Piccolo", .maxclock = { /* guess */ 90000, 90000, 90000, 90000, 90000 }, .init_sr07 = TRUE, .init_sr1f = TRUE, .scrn_start_bit19 = FALSE, .sr07 = 0x80, .sr07_1bpp = 0x80, .sr07_8bpp = 0x81, .sr1f = 0x22 }, [BT_PICASSO] = { .name = "CL Picasso", .maxclock = { /* guess */ 90000, 90000, 90000, 90000, 90000 }, .init_sr07 = TRUE, .init_sr1f = TRUE, .scrn_start_bit19 = FALSE, .sr07 = 0x20, .sr07_1bpp = 0x20, .sr07_8bpp = 0x21, .sr1f = 0x22 }, [BT_SPECTRUM] = { .name = "CL Spectrum", .maxclock = { /* guess */ 90000, 90000, 90000, 90000, 90000 }, .init_sr07 = TRUE, .init_sr1f = TRUE, .scrn_start_bit19 = FALSE, .sr07 = 0x80, .sr07_1bpp = 0x80, .sr07_8bpp = 0x81, .sr1f = 0x22 }, [BT_PICASSO4] = { .name = "CL Picasso4", .maxclock = { 135100, 135100, 85500, 85500, 0 }, .init_sr07 = TRUE, .init_sr1f = FALSE, .scrn_start_bit19 = TRUE, .sr07 = 0x20, .sr07_1bpp = 0x20, .sr07_8bpp = 0x21, .sr1f = 0 }, [BT_ALPINE] = { .name = "CL Alpine", .maxclock = { /* for the GD5430. GD5446 can do more... */ 85500, 85500, 50000, 28500, 0 }, .init_sr07 = TRUE, .init_sr1f = TRUE, .scrn_start_bit19 = TRUE, .sr07 = 0xA0, .sr07_1bpp = 0xA1, .sr07_1bpp_mux = 0xA7, .sr07_8bpp = 0xA1, .sr07_8bpp_mux = 0xA7, .sr1f = 0x1C }, [BT_GD5480] = { .name = "CL GD5480", .maxclock = { 135100, 200000, 200000, 135100, 135100 }, .init_sr07 = TRUE, .init_sr1f = TRUE, .scrn_start_bit19 = TRUE, .sr07 = 0x10, .sr07_1bpp = 0x11, .sr07_8bpp = 0x11, .sr1f = 0x1C }, [BT_LAGUNA] = { .name = "CL Laguna", .maxclock = { /* guess */ 135100, 135100, 135100, 135100, 135100, }, .init_sr07 = FALSE, .init_sr1f = FALSE, .scrn_start_bit19 = TRUE, }};#ifdef CONFIG_PCI#define CHIP(id, btype) \ { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_##id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }static struct pci_device_id cirrusfb_pci_table[] = { CHIP( CIRRUS_5436, BT_ALPINE ), CHIP( CIRRUS_5434_8, BT_ALPINE ), CHIP( CIRRUS_5434_4, BT_ALPINE ), CHIP( CIRRUS_5430, BT_ALPINE ), /* GD-5440 has identical id */ CHIP( CIRRUS_7543, BT_ALPINE ), CHIP( CIRRUS_7548, BT_ALPINE ), CHIP( CIRRUS_5480, BT_GD5480 ), /* MacPicasso probably */ CHIP( CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is a GD5446 */ CHIP( CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */ CHIP( CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */ CHIP( CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/ { 0, }};MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);#undef CHIP#endif /* CONFIG_PCI */#ifdef CONFIG_ZORROstatic const struct zorro_device_id cirrusfb_zorro_table[] = { { .id = ZORRO_PROD_HELFRICH_SD64_RAM, .driver_data = BT_SD64, }, { .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM, .driver_data = BT_PICCOLO, }, { .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, .driver_data = BT_PICASSO, }, { .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, .driver_data = BT_SPECTRUM, }, { .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3, .driver_data = BT_PICASSO4, }, { 0 }};static const struct { zorro_id id2; unsigned long size;} cirrusfb_zorro_table2[] = { [BT_SD64] = { .id2 = ZORRO_PROD_HELFRICH_SD64_REG, .size = 0x400000 }, [BT_PICCOLO] = { .id2 = ZORRO_PROD_HELFRICH_PICCOLO_REG, .size = 0x200000 }, [BT_PICASSO] = { .id2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG, .size = 0x200000 }, [BT_SPECTRUM] = { .id2 = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG, .size = 0x200000 }, [BT_PICASSO4] = { .id2 = 0, .size = 0x400000 }};#endif /* CONFIG_ZORRO */struct cirrusfb_regs { __u32 line_length; /* in BYTES! */ __u32 visual; __u32 type; long freq; long nom; long den; long div; long multiplexing; long mclk; long divMCLK; long HorizRes; /* The x resolution in pixel */ long HorizTotal; long HorizDispEnd; long HorizBlankStart; long HorizBlankEnd; long HorizSyncStart; long HorizSyncEnd; long VertRes; /* the physical y resolution in scanlines */ long VertTotal; long VertDispEnd; long VertSyncStart; long VertSyncEnd; long VertBlankStart; long VertBlankEnd;};#ifdef CIRRUSFB_DEBUGtypedef enum { CRT, SEQ} cirrusfb_dbg_reg_class_t;#endif /* CIRRUSFB_DEBUG *//* info about board */struct cirrusfb_info { struct fb_info *info; caddr_t fbmem; caddr_t regbase; caddr_t mem; unsigned long size; cirrusfb_board_t btype; unsigned char SFR; /* Shadow of special function register */ unsigned long fbmem_phys; unsigned long fbregs_phys; struct cirrusfb_regs currentmode; int blank_mode; u32 pseudo_palette[17]; struct { u8 red, green, blue, pad; } palette[256];#ifdef CONFIG_ZORRO struct zorro_dev *zdev;#endif#ifdef CONFIG_PCI struct pci_dev *pdev;#endif void (*unmap)(struct cirrusfb_info *cinfo);};static unsigned cirrusfb_def_mode = 1;static int noaccel = 0;/* * Predefined Video Modes */static const struct { const char *name; struct fb_var_screeninfo var;} cirrusfb_predefined[] = { { /* autodetect mode */ .name = "Autodetect", }, { /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */ .name = "640x480", .var = { .xres = 640, .yres = 480, .xres_virtual = 640, .yres_virtual = 480, .bits_per_pixel = 8, .red = { .length = 8 }, .green = { .length = 8 }, .blue = { .length = 8 }, .width = -1, .height = -1, .pixclock = 40000, .left_margin = 48, .right_margin = 16, .upper_margin = 32, .lower_margin = 8, .hsync_len = 96, .vsync_len = 4, .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, .vmode = FB_VMODE_NONINTERLACED } }, { /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */ .name = "800x600", .var = { .xres = 800, .yres = 600, .xres_virtual = 800, .yres_virtual = 600, .bits_per_pixel = 8,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?