linux/arch/arm/mach-at91/pm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * arch/arm/mach-at91/pm.c
   4 * AT91 Power Management
   5 *
   6 * Copyright (C) 2005 David Brownell
   7 */
   8
   9#include <linux/genalloc.h>
  10#include <linux/io.h>
  11#include <linux/of_address.h>
  12#include <linux/of.h>
  13#include <linux/of_platform.h>
  14#include <linux/parser.h>
  15#include <linux/suspend.h>
  16
  17#include <linux/clk/at91_pmc.h>
  18#include <linux/platform_data/atmel.h>
  19
  20#include <asm/cacheflush.h>
  21#include <asm/fncpy.h>
  22#include <asm/system_misc.h>
  23#include <asm/suspend.h>
  24
  25#include "generic.h"
  26#include "pm.h"
  27
  28/*
  29 * FIXME: this is needed to communicate between the pinctrl driver and
  30 * the PM implementation in the machine. Possibly part of the PM
  31 * implementation should be moved down into the pinctrl driver and get
  32 * called as part of the generic suspend/resume path.
  33 */
  34#ifdef CONFIG_PINCTRL_AT91
  35extern void at91_pinctrl_gpio_suspend(void);
  36extern void at91_pinctrl_gpio_resume(void);
  37#endif
  38
  39struct at91_soc_pm {
  40        int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity);
  41        int (*config_pmc_ws)(void __iomem *pmc, u32 mode, u32 polarity);
  42        const struct of_device_id *ws_ids;
  43        struct at91_pm_data data;
  44};
  45
  46static struct at91_soc_pm soc_pm = {
  47        .data = {
  48                .standby_mode = AT91_PM_STANDBY,
  49                .suspend_mode = AT91_PM_ULP0,
  50        },
  51};
  52
  53static const match_table_t pm_modes __initconst = {
  54        { AT91_PM_STANDBY, "standby" },
  55        { AT91_PM_ULP0, "ulp0" },
  56        { AT91_PM_ULP1, "ulp1" },
  57        { AT91_PM_BACKUP, "backup" },
  58        { -1, NULL },
  59};
  60
  61#define at91_ramc_read(id, field) \
  62        __raw_readl(soc_pm.data.ramc[id] + field)
  63
  64#define at91_ramc_write(id, field, value) \
  65        __raw_writel(value, soc_pm.data.ramc[id] + field)
  66
  67static int at91_pm_valid_state(suspend_state_t state)
  68{
  69        switch (state) {
  70                case PM_SUSPEND_ON:
  71                case PM_SUSPEND_STANDBY:
  72                case PM_SUSPEND_MEM:
  73                        return 1;
  74
  75                default:
  76                        return 0;
  77        }
  78}
  79
  80static int canary = 0xA5A5A5A5;
  81
  82static struct at91_pm_bu {
  83        int suspended;
  84        unsigned long reserved;
  85        phys_addr_t canary;
  86        phys_addr_t resume;
  87} *pm_bu;
  88
  89struct wakeup_source_info {
  90        unsigned int pmc_fsmr_bit;
  91        unsigned int shdwc_mr_bit;
  92        bool set_polarity;
  93};
  94
  95static const struct wakeup_source_info ws_info[] = {
  96        { .pmc_fsmr_bit = AT91_PMC_FSTT(10),    .set_polarity = true },
  97        { .pmc_fsmr_bit = AT91_PMC_RTCAL,       .shdwc_mr_bit = BIT(17) },
  98        { .pmc_fsmr_bit = AT91_PMC_USBAL },
  99        { .pmc_fsmr_bit = AT91_PMC_SDMMC_CD },
 100        { .pmc_fsmr_bit = AT91_PMC_RTTAL },
 101        { .pmc_fsmr_bit = AT91_PMC_RXLP_MCE },
 102};
 103
 104static const struct of_device_id sama5d2_ws_ids[] = {
 105        { .compatible = "atmel,sama5d2-gem",            .data = &ws_info[0] },
 106        { .compatible = "atmel,at91rm9200-rtc",         .data = &ws_info[1] },
 107        { .compatible = "atmel,sama5d3-udc",            .data = &ws_info[2] },
 108        { .compatible = "atmel,at91rm9200-ohci",        .data = &ws_info[2] },
 109        { .compatible = "usb-ohci",                     .data = &ws_info[2] },
 110        { .compatible = "atmel,at91sam9g45-ehci",       .data = &ws_info[2] },
 111        { .compatible = "usb-ehci",                     .data = &ws_info[2] },
 112        { .compatible = "atmel,sama5d2-sdhci",          .data = &ws_info[3] },
 113        { /* sentinel */ }
 114};
 115
 116static const struct of_device_id sam9x60_ws_ids[] = {
 117        { .compatible = "atmel,at91sam9x5-rtc",         .data = &ws_info[1] },
 118        { .compatible = "atmel,at91rm9200-ohci",        .data = &ws_info[2] },
 119        { .compatible = "usb-ohci",                     .data = &ws_info[2] },
 120        { .compatible = "atmel,at91sam9g45-ehci",       .data = &ws_info[2] },
 121        { .compatible = "usb-ehci",                     .data = &ws_info[2] },
 122        { .compatible = "atmel,at91sam9260-rtt",        .data = &ws_info[4] },
 123        { .compatible = "cdns,sam9x60-macb",            .data = &ws_info[5] },
 124        { /* sentinel */ }
 125};
 126
 127static int at91_pm_config_ws(unsigned int pm_mode, bool set)
 128{
 129        const struct wakeup_source_info *wsi;
 130        const struct of_device_id *match;
 131        struct platform_device *pdev;
 132        struct device_node *np;
 133        unsigned int mode = 0, polarity = 0, val = 0;
 134
 135        if (pm_mode != AT91_PM_ULP1)
 136                return 0;
 137
 138        if (!soc_pm.data.pmc || !soc_pm.data.shdwc || !soc_pm.ws_ids)
 139                return -EPERM;
 140
 141        if (!set) {
 142                writel(mode, soc_pm.data.pmc + AT91_PMC_FSMR);
 143                return 0;
 144        }
 145
 146        if (soc_pm.config_shdwc_ws)
 147                soc_pm.config_shdwc_ws(soc_pm.data.shdwc, &mode, &polarity);
 148
 149        /* SHDWC.MR */
 150        val = readl(soc_pm.data.shdwc + 0x04);
 151
 152        /* Loop through defined wakeup sources. */
 153        for_each_matching_node_and_match(np, soc_pm.ws_ids, &match) {
 154                pdev = of_find_device_by_node(np);
 155                if (!pdev)
 156                        continue;
 157
 158                if (device_may_wakeup(&pdev->dev)) {
 159                        wsi = match->data;
 160
 161                        /* Check if enabled on SHDWC. */
 162                        if (wsi->shdwc_mr_bit && !(val & wsi->shdwc_mr_bit))
 163                                goto put_device;
 164
 165                        mode |= wsi->pmc_fsmr_bit;
 166                        if (wsi->set_polarity)
 167                                polarity |= wsi->pmc_fsmr_bit;
 168                }
 169
 170put_device:
 171                put_device(&pdev->dev);
 172        }
 173
 174        if (mode) {
 175                if (soc_pm.config_pmc_ws)
 176                        soc_pm.config_pmc_ws(soc_pm.data.pmc, mode, polarity);
 177        } else {
 178                pr_err("AT91: PM: no ULP1 wakeup sources found!");
 179        }
 180
 181        return mode ? 0 : -EPERM;
 182}
 183
 184static int at91_sama5d2_config_shdwc_ws(void __iomem *shdwc, u32 *mode,
 185                                        u32 *polarity)
 186{
 187        u32 val;
 188
 189        /* SHDWC.WUIR */
 190        val = readl(shdwc + 0x0c);
 191        *mode |= (val & 0x3ff);
 192        *polarity |= ((val >> 16) & 0x3ff);
 193
 194        return 0;
 195}
 196
 197static int at91_sama5d2_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
 198{
 199        writel(mode, pmc + AT91_PMC_FSMR);
 200        writel(polarity, pmc + AT91_PMC_FSPR);
 201
 202        return 0;
 203}
 204
 205static int at91_sam9x60_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
 206{
 207        writel(mode, pmc + AT91_PMC_FSMR);
 208
 209        return 0;
 210}
 211
 212/*
 213 * Called after processes are frozen, but before we shutdown devices.
 214 */
 215static int at91_pm_begin(suspend_state_t state)
 216{
 217        switch (state) {
 218        case PM_SUSPEND_MEM:
 219                soc_pm.data.mode = soc_pm.data.suspend_mode;
 220                break;
 221
 222        case PM_SUSPEND_STANDBY:
 223                soc_pm.data.mode = soc_pm.data.standby_mode;
 224                break;
 225
 226        default:
 227                soc_pm.data.mode = -1;
 228        }
 229
 230        return at91_pm_config_ws(soc_pm.data.mode, true);
 231}
 232
 233/*
 234 * Verify that all the clocks are correct before entering
 235 * slow-clock mode.
 236 */
 237static int at91_pm_verify_clocks(void)
 238{
 239        unsigned long scsr;
 240        int i;
 241
 242        scsr = readl(soc_pm.data.pmc + AT91_PMC_SCSR);
 243
 244        /* USB must not be using PLLB */
 245        if ((scsr & soc_pm.data.uhp_udp_mask) != 0) {
 246                pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 247                return 0;
 248        }
 249
 250        /* PCK0..PCK3 must be disabled, or configured to use clk32k */
 251        for (i = 0; i < 4; i++) {
 252                u32 css;
 253
 254                if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
 255                        continue;
 256                css = readl(soc_pm.data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
 257                if (css != AT91_PMC_CSS_SLOW) {
 258                        pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
 259                        return 0;
 260                }
 261        }
 262
 263        return 1;
 264}
 265
 266/*
 267 * Call this from platform driver suspend() to see how deeply to suspend.
 268 * For example, some controllers (like OHCI) need one of the PLL clocks
 269 * in order to act as a wakeup source, and those are not available when
 270 * going into slow clock mode.
 271 *
 272 * REVISIT: generalize as clk_will_be_available(clk)?  Other platforms have
 273 * the very same problem (but not using at91 main_clk), and it'd be better
 274 * to add one generic API rather than lots of platform-specific ones.
 275 */
 276int at91_suspend_entering_slow_clock(void)
 277{
 278        return (soc_pm.data.mode >= AT91_PM_ULP0);
 279}
 280EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
 281
 282static void (*at91_suspend_sram_fn)(struct at91_pm_data *);
 283extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data);
 284extern u32 at91_pm_suspend_in_sram_sz;
 285
 286static int at91_suspend_finish(unsigned long val)
 287{
 288        flush_cache_all();
 289        outer_disable();
 290
 291        at91_suspend_sram_fn(&soc_pm.data);
 292
 293        return 0;
 294}
 295
 296static void at91_pm_suspend(suspend_state_t state)
 297{
 298        if (soc_pm.data.mode == AT91_PM_BACKUP) {
 299                pm_bu->suspended = 1;
 300
 301                cpu_suspend(0, at91_suspend_finish);
 302
 303                /* The SRAM is lost between suspend cycles */
 304                at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn,
 305                                             &at91_pm_suspend_in_sram,
 306                                             at91_pm_suspend_in_sram_sz);
 307        } else {
 308                at91_suspend_finish(0);
 309        }
 310
 311        outer_resume();
 312}
 313
 314/*
 315 * STANDBY mode has *all* drivers suspended; ignores irqs not marked as 'wakeup'
 316 * event sources; and reduces DRAM power.  But otherwise it's identical to
 317 * PM_SUSPEND_ON: cpu idle, and nothing fancy done with main or cpu clocks.
 318 *
 319 * AT91_PM_ULP0 is like STANDBY plus slow clock mode, so drivers must
 320 * suspend more deeply, the master clock switches to the clk32k and turns off
 321 * the main oscillator
 322 *
 323 * AT91_PM_BACKUP turns off the whole SoC after placing the DDR in self refresh
 324 */
 325static int at91_pm_enter(suspend_state_t state)
 326{
 327#ifdef CONFIG_PINCTRL_AT91
 328        at91_pinctrl_gpio_suspend();
 329#endif
 330
 331        switch (state) {
 332        case PM_SUSPEND_MEM:
 333        case PM_SUSPEND_STANDBY:
 334                /*
 335                 * Ensure that clocks are in a valid state.
 336                 */
 337                if (soc_pm.data.mode >= AT91_PM_ULP0 &&
 338                    !at91_pm_verify_clocks())
 339                        goto error;
 340
 341                at91_pm_suspend(state);
 342
 343                break;
 344
 345        case PM_SUSPEND_ON:
 346                cpu_do_idle();
 347                break;
 348
 349        default:
 350                pr_debug("AT91: PM - bogus suspend state %d\n", state);
 351                goto error;
 352        }
 353
 354error:
 355#ifdef CONFIG_PINCTRL_AT91
 356        at91_pinctrl_gpio_resume();
 357#endif
 358        return 0;
 359}
 360
 361/*
 362 * Called right prior to thawing processes.
 363 */
 364static void at91_pm_end(void)
 365{
 366        at91_pm_config_ws(soc_pm.data.mode, false);
 367}
 368
 369
 370static const struct platform_suspend_ops at91_pm_ops = {
 371        .valid  = at91_pm_valid_state,
 372        .begin  = at91_pm_begin,
 373        .enter  = at91_pm_enter,
 374        .end    = at91_pm_end,
 375};
 376
 377static struct platform_device at91_cpuidle_device = {
 378        .name = "cpuidle-at91",
 379};
 380
 381/*
 382 * The AT91RM9200 goes into self-refresh mode with this command, and will
 383 * terminate self-refresh automatically on the next SDRAM access.
 384 *
 385 * Self-refresh mode is exited as soon as a memory access is made, but we don't
 386 * know for sure when that happens. However, we need to restore the low-power
 387 * mode if it was enabled before going idle. Restoring low-power mode while
 388 * still in self-refresh is "not recommended", but seems to work.
 389 */
 390static void at91rm9200_standby(void)
 391{
 392        asm volatile(
 393                "b    1f\n\t"
 394                ".align    5\n\t"
 395                "1:  mcr    p15, 0, %0, c7, c10, 4\n\t"
 396                "    str    %2, [%1, %3]\n\t"
 397                "    mcr    p15, 0, %0, c7, c0, 4\n\t"
 398                :
 399                : "r" (0), "r" (soc_pm.data.ramc[0]),
 400                  "r" (1), "r" (AT91_MC_SDRAMC_SRR));
 401}
 402
 403/* We manage both DDRAM/SDRAM controllers, we need more than one value to
 404 * remember.
 405 */
 406static void at91_ddr_standby(void)
 407{
 408        /* Those two values allow us to delay self-refresh activation
 409         * to the maximum. */
 410        u32 lpr0, lpr1 = 0;
 411        u32 mdr, saved_mdr0, saved_mdr1 = 0;
 412        u32 saved_lpr0, saved_lpr1 = 0;
 413
 414        /* LPDDR1 --> force DDR2 mode during self-refresh */
 415        saved_mdr0 = at91_ramc_read(0, AT91_DDRSDRC_MDR);
 416        if ((saved_mdr0 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) {
 417                mdr = saved_mdr0 & ~AT91_DDRSDRC_MD;
 418                mdr |= AT91_DDRSDRC_MD_DDR2;
 419                at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr);
 420        }
 421
 422        if (soc_pm.data.ramc[1]) {
 423                saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
 424                lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
 425                lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
 426                saved_mdr1 = at91_ramc_read(1, AT91_DDRSDRC_MDR);
 427                if ((saved_mdr1 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) {
 428                        mdr = saved_mdr1 & ~AT91_DDRSDRC_MD;
 429                        mdr |= AT91_DDRSDRC_MD_DDR2;
 430                        at91_ramc_write(1, AT91_DDRSDRC_MDR, mdr);
 431                }
 432        }
 433
 434        saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
 435        lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
 436        lpr0 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
 437
 438        /* self-refresh mode now */
 439        at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
 440        if (soc_pm.data.ramc[1])
 441                at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
 442
 443        cpu_do_idle();
 444
 445        at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0);
 446        at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
 447        if (soc_pm.data.ramc[1]) {
 448                at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1);
 449                at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
 450        }
 451}
 452
 453static void sama5d3_ddr_standby(void)
 454{
 455        u32 lpr0;
 456        u32 saved_lpr0;
 457
 458        saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
 459        lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
 460        lpr0 |= AT91_DDRSDRC_LPCB_POWER_DOWN;
 461
 462        at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
 463
 464        cpu_do_idle();
 465
 466        at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
 467}
 468
 469/* We manage both DDRAM/SDRAM controllers, we need more than one value to
 470 * remember.
 471 */
 472static void at91sam9_sdram_standby(void)
 473{
 474        u32 lpr0, lpr1 = 0;
 475        u32 saved_lpr0, saved_lpr1 = 0;
 476
 477        if (soc_pm.data.ramc[1]) {
 478                saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
 479                lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
 480                lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
 481        }
 482
 483        saved_lpr0 = at91_ramc_read(0, AT91_SDRAMC_LPR);
 484        lpr0 = saved_lpr0 & ~AT91_SDRAMC_LPCB;
 485        lpr0 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
 486
 487        /* self-refresh mode now */
 488        at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
 489        if (soc_pm.data.ramc[1])
 490                at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
 491
 492        cpu_do_idle();
 493
 494        at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
 495        if (soc_pm.data.ramc[1])
 496                at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
 497}
 498
 499struct ramc_info {
 500        void (*idle)(void);
 501        unsigned int memctrl;
 502};
 503
 504static const struct ramc_info ramc_infos[] __initconst = {
 505        { .idle = at91rm9200_standby, .memctrl = AT91_MEMCTRL_MC},
 506        { .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC},
 507        { .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
 508        { .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
 509};
 510
 511static const struct of_device_id ramc_ids[] __initconst = {
 512        { .compatible = "atmel,at91rm9200-sdramc", .data = &ramc_infos[0] },
 513        { .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
 514        { .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
 515        { .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
 516        { /*sentinel*/ }
 517};
 518
 519static __init void at91_dt_ramc(void)
 520{
 521        struct device_node *np;
 522        const struct of_device_id *of_id;
 523        int idx = 0;
 524        void *standby = NULL;
 525        const struct ramc_info *ramc;
 526
 527        for_each_matching_node_and_match(np, ramc_ids, &of_id) {
 528                soc_pm.data.ramc[idx] = of_iomap(np, 0);
 529                if (!soc_pm.data.ramc[idx])
 530                        panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
 531
 532                ramc = of_id->data;
 533                if (!standby)
 534                        standby = ramc->idle;
 535                soc_pm.data.memctrl = ramc->memctrl;
 536
 537                idx++;
 538        }
 539
 540        if (!idx)
 541                panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
 542
 543        if (!standby) {
 544                pr_warn("ramc no standby function available\n");
 545                return;
 546        }
 547
 548        at91_cpuidle_device.dev.platform_data = standby;
 549}
 550
 551static void at91rm9200_idle(void)
 552{
 553        /*
 554         * Disable the processor clock.  The processor will be automatically
 555         * re-enabled by an interrupt or by a reset.
 556         */
 557        writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR);
 558}
 559
 560static void at91sam9x60_idle(void)
 561{
 562        cpu_do_idle();
 563}
 564
 565static void at91sam9_idle(void)
 566{
 567        writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR);
 568        cpu_do_idle();
 569}
 570
 571static void __init at91_pm_sram_init(void)
 572{
 573        struct gen_pool *sram_pool;
 574        phys_addr_t sram_pbase;
 575        unsigned long sram_base;
 576        struct device_node *node;
 577        struct platform_device *pdev = NULL;
 578
 579        for_each_compatible_node(node, NULL, "mmio-sram") {
 580                pdev = of_find_device_by_node(node);
 581                if (pdev) {
 582                        of_node_put(node);
 583                        break;
 584                }
 585        }
 586
 587        if (!pdev) {
 588                pr_warn("%s: failed to find sram device!\n", __func__);
 589                return;
 590        }
 591
 592        sram_pool = gen_pool_get(&pdev->dev, NULL);
 593        if (!sram_pool) {
 594                pr_warn("%s: sram pool unavailable!\n", __func__);
 595                return;
 596        }
 597
 598        sram_base = gen_pool_alloc(sram_pool, at91_pm_suspend_in_sram_sz);
 599        if (!sram_base) {
 600                pr_warn("%s: unable to alloc sram!\n", __func__);
 601                return;
 602        }
 603
 604        sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
 605        at91_suspend_sram_fn = __arm_ioremap_exec(sram_pbase,
 606                                        at91_pm_suspend_in_sram_sz, false);
 607        if (!at91_suspend_sram_fn) {
 608                pr_warn("SRAM: Could not map\n");
 609                return;
 610        }
 611
 612        /* Copy the pm suspend handler to SRAM */
 613        at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn,
 614                        &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
 615}
 616
 617static bool __init at91_is_pm_mode_active(int pm_mode)
 618{
 619        return (soc_pm.data.standby_mode == pm_mode ||
 620                soc_pm.data.suspend_mode == pm_mode);
 621}
 622
 623static int __init at91_pm_backup_init(void)
 624{
 625        struct gen_pool *sram_pool;
 626        struct device_node *np;
 627        struct platform_device *pdev = NULL;
 628        int ret = -ENODEV;
 629
 630        if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
 631                return -EPERM;
 632
 633        if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
 634                return 0;
 635
 636        np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
 637        if (!np) {
 638                pr_warn("%s: failed to find sfrbu!\n", __func__);
 639                return ret;
 640        }
 641
 642        soc_pm.data.sfrbu = of_iomap(np, 0);
 643        of_node_put(np);
 644
 645        np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam");
 646        if (!np)
 647                goto securam_fail_no_ref_dev;
 648
 649        pdev = of_find_device_by_node(np);
 650        of_node_put(np);
 651        if (!pdev) {
 652                pr_warn("%s: failed to find securam device!\n", __func__);
 653                goto securam_fail_no_ref_dev;
 654        }
 655
 656        sram_pool = gen_pool_get(&pdev->dev, NULL);
 657        if (!sram_pool) {
 658                pr_warn("%s: securam pool unavailable!\n", __func__);
 659                goto securam_fail;
 660        }
 661
 662        pm_bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu));
 663        if (!pm_bu) {
 664                pr_warn("%s: unable to alloc securam!\n", __func__);
 665                ret = -ENOMEM;
 666                goto securam_fail;
 667        }
 668
 669        pm_bu->suspended = 0;
 670        pm_bu->canary = __pa_symbol(&canary);
 671        pm_bu->resume = __pa_symbol(cpu_resume);
 672
 673        return 0;
 674
 675securam_fail:
 676        put_device(&pdev->dev);
 677securam_fail_no_ref_dev:
 678        iounmap(soc_pm.data.sfrbu);
 679        soc_pm.data.sfrbu = NULL;
 680        return ret;
 681}
 682
 683static void __init at91_pm_use_default_mode(int pm_mode)
 684{
 685        if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP)
 686                return;
 687
 688        if (soc_pm.data.standby_mode == pm_mode)
 689                soc_pm.data.standby_mode = AT91_PM_ULP0;
 690        if (soc_pm.data.suspend_mode == pm_mode)
 691                soc_pm.data.suspend_mode = AT91_PM_ULP0;
 692}
 693
 694static const struct of_device_id atmel_shdwc_ids[] = {
 695        { .compatible = "atmel,sama5d2-shdwc" },
 696        { .compatible = "microchip,sam9x60-shdwc" },
 697        { /* sentinel. */ }
 698};
 699
 700static void __init at91_pm_modes_init(void)
 701{
 702        struct device_node *np;
 703        int ret;
 704
 705        if (!at91_is_pm_mode_active(AT91_PM_BACKUP) &&
 706            !at91_is_pm_mode_active(AT91_PM_ULP1))
 707                return;
 708
 709        np = of_find_matching_node(NULL, atmel_shdwc_ids);
 710        if (!np) {
 711                pr_warn("%s: failed to find shdwc!\n", __func__);
 712                goto ulp1_default;
 713        }
 714
 715        soc_pm.data.shdwc = of_iomap(np, 0);
 716        of_node_put(np);
 717
 718        ret = at91_pm_backup_init();
 719        if (ret) {
 720                if (!at91_is_pm_mode_active(AT91_PM_ULP1))
 721                        goto unmap;
 722                else
 723                        goto backup_default;
 724        }
 725
 726        return;
 727
 728unmap:
 729        iounmap(soc_pm.data.shdwc);
 730        soc_pm.data.shdwc = NULL;
 731ulp1_default:
 732        at91_pm_use_default_mode(AT91_PM_ULP1);
 733backup_default:
 734        at91_pm_use_default_mode(AT91_PM_BACKUP);
 735}
 736
 737struct pmc_info {
 738        unsigned long uhp_udp_mask;
 739        unsigned long mckr;
 740        unsigned long version;
 741};
 742
 743static const struct pmc_info pmc_infos[] __initconst = {
 744        {
 745                .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP,
 746                .mckr = 0x30,
 747                .version = AT91_PMC_V1,
 748        },
 749
 750        {
 751                .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
 752                .mckr = 0x30,
 753                .version = AT91_PMC_V1,
 754        },
 755        {
 756                .uhp_udp_mask = AT91SAM926x_PMC_UHP,
 757                .mckr = 0x30,
 758                .version = AT91_PMC_V1,
 759        },
 760        {       .uhp_udp_mask = 0,
 761                .mckr = 0x30,
 762                .version = AT91_PMC_V1,
 763        },
 764        {
 765                .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
 766                .mckr = 0x28,
 767                .version = AT91_PMC_V2,
 768        },
 769};
 770
 771static const struct of_device_id atmel_pmc_ids[] __initconst = {
 772        { .compatible = "atmel,at91rm9200-pmc", .data = &pmc_infos[0] },
 773        { .compatible = "atmel,at91sam9260-pmc", .data = &pmc_infos[1] },
 774        { .compatible = "atmel,at91sam9261-pmc", .data = &pmc_infos[1] },
 775        { .compatible = "atmel,at91sam9263-pmc", .data = &pmc_infos[1] },
 776        { .compatible = "atmel,at91sam9g45-pmc", .data = &pmc_infos[2] },
 777        { .compatible = "atmel,at91sam9n12-pmc", .data = &pmc_infos[1] },
 778        { .compatible = "atmel,at91sam9rl-pmc", .data = &pmc_infos[3] },
 779        { .compatible = "atmel,at91sam9x5-pmc", .data = &pmc_infos[1] },
 780        { .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
 781        { .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
 782        { .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
 783        { .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] },
 784        { /* sentinel */ },
 785};
 786
 787static void __init at91_pm_init(void (*pm_idle)(void))
 788{
 789        struct device_node *pmc_np;
 790        const struct of_device_id *of_id;
 791        const struct pmc_info *pmc;
 792
 793        if (at91_cpuidle_device.dev.platform_data)
 794                platform_device_register(&at91_cpuidle_device);
 795
 796        pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id);
 797        soc_pm.data.pmc = of_iomap(pmc_np, 0);
 798        if (!soc_pm.data.pmc) {
 799                pr_err("AT91: PM not supported, PMC not found\n");
 800                return;
 801        }
 802
 803        pmc = of_id->data;
 804        soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask;
 805        soc_pm.data.pmc_mckr_offset = pmc->mckr;
 806        soc_pm.data.pmc_version = pmc->version;
 807
 808        if (pm_idle)
 809                arm_pm_idle = pm_idle;
 810
 811        at91_pm_sram_init();
 812
 813        if (at91_suspend_sram_fn) {
 814                suspend_set_ops(&at91_pm_ops);
 815                pr_info("AT91: PM: standby: %s, suspend: %s\n",
 816                        pm_modes[soc_pm.data.standby_mode].pattern,
 817                        pm_modes[soc_pm.data.suspend_mode].pattern);
 818        } else {
 819                pr_info("AT91: PM not supported, due to no SRAM allocated\n");
 820        }
 821}
 822
 823void __init at91rm9200_pm_init(void)
 824{
 825        if (!IS_ENABLED(CONFIG_SOC_AT91RM9200))
 826                return;
 827
 828        at91_dt_ramc();
 829
 830        /*
 831         * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh.
 832         */
 833        at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
 834
 835        at91_pm_init(at91rm9200_idle);
 836}
 837
 838void __init sam9x60_pm_init(void)
 839{
 840        if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
 841                return;
 842
 843        at91_pm_modes_init();
 844        at91_dt_ramc();
 845        at91_pm_init(at91sam9x60_idle);
 846
 847        soc_pm.ws_ids = sam9x60_ws_ids;
 848        soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
 849}
 850
 851void __init at91sam9_pm_init(void)
 852{
 853        if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
 854                return;
 855
 856        at91_dt_ramc();
 857        at91_pm_init(at91sam9_idle);
 858}
 859
 860void __init sama5_pm_init(void)
 861{
 862        if (!IS_ENABLED(CONFIG_SOC_SAMA5))
 863                return;
 864
 865        at91_dt_ramc();
 866        at91_pm_init(NULL);
 867}
 868
 869void __init sama5d2_pm_init(void)
 870{
 871        if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
 872                return;
 873
 874        at91_pm_modes_init();
 875        sama5_pm_init();
 876
 877        soc_pm.ws_ids = sama5d2_ws_ids;
 878        soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws;
 879        soc_pm.config_pmc_ws = at91_sama5d2_config_pmc_ws;
 880}
 881
 882static int __init at91_pm_modes_select(char *str)
 883{
 884        char *s;
 885        substring_t args[MAX_OPT_ARGS];
 886        int standby, suspend;
 887
 888        if (!str)
 889                return 0;
 890
 891        s = strsep(&str, ",");
 892        standby = match_token(s, pm_modes, args);
 893        if (standby < 0)
 894                return 0;
 895
 896        suspend = match_token(str, pm_modes, args);
 897        if (suspend < 0)
 898                return 0;
 899
 900        soc_pm.data.standby_mode = standby;
 901        soc_pm.data.suspend_mode = suspend;
 902
 903        return 0;
 904}
 905early_param("atmel.pm_modes", at91_pm_modes_select);
 906