rk30: add retry after dvfs set voltage error, and check voltage value to make sure...
authorchenxing <chenxing@rock-chips.com>
Wed, 27 Jun 2012 08:35:40 +0000 (16:35 +0800)
committerchenxing <chenxing@rock-chips.com>
Wed, 27 Jun 2012 08:35:40 +0000 (16:35 +0800)
arch/arm/mach-rk30/dvfs.c

index c4dc325eddc4eea97df9ff746b45acb631818ff6..df821d75c246e1d3f145bfc98861a67245c61bbe 100644 (file)
@@ -64,6 +64,35 @@ static void dump_dbg_map(void);
 #define PD_ON  1\r
 #define PD_OFF 0\r
 \r
+int dvfs_regulator_set_voltage_readback(struct regulator *regulator, int min_uV, int max_uV)\r
+{\r
+       int ret = 0, read_back = 0;\r
+       int retry = 3;\r
+       ret = dvfs_regulator_set_voltage(regulator, max_uV, max_uV);\r
+       if (ret < 0) {\r
+               while (ret != 0 && retry > 0) {\r
+                       DVFS_ERR("%s retrying...left %d times! regu=%p, volt=%d\n", __func__, retry, regulator, max_uV);\r
+                       mdelay(1);\r
+                       ret = dvfs_regulator_set_voltage(regulator, max_uV, max_uV);\r
+                       if (ret == 0)\r
+                               return ret;\r
+                       retry--;\r
+               }\r
+               DVFS_ERR("%s now read back to check voltage\n", __func__);\r
+\r
+               /* read back to judge if it is already effect */\r
+               mdelay(2);\r
+               read_back = dvfs_regulator_get_voltage(regulator); \r
+               if (read_back == max_uV) {\r
+                       DVFS_ERR("%s set ERROR but already effected, volt=%d\n", __func__, read_back);\r
+                       ret = 0;\r
+               } else {\r
+                       DVFS_ERR("%s set ERROR AND NOT effected, volt=%d\n", __func__, read_back);\r
+               }\r
+       }\r
+       return ret;\r
+}\r
+\r
 struct regulator* dvfs_get_regulator(char *regulator_name)\r
 {\r
        struct vd_node *vd;\r
@@ -609,7 +638,7 @@ static int dvfs_set_depend_pre(struct clk_node *dvfs_clk, unsigned long rate_old
                depend->req_volt = clk_fv.index;\r
                volt = dvfs_vd_get_newvolt_bypd(depend->dep_vd);\r
                DVFS_LOG("%s setting voltage = %d\n", __func__, volt);\r
-               ret = dvfs_regulator_set_voltage(depend->dep_vd->regulator, volt, volt);\r
+               ret = dvfs_regulator_set_voltage_readback(depend->dep_vd->regulator, volt, volt);\r
                if (0 != ret) {\r
                        DVFS_ERR("%s set voltage = %d ERROR, ret = %d\n", __func__, volt, ret);\r
                        return -1;\r
@@ -666,7 +695,7 @@ static int dvfs_set_depend_post(struct clk_node *dvfs_clk, unsigned long rate_ol
                depend->req_volt = clk_fv.index;\r
                volt = dvfs_vd_get_newvolt_bypd(depend->dep_vd);\r
                DVFS_LOG("%s setting voltage = %d\n", __func__, volt);\r
-               ret = dvfs_regulator_set_voltage(depend->dep_vd->regulator, volt, volt);\r
+               ret = dvfs_regulator_set_voltage_readback(depend->dep_vd->regulator, volt, volt);\r
                if (0 != ret) {\r
                        DVFS_ERR("%s set voltage = %d ERROR, ret = %d\n", __func__, volt, ret);\r
                        return -1;\r
@@ -767,7 +796,7 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
        /* if up the voltage */\r
        if (volt_old < volt_new) {\r
                if (!IS_ERR(dvfs_clk->vd->regulator)) {\r
-                       ret = dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_new, volt_new);\r
+                       ret = dvfs_regulator_set_voltage_readback(dvfs_clk->vd->regulator, volt_new, volt_new);\r
                        if (ret < 0) {\r
                                flag_core_set_volt_err = 1;\r
                                DVFS_ERR("%s %s set voltage up err ret = %d, Rnew = %lu(was %lu)Hz, Vnew = %d(was %d)mV\n", \r
@@ -805,7 +834,7 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
        /* if down the voltage */\r
        if (volt_old > volt_new) {\r
                if (!IS_ERR(dvfs_clk->vd->regulator)) {\r
-                       ret = dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_new, volt_new);\r
+                       ret = dvfs_regulator_set_voltage_readback(dvfs_clk->vd->regulator, volt_new, volt_new);\r
                        if (ret < 0) {\r
                                flag_core_set_volt_err = 1;\r
                                DVFS_ERR("%s %s set voltage down err ret = %d, Rnew = %lu(was %lu)Hz, Vnew = %d(was %d)mV\n", \r
@@ -898,7 +927,7 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
        /* if up the voltage */\r
        if (volt_old < volt_new) {\r
                if (!IS_ERR(dvfs_clk->vd->regulator)) {\r
-                       ret = dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_new, volt_new);\r
+                       ret = dvfs_regulator_set_voltage_readback(dvfs_clk->vd->regulator, volt_new, volt_new);\r
                        if (ret < 0) {\r
                                flag_arm_set_volt_err = 1;\r
                                DVFS_ERR("%s %s set voltage up err ret = %d, Rnew = %lu(was %lu)Hz, Vnew = %d(was %d)mV\n", \r
@@ -951,7 +980,7 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
        /* if down the voltage */\r
        if (volt_old > volt_new) {\r
                if (!IS_ERR(dvfs_clk->vd->regulator)) {\r
-                       ret = dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_new, volt_new);\r
+                       ret = dvfs_regulator_set_voltage_readback(dvfs_clk->vd->regulator, volt_new, volt_new);\r
                        if (ret < 0) {\r
                                flag_arm_set_volt_err = 1;\r
                                DVFS_ERR("%s %s set voltage down err ret = %d, Rnew = %lu(was %lu)Hz, Vnew = %d(was %d)mV\n", \r