From: chenxing Date: Tue, 8 Oct 2013 07:55:46 +0000 (+0800) Subject: rk: add pwm scale arm voltage support && update rk3026 test frequencies X-Git-Tag: firefly_0821_release~6579 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6eb352d2006f58dadf115f8d41561115485bd5cd;p=firefly-linux-kernel-4.4.55.git rk: add pwm scale arm voltage support && update rk3026 test frequencies --- diff --git a/arch/arm/plat-rk/rk_pm_tests/ft/Makefile b/arch/arm/plat-rk/rk_pm_tests/ft/Makefile index 1cbf4567ed88..3b36219ebc75 100755 --- a/arch/arm/plat-rk/rk_pm_tests/ft/Makefile +++ b/arch/arm/plat-rk/rk_pm_tests/ft/Makefile @@ -1,3 +1,4 @@ obj-y += ft_cpu_tst.o obj-y += ft_cpu_tst1.o obj-y += ft_test.o +obj-y += ft_pwm.o diff --git a/arch/arm/plat-rk/rk_pm_tests/ft/ft_pwm.c b/arch/arm/plat-rk/rk_pm_tests/ft/ft_pwm.c new file mode 100644 index 000000000000..10cb1eb0a688 --- /dev/null +++ b/arch/arm/plat-rk/rk_pm_tests/ft/ft_pwm.c @@ -0,0 +1,178 @@ +/* + * + * Copyright (C) 2013 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ft_pwm.h" +#if 0 +#define DBG(x...) printk(KERN_INFO x) +#else +#define DBG(x...) +#endif + +#if defined(CONFIG_SOC_RK3168) || defined(CONFIG_SOC_RK3168M) || defined(CONFIG_ARCH_RK3188) || defined(CONFIG_ARCH_RK3026) +const static int pwm_voltage_map[] = { + 800000,825000,850000, 875000,900000, 925000 ,950000, 975000,1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000,1375000 +}; +#else +const static int pwm_voltage_map[] = { + 950000, 975000,1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000 +}; +#endif +#if 0 +struct ft_pwm_data { + int pwm_id; + char* gpio_name; + char* pwm_iomux_name; + unsigned int pwm_gpio; + unsigned int pwm_iomux_pwm; + unsigned int pwm_iomux_gpio; + int pwm_voltage; + int suspend_voltage; + int min_uV; + int max_uV; + int coefficient; + const int *pwm_voltage_map; +}; +#endif +static struct ft_pwm_data ft_pwm[2] = { + { + .pwm_id = 0, + .min_uV = 820000, + .max_uV = 1380000, + .coefficient = 560, //56% + .pwm_voltage_map = pwm_voltage_map, + }, { + .pwm_id = 1, + .min_uV = 820000, + .max_uV = 1380000, + .coefficient = 560, //56% + .pwm_voltage_map = pwm_voltage_map, + }, +}; + +int ft_pwm_set_rate(struct ft_pwm_data* pwm, int nHz, u32 rate) +{ + u32 lrc, hrc; + unsigned long clkrate; + + clkrate = clk_get_rate(clk_get(NULL, "pwm01")); + + printk("%s: out_rate=%d, get clkrate=%lu\n", __func__, nHz, clkrate); + gpio_request(pwm->pwm_gpio, "ft pwm gpio"); + if (rate == 0) { + // iomux pwm to gpio + rk30_mux_api_set(pwm->gpio_name, pwm->pwm_iomux_gpio); + //disable pull up or down + gpio_pull_updown(pwm->pwm_gpio, PullDisable); + // set gpio to low level + gpio_direction_output(pwm->pwm_gpio, GPIO_LOW); + + } else if (rate < 100) { + // iomux pwm to gpio + lrc = clkrate / nHz; + lrc = lrc >> (1 + (PWM_DIV >> 9)); + lrc = lrc ? lrc : 1; + hrc = lrc * rate / 100; + hrc = hrc ? hrc : 1; + + // iomux pwm + rk30_mux_api_set(pwm->pwm_iomux_name, pwm->pwm_iomux_pwm); + + printk("%s: lrc=%d, hrc=%d\n", __func__, lrc, hrc); + rk_pwm_setup(pwm->pwm_id, PWM_DIV, hrc, lrc); + + } else if (rate == 100) { + // iomux pwm to gpio + rk30_mux_api_set(pwm->gpio_name, pwm->pwm_iomux_gpio); + //disable pull up or down + gpio_pull_updown(pwm->pwm_gpio, PullDisable); + // set gpio to low level + gpio_direction_output(pwm->pwm_gpio, GPIO_HIGH); + + } else { + printk("%s:rate error\n",__func__); + return -1; + } + + usleep_range(10 * 1000, 10 * 1000); + + return (0); +} + +int ft_pwm_regulator_get_voltage(char* name) +{ + DBG("%s: get %s voltage\n", __func__, name); + + return 0; +} + +int ft_pwm_set_voltage(char *name, int vol) +{ + int ret = 0; + // VDD12 = 1.40 - 0.455*D , 其中D为PWM占空比, + int pwm_value, pwm_id = 0; + + if (strcmp(name, "arm") == 0) { + pwm_id = 0; + + } else if (strcmp(name, "logic") == 0) { + pwm_id = 1; + + } else { + printk("unknown name"); + return -EINVAL; + } + + printk("%s: name=%s, pwm_id=%d, vol=%d\n", __func__, name, pwm_id, vol); + /* pwm_value %, coefficient * 1000 */ + pwm_value = (ft_pwm[pwm_id].max_uV - vol) / ft_pwm[pwm_id].coefficient / 10; + printk("%s: name=%s, pwm_id=%d, duty=%d%%, [min,max]=[%d, %d], coefficient=%d\n", + __func__, name, pwm_id, pwm_value, + ft_pwm[pwm_id].min_uV, + ft_pwm[pwm_id].max_uV, + ft_pwm[pwm_id].coefficient); + ret = ft_pwm_set_rate(&ft_pwm[pwm_id], 1000 * 1000, pwm_value); + + if (ret != 0) { + printk("%s: fail to set pwm rate, pwm_value = %d\n", __func__, pwm_value); + return -1; + } + + return 0; + + +} +static int pwm_mode[] = {PWM0, PWM1, PWM2}; +void ft_pwm_init(void) +{ + int i = 0; + for (i = 0; i < ARRAY_SIZE(ft_pwm); i++) { + ft_pwm[i].pwm_gpio = iomux_mode_to_gpio(pwm_mode[ft_pwm[i].pwm_id]); + ft_pwm[i].pwm_iomux_pwm = pwm_mode[ft_pwm[i].pwm_id]; + ft_pwm[i].pwm_iomux_gpio = iomux_switch_gpio_mode(pwm_mode[ft_pwm[i].pwm_id]); + } +} diff --git a/arch/arm/plat-rk/rk_pm_tests/ft/ft_pwm.h b/arch/arm/plat-rk/rk_pm_tests/ft/ft_pwm.h new file mode 100644 index 000000000000..7cbecd2c54b6 --- /dev/null +++ b/arch/arm/plat-rk/rk_pm_tests/ft/ft_pwm.h @@ -0,0 +1,49 @@ +/* + * + * Copyright (C) 2013 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ft_pwm_data { + int pwm_id; + char* gpio_name; + char* pwm_iomux_name; + unsigned int pwm_gpio; + unsigned int pwm_iomux_pwm; + unsigned int pwm_iomux_gpio; + int pwm_voltage; + int suspend_voltage; + int min_uV; + int max_uV; + int coefficient; + const int *pwm_voltage_map; +}; + +int ft_pwm_set_rate(struct ft_pwm_data* pwm, int nHz, u32 rate); +int ft_pwm_regulator_get_voltage(char* name); +int ft_pwm_set_voltage(char *name, int vol); +void ft_pwm_init(void); + diff --git a/arch/arm/plat-rk/rk_pm_tests/ft/ft_test.c b/arch/arm/plat-rk/rk_pm_tests/ft/ft_test.c index 19cd62bf48c2..21d98c6a6710 100755 --- a/arch/arm/plat-rk/rk_pm_tests/ft/ft_test.c +++ b/arch/arm/plat-rk/rk_pm_tests/ft/ft_test.c @@ -49,9 +49,9 @@ REVISION 0.01 #include #include #include - #include #include +#include "ft_pwm.h" #if 0 @@ -75,6 +75,9 @@ REVISION 0.01 #define ft_printk_info(fmt, arg...) {while(0);} #endif +#define FT_PWM 0 + +int pwm_volt[5] = {900000, 1250000, 1350000, 0, 0}; #define MHZ (1000*1000) #define TST_SETUPS (4) @@ -138,7 +141,7 @@ const static unsigned long l2_cpy_cnt[TST_SETUPS]={5*3,5*4,0,0}; #elif defined(CONFIG_ARCH_RK3026) -const static unsigned long arm_setups_rate[4] = {312 * MHZ, 816 * MHZ, 0, 0}; +const static unsigned long arm_setups_rate[4] = {312 * MHZ, 816 * MHZ, 1008 * MHZ, 0}; const static unsigned long l1_tst_cnt[TST_SETUPS]={5 * 10, 5 * 10, 0, 0}; const static unsigned long l2_cpy_cnt[TST_SETUPS]={5 * 3, 5 * 4, 0, 0}; @@ -510,6 +513,10 @@ void ft_cpu_test_type0(int steps) ft_printk_dbg("test typ0 step%d cpu=%d start\n",steps,cpu); //arm rate init ft_cpu_l1_test(l1_tst_cnt[steps]); +#if FT_PWM + ft_pwm_set_voltage("arm", pwm_volt[0]); + mdelay(5); +#endif per_cpu(cpu_tst_flags, cpu)&=~setup_l1_bits[steps]; //temp=ft_test_cpus_l2(l2_test_buf[cpu],sizeof(char)*BUF_SIZE,20); @@ -534,8 +541,9 @@ int ft_cpu_test_type0_check(int steps,const char *str) for (cpu = 0; cpu < NR_CPUS; cpu++) { ret|=per_cpu(cpu_tst_flags, cpu); - ft_printk_dbg("setup%d,cpu%d flags=%x(%x)\n",steps,cpu,per_cpu(cpu_tst_flags, cpu)&setup_bits_msk[steps], - per_cpu(cpu_tst_flags, cpu)); + ft_printk_dbg("setup%d,cpu%d flags=%x(%x)\n", + steps, cpu, per_cpu(cpu_tst_flags, cpu) & setup_bits_msk[steps], + per_cpu(cpu_tst_flags, cpu)); } ret&=setup_bits_msk[steps];// test setup1 @@ -607,24 +615,27 @@ int ft_cpu_test_type1_check(int steps,const char *str) if(arm_setups_rate[steps]=rate) clk_set_rate(arm_clk,arm_setups_rate[steps]); @@ -640,8 +651,9 @@ int ft_cpu_test_type1_check(int steps,const char *str) for (cpu = 0; cpu < NR_CPUS; cpu++) { ret|=per_cpu(cpu_tst_flags, cpu); - ft_printk_dbg("setup%d,cpu%d flags=%x(%x)\n",steps,cpu,per_cpu(cpu_tst_flags, cpu)&setup_bits_msk[steps], - per_cpu(cpu_tst_flags, cpu)); + ft_printk_dbg("setup%d,cpu%d flags=%x(%x)\n", + steps, cpu, per_cpu(cpu_tst_flags, cpu) & setup_bits_msk[steps], + per_cpu(cpu_tst_flags, cpu)); } ret&=setup_bits_msk[steps];// test setup2 @@ -692,6 +704,7 @@ static int __init rk_ft_tests_init(void) char *buf; arm_clk=clk_get(NULL, "cpu"); + ft_pwm_init(); for (cpu = 0; cpu < NR_CPUS; cpu++) { l2_test_mbuf[cpu]=NULL; buf = kmalloc(BUF_SIZE_M, GFP_KERNEL);