aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-01-15 08:24:02 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-01-15 08:24:02 -0500
commitbbba75606963c82febf7bd2761ea848ac5d1a1bb (patch)
tree50880b4539c578c407f6c1aa605fddf5e371bb7e
parent073154459b80a43f7e4f088b11c93c8e9cb07f14 (diff)
parentccbc87693dcb428443a72d644e63484676517c2d (diff)
Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into devel-stable
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c22
-rw-r--r--arch/arm/mach-s3c2410/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-s3c2410/include/mach/map.h4
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h1
-rw-r--r--arch/arm/mach-s3c2412/irq.c50
-rw-r--r--arch/arm/mach-s3c2416/Kconfig12
-rw-r--r--arch/arm/mach-s3c2416/Makefile4
-rw-r--r--arch/arm/mach-s3c2416/clock.c18
-rw-r--r--arch/arm/mach-s3c2416/irq.c76
-rw-r--r--arch/arm/mach-s3c2416/mach-smdk2416.c23
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c5
-rw-r--r--arch/arm/mach-s3c2416/setup-sdhci-gpio.c34
-rw-r--r--arch/arm/mach-s3c2416/setup-sdhci.c61
-rw-r--r--arch/arm/mach-s3c2440/irq.c18
-rw-r--r--arch/arm/mach-s3c2440/s3c244x-irq.c18
-rw-r--r--arch/arm/mach-s3c2443/Kconfig3
-rw-r--r--arch/arm/mach-s3c2443/clock.c4
-rw-r--r--arch/arm/mach-s3c2443/irq.c95
-rw-r--r--arch/arm/mach-s3c2443/mach-smdk2443.c9
-rw-r--r--arch/arm/mach-s3c2443/s3c2443.c7
-rw-r--r--arch/arm/mach-s3c64xx/clock.c21
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c60
-rw-r--r--arch/arm/mach-s3c64xx/dma.c1
-rw-r--r--arch/arm/mach-s3c64xx/irq-eint.c37
-rw-r--r--arch/arm/mach-s5p6442/clock.c16
-rw-r--r--arch/arm/mach-s5p6442/dev-audio.c44
-rw-r--r--arch/arm/mach-s5p6442/include/mach/map.h3
-rw-r--r--arch/arm/mach-s5p6442/mach-smdk6442.c10
-rw-r--r--arch/arm/mach-s5p6442/setup-i2c0.c5
-rw-r--r--arch/arm/mach-s5p64x0/Makefile4
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c24
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c36
-rw-r--r--arch/arm/mach-s5p64x0/dev-audio.c144
-rw-r--r--arch/arm/mach-s5p64x0/gpiolib.c (renamed from arch/arm/mach-s5p64x0/gpio.c)221
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/map.h5
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-gpio.h57
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c1
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c1
-rw-r--r--arch/arm/mach-s5pc100/clock.c16
-rw-r--r--arch/arm/mach-s5pc100/dev-audio.c54
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h2
-rw-r--r--arch/arm/mach-s5pv210/Kconfig2
-rw-r--r--arch/arm/mach-s5pv210/clock.c35
-rw-r--r--arch/arm/mach-s5pv210/cpu.c5
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c56
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h3
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h6
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h5
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c1
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c139
-rw-r--r--arch/arm/mach-s5pv310/Kconfig22
-rw-r--r--arch/arm/mach-s5pv310/Makefile7
-rw-r--r--arch/arm/mach-s5pv310/clock.c77
-rw-r--r--arch/arm/mach-s5pv310/cpu.c21
-rw-r--r--arch/arm/mach-s5pv310/cpufreq.c580
-rw-r--r--arch/arm/mach-s5pv310/dev-audio.c364
-rw-r--r--arch/arm/mach-s5pv310/dev-pd.c139
-rw-r--r--arch/arm/mach-s5pv310/dev-sysmmu.c187
-rw-r--r--arch/arm/mach-s5pv310/dma.c168
-rw-r--r--arch/arm/mach-s5pv310/include/mach/dma.h26
-rw-r--r--arch/arm/mach-s5pv310/include/mach/irqs.h37
-rw-r--r--arch/arm/mach-s5pv310/include/mach/map.h50
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-clock.h80
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-mem.h23
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-pmu.h30
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-srom.h50
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h24
-rw-r--r--arch/arm/mach-s5pv310/include/mach/sysmmu.h119
-rw-r--r--arch/arm/mach-s5pv310/irq-combiner.c32
-rw-r--r--arch/arm/mach-s5pv310/irq-eint.c55
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkc210.c52
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkv310.c52
-rw-r--r--arch/arm/mach-s5pv310/mach-universal_c210.c80
-rw-r--r--arch/arm/plat-s3c24xx/devs.c1
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/irq.h4
-rw-r--r--arch/arm/plat-s3c24xx/irq-pm.c9
-rw-r--r--arch/arm/plat-s3c24xx/irq.c182
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c2
-rw-r--r--arch/arm/plat-s5p/Kconfig26
-rw-r--r--arch/arm/plat-s5p/Makefile3
-rw-r--r--arch/arm/plat-s5p/cpu.c5
-rw-r--r--arch/arm/plat-s5p/dev-csis0.c34
-rw-r--r--arch/arm/plat-s5p/dev-csis1.c34
-rw-r--r--arch/arm/plat-s5p/include/plat/csis.h28
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h1
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-srom.h54
-rw-r--r--arch/arm/plat-s5p/include/plat/sysmmu.h23
-rw-r--r--arch/arm/plat-s5p/irq-eint.c86
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c50
-rw-r--r--arch/arm/plat-s5p/irq-pm.c6
-rw-r--r--arch/arm/plat-s5p/sysmmu.c328
-rw-r--r--arch/arm/plat-samsung/Kconfig14
-rw-r--r--arch/arm/plat-samsung/Makefile4
-rw-r--r--arch/arm/plat-samsung/clock.c92
-rw-r--r--arch/arm/plat-samsung/dev-nand.c2
-rw-r--r--arch/arm/plat-samsung/gpio-config.c42
-rw-r--r--arch/arm/plat-samsung/gpiolib.c7
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h24
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h17
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/pd.h30
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h35
-rw-r--r--arch/arm/plat-samsung/irq-uart.c40
-rw-r--r--arch/arm/plat-samsung/irq-vic-timer.c26
-rw-r--r--arch/arm/plat-samsung/pd.c95
-rw-r--r--arch/arm/plat-samsung/pm.c6
-rw-r--r--drivers/serial/samsung.c4
111 files changed, 4277 insertions, 806 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5711c8160e75..2aef8a5a3661 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -766,6 +766,7 @@ config ARCH_S5PV310
766 select ARCH_SPARSEMEM_ENABLE 766 select ARCH_SPARSEMEM_ENABLE
767 select GENERIC_GPIO 767 select GENERIC_GPIO
768 select HAVE_CLK 768 select HAVE_CLK
769 select ARCH_HAS_CPUFREQ
769 select GENERIC_CLOCKEVENTS 770 select GENERIC_CLOCKEVENTS
770 select HAVE_S3C_RTC if RTC_CLASS 771 select HAVE_S3C_RTC if RTC_CLASS
771 select HAVE_S3C2410_I2C if I2C 772 select HAVE_S3C2410_I2C if I2C
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 217b102866d0..606cb6b1cc47 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -75,38 +75,38 @@ static unsigned char bast_pc104_irqmasks[] = {
75static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 }; 75static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
76 76
77static void 77static void
78bast_pc104_mask(unsigned int irqno) 78bast_pc104_mask(struct irq_data *data)
79{ 79{
80 unsigned long temp; 80 unsigned long temp;
81 81
82 temp = __raw_readb(BAST_VA_PC104_IRQMASK); 82 temp = __raw_readb(BAST_VA_PC104_IRQMASK);
83 temp &= ~bast_pc104_irqmasks[irqno]; 83 temp &= ~bast_pc104_irqmasks[data->irq];
84 __raw_writeb(temp, BAST_VA_PC104_IRQMASK); 84 __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
85} 85}
86 86
87static void 87static void
88bast_pc104_maskack(unsigned int irqno) 88bast_pc104_maskack(struct irq_data *data)
89{ 89{
90 struct irq_desc *desc = irq_desc + IRQ_ISA; 90 struct irq_desc *desc = irq_desc + IRQ_ISA;
91 91
92 bast_pc104_mask(irqno); 92 bast_pc104_mask(data);
93 desc->chip->ack(IRQ_ISA); 93 desc->irq_data.chip->irq_ack(&desc->irq_data);
94} 94}
95 95
96static void 96static void
97bast_pc104_unmask(unsigned int irqno) 97bast_pc104_unmask(struct irq_data *data)
98{ 98{
99 unsigned long temp; 99 unsigned long temp;
100 100
101 temp = __raw_readb(BAST_VA_PC104_IRQMASK); 101 temp = __raw_readb(BAST_VA_PC104_IRQMASK);
102 temp |= bast_pc104_irqmasks[irqno]; 102 temp |= bast_pc104_irqmasks[data->irq];
103 __raw_writeb(temp, BAST_VA_PC104_IRQMASK); 103 __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
104} 104}
105 105
106static struct irq_chip bast_pc104_chip = { 106static struct irq_chip bast_pc104_chip = {
107 .mask = bast_pc104_mask, 107 .irq_mask = bast_pc104_mask,
108 .unmask = bast_pc104_unmask, 108 .irq_unmask = bast_pc104_unmask,
109 .ack = bast_pc104_maskack 109 .irq_ack = bast_pc104_maskack
110}; 110};
111 111
112static void 112static void
@@ -123,7 +123,7 @@ bast_irq_pc104_demux(unsigned int irq,
123 /* ack if we get an irq with nothing (ie, startup) */ 123 /* ack if we get an irq with nothing (ie, startup) */
124 124
125 desc = irq_desc + IRQ_ISA; 125 desc = irq_desc + IRQ_ISA;
126 desc->chip->ack(IRQ_ISA); 126 desc->irq_data.chip->irq_ack(&desc->irq_data);
127 } else { 127 } else {
128 /* handle the IRQ */ 128 /* handle the IRQ */
129 129
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
index 11bb0f08fe6a..e5a68ea13113 100644
--- a/arch/arm/mach-s3c2410/include/mach/irqs.h
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -152,8 +152,8 @@
152 152
153#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */ 153#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */
154 154
155#define IRQ_HSMMC0 IRQ_S3C2443_HSMMC 155#define IRQ_HSMMC0 IRQ_S3C2416_HSMMC0
156#define IRQ_HSMMC1 IRQ_S3C2416_HSMMC0 156#define IRQ_HSMMC1 IRQ_S3C2443_HSMMC
157 157
158#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14) 158#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14)
159#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15) 159#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15)
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index cd3983ad4160..25bbf5a942dd 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -112,8 +112,8 @@
112#define S3C_PA_IIC S3C2410_PA_IIC 112#define S3C_PA_IIC S3C2410_PA_IIC
113#define S3C_PA_UART S3C24XX_PA_UART 113#define S3C_PA_UART S3C24XX_PA_UART
114#define S3C_PA_USBHOST S3C2410_PA_USBHOST 114#define S3C_PA_USBHOST S3C2410_PA_USBHOST
115#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC 115#define S3C_PA_HSMMC0 S3C2416_PA_HSMMC0
116#define S3C_PA_HSMMC1 S3C2416_PA_HSMMC0 116#define S3C_PA_HSMMC1 S3C2443_PA_HSMMC
117#define S3C_PA_WDT S3C2410_PA_WATCHDOG 117#define S3C_PA_WDT S3C2410_PA_WATCHDOG
118#define S3C_PA_NAND S3C24XX_PA_NAND 118#define S3C_PA_NAND S3C24XX_PA_NAND
119 119
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
index 101aeea22310..44494a56e68b 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
@@ -86,6 +86,7 @@
86#define S3C2443_HCLKCON_LCDC (1<<9) 86#define S3C2443_HCLKCON_LCDC (1<<9)
87#define S3C2443_HCLKCON_USBH (1<<11) 87#define S3C2443_HCLKCON_USBH (1<<11)
88#define S3C2443_HCLKCON_USBD (1<<12) 88#define S3C2443_HCLKCON_USBD (1<<12)
89#define S3C2416_HCLKCON_HSMMC0 (1<<15)
89#define S3C2443_HCLKCON_HSMMC (1<<16) 90#define S3C2443_HCLKCON_HSMMC (1<<16)
90#define S3C2443_HCLKCON_CFC (1<<17) 91#define S3C2443_HCLKCON_CFC (1<<17)
91#define S3C2443_HCLKCON_SSMC (1<<18) 92#define S3C2443_HCLKCON_SSMC (1<<18)
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index 6000ca9d1815..eddb52ba5b65 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -49,9 +49,9 @@
49*/ 49*/
50 50
51static void 51static void
52s3c2412_irq_mask(unsigned int irqno) 52s3c2412_irq_mask(struct irq_data *data)
53{ 53{
54 unsigned long bitval = 1UL << (irqno - IRQ_EINT0); 54 unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
55 unsigned long mask; 55 unsigned long mask;
56 56
57 mask = __raw_readl(S3C2410_INTMSK); 57 mask = __raw_readl(S3C2410_INTMSK);
@@ -62,9 +62,9 @@ s3c2412_irq_mask(unsigned int irqno)
62} 62}
63 63
64static inline void 64static inline void
65s3c2412_irq_ack(unsigned int irqno) 65s3c2412_irq_ack(struct irq_data *data)
66{ 66{
67 unsigned long bitval = 1UL << (irqno - IRQ_EINT0); 67 unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
68 68
69 __raw_writel(bitval, S3C2412_EINTPEND); 69 __raw_writel(bitval, S3C2412_EINTPEND);
70 __raw_writel(bitval, S3C2410_SRCPND); 70 __raw_writel(bitval, S3C2410_SRCPND);
@@ -72,9 +72,9 @@ s3c2412_irq_ack(unsigned int irqno)
72} 72}
73 73
74static inline void 74static inline void
75s3c2412_irq_maskack(unsigned int irqno) 75s3c2412_irq_maskack(struct irq_data *data)
76{ 76{
77 unsigned long bitval = 1UL << (irqno - IRQ_EINT0); 77 unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
78 unsigned long mask; 78 unsigned long mask;
79 79
80 mask = __raw_readl(S3C2410_INTMSK); 80 mask = __raw_readl(S3C2410_INTMSK);
@@ -89,9 +89,9 @@ s3c2412_irq_maskack(unsigned int irqno)
89} 89}
90 90
91static void 91static void
92s3c2412_irq_unmask(unsigned int irqno) 92s3c2412_irq_unmask(struct irq_data *data)
93{ 93{
94 unsigned long bitval = 1UL << (irqno - IRQ_EINT0); 94 unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
95 unsigned long mask; 95 unsigned long mask;
96 96
97 mask = __raw_readl(S3C2412_EINTMASK); 97 mask = __raw_readl(S3C2412_EINTMASK);
@@ -102,11 +102,11 @@ s3c2412_irq_unmask(unsigned int irqno)
102} 102}
103 103
104static struct irq_chip s3c2412_irq_eint0t4 = { 104static struct irq_chip s3c2412_irq_eint0t4 = {
105 .ack = s3c2412_irq_ack, 105 .irq_ack = s3c2412_irq_ack,
106 .mask = s3c2412_irq_mask, 106 .irq_mask = s3c2412_irq_mask,
107 .unmask = s3c2412_irq_unmask, 107 .irq_unmask = s3c2412_irq_unmask,
108 .set_wake = s3c_irq_wake, 108 .irq_set_wake = s3c_irq_wake,
109 .set_type = s3c_irqext_type, 109 .irq_set_type = s3c_irqext_type,
110}; 110};
111 111
112#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0))) 112#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0)))
@@ -132,29 +132,29 @@ static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
132#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0)) 132#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
133#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF) 133#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
134 134
135static void s3c2412_irq_cfsdi_mask(unsigned int irqno) 135static void s3c2412_irq_cfsdi_mask(struct irq_data *data)
136{ 136{
137 s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI); 137 s3c_irqsub_mask(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
138} 138}
139 139
140static void s3c2412_irq_cfsdi_unmask(unsigned int irqno) 140static void s3c2412_irq_cfsdi_unmask(struct irq_data *data)
141{ 141{
142 s3c_irqsub_unmask(irqno, INTMSK_CFSDI); 142 s3c_irqsub_unmask(data->irq, INTMSK_CFSDI);
143} 143}
144 144
145static void s3c2412_irq_cfsdi_ack(unsigned int irqno) 145static void s3c2412_irq_cfsdi_ack(struct irq_data *data)
146{ 146{
147 s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI); 147 s3c_irqsub_maskack(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
148} 148}
149 149
150static struct irq_chip s3c2412_irq_cfsdi = { 150static struct irq_chip s3c2412_irq_cfsdi = {
151 .name = "s3c2412-cfsdi", 151 .name = "s3c2412-cfsdi",
152 .ack = s3c2412_irq_cfsdi_ack, 152 .irq_ack = s3c2412_irq_cfsdi_ack,
153 .mask = s3c2412_irq_cfsdi_mask, 153 .irq_mask = s3c2412_irq_cfsdi_mask,
154 .unmask = s3c2412_irq_cfsdi_unmask, 154 .irq_unmask = s3c2412_irq_cfsdi_unmask,
155}; 155};
156 156
157static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state) 157static int s3c2412_irq_rtc_wake(struct irq_data *data, unsigned int state)
158{ 158{
159 unsigned long pwrcfg; 159 unsigned long pwrcfg;
160 160
@@ -165,7 +165,7 @@ static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
165 pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ; 165 pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
166 __raw_writel(pwrcfg, S3C2412_PWRCFG); 166 __raw_writel(pwrcfg, S3C2412_PWRCFG);
167 167
168 return s3c_irq_chip.set_wake(irqno, state); 168 return s3c_irq_chip.irq_set_wake(data, state);
169} 169}
170 170
171static struct irq_chip s3c2412_irq_rtc_chip; 171static struct irq_chip s3c2412_irq_rtc_chip;
@@ -193,7 +193,7 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
193 /* change RTC IRQ's set wake method */ 193 /* change RTC IRQ's set wake method */
194 194
195 s3c2412_irq_rtc_chip = s3c_irq_chip; 195 s3c2412_irq_rtc_chip = s3c_irq_chip;
196 s3c2412_irq_rtc_chip.set_wake = s3c2412_irq_rtc_wake; 196 s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake;
197 197
198 set_irq_chip(IRQ_RTC, &s3c2412_irq_rtc_chip); 198 set_irq_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
199 199
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
index df8d14974c90..69b48a7d1dbd 100644
--- a/arch/arm/mach-s3c2416/Kconfig
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -31,6 +31,17 @@ config S3C2416_PM
31 help 31 help
32 Internal config node to apply S3C2416 power management 32 Internal config node to apply S3C2416 power management
33 33
34config S3C2416_SETUP_SDHCI
35 bool
36 select S3C2416_SETUP_SDHCI_GPIO
37 help
38 Internal helper functions for S3C2416 based SDHCI systems
39
40config S3C2416_SETUP_SDHCI_GPIO
41 bool
42 help
43 Common setup code for SDHCI gpio.
44
34menu "S3C2416 Machines" 45menu "S3C2416 Machines"
35 46
36config MACH_SMDK2416 47config MACH_SMDK2416
@@ -42,6 +53,7 @@ config MACH_SMDK2416
42 select S3C_DEV_HSMMC1 53 select S3C_DEV_HSMMC1
43 select S3C_DEV_NAND 54 select S3C_DEV_NAND
44 select S3C_DEV_USB_HOST 55 select S3C_DEV_USB_HOST
56 select S3C2416_SETUP_SDHCI
45 select S3C2416_PM if PM 57 select S3C2416_PM if PM
46 help 58 help
47 Say Y here if you are using an SMDK2416 59 Say Y here if you are using an SMDK2416
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
index ef038d62ffdb..7b805b279caf 100644
--- a/arch/arm/mach-s3c2416/Makefile
+++ b/arch/arm/mach-s3c2416/Makefile
@@ -14,6 +14,10 @@ obj-$(CONFIG_CPU_S3C2416) += irq.o
14obj-$(CONFIG_S3C2416_PM) += pm.o 14obj-$(CONFIG_S3C2416_PM) += pm.o
15#obj-$(CONFIG_S3C2416_DMA) += dma.o 15#obj-$(CONFIG_S3C2416_DMA) += dma.o
16 16
17# Device setup
18obj-$(CONFIG_S3C2416_SETUP_SDHCI) += setup-sdhci.o
19obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
20
17# Machine support 21# Machine support
18 22
19obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o 23obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
index 7ccf5a2a2bfc..3b02d8506e25 100644
--- a/arch/arm/mach-s3c2416/clock.c
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -38,12 +38,11 @@ static unsigned int armdiv[8] = {
38 [7] = 8, 38 [7] = 8,
39}; 39};
40 40
41/* ID to hardware numbering, 0 is HSMMC1, 1 is HSMMC0 */
42static struct clksrc_clk hsmmc_div[] = { 41static struct clksrc_clk hsmmc_div[] = {
43 [0] = { 42 [0] = {
44 .clk = { 43 .clk = {
45 .name = "hsmmc-div", 44 .name = "hsmmc-div",
46 .id = 1, 45 .id = 0,
47 .parent = &clk_esysclk.clk, 46 .parent = &clk_esysclk.clk,
48 }, 47 },
49 .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 }, 48 .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
@@ -51,7 +50,7 @@ static struct clksrc_clk hsmmc_div[] = {
51 [1] = { 50 [1] = {
52 .clk = { 51 .clk = {
53 .name = "hsmmc-div", 52 .name = "hsmmc-div",
54 .id = 0, 53 .id = 1,
55 .parent = &clk_esysclk.clk, 54 .parent = &clk_esysclk.clk,
56 }, 55 },
57 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 }, 56 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
@@ -61,7 +60,7 @@ static struct clksrc_clk hsmmc_div[] = {
61static struct clksrc_clk hsmmc_mux[] = { 60static struct clksrc_clk hsmmc_mux[] = {
62 [0] = { 61 [0] = {
63 .clk = { 62 .clk = {
64 .id = 1, 63 .id = 0,
65 .name = "hsmmc-if", 64 .name = "hsmmc-if",
66 .ctrlbit = (1 << 6), 65 .ctrlbit = (1 << 6),
67 .enable = s3c2443_clkcon_enable_s, 66 .enable = s3c2443_clkcon_enable_s,
@@ -77,7 +76,7 @@ static struct clksrc_clk hsmmc_mux[] = {
77 }, 76 },
78 [1] = { 77 [1] = {
79 .clk = { 78 .clk = {
80 .id = 0, 79 .id = 1,
81 .name = "hsmmc-if", 80 .name = "hsmmc-if",
82 .ctrlbit = (1 << 12), 81 .ctrlbit = (1 << 12),
83 .enable = s3c2443_clkcon_enable_s, 82 .enable = s3c2443_clkcon_enable_s,
@@ -93,6 +92,13 @@ static struct clksrc_clk hsmmc_mux[] = {
93 }, 92 },
94}; 93};
95 94
95static struct clk hsmmc0_clk = {
96 .name = "hsmmc",
97 .id = 0,
98 .parent = &clk_h,
99 .enable = s3c2443_clkcon_enable_h,
100 .ctrlbit = S3C2416_HCLKCON_HSMMC0,
101};
96 102
97static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0) 103static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
98{ 104{
@@ -130,6 +136,8 @@ void __init s3c2416_init_clocks(int xtal)
130 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 136 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
131 s3c_register_clksrc(clksrcs[ptr], 1); 137 s3c_register_clksrc(clksrcs[ptr], 1);
132 138
139 s3c24xx_register_clock(&hsmmc0_clk);
140
133 s3c_pwmclk_init(); 141 s3c_pwmclk_init();
134 142
135} 143}
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
index 00174daf1526..680fe386aca5 100644
--- a/arch/arm/mach-s3c2416/irq.c
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -77,28 +77,27 @@ static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
77#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0)) 77#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
78#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97) 78#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
79 79
80static void s3c2416_irq_wdtac97_mask(unsigned int irqno) 80static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
81{ 81{
82 s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97); 82 s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
83} 83}
84 84
85static void s3c2416_irq_wdtac97_unmask(unsigned int irqno) 85static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
86{ 86{
87 s3c_irqsub_unmask(irqno, INTMSK_WDTAC97); 87 s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
88} 88}
89 89
90static void s3c2416_irq_wdtac97_ack(unsigned int irqno) 90static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
91{ 91{
92 s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97); 92 s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
93} 93}
94 94
95static struct irq_chip s3c2416_irq_wdtac97 = { 95static struct irq_chip s3c2416_irq_wdtac97 = {
96 .mask = s3c2416_irq_wdtac97_mask, 96 .irq_mask = s3c2416_irq_wdtac97_mask,
97 .unmask = s3c2416_irq_wdtac97_unmask, 97 .irq_unmask = s3c2416_irq_wdtac97_unmask,
98 .ack = s3c2416_irq_wdtac97_ack, 98 .irq_ack = s3c2416_irq_wdtac97_ack,
99}; 99};
100 100
101
102/* LCD sub interrupts */ 101/* LCD sub interrupts */
103 102
104static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc) 103static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
@@ -109,28 +108,27 @@ static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
109#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) 108#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
110#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4) 109#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
111 110
112static void s3c2416_irq_lcd_mask(unsigned int irqno) 111static void s3c2416_irq_lcd_mask(struct irq_data *data)
113{ 112{
114 s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD); 113 s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
115} 114}
116 115
117static void s3c2416_irq_lcd_unmask(unsigned int irqno) 116static void s3c2416_irq_lcd_unmask(struct irq_data *data)
118{ 117{
119 s3c_irqsub_unmask(irqno, INTMSK_LCD); 118 s3c_irqsub_unmask(data->irq, INTMSK_LCD);
120} 119}
121 120
122static void s3c2416_irq_lcd_ack(unsigned int irqno) 121static void s3c2416_irq_lcd_ack(struct irq_data *data)
123{ 122{
124 s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD); 123 s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
125} 124}
126 125
127static struct irq_chip s3c2416_irq_lcd = { 126static struct irq_chip s3c2416_irq_lcd = {
128 .mask = s3c2416_irq_lcd_mask, 127 .irq_mask = s3c2416_irq_lcd_mask,
129 .unmask = s3c2416_irq_lcd_unmask, 128 .irq_unmask = s3c2416_irq_lcd_unmask,
130 .ack = s3c2416_irq_lcd_ack, 129 .irq_ack = s3c2416_irq_lcd_ack,
131}; 130};
132 131
133
134/* DMA sub interrupts */ 132/* DMA sub interrupts */
135 133
136static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc) 134static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
@@ -142,28 +140,27 @@ static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
142#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5) 140#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
143 141
144 142
145static void s3c2416_irq_dma_mask(unsigned int irqno) 143static void s3c2416_irq_dma_mask(struct irq_data *data)
146{ 144{
147 s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA); 145 s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
148} 146}
149 147
150static void s3c2416_irq_dma_unmask(unsigned int irqno) 148static void s3c2416_irq_dma_unmask(struct irq_data *data)
151{ 149{
152 s3c_irqsub_unmask(irqno, INTMSK_DMA); 150 s3c_irqsub_unmask(data->irq, INTMSK_DMA);
153} 151}
154 152
155static void s3c2416_irq_dma_ack(unsigned int irqno) 153static void s3c2416_irq_dma_ack(struct irq_data *data)
156{ 154{
157 s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA); 155 s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
158} 156}
159 157
160static struct irq_chip s3c2416_irq_dma = { 158static struct irq_chip s3c2416_irq_dma = {
161 .mask = s3c2416_irq_dma_mask, 159 .irq_mask = s3c2416_irq_dma_mask,
162 .unmask = s3c2416_irq_dma_unmask, 160 .irq_unmask = s3c2416_irq_dma_unmask,
163 .ack = s3c2416_irq_dma_ack, 161 .irq_ack = s3c2416_irq_dma_ack,
164}; 162};
165 163
166
167/* UART3 sub interrupts */ 164/* UART3 sub interrupts */
168 165
169static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) 166static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
@@ -174,28 +171,27 @@ static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
174#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) 171#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
175#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) 172#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
176 173
177static void s3c2416_irq_uart3_mask(unsigned int irqno) 174static void s3c2416_irq_uart3_mask(struct irq_data *data)
178{ 175{
179 s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3); 176 s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
180} 177}
181 178
182static void s3c2416_irq_uart3_unmask(unsigned int irqno) 179static void s3c2416_irq_uart3_unmask(struct irq_data *data)
183{ 180{
184 s3c_irqsub_unmask(irqno, INTMSK_UART3); 181 s3c_irqsub_unmask(data->irq, INTMSK_UART3);
185} 182}
186 183
187static void s3c2416_irq_uart3_ack(unsigned int irqno) 184static void s3c2416_irq_uart3_ack(struct irq_data *data)
188{ 185{
189 s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3); 186 s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
190} 187}
191 188
192static struct irq_chip s3c2416_irq_uart3 = { 189static struct irq_chip s3c2416_irq_uart3 = {
193 .mask = s3c2416_irq_uart3_mask, 190 .irq_mask = s3c2416_irq_uart3_mask,
194 .unmask = s3c2416_irq_uart3_unmask, 191 .irq_unmask = s3c2416_irq_uart3_unmask,
195 .ack = s3c2416_irq_uart3_ack, 192 .irq_ack = s3c2416_irq_uart3_ack,
196}; 193};
197 194
198
199/* IRQ initialisation code */ 195/* IRQ initialisation code */
200 196
201static int __init s3c2416_add_sub(unsigned int base, 197static int __init s3c2416_add_sub(unsigned int base,
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
index 7fc366476d7e..3f83177246c7 100644
--- a/arch/arm/mach-s3c2416/mach-smdk2416.c
+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
@@ -46,6 +46,7 @@
46#include <plat/devs.h> 46#include <plat/devs.h>
47#include <plat/cpu.h> 47#include <plat/cpu.h>
48#include <plat/nand.h> 48#include <plat/nand.h>
49#include <plat/sdhci.h>
49 50
50#include <plat/regs-fb-v4.h> 51#include <plat/regs-fb-v4.h>
51#include <plat/fb.h> 52#include <plat/fb.h>
@@ -110,6 +111,13 @@ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
110 .ucon = UCON, 111 .ucon = UCON,
111 .ulcon = ULCON | 0x50, 112 .ulcon = ULCON | 0x50,
112 .ufcon = UFCON, 113 .ufcon = UFCON,
114 },
115 [3] = {
116 .hwport = 3,
117 .flags = 0,
118 .ucon = UCON,
119 .ulcon = ULCON,
120 .ufcon = UFCON,
113 } 121 }
114}; 122};
115 123
@@ -159,6 +167,18 @@ static struct s3c_fb_platdata smdk2416_fb_platdata = {
159 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 167 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
160}; 168};
161 169
170static struct s3c_sdhci_platdata smdk2416_hsmmc0_pdata __initdata = {
171 .max_width = 4,
172 .cd_type = S3C_SDHCI_CD_GPIO,
173 .ext_cd_gpio = S3C2410_GPF(1),
174 .ext_cd_gpio_invert = 1,
175};
176
177static struct s3c_sdhci_platdata smdk2416_hsmmc1_pdata __initdata = {
178 .max_width = 4,
179 .cd_type = S3C_SDHCI_CD_NONE,
180};
181
162static struct platform_device *smdk2416_devices[] __initdata = { 182static struct platform_device *smdk2416_devices[] __initdata = {
163 &s3c_device_fb, 183 &s3c_device_fb,
164 &s3c_device_wdt, 184 &s3c_device_wdt,
@@ -180,6 +200,9 @@ static void __init smdk2416_machine_init(void)
180 s3c_i2c0_set_platdata(NULL); 200 s3c_i2c0_set_platdata(NULL);
181 s3c_fb_set_platdata(&smdk2416_fb_platdata); 201 s3c_fb_set_platdata(&smdk2416_fb_platdata);
182 202
203 s3c_sdhci0_set_platdata(&smdk2416_hsmmc0_pdata);
204 s3c_sdhci1_set_platdata(&smdk2416_hsmmc1_pdata);
205
183 gpio_request(S3C2410_GPB(4), "USBHost Power"); 206 gpio_request(S3C2410_GPB(4), "USBHost Power");
184 gpio_direction_output(S3C2410_GPB(4), 1); 207 gpio_direction_output(S3C2410_GPB(4), 1);
185 208
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
index 63f39cdc0972..ba7fd8737434 100644
--- a/arch/arm/mach-s3c2416/s3c2416.c
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -53,6 +53,7 @@
53#include <plat/s3c2416.h> 53#include <plat/s3c2416.h>
54#include <plat/devs.h> 54#include <plat/devs.h>
55#include <plat/cpu.h> 55#include <plat/cpu.h>
56#include <plat/sdhci.h>
56 57
57#include <plat/iic-core.h> 58#include <plat/iic-core.h>
58#include <plat/fb-core.h> 59#include <plat/fb-core.h>
@@ -115,6 +116,10 @@ void __init s3c2416_map_io(void)
115 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown; 116 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown;
116 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown; 117 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown;
117 118
119 /* initialize device information early */
120 s3c2416_default_sdhci0();
121 s3c2416_default_sdhci1();
122
118 iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc)); 123 iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
119} 124}
120 125
diff --git a/arch/arm/mach-s3c2416/setup-sdhci-gpio.c b/arch/arm/mach-s3c2416/setup-sdhci-gpio.c
new file mode 100644
index 000000000000..f65cb3ef16ce
--- /dev/null
+++ b/arch/arm/mach-s3c2416/setup-sdhci-gpio.c
@@ -0,0 +1,34 @@
1/* linux/arch/arm/plat-s3c2416/setup-sdhci-gpio.c
2 *
3 * Copyright 2010 Promwad Innovation Company
4 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
5 *
6 * S3C2416 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
7 *
8 * Based on mach-s3c64xx/setup-sdhci-gpio.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/io.h>
20#include <linux/gpio.h>
21
22#include <mach/regs-gpio.h>
23#include <plat/gpio-cfg.h>
24
25void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
26{
27 s3c_gpio_cfgrange_nopull(S3C2410_GPE(5), 2 + width, S3C_GPIO_SFN(2));
28}
29
30void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
31{
32 s3c_gpio_cfgrange_nopull(S3C2410_GPL(0), width, S3C_GPIO_SFN(2));
33 s3c_gpio_cfgrange_nopull(S3C2410_GPL(8), 2, S3C_GPIO_SFN(2));
34}
diff --git a/arch/arm/mach-s3c2416/setup-sdhci.c b/arch/arm/mach-s3c2416/setup-sdhci.c
new file mode 100644
index 000000000000..ed34fad8f2c6
--- /dev/null
+++ b/arch/arm/mach-s3c2416/setup-sdhci.c
@@ -0,0 +1,61 @@
1/* linux/arch/arm/mach-s3c2416/setup-sdhci.c
2 *
3 * Copyright 2010 Promwad Innovation Company
4 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
5 *
6 * S3C2416 - Helper functions for settign up SDHCI device(s) (HSMMC)
7 *
8 * Based on mach-s3c64xx/setup-sdhci.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/io.h>
20
21#include <linux/mmc/card.h>
22#include <linux/mmc/host.h>
23
24#include <plat/regs-sdhci.h>
25#include <plat/sdhci.h>
26
27/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
28
29char *s3c2416_hsmmc_clksrcs[4] = {
30 [0] = "hsmmc",
31 [1] = "hsmmc",
32 [2] = "hsmmc-if",
33 /* [3] = "48m", - note not successfully used yet */
34};
35
36void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
37 void __iomem *r,
38 struct mmc_ios *ios,
39 struct mmc_card *card)
40{
41 u32 ctrl2, ctrl3;
42
43 ctrl2 = __raw_readl(r + S3C_SDHCI_CONTROL2);
44 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
45 ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
46 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
47 S3C_SDHCI_CTRL2_ENFBCLKRX |
48 S3C_SDHCI_CTRL2_DFCNT_NONE |
49 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
50
51 if (ios->clock < 25 * 1000000)
52 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
53 S3C_SDHCI_CTRL3_FCSEL2 |
54 S3C_SDHCI_CTRL3_FCSEL1 |
55 S3C_SDHCI_CTRL3_FCSEL0);
56 else
57 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
58
59 __raw_writel(ctrl2, r + S3C_SDHCI_CONTROL2);
60 __raw_writel(ctrl3, r + S3C_SDHCI_CONTROL3);
61}
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index 0c049b95c378..acad4428bef0 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -69,27 +69,27 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
69#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0)) 69#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0))
70 70
71static void 71static void
72s3c_irq_wdtac97_mask(unsigned int irqno) 72s3c_irq_wdtac97_mask(struct irq_data *data)
73{ 73{
74 s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13); 74 s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13);
75} 75}
76 76
77static void 77static void
78s3c_irq_wdtac97_unmask(unsigned int irqno) 78s3c_irq_wdtac97_unmask(struct irq_data *data)
79{ 79{
80 s3c_irqsub_unmask(irqno, INTMSK_WDT); 80 s3c_irqsub_unmask(data->irq, INTMSK_WDT);
81} 81}
82 82
83static void 83static void
84s3c_irq_wdtac97_ack(unsigned int irqno) 84s3c_irq_wdtac97_ack(struct irq_data *data)
85{ 85{
86 s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13); 86 s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13);
87} 87}
88 88
89static struct irq_chip s3c_irq_wdtac97 = { 89static struct irq_chip s3c_irq_wdtac97 = {
90 .mask = s3c_irq_wdtac97_mask, 90 .irq_mask = s3c_irq_wdtac97_mask,
91 .unmask = s3c_irq_wdtac97_unmask, 91 .irq_unmask = s3c_irq_wdtac97_unmask,
92 .ack = s3c_irq_wdtac97_ack, 92 .irq_ack = s3c_irq_wdtac97_ack,
93}; 93};
94 94
95static int s3c2440_irq_add(struct sys_device *sysdev) 95static int s3c2440_irq_add(struct sys_device *sysdev)
diff --git a/arch/arm/mach-s3c2440/s3c244x-irq.c b/arch/arm/mach-s3c2440/s3c244x-irq.c
index a75c0c2431ea..83daf4ece764 100644
--- a/arch/arm/mach-s3c2440/s3c244x-irq.c
+++ b/arch/arm/mach-s3c2440/s3c244x-irq.c
@@ -68,27 +68,27 @@ static void s3c_irq_demux_cam(unsigned int irq,
68#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) 68#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
69 69
70static void 70static void
71s3c_irq_cam_mask(unsigned int irqno) 71s3c_irq_cam_mask(struct irq_data *data)
72{ 72{
73 s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11); 73 s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11);
74} 74}
75 75
76static void 76static void
77s3c_irq_cam_unmask(unsigned int irqno) 77s3c_irq_cam_unmask(struct irq_data *data)
78{ 78{
79 s3c_irqsub_unmask(irqno, INTMSK_CAM); 79 s3c_irqsub_unmask(data->irq, INTMSK_CAM);
80} 80}
81 81
82static void 82static void
83s3c_irq_cam_ack(unsigned int irqno) 83s3c_irq_cam_ack(struct irq_data *data)
84{ 84{
85 s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11); 85 s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11);
86} 86}
87 87
88static struct irq_chip s3c_irq_cam = { 88static struct irq_chip s3c_irq_cam = {
89 .mask = s3c_irq_cam_mask, 89 .irq_mask = s3c_irq_cam_mask,
90 .unmask = s3c_irq_cam_unmask, 90 .irq_unmask = s3c_irq_cam_unmask,
91 .ack = s3c_irq_cam_ack, 91 .irq_ack = s3c_irq_cam_ack,
92}; 92};
93 93
94static int s3c244x_irq_add(struct sys_device *sysdev) 94static int s3c244x_irq_add(struct sys_device *sysdev)
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
index 31babec90cec..d8eb86823df7 100644
--- a/arch/arm/mach-s3c2443/Kconfig
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -10,6 +10,7 @@ config CPU_S3C2443
10 select CPU_LLSERIAL_S3C2440 10 select CPU_LLSERIAL_S3C2440
11 select SAMSUNG_CLKSRC 11 select SAMSUNG_CLKSRC
12 select S3C2443_CLOCK 12 select S3C2443_CLOCK
13 select S3C_GPIO_PULL_S3C2443
13 help 14 help
14 Support for the S3C2443 SoC from the S3C24XX line 15 Support for the S3C2443 SoC from the S3C24XX line
15 16
@@ -25,7 +26,7 @@ config MACH_SMDK2443
25 bool "SMDK2443" 26 bool "SMDK2443"
26 select CPU_S3C2443 27 select CPU_S3C2443
27 select MACH_SMDK 28 select MACH_SMDK
28 select S3C_DEV_HSMMC 29 select S3C_DEV_HSMMC1
29 help 30 help
30 Say Y here if you are using an SMDK2443 31 Say Y here if you are using an SMDK2443
31 32
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 0c3c0c884cd3..f4ec6d5715c8 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -196,7 +196,7 @@ static struct clksrc_clk clk_hsspi = {
196static struct clksrc_clk clk_hsmmc_div = { 196static struct clksrc_clk clk_hsmmc_div = {
197 .clk = { 197 .clk = {
198 .name = "hsmmc-div", 198 .name = "hsmmc-div",
199 .id = -1, 199 .id = 1,
200 .parent = &clk_esysclk.clk, 200 .parent = &clk_esysclk.clk,
201 }, 201 },
202 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 }, 202 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
@@ -231,7 +231,7 @@ static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
231 231
232static struct clk clk_hsmmc = { 232static struct clk clk_hsmmc = {
233 .name = "hsmmc-if", 233 .name = "hsmmc-if",
234 .id = -1, 234 .id = 1,
235 .parent = &clk_hsmmc_div.clk, 235 .parent = &clk_hsmmc_div.clk,
236 .enable = s3c2443_enable_hsmmc, 236 .enable = s3c2443_enable_hsmmc,
237 .ops = &(struct clk_ops) { 237 .ops = &(struct clk_ops) {
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 893424767ce1..c7820f9c1352 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -75,28 +75,27 @@ static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
75#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0)) 75#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
76#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97) 76#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
77 77
78static void s3c2443_irq_wdtac97_mask(unsigned int irqno) 78static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
79{ 79{
80 s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97); 80 s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
81} 81}
82 82
83static void s3c2443_irq_wdtac97_unmask(unsigned int irqno) 83static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
84{ 84{
85 s3c_irqsub_unmask(irqno, INTMSK_WDTAC97); 85 s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
86} 86}
87 87
88static void s3c2443_irq_wdtac97_ack(unsigned int irqno) 88static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
89{ 89{
90 s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97); 90 s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
91} 91}
92 92
93static struct irq_chip s3c2443_irq_wdtac97 = { 93static struct irq_chip s3c2443_irq_wdtac97 = {
94 .mask = s3c2443_irq_wdtac97_mask, 94 .irq_mask = s3c2443_irq_wdtac97_mask,
95 .unmask = s3c2443_irq_wdtac97_unmask, 95 .irq_unmask = s3c2443_irq_wdtac97_unmask,
96 .ack = s3c2443_irq_wdtac97_ack, 96 .irq_ack = s3c2443_irq_wdtac97_ack,
97}; 97};
98 98
99
100/* LCD sub interrupts */ 99/* LCD sub interrupts */
101 100
102static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc) 101static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
@@ -107,28 +106,27 @@ static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
107#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) 106#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
108#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4) 107#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
109 108
110static void s3c2443_irq_lcd_mask(unsigned int irqno) 109static void s3c2443_irq_lcd_mask(struct irq_data *data)
111{ 110{
112 s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD); 111 s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
113} 112}
114 113
115static void s3c2443_irq_lcd_unmask(unsigned int irqno) 114static void s3c2443_irq_lcd_unmask(struct irq_data *data)
116{ 115{
117 s3c_irqsub_unmask(irqno, INTMSK_LCD); 116 s3c_irqsub_unmask(data->irq, INTMSK_LCD);
118} 117}
119 118
120static void s3c2443_irq_lcd_ack(unsigned int irqno) 119static void s3c2443_irq_lcd_ack(struct irq_data *data)
121{ 120{
122 s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD); 121 s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
123} 122}
124 123
125static struct irq_chip s3c2443_irq_lcd = { 124static struct irq_chip s3c2443_irq_lcd = {
126 .mask = s3c2443_irq_lcd_mask, 125 .irq_mask = s3c2443_irq_lcd_mask,
127 .unmask = s3c2443_irq_lcd_unmask, 126 .irq_unmask = s3c2443_irq_lcd_unmask,
128 .ack = s3c2443_irq_lcd_ack, 127 .irq_ack = s3c2443_irq_lcd_ack,
129}; 128};
130 129
131
132/* DMA sub interrupts */ 130/* DMA sub interrupts */
133 131
134static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc) 132static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
@@ -139,29 +137,27 @@ static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
139#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0)) 137#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
140#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5) 138#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
141 139
142 140static void s3c2443_irq_dma_mask(struct irq_data *data)
143static void s3c2443_irq_dma_mask(unsigned int irqno)
144{ 141{
145 s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA); 142 s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
146} 143}
147 144
148static void s3c2443_irq_dma_unmask(unsigned int irqno) 145static void s3c2443_irq_dma_unmask(struct irq_data *data)
149{ 146{
150 s3c_irqsub_unmask(irqno, INTMSK_DMA); 147 s3c_irqsub_unmask(data->irq, INTMSK_DMA);
151} 148}
152 149
153static void s3c2443_irq_dma_ack(unsigned int irqno) 150static void s3c2443_irq_dma_ack(struct irq_data *data)
154{ 151{
155 s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA); 152 s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
156} 153}
157 154
158static struct irq_chip s3c2443_irq_dma = { 155static struct irq_chip s3c2443_irq_dma = {
159 .mask = s3c2443_irq_dma_mask, 156 .irq_mask = s3c2443_irq_dma_mask,
160 .unmask = s3c2443_irq_dma_unmask, 157 .irq_unmask = s3c2443_irq_dma_unmask,
161 .ack = s3c2443_irq_dma_ack, 158 .irq_ack = s3c2443_irq_dma_ack,
162}; 159};
163 160
164
165/* UART3 sub interrupts */ 161/* UART3 sub interrupts */
166 162
167static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) 163static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
@@ -172,28 +168,27 @@ static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
172#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) 168#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
173#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) 169#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
174 170
175static void s3c2443_irq_uart3_mask(unsigned int irqno) 171static void s3c2443_irq_uart3_mask(struct irq_data *data)
176{ 172{
177 s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3); 173 s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
178} 174}
179 175
180static void s3c2443_irq_uart3_unmask(unsigned int irqno) 176static void s3c2443_irq_uart3_unmask(struct irq_data *data)
181{ 177{
182 s3c_irqsub_unmask(irqno, INTMSK_UART3); 178 s3c_irqsub_unmask(data->irq, INTMSK_UART3);
183} 179}
184 180
185static void s3c2443_irq_uart3_ack(unsigned int irqno) 181static void s3c2443_irq_uart3_ack(struct irq_data *data)
186{ 182{
187 s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3); 183 s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
188} 184}
189 185
190static struct irq_chip s3c2443_irq_uart3 = { 186static struct irq_chip s3c2443_irq_uart3 = {
191 .mask = s3c2443_irq_uart3_mask, 187 .irq_mask = s3c2443_irq_uart3_mask,
192 .unmask = s3c2443_irq_uart3_unmask, 188 .irq_unmask = s3c2443_irq_uart3_unmask,
193 .ack = s3c2443_irq_uart3_ack, 189 .irq_ack = s3c2443_irq_uart3_ack,
194}; 190};
195 191
196
197/* CAM sub interrupts */ 192/* CAM sub interrupts */
198 193
199static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc) 194static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
@@ -204,25 +199,25 @@ static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
204#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) 199#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
205#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P) 200#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
206 201
207static void s3c2443_irq_cam_mask(unsigned int irqno) 202static void s3c2443_irq_cam_mask(struct irq_data *data)
208{ 203{
209 s3c_irqsub_mask(irqno, INTMSK_CAM, SUBMSK_CAM); 204 s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
210} 205}
211 206
212static void s3c2443_irq_cam_unmask(unsigned int irqno) 207static void s3c2443_irq_cam_unmask(struct irq_data *data)
213{ 208{
214 s3c_irqsub_unmask(irqno, INTMSK_CAM); 209 s3c_irqsub_unmask(data->irq, INTMSK_CAM);
215} 210}
216 211
217static void s3c2443_irq_cam_ack(unsigned int irqno) 212static void s3c2443_irq_cam_ack(struct irq_data *data)
218{ 213{
219 s3c_irqsub_maskack(irqno, INTMSK_CAM, SUBMSK_CAM); 214 s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
220} 215}
221 216
222static struct irq_chip s3c2443_irq_cam = { 217static struct irq_chip s3c2443_irq_cam = {
223 .mask = s3c2443_irq_cam_mask, 218 .irq_mask = s3c2443_irq_cam_mask,
224 .unmask = s3c2443_irq_cam_unmask, 219 .irq_unmask = s3c2443_irq_cam_unmask,
225 .ack = s3c2443_irq_cam_ack, 220 .irq_ack = s3c2443_irq_cam_ack,
226}; 221};
227 222
228/* IRQ initialisation code */ 223/* IRQ initialisation code */
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
index 4337f0a9960d..514275e43ca0 100644
--- a/arch/arm/mach-s3c2443/mach-smdk2443.c
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -99,13 +99,20 @@ static struct s3c2410_uartcfg smdk2443_uartcfgs[] __initdata = {
99 .ucon = 0x3c5, 99 .ucon = 0x3c5,
100 .ulcon = 0x43, 100 .ulcon = 0x43,
101 .ufcon = 0x51, 101 .ufcon = 0x51,
102 },
103 [3] = {
104 .hwport = 3,
105 .flags = 0,
106 .ucon = 0x3c5,
107 .ulcon = 0x03,
108 .ufcon = 0x51,
102 } 109 }
103}; 110};
104 111
105static struct platform_device *smdk2443_devices[] __initdata = { 112static struct platform_device *smdk2443_devices[] __initdata = {
106 &s3c_device_wdt, 113 &s3c_device_wdt,
107 &s3c_device_i2c0, 114 &s3c_device_i2c0,
108 &s3c_device_hsmmc0, 115 &s3c_device_hsmmc1,
109#ifdef CONFIG_SND_SOC_SMDK2443_WM9710 116#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
110 &s3c_device_ac97, 117 &s3c_device_ac97,
111#endif 118#endif
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
index 33d18dd1ebd5..e6a28ba52c7d 100644
--- a/arch/arm/mach-s3c2443/s3c2443.c
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -16,6 +16,7 @@
16#include <linux/list.h> 16#include <linux/list.h>
17#include <linux/timer.h> 17#include <linux/timer.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/gpio.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20#include <linux/serial_core.h> 21#include <linux/serial_core.h>
21#include <linux/sysdev.h> 22#include <linux/sysdev.h>
@@ -32,6 +33,9 @@
32#include <mach/regs-s3c2443-clock.h> 33#include <mach/regs-s3c2443-clock.h>
33#include <mach/reset.h> 34#include <mach/reset.h>
34 35
36#include <plat/gpio-core.h>
37#include <plat/gpio-cfg.h>
38#include <plat/gpio-cfg-helpers.h>
35#include <plat/s3c2443.h> 39#include <plat/s3c2443.h>
36#include <plat/devs.h> 40#include <plat/devs.h>
37#include <plat/cpu.h> 41#include <plat/cpu.h>
@@ -86,6 +90,9 @@ void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
86 90
87void __init s3c2443_map_io(void) 91void __init s3c2443_map_io(void)
88{ 92{
93 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_s3c2443;
94 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_s3c2443;
95
89 iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc)); 96 iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
90} 97}
91 98
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 7e03f0ae2fc8..dd3782064508 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -127,7 +127,7 @@ int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
127 return s3c64xx_gate(S3C_SCLK_GATE, clk, enable); 127 return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
128} 128}
129 129
130static struct clk init_clocks_disable[] = { 130static struct clk init_clocks_off[] = {
131 { 131 {
132 .name = "nand", 132 .name = "nand",
133 .id = -1, 133 .id = -1,
@@ -695,7 +695,7 @@ static struct clksrc_clk clksrcs[] = {
695 }, { 695 }, {
696 .clk = { 696 .clk = {
697 .name = "audio-bus", 697 .name = "audio-bus",
698 .id = -1, /* There's only one IISv4 port */ 698 .id = 2,
699 .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2, 699 .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2,
700 .enable = s3c64xx_sclk_ctrl, 700 .enable = s3c64xx_sclk_ctrl,
701 }, 701 },
@@ -834,10 +834,6 @@ static struct clk *clks[] __initdata = {
834void __init s3c64xx_register_clocks(unsigned long xtal, 834void __init s3c64xx_register_clocks(unsigned long xtal,
835 unsigned armclk_divlimit) 835 unsigned armclk_divlimit)
836{ 836{
837 struct clk *clkp;
838 int ret;
839 int ptr;
840
841 armclk_mask = armclk_divlimit; 837 armclk_mask = armclk_divlimit;
842 838
843 s3c24xx_register_baseclocks(xtal); 839 s3c24xx_register_baseclocks(xtal);
@@ -845,17 +841,8 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
845 841
846 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 842 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
847 843
848 clkp = init_clocks_disable; 844 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
849 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 845 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
850
851 ret = s3c24xx_register_clock(clkp);
852 if (ret < 0) {
853 printk(KERN_ERR "Failed to register clock %s (%d)\n",
854 clkp->name, ret);
855 }
856
857 (clkp->enable)(clkp, 0);
858 }
859 846
860 s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); 847 s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
861 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 848 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index 76426a32c013..7618627b98f5 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -22,7 +22,12 @@
22#include <plat/audio.h> 22#include <plat/audio.h>
23#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
24 24
25static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) 25static const char *rclksrc[] = {
26 [0] = "iis",
27 [1] = "audio-bus",
28};
29
30static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
26{ 31{
27 unsigned int base; 32 unsigned int base;
28 33
@@ -33,6 +38,12 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
33 case 1: 38 case 1:
34 base = S3C64XX_GPE(0); 39 base = S3C64XX_GPE(0);
35 break; 40 break;
41 case 2:
42 s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
43 s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
44 s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
45 s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
46 return 0;
36 default: 47 default:
37 printk(KERN_DEBUG "Invalid I2S Controller number: %d\n", 48 printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
38 pdev->id); 49 pdev->id);
@@ -44,16 +55,6 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
44 return 0; 55 return 0;
45} 56}
46 57
47static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
48{
49 s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
50 s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
51 s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
52 s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
53
54 return 0;
55}
56
57static struct resource s3c64xx_iis0_resource[] = { 58static struct resource s3c64xx_iis0_resource[] = {
58 [0] = { 59 [0] = {
59 .start = S3C64XX_PA_IIS0, 60 .start = S3C64XX_PA_IIS0,
@@ -72,17 +73,22 @@ static struct resource s3c64xx_iis0_resource[] = {
72 }, 73 },
73}; 74};
74 75
75static struct s3c_audio_pdata s3c_i2s0_pdata = { 76static struct s3c_audio_pdata i2sv3_pdata = {
76 .cfg_gpio = s3c64xx_i2sv3_cfg_gpio, 77 .cfg_gpio = s3c64xx_i2s_cfg_gpio,
78 .type = {
79 .i2s = {
80 .src_clk = rclksrc,
81 },
82 },
77}; 83};
78 84
79struct platform_device s3c64xx_device_iis0 = { 85struct platform_device s3c64xx_device_iis0 = {
80 .name = "s3c64xx-iis", 86 .name = "samsung-i2s",
81 .id = 0, 87 .id = 0,
82 .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource), 88 .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
83 .resource = s3c64xx_iis0_resource, 89 .resource = s3c64xx_iis0_resource,
84 .dev = { 90 .dev = {
85 .platform_data = &s3c_i2s0_pdata, 91 .platform_data = &i2sv3_pdata,
86 }, 92 },
87}; 93};
88EXPORT_SYMBOL(s3c64xx_device_iis0); 94EXPORT_SYMBOL(s3c64xx_device_iis0);
@@ -105,17 +111,13 @@ static struct resource s3c64xx_iis1_resource[] = {
105 }, 111 },
106}; 112};
107 113
108static struct s3c_audio_pdata s3c_i2s1_pdata = {
109 .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
110};
111
112struct platform_device s3c64xx_device_iis1 = { 114struct platform_device s3c64xx_device_iis1 = {
113 .name = "s3c64xx-iis", 115 .name = "samsung-i2s",
114 .id = 1, 116 .id = 1,
115 .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource), 117 .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
116 .resource = s3c64xx_iis1_resource, 118 .resource = s3c64xx_iis1_resource,
117 .dev = { 119 .dev = {
118 .platform_data = &s3c_i2s1_pdata, 120 .platform_data = &i2sv3_pdata,
119 }, 121 },
120}; 122};
121EXPORT_SYMBOL(s3c64xx_device_iis1); 123EXPORT_SYMBOL(s3c64xx_device_iis1);
@@ -138,17 +140,23 @@ static struct resource s3c64xx_iisv4_resource[] = {
138 }, 140 },
139}; 141};
140 142
141static struct s3c_audio_pdata s3c_i2sv4_pdata = { 143static struct s3c_audio_pdata i2sv4_pdata = {
142 .cfg_gpio = s3c64xx_i2sv4_cfg_gpio, 144 .cfg_gpio = s3c64xx_i2s_cfg_gpio,
145 .type = {
146 .i2s = {
147 .quirks = QUIRK_PRI_6CHAN,
148 .src_clk = rclksrc,
149 },
150 },
143}; 151};
144 152
145struct platform_device s3c64xx_device_iisv4 = { 153struct platform_device s3c64xx_device_iisv4 = {
146 .name = "s3c64xx-iis-v4", 154 .name = "samsung-i2s",
147 .id = -1, 155 .id = 2,
148 .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource), 156 .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
149 .resource = s3c64xx_iisv4_resource, 157 .resource = s3c64xx_iisv4_resource,
150 .dev = { 158 .dev = {
151 .platform_data = &s3c_i2sv4_pdata, 159 .platform_data = &i2sv4_pdata,
152 }, 160 },
153}; 161};
154EXPORT_SYMBOL(s3c64xx_device_iisv4); 162EXPORT_SYMBOL(s3c64xx_device_iisv4);
diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c
index e7d03ab41d80..d9aa072ecee3 100644
--- a/arch/arm/mach-s3c64xx/dma.c
+++ b/arch/arm/mach-s3c64xx/dma.c
@@ -212,6 +212,7 @@ static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
212 212
213 config = readl(chan->regs + PL080S_CH_CONFIG); 213 config = readl(chan->regs + PL080S_CH_CONFIG);
214 config |= PL080_CONFIG_ENABLE; 214 config |= PL080_CONFIG_ENABLE;
215 config &= ~PL080_CONFIG_HALT;
215 216
216 pr_debug("%s: writing config %08x\n", __func__, config); 217 pr_debug("%s: writing config %08x\n", __func__, config);
217 writel(config, chan->regs + PL080S_CH_CONFIG); 218 writel(config, chan->regs + PL080S_CH_CONFIG);
diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c
index 5682d6a7f4af..2ead8189da74 100644
--- a/arch/arm/mach-s3c64xx/irq-eint.c
+++ b/arch/arm/mach-s3c64xx/irq-eint.c
@@ -30,41 +30,41 @@
30#include <plat/pm.h> 30#include <plat/pm.h>
31 31
32#define eint_offset(irq) ((irq) - IRQ_EINT(0)) 32#define eint_offset(irq) ((irq) - IRQ_EINT(0))
33#define eint_irq_to_bit(irq) (1 << eint_offset(irq)) 33#define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq)))
34 34
35static inline void s3c_irq_eint_mask(unsigned int irq) 35static inline void s3c_irq_eint_mask(struct irq_data *data)
36{ 36{
37 u32 mask; 37 u32 mask;
38 38
39 mask = __raw_readl(S3C64XX_EINT0MASK); 39 mask = __raw_readl(S3C64XX_EINT0MASK);
40 mask |= eint_irq_to_bit(irq); 40 mask |= (u32)data->chip_data;
41 __raw_writel(mask, S3C64XX_EINT0MASK); 41 __raw_writel(mask, S3C64XX_EINT0MASK);
42} 42}
43 43
44static void s3c_irq_eint_unmask(unsigned int irq) 44static void s3c_irq_eint_unmask(struct irq_data *data)
45{ 45{
46 u32 mask; 46 u32 mask;
47 47
48 mask = __raw_readl(S3C64XX_EINT0MASK); 48 mask = __raw_readl(S3C64XX_EINT0MASK);
49 mask &= ~eint_irq_to_bit(irq); 49 mask &= ~((u32)data->chip_data);
50 __raw_writel(mask, S3C64XX_EINT0MASK); 50 __raw_writel(mask, S3C64XX_EINT0MASK);
51} 51}
52 52
53static inline void s3c_irq_eint_ack(unsigned int irq) 53static inline void s3c_irq_eint_ack(struct irq_data *data)
54{ 54{
55 __raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND); 55 __raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND);
56} 56}
57 57
58static void s3c_irq_eint_maskack(unsigned int irq) 58static void s3c_irq_eint_maskack(struct irq_data *data)
59{ 59{
60 /* compiler should in-line these */ 60 /* compiler should in-line these */
61 s3c_irq_eint_mask(irq); 61 s3c_irq_eint_mask(data);
62 s3c_irq_eint_ack(irq); 62 s3c_irq_eint_ack(data);
63} 63}
64 64
65static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) 65static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type)
66{ 66{
67 int offs = eint_offset(irq); 67 int offs = eint_offset(data->irq);
68 int pin, pin_val; 68 int pin, pin_val;
69 int shift; 69 int shift;
70 u32 ctrl, mask; 70 u32 ctrl, mask;
@@ -140,12 +140,12 @@ static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
140 140
141static struct irq_chip s3c_irq_eint = { 141static struct irq_chip s3c_irq_eint = {
142 .name = "s3c-eint", 142 .name = "s3c-eint",
143 .mask = s3c_irq_eint_mask, 143 .irq_mask = s3c_irq_eint_mask,
144 .unmask = s3c_irq_eint_unmask, 144 .irq_unmask = s3c_irq_eint_unmask,
145 .mask_ack = s3c_irq_eint_maskack, 145 .irq_mask_ack = s3c_irq_eint_maskack,
146 .ack = s3c_irq_eint_ack, 146 .irq_ack = s3c_irq_eint_ack,
147 .set_type = s3c_irq_eint_set_type, 147 .irq_set_type = s3c_irq_eint_set_type,
148 .set_wake = s3c_irqext_wake, 148 .irq_set_wake = s3c_irqext_wake,
149}; 149};
150 150
151/* s3c_irq_demux_eint 151/* s3c_irq_demux_eint
@@ -198,6 +198,7 @@ static int __init s3c64xx_init_irq_eint(void)
198 198
199 for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { 199 for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
200 set_irq_chip(irq, &s3c_irq_eint); 200 set_irq_chip(irq, &s3c_irq_eint);
201 set_irq_chip_data(irq, (void *)eint_irq_to_bit(irq));
201 set_irq_handler(irq, handle_level_irq); 202 set_irq_handler(irq, handle_level_irq);
202 set_irq_flags(irq, IRQF_VALID); 203 set_irq_flags(irq, IRQF_VALID);
203 } 204 }
diff --git a/arch/arm/mach-s5p6442/clock.c b/arch/arm/mach-s5p6442/clock.c
index 16d6e7e61b50..fbbc7bede685 100644
--- a/arch/arm/mach-s5p6442/clock.c
+++ b/arch/arm/mach-s5p6442/clock.c
@@ -340,7 +340,7 @@ void __init_or_cpufreq s5p6442_setup_clocks(void)
340 clk_pclkd1.rate = pclkd1; 340 clk_pclkd1.rate = pclkd1;
341} 341}
342 342
343static struct clk init_clocks_disable[] = { 343static struct clk init_clocks_off[] = {
344 { 344 {
345 .name = "pdma", 345 .name = "pdma",
346 .id = -1, 346 .id = -1,
@@ -408,23 +408,13 @@ static struct clk *clks[] __initdata = {
408 408
409void __init s5p6442_register_clocks(void) 409void __init s5p6442_register_clocks(void)
410{ 410{
411 struct clk *clkptr;
412 int i, ret;
413
414 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); 411 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
415 412
416 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 413 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
417 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 414 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
418 415
419 clkptr = init_clocks_disable; 416 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
420 for (i = 0; i < ARRAY_SIZE(init_clocks_disable); i++, clkptr++) { 417 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
421 ret = s3c24xx_register_clock(clkptr);
422 if (ret < 0) {
423 printk(KERN_ERR "Fail to register clock %s (%d)\n",
424 clkptr->name, ret);
425 } else
426 (clkptr->enable)(clkptr, 0);
427 }
428 418
429 s3c_pwmclk_init(); 419 s3c_pwmclk_init();
430} 420}
diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c
index 3462197ff352..8719dc41fe32 100644
--- a/arch/arm/mach-s5p6442/dev-audio.c
+++ b/arch/arm/mach-s5p6442/dev-audio.c
@@ -29,7 +29,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
29 base = S5P6442_GPC1(0); 29 base = S5P6442_GPC1(0);
30 break; 30 break;
31 31
32 case -1: 32 case 0:
33 base = S5P6442_GPC0(0); 33 base = S5P6442_GPC0(0);
34 break; 34 break;
35 35
@@ -42,8 +42,19 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
42 return 0; 42 return 0;
43} 43}
44 44
45static struct s3c_audio_pdata s3c_i2s_pdata = { 45static const char *rclksrc_v35[] = {
46 [0] = "busclk",
47 [1] = "i2sclk",
48};
49
50static struct s3c_audio_pdata i2sv35_pdata = {
46 .cfg_gpio = s5p6442_cfg_i2s, 51 .cfg_gpio = s5p6442_cfg_i2s,
52 .type = {
53 .i2s = {
54 .quirks = QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR,
55 .src_clk = rclksrc_v35,
56 },
57 },
47}; 58};
48 59
49static struct resource s5p6442_iis0_resource[] = { 60static struct resource s5p6442_iis0_resource[] = {
@@ -62,15 +73,34 @@ static struct resource s5p6442_iis0_resource[] = {
62 .end = DMACH_I2S0_RX, 73 .end = DMACH_I2S0_RX,
63 .flags = IORESOURCE_DMA, 74 .flags = IORESOURCE_DMA,
64 }, 75 },
76 [3] = {
77 .start = DMACH_I2S0S_TX,
78 .end = DMACH_I2S0S_TX,
79 .flags = IORESOURCE_DMA,
80 },
65}; 81};
66 82
67struct platform_device s5p6442_device_iis0 = { 83struct platform_device s5p6442_device_iis0 = {
68 .name = "s3c64xx-iis-v4", 84 .name = "samsung-i2s",
69 .id = -1, 85 .id = 0,
70 .num_resources = ARRAY_SIZE(s5p6442_iis0_resource), 86 .num_resources = ARRAY_SIZE(s5p6442_iis0_resource),
71 .resource = s5p6442_iis0_resource, 87 .resource = s5p6442_iis0_resource,
72 .dev = { 88 .dev = {
73 .platform_data = &s3c_i2s_pdata, 89 .platform_data = &i2sv35_pdata,
90 },
91};
92
93static const char *rclksrc_v3[] = {
94 [0] = "iis",
95 [1] = "sclk_audio",
96};
97
98static struct s3c_audio_pdata i2sv3_pdata = {
99 .cfg_gpio = s5p6442_cfg_i2s,
100 .type = {
101 .i2s = {
102 .src_clk = rclksrc_v3,
103 },
74 }, 104 },
75}; 105};
76 106
@@ -93,12 +123,12 @@ static struct resource s5p6442_iis1_resource[] = {
93}; 123};
94 124
95struct platform_device s5p6442_device_iis1 = { 125struct platform_device s5p6442_device_iis1 = {
96 .name = "s3c64xx-iis", 126 .name = "samsung-i2s",
97 .id = 1, 127 .id = 1,
98 .num_resources = ARRAY_SIZE(s5p6442_iis1_resource), 128 .num_resources = ARRAY_SIZE(s5p6442_iis1_resource),
99 .resource = s5p6442_iis1_resource, 129 .resource = s5p6442_iis1_resource,
100 .dev = { 130 .dev = {
101 .platform_data = &s3c_i2s_pdata, 131 .platform_data = &i2sv3_pdata,
102 }, 132 },
103}; 133};
104 134
diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h
index 31fb2e68d527..203dd5a18bd5 100644
--- a/arch/arm/mach-s5p6442/include/mach/map.h
+++ b/arch/arm/mach-s5p6442/include/mach/map.h
@@ -28,6 +28,9 @@
28#define S5P6442_PA_VIC1 (0xE4100000) 28#define S5P6442_PA_VIC1 (0xE4100000)
29#define S5P6442_PA_VIC2 (0xE4200000) 29#define S5P6442_PA_VIC2 (0xE4200000)
30 30
31#define S5P6442_PA_SROMC (0xE7000000)
32#define S5P_PA_SROMC S5P6442_PA_SROMC
33
31#define S5P6442_PA_MDMA 0xE8000000 34#define S5P6442_PA_MDMA 0xE8000000
32#define S5P6442_PA_PDMA 0xE9000000 35#define S5P6442_PA_PDMA 0xE9000000
33 36
diff --git a/arch/arm/mach-s5p6442/mach-smdk6442.c b/arch/arm/mach-s5p6442/mach-smdk6442.c
index 819fd80d00af..e69f137b0a39 100644
--- a/arch/arm/mach-s5p6442/mach-smdk6442.c
+++ b/arch/arm/mach-s5p6442/mach-smdk6442.c
@@ -12,6 +12,7 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/serial_core.h> 14#include <linux/serial_core.h>
15#include <linux/i2c.h>
15 16
16#include <asm/mach/arch.h> 17#include <asm/mach/arch.h>
17#include <asm/mach/map.h> 18#include <asm/mach/map.h>
@@ -25,6 +26,7 @@
25#include <plat/s5p6442.h> 26#include <plat/s5p6442.h>
26#include <plat/devs.h> 27#include <plat/devs.h>
27#include <plat/cpu.h> 28#include <plat/cpu.h>
29#include <plat/iic.h>
28 30
29/* Following are default values for UCON, ULCON and UFCON UART registers */ 31/* Following are default values for UCON, ULCON and UFCON UART registers */
30#define SMDK6442_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 32#define SMDK6442_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -65,10 +67,15 @@ static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
65}; 67};
66 68
67static struct platform_device *smdk6442_devices[] __initdata = { 69static struct platform_device *smdk6442_devices[] __initdata = {
70 &s3c_device_i2c0,
68 &s5p6442_device_iis0, 71 &s5p6442_device_iis0,
69 &s3c_device_wdt, 72 &s3c_device_wdt,
70}; 73};
71 74
75static struct i2c_board_info smdk6442_i2c_devs0[] __initdata = {
76 { I2C_BOARD_INFO("wm8580", 0x1b), },
77};
78
72static void __init smdk6442_map_io(void) 79static void __init smdk6442_map_io(void)
73{ 80{
74 s5p_init_io(NULL, 0, S5P_VA_CHIPID); 81 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -78,6 +85,9 @@ static void __init smdk6442_map_io(void)
78 85
79static void __init smdk6442_machine_init(void) 86static void __init smdk6442_machine_init(void)
80{ 87{
88 s3c_i2c0_set_platdata(NULL);
89 i2c_register_board_info(0, smdk6442_i2c_devs0,
90 ARRAY_SIZE(smdk6442_i2c_devs0));
81 platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices)); 91 platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices));
82} 92}
83 93
diff --git a/arch/arm/mach-s5p6442/setup-i2c0.c b/arch/arm/mach-s5p6442/setup-i2c0.c
index 662695dd7761..aad85656b0cc 100644
--- a/arch/arm/mach-s5p6442/setup-i2c0.c
+++ b/arch/arm/mach-s5p6442/setup-i2c0.c
@@ -14,12 +14,15 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/gpio.h>
17 18
18struct platform_device; /* don't need the contents */ 19struct platform_device; /* don't need the contents */
19 20
21#include <plat/gpio-cfg.h>
20#include <plat/iic.h> 22#include <plat/iic.h>
21 23
22void s3c_i2c0_cfg_gpio(struct platform_device *dev) 24void s3c_i2c0_cfg_gpio(struct platform_device *dev)
23{ 25{
24 /* Will be populated later */ 26 s3c_gpio_cfgall_range(S5P6442_GPD1(0), 2,
27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
25} 28}
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
index 2655829e6bf8..ae6bf6feba89 100644
--- a/arch/arm/mach-s5p64x0/Makefile
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -12,9 +12,9 @@ obj- :=
12 12
13# Core support for S5P64X0 system 13# Core support for S5P64X0 system
14 14
15obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o 15obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o gpiolib.o
16obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o 16obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o
17obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o gpio.o 17obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o
18obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o 18obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o
19 19
20# machine support 20# machine support
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index e4883dc1c8d7..9f12c2ebf416 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -133,7 +133,7 @@ static struct clksrc_clk clk_pclk_low = {
133 * recommended to keep the following clocks disabled until the driver requests 133 * recommended to keep the following clocks disabled until the driver requests
134 * for enabling the clock. 134 * for enabling the clock.
135 */ 135 */
136static struct clk init_clocks_disable[] = { 136static struct clk init_clocks_off[] = {
137 { 137 {
138 .name = "nand", 138 .name = "nand",
139 .id = -1, 139 .id = -1,
@@ -261,7 +261,7 @@ static struct clk init_clocks_disable[] = {
261 .enable = s5p64x0_pclk_ctrl, 261 .enable = s5p64x0_pclk_ctrl,
262 .ctrlbit = (1 << 25), 262 .ctrlbit = (1 << 25),
263 }, { 263 }, {
264 .name = "i2s_v40", 264 .name = "iis",
265 .id = 0, 265 .id = 0,
266 .parent = &clk_pclk_low.clk, 266 .parent = &clk_pclk_low.clk,
267 .enable = s5p64x0_pclk_ctrl, 267 .enable = s5p64x0_pclk_ctrl,
@@ -419,7 +419,7 @@ static struct clksrc_sources clkset_audio = {
419static struct clksrc_clk clksrcs[] = { 419static struct clksrc_clk clksrcs[] = {
420 { 420 {
421 .clk = { 421 .clk = {
422 .name = "mmc_bus", 422 .name = "sclk_mmc",
423 .id = 0, 423 .id = 0,
424 .ctrlbit = (1 << 24), 424 .ctrlbit = (1 << 24),
425 .enable = s5p64x0_sclk_ctrl, 425 .enable = s5p64x0_sclk_ctrl,
@@ -429,7 +429,7 @@ static struct clksrc_clk clksrcs[] = {
429 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 }, 429 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
430 }, { 430 }, {
431 .clk = { 431 .clk = {
432 .name = "mmc_bus", 432 .name = "sclk_mmc",
433 .id = 1, 433 .id = 1,
434 .ctrlbit = (1 << 25), 434 .ctrlbit = (1 << 25),
435 .enable = s5p64x0_sclk_ctrl, 435 .enable = s5p64x0_sclk_ctrl,
@@ -439,7 +439,7 @@ static struct clksrc_clk clksrcs[] = {
439 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 }, 439 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
440 }, { 440 }, {
441 .clk = { 441 .clk = {
442 .name = "mmc_bus", 442 .name = "sclk_mmc",
443 .id = 2, 443 .id = 2,
444 .ctrlbit = (1 << 26), 444 .ctrlbit = (1 << 26),
445 .enable = s5p64x0_sclk_ctrl, 445 .enable = s5p64x0_sclk_ctrl,
@@ -602,8 +602,6 @@ static struct clk *clks[] __initdata = {
602 602
603void __init s5p6440_register_clocks(void) 603void __init s5p6440_register_clocks(void)
604{ 604{
605 struct clk *clkp;
606 int ret;
607 int ptr; 605 int ptr;
608 606
609 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); 607 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
@@ -614,16 +612,8 @@ void __init s5p6440_register_clocks(void)
614 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 612 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
615 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 613 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
616 614
617 clkp = init_clocks_disable; 615 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
618 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 616 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
619
620 ret = s3c24xx_register_clock(clkp);
621 if (ret < 0) {
622 printk(KERN_ERR "Failed to register clock %s (%d)\n",
623 clkp->name, ret);
624 }
625 (clkp->enable)(clkp, 0);
626 }
627 617
628 s3c_pwmclk_init(); 618 s3c_pwmclk_init();
629} 619}
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index 7dbf3c968f53..4eec457ddccc 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -181,7 +181,7 @@ static struct clksrc_clk clk_pclk_low = {
181 * recommended to keep the following clocks disabled until the driver requests 181 * recommended to keep the following clocks disabled until the driver requests
182 * for enabling the clock. 182 * for enabling the clock.
183 */ 183 */
184static struct clk init_clocks_disable[] = { 184static struct clk init_clocks_off[] = {
185 { 185 {
186 .name = "usbhost", 186 .name = "usbhost",
187 .id = -1, 187 .id = -1,
@@ -231,6 +231,12 @@ static struct clk init_clocks_disable[] = {
231 .enable = s5p64x0_pclk_ctrl, 231 .enable = s5p64x0_pclk_ctrl,
232 .ctrlbit = (1 << 5), 232 .ctrlbit = (1 << 5),
233 }, { 233 }, {
234 .name = "rtc",
235 .id = -1,
236 .parent = &clk_pclk_low.clk,
237 .enable = s5p64x0_pclk_ctrl,
238 .ctrlbit = (1 << 6),
239 }, {
234 .name = "adc", 240 .name = "adc",
235 .id = -1, 241 .id = -1,
236 .parent = &clk_pclk_low.clk, 242 .parent = &clk_pclk_low.clk,
@@ -256,11 +262,23 @@ static struct clk init_clocks_disable[] = {
256 .ctrlbit = (1 << 22), 262 .ctrlbit = (1 << 22),
257 }, { 263 }, {
258 .name = "iis", 264 .name = "iis",
259 .id = -1, 265 .id = 0,
260 .parent = &clk_pclk_low.clk, 266 .parent = &clk_pclk_low.clk,
261 .enable = s5p64x0_pclk_ctrl, 267 .enable = s5p64x0_pclk_ctrl,
262 .ctrlbit = (1 << 26), 268 .ctrlbit = (1 << 26),
263 }, { 269 }, {
270 .name = "iis",
271 .id = 1,
272 .parent = &clk_pclk_low.clk,
273 .enable = s5p64x0_pclk_ctrl,
274 .ctrlbit = (1 << 15),
275 }, {
276 .name = "iis",
277 .id = 2,
278 .parent = &clk_pclk_low.clk,
279 .enable = s5p64x0_pclk_ctrl,
280 .ctrlbit = (1 << 16),
281 }, {
264 .name = "i2c", 282 .name = "i2c",
265 .id = 1, 283 .id = 1,
266 .parent = &clk_pclk_low.clk, 284 .parent = &clk_pclk_low.clk,
@@ -633,8 +651,6 @@ void __init_or_cpufreq s5p6450_setup_clocks(void)
633 651
634void __init s5p6450_register_clocks(void) 652void __init s5p6450_register_clocks(void)
635{ 653{
636 struct clk *clkp;
637 int ret;
638 int ptr; 654 int ptr;
639 655
640 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) 656 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
@@ -643,16 +659,8 @@ void __init s5p6450_register_clocks(void)
643 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 659 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
644 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 660 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
645 661
646 clkp = init_clocks_disable; 662 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
647 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 663 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
648
649 ret = s3c24xx_register_clock(clkp);
650 if (ret < 0) {
651 printk(KERN_ERR "Failed to register clock %s (%d)\n",
652 clkp->name, ret);
653 }
654 (clkp->enable)(clkp, 0);
655 }
656 664
657 s3c_pwmclk_init(); 665 s3c_pwmclk_init();
658} 666}
diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c
index 396bacc0a39a..35f1f226dabb 100644
--- a/arch/arm/mach-s5p64x0/dev-audio.c
+++ b/arch/arm/mach-s5p64x0/dev-audio.c
@@ -19,15 +19,19 @@
19#include <mach/dma.h> 19#include <mach/dma.h>
20#include <mach/irqs.h> 20#include <mach/irqs.h>
21 21
22static const char *rclksrc[] = {
23 [0] = "iis",
24 [1] = "sclk_audio2",
25};
26
22static int s5p6440_cfg_i2s(struct platform_device *pdev) 27static int s5p6440_cfg_i2s(struct platform_device *pdev)
23{ 28{
24 /* configure GPIO for i2s port */
25 switch (pdev->id) { 29 switch (pdev->id) {
26 case -1: 30 case 0:
27 s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5)); 31 s3c_gpio_cfgpin_range(S5P6440_GPC(4), 2, S3C_GPIO_SFN(5));
28 s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5)); 32 s3c_gpio_cfgpin(S5P6440_GPC(7), S3C_GPIO_SFN(5));
33 s3c_gpio_cfgpin_range(S5P6440_GPH(6), 4, S3C_GPIO_SFN(5));
29 break; 34 break;
30
31 default: 35 default:
32 printk(KERN_ERR "Invalid Device %d\n", pdev->id); 36 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
33 return -EINVAL; 37 return -EINVAL;
@@ -36,17 +40,58 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev)
36 return 0; 40 return 0;
37} 41}
38 42
43static struct s3c_audio_pdata s5p6440_i2s_pdata = {
44 .cfg_gpio = s5p6440_cfg_i2s,
45 .type = {
46 .i2s = {
47 .quirks = QUIRK_PRI_6CHAN,
48 .src_clk = rclksrc,
49 },
50 },
51};
52
53static struct resource s5p64x0_i2s0_resource[] = {
54 [0] = {
55 .start = S5P64X0_PA_I2S,
56 .end = S5P64X0_PA_I2S + 0x100 - 1,
57 .flags = IORESOURCE_MEM,
58 },
59 [1] = {
60 .start = DMACH_I2S0_TX,
61 .end = DMACH_I2S0_TX,
62 .flags = IORESOURCE_DMA,
63 },
64 [2] = {
65 .start = DMACH_I2S0_RX,
66 .end = DMACH_I2S0_RX,
67 .flags = IORESOURCE_DMA,
68 },
69};
70
71struct platform_device s5p6440_device_iis = {
72 .name = "samsung-i2s",
73 .id = 0,
74 .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
75 .resource = s5p64x0_i2s0_resource,
76 .dev = {
77 .platform_data = &s5p6440_i2s_pdata,
78 },
79};
80
39static int s5p6450_cfg_i2s(struct platform_device *pdev) 81static int s5p6450_cfg_i2s(struct platform_device *pdev)
40{ 82{
41 /* configure GPIO for i2s port */
42 switch (pdev->id) { 83 switch (pdev->id) {
43 case -1: 84 case 0:
44 s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
45 s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5)); 85 s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
46 s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5)); 86 s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
47
48 break; 87 break;
49 88 case 1:
89 s3c_gpio_cfgpin(S5P6440_GPB(4), S3C_GPIO_SFN(5));
90 s3c_gpio_cfgpin_range(S5P6450_GPC(0), 4, S3C_GPIO_SFN(5));
91 break;
92 case 2:
93 s3c_gpio_cfgpin_range(S5P6450_GPK(0), 5, S3C_GPIO_SFN(5));
94 break;
50 default: 95 default:
51 printk(KERN_ERR "Invalid Device %d\n", pdev->id); 96 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
52 return -EINVAL; 97 return -EINVAL;
@@ -55,47 +100,86 @@ static int s5p6450_cfg_i2s(struct platform_device *pdev)
55 return 0; 100 return 0;
56} 101}
57 102
58static struct s3c_audio_pdata s5p6440_i2s_pdata = { 103static struct s3c_audio_pdata s5p6450_i2s0_pdata = {
59 .cfg_gpio = s5p6440_cfg_i2s, 104 .cfg_gpio = s5p6450_cfg_i2s,
105 .type = {
106 .i2s = {
107 .quirks = QUIRK_PRI_6CHAN,
108 .src_clk = rclksrc,
109 },
110 },
111};
112
113struct platform_device s5p6450_device_iis0 = {
114 .name = "samsung-i2s",
115 .id = 0,
116 .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
117 .resource = s5p64x0_i2s0_resource,
118 .dev = {
119 .platform_data = &s5p6450_i2s0_pdata,
120 },
60}; 121};
61 122
62static struct s3c_audio_pdata s5p6450_i2s_pdata = { 123static struct s3c_audio_pdata s5p6450_i2s_pdata = {
63 .cfg_gpio = s5p6450_cfg_i2s, 124 .cfg_gpio = s5p6450_cfg_i2s,
125 .type = {
126 .i2s = {
127 .src_clk = rclksrc,
128 },
129 },
64}; 130};
65 131
66static struct resource s5p64x0_iis0_resource[] = { 132static struct resource s5p6450_i2s1_resource[] = {
67 [0] = { 133 [0] = {
68 .start = S5P64X0_PA_I2S, 134 .start = S5P6450_PA_I2S1,
69 .end = S5P64X0_PA_I2S + 0x100 - 1, 135 .end = S5P6450_PA_I2S1 + 0x100 - 1,
70 .flags = IORESOURCE_MEM, 136 .flags = IORESOURCE_MEM,
71 }, 137 },
72 [1] = { 138 [1] = {
73 .start = DMACH_I2S0_TX, 139 .start = DMACH_I2S1_TX,
74 .end = DMACH_I2S0_TX, 140 .end = DMACH_I2S1_TX,
75 .flags = IORESOURCE_DMA, 141 .flags = IORESOURCE_DMA,
76 }, 142 },
77 [2] = { 143 [2] = {
78 .start = DMACH_I2S0_RX, 144 .start = DMACH_I2S1_RX,
79 .end = DMACH_I2S0_RX, 145 .end = DMACH_I2S1_RX,
80 .flags = IORESOURCE_DMA, 146 .flags = IORESOURCE_DMA,
81 }, 147 },
82}; 148};
83 149
84struct platform_device s5p6440_device_iis = { 150struct platform_device s5p6450_device_iis1 = {
85 .name = "s3c64xx-iis-v4", 151 .name = "samsung-i2s",
86 .id = -1, 152 .id = 1,
87 .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), 153 .num_resources = ARRAY_SIZE(s5p6450_i2s1_resource),
88 .resource = s5p64x0_iis0_resource, 154 .resource = s5p6450_i2s1_resource,
89 .dev = { 155 .dev = {
90 .platform_data = &s5p6440_i2s_pdata, 156 .platform_data = &s5p6450_i2s_pdata,
91 }, 157 },
92}; 158};
93 159
94struct platform_device s5p6450_device_iis0 = { 160static struct resource s5p6450_i2s2_resource[] = {
95 .name = "s3c64xx-iis-v4", 161 [0] = {
96 .id = -1, 162 .start = S5P6450_PA_I2S2,
97 .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), 163 .end = S5P6450_PA_I2S2 + 0x100 - 1,
98 .resource = s5p64x0_iis0_resource, 164 .flags = IORESOURCE_MEM,
165 },
166 [1] = {
167 .start = DMACH_I2S2_TX,
168 .end = DMACH_I2S2_TX,
169 .flags = IORESOURCE_DMA,
170 },
171 [2] = {
172 .start = DMACH_I2S2_RX,
173 .end = DMACH_I2S2_RX,
174 .flags = IORESOURCE_DMA,
175 },
176};
177
178struct platform_device s5p6450_device_iis2 = {
179 .name = "samsung-i2s",
180 .id = 2,
181 .num_resources = ARRAY_SIZE(s5p6450_i2s2_resource),
182 .resource = s5p6450_i2s2_resource,
99 .dev = { 183 .dev = {
100 .platform_data = &s5p6450_i2s_pdata, 184 .platform_data = &s5p6450_i2s_pdata,
101 }, 185 },
diff --git a/arch/arm/mach-s5p64x0/gpio.c b/arch/arm/mach-s5p64x0/gpiolib.c
index 39159dd5a29a..e7fb3b004e77 100644
--- a/arch/arm/mach-s5p64x0/gpio.c
+++ b/arch/arm/mach-s5p64x0/gpiolib.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s5p64x0/gpio.c 1/* linux/arch/arm/mach-s5p64x0/gpiolib.c
2 * 2 *
3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
@@ -17,13 +17,12 @@
17 17
18#include <mach/map.h> 18#include <mach/map.h>
19#include <mach/regs-gpio.h> 19#include <mach/regs-gpio.h>
20#include <mach/regs-clock.h>
20 21
21#include <plat/gpio-core.h> 22#include <plat/gpio-core.h>
22#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
23#include <plat/gpio-cfg-helpers.h> 24#include <plat/gpio-cfg-helpers.h>
24 25
25/* To be implemented S5P6450 GPIO */
26
27/* 26/*
28 * S5P6440 GPIO bank summary: 27 * S5P6440 GPIO bank summary:
29 * 28 *
@@ -40,6 +39,25 @@
40 * P 8 2Bit Yes 8 39 * P 8 2Bit Yes 8
41 * R 15 4Bit[2] Yes 8 40 * R 15 4Bit[2] Yes 8
42 * 41 *
42 * S5P6450 GPIO bank summary:
43 *
44 * Bank GPIOs Style SlpCon ExtInt Group
45 * A 6 4Bit Yes 1
46 * B 7 4Bit Yes 1
47 * C 8 4Bit Yes 2
48 * D 8 4Bit Yes None
49 * F 2 2Bit Yes None
50 * G 14 4Bit[2] Yes 5
51 * H 10 4Bit[2] Yes 6
52 * I 16 2Bit Yes None
53 * J 12 2Bit Yes None
54 * K 5 4Bit Yes None
55 * N 16 2Bit No IRQ_EINT
56 * P 11 2Bit Yes 8
57 * Q 14 2Bit Yes None
58 * R 15 4Bit[2] Yes None
59 * S 8 2Bit Yes None
60 *
43 * [1] BANKF pins 14,15 do not form part of the external interrupt sources 61 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
44 * [2] BANK has two control registers, GPxCON0 and GPxCON1 62 * [2] BANK has two control registers, GPxCON0 and GPxCON1
45 */ 63 */
@@ -190,7 +208,7 @@ static struct s3c_gpio_cfg s5p64x0_gpio_cfgs[] = {
190 208
191static struct s3c_gpio_chip s5p6440_gpio_4bit[] = { 209static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
192 { 210 {
193 .base = S5P6440_GPA_BASE, 211 .base = S5P64X0_GPA_BASE,
194 .config = &s5p64x0_gpio_cfgs[1], 212 .config = &s5p64x0_gpio_cfgs[1],
195 .chip = { 213 .chip = {
196 .base = S5P6440_GPA(0), 214 .base = S5P6440_GPA(0),
@@ -198,7 +216,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
198 .label = "GPA", 216 .label = "GPA",
199 }, 217 },
200 }, { 218 }, {
201 .base = S5P6440_GPB_BASE, 219 .base = S5P64X0_GPB_BASE,
202 .config = &s5p64x0_gpio_cfgs[1], 220 .config = &s5p64x0_gpio_cfgs[1],
203 .chip = { 221 .chip = {
204 .base = S5P6440_GPB(0), 222 .base = S5P6440_GPB(0),
@@ -206,7 +224,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
206 .label = "GPB", 224 .label = "GPB",
207 }, 225 },
208 }, { 226 }, {
209 .base = S5P6440_GPC_BASE, 227 .base = S5P64X0_GPC_BASE,
210 .config = &s5p64x0_gpio_cfgs[1], 228 .config = &s5p64x0_gpio_cfgs[1],
211 .chip = { 229 .chip = {
212 .base = S5P6440_GPC(0), 230 .base = S5P6440_GPC(0),
@@ -214,7 +232,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
214 .label = "GPC", 232 .label = "GPC",
215 }, 233 },
216 }, { 234 }, {
217 .base = S5P6440_GPG_BASE, 235 .base = S5P64X0_GPG_BASE,
218 .config = &s5p64x0_gpio_cfgs[1], 236 .config = &s5p64x0_gpio_cfgs[1],
219 .chip = { 237 .chip = {
220 .base = S5P6440_GPG(0), 238 .base = S5P6440_GPG(0),
@@ -226,7 +244,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
226 244
227static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = { 245static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
228 { 246 {
229 .base = S5P6440_GPH_BASE + 0x4, 247 .base = S5P64X0_GPH_BASE + 0x4,
230 .config = &s5p64x0_gpio_cfgs[1], 248 .config = &s5p64x0_gpio_cfgs[1],
231 .chip = { 249 .chip = {
232 .base = S5P6440_GPH(0), 250 .base = S5P6440_GPH(0),
@@ -238,7 +256,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
238 256
239static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = { 257static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = {
240 { 258 {
241 .base = S5P6440_GPR_BASE + 0x4, 259 .base = S5P64X0_GPR_BASE + 0x4,
242 .config = &s5p64x0_gpio_cfgs[2], 260 .config = &s5p64x0_gpio_cfgs[2],
243 .chip = { 261 .chip = {
244 .base = S5P6440_GPR(0), 262 .base = S5P6440_GPR(0),
@@ -250,7 +268,7 @@ static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = {
250 268
251static struct s3c_gpio_chip s5p6440_gpio_2bit[] = { 269static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
252 { 270 {
253 .base = S5P6440_GPF_BASE, 271 .base = S5P64X0_GPF_BASE,
254 .config = &s5p64x0_gpio_cfgs[5], 272 .config = &s5p64x0_gpio_cfgs[5],
255 .chip = { 273 .chip = {
256 .base = S5P6440_GPF(0), 274 .base = S5P6440_GPF(0),
@@ -258,7 +276,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
258 .label = "GPF", 276 .label = "GPF",
259 }, 277 },
260 }, { 278 }, {
261 .base = S5P6440_GPI_BASE, 279 .base = S5P64X0_GPI_BASE,
262 .config = &s5p64x0_gpio_cfgs[3], 280 .config = &s5p64x0_gpio_cfgs[3],
263 .chip = { 281 .chip = {
264 .base = S5P6440_GPI(0), 282 .base = S5P6440_GPI(0),
@@ -266,7 +284,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
266 .label = "GPI", 284 .label = "GPI",
267 }, 285 },
268 }, { 286 }, {
269 .base = S5P6440_GPJ_BASE, 287 .base = S5P64X0_GPJ_BASE,
270 .config = &s5p64x0_gpio_cfgs[3], 288 .config = &s5p64x0_gpio_cfgs[3],
271 .chip = { 289 .chip = {
272 .base = S5P6440_GPJ(0), 290 .base = S5P6440_GPJ(0),
@@ -274,7 +292,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
274 .label = "GPJ", 292 .label = "GPJ",
275 }, 293 },
276 }, { 294 }, {
277 .base = S5P6440_GPN_BASE, 295 .base = S5P64X0_GPN_BASE,
278 .config = &s5p64x0_gpio_cfgs[4], 296 .config = &s5p64x0_gpio_cfgs[4],
279 .chip = { 297 .chip = {
280 .base = S5P6440_GPN(0), 298 .base = S5P6440_GPN(0),
@@ -282,7 +300,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
282 .label = "GPN", 300 .label = "GPN",
283 }, 301 },
284 }, { 302 }, {
285 .base = S5P6440_GPP_BASE, 303 .base = S5P64X0_GPP_BASE,
286 .config = &s5p64x0_gpio_cfgs[5], 304 .config = &s5p64x0_gpio_cfgs[5],
287 .chip = { 305 .chip = {
288 .base = S5P6440_GPP(0), 306 .base = S5P6440_GPP(0),
@@ -292,6 +310,142 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
292 }, 310 },
293}; 311};
294 312
313static struct s3c_gpio_chip s5p6450_gpio_4bit[] = {
314 {
315 .base = S5P64X0_GPA_BASE,
316 .config = &s5p64x0_gpio_cfgs[1],
317 .chip = {
318 .base = S5P6450_GPA(0),
319 .ngpio = S5P6450_GPIO_A_NR,
320 .label = "GPA",
321 },
322 }, {
323 .base = S5P64X0_GPB_BASE,
324 .config = &s5p64x0_gpio_cfgs[1],
325 .chip = {
326 .base = S5P6450_GPB(0),
327 .ngpio = S5P6450_GPIO_B_NR,
328 .label = "GPB",
329 },
330 }, {
331 .base = S5P64X0_GPC_BASE,
332 .config = &s5p64x0_gpio_cfgs[1],
333 .chip = {
334 .base = S5P6450_GPC(0),
335 .ngpio = S5P6450_GPIO_C_NR,
336 .label = "GPC",
337 },
338 }, {
339 .base = S5P6450_GPD_BASE,
340 .config = &s5p64x0_gpio_cfgs[1],
341 .chip = {
342 .base = S5P6450_GPD(0),
343 .ngpio = S5P6450_GPIO_D_NR,
344 .label = "GPD",
345 },
346 }, {
347 .base = S5P6450_GPK_BASE,
348 .config = &s5p64x0_gpio_cfgs[1],
349 .chip = {
350 .base = S5P6450_GPK(0),
351 .ngpio = S5P6450_GPIO_K_NR,
352 .label = "GPK",
353 },
354 },
355};
356
357static struct s3c_gpio_chip s5p6450_gpio_4bit2[] = {
358 {
359 .base = S5P64X0_GPG_BASE + 0x4,
360 .config = &s5p64x0_gpio_cfgs[1],
361 .chip = {
362 .base = S5P6450_GPG(0),
363 .ngpio = S5P6450_GPIO_G_NR,
364 .label = "GPG",
365 },
366 }, {
367 .base = S5P64X0_GPH_BASE + 0x4,
368 .config = &s5p64x0_gpio_cfgs[1],
369 .chip = {
370 .base = S5P6450_GPH(0),
371 .ngpio = S5P6450_GPIO_H_NR,
372 .label = "GPH",
373 },
374 },
375};
376
377static struct s3c_gpio_chip s5p6450_gpio_rbank_4bit2[] = {
378 {
379 .base = S5P64X0_GPR_BASE + 0x4,
380 .config = &s5p64x0_gpio_cfgs[2],
381 .chip = {
382 .base = S5P6450_GPR(0),
383 .ngpio = S5P6450_GPIO_R_NR,
384 .label = "GPR",
385 },
386 },
387};
388
389static struct s3c_gpio_chip s5p6450_gpio_2bit[] = {
390 {
391 .base = S5P64X0_GPF_BASE,
392 .config = &s5p64x0_gpio_cfgs[5],
393 .chip = {
394 .base = S5P6450_GPF(0),
395 .ngpio = S5P6450_GPIO_F_NR,
396 .label = "GPF",
397 },
398 }, {
399 .base = S5P64X0_GPI_BASE,
400 .config = &s5p64x0_gpio_cfgs[3],
401 .chip = {
402 .base = S5P6450_GPI(0),
403 .ngpio = S5P6450_GPIO_I_NR,
404 .label = "GPI",
405 },
406 }, {
407 .base = S5P64X0_GPJ_BASE,
408 .config = &s5p64x0_gpio_cfgs[3],
409 .chip = {
410 .base = S5P6450_GPJ(0),
411 .ngpio = S5P6450_GPIO_J_NR,
412 .label = "GPJ",
413 },
414 }, {
415 .base = S5P64X0_GPN_BASE,
416 .config = &s5p64x0_gpio_cfgs[4],
417 .chip = {
418 .base = S5P6450_GPN(0),
419 .ngpio = S5P6450_GPIO_N_NR,
420 .label = "GPN",
421 },
422 }, {
423 .base = S5P64X0_GPP_BASE,
424 .config = &s5p64x0_gpio_cfgs[5],
425 .chip = {
426 .base = S5P6450_GPP(0),
427 .ngpio = S5P6450_GPIO_P_NR,
428 .label = "GPP",
429 },
430 }, {
431 .base = S5P6450_GPQ_BASE,
432 .config = &s5p64x0_gpio_cfgs[4],
433 .chip = {
434 .base = S5P6450_GPQ(0),
435 .ngpio = S5P6450_GPIO_Q_NR,
436 .label = "GPQ",
437 },
438 }, {
439 .base = S5P6450_GPS_BASE,
440 .config = &s5p64x0_gpio_cfgs[5],
441 .chip = {
442 .base = S5P6450_GPS(0),
443 .ngpio = S5P6450_GPIO_S_NR,
444 .label = "GPS",
445 },
446 },
447};
448
295void __init s5p64x0_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips) 449void __init s5p64x0_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
296{ 450{
297 for (; nr_chips > 0; nr_chips--, chipcfg++) { 451 for (; nr_chips > 0; nr_chips--, chipcfg++) {
@@ -317,26 +471,41 @@ static void __init s5p64x0_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
317 } 471 }
318} 472}
319 473
320static int __init s5p6440_gpiolib_init(void) 474static int __init s5p64x0_gpiolib_init(void)
321{ 475{
322 struct s3c_gpio_chip *chips = s5p6440_gpio_2bit; 476 unsigned int chipid;
323 int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit); 477
478 chipid = __raw_readl(S5P64X0_SYS_ID);
324 479
325 s5p64x0_gpiolib_set_cfg(s5p64x0_gpio_cfgs, 480 s5p64x0_gpiolib_set_cfg(s5p64x0_gpio_cfgs,
326 ARRAY_SIZE(s5p64x0_gpio_cfgs)); 481 ARRAY_SIZE(s5p64x0_gpio_cfgs));
327 482
328 for (; nr_chips > 0; nr_chips--, chips++) 483 if ((chipid & 0xff000) == 0x50000) {
329 s3c_gpiolib_add(chips); 484 samsung_gpiolib_add_2bit_chips(s5p6450_gpio_2bit,
485 ARRAY_SIZE(s5p6450_gpio_2bit));
486
487 samsung_gpiolib_add_4bit_chips(s5p6450_gpio_4bit,
488 ARRAY_SIZE(s5p6450_gpio_4bit));
330 489
331 samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit, 490 samsung_gpiolib_add_4bit2_chips(s5p6450_gpio_4bit2,
332 ARRAY_SIZE(s5p6440_gpio_4bit)); 491 ARRAY_SIZE(s5p6450_gpio_4bit2));
333 492
334 samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2, 493 s5p64x0_gpio_add_rbank_4bit2(s5p6450_gpio_rbank_4bit2,
335 ARRAY_SIZE(s5p6440_gpio_4bit2)); 494 ARRAY_SIZE(s5p6450_gpio_rbank_4bit2));
495 } else {
496 samsung_gpiolib_add_2bit_chips(s5p6440_gpio_2bit,
497 ARRAY_SIZE(s5p6440_gpio_2bit));
336 498
337 s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2, 499 samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit,
338 ARRAY_SIZE(s5p6440_gpio_rbank_4bit2)); 500 ARRAY_SIZE(s5p6440_gpio_4bit));
501
502 samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
503 ARRAY_SIZE(s5p6440_gpio_4bit2));
504
505 s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2,
506 ARRAY_SIZE(s5p6440_gpio_rbank_4bit2));
507 }
339 508
340 return 0; 509 return 0;
341} 510}
342arch_initcall(s5p6440_gpiolib_init); 511core_initcall(s5p64x0_gpiolib_init);
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
index 31e534156e06..a9365e5ba614 100644
--- a/arch/arm/mach-s5p64x0/include/mach/map.h
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -29,6 +29,9 @@
29#define S5P64X0_PA_VIC0 (0xE4000000) 29#define S5P64X0_PA_VIC0 (0xE4000000)
30#define S5P64X0_PA_VIC1 (0xE4100000) 30#define S5P64X0_PA_VIC1 (0xE4100000)
31 31
32#define S5P64X0_PA_SROMC (0xE7000000)
33#define S5P_PA_SROMC S5P64X0_PA_SROMC
34
32#define S5P64X0_PA_PDMA (0xE9000000) 35#define S5P64X0_PA_PDMA (0xE9000000)
33 36
34#define S5P64X0_PA_TIMER (0xEA000000) 37#define S5P64X0_PA_TIMER (0xEA000000)
@@ -63,6 +66,8 @@
63#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000)) 66#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000))
64 67
65#define S5P64X0_PA_I2S (0xF2000000) 68#define S5P64X0_PA_I2S (0xF2000000)
69#define S5P6450_PA_I2S1 0xF2800000
70#define S5P6450_PA_I2S2 0xF2900000
66 71
67#define S5P64X0_PA_PCM (0xF2100000) 72#define S5P64X0_PA_PCM (0xF2100000)
68 73
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
index 85f448e20a8b..0953ef6b1c77 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
@@ -15,48 +15,23 @@
15 15
16#include <mach/map.h> 16#include <mach/map.h>
17 17
18/* Will be implemented S5P6442 GPIOlib */
19
20/* Base addresses for each of the banks */ 18/* Base addresses for each of the banks */
21 19
22#define S5P6440_GPA_BASE (S5P_VA_GPIO + 0x0000) 20#define S5P64X0_GPA_BASE (S5P_VA_GPIO + 0x0000)
23#define S5P6440_GPB_BASE (S5P_VA_GPIO + 0x0020) 21#define S5P64X0_GPB_BASE (S5P_VA_GPIO + 0x0020)
24#define S5P6440_GPC_BASE (S5P_VA_GPIO + 0x0040) 22#define S5P64X0_GPC_BASE (S5P_VA_GPIO + 0x0040)
25#define S5P6440_GPF_BASE (S5P_VA_GPIO + 0x00A0) 23#define S5P64X0_GPF_BASE (S5P_VA_GPIO + 0x00A0)
26#define S5P6440_GPG_BASE (S5P_VA_GPIO + 0x00C0) 24#define S5P64X0_GPG_BASE (S5P_VA_GPIO + 0x00C0)
27#define S5P6440_GPH_BASE (S5P_VA_GPIO + 0x00E0) 25#define S5P64X0_GPH_BASE (S5P_VA_GPIO + 0x00E0)
28#define S5P6440_GPI_BASE (S5P_VA_GPIO + 0x0100) 26#define S5P64X0_GPI_BASE (S5P_VA_GPIO + 0x0100)
29#define S5P6440_GPJ_BASE (S5P_VA_GPIO + 0x0120) 27#define S5P64X0_GPJ_BASE (S5P_VA_GPIO + 0x0120)
30#define S5P6440_GPN_BASE (S5P_VA_GPIO + 0x0830) 28#define S5P64X0_GPN_BASE (S5P_VA_GPIO + 0x0830)
31#define S5P6440_GPP_BASE (S5P_VA_GPIO + 0x0160) 29#define S5P64X0_GPP_BASE (S5P_VA_GPIO + 0x0160)
32#define S5P6440_GPR_BASE (S5P_VA_GPIO + 0x0290) 30#define S5P64X0_GPR_BASE (S5P_VA_GPIO + 0x0290)
33 31
34#define S5P6440_EINT0CON0 (S5P_VA_GPIO + 0x900) 32#define S5P6450_GPD_BASE (S5P_VA_GPIO + 0x0060)
35#define S5P6440_EINT0FLTCON0 (S5P_VA_GPIO + 0x910) 33#define S5P6450_GPK_BASE (S5P_VA_GPIO + 0x0140)
36#define S5P6440_EINT0FLTCON1 (S5P_VA_GPIO + 0x914) 34#define S5P6450_GPQ_BASE (S5P_VA_GPIO + 0x0180)
37#define S5P6440_EINT0MASK (S5P_VA_GPIO + 0x920) 35#define S5P6450_GPS_BASE (S5P_VA_GPIO + 0x0300)
38#define S5P6440_EINT0PEND (S5P_VA_GPIO + 0x924)
39
40/* for LCD */
41
42#define S5P6440_SPCON_LCD_SEL_RGB (1 << 0)
43#define S5P6440_SPCON_LCD_SEL_MASK (3 << 0)
44
45/*
46 * These set of macros are not really useful for the
47 * GPF/GPI/GPJ/GPN/GPP, useful for others set of GPIO's (4 bit)
48 */
49
50#define S5P6440_GPIO_CONMASK(__gpio) (0xf << ((__gpio) * 4))
51#define S5P6440_GPIO_INPUT(__gpio) (0x0 << ((__gpio) * 4))
52#define S5P6440_GPIO_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
53
54/*
55 * Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
56 */
57
58#define S5P6440_GPIO2_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
59#define S5P6440_GPIO2_INPUT(__gpio) (0x0 << ((__gpio) * 2))
60#define S5P6440_GPIO2_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
61 36
62#endif /* __ASM_ARCH_REGS_GPIO_H */ 37#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 87c3f03c618c..e9802755daeb 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -117,6 +117,7 @@ static struct s3c2410_platform_i2c s5p6440_i2c1_data __initdata = {
117 117
118static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = { 118static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = {
119 { I2C_BOARD_INFO("24c08", 0x50), }, 119 { I2C_BOARD_INFO("24c08", 0x50), },
120 { I2C_BOARD_INFO("wm8580", 0x1b), },
120}; 121};
121 122
122static struct i2c_board_info smdk6440_i2c_devs1[] __initdata = { 123static struct i2c_board_info smdk6440_i2c_devs1[] __initdata = {
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index d609f5af2b98..b78f56292780 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -135,6 +135,7 @@ static struct s3c2410_platform_i2c s5p6450_i2c1_data __initdata = {
135}; 135};
136 136
137static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = { 137static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = {
138 { I2C_BOARD_INFO("wm8580", 0x1b), },
138 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */ 139 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */
139}; 140};
140 141
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index 2d4a761a5163..0305e9b8282d 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -396,7 +396,7 @@ static int s5pc100_sclk1_ctrl(struct clk *clk, int enable)
396 * recommended to keep the following clocks disabled until the driver requests 396 * recommended to keep the following clocks disabled until the driver requests
397 * for enabling the clock. 397 * for enabling the clock.
398 */ 398 */
399static struct clk init_clocks_disable[] = { 399static struct clk init_clocks_off[] = {
400 { 400 {
401 .name = "cssys", 401 .name = "cssys",
402 .id = -1, 402 .id = -1,
@@ -1381,8 +1381,6 @@ static struct clk *clks[] __initdata = {
1381 1381
1382void __init s5pc100_register_clocks(void) 1382void __init s5pc100_register_clocks(void)
1383{ 1383{
1384 struct clk *clkp;
1385 int ret;
1386 int ptr; 1384 int ptr;
1387 1385
1388 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); 1386 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
@@ -1393,16 +1391,8 @@ void __init s5pc100_register_clocks(void)
1393 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1391 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1394 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1392 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1395 1393
1396 clkp = init_clocks_disable; 1394 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1397 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 1395 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1398
1399 ret = s3c24xx_register_clock(clkp);
1400 if (ret < 0) {
1401 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1402 clkp->name, ret);
1403 }
1404 (clkp->enable)(clkp, 0);
1405 }
1406 1396
1407 s3c_pwmclk_init(); 1397 s3c_pwmclk_init();
1408} 1398}
diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c
index 564e195ec493..10ab275ebd63 100644
--- a/arch/arm/mach-s5pc100/dev-audio.c
+++ b/arch/arm/mach-s5pc100/dev-audio.c
@@ -23,17 +23,14 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
23{ 23{
24 /* configure GPIO for i2s port */ 24 /* configure GPIO for i2s port */
25 switch (pdev->id) { 25 switch (pdev->id) {
26 case 0: /* Dedicated pins */
27 break;
26 case 1: 28 case 1:
27 s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2)); 29 s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
28 break; 30 break;
29
30 case 2: 31 case 2:
31 s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4)); 32 s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
32 break; 33 break;
33
34 case -1: /* Dedicated pins */
35 break;
36
37 default: 34 default:
38 printk(KERN_ERR "Invalid Device %d\n", pdev->id); 35 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
39 return -EINVAL; 36 return -EINVAL;
@@ -42,8 +39,20 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
42 return 0; 39 return 0;
43} 40}
44 41
45static struct s3c_audio_pdata s3c_i2s_pdata = { 42static const char *rclksrc_v5[] = {
43 [0] = "iis",
44 [1] = "i2sclkd2",
45};
46
47static struct s3c_audio_pdata i2sv5_pdata = {
46 .cfg_gpio = s5pc100_cfg_i2s, 48 .cfg_gpio = s5pc100_cfg_i2s,
49 .type = {
50 .i2s = {
51 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
52 | QUIRK_NEED_RSTCLR,
53 .src_clk = rclksrc_v5,
54 },
55 },
47}; 56};
48 57
49static struct resource s5pc100_iis0_resource[] = { 58static struct resource s5pc100_iis0_resource[] = {
@@ -62,15 +71,34 @@ static struct resource s5pc100_iis0_resource[] = {
62 .end = DMACH_I2S0_RX, 71 .end = DMACH_I2S0_RX,
63 .flags = IORESOURCE_DMA, 72 .flags = IORESOURCE_DMA,
64 }, 73 },
74 [3] = {
75 .start = DMACH_I2S0S_TX,
76 .end = DMACH_I2S0S_TX,
77 .flags = IORESOURCE_DMA,
78 },
65}; 79};
66 80
67struct platform_device s5pc100_device_iis0 = { 81struct platform_device s5pc100_device_iis0 = {
68 .name = "s3c64xx-iis-v4", 82 .name = "samsung-i2s",
69 .id = -1, 83 .id = 0,
70 .num_resources = ARRAY_SIZE(s5pc100_iis0_resource), 84 .num_resources = ARRAY_SIZE(s5pc100_iis0_resource),
71 .resource = s5pc100_iis0_resource, 85 .resource = s5pc100_iis0_resource,
72 .dev = { 86 .dev = {
73 .platform_data = &s3c_i2s_pdata, 87 .platform_data = &i2sv5_pdata,
88 },
89};
90
91static const char *rclksrc_v3[] = {
92 [0] = "iis",
93 [1] = "sclk_audio",
94};
95
96static struct s3c_audio_pdata i2sv3_pdata = {
97 .cfg_gpio = s5pc100_cfg_i2s,
98 .type = {
99 .i2s = {
100 .src_clk = rclksrc_v3,
101 },
74 }, 102 },
75}; 103};
76 104
@@ -93,12 +121,12 @@ static struct resource s5pc100_iis1_resource[] = {
93}; 121};
94 122
95struct platform_device s5pc100_device_iis1 = { 123struct platform_device s5pc100_device_iis1 = {
96 .name = "s3c64xx-iis", 124 .name = "samsung-i2s",
97 .id = 1, 125 .id = 1,
98 .num_resources = ARRAY_SIZE(s5pc100_iis1_resource), 126 .num_resources = ARRAY_SIZE(s5pc100_iis1_resource),
99 .resource = s5pc100_iis1_resource, 127 .resource = s5pc100_iis1_resource,
100 .dev = { 128 .dev = {
101 .platform_data = &s3c_i2s_pdata, 129 .platform_data = &i2sv3_pdata,
102 }, 130 },
103}; 131};
104 132
@@ -121,12 +149,12 @@ static struct resource s5pc100_iis2_resource[] = {
121}; 149};
122 150
123struct platform_device s5pc100_device_iis2 = { 151struct platform_device s5pc100_device_iis2 = {
124 .name = "s3c64xx-iis", 152 .name = "samsung-i2s",
125 .id = 2, 153 .id = 2,
126 .num_resources = ARRAY_SIZE(s5pc100_iis2_resource), 154 .num_resources = ARRAY_SIZE(s5pc100_iis2_resource),
127 .resource = s5pc100_iis2_resource, 155 .resource = s5pc100_iis2_resource,
128 .dev = { 156 .dev = {
129 .platform_data = &s3c_i2s_pdata, 157 .platform_data = &i2sv3_pdata,
130 }, 158 },
131}; 159};
132 160
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index 32e9cab5c864..328467b346aa 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -55,6 +55,8 @@
55#define S5PC100_VA_VIC_OFFSET 0x10000 55#define S5PC100_VA_VIC_OFFSET 0x10000
56#define S5PC1XX_VA_VIC(x) (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET)) 56#define S5PC1XX_VA_VIC(x) (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
57 57
58#define S5PC100_PA_SROMC (0xE7000000)
59#define S5P_PA_SROMC S5PC100_PA_SROMC
58 60
59#define S5PC100_PA_ONENAND (0xE7100000) 61#define S5PC100_PA_ONENAND (0xE7100000)
60 62
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 862f239a0fdb..53aabef1e9ce 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -118,6 +118,7 @@ menu "S5PV210 Machines"
118config MACH_SMDKV210 118config MACH_SMDKV210
119 bool "SMDKV210" 119 bool "SMDKV210"
120 select CPU_S5PV210 120 select CPU_S5PV210
121 select S3C_DEV_FB
121 select S3C_DEV_HSMMC 122 select S3C_DEV_HSMMC
122 select S3C_DEV_HSMMC1 123 select S3C_DEV_HSMMC1
123 select S3C_DEV_HSMMC2 124 select S3C_DEV_HSMMC2
@@ -130,6 +131,7 @@ config MACH_SMDKV210
130 select SAMSUNG_DEV_IDE 131 select SAMSUNG_DEV_IDE
131 select SAMSUNG_DEV_KEYPAD 132 select SAMSUNG_DEV_KEYPAD
132 select SAMSUNG_DEV_TS 133 select SAMSUNG_DEV_TS
134 select S5PV210_SETUP_FB_24BPP
133 select S5PV210_SETUP_I2C1 135 select S5PV210_SETUP_I2C1
134 select S5PV210_SETUP_I2C2 136 select S5PV210_SETUP_I2C2
135 select S5PV210_SETUP_IDE 137 select S5PV210_SETUP_IDE
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 019c3a69b0e4..2d599499cefe 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -309,7 +309,7 @@ static struct clk_ops clk_fout_apll_ops = {
309 .get_rate = s5pv210_clk_fout_apll_get_rate, 309 .get_rate = s5pv210_clk_fout_apll_get_rate,
310}; 310};
311 311
312static struct clk init_clocks_disable[] = { 312static struct clk init_clocks_off[] = {
313 { 313 {
314 .name = "pdma", 314 .name = "pdma",
315 .id = 0, 315 .id = 0,
@@ -467,20 +467,20 @@ static struct clk init_clocks_disable[] = {
467 .enable = s5pv210_clk_ip3_ctrl, 467 .enable = s5pv210_clk_ip3_ctrl,
468 .ctrlbit = (1<<21), 468 .ctrlbit = (1<<21),
469 }, { 469 }, {
470 .name = "i2s_v50", 470 .name = "iis",
471 .id = 0, 471 .id = 0,
472 .parent = &clk_p, 472 .parent = &clk_p,
473 .enable = s5pv210_clk_ip3_ctrl, 473 .enable = s5pv210_clk_ip3_ctrl,
474 .ctrlbit = (1<<4), 474 .ctrlbit = (1<<4),
475 }, { 475 }, {
476 .name = "i2s_v32", 476 .name = "iis",
477 .id = 0, 477 .id = 1,
478 .parent = &clk_p, 478 .parent = &clk_p,
479 .enable = s5pv210_clk_ip3_ctrl, 479 .enable = s5pv210_clk_ip3_ctrl,
480 .ctrlbit = (1 << 5), 480 .ctrlbit = (1 << 5),
481 }, { 481 }, {
482 .name = "i2s_v32", 482 .name = "iis",
483 .id = 1, 483 .id = 2,
484 .parent = &clk_p, 484 .parent = &clk_p,
485 .enable = s5pv210_clk_ip3_ctrl, 485 .enable = s5pv210_clk_ip3_ctrl,
486 .ctrlbit = (1 << 6), 486 .ctrlbit = (1 << 6),
@@ -525,6 +525,12 @@ static struct clk init_clocks[] = {
525 .parent = &clk_pclk_psys.clk, 525 .parent = &clk_pclk_psys.clk,
526 .enable = s5pv210_clk_ip3_ctrl, 526 .enable = s5pv210_clk_ip3_ctrl,
527 .ctrlbit = (1 << 20), 527 .ctrlbit = (1 << 20),
528 }, {
529 .name = "sromc",
530 .id = -1,
531 .parent = &clk_hclk_psys.clk,
532 .enable = s5pv210_clk_ip1_ctrl,
533 .ctrlbit = (1 << 26),
528 }, 534 },
529}; 535};
530 536
@@ -1220,13 +1226,9 @@ static struct clk *clks[] __initdata = {
1220 1226
1221void __init s5pv210_register_clocks(void) 1227void __init s5pv210_register_clocks(void)
1222{ 1228{
1223 struct clk *clkp;
1224 int ret;
1225 int ptr; 1229 int ptr;
1226 1230
1227 ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); 1231 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1228 if (ret > 0)
1229 printk(KERN_ERR "Failed to register %u clocks\n", ret);
1230 1232
1231 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) 1233 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1232 s3c_register_clksrc(sysclks[ptr], 1); 1234 s3c_register_clksrc(sysclks[ptr], 1);
@@ -1234,15 +1236,8 @@ void __init s5pv210_register_clocks(void)
1234 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1236 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1235 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1237 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1236 1238
1237 clkp = init_clocks_disable; 1239 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1238 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 1240 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1239 ret = s3c24xx_register_clock(clkp);
1240 if (ret < 0) {
1241 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1242 clkp->name, ret);
1243 }
1244 (clkp->enable)(clkp, 0);
1245 }
1246 1241
1247 s3c_pwmclk_init(); 1242 s3c_pwmclk_init();
1248} 1243}
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 8eb480e201b0..61e6c24b90ac 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -81,11 +81,6 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
81 .length = SZ_512K, 81 .length = SZ_512K,
82 .type = MT_DEVICE, 82 .type = MT_DEVICE,
83 }, { 83 }, {
84 .virtual = (unsigned long)S5P_VA_SROMC,
85 .pfn = __phys_to_pfn(S5PV210_PA_SROMC),
86 .length = SZ_4K,
87 .type = MT_DEVICE,
88 }, {
89 .virtual = (unsigned long)S5P_VA_DMC0, 84 .virtual = (unsigned long)S5P_VA_DMC0,
90 .pfn = __phys_to_pfn(S5PV210_PA_DMC0), 85 .pfn = __phys_to_pfn(S5PV210_PA_DMC0),
91 .length = SZ_4K, 86 .length = SZ_4K,
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
index 1303fcb12b51..ddd2704b3467 100644
--- a/arch/arm/mach-s5pv210/dev-audio.c
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -19,22 +19,24 @@
19#include <mach/dma.h> 19#include <mach/dma.h>
20#include <mach/irqs.h> 20#include <mach/irqs.h>
21 21
22static const char *rclksrc[] = {
23 [0] = "busclk",
24 [1] = "i2sclk",
25};
26
22static int s5pv210_cfg_i2s(struct platform_device *pdev) 27static int s5pv210_cfg_i2s(struct platform_device *pdev)
23{ 28{
24 /* configure GPIO for i2s port */ 29 /* configure GPIO for i2s port */
25 switch (pdev->id) { 30 switch (pdev->id) {
31 case 0:
32 s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
33 break;
26 case 1: 34 case 1:
27 s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2)); 35 s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
28 break; 36 break;
29
30 case 2: 37 case 2:
31 s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4)); 38 s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
32 break; 39 break;
33
34 case -1:
35 s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
36 break;
37
38 default: 40 default:
39 printk(KERN_ERR "Invalid Device %d\n", pdev->id); 41 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
40 return -EINVAL; 42 return -EINVAL;
@@ -43,8 +45,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev)
43 return 0; 45 return 0;
44} 46}
45 47
46static struct s3c_audio_pdata s3c_i2s_pdata = { 48static struct s3c_audio_pdata i2sv5_pdata = {
47 .cfg_gpio = s5pv210_cfg_i2s, 49 .cfg_gpio = s5pv210_cfg_i2s,
50 .type = {
51 .i2s = {
52 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
53 | QUIRK_NEED_RSTCLR,
54 .src_clk = rclksrc,
55 },
56 },
48}; 57};
49 58
50static struct resource s5pv210_iis0_resource[] = { 59static struct resource s5pv210_iis0_resource[] = {
@@ -63,15 +72,34 @@ static struct resource s5pv210_iis0_resource[] = {
63 .end = DMACH_I2S0_RX, 72 .end = DMACH_I2S0_RX,
64 .flags = IORESOURCE_DMA, 73 .flags = IORESOURCE_DMA,
65 }, 74 },
75 [3] = {
76 .start = DMACH_I2S0S_TX,
77 .end = DMACH_I2S0S_TX,
78 .flags = IORESOURCE_DMA,
79 },
66}; 80};
67 81
68struct platform_device s5pv210_device_iis0 = { 82struct platform_device s5pv210_device_iis0 = {
69 .name = "s3c64xx-iis-v4", 83 .name = "samsung-i2s",
70 .id = -1, 84 .id = 0,
71 .num_resources = ARRAY_SIZE(s5pv210_iis0_resource), 85 .num_resources = ARRAY_SIZE(s5pv210_iis0_resource),
72 .resource = s5pv210_iis0_resource, 86 .resource = s5pv210_iis0_resource,
73 .dev = { 87 .dev = {
74 .platform_data = &s3c_i2s_pdata, 88 .platform_data = &i2sv5_pdata,
89 },
90};
91
92static const char *rclksrc_v3[] = {
93 [0] = "iis",
94 [1] = "audio-bus",
95};
96
97static struct s3c_audio_pdata i2sv3_pdata = {
98 .cfg_gpio = s5pv210_cfg_i2s,
99 .type = {
100 .i2s = {
101 .src_clk = rclksrc_v3,
102 },
75 }, 103 },
76}; 104};
77 105
@@ -94,12 +122,12 @@ static struct resource s5pv210_iis1_resource[] = {
94}; 122};
95 123
96struct platform_device s5pv210_device_iis1 = { 124struct platform_device s5pv210_device_iis1 = {
97 .name = "s3c64xx-iis", 125 .name = "samsung-i2s",
98 .id = 1, 126 .id = 1,
99 .num_resources = ARRAY_SIZE(s5pv210_iis1_resource), 127 .num_resources = ARRAY_SIZE(s5pv210_iis1_resource),
100 .resource = s5pv210_iis1_resource, 128 .resource = s5pv210_iis1_resource,
101 .dev = { 129 .dev = {
102 .platform_data = &s3c_i2s_pdata, 130 .platform_data = &i2sv3_pdata,
103 }, 131 },
104}; 132};
105 133
@@ -122,12 +150,12 @@ static struct resource s5pv210_iis2_resource[] = {
122}; 150};
123 151
124struct platform_device s5pv210_device_iis2 = { 152struct platform_device s5pv210_device_iis2 = {
125 .name = "s3c64xx-iis", 153 .name = "samsung-i2s",
126 .id = 2, 154 .id = 2,
127 .num_resources = ARRAY_SIZE(s5pv210_iis2_resource), 155 .num_resources = ARRAY_SIZE(s5pv210_iis2_resource),
128 .resource = s5pv210_iis2_resource, 156 .resource = s5pv210_iis2_resource,
129 .dev = { 157 .dev = {
130 .platform_data = &s3c_i2s_pdata, 158 .platform_data = &i2sv3_pdata,
131 }, 159 },
132}; 160};
133 161
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index 119b95fdc3ce..26710b35ef87 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -65,7 +65,7 @@
65#define IRQ_HSMMC0 S5P_IRQ_VIC1(26) 65#define IRQ_HSMMC0 S5P_IRQ_VIC1(26)
66#define IRQ_HSMMC1 S5P_IRQ_VIC1(27) 66#define IRQ_HSMMC1 S5P_IRQ_VIC1(27)
67#define IRQ_HSMMC2 S5P_IRQ_VIC1(28) 67#define IRQ_HSMMC2 S5P_IRQ_VIC1(28)
68#define IRQ_MIPICSI S5P_IRQ_VIC1(29) 68#define IRQ_MIPI_CSIS S5P_IRQ_VIC1(29)
69#define IRQ_MIPIDSI S5P_IRQ_VIC1(30) 69#define IRQ_MIPIDSI S5P_IRQ_VIC1(30)
70#define IRQ_ONENAND_AUDI S5P_IRQ_VIC1(31) 70#define IRQ_ONENAND_AUDI S5P_IRQ_VIC1(31)
71 71
@@ -132,5 +132,6 @@
132#define IRQ_LCD_FIFO IRQ_LCD0 132#define IRQ_LCD_FIFO IRQ_LCD0
133#define IRQ_LCD_VSYNC IRQ_LCD1 133#define IRQ_LCD_VSYNC IRQ_LCD1
134#define IRQ_LCD_SYSTEM IRQ_LCD2 134#define IRQ_LCD_SYSTEM IRQ_LCD2
135#define IRQ_MIPI_CSIS0 IRQ_MIPI_CSIS
135 136
136#endif /* ASM_ARCH_IRQS_H */ 137#endif /* ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index 861d7fe11fc9..3611492ad681 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -16,6 +16,8 @@
16#include <plat/map-base.h> 16#include <plat/map-base.h>
17#include <plat/map-s5p.h> 17#include <plat/map-s5p.h>
18 18
19#define S5PV210_PA_SROM_BANK5 (0xA8000000)
20
19#define S5PC110_PA_ONENAND (0xB0000000) 21#define S5PC110_PA_ONENAND (0xB0000000)
20#define S5P_PA_ONENAND S5PC110_PA_ONENAND 22#define S5P_PA_ONENAND S5PC110_PA_ONENAND
21 23
@@ -60,6 +62,7 @@
60#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) 62#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
61 63
62#define S5PV210_PA_SROMC (0xE8000000) 64#define S5PV210_PA_SROMC (0xE8000000)
65#define S5P_PA_SROMC S5PV210_PA_SROMC
63 66
64#define S5PV210_PA_CFCON (0xE8200000) 67#define S5PV210_PA_CFCON (0xE8200000)
65 68
@@ -107,6 +110,8 @@
107#define S5PV210_PA_DMC0 (0xF0000000) 110#define S5PV210_PA_DMC0 (0xF0000000)
108#define S5PV210_PA_DMC1 (0xF1400000) 111#define S5PV210_PA_DMC1 (0xF1400000)
109 112
113#define S5PV210_PA_MIPI_CSIS 0xFA600000
114
110/* compatibiltiy defines. */ 115/* compatibiltiy defines. */
111#define S3C_PA_UART S5PV210_PA_UART 116#define S3C_PA_UART S5PV210_PA_UART
112#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0) 117#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0)
@@ -123,6 +128,7 @@
123#define S5P_PA_FIMC0 S5PV210_PA_FIMC0 128#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
124#define S5P_PA_FIMC1 S5PV210_PA_FIMC1 129#define S5P_PA_FIMC1 S5PV210_PA_FIMC1
125#define S5P_PA_FIMC2 S5PV210_PA_FIMC2 130#define S5P_PA_FIMC2 S5PV210_PA_FIMC2
131#define S5P_PA_MIPI_CSIS0 S5PV210_PA_MIPI_CSIS
126 132
127#define SAMSUNG_PA_ADC S5PV210_PA_ADC 133#define SAMSUNG_PA_ADC S5PV210_PA_ADC
128#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON 134#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index ebaabe021af9..4c45b74def5f 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -161,7 +161,7 @@
161#define S5P_MDNIE_SEL S5P_CLKREG(0x7008) 161#define S5P_MDNIE_SEL S5P_CLKREG(0x7008)
162#define S5P_MIPI_PHY_CON0 S5P_CLKREG(0x7200) 162#define S5P_MIPI_PHY_CON0 S5P_CLKREG(0x7200)
163#define S5P_MIPI_PHY_CON1 S5P_CLKREG(0x7204) 163#define S5P_MIPI_PHY_CON1 S5P_CLKREG(0x7204)
164#define S5P_MIPI_CONTROL S5P_CLKREG(0xE814) 164#define S5P_MIPI_DPHY_CONTROL S5P_CLKREG(0xE814)
165 165
166#define S5P_IDLE_CFG_TL_MASK (3 << 30) 166#define S5P_IDLE_CFG_TL_MASK (3 << 30)
167#define S5P_IDLE_CFG_TM_MASK (3 << 28) 167#define S5P_IDLE_CFG_TM_MASK (3 << 28)
@@ -195,9 +195,6 @@
195#define S5P_OTHERS_RET_UART (1 << 28) 195#define S5P_OTHERS_RET_UART (1 << 28)
196#define S5P_OTHERS_USB_SIG_MASK (1 << 16) 196#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
197 197
198/* MIPI */
199#define S5P_MIPI_DPHY_EN (3)
200
201/* S5P_DAC_CONTROL */ 198/* S5P_DAC_CONTROL */
202#define S5P_DAC_ENABLE (1) 199#define S5P_DAC_ENABLE (1)
203#define S5P_DAC_DISABLE (0) 200#define S5P_DAC_DISABLE (0)
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index 5dd1681c069e..bb20a14da100 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -94,6 +94,7 @@ static struct platform_device *smdkc110_devices[] __initdata = {
94 94
95static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = { 95static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = {
96 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */ 96 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
97 { I2C_BOARD_INFO("wm8580", 0x1b), },
97}; 98};
98 99
99static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = { 100static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = {
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index 1fbc45b2a432..88e45223c8af 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -14,16 +14,25 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/serial_core.h> 15#include <linux/serial_core.h>
16#include <linux/sysdev.h> 16#include <linux/sysdev.h>
17#include <linux/dm9000.h>
18#include <linux/fb.h>
19#include <linux/gpio.h>
20#include <linux/delay.h>
17 21
18#include <asm/mach/arch.h> 22#include <asm/mach/arch.h>
19#include <asm/mach/map.h> 23#include <asm/mach/map.h>
20#include <asm/setup.h> 24#include <asm/setup.h>
21#include <asm/mach-types.h> 25#include <asm/mach-types.h>
22 26
27#include <video/platform_lcd.h>
28
23#include <mach/map.h> 29#include <mach/map.h>
24#include <mach/regs-clock.h> 30#include <mach/regs-clock.h>
31#include <mach/regs-fb.h>
25 32
26#include <plat/regs-serial.h> 33#include <plat/regs-serial.h>
34#include <plat/regs-srom.h>
35#include <plat/gpio-cfg.h>
27#include <plat/s5pv210.h> 36#include <plat/s5pv210.h>
28#include <plat/devs.h> 37#include <plat/devs.h>
29#include <plat/cpu.h> 38#include <plat/cpu.h>
@@ -33,6 +42,7 @@
33#include <plat/iic.h> 42#include <plat/iic.h>
34#include <plat/keypad.h> 43#include <plat/keypad.h>
35#include <plat/pm.h> 44#include <plat/pm.h>
45#include <plat/fb.h>
36 46
37/* Following are default values for UCON, ULCON and UFCON UART registers */ 47/* Following are default values for UCON, ULCON and UFCON UART registers */
38#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 48#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -102,12 +112,106 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
102 .cols = 8, 112 .cols = 8,
103}; 113};
104 114
115static struct resource smdkv210_dm9000_resources[] = {
116 [0] = {
117 .start = S5PV210_PA_SROM_BANK5,
118 .end = S5PV210_PA_SROM_BANK5,
119 .flags = IORESOURCE_MEM,
120 },
121 [1] = {
122 .start = S5PV210_PA_SROM_BANK5 + 2,
123 .end = S5PV210_PA_SROM_BANK5 + 2,
124 .flags = IORESOURCE_MEM,
125 },
126 [2] = {
127 .start = IRQ_EINT(9),
128 .end = IRQ_EINT(9),
129 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
130 },
131};
132
133static struct dm9000_plat_data smdkv210_dm9000_platdata = {
134 .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
135 .dev_addr = { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 },
136};
137
138struct platform_device smdkv210_dm9000 = {
139 .name = "dm9000",
140 .id = -1,
141 .num_resources = ARRAY_SIZE(smdkv210_dm9000_resources),
142 .resource = smdkv210_dm9000_resources,
143 .dev = {
144 .platform_data = &smdkv210_dm9000_platdata,
145 },
146};
147
148static void smdkv210_lte480wv_set_power(struct plat_lcd_data *pd,
149 unsigned int power)
150{
151 if (power) {
152#if !defined(CONFIG_BACKLIGHT_PWM)
153 gpio_request(S5PV210_GPD0(3), "GPD0");
154 gpio_direction_output(S5PV210_GPD0(3), 1);
155 gpio_free(S5PV210_GPD0(3));
156#endif
157
158 /* fire nRESET on power up */
159 gpio_request(S5PV210_GPH0(6), "GPH0");
160
161 gpio_direction_output(S5PV210_GPH0(6), 1);
162
163 gpio_set_value(S5PV210_GPH0(6), 0);
164 mdelay(10);
165
166 gpio_set_value(S5PV210_GPH0(6), 1);
167 mdelay(10);
168
169 gpio_free(S5PV210_GPH0(6));
170 } else {
171#if !defined(CONFIG_BACKLIGHT_PWM)
172 gpio_request(S5PV210_GPD0(3), "GPD0");
173 gpio_direction_output(S5PV210_GPD0(3), 0);
174 gpio_free(S5PV210_GPD0(3));
175#endif
176 }
177}
178
179static struct plat_lcd_data smdkv210_lcd_lte480wv_data = {
180 .set_power = smdkv210_lte480wv_set_power,
181};
182
183static struct platform_device smdkv210_lcd_lte480wv = {
184 .name = "platform-lcd",
185 .dev.parent = &s3c_device_fb.dev,
186 .dev.platform_data = &smdkv210_lcd_lte480wv_data,
187};
188
189static struct s3c_fb_pd_win smdkv210_fb_win0 = {
190 .win_mode = {
191 .left_margin = 13,
192 .right_margin = 8,
193 .upper_margin = 7,
194 .lower_margin = 5,
195 .hsync_len = 3,
196 .vsync_len = 1,
197 .xres = 800,
198 .yres = 480,
199 },
200 .max_bpp = 32,
201 .default_bpp = 24,
202};
203
204static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = {
205 .win[0] = &smdkv210_fb_win0,
206 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
207 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
208 .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
209};
210
105static struct platform_device *smdkv210_devices[] __initdata = { 211static struct platform_device *smdkv210_devices[] __initdata = {
106 &s5pv210_device_iis0,
107 &s5pv210_device_ac97,
108 &s5pv210_device_spdif,
109 &s3c_device_adc, 212 &s3c_device_adc,
110 &s3c_device_cfcon, 213 &s3c_device_cfcon,
214 &s3c_device_fb,
111 &s3c_device_hsmmc0, 215 &s3c_device_hsmmc0,
112 &s3c_device_hsmmc1, 216 &s3c_device_hsmmc1,
113 &s3c_device_hsmmc2, 217 &s3c_device_hsmmc2,
@@ -115,14 +219,37 @@ static struct platform_device *smdkv210_devices[] __initdata = {
115 &s3c_device_i2c0, 219 &s3c_device_i2c0,
116 &s3c_device_i2c1, 220 &s3c_device_i2c1,
117 &s3c_device_i2c2, 221 &s3c_device_i2c2,
118 &samsung_device_keypad,
119 &s3c_device_rtc, 222 &s3c_device_rtc,
120 &s3c_device_ts, 223 &s3c_device_ts,
121 &s3c_device_wdt, 224 &s3c_device_wdt,
225 &s5pv210_device_ac97,
226 &s5pv210_device_iis0,
227 &s5pv210_device_spdif,
228 &samsung_device_keypad,
229 &smdkv210_dm9000,
230 &smdkv210_lcd_lte480wv,
122}; 231};
123 232
233static void __init smdkv210_dm9000_init(void)
234{
235 unsigned int tmp;
236
237 gpio_request(S5PV210_MP01(5), "nCS5");
238 s3c_gpio_cfgpin(S5PV210_MP01(5), S3C_GPIO_SFN(2));
239 gpio_free(S5PV210_MP01(5));
240
241 tmp = (5 << S5P_SROM_BCX__TACC__SHIFT);
242 __raw_writel(tmp, S5P_SROM_BC5);
243
244 tmp = __raw_readl(S5P_SROM_BW);
245 tmp &= (S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS5__SHIFT);
246 tmp |= (1 << S5P_SROM_BW__NCS5__SHIFT);
247 __raw_writel(tmp, S5P_SROM_BW);
248}
249
124static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = { 250static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {
125 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */ 251 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
252 { I2C_BOARD_INFO("wm8580", 0x1b), },
126}; 253};
127 254
128static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = { 255static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = {
@@ -150,6 +277,8 @@ static void __init smdkv210_machine_init(void)
150{ 277{
151 s3c_pm_init(); 278 s3c_pm_init();
152 279
280 smdkv210_dm9000_init();
281
153 samsung_keypad_set_platdata(&smdkv210_keypad_data); 282 samsung_keypad_set_platdata(&smdkv210_keypad_data);
154 s3c24xx_ts_set_platdata(&s3c_ts_platform); 283 s3c24xx_ts_set_platdata(&s3c_ts_platform);
155 284
@@ -165,6 +294,8 @@ static void __init smdkv210_machine_init(void)
165 294
166 s3c_ide_set_platdata(&smdkv210_ide_pdata); 295 s3c_ide_set_platdata(&smdkv210_ide_pdata);
167 296
297 s3c_fb_set_platdata(&smdkv210_lcd0_pdata);
298
168 platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices)); 299 platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
169} 300}
170 301
diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig
index 1150b360f38c..09c4c21b70cc 100644
--- a/arch/arm/mach-s5pv310/Kconfig
+++ b/arch/arm/mach-s5pv310/Kconfig
@@ -11,9 +11,15 @@ if ARCH_S5PV310
11 11
12config CPU_S5PV310 12config CPU_S5PV310
13 bool 13 bool
14 select S3C_PL330_DMA
14 help 15 help
15 Enable S5PV310 CPU support 16 Enable S5PV310 CPU support
16 17
18config S5PV310_DEV_PD
19 bool
20 help
21 Compile in platform device definitions for Power Domain
22
17config S5PV310_SETUP_I2C1 23config S5PV310_SETUP_I2C1
18 bool 24 bool
19 help 25 help
@@ -60,6 +66,11 @@ config S5PV310_SETUP_SDHCI_GPIO
60 help 66 help
61 Common setup code for SDHCI gpio. 67 Common setup code for SDHCI gpio.
62 68
69config S5PV310_DEV_SYSMMU
70 bool
71 help
72 Common setup code for SYSTEM MMU in S5PV310
73
63# machine support 74# machine support
64 75
65menu "S5PC210 Machines" 76menu "S5PC210 Machines"
@@ -69,11 +80,15 @@ config MACH_SMDKC210
69 select CPU_S5PV310 80 select CPU_S5PV310
70 select S3C_DEV_RTC 81 select S3C_DEV_RTC
71 select S3C_DEV_WDT 82 select S3C_DEV_WDT
83 select S3C_DEV_I2C1
72 select S3C_DEV_HSMMC 84 select S3C_DEV_HSMMC
73 select S3C_DEV_HSMMC1 85 select S3C_DEV_HSMMC1
74 select S3C_DEV_HSMMC2 86 select S3C_DEV_HSMMC2
75 select S3C_DEV_HSMMC3 87 select S3C_DEV_HSMMC3
88 select S5PV310_DEV_PD
89 select S5PV310_SETUP_I2C1
76 select S5PV310_SETUP_SDHCI 90 select S5PV310_SETUP_SDHCI
91 select S5PV310_DEV_SYSMMU
77 help 92 help
78 Machine support for Samsung SMDKC210 93 Machine support for Samsung SMDKC210
79 S5PC210(MCP) is one of package option of S5PV310 94 S5PC210(MCP) is one of package option of S5PV310
@@ -82,6 +97,10 @@ config MACH_UNIVERSAL_C210
82 bool "Mobile UNIVERSAL_C210 Board" 97 bool "Mobile UNIVERSAL_C210 Board"
83 select CPU_S5PV310 98 select CPU_S5PV310
84 select S5P_DEV_ONENAND 99 select S5P_DEV_ONENAND
100 select S3C_DEV_HSMMC
101 select S3C_DEV_HSMMC2
102 select S3C_DEV_HSMMC3
103 select S5PV310_SETUP_SDHCI
85 select S3C_DEV_I2C1 104 select S3C_DEV_I2C1
86 select S5PV310_SETUP_I2C1 105 select S5PV310_SETUP_I2C1
87 help 106 help
@@ -97,10 +116,13 @@ config MACH_SMDKV310
97 select CPU_S5PV310 116 select CPU_S5PV310
98 select S3C_DEV_RTC 117 select S3C_DEV_RTC
99 select S3C_DEV_WDT 118 select S3C_DEV_WDT
119 select S3C_DEV_I2C1
100 select S3C_DEV_HSMMC 120 select S3C_DEV_HSMMC
101 select S3C_DEV_HSMMC1 121 select S3C_DEV_HSMMC1
102 select S3C_DEV_HSMMC2 122 select S3C_DEV_HSMMC2
103 select S3C_DEV_HSMMC3 123 select S3C_DEV_HSMMC3
124 select S5PV310_DEV_PD
125 select S5PV310_SETUP_I2C1
104 select S5PV310_SETUP_SDHCI 126 select S5PV310_SETUP_SDHCI
105 help 127 help
106 Machine support for Samsung SMDKV310 128 Machine support for Samsung SMDKV310
diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile
index 84afc64e7c01..036fb383b830 100644
--- a/arch/arm/mach-s5pv310/Makefile
+++ b/arch/arm/mach-s5pv310/Makefile
@@ -13,7 +13,8 @@ obj- :=
13# Core support for S5PV310 system 13# Core support for S5PV310 system
14 14
15obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o 15obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o
16obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o 16obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o dma.o
17obj-$(CONFIG_CPU_FREQ) += cpufreq.o
17 18
18obj-$(CONFIG_SMP) += platsmp.o headsmp.o 19obj-$(CONFIG_SMP) += platsmp.o headsmp.o
19obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o 20obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
@@ -27,6 +28,10 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
27 28
28# device support 29# device support
29 30
31obj-y += dev-audio.o
32obj-$(CONFIG_S5PV310_DEV_PD) += dev-pd.o
33obj-$(CONFIG_S5PV310_DEV_SYSMMU) += dev-sysmmu.o
34
30obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o 35obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o
31obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o 36obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o
32obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o 37obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o
diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c
index 58c9d33f36fe..fc7c2f8d165e 100644
--- a/arch/arm/mach-s5pv310/clock.c
+++ b/arch/arm/mach-s5pv310/clock.c
@@ -244,7 +244,7 @@ static struct clksrc_clk clk_mout_corebus = {
244 .id = -1, 244 .id = -1,
245 }, 245 },
246 .sources = &clkset_mout_corebus, 246 .sources = &clkset_mout_corebus,
247 .reg_src = { .reg = S5P_CLKSRC_CORE, .shift = 4, .size = 1 }, 247 .reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
248}; 248};
249 249
250static struct clksrc_clk clk_sclk_dmc = { 250static struct clksrc_clk clk_sclk_dmc = {
@@ -253,7 +253,7 @@ static struct clksrc_clk clk_sclk_dmc = {
253 .id = -1, 253 .id = -1,
254 .parent = &clk_mout_corebus.clk, 254 .parent = &clk_mout_corebus.clk,
255 }, 255 },
256 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 12, .size = 3 }, 256 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
257}; 257};
258 258
259static struct clksrc_clk clk_aclk_cored = { 259static struct clksrc_clk clk_aclk_cored = {
@@ -262,7 +262,7 @@ static struct clksrc_clk clk_aclk_cored = {
262 .id = -1, 262 .id = -1,
263 .parent = &clk_sclk_dmc.clk, 263 .parent = &clk_sclk_dmc.clk,
264 }, 264 },
265 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 16, .size = 3 }, 265 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
266}; 266};
267 267
268static struct clksrc_clk clk_aclk_corep = { 268static struct clksrc_clk clk_aclk_corep = {
@@ -271,7 +271,7 @@ static struct clksrc_clk clk_aclk_corep = {
271 .id = -1, 271 .id = -1,
272 .parent = &clk_aclk_cored.clk, 272 .parent = &clk_aclk_cored.clk,
273 }, 273 },
274 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 20, .size = 3 }, 274 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
275}; 275};
276 276
277static struct clksrc_clk clk_aclk_acp = { 277static struct clksrc_clk clk_aclk_acp = {
@@ -280,7 +280,7 @@ static struct clksrc_clk clk_aclk_acp = {
280 .id = -1, 280 .id = -1,
281 .parent = &clk_mout_corebus.clk, 281 .parent = &clk_mout_corebus.clk,
282 }, 282 },
283 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 0, .size = 3 }, 283 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
284}; 284};
285 285
286static struct clksrc_clk clk_pclk_acp = { 286static struct clksrc_clk clk_pclk_acp = {
@@ -289,7 +289,7 @@ static struct clksrc_clk clk_pclk_acp = {
289 .id = -1, 289 .id = -1,
290 .parent = &clk_aclk_acp.clk, 290 .parent = &clk_aclk_acp.clk,
291 }, 291 },
292 .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 4, .size = 3 }, 292 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
293}; 293};
294 294
295/* Core list of CMU_TOP side */ 295/* Core list of CMU_TOP side */
@@ -384,7 +384,7 @@ static struct clksrc_clk clk_sclk_vpll = {
384 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 }, 384 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
385}; 385};
386 386
387static struct clk init_clocks_disable[] = { 387static struct clk init_clocks_off[] = {
388 { 388 {
389 .name = "timers", 389 .name = "timers",
390 .id = -1, 390 .id = -1,
@@ -467,6 +467,16 @@ static struct clk init_clocks_disable[] = {
467 .enable = s5pv310_clk_ip_fsys_ctrl, 467 .enable = s5pv310_clk_ip_fsys_ctrl,
468 .ctrlbit = (1 << 10), 468 .ctrlbit = (1 << 10),
469 }, { 469 }, {
470 .name = "pdma",
471 .id = 0,
472 .enable = s5pv310_clk_ip_fsys_ctrl,
473 .ctrlbit = (1 << 0),
474 }, {
475 .name = "pdma",
476 .id = 1,
477 .enable = s5pv310_clk_ip_fsys_ctrl,
478 .ctrlbit = (1 << 1),
479 }, {
470 .name = "adc", 480 .name = "adc",
471 .id = -1, 481 .id = -1,
472 .enable = s5pv310_clk_ip_peril_ctrl, 482 .enable = s5pv310_clk_ip_peril_ctrl,
@@ -507,6 +517,26 @@ static struct clk init_clocks_disable[] = {
507 .enable = s5pv310_clk_ip_peril_ctrl, 517 .enable = s5pv310_clk_ip_peril_ctrl,
508 .ctrlbit = (1 << 18), 518 .ctrlbit = (1 << 18),
509 }, { 519 }, {
520 .name = "iis",
521 .id = 0,
522 .enable = s5pv310_clk_ip_peril_ctrl,
523 .ctrlbit = (1 << 19),
524 }, {
525 .name = "iis",
526 .id = 1,
527 .enable = s5pv310_clk_ip_peril_ctrl,
528 .ctrlbit = (1 << 20),
529 }, {
530 .name = "iis",
531 .id = 2,
532 .enable = s5pv310_clk_ip_peril_ctrl,
533 .ctrlbit = (1 << 21),
534 }, {
535 .name = "ac97",
536 .id = -1,
537 .enable = s5pv310_clk_ip_peril_ctrl,
538 .ctrlbit = (1 << 27),
539 }, {
510 .name = "fimg2d", 540 .name = "fimg2d",
511 .id = -1, 541 .id = -1,
512 .enable = s5pv310_clk_ip_image_ctrl, 542 .enable = s5pv310_clk_ip_image_ctrl,
@@ -990,6 +1020,17 @@ static struct clksrc_clk *sysclks[] = {
990 &clk_dout_mmc4, 1020 &clk_dout_mmc4,
991}; 1021};
992 1022
1023static int xtal_rate;
1024
1025static unsigned long s5pv310_fout_apll_get_rate(struct clk *clk)
1026{
1027 return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
1028}
1029
1030static struct clk_ops s5pv310_fout_apll_ops = {
1031 .get_rate = s5pv310_fout_apll_get_rate,
1032};
1033
993void __init_or_cpufreq s5pv310_setup_clocks(void) 1034void __init_or_cpufreq s5pv310_setup_clocks(void)
994{ 1035{
995 struct clk *xtal_clk; 1036 struct clk *xtal_clk;
@@ -1013,6 +1054,9 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
1013 BUG_ON(IS_ERR(xtal_clk)); 1054 BUG_ON(IS_ERR(xtal_clk));
1014 1055
1015 xtal = clk_get_rate(xtal_clk); 1056 xtal = clk_get_rate(xtal_clk);
1057
1058 xtal_rate = xtal;
1059
1016 clk_put(xtal_clk); 1060 clk_put(xtal_clk);
1017 1061
1018 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); 1062 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
@@ -1026,7 +1070,7 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
1026 vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), 1070 vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1027 __raw_readl(S5P_VPLL_CON1), pll_4650); 1071 __raw_readl(S5P_VPLL_CON1), pll_4650);
1028 1072
1029 clk_fout_apll.rate = apll; 1073 clk_fout_apll.ops = &s5pv310_fout_apll_ops;
1030 clk_fout_mpll.rate = mpll; 1074 clk_fout_mpll.rate = mpll;
1031 clk_fout_epll.rate = epll; 1075 clk_fout_epll.rate = epll;
1032 clk_fout_vpll.rate = vpll; 1076 clk_fout_vpll.rate = vpll;
@@ -1061,13 +1105,9 @@ static struct clk *clks[] __initdata = {
1061 1105
1062void __init s5pv310_register_clocks(void) 1106void __init s5pv310_register_clocks(void)
1063{ 1107{
1064 struct clk *clkp;
1065 int ret;
1066 int ptr; 1108 int ptr;
1067 1109
1068 ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); 1110 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1069 if (ret > 0)
1070 printk(KERN_ERR "Failed to register %u clocks\n", ret);
1071 1111
1072 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) 1112 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1073 s3c_register_clksrc(sysclks[ptr], 1); 1113 s3c_register_clksrc(sysclks[ptr], 1);
@@ -1075,15 +1115,8 @@ void __init s5pv310_register_clocks(void)
1075 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1115 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1076 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1116 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1077 1117
1078 clkp = init_clocks_disable; 1118 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1079 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 1119 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1080 ret = s3c24xx_register_clock(clkp);
1081 if (ret < 0) {
1082 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1083 clkp->name, ret);
1084 }
1085 (clkp->enable)(clkp, 0);
1086 }
1087 1120
1088 s3c_pwmclk_init(); 1121 s3c_pwmclk_init();
1089} 1122}
diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c
index 72ab289e7816..0db0fb65bd70 100644
--- a/arch/arm/mach-s5pv310/cpu.c
+++ b/arch/arm/mach-s5pv310/cpu.c
@@ -41,6 +41,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
41 .length = SZ_128K, 41 .length = SZ_128K,
42 .type = MT_DEVICE, 42 .type = MT_DEVICE,
43 }, { 43 }, {
44 .virtual = (unsigned long)S5P_VA_PMU,
45 .pfn = __phys_to_pfn(S5PV310_PA_PMU),
46 .length = SZ_64K,
47 .type = MT_DEVICE,
48 }, {
44 .virtual = (unsigned long)S5P_VA_COMBINER_BASE, 49 .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
45 .pfn = __phys_to_pfn(S5PV310_PA_COMBINER), 50 .pfn = __phys_to_pfn(S5PV310_PA_COMBINER),
46 .length = SZ_4K, 51 .length = SZ_4K,
@@ -71,6 +76,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
71 .length = SZ_256, 76 .length = SZ_256,
72 .type = MT_DEVICE, 77 .type = MT_DEVICE,
73 }, { 78 }, {
79 .virtual = (unsigned long)S5P_VA_DMC0,
80 .pfn = __phys_to_pfn(S5PV310_PA_DMC0),
81 .length = SZ_4K,
82 .type = MT_DEVICE,
83 }, {
74 .virtual = (unsigned long)S3C_VA_UART, 84 .virtual = (unsigned long)S3C_VA_UART,
75 .pfn = __phys_to_pfn(S3C_PA_UART), 85 .pfn = __phys_to_pfn(S3C_PA_UART),
76 .length = SZ_512K, 86 .length = SZ_512K,
@@ -123,6 +133,15 @@ void __init s5pv310_init_irq(void)
123 gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); 133 gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
124 134
125 for (irq = 0; irq < MAX_COMBINER_NR; irq++) { 135 for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
136
137 /*
138 * From SPI(0) to SPI(39) and SPI(51), SPI(53) are
139 * connected to the interrupt combiner. These irqs
140 * should be initialized to support cascade interrupt.
141 */
142 if ((irq >= 40) && !(irq == 51) && !(irq == 53))
143 continue;
144
126 combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), 145 combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
127 COMBINER_IRQ(irq, 0)); 146 COMBINER_IRQ(irq, 0));
128 combiner_cascade_irq(irq, IRQ_SPI(irq)); 147 combiner_cascade_irq(irq, IRQ_SPI(irq));
@@ -164,7 +183,7 @@ static int __init s5pv310_l2x0_cache_init(void)
164 __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, 183 __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
165 S5P_VA_L2CC + L2X0_POWER_CTRL); 184 S5P_VA_L2CC + L2X0_POWER_CTRL);
166 185
167 l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff); 186 l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
168 187
169 return 0; 188 return 0;
170} 189}
diff --git a/arch/arm/mach-s5pv310/cpufreq.c b/arch/arm/mach-s5pv310/cpufreq.c
new file mode 100644
index 000000000000..b04cbc731128
--- /dev/null
+++ b/arch/arm/mach-s5pv310/cpufreq.c
@@ -0,0 +1,580 @@
1/* linux/arch/arm/mach-s5pv310/cpufreq.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - CPU frequency scaling support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/types.h>
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <linux/clk.h>
17#include <linux/io.h>
18#include <linux/slab.h>
19#include <linux/regulator/consumer.h>
20#include <linux/cpufreq.h>
21
22#include <mach/map.h>
23#include <mach/regs-clock.h>
24#include <mach/regs-mem.h>
25
26#include <plat/clock.h>
27#include <plat/pm.h>
28
29static struct clk *cpu_clk;
30static struct clk *moutcore;
31static struct clk *mout_mpll;
32static struct clk *mout_apll;
33
34#ifdef CONFIG_REGULATOR
35static struct regulator *arm_regulator;
36static struct regulator *int_regulator;
37#endif
38
39static struct cpufreq_freqs freqs;
40static unsigned int memtype;
41
42enum s5pv310_memory_type {
43 DDR2 = 4,
44 LPDDR2,
45 DDR3,
46};
47
48enum cpufreq_level_index {
49 L0, L1, L2, L3, CPUFREQ_LEVEL_END,
50};
51
52static struct cpufreq_frequency_table s5pv310_freq_table[] = {
53 {L0, 1000*1000},
54 {L1, 800*1000},
55 {L2, 400*1000},
56 {L3, 100*1000},
57 {0, CPUFREQ_TABLE_END},
58};
59
60static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = {
61 /*
62 * Clock divider value for following
63 * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
64 * DIVATB, DIVPCLK_DBG, DIVAPLL }
65 */
66
67 /* ARM L0: 1000MHz */
68 { 0, 3, 7, 3, 3, 0, 1 },
69
70 /* ARM L1: 800MHz */
71 { 0, 3, 7, 3, 3, 0, 1 },
72
73 /* ARM L2: 400MHz */
74 { 0, 1, 3, 1, 3, 0, 1 },
75
76 /* ARM L3: 100MHz */
77 { 0, 0, 1, 0, 3, 1, 1 },
78};
79
80static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = {
81 /*
82 * Clock divider value for following
83 * { DIVCOPY, DIVHPM }
84 */
85
86 /* ARM L0: 1000MHz */
87 { 3, 0 },
88
89 /* ARM L1: 800MHz */
90 { 3, 0 },
91
92 /* ARM L2: 400MHz */
93 { 3, 0 },
94
95 /* ARM L3: 100MHz */
96 { 3, 0 },
97};
98
99static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END][8] = {
100 /*
101 * Clock divider value for following
102 * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
103 * DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
104 */
105
106 /* DMC L0: 400MHz */
107 { 3, 1, 1, 1, 1, 1, 3, 1 },
108
109 /* DMC L1: 400MHz */
110 { 3, 1, 1, 1, 1, 1, 3, 1 },
111
112 /* DMC L2: 266.7MHz */
113 { 7, 1, 1, 2, 1, 1, 3, 1 },
114
115 /* DMC L3: 200MHz */
116 { 7, 1, 1, 3, 1, 1, 3, 1 },
117};
118
119static unsigned int clkdiv_top[CPUFREQ_LEVEL_END][5] = {
120 /*
121 * Clock divider value for following
122 * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
123 */
124
125 /* ACLK200 L0: 200MHz */
126 { 3, 7, 4, 5, 1 },
127
128 /* ACLK200 L1: 200MHz */
129 { 3, 7, 4, 5, 1 },
130
131 /* ACLK200 L2: 160MHz */
132 { 4, 7, 5, 7, 1 },
133
134 /* ACLK200 L3: 133.3MHz */
135 { 5, 7, 7, 7, 1 },
136};
137
138static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END][2] = {
139 /*
140 * Clock divider value for following
141 * { DIVGDL/R, DIVGPL/R }
142 */
143
144 /* ACLK_GDL/R L0: 200MHz */
145 { 3, 1 },
146
147 /* ACLK_GDL/R L1: 200MHz */
148 { 3, 1 },
149
150 /* ACLK_GDL/R L2: 160MHz */
151 { 4, 1 },
152
153 /* ACLK_GDL/R L3: 133.3MHz */
154 { 5, 1 },
155};
156
157struct cpufreq_voltage_table {
158 unsigned int index; /* any */
159 unsigned int arm_volt; /* uV */
160 unsigned int int_volt;
161};
162
163static struct cpufreq_voltage_table s5pv310_volt_table[CPUFREQ_LEVEL_END] = {
164 {
165 .index = L0,
166 .arm_volt = 1200000,
167 .int_volt = 1100000,
168 }, {
169 .index = L1,
170 .arm_volt = 1100000,
171 .int_volt = 1100000,
172 }, {
173 .index = L2,
174 .arm_volt = 1000000,
175 .int_volt = 1000000,
176 }, {
177 .index = L3,
178 .arm_volt = 900000,
179 .int_volt = 1000000,
180 },
181};
182
183static unsigned int s5pv310_apll_pms_table[CPUFREQ_LEVEL_END] = {
184 /* APLL FOUT L0: 1000MHz */
185 ((250 << 16) | (6 << 8) | 1),
186
187 /* APLL FOUT L1: 800MHz */
188 ((200 << 16) | (6 << 8) | 1),
189
190 /* APLL FOUT L2 : 400MHz */
191 ((200 << 16) | (6 << 8) | 2),
192
193 /* APLL FOUT L3: 100MHz */
194 ((200 << 16) | (6 << 8) | 4),
195};
196
197int s5pv310_verify_speed(struct cpufreq_policy *policy)
198{
199 return cpufreq_frequency_table_verify(policy, s5pv310_freq_table);
200}
201
202unsigned int s5pv310_getspeed(unsigned int cpu)
203{
204 return clk_get_rate(cpu_clk) / 1000;
205}
206
207void s5pv310_set_clkdiv(unsigned int div_index)
208{
209 unsigned int tmp;
210
211 /* Change Divider - CPU0 */
212
213 tmp = __raw_readl(S5P_CLKDIV_CPU);
214
215 tmp &= ~(S5P_CLKDIV_CPU0_CORE_MASK | S5P_CLKDIV_CPU0_COREM0_MASK |
216 S5P_CLKDIV_CPU0_COREM1_MASK | S5P_CLKDIV_CPU0_PERIPH_MASK |
217 S5P_CLKDIV_CPU0_ATB_MASK | S5P_CLKDIV_CPU0_PCLKDBG_MASK |
218 S5P_CLKDIV_CPU0_APLL_MASK);
219
220 tmp |= ((clkdiv_cpu0[div_index][0] << S5P_CLKDIV_CPU0_CORE_SHIFT) |
221 (clkdiv_cpu0[div_index][1] << S5P_CLKDIV_CPU0_COREM0_SHIFT) |
222 (clkdiv_cpu0[div_index][2] << S5P_CLKDIV_CPU0_COREM1_SHIFT) |
223 (clkdiv_cpu0[div_index][3] << S5P_CLKDIV_CPU0_PERIPH_SHIFT) |
224 (clkdiv_cpu0[div_index][4] << S5P_CLKDIV_CPU0_ATB_SHIFT) |
225 (clkdiv_cpu0[div_index][5] << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) |
226 (clkdiv_cpu0[div_index][6] << S5P_CLKDIV_CPU0_APLL_SHIFT));
227
228 __raw_writel(tmp, S5P_CLKDIV_CPU);
229
230 do {
231 tmp = __raw_readl(S5P_CLKDIV_STATCPU);
232 } while (tmp & 0x1111111);
233
234 /* Change Divider - CPU1 */
235
236 tmp = __raw_readl(S5P_CLKDIV_CPU1);
237
238 tmp &= ~((0x7 << 4) | 0x7);
239
240 tmp |= ((clkdiv_cpu1[div_index][0] << 4) |
241 (clkdiv_cpu1[div_index][1] << 0));
242
243 __raw_writel(tmp, S5P_CLKDIV_CPU1);
244
245 do {
246 tmp = __raw_readl(S5P_CLKDIV_STATCPU1);
247 } while (tmp & 0x11);
248
249 /* Change Divider - DMC0 */
250
251 tmp = __raw_readl(S5P_CLKDIV_DMC0);
252
253 tmp &= ~(S5P_CLKDIV_DMC0_ACP_MASK | S5P_CLKDIV_DMC0_ACPPCLK_MASK |
254 S5P_CLKDIV_DMC0_DPHY_MASK | S5P_CLKDIV_DMC0_DMC_MASK |
255 S5P_CLKDIV_DMC0_DMCD_MASK | S5P_CLKDIV_DMC0_DMCP_MASK |
256 S5P_CLKDIV_DMC0_COPY2_MASK | S5P_CLKDIV_DMC0_CORETI_MASK);
257
258 tmp |= ((clkdiv_dmc0[div_index][0] << S5P_CLKDIV_DMC0_ACP_SHIFT) |
259 (clkdiv_dmc0[div_index][1] << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) |
260 (clkdiv_dmc0[div_index][2] << S5P_CLKDIV_DMC0_DPHY_SHIFT) |
261 (clkdiv_dmc0[div_index][3] << S5P_CLKDIV_DMC0_DMC_SHIFT) |
262 (clkdiv_dmc0[div_index][4] << S5P_CLKDIV_DMC0_DMCD_SHIFT) |
263 (clkdiv_dmc0[div_index][5] << S5P_CLKDIV_DMC0_DMCP_SHIFT) |
264 (clkdiv_dmc0[div_index][6] << S5P_CLKDIV_DMC0_COPY2_SHIFT) |
265 (clkdiv_dmc0[div_index][7] << S5P_CLKDIV_DMC0_CORETI_SHIFT));
266
267 __raw_writel(tmp, S5P_CLKDIV_DMC0);
268
269 do {
270 tmp = __raw_readl(S5P_CLKDIV_STAT_DMC0);
271 } while (tmp & 0x11111111);
272
273 /* Change Divider - TOP */
274
275 tmp = __raw_readl(S5P_CLKDIV_TOP);
276
277 tmp &= ~(S5P_CLKDIV_TOP_ACLK200_MASK | S5P_CLKDIV_TOP_ACLK100_MASK |
278 S5P_CLKDIV_TOP_ACLK160_MASK | S5P_CLKDIV_TOP_ACLK133_MASK |
279 S5P_CLKDIV_TOP_ONENAND_MASK);
280
281 tmp |= ((clkdiv_top[div_index][0] << S5P_CLKDIV_TOP_ACLK200_SHIFT) |
282 (clkdiv_top[div_index][1] << S5P_CLKDIV_TOP_ACLK100_SHIFT) |
283 (clkdiv_top[div_index][2] << S5P_CLKDIV_TOP_ACLK160_SHIFT) |
284 (clkdiv_top[div_index][3] << S5P_CLKDIV_TOP_ACLK133_SHIFT) |
285 (clkdiv_top[div_index][4] << S5P_CLKDIV_TOP_ONENAND_SHIFT));
286
287 __raw_writel(tmp, S5P_CLKDIV_TOP);
288
289 do {
290 tmp = __raw_readl(S5P_CLKDIV_STAT_TOP);
291 } while (tmp & 0x11111);
292
293 /* Change Divider - LEFTBUS */
294
295 tmp = __raw_readl(S5P_CLKDIV_LEFTBUS);
296
297 tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
298
299 tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
300 (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
301
302 __raw_writel(tmp, S5P_CLKDIV_LEFTBUS);
303
304 do {
305 tmp = __raw_readl(S5P_CLKDIV_STAT_LEFTBUS);
306 } while (tmp & 0x11);
307
308 /* Change Divider - RIGHTBUS */
309
310 tmp = __raw_readl(S5P_CLKDIV_RIGHTBUS);
311
312 tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
313
314 tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
315 (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
316
317 __raw_writel(tmp, S5P_CLKDIV_RIGHTBUS);
318
319 do {
320 tmp = __raw_readl(S5P_CLKDIV_STAT_RIGHTBUS);
321 } while (tmp & 0x11);
322}
323
324static void s5pv310_set_apll(unsigned int index)
325{
326 unsigned int tmp;
327
328 /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
329 clk_set_parent(moutcore, mout_mpll);
330
331 do {
332 tmp = (__raw_readl(S5P_CLKMUX_STATCPU)
333 >> S5P_CLKSRC_CPU_MUXCORE_SHIFT);
334 tmp &= 0x7;
335 } while (tmp != 0x2);
336
337 /* 2. Set APLL Lock time */
338 __raw_writel(S5P_APLL_LOCKTIME, S5P_APLL_LOCK);
339
340 /* 3. Change PLL PMS values */
341 tmp = __raw_readl(S5P_APLL_CON0);
342 tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
343 tmp |= s5pv310_apll_pms_table[index];
344 __raw_writel(tmp, S5P_APLL_CON0);
345
346 /* 4. wait_lock_time */
347 do {
348 tmp = __raw_readl(S5P_APLL_CON0);
349 } while (!(tmp & (0x1 << S5P_APLLCON0_LOCKED_SHIFT)));
350
351 /* 5. MUX_CORE_SEL = APLL */
352 clk_set_parent(moutcore, mout_apll);
353
354 do {
355 tmp = __raw_readl(S5P_CLKMUX_STATCPU);
356 tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK;
357 } while (tmp != (0x1 << S5P_CLKSRC_CPU_MUXCORE_SHIFT));
358}
359
360static void s5pv310_set_frequency(unsigned int old_index, unsigned int new_index)
361{
362 unsigned int tmp;
363
364 if (old_index > new_index) {
365 /* The frequency changing to L0 needs to change apll */
366 if (freqs.new == s5pv310_freq_table[L0].frequency) {
367 /* 1. Change the system clock divider values */
368 s5pv310_set_clkdiv(new_index);
369
370 /* 2. Change the apll m,p,s value */
371 s5pv310_set_apll(new_index);
372 } else {
373 /* 1. Change the system clock divider values */
374 s5pv310_set_clkdiv(new_index);
375
376 /* 2. Change just s value in apll m,p,s value */
377 tmp = __raw_readl(S5P_APLL_CON0);
378 tmp &= ~(0x7 << 0);
379 tmp |= (s5pv310_apll_pms_table[new_index] & 0x7);
380 __raw_writel(tmp, S5P_APLL_CON0);
381 }
382 }
383
384 else if (old_index < new_index) {
385 /* The frequency changing from L0 needs to change apll */
386 if (freqs.old == s5pv310_freq_table[L0].frequency) {
387 /* 1. Change the apll m,p,s value */
388 s5pv310_set_apll(new_index);
389
390 /* 2. Change the system clock divider values */
391 s5pv310_set_clkdiv(new_index);
392 } else {
393 /* 1. Change just s value in apll m,p,s value */
394 tmp = __raw_readl(S5P_APLL_CON0);
395 tmp &= ~(0x7 << 0);
396 tmp |= (s5pv310_apll_pms_table[new_index] & 0x7);
397 __raw_writel(tmp, S5P_APLL_CON0);
398
399 /* 2. Change the system clock divider values */
400 s5pv310_set_clkdiv(new_index);
401 }
402 }
403}
404
405static int s5pv310_target(struct cpufreq_policy *policy,
406 unsigned int target_freq,
407 unsigned int relation)
408{
409 unsigned int index, old_index;
410 unsigned int arm_volt, int_volt;
411
412 freqs.old = s5pv310_getspeed(policy->cpu);
413
414 if (cpufreq_frequency_table_target(policy, s5pv310_freq_table,
415 freqs.old, relation, &old_index))
416 return -EINVAL;
417
418 if (cpufreq_frequency_table_target(policy, s5pv310_freq_table,
419 target_freq, relation, &index))
420 return -EINVAL;
421
422 freqs.new = s5pv310_freq_table[index].frequency;
423 freqs.cpu = policy->cpu;
424
425 if (freqs.new == freqs.old)
426 return 0;
427
428 /* get the voltage value */
429 arm_volt = s5pv310_volt_table[index].arm_volt;
430 int_volt = s5pv310_volt_table[index].int_volt;
431
432 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
433
434 /* control regulator */
435 if (freqs.new > freqs.old) {
436 /* Voltage up */
437#ifdef CONFIG_REGULATOR
438 regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
439 regulator_set_voltage(int_regulator, int_volt, int_volt);
440#endif
441 }
442
443 /* Clock Configuration Procedure */
444 s5pv310_set_frequency(old_index, index);
445
446 /* control regulator */
447 if (freqs.new < freqs.old) {
448 /* Voltage down */
449#ifdef CONFIG_REGULATOR
450 regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
451 regulator_set_voltage(int_regulator, int_volt, int_volt);
452#endif
453 }
454
455 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
456
457 return 0;
458}
459
460#ifdef CONFIG_PM
461static int s5pv310_cpufreq_suspend(struct cpufreq_policy *policy,
462 pm_message_t pmsg)
463{
464 return 0;
465}
466
467static int s5pv310_cpufreq_resume(struct cpufreq_policy *policy)
468{
469 return 0;
470}
471#endif
472
473static int s5pv310_cpufreq_cpu_init(struct cpufreq_policy *policy)
474{
475 policy->cur = policy->min = policy->max = s5pv310_getspeed(policy->cpu);
476
477 cpufreq_frequency_table_get_attr(s5pv310_freq_table, policy->cpu);
478
479 /* set the transition latency value */
480 policy->cpuinfo.transition_latency = 100000;
481
482 /*
483 * S5PV310 multi-core processors has 2 cores
484 * that the frequency cannot be set independently.
485 * Each cpu is bound to the same speed.
486 * So the affected cpu is all of the cpus.
487 */
488 cpumask_setall(policy->cpus);
489
490 return cpufreq_frequency_table_cpuinfo(policy, s5pv310_freq_table);
491}
492
493static struct cpufreq_driver s5pv310_driver = {
494 .flags = CPUFREQ_STICKY,
495 .verify = s5pv310_verify_speed,
496 .target = s5pv310_target,
497 .get = s5pv310_getspeed,
498 .init = s5pv310_cpufreq_cpu_init,
499 .name = "s5pv310_cpufreq",
500#ifdef CONFIG_PM
501 .suspend = s5pv310_cpufreq_suspend,
502 .resume = s5pv310_cpufreq_resume,
503#endif
504};
505
506static int __init s5pv310_cpufreq_init(void)
507{
508 cpu_clk = clk_get(NULL, "armclk");
509 if (IS_ERR(cpu_clk))
510 return PTR_ERR(cpu_clk);
511
512 moutcore = clk_get(NULL, "moutcore");
513 if (IS_ERR(moutcore))
514 goto out;
515
516 mout_mpll = clk_get(NULL, "mout_mpll");
517 if (IS_ERR(mout_mpll))
518 goto out;
519
520 mout_apll = clk_get(NULL, "mout_apll");
521 if (IS_ERR(mout_apll))
522 goto out;
523
524#ifdef CONFIG_REGULATOR
525 arm_regulator = regulator_get(NULL, "vdd_arm");
526 if (IS_ERR(arm_regulator)) {
527 printk(KERN_ERR "failed to get resource %s\n", "vdd_arm");
528 goto out;
529 }
530
531 int_regulator = regulator_get(NULL, "vdd_int");
532 if (IS_ERR(int_regulator)) {
533 printk(KERN_ERR "failed to get resource %s\n", "vdd_int");
534 goto out;
535 }
536#endif
537
538 /*
539 * Check DRAM type.
540 * Because DVFS level is different according to DRAM type.
541 */
542 memtype = __raw_readl(S5P_VA_DMC0 + S5P_DMC0_MEMCON_OFFSET);
543 memtype = (memtype >> S5P_DMC0_MEMTYPE_SHIFT);
544 memtype &= S5P_DMC0_MEMTYPE_MASK;
545
546 if ((memtype < DDR2) && (memtype > DDR3)) {
547 printk(KERN_ERR "%s: wrong memtype= 0x%x\n", __func__, memtype);
548 goto out;
549 } else {
550 printk(KERN_DEBUG "%s: memtype= 0x%x\n", __func__, memtype);
551 }
552
553 return cpufreq_register_driver(&s5pv310_driver);
554
555out:
556 if (!IS_ERR(cpu_clk))
557 clk_put(cpu_clk);
558
559 if (!IS_ERR(moutcore))
560 clk_put(moutcore);
561
562 if (!IS_ERR(mout_mpll))
563 clk_put(mout_mpll);
564
565 if (!IS_ERR(mout_apll))
566 clk_put(mout_apll);
567
568#ifdef CONFIG_REGULATOR
569 if (!IS_ERR(arm_regulator))
570 regulator_put(arm_regulator);
571
572 if (!IS_ERR(int_regulator))
573 regulator_put(int_regulator);
574#endif
575
576 printk(KERN_ERR "%s: failed initialization\n", __func__);
577
578 return -EINVAL;
579}
580late_initcall(s5pv310_cpufreq_init);
diff --git a/arch/arm/mach-s5pv310/dev-audio.c b/arch/arm/mach-s5pv310/dev-audio.c
new file mode 100644
index 000000000000..a1964242f0fa
--- /dev/null
+++ b/arch/arm/mach-s5pv310/dev-audio.c
@@ -0,0 +1,364 @@
1/* linux/arch/arm/mach-s5pv310/dev-audio.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co. Ltd
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
14
15#include <plat/gpio-cfg.h>
16#include <plat/audio.h>
17
18#include <mach/map.h>
19#include <mach/dma.h>
20#include <mach/irqs.h>
21
22static const char *rclksrc[] = {
23 [0] = "busclk",
24 [1] = "i2sclk",
25};
26
27static int s5pv310_cfg_i2s(struct platform_device *pdev)
28{
29 /* configure GPIO for i2s port */
30 switch (pdev->id) {
31 case 0:
32 s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 7, S3C_GPIO_SFN(2));
33 break;
34 case 1:
35 s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(2));
36 break;
37 case 2:
38 s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(4));
39 break;
40 default:
41 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
42 return -EINVAL;
43 }
44
45 return 0;
46}
47
48static struct s3c_audio_pdata i2sv5_pdata = {
49 .cfg_gpio = s5pv310_cfg_i2s,
50 .type = {
51 .i2s = {
52 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
53 | QUIRK_NEED_RSTCLR,
54 .src_clk = rclksrc,
55 },
56 },
57};
58
59static struct resource s5pv310_i2s0_resource[] = {
60 [0] = {
61 .start = S5PV310_PA_I2S0,
62 .end = S5PV310_PA_I2S0 + 0x100 - 1,
63 .flags = IORESOURCE_MEM,
64 },
65 [1] = {
66 .start = DMACH_I2S0_TX,
67 .end = DMACH_I2S0_TX,
68 .flags = IORESOURCE_DMA,
69 },
70 [2] = {
71 .start = DMACH_I2S0_RX,
72 .end = DMACH_I2S0_RX,
73 .flags = IORESOURCE_DMA,
74 },
75 [3] = {
76 .start = DMACH_I2S0S_TX,
77 .end = DMACH_I2S0S_TX,
78 .flags = IORESOURCE_DMA,
79 },
80};
81
82struct platform_device s5pv310_device_i2s0 = {
83 .name = "samsung-i2s",
84 .id = 0,
85 .num_resources = ARRAY_SIZE(s5pv310_i2s0_resource),
86 .resource = s5pv310_i2s0_resource,
87 .dev = {
88 .platform_data = &i2sv5_pdata,
89 },
90};
91
92static const char *rclksrc_v3[] = {
93 [0] = "sclk_i2s",
94 [1] = "no_such_clock",
95};
96
97static struct s3c_audio_pdata i2sv3_pdata = {
98 .cfg_gpio = s5pv310_cfg_i2s,
99 .type = {
100 .i2s = {
101 .quirks = QUIRK_NO_MUXPSR,
102 .src_clk = rclksrc_v3,
103 },
104 },
105};
106
107static struct resource s5pv310_i2s1_resource[] = {
108 [0] = {
109 .start = S5PV310_PA_I2S1,
110 .end = S5PV310_PA_I2S1 + 0x100 - 1,
111 .flags = IORESOURCE_MEM,
112 },
113 [1] = {
114 .start = DMACH_I2S1_TX,
115 .end = DMACH_I2S1_TX,
116 .flags = IORESOURCE_DMA,
117 },
118 [2] = {
119 .start = DMACH_I2S1_RX,
120 .end = DMACH_I2S1_RX,
121 .flags = IORESOURCE_DMA,
122 },
123};
124
125struct platform_device s5pv310_device_i2s1 = {
126 .name = "samsung-i2s",
127 .id = 1,
128 .num_resources = ARRAY_SIZE(s5pv310_i2s1_resource),
129 .resource = s5pv310_i2s1_resource,
130 .dev = {
131 .platform_data = &i2sv3_pdata,
132 },
133};
134
135static struct resource s5pv310_i2s2_resource[] = {
136 [0] = {
137 .start = S5PV310_PA_I2S2,
138 .end = S5PV310_PA_I2S2 + 0x100 - 1,
139 .flags = IORESOURCE_MEM,
140 },
141 [1] = {
142 .start = DMACH_I2S2_TX,
143 .end = DMACH_I2S2_TX,
144 .flags = IORESOURCE_DMA,
145 },
146 [2] = {
147 .start = DMACH_I2S2_RX,
148 .end = DMACH_I2S2_RX,
149 .flags = IORESOURCE_DMA,
150 },
151};
152
153struct platform_device s5pv310_device_i2s2 = {
154 .name = "samsung-i2s",
155 .id = 2,
156 .num_resources = ARRAY_SIZE(s5pv310_i2s2_resource),
157 .resource = s5pv310_i2s2_resource,
158 .dev = {
159 .platform_data = &i2sv3_pdata,
160 },
161};
162
163/* PCM Controller platform_devices */
164
165static int s5pv310_pcm_cfg_gpio(struct platform_device *pdev)
166{
167 switch (pdev->id) {
168 case 0:
169 s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 5, S3C_GPIO_SFN(3));
170 break;
171 case 1:
172 s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(3));
173 break;
174 case 2:
175 s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(3));
176 break;
177 default:
178 printk(KERN_DEBUG "Invalid PCM Controller number!");
179 return -EINVAL;
180 }
181
182 return 0;
183}
184
185static struct s3c_audio_pdata s3c_pcm_pdata = {
186 .cfg_gpio = s5pv310_pcm_cfg_gpio,
187};
188
189static struct resource s5pv310_pcm0_resource[] = {
190 [0] = {
191 .start = S5PV310_PA_PCM0,
192 .end = S5PV310_PA_PCM0 + 0x100 - 1,
193 .flags = IORESOURCE_MEM,
194 },
195 [1] = {
196 .start = DMACH_PCM0_TX,
197 .end = DMACH_PCM0_TX,
198 .flags = IORESOURCE_DMA,
199 },
200 [2] = {
201 .start = DMACH_PCM0_RX,
202 .end = DMACH_PCM0_RX,
203 .flags = IORESOURCE_DMA,
204 },
205};
206
207struct platform_device s5pv310_device_pcm0 = {
208 .name = "samsung-pcm",
209 .id = 0,
210 .num_resources = ARRAY_SIZE(s5pv310_pcm0_resource),
211 .resource = s5pv310_pcm0_resource,
212 .dev = {
213 .platform_data = &s3c_pcm_pdata,
214 },
215};
216
217static struct resource s5pv310_pcm1_resource[] = {
218 [0] = {
219 .start = S5PV310_PA_PCM1,
220 .end = S5PV310_PA_PCM1 + 0x100 - 1,
221 .flags = IORESOURCE_MEM,
222 },
223 [1] = {
224 .start = DMACH_PCM1_TX,
225 .end = DMACH_PCM1_TX,
226 .flags = IORESOURCE_DMA,
227 },
228 [2] = {
229 .start = DMACH_PCM1_RX,
230 .end = DMACH_PCM1_RX,
231 .flags = IORESOURCE_DMA,
232 },
233};
234
235struct platform_device s5pv310_device_pcm1 = {
236 .name = "samsung-pcm",
237 .id = 1,
238 .num_resources = ARRAY_SIZE(s5pv310_pcm1_resource),
239 .resource = s5pv310_pcm1_resource,
240 .dev = {
241 .platform_data = &s3c_pcm_pdata,
242 },
243};
244
245static struct resource s5pv310_pcm2_resource[] = {
246 [0] = {
247 .start = S5PV310_PA_PCM2,
248 .end = S5PV310_PA_PCM2 + 0x100 - 1,
249 .flags = IORESOURCE_MEM,
250 },
251 [1] = {
252 .start = DMACH_PCM2_TX,
253 .end = DMACH_PCM2_TX,
254 .flags = IORESOURCE_DMA,
255 },
256 [2] = {
257 .start = DMACH_PCM2_RX,
258 .end = DMACH_PCM2_RX,
259 .flags = IORESOURCE_DMA,
260 },
261};
262
263struct platform_device s5pv310_device_pcm2 = {
264 .name = "samsung-pcm",
265 .id = 2,
266 .num_resources = ARRAY_SIZE(s5pv310_pcm2_resource),
267 .resource = s5pv310_pcm2_resource,
268 .dev = {
269 .platform_data = &s3c_pcm_pdata,
270 },
271};
272
273/* AC97 Controller platform devices */
274
275static int s5pv310_ac97_cfg_gpio(struct platform_device *pdev)
276{
277 return s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(4));
278}
279
280static struct resource s5pv310_ac97_resource[] = {
281 [0] = {
282 .start = S5PV310_PA_AC97,
283 .end = S5PV310_PA_AC97 + 0x100 - 1,
284 .flags = IORESOURCE_MEM,
285 },
286 [1] = {
287 .start = DMACH_AC97_PCMOUT,
288 .end = DMACH_AC97_PCMOUT,
289 .flags = IORESOURCE_DMA,
290 },
291 [2] = {
292 .start = DMACH_AC97_PCMIN,
293 .end = DMACH_AC97_PCMIN,
294 .flags = IORESOURCE_DMA,
295 },
296 [3] = {
297 .start = DMACH_AC97_MICIN,
298 .end = DMACH_AC97_MICIN,
299 .flags = IORESOURCE_DMA,
300 },
301 [4] = {
302 .start = IRQ_AC97,
303 .end = IRQ_AC97,
304 .flags = IORESOURCE_IRQ,
305 },
306};
307
308static struct s3c_audio_pdata s3c_ac97_pdata = {
309 .cfg_gpio = s5pv310_ac97_cfg_gpio,
310};
311
312static u64 s5pv310_ac97_dmamask = DMA_BIT_MASK(32);
313
314struct platform_device s5pv310_device_ac97 = {
315 .name = "samsung-ac97",
316 .id = -1,
317 .num_resources = ARRAY_SIZE(s5pv310_ac97_resource),
318 .resource = s5pv310_ac97_resource,
319 .dev = {
320 .platform_data = &s3c_ac97_pdata,
321 .dma_mask = &s5pv310_ac97_dmamask,
322 .coherent_dma_mask = DMA_BIT_MASK(32),
323 },
324};
325
326/* S/PDIF Controller platform_device */
327
328static int s5pv310_spdif_cfg_gpio(struct platform_device *pdev)
329{
330 s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 2, S3C_GPIO_SFN(3));
331
332 return 0;
333}
334
335static struct resource s5pv310_spdif_resource[] = {
336 [0] = {
337 .start = S5PV310_PA_SPDIF,
338 .end = S5PV310_PA_SPDIF + 0x100 - 1,
339 .flags = IORESOURCE_MEM,
340 },
341 [1] = {
342 .start = DMACH_SPDIF,
343 .end = DMACH_SPDIF,
344 .flags = IORESOURCE_DMA,
345 },
346};
347
348static struct s3c_audio_pdata samsung_spdif_pdata = {
349 .cfg_gpio = s5pv310_spdif_cfg_gpio,
350};
351
352static u64 s5pv310_spdif_dmamask = DMA_BIT_MASK(32);
353
354struct platform_device s5pv310_device_spdif = {
355 .name = "samsung-spdif",
356 .id = -1,
357 .num_resources = ARRAY_SIZE(s5pv310_spdif_resource),
358 .resource = s5pv310_spdif_resource,
359 .dev = {
360 .platform_data = &samsung_spdif_pdata,
361 .dma_mask = &s5pv310_spdif_dmamask,
362 .coherent_dma_mask = DMA_BIT_MASK(32),
363 },
364};
diff --git a/arch/arm/mach-s5pv310/dev-pd.c b/arch/arm/mach-s5pv310/dev-pd.c
new file mode 100644
index 000000000000..58a50c2d0b67
--- /dev/null
+++ b/arch/arm/mach-s5pv310/dev-pd.c
@@ -0,0 +1,139 @@
1/* linux/arch/arm/mach-s5pv310/dev-pd.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - Power Domain support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/io.h>
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/delay.h>
17
18#include <mach/regs-pmu.h>
19
20#include <plat/pd.h>
21
22static int s5pv310_pd_enable(struct device *dev)
23{
24 struct samsung_pd_info *pdata = dev->platform_data;
25 u32 timeout;
26
27 __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
28
29 /* Wait max 1ms */
30 timeout = 10;
31 while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
32 != S5P_INT_LOCAL_PWR_EN) {
33 if (timeout == 0) {
34 printk(KERN_ERR "Power domain %s enable failed.\n",
35 dev_name(dev));
36 return -ETIMEDOUT;
37 }
38 timeout--;
39 udelay(100);
40 }
41
42 return 0;
43}
44
45static int s5pv310_pd_disable(struct device *dev)
46{
47 struct samsung_pd_info *pdata = dev->platform_data;
48 u32 timeout;
49
50 __raw_writel(0, pdata->base);
51
52 /* Wait max 1ms */
53 timeout = 10;
54 while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
55 if (timeout == 0) {
56 printk(KERN_ERR "Power domain %s disable failed.\n",
57 dev_name(dev));
58 return -ETIMEDOUT;
59 }
60 timeout--;
61 udelay(100);
62 }
63
64 return 0;
65}
66
67struct platform_device s5pv310_device_pd[] = {
68 {
69 .name = "samsung-pd",
70 .id = 0,
71 .dev = {
72 .platform_data = &(struct samsung_pd_info) {
73 .enable = s5pv310_pd_enable,
74 .disable = s5pv310_pd_disable,
75 .base = S5P_PMU_MFC_CONF,
76 },
77 },
78 }, {
79 .name = "samsung-pd",
80 .id = 1,
81 .dev = {
82 .platform_data = &(struct samsung_pd_info) {
83 .enable = s5pv310_pd_enable,
84 .disable = s5pv310_pd_disable,
85 .base = S5P_PMU_G3D_CONF,
86 },
87 },
88 }, {
89 .name = "samsung-pd",
90 .id = 2,
91 .dev = {
92 .platform_data = &(struct samsung_pd_info) {
93 .enable = s5pv310_pd_enable,
94 .disable = s5pv310_pd_disable,
95 .base = S5P_PMU_LCD0_CONF,
96 },
97 },
98 }, {
99 .name = "samsung-pd",
100 .id = 3,
101 .dev = {
102 .platform_data = &(struct samsung_pd_info) {
103 .enable = s5pv310_pd_enable,
104 .disable = s5pv310_pd_disable,
105 .base = S5P_PMU_LCD1_CONF,
106 },
107 },
108 }, {
109 .name = "samsung-pd",
110 .id = 4,
111 .dev = {
112 .platform_data = &(struct samsung_pd_info) {
113 .enable = s5pv310_pd_enable,
114 .disable = s5pv310_pd_disable,
115 .base = S5P_PMU_TV_CONF,
116 },
117 },
118 }, {
119 .name = "samsung-pd",
120 .id = 5,
121 .dev = {
122 .platform_data = &(struct samsung_pd_info) {
123 .enable = s5pv310_pd_enable,
124 .disable = s5pv310_pd_disable,
125 .base = S5P_PMU_CAM_CONF,
126 },
127 },
128 }, {
129 .name = "samsung-pd",
130 .id = 6,
131 .dev = {
132 .platform_data = &(struct samsung_pd_info) {
133 .enable = s5pv310_pd_enable,
134 .disable = s5pv310_pd_disable,
135 .base = S5P_PMU_GPS_CONF,
136 },
137 },
138 },
139};
diff --git a/arch/arm/mach-s5pv310/dev-sysmmu.c b/arch/arm/mach-s5pv310/dev-sysmmu.c
new file mode 100644
index 000000000000..e1bb200ac0f0
--- /dev/null
+++ b/arch/arm/mach-s5pv310/dev-sysmmu.c
@@ -0,0 +1,187 @@
1/* linux/arch/arm/mach-s5pv310/dev-sysmmu.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
13
14#include <mach/map.h>
15#include <mach/irqs.h>
16
17static struct resource s5pv310_sysmmu_resource[] = {
18 [0] = {
19 .start = S5PV310_PA_SYSMMU_MDMA,
20 .end = S5PV310_PA_SYSMMU_MDMA + SZ_64K - 1,
21 .flags = IORESOURCE_MEM,
22 },
23 [1] = {
24 .start = IRQ_SYSMMU_MDMA0_0,
25 .end = IRQ_SYSMMU_MDMA0_0,
26 .flags = IORESOURCE_IRQ,
27 },
28 [2] = {
29 .start = S5PV310_PA_SYSMMU_SSS,
30 .end = S5PV310_PA_SYSMMU_SSS + SZ_64K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [3] = {
34 .start = IRQ_SYSMMU_SSS_0,
35 .end = IRQ_SYSMMU_SSS_0,
36 .flags = IORESOURCE_IRQ,
37 },
38 [4] = {
39 .start = S5PV310_PA_SYSMMU_FIMC0,
40 .end = S5PV310_PA_SYSMMU_FIMC0 + SZ_64K - 1,
41 .flags = IORESOURCE_MEM,
42 },
43 [5] = {
44 .start = IRQ_SYSMMU_FIMC0_0,
45 .end = IRQ_SYSMMU_FIMC0_0,
46 .flags = IORESOURCE_IRQ,
47 },
48 [6] = {
49 .start = S5PV310_PA_SYSMMU_FIMC1,
50 .end = S5PV310_PA_SYSMMU_FIMC1 + SZ_64K - 1,
51 .flags = IORESOURCE_MEM,
52 },
53 [7] = {
54 .start = IRQ_SYSMMU_FIMC1_0,
55 .end = IRQ_SYSMMU_FIMC1_0,
56 .flags = IORESOURCE_IRQ,
57 },
58 [8] = {
59 .start = S5PV310_PA_SYSMMU_FIMC2,
60 .end = S5PV310_PA_SYSMMU_FIMC2 + SZ_64K - 1,
61 .flags = IORESOURCE_MEM,
62 },
63 [9] = {
64 .start = IRQ_SYSMMU_FIMC2_0,
65 .end = IRQ_SYSMMU_FIMC2_0,
66 .flags = IORESOURCE_IRQ,
67 },
68 [10] = {
69 .start = S5PV310_PA_SYSMMU_FIMC3,
70 .end = S5PV310_PA_SYSMMU_FIMC3 + SZ_64K - 1,
71 .flags = IORESOURCE_MEM,
72 },
73 [11] = {
74 .start = IRQ_SYSMMU_FIMC3_0,
75 .end = IRQ_SYSMMU_FIMC3_0,
76 .flags = IORESOURCE_IRQ,
77 },
78 [12] = {
79 .start = S5PV310_PA_SYSMMU_JPEG,
80 .end = S5PV310_PA_SYSMMU_JPEG + SZ_64K - 1,
81 .flags = IORESOURCE_MEM,
82 },
83 [13] = {
84 .start = IRQ_SYSMMU_JPEG_0,
85 .end = IRQ_SYSMMU_JPEG_0,
86 .flags = IORESOURCE_IRQ,
87 },
88 [14] = {
89 .start = S5PV310_PA_SYSMMU_FIMD0,
90 .end = S5PV310_PA_SYSMMU_FIMD0 + SZ_64K - 1,
91 .flags = IORESOURCE_MEM,
92 },
93 [15] = {
94 .start = IRQ_SYSMMU_LCD0_M0_0,
95 .end = IRQ_SYSMMU_LCD0_M0_0,
96 .flags = IORESOURCE_IRQ,
97 },
98 [16] = {
99 .start = S5PV310_PA_SYSMMU_FIMD1,
100 .end = S5PV310_PA_SYSMMU_FIMD1 + SZ_64K - 1,
101 .flags = IORESOURCE_MEM,
102 },
103 [17] = {
104 .start = IRQ_SYSMMU_LCD1_M1_0,
105 .end = IRQ_SYSMMU_LCD1_M1_0,
106 .flags = IORESOURCE_IRQ,
107 },
108 [18] = {
109 .start = S5PV310_PA_SYSMMU_PCIe,
110 .end = S5PV310_PA_SYSMMU_PCIe + SZ_64K - 1,
111 .flags = IORESOURCE_MEM,
112 },
113 [19] = {
114 .start = IRQ_SYSMMU_PCIE_0,
115 .end = IRQ_SYSMMU_PCIE_0,
116 .flags = IORESOURCE_IRQ,
117 },
118 [20] = {
119 .start = S5PV310_PA_SYSMMU_G2D,
120 .end = S5PV310_PA_SYSMMU_G2D + SZ_64K - 1,
121 .flags = IORESOURCE_MEM,
122 },
123 [21] = {
124 .start = IRQ_SYSMMU_2D_0,
125 .end = IRQ_SYSMMU_2D_0,
126 .flags = IORESOURCE_IRQ,
127 },
128 [22] = {
129 .start = S5PV310_PA_SYSMMU_ROTATOR,
130 .end = S5PV310_PA_SYSMMU_ROTATOR + SZ_64K - 1,
131 .flags = IORESOURCE_MEM,
132 },
133 [23] = {
134 .start = IRQ_SYSMMU_ROTATOR_0,
135 .end = IRQ_SYSMMU_ROTATOR_0,
136 .flags = IORESOURCE_IRQ,
137 },
138 [24] = {
139 .start = S5PV310_PA_SYSMMU_MDMA2,
140 .end = S5PV310_PA_SYSMMU_MDMA2 + SZ_64K - 1,
141 .flags = IORESOURCE_MEM,
142 },
143 [25] = {
144 .start = IRQ_SYSMMU_MDMA1_0,
145 .end = IRQ_SYSMMU_MDMA1_0,
146 .flags = IORESOURCE_IRQ,
147 },
148 [26] = {
149 .start = S5PV310_PA_SYSMMU_TV,
150 .end = S5PV310_PA_SYSMMU_TV + SZ_64K - 1,
151 .flags = IORESOURCE_MEM,
152 },
153 [27] = {
154 .start = IRQ_SYSMMU_TV_M0_0,
155 .end = IRQ_SYSMMU_TV_M0_0,
156 .flags = IORESOURCE_IRQ,
157 },
158 [28] = {
159 .start = S5PV310_PA_SYSMMU_MFC_L,
160 .end = S5PV310_PA_SYSMMU_MFC_L + SZ_64K - 1,
161 .flags = IORESOURCE_MEM,
162 },
163 [29] = {
164 .start = IRQ_SYSMMU_MFC_M0_0,
165 .end = IRQ_SYSMMU_MFC_M0_0,
166 .flags = IORESOURCE_IRQ,
167 },
168 [30] = {
169 .start = S5PV310_PA_SYSMMU_MFC_R,
170 .end = S5PV310_PA_SYSMMU_MFC_R + SZ_64K - 1,
171 .flags = IORESOURCE_MEM,
172 },
173 [31] = {
174 .start = IRQ_SYSMMU_MFC_M1_0,
175 .end = IRQ_SYSMMU_MFC_M1_0,
176 .flags = IORESOURCE_IRQ,
177 },
178};
179
180struct platform_device s5pv310_device_sysmmu = {
181 .name = "s5p-sysmmu",
182 .id = 32,
183 .num_resources = ARRAY_SIZE(s5pv310_sysmmu_resource),
184 .resource = s5pv310_sysmmu_resource,
185};
186
187EXPORT_SYMBOL(s5pv310_device_sysmmu);
diff --git a/arch/arm/mach-s5pv310/dma.c b/arch/arm/mach-s5pv310/dma.c
new file mode 100644
index 000000000000..20066c7c9e56
--- /dev/null
+++ b/arch/arm/mach-s5pv310/dma.c
@@ -0,0 +1,168 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/platform_device.h>
21#include <linux/dma-mapping.h>
22
23#include <plat/devs.h>
24#include <plat/irqs.h>
25
26#include <mach/map.h>
27#include <mach/irqs.h>
28
29#include <plat/s3c-pl330-pdata.h>
30
31static u64 dma_dmamask = DMA_BIT_MASK(32);
32
33static struct resource s5pv310_pdma0_resource[] = {
34 [0] = {
35 .start = S5PV310_PA_PDMA0,
36 .end = S5PV310_PA_PDMA0 + SZ_4K,
37 .flags = IORESOURCE_MEM,
38 },
39 [1] = {
40 .start = IRQ_PDMA0,
41 .end = IRQ_PDMA0,
42 .flags = IORESOURCE_IRQ,
43 },
44};
45
46static struct s3c_pl330_platdata s5pv310_pdma0_pdata = {
47 .peri = {
48 [0] = DMACH_PCM0_RX,
49 [1] = DMACH_PCM0_TX,
50 [2] = DMACH_PCM2_RX,
51 [3] = DMACH_PCM2_TX,
52 [4] = DMACH_MSM_REQ0,
53 [5] = DMACH_MSM_REQ2,
54 [6] = DMACH_SPI0_RX,
55 [7] = DMACH_SPI0_TX,
56 [8] = DMACH_SPI2_RX,
57 [9] = DMACH_SPI2_TX,
58 [10] = DMACH_I2S0S_TX,
59 [11] = DMACH_I2S0_RX,
60 [12] = DMACH_I2S0_TX,
61 [13] = DMACH_I2S2_RX,
62 [14] = DMACH_I2S2_TX,
63 [15] = DMACH_UART0_RX,
64 [16] = DMACH_UART0_TX,
65 [17] = DMACH_UART2_RX,
66 [18] = DMACH_UART2_TX,
67 [19] = DMACH_UART4_RX,
68 [20] = DMACH_UART4_TX,
69 [21] = DMACH_SLIMBUS0_RX,
70 [22] = DMACH_SLIMBUS0_TX,
71 [23] = DMACH_SLIMBUS2_RX,
72 [24] = DMACH_SLIMBUS2_TX,
73 [25] = DMACH_SLIMBUS4_RX,
74 [26] = DMACH_SLIMBUS4_TX,
75 [27] = DMACH_AC97_MICIN,
76 [28] = DMACH_AC97_PCMIN,
77 [29] = DMACH_AC97_PCMOUT,
78 [30] = DMACH_MAX,
79 [31] = DMACH_MAX,
80 },
81};
82
83static struct platform_device s5pv310_device_pdma0 = {
84 .name = "s3c-pl330",
85 .id = 0,
86 .num_resources = ARRAY_SIZE(s5pv310_pdma0_resource),
87 .resource = s5pv310_pdma0_resource,
88 .dev = {
89 .dma_mask = &dma_dmamask,
90 .coherent_dma_mask = DMA_BIT_MASK(32),
91 .platform_data = &s5pv310_pdma0_pdata,
92 },
93};
94
95static struct resource s5pv310_pdma1_resource[] = {
96 [0] = {
97 .start = S5PV310_PA_PDMA1,
98 .end = S5PV310_PA_PDMA1 + SZ_4K,
99 .flags = IORESOURCE_MEM,
100 },
101 [1] = {
102 .start = IRQ_PDMA1,
103 .end = IRQ_PDMA1,
104 .flags = IORESOURCE_IRQ,
105 },
106};
107
108static struct s3c_pl330_platdata s5pv310_pdma1_pdata = {
109 .peri = {
110 [0] = DMACH_PCM0_RX,
111 [1] = DMACH_PCM0_TX,
112 [2] = DMACH_PCM1_RX,
113 [3] = DMACH_PCM1_TX,
114 [4] = DMACH_MSM_REQ1,
115 [5] = DMACH_MSM_REQ3,
116 [6] = DMACH_SPI1_RX,
117 [7] = DMACH_SPI1_TX,
118 [8] = DMACH_I2S0S_TX,
119 [9] = DMACH_I2S0_RX,
120 [10] = DMACH_I2S0_TX,
121 [11] = DMACH_I2S1_RX,
122 [12] = DMACH_I2S1_TX,
123 [13] = DMACH_UART0_RX,
124 [14] = DMACH_UART0_TX,
125 [15] = DMACH_UART1_RX,
126 [16] = DMACH_UART1_TX,
127 [17] = DMACH_UART3_RX,
128 [18] = DMACH_UART3_TX,
129 [19] = DMACH_SLIMBUS1_RX,
130 [20] = DMACH_SLIMBUS1_TX,
131 [21] = DMACH_SLIMBUS3_RX,
132 [22] = DMACH_SLIMBUS3_TX,
133 [23] = DMACH_SLIMBUS5_RX,
134 [24] = DMACH_SLIMBUS5_TX,
135 [25] = DMACH_SLIMBUS0AUX_RX,
136 [26] = DMACH_SLIMBUS0AUX_TX,
137 [27] = DMACH_SPDIF,
138 [28] = DMACH_MAX,
139 [29] = DMACH_MAX,
140 [30] = DMACH_MAX,
141 [31] = DMACH_MAX,
142 },
143};
144
145static struct platform_device s5pv310_device_pdma1 = {
146 .name = "s3c-pl330",
147 .id = 1,
148 .num_resources = ARRAY_SIZE(s5pv310_pdma1_resource),
149 .resource = s5pv310_pdma1_resource,
150 .dev = {
151 .dma_mask = &dma_dmamask,
152 .coherent_dma_mask = DMA_BIT_MASK(32),
153 .platform_data = &s5pv310_pdma1_pdata,
154 },
155};
156
157static struct platform_device *s5pv310_dmacs[] __initdata = {
158 &s5pv310_device_pdma0,
159 &s5pv310_device_pdma1,
160};
161
162static int __init s5pv310_dma_init(void)
163{
164 platform_add_devices(s5pv310_dmacs, ARRAY_SIZE(s5pv310_dmacs));
165
166 return 0;
167}
168arch_initcall(s5pv310_dma_init);
diff --git a/arch/arm/mach-s5pv310/include/mach/dma.h b/arch/arm/mach-s5pv310/include/mach/dma.h
new file mode 100644
index 000000000000..81209eb1409b
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/dma.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef __MACH_DMA_H
21#define __MACH_DMA_H
22
23/* This platform uses the common S3C DMA API driver for PL330 */
24#include <plat/s3c-dma-pl330.h>
25
26#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
index 99e7dad8a85a..536b0b59fc83 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -25,6 +25,8 @@
25 25
26#define IRQ_SPI(x) S5P_IRQ(x+32) 26#define IRQ_SPI(x) S5P_IRQ(x+32)
27 27
28#define IRQ_MCT1 IRQ_SPI(35)
29
28#define IRQ_EINT0 IRQ_SPI(40) 30#define IRQ_EINT0 IRQ_SPI(40)
29#define IRQ_EINT1 IRQ_SPI(41) 31#define IRQ_EINT1 IRQ_SPI(41)
30#define IRQ_EINT2 IRQ_SPI(42) 32#define IRQ_EINT2 IRQ_SPI(42)
@@ -36,9 +38,8 @@
36#define IRQ_JPEG IRQ_SPI(48) 38#define IRQ_JPEG IRQ_SPI(48)
37#define IRQ_2D IRQ_SPI(49) 39#define IRQ_2D IRQ_SPI(49)
38#define IRQ_PCIE IRQ_SPI(50) 40#define IRQ_PCIE IRQ_SPI(50)
39#define IRQ_SYSTEM_TIMER IRQ_SPI(51) 41#define IRQ_MCT0 IRQ_SPI(51)
40#define IRQ_MFC IRQ_SPI(52) 42#define IRQ_MFC IRQ_SPI(52)
41#define IRQ_WDT IRQ_SPI(53)
42#define IRQ_AUDIO_SS IRQ_SPI(54) 43#define IRQ_AUDIO_SS IRQ_SPI(54)
43#define IRQ_AC97 IRQ_SPI(55) 44#define IRQ_AC97 IRQ_SPI(55)
44#define IRQ_SPDIF IRQ_SPI(56) 45#define IRQ_SPDIF IRQ_SPI(56)
@@ -54,6 +55,27 @@
54#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64)) 55#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64))
55#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y) 56#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y)
56 57
58#define IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0)
59#define IRQ_SYSMMU_SSS_0 COMBINER_IRQ(4, 1)
60#define IRQ_SYSMMU_FIMC0_0 COMBINER_IRQ(4, 2)
61#define IRQ_SYSMMU_FIMC1_0 COMBINER_IRQ(4, 3)
62#define IRQ_SYSMMU_FIMC2_0 COMBINER_IRQ(4, 4)
63#define IRQ_SYSMMU_FIMC3_0 COMBINER_IRQ(4, 5)
64#define IRQ_SYSMMU_JPEG_0 COMBINER_IRQ(4, 6)
65#define IRQ_SYSMMU_2D_0 COMBINER_IRQ(4, 7)
66
67#define IRQ_SYSMMU_ROTATOR_0 COMBINER_IRQ(5, 0)
68#define IRQ_SYSMMU_MDMA1_0 COMBINER_IRQ(5, 1)
69#define IRQ_SYSMMU_LCD0_M0_0 COMBINER_IRQ(5, 2)
70#define IRQ_SYSMMU_LCD1_M1_0 COMBINER_IRQ(5, 3)
71#define IRQ_SYSMMU_TV_M0_0 COMBINER_IRQ(5, 4)
72#define IRQ_SYSMMU_MFC_M0_0 COMBINER_IRQ(5, 5)
73#define IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6)
74#define IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7)
75
76#define IRQ_PDMA0 COMBINER_IRQ(21, 0)
77#define IRQ_PDMA1 COMBINER_IRQ(21, 1)
78
57#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0) 79#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0)
58#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1) 80#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1)
59#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2) 81#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2)
@@ -83,8 +105,13 @@
83#define IRQ_HSMMC2 COMBINER_IRQ(29, 2) 105#define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
84#define IRQ_HSMMC3 COMBINER_IRQ(29, 3) 106#define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
85 107
108#define IRQ_MIPI_CSIS0 COMBINER_IRQ(30, 0)
109#define IRQ_MIPI_CSIS1 COMBINER_IRQ(30, 1)
110
86#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0) 111#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
87 112
113#define IRQ_MCT_L1 COMBINER_IRQ(35, 3)
114
88#define IRQ_EINT4 COMBINER_IRQ(37, 0) 115#define IRQ_EINT4 COMBINER_IRQ(37, 0)
89#define IRQ_EINT5 COMBINER_IRQ(37, 1) 116#define IRQ_EINT5 COMBINER_IRQ(37, 1)
90#define IRQ_EINT6 COMBINER_IRQ(37, 2) 117#define IRQ_EINT6 COMBINER_IRQ(37, 2)
@@ -101,7 +128,11 @@
101 128
102#define IRQ_EINT16_31 COMBINER_IRQ(39, 0) 129#define IRQ_EINT16_31 COMBINER_IRQ(39, 0)
103 130
104#define MAX_COMBINER_NR 40 131#define IRQ_MCT_L0 COMBINER_IRQ(51, 0)
132
133#define IRQ_WDT COMBINER_IRQ(53, 0)
134
135#define MAX_COMBINER_NR 54
105 136
106#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0) 137#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
107 138
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h
index 7acf4e77e92e..74d400625a23 100644
--- a/arch/arm/mach-s5pv310/include/mach/map.h
+++ b/arch/arm/mach-s5pv310/include/mach/map.h
@@ -39,11 +39,15 @@
39#define S5PV310_PA_SYSCON (0x10010000) 39#define S5PV310_PA_SYSCON (0x10010000)
40#define S5P_PA_SYSCON S5PV310_PA_SYSCON 40#define S5P_PA_SYSCON S5PV310_PA_SYSCON
41 41
42#define S5PV310_PA_PMU (0x10020000)
43
42#define S5PV310_PA_CMU (0x10030000) 44#define S5PV310_PA_CMU (0x10030000)
43 45
44#define S5PV310_PA_WATCHDOG (0x10060000) 46#define S5PV310_PA_WATCHDOG (0x10060000)
45#define S5PV310_PA_RTC (0x10070000) 47#define S5PV310_PA_RTC (0x10070000)
46 48
49#define S5PV310_PA_DMC0 (0x10400000)
50
47#define S5PV310_PA_COMBINER (0x10448000) 51#define S5PV310_PA_COMBINER (0x10448000)
48 52
49#define S5PV310_PA_COREPERI (0x10500000) 53#define S5PV310_PA_COREPERI (0x10500000)
@@ -52,13 +56,38 @@
52#define S5PV310_PA_GIC_DIST (0x10501000) 56#define S5PV310_PA_GIC_DIST (0x10501000)
53#define S5PV310_PA_L2CC (0x10502000) 57#define S5PV310_PA_L2CC (0x10502000)
54 58
59/* DMA */
60#define S5PV310_PA_MDMA 0x10810000
61#define S5PV310_PA_PDMA0 0x12680000
62#define S5PV310_PA_PDMA1 0x12690000
63
55#define S5PV310_PA_GPIO1 (0x11400000) 64#define S5PV310_PA_GPIO1 (0x11400000)
56#define S5PV310_PA_GPIO2 (0x11000000) 65#define S5PV310_PA_GPIO2 (0x11000000)
57#define S5PV310_PA_GPIO3 (0x03860000) 66#define S5PV310_PA_GPIO3 (0x03860000)
58 67
68#define S5PV310_PA_MIPI_CSIS0 0x11880000
69#define S5PV310_PA_MIPI_CSIS1 0x11890000
70
59#define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) 71#define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
60 72
61#define S5PV310_PA_SROMC (0x12570000) 73#define S5PV310_PA_SROMC (0x12570000)
74#define S5P_PA_SROMC S5PV310_PA_SROMC
75
76/* S/PDIF */
77#define S5PV310_PA_SPDIF 0xE1100000
78
79/* I2S */
80#define S5PV310_PA_I2S0 0x03830000
81#define S5PV310_PA_I2S1 0xE3100000
82#define S5PV310_PA_I2S2 0xE2A00000
83
84/* PCM */
85#define S5PV310_PA_PCM0 0x03840000
86#define S5PV310_PA_PCM1 0x13980000
87#define S5PV310_PA_PCM2 0x13990000
88
89/* AC97 */
90#define S5PV310_PA_AC97 0x139A0000
62 91
63#define S5PV310_PA_UART (0x13800000) 92#define S5PV310_PA_UART (0x13800000)
64 93
@@ -79,6 +108,25 @@
79#define S5PV310_PA_SDRAM (0x40000000) 108#define S5PV310_PA_SDRAM (0x40000000)
80#define S5P_PA_SDRAM S5PV310_PA_SDRAM 109#define S5P_PA_SDRAM S5PV310_PA_SDRAM
81 110
111#define S5PV310_PA_SYSMMU_MDMA 0x10A40000
112#define S5PV310_PA_SYSMMU_SSS 0x10A50000
113#define S5PV310_PA_SYSMMU_FIMC0 0x11A20000
114#define S5PV310_PA_SYSMMU_FIMC1 0x11A30000
115#define S5PV310_PA_SYSMMU_FIMC2 0x11A40000
116#define S5PV310_PA_SYSMMU_FIMC3 0x11A50000
117#define S5PV310_PA_SYSMMU_JPEG 0x11A60000
118#define S5PV310_PA_SYSMMU_FIMD0 0x11E20000
119#define S5PV310_PA_SYSMMU_FIMD1 0x12220000
120#define S5PV310_PA_SYSMMU_PCIe 0x12620000
121#define S5PV310_PA_SYSMMU_G2D 0x12A20000
122#define S5PV310_PA_SYSMMU_ROTATOR 0x12A30000
123#define S5PV310_PA_SYSMMU_MDMA2 0x12A40000
124#define S5PV310_PA_SYSMMU_TV 0x12E20000
125#define S5PV310_PA_SYSMMU_MFC_L 0x13620000
126#define S5PV310_PA_SYSMMU_MFC_R 0x13630000
127#define S5PV310_SYSMMU_TOTAL_IPNUM 16
128#define S5P_SYSMMU_TOTAL_IPNUM S5PV310_SYSMMU_TOTAL_IPNUM
129
82/* compatibiltiy defines. */ 130/* compatibiltiy defines. */
83#define S3C_PA_UART S5PV310_PA_UART 131#define S3C_PA_UART S5PV310_PA_UART
84#define S3C_PA_HSMMC0 S5PV310_PA_HSMMC(0) 132#define S3C_PA_HSMMC0 S5PV310_PA_HSMMC(0)
@@ -95,5 +143,7 @@
95#define S3C_PA_IIC7 S5PV310_PA_IIC(7) 143#define S3C_PA_IIC7 S5PV310_PA_IIC(7)
96#define S3C_PA_RTC S5PV310_PA_RTC 144#define S3C_PA_RTC S5PV310_PA_RTC
97#define S3C_PA_WDT S5PV310_PA_WATCHDOG 145#define S3C_PA_WDT S5PV310_PA_WATCHDOG
146#define S5P_PA_MIPI_CSIS0 S5PV310_PA_MIPI_CSIS0
147#define S5P_PA_MIPI_CSIS1 S5PV310_PA_MIPI_CSIS1
98 148
99#endif /* __ASM_ARCH_MAP_H */ 149#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
index f1028cad9788..b5c4ada1cff5 100644
--- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
@@ -19,6 +19,12 @@
19 19
20#define S5P_INFORM0 S5P_CLKREG(0x800) 20#define S5P_INFORM0 S5P_CLKREG(0x800)
21 21
22#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500)
23#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600)
24
25#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500)
26#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600)
27
22#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110) 28#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110)
23#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114) 29#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114)
24#define S5P_VPLL_CON0 S5P_CLKREG(0x0C120) 30#define S5P_VPLL_CON0 S5P_CLKREG(0x0C120)
@@ -58,6 +64,8 @@
58#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350) 64#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
59#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354) 65#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
60 66
67#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610)
68
61#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920) 69#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
62#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930) 70#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
63#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934) 71#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
@@ -66,8 +74,9 @@
66#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) 74#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
67#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960) 75#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
68 76
69#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200) 77#define S5P_CLKSRC_DMC S5P_CLKREG(0x10200)
70#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500) 78#define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500)
79#define S5P_CLKDIV_STAT_DMC0 S5P_CLKREG(0x10600)
71 80
72#define S5P_APLL_LOCK S5P_CLKREG(0x14000) 81#define S5P_APLL_LOCK S5P_CLKREG(0x14000)
73#define S5P_MPLL_LOCK S5P_CLKREG(0x14004) 82#define S5P_MPLL_LOCK S5P_CLKREG(0x14004)
@@ -80,10 +89,77 @@
80#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400) 89#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400)
81 90
82#define S5P_CLKDIV_CPU S5P_CLKREG(0x14500) 91#define S5P_CLKDIV_CPU S5P_CLKREG(0x14500)
92#define S5P_CLKDIV_CPU1 S5P_CLKREG(0x14504)
83#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600) 93#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600)
94#define S5P_CLKDIV_STATCPU1 S5P_CLKREG(0x14604)
84 95
85#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) 96#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
86 97
98/* APLL_LOCK */
99#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */
100
101/* APLL_CON0 */
102#define S5P_APLLCON0_ENABLE_SHIFT (31)
103#define S5P_APLLCON0_LOCKED_SHIFT (29)
104#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1)
105#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1)
106
107/* CLK_SRC_CPU */
108#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16)
109#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
110
111/* CLKDIV_CPU0 */
112#define S5P_CLKDIV_CPU0_CORE_SHIFT (0)
113#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
114#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4)
115#define S5P_CLKDIV_CPU0_COREM0_MASK (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
116#define S5P_CLKDIV_CPU0_COREM1_SHIFT (8)
117#define S5P_CLKDIV_CPU0_COREM1_MASK (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
118#define S5P_CLKDIV_CPU0_PERIPH_SHIFT (12)
119#define S5P_CLKDIV_CPU0_PERIPH_MASK (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
120#define S5P_CLKDIV_CPU0_ATB_SHIFT (16)
121#define S5P_CLKDIV_CPU0_ATB_MASK (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
122#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT (20)
123#define S5P_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
124#define S5P_CLKDIV_CPU0_APLL_SHIFT (24)
125#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
126
127/* CLKDIV_DMC0 */
128#define S5P_CLKDIV_DMC0_ACP_SHIFT (0)
129#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
130#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4)
131#define S5P_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
132#define S5P_CLKDIV_DMC0_DPHY_SHIFT (8)
133#define S5P_CLKDIV_DMC0_DPHY_MASK (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
134#define S5P_CLKDIV_DMC0_DMC_SHIFT (12)
135#define S5P_CLKDIV_DMC0_DMC_MASK (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
136#define S5P_CLKDIV_DMC0_DMCD_SHIFT (16)
137#define S5P_CLKDIV_DMC0_DMCD_MASK (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
138#define S5P_CLKDIV_DMC0_DMCP_SHIFT (20)
139#define S5P_CLKDIV_DMC0_DMCP_MASK (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
140#define S5P_CLKDIV_DMC0_COPY2_SHIFT (24)
141#define S5P_CLKDIV_DMC0_COPY2_MASK (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
142#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28)
143#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
144
145/* CLKDIV_TOP */
146#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0)
147#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
148#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4)
149#define S5P_CLKDIV_TOP_ACLK100_MASK (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
150#define S5P_CLKDIV_TOP_ACLK160_SHIFT (8)
151#define S5P_CLKDIV_TOP_ACLK160_MASK (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
152#define S5P_CLKDIV_TOP_ACLK133_SHIFT (12)
153#define S5P_CLKDIV_TOP_ACLK133_MASK (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
154#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16)
155#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
156
157/* CLKDIV_LEFTBUS / CLKDIV_RIGHTBUS*/
158#define S5P_CLKDIV_BUS_GDLR_SHIFT (0)
159#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
160#define S5P_CLKDIV_BUS_GPLR_SHIFT (4)
161#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
162
87/* Compatibility defines */ 163/* Compatibility defines */
88 164
89#define S5P_EPLL_CON S5P_EPLL_CON0 165#define S5P_EPLL_CON S5P_EPLL_CON0
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-mem.h b/arch/arm/mach-s5pv310/include/mach/regs-mem.h
new file mode 100644
index 000000000000..834227140eaa
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-mem.h
@@ -0,0 +1,23 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/regs-mem.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - SROMC and DMC register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_MEM_H
14#define __ASM_ARCH_REGS_MEM_H __FILE__
15
16#include <mach/map.h>
17
18#define S5P_DMC0_MEMCON_OFFSET 0x04
19
20#define S5P_DMC0_MEMTYPE_SHIFT 8
21#define S5P_DMC0_MEMTYPE_MASK 0xF
22
23#endif /* __ASM_ARCH_REGS_MEM_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-pmu.h b/arch/arm/mach-s5pv310/include/mach/regs-pmu.h
new file mode 100644
index 000000000000..fb333d0f6073
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-pmu.h
@@ -0,0 +1,30 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/regs-pmu.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - Power management unit definition
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_PMU_H
14#define __ASM_ARCH_REGS_PMU_H __FILE__
15
16#include <mach/map.h>
17
18#define S5P_PMUREG(x) (S5P_VA_PMU + (x))
19
20#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00)
21#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20)
22#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40)
23#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60)
24#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80)
25#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
26#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0)
27
28#define S5P_INT_LOCAL_PWR_EN 0x7
29
30#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-srom.h b/arch/arm/mach-s5pv310/include/mach/regs-srom.h
deleted file mode 100644
index 1898b3e10550..000000000000
--- a/arch/arm/mach-s5pv310/include/mach/regs-srom.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/regs-srom.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - SROMC register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_SROM_H
14#define __ASM_ARCH_REGS_SROM_H __FILE__
15
16#include <mach/map.h>
17
18#define S5PV310_SROMREG(x) (S5P_VA_SROMC + (x))
19
20#define S5PV310_SROM_BW S5PV310_SROMREG(0x0)
21#define S5PV310_SROM_BC0 S5PV310_SROMREG(0x4)
22#define S5PV310_SROM_BC1 S5PV310_SROMREG(0x8)
23#define S5PV310_SROM_BC2 S5PV310_SROMREG(0xc)
24#define S5PV310_SROM_BC3 S5PV310_SROMREG(0x10)
25
26/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
27
28#define S5PV310_SROM_BW__DATAWIDTH__SHIFT 0
29#define S5PV310_SROM_BW__ADDRMODE__SHIFT 1
30#define S5PV310_SROM_BW__WAITENABLE__SHIFT 2
31#define S5PV310_SROM_BW__BYTEENABLE__SHIFT 3
32
33#define S5PV310_SROM_BW__CS_MASK 0xf
34
35#define S5PV310_SROM_BW__NCS0__SHIFT 0
36#define S5PV310_SROM_BW__NCS1__SHIFT 4
37#define S5PV310_SROM_BW__NCS2__SHIFT 8
38#define S5PV310_SROM_BW__NCS3__SHIFT 12
39
40/* applies to same to BCS0 - BCS3 */
41
42#define S5PV310_SROM_BCX__PMC__SHIFT 0
43#define S5PV310_SROM_BCX__TACP__SHIFT 4
44#define S5PV310_SROM_BCX__TCAH__SHIFT 8
45#define S5PV310_SROM_BCX__TCOH__SHIFT 12
46#define S5PV310_SROM_BCX__TACC__SHIFT 16
47#define S5PV310_SROM_BCX__TCOS__SHIFT 24
48#define S5PV310_SROM_BCX__TACS__SHIFT 28
49
50#endif /* __ASM_ARCH_REGS_SROM_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h b/arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h
new file mode 100644
index 000000000000..0b28e81a16f7
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h
@@ -0,0 +1,24 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - System MMU register
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_SYSMMU_H
14#define __ASM_ARCH_REGS_SYSMMU_H __FILE__
15
16#define S5P_MMU_CTRL 0x000
17#define S5P_MMU_CFG 0x004
18#define S5P_MMU_STATUS 0x008
19#define S5P_MMU_FLUSH 0x00C
20#define S5P_PT_BASE_ADDR 0x014
21#define S5P_INT_STATUS 0x018
22#define S5P_PAGE_FAULT_ADDR 0x024
23
24#endif /* __ASM_ARCH_REGS_SYSMMU_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/sysmmu.h b/arch/arm/mach-s5pv310/include/mach/sysmmu.h
new file mode 100644
index 000000000000..662fe85ff4d5
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/sysmmu.h
@@ -0,0 +1,119 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/sysmmu.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Samsung sysmmu driver for S5PV310
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARM_ARCH_SYSMMU_H
14#define __ASM_ARM_ARCH_SYSMMU_H __FILE__
15
16enum s5pv310_sysmmu_ips {
17 SYSMMU_MDMA,
18 SYSMMU_SSS,
19 SYSMMU_FIMC0,
20 SYSMMU_FIMC1,
21 SYSMMU_FIMC2,
22 SYSMMU_FIMC3,
23 SYSMMU_JPEG,
24 SYSMMU_FIMD0,
25 SYSMMU_FIMD1,
26 SYSMMU_PCIe,
27 SYSMMU_G2D,
28 SYSMMU_ROTATOR,
29 SYSMMU_MDMA2,
30 SYSMMU_TV,
31 SYSMMU_MFC_L,
32 SYSMMU_MFC_R,
33};
34
35static char *sysmmu_ips_name[S5P_SYSMMU_TOTAL_IPNUM] = {
36 "SYSMMU_MDMA" ,
37 "SYSMMU_SSS" ,
38 "SYSMMU_FIMC0" ,
39 "SYSMMU_FIMC1" ,
40 "SYSMMU_FIMC2" ,
41 "SYSMMU_FIMC3" ,
42 "SYSMMU_JPEG" ,
43 "SYSMMU_FIMD0" ,
44 "SYSMMU_FIMD1" ,
45 "SYSMMU_PCIe" ,
46 "SYSMMU_G2D" ,
47 "SYSMMU_ROTATOR",
48 "SYSMMU_MDMA2" ,
49 "SYSMMU_TV" ,
50 "SYSMMU_MFC_L" ,
51 "SYSMMU_MFC_R" ,
52};
53
54typedef enum s5pv310_sysmmu_ips sysmmu_ips;
55
56struct sysmmu_tt_info {
57 unsigned long *pgd;
58 unsigned long pgd_paddr;
59 unsigned long *pte;
60};
61
62struct sysmmu_controller {
63 const char *name;
64
65 /* channels registers */
66 void __iomem *regs;
67
68 /* channel irq */
69 unsigned int irq;
70
71 sysmmu_ips ips;
72
73 /* Translation Table Info. */
74 struct sysmmu_tt_info *tt_info;
75
76 struct resource *mem;
77 struct device *dev;
78
79 /* SysMMU controller enable - true : enable */
80 bool enable;
81};
82
83/**
84 * s5p_sysmmu_enable() - enable system mmu of ip
85 * @ips: The ip connected system mmu.
86 *
87 * This function enable system mmu to transfer address
88 * from virtual address to physical address
89 */
90int s5p_sysmmu_enable(sysmmu_ips ips);
91
92/**
93 * s5p_sysmmu_disable() - disable sysmmu mmu of ip
94 * @ips: The ip connected system mmu.
95 *
96 * This function disable system mmu to transfer address
97 * from virtual address to physical address
98 */
99int s5p_sysmmu_disable(sysmmu_ips ips);
100
101/**
102 * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table
103 * @ips: The ip connected system mmu.
104 * @pgd: The page table base address.
105 *
106 * This function set page table base address
107 * When system mmu transfer address from virtaul address to physical address,
108 * system mmu refer address information from page table
109 */
110int s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd);
111
112/**
113 * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
114 * @ips: The ip connected system mmu.
115 *
116 * This function flush all TLB entry in system mmu
117 */
118int s5p_sysmmu_tlb_invalidate(sysmmu_ips ips);
119#endif /* __ASM_ARM_ARCH_SYSMMU_H */
diff --git a/arch/arm/mach-s5pv310/irq-combiner.c b/arch/arm/mach-s5pv310/irq-combiner.c
index c3f88c3faf6c..1ea4a9e83bbe 100644
--- a/arch/arm/mach-s5pv310/irq-combiner.c
+++ b/arch/arm/mach-s5pv310/irq-combiner.c
@@ -24,29 +24,32 @@ static DEFINE_SPINLOCK(irq_controller_lock);
24 24
25struct combiner_chip_data { 25struct combiner_chip_data {
26 unsigned int irq_offset; 26 unsigned int irq_offset;
27 unsigned int irq_mask;
27 void __iomem *base; 28 void __iomem *base;
28}; 29};
29 30
30static struct combiner_chip_data combiner_data[MAX_COMBINER_NR]; 31static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
31 32
32static inline void __iomem *combiner_base(unsigned int irq) 33static inline void __iomem *combiner_base(struct irq_data *data)
33{ 34{
34 struct combiner_chip_data *combiner_data = get_irq_chip_data(irq); 35 struct combiner_chip_data *combiner_data =
36 irq_data_get_irq_chip_data(data);
37
35 return combiner_data->base; 38 return combiner_data->base;
36} 39}
37 40
38static void combiner_mask_irq(unsigned int irq) 41static void combiner_mask_irq(struct irq_data *data)
39{ 42{
40 u32 mask = 1 << (irq % 32); 43 u32 mask = 1 << (data->irq % 32);
41 44
42 __raw_writel(mask, combiner_base(irq) + COMBINER_ENABLE_CLEAR); 45 __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
43} 46}
44 47
45static void combiner_unmask_irq(unsigned int irq) 48static void combiner_unmask_irq(struct irq_data *data)
46{ 49{
47 u32 mask = 1 << (irq % 32); 50 u32 mask = 1 << (data->irq % 32);
48 51
49 __raw_writel(mask, combiner_base(irq) + COMBINER_ENABLE_SET); 52 __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
50} 53}
51 54
52static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) 55static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
@@ -57,11 +60,12 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
57 unsigned long status; 60 unsigned long status;
58 61
59 /* primary controller ack'ing */ 62 /* primary controller ack'ing */
60 chip->ack(irq); 63 chip->irq_ack(&desc->irq_data);
61 64
62 spin_lock(&irq_controller_lock); 65 spin_lock(&irq_controller_lock);
63 status = __raw_readl(chip_data->base + COMBINER_INT_STATUS); 66 status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
64 spin_unlock(&irq_controller_lock); 67 spin_unlock(&irq_controller_lock);
68 status &= chip_data->irq_mask;
65 69
66 if (status == 0) 70 if (status == 0)
67 goto out; 71 goto out;
@@ -76,13 +80,13 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
76 80
77 out: 81 out:
78 /* primary controller unmasking */ 82 /* primary controller unmasking */
79 chip->unmask(irq); 83 chip->irq_unmask(&desc->irq_data);
80} 84}
81 85
82static struct irq_chip combiner_chip = { 86static struct irq_chip combiner_chip = {
83 .name = "COMBINER", 87 .name = "COMBINER",
84 .mask = combiner_mask_irq, 88 .irq_mask = combiner_mask_irq,
85 .unmask = combiner_unmask_irq, 89 .irq_unmask = combiner_unmask_irq,
86}; 90};
87 91
88void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq) 92void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
@@ -104,10 +108,12 @@ void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
104 108
105 combiner_data[combiner_nr].base = base; 109 combiner_data[combiner_nr].base = base;
106 combiner_data[combiner_nr].irq_offset = irq_start; 110 combiner_data[combiner_nr].irq_offset = irq_start;
111 combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
107 112
108 /* Disable all interrupts */ 113 /* Disable all interrupts */
109 114
110 __raw_writel(0xffffffff, base + COMBINER_ENABLE_CLEAR); 115 __raw_writel(combiner_data[combiner_nr].irq_mask,
116 base + COMBINER_ENABLE_CLEAR);
111 117
112 /* Setup the Linux IRQ subsystem */ 118 /* Setup the Linux IRQ subsystem */
113 119
diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c
index 5877503e92c3..477bd9e97f0f 100644
--- a/arch/arm/mach-s5pv310/irq-eint.c
+++ b/arch/arm/mach-s5pv310/irq-eint.c
@@ -48,42 +48,43 @@ static unsigned int s5pv310_get_irq_nr(unsigned int number)
48 return ret; 48 return ret;
49} 49}
50 50
51static inline void s5pv310_irq_eint_mask(unsigned int irq) 51static inline void s5pv310_irq_eint_mask(struct irq_data *data)
52{ 52{
53 u32 mask; 53 u32 mask;
54 54
55 spin_lock(&eint_lock); 55 spin_lock(&eint_lock);
56 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq))); 56 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
57 mask |= eint_irq_to_bit(irq); 57 mask |= eint_irq_to_bit(data->irq);
58 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq))); 58 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
59 spin_unlock(&eint_lock); 59 spin_unlock(&eint_lock);
60} 60}
61 61
62static void s5pv310_irq_eint_unmask(unsigned int irq) 62static void s5pv310_irq_eint_unmask(struct irq_data *data)
63{ 63{
64 u32 mask; 64 u32 mask;
65 65
66 spin_lock(&eint_lock); 66 spin_lock(&eint_lock);
67 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq))); 67 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
68 mask &= ~(eint_irq_to_bit(irq)); 68 mask &= ~(eint_irq_to_bit(data->irq));
69 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq))); 69 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
70 spin_unlock(&eint_lock); 70 spin_unlock(&eint_lock);
71} 71}
72 72
73static inline void s5pv310_irq_eint_ack(unsigned int irq) 73static inline void s5pv310_irq_eint_ack(struct irq_data *data)
74{ 74{
75 __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq))); 75 __raw_writel(eint_irq_to_bit(data->irq),
76 S5P_EINT_PEND(EINT_REG_NR(data->irq)));
76} 77}
77 78
78static void s5pv310_irq_eint_maskack(unsigned int irq) 79static void s5pv310_irq_eint_maskack(struct irq_data *data)
79{ 80{
80 s5pv310_irq_eint_mask(irq); 81 s5pv310_irq_eint_mask(data);
81 s5pv310_irq_eint_ack(irq); 82 s5pv310_irq_eint_ack(data);
82} 83}
83 84
84static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type) 85static int s5pv310_irq_eint_set_type(struct irq_data *data, unsigned int type)
85{ 86{
86 int offs = EINT_OFFSET(irq); 87 int offs = EINT_OFFSET(data->irq);
87 int shift; 88 int shift;
88 u32 ctrl, mask; 89 u32 ctrl, mask;
89 u32 newvalue = 0; 90 u32 newvalue = 0;
@@ -118,10 +119,10 @@ static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type)
118 mask = 0x7 << shift; 119 mask = 0x7 << shift;
119 120
120 spin_lock(&eint_lock); 121 spin_lock(&eint_lock);
121 ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(irq))); 122 ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
122 ctrl &= ~mask; 123 ctrl &= ~mask;
123 ctrl |= newvalue << shift; 124 ctrl |= newvalue << shift;
124 __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(irq))); 125 __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
125 spin_unlock(&eint_lock); 126 spin_unlock(&eint_lock);
126 127
127 switch (offs) { 128 switch (offs) {
@@ -146,13 +147,13 @@ static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type)
146 147
147static struct irq_chip s5pv310_irq_eint = { 148static struct irq_chip s5pv310_irq_eint = {
148 .name = "s5pv310-eint", 149 .name = "s5pv310-eint",
149 .mask = s5pv310_irq_eint_mask, 150 .irq_mask = s5pv310_irq_eint_mask,
150 .unmask = s5pv310_irq_eint_unmask, 151 .irq_unmask = s5pv310_irq_eint_unmask,
151 .mask_ack = s5pv310_irq_eint_maskack, 152 .irq_mask_ack = s5pv310_irq_eint_maskack,
152 .ack = s5pv310_irq_eint_ack, 153 .irq_ack = s5pv310_irq_eint_ack,
153 .set_type = s5pv310_irq_eint_set_type, 154 .irq_set_type = s5pv310_irq_eint_set_type,
154#ifdef CONFIG_PM 155#ifdef CONFIG_PM
155 .set_wake = s3c_irqext_wake, 156 .irq_set_wake = s3c_irqext_wake,
156#endif 157#endif
157}; 158};
158 159
@@ -192,14 +193,14 @@ static void s5pv310_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
192 u32 *irq_data = get_irq_data(irq); 193 u32 *irq_data = get_irq_data(irq);
193 struct irq_chip *chip = get_irq_chip(irq); 194 struct irq_chip *chip = get_irq_chip(irq);
194 195
195 chip->mask(irq); 196 chip->irq_mask(&desc->irq_data);
196 197
197 if (chip->ack) 198 if (chip->irq_ack)
198 chip->ack(irq); 199 chip->irq_ack(&desc->irq_data);
199 200
200 generic_handle_irq(*irq_data); 201 generic_handle_irq(*irq_data);
201 202
202 chip->unmask(irq); 203 chip->irq_unmask(&desc->irq_data);
203} 204}
204 205
205int __init s5pv310_init_irq_eint(void) 206int __init s5pv310_init_irq_eint(void)
diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c
index 2b8d4fc52d7c..2d49273c0a26 100644
--- a/arch/arm/mach-s5pv310/mach-smdkc210.c
+++ b/arch/arm/mach-s5pv310/mach-smdkc210.c
@@ -14,18 +14,21 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/smsc911x.h> 15#include <linux/smsc911x.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/i2c.h>
17 18
18#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
19#include <asm/mach-types.h> 20#include <asm/mach-types.h>
20 21
21#include <plat/regs-serial.h> 22#include <plat/regs-serial.h>
23#include <plat/regs-srom.h>
22#include <plat/s5pv310.h> 24#include <plat/s5pv310.h>
23#include <plat/cpu.h> 25#include <plat/cpu.h>
24#include <plat/devs.h> 26#include <plat/devs.h>
25#include <plat/sdhci.h> 27#include <plat/sdhci.h>
28#include <plat/iic.h>
29#include <plat/pd.h>
26 30
27#include <mach/map.h> 31#include <mach/map.h>
28#include <mach/regs-srom.h>
29 32
30/* Following are default values for UCON, ULCON and UFCON UART registers */ 33/* Following are default values for UCON, ULCON and UFCON UART registers */
31#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 34#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -139,14 +142,29 @@ static struct platform_device smdkc210_smsc911x = {
139 }, 142 },
140}; 143};
141 144
145static struct i2c_board_info i2c_devs1[] __initdata = {
146 {I2C_BOARD_INFO("wm8994", 0x1a),},
147};
148
142static struct platform_device *smdkc210_devices[] __initdata = { 149static struct platform_device *smdkc210_devices[] __initdata = {
143 &s3c_device_hsmmc0, 150 &s3c_device_hsmmc0,
144 &s3c_device_hsmmc1, 151 &s3c_device_hsmmc1,
145 &s3c_device_hsmmc2, 152 &s3c_device_hsmmc2,
146 &s3c_device_hsmmc3, 153 &s3c_device_hsmmc3,
154 &s3c_device_i2c1,
147 &s3c_device_rtc, 155 &s3c_device_rtc,
148 &s3c_device_wdt, 156 &s3c_device_wdt,
157 &s5pv310_device_ac97,
158 &s5pv310_device_i2s0,
159 &s5pv310_device_pd[PD_MFC],
160 &s5pv310_device_pd[PD_G3D],
161 &s5pv310_device_pd[PD_LCD0],
162 &s5pv310_device_pd[PD_LCD1],
163 &s5pv310_device_pd[PD_CAM],
164 &s5pv310_device_pd[PD_TV],
165 &s5pv310_device_pd[PD_GPS],
149 &smdkc210_smsc911x, 166 &smdkc210_smsc911x,
167 &s5pv310_device_sysmmu,
150}; 168};
151 169
152static void __init smdkc210_smsc911x_init(void) 170static void __init smdkc210_smsc911x_init(void)
@@ -154,23 +172,22 @@ static void __init smdkc210_smsc911x_init(void)
154 u32 cs1; 172 u32 cs1;
155 173
156 /* configure nCS1 width to 16 bits */ 174 /* configure nCS1 width to 16 bits */
157 cs1 = __raw_readl(S5PV310_SROM_BW) & 175 cs1 = __raw_readl(S5P_SROM_BW) &
158 ~(S5PV310_SROM_BW__CS_MASK << 176 ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
159 S5PV310_SROM_BW__NCS1__SHIFT); 177 cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
160 cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) | 178 (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
161 (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) | 179 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
162 (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) << 180 S5P_SROM_BW__NCS1__SHIFT;
163 S5PV310_SROM_BW__NCS1__SHIFT; 181 __raw_writel(cs1, S5P_SROM_BW);
164 __raw_writel(cs1, S5PV310_SROM_BW);
165 182
166 /* set timing for nCS1 suitable for ethernet chip */ 183 /* set timing for nCS1 suitable for ethernet chip */
167 __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) | 184 __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
168 (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) | 185 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
169 (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) | 186 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
170 (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) | 187 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
171 (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) | 188 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
172 (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) | 189 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
173 (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1); 190 (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
174} 191}
175 192
176static void __init smdkc210_map_io(void) 193static void __init smdkc210_map_io(void)
@@ -182,6 +199,9 @@ static void __init smdkc210_map_io(void)
182 199
183static void __init smdkc210_machine_init(void) 200static void __init smdkc210_machine_init(void)
184{ 201{
202 s3c_i2c1_set_platdata(NULL);
203 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
204
185 smdkc210_smsc911x_init(); 205 smdkc210_smsc911x_init();
186 206
187 s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata); 207 s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata);
diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c
index 35826d66632c..28680cf9a72c 100644
--- a/arch/arm/mach-s5pv310/mach-smdkv310.c
+++ b/arch/arm/mach-s5pv310/mach-smdkv310.c
@@ -14,18 +14,21 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/smsc911x.h> 15#include <linux/smsc911x.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/i2c.h>
17 18
18#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
19#include <asm/mach-types.h> 20#include <asm/mach-types.h>
20 21
21#include <plat/regs-serial.h> 22#include <plat/regs-serial.h>
23#include <plat/regs-srom.h>
22#include <plat/s5pv310.h> 24#include <plat/s5pv310.h>
23#include <plat/cpu.h> 25#include <plat/cpu.h>
24#include <plat/devs.h> 26#include <plat/devs.h>
25#include <plat/sdhci.h> 27#include <plat/sdhci.h>
28#include <plat/iic.h>
29#include <plat/pd.h>
26 30
27#include <mach/map.h> 31#include <mach/map.h>
28#include <mach/regs-srom.h>
29 32
30/* Following are default values for UCON, ULCON and UFCON UART registers */ 33/* Following are default values for UCON, ULCON and UFCON UART registers */
31#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 34#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -139,14 +142,29 @@ static struct platform_device smdkv310_smsc911x = {
139 }, 142 },
140}; 143};
141 144
145static struct i2c_board_info i2c_devs1[] __initdata = {
146 {I2C_BOARD_INFO("wm8994", 0x1a),},
147};
148
142static struct platform_device *smdkv310_devices[] __initdata = { 149static struct platform_device *smdkv310_devices[] __initdata = {
143 &s3c_device_hsmmc0, 150 &s3c_device_hsmmc0,
144 &s3c_device_hsmmc1, 151 &s3c_device_hsmmc1,
145 &s3c_device_hsmmc2, 152 &s3c_device_hsmmc2,
146 &s3c_device_hsmmc3, 153 &s3c_device_hsmmc3,
154 &s3c_device_i2c1,
147 &s3c_device_rtc, 155 &s3c_device_rtc,
148 &s3c_device_wdt, 156 &s3c_device_wdt,
157 &s5pv310_device_ac97,
158 &s5pv310_device_i2s0,
159 &s5pv310_device_pd[PD_MFC],
160 &s5pv310_device_pd[PD_G3D],
161 &s5pv310_device_pd[PD_LCD0],
162 &s5pv310_device_pd[PD_LCD1],
163 &s5pv310_device_pd[PD_CAM],
164 &s5pv310_device_pd[PD_TV],
165 &s5pv310_device_pd[PD_GPS],
149 &smdkv310_smsc911x, 166 &smdkv310_smsc911x,
167 &s5pv310_device_sysmmu,
150}; 168};
151 169
152static void __init smdkv310_smsc911x_init(void) 170static void __init smdkv310_smsc911x_init(void)
@@ -154,23 +172,22 @@ static void __init smdkv310_smsc911x_init(void)
154 u32 cs1; 172 u32 cs1;
155 173
156 /* configure nCS1 width to 16 bits */ 174 /* configure nCS1 width to 16 bits */
157 cs1 = __raw_readl(S5PV310_SROM_BW) & 175 cs1 = __raw_readl(S5P_SROM_BW) &
158 ~(S5PV310_SROM_BW__CS_MASK << 176 ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
159 S5PV310_SROM_BW__NCS1__SHIFT); 177 cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
160 cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) | 178 (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
161 (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) | 179 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
162 (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) << 180 S5P_SROM_BW__NCS1__SHIFT;
163 S5PV310_SROM_BW__NCS1__SHIFT; 181 __raw_writel(cs1, S5P_SROM_BW);
164 __raw_writel(cs1, S5PV310_SROM_BW);
165 182
166 /* set timing for nCS1 suitable for ethernet chip */ 183 /* set timing for nCS1 suitable for ethernet chip */
167 __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) | 184 __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
168 (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) | 185 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
169 (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) | 186 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
170 (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) | 187 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
171 (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) | 188 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
172 (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) | 189 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
173 (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1); 190 (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
174} 191}
175 192
176static void __init smdkv310_map_io(void) 193static void __init smdkv310_map_io(void)
@@ -182,6 +199,9 @@ static void __init smdkv310_map_io(void)
182 199
183static void __init smdkv310_machine_init(void) 200static void __init smdkv310_machine_init(void)
184{ 201{
202 s3c_i2c1_set_platdata(NULL);
203 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
204
185 smdkv310_smsc911x_init(); 205 smdkv310_smsc911x_init();
186 206
187 s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata); 207 s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
diff --git a/arch/arm/mach-s5pv310/mach-universal_c210.c b/arch/arm/mach-s5pv310/mach-universal_c210.c
index 16d8fc00cafd..36bc3cf825e3 100644
--- a/arch/arm/mach-s5pv310/mach-universal_c210.c
+++ b/arch/arm/mach-s5pv310/mach-universal_c210.c
@@ -13,6 +13,9 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/gpio_keys.h> 14#include <linux/gpio_keys.h>
15#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/regulator/machine.h>
17#include <linux/regulator/fixed.h>
18#include <linux/mmc/host.h>
16 19
17#include <asm/mach/arch.h> 20#include <asm/mach/arch.h>
18#include <asm/mach-types.h> 21#include <asm/mach-types.h>
@@ -21,6 +24,7 @@
21#include <plat/s5pv310.h> 24#include <plat/s5pv310.h>
22#include <plat/cpu.h> 25#include <plat/cpu.h>
23#include <plat/devs.h> 26#include <plat/devs.h>
27#include <plat/sdhci.h>
24 28
25#include <mach/map.h> 29#include <mach/map.h>
26 30
@@ -116,6 +120,73 @@ static struct platform_device universal_gpio_keys = {
116 }, 120 },
117}; 121};
118 122
123/* eMMC */
124static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
125 .max_width = 8,
126 .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
127 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
128 MMC_CAP_DISABLE),
129 .cd_type = S3C_SDHCI_CD_PERMANENT,
130 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
131};
132
133static struct regulator_consumer_supply mmc0_supplies[] = {
134 REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
135};
136
137static struct regulator_init_data mmc0_fixed_voltage_init_data = {
138 .constraints = {
139 .name = "VMEM_VDD_2.8V",
140 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
141 },
142 .num_consumer_supplies = ARRAY_SIZE(mmc0_supplies),
143 .consumer_supplies = mmc0_supplies,
144};
145
146static struct fixed_voltage_config mmc0_fixed_voltage_config = {
147 .supply_name = "MASSMEMORY_EN",
148 .microvolts = 2800000,
149 .gpio = S5PV310_GPE1(3),
150 .enable_high = true,
151 .init_data = &mmc0_fixed_voltage_init_data,
152};
153
154static struct platform_device mmc0_fixed_voltage = {
155 .name = "reg-fixed-voltage",
156 .id = 0,
157 .dev = {
158 .platform_data = &mmc0_fixed_voltage_config,
159 },
160};
161
162/* SD */
163static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = {
164 .max_width = 4,
165 .host_caps = MMC_CAP_4_BIT_DATA |
166 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
167 MMC_CAP_DISABLE,
168 .ext_cd_gpio = S5PV310_GPX3(4), /* XEINT_28 */
169 .ext_cd_gpio_invert = 1,
170 .cd_type = S3C_SDHCI_CD_GPIO,
171 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
172};
173
174/* WiFi */
175static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = {
176 .max_width = 4,
177 .host_caps = MMC_CAP_4_BIT_DATA |
178 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
179 MMC_CAP_DISABLE,
180 .cd_type = S3C_SDHCI_CD_EXTERNAL,
181};
182
183static void __init universal_sdhci_init(void)
184{
185 s3c_sdhci0_set_platdata(&universal_hsmmc0_data);
186 s3c_sdhci2_set_platdata(&universal_hsmmc2_data);
187 s3c_sdhci3_set_platdata(&universal_hsmmc3_data);
188}
189
119/* I2C0 */ 190/* I2C0 */
120static struct i2c_board_info i2c0_devs[] __initdata = { 191static struct i2c_board_info i2c0_devs[] __initdata = {
121 /* Camera, To be updated */ 192 /* Camera, To be updated */
@@ -127,6 +198,13 @@ static struct i2c_board_info i2c1_devs[] __initdata = {
127}; 198};
128 199
129static struct platform_device *universal_devices[] __initdata = { 200static struct platform_device *universal_devices[] __initdata = {
201 /* Samsung Platform Devices */
202 &mmc0_fixed_voltage,
203 &s3c_device_hsmmc0,
204 &s3c_device_hsmmc2,
205 &s3c_device_hsmmc3,
206
207 /* Universal Devices */
130 &universal_gpio_keys, 208 &universal_gpio_keys,
131 &s5p_device_onenand, 209 &s5p_device_onenand,
132}; 210};
@@ -140,6 +218,8 @@ static void __init universal_map_io(void)
140 218
141static void __init universal_machine_init(void) 219static void __init universal_machine_init(void)
142{ 220{
221 universal_sdhci_init();
222
143 i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs)); 223 i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
144 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); 224 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
145 225
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 2f91057a0c02..10ce6666687e 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -194,7 +194,6 @@ void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_
194 memcpy(&s3c2410ts_info, hard_s3c2410ts_info, sizeof(struct s3c2410_ts_mach_info)); 194 memcpy(&s3c2410ts_info, hard_s3c2410ts_info, sizeof(struct s3c2410_ts_mach_info));
195 s3c_device_ts.dev.platform_data = &s3c2410ts_info; 195 s3c_device_ts.dev.platform_data = &s3c2410ts_info;
196} 196}
197EXPORT_SYMBOL(s3c24xx_ts_set_platdata);
198 197
199/* USB Device (Gadget)*/ 198/* USB Device (Gadget)*/
200 199
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h
index 69e1be8bec35..ec087d6054b1 100644
--- a/arch/arm/plat-s3c24xx/include/plat/irq.h
+++ b/arch/arm/plat-s3c24xx/include/plat/irq.h
@@ -107,9 +107,9 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
107/* exported for use in arch/arm/mach-s3c2410 */ 107/* exported for use in arch/arm/mach-s3c2410 */
108 108
109#ifdef CONFIG_PM 109#ifdef CONFIG_PM
110extern int s3c_irq_wake(unsigned int irqno, unsigned int state); 110extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
111#else 111#else
112#define s3c_irq_wake NULL 112#define s3c_irq_wake NULL
113#endif 113#endif
114 114
115extern int s3c_irqext_type(unsigned int irq, unsigned int type); 115extern int s3c_irqext_type(struct irq_data *d, unsigned int type);
diff --git a/arch/arm/plat-s3c24xx/irq-pm.c b/arch/arm/plat-s3c24xx/irq-pm.c
index ea8dea3339a4..c3624d898630 100644
--- a/arch/arm/plat-s3c24xx/irq-pm.c
+++ b/arch/arm/plat-s3c24xx/irq-pm.c
@@ -15,11 +15,14 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/sysdev.h> 17#include <linux/sysdev.h>
18#include <linux/irq.h>
18 19
19#include <plat/cpu.h> 20#include <plat/cpu.h>
20#include <plat/pm.h> 21#include <plat/pm.h>
21#include <plat/irq.h> 22#include <plat/irq.h>
22 23
24#include <asm/irq.h>
25
23/* state for IRQs over sleep */ 26/* state for IRQs over sleep */
24 27
25/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources 28/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
@@ -30,15 +33,15 @@
30unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL; 33unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
31unsigned long s3c_irqwake_eintallow = 0x0000fff0L; 34unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
32 35
33int s3c_irq_wake(unsigned int irqno, unsigned int state) 36int s3c_irq_wake(struct irq_data *data, unsigned int state)
34{ 37{
35 unsigned long irqbit = 1 << (irqno - IRQ_EINT0); 38 unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
36 39
37 if (!(s3c_irqwake_intallow & irqbit)) 40 if (!(s3c_irqwake_intallow & irqbit))
38 return -ENOENT; 41 return -ENOENT;
39 42
40 printk(KERN_INFO "wake %s for irq %d\n", 43 printk(KERN_INFO "wake %s for irq %d\n",
41 state ? "enabled" : "disabled", irqno); 44 state ? "enabled" : "disabled", data->irq);
42 45
43 if (!state) 46 if (!state)
44 s3c_irqwake_intmask |= irqbit; 47 s3c_irqwake_intmask |= irqbit;
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ad0d44ef1f93..4434cb56bd9a 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -34,30 +34,29 @@
34#include <plat/irq.h> 34#include <plat/irq.h>
35 35
36static void 36static void
37s3c_irq_mask(unsigned int irqno) 37s3c_irq_mask(struct irq_data *data)
38{ 38{
39 unsigned int irqno = data->irq - IRQ_EINT0;
39 unsigned long mask; 40 unsigned long mask;
40 41
41 irqno -= IRQ_EINT0;
42
43 mask = __raw_readl(S3C2410_INTMSK); 42 mask = __raw_readl(S3C2410_INTMSK);
44 mask |= 1UL << irqno; 43 mask |= 1UL << irqno;
45 __raw_writel(mask, S3C2410_INTMSK); 44 __raw_writel(mask, S3C2410_INTMSK);
46} 45}
47 46
48static inline void 47static inline void
49s3c_irq_ack(unsigned int irqno) 48s3c_irq_ack(struct irq_data *data)
50{ 49{
51 unsigned long bitval = 1UL << (irqno - IRQ_EINT0); 50 unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
52 51
53 __raw_writel(bitval, S3C2410_SRCPND); 52 __raw_writel(bitval, S3C2410_SRCPND);
54 __raw_writel(bitval, S3C2410_INTPND); 53 __raw_writel(bitval, S3C2410_INTPND);
55} 54}
56 55
57static inline void 56static inline void
58s3c_irq_maskack(unsigned int irqno) 57s3c_irq_maskack(struct irq_data *data)
59{ 58{
60 unsigned long bitval = 1UL << (irqno - IRQ_EINT0); 59 unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
61 unsigned long mask; 60 unsigned long mask;
62 61
63 mask = __raw_readl(S3C2410_INTMSK); 62 mask = __raw_readl(S3C2410_INTMSK);
@@ -69,8 +68,9 @@ s3c_irq_maskack(unsigned int irqno)
69 68
70 69
71static void 70static void
72s3c_irq_unmask(unsigned int irqno) 71s3c_irq_unmask(struct irq_data *data)
73{ 72{
73 unsigned int irqno = data->irq;
74 unsigned long mask; 74 unsigned long mask;
75 75
76 if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23) 76 if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
@@ -85,40 +85,39 @@ s3c_irq_unmask(unsigned int irqno)
85 85
86struct irq_chip s3c_irq_level_chip = { 86struct irq_chip s3c_irq_level_chip = {
87 .name = "s3c-level", 87 .name = "s3c-level",
88 .ack = s3c_irq_maskack, 88 .irq_ack = s3c_irq_maskack,
89 .mask = s3c_irq_mask, 89 .irq_mask = s3c_irq_mask,
90 .unmask = s3c_irq_unmask, 90 .irq_unmask = s3c_irq_unmask,
91 .set_wake = s3c_irq_wake 91 .irq_set_wake = s3c_irq_wake
92}; 92};
93 93
94struct irq_chip s3c_irq_chip = { 94struct irq_chip s3c_irq_chip = {
95 .name = "s3c", 95 .name = "s3c",
96 .ack = s3c_irq_ack, 96 .irq_ack = s3c_irq_ack,
97 .mask = s3c_irq_mask, 97 .irq_mask = s3c_irq_mask,
98 .unmask = s3c_irq_unmask, 98 .irq_unmask = s3c_irq_unmask,
99 .set_wake = s3c_irq_wake 99 .irq_set_wake = s3c_irq_wake
100}; 100};
101 101
102static void 102static void
103s3c_irqext_mask(unsigned int irqno) 103s3c_irqext_mask(struct irq_data *data)
104{ 104{
105 unsigned int irqno = data->irq - EXTINT_OFF;
105 unsigned long mask; 106 unsigned long mask;
106 107
107 irqno -= EXTINT_OFF;
108
109 mask = __raw_readl(S3C24XX_EINTMASK); 108 mask = __raw_readl(S3C24XX_EINTMASK);
110 mask |= ( 1UL << irqno); 109 mask |= ( 1UL << irqno);
111 __raw_writel(mask, S3C24XX_EINTMASK); 110 __raw_writel(mask, S3C24XX_EINTMASK);
112} 111}
113 112
114static void 113static void
115s3c_irqext_ack(unsigned int irqno) 114s3c_irqext_ack(struct irq_data *data)
116{ 115{
117 unsigned long req; 116 unsigned long req;
118 unsigned long bit; 117 unsigned long bit;
119 unsigned long mask; 118 unsigned long mask;
120 119
121 bit = 1UL << (irqno - EXTINT_OFF); 120 bit = 1UL << (data->irq - EXTINT_OFF);
122 121
123 mask = __raw_readl(S3C24XX_EINTMASK); 122 mask = __raw_readl(S3C24XX_EINTMASK);
124 123
@@ -129,64 +128,57 @@ s3c_irqext_ack(unsigned int irqno)
129 128
130 /* not sure if we should be acking the parent irq... */ 129 /* not sure if we should be acking the parent irq... */
131 130
132 if (irqno <= IRQ_EINT7 ) { 131 if (data->irq <= IRQ_EINT7) {
133 if ((req & 0xf0) == 0) 132 if ((req & 0xf0) == 0)
134 s3c_irq_ack(IRQ_EINT4t7); 133 s3c_irq_ack(irq_get_irq_data(IRQ_EINT4t7));
135 } else { 134 } else {
136 if ((req >> 8) == 0) 135 if ((req >> 8) == 0)
137 s3c_irq_ack(IRQ_EINT8t23); 136 s3c_irq_ack(irq_get_irq_data(IRQ_EINT8t23));
138 } 137 }
139} 138}
140 139
141static void 140static void
142s3c_irqext_unmask(unsigned int irqno) 141s3c_irqext_unmask(struct irq_data *data)
143{ 142{
143 unsigned int irqno = data->irq - EXTINT_OFF;
144 unsigned long mask; 144 unsigned long mask;
145 145
146 irqno -= EXTINT_OFF;
147
148 mask = __raw_readl(S3C24XX_EINTMASK); 146 mask = __raw_readl(S3C24XX_EINTMASK);
149 mask &= ~( 1UL << irqno); 147 mask &= ~(1UL << irqno);
150 __raw_writel(mask, S3C24XX_EINTMASK); 148 __raw_writel(mask, S3C24XX_EINTMASK);
151} 149}
152 150
153int 151int
154s3c_irqext_type(unsigned int irq, unsigned int type) 152s3c_irqext_type(struct irq_data *data, unsigned int type)
155{ 153{
156 void __iomem *extint_reg; 154 void __iomem *extint_reg;
157 void __iomem *gpcon_reg; 155 void __iomem *gpcon_reg;
158 unsigned long gpcon_offset, extint_offset; 156 unsigned long gpcon_offset, extint_offset;
159 unsigned long newvalue = 0, value; 157 unsigned long newvalue = 0, value;
160 158
161 if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3)) 159 if ((data->irq >= IRQ_EINT0) && (data->irq <= IRQ_EINT3)) {
162 {
163 gpcon_reg = S3C2410_GPFCON; 160 gpcon_reg = S3C2410_GPFCON;
164 extint_reg = S3C24XX_EXTINT0; 161 extint_reg = S3C24XX_EXTINT0;
165 gpcon_offset = (irq - IRQ_EINT0) * 2; 162 gpcon_offset = (data->irq - IRQ_EINT0) * 2;
166 extint_offset = (irq - IRQ_EINT0) * 4; 163 extint_offset = (data->irq - IRQ_EINT0) * 4;
167 } 164 } else if ((data->irq >= IRQ_EINT4) && (data->irq <= IRQ_EINT7)) {
168 else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
169 {
170 gpcon_reg = S3C2410_GPFCON; 165 gpcon_reg = S3C2410_GPFCON;
171 extint_reg = S3C24XX_EXTINT0; 166 extint_reg = S3C24XX_EXTINT0;
172 gpcon_offset = (irq - (EXTINT_OFF)) * 2; 167 gpcon_offset = (data->irq - (EXTINT_OFF)) * 2;
173 extint_offset = (irq - (EXTINT_OFF)) * 4; 168 extint_offset = (data->irq - (EXTINT_OFF)) * 4;
174 } 169 } else if ((data->irq >= IRQ_EINT8) && (data->irq <= IRQ_EINT15)) {
175 else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
176 {
177 gpcon_reg = S3C2410_GPGCON; 170 gpcon_reg = S3C2410_GPGCON;
178 extint_reg = S3C24XX_EXTINT1; 171 extint_reg = S3C24XX_EXTINT1;
179 gpcon_offset = (irq - IRQ_EINT8) * 2; 172 gpcon_offset = (data->irq - IRQ_EINT8) * 2;
180 extint_offset = (irq - IRQ_EINT8) * 4; 173 extint_offset = (data->irq - IRQ_EINT8) * 4;
181 } 174 } else if ((data->irq >= IRQ_EINT16) && (data->irq <= IRQ_EINT23)) {
182 else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
183 {
184 gpcon_reg = S3C2410_GPGCON; 175 gpcon_reg = S3C2410_GPGCON;
185 extint_reg = S3C24XX_EXTINT2; 176 extint_reg = S3C24XX_EXTINT2;
186 gpcon_offset = (irq - IRQ_EINT8) * 2; 177 gpcon_offset = (data->irq - IRQ_EINT8) * 2;
187 extint_offset = (irq - IRQ_EINT16) * 4; 178 extint_offset = (data->irq - IRQ_EINT16) * 4;
188 } else 179 } else {
189 return -1; 180 return -1;
181 }
190 182
191 /* Set the GPIO to external interrupt mode */ 183 /* Set the GPIO to external interrupt mode */
192 value = __raw_readl(gpcon_reg); 184 value = __raw_readl(gpcon_reg);
@@ -234,20 +226,20 @@ s3c_irqext_type(unsigned int irq, unsigned int type)
234 226
235static struct irq_chip s3c_irqext_chip = { 227static struct irq_chip s3c_irqext_chip = {
236 .name = "s3c-ext", 228 .name = "s3c-ext",
237 .mask = s3c_irqext_mask, 229 .irq_mask = s3c_irqext_mask,
238 .unmask = s3c_irqext_unmask, 230 .irq_unmask = s3c_irqext_unmask,
239 .ack = s3c_irqext_ack, 231 .irq_ack = s3c_irqext_ack,
240 .set_type = s3c_irqext_type, 232 .irq_set_type = s3c_irqext_type,
241 .set_wake = s3c_irqext_wake 233 .irq_set_wake = s3c_irqext_wake
242}; 234};
243 235
244static struct irq_chip s3c_irq_eint0t4 = { 236static struct irq_chip s3c_irq_eint0t4 = {
245 .name = "s3c-ext0", 237 .name = "s3c-ext0",
246 .ack = s3c_irq_ack, 238 .irq_ack = s3c_irq_ack,
247 .mask = s3c_irq_mask, 239 .irq_mask = s3c_irq_mask,
248 .unmask = s3c_irq_unmask, 240 .irq_unmask = s3c_irq_unmask,
249 .set_wake = s3c_irq_wake, 241 .irq_set_wake = s3c_irq_wake,
250 .set_type = s3c_irqext_type, 242 .irq_set_type = s3c_irqext_type,
251}; 243};
252 244
253/* mask values for the parent registers for each of the interrupt types */ 245/* mask values for the parent registers for each of the interrupt types */
@@ -261,109 +253,109 @@ static struct irq_chip s3c_irq_eint0t4 = {
261/* UART0 */ 253/* UART0 */
262 254
263static void 255static void
264s3c_irq_uart0_mask(unsigned int irqno) 256s3c_irq_uart0_mask(struct irq_data *data)
265{ 257{
266 s3c_irqsub_mask(irqno, INTMSK_UART0, 7); 258 s3c_irqsub_mask(data->irq, INTMSK_UART0, 7);
267} 259}
268 260
269static void 261static void
270s3c_irq_uart0_unmask(unsigned int irqno) 262s3c_irq_uart0_unmask(struct irq_data *data)
271{ 263{
272 s3c_irqsub_unmask(irqno, INTMSK_UART0); 264 s3c_irqsub_unmask(data->irq, INTMSK_UART0);
273} 265}
274 266
275static void 267static void
276s3c_irq_uart0_ack(unsigned int irqno) 268s3c_irq_uart0_ack(struct irq_data *data)
277{ 269{
278 s3c_irqsub_maskack(irqno, INTMSK_UART0, 7); 270 s3c_irqsub_maskack(data->irq, INTMSK_UART0, 7);
279} 271}
280 272
281static struct irq_chip s3c_irq_uart0 = { 273static struct irq_chip s3c_irq_uart0 = {
282 .name = "s3c-uart0", 274 .name = "s3c-uart0",
283 .mask = s3c_irq_uart0_mask, 275 .irq_mask = s3c_irq_uart0_mask,
284 .unmask = s3c_irq_uart0_unmask, 276 .irq_unmask = s3c_irq_uart0_unmask,
285 .ack = s3c_irq_uart0_ack, 277 .irq_ack = s3c_irq_uart0_ack,
286}; 278};
287 279
288/* UART1 */ 280/* UART1 */
289 281
290static void 282static void
291s3c_irq_uart1_mask(unsigned int irqno) 283s3c_irq_uart1_mask(struct irq_data *data)
292{ 284{
293 s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3); 285 s3c_irqsub_mask(data->irq, INTMSK_UART1, 7 << 3);
294} 286}
295 287
296static void 288static void
297s3c_irq_uart1_unmask(unsigned int irqno) 289s3c_irq_uart1_unmask(struct irq_data *data)
298{ 290{
299 s3c_irqsub_unmask(irqno, INTMSK_UART1); 291 s3c_irqsub_unmask(data->irq, INTMSK_UART1);
300} 292}
301 293
302static void 294static void
303s3c_irq_uart1_ack(unsigned int irqno) 295s3c_irq_uart1_ack(struct irq_data *data)
304{ 296{
305 s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3); 297 s3c_irqsub_maskack(data->irq, INTMSK_UART1, 7 << 3);
306} 298}
307 299
308static struct irq_chip s3c_irq_uart1 = { 300static struct irq_chip s3c_irq_uart1 = {
309 .name = "s3c-uart1", 301 .name = "s3c-uart1",
310 .mask = s3c_irq_uart1_mask, 302 .irq_mask = s3c_irq_uart1_mask,
311 .unmask = s3c_irq_uart1_unmask, 303 .irq_unmask = s3c_irq_uart1_unmask,
312 .ack = s3c_irq_uart1_ack, 304 .irq_ack = s3c_irq_uart1_ack,
313}; 305};
314 306
315/* UART2 */ 307/* UART2 */
316 308
317static void 309static void
318s3c_irq_uart2_mask(unsigned int irqno) 310s3c_irq_uart2_mask(struct irq_data *data)
319{ 311{
320 s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6); 312 s3c_irqsub_mask(data->irq, INTMSK_UART2, 7 << 6);
321} 313}
322 314
323static void 315static void
324s3c_irq_uart2_unmask(unsigned int irqno) 316s3c_irq_uart2_unmask(struct irq_data *data)
325{ 317{
326 s3c_irqsub_unmask(irqno, INTMSK_UART2); 318 s3c_irqsub_unmask(data->irq, INTMSK_UART2);
327} 319}
328 320
329static void 321static void
330s3c_irq_uart2_ack(unsigned int irqno) 322s3c_irq_uart2_ack(struct irq_data *data)
331{ 323{
332 s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6); 324 s3c_irqsub_maskack(data->irq, INTMSK_UART2, 7 << 6);
333} 325}
334 326
335static struct irq_chip s3c_irq_uart2 = { 327static struct irq_chip s3c_irq_uart2 = {
336 .name = "s3c-uart2", 328 .name = "s3c-uart2",
337 .mask = s3c_irq_uart2_mask, 329 .irq_mask = s3c_irq_uart2_mask,
338 .unmask = s3c_irq_uart2_unmask, 330 .irq_unmask = s3c_irq_uart2_unmask,
339 .ack = s3c_irq_uart2_ack, 331 .irq_ack = s3c_irq_uart2_ack,
340}; 332};
341 333
342/* ADC and Touchscreen */ 334/* ADC and Touchscreen */
343 335
344static void 336static void
345s3c_irq_adc_mask(unsigned int irqno) 337s3c_irq_adc_mask(struct irq_data *d)
346{ 338{
347 s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9); 339 s3c_irqsub_mask(d->irq, INTMSK_ADCPARENT, 3 << 9);
348} 340}
349 341
350static void 342static void
351s3c_irq_adc_unmask(unsigned int irqno) 343s3c_irq_adc_unmask(struct irq_data *d)
352{ 344{
353 s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT); 345 s3c_irqsub_unmask(d->irq, INTMSK_ADCPARENT);
354} 346}
355 347
356static void 348static void
357s3c_irq_adc_ack(unsigned int irqno) 349s3c_irq_adc_ack(struct irq_data *d)
358{ 350{
359 s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9); 351 s3c_irqsub_ack(d->irq, INTMSK_ADCPARENT, 3 << 9);
360} 352}
361 353
362static struct irq_chip s3c_irq_adc = { 354static struct irq_chip s3c_irq_adc = {
363 .name = "s3c-adc", 355 .name = "s3c-adc",
364 .mask = s3c_irq_adc_mask, 356 .irq_mask = s3c_irq_adc_mask,
365 .unmask = s3c_irq_adc_unmask, 357 .irq_unmask = s3c_irq_adc_unmask,
366 .ack = s3c_irq_adc_ack, 358 .irq_ack = s3c_irq_adc_ack,
367}; 359};
368 360
369/* irq demux for adc */ 361/* irq demux for adc */
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 461f070eb62d..82f2d4a39291 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -271,7 +271,7 @@ static struct clk init_clocks[] = {
271 .ctrlbit = S3C2443_HCLKCON_DMA5, 271 .ctrlbit = S3C2443_HCLKCON_DMA5,
272 }, { 272 }, {
273 .name = "hsmmc", 273 .name = "hsmmc",
274 .id = 0, 274 .id = 1,
275 .parent = &clk_h, 275 .parent = &clk_h,
276 .enable = s3c2443_clkcon_enable_h, 276 .enable = s3c2443_clkcon_enable_h,
277 .ctrlbit = S3C2443_HCLKCON_HSMMC, 277 .ctrlbit = S3C2443_HCLKCON_HSMMC,
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 65dbfa8e0a86..deb39951a22e 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -56,3 +56,29 @@ config S5P_DEV_ONENAND
56 bool 56 bool
57 help 57 help
58 Compile in platform device definition for OneNAND controller 58 Compile in platform device definition for OneNAND controller
59
60config S5P_DEV_CSIS0
61 bool
62 help
63 Compile in platform device definitions for MIPI-CSIS channel 0
64
65config S5P_DEV_CSIS1
66 bool
67 help
68 Compile in platform device definitions for MIPI-CSIS channel 1
69
70menuconfig S5P_SYSMMU
71 bool "SYSMMU support"
72 depends on ARCH_S5PV310
73 help
74 This is a System MMU driver for Samsung ARM based Soc.
75
76if S5P_SYSMMU
77
78config S5P_SYSMMU_DEBUG
79 bool "Enables debug messages"
80 depends on S5P_SYSMMU
81 help
82 This enables SYSMMU driver debug massages.
83
84endif
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index de65238a7aef..92efe1adcfd6 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -28,3 +28,6 @@ obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
28obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o 28obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
29obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o 29obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
30obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o 30obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
31obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
32obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
33obj-$(CONFIG_S5P_SYSMMU) += sysmmu.o
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index 74f7f5a5446c..047d31c1bbd8 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -108,6 +108,11 @@ static struct map_desc s5p_iodesc[] __initdata = {
108 .pfn = __phys_to_pfn(S3C_PA_WDT), 108 .pfn = __phys_to_pfn(S3C_PA_WDT),
109 .length = SZ_4K, 109 .length = SZ_4K,
110 .type = MT_DEVICE, 110 .type = MT_DEVICE,
111 }, {
112 .virtual = (unsigned long)S5P_VA_SROMC,
113 .pfn = __phys_to_pfn(S5P_PA_SROMC),
114 .length = SZ_4K,
115 .type = MT_DEVICE,
111 }, 116 },
112}; 117};
113 118
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
new file mode 100644
index 000000000000..dfab1c85f54f
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis0.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics
3 *
4 * S5P series device definition for MIPI-CSIS channel 0
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <mach/map.h>
15
16static struct resource s5p_mipi_csis0_resource[] = {
17 [0] = {
18 .start = S5P_PA_MIPI_CSIS0,
19 .end = S5P_PA_MIPI_CSIS0 + SZ_4K - 1,
20 .flags = IORESOURCE_MEM,
21 },
22 [1] = {
23 .start = IRQ_MIPI_CSIS0,
24 .end = IRQ_MIPI_CSIS0,
25 .flags = IORESOURCE_IRQ,
26 }
27};
28
29struct platform_device s5p_device_mipi_csis0 = {
30 .name = "s5p-mipi-csis",
31 .id = 0,
32 .num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
33 .resource = s5p_mipi_csis0_resource,
34};
diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c
new file mode 100644
index 000000000000..e3053f27fbbf
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis1.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics
3 *
4 * S5P series device definition for MIPI-CSIS channel 1
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <mach/map.h>
15
16static struct resource s5p_mipi_csis1_resource[] = {
17 [0] = {
18 .start = S5P_PA_MIPI_CSIS1,
19 .end = S5P_PA_MIPI_CSIS1 + SZ_4K - 1,
20 .flags = IORESOURCE_MEM,
21 },
22 [1] = {
23 .start = IRQ_MIPI_CSIS1,
24 .end = IRQ_MIPI_CSIS1,
25 .flags = IORESOURCE_IRQ,
26 },
27};
28
29struct platform_device s5p_device_mipi_csis1 = {
30 .name = "s5p-mipi-csis",
31 .id = 1,
32 .num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource),
33 .resource = s5p_mipi_csis1_resource,
34};
diff --git a/arch/arm/plat-s5p/include/plat/csis.h b/arch/arm/plat-s5p/include/plat/csis.h
new file mode 100644
index 000000000000..51e308c7981d
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/csis.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics
3 *
4 * S5P series MIPI CSI slave device support
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef PLAT_S5P_CSIS_H_
12#define PLAT_S5P_CSIS_H_ __FILE__
13
14/**
15 * struct s5p_platform_mipi_csis - platform data for MIPI-CSIS
16 * @clk_rate: bus clock frequency
17 * @lanes: number of data lanes used
18 * @alignment: data alignment in bits
19 * @hs_settle: HS-RX settle time
20 */
21struct s5p_platform_mipi_csis {
22 unsigned long clk_rate;
23 u8 lanes;
24 u8 alignment;
25 u8 hs_settle;
26};
27
28#endif /* PLAT_S5P_CSIS_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
index fef353d44513..d973d39666a3 100644
--- a/arch/arm/plat-s5p/include/plat/map-s5p.h
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -15,6 +15,7 @@
15 15
16#define S5P_VA_CHIPID S3C_ADDR(0x02000000) 16#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
17#define S5P_VA_CMU S3C_ADDR(0x02100000) 17#define S5P_VA_CMU S3C_ADDR(0x02100000)
18#define S5P_VA_PMU S3C_ADDR(0x02180000)
18#define S5P_VA_GPIO S3C_ADDR(0x02200000) 19#define S5P_VA_GPIO S3C_ADDR(0x02200000)
19#define S5P_VA_GPIO1 S5P_VA_GPIO 20#define S5P_VA_GPIO1 S5P_VA_GPIO
20#define S5P_VA_GPIO2 S3C_ADDR(0x02240000) 21#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
diff --git a/arch/arm/plat-s5p/include/plat/regs-srom.h b/arch/arm/plat-s5p/include/plat/regs-srom.h
new file mode 100644
index 000000000000..f121ab5e76cb
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-srom.h
@@ -0,0 +1,54 @@
1/* linux/arch/arm/plat-s5p/include/plat/regs-srom.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P SROMC register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_PLAT_S5P_REGS_SROM_H
14#define __ASM_PLAT_S5P_REGS_SROM_H __FILE__
15
16#include <mach/map.h>
17
18#define S5P_SROMREG(x) (S5P_VA_SROMC + (x))
19
20#define S5P_SROM_BW S5P_SROMREG(0x0)
21#define S5P_SROM_BC0 S5P_SROMREG(0x4)
22#define S5P_SROM_BC1 S5P_SROMREG(0x8)
23#define S5P_SROM_BC2 S5P_SROMREG(0xc)
24#define S5P_SROM_BC3 S5P_SROMREG(0x10)
25#define S5P_SROM_BC4 S5P_SROMREG(0x14)
26#define S5P_SROM_BC5 S5P_SROMREG(0x18)
27
28/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
29
30#define S5P_SROM_BW__DATAWIDTH__SHIFT 0
31#define S5P_SROM_BW__ADDRMODE__SHIFT 1
32#define S5P_SROM_BW__WAITENABLE__SHIFT 2
33#define S5P_SROM_BW__BYTEENABLE__SHIFT 3
34
35#define S5P_SROM_BW__CS_MASK 0xf
36
37#define S5P_SROM_BW__NCS0__SHIFT 0
38#define S5P_SROM_BW__NCS1__SHIFT 4
39#define S5P_SROM_BW__NCS2__SHIFT 8
40#define S5P_SROM_BW__NCS3__SHIFT 12
41#define S5P_SROM_BW__NCS4__SHIFT 16
42#define S5P_SROM_BW__NCS5__SHIFT 20
43
44/* applies to same to BCS0 - BCS3 */
45
46#define S5P_SROM_BCX__PMC__SHIFT 0
47#define S5P_SROM_BCX__TACP__SHIFT 4
48#define S5P_SROM_BCX__TCAH__SHIFT 8
49#define S5P_SROM_BCX__TCOH__SHIFT 12
50#define S5P_SROM_BCX__TACC__SHIFT 16
51#define S5P_SROM_BCX__TCOS__SHIFT 24
52#define S5P_SROM_BCX__TACS__SHIFT 28
53
54#endif /* __ASM_PLAT_S5P_REGS_SROM_H */
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h
new file mode 100644
index 000000000000..db298fc5438a
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/sysmmu.h
@@ -0,0 +1,23 @@
1/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Samsung sysmmu driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_PLAT_S5P_SYSMMU_H
14#define __ASM_PLAT_S5P_SYSMMU_H __FILE__
15
16/* debug macro */
17#ifdef CONFIG_S5P_SYSMMU_DEBUG
18#define sysmmu_debug(fmt, arg...) printk(KERN_INFO "[%s] " fmt, __func__, ## arg)
19#else
20#define sysmmu_debug(fmt, arg...) do { } while (0)
21#endif
22
23#endif /* __ASM_PLAT_S5P_SYSMMU_H */
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index 752f1a645f9d..225aa25405db 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -28,39 +28,40 @@
28#include <plat/gpio-cfg.h> 28#include <plat/gpio-cfg.h>
29#include <mach/regs-gpio.h> 29#include <mach/regs-gpio.h>
30 30
31static inline void s5p_irq_eint_mask(unsigned int irq) 31static inline void s5p_irq_eint_mask(struct irq_data *data)
32{ 32{
33 u32 mask; 33 u32 mask;
34 34
35 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq))); 35 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
36 mask |= eint_irq_to_bit(irq); 36 mask |= eint_irq_to_bit(data->irq);
37 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq))); 37 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
38} 38}
39 39
40static void s5p_irq_eint_unmask(unsigned int irq) 40static void s5p_irq_eint_unmask(struct irq_data *data)
41{ 41{
42 u32 mask; 42 u32 mask;
43 43
44 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq))); 44 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
45 mask &= ~(eint_irq_to_bit(irq)); 45 mask &= ~(eint_irq_to_bit(data->irq));
46 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq))); 46 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
47} 47}
48 48
49static inline void s5p_irq_eint_ack(unsigned int irq) 49static inline void s5p_irq_eint_ack(struct irq_data *data)
50{ 50{
51 __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq))); 51 __raw_writel(eint_irq_to_bit(data->irq),
52 S5P_EINT_PEND(EINT_REG_NR(data->irq)));
52} 53}
53 54
54static void s5p_irq_eint_maskack(unsigned int irq) 55static void s5p_irq_eint_maskack(struct irq_data *data)
55{ 56{
56 /* compiler should in-line these */ 57 /* compiler should in-line these */
57 s5p_irq_eint_mask(irq); 58 s5p_irq_eint_mask(data);
58 s5p_irq_eint_ack(irq); 59 s5p_irq_eint_ack(data);
59} 60}
60 61
61static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type) 62static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type)
62{ 63{
63 int offs = EINT_OFFSET(irq); 64 int offs = EINT_OFFSET(data->irq);
64 int shift; 65 int shift;
65 u32 ctrl, mask; 66 u32 ctrl, mask;
66 u32 newvalue = 0; 67 u32 newvalue = 0;
@@ -94,10 +95,10 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
94 shift = (offs & 0x7) * 4; 95 shift = (offs & 0x7) * 4;
95 mask = 0x7 << shift; 96 mask = 0x7 << shift;
96 97
97 ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(irq))); 98 ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
98 ctrl &= ~mask; 99 ctrl &= ~mask;
99 ctrl |= newvalue << shift; 100 ctrl |= newvalue << shift;
100 __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(irq))); 101 __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
101 102
102 if ((0 <= offs) && (offs < 8)) 103 if ((0 <= offs) && (offs < 8))
103 s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); 104 s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
@@ -119,13 +120,13 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
119 120
120static struct irq_chip s5p_irq_eint = { 121static struct irq_chip s5p_irq_eint = {
121 .name = "s5p-eint", 122 .name = "s5p-eint",
122 .mask = s5p_irq_eint_mask, 123 .irq_mask = s5p_irq_eint_mask,
123 .unmask = s5p_irq_eint_unmask, 124 .irq_unmask = s5p_irq_eint_unmask,
124 .mask_ack = s5p_irq_eint_maskack, 125 .irq_mask_ack = s5p_irq_eint_maskack,
125 .ack = s5p_irq_eint_ack, 126 .irq_ack = s5p_irq_eint_ack,
126 .set_type = s5p_irq_eint_set_type, 127 .irq_set_type = s5p_irq_eint_set_type,
127#ifdef CONFIG_PM 128#ifdef CONFIG_PM
128 .set_wake = s3c_irqext_wake, 129 .irq_set_wake = s3c_irqext_wake,
129#endif 130#endif
130}; 131};
131 132
@@ -159,42 +160,43 @@ static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
159 s5p_irq_demux_eint(IRQ_EINT(24)); 160 s5p_irq_demux_eint(IRQ_EINT(24));
160} 161}
161 162
162static inline void s5p_irq_vic_eint_mask(unsigned int irq) 163static inline void s5p_irq_vic_eint_mask(struct irq_data *data)
163{ 164{
164 void __iomem *base = get_irq_chip_data(irq); 165 void __iomem *base = irq_data_get_irq_chip_data(data);
165 166
166 s5p_irq_eint_mask(irq); 167 s5p_irq_eint_mask(data);
167 writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE_CLEAR); 168 writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR);
168} 169}
169 170
170static void s5p_irq_vic_eint_unmask(unsigned int irq) 171static void s5p_irq_vic_eint_unmask(struct irq_data *data)
171{ 172{
172 void __iomem *base = get_irq_chip_data(irq); 173 void __iomem *base = irq_data_get_irq_chip_data(data);
173 174
174 s5p_irq_eint_unmask(irq); 175 s5p_irq_eint_unmask(data);
175 writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE); 176 writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE);
176} 177}
177 178
178static inline void s5p_irq_vic_eint_ack(unsigned int irq) 179static inline void s5p_irq_vic_eint_ack(struct irq_data *data)
179{ 180{
180 __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq))); 181 __raw_writel(eint_irq_to_bit(data->irq),
182 S5P_EINT_PEND(EINT_REG_NR(data->irq)));
181} 183}
182 184
183static void s5p_irq_vic_eint_maskack(unsigned int irq) 185static void s5p_irq_vic_eint_maskack(struct irq_data *data)
184{ 186{
185 s5p_irq_vic_eint_mask(irq); 187 s5p_irq_vic_eint_mask(data);
186 s5p_irq_vic_eint_ack(irq); 188 s5p_irq_vic_eint_ack(data);
187} 189}
188 190
189static struct irq_chip s5p_irq_vic_eint = { 191static struct irq_chip s5p_irq_vic_eint = {
190 .name = "s5p_vic_eint", 192 .name = "s5p_vic_eint",
191 .mask = s5p_irq_vic_eint_mask, 193 .irq_mask = s5p_irq_vic_eint_mask,
192 .unmask = s5p_irq_vic_eint_unmask, 194 .irq_unmask = s5p_irq_vic_eint_unmask,
193 .mask_ack = s5p_irq_vic_eint_maskack, 195 .irq_mask_ack = s5p_irq_vic_eint_maskack,
194 .ack = s5p_irq_vic_eint_ack, 196 .irq_ack = s5p_irq_vic_eint_ack,
195 .set_type = s5p_irq_eint_set_type, 197 .irq_set_type = s5p_irq_eint_set_type,
196#ifdef CONFIG_PM 198#ifdef CONFIG_PM
197 .set_wake = s3c_irqext_wake, 199 .irq_set_wake = s3c_irqext_wake,
198#endif 200#endif
199}; 201};
200 202
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index 0e5dc8cbf5e3..3b6bf89d1739 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -30,9 +30,9 @@
30 30
31static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR]; 31static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
32 32
33static int s5p_gpioint_get_group(unsigned int irq) 33static int s5p_gpioint_get_group(struct irq_data *data)
34{ 34{
35 struct gpio_chip *chip = get_irq_data(irq); 35 struct gpio_chip *chip = irq_data_get_irq_data(data);
36 struct s3c_gpio_chip *s3c_chip = container_of(chip, 36 struct s3c_gpio_chip *s3c_chip = container_of(chip,
37 struct s3c_gpio_chip, chip); 37 struct s3c_gpio_chip, chip);
38 int group; 38 int group;
@@ -44,22 +44,22 @@ static int s5p_gpioint_get_group(unsigned int irq)
44 return group; 44 return group;
45} 45}
46 46
47static int s5p_gpioint_get_offset(unsigned int irq) 47static int s5p_gpioint_get_offset(struct irq_data *data)
48{ 48{
49 struct gpio_chip *chip = get_irq_data(irq); 49 struct gpio_chip *chip = irq_data_get_irq_data(data);
50 struct s3c_gpio_chip *s3c_chip = container_of(chip, 50 struct s3c_gpio_chip *s3c_chip = container_of(chip,
51 struct s3c_gpio_chip, chip); 51 struct s3c_gpio_chip, chip);
52 52
53 return irq - s3c_chip->irq_base; 53 return data->irq - s3c_chip->irq_base;
54} 54}
55 55
56static void s5p_gpioint_ack(unsigned int irq) 56static void s5p_gpioint_ack(struct irq_data *data)
57{ 57{
58 int group, offset, pend_offset; 58 int group, offset, pend_offset;
59 unsigned int value; 59 unsigned int value;
60 60
61 group = s5p_gpioint_get_group(irq); 61 group = s5p_gpioint_get_group(data);
62 offset = s5p_gpioint_get_offset(irq); 62 offset = s5p_gpioint_get_offset(data);
63 pend_offset = group << 2; 63 pend_offset = group << 2;
64 64
65 value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset); 65 value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
@@ -67,13 +67,13 @@ static void s5p_gpioint_ack(unsigned int irq)
67 __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset); 67 __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
68} 68}
69 69
70static void s5p_gpioint_mask(unsigned int irq) 70static void s5p_gpioint_mask(struct irq_data *data)
71{ 71{
72 int group, offset, mask_offset; 72 int group, offset, mask_offset;
73 unsigned int value; 73 unsigned int value;
74 74
75 group = s5p_gpioint_get_group(irq); 75 group = s5p_gpioint_get_group(data);
76 offset = s5p_gpioint_get_offset(irq); 76 offset = s5p_gpioint_get_offset(data);
77 mask_offset = group << 2; 77 mask_offset = group << 2;
78 78
79 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); 79 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
@@ -81,13 +81,13 @@ static void s5p_gpioint_mask(unsigned int irq)
81 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); 81 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
82} 82}
83 83
84static void s5p_gpioint_unmask(unsigned int irq) 84static void s5p_gpioint_unmask(struct irq_data *data)
85{ 85{
86 int group, offset, mask_offset; 86 int group, offset, mask_offset;
87 unsigned int value; 87 unsigned int value;
88 88
89 group = s5p_gpioint_get_group(irq); 89 group = s5p_gpioint_get_group(data);
90 offset = s5p_gpioint_get_offset(irq); 90 offset = s5p_gpioint_get_offset(data);
91 mask_offset = group << 2; 91 mask_offset = group << 2;
92 92
93 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); 93 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
@@ -95,19 +95,19 @@ static void s5p_gpioint_unmask(unsigned int irq)
95 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); 95 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
96} 96}
97 97
98static void s5p_gpioint_mask_ack(unsigned int irq) 98static void s5p_gpioint_mask_ack(struct irq_data *data)
99{ 99{
100 s5p_gpioint_mask(irq); 100 s5p_gpioint_mask(data);
101 s5p_gpioint_ack(irq); 101 s5p_gpioint_ack(data);
102} 102}
103 103
104static int s5p_gpioint_set_type(unsigned int irq, unsigned int type) 104static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
105{ 105{
106 int group, offset, con_offset; 106 int group, offset, con_offset;
107 unsigned int value; 107 unsigned int value;
108 108
109 group = s5p_gpioint_get_group(irq); 109 group = s5p_gpioint_get_group(data);
110 offset = s5p_gpioint_get_offset(irq); 110 offset = s5p_gpioint_get_offset(data);
111 con_offset = group << 2; 111 con_offset = group << 2;
112 112
113 switch (type) { 113 switch (type) {
@@ -142,11 +142,11 @@ static int s5p_gpioint_set_type(unsigned int irq, unsigned int type)
142 142
143struct irq_chip s5p_gpioint = { 143struct irq_chip s5p_gpioint = {
144 .name = "s5p_gpioint", 144 .name = "s5p_gpioint",
145 .ack = s5p_gpioint_ack, 145 .irq_ack = s5p_gpioint_ack,
146 .mask = s5p_gpioint_mask, 146 .irq_mask = s5p_gpioint_mask,
147 .mask_ack = s5p_gpioint_mask_ack, 147 .irq_mask_ack = s5p_gpioint_mask_ack,
148 .unmask = s5p_gpioint_unmask, 148 .irq_unmask = s5p_gpioint_unmask,
149 .set_type = s5p_gpioint_set_type, 149 .irq_set_type = s5p_gpioint_set_type,
150}; 150};
151 151
152static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) 152static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
index dc33b9ecda45..5259ad458bc8 100644
--- a/arch/arm/plat-s5p/irq-pm.c
+++ b/arch/arm/plat-s5p/irq-pm.c
@@ -37,14 +37,14 @@
37unsigned long s3c_irqwake_intallow = 0x00000006L; 37unsigned long s3c_irqwake_intallow = 0x00000006L;
38unsigned long s3c_irqwake_eintallow = 0xffffffffL; 38unsigned long s3c_irqwake_eintallow = 0xffffffffL;
39 39
40int s3c_irq_wake(unsigned int irqno, unsigned int state) 40int s3c_irq_wake(struct irq_data *data, unsigned int state)
41{ 41{
42 unsigned long irqbit; 42 unsigned long irqbit;
43 43
44 switch (irqno) { 44 switch (data->irq) {
45 case IRQ_RTC_TIC: 45 case IRQ_RTC_TIC:
46 case IRQ_RTC_ALARM: 46 case IRQ_RTC_ALARM:
47 irqbit = 1 << (irqno + 1 - IRQ_RTC_ALARM); 47 irqbit = 1 << (data->irq + 1 - IRQ_RTC_ALARM);
48 if (!state) 48 if (!state)
49 s3c_irqwake_intmask |= irqbit; 49 s3c_irqwake_intmask |= irqbit;
50 else 50 else
diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c
new file mode 100644
index 000000000000..d804914dc2e2
--- /dev/null
+++ b/arch/arm/plat-s5p/sysmmu.c
@@ -0,0 +1,328 @@
1/* linux/arch/arm/plat-s5p/sysmmu.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/io.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14
15#include <mach/map.h>
16#include <mach/regs-sysmmu.h>
17#include <mach/sysmmu.h>
18
19#include <plat/sysmmu.h>
20
21struct sysmmu_controller s5p_sysmmu_cntlrs[S5P_SYSMMU_TOTAL_IPNUM];
22
23void s5p_sysmmu_register(struct sysmmu_controller *sysmmuconp)
24{
25 unsigned int reg_mmu_ctrl;
26 unsigned int reg_mmu_status;
27 unsigned int reg_pt_base_addr;
28 unsigned int reg_int_status;
29 unsigned int reg_page_ft_addr;
30
31 reg_int_status = __raw_readl(sysmmuconp->regs + S5P_INT_STATUS);
32 reg_mmu_ctrl = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
33 reg_mmu_status = __raw_readl(sysmmuconp->regs + S5P_MMU_STATUS);
34 reg_pt_base_addr = __raw_readl(sysmmuconp->regs + S5P_PT_BASE_ADDR);
35 reg_page_ft_addr = __raw_readl(sysmmuconp->regs + S5P_PAGE_FAULT_ADDR);
36
37 printk(KERN_INFO "%s: ips:%s\n", __func__, sysmmuconp->name);
38 printk(KERN_INFO "%s: MMU_CTRL:0x%X, ", __func__, reg_mmu_ctrl);
39 printk(KERN_INFO "MMU_STATUS:0x%X, PT_BASE_ADDR:0x%X\n", reg_mmu_status, reg_pt_base_addr);
40 printk(KERN_INFO "%s: INT_STATUS:0x%X, PAGE_FAULT_ADDR:0x%X\n", __func__, reg_int_status, reg_page_ft_addr);
41
42 switch (reg_int_status & 0xFF) {
43 case 0x1:
44 printk(KERN_INFO "%s: Page fault\n", __func__);
45 printk(KERN_INFO "%s: Virtual address causing last page fault or bus error : 0x%x\n", __func__ , reg_page_ft_addr);
46 break;
47 case 0x2:
48 printk(KERN_INFO "%s: AR multi-hit fault\n", __func__);
49 break;
50 case 0x4:
51 printk(KERN_INFO "%s: AW multi-hit fault\n", __func__);
52 break;
53 case 0x8:
54 printk(KERN_INFO "%s: Bus error\n", __func__);
55 break;
56 case 0x10:
57 printk(KERN_INFO "%s: AR Security protection fault\n", __func__);
58 break;
59 case 0x20:
60 printk(KERN_INFO "%s: AR Access protection fault\n", __func__);
61 break;
62 case 0x40:
63 printk(KERN_INFO "%s: AW Security protection fault\n", __func__);
64 break;
65 case 0x80:
66 printk(KERN_INFO "%s: AW Access protection fault\n", __func__);
67 break;
68 }
69}
70
71static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id)
72{
73 unsigned int i;
74 unsigned int reg_int_status;
75 struct sysmmu_controller *sysmmuconp;
76
77 for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
78 sysmmuconp = &s5p_sysmmu_cntlrs[i];
79
80 if (sysmmuconp->enable == true) {
81 reg_int_status = __raw_readl(sysmmuconp->regs + S5P_INT_STATUS);
82
83 if (reg_int_status & 0xFF)
84 s5p_sysmmu_register(sysmmuconp);
85 }
86 }
87 return IRQ_HANDLED;
88}
89
90int s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd)
91{
92 struct sysmmu_controller *sysmmuconp = NULL;
93
94 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
95
96 if (sysmmuconp == NULL) {
97 printk(KERN_ERR "failed to get ip's sysmmu info\n");
98 return 1;
99 }
100
101 /* Set sysmmu page table base address */
102 __raw_writel(pgd, sysmmuconp->regs + S5P_PT_BASE_ADDR);
103
104 if (s5p_sysmmu_tlb_invalidate(ips) != 0)
105 printk(KERN_ERR "failed s5p_sysmmu_tlb_invalidate\n");
106
107 return 0;
108}
109
110static int s5p_sysmmu_set_tablebase(sysmmu_ips ips)
111{
112 unsigned int pg;
113 struct sysmmu_controller *sysmmuconp;
114
115 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
116
117 if (sysmmuconp == NULL) {
118 printk(KERN_ERR "failed to get ip's sysmmu info\n");
119 return 1;
120 }
121
122 __asm__("mrc p15, 0, %0, c2, c0, 0" \
123 : "=r" (pg) : : "cc"); \
124 pg &= ~0x3fff;
125
126 sysmmu_debug("CP15 TTBR0 : 0x%x\n", pg);
127
128 /* Set sysmmu page table base address */
129 __raw_writel(pg, sysmmuconp->regs + S5P_PT_BASE_ADDR);
130
131 return 0;
132}
133
134int s5p_sysmmu_enable(sysmmu_ips ips)
135{
136 unsigned int reg;
137
138 struct sysmmu_controller *sysmmuconp;
139
140 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
141
142 if (sysmmuconp == NULL) {
143 printk(KERN_ERR "failed to get ip's sysmmu info\n");
144 return 1;
145 }
146
147 s5p_sysmmu_set_tablebase(ips);
148
149 /* replacement policy : LRU */
150 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CFG);
151 reg |= 0x1;
152 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CFG);
153
154 /* Enable interrupt, Enable MMU */
155 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
156 reg |= (0x1 << 2) | (0x1 << 0);
157
158 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CTRL);
159
160 sysmmuconp->enable = true;
161
162 return 0;
163}
164
165int s5p_sysmmu_disable(sysmmu_ips ips)
166{
167 unsigned int reg;
168
169 struct sysmmu_controller *sysmmuconp = NULL;
170
171 if (ips > S5P_SYSMMU_TOTAL_IPNUM)
172 printk(KERN_ERR "failed to get ips parameter\n");
173
174 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
175
176 if (sysmmuconp == NULL) {
177 printk(KERN_ERR "failed to get ip's sysmmu info\n");
178 return 1;
179 }
180
181 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CFG);
182
183 /* replacement policy : LRU */
184 reg |= 0x1;
185 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CFG);
186
187 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
188
189 /* Disable MMU */
190 reg &= ~0x1;
191 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CTRL);
192
193 sysmmuconp->enable = false;
194
195 return 0;
196}
197
198int s5p_sysmmu_tlb_invalidate(sysmmu_ips ips)
199{
200 unsigned int reg;
201 struct sysmmu_controller *sysmmuconp = NULL;
202
203 sysmmuconp = &s5p_sysmmu_cntlrs[ips];
204
205 if (sysmmuconp == NULL) {
206 printk(KERN_ERR "failed to get ip's sysmmu info\n");
207 return 1;
208 }
209
210 /* set Block MMU for flush TLB */
211 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
212 reg |= 0x1 << 1;
213 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CTRL);
214
215 /* flush all TLB entry */
216 __raw_writel(0x1, sysmmuconp->regs + S5P_MMU_FLUSH);
217
218 /* set Un-block MMU after flush TLB */
219 reg = __raw_readl(sysmmuconp->regs + S5P_MMU_CTRL);
220 reg &= ~(0x1 << 1);
221 __raw_writel(reg, sysmmuconp->regs + S5P_MMU_CTRL);
222
223 return 0;
224}
225
226static int s5p_sysmmu_probe(struct platform_device *pdev)
227{
228 int i;
229 int ret;
230 struct resource *res;
231 struct sysmmu_controller *sysmmuconp;
232 sysmmu_ips ips;
233
234 for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
235 sysmmuconp = &s5p_sysmmu_cntlrs[i];
236 if (sysmmuconp == NULL) {
237 printk(KERN_ERR "failed to get ip's sysmmu info\n");
238 ret = -ENOENT;
239 goto err_res;
240 }
241
242 sysmmuconp->name = sysmmu_ips_name[i];
243
244 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
245 if (!res) {
246 printk(KERN_ERR "failed to get sysmmu resource\n");
247 ret = -ENODEV;
248 goto err_res;
249 }
250
251 sysmmuconp->mem = request_mem_region(res->start,
252 ((res->end) - (res->start)) + 1, pdev->name);
253 if (!sysmmuconp->mem) {
254 pr_err("failed to request sysmmu memory region\n");
255 ret = -EBUSY;
256 goto err_res;
257 }
258
259 sysmmuconp->regs = ioremap(res->start, res->end - res->start + 1);
260 if (!sysmmuconp->regs) {
261 pr_err("failed to sysmmu ioremap\n");
262 ret = -ENXIO;
263 goto err_reg;
264 }
265
266 sysmmuconp->irq = platform_get_irq(pdev, i);
267 if (sysmmuconp->irq <= 0) {
268 pr_err("failed to get sysmmu irq resource\n");
269 ret = -ENOENT;
270 goto err_map;
271 }
272
273 ret = request_irq(sysmmuconp->irq, s5p_sysmmu_irq, IRQF_DISABLED, pdev->name, sysmmuconp);
274 if (ret) {
275 pr_err("failed to request irq\n");
276 ret = -ENOENT;
277 goto err_map;
278 }
279
280 ips = (sysmmu_ips)i;
281
282 sysmmuconp->ips = ips;
283 }
284
285 return 0;
286
287err_reg:
288 release_mem_region((resource_size_t)sysmmuconp->mem, (resource_size_t)((res->end) - (res->start) + 1));
289err_map:
290 iounmap(sysmmuconp->regs);
291err_res:
292 return ret;
293}
294
295static int s5p_sysmmu_remove(struct platform_device *pdev)
296{
297 return 0;
298}
299int s5p_sysmmu_runtime_suspend(struct device *dev)
300{
301 return 0;
302}
303
304int s5p_sysmmu_runtime_resume(struct device *dev)
305{
306 return 0;
307}
308
309const struct dev_pm_ops s5p_sysmmu_pm_ops = {
310 .runtime_suspend = s5p_sysmmu_runtime_suspend,
311 .runtime_resume = s5p_sysmmu_runtime_resume,
312};
313
314static struct platform_driver s5p_sysmmu_driver = {
315 .probe = s5p_sysmmu_probe,
316 .remove = s5p_sysmmu_remove,
317 .driver = {
318 .owner = THIS_MODULE,
319 .name = "s5p-sysmmu",
320 .pm = &s5p_sysmmu_pm_ops,
321 }
322};
323
324static int __init s5p_sysmmu_init(void)
325{
326 return platform_driver_register(&s5p_sysmmu_driver);
327}
328arch_initcall(s5p_sysmmu_init);
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index dcd6eff4ee53..32be05cf82a3 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -95,6 +95,12 @@ config S3C_GPIO_PULL_UPDOWN
95 help 95 help
96 Internal configuration to enable the correct GPIO pull helper 96 Internal configuration to enable the correct GPIO pull helper
97 97
98config S3C_GPIO_PULL_S3C2443
99 bool
100 select S3C_GPIO_PULL_UPDOWN
101 help
102 Internal configuration to enable the correct GPIO pull helper for S3C2443-style GPIO
103
98config S3C_GPIO_PULL_DOWN 104config S3C_GPIO_PULL_DOWN
99 bool 105 bool
100 help 106 help
@@ -333,4 +339,12 @@ config SAMSUNG_WAKEMASK
333 and above. This code allows a set of interrupt to wakeup-mask 339 and above. This code allows a set of interrupt to wakeup-mask
334 mappings. See <plat/wakeup-mask.h> 340 mappings. See <plat/wakeup-mask.h>
335 341
342comment "Power Domain"
343
344config SAMSUNG_PD
345 bool "Samsung Power Domain"
346 depends on PM_RUNTIME
347 help
348 Say Y here if you want to control Power Domain by Runtime PM.
349
336endif 350endif
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index afcce474af8e..09dbd78b56f5 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -73,6 +73,10 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
73 73
74obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o 74obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
75 75
76# PD support
77
78obj-$(CONFIG_SAMSUNG_PD) += pd.o
79
76# PWM support 80# PWM support
77 81
78obj-$(CONFIG_HAVE_PWM) += pwm.o 82obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index e8d20b0bc50e..772892826ffc 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -39,6 +39,9 @@
39#include <linux/clk.h> 39#include <linux/clk.h>
40#include <linux/spinlock.h> 40#include <linux/spinlock.h>
41#include <linux/io.h> 41#include <linux/io.h>
42#if defined(CONFIG_DEBUG_FS)
43#include <linux/debugfs.h>
44#endif
42 45
43#include <mach/hardware.h> 46#include <mach/hardware.h>
44#include <asm/irq.h> 47#include <asm/irq.h>
@@ -447,3 +450,92 @@ int __init s3c24xx_register_baseclocks(unsigned long xtal)
447 return 0; 450 return 0;
448} 451}
449 452
453#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
454/* debugfs support to trace clock tree hierarchy and attributes */
455
456static struct dentry *clk_debugfs_root;
457
458static int clk_debugfs_register_one(struct clk *c)
459{
460 int err;
461 struct dentry *d, *child, *child_tmp;
462 struct clk *pa = c->parent;
463 char s[255];
464 char *p = s;
465
466 p += sprintf(p, "%s", c->name);
467
468 if (c->id >= 0)
469 sprintf(p, ":%d", c->id);
470
471 d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
472 if (!d)
473 return -ENOMEM;
474
475 c->dent = d;
476
477 d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usage);
478 if (!d) {
479 err = -ENOMEM;
480 goto err_out;
481 }
482
483 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
484 if (!d) {
485 err = -ENOMEM;
486 goto err_out;
487 }
488 return 0;
489
490err_out:
491 d = c->dent;
492 list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
493 debugfs_remove(child);
494 debugfs_remove(c->dent);
495 return err;
496}
497
498static int clk_debugfs_register(struct clk *c)
499{
500 int err;
501 struct clk *pa = c->parent;
502
503 if (pa && !pa->dent) {
504 err = clk_debugfs_register(pa);
505 if (err)
506 return err;
507 }
508
509 if (!c->dent) {
510 err = clk_debugfs_register_one(c);
511 if (err)
512 return err;
513 }
514 return 0;
515}
516
517static int __init clk_debugfs_init(void)
518{
519 struct clk *c;
520 struct dentry *d;
521 int err;
522
523 d = debugfs_create_dir("clock", NULL);
524 if (!d)
525 return -ENOMEM;
526 clk_debugfs_root = d;
527
528 list_for_each_entry(c, &clocks, list) {
529 err = clk_debugfs_register(c);
530 if (err)
531 goto err_out;
532 }
533 return 0;
534
535err_out:
536 debugfs_remove_recursive(clk_debugfs_root);
537 return err;
538}
539late_initcall(clk_debugfs_init);
540
541#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */
diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c
index 3a7b8891ba4f..6927ae8fd118 100644
--- a/arch/arm/plat-samsung/dev-nand.c
+++ b/arch/arm/plat-samsung/dev-nand.c
@@ -126,5 +126,3 @@ void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
126 126
127 s3c_device_nand.dev.platform_data = npd; 127 s3c_device_nand.dev.platform_data = npd;
128} 128}
129
130EXPORT_SYMBOL_GPL(s3c_nand_set_platdata);
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 0aa32f242ee4..1c0b0401594b 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -278,6 +278,48 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
278 pup &= 0x3; 278 pup &= 0x3;
279 return (__force s3c_gpio_pull_t)pup; 279 return (__force s3c_gpio_pull_t)pup;
280} 280}
281
282#ifdef CONFIG_S3C_GPIO_PULL_S3C2443
283int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
284 unsigned int off, s3c_gpio_pull_t pull)
285{
286 switch (pull) {
287 case S3C_GPIO_PULL_NONE:
288 pull = 0x01;
289 break;
290 case S3C_GPIO_PULL_UP:
291 pull = 0x00;
292 break;
293 case S3C_GPIO_PULL_DOWN:
294 pull = 0x02;
295 break;
296 }
297 return s3c_gpio_setpull_updown(chip, off, pull);
298}
299
300s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
301 unsigned int off)
302{
303 s3c_gpio_pull_t pull;
304
305 pull = s3c_gpio_getpull_updown(chip, off);
306
307 switch (pull) {
308 case 0x00:
309 pull = S3C_GPIO_PULL_UP;
310 break;
311 case 0x01:
312 case 0x03:
313 pull = S3C_GPIO_PULL_NONE;
314 break;
315 case 0x02:
316 pull = S3C_GPIO_PULL_DOWN;
317 break;
318 }
319
320 return pull;
321}
322#endif
281#endif 323#endif
282 324
283#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN) 325#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN)
diff --git a/arch/arm/plat-samsung/gpiolib.c b/arch/arm/plat-samsung/gpiolib.c
index c354089254fc..ea37c0461788 100644
--- a/arch/arm/plat-samsung/gpiolib.c
+++ b/arch/arm/plat-samsung/gpiolib.c
@@ -197,3 +197,10 @@ void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
197 s3c_gpiolib_add(chip); 197 s3c_gpiolib_add(chip);
198 } 198 }
199} 199}
200
201void __init samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
202 int nr_chips)
203{
204 for (; nr_chips > 0; nr_chips--, chip++)
205 s3c_gpiolib_add(chip);
206}
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
index 7712ff6336f4..a0826ed2f9fe 100644
--- a/arch/arm/plat-samsung/include/plat/audio.h
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -25,10 +25,34 @@ extern void s3c64xx_ac97_setup_gpio(int);
25#define S5PC100_SPDIF_GPG3 1 25#define S5PC100_SPDIF_GPG3 1
26extern void s5pc100_spdif_setup_gpio(int); 26extern void s5pc100_spdif_setup_gpio(int);
27 27
28struct samsung_i2s {
29/* If the Primary DAI has 5.1 Channels */
30#define QUIRK_PRI_6CHAN (1 << 0)
31/* If the I2S block has a Stereo Overlay Channel */
32#define QUIRK_SEC_DAI (1 << 1)
33/*
34 * If the I2S block has no internal prescalar or MUX (I2SMOD[10] bit)
35 * The Machine driver must provide suitably set clock to the I2S block.
36 */
37#define QUIRK_NO_MUXPSR (1 << 2)
38#define QUIRK_NEED_RSTCLR (1 << 3)
39 /* Quirks of the I2S controller */
40 u32 quirks;
41
42 /*
43 * Array of clock names that can be used to generate I2S signals.
44 * Also corresponds to clocks of I2SMOD[10]
45 */
46 const char **src_clk;
47};
48
28/** 49/**
29 * struct s3c_audio_pdata - common platform data for audio device drivers 50 * struct s3c_audio_pdata - common platform data for audio device drivers
30 * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode 51 * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
31 */ 52 */
32struct s3c_audio_pdata { 53struct s3c_audio_pdata {
33 int (*cfg_gpio)(struct platform_device *); 54 int (*cfg_gpio)(struct platform_device *);
55 union {
56 struct samsung_i2s i2s;
57 } type;
34}; 58};
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index 0fbcd0effd8e..9a82b8874918 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -47,6 +47,9 @@ struct clk {
47 47
48 struct clk_ops *ops; 48 struct clk_ops *ops;
49 int (*enable)(struct clk *, int enable); 49 int (*enable)(struct clk *, int enable);
50#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
51 struct dentry *dent; /* For visible tree hierarchy */
52#endif
50}; 53};
51 54
52/* other clocks which may be registered by board support */ 55/* other clocks which may be registered by board support */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 2d82a6cb1444..1be192209a7e 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -96,6 +96,16 @@ extern struct platform_device s5pv210_device_iis1;
96extern struct platform_device s5pv210_device_iis2; 96extern struct platform_device s5pv210_device_iis2;
97extern struct platform_device s5pv210_device_spdif; 97extern struct platform_device s5pv210_device_spdif;
98 98
99extern struct platform_device s5pv310_device_ac97;
100extern struct platform_device s5pv310_device_pcm0;
101extern struct platform_device s5pv310_device_pcm1;
102extern struct platform_device s5pv310_device_pcm2;
103extern struct platform_device s5pv310_device_i2s0;
104extern struct platform_device s5pv310_device_i2s1;
105extern struct platform_device s5pv310_device_i2s2;
106extern struct platform_device s5pv310_device_spdif;
107extern struct platform_device s5pv310_device_pd[];
108
99extern struct platform_device s5p6442_device_pcm0; 109extern struct platform_device s5p6442_device_pcm0;
100extern struct platform_device s5p6442_device_pcm1; 110extern struct platform_device s5p6442_device_pcm1;
101extern struct platform_device s5p6442_device_iis0; 111extern struct platform_device s5p6442_device_iis0;
@@ -106,6 +116,8 @@ extern struct platform_device s5p6440_device_pcm;
106extern struct platform_device s5p6440_device_iis; 116extern struct platform_device s5p6440_device_iis;
107 117
108extern struct platform_device s5p6450_device_iis0; 118extern struct platform_device s5p6450_device_iis0;
119extern struct platform_device s5p6450_device_iis1;
120extern struct platform_device s5p6450_device_iis2;
109extern struct platform_device s5p6450_device_pcm0; 121extern struct platform_device s5p6450_device_pcm0;
110 122
111extern struct platform_device s5pc100_device_ac97; 123extern struct platform_device s5pc100_device_ac97;
@@ -122,6 +134,11 @@ extern struct platform_device s5p_device_fimc0;
122extern struct platform_device s5p_device_fimc1; 134extern struct platform_device s5p_device_fimc1;
123extern struct platform_device s5p_device_fimc2; 135extern struct platform_device s5p_device_fimc2;
124 136
137extern struct platform_device s5p_device_mipi_csis0;
138extern struct platform_device s5p_device_mipi_csis1;
139
140extern struct platform_device s5pv310_device_sysmmu;
141
125/* s3c2440 specific devices */ 142/* s3c2440 specific devices */
126 143
127#ifdef CONFIG_CPU_S3C2440 144#ifdef CONFIG_CPU_S3C2440
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index 0d2c5703f1ee..5603db0b79bc 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -244,7 +244,7 @@ extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
244 * This helper function reads the state of the pull-{up,down} resistor for the 244 * This helper function reads the state of the pull-{up,down} resistor for the
245 * given GPIO in the same case as s3c_gpio_setpull_upown. 245 * given GPIO in the same case as s3c_gpio_setpull_upown.
246*/ 246*/
247extern s3c_gpio_pull_t s3c_gpio_getpull_s3c24xx(struct s3c_gpio_chip *chip, 247extern s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
248 unsigned int off); 248 unsigned int off);
249 249
250#endif /* __PLAT_GPIO_CFG_HELPERS_H */ 250#endif /* __PLAT_GPIO_CFG_HELPERS_H */
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 13a22b8861ef..dac35d0a711d 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -118,6 +118,8 @@ extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
118 int nr_chips); 118 int nr_chips);
119extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip, 119extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
120 int nr_chips); 120 int nr_chips);
121extern void samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
122 int nr_chips);
121 123
122extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); 124extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
123extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); 125extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h
new file mode 100644
index 000000000000..5f0ad85783db
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pd.h
@@ -0,0 +1,30 @@
1/* linux/arch/arm/plat-samsung/include/plat/pd.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#ifndef __ASM_PLAT_SAMSUNG_PD_H
12#define __ASM_PLAT_SAMSUNG_PD_H __FILE__
13
14struct samsung_pd_info {
15 int (*enable)(struct device *dev);
16 int (*disable)(struct device *dev);
17 void __iomem *base;
18};
19
20enum s5pv310_pd_block {
21 PD_MFC,
22 PD_G3D,
23 PD_LCD0,
24 PD_LCD1,
25 PD_TV,
26 PD_CAM,
27 PD_GPS
28};
29
30#endif /* __ASM_PLAT_SAMSUNG_PD_H */
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 245836d91931..d9025e377675 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -15,6 +15,8 @@
15 * management 15 * management
16*/ 16*/
17 17
18#include <linux/irq.h>
19
18#ifdef CONFIG_PM 20#ifdef CONFIG_PM
19 21
20extern __init int s3c_pm_init(void); 22extern __init int s3c_pm_init(void);
@@ -100,7 +102,7 @@ extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
100extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); 102extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
101 103
102#ifdef CONFIG_PM 104#ifdef CONFIG_PM
103extern int s3c_irqext_wake(unsigned int irqno, unsigned int state); 105extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
104extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); 106extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
105extern int s3c24xx_irq_resume(struct sys_device *dev); 107extern int s3c24xx_irq_resume(struct sys_device *dev);
106#else 108#else
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 85853f8c4c5d..5a41a0b69eec 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -107,6 +107,8 @@ extern struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata;
107 107
108/* Helper function availablity */ 108/* Helper function availablity */
109 109
110extern void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
111extern void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
110extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w); 112extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
111extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w); 113extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
112extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w); 114extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
@@ -122,6 +124,39 @@ extern void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
122extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w); 124extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
123extern void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *, int w); 125extern void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
124 126
127/* S3C2416 SDHCI setup */
128
129#ifdef CONFIG_S3C2416_SETUP_SDHCI
130extern char *s3c2416_hsmmc_clksrcs[4];
131
132extern void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
133 void __iomem *r,
134 struct mmc_ios *ios,
135 struct mmc_card *card);
136
137static inline void s3c2416_default_sdhci0(void)
138{
139#ifdef CONFIG_S3C_DEV_HSMMC
140 s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
141 s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio;
142 s3c_hsmmc0_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
143#endif /* CONFIG_S3C_DEV_HSMMC */
144}
145
146static inline void s3c2416_default_sdhci1(void)
147{
148#ifdef CONFIG_S3C_DEV_HSMMC1
149 s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
150 s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio;
151 s3c_hsmmc1_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
152#endif /* CONFIG_S3C_DEV_HSMMC1 */
153}
154
155#else
156static inline void s3c2416_default_sdhci0(void) { }
157static inline void s3c2416_default_sdhci1(void) { }
158
159#endif /* CONFIG_S3C2416_SETUP_SDHCI */
125/* S3C64XX SDHCI setup */ 160/* S3C64XX SDHCI setup */
126 161
127#ifdef CONFIG_S3C64XX_SETUP_SDHCI 162#ifdef CONFIG_S3C64XX_SETUP_SDHCI
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c
index 4f8c102674ae..4e770355ccbc 100644
--- a/arch/arm/plat-samsung/irq-uart.c
+++ b/arch/arm/plat-samsung/irq-uart.c
@@ -28,9 +28,9 @@
28 * are consecutive when looking up the interrupt in the demux routines. 28 * are consecutive when looking up the interrupt in the demux routines.
29 */ 29 */
30 30
31static inline void __iomem *s3c_irq_uart_base(unsigned int irq) 31static inline void __iomem *s3c_irq_uart_base(struct irq_data *data)
32{ 32{
33 struct s3c_uart_irq *uirq = get_irq_chip_data(irq); 33 struct s3c_uart_irq *uirq = irq_data_get_irq_chip_data(data);
34 return uirq->regs; 34 return uirq->regs;
35} 35}
36 36
@@ -39,10 +39,10 @@ static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
39 return irq & 3; 39 return irq & 3;
40} 40}
41 41
42static void s3c_irq_uart_mask(unsigned int irq) 42static void s3c_irq_uart_mask(struct irq_data *data)
43{ 43{
44 void __iomem *regs = s3c_irq_uart_base(irq); 44 void __iomem *regs = s3c_irq_uart_base(data);
45 unsigned int bit = s3c_irq_uart_bit(irq); 45 unsigned int bit = s3c_irq_uart_bit(data->irq);
46 u32 reg; 46 u32 reg;
47 47
48 reg = __raw_readl(regs + S3C64XX_UINTM); 48 reg = __raw_readl(regs + S3C64XX_UINTM);
@@ -50,10 +50,10 @@ static void s3c_irq_uart_mask(unsigned int irq)
50 __raw_writel(reg, regs + S3C64XX_UINTM); 50 __raw_writel(reg, regs + S3C64XX_UINTM);
51} 51}
52 52
53static void s3c_irq_uart_maskack(unsigned int irq) 53static void s3c_irq_uart_maskack(struct irq_data *data)
54{ 54{
55 void __iomem *regs = s3c_irq_uart_base(irq); 55 void __iomem *regs = s3c_irq_uart_base(data);
56 unsigned int bit = s3c_irq_uart_bit(irq); 56 unsigned int bit = s3c_irq_uart_bit(data->irq);
57 u32 reg; 57 u32 reg;
58 58
59 reg = __raw_readl(regs + S3C64XX_UINTM); 59 reg = __raw_readl(regs + S3C64XX_UINTM);
@@ -62,10 +62,10 @@ static void s3c_irq_uart_maskack(unsigned int irq)
62 __raw_writel(1 << bit, regs + S3C64XX_UINTP); 62 __raw_writel(1 << bit, regs + S3C64XX_UINTP);
63} 63}
64 64
65static void s3c_irq_uart_unmask(unsigned int irq) 65static void s3c_irq_uart_unmask(struct irq_data *data)
66{ 66{
67 void __iomem *regs = s3c_irq_uart_base(irq); 67 void __iomem *regs = s3c_irq_uart_base(data);
68 unsigned int bit = s3c_irq_uart_bit(irq); 68 unsigned int bit = s3c_irq_uart_bit(data->irq);
69 u32 reg; 69 u32 reg;
70 70
71 reg = __raw_readl(regs + S3C64XX_UINTM); 71 reg = __raw_readl(regs + S3C64XX_UINTM);
@@ -73,17 +73,17 @@ static void s3c_irq_uart_unmask(unsigned int irq)
73 __raw_writel(reg, regs + S3C64XX_UINTM); 73 __raw_writel(reg, regs + S3C64XX_UINTM);
74} 74}
75 75
76static void s3c_irq_uart_ack(unsigned int irq) 76static void s3c_irq_uart_ack(struct irq_data *data)
77{ 77{
78 void __iomem *regs = s3c_irq_uart_base(irq); 78 void __iomem *regs = s3c_irq_uart_base(data);
79 unsigned int bit = s3c_irq_uart_bit(irq); 79 unsigned int bit = s3c_irq_uart_bit(data->irq);
80 80
81 __raw_writel(1 << bit, regs + S3C64XX_UINTP); 81 __raw_writel(1 << bit, regs + S3C64XX_UINTP);
82} 82}
83 83
84static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) 84static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
85{ 85{
86 struct s3c_uart_irq *uirq = desc->handler_data; 86 struct s3c_uart_irq *uirq = desc->irq_data.handler_data;
87 u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP); 87 u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
88 int base = uirq->base_irq; 88 int base = uirq->base_irq;
89 89
@@ -99,10 +99,10 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
99 99
100static struct irq_chip s3c_irq_uart = { 100static struct irq_chip s3c_irq_uart = {
101 .name = "s3c-uart", 101 .name = "s3c-uart",
102 .mask = s3c_irq_uart_mask, 102 .irq_mask = s3c_irq_uart_mask,
103 .unmask = s3c_irq_uart_unmask, 103 .irq_unmask = s3c_irq_uart_unmask,
104 .mask_ack = s3c_irq_uart_maskack, 104 .irq_mask_ack = s3c_irq_uart_maskack,
105 .ack = s3c_irq_uart_ack, 105 .irq_ack = s3c_irq_uart_ack,
106}; 106};
107 107
108static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) 108static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
@@ -124,7 +124,7 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
124 set_irq_flags(irq, IRQF_VALID); 124 set_irq_flags(irq, IRQF_VALID);
125 } 125 }
126 126
127 desc->handler_data = uirq; 127 desc->irq_data.handler_data = uirq;
128 set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); 128 set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
129} 129}
130 130
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
index 0270519fcabc..dd8692ae5c4c 100644
--- a/arch/arm/plat-samsung/irq-vic-timer.c
+++ b/arch/arm/plat-samsung/irq-vic-timer.c
@@ -24,43 +24,46 @@
24 24
25static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) 25static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
26{ 26{
27 generic_handle_irq((int)desc->handler_data); 27 generic_handle_irq((int)desc->irq_data.handler_data);
28} 28}
29 29
30/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ 30/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
31 31
32static void s3c_irq_timer_mask(unsigned int irq) 32static void s3c_irq_timer_mask(struct irq_data *data)
33{ 33{
34 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); 34 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
35 u32 mask = (u32)data->chip_data;
35 36
36 reg &= 0x1f; /* mask out pending interrupts */ 37 reg &= 0x1f; /* mask out pending interrupts */
37 reg &= ~(1 << (irq - IRQ_TIMER0)); 38 reg &= ~mask;
38 __raw_writel(reg, S3C64XX_TINT_CSTAT); 39 __raw_writel(reg, S3C64XX_TINT_CSTAT);
39} 40}
40 41
41static void s3c_irq_timer_unmask(unsigned int irq) 42static void s3c_irq_timer_unmask(struct irq_data *data)
42{ 43{
43 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); 44 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
45 u32 mask = (u32)data->chip_data;
44 46
45 reg &= 0x1f; /* mask out pending interrupts */ 47 reg &= 0x1f; /* mask out pending interrupts */
46 reg |= 1 << (irq - IRQ_TIMER0); 48 reg |= mask;
47 __raw_writel(reg, S3C64XX_TINT_CSTAT); 49 __raw_writel(reg, S3C64XX_TINT_CSTAT);
48} 50}
49 51
50static void s3c_irq_timer_ack(unsigned int irq) 52static void s3c_irq_timer_ack(struct irq_data *data)
51{ 53{
52 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); 54 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
55 u32 mask = (u32)data->chip_data;
53 56
54 reg &= 0x1f; 57 reg &= 0x1f;
55 reg |= (1 << 5) << (irq - IRQ_TIMER0); 58 reg |= mask << 5;
56 __raw_writel(reg, S3C64XX_TINT_CSTAT); 59 __raw_writel(reg, S3C64XX_TINT_CSTAT);
57} 60}
58 61
59static struct irq_chip s3c_irq_timer = { 62static struct irq_chip s3c_irq_timer = {
60 .name = "s3c-timer", 63 .name = "s3c-timer",
61 .mask = s3c_irq_timer_mask, 64 .irq_mask = s3c_irq_timer_mask,
62 .unmask = s3c_irq_timer_unmask, 65 .irq_unmask = s3c_irq_timer_unmask,
63 .ack = s3c_irq_timer_ack, 66 .irq_ack = s3c_irq_timer_ack,
64}; 67};
65 68
66/** 69/**
@@ -79,8 +82,9 @@ void __init s3c_init_vic_timer_irq(unsigned int parent_irq,
79 set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer); 82 set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer);
80 83
81 set_irq_chip(timer_irq, &s3c_irq_timer); 84 set_irq_chip(timer_irq, &s3c_irq_timer);
85 set_irq_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0)));
82 set_irq_handler(timer_irq, handle_level_irq); 86 set_irq_handler(timer_irq, handle_level_irq);
83 set_irq_flags(timer_irq, IRQF_VALID); 87 set_irq_flags(timer_irq, IRQF_VALID);
84 88
85 desc->handler_data = (void *)timer_irq; 89 desc->irq_data.handler_data = (void *)timer_irq;
86} 90}
diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c
new file mode 100644
index 000000000000..efe1d564473e
--- /dev/null
+++ b/arch/arm/plat-samsung/pd.c
@@ -0,0 +1,95 @@
1/* linux/arch/arm/plat-samsung/pd.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung Power domain support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/err.h>
17#include <linux/pm_runtime.h>
18
19#include <plat/pd.h>
20
21static int samsung_pd_probe(struct platform_device *pdev)
22{
23 struct samsung_pd_info *pdata = pdev->dev.platform_data;
24 struct device *dev = &pdev->dev;
25
26 if (!pdata) {
27 dev_err(dev, "no device data specified\n");
28 return -ENOENT;
29 }
30
31 pm_runtime_set_active(dev);
32 pm_runtime_enable(dev);
33
34 dev_info(dev, "power domain registered\n");
35 return 0;
36}
37
38static int __devexit samsung_pd_remove(struct platform_device *pdev)
39{
40 struct device *dev = &pdev->dev;
41
42 pm_runtime_disable(dev);
43 return 0;
44}
45
46static int samsung_pd_runtime_suspend(struct device *dev)
47{
48 struct samsung_pd_info *pdata = dev->platform_data;
49 int ret = 0;
50
51 if (pdata->disable)
52 ret = pdata->disable(dev);
53
54 dev_dbg(dev, "suspended\n");
55 return ret;
56}
57
58static int samsung_pd_runtime_resume(struct device *dev)
59{
60 struct samsung_pd_info *pdata = dev->platform_data;
61 int ret = 0;
62
63 if (pdata->enable)
64 ret = pdata->enable(dev);
65
66 dev_dbg(dev, "resumed\n");
67 return ret;
68}
69
70static const struct dev_pm_ops samsung_pd_pm_ops = {
71 .runtime_suspend = samsung_pd_runtime_suspend,
72 .runtime_resume = samsung_pd_runtime_resume,
73};
74
75static struct platform_driver samsung_pd_driver = {
76 .driver = {
77 .name = "samsung-pd",
78 .owner = THIS_MODULE,
79 .pm = &samsung_pd_pm_ops,
80 },
81 .probe = samsung_pd_probe,
82 .remove = __devexit_p(samsung_pd_remove),
83};
84
85static int __init samsung_pd_init(void)
86{
87 int ret;
88
89 ret = platform_driver_register(&samsung_pd_driver);
90 if (ret)
91 printk(KERN_ERR "%s: failed to add PD driver\n", __func__);
92
93 return ret;
94}
95arch_initcall(samsung_pd_init);
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 27cfca597699..eaa57dc969ae 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -136,15 +136,15 @@ static void s3c_pm_restore_uarts(void) { }
136unsigned long s3c_irqwake_intmask = 0xffffffffL; 136unsigned long s3c_irqwake_intmask = 0xffffffffL;
137unsigned long s3c_irqwake_eintmask = 0xffffffffL; 137unsigned long s3c_irqwake_eintmask = 0xffffffffL;
138 138
139int s3c_irqext_wake(unsigned int irqno, unsigned int state) 139int s3c_irqext_wake(struct irq_data *data, unsigned int state)
140{ 140{
141 unsigned long bit = 1L << IRQ_EINT_BIT(irqno); 141 unsigned long bit = 1L << IRQ_EINT_BIT(data->irq);
142 142
143 if (!(s3c_irqwake_eintallow & bit)) 143 if (!(s3c_irqwake_eintallow & bit))
144 return -ENOENT; 144 return -ENOENT;
145 145
146 printk(KERN_INFO "wake %s for irq %d\n", 146 printk(KERN_INFO "wake %s for irq %d\n",
147 state ? "enabled" : "disabled", irqno); 147 state ? "enabled" : "disabled", data->irq);
148 148
149 if (!state) 149 if (!state)
150 s3c_irqwake_eintmask |= bit; 150 s3c_irqwake_eintmask |= bit;
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index 7ac2bf5167cd..2335edafe903 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -883,10 +883,10 @@ static struct uart_ops s3c24xx_serial_ops = {
883 883
884static struct uart_driver s3c24xx_uart_drv = { 884static struct uart_driver s3c24xx_uart_drv = {
885 .owner = THIS_MODULE, 885 .owner = THIS_MODULE,
886 .dev_name = "s3c2410_serial", 886 .driver_name = "s3c2410_serial",
887 .nr = CONFIG_SERIAL_SAMSUNG_UARTS, 887 .nr = CONFIG_SERIAL_SAMSUNG_UARTS,
888 .cons = S3C24XX_SERIAL_CONSOLE, 888 .cons = S3C24XX_SERIAL_CONSOLE,
889 .driver_name = S3C24XX_SERIAL_NAME, 889 .dev_name = S3C24XX_SERIAL_NAME,
890 .major = S3C24XX_SERIAL_MAJOR, 890 .major = S3C24XX_SERIAL_MAJOR,
891 .minor = S3C24XX_SERIAL_MINOR, 891 .minor = S3C24XX_SERIAL_MINOR,
892}; 892};