diff options
Diffstat (limited to 'src/rdc_vgatool.c')
-rw-r--r-- | src/rdc_vgatool.c | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/src/rdc_vgatool.c b/src/rdc_vgatool.c new file mode 100644 index 0000000..0d84bad --- /dev/null +++ b/src/rdc_vgatool.c @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2009 RDC Semiconductor Co.,Ltd + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + * + * For technical support : + * <jason.lin@rdc.com.tw> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86RAC.h" +#include "xf86cmap.h" +#include "compiler.h" +#include "mibstore.h" +#include "vgaHW.h" +#include "mipointer.h" +#include "micmap.h" + +#include "fb.h" +#include "regionstr.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> +#include "vbe.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +/* framebuffer offscreen manager */ +#include "xf86fbman.h" + +/* include xaa includes */ +#include "xaa.h" +#include "xaarop.h" + +/* H/W cursor support */ +#include "xf86Cursor.h" + +/* Driver specific headers */ +#include "rdc.h" + +/* Prototype type declaration*/ +void vRDCOpenKey(ScrnInfoPtr pScrn); +Bool bRDCRegInit(ScrnInfoPtr pScrn); +ULONG GetVRAMInfo(ScrnInfoPtr pScrn); +Bool RDCFilterModeByBandWidth(ScrnInfoPtr pScrn, DisplayModePtr mode); +void vSetStartAddressCRT1(RDCRecPtr pRDC, ULONG base); +void vRDCLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual); +void RDCDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); +ULONG RDCGetMemBandWidth(ScrnInfoPtr pScrn); + + +void +vRDCOpenKey(ScrnInfoPtr pScrn) +{ + RDCRecPtr pRDC = RDCPTR(pScrn); + + SetIndexReg(CRTC_PORT,0x80, 0xA8); +} + +Bool +bRDCRegInit(ScrnInfoPtr pScrn) +{ + RDCRecPtr pRDC = RDCPTR(pScrn); + + /* Enable MMIO */ + SetIndexRegMask(CRTC_PORT,0xA1, 0xFF, 0x04); + + return (TRUE); +} + +ULONG +GetVRAMInfo(ScrnInfoPtr pScrn) +{ + RDCRecPtr pRDC = RDCPTR(pScrn); + UCHAR jReg; + + vRDCOpenKey(pScrn); + + GetIndexRegMask(CRTC_PORT, 0xAA, 0xFF, jReg); + + switch (jReg & 0x07) + { + case 0x00: + return (VIDEOMEM_SIZE_08M); + case 0x01: + return (VIDEOMEM_SIZE_16M); + case 0x02: + return (VIDEOMEM_SIZE_32M); + case 0x03: + return (VIDEOMEM_SIZE_64M); + case 0x04: + return (VIDEOMEM_SIZE_128M); + } + + return (DEFAULT_VIDEOMEM_SIZE); +} + +Bool +RDCFilterModeByBandWidth(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + ULONG RequestMemBandWidth = 0; + RDCRecPtr pRDC = RDCPTR(pScrn); + Bool Flags = MODE_OK; + + RequestMemBandWidth = mode->Clock * ((pScrn->bitsPerPixel + 7) >> 3) / 1000; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, InfoLevel, + "==Filter Mode() Memory bandwidth request %u MB==\n", RequestMemBandWidth); + + if (RequestMemBandWidth > pRDC->MemoryBandwidth) + Flags = MODE_MEM; + + return(Flags); +} + +void +vSetStartAddressCRT1(RDCRecPtr pRDC, ULONG base) +{ + /* base is byte aligned, flipping base address is quad-word aligned */ + ULONG uc1stFlippingCmdReg; + + /* clear [27:3] base address of flipping control */ + uc1stFlippingCmdReg = *(ULONG *)MMIOREG_1ST_FLIP & (~MASK_1ST_FLIP_BASE); + + /* combine base with uc1stFlippingCmdReg */ + uc1stFlippingCmdReg |= (base & MASK_1ST_FLIP_BASE); + + *(ULONG *)MMIOREG_1ST_FLIP = uc1stFlippingCmdReg; +} + +ULONG +RDCGetMemBandWidth(ScrnInfoPtr pScrn) +{ + CBIOS_ARGUMENTS CBiosArguments; + CBIOS_Extension CBiosExtension; + RDCRecPtr pRDC = RDCPTR(pScrn); + + ULONG ulDRAMBusWidth, DRAMEfficiency; + ULONG ulMCLK, ulDRAMBandwidth, ActualDRAMBandwidth; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 7, + "==Device ID 0x%x==\n",DEVICE_ID(pRDC->PciInfo)); + + switch(DEVICE_ID(pRDC->PciInfo)) + { + case PCI_CHIP_M2010_A0: + /* Bus width is 16bit, and DRAM utilization is 30% */ + ulDRAMBusWidth = 16; + DRAMEfficiency = 300; + break; + case PCI_CHIP_M2011: + /* Bus width is 32bit, and DRAM utilization is 60% */ + ulDRAMBusWidth = 32; + DRAMEfficiency = 600; + break; + default: + /* Bus width is 16bit, and DRAM utilization is 60% */ + ulDRAMBusWidth = 16; + DRAMEfficiency = 600; + } + + CBiosExtension.pCBiosArguments = &CBiosArguments; + CBiosExtension.IOAddress = (USHORT)(pRDC->RelocateIO); + CBiosExtension.VideoVirtualAddress = (ULONG)(pRDC->FBVirtualAddr); + + vRDCOpenKey(pScrn); + + CBiosExtension.pCBiosArguments->reg.x.AX = 0x4F14; + CBiosExtension.pCBiosArguments->reg.x.BX = 0x0000; + CInt10(&CBiosExtension); + + if ((CBiosExtension.pCBiosArguments->reg.lh.CL & (0x07)) == 0x03) + { + ulMCLK = 266; + } + else + { + ulMCLK = 200; + } + + /* Get Bandwidth */ + /* Use DDRII DRAM, so multiply 2 */ + /* Translate DRAM Bandwidth to byte, so div 8*/ + ulDRAMBandwidth = ulMCLK * ulDRAMBusWidth * 2 / 8; + + ActualDRAMBandwidth = ulDRAMBandwidth * DRAMEfficiency / 1000; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, InfoLevel, + "==Get actual memory bandwidth request %u MB==\n", ActualDRAMBandwidth); + + return(ActualDRAMBandwidth); +} + +void +vRDCLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, + VisualPtr pVisual) +{ + RDCRecPtr pRDC = RDCPTR(pScrn); + int i, j, index; + UCHAR DACIndex, DACR, DACG, DACB; + + switch (pScrn->bitsPerPixel) + { + case 15: + for(i=0; i<numColors; i++) + { + index = indices[i]; + for(j=0; j<8; j++) + { + DACIndex = (index * 8) + j; + DACR = colors[index].red << (8- pScrn->rgbBits); + DACG = colors[index].green << (8- pScrn->rgbBits); + DACB = colors[index].blue << (8- pScrn->rgbBits); + + VGA_LOAD_PALETTE_INDEX (DACIndex, DACR, DACG, DACB); + } + } + break; + + case 16: + for(i=0; i<numColors; i++) + { + index = indices[i]; + for(j=0; j<4; j++) + { + DACIndex = (index * 4) + j; + DACR = colors[index/2].red << (8- pScrn->rgbBits); + DACG = colors[index].green << (8- pScrn->rgbBits); + DACB = colors[index/2].blue << (8- pScrn->rgbBits); + + VGA_LOAD_PALETTE_INDEX (DACIndex, DACR, DACG, DACB); + } + } + break; + + case 24: + for(i=0; i<numColors; i++) + { + index = indices[i]; + DACIndex = index; + DACR = colors[index].red; + DACG = colors[index].green; + DACB = colors[index].blue; + + VGA_LOAD_PALETTE_INDEX (DACIndex, DACR, DACG, DACB); + } + break; + + default: + for(i=0; i<numColors; i++) + { + index = indices[i]; + DACIndex = index; + DACR = colors[index].red >> (8 - pScrn->rgbBits); + DACG = colors[index].green >> (8 - pScrn->rgbBits); + DACB = colors[index].blue >> (8 - pScrn->rgbBits); + + VGA_LOAD_PALETTE_INDEX (DACIndex, DACR, DACG, DACB); + } + } /* end of switch */ +} /* end of vRDCLoadPalette */ + +void +RDCDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) +{ + RDCRecPtr pRDC; + UCHAR SEQ01, CRB6; + + pRDC = RDCPTR(pScrn); + SEQ01=CRB6=0; + + vRDCOpenKey(pScrn); + + switch (PowerManagementMode) + { + case DPMSModeOn: + /* Screen: On; HSync: On, VSync: On */ + SEQ01 = 0x00; + CRB6 = 0x00; + break; + + case DPMSModeStandby: + /* Screen: Off; HSync: Off, VSync: On */ + SEQ01 = 0x20; + CRB6 = 0x01; + break; + + case DPMSModeSuspend: + /* Screen: Off; HSync: On, VSync: Off */ + SEQ01 = 0x20; + CRB6 = 0x02; + break; + + case DPMSModeOff: + /* Screen: Off; HSync: Off, VSync: Off */ + SEQ01 = 0x20; + CRB6 = 0x03; + break; + } + + SetIndexRegMask(SEQ_PORT,0x01, 0xDF, SEQ01); + SetIndexRegMask(CRTC_PORT,0xB6, 0xFC, CRB6); +} + |