📄 mga_vid.c
字号:
//#define CRTC2// YUY2 support (see config.format) added by A'rpi/ESP-team// double buffering added by A'rpi/ESP-team// brightness/contrast introduced by eyck// multiple card support by Attila Kinali <attila@kinali.ch>// Set this value, if autodetection fails! (video ram size in megabytes)// #define MGA_MEMORY_SIZE 16//#define MGA_ALLOW_IRQ#define MGA_VSYNC_POS 2/* * * mga_vid.c * * Copyright (C) 1999 Aaron Holtzman * * Module skeleton based on gutted agpgart module by Jeff Hartmann * <slicer@ionet.net> * * Matrox MGA G200/G400 YUV Video Interface module Version 0.1.0 * * BES == Back End Scaler * * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. *///It's entirely possible this major conflicts with something else//use the 'major' parameter to override the default major number (178)/* mknod /dev/mga_vid c 178 0 */#include <linux/config.h>#include <linux/version.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/mm.h>#include "mplaylib.h"#include <linux/errno.h>#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)#include <linux/malloc.h>#else#include <linux/slab.h>#endif#include <linux/pci.h>#include <linux/ioport.h>#include <linux/init.h>#include "mga_vid.h"#ifdef CONFIG_MTRR #include <asm/mtrr.h>#endif#ifdef CONFIG_DEVFS_FS#include <linux/devfs_fs_kernel.h>#endif#include <asm/uaccess.h>#include <asm/system.h>#include <asm/io.h>#define TRUE 1#define FALSE 0#define DEFAULT_MGA_VID_MAJOR 178#ifndef PCI_DEVICE_ID_MATROX_G200_PCI #define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520#endif#ifndef PCI_DEVICE_ID_MATROX_G200_AGP #define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521#endif#ifndef PCI_DEVICE_ID_MATROX_G400 #define PCI_DEVICE_ID_MATROX_G400 0x0525#endif#ifndef PCI_DEVICE_ID_MATROX_G550 #define PCI_DEVICE_ID_MATROX_G550 0x2527#endif#ifndef PCI_SUBSYSTEM_ID_MATROX_G400_DH_16MB#define PCI_SUBSYSTEM_ID_MATROX_G400_DH_16MB 0x2159#endif#ifndef PCI_SUBSYSTEM_ID_MATROX_G400_16MB_SGRAM#define PCI_SUBSYSTEM_ID_MATROX_G400_16MB_SGRAM 0x19d8#endif#ifndef PCI_SUBSYSTEM_ID_MATROX_G400_16MB_SDRAM#define PCI_SUBSYSTEM_ID_MATROX_G400_16MB_SDRAM 0x0328#endifMODULE_AUTHOR("Aaron Holtzman <aholtzma@engr.uvic.ca>");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endif#define PARAM_BRIGHTNESS "brightness="#define PARAM_CONTRAST "contrast="#define PARAM_BLACKIE "blackie="// set PARAM_BUFF_SIZE to just below 4k because some kernel versions// store additional information in the memory page which leads to// the allocation of an additional page if exactly 4k is used#define PARAM_BUFF_SIZE 4000#ifndef min#define min(x,y) (((x)<(y))?(x):(y))#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)#include <linux/ctype.h>static unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base){ unsigned long result = 0,value; if (!base) { base = 10; if (*cp == '0') { base = 8; cp++; if ((*cp == 'x') && isxdigit(cp[1])) { cp++; base = 16; } } } while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) ? toupper(*cp) : *cp)-'A'+10) < base) { result = result*base + value; cp++; } if (endp) *endp = (char *)cp; return result;}static long simple_strtol(const char *cp,char **endp,unsigned int base){ if(*cp=='-') return -simple_strtoul(cp+1,endp,base); return simple_strtoul(cp,endp,base);}#endiftypedef struct bes_registers_s{ //BES Control uint32_t besctl; //BES Global control uint32_t besglobctl; //Luma control (brightness and contrast) uint32_t beslumactl; //Line pitch uint32_t bespitch; //Buffer A-1 Chroma 3 plane org uint32_t besa1c3org; //Buffer A-1 Chroma org uint32_t besa1corg; //Buffer A-1 Luma org uint32_t besa1org; //Buffer A-2 Chroma 3 plane org uint32_t besa2c3org; //Buffer A-2 Chroma org uint32_t besa2corg; //Buffer A-2 Luma org uint32_t besa2org; //Buffer B-1 Chroma 3 plane org uint32_t besb1c3org; //Buffer B-1 Chroma org uint32_t besb1corg; //Buffer B-1 Luma org uint32_t besb1org; //Buffer B-2 Chroma 3 plane org uint32_t besb2c3org; //Buffer B-2 Chroma org uint32_t besb2corg; //Buffer B-2 Luma org uint32_t besb2org; //BES Horizontal coord uint32_t beshcoord; //BES Horizontal inverse scaling [5.14] uint32_t beshiscal; //BES Horizontal source start [10.14] (for scaling) uint32_t beshsrcst; //BES Horizontal source ending [10.14] (for scaling) uint32_t beshsrcend; //BES Horizontal source last uint32_t beshsrclst; //BES Vertical coord uint32_t besvcoord; //BES Vertical inverse scaling [5.14] uint32_t besviscal; //BES Field 1 vertical source last position uint32_t besv1srclst; //BES Field 1 weight start uint32_t besv1wght; //BES Field 2 vertical source last position uint32_t besv2srclst; //BES Field 2 weight start uint32_t besv2wght; //configurable stuff int blackie;} bes_registers_t;#ifdef CRTC2typedef struct crtc2_registers_s{ uint32_t c2ctl; uint32_t c2datactl; uint32_t c2misc; uint32_t c2hparam; uint32_t c2hsync; uint32_t c2offset; uint32_t c2pl2startadd0; uint32_t c2pl2startadd1; uint32_t c2pl3startadd0; uint32_t c2pl3startadd1; uint32_t c2preload; uint32_t c2spicstartadd0; uint32_t c2spicstartadd1; uint32_t c2startadd0; uint32_t c2startadd1; uint32_t c2subpiclut; uint32_t c2vcount; uint32_t c2vparam; uint32_t c2vsync;} crtc2_registers_t;#endif//All register offsets are converted to word aligned offsets (32 bit)//because we want all our register accesses to be 32 bits#define VCOUNT 0x1e20#define PALWTADD 0x3c00 // Index register for X_DATAREG port#define X_DATAREG 0x3c0a#define XMULCTRL 0x19#define BPP_8 0x00#define BPP_15 0x01#define BPP_16 0x02#define BPP_24 0x03#define BPP_32_DIR 0x04#define BPP_32_PAL 0x07#define XCOLMSK 0x40#define X_COLKEY 0x42#define XKEYOPMODE 0x51#define XCOLMSK0RED 0x52#define XCOLMSK0GREEN 0x53#define XCOLMSK0BLUE 0x54#define XCOLKEY0RED 0x55#define XCOLKEY0GREEN 0x56#define XCOLKEY0BLUE 0x57#ifdef CRTC2/*CRTC2 registers*/#define XMISCCTRL 0x1e#define C2CTL 0x3c10 #define C2DATACTL 0x3c4c#define C2MISC 0x3c44#define C2HPARAM 0x3c14#define C2HSYNC 0x3c18#define C2OFFSET 0x3c40#define C2PL2STARTADD0 0x3c30 // like BESA1CORG#define C2PL2STARTADD1 0x3c34 // like BESA2CORG#define C2PL3STARTADD0 0x3c38 // like BESA1C3ORG#define C2PL3STARTADD1 0x3c3c // like BESA2C3ORG#define C2PRELOAD 0x3c24#define C2SPICSTARTADD0 0x3c54#define C2SPICSTARTADD1 0x3c58#define C2STARTADD0 0x3c28 // like BESA1ORG#define C2STARTADD1 0x3c2c // like BESA2ORG#define C2SUBPICLUT 0x3c50#define C2VCOUNT 0x3c48#define C2VPARAM 0x3c1c#define C2VSYNC 0x3c20#endif// Backend Scaler registers#define BESCTL 0x3d20#define BESGLOBCTL 0x3dc0#define BESLUMACTL 0x3d40#define BESPITCH 0x3d24#define BESA1C3ORG 0x3d60#define BESA1CORG 0x3d10#define BESA1ORG 0x3d00#define BESA2C3ORG 0x3d64 #define BESA2CORG 0x3d14#define BESA2ORG 0x3d04#define BESB1C3ORG 0x3d68#define BESB1CORG 0x3d18#define BESB1ORG 0x3d08#define BESB2C3ORG 0x3d6C#define BESB2CORG 0x3d1C#define BESB2ORG 0x3d0C#define BESHCOORD 0x3d28#define BESHISCAL 0x3d30#define BESHSRCEND 0x3d3C#define BESHSRCLST 0x3d50#define BESHSRCST 0x3d38#define BESV1WGHT 0x3d48#define BESV2WGHT 0x3d4c#define BESV1SRCLST 0x3d54#define BESV2SRCLST 0x3d58#define BESVISCAL 0x3d34#define BESVCOORD 0x3d2c#define BESSTATUS 0x3dc4#define CRTCX 0x1fd4#define CRTCD 0x1fd5#define IEN 0x1e1c#define ICLEAR 0x1e18#define STATUS 0x1e14// global devfs handle for /dev/mga_vid#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t dev_handle = NULL;#endif// card local configtypedef struct mga_card_s {// local devfs handle for /dev/mga_vidX#ifdef CONFIG_DEVFS_FS devfs_handle_t dev_handle;#endif uint8_t *param_buff; // buffer for read() uint32_t param_buff_size; uint32_t param_buff_len; bes_registers_t regs;#ifdef CRTC2 crtc2_registers_t cregs;#endif uint32_t vid_in_use; uint32_t is_g400; uint32_t vid_src_ready; uint32_t vid_overlay_on; uint8_t *mmio_base; uint32_t mem_base; int src_base; // YUV buffer position in video memory uint32_t ram_size; // how much megabytes videoram we have uint32_t top_reserved; // reserved space for console font (matroxfb + fastfont) int brightness; // initial brightness int contrast; // initial contrast struct pci_dev *pci_dev; mga_vid_config_t config; int configured; // set to 1 when the card is configured over ioctl int colkey_saved; int colkey_on; unsigned char colkey_color[4]; unsigned char colkey_mask[4]; int irq; // = -1 int next_frame; } mga_card_t;#define MGA_MAX_CARDS 16// this is used as init value for the parameter arrays// it should have exactly MGA_MAX_CARDS elements#define MGA_MAX_CARDS_INIT_ARRAY {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}static unsigned int mga_cards_num=0;static mga_card_t * mga_cards[MGA_MAX_CARDS] = MGA_MAX_CARDS_INIT_ARRAY;// module parametersstatic int major = DEFAULT_MGA_VID_MAJOR;static int mga_ram_size[MGA_MAX_CARDS] = MGA_MAX_CARDS_INIT_ARRAY;static int mga_brightness[MGA_MAX_CARDS] = MGA_MAX_CARDS_INIT_ARRAY;static int mga_contrast[MGA_MAX_CARDS] = MGA_MAX_CARDS_INIT_ARRAY;static int mga_top_reserved[MGA_MAX_CARDS] = MGA_MAX_CARDS_INIT_ARRAY;MODULE_PARM(mga_ram_size, "1-" __MODULE_STRING(MGA_MAX_CARDS) "i");MODULE_PARM(mga_top_reserved, "1-" __MODULE_STRING(MGA_MAX_CARDS) "i");MODULE_PARM(mga_brightness, "1-" __MODULE_STRING(MGA_MAX_CARDS) "i");MODULE_PARM(mga_contrast, "1-" __MODULE_STRING(MGA_MAX_CARDS) "i");MODULE_PARM(major, "i");#ifdef CRTC2static void crtc2_frame_sel(mga_card_t * card, int frame){switch(frame) {case 0: card->cregs.c2pl2startadd0=card->regs.besa1corg; card->cregs.c2pl3startadd0=card->regs.besa1c3org; card->cregs.c2startadd0=card->regs.besa1org; break;case 1: card->cregs.c2pl2startadd0=card->regs.besa2corg; card->cregs.c2pl3startadd0=card->regs.besa2c3org; card->cregs.c2startadd0=card->regs.besa2org; break;case 2: card->cregs.c2pl2startadd0=card->regs.besb1corg; card->cregs.c2pl3startadd0=card->regs.besb1c3org; card->cregs.c2startadd0=card->regs.besb1org; break;case 3: card->cregs.c2pl2startadd0=card->regs.besb2corg; card->cregs.c2pl3startadd0=card->regs.besb2c3org; card->cregs.c2startadd0=card->regs.besb2org; break;} writel(card->cregs.c2startadd0, card->mmio_base + C2STARTADD0); writel(card->cregs.c2pl2startadd0, card->mmio_base + C2PL2STARTADD0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -