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.
8 #include <linux/platform_device.h>
9 #include <linux/version.h>
11 #ifdef CONFIG_PM_RUNTIME
12 #include <linux/pm_runtime.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>
20 #include "arm_core_scaling.h"
21 #include "mali_executor.h"
22 #include "platform_pmm.h"
25 static int mali_core_scaling_enable
= 0;
26 extern unsigned int current_sample_utilization
;
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);
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
);
40 #ifndef CONFIG_MALI_DT
41 static void mali_platform_device_release(struct device
*device
);
43 #if defined(CONFIG_ARCH_VEXPRESS)
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)
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)
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)
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)
63 #endif /* CONFIG_ARM64 */
65 #elif defined(CONFIG_ARCH_REALVIEW)
67 static struct resource mali_gpu_resources_m300
[] = {
68 MALI_GPU_RESOURCES_MALI300_PMU(0xC0000000, -1, -1, -1, -1)
71 static struct resource mali_gpu_resources_m400_mp1
[] = {
72 MALI_GPU_RESOURCES_MALI400_MP1_PMU(0xC0000000, -1, -1, -1, -1)
75 static struct resource mali_gpu_resources_m400_mp2
[] = {
76 MALI_GPU_RESOURCES_MALI400_MP2_PMU(0xC0000000, -1, -1, -1, -1, -1, -1)
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 */
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 */
95 #if defined(CONFIG_ARM64)
96 .fb_start
= 0x5f000000,
97 .fb_size
= 0x91000000,
99 .fb_start
= 0x80000000,
100 .fb_size
= 0x80000000,
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
,
109 .get_clock_info
= NULL
,
116 #ifndef CONFIG_MALI_DT
117 static struct platform_device mali_gpu_device
= {
118 .name
= MALI_GPU_NAME_UTGARD
,
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),
124 .dev
.platform_data
= &mali_gpu_data
,
125 #if defined(CONFIG_ARM64)
126 .dev
.archdata
.dma_ops
= &noncoherent_swiotlb_dma_ops
,
130 int mali_platform_device_register(void)
133 int num_pp_cores
= 0;
134 #if defined(CONFIG_ARCH_REALVIEW)
138 MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
140 /* Detect present Mali GPU and connect the correct resources to the device */
141 #if defined(CONFIG_ARCH_VEXPRESS)
143 #if defined(CONFIG_ARM64)
144 if (mali_read_phys(0x6F000000) == 0x40601450) {
145 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n"));
147 mali_gpu_device
.num_resources
= ARRAY_SIZE(mali_gpu_resources_m450_mp6
);
148 mali_gpu_device
.resource
= mali_gpu_resources_m450_mp6
;
151 if (mali_read_phys(0xFC000000) == 0x00000450) {
152 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n"));
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"));
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"));
164 mali_gpu_device
.num_resources
= ARRAY_SIZE(mali_gpu_resources_m450_mp4
);
165 mali_gpu_device
.resource
= mali_gpu_resources_m450_mp4
;
167 #endif /* CONFIG_ARM64 */
169 #elif defined(CONFIG_ARCH_REALVIEW)
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"));
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"));
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"));
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 */
199 /* Register the platform device */
200 err
= platform_device_register(&mali_gpu_device
);
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
));
207 pm_runtime_enable(&(mali_gpu_device
.dev
));
209 //MALI_DEBUG_ASSERT(0 < num_pp_cores);
210 mali_core_scaling_init(num_pp_cores
);
218 void mali_platform_device_unregister(void)
220 MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
222 mali_core_scaling_term();
223 platform_device_unregister(&mali_gpu_device
);
225 platform_device_put(&mali_gpu_device
);
227 #if defined(CONFIG_ARCH_REALVIEW)
228 mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */
232 static void mali_platform_device_release(struct device
*device
)
234 MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
237 #else /* CONFIG_MALI_DT */
239 static int mali_pm_suspend(struct device
*device
)
243 MALI_DEBUG_PRINT(3, ("Mali PM:%s\n", __func__
));
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
);
251 /* _mali_osk_pm_delete_callback_timer();*/
252 mali_platform_power_mode_change(device
, MALI_POWER_MODE_DEEP_SLEEP
);
257 static int mali_pm_resume(struct device
*device
)
261 MALI_DEBUG_PRINT(3, ("Mali PM: %s\n", __func__
));
263 mali_platform_power_mode_change(device
, MALI_POWER_MODE_ON
);
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
);
274 #ifdef CONFIG_PM_RUNTIME
275 static int mali_runtime_suspend(struct device
*device
)
279 MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
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
);
287 mali_platform_power_mode_change(device
, MALI_POWER_MODE_LIGHT_SLEEP
);
292 static int mali_runtime_resume(struct device
*device
)
296 MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
298 mali_platform_power_mode_change(device
, MALI_POWER_MODE_ON
);
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
);
309 static int mali_runtime_idle(struct device
*device
)
311 MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
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
);
321 pm_runtime_suspend(device
);
325 #endif /* CONFIG_PM_RUNTIME */
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
,
334 #ifdef CONFIG_PM_RUNTIME
335 .runtime_suspend
= mali_runtime_suspend
,
336 .runtime_resume
= mali_runtime_resume
,
337 .runtime_idle
= mali_runtime_idle
,
341 static struct device_type mali_gpu_device_device_type
= {
342 .pm
= &mali_gpu_device_type_pm_ops
,
345 int mali_platform_device_init(struct platform_device
*device
)
347 int num_pp_cores
= 4;
349 #if defined(CONFIG_ARCH_REALVIEW)
353 /* Detect present Mali GPU and connect the correct resources to the device */
354 #if defined(CONFIG_ARCH_VEXPRESS)
356 #if defined(CONFIG_ARM64)
357 if (mali_read_phys(0x6F000000) == 0x40601450) {
358 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n"));
362 if (mali_read_phys(0xFC000000) == 0x00000450) {
363 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n"));
365 } else if (mali_read_phys(0xFC000000) == 0x40400450) {
366 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP4 device\n"));
371 #elif defined(CONFIG_ARCH_REALVIEW)
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"));
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"));
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"));
389 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
395 if (mali_pmm_init(device
))
398 device
->dev
.type
= &mali_gpu_device_device_type
;
400 err
= platform_device_add_data(device
, &mali_gpu_data
, sizeof(mali_gpu_data
));
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
));
409 pm_runtime_enable(&(device
->dev
));
411 MALI_DEBUG_ASSERT(0 < num_pp_cores
);
412 mali_core_scaling_init(num_pp_cores
);
418 int mali_platform_device_deinit(struct platform_device
*device
)
420 /*MALI_IGNORE(device);*/
422 MALI_DEBUG_PRINT(4, ("mali_platform_device_deinit() called\n"));
424 mali_core_scaling_term();
426 mali_pmm_deinit(device
);
428 #if defined(CONFIG_ARCH_REALVIEW)
429 mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */
435 #endif /* CONFIG_MALI_DT */
437 #if defined(CONFIG_ARCH_REALVIEW)
438 static u32
mali_read_phys(u32 phys_addr
)
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
);
453 static void mali_write_phys(u32 phys_addr
, u32 value
)
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
);
466 static int param_set_core_scaling(const char *val
, const struct kernel_param
*kp
)
468 int ret
= param_set_int(val
, kp
);
470 if (1 == mali_core_scaling_enable
) {
471 mali_core_scaling_sync(mali_executor_get_num_cores_enabled());
476 static struct kernel_param_ops param_ops_core_scaling
= {
477 .set
= param_set_core_scaling
,
478 .get
= param_get_int
,
481 module_param_cb(mali_core_scaling_enable
, ¶m_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");
484 void mali_gpu_utilization_callback(struct mali_gpu_utilization_data
*data
)
486 if (1 == mali_core_scaling_enable
) {
487 mali_core_scaling_update(data
);
489 current_sample_utilization
= (unsigned int)data
->utilization_gpu
;
492 #if defined(CONFIG_MALI_DVFS)
493 int mali_gpu_set_freq(int setting_clock_step
)
495 MALI_DEBUG_PRINT(1, ("mali_gpu_set_freq : incomplete\n"));
498 int mali_gpu_get_freq(void)
500 /* return clock_step */
501 MALI_DEBUG_PRINT(1, ("mali_gpu_get_freq : incomplete\n"));
506 static struct mali_gpu_clk_item clk_item
[] = { {455,1} };
507 static struct mali_gpu_clock mali_clock_info
=
509 .item
= &clk_item
[0],
513 void mali_gpu_get_clock_info(struct mali_gpu_clock
**data
)
515 MALI_DEBUG_PRINT(1, ("mali_gpu_set_freq : incomplete\n"));
516 *data
= &mali_clock_info
;