On Mon, Oct 15, 2012 at 1:51 PM, Rajagopal Venkat <rajagopal.ven...@linaro.org> wrote: > This patch adds devfreq support for Mali driver. Though mali driver > has its own mechanism for load monitoring, this patch makes use of > devfreq framework to achieve same functionality. The goal is to > export gpu dvfs information to user space. > > Depends on devfreq patchset - https://lkml.org/lkml/2012/10/4/95 > > Patch is based on git://git.linaro.org/people/chunsangjeong/mali-dev.git > tree.
Adding Jesse and Andrey to cc. Let's make sure that we coordinate this patch integration into the mali driver with the integration of your devfreq patches to LLCT. In fact, I suggest that Andrey pull in your devfreq patchset into LLCT now since it won't break anything. /Amit > Signed-off-by: Rajagopal Venkat <rajagopal.ven...@linaro.org> > --- > drivers/gpu/arm/mali/Kconfig | 7 + > drivers/gpu/arm/mali/Makefile | 11 ++ > drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c | 188 > +++++++++++++++++++++ > drivers/gpu/arm/mali/linux/mali_kernel_devfreq.h | 51 ++++++ > drivers/gpu/arm/mali/linux/mali_kernel_pm.c | 10 ++ > .../gpu/arm/mali/platform/default/mali_platform.c | 5 +- > drivers/gpu/arm/mali/platform/mali_platform.h | 8 + > 7 files changed, 279 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c > create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_devfreq.h > > diff --git a/drivers/gpu/arm/mali/Kconfig b/drivers/gpu/arm/mali/Kconfig > index 416c231..41634f9 100644 > --- a/drivers/gpu/arm/mali/Kconfig > +++ b/drivers/gpu/arm/mali/Kconfig > @@ -39,6 +39,13 @@ config USING_GPU_UTILIZATION > ---help--- > This enables GPU utilization information. > > +config USING_GPU_DEVFREQ > + bool "GPU devfreq" > + depends on MALI400MP && USING_GPU_UTILIZATION > + default n > + ---help--- > + This enables GPU devfreq. > + > config USING_MALI_RUN_TIME_PM > bool "Using Run time Power Management" > depends on MALI400MP > diff --git a/drivers/gpu/arm/mali/Makefile b/drivers/gpu/arm/mali/Makefile > index 525a23e..6c854b1 100755 > --- a/drivers/gpu/arm/mali/Makefile > +++ b/drivers/gpu/arm/mali/Makefile > @@ -45,6 +45,10 @@ ifeq ($(CONFIG_USING_GPU_UTILIZATION),y) > USING_GPU_UTILIZATION =1 > endif > > +ifeq ($(CONFIG_USING_GPU_DEVFREQ),y) > +USING_GPU_DEVFREQ =1 > +endif > + > ifeq ($(CONFIG_USING_MALI_RUN_TIME_PM),y) > USING_MALI_RUN_TIME_PM =1 > endif > @@ -64,6 +68,7 @@ USING_UMP ?= 0 > USING_OS_MEMORY ?= 0 > USING_PMM ?= 0 > USING_GPU_UTILIZATION ?= 0 > +USING_GPU_DEVFREQ ?= 0 > USING_MALI_RUN_TIME_PM ?= 0 > USING_MALI_PMM_TESTSUITE ?= 0 > OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6 > @@ -105,6 +110,7 @@ endif > > DEFINES += -DUSING_MALI_PMM=$(USING_PMM) > DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION) > +DEFINES += -DMALI_GPU_DEVFREQ=$(USING_GPU_DEVFREQ) > > ifeq ($(CONFIG_DEBUG_BUILD),y) > DEFINES += -DDEBUG > @@ -201,9 +207,14 @@ mali-y += \ > endif > > ifeq ($(USING_GPU_UTILIZATION),1) > +ifeq ($(USING_GPU_DEVFREQ),1) > +mali-y += \ > + linux/mali_kernel_devfreq.o > +else > mali-y += \ > common/mali_kernel_utilization.o > endif > +endif > > ifneq ($(call submodule_enabled, $M, MALI400PP),0) > # Mali-400 PP in use > diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c > b/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c > new file mode 100644 > index 0000000..1213e7b > --- /dev/null > +++ b/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c > @@ -0,0 +1,188 @@ > +/* > + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. > + * > + * This program is free software and is provided to you under the terms of > the GNU General Public License version 2 > + * as published by the Free Software Foundation, and any use by you of this > program is subject to the terms of such GNU licence. > + * > + * A copy of the licence is included with the program, and can also be > obtained from Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > 02110-1301, USA. > + */ > + > +#include <linux/devfreq.h> > +#include <linux/platform_device.h> > +#include "mali_kernel_devfreq.h" > +#include "mali_osk.h" > +#include "mali_platform.h" > +#include "mali_linux_pm.h" > + > +#define MALI_GPU_UTILIZATION_PERIOD 500 > + > +static _mali_osk_lock_t *time_data_lock; > + > +static _mali_osk_atomic_t num_running_cores; > + > +static u64 period_start_time = 0; > +static u64 work_start_time = 0; > +static u64 accumulated_work_time = 0; > +static mali_bool timer_running = MALI_FALSE; > + > +static struct devfreq *mali_devfreq; > + > +static int mali_get_dev_status(struct device *dev, > + struct devfreq_dev_status *stat) > +{ > + u64 time_now; > + u64 time_period; > + > + _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); > + > + if (accumulated_work_time == 0 && work_start_time == 0) > + { > + /* No work done for this period, report zero usage */ > + stat->total_time = 0; > + stat->busy_time = 0; > + stat->current_frequency = get_mali_platform_cur_freq(); > + > + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); > + > + return 0; > + } > + > + time_now = _mali_osk_time_get_ns(); > + time_period = time_now - period_start_time; > + > + /* If we are currently busy, update working period up to now */ > + if (work_start_time != 0) > + { > + accumulated_work_time += (time_now - work_start_time); > + work_start_time = time_now; > + } > + > + stat->total_time = time_period; > + stat->busy_time = accumulated_work_time; > + stat->current_frequency = get_mali_platform_cur_freq(); > + > + accumulated_work_time = 0; > + /* start a new period */ > + period_start_time = time_now; > + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); > + > + return 0; > +} > + > +static int mali_set_target_freq(struct device *dev, > + unsigned long *freq, > + u32 flags) > +{ > + mali_gpu_utilization_handler(*freq); > + return 0; > +} > + > +static int mali_get_cur_freq(struct device *dev, unsigned long *freq) > +{ > + *freq = get_mali_platform_cur_freq(); > + return 0; > +} > + > +static struct devfreq_dev_profile mali_devfreq_profile = { > + .polling_ms = MALI_GPU_UTILIZATION_PERIOD, > + .initial_freq = 0, > + .target = mali_set_target_freq, > + .get_dev_status = mali_get_dev_status, > + .get_cur_freq = mali_get_cur_freq, > +}; > + > +_mali_osk_errcode_t mali_utilization_init(void) > +{ > + /* Register mali devfreq with ondemand governor */ > + mali_devfreq = devfreq_add_device(&mali_gpu_device.dev, > + &mali_devfreq_profile, > + &devfreq_simple_ondemand, > + NULL); > + if (NULL == mali_devfreq) > + { > + return _MALI_OSK_ERR_FAULT; > + } > + > + time_data_lock = _mali_osk_lock_init( 0, 0, 0 ); > + if (NULL == time_data_lock) > + { > + return _MALI_OSK_ERR_FAULT; > + } > + > + _mali_osk_atomic_init(&num_running_cores, 0); > + > + return _MALI_OSK_ERR_OK; > +} > + > +void mali_utilization_suspend(void) > +{ > + if (timer_running == MALI_TRUE) > + { > + devfreq_suspend_device(mali_devfreq); > + _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); > + timer_running = MALI_FALSE; > + work_start_time = 0; > + period_start_time = 0; > + accumulated_work_time = 0; > + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); > + } > +} > + > +void mali_utilization_resume(void) > +{ > + devfreq_resume_device(mali_devfreq); > +} > + > +void mali_utilization_term(void) > +{ > + devfreq_remove_device(mali_devfreq); > + mali_devfreq = NULL; > + > + timer_running = MALI_FALSE; > + > + _mali_osk_atomic_term(&num_running_cores); > + > + _mali_osk_lock_term(time_data_lock); > +} > + > +void mali_utilization_core_start(void) > +{ > + if (_mali_osk_atomic_inc_return(&num_running_cores) == 1) > + { > + /* > + * We went from zero cores working, to one core working, > + * we now consider the entire GPU for being busy > + */ > + _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); > + > + work_start_time = _mali_osk_time_get_ns(); > + > + if (timer_running != MALI_TRUE) > + { > + timer_running = MALI_TRUE; > + period_start_time = work_start_time; > + } > + > + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); > + } > +} > + > +void mali_utilization_core_end(void) > +{ > + if (_mali_osk_atomic_dec_return(&num_running_cores) == 0) > + { > + /* > + * No more cores are working, so accumulate the time we was > busy. > + */ > + u64 time_now; > + > + _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); > + > + time_now = _mali_osk_time_get_ns(); > + accumulated_work_time += (time_now - work_start_time); > + work_start_time = 0; > + > + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); > + } > +} > diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.h > b/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.h > new file mode 100644 > index 0000000..e0a76dc > --- /dev/null > +++ b/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.h > @@ -0,0 +1,51 @@ > +/* > + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. > + * > + * This program is free software and is provided to you under the terms of > the GNU General Public License version 2 > + * as published by the Free Software Foundation, and any use by you of this > program is subject to the terms of such GNU licence. > + * > + * A copy of the licence is included with the program, and can also be > obtained from Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > 02110-1301, USA. > + */ > + > +#ifndef __MALI_KERNEL_DEVFREQ_H__ > +#define __MALI_KERNEL_DEVFREQ_H__ > + > +#include "mali_osk.h" > + > +/** > + * Initialize/start the Mali GPU utilization metrics reporting. > + * > + * @return _MALI_OSK_ERR_OK on success, otherwise failure. > + */ > +_mali_osk_errcode_t mali_utilization_init(void); > + > +/** > + * Terminate the Mali GPU utilization metrics reporting > + */ > +void mali_utilization_term(void); > + > +/** > + * Should be called when a job is about to execute a job > + */ > +void mali_utilization_core_start(void); > + > +/** > + * Should be called to suspend the utilization monitoring during > + * system suspend or device pm-runtime suspend > + */ > +void mali_utilization_suspend(void); > + > +/** > + * Should be called to resume the utilization monitoring during > + * system resume or device pm-runtime resume > + */ > +void mali_utilization_resume(void); > + > +/** > + * Should be called when a job has completed executing a job > + */ > +void mali_utilization_core_end(void); > + > + > +#endif /* __MALI_KERNEL_DEVFREQ_H__ */ > diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c > b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c > index 0c03678..958164e 100644 > --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c > +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c > @@ -40,6 +40,10 @@ > #include "mali_kernel_utilization.h" > #endif /* MALI_GPU_UTILIZATION */ > > +#if MALI_GPU_DEVFREQ > +#include "mali_kernel_devfreq.h" > +#endif /* MALI_GPU_DEVFREQ */ > + > #if MALI_POWER_MGMT_TEST_SUITE > #ifdef CONFIG_PM > #include "mali_linux_pm_testsuite.h" > @@ -418,6 +422,9 @@ static int mali_pm_os_resume_on_hibernation(struct device > *dev) > */ > static int mali_device_runtime_suspend(struct device *dev) > { > +#if MALI_GPU_DEVFREQ > + mali_utilization_suspend(); > +#endif /* MALI_GPU_DEVFREQ */ > MALI_DEBUG_PRINT(4, ("PMMDEBUG: Mali device Run time suspended \n" )); > return 0; > } > @@ -426,6 +433,9 @@ static int mali_device_runtime_suspend(struct device *dev) > */ > static int mali_device_runtime_resume(struct device *dev) > { > +#if MALI_GPU_DEVFREQ > + mali_utilization_resume(); > +#endif /* MALI_GPU_DEVFREQ */ > MALI_DEBUG_PRINT(4, ("PMMDEBUG: Mali device Run time Resumed \n" )); > return 0; > } > diff --git a/drivers/gpu/arm/mali/platform/default/mali_platform.c > b/drivers/gpu/arm/mali/platform/default/mali_platform.c > index d966f25..8247856 100644 > --- a/drivers/gpu/arm/mali/platform/default/mali_platform.c > +++ b/drivers/gpu/arm/mali/platform/default/mali_platform.c > @@ -40,4 +40,7 @@ void set_mali_parent_power_domain(void* dev) > { > } > > - > +unsigned long get_mali_platform_cur_freq(void) > +{ > + return 0; > +} > diff --git a/drivers/gpu/arm/mali/platform/mali_platform.h > b/drivers/gpu/arm/mali/platform/mali_platform.h > index 078bcef..f1bb2b5 100644 > --- a/drivers/gpu/arm/mali/platform/mali_platform.h > +++ b/drivers/gpu/arm/mali/platform/mali_platform.h > @@ -93,6 +93,14 @@ void mali_gpu_utilization_handler(u32 utilization); > */ > void set_mali_parent_power_domain(void* dev); > > +/** @brief Get MALI current running frequency > + * > + * This function gets the current running frequency of MALI > + * > + * @return frequency in Hz > + */ > +unsigned long get_mali_platform_cur_freq(void); > + > #ifdef __cplusplus > } > #endif > -- > 1.7.11.3 > > > _______________________________________________ > linaro-dev mailing list > linaro-dev@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/linaro-dev _______________________________________________ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev