History

Merge tag 'at91-5.2-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux into arm/late

AT91 SoC for 5.2 - PM changes for SAM9X60 * tag 'at91-5.2-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux: ARM: at91: pm: do not disable/enable PLLA for ULP modes ARM: at91: pm: disable RC oscillator in ULP0 ARM: at91: pm: add ULP1 support for SAM9X60 ARM: at91: pm: add support for per SoC wakeup source configuration ARM: at91: pm: keep at91_pm_backup_init() only for SAMA5D2 SoCs ARM: at91: pm: initial PM support for SAM9X60 dt-bindings: arm: atmel: add binding for SAM9X60 SoC ARM: at91: pm: introduce at91_soc_pm structure

Olof Johansson committed 7 years ago

Commit faff3fc2 parents e40b069 2725d706 files · +232 −94Browse files

Unified · Split

6 files
  1. Documentation/devicetree/bindings/arm/atmel-at91.txt +1 −0
  2. arch/arm/mach-at91/at91sam9.c +18 −0
  3. arch/arm/mach-at91/generic.h +2 −0
  4. arch/arm/mach-at91/pm.c +133 −60
  5. arch/arm/mach-at91/pm_suspend.S +77 −34
  6. include/linux/clk/at91_pmc.h +1 −0
Documentation/devicetree/bindings/arm/atmel-at91.txt+1−0
@@ -25,6 +25,7 @@ compatible: must be one of: · 24 unmodified lines
25 o "atmel,at91sam9n12"25 o "atmel,at91sam9n12"
26 o "atmel,at91sam9rl"26 o "atmel,at91sam9rl"
27 o "atmel,at91sam9xe"27 o "atmel,at91sam9xe"
28 o "microchip,sam9x60"
28 * "atmel,sama5" for SoCs using a Cortex-A5, shall be extended with the specific29 * "atmel,sama5" for SoCs using a Cortex-A5, shall be extended with the specific
29 SoC family:30 SoC family:
30 o "atmel,sama5d2" shall be extended with the specific SoC compatible:31 o "atmel,sama5d2" shall be extended with the specific SoC compatible:
arch/arm/mach-at91/at91sam9.c+18−0
@@ -32,3 +32,21 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9") · 31 unmodified lines
32 .init_machine = at91sam9_init,32 .init_machine = at91sam9_init,
33 .dt_compat = at91_dt_board_compat,33 .dt_compat = at91_dt_board_compat,
34MACHINE_END34MACHINE_END
35
36static void __init sam9x60_init(void)
37{
38 of_platform_default_populate(NULL, NULL, NULL);
39
40 sam9x60_pm_init();
41}
42
43static const char *const sam9x60_dt_board_compat[] __initconst = {
44 "microchip,sam9x60",
45 NULL
46};
47
48DT_MACHINE_START(sam9x60_dt, "Microchip SAM9X60")
49 /* Maintainer: Microchip */
50 .init_machine = sam9x60_init,
51 .dt_compat = sam9x60_dt_board_compat,
52MACHINE_END
arch/arm/mach-at91/generic.h+2−0
@@ -14,11 +14,13 @@ · 13 unmodified lines
14#ifdef CONFIG_PM14#ifdef CONFIG_PM
15extern void __init at91rm9200_pm_init(void);15extern void __init at91rm9200_pm_init(void);
16extern void __init at91sam9_pm_init(void);16extern void __init at91sam9_pm_init(void);
17extern void __init sam9x60_pm_init(void);
17extern void __init sama5_pm_init(void);18extern void __init sama5_pm_init(void);
18extern void __init sama5d2_pm_init(void);19extern void __init sama5d2_pm_init(void);
19#else20#else
20static inline void __init at91rm9200_pm_init(void) { }21static inline void __init at91rm9200_pm_init(void) { }
21static inline void __init at91sam9_pm_init(void) { }22static inline void __init at91sam9_pm_init(void) { }
23static inline void __init sam9x60_pm_init(void) { }
22static inline void __init sama5_pm_init(void) { }24static inline void __init sama5_pm_init(void) { }
23static inline void __init sama5d2_pm_init(void) { }25static inline void __init sama5d2_pm_init(void) { }
24#endif26#endif
arch/arm/mach-at91/pm.c+133−60
@@ -39,6 +39,20 @@ extern void at91_pinctrl_gpio_suspend(void); · 38 unmodified lines
39extern void at91_pinctrl_gpio_resume(void);39extern void at91_pinctrl_gpio_resume(void);
40#endif40#endif
41 41
42struct at91_soc_pm {
43 int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity);
44 int (*config_pmc_ws)(void __iomem *pmc, u32 mode, u32 polarity);
45 const struct of_device_id *ws_ids;
46 struct at91_pm_data data;
47};
48
49static struct at91_soc_pm soc_pm = {
50 .data = {
51 .standby_mode = AT91_PM_STANDBY,
52 .suspend_mode = AT91_PM_ULP0,
53 },
54};
55
42static const match_table_t pm_modes __initconst = {56static const match_table_t pm_modes __initconst = {
43 { AT91_PM_STANDBY, "standby" },57 { AT91_PM_STANDBY, "standby" },
44 { AT91_PM_ULP0, "ulp0" },58 { AT91_PM_ULP0, "ulp0" },
@@ -47,16 +61,11 @@ static const match_table_t pm_modes __initconst = { · 2 unmodified lines
47 { -1, NULL },61 { -1, NULL },
48};62};
49 63
50static struct at91_pm_data pm_data = {
51 .standby_mode = AT91_PM_STANDBY,
52 .suspend_mode = AT91_PM_ULP0,
53};
54
55#define at91_ramc_read(id, field) \64#define at91_ramc_read(id, field) \
56 __raw_readl(pm_data.ramc[id] + field)65 __raw_readl(soc_pm.data.ramc[id] + field)
57 66
58#define at91_ramc_write(id, field, value) \67#define at91_ramc_write(id, field, value) \
59 __raw_writel(value, pm_data.ramc[id] + field)68 __raw_writel(value, soc_pm.data.ramc[id] + field)
60 69
61static int at91_pm_valid_state(suspend_state_t state)70static int at91_pm_valid_state(suspend_state_t state)
62{71{
@@ -91,6 +100,8 @@ static const struct wakeup_source_info ws_info[] = { · 28 unmodified lines
91 { .pmc_fsmr_bit = AT91_PMC_RTCAL, .shdwc_mr_bit = BIT(17) },100 { .pmc_fsmr_bit = AT91_PMC_RTCAL, .shdwc_mr_bit = BIT(17) },
92 { .pmc_fsmr_bit = AT91_PMC_USBAL },101 { .pmc_fsmr_bit = AT91_PMC_USBAL },
93 { .pmc_fsmr_bit = AT91_PMC_SDMMC_CD },102 { .pmc_fsmr_bit = AT91_PMC_SDMMC_CD },
103 { .pmc_fsmr_bit = AT91_PMC_RTTAL },
104 { .pmc_fsmr_bit = AT91_PMC_RXLP_MCE },
94};105};
95 106
96static const struct of_device_id sama5d2_ws_ids[] = {107static const struct of_device_id sama5d2_ws_ids[] = {
@@ -105,6 +116,17 @@ static const struct of_device_id sama5d2_ws_ids[] = { · 8 unmodified lines
105 { /* sentinel */ }116 { /* sentinel */ }
106};117};
107 118
119static const struct of_device_id sam9x60_ws_ids[] = {
120 { .compatible = "atmel,at91sam9x5-rtc", .data = &ws_info[1] },
121 { .compatible = "atmel,at91rm9200-ohci", .data = &ws_info[2] },
122 { .compatible = "usb-ohci", .data = &ws_info[2] },
123 { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] },
124 { .compatible = "usb-ehci", .data = &ws_info[2] },
125 { .compatible = "atmel,at91sam9260-rtt", .data = &ws_info[4] },
126 { .compatible = "cdns,sam9x60-macb", .data = &ws_info[5] },
127 { /* sentinel */ }
128};
129
108static int at91_pm_config_ws(unsigned int pm_mode, bool set)130static int at91_pm_config_ws(unsigned int pm_mode, bool set)
109{131{
110 const struct wakeup_source_info *wsi;132 const struct wakeup_source_info *wsi;
@@ -116,24 +138,22 @@ static int at91_pm_config_ws(unsigned int pm_mode, bool set) · 5 unmodified lines
116 if (pm_mode != AT91_PM_ULP1)138 if (pm_mode != AT91_PM_ULP1)
117 return 0;139 return 0;
118 140
119 if (!pm_data.pmc || !pm_data.shdwc)141 if (!soc_pm.data.pmc || !soc_pm.data.shdwc || !soc_pm.ws_ids)
120 return -EPERM;142 return -EPERM;
121 143
122 if (!set) {144 if (!set) {
123 writel(mode, pm_data.pmc + AT91_PMC_FSMR);145 writel(mode, soc_pm.data.pmc + AT91_PMC_FSMR);
124 return 0;146 return 0;
125 }147 }
126 148
127 /* SHDWC.WUIR */149 if (soc_pm.config_shdwc_ws)
128 val = readl(pm_data.shdwc + 0x0c);150 soc_pm.config_shdwc_ws(soc_pm.data.shdwc, &mode, &polarity);
129 mode |= (val & 0x3ff);
130 polarity |= ((val >> 16) & 0x3ff);
131 151
132 /* SHDWC.MR */152 /* SHDWC.MR */
133 val = readl(pm_data.shdwc + 0x04);153 val = readl(soc_pm.data.shdwc + 0x04);
134 154
135 /* Loop through defined wakeup sources. */155 /* Loop through defined wakeup sources. */
136 for_each_matching_node_and_match(np, sama5d2_ws_ids, &match) {156 for_each_matching_node_and_match(np, soc_pm.ws_ids, &match) {
137 pdev = of_find_device_by_node(np);157 pdev = of_find_device_by_node(np);
138 if (!pdev)158 if (!pdev)
139 continue;159 continue;
@@ -155,8 +175,8 @@ put_device: · 15 unmodified lines
155 }175 }
156 176
157 if (mode) {177 if (mode) {
158 writel(mode, pm_data.pmc + AT91_PMC_FSMR);178 if (soc_pm.config_pmc_ws)
159 writel(polarity, pm_data.pmc + AT91_PMC_FSPR);179 soc_pm.config_pmc_ws(soc_pm.data.pmc, mode, polarity);
160 } else {180 } else {
161 pr_err("AT91: PM: no ULP1 wakeup sources found!");181 pr_err("AT91: PM: no ULP1 wakeup sources found!");
162 }182 }
@@ -164,6 +184,34 @@ put_device: · 1 unmodified line
164 return mode ? 0 : -EPERM;184 return mode ? 0 : -EPERM;
165}185}
166 186
187static int at91_sama5d2_config_shdwc_ws(void __iomem *shdwc, u32 *mode,
188 u32 *polarity)
189{
190 u32 val;
191
192 /* SHDWC.WUIR */
193 val = readl(shdwc + 0x0c);
194 *mode |= (val & 0x3ff);
195 *polarity |= ((val >> 16) & 0x3ff);
196
197 return 0;
198}
199
200static int at91_sama5d2_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
201{
202 writel(mode, pmc + AT91_PMC_FSMR);
203 writel(polarity, pmc + AT91_PMC_FSPR);
204
205 return 0;
206}
207
208static int at91_sam9x60_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
209{
210 writel(mode, pmc + AT91_PMC_FSMR);
211
212 return 0;
213}
214
167/*215/*
168 * Called after processes are frozen, but before we shutdown devices.216 * Called after processes are frozen, but before we shutdown devices.
169 */217 */
@@ -171,18 +219,18 @@ static int at91_pm_begin(suspend_state_t state) · 1 unmodified line
171{219{
172 switch (state) {220 switch (state) {
173 case PM_SUSPEND_MEM:221 case PM_SUSPEND_MEM:
174 pm_data.mode = pm_data.suspend_mode;222 soc_pm.data.mode = soc_pm.data.suspend_mode;
175 break;223 break;
176 224
177 case PM_SUSPEND_STANDBY:225 case PM_SUSPEND_STANDBY:
178 pm_data.mode = pm_data.standby_mode;226 soc_pm.data.mode = soc_pm.data.standby_mode;
179 break;227 break;
180 228
181 default:229 default:
182 pm_data.mode = -1;230 soc_pm.data.mode = -1;
183 }231 }
184 232
185 return at91_pm_config_ws(pm_data.mode, true);233 return at91_pm_config_ws(soc_pm.data.mode, true);
186}234}
187 235
188/*236/*
@@ -194,10 +242,10 @@ static int at91_pm_verify_clocks(void) · 5 unmodified lines
194 unsigned long scsr;242 unsigned long scsr;
195 int i;243 int i;
196 244
197 scsr = readl(pm_data.pmc + AT91_PMC_SCSR);245 scsr = readl(soc_pm.data.pmc + AT91_PMC_SCSR);
198 246
199 /* USB must not be using PLLB */247 /* USB must not be using PLLB */
200 if ((scsr & pm_data.uhp_udp_mask) != 0) {248 if ((scsr & soc_pm.data.uhp_udp_mask) != 0) {
201 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");249 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
202 return 0;250 return 0;
203 }251 }
@@ -208,7 +256,7 @@ static int at91_pm_verify_clocks(void) · 4 unmodified lines
208 256
209 if ((scsr & (AT91_PMC_PCK0 << i)) == 0)257 if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
210 continue;258 continue;
211 css = readl(pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;259 css = readl(soc_pm.data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
212 if (css != AT91_PMC_CSS_SLOW) {260 if (css != AT91_PMC_CSS_SLOW) {
213 pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);261 pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
214 return 0;262 return 0;
@@ -230,7 +278,7 @@ static int at91_pm_verify_clocks(void) · 15 unmodified lines
230 */278 */
231int at91_suspend_entering_slow_clock(void)279int at91_suspend_entering_slow_clock(void)
232{280{
233 return (pm_data.mode >= AT91_PM_ULP0);281 return (soc_pm.data.mode >= AT91_PM_ULP0);
234}282}
235EXPORT_SYMBOL(at91_suspend_entering_slow_clock);283EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
236 284
@@ -243,14 +291,14 @@ static int at91_suspend_finish(unsigned long val) · 6 unmodified lines
243 flush_cache_all();291 flush_cache_all();
244 outer_disable();292 outer_disable();
245 293
246 at91_suspend_sram_fn(&pm_data);294 at91_suspend_sram_fn(&soc_pm.data);
247 295
248 return 0;296 return 0;
249}297}
250 298
251static void at91_pm_suspend(suspend_state_t state)299static void at91_pm_suspend(suspend_state_t state)
252{300{
253 if (pm_data.mode == AT91_PM_BACKUP) {301 if (soc_pm.data.mode == AT91_PM_BACKUP) {
254 pm_bu->suspended = 1;302 pm_bu->suspended = 1;
255 303
256 cpu_suspend(0, at91_suspend_finish);304 cpu_suspend(0, at91_suspend_finish);
@@ -289,7 +337,7 @@ static int at91_pm_enter(suspend_state_t state) · 32 unmodified lines
289 /*337 /*
290 * Ensure that clocks are in a valid state.338 * Ensure that clocks are in a valid state.
291 */339 */
292 if (pm_data.mode >= AT91_PM_ULP0 &&340 if (soc_pm.data.mode >= AT91_PM_ULP0 &&
293 !at91_pm_verify_clocks())341 !at91_pm_verify_clocks())
294 goto error;342 goto error;
295 343
@@ -318,7 +366,7 @@ error: · 22 unmodified lines
318 */366 */
319static void at91_pm_end(void)367static void at91_pm_end(void)
320{368{
321 at91_pm_config_ws(pm_data.mode, false);369 at91_pm_config_ws(soc_pm.data.mode, false);
322}370}
323 371
324 372
@@ -351,7 +399,7 @@ static void at91rm9200_standby(void) · 26 unmodified lines
351 " str %2, [%1, %3]\n\t"399 " str %2, [%1, %3]\n\t"
352 " mcr p15, 0, %0, c7, c0, 4\n\t"400 " mcr p15, 0, %0, c7, c0, 4\n\t"
353 :401 :
354 : "r" (0), "r" (pm_data.ramc[0]),402 : "r" (0), "r" (soc_pm.data.ramc[0]),
355 "r" (1), "r" (AT91_MC_SDRAMC_SRR));403 "r" (1), "r" (AT91_MC_SDRAMC_SRR));
356}404}
357 405
@@ -374,7 +422,7 @@ static void at91_ddr_standby(void) · 16 unmodified lines
374 at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr);422 at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr);
375 }423 }
376 424
377 if (pm_data.ramc[1]) {425 if (soc_pm.data.ramc[1]) {
378 saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);426 saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
379 lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;427 lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
380 lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;428 lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
@@ -392,14 +440,14 @@ static void at91_ddr_standby(void) · 11 unmodified lines
392 440
393 /* self-refresh mode now */441 /* self-refresh mode now */
394 at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);442 at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
395 if (pm_data.ramc[1])443 if (soc_pm.data.ramc[1])
396 at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);444 at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
397 445
398 cpu_do_idle();446 cpu_do_idle();
399 447
400 at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0);448 at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0);
401 at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);449 at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
402 if (pm_data.ramc[1]) {450 if (soc_pm.data.ramc[1]) {
403 at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1);451 at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1);
404 at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);452 at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
405 }453 }
@@ -429,7 +477,7 @@ static void at91sam9_sdram_standby(void) · 23 unmodified lines
429 u32 lpr0, lpr1 = 0;477 u32 lpr0, lpr1 = 0;
430 u32 saved_lpr0, saved_lpr1 = 0;478 u32 saved_lpr0, saved_lpr1 = 0;
431 479
432 if (pm_data.ramc[1]) {480 if (soc_pm.data.ramc[1]) {
433 saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);481 saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
434 lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;482 lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
435 lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;483 lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
@@ -441,13 +489,13 @@ static void at91sam9_sdram_standby(void) · 5 unmodified lines
441 489
442 /* self-refresh mode now */490 /* self-refresh mode now */
443 at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);491 at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
444 if (pm_data.ramc[1])492 if (soc_pm.data.ramc[1])
445 at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);493 at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
446 494
447 cpu_do_idle();495 cpu_do_idle();
448 496
449 at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);497 at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
450 if (pm_data.ramc[1])498 if (soc_pm.data.ramc[1])
451 at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);499 at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
452}500}
453 501
@@ -480,14 +528,14 @@ static __init void at91_dt_ramc(void) · 26 unmodified lines
480 const struct ramc_info *ramc;528 const struct ramc_info *ramc;
481 529
482 for_each_matching_node_and_match(np, ramc_ids, &of_id) {530 for_each_matching_node_and_match(np, ramc_ids, &of_id) {
483 pm_data.ramc[idx] = of_iomap(np, 0);531 soc_pm.data.ramc[idx] = of_iomap(np, 0);
484 if (!pm_data.ramc[idx])532 if (!soc_pm.data.ramc[idx])
485 panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);533 panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
486 534
487 ramc = of_id->data;535 ramc = of_id->data;
488 if (!standby)536 if (!standby)
489 standby = ramc->idle;537 standby = ramc->idle;
490 pm_data.memctrl = ramc->memctrl;538 soc_pm.data.memctrl = ramc->memctrl;
491 539
492 idx++;540 idx++;
493 }541 }
@@ -509,12 +557,17 @@ static void at91rm9200_idle(void) · 15 unmodified lines
509 * Disable the processor clock. The processor will be automatically557 * Disable the processor clock. The processor will be automatically
510 * re-enabled by an interrupt or by a reset.558 * re-enabled by an interrupt or by a reset.
511 */559 */
512 writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);560 writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR);
561}
562
563static void at91sam9x60_idle(void)
564{
565 cpu_do_idle();
513}566}
514 567
515static void at91sam9_idle(void)568static void at91sam9_idle(void)
516{569{
517 writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);570 writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR);
518 cpu_do_idle();571 cpu_do_idle();
519}572}
520 573
@@ -566,8 +619,8 @@ static void __init at91_pm_sram_init(void) · 45 unmodified lines
566 619
567static bool __init at91_is_pm_mode_active(int pm_mode)620static bool __init at91_is_pm_mode_active(int pm_mode)
568{621{
569 return (pm_data.standby_mode == pm_mode ||622 return (soc_pm.data.standby_mode == pm_mode ||
570 pm_data.suspend_mode == pm_mode);623 soc_pm.data.suspend_mode == pm_mode);
571}624}
572 625
573static int __init at91_pm_backup_init(void)626static int __init at91_pm_backup_init(void)
@@ -577,6 +630,9 @@ static int __init at91_pm_backup_init(void) · 3 unmodified lines
577 struct platform_device *pdev = NULL;630 struct platform_device *pdev = NULL;
578 int ret = -ENODEV;631 int ret = -ENODEV;
579 632
633 if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
634 return -EPERM;
635
580 if (!at91_is_pm_mode_active(AT91_PM_BACKUP))636 if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
581 return 0;637 return 0;
582 638
@@ -586,7 +642,7 @@ static int __init at91_pm_backup_init(void) · 3 unmodified lines
586 return ret;642 return ret;
587 }643 }
588 644
589 pm_data.sfrbu = of_iomap(np, 0);645 soc_pm.data.sfrbu = of_iomap(np, 0);
590 of_node_put(np);646 of_node_put(np);
591 647
592 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam");648 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam");
@@ -622,8 +678,8 @@ static int __init at91_pm_backup_init(void) · 29 unmodified lines
622securam_fail:678securam_fail:
623 put_device(&pdev->dev);679 put_device(&pdev->dev);
624securam_fail_no_ref_dev:680securam_fail_no_ref_dev:
625 iounmap(pm_data.sfrbu);681 iounmap(soc_pm.data.sfrbu);
626 pm_data.sfrbu = NULL;682 soc_pm.data.sfrbu = NULL;
627 return ret;683 return ret;
628}684}
629 685
@@ -632,10 +688,10 @@ static void __init at91_pm_use_default_mode(int pm_mode) · 2 unmodified lines
632 if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP)688 if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP)
633 return;689 return;
634 690
635 if (pm_data.standby_mode == pm_mode)691 if (soc_pm.data.standby_mode == pm_mode)
636 pm_data.standby_mode = AT91_PM_ULP0;692 soc_pm.data.standby_mode = AT91_PM_ULP0;
637 if (pm_data.suspend_mode == pm_mode)693 if (soc_pm.data.suspend_mode == pm_mode)
638 pm_data.suspend_mode = AT91_PM_ULP0;694 soc_pm.data.suspend_mode = AT91_PM_ULP0;
639}695}
640 696
641static void __init at91_pm_modes_init(void)697static void __init at91_pm_modes_init(void)
@@ -653,7 +709,7 @@ static void __init at91_pm_modes_init(void) · 11 unmodified lines
653 goto ulp1_default;709 goto ulp1_default;
654 }710 }
655 711
656 pm_data.shdwc = of_iomap(np, 0);712 soc_pm.data.shdwc = of_iomap(np, 0);
657 of_node_put(np);713 of_node_put(np);
658 714
659 ret = at91_pm_backup_init();715 ret = at91_pm_backup_init();
@@ -667,8 +723,8 @@ static void __init at91_pm_modes_init(void) · 7 unmodified lines
667 return;723 return;
668 724
669unmap:725unmap:
670 iounmap(pm_data.shdwc);726 iounmap(soc_pm.data.shdwc);
671 pm_data.shdwc = NULL;727 soc_pm.data.shdwc = NULL;
672ulp1_default:728ulp1_default:
673 at91_pm_use_default_mode(AT91_PM_ULP1);729 at91_pm_use_default_mode(AT91_PM_ULP1);
674backup_default:730backup_default:
@@ -711,14 +767,14 @@ static void __init at91_pm_init(void (*pm_idle)(void)) · 36 unmodified lines
711 platform_device_register(&at91_cpuidle_device);767 platform_device_register(&at91_cpuidle_device);
712 768
713 pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id);769 pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id);
714 pm_data.pmc = of_iomap(pmc_np, 0);770 soc_pm.data.pmc = of_iomap(pmc_np, 0);
715 if (!pm_data.pmc) {771 if (!soc_pm.data.pmc) {
716 pr_err("AT91: PM not supported, PMC not found\n");772 pr_err("AT91: PM not supported, PMC not found\n");
717 return;773 return;
718 }774 }
719 775
720 pmc = of_id->data;776 pmc = of_id->data;
721 pm_data.uhp_udp_mask = pmc->uhp_udp_mask;777 soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask;
722 778
723 if (pm_idle)779 if (pm_idle)
724 arm_pm_idle = pm_idle;780 arm_pm_idle = pm_idle;
@@ -728,8 +784,8 @@ static void __init at91_pm_init(void (*pm_idle)(void)) · 3 unmodified lines
728 if (at91_suspend_sram_fn) {784 if (at91_suspend_sram_fn) {
729 suspend_set_ops(&at91_pm_ops);785 suspend_set_ops(&at91_pm_ops);
730 pr_info("AT91: PM: standby: %s, suspend: %s\n",786 pr_info("AT91: PM: standby: %s, suspend: %s\n",
731 pm_modes[pm_data.standby_mode].pattern,787 pm_modes[soc_pm.data.standby_mode].pattern,
732 pm_modes[pm_data.suspend_mode].pattern);788 pm_modes[soc_pm.data.suspend_mode].pattern);
733 } else {789 } else {
734 pr_info("AT91: PM not supported, due to no SRAM allocated\n");790 pr_info("AT91: PM not supported, due to no SRAM allocated\n");
735 }791 }
@@ -750,6 +806,19 @@ void __init at91rm9200_pm_init(void) · 14 unmodified lines
750 at91_pm_init(at91rm9200_idle);806 at91_pm_init(at91rm9200_idle);
751}807}
752 808
809void __init sam9x60_pm_init(void)
810{
811 if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
812 return;
813
814 at91_pm_modes_init();
815 at91_dt_ramc();
816 at91_pm_init(at91sam9x60_idle);
817
818 soc_pm.ws_ids = sam9x60_ws_ids;
819 soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
820}
821
753void __init at91sam9_pm_init(void)822void __init at91sam9_pm_init(void)
754{823{
755 if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))824 if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
@@ -775,6 +844,10 @@ void __init sama5d2_pm_init(void) · 19 unmodified lines
775 844
776 at91_pm_modes_init();845 at91_pm_modes_init();
777 sama5_pm_init();846 sama5_pm_init();
847
848 soc_pm.ws_ids = sama5d2_ws_ids;
849 soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws;
850 soc_pm.config_pmc_ws = at91_sama5d2_config_pmc_ws;
778}851}
779 852
780static int __init at91_pm_modes_select(char *str)853static int __init at91_pm_modes_select(char *str)
@@ -795,8 +868,8 @@ static int __init at91_pm_modes_select(char *str) · 14 unmodified lines
795 if (suspend < 0)868 if (suspend < 0)
796 return 0;869 return 0;
797 870
798 pm_data.standby_mode = standby;871 soc_pm.data.standby_mode = standby;
799 pm_data.suspend_mode = suspend;872 soc_pm.data.suspend_mode = suspend;
800 873
801 return 0;874 return 0;
802}875}
arch/arm/mach-at91/pm_suspend.S+77−34
@@ -50,15 +50,6 @@ tmp2 .req r5 · 49 unmodified lines
50 beq 1b50 beq 1b
51 .endm51 .endm
52 52
53/*
54 * Wait until PLLA has locked.
55 */
56 .macro wait_pllalock
571: ldr tmp1, [pmc, #AT91_PMC_SR]
58 tst tmp1, #AT91_PMC_LOCKA
59 beq 1b
60 .endm
61
62/*53/*
63 * Put the processor to enter the idle state54 * Put the processor to enter the idle state
64 */55 */
@@ -178,11 +169,46 @@ ENDPROC(at91_backup_mode) · 113 unmodified lines
178 orr tmp1, tmp1, #AT91_PMC_KEY169 orr tmp1, tmp1, #AT91_PMC_KEY
179 str tmp1, [pmc, #AT91_CKGR_MOR]170 str tmp1, [pmc, #AT91_CKGR_MOR]
180 171
172 /* Save RC oscillator state */
173 ldr tmp1, [pmc, #AT91_PMC_SR]
174 str tmp1, .saved_osc_status
175 tst tmp1, #AT91_PMC_MOSCRCS
176 bne 1f
177
178 /* Turn off RC oscillator */
179 ldr tmp1, [pmc, #AT91_CKGR_MOR]
180 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
181 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
182 orr tmp1, tmp1, #AT91_PMC_KEY
183 str tmp1, [pmc, #AT91_CKGR_MOR]
184
185 /* Wait main RC disabled done */
1862: ldr tmp1, [pmc, #AT91_PMC_SR]
187 tst tmp1, #AT91_PMC_MOSCRCS
188 bne 2b
189
181 /* Wait for interrupt */190 /* Wait for interrupt */
182 at91_cpu_idle1911: at91_cpu_idle
183 192
184 /* Turn on the crystal oscillator */193 /* Restore RC oscillator state */
194 ldr tmp1, .saved_osc_status
195 tst tmp1, #AT91_PMC_MOSCRCS
196 beq 4f
197
198 /* Turn on RC oscillator */
185 ldr tmp1, [pmc, #AT91_CKGR_MOR]199 ldr tmp1, [pmc, #AT91_CKGR_MOR]
200 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
201 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
202 orr tmp1, tmp1, #AT91_PMC_KEY
203 str tmp1, [pmc, #AT91_CKGR_MOR]
204
205 /* Wait main RC stabilization */
2063: ldr tmp1, [pmc, #AT91_PMC_SR]
207 tst tmp1, #AT91_PMC_MOSCRCS
208 beq 3b
209
210 /* Turn on the crystal oscillator */
2114: ldr tmp1, [pmc, #AT91_CKGR_MOR]
186 orr tmp1, tmp1, #AT91_PMC_MOSCEN212 orr tmp1, tmp1, #AT91_PMC_MOSCEN
187 orr tmp1, tmp1, #AT91_PMC_KEY213 orr tmp1, tmp1, #AT91_PMC_KEY
188 str tmp1, [pmc, #AT91_CKGR_MOR]214 str tmp1, [pmc, #AT91_CKGR_MOR]
@@ -197,8 +223,26 @@ ENDPROC(at91_backup_mode) · 8 unmodified lines
197.macro at91_pm_ulp1_mode223.macro at91_pm_ulp1_mode
198 ldr pmc, .pmc_base224 ldr pmc, .pmc_base
199 225
200 /* Switch the main clock source to 12-MHz RC oscillator */226 /* Save RC oscillator state and check if it is enabled. */
227 ldr tmp1, [pmc, #AT91_PMC_SR]
228 str tmp1, .saved_osc_status
229 tst tmp1, #AT91_PMC_MOSCRCS
230 bne 2f
231
232 /* Enable RC oscillator */
201 ldr tmp1, [pmc, #AT91_CKGR_MOR]233 ldr tmp1, [pmc, #AT91_CKGR_MOR]
234 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
235 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
236 orr tmp1, tmp1, #AT91_PMC_KEY
237 str tmp1, [pmc, #AT91_CKGR_MOR]
238
239 /* Wait main RC stabilization */
2401: ldr tmp1, [pmc, #AT91_PMC_SR]
241 tst tmp1, #AT91_PMC_MOSCRCS
242 beq 1b
243
244 /* Switch the main clock source to 12-MHz RC oscillator */
2452: ldr tmp1, [pmc, #AT91_CKGR_MOR]
202 bic tmp1, tmp1, #AT91_PMC_MOSCSEL246 bic tmp1, tmp1, #AT91_PMC_MOSCSEL
203 bic tmp1, tmp1, #AT91_PMC_KEY_MASK247 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
204 orr tmp1, tmp1, #AT91_PMC_KEY248 orr tmp1, tmp1, #AT91_PMC_KEY
@@ -262,6 +306,25 @@ ENDPROC(at91_backup_mode) · 57 unmodified lines
262 str tmp1, [pmc, #AT91_PMC_MCKR]306 str tmp1, [pmc, #AT91_PMC_MCKR]
263 307
264 wait_mckrdy308 wait_mckrdy
309
310 /* Restore RC oscillator state */
311 ldr tmp1, .saved_osc_status
312 tst tmp1, #AT91_PMC_MOSCRCS
313 bne 3f
314
315 /* Disable RC oscillator */
316 ldr tmp1, [pmc, #AT91_CKGR_MOR]
317 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
318 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
319 orr tmp1, tmp1, #AT91_PMC_KEY
320 str tmp1, [pmc, #AT91_CKGR_MOR]
321
322 /* Wait RC oscillator disable done */
3234: ldr tmp1, [pmc, #AT91_PMC_SR]
324 tst tmp1, #AT91_PMC_MOSCRCS
325 bne 4b
326
3273:
265.endm328.endm
266 329
267ENTRY(at91_ulp_mode)330ENTRY(at91_ulp_mode)
@@ -279,14 +342,6 @@ ENTRY(at91_ulp_mode) · 11 unmodified lines
279 342
280 wait_mckrdy343 wait_mckrdy
281 344
282 /* Save PLLA setting and disable it */
283 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
284 str tmp1, .saved_pllar
285
286 mov tmp1, #AT91_PMC_PLLCOUNT
287 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
288 str tmp1, [pmc, #AT91_CKGR_PLLAR]
289
290 ldr r0, .pm_mode345 ldr r0, .pm_mode
291 cmp r0, #AT91_PM_ULP1346 cmp r0, #AT91_PM_ULP1
292 beq ulp1_mode347 beq ulp1_mode
@@ -301,18 +356,6 @@ ulp1_mode: · 8 unmodified lines
301ulp_exit:356ulp_exit:
302 ldr pmc, .pmc_base357 ldr pmc, .pmc_base
303 358
304 /* Restore PLLA setting */
305 ldr tmp1, .saved_pllar
306 str tmp1, [pmc, #AT91_CKGR_PLLAR]
307
308 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
309 bne 3f
310 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
311 beq 4f
3123:
313 wait_pllalock
3144:
315
316 /*359 /*
317 * Restore master clock setting360 * Restore master clock setting
318 */361 */
@@ -465,8 +508,6 @@ ENDPROC(at91_sramc_self_refresh) · 146 unmodified lines
465 .word 0508 .word 0
466.saved_mckr:509.saved_mckr:
467 .word 0510 .word 0
468.saved_pllar:
469 .word 0
470.saved_sam9_lpr:511.saved_sam9_lpr:
471 .word 0512 .word 0
472.saved_sam9_lpr1:513.saved_sam9_lpr1:
@@ -475,6 +516,8 @@ ENDPROC(at91_sramc_self_refresh) · 2 unmodified lines
475 .word 0516 .word 0
476.saved_sam9_mdr1:517.saved_sam9_mdr1:
477 .word 0518 .word 0
519.saved_osc_status:
520 .word 0
478 521
479ENTRY(at91_pm_suspend_in_sram_sz)522ENTRY(at91_pm_suspend_in_sram_sz)
480 .word .-at91_pm_suspend_in_sram523 .word .-at91_pm_suspend_in_sram
include/linux/clk/at91_pmc.h+1−0
@@ -161,6 +161,7 @@ · 160 unmodified lines
161 161
162#define AT91_PMC_FSMR 0x70 /* Fast Startup Mode Register */162#define AT91_PMC_FSMR 0x70 /* Fast Startup Mode Register */
163#define AT91_PMC_FSTT(n) BIT(n)163#define AT91_PMC_FSTT(n) BIT(n)
164#define AT91_PMC_RTTAL BIT(16)
164#define AT91_PMC_RTCAL BIT(17) /* RTC Alarm Enable */165#define AT91_PMC_RTCAL BIT(17) /* RTC Alarm Enable */
165#define AT91_PMC_USBAL BIT(18) /* USB Resume Enable */166#define AT91_PMC_USBAL BIT(18) /* USB Resume Enable */
166#define AT91_PMC_SDMMC_CD BIT(19) /* SDMMC Card Detect Enable */167#define AT91_PMC_SDMMC_CD BIT(19) /* SDMMC Card Detect Enable */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t