📄 clgenfb.c
字号:
/* * drivers/video/clgenfb.c - driver for Cirrus Logic chipsets * * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com> * * Contributors (thanks, all!) * * 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. * * Cliff Matthews <ctm@ardi.com>: * 16bpp fix for CL-GD7548 (uses info from XFree86 4.2.0 source) * * Original clgenfb author: Frank Neumann * * Based on retz3fb.c and clgen.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 CLGEN_VERSION "1.9.9.1"#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_ALL_PPC#include <asm/processor.h>#define isPReP (_machine == _MACH_prep)#else#define isPReP 0#endif#include <video/fbcon.h>#include <video/fbcon-mfb.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include <video/fbcon-cfb24.h>#include <video/fbcon-cfb32.h>#include "clgenfb.h"#include "vga.h"/***************************************************************** * * debugging and utility macros * *//* enable debug output? *//* #define CLGEN_DEBUG 1 *//* disable runtime assertions? *//* #define CLGEN_NDEBUG *//* debug output */#ifdef CLGEN_DEBUG#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)#else#define DPRINTK(fmt, args...)#endif/* debugging assertions */#ifndef CLGEN_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 */} clgen_board_t;/* * per-board-type information, used for enumerating and abstracting * chip-specific information * NOTE: MUST be in the same order as clgen_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 clgen_board_info_rec { clgen_board_t btype; /* chipset enum, not strictly necessary, as * clgen_board_info[] is directly indexed * by this value */ char *name; /* ASCII name of chipset */ long maxclock; /* maximum video clock */ 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 */} clgen_board_info[] = { { BT_NONE, }, /* dummy record */ { BT_SD64, "CL SD64", 140000, /* the SD64/P4 have a higher max. videoclock */ TRUE, TRUE, TRUE, 0xF0, 0xF0, 0, /* unused, does not multiplex */ 0xF1, 0, /* unused, does not multiplex */ 0x20 }, { BT_PICCOLO, "CL Piccolo", 90000, TRUE, TRUE, FALSE, 0x80, 0x80, 0, /* unused, does not multiplex */ 0x81, 0, /* unused, does not multiplex */ 0x22 }, { BT_PICASSO, "CL Picasso", 90000, TRUE, TRUE, FALSE, 0x20, 0x20, 0, /* unused, does not multiplex */ 0x21, 0, /* unused, does not multiplex */ 0x22 }, { BT_SPECTRUM, "CL Spectrum", 90000, TRUE, TRUE, FALSE, 0x80, 0x80, 0, /* unused, does not multiplex */ 0x81, 0, /* unused, does not multiplex */ 0x22 }, { BT_PICASSO4, "CL Picasso4", 140000, /* the SD64/P4 have a higher max. videoclock */ TRUE, FALSE, TRUE, 0x20, 0x20, 0, /* unused, does not multiplex */ 0x21, 0, /* unused, does not multiplex */ 0 }, { BT_ALPINE, "CL Alpine", 110000, /* 135100 for some, 85500 for others */ TRUE, TRUE, TRUE, 0xA0, 0xA1, 0xA7, 0xA1, 0xA7, 0x1C }, { BT_GD5480, "CL GD5480", 90000, TRUE, TRUE, TRUE, 0x10, 0x11, 0, /* unused, does not multiplex */ 0x11, 0, /* unused, does not multiplex */ 0x1C }, { BT_LAGUNA, "CL Laguna", 135100, FALSE, FALSE, TRUE, 0, /* unused */ 0, /* unused */ 0, /* unused */ 0, /* unused */ 0, /* unused */ 0 }, /* unused */};#ifdef CONFIG_PCI/* the list of PCI devices for which we probe, and the * order in which we do it */static const struct { clgen_board_t btype; const char *nameOverride; /* XXX unused... for now */ unsigned short device;} clgen_pci_probe_list[] __initdata = { { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5436 }, { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_8 }, { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_4 }, { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5430 }, /* GD-5440 has identical id */ { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_7543 }, { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_7548 }, { BT_GD5480, NULL, PCI_DEVICE_ID_CIRRUS_5480 }, /* MacPicasso probably */ { BT_PICASSO4, NULL, PCI_DEVICE_ID_CIRRUS_5446 }, /* Picasso 4 is a GD5446 */ { BT_LAGUNA, "CL Laguna", PCI_DEVICE_ID_CIRRUS_5462 }, { BT_LAGUNA, "CL Laguna 3D", PCI_DEVICE_ID_CIRRUS_5464 }, { BT_LAGUNA, "CL Laguna 3DA", PCI_DEVICE_ID_CIRRUS_5465 },};#endif /* CONFIG_PCI */#ifdef CONFIG_ZORROstatic const struct { clgen_board_t btype; zorro_id id, id2; unsigned long size;} clgen_zorro_probe_list[] __initdata = { { BT_SD64, ZORRO_PROD_HELFRICH_SD64_RAM, ZORRO_PROD_HELFRICH_SD64_REG, 0x400000 }, { BT_PICCOLO, ZORRO_PROD_HELFRICH_PICCOLO_RAM, ZORRO_PROD_HELFRICH_PICCOLO_REG, 0x200000 }, { BT_PICASSO, ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG, 0x200000 }, { BT_SPECTRUM, ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG, 0x200000 }, { BT_PICASSO4, ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3, 0, 0x400000 },};#endif /* CONFIG_ZORRO */struct clgenfb_par { struct fb_var_screeninfo var; __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 CLGEN_DEBUGtypedef enum { CRT, SEQ} clgen_dbg_reg_class_t;#endif /* CLGEN_DEBUG *//* info about board */struct clgenfb_info { struct fb_info_gen gen; caddr_t fbmem; caddr_t regs; caddr_t mem; unsigned long size; clgen_board_t btype; int smallboard; unsigned char SFR; /* Shadow of special function register */ unsigned long fbmem_phys; unsigned long fbregs_phys; struct clgenfb_par currentmode; struct { u8 red, green, blue, pad; } palette[256]; union {#ifdef FBCON_HAS_CFB16 u16 cfb16[16];#endif#ifdef FBCON_HAS_CFB24 u32 cfb24[16];#endif#ifdef FBCON_HAS_CFB32 u32 cfb32[16];#endif } fbcon_cmap;#ifdef CONFIG_ZORRO unsigned long board_addr, board_size;#endif#ifdef CONFIG_PCI struct pci_dev *pdev;#define IS_7548(x) ((x)->pdev->device == PCI_DEVICE_ID_CIRRUS_7548)#else#define IS_7548(x) (FALSE)#endif};static struct display disp;static struct clgenfb_info boards[MAX_NUM_BOARDS]; /* the boards */static unsigned clgen_def_mode = 1;static int noaccel = 0;/* * Predefined Video Modes */static const struct { const char *name; struct fb_var_screeninfo var;} clgenfb_predefined[] __initdata ={ {"Autodetect", /* autodetect mode */ {0} }, {"640x480", /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */ { 640, 480, 640, 480, 0, 0, 8, 0, {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0, 0, -1, -1, FB_ACCEL_NONE, 40000, 48, 16, 32, 8, 96, 4, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED } }, {"800x600", /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */ { 800, 600, 800, 600, 0, 0, 8, 0, {0, 8, 0}, {0, 8, 0}, {0, 8, 0},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -