From: b20788@freescale.com (Anson Huang)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: imx: avoid calling clk APIs in idle thread which may cause schedule
Date: Tue, 11 Feb 2014 16:11:47 +0800 [thread overview]
Message-ID: <20140211081146.GA20631@ubuntu> (raw)
In-Reply-To: <20140211061833.GD31484@S2101-09.ap.freescale.net>
On Tue, Feb 11, 2014 at 02:18:35PM +0800, Shawn Guo wrote:
> On Mon, Feb 10, 2014 at 02:34:50PM +0800, Anson Huang wrote:
> > @@ -81,19 +99,67 @@ static const u32 clks_init_on[] __initconst = {
> > * entering WAIT mode.
> > *
> > * This function will set the ARM clk to max value within the 12:5 limit.
> > + * As IPG clock is fixed at 66MHz(so ARM freq must not exceed 158.4MHz),
> > + * ARM freq are one of below setpoints: 396MHz, 792MHz and 996MHz, since
> > + * the clk APIs can NOT be called in idle thread(may cause kernel schedule
> > + * as there is sleep function in PLL wait function), so here we just slow
> > + * down ARM to below freq according to previous freq:
> > + *
> > + * run mode wait mode
> > + * 396MHz -> 132MHz;
> > + * 792MHz -> 158.4MHz;
> > + * 996MHz -> 142.3MHz;
> > */
> > +static int imx6sl_get_arm_divider_for_wait(void)
> > +{
> > + if (readl_relaxed(ccm_base + CCSR) & BM_CCSR_PLL1_SW_CLK_SEL) {
> > + return ARM_WAIT_DIV_396M;
> > + } else {
> > + if ((readl_relaxed(anatop_base + PLL_ARM) &
> > + BM_PLL_ARM_DIV_SELECT) == PLL_ARM_DIV_792M)
> > + return ARM_WAIT_DIV_792M;
> > + else
> > + return ARM_WAIT_DIV_996M;
> > + }
> > +}
> > +
> > +static void imx6sl_enable_pll_arm(bool enable)
> > +{
> > + static u32 saved_pll_arm;
> > + u32 val;
> > +
> > + if (enable) {
> > + saved_pll_arm = val = readl_relaxed(anatop_base + PLL_ARM);
> > + val |= BM_PLL_ARM_ENABLE;
> > + val &= ~BM_PLL_ARM_POWERDOWN;
> > + writel_relaxed(val, anatop_base + PLL_ARM);
> > + while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
> > + ;
> > + } else {
> > + writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
> > + }
> > +}
> > +
> > void imx6sl_set_wait_clk(bool enter)
> > {
> > - static unsigned long saved_arm_rate;
> > + static unsigned long saved_arm_div;
> >
> > + /*
> > + * According to hardware design, arm podf change need
> > + * PLL1 clock enabled.
> > + */
> > + imx6sl_enable_pll_arm(true);
>
> This only applies to the ARM_WAIT_DIV_396M case, since for the other two
> PLL1 must already be enabled, right?
Yes, I will add condition check to make sure it is only called when ARM is
@396MHz.
>
> > if (enter) {
> > - unsigned long ipg_rate = clk_get_rate(clks[IMX6SL_CLK_IPG]);
> > - unsigned long max_arm_wait_rate = (12 * ipg_rate) / 5;
> > - saved_arm_rate = clk_get_rate(clks[IMX6SL_CLK_ARM]);
> > - clk_set_rate(clks[IMX6SL_CLK_ARM], max_arm_wait_rate);
> > + saved_arm_div = readl_relaxed(ccm_base + CACRR);
> > + writel_relaxed(imx6sl_get_arm_divider_for_wait(),
> > + ccm_base + CACRR);
> > } else {
> > - clk_set_rate(clks[IMX6SL_CLK_ARM], saved_arm_rate);
> > + writel_relaxed(saved_arm_div, ccm_base + CACRR);
> > }
> > +
> > + while (__raw_readl(ccm_base + CDHIPR) & BM_CDHIPR_ARM_PODF_BUSY)
> > + ;
> > + imx6sl_enable_pll_arm(false);
> > }
> >
> > static void __init imx6sl_clocks_init(struct device_node *ccm_node)
> > @@ -110,6 +176,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
> >
> > np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
> > base = of_iomap(np, 0);
> > + anatop_base = base;
>
> More logical to put it after the WARN_ON() below?
>
> > WARN_ON(!base);
> >
> > /* type name parent base div_mask */
> > @@ -157,6 +224,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
> >
> > np = ccm_node;
> > base = of_iomap(np, 0);
> > + ccm_base = base;
>
> Ditto.
Will improve it in V2, thanks.
Anson.
>
> Shawn
>
> > WARN_ON(!base);
> >
> > /* Reuse imx6q pm code */
> > --
> > 1.7.9.5
> >
> >
>
prev parent reply other threads:[~2014-02-11 8:11 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-10 6:34 [PATCH] ARM: imx: avoid calling clk APIs in idle thread which may cause schedule Anson Huang
2014-02-11 6:18 ` Shawn Guo
2014-02-11 8:11 ` Anson Huang [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140211081146.GA20631@ubuntu \
--to=b20788@freescale.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.