From f1785f9c1e8ab9a8ebf28250e6bcdf6a62a3e2f1 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 11 Jun 2014 10:08:09 +0900 Subject: ARM/MALI400: R4P0_REL0: port with exynos common platform This patch ports mali400 r4p0 rel0 with exynos common platform. Change-Id: I741c2fbd76cbb7177472ea61b40d7fab22a7c081 Signed-off-by: YoungJun Cho --- drivers/gpu/arm/mali400/r4p0_rel0/Kbuild | 18 +- .../gpu/arm/mali400/r4p0_rel0/MALI_CONFIGURATION | 5 +- .../mali400/r4p0_rel0/linux/mali_kernel_linux.c | 24 +- .../mali400/r4p0_rel0/linux/mali_memory_dma_buf.c | 6 + .../mali400/r4p0_rel0/linux/mali_memory_os_alloc.c | 2 + .../arm/mali400/r4p0_rel0/platform/exynos/exynos.c | 514 ++++++++ .../arm/mali400/r4p0_rel0/platform/exynos/exynos.h | 82 ++ .../r4p0_rel0/platform/exynos3470/exynos4.c | 86 -- .../r4p0_rel0/platform/exynos3470/exynos4_pmm.c | 1198 ------------------ .../r4p0_rel0/platform/exynos3470/exynos4_pmm.h | 95 -- .../r4p0_rel0/platform/exynos3472/exynos4.c | 86 -- .../r4p0_rel0/platform/exynos3472/exynos4_pmm.c | 973 --------------- .../r4p0_rel0/platform/exynos3472/exynos4_pmm.h | 93 -- .../r4p0_rel0/platform/exynos4415/exynos4.c | 86 -- .../r4p0_rel0/platform/exynos4415/exynos4_pmm.c | 937 -------------- .../r4p0_rel0/platform/exynos4415/exynos4_pmm.h | 93 -- .../r4p0_rel0/platform/pegasus-m400/exynos4.c | 405 ------ .../r4p0_rel0/platform/pegasus-m400/exynos4_pmm.c | 1298 -------------------- .../r4p0_rel0/platform/pegasus-m400/exynos4_pmm.h | 121 -- 19 files changed, 626 insertions(+), 5496 deletions(-) create mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos/exynos.c create mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos/exynos.h delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4.c delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4_pmm.c delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4_pmm.h delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4.c delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.h delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4.c delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4_pmm.c delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4_pmm.h delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4.c delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4_pmm.c delete mode 100644 drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4_pmm.h diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/Kbuild b/drivers/gpu/arm/mali400/r4p0_rel0/Kbuild index 5d721bd8064..fe75b41eb81 100644 --- a/drivers/gpu/arm/mali400/r4p0_rel0/Kbuild +++ b/drivers/gpu/arm/mali400/r4p0_rel0/Kbuild @@ -24,25 +24,11 @@ MALI_ENABLE_CPU_CYCLES ?= 0 # MALI_SEC # Include the mapping between TARGET_PLATFORM and KDIR + MALI_PLATFORM -ifeq ($(CONFIG_CPU_EXYNOS4212),y) - TARGET_PLATFORM=pegasus-m400 -endif -ifeq ($(CONFIG_CPU_EXYNOS4412),y) - TARGET_PLATFORM=pegasus-m400 -endif -ifeq ($(CONFIG_SOC_EXYNOS4415),y) - TARGET_PLATFORM=exynos4415 -endif -ifeq ($(CONFIG_SOC_EXYNOS3470),y) - TARGET_PLATFORM=exynos3470 -endif -ifeq ($(CONFIG_SOC_EXYNOS3472),y) - TARGET_PLATFORM=exynos3472 -endif +TARGET_PLATFORM=exynos include $(src)/MALI_CONFIGURATION MALI_PLATFORM = $(MALI_PLATFORM-$(TARGET_PLATFORM)) -EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1 +#EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1 MALI_PLATFORM_FILES = $(subst $(src)/,,$(wildcard $(src)/platform/$(MALI_PLATFORM)/*.c)) # End of MALI_SEC diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/MALI_CONFIGURATION b/drivers/gpu/arm/mali400/r4p0_rel0/MALI_CONFIGURATION index 88fddf8442c..bf529efe6c2 100644 --- a/drivers/gpu/arm/mali400/r4p0_rel0/MALI_CONFIGURATION +++ b/drivers/gpu/arm/mali400/r4p0_rel0/MALI_CONFIGURATION @@ -17,11 +17,8 @@ MALI_PLATFORM-orion=exynos4 MALI_PLATFORM-pegasus=exynos4 # MALI_SEC MALI_PLATFORM-pegasus-m400=pegasus-m400 -MALI_PLATFORM-exynos3250=exynos3250 -MALI_PLATFORM-exynos3470=exynos3470 -MALI_PLATFORM-exynos3472=exynos3472 -MALI_PLATFORM-exynos4415=exynos4415 MALI_PLATFORM-tcc8900=tcc8900 MALI_PLATFORM-pb11mp=arm MALI_PLATFORM-vea9=arm MALI_PLATFORM-snowball=ux500 +MALI_PLATFORM-exynos=exynos diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_kernel_linux.c index 3c491a901d4..b959179d775 100644 --- a/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_kernel_linux.c +++ b/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_kernel_linux.c @@ -39,7 +39,7 @@ #include "mali_profiling_internal.h" #endif /* MALI_SEC */ -#include +#include /* Streamline support for the Mali driver */ #if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_MALI400_PROFILING) @@ -191,6 +191,9 @@ static struct platform_driver mali_platform_driver = { .bus = &platform_bus_type, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) .pm = &mali_dev_pm_ops, +#endif +#if !defined(MALI_FAKE_PLATFORM_DEVICE) + .of_match_table = of_match_ptr(mali_of_matches), #endif }, }; @@ -409,6 +412,14 @@ static int mali_probe(struct platform_device *pdev) mali_platform_device = pdev; +#if !defined(MALI_FAKE_PLATFORM_DEVICE) + if (mali_platform_init() != _MALI_OSK_ERR_OK) + { + MALI_PRINT_ERROR(("mali_probe(): mali_platform_init() failed.")); + return -ENODEV; + } +#endif + if (_MALI_OSK_ERR_OK == _mali_osk_wq_init()) { /* Initialize the Mali GPU HW specified by pdev */ if (_MALI_OSK_ERR_OK == mali_initialize_subsystems()) { @@ -445,6 +456,9 @@ static int mali_remove(struct platform_device *pdev) mali_miscdevice_unregister(); mali_terminate_subsystems(); _mali_osk_wq_term(); +#if !defined(MALI_FAKE_PLATFORM_DEVICE) + mali_platform_deinit(); +#endif mali_platform_device = NULL; return 0; } @@ -475,14 +489,14 @@ static int mali_driver_suspend_scheduler(struct device *dev) { mali_pm_os_suspend(); /* MALI_SEC */ - mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP); + mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP); return 0; } static int mali_driver_resume_scheduler(struct device *dev) { /* MALI_SEC */ - mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON); + mali_platform_power_mode_change(MALI_POWER_MODE_ON); mali_pm_os_resume(); return 0; } @@ -492,14 +506,14 @@ static int mali_driver_runtime_suspend(struct device *dev) { mali_pm_runtime_suspend(); /* MALI_SEC */ - mali_platform_power_mode_change(dev, MALI_POWER_MODE_LIGHT_SLEEP); + mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP); return 0; } static int mali_driver_runtime_resume(struct device *dev) { /* MALI_SEC */ - mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON); + mali_platform_power_mode_change(MALI_POWER_MODE_ON); mali_pm_runtime_resume(); return 0; } diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_memory_dma_buf.c b/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_memory_dma_buf.c index f4bcce00546..694887b3c21 100644 --- a/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_memory_dma_buf.c +++ b/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_memory_dma_buf.c @@ -17,7 +17,9 @@ #include #include #include +#if defined (CONFIG_ION_EXYNOS) #include +#endif #include "mali_ukk.h" #include "mali_osk.h" @@ -105,8 +107,10 @@ static int mali_dma_buf_map(struct mali_dma_buf_attachment *mem, struct mali_ses return -EFAULT; } +#if defined (CONFIG_ION_EXYNOS) exynos_ion_sync_dmabuf_for_device(&mali_platform_device->dev, mem->buf, mem->buf->size, DMA_BIDIRECTIONAL); +#endif for_each_sg(mem->sgt->sgl, sg, mem->sgt->nents, i) { u32 size = sg_dma_len(sg); @@ -155,8 +159,10 @@ static void mali_dma_buf_unmap(struct mali_dma_buf_attachment *mem) if (0 == mem->map_ref) { dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL); +#if defined (CONFIG_ION_EXYNOS) exynos_ion_sync_dmabuf_for_cpu(&mali_platform_device->dev, mem->buf, mem->buf->size, DMA_BIDIRECTIONAL); +#endif mem->is_mapped = MALI_FALSE; } diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_memory_os_alloc.c b/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_memory_os_alloc.c index b6599fca7d0..40bb858b92d 100644 --- a/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_memory_os_alloc.c +++ b/drivers/gpu/arm/mali400/r4p0_rel0/linux/mali_memory_os_alloc.c @@ -56,7 +56,9 @@ static struct mali_mem_os_allocator { .allocated_pages = ATOMIC_INIT(0), .allocation_limit = 0, +#if 0 .shrinker.shrink = mali_mem_os_shrink, +#endif .shrinker.seeks = DEFAULT_SEEKS, #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) .timed_shrinker = __DELAYED_WORK_INITIALIZER(mali_mem_os_allocator.timed_shrinker, mali_mem_os_trim_pool, TIMER_DEFERRABLE), diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos/exynos.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos/exynos.c new file mode 100644 index 00000000000..96b8d5f600b --- /dev/null +++ b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos/exynos.c @@ -0,0 +1,514 @@ +/* drivers/gpu/mali400/mali/platform/exynos/exynos.c + * + * Copyright 2011 by S.LSI. Samsung Electronics Inc. + * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea + * + * Samsung SoC Mali400 DVFS driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software FoundatIon. + */ + +/** + * @file exynos.c + * Platform specific Mali driver functions for the exynos platforms + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_CPU_FREQ +#include +#endif + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#ifdef CONFIG_MALI400_PROFILING +#include "mali_osk_profiling.h" +#endif +#include "exynos.h" + +struct mali_exynos_dvfs_step { + unsigned int rate; + unsigned int min_uv; + unsigned int max_uv; + unsigned int downthreshold; + unsigned int upthreshold; +}; + +struct mali_exynos_variant { + const struct mali_exynos_dvfs_step *steps; + unsigned int nr_steps; +}; + +struct mali_exynos_drvdata { + struct device *dev; + + const struct mali_exynos_dvfs_step *steps; + unsigned int nr_steps; + + struct clk *pll; + struct clk *mux1; + struct clk *mux2; + struct clk *sclk; + struct clk *smmu; + struct clk *g3d; + + struct regulator *vdd_g3d; + + mali_power_mode power_mode; + unsigned int dvfs_step; + unsigned int load; + + struct work_struct dvfs_work; + struct workqueue_struct *dvfs_workqueue; +}; + +extern struct platform_device *mali_platform_device; +static struct mali_exynos_drvdata *mali; + +static void mali_exynos_update_dvfs(struct mali_gpu_utilization_data *data); + +static const struct mali_gpu_device_data mali_exynos_gpu_data = { + .shared_mem_size = 256 * 1024 * 1024, /* 256MB */ + .fb_start = 0x40000000, + .fb_size = 0xb1000000, + .utilization_interval = 100, /* 100ms */ + .utilization_callback = mali_exynos_update_dvfs, +}; + +#define MALI_DVFS_STEP(freq, min_uv, max_uv, down, up) \ + {freq * 1000000, min_uv, max_uv, (255 * down) / 100, (255 * up) / 100} + +static const struct mali_exynos_dvfs_step mali_exynos_dvfs_step_3250[] = { + MALI_DVFS_STEP(134, 0, 0, 0, 100) +}; + +static const struct mali_exynos_dvfs_step mali_exynos_dvfs_step_3472[] = { + MALI_DVFS_STEP(160, 875000, 875000, 0, 70), + MALI_DVFS_STEP(266, 875000, 875000, 62, 90), + MALI_DVFS_STEP(350, 925000, 925000, 85, 90), + MALI_DVFS_STEP(440, 1000000, 1000000, 85, 100) +}; + +static const struct mali_exynos_dvfs_step mali_exynos_dvfs_step_4210[] = { + MALI_DVFS_STEP(160, 950000, 975000, 0, 85), + MALI_DVFS_STEP(266, 1000000, 1025000, 75, 100) +}; + +static const struct mali_exynos_dvfs_step mali_exynos_dvfs_step_4x12[] = { + MALI_DVFS_STEP(160, 875000, 900000, 0, 70), + MALI_DVFS_STEP(266, 900000, 925000, 62, 90), + MALI_DVFS_STEP(350, 950000, 975000, 85, 90), + MALI_DVFS_STEP(440, 1025000, 1050000, 85, 100) +}; + +static const struct mali_exynos_dvfs_step mali_exynos_dvfs_step_4x12_prime[] = { + MALI_DVFS_STEP(160, 875000, 900000, 0, 70), + MALI_DVFS_STEP(266, 900000, 925000, 62, 90), + MALI_DVFS_STEP(350, 950000, 975000, 85, 90), + MALI_DVFS_STEP(440, 1025000, 1050000, 85, 90), + MALI_DVFS_STEP(533, 1075000, 1100000, 85, 100) +}; + +static const struct mali_exynos_variant mali_exynos_variant_3250 = { + .steps = mali_exynos_dvfs_step_3250, + .nr_steps = ARRAY_SIZE(mali_exynos_dvfs_step_3250), +}; + +static const struct mali_exynos_variant mali_exynos_variant_3472 = { + .steps = mali_exynos_dvfs_step_3472, + .nr_steps = ARRAY_SIZE(mali_exynos_dvfs_step_3472), +}; + +static const struct mali_exynos_variant mali_exynos_variant_4210 = { + .steps = mali_exynos_dvfs_step_4210, + .nr_steps = ARRAY_SIZE(mali_exynos_dvfs_step_4210), +}; + +static const struct mali_exynos_variant mali_exynos_variant_4x12 = { + .steps = mali_exynos_dvfs_step_4x12, + .nr_steps = ARRAY_SIZE(mali_exynos_dvfs_step_4x12), +}; + +static const struct mali_exynos_variant mali_exynos_variant_4x12_prime = { + .steps = mali_exynos_dvfs_step_4x12_prime, + .nr_steps = ARRAY_SIZE(mali_exynos_dvfs_step_4x12_prime), +}; + +/* PegaW1 */ +int mali_gpu_clk, mali_gpu_vol; +unsigned int mali_dvfs_utilization; + +/* export GPU frequency as a read-only parameter so that it can be read in /sys */ +module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock"); +module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage"); + +const struct of_device_id mali_of_matches[] = { + { + .compatible = "samsung,exynos3250-g3d", + .data = &mali_exynos_variant_3250, + }, + { + .compatible = "samsung,exynos3472-g3d", + .data = &mali_exynos_variant_3472, + }, + { + .compatible = "samsung,exynos4210-g3d", + .data = &mali_exynos_variant_4210, + }, + { + .compatible = "samsung,exynos4x12-g3d", + .data = &mali_exynos_variant_4x12, + }, + { + .compatible = "samsung,exynos4x12_prime-g3d", + .data = &mali_exynos_variant_4x12_prime, + }, + { /* Sentinel */ } +}; + +#ifdef CONFIG_MALI400_PROFILING +static inline void _mali_osk_profiling_add_gpufreq_event(int rate, int vol) +{ + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | + MALI_PROFILING_EVENT_CHANNEL_GPU | + MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, + rate, vol, 0, 0, 0); +} +#else +static inline void _mali_osk_profiling_add_gpufreq_event(int rate, int vol) +{ +} +#endif + +static inline int mali_exynos_regulator_set_voltage(struct regulator *vdd_g3d, + const struct mali_exynos_dvfs_step *next) +{ + unsigned int min_uv, max_uv; + +#ifdef CONFIG_CPU_FREQ + min_uv = max_uv = get_match_vol(ID_G3D, next->rate / 1000); +#else + min_uv = next->min_uv; + max_uv = next->max_uv; +#endif + + return regulator_set_voltage(vdd_g3d, min_uv, max_uv); +} + +static void mali_exynos_set_dvfs_step(struct mali_exynos_drvdata *mali, + unsigned int step) +{ + const struct mali_exynos_dvfs_step *next = &mali->steps[step]; + + if (step > mali->dvfs_step) { + if (mali->vdd_g3d) + mali_exynos_regulator_set_voltage(mali->vdd_g3d, next); + clk_set_rate(mali->sclk, next->rate); + } else { + clk_set_rate(mali->sclk, next->rate); + if (mali->vdd_g3d) + mali_exynos_regulator_set_voltage(mali->vdd_g3d, next); + } + + mali_gpu_clk = (int)(clk_get_rate(mali->sclk) / 1000000); + if (mali->vdd_g3d) + mali_gpu_vol = + (int)(regulator_get_voltage(mali->vdd_g3d) / 1000); + else + mali_gpu_vol = 0; + + _mali_osk_profiling_add_gpufreq_event(mali_gpu_clk, mali_gpu_vol); + + mali->dvfs_step = step; +} + +static void mali_exynos_dvfs_work(struct work_struct *work) +{ + struct mali_exynos_drvdata *mali = container_of(work, + struct mali_exynos_drvdata, dvfs_work); + unsigned int step = mali->dvfs_step; + const struct mali_exynos_dvfs_step *cur = &mali->steps[step]; + + if (mali->load > cur->upthreshold) + ++step; + else if (mali->load < cur->downthreshold) + --step; + + BUG_ON(step >= mali->nr_steps); + + if (step != mali->dvfs_step) + mali_exynos_set_dvfs_step(mali, step); +} + +static void mali_exynos_update_dvfs(struct mali_gpu_utilization_data *data) +{ + if (data->utilization_gpu > 255) + data->utilization_gpu = 255; + + mali->load = data->utilization_gpu; + mali_dvfs_utilization = data->utilization_gpu; + + queue_work(mali->dvfs_workqueue, &mali->dvfs_work); +} + +static _mali_osk_errcode_t + mali_exynos_enable_clks(struct mali_exynos_drvdata *mali, bool enable) +{ + if (enable) { + if (clk_prepare_enable(mali->smmu)) + MALI_ERROR(_MALI_OSK_ERR_FAULT); + + if (clk_prepare_enable(mali->g3d)) { + clk_disable_unprepare(mali->smmu); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + if (clk_prepare_enable(mali->sclk)) { + clk_disable_unprepare(mali->g3d); + clk_disable_unprepare(mali->smmu); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + } else { + clk_disable_unprepare(mali->sclk); + clk_disable_unprepare(mali->g3d); + clk_disable_unprepare(mali->smmu); + } + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) +{ + if (mali->power_mode == power_mode) + MALI_SUCCESS; + /* to avoid multiple clk_disable() call */ + else if ((mali->power_mode > MALI_POWER_MODE_ON) && + (power_mode > MALI_POWER_MODE_ON)) { + mali->power_mode = power_mode; + MALI_SUCCESS; + } + + switch (power_mode) { + case MALI_POWER_MODE_ON: + mali_exynos_set_dvfs_step(mali, 0); + + if (mali_exynos_enable_clks(mali, true)) { + MALI_PRINT_ERROR(("fail to enable clocks")); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + break; + case MALI_POWER_MODE_DEEP_SLEEP: + case MALI_POWER_MODE_LIGHT_SLEEP: + if (mali_exynos_enable_clks(mali, false)) { + MALI_PRINT_ERROR(("fail to disable clocks")); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + mali_exynos_set_dvfs_step(mali, 0); + mali_gpu_clk = 0; + break; + } + + mali->power_mode = power_mode; + + MALI_SUCCESS; +} + +static const struct mali_exynos_variant * + mali_exynos_get_variant_data(struct platform_device *pdev) +{ + const struct of_device_id *match = of_match_node(mali_of_matches, + pdev->dev.of_node); + if (!match) + return NULL; + + return (const struct mali_exynos_variant *)match->data; +} + +static int mali_exynos_rearrange_resources(struct platform_device *pdev) +{ + unsigned int idx; + unsigned int irq_idx = 0; + unsigned int mem_idx = 0; + struct resource *old_res, *new_res; + + old_res = pdev->resource; + new_res= kzalloc(sizeof(*new_res) * pdev->num_resources, GFP_KERNEL); + if (WARN_ON(!new_res)) + return -ENOMEM; + + /* Copy first resource, L2 cache memory region. */ + memcpy(new_res, old_res++, sizeof(*new_res)); + + /* + * The gpu resources from device tree are arranged like below, + * MEM, MEM, ..., IRQ, IRQ, ... + * So they should be rearranged like below + * because _mali_osk_resource_find function requires, + * MEM, IRQ, MEM, IRQ, ... + */ + for (idx = 1; idx < pdev->num_resources; ++idx, ++old_res) { + if (resource_type(old_res) == IORESOURCE_MEM) + memcpy(&new_res[1 + 2 * mem_idx++], + old_res, sizeof(*old_res)); + if (resource_type(old_res) == IORESOURCE_IRQ) + memcpy(&new_res[2 + 2 * irq_idx++], + old_res, sizeof(*old_res)); + } + + kfree(pdev->resource); + pdev->resource = new_res; + + return 0; +} + +static int mali_exynos_get_clks(struct mali_exynos_drvdata *mali) +{ + mali->pll = devm_clk_get(mali->dev, "pll"); + if (WARN_ON(IS_ERR(mali->pll))) + return PTR_ERR(mali->pll); + + mali->mux1 = devm_clk_get(mali->dev, "mux1"); + if (WARN_ON(IS_ERR(mali->mux1))) + return PTR_ERR(mali->mux1); + + mali->mux2 = devm_clk_get(mali->dev, "mux2"); + if (WARN_ON(IS_ERR(mali->mux2))) + return PTR_ERR(mali->mux2); + + mali->sclk = devm_clk_get(mali->dev, "sclk"); + if (WARN_ON(IS_ERR(mali->sclk))) + return PTR_ERR(mali->sclk); + + mali->smmu = devm_clk_get(mali->dev, "smmu"); + if (WARN_ON(IS_ERR(mali->smmu))) + return PTR_ERR(mali->smmu); + + mali->g3d = devm_clk_get(mali->dev, "g3d"); + if (WARN_ON(IS_ERR(mali->g3d))) + return PTR_ERR(mali->g3d); + + clk_set_parent(mali->mux1, mali->pll); + clk_set_parent(mali->mux2, mali->mux1); + clk_set_parent(mali->sclk, mali->mux2); + + return 0; +} + +static bool + mali_exynos_check_regulator_is_needed(struct mali_exynos_drvdata *mali) +{ + const struct mali_exynos_dvfs_step *step = &mali->steps[0]; + + if (step->min_uv || step->max_uv) + return true; + + return false; +} + +_mali_osk_errcode_t mali_platform_init(void) +{ + struct platform_device *pdev = mali_platform_device; + const struct mali_exynos_variant *variant; + int ret; + + if (WARN_ON(!pdev)) + MALI_ERROR(_MALI_OSK_ERR_FAULT); + + if (WARN_ON(!pdev->dev.of_node)) + MALI_ERROR(_MALI_OSK_ERR_FAULT); + + variant = mali_exynos_get_variant_data(pdev); + if (WARN_ON(!variant)) + MALI_ERROR(_MALI_OSK_ERR_FAULT); + + pdev->dev.platform_data = (void *)&mali_exynos_gpu_data; + + ret = mali_exynos_rearrange_resources(pdev); + if (ret < 0) + MALI_ERROR(_MALI_OSK_ERR_FAULT); + + mali = kzalloc(sizeof(*mali), GFP_KERNEL); + if (WARN_ON(!mali)) + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + + mali->dev = &pdev->dev; + mali->steps = variant->steps; + mali->nr_steps = variant->nr_steps; + + ret = mali_exynos_get_clks(mali); + if (ret < 0) { + MALI_PRINT_ERROR(("Failed to get Mali clocks")); + goto err_free_mali; + } + + mali->vdd_g3d = devm_regulator_get(mali->dev, "vdd"); + if (IS_ERR(mali->vdd_g3d)) { + if (WARN_ON(mali_exynos_check_regulator_is_needed(mali))) { + MALI_PRINT_ERROR(("failed to get Mali regulator")); + goto err_free_mali; + } + + mali->vdd_g3d = NULL; + } + + mali->dvfs_workqueue = create_singlethread_workqueue("mali_dvfs"); + if (WARN_ON(!mali->dvfs_workqueue)) { + MALI_PRINT_ERROR(("failed to create workqueue")); + goto err_free_mali; + } + + mali->power_mode = MALI_POWER_MODE_DEEP_SLEEP; + + INIT_WORK(&mali->dvfs_work, mali_exynos_dvfs_work); + + if (mali->vdd_g3d) { + ret = regulator_enable(mali->vdd_g3d); + if (WARN_ON(ret)) + goto err_destroy_dvfs_wq; + } + + mali_exynos_set_dvfs_step(mali, 0); + +#if !defined(MALI_FAKE_PLATFORM_DEVICE) + pm_runtime_set_autosuspend_delay(&pdev->dev, 300); + pm_runtime_use_autosuspend(&pdev->dev); + + pm_runtime_enable(&pdev->dev); +#endif + + MALI_SUCCESS; + +err_destroy_dvfs_wq: + destroy_workqueue(mali->dvfs_workqueue); +err_free_mali: + kfree(mali); + MALI_ERROR(_MALI_OSK_ERR_FAULT); +} + +_mali_osk_errcode_t mali_platform_deinit(void) +{ + struct platform_device *pdev = mali_platform_device; + +#if !defined(MALI_FAKE_PLATFORM_DEVICE) + pm_runtime_disable(&pdev->dev); +#endif + + if (mali->vdd_g3d) + regulator_disable(mali->vdd_g3d); + + kfree(mali); + + MALI_SUCCESS; +} diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos/exynos.h b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos/exynos.h new file mode 100644 index 00000000000..fef9efd7164 --- /dev/null +++ b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos/exynos.h @@ -0,0 +1,82 @@ +/* drivers/gpu/mali400/mali/platform/exynos/exynos.h + * + * Copyright 2011 by S.LSI. Samsung Electronics Inc. + * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea + * + * Samsung SoC Mali400 DVFS driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software FoundatIon. + */ + +/** + * @file exynos.h + * Platform specific Mali driver functions for the exynos platforms + */ + +#ifndef __EXYNOS_H__ +#define __EXYNOS_H__ + +#include + +#include "mali_osk.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief description of power change reasons + */ +typedef enum mali_power_mode_tag +{ + MALI_POWER_MODE_ON, + MALI_POWER_MODE_LIGHT_SLEEP, + MALI_POWER_MODE_DEEP_SLEEP, +} mali_power_mode; + +/** @brief Platform specific setup and initialisation of MALI + * + * This is called from the entrypoint of the driver to initialize the platform + * + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_platform_init(void); + +/** @brief Platform specific deinitialisation of MALI + * + * This is called on the exit of the driver to terminate the platform + * + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_platform_deinit(void); + +/** @brief Platform specific powerdown sequence of MALI + * + * Call as part of platform init if there is no PMM support, else the + * PMM will call it. + * There are three power modes defined: + * 1) MALI_POWER_MODE_ON + * 2) MALI_POWER_MODE_LIGHT_SLEEP + * 3) MALI_POWER_MODE_DEEP_SLEEP + * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle + * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions + * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued. + * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power + * off. + * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP + * mode. + * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during + * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from + * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well. + * @param power_mode defines the power modes + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode); + +extern const struct of_device_id mali_of_matches[]; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4.c deleted file mode 100644 index 8daffbf5a2f..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4.c +++ /dev/null @@ -1,86 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/exynos3470/exynos4.c - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4.c - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ - -#ifdef CONFIG_PM_RUNTIME -#include -#endif - -#include -#include "mali_kernel_common.h" -#include "exynos4_pmm.h" - -#define MALI_GP_IRQ EXYNOS4_IRQ_GP_3D -#define MALI_PP0_IRQ EXYNOS4_IRQ_PP0_3D -#define MALI_PP1_IRQ EXYNOS4_IRQ_PP1_3D -#define MALI_PP2_IRQ EXYNOS4_IRQ_PP2_3D -#define MALI_PP3_IRQ EXYNOS4_IRQ_PP3_3D -#define MALI_GP_MMU_IRQ EXYNOS4_IRQ_GPMMU_3D -#define MALI_PP0_MMU_IRQ EXYNOS4_IRQ_PPMMU0_3D -#define MALI_PP1_MMU_IRQ EXYNOS4_IRQ_PPMMU1_3D -#define MALI_PP2_MMU_IRQ EXYNOS4_IRQ_PPMMU2_3D -#define MALI_PP3_MMU_IRQ EXYNOS4_IRQ_PPMMU3_3D - -static struct resource mali_gpu_resources[] = -{ - MALI_GPU_RESOURCES_MALI400_MP4(0x13000000, - MALI_GP_IRQ, MALI_GP_MMU_IRQ, - MALI_PP0_IRQ, MALI_PP0_MMU_IRQ, - MALI_PP1_IRQ, MALI_PP1_MMU_IRQ, - MALI_PP2_IRQ, MALI_PP2_MMU_IRQ, - MALI_PP3_IRQ, MALI_PP3_MMU_IRQ) -}; - -static struct mali_gpu_device_data mali_gpu_data = -{ - .shared_mem_size = 256 * 1024 * 1024, /* 256MB */ - .fb_start = 0x40000000, - .fb_size = 0xb1000000, - .utilization_interval = 100, /* 100ms */ - .utilization_callback = mali_gpu_utilization_handler, -}; - -int mali_platform_device_register(void) -{ - int err; - - MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n")); - - /* Connect resources to the device */ - err = platform_device_add_resources(&exynos4_device_g3d, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0])); - if (0 == err) - { - err = platform_device_add_data(&exynos4_device_g3d, &mali_gpu_data, sizeof(mali_gpu_data)); - if (0 == err) - { - mali_platform_init(&(exynos4_device_g3d.dev)); -#ifdef CONFIG_PM_RUNTIME - pm_runtime_set_autosuspend_delay(&(exynos4_device_g3d.dev), 50); - pm_runtime_use_autosuspend(&(exynos4_device_g3d.dev)); - pm_runtime_enable(&(exynos4_device_g3d.dev)); -#endif - return 0; - } - - } - return err; -} - -void mali_platform_device_unregister(void) -{ - MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n")); - mali_platform_deinit(&(exynos4_device_g3d.dev)); -} diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4_pmm.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4_pmm.c deleted file mode 100644 index dce27f2c3ff..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4_pmm.c +++ /dev/null @@ -1,1198 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/exynos3470/exynos4_pmm.c - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4_pmm.c - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "exynos4_pmm.h" - -#include -#include -#include -#include -#include - -#if defined(CONFIG_MALI400_PROFILING) -#include "mali_osk_profiling.h" -#endif - -/* lock/unlock CPU freq by Mali */ -#include -#include -#include -#include -#ifdef CONFIG_CPU_FREQ -#define EXYNOS4_ASV_ENABLED -#endif - -/* MALI_SEC_QOS */ -#ifdef CONFIG_MALI_DVFS -#define BUSFREQ_QOS_LOCK -#endif - -#ifdef BUSFREQ_QOS_LOCK -#include -static struct pm_qos_request mif_min_qos; -#endif - -/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */ -#ifndef S5P_G3D_CONFIGURATION -#define S5P_G3D_CONFIGURATION EXYNOS4_G3D_CONFIGURATION -#endif -#ifndef S5P_G3D_STATUS -#define S5P_G3D_STATUS (EXYNOS4_G3D_CONFIGURATION + 0x4) -#endif -#ifndef S5P_INT_LOCAL_PWR_EN -#define S5P_INT_LOCAL_PWR_EN EXYNOS_INT_LOCAL_PWR_EN -#endif - -#include -#include -#include - -#define MALI_DVFS_STEPS 5 -#define MALI_DVFS_STEPS_ISP 4 -#define MALI_DVFS_WATING 10 /* msec */ -#define MALI_DVFS_DEFAULT_STEP 1 -#define MALI_DVFS_DEFAULT_STEP_ISP 3 - -#define MALI_DVFS_CLK_DEBUG 0 -#define CPUFREQ_LOCK_DURING_440 1 - -static int bMaliDvfsRun = 0; - -typedef struct mali_dvfs_tableTag{ - unsigned int clock; - unsigned int freq; - unsigned int vol; - unsigned int downthreshold; - unsigned int upthreshold; -#ifdef BUSFREQ_QOS_LOCK - unsigned int mif_min_lock_value; -#endif -}mali_dvfs_table; - -typedef struct mali_dvfs_statusTag{ - unsigned int currentStep; - mali_dvfs_table * pCurrentDvfs; -} mali_dvfs_status_t; - -/*dvfs status*/ -mali_dvfs_status_t maliDvfsStatus; -int mali_dvfs_control; -int mali_isp_current_clock; -static _mali_osk_atomic_t dvfslock_status; - -typedef struct mali_runtime_resumeTag{ - int clk; - int vol; - unsigned int step; -}mali_runtime_resume_table; - -mali_runtime_resume_table mali_runtime_resume = {160, 850000, 0}; - -/* dvfs table updated on 130520 */ -mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS] = { - /* step 0 */{160, 1000000, 850000, 0, 70 -#ifdef BUSFREQ_QOS_LOCK - /* mif_min_lock_value */ - , 0 -#endif - }, - /* step 1 */{266, 1000000, 850000, 62, 90 -#ifdef BUSFREQ_QOS_LOCK - /* mif_min_lock_value */ - , 267000 -#endif - }, - /* step 2 */{340, 1000000, 875000, 85, 90 -#ifdef BUSFREQ_QOS_LOCK - /* mif_min_lock_value */ - , 267000 -#endif - }, - /* step 3 */{440, 1000000, 925000, 85, 90 -#ifdef BUSFREQ_QOS_LOCK - /* mif_min_lock_value */ - , 267000 -#endif - }, - /* step 4 */{533, 1000000, 1000000, 95, 100 -#ifdef BUSFREQ_QOS_LOCK - /* mif_min_lock_value */ - , 267000 -#endif - } }; - -/* dvfs table updated on 140314 */ -mali_dvfs_table mali_dvfs_isp[MALI_DVFS_STEPS_ISP] = { - /* step 0 */{150, 1000000, 850000, 0, 70 -#ifdef BUSFREQ_QOS_LOCK - /* mif_min_lock_value */ - , 0 -#endif - }, - /* step 1 */{225, 1000000, 850000, 62, 90 -#ifdef BUSFREQ_QOS_LOCK - /* mif_min_lock_value */ - , 267000 -#endif - }, - /* step 2 */{300, 1000000, 875000, 85, 90 -#ifdef BUSFREQ_QOS_LOCK - /* mif_min_lock_value */ - , 267000 -#endif - }, - /* step 3 */{450, 1000000, 925000, 95, 100 -#ifdef BUSFREQ_QOS_LOCK - /* mif_min_lock_value */ - , 267000 -#endif - } }; - -/* Exynos3470 */ -int mali_gpu_clk = 160; -int mali_gpu_vol = 850000; -unsigned int mali_vpll_clk = 900; -char *mali_freq_table = "533 440 340 266 160"; -#define EXTXTALCLK_NAME "ext_xtal" -#define VPLLSRCCLK_NAME "vpll_src" -#define FOUTVPLLCLK_NAME "fout_vpll" -#define MOUTEPLLCLK_NAME "mout_epll" -#define SCLVPLLCLK_NAME "sclk_vpll" -#define GPUMOUT1CLK_NAME "mout_g3d1" -#define GPUMOUT0CLK_NAME "mout_g3d0" -#define GPUCLK_NAME "sclk_g3d" -#define CLK_DIV_STAT_G3D 0x1003C62C -#define CLK_DESC "clk-divider-status" -int ENABLE_LOCK_BY_ISP; -int mali_isp_current_level; - -static struct clk *ext_xtal_clock = NULL; -static struct clk *vpll_src_clock = NULL; -static struct clk *fout_vpll_clock = NULL; -static struct clk *mout_epll_clock = NULL; -static struct clk *sclk_vpll_clock = NULL; -static struct clk *mali_parent_clock = NULL; -static struct clk *mali_clock = NULL; - -static unsigned int GPU_MHZ = 1000000; -static unsigned int const GPU_ASV_VOLT = 1000; -static int nPowermode; -static atomic_t clk_active; - -mali_io_address clk_register_map = 0; - -/* export GPU frequency as a read-only parameter so that it can be read in /sys */ -module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); -module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); -module_param(mali_freq_table, charp, S_IRUSR | S_IRGRP | S_IROTH); -#ifdef CONFIG_MALI_DVFS -module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS"); -DEVICE_ATTR(time_in_state, S_IRUGO|S_IWUSR, show_time_in_state, set_time_in_state); -MODULE_PARM_DESC(time_in_state, "Time-in-state of Mali DVFS"); -#endif -MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock"); -MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage"); -MODULE_PARM_DESC(mali_freq_table, "Mali frequency table"); - -#ifdef CONFIG_REGULATOR -struct regulator *g3d_regulator = NULL; -#endif -atomic_t mali_cpufreq_lock; - -/* DVFS */ -#ifdef CONFIG_MALI_DVFS -static unsigned int mali_dvfs_utilization = 255; -static void update_time_in_state(int level); -u64 mali_dvfs_time[MALI_DVFS_STEPS]; -#endif - -static void mali_dvfs_work_handler(struct work_struct *w); -static struct workqueue_struct *mali_dvfs_wq = 0; -_mali_osk_mutex_t *mali_dvfs_lock; -_mali_osk_mutex_t *mali_isp_lock; -static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler); - -int cpufreq_lock_by_mali(unsigned int freq) -{ -#ifdef CONFIG_EXYNOS4_CPUFREQ - unsigned int level; - - if (atomic_read(&mali_cpufreq_lock) == 0) { - if (exynos_cpufreq_get_level(freq * 1000, &level)) { - printk(KERN_ERR "Mali: failed to get cpufreq level for %dMHz", freq); - return -EINVAL; - } - - if (exynos_cpufreq_lock(DVFS_LOCK_ID_G3D, level)) { - printk(KERN_ERR "Mali: failed to cpufreq lock for L%d", level); - return -EINVAL; - } - - atomic_set(&mali_cpufreq_lock, 1); - printk(KERN_DEBUG "Mali: cpufreq locked on <%d>%dMHz\n", level, freq); - } -#endif - return 0; -} - -void cpufreq_unlock_by_mali(void) -{ -#ifdef CONFIG_EXYNOS4_CPUFREQ - if (atomic_read(&mali_cpufreq_lock) == 1) { - exynos_cpufreq_lock_free(DVFS_LOCK_ID_G3D); - atomic_set(&mali_cpufreq_lock, 0); - printk(KERN_DEBUG "Mali: cpufreq locked off\n"); - } -#endif -} - -#ifdef CONFIG_REGULATOR -void mali_regulator_disable(void) -{ - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n")); - return; - } - regulator_disable(g3d_regulator); -} - -void mali_regulator_enable(void) -{ - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n")); - return; - } - regulator_enable(g3d_regulator); -} - -void mali_regulator_set_voltage(int min_uV, int max_uV) -{ - _mali_osk_mutex_wait(mali_dvfs_lock); - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); - _mali_osk_mutex_signal(mali_dvfs_lock); - return; - } - MALI_DEBUG_PRINT(1, ("= regulator_set_voltage: %d, %d \n", min_uV, max_uV)); - regulator_set_voltage(g3d_regulator, min_uV, max_uV); - mali_gpu_vol = regulator_get_voltage(g3d_regulator); - MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol)); - _mali_osk_mutex_signal(mali_dvfs_lock); -} -#endif - -#ifdef CONFIG_MALI_DVFS -static unsigned int get_mali_dvfs_status(void) -{ - return maliDvfsStatus.currentStep; -} -#endif - -mali_bool mali_clk_get(void) -{ - if (ext_xtal_clock == NULL) { - ext_xtal_clock = clk_get(NULL, EXTXTALCLK_NAME); - if (IS_ERR(ext_xtal_clock)) { - MALI_PRINT(("MALI Error : failed to get source ext_xtal_clock\n")); - return MALI_FALSE; - } - } - - if (vpll_src_clock == NULL) { - vpll_src_clock = clk_get(NULL, VPLLSRCCLK_NAME); - if (IS_ERR(vpll_src_clock)) { - MALI_PRINT(("MALI Error : failed to get source vpll_src_clock\n")); - return MALI_FALSE; - } - } - - if (fout_vpll_clock == NULL) { - fout_vpll_clock = clk_get(NULL, FOUTVPLLCLK_NAME); - if (IS_ERR(fout_vpll_clock)) { - MALI_PRINT(("MALI Error : failed to get source fout_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (mout_epll_clock == NULL) { - mout_epll_clock = clk_get(NULL, MOUTEPLLCLK_NAME); - if (IS_ERR(mout_epll_clock)) { - MALI_PRINT(("MALI Error : failed to get source mout_epll_clock\n")); - return MALI_FALSE; - } - } - - if (sclk_vpll_clock == NULL) { - sclk_vpll_clock = clk_get(NULL, SCLVPLLCLK_NAME); - if (IS_ERR(sclk_vpll_clock)) { - MALI_PRINT(("MALI Error : failed to get source sclk_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (mali_parent_clock == NULL) { - mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME); - if (IS_ERR(mali_parent_clock)) { - MALI_PRINT(("MALI Error : failed to get source mali parent clock\n")); - return MALI_FALSE; - } - } - - /* mali clock get always. */ - if (mali_clock == NULL) { - mali_clock = clk_get(NULL, GPUCLK_NAME); - if (IS_ERR(mali_clock)) { - MALI_PRINT(("MALI Error : failed to get source mali clock\n")); - return MALI_FALSE; - } - } - - return MALI_TRUE; -} - -void mali_clk_put(mali_bool binc_mali_clock) -{ - if (mali_parent_clock) - { - clk_put(mali_parent_clock); - mali_parent_clock = NULL; - } - - if (sclk_vpll_clock) - { - clk_put(sclk_vpll_clock); - sclk_vpll_clock = NULL; - } - - if (binc_mali_clock && fout_vpll_clock) - { - clk_put(fout_vpll_clock); - fout_vpll_clock = NULL; - } - - if (mout_epll_clock) - { - clk_put(mout_epll_clock); - mout_epll_clock = NULL; - } - - if (vpll_src_clock) - { - clk_put(vpll_src_clock); - vpll_src_clock = NULL; - } - - if (ext_xtal_clock) - { - clk_put(ext_xtal_clock); - ext_xtal_clock = NULL; - } - - if (binc_mali_clock && mali_clock) - { - clk_put(mali_clock); - mali_clock = NULL; - } -} - -mali_bool set_mali_dvfs_current_step(unsigned int step) -{ - _mali_osk_mutex_wait(mali_dvfs_lock); - if (ENABLE_LOCK_BY_ISP) { - maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS_ISP; - mali_isp_current_clock = mali_dvfs_isp[maliDvfsStatus.currentStep].clock; - } else { - maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS; - } - _mali_osk_mutex_signal(mali_dvfs_lock); - return MALI_TRUE; -} - -mali_bool mali_clk_set_rate_isp(u32 step) -{ -#ifdef EXYNOS4_ASV_ENABLED - int lock_vol; -#endif - unsigned long rate = (unsigned long)mali_dvfs_isp[step].clock * (unsigned long)GPU_MHZ; -#ifdef CONFIG_REGULATOR - if (IS_ERR_OR_NULL(g3d_regulator)) { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); - return MALI_FALSE; - } -#ifdef EXYNOS4_ASV_ENABLED - lock_vol = get_match_volt(ID_G3D, mali_dvfs_isp[step].clock * GPU_ASV_VOLT); - regulator_set_voltage(g3d_regulator, lock_vol, lock_vol); - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_dvfs_isp[step].clock * GPU_ASV_VOLT)); -#else - regulator_set_voltage(g3d_regulator, mali_dvfs_isp[step].vol, mali_dvfs_isp[step].vol); -#endif - mali_gpu_vol = regulator_get_voltage(g3d_regulator); - MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol)); -#endif - if (mali_clk_get() == MALI_FALSE) - return MALI_FALSE; - - if (atomic_read(&clk_active) == 0) { - if (clk_enable(mali_clock) < 0) { - return MALI_FALSE; - } - atomic_set(&clk_active, 1); - } - -#ifdef BUSFREQ_QOS_LOCK - if (pm_qos_request_active(&mif_min_qos)) - pm_qos_update_request(&mif_min_qos, mali_dvfs_isp[step].mif_min_lock_value); -#endif - - clk_set_rate(mali_clock, rate); - rate = clk_get_rate(mali_clock); - mali_gpu_clk = (int)(rate / GPU_MHZ); - mali_isp_current_level = step; - mali_clk_put(MALI_FALSE); - set_mali_dvfs_current_step(step); - return MALI_TRUE; -} - -void mali_clk_set_rate(unsigned int clk, unsigned int mhz) -{ - int err; - unsigned int read_val; - unsigned long rate = (unsigned long)clk * (unsigned long)mhz; - - _mali_osk_mutex_wait(mali_dvfs_lock); - - MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk)); - - if (mali_clk_get() == MALI_FALSE) { - _mali_osk_mutex_signal(mali_dvfs_lock); - return; - } - clk_set_parent(mali_parent_clock, mout_epll_clock); - - do { - cpu_relax(); - read_val = __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0); - } while (((read_val >> 4) & 0x7) != 0x1); - - MALI_DEBUG_PRINT(3, ("Mali platform: set to EPLL EXYNOS4_CLKMUX_STAT_G3D0 : 0x%08x\n", __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0))); - - err = clk_set_parent(sclk_vpll_clock, ext_xtal_clock); - - if (err) - MALI_PRINT_ERROR(("sclk_vpll set parent to ext_xtal failed\n")); - - MALI_DEBUG_PRINT(3, ("Mali platform: set_parent_vpll : %8.x \n", (__raw_readl(EXYNOS4_CLKSRC_TOP0) >> 8) & 0x1)); - - clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ); - clk_set_parent(vpll_src_clock, ext_xtal_clock); - - err = clk_set_parent(sclk_vpll_clock, fout_vpll_clock); - - if (err) - MALI_PRINT_ERROR(("sclk_vpll set parent to fout_vpll failed\n")); - - MALI_DEBUG_PRINT(3, ("Mali platform: set_parent_vpll : %8.x \n", (__raw_readl(EXYNOS4_CLKSRC_TOP0) >> 8) & 0x1)); - - clk_set_parent(mali_parent_clock, sclk_vpll_clock); - - do { - cpu_relax(); - read_val = __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0); - } while (((read_val >> 4) & 0x7) != 0x2); - - MALI_DEBUG_PRINT(3, ("SET to VPLL EXYNOS4_CLKMUX_STAT_G3D0 : 0x%08x\n", __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0))); - - clk_set_parent(mali_clock, mali_parent_clock); - - if (atomic_read(&clk_active) == 0) { - if (clk_enable(mali_clock) < 0) { - _mali_osk_mutex_signal(mali_dvfs_lock); - return; - } - atomic_set(&clk_active, 1); - } - - err = clk_set_rate(mali_clock, rate); - - if (err > 0) - MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err)); - - rate = clk_get_rate(mali_clock); - - MALI_DEBUG_PRINT(1, ("Mali frequency %d\n", rate / mhz)); - GPU_MHZ = mhz; - - mali_gpu_clk = (int)(rate / mhz); - mali_clk_put(MALI_FALSE); - - _mali_osk_mutex_signal(mali_dvfs_lock); -} - -#ifdef CONFIG_MALI_DVFS -static mali_bool set_mali_dvfs_status(u32 step, mali_bool boostup) -{ -#if MALI_DVFS_CLK_DEBUG - unsigned int *pRegMaliClkDiv; - unsigned int *pRegMaliMpll; -#endif - _mali_osk_mutex_wait(mali_isp_lock); - if (ENABLE_LOCK_BY_ISP) { - MALI_DEBUG_PRINT(1, ("DVFS is already locked by ISP\n")); - if (mali_clk_set_rate_isp(step) == MALI_FALSE) { - _mali_osk_mutex_signal(mali_isp_lock); - return MALI_FALSE; - } - _mali_osk_mutex_signal(mali_isp_lock); - return MALI_TRUE; - } else if (mali_isp_current_clock > 0) { - mali_isp_current_clock = 0; - } - -#ifdef BUSFREQ_QOS_LOCK - if (pm_qos_request_active(&mif_min_qos)) - pm_qos_update_request(&mif_min_qos, mali_dvfs[step].mif_min_lock_value); -#endif - - if(boostup) { -#ifdef CONFIG_REGULATOR - /*change the voltage*/ -#ifdef EXYNOS4_ASV_ENABLED - mali_regulator_set_voltage(get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT), get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); -#else - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif -#endif - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); - } else { - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); -#ifdef CONFIG_REGULATOR -#ifdef EXYNOS4_ASV_ENABLED - /*change the voltage*/ - mali_regulator_set_voltage(get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT), get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); -#else - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif -#endif - } - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| - MALI_PROFILING_EVENT_CHANNEL_GPU| - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - mali_clk_put(MALI_FALSE); - -#if MALI_DVFS_CLK_DEBUG - pRegMaliClkDiv = ioremap(0x1003c52c, 32); - pRegMaliMpll = ioremap(0x1003c22c, 32); - MALI_PRINT(("Mali MPLL reg:%d, CLK DIV: %d \n", *pRegMaliMpll, *pRegMaliClkDiv)); -#endif - set_mali_dvfs_current_step(step); - /*for future use*/ - maliDvfsStatus.pCurrentDvfs = &mali_dvfs[step]; - -#if CPUFREQ_LOCK_DURING_440 - /* lock/unlock CPU freq by Mali */ - if (mali_dvfs[step].clock >= 440) - cpufreq_lock_by_mali(400); - else - cpufreq_unlock_by_mali(); -#endif - _mali_osk_mutex_signal(mali_isp_lock); - return MALI_TRUE; -} - -static void mali_platform_wating(u32 msec) -{ - /* - * sample wating - * change this in the future with proper check routine. - */ - unsigned int read_val; - while(1) { - read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00); - if ((read_val & 0x8000)==0x0000) break; - - _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */ - } -} - -static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup ) -{ - MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n", step, boostup)); - - if (!set_mali_dvfs_status(step, boostup)) { - MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup)); - return MALI_FALSE; - } - - /* wait until clock and voltage is stablized */ - mali_platform_wating(MALI_DVFS_WATING); /* msec */ - return MALI_TRUE; -} - -static unsigned int decideNextStatus(unsigned int utilization) -{ - static unsigned int level = 0; - int iStepCount = 0; - - if (ENABLE_LOCK_BY_ISP) { - if (level >= MALI_DVFS_STEPS_ISP) - level--; - - if (utilization > (int)(255 * mali_dvfs_isp[maliDvfsStatus.currentStep].upthreshold / 100) && - level < MALI_DVFS_STEPS_ISP - 1) { - level++; - } else if (utilization < (int)(255 * mali_dvfs_isp[maliDvfsStatus.currentStep].downthreshold / 100) && - level > 0) { - level--; - } - return level; - } else if (mali_dvfs_control == 0) { - if (utilization > (int)(255 * mali_dvfs_isp[maliDvfsStatus.currentStep].upthreshold / 100) && - level < MALI_DVFS_STEPS - 1) { - level++; - } else if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) && - level > 0) { - level--; - } - } else { - for (iStepCount = MALI_DVFS_STEPS - 1; iStepCount >= 0; iStepCount--) { - if (mali_dvfs_control >= mali_dvfs[iStepCount].clock) { - level = iStepCount; - break; - } - } - } - return level; -} - -static mali_bool mali_dvfs_status(unsigned int utilization) -{ - unsigned int nextStatus = 0; - unsigned int curStatus = 0; - mali_bool boostup = MALI_FALSE; - static int stay_count = 5; - - MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n", utilization)); - - /* decide next step */ - curStatus = get_mali_dvfs_status(); - nextStatus = decideNextStatus(utilization); - - MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d\n", curStatus, nextStatus)); - /* if next status is same with current status, don't change anything */ - if (curStatus != nextStatus) { - /*check if boost up or not*/ - if (curStatus < nextStatus) { - boostup = 1; - stay_count = 5; - } else if (curStatus > nextStatus) { - stay_count--; - } - - if (boostup == 1 || stay_count <= 0) { - /*change mali dvfs status*/ - update_time_in_state(curStatus); - if (!change_mali_dvfs_status(nextStatus, boostup)) { - MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); - return MALI_FALSE; - } - boostup = 0; - stay_count = 5; - } - } else { - stay_count = 5; - } - - return MALI_TRUE; -} -#endif - -static void mali_dvfs_work_handler(struct work_struct *w) -{ - bMaliDvfsRun = 1; - MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); - -#ifdef CONFIG_MALI_DVFS - if(!mali_dvfs_status(mali_dvfs_utilization)) - MALI_DEBUG_PRINT(1, ( "error on mali dvfs status in mali_dvfs_work_handler")); -#endif - - bMaliDvfsRun = 0; -} - -mali_bool init_mali_dvfs_status(void) -{ - /* - * default status - * add here with the right function to get initilization value. - */ - if (!mali_dvfs_wq) - mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs"); - - _mali_osk_atomic_init(&dvfslock_status, 0); - - /* add a error handling here */ - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; - - return MALI_TRUE; -} - -void deinit_mali_dvfs_status(void) -{ - if (mali_dvfs_wq) - destroy_workqueue(mali_dvfs_wq); - - _mali_osk_atomic_term(&dvfslock_status); - - mali_dvfs_wq = NULL; -} - -#ifdef CONFIG_MALI_DVFS -mali_bool mali_dvfs_handler(unsigned int utilization) -{ - mali_dvfs_utilization = utilization; - queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work); - - return MALI_TRUE; -} -#endif - -static mali_bool init_mali_clock(void) -{ - mali_bool ret = MALI_TRUE; - nPowermode = MALI_POWER_MODE_DEEP_SLEEP; - - if (mali_clock != 0) - return ret; /* already initialized */ - - mali_dvfs_lock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED, 0); - mali_isp_lock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED, 0); - - if (mali_dvfs_lock == NULL || mali_isp_lock == NULL) - return _MALI_OSK_ERR_FAULT; - - if (!mali_clk_get()) - { - MALI_PRINT(("Error: Failed to get Mali clock\n")); - goto err_clk; - } - - clk_set_parent(vpll_src_clock, ext_xtal_clock); - clk_set_parent(sclk_vpll_clock, fout_vpll_clock); - clk_set_parent(mali_parent_clock, sclk_vpll_clock); - clk_set_parent(mali_clock, mali_parent_clock); - - if (!atomic_read(&clk_active)) { - if (clk_enable(mali_clock) < 0) { - MALI_PRINT(("Error: Failed to enable clock\n")); - goto err_clk; - } - atomic_set(&clk_active, 1); - } - - mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); - - MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock)); - -#ifdef CONFIG_REGULATOR - g3d_regulator = regulator_get(NULL, "vdd_g3d"); - - if (IS_ERR(g3d_regulator)) - { - MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n")); - ret = MALI_FALSE; - goto err_regulator; - } - - mali_gpu_vol = mali_runtime_resume.vol; -#ifdef EXYNOS4_ASV_ENABLED - mali_gpu_vol = get_match_volt(ID_G3D, mali_gpu_clk * GPU_ASV_VOLT); - mali_runtime_resume.vol = get_match_volt(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT); -#endif - - regulator_enable(g3d_regulator); - mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); - -#ifdef EXYNOS4_ASV_ENABLED - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT)); -#endif -#endif - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| - MALI_PROFILING_EVENT_CHANNEL_GPU| - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - mali_clk_put(MALI_FALSE); - - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR -err_regulator: - regulator_put(g3d_regulator); -#endif -err_clk: - mali_clk_put(MALI_TRUE); - - return ret; -} - -static mali_bool deinit_mali_clock(void) -{ - if (mali_clock == 0) - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR - if (g3d_regulator) - { - regulator_put(g3d_regulator); - g3d_regulator = NULL; - } -#endif - mali_clk_put(MALI_TRUE); - - return MALI_TRUE; -} - -static _mali_osk_errcode_t enable_mali_clocks(void) -{ - int err; - - _mali_osk_mutex_wait(mali_isp_lock); - if (atomic_read(&clk_active) == 0) { - err = clk_enable(mali_clock); - MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err)); - atomic_set(&clk_active, 1); - } - - if (ENABLE_LOCK_BY_ISP) { - MALI_DEBUG_PRINT(1, ("DVFS is already locked by ISP\n")); -#ifdef EXYNOS4_ASV_ENABLED - if (samsung_rev() >= EXYNOS3470_REV_2_0) - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_dvfs_isp[mali_isp_current_level].clock * GPU_ASV_VOLT)); -#endif - mali_clk_set_rate_isp(mali_isp_current_level); - _mali_osk_mutex_signal(mali_isp_lock); - MALI_SUCCESS; - } - - /* set clock rate */ -#ifdef CONFIG_MALI_DVFS -#ifdef EXYNOS4_ASV_ENABLED - if (samsung_rev() >= EXYNOS3470_REV_2_0) - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT)); -#endif - - if (mali_dvfs_control != 0 || mali_gpu_clk >= mali_runtime_resume.clk) { - mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); - } else { -#ifdef CONFIG_REGULATOR - mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol); -#ifdef EXYNOS4_ASV_ENABLED - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT)); -#endif -#endif - mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ); - set_mali_dvfs_current_step(mali_runtime_resume.step); - } -#else - mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; -#endif - -#ifdef BUSFREQ_QOS_LOCK - if (pm_qos_request_active(&mif_min_qos)) - pm_qos_update_request(&mif_min_qos, mali_dvfs[maliDvfsStatus.currentStep].mif_min_lock_value); -#endif - - _mali_osk_mutex_signal(mali_isp_lock); - MALI_SUCCESS; -} - -static _mali_osk_errcode_t disable_mali_clocks(void) -{ - _mali_osk_mutex_wait(mali_isp_lock); -#ifdef EXYNOS4_ASV_ENABLED - if (samsung_rev() >= EXYNOS3470_REV_2_0) - exynos_set_abb(ID_G3D, ABB_BYPASS); -#endif - - if (atomic_read(&clk_active)) { - clk_disable(mali_clock); - MALI_DEBUG_PRINT(3, ("disable_mali_clocks mali_clock %p\n", mali_clock)); - atomic_set(&clk_active, 0); -#ifdef BUSFREQ_QOS_LOCK - pm_qos_update_request(&mif_min_qos, 0); -#endif - } - _mali_osk_mutex_signal(mali_isp_lock); - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_init(struct device *dev) -{ - atomic_set(&clk_active, 0); - MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT); - -#ifdef CONFIG_MALI_DVFS - -#ifdef BUSFREQ_QOS_LOCK - pm_qos_add_request(&mif_min_qos, PM_QOS_BUS_THROUGHPUT, 0); -#endif - - /* Create sysfs for time-in-state */ - if (device_create_file(dev, &dev_attr_time_in_state)) { - dev_err(dev, "Couldn't create sysfs file [time_in_state]\n"); - } - - if (!clk_register_map) - clk_register_map = _mali_osk_mem_mapioregion(CLK_DIV_STAT_G3D, 0x20, CLK_DESC); - - if (!init_mali_dvfs_status()) - MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n")); - - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; -#endif - mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON); - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_deinit(struct device *dev) -{ - mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP); - deinit_mali_clock(); - -#ifdef CONFIG_MALI_DVFS - deinit_mali_dvfs_status(); - if (clk_register_map) - { - _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map); - clk_register_map = NULL; - } -#endif - -#ifdef BUSFREQ_QOS_LOCK - pm_qos_remove_request(&mif_min_qos); -#endif - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode) -{ - switch (power_mode) - { - case MALI_POWER_MODE_ON: - MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n", - nPowermode ? "powering on" : "already on")); - if (nPowermode == MALI_POWER_MODE_LIGHT_SLEEP || nPowermode == MALI_POWER_MODE_DEEP_SLEEP) { - MALI_DEBUG_PRINT(4, ("enable clock\n")); - enable_mali_clocks(); - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - nPowermode = power_mode; - } - break; - case MALI_POWER_MODE_DEEP_SLEEP: - case MALI_POWER_MODE_LIGHT_SLEEP: - MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode == MALI_POWER_MODE_LIGHT_SLEEP ? - "MALI_POWER_MODE_LIGHT_SLEEP" : "MALI_POWER_MODE_DEEP_SLEEP", - nPowermode ? "already off" : "powering off")); - if (nPowermode == MALI_POWER_MODE_ON) { - disable_mali_clocks(); - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - 0, 0, 0, 0, 0); -#endif - nPowermode = power_mode; - } - break; - } - MALI_SUCCESS; -} - -void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data) -{ - if (nPowermode == MALI_POWER_MODE_ON) - { -#ifdef CONFIG_MALI_DVFS - if(!mali_dvfs_handler(data->utilization_gpu)) - MALI_DEBUG_PRINT(1, ("error on mali dvfs status in utilization\n")); -#endif - } -} - -#ifdef CONFIG_MALI_DVFS -static void update_time_in_state(int level) -{ - u64 current_time; - static u64 prev_time = 0; - - if (prev_time == 0) - prev_time = get_jiffies_64(); - - current_time = get_jiffies_64(); - mali_dvfs_time[level] += current_time - prev_time; - prev_time = current_time; -} - -ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf) -{ - ssize_t ret = 0; - int i; - - update_time_in_state(maliDvfsStatus.currentStep); - - for (i = 0; i < MALI_DVFS_STEPS; i++) { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d %llu\n", - mali_dvfs[i].clock, - mali_dvfs_time[i]); - } - - if (ret < PAGE_SIZE - 1) { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - } else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - return ret; -} - -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - int i; - - for (i = 0; i < MALI_DVFS_STEPS; i++) { - mali_dvfs_time[i] = 0; - } - return count; -} -#endif - -int mali_dvfs_level_lock(void) -{ - int prev_status = _mali_osk_atomic_read(&dvfslock_status); - unsigned long rate = (mali_dvfs_isp[MALI_DVFS_DEFAULT_STEP_ISP].clock * mali_dvfs_isp[MALI_DVFS_DEFAULT_STEP_ISP].freq); - unsigned int read_val; -#ifdef EXYNOS4_ASV_ENABLED - int lock_vol; -#endif - - if (prev_status < 0) { - MALI_PRINT(("DVFS lock status is not valid for lock\n")); - return -1; - } else if (prev_status > 0) { - MALI_PRINT(("DVFS lock already enabled\n")); - return -1; - } - - _mali_osk_mutex_wait(mali_isp_lock); - - ENABLE_LOCK_BY_ISP = 1; - mali_isp_current_clock = mali_dvfs_isp[MALI_DVFS_DEFAULT_STEP_ISP].clock; -#ifdef CONFIG_REGULATOR - if (IS_ERR_OR_NULL(g3d_regulator)) { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); - _mali_osk_mutex_signal(mali_isp_lock); - return -1; - } - -#ifdef EXYNOS4_ASV_ENABLED - lock_vol = get_match_volt(ID_G3D, mali_dvfs_isp[MALI_DVFS_DEFAULT_STEP_ISP].clock * GPU_ASV_VOLT); - regulator_set_voltage(g3d_regulator, lock_vol, lock_vol); - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_dvfs_isp[MALI_DVFS_DEFAULT_STEP_ISP].clock * GPU_ASV_VOLT)); -#else - regulator_set_voltage(g3d_regulator, mali_dvfs_isp[MALI_DVFS_DEFAULT_STEP_ISP].vol, mali_dvfs_isp[MALI_DVFS_DEFAULT_STEP_ISP].vol); -#endif - mali_gpu_vol = regulator_get_voltage(g3d_regulator); - MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol)); -#endif - if (mali_clk_get() == MALI_FALSE) { - _mali_osk_mutex_signal(mali_isp_lock); - return -1; - } - clk_set_rate(mali_clock, (clk_get_rate(mali_clock) / 2)); - clk_set_parent(mali_parent_clock, mout_epll_clock); - - do { - cpu_relax(); - read_val = __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0); - } while (((read_val >> 4) & 0x7) != 0x1); - - clk_set_rate(fout_vpll_clock, mali_vpll_clk * GPU_MHZ); - clk_set_parent(mali_parent_clock, sclk_vpll_clock); - clk_set_parent(mali_clock, mali_parent_clock); - - do { - cpu_relax(); - read_val = __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0); - } while (((read_val >> 4) & 0x7) != 0x2); - - if (atomic_read(&clk_active) == 0) { - if (clk_enable(mali_clock) < 0) { - return MALI_FALSE; - } - atomic_set(&clk_active, 1); - } - - clk_set_rate(mali_clock, rate); - rate = clk_get_rate(mali_clock); - mali_gpu_clk = (int)(rate / GPU_MHZ); - mali_clk_put(MALI_FALSE); - _mali_osk_mutex_signal(mali_isp_lock); - MALI_DEBUG_PRINT(1, ("DVFS is locked by ISP\n")); - - return _mali_osk_atomic_inc_return(&dvfslock_status); -} - -int mali_dvfs_level_unlock(void) -{ - int prev_status = _mali_osk_atomic_read(&dvfslock_status); - if (prev_status <= 0) { - MALI_PRINT(("DVFS lock status is not valid for unlock\n")); - return -1; - } else if (prev_status >= 1) { - _mali_osk_mutex_wait(mali_isp_lock); - ENABLE_LOCK_BY_ISP = 0; - mali_isp_current_level = 0; - MALI_DEBUG_PRINT(1, ("DVFS lock is released ISP\n")); - _mali_osk_mutex_signal(mali_isp_lock); - } - return _mali_osk_atomic_dec_return(&dvfslock_status); -} diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4_pmm.h b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4_pmm.h deleted file mode 100644 index 0886a35146c..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3470/exynos4_pmm.h +++ /dev/null @@ -1,95 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/exynos3470/exynos4_pmm.h - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4_pmm.h - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ - -#ifndef __EXYNOS4_PMM_H__ -#define __EXYNOS4_PMM_H__ - -#include "mali_utgard.h" -#include "mali_osk.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @brief description of power change reasons - */ -typedef enum mali_power_mode_tag -{ - MALI_POWER_MODE_ON, - MALI_POWER_MODE_LIGHT_SLEEP, - MALI_POWER_MODE_DEEP_SLEEP, -} mali_power_mode; - -/** @brief Platform specific setup and initialisation of MALI - * - * This is called from the entrypoint of the driver to initialize the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_init(struct device *dev); - -/** @brief Platform specific deinitialisation of MALI - * - * This is called on the exit of the driver to terminate the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_deinit(struct device *dev); - -/** @brief Platform specific powerdown sequence of MALI - * - * Call as part of platform init if there is no PMM support, else the - * PMM will call it. - * There are three power modes defined: - * 1) MALI_POWER_MODE_ON - * 2) MALI_POWER_MODE_LIGHT_SLEEP - * 3) MALI_POWER_MODE_DEEP_SLEEP - * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle - * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions - * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued. - * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power - * off. - * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP - * mode. - * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during - * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from - * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well. - * @param power_mode defines the power modes - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode); - - -/** @brief Platform specific handling of GPU utilization data - * - * When GPU utilization data is enabled, this function will be - * periodically called. - * - * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. - */ -void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data); - -#ifdef CONFIG_MALI_DVFS -ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf); -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -extern int mali_dvfs_level_lock(void); -extern int mali_dvfs_level_unlock(void); -#endif -#ifdef __cplusplus -} -#endif -#endif diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4.c deleted file mode 100644 index bb8ec93c295..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4.c +++ /dev/null @@ -1,86 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/exynos3472/exynos4.c - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4.c - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ - -#ifdef CONFIG_PM_RUNTIME -#include -#endif - -#include -#include "mali_kernel_common.h" -#include "exynos4_pmm.h" - -#define MALI_GP_IRQ EXYNOS3_IRQ_GP_3D -#define MALI_PP0_IRQ EXYNOS3_IRQ_PP0_3D -#define MALI_PP1_IRQ EXYNOS3_IRQ_PP1_3D -#define MALI_PP2_IRQ EXYNOS3_IRQ_PP2_3D -#define MALI_PP3_IRQ EXYNOS3_IRQ_PP3_3D -#define MALI_GP_MMU_IRQ EXYNOS3_IRQ_GPMMU_3D -#define MALI_PP0_MMU_IRQ EXYNOS3_IRQ_PPMMU0_3D -#define MALI_PP1_MMU_IRQ EXYNOS3_IRQ_PPMMU1_3D -#define MALI_PP2_MMU_IRQ EXYNOS3_IRQ_PPMMU2_3D -#define MALI_PP3_MMU_IRQ EXYNOS3_IRQ_PPMMU3_3D - -static struct resource mali_gpu_resources[] = -{ - MALI_GPU_RESOURCES_MALI400_MP4(0x13000000, - MALI_GP_IRQ, MALI_GP_MMU_IRQ, - MALI_PP0_IRQ, MALI_PP0_MMU_IRQ, - MALI_PP1_IRQ, MALI_PP1_MMU_IRQ, - MALI_PP2_IRQ, MALI_PP2_MMU_IRQ, - MALI_PP3_IRQ, MALI_PP3_MMU_IRQ) -}; - -static struct mali_gpu_device_data mali_gpu_data = -{ - .shared_mem_size = 256 * 1024 * 1024, /* 256MB */ - .fb_start = 0x40000000, - .fb_size = 0xb1000000, - .utilization_interval = 100, /* 100ms */ - .utilization_callback = mali_gpu_utilization_handler, -}; - -int mali_platform_device_register(void) -{ - int err; - - MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n")); - - /* Connect resources to the device */ - err = platform_device_add_resources(&exynos4_device_g3d, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0])); - if (0 == err) - { - err = platform_device_add_data(&exynos4_device_g3d, &mali_gpu_data, sizeof(mali_gpu_data)); - if (0 == err) - { - mali_platform_init(&(exynos4_device_g3d.dev)); -#ifdef CONFIG_PM_RUNTIME - pm_runtime_set_autosuspend_delay(&(exynos4_device_g3d.dev), 1000); - pm_runtime_use_autosuspend(&(exynos4_device_g3d.dev)); - pm_runtime_enable(&(exynos4_device_g3d.dev)); -#endif - return 0; - } - - } - return err; -} - -void mali_platform_device_unregister(void) -{ - MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n")); - mali_platform_deinit(&(exynos4_device_g3d.dev)); -} diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c deleted file mode 100644 index 097115b0049..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.c +++ /dev/null @@ -1,973 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/exynos3472/exynos4_pmm.c - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4_pmm.c - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "exynos4_pmm.h" - -#include -#include -#include -#include -#include - -#if defined(CONFIG_MALI400_PROFILING) -#include "mali_osk_profiling.h" -#endif - -/* lock/unlock CPU freq by Mali */ -#include -#include -#include -#include -#ifdef CONFIG_CPU_FREQ -#define EXYNOS4_ASV_ENABLED -#endif - -/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */ -#ifndef S5P_G3D_CONFIGURATION -#define S5P_G3D_CONFIGURATION EXYNOS4_G3D_CONFIGURATION -#endif -#ifndef S5P_G3D_STATUS -#define S5P_G3D_STATUS (EXYNOS4_G3D_CONFIGURATION + 0x4) -#endif -#ifndef S5P_INT_LOCAL_PWR_EN -#define S5P_INT_LOCAL_PWR_EN EXYNOS_INT_LOCAL_PWR_EN -#endif - -#include -#include -#include - -#define MALI_DVFS_STEPS 4 - -#define MALI_DVFS_WATING 10 /* msec */ -#define MALI_DVFS_DEFAULT_STEP 0 -#define PD_G3D_LOCK_FLAG 2 - -#define MALI_DVFS_CLK_DEBUG 0 -#define CPUFREQ_LOCK_DURING_440 1 - -static int bMaliDvfsRun = 0; - -typedef struct mali_dvfs_tableTag{ - unsigned int clock; - unsigned int freq; - unsigned int vol; - unsigned int downthreshold; - unsigned int upthreshold; -}mali_dvfs_table; - -typedef struct mali_dvfs_statusTag{ - unsigned int currentStep; - mali_dvfs_table * pCurrentDvfs; - -} mali_dvfs_status_t; - -/*dvfs status*/ -mali_dvfs_status_t maliDvfsStatus; -int mali_dvfs_control; - -typedef struct mali_runtime_resumeTag{ - int clk; - int vol; - unsigned int step; -}mali_runtime_resume_table; - -mali_runtime_resume_table mali_runtime_resume = {266, 875000, 1}; - -/* dvfs table updated on 140227 */ -mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ - /*step 0*/{160, 1000000, 875000, 0, 70}, - /*step 1*/{266, 1000000, 875000, 62, 90}, - /*step 2*/{350, 1000000, 925000, 85, 90}, - /*step 3*/{440, 1000000, 1000000, 85, 100} }; - - -char *mali_freq_table = "440 350 266 160"; - -#define EXTXTALCLK_NAME "ext_xtal" -#define VPLLSRCCLK_NAME "mout_vpllsrc" -#define FOUTVPLLCLK_NAME "fout_vpll" -#define SCLEPLLCLK_NAME "sclk_epll_muxed" -#define SCLVPLLCLK_NAME "mout_vpll" -#define GPUMOUT1CLK_NAME "mout_g3d1" -#define MPLLCLK_NAME "mout_mpll" -#define SCLK_MPLL_PRE_DIV_CLK_NAME "sclk_mpll_pre_div" -#define GPUMOUT0CLK_NAME "mout_g3d0" -#define GPUCLK_NAME "sclk_g3d" -#define CLK_DIV_STAT_G3D 0x1003C62C -#define CLK_DESC "clk-divider-status" - -static struct clk *ext_xtal_clock = NULL; -static struct clk *vpll_src_clock = NULL; -static struct clk *mpll_clock = NULL; -static struct clk *sclk_mpll_pre_div_clock; -static struct clk *mali_mout0_clock; -static struct clk *fout_vpll_clock = NULL; -static struct clk *sclk_epll_clock; -static struct clk *sclk_vpll_clock = NULL; -static struct clk *mali_parent_clock; -static struct clk *mali_clock = NULL; - -/* Exynos3472 */ -int mali_gpu_clk = 266; -int mali_gpu_vol = 875000; -static unsigned int GPU_MHZ = 1000000; -static unsigned int const GPU_ASV_VOLT = 1000; -static int nPowermode; -static atomic_t clk_active; - -mali_io_address clk_register_map = 0; - -/* export GPU frequency as a read-only parameter so that it can be read in /sys */ -module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); -module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); -module_param(mali_freq_table, charp, S_IRUSR | S_IRGRP | S_IROTH); -#ifdef CONFIG_MALI_DVFS -module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS"); -DEVICE_ATTR(time_in_state, S_IRUGO|S_IWUSR, show_time_in_state, set_time_in_state); -MODULE_PARM_DESC(time_in_state, "Time-in-state of Mali DVFS"); -#endif -MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock"); -MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage"); -MODULE_PARM_DESC(mali_freq_table, "Mali frequency table"); - -#ifdef CONFIG_REGULATOR -struct regulator *g3d_regulator = NULL; -#endif -atomic_t mali_cpufreq_lock; - -/* DVFS */ -#ifdef CONFIG_MALI_DVFS -static unsigned int mali_dvfs_utilization = 255; -static void update_time_in_state(int level); -u64 mali_dvfs_time[MALI_DVFS_STEPS]; -#endif - -static void mali_dvfs_work_handler(struct work_struct *w); -static struct workqueue_struct *mali_dvfs_wq = 0; -_mali_osk_mutex_t *mali_dvfs_lock; -int mali_runtime_resumed = -1; -static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler); - -int cpufreq_lock_by_mali(unsigned int freq) -{ -#ifdef CONFIG_EXYNOS4_CPUFREQ - unsigned int level; - - if (atomic_read(&mali_cpufreq_lock) == 0) { - if (exynos_cpufreq_get_level(freq * 1000, &level)) { - printk(KERN_ERR "Mali: failed to get cpufreq level for %dMHz", freq); - return -EINVAL; - } - - if (exynos_cpufreq_lock(DVFS_LOCK_ID_G3D, level)) { - printk(KERN_ERR "Mali: failed to cpufreq lock for L%d", level); - return -EINVAL; - } - - atomic_set(&mali_cpufreq_lock, 1); - printk(KERN_DEBUG "Mali: cpufreq locked on <%d>%dMHz\n", level, freq); - } -#endif - return 0; -} - -void cpufreq_unlock_by_mali(void) -{ -#ifdef CONFIG_EXYNOS4_CPUFREQ - if (atomic_read(&mali_cpufreq_lock) == 1) { - exynos_cpufreq_lock_free(DVFS_LOCK_ID_G3D); - atomic_set(&mali_cpufreq_lock, 0); - printk(KERN_DEBUG "Mali: cpufreq locked off\n"); - } -#endif -} - -#ifdef CONFIG_REGULATOR -void mali_regulator_disable(void) -{ - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n")); - return; - } - regulator_disable(g3d_regulator); -} - -void mali_regulator_enable(void) -{ - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n")); - return; - } - regulator_enable(g3d_regulator); -} - -void mali_regulator_set_voltage(int min_uV, int max_uV) -{ - _mali_osk_mutex_wait(mali_dvfs_lock); - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); - _mali_osk_mutex_signal(mali_dvfs_lock); - return; - } - MALI_DEBUG_PRINT(1, ("= regulator_set_voltage: %d, %d \n", min_uV, max_uV)); - regulator_set_voltage(g3d_regulator, min_uV, max_uV); - mali_gpu_vol = regulator_get_voltage(g3d_regulator); - MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol)); - _mali_osk_mutex_signal(mali_dvfs_lock); -} -#endif - -#ifdef CONFIG_MALI_DVFS -static unsigned int get_mali_dvfs_status(void) -{ - return maliDvfsStatus.currentStep; -} -#endif - -mali_bool mali_clk_get(void) -{ - if (ext_xtal_clock == NULL) { - ext_xtal_clock = clk_get(NULL, EXTXTALCLK_NAME); - if (IS_ERR(ext_xtal_clock)) { - MALI_PRINT(("MALI Error : failed to get source ext_xtal_clock\n")); - return MALI_FALSE; - } - } - - if (vpll_src_clock == NULL) { - vpll_src_clock = clk_get(NULL, VPLLSRCCLK_NAME); - if (IS_ERR(vpll_src_clock)) { - MALI_PRINT(("MALI Error : failed to get source vpll_src_clock\n")); - return MALI_FALSE; - } - } - - if (fout_vpll_clock == NULL) { - fout_vpll_clock = clk_get(NULL, FOUTVPLLCLK_NAME); - if (IS_ERR(fout_vpll_clock)) { - MALI_PRINT(("MALI Error : failed to get source fout_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (mpll_clock == NULL) - { - mpll_clock = clk_get(NULL,MPLLCLK_NAME); - - if (IS_ERR(mpll_clock)) { - MALI_PRINT( ("MALI Error : failed to get source mpll clock\n")); - return MALI_FALSE; - } - } - - if (sclk_epll_clock == NULL) { - sclk_epll_clock = clk_get(NULL, SCLEPLLCLK_NAME); - if (IS_ERR(sclk_epll_clock)) { - MALI_PRINT(("MALI Error : failed to get source sclk_epll_clock\n")); - } - } - - if (sclk_mpll_pre_div_clock == NULL) { - sclk_mpll_pre_div_clock = clk_get(NULL, SCLK_MPLL_PRE_DIV_CLK_NAME); - - if (IS_ERR(sclk_mpll_pre_div_clock)) { - MALI_PRINT(("MALI Error : failed to get source sclk_mpll_pre_div clock\n")); - return MALI_FALSE; - } - } - - if (mali_mout0_clock == NULL) - { - mali_mout0_clock = clk_get(NULL, GPUMOUT0CLK_NAME); - - if (IS_ERR(mali_mout0_clock)) { - MALI_PRINT(("MALI Error : failed to get source mali mout0 clock\n")); - return MALI_FALSE; - } - } - - if (sclk_vpll_clock == NULL) { - sclk_vpll_clock = clk_get(NULL, SCLVPLLCLK_NAME); - if (IS_ERR(sclk_vpll_clock)) { - MALI_PRINT(("MALI Error : failed to get source sclk_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (mali_parent_clock == NULL) { - mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME); - if (IS_ERR(mali_parent_clock)) { - MALI_PRINT(("MALI Error : failed to get source mali parent clock\n")); - return MALI_FALSE; - } - } - - if (mali_clock == NULL) { - mali_clock = clk_get(NULL, GPUCLK_NAME); - if (IS_ERR(mali_clock)) { - MALI_PRINT(("MALI Error : failed to get source mali clock\n")); - return MALI_FALSE; - } - } - - return MALI_TRUE; -} - -void mali_clk_put(mali_bool binc_mali_clock) -{ - if (mali_parent_clock) { - clk_put(mali_parent_clock); - mali_parent_clock = NULL; - } - - if (sclk_vpll_clock) { - clk_put(sclk_vpll_clock); - sclk_vpll_clock = NULL; - } - - if (binc_mali_clock && fout_vpll_clock) { - clk_put(fout_vpll_clock); - fout_vpll_clock = NULL; - } - - if (sclk_epll_clock) { - clk_put(sclk_epll_clock); - sclk_epll_clock = NULL; - } - - if (mpll_clock) { - clk_put(mpll_clock); - mpll_clock = NULL; - } - - if (sclk_mpll_pre_div_clock) { - clk_put(sclk_mpll_pre_div_clock); - sclk_mpll_pre_div_clock = NULL; - } - - if (mali_mout0_clock) { - clk_put(mali_mout0_clock); - mali_mout0_clock = NULL; - } - - if (vpll_src_clock) { - clk_put(vpll_src_clock); - vpll_src_clock = NULL; - } - - if (ext_xtal_clock) { - clk_put(ext_xtal_clock); - ext_xtal_clock = NULL; - } - - if (binc_mali_clock && mali_clock) { - clk_put(mali_clock); - mali_clock = NULL; - } -} - -void mali_clk_set_rate(unsigned int clk, unsigned int mhz) -{ - int err; - unsigned int read_val; - unsigned long rate = (unsigned long)clk * (unsigned long)mhz; - unsigned long CurRate = 0; - - _mali_osk_mutex_wait(mali_dvfs_lock); - MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk)); - - if (mali_clk_get() == MALI_FALSE) { - _mali_osk_mutex_signal(mali_dvfs_lock); - return; - } - - CurRate = clk_get_rate(mali_clock); - - if (CurRate == 0) { - _mali_osk_mutex_signal(mali_dvfs_lock); - MALI_PRINT_ERROR(("clk_get_rate[mali_clock] is 0 - return\n")); - return; - } - - /* Use MPLL 200Mhz for a moment */ - err = clk_set_rate(mali_clock, CurRate / 4); - - if (err > 0) - MALI_PRINT_ERROR(("Failed to set Mali clock before change PLL: %d\n", err)); - - err = clk_set_parent(mali_mout0_clock, sclk_mpll_pre_div_clock); - - if (err) - MALI_PRINT_ERROR(("mali_mout0_clock set parent to sclk_mpll_pre_div_clock failed\n")); - - err = clk_set_parent(mali_clock, mali_mout0_clock); - - if (err) - MALI_PRINT_ERROR(("mali_clock set parent to mali_mout0_clock failed\n")); - - err = clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ); - - if (err > 0) - MALI_PRINT_ERROR(("Failed to set fout_vpll clock: %d\n", err)); - - - err = clk_set_parent(vpll_src_clock, ext_xtal_clock); - - if (err) - MALI_PRINT_ERROR(("vpll_src set parent to ext_xtal failed\n")); - - err = clk_set_parent(sclk_vpll_clock, fout_vpll_clock); - - if (err) - MALI_PRINT_ERROR(("sclk_vpll set parent to fout_vpll failed\n")); - - MALI_DEBUG_PRINT(3, ("Mali platform: set_parent_vpll : %8.x \n", (__raw_readl(EXYNOS4_CLKSRC_TOP0) >> 8) & 0x1)); - - err = clk_set_parent(mali_parent_clock, sclk_vpll_clock); - - if (err) - MALI_PRINT_ERROR(("mali_parent set parent to sclk_vpll failed\n")); - - do { - cpu_relax(); - read_val = __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0); - } while (((read_val >> 4) & 0x7) != 0x2); - - MALI_DEBUG_PRINT(3, ("SET to VPLL EXYNOS4_CLKMUX_STAT_G3D0 : 0x%08x\n", __raw_readl(EXYNOS4_CLKMUX_STAT_G3D0))); - - err = clk_set_parent(mali_clock, mali_parent_clock); - - if (err) - MALI_PRINT_ERROR(("mali_clock set parent to mali_parent failed\n")); - - if (atomic_read(&clk_active) == 0) { - if (clk_enable(mali_clock) < 0) { - _mali_osk_mutex_signal(mali_dvfs_lock); - return; - } - atomic_set(&clk_active, 1); - } - - err = clk_set_rate(mali_clock, rate); - - if (err > 0) - MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err)); - - rate = clk_get_rate(mali_clock); - - MALI_DEBUG_PRINT(1, ("Mali frequency %d\n", rate / mhz)); - GPU_MHZ = mhz; - - mali_gpu_clk = (int)(rate / mhz); - mali_clk_put(MALI_FALSE); - - _mali_osk_mutex_signal(mali_dvfs_lock); -} - -#ifdef CONFIG_MALI_DVFS -mali_bool set_mali_dvfs_current_step(unsigned int step) -{ - _mali_osk_mutex_wait(mali_dvfs_lock); - maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS; - _mali_osk_mutex_signal(mali_dvfs_lock); - return MALI_TRUE; -} - -static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) -{ - u32 validatedStep = step; -#if MALI_DVFS_CLK_DEBUG - unsigned int *pRegMaliClkDiv; - unsigned int *pRegMaliMpll; -#endif - - if(boostup) { -#ifdef CONFIG_REGULATOR - /*change the voltage*/ -#ifdef EXYNOS4_ASV_ENABLED - mali_regulator_set_voltage(get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT), get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); -#ifdef EXYNOS4_ABB_ENABLED - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); -#endif -#else - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif -#endif - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); - } else { - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); -#ifdef CONFIG_REGULATOR -#ifdef EXYNOS4_ASV_ENABLED - /*change the voltage*/ - mali_regulator_set_voltage(get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT), get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); -#ifdef EXYNOS4_ABB_ENABLED - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); -#endif -#else - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif -#endif - } - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| - MALI_PROFILING_EVENT_CHANNEL_GPU| - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - mali_clk_put(MALI_FALSE); - -#if MALI_DVFS_CLK_DEBUG - pRegMaliClkDiv = ioremap(0x1003c52c, 32); - pRegMaliMpll = ioremap(0x1003c22c, 32); - MALI_PRINT(("Mali MPLL reg:%d, CLK DIV: %d \n", *pRegMaliMpll, *pRegMaliClkDiv)); -#endif - set_mali_dvfs_current_step(validatedStep); - /*for future use*/ - maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep]; - -#if CPUFREQ_LOCK_DURING_440 - /* lock/unlock CPU freq by Mali */ - if (mali_dvfs[step].clock >= 440) - cpufreq_lock_by_mali(400); - else - cpufreq_unlock_by_mali(); -#endif - return MALI_TRUE; -} - -static void mali_platform_wating(u32 msec) -{ - /* - * sample wating - * change this in the future with proper check routine. - */ - unsigned int read_val; - while(1) { - read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00); - if ((read_val & 0x8000)==0x0000) break; - - _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */ - } -} - -static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup ) -{ - MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n", step, boostup)); - - if (!set_mali_dvfs_status(step, boostup)) { - MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup)); - return MALI_FALSE; - } - - /* wait until clock and voltage is stablized */ - mali_platform_wating(MALI_DVFS_WATING); /* msec */ - return MALI_TRUE; -} - -static unsigned int decideNextStatus(unsigned int utilization) -{ - static unsigned int level = 0; - int iStepCount = 0; - - if (mali_runtime_resumed >= 0) { - level = mali_runtime_resumed; - mali_runtime_resumed = -1; - } - - if (mali_dvfs_control == 0) { - if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) && - level < MALI_DVFS_STEPS - 1) { - level++; - } else if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) && - level > 0) { - level--; - } - } else { - for (iStepCount = MALI_DVFS_STEPS - 1; iStepCount >= 0; iStepCount--) { - if (mali_dvfs_control >= mali_dvfs[iStepCount].clock) { - level = iStepCount; - break; - } - } - } - - return level; -} - -static mali_bool mali_dvfs_status(unsigned int utilization) -{ - unsigned int nextStatus = 0; - unsigned int curStatus = 0; - mali_bool boostup = MALI_FALSE; - static int stay_count = 5; - - MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n", utilization)); - - /* decide next step */ - curStatus = get_mali_dvfs_status(); - nextStatus = decideNextStatus(utilization); - - MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); - /* if next status is same with current status, don't change anything */ - if(curStatus != nextStatus) { - /*check if boost up or not*/ - if(maliDvfsStatus.currentStep < nextStatus) { - boostup = 1; - stay_count = 5; - } else if (maliDvfsStatus.currentStep > nextStatus){ - stay_count--; - } - - if( boostup == 1 || stay_count <= 0){ - /*change mali dvfs status*/ - update_time_in_state(curStatus); - if (!change_mali_dvfs_status(nextStatus, boostup)) { - MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); - return MALI_FALSE; - } - boostup = 0; - stay_count = 5; - } - } - else - stay_count = 5; - - return MALI_TRUE; -} -#endif - -static void mali_dvfs_work_handler(struct work_struct *w) -{ - bMaliDvfsRun = 1; - MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); - -#ifdef CONFIG_MALI_DVFS - if(!mali_dvfs_status(mali_dvfs_utilization)) - MALI_DEBUG_PRINT(1, ( "error on mali dvfs status in mali_dvfs_work_handler")); -#endif - - bMaliDvfsRun = 0; -} - -mali_bool init_mali_dvfs_status(void) -{ - /* - * default status - * add here with the right function to get initilization value. - */ - if (!mali_dvfs_wq) - mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs"); - - /* add a error handling here */ - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; - - return MALI_TRUE; -} - -void deinit_mali_dvfs_status(void) -{ - if (mali_dvfs_wq) - destroy_workqueue(mali_dvfs_wq); - - mali_dvfs_wq = NULL; -} - -#ifdef CONFIG_MALI_DVFS -mali_bool mali_dvfs_handler(unsigned int utilization) -{ - mali_dvfs_utilization = utilization; - queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work); - - return MALI_TRUE; -} -#endif - -static mali_bool init_mali_clock(void) -{ - mali_bool ret = MALI_TRUE; - nPowermode = MALI_POWER_MODE_DEEP_SLEEP; - - if (mali_clock != 0) - return ret; /* already initialized */ - - mali_dvfs_lock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED, 0); - - if (mali_dvfs_lock == NULL) - return _MALI_OSK_ERR_FAULT; - - if (!mali_clk_get()) - { - MALI_PRINT(("Error: Failed to get Mali clock\n")); - goto err_clk; - } - - mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); - - MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock)); - -#ifdef CONFIG_REGULATOR - g3d_regulator = regulator_get(NULL, "vdd_g3d"); - - if (IS_ERR(g3d_regulator)) { - MALI_PRINT(("MALI Error : failed to get vdd_g3d\n")); - ret = MALI_FALSE; - goto err_regulator; - } - - mali_gpu_vol = mali_runtime_resume.vol; -#ifdef EXYNOS4_ASV_ENABLED - mali_gpu_vol = get_match_volt(ID_G3D, mali_gpu_clk * GPU_ASV_VOLT); - mali_runtime_resume.vol = get_match_volt(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT); -#endif - - regulator_enable(g3d_regulator); - mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); - -#if defined(EXYNOS4_ASV_ENABLED) && defined(EXYNOS4_ABB_ENABLED) - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT)); -#endif -#endif - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| - MALI_PROFILING_EVENT_CHANNEL_GPU| - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - mali_clk_put(MALI_FALSE); - - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR -err_regulator: - regulator_put(g3d_regulator); -#endif -err_clk: - mali_clk_put(MALI_TRUE); - - return ret; -} - -static mali_bool deinit_mali_clock(void) -{ - if (mali_clock == 0) - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR - if (g3d_regulator) { - regulator_put(g3d_regulator); - g3d_regulator = NULL; - } -#endif - mali_clk_put(MALI_TRUE); - return MALI_TRUE; -} - -static _mali_osk_errcode_t enable_mali_clocks(void) -{ - int err; - - if (atomic_read(&clk_active) == 0) { - err = clk_enable(mali_clock); - MALI_DEBUG_PRINT(3, ("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err)); - atomic_set(&clk_active, 1); - } - - /* set clock rate */ -#ifdef CONFIG_MALI_DVFS -#if defined(EXYNOS4_ASV_ENABLED) && defined(EXYNOS4_ABB_ENABLED) - if (samsung_rev() == EXYNOS3470_REV_2_0) - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT)); -#endif - - if (mali_dvfs_control != 0 || mali_gpu_clk >= mali_runtime_resume.clk) { - mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); - } else { -#ifdef CONFIG_REGULATOR - mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol); -#if defined(EXYNOS4_ASV_ENABLED) && defined(EXYNOS4_ABB_ENABLED) - exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT)); -#endif -#endif - mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ); - set_mali_dvfs_current_step(mali_runtime_resume.step); - } -#else - mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; -#endif - MALI_SUCCESS; -} - -static _mali_osk_errcode_t disable_mali_clocks(void) -{ -#if defined(EXYNOS4_ASV_ENABLED) && defined(EXYNOS4_ABB_ENABLED) - if (samsung_rev() == EXYNOS3470_REV_2_0) - exynos_set_abb(ID_G3D, ABB_BYPASS); -#endif - - if (atomic_read(&clk_active)) { - clk_disable(mali_clock); - MALI_DEBUG_PRINT(3, ("disable_mali_clocks mali_clock %p\n", mali_clock)); - atomic_set(&clk_active, 0); - } - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_init(struct device *dev) -{ - atomic_set(&clk_active, 0); - MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT); - -#ifdef CONFIG_MALI_DVFS - if (!clk_register_map) - clk_register_map = _mali_osk_mem_mapioregion(CLK_DIV_STAT_G3D, 0x20, CLK_DESC); - - if (!init_mali_dvfs_status()) - MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n")); - - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; -#endif - mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON); - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_deinit(struct device *dev) -{ - mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP); - deinit_mali_clock(); - -#ifdef CONFIG_MALI_DVFS - deinit_mali_dvfs_status(); - if (clk_register_map) { - _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map); - clk_register_map = NULL; - } -#endif - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode) -{ - switch (power_mode) - { - case MALI_POWER_MODE_ON: - MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n", - nPowermode ? "powering on" : "already on")); - if (nPowermode == MALI_POWER_MODE_LIGHT_SLEEP || nPowermode == MALI_POWER_MODE_DEEP_SLEEP) { - MALI_DEBUG_PRINT(4, ("enable clock\n")); - enable_mali_clocks(); - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - nPowermode = power_mode; - } - break; - case MALI_POWER_MODE_DEEP_SLEEP: - case MALI_POWER_MODE_LIGHT_SLEEP: - MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode == MALI_POWER_MODE_LIGHT_SLEEP ? - "MALI_POWER_MODE_LIGHT_SLEEP" : "MALI_POWER_MODE_DEEP_SLEEP", - nPowermode ? "already off" : "powering off")); - if (nPowermode == MALI_POWER_MODE_ON) { - disable_mali_clocks(); - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - 0, 0, 0, 0, 0); -#endif - nPowermode = power_mode; - } - break; - } - MALI_SUCCESS; -} - -void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data) -{ - if (nPowermode == MALI_POWER_MODE_ON) - { -#ifdef CONFIG_MALI_DVFS - if(!mali_dvfs_handler(data->utilization_gpu)) - MALI_DEBUG_PRINT(1, ("error on mali dvfs status in utilization\n")); -#endif - } -} - -#ifdef CONFIG_MALI_DVFS -static void update_time_in_state(int level) -{ - u64 current_time; - static u64 prev_time = 0; - - if (prev_time == 0) - prev_time = get_jiffies_64(); - - current_time = get_jiffies_64(); - mali_dvfs_time[level] += current_time - prev_time; - prev_time = current_time; -} - -ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf) -{ - ssize_t ret = 0; - int i; - - update_time_in_state(maliDvfsStatus.currentStep); - - for (i = 0; i < MALI_DVFS_STEPS; i++) { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d %llu\n", - mali_dvfs[i].clock, - mali_dvfs_time[i]); - } - - if (ret < PAGE_SIZE - 1) { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - } else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - return ret; -} - -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - int i; - - for (i = 0; i < MALI_DVFS_STEPS; i++) { - mali_dvfs_time[i] = 0; - } - return count; -} -#endif diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.h b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.h deleted file mode 100644 index ad972aa1c49..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos3472/exynos4_pmm.h +++ /dev/null @@ -1,93 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/exynos3472/exynos4_pmm.h - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4_pmm.h - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ - -#ifndef __EXYNOS4_PMM_H__ -#define __EXYNOS4_PMM_H__ - -#include "mali_utgard.h" -#include "mali_osk.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @brief description of power change reasons - */ -typedef enum mali_power_mode_tag -{ - MALI_POWER_MODE_ON, - MALI_POWER_MODE_LIGHT_SLEEP, - MALI_POWER_MODE_DEEP_SLEEP, -} mali_power_mode; - -/** @brief Platform specific setup and initialisation of MALI - * - * This is called from the entrypoint of the driver to initialize the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_init(struct device *dev); - -/** @brief Platform specific deinitialisation of MALI - * - * This is called on the exit of the driver to terminate the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_deinit(struct device *dev); - -/** @brief Platform specific powerdown sequence of MALI - * - * Call as part of platform init if there is no PMM support, else the - * PMM will call it. - * There are three power modes defined: - * 1) MALI_POWER_MODE_ON - * 2) MALI_POWER_MODE_LIGHT_SLEEP - * 3) MALI_POWER_MODE_DEEP_SLEEP - * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle - * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions - * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued. - * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power - * off. - * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP - * mode. - * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during - * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from - * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well. - * @param power_mode defines the power modes - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode); - - -/** @brief Platform specific handling of GPU utilization data - * - * When GPU utilization data is enabled, this function will be - * periodically called. - * - * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. - */ -void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data); - -#ifdef CONFIG_MALI_DVFS -ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf); -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -#endif -#ifdef __cplusplus -} -#endif -#endif diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4.c deleted file mode 100644 index 482577daa35..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4.c +++ /dev/null @@ -1,86 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/exynos4415/exynos4.c - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4.c - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ - -#ifdef CONFIG_PM_RUNTIME -#include -#endif - -#include -#include "mali_kernel_common.h" -#include "exynos4_pmm.h" - -#define MALI_GP_IRQ EXYNOS4_IRQ_GP_3D -#define MALI_PP0_IRQ EXYNOS4_IRQ_PP0_3D -#define MALI_PP1_IRQ EXYNOS4_IRQ_PP1_3D -#define MALI_PP2_IRQ EXYNOS4_IRQ_PP2_3D -#define MALI_PP3_IRQ EXYNOS4_IRQ_PP3_3D -#define MALI_GP_MMU_IRQ EXYNOS4_IRQ_GPMMU_3D -#define MALI_PP0_MMU_IRQ EXYNOS4_IRQ_PPMMU0_3D -#define MALI_PP1_MMU_IRQ EXYNOS4_IRQ_PPMMU1_3D -#define MALI_PP2_MMU_IRQ EXYNOS4_IRQ_PPMMU2_3D -#define MALI_PP3_MMU_IRQ EXYNOS4_IRQ_PPMMU3_3D - -static struct resource mali_gpu_resources[] = -{ - MALI_GPU_RESOURCES_MALI400_MP4(0x13000000, - MALI_GP_IRQ, MALI_GP_MMU_IRQ, - MALI_PP0_IRQ, MALI_PP0_MMU_IRQ, - MALI_PP1_IRQ, MALI_PP1_MMU_IRQ, - MALI_PP2_IRQ, MALI_PP2_MMU_IRQ, - MALI_PP3_IRQ, MALI_PP3_MMU_IRQ) -}; - -static struct mali_gpu_device_data mali_gpu_data = -{ - .shared_mem_size = 256 * 1024 * 1024, /* 256MB */ - .fb_start = 0x40000000, - .fb_size = 0xb1000000, - .utilization_interval = 100, /* 100ms */ - .utilization_callback = mali_gpu_utilization_handler, -}; - -int mali_platform_device_register(void) -{ - int err; - - MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n")); - - /* Connect resources to the device */ - err = platform_device_add_resources(&exynos4_device_g3d, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0])); - if (0 == err) - { - err = platform_device_add_data(&exynos4_device_g3d, &mali_gpu_data, sizeof(mali_gpu_data)); - if (0 == err) - { - mali_platform_init(&(exynos4_device_g3d.dev)); -#ifdef CONFIG_PM_RUNTIME - pm_runtime_set_autosuspend_delay(&(exynos4_device_g3d.dev), 1000); - pm_runtime_use_autosuspend(&(exynos4_device_g3d.dev)); - pm_runtime_enable(&(exynos4_device_g3d.dev)); -#endif - return 0; - } - - } - return err; -} - -void mali_platform_device_unregister(void) -{ - MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n")); - mali_platform_deinit(&(exynos4_device_g3d.dev)); -} diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4_pmm.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4_pmm.c deleted file mode 100644 index 1ce580c6727..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4_pmm.c +++ /dev/null @@ -1,937 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/exynos4415/exynos4_pmm.c - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4_pmm.c - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "exynos4_pmm.h" - -#include -#include -#include -#include -#include - -#if defined(CONFIG_MALI400_PROFILING) -#include "mali_osk_profiling.h" -#endif - -/* lock/unlock CPU freq by Mali */ -#include -#include -#include -#include -#ifdef CONFIG_CPU_FREQ -#define EXYNOS4_ASV_ENABLED -#endif - -#ifdef CONFIG_MALI_DVFS_FULL_LEVEL -#define MALI_DVFS_FULL_LEVEL -#endif - -/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */ -#ifndef S5P_G3D_CONFIGURATION -#define S5P_G3D_CONFIGURATION EXYNOS4_G3D_CONFIGURATION -#endif -#ifndef S5P_G3D_STATUS -#define S5P_G3D_STATUS (EXYNOS4_G3D_CONFIGURATION + 0x4) -#endif -#ifndef S5P_INT_LOCAL_PWR_EN -#define S5P_INT_LOCAL_PWR_EN EXYNOS_INT_LOCAL_PWR_EN -#endif - -#include -#include -#include - -#ifdef MALI_DVFS_FULL_LEVEL -#define MALI_DVFS_STEPS 7 -#else -#define MALI_DVFS_STEPS 4 -#endif - -#define MALI_DVFS_WATING 10 /* msec */ -#define MALI_DVFS_DEFAULT_STEP 1 -#define PD_G3D_LOCK_FLAG 2 - -#define MALI_DVFS_CLK_DEBUG 0 -#define CPUFREQ_LOCK_DURING_440 1 - -static int bMaliDvfsRun = 0; - -typedef struct mali_dvfs_tableTag{ - unsigned int clock; - unsigned int freq; - unsigned int vol; - unsigned int downthreshold; - unsigned int upthreshold; -}mali_dvfs_table; - -typedef struct mali_dvfs_statusTag{ - unsigned int currentStep; - mali_dvfs_table * pCurrentDvfs; - -} mali_dvfs_status_t; - -/*dvfs status*/ -mali_dvfs_status_t maliDvfsStatus; -int mali_dvfs_control; - -typedef struct mali_runtime_resumeTag{ - int clk; - int vol; - unsigned int step; -}mali_runtime_resume_table; - -mali_runtime_resume_table mali_runtime_resume = {266, 875000, 1}; - -#ifdef MALI_DVFS_FULL_LEVEL -/*dvfs table updated on 131203*/ -mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ - /*step 0*/{160, 1000000, 850000, 0, 60}, - /*step 1*/{266, 1000000, 875000, 52, 70}, - /*step 2*/{350, 1000000, 950000, 62, 80}, - /*step 3*/{440, 1000000, 1025000, 75, 80}, - /*step 4*/{550, 1000000, 1125000, 85, 90}, - /*step 5*/{667, 1000000, 1225000, 85, 95}, - /*step 6*/{733, 1000000, 1300000, 95, 100} }; -#else -/*dvfs table updated on 131203*/ -mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ - /*step 0*/{160, 1000000, 850000, 0, 70}, - /*step 1*/{266, 1000000, 875000, 62, 90}, - /*step 2*/{350, 1000000, 950000, 85, 90}, - /*step 3*/{440, 1000000, 1025000, 85, 100} }; -#endif - -/* Exynos4415 */ -int mali_gpu_clk = 266; -int mali_gpu_vol = 875000; -#ifdef MALI_DVFS_FULL_LEVEL -char *mali_freq_table = "733 667 550 440 350 266 160"; -#else -char *mali_freq_table = "440 350 266 160"; -#endif - -#define EXTXTALCLK_NAME "ext_xtal" -#define VPLLSRCCLK_NAME "vpll_src" -#define FOUTVPLLCLK_NAME "fout_vpll" -#define SCLKEPLLCLK_NAME "sclk_epll" -#define SCLVPLLCLK_NAME "sclk_vpll" -#define GPUMOUT1CLK_NAME "mout_g3d1" -#define GPUMOUT0CLK_NAME "mout_g3d0" -#define GPUCLK_NAME "sclk_g3d" -#define CLK_DIV_STAT_G3D 0x1003C62C -#define CLK_DESC "clk-divider-status" - -static struct clk *ext_xtal_clock = NULL; -static struct clk *vpll_src_clock = NULL; -static struct clk *fout_vpll_clock = NULL; -static struct clk *sclk_epll_clock = NULL; -static struct clk *sclk_vpll_clock = NULL; -static struct clk *mali_parent_clock = NULL; -static struct clk *mali_clock = NULL; - -static unsigned int GPU_MHZ = 1000000; -static unsigned int const GPU_ASV_VOLT = 1000; -static int nPowermode; -static atomic_t clk_active; - -mali_io_address clk_register_map = 0; - -/* export GPU frequency as a read-only parameter so that it can be read in /sys */ -module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); -module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); -module_param(mali_freq_table, charp, S_IRUSR | S_IRGRP | S_IROTH); -#ifdef CONFIG_MALI_DVFS -module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS"); -DEVICE_ATTR(time_in_state, S_IRUGO|S_IWUSR, show_time_in_state, set_time_in_state); -MODULE_PARM_DESC(time_in_state, "Time-in-state of Mali DVFS"); -#endif -MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock"); -MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage"); -MODULE_PARM_DESC(mali_freq_table, "Mali frequency table"); - -#ifdef CONFIG_REGULATOR -struct regulator *g3d_regulator = NULL; -#endif -atomic_t mali_cpufreq_lock; - -/* DVFS */ -#ifdef CONFIG_MALI_DVFS -static unsigned int mali_dvfs_utilization = 255; -static void update_time_in_state(int level); -u64 mali_dvfs_time[MALI_DVFS_STEPS]; -#endif - -static void mali_dvfs_work_handler(struct work_struct *w); -static struct workqueue_struct *mali_dvfs_wq = 0; -_mali_osk_mutex_t *mali_dvfs_lock; -int mali_runtime_resumed = -1; -static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler); - -int cpufreq_lock_by_mali(unsigned int freq) -{ -#ifdef CONFIG_EXYNOS4_CPUFREQ - unsigned int level; - - if (atomic_read(&mali_cpufreq_lock) == 0) { - if (exynos_cpufreq_get_level(freq * 1000, &level)) { - printk(KERN_ERR "Mali: failed to get cpufreq level for %dMHz", freq); - return -EINVAL; - } - - if (exynos_cpufreq_lock(DVFS_LOCK_ID_G3D, level)) { - printk(KERN_ERR "Mali: failed to cpufreq lock for L%d", level); - return -EINVAL; - } - - atomic_set(&mali_cpufreq_lock, 1); - printk(KERN_DEBUG "Mali: cpufreq locked on <%d>%dMHz\n", level, freq); - } -#endif - return 0; -} - -void cpufreq_unlock_by_mali(void) -{ -#ifdef CONFIG_EXYNOS4_CPUFREQ - if (atomic_read(&mali_cpufreq_lock) == 1) { - exynos_cpufreq_lock_free(DVFS_LOCK_ID_G3D); - atomic_set(&mali_cpufreq_lock, 0); - printk(KERN_DEBUG "Mali: cpufreq locked off\n"); - } -#endif -} - -#ifdef CONFIG_REGULATOR -void mali_regulator_disable(void) -{ - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n")); - return; - } - regulator_disable(g3d_regulator); -} - -void mali_regulator_enable(void) -{ - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n")); - return; - } - regulator_enable(g3d_regulator); -} - -void mali_regulator_set_voltage(int min_uV, int max_uV) -{ - _mali_osk_mutex_wait(mali_dvfs_lock); - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); - _mali_osk_mutex_signal(mali_dvfs_lock); - return; - } - MALI_DEBUG_PRINT(1, ("= regulator_set_voltage: %d, %d \n", min_uV, max_uV)); - regulator_set_voltage(g3d_regulator, min_uV, max_uV); - mali_gpu_vol = regulator_get_voltage(g3d_regulator); - MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol)); - _mali_osk_mutex_signal(mali_dvfs_lock); -} -#endif - -#ifdef CONFIG_MALI_DVFS -static unsigned int get_mali_dvfs_status(void) -{ - return maliDvfsStatus.currentStep; -} -#endif - -mali_bool mali_clk_get(void) -{ - if (ext_xtal_clock == NULL) { - ext_xtal_clock = clk_get(NULL, EXTXTALCLK_NAME); - if (IS_ERR(ext_xtal_clock)) { - MALI_PRINT(("MALI Error : failed to get source ext_xtal_clock\n")); - return MALI_FALSE; - } - } - - if (vpll_src_clock == NULL) { - vpll_src_clock = clk_get(NULL, VPLLSRCCLK_NAME); - if (IS_ERR(vpll_src_clock)) { - MALI_PRINT(("MALI Error : failed to get source vpll_src_clock\n")); - return MALI_FALSE; - } - } - - if (fout_vpll_clock == NULL) { - fout_vpll_clock = clk_get(NULL, FOUTVPLLCLK_NAME); - if (IS_ERR(fout_vpll_clock)) { - MALI_PRINT(("MALI Error : failed to get source fout_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (sclk_epll_clock == NULL) { - sclk_epll_clock = clk_get(NULL, SCLKEPLLCLK_NAME); - if (IS_ERR(sclk_epll_clock)) { - MALI_PRINT(("MALI Error : failed to get source sclk_epll_clock\n")); - return MALI_FALSE; - } - } - - if (sclk_vpll_clock == NULL) { - sclk_vpll_clock = clk_get(NULL, SCLVPLLCLK_NAME); - if (IS_ERR(sclk_vpll_clock)) { - MALI_PRINT(("MALI Error : failed to get source sclk_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (mali_parent_clock == NULL) { - mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME); - if (IS_ERR(mali_parent_clock)) { - MALI_PRINT(("MALI Error : failed to get source mali parent clock\n")); - return MALI_FALSE; - } - } - - /* mali clock get always. */ - if (mali_clock == NULL) { - mali_clock = clk_get(NULL, GPUCLK_NAME); - if (IS_ERR(mali_clock)) { - MALI_PRINT(("MALI Error : failed to get source mali clock\n")); - return MALI_FALSE; - } - } - - return MALI_TRUE; -} - -void mali_clk_put(mali_bool binc_mali_clock) -{ - if (mali_parent_clock) - { - clk_put(mali_parent_clock); - mali_parent_clock = NULL; - } - - if (sclk_vpll_clock) - { - clk_put(sclk_vpll_clock); - sclk_vpll_clock = NULL; - } - - if (binc_mali_clock && fout_vpll_clock) - { - clk_put(fout_vpll_clock); - fout_vpll_clock = NULL; - } - - if (sclk_epll_clock) - { - clk_put(sclk_epll_clock); - sclk_epll_clock = NULL; - } - - if (vpll_src_clock) - { - clk_put(vpll_src_clock); - vpll_src_clock = NULL; - } - - if (ext_xtal_clock) - { - clk_put(ext_xtal_clock); - ext_xtal_clock = NULL; - } - - if (binc_mali_clock && mali_clock) - { - clk_put(mali_clock); - mali_clock = NULL; - } -} - -void mali_clk_set_rate(unsigned int clk, unsigned int mhz) -{ - int err; - unsigned int read_val; - unsigned long rate = (unsigned long)clk * (unsigned long)mhz; - unsigned long CurRate = 0; - - _mali_osk_mutex_wait(mali_dvfs_lock); - MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk)); - - if (mali_clk_get() == MALI_FALSE) { - _mali_osk_mutex_signal(mali_dvfs_lock); - return; - } - - CurRate = clk_get_rate(mali_clock); - - if (CurRate == 0) { - _mali_osk_mutex_signal(mali_dvfs_lock); - MALI_PRINT_ERROR(("clk_get_rate[mali_clock] is 0 - return\n")); - return; - } - - err = clk_set_rate(mali_clock, CurRate / 4); - - if (err > 0) - MALI_PRINT_ERROR(("Failed to set Mali clock before change PLL: %d\n", err)); - - err = clk_set_parent(mali_parent_clock, sclk_epll_clock); - - if (err) - MALI_PRINT_ERROR(("mali_parent set parent to sclk_epll failed\n")); - - do { - cpu_relax(); - read_val = __raw_readl(EXYNOS4415_CLKMUX_STAT_G3D0); - } while (((read_val >> 4) & 0x7) != 0x1); - - MALI_DEBUG_PRINT(3, ("Mali platform: set to EPLL EXYNOS4415_CLKMUX_STAT_G3D0: 0x%08x\n", __raw_readl(EXYNOS4415_CLKMUX_STAT_G3D0))); - - err = clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ); - - if (err > 0) - MALI_PRINT_ERROR(("Failed to set fout_vpll clock: %d\n", err)); - - - err = clk_set_parent(vpll_src_clock, ext_xtal_clock); - - if (err) - MALI_PRINT_ERROR(("vpll_src set parent to ext_xtal failed\n")); - - err = clk_set_parent(sclk_vpll_clock, fout_vpll_clock); - - if (err) - MALI_PRINT_ERROR(("sclk_vpll set parent to fout_vpll failed\n")); - - MALI_DEBUG_PRINT(3, ("Mali platform: set_parent_vpll : %8.x \n", (__raw_readl(EXYNOS4_CLKSRC_TOP0) >> 8) & 0x1)); - - err = clk_set_parent(mali_parent_clock, sclk_vpll_clock); - - if (err) - MALI_PRINT_ERROR(("mali_parent set parent to sclk_vpll failed\n")); - - do { - cpu_relax(); - read_val = __raw_readl(EXYNOS4415_CLKMUX_STAT_G3D0); - } while (((read_val >> 4) & 0x7) != 0x2); - - MALI_DEBUG_PRINT(3, ("SET to VPLL EXYNOS4_CLKMUX_STAT_G3D0 : 0x%08x\n", __raw_readl(EXYNOS4415_CLKMUX_STAT_G3D0))); - - err = clk_set_parent(mali_clock, mali_parent_clock); - - if (err) - MALI_PRINT_ERROR(("mali_clock set parent to mali_parent failed\n")); - - if (atomic_read(&clk_active) == 0) { - if (clk_enable(mali_clock) < 0) { - _mali_osk_mutex_signal(mali_dvfs_lock); - return; - } - atomic_set(&clk_active, 1); - } - - err = clk_set_rate(mali_clock, rate); - - if (err > 0) - MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err)); - - rate = clk_get_rate(mali_clock); - - MALI_DEBUG_PRINT(1, ("Mali frequency %d\n", rate / mhz)); - GPU_MHZ = mhz; - - mali_gpu_clk = (int)(rate / mhz); - mali_clk_put(MALI_FALSE); - - _mali_osk_mutex_signal(mali_dvfs_lock); -} - -#ifdef CONFIG_MALI_DVFS -mali_bool set_mali_dvfs_current_step(unsigned int step) -{ - _mali_osk_mutex_wait(mali_dvfs_lock); - maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS; - _mali_osk_mutex_signal(mali_dvfs_lock); - return MALI_TRUE; -} - -static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) -{ - u32 validatedStep = step; -#if MALI_DVFS_CLK_DEBUG - unsigned int *pRegMaliClkDiv; - unsigned int *pRegMaliMpll; -#endif - - if(boostup) { -#ifdef CONFIG_REGULATOR - /*change the voltage*/ -#ifdef EXYNOS4_ASV_ENABLED - mali_regulator_set_voltage(get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT), get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); -#else - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif -#endif - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); - } else { - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); -#ifdef CONFIG_REGULATOR -#ifdef EXYNOS4_ASV_ENABLED - /*change the voltage*/ - mali_regulator_set_voltage(get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT), get_match_volt(ID_G3D, mali_dvfs[step].clock * GPU_ASV_VOLT)); -#else - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif -#endif - } - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| - MALI_PROFILING_EVENT_CHANNEL_GPU| - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - mali_clk_put(MALI_FALSE); - -#if MALI_DVFS_CLK_DEBUG - pRegMaliClkDiv = ioremap(0x1003c52c, 32); - pRegMaliMpll = ioremap(0x1003c22c, 32); - MALI_PRINT(("Mali MPLL reg:%d, CLK DIV: %d \n", *pRegMaliMpll, *pRegMaliClkDiv)); -#endif - set_mali_dvfs_current_step(validatedStep); - /*for future use*/ - maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep]; - -#if CPUFREQ_LOCK_DURING_440 - /* lock/unlock CPU freq by Mali */ - if (mali_dvfs[step].clock >= 440) - cpufreq_lock_by_mali(400); - else - cpufreq_unlock_by_mali(); -#endif - return MALI_TRUE; -} - -static void mali_platform_wating(u32 msec) -{ - /* - * sample wating - * change this in the future with proper check routine. - */ - unsigned int read_val; - while(1) { - read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00); - if ((read_val & 0x8000)==0x0000) break; - - _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */ - } -} - -static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup ) -{ - MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n", step, boostup)); - - if (!set_mali_dvfs_status(step, boostup)) { - MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup)); - return MALI_FALSE; - } - - /* wait until clock and voltage is stablized */ - mali_platform_wating(MALI_DVFS_WATING); /* msec */ - return MALI_TRUE; -} - -static unsigned int decideNextStatus(unsigned int utilization) -{ - static unsigned int level = 0; - int iStepCount = 0; - - if (mali_runtime_resumed >= 0) { - level = mali_runtime_resumed; - mali_runtime_resumed = -1; - } - - if (mali_dvfs_control == 0) { - if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) && - level < MALI_DVFS_STEPS - 1) { - level++; - } else if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) && - level > 0) { - level--; - } - } else { - for (iStepCount = MALI_DVFS_STEPS-1; iStepCount >= 0; iStepCount--) { - if (mali_dvfs_control >= mali_dvfs[iStepCount].clock) { - level = iStepCount; - break; - } - } - } - return level; -} - -static mali_bool mali_dvfs_status(unsigned int utilization) -{ - unsigned int nextStatus = 0; - unsigned int curStatus = 0; - mali_bool boostup = MALI_FALSE; - static int stay_count = 5; - - MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n", utilization)); - - /* decide next step */ - curStatus = get_mali_dvfs_status(); - nextStatus = decideNextStatus(utilization); - - MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); - /* if next status is same with current status, don't change anything */ - if(curStatus != nextStatus) { - /*check if boost up or not*/ - if(maliDvfsStatus.currentStep < nextStatus) { - boostup = 1; - stay_count = 5; - } else if (maliDvfsStatus.currentStep > nextStatus){ - stay_count--; - } - - if( boostup == 1 || stay_count <= 0){ - /*change mali dvfs status*/ - update_time_in_state(curStatus); - if (!change_mali_dvfs_status(nextStatus, boostup)) { - MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); - return MALI_FALSE; - } - boostup = 0; - stay_count = 5; - } - } - else - stay_count = 5; - - return MALI_TRUE; -} -#endif - -static void mali_dvfs_work_handler(struct work_struct *w) -{ - bMaliDvfsRun = 1; - MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); - -#ifdef CONFIG_MALI_DVFS - if(!mali_dvfs_status(mali_dvfs_utilization)) - MALI_DEBUG_PRINT(1, ( "error on mali dvfs status in mali_dvfs_work_handler")); -#endif - - bMaliDvfsRun = 0; -} - -mali_bool init_mali_dvfs_status(void) -{ - /* - * default status - * add here with the right function to get initilization value. - */ - if (!mali_dvfs_wq) - mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs"); - - /* add a error handling here */ - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; - - return MALI_TRUE; -} - -void deinit_mali_dvfs_status(void) -{ - if (mali_dvfs_wq) - destroy_workqueue(mali_dvfs_wq); - - mali_dvfs_wq = NULL; -} - -#ifdef CONFIG_MALI_DVFS -mali_bool mali_dvfs_handler(unsigned int utilization) -{ - mali_dvfs_utilization = utilization; - queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work); - - return MALI_TRUE; -} -#endif - -static mali_bool init_mali_clock(void) -{ - mali_bool ret = MALI_TRUE; - nPowermode = MALI_POWER_MODE_DEEP_SLEEP; - - if (mali_clock != 0) - return ret; /* already initialized */ - - mali_dvfs_lock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED, 0); - - if (mali_dvfs_lock == NULL) - return _MALI_OSK_ERR_FAULT; - - if (!mali_clk_get()) - { - MALI_PRINT(("Error: Failed to get Mali clock\n")); - goto err_clk; - } - - mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); - - MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock)); - -#ifdef CONFIG_REGULATOR - g3d_regulator = regulator_get(NULL, "vdd_g3d"); - - if (IS_ERR(g3d_regulator)) - { - MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n")); - ret = MALI_FALSE; - goto err_regulator; - } - - mali_gpu_vol = mali_runtime_resume.vol; -#ifdef EXYNOS4_ASV_ENABLED - mali_gpu_vol = get_match_volt(ID_G3D, mali_gpu_clk * GPU_ASV_VOLT); - mali_runtime_resume.vol = get_match_volt(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT); -#endif - - regulator_enable(g3d_regulator); - mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); - -#endif - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| - MALI_PROFILING_EVENT_CHANNEL_GPU| - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - mali_clk_put(MALI_FALSE); - - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR -err_regulator: - regulator_put(g3d_regulator); -#endif -err_clk: - mali_clk_put(MALI_TRUE); - - return ret; -} - -static mali_bool deinit_mali_clock(void) -{ - if (mali_clock == 0) - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR - if (g3d_regulator) - { - regulator_put(g3d_regulator); - g3d_regulator = NULL; - } -#endif - mali_clk_put(MALI_TRUE); - - return MALI_TRUE; -} - -static _mali_osk_errcode_t enable_mali_clocks(void) -{ - int err; - - if (atomic_read(&clk_active) == 0) { - err = clk_enable(mali_clock); - MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err)); - atomic_set(&clk_active, 1); - } - - /* set clock rate */ -#ifdef CONFIG_MALI_DVFS - if (mali_dvfs_control != 0 || mali_gpu_clk >= mali_runtime_resume.clk) { - mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); - } else { -#ifdef CONFIG_REGULATOR - mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol); -#endif - mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ); - set_mali_dvfs_current_step(mali_runtime_resume.step); - } -#else - mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; -#endif - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t disable_mali_clocks(void) -{ - if (atomic_read(&clk_active)) { - clk_disable(mali_clock); - MALI_DEBUG_PRINT(3, ("disable_mali_clocks mali_clock %p\n", mali_clock)); - atomic_set(&clk_active, 0); - } - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_init(struct device *dev) -{ - atomic_set(&clk_active, 0); - MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT); - -#ifdef CONFIG_MALI_DVFS - if (!clk_register_map) - clk_register_map = _mali_osk_mem_mapioregion(CLK_DIV_STAT_G3D, 0x20, CLK_DESC); - - if (!init_mali_dvfs_status()) - MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n")); - - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; -#endif - mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON); - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_deinit(struct device *dev) -{ - mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP); - deinit_mali_clock(); - -#ifdef CONFIG_MALI_DVFS - deinit_mali_dvfs_status(); - if (clk_register_map) - { - _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map); - clk_register_map = NULL; - } -#endif - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode) -{ - switch (power_mode) - { - case MALI_POWER_MODE_ON: - MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n", - nPowermode ? "powering on" : "already on")); - if (nPowermode == MALI_POWER_MODE_LIGHT_SLEEP || nPowermode == MALI_POWER_MODE_DEEP_SLEEP) { - MALI_DEBUG_PRINT(4, ("enable clock\n")); - enable_mali_clocks(); - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - nPowermode = power_mode; - } - break; - case MALI_POWER_MODE_DEEP_SLEEP: - case MALI_POWER_MODE_LIGHT_SLEEP: - MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode == MALI_POWER_MODE_LIGHT_SLEEP ? - "MALI_POWER_MODE_LIGHT_SLEEP" : "MALI_POWER_MODE_DEEP_SLEEP", - nPowermode ? "already off" : "powering off")); - if (nPowermode == MALI_POWER_MODE_ON) { - disable_mali_clocks(); - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - 0, 0, 0, 0, 0); -#endif - nPowermode = power_mode; - } - break; - } - MALI_SUCCESS; -} - -void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data) -{ - if (nPowermode == MALI_POWER_MODE_ON) - { -#ifdef CONFIG_MALI_DVFS - if(!mali_dvfs_handler(data->utilization_gpu)) - MALI_DEBUG_PRINT(1, ("error on mali dvfs status in utilization\n")); -#endif - } -} - -#ifdef CONFIG_MALI_DVFS -static void update_time_in_state(int level) -{ - u64 current_time; - static u64 prev_time = 0; - - if (prev_time == 0) - prev_time = get_jiffies_64(); - - current_time = get_jiffies_64(); - mali_dvfs_time[level] += current_time - prev_time; - prev_time = current_time; -} - -ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf) -{ - ssize_t ret = 0; - int i; - - update_time_in_state(maliDvfsStatus.currentStep); - - for (i = 0; i < MALI_DVFS_STEPS; i++) { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d %llu\n", - mali_dvfs[i].clock, - mali_dvfs_time[i]); - } - - if (ret < PAGE_SIZE - 1) { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - } else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - return ret; -} - -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - int i; - - for (i = 0; i < MALI_DVFS_STEPS; i++) { - mali_dvfs_time[i] = 0; - } - return count; -} -#endif diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4_pmm.h b/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4_pmm.h deleted file mode 100644 index e0f3f6151d3..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/exynos4415/exynos4_pmm.h +++ /dev/null @@ -1,93 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/exynos4415/exynos4_pmm.h - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4_pmm.h - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ - -#ifndef __EXYNOS4_PMM_H__ -#define __EXYNOS4_PMM_H__ - -#include "mali_utgard.h" -#include "mali_osk.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @brief description of power change reasons - */ -typedef enum mali_power_mode_tag -{ - MALI_POWER_MODE_ON, - MALI_POWER_MODE_LIGHT_SLEEP, - MALI_POWER_MODE_DEEP_SLEEP, -} mali_power_mode; - -/** @brief Platform specific setup and initialisation of MALI - * - * This is called from the entrypoint of the driver to initialize the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_init(struct device *dev); - -/** @brief Platform specific deinitialisation of MALI - * - * This is called on the exit of the driver to terminate the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_deinit(struct device *dev); - -/** @brief Platform specific powerdown sequence of MALI - * - * Call as part of platform init if there is no PMM support, else the - * PMM will call it. - * There are three power modes defined: - * 1) MALI_POWER_MODE_ON - * 2) MALI_POWER_MODE_LIGHT_SLEEP - * 3) MALI_POWER_MODE_DEEP_SLEEP - * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle - * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions - * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued. - * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power - * off. - * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP - * mode. - * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during - * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from - * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well. - * @param power_mode defines the power modes - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode); - - -/** @brief Platform specific handling of GPU utilization data - * - * When GPU utilization data is enabled, this function will be - * periodically called. - * - * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. - */ -void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data); - -#ifdef CONFIG_MALI_DVFS -ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf); -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -#endif -#ifdef __cplusplus -} -#endif -#endif diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4.c deleted file mode 100644 index bf83249b4b2..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4.c +++ /dev/null @@ -1,405 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4.c - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4.c - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ -#include -#include -#include -#include - -#ifdef CONFIG_PM_RUNTIME -#include -#endif - -#ifdef CONFIG_MALI_DVFS -#include "mali_kernel_utilization.h" -#endif /* CONFIG_MALI_DVFS */ - -#include -#include "mali_kernel_common.h" -#include "mali_kernel_linux.h" -#include "mali_pm.h" - -#include - -#include "exynos4_pmm.h" - -#if defined(CONFIG_PM_RUNTIME) -/* We does not need PM NOTIFIER in r3p2 DDK */ -//#define USE_PM_NOTIFIER -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) -struct exynos_pm_domain; -extern struct exynos_pm_domain exynos4_pd_g3d; -void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) -extern struct platform_device exynos4_device_pd[]; -#else -extern struct platform_device s5pv310_device_pd[]; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */ - -static void mali_platform_device_release(struct device *device); - -#if defined(CONFIG_PM_RUNTIME) -#if defined(USE_PM_NOTIFIER) -static int mali_os_suspend(struct device *device); -static int mali_os_resume(struct device *device); -static int mali_os_freeze(struct device *device); -static int mali_os_thaw(struct device *device); - -static int mali_runtime_suspend(struct device *device); -static int mali_runtime_resume(struct device *device); -static int mali_runtime_idle(struct device *device); -#endif -#endif - -#if defined(CONFIG_ARCH_S5PV310) && !defined(CONFIG_BOARD_HKDKC210) - -/* This is for other SMDK boards */ -#define MALI_BASE_IRQ 232 - -#else - -/* This is for the Odroid boards */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) -#define MALI_BASE_IRQ 182 -#else -#define MALI_BASE_IRQ 150 -#endif - -#endif - -#define MALI_GP_IRQ MALI_BASE_IRQ + 9 -#define MALI_PP0_IRQ MALI_BASE_IRQ + 5 -#define MALI_PP1_IRQ MALI_BASE_IRQ + 6 -#define MALI_PP2_IRQ MALI_BASE_IRQ + 7 -#define MALI_PP3_IRQ MALI_BASE_IRQ + 8 -#define MALI_GP_MMU_IRQ MALI_BASE_IRQ + 4 -#define MALI_PP0_MMU_IRQ MALI_BASE_IRQ + 0 -#define MALI_PP1_MMU_IRQ MALI_BASE_IRQ + 1 -#define MALI_PP2_MMU_IRQ MALI_BASE_IRQ + 2 -#define MALI_PP3_MMU_IRQ MALI_BASE_IRQ + 3 - -static struct resource mali_gpu_resources[] = -{ - MALI_GPU_RESOURCES_MALI400_MP4(0x13000000, - MALI_GP_IRQ, MALI_GP_MMU_IRQ, - MALI_PP0_IRQ, MALI_PP0_MMU_IRQ, - MALI_PP1_IRQ, MALI_PP1_MMU_IRQ, - MALI_PP2_IRQ, MALI_PP2_MMU_IRQ, - MALI_PP3_IRQ, MALI_PP3_MMU_IRQ) -}; - -#ifdef CONFIG_PM_RUNTIME -#if defined(USE_PM_NOTIFIER) -static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy); - -static struct notifier_block mali_pwr_notif_block = { - .notifier_call = mali_pwr_suspend_notifier -}; -#endif -#endif /* CONFIG_PM_RUNTIME */ - -#if 0 -static struct dev_pm_ops mali_gpu_device_type_pm_ops = -{ -#ifndef CONFIG_PM_RUNTIME - .suspend = mali_os_suspend, - .resume = mali_os_resume, -#endif - .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 -}; -#endif - -#if defined(USE_PM_NOTIFIER) -static struct device_type mali_gpu_device_device_type = -{ - .pm = &mali_gpu_device_type_pm_ops, -}; -#endif - -static struct platform_device mali_gpu_device = -{ - .name = "mali_dev", /* MALI_SEC MALI_GPU_NAME_UTGARD, */ - .id = 0, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) - /* Set in mali_platform_device_register() for these kernels */ -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) - .dev.parent = &exynos4_device_pd[PD_G3D].dev, -#else - .dev.parent = &s5pv310_device_pd[PD_G3D].dev, -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */ - .dev.release = mali_platform_device_release, -#if 0 - /* - * We temporarily make use of a device type so that we can control the Mali power - * from within the mali.ko (since the default platform bus implementation will not do that). - * Ideally .dev.pm_domain should be used instead, as this is the new framework designed - * to control the power of devices. - */ - .dev.type = &mali_gpu_device_device_type, /* We should probably use the pm_domain instead of type on newer kernels */ -#endif -}; - -static struct mali_gpu_device_data mali_gpu_data = -{ - .shared_mem_size = 256 * 1024 * 1024, /* 256MB */ - .fb_start = 0x40000000, - .fb_size = 0xb1000000, - .utilization_interval = 100, /* 100ms */ - .utilization_callback = mali_gpu_utilization_handler, -}; - -int mali_platform_device_register(void) -{ - int err; - - MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n")); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) - exynos_pm_add_dev_to_genpd(&mali_gpu_device, &exynos4_pd_g3d); -#endif - - /* Connect resources to the device */ - err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0])); - if (0 == err) - { - err = platform_device_add_data(&mali_gpu_device, &mali_gpu_data, sizeof(mali_gpu_data)); - if (0 == err) - { -#ifdef CONFIG_PM_RUNTIME -#if defined(USE_PM_NOTIFIER) - err = register_pm_notifier(&mali_pwr_notif_block); - if (err) - { - goto plat_init_err; - } -#endif -#endif /* CONFIG_PM_RUNTIME */ - - /* Register the platform device */ - err = platform_device_register(&mali_gpu_device); - if (0 == err) - { - mali_platform_init(&(mali_gpu_device.dev)); - -#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 - - return 0; - } - } - -#ifdef CONFIG_PM_RUNTIME -#if defined(USE_PM_NOTIFIER) -plat_init_err: - unregister_pm_notifier(&mali_pwr_notif_block); -#endif -#endif /* CONFIG_PM_RUNTIME */ - platform_device_unregister(&mali_gpu_device); - } - - return err; -} - -void mali_platform_device_unregister(void) -{ - MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n")); - -#ifdef CONFIG_PM_RUNTIME -#if defined(USE_PM_NOTIFIER) - unregister_pm_notifier(&mali_pwr_notif_block); -#endif -#endif /* CONFIG_PM_RUNTIME */ - - mali_platform_deinit(&(mali_gpu_device.dev)); - - platform_device_unregister(&mali_gpu_device); -} - -static void mali_platform_device_release(struct device *device) -{ - MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n")); -} - -#ifdef CONFIG_PM_RUNTIME -#if defined(USE_PM_NOTIFIER) -static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy) -{ - int err = 0; - switch (event) - { - case PM_SUSPEND_PREPARE: - mali_pm_os_suspend(); - err = mali_os_suspend(&(mali_platform_device->dev)); - break; - - case PM_POST_SUSPEND: - err = mali_os_resume(&(mali_platform_device->dev)); - mali_pm_os_resume(); - break; - default: - break; - } - return err; -} - -static int mali_os_suspend(struct device *device) -{ - int ret = 0; - MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n")); - -#ifdef CONFIG_MALI_DVFS - mali_utilization_suspend(); -#endif - - if (NULL != device && - NULL != device->driver && - NULL != device->driver->pm && - NULL != device->driver->pm->suspend) - { - /* Need to notify Mali driver about this event */ - ret = device->driver->pm->suspend(device); - } - - mali_platform_power_mode_change(device, MALI_POWER_MODE_DEEP_SLEEP); - - return ret; -} - -static int mali_os_resume(struct device *device) -{ - int ret = 0; - - MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n")); -#ifdef CONFIG_REGULATOR - mali_regulator_enable(); - g3d_power_domain_control(1); -#endif - mali_platform_power_mode_change(device, MALI_POWER_MODE_ON); - - if (NULL != device && - NULL != device->driver && - NULL != device->driver->pm && - NULL != device->driver->pm->resume) - { - /* Need to notify Mali driver about this event */ - ret = device->driver->pm->resume(device); - } - - return ret; -} - -static int mali_os_freeze(struct device *device) -{ - int ret = 0; - MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n")); - - if (NULL != device->driver && - NULL != device->driver->pm && - NULL != device->driver->pm->freeze) - { - /* Need to notify Mali driver about this event */ - ret = device->driver->pm->freeze(device); - } - - return ret; -} - -static int mali_os_thaw(struct device *device) -{ - int ret = 0; - MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n")); - - if (NULL != device->driver && - NULL != device->driver->pm && - NULL != device->driver->pm->thaw) - { - /* Need to notify Mali driver about this event */ - ret = device->driver->pm->thaw(device); - } - - return ret; -} - -static int mali_runtime_suspend(struct device *device) -{ - int ret = 0; - - MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n")); - if (NULL != device->driver && - NULL != device->driver->pm && - NULL != device->driver->pm->runtime_suspend) - { - /* Need to notify Mali driver about this event */ - ret = device->driver->pm->runtime_suspend(device); - } - - mali_platform_power_mode_change(device, MALI_POWER_MODE_LIGHT_SLEEP); - - return ret; -} - -static int mali_runtime_resume(struct device *device) -{ - int ret = 0; - MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n")); - - mali_platform_power_mode_change(device, MALI_POWER_MODE_ON); - - if (NULL != device->driver && - NULL != device->driver->pm && - NULL != device->driver->pm->runtime_resume) - { - /* Need to notify Mali driver about this event */ - ret = device->driver->pm->runtime_resume(device); - } - - return ret; -} - -static int mali_runtime_idle(struct device *device) -{ - MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n")); - if (NULL != device->driver && - NULL != device->driver->pm && - NULL != device->driver->pm->runtime_idle) - { - int ret = 0; - /* Need to notify Mali driver about this event */ - ret = device->driver->pm->runtime_idle(device); - if (0 != ret) - { - return ret; - } - } - - return 1; -} - -#endif /* USE_PM_NOTIFIER */ -#endif /* CONFIG_PM_RUNTIME */ diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4_pmm.c b/drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4_pmm.c deleted file mode 100644 index accdb29337b..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4_pmm.c +++ /dev/null @@ -1,1298 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4_pmm.c - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4_pmm.c - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "exynos4_pmm.h" -#include -#include -#include -#include -#include - -#if defined(CONFIG_MALI400_PROFILING) -#include "mali_osk_profiling.h" -#endif - -#if defined(CONFIG_PM_RUNTIME) -#include -#endif - -#include -#include - -#include - -#define MALI_DVFS_STEPS 5 -#define MALI_DVFS_WATING 10 /* msec */ -#define MALI_DVFS_DEFAULT_STEP 1 -#define PD_G3D_LOCK_FLAG 2 - -#ifdef CONFIG_CPU_FREQ -#include -#define EXYNOS4_ASV_ENABLED -#endif - -#define MALI_DVFS_CLK_DEBUG 0 -#define SEC_THRESHOLD 1 - -#define CPUFREQ_LOCK_DURING_440 0 -#define CHIPID_REG (S5P_VA_CHIPID + 0x4) - -static int bMaliDvfsRun = 0; - -typedef struct mali_dvfs_tableTag{ - unsigned int clock; - unsigned int freq; - unsigned int vol; -#if SEC_THRESHOLD - unsigned int downthreshold; - unsigned int upthreshold; -#endif -}mali_dvfs_table; - -typedef struct mali_dvfs_statusTag{ - unsigned int currentStep; - mali_dvfs_table * pCurrentDvfs; - -} mali_dvfs_status_t; - -/* dvfs status */ -mali_dvfs_status_t maliDvfsStatus; -int mali_dvfs_control; - -typedef struct mali_runtime_resumeTag{ - int clk; - int vol; - unsigned int step; -}mali_runtime_resume_table; - -mali_runtime_resume_table mali_runtime_resume = {266, 900000, 1}; - -/* dvfs table */ -mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ -#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412) - /* step 0 */{160 ,1000000 ,875000 , 0 , 70}, - /* step 1 */{266 ,1000000 ,900000 ,62 , 90}, - /* step 2 */{350 ,1000000 ,950000 ,85 , 90}, - /* step 3 */{440 ,1000000 ,1025000 ,85 , 90}, - /* step 4 */{533 ,1000000 ,1075000 ,95 ,100} }; -#else - /* step 0 */{134 ,1000000 , 950000 ,85 , 90}, - /* step 1 */{267 ,1000000 ,1050000 ,85 ,100} }; -#endif - -#ifdef EXYNOS4_ASV_ENABLED -#define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */ -#define ASV_LEVEL_PRIME 13 /* ASV0, 1, 12 is reserved */ -#define ASV_LEVEL_PD 13 - - -static unsigned int asv_3d_volt_9_table_1ghz_type[MALI_DVFS_STEPS-1][ASV_LEVEL] = { - { 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 900000, 875000}, /* L3(160Mhz) */ -#if (MALI_DVFS_STEPS > 1) - { 1000000, 975000, 975000, 975000, 950000, 950000, 950000, 900000, 900000, 900000, 900000, 875000}, /* L2(266Mhz) */ -#if (MALI_DVFS_STEPS > 2) - { 1075000, 1050000, 1050000, 1050000, 1000000, 1000000, 1000000, 975000, 975000, 975000, 975000, 925000}, /* L1(350Mhz) */ -#if (MALI_DVFS_STEPS > 3) - { 1125000, 1100000, 1100000, 1100000, 1075000, 1075000, 1075000, 1025000, 1025000, 1025000, 1025000, 975000}, /* L0(440Mhz) */ -#endif -#endif -#endif -}; -static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS-1][ASV_LEVEL] = { - { 950000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */ -#if (MALI_DVFS_STEPS > 1) - { 975000, 950000, 925000, 925000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000}, /* L2(266Mhz) */ -#if (MALI_DVFS_STEPS > 2) - { 1050000, 1025000, 1000000, 1000000, 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000}, /* L1(350Mhz) */ -#if (MALI_DVFS_STEPS > 3) - { 1100000, 1075000, 1050000, 1050000, 1050000, 1025000, 1025000, 1000000, 1000000, 1000000, 975000, 950000}, /* L0(440Mhz) */ -#endif -#endif -#endif -}; - -static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL_PRIME] = { - { 950000, 937500, 925000, 912500, 900000, 887500, 875000, 862500, 875000, 862500, 850000, 850000, 850000}, /* L4(160Mhz) */ -#if (MALI_DVFS_STEPS > 1) - { 975000, 962500, 950000, 937500, 925000, 912500, 900000, 887500, 900000, 887500, 875000, 875000, 875000}, /* L3(266Mhz) */ -#if (MALI_DVFS_STEPS > 2) - { 1025000, 1012500, 1000000, 987500, 975000, 962500, 950000, 937500, 950000, 937500, 912500, 900000, 887500}, /* L2(350Mhz) */ -#if (MALI_DVFS_STEPS > 3) - { 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 975000, 962500, 950000}, /* L1(440Mhz) */ -#if (MALI_DVFS_STEPS > 4) - { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1075000, 1062500, 1037500, 1025000, 1012500}, /* L0(533Mhz) */ -#endif -#endif -#endif -#endif -}; - -static unsigned int asv_3d_volt_4212_9_table[MALI_DVFS_STEPS][ASV_LEVEL_PD] = { - { 950000, 925000, 900000, 900000, 900000, 900000, 900000, 900000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */ -#if (MALI_DVFS_STEPS > 1) - { 975000, 950000, 925000, 925000, 925000, 925000, 925000, 900000, 900000, 900000, 875000, 875000, 875000}, /* L2(266Mhz) */ -#if (MALI_DVFS_STEPS > 2) - { 1025000, 1000000, 975000, 975000, 975000, 950000, 950000, 925000, 925000, 925000, 925000, 900000, 875000}, /* L1(350Mhz) */ -#if (MALI_DVFS_STEPS > 3) - { 1100000, 1075000, 1050000, 1050000, 1050000, 1050000, 1025000, 1000000, 1000000, 975000, 975000, 950000, 925000}, /* L0(440Mhz) */ -#endif -#endif -#endif -}; -#endif /* ASV_LEVEL */ - -#define EXTXTALCLK_NAME "ext_xtal" -#define VPLLSRCCLK_NAME "vpll_src" -#define FOUTVPLLCLK_NAME "fout_vpll" -#define SCLVPLLCLK_NAME "sclk_vpll" -#define GPUMOUT1CLK_NAME "mout_g3d1" - -#define MPLLCLK_NAME "mout_mpll" -#define GPUMOUT0CLK_NAME "mout_g3d0" -#define GPUCLK_NAME "sclk_g3d" -#define CLK_DIV_STAT_G3D 0x1003C62C -#define CLK_DESC "clk-divider-status" - -static struct clk *ext_xtal_clock = NULL; -static struct clk *vpll_src_clock = NULL; -static struct clk *fout_vpll_clock = NULL; -static struct clk *sclk_vpll_clock = NULL; - -static struct clk *mpll_clock = NULL; -static struct clk *mali_parent_clock = NULL; -static struct clk *mali_mout0_clock = NULL; -static struct clk *mali_clock = NULL; - -#if defined(CONFIG_CPU_EXYNOS4412) || defined(CONFIG_CPU_EXYNOS4212) -/* Pegasus */ -static const mali_bool bis_vpll = MALI_TRUE; -int mali_gpu_clk = 440; -int mali_gpu_vol = 1025000; -#else -/* Orion */ -static const mali_bool bis_vpll = MALI_FALSE; -int mali_gpu_clk = 267; -int mali_gpu_vol = 1050000; -#endif - -static unsigned int GPU_MHZ = 1000000; - -int gpu_power_state; -static int bPoweroff; -atomic_t clk_active; - -#define MAX_MALI_DVFS_STEPS 5 -static _mali_osk_atomic_t bottomlock_status; -int bottom_lock_step = 0; - -#if MALI_VOLTAGE_LOCK -int mali_lock_vol = 0; -static _mali_osk_atomic_t voltage_lock_status; -static mali_bool mali_vol_lock_flag = 0; -#endif - -/* Declare for sysfs */ -#ifdef CONFIG_MALI_DVFS -module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS"); - -DEVICE_ATTR(time_in_state, S_IRUGO|S_IWUSR, show_time_in_state, set_time_in_state); -MODULE_PARM_DESC(time_in_state, "Time-in-state of Mali DVFS"); -#endif - -module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ -MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock"); - -module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ -MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage"); - -module_param(gpu_power_state, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ -MODULE_PARM_DESC(gpu_power_state, "Mali Power State"); - -#ifdef CONFIG_REGULATOR -struct regulator *g3d_regulator = NULL; -#endif - -mali_io_address clk_register_map = 0; - -/* DVFS */ -static unsigned int mali_dvfs_utilization = 255; -u64 mali_dvfs_time[MALI_DVFS_STEPS]; -#ifdef CONFIG_MALI_DVFS -static void update_time_in_state(int level); -#endif -static void mali_dvfs_work_handler(struct work_struct *w); -static struct workqueue_struct *mali_dvfs_wq = 0; -extern mali_io_address clk_register_map; -_mali_osk_lock_t *mali_dvfs_lock; -int mali_runtime_resumed = -1; -static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler); - -#ifdef CONFIG_REGULATOR -void mali_regulator_disable(void) -{ - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n")); - return; - } - regulator_disable(g3d_regulator); -} - -void mali_regulator_enable(void) -{ - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n")); - return; - } - regulator_enable(g3d_regulator); -} - -void mali_regulator_set_voltage(int min_uV, int max_uV) -{ - _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - if(IS_ERR_OR_NULL(g3d_regulator)) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - return; - } - MALI_PRINT(("= regulator_set_voltage: %d, %d \n",min_uV, max_uV)); - regulator_set_voltage(g3d_regulator, min_uV, max_uV); - mali_gpu_vol = regulator_get_voltage(g3d_regulator); - MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol)); - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); -} -#endif - -unsigned long mali_clk_get_rate(void) -{ - return clk_get_rate(mali_clock); -} - - -static unsigned int get_mali_dvfs_status(void) -{ - return maliDvfsStatus.currentStep; -} - -mali_bool mali_clk_get(void) -{ - if (bis_vpll) - { - if (ext_xtal_clock == NULL) - { - ext_xtal_clock = clk_get(NULL, EXTXTALCLK_NAME); - if (IS_ERR(ext_xtal_clock)) { - MALI_PRINT(("MALI Error : failed to get source ext_xtal_clock\n")); - return MALI_FALSE; - } - } - - if (vpll_src_clock == NULL) - { - vpll_src_clock = clk_get(NULL, VPLLSRCCLK_NAME); - if (IS_ERR(vpll_src_clock)) { - MALI_PRINT(("MALI Error : failed to get source vpll_src_clock\n")); - return MALI_FALSE; - } - } - - if (fout_vpll_clock == NULL) - { - fout_vpll_clock = clk_get(NULL, FOUTVPLLCLK_NAME); - if (IS_ERR(fout_vpll_clock)) { - MALI_PRINT(("MALI Error : failed to get source fout_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (sclk_vpll_clock == NULL) - { - sclk_vpll_clock = clk_get(NULL, SCLVPLLCLK_NAME); - if (IS_ERR(sclk_vpll_clock)) { - MALI_PRINT(("MALI Error : failed to get source sclk_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (mali_parent_clock == NULL) - { - mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME); - - if (IS_ERR(mali_parent_clock)) { - MALI_PRINT(( "MALI Error : failed to get source mali parent clock\n")); - return MALI_FALSE; - } - } - - if (mali_mout0_clock == NULL) - { - mali_mout0_clock = clk_get(NULL, GPUMOUT0CLK_NAME); - - if (IS_ERR(mali_mout0_clock)) { - MALI_PRINT( ( "MALI Error : failed to get source mali mout0 clock\n")); - return MALI_FALSE; - } - } - } - else /* mpll */ - { - if (mpll_clock == NULL) - { - mpll_clock = clk_get(NULL, MPLLCLK_NAME); - - if (IS_ERR(mpll_clock)) { - MALI_PRINT(("MALI Error : failed to get source mpll clock\n")); - return MALI_FALSE; - } - } - - if (mali_parent_clock == NULL) - { - mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME); - - if (IS_ERR(mali_parent_clock)) { - MALI_PRINT(( "MALI Error : failed to get source mali parent clock\n")); - return MALI_FALSE; - } - } - } - - /* mali clock get always. */ - if (mali_clock == NULL) - { - mali_clock = clk_get(NULL, GPUCLK_NAME); - - if (IS_ERR(mali_clock)) { - MALI_PRINT(("MALI Error : failed to get source mali clock\n")); - return MALI_FALSE; - } - } - - return MALI_TRUE; -} - -void mali_clk_put(mali_bool binc_mali_clock) -{ - if (mali_parent_clock) - { - clk_put(mali_parent_clock); - mali_parent_clock = NULL; - } - - if (mali_mout0_clock) - { - clk_put(mali_mout0_clock); - mali_mout0_clock = NULL; - } - - if (mpll_clock) - { - clk_put(mpll_clock); - mpll_clock = NULL; - } - - if (sclk_vpll_clock) - { - clk_put(sclk_vpll_clock); - sclk_vpll_clock = NULL; - } - - if (binc_mali_clock && fout_vpll_clock) - { - clk_put(fout_vpll_clock); - fout_vpll_clock = NULL; - } - - if (vpll_src_clock) - { - clk_put(vpll_src_clock); - vpll_src_clock = NULL; - } - - if (ext_xtal_clock) - { - clk_put(ext_xtal_clock); - ext_xtal_clock = NULL; - } - - if (binc_mali_clock && mali_clock) - { - clk_put(mali_clock); - mali_clock = NULL; - } -} - -void mali_clk_set_rate(unsigned int clk, unsigned int mhz) -{ - int err; - unsigned long rate = (unsigned long)clk * (unsigned long)mhz; - - _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk)); - - if (mali_clk_get() == MALI_FALSE) { - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - return; - } - - if (bis_vpll) - { - clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ); - clk_set_parent(vpll_src_clock, ext_xtal_clock); - clk_set_parent(sclk_vpll_clock, fout_vpll_clock); - - clk_set_parent(mali_parent_clock, sclk_vpll_clock); - clk_set_parent(mali_clock, mali_parent_clock); - } - else - { - clk_set_parent(mali_parent_clock, mpll_clock); - clk_set_parent(mali_clock, mali_parent_clock); - } - - if (atomic_read(&clk_active) == 0) { - if (clk_enable(mali_clock) < 0) { - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - return; - } - atomic_set(&clk_active, 1); - } - - err = clk_set_rate(mali_clock, rate); - if (err > 0) - MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err)); - - rate = mali_clk_get_rate(); - - MALI_PRINT(("Mali frequency %d\n", rate / mhz)); - GPU_MHZ = mhz; - mali_gpu_clk = (int)(rate / mhz); - - mali_clk_put(MALI_FALSE); - - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); -} - -int get_mali_dvfs_control_status(void) -{ - return mali_dvfs_control; -} - -mali_bool set_mali_dvfs_current_step(unsigned int step) -{ - _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS; - if (step >= MALI_DVFS_STEPS) - mali_runtime_resumed = maliDvfsStatus.currentStep; - - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - return MALI_TRUE; -} - - -static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) -{ - u32 validatedStep=step; -#if MALI_DVFS_CLK_DEBUG - unsigned int *pRegMaliClkDiv; - unsigned int *pRegMaliMpll; -#endif - - if(boostup) { -#ifdef CONFIG_REGULATOR - /* change the voltage */ - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif - /* change the clock */ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); - } else { - /* change the clock */ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); -#ifdef CONFIG_REGULATOR - /* change the voltage */ - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif - } - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| - MALI_PROFILING_EVENT_CHANNEL_GPU| - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - mali_clk_put(MALI_FALSE); - -#if MALI_DVFS_CLK_DEBUG - pRegMaliClkDiv = ioremap(0x1003c52c,32); - pRegMaliMpll = ioremap(0x1003c22c,32); - MALI_PRINT(("Mali MPLL reg:%d, CLK DIV: %d \n",*pRegMaliMpll, *pRegMaliClkDiv)); -#endif - -#ifdef EXYNOS4_ASV_ENABLED - if (samsung_rev() < EXYNOS4412_REV_2_0) { - if (mali_dvfs[step].clock == 160) - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V); - else - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V); - } -#endif - - set_mali_dvfs_current_step(validatedStep); - /* for future use */ - maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep]; - -#if CPUFREQ_LOCK_DURING_440 - /* lock/unlock CPU freq by Mali */ - if (mali_dvfs[step].clock >= 440) - err = cpufreq_lock_by_mali(400); - else - cpufreq_unlock_by_mali(); -#endif - - - return MALI_TRUE; -} - -static void mali_platform_wating(u32 msec) -{ - /* - * sample wating - * change this in the future with proper check routine. - */ - unsigned int read_val; - while(1) { - read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00); - if ((read_val & 0x8000)==0x0000) break; - - _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */ - } -} - -static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup ) -{ - MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n",step, boostup)); - - if (!set_mali_dvfs_status(step, boostup)) { - MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup)); - return MALI_FALSE; - } - - /* wait until clock and voltage is stablized */ - mali_platform_wating(MALI_DVFS_WATING); /* msec */ - - return MALI_TRUE; -} - -#ifdef EXYNOS4_ASV_ENABLED -extern unsigned int exynos_result_of_asv; - -static mali_bool mali_dvfs_table_update(void) -{ - unsigned int i, tmp, g3d_lock_volt = 0; - unsigned int step_num = MALI_DVFS_STEPS; - bool lock_flag_g3d = false; - - if(samsung_rev() < EXYNOS4412_REV_2_0) - step_num = MALI_DVFS_STEPS - 1; - - if(soc_is_exynos4412()) { - if (exynos_armclk_max == 1000000) { - MALI_PRINT(("::C::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - for (i = 0; i < step_num; i++) { - mali_dvfs[i].vol = asv_3d_volt_9_table_1ghz_type[i][exynos_result_of_asv]; - MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol)); - - // Update voltage using for resume - if (mali_runtime_resume.clk == mali_dvfs[i].clock) { - mali_runtime_resume.vol = mali_dvfs[i].vol; - - MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol)); - } - - // update voltage using for init timing - if (mali_gpu_clk == mali_dvfs[i].clock) { - mali_gpu_vol = mali_dvfs[i].vol; - - MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol)); - } - } - } else if(((is_special_flag() >> G3D_LOCK_FLAG) & 0x1) && (samsung_rev() >= EXYNOS4412_REV_2_0)) { - MALI_PRINT(("::L::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - for (i = 0; i < step_num; i++) { - mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv] + 25000; - MALI_PRINT(("mali_dvfs[%d].vol = %d \n ", i, mali_dvfs[i].vol)); - - // Update voltage using for resume - if (mali_runtime_resume.clk == mali_dvfs[i].clock) { - mali_runtime_resume.vol = mali_dvfs[i].vol; - - MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol)); - } - - // update voltage using for init timing - if (mali_gpu_clk == mali_dvfs[i].clock) { - mali_gpu_vol = mali_dvfs[i].vol; - - MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol)); - } - } - } else if (samsung_rev() >= EXYNOS4412_REV_2_0) { - MALI_PRINT(("::P::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - for (i = 0; i < step_num; i++) { - mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv]; - MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol)); - - // Update voltage using for resume - if (mali_runtime_resume.clk == mali_dvfs[i].clock) { - mali_runtime_resume.vol = mali_dvfs[i].vol; - - MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol)); - } - - // update voltage using for init timing - if (mali_gpu_clk == mali_dvfs[i].clock) { - mali_gpu_vol = mali_dvfs[i].vol; - - MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol)); - } - } - } else { - MALI_PRINT(("::Q::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - for (i = 0; i < step_num; i++) { - mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv]; - MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol)); - - // Update voltage using for resume - if (mali_runtime_resume.clk == mali_dvfs[i].clock) { - mali_runtime_resume.vol = mali_dvfs[i].vol; - - MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol)); - } - - // update voltage using for init timing - if (mali_gpu_clk == mali_dvfs[i].clock) { - mali_gpu_vol = mali_dvfs[i].vol; - - MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol)); - } - } - } - } - else if(soc_is_exynos4212()) { - tmp = __raw_readl(CHIPID_REG); - lock_flag_g3d = (tmp >> PD_G3D_LOCK_FLAG) & 0x1; - if (lock_flag_g3d) - g3d_lock_volt = 25000; - - for (i = 0; i < step_num; i++) { - MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - mali_dvfs[i].vol = asv_3d_volt_4212_9_table[i][exynos_result_of_asv] + g3d_lock_volt; - MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); - - // Update voltage using for resume - if (mali_runtime_resume.clk == mali_dvfs[i].clock) { - mali_runtime_resume.vol = mali_dvfs[i].vol; - - MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol)); - } - - // update voltage using for init timing - if (mali_gpu_clk == mali_dvfs[i].clock) { - mali_gpu_vol = mali_dvfs[i].vol; - - MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol)); - } - } - } - - return MALI_TRUE; -} -#endif - -static unsigned int decideNextStatus(unsigned int utilization) -{ - static unsigned int level = 0; - int iStepCount = 0; - if (mali_runtime_resumed >= 0) { - level = mali_runtime_resumed; - mali_runtime_resumed = -1; - } - - if (mali_dvfs_control == 0 && level == get_mali_dvfs_status()) { - if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) && - level < MALI_DVFS_STEPS - 1) { - level++; - if ((samsung_rev() < EXYNOS4412_REV_2_0) && 3 == get_mali_dvfs_status()) { - level=get_mali_dvfs_status(); - } - } - else if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) && - level > 0) { - level--; - } - - if (_mali_osk_atomic_read(&bottomlock_status) > 0) { - if (level < bottom_lock_step) - level = bottom_lock_step; - } - } else { - for (iStepCount = MALI_DVFS_STEPS-1; iStepCount >= 0; iStepCount--) { - if ( mali_dvfs_control >= mali_dvfs[iStepCount].clock ) { - level = iStepCount; - break; - } - } - } - - return level; -} - - -static mali_bool mali_dvfs_status(unsigned int utilization) -{ - unsigned int nextStatus = 0; - unsigned int curStatus = 0; - mali_bool boostup = MALI_FALSE; - static int stay_count = 5; - - MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n",utilization)); - - /* decide next step */ - curStatus = get_mali_dvfs_status(); - nextStatus = decideNextStatus(utilization); - - MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); - /* if next status is same with current status, don't change anything */ - if(curStatus != nextStatus) { - /*check if boost up or not*/ - if(maliDvfsStatus.currentStep < nextStatus) { - boostup = 1; - stay_count = 5; - } else if (maliDvfsStatus.currentStep > nextStatus){ - stay_count--; - } - if( boostup == 1 || stay_count <= 0){ - /*change mali dvfs status*/ -#ifdef CONFIG_MALI_DVFS - update_time_in_state(curStatus); -#endif - if (!change_mali_dvfs_status(nextStatus,boostup)) { - MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); - return MALI_FALSE; - } - boostup = 0; - stay_count = 5; - } - } - else - stay_count = 5; - return MALI_TRUE; -} - - -int mali_dvfs_is_running(void) -{ - return bMaliDvfsRun; -} - - -static void mali_dvfs_work_handler(struct work_struct *w) -{ - bMaliDvfsRun=1; - - MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); - - if(!mali_dvfs_status(mali_dvfs_utilization)) - MALI_DEBUG_PRINT(1, ( "error on mali dvfs status in mali_dvfs_work_handler")); - - bMaliDvfsRun=0; -} - -mali_bool init_mali_dvfs_status(void) -{ - /* - * default status - * add here with the right function to get initilization value. - */ - - if (!mali_dvfs_wq) - mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs"); - - _mali_osk_atomic_init(&bottomlock_status, 0); - - /* add a error handling here */ - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; - - return MALI_TRUE; -} - -void deinit_mali_dvfs_status(void) -{ - if (mali_dvfs_wq) - destroy_workqueue(mali_dvfs_wq); - - _mali_osk_atomic_term(&bottomlock_status); - - mali_dvfs_wq = NULL; -} - -mali_bool mali_dvfs_handler(unsigned int utilization) -{ - mali_dvfs_utilization = utilization; - queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work); - - return MALI_TRUE; -} - -static mali_bool init_mali_clock(void) -{ - mali_bool ret = MALI_TRUE; - gpu_power_state = 1; - bPoweroff = 1; - - if (mali_clock != 0) - return ret; /* already initialized */ - - mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE - | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0); - if (mali_dvfs_lock == NULL) - return _MALI_OSK_ERR_FAULT; - - if (!mali_clk_get()) - { - MALI_PRINT(("Error: Failed to get Mali clock\n")); - goto err_clk; - } - - mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); - - MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock)); - -#ifdef CONFIG_REGULATOR - g3d_regulator = regulator_get(NULL, "vdd_g3d"); - - if (IS_ERR(g3d_regulator)) - { - MALI_PRINT(("MALI Error : failed to get vdd_g3d\n")); - ret = MALI_FALSE; - goto err_regulator; - } - - regulator_enable(g3d_regulator); - mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); - -#ifdef EXYNOS4_ASV_ENABLED - if (samsung_rev() < EXYNOS4412_REV_2_0) { - if (mali_gpu_clk == 160) - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V); - else - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V); - } -#endif -#endif - -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| - MALI_PROFILING_EVENT_CHANNEL_GPU| - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - - mali_clk_put(MALI_FALSE); - - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR -err_regulator: - regulator_put(g3d_regulator); -#endif -err_clk: - mali_clk_put(MALI_TRUE); - - return ret; -} - -static mali_bool deinit_mali_clock(void) -{ - if (mali_clock == 0) - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR - if (g3d_regulator) - { - regulator_put(g3d_regulator); - g3d_regulator = NULL; - } -#endif - - mali_clk_put(MALI_TRUE); - - return MALI_TRUE; -} - - -static _mali_osk_errcode_t enable_mali_clocks(void) -{ - int err; - - if (atomic_read(&clk_active) == 0) { - err = clk_enable(mali_clock); - MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err)); - atomic_set(&clk_active, 1); - gpu_power_state = 1; - } - - /* set clock rate */ -#ifdef CONFIG_MALI_DVFS - if (get_mali_dvfs_control_status() != 0 || mali_gpu_clk >= mali_runtime_resume.clk) { - mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); - } else { -#ifdef CONFIG_REGULATOR - mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol); - -#ifdef EXYNOS4_ASV_ENABLED - if (samsung_rev() < EXYNOS4412_REV_2_0) { - if (mali_runtime_resume.clk == 160) - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V); - else - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V); - } -#endif -#endif - mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ); - set_mali_dvfs_current_step(mali_runtime_resume.step); - } -#else - mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); - maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP; -#endif - - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t disable_mali_clocks(void) -{ - if (atomic_read(&clk_active) == 1) { - clk_disable(mali_clock); - atomic_set(&clk_active, 0); - gpu_power_state = 0; - } - MALI_DEBUG_PRINT(3, ("disable_mali_clocks mali_clock %p \n", mali_clock)); - - MALI_SUCCESS; -} - -/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */ -#ifndef S5P_G3D_CONFIGURATION -#define S5P_G3D_CONFIGURATION S5P_PMU_G3D_CONF -#endif -#ifndef S5P_G3D_STATUS -#define S5P_G3D_STATUS S5P_PMU_G3D_CONF + 0x4 -#endif - -_mali_osk_errcode_t g3d_power_domain_control(int bpower_on) -{ - if (bpower_on) - { - void __iomem *status; - u32 timeout; - __raw_writel(S5P_INT_LOCAL_PWR_EN, S5P_G3D_CONFIGURATION); - status = S5P_G3D_STATUS; - - timeout = 10; - while ((__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) - != S5P_INT_LOCAL_PWR_EN) { - if (timeout == 0) { - MALI_PRINTF(("Power domain enable failed.\n")); - return -ETIMEDOUT; - } - timeout--; - _mali_osk_time_ubusydelay(100); - } - } - else - { - void __iomem *status; - u32 timeout; - __raw_writel(0, S5P_G3D_CONFIGURATION); - - status = S5P_G3D_STATUS; - /* Wait max 1ms */ - timeout = 10; - while (__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) - { - if (timeout == 0) { - MALI_PRINTF(("Power domain disable failed.\n" )); - return -ETIMEDOUT; - } - timeout--; - _mali_osk_time_ubusydelay(100); - } - } - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_init(struct device *dev) -{ -#ifdef EXYNOS4_ASV_ENABLED - mali_dvfs_table_update(); -#endif - - MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT); - - atomic_set(&clk_active, 0); - -#ifdef CONFIG_MALI_DVFS - /* Create sysfs for time-in-state */ - if (device_create_file(dev, &dev_attr_time_in_state)) { - dev_err(dev, "Couldn't create sysfs file [time_in_state]\n"); - } - - if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC ); - if (!init_mali_dvfs_status()) - MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n")); -#endif - - mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON); - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_deinit(struct device *dev) -{ - - mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP); - deinit_mali_clock(); - -#ifdef CONFIG_MALI_DVFS - deinit_mali_dvfs_status(); - if (clk_register_map ) - { - _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map); - clk_register_map = NULL; - } -#endif - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode) -{ - switch (power_mode) - { - case MALI_POWER_MODE_ON: - MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n", - bPoweroff ? "powering on" : "already on")); - if (bPoweroff == 1) - { -#if !defined(CONFIG_PM_RUNTIME) - g3d_power_domain_control(1); -#endif - MALI_DEBUG_PRINT(4, ("enable clock \n")); - enable_mali_clocks(); -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); - -#endif - bPoweroff=0; - } - break; - case MALI_POWER_MODE_LIGHT_SLEEP: - case MALI_POWER_MODE_DEEP_SLEEP: - MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode == - MALI_POWER_MODE_LIGHT_SLEEP ? "MALI_POWER_MODE_LIGHT_SLEEP" : - "MALI_POWER_MODE_DEEP_SLEEP", bPoweroff ? "already off" : "powering off")); - if (bPoweroff == 0) - { - disable_mali_clocks(); -#if defined(CONFIG_MALI400_PROFILING) - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - 0, 0, 0, 0, 0); -#endif - -#if !defined(CONFIG_PM_RUNTIME) - g3d_power_domain_control(0); -#endif - bPoweroff=1; - } - - break; - } - MALI_SUCCESS; -} - -void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data) -{ - if (bPoweroff==0) - { -#ifdef CONFIG_MALI_DVFS - if(!mali_dvfs_handler(data->utilization_gpu)) - MALI_DEBUG_PRINT(1, ("error on mali dvfs status in utilization\n")); -#endif - } -} - -int mali_dvfs_bottom_lock_push(int lock_step) -{ - int prev_status = _mali_osk_atomic_read(&bottomlock_status); - - if (prev_status < 0) { - MALI_PRINT(("gpu bottom lock status is not valid for push\n")); - return -1; - } - if (bottom_lock_step < lock_step) { - bottom_lock_step = lock_step; - if (get_mali_dvfs_status() < lock_step) { - mali_regulator_set_voltage(mali_dvfs[lock_step].vol, mali_dvfs[lock_step].vol); - mali_clk_set_rate(mali_dvfs[lock_step].clock, mali_dvfs[lock_step].freq); - set_mali_dvfs_current_step(lock_step); - } - } - return _mali_osk_atomic_inc_return(&bottomlock_status); -} - -int mali_dvfs_bottom_lock_pop(void) -{ - int prev_status = _mali_osk_atomic_read(&bottomlock_status); - if (prev_status <= 0) { - MALI_PRINT(("gpu bottom lock status is not valid for pop\n")); - return -1; - } else if (prev_status >= 1) { - bottom_lock_step = 0; - MALI_PRINT(("gpu bottom lock release\n")); - } - - return _mali_osk_atomic_dec_return(&bottomlock_status); -} - -int mali_dvfs_get_vol(int step) -{ - step = step % MAX_MALI_DVFS_STEPS; - MALI_DEBUG_ASSERT(step= vol) - return mali_dvfs[i].vol; - } - MALI_PRINT(("Failed to get voltage from mali_dvfs table, maximum voltage is %d uV\n", mali_dvfs[MALI_DVFS_STEPS-1].vol)); - return 0; -} -#endif - -#ifdef CONFIG_MALI_DVFS -static void update_time_in_state(int level) -{ - u64 current_time; - static u64 prev_time=0; - - if (prev_time ==0) - prev_time=get_jiffies_64(); - - current_time = get_jiffies_64(); - mali_dvfs_time[level] += current_time-prev_time; - prev_time = current_time; -} - -ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf) -{ - ssize_t ret = 0; - int i; - - update_time_in_state(maliDvfsStatus.currentStep); - - for (i = 0; i < MALI_DVFS_STEPS; i++) { - ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d %llu\n", - mali_dvfs[i].clock, - mali_dvfs_time[i]); - } - - if (ret < PAGE_SIZE - 1) { - ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n"); - } else { - buf[PAGE_SIZE-2] = '\n'; - buf[PAGE_SIZE-1] = '\0'; - ret = PAGE_SIZE-1; - } - - return ret; -} - -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - int i; - - for (i = 0; i < MALI_DVFS_STEPS; i++) { - mali_dvfs_time[i] = 0; - } - - return count; -} -#endif diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4_pmm.h b/drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4_pmm.h deleted file mode 100644 index 1b9cf5790c6..00000000000 --- a/drivers/gpu/arm/mali400/r4p0_rel0/platform/pegasus-m400/exynos4_pmm.h +++ /dev/null @@ -1,121 +0,0 @@ -/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4_pmm.h - * - * Copyright 2011 by S.LSI. Samsung Electronics Inc. - * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea - * - * Samsung SoC Mali400 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file exynos4_pmm.h - * Platform specific Mali driver functions for the exynos 4XXX based platforms - */ - -#ifndef __EXYNOS4_PMM_H__ -#define __EXYNOS4_PMM_H__ - -#include "mali_utgard.h" -#include "mali_osk.h" -#include -/* @Enable or Disable Mali GPU Bottom Lock feature */ -#define MALI_GPU_BOTTOM_LOCK 1 -#define MALI_VOLTAGE_LOCK 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/** @brief description of power change reasons - */ -typedef enum mali_power_mode_tag -{ - MALI_POWER_MODE_ON, - MALI_POWER_MODE_LIGHT_SLEEP, - MALI_POWER_MODE_DEEP_SLEEP, -} mali_power_mode; - -/** @brief Platform specific setup and initialisation of MALI - * - * This is called from the entrypoint of the driver to initialize the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_init(struct device *dev); - -/** @brief Platform specific deinitialisation of MALI - * - * This is called on the exit of the driver to terminate the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_deinit(struct device *dev); - -/** @brief Platform specific powerdown sequence of MALI - * - * Call as part of platform init if there is no PMM support, else the - * PMM will call it. - * There are three power modes defined: - * 1) MALI_POWER_MODE_ON - * 2) MALI_POWER_MODE_LIGHT_SLEEP - * 3) MALI_POWER_MODE_DEEP_SLEEP - * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle - * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions - * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued. - * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power - * off. - * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP - * mode. - * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during - * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from - * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well. - * @param power_mode defines the power modes - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode); - - -/** @brief Platform specific handling of GPU utilization data - * - * When GPU utilization data is enabled, this function will be - * periodically called. - * - * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. - */ -void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data); - -_mali_osk_errcode_t g3d_power_domain_control(int bpower_on); - -#ifdef CONFIG_REGULATOR -void mali_regulator_disable(void); -void mali_regulator_enable(void); -void mali_regulator_set_voltage(int min_uV, int max_uV); -#endif - -#ifdef CONFIG_MALI_DVFS -ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf); -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -#ifdef CONFIG_CPU_EXYNOS4210 -#if MALI_GPU_BOTTOM_LOCK -int mali_dvfs_bottom_lock_push(void); -int mali_dvfs_bottom_lock_pop(void); -#endif -#else -int mali_dvfs_bottom_lock_push(int lock_step); -int mali_dvfs_bottom_lock_pop(void); -#endif -#endif - -#if MALI_VOLTAGE_LOCK -int mali_voltage_lock_push(int lock_vol); -int mali_voltage_lock_pop(void); -int mali_voltage_lock_init(void); -int mali_vol_get_from_table(int vol); -#endif -#ifdef __cplusplus -} -#endif -#endif -- cgit v1.2.3