#include <linux/rockchip/cpu.h>
#include <linux/rockchip/dvfs.h>
-/*author@xxm*/
-#define GPUCLK_NAME "gpu"
-#define GPUCLK_PD_NAME "pd_gpu"
-#define GPU_MHZ 1000000
-static struct dvfs_node *mali_clock = 0;
-static struct clk *mali_clock_pd = 0;
+#define GPUCLK_NAME "clk_gpu"
+#define GPUCLK_PD_NAME "pd_gpu"
+#define GPU_MHZ 1000000
+static struct dvfs_node *mali_clock = 0;
+static struct clk *mali_clock_pd = 0;
+static struct clk *audis_gpu_clk = 0;
#define MALI_DVFS_DEFAULT_STEP 0 // 50Mhz default
-u32 mali_dvfs[] = {50,100,133,160,200,266,400};
+u32 mali_dvfs[] = {50, 100, 133, 160, 200, 266, 400};
int num_clock;
u32 mali_init_clock = 50;
u32 mali_utilization_timeout = 10;
u32 sampling_enable = 1;
+
#define mali_freq_workqueue_name "mali_freq_workqueue"
#define mali_freq_work_name "mali_freq_work"
+
struct mali_freq_data {
struct workqueue_struct *wq;
struct work_struct work;
u32 freq;
-}*mali_freq_data;
+} *mali_freq_data;
-typedef struct mali_dvfs_tableTag{
+typedef struct mali_dvfs_tableTag {
u32 clock;
u32 vol;
-}mali_dvfs_table;
+} mali_dvfs_table;
-typedef struct mali_dvfs_statusTag{
+typedef struct mali_dvfs_statusTag {
int currentStep;
mali_dvfs_table * pCurrentDvfs;
-}mali_dvfs_status;
+} mali_dvfs_status;
mali_dvfs_status maliDvfsStatus;
return dvfs_clk_get_rate(clk);
}
-void mali_clk_set_rate(struct dvfs_node *clk,u32 value)
+void mali_clk_set_rate(struct dvfs_node *clk, u32 value)
{
unsigned long rate = (unsigned long)value * GPU_MHZ;
dvfs_clk_set_rate(clk, rate);
{
u32 i;
u32 clock = value;
- for(i=0;i<num_clock;i++)
- {
- if(clock == mali_dvfs[i])
- {
+ for (i=0;i<num_clock;i++) {
+ if (clock == mali_dvfs[i]) {
_mali_osk_mutex_wait(clockSetlock);
mali_clk_set_rate(mali_clock,clock);
_mali_osk_mutex_signal(clockSetlock);
scale_enable_set(0);
return 0;
}
- if(i>=7)
- MALI_DEBUG_PRINT(2,("USER set clock not in the mali_dvfs table\r\n"));
+ if (i>=7)
+ MALI_DEBUG_PRINT(2,("USER set clock not in the mali_dvfs table\r\n"));
}
return 1;
}
currentStep = get_mali_dvfs_status();
timeValue = _mali_osk_time_get_ns();
/*MALI_PRINT(("USER SET CLOCK,%d\r\n",clock));*/
- if(!clock)
- {
+ if(!clock) {
scale_enable_set(1);
- }
- else
- {
+ } else {
mali_dvfs_search(clock);
}
return count;
u32 i;
char *pos = buf;
pos += snprintf(pos,PAGE_SIZE,"%d,",num_clock);
- for(i=0;i<(num_clock-1);i++)
- {
+ for(i=0;i<(num_clock-1);i++) {
pos += snprintf(pos,PAGE_SIZE,"%d,",mali_dvfs[i]);
}
pos +=snprintf(pos,PAGE_SIZE,"%d\n",mali_dvfs[i]);
{
return sprintf(buf, "mali_utilization_timeout = %d\n", mali_utilization_timeout);
}
-static int sampling_timeout_set(struct device *dev,struct device_attribute *attr, const char *buf,u32 count)
+static int sampling_timeout_set(struct device *dev,struct device_attribute *attr,
+ const char *buf,u32 count)
{
u32 sampling;
sampling = simple_strtoul(buf, NULL, 10);
- if(sampling == 0 )
- {
+ if (sampling == 0 ) {
sampling_enable = 0;
MALI_PRINT(("disable mali clock frequency scalling\r\n"));
- }
- else
- {
+ } else {
mali_utilization_timeout = sampling;
sampling_enable = 1;
- MALI_PRINT(("enable mali clock frequency scalling ,mali_utilization_timeout : %dms\r\n",mali_utilization_timeout));
+ MALI_PRINT(("enable mali clock frequency scalling ,mali_utilization_timeout : %dms\r\n",
+ mali_utilization_timeout));
}
return count;
}
static DEVICE_ATTR(utility, 0644, mali400_utility_show, mali400_clock_set);
static DEVICE_ATTR(param, 0644, clock_show, NULL);
-static DEVICE_ATTR(sampling_timeout, 0644, sampling_timeout_show,sampling_timeout_set);
+static DEVICE_ATTR(sampling_timeout, 0644, sampling_timeout_show, sampling_timeout_set);
static DEVICE_ATTR(error_count, 0644, error_count_show, NULL);
static unsigned int decideNextStatus(unsigned int utilization)
{
u32 level=0;
-#if 1
- {
- if(utilization>GPU_DVFS_UP_THRESHOLD && maliDvfsStatus.currentStep==0 && maliDvfsStatus.currentStep<(num_clock-minuend))
- level=1;
- else if(utilization>GPU_DVFS_UP_THRESHOLD && maliDvfsStatus.currentStep==1 && maliDvfsStatus.currentStep<(num_clock-minuend))
- level=2;
- else if(utilization>GPU_DVFS_UP_THRESHOLD && maliDvfsStatus.currentStep==2 && maliDvfsStatus.currentStep<(num_clock-minuend))
- level=3;
- else if(utilization>GPU_DVFS_UP_THRESHOLD && maliDvfsStatus.currentStep==3 && maliDvfsStatus.currentStep<(num_clock-minuend))
- level=4;
- else if(utilization>GPU_DVFS_UP_THRESHOLD && maliDvfsStatus.currentStep==4 && maliDvfsStatus.currentStep<(num_clock-minuend))
- level=5;
- else if(utilization>GPU_DVFS_UP_THRESHOLD && maliDvfsStatus.currentStep==5 && maliDvfsStatus.currentStep<(num_clock-minuend))
- level=6;
- /*
- determined by minuend to up to level 6
- */
- else if(utilization<GPU_DVFS_DOWN_THRESHOLD && maliDvfsStatus.currentStep==6 /*&& maliDvfsStatus.currentStep<num_clock*/)
- level=5;
- else if(utilization<GPU_DVFS_DOWN_THRESHOLD && maliDvfsStatus.currentStep==5 /*&& maliDvfsStatus.currentStep<num_clock*/)
- level=4;
- else if(utilization<GPU_DVFS_DOWN_THRESHOLD && maliDvfsStatus.currentStep==4 /*&& maliDvfsStatus.currentStep<num_clock*/)
- level=3;
- else if(utilization<GPU_DVFS_DOWN_THRESHOLD && maliDvfsStatus.currentStep==3 /*&& maliDvfsStatus.currentStep<num_clock*/)
- level=2;
- else if(utilization<GPU_DVFS_DOWN_THRESHOLD && maliDvfsStatus.currentStep==2 /*&& maliDvfsStatus.currentStep<num_clock*/)
- level=1;
- else if(utilization<GPU_DVFS_DOWN_THRESHOLD && maliDvfsStatus.currentStep==1 /*&& maliDvfsStatus.currentStep<num_clock*/)
- level=0;
- else
- level = maliDvfsStatus.currentStep;
- }
-#endif
+
+ if(utilization > GPU_DVFS_UP_THRESHOLD &&
+ maliDvfsStatus.currentStep == 0 &&
+ maliDvfsStatus.currentStep < (num_clock-minuend))
+ level = 1;
+ else if (utilization > GPU_DVFS_UP_THRESHOLD &&
+ maliDvfsStatus.currentStep == 1 &&
+ maliDvfsStatus.currentStep < (num_clock-minuend))
+ level = 2;
+ else if (utilization > GPU_DVFS_UP_THRESHOLD &&
+ maliDvfsStatus.currentStep == 2 &&
+ maliDvfsStatus.currentStep < (num_clock-minuend))
+ level = 3;
+ else if (utilization > GPU_DVFS_UP_THRESHOLD &&
+ maliDvfsStatus.currentStep == 3 &&
+ maliDvfsStatus.currentStep < (num_clock-minuend))
+ level = 4;
+ else if (utilization > GPU_DVFS_UP_THRESHOLD &&
+ maliDvfsStatus.currentStep == 4 &&
+ maliDvfsStatus.currentStep < (num_clock-minuend))
+ level = 5;
+ else if (utilization > GPU_DVFS_UP_THRESHOLD &&
+ maliDvfsStatus.currentStep == 5 &&
+ maliDvfsStatus.currentStep < (num_clock-minuend))
+ level = 6;
+ /*
+ determined by minuend to up to level 6
+ */
+ else if(utilization < GPU_DVFS_DOWN_THRESHOLD &&
+ maliDvfsStatus.currentStep == 6)
+ level = 5;
+ else if(utilization < GPU_DVFS_DOWN_THRESHOLD &&
+ maliDvfsStatus.currentStep == 5)
+ level = 4;
+ else if(utilization < GPU_DVFS_DOWN_THRESHOLD &&
+ maliDvfsStatus.currentStep == 4)
+ level = 3;
+ else if(utilization < GPU_DVFS_DOWN_THRESHOLD &&
+ maliDvfsStatus.currentStep == 3)
+ level = 2;
+ else if(utilization < GPU_DVFS_DOWN_THRESHOLD &&
+ maliDvfsStatus.currentStep == 2)
+ level = 1;
+ else if(utilization < GPU_DVFS_DOWN_THRESHOLD &&
+ maliDvfsStatus.currentStep == 1)
+ level = 0;
+ else
+ level = maliDvfsStatus.currentStep;
return level;
}
static mali_bool set_mali_dvfs_status(u32 step)
{
- u32 validatedStep=step;
- if(1)
- {
- _mali_osk_mutex_wait(clockSetlock);
+ u32 validatedStep=step;
+
+ _mali_osk_mutex_wait(clockSetlock);
mali_clk_set_rate(mali_clock, mali_dvfs[validatedStep]);
- _mali_osk_mutex_signal(clockSetlock);
- set_mali_dvfs_step(validatedStep);
- }
- return MALI_TRUE;
+ _mali_osk_mutex_signal(clockSetlock);
+ set_mali_dvfs_step(validatedStep);
+
+ return MALI_TRUE;
}
static mali_bool change_mali_dvfs_status(u32 step)
{
- if(!set_mali_dvfs_status(step))
- {
- MALI_DEBUG_PRINT(2,("error on set_mali_dvfs_status: %d\n",step));
- return MALI_FALSE;
- }
+ if(!set_mali_dvfs_status(step)) {
+ MALI_DEBUG_PRINT(2,("error on set_mali_dvfs_status: %d\n",step));
+ return MALI_FALSE;
+ }
+
return MALI_TRUE;
}
curStatus = get_mali_dvfs_status();
nextStatus = decideNextStatus(utilization_global);
- if(curStatus!=nextStatus)
- {
- if(!change_mali_dvfs_status(nextStatus))
- {
+ if (curStatus!=nextStatus) {
+ if (!change_mali_dvfs_status(nextStatus)) {
MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
}
}
{
mali_bool ret = MALI_TRUE;
int i;
+
if (mali_clock != 0 || mali_clock_pd != 0)
return ret;
mali_clock_pd = clk_get(NULL,GPUCLK_PD_NAME);
- if (IS_ERR(mali_clock_pd))
- {
+ if (IS_ERR(mali_clock_pd)) {
MALI_PRINT( ("MALI Error : failed to get source mali pd\n"));
ret = MALI_FALSE;
goto err_gpu_clk;
clk_prepare_enable(mali_clock_pd);
mali_clock = clk_get_dvfs_node(GPUCLK_NAME);
- if (IS_ERR(mali_clock))
- {
+ if (IS_ERR(mali_clock)) {
MALI_PRINT( ("MALI Error : failed to get source mali clock\n"));
ret = MALI_FALSE;
goto err_gpu_clk;
}
dvfs_clk_prepare_enable(mali_clock);
freq_table = dvfs_get_freq_volt_table(mali_clock);
- if(!freq_table)
- {
+ if (!freq_table) {
MALI_PRINT(("Stop,dvfs table should be set in dts\n"));
return MALI_FALSE;
}
- for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
- {
+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
mali_dvfs[i] = freq_table[i].frequency/1000;
}
mali_init_clock = mali_dvfs[0];
mali_clock_pd = 0;
if(gpu_power_state)
gpu_power_state = 0;
+
return MALI_TRUE;
}
_mali_osk_errcode_t mali_platform_init(void)
{
- if (cpu_is_rk3036())
- MALI_SUCCESS;
+ if (cpu_is_rk3036()) {
+ audis_gpu_clk = clk_get(NULL,"clk_gpu");
+ if (IS_ERR(mali_clock_pd)) {
+ MALI_PRINT( ("MALI Error : failed to get audis mali clk\n"));
+ return MALI_FALSE;
+
+ }
+
+ clk_prepare_enable(audis_gpu_clk);
+
+ MALI_SUCCESS;
+ }
MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
clockSetlock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED,_MALI_OSK_LOCK_ORDER_UTILIZATION);
MALI_PRINT(("mali400_utility_sysfs_init error\r\n"));
mali_freq_data = kmalloc(sizeof(struct mali_freq_data), GFP_KERNEL);
- if(!mali_freq_data)
- {
+ if(!mali_freq_data) {
MALI_PRINT(("kmalloc error\r\n"));
MALI_ERROR(-1);
}
_mali_osk_errcode_t mali_platform_deinit(void)
{
- if (cpu_is_rk3036())
+ if (cpu_is_rk3036()) {
+ clk_disable_unprepare(audis_gpu_clk);
MALI_SUCCESS;
+ }
deinit_mali_clock();
_mali_osk_mutex_term(clockSetlock);
}
_mali_osk_errcode_t mali_power_domain_control(u32 bpower_off)
{
- if (cpu_is_rk3036())
- MALI_SUCCESS;
-
- if (!bpower_off)
- {
- if(!gpu_power_state)
- {
- clk_prepare_enable(mali_clock_pd);
- dvfs_clk_prepare_enable(mali_clock);
+ if (!bpower_off) {
+ if (!gpu_power_state) {
+ if (cpu_is_rk3036()) {
+ clk_prepare_enable(audis_gpu_clk);
+ } else {
+ clk_prepare_enable(mali_clock_pd);
+ dvfs_clk_prepare_enable(mali_clock);
+ }
gpu_power_state = 1 ;
}
- }
- else if (bpower_off == 2)
- {
+ } else if (bpower_off == 2) {
;
- }
- else if (bpower_off == 1)
- {
- if(gpu_power_state)
- {
- dvfs_clk_disable_unprepare(mali_clock);
- clk_disable_unprepare(mali_clock_pd);
+ } else if (bpower_off == 1) {
+ if(gpu_power_state) {
+ if (cpu_is_rk3036()) {
+ clk_disable_unprepare(audis_gpu_clk);
+ } else {
+ dvfs_clk_disable_unprepare(mali_clock);
+ clk_disable_unprepare(mali_clock_pd);
+ }
gpu_power_state = 0;
}
}
- MALI_SUCCESS;
+ MALI_SUCCESS;
}
_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
{
-#if 0
- switch(power_mode)
- {
+#if 1
+ switch(power_mode) {
case MALI_POWER_MODE_ON:
MALI_DEBUG_PRINT(2,("MALI_POWER_MODE_ON\r\n"));
mali_power_domain_control(MALI_POWER_MODE_ON);
return ;
}
-
-void set_mali_parent_power_domain(void* dev)
-{
-}
-
-
-
static struct work_struct wq_work;
-static struct dev_pm_ops mali_gpu_device_type_pm_ops =
-{
+static struct dev_pm_ops mali_gpu_device_type_pm_ops = {
.suspend = mali_os_suspend,
.resume = mali_os_resume,
.freeze = mali_os_freeze,
#endif
};
-static struct device_type mali_gpu_device_device_type =
-{
+static struct device_type mali_gpu_device_device_type = {
.pm = &mali_gpu_device_type_pm_ops,
};
static u64 dma_dmamask = DMA_BIT_MASK(32);
-static struct mali_gpu_device_data mali_gpu_data =
-{
+static struct mali_gpu_device_data mali_gpu_data = {
.shared_mem_size = 1024* 1024 * 1024, /* 1GB */
.fb_start = 0x40000000,
.fb_size = 0xb1000000,
}
static void enable_one_core(void)
{
- if (num_cores_enabled < num_cores_total)
- {
+ if (num_cores_enabled < num_cores_total) {
++num_cores_enabled;
schedule_work(&wq_work);
MALI_DEBUG_PRINT(3, ("Core scaling: Enabling one more core\n"));
}
- MALI_DEBUG_ASSERT( 1 <= num_cores_enabled);
+ MALI_DEBUG_ASSERT(1 <= num_cores_enabled);
MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
}
static void disable_one_core(void)
{
- if (1 < num_cores_enabled)
- {
+ if (1 < num_cores_enabled) {
--num_cores_enabled;
schedule_work(&wq_work);
MALI_DEBUG_PRINT(3, ("Core scaling: Disabling one core\n"));
}
- MALI_DEBUG_ASSERT( 1 <= num_cores_enabled);
+ MALI_DEBUG_ASSERT(1 <= num_cores_enabled);
MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
}
static void enable_max_num_cores(void)
{
- if (num_cores_enabled < num_cores_total)
- {
+ if (num_cores_enabled < num_cores_total) {
num_cores_enabled = num_cores_total;
schedule_work(&wq_work);
MALI_DEBUG_PRINT(3, ("Core scaling: Enabling maximum number of cores\n"));
* in order to make a good core scaling algorithm.
*/
- MALI_DEBUG_PRINT(3, ("Utilization: (%3d, %3d, %3d), cores enabled: %d/%d\n", data->utilization_gpu, data->utilization_gp, data->utilization_pp, num_cores_enabled, num_cores_total));
+ MALI_DEBUG_PRINT(3, ("Utilization: (%3d, %3d, %3d), cores enabled: %d/%d\n",
+ data->utilization_gpu, data->utilization_gp,
+ data->utilization_pp, num_cores_enabled, num_cores_total));
/* NOTE: this function is normally called directly from the utilization callback which is in
* timer context. */
- if ( PERCENT_OF(90, 256) < data->utilization_pp)
- {
+ if (PERCENT_OF(90, 256) < data->utilization_pp) {
enable_max_num_cores();
- }
- else if (PERCENT_OF(50, 256) < data->utilization_pp)
- {
+ } else if (PERCENT_OF(50, 256) < data->utilization_pp) {
enable_one_core();
- }
- else if (PERCENT_OF(40, 256) < data->utilization_pp)
- {
+ } else if (PERCENT_OF(40, 256) < data->utilization_pp) {
/* do nothing */
- }
- else if (PERCENT_OF( 0, 256) < data->utilization_pp)
- {
+ } else if (PERCENT_OF( 0, 256) < data->utilization_pp) {
disable_one_core();
- }
- else
- {
+ } else {
/* do nothing */
}
}
err = platform_device_add_data(pdev, &mali_gpu_data, sizeof(mali_gpu_data));
- if (0 == err)
- {
+ if (0 == err) {
err = mali_platform_init();
- if(0 == err)
- {
+ if(0 == err) {
#ifdef CONFIG_PM_RUNTIME
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
pm_runtime_set_autosuspend_delay(&(pdev->dev), 1000);
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->suspend)
- {
+ NULL != device->driver->pm->suspend) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->suspend(device);
}
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->resume)
- {
+ NULL != device->driver->pm->resume) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->resume(device);
}
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->freeze)
- {
+ NULL != device->driver->pm->freeze) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->freeze(device);
}
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->thaw)
- {
+ NULL != device->driver->pm->thaw) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->thaw(device);
}
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->runtime_suspend)
- {
+ NULL != device->driver->pm->runtime_suspend) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->runtime_suspend(device);
}
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->runtime_resume)
- {
+ NULL != device->driver->pm->runtime_resume) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->runtime_resume(device);
}
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->runtime_idle)
- {
+ NULL != device->driver->pm->runtime_idle) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->runtime_idle(device);
if (0 != ret)
- {
return ret;
- }
}
pm_runtime_suspend(device);