2 * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
4 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
7 * A copy of the licence is included with the program, and can also be obtained from Free Software
8 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 * @file mali_platform.c
13 * Platform specific Mali driver functions for:
14 * - Realview Versatile platforms with ARM11 Mpcore and virtex 5.
15 * - Versatile Express platforms with ARM Cortex-A9 and virtex 6.
17 #include <linux/platform_device.h>
18 #include <linux/version.h>
20 #include "mali_kernel_linux.h"
21 #ifdef CONFIG_PM_RUNTIME
22 #include <linux/pm_runtime.h>
25 #include <linux/mali/mali_utgard.h>
26 #include "mali_kernel_common.h"
27 #include <linux/dma-mapping.h>
28 #include <linux/moduleparam.h>
30 #include "arm_core_scaling.h"
31 #include "mali_executor.h"
34 static int mali_core_scaling_enable = 0;
36 void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data);
37 static u32 mali_read_phys(u32 phys_addr);
38 #if defined(CONFIG_ARCH_REALVIEW)
39 static void mali_write_phys(u32 phys_addr, u32 value);
42 #ifndef CONFIG_MALI_DT
43 static void mali_platform_device_release(struct device *device);
45 #if defined(CONFIG_ARCH_VEXPRESS)
47 #if defined(CONFIG_ARM64)
48 /* Juno + Mali-450 MP6 in V7 FPGA */
49 static struct resource mali_gpu_resources_m450_mp6[] = {
50 MALI_GPU_RESOURCES_MALI450_MP6_PMU(0x6F040000, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200)
53 static struct resource mali_gpu_resources_m470_mp4[] = {
54 MALI_GPU_RESOURCES_MALI470_MP4_PMU(0x6F040000, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200)
57 static struct resource mali_gpu_resources_m470_mp3[] = {
58 MALI_GPU_RESOURCES_MALI470_MP3_PMU(0x6F040000, 200, 200, 200, 200, 200, 200, 200, 200, 200)
61 static struct resource mali_gpu_resources_m470_mp2[] = {
62 MALI_GPU_RESOURCES_MALI470_MP2_PMU(0x6F040000, 200, 200, 200, 200, 200, 200, 200)
65 static struct resource mali_gpu_resources_m470_mp1[] = {
66 MALI_GPU_RESOURCES_MALI470_MP1_PMU(0x6F040000, 200, 200, 200, 200, 200)
70 static struct resource mali_gpu_resources_m450_mp8[] = {
71 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)
74 static struct resource mali_gpu_resources_m450_mp6[] = {
75 MALI_GPU_RESOURCES_MALI450_MP6_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68)
78 static struct resource mali_gpu_resources_m450_mp4[] = {
79 MALI_GPU_RESOURCES_MALI450_MP4_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68)
82 static struct resource mali_gpu_resources_m470_mp4[] = {
83 MALI_GPU_RESOURCES_MALI470_MP4_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68)
85 #endif /* CONFIG_ARM64 */
87 #elif defined(CONFIG_ARCH_REALVIEW)
89 static struct resource mali_gpu_resources_m300[] = {
90 MALI_GPU_RESOURCES_MALI300_PMU(0xC0000000, -1, -1, -1, -1)
93 static struct resource mali_gpu_resources_m400_mp1[] = {
94 MALI_GPU_RESOURCES_MALI400_MP1_PMU(0xC0000000, -1, -1, -1, -1)
97 static struct resource mali_gpu_resources_m400_mp2[] = {
98 MALI_GPU_RESOURCES_MALI400_MP2_PMU(0xC0000000, -1, -1, -1, -1, -1, -1)
104 static struct mali_gpu_device_data mali_gpu_data = {
105 #ifndef CONFIG_MALI_DT
106 .pmu_switch_delay = 0xFF, /* do not have to be this high on FPGA, but it is good for testing to have a delay */
107 .max_job_runtime = 60000, /* 60 seconds */
108 #if defined(CONFIG_ARCH_VEXPRESS)
109 .shared_mem_size = 256 * 1024 * 1024, /* 256MB */
113 #if defined(CONFIG_ARCH_REALVIEW)
114 .dedicated_mem_start = 0x80000000, /* Physical start address (use 0xD0000000 for old indirect setup) */
115 .dedicated_mem_size = 0x10000000, /* 256MB */
117 #if defined(CONFIG_ARM64)
118 /* Some framebuffer drivers get the framebuffer dynamically, such as through GEM,
119 * in which the memory resource can't be predicted in advance.
122 .fb_size = 0xFFFFF000,
124 .fb_start = 0xe0000000,
125 .fb_size = 0x01000000,
127 .control_interval = 1000, /* 1000ms */
128 .utilization_callback = mali_gpu_utilization_callback,
129 .get_clock_info = NULL,
134 #ifndef CONFIG_MALI_DT
135 static struct platform_device mali_gpu_device = {
136 .name = MALI_GPU_NAME_UTGARD,
138 .dev.release = mali_platform_device_release,
139 .dev.dma_mask = &mali_gpu_device.dev.coherent_dma_mask,
140 .dev.coherent_dma_mask = DMA_BIT_MASK(32),
142 .dev.platform_data = &mali_gpu_data,
145 int mali_platform_device_register(void)
148 int num_pp_cores = 0;
149 #if defined(CONFIG_ARCH_REALVIEW)
153 MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
155 /* Detect present Mali GPU and connect the correct resources to the device */
156 #if defined(CONFIG_ARCH_VEXPRESS)
158 #if defined(CONFIG_ARM64)
159 mali_gpu_device.dev.archdata.dma_ops = dma_ops;
160 if ((mali_read_phys(0x6F000000) & 0x00600450) == 0x00600450) {
161 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n"));
163 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp6);
164 mali_gpu_device.resource = mali_gpu_resources_m450_mp6;
165 } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00400430) {
166 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP4 device\n"));
168 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp4);
169 mali_gpu_device.resource = mali_gpu_resources_m470_mp4;
170 } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00300430) {
171 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP3 device\n"));
173 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp3);
174 mali_gpu_device.resource = mali_gpu_resources_m470_mp3;
175 } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00200430) {
176 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP2 device\n"));
178 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp2);
179 mali_gpu_device.resource = mali_gpu_resources_m470_mp2;
180 } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00100430) {
181 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP1 device\n"));
183 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp1);
184 mali_gpu_device.resource = mali_gpu_resources_m470_mp1;
187 if (mali_read_phys(0xFC000000) == 0x00000450) {
188 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n"));
190 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp8);
191 mali_gpu_device.resource = mali_gpu_resources_m450_mp8;
192 } else if (mali_read_phys(0xFC000000) == 0x40600450) {
193 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n"));
195 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp6);
196 mali_gpu_device.resource = mali_gpu_resources_m450_mp6;
197 } else if (mali_read_phys(0xFC000000) == 0x40400450) {
198 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP4 device\n"));
200 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp4);
201 mali_gpu_device.resource = mali_gpu_resources_m450_mp4;
202 } else if (mali_read_phys(0xFC000000) == 0xFFFFFFFF) {
203 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP4 device\n"));
205 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp4);
206 mali_gpu_device.resource = mali_gpu_resources_m470_mp4;
208 #endif /* CONFIG_ARM64 */
210 #elif defined(CONFIG_ARCH_REALVIEW)
212 m400_gp_version = mali_read_phys(0xC000006C);
213 if ((m400_gp_version & 0xFFFF0000) == 0x0C070000) {
214 MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n"));
216 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m300);
217 mali_gpu_device.resource = mali_gpu_resources_m300;
218 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
219 } else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000) {
220 u32 fpga_fw_version = mali_read_phys(0xC0010000);
221 if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F) {
222 /* Mali-400 MP1 r1p0 or r1p1 */
223 MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n"));
225 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m400_mp1);
226 mali_gpu_device.resource = mali_gpu_resources_m400_mp1;
227 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
228 } else if (fpga_fw_version == 0x130C000F) {
229 /* Mali-400 MP2 r1p1 */
230 MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n"));
232 mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m400_mp2);
233 mali_gpu_device.resource = mali_gpu_resources_m400_mp2;
234 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
239 /* Register the platform device */
240 err = platform_device_register(&mali_gpu_device);
242 #ifdef CONFIG_PM_RUNTIME
243 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
244 pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
245 pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
247 pm_runtime_enable(&(mali_gpu_device.dev));
249 MALI_DEBUG_ASSERT(0 < num_pp_cores);
250 mali_core_scaling_init(num_pp_cores);
258 void mali_platform_device_unregister(void)
260 MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
262 mali_core_scaling_term();
263 platform_device_unregister(&mali_gpu_device);
265 platform_device_put(&mali_gpu_device);
267 #if defined(CONFIG_ARCH_REALVIEW)
268 mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */
272 static void mali_platform_device_release(struct device *device)
274 MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
277 #else /* CONFIG_MALI_DT */
278 int mali_platform_device_init(struct platform_device *device)
280 int num_pp_cores = 0;
282 #if defined(CONFIG_ARCH_REALVIEW)
286 /* Detect present Mali GPU and connect the correct resources to the device */
287 #if defined(CONFIG_ARCH_VEXPRESS)
289 #if defined(CONFIG_ARM64)
290 if ((mali_read_phys(0x6F000000) & 0x00600450) == 0x00600450) {
291 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n"));
293 } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00400430) {
294 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP4 device\n"));
296 } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00300430) {
297 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP3 device\n"));
299 } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00200430) {
300 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP2 device\n"));
302 } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00100430) {
303 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP1 device\n"));
307 if (mali_read_phys(0xFC000000) == 0x00000450) {
308 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n"));
310 } else if (mali_read_phys(0xFC000000) == 0x40400450) {
311 MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP4 device\n"));
313 } else if (mali_read_phys(0xFC000000) == 0xFFFFFFFF) {
314 MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP4 device\n"));
319 #elif defined(CONFIG_ARCH_REALVIEW)
321 m400_gp_version = mali_read_phys(0xC000006C);
322 if ((m400_gp_version & 0xFFFF0000) == 0x0C070000) {
323 MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n"));
325 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
326 } else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000) {
327 u32 fpga_fw_version = mali_read_phys(0xC0010000);
328 if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F) {
329 /* Mali-400 MP1 r1p0 or r1p1 */
330 MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n"));
332 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
333 } else if (fpga_fw_version == 0x130C000F) {
334 /* Mali-400 MP2 r1p1 */
335 MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n"));
337 mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
342 /* After kernel 3.15 device tree will default set dev
343 * related parameters in of_platform_device_create_pdata.
344 * But kernel changes from version to version,
345 * For example 3.10 didn't include device->dev.dma_mask parameter setting,
346 * if we didn't include here will cause dma_mapping error,
347 * but in kernel 3.15 it include device->dev.dma_mask parameter setting,
348 * so it's better to set must need paramter by DDK itself.
350 if (!device->dev.dma_mask)
351 device->dev.dma_mask = &device->dev.coherent_dma_mask;
352 device->dev.archdata.dma_ops = dma_ops;
354 err = platform_device_add_data(device, &mali_gpu_data, sizeof(mali_gpu_data));
357 #ifdef CONFIG_PM_RUNTIME
358 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
359 pm_runtime_set_autosuspend_delay(&(device->dev), 1000);
360 pm_runtime_use_autosuspend(&(device->dev));
362 pm_runtime_enable(&(device->dev));
364 MALI_DEBUG_ASSERT(0 < num_pp_cores);
365 mali_core_scaling_init(num_pp_cores);
371 int mali_platform_device_deinit(struct platform_device *device)
375 MALI_DEBUG_PRINT(4, ("mali_platform_device_deinit() called\n"));
377 mali_core_scaling_term();
379 #if defined(CONFIG_ARCH_REALVIEW)
380 mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */
386 #endif /* CONFIG_MALI_DT */
388 static u32 mali_read_phys(u32 phys_addr)
390 u32 phys_addr_page = phys_addr & 0xFFFFE000;
391 u32 phys_offset = phys_addr & 0x00001FFF;
392 u32 map_size = phys_offset + sizeof(u32);
393 u32 ret = 0xDEADBEEF;
394 void *mem_mapped = ioremap_nocache(phys_addr_page, map_size);
395 if (NULL != mem_mapped) {
396 ret = (u32)ioread32(((u8 *)mem_mapped) + phys_offset);
403 #if defined(CONFIG_ARCH_REALVIEW)
404 static void mali_write_phys(u32 phys_addr, u32 value)
406 u32 phys_addr_page = phys_addr & 0xFFFFE000;
407 u32 phys_offset = phys_addr & 0x00001FFF;
408 u32 map_size = phys_offset + sizeof(u32);
409 void *mem_mapped = ioremap_nocache(phys_addr_page, map_size);
410 if (NULL != mem_mapped) {
411 iowrite32(value, ((u8 *)mem_mapped) + phys_offset);
417 static int param_set_core_scaling(const char *val, const struct kernel_param *kp)
419 int ret = param_set_int(val, kp);
421 if (1 == mali_core_scaling_enable) {
422 mali_core_scaling_sync(mali_executor_get_num_cores_enabled());
427 static struct kernel_param_ops param_ops_core_scaling = {
428 .set = param_set_core_scaling,
429 .get = param_get_int,
432 module_param_cb(mali_core_scaling_enable, ¶m_ops_core_scaling, &mali_core_scaling_enable, 0644);
433 MODULE_PARM_DESC(mali_core_scaling_enable, "1 means to enable core scaling policy, 0 means to disable core scaling policy");
435 void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data)
437 if (1 == mali_core_scaling_enable) {
438 mali_core_scaling_update(data);