📄 pm.c
字号:
/* * pm.c * * This file implements the Jz47xx CPU clock change and suspend/resume. * * Author: Wei Jianli <jlwei@ingenic.cn> * * Copyright (C) 2006 Ingenic Semiconductor Inc. All rights reserved. */#include <regs.h>#include <ops.h>#include <clock.h>//=======================================================================//// CPU clock change local variables////=======================================================================static unsigned long boot_rtcor_val;static unsigned long boot_mclk_val;#define PLL_WAIT_500NS (500*(1000000000/__cpm_get_iclk()))//==========================================================================//// CPU suspend / resume local routines////==========================================================================#define SAVE(x,s) sleep_save[SLEEP_SAVE_##x] = REG##s(x)#define RESTORE(x,s) REG##s(x) = sleep_save[SLEEP_SAVE_##x]/* * List of global jz47xx peripheral registers to preserve. * More ones like core register and general purpose register values * are preserved with the stack pointer in sleep.S. */enum { SLEEP_SAVE_START = 0, /* OST */ SLEEP_SAVE_OST_TER, SLEEP_SAVE_OST_TCSR0, SLEEP_SAVE_OST_TCSR1, SLEEP_SAVE_OST_TCSR2, SLEEP_SAVE_OST_TRDR0, SLEEP_SAVE_OST_TRDR1, SLEEP_SAVE_OST_TRDR2, SLEEP_SAVE_OST_TCNT0, SLEEP_SAVE_OST_TCNT1, SLEEP_SAVE_OST_TCNT2, /* HARB */ SLEEP_SAVE_HARB_HAPOR, SLEEP_SAVE_HARB_HMCTR, SLEEP_SAVE_HARB_HMLTR, /* GPIO */ SLEEP_SAVE_GPIO_GPDR0, SLEEP_SAVE_GPIO_GPDR1, SLEEP_SAVE_GPIO_GPDR2, SLEEP_SAVE_GPIO_GPDR3, SLEEP_SAVE_GPIO_GPDIR0, SLEEP_SAVE_GPIO_GPDIR1, SLEEP_SAVE_GPIO_GPDIR2, SLEEP_SAVE_GPIO_GPDIR3, SLEEP_SAVE_GPIO_GPODR0, SLEEP_SAVE_GPIO_GPODR1, SLEEP_SAVE_GPIO_GPODR2, SLEEP_SAVE_GPIO_GPODR3, SLEEP_SAVE_GPIO_GPPUR0, SLEEP_SAVE_GPIO_GPPUR1, SLEEP_SAVE_GPIO_GPPUR2, SLEEP_SAVE_GPIO_GPPUR3, SLEEP_SAVE_GPIO_GPALR0, SLEEP_SAVE_GPIO_GPALR1, SLEEP_SAVE_GPIO_GPALR2, SLEEP_SAVE_GPIO_GPALR3, SLEEP_SAVE_GPIO_GPAUR0, SLEEP_SAVE_GPIO_GPAUR1, SLEEP_SAVE_GPIO_GPAUR2, SLEEP_SAVE_GPIO_GPAUR3, SLEEP_SAVE_GPIO_GPIDLR0, SLEEP_SAVE_GPIO_GPIDLR1, SLEEP_SAVE_GPIO_GPIDLR2, SLEEP_SAVE_GPIO_GPIDLR3, SLEEP_SAVE_GPIO_GPIDUR0, SLEEP_SAVE_GPIO_GPIDUR1, SLEEP_SAVE_GPIO_GPIDUR2, SLEEP_SAVE_GPIO_GPIDUR3, SLEEP_SAVE_GPIO_GPIER0, SLEEP_SAVE_GPIO_GPIER1, SLEEP_SAVE_GPIO_GPIER2, SLEEP_SAVE_GPIO_GPIER3, SLEEP_SAVE_GPIO_GPIMR0, SLEEP_SAVE_GPIO_GPIMR1, SLEEP_SAVE_GPIO_GPIMR2, SLEEP_SAVE_GPIO_GPIMR3, SLEEP_SAVE_GPIO_GPFR0, SLEEP_SAVE_GPIO_GPFR1, SLEEP_SAVE_GPIO_GPFR2, SLEEP_SAVE_GPIO_GPFR3, /* UART(0-3) */ SLEEP_SAVE_UART0_IER, SLEEP_SAVE_UART0_LCR, SLEEP_SAVE_UART0_MCR, SLEEP_SAVE_UART0_SPR, SLEEP_SAVE_UART0_DLLR, SLEEP_SAVE_UART0_DLHR, SLEEP_SAVE_UART1_IER, SLEEP_SAVE_UART1_LCR, SLEEP_SAVE_UART1_MCR, SLEEP_SAVE_UART1_SPR, SLEEP_SAVE_UART1_DLLR, SLEEP_SAVE_UART1_DLHR, SLEEP_SAVE_UART2_IER, SLEEP_SAVE_UART2_LCR, SLEEP_SAVE_UART2_MCR, SLEEP_SAVE_UART2_SPR, SLEEP_SAVE_UART2_DLLR, SLEEP_SAVE_UART2_DLHR, SLEEP_SAVE_UART3_IER, SLEEP_SAVE_UART3_LCR, SLEEP_SAVE_UART3_MCR, SLEEP_SAVE_UART3_SPR, SLEEP_SAVE_UART3_DLLR, SLEEP_SAVE_UART3_DLHR, /* DMAC */ SLEEP_SAVE_DMAC_DMACR, SLEEP_SAVE_DMAC_DSAR0, SLEEP_SAVE_DMAC_DSAR1, SLEEP_SAVE_DMAC_DSAR2, SLEEP_SAVE_DMAC_DSAR3, SLEEP_SAVE_DMAC_DSAR4, SLEEP_SAVE_DMAC_DSAR5, SLEEP_SAVE_DMAC_DSAR6, SLEEP_SAVE_DMAC_DSAR7, SLEEP_SAVE_DMAC_DDAR0, SLEEP_SAVE_DMAC_DDAR1, SLEEP_SAVE_DMAC_DDAR2, SLEEP_SAVE_DMAC_DDAR3, SLEEP_SAVE_DMAC_DDAR4, SLEEP_SAVE_DMAC_DDAR5, SLEEP_SAVE_DMAC_DDAR6, SLEEP_SAVE_DMAC_DDAR7, SLEEP_SAVE_DMAC_DTCR0, SLEEP_SAVE_DMAC_DTCR1, SLEEP_SAVE_DMAC_DTCR2, SLEEP_SAVE_DMAC_DTCR3, SLEEP_SAVE_DMAC_DTCR4, SLEEP_SAVE_DMAC_DTCR5, SLEEP_SAVE_DMAC_DTCR6, SLEEP_SAVE_DMAC_DTCR7, SLEEP_SAVE_DMAC_DRSR0, SLEEP_SAVE_DMAC_DRSR1, SLEEP_SAVE_DMAC_DRSR2, SLEEP_SAVE_DMAC_DRSR3, SLEEP_SAVE_DMAC_DRSR4, SLEEP_SAVE_DMAC_DRSR5, SLEEP_SAVE_DMAC_DRSR6, SLEEP_SAVE_DMAC_DRSR7, SLEEP_SAVE_DMAC_DCCSR0, SLEEP_SAVE_DMAC_DCCSR1, SLEEP_SAVE_DMAC_DCCSR2, SLEEP_SAVE_DMAC_DCCSR3, SLEEP_SAVE_DMAC_DCCSR4, SLEEP_SAVE_DMAC_DCCSR5, SLEEP_SAVE_DMAC_DCCSR6, SLEEP_SAVE_DMAC_DCCSR7, /* INTC */ SLEEP_SAVE_INTC_IMR, /* Checksum */ SLEEP_SAVE_CKSUM, SLEEP_SAVE_SIZE};/*********************************************************************** * void pm_wakeup_setup(void) * * This is called to setup the wakeup sources (such as key input etc.) * before suspending the CPU. * ***********************************************************************/static void pm_wakeup_setup(void){ REG_CPM_WER = 0; /* Clear all wakeup sources first */ /* Set the GPIO/CS/PCMCIA pins state in hibernate mode */ /* Put next pins to there proper states during HIBERNATE * * GP66(PW_O) = high * GP94(PWM0) = low */ __cpm_set_pin(66); __cpm_clear_pin(94); /* Enable GP97(PW_I) wakeup function */ __gpio_as_input(97); REG_CPM_WER |= 1 << 1; REG_CPM_WRER |= 1 << 1; REG_CPM_WFER |= 1 << 1; __intc_unmask_irq(IRQ_GPIO3); /* enable INTC irq */}/*********************************************************************** * void pm_cpu_suspend_enter(void) * * This is called to suspend all other devices before suspending the CPU. * ***********************************************************************/#define MMC_POWER_PIN 91 /* Pin to enable/disable card power */#define MMC_POWER_OFF() \do { \ __gpio_set_pin(MMC_POWER_PIN); \} while (0)static void pm_cpu_suspend_enter(void){ MMC_POWER_OFF(); /* Disable power to MMC/SD card */}/*********************************************************************** * void pm_cpu_suspend_exit(void) * * This is called to resume all other devices after resuming. * ***********************************************************************/static void pm_cpu_suspend_exit(void){ REG_EMC_NFCSR |= EMC_NFCSR_NFE; /* Enable NAND flash */ MMC_Initialize(); /* ReInitialize the MMC/SD card */ pcm_init(); /* ReInitialize the audio system */}/*********************************************************************** * void do_pm_cpu_suspend(void) * * This is called internally to do the CPU suspend. * ***********************************************************************/extern void jz_cpu_suspend(void);extern void jz_cpu_resume(void);#define PHYS(addr) ((unsigned long)(addr) & ~0xE0000000)static void do_pm_cpu_suspend(void){ unsigned long sleep_save[SLEEP_SAVE_SIZE]; unsigned long delta; unsigned long checksum = 0; int i; REG_CPM_OCR |= CPM_OCR_SUSPEND_PHY0; /* suspend USB PHY 0 */ REG_CPM_OCR |= CPM_OCR_SUSPEND_PHY1; /* suspend USB PHY 1 */ REG_CPM_OCR |= CPM_OCR_EXT_RTC_CLK; /* select the external RTC clock (32.768KHz) */ /* * Temporary solution. This won't be necessary once * we move jz support into the serial driver. * Save the on-chip UART */ SAVE(UART0_LCR, 8); SAVE(UART0_MCR, 8); SAVE(UART0_SPR, 8); REG8(UART0_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ SAVE(UART0_DLLR, 8); SAVE(UART0_DLHR, 8); REG8(UART0_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ SAVE(UART0_IER, 8); SAVE(UART1_LCR, 8); SAVE(UART1_MCR, 8); SAVE(UART1_SPR, 8); REG8(UART1_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ SAVE(UART1_DLLR, 8); SAVE(UART1_DLHR, 8); REG8(UART1_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ SAVE(UART1_IER, 8); SAVE(UART2_LCR, 8); SAVE(UART2_MCR, 8); SAVE(UART2_SPR, 8); REG8(UART2_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ SAVE(UART2_DLLR, 8); SAVE(UART2_DLHR, 8); REG8(UART2_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ SAVE(UART2_IER, 8); SAVE(UART3_LCR, 8); SAVE(UART3_MCR, 8); SAVE(UART3_SPR, 8); REG8(UART3_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ SAVE(UART3_DLLR, 8); SAVE(UART3_DLHR, 8); REG8(UART3_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ SAVE(UART3_IER, 8); /* Save vital registers */ SAVE(OST_TER, 8); SAVE(OST_TCSR0, 16); SAVE(OST_TCSR1, 16); SAVE(OST_TCSR2, 16); SAVE(OST_TRDR0, 32); SAVE(OST_TRDR1, 32); SAVE(OST_TRDR2, 32); SAVE(OST_TCNT0, 32); SAVE(OST_TCNT1, 32); SAVE(OST_TCNT2, 32); SAVE(HARB_HAPOR, 32); SAVE(HARB_HMCTR, 32); SAVE(HARB_HMLTR, 32); SAVE(GPIO_GPDR0, 32); SAVE(GPIO_GPDR1, 32); SAVE(GPIO_GPDR2, 32); SAVE(GPIO_GPDR3, 32); SAVE(GPIO_GPDIR0, 32); SAVE(GPIO_GPDIR1, 32); SAVE(GPIO_GPDIR2, 32); SAVE(GPIO_GPDIR3, 32); SAVE(GPIO_GPODR0, 32); SAVE(GPIO_GPODR1, 32); SAVE(GPIO_GPODR2, 32); SAVE(GPIO_GPODR3, 32); SAVE(GPIO_GPPUR0, 32); SAVE(GPIO_GPPUR1, 32); SAVE(GPIO_GPPUR2, 32); SAVE(GPIO_GPPUR3, 32); SAVE(GPIO_GPALR0, 32); SAVE(GPIO_GPALR1, 32); SAVE(GPIO_GPALR2, 32); SAVE(GPIO_GPALR3, 32); SAVE(GPIO_GPAUR0, 32); SAVE(GPIO_GPAUR1, 32); SAVE(GPIO_GPAUR2, 32); SAVE(GPIO_GPAUR3, 32); SAVE(GPIO_GPIDLR0, 32); SAVE(GPIO_GPIDLR1, 32); SAVE(GPIO_GPIDLR2, 32); SAVE(GPIO_GPIDLR3, 32); SAVE(GPIO_GPIDUR0, 32); SAVE(GPIO_GPIDUR1, 32); SAVE(GPIO_GPIDUR2, 32); SAVE(GPIO_GPIDUR3, 32); SAVE(GPIO_GPIER0, 32); SAVE(GPIO_GPIER1, 32); SAVE(GPIO_GPIER2, 32); SAVE(GPIO_GPIER3, 32); SAVE(GPIO_GPIMR0, 32); SAVE(GPIO_GPIMR1, 32); SAVE(GPIO_GPIMR2, 32); SAVE(GPIO_GPIMR3, 32); SAVE(GPIO_GPFR0, 32); SAVE(GPIO_GPFR1, 32); SAVE(GPIO_GPFR2, 32); SAVE(GPIO_GPFR3, 32); SAVE(DMAC_DMACR, 32); SAVE(DMAC_DSAR0, 32); SAVE(DMAC_DSAR1, 32); SAVE(DMAC_DSAR2, 32); SAVE(DMAC_DSAR3, 32); SAVE(DMAC_DSAR4, 32); SAVE(DMAC_DSAR5, 32); SAVE(DMAC_DSAR6, 32); SAVE(DMAC_DSAR7, 32); SAVE(DMAC_DDAR0, 32); SAVE(DMAC_DDAR1, 32); SAVE(DMAC_DDAR2, 32); SAVE(DMAC_DDAR3, 32); SAVE(DMAC_DDAR4, 32); SAVE(DMAC_DDAR5, 32); SAVE(DMAC_DDAR6, 32); SAVE(DMAC_DDAR7, 32); SAVE(DMAC_DTCR0, 32); SAVE(DMAC_DTCR1, 32); SAVE(DMAC_DTCR2, 32); SAVE(DMAC_DTCR3, 32); SAVE(DMAC_DTCR4, 32); SAVE(DMAC_DTCR5, 32); SAVE(DMAC_DTCR6, 32); SAVE(DMAC_DTCR7, 32); SAVE(DMAC_DRSR0, 32); SAVE(DMAC_DRSR1, 32); SAVE(DMAC_DRSR2, 32); SAVE(DMAC_DRSR3, 32); SAVE(DMAC_DRSR4, 32); SAVE(DMAC_DRSR5, 32); SAVE(DMAC_DRSR6, 32); SAVE(DMAC_DRSR7, 32); SAVE(DMAC_DCCSR0, 32); SAVE(DMAC_DCCSR1, 32); SAVE(DMAC_DCCSR2, 32); SAVE(DMAC_DCCSR3, 32); SAVE(DMAC_DCCSR4, 32); SAVE(DMAC_DCCSR5, 32); SAVE(DMAC_DCCSR6, 32); SAVE(DMAC_DCCSR7, 32); SAVE(INTC_IMR, 32); REG32(INTC_IMSR) = 0xffffffff; /* Mask all intrs */ pm_wakeup_setup(); /* setup wakeup sources */ /* Clear previous reset status */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -