0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <linux/pm.h>
0033 #include <linux/sysctl.h>
0034 #include <linux/jiffies.h>
0035
0036 #include <linux/uaccess.h>
0037 #include <asm/mach-au1x00/au1000.h>
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 static unsigned int sleep_sys_clocks[5];
0050 static unsigned int sleep_sys_pinfunc;
0051 static unsigned int sleep_static_memctlr[4][3];
0052
0053
0054 static void save_core_regs(void)
0055 {
0056
0057 sleep_sys_clocks[0] = alchemy_rdsys(AU1000_SYS_FREQCTRL0);
0058 sleep_sys_clocks[1] = alchemy_rdsys(AU1000_SYS_FREQCTRL1);
0059 sleep_sys_clocks[2] = alchemy_rdsys(AU1000_SYS_CLKSRC);
0060 sleep_sys_clocks[3] = alchemy_rdsys(AU1000_SYS_CPUPLL);
0061 sleep_sys_clocks[4] = alchemy_rdsys(AU1000_SYS_AUXPLL);
0062
0063
0064 sleep_sys_pinfunc = alchemy_rdsys(AU1000_SYS_PINFUNC);
0065
0066
0067 sleep_static_memctlr[0][0] = alchemy_rdsmem(AU1000_MEM_STCFG0);
0068 sleep_static_memctlr[0][1] = alchemy_rdsmem(AU1000_MEM_STTIME0);
0069 sleep_static_memctlr[0][2] = alchemy_rdsmem(AU1000_MEM_STADDR0);
0070 sleep_static_memctlr[1][0] = alchemy_rdsmem(AU1000_MEM_STCFG1);
0071 sleep_static_memctlr[1][1] = alchemy_rdsmem(AU1000_MEM_STTIME1);
0072 sleep_static_memctlr[1][2] = alchemy_rdsmem(AU1000_MEM_STADDR1);
0073 sleep_static_memctlr[2][0] = alchemy_rdsmem(AU1000_MEM_STCFG2);
0074 sleep_static_memctlr[2][1] = alchemy_rdsmem(AU1000_MEM_STTIME2);
0075 sleep_static_memctlr[2][2] = alchemy_rdsmem(AU1000_MEM_STADDR2);
0076 sleep_static_memctlr[3][0] = alchemy_rdsmem(AU1000_MEM_STCFG3);
0077 sleep_static_memctlr[3][1] = alchemy_rdsmem(AU1000_MEM_STTIME3);
0078 sleep_static_memctlr[3][2] = alchemy_rdsmem(AU1000_MEM_STADDR3);
0079 }
0080
0081 static void restore_core_regs(void)
0082 {
0083
0084
0085
0086
0087
0088 alchemy_wrsys(sleep_sys_clocks[0], AU1000_SYS_FREQCTRL0);
0089 alchemy_wrsys(sleep_sys_clocks[1], AU1000_SYS_FREQCTRL1);
0090 alchemy_wrsys(sleep_sys_clocks[2], AU1000_SYS_CLKSRC);
0091 alchemy_wrsys(sleep_sys_clocks[4], AU1000_SYS_AUXPLL);
0092 if (!au1xxx_cpu_has_pll_wo())
0093 alchemy_wrsys(sleep_sys_clocks[3], AU1000_SYS_CPUPLL);
0094
0095 alchemy_wrsys(sleep_sys_pinfunc, AU1000_SYS_PINFUNC);
0096
0097
0098 alchemy_wrsmem(sleep_static_memctlr[0][0], AU1000_MEM_STCFG0);
0099 alchemy_wrsmem(sleep_static_memctlr[0][1], AU1000_MEM_STTIME0);
0100 alchemy_wrsmem(sleep_static_memctlr[0][2], AU1000_MEM_STADDR0);
0101 alchemy_wrsmem(sleep_static_memctlr[1][0], AU1000_MEM_STCFG1);
0102 alchemy_wrsmem(sleep_static_memctlr[1][1], AU1000_MEM_STTIME1);
0103 alchemy_wrsmem(sleep_static_memctlr[1][2], AU1000_MEM_STADDR1);
0104 alchemy_wrsmem(sleep_static_memctlr[2][0], AU1000_MEM_STCFG2);
0105 alchemy_wrsmem(sleep_static_memctlr[2][1], AU1000_MEM_STTIME2);
0106 alchemy_wrsmem(sleep_static_memctlr[2][2], AU1000_MEM_STADDR2);
0107 alchemy_wrsmem(sleep_static_memctlr[3][0], AU1000_MEM_STCFG3);
0108 alchemy_wrsmem(sleep_static_memctlr[3][1], AU1000_MEM_STTIME3);
0109 alchemy_wrsmem(sleep_static_memctlr[3][2], AU1000_MEM_STADDR3);
0110 }
0111
0112 void au_sleep(void)
0113 {
0114 save_core_regs();
0115
0116 switch (alchemy_get_cputype()) {
0117 case ALCHEMY_CPU_AU1000:
0118 case ALCHEMY_CPU_AU1500:
0119 case ALCHEMY_CPU_AU1100:
0120 alchemy_sleep_au1000();
0121 break;
0122 case ALCHEMY_CPU_AU1550:
0123 case ALCHEMY_CPU_AU1200:
0124 alchemy_sleep_au1550();
0125 break;
0126 case ALCHEMY_CPU_AU1300:
0127 alchemy_sleep_au1300();
0128 break;
0129 }
0130
0131 restore_core_regs();
0132 }