aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2010-05-19 05:04:11 -0400
committerBen Dooks <ben-linux@fluff.org>2010-05-19 05:04:11 -0400
commit32457942b90aabb9242b450f02d18d9c8d982916 (patch)
tree6472b77016f83f2ada7a7e2ca83a9803f313f1a8
parent6071399674e813d797d9f458ec8913b86c85398e (diff)
parentf64bea4318a73e833d0a9b8400cc0f6cee957da3 (diff)
ARM: Merge for-2635/fb-updates1
Merge branch 'for-2635/fb-updates1' into for-linus/samsung2
-rw-r--r--arch/arm/Kconfig7
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/dma.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/irqs.h28
-rw-r--r--arch/arm/mach-s3c2410/include/mach/map.h8
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-clock.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-dsc.h36
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpio.h28
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-irq.h10
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h30
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h24
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h3
-rw-r--r--arch/arm/mach-s3c2410/include/mach/uncompress.h4
-rw-r--r--arch/arm/mach-s3c2412/Kconfig3
-rw-r--r--arch/arm/mach-s3c2416/Kconfig39
-rw-r--r--arch/arm/mach-s3c2416/Makefile19
-rw-r--r--arch/arm/mach-s3c2416/clock.c135
-rw-r--r--arch/arm/mach-s3c2416/irq.c254
-rw-r--r--arch/arm/mach-s3c2416/mach-smdk2416.c206
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c130
-rw-r--r--arch/arm/mach-s3c2443/Kconfig1
-rw-r--r--arch/arm/mach-s3c2443/clock.c479
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pll.h35
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig6
-rw-r--r--arch/arm/plat-s3c24xx/Makefile1
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c21
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pll.h25
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2416.h31
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2443.h19
-rw-r--r--arch/arm/plat-s3c24xx/s3c2410-clock.c15
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c472
-rw-r--r--arch/arm/plat-samsung/clock.c15
-rw-r--r--arch/arm/plat-samsung/dev-fb.c1
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/fb.h7
-rw-r--r--arch/arm/plat-samsung/include/plat/pll6553x.h51
-rw-r--r--drivers/serial/Kconfig7
38 files changed, 1631 insertions, 527 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 92622eb5cc0..3f8718fc405 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -647,7 +647,7 @@ config ARCH_SA1100
647 Support for StrongARM 11x0 based boards. 647 Support for StrongARM 11x0 based boards.
648 648
649config ARCH_S3C2410 649config ARCH_S3C2410
650 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443" 650 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450"
651 select GENERIC_GPIO 651 select GENERIC_GPIO
652 select ARCH_HAS_CPUFREQ 652 select ARCH_HAS_CPUFREQ
653 select HAVE_CLK 653 select HAVE_CLK
@@ -656,6 +656,10 @@ config ARCH_S3C2410
656 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or 656 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
657 the Samsung SMDK2410 development board (and derivatives). 657 the Samsung SMDK2410 development board (and derivatives).
658 658
659 Note, the S3C2416 and the S3C2450 are so close that they even share
660 the same SoC ID code. This means that there is no seperate machine
661 directory (no arch/arm/mach-s3c2450) as the S3C2416 was first.
662
659config ARCH_S3C64XX 663config ARCH_S3C64XX
660 bool "Samsung S3C64XX" 664 bool "Samsung S3C64XX"
661 select PLAT_SAMSUNG 665 select PLAT_SAMSUNG
@@ -892,6 +896,7 @@ if ARCH_S3C2410
892source "arch/arm/mach-s3c2400/Kconfig" 896source "arch/arm/mach-s3c2400/Kconfig"
893source "arch/arm/mach-s3c2410/Kconfig" 897source "arch/arm/mach-s3c2410/Kconfig"
894source "arch/arm/mach-s3c2412/Kconfig" 898source "arch/arm/mach-s3c2412/Kconfig"
899source "arch/arm/mach-s3c2416/Kconfig"
895source "arch/arm/mach-s3c2440/Kconfig" 900source "arch/arm/mach-s3c2440/Kconfig"
896source "arch/arm/mach-s3c2443/Kconfig" 901source "arch/arm/mach-s3c2443/Kconfig"
897endif 902endif
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index eddcbba87c6..9505a70bfc0 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -162,7 +162,7 @@ machine-$(CONFIG_ARCH_PNX4008) := pnx4008
162machine-$(CONFIG_ARCH_PXA) := pxa 162machine-$(CONFIG_ARCH_PXA) := pxa
163machine-$(CONFIG_ARCH_REALVIEW) := realview 163machine-$(CONFIG_ARCH_REALVIEW) := realview
164machine-$(CONFIG_ARCH_RPC) := rpc 164machine-$(CONFIG_ARCH_RPC) := rpc
165machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2443 165machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
166machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 166machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
167machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx 167machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
168machine-$(CONFIG_ARCH_S5P6440) := s5p6440 168machine-$(CONFIG_ARCH_S5P6440) := s5p6440
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index 08ac5f96c01..cf68136cc66 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -54,7 +54,7 @@ enum dma_ch {
54#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ 54#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
55 55
56/* we have 4 dma channels */ 56/* we have 4 dma channels */
57#ifndef CONFIG_CPU_S3C2443 57#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
58#define S3C_DMA_CHANNELS (4) 58#define S3C_DMA_CHANNELS (4)
59#else 59#else
60#define S3C_DMA_CHANNELS (6) 60#define S3C_DMA_CHANNELS (6)
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
index 6c12c6312ad..11bb0f08fe6 100644
--- a/arch/arm/mach-s3c2410/include/mach/irqs.h
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -115,6 +115,26 @@
115#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13) 115#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13)
116#define IRQ_S3C2412_CF S3C2410_IRQSUB(14) 116#define IRQ_S3C2412_CF S3C2410_IRQSUB(14)
117 117
118
119#define IRQ_S3C2416_EINT8t15 S3C2410_IRQ(5)
120#define IRQ_S3C2416_DMA S3C2410_IRQ(17)
121#define IRQ_S3C2416_UART3 S3C2410_IRQ(18)
122#define IRQ_S3C2416_SDI1 S3C2410_IRQ(20)
123#define IRQ_S3C2416_SDI0 S3C2410_IRQ(21)
124
125#define IRQ_S3C2416_LCD2 S3C2410_IRQSUB(15)
126#define IRQ_S3C2416_LCD3 S3C2410_IRQSUB(16)
127#define IRQ_S3C2416_LCD4 S3C2410_IRQSUB(17)
128#define IRQ_S3C2416_DMA0 S3C2410_IRQSUB(18)
129#define IRQ_S3C2416_DMA1 S3C2410_IRQSUB(19)
130#define IRQ_S3C2416_DMA2 S3C2410_IRQSUB(20)
131#define IRQ_S3C2416_DMA3 S3C2410_IRQSUB(21)
132#define IRQ_S3C2416_DMA4 S3C2410_IRQSUB(22)
133#define IRQ_S3C2416_DMA5 S3C2410_IRQSUB(23)
134#define IRQ_S32416_WDT S3C2410_IRQSUB(27)
135#define IRQ_S32416_AC97 S3C2410_IRQSUB(28)
136
137
118/* extra irqs for s3c2440 */ 138/* extra irqs for s3c2440 */
119 139
120#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */ 140#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */
@@ -130,7 +150,10 @@
130#define IRQ_S3C2443_HSMMC S3C2410_IRQ(20) /* IRQ_SDI */ 150#define IRQ_S3C2443_HSMMC S3C2410_IRQ(20) /* IRQ_SDI */
131#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */ 151#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */
132 152
153#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */
154
133#define IRQ_HSMMC0 IRQ_S3C2443_HSMMC 155#define IRQ_HSMMC0 IRQ_S3C2443_HSMMC
156#define IRQ_HSMMC1 IRQ_S3C2416_HSMMC0
134 157
135#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14) 158#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14)
136#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15) 159#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15)
@@ -152,7 +175,7 @@
152#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27) 175#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27)
153#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) 176#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28)
154 177
155#ifdef CONFIG_CPU_S3C2443 178#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
156#define NR_IRQS (IRQ_S3C2443_AC97+1) 179#define NR_IRQS (IRQ_S3C2443_AC97+1)
157#else 180#else
158#define NR_IRQS (IRQ_S3C2440_AC97+1) 181#define NR_IRQS (IRQ_S3C2440_AC97+1)
@@ -164,6 +187,9 @@
164#define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3 187#define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3
165#define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3 188#define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3
166 189
190#define IRQ_LCD_VSYNC IRQ_S3C2443_LCD3
191#define IRQ_LCD_SYSTEM IRQ_S3C2443_LCD2
192
167#ifdef CONFIG_CPU_S3C2440 193#ifdef CONFIG_CPU_S3C2440
168#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97 194#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97
169#else 195#else
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index b049e61460b..091c98a639d 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -63,9 +63,11 @@
63#define S3C2440_PA_AC97 (0x5B000000) 63#define S3C2440_PA_AC97 (0x5B000000)
64#define S3C2440_SZ_AC97 SZ_1M 64#define S3C2440_SZ_AC97 SZ_1M
65 65
66/* S3C2443 High-speed SD/MMC */ 66/* S3C2443/S3C2416 High-speed SD/MMC */
67#define S3C2443_PA_HSMMC (0x4A800000) 67#define S3C2443_PA_HSMMC (0x4A800000)
68#define S3C2443_SZ_HSMMC (256) 68#define S3C2416_PA_HSMMC0 (0x4AC00000)
69
70#define S3C2443_PA_FB (0x4C800000)
69 71
70/* S3C2412 memory and IO controls */ 72/* S3C2412 memory and IO controls */
71#define S3C2412_PA_SSMC (0x4F000000) 73#define S3C2412_PA_SSMC (0x4F000000)
@@ -106,10 +108,12 @@
106#define S3C24XX_PA_SDI S3C2410_PA_SDI 108#define S3C24XX_PA_SDI S3C2410_PA_SDI
107#define S3C24XX_PA_NAND S3C2410_PA_NAND 109#define S3C24XX_PA_NAND S3C2410_PA_NAND
108 110
111#define S3C_PA_FB S3C2443_PA_FB
109#define S3C_PA_IIC S3C2410_PA_IIC 112#define S3C_PA_IIC S3C2410_PA_IIC
110#define S3C_PA_UART S3C24XX_PA_UART 113#define S3C_PA_UART S3C24XX_PA_UART
111#define S3C_PA_USBHOST S3C2410_PA_USBHOST 114#define S3C_PA_USBHOST S3C2410_PA_USBHOST
112#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC 115#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC
116#define S3C_PA_HSMMC1 S3C2416_PA_HSMMC0
113#define S3C_PA_NAND S3C24XX_PA_NAND 117#define S3C_PA_NAND S3C24XX_PA_NAND
114 118
115#endif /* __ASM_ARCH_MAP_H */ 119#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
index 9a0d169be13..3415b60082d 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
@@ -161,4 +161,6 @@
161 161
162#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */ 162#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
163 163
164#define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28)
165
164#endif /* __ASM_ARM_REGS_CLOCK */ 166#endif /* __ASM_ARM_REGS_CLOCK */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
index 3c3853cd3cf..98fd4a05587 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
@@ -19,6 +19,42 @@
19#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0) 19#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
20#endif 20#endif
21 21
22#if defined(CONFIG_CPU_S3C2416)
23#define S3C2416_DSC0 S3C2410_GPIOREG(0xc0)
24#define S3C2416_DSC1 S3C2410_GPIOREG(0xc4)
25#define S3C2416_DSC2 S3C2410_GPIOREG(0xc8)
26#define S3C2416_DSC3 S3C2410_GPIOREG(0x110)
27
28#define S3C2416_SELECT_DSC0 (0 << 30)
29#define S3C2416_SELECT_DSC1 (1 << 30)
30#define S3C2416_SELECT_DSC2 (2 << 30)
31#define S3C2416_SELECT_DSC3 (3 << 30)
32
33#define S3C2416_DSC_GETSHIFT(x) (x & 30)
34
35#define S3C2416_DSC0_CF (S3C2416_SELECT_DSC0 | 28)
36#define S3C2416_DSC0_CF_5mA (0 << 28)
37#define S3C2416_DSC0_CF_10mA (1 << 28)
38#define S3C2416_DSC0_CF_15mA (2 << 28)
39#define S3C2416_DSC0_CF_21mA (3 << 28)
40#define S3C2416_DSC0_CF_MASK (3 << 28)
41
42#define S3C2416_DSC0_nRBE (S3C2416_SELECT_DSC0 | 26)
43#define S3C2416_DSC0_nRBE_5mA (0 << 26)
44#define S3C2416_DSC0_nRBE_10mA (1 << 26)
45#define S3C2416_DSC0_nRBE_15mA (2 << 26)
46#define S3C2416_DSC0_nRBE_21mA (3 << 26)
47#define S3C2416_DSC0_nRBE_MASK (3 << 26)
48
49#define S3C2416_DSC0_nROE (S3C2416_SELECT_DSC0 | 24)
50#define S3C2416_DSC0_nROE_5mA (0 << 24)
51#define S3C2416_DSC0_nROE_10mA (1 << 24)
52#define S3C2416_DSC0_nROE_15mA (2 << 24)
53#define S3C2416_DSC0_nROE_21mA (3 << 24)
54#define S3C2416_DSC0_nROE_MASK (3 << 24)
55
56#endif
57
22#if defined(CONFIG_CPU_S3C244X) 58#if defined(CONFIG_CPU_S3C244X)
23 59
24#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4) 60#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
index 95e29fefec3..a0a89d42929 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -592,29 +592,50 @@
592#define S3C2410_GPHUP S3C2410_GPIOREG(0x78) 592#define S3C2410_GPHUP S3C2410_GPIOREG(0x78)
593 593
594#define S3C2410_GPH0_nCTS0 (0x02 << 0) 594#define S3C2410_GPH0_nCTS0 (0x02 << 0)
595#define S3C2416_GPH0_TXD0 (0x02 << 0)
595 596
596#define S3C2410_GPH1_nRTS0 (0x02 << 2) 597#define S3C2410_GPH1_nRTS0 (0x02 << 2)
598#define S3C2416_GPH1_RXD0 (0x02 << 2)
597 599
598#define S3C2410_GPH2_TXD0 (0x02 << 4) 600#define S3C2410_GPH2_TXD0 (0x02 << 4)
601#define S3C2416_GPH2_TXD1 (0x02 << 4)
599 602
600#define S3C2410_GPH3_RXD0 (0x02 << 6) 603#define S3C2410_GPH3_RXD0 (0x02 << 6)
604#define S3C2416_GPH3_RXD1 (0x02 << 6)
601 605
602#define S3C2410_GPH4_TXD1 (0x02 << 8) 606#define S3C2410_GPH4_TXD1 (0x02 << 8)
607#define S3C2416_GPH4_TXD2 (0x02 << 8)
603 608
604#define S3C2410_GPH5_RXD1 (0x02 << 10) 609#define S3C2410_GPH5_RXD1 (0x02 << 10)
610#define S3C2416_GPH5_RXD2 (0x02 << 10)
605 611
606#define S3C2410_GPH6_TXD2 (0x02 << 12) 612#define S3C2410_GPH6_TXD2 (0x02 << 12)
613#define S3C2416_GPH6_TXD3 (0x02 << 12)
607#define S3C2410_GPH6_nRTS1 (0x03 << 12) 614#define S3C2410_GPH6_nRTS1 (0x03 << 12)
615#define S3C2416_GPH6_nRTS2 (0x03 << 12)
608 616
609#define S3C2410_GPH7_RXD2 (0x02 << 14) 617#define S3C2410_GPH7_RXD2 (0x02 << 14)
618#define S3C2416_GPH7_RXD3 (0x02 << 14)
610#define S3C2410_GPH7_nCTS1 (0x03 << 14) 619#define S3C2410_GPH7_nCTS1 (0x03 << 14)
620#define S3C2416_GPH7_nCTS2 (0x03 << 14)
611 621
612#define S3C2410_GPH8_UCLK (0x02 << 16) 622#define S3C2410_GPH8_UCLK (0x02 << 16)
623#define S3C2416_GPH8_nCTS0 (0x02 << 16)
613 624
614#define S3C2410_GPH9_CLKOUT0 (0x02 << 18) 625#define S3C2410_GPH9_CLKOUT0 (0x02 << 18)
615#define S3C2442_GPH9_nSPICS0 (0x03 << 18) 626#define S3C2442_GPH9_nSPICS0 (0x03 << 18)
627#define S3C2416_GPH9_nRTS0 (0x02 << 18)
616 628
617#define S3C2410_GPH10_CLKOUT1 (0x02 << 20) 629#define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
630#define S3C2416_GPH10_nCTS1 (0x02 << 20)
631
632#define S3C2416_GPH11_nRTS1 (0x02 << 22)
633
634#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24)
635
636#define S3C2416_GPH13_CLKOUT0 (0x02 << 26)
637
638#define S3C2416_GPH14_CLKOUT1 (0x02 << 28)
618 639
619/* The S3C2412 and S3C2413 move the GPJ register set to after 640/* The S3C2412 and S3C2413 move the GPJ register set to after
620 * GPH, which means all registers after 0x80 are now offset by 0x10 641 * GPH, which means all registers after 0x80 are now offset by 0x10
@@ -685,6 +706,7 @@
685#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8) 706#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8)
686 707
687#define S3C2410_MISCCR_USBSUSPND0 (1<<12) 708#define S3C2410_MISCCR_USBSUSPND0 (1<<12)
709#define S3C2416_MISCCR_SEL_SUSPND (1<<12)
688#define S3C2410_MISCCR_USBSUSPND1 (1<<13) 710#define S3C2410_MISCCR_USBSUSPND1 (1<<13)
689 711
690#define S3C2410_MISCCR_nRSTCON (1<<16) 712#define S3C2410_MISCCR_nRSTCON (1<<16)
@@ -694,6 +716,9 @@
694#define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */ 716#define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */
695#define S3C2410_MISCCR_SDSLEEP (7<<17) 717#define S3C2410_MISCCR_SDSLEEP (7<<17)
696 718
719#define S3C2416_MISCCR_FLT_I2C (1<<24)
720#define S3C2416_MISCCR_HSSPI_EN2 (1<<31)
721
697/* external interrupt control... */ 722/* external interrupt control... */
698/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7 723/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
699 * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15 724 * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
@@ -761,8 +786,11 @@
761#define S3C2410_GSTATUS1_IDMASK (0xffff0000) 786#define S3C2410_GSTATUS1_IDMASK (0xffff0000)
762#define S3C2410_GSTATUS1_2410 (0x32410000) 787#define S3C2410_GSTATUS1_2410 (0x32410000)
763#define S3C2410_GSTATUS1_2412 (0x32412001) 788#define S3C2410_GSTATUS1_2412 (0x32412001)
789#define S3C2410_GSTATUS1_2416 (0x32416003)
764#define S3C2410_GSTATUS1_2440 (0x32440000) 790#define S3C2410_GSTATUS1_2440 (0x32440000)
765#define S3C2410_GSTATUS1_2442 (0x32440aaa) 791#define S3C2410_GSTATUS1_2442 (0x32440aaa)
792/* some 2416 CPUs report this value also */
793#define S3C2410_GSTATUS1_2450 (0x32450003)
766 794
767#define S3C2410_GSTATUS2_WTRESET (1<<2) 795#define S3C2410_GSTATUS2_WTRESET (1<<2)
768#define S3C2410_GSTATUS2_OFFRESET (1<<1) 796#define S3C2410_GSTATUS2_OFFRESET (1<<1)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-irq.h b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
index de86ee8812b..0f07ba30b1f 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-irq.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
@@ -27,6 +27,16 @@
27#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018) 27#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018)
28#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C) 28#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C)
29 29
30#define S3C2416_PRIORITY_MODE1 S3C2410_IRQREG(0x030)
31#define S3C2416_PRIORITY_UPDATE1 S3C2410_IRQREG(0x034)
32#define S3C2416_SRCPND2 S3C2410_IRQREG(0x040)
33#define S3C2416_INTMOD2 S3C2410_IRQREG(0x044)
34#define S3C2416_INTMSK2 S3C2410_IRQREG(0x048)
35#define S3C2416_INTPND2 S3C2410_IRQREG(0x050)
36#define S3C2416_INTOFFSET2 S3C2410_IRQREG(0x054)
37#define S3C2416_PRIORITY_MODE2 S3C2410_IRQREG(0x070)
38#define S3C2416_PRIORITY_UPDATE2 S3C2410_IRQREG(0x074)
39
30/* mask: 0=enable, 1=disable 40/* mask: 0=enable, 1=disable
31 * 1 bit EINT, 4=EINT4, 23=EINT23 41 * 1 bit EINT, 4=EINT4, 23=EINT23
32 * EINT0,1,2,3 are not handled here. 42 * EINT0,1,2,3 are not handled here.
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
new file mode 100644
index 00000000000..2f31b74974a
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
@@ -0,0 +1,30 @@
1/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
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 * S3C2416 memory register definitions
13*/
14
15#ifndef __ASM_ARM_REGS_S3C2416_MEM
16#define __ASM_ARM_REGS_S3C2416_MEM
17
18#ifndef S3C2416_MEMREG
19#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
20#endif
21
22#define S3C2416_BANKCFG S3C2416_MEMREG(0x00)
23#define S3C2416_BANKCON1 S3C2416_MEMREG(0x04)
24#define S3C2416_BANKCON2 S3C2416_MEMREG(0x08)
25#define S3C2416_BANKCON3 S3C2416_MEMREG(0x0C)
26
27#define S3C2416_REFRESH S3C2416_MEMREG(0x10)
28#define S3C2416_TIMEOUT S3C2416_MEMREG(0x14)
29
30#endif /* __ASM_ARM_REGS_S3C2416_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
new file mode 100644
index 00000000000..e443167efb8
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
@@ -0,0 +1,24 @@
1/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
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 * S3C2416 specific register definitions
13*/
14
15#ifndef __ASM_ARCH_REGS_S3C2416_H
16#define __ASM_ARCH_REGS_S3C2416_H "s3c2416"
17
18#define S3C2416_SWRST (S3C24XX_VA_CLKPWR + 0x44)
19#define S3C2416_SWRST_RESET (0x533C2416)
20
21/* see regs-power.h for the other registers in the power block. */
22
23#endif /* __ASM_ARCH_REGS_S3C2416_H */
24
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 d87ebe0cb62..08ab9dfb6ae 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
@@ -83,8 +83,7 @@
83#define S3C2443_HCLKCON_DMA4 (1<<4) 83#define S3C2443_HCLKCON_DMA4 (1<<4)
84#define S3C2443_HCLKCON_DMA5 (1<<5) 84#define S3C2443_HCLKCON_DMA5 (1<<5)
85#define S3C2443_HCLKCON_CAMIF (1<<8) 85#define S3C2443_HCLKCON_CAMIF (1<<8)
86#define S3C2443_HCLKCON_DISP (1<<9) 86#define S3C2443_HCLKCON_LCDC (1<<9)
87#define S3C2443_HCLKCON_LCDC (1<<10)
88#define S3C2443_HCLKCON_USBH (1<<11) 87#define S3C2443_HCLKCON_USBH (1<<11)
89#define S3C2443_HCLKCON_USBD (1<<12) 88#define S3C2443_HCLKCON_USBD (1<<12)
90#define S3C2443_HCLKCON_HSMMC (1<<16) 89#define S3C2443_HCLKCON_HSMMC (1<<16)
diff --git a/arch/arm/mach-s3c2410/include/mach/uncompress.h b/arch/arm/mach-s3c2410/include/mach/uncompress.h
index 72f756c5e50..8b283f847da 100644
--- a/arch/arm/mach-s3c2410/include/mach/uncompress.h
+++ b/arch/arm/mach-s3c2410/include/mach/uncompress.h
@@ -40,7 +40,9 @@ static void arch_detect_cpu(void)
40 cpuid &= S3C2410_GSTATUS1_IDMASK; 40 cpuid &= S3C2410_GSTATUS1_IDMASK;
41 41
42 if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 || 42 if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
43 cpuid == S3C2410_GSTATUS1_2442) { 43 cpuid == S3C2410_GSTATUS1_2442 ||
44 cpuid == S3C2410_GSTATUS1_2416 ||
45 cpuid == S3C2410_GSTATUS1_2450) {
44 fifo_mask = S3C2440_UFSTAT_TXMASK; 46 fifo_mask = S3C2440_UFSTAT_TXMASK;
45 fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; 47 fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
46 } else { 48 } else {
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 9a8c0657ae5..cef6a65637b 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -16,7 +16,8 @@ config CPU_S3C2412
16config CPU_S3C2412_ONLY 16config CPU_S3C2412_ONLY
17 bool 17 bool
18 depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ 18 depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
19 !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412 19 !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
20 !CPU_S3C2443 && CPU_S3C2412
20 default y if CPU_S3C2412 21 default y if CPU_S3C2412
21 22
22config S3C2412_DMA 23config S3C2412_DMA
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
new file mode 100644
index 00000000000..657e4fe17f3
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -0,0 +1,39 @@
1# arch/arm/mach-s3c2416/Kconfig
2#
3# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
4#
5# Licensed under GPLv2
6
7# note, this also supports the S3C2450 which is so similar it has the same
8# ID code as the S3C2416.
9
10config CPU_S3C2416
11 bool
12 depends on ARCH_S3C2410
13 select CPU_ARM926T
14 select S3C2416_DMA if S3C2410_DMA
15 select CPU_LLSERIAL_S3C2440
16 select S3C_GPIO_PULL_UPDOWN
17 select SAMSUNG_CLKSRC
18 select S3C2443_CLOCK
19 help
20 Support for the S3C2416 SoC from the S3C24XX line
21
22config S3C2416_DMA
23 bool
24 depends on CPU_S3C2416
25 help
26 Internal config node for S3C2416 DMA support
27
28menu "S3C2416 Machines"
29
30config MACH_SMDK2416
31 bool "SMDK2416"
32 select CPU_S3C2416
33 select S3C_DEV_FB
34 select S3C_DEV_HSMMC
35 select S3C_DEV_HSMMC1
36 help
37 Say Y here if you are using an SMDK2416
38
39endmenu
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
new file mode 100644
index 00000000000..6c12c7bf40a
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Makefile
@@ -0,0 +1,19 @@
1# arch/arm/mach-s3c2416/Makefile
2#
3# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n :=
10obj- :=
11
12obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o
13obj-$(CONFIG_CPU_S3C2416) += irq.o
14
15#obj-$(CONFIG_S3C2416_DMA) += dma.o
16
17# Machine support
18
19obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
new file mode 100644
index 00000000000..7ccf5a2a2bf
--- /dev/null
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -0,0 +1,135 @@
1/* linux/arch/arm/mach-s3c2416/clock.c
2 *
3 * Copyright (c) 2010 Simtec Electronics
4 * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
5 *
6 * S3C2416 Clock control 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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/clk.h>
16
17#include <plat/s3c2416.h>
18#include <plat/s3c2443.h>
19#include <plat/clock.h>
20#include <plat/clock-clksrc.h>
21#include <plat/cpu.h>
22
23#include <plat/cpu-freq.h>
24#include <plat/pll6553x.h>
25#include <plat/pll.h>
26
27#include <asm/mach/map.h>
28
29#include <mach/regs-clock.h>
30#include <mach/regs-s3c2443-clock.h>
31
32static unsigned int armdiv[8] = {
33 [0] = 1,
34 [1] = 2,
35 [2] = 3,
36 [3] = 4,
37 [5] = 6,
38 [7] = 8,
39};
40
41/* ID to hardware numbering, 0 is HSMMC1, 1 is HSMMC0 */
42static struct clksrc_clk hsmmc_div[] = {
43 [0] = {
44 .clk = {
45 .name = "hsmmc-div",
46 .id = 1,
47 .parent = &clk_esysclk.clk,
48 },
49 .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
50 },
51 [1] = {
52 .clk = {
53 .name = "hsmmc-div",
54 .id = 0,
55 .parent = &clk_esysclk.clk,
56 },
57 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
58 },
59};
60
61static struct clksrc_clk hsmmc_mux[] = {
62 [0] = {
63 .clk = {
64 .id = 1,
65 .name = "hsmmc-if",
66 .ctrlbit = (1 << 6),
67 .enable = s3c2443_clkcon_enable_s,
68 },
69 .sources = &(struct clksrc_sources) {
70 .nr_sources = 2,
71 .sources = (struct clk *[]) {
72 [0] = &hsmmc_div[0].clk,
73 [1] = NULL, /* to fix */
74 },
75 },
76 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
77 },
78 [1] = {
79 .clk = {
80 .id = 0,
81 .name = "hsmmc-if",
82 .ctrlbit = (1 << 12),
83 .enable = s3c2443_clkcon_enable_s,
84 },
85 .sources = &(struct clksrc_sources) {
86 .nr_sources = 2,
87 .sources = (struct clk *[]) {
88 [0] = &hsmmc_div[1].clk,
89 [1] = NULL, /* to fix */
90 },
91 },
92 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
93 },
94};
95
96
97static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
98{
99 clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT;
100
101 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
102}
103
104void __init_or_cpufreq s3c2416_setup_clocks(void)
105{
106 s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div);
107}
108
109
110static struct clksrc_clk *clksrcs[] __initdata = {
111 &hsmmc_div[0],
112 &hsmmc_div[1],
113 &hsmmc_mux[0],
114 &hsmmc_mux[1],
115};
116
117void __init s3c2416_init_clocks(int xtal)
118{
119 u32 epllcon = __raw_readl(S3C2443_EPLLCON);
120 u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
121 int ptr;
122
123 /* s3c2416 EPLL compatible with s3c64xx */
124 clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
125
126 clk_epll.parent = &clk_epllref.clk;
127
128 s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div);
129
130 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
131 s3c_register_clksrc(clksrcs[ptr], 1);
132
133 s3c_pwmclk_init();
134
135}
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
new file mode 100644
index 00000000000..89f521d59d0
--- /dev/null
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -0,0 +1,254 @@
1/* linux/arch/arm/mach-s3c2416/irq.c
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22*/
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/interrupt.h>
27#include <linux/ioport.h>
28#include <linux/sysdev.h>
29#include <linux/io.h>
30
31#include <mach/hardware.h>
32#include <asm/irq.h>
33
34#include <asm/mach/irq.h>
35
36#include <mach/regs-irq.h>
37#include <mach/regs-gpio.h>
38
39#include <plat/cpu.h>
40#include <plat/pm.h>
41#include <plat/irq.h>
42
43#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
44
45static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
46{
47 unsigned int subsrc, submsk;
48 unsigned int end;
49
50 /* read the current pending interrupts, and the mask
51 * for what it is available */
52
53 subsrc = __raw_readl(S3C2410_SUBSRCPND);
54 submsk = __raw_readl(S3C2410_INTSUBMSK);
55
56 subsrc &= ~submsk;
57 subsrc >>= (irq - S3C2410_IRQSUB(0));
58 subsrc &= (1 << len)-1;
59
60 end = len + irq;
61
62 for (; irq < end && subsrc; irq++) {
63 if (subsrc & 1)
64 generic_handle_irq(irq);
65
66 subsrc >>= 1;
67 }
68}
69
70/* WDT/AC97 sub interrupts */
71
72static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
73{
74 s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
75}
76
77#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
78#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
79
80static void s3c2416_irq_wdtac97_mask(unsigned int irqno)
81{
82 s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
83}
84
85static void s3c2416_irq_wdtac97_unmask(unsigned int irqno)
86{
87 s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
88}
89
90static void s3c2416_irq_wdtac97_ack(unsigned int irqno)
91{
92 s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
93}
94
95static struct irq_chip s3c2416_irq_wdtac97 = {
96 .mask = s3c2416_irq_wdtac97_mask,
97 .unmask = s3c2416_irq_wdtac97_unmask,
98 .ack = s3c2416_irq_wdtac97_ack,
99};
100
101
102/* LCD sub interrupts */
103
104static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
105{
106 s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
107}
108
109#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
110#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
111
112static void s3c2416_irq_lcd_mask(unsigned int irqno)
113{
114 s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
115}
116
117static void s3c2416_irq_lcd_unmask(unsigned int irqno)
118{
119 s3c_irqsub_unmask(irqno, INTMSK_LCD);
120}
121
122static void s3c2416_irq_lcd_ack(unsigned int irqno)
123{
124 s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
125}
126
127static struct irq_chip s3c2416_irq_lcd = {
128 .mask = s3c2416_irq_lcd_mask,
129 .unmask = s3c2416_irq_lcd_unmask,
130 .ack = s3c2416_irq_lcd_ack,
131};
132
133
134/* DMA sub interrupts */
135
136static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
137{
138 s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
139}
140
141#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
142#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
143
144
145static void s3c2416_irq_dma_mask(unsigned int irqno)
146{
147 s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
148}
149
150static void s3c2416_irq_dma_unmask(unsigned int irqno)
151{
152 s3c_irqsub_unmask(irqno, INTMSK_DMA);
153}
154
155static void s3c2416_irq_dma_ack(unsigned int irqno)
156{
157 s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
158}
159
160static struct irq_chip s3c2416_irq_dma = {
161 .mask = s3c2416_irq_dma_mask,
162 .unmask = s3c2416_irq_dma_unmask,
163 .ack = s3c2416_irq_dma_ack,
164};
165
166
167/* UART3 sub interrupts */
168
169static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
170{
171 s3c2416_irq_demux(IRQ_S3C2443_UART3, 3);
172}
173
174#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
175#define SUBMSK_UART3 (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
176
177
178static void s3c2416_irq_uart3_mask(unsigned int irqno)
179{
180 s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
181}
182
183static void s3c2416_irq_uart3_unmask(unsigned int irqno)
184{
185 s3c_irqsub_unmask(irqno, INTMSK_UART3);
186}
187
188static void s3c2416_irq_uart3_ack(unsigned int irqno)
189{
190 s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
191}
192
193static struct irq_chip s3c2416_irq_uart3 = {
194 .mask = s3c2416_irq_uart3_mask,
195 .unmask = s3c2416_irq_uart3_unmask,
196 .ack = s3c2416_irq_uart3_ack,
197};
198
199
200/* IRQ initialisation code */
201
202static int __init s3c2416_add_sub(unsigned int base,
203 void (*demux)(unsigned int,
204 struct irq_desc *),
205 struct irq_chip *chip,
206 unsigned int start, unsigned int end)
207{
208 unsigned int irqno;
209
210 set_irq_chip(base, &s3c_irq_level_chip);
211 set_irq_handler(base, handle_level_irq);
212 set_irq_chained_handler(base, demux);
213
214 for (irqno = start; irqno <= end; irqno++) {
215 set_irq_chip(irqno, chip);
216 set_irq_handler(irqno, handle_level_irq);
217 set_irq_flags(irqno, IRQF_VALID);
218 }
219
220 return 0;
221}
222
223static int __init s3c2416_irq_add(struct sys_device *sysdev)
224{
225 printk(KERN_INFO "S3C2416: IRQ Support\n");
226
227 s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
228 IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
229
230 s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
231 &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
232
233 s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
234 &s3c2416_irq_uart3,
235 IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
236
237 s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
238 &s3c2416_irq_wdtac97,
239 IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
240
241 return 0;
242}
243
244static struct sysdev_driver s3c2416_irq_driver = {
245 .add = s3c2416_irq_add,
246};
247
248static int __init s3c2416_irq_init(void)
249{
250 return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_irq_driver);
251}
252
253arch_initcall(s3c2416_irq_init);
254
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
new file mode 100644
index 00000000000..5fc3f67ef26
--- /dev/null
+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
@@ -0,0 +1,206 @@
1/* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
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
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/list.h>
18#include <linux/timer.h>
19#include <linux/init.h>
20#include <linux/serial_core.h>
21#include <linux/platform_device.h>
22#include <linux/io.h>
23#include <linux/mtd/partitions.h>
24#include <linux/gpio.h>
25#include <linux/fb.h>
26
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29#include <asm/mach/irq.h>
30
31#include <mach/hardware.h>
32#include <asm/irq.h>
33#include <asm/mach-types.h>
34
35#include <plat/regs-serial.h>
36#include <mach/regs-gpio.h>
37#include <mach/regs-lcd.h>
38
39#include <mach/idle.h>
40#include <mach/leds-gpio.h>
41#include <plat/iic.h>
42
43#include <plat/s3c2416.h>
44#include <plat/gpio-cfg.h>
45#include <plat/clock.h>
46#include <plat/devs.h>
47#include <plat/cpu.h>
48#include <plat/nand.h>
49
50#include <plat/regs-fb-v4.h>
51#include <plat/fb.h>
52
53#include <plat/common-smdk.h>
54
55static struct map_desc smdk2416_iodesc[] __initdata = {
56 /* ISA IO Space map (memory space selected by A24) */
57
58 {
59 .virtual = (u32)S3C24XX_VA_ISA_WORD,
60 .pfn = __phys_to_pfn(S3C2410_CS2),
61 .length = 0x10000,
62 .type = MT_DEVICE,
63 }, {
64 .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
65 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
66 .length = SZ_4M,
67 .type = MT_DEVICE,
68 }, {
69 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
70 .pfn = __phys_to_pfn(S3C2410_CS2),
71 .length = 0x10000,
72 .type = MT_DEVICE,
73 }, {
74 .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
75 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
76 .length = SZ_4M,
77 .type = MT_DEVICE,
78 }
79};
80
81#define UCON (S3C2410_UCON_DEFAULT | \
82 S3C2440_UCON_PCLK | \
83 S3C2443_UCON_RXERR_IRQEN)
84
85#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
86
87#define UFCON (S3C2410_UFCON_RXTRIG8 | \
88 S3C2410_UFCON_FIFOMODE | \
89 S3C2440_UFCON_TXTRIG16)
90
91static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
92 [0] = {
93 .hwport = 0,
94 .flags = 0,
95 .ucon = UCON,
96 .ulcon = ULCON,
97 .ufcon = UFCON,
98 },
99 [1] = {
100 .hwport = 1,
101 .flags = 0,
102 .ucon = UCON,
103 .ulcon = ULCON,
104 .ufcon = UFCON,
105 },
106 /* IR port */
107 [2] = {
108 .hwport = 2,
109 .flags = 0,
110 .ucon = UCON,
111 .ulcon = ULCON | 0x50,
112 .ufcon = UFCON,
113 }
114};
115
116struct s3c_fb_pd_win smdk2416_fb_win[] = {
117 [0] = {
118 /* think this is the same as the smdk6410 */
119 .win_mode = {
120 .pixclock = 41094,
121 .left_margin = 8,
122 .right_margin = 13,
123 .upper_margin = 7,
124 .lower_margin = 5,
125 .hsync_len = 3,
126 .vsync_len = 1,
127 .xres = 800,
128 .yres = 480,
129 },
130 .default_bpp = 16,
131 .max_bpp = 32,
132 },
133};
134
135static void s3c2416_fb_gpio_setup_24bpp(void)
136{
137 unsigned int gpio;
138
139 for (gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) {
140 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
141 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
142 }
143
144 for (gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) {
145 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
146 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
147 }
148
149 for (gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) {
150 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
151 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
152 }
153}
154
155static struct s3c_fb_platdata smdk2416_fb_platdata = {
156 .win[0] = &smdk2416_fb_win[0],
157 .setup_gpio = s3c2416_fb_gpio_setup_24bpp,
158 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
159 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
160};
161
162static struct platform_device *smdk2416_devices[] __initdata = {
163 &s3c_device_fb,
164 &s3c_device_wdt,
165 &s3c_device_ohci,
166 &s3c_device_i2c0,
167 &s3c_device_hsmmc0,
168 &s3c_device_hsmmc1,
169};
170
171static void __init smdk2416_map_io(void)
172{
173 s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
174 s3c24xx_init_clocks(12000000);
175 s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
176}
177
178static void __init smdk2416_machine_init(void)
179{
180 s3c_i2c0_set_platdata(NULL);
181 s3c_fb_set_platdata(&smdk2416_fb_platdata);
182
183 gpio_request(S3C2410_GPB(4), "USBHost Power");
184 gpio_direction_output(S3C2410_GPB(4), 1);
185
186 gpio_request(S3C2410_GPB(3), "Display Power");
187 gpio_direction_output(S3C2410_GPB(3), 1);
188
189 gpio_request(S3C2410_GPB(1), "Display Reset");
190 gpio_direction_output(S3C2410_GPB(1), 1);
191
192 platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
193 smdk_machine_init();
194}
195
196MACHINE_START(SMDK2416, "SMDK2416")
197 /* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
198 .phys_io = S3C2410_PA_UART,
199 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
200 .boot_params = S3C2410_SDRAM_PA + 0x100,
201
202 .init_irq = s3c24xx_init_irq,
203 .map_io = smdk2416_map_io,
204 .init_machine = smdk2416_machine_init,
205 .timer = &s3c24xx_timer,
206MACHINE_END
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
new file mode 100644
index 00000000000..35dabccd0ac
--- /dev/null
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -0,0 +1,130 @@
1/* linux/arch/arm/mach-s3c2416/s3c2416.c
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
7 *
8 * Samsung S3C2416 Mobile CPU support
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 as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/interrupt.h>
28#include <linux/list.h>
29#include <linux/timer.h>
30#include <linux/init.h>
31#include <linux/gpio.h>
32#include <linux/platform_device.h>
33#include <linux/serial_core.h>
34#include <linux/sysdev.h>
35#include <linux/clk.h>
36#include <linux/io.h>
37
38#include <asm/mach/arch.h>
39#include <asm/mach/map.h>
40#include <asm/mach/irq.h>
41
42#include <mach/hardware.h>
43#include <asm/proc-fns.h>
44#include <asm/irq.h>
45
46#include <mach/reset.h>
47#include <mach/idle.h>
48#include <mach/regs-s3c2443-clock.h>
49
50#include <plat/gpio-core.h>
51#include <plat/gpio-cfg.h>
52#include <plat/gpio-cfg-helpers.h>
53#include <plat/s3c2416.h>
54#include <plat/devs.h>
55#include <plat/cpu.h>
56
57#include <plat/iic-core.h>
58
59static struct map_desc s3c2416_iodesc[] __initdata = {
60 IODESC_ENT(WATCHDOG),
61 IODESC_ENT(CLKPWR),
62 IODESC_ENT(TIMER),
63};
64
65struct sysdev_class s3c2416_sysclass = {
66 .name = "s3c2416-core",
67};
68
69static struct sys_device s3c2416_sysdev = {
70 .cls = &s3c2416_sysclass,
71};
72
73static void s3c2416_hard_reset(void)
74{
75 __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
76}
77
78int __init s3c2416_init(void)
79{
80 printk(KERN_INFO "S3C2416: Initializing architecture\n");
81
82 s3c24xx_reset_hook = s3c2416_hard_reset;
83 /* s3c24xx_idle = s3c2416_idle; */
84
85 /* change WDT IRQ number */
86 s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
87 s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT;
88
89 /* the i2c devices are directly compatible with s3c2440 */
90 s3c_i2c0_setname("s3c2440-i2c");
91 s3c_i2c1_setname("s3c2440-i2c");
92
93 s3c_device_fb.name = "s3c2443-fb";
94
95 return sysdev_register(&s3c2416_sysdev);
96}
97
98void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
99{
100 s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
101
102 s3c_device_nand.name = "s3c2416-nand";
103}
104
105/* s3c2416_map_io
106 *
107 * register the standard cpu IO areas, and any passed in from the
108 * machine specific initialisation.
109 */
110
111void __init s3c2416_map_io(void)
112{
113 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown;
114 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown;
115
116 iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
117}
118
119/* need to register class before we actually register the device, and
120 * we also need to ensure that it has been initialised before any of the
121 * drivers even try to use it (even if not on an s3c2416 based system)
122 * as a driver which may support both 2443 and 2440 may try and use it.
123*/
124
125static int __init s3c2416_core_init(void)
126{
127 return sysdev_class_register(&s3c2416_sysclass);
128}
129
130core_initcall(s3c2416_core_init);
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
index 698140af247..4fef723126f 100644
--- a/arch/arm/mach-s3c2443/Kconfig
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -8,6 +8,7 @@ config CPU_S3C2443
8 select S3C2443_DMA if S3C2410_DMA 8 select S3C2443_DMA if S3C2410_DMA
9 select CPU_LLSERIAL_S3C2440 9 select CPU_LLSERIAL_S3C2440
10 select SAMSUNG_CLKSRC 10 select SAMSUNG_CLKSRC
11 select S3C2443_CLOCK
11 help 12 help
12 Support for the S3C2443 SoC from the S3C24XX line 13 Support for the S3C2443 SoC from the S3C24XX line
13 14
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 62cd4eaee01..83b1aa63d77 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -21,6 +21,7 @@
21*/ 21*/
22 22
23#include <linux/init.h> 23#include <linux/init.h>
24
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/kernel.h> 26#include <linux/kernel.h>
26#include <linux/list.h> 27#include <linux/list.h>
@@ -54,111 +55,13 @@
54 * set the correct muxing at initialisation 55 * set the correct muxing at initialisation
55*/ 56*/
56 57
57static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
58{
59 u32 ctrlbit = clk->ctrlbit;
60 u32 con = __raw_readl(reg);
61
62 if (enable)
63 con |= ctrlbit;
64 else
65 con &= ~ctrlbit;
66
67 __raw_writel(con, reg);
68 return 0;
69}
70
71static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
72{
73 return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
74}
75
76static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
77{
78 return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
79}
80
81static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
82{
83 return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
84}
85
86/* clock selections */ 58/* clock selections */
87 59
88/* mpllref is a direct descendant of clk_xtal by default, but it is not
89 * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
90 * such directly equating the two source clocks is impossible.
91 */
92static struct clk clk_mpllref = {
93 .name = "mpllref",
94 .parent = &clk_xtal,
95 .id = -1,
96};
97
98static struct clk clk_i2s_ext = { 60static struct clk clk_i2s_ext = {
99 .name = "i2s-ext", 61 .name = "i2s-ext",
100 .id = -1, 62 .id = -1,
101}; 63};
102 64
103static struct clk *clk_epllref_sources[] = {
104 [0] = &clk_mpllref,
105 [1] = &clk_mpllref,
106 [2] = &clk_xtal,
107 [3] = &clk_ext,
108};
109
110static struct clksrc_clk clk_epllref = {
111 .clk = {
112 .name = "epllref",
113 .id = -1,
114 },
115 .sources = &(struct clksrc_sources) {
116 .sources = clk_epllref_sources,
117 .nr_sources = ARRAY_SIZE(clk_epllref_sources),
118 },
119 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
120};
121
122static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
123{
124 unsigned long parent_rate = clk_get_rate(clk->parent);
125 unsigned long div = __raw_readl(S3C2443_CLKDIV0);
126
127 div &= S3C2443_CLKDIV0_EXTDIV_MASK;
128 div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
129
130 return parent_rate / (div + 1);
131}
132
133static struct clk clk_mdivclk = {
134 .name = "mdivclk",
135 .parent = &clk_mpllref,
136 .id = -1,
137 .ops = &(struct clk_ops) {
138 .get_rate = s3c2443_getrate_mdivclk,
139 },
140};
141
142static struct clk *clk_msysclk_sources[] = {
143 [0] = &clk_mpllref,
144 [1] = &clk_mpll,
145 [2] = &clk_mdivclk,
146 [3] = &clk_mpllref,
147};
148
149static struct clksrc_clk clk_msysclk = {
150 .clk = {
151 .name = "msysclk",
152 .parent = &clk_xtal,
153 .id = -1,
154 },
155 .sources = &(struct clksrc_sources) {
156 .sources = clk_msysclk_sources,
157 .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
158 },
159 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
160};
161
162/* armdiv 65/* armdiv
163 * 66 *
164 * this clock is sourced from msysclk and can have a number of 67 * this clock is sourced from msysclk and can have a number of
@@ -266,44 +169,6 @@ static struct clksrc_clk clk_arm = {
266 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 }, 169 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
267}; 170};
268 171
269/* esysclk
270 *
271 * this is sourced from either the EPLL or the EPLLref clock
272*/
273
274static struct clk *clk_sysclk_sources[] = {
275 [0] = &clk_epllref.clk,
276 [1] = &clk_epll,
277};
278
279static struct clksrc_clk clk_esysclk = {
280 .clk = {
281 .name = "esysclk",
282 .parent = &clk_epll,
283 .id = -1,
284 },
285 .sources = &(struct clksrc_sources) {
286 .sources = clk_sysclk_sources,
287 .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
288 },
289 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
290};
291
292/* uartclk
293 *
294 * UART baud-rate clock sourced from esysclk via a divisor
295*/
296
297static struct clksrc_clk clk_uart = {
298 .clk = {
299 .name = "uartclk",
300 .id = -1,
301 .parent = &clk_esysclk.clk,
302 },
303 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
304};
305
306
307/* hsspi 172/* hsspi
308 * 173 *
309 * high-speed spi clock, sourced from esysclk 174 * high-speed spi clock, sourced from esysclk
@@ -320,21 +185,6 @@ static struct clksrc_clk clk_hsspi = {
320 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 }, 185 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
321}; 186};
322 187
323/* usbhost
324 *
325 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
326*/
327
328static struct clksrc_clk clk_usb_bus_host = {
329 .clk = {
330 .name = "usb-bus-host-parent",
331 .id = -1,
332 .parent = &clk_esysclk.clk,
333 .ctrlbit = S3C2443_SCLKCON_USBHOST,
334 .enable = s3c2443_clkcon_enable_s,
335 },
336 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
337};
338 188
339/* clk_hsmcc_div 189/* clk_hsmcc_div
340 * 190 *
@@ -433,89 +283,16 @@ static struct clksrc_clk clk_i2s = {
433 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 }, 283 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
434}; 284};
435 285
436/* cam-if
437 *
438 * camera interface bus-clock, divided down from esysclk
439*/
440
441static struct clksrc_clk clk_cam = {
442 .clk = {
443 .name = "camif-upll", /* same as 2440 name */
444 .id = -1,
445 .parent = &clk_esysclk.clk,
446 .ctrlbit = S3C2443_SCLKCON_CAMCLK,
447 .enable = s3c2443_clkcon_enable_s,
448 },
449 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
450};
451
452/* display-if
453 *
454 * display interface clock, divided from esysclk
455*/
456
457static struct clksrc_clk clk_display = {
458 .clk = {
459 .name = "display-if",
460 .id = -1,
461 .parent = &clk_esysclk.clk,
462 .ctrlbit = S3C2443_SCLKCON_DISPCLK,
463 .enable = s3c2443_clkcon_enable_s,
464 },
465 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
466};
467
468/* prediv
469 *
470 * this divides the msysclk down to pass to h/p/etc.
471 */
472
473static unsigned long s3c2443_prediv_getrate(struct clk *clk)
474{
475 unsigned long rate = clk_get_rate(clk->parent);
476 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
477
478 clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
479 clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
480
481 return rate / (clkdiv0 + 1);
482}
483
484static struct clk clk_prediv = {
485 .name = "prediv",
486 .id = -1,
487 .parent = &clk_msysclk.clk,
488 .ops = &(struct clk_ops) {
489 .get_rate = s3c2443_prediv_getrate,
490 },
491};
492
493/* standard clock definitions */ 286/* standard clock definitions */
494 287
495static struct clk init_clocks_disable[] = { 288static struct clk init_clocks_off[] = {
496 { 289 {
497 .name = "nand",
498 .id = -1,
499 .parent = &clk_h,
500 }, {
501 .name = "sdi", 290 .name = "sdi",
502 .id = -1, 291 .id = -1,
503 .parent = &clk_p, 292 .parent = &clk_p,
504 .enable = s3c2443_clkcon_enable_p, 293 .enable = s3c2443_clkcon_enable_p,
505 .ctrlbit = S3C2443_PCLKCON_SDI, 294 .ctrlbit = S3C2443_PCLKCON_SDI,
506 }, { 295 }, {
507 .name = "adc",
508 .id = -1,
509 .parent = &clk_p,
510 .enable = s3c2443_clkcon_enable_p,
511 .ctrlbit = S3C2443_PCLKCON_ADC,
512 }, {
513 .name = "i2c",
514 .id = -1,
515 .parent = &clk_p,
516 .enable = s3c2443_clkcon_enable_p,
517 .ctrlbit = S3C2443_PCLKCON_IIC,
518 }, {
519 .name = "iis", 296 .name = "iis",
520 .id = -1, 297 .id = -1,
521 .parent = &clk_p, 298 .parent = &clk_p,
@@ -537,179 +314,12 @@ static struct clk init_clocks_disable[] = {
537}; 314};
538 315
539static struct clk init_clocks[] = { 316static struct clk init_clocks[] = {
540 {
541 .name = "dma",
542 .id = 0,
543 .parent = &clk_h,
544 .enable = s3c2443_clkcon_enable_h,
545 .ctrlbit = S3C2443_HCLKCON_DMA0,
546 }, {
547 .name = "dma",
548 .id = 1,
549 .parent = &clk_h,
550 .enable = s3c2443_clkcon_enable_h,
551 .ctrlbit = S3C2443_HCLKCON_DMA1,
552 }, {
553 .name = "dma",
554 .id = 2,
555 .parent = &clk_h,
556 .enable = s3c2443_clkcon_enable_h,
557 .ctrlbit = S3C2443_HCLKCON_DMA2,
558 }, {
559 .name = "dma",
560 .id = 3,
561 .parent = &clk_h,
562 .enable = s3c2443_clkcon_enable_h,
563 .ctrlbit = S3C2443_HCLKCON_DMA3,
564 }, {
565 .name = "dma",
566 .id = 4,
567 .parent = &clk_h,
568 .enable = s3c2443_clkcon_enable_h,
569 .ctrlbit = S3C2443_HCLKCON_DMA4,
570 }, {
571 .name = "dma",
572 .id = 5,
573 .parent = &clk_h,
574 .enable = s3c2443_clkcon_enable_h,
575 .ctrlbit = S3C2443_HCLKCON_DMA5,
576 }, {
577 .name = "lcd",
578 .id = -1,
579 .parent = &clk_h,
580 .enable = s3c2443_clkcon_enable_h,
581 .ctrlbit = S3C2443_HCLKCON_LCDC,
582 }, {
583 .name = "gpio",
584 .id = -1,
585 .parent = &clk_p,
586 .enable = s3c2443_clkcon_enable_p,
587 .ctrlbit = S3C2443_PCLKCON_GPIO,
588 }, {
589 .name = "usb-host",
590 .id = -1,
591 .parent = &clk_h,
592 .enable = s3c2443_clkcon_enable_h,
593 .ctrlbit = S3C2443_HCLKCON_USBH,
594 }, {
595 .name = "usb-device",
596 .id = -1,
597 .parent = &clk_h,
598 .enable = s3c2443_clkcon_enable_h,
599 .ctrlbit = S3C2443_HCLKCON_USBD,
600 }, {
601 .name = "hsmmc",
602 .id = -1,
603 .parent = &clk_h,
604 .enable = s3c2443_clkcon_enable_h,
605 .ctrlbit = S3C2443_HCLKCON_HSMMC,
606 }, {
607 .name = "cfc",
608 .id = -1,
609 .parent = &clk_h,
610 .enable = s3c2443_clkcon_enable_h,
611 .ctrlbit = S3C2443_HCLKCON_CFC,
612 }, {
613 .name = "ssmc",
614 .id = -1,
615 .parent = &clk_h,
616 .enable = s3c2443_clkcon_enable_h,
617 .ctrlbit = S3C2443_HCLKCON_SSMC,
618 }, {
619 .name = "timers",
620 .id = -1,
621 .parent = &clk_p,
622 .enable = s3c2443_clkcon_enable_p,
623 .ctrlbit = S3C2443_PCLKCON_PWMT,
624 }, {
625 .name = "uart",
626 .id = 0,
627 .parent = &clk_p,
628 .enable = s3c2443_clkcon_enable_p,
629 .ctrlbit = S3C2443_PCLKCON_UART0,
630 }, {
631 .name = "uart",
632 .id = 1,
633 .parent = &clk_p,
634 .enable = s3c2443_clkcon_enable_p,
635 .ctrlbit = S3C2443_PCLKCON_UART1,
636 }, {
637 .name = "uart",
638 .id = 2,
639 .parent = &clk_p,
640 .enable = s3c2443_clkcon_enable_p,
641 .ctrlbit = S3C2443_PCLKCON_UART2,
642 }, {
643 .name = "uart",
644 .id = 3,
645 .parent = &clk_p,
646 .enable = s3c2443_clkcon_enable_p,
647 .ctrlbit = S3C2443_PCLKCON_UART3,
648 }, {
649 .name = "rtc",
650 .id = -1,
651 .parent = &clk_p,
652 .enable = s3c2443_clkcon_enable_p,
653 .ctrlbit = S3C2443_PCLKCON_RTC,
654 }, {
655 .name = "watchdog",
656 .id = -1,
657 .parent = &clk_p,
658 .ctrlbit = S3C2443_PCLKCON_WDT,
659 }, {
660 .name = "usb-bus-host",
661 .id = -1,
662 .parent = &clk_usb_bus_host.clk,
663 }, {
664 .name = "ac97",
665 .id = -1,
666 .parent = &clk_p,
667 .ctrlbit = S3C2443_PCLKCON_AC97,
668 }
669};
670
671/* clocks to add where we need to check their parentage */
672
673static struct clksrc_clk __initdata *init_list[] = {
674 &clk_epllref, /* should be first */
675 &clk_esysclk,
676 &clk_msysclk,
677 &clk_arm,
678 &clk_i2s_eplldiv,
679 &clk_i2s,
680 &clk_cam,
681 &clk_uart,
682 &clk_display,
683 &clk_hsmmc_div,
684 &clk_usb_bus_host,
685}; 317};
686 318
687static void __init s3c2443_clk_initparents(void)
688{
689 int ptr;
690
691 for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++)
692 s3c_set_clksrc(init_list[ptr], true);
693}
694
695static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
696{
697 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
698
699 return clkcon0 + 1;
700}
701
702/* clocks to add straight away */ 319/* clocks to add straight away */
703 320
704static struct clksrc_clk *clksrcs[] __initdata = { 321static struct clksrc_clk *clksrcs[] __initdata = {
705 &clk_usb_bus_host,
706 &clk_epllref,
707 &clk_esysclk,
708 &clk_msysclk,
709 &clk_arm, 322 &clk_arm,
710 &clk_uart,
711 &clk_display,
712 &clk_cam,
713 &clk_i2s_eplldiv, 323 &clk_i2s_eplldiv,
714 &clk_i2s, 324 &clk_i2s,
715 &clk_hsspi, 325 &clk_hsspi,
@@ -717,92 +327,32 @@ static struct clksrc_clk *clksrcs[] __initdata = {
717}; 327};
718 328
719static struct clk *clks[] __initdata = { 329static struct clk *clks[] __initdata = {
720 &clk_ext,
721 &clk_epll,
722 &clk_usb_bus,
723 &clk_mpllref,
724 &clk_hsmmc, 330 &clk_hsmmc,
725 &clk_armdiv, 331 &clk_armdiv,
726 &clk_prediv,
727}; 332};
728 333
729void __init_or_cpufreq s3c2443_setup_clocks(void) 334void __init_or_cpufreq s3c2443_setup_clocks(void)
730{ 335{
731 unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); 336 s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div);
732 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
733 struct clk *xtal_clk;
734 unsigned long xtal;
735 unsigned long pll;
736 unsigned long fclk;
737 unsigned long hclk;
738 unsigned long pclk;
739
740 xtal_clk = clk_get(NULL, "xtal");
741 xtal = clk_get_rate(xtal_clk);
742 clk_put(xtal_clk);
743
744 pll = s3c2443_get_mpll(mpllcon, xtal);
745 clk_msysclk.clk.rate = pll;
746
747 fclk = pll / s3c2443_fclk_div(clkdiv0);
748 hclk = s3c2443_prediv_getrate(&clk_prediv);
749 hclk /= s3c2443_get_hdiv(clkdiv0);
750 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
751
752 s3c24xx_setup_clocks(fclk, hclk, pclk);
753
754 printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
755 (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
756 print_mhz(pll), print_mhz(fclk),
757 print_mhz(hclk), print_mhz(pclk));
758
759 s3c24xx_setup_clocks(fclk, hclk, pclk);
760} 337}
761 338
762void __init s3c2443_init_clocks(int xtal) 339void __init s3c2443_init_clocks(int xtal)
763{ 340{
764 struct clk *clkp;
765 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); 341 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
766 int ret;
767 int ptr; 342 int ptr;
768 343
769 /* s3c2443 parents h and p clocks from prediv */ 344 clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
770 clk_h.parent = &clk_prediv; 345 clk_epll.parent = &clk_epllref.clk;
771 clk_p.parent = &clk_prediv; 346
347 s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div);
772 348
773 s3c24xx_register_baseclocks(xtal);
774 s3c2443_setup_clocks(); 349 s3c2443_setup_clocks();
775 s3c2443_clk_initparents();
776
777 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
778 clkp = clks[ptr];
779 350
780 ret = s3c24xx_register_clock(clkp); 351 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
781 if (ret < 0) {
782 printk(KERN_ERR "Failed to register clock %s (%d)\n",
783 clkp->name, ret);
784 }
785 }
786 352
787 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 353 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
788 s3c_register_clksrc(clksrcs[ptr], 1); 354 s3c_register_clksrc(clksrcs[ptr], 1);
789 355
790 clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
791 clk_epll.parent = &clk_epllref.clk;
792 clk_usb_bus.parent = &clk_usb_bus_host.clk;
793
794 /* ensure usb bus clock is within correct rate of 48MHz */
795
796 if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
797 printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
798 clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
799 }
800
801 printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
802 (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
803 print_mhz(clk_get_rate(&clk_epll)),
804 print_mhz(clk_get_rate(&clk_usb_bus)));
805
806 /* register clocks from clock array */ 356 /* register clocks from clock array */
807 357
808 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 358 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
@@ -819,17 +369,8 @@ void __init s3c2443_init_clocks(int xtal)
819 369
820 /* install (and disable) the clocks we do not need immediately */ 370 /* install (and disable) the clocks we do not need immediately */
821 371
822 clkp = init_clocks_disable; 372 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
823 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 373 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
824
825 ret = s3c24xx_register_clock(clkp);
826 if (ret < 0) {
827 printk(KERN_ERR "Failed to register clock %s (%d)\n",
828 clkp->name, ret);
829 }
830
831 (clkp->enable)(clkp, 0);
832 }
833 374
834 s3c_pwmclk_init(); 375 s3c_pwmclk_init();
835} 376}
diff --git a/arch/arm/mach-s3c64xx/include/mach/pll.h b/arch/arm/mach-s3c64xx/include/mach/pll.h
index 90bbd72fdc4..5ef0bb698ee 100644
--- a/arch/arm/mach-s3c64xx/include/mach/pll.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pll.h
@@ -20,6 +20,7 @@
20#define S3C6400_PLL_SDIV_SHIFT (0) 20#define S3C6400_PLL_SDIV_SHIFT (0)
21 21
22#include <asm/div64.h> 22#include <asm/div64.h>
23#include <plat/pll6553x.h>
23 24
24static inline unsigned long s3c6400_get_pll(unsigned long baseclk, 25static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
25 u32 pllcon) 26 u32 pllcon)
@@ -37,38 +38,8 @@ static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
37 return (unsigned long)fvco; 38 return (unsigned long)fvco;
38} 39}
39 40
40#define S3C6400_EPLL_MDIV_MASK ((1 << (23-16)) - 1)
41#define S3C6400_EPLL_PDIV_MASK ((1 << (13-8)) - 1)
42#define S3C6400_EPLL_SDIV_MASK ((1 << (2-0)) - 1)
43#define S3C6400_EPLL_MDIV_SHIFT (16)
44#define S3C6400_EPLL_PDIV_SHIFT (8)
45#define S3C6400_EPLL_SDIV_SHIFT (0)
46#define S3C6400_EPLL_KDIV_MASK (0xffff)
47
48static inline unsigned long s3c6400_get_epll(unsigned long baseclk) 41static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
49{ 42{
50 unsigned long result; 43 return s3c_get_pll6553x(baseclk, __raw_readl(S3C_EPLL_CON0),
51 u32 epll0 = __raw_readl(S3C_EPLL_CON0); 44 __raw_readl(S3C_EPLL_CON1));
52 u32 epll1 = __raw_readl(S3C_EPLL_CON1);
53 u32 mdiv, pdiv, sdiv, kdiv;
54 u64 tmp;
55
56 mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK;
57 pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK;
58 sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK;
59 kdiv = epll1 & S3C6400_EPLL_KDIV_MASK;
60
61 /* We need to multiple baseclk by mdiv (the integer part) and kdiv
62 * which is in 2^16ths, so shift mdiv up (does not overflow) and
63 * add kdiv before multiplying. The use of tmp is to avoid any
64 * overflows before shifting bac down into result when multipling
65 * by the mdiv and kdiv pair.
66 */
67
68 tmp = baseclk;
69 tmp *= (mdiv << 16) + kdiv;
70 do_div(tmp, (pdiv << sdiv));
71 result = tmp >> 16;
72
73 return result;
74} 45}
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index a830fad6f89..3ce8f010b3c 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -45,6 +45,12 @@ config S3C2410_CLOCK
45 Clock code for the S3C2410, and similar processors which 45 Clock code for the S3C2410, and similar processors which
46 is currently includes the S3C2410, S3C2440, S3C2442. 46 is currently includes the S3C2410, S3C2440, S3C2442.
47 47
48config S3C2443_CLOCK
49 bool
50 help
51 Clock code for the S3C2443 and similar processors, which includes
52 the S3C2416 and S3C2450.
53
48config S3C24XX_DCLK 54config S3C24XX_DCLK
49 bool 55 bool
50 help 56 help
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index c2237c41141..44aea8868f8 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PM) += pm.o
30obj-$(CONFIG_PM) += irq-pm.o 30obj-$(CONFIG_PM) += irq-pm.o
31obj-$(CONFIG_PM) += sleep.o 31obj-$(CONFIG_PM) += sleep.o
32obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o 32obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
33obj-$(CONFIG_S3C2443_CLOCK) += s3c2443-clock.o
33obj-$(CONFIG_S3C2410_DMA) += dma.o 34obj-$(CONFIG_S3C2410_DMA) += dma.o
34obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o 35obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o
35obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o 36obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 9ca64df35bf..76d0858c3cb 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -49,6 +49,7 @@
49#include <plat/s3c2400.h> 49#include <plat/s3c2400.h>
50#include <plat/s3c2410.h> 50#include <plat/s3c2410.h>
51#include <plat/s3c2412.h> 51#include <plat/s3c2412.h>
52#include <plat/s3c2416.h>
52#include <plat/s3c244x.h> 53#include <plat/s3c244x.h>
53#include <plat/s3c2443.h> 54#include <plat/s3c2443.h>
54 55
@@ -57,6 +58,7 @@
57static const char name_s3c2400[] = "S3C2400"; 58static const char name_s3c2400[] = "S3C2400";
58static const char name_s3c2410[] = "S3C2410"; 59static const char name_s3c2410[] = "S3C2410";
59static const char name_s3c2412[] = "S3C2412"; 60static const char name_s3c2412[] = "S3C2412";
61static const char name_s3c2416[] = "S3C2416/S3C2450";
60static const char name_s3c2440[] = "S3C2440"; 62static const char name_s3c2440[] = "S3C2440";
61static const char name_s3c2442[] = "S3C2442"; 63static const char name_s3c2442[] = "S3C2442";
62static const char name_s3c2442b[] = "S3C2442B"; 64static const char name_s3c2442b[] = "S3C2442B";
@@ -137,6 +139,15 @@ static struct cpu_table cpu_ids[] __initdata = {
137 .init = s3c2412_init, 139 .init = s3c2412_init,
138 .name = name_s3c2412, 140 .name = name_s3c2412,
139 }, 141 },
142 { /* a strange version of the s3c2416 */
143 .idcode = 0x32450003,
144 .idmask = 0xffffffff,
145 .map_io = s3c2416_map_io,
146 .init_clocks = s3c2416_init_clocks,
147 .init_uarts = s3c2416_init_uarts,
148 .init = s3c2416_init,
149 .name = name_s3c2416,
150 },
140 { 151 {
141 .idcode = 0x32443001, 152 .idcode = 0x32443001,
142 .idmask = 0xffffffff, 153 .idmask = 0xffffffff,
@@ -170,6 +181,16 @@ static struct map_desc s3c_iodesc[] __initdata = {
170 181
171static unsigned long s3c24xx_read_idcode_v5(void) 182static unsigned long s3c24xx_read_idcode_v5(void)
172{ 183{
184#if defined(CONFIG_CPU_S3C2416)
185 /* s3c2416 is v5, with S3C24XX_GSTATUS1 instead of S3C2412_GSTATUS1 */
186
187 u32 gs = __raw_readl(S3C24XX_GSTATUS1);
188
189 /* test for s3c2416 or similar device */
190 if ((gs >> 16) == 0x3245)
191 return gs;
192#endif
193
173#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) 194#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
174 return __raw_readl(S3C2412_GSTATUS1); 195 return __raw_readl(S3C2412_GSTATUS1);
175#else 196#else
diff --git a/arch/arm/plat-s3c24xx/include/plat/pll.h b/arch/arm/plat-s3c24xx/include/plat/pll.h
index 7ea8bffa7a9..005729a1077 100644
--- a/arch/arm/plat-s3c24xx/include/plat/pll.h
+++ b/arch/arm/plat-s3c24xx/include/plat/pll.h
@@ -35,3 +35,28 @@ s3c24xx_get_pll(unsigned int pllval, unsigned int baseclk)
35 35
36 return (unsigned int)fvco; 36 return (unsigned int)fvco;
37} 37}
38
39#define S3C2416_PLL_M_SHIFT (14)
40#define S3C2416_PLL_P_SHIFT (5)
41#define S3C2416_PLL_S_MASK (7)
42#define S3C2416_PLL_M_MASK ((1 << 10) - 1)
43#define S3C2416_PLL_P_MASK (63)
44
45static inline unsigned int
46s3c2416_get_pll(unsigned int pllval, unsigned int baseclk)
47{
48 unsigned int m, p, s;
49 uint64_t fvco;
50
51 m = pllval >> S3C2416_PLL_M_SHIFT;
52 p = pllval >> S3C2416_PLL_P_SHIFT;
53
54 s = pllval & S3C2416_PLL_S_MASK;
55 m &= S3C2416_PLL_M_MASK;
56 p &= S3C2416_PLL_P_MASK;
57
58 fvco = (uint64_t)baseclk * m;
59 do_div(fvco, (p << s));
60
61 return (unsigned int)fvco;
62}
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
new file mode 100644
index 00000000000..dc3c0907d22
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
@@ -0,0 +1,31 @@
1/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
4 *
5 * Header file for s3c2416 cpu support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#ifdef CONFIG_CPU_S3C2416
13
14struct s3c2410_uartcfg;
15
16extern int s3c2416_init(void);
17
18extern void s3c2416_map_io(void);
19
20extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
21
22extern void s3c2416_init_clocks(int xtal);
23
24extern int s3c2416_baseclk_add(void);
25
26#else
27#define s3c2416_init_clocks NULL
28#define s3c2416_init_uarts NULL
29#define s3c2416_map_io NULL
30#define s3c2416_init NULL
31#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
index 815b107ed89..a19715feb79 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
@@ -30,3 +30,22 @@ extern int s3c2443_baseclk_add(void);
30#define s3c2443_map_io NULL 30#define s3c2443_map_io NULL
31#define s3c2443_init NULL 31#define s3c2443_init NULL
32#endif 32#endif
33
34/* common code used by s3c2443 and others.
35 * note, not to be used outside of arch/arm/mach-s3c* */
36
37struct clk; /* some files don't need clk.h otherwise */
38
39typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
40typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
41
42extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv);
43extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv);
44
45extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
46extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
47extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
48
49extern struct clksrc_clk clk_epllref;
50extern struct clksrc_clk clk_esysclk;
51extern struct clksrc_clk clk_msysclk;
diff --git a/arch/arm/plat-s3c24xx/s3c2410-clock.c b/arch/arm/plat-s3c24xx/s3c2410-clock.c
index b61bdb79373..9ecc5d91367 100644
--- a/arch/arm/plat-s3c24xx/s3c2410-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2410-clock.c
@@ -87,7 +87,7 @@ static int s3c2410_upll_enable(struct clk *clk, int enable)
87 87
88/* standard clock definitions */ 88/* standard clock definitions */
89 89
90static struct clk init_clocks_disable[] = { 90static struct clk init_clocks_off[] = {
91 { 91 {
92 .name = "nand", 92 .name = "nand",
93 .id = -1, 93 .id = -1,
@@ -249,17 +249,8 @@ int __init s3c2410_baseclk_add(void)
249 249
250 /* install (and disable) the clocks we do not need immediately */ 250 /* install (and disable) the clocks we do not need immediately */
251 251
252 clkp = init_clocks_disable; 252 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
253 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 253 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
254
255 ret = s3c24xx_register_clock(clkp);
256 if (ret < 0) {
257 printk(KERN_ERR "Failed to register clock %s (%d)\n",
258 clkp->name, ret);
259 }
260
261 s3c2410_clkcon_enable(clkp, 0);
262 }
263 254
264 /* show the clock-slow value */ 255 /* show the clock-slow value */
265 256
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
new file mode 100644
index 00000000000..461f070eb62
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -0,0 +1,472 @@
1/* linux/arch/arm/plat-s3c24xx/s3c2443-clock.c
2 *
3 * Copyright (c) 2007, 2010 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2443 Clock control suport - common code
7 */
8
9#include <linux/init.h>
10#include <linux/clk.h>
11#include <linux/io.h>
12
13#include <mach/regs-s3c2443-clock.h>
14
15#include <plat/s3c2443.h>
16#include <plat/clock.h>
17#include <plat/clock-clksrc.h>
18#include <plat/cpu.h>
19
20#include <plat/cpu-freq.h>
21
22
23static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
24{
25 u32 ctrlbit = clk->ctrlbit;
26 u32 con = __raw_readl(reg);
27
28 if (enable)
29 con |= ctrlbit;
30 else
31 con &= ~ctrlbit;
32
33 __raw_writel(con, reg);
34 return 0;
35}
36
37int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
38{
39 return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
40}
41
42int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
43{
44 return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
45}
46
47int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
48{
49 return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
50}
51
52/* mpllref is a direct descendant of clk_xtal by default, but it is not
53 * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
54 * such directly equating the two source clocks is impossible.
55 */
56struct clk clk_mpllref = {
57 .name = "mpllref",
58 .parent = &clk_xtal,
59 .id = -1,
60};
61
62static struct clk *clk_epllref_sources[] = {
63 [0] = &clk_mpllref,
64 [1] = &clk_mpllref,
65 [2] = &clk_xtal,
66 [3] = &clk_ext,
67};
68
69struct clksrc_clk clk_epllref = {
70 .clk = {
71 .name = "epllref",
72 .id = -1,
73 },
74 .sources = &(struct clksrc_sources) {
75 .sources = clk_epllref_sources,
76 .nr_sources = ARRAY_SIZE(clk_epllref_sources),
77 },
78 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
79};
80
81/* esysclk
82 *
83 * this is sourced from either the EPLL or the EPLLref clock
84*/
85
86static struct clk *clk_sysclk_sources[] = {
87 [0] = &clk_epllref.clk,
88 [1] = &clk_epll,
89};
90
91struct clksrc_clk clk_esysclk = {
92 .clk = {
93 .name = "esysclk",
94 .parent = &clk_epll,
95 .id = -1,
96 },
97 .sources = &(struct clksrc_sources) {
98 .sources = clk_sysclk_sources,
99 .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
100 },
101 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
102};
103
104static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
105{
106 unsigned long parent_rate = clk_get_rate(clk->parent);
107 unsigned long div = __raw_readl(S3C2443_CLKDIV0);
108
109 div &= S3C2443_CLKDIV0_EXTDIV_MASK;
110 div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
111
112 return parent_rate / (div + 1);
113}
114
115static struct clk clk_mdivclk = {
116 .name = "mdivclk",
117 .parent = &clk_mpllref,
118 .id = -1,
119 .ops = &(struct clk_ops) {
120 .get_rate = s3c2443_getrate_mdivclk,
121 },
122};
123
124static struct clk *clk_msysclk_sources[] = {
125 [0] = &clk_mpllref,
126 [1] = &clk_mpll,
127 [2] = &clk_mdivclk,
128 [3] = &clk_mpllref,
129};
130
131struct clksrc_clk clk_msysclk = {
132 .clk = {
133 .name = "msysclk",
134 .parent = &clk_xtal,
135 .id = -1,
136 },
137 .sources = &(struct clksrc_sources) {
138 .sources = clk_msysclk_sources,
139 .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
140 },
141 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
142};
143
144/* prediv
145 *
146 * this divides the msysclk down to pass to h/p/etc.
147 */
148
149static unsigned long s3c2443_prediv_getrate(struct clk *clk)
150{
151 unsigned long rate = clk_get_rate(clk->parent);
152 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
153
154 clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
155 clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
156
157 return rate / (clkdiv0 + 1);
158}
159
160static struct clk clk_prediv = {
161 .name = "prediv",
162 .id = -1,
163 .parent = &clk_msysclk.clk,
164 .ops = &(struct clk_ops) {
165 .get_rate = s3c2443_prediv_getrate,
166 },
167};
168
169/* usbhost
170 *
171 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
172*/
173
174static struct clksrc_clk clk_usb_bus_host = {
175 .clk = {
176 .name = "usb-bus-host-parent",
177 .id = -1,
178 .parent = &clk_esysclk.clk,
179 .ctrlbit = S3C2443_SCLKCON_USBHOST,
180 .enable = s3c2443_clkcon_enable_s,
181 },
182 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
183};
184
185/* common clksrc clocks */
186
187static struct clksrc_clk clksrc_clks[] = {
188 {
189 /* ART baud-rate clock sourced from esysclk via a divisor */
190 .clk = {
191 .name = "uartclk",
192 .id = -1,
193 .parent = &clk_esysclk.clk,
194 },
195 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
196 }, {
197 /* camera interface bus-clock, divided down from esysclk */
198 .clk = {
199 .name = "camif-upll", /* same as 2440 name */
200 .id = -1,
201 .parent = &clk_esysclk.clk,
202 .ctrlbit = S3C2443_SCLKCON_CAMCLK,
203 .enable = s3c2443_clkcon_enable_s,
204 },
205 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
206 }, {
207 .clk = {
208 .name = "display-if",
209 .id = -1,
210 .parent = &clk_esysclk.clk,
211 .ctrlbit = S3C2443_SCLKCON_DISPCLK,
212 .enable = s3c2443_clkcon_enable_s,
213 },
214 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
215 },
216};
217
218
219static struct clk init_clocks_off[] = {
220 {
221 .name = "adc",
222 .id = -1,
223 .parent = &clk_p,
224 .enable = s3c2443_clkcon_enable_p,
225 .ctrlbit = S3C2443_PCLKCON_ADC,
226 }, {
227 .name = "i2c",
228 .id = -1,
229 .parent = &clk_p,
230 .enable = s3c2443_clkcon_enable_p,
231 .ctrlbit = S3C2443_PCLKCON_IIC,
232 }
233};
234
235static struct clk init_clocks[] = {
236 {
237 .name = "dma",
238 .id = 0,
239 .parent = &clk_h,
240 .enable = s3c2443_clkcon_enable_h,
241 .ctrlbit = S3C2443_HCLKCON_DMA0,
242 }, {
243 .name = "dma",
244 .id = 1,
245 .parent = &clk_h,
246 .enable = s3c2443_clkcon_enable_h,
247 .ctrlbit = S3C2443_HCLKCON_DMA1,
248 }, {
249 .name = "dma",
250 .id = 2,
251 .parent = &clk_h,
252 .enable = s3c2443_clkcon_enable_h,
253 .ctrlbit = S3C2443_HCLKCON_DMA2,
254 }, {
255 .name = "dma",
256 .id = 3,
257 .parent = &clk_h,
258 .enable = s3c2443_clkcon_enable_h,
259 .ctrlbit = S3C2443_HCLKCON_DMA3,
260 }, {
261 .name = "dma",
262 .id = 4,
263 .parent = &clk_h,
264 .enable = s3c2443_clkcon_enable_h,
265 .ctrlbit = S3C2443_HCLKCON_DMA4,
266 }, {
267 .name = "dma",
268 .id = 5,
269 .parent = &clk_h,
270 .enable = s3c2443_clkcon_enable_h,
271 .ctrlbit = S3C2443_HCLKCON_DMA5,
272 }, {
273 .name = "hsmmc",
274 .id = 0,
275 .parent = &clk_h,
276 .enable = s3c2443_clkcon_enable_h,
277 .ctrlbit = S3C2443_HCLKCON_HSMMC,
278 }, {
279 .name = "gpio",
280 .id = -1,
281 .parent = &clk_p,
282 .enable = s3c2443_clkcon_enable_p,
283 .ctrlbit = S3C2443_PCLKCON_GPIO,
284 }, {
285 .name = "usb-host",
286 .id = -1,
287 .parent = &clk_h,
288 .enable = s3c2443_clkcon_enable_h,
289 .ctrlbit = S3C2443_HCLKCON_USBH,
290 }, {
291 .name = "usb-device",
292 .id = -1,
293 .parent = &clk_h,
294 .enable = s3c2443_clkcon_enable_h,
295 .ctrlbit = S3C2443_HCLKCON_USBD,
296 }, {
297 .name = "lcd",
298 .id = -1,
299 .parent = &clk_h,
300 .enable = s3c2443_clkcon_enable_h,
301 .ctrlbit = S3C2443_HCLKCON_LCDC,
302
303 }, {
304 .name = "timers",
305 .id = -1,
306 .parent = &clk_p,
307 .enable = s3c2443_clkcon_enable_p,
308 .ctrlbit = S3C2443_PCLKCON_PWMT,
309 }, {
310 .name = "cfc",
311 .id = -1,
312 .parent = &clk_h,
313 .enable = s3c2443_clkcon_enable_h,
314 .ctrlbit = S3C2443_HCLKCON_CFC,
315 }, {
316 .name = "ssmc",
317 .id = -1,
318 .parent = &clk_h,
319 .enable = s3c2443_clkcon_enable_h,
320 .ctrlbit = S3C2443_HCLKCON_SSMC,
321 }, {
322 .name = "uart",
323 .id = 0,
324 .parent = &clk_p,
325 .enable = s3c2443_clkcon_enable_p,
326 .ctrlbit = S3C2443_PCLKCON_UART0,
327 }, {
328 .name = "uart",
329 .id = 1,
330 .parent = &clk_p,
331 .enable = s3c2443_clkcon_enable_p,
332 .ctrlbit = S3C2443_PCLKCON_UART1,
333 }, {
334 .name = "uart",
335 .id = 2,
336 .parent = &clk_p,
337 .enable = s3c2443_clkcon_enable_p,
338 .ctrlbit = S3C2443_PCLKCON_UART2,
339 }, {
340 .name = "uart",
341 .id = 3,
342 .parent = &clk_p,
343 .enable = s3c2443_clkcon_enable_p,
344 .ctrlbit = S3C2443_PCLKCON_UART3,
345 }, {
346 .name = "rtc",
347 .id = -1,
348 .parent = &clk_p,
349 .enable = s3c2443_clkcon_enable_p,
350 .ctrlbit = S3C2443_PCLKCON_RTC,
351 }, {
352 .name = "watchdog",
353 .id = -1,
354 .parent = &clk_p,
355 .ctrlbit = S3C2443_PCLKCON_WDT,
356 }, {
357 .name = "ac97",
358 .id = -1,
359 .parent = &clk_p,
360 .ctrlbit = S3C2443_PCLKCON_AC97,
361 }, {
362 .name = "nand",
363 .id = -1,
364 .parent = &clk_h,
365 }, {
366 .name = "usb-bus-host",
367 .id = -1,
368 .parent = &clk_usb_bus_host.clk,
369 }
370};
371
372static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
373{
374 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
375
376 return clkcon0 + 1;
377}
378
379/* EPLLCON compatible enough to get on/off information */
380
381void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
382 fdiv_fn get_fdiv)
383{
384 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
385 unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
386 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
387 struct clk *xtal_clk;
388 unsigned long xtal;
389 unsigned long pll;
390 unsigned long fclk;
391 unsigned long hclk;
392 unsigned long pclk;
393 int ptr;
394
395 xtal_clk = clk_get(NULL, "xtal");
396 xtal = clk_get_rate(xtal_clk);
397 clk_put(xtal_clk);
398
399 pll = get_mpll(mpllcon, xtal);
400 clk_msysclk.clk.rate = pll;
401
402 fclk = pll / get_fdiv(clkdiv0);
403 hclk = s3c2443_prediv_getrate(&clk_prediv);
404 hclk /= s3c2443_get_hdiv(clkdiv0);
405 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
406
407 s3c24xx_setup_clocks(fclk, hclk, pclk);
408
409 printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
410 (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
411 print_mhz(pll), print_mhz(fclk),
412 print_mhz(hclk), print_mhz(pclk));
413
414 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
415 s3c_set_clksrc(&clksrc_clks[ptr], true);
416
417 /* ensure usb bus clock is within correct rate of 48MHz */
418
419 if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
420 printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
421 clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
422 }
423
424 printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
425 (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
426 print_mhz(clk_get_rate(&clk_epll)),
427 print_mhz(clk_get_rate(&clk_usb_bus)));
428}
429
430static struct clk *clks[] __initdata = {
431 &clk_prediv,
432 &clk_mpllref,
433 &clk_mdivclk,
434 &clk_ext,
435 &clk_epll,
436 &clk_usb_bus,
437};
438
439static struct clksrc_clk *clksrcs[] __initdata = {
440 &clk_usb_bus_host,
441 &clk_epllref,
442 &clk_esysclk,
443 &clk_msysclk,
444};
445
446void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
447 fdiv_fn get_fdiv)
448{
449 int ptr;
450
451 /* s3c2443 parents h and p clocks from prediv */
452 clk_h.parent = &clk_prediv;
453 clk_p.parent = &clk_prediv;
454
455 clk_usb_bus.parent = &clk_usb_bus_host.clk;
456 clk_epll.parent = &clk_epllref.clk;
457
458 s3c24xx_register_baseclocks(xtal);
459 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
460
461 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
462 s3c_register_clksrc(clksrcs[ptr], 1);
463
464 s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
465 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
466
467 /* See s3c2443/etc notes on disabling clocks at init time */
468 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
469 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
470
471 s3c2443_common_setup_clocks(get_mpll, get_fdiv);
472}
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 1b25c9d8c40..8bf79f3efdf 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -376,6 +376,21 @@ void __init s3c_register_clocks(struct clk *clkp, int nr_clks)
376 } 376 }
377} 377}
378 378
379/**
380 * s3c_disable_clocks() - disable an array of clocks
381 * @clkp: Pointer to the first clock in the array.
382 * @nr_clks: Number of clocks to register.
383 *
384 * for internal use only at initialisation time. disable the clocks in the
385 * @clkp array.
386 */
387
388void __init s3c_disable_clocks(struct clk *clkp, int nr_clks)
389{
390 for (; nr_clks > 0; nr_clks--, clkp++)
391 (clkp->enable)(clkp, 0);
392}
393
379/* initalise all the clocks */ 394/* initalise all the clocks */
380 395
381int __init s3c24xx_register_baseclocks(unsigned long xtal) 396int __init s3c24xx_register_baseclocks(unsigned long xtal)
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
index 002a15f313f..bf60204c629 100644
--- a/arch/arm/plat-samsung/dev-fb.c
+++ b/arch/arm/plat-samsung/dev-fb.c
@@ -19,7 +19,6 @@
19 19
20#include <mach/irqs.h> 20#include <mach/irqs.h>
21#include <mach/map.h> 21#include <mach/map.h>
22#include <mach/regs-fb.h>
23 22
24#include <plat/fb.h> 23#include <plat/fb.h>
25#include <plat/devs.h> 24#include <plat/devs.h>
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index efbc984640c..0fbcd0effd8 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -92,6 +92,7 @@ extern int s3c24xx_register_clock(struct clk *clk);
92extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks); 92extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
93 93
94extern void s3c_register_clocks(struct clk *clk, int nr_clks); 94extern void s3c_register_clocks(struct clk *clk, int nr_clks);
95extern void s3c_disable_clocks(struct clk *clkp, int nr_clks);
95 96
96extern int s3c24xx_register_baseclocks(unsigned long xtal); 97extern int s3c24xx_register_baseclocks(unsigned long xtal);
97 98
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index c54f318991b..6412933d6fb 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -73,6 +73,7 @@ extern struct sys_timer s3c24xx_timer;
73extern struct sysdev_class s3c2410_sysclass; 73extern struct sysdev_class s3c2410_sysclass;
74extern struct sysdev_class s3c2410a_sysclass; 74extern struct sysdev_class s3c2410a_sysclass;
75extern struct sysdev_class s3c2412_sysclass; 75extern struct sysdev_class s3c2412_sysclass;
76extern struct sysdev_class s3c2416_sysclass;
76extern struct sysdev_class s3c2440_sysclass; 77extern struct sysdev_class s3c2440_sysclass;
77extern struct sysdev_class s3c2442_sysclass; 78extern struct sysdev_class s3c2442_sysclass;
78extern struct sysdev_class s3c2443_sysclass; 79extern struct sysdev_class s3c2443_sysclass;
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index ffc01a76b7c..1f85649d8c1 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -15,6 +15,13 @@
15#ifndef __PLAT_S3C_FB_H 15#ifndef __PLAT_S3C_FB_H
16#define __PLAT_S3C_FB_H __FILE__ 16#define __PLAT_S3C_FB_H __FILE__
17 17
18/* S3C_FB_MAX_WIN
19 * Set to the maximum number of windows that any of the supported hardware
20 * can use. Since the platform data uses this for an array size, having it
21 * set to the maximum of any version of the hardware can do is safe.
22 */
23#define S3C_FB_MAX_WIN (5)
24
18/** 25/**
19 * struct s3c_fb_pd_win - per window setup data 26 * struct s3c_fb_pd_win - per window setup data
20 * @win_mode: The display parameters to initialise (not for window 0) 27 * @win_mode: The display parameters to initialise (not for window 0)
diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h
new file mode 100644
index 00000000000..b8b7e1d884f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pll6553x.h
@@ -0,0 +1,51 @@
1/* arch/arm/plat-samsung/include/plat/pll6553x.h
2 * partially from arch/arm/mach-s3c64xx/include/mach/pll.h
3 *
4 * Copyright 2008 Openmoko, Inc.
5 * Copyright 2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
8 *
9 * Samsung PLL6553x PLL code
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16/* S3C6400 and compatible (S3C2416, etc.) EPLL code */
17
18#define PLL6553X_MDIV_MASK ((1 << (23-16)) - 1)
19#define PLL6553X_PDIV_MASK ((1 << (13-8)) - 1)
20#define PLL6553X_SDIV_MASK ((1 << (2-0)) - 1)
21#define PLL6553X_MDIV_SHIFT (16)
22#define PLL6553X_PDIV_SHIFT (8)
23#define PLL6553X_SDIV_SHIFT (0)
24#define PLL6553X_KDIV_MASK (0xffff)
25
26static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
27 u32 pll0, u32 pll1)
28{
29 unsigned long result;
30 u32 mdiv, pdiv, sdiv, kdiv;
31 u64 tmp;
32
33 mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
34 pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
35 sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
36 kdiv = pll1 & PLL6553X_KDIV_MASK;
37
38 /* We need to multiple baseclk by mdiv (the integer part) and kdiv
39 * which is in 2^16ths, so shift mdiv up (does not overflow) and
40 * add kdiv before multiplying. The use of tmp is to avoid any
41 * overflows before shifting bac down into result when multipling
42 * by the mdiv and kdiv pair.
43 */
44
45 tmp = baseclk;
46 tmp *= (mdiv << 16) + kdiv;
47 do_div(tmp, (pdiv << sdiv));
48 result = tmp >> 16;
49
50 return result;
51}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index f55c49475a8..5f3f03df92e 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -518,12 +518,13 @@ config SERIAL_S3C2412
518 Serial port support for the Samsung S3C2412 and S3C2413 SoC 518 Serial port support for the Samsung S3C2412 and S3C2413 SoC
519 519
520config SERIAL_S3C2440 520config SERIAL_S3C2440
521 tristate "Samsung S3C2440/S3C2442 Serial port support" 521 tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support"
522 depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442) 522 depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416)
523 default y if CPU_S3C2440 523 default y if CPU_S3C2440
524 default y if CPU_S3C2442 524 default y if CPU_S3C2442
525 select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416
525 help 526 help
526 Serial port support for the Samsung S3C2440 and S3C2442 SoC 527 Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC
527 528
528config SERIAL_S3C24A0 529config SERIAL_S3C24A0
529 tristate "Samsung S3C24A0 Serial port support" 530 tristate "Samsung S3C24A0 Serial port support"