📄 smi7xx.c
字号:
/********************************************************************************
*
* Copyright WIS Technologies (c) (2003)
* All Rights Reserved
*
/********************************************************************************
*
* FILE:
*
* smi7xx.c
*
* DESCRIPTION:
*
* Frame Buffer driver for the SMI 7xx VGA (Video Graphcs Driver).
*
*********************************************************************************/
#include "pci.h"
#include "video_fb.h"
/*#include <osl_vx.h>*/
/*#include <ixp425Pci.h>*/
/* XScale I/O constants */
#define CFG_ISA_IO 0x0000
/* Generic PCI Command Register constants */
#define PCI_CMD_IO_ENABLE 0x0001 /* IO access enable */
#define PCI_CMD_MEM_ENABLE 0x0002 /* memory access enable */
#define PCI_CMD_MASTER_ENABLE 0x0004 /* bus master enable */
#define PCI_CMD_MON_ENABLE 0x0008 /* monitor special cycles enable */
#define PCI_CMD_WI_ENABLE 0x0010 /* write and invalidate enable */
#define PCI_CMD_SNOOP_ENABLE 0x0020 /* palette snoop enable */
#define PCI_CMD_PERR_ENABLE 0x0040 /* parity error enable */
#define PCI_CMD_WC_ENABLE 0x0080 /* wait cycle enable */
#define PCI_CMD_SERR_ENABLE 0x0100 /* system error enable */
#define PCI_CMD_FBTB_ENABLE 0x0200 /* fast back to back enable */
/*
* I/O Support: Note - these could be optimized for many platforms.
* For example, on PPC, all of these I/O routines can be implemented
* with ONE instruction. For now, we use the C routines for
* portability. XXX Todo: optimize for your platform
*/
#define MSB(x) (((x) >> 8) & 0xff) /* most signif byte of 2-byte integer */
#define LSB(x) ((x) & 0xff) /* least signif byte of 2-byte integer*/
#define MSW(x) (((x) >> 16) & 0xffff) /* most signif word of 2-word integer */
#define LSW(x) ((x) & 0xffff) /* least signif byte of 2-word integer*/
/*
* See vxWorks.h, which has a bug in the word-swap,
* macro!
*/
#define WSWAP(x) (MSB(x) | (LSB(x) << 8))
#define LSWAP(x) ((LLSB(x) << 24) | \
(LNLSB(x) << 16)| \
(LNMSB(x) << 8) | \
(LMSB(x)))
#define SWAP16(x) ((((x) << 8) | ((x) >> 8)) & 0xFFFF)
#define SWAP32(x) \
(((x) << 24) | \
(((x) & 0x0000FF00) << 8) | \
(((x) & 0x00FF0000) >> 8) | \
(((unsigned int)(x)) >> 24))
#ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
#define sysPciOutWord1(addr,data) *(volatile UINT16*)((addr)) = SWAP16((UINT16)data)
#define sysPciOutLong1(addr,data) *(volatile UINT32*)((addr)) = SWAP32((UINT32)data)
#else
#define sysPciOutWord1(addr,data) *((volatile UINT16*)((addr) & ~3)) = (UINT16)data
#define sysPciOutLong1(addr,data) *(volatile UINT32*)((addr)) = (UINT32)data
#endif
/*because we do not return read values as return codes in our
*pci IO config library, we must define these as functions, not macros
*/
UINT16 sysPciInWord1(ULONG addr)
{
UINT32 val;
UINT16 retval;
if (addr & 3)
{
addr=addr & ~3; /*round down to 32 bit align*/
val = *((UINT32*)addr);
#ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
val = SWAP32(val);
#endif
retval = val >> 16;
return retval;
}
else
{
return *((UINT16*)addr);
}
}
ULONG sysPciInLong1(ULONG addr)
{
#ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
return SWAP32(*((ULONG*)addr));
#else
return *((ULONG*)addr);
#endif
}
/* XScale IXP425 */
/* NOTE: we need to differentiate from I/O cycles */
/* XScale NP PCI I/O Cycle */
unsigned char in8_io(unsigned int addr){
unsigned char data;
/*data = *(volatile char *)(addr);*/
data=sysInByte(addr);
return data;
}
void out8_io(unsigned int addr , unsigned char val){
/**(volatile char *)(addr) = val;*/
sysOutByte(addr,val);
}
#if 0
/* XScale NP PCI Memory Half-Word I/0 */
unsigned short in16(unsigned int addr){
unsigned short data;
pciMemInWord((void*)addr, &data);
return data;
}
unsigned short in16r(unsigned int addr){
return WSWAP(in16(addr));
}
void out16(unsigned int addr, unsigned short value){
pciMemOutWord((void*)addr, value);
}
void out16r(unsigned int addr, unsigned short value){
out16(addr,WSWAP(value));
}
/* XScale NP PCI Memory Word I/0 */
unsigned long in32(unsigned int addr){
unsigned int data;
pciMemInLong((void*)addr, &data);
return data;
}
unsigned long in32r(unsigned int addr){
return LSWAP(in32(addr));
}
void out32(unsigned int addr, unsigned long value){
pciMemOutLong((void*)addr, value);
}
void out32r(unsigned int addr, unsigned long value){
out32(addr,LSWAP(value));
}
#else
/* XScale PCI Memory Half-Word I/0 */
unsigned short in16(unsigned int addr){
return sysPciInWord1(addr);
}
unsigned short in16r(unsigned int addr){
#ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
return WSWAP(in16(addr));
#else
return in16(addr);
#endif
}
void out16(unsigned int addr, unsigned short value){
sysPciOutWord1(addr, value);
}
void out16r(unsigned int addr, unsigned short value){
#ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
out16(addr,WSWAP(value));
#else
out16(addr,value);
#endif
}
/* XScale PCI Memory Word I/0 */
unsigned long in32(unsigned int addr){
return sysPciInLong1(addr);
}
unsigned long in32r(unsigned int addr){
#ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
return LSWAP(in32(addr));
#else
return in32(addr);
#endif
}
void out32(unsigned int addr, unsigned long value){
sysPciOutLong1(addr, value);
}
void out32r(unsigned int addr, unsigned long value){
#ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
out32(addr,LSWAP(value));
#else
out32(addr,value);
#endif
}
#endif /* !XSCALE */
#define pci_mem_to_phys(x,y) (y)
/*#define udelay(x) sysMicroDelay(x)*/
/*
* Export Graphic Device
*/
GraphicDevice smi;
/*
* SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
*/
#define VIDEO_MEM_SIZE 0x400000
/*
* Supported video modes for SMI Lynx E/EM/EM+
*/
#define VIDEO_MODES 7
#define DUAL_800_600 0 /* SMI710:VGA1:75Hz (pitch=1600) */
/* VGA2:60/120Hz (pitch=1600) */
/* SMI810:VGA1:75Hz (pitch=1600) */
/* VGA2:75Hz (pitch=1600) */
#define DUAL_1024_768 1 /* VGA1:75Hz VGA2:73Hz (pitch=2048) */
#define SINGLE_800_600 2 /* VGA1:75Hz (pitch=800) */
#define SINGLE_1024_768 3 /* VGA1:75Hz (pitch=1024) */
#define SINGLE_1280_1024 4 /* VGA1:75Hz (pitch=1280) */
#define TV_MODE_CCIR 5 /* VGA1:50Hz (h=720;v=576;pitch=720) */
#define TV_MODE_EIA 6 /* VGA1:60Hz (h=720;v=484;pitch=720) */
/*
* ISA mapped regs
*/
#define SMI_INDX_C4 (pGD->isaBase + 0x03c4) /* index reg */
#define SMI_DATA_C5 (pGD->isaBase + 0x03c5) /* data reg */
#define SMI_INDX_D4 (pGD->isaBase + 0x03d4) /* index reg */
#define SMI_DATA_D5 (pGD->isaBase + 0x03d5) /* data reg */
#define SMI_INDX_CE (pGD->isaBase + 0x03ce) /* index reg */
#define SMI_DATA_CF (pGD->isaBase + 0x03cf) /* data reg */
#define SMI_LOCK_REG (pGD->isaBase + 0x03c3) /* unlock/lock ext crt reg */
#define SMI_MISC_REG (pGD->isaBase + 0x03c2) /* misc reg */
#define SMI_LUT_MASK (pGD->isaBase + 0x03c6) /* lut mask reg */
#define SMI_LUT_START (pGD->isaBase + 0x03c8) /* lut start index */
#define SMI_LUT_RGB (pGD->isaBase + 0x03c9) /* lut colors auto incr.*/
/*
* Video processor control
*/
typedef struct {
unsigned int control;
unsigned int colorKey;
unsigned int colorKeyMask;
unsigned int start;
unsigned short offset;
unsigned short width;
unsigned int fifoPrio;
unsigned int fifoERL;
unsigned int YUVtoRGB;
} SmiVideoProc;
/*
* Video window control
*/
typedef struct {
unsigned short top;
unsigned short left;
unsigned short bottom;
unsigned short right;
unsigned int srcStart;
unsigned short width;
unsigned short offset;
unsigned char hStretch;
unsigned char vStretch;
} SmiVideoWin;
/*
* Capture port control
*/
typedef struct {
unsigned int control;
unsigned short topClip;
unsigned short leftClip;
unsigned short srcHeight;
unsigned short srcWidth;
unsigned int srcBufStart1;
unsigned int srcBufStart2;
unsigned short srcOffset;
unsigned short fifoControl;
} SmiCapturePort;
/*
* Register values for common video modes
*/
char SMI_SCR[22] = {
/* all modes */
0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0x00, 0x15, 0x90,
0x16, 0x10, 0x17, 0x2c, 0x18, 0xb1, 0x19, 0x20, 0x1a, 0x01
};
char SMI_EXT_CRT[VIDEO_MODES][24] = {
{ /* DUAL_800_600_8 */
0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
},
{ /* DUAL_1024_768_8 */
0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
},
{ /* SINGLE_800_600_8 */
0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
},
{ /* SINGLE_1024_768_8 */
0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
},
{ /* SINGLE_1280_1024_8 */
0x30, 0x09, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
},
{ /* TV_MODE_CCIR */
0x30, 0x80, 0x31, 0x2b, 0x32, 0x06, 0x33, 0x01, 0x34, 0x26, 0x35, 0x88,
0x36, 0x02, 0x38, 0x11, 0x39, 0x11, 0x3a, 0x20, 0x3e, 0xa3, 0x3f, 0x00
},
{ /* TV_MODE_EIA */
0x30, 0x80, 0x31, 0x2b, 0x32, 0x06, 0x33, 0x00, 0x34, 0xf8, 0x35, 0x88,
0x36, 0x02, 0x38, 0x11, 0x39, 0x11, 0x3a, 0x20, 0x3e, 0xa3, 0x3f, 0x00
},
};
char SMI_CRTCR[VIDEO_MODES][50] = {
{ /* DUAL_800_600_8 */
0x00, 0x7f, 0x01, 0x63, 0x02, 0x63, 0x03, 0x00, 0x04, 0x68, 0x05, 0x12,
0x06, 0x6f, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x59, 0x11, 0x2c,
0x12, 0x57, 0x13, 0x64, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
0x18, 0xff
},
{ /* DUAL_1024_768_8 */
0x00, 0x9f, 0x01, 0x7f, 0x02, 0x7f, 0x03, 0x00, 0x04, 0x82, 0x05, 0x0e,
0x06, 0x1e, 0x07, 0xf5, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x24,
0x12, 0xff, 0x13, 0x80, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
0x18, 0xff
},
{ /* SINGLE_800_600_8 */
0x00, 0x7f, 0x01, 0x63, 0x02, 0x63, 0x03, 0x00, 0x04, 0x68, 0x05, 0x12,
0x06, 0x6f, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x59, 0x11, 0x2c,
0x12, 0x57, 0x13, 0x32, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
0x18, 0xff
},
{ /* SINGLE_1024_768_8 */
0x00, 0x9f, 0x01, 0x7f, 0x02, 0x7f, 0x03, 0x00, 0x04, 0x82, 0x05, 0x0e,
0x06, 0x1e, 0x07, 0xf5, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x24,
0x12, 0xff, 0x13, 0x40, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
0x18, 0xff
},
{ /* SINGLE_1280_1024_8 */
0x00, 0xce, 0x01, 0x9f, 0x02, 0x9f, 0x03, 0x00, 0x04, 0xa2, 0x05, 0x12,
0x06, 0x2a, 0x07, 0x5a, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x23,
0x12, 0xff, 0x13, 0x50, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
0x18, 0xff
},
{ /* TV_MODE_CCIR */
0x00, 0x00, 0x01, 0x59, 0x02, 0x63, 0x03, 0x00, 0x04, 0x69, 0x05, 0x10,
0x06, 0x72, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x58, 0x11, 0x2c,
0x12, 0x57, 0x13, 0x2d, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
0x18, 0xff
},
{ /* TV_MODE_EIA */
0x00, 0x00, 0x01, 0x59, 0x02, 0x63, 0x03, 0x00, 0x04, 0x69, 0x05, 0x10,
0x06, 0x72, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x58, 0x11, 0x2c,
0x12, 0x57, 0x13, 0x2d, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
0x18, 0xff
},
};
char SMI_SEQR[10] = {
0x00, 0x03, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e
};
char SMI_PCR[VIDEO_MODES][8] = {
{ /* DUAL_800_600_8 */
0x20, 0x04, 0x21, 0x20, 0x22, 0x00, 0x23, 0x00
},
{ /* DUAL_1024_768_8 */
0x20, 0x04, 0x21, 0x20, 0x22, 0x00, 0x23, 0x00
},
{ /* SINGLE_800_600_8 */
0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
},
{ /* SINGLE_1024_768_8 */
0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
},
{ /* SINGLE_1280_1024_8 */
0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
},
{ /* TV_MODE_CCIR */
0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
},
{ /* TV_MODE_EIA */
0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
},
};
char SMI_MCR[VIDEO_MODES][6] = {
{ /* DUAL_800_600_8 */
0x60, 0x01, 0x61, 0x00, 0x62, 0x7a
},
{ /* DUAL_1024_768_8 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -