[android-sdk/device-ti-proprietary-open.git] / jacinto6 / sgx_src / eurasia_km / services4 / srvkm / env / linux / module.c
1 /*************************************************************************/ /*!
2 @Title Linux module setup
3 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
4 @License Dual MIT/GPLv2
6 The contents of this file are subject to the MIT license as set out below.
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
18 Alternatively, the contents of this file may be used under the terms of
19 the GNU General Public License Version 2 ("GPL") in which case the provisions
20 of GPL are applicable instead of those above.
22 If you wish to allow use of your version of this file only under the terms of
23 GPL, and not to allow others to use your version of this file under the terms
24 of the MIT license, indicate your decision by deleting the provisions above
25 and replace them with the notice and other provisions required by GPL as set
26 out in the file called "GPL-COPYING" included in this distribution. If you do
27 not delete the provisions above, a recipient may use your version of this file
28 under the terms of either the MIT license or GPL.
30 This License is also included in this distribution in the file called
31 "MIT-COPYING".
33 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
34 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
35 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
37 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
38 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 */ /**************************************************************************/
42 #include <linux/version.h>
44 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
45 #ifndef AUTOCONF_INCLUDED
46 #include <linux/config.h>
47 #endif
48 #endif
50 #if defined(SUPPORT_DRI_DRM) && !defined(SUPPORT_DRI_DRM_PLUGIN)
51 #define PVR_MOD_STATIC
52 #else
53 /*
54 * For LDM drivers, define PVR_LDM_MODULE to indicate generic LDM
55 * support is required, besides indicating the exact support
56 * required (e.g. platform, or PCI device).
57 */
58 #if defined(LDM_PLATFORM)
59 #define PVR_LDM_PLATFORM_MODULE
60 #define PVR_LDM_DEVICE_CLASS
61 #define PVR_LDM_MODULE
62 #else
63 #if defined(LDM_PCI)
64 #define PVR_LDM_DEVICE_CLASS
65 #define PVR_LDM_PCI_MODULE
66 #define PVR_LDM_MODULE
67 #else
68 #if defined(SYS_SHARES_WITH_3PKM)
69 #define PVR_LDM_DEVICE_CLASS
70 #endif
71 #endif
72 #endif
73 #define PVR_MOD_STATIC static
74 #endif
76 #if defined(PVR_LDM_PLATFORM_PRE_REGISTERED)
77 #if !defined(NO_HARDWARE)
78 #define PVR_USE_PRE_REGISTERED_PLATFORM_DEV
79 #endif
80 #endif
82 #include <linux/init.h>
83 #include <linux/kernel.h>
84 #include <linux/module.h>
85 #include <linux/fs.h>
87 #ifdef CONFIG_OF
88 #include <linux/of.h>
89 #endif
91 #if defined(SUPPORT_DRI_DRM)
92 #include <drm/drmP.h>
93 #if defined(PVR_SECURE_DRM_AUTH_EXPORT)
94 #include "env_perproc.h"
95 #endif
96 #endif
98 #if defined(PVR_LDM_PLATFORM_MODULE)
99 #include <linux/platform_device.h>
100 #endif /* PVR_LDM_PLATFORM_MODULE */
102 #if defined(PVR_LDM_PCI_MODULE)
103 #include <linux/pci.h>
104 #endif /* PVR_LDM_PCI_MODULE */
106 #if defined(PVR_LDM_DEVICE_CLASS)
107 #include <linux/device.h>
108 #endif /* PVR_LDM_DEVICE_CLASS */
110 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
111 #include <asm/uaccess.h>
112 #endif
114 #include "img_defs.h"
115 #include "services.h"
116 #include "kerneldisplay.h"
117 #include "kernelbuffer.h"
118 #include "syscommon.h"
119 #include "pvrmmap.h"
120 #include "mutils.h"
121 #include "mm.h"
122 #include "mmap.h"
123 #include "mutex.h"
124 #include "pvr_debug.h"
125 #include "srvkm.h"
126 #include "perproc.h"
127 #include "handle.h"
128 #include "pvr_bridge_km.h"
129 #include "proc.h"
130 #include "pvrmodule.h"
131 #include "private_data.h"
132 #include "lock.h"
133 #include "linkage.h"
134 #include "buffer_manager.h"
135 #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC)
136 #include "pvr_sync.h"
137 #endif
139 #if defined(SUPPORT_PVRSRV_ANDROID_SYSTRACE)
140 #include "systrace.h"
141 #endif
143 #if defined(SUPPORT_DRI_DRM)
144 #include "pvr_drm.h"
145 #endif
146 /*
147 * DRVNAME is the name we use to register our driver.
148 * DEVNAME is the name we use to register actual device nodes.
149 */
150 #if defined(PVR_LDM_MODULE)
151 #define DRVNAME PVR_LDM_DRIVER_REGISTRATION_NAME
152 #endif
153 #define DEVNAME PVRSRV_MODNAME
155 #if defined(SUPPORT_DRI_DRM)
156 #define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
157 #else
158 #define PRIVATE_DATA(pFile) ((pFile)->private_data)
159 #endif
161 /*
162 * This is all module configuration stuff required by the linux kernel.
163 */
164 MODULE_SUPPORTED_DEVICE(DEVNAME);
166 #if defined(PVRSRV_NEED_PVR_DPF)
167 #include <linux/moduleparam.h>
168 extern IMG_UINT32 gPVRDebugLevel;
169 module_param(gPVRDebugLevel, uint, 0644);
170 MODULE_PARM_DESC(gPVRDebugLevel, "Sets the level of debug output (default 0x7)");
171 #endif /* defined(PVRSRV_NEED_PVR_DPF) */
173 /* Newer kernels no longer support __devinitdata */
174 #if !defined(__devinitdata)
175 #define __devinitdata
176 #endif
178 #if defined(SUPPORT_PVRSRV_DEVICE_CLASS)
179 /* PRQA S 3207 2 */ /* ignore 'not used' warning */
180 EXPORT_SYMBOL(PVRGetDisplayClassJTable);
181 EXPORT_SYMBOL(PVRGetBufferClassJTable);
182 #endif /* defined(SUPPORT_PVRSRV_DEVICE_CLASS) */
184 #if defined(PVR_LDM_DEVICE_CLASS) && !defined(SUPPORT_DRI_DRM)
185 /*
186 * Device class used for /sys entries (and udev device node creation)
187 */
188 static struct class *psPvrClass;
189 #endif
191 #if !defined(SUPPORT_DRI_DRM)
192 /*
193 * This is the major number we use for all nodes in /dev.
194 */
195 static int AssignedMajorNumber;
197 /*
198 * These are the operations that will be associated with the device node
199 * we create.
200 *
201 * With gcc -W, specifying only the non-null members produces "missing
202 * initializer" warnings.
203 */
204 static int PVRSRVOpen(struct inode* pInode, struct file* pFile);
205 static int PVRSRVRelease(struct inode* pInode, struct file* pFile);
207 static struct file_operations pvrsrv_fops =
208 {
209 .owner=THIS_MODULE,
210 .unlocked_ioctl = PVRSRV_BridgeDispatchKM,
211 .open=PVRSRVOpen,
212 .release=PVRSRVRelease,
213 .mmap=PVRMMap,
214 };
215 #endif
217 PVRSRV_LINUX_MUTEX gPVRSRVLock;
219 /* PID of process being released */
220 IMG_UINT32 gui32ReleasePID;
222 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
223 static IMG_UINT32 gPVRPowerLevel;
224 #endif
226 #if defined(PVR_LDM_MODULE)
228 #if defined(PVR_LDM_PLATFORM_MODULE)
229 #define LDM_DEV struct platform_device
230 #define LDM_DRV struct platform_driver
231 #endif /*PVR_LDM_PLATFORM_MODULE */
233 #if defined(PVR_LDM_PCI_MODULE)
234 #define LDM_DEV struct pci_dev
235 #define LDM_DRV struct pci_driver
236 #endif /* PVR_LDM_PCI_MODULE */
237 /*
238 * This is the driver interface we support.
239 */
240 #if defined(PVR_LDM_PLATFORM_MODULE)
241 static int PVRSRVDriverRemove(LDM_DEV *device);
242 static int PVRSRVDriverProbe(LDM_DEV *device);
243 #endif
244 #if defined(PVR_LDM_PCI_MODULE)
245 static void PVRSRVDriverRemove(LDM_DEV *device);
246 static int PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id);
247 #endif
248 static int PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state);
249 static void PVRSRVDriverShutdown(LDM_DEV *device);
250 static int PVRSRVDriverResume(LDM_DEV *device);
252 #if defined(PVR_LDM_PCI_MODULE)
253 /* This structure is used by the Linux module code */
254 struct pci_device_id powervr_id_table[] __devinitdata = {
255 {PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID)},
256 #if defined (SYS_SGX_DEV1_DEVICE_ID)
257 {PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID)},
258 #endif
259 {0}
260 };
262 MODULE_DEVICE_TABLE(pci, powervr_id_table);
263 #endif
265 #if defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
266 static struct platform_device_id powervr_id_table[] __devinitdata = {
267 {SYS_SGX_DEV_NAME, 0},
268 {}
269 };
270 #endif
272 #ifdef CONFIG_OF
273 static const struct of_device_id omap_gpu_id_table[] = {
274 { .compatible = "ti,omap4-gpu" },
275 {}
276 };
277 MODULE_DEVICE_TABLE(of, omap_gpu_id_table);
278 #endif
280 static LDM_DRV powervr_driver = {
281 #if defined(PVR_LDM_PLATFORM_MODULE)
282 .driver = {
283 .name = DRVNAME,
284 #ifdef CONFIG_OF
285 .of_match_table = of_match_ptr(omap_gpu_id_table),
286 #endif
287 },
288 #endif
289 #if defined(PVR_LDM_PCI_MODULE)
290 .name = DRVNAME,
291 #endif
292 #if defined(PVR_LDM_PCI_MODULE) || defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
293 .id_table = powervr_id_table,
294 #endif
295 .probe = PVRSRVDriverProbe,
296 #if defined(PVR_LDM_PLATFORM_MODULE)
297 .remove = PVRSRVDriverRemove,
298 #endif
299 #if defined(PVR_LDM_PCI_MODULE)
300 .remove = __devexit_p(PVRSRVDriverRemove),
301 #endif
302 .suspend = PVRSRVDriverSuspend,
303 .resume = PVRSRVDriverResume,
304 .shutdown = PVRSRVDriverShutdown,
305 };
307 LDM_DEV *gpsPVRLDMDev;
309 #if defined(MODULE) && defined(PVR_LDM_PLATFORM_MODULE) && \
310 !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
311 static void PVRSRVDeviceRelease(struct device unref__ *pDevice)
312 {
313 }
315 static struct platform_device powervr_device = {
316 .name = DEVNAME,
317 .id = -1,
318 .dev = {
319 .release = PVRSRVDeviceRelease
320 }
321 };
322 #endif
324 /*!
325 ******************************************************************************
327 @Function PVRSRVDriverProbe
329 @Description
331 See whether a given device is really one we can drive. The platform bus
332 handler has already established that we should be able to service this device
333 because of the name match. We probably don't need to do anything else.
335 @input pDevice - the device for which a probe is requested
337 @Return 0 for success or <0 for an error.
339 *****************************************************************************/
340 #if defined(PVR_LDM_PLATFORM_MODULE)
341 static int PVRSRVDriverProbe(LDM_DEV *pDevice)
342 #endif
343 #if defined(PVR_LDM_PCI_MODULE)
344 static int __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id)
345 #endif
346 {
347 SYS_DATA *psSysData;
349 PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice));
351 #if 0 /* INTEGRATION_POINT */
352 /* Some systems require device-specific system initialisation.
353 * E.g. this lets the OS track a device's dependencies on various
354 * system hardware.
355 *
356 * Note: some systems use this to enable HW that SysAcquireData
357 * will depend on, therefore it must be called first.
358 */
359 if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
360 {
361 return -EINVAL;
362 }
363 #endif
364 /* SysInitialise only designed to be called once.
365 */
366 psSysData = SysAcquireDataNoCheck();
367 if (psSysData == IMG_NULL)
368 {
369 gpsPVRLDMDev = pDevice;
370 if (SysInitialise() != PVRSRV_OK)
371 {
372 return -ENODEV;
373 }
374 }
376 return 0;
377 }
380 /*!
381 ******************************************************************************
383 @Function PVRSRVDriverRemove
385 @Description
387 This call is the opposite of the probe call: it is called when the device is
388 being removed from the driver's control. See the file $KERNELDIR/drivers/
389 base/bus.c:device_release_driver() for the call to this function.
391 This is the correct place to clean up anything our driver did while it was
392 asoociated with the device.
394 @input pDevice - the device for which driver detachment is happening
396 @Return 0 for success or <0 for an error.
398 *****************************************************************************/
399 #if defined (PVR_LDM_PLATFORM_MODULE)
400 static int PVRSRVDriverRemove(LDM_DEV *pDevice)
401 #endif
402 #if defined(PVR_LDM_PCI_MODULE)
403 static void __devexit PVRSRVDriverRemove(LDM_DEV *pDevice)
404 #endif
405 {
406 SYS_DATA *psSysData;
408 PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice));
410 SysAcquireData(&psSysData);
412 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
413 if (gPVRPowerLevel != 0)
414 {
415 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
416 {
417 gPVRPowerLevel = 0;
418 }
419 }
420 #endif
421 (void) SysDeinitialise(psSysData);
423 gpsPVRLDMDev = IMG_NULL;
425 #if 0 /* INTEGRATION_POINT */
426 /* See previous integration point for details. */
427 if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
428 {
429 return -EINVAL;
430 }
431 #endif
433 #if defined (PVR_LDM_PLATFORM_MODULE)
434 return 0;
435 #endif
436 #if defined (PVR_LDM_PCI_MODULE)
437 return;
438 #endif
439 }
440 #endif /* defined(PVR_LDM_MODULE) */
443 #if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
444 static PVRSRV_LINUX_MUTEX gsPMMutex;
445 static IMG_BOOL bDriverIsSuspended;
446 static IMG_BOOL bDriverIsShutdown;
447 #endif
449 #if defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV)
450 /*!
451 ******************************************************************************
453 @Function PVRSRVDriverShutdown
455 @Description
457 Suspend device operation for system shutdown. This is called as part of the
458 system halt/reboot process. The driver is put into a quiescent state by
459 setting the power state to D3.
461 @input pDevice - the device for which shutdown is requested
463 @Return nothing
465 *****************************************************************************/
466 #if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \
467 !defined(SUPPORT_DRI_DRM_PLUGIN)
468 void PVRSRVDriverShutdown(struct drm_device *pDevice)
469 #else
470 PVR_MOD_STATIC void PVRSRVDriverShutdown(LDM_DEV *pDevice)
471 #endif
472 {
473 PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
475 LinuxLockMutexNested(&gsPMMutex, PVRSRV_LOCK_CLASS_POWER);
477 if (!bDriverIsShutdown && !bDriverIsSuspended)
478 {
479 /*
480 * Take the bridge mutex, and never release it, to stop
481 * processes trying to use the driver after it has been
482 * shutdown.
483 */
484 LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE);
486 (void) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
487 }
489 bDriverIsShutdown = IMG_TRUE;
491 /* The bridge mutex is held on exit */
492 LinuxUnLockMutex(&gsPMMutex);
493 }
495 #endif /* defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV) */
498 #if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
499 /*!
500 ******************************************************************************
502 @Function PVRSRVDriverSuspend
504 @Description
506 For 2.6 kernels:
507 Suspend device operation. We always get three calls to this regardless of
508 the state (D1-D3) chosen. The order is SUSPEND_DISABLE, SUSPEND_SAVE_STATE
509 then SUSPEND_POWER_DOWN. We take action as soon as we get the disable call,
510 the other states not being handled by us yet.
512 For MontaVista 2.4 kernels:
513 This call gets made once only when someone does something like
515 # echo -e -n "suspend powerdown 0" >/sys.devices/legacy/pvrsrv0/power
517 The 3rd, numeric parameter (0) in the above has no relevence and is not
518 passed into us. The state parameter is always zero and the level parameter
519 is always SUSPEND_POWER_DOWN. Vive la difference!
521 @input pDevice - the device for which resume is requested
523 @Return 0 for success or <0 for an error.
525 *****************************************************************************/
526 #if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \
527 !defined(SUPPORT_DRI_DRM_PLUGIN)
528 #if defined(SUPPORT_DRM_MODESET)
529 int PVRSRVDriverSuspend(struct pci_dev *pDevice, pm_message_t state)
530 #else
531 int PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state)
532 #endif
533 #else
534 PVR_MOD_STATIC int PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state)
535 #endif
536 {
537 int res = 0;
538 #if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
539 PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice));
541 LinuxLockMutexNested(&gsPMMutex, PVRSRV_LOCK_CLASS_POWER);
543 if (!bDriverIsSuspended && !bDriverIsShutdown)
544 {
545 LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE);
547 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) == PVRSRV_OK)
548 {
549 /* The bridge mutex will be held until we resume */
550 bDriverIsSuspended = IMG_TRUE;
551 }
552 else
553 {
554 LinuxUnLockMutex(&gPVRSRVLock);
555 res = -EINVAL;
556 }
557 }
559 LinuxUnLockMutex(&gsPMMutex);
560 #endif
561 return res;
562 }
565 /*!
566 ******************************************************************************
568 @Function PVRSRVDriverResume
570 @Description
572 Resume device operation following a lull due to earlier suspension. It is
573 implicit we're returning to D0 (fully operational) state. We always get three
574 calls to this using level thus: RESUME_POWER_ON, RESUME_RESTORE_STATE then
575 RESUME_ENABLE. On 2.6 kernels We don't do anything until we get the enable
576 call; on the MontaVista set-up we only ever get the RESUME_POWER_ON call.
578 @input pDevice - the device for which resume is requested
580 @Return 0 for success or <0 for an error.
582 *****************************************************************************/
583 #if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \
584 !defined(SUPPORT_DRI_DRM_PLUGIN)
585 #if defined(SUPPORT_DRM_MODESET)
586 int PVRSRVDriverResume(struct pci_dev *pDevice)
587 #else
588 int PVRSRVDriverResume(struct drm_device *pDevice)
589 #endif
590 #else
591 PVR_MOD_STATIC int PVRSRVDriverResume(LDM_DEV *pDevice)
592 #endif
593 {
594 int res = 0;
595 #if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
596 PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice));
598 LinuxLockMutexNested(&gsPMMutex, PVRSRV_LOCK_CLASS_POWER);
600 if (bDriverIsSuspended && !bDriverIsShutdown)
601 {
602 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
603 {
604 bDriverIsSuspended = IMG_FALSE;
605 LinuxUnLockMutex(&gPVRSRVLock);
606 }
607 else
608 {
609 /* The bridge mutex is not released on failure */
610 res = -EINVAL;
611 }
612 }
614 LinuxUnLockMutex(&gsPMMutex);
615 #endif
616 return res;
617 }
618 #endif /* defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM) */
621 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)
622 /*
623 * If PVR_LDM_PCI_MODULE is defined (and PVR_MANUAL_POWER_CONTROL is *NOT* defined),
624 * the device can be suspended and resumed without suspending/resuming the
625 * system, by writing values into the power/state sysfs file for the device.
626 * To suspend:
627 * echo -n 2 > power/state
628 * To Resume:
629 * echo -n 0 > power/state
630 *
631 * The problem with this approach is that the device is usually left
632 * powered up; it is the responsibility of the bus driver to remove
633 * the power.
634 *
635 * Defining PVR_MANUAL_POWER_CONTROL is intended to make it easier to
636 * debug power management issues, especially when power is really removed
637 * from the device. It is easier to debug the driver if it is not being
638 * suspended/resumed with the rest of the system.
639 *
640 * When PVR_MANUAL_POWER_CONTROL is defined, the following proc entry is
641 * created:
642 * /proc/pvr/power_control
643 * The driver suspend/resume entry points defined below no longer suspend or
644 * resume the device. To suspend the device, type the following:
645 * echo 2 > /proc/pvr/power_control
646 * To resume the device, type:
647 * echo 0 > /proc/pvr/power_control
648 *
649 * The following example shows how to suspend/resume the device independently
650 * of the rest of the system.
651 * Suspend the device:
652 * echo 2 > /proc/pvr/power_control
653 * Suspend the system. Then you should be able to suspend and resume
654 * as normal. To resume the device type the following:
655 * echo 0 > /proc/pvr/power_control
656 */
658 IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
659 {
660 IMG_CHAR data_buffer[2];
661 IMG_UINT32 PVRPowerLevel;
663 if (count != sizeof(data_buffer))
664 {
665 return -EINVAL;
666 }
667 else
668 {
669 if (copy_from_user(data_buffer, buffer, count))
670 return -EINVAL;
671 if (data_buffer[count - 1] != '\n')
672 return -EINVAL;
673 PVRPowerLevel = data_buffer[0] - '0';
674 if (PVRPowerLevel != gPVRPowerLevel)
675 {
676 if (PVRPowerLevel != 0)
677 {
678 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
679 {
680 return -EINVAL;
681 }
682 }
683 else
684 {
685 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
686 {
687 return -EINVAL;
688 }
689 }
691 gPVRPowerLevel = PVRPowerLevel;
692 }
693 }
694 return (count);
695 }
697 void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el)
698 {
699 seq_printf(sfile, "%lu\n", gPVRPowerLevel);
700 }
702 #endif
704 /*!
705 ******************************************************************************
707 @Function PVRSRVOpen
709 @Description
711 Open the PVR services node - called when the relevant device node is open()ed.
713 @input pInode - the inode for the file being openeded
714 @input dev - the DRM device corresponding to this driver.
716 @input pFile - the file handle data for the actual file being opened
718 @Return 0 for success or <0 for an error.
720 *****************************************************************************/
721 #if defined(SUPPORT_DRI_DRM)
722 int PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pFile)
723 #else
724 static int PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile)
725 #endif
726 {
727 PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
728 IMG_HANDLE hBlockAlloc;
729 int iRet = -ENOMEM;
730 PVRSRV_ERROR eError;
731 IMG_UINT32 ui32PID;
732 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
733 PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
734 #endif
736 LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE);
738 ui32PID = OSGetCurrentProcessIDKM();
740 if (PVRSRVProcessConnect(ui32PID, 0) != PVRSRV_OK)
741 goto err_unlock;
743 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
744 psEnvPerProc = PVRSRVPerProcessPrivateData(ui32PID);
745 if (psEnvPerProc == IMG_NULL)
746 {
747 PVR_DPF((PVR_DBG_ERROR, "%s: No per-process private data", __FUNCTION__));
748 goto err_unlock;
749 }
750 #endif
752 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
753 sizeof(PVRSRV_FILE_PRIVATE_DATA),
754 (IMG_PVOID *)&psPrivateData,
755 &hBlockAlloc,
756 "File Private Data");
758 if(eError != PVRSRV_OK)
759 goto err_unlock;
761 psPrivateData->hKernelMemInfo = NULL;
762 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
763 psPrivateData->psDRMFile = pFile;
765 list_add_tail(&psPrivateData->sDRMAuthListItem, &psEnvPerProc->sDRMAuthListHead);
766 #endif
767 psPrivateData->ui32OpenPID = ui32PID;
768 psPrivateData->hBlockAlloc = hBlockAlloc;
769 PRIVATE_DATA(pFile) = psPrivateData;
770 iRet = 0;
771 err_unlock:
772 LinuxUnLockMutex(&gPVRSRVLock);
773 return iRet;
774 }
777 /*!
778 ******************************************************************************
780 @Function PVRSRVRelease
782 @Description
784 Release access the PVR services node - called when a file is closed, whether
785 at exit or using close(2) system call.
787 @input pInode - the inode for the file being released
789 @input pFile - the file handle data for the actual file being released
791 @Return 0 for success or <0 for an error.
793 *****************************************************************************/
794 #if defined(SUPPORT_DRI_DRM)
795 void PVRSRVRelease(void *pvPrivData)
796 #else
797 static int PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile)
798 #endif
799 {
800 PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
801 int err = 0;
803 LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE);
805 #if defined(SUPPORT_DRI_DRM)
806 psPrivateData = (PVRSRV_FILE_PRIVATE_DATA *)pvPrivData;
807 #else
808 psPrivateData = PRIVATE_DATA(pFile);
809 #endif
810 if (psPrivateData != IMG_NULL)
811 {
812 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
813 list_del(&psPrivateData->sDRMAuthListItem);
814 #endif
816 if(psPrivateData->hKernelMemInfo)
817 {
818 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
820 /* Look up the meminfo we just exported */
821 if(PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
822 (IMG_PVOID *)&psKernelMemInfo,
823 psPrivateData->hKernelMemInfo,
824 PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
825 {
826 PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up export handle", __FUNCTION__));
827 err = -EFAULT;
828 goto err_unlock;
829 }
831 /* Tell the XProc about the export if required */
832 if (psKernelMemInfo->sShareMemWorkaround.bInUse)
833 {
834 BM_XProcIndexRelease(psKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
835 }
837 /* This drops the psMemInfo refcount bumped on export */
838 if(FreeMemCallBackCommon(psKernelMemInfo, 0,
839 PVRSRV_FREE_CALLBACK_ORIGIN_EXTERNAL) != PVRSRV_OK)
840 {
841 PVR_DPF((PVR_DBG_ERROR, "%s: FreeMemCallBackCommon failed", __FUNCTION__));
842 err = -EFAULT;
843 goto err_unlock;
844 }
845 }
847 /* Usually this is the same as OSGetCurrentProcessIDKM(),
848 * but not necessarily (e.g. fork(), child closes last..)
849 */
850 gui32ReleasePID = psPrivateData->ui32OpenPID;
851 PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID);
852 gui32ReleasePID = 0;
854 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
855 sizeof(PVRSRV_FILE_PRIVATE_DATA),
856 psPrivateData, psPrivateData->hBlockAlloc);
858 #if !defined(SUPPORT_DRI_DRM)
859 PRIVATE_DATA(pFile) = IMG_NULL; /*nulling shared pointer*/
860 #endif
861 }
863 err_unlock:
864 LinuxUnLockMutex(&gPVRSRVLock);
865 #if defined(SUPPORT_DRI_DRM)
866 return;
867 #else
868 return err;
869 #endif
870 }
873 /*!
874 ******************************************************************************
876 @Function PVRCore_Init
878 @Description
880 Insert the driver into the kernel.
882 The device major number is allocated by the kernel dynamically. This means
883 that the device node (nominally /dev/pvrsrv) will need to be re-made at boot
884 time if the number changes between subsequent loads of the module. While the
885 number often stays constant between loads this is not guaranteed. The node
886 is made as root on the shell with:
888 mknod /dev/pvrsrv c nnn 0
890 where nnn is the major number found in /proc/devices for DEVNAME and also
891 reported by the PVR_DPF() - look at the boot log using dmesg' to see this).
893 Currently the auto-generated script /etc/init.d/rc.pvr handles creation of
894 the device. In other environments the device may be created either through
895 devfs or sysfs.
897 Readable proc-filesystem entries under /proc/pvr are created with
898 CreateProcEntries(). These can be read at runtime to get information about
899 the device (eg. 'cat /proc/pvr/vm')
901 __init places the function in a special memory section that the kernel frees
902 once the function has been run. Refer also to module_init() macro call below.
904 @input none
906 @Return none
908 *****************************************************************************/
909 #if defined(SUPPORT_DRI_DRM)
910 int PVRCore_Init(void)
911 #else
912 static int __init PVRCore_Init(void)
913 #endif
914 {
915 int error;
916 #if !defined(PVR_LDM_MODULE)
917 PVRSRV_ERROR eError;
918 #endif
919 #if !defined(SUPPORT_DRI_DRM) && defined(PVR_LDM_DEVICE_CLASS)
920 struct device *psDev;
921 #endif
925 #if !defined(SUPPORT_DRI_DRM)
926 /*
927 * Must come before attempting to print anything via Services.
928 * For DRM, the initialisation will already have been done.
929 */
930 PVRDPFInit();
931 #endif
932 PVR_TRACE(("PVRCore_Init"));
934 #if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
935 LinuxInitMutex(&gsPMMutex);
936 #endif
937 LinuxInitMutex(&gPVRSRVLock);
939 if (CreateProcEntries ())
940 {
941 error = -ENOMEM;
942 return error;
943 }
945 if (PVROSFuncInit() != PVRSRV_OK)
946 {
947 error = -ENOMEM;
948 goto init_failed;
949 }
951 PVRLinuxMUtilsInit();
953 if(LinuxMMInit() != PVRSRV_OK)
954 {
955 error = -ENOMEM;
956 goto init_failed;
957 }
959 LinuxBridgeInit();
962 PVRMMapInit();
964 #if defined(PVR_LDM_MODULE)
966 #if defined(PVR_LDM_PLATFORM_MODULE) || defined(SUPPORT_DRI_DRM_PLUGIN)
967 if ((error = platform_driver_register(&powervr_driver)) != 0)
968 {
969 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error));
971 goto init_failed;
972 }
974 #if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
975 if ((error = platform_device_register(&powervr_device)) != 0)
976 {
977 platform_driver_unregister(&powervr_driver);
979 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error));
981 goto init_failed;
982 }
983 #endif
984 #endif /* PVR_LDM_PLATFORM_MODULE */
986 #if defined(PVR_LDM_PCI_MODULE)
987 if ((error = pci_register_driver(&powervr_driver)) != 0)
988 {
989 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error));
991 goto init_failed;
992 }
993 #endif /* PVR_LDM_PCI_MODULE */
994 #endif /* defined(PVR_LDM_MODULE) */
996 #if !defined(PVR_LDM_MODULE)
997 /*
998 * Drivers using LDM, will call SysInitialise in the probe/attach code
999 */
1000 if ((eError = SysInitialise()) != PVRSRV_OK)
1001 {
1002 error = -ENODEV;
1003 #if defined(TCF_REV) && (TCF_REV == 110)
1004 if(eError == PVRSRV_ERROR_NOT_SUPPORTED)
1005 {
1006 printk("\nAtlas wrapper (FPGA image) version mismatch");
1007 error = -ENODEV;
1008 }
1009 #endif
1010 goto init_failed;
1011 }
1012 #endif /* !defined(PVR_LDM_MODULE) */
1014 #if !defined(SUPPORT_DRI_DRM)
1015 AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops);
1017 if (AssignedMajorNumber <= 0)
1018 {
1019 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number"));
1021 error = -EBUSY;
1022 goto sys_deinit;
1023 }
1025 PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
1027 #if defined(PVR_LDM_DEVICE_CLASS)
1028 /*
1029 * This code (using GPL symbols) facilitates automatic device
1030 * node creation on platforms with udev (or similar).
1031 */
1032 psPvrClass = class_create(THIS_MODULE, "pvr");
1034 if (IS_ERR(psPvrClass))
1035 {
1036 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create class (%ld)", PTR_ERR(psPvrClass)));
1037 error = -EBUSY;
1038 goto unregister_device;
1039 }
1041 psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0),
1042 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
1043 NULL,
1044 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */
1045 DEVNAME);
1046 if (IS_ERR(psDev))
1047 {
1048 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev)));
1049 error = -EBUSY;
1050 goto destroy_class;
1051 }
1052 #endif /* defined(PVR_LDM_DEVICE_CLASS) */
1053 #endif /* !defined(SUPPORT_DRI_DRM) */
1055 #if defined(SUPPORT_PVRSRV_ANDROID_SYSTRACE)
1056 SystraceCreateFS();
1057 #endif
1059 #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC)
1060 PVRSyncDeviceInit();
1061 #endif
1062 return 0;
1064 #if !defined(SUPPORT_DRI_DRM)
1065 #if defined(PVR_LDM_DEVICE_CLASS)
1066 destroy_class:
1067 class_destroy(psPvrClass);
1068 unregister_device:
1069 unregister_chrdev((IMG_UINT)AssignedMajorNumber, DEVNAME);
1070 #endif
1071 #endif
1072 #if !defined(SUPPORT_DRI_DRM)
1073 sys_deinit:
1074 #endif
1075 #if defined(PVR_LDM_MODULE)
1076 #if defined(PVR_LDM_PCI_MODULE)
1077 pci_unregister_driver(&powervr_driver);
1078 #endif
1080 #if defined (PVR_LDM_PLATFORM_MODULE)
1081 #if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
1082 platform_device_unregister(&powervr_device);
1083 #endif
1084 platform_driver_unregister(&powervr_driver);
1085 #endif
1087 #else /* defined(PVR_LDM_MODULE) */
1088 /* LDM drivers call SysDeinitialise during PVRSRVDriverRemove */
1089 {
1090 SYS_DATA *psSysData;
1092 psSysData = SysAcquireDataNoCheck();
1093 if (psSysData != IMG_NULL)
1094 {
1095 (void) SysDeinitialise(psSysData);
1096 }
1097 }
1098 #endif /* defined(PVR_LDM_MODULE) */
1099 init_failed:
1100 PVRMMapCleanup();
1101 LinuxMMCleanup();
1102 LinuxBridgeDeInit();
1103 PVROSFuncDeInit();
1104 RemoveProcEntries();
1105 return error;
1107 } /*PVRCore_Init*/
1110 /*!
1111 *****************************************************************************
1113 @Function PVRCore_Cleanup
1115 @Description
1117 Remove the driver from the kernel.
1119 There's no way we can get out of being unloaded other than panicking; we
1120 just do everything and plough on regardless of error.
1122 __exit places the function in a special memory section that the kernel frees
1123 once the function has been run. Refer also to module_exit() macro call below.
1125 Note that the for LDM on MontaVista kernels, the positioning of the driver
1126 de-registration is the opposite way around than would be suggested by the
1127 registration case or the 2,6 kernel case. This is the correct way to do it
1128 and the kernel panics if you change it. You have been warned.
1130 @input none
1132 @Return none
1134 *****************************************************************************/
1135 #if defined(SUPPORT_DRI_DRM)
1136 void PVRCore_Cleanup(void)
1137 #else
1138 static void __exit PVRCore_Cleanup(void)
1139 #endif
1140 {
1141 #if !defined(PVR_LDM_MODULE)
1142 SYS_DATA *psSysData;
1143 #endif
1144 PVR_TRACE(("PVRCore_Cleanup"));
1146 #if !defined(PVR_LDM_MODULE)
1147 SysAcquireData(&psSysData);
1148 #endif
1150 #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC)
1151 PVRSyncDeviceDeInit();
1152 #endif
1154 #if !defined(SUPPORT_DRI_DRM)
1156 #if defined(PVR_LDM_DEVICE_CLASS)
1157 device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
1158 class_destroy(psPvrClass);
1159 #endif
1161 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
1162 if (
1163 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) */
1164 unregister_chrdev((IMG_UINT)AssignedMajorNumber, DEVNAME)
1165 #if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
1166 ;
1167 #else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) */
1168 )
1169 {
1170 PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber));
1171 }
1172 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) */
1173 #endif /* !defined(SUPPORT_DRI_DRM) */
1175 #if defined(PVR_LDM_MODULE)
1177 #if defined(PVR_LDM_PCI_MODULE)
1178 pci_unregister_driver(&powervr_driver);
1179 #endif
1181 #if defined (PVR_LDM_PLATFORM_MODULE)
1182 #if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
1183 platform_device_unregister(&powervr_device);
1184 #endif
1185 platform_driver_unregister(&powervr_driver);
1186 #endif
1188 #else /* defined(PVR_LDM_MODULE) */
1189 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
1190 if (gPVRPowerLevel != 0)
1191 {
1192 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
1193 {
1194 gPVRPowerLevel = 0;
1195 }
1196 }
1197 #endif
1198 /* LDM drivers call SysDeinitialise during PVRSRVDriverRemove */
1199 (void) SysDeinitialise(psSysData);
1200 #endif /* defined(PVR_LDM_MODULE) */
1202 PVRMMapCleanup();
1204 LinuxMMCleanup();
1206 LinuxBridgeDeInit();
1208 PVROSFuncDeInit();
1210 RemoveProcEntries();
1212 #if defined(SUPPORT_PVRSRV_ANDROID_SYSTRACE)
1213 SystraceDestroyFS();
1214 #endif
1216 PVR_TRACE(("PVRCore_Cleanup: unloading"));
1217 }
1219 /*
1220 * These macro calls define the initialisation and removal functions of the
1221 * driver. Although they are prefixed `module_', they apply when compiling
1222 * statically as well; in both cases they define the function the kernel will
1223 * run to start/stop the driver.
1224 */
1225 #if !defined(SUPPORT_DRI_DRM)
1226 module_init(PVRCore_Init);
1227 module_exit(PVRCore_Cleanup);
1228 #endif