/* * linux/arch/mips/jz4760/common/pm.c * * JZ4760 Power Management Routines * * Copyright (C) 2006 Ingenic Semiconductor Inc. * Author: * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #undef DEBUG //#define DEBUG #ifdef DEBUG #define dprintk(x...) printk(x) #else #define dprintk(x...) #endif #define GPIO_PORT_NUM 6 /* * __gpio_as_sleep set all pins to pull-disable, and set all pins as input * except sdram and the pins which can be used as CS1_N to CS4_N for chip select. */ #define __gpio_as_sleep() \ do { \ REG_GPIO_PXFUNC(1) = ~0x03ff7fff; \ REG_GPIO_PXSELC(1) = ~0x03ff7fff; \ REG_GPIO_PXDIRC(1) = ~0x03ff7fff; \ REG_GPIO_PXPES(1) = 0xffffffff; \ REG_GPIO_PXFUNC(2) = ~0x01e00000; \ REG_GPIO_PXSELC(2) = ~0x01e00000; \ REG_GPIO_PXDIRC(2) = ~0x01e00000; \ REG_GPIO_PXPES(2) = 0xffffffff; \ REG_GPIO_PXFUNC(3) = 0xffffffff; \ REG_GPIO_PXSELC(3) = 0xffffffff; \ REG_GPIO_PXDIRC(3) = 0xffffffff; \ REG_GPIO_PXPES(3) = 0xffffffff; \ REG_GPIO_PXFUNC(4) = 0xffffffff; \ REG_GPIO_PXSELC(4) = 0xffffffff; \ REG_GPIO_PXDIRC(4) = 0xffffffff; \ REG_GPIO_PXPES(4) = 0xffffffff; \ REG_GPIO_PXFUNC(5) = 0xffffffff; \ REG_GPIO_PXSELC(5) = 0xffffffff; \ REG_GPIO_PXDIRC(5) = 0xffffffff; \ REG_GPIO_PXPES(5) = 0xffffffff; \ } while (0) static int jz_pm_do_hibernate(void) { printk("Put CPU into hibernate mode.\n"); /* Mask all interrupts */ REG_INTC_IMSR = 0xffffffff; /* * RTC Wakeup or 1Hz interrupt can be enabled or disabled * through RTC driver's ioctl (linux/driver/char/rtc_jz.c). */ /* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */ while (!(REG_RTC_RCR & RTC_RCR_WRDY)); REG_RTC_HWFCR = (100 << RTC_HWFCR_BIT); /* Set reset pin low-level assertion time after wakeup: must > 60ms */ while (!(REG_RTC_RCR & RTC_RCR_WRDY)); REG_RTC_HRCR = (60 << RTC_HRCR_BIT); /* 60 ms */ /* Scratch pad register to be reserved */ while (!(REG_RTC_RCR & RTC_RCR_WRDY)); REG_RTC_HSPR = 0x12345678; /* clear wakeup status register */ while (!(REG_RTC_RCR & RTC_RCR_WRDY)); REG_RTC_HWRSR = 0x0; /* Put CPU to power down mode */ while (!(REG_RTC_RCR & RTC_RCR_WRDY)); REG_RTC_HCR = RTC_HCR_PD; while (!(REG_RTC_RCR & RTC_RCR_WRDY)); while(1); /* We can't get here */ return 0; } /* NOTES: * 1: Pins that are floated (NC) should be set as input and pull-enable. * 2: Pins that are pull-up or pull-down by outside should be set as input * and pull-disable. * 3: Pins that are connected to a chip except sdram and nand flash * should be set as input and pull-disable, too. */ static void jz_board_do_sleep(unsigned long *ptr) { unsigned char i; /* Print messages of GPIO registers for debug */ for(i=0;i