/*
Matrox MGA driver
ported to VIDIX by Alex Beregszaszi
YUY2 support (see config.format) added by A'rpi/ESP-team
double buffering added by A'rpi/ESP-team
Brightness/contrast support by Nick Kurshev/Dariush Pietrzak (eyck) and me
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
*/
/*
* Original copyright:
*
* 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.
*/
//#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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <inttypes.h>
#include "vidix.h"
#include "vidixlib.h"
#include "fourcc.h"
#include "../libdha/libdha.h"
#include "../libdha/pci_ids.h"
#include "../libdha/pci_names.h"
#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 CRTC2
typedef 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
#de
|