1) access mali clock in critical method.
2) I found pp scaling not work well.
MALI_PLATFORM_FILES:= platform/meson8/mali_scaling.c \
platform/meson8/meson_main.c \
platform/meson8/mali_clock.c \
- platform/meson8/mali_device_type.c
+ platform/meson8/mali_device_type.c \
+ platform/mpgpu.c
endif
##################### end Kasin Added. ###################
.read = domain_stat_read,
};
-static ssize_t gate_test_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
-{
- int ret;
- char buffer[32];
- unsigned long val;
-
- if (count >= sizeof(buffer))
- {
- return -ENOMEM;
- }
-
- if (copy_from_user(&buffer[0], buf, count))
- {
- return -EFAULT;
- }
- buffer[count] = '\0';
-
- ret = strict_strtoul(&buffer[0], 10, &val);
- if (0 != ret)
- {
- return -EINVAL;
- }
-
- if (val == 0) {
- printk(" gate off the mali clock.\n");
- disable_clock();
- } else {
- printk(" gate off the mali clock.\n");
- enable_clock();
- }
-
- *offp += count;
- return count;
-}
-
-static const struct file_operations gate_test_fops = {
- .owner = THIS_MODULE,
- .write = gate_test_write
-};
-
static ssize_t max_pp_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
{
int r;
debugfs_create_file("cur_freq", 0600, mali_misc_setting_dir, NULL, &cur_freq_fops);
debugfs_create_file("scale_mode", 0600, mali_misc_setting_dir, NULL, &scale_mode_fops);
debugfs_create_file("domain_stat", 0600, mali_misc_setting_dir, NULL, &domain_stat_fops);
- debugfs_create_file("gate_test", 0600, mali_misc_setting_dir, NULL, &gate_test_fops);
debugfs_create_file("max_pp", 0600, mali_misc_setting_dir, NULL, &max_pp_fops);
debugfs_create_file("min_pp", 0600, mali_misc_setting_dir, NULL, &min_pp_fops);
debugfs_create_file("max_freq", 0600, mali_misc_setting_dir, NULL, &max_freq_fops);
//#include "mali_osk.h"
#define MALI_CLOCK_CTL ((u32)(P_HHI_MALI_CLK_CNTL))
+static DEFINE_SPINLOCK(lock);
-//static _mali_osk_lock_t *mali_clock_locker = NULL;
static u32 mali_default_clock_step = 0;
static u32 mali_dvfs_clk[] = {
637, /* 637.5 Mhz */
};
-void mali_clock_lock(void)
-{
- //_mali_osk_lock_wait(mali_clock_locker, _MALI_OSK_LOCKMODE_RW);
-}
-
-void mali_clock_unlock(void)
-{
- //_mali_osk_lock_signal(mali_clock_locker, _MALI_OSK_LOCKMODE_RW);
-}
-
int mali_clock_init(u32 def_clk_idx)
{
mali_default_clock_step = def_clk_idx;
mali_clock_set(mali_default_clock_step);
- //mali_clock_locker = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_EXECUTE);
- //if (NULL == mali_clock_locker)
- //return _MALI_OSK_ERR_NOMEM;
return 0;
}
-void mali_clock_term(void)
-{
- //if (mali_clock_locker)
- //_mali_osk_lock_term(mali_clock_locker);
- //mali_clock_locker = NULL;
-}
-
u32 get_mali_default_clock_idx(void)
{
return mali_default_clock_step;
mali_default_clock_step = idx;
}
-int mali_clock_set(unsigned int idx) {
- clrbits_le32(MALI_CLOCK_CTL, 1 << 8);
- clrbits_le32(MALI_CLOCK_CTL, (0x7F | (0x7 << 9)));
- writel(mali_dvfs_clk[idx], MALI_CLOCK_CTL); /* set clock to 333MHZ.*/
- setbits_le32(MALI_CLOCK_CTL, 1 << 8);
+int mali_clock_critical(critical_t critical, u64 param)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+ ret = critical(param);
+ spin_unlock_irqrestore(&lock, flags);
+ return ret;
}
-u32 mali_clock_test(void)
+static int critical_clock_set(u64 param)
{
- unsigned int clk_mux = 35;
- unsigned int regval = 0;
- /// Set the measurement gate to 64uS
- clrsetbits_le32(P_MSR_CLK_REG0,0xffff,121);///122us
-
- // Disable continuous measurement
- // disable interrupts
- clrsetbits_le32(P_MSR_CLK_REG0,
- ((1 << 18) | (1 << 17)|(0x1f << 20)),///clrbits
- (clk_mux << 20) | /// Select MUX
- (1 << 19) | /// enable the clock
- (1 << 16));
- // Wait for the measurement to be done
- regval = readl(P_MSR_CLK_REG0);
- do {
- regval = readl(P_MSR_CLK_REG0);
- } while (regval & (1 << 31));
-
- // disable measuring
- clrbits_le32(P_MSR_CLK_REG0, (1 << 16));
- regval = (readl(P_MSR_CLK_REG2)) & 0x000FFFFF;
- regval += (regval/10000) * 6;
- // Return value in MHz*measured_val
- return (regval << 13);
+ unsigned int idx = param;
+ clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
+ clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, (0x7F | (0x7 << 9)));
+ writel(mali_dvfs_clk[idx], (u32*)MALI_CLOCK_CTL); /* set clock to 333MHZ.*/
+ setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
+ return 0;
}
-void try_open_clock(void)
+int mali_clock_set(unsigned int clock)
{
- if ((readl(MALI_CLOCK_CTL) & (1 << 8)) == 0 ) {
- setbits_le32(P_HHI_MALI_CLK_CNTL, 1 << 8);
- }
+ return mali_clock_critical(critical_clock_set, (u64)clock);
}
void disable_clock(void)
{
- clrbits_le32(MALI_CLOCK_CTL, 1 << 8);
+ unsigned long flags;
+ spin_lock_irqsave(&lock, flags);
+ clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
+ spin_unlock_irqrestore(&lock, flags);
+ printk("## mali clock off----\n");
}
-
void enable_clock(void)
{
u32 ret = 0;
- setbits_le32(MALI_CLOCK_CTL, 1 << 8);
- ret = readl(MALI_CLOCK_CTL) & (1 << 8);
+ unsigned long flags;
+ spin_lock_irqsave(&lock, flags);
+ setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
+ ret = readl((u32 *)P_HHI_MALI_CLK_CNTL) & (1 << 8);
+ spin_unlock_irqrestore(&lock, flags);
+ printk("## mali clock on :%x++++\n", ret);
}
u32 get_clock_state(void)
{
u32 ret = 0;
- //mali_clock_lock();
- ret = readl(MALI_CLOCK_CTL) & (1 << 8);
- //mali_clock_unlock();
+ unsigned long flags;
+ spin_lock_irqsave(&lock, flags);
+ ret = readl((u32 *)P_HHI_MALI_CLK_CNTL) & (1 << 8);
+ spin_unlock_irqrestore(&lock, flags);
return ret;
}
u32 get_mali_reg(void)
{
- return readl(MALI_CLOCK_CTL);
+ return readl((u32 *)MALI_CLOCK_CTL);
}
u32 get_mali_freq(u32 idx)
extern unsigned int min_mali_clock_index;
extern unsigned int max_mali_clock_index;
+typedef int (*critical_t)(u64 param);
+int mali_clock_critical(critical_t critical, u64 param);
int mali_clock_init(u32 def_clk_idx);
-void mali_clock_term(void);
-void mali_clock_lock(void);
-void mali_clock_unlock(void);
-
int mali_clock_set(unsigned int index);
void disable_clock(void);
void enable_clock(void);
-void try_open_clock(void);
-
u32 get_clock_state(void);
u32 get_mali_freq(u32 idx);
u32 get_mali_default_clock_idx(void);
#include "mali_scaling.h"
#include "mali_clock.h"
-static int mali_os_suspend(struct device *device)
+int mali_cri_pmu_on_off(u64 param)
{
- int ret = 0;
struct mali_pmu_core *pmu;
MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
pmu = mali_pmu_get_global_pmu_core();
+ if (param == 0)
+ mali_pmu_power_down_all(pmu);
+ else
+ mali_pmu_power_up_all(pmu);
+ return 0;
+}
- try_open_clock();
+static int mali_os_suspend(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
+
+ enable_clock();
flush_scaling_job();
if (NULL != device->driver &&
NULL != device->driver->pm &&
}
/* clock scaling off. Kasin... */
- mali_pmu_power_down_all(pmu);
+ mali_clock_critical(mali_cri_pmu_on_off, 0);
disable_clock();
return ret;
static int mali_os_resume(struct device *device)
{
int ret = 0;
- struct mali_pmu_core *pmu;
MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
- pmu = mali_pmu_get_global_pmu_core();
/* clock scaling up. Kasin.. */
enable_clock();
- mali_pmu_power_up_all(pmu);
+ mali_clock_critical(mali_cri_pmu_on_off, 1);
if (NULL != device->driver &&
NULL != device->driver->pm &&
NULL != device->driver->pm->resume)
static int mali_runtime_suspend(struct device *device)
{
int ret = 0;
- struct mali_pmu_core *pmu;
- pmu = mali_pmu_get_global_pmu_core();
MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
#ifdef CONFIG_MALI400_PROFILING
}
/* clock scaling. Kasin..*/
- if (get_clock_state()) {
- mali_pmu_power_down_all(pmu);
- } else
- printk("fkclk test..\n");
+ mali_clock_critical(mali_cri_pmu_on_off, 0);
//disable_clock();
return ret;
}
static int mali_runtime_resume(struct device *device)
{
int ret = 0;
- struct mali_pmu_core *pmu;
- pmu = mali_pmu_get_global_pmu_core();
- MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
+ MALI_DEBUG_PRINT(4, ("mali_run time_resume() called\n"));
/* clock scaling. Kasin..*/
//enable_clock();
- mali_pmu_power_up_all(pmu);
+ mali_clock_critical(mali_cri_pmu_on_off, 1);
#ifdef CONFIG_MALI400_PROFILING
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
MALI_PROFILING_EVENT_CHANNEL_GPU |
}
extern int try_exclu_cpu_exe2(exl_call_func_t func, void * p_arg);
static void do_scaling(struct work_struct *work)
-{int err = 0;
- //int err = mali_perf_set_num_pp_cores(num_cores_enabled);
+{
+ int err = mali_perf_set_num_pp_cores(num_cores_enabled);
MALI_DEBUG_ASSERT(0 == err);
MALI_IGNORE(err);
if (mali_dvfs_threshold[currentStep].freq_index != mali_dvfs_threshold[lastStep].freq_index) {
MALI_DEBUG_PRINT(3, ("Core scaling: Disabling one core\n"));
}
- MALI_DEBUG_ASSERT( min_pp_num <= num_cores_enabled);
+ MALI_DEBUG_ASSERT(min_pp_num <= num_cores_enabled);
MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
return ret;
}
{
INIT_WORK(&wq_work, do_scaling);
- num_cores_total = 4;
+ num_cores_total = MALI_PP_NUMBER;
num_cores_enabled = num_cores_total;
currentStep = get_mali_default_clock_idx();
if (loading_complete > (2<<16) &&
currentStep > freq_for_mem_limit) {
currentStep --;
- MALI_DEBUG_PRINT(2, (" active time vs command complete:%d\n", loading_complete));
+ MALI_DEBUG_PRINT(3, (" active time vs command complete:%d\n", loading_complete));
goto exit;
}
} else {
enable_one_core();
}
- MALI_DEBUG_PRINT(2, (" > utilization:%d currentStep:%d.pp:%d. upthreshold:%d.\n",
+ MALI_DEBUG_PRINT(3, (" > utilization:%d currentStep:%d.pp:%d. upthreshold:%d.\n",
utilization, currentStep, num_cores_enabled, mali_dvfs_threshold[currentStep].upthreshold ));
} else if (utilization < mali_dvfs_threshold[currentStep].downthreshold && currentStep > min_mali_clock) {
currentStep--;
- MALI_DEBUG_PRINT(2, (" < utilization:%d currentStep:%d. downthreshold:%d.\n",
+ MALI_DEBUG_PRINT(3, (" < utilization:%d currentStep:%d. downthreshold:%d.\n",
utilization, currentStep,mali_dvfs_threshold[currentStep].downthreshold ));
} else {
if (data->utilization_pp < mali_pp_scale_threshold[MALI_PP_THRESHOLD_30])
ret = disable_one_core();
- MALI_DEBUG_PRINT(2, (" < utilization:%d currentStep:%d. downthreshold:%d.pp:%d\n",
+ MALI_DEBUG_PRINT(3, (" < utilization:%d currentStep:%d. downthreshold:%d.pp:%d\n",
utilization, currentStep,mali_dvfs_threshold[currentStep].downthreshold, num_cores_enabled));
}
void set_mali_qq_for_sched(u32 pp_num)
{
- num_cores_total = pp_num;
num_cores_enabled = pp_num;
schedule_work(&wq_work);
}
return 0;
}
+void mali_plat_preheat(void)
+{
+ //printk(" aml mali test*************\n");
+ int ret;
+ ret = enable_max_num_cores();
+ if (ret)
+ schedule_work(&wq_work);
+}
+
u32 get_current_frequency(void) {
return get_mali_freq(currentStep);
}
#ifndef __ARM_CORE_SCALING_H__
#define __ARM_CORE_SCALING_H__
+#define MALI_PP_NUMBER 6
+
struct mali_gpu_utilization_data;
typedef struct mali_dvfs_threshold_table {
u32 set_mali_dvfs_tbl_size(u32 size);
u32 get_max_dvfs_tbl_size(void);
uint32_t* get_mali_dvfs_tbl_addr(void);
+void mali_plat_preheat(void);
#endif /* __ARM_CORE_SCALING_H__ */
int mali_pdev_pre_init(struct platform_device* ptr_plt_dev)
{
- int num_pp_cores = MALI_PP_NUMBER;
-
if (mali_gpu_data.shared_mem_size < 10) {
MALI_DEBUG_PRINT(2, ("mali os memory didn't configered, set to default(512M)\n"));
mali_gpu_data.shared_mem_size = 1024 * 1024 *1024;
MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
ptr_plt_dev->num_resources = ARRAY_SIZE(mali_gpu_resources_m450);
- ptr_plt_dev->resource = &mali_gpu_resources_m450;
+ ptr_plt_dev->resource = mali_gpu_resources_m450;
return mali_clock_init(MALI_CLOCK_318);
}
void mali_platform_device_unregister(void)
{
MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
- mali_core_scaling_term();
- mali_clock_term();
platform_device_unregister(&mali_gpu_device);
platform_device_put(&mali_gpu_device);
--- /dev/null
+/*******************************************************************\r
+ *\r
+ * Copyright C 2013 by Amlogic, Inc. All Rights Reserved.\r
+ *\r
+ * Description:\r
+ *\r
+ * Author: Amlogic Software\r
+ * Created: 2010/4/1 19:46\r
+ *\r
+ *******************************************************************/\r
+/* Standard Linux headers */\r
+#include <linux/types.h>\r
+#include <linux/init.h>\r
+#include <linux/module.h>\r
+#include <linux/kernel.h>\r
+#include <linux/device.h>\r
+#include <linux/string.h>\r
+#include <linux/slab.h>\r
+#include <linux/list.h>\r
+\r
+static ssize_t mpgpu_show(struct class *class,\r
+ struct class_attribute *attr, char *buf)\r
+{\r
+ return 0;\r
+}\r
+\r
+#define PREHEAT_CMD "preheat"\r
+\r
+void mali_plat_preheat(void);\r
+static ssize_t mpgpu_store(struct class *class,\r
+ struct class_attribute *attr, const char *buf, size_t count)\r
+{\r
+ if(!strncmp(buf,PREHEAT_CMD,strlen(PREHEAT_CMD)))\r
+ mali_plat_preheat();\r
+ return count;\r
+}\r
+\r
+static CLASS_ATTR(mpgpucmd, 0644, mpgpu_show, mpgpu_store);\r
+\r
+static struct class_attribute *mali_attr[]={\r
+ &class_attr_mpgpucmd,\r
+ \r
+};\r
+\r
+static struct class mpgpu_class = {\r
+ .name = "mpgpu",\r
+};\r
+\r
+static int __init mpgpu_class_init(void)\r
+{\r
+ int error;\r
+ int i;\r
+ \r
+ error = class_register(&mpgpu_class);\r
+ if (error) {\r
+ printk(KERN_ERR "%s: class_register failed\n", __func__);\r
+ return error;\r
+ }\r
+ for(i=0;i<ARRAY_SIZE(mali_attr);i++) {\r
+ error = class_create_file(&mpgpu_class,mali_attr[i]);\r
+ if (error < 0)\r
+ goto err;\r
+ }\r
+\r
+ return 0;\r
+err:\r
+ printk(KERN_ERR "MALI: %dst class failed\n",i);\r
+ class_unregister(&mpgpu_class);\r
+}\r
+static void __exit mpgpu_class_exit(void)\r
+{\r
+ class_unregister(&mpgpu_class);\r
+}\r
+\r
+fs_initcall(mpgpu_class_init);\r
+module_exit(mpgpu_class_exit);\r
+\r
+MODULE_DESCRIPTION("AMLOGIC mpgpu driver");\r
+MODULE_LICENSE("GPL");\r
+MODULE_AUTHOR("aml-sh <kasin.li@amlogic.com>");\r
+\r
+\r