diff options
Diffstat (limited to 'src/rdc_extension.c')
-rw-r--r-- | src/rdc_extension.c | 575 |
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; +} + + |