oe patch: 0002-Compile-fixes-for-recent-kernels
[sgx.git] / services4 / system / omap3630 / sysutils_linux.c
1 /**********************************************************************\r
2  *\r
3  * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
4  *\r
5  * This program is free software; you can redistribute it and/or modify it\r
6  * under the terms and conditions of the GNU General Public License,\r
7  * version 2, as published by the Free Software Foundation.\r
8  *\r
9  * This program is distributed in the hope it will be useful but, except\r
10  * as otherwise stated in writing, without any warranty; without even the\r
11  * implied warranty of merchantability or fitness for a particular purpose.\r
12  * See the GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along with\r
15  * this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
17  *\r
18  * The full GNU General Public License is included in this distribution in\r
19  * the file called "COPYING".\r
20  *\r
21  * Contact Information:\r
22  * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
23  * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK\r
24  *\r
25  ******************************************************************************/\r
26 \r
27 #include <linux/version.h>\r
28 #include <linux/clk.h>\r
29 #include <linux/err.h>\r
30 #include <linux/hardirq.h>\r
31 #include <linux/spinlock.h>\r
32 #include <asm/bug.h>\r
33 #include <linux/platform_device.h>\r
34 \r
35 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,33))\r
36 #include <linux/semaphore.h>\r
37 #include <asm-generic/resource.h>\r
38 #include <plat/omap-pm.h>\r
39 #else\r
40 \r
41 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31))\r
42 #include <linux/semaphore.h>\r
43 #include <plat/resource.h>\r
44 #include <plat/omap-pm.h>\r
45 #else\r
46 \r
47 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))\r
48 #include <linux/semaphore.h>\r
49 #include <mach/resource.h>\r
50 #include <mach/omap-pm.h>\r
51 #else\r
52 #include <asm/semaphore.h>\r
53 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))\r
54 #include <asm/arch/resource.h>\r
55 #endif\r
56 #endif\r
57 #endif\r
58 #endif\r
59 \r
60 #if     (LINUX_VERSION_CODE >  KERNEL_VERSION(2,6,27)) && \\r
61         (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29))\r
62 #define CONSTRAINT_NOTIFICATIONS\r
63 #endif\r
64 #include "sgxdefs.h"\r
65 #include "services_headers.h"\r
66 #include "sysinfo.h"\r
67 #include "sgxapi_km.h"\r
68 #include "sysconfig.h"\r
69 #include "sgxinfokm.h"\r
70 #include "syslocal.h"\r
71 void set_vdd2_constraint(void);\r
72 void remove_vdd2_constraint(void);\r
73 #define ONE_MHZ 1000000\r
74 #define HZ_TO_MHZ(m) ((m) / ONE_MHZ)\r
75 \r
76 #if defined(SUPPORT_OMAP3630_SGXFCLK_96M)\r
77 #define SGX_PARENT_CLOCK "cm_96m_fck"\r
78 #elif defined(SUPPORT_OMAP3630_SGXFCLK_192M)\r
79 #define SGX_PARENT_CLOCK "omap_192m_alwon_ck"\r
80 #elif defined(SUPPORT_OMAP3630_SGXFCLK_corex2)\r
81 #define SGX_PARENT_CLOCK "corex2_fck"\r
82 #else\r
83 #define SGX_PARENT_CLOCK "core_ck"\r
84 #endif\r
85 \r
86 #if !defined(PDUMP) && !defined(NO_HARDWARE)\r
87 struct sgx_platform_data {\r
88           void(*set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r);\r
89 };\r
90 \r
91 static struct sgx_platform_data pdata = {\r
92 \r
93         //.set_min_bus_tput = &omap_pm_set_min_bus_tput,\r
94           .set_min_bus_tput = NULL,\r
95 };\r
96 \r
97 static struct platform_device sgx_dev = {\r
98          .name = "sgx_dev",\r
99          .id = 1,\r
100          .dev.platform_data = &pdata,\r
101 };\r
102 void set_vdd2_constraint(void)\r
103 {\r
104         if(pdata.set_min_bus_tput){\r
105                 pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT,800000);\r
106         }\r
107 }\r
108 \r
109 void remove_vdd2_constraint(void)\r
110 {\r
111         if(pdata.set_min_bus_tput)\r
112                 pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT, 0);\r
113 \r
114 }\r
115 #endif\r
116 #if !defined(PDUMP) && !defined(NO_HARDWARE)\r
117 static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData)\r
118 {\r
119         IMG_INT iCPU;\r
120         IMG_BOOL bLocked = IMG_FALSE;\r
121 \r
122         if (!in_interrupt())\r
123         {\r
124                 iCPU = get_cpu();\r
125                 bLocked = (iCPU == atomic_read(&psSysSpecData->sPowerLockCPU));\r
126 \r
127                 put_cpu();\r
128         }\r
129 \r
130         return bLocked;\r
131 }\r
132 \r
133 static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData)\r
134 {\r
135         IMG_INT iCPU;\r
136 \r
137         if (!in_interrupt())\r
138         {\r
139 \r
140                 iCPU = get_cpu();\r
141 \r
142 \r
143                 PVR_ASSERT(iCPU != -1);\r
144 \r
145                 PVR_ASSERT(!PowerLockWrappedOnCPU(psSysSpecData));\r
146 \r
147                 spin_lock(&psSysSpecData->sPowerLock);\r
148 \r
149                 atomic_set(&psSysSpecData->sPowerLockCPU, iCPU);\r
150         }\r
151 }\r
152 \r
153 static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData)\r
154 {\r
155         if (!in_interrupt())\r
156         {\r
157                 PVR_ASSERT(PowerLockWrappedOnCPU(psSysSpecData));\r
158 \r
159                 atomic_set(&psSysSpecData->sPowerLockCPU, -1);\r
160 \r
161                 spin_unlock(&psSysSpecData->sPowerLock);\r
162 \r
163                 put_cpu();\r
164         }\r
165 }\r
166 \r
167 PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData)\r
168 {\r
169         SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
170 \r
171         PowerLockWrap(psSysSpecData);\r
172 \r
173         return PVRSRV_OK;\r
174 }\r
175 \r
176 IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData)\r
177 {\r
178         SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
179 \r
180         PowerLockUnwrap(psSysSpecData);\r
181 }\r
182 #else\r
183 static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA unref__ *psSysSpecData)\r
184 {\r
185         return IMG_FALSE;\r
186 }\r
187 \r
188 static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData)\r
189 {\r
190 }\r
191 \r
192 static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData)\r
193 {\r
194 }\r
195 \r
196 PVRSRV_ERROR SysPowerLockWrap(SYS_DATA unref__ *psSysData)\r
197 {\r
198         return PVRSRV_OK;\r
199 }\r
200 \r
201 IMG_VOID SysPowerLockUnwrap(SYS_DATA unref__ *psSysData)\r
202 {\r
203 }\r
204 #endif\r
205 \r
206 IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)\r
207 {\r
208         IMG_BOOL bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);\r
209 \r
210         if (bPowerLock)\r
211         {\r
212                 PowerLockUnwrap(psSysSpecData);\r
213         }\r
214 \r
215         return bPowerLock;\r
216 }\r
217 \r
218 IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)\r
219 {\r
220         PowerLockWrap(psSysSpecData);\r
221 }\r
222 \r
223 static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2)\r
224 {\r
225         if (rate1 >= rate2)\r
226         {\r
227                 return val * (rate1 / rate2);\r
228         }\r
229 \r
230         return val / (rate2 / rate1);\r
231 }\r
232 \r
233 static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)\r
234 {\r
235         return scale_by_rate(val, rate, SYS_SGX_CLOCK_SPEED);\r
236 }\r
237 \r
238 static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)\r
239 {\r
240         return scale_by_rate(val, SYS_SGX_CLOCK_SPEED, rate);\r
241 }\r
242 \r
243 IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo)\r
244 {\r
245         IMG_UINT32 rate;\r
246 \r
247 #if defined(NO_HARDWARE)\r
248         rate = SYS_SGX_CLOCK_SPEED;\r
249 #else\r
250         PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0);\r
251 \r
252         rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK);\r
253         PVR_ASSERT(rate != 0);\r
254 #endif\r
255         psTimingInfo->ui32CoreClockSpeed = rate;\r
256         psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate);\r
257         psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate);\r
258         psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;\r
259 }\r
260 \r
261 #if defined(CONSTRAINT_NOTIFICATIONS)\r
262 #if !defined(SGX_DYNAMIC_TIMING_INFO)\r
263 #error "SGX_DYNAMIC_TIMING_INFO must be defined for this platform"\r
264 #endif\r
265 \r
266 #if !defined(PDUMP) && !defined(NO_HARDWARE)\r
267 static inline IMG_BOOL ConstraintNotificationsEnabled(SYS_SPECIFIC_DATA *psSysSpecData)\r
268 {\r
269         return (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) && psSysSpecData->bSGXInitComplete && psSysSpecData->bConstraintNotificationsEnabled;\r
270 \r
271 }\r
272 \r
273 static IMG_BOOL NotifyLockedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData)\r
274 {\r
275         IMG_INT iCPU = get_cpu();\r
276         IMG_BOOL bLocked = (iCPU == atomic_read(&psSysSpecData->sNotifyLockCPU));\r
277 \r
278         put_cpu();\r
279 \r
280         return bLocked;\r
281 }\r
282 \r
283 static IMG_VOID NotifyLock(SYS_SPECIFIC_DATA *psSysSpecData)\r
284 {\r
285         IMG_INT iCPU;\r
286 \r
287         BUG_ON(in_interrupt());\r
288 \r
289 \r
290         iCPU = get_cpu();\r
291 \r
292 \r
293         PVR_ASSERT(iCPU != -1);\r
294 \r
295         PVR_ASSERT(!NotifyLockedOnCPU(psSysSpecData));\r
296 \r
297         spin_lock(&psSysSpecData->sNotifyLock);\r
298 \r
299         atomic_set(&psSysSpecData->sNotifyLockCPU, iCPU);\r
300 \r
301 }\r
302 \r
303 static IMG_VOID NotifyUnlock(SYS_SPECIFIC_DATA *psSysSpecData)\r
304 {\r
305         PVR_ASSERT(NotifyLockedOnCPU(psSysSpecData));\r
306 \r
307         atomic_set(&psSysSpecData->sNotifyLockCPU, -1);\r
308 \r
309         spin_unlock(&psSysSpecData->sNotifyLock);\r
310 \r
311         put_cpu();\r
312 }\r
313 \r
314 static IMG_INT VDD2PostFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr)\r
315 {\r
316         PVR_UNREFERENCED_PARAMETER(n);\r
317         PVR_UNREFERENCED_PARAMETER(event);\r
318         PVR_UNREFERENCED_PARAMETER(ptr);\r
319 \r
320         if (in_interrupt())\r
321         {\r
322                 PVR_DPF((PVR_DBG_ERROR, "%s Called in interrupt context.  Ignoring.", __FUNCTION__));\r
323                 return 0;\r
324         }\r
325 \r
326 \r
327         if (!NotifyLockedOnCPU(gpsSysSpecificData))\r
328         {\r
329                 return 0;\r
330         }\r
331 \r
332 #if defined(DEBUG)\r
333         if (ConstraintNotificationsEnabled(gpsSysSpecificData))\r
334         {\r
335                 IMG_UINT32 rate;\r
336 \r
337                 rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK);\r
338 \r
339                 PVR_ASSERT(rate != 0);\r
340 \r
341                 PVR_DPF((PVR_DBG_MESSAGE, "%s: SGX clock rate: %dMHz", __FUNCTION__, HZ_TO_MHZ(rate)));\r
342         }\r
343 #endif\r
344         if (gpsSysSpecificData->bCallVDD2PostFunc)\r
345         {\r
346                 PVRSRVDevicePostClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL);\r
347 \r
348                 gpsSysSpecificData->bCallVDD2PostFunc = IMG_FALSE;\r
349         }\r
350         else\r
351         {\r
352                 if (ConstraintNotificationsEnabled(gpsSysSpecificData))\r
353                 {\r
354                         PVR_TRACE(("%s: Not calling PVR clock speed notification functions", __FUNCTION__));\r
355                 }\r
356         }\r
357 \r
358         NotifyUnlock(gpsSysSpecificData);\r
359 \r
360         return 0;\r
361 }\r
362 \r
363 static IMG_INT VDD2PreFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr)\r
364 {\r
365         PVR_UNREFERENCED_PARAMETER(n);\r
366         PVR_UNREFERENCED_PARAMETER(event);\r
367         PVR_UNREFERENCED_PARAMETER(ptr);\r
368 \r
369         if (in_interrupt())\r
370         {\r
371                 PVR_DPF((PVR_DBG_WARNING, "%s Called in interrupt context.  Ignoring.", __FUNCTION__));\r
372                 return 0;\r
373         }\r
374 \r
375         if (PowerLockWrappedOnCPU(gpsSysSpecificData))\r
376         {\r
377                 PVR_DPF((PVR_DBG_WARNING, "%s Called from within a power transition.  Ignoring.", __FUNCTION__));\r
378                 return 0;\r
379         }\r
380 \r
381         NotifyLock(gpsSysSpecificData);\r
382 \r
383         PVR_ASSERT(!gpsSysSpecificData->bCallVDD2PostFunc);\r
384 \r
385         if (ConstraintNotificationsEnabled(gpsSysSpecificData))\r
386         {\r
387                 PVRSRV_ERROR eError;\r
388 \r
389                 eError = PVRSRVDevicePreClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL);\r
390 \r
391                 gpsSysSpecificData->bCallVDD2PostFunc = (eError == PVRSRV_OK);\r
392 \r
393         }\r
394 \r
395         return 0;\r
396 }\r
397 static IMG_VOID RegisterConstraintNotifications(IMG_VOID)\r
398 {\r
399         PVR_TRACE(("Registering constraint notifications"));\r
400 \r
401         PVR_ASSERT(!gpsSysSpecificData->bConstraintNotificationsEnabled);\r
402 \r
403 \r
404         NotifyLock(gpsSysSpecificData);\r
405         gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_TRUE;\r
406         NotifyUnlock(gpsSysSpecificData);\r
407 \r
408         PVR_TRACE(("VDD2 constraint notifications registered"));\r
409 }\r
410 \r
411 static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID)\r
412 {\r
413         PVR_TRACE(("Unregistering constraint notifications"));\r
414 \r
415 \r
416         NotifyLock(gpsSysSpecificData);\r
417         gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_FALSE;\r
418         NotifyUnlock(gpsSysSpecificData);\r
419 \r
420 }\r
421 #else\r
422 static IMG_VOID RegisterConstraintNotifications(IMG_VOID)\r
423 {\r
424 }\r
425 \r
426 static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID)\r
427 {\r
428 }\r
429 #endif\r
430 #endif\r
431 \r
432 PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)\r
433 {\r
434 #if !defined(NO_HARDWARE)\r
435         SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
436         long lNewRate;\r
437         IMG_INT res;\r
438 \r
439 \r
440         if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0)\r
441         {\r
442                 return PVRSRV_OK;\r
443         }\r
444 \r
445         PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks"));\r
446 \r
447 #if defined(DEBUG)\r
448         {\r
449 \r
450                 IMG_UINT32 rate = clk_get_rate(psSysSpecData->psMPU_CK);\r
451                 PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: CPU Clock is %dMhz", HZ_TO_MHZ(rate)));\r
452         }\r
453 #endif\r
454 \r
455         res = clk_enable(psSysSpecData->psSGX_FCK);\r
456         if (res < 0)\r
457         {\r
458                 PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res));\r
459                 return PVRSRV_ERROR_GENERIC;\r
460         }\r
461 \r
462         res = clk_enable(psSysSpecData->psSGX_ICK);\r
463         if (res < 0)\r
464         {\r
465                 PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX interface clock (%d)", res));\r
466 \r
467                 clk_disable(psSysSpecData->psSGX_FCK);\r
468                 return PVRSRV_ERROR_GENERIC;\r
469         }\r
470 \r
471         lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ);\r
472         //PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: New SGX Func Clk = (%d)", lNewRate));\r
473         if (lNewRate <= 0)\r
474         {\r
475                 PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate"));\r
476                 return PVRSRV_ERROR_GENERIC;\r
477         }\r
478 \r
479         res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate);\r
480         if (res < 0)\r
481         {\r
482                 PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't set SGX function clock rate (%d)", res));\r
483                 return PVRSRV_ERROR_GENERIC;\r
484         }\r
485 \r
486 \r
487 #if defined(DEBUG)\r
488         {\r
489 \r
490                 IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK);\r
491                 PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate)));\r
492         }\r
493 #endif\r
494 \r
495         set_vdd2_constraint();\r
496 \r
497         lNewRate  = clk_get_rate(psSysSpecData->psSGX_FCK);\r
498         atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);\r
499         //PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Final SGX Func Clk = (%d)", lNewRate));\r
500 \r
501 #else\r
502         PVR_UNREFERENCED_PARAMETER(psSysData);\r
503 #endif\r
504         return PVRSRV_OK;\r
505 }\r
506 \r
507 \r
508 IMG_VOID DisableSGXClocks(SYS_DATA *psSysData)\r
509 {\r
510 #if !defined(NO_HARDWARE)\r
511         SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
512 \r
513         if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0)\r
514         {\r
515                 return;\r
516         }\r
517 \r
518         PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks"));\r
519 \r
520         if (psSysSpecData->psSGX_ICK)\r
521         {\r
522                 clk_disable(psSysSpecData->psSGX_ICK);\r
523         }\r
524 \r
525         if (psSysSpecData->psSGX_FCK)\r
526         {\r
527                 clk_disable(psSysSpecData->psSGX_FCK);\r
528         }\r
529 \r
530         remove_vdd2_constraint();\r
531 \r
532         atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);\r
533 \r
534 #else\r
535         PVR_UNREFERENCED_PARAMETER(psSysData);\r
536 #endif\r
537 }\r
538 \r
539 PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)\r
540 {\r
541         SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
542         struct clk *psCLK;\r
543         IMG_INT res;\r
544         PVRSRV_ERROR eError;\r
545         IMG_BOOL bPowerLock;\r
546 \r
547 #if defined(DEBUG) || defined(TIMING)\r
548         IMG_INT rate;\r
549         struct clk *sys_ck;\r
550         IMG_CPU_PHYADDR     TimerRegPhysBase;\r
551         IMG_HANDLE hTimerEnable;\r
552         IMG_UINT32 *pui32TimerEnable;\r
553 \r
554 #endif\r
555 \r
556         PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));\r
557 \r
558         if (!psSysSpecData->bSysClocksOneTimeInit)\r
559         {\r
560                 bPowerLock = IMG_FALSE;\r
561 \r
562                 spin_lock_init(&psSysSpecData->sPowerLock);\r
563                 atomic_set(&psSysSpecData->sPowerLockCPU, -1);\r
564                 spin_lock_init(&psSysSpecData->sNotifyLock);\r
565                 atomic_set(&psSysSpecData->sNotifyLockCPU, -1);\r
566 \r
567                 atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);\r
568 \r
569                 psCLK = clk_get(NULL, SGX_PARENT_CLOCK);\r
570                 if (IS_ERR(psCLK))\r
571                 {\r
572                         PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock"));\r
573                         goto ExitError;\r
574                 }\r
575                 psSysSpecData->psCORE_CK = psCLK;\r
576 \r
577                 psCLK = clk_get(NULL, "sgx_fck");\r
578                 if (IS_ERR(psCLK))\r
579                 {\r
580                         PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock"));\r
581                         goto ExitError;\r
582                 }\r
583                 psSysSpecData->psSGX_FCK = psCLK;\r
584 \r
585                 psCLK = clk_get(NULL, "sgx_ick");\r
586                 if (IS_ERR(psCLK))\r
587                 {\r
588                         PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock"));\r
589                         goto ExitError;\r
590                 }\r
591                 psSysSpecData->psSGX_ICK = psCLK;\r
592 \r
593 #if defined(DEBUG)\r
594                 psCLK = clk_get(NULL, "mpu_ck");\r
595                 if (IS_ERR(psCLK))\r
596                 {\r
597                         PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get MPU Clock"));\r
598                         goto ExitError;\r
599                 }\r
600                 psSysSpecData->psMPU_CK = psCLK;\r
601 #endif\r
602                 res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK);\r
603                 if (res < 0)\r
604                 {\r
605                         PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res));\r
606                         goto ExitError;\r
607                 }\r
608 \r
609                 psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;\r
610         }\r
611         else\r
612         {\r
613 \r
614                 bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);\r
615                 if (bPowerLock)\r
616                 {\r
617                         PowerLockUnwrap(psSysSpecData);\r
618                 }\r
619         }\r
620 \r
621 #if defined(CONSTRAINT_NOTIFICATIONS)\r
622 \r
623         RegisterConstraintNotifications();\r
624 #endif\r
625 \r
626 #if defined(DEBUG) || defined(TIMING)\r
627 \r
628         psCLK = clk_get(NULL, "gpt11_fck");\r
629         if (IS_ERR(psCLK))\r
630         {\r
631                 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));\r
632                 goto ExitUnRegisterConstraintNotifications;\r
633         }\r
634         psSysSpecData->psGPT11_FCK = psCLK;\r
635 \r
636         psCLK = clk_get(NULL, "gpt11_ick");\r
637         if (IS_ERR(psCLK))\r
638         {\r
639                 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock"));\r
640                 goto ExitUnRegisterConstraintNotifications;\r
641         }\r
642         psSysSpecData->psGPT11_ICK = psCLK;\r
643 \r
644         sys_ck = clk_get(NULL, "sys_ck");\r
645         if (IS_ERR(sys_ck))\r
646         {\r
647                 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock"));\r
648                 goto ExitUnRegisterConstraintNotifications;\r
649         }\r
650 \r
651         if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck)\r
652         {\r
653                 PVR_TRACE(("Setting GPTIMER11 parent to System Clock"));\r
654                 res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck);\r
655                 if (res < 0)\r
656                 {\r
657                         PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res));\r
658                 goto ExitUnRegisterConstraintNotifications;\r
659                 }\r
660         }\r
661 \r
662         rate = clk_get_rate(psSysSpecData->psGPT11_FCK);\r
663         PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate)));\r
664 \r
665         res = clk_enable(psSysSpecData->psGPT11_FCK);\r
666         if (res < 0)\r
667         {\r
668                 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res));\r
669                 goto ExitUnRegisterConstraintNotifications;\r
670         }\r
671 \r
672         res = clk_enable(psSysSpecData->psGPT11_ICK);\r
673         if (res < 0)\r
674         {\r
675                 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res));\r
676                 goto ExitDisableGPT11FCK;\r
677         }\r
678 \r
679 \r
680         TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE;\r
681         pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,\r
682                   4,\r
683                   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
684                   &hTimerEnable);\r
685 \r
686         if (pui32TimerEnable == IMG_NULL)\r
687         {\r
688                 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));\r
689                 goto ExitDisableGPT11ICK;\r
690         }\r
691 \r
692         rate = *pui32TimerEnable;\r
693         if(!(rate & 4))\r
694         {\r
695                 PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));\r
696 \r
697 \r
698                 *pui32TimerEnable = rate | 4;\r
699         }\r
700 \r
701         OSUnMapPhysToLin(pui32TimerEnable,\r
702                     4,\r
703                     PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
704                     hTimerEnable);\r
705 \r
706 \r
707         TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;\r
708         pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,\r
709                   4,\r
710                   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
711                   &hTimerEnable);\r
712 \r
713         if (pui32TimerEnable == IMG_NULL)\r
714         {\r
715                 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));\r
716                 goto ExitDisableGPT11ICK;\r
717         }\r
718 \r
719 \r
720         *pui32TimerEnable = 3;\r
721 \r
722         OSUnMapPhysToLin(pui32TimerEnable,\r
723                     4,\r
724                     PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
725                     hTimerEnable);\r
726 \r
727 #endif\r
728 \r
729         eError = PVRSRV_OK;\r
730         goto Exit;\r
731 \r
732 #if defined(DEBUG) || defined(TIMING)\r
733 ExitDisableGPT11ICK:\r
734         clk_disable(psSysSpecData->psGPT11_ICK);\r
735 ExitDisableGPT11FCK:\r
736         clk_disable(psSysSpecData->psGPT11_FCK);\r
737 ExitUnRegisterConstraintNotifications:\r
738 #endif\r
739 #if defined(CONSTRAINT_NOTIFICATIONS)\r
740         UnRegisterConstraintNotifications();\r
741 \r
742 #endif\r
743 ExitError:\r
744         eError = PVRSRV_ERROR_GENERIC;\r
745 Exit:\r
746         if (bPowerLock)\r
747         {\r
748                 PowerLockWrap(psSysSpecData);\r
749         }\r
750 \r
751 #if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
752         if (eError == PVRSRV_OK)\r
753         {\r
754 \r
755                 eError = EnableSGXClocks(psSysData);\r
756         }\r
757 #endif\r
758         return eError;\r
759 }\r
760 \r
761 IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)\r
762 {\r
763         SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
764         IMG_BOOL bPowerLock;\r
765 #if defined(DEBUG) || defined(TIMING)\r
766         IMG_CPU_PHYADDR TimerRegPhysBase;\r
767         IMG_HANDLE hTimerDisable;\r
768         IMG_UINT32 *pui32TimerDisable;\r
769 #endif\r
770 \r
771         PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));\r
772 \r
773         DisableSGXClocks(psSysData);\r
774 \r
775         bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);\r
776         if (bPowerLock)\r
777         {\r
778 \r
779                 PowerLockUnwrap(psSysSpecData);\r
780         }\r
781 \r
782 #if defined(CONSTRAINT_NOTIFICATIONS)\r
783         UnRegisterConstraintNotifications();\r
784 #endif\r
785 \r
786 #if defined(DEBUG) || defined(TIMING)\r
787 \r
788         TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;\r
789         pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,\r
790                                 4,\r
791                                 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
792                                 &hTimerDisable);\r
793 \r
794         if (pui32TimerDisable == IMG_NULL)\r
795         {\r
796                 PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed"));\r
797         }\r
798         else\r
799         {\r
800                 *pui32TimerDisable = 0;\r
801 \r
802                 OSUnMapPhysToLin(pui32TimerDisable,\r
803                                 4,\r
804                                 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
805                                 hTimerDisable);\r
806         }\r
807 \r
808         clk_disable(psSysSpecData->psGPT11_ICK);\r
809 \r
810         clk_disable(psSysSpecData->psGPT11_FCK);\r
811 \r
812 #endif\r
813         if (bPowerLock)\r
814         {\r
815                 PowerLockWrap(psSysSpecData);\r
816         }\r
817 }\r