diff options
author | Linaro CI <ci_notify@linaro.org> | 2017-09-24 20:35:18 +0000 |
---|---|---|
committer | Linaro CI <ci_notify@linaro.org> | 2017-09-24 20:35:18 +0000 |
commit | c03adb6848aa7e80ad0c0e46b9f6d96ba0a91822 (patch) | |
tree | 05de08cd2d77fc5697e9e6fc1fae5ef23a1d0a85 /drivers/gpu/arm/utgard/platform | |
parent | 6ce85a78b6151e8ab2eac57e1447d90d3efb551d (diff) | |
parent | 357fdc8959dc79696d9c43c2a3f7a93e3a503d87 (diff) |
Merge remote-tracking branch 'sumit-lts/lts-4.4.y-hikey' into linux-4.4.y4.4.89-rc1-hikey-20170924
Diffstat (limited to 'drivers/gpu/arm/utgard/platform')
5 files changed, 1354 insertions, 0 deletions
diff --git a/drivers/gpu/arm/utgard/platform/arm/arm.c b/drivers/gpu/arm/utgard/platform/arm/arm.c new file mode 100644 index 000000000000..41ad63c0793b --- /dev/null +++ b/drivers/gpu/arm/utgard/platform/arm/arm.c @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform.c + * Platform specific Mali driver functions for: + * - Realview Versatile platforms with ARM11 Mpcore and virtex 5. + * - Versatile Express platforms with ARM Cortex-A9 and virtex 6. + */ +#include <linux/platform_device.h> +#include <linux/version.h> +#include <linux/pm.h> +#ifdef CONFIG_PM_RUNTIME +#include <linux/pm_runtime.h> +#endif +#include <asm/io.h> +#include <linux/mali/mali_utgard.h> +#include "mali_kernel_common.h" +#include <linux/dma-mapping.h> +#include <linux/moduleparam.h> + +#include "arm_core_scaling.h" +#include "mali_executor.h" + + +static int mali_core_scaling_enable = 0; + +void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data); +static u32 mali_read_phys(u32 phys_addr); +#if defined(CONFIG_ARCH_REALVIEW) +static void mali_write_phys(u32 phys_addr, u32 value); +#endif + +#ifndef CONFIG_MALI_DT +static void mali_platform_device_release(struct device *device); + +#if defined(CONFIG_ARCH_VEXPRESS) + +#if defined(CONFIG_ARM64) +/* Juno + Mali-450 MP6 in V7 FPGA */ +static struct resource mali_gpu_resources_m450_mp6[] = { + MALI_GPU_RESOURCES_MALI450_MP6_PMU(0x6F040000, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200) +}; + +static struct resource mali_gpu_resources_m470_mp4[] = { + MALI_GPU_RESOURCES_MALI470_MP4_PMU(0x6F040000, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200) +}; + +static struct resource mali_gpu_resources_m470_mp3[] = { + MALI_GPU_RESOURCES_MALI470_MP3_PMU(0x6F040000, 200, 200, 200, 200, 200, 200, 200, 200, 200) +}; + +static struct resource mali_gpu_resources_m470_mp2[] = { + MALI_GPU_RESOURCES_MALI470_MP2_PMU(0x6F040000, 200, 200, 200, 200, 200, 200, 200) +}; + +static struct resource mali_gpu_resources_m470_mp1[] = { + MALI_GPU_RESOURCES_MALI470_MP1_PMU(0x6F040000, 200, 200, 200, 200, 200) +}; + +#else +static struct resource mali_gpu_resources_m450_mp8[] = { + 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) +}; + +static struct resource mali_gpu_resources_m450_mp6[] = { + MALI_GPU_RESOURCES_MALI450_MP6_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68) +}; + +static struct resource mali_gpu_resources_m450_mp4[] = { + MALI_GPU_RESOURCES_MALI450_MP4_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68) +}; + +static struct resource mali_gpu_resources_m470_mp4[] = { + MALI_GPU_RESOURCES_MALI470_MP4_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68) +}; +#endif /* CONFIG_ARM64 */ + +#elif defined(CONFIG_ARCH_REALVIEW) + +static struct resource mali_gpu_resources_m300[] = { + MALI_GPU_RESOURCES_MALI300_PMU(0xC0000000, -1, -1, -1, -1) +}; + +static struct resource mali_gpu_resources_m400_mp1[] = { + MALI_GPU_RESOURCES_MALI400_MP1_PMU(0xC0000000, -1, -1, -1, -1) +}; + +static struct resource mali_gpu_resources_m400_mp2[] = { + MALI_GPU_RESOURCES_MALI400_MP2_PMU(0xC0000000, -1, -1, -1, -1, -1, -1) +}; + +#endif +#endif + +static struct mali_gpu_device_data mali_gpu_data = { +#ifndef CONFIG_MALI_DT + .pmu_switch_delay = 0xFF, /* do not have to be this high on FPGA, but it is good for testing to have a delay */ + .max_job_runtime = 60000, /* 60 seconds */ +#if defined(CONFIG_ARCH_VEXPRESS) + .shared_mem_size = 256 * 1024 * 1024, /* 256MB */ +#endif +#endif + +#if defined(CONFIG_ARCH_REALVIEW) + .dedicated_mem_start = 0x80000000, /* Physical start address (use 0xD0000000 for old indirect setup) */ + .dedicated_mem_size = 0x10000000, /* 256MB */ +#endif +#if defined(CONFIG_ARM64) + /* Some framebuffer drivers get the framebuffer dynamically, such as through GEM, + * in which the memory resource can't be predicted in advance. + */ + .fb_start = 0x0, + .fb_size = 0xFFFFF000, +#else + .fb_start = 0xe0000000, + .fb_size = 0x01000000, +#endif + .control_interval = 1000, /* 1000ms */ + .utilization_callback = mali_gpu_utilization_callback, + .get_clock_info = NULL, + .get_freq = NULL, + .set_freq = NULL, +}; + +#ifndef CONFIG_MALI_DT +static struct platform_device mali_gpu_device = { + .name = MALI_GPU_NAME_UTGARD, + .id = 0, + .dev.release = mali_platform_device_release, + .dev.dma_mask = &mali_gpu_device.dev.coherent_dma_mask, + .dev.coherent_dma_mask = DMA_BIT_MASK(32), + + .dev.platform_data = &mali_gpu_data, +}; + +int mali_platform_device_register(void) +{ + int err = -1; + int num_pp_cores = 0; +#if defined(CONFIG_ARCH_REALVIEW) + u32 m400_gp_version; +#endif + + MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n")); + + /* Detect present Mali GPU and connect the correct resources to the device */ +#if defined(CONFIG_ARCH_VEXPRESS) + +#if defined(CONFIG_ARM64) + mali_gpu_device.dev.archdata.dma_ops = dma_ops; + if ((mali_read_phys(0x6F000000) & 0x00600450) == 0x00600450) { + MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n")); + num_pp_cores = 6; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp6); + mali_gpu_device.resource = mali_gpu_resources_m450_mp6; + } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00400430) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP4 device\n")); + num_pp_cores = 4; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp4); + mali_gpu_device.resource = mali_gpu_resources_m470_mp4; + } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00300430) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP3 device\n")); + num_pp_cores = 3; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp3); + mali_gpu_device.resource = mali_gpu_resources_m470_mp3; + } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00200430) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP2 device\n")); + num_pp_cores = 2; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp2); + mali_gpu_device.resource = mali_gpu_resources_m470_mp2; + } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00100430) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP1 device\n")); + num_pp_cores = 1; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp1); + mali_gpu_device.resource = mali_gpu_resources_m470_mp1; + } +#else + if (mali_read_phys(0xFC000000) == 0x00000450) { + MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n")); + num_pp_cores = 8; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp8); + mali_gpu_device.resource = mali_gpu_resources_m450_mp8; + } else if (mali_read_phys(0xFC000000) == 0x40600450) { + MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n")); + num_pp_cores = 6; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp6); + mali_gpu_device.resource = mali_gpu_resources_m450_mp6; + } else if (mali_read_phys(0xFC000000) == 0x40400450) { + MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP4 device\n")); + num_pp_cores = 4; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp4); + mali_gpu_device.resource = mali_gpu_resources_m450_mp4; + } else if (mali_read_phys(0xFC000000) == 0xFFFFFFFF) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP4 device\n")); + num_pp_cores = 4; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m470_mp4); + mali_gpu_device.resource = mali_gpu_resources_m470_mp4; + } +#endif /* CONFIG_ARM64 */ + +#elif defined(CONFIG_ARCH_REALVIEW) + + m400_gp_version = mali_read_phys(0xC000006C); + if ((m400_gp_version & 0xFFFF0000) == 0x0C070000) { + MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n")); + num_pp_cores = 1; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m300); + mali_gpu_device.resource = mali_gpu_resources_m300; + mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ + } else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000) { + u32 fpga_fw_version = mali_read_phys(0xC0010000); + if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F) { + /* Mali-400 MP1 r1p0 or r1p1 */ + MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n")); + num_pp_cores = 1; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m400_mp1); + mali_gpu_device.resource = mali_gpu_resources_m400_mp1; + mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ + } else if (fpga_fw_version == 0x130C000F) { + /* Mali-400 MP2 r1p1 */ + MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n")); + num_pp_cores = 2; + mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_m400_mp2); + mali_gpu_device.resource = mali_gpu_resources_m400_mp2; + mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ + } + } + +#endif + /* Register the platform device */ + err = platform_device_register(&mali_gpu_device); + if (0 == err) { +#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) + pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000); + pm_runtime_use_autosuspend(&(mali_gpu_device.dev)); +#endif + pm_runtime_enable(&(mali_gpu_device.dev)); +#endif + MALI_DEBUG_ASSERT(0 < num_pp_cores); + mali_core_scaling_init(num_pp_cores); + + return 0; + } + + return err; +} + +void mali_platform_device_unregister(void) +{ + MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n")); + + mali_core_scaling_term(); + platform_device_unregister(&mali_gpu_device); + + platform_device_put(&mali_gpu_device); + +#if defined(CONFIG_ARCH_REALVIEW) + mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */ +#endif +} + +static void mali_platform_device_release(struct device *device) +{ + MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n")); +} + +#else /* CONFIG_MALI_DT */ +int mali_platform_device_init(struct platform_device *device) +{ + int num_pp_cores = 0; + int err = -1; +#if defined(CONFIG_ARCH_REALVIEW) + u32 m400_gp_version; +#endif + + /* Detect present Mali GPU and connect the correct resources to the device */ +#if defined(CONFIG_ARCH_VEXPRESS) + +#if defined(CONFIG_ARM64) + if ((mali_read_phys(0x6F000000) & 0x00600450) == 0x00600450) { + MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n")); + num_pp_cores = 6; + } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00400430) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP4 device\n")); + num_pp_cores = 4; + } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00300430) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP3 device\n")); + num_pp_cores = 3; + } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00200430) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP2 device\n")); + num_pp_cores = 2; + } else if ((mali_read_phys(0x6F000000) & 0x00F00430) == 0x00100430) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP1 device\n")); + num_pp_cores = 1; + } +#else + if (mali_read_phys(0xFC000000) == 0x00000450) { + MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n")); + num_pp_cores = 8; + } else if (mali_read_phys(0xFC000000) == 0x40400450) { + MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP4 device\n")); + num_pp_cores = 4; + } else if (mali_read_phys(0xFC000000) == 0xFFFFFFFF) { + MALI_DEBUG_PRINT(4, ("Registering Mali-470 MP4 device\n")); + num_pp_cores = 4; + } +#endif + +#elif defined(CONFIG_ARCH_REALVIEW) + + m400_gp_version = mali_read_phys(0xC000006C); + if ((m400_gp_version & 0xFFFF0000) == 0x0C070000) { + MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n")); + num_pp_cores = 1; + mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ + } else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000) { + u32 fpga_fw_version = mali_read_phys(0xC0010000); + if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F) { + /* Mali-400 MP1 r1p0 or r1p1 */ + MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n")); + num_pp_cores = 1; + mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ + } else if (fpga_fw_version == 0x130C000F) { + /* Mali-400 MP2 r1p1 */ + MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n")); + num_pp_cores = 2; + mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ + } + } +#endif + + /* After kernel 3.15 device tree will default set dev + * related parameters in of_platform_device_create_pdata. + * But kernel changes from version to version, + * For example 3.10 didn't include device->dev.dma_mask parameter setting, + * if we didn't include here will cause dma_mapping error, + * but in kernel 3.15 it include device->dev.dma_mask parameter setting, + * so it's better to set must need paramter by DDK itself. + */ + if (!device->dev.dma_mask) + device->dev.dma_mask = &device->dev.coherent_dma_mask; + device->dev.archdata.dma_ops = dma_ops; + + err = platform_device_add_data(device, &mali_gpu_data, sizeof(mali_gpu_data)); + + if (0 == err) { +#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) + pm_runtime_set_autosuspend_delay(&(device->dev), 1000); + pm_runtime_use_autosuspend(&(device->dev)); +#endif + pm_runtime_enable(&(device->dev)); +#endif + MALI_DEBUG_ASSERT(0 < num_pp_cores); + mali_core_scaling_init(num_pp_cores); + } + + return err; +} + +int mali_platform_device_deinit(struct platform_device *device) +{ + MALI_IGNORE(device); + + MALI_DEBUG_PRINT(4, ("mali_platform_device_deinit() called\n")); + + mali_core_scaling_term(); + +#if defined(CONFIG_ARCH_REALVIEW) + mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */ +#endif + + return 0; +} + +#endif /* CONFIG_MALI_DT */ + +static u32 mali_read_phys(u32 phys_addr) +{ + u32 phys_addr_page = phys_addr & 0xFFFFE000; + u32 phys_offset = phys_addr & 0x00001FFF; + u32 map_size = phys_offset + sizeof(u32); + u32 ret = 0xDEADBEEF; + void *mem_mapped = ioremap_nocache(phys_addr_page, map_size); + if (NULL != mem_mapped) { + ret = (u32)ioread32(((u8 *)mem_mapped) + phys_offset); + iounmap(mem_mapped); + } + + return ret; +} + +#if defined(CONFIG_ARCH_REALVIEW) +static void mali_write_phys(u32 phys_addr, u32 value) +{ + u32 phys_addr_page = phys_addr & 0xFFFFE000; + u32 phys_offset = phys_addr & 0x00001FFF; + u32 map_size = phys_offset + sizeof(u32); + void *mem_mapped = ioremap_nocache(phys_addr_page, map_size); + if (NULL != mem_mapped) { + iowrite32(value, ((u8 *)mem_mapped) + phys_offset); + iounmap(mem_mapped); + } +} +#endif + +static int param_set_core_scaling(const char *val, const struct kernel_param *kp) +{ + int ret = param_set_int(val, kp); + + if (1 == mali_core_scaling_enable) { + mali_core_scaling_sync(mali_executor_get_num_cores_enabled()); + } + return ret; +} + +static struct kernel_param_ops param_ops_core_scaling = { + .set = param_set_core_scaling, + .get = param_get_int, +}; + +module_param_cb(mali_core_scaling_enable, ¶m_ops_core_scaling, &mali_core_scaling_enable, 0644); +MODULE_PARM_DESC(mali_core_scaling_enable, "1 means to enable core scaling policy, 0 means to disable core scaling policy"); + +void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data) +{ + if (1 == mali_core_scaling_enable) { + mali_core_scaling_update(data); + } +} diff --git a/drivers/gpu/arm/utgard/platform/arm/arm_core_scaling.c b/drivers/gpu/arm/utgard/platform/arm/arm_core_scaling.c new file mode 100644 index 000000000000..2c24742eb4de --- /dev/null +++ b/drivers/gpu/arm/utgard/platform/arm/arm_core_scaling.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2013-2015 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file arm_core_scaling.c + * Example core scaling policy. + */ + +#include "arm_core_scaling.h" + +#include <linux/mali/mali_utgard.h> +#include "mali_kernel_common.h" + +#include <linux/workqueue.h> + +static int num_cores_total; +static int num_cores_enabled; + +static struct work_struct wq_work; + +static void set_num_cores(struct work_struct *work) +{ + int err = mali_perf_set_num_pp_cores(num_cores_enabled); + MALI_DEBUG_ASSERT(0 == err); + MALI_IGNORE(err); +} + +static void enable_one_core(void) +{ + if (num_cores_enabled < num_cores_total) { + ++num_cores_enabled; + schedule_work(&wq_work); + MALI_DEBUG_PRINT(3, ("Core scaling: Enabling one more core\n")); + } + + MALI_DEBUG_ASSERT(1 <= num_cores_enabled); + MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled); +} + +static void disable_one_core(void) +{ + if (1 < num_cores_enabled) { + --num_cores_enabled; + schedule_work(&wq_work); + MALI_DEBUG_PRINT(3, ("Core scaling: Disabling one core\n")); + } + + MALI_DEBUG_ASSERT(1 <= num_cores_enabled); + MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled); +} + +static void enable_max_num_cores(void) +{ + if (num_cores_enabled < num_cores_total) { + num_cores_enabled = num_cores_total; + schedule_work(&wq_work); + MALI_DEBUG_PRINT(3, ("Core scaling: Enabling maximum number of cores\n")); + } + + MALI_DEBUG_ASSERT(num_cores_total == num_cores_enabled); +} + +void mali_core_scaling_init(int num_pp_cores) +{ + INIT_WORK(&wq_work, set_num_cores); + + num_cores_total = num_pp_cores; + num_cores_enabled = num_pp_cores; + + /* NOTE: Mali is not fully initialized at this point. */ +} + +void mali_core_scaling_sync(int num_cores) +{ + num_cores_enabled = num_cores; +} + +void mali_core_scaling_term(void) +{ + flush_scheduled_work(); +} + +#define PERCENT_OF(percent, max) ((int) ((percent)*(max)/100.0 + 0.5)) + +void mali_core_scaling_update(struct mali_gpu_utilization_data *data) +{ + /* + * This function implements a very trivial PP core scaling algorithm. + * + * It is _NOT_ of production quality. + * The only intention behind this algorithm is to exercise and test the + * core scaling functionality of the driver. + * It is _NOT_ tuned for neither power saving nor performance! + * + * Other metrics than PP utilization need to be considered as well + * in order to make a good core scaling algorithm. + */ + + MALI_DEBUG_PRINT(3, ("Utilization: (%3d, %3d, %3d), cores enabled: %d/%d\n", data->utilization_gpu, data->utilization_gp, data->utilization_pp, num_cores_enabled, num_cores_total)); + + /* NOTE: this function is normally called directly from the utilization callback which is in + * timer context. */ + + if (PERCENT_OF(90, 256) < data->utilization_pp) { + enable_max_num_cores(); + } else if (PERCENT_OF(50, 256) < data->utilization_pp) { + enable_one_core(); + } else if (PERCENT_OF(40, 256) < data->utilization_pp) { + /* do nothing */ + } else if (PERCENT_OF(0, 256) < data->utilization_pp) { + disable_one_core(); + } else { + /* do nothing */ + } +} diff --git a/drivers/gpu/arm/utgard/platform/arm/arm_core_scaling.h b/drivers/gpu/arm/utgard/platform/arm/arm_core_scaling.h new file mode 100644 index 000000000000..325b5b1c6894 --- /dev/null +++ b/drivers/gpu/arm/utgard/platform/arm/arm_core_scaling.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013, 2015 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file arm_core_scaling.h + * Example core scaling policy. + */ + +#ifndef __ARM_CORE_SCALING_H__ +#define __ARM_CORE_SCALING_H__ + +struct mali_gpu_utilization_data; + +/** + * Initialize core scaling policy. + * + * @note The core scaling policy will assume that all PP cores are on initially. + * + * @param num_pp_cores Total number of PP cores. + */ +void mali_core_scaling_init(int num_pp_cores); + +/** + * Terminate core scaling policy. + */ +void mali_core_scaling_term(void); + +/** + * Update core scaling policy with new utilization data. + * + * @param data Utilization data. + */ +void mali_core_scaling_update(struct mali_gpu_utilization_data *data); + +void mali_core_scaling_sync(int num_cores); + +#endif /* __ARM_CORE_SCALING_H__ */ diff --git a/drivers/gpu/arm/utgard/platform/hikey/mali_hikey.c b/drivers/gpu/arm/utgard/platform/hikey/mali_hikey.c new file mode 100644 index 000000000000..cc556b2656fe --- /dev/null +++ b/drivers/gpu/arm/utgard/platform/hikey/mali_hikey.c @@ -0,0 +1,683 @@ +/* + * Copyright (C) 2014 Hisilicon Co. Ltd. + * Copyright (C) 2015 ARM Limited + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +/** + * @file mali_hikey.c + * HiKey platform specific Mali driver functions. + */ + +/* Set to 1 to enable ION (not tested yet). */ +#define HISI6220_USE_ION 0 + +#define pr_fmt(fmt) "Mali: HiKey: " fmt + +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/regulator/driver.h> +#include <linux/pm.h> +#include <linux/mm.h> +#include <linux/of.h> + +#ifdef CONFIG_PM_RUNTIME +#include <linux/pm_runtime.h> +#endif +#include <linux/fs.h> +#include <linux/delay.h> +#include <linux/version.h> +#include <linux/dma-mapping.h> +#if HISI6220_USE_ION +#include <linux/hisi/hisi_ion.h> +#endif +#include <linux/byteorder/generic.h> + +#include <linux/mali/mali_utgard.h> + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_hikey_hi6220_registers_gpu.h" + +#define MALI_GPU_MHZ 1000000 +#define MALI_IRQ_ID 142 +#define MALI_FRAME_BUFFER_ADDR 0x3F100000 +#define MALI_FRAME_BUFFER_SIZE 0x00708000 + +#define MALI_CALC_REG_MASK(bit_start, bit_end) \ + (((0x1 << (bit_end - bit_start + 1)) - 1) << bit_start) + +enum mali_core_type { + MALI_CORE_400_MP1 = 0, + MALI_CORE_400_MP2 = 1, + MALI_CORE_450_MP4 = 2, + MALI_CORE_TYPE_MAX +}; + +enum mali_power_mode { + MALI_POWER_MODE_ON, /**< Power on */ + MALI_POWER_MODE_LIGHT_SLEEP, /**< Idle for a short or PM suspend */ + MALI_POWER_MODE_DEEP_SLEEP, /**< Idle for a long or OS suspend */ +}; + +struct mali_soc_remap_addr_table { + u8 *soc_media_sctrl_base_addr; + u8 *soc_ao_sctrl_base_addr; + u8 *soc_peri_sctrl_base_addr; + u8 *soc_pmctl_base_addr; +}; + +static struct clk *mali_clk_g3d; +static struct clk *mali_pclk_g3d; +static struct regulator *mali_regulator; +static struct device_node *mali_np; +static bool mali_gpu_power_status; + +static struct resource mali_gpu_resources_m450_mp4[] = { + MALI_GPU_RESOURCES_MALI450_MP4( + SOC_G3D_S_BASE_ADDR, MALI_IRQ_ID, MALI_IRQ_ID, MALI_IRQ_ID, + MALI_IRQ_ID, MALI_IRQ_ID, MALI_IRQ_ID, MALI_IRQ_ID, + MALI_IRQ_ID, MALI_IRQ_ID, MALI_IRQ_ID, MALI_IRQ_ID) +}; + +static struct mali_soc_remap_addr_table *mali_soc_addr_table; + +static void mali_reg_writel(u8 *base_addr, unsigned int reg_offset, + unsigned char start_bit, unsigned char end_bit, + unsigned int val) +{ + int read_val; + unsigned long flags; + static DEFINE_SPINLOCK(reg_lock); + void __iomem *addr; + + WARN_ON(!base_addr); + + addr = base_addr + reg_offset; + spin_lock_irqsave(®_lock, flags); + read_val = readl(addr) & ~(MALI_CALC_REG_MASK(start_bit, end_bit)); + read_val |= (MALI_CALC_REG_MASK(start_bit, end_bit) + & (val << start_bit)); + writel(read_val, addr); + spin_unlock_irqrestore(®_lock, flags); +} + +static unsigned int mali_reg_readl(u8 *base_addr, unsigned int reg_offset, + unsigned char start_bit, + unsigned char end_bit) +{ + unsigned int val; + + WARN_ON(!base_addr); + + val = readl((void __iomem *)(base_addr + reg_offset)); + val &= MALI_CALC_REG_MASK(start_bit, end_bit); + + return val >> start_bit; +} + +static int mali_clock_on(void) +{ + u32 core_freq = 0; + u32 pclk_freq = 0; + int stat; + + stat = clk_prepare_enable(mali_pclk_g3d); + if (stat) + return stat; + + stat = of_property_read_u32(mali_np, "pclk_freq", &pclk_freq); + if (stat) + return stat; + + stat = clk_set_rate(mali_pclk_g3d, pclk_freq * MALI_GPU_MHZ); + if (stat) + return stat; + + stat = of_property_read_u32(mali_np, "mali_def_freq", &core_freq); + if (stat) + return stat; + + stat = clk_set_rate(mali_clk_g3d, core_freq * MALI_GPU_MHZ); + if (stat) + return stat; + + stat = clk_prepare_enable(mali_clk_g3d); + if (stat) + return stat; + + mali_reg_writel(mali_soc_addr_table->soc_media_sctrl_base_addr, + SOC_MEDIA_SCTRL_SC_MEDIA_CLKDIS_ADDR(0), 17, 17, 1); + + return 0; +} + +static void mali_clock_off(void) +{ + clk_disable_unprepare(mali_clk_g3d); + clk_disable_unprepare(mali_pclk_g3d); +} + +static int mali_domain_powerup_finish(void) +{ + unsigned int ret; + + mali_reg_writel(mali_soc_addr_table->soc_ao_sctrl_base_addr, + SOC_AO_SCTRL_SC_PW_RSTDIS0_ADDR(0), 1, 1, 1); + ret = mali_reg_readl(mali_soc_addr_table->soc_ao_sctrl_base_addr, + SOC_AO_SCTRL_SC_PW_RST_STAT0_ADDR(0), 1, 1); + if (ret != 0) { + pr_err("SET SC_PW_RSTDIS0 failed!\n"); + return -EFAULT; + } + + mali_reg_writel(mali_soc_addr_table->soc_ao_sctrl_base_addr, + SOC_AO_SCTRL_SC_PW_ISODIS0_ADDR(0), 1, 1, 1); + ret = mali_reg_readl(mali_soc_addr_table->soc_ao_sctrl_base_addr, + SOC_AO_SCTRL_SC_PW_ISO_STAT0_ADDR(0), 1, 1); + if (ret != 0) { + pr_err("SET SC_PW_ISODIS0 failed!\n"); + return -EFAULT; + } + + mali_reg_writel(mali_soc_addr_table->soc_ao_sctrl_base_addr, + SOC_AO_SCTRL_SC_PW_CLKEN0_ADDR(0), 1, 1, 1); + ret = mali_reg_readl(mali_soc_addr_table->soc_ao_sctrl_base_addr, + SOC_AO_SCTRL_SC_PW_CLK_STAT0_ADDR(0), 1, 1); + if (ret != 1) { + pr_err("SET SC_PW_CLKEN0 failed!\n"); + return -EFAULT; + } + + mali_reg_writel(mali_soc_addr_table->soc_media_sctrl_base_addr, + SOC_MEDIA_SCTRL_SC_MEDIA_RSTDIS_ADDR(0), 0, 0, 1); + ret = mali_reg_readl(mali_soc_addr_table->soc_media_sctrl_base_addr, + SOC_MEDIA_SCTRL_SC_MEDIA_RST_STAT_ADDR(0), 0, 0); + if (ret != 0) { + pr_err("SET SC_MEDIA_RSTDIS failed!\n"); + return -EFAULT; + } + + return 0; +} + +static int mali_regulator_enable(void) +{ + int i, stat; + + stat = regulator_enable(mali_regulator); + if (stat) + return stat; + + for (i = 0; i < 50; i++) { + stat = regulator_is_enabled(mali_regulator); + if (stat > 0) + break; + udelay(1); + } + + if (50 == i) { + pr_err("regulator enable timeout\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int mali_platform_powerup(void) +{ + int stat; + + if (mali_gpu_power_status) + return 0; + + stat = mali_regulator_enable(); + if (stat) + return stat; + + stat = mali_clock_on(); + if (stat) + return stat; + + stat = mali_domain_powerup_finish(); + if (stat) + return stat; + + mali_gpu_power_status = true; + + return 0; +} + +static int mali_regulator_disable(void) +{ + mali_reg_writel(mali_soc_addr_table->soc_media_sctrl_base_addr, + SOC_MEDIA_SCTRL_SC_MEDIA_RSTEN_ADDR(0), 0, 0, 1); + mali_reg_writel(mali_soc_addr_table->soc_ao_sctrl_base_addr, + SOC_AO_SCTRL_SC_PW_CLKDIS0_ADDR(0), 1, 1, 1); + mali_reg_writel(mali_soc_addr_table->soc_ao_sctrl_base_addr, + SOC_AO_SCTRL_SC_PW_ISOEN0_ADDR(0), 1, 1, 1); + mali_reg_writel(mali_soc_addr_table->soc_ao_sctrl_base_addr, + SOC_AO_SCTRL_SC_PW_RSTEN0_ADDR(0), 1, 1, 1); + + return regulator_disable(mali_regulator); +} + +static int mali_platform_powerdown(void) +{ + int stat; + + if (!mali_gpu_power_status) + return 0; + + stat = mali_regulator_disable(); + if (stat) + return stat; + + mali_clock_off(); + mali_gpu_power_status = false; + + return 0; +} + +static int mali_platform_power_mode_change(enum mali_power_mode power_mode) +{ + int stat; + + switch (power_mode) { + case MALI_POWER_MODE_ON: + stat = mali_platform_powerup(); + break; + case MALI_POWER_MODE_LIGHT_SLEEP: + case MALI_POWER_MODE_DEEP_SLEEP: + stat = mali_platform_powerdown(); + break; + default: + pr_err("Invalid power mode\n"); + stat = -EINVAL; + break; + } + + return stat; +} + +static int mali_os_suspend(struct device *device) +{ + int stat; + + if (device->driver && + device->driver->pm && + device->driver->pm->suspend) { + stat = device->driver->pm->suspend(device); + } else { + stat = 0; + } + + if (stat) + return stat; + + return mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP); +} + +static int mali_os_resume(struct device *device) +{ + int stat; + + stat = mali_platform_power_mode_change(MALI_POWER_MODE_ON); + if (stat) + return stat; + + if (device->driver && + device->driver->pm && + device->driver->pm->resume) { + stat = device->driver->pm->resume(device); + } + + return stat; +} + +static int mali_os_freeze(struct device *device) +{ + int stat; + + if (device->driver && + device->driver->pm && + device->driver->pm->freeze) { + stat = device->driver->pm->freeze(device); + } else { + stat = 0; + } + + return stat; +} + +static int mali_os_thaw(struct device *device) +{ + int stat; + + if (device->driver && + device->driver->pm && + device->driver->pm->thaw) { + stat = device->driver->pm->thaw(device); + } else { + stat = 0; + } + + return stat; +} + +#ifdef CONFIG_PM_RUNTIME +static int mali_runtime_suspend(struct device *device) +{ + int stat; + + if (device->driver && + device->driver->pm && + device->driver->pm->runtime_suspend) { + stat = device->driver->pm->runtime_suspend(device); + } else { + stat = 0; + } + + if (stat) + return stat; + + return mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP); +} + +static int mali_runtime_resume(struct device *device) +{ + int stat; + + stat = mali_platform_power_mode_change(MALI_POWER_MODE_ON); + if (stat) + return stat; + + if (device->driver && + device->driver->pm && + device->driver->pm->runtime_resume) { + stat = device->driver->pm->runtime_resume(device); + } + + return stat; +} + +static int mali_runtime_idle(struct device *device) +{ + int stat; + + if (device->driver && + device->driver->pm && + device->driver->pm->runtime_idle) { + stat = device->driver->pm->runtime_idle(device); + } else { + stat = 0; + } + + if (stat) + return stat; + + return pm_runtime_suspend(device); +} +#endif + +static int init_mali_clock_regulator(struct platform_device *pdev) +{ + int stat, ret; + + BUG_ON(mali_regulator || mali_clk_g3d || mali_pclk_g3d); + + /* regulator init */ + + mali_regulator = regulator_get(&pdev->dev, "G3D_PD_VDD"); + if (IS_ERR(mali_regulator)) { + pr_err("failed to get G3D_PD_VDD\n"); + return -ENODEV; + } + + stat = mali_regulator_enable(); + if (stat) + return stat; + + mali_gpu_power_status = true; + + /* clk init */ + + mali_clk_g3d = clk_get(&pdev->dev, "clk_g3d"); + if (IS_ERR(mali_clk_g3d)) { + pr_err("failed to get source CLK_G3D\n"); + return -ENODEV; + } + + mali_pclk_g3d = clk_get(&pdev->dev, "pclk_g3d"); + if (IS_ERR(mali_pclk_g3d)) { + pr_err("failed to get source PCLK_G3D\n"); + return -ENODEV; + } + + ret = mali_reg_readl(mali_soc_addr_table->soc_peri_sctrl_base_addr, + SOC_PERI_SCTRL_SC_PERIPH_CLKSTAT12_ADDR(0), + 10, 10); + if (ret != 1) { + mali_reg_writel(mali_soc_addr_table->soc_peri_sctrl_base_addr, + SOC_PERI_SCTRL_SC_PERIPH_CLKEN12_ADDR(0), + 10, 10, 1); + ret = mali_reg_readl( + mali_soc_addr_table->soc_peri_sctrl_base_addr, + SOC_PERI_SCTRL_SC_PERIPH_CLKSTAT12_ADDR(0), 10, 10); + if (ret != 1) { + pr_err("SET SC_PERIPH_CLKEN12 failed!\n"); + return -EFAULT; + } + } + + stat = mali_clock_on(); + if (stat) + return stat; + + mali_reg_writel(mali_soc_addr_table->soc_media_sctrl_base_addr, + SOC_MEDIA_SCTRL_SC_MEDIA_CLKCFG2_ADDR(0), 15, 15, 1); + ret = mali_reg_readl(mali_soc_addr_table->soc_media_sctrl_base_addr, + SOC_MEDIA_SCTRL_SC_MEDIA_CLKCFG2_ADDR(0), 15, 15); + if (ret != 1) { + pr_err("SET SC_MEDIA_CLKCFG2 failed!\n"); + return -EFAULT; + } + + return mali_domain_powerup_finish(); +} + +static int deinit_mali_clock_regulator(void) +{ + int stat; + + BUG_ON(!mali_regulator || !mali_clk_g3d || !mali_pclk_g3d); + + stat = mali_platform_powerdown(); + if (stat) + return stat; + + clk_put(mali_clk_g3d); + mali_clk_g3d = NULL; + clk_put(mali_pclk_g3d); + mali_pclk_g3d = NULL; + regulator_put(mali_regulator); + mali_regulator = NULL; + + return 0; +} + +static struct mali_gpu_device_data mali_gpu_data = { + .shared_mem_size = 1024 * 1024 * 1024, /* 1024MB */ + .fb_start = MALI_FRAME_BUFFER_ADDR, + .fb_size = MALI_FRAME_BUFFER_SIZE, + .max_job_runtime = 2000, /* 2 seconds time out */ + .control_interval = 50, /* 50ms */ +#ifdef CONFIG_MALI_DVFS + .utilization_callback = mali_gpu_utilization_proc, +#endif +}; + +static const struct dev_pm_ops mali_gpu_device_type_pm_ops = { + .suspend = mali_os_suspend, + .resume = mali_os_resume, + .freeze = mali_os_freeze, + .thaw = mali_os_thaw, +#ifdef CONFIG_PM_RUNTIME + .runtime_suspend = mali_runtime_suspend, + .runtime_resume = mali_runtime_resume, + .runtime_idle = mali_runtime_idle, +#endif +}; + +static struct device_type mali_gpu_device_device_type = { + .pm = &mali_gpu_device_type_pm_ops, +}; + +static enum mali_core_type mali_get_gpu_type(void) +{ + u32 gpu_type = MALI_CORE_TYPE_MAX; + int err = of_property_read_u32(mali_np, "mali_type", &gpu_type); + + if (err) { + pr_err("failed to read mali_type from device tree\n"); + return -EFAULT; + } + + return gpu_type; +} + +#if HISI6220_USE_ION +static int mali_ion_mem_init(void) +{ + struct ion_heap_info_data mem_data; + + if (hisi_ion_get_heap_info(ION_FB_HEAP_ID, &mem_data)) { + pr_err("Failed to get ION_FB_HEAP_ID\n"); + return -EFAULT; + } + + if (mem_data.heap_size == 0) { + pr_err("fb size is 0\n"); + return -EINVAL; + } + + mali_gpu_data.fb_size = mem_data.heap_size; + mali_gpu_data.fb_start = (unsigned long)(mem_data.heap_phy); + pr_debug("fb_size=0x%x, fb_start=0x%x\n", + mali_gpu_data.fb_size, mali_gpu_data.fb_start); + + return 0; +} +#endif + +static int mali_remap_soc_addr(void) +{ + BUG_ON(mali_soc_addr_table); + + mali_soc_addr_table = kmalloc(sizeof(struct mali_soc_remap_addr_table), + GFP_KERNEL); + if (!mali_soc_addr_table) + return -ENOMEM; + + mali_soc_addr_table->soc_media_sctrl_base_addr = + ioremap(SOC_MEDIA_SCTRL_BASE_ADDR, REG_MEDIA_SC_IOSIZE); + mali_soc_addr_table->soc_ao_sctrl_base_addr = + ioremap(SOC_AO_SCTRL_BASE_ADDR, REG_SC_ON_IOSIZE); + mali_soc_addr_table->soc_peri_sctrl_base_addr = + ioremap(SOC_PERI_SCTRL_BASE_ADDR, REG_SC_OFF_IOSIZE); + mali_soc_addr_table->soc_pmctl_base_addr = + ioremap(SOC_PMCTRL_BASE_ADDR, REG_PMCTRL_IOSIZE); + + if (!mali_soc_addr_table->soc_media_sctrl_base_addr + || !mali_soc_addr_table->soc_ao_sctrl_base_addr + || !mali_soc_addr_table->soc_peri_sctrl_base_addr + || !mali_soc_addr_table->soc_pmctl_base_addr) { + pr_err("Failed to remap SoC addresses\n"); + return -ENOMEM; + } + + return 0; +} + +static void mali_unmap_soc_addr(void) +{ + iounmap((void __iomem *)mali_soc_addr_table->soc_media_sctrl_base_addr); + iounmap((void __iomem *)mali_soc_addr_table->soc_ao_sctrl_base_addr); + iounmap((void __iomem *)mali_soc_addr_table->soc_peri_sctrl_base_addr); + iounmap((void __iomem *)mali_soc_addr_table->soc_pmctl_base_addr); + kfree(mali_soc_addr_table); + mali_soc_addr_table = NULL; +} + +int mali_platform_device_init(struct platform_device *pdev) +{ + int stat; + int irq, i; + +#if HISI6220_USE_ION + stat = mali_ion_mem_init(); + if (stat) + return stat; +#endif + + stat = mali_remap_soc_addr(); + if (stat) + return stat; + + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + pdev->dev.type = &mali_gpu_device_device_type; + pdev->dev.platform_data = &mali_gpu_data; + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + mali_np = pdev->dev.of_node; + + if (mali_get_gpu_type() != MALI_CORE_450_MP4) { + pr_err("Unexpected GPU type\n"); + return -EINVAL; + } + + /* + * We need to use DT to get the irq domain, so rewrite the static + * table with the irq given from platform_get_irq(). + */ + irq = platform_get_irq(pdev, 0); + for (i = 0; i < ARRAY_SIZE(mali_gpu_resources_m450_mp4); i++) { + if (IORESOURCE_IRQ & mali_gpu_resources_m450_mp4[i].flags) { + mali_gpu_resources_m450_mp4[i].start = irq; + mali_gpu_resources_m450_mp4[i].end = irq; + } + } + pdev->num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp4); + pdev->resource = mali_gpu_resources_m450_mp4; + + stat = init_mali_clock_regulator(pdev); + if (stat) + return stat; + +#ifdef CONFIG_PM_RUNTIME + pm_runtime_set_autosuspend_delay(&(pdev->dev), 1); + pm_runtime_use_autosuspend(&(pdev->dev)); + pm_runtime_enable(&pdev->dev); +#endif + + return 0; +} + +int mali_platform_device_deinit(void) +{ + int stat; + + stat = deinit_mali_clock_regulator(); + if (stat) + return stat; + + mali_unmap_soc_addr(); + + return 0; +} diff --git a/drivers/gpu/arm/utgard/platform/hikey/mali_hikey_hi6220_registers_gpu.h b/drivers/gpu/arm/utgard/platform/hikey/mali_hikey_hi6220_registers_gpu.h new file mode 100644 index 000000000000..0bdf4a0482fd --- /dev/null +++ b/drivers/gpu/arm/utgard/platform/hikey/mali_hikey_hi6220_registers_gpu.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2014 Hisilicon Co. Ltd. + * Copyright (C) 2015 ARM Ltd. + * + * Author: Xuzixin <Xuzixin@hisilicon.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef MALI_HIKEY_HI6220_REGISTERS_GPU_H +#define MALI_HIKEY_HI6220_REGISTERS_GPU_H 1 + +#include <linux/mm.h> + +#define SOC_G3D_S_BASE_ADDR 0xF4080000 /* G3D ctrl base addr */ +#define SOC_MEDIA_SCTRL_BASE_ADDR 0xF4410000 /* media ctrl base addr */ +#define REG_MEDIA_SC_IOSIZE PAGE_ALIGN(SZ_4K) +#define SOC_PMCTRL_BASE_ADDR 0xF7032000 /* pm ctrl base addr */ +#define REG_PMCTRL_IOSIZE PAGE_ALIGN(SZ_4K) +#define SOC_AO_SCTRL_BASE_ADDR 0xF7800000 /* ao ctrl base addr */ +#define SOC_PERI_SCTRL_BASE_ADDR 0xF7030000 /* peri ctrl base addr */ +#define REG_SC_ON_IOSIZE PAGE_ALIGN(SZ_8K) +#define REG_SC_OFF_IOSIZE PAGE_ALIGN(SZ_4K) + +/* ---------------------------------------------------------------------------- + * MEDIA SCTRL + */ + +#define SOC_MEDIA_SCTRL_SC_MEDIA_SUBSYS_CTRL5_ADDR(base) ((base) + (0x51C)) +#define SOC_MEDIA_SCTRL_SC_MEDIA_CLKCFG0_ADDR(base) ((base) + (0xCBC)) +#define SOC_MEDIA_SCTRL_SC_MEDIA_CLKCFG2_ADDR(base) ((base) + (0xCC4)) +#define SOC_MEDIA_SCTRL_SC_MEDIA_CLKEN_ADDR(base) ((base) + (0x520)) +#define SOC_MEDIA_SCTRL_SC_MEDIA_CLKDIS_ADDR(base) ((base) + (0x524)) +#define SOC_MEDIA_SCTRL_SC_MEDIA_RSTEN_ADDR(base) ((base) + (0x52C)) +#define SOC_MEDIA_SCTRL_SC_MEDIA_RSTDIS_ADDR(base) ((base) + (0x530)) +#define SOC_MEDIA_SCTRL_SC_MEDIA_RST_STAT_ADDR(base) ((base) + (0x534)) + +/* ---------------------------------------------------------------------------- + * AO SCTRL,only bit 1 is necessary for GPU. + */ + +#define SOC_AO_SCTRL_SC_PW_CLKEN0_ADDR(base) ((base) + (0x800)) +#define SOC_AO_SCTRL_SC_PW_CLKDIS0_ADDR(base) ((base) + (0x804)) +#define SOC_AO_SCTRL_SC_PW_CLK_STAT0_ADDR(base) ((base) + (0x808)) +#define SOC_AO_SCTRL_SC_PW_RSTEN0_ADDR(base) ((base) + (0x810)) +#define SOC_AO_SCTRL_SC_PW_RSTDIS0_ADDR(base) ((base) + (0x814)) +#define SOC_AO_SCTRL_SC_PW_RST_STAT0_ADDR(base) ((base) + (0x818)) +#define SOC_AO_SCTRL_SC_PW_ISOEN0_ADDR(base) ((base) + (0x820)) +#define SOC_AO_SCTRL_SC_PW_ISODIS0_ADDR(base) ((base) + (0x824)) +#define SOC_AO_SCTRL_SC_PW_ISO_STAT0_ADDR(base) ((base) + (0x828)) +#define SOC_AO_SCTRL_SC_PW_MTCMOS_EN0_ADDR(base) ((base) + (0x830)) +#define SOC_AO_SCTRL_SC_PW_MTCMOS_DIS0_ADDR(base) ((base) + (0x834)) +#define SOC_AO_SCTRL_SC_PW_MTCMOS_STAT0_ADDR(base) ((base) + (0x838)) + +/* ---------------------------------------------------------------------------- + * PERI SCTRL,only bit 10 is necessary for GPU. + */ + +#define SOC_PERI_SCTRL_SC_PERIPH_CLKEN12_ADDR(base) ((base) + (0x270)) +#define SOC_PERI_SCTRL_SC_PERIPH_CLKSTAT12_ADDR(base) ((base) + (0x278)) + +#endif /* MALI_HIKEY_HI6220_REGISTERS_GPU_H */ |