* [PATCH v4 1/2] clk: at91: fix clk-generated parenting @ 2017-05-12 14:25 Alexandre Belloni 2017-05-12 14:25 ` [PATCH v4 2/2] clk: at91: Add sama5d2 suspend/resume Alexandre Belloni 2017-05-19 1:33 ` [PATCH v4 1/2] clk: at91: fix clk-generated parenting Stephen Boyd 0 siblings, 2 replies; 7+ messages in thread From: Alexandre Belloni @ 2017-05-12 14:25 UTC (permalink / raw) To: Boris Brezillon, Stephen Boyd, Nicolas Ferre Cc: linux-clk, linux-kernel, Alexandre Belloni clk_generated_startup is called after clk_hw_register. So the first call to get_parent will not have the correct value (i.e. 0) and because this is cached, it may never be updated. Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> --- drivers/clk/at91/clk-generated.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 4e1cd5aa69d8..70474bd97a10 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -260,13 +260,12 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, gck->lock = lock; gck->range = *range; + clk_generated_startup(gck); hw = &gck->hw; ret = clk_hw_register(NULL, &gck->hw); if (ret) { kfree(gck); hw = ERR_PTR(ret); - } else - clk_generated_startup(gck); return hw; } -- 2.11.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v4 2/2] clk: at91: Add sama5d2 suspend/resume 2017-05-12 14:25 [PATCH v4 1/2] clk: at91: fix clk-generated parenting Alexandre Belloni @ 2017-05-12 14:25 ` Alexandre Belloni 2017-06-01 7:46 ` Stephen Boyd 2017-05-19 1:33 ` [PATCH v4 1/2] clk: at91: fix clk-generated parenting Stephen Boyd 1 sibling, 1 reply; 7+ messages in thread From: Alexandre Belloni @ 2017-05-12 14:25 UTC (permalink / raw) To: Boris Brezillon, Stephen Boyd, Nicolas Ferre Cc: linux-clk, linux-kernel, Alexandre Belloni On sama5d2, VDD core maybe be cut while in suspend. This means registers will be lost. Ensure they are saved and restored properly. Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> --- Changes in v4: - only save and restore PCR for used ids drivers/clk/at91/clk-generated.c | 3 + drivers/clk/at91/clk-peripheral.c | 4 +- drivers/clk/at91/pmc.c | 129 ++++++++++++++++++++++++++++++++++++++ drivers/clk/at91/pmc.h | 2 + 4 files changed, 137 insertions(+), 1 deletion(-) diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 70474bd97a10..f0b7ae904ce2 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -266,6 +266,9 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, if (ret) { kfree(gck); hw = ERR_PTR(ret); + } else { + pmc_register_id(id); + } return hw; } diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index dc29fd979d3f..770118369230 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c @@ -367,8 +367,10 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, if (ret) { kfree(periph); hw = ERR_PTR(ret); - } else + } else { clk_sam9x5_peripheral_autodiv(periph); + pmc_register_id(id); + } return hw; } diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 526df5ba042d..a4cd9f35160e 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -13,12 +13,16 @@ #include <linux/clk/at91_pmc.h> #include <linux/of.h> #include <linux/mfd/syscon.h> +#include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/syscore_ops.h> #include <asm/proc-fns.h> #include "pmc.h" +#define PMC_MAX_IDS 128 + int of_at91_get_clk_range(struct device_node *np, const char *propname, struct clk_range *range) { @@ -41,3 +45,128 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname, return 0; } EXPORT_SYMBOL_GPL(of_at91_get_clk_range); + +static u8 registered_ids[PMC_MAX_IDS]; + +void pmc_register_id(u8 id) +{ + int i; + + for (i = 0; i < PMC_MAX_IDS; i++) { + if (registered_ids[i] == 0) { + registered_ids[i] = id; + break; + } + if (registered_ids[i] == id) + break; + } +} + +#ifdef CONFIG_PM +static struct regmap *pmcreg; + +static struct +{ + u32 scsr; + u32 pcsr0; + u32 uckr; + u32 mor; + u32 mcfr; + u32 pllar; + u32 mckr; + u32 usb; + u32 imr; + u32 pcsr1; + u32 pcr[PMC_MAX_IDS]; + u32 audio_pll0; + u32 audio_pll1; +} pmc_cache; + +static int pmc_suspend(void) +{ + int i; + + regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.scsr); + regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0); + regmap_read(pmcreg, AT91_CKGR_UCKR, &pmc_cache.uckr); + regmap_read(pmcreg, AT91_CKGR_MOR, &pmc_cache.mor); + regmap_read(pmcreg, AT91_CKGR_MCFR, &pmc_cache.mcfr); + regmap_read(pmcreg, AT91_CKGR_PLLAR, &pmc_cache.pllar); + regmap_read(pmcreg, AT91_PMC_MCKR, &pmc_cache.mckr); + regmap_read(pmcreg, AT91_PMC_USB, &pmc_cache.usb); + regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.imr); + regmap_read(pmcreg, AT91_PMC_PCSR1, &pmc_cache.pcsr1); + + for (i = 0; registered_ids[i]; i++) { + regmap_write(pmcreg, AT91_PMC_PCR, + (registered_ids[i] & AT91_PMC_PCR_PID_MASK)); + regmap_read(pmcreg, AT91_PMC_PCR, + &pmc_cache.pcr[registered_ids[i]]); + } + + return 0; +} + +static void pmc_resume(void) +{ + int i, ret = 0; + u32 tmp; + + regmap_read(pmcreg, AT91_PMC_MCKR, &tmp); + if (pmc_cache.mckr != tmp) + pr_warn("MCKR was not configured properly by the firmware\n"); + regmap_read(pmcreg, AT91_CKGR_PLLAR, &tmp); + if (pmc_cache.pllar != tmp) + pr_warn("PLLAR was not configured properly by the firmware\n"); + + regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.scsr); + regmap_write(pmcreg, AT91_PMC_PCER, pmc_cache.pcsr0); + regmap_write(pmcreg, AT91_CKGR_UCKR, pmc_cache.uckr); + regmap_write(pmcreg, AT91_CKGR_MOR, pmc_cache.mor); + regmap_write(pmcreg, AT91_CKGR_MCFR, pmc_cache.mcfr); + regmap_write(pmcreg, AT91_PMC_USB, pmc_cache.usb); + regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.imr); + regmap_write(pmcreg, AT91_PMC_PCER1, pmc_cache.pcsr1); + + for (i = 0; registered_ids[i]; i++) { + regmap_write(pmcreg, AT91_PMC_PCR, + pmc_cache.pcr[registered_ids[i]] | + AT91_PMC_PCR_CMD); + } + + if (pmc_cache.uckr & AT91_PMC_UPLLEN) { + ret = regmap_read_poll_timeout(pmcreg, AT91_PMC_SR, tmp, + !(tmp & AT91_PMC_LOCKU), + 10, 5000); + if (ret) + pr_crit("USB PLL didn't lock when resuming\n"); + } +} + +static struct syscore_ops pmc_syscore_ops = { + .suspend = pmc_suspend, + .resume = pmc_resume, +}; + +static const struct of_device_id sama5d2_pmc_dt_ids[] = { + { .compatible = "atmel,sama5d2-pmc" }, + { /* sentinel */ } +}; + +static int __init pmc_register_ops(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids); + + pmcreg = syscon_node_to_regmap(np); + if (IS_ERR(pmcreg)) + return PTR_ERR(pmcreg); + + register_syscore_ops(&pmc_syscore_ops); + + return 0; +} +/* This has to happen before arch_initcall because of the tcb_clksrc driver */ +postcore_initcall(pmc_register_ops); +#endif diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 5771fff0ee3f..aa7e1f1e3265 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -29,4 +29,6 @@ struct clk_range { int of_at91_get_clk_range(struct device_node *np, const char *propname, struct clk_range *range); +void pmc_register_id(u8 id); + #endif /* __PMC_H_ */ -- 2.11.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v4 2/2] clk: at91: Add sama5d2 suspend/resume 2017-05-12 14:25 ` [PATCH v4 2/2] clk: at91: Add sama5d2 suspend/resume Alexandre Belloni @ 2017-06-01 7:46 ` Stephen Boyd 2017-06-05 14:25 ` Alexandre Belloni 0 siblings, 1 reply; 7+ messages in thread From: Stephen Boyd @ 2017-06-01 7:46 UTC (permalink / raw) To: Alexandre Belloni; +Cc: Boris Brezillon, Nicolas Ferre, linux-clk, linux-kernel On 05/12, Alexandre Belloni wrote: > On sama5d2, VDD core maybe be cut while in suspend. This means registers > will be lost. Ensure they are saved and restored properly. > > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> > --- > Changes in v4: > - only save and restore PCR for used ids > > drivers/clk/at91/clk-generated.c | 3 + > drivers/clk/at91/clk-peripheral.c | 4 +- > drivers/clk/at91/pmc.c | 129 ++++++++++++++++++++++++++++++++++++++ > drivers/clk/at91/pmc.h | 2 + > 4 files changed, 137 insertions(+), 1 deletion(-) > > diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c > index 70474bd97a10..f0b7ae904ce2 100644 > --- a/drivers/clk/at91/clk-generated.c > +++ b/drivers/clk/at91/clk-generated.c > @@ -266,6 +266,9 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, > if (ret) { > kfree(gck); > hw = ERR_PTR(ret); > + } else { > + pmc_register_id(id); > + } > > return hw; > } > diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c > index dc29fd979d3f..770118369230 100644 > --- a/drivers/clk/at91/clk-peripheral.c > +++ b/drivers/clk/at91/clk-peripheral.c > @@ -367,8 +367,10 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, > if (ret) { > kfree(periph); > hw = ERR_PTR(ret); > - } else > + } else { > clk_sam9x5_peripheral_autodiv(periph); > + pmc_register_id(id); > + } > > return hw; > } > diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c > index 526df5ba042d..a4cd9f35160e 100644 > --- a/drivers/clk/at91/pmc.c > +++ b/drivers/clk/at91/pmc.c > @@ -13,12 +13,16 @@ > #include <linux/clk/at91_pmc.h> > #include <linux/of.h> > #include <linux/mfd/syscon.h> > +#include <linux/platform_device.h> > #include <linux/regmap.h> > +#include <linux/syscore_ops.h> > > #include <asm/proc-fns.h> > > #include "pmc.h" > > +#define PMC_MAX_IDS 128 > + > int of_at91_get_clk_range(struct device_node *np, const char *propname, > struct clk_range *range) > { > @@ -41,3 +45,128 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname, > return 0; > } > EXPORT_SYMBOL_GPL(of_at91_get_clk_range); > + > +static u8 registered_ids[PMC_MAX_IDS]; > + > +void pmc_register_id(u8 id) > +{ Shouldn't this also be inside CONFIG_PM? And then pmc_register_id() is a nop function when CONFIG_PM=n? > + int i; > + > + for (i = 0; i < PMC_MAX_IDS; i++) { > + if (registered_ids[i] == 0) { > + registered_ids[i] = id; > + break; > + } > + if (registered_ids[i] == id) > + break; > + } > +} -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 2/2] clk: at91: Add sama5d2 suspend/resume 2017-06-01 7:46 ` Stephen Boyd @ 2017-06-05 14:25 ` Alexandre Belloni 0 siblings, 0 replies; 7+ messages in thread From: Alexandre Belloni @ 2017-06-05 14:25 UTC (permalink / raw) To: Stephen Boyd; +Cc: Boris Brezillon, Nicolas Ferre, linux-clk, linux-kernel Hi, On 01/06/2017 at 00:46:44 -0700, Stephen Boyd wrote: > > + > > +static u8 registered_ids[PMC_MAX_IDS]; > > + > > +void pmc_register_id(u8 id) > > +{ > > Shouldn't this also be inside CONFIG_PM? And then > pmc_register_id() is a nop function when CONFIG_PM=n? > I'll do that. I'll rebase on top of clk-next once you fix my silly mistake. > > + int i; > > + > > + for (i = 0; i < PMC_MAX_IDS; i++) { > > + if (registered_ids[i] == 0) { > > + registered_ids[i] = id; > > + break; > > + } > > + if (registered_ids[i] == id) > > + break; > > + } > > +} > > -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, > a Linux Foundation Collaborative Project -- Alexandre Belloni, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 1/2] clk: at91: fix clk-generated parenting 2017-05-12 14:25 [PATCH v4 1/2] clk: at91: fix clk-generated parenting Alexandre Belloni 2017-05-12 14:25 ` [PATCH v4 2/2] clk: at91: Add sama5d2 suspend/resume Alexandre Belloni @ 2017-05-19 1:33 ` Stephen Boyd 2017-05-30 9:50 ` Alexandre Belloni 1 sibling, 1 reply; 7+ messages in thread From: Stephen Boyd @ 2017-05-19 1:33 UTC (permalink / raw) To: Alexandre Belloni; +Cc: Boris Brezillon, Nicolas Ferre, linux-clk, linux-kernel On 05/12, Alexandre Belloni wrote: > clk_generated_startup is called after clk_hw_register. So the first call to > get_parent will not have the correct value (i.e. 0) and because this is > cached, it may never be updated. > > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> > --- Fixes tag? -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 1/2] clk: at91: fix clk-generated parenting 2017-05-19 1:33 ` [PATCH v4 1/2] clk: at91: fix clk-generated parenting Stephen Boyd @ 2017-05-30 9:50 ` Alexandre Belloni 2017-06-01 7:47 ` Stephen Boyd 0 siblings, 1 reply; 7+ messages in thread From: Alexandre Belloni @ 2017-05-30 9:50 UTC (permalink / raw) To: Stephen Boyd; +Cc: Boris Brezillon, Nicolas Ferre, linux-clk, linux-kernel On 18/05/2017 at 18:33:02 -0700, Stephen Boyd wrote: > On 05/12, Alexandre Belloni wrote: > > clk_generated_startup is called after clk_hw_register. So the first call to > > get_parent will not have the correct value (i.e. 0) and because this is > > cached, it may never be updated. > > > > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> > > --- > > Fixes tag? Yep, Fixes: df70aeef6083 ("clk: at91: add generated clock driver") Can you add it or do you want a new version? -- Alexandre Belloni, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 1/2] clk: at91: fix clk-generated parenting 2017-05-30 9:50 ` Alexandre Belloni @ 2017-06-01 7:47 ` Stephen Boyd 0 siblings, 0 replies; 7+ messages in thread From: Stephen Boyd @ 2017-06-01 7:47 UTC (permalink / raw) To: Alexandre Belloni; +Cc: Boris Brezillon, Nicolas Ferre, linux-clk, linux-kernel On 05/30, Alexandre Belloni wrote: > On 18/05/2017 at 18:33:02 -0700, Stephen Boyd wrote: > > On 05/12, Alexandre Belloni wrote: > > > clk_generated_startup is called after clk_hw_register. So the first call to > > > get_parent will not have the correct value (i.e. 0) and because this is > > > cached, it may never be updated. > > > > > > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> > > > --- > > > > Fixes tag? > > Yep, > > Fixes: df70aeef6083 ("clk: at91: add generated clock driver") > > Can you add it or do you want a new version? > I'll take care of it now and apply it to clk-next. The second patch can go in after comments are addressed. -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-06-05 14:26 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-05-12 14:25 [PATCH v4 1/2] clk: at91: fix clk-generated parenting Alexandre Belloni 2017-05-12 14:25 ` [PATCH v4 2/2] clk: at91: Add sama5d2 suspend/resume Alexandre Belloni 2017-06-01 7:46 ` Stephen Boyd 2017-06-05 14:25 ` Alexandre Belloni 2017-05-19 1:33 ` [PATCH v4 1/2] clk: at91: fix clk-generated parenting Stephen Boyd 2017-05-30 9:50 ` Alexandre Belloni 2017-06-01 7:47 ` Stephen Boyd
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.