mga_vid.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,405 行 · 第 1/3 页

C
1,405
字号
/* * VIDIX driver for Matrox chipsets. * Copyright (C) 2002 Alex Beregszaszi * * This file is part of MPlayer. * * MPlayer is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MPlayer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MPlayer; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Original sources from Aaron Holtzman (C) 1999. * Module skeleton based on gutted agpgart module by Jeff Hartmann  *   <slicer@ionet.net> * YUY2 support added by A'rpi/ESP-team     double buffering added by A'rpi/ESP-team * Brightness/contrast support by Nick Kurshev/Dariush Pietrzak (eyck) * * TODO: *   - fix memory size detection (current reading pci userconfig isn't *     working as requested - returns the max avail. ram on arch?) *   - translate all non-english comments to english *///#define CRTC2// Set this value, if autodetection fails! (video ram size in megabytes)//#define MGA_MEMORY_SIZE 16/* No irq support in userspace implemented yet, do not enable this! *//* disable irq */#undef MGA_ALLOW_IRQ#define MGA_VSYNC_POS 2#undef MGA_PCICONFIG_MEMDETECT#define MGA_DEFAULT_FRAMES 4#include <errno.h>#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <math.h>#include <inttypes.h>#include "vidix.h"#include "vidixlib.h"#include "fourcc.h"#include "dha.h"#include "pci_ids.h"#include "pci_names.h"#undef memcpy#define memcpy uc_memcpy#ifdef __MINGW32__#define ENOTSUP 134#endif#if    !defined(ENOTSUP) && defined(EOPNOTSUPP)#define ENOTSUP EOPNOTSUPP#endif/* from radeon_vid */#define GETREG(TYPE,PTR,OFFZ)		(*((volatile TYPE*)((PTR)+(OFFZ))))#define SETREG(TYPE,PTR,OFFZ,VAL)	(*((volatile TYPE*)((PTR)+(OFFZ))))=VAL#define readb(addr)		GETREG(uint8_t,(uint32_t)(addr),0)#define writeb(val,addr)	SETREG(uint8_t,(uint32_t)(addr),0,val)#define readl(addr)		GETREG(uint32_t,(uint32_t)(addr),0)#define writel(val,addr)	SETREG(uint32_t,(uint32_t)(addr),0,val)static int mga_verbose = 0;/* for device detection */static int probed = 0;static pciinfo_t pci_info;/* internal booleans */static int mga_vid_in_use = 0;static int is_g400 = 0;static int vid_src_ready = 0;static int vid_overlay_on = 0;/* mapped physical addresses */static uint8_t *mga_mmio_base = 0;static uint8_t *mga_mem_base = 0;static int mga_src_base = 0; /* YUV buffer position in video memory */static uint32_t mga_ram_size = 0; /* how much megabytes videoram we have *//* Graphic keys */static vidix_grkey_t mga_grkey;static int colkey_saved = 0;static int colkey_on = 0;static unsigned char colkey_color[4];static unsigned char colkey_mask[4];/* for IRQ */static int mga_irq = -1;static int mga_next_frame = 0;static vidix_capability_t mga_cap ={    "Matrox MGA G200/G4x0/G5x0 YUV Video",    "Aaron Holtzman, Arpad Gereoffy, Alex Beregszaszi, Nick Kurshev",    TYPE_OUTPUT,    { 0, 0, 0, 0 },    2048,    2048,    4,    4,    -1,    FLAG_UPSCALER | FLAG_DOWNSCALER | FLAG_EQUALIZER,    VENDOR_MATROX,    -1, /* will be set in vixProbe */    { 0, 0, 0, 0}};/* MATROX BES registers */typedef 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;} bes_registers_t;static bes_registers_t regs;#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;static crtc2_registers_t cregs;#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 /* CRTC2 */// 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#ifdef CRTC2static void crtc2_frame_sel(int frame){switch(frame) {case 0:		cregs.c2pl2startadd0=regs.besa1corg;	cregs.c2pl3startadd0=regs.besa1c3org;	cregs.c2startadd0=regs.besa1org;	break;case 1:	cregs.c2pl2startadd0=regs.besa2corg;	cregs.c2pl3startadd0=regs.besa2c3org;	cregs.c2startadd0=regs.besa2org;	break;case 2:	cregs.c2pl2startadd0=regs.besb1corg;	cregs.c2pl3startadd0=regs.besb1c3org;	cregs.c2startadd0=regs.besb1org;	break;case 3:	cregs.c2pl2startadd0=regs.besb2corg;	cregs.c2pl3startadd0=regs.besb2c3org;	cregs.c2startadd0=regs.besb2org;	break;}	writel(cregs.c2startadd0, mga_mmio_base + C2STARTADD0);	writel(cregs.c2pl2startadd0, mga_mmio_base + C2PL2STARTADD0);	writel(cregs.c2pl3startadd0, mga_mmio_base + C2PL3STARTADD0);}#endifstatic int mga_frame_select(unsigned int frame){    mga_next_frame = frame;    if (mga_verbose>1) printf("[mga] frameselect: %d\n", mga_next_frame);#if MGA_ALLOW_IRQ    if (mga_irq == -1)#endif    {	//we don't need the vcount protection as we're only hitting	//one register (and it doesn't seem to be double buffered)	regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25);	writel( regs.besctl, mga_mmio_base + BESCTL ); //	writel( regs.besglobctl + ((readl(mga_mmio_base + VCOUNT)+2)<<16),	writel( regs.besglobctl + (MGA_VSYNC_POS<<16),			mga_mmio_base + BESGLOBCTL);#ifdef CRTC2	crtc2_frame_sel(mga_next_frame);#endif    }    return(0);}static void mga_vid_write_regs(int restore){	//Make sure internal registers don't get updated until we're done	writel( (readl(mga_mmio_base + VCOUNT)-1)<<16,			mga_mmio_base + BESGLOBCTL);	// color or coordinate keying		if(restore && colkey_saved){	    // restore it	    colkey_saved=0;		// Set color key registers:		writeb( XKEYOPMODE, mga_mmio_base + PALWTADD);		writeb( colkey_on, mga_mmio_base + X_DATAREG);				writeb( XCOLKEY0RED, mga_mmio_base + PALWTADD);		writeb( colkey_color[0], mga_mmio_base + X_DATAREG);		writeb( XCOLKEY0GREEN, mga_mmio_base + PALWTADD);		writeb( colkey_color[1], mga_mmio_base + X_DATAREG);		writeb( XCOLKEY0BLUE, mga_mmio_base + PALWTADD);		writeb( colkey_color[2], mga_mmio_base + X_DATAREG);		writeb( X_COLKEY, mga_mmio_base + PALWTADD);		writeb( colkey_color[3], mga_mmio_base + X_DATAREG);		writeb( XCOLMSK0RED, mga_mmio_base + PALWTADD);		writeb( colkey_mask[0], mga_mmio_base + X_DATAREG);		writeb( XCOLMSK0GREEN, mga_mmio_base + PALWTADD);		writeb( colkey_mask[1], mga_mmio_base + X_DATAREG);		writeb( XCOLMSK0BLUE, mga_mmio_base + PALWTADD);		writeb( colkey_mask[2], mga_mmio_base + X_DATAREG);		writeb( XCOLMSK, mga_mmio_base + PALWTADD);		writeb( colkey_mask[3], mga_mmio_base + X_DATAREG);	} else if(!colkey_saved){	    // save it	    colkey_saved=1;		// Get color key registers:		writeb( XKEYOPMODE, mga_mmio_base + PALWTADD);		colkey_on=(unsigned char)readb(mga_mmio_base + X_DATAREG) & 1;				writeb( XCOLKEY0RED, mga_mmio_base + PALWTADD);		colkey_color[0]=(unsigned char)readb(mga_mmio_base + X_DATAREG);		writeb( XCOLKEY0GREEN, mga_mmio_base + PALWTADD);		colkey_color[1]=(unsigned char)readb(mga_mmio_base + X_DATAREG);		writeb( XCOLKEY0BLUE, mga_mmio_base + PALWTADD);		colkey_color[2]=(unsigned char)readb(mga_mmio_base + X_DATAREG);		writeb( X_COLKEY, mga_mmio_base + PALWTADD);		colkey_color[3]=(unsigned char)readb(mga_mmio_base + X_DATAREG);		writeb( XCOLMSK0RED, mga_mmio_base + PALWTADD);		colkey_mask[0]=(unsigned char)readb(mga_mmio_base + X_DATAREG);		writeb( XCOLMSK0GREEN, mga_mmio_base + PALWTADD);		colkey_mask[1]=(unsigned char)readb(mga_mmio_base + X_DATAREG);		writeb( XCOLMSK0BLUE, mga_mmio_base + PALWTADD);		colkey_mask[2]=(unsigned char)readb(mga_mmio_base + X_DATAREG);		writeb( XCOLMSK, mga_mmio_base + PALWTADD);		colkey_mask[3]=(unsigned char)readb(mga_mmio_base + X_DATAREG);	}	if(!restore){	writeb( XKEYOPMODE, mga_mmio_base + PALWTADD);	writeb( mga_grkey.ckey.op == CKEY_TRUE, mga_mmio_base + X_DATAREG);	if ( mga_grkey.ckey.op == CKEY_TRUE )	{		uint32_t r=0, g=0, b=0;		writeb( XMULCTRL, mga_mmio_base + PALWTADD);		switch (readb (mga_mmio_base + X_DATAREG)) 		{			case BPP_8:				/* Need to look up the color index, just using														 color 0 for now. */			break;			case BPP_15:				r = mga_grkey.ckey.red   >> 3;				g = mga_grkey.ckey.green >> 3;				b = mga_grkey.ckey.blue  >> 3;			break;			case BPP_16:				r = mga_grkey.ckey.red   >> 3;				g = mga_grkey.ckey.green >> 2;				b = mga_grkey.ckey.blue  >> 3;			break;			case BPP_24:			case BPP_32_DIR:			case BPP_32_PAL:				r = mga_grkey.ckey.red;				g = mga_grkey.ckey.green;				b = mga_grkey.ckey.blue;			break;		}		// Enable colorkeying		writeb( XKEYOPMODE, mga_mmio_base + PALWTADD);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?