eric miao | b1d907f | 2008-01-28 23:00:02 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Static Memory Controller |
| 3 | */ |
| 4 | |
| 5 | #include <linux/module.h> |
| 6 | #include <linux/kernel.h> |
| 7 | #include <linux/init.h> |
| 8 | #include <linux/io.h> |
| 9 | #include <linux/sysdev.h> |
| 10 | |
Russell King | 05678a9 | 2008-11-28 16:04:54 +0000 | [diff] [blame^] | 11 | #include <mach/hardware.h> |
| 12 | |
eric miao | b1d907f | 2008-01-28 23:00:02 +0000 | [diff] [blame] | 13 | #define SMEMC_PHYS_BASE (0x4A000000) |
| 14 | #define SMEMC_PHYS_SIZE (0x90) |
| 15 | |
| 16 | #define MSC0 (0x08) /* Static Memory Controller Register 0 */ |
| 17 | #define MSC1 (0x0C) /* Static Memory Controller Register 1 */ |
| 18 | #define SXCNFG (0x1C) /* Synchronous Static Memory Control Register */ |
| 19 | #define MEMCLKCFG (0x68) /* Clock Configuration */ |
| 20 | #define CSADRCFG0 (0x80) /* Address Configuration Register for CS0 */ |
| 21 | #define CSADRCFG1 (0x84) /* Address Configuration Register for CS1 */ |
| 22 | #define CSADRCFG2 (0x88) /* Address Configuration Register for CS2 */ |
| 23 | #define CSADRCFG3 (0x8C) /* Address Configuration Register for CS3 */ |
| 24 | |
| 25 | #ifdef CONFIG_PM |
| 26 | static void __iomem *smemc_mmio_base; |
| 27 | |
| 28 | static unsigned long msc[2]; |
| 29 | static unsigned long sxcnfg, memclkcfg; |
| 30 | static unsigned long csadrcfg[4]; |
| 31 | |
| 32 | static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state) |
| 33 | { |
| 34 | msc[0] = __raw_readl(smemc_mmio_base + MSC0); |
| 35 | msc[1] = __raw_readl(smemc_mmio_base + MSC1); |
| 36 | sxcnfg = __raw_readl(smemc_mmio_base + SXCNFG); |
| 37 | memclkcfg = __raw_readl(smemc_mmio_base + MEMCLKCFG); |
| 38 | csadrcfg[0] = __raw_readl(smemc_mmio_base + CSADRCFG0); |
| 39 | csadrcfg[1] = __raw_readl(smemc_mmio_base + CSADRCFG1); |
| 40 | csadrcfg[2] = __raw_readl(smemc_mmio_base + CSADRCFG2); |
| 41 | csadrcfg[3] = __raw_readl(smemc_mmio_base + CSADRCFG3); |
| 42 | |
| 43 | return 0; |
| 44 | } |
| 45 | |
| 46 | static int pxa3xx_smemc_resume(struct sys_device *dev) |
| 47 | { |
| 48 | __raw_writel(msc[0], smemc_mmio_base + MSC0); |
| 49 | __raw_writel(msc[1], smemc_mmio_base + MSC1); |
| 50 | __raw_writel(sxcnfg, smemc_mmio_base + SXCNFG); |
| 51 | __raw_writel(memclkcfg, smemc_mmio_base + MEMCLKCFG); |
| 52 | __raw_writel(csadrcfg[0], smemc_mmio_base + CSADRCFG0); |
| 53 | __raw_writel(csadrcfg[1], smemc_mmio_base + CSADRCFG1); |
| 54 | __raw_writel(csadrcfg[2], smemc_mmio_base + CSADRCFG2); |
| 55 | __raw_writel(csadrcfg[3], smemc_mmio_base + CSADRCFG3); |
| 56 | |
| 57 | return 0; |
| 58 | } |
| 59 | |
| 60 | static struct sysdev_class smemc_sysclass = { |
| 61 | .name = "smemc", |
| 62 | .suspend = pxa3xx_smemc_suspend, |
| 63 | .resume = pxa3xx_smemc_resume, |
| 64 | }; |
| 65 | |
| 66 | static struct sys_device smemc_sysdev = { |
| 67 | .id = 0, |
| 68 | .cls = &smemc_sysclass, |
| 69 | }; |
| 70 | |
| 71 | static int __init smemc_init(void) |
| 72 | { |
| 73 | int ret = 0; |
| 74 | |
| 75 | if (cpu_is_pxa3xx()) { |
| 76 | smemc_mmio_base = ioremap(SMEMC_PHYS_BASE, SMEMC_PHYS_SIZE); |
| 77 | if (smemc_mmio_base == NULL) |
| 78 | return -ENODEV; |
| 79 | |
| 80 | ret = sysdev_class_register(&smemc_sysclass); |
| 81 | if (ret) |
| 82 | return ret; |
| 83 | |
| 84 | ret = sysdev_register(&smemc_sysdev); |
| 85 | } |
| 86 | |
| 87 | return ret; |
| 88 | } |
| 89 | subsys_initcall(smemc_init); |
| 90 | #endif |