From 25fefda6f8416c71921565abf18b7b750a3238ca Mon Sep 17 00:00:00 2001 From: chenxing Date: Wed, 8 May 2013 19:32:01 +0800 Subject: [PATCH] rk: pm_test: add maxfreq operation support --- arch/arm/plat-rk/rk_pm_tests/Kconfig | 6 + arch/arm/plat-rk/rk_pm_tests/Makefile | 1 + arch/arm/plat-rk/rk_pm_tests/maxfreq.c | 241 +++++++++++++++++++++ arch/arm/plat-rk/rk_pm_tests/maxfreq.h | 8 + arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c | 4 + 5 files changed, 260 insertions(+) create mode 100644 arch/arm/plat-rk/rk_pm_tests/maxfreq.c create mode 100644 arch/arm/plat-rk/rk_pm_tests/maxfreq.h diff --git a/arch/arm/plat-rk/rk_pm_tests/Kconfig b/arch/arm/plat-rk/rk_pm_tests/Kconfig index ae575e948570..4acf1bf425f6 100755 --- a/arch/arm/plat-rk/rk_pm_tests/Kconfig +++ b/arch/arm/plat-rk/rk_pm_tests/Kconfig @@ -17,6 +17,12 @@ config PM_TEST_CLK_VOLT help Use to set voltage domain's voltage +config PM_TEST_MAXFREQ + bool "For max runable frequency test" + default y + help + Use to test the max runable frequency of a fixed voltage + config PM_TEST_FREQ_LIMIT bool "Limit clocks' frequency" help diff --git a/arch/arm/plat-rk/rk_pm_tests/Makefile b/arch/arm/plat-rk/rk_pm_tests/Makefile index 39cf7ba74c4e..6d01b0bcdbad 100644 --- a/arch/arm/plat-rk/rk_pm_tests/Makefile +++ b/arch/arm/plat-rk/rk_pm_tests/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_RK_PM_TESTS) += rk_pm_tests.o # Optional functions obj-$(CONFIG_PM_TEST_CLK_RATE) += clk_rate.o obj-$(CONFIG_PM_TEST_CLK_VOLT) += clk_volt.o +obj-$(CONFIG_PM_TEST_MAXFREQ) += maxfreq.o obj-$(CONFIG_PM_TEST_FREQ_LIMIT) += freq_limit.o obj-$(CONFIG_PM_TEST_CPU_USAGE) += cpu_usage.o obj-$(CONFIG_PM_TEST_SUSPEND_DBG) += rk_suspend_test.o diff --git a/arch/arm/plat-rk/rk_pm_tests/maxfreq.c b/arch/arm/plat-rk/rk_pm_tests/maxfreq.c new file mode 100644 index 000000000000..631c34feded6 --- /dev/null +++ b/arch/arm/plat-rk/rk_pm_tests/maxfreq.c @@ -0,0 +1,241 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "rk_pm_tests.h" +#include "maxfreq.h" +/* + * Warning: Must set ddr_freq = 200M, gpu_freq = 200M; to make sure ddr + * and gpu can run under log = 1V. + * Remember to close cpufreq's max freq limit + * + * */ +static struct cpufreq_frequency_table *dvfs_arm_table_save; +static struct cpufreq_frequency_table dvfs_arm_table_maxfreq[] = { + {.frequency = 252 * 1000, .index = 1000 * 1000}, + {.frequency = 312 * 1000, .index = 1000 * 1000}, + {.frequency = 504 * 1000, .index = 1000 * 1000}, + {.frequency = 816 * 1000, .index = 1000 * 1000}, + {.frequency = 912 * 1000, .index = 1000 * 1000}, + {.frequency = 936 * 1000, .index = 1000 * 1000}, + {.frequency = 960 * 1000, .index = 1000 * 1000}, + {.frequency = 984 * 1000, .index = 1000 * 1000}, + {.frequency = 1008 * 1000, .index = 1000 * 1000}, + {.frequency = 1032 * 1000, .index = 1000 * 1000}, + {.frequency = 1056 * 1000, .index = 1000 * 1000}, + {.frequency = 1080 * 1000, .index = 1000 * 1000}, + {.frequency = 1104 * 1000, .index = 1000 * 1000}, + {.frequency = 1128 * 1000, .index = 1000 * 1000}, + {.frequency = 1152 * 1000, .index = 1000 * 1000}, + {.frequency = 1176 * 1000, .index = 1000 * 1000}, + {.frequency = 1200 * 1000, .index = 1000 * 1000}, + {.frequency = 1224 * 1000, .index = 1000 * 1000}, + {.frequency = 1248 * 1000, .index = 1000 * 1000}, + {.frequency = 1272 * 1000, .index = 1000 * 1000}, + {.frequency = 1296 * 1000, .index = 1000 * 1000}, + {.frequency = 1320 * 1000, .index = 1000 * 1000}, + {.frequency = 1344 * 1000, .index = 1000 * 1000}, + {.frequency = 1368 * 1000, .index = 1000 * 1000}, + {.frequency = 1392 * 1000, .index = 1000 * 1000}, + {.frequency = 1416 * 1000, .index = 1000 * 1000}, + {.frequency = 1440 * 1000, .index = 1000 * 1000}, + {.frequency = 1464 * 1000, .index = 1000 * 1000}, + {.frequency = 1488 * 1000, .index = 1000 * 1000}, + {.frequency = 1512 * 1000, .index = 1000 * 1000}, + {.frequency = 1536 * 1000, .index = 1000 * 1000}, + {.frequency = 1560 * 1000, .index = 1000 * 1000}, + {.frequency = 1584 * 1000, .index = 1000 * 1000}, + {.frequency = 1608 * 1000, .index = 1000 * 1000}, + {.frequency = 1632 * 1000, .index = 1000 * 1000}, + {.frequency = 1656 * 1000, .index = 1000 * 1000}, + {.frequency = 1680 * 1000, .index = 1000 * 1000}, + {.frequency = 1704 * 1000, .index = 1000 * 1000}, + {.frequency = 1728 * 1000, .index = 1000 * 1000}, + {.frequency = 1752 * 1000, .index = 1000 * 1000}, + {.frequency = 1776 * 1000, .index = 1000 * 1000}, + {.frequency = 1800 * 1000, .index = 1000 * 1000}, + {.frequency = 1824 * 1000, .index = 1000 * 1000}, + {.frequency = 1848 * 1000, .index = 1000 * 1000}, + {.frequency = 1872 * 1000, .index = 1000 * 1000}, + {.frequency = 1896 * 1000, .index = 1000 * 1000}, + {.frequency = 1920 * 1000, .index = 1000 * 1000}, + {.frequency = 1944 * 1000, .index = 1000 * 1000}, + {.frequency = 1968 * 1000, .index = 1000 * 1000}, + {.frequency = 1992 * 1000, .index = 1000 * 1000}, + {.frequency = 2016 * 1000, .index = 1000 * 1000}, + {.frequency = 2040 * 1000, .index = 1000 * 1000}, + {.frequency = 2064 * 1000, .index = 1000 * 1000}, + {.frequency = 2088 * 1000, .index = 1000 * 1000}, + {.frequency = 2112 * 1000, .index = 1000 * 1000}, + {.frequency = 2136 * 1000, .index = 1000 * 1000}, + {.frequency = 2160 * 1000, .index = 1000 * 1000}, + {.frequency = 2184 * 1000, .index = 1000 * 1000}, + {.frequency = 2208 * 1000, .index = 1000 * 1000}, + {.frequency = CPUFREQ_TABLE_END}, +}; +static int curr_mode = 0; +/***************************************************************************/ +#define FILE_GOV_MODE "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" +#define FILE_SETSPEED "/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed" +#define FILE_CUR_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" + +static int file_read(char *file_path, char *buf) +{ + struct file *file = NULL; + mm_segment_t old_fs; + loff_t offset = 0; + + PM_DBG("read %s\n", file_path); + file = filp_open(file_path, O_RDONLY, 0); + + if (IS_ERR(file)) { + PM_ERR("%s error open file %s\n", __func__, file_path); + return -1; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + file->f_op->read(file, (char *)buf, 32, &offset); + sscanf(buf, "%s", buf); + + set_fs(old_fs); + filp_close(file, NULL); + + file = NULL; + + return 0; + +} + +static int file_write(char *file_path, char *buf) +{ + struct file *file = NULL; + mm_segment_t old_fs; + loff_t offset = 0; + + PM_DBG("write %s %s size = %d\n", file_path, buf, strlen(buf)); + file = filp_open(file_path, O_RDWR, 0); + + if (IS_ERR(file)) { + PM_ERR("%s error open file %s\n", __func__, file_path); + return -1; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + file->f_op->write(file, (char *)buf, strlen(buf), &offset); + + set_fs(old_fs); + filp_close(file, NULL); + + file = NULL; + + return 0; + +} + +ssize_t maxfreq_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + char *str = buf; + str += sprintf(str, "setarmvolt [ArmVoltage(mV)]\n" + "reset\n"); + if (str != buf) + *(str - 1) = '\n'; + return (str - buf); + +} + +ssize_t maxfreq_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ + char cmd[20], gov_mode[50]; + int armVolt, i = 0; + struct clk *clk; + sscanf(buf, "%s %d", cmd, &armVolt); + + + clk = clk_get(NULL, "cpu"); + if (IS_ERR(clk)) { + PM_ERR("%s get arm clk error\n", __func__); + return n; + } + + if (0 == strncmp(cmd, "setarmvolt", strlen("setarmvolt"))) { + if (armVolt < 500000 || armVolt > 1500000) { + PM_ERR("Arm Volt = %d, out of bound\n", armVolt); + return n; + } + + PM_DBG("Get command Set Arm Volt = %d mV\n", armVolt); + if (file_read(FILE_GOV_MODE, gov_mode) != 0) { + PM_ERR("read current governor error\n"); + return n; + } else { + PM_DBG("current governor = %s\n", gov_mode); + } + + strcpy(gov_mode, "userspace"); + if (file_write(FILE_GOV_MODE, gov_mode) != 0) { + PM_ERR("set current governor error\n"); + return n; + } + + if (curr_mode == 0) { + // save normal table + PM_DBG("save dvfs normal table\n"); + dvfs_arm_table_save = dvfs_get_freq_volt_table(clk); + curr_mode = 1; + } + for (i = 0; dvfs_arm_table_maxfreq[i].frequency != CPUFREQ_TABLE_END; i++) { + dvfs_arm_table_maxfreq[i].index = armVolt; + } + + dvfs_set_freq_volt_table(clk, dvfs_arm_table_maxfreq); + clk_set_rate(clk, dvfs_arm_table_maxfreq[0].frequency * 1000); + + } else if (0 == strncmp(cmd, "reset", strlen("reset"))) { + PM_DBG("Get command reset\n"); + if (file_read(FILE_GOV_MODE, gov_mode) != 0) { + PM_ERR("read current governor error\n"); + return n; + } else { + PM_DBG("current governor = %s\n", gov_mode); + } + + dvfs_set_freq_volt_table(clk, dvfs_arm_table_save); + strcpy(gov_mode, "interactive"); + if (file_write(FILE_GOV_MODE, gov_mode) != 0) { + PM_ERR("set current governor error\n"); + return n; + } + curr_mode = 0; + } + + return n; +} + diff --git a/arch/arm/plat-rk/rk_pm_tests/maxfreq.h b/arch/arm/plat-rk/rk_pm_tests/maxfreq.h new file mode 100644 index 000000000000..9db3bde92f26 --- /dev/null +++ b/arch/arm/plat-rk/rk_pm_tests/maxfreq.h @@ -0,0 +1,8 @@ +#ifndef _MAXFREQ_H_ +#define _MAXFREQ_H_ +ssize_t maxfreq_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); +ssize_t maxfreq_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n); + +#endif diff --git a/arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c b/arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c index 88aed7b05964..e20cd5e0c333 100755 --- a/arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c +++ b/arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c @@ -50,6 +50,7 @@ REVISION 0.01 #include "clk_rate.h" #include "clk_volt.h" +#include "maxfreq.h" #include "freq_limit.h" #include "cpu_usage.h" #include "rk_suspend_test.h" @@ -78,6 +79,9 @@ static struct pm_attribute pm_attrs[] = { #ifdef CONFIG_PM_TEST_CLK_VOLT __ATTR(clk_volt, S_IRUGO | S_IWUSR, clk_volt_show, clk_volt_store), #endif +#ifdef CONFIG_PM_TEST_MAXFREQ + __ATTR(maxfreq_volt, S_IRUGO | S_IWUSR, maxfreq_show, maxfreq_store), +#endif #ifdef CONFIG_PM_TEST_FREQ_LIMIT __ATTR(freq_limit, S_IRUGO | S_IWUSR, freq_limit_show, freq_limit_store), #endif -- 2.34.1