예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
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;
}