rk: add pwm scale arm voltage support && update rk3026 test frequencies
authorchenxing <chenxing@rock-chips.com>
Tue, 8 Oct 2013 07:55:46 +0000 (15:55 +0800)
committerchenxing <chenxing@rock-chips.com>
Tue, 8 Oct 2013 07:55:46 +0000 (15:55 +0800)
arch/arm/plat-rk/rk_pm_tests/ft/Makefile
arch/arm/plat-rk/rk_pm_tests/ft/ft_pwm.c [new file with mode: 0644]
arch/arm/plat-rk/rk_pm_tests/ft/ft_pwm.h [new file with mode: 0644]
arch/arm/plat-rk/rk_pm_tests/ft/ft_test.c

index 1cbf4567ed88dd90e95df80cf9e0a6f6e45f70c3..3b36219ebc753df3ab1d6ba615858a343a3120b4 100755 (executable)
@@ -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 (file)
index 0000000..10cb1eb
--- /dev/null
@@ -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 <linux/bug.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/rk29-pwm-regulator.h>
+#include <mach/iomux.h>
+#include <linux/gpio.h>
+#include <mach/board.h>
+#include <plat/pwm.h>
+#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 (file)
index 0000000..7cbecd2
--- /dev/null
@@ -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 <linux/bug.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/rk29-pwm-regulator.h>
+#include <mach/iomux.h>
+#include <linux/gpio.h>
+#include <mach/board.h>
+#include <plat/pwm.h>
+
+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);
+
index 19cd62bf48c2f10b4039d5c13a483db514543c13..21d98c6a671035600dace71f4208fc0cab7ca6b7 100755 (executable)
@@ -49,9 +49,9 @@ REVISION 0.01
 #include <linux/kthread.h>
 #include <linux/clk.h>
 #include <linux/suspend.h>
-
 #include <linux/io.h>
 #include <linux/gpio.h>
+#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]);
                
-
-               #ifdef ENABLE_FT_TEST_GPIO
+#if FT_PWM
+               ft_pwm_set_voltage("arm", pwm_volt[steps]);
+               mdelay(5);
+#else
+#ifdef ENABLE_FT_TEST_GPIO
                // send msg to ctr board to up the volt
                gpio_request(FT_CLIENT_READY_PIN, "client ready");
                gpio_request(FT_CLIENT_IDLE_PIN, "client idle");
 
                gpio_direction_output(FT_CLIENT_READY_PIN, GPIO_HIGH);
                gpio_direction_input(FT_CLIENT_IDLE_PIN);
-               
+
                // waiting for volt upping ok 
                if((steps%2))
                        while( 0 == gpio_get_value(FT_CLIENT_IDLE_PIN));
                else
                        while( 1 == gpio_get_value(FT_CLIENT_IDLE_PIN));
-                       
-               gpio_set_value(FT_CLIENT_READY_PIN, GPIO_LOW);    
-               #endif
 
+               gpio_set_value(FT_CLIENT_READY_PIN, GPIO_LOW);
+#endif
+#endif
 
                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);