static int at91_pm_enter(suspend_state_t state) { u32 saved_lpr; at91_gpio_suspend(); at91_irq_suspend(); pr_debug("AT91: PM - wake mask %08x, pm state %d\n", /* remember all the always-wake irqs */ (at91_sys_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) | (at91_extern_irq)) & at91_sys_read(AT91_AIC_IMR), state); switch (state) { /* * Suspend-to-RAM is like STANDBY plus slow clock mode, so * drivers must suspend more deeply: only the master clock * controller may be using the main oscillator. */ case PM_SUSPEND_MEM: /* * Ensure that clocks are in a valid state. */ if (!at91_pm_verify_clocks()) goto error; /* * Enter slow clock mode by switching over to clk32k and * turning off the main oscillator; reverse on wakeup. */ if (slow_clock) { #ifdef CONFIG_AT91_SLOW_CLOCK /* copy slow_clock handler to SRAM, and call it */ memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); #endif slow_clock(); break; } else { pr_info("AT91: PM - no slow clock mode enabled ...\n"); /* FALLTHROUGH leaving master clock alone */ } /* * STANDBY mode has *all* drivers suspended; ignores irqs not * marked as 'wakeup' event sources; and reduces DRAM power. * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and * nothing fancy done with main or cpu clocks. */ case PM_SUSPEND_STANDBY: /* * NOTE: the Wait-for-Interrupt instruction needs to be * in icache so no SDRAM accesses are needed until the * wakeup IRQ occurs and self-refresh is terminated. */ asm("b 1f; .align 5; 1:"); asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ saved_lpr = sdram_selfrefresh_enable(); asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */ sdram_selfrefresh_disable(saved_lpr); break; case PM_SUSPEND_ON: asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */ break; default: pr_debug("AT91: PM - bogus suspend state %d\n", state); goto error; } pr_debug("AT91: PM - wakeup %08x\n", at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); error: target_state = PM_SUSPEND_ON; at91_irq_resume(); at91_gpio_resume(); return 0; }
static int at91_pm_enter(suspend_state_t state) { at91_gpio_suspend(); at91_irq_suspend(); pr_debug("AT91: PM - wake mask %08x, pm state %d\n", /* */ (at91_pmc_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) | (at91_extern_irq)) & at91_aic_read(AT91_AIC_IMR), state); switch (state) { /* */ case PM_SUSPEND_MEM: /* */ if (!at91_pm_verify_clocks()) goto error; /* */ if (slow_clock) { int memctrl = AT91_MEMCTRL_SDRAMC; if (cpu_is_at91rm9200()) memctrl = AT91_MEMCTRL_MC; else if (cpu_is_at91sam9g45()) memctrl = AT91_MEMCTRL_DDRSDR; #ifdef CONFIG_AT91_SLOW_CLOCK /* */ memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); #endif slow_clock(at91_pmc_base, at91_ramc_base[0], at91_ramc_base[1], memctrl); break; } else { pr_info("AT91: PM - no slow clock mode enabled ...\n"); /* */ } /* */ case PM_SUSPEND_STANDBY: /* */ at91_standby(); break; case PM_SUSPEND_ON: cpu_do_idle(); break; default: pr_debug("AT91: PM - bogus suspend state %d\n", state); goto error; } pr_debug("AT91: PM - wakeup %08x\n", at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR)); error: target_state = PM_SUSPEND_ON; at91_irq_resume(); at91_gpio_resume(); return 0; }
static int at91_pm_enter(suspend_state_t state) { if (of_have_populated_dt()) at91_pinctrl_gpio_suspend(); else at91_gpio_suspend(); at91_irq_suspend(); pr_debug("AT91: PM - wake mask %08x, pm state %d\n", /* remember all the always-wake irqs */ (at91_pmc_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) | (at91_get_extern_irq())) & at91_aic_read(AT91_AIC_IMR), state); switch (state) { /* * Suspend-to-RAM is like STANDBY plus slow clock mode, so * drivers must suspend more deeply: only the master clock * controller may be using the main oscillator. */ case PM_SUSPEND_MEM: /* * Ensure that clocks are in a valid state. */ if (!at91_pm_verify_clocks()) goto error; /* * Enter slow clock mode by switching over to clk32k and * turning off the main oscillator; reverse on wakeup. */ if (slow_clock) { int memctrl = AT91_MEMCTRL_SDRAMC; if (cpu_is_at91rm9200()) memctrl = AT91_MEMCTRL_MC; else if (cpu_is_at91sam9g45()) memctrl = AT91_MEMCTRL_DDRSDR; #ifdef CONFIG_AT91_SLOW_CLOCK /* copy slow_clock handler to SRAM, and call it */ memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); #endif slow_clock(at91_pmc_base, at91_ramc_base[0], at91_ramc_base[1], memctrl); break; } else { pr_info("AT91: PM - no slow clock mode enabled ...\n"); /* FALLTHROUGH leaving master clock alone */ } /* * STANDBY mode has *all* drivers suspended; ignores irqs not * marked as 'wakeup' event sources; and reduces DRAM power. * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and * nothing fancy done with main or cpu clocks. */ case PM_SUSPEND_STANDBY: /* * NOTE: the Wait-for-Interrupt instruction needs to be * in icache so no SDRAM accesses are needed until the * wakeup IRQ occurs and self-refresh is terminated. * For ARM 926 based chips, this requirement is weaker * as at91sam9 can access a RAM in self-refresh mode. */ if (at91_pm_standby) at91_pm_standby(); break; case PM_SUSPEND_ON: cpu_do_idle(); break; default: pr_debug("AT91: PM - bogus suspend state %d\n", state); goto error; } pr_debug("AT91: PM - wakeup %08x\n", at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR)); error: target_state = PM_SUSPEND_ON; at91_irq_resume(); if (of_have_populated_dt()) at91_pinctrl_gpio_resume(); else at91_gpio_resume(); return 0; }
static int at91_pm_enter(suspend_state_t state) { at91_gpio_suspend(); at91_irq_suspend(); pr_debug("AT91: PM - wake mask %08x, pm state %d\n", /* remember all the always-wake irqs */ (at91_sys_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) | (1 << AT91_ID_IRQ0) | (1 << AT91_ID_IRQ1) | (1 << AT91_ID_IRQ2) | (1 << AT91_ID_IRQ3) | (1 << AT91_ID_IRQ4) | (1 << AT91_ID_IRQ5) | (1 << AT91_ID_IRQ6)) & at91_sys_read(AT91_AIC_IMR), state); switch (state) { /* * Suspend-to-RAM is like STANDBY plus slow clock mode, so * drivers must suspend more deeply: only the master clock * controller may be using the main oscillator. */ case PM_SUSPEND_MEM: /* * Ensure that clocks are in a valid state. */ if (!at91_pm_verify_clocks()) goto error; /* * Enter slow clock mode by switching over to clk32k and * turning off the main oscillator; reverse on wakeup. */ if (slow_clock) { slow_clock(); break; } else { /* DEVELOPMENT ONLY */ pr_info("AT91: PM - no slow clock mode yet ...\n"); /* FALLTHROUGH leaving master clock alone */ } /* * STANDBY mode has *all* drivers suspended; ignores irqs not * marked as 'wakeup' event sources; and reduces DRAM power. * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and * nothing fancy done with main or cpu clocks. */ case PM_SUSPEND_STANDBY: /* * NOTE: the Wait-for-Interrupt instruction needs to be * in icache so the SDRAM stays in self-refresh mode until * the wakeup IRQ occurs. */ asm("b 1f; .align 5; 1:"); asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ at91_sys_write(AT91_SDRAMC_SRR, 1); /* self-refresh mode */ /* fall though to next state */ case PM_SUSPEND_ON: asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */ break; default: pr_debug("AT91: PM - bogus suspend state %d\n", state); goto error; } pr_debug("AT91: PM - wakeup %08x\n", at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); error: target_state = PM_SUSPEND_ON; at91_irq_resume(); at91_gpio_resume(); return 0; }