tizen 2.4 release
[kernel/linux-3.0.git] / drivers / gpu / arm / mali400 / mali / platform / redwood / exynos4.c
1 /* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4.c
2  *
3  * Copyright 2011 by S.LSI. Samsung Electronics Inc.
4  * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
5  *
6  * Samsung SoC Mali400 DVFS driver
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software FoundatIon.
11  */
12
13 /**
14  * @file exynos4.c
15  * Platform specific Mali driver functions for the exynos 4XXX based platforms
16  */
17 #include <linux/platform_device.h>
18 #include <linux/version.h>
19 #include <linux/pm.h>
20 #ifdef CONFIG_PM_RUNTIME
21 #include <linux/pm_runtime.h>
22 #endif
23 #include <linux/mali/mali_utgard.h>
24 #include "mali_kernel_common.h"
25
26 #include <linux/irq.h>
27 #include <plat/devs.h>
28
29 #include "exynos4_pmm.h"
30
31 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) && LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
32 extern struct platform_device exynos4_device_pd[];
33 #else
34 extern struct platform_device s5pv310_device_pd[];
35 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
36
37 static void mali_platform_device_release(struct device *device);
38 static int mali_os_suspend(struct device *device);
39 static int mali_os_resume(struct device *device);
40 static int mali_os_freeze(struct device *device);
41 static int mali_os_thaw(struct device *device);
42 #ifdef CONFIG_PM_RUNTIME
43 static int mali_runtime_suspend(struct device *device);
44 static int mali_runtime_resume(struct device *device);
45 static int mali_runtime_idle(struct device *device);
46 #endif
47
48 #define MALI_GP_IRQ       EXYNOS4_IRQ_GP_3D
49 #define MALI_PP0_IRQ      EXYNOS4_IRQ_PP0_3D
50 #define MALI_PP1_IRQ      EXYNOS4_IRQ_PP1_3D
51 #define MALI_PP2_IRQ      EXYNOS4_IRQ_PP2_3D
52 #define MALI_PP3_IRQ      EXYNOS4_IRQ_PP3_3D
53 #define MALI_GP_MMU_IRQ   EXYNOS4_IRQ_GPMMU_3D
54 #define MALI_PP0_MMU_IRQ  EXYNOS4_IRQ_PPMMU0_3D
55 #define MALI_PP1_MMU_IRQ  EXYNOS4_IRQ_PPMMU1_3D
56 #define MALI_PP2_MMU_IRQ  EXYNOS4_IRQ_PPMMU2_3D
57 #define MALI_PP3_MMU_IRQ  EXYNOS4_IRQ_PPMMU3_3D
58
59 static struct resource mali_gpu_resources[] =
60 {
61         MALI_GPU_RESOURCES_MALI400_MP4(0x13000000,
62                                        MALI_GP_IRQ, MALI_GP_MMU_IRQ,
63                                        MALI_PP0_IRQ, MALI_PP0_MMU_IRQ,
64                                        MALI_PP1_IRQ, MALI_PP1_MMU_IRQ,
65                                        MALI_PP2_IRQ, MALI_PP2_MMU_IRQ,
66                                        MALI_PP3_IRQ, MALI_PP3_MMU_IRQ)
67 };
68
69 static struct dev_pm_ops mali_gpu_device_type_pm_ops =
70 {
71         .suspend = mali_os_suspend,
72         .resume = mali_os_resume,
73         .freeze = mali_os_freeze,
74         .thaw = mali_os_thaw,
75 #ifdef CONFIG_PM_RUNTIME
76         .runtime_suspend = mali_runtime_suspend,
77         .runtime_resume = mali_runtime_resume,
78         .runtime_idle = mali_runtime_idle,
79 #endif
80 };
81
82 static struct device_type mali_gpu_device_device_type =
83 {
84         .pm = &mali_gpu_device_type_pm_ops,
85 };
86
87
88 static struct platform_device *mali_gpu_device;
89
90 static struct mali_gpu_device_data mali_gpu_data =
91 {
92         .shared_mem_size = 256 * 1024 * 1024, /* 256MB */
93         .fb_start = 0x40000000,
94         .fb_size = 0xb1000000,
95 /*      .utilization_interval = 1000, *//* 1000ms */
96         .utilization_interval = 100, /* 100ms in Tizen */
97         .utilization_handler = mali_gpu_utilization_handler,
98 };
99
100 int mali_platform_device_register(void)
101 {
102         int err;
103
104         MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
105
106         /* Connect resources to the device */
107         err = platform_device_add_resources(&exynos4_device_g3d, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0]));
108         if (0 == err)
109         {
110                 err = platform_device_add_data(&exynos4_device_g3d, &mali_gpu_data, sizeof(mali_gpu_data));
111                 if (0 == err)
112                 {
113                         mali_platform_init();
114
115 #ifdef CONFIG_PM_RUNTIME
116 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
117                         pm_runtime_set_autosuspend_delay(&(exynos4_device_g3d.dev), 300);
118                         pm_runtime_use_autosuspend(&(exynos4_device_g3d.dev));
119 #endif
120                         pm_runtime_enable(&(exynos4_device_g3d.dev));
121 #endif
122                         return 0;
123                 }
124
125         }
126         return err;
127 }
128
129 void mali_platform_device_unregister(void)
130 {
131         MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
132
133         mali_platform_deinit();
134 }
135
136 static void mali_platform_device_release(struct device *device)
137 {
138         MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
139 }
140
141 static int mali_os_suspend(struct device *device)
142 {
143         int ret = 0;
144
145         MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
146
147         if (NULL != device->driver &&
148             NULL != device->driver->pm &&
149             NULL != device->driver->pm->suspend)
150         {
151                 /* Need to notify Mali driver about this event */
152                 ret = device->driver->pm->suspend(device);
153         }
154
155         mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
156
157         return ret;
158 }
159
160 static int mali_os_resume(struct device *device)
161 {
162         int ret = 0;
163
164         MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
165
166         mali_platform_power_mode_change(MALI_POWER_MODE_ON);
167
168         if (NULL != device->driver &&
169             NULL != device->driver->pm &&
170             NULL != device->driver->pm->resume)
171         {
172                 /* Need to notify Mali driver about this event */
173                 ret = device->driver->pm->resume(device);
174         }
175
176         return ret;
177 }
178
179 static int mali_os_freeze(struct device *device)
180 {
181         int ret = 0;
182
183         MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
184
185         if (NULL != device->driver &&
186             NULL != device->driver->pm &&
187             NULL != device->driver->pm->freeze)
188         {
189                 /* Need to notify Mali driver about this event */
190                 ret = device->driver->pm->freeze(device);
191         }
192
193         return ret;
194 }
195
196 static int mali_os_thaw(struct device *device)
197 {
198         int ret = 0;
199
200         MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
201
202         if (NULL != device->driver &&
203             NULL != device->driver->pm &&
204             NULL != device->driver->pm->thaw)
205         {
206                 /* Need to notify Mali driver about this event */
207                 ret = device->driver->pm->thaw(device);
208         }
209
210         return ret;
211 }
212
213 #ifdef CONFIG_PM_RUNTIME
214 static int mali_runtime_suspend(struct device *device)
215 {
216         int ret = 0;
217
218         MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
219
220         if (NULL != device->driver &&
221             NULL != device->driver->pm &&
222             NULL != device->driver->pm->runtime_suspend)
223         {
224                 /* Need to notify Mali driver about this event */
225                 ret = device->driver->pm->runtime_suspend(device);
226         }
227
228         mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
229
230         return ret;
231 }
232
233 static int mali_runtime_resume(struct device *device)
234 {
235         int ret = 0;
236
237         MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
238
239         mali_platform_power_mode_change(MALI_POWER_MODE_ON);
240
241         if (NULL != device->driver &&
242             NULL != device->driver->pm &&
243             NULL != device->driver->pm->runtime_resume)
244         {
245                 /* Need to notify Mali driver about this event */
246                 ret = device->driver->pm->runtime_resume(device);
247         }
248
249         return ret;
250 }
251
252 static int mali_runtime_idle(struct device *device)
253 {
254         MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
255
256         if (NULL != device->driver &&
257             NULL != device->driver->pm &&
258             NULL != device->driver->pm->runtime_idle)
259         {
260                 /* Need to notify Mali driver about this event */
261                 int ret = device->driver->pm->runtime_idle(device);
262                 if (0 != ret)
263                 {
264                         return ret;
265                 }
266         }
267
268         pm_runtime_suspend(device);
269
270         return 0;
271 }
272 #endif