msm: clock: Add support for current to vdd_class
The regulator_set_optimum_mode() API is used by acpuclock-krait. As part
of the effort to rewrite this code using standard clock APIs, broaden
these standard APIs to allow configuring both regulator voltage and
current.
Change-Id: Ic6dfa5c0c18d1c3eb531727ee79e4f5be84e8a97
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 486842f..27bfcac 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -176,7 +176,7 @@
[VDD_DIG_HIGH] = VDD_UV(RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner);
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner, NULL);
#define RPM_MISC_CLK_TYPE 0x306b6c63
#define RPM_BUS_CLK_TYPE 0x316b6c63
@@ -2760,7 +2760,8 @@
[VDD_SR2_PLL_TUR] = VDD_UV(1800000, RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 2, vdd_sr2_levels);
+static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 2,
+ vdd_sr2_levels, NULL);
static struct pll_freq_tbl apcs_pll_freq[] = {
F_APCS_PLL( 384000000, 20, 0x0, 0x1, 0x0, 0x0, 0x0),
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index 2683d19..f44a983 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -441,7 +441,7 @@
[VDD_DIG_HIGH] = VDD_UV(RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner);
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner, NULL);
#define RPM_MISC_CLK_TYPE 0x306b6c63
#define RPM_BUS_CLK_TYPE 0x316b6c63
@@ -540,7 +540,8 @@
[VDD_SR2_PLL_TUR] = VDD_UV(1800000, RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 2, vdd_sr2_levels);
+static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 2,
+ vdd_sr2_levels, NULL);
static struct pll_freq_tbl apcs_pll_freq[] = {
F_APCS_PLL( 384000000, 20, 0x0, 0x1, 0x0, 0x0, 0x0),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index f5af727..8226f58 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -645,7 +645,7 @@
[VDD_DIG_HIGH] = VDD_UV(RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner);
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner, NULL);
#define RPM_MISC_CLK_TYPE 0x306b6c63
#define RPM_BUS_CLK_TYPE 0x316b6c63
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
index 65176b4..313e04c 100644
--- a/arch/arm/mach-msm/clock-9625.c
+++ b/arch/arm/mach-msm/clock-9625.c
@@ -287,7 +287,7 @@
[VDD_DIG_HIGH] = VDD_UV(RPM_REGULATOR_CORNER_SUPER_TURBO),
};
-static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner);
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner, NULL);
/* TODO: Needs to confirm the below values */
#define RPM_MISC_CLK_TYPE 0x306b6c63
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 2e12e27..08817c0 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -63,6 +63,7 @@
int level, rc = 0, i;
struct regulator **r = vdd_class->regulator;
int **vdd_uv = vdd_class->vdd_uv;
+ int **vdd_ua = vdd_class->vdd_ua;
int max_level = vdd_class->num_levels - 1;
for (level = max_level; level > 0; level--)
@@ -77,20 +78,36 @@
vdd_uv[max_level][i]);
if (rc)
goto set_voltage_fail;
+
+ if (!vdd_ua)
+ continue;
+
+ rc = regulator_set_optimum_mode(r[i], vdd_ua[level][i]);
+ if (rc < 0)
+ goto set_mode_fail;
}
if (vdd_class->set_vdd && !vdd_class->num_regulators)
rc = vdd_class->set_vdd(vdd_class, level);
- if (!rc)
+ if (rc < 0)
vdd_class->cur_level = level;
- return rc;
+ return 0;
+
+set_mode_fail:
+ regulator_set_voltage(r[i], vdd_uv[vdd_class->cur_level][i],
+ vdd_uv[max_level][i]);
set_voltage_fail:
- level = vdd_class->cur_level;
- for (i--; i >= 0; i--)
- regulator_set_voltage(r[i], vdd_uv[level][i],
- vdd_uv[max_level][i]);
+ for (i--; i >= 0; i--) {
+ regulator_set_voltage(r[i], vdd_uv[vdd_class->cur_level][i],
+ vdd_uv[max_level][i]);
+
+ if (!vdd_ua)
+ continue;
+ regulator_set_optimum_mode(r[i],
+ vdd_ua[vdd_class->cur_level][i]);
+ }
return rc;
}
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
index b358b53..0dd4957 100644
--- a/arch/arm/mach-msm/include/mach/clk-provider.h
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -49,6 +49,8 @@
* @set_vdd: function to call when applying a new voltage setting.
* @vdd_uv: sorted 2D array of legal voltage settings. Indexed by level, then
regulator.
+ * @vdd_ua: sorted 2D array of legal cureent settings. Indexed by level, then
+ regulator. Optional parameter.
* @level_votes: array of votes for each level.
* @num_levels: specifies the size of level_votes array.
* @cur_level: the currently set voltage level
@@ -60,6 +62,7 @@
int num_regulators;
int (*set_vdd)(struct clk_vdd_class *v_class, int level);
int **vdd_uv;
+ int **vdd_ua;
int *level_votes;
int num_levels;
unsigned long cur_level;
@@ -76,10 +79,12 @@
.lock = __MUTEX_INITIALIZER(_name.lock) \
}
-#define DEFINE_VDD_REGULATORS(_name, _num_levels, _num_regulators, _vdd_uv) \
+#define DEFINE_VDD_REGULATORS(_name, _num_levels, _num_regulators, _vdd_uv, \
+ _vdd_ua) \
struct clk_vdd_class _name = { \
.class_name = #_name, \
.vdd_uv = _vdd_uv, \
+ .vdd_ua = _vdd_ua, \
.regulator = (struct regulator * [_num_regulators]) {}, \
.num_regulators = _num_regulators, \
.level_votes = (int [_num_levels]) {}, \
@@ -89,6 +94,7 @@
}
#define VDD_UV(...) ((int []){__VA_ARGS__})
+#define VDD_UA(...) ((int []){__VA_ARGS__})
enum handoff {
HANDOFF_ENABLED_CLK,