summaryrefslogtreecommitdiff
path: root/src/rdc_extension.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rdc_extension.c')
-rw-r--r--src/rdc_extension.c575
1 files changed, 575 insertions, 0 deletions
diff --git a/src/rdc_extension.c b/src/rdc_extension.c
new file mode 100644
index 0000000..cba9c61
--- /dev/null
+++ b/src/rdc_extension.c
@@ -0,0 +1,575 @@
+/*
+ * 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>
+ */
+
+/*
+ * I N C L U D E S
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#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"
+
+#include "X11/Xproto.h" /* For Xextension */
+#include "extnsionst.h" /* For Xextension */
+#include "dixstruct.h" /* For Xextension */
+
+#include "rdc_extension.h"
+
+//#include <sys/ipc.h>
+//#include <sys/shm.h>
+
+CARD32 *inBufPtr, *outBufPtr ; /* For share memory use */
+
+/* Record screen number. */
+int g_ScreenNumber;
+
+
+/*
+ Query the RDCGFX_API version.
+*/
+static int ProcRDCGFXQueryVersion (ClientPtr client)
+{
+ xRDCGFXQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xRDCGFXQueryVersionReply);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = 2;
+ rep.minorVersion = 0;
+
+ if(client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+
+ WriteToClient(client, sizeof(xRDCGFXQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+
+/*
+ Receive and process the request from AP.
+*/
+static int ProcRDCGFXCommand(ClientPtr client)
+{
+ xRDCGFXCommandReq *req = (xRDCGFXCommandReq*)client->requestBuffer; register int n;
+ int i, ret;
+
+ REQUEST_SIZE_MATCH(*req);
+ /*if ((SIZEOF(xRDCGFXCommandReq) >> 2) != req->length) { \
+ int lengthword = req->length; \
+ SendErrToClient(client, FSBadLength, (pointer)&lengthword); \
+ return (FSBadLength); \
+ }*/
+
+ /* Get pointer to ExtensionEntry */
+ if(!CheckExtension(RDC_GFX_UT_EXTENSION_NAME)) return BadMatch;
+
+ /* Process the request. */
+ RDCGFXUtilityProc(req);
+
+ //req->reqType = X_Reply;
+ //req->length = (CARD16)(sizeof(xRDCGFXCommandReq) - sizeof(xGenericReply)) >> 2;
+ xGenericReply *reply = client->requestBuffer;
+ reply->type = X_Reply;
+ reply->length = 0;
+#if 0
+ if(client->swapped)
+ {
+ swapl(&req->length, n);
+ swapl(&req->util_cmd_id, n);
+ swapl(&req->result_header, n);
+
+ for(i = 0; i < req->outBufferSize; i++)
+ {
+ swapl(&req->outBuffer[i], n);
+ }
+ }
+#endif
+ //WriteToClient(client, sizeof(xRDCGFXCommandReq), (char *)req);
+ WriteToClient(client, sizeof(xGenericReply), (char *)reply);
+ return client->noClientException;
+}
+
+static void RDCGFXResetProc(ExtensionEntry* extEntry)
+{
+}
+
+static int ProcRDCGFXDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch(stuff->data)
+ {
+ case X_RDCGFXQueryVersion:
+ return ProcRDCGFXQueryVersion(client);
+ case X_RDCGFXCommand:
+ return ProcRDCGFXCommand(client);
+ }
+
+ return BadRequest;
+}
+
+void RDCDisplayExtensionInit(ScrnInfoPtr pScrn)
+{
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "==Enter RDCDisplayExtensionInit()== \n");
+
+ // init share memory
+ int shm_in_id, shm_out_id ;
+ key_t in_key, out_key ;
+ char inBufName[32] = "/RDC/GFX/shm/inBuf" ;
+ char outBufName[32] = "/RDC/GFX/shm/outBuf" ;
+
+ in_key = ftok(inBufName, 4) ;
+ out_key = ftok(outBufName, 4) ;
+ shm_in_id = shmget(in_key, 4096, IPC_CREAT) ;
+ shm_out_id = shmget(out_key, 4096, IPC_CREAT) ;
+ inBufPtr = (CARD32 *) shmat(shm_in_id, NULL, 0) ;
+ outBufPtr = (CARD32 *) shmat(shm_out_id, NULL, 0) ;
+
+ if(NULL == CheckExtension(RDC_GFX_UT_EXTENSION_NAME))
+ {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 6, "== check point 1== \n");
+ /* if extension doesn't exist, add it */
+ if (!AddExtension(RDC_GFX_UT_EXTENSION_NAME, 0, 0,
+ ProcRDCGFXDispatch,
+ ProcRDCGFXDispatch,
+ RDCGFXResetProc,
+ StandardMinorOpcode))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to add RDCGFX extension\n");
+ return;
+ }
+ }
+ else
+ {
+ /* else if extension exists */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "error: RDC GFX Extension Exists!\n");
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "==Exit RDCDisplayExtensionInit()== \n");
+}
+
+int RDCGFXUtilityProc(xRDCGFXCommandReq* req)
+{
+ ScrnInfoPtr pScrn = xf86Screens[g_ScreenNumber];
+ RDCRecPtr pRDC = RDCPTR(pScrn);
+
+ CBIOS_Extension CBIOSExtension;
+ CBIOS_ARGUMENTS CBiosArguments;
+
+ CBIOSExtension.pCBiosArguments = &CBiosArguments;
+ CBIOSExtension.IOAddress = (USHORT)(pRDC->RelocateIO) ;
+ CBIOSExtension.VideoVirtualAddress = (ULONG)(pRDC->FBVirtualAddr);
+ /*
+ STChen[2006.7.11]: In SAMM case, a driver controls a screen.
+ In the past, we have to move application's window to switch to correct driver.
+ So I add following step to detect which driver we should use to avoid this problem.
+
+ if (pRDC->pBIOSInfo->SAMM)
+ {
+ pScrn = RDCScreenSelection(pScrn, rep->primary_id, rep->secondary_id);
+ pRDC = RDCPTR(pScrn);
+ }
+ */
+
+ ULONG ulResult;
+
+ switch(req->util_cmd_id)
+ {
+ //
+ // Output devices function group
+ //
+ case UT_QUERY_SUPPORT_DEVICE: /* done */
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "DrvEscape: Query Device Support");
+
+ if (req->outBufferSize != sizeof(ULONG))
+ return UT_FAIL;
+
+ CBiosArguments.reg.x.AX = OEMFunction;
+ CBiosArguments.reg.x.BX = QueryBiosInfo;
+ if (CInt10(&CBIOSExtension))
+ {
+ ((UTDEVICELIST *) outBufPtr)->MERGE = (USHORT)CBiosArguments.reg.x.SI;
+ return (UT_SUCCESS);
+ }
+ else
+ {
+ return(UT_FAIL);
+ }
+ break;
+
+ case UT_QUERY_CONNECT_DEVICE: /* done */
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "DrvEscape: Query Device Connect");
+
+ if (req->outBufferSize != sizeof(ULONG))
+ return UT_FAIL;
+
+ CBiosArguments.reg.x.AX = OEMFunction;
+ CBiosArguments.reg.x.BX = QueryDeviceConnectStatus;
+ if (CInt10(&CBIOSExtension))
+ {
+ ((UTDEVICELIST *) outBufPtr)->MERGE = (USHORT)CBiosArguments.reg.x.BX;
+ return (UT_SUCCESS);
+ }
+ else
+ {
+ return(UT_FAIL);
+ }
+ break;
+
+ case UT_SET_DEVICE_ACT:
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "DrvEscape: Set Active Device");
+
+ if (req->inBufferSize != sizeof(UTDEVICELIST))
+ return UT_FAIL;
+
+ CBiosArguments.reg.x.AX = OEMFunction;
+ CBiosArguments.reg.x.BX = SetActiveDisplayDevice;
+
+ switch (inBufPtr[0] & 0xFFFF)
+ {
+ case 0x04: /* B_CRT */
+ CBiosArguments.reg.lh.CL = 3; /* CRT_ID */
+ break;
+ case 0x01: /* B_LCD */
+ CBiosArguments.reg.lh.CL = 1; /* LCD_ID */
+ break;
+ case 0x02: /* B_DVI */
+ CBiosArguments.reg.lh.CL = 2; /* DVI_ID */
+ break;
+ case 0x20: /* B_TV */
+ CBiosArguments.reg.lh.CL = 6; /* TV_ID */
+ break;
+ default:
+ CBiosArguments.reg.lh.CL = 0;
+ break;
+ }
+
+ if (CInt10(&CBIOSExtension))
+ {
+ return(UT_SUCCESS | UT_MODESET);
+ }
+ else
+ {
+ return(UT_FAIL);
+ }
+ break;
+
+ case UT_QUERY_ACT_DEVICE:
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "DrvEscape: Query active device");
+
+ if (req->outBufferSize != sizeof(UCHAR) * 2)
+ return UT_FAIL;
+
+ CBiosArguments.reg.x.AX = OEMFunction;
+ CBiosArguments.reg.x.BX = QueryDisplayPathInfo;
+ if (CInt10(&CBIOSExtension))
+ {
+ outBufPtr[0] = 0;
+ switch ((CBiosArguments.reg.ex.EBX & 0x000F0000) >> 16)
+ {
+ case 3: /* CRT_ID */
+ outBufPtr[0] |= 0x0004; /* B_CRT */
+ break;
+ case 1: /* LCD_ID */
+ outBufPtr[0] |= 0x0001; /* B_LCD */
+ break;
+ case 2: /* DVI_ID */
+ outBufPtr[0] |= 0x0002; /* B_DVI */
+ break;
+ case 6: /* TV_ID */
+ outBufPtr[0] |= 0x0020; /* B_TV */
+ break;
+ default:
+ break;
+ }
+ switch ((CBiosArguments.reg.ex.ECX & 0x000F0000) >> 16)
+ {
+ case 3: /* CRT_ID */
+ outBufPtr[0] |= 0x0004; /* B_CRT */
+ break;
+ case 1: /* LCD_ID */
+ outBufPtr[0] |= 0x0001; /* B_LCD */
+ break;
+ case 2: /* DVI_ID */
+ outBufPtr[0] |= 0x0002; /* B_DVI */
+ break;
+ case 6: /* TV_ID */
+ outBufPtr[0] |= 0x0020; /* B_TV */
+ break;
+ default:
+ break;
+ }
+
+ return (UT_SUCCESS);
+ }
+ else
+ {
+ return (UT_NOT_IMPLEMENT);
+ }
+ break;
+
+ /* Query hardware info function group */
+ case UT_QUERY_HW_INFO:
+ if (req->outBufferSize != sizeof(UTHWINFO))
+ return UT_FAIL;
+ {
+ UTHWINFO *pUTHWInfo = (UTHWINFO*)outBufPtr;
+ pUTHWInfo->ulVenderID = (ULONG)VENDOR_ID(pRDC->PciInfo);
+ pUTHWInfo->ulDeviceID = (ULONG)DEVICE_ID(pRDC->PciInfo);
+ pUTHWInfo->ulSubSystemID = (ULONG)SUBSYS_ID(pRDC->PciInfo);
+ pUTHWInfo->ulSubVenderID = (ULONG)SUBVENDOR_ID(pRDC->PciInfo);
+ pUTHWInfo->ulRevision = (ULONG)CHIP_REVISION(pRDC->PciInfo);
+ return (UT_SUCCESS);
+ break;
+ }
+ case UT_QUERY_BIOS_VERSION:
+ if (req->outBufferSize != sizeof(ULONG))
+ return UT_FAIL;
+
+ CBiosArguments.reg.x.AX = OEMFunction;
+ CBiosArguments.reg.x.BX = QueryBiosInfo;
+ if (CInt10(&CBIOSExtension))
+ {
+ outBufPtr[0] = CBiosArguments.reg.ex.EBX;
+ return(UT_SUCCESS);
+ }
+ else
+ {
+ return (UT_NOT_IMPLEMENT);
+ }
+ break;
+
+ case UT_QUERY_MEM_INFO:
+ if (req->outBufferSize != sizeof(ULONG))
+ return UT_FAIL;
+
+ outBufPtr[0] = pRDC->FbMapSize;
+ return(UT_SUCCESS);
+ break;
+
+ case UT_QUERY_CLK_SPEED:
+ if (req->outBufferSize != sizeof(CLKINFO))
+ return UT_FAIL;
+ {
+ CLKINFO *pCLKInfo = (CLKINFO*)outBufPtr;
+ CBiosArguments.reg.x.AX = OEMFunction;
+ CBiosArguments.reg.x.BX = QueryBiosInfo;
+ if (CInt10(&CBIOSExtension))
+ {
+ ULONG ulMCLK;
+ switch (CBiosArguments.reg.x.CX & 0x000F)
+ {
+ case 0:
+ ulMCLK = 266;
+ break;
+ case 1:
+ ulMCLK = 333;
+ break;
+ case 2:
+ ulMCLK = 400;
+ break;
+ case 3:
+ ulMCLK = 533;
+ break;
+ }
+ pCLKInfo->EngCLK = pCLKInfo->MemCLK = ulMCLK;
+ return(UT_SUCCESS);
+ }
+ else
+ {
+ return (UT_NOT_IMPLEMENT);
+ }
+ }
+ break;
+#if 0
+/*
+ case UT_QUERY_SAMM:
+ {
+ if (cjOut != sizeof(ULONG))
+ return UT_INVALID;
+
+ *(ULONG*)pvOut = ppdev->pMultiMon->bEnableSAMMMode;
+
+ return (UT_SUCCESS);
+ }
+ break;
+ case UT_SET_GAMMA:
+ {
+ if ((cjIn != sizeof(GammaTbl)) ||
+ (((pGammaTbl)pvIn)->dwSize != MAX_CLUT_SIZE))
+ return UT_INVALID;
+
+ if (!EngDeviceIoControl(ppdev->hDriver,
+ IOCTL_VIDEO_SET_COLOR_REGISTERS,
+ ((pGammaTbl)pvIn)->pClut,
+ ((pGammaTbl)pvIn)->dwSize,
+ NULL,
+ 0,
+ &ulResult))
+ {
+ return UT_SUCCESS;
+ }
+ else
+ return UT_FAIL;
+ }
+ break;
+ case UT_QUERY_GAMMA:
+ {
+ if ((cjOut != sizeof(GammaTbl)) ||
+ (((pGammaTbl)pvIn)->dwSize != MAX_CLUT_SIZE))
+ return UT_INVALID;
+
+ //
+ // Get Gamma value from Look up table
+ //
+ if (*(ULONG*)pvIn & CRT)
+ QueryRegistryValue(ppdev, CRTGamma, ((pGammaTbl)pvOut)->pClut, MAX_CLUT_SIZE);
+ else if (*(ULONG*)pvIn & LCD)
+ QueryRegistryValue(ppdev, LCDGamma, ((pGammaTbl)pvOut)->pClut, MAX_CLUT_SIZE);
+
+ return UT_SUCCESS;
+ }
+ break;
+*/
+#endif
+ case UT_SET_LCD_PWM:
+ if (req->inBufferSize != sizeof(UCHAR))
+ return UT_FAIL;
+
+ CBiosArguments.reg.x.AX = OEMFunction;
+ CBiosArguments.reg.x.BX = SetLCDPWMLevel;
+ CBiosArguments.reg.lh.CL = *(UCHAR*)req->inBuffer;
+ if (CInt10(&CBIOSExtension))
+ {
+ return(UT_SUCCESS);
+ }
+ break;
+
+ case UT_QUERY_LCD_PWM:
+ if (req->outBufferSize != sizeof(UCHAR))
+ return UT_FAIL;
+
+ CBiosArguments.reg.x.AX = OEMFunction;
+ CBiosArguments.reg.x.BX = QueryLCDPWMLevel;
+ if (CInt10(&CBIOSExtension))
+ {
+ *(UCHAR*)req->outBuffer = CBiosArguments.reg.lh.BL;
+ return(UT_SUCCESS);
+ }
+ break;
+
+ case UT_QUERY_LCD_SIZE:
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "DrvEscape: Query LCD Size");
+
+ if (req->outBufferSize != sizeof(LCDINFO))
+ return UT_FAIL;
+
+ // If color depth is 32 bpp, set it to 24.
+ int iDepth = pScrn->depth;
+ if (iDepth == 32) // 24 and 32 bpp should have same index 2.
+ iDepth = 24;
+
+ CBiosArguments.reg.x.AX = OEMFunction;
+ CBiosArguments.reg.x.BX = QueryLCDPanelSizeMode;
+ CBiosArguments.reg.lh.CL = (iDepth/8) - 1; // Color depth : 0(8 bpp), 1(16 bpp), 2(24/32 bpp)
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "Color depth is %d\n", CBiosArguments.reg.lh.CL);
+ if (CInt10(&CBIOSExtension))
+ {
+ PLCDINFO pLcdPanelSize;
+ pLcdPanelSize = (PLCDINFO) outBufPtr;
+ pLcdPanelSize->wLCDWidth = CBiosArguments.reg.ex.EDX & 0x0000FFFF;
+ pLcdPanelSize->wLCDHeight = CBiosArguments.reg.ex.EDX >> 16;
+ return(UT_SUCCESS);
+ }
+ break;
+#if 0
+/*
+ case UT_DECODER_JPEG_ENTRY:
+ {
+ DBG_GDI((0, "DrvEscape: UT_DECODER_JPEG_ENTRY"));
+ ulResult = ExtJpegDecoderEntry(pso, cjIn, pvIn, cjOut, pvOut);
+ return ulResult;
+ }
+ break;
+ case UT_ENCODER_JPEG_ENTRY:
+ {
+ DBG_GDI((0, "DrvEscape: UT_ENCODER_JPEG_ENTRY"));
+ ulResult = ExtJpegEncoderEntry(pso, cjIn, pvIn, cjOut, pvOut);
+ return ulResult;
+ }
+ break;
+ case UT_GET_USERMODE_DIRECTACCESS:
+ {
+ DBG_GDI((0, "DrvEscape: UT_GET_USERMODE_DIRECTACCESS")) ;
+ ulResult = ExtUserModeDirectAccess(pso, cjIn, pvIn, cjOut, pvOut) ;
+ return ulResult ;
+ }
+ break ;
+*/
+#endif
+ default:
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "RDCGFXUtilityProc: unknown command 0x%x", req->util_cmd_id);
+ break;
+ }
+
+ return UT_INVALID;
+}
+
+