summaryrefslogtreecommitdiff
path: root/src/rdc_vgatool.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rdc_vgatool.c')
-rw-r--r--src/rdc_vgatool.c321
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);
+}
+