1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
27 #ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
31 #include <linux/init.h>
32 #include <linux/kernel.h>
33 #include <linux/module.h>
34 #include <linux/version.h>
36 #include <linux/proc_fs.h>
38 #if defined(LDM_PLATFORM)
39 #include <linux/platform_device.h>
43 #include <linux/pci.h>
46 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
47 #include <asm/uaccess.h>
52 #include "kerneldisplay.h"
53 #include "kernelbuffer.h"
54 #include "syscommon.h"
59 #include "pvr_debug.h"
63 #include "pvr_bridge_km.h"
65 #include "pvrmodule.h"
67 #define DRVNAME "pvrsrvkm"
68 #define DEVNAME "pvrsrvkm"
70 MODULE_SUPPORTED_DEVICE(DEVNAME);
72 static int debug = DBGPRIV_WARNING;
73 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
74 #include <linux/moduleparam.h>
75 module_param(debug, int, 0);
77 MODULE_PARM(debug, "i");
78 MODULE_PARM_DESC(debug, "Sets the level of debug output (default=0x4)");
82 void PVRDebugSetLevel(IMG_UINT32 uDebugLevel);
84 extern IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *
86 extern IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *
88 EXPORT_SYMBOL(PVRGetDisplayClassJTable);
89 EXPORT_SYMBOL(PVRGetBufferClassJTable);
91 static int AssignedMajorNumber;
93 extern int PVRSRV_BridgeDispatchKM(struct inode *inode, struct file *file,
94 unsigned int cmd, unsigned long arg);
95 static int PVRSRVOpen(struct inode *pInode, struct file *pFile);
96 static int PVRSRVRelease(struct inode *pInode, struct file *pFile);
98 PVRSRV_LINUX_MUTEX gPVRSRVLock;
100 static struct file_operations pvrsrv_fops = {
102 ioctl: PVRSRV_BridgeDispatchKM,
104 release:PVRSRVRelease,
108 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
109 static IMG_UINT32 gPVRPowerLevel;
112 #if defined(LDM_PLATFORM) || defined(LDM_PCI)
114 #if defined(LDM_PLATFORM)
115 #define LDM_DEV struct platform_device
116 #define LDM_DRV struct platform_driver
123 #define LDM_DEV struct pci_dev
124 #define LDM_DRV struct pci_driver
127 #if defined(LDM_PLATFORM)
128 static int PVRSRVDriverRemove(LDM_DEV * device);
129 static int PVRSRVDriverProbe(LDM_DEV * device);
132 static void PVRSRVDriverRemove(LDM_DEV * device);
133 static int PVRSRVDriverProbe(LDM_DEV * device, const struct pci_device_id *id);
135 static int PVRSRVDriverSuspend(LDM_DEV * device, pm_message_t state);
136 static void PVRSRVDriverShutdown(LDM_DEV * device);
137 static int PVRSRVDriverResume(LDM_DEV * device);
140 struct pci_device_id powervr_id_table[] __devinitdata = {
141 {PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID)},
145 MODULE_DEVICE_TABLE(pci, powervr_id_table);
148 static LDM_DRV powervr_driver = {
149 #if defined(LDM_PLATFORM)
156 .id_table = powervr_id_table,
158 .probe = PVRSRVDriverProbe,
159 #if defined(LDM_PLATFORM)
160 .remove = PVRSRVDriverRemove,
163 .remove = __devexit_p(PVRSRVDriverRemove),
165 .suspend = PVRSRVDriverSuspend,
166 .resume = PVRSRVDriverResume,
167 .shutdown = PVRSRVDriverShutdown,
170 LDM_DEV *gpsPVRLDMDev;
172 #if defined(LDM_PLATFORM)
173 static void PVRSRVDeviceRelease(struct device *device);
175 static struct platform_device powervr_device = {
179 .release = PVRSRVDeviceRelease}
183 #if defined(LDM_PLATFORM)
184 static int PVRSRVDriverProbe(LDM_DEV * pDevice)
187 static int __devinit PVRSRVDriverProbe(LDM_DEV * pDevice,
188 const struct pci_device_id *id)
193 PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice));
197 if (PerDeviceSysInitialise((IMG_PVOID) pDevice) != PVRSRV_OK) {
202 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
203 gpsPVRLDMDev = pDevice;
205 if (SysInitialise() != PVRSRV_OK) {
213 #if defined (LDM_PLATFORM)
214 static int PVRSRVDriverRemove(LDM_DEV * pDevice)
217 static void __devexit PVRSRVDriverRemove(LDM_DEV * pDevice)
222 PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice));
224 if (SysAcquireData(&psSysData) == PVRSRV_OK) {
225 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
226 if (gPVRPowerLevel != 0) {
227 if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) ==
233 SysDeinitialise(psSysData);
235 gpsPVRLDMDev = IMG_NULL;
238 if (PerDeviceSysDeInitialise((IMG_PVOID) pDevice) != PVRSRV_OK) {
243 #if defined (LDM_PLATFORM)
246 #if defined (LDM_PCI)
251 static void PVRSRVDriverShutdown(LDM_DEV * pDevice)
253 PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
255 (void)PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3);
258 static int PVRSRVDriverSuspend(LDM_DEV * pDevice, pm_message_t state)
260 #if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL))
261 PVR_TRACE(("PVRSRVDriverSuspend(pDevice=%p)", pDevice));
263 if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3) != PVRSRV_OK) {
270 static int PVRSRVDriverResume(LDM_DEV * pDevice)
272 #if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL))
273 PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice));
275 if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) != PVRSRV_OK) {
282 #if defined(LDM_PLATFORM)
283 static void PVRSRVDeviceRelease(struct device *pDevice)
285 PVR_DPF((PVR_DBG_WARNING, "PVRSRVDeviceRelease(pDevice=%p)", pDevice));
290 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
291 int PVRProcSetPowerLevel(struct file *file, const char *buffer,
292 unsigned long count, void *data)
295 IMG_UINT32 PVRPowerLevel;
297 if (count != sizeof(data_buffer)) {
300 if (copy_from_user(data_buffer, buffer, count))
302 if (data_buffer[count - 1] != '\n')
304 PVRPowerLevel = data_buffer[0] - '0';
305 if (PVRPowerLevel != gPVRPowerLevel) {
306 if (PVRPowerLevel != 0) {
307 if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3)
312 if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0)
318 gPVRPowerLevel = PVRPowerLevel;
324 int PVRProcGetPowerLevel(char *page, char **start, off_t off, int count,
325 int *eof, void *data)
329 return printAppend(page, count, 0, "%lu\n", gPVRPowerLevel);
336 static int PVRSRVOpen(struct inode unref__ * pInode,
337 struct file unref__ * pFile)
341 LinuxLockMutex(&gPVRSRVLock);
343 if (PVRSRVProcessConnect(OSGetCurrentProcessIDKM()) != PVRSRV_OK) {
347 LinuxUnLockMutex(&gPVRSRVLock);
352 static int PVRSRVRelease(struct inode unref__ * pInode,
353 struct file unref__ * pFile)
357 LinuxLockMutex(&gPVRSRVLock);
359 PVRSRVProcessDisconnect(OSGetCurrentProcessIDKM());
361 LinuxUnLockMutex(&gPVRSRVLock);
366 static int __init PVRCore_Init(void)
369 #if !(defined(LDM_PLATFORM) || defined(LDM_PCI))
373 PVR_TRACE(("PVRCore_Init"));
375 AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops);
377 if (AssignedMajorNumber <= 0) {
378 PVR_DPF((PVR_DBG_ERROR,
379 "PVRCore_Init: unable to get major number"));
384 PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
386 if (CreateProcEntries()) {
387 unregister_chrdev(AssignedMajorNumber, DRVNAME);
392 LinuxInitMutex(&gPVRSRVLock);
395 PVRDebugSetLevel(debug);
398 if (LinuxMMInit() != PVRSRV_OK) {
407 #if defined(LDM_PLATFORM) || defined(LDM_PCI)
409 #if defined(LDM_PLATFORM)
410 if ((error = platform_driver_register(&powervr_driver)) != 0) {
411 PVR_DPF((PVR_DBG_ERROR,
412 "PVRCore_Init: unable to register platform driver (%d)",
418 if ((error = platform_device_register(&powervr_device)) != 0) {
419 platform_driver_unregister(&powervr_driver);
421 PVR_DPF((PVR_DBG_ERROR,
422 "PVRCore_Init: unable to register platform device (%d)",
430 if ((error = pci_register_driver(&powervr_driver)) != 0) {
431 PVR_DPF((PVR_DBG_ERROR,
432 "PVRCore_Init: unable to register PCI driver (%d)",
441 if ((eError = SysInitialise()) != PVRSRV_OK) {
443 #if defined(TCF_REV) && (TCF_REV == 110)
444 if (eError == PVRSRV_ERROR_NOT_SUPPORTED) {
445 printk("\nAtlas wrapper (FPGA image) version mismatch");
460 unregister_chrdev(AssignedMajorNumber, DRVNAME);
466 static void __exit PVRCore_Cleanup(void)
470 PVR_TRACE(("PVRCore_Cleanup"));
472 SysAcquireData(&psSysData);
474 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
477 unregister_chrdev(AssignedMajorNumber, DRVNAME)
478 #if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
482 PVR_DPF((PVR_DBG_ERROR, " can't unregister device major %d",
483 AssignedMajorNumber));
487 #if defined(LDM_PLATFORM) || defined(LDM_PCI)
490 pci_unregister_driver(&powervr_driver);
493 #if defined (LDM_PLATFORM)
494 platform_device_unregister(&powervr_device);
495 platform_driver_unregister(&powervr_driver);
499 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
500 if (gPVRPowerLevel != 0) {
501 if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) == PVRSRV_OK) {
507 SysDeinitialise(psSysData);
518 PVR_TRACE(("PVRCore_Cleanup: unloading"));
521 module_init(PVRCore_Init);
522 module_exit(PVRCore_Cleanup);