[PATCHV3] OMAP3630: Clock: Workaround for DPLL HS divider limitation
From: Mike Turquette mturque...@ti.com Date: Fri, 5 Feb 2010 19:09:52 +0530 Subject: [PATCH] OMAP3630: Clock: Workaround for DPLL HS divider limitation This patch implements a workaround for the DPLL HS divider limitation in OMAP3630 as given by Errata ID: i556. Errata: When PWRDN bit is set, it resets the internal HSDIVIDER divide-by value (Mx). The reset value gets loaded instead of the previous value. The following HSDIVIDERs exhibit above behavior: . DPLL4 : M6 / M5 / M4 / M3 / M2 (CM_CLKEN_PLL[31:26] register bits) . DPLL3 : M3 (CM_CLKEN_PLL[12] register bit). Work Around: It is mandatory to apply the following sequence to ensure the write value will be loaded in DPLL HSDIVIDER FSM: The global sequence when using PWRDN bit is the following: . Disable Mx HSDIVIDER clock output related functional clock enable bits (in CM_FCLKEN_xxx / CM_ICLKEN_xxx) . Enable PWRDN bit of HSDIVIDER . Disable PWRDN bit of HSDIVIDER . Read current HSDIVIDER register value . Write different value in HSDIVIDER register . Write expected value in HSDIVIDER register . Enable Mx HSDIVIDER clock output related functional clocks (CM_FCLKEN_xxx / CM_ICLKEN_xxx) Signed-off-by: Mike Turquette mturque...@ti.com Signed-off-by: Vishwanath BS vishwanath...@ti.com Signed-off-by: Vijaykumar GN vijaykumar...@ti.com --- arch/arm/mach-omap2/clock34xx.c | 41 ++ arch/arm/mach-omap2/clock34xx.h |1 + arch/arm/mach-omap2/clock34xx_data.c | 20 3 files changed, 62 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index c1c1b93..1e6297f 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -133,6 +133,47 @@ const struct clkops clkops_omap3430es2_hsotgusb_wait = { .find_companion = omap2_clk_dflt_find_companion, }; +/** + * omap3_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering + * from HSDivider PWRDN problem Implements Errata ID: i556. + * @clk: DPLL output struct clk + * + * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck, dpll4_m5_ck + * dpll4_m6_ck dividers gets loaded with reset valueafter their respective + * PWRDN bits are set. + * Any dummy write (Any other value different from the Read value) to the + * corresponding CM_CLKSEL register will refresh the dividers. + */ +int omap3_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk) +{ + u32 dummy_v, orig_v, clksel_shift; + int ret; + + /* Enable PWRDN bit of HSDIVIDER */ + ret = omap2_dflt_clk_enable(clk); + + /* Restore the dividers */ + if (!ret) { + clksel_shift = __ffs(clk-parent-clksel_mask); + orig_v = dummy_v = __raw_readl(clk-parent-clksel_reg); + + /* Write any other value different from the Read value */ + dummy_v ^= (1 clksel_shift); + __raw_writel(dummy_v, clk-parent-clksel_reg); + + /* Write the original divider */ + __raw_writel(orig_v, clk-parent-clksel_reg); + } + return ret; +} + +const struct clkops clkops_omap3_pwrdn_with_hsdiv_wait_restore = { + .enable = omap3_pwrdn_clk_enable_with_hsdiv_restore, + .disable= omap2_dflt_clk_disable, + .find_companion = omap2_clk_dflt_find_companion, + .find_idlest= omap2_clk_dflt_find_idlest, +}; + const struct clkops omap3_clkops_noncore_dpll_ops = { .enable = omap3_noncore_dpll_enable, .disable= omap3_noncore_dpll_disable, diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index 313efc0..29ef390 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -21,5 +21,6 @@ extern const struct clkops clkops_omap3430es2_ssi_wait; extern const struct clkops clkops_omap3430es2_hsotgusb_wait; extern const struct clkops clkops_omap3430es2_dss_usbhost_wait; extern const struct clkops omap3_clkops_noncore_dpll_ops; +extern const struct clkops clkops_omap3_pwrdn_with_hsdiv_wait_restore; #endif diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c index 8728f1f..9d11d53 100644 --- a/arch/arm/mach-omap2/clock34xx_data.c +++ b/arch/arm/mach-omap2/clock34xx_data.c @@ -3240,6 +3240,26 @@ int __init omap3xxx_clk_init(void) } } + if (cpu_is_omap3630()) { + + /* +* For 3630: override clkops_omap2_dflt_wait for the +* clocks affected from PWRDN reset Limitation +*/ + dpll3_m3x2_ck.ops = + clkops_omap3_pwrdn_with_hsdiv_wait_restore; + dpll4_m2x2_ck.ops = + clkops_omap3_pwrdn_with_hsdiv_wait_restore; + dpll4_m3x2_ck.ops = + clkops_omap3_pwrdn_with_hsdiv_wait_restore; + dpll4_m4x2_ck.ops
RE: [PATCHV3] OMAP3630: Clock: Workaround for DPLL HS divider limitation
-Original Message- From: Paul Walmsley [mailto:p...@pwsan.com] Sent: Wednesday, February 10, 2010 11:33 AM To: G.N, Vijayakumar Cc: linux-omap@vger.kernel.org; Sripathy, Vishwanath; Turquette, Mike; khil...@deeprootsystems.com Subject: Re: [PATCHV3] OMAP3630: Clock: Workaround for DPLL HS divider limitation Hello Mike, Vijayakumar, one comment below. On Tue, 9 Feb 2010, G.N, Vijayakumar wrote: From: Mike Turquette mturque...@ti.com Date: Fri, 5 Feb 2010 19:09:52 +0530 Subject: [PATCH] OMAP3630: Clock: Workaround for DPLL HS divider limitation This patch implements a workaround for the DPLL HS divider limitation in OMAP3630 as given by Errata ID: i556. Errata: When PWRDN bit is set, it resets the internal HSDIVIDER divide-by value (Mx). The reset value gets loaded instead of the previous value. The following HSDIVIDERs exhibit above behavior: . DPLL4 : M6 / M5 / M4 / M3 / M2 (CM_CLKEN_PLL[31:26] register bits) . DPLL3 : M3 (CM_CLKEN_PLL[12] register bit). Work Around: It is mandatory to apply the following sequence to ensure the write value will be loaded in DPLL HSDIVIDER FSM: The global sequence when using PWRDN bit is the following: . Disable Mx HSDIVIDER clock output related functional clock enable bits (in CM_FCLKEN_xxx / CM_ICLKEN_xxx) . Enable PWRDN bit of HSDIVIDER . Disable PWRDN bit of HSDIVIDER . Read current HSDIVIDER register value . Write different value in HSDIVIDER register . Write expected value in HSDIVIDER register . Enable Mx HSDIVIDER clock output related functional clocks (CM_FCLKEN_xxx / CM_ICLKEN_xxx) Signed-off-by: Mike Turquette mturque...@ti.com Signed-off-by: Vishwanath BS vishwanath...@ti.com Signed-off-by: Vijaykumar GN vijaykumar...@ti.com --- arch/arm/mach-omap2/clock34xx.c | 41 ++ arch/arm/mach-omap2/clock34xx.h |1 + arch/arm/mach-omap2/clock34xx_data.c | 20 3 files changed, 62 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach- omap2/clock34xx.c index c1c1b93..1e6297f 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -133,6 +133,47 @@ const struct clkops clkops_omap3430es2_hsotgusb_wait = { .find_companion = omap2_clk_dflt_find_companion, }; +/** + * omap3_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering + * from HSDivider PWRDN problem Implements Errata ID: i556. + * @clk: DPLL output struct clk + * + * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck, dpll4_m5_ck + * dpll4_m6_ck dividers gets loaded with reset valueafter their respective + * PWRDN bits are set. + * Any dummy write (Any other value different from the Read value) to the + * corresponding CM_CLKSEL register will refresh the dividers. + */ +int omap3_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk) +{ + u32 dummy_v, orig_v, clksel_shift; + int ret; + + /* Enable PWRDN bit of HSDIVIDER */ + ret = omap2_dflt_clk_enable(clk); + + /* Restore the dividers */ + if (!ret) { + clksel_shift = __ffs(clk-parent-clksel_mask); + orig_v = dummy_v = __raw_readl(clk-parent-clksel_reg); + + /* Write any other value different from the Read value */ + dummy_v ^= (1 clksel_shift); Shouldn't there also be a: dummy_v = clk-parent-clksel_mask; here to avoid writing to reserved bits? XOR with 0x00 will always retains the original values, hence I don't see any requirement of mask. Example: For CM_CLKSEL1_PLL clksel_mask: #define OMAP3430_DIV_DPLL3_MASK (0x1f 16) clksel_shift = __ffs(clk-parent-clksel_mask); becomes 16 (1 clksel_shift) will become (1 16) XOR operator will only change the Divisor's LSB 1st bit to it's negated value. Hence we will be always changing the Divisor's LSB 1's bit and hence the value written will be different one from the existing value and won't be touching any reserved fileds. + __raw_writel(dummy_v, clk-parent-clksel_reg); + + /* Write the original divider */ + __raw_writel(orig_v, clk-parent-clksel_reg); + } + return ret; +} + +const struct clkops clkops_omap3_pwrdn_with_hsdiv_wait_restore = { + .enable = omap3_pwrdn_clk_enable_with_hsdiv_restore, + .disable= omap2_dflt_clk_disable, + .find_companion = omap2_clk_dflt_find_companion, + .find_idlest= omap2_clk_dflt_find_idlest, +}; + const struct clkops omap3_clkops_noncore_dpll_ops = { .enable = omap3_noncore_dpll_enable, .disable= omap3_noncore_dpll_disable, diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach- omap2/clock34xx.h index 313efc0..29ef390 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h
RE: [PATCHV3] OMAP3630: Clock: Workaround for DPLL HS divider limitation
Thanks :) -Original Message- From: Paul Walmsley [mailto:p...@pwsan.com] Sent: Wednesday, February 10, 2010 11:55 AM To: G.N, Vijayakumar Cc: linux-omap@vger.kernel.org; Sripathy, Vishwanath; Turquette, Mike; khil...@deeprootsystems.com Subject: RE: [PATCHV3] OMAP3630: Clock: Workaround for DPLL HS divider limitation Hello Vijayakumar, On Wed, 10 Feb 2010, G.N, Vijayakumar wrote: From: Paul Walmsley [mailto:p...@pwsan.com] Shouldn't there also be a: dummy_v = clk-parent-clksel_mask; here to avoid writing to reserved bits? XOR with 0x00 will always retains the original values, hence I don't see any requirement of mask. Example: For CM_CLKSEL1_PLL clksel_mask: #define OMAP3430_DIV_DPLL3_MASK (0x1f 16) clksel_shift = __ffs(clk-parent-clksel_mask); becomes 16 (1 clksel_shift) will become (1 16) XOR operator will only change the Divisor's LSB 1st bit to it's negated value. Hence we will be always changing the Divisor's LSB 1's bit and hence the value written will be different one from the existing value and won't be touching any reserved fileds. OK, thanks, looks like I misread the code. Queued for 2.6.34. - Paul -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCHV3] OMAP3630: Clock: Workaround for DPLL HS divider limitation
No Comments. -Original Message- From: Paul Walmsley [mailto:p...@pwsan.com] Sent: Wednesday, February 10, 2010 12:09 PM To: G.N, Vijayakumar Cc: linux-omap@vger.kernel.org; Sripathy, Vishwanath; Turquette, Mike; khil...@deeprootsystems.com Subject: RE: [PATCHV3] OMAP3630: Clock: Workaround for DPLL HS divider limitation On Wed, 10 Feb 2010, G.N, Vijayakumar wrote: Thanks :) I had to fix a few minor issues with the patch. Here's the patch as applied. Please advise if there are any further comments. - Paul From d88ef2155dce7a7d995e6dea37433d1643827553 Mon Sep 17 00:00:00 2001 From: Mike Turquette mturque...@ti.com Date: Tue, 9 Feb 2010 23:26:45 -0700 Subject: [PATCH] OMAP3630: Clock: Workaround for DPLL HS divider limitation This patch implements a workaround for the DPLL HS divider limitation in OMAP3630 as given by Errata ID: i556. Errata: When PWRDN bit is set, it resets the internal HSDIVIDER divide-by value (Mx). The reset value gets loaded instead of the previous value. The following HSDIVIDERs exhibit above behavior: . DPLL4 : M6 / M5 / M4 / M3 / M2 (CM_CLKEN_PLL[31:26] register bits) . DPLL3 : M3 (CM_CLKEN_PLL[12] register bit). Work Around: It is mandatory to apply the following sequence to ensure the write value will be loaded in DPLL HSDIVIDER FSM: The global sequence when using PWRDN bit is the following: . Disable Mx HSDIVIDER clock output related functional clock enable bits (in CM_FCLKEN_xxx / CM_ICLKEN_xxx) . Enable PWRDN bit of HSDIVIDER . Disable PWRDN bit of HSDIVIDER . Read current HSDIVIDER register value . Write different value in HSDIVIDER register . Write expected value in HSDIVIDER register . Enable Mx HSDIVIDER clock output related functional clocks (CM_FCLKEN_xxx / CM_ICLKEN_xxx) Signed-off-by: Mike Turquette mturque...@ti.com Signed-off-by: Vishwanath BS vishwanath...@ti.com Signed-off-by: Vijaykumar GN vijaykumar...@ti.com [p...@pwsan.com: updated patch to apply; made workaround function static; marked as being 36xx-specific] Signed-off-by: Paul Walmsley p...@pwsan.com --- arch/arm/mach-omap2/clock34xx.c | 42 ++ arch/arm/mach-omap2/clock34xx.h |3 ++ arch/arm/mach-omap2/clock34xx_data.c | 19 +++ 3 files changed, 64 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 37da629..ea6c2d6 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -150,6 +150,48 @@ const struct clkops clkops_omap3430es2_hsotgusb_wait = { .find_companion = omap2_clk_dflt_find_companion, }; +/** + * omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering + * from HSDivider PWRDN problem Implements Errata ID: i556. + * @clk: DPLL output struct clk + * + * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck, + * dpll4_m5_ck dpll4_m6_ck dividers gets loaded with reset + * valueafter their respective PWRDN bits are set. Any dummy write + * (Any other value different from the Read value) to the + * corresponding CM_CLKSEL register will refresh the dividers. + */ +static int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk) +{ + u32 dummy_v, orig_v, clksel_shift; + int ret; + + /* Clear PWRDN bit of HSDIVIDER */ + ret = omap2_dflt_clk_enable(clk); + + /* Restore the dividers */ + if (!ret) { + clksel_shift = __ffs(clk-parent-clksel_mask); + orig_v = dummy_v = __raw_readl(clk-parent-clksel_reg); + + /* Write any other value different from the Read value */ + dummy_v ^= (1 clksel_shift); + __raw_writel(dummy_v, clk-parent-clksel_reg); + + /* Write the original divider */ + __raw_writel(orig_v, clk-parent-clksel_reg); + } + + return ret; +} + +const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore = { + .enable = omap36xx_pwrdn_clk_enable_with_hsdiv_restore, + .disable= omap2_dflt_clk_disable, + .find_companion = omap2_clk_dflt_find_companion, + .find_idlest= omap2_clk_dflt_find_idlest, +}; + const struct clkops clkops_noncore_dpll_ops = { .enable = omap3_noncore_dpll_enable, .disable= omap3_noncore_dpll_disable, diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index e61e653..b9c65f5 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -26,4 +26,7 @@ extern const struct clkops clkops_noncore_dpll_ops; extern const struct clkops clkops_am35xx_ipss_module_wait; extern const struct clkops clkops_am35xx_ipss_wait; +/* OMAP36xx-specific clkops */ +extern const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore; + #endif diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm
RE: [PATCHV2 2/2] OMAP3630: Clock: Fixing HSDivider Limitation
-Original Message- From: Paul Walmsley [mailto:p...@pwsan.com] Sent: Tuesday, January 19, 2010 11:39 PM To: Turquette, Mike Cc: Kauppi Ari (EXT-Ixonos/Oulu); G.N, Vijayakumar; linux-omap@vger.kernel.org; khil...@deeprootsystems.com; Sripathy, Vishwanath Subject: Re: [PATCHV2 2/2] OMAP3630: Clock: Fixing HSDivider Limitation Hi, On Tue, 19 Jan 2010, Mike Turquette wrote: Kauppi Ari (EXT-Ixonos/Oulu) wrote: On Mon, 2010-01-18 at 19:04 +0100, ext Paul Walmsley wrote: (some missing attribution here) +int omap3_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk) +{ + u32 v; + int ret; + + /* enable the clock */ + ret = omap2_dflt_clk_enable(clk); + + /* Restore the dividers */ + if (!ret) { + v = __raw_readl(clk-parent-clksel_reg); + v += (1 clk-parent-clksel_shift); Using += here could affect many bits in the register if the add carries. This doesn't seem like what you want. Also, isn't there a risk of side-effects here, that if this bit was not already set, that everything further down the clock tree from this could be affected? Wouldn't it be best to just rewrite the correct clksel value? The assumption is that the divider is correct in the register so I guess the clock tree should be fine? The proper clksel/divider has been earlier set but for some reason HW loses the divider if PWRDN is toggled. In my testing that assumption was always correct. In fact that is what made this bug very difficult to track down: the register values were always the correct value programmed initially but the actual clocks were wrong. Our experiments with this issue show that just read/write of same value is not enough to refresh the HW. The clksel has to be written with a different divider first and then write the original divider back. ACK to the above comment. Registers need to be changed to a different value and back. Please put that into the comments on the function. Right now it says Any write to the corresponding CM_CLKSEL register will refresh the dividers. Also, in that case the v += / v -= seems more appropriate. The concern then is, what happens if the divider is already at its maximum value? Won't it wrap around, which could potentially result in excessively high clocks further down the tree? In this case it might be best to step down to the next lowest divider, rather than wrapping. Maybe something like this? (untested) u32 orig_v, v, c, clksel_shift, max_div; [...] v = __raw_readl(clk-parent-clksel_reg); orig_v = v; clksel_shift = __ffs(clk-parent-clksel_mask); max_div = clk-parent-clksel_mask clksel_shift; /* Isolate the current divider */ c = v clk-parent-clksel_mask; c = clksel_shift; /* Prevent excessively high clock rates if divider would wrap */ c += (c == max_div) ? -1 : 1; /* Write the temporarily altered divider back */ c = clksel_shift; v = ~c; v |= c; __raw_writel(v, clk-parent-clksel_reg); /* Write the original divider */ __raw_writel(orig_v, clk-parent-clksel_reg); This seems to better than which currently I have; I will incorporate and test it for the same. I will add few more comments to have a better clarity in the same function. Thanks Vijay - Paul -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCHV2 2/2] OMAP3630: Clock: Fixing HSDivider Limitation
:) Thanks.. -Original Message- From: Paul Walmsley [mailto:p...@pwsan.com] Sent: Wednesday, January 20, 2010 11:15 AM To: G.N, Vijayakumar Cc: Turquette, Mike; Kauppi Ari (EXT-Ixonos/Oulu); linux-omap@vger.kernel.org; khil...@deeprootsystems.com; Sripathy, Vishwanath Subject: RE: [PATCHV2 2/2] OMAP3630: Clock: Fixing HSDivider Limitation Hello Vijayakumar, On Wed, 20 Jan 2010, G.N, Vijayakumar wrote: This seems to better than which currently I have; I will incorporate and test it for the same. I will add few more comments to have a better clarity in the same function. That's fine but please keep in mind this section from CodingStyle: Generally, you want your comments to tell WHAT your code does, not HOW. Also, try to avoid putting comments inside a function body: if the function is so complex that you need to separately comment parts of it, you should probably go back to chapter 6 for a while. You can make small comments to note or warn about something particularly clever (or ugly), but try to avoid excess. Instead, put the comments at the head of the function, telling people what it does, and possibly WHY it does it. - Paul -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHV2 0/2] OMAP3630: Clock: Workaround for DPLL HS divider limitation
From e599557dc73a581001b39d595cfacdc45ec2 Mon Sep 17 00:00:00 2001 From: Vijaykumar GN vijaykumar...@ti.com Date: Tue, 12 Jan 2010 17:15:29 +0530 Subject: [PATCH 0/2] OMAP3630: Clock: Workaround for DPLL HS divider limitation This series of patch implements a workaround for the DPLL HS divider limitation in OMAP3630. Without this workaround the divider value goes to its reset state after the corresponding PWRDN bit is set from the CM_CLKEN_PLL register. The correct divider value can be restored by writing dummy value to the register than what is in there, and then re-writing the desired value. HS Dividers impacted are 1. DPLL3_M3 2. DPLL4_M2 3. DPLL4_M3 4. DPLL4_M4 5. DPLL4_M5 6. DPLL4_M6 This patch series has dependency on Clock framework reorganization available at http://patchwork.kernel.org/patch/73638/ http://patchwork.kernel.org/patch/73635/ http://patchwork.kernel.org/patch/73637/ http://patchwork.kernel.org/patch/73636/ V1: Initial Patch Series V2: Incorporated comments Mike Turquette (2): OMAP3630: Clock: add clksel_shift to struct clk OMAP3630: Clock: Fixing HSDivider Limitation arch/arm/mach-omap2/clock34xx.c | 36 ++ arch/arm/mach-omap2/clock34xx.h |1 + arch/arm/mach-omap2/clock34xx_data.c| 21 arch/arm/plat-omap/include/plat/clock.h |1 + 4 files changed, 62 insertions(+), 0 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHV2 1/2] OMAP3630: Clock: add clksel_shift to struct clk
From f9a7f877368830fdf28f9892940d05517f07a582 Mon Sep 17 00:00:00 2001 From: Mike Turquette mturque...@ti.com Date: Tue, 12 Jan 2010 16:58:39 +0530 Subject: [PATCH 1/2] OMAP3630: Clock: add clksel_shift to struct clk Introduces clksel_shift to struct clk and populates the same for dpll4_m3_ck, dpll4_m4_ck, dpll4_m2_ck, dpll4_m6, dpll4_m5_ck and dpll3_m3. The purpose of this change is to make it easy for a generic function to refresh specific CM_CLKSEL registers on a per-clock basis by first adding then subtracting the shift value from the register.This is the recommended sequence to solve HSDivider PWRDN limitations in OMAP3630. Signed-off-by: Mike Turquette mturque...@ti.com Signed-off-by: Vijaykumar GN vijaykumar...@ti.com --- arch/arm/mach-omap2/clock34xx_data.c|6 ++ arch/arm/plat-omap/include/plat/clock.h |1 + 2 files changed, 7 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c index 6473247..ed17501 100755 --- a/arch/arm/mach-omap2/clock34xx_data.c +++ b/arch/arm/mach-omap2/clock34xx_data.c @@ -537,6 +537,7 @@ static struct clk dpll3_m3_ck = { .init = omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), .clksel_mask= OMAP3430_DIV_DPLL3_MASK, + .clksel_shift = OMAP3430_DIV_DPLL3_SHIFT, .clksel = div16_dpll3_clksel, .clkdm_name = dpll3_clkdm, .recalc = omap2_clksel_recalc, @@ -677,6 +678,7 @@ static struct clk dpll4_m2_ck_3630 __initdata = { .init = omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3), .clksel_mask= OMAP3630_DIV_96M_MASK, + .clksel_shift = OMAP3430_DIV_96M_SHIFT, .clksel = div32_dpll4_clksel, .clkdm_name = dpll4_clkdm, .recalc = omap2_clksel_recalc, @@ -792,6 +794,7 @@ static struct clk dpll4_m3_ck_3630 __initdata = { .init = omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), .clksel_mask= OMAP3630_CLKSEL_TV_MASK, + .clksel_shift = OMAP3430_CLKSEL_TV_SHIFT, .clksel = div32_dpll4_clksel, .clkdm_name = dpll4_clkdm, .recalc = omap2_clksel_recalc, @@ -892,6 +895,7 @@ static struct clk dpll4_m4_ck_3630 __initdata = { .init = omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), .clksel_mask= OMAP3630_CLKSEL_DSS1_MASK, + .clksel_shift = OMAP3430_CLKSEL_DSS1_SHIFT, .clksel = div32_dpll4_clksel, .clkdm_name = dpll4_clkdm, .recalc = omap2_clksel_recalc, @@ -933,6 +937,7 @@ static struct clk dpll4_m5_ck_3630 __initdata = { .init = omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL), .clksel_mask= OMAP3630_CLKSEL_CAM_MASK, + .clksel_shift = OMAP3430_CLKSEL_CAM_SHIFT, .clksel = div32_dpll4_clksel, .clkdm_name = dpll4_clkdm, .recalc = omap2_clksel_recalc, @@ -970,6 +975,7 @@ static struct clk dpll4_m6_ck_3630 __initdata = { .init = omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), .clksel_mask= OMAP3630_DIV_DPLL4_MASK, + .clksel_shift = OMAP3430_DIV_DPLL4_SHIFT, .clksel = div32_dpll4_clksel, .clkdm_name = dpll4_clkdm, .recalc = omap2_clksel_recalc, diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index 71d78f7..e841755 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -93,6 +93,7 @@ struct clk { #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \ defined(CONFIG_ARCH_OMAP4) u8 fixed_div; + u8 clksel_shift; void __iomem*clksel_reg; u32 clksel_mask; const struct clksel *clksel; -- 1.5.6.3 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHV2 2/2] OMAP3630: Clock: Fixing HSDivider Limitation
From 719417657425d4f12369b5ddad79c86baddfefa5 Mon Sep 17 00:00:00 2001 From: Mike Turquette mturque...@ti.com Date: Mon, 18 Jan 2010 17:38:19 +0530 Subject: [PATCH 2/2] OMAP3630: Clock: Fixing HSDivider Limitation It implements the recommended sequence to solve HS divider PWRDN limitation in OMAP3630 DPLL3 and DPLL4. Without this workaround the divider value goes to its reset state after the corresponding PWRDN bit is set from the CM_CLKEN_PLL register. The correct divider value can be restored by writing a dummy value to the register different than what is in there, and then re-writing the desired value. This Work around is applicable for below HS Dividers. 1. DPLL3_M3 2. DPLL4_M2 3. DPLL4_M3 4. DPLL4_M4 5. DPLL4_M5 6. DPLL4_M6 Signed-off-by: Mike Turquette mturque...@ti.com Signed-off-by: Vishwanath BS vishwanath...@ti.com Signed-off-by: Vijaykumar GN vijaykumar...@ti.com --- arch/arm/mach-omap2/clock34xx.c | 36 ++ arch/arm/mach-omap2/clock34xx.h |1 + arch/arm/mach-omap2/clock34xx_data.c | 15 ++ 3 files changed, 52 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 0d30e53..e5213f8 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -146,6 +146,42 @@ const struct clkops clkops_omap3430es2_hsotgusb_wait = { .find_companion = omap2_clk_dflt_find_companion, }; +/** omap3_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering + * from HSDivider problem. + * @clk: DPLL output struct clk + * + * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck, dpll4_m5_ck + * dpll4_m6_ck dividers get lost after their respective PWRDN bits are set. + * Any write to the corresponding CM_CLKSEL register will refresh the + * dividers. Only x2 clocks are affected, so it is safe to trust the parent + * clock information to refresh the CM_CLKSEL registers. + */ +int omap3_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk) +{ + u32 v; + int ret; + + /* enable the clock */ + ret = omap2_dflt_clk_enable(clk); + + /* Restore the dividers */ + if (!ret) { + v = __raw_readl(clk-parent-clksel_reg); + v += (1 clk-parent-clksel_shift); + __raw_writel(v, clk-parent-clksel_reg); + v -= (1 clk-parent-clksel_shift); + __raw_writel(v, clk-parent-clksel_reg); + } + return ret; +} + +const struct clkops clkops_omap3_pwrdn_with_hsdiv_wait_restore = { + .enable = omap3_pwrdn_clk_enable_with_hsdiv_restore, + .disable= omap2_dflt_clk_disable, + .find_companion = omap2_clk_dflt_find_companion, + .find_idlest= omap2_clk_dflt_find_idlest, +}; + const struct clkops clkops_noncore_dpll_ops = { .enable = omap3_noncore_dpll_enable, .disable= omap3_noncore_dpll_disable, diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index 9a2c07e..6f7d271 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -20,5 +20,6 @@ extern const struct clkops clkops_omap3430es2_ssi_wait; extern const struct clkops clkops_omap3430es2_hsotgusb_wait; extern const struct clkops clkops_omap3430es2_dss_usbhost_wait; extern const struct clkops clkops_noncore_dpll_ops; +extern const struct clkops clkops_omap3_pwrdn_with_hsdiv_wait_restore; #endif diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c index 955d4ef..39a1b3c 100755 --- a/arch/arm/mach-omap2/clock34xx_data.c +++ b/arch/arm/mach-omap2/clock34xx_data.c @@ -3447,6 +3447,21 @@ int __init omap2_clk_init(void) dpll4_m4_ck = dpll4_m4_ck_3630; dpll4_m5_ck = dpll4_m5_ck_3630; dpll4_m6_ck = dpll4_m6_ck_3630; + + /* For 3630: override clkops_omap2_dflt_wait for the +* clocks affected from HSDivider PWRDN reset limitation */ + dpll3_m3x2_ck.ops = + clkops_omap3_pwrdn_with_hsdiv_wait_restore; + dpll4_m2x2_ck.ops = + clkops_omap3_pwrdn_with_hsdiv_wait_restore; + dpll4_m3x2_ck.ops = + clkops_omap3_pwrdn_with_hsdiv_wait_restore; + dpll4_m4x2_ck.ops = + clkops_omap3_pwrdn_with_hsdiv_wait_restore; + dpll4_m5x2_ck.ops = + clkops_omap3_pwrdn_with_hsdiv_wait_restore; + dpll4_m6x2_ck.ops = + clkops_omap3_pwrdn_with_hsdiv_wait_restore; } else { dpll4_dd = dpll4_dd_34xx; dpll4_m2_ck = dpll4_m2_ck_34xx; -- 1.5.6.3 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] OMAP3630 PM: Correct VDD1/VDD2 Retention and On voltage
Yes, If you have already thought of some specific place holder please let me know Thanks Vijay -Original Message- From: Kevin Hilman [mailto:khil...@deeprootsystems.com] Sent: Wednesday, January 13, 2010 1:15 AM To: G.N, Vijayakumar Cc: linux-omap@vger.kernel.org; Sripathy, Vishwanath Subject: Re: [PATCH] OMAP3630 PM: Correct VDD1/VDD2 Retention and On voltage G.N, Vijayakumar vijaykumar...@ti.com writes: From 61474f885fe048dd1b8b6f17cfbd1690ff281c49 Mon Sep 17 00:00:00 2001 From: Vijaykumar GN vijaykumar...@ti.com Date: Mon, 21 Dec 2009 12:43:14 +0530 Subject: [PATCH] OMAP3630 PM: Correct VDD1/VDD2 Retention and On voltage For OMAP3630 Retention Voltage must be set to OPP25 1. vdd1 retention voltage == 0.83 2. vdd2 retention voltage == 0.85 On Voltage must be at default OPP (OPP100) 1. vdd1 on voltage == 1.1 2. vdd2 on voltage == 1.375 Signed-off-by: Vishwanath Sripathy vishwanath...@ti.com Signed-off-by: Vijaykumar GN vijaykumar...@ti.com These are SoC-specific values, not board-specific values, right? We should have a way to do this in SoC common code instead of duplicating across board files. Kevin --- arch/arm/mach-omap2/board-3630sdp.c | 19 +++ arch/arm/mach-omap2/board-zoom3.c | 19 +++ 2 files changed, 38 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach- omap2/board-3630sdp.c index d509c08..4d464fb 100755 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -25,6 +25,24 @@ #include mux.h #include sdram-hynix-h8mbx00u0mer-0em.h +#include pm.h + +/* Update with the optimal setup values to be used on 3630sdp */ +static struct prm_setup_vc omap3_setuptime_table = { + .clksetup = 0x14A, + .voltsetup_time1 = 0x00B3, + .voltsetup_time2 = 0x00A0, + .voltoffset = 0x118, + .voltsetup2 = 0x32, + .vdd0_on = 0x28,/* 1.1v */ + .vdd0_onlp = 0x20, /* 1.0v */ + .vdd0_ret = 0x12, /* 0.83v */ + .vdd0_off = 0x00, /* 0.6v */ + .vdd1_on = 0x2B,/* 1.1375v */ + .vdd1_onlp = 0x20, /* 1.0v */ + .vdd1_ret = 0x14, /* 0.85v */ + .vdd1_off = 0x00, /* 0.6v */ +}; #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) @@ -79,6 +97,7 @@ static void __init omap_sdp_init_irq(void) { omap_board_config = sdp_config; omap_board_config_size = ARRAY_SIZE(sdp_config); + omap3_pm_init_vc(omap3_setuptime_table); omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params, NULL, NULL, NULL); diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board- zoom3.c index 0778077..2c1f954 100644 --- a/arch/arm/mach-omap2/board-zoom3.c +++ b/arch/arm/mach-omap2/board-zoom3.c @@ -23,6 +23,24 @@ #include mux.h #include sdram-hynix-h8mbx00u0mer-0em.h +#include pm.h + +/* Update with the optimal setup values to be used on Zoom3 */ +static struct prm_setup_vc omap3_setuptime_table = { + .clksetup = 0x14A, + .voltsetup_time1 = 0x00B3, + .voltsetup_time2 = 0x00A0, + .voltoffset = 0x118, + .voltsetup2 = 0x32, + .vdd0_on = 0x28,/* 1.1v */ + .vdd0_onlp = 0x20, /* 1.0v */ + .vdd0_ret = 0x12, /* 0.83v */ + .vdd0_off = 0x00, /* 0.6v */ + .vdd1_on = 0x2B,/* 1.1375v */ + .vdd1_onlp = 0x20, /* 1.0v */ + .vdd1_ret = 0x14, /* 0.85v */ + .vdd1_off = 0x00, /* 0.6v */ +}; static void __init omap_zoom_map_io(void) { @@ -37,6 +55,7 @@ static void __init omap_zoom_init_irq(void) { omap_board_config = zoom_config; omap_board_config_size = ARRAY_SIZE(zoom_config); + omap3_pm_init_vc(omap3_setuptime_table); omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params, NULL, NULL, NULL); -- 1.5.6.3 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] OMAP3630 PM: Correct VDD1/VDD2 Retention and On voltage
From 61474f885fe048dd1b8b6f17cfbd1690ff281c49 Mon Sep 17 00:00:00 2001 From: Vijaykumar GN vijaykumar...@ti.com Date: Mon, 21 Dec 2009 12:43:14 +0530 Subject: [PATCH] OMAP3630 PM: Correct VDD1/VDD2 Retention and On voltage For OMAP3630 Retention Voltage must be set to OPP25 1. vdd1 retention voltage == 0.83 2. vdd2 retention voltage == 0.85 On Voltage must be at default OPP (OPP100) 1. vdd1 on voltage == 1.1 2. vdd2 on voltage == 1.375 Signed-off-by: Vishwanath Sripathy vishwanath...@ti.com Signed-off-by: Vijaykumar GN vijaykumar...@ti.com --- arch/arm/mach-omap2/board-3630sdp.c | 19 +++ arch/arm/mach-omap2/board-zoom3.c | 19 +++ 2 files changed, 38 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index d509c08..4d464fb 100755 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -25,6 +25,24 @@ #include mux.h #include sdram-hynix-h8mbx00u0mer-0em.h +#include pm.h + +/* Update with the optimal setup values to be used on 3630sdp */ +static struct prm_setup_vc omap3_setuptime_table = { + .clksetup = 0x14A, + .voltsetup_time1 = 0x00B3, + .voltsetup_time2 = 0x00A0, + .voltoffset = 0x118, + .voltsetup2 = 0x32, + .vdd0_on = 0x28,/* 1.1v */ + .vdd0_onlp = 0x20, /* 1.0v */ + .vdd0_ret = 0x12, /* 0.83v */ + .vdd0_off = 0x00, /* 0.6v */ + .vdd1_on = 0x2B,/* 1.1375v */ + .vdd1_onlp = 0x20, /* 1.0v */ + .vdd1_ret = 0x14, /* 0.85v */ + .vdd1_off = 0x00, /* 0.6v */ +}; #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) @@ -79,6 +97,7 @@ static void __init omap_sdp_init_irq(void) { omap_board_config = sdp_config; omap_board_config_size = ARRAY_SIZE(sdp_config); + omap3_pm_init_vc(omap3_setuptime_table); omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params, NULL, NULL, NULL); diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c index 0778077..2c1f954 100644 --- a/arch/arm/mach-omap2/board-zoom3.c +++ b/arch/arm/mach-omap2/board-zoom3.c @@ -23,6 +23,24 @@ #include mux.h #include sdram-hynix-h8mbx00u0mer-0em.h +#include pm.h + +/* Update with the optimal setup values to be used on Zoom3 */ +static struct prm_setup_vc omap3_setuptime_table = { + .clksetup = 0x14A, + .voltsetup_time1 = 0x00B3, + .voltsetup_time2 = 0x00A0, + .voltoffset = 0x118, + .voltsetup2 = 0x32, + .vdd0_on = 0x28,/* 1.1v */ + .vdd0_onlp = 0x20, /* 1.0v */ + .vdd0_ret = 0x12, /* 0.83v */ + .vdd0_off = 0x00, /* 0.6v */ + .vdd1_on = 0x2B,/* 1.1375v */ + .vdd1_onlp = 0x20, /* 1.0v */ + .vdd1_ret = 0x14, /* 0.85v */ + .vdd1_off = 0x00, /* 0.6v */ +}; static void __init omap_zoom_map_io(void) { @@ -37,6 +55,7 @@ static void __init omap_zoom_init_irq(void) { omap_board_config = zoom_config; omap_board_config_size = ARRAY_SIZE(zoom_config); + omap3_pm_init_vc(omap3_setuptime_table); omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params, h8mbx00u0mer0em_sdrc_params, NULL, NULL, NULL); -- 1.5.6.3 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3] omap3: pm: removes hardcoded VDD1/2 OPP values and make threshold generic
With 3 patches I am trying to 1. Remove hardcoded VDD1 OPP values and make threshold generic 2. Remove hardcoded VDD2 OPP values and make threshold generic 3. adding new api inplace of MIN/MAX_VDD1/VDD2_OPP to support 3630 OPP constraning along with the existing 3430 constraint. Patches are rebased on the 2.6.32-rc7. Patches have been tested for 3630 for 2.6.32-rc5. Thanks and Regards Vijay -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] omap3: pm: removes hardcoded VDD1/2 OPP values and make threshold generic
From e5e225fc19410178ad378acc74183a1bf1f0251a Mon Sep 17 00:00:00 2001 From: Vijay Kumar vijaykumar...@ti.com Date: Thu, 19 Nov 2009 14:39:59 +0530 Subject: [PATCH 1/3] omap3: pm: Adding facility to support OPP dynamically introduce new accessor api's for 1. Correcting VDD2 DVFS OPP threshold 2. Removing hardcoded VDD1 OPP values and make threshold generic Signed-off-by: Vijay Kumar vijaykumar...@ti.com Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap2/clock34xx.c|2 +- arch/arm/mach-omap2/pm.c |5 ++- arch/arm/mach-omap2/pm34xx.c | 39 arch/arm/mach-omap2/resource34xx.c |3 +- arch/arm/plat-omap/include/plat/omap-pm.h | 27 +++ arch/arm/plat-omap/include/plat/omap34xx.h | 11 +--- 6 files changed, 79 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index da5bc1f..9cfc7a0 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -1042,7 +1042,7 @@ static unsigned long omap3_clkoutx2_recalc(struct clk *clk) #if defined(CONFIG_ARCH_OMAP3) #ifdef CONFIG_CPU_FREQ -static struct cpufreq_frequency_table freq_table[MAX_VDD1_OPP+1]; +static struct cpufreq_frequency_table freq_table[MAX_VDD1_OPPS+1]; void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) { diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index b324315..ba018f8 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -14,6 +14,7 @@ #include plat/resource.h #include plat/omap34xx.h +#include plat/omap-pm.h #include pm.h @@ -92,13 +93,13 @@ static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr, } if (attr == vdd1_opp_attr) { - if (value 1 || value 5) { + if (value MIN_VDD1_OPP || value MAX_VDD1_OPP) { printk(KERN_ERR vdd_opp_store: Invalid value\n); return -EINVAL; } resource_set_opp_level(VDD1_OPP, value, flags); } else if (attr == vdd2_opp_attr) { - if (value 2 || value 3) { + if (value MIN_VDD2_OPP || value 3) { printk(KERN_ERR vdd_opp_store: Invalid value\n); return -EINVAL; } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index c328164..1ed7f53 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -1059,6 +1059,45 @@ void omap3_pm_init_vc(struct prm_setup_vc *setup_vc) prm_setup.vdd1_off = setup_vc-vdd1_off; } +int omap3_get_max_vdd1_opp(void) +{ + if (cpu_is_omap3630()) + return VDD1_OPP4; + else /* Place holder for other 34xx (3430/3440) */ + return VDD1_OPP5; +} +EXPORT_SYMBOL(omap3_get_max_vdd1_opp); + +int omap3_get_min_vdd1_opp(void) +{ + if (cpu_is_omap3630()) + return VDD1_OPP1; + else /* Place holder for other 34xx (3430/3440) */ + return VDD1_OPP1; +} +EXPORT_SYMBOL(omap3_get_min_vdd1_opp); + +int omap3_get_max_vdd2_opp(void) +{ + if (cpu_is_omap3630()) + return VDD2_OPP3; + else /* Place holder for other 34xx (3430/3440) */ + return VDD2_OPP3; + +} +EXPORT_SYMBOL(omap3_get_max_vdd2_opp); + +int omap3_get_min_vdd2_opp(void) +{ + if (cpu_is_omap3630()) + return VDD2_OPP2; + else /* Place holder for other 34xx (3430/3440) */ + return VDD2_OPP1; + +} +EXPORT_SYMBOL(omap3_get_min_vdd2_opp); + + static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) { struct power_state *pwrst; diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c index 04be4d2..cc85601 100644 --- a/arch/arm/mach-omap2/resource34xx.c +++ b/arch/arm/mach-omap2/resource34xx.c @@ -382,7 +382,8 @@ int set_opp(struct shared_resource *resp, u32 target_level) * throughput in KiB/s for 100 Mhz = 100 * 1000 * 4. */ if (target_level = 3) - resource_request(vdd2_opp, vdd2_dev, 40); + resource_request(vdd2_opp, vdd2_dev, + (4 * (l3_opps + MAX_VDD2_OPP)-rate / 1000)); } else if (resp == vdd2_resp) { tput = target_level; diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h index 583e540..b089ccc 100644 --- a/arch/arm/plat-omap/include/plat/omap-pm.h +++ b/arch/arm/plat-omap/include/plat/omap-pm.h @@ -322,5 +322,32 @@ unsigned long omap_pm_cpu_get_freq(void); */ int omap_pm_get_dev_context_loss_count(struct device *dev); +/** + * omap3_get_max_opp - report Max OPP entries available for supplied VDD1 resource + * + * Returns the Max OPP entries available for
[PATCH 2/3] omap3: pm: removes hardcoded VDD1/2 OPP values and make threshold generic
From 3a4213ec9284c04e1a6a3b14094819e70ac951d9 Mon Sep 17 00:00:00 2001 From: Vijay Kumar vijaykumar...@ti.com Date: Thu, 19 Nov 2009 15:06:30 +0530 Subject: [PATCH 2/3] Correct VDD2 DVFS OPP threshold VDD2 OPP is linked with VDD1 OPP. THis patch removes hardcoded VDD2 OPP values and make threshold generic Signed-off-by: Vishwanath B.S. vishwanath...@ti.com Signed-off-by: Vijay Kumar vijaykumar...@ti.com --- arch/arm/mach-omap2/resource34xx.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c index cc85601..3bdb1f9 100644 --- a/arch/arm/mach-omap2/resource34xx.c +++ b/arch/arm/mach-omap2/resource34xx.c @@ -372,7 +372,7 @@ int set_opp(struct shared_resource *resp, u32 target_level) int ind; if (resp == vdd1_resp) { - if (target_level 3) + if (target_level MAX_VDD2_OPP) resource_release(vdd2_opp, vdd2_dev); resource_set_opp_level(VDD1_OPP, target_level, 0); @@ -381,7 +381,7 @@ int set_opp(struct shared_resource *resp, u32 target_level) * is at 100Mhz or above. * throughput in KiB/s for 100 Mhz = 100 * 1000 * 4. */ - if (target_level = 3) + if (target_level MIN_VDD2_OPP) resource_request(vdd2_opp, vdd2_dev, (4 * (l3_opps + MAX_VDD2_OPP)-rate / 1000)); @@ -391,7 +391,7 @@ int set_opp(struct shared_resource *resp, u32 target_level) /* Convert the tput in KiB/s to Bus frequency in MHz */ req_l3_freq = (tput * 1000)/4; - for (ind = 2; ind = MAX_VDD2_OPP; ind++) + for (ind = MIN_VDD2_OPP; ind = MAX_VDD2_OPP; ind++) if ((l3_opps + ind)-rate = req_l3_freq) { target_level = ind; break; -- 1.5.4.3 Thanks and Regards Vijay-- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] omap3: pm: removes hardcoded VDD1/2 OPP values and make threshold generic
From 202416dbdf3fce31bfd76f1e74dda89b382a78c3 Mon Sep 17 00:00:00 2001 From: Vijay Kumar vijaykumar...@ti.com Date: Thu, 19 Nov 2009 15:07:38 +0530 Subject: [PATCH 3/3] OMAP 3630: Update VDD2 values The OMAP3630 VDD2 minimum value is 1 and Maximum value is 2. The VDD2 API's are updated to return proper VDD2 values. Signed-off-by: Charulatha V ch...@ti.com Signed-off-by: Manjunath GK manj...@ti.com Signed-off-by: Vijay Kumar vijaykumar...@ti.com --- arch/arm/mach-omap2/pm34xx.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 1ed7f53..c240804 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -1080,7 +1080,7 @@ EXPORT_SYMBOL(omap3_get_min_vdd1_opp); int omap3_get_max_vdd2_opp(void) { if (cpu_is_omap3630()) - return VDD2_OPP3; + return VDD2_OPP2; else /* Place holder for other 34xx (3430/3440) */ return VDD2_OPP3; @@ -1090,9 +1090,9 @@ EXPORT_SYMBOL(omap3_get_max_vdd2_opp); int omap3_get_min_vdd2_opp(void) { if (cpu_is_omap3630()) - return VDD2_OPP2; - else /* Place holder for other 34xx (3430/3440) */ return VDD2_OPP1; + else /* Place holder for other 34xx (3430/3440) */ + return VDD2_OPP2; } EXPORT_SYMBOL(omap3_get_min_vdd2_opp); -- 1.5.4.3 Thanks and Regards Vijay-- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 3/3] omap3: pm: removes hardcoded VDD1/2 OPP values and make threshold generic
My apologies for the noise generated for the below patches submitted by me. http://patchwork.kernel.org/patch/61277/ http://patchwork.kernel.org/patch/61276/ http://patchwork.kernel.org/patch/61275/ I was not aware of the discussions happening on dynamic OPP management for supporting multiple OMAP cpu types. Please disregard the above patch series Best Regards Vijay -Original Message- From: linux-omap-ow...@vger.kernel.org [mailto:linux-omap-ow...@vger.kernel.org] On Behalf Of G.N, Vijayakumar Sent: Thursday, November 19, 2009 4:56 PM To: khil...@deeprootsystems.com; linux-omap@vger.kernel.org Subject: [PATCH 3/3] omap3: pm: removes hardcoded VDD1/2 OPP values and make threshold generic From 202416dbdf3fce31bfd76f1e74dda89b382a78c3 Mon Sep 17 00:00:00 2001 From: Vijay Kumar vijaykumar...@ti.com Date: Thu, 19 Nov 2009 15:07:38 +0530 Subject: [PATCH 3/3] OMAP 3630: Update VDD2 values The OMAP3630 VDD2 minimum value is 1 and Maximum value is 2. The VDD2 API's are updated to return proper VDD2 values. Signed-off-by: Charulatha V ch...@ti.com Signed-off-by: Manjunath GK manj...@ti.com Signed-off-by: Vijay Kumar vijaykumar...@ti.com --- arch/arm/mach-omap2/pm34xx.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 1ed7f53..c240804 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -1080,7 +1080,7 @@ EXPORT_SYMBOL(omap3_get_min_vdd1_opp); int omap3_get_max_vdd2_opp(void) { if (cpu_is_omap3630()) - return VDD2_OPP3; + return VDD2_OPP2; else /* Place holder for other 34xx (3430/3440) */ return VDD2_OPP3; @@ -1090,9 +1090,9 @@ EXPORT_SYMBOL(omap3_get_max_vdd2_opp); int omap3_get_min_vdd2_opp(void) { if (cpu_is_omap3630()) - return VDD2_OPP2; - else /* Place holder for other 34xx (3430/3440) */ return VDD2_OPP1; + else /* Place holder for other 34xx (3430/3440) */ + return VDD2_OPP2; } EXPORT_SYMBOL(omap3_get_min_vdd2_opp); -- 1.5.4.3 Thanks and Regards Vijay-- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html