mali mess
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mali / mali / platform / platform.c
1
2 /**
3 * @file mali_platform.c
4 * Platform specific Mali driver functions for:
5 * - Realview Versatile platforms with ARM11 Mpcore and virtex 5.
6 * - Versatile Express platforms with ARM Cortex-A9 and virtex 6.
7 */
8 #include <linux/platform_device.h>
9 #include <linux/version.h>
10 #include <linux/pm.h>
11 #ifdef CONFIG_PM_RUNTIME
12 #include <linux/pm_runtime.h>
13 #endif
14 #include <asm/io.h>
15 #include <linux/mali/mali_utgard.h>
16 #include "mali_kernel_common.h"
17 #include <linux/dma-mapping.h>
18 #include <linux/moduleparam.h>
19
20 #include "arm_core_scaling.h"
21 #include "mali_executor.h"
22 #include "platform_pmm.h"
23
24
25 static int mali_core_scaling_enable = 0;
26 extern unsigned int current_sample_utilization;
27
28 void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data);
29 #if defined(CONFIG_MALI_DVFS)
30 int mali_gpu_set_freq(int setting_clock_step);
31 void mali_gpu_get_clock_info(struct mali_gpu_clock **data);
32 int mali_gpu_get_freq(void);
33 #endif
34
35 #if defined(CONFIG_ARCH_REALVIEW)
36 static u32 mali_read_phys(u32 phys_addr);
37 static void mali_write_phys(u32 phys_addr, u32 value);
38 #endif
39
40 #ifndef CONFIG_MALI_DT
41 static void mali_platform_device_release(struct device *device);
42
43 #if defined(CONFIG_ARCH_VEXPRESS)
44
45 #if defined(CONFIG_ARM64)
46 /* Juno + Mali-450 MP6 in V7 FPGA */
47 static struct resource mali_gpu_resources_m450_mp6[] = {
48 MALI_GPU_RESOURCES_MALI450_MP6_PMU(0x6F040000, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200)
49 };
50
51 #else
52 static struct resource mali_gpu_resources_m450_mp8[] = {
53 MALI_GPU_RESOURCES_MALI450_MP8_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68)
54 };
55
56 static struct resource mali_gpu_resources_m450_mp6[] = {
57 MALI_GPU_RESOURCES_MALI450_MP6_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68)
58 };
59
60 static struct resource mali_gpu_resources_m450_mp4[] = {
61 MALI_GPU_RESOURCES_MALI450_MP4_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68)
62 };
63 #endif /* CONFIG_ARM64 */
64
65 #elif defined(CONFIG_ARCH_REALVIEW)
66
67 static struct resource mali_gpu_resources_m300[] = {
68 MALI_GPU_RESOURCES_MALI300_PMU(0xC0000000, -1, -1, -1, -1)
69 };
70
71 static struct resource mali_gpu_resources_m400_mp1[] = {
72 MALI_GPU_RESOURCES_MALI400_MP1_PMU(0xC0000000, -1, -1, -1, -1)
73 };
74
75 static struct resource mali_gpu_resources_m400_mp2[] = {
76 MALI_GPU_RESOURCES_MALI400_MP2_PMU(0xC0000000, -1, -1, -1, -1, -1, -1)
77 };
78
79 #endif
80 #endif
81
82 static struct mali_gpu_device_data mali_gpu_data = {
83 #ifndef CONFIG_MALI_DT
84 .pmu_switch_delay = 0xFF, /* do not have to be this high on FPGA, but it is good for testing to have a delay */
85 .max_job_runtime = 60000, /* 60 seconds */
86 #if defined(CONFIG_ARCH_VEXPRESS)
87 .shared_mem_size = 1024 * 1024 * 1024, /* 1GB */
88 #endif
89 #endif
90
91 #if defined(CONFIG_ARCH_REALVIEW)
92 .dedicated_mem_start = 0x80000000, /* Physical start address (use 0xD0000000 for old indirect setup) */
93 .dedicated_mem_size = 0x10000000, /* 256MB */
94 #endif
95 #if defined(CONFIG_ARM64)
96 .fb_start = 0x5f000000,
97 .fb_size = 0x91000000,
98 #else
99 .fb_start = 0x80000000,
100 .fb_size = 0x80000000,
101 #endif
102 .control_interval = 200, /* 200ms */
103 .utilization_callback = mali_gpu_utilization_callback,
104 #if defined(CONFIG_MALI_DVFS)
105 .get_clock_info = mali_gpu_get_clock_info,
106 .get_freq = mali_gpu_get_freq,
107 .set_freq = mali_gpu_set_freq,
108 #else
109 .get_clock_info = NULL,
110 .get_freq = NULL,
111 .set_freq = NULL,
112 #endif
113 };
114
115
116 #ifndef CONFIG_MALI_DT
117 static struct platform_device mali_gpu_device = {
118 .name = MALI_GPU_NAME_UTGARD,
119 .id = 0,
120 .dev.release = mali_platform_device_release,
121 .dev.dma_mask = &mali_gpu_device.dev.coherent_dma_mask,
122 .dev.coherent_dma_mask = DMA_BIT_MASK(32),
123
124 .dev.platform_data = &mali_gpu_data,
125 #if defined(CONFIG_ARM64)
126 .dev.archdata.dma_ops = &noncoherent_swiotlb_dma_ops,
127 #endif
128 };
129
130 int mali_platform_device_register(void)
131 {
132 int err = -1;
133 int num_pp_cores = 0;
134 #if defined(CONFIG_ARCH_REALVIEW)
135 u32 m400_gp_version;
136 #endif
137
138 MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
139
140 /* Detect present Mali GPU and connect the correct resources to the device */
141 #if defined(CONFIG_ARCH_VEXPRESS)
142
143 #if defined(CONFIG_ARM64)
144 if (mali_read_phys(0x6F000000) == 0x40601450) {
145 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n"));
146 num_pp_cores = 6;
147 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp6);
148 mali_gpu_device.resource = mali_gpu_resources_m450_mp6;
149 }
150 #else
151 if (mali_read_phys(0xFC000000) == 0x00000450) {
152 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n"));
153 num_pp_cores = 8;
154 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp8);
155 mali_gpu_device.resource = mali_gpu_resources_m450_mp8;
156 } else if (mali_read_phys(0xFC000000) == 0x40600450) {
157 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n"));
158 num_pp_cores = 6;
159 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp6);
160 mali_gpu_device.resource = mali_gpu_resources_m450_mp6;
161 } else if (mali_read_phys(0xFC000000) == 0x40400450) {
162 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP4 device\n"));
163 num_pp_cores = 4;
164 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp4);
165 mali_gpu_device.resource = mali_gpu_resources_m450_mp4;
166 }
167 #endif /* CONFIG_ARM64 */
168
169 #elif defined(CONFIG_ARCH_REALVIEW)
170
171 m400_gp_version = mali_read_phys(0xC000006C);
172 if ((m400_gp_version & 0xFFFF0000) == 0x0C070000) {
173 MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n"));
174 num_pp_cores = 1;
175 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m300);
176 mali_gpu_device.resource = mali_gpu_resources_m300;
177 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
178 } else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000) {
179 u32 fpga_fw_version = mali_read_phys(0xC0010000);
180 if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F) {
181 /* Mali-400 MP1 r1p0 or r1p1 */
182 MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n"));
183 num_pp_cores = 1;
184 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m400_mp1);
185 mali_gpu_device.resource = mali_gpu_resources_m400_mp1;
186 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
187 } else if (fpga_fw_version == 0x130C000F) {
188 /* Mali-400 MP2 r1p1 */
189 MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n"));
190 num_pp_cores = 2;
191 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m400_mp2);
192 mali_gpu_device.resource = mali_gpu_resources_m400_mp2;
193 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
194 }
195 }
196
197 #endif
198
199 /* Register the platform device */
200 err = platform_device_register(&mali_gpu_device);
201 if (0 == err) {
202 #ifdef CONFIG_PM_RUNTIME
203 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
204 pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
205 pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
206 #endif
207 pm_runtime_enable(&(mali_gpu_device.dev));
208 #endif
209 //MALI_DEBUG_ASSERT(0 < num_pp_cores);
210 mali_core_scaling_init(num_pp_cores);
211
212 return 0;
213 }
214
215 return err;
216 }
217
218 void mali_platform_device_unregister(void)
219 {
220 MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
221
222 mali_core_scaling_term();
223 platform_device_unregister(&mali_gpu_device);
224
225 platform_device_put(&mali_gpu_device);
226
227 #if defined(CONFIG_ARCH_REALVIEW)
228 mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */
229 #endif
230 }
231
232 static void mali_platform_device_release(struct device *device)
233 {
234 MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
235 }
236
237 #else /* CONFIG_MALI_DT */
238
239 static int mali_pm_suspend(struct device *device)
240 {
241 int ret = 0;
242
243 MALI_DEBUG_PRINT(3, ("Mali PM:%s\n", __func__));
244
245 if (NULL != device->driver && NULL != device->driver->pm
246 && NULL != device->driver->pm->suspend) {
247 /* Need to notify Mali driver about this event */
248 ret = device->driver->pm->suspend(device);
249 }
250
251 /* _mali_osk_pm_delete_callback_timer();*/
252 mali_platform_power_mode_change(device, MALI_POWER_MODE_DEEP_SLEEP);
253
254 return ret;
255 }
256
257 static int mali_pm_resume(struct device *device)
258 {
259 int ret = 0;
260
261 MALI_DEBUG_PRINT(3, ("Mali PM: %s\n", __func__));
262
263 mali_platform_power_mode_change(device, MALI_POWER_MODE_ON);
264
265 if (NULL != device->driver && NULL != device->driver->pm
266 && NULL != device->driver->pm->resume) {
267 /* Need to notify Mali driver about this event */
268 ret = device->driver->pm->resume(device);
269 }
270
271 return ret;
272 }
273
274 #ifdef CONFIG_PM_RUNTIME
275 static int mali_runtime_suspend(struct device *device)
276 {
277 int ret = 0;
278
279 MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
280
281 if (NULL != device->driver && NULL != device->driver->pm
282 && NULL != device->driver->pm->runtime_suspend) {
283 /* Need to notify Mali driver about this event */
284 ret = device->driver->pm->runtime_suspend(device);
285 }
286
287 mali_platform_power_mode_change(device, MALI_POWER_MODE_LIGHT_SLEEP);
288
289 return ret;
290 }
291
292 static int mali_runtime_resume(struct device *device)
293 {
294 int ret = 0;
295
296 MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
297
298 mali_platform_power_mode_change(device, MALI_POWER_MODE_ON);
299
300 if (NULL != device->driver && NULL != device->driver->pm
301 && NULL != device->driver->pm->runtime_resume) {
302 /* Need to notify Mali driver about this event */
303 ret = device->driver->pm->runtime_resume(device);
304 }
305
306 return ret;
307 }
308
309 static int mali_runtime_idle(struct device *device)
310 {
311 MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
312
313 if (NULL != device->driver && NULL != device->driver->pm
314 && NULL != device->driver->pm->runtime_idle) {
315 /* Need to notify Mali driver about this event */
316 int ret = device->driver->pm->runtime_idle(device);
317 if (0 != ret)
318 return ret;
319 }
320
321 pm_runtime_suspend(device);
322
323 return 0;
324 }
325 #endif /* CONFIG_PM_RUNTIME */
326
327 static const struct dev_pm_ops mali_gpu_device_type_pm_ops = {
328 .suspend = mali_pm_suspend,
329 .resume = mali_pm_resume,
330 .freeze = mali_pm_suspend,
331 .thaw = mali_pm_resume,
332 .restore = mali_pm_resume,
333
334 #ifdef CONFIG_PM_RUNTIME
335 .runtime_suspend = mali_runtime_suspend,
336 .runtime_resume = mali_runtime_resume,
337 .runtime_idle = mali_runtime_idle,
338 #endif
339 };
340
341 static struct device_type mali_gpu_device_device_type = {
342 .pm = &mali_gpu_device_type_pm_ops,
343 };
344
345 int mali_platform_device_init(struct platform_device *device)
346 {
347 int num_pp_cores = 4;
348 int err = -1;
349 #if defined(CONFIG_ARCH_REALVIEW)
350 u32 m400_gp_version;
351 #endif
352
353 /* Detect present Mali GPU and connect the correct resources to the device */
354 #if defined(CONFIG_ARCH_VEXPRESS)
355
356 #if defined(CONFIG_ARM64)
357 if (mali_read_phys(0x6F000000) == 0x40601450) {
358 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n"));
359 num_pp_cores = 6;
360 }
361 #else
362 if (mali_read_phys(0xFC000000) == 0x00000450) {
363 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n"));
364 num_pp_cores = 8;
365 } else if (mali_read_phys(0xFC000000) == 0x40400450) {
366 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP4 device\n"));
367 num_pp_cores = 4;
368 }
369 #endif
370
371 #elif defined(CONFIG_ARCH_REALVIEW)
372
373 m400_gp_version = mali_read_phys(0xC000006C);
374 if ((m400_gp_version & 0xFFFF0000) == 0x0C070000) {
375 MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n"));
376 num_pp_cores = 1;
377 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
378 } else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000) {
379 u32 fpga_fw_version = mali_read_phys(0xC0010000);
380 if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F) {
381 /* Mali-400 MP1 r1p0 or r1p1 */
382 MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n"));
383 num_pp_cores = 1;
384 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
385 } else if (fpga_fw_version == 0x130C000F) {
386 /* Mali-400 MP2 r1p1 */
387 MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n"));
388 num_pp_cores = 2;
389 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
390 }
391 }
392 #endif
393
394
395 if (mali_pmm_init(device))
396 return err;
397
398 device->dev.type = &mali_gpu_device_device_type;
399
400 err = platform_device_add_data(device, &mali_gpu_data, sizeof(mali_gpu_data));
401
402 if (0 == err) {
403
404 #ifdef CONFIG_PM_RUNTIME
405 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
406 pm_runtime_set_autosuspend_delay(&(device->dev), 2000);
407 pm_runtime_use_autosuspend(&(device->dev));
408 #endif
409 pm_runtime_enable(&(device->dev));
410 #endif
411 MALI_DEBUG_ASSERT(0 < num_pp_cores);
412 mali_core_scaling_init(num_pp_cores);
413 }
414
415 return err;
416 }
417
418 int mali_platform_device_deinit(struct platform_device *device)
419 {
420 /*MALI_IGNORE(device);*/
421
422 MALI_DEBUG_PRINT(4, ("mali_platform_device_deinit() called\n"));
423
424 mali_core_scaling_term();
425
426 mali_pmm_deinit(device);
427
428 #if defined(CONFIG_ARCH_REALVIEW)
429 mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */
430 #endif
431
432 return 0;
433 }
434
435 #endif /* CONFIG_MALI_DT */
436
437 #if defined(CONFIG_ARCH_REALVIEW)
438 static u32 mali_read_phys(u32 phys_addr)
439 {
440 u32 phys_addr_page = phys_addr & 0xFFFFE000;
441 u32 phys_offset = phys_addr & 0x00001FFF;
442 u32 map_size = phys_offset + sizeof(u32);
443 u32 ret = 0xDEADBEEF;
444 void *mem_mapped = ioremap_nocache(phys_addr_page, map_size);
445 if (NULL != mem_mapped) {
446 ret = (u32)ioread32(((u8 *)mem_mapped) + phys_offset);
447 iounmap(mem_mapped);
448 }
449
450 return ret;
451 }
452
453 static void mali_write_phys(u32 phys_addr, u32 value)
454 {
455 u32 phys_addr_page = phys_addr & 0xFFFFE000;
456 u32 phys_offset = phys_addr & 0x00001FFF;
457 u32 map_size = phys_offset + sizeof(u32);
458 void *mem_mapped = ioremap_nocache(phys_addr_page, map_size);
459 if (NULL != mem_mapped) {
460 iowrite32(value, ((u8 *)mem_mapped) + phys_offset);
461 iounmap(mem_mapped);
462 }
463 }
464 #endif
465
466 static int param_set_core_scaling(const char *val, const struct kernel_param *kp)
467 {
468 int ret = param_set_int(val, kp);
469
470 if (1 == mali_core_scaling_enable) {
471 mali_core_scaling_sync(mali_executor_get_num_cores_enabled());
472 }
473 return ret;
474 }
475
476 static struct kernel_param_ops param_ops_core_scaling = {
477 .set = param_set_core_scaling,
478 .get = param_get_int,
479 };
480
481 module_param_cb(mali_core_scaling_enable, &param_ops_core_scaling, &mali_core_scaling_enable, 0644);
482 MODULE_PARM_DESC(mali_core_scaling_enable, "1 means to enable core scaling policy, 0 means to disable core scaling policy");
483
484 void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data)
485 {
486 if (1 == mali_core_scaling_enable) {
487 mali_core_scaling_update(data);
488 }
489 current_sample_utilization = (unsigned int)data->utilization_gpu;
490 }
491
492 #if defined(CONFIG_MALI_DVFS)
493 int mali_gpu_set_freq(int setting_clock_step)
494 {
495 MALI_DEBUG_PRINT(1, ("mali_gpu_set_freq : incomplete\n"));
496 }
497
498 int mali_gpu_get_freq(void)
499 {
500 /* return clock_step */
501 MALI_DEBUG_PRINT(1, ("mali_gpu_get_freq : incomplete\n"));
502
503 return 0;
504 }
505
506 static struct mali_gpu_clk_item clk_item[] = { {455,1} };
507 static struct mali_gpu_clock mali_clock_info =
508 {
509 .item = &clk_item[0],
510 .num_of_steps = 1,
511 };
512
513 void mali_gpu_get_clock_info(struct mali_gpu_clock **data)
514 {
515 MALI_DEBUG_PRINT(1, ("mali_gpu_set_freq : incomplete\n"));
516 *data = &mali_clock_info;
517 }
518 #endif