Lines Matching +full:suspend +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * arch/arm/mach-at91/pm.c
16 #include <linux/suspend.h>
26 #include <asm/suspend.h>
34 * struct at91_pm_bu - AT91 power management backup unit data structure
35 * @suspended: true if suspended to backup mode
37 * @canary: canary data for memory checking after exit from backup mode
64 * struct at91_soc_pm - AT91 SoC power management data structure
68 * @data: PM data to be used on last phase of suspend
70 * @bu: backup unit mapped data (for backup mode)
74 int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity);
75 int (*config_pmc_ws)(void __iomem *pmc, u32 mode, u32 polarity);
105 { AT91_PM_ULP0_FAST, "ulp0-fast" },
108 { -1, NULL },
148 { .compatible = "atmel,sama5d2-gem", .data = &ws_info[0] },
149 { .compatible = "atmel,at91rm9200-rtc", .data = &ws_info[1] },
150 { .compatible = "atmel,sama5d3-udc", .data = &ws_info[2] },
151 { .compatible = "atmel,at91rm9200-ohci", .data = &ws_info[2] },
152 { .compatible = "usb-ohci", .data = &ws_info[2] },
153 { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] },
154 { .compatible = "usb-ehci", .data = &ws_info[2] },
155 { .compatible = "atmel,sama5d2-sdhci", .data = &ws_info[3] },
160 { .compatible = "atmel,at91sam9x5-rtc", .data = &ws_info[1] },
161 { .compatible = "atmel,at91rm9200-ohci", .data = &ws_info[2] },
162 { .compatible = "usb-ohci", .data = &ws_info[2] },
163 { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] },
164 { .compatible = "usb-ehci", .data = &ws_info[2] },
165 { .compatible = "atmel,at91sam9260-rtt", .data = &ws_info[4] },
166 { .compatible = "cdns,sam9x60-macb", .data = &ws_info[5] },
171 { .compatible = "atmel,at91sam9x5-rtc", .data = &ws_info[1] },
172 { .compatible = "microchip,sama7g5-ohci", .data = &ws_info[2] },
173 { .compatible = "usb-ohci", .data = &ws_info[2] },
174 { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] },
175 { .compatible = "usb-ehci", .data = &ws_info[2] },
176 { .compatible = "microchip,sama7g5-sdhci", .data = &ws_info[3] },
177 { .compatible = "atmel,at91sam9260-rtt", .data = &ws_info[4] },
187 unsigned int mode = 0, polarity = 0, val = 0; in at91_pm_config_ws() local
193 return -EPERM; in at91_pm_config_ws()
196 writel(mode, soc_pm.data.pmc + AT91_PMC_FSMR); in at91_pm_config_ws()
201 soc_pm.config_shdwc_ws(soc_pm.data.shdwc, &mode, &polarity); in at91_pm_config_ws()
212 if (device_may_wakeup(&pdev->dev)) { in at91_pm_config_ws()
213 wsi = match->data; in at91_pm_config_ws()
216 if (wsi->shdwc_mr_bit && !(val & wsi->shdwc_mr_bit)) in at91_pm_config_ws()
219 mode |= wsi->pmc_fsmr_bit; in at91_pm_config_ws()
220 if (wsi->set_polarity) in at91_pm_config_ws()
221 polarity |= wsi->pmc_fsmr_bit; in at91_pm_config_ws()
225 put_device(&pdev->dev); in at91_pm_config_ws()
228 if (mode) { in at91_pm_config_ws()
230 soc_pm.config_pmc_ws(soc_pm.data.pmc, mode, polarity); in at91_pm_config_ws()
235 return mode ? 0 : -EPERM; in at91_pm_config_ws()
238 static int at91_sama5d2_config_shdwc_ws(void __iomem *shdwc, u32 *mode, in at91_sama5d2_config_shdwc_ws() argument
245 *mode |= (val & 0x3ff); in at91_sama5d2_config_shdwc_ws()
251 static int at91_sama5d2_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity) in at91_sama5d2_config_pmc_ws() argument
253 writel(mode, pmc + AT91_PMC_FSMR); in at91_sama5d2_config_pmc_ws()
259 static int at91_sam9x60_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity) in at91_sam9x60_config_pmc_ws() argument
261 writel(mode, pmc + AT91_PMC_FSMR); in at91_sam9x60_config_pmc_ws()
275 soc_pm.data.mode = soc_pm.data.suspend_mode; in at91_pm_begin()
279 soc_pm.data.mode = soc_pm.data.standby_mode; in at91_pm_begin()
283 soc_pm.data.mode = -1; in at91_pm_begin()
286 ret = at91_pm_config_ws(soc_pm.data.mode, true); in at91_pm_begin()
290 if (soc_pm.data.mode == AT91_PM_BACKUP) in at91_pm_begin()
291 soc_pm.bu->suspended = 1; in at91_pm_begin()
293 soc_pm.bu->suspended = 0; in at91_pm_begin()
300 * slow-clock mode.
311 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); in at91_pm_verify_clocks()
323 pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); in at91_pm_verify_clocks()
332 * Call this from platform driver suspend() to see how deeply to suspend.
335 * going into slow clock mode.
339 * to add one generic API rather than lots of platform-specific ones.
343 return (soc_pm.data.mode >= AT91_PM_ULP0); in at91_suspend_entering_slow_clock()
355 if (soc_pm.data.mode == AT91_PM_BACKUP && soc_pm.data.ramc_phy) { in at91_suspend_finish()
362 soc_pm.bu->ddr_phy_calibration[i] = in at91_suspend_finish()
363 *((unsigned int *)soc_pm.memcs + (i - 1)); in at91_suspend_finish()
401 if (soc_pm.data.mode == AT91_PM_BACKUP) { in at91_pm_suspend()
406 /* The SRAM is lost between suspend cycles */ in at91_pm_suspend()
418 * STANDBY mode has *all* drivers suspended; ignores irqs not marked as 'wakeup'
422 * AT91_PM_ULP0 is like STANDBY plus slow clock mode, so drivers must
423 * suspend more deeply, the master clock switches to the clk32k and turns off
435 * called as part of the generic suspend/resume path. in at91_pm_enter()
446 if (soc_pm.data.mode >= AT91_PM_ULP0 && in at91_pm_enter()
459 pr_debug("AT91: PM - bogus suspend state %d\n", state); in at91_pm_enter()
475 at91_pm_config_ws(soc_pm.data.mode, false); in at91_pm_end()
487 .name = "cpuidle-at91",
491 * The AT91RM9200 goes into self-refresh mode with this command, and will
492 * terminate self-refresh automatically on the next SDRAM access.
494 * Self-refresh mode is exited as soon as a memory access is made, but we don't
495 * know for sure when that happens. However, we need to restore the low-power
496 * mode if it was enabled before going idle. Restoring low-power mode while
497 * still in self-refresh is "not recommended", but seems to work.
517 /* Those two values allow us to delay self-refresh activation in at91_ddr_standby()
523 /* LPDDR1 --> force DDR2 mode during self-refresh */ in at91_ddr_standby()
547 /* self-refresh mode now */ in at91_ddr_standby()
596 /* self-refresh mode now */ in at91sam9_sdram_standby()
621 { .compatible = "atmel,at91rm9200-sdramc", .data = &ramc_infos[0] },
622 { .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
623 { .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
624 { .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
625 { .compatible = "microchip,sama7g5-uddrc", },
630 { .compatible = "microchip,sama7g5-ddr3phy", },
647 ret = -ENOMEM; in at91_dt_ramc()
651 ramc = of_id->data; in at91_dt_ramc()
654 standby = ramc->idle; in at91_dt_ramc()
655 soc_pm.data.memctrl = ramc->memctrl; in at91_dt_ramc()
663 ret = -ENODEV; in at91_dt_ramc()
672 ret = -ENOMEM; in at91_dt_ramc()
679 ret = -ENODEV; in at91_dt_ramc()
694 iounmap(soc_pm.data.ramc[--idx]); in at91_dt_ramc()
703 * re-enabled by an interrupt or by a reset. in at91rm9200_idle()
722 for_each_compatible_node(node, NULL, "mmio-sram") { in at91_pm_sram_init()
735 sram_pool = gen_pool_get(&pdev->dev, NULL); in at91_pm_sram_init()
755 /* Copy the pm suspend handler to SRAM */ in at91_pm_sram_init()
761 put_device(&pdev->dev); in at91_pm_sram_init()
804 int ret = -ENODEV, located = 0; in at91_pm_backup_init()
808 return -EPERM; in at91_pm_backup_init()
813 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam"); in at91_pm_backup_init()
824 sram_pool = gen_pool_get(&pdev->dev, NULL); in at91_pm_backup_init()
833 ret = -ENOMEM; in at91_pm_backup_init()
837 soc_pm.bu->suspended = 0; in at91_pm_backup_init()
838 soc_pm.bu->canary = __pa_symbol(&canary); in at91_pm_backup_init()
839 soc_pm.bu->resume = __pa_symbol(cpu_resume); in at91_pm_backup_init()
846 soc_pm.bu->ddr_phy_calibration[0] = readl(soc_pm.data.ramc_phy + in at91_pm_backup_init()
853 put_device(&pdev->dev); in at91_pm_backup_init()
858 { .compatible = "atmel,sama5d2-shdwc" },
859 { .compatible = "microchip,sam9x60-shdwc" },
860 { .compatible = "microchip,sama7g5-shdwc" },
867 int ret, mode; in at91_pm_modes_init() local
885 mode = AT91_PM_ULP0; in at91_pm_modes_init()
887 mode = AT91_PM_STANDBY; in at91_pm_modes_init()
890 soc_pm.data.standby_mode = mode; in at91_pm_modes_init()
892 soc_pm.data.suspend_mode = mode; in at91_pm_modes_init()
901 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu"); in at91_pm_modes_init()
911 mode = AT91_PM_ULP0; in at91_pm_modes_init()
913 mode = AT91_PM_STANDBY; in at91_pm_modes_init()
916 soc_pm.data.standby_mode = mode; in at91_pm_modes_init()
918 soc_pm.data.suspend_mode = mode; in at91_pm_modes_init()
983 { .compatible = "atmel,at91rm9200-pmc", .data = &pmc_infos[0] },
984 { .compatible = "atmel,at91sam9260-pmc", .data = &pmc_infos[1] },
985 { .compatible = "atmel,at91sam9261-pmc", .data = &pmc_infos[1] },
986 { .compatible = "atmel,at91sam9263-pmc", .data = &pmc_infos[1] },
987 { .compatible = "atmel,at91sam9g45-pmc", .data = &pmc_infos[2] },
988 { .compatible = "atmel,at91sam9n12-pmc", .data = &pmc_infos[1] },
989 { .compatible = "atmel,at91sam9rl-pmc", .data = &pmc_infos[3] },
990 { .compatible = "atmel,at91sam9x5-pmc", .data = &pmc_infos[1] },
991 { .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
992 { .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
993 { .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
994 { .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] },
995 { .compatible = "microchip,sama7g5-pmc", .data = &pmc_infos[5] },
1001 u8 i, standby = 0, suspend = 0; in at91_pm_modes_validate() local
1002 int mode; in at91_pm_modes_validate() local
1005 if (standby && suspend) in at91_pm_modes_validate()
1013 if (modes[i] == soc_pm.data.suspend_mode && !suspend) { in at91_pm_modes_validate()
1014 suspend = 1; in at91_pm_modes_validate()
1021 mode = AT91_PM_ULP0; in at91_pm_modes_validate()
1023 mode = AT91_PM_STANDBY; in at91_pm_modes_validate()
1025 pr_warn("AT91: PM: %s mode not supported! Using %s.\n", in at91_pm_modes_validate()
1027 pm_modes[mode].pattern); in at91_pm_modes_validate()
1028 soc_pm.data.standby_mode = mode; in at91_pm_modes_validate()
1031 if (!suspend) { in at91_pm_modes_validate()
1033 mode = AT91_PM_STANDBY; in at91_pm_modes_validate()
1035 mode = AT91_PM_ULP0; in at91_pm_modes_validate()
1037 pr_warn("AT91: PM: %s mode not supported! Using %s.\n", in at91_pm_modes_validate()
1039 pm_modes[mode].pattern); in at91_pm_modes_validate()
1040 soc_pm.data.suspend_mode = mode; in at91_pm_modes_validate()
1061 pmc = of_id->data; in at91_pm_init()
1062 soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask; in at91_pm_init()
1063 soc_pm.data.pmc_mckr_offset = pmc->mckr; in at91_pm_init()
1064 soc_pm.data.pmc_version = pmc->version; in at91_pm_init()
1073 pr_info("AT91: PM: standby: %s, suspend: %s\n", in at91_pm_init()
1089 * Force STANDBY and ULP0 mode to avoid calling in at91rm9200_pm_init()
1101 * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. in at91rm9200_pm_init()
1141 * Force STANDBY and ULP0 mode to avoid calling in at91sam9_pm_init()
1246 int standby, suspend; in at91_pm_modes_select() local
1256 suspend = match_token(str, pm_modes, args); in at91_pm_modes_select()
1257 if (suspend < 0) in at91_pm_modes_select()
1261 soc_pm.data.suspend_mode = suspend; in at91_pm_modes_select()