1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Static Memory Controller 4 */ 5 6 #include <linux/module.h> 7 #include <linux/kernel.h> 8 #include <linux/init.h> 9 #include <linux/io.h> 10 #include <linux/syscore_ops.h> 11 12 #include <mach/hardware.h> 13 #include <mach/smemc.h> 14 15 #ifdef CONFIG_PM 16 static unsigned long msc[2]; 17 static unsigned long sxcnfg, memclkcfg; 18 static unsigned long csadrcfg[4]; 19 20 static int pxa3xx_smemc_suspend(void) 21 { 22 msc[0] = __raw_readl(MSC0); 23 msc[1] = __raw_readl(MSC1); 24 sxcnfg = __raw_readl(SXCNFG); 25 memclkcfg = __raw_readl(MEMCLKCFG); 26 csadrcfg[0] = __raw_readl(CSADRCFG0); 27 csadrcfg[1] = __raw_readl(CSADRCFG1); 28 csadrcfg[2] = __raw_readl(CSADRCFG2); 29 csadrcfg[3] = __raw_readl(CSADRCFG3); 30 31 return 0; 32 } 33 34 static void pxa3xx_smemc_resume(void) 35 { 36 __raw_writel(msc[0], MSC0); 37 __raw_writel(msc[1], MSC1); 38 __raw_writel(sxcnfg, SXCNFG); 39 __raw_writel(memclkcfg, MEMCLKCFG); 40 __raw_writel(csadrcfg[0], CSADRCFG0); 41 __raw_writel(csadrcfg[1], CSADRCFG1); 42 __raw_writel(csadrcfg[2], CSADRCFG2); 43 __raw_writel(csadrcfg[3], CSADRCFG3); 44 /* CSMSADRCFG wakes up in its default state (0), so we need to set it */ 45 __raw_writel(0x2, CSMSADRCFG); 46 } 47 48 static struct syscore_ops smemc_syscore_ops = { 49 .suspend = pxa3xx_smemc_suspend, 50 .resume = pxa3xx_smemc_resume, 51 }; 52 53 static int __init smemc_init(void) 54 { 55 if (cpu_is_pxa3xx()) { 56 /* 57 * The only documentation we have on the 58 * Chip Select Configuration Register (CSMSADRCFG) is that 59 * it must be programmed to 0x2. 60 * Moreover, in the bit definitions, the second bit 61 * (CSMSADRCFG[1]) is called "SETALWAYS". 62 * Other bits are reserved in this register. 63 */ 64 __raw_writel(0x2, CSMSADRCFG); 65 66 register_syscore_ops(&smemc_syscore_ops); 67 } 68 69 return 0; 70 } 71 subsys_initcall(smemc_init); 72 #endif 73