📄 i81xhw.c
字号:
/* i81xHw.c - Intel 81x graphics driver for all modes *//* Copyright 2000 - 2003 Wind River Systems, Inc. All Rights Reserved *//*modification history--------------------01b,18jun03,jlb Updated to Tornado 2.201a,28oct01,jlb written - based on work from dmh.*//*DESCRIPTIONThis file provides general functions to access and set the Intel 81x intovarious modes. The functions within this file are common to bothdirect and indexed color modes.*/#include <vxWorks.h>#include <math.h>#include <ugl/ugl.h>#include <string.h>#include <ugl/driver/graphics/intel/i81x.h>#include <ugl/driver/graphics/intel/i81xGart.h>#if DEBUG#include <stdio.h>#include <sysLib.h>#endif#define MAX_VCO_FREQ 600.0#define TARGET_MAX_N 30#define REF_FREQ 24.0#define CALC_VCLK(m,n,p) (double)m / ((double)n * (1 << p)) * 4 * REF_FREQstatic void i81xHwSetExtendedRegs(ModeLine * cv, i81xHwRegSet* xset);static STATUS i81xHwClock2(double freq, i81xHwRegSet* xset);unsigned int I810CalcWatermark( i81x_DRIVER* pI810, double freq, BOOL dcache );/******************************************************************************* i81xHwDWordOut - write a double word to device*** RETURNS: N/A***/void i81xHwDWordOut ( i81x_DRIVER * pDriver, /* Driver structure */ UINT32 reg, /* Regsiert to write to */ UINT32 val /* Value to write to register */ ) { UINT32 offset = pDriver->svga.vgahw.mmoffset; *(volatile unsigned long int *)(offset + reg) = (val); }/******************************************************************************* i81xHwByteOut - write a byte to device*** RETURNS: N/A***/void i81xHwByteOut ( i81x_DRIVER * pDriver, /* Driver structure */ UINT32 reg, /* Regsiert to write to */ UINT8 val /* Value to write to register */ ) { UINT32 offset = pDriver->svga.vgahw.mmoffset; *(volatile unsigned char *)(offset + reg) = (val); }/******************************************************************************* i81xHwStoreRegs - store device regsiters to an array*** RETURNS: N/A***/void i81xHwStoreRegs ( i81x_DRIVER * pDriver, /* Driver structure */ i81xHwRegSet* xset /* Structure to store registers */ ) { VgaHw* vgaHwp = &pDriver->svga.vgahw; vgaStoreRegSet(vgaHwp, &xset->vgaset); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x30); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr30); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x31); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr31); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x32); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr32); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x33); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr33); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x35); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr35); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x39); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr39); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x40); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr40); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x41); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr41); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x42); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr42); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x70); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr70); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x82); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr82); vgaOutByte(vgaHwp, VGA_GRAPHICS_REG, 0x10); vgaOutByte(vgaHwp, VGA_GRAPHICS_DATA, xset->gr10); vgaOutByte(vgaHwp, VGA_GRAPHICS_REG, 0x11); vgaOutByte(vgaHwp, VGA_GRAPHICS_DATA, xset->gr11); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x80); vgaOutByte(vgaHwp, VGA_CRTC_DATA, xset->cr80); i81xHwDWordOut(pDriver, 0x6008, (xset->VideoClk_N << 16) | xset->VideoClk_M); i81xHwByteOut(pDriver, 0x6012, xset->VideoClk_DivisorSel); }/******************************************************************************* i81xHwLoadRegs - load device registers from an array*** RETURNS: N/A***/void i81xHwLoadRegs ( i81x_DRIVER * pDriver, /* Driver structure */ i81xHwRegSet* xset /* Array containing reg values */ ) { VgaHw* vgaHwp = &pDriver->svga.vgahw; vgaLoadRegSet(vgaHwp, &xset->vgaset); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x30); xset->cr30 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x31); xset->cr31 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x32); xset->cr32 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x33); xset->cr33 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x35); xset->cr35 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x39); xset->cr39 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x40); xset->cr40 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x41); xset->cr41 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x42); xset->cr42 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x70); xset->cr70 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x80); xset->cr80 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_CRTC_REG, 0x82); xset->cr82 = vgaInByte(vgaHwp, VGA_CRTC_DATA); vgaOutByte(vgaHwp, VGA_GRAPHICS_REG, 0x10); xset->gr10 = vgaInByte(vgaHwp, VGA_GRAPHICS_DATA); vgaOutByte(vgaHwp, VGA_GRAPHICS_REG, 0x11); xset->gr11 = vgaInByte(vgaHwp, VGA_GRAPHICS_DATA); }/******************************************************************************* i81xHwClock2 - calculate clock value*** RETURNS: N/A***/static STATUS i81xHwClock2 ( double freq, /* Clock frequency */ i81xHwRegSet* xset /* Store calculated values */ ) { int m, n, p; double f_out, f_best; double f_err; double f_vco; int m_best = 0, n_best = 0, p_best = 0; double f_target = freq; double err_max = 0.005; double err_target = 0.001; double err_best = 999999.0; p_best = p = log(MAX_VCO_FREQ/f_target)/log((double)2); f_vco = f_target * (1 << p); n = 2; do { n++; m = f_vco / (REF_FREQ / (double)n) / (double)4.0 + 0.5; if (m < 3) m = 3; f_out = CALC_VCLK(m,n,p); f_err = 1.0 - (f_target/f_out); if (fabs(f_err) < err_max) { m_best = m; n_best = n; f_best = f_out; err_best = f_err; } } while ((fabs(f_err) >= err_target) && ((n <= TARGET_MAX_N) || (fabs(err_best) > err_max))); if (fabs(f_err) < err_target) { m_best = m; n_best = n; } xset->VideoClk_M = (m_best-2) & 0x3FF; xset->VideoClk_N = (n_best-2) & 0x3FF; xset->VideoClk_DivisorSel = (p_best << 4);#if DEBUG printf("Setting dot clock to %.1f MHz " "[ 0x%x 0x%x 0x%x ] " "[ %d %d %d ]\n", CALC_VCLK(m_best,n_best,p_best), xset->VideoClk_M, xset->VideoClk_N, xset->VideoClk_DivisorSel, m_best, n_best, p_best);#endif return OK; /* maybe later we will add code to detect really bad clocks */ }/******************************************************************************* i81xHwSetExtendedRegs - set up extended registers for a mode*** RETURNS: N/A***/static void i81xHwSetExtendedRegs ( ModeLine * cv, /* mode */ i81xHwRegSet* xset /* array to contain register values */ ) { unsigned int pixperchar = 9 - (xset->vgaset.sequencer[1] & 1); vgaSetRegisters(cv, &xset->vgaset); xset->cr30 = cv->vtotal >> 8; xset->cr31 = cv->vdisplay >> 8; xset->cr32 = cv->vsyncstart >> 8; xset->cr33 = cv->vblankstart >> 8; xset->cr35 = (cv->htotal / pixperchar) >> 8; xset->cr39 = (cv->hblankend / pixperchar) >> 6; /* set some some extended registers */ xset->gr10 = 0xa; xset->gr11 = 0x0; /* xset->cr80 = 0x1; */ }/******************************************************************************* i81xHwUglModeCheck - validate a mode*** RETURNS: N/A***/STATUS i81xHwUglModeCheck ( /* Driver structure */ i81x_DRIVER * pDriver ) { UGL_GENERIC_DRIVER * pGen = (UGL_GENERIC_DRIVER *)pDriver; if((pGen->ugi.pMode->colorDepth != 8) && (pGen->ugi.pMode->colorDepth != 16)) return(ERROR); if(pGen->ugi.pMode->monitorType != UGL_MODE_CRT) return(ERROR); if(vgaGetModeLine(pGen->ugi.pMode) == NULL) return(ERROR); else return(OK); }/******************************************************************************* i81xHwSetMode - set hardware in a mode** The specified mode must be set in the device structure <pDriver>** RETURNS: N/A***/void i81xHwSetMode ( i81x_DRIVER * pDriver /* Device structure */ ) { char tmp; UINT32 pixconf; i81xHwRegSet xset; ModeLine* pModeLine; VgaHw* vgaHwp = &pDriver->svga.vgahw; UGL_GENERIC_DRIVER * pGen = (UGL_GENERIC_DRIVER *)pDriver; UGL_MODE* pMode = pGen->ugi.pMode; pModeLine = vgaGetModeLine(pMode); i81xHwLoadRegs(pDriver, &pDriver->regSet); memcpy(&xset, &pDriver->regSet, sizeof(pDriver->regSet)); vgaSetGraphicsMode(pModeLine, &xset.vgaset); if(pModeLine->freq == 25.175) xset.vgaset.msr = (~0xc & xset.vgaset.msr); /* 25Mhz fixed */ else if(pModeLine->freq == 28) xset.vgaset.msr = (~0x8 & xset.vgaset.msr) | 0x04; /* 28Mhz fixed */ else xset.vgaset.msr = (xset.vgaset.msr | 0x08); /* programmable dot clock */ i81xHwSetExtendedRegs(pModeLine, &xset); i81xHwClock2(pModeLine->freq, &xset); switch(pMode->colorDepth) { case 15: pixconf = 0x00141003; xset.vgaset.crtc[0x13] = pMode->width >> 2; break; case 16: pixconf = 0x00151003; xset.vgaset.crtc[0x13] = pMode->width >> 2; break; case 8: default: pixconf = 0x00121003; xset.vgaset.crtc[0x13] = pMode->width >> 3; break; } /* disable video output by setting Screen Out bit */ vgaOutByte(vgaHwp, VGA_SEQUENCER_REG, 0x1); tmp = vgaInByte(vgaHwp, VGA_SEQUENCER_DATA); vgaOutByte(vgaHwp, VGA_SEQUENCER_DATA, tmp | 0x20); i81xHwStoreRegs(pDriver, &xset); taskDelay(1); /* wait a moment as documented in PIXCONF docs */ i81xHwDWordOut(pDriver, FW_BLC, I810CalcWatermark(pDriver, pModeLine->freq, FALSE)); i81xHwDWordOut(pDriver, PIXCONF, pixconf); /* re-enable video output */ vgaOutByte(vgaHwp, VGA_SEQUENCER_REG, 0x1); tmp = vgaInByte(vgaHwp, VGA_SEQUENCER_DATA); vgaOutByte(vgaHwp, VGA_SEQUENCER_DATA, tmp & ~0x20); taskDelay(1); vgaOutByte(vgaHwp, VGA_CRTC_REG,0x80); vgaOutByte(vgaHwp, VGA_CRTC_DATA,1); }/******************************************************************************* i81xHwPrevMode - restore a previous mode*** RETURNS: N/A***/void i81xHwPrevMode ( i81x_DRIVER * pDriver /* Device structure */ ) { char tmp; VgaHw* vgaHwp = &pDriver->svga.vgahw; /* disable video output by setting Screen Out bit */ vgaOutByte(vgaHwp, VGA_SEQUENCER_REG, 0x1); tmp = vgaInByte(vgaHwp, VGA_SEQUENCER_DATA); vgaOutByte(vgaHwp, VGA_SEQUENCER_DATA, tmp | 0x20); i81xHwStoreRegs(pDriver, &pDriver->regSet); i81xHwDWordOut(pDriver, PIXCONF, 0); /* re-enable video output */ vgaOutByte(vgaHwp, VGA_SEQUENCER_REG, 0x1); tmp = vgaInByte(vgaHwp, VGA_SEQUENCER_DATA); vgaOutByte(vgaHwp, VGA_SEQUENCER_DATA, tmp & ~0x20); }#if DEBUG/******************************************************************************* i81xHwShowRegSet - print out register values*** RETURNS: N/A***/static void i81xHwShowRegSet ( i81xHwRegSet* xset ) { printf("CR30: 0x%x\n", 0xff & xset->cr30); printf("CR31: 0x%x\n", 0xff & xset->cr31); printf("CR32: 0x%x\n", 0xff & xset->cr32); printf("CR33: 0x%x\n", 0xff & xset->cr33); printf("CR35: 0x%x\n", 0xff & xset->cr35); printf("CR39: 0x%x\n", 0xff & xset->cr39); printf("CR40: 0x%x\n", 0xff & xset->cr40); printf("CR41: 0x%x\n", 0xff & xset->cr41); printf("CR42: 0x%x\n", 0xff & xset->cr42); printf("CR70: 0x%x\n", 0xff & xset->cr70); printf("CR80: 0x%x\n", 0xff & xset->cr80); printf("GR10: 0x%x\n", 0xff & xset->gr10); printf("GR11: 0x%x\n", 0xff & xset->gr11); }/******************************************************************************* i81xHwShow - print out register values*** RETURNS: N/A***/void i81xHwShow() { i81xHwRegSet xset; i81xHwLoadRegs(NULL, &xset); i81xHwShowRegSet(&xset); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -