📄 smi7xx.c
字号:
/*******************************************************************************
*
* Init video chip with common Linux graphic modes (lilo)
*/
void *video_hw_init (void)
{
GraphicDevice *pGD = (GraphicDevice *)&smi;
unsigned short device_id;
pci_dev_t devbusfn;
int videomode;
unsigned int pci_mem_base, *vm, i;
UINT8 cl, lt;
unsigned int gdfTab[] = { 1, 2, 2, 4, 3, 1 };
char *gdfModes[] =
{
"8 Bit Index Color",
"15 Bit 5-5-5 RGB",
"16 Bit 5-6-5 RGB",
"32 Bit X-8-8-8 RGB",
"24 Bit 8-8-8 RGB",
"8 Bit 3-3-2 RGB"
};
int vgaModes[16][2] =
{
{769, -1}, {771, 0x00002}, {773, 0x00003}, {775, 0x00004},
{784, -1}, {787, 0x10002}, {790, 0x10003}, {793, 0x10004},
{785, -1}, {788, 0x20002}, {791, 0x20003}, {794, 0x20004},
{786, -1}, {789, 0x40002}, {792, 0x40003}, {795, 0x40004}
};
#if 0
PciDevice* pDev = NULL;
/* Now, the VGA ... */
if( (pDev = pciDeviceGet(PCI_VENDOR_ID_SMI,
PCI_DEVICE_ID_SMI_712,0) ) == NULL){
printf("Error: could not find "
"device instance 0 for SMI712 VENDOR: 0x%x, Device: 0x%x\n",
PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712);
return 0;
}
printf("Video: Detected SMI712 Controller\n");
/* Set PCI membase/base */
/**((unsigned int*)0xc0000034)=0x01010101;*/
pci_mem_base = 0xdc000000;
pGD->isaBase = 0xfe000000;
pciConfigOutLong (pDev->bus, pDev->device, pDev->func,
PCI_CFG_BASE_ADDRESS_0,
pci_mem_base);
/* enable mapped I/O addresses */
pciConfigOutLong (pDev->bus, pDev->device, pDev->func,
PCI_CFG_COMMAND,
PCI_CMD_WI_ENABLE|
PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE);
#endif
/*device_id = PCI_DEVICE_ID_SMI_712;*/
pci_mem_base = 0xdc800000;
pGD->isaBase = 0xfe000000;
/* Relocate to CPU addr */
/*pci_mem_base += 0x48000000;*/
printf("CPU PCI Mem Virtual address: 0x%x\n", pci_mem_base);
printf("CPU PCI I/O Virtual address: 0x%x\n", pGD->isaBase);
pGD->pciBase = pci_mem_base;
pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
pGD->frameAdrs = pci_mem_base;
pGD->memSize = VIDEO_MEM_SIZE;
printf("SMI712: PCIMEM:@0x%x, ISAMEM:@0x%x\n"
"DPR:@0x%x,VPR:@0x%x,CPR=0x%x\n"
"VRAM=0x%x, %dMB\n", pGD->pciBase,
pGD->isaBase,
pGD->dprBase,
pGD->vprBase,
pGD->cprBase,
pGD->frameAdrs,
VIDEO_MEM_SIZE/0x100000
);
/* Default 800x600 8 bit index color */
videomode = 788/*0x303*/;
/* videomode = 790; */
/* Compare with common vga mode numbers */
for (i=0; i<16; i++)
{
if (vgaModes[i][0] == videomode)
{
if (vgaModes[i][1] == -1)
{
printf("Videomode not supported !\n");
return (NULL); /* mode not supported */
}
pGD->mode = vgaModes[i][1]; /* use driver int. mode number */
break;
}
}
/* Extract graphic data format */
pGD->gdfIndex = (pGD->mode & 0x00070000) >> 16;
if (pGD->gdfIndex > 5)
pGD->gdfIndex = 0;
#if 0
/* Force 8-bpp */
pGD->gdfIndex = 0;
#else
/* XXX NOTE: Force 16BPP mode for now */
pGD->gdfIndex = GDF_16BIT_565RGB; /* was GDF_32BIT_X888RGB */
#endif
pGD->gdfBytesPP = gdfTab[pGD->gdfIndex];
/* Extract graphic resolution */
pGD->mode &= 0xf;
/* Exit for not supported resolutions */
if (((pGD->mode==DUAL_800_600) ||
(pGD->mode==DUAL_1024_768)) && (pGD->gdfBytesPP > 1))
{
printf ("Dual screen for 1BPP only !\n");
return (NULL);
}
if ((pGD->mode==SINGLE_1280_1024) && (pGD->gdfBytesPP==4))
{
printf ("Out of memory !\n");
return (NULL);
}
/* Set graphic parameters */
switch (pGD->mode)
{
case DUAL_800_600:
pGD->winSizeX = 800;
pGD->winSizeY = 600;
pGD->plnSizeX = 1600;
pGD->plnSizeY = 600;
sprintf (pGD->modeIdent,
"Dual Screen 800x600 with %s", gdfModes[pGD->gdfIndex]);
break;
case DUAL_1024_768:
pGD->winSizeX = 1024;
pGD->winSizeY = 768;
pGD->plnSizeX = 2048;
pGD->plnSizeY = 768;
sprintf (pGD->modeIdent,
"Dual Screen 1024x768 with %s", gdfModes[pGD->gdfIndex]);
break;
case SINGLE_800_600:
pGD->winSizeX = 800;
pGD->winSizeY = 600;
pGD->plnSizeX = 800;
pGD->plnSizeY = 600;
sprintf (pGD->modeIdent,
"Single Screen 800x600 with %s", gdfModes[pGD->gdfIndex]);
break;
case SINGLE_1024_768:
pGD->winSizeX = 1024;
pGD->winSizeY = 768;
pGD->plnSizeX = 1024;
pGD->plnSizeY = 768;
sprintf (pGD->modeIdent,
"Single Screen 1024x768 with %s",
gdfModes[pGD->gdfIndex]);
break;
case TV_MODE_CCIR:
pGD->winSizeX = 720;
pGD->winSizeY = 576;
pGD->plnSizeX = 720;
pGD->plnSizeY = 576;
sprintf (pGD->modeIdent,
"TV Mode CCIR with %s", gdfModes[pGD->gdfIndex]);
break;
case TV_MODE_EIA:
pGD->winSizeX = 720;
pGD->winSizeY = 484;
pGD->plnSizeX = 720;
pGD->plnSizeY = 484;
sprintf (pGD->modeIdent,
"TV Mode EIA with %s", gdfModes[pGD->gdfIndex]);
break;
case SINGLE_1280_1024:
pGD->winSizeX = 1280;
pGD->winSizeY = 1024;
pGD->plnSizeX = 1280;
pGD->plnSizeY = 1024;
sprintf (pGD->modeIdent,
"Single Screen 1280x1024 with %s",
gdfModes[pGD->gdfIndex]);
break;
default:
printf("Videomode not supported !\n");
return (NULL);
}
/* Turn off display */
smiWrite (0x3c4, 0x01, 0x20);
/* Unlock ext. crt regs */
out8_io (SMI_LOCK_REG, 0x40);
/* Set Register base to isa 3dx for 3?x regs (color mode) */
out8_io (SMI_MISC_REG, 0x2b);
/* Unlock crt regs 0-7 */
smiWrite (0x3d4, 0x11, 0x0e);
/* Sytem Control Register */
smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
SMI_SCR, sizeof(SMI_SCR));
/* extented CRT Register */
smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
SMI_EXT_CRT[pGD->mode], sizeof(SMI_EXT_CRT)/VIDEO_MODES);
/* Sequencer Register */
smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
SMI_SEQR, sizeof(SMI_SEQR));
/* Power Control Register */
smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
SMI_PCR[pGD->mode], sizeof(SMI_PCR)/VIDEO_MODES);
/* Memory Control Register */
smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
SMI_MCR[pGD->mode], sizeof(SMI_MCR)/VIDEO_MODES);
/* Clock Control Register */
smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
SMI_CCR[pGD->mode], sizeof(SMI_CCR)/VIDEO_MODES);
/* Shadow VGA Register */
smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
SMI_SHVGA[pGD->mode], sizeof(SMI_SHVGA)/VIDEO_MODES);
/* General Purpose Register */
smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
SMI_GPR[pGD->mode], sizeof(SMI_GPR)/VIDEO_MODES);
/* Hardware Cusor Register */
smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
SMI_HCR[pGD->mode], sizeof(SMI_HCR)/VIDEO_MODES);
/* Flat Panel Register */
smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
SMI_FPR[pGD->mode], sizeof(SMI_FPR)/VIDEO_MODES);
/* CRTC Register */
smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
SMI_CRTCR[pGD->mode], sizeof(SMI_CRTCR)/VIDEO_MODES);
/* Graphics Controller Register */
smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF,
SMI_GCR, sizeof(SMI_GCR));
/* Patch memory and refresh settings for SMI710 */
if (device_id == PCI_DEVICE_ID_SMI_710)
{
unsigned char reg = smiRead (0x3c4, 0x62);
/* external memory disabled */
smiWrite (0x3c4, 0x62, (reg & 0xfb));
/* memory clock */
smiWrite (0x3c4, 0x6a, 0x75);
}
/* Patch memory and refresh settings for SMI712 */
if (device_id == PCI_DEVICE_ID_SMI_712)
{
unsigned char reg = smiRead (0x3c4, 0x62);
/* IL runs at MCLK; 64bit bus; external memory disabled */
smiWrite (0x3c4, 0x62, (reg | 0xc4));
/* memory clock */
smiWrite (0x3c4, 0x6a, 0x80);
}
/* Patch clock settings for SMI810 */
if (device_id == PCI_DEVICE_ID_SMI_810)
{
/* clock control */
smiWrite (0x3c4, 0x69, 0x03);
}
/* Video processor default setup */
smiInitVideoProcessor ();
/* Capture port default setup */
smiInitCapturePort ();
/* Drawing engine default setup */
smiInitDrawingEngine ();
/* Turn on display */
smiWrite (0x3c4, 0x01, 0x01);
printf("Clearing VRAM\n");
/* Clear video memory */
i = pGD->memSize/4;
vm = (unsigned int *)pGD->pciBase;
/*VgaLinuxInit();
memregInit();*/
while(i--)
*vm++ = 0;
printf("mode=%x - %s\n", videomode, pGD->modeIdent);
return ((void*)&smi);
}
/*******************************************************************************
*
* Drawing engine fill on screen region
*/
void video_hw_rectfill (
unsigned int bpp, /* bytes per pixel */
unsigned int dst_x, /* dest pos x */
unsigned int dst_y, /* dest pos y */
unsigned int dim_x, /* frame width */
unsigned int dim_y, /* frame height */
unsigned int color /* fill color */
)
{
register GraphicDevice *pGD = (GraphicDevice *)&smi;
register unsigned int control;
dim_x *= bpp;
if(bpp == 1)
{
out16r ((pGD->dprBase + 0x001e), in16r(pGD->dprBase + 0x001e)&(~0x30));
}
else if(bpp==2)
{
out16r ((pGD->dprBase + 0x001e), in16r(pGD->dprBase + 0x001e)|0x10);
}
out32r ((pGD->dprBase + 0x0014), color);
out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
control = 0x0000ffff & in32r ((pGD->dprBase + 0x000c));
control |= 0x80010000;
out32r ((pGD->dprBase + 0x000c), control);
/* Wait for drawing processor */
do
{
out8_io ((pGD->isaBase + 0x3c4), 0x16);
} while (in8_io (pGD->isaBase + 0x3c5) & 0x08);
}
/*******************************************************************************
*
* Drawing engine bitblt with screen region
*/
void video_hw_bitblt (
unsigned int bpp, /* bytes per pixel */
unsigned int src_x, /* source pos x */
unsigned int src_y, /* source pos y */
unsigned int dst_x, /* dest pos x */
unsigned int dst_y, /* dest pos y */
unsigned int dim_x, /* frame width */
unsigned int dim_y /* frame height */
)
{
register GraphicDevice *pGD = (GraphicDevice *)&smi;
register unsigned int control;
dim_x *= bpp;
if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
{
out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
control = 0x88000000;
}
else
{
out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
control = 0x80000000;
}
out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
control |= (0x0000ffff & in32r ((pGD->dprBase + 0x000c)));
out32r ((pGD->dprBase + 0x000c), control);
/* Wait for drawing processor */
do
{
out8_io ((pGD->isaBase + 0x3c4), 0x16);
} while (in8_io (pGD->isaBase + 0x3c5) & 0x08);
}
/*******************************************************************************
*
* Set a RGB color in the LUT (8 bit index)
*/
void video_set_lut (
unsigned int index, /* color number */
unsigned char r, /* red */
unsigned char g, /* green */
unsigned char b /* blue */
)
{
register GraphicDevice *pGD = (GraphicDevice *)&smi;
out8_io (SMI_LUT_MASK, 0xff);
out8_io (SMI_LUT_START, (char)index);
out8_io (SMI_LUT_RGB, r>>2); /* red */
/*udelay (10);*/
taskDelay(10);
out8_io (SMI_LUT_RGB, g>>2); /* green */
/*udelay (10);*/
taskDelay(10);
out8_io (SMI_LUT_RGB, b>>2); /* blue */
/*udelay (10);*/
taskDelay(10);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -