1 /* 2 * BRIEF MODULE DESCRIPTION 3 * Au1xx0 Power Management routines. 4 * 5 * Copyright 2001, 2008 MontaVista Software Inc. 6 * Author: MontaVista Software, Inc. <source@mvista.com> 7 * 8 * Some of the routines are right out of init/main.c, whose 9 * copyrights apply here. 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License as published by the 13 * Free Software Foundation; either version 2 of the License, or (at your 14 * option) any later version. 15 * 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 22 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * You should have received a copy of the GNU General Public License along 28 * with this program; if not, write to the Free Software Foundation, Inc., 29 * 675 Mass Ave, Cambridge, MA 02139, USA. 30 */ 31 32 #include <linux/init.h> 33 #include <linux/pm.h> 34 #include <linux/sysctl.h> 35 #include <linux/jiffies.h> 36 37 #include <asm/uaccess.h> 38 #include <asm/mach-au1x00/au1000.h> 39 40 /* 41 * We need to save/restore a bunch of core registers that are 42 * either volatile or reset to some state across a processor sleep. 43 * If reading a register doesn't provide a proper result for a 44 * later restore, we have to provide a function for loading that 45 * register and save a copy. 46 * 47 * We only have to save/restore registers that aren't otherwise 48 * done as part of a driver pm_* function. 49 */ 50 static unsigned int sleep_sys_clocks[5]; 51 static unsigned int sleep_sys_pinfunc; 52 static unsigned int sleep_static_memctlr[4][3]; 53 54 55 static void save_core_regs(void) 56 { 57 /* Clocks and PLLs. */ 58 sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); 59 sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); 60 sleep_sys_clocks[2] = au_readl(SYS_CLKSRC); 61 sleep_sys_clocks[3] = au_readl(SYS_CPUPLL); 62 sleep_sys_clocks[4] = au_readl(SYS_AUXPLL); 63 64 /* pin mux config */ 65 sleep_sys_pinfunc = au_readl(SYS_PINFUNC); 66 67 /* Save the static memory controller configuration. */ 68 sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); 69 sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0); 70 sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0); 71 sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1); 72 sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1); 73 sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1); 74 sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2); 75 sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2); 76 sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2); 77 sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); 78 sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); 79 sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); 80 } 81 82 static void restore_core_regs(void) 83 { 84 /* restore clock configuration. Writing CPUPLL last will 85 * stall a bit and stabilize other clocks (unless this is 86 * one of those Au1000 with a write-only PLL, where we dont 87 * have a valid value) 88 */ 89 au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0); 90 au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1); 91 au_writel(sleep_sys_clocks[2], SYS_CLKSRC); 92 au_writel(sleep_sys_clocks[4], SYS_AUXPLL); 93 if (!au1xxx_cpu_has_pll_wo()) 94 au_writel(sleep_sys_clocks[3], SYS_CPUPLL); 95 au_sync(); 96 97 au_writel(sleep_sys_pinfunc, SYS_PINFUNC); 98 au_sync(); 99 100 /* Restore the static memory controller configuration. */ 101 au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); 102 au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); 103 au_writel(sleep_static_memctlr[0][2], MEM_STADDR0); 104 au_writel(sleep_static_memctlr[1][0], MEM_STCFG1); 105 au_writel(sleep_static_memctlr[1][1], MEM_STTIME1); 106 au_writel(sleep_static_memctlr[1][2], MEM_STADDR1); 107 au_writel(sleep_static_memctlr[2][0], MEM_STCFG2); 108 au_writel(sleep_static_memctlr[2][1], MEM_STTIME2); 109 au_writel(sleep_static_memctlr[2][2], MEM_STADDR2); 110 au_writel(sleep_static_memctlr[3][0], MEM_STCFG3); 111 au_writel(sleep_static_memctlr[3][1], MEM_STTIME3); 112 au_writel(sleep_static_memctlr[3][2], MEM_STADDR3); 113 } 114 115 void au_sleep(void) 116 { 117 save_core_regs(); 118 119 switch (alchemy_get_cputype()) { 120 case ALCHEMY_CPU_AU1000: 121 case ALCHEMY_CPU_AU1500: 122 case ALCHEMY_CPU_AU1100: 123 alchemy_sleep_au1000(); 124 break; 125 case ALCHEMY_CPU_AU1550: 126 case ALCHEMY_CPU_AU1200: 127 alchemy_sleep_au1550(); 128 break; 129 } 130 131 restore_core_regs(); 132 } 133