import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mali / mali / platform / platform.c
1 #include <linux/platform_device.h>
2 #include <linux/version.h>
3 #include <linux/pm.h>
4 #ifdef CONFIG_PM_RUNTIME
5 #include <linux/pm_runtime.h>
6 #endif
7 #include <asm/io.h>
8 #include <linux/mali/mali_utgard.h>
9 #include "mali_kernel_common.h"
10 #include <linux/dma-mapping.h>
11 #include <mach/mt_irq.h>
12 #include "arm_core_scaling.h"
13 #include "platform_pmm.h"
14 #include "mali_pm.h"
15 #include "mali_osk.h"
16 #include "mt_reg_base.h"
17
18 static void mali_platform_device_release(struct device *device);
19 static int mali_pm_suspend(struct device *device);
20 static int mali_pm_resume(struct device *device);
21
22
23 static struct mali_gpu_device_data mali_gpu_data =
24 {
25 // System memory
26 .shared_mem_size = 1024 * 1024 * 1024, /* 1GB */
27 // Framebuffer physical address, only for validation usage
28 .fb_start = 0x80000000,
29 .fb_size = 0x80000000,
30 // DVFS
31 .utilization_interval = 200, /* ms */
32 .utilization_callback = mali_pmm_utilization_handler, /*<utilization function>,*/
33 };
34
35 static struct resource mali_gpu_resources[] =
36 {
37 MALI_GPU_RESOURCES_MALI450_MP4(
38 IO_VIRT_TO_PHYS(MALI_BASE),
39 MT_MFG_IRQ0_ID,
40 MT_MFG_IRQ1_ID,
41 MT_MFG_IRQ2_ID,
42 MT_MFG_IRQ3_ID,
43 MT_MFG_IRQ4_ID,
44 MT_MFG_IRQ5_ID,
45 MT_MFG_IRQ6_ID,
46 MT_MFG_IRQ7_ID,
47 MT_MFG_IRQ8_ID,
48 MT_MFG_IRQ9_ID,
49 MT_MFG_IRQ10_ID
50 )
51 };
52
53 static struct resource mali_gpu_resources_MP3[] =
54 {
55 MALI_GPU_RESOURCES_MALI450_MP3(
56 IO_VIRT_TO_PHYS(MALI_BASE),
57 MT_MFG_IRQ0_ID,
58 MT_MFG_IRQ1_ID,
59 MT_MFG_IRQ2_ID,
60 MT_MFG_IRQ3_ID,
61 MT_MFG_IRQ4_ID,
62 MT_MFG_IRQ5_ID,
63 MT_MFG_IRQ6_ID,
64 MT_MFG_IRQ7_ID,
65 MT_MFG_IRQ10_ID
66 )
67 };
68
69
70 static struct resource mali_gpu_resources_MP2[] =
71 {
72 MALI_GPU_RESOURCES_MALI450_MP2(
73 IO_VIRT_TO_PHYS(MALI_BASE),
74 MT_MFG_IRQ0_ID,
75 MT_MFG_IRQ1_ID,
76 MT_MFG_IRQ2_ID,
77 MT_MFG_IRQ3_ID,
78 MT_MFG_IRQ4_ID,
79 MT_MFG_IRQ5_ID,
80 MT_MFG_IRQ10_ID
81 )
82 };
83
84
85 static struct dev_pm_ops mali_gpu_device_type_pm_ops =
86 {
87 .suspend = mali_pm_suspend,
88 .resume = mali_pm_resume,
89 .freeze = mali_pm_suspend,
90 .thaw = mali_pm_resume,
91 .restore = mali_pm_resume,
92
93 #ifdef CONFIG_PM_RUNTIME
94 .runtime_suspend = mali_runtime_suspend,
95 .runtime_resume = mali_runtime_resume,
96 .runtime_idle = mali_runtime_idle,
97 #endif
98 };
99
100 static struct device_type mali_gpu_device_device_type =
101 {
102 .pm = &mali_gpu_device_type_pm_ops,
103 };
104
105
106 static struct platform_device mali_gpu_device =
107 {
108 .name = MALI_GPU_NAME_UTGARD,
109 .id = 0,
110 .num_resources = ARRAY_SIZE(mali_gpu_resources),
111 .resource = (struct resource *)&mali_gpu_resources,
112 .dev.platform_data = &mali_gpu_data,
113 .dev.release = mali_platform_device_release,
114 .dev.coherent_dma_mask = DMA_BIT_MASK(32),
115 /// Ideally .dev.pm_domain should be used instead, as this is the new framework designed
116 /// to control the power of devices.
117 .dev.type = &mali_gpu_device_device_type /// We should probably use the pm_domain instead of type on newer kernels
118 };
119
120
121 extern u32 get_devinfo_with_index(u32 index);
122
123 static u32 get_devinfo() {
124 /*TODO: replace this with get_devinfo_with_index*/
125 return *(volatile u32 *)0xf0206174;
126 }
127 static u32 get_gpuinfo() {
128 /*TODO: replace this with get_devinfo_with_index*/
129 return *(volatile u32 *)0xf0206040;
130 }
131
132 #define MALI_REASSIGN_RESOURCE(device, X) \
133 do {\
134 device->resource = (struct resource *)&(X);\
135 device->num_resources = ARRAY_SIZE((X));\
136 }while(0)
137
138 static void update_dev_info(struct platform_device * device ) {
139 u32 info = get_devinfo();
140 MALI_DEBUG_PRINT(1, ("devinfo %#x\n", info));
141
142 /*if(0x0 == (info & (0x1 << 31))) { t or b*/
143 /*T*/
144 u32 gpuinfo = get_gpuinfo();
145 MALI_DEBUG_PRINT(1, ("gpuinfo %#x\n", gpuinfo));
146 u32 pp = (gpuinfo & 0x60000) >> 17;
147 if(pp == 0x1) {
148 MALI_DEBUG_PRINT(1, ("Found devinfo of MP3 %s\n", __FUNCTION__));
149 MALI_REASSIGN_RESOURCE(device, mali_gpu_resources_MP3);
150 } else if(pp == 0x2 || pp == 0x3) {
151 MALI_DEBUG_PRINT(1, ("Found devinfo of MP2 %s, %d\n", __FUNCTION__, pp));
152 MALI_REASSIGN_RESOURCE(device, mali_gpu_resources_MP2);
153 } else {
154 #ifdef MTK_NR_MALI_PP
155 #if (MTK_NR_MALI_PP == 3)
156 MALI_DEBUG_PRINT(1, ("Mali MP3 %s (MTK_NR_MALI_PP)\n", __FUNCTION__));
157 MALI_REASSIGN_RESOURCE(device, mali_gpu_resources_MP3);
158 #elif (MTK_NR_MALI_PP == 2)
159 MALI_DEBUG_PRINT(1, ("Mali MP2 %s (MTK_NR_MALI_PP)\n", __FUNCTION__));
160 MALI_REASSIGN_RESOURCE(device, mali_gpu_resources_MP2);
161 #else
162 MALI_DEBUG_PRINT(1, ("Default MP4 %s, ignore cfg: %d\n", __FUNCTION__, MTK_NR_MALI_PP));
163 #endif
164 #else
165 MALI_DEBUG_PRINT(1, ("Default MP4 %s\n", __FUNCTION__));
166 #endif
167 }
168 }
169
170
171 extern unsigned int get_max_DRAM_size (void);
172 int mali_platform_device_register(void)
173 {
174 int err = -1;
175 int num_pp_cores = 4; //TODO: Need specify if we are using diff config
176 MALI_DEBUG_PRINT(1, ("%s\n", __FUNCTION__));
177 mali_gpu_data.shared_mem_size = get_max_DRAM_size();
178
179 update_dev_info(&mali_gpu_device);
180
181 err = platform_device_register(&mali_gpu_device);
182
183 if (0 == err)
184 {
185 mali_pmm_init();
186
187 #ifdef CONFIG_PM_RUNTIME
188 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
189 pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
190 pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
191 #endif
192 pm_runtime_enable(&(mali_gpu_device.dev));
193 #endif
194
195 #if defined(__MALI_CORE_SCALING_ENABLE__)
196 mali_core_scaling_init(num_pp_cores);
197 #endif
198 return 0;
199 }
200
201 MALI_DEBUG_PRINT(1, ("%s err=%d\n",__FUNCTION__, err));
202
203 platform_device_unregister(&mali_gpu_device);
204
205 return err;
206 }
207
208 void mali_platform_device_unregister(void)
209 {
210 MALI_DEBUG_PRINT(1, ("%s\n", __FUNCTION__));
211
212 #if defined(__MALI_CORE_SCALING_ENABLE__)
213 mali_core_scaling_term();
214 #endif
215
216 mali_pmm_deinit();
217
218 platform_device_unregister(&mali_gpu_device);
219 }
220
221 static void mali_platform_device_release(struct device *device)
222 {
223 MALI_DEBUG_PRINT(1, ("%s\n", __FUNCTION__));
224 }
225
226 static int mali_pm_suspend(struct device *device)
227 {
228 int ret = 0;
229
230 MALI_DEBUG_PRINT(1, ("Mali PM:%s\n", __FUNCTION__));
231
232 if (NULL != device->driver &&
233 NULL != device->driver->pm &&
234 NULL != device->driver->pm->suspend)
235 {
236 /* Need to notify Mali driver about this event */
237 ret = device->driver->pm->suspend(device);
238 }
239
240 _mali_osk_pm_delete_callback_timer();
241 mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
242
243 return ret;
244 }
245
246 static int mali_pm_resume(struct device *device)
247 {
248 int ret = 0;
249
250 MALI_DEBUG_PRINT(1, ("Mali PM: %s\n", __FUNCTION__));
251
252 mali_platform_power_mode_change(MALI_POWER_MODE_ON);
253
254 if (NULL != device->driver &&
255 NULL != device->driver->pm &&
256 NULL != device->driver->pm->resume)
257 {
258 /* Need to notify Mali driver about this event */
259 ret = device->driver->pm->resume(device);
260 }
261
262 return ret;
263 }
264
265
266
267 #if 0//because not used
268 static int mali_pm_freeze(struct device *device)
269 {
270 int ret = 0;
271
272 MALI_DEBUG_PRINT(1, ("Mali PM: %s\n", __FUNCTION__));
273
274 if (NULL != device->driver &&
275 NULL != device->driver->pm &&
276 NULL != device->driver->pm->freeze)
277 {
278 /* Need to notify Mali driver about this event */
279 ret = device->driver->pm->freeze(device);
280 }
281
282 return ret;
283 }
284
285 static int mali_pm_thaw(struct device *device)
286 {
287 int ret = 0;
288
289 MALI_DEBUG_PRINT(1, ("Mali PM: %s\n", __FUNCTION__));
290
291 if (NULL != device->driver &&
292 NULL != device->driver->pm &&
293 NULL != device->driver->pm->thaw)
294 {
295 /* Need to notify Mali driver about this event */
296 ret = device->driver->pm->thaw(device);
297 }
298
299 return ret;
300 }
301 #endif
302
303 #ifdef CONFIG_PM_RUNTIME
304 static int mali_runtime_suspend(struct device *device)
305 {
306 int ret = 0;
307
308 MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
309
310 if (NULL != device->driver &&
311 NULL != device->driver->pm &&
312 NULL != device->driver->pm->runtime_suspend)
313 {
314 /* Need to notify Mali driver about this event */
315 ret = device->driver->pm->runtime_suspend(device);
316 }
317
318 mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
319
320 return ret;
321 }
322
323 static int mali_runtime_resume(struct device *device)
324 {
325 int ret = 0;
326
327 MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
328
329 mali_platform_power_mode_change(MALI_POWER_MODE_ON);
330
331 if (NULL != device->driver &&
332 NULL != device->driver->pm &&
333 NULL != device->driver->pm->runtime_resume)
334 {
335 /* Need to notify Mali driver about this event */
336 ret = device->driver->pm->runtime_resume(device);
337 }
338
339 return ret;
340 }
341
342 static int mali_runtime_idle(struct device *device)
343 {
344 MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
345
346 if (NULL != device->driver &&
347 NULL != device->driver->pm &&
348 NULL != device->driver->pm->runtime_idle)
349 {
350 /* Need to notify Mali driver about this event */
351 int ret = device->driver->pm->runtime_idle(device);
352 if (0 != ret)
353 {
354 return ret;
355 }
356 }
357
358 pm_runtime_suspend(device);
359
360 return 0;
361 }
362 #endif /// CONFIG_PM_RUNTIME