* [PATCH 01/12] OMAP OPP: remove some unnecessary variables
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-18 17:28 ` Kevin Hilman
2009-12-18 0:47 ` [PATCH 02/12] OMAP OPP: split opp_find_freq_approx() into opp_find_freq_{floor, ceil}() Paul Walmsley
` (10 subsequent siblings)
11 siblings, 1 reply; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
No need to allocate new variables; the passed-in OPP list pointers do nicely
as iterators.
---
arch/arm/plat-omap/include/plat/opp.h | 2 +
arch/arm/plat-omap/opp.c | 52 +++++++++++++++------------------
2 files changed, 24 insertions(+), 30 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
index 5d5d21b..f340928 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -60,7 +60,7 @@ unsigned long opp_get_freq(const struct omap_opp *opp);
* This functions returns the number of opps if there are any OPPs enabled,
* else returns corresponding error value.
*/
-int opp_get_opp_count(const struct omap_opp *oppl);
+int opp_get_opp_count(struct omap_opp *oppl);
/**
* opp_find_freq_exact() - search for an exact frequency
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index c4dc07b..4c581c7 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -62,21 +62,19 @@ unsigned long opp_get_freq(const struct omap_opp *opp)
return opp->rate;
}
-int opp_get_opp_count(const struct omap_opp *oppl)
+int opp_get_opp_count(struct omap_opp *oppl)
{
- struct omap_opp *opp;
u8 n = 0;
if (unlikely(!oppl || IS_ERR(oppl))) {
pr_err("%s: Invalid parameters being passed\n", __func__);
return -EINVAL;
}
- opp = (struct omap_opp *)oppl;
- opp++; /* skip initial terminator */
- while (!OPP_TERM(opp)) {
- if (opp->enabled)
+ oppl++; /* skip initial terminator */
+ while (!OPP_TERM(oppl)) {
+ if (oppl->enabled)
n++;
- opp++;
+ oppl++;
}
return n;
}
@@ -84,54 +82,50 @@ int opp_get_opp_count(const struct omap_opp *oppl)
struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
unsigned long freq, bool enabled)
{
- struct omap_opp *opp = (struct omap_opp *)oppl;
-
if (unlikely(!oppl || IS_ERR(oppl))) {
pr_err("%s: Invalid parameters being passed\n", __func__);
return ERR_PTR(-EINVAL);
}
/* skip initial terminator */
- if (OPP_TERM(opp))
- opp++;
- while (!OPP_TERM(opp)) {
- if ((opp->rate == freq) && (opp->enabled == enabled))
+ if (OPP_TERM(oppl))
+ oppl++;
+ while (!OPP_TERM(oppl)) {
+ if ((oppl->rate == freq) && (oppl->enabled == enabled))
break;
- opp++;
+ oppl++;
}
- return OPP_TERM(opp) ? ERR_PTR(-ENOENT) : opp;
+ return OPP_TERM(oppl) ? ERR_PTR(-ENOENT) : oppl;
}
struct omap_opp *opp_find_freq_approx(struct omap_opp *oppl,
unsigned long *freq, u8 dir_flag)
{
- struct omap_opp *opp = (struct omap_opp *)oppl;
-
if (unlikely(!oppl || IS_ERR(oppl) || !freq || IS_ERR(freq))) {
pr_err("%s: Invalid parameters being passed\n", __func__);
return ERR_PTR(-EINVAL);
}
/* skip initial terminator */
- if (OPP_TERM(opp)) {
- opp++;
+ if (OPP_TERM(oppl)) {
+ oppl++;
/* If searching init list for a high val, skip to very top */
if (dir_flag == OPP_SEARCH_LOW)
- while (!OPP_TERM(opp + 1))
- opp++;
+ while (!OPP_TERM(oppl + 1))
+ oppl++;
}
- while (!OPP_TERM(opp)) {
- if (opp->enabled &&
- (((dir_flag == OPP_SEARCH_HIGH) && (opp->rate >= *freq)) ||
- ((dir_flag == OPP_SEARCH_LOW) && (opp->rate <= *freq))))
+ while (!OPP_TERM(oppl)) {
+ if (oppl->enabled &&
+ (((dir_flag == OPP_SEARCH_HIGH) && (oppl->rate >= *freq)) ||
+ ((dir_flag == OPP_SEARCH_LOW) && (oppl->rate <= *freq))))
break;
- opp += (dir_flag == OPP_SEARCH_LOW) ? -1 : 1;
+ oppl += (dir_flag == OPP_SEARCH_LOW) ? -1 : 1;
}
- if (OPP_TERM(opp))
+ if (OPP_TERM(oppl))
return ERR_PTR(-ENOENT);
- *freq = opp->rate;
- return opp;
+ *freq = oppl->rate;
+ return oppl;
}
/* wrapper to reuse converting opp_def to opp struct */
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 02/12] OMAP OPP: split opp_find_freq_approx() into opp_find_freq_{floor, ceil}()
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
2009-12-18 0:47 ` [PATCH 01/12] OMAP OPP: remove some unnecessary variables Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-18 0:47 ` [PATCH 03/12] OMAP OPP: only traverse opp_find_freq_floor() once Paul Walmsley
` (9 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
Split opp_find_freq_approx() into opp_find_freq_{floor,ceil}(). This seems
more readable.
---
arch/arm/mach-omap2/clock34xx.c | 3 -
arch/arm/mach-omap2/resource34xx.c | 8 +---
arch/arm/plat-omap/cpu-omap.c | 3 -
arch/arm/plat-omap/include/plat/opp.h | 67 +++++++++++++++++++--------------
arch/arm/plat-omap/opp.c | 52 +++++++++++++++++++++-----
5 files changed, 86 insertions(+), 47 deletions(-)
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 4862594..ba3dd70 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -293,8 +293,7 @@ void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
return;
}
- while (!IS_ERR(opp = opp_find_freq_approx(opp, &freq,
- OPP_SEARCH_LOW))) {
+ while (!IS_ERR(opp = opp_find_freq_floor(opp, &freq))) {
freq_table[i].index = i;
freq_table[i].frequency = freq / 1000;
i++;
diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index 1f2c713..baa33c4 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -207,7 +207,7 @@ static int __deprecated freq_to_opp(u8 *opp_id, struct omap_opp *opps,
struct omap_opp *opp;
BUG_ON(!opp_id || !opps);
- opp = opp_find_freq_approx(opps, &freq, OPP_SEARCH_HIGH);
+ opp = opp_find_freq_ceil(opps, &freq);
if (IS_ERR(opp))
return -EINVAL;
*opp_id = opp->opp_id;
@@ -476,13 +476,11 @@ int set_opp(struct shared_resource *resp, u32 target_level)
req_l3_freq = (target_level * 1000)/4;
/* Do I have a best match? */
- oppx = opp_find_freq_approx(l3_opps, &req_l3_freq,
- OPP_SEARCH_HIGH);
+ oppx = opp_find_freq_ceil(l3_opps, &req_l3_freq);
if (IS_ERR(oppx)) {
/* Give me the best we got */
req_l3_freq = ULONG_MAX;
- oppx = opp_find_freq_approx(l3_opps,
- &req_l3_freq, OPP_SEARCH_LOW);
+ oppx = opp_find_freq_floor(l3_opps, &req_l3_freq);
}
/* uh uh.. no OPPs?? */
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 9603360..a2b5ee4 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -112,8 +112,7 @@ static int omap_target(struct cpufreq_policy *policy,
#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
if (mpu_opps) {
unsigned long freq = target_freq * 1000;
- if (!IS_ERR(opp_find_freq_approx(mpu_opps, &freq,
- OPP_SEARCH_HIGH)))
+ if (!IS_ERR(opp_find_freq_ceil(mpu_opps, &freq)))
omap_pm_cpu_set_freq(freq);
}
#endif
diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
index f340928..2a7c113 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -79,35 +79,23 @@ int opp_get_opp_count(struct omap_opp *oppl);
struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
unsigned long freq, bool enabled);
-#define OPP_SEARCH_HIGH (0 << 1)
-#define OPP_SEARCH_LOW (1 << 1)
+/* XXX This documentation needs fixing */
+
/**
- * opp_find_freq_approx() - Search for an rounded freq
+ * opp_find_freq_floor() - Search for an rounded freq
* @oppl: Starting list
* @freq: Start frequency
- * @dir_flag: Search direction
- * OPP_SEARCH_HIGH - search for next highest freq
- * OPP_SEARCH_LOW - search for next lowest freq
*
- * Search for the higher/lower *enabled* OPP from a starting freq
+ * Search for the lower *enabled* OPP from a starting freq
* from a start opp list.
*
- * Returns *opp and *freq is populated with the next match,
- * else returns NULL
- * opp if found, else returns ERR_PTR in case of error.
+ * Returns *opp and *freq is populated with the next match, else
+ * returns NULL opp if found, else returns ERR_PTR in case of error.
*
* Example usages:
- * * find match/next highest available frequency
- * freq = 350000;
- * opp = opp_find_freq_approx(oppl, &freq, OPP_SEARCH_HIGH)))
- * if (IS_ERR(opp))
- * pr_err ("unable to find a higher frequency\n");
- * else
- * pr_info("match freq = %ld\n", freq);
- *
* * find match/next lowest available frequency
* freq = 350000;
- * opp = opp_find_freq_approx(oppl, &freq, OPP_SEARCH_LOW)))
+ * opp = opp_find_freq_floor(oppl, &freq)))
* if (IS_ERR(opp))
* pr_err ("unable to find a lower frequency\n");
* else
@@ -116,26 +104,49 @@ struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
* * print all supported frequencies in descending order *
* opp = oppl;
* freq = ULONG_MAX;
- * while (!IS_ERR(opp = opp_find_freq_approx(opp, &freq,
- * OPP_SEARCH_LOW))) {
+ * while (!IS_ERR(opp = opp_find_freq_floor(opp, &freq)) {
* pr_info("freq = %ld\n", freq);
* freq--; * for next lower match *
* }
*
+ * NOTE: if we set freq as ULONG_MAX and search low, we get the
+ * highest enabled frequency
+ */
+struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl,
+ unsigned long *freq);
+
+/* XXX This documentation needs fixing */
+
+/**
+ * opp_find_freq_ceil() - Search for an rounded freq
+ * @oppl: Starting list
+ * @freq: Start frequency
+ *
+ * Search for the higher *enabled* OPP from a starting freq
+ * from a start opp list.
+ *
+ * Returns *opp and *freq is populated with the next match, else
+ * returns NULL opp if found, else returns ERR_PTR in case of error.
+ *
+ * Example usages:
+ * * find match/next highest available frequency
+ * freq = 350000;
+ * opp = opp_find_freq_ceil(oppl, &freq))
+ * if (IS_ERR(opp))
+ * pr_err ("unable to find a higher frequency\n");
+ * else
+ * pr_info("match freq = %ld\n", freq);
+ *
* * print all supported frequencies in ascending order *
* opp = oppl;
* freq = 0;
- * while (!IS_ERR(opp = opp_find_freq_approx(opp, &freq,
- * OPP_SEARCH_HIGH))) {
+ * while (!IS_ERR(opp = opp_find_freq_ceil(opp, &freq)) {
* pr_info("freq = %ld\n", freq);
* freq++; * for next higher match *
* }
- *
- * NOTE: if we set freq as ULONG_MAX and search low, we get the highest enabled
- * frequency
*/
-struct omap_opp *opp_find_freq_approx(struct omap_opp *oppl,
- unsigned long *freq, u8 dir_flag);
+struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq);
+
/**
* struct omap_opp_def - OMAP OPP Definition
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 4c581c7..fc250b8 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -98,33 +98,65 @@ struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
return OPP_TERM(oppl) ? ERR_PTR(-ENOENT) : oppl;
}
-struct omap_opp *opp_find_freq_approx(struct omap_opp *oppl,
- unsigned long *freq, u8 dir_flag)
+struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq)
{
if (unlikely(!oppl || IS_ERR(oppl) || !freq || IS_ERR(freq))) {
pr_err("%s: Invalid parameters being passed\n", __func__);
return ERR_PTR(-EINVAL);
}
+
+ /* skip initial terminator */
+ if (OPP_TERM(oppl))
+ oppl++;
+
+ while (!OPP_TERM(oppl)) {
+ if (oppl->enabled && oppl->rate >= *freq)
+ break;
+
+ oppl++;
+ }
+
+ if (OPP_TERM(oppl))
+ return ERR_PTR(-ENOENT);
+
+ *freq = oppl->rate;
+
+ return oppl;
+}
+
+struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl, unsigned long *freq)
+{
+ if (unlikely(!oppl || IS_ERR(oppl) || !freq || IS_ERR(freq))) {
+ pr_err("%s: Invalid parameters being passed\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
/* skip initial terminator */
if (OPP_TERM(oppl)) {
oppl++;
/* If searching init list for a high val, skip to very top */
- if (dir_flag == OPP_SEARCH_LOW)
- while (!OPP_TERM(oppl + 1))
- oppl++;
+ /*
+ * XXX What is the point of this? If one is going to traverse
+ * the list, might as well do what we need to do during the
+ * traversal.
+ */
+ while (!OPP_TERM(oppl)) /* XXX above */
+ oppl++;
}
- while (!OPP_TERM(oppl)) {
- if (oppl->enabled &&
- (((dir_flag == OPP_SEARCH_HIGH) && (oppl->rate >= *freq)) ||
- ((dir_flag == OPP_SEARCH_LOW) && (oppl->rate <= *freq))))
+
+ while (!OPP_TERM(--oppl)) {
+ if (!oppl->enabled)
+ continue;
+
+ if (oppl->rate <= *freq)
break;
- oppl += (dir_flag == OPP_SEARCH_LOW) ? -1 : 1;
}
if (OPP_TERM(oppl))
return ERR_PTR(-ENOENT);
*freq = oppl->rate;
+
return oppl;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 03/12] OMAP OPP: only traverse opp_find_freq_floor() once
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
2009-12-18 0:47 ` [PATCH 01/12] OMAP OPP: remove some unnecessary variables Paul Walmsley
2009-12-18 0:47 ` [PATCH 02/12] OMAP OPP: split opp_find_freq_approx() into opp_find_freq_{floor, ceil}() Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-19 12:10 ` Menon, Nishanth
2009-12-18 0:47 ` [PATCH 04/12] OMAP TWL/TPS OPP: move TWL/TPS-specific code to its own file Paul Walmsley
` (8 subsequent siblings)
11 siblings, 1 reply; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
There's no point traversing the OPP list twice in opp_find_freq_floor().
---
arch/arm/plat-omap/opp.c | 30 +++++++++++++-----------------
1 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index fc250b8..e9f5706 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -126,36 +126,32 @@ struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq)
struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl, unsigned long *freq)
{
+ struct omap_opp *prev_opp = oppl;
+
if (unlikely(!oppl || IS_ERR(oppl) || !freq || IS_ERR(freq))) {
pr_err("%s: Invalid parameters being passed\n", __func__);
return ERR_PTR(-EINVAL);
}
/* skip initial terminator */
- if (OPP_TERM(oppl)) {
+ if (OPP_TERM(oppl))
oppl++;
- /* If searching init list for a high val, skip to very top */
- /*
- * XXX What is the point of this? If one is going to traverse
- * the list, might as well do what we need to do during the
- * traversal.
- */
- while (!OPP_TERM(oppl)) /* XXX above */
- oppl++;
- }
- while (!OPP_TERM(--oppl)) {
- if (!oppl->enabled)
- continue;
+ while (!OPP_TERM(oppl)) {
+ if (oppl->enabled) {
+ if (oppl->rate > *freq)
+ break;
- if (oppl->rate <= *freq)
- break;
+ prev_opp = oppl;
+ }
+
+ oppl++;
}
- if (OPP_TERM(oppl))
+ if (prev_opp->rate > *freq)
return ERR_PTR(-ENOENT);
- *freq = oppl->rate;
+ *freq = prev_opp->rate;
return oppl;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 04/12] OMAP TWL/TPS OPP: move TWL/TPS-specific code to its own file
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
` (2 preceding siblings ...)
2009-12-18 0:47 ` [PATCH 03/12] OMAP OPP: only traverse opp_find_freq_floor() once Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-19 12:14 ` Menon, Nishanth
2009-12-18 0:47 ` [PATCH 05/12] OMAP TWL/TPS OPP: vsel rounding belongs in opp_twl_tps.c Paul Walmsley
` (7 subsequent siblings)
11 siblings, 1 reply; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
The OPP layer code should be independent of the PMIC, so move
the TWL/TPS-specific code out to its own file.
---
arch/arm/plat-omap/Makefile | 4 ++-
arch/arm/plat-omap/include/plat/opp_twl_tps.h | 21 ++++++++++++++
arch/arm/plat-omap/opp.c | 27 +++---------------
arch/arm/plat-omap/opp_twl_tps.c | 38 +++++++++++++++++++++++++
4 files changed, 66 insertions(+), 24 deletions(-)
create mode 100644 arch/arm/plat-omap/include/plat/opp_twl_tps.h
create mode 100644 arch/arm/plat-omap/opp_twl_tps.c
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index e9cf601..b0c5b31 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -13,7 +13,9 @@ obj- :=
obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
# OPP support in (OMAP3+ only at the moment)
-obj-$(CONFIG_ARCH_OMAP3) += opp.o
+# XXX The OPP TWL/TPS code should only be included when a TWL/TPS
+# PMIC is selected.
+obj-$(CONFIG_ARCH_OMAP3) += opp.o opp_twl_tps.o
# omap_device support (OMAP2+ only at the moment)
obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
diff --git a/arch/arm/plat-omap/include/plat/opp_twl_tps.h b/arch/arm/plat-omap/include/plat/opp_twl_tps.h
new file mode 100644
index 0000000..8784e5f
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/opp_twl_tps.h
@@ -0,0 +1,21 @@
+/*
+ * opp_twl_tps.h - TWL/TPS-specific headers for the OPP code
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated.
+ * Nishanth Menon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This code belongs as part of some other TWL/TPS code.
+ */
+#ifndef _ARCH_ARM_PLAT_OMAP_OPP_TWL_TPS_H
+#define _ARCH_ARM_PLAT_OMAP_OPP_TWL_TPS_H
+
+#include <linux/kernel.h>
+
+unsigned long omap_twl_vsel_to_uv(const u8 vsel);
+u8 omap_twl_uv_to_vsel(unsigned long uV);
+
+#endif
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index e9f5706..9586e3b 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/slab.h>
+#include <plat/opp_twl_tps.h>
#include <plat/opp.h>
/*
@@ -24,33 +25,13 @@
*/
#define OPP_TERM(opp) (!(opp)->rate && !(opp)->vsel && !(opp)->enabled)
-/*
- * DEPRECATED: Meant to convert vsel value to uVolt
- * This is meant to help co-exist with current SRF etc
- * TODO: REMOVE!
- */
-static inline unsigned long vsel_to_uv(const u8 vsel)
-{
- return (((vsel * 125) + 6000)) * 100;
-}
-
-/*
- * DEPRECATED: Meant to convert uVolt to vsel value
- * This is meant to help co-exist with current SRF etc
- * TODO: REMOVE!
- */
-static inline unsigned char uv_to_vsel(unsigned long uV)
-{
- return ((uV / 100) - 6000) / 125;
-}
-
unsigned long opp_get_voltage(const struct omap_opp *opp)
{
if (unlikely(!opp || IS_ERR(opp)) || !opp->enabled) {
pr_err("%s: Invalid parameters being passed\n", __func__);
return 0;
}
- return vsel_to_uv(opp->vsel);
+ return omap_twl_vsel_to_uv(opp->vsel);
}
unsigned long opp_get_freq(const struct omap_opp *opp)
@@ -162,9 +143,9 @@ static void omap_opp_populate(struct omap_opp *opp,
{
opp->rate = opp_def->freq;
opp->enabled = opp_def->enabled;
- opp->vsel = uv_to_vsel(opp_def->u_volt);
+ opp->vsel = omap_twl_uv_to_vsel(opp_def->u_volt);
/* round off to higher voltage */
- if (opp_def->u_volt > vsel_to_uv(opp->vsel))
+ if (opp_def->u_volt > omap_twl_vsel_to_uv(opp->vsel))
opp->vsel++;
}
diff --git a/arch/arm/plat-omap/opp_twl_tps.c b/arch/arm/plat-omap/opp_twl_tps.c
new file mode 100644
index 0000000..edcb719
--- /dev/null
+++ b/arch/arm/plat-omap/opp_twl_tps.c
@@ -0,0 +1,38 @@
+/*
+ * opp_twl_tps.c - TWL/TPS-specific functions for the OPP code
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated.
+ * Nishanth Menon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This code should be part of some other TWL/TPS code.
+ */
+
+#include <plat/opp_twl_tps.h>
+
+/**
+ * omap_twl_vsel_to_vdc - convert TWL/TPS VSEL value to microvolts DC
+ * @vsel: TWL/TPS VSEL value to convert
+ *
+ * Returns the microvolts DC that the TWL/TPS family of PMICs should
+ * generate when programmed with @vsel.
+ */
+unsigned long omap_twl_vsel_to_uv(const u8 vsel)
+{
+ return (((vsel * 125) + 6000)) * 100;
+}
+
+/**
+ * omap_twl_uv_to_vsel - convert microvolts DC to TWL/TPS VSEL value
+ * @uv: microvolts DC to convert
+ *
+ * Returns the VSEL value necessary for the TWL/TPS family of PMICs to
+ * generate an output voltage equal to or greater than @uv microvolts DC.
+ */
+u8 omap_twl_uv_to_vsel(unsigned long uv)
+{
+ return ((uv / 100) - 6000) / 125;
+}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 05/12] OMAP TWL/TPS OPP: vsel rounding belongs in opp_twl_tps.c
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
` (3 preceding siblings ...)
2009-12-18 0:47 ` [PATCH 04/12] OMAP TWL/TPS OPP: move TWL/TPS-specific code to its own file Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-19 12:16 ` Menon, Nishanth
2009-12-18 0:47 ` [PATCH 06/12] OMAP OPP: add microvolts DC ("u_volt") field into struct omap_opp Paul Walmsley
` (6 subsequent siblings)
11 siblings, 1 reply; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
The vsel roundoff code belongs in omap_twl_uv_to_vsel(), not
omap_opp_populate(), since other code may use omap_twl_uv_to_vsel().
---
arch/arm/plat-omap/opp.c | 3 ---
arch/arm/plat-omap/opp_twl_tps.c | 15 +++++++++++++--
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 9586e3b..2543932 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -144,9 +144,6 @@ static void omap_opp_populate(struct omap_opp *opp,
opp->rate = opp_def->freq;
opp->enabled = opp_def->enabled;
opp->vsel = omap_twl_uv_to_vsel(opp_def->u_volt);
- /* round off to higher voltage */
- if (opp_def->u_volt > omap_twl_vsel_to_uv(opp->vsel))
- opp->vsel++;
}
struct omap_opp *opp_add(struct omap_opp *oppl,
diff --git a/arch/arm/plat-omap/opp_twl_tps.c b/arch/arm/plat-omap/opp_twl_tps.c
index edcb719..e0db39b 100644
--- a/arch/arm/plat-omap/opp_twl_tps.c
+++ b/arch/arm/plat-omap/opp_twl_tps.c
@@ -2,7 +2,9 @@
* opp_twl_tps.c - TWL/TPS-specific functions for the OPP code
*
* Copyright (C) 2009 Texas Instruments Incorporated.
- * Nishanth Menon
+ * Nishanth Menon
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,5 +36,14 @@ unsigned long omap_twl_vsel_to_uv(const u8 vsel)
*/
u8 omap_twl_uv_to_vsel(unsigned long uv)
{
- return ((uv / 100) - 6000) / 125;
+ u8 vsel;
+
+ vsel = ((uv / 100) - 6000) / 125;
+
+ /* round off to higher voltage */
+ /* XXX Surely not the best way to handle this. */
+ if (uv > omap_twl_vsel_to_uv(vsel))
+ vsel++;
+
+ return vsel;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 06/12] OMAP OPP: add microvolts DC ("u_volt") field into struct omap_opp
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
` (4 preceding siblings ...)
2009-12-18 0:47 ` [PATCH 05/12] OMAP TWL/TPS OPP: vsel rounding belongs in opp_twl_tps.c Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-18 0:47 ` [PATCH 07/12] OMAP OPP: add opp_find_opp_by_opp_id() Paul Walmsley
` (5 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
OPP layer code should be PMIC-independent. A future patch will remove
the vsel field, which is TPS/TWL-dependent.
---
arch/arm/plat-omap/include/plat/opp.h | 4 +++-
arch/arm/plat-omap/opp.c | 9 ++++++---
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
index 2a7c113..4329767 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -21,6 +21,7 @@
* @vsel: Voltage in volt processor level(this usage is
* DEPRECATED to use Voltage in microvolts in future)
* uV = ((vsel * 12.5) + 600) * 1000
+ * @u_volt: minimum microvolts DC required for this OPP to function
*
* This structure stores the OPP information for a given domain.
* Due to legacy reasons, this structure is currently exposed and
@@ -30,8 +31,9 @@
struct omap_opp {
bool enabled;
unsigned long rate;
+ unsigned long u_volt;
u8 __deprecated opp_id;
- u16 __deprecated vsel;
+ u8 __deprecated vsel;
};
/**
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 2543932..2e97237 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -23,7 +23,7 @@
* This is meant to help co-exist with current SRF etc
* TODO: REMOVE!
*/
-#define OPP_TERM(opp) (!(opp)->rate && !(opp)->vsel && !(opp)->enabled)
+#define OPP_TERM(opp) (!(opp)->rate && !(opp)->u_volt && !(opp)->enabled)
unsigned long opp_get_voltage(const struct omap_opp *opp)
{
@@ -31,7 +31,7 @@ unsigned long opp_get_voltage(const struct omap_opp *opp)
pr_err("%s: Invalid parameters being passed\n", __func__);
return 0;
}
- return omap_twl_vsel_to_uv(opp->vsel);
+ return opp->u_volt;
}
unsigned long opp_get_freq(const struct omap_opp *opp)
@@ -143,7 +143,8 @@ static void omap_opp_populate(struct omap_opp *opp,
{
opp->rate = opp_def->freq;
opp->enabled = opp_def->enabled;
- opp->vsel = omap_twl_uv_to_vsel(opp_def->u_volt);
+ opp->u_volt = opp_def->u_volt;
+ opp->vsel = omap_twl_uv_to_vsel(opp_def->u_volt); /* XXX remove me */
}
struct omap_opp *opp_add(struct omap_opp *oppl,
@@ -234,6 +235,7 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
opp->rate = 0;
opp->enabled = 0;
opp->vsel = 0;
+ opp->u_volt = 0;
opp++;
while (n) {
omap_opp_populate(opp, opp_defs);
@@ -247,6 +249,7 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
opp->rate = 0;
opp->enabled = 0;
opp->vsel = 0;
+ opp->u_volt = 0;
return oppl;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 07/12] OMAP OPP: add opp_find_opp_by_opp_id()
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
` (5 preceding siblings ...)
2009-12-18 0:47 ` [PATCH 06/12] OMAP OPP: add microvolts DC ("u_volt") field into struct omap_opp Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-18 0:47 ` [PATCH 08/12] OMAP SR/SRF: use opp_find_opp_by_opp_id() Paul Walmsley
` (4 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
Add code to the OPP layer to find OPPs by OPP ID. This is needed to hide
the details of the struct omap_opp from SmartReflex and SRF code.
---
arch/arm/plat-omap/include/plat/opp.h | 3 +++
arch/arm/plat-omap/opp.c | 25 +++++++++++++++++++++++++
2 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
index 4329767..38b5069 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -241,4 +241,7 @@ int opp_enable(struct omap_opp *opp);
*/
int opp_disable(struct omap_opp *opp);
+struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
+ u8 opp_id);
+
#endif /* __ASM_ARM_OMAP_OPP_H */
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 2e97237..a5cc9a6 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -43,6 +43,31 @@ unsigned long opp_get_freq(const struct omap_opp *opp)
return opp->rate;
}
+/**
+ * opp_find_by_opp_id - look up OPP by OPP ID (deprecated)
+ * @opps: pointer to an array of struct omap_opp
+ *
+ * Returns the struct omap_opp pointer corresponding to the given OPP
+ * ID @opp_id, or returns NULL on error.
+ */
+struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
+ u8 opp_id)
+{
+ int i = 1;
+
+ if (!opps || !opp_id)
+ return NULL;
+
+ /* The first entry is a dummy one, loop till we hit terminator */
+ while (!OPP_TERM(&opps[i])) {
+ if (opps[i].enabled && (opps[i].opp_id == opp_id))
+ return &opps[i];
+ i++;
+ }
+
+ return NULL;
+}
+
int opp_get_opp_count(struct omap_opp *oppl)
{
u8 n = 0;
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 08/12] OMAP SR/SRF: use opp_find_opp_by_opp_id()
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
` (6 preceding siblings ...)
2009-12-18 0:47 ` [PATCH 07/12] OMAP OPP: add opp_find_opp_by_opp_id() Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-18 0:47 ` [PATCH 09/12] OMAP OPP: remove vsel Paul Walmsley
` (3 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
SmartReflex and SRF code should use opp_find_opp_by_opp_id() to find
OPP entries by the OPP ID. This hides OPP layer details from SR/SRF code
and also allows the removal of the open-coded OPP traversal.
---
arch/arm/mach-omap2/resource34xx.c | 30 ++++++++--------
arch/arm/mach-omap2/smartreflex.c | 66 ++++++++++++++++++++++++++++--------
2 files changed, 66 insertions(+), 30 deletions(-)
diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index baa33c4..05e70b7 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -25,6 +25,7 @@
#include <plat/powerdomain.h>
#include <plat/clockdomain.h>
#include <plat/omap34xx.h>
+#include <plat/opp_twl_tps.h>
#include "smartreflex.h"
#include "resource34xx.h"
@@ -157,10 +158,6 @@ static int curr_vdd1_opp;
static int curr_vdd2_opp;
static DEFINE_MUTEX(dvfs_mutex);
-/* Introducing deprecated function because we got to.. */
-#define IS_OPP_TERMINATOR(opps, i) (!(opps)[(i)].enabled && \
- !(opps)[(i)].rate && !(opps)[(i)].vsel)
-
/**
* opp_to_freq - convert OPPID to frequency (DEPRECATED)
* @freq: return frequency back to caller
@@ -175,20 +172,17 @@ static DEFINE_MUTEX(dvfs_mutex);
static int __deprecated opp_to_freq(unsigned long *freq,
const struct omap_opp *opps, u8 opp_id)
{
- int i = 1;
+ struct omap_opp *opp;
BUG_ON(!freq || !opps);
- /* The first entry is a dummy one, loop till we hit terminator */
- while (!IS_OPP_TERMINATOR(opps, i)) {
- if (opps[i].enabled && (opps[i].opp_id == opp_id)) {
- *freq = opps[i].rate;
- return 0;
- }
- i++;
- }
+ opp = opp_find_by_opp_id(opps, opp_id);
+ if (!opp)
+ return -EINVAL;
- return -EINVAL;
+ *freq = opp_get_freq(opp);
+
+ return 0;
}
/**
@@ -365,18 +359,22 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
else {
u8 vc, vt;
struct omap_opp *oppx;
+ unsigned long uvdc;
+
/*
* transitioning from good to good OPP
* none of the following should fail..
*/
oppx = opp_find_freq_exact(opp, freq, true);
BUG_ON(IS_ERR(oppx));
- vt = oppx->vsel;
+ uvdc = opp_get_voltage(oppx);
+ vt = omap_twl_uv_to_vsel(uvdc);
BUG_ON(opp_to_freq(&freq, opp, current_level));
oppx = opp_find_freq_exact(opp, freq, true);
BUG_ON(IS_ERR(oppx));
- vc = oppx->vsel;
+ uvdc = opp_get_voltage(oppx);
+ vc = omap_twl_uv_to_vsel(uvdc);
/* ok to scale.. */
sr_voltagescale_vcbypass(t_opp, c_opp, vt, vc);
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 50332ae..e086f2d 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -31,6 +31,7 @@
#include <plat/control.h>
#include <plat/clock.h>
#include <plat/omap-pm.h>
+#include <plat/opp_twl_tps.h>
#include "prm.h"
#include "smartreflex.h"
@@ -282,15 +283,20 @@ static void sr_configure_vp(int srid)
{
u32 vpconfig;
u32 vsel;
+ int uvdc;
u32 target_opp_no;
+ struct omap_opp *opp;
if (srid == SR1) {
target_opp_no = get_vdd1_opp();
if (!target_opp_no)
- /* Assume Nominal OPP as current OPP unknown */
- vsel = mpu_opps[VDD1_OPP3].vsel;
- else
- vsel = mpu_opps[target_opp_no].vsel;
+ target_opp_no = VDD1_OPP3;
+
+ opp = opp_find_by_opp_id(mpu_opps, target_opp_no);
+ BUG_ON(!opp); /* XXX ugh */
+
+ uvdc = opp_get_voltage(opp);
+ vsel = omap_twl_uv_to_vsel(uvdc);
vpconfig = PRM_VP1_CONFIG_ERROROFFSET |
PRM_VP1_CONFIG_ERRORGAIN |
@@ -333,10 +339,13 @@ static void sr_configure_vp(int srid)
} else if (srid == SR2) {
target_opp_no = get_vdd2_opp();
if (!target_opp_no)
- /* Assume Nominal OPP */
- vsel = l3_opps[VDD2_OPP3].vsel;
- else
- vsel = l3_opps[target_opp_no].vsel;
+ target_opp_no = VDD2_OPP3;
+
+ opp = opp_find_by_opp_id(l3_opps, target_opp_no);
+ BUG_ON(!opp); /* XXX ugh */
+
+ uvdc = opp_get_voltage(opp);
+ vsel = omap_twl_uv_to_vsel(uvdc);
vpconfig = PRM_VP2_CONFIG_ERROROFFSET |
PRM_VP2_CONFIG_ERRORGAIN |
@@ -428,6 +437,8 @@ static void sr_configure(struct omap_sr *sr)
static int sr_reset_voltage(int srid)
{
+ struct omap_opp *opp;
+ unsigned long uvdc;
u32 target_opp_no, vsel = 0;
u32 reg_addr = 0;
u32 loop_cnt = 0, retries_cnt = 0;
@@ -442,7 +453,14 @@ static int sr_reset_voltage(int srid)
pr_info("Current OPP unknown: Cannot reset voltage\n");
return 1;
}
- vsel = mpu_opps[target_opp_no].vsel;
+
+ opp = opp_find_by_opp_id(mpu_opps, target_opp_no);
+ if (!opp)
+ return 1;
+
+ uvdc = opp_get_voltage(opp);
+ vsel = omap_twl_uv_to_vsel(uvdc);
+
reg_addr = R_VDD1_SR_CONTROL;
prm_vp1_voltage = prm_read_mod_reg(OMAP3430_GR_MOD,
OMAP3_PRM_VP1_VOLTAGE_OFFSET);
@@ -453,7 +471,14 @@ static int sr_reset_voltage(int srid)
pr_info("Current OPP unknown: Cannot reset voltage\n");
return 1;
}
- vsel = l3_opps[target_opp_no].vsel;
+
+ opp = opp_find_by_opp_id(l3_opps, target_opp_no);
+ if (!opp)
+ return 1;
+
+ uvdc = opp_get_voltage(opp);
+ vsel = omap_twl_uv_to_vsel(uvdc);
+
reg_addr = R_VDD2_SR_CONTROL;
prm_vp2_voltage = prm_read_mod_reg(OMAP3430_GR_MOD,
OMAP3_PRM_VP2_VOLTAGE_OFFSET);
@@ -499,6 +524,9 @@ static int sr_reset_voltage(int srid)
static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
{
u32 nvalue_reciprocal, v;
+ struct omap_opp *opp;
+ int uvdc;
+ char vsel;
if (!(mpu_opps && l3_opps)) {
pr_notice("VSEL values not found\n");
@@ -528,6 +556,10 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
nvalue_reciprocal = sr->opp3_nvalue;
break;
}
+
+ opp = opp_find_by_opp_id(mpu_opps, target_opp_no);
+ if (!opp)
+ return false;
} else {
switch (target_opp_no) {
case 3:
@@ -543,6 +575,10 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
nvalue_reciprocal = sr->opp3_nvalue;
break;
}
+
+ opp = opp_find_by_opp_id(l3_opps, target_opp_no);
+ if (!opp)
+ return false;
}
if (nvalue_reciprocal == 0) {
@@ -558,13 +594,16 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
+ uvdc = opp_get_voltage(opp);
+ vsel = omap_twl_uv_to_vsel(uvdc);
+
if (sr->srid == SR1) {
/* set/latch init voltage */
v = prm_read_mod_reg(OMAP3430_GR_MOD,
OMAP3_PRM_VP1_CONFIG_OFFSET);
v &= ~(OMAP3430_INITVOLTAGE_MASK | OMAP3430_INITVDD);
- v |= mpu_opps[target_opp_no].vsel <<
- OMAP3430_INITVOLTAGE_SHIFT;
+
+ v |= vsel << OMAP3430_INITVOLTAGE_SHIFT;
prm_write_mod_reg(v, OMAP3430_GR_MOD,
OMAP3_PRM_VP1_CONFIG_OFFSET);
/* write1 to latch */
@@ -581,8 +620,7 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
v = prm_read_mod_reg(OMAP3430_GR_MOD,
OMAP3_PRM_VP2_CONFIG_OFFSET);
v &= ~(OMAP3430_INITVOLTAGE_MASK | OMAP3430_INITVDD);
- v |= l3_opps[target_opp_no].vsel <<
- OMAP3430_INITVOLTAGE_SHIFT;
+ v |= vsel << OMAP3430_INITVOLTAGE_SHIFT;
prm_write_mod_reg(v, OMAP3430_GR_MOD,
OMAP3_PRM_VP2_CONFIG_OFFSET);
/* write1 to latch */
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 09/12] OMAP OPP: remove vsel
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
` (7 preceding siblings ...)
2009-12-18 0:47 ` [PATCH 08/12] OMAP SR/SRF: use opp_find_opp_by_opp_id() Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-18 0:47 ` [PATCH 10/12] OMAP OPP: remove "initial terminators" from OPP lists Paul Walmsley
` (2 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
The OPP code should be PMIC-independent; vsel is a TWL/TPS-ism; so remove it.
---
arch/arm/plat-omap/include/plat/opp.h | 4 ----
arch/arm/plat-omap/opp.c | 3 ---
2 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
index 38b5069..b00f7f9 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -18,9 +18,6 @@
* @enabled: true/false - marking this OPP as enabled/disabled
* @rate: Frequency in hertz
* @opp_id: (DEPRECATED) opp identifier
- * @vsel: Voltage in volt processor level(this usage is
- * DEPRECATED to use Voltage in microvolts in future)
- * uV = ((vsel * 12.5) + 600) * 1000
* @u_volt: minimum microvolts DC required for this OPP to function
*
* This structure stores the OPP information for a given domain.
@@ -33,7 +30,6 @@ struct omap_opp {
unsigned long rate;
unsigned long u_volt;
u8 __deprecated opp_id;
- u8 __deprecated vsel;
};
/**
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index a5cc9a6..596e3ee 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -169,7 +169,6 @@ static void omap_opp_populate(struct omap_opp *opp,
opp->rate = opp_def->freq;
opp->enabled = opp_def->enabled;
opp->u_volt = opp_def->u_volt;
- opp->vsel = omap_twl_uv_to_vsel(opp_def->u_volt); /* XXX remove me */
}
struct omap_opp *opp_add(struct omap_opp *oppl,
@@ -259,7 +258,6 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
/* Setup start terminator - SRF depends on this for indexing :( */
opp->rate = 0;
opp->enabled = 0;
- opp->vsel = 0;
opp->u_volt = 0;
opp++;
while (n) {
@@ -273,7 +271,6 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
/* Setup terminator - this is for our search algos */
opp->rate = 0;
opp->enabled = 0;
- opp->vsel = 0;
opp->u_volt = 0;
return oppl;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 10/12] OMAP OPP: remove "initial terminators" from OPP lists
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
` (8 preceding siblings ...)
2009-12-18 0:47 ` [PATCH 09/12] OMAP OPP: remove vsel Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-18 19:08 ` Kevin Hilman
2009-12-18 0:47 ` [PATCH 11/12] OMAP OPP: use kzalloc() rather than kmalloc() Paul Walmsley
2009-12-18 0:47 ` [PATCH 12/12] OMAP3 OPP: move CPUFreq table init code to OPP layer Paul Walmsley
11 siblings, 1 reply; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
Now that the SRF and Smartreflex code uses accessor functions to interact
with OPPs, the "initial terminators" can be removed.
---
arch/arm/plat-omap/opp.c | 36 ++++++++----------------------------
1 files changed, 8 insertions(+), 28 deletions(-)
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 596e3ee..f651912 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -53,15 +53,15 @@ unsigned long opp_get_freq(const struct omap_opp *opp)
struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
u8 opp_id)
{
- int i = 1;
+ int i = 0;
if (!opps || !opp_id)
return NULL;
- /* The first entry is a dummy one, loop till we hit terminator */
while (!OPP_TERM(&opps[i])) {
if (opps[i].enabled && (opps[i].opp_id == opp_id))
return &opps[i];
+
i++;
}
@@ -76,7 +76,6 @@ int opp_get_opp_count(struct omap_opp *oppl)
pr_err("%s: Invalid parameters being passed\n", __func__);
return -EINVAL;
}
- oppl++; /* skip initial terminator */
while (!OPP_TERM(oppl)) {
if (oppl->enabled)
n++;
@@ -92,9 +91,7 @@ struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
pr_err("%s: Invalid parameters being passed\n", __func__);
return ERR_PTR(-EINVAL);
}
- /* skip initial terminator */
- if (OPP_TERM(oppl))
- oppl++;
+
while (!OPP_TERM(oppl)) {
if ((oppl->rate == freq) && (oppl->enabled == enabled))
break;
@@ -111,10 +108,6 @@ struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq)
return ERR_PTR(-EINVAL);
}
- /* skip initial terminator */
- if (OPP_TERM(oppl))
- oppl++;
-
while (!OPP_TERM(oppl)) {
if (oppl->enabled && oppl->rate >= *freq)
break;
@@ -139,10 +132,6 @@ struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl, unsigned long *freq)
return ERR_PTR(-EINVAL);
}
- /* skip initial terminator */
- if (OPP_TERM(oppl))
- oppl++;
-
while (!OPP_TERM(oppl)) {
if (oppl->enabled) {
if (oppl->rate > *freq)
@@ -181,20 +170,16 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
pr_err("%s: Invalid params being passed\n", __func__);
return ERR_PTR(-EINVAL);
}
- /* need a start terminator.. */
- if (unlikely(!OPP_TERM(oppl))) {
- pr_err("%s: Expected a start terminator!!\n", __func__);
- return ERR_PTR(-EINVAL);
- }
+
n = 0;
opp = oppl;
- opp++;
while (!OPP_TERM(opp)) {
n++;
opp++;
}
+
/* lets now reallocate memory */
- oppr = kmalloc(sizeof(struct omap_opp) * (n + 3), GFP_KERNEL);
+ oppr = kmalloc(sizeof(struct omap_opp) * (n + 2), GFP_KERNEL);
if (!oppr) {
pr_err("%s: No memory for new opp array\n", __func__);
return ERR_PTR(-ENOMEM);
@@ -204,7 +189,7 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
opp = oppl;
oppt = oppr;
ins = 0;
- i = 0;
+ i = 1;
do {
if (ins || opp->rate < opp_def->freq) {
memcpy(oppt, opp, sizeof(struct omap_opp));
@@ -249,17 +234,12 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
t++;
}
- oppl = kmalloc(sizeof(struct omap_opp) * (n + 2), GFP_KERNEL);
+ oppl = kmalloc(sizeof(struct omap_opp) * (n + 1), GFP_KERNEL);
if (!oppl) {
pr_err("%s: No memory for opp array\n", __func__);
return ERR_PTR(-ENOMEM);
}
opp = oppl;
- /* Setup start terminator - SRF depends on this for indexing :( */
- opp->rate = 0;
- opp->enabled = 0;
- opp->u_volt = 0;
- opp++;
while (n) {
omap_opp_populate(opp, opp_defs);
opp->opp_id = i;
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 11/12] OMAP OPP: use kzalloc() rather than kmalloc()
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
` (9 preceding siblings ...)
2009-12-18 0:47 ` [PATCH 10/12] OMAP OPP: remove "initial terminators" from OPP lists Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-18 0:47 ` [PATCH 12/12] OMAP3 OPP: move CPUFreq table init code to OPP layer Paul Walmsley
11 siblings, 0 replies; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
Using kzalloc() avoids inadvertently forgetting to initialize some structure
member.
---
arch/arm/plat-omap/opp.c | 25 ++++++++++++++++---------
1 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index f651912..8bdad43 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -178,8 +178,11 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
opp++;
}
- /* lets now reallocate memory */
- oppr = kmalloc(sizeof(struct omap_opp) * (n + 2), GFP_KERNEL);
+ /*
+ * Allocate enough entries to copy the original list, plus the new
+ * OPP, plus the concluding terminator
+ */
+ oppr = kzalloc(sizeof(struct omap_opp) * (n + 2), GFP_KERNEL);
if (!oppr) {
pr_err("%s: No memory for new opp array\n", __func__);
return ERR_PTR(-ENOMEM);
@@ -209,8 +212,8 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
oppt->opp_id = i;
oppt++;
}
- /* Put the terminator back on */
- memcpy(oppt, opp, sizeof(struct omap_opp));
+
+ /* Terminator implicitly added by kzalloc() */
/* Free the old list */
kfree(oppl);
@@ -234,11 +237,16 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
t++;
}
- oppl = kmalloc(sizeof(struct omap_opp) * (n + 1), GFP_KERNEL);
+ /*
+ * Allocate enough entries to copy the original list, plus the
+ * concluding terminator
+ */
+ oppl = kzalloc(sizeof(struct omap_opp) * (n + 1), GFP_KERNEL);
if (!oppl) {
pr_err("%s: No memory for opp array\n", __func__);
return ERR_PTR(-ENOMEM);
}
+
opp = oppl;
while (n) {
omap_opp_populate(opp, opp_defs);
@@ -248,10 +256,9 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
opp_defs++;
i++;
}
- /* Setup terminator - this is for our search algos */
- opp->rate = 0;
- opp->enabled = 0;
- opp->u_volt = 0;
+
+ /* Terminator implicitly added by kzalloc() */
+
return oppl;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 12/12] OMAP3 OPP: move CPUFreq table init code to OPP layer
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
` (10 preceding siblings ...)
2009-12-18 0:47 ` [PATCH 11/12] OMAP OPP: use kzalloc() rather than kmalloc() Paul Walmsley
@ 2009-12-18 0:47 ` Paul Walmsley
2009-12-19 12:22 ` Menon, Nishanth
11 siblings, 1 reply; 18+ messages in thread
From: Paul Walmsley @ 2009-12-18 0:47 UTC (permalink / raw)
To: nm; +Cc: linux-omap
Move omap2_clk_init_cpufreq_table() to opp_init_cpufreq_table() in opp.c
where it now belongs. OMAP2 still needs to be converted to use the OPP layer,
so it is using the old code.
---
arch/arm/mach-omap2/clock34xx.c | 55 +--------------------------------
arch/arm/plat-omap/cpu-omap.c | 6 +++-
arch/arm/plat-omap/include/plat/opp.h | 4 ++
arch/arm/plat-omap/opp.c | 46 ++++++++++++++++++++++++++++
4 files changed, 56 insertions(+), 55 deletions(-)
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index ba3dd70..6a40fb1 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -27,7 +27,6 @@
#include <linux/limits.h>
#include <linux/bitops.h>
#include <linux/err.h>
-#include <linux/cpufreq.h>
#include <plat/cpu.h>
#include <plat/clock.h>
@@ -257,56 +256,7 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
/* Common clock code */
-/*
- * As it is structured now, this will prevent an OMAP2/3 multiboot
- * kernel from compiling. This will need further attention.
- */
-#if defined(CONFIG_ARCH_OMAP3)
-
-#ifdef CONFIG_CPU_FREQ
-
-static struct cpufreq_frequency_table *freq_table;
-
-void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
-{
- int i = 0;
- int opp_num;
- struct omap_opp *opp = mpu_opps;
- unsigned long freq = ULONG_MAX;
-
- if (!mpu_opps) {
- pr_warning("%s: failed to initialize frequency"
- "table\n", __func__);
- return;
- }
- opp_num = opp_get_opp_count(mpu_opps);
- if (opp_num < 0) {
- pr_err("%s: no opp table?\n", __func__);
- return;
- }
-
- freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
- (opp_num + 1), GFP_ATOMIC);
- if (!freq_table) {
- pr_warning("%s: failed to allocate frequency"
- "table\n", __func__);
- return;
- }
-
- while (!IS_ERR(opp = opp_find_freq_floor(opp, &freq))) {
- freq_table[i].index = i;
- freq_table[i].frequency = freq / 1000;
- i++;
- /* set the next benchmark to search */
- freq--;
- }
-
- freq_table[i].index = i;
- freq_table[i].frequency = CPUFREQ_TABLE_END;
-
- *table = &freq_table[0];
-}
-#endif
+#ifdef CONFIG_ARCH_OMAP3
struct clk_functions omap2_clk_functions = {
.clk_enable = omap2_clk_enable,
@@ -315,9 +265,6 @@ struct clk_functions omap2_clk_functions = {
.clk_set_rate = omap2_clk_set_rate,
.clk_set_parent = omap2_clk_set_parent,
.clk_disable_unused = omap2_clk_disable_unused,
-#ifdef CONFIG_CPU_FREQ
- .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
-#endif
};
/*
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index a2b5ee4..723834e 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -132,7 +132,11 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy)
policy->cur = policy->min = policy->max = omap_getspeed(0);
- clk_init_cpufreq_table(&freq_table);
+ if (!cpu_is_omap34xx())
+ clk_init_cpufreq_table(&freq_table);
+ else
+ opp_init_cpufreq_table(mpu_opps, &freq_table);
+
if (freq_table) {
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
if (!result)
diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
index b00f7f9..91b0aa6 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -240,4 +240,8 @@ int opp_disable(struct omap_opp *opp);
struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
u8 opp_id);
+void opp_init_cpufreq_table(struct omap_opp *opps,
+ struct cpufreq_frequency_table **table);
+
+
#endif /* __ASM_ARM_OMAP_OPP_H */
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 8bdad43..aaafc10 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -14,6 +14,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/cpufreq.h>
#include <plat/opp_twl_tps.h>
#include <plat/opp.h>
@@ -281,3 +282,48 @@ int opp_disable(struct omap_opp *opp)
opp->enabled = false;
return 0;
}
+
+/* XXX document */
+void opp_init_cpufreq_table(struct omap_opp *opps,
+ struct cpufreq_frequency_table **table)
+{
+ int i = 0;
+ int opp_num;
+ unsigned long freq = ULONG_MAX;
+ struct cpufreq_frequency_table *freq_table;
+
+ if (!opps) {
+ pr_warning("%s: failed to initialize frequency"
+ "table\n", __func__);
+ return;
+ }
+
+ opp_num = opp_get_opp_count(opps);
+ if (opp_num < 0) {
+ pr_err("%s: no opp table?\n", __func__);
+ return;
+ }
+
+ freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
+ (opp_num + 1), GFP_ATOMIC);
+ if (!freq_table) {
+ pr_warning("%s: failed to allocate frequency"
+ "table\n", __func__);
+ return;
+ }
+
+ while (!OPP_TERM(opps)) {
+ if (opps->enabled) {
+ freq_table[i].index = i;
+ freq_table[i].frequency = freq / 1000;
+ i++;
+ }
+
+ opps++;
+ }
+
+ freq_table[i].index = i;
+ freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ *table = &freq_table[0];
+}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 01/12] OMAP OPP: remove some unnecessary variables
2009-12-18 0:47 ` [PATCH 01/12] OMAP OPP: remove some unnecessary variables Paul Walmsley
@ 2009-12-18 17:28 ` Kevin Hilman
0 siblings, 0 replies; 18+ messages in thread
From: Kevin Hilman @ 2009-12-18 17:28 UTC (permalink / raw)
To: Paul Walmsley; +Cc: nm, linux-omap
Paul Walmsley <paul@pwsan.com> writes:
> No need to allocate new variables; the passed-in OPP list pointers do nicely
> as iterators.
Thanks Paul for this series. I totally agree with the cleanups you've
done.
I've rebased this on top of my current pm-wip-opp branch and will include it
in the next push of that branch for broader use and testing.
Kevin
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 10/12] OMAP OPP: remove "initial terminators" from OPP lists
2009-12-18 0:47 ` [PATCH 10/12] OMAP OPP: remove "initial terminators" from OPP lists Paul Walmsley
@ 2009-12-18 19:08 ` Kevin Hilman
0 siblings, 0 replies; 18+ messages in thread
From: Kevin Hilman @ 2009-12-18 19:08 UTC (permalink / raw)
To: Paul Walmsley; +Cc: nm, linux-omap
Paul Walmsley <paul@pwsan.com> writes:
> Now that the SRF and Smartreflex code uses accessor functions to interact
> with OPPs, the "initial terminators" can be removed.
Nice.
With the initial terminators gone, some assumptions in SRF have to be
changed too where SRF is directly indexing into the OPP table.
I'll fix that up in an updated version of my 'hide OPP details' series.
Kevin
> ---
> arch/arm/plat-omap/opp.c | 36 ++++++++----------------------------
> 1 files changed, 8 insertions(+), 28 deletions(-)
>
> diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
> index 596e3ee..f651912 100644
> --- a/arch/arm/plat-omap/opp.c
> +++ b/arch/arm/plat-omap/opp.c
> @@ -53,15 +53,15 @@ unsigned long opp_get_freq(const struct omap_opp *opp)
> struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
> u8 opp_id)
> {
> - int i = 1;
> + int i = 0;
>
> if (!opps || !opp_id)
> return NULL;
>
> - /* The first entry is a dummy one, loop till we hit terminator */
> while (!OPP_TERM(&opps[i])) {
> if (opps[i].enabled && (opps[i].opp_id == opp_id))
> return &opps[i];
> +
> i++;
> }
>
> @@ -76,7 +76,6 @@ int opp_get_opp_count(struct omap_opp *oppl)
> pr_err("%s: Invalid parameters being passed\n", __func__);
> return -EINVAL;
> }
> - oppl++; /* skip initial terminator */
> while (!OPP_TERM(oppl)) {
> if (oppl->enabled)
> n++;
> @@ -92,9 +91,7 @@ struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
> pr_err("%s: Invalid parameters being passed\n", __func__);
> return ERR_PTR(-EINVAL);
> }
> - /* skip initial terminator */
> - if (OPP_TERM(oppl))
> - oppl++;
> +
> while (!OPP_TERM(oppl)) {
> if ((oppl->rate == freq) && (oppl->enabled == enabled))
> break;
> @@ -111,10 +108,6 @@ struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq)
> return ERR_PTR(-EINVAL);
> }
>
> - /* skip initial terminator */
> - if (OPP_TERM(oppl))
> - oppl++;
> -
> while (!OPP_TERM(oppl)) {
> if (oppl->enabled && oppl->rate >= *freq)
> break;
> @@ -139,10 +132,6 @@ struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl, unsigned long *freq)
> return ERR_PTR(-EINVAL);
> }
>
> - /* skip initial terminator */
> - if (OPP_TERM(oppl))
> - oppl++;
> -
> while (!OPP_TERM(oppl)) {
> if (oppl->enabled) {
> if (oppl->rate > *freq)
> @@ -181,20 +170,16 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
> pr_err("%s: Invalid params being passed\n", __func__);
> return ERR_PTR(-EINVAL);
> }
> - /* need a start terminator.. */
> - if (unlikely(!OPP_TERM(oppl))) {
> - pr_err("%s: Expected a start terminator!!\n", __func__);
> - return ERR_PTR(-EINVAL);
> - }
> +
> n = 0;
> opp = oppl;
> - opp++;
> while (!OPP_TERM(opp)) {
> n++;
> opp++;
> }
> +
> /* lets now reallocate memory */
> - oppr = kmalloc(sizeof(struct omap_opp) * (n + 3), GFP_KERNEL);
> + oppr = kmalloc(sizeof(struct omap_opp) * (n + 2), GFP_KERNEL);
> if (!oppr) {
> pr_err("%s: No memory for new opp array\n", __func__);
> return ERR_PTR(-ENOMEM);
> @@ -204,7 +189,7 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
> opp = oppl;
> oppt = oppr;
> ins = 0;
> - i = 0;
> + i = 1;
> do {
> if (ins || opp->rate < opp_def->freq) {
> memcpy(oppt, opp, sizeof(struct omap_opp));
> @@ -249,17 +234,12 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
> t++;
> }
>
> - oppl = kmalloc(sizeof(struct omap_opp) * (n + 2), GFP_KERNEL);
> + oppl = kmalloc(sizeof(struct omap_opp) * (n + 1), GFP_KERNEL);
> if (!oppl) {
> pr_err("%s: No memory for opp array\n", __func__);
> return ERR_PTR(-ENOMEM);
> }
> opp = oppl;
> - /* Setup start terminator - SRF depends on this for indexing :( */
> - opp->rate = 0;
> - opp->enabled = 0;
> - opp->u_volt = 0;
> - opp++;
> while (n) {
> omap_opp_populate(opp, opp_defs);
> opp->opp_id = i;
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 03/12] OMAP OPP: only traverse opp_find_freq_floor() once
2009-12-18 0:47 ` [PATCH 03/12] OMAP OPP: only traverse opp_find_freq_floor() once Paul Walmsley
@ 2009-12-19 12:10 ` Menon, Nishanth
0 siblings, 0 replies; 18+ messages in thread
From: Menon, Nishanth @ 2009-12-19 12:10 UTC (permalink / raw)
To: Paul Walmsley; +Cc: linux-omap@vger.kernel.org
Paul Walmsley said the following on 12/18/2009 06:17 AM:
> There's no point traversing the OPP list twice in opp_find_freq_floor().
> ---
> arch/arm/plat-omap/opp.c | 30 +++++++++++++-----------------
> 1 files changed, 13 insertions(+), 17 deletions(-)
>
> diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
> index fc250b8..e9f5706 100644
> --- a/arch/arm/plat-omap/opp.c
> +++ b/arch/arm/plat-omap/opp.c
> @@ -126,36 +126,32 @@ struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq)
>
> struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl, unsigned long *freq)
> {
> + struct omap_opp *prev_opp = oppl;
> +
> if (unlikely(!oppl || IS_ERR(oppl) || !freq || IS_ERR(freq))) {
> pr_err("%s: Invalid parameters being passed\n", __func__);
> return ERR_PTR(-EINVAL);
> }
>
> /* skip initial terminator */
> - if (OPP_TERM(oppl)) {
> + if (OPP_TERM(oppl))
> oppl++;
> - /* If searching init list for a high val, skip to very top */
> - /*
> - * XXX What is the point of this? If one is going to traverse
> - * the list, might as well do what we need to do during the
> - * traversal.
> - */
> - while (!OPP_TERM(oppl)) /* XXX above */
> - oppl++;
> - }
>
> - while (!OPP_TERM(--oppl)) {
> - if (!oppl->enabled)
> - continue;
> + while (!OPP_TERM(oppl)) {
> + if (oppl->enabled) {
> + if (oppl->rate > *freq)
> + break;
>
> - if (oppl->rate <= *freq)
> - break;
> + prev_opp = oppl;
> + }
> +
> + oppl++;
> }
>
> - if (OPP_TERM(oppl))
> + if (prev_opp->rate > *freq)
> return ERR_PTR(-ENOENT);
>
> - *freq = oppl->rate;
> + *freq = prev_opp->rate;
>
> return oppl;
> }
>
>
>
Nice. thanks.
Acked-by: Nishanth Menon <nm@ti.com>
Regards,
Nishanth Menon
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 04/12] OMAP TWL/TPS OPP: move TWL/TPS-specific code to its own file
2009-12-18 0:47 ` [PATCH 04/12] OMAP TWL/TPS OPP: move TWL/TPS-specific code to its own file Paul Walmsley
@ 2009-12-19 12:14 ` Menon, Nishanth
0 siblings, 0 replies; 18+ messages in thread
From: Menon, Nishanth @ 2009-12-19 12:14 UTC (permalink / raw)
To: Paul Walmsley; +Cc: linux-omap@vger.kernel.org
Paul Walmsley said the following on 12/18/2009 06:17 AM:
> The OPP layer code should be independent of the PMIC, so move
> the TWL/TPS-specific code out to its own file.
> ---
> arch/arm/plat-omap/Makefile | 4 ++-
> arch/arm/plat-omap/include/plat/opp_twl_tps.h | 21 ++++++++++++++
> arch/arm/plat-omap/opp.c | 27 +++---------------
> arch/arm/plat-omap/opp_twl_tps.c | 38 +++++++++++++++++++++++++
> 4 files changed, 66 insertions(+), 24 deletions(-)
> create mode 100644 arch/arm/plat-omap/include/plat/opp_twl_tps.h
> create mode 100644 arch/arm/plat-omap/opp_twl_tps.c
>
> diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
> index e9cf601..b0c5b31 100644
> --- a/arch/arm/plat-omap/Makefile
> +++ b/arch/arm/plat-omap/Makefile
> @@ -13,7 +13,9 @@ obj- :=
> obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
>
> # OPP support in (OMAP3+ only at the moment)
> -obj-$(CONFIG_ARCH_OMAP3) += opp.o
> +# XXX The OPP TWL/TPS code should only be included when a TWL/TPS
> +# PMIC is selected.
> +obj-$(CONFIG_ARCH_OMAP3) += opp.o opp_twl_tps.o
>
> # omap_device support (OMAP2+ only at the moment)
> obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
> diff --git a/arch/arm/plat-omap/include/plat/opp_twl_tps.h b/arch/arm/plat-omap/include/plat/opp_twl_tps.h
> new file mode 100644
> index 0000000..8784e5f
> --- /dev/null
> +++ b/arch/arm/plat-omap/include/plat/opp_twl_tps.h
> @@ -0,0 +1,21 @@
> +/*
> + * opp_twl_tps.h - TWL/TPS-specific headers for the OPP code
> + *
> + * Copyright (C) 2009 Texas Instruments Incorporated.
> + * Nishanth Menon
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * XXX This code belongs as part of some other TWL/TPS code.
> + */
> +#ifndef _ARCH_ARM_PLAT_OMAP_OPP_TWL_TPS_H
> +#define _ARCH_ARM_PLAT_OMAP_OPP_TWL_TPS_H
> +
> +#include <linux/kernel.h>
> +
> +unsigned long omap_twl_vsel_to_uv(const u8 vsel);
> +u8 omap_twl_uv_to_vsel(unsigned long uV);
> +
> +#endif
> diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
> index e9f5706..9586e3b 100644
> --- a/arch/arm/plat-omap/opp.c
> +++ b/arch/arm/plat-omap/opp.c
> @@ -15,6 +15,7 @@
> #include <linux/init.h>
> #include <linux/slab.h>
>
> +#include <plat/opp_twl_tps.h>
> #include <plat/opp.h>
>
> /*
> @@ -24,33 +25,13 @@
> */
> #define OPP_TERM(opp) (!(opp)->rate && !(opp)->vsel && !(opp)->enabled)
>
> -/*
> - * DEPRECATED: Meant to convert vsel value to uVolt
> - * This is meant to help co-exist with current SRF etc
> - * TODO: REMOVE!
> - */
> -static inline unsigned long vsel_to_uv(const u8 vsel)
> -{
> - return (((vsel * 125) + 6000)) * 100;
> -}
> -
> -/*
> - * DEPRECATED: Meant to convert uVolt to vsel value
> - * This is meant to help co-exist with current SRF etc
> - * TODO: REMOVE!
> - */
> -static inline unsigned char uv_to_vsel(unsigned long uV)
> -{
> - return ((uV / 100) - 6000) / 125;
> -}
> -
> unsigned long opp_get_voltage(const struct omap_opp *opp)
> {
> if (unlikely(!opp || IS_ERR(opp)) || !opp->enabled) {
> pr_err("%s: Invalid parameters being passed\n", __func__);
> return 0;
> }
> - return vsel_to_uv(opp->vsel);
> + return omap_twl_vsel_to_uv(opp->vsel);
> }
>
> unsigned long opp_get_freq(const struct omap_opp *opp)
> @@ -162,9 +143,9 @@ static void omap_opp_populate(struct omap_opp *opp,
> {
> opp->rate = opp_def->freq;
> opp->enabled = opp_def->enabled;
> - opp->vsel = uv_to_vsel(opp_def->u_volt);
> + opp->vsel = omap_twl_uv_to_vsel(opp_def->u_volt);
> /* round off to higher voltage */
> - if (opp_def->u_volt > vsel_to_uv(opp->vsel))
> + if (opp_def->u_volt > omap_twl_vsel_to_uv(opp->vsel))
> opp->vsel++;
> }
>
> diff --git a/arch/arm/plat-omap/opp_twl_tps.c b/arch/arm/plat-omap/opp_twl_tps.c
> new file mode 100644
> index 0000000..edcb719
> --- /dev/null
> +++ b/arch/arm/plat-omap/opp_twl_tps.c
> @@ -0,0 +1,38 @@
> +/*
> + * opp_twl_tps.c - TWL/TPS-specific functions for the OPP code
> + *
> + * Copyright (C) 2009 Texas Instruments Incorporated.
> + * Nishanth Menon
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * XXX This code should be part of some other TWL/TPS code.
> + */
> +
> +#include <plat/opp_twl_tps.h>
> +
> +/**
> + * omap_twl_vsel_to_vdc - convert TWL/TPS VSEL value to microvolts DC
> + * @vsel: TWL/TPS VSEL value to convert
> + *
> + * Returns the microvolts DC that the TWL/TPS family of PMICs should
> + * generate when programmed with @vsel.
> + */
> +unsigned long omap_twl_vsel_to_uv(const u8 vsel)
> +{
> + return (((vsel * 125) + 6000)) * 100;
> +}
> +
> +/**
> + * omap_twl_uv_to_vsel - convert microvolts DC to TWL/TPS VSEL value
> + * @uv: microvolts DC to convert
> + *
> + * Returns the VSEL value necessary for the TWL/TPS family of PMICs to
> + * generate an output voltage equal to or greater than @uv microvolts DC.
> + */
> +u8 omap_twl_uv_to_vsel(unsigned long uv)
> +{
> + return ((uv / 100) - 6000) / 125;
>
you may want to ensure that this returns ceil instead - that way you can
clean bit of code off the init logic
if (opp_def->u_volt > omap_twl_vsel_to_uv(opp->vsel))
> +}
>
>
>
I dont think this belongs here.. I agree this is a twl settings Vs being
other custom chip settings, probably we can do it part of sr cleanup
though..
Regards,
NM
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 05/12] OMAP TWL/TPS OPP: vsel rounding belongs in opp_twl_tps.c
2009-12-18 0:47 ` [PATCH 05/12] OMAP TWL/TPS OPP: vsel rounding belongs in opp_twl_tps.c Paul Walmsley
@ 2009-12-19 12:16 ` Menon, Nishanth
0 siblings, 0 replies; 18+ messages in thread
From: Menon, Nishanth @ 2009-12-19 12:16 UTC (permalink / raw)
To: Paul Walmsley; +Cc: linux-omap@vger.kernel.org
Paul Walmsley said the following on 12/18/2009 06:17 AM:
> The vsel roundoff code belongs in omap_twl_uv_to_vsel(), not
> omap_opp_populate(), since other code may use omap_twl_uv_to_vsel().
> ---
> arch/arm/plat-omap/opp.c | 3 ---
> arch/arm/plat-omap/opp_twl_tps.c | 15 +++++++++++++--
> 2 files changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
> index 9586e3b..2543932 100644
> --- a/arch/arm/plat-omap/opp.c
> +++ b/arch/arm/plat-omap/opp.c
> @@ -144,9 +144,6 @@ static void omap_opp_populate(struct omap_opp *opp,
> opp->rate = opp_def->freq;
> opp->enabled = opp_def->enabled;
> opp->vsel = omap_twl_uv_to_vsel(opp_def->u_volt);
> - /* round off to higher voltage */
> - if (opp_def->u_volt > omap_twl_vsel_to_uv(opp->vsel))
> - opp->vsel++;
> }
>
> struct omap_opp *opp_add(struct omap_opp *oppl,
> diff --git a/arch/arm/plat-omap/opp_twl_tps.c b/arch/arm/plat-omap/opp_twl_tps.c
> index edcb719..e0db39b 100644
> --- a/arch/arm/plat-omap/opp_twl_tps.c
> +++ b/arch/arm/plat-omap/opp_twl_tps.c
> @@ -2,7 +2,9 @@
> * opp_twl_tps.c - TWL/TPS-specific functions for the OPP code
> *
> * Copyright (C) 2009 Texas Instruments Incorporated.
> - * Nishanth Menon
> + * Nishanth Menon
> + * Copyright (C) 2009 Nokia Corporation
> + * Paul Walmsley
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License version 2 as
> @@ -34,5 +36,14 @@ unsigned long omap_twl_vsel_to_uv(const u8 vsel)
> */
> u8 omap_twl_uv_to_vsel(unsigned long uv)
> {
> - return ((uv / 100) - 6000) / 125;
> + u8 vsel;
> +
> + vsel = ((uv / 100) - 6000) / 125;
> +
> + /* round off to higher voltage */
> + /* XXX Surely not the best way to handle this. */
> + if (uv > omap_twl_vsel_to_uv(vsel))
> + vsel++;
> +
> + return vsel;
> }
>
>
>
ouch I missed this patch - this looks fine now.. thanks
Regards,
NM
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 12/12] OMAP3 OPP: move CPUFreq table init code to OPP layer
2009-12-18 0:47 ` [PATCH 12/12] OMAP3 OPP: move CPUFreq table init code to OPP layer Paul Walmsley
@ 2009-12-19 12:22 ` Menon, Nishanth
0 siblings, 0 replies; 18+ messages in thread
From: Menon, Nishanth @ 2009-12-19 12:22 UTC (permalink / raw)
To: Paul Walmsley; +Cc: linux-omap@vger.kernel.org
Paul Walmsley said the following on 12/18/2009 06:17 AM:
> Move omap2_clk_init_cpufreq_table() to opp_init_cpufreq_table() in opp.c
> where it now belongs. OMAP2 still needs to be converted to use the OPP layer,
> so it is using the old code.
>
Neat.. thanks.. helps Omap4 too I can see..
Acked-by: Nishanth Menon <nm@ti.com>
> ---
> arch/arm/mach-omap2/clock34xx.c | 55 +--------------------------------
> arch/arm/plat-omap/cpu-omap.c | 6 +++-
> arch/arm/plat-omap/include/plat/opp.h | 4 ++
> arch/arm/plat-omap/opp.c | 46 ++++++++++++++++++++++++++++
> 4 files changed, 56 insertions(+), 55 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
> index ba3dd70..6a40fb1 100644
> --- a/arch/arm/mach-omap2/clock34xx.c
> +++ b/arch/arm/mach-omap2/clock34xx.c
> @@ -27,7 +27,6 @@
> #include <linux/limits.h>
> #include <linux/bitops.h>
> #include <linux/err.h>
> -#include <linux/cpufreq.h>
>
> #include <plat/cpu.h>
> #include <plat/clock.h>
> @@ -257,56 +256,7 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
>
> /* Common clock code */
>
> -/*
> - * As it is structured now, this will prevent an OMAP2/3 multiboot
> - * kernel from compiling. This will need further attention.
> - */
> -#if defined(CONFIG_ARCH_OMAP3)
> -
> -#ifdef CONFIG_CPU_FREQ
> -
> -static struct cpufreq_frequency_table *freq_table;
> -
> -void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
> -{
> - int i = 0;
> - int opp_num;
> - struct omap_opp *opp = mpu_opps;
> - unsigned long freq = ULONG_MAX;
> -
> - if (!mpu_opps) {
> - pr_warning("%s: failed to initialize frequency"
> - "table\n", __func__);
> - return;
> - }
> - opp_num = opp_get_opp_count(mpu_opps);
> - if (opp_num < 0) {
> - pr_err("%s: no opp table?\n", __func__);
> - return;
> - }
> -
> - freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
> - (opp_num + 1), GFP_ATOMIC);
> - if (!freq_table) {
> - pr_warning("%s: failed to allocate frequency"
> - "table\n", __func__);
> - return;
> - }
> -
> - while (!IS_ERR(opp = opp_find_freq_floor(opp, &freq))) {
> - freq_table[i].index = i;
> - freq_table[i].frequency = freq / 1000;
> - i++;
> - /* set the next benchmark to search */
> - freq--;
> - }
> -
> - freq_table[i].index = i;
> - freq_table[i].frequency = CPUFREQ_TABLE_END;
> -
> - *table = &freq_table[0];
> -}
> -#endif
> +#ifdef CONFIG_ARCH_OMAP3
>
> struct clk_functions omap2_clk_functions = {
> .clk_enable = omap2_clk_enable,
> @@ -315,9 +265,6 @@ struct clk_functions omap2_clk_functions = {
> .clk_set_rate = omap2_clk_set_rate,
> .clk_set_parent = omap2_clk_set_parent,
> .clk_disable_unused = omap2_clk_disable_unused,
> -#ifdef CONFIG_CPU_FREQ
> - .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
> -#endif
> };
>
> /*
> diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
> index a2b5ee4..723834e 100644
> --- a/arch/arm/plat-omap/cpu-omap.c
> +++ b/arch/arm/plat-omap/cpu-omap.c
> @@ -132,7 +132,11 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy)
>
> policy->cur = policy->min = policy->max = omap_getspeed(0);
>
> - clk_init_cpufreq_table(&freq_table);
> + if (!cpu_is_omap34xx())
> + clk_init_cpufreq_table(&freq_table);
> + else
> + opp_init_cpufreq_table(mpu_opps, &freq_table);
> +
> if (freq_table) {
> result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
> if (!result)
> diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
> index b00f7f9..91b0aa6 100644
> --- a/arch/arm/plat-omap/include/plat/opp.h
> +++ b/arch/arm/plat-omap/include/plat/opp.h
> @@ -240,4 +240,8 @@ int opp_disable(struct omap_opp *opp);
> struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
> u8 opp_id);
>
> +void opp_init_cpufreq_table(struct omap_opp *opps,
> + struct cpufreq_frequency_table **table);
> +
> +
> #endif /* __ASM_ARM_OMAP_OPP_H */
> diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
> index 8bdad43..aaafc10 100644
> --- a/arch/arm/plat-omap/opp.c
> +++ b/arch/arm/plat-omap/opp.c
> @@ -14,6 +14,7 @@
> #include <linux/err.h>
> #include <linux/init.h>
> #include <linux/slab.h>
> +#include <linux/cpufreq.h>
>
> #include <plat/opp_twl_tps.h>
> #include <plat/opp.h>
> @@ -281,3 +282,48 @@ int opp_disable(struct omap_opp *opp)
> opp->enabled = false;
> return 0;
> }
> +
> +/* XXX document */
> +void opp_init_cpufreq_table(struct omap_opp *opps,
> + struct cpufreq_frequency_table **table)
> +{
> + int i = 0;
> + int opp_num;
> + unsigned long freq = ULONG_MAX;
> + struct cpufreq_frequency_table *freq_table;
> +
> + if (!opps) {
> + pr_warning("%s: failed to initialize frequency"
> + "table\n", __func__);
> + return;
> + }
> +
> + opp_num = opp_get_opp_count(opps);
> + if (opp_num < 0) {
> + pr_err("%s: no opp table?\n", __func__);
> + return;
> + }
> +
> + freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
> + (opp_num + 1), GFP_ATOMIC);
> + if (!freq_table) {
> + pr_warning("%s: failed to allocate frequency"
> + "table\n", __func__);
> + return;
> + }
> +
> + while (!OPP_TERM(opps)) {
> + if (opps->enabled) {
> + freq_table[i].index = i;
> + freq_table[i].frequency = freq / 1000;
> + i++;
> + }
> +
> + opps++;
> + }
> +
> + freq_table[i].index = i;
> + freq_table[i].frequency = CPUFREQ_TABLE_END;
> +
> + *table = &freq_table[0];
> +}
>
>
>
here is a future problem I see:
I think we need notifiers for opp_enable,disable and add -> this will
allow dynamic opp table modification allowing cpufreq changes accordingly.
Regards,
Nishanth Menon
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2009-12-19 12:22 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20091218004617.7694.84525.stgit@localhost.localdomain>
2009-12-18 0:47 ` [PATCH 01/12] OMAP OPP: remove some unnecessary variables Paul Walmsley
2009-12-18 17:28 ` Kevin Hilman
2009-12-18 0:47 ` [PATCH 02/12] OMAP OPP: split opp_find_freq_approx() into opp_find_freq_{floor, ceil}() Paul Walmsley
2009-12-18 0:47 ` [PATCH 03/12] OMAP OPP: only traverse opp_find_freq_floor() once Paul Walmsley
2009-12-19 12:10 ` Menon, Nishanth
2009-12-18 0:47 ` [PATCH 04/12] OMAP TWL/TPS OPP: move TWL/TPS-specific code to its own file Paul Walmsley
2009-12-19 12:14 ` Menon, Nishanth
2009-12-18 0:47 ` [PATCH 05/12] OMAP TWL/TPS OPP: vsel rounding belongs in opp_twl_tps.c Paul Walmsley
2009-12-19 12:16 ` Menon, Nishanth
2009-12-18 0:47 ` [PATCH 06/12] OMAP OPP: add microvolts DC ("u_volt") field into struct omap_opp Paul Walmsley
2009-12-18 0:47 ` [PATCH 07/12] OMAP OPP: add opp_find_opp_by_opp_id() Paul Walmsley
2009-12-18 0:47 ` [PATCH 08/12] OMAP SR/SRF: use opp_find_opp_by_opp_id() Paul Walmsley
2009-12-18 0:47 ` [PATCH 09/12] OMAP OPP: remove vsel Paul Walmsley
2009-12-18 0:47 ` [PATCH 10/12] OMAP OPP: remove "initial terminators" from OPP lists Paul Walmsley
2009-12-18 19:08 ` Kevin Hilman
2009-12-18 0:47 ` [PATCH 11/12] OMAP OPP: use kzalloc() rather than kmalloc() Paul Walmsley
2009-12-18 0:47 ` [PATCH 12/12] OMAP3 OPP: move CPUFreq table init code to OPP layer Paul Walmsley
2009-12-19 12:22 ` Menon, Nishanth
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox