1 /**********************************************************************
2 Copyright (c) Imagination Technologies Ltd.
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 ******************************************************************************/
23 #if !defined(SUPPORT_DRI_DRM)
25 #if defined(LDM_PLATFORM)
26 #define PVR_LDM_PLATFORM_MODULE
27 #define PVR_LDM_MODULE
30 #define PVR_LDM_PCI_MODULE
31 #define PVR_LDM_MODULE
36 #include <linux/init.h>
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/version.h>
41 #include <linux/proc_fs.h>
43 #if defined(SUPPORT_DRI_DRM)
47 #if defined(PVR_LDM_PLATFORM_MODULE)
48 #include <linux/platform_device.h>
51 #if defined(PVR_LDM_PCI_MODULE)
52 #include <linux/pci.h>
55 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
56 #include <asm/uaccess.h>
61 #include "kerneldisplay.h"
62 #include "kernelbuffer.h"
63 #include "sysconfig.h"
71 #include "pvr_debug.h"
75 #include "pvr_bridge_km.h"
77 #include "pvrmodule.h"
78 #include "private_data.h"
82 #if defined(SUPPORT_DRI_DRM)
85 #define DRVNAME "pvrsrvkm"
86 #define DEVNAME "pvrsrvkm"
88 #if defined(SUPPORT_DRI_DRM)
89 #define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
91 #define PRIVATE_DATA(pFile) ((pFile)->private_data)
94 MODULE_SUPPORTED_DEVICE(DEVNAME);
96 static IMG_INT debug = DBGPRIV_WARNING;
97 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
98 #include <linux/moduleparam.h>
99 module_param(debug, int, 0);
101 MODULE_PARM(debug, "i");
102 MODULE_PARM_DESC(debug, "Sets the level of debug output (default=0x4)");
107 extern IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
108 extern IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable);
110 EXPORT_SYMBOL(PVRGetDisplayClassJTable);
111 EXPORT_SYMBOL(PVRGetBufferClassJTable);
114 #if defined(PVR_LDM_MODULE)
115 static struct class *psPvrClass;
118 #if !defined(SUPPORT_DRI_DRM)
119 static IMG_INT AssignedMajorNumber;
121 static IMG_INT PVRSRVOpen(struct inode* pInode, struct file* pFile);
122 static IMG_INT PVRSRVRelease(struct inode* pInode, struct file* pFile);
124 static struct file_operations pvrsrv_fops = {
126 .unlocked_ioctl=PVRSRV_BridgeDispatchKM,
128 .release=PVRSRVRelease,
133 struct mutex gPVRSRVLock;
135 IMG_UINT32 gui32ReleasePID;
137 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
138 static IMG_UINT32 gPVRPowerLevel;
141 #if defined(PVR_LDM_MODULE)
143 #if defined(PVR_LDM_PLATFORM_MODULE)
144 #define LDM_DEV struct platform_device
145 #define LDM_DRV struct platform_driver
148 #if defined(PVR_LDM_PCI_MODULE)
149 #define LDM_DEV struct pci_dev
150 #define LDM_DRV struct pci_driver
153 #if defined(PVR_LDM_PLATFORM_MODULE)
154 static IMG_INT PVRSRVDriverRemove(LDM_DEV *device);
155 static IMG_INT PVRSRVDriverProbe(LDM_DEV *device);
157 #if defined(PVR_LDM_PCI_MODULE)
158 static IMG_VOID PVRSRVDriverRemove(LDM_DEV *device);
159 static IMG_INT PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id);
161 static IMG_INT PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state);
162 static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *device);
163 static IMG_INT PVRSRVDriverResume(LDM_DEV *device);
165 #if defined(PVR_LDM_PCI_MODULE)
166 /* all supported platform ids */
167 struct pci_device_id powervr_id_table[] __devinitdata = {
168 { PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID_PLB) },
169 { PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID_TNC) },
173 MODULE_DEVICE_TABLE(pci, powervr_id_table);
176 static LDM_DRV powervr_driver = {
177 #if defined(PVR_LDM_PLATFORM_MODULE)
182 #if defined(PVR_LDM_PCI_MODULE)
184 .id_table = powervr_id_table,
186 .probe = PVRSRVDriverProbe,
187 #if defined(PVR_LDM_PLATFORM_MODULE)
188 .remove = PVRSRVDriverRemove,
190 #if defined(PVR_LDM_PCI_MODULE)
191 .remove = __devexit_p(PVRSRVDriverRemove),
193 .suspend = PVRSRVDriverSuspend,
194 .resume = PVRSRVDriverResume,
195 .shutdown = PVRSRVDriverShutdown,
198 LDM_DEV *gpsPVRLDMDev;
200 #if defined(MODULE) && defined(PVR_LDM_PLATFORM_MODULE)
202 static IMG_VOID PVRSRVDeviceRelease(struct device *pDevice)
204 PVR_UNREFERENCED_PARAMETER(pDevice);
207 static struct platform_device powervr_device = {
211 .release = PVRSRVDeviceRelease
217 #if defined(PVR_LDM_PLATFORM_MODULE)
218 static IMG_INT PVRSRVDriverProbe(LDM_DEV *pDevice)
220 #if defined(PVR_LDM_PCI_MODULE)
221 static IMG_INT __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id)
226 PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice));
230 if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
236 if (SysAcquireData(&psSysData) != PVRSRV_OK)
238 gpsPVRLDMDev = pDevice;
240 if (SysInitialise() != PVRSRV_OK)
250 #if defined (PVR_LDM_PLATFORM_MODULE)
251 static IMG_INT PVRSRVDriverRemove(LDM_DEV *pDevice)
253 #if defined(PVR_LDM_PCI_MODULE)
254 static IMG_VOID __devexit PVRSRVDriverRemove(LDM_DEV *pDevice)
259 PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice));
261 if (SysAcquireData(&psSysData) == PVRSRV_OK)
263 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
264 if (gPVRPowerLevel != 0)
266 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
272 SysDeinitialise(psSysData);
274 gpsPVRLDMDev = IMG_NULL;
278 if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
284 #if defined (PVR_LDM_PLATFORM_MODULE)
287 #if defined (PVR_LDM_PCI_MODULE)
293 static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *pDevice)
295 PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
297 (IMG_VOID) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
303 #if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
304 #if defined(SUPPORT_DRI_DRM)
305 IMG_INT PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state)
307 static IMG_INT PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state)
310 #if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
311 PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice));
313 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
322 #if defined(SUPPORT_DRI_DRM)
323 IMG_INT PVRSRVDriverResume(struct drm_device *pDevice)
325 static IMG_INT PVRSRVDriverResume(LDM_DEV *pDevice)
328 #if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
329 PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice));
331 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
341 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)
342 IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
344 IMG_CHAR data_buffer[2];
345 IMG_UINT32 PVRPowerLevel;
347 if (count != sizeof(data_buffer))
353 if (copy_from_user(data_buffer, buffer, count))
355 if (data_buffer[count - 1] != '\n')
357 PVRPowerLevel = data_buffer[0] - '0';
358 if (PVRPowerLevel != gPVRPowerLevel)
360 if (PVRPowerLevel != 0)
362 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
369 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
375 gPVRPowerLevel = PVRPowerLevel;
381 #ifdef PVR_PROC_USE_SEQ_FILE
382 void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el)
384 seq_printf(sfile, "%lu\n", gPVRPowerLevel);
388 IMG_INT PVRProcGetPowerLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data)
391 *start = (IMG_CHAR *)1;
392 return printAppend(page, count, 0, "%lu\n", gPVRPowerLevel);
401 #if defined(SUPPORT_DRI_DRM)
402 IMG_INT PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pFile)
404 static IMG_INT PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile)
407 PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
408 IMG_HANDLE hBlockAlloc;
409 IMG_INT iRet = -ENOMEM;
412 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
413 PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
416 #if defined(SUPPORT_DRI_DRM)
417 PVR_UNREFERENCED_PARAMETER(dev);
419 PVR_UNREFERENCED_PARAMETER(pInode);
422 mutex_lock(&gPVRSRVLock);
424 ui32PID = OSGetCurrentProcessIDKM();
426 if (PVRSRVProcessConnect(ui32PID) != PVRSRV_OK)
429 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
430 psEnvPerProc = PVRSRVPerProcessPrivateData(ui32PID);
431 if (psEnvPerProc == IMG_NULL)
433 PVR_DPF((PVR_DBG_ERROR, "%s: No per-process private data", __FUNCTION__));
438 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
439 sizeof(PVRSRV_FILE_PRIVATE_DATA),
440 (IMG_PVOID *)&psPrivateData,
442 "File Private Data");
444 if(eError != PVRSRV_OK)
447 #if defined(PVR_SECURE_FD_EXPORT)
448 psPrivateData->hKernelMemInfo = NULL;
450 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
451 psPrivateData->psDRMFile = pFile;
453 list_add_tail(&psPrivateData->sDRMAuthListItem, &psEnvPerProc->sDRMAuthListHead);
455 psPrivateData->ui32OpenPID = ui32PID;
456 psPrivateData->hBlockAlloc = hBlockAlloc;
457 PRIVATE_DATA(pFile) = psPrivateData;
460 mutex_unlock(&gPVRSRVLock);
465 #if defined(SUPPORT_DRI_DRM)
466 IMG_INT PVRSRVRelease(struct drm_device unref__ *dev, struct drm_file *pFile)
468 static IMG_INT PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile)
471 PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
473 #if defined(SUPPORT_DRI_DRM)
474 PVR_UNREFERENCED_PARAMETER(dev);
476 PVR_UNREFERENCED_PARAMETER(pInode);
479 mutex_lock(&gPVRSRVLock);
481 psPrivateData = PRIVATE_DATA(pFile);
483 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
484 list_del(&psPrivateData->sDRMAuthListItem);
488 gui32ReleasePID = psPrivateData->ui32OpenPID;
489 PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID);
492 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
493 sizeof(PVRSRV_FILE_PRIVATE_DATA),
494 psPrivateData, psPrivateData->hBlockAlloc);
496 PRIVATE_DATA(pFile) = NULL;
498 mutex_unlock(&gPVRSRVLock);
503 #if defined(SUPPORT_DRI_DRM)
504 IMG_INT PVRCore_Init(IMG_VOID)
506 static IMG_INT __init PVRCore_Init(IMG_VOID)
510 #if !defined(PVR_LDM_MODULE)
513 struct device *psDev;
517 PVR_TRACE(("PVRCore_Init"));
519 mutex_init(&gPVRSRVLock);
522 PVRDebugSetLevel(debug);
525 if (CreateProcEntries ())
531 if (PVROSFuncInit() != PVRSRV_OK)
537 PVRLinuxMUtilsInit();
539 if(LinuxMMInit() != PVRSRV_OK)
549 #if defined(PVR_LDM_MODULE)
551 #if defined(PVR_LDM_PLATFORM_MODULE)
552 if ((error = platform_driver_register(&powervr_driver)) != 0)
554 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error));
560 if ((error = platform_device_register(&powervr_device)) != 0)
562 platform_driver_unregister(&powervr_driver);
564 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error));
571 #if defined(PVR_LDM_PCI_MODULE)
572 if ((error = pci_register_driver(&powervr_driver)) != 0)
574 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error));
582 if ((eError = SysInitialise()) != PVRSRV_OK)
585 #if defined(TCF_REV) && (TCF_REV == 110)
586 if(eError == PVRSRV_ERROR_NOT_SUPPORTED)
588 printk("\nAtlas wrapper (FPGA image) version mismatch");
596 #if !defined(SUPPORT_DRI_DRM)
597 AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops);
599 if (AssignedMajorNumber <= 0)
601 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number"));
607 PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
610 #if defined(PVR_LDM_MODULE)
612 psPvrClass = class_create(THIS_MODULE, "pvr");
614 if (IS_ERR(psPvrClass))
616 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create class (%ld)", PTR_ERR(psPvrClass)));
618 goto unregister_device;
621 psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0),
622 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
628 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev)));
636 #if defined(PVR_LDM_MODULE)
638 class_destroy(psPvrClass);
640 unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME);
642 #if !defined(SUPPORT_DRI_DRM)
645 #if defined(PVR_LDM_MODULE)
646 #if defined(PVR_LDM_PCI_MODULE)
647 pci_unregister_driver(&powervr_driver);
650 #if defined (PVR_LDM_PLATFORM_MODULE)
652 platform_device_unregister(&powervr_device);
654 platform_driver_unregister(&powervr_driver);
662 SysAcquireData(&psSysData);
663 if (psSysData != IMG_NULL)
665 SysDeinitialise(psSysData);
681 #if defined(SUPPORT_DRI_DRM)
682 IMG_VOID PVRCore_Cleanup(IMG_VOID)
684 static IMG_VOID __exit PVRCore_Cleanup(IMG_VOID)
689 PVR_TRACE(("PVRCore_Cleanup"));
691 SysAcquireData(&psSysData);
693 #if defined(PVR_LDM_MODULE)
694 device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
695 class_destroy(psPvrClass);
698 #if !defined(SUPPORT_DRI_DRM)
699 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
702 unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME)
703 #if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
708 PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber));
713 #if defined(PVR_LDM_MODULE)
715 #if defined(PVR_LDM_PCI_MODULE)
716 pci_unregister_driver(&powervr_driver);
719 #if defined (PVR_LDM_PLATFORM_MODULE)
721 platform_device_unregister(&powervr_device);
723 platform_driver_unregister(&powervr_driver);
727 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
728 if (gPVRPowerLevel != 0)
730 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
737 SysDeinitialise(psSysData);
750 PVR_TRACE(("PVRCore_Cleanup: unloading"));
753 #if !defined(SUPPORT_DRI_DRM)
754 module_init(PVRCore_Init);
755 module_exit(PVRCore_Cleanup);