aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2006-06-24 16:21:27 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-06-24 16:21:27 -0400
commit68d9ab394f06f95fd4ca612c08edf13e410fd8d0 (patch)
treead5fc04b5b3c319134db680bebc9a552d88375fc /arch/arm
parenta3ff55026e59687040f00fc35680fc0e774859f4 (diff)
[ARM] 3635/1: S3C24XX: Add S3C2412 core cpu support
Patch from Ben Dooks Add support for the Samsung S3C2412 and S3C2413 range of SoCs. This patch contains the core identification, debug macros, and basic register updates to get these to build. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-s3c2410/Kconfig14
-rw-r--r--arch/arm/mach-s3c2410/Makefile4
-rw-r--r--arch/arm/mach-s3c2410/cpu.c37
-rw-r--r--arch/arm/mach-s3c2410/cpu.h1
-rw-r--r--arch/arm/mach-s3c2410/s3c2412.c195
-rw-r--r--arch/arm/mach-s3c2410/s3c2412.h29
6 files changed, 277 insertions, 3 deletions
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 7b786d725636..b61af3a6a414 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -127,6 +127,20 @@ config CPU_S3C2410
127 Support for S3C2410 and S3C2410A family from the S3C24XX line 127 Support for S3C2410 and S3C2410A family from the S3C24XX line
128 of Samsung Mobile CPUs. 128 of Samsung Mobile CPUs.
129 129
130# internal node to signify if we are only dealing with an S3C2412
131
132config CPU_S3C2412_ONLY
133 bool
134 depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
135 !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
136 default y if CPU_S3C2412
137
138config CPU_S3C2412
139 bool
140 depends on ARCH_S3C2410
141 help
142 Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
143
130config CPU_S3C244X 144config CPU_S3C244X
131 bool 145 bool
132 depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442) 146 depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 372dbcea1434..86219c6df32c 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -24,6 +24,10 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o
24obj-$(CONFIG_PM) += pm.o sleep.o 24obj-$(CONFIG_PM) += pm.o sleep.o
25obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o 25obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
26 26
27# S3C2412 support
28obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
29
30#
27# S3C244X support 31# S3C244X support
28 32
29obj-$(CONFIG_CPU_S3C244X) += s3c244x.o 33obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
index 52842e6e86e6..1c3c6adae6c4 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/mach-s3c2410/cpu.c
@@ -44,6 +44,7 @@
44#include "clock.h" 44#include "clock.h"
45#include "s3c2400.h" 45#include "s3c2400.h"
46#include "s3c2410.h" 46#include "s3c2410.h"
47#include "s3c2412.h"
47#include "s3c244x.h" 48#include "s3c244x.h"
48#include "s3c2440.h" 49#include "s3c2440.h"
49#include "s3c2442.h" 50#include "s3c2442.h"
@@ -62,6 +63,7 @@ struct cpu_table {
62 63
63static const char name_s3c2400[] = "S3C2400"; 64static const char name_s3c2400[] = "S3C2400";
64static const char name_s3c2410[] = "S3C2410"; 65static const char name_s3c2410[] = "S3C2410";
66static const char name_s3c2412[] = "S3C2412";
65static const char name_s3c2440[] = "S3C2440"; 67static const char name_s3c2440[] = "S3C2440";
66static const char name_s3c2442[] = "S3C2442"; 68static const char name_s3c2442[] = "S3C2442";
67static const char name_s3c2410a[] = "S3C2410A"; 69static const char name_s3c2410a[] = "S3C2410A";
@@ -114,6 +116,15 @@ static struct cpu_table cpu_ids[] __initdata = {
114 .name = name_s3c2442 116 .name = name_s3c2442
115 }, 117 },
116 { 118 {
119 .idcode = 0x32412001,
120 .idmask = 0xffffffff,
121 .map_io = s3c2412_map_io,
122 .init_clocks = s3c2412_init_clocks,
123 .init_uarts = s3c2412_init_uarts,
124 .init = s3c2412_init,
125 .name = name_s3c2412,
126 },
127 {
117 .idcode = 0x0, /* S3C2400 doesn't have an idcode */ 128 .idcode = 0x0, /* S3C2400 doesn't have an idcode */
118 .idmask = 0xffffffff, 129 .idmask = 0xffffffff,
119 .map_io = s3c2400_map_io, 130 .map_io = s3c2400_map_io,
@@ -171,6 +182,24 @@ void s3c24xx_set_board(struct s3c24xx_board *b)
171 182
172static struct cpu_table *cpu; 183static struct cpu_table *cpu;
173 184
185static unsigned long s3c24xx_read_idcode_v5(void)
186{
187#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
188 return __raw_readl(S3C2412_GSTATUS1);
189#else
190 return 1UL; /* don't look like an 2400 */
191#endif
192}
193
194static unsigned long s3c24xx_read_idcode_v4(void)
195{
196#ifndef CONFIG_CPU_S3C2400
197 return __raw_readl(S3C2410_GSTATUS1);
198#else
199 return 0UL;
200#endif
201}
202
174void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) 203void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
175{ 204{
176 unsigned long idcode = 0x0; 205 unsigned long idcode = 0x0;
@@ -178,9 +207,11 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
178 /* initialise the io descriptors we need for initialisation */ 207 /* initialise the io descriptors we need for initialisation */
179 iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); 208 iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
180 209
181#ifndef CONFIG_CPU_S3C2400 210 if (cpu_architecture() >= CPU_ARCH_ARMv5) {
182 idcode = __raw_readl(S3C2410_GSTATUS1); 211 idcode = s3c24xx_read_idcode_v5();
183#endif 212 } else {
213 idcode = s3c24xx_read_idcode_v4();
214 }
184 215
185 cpu = s3c_lookup_cpu(idcode); 216 cpu = s3c_lookup_cpu(idcode);
186 217
diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
index 21c62dc29bb2..b0ed9d2d141b 100644
--- a/arch/arm/mach-s3c2410/cpu.h
+++ b/arch/arm/mach-s3c2410/cpu.h
@@ -74,5 +74,6 @@ extern struct sys_timer s3c24xx_timer;
74/* system device classes */ 74/* system device classes */
75 75
76extern struct sysdev_class s3c2410_sysclass; 76extern struct sysdev_class s3c2410_sysclass;
77extern struct sysdev_class s3c2412_sysclass;
77extern struct sysdev_class s3c2440_sysclass; 78extern struct sysdev_class s3c2440_sysclass;
78extern struct sysdev_class s3c2442_sysclass; 79extern struct sysdev_class s3c2442_sysclass;
diff --git a/arch/arm/mach-s3c2410/s3c2412.c b/arch/arm/mach-s3c2410/s3c2412.c
new file mode 100644
index 000000000000..e24ffd5e478b
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412.c
@@ -0,0 +1,195 @@
1/* linux/arch/arm/mach-s3c2410/s3c2412.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * http://armlinux.simtec.co.uk/.
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 * Modifications:
13 * 16-May-2003 BJD Created initial version
14 * 16-Aug-2003 BJD Fixed header files and copyright, added URL
15 * 05-Sep-2003 BJD Moved to kernel v2.6
16 * 18-Jan-2004 BJD Added serial port configuration
17 * 21-Aug-2004 BJD Added new struct s3c2410_board handler
18 * 28-Sep-2004 BJD Updates for new serial port bits
19 * 04-Nov-2004 BJD Updated UART configuration process
20 * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate
21 * 13-Aug-2005 DA Removed UART from initial I/O mappings
22*/
23
24#include <linux/kernel.h>
25#include <linux/types.h>
26#include <linux/interrupt.h>
27#include <linux/list.h>
28#include <linux/timer.h>
29#include <linux/init.h>
30#include <linux/sysdev.h>
31#include <linux/platform_device.h>
32
33#include <asm/mach/arch.h>
34#include <asm/mach/map.h>
35#include <asm/mach/irq.h>
36
37#include <asm/hardware.h>
38#include <asm/io.h>
39#include <asm/irq.h>
40
41#include <asm/arch/regs-clock.h>
42#include <asm/arch/regs-serial.h>
43#include <asm/arch/regs-gpio.h>
44#include <asm/arch/regs-gpioj.h>
45#include <asm/arch/regs-dsc.h>
46
47#include "s3c2412.h"
48#include "cpu.h"
49#include "devs.h"
50#include "clock.h"
51#include "pm.h"
52
53#ifndef CONFIG_CPU_S3C2412_ONLY
54void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
55#endif
56
57/* Initial IO mappings */
58
59static struct map_desc s3c2412_iodesc[] __initdata = {
60 IODESC_ENT(CLKPWR),
61 IODESC_ENT(LCD),
62 IODESC_ENT(TIMER),
63 IODESC_ENT(ADC),
64 IODESC_ENT(WATCHDOG),
65};
66
67/* uart registration process */
68
69void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
70{
71 s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
72
73 /* rename devices that are s3c2412/s3c2413 specific */
74 s3c_device_sdi.name = "s3c2412-sdi";
75 s3c_device_nand.name = "s3c2412-nand";
76}
77
78/* s3c2412_map_io
79 *
80 * register the standard cpu IO areas, and any passed in from the
81 * machine specific initialisation.
82*/
83
84void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
85{
86 /* move base of IO */
87
88 s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
89
90 /* register our io-tables */
91
92 iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
93 iotable_init(mach_desc, mach_size);
94}
95
96void __init s3c2412_init_clocks(int xtal)
97{
98 unsigned long tmp;
99 unsigned long fclk;
100 unsigned long hclk;
101 unsigned long pclk;
102
103 /* now we've got our machine bits initialised, work out what
104 * clocks we've got */
105
106 fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2);
107
108 tmp = __raw_readl(S3C2410_CLKDIVN);
109
110 /* work out clock scalings */
111
112 hclk = fclk / ((tmp & S3C2412_CLKDIVN_HDIVN_MASK) + 1);
113 hclk /= ((tmp & S3C2421_CLKDIVN_ARMDIVN) ? 2 : 1);
114 pclk = hclk / ((tmp & S3C2412_CLKDIVN_PDIVN) ? 2 : 1);
115
116 /* print brieft summary of clocks, etc */
117
118 printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
119 print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
120
121 /* initialise the clocks here, to allow other things like the
122 * console to use them
123 */
124
125 s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
126 s3c2412_baseclk_add();
127}
128
129/* need to register class before we actually register the device, and
130 * we also need to ensure that it has been initialised before any of the
131 * drivers even try to use it (even if not on an s3c2412 based system)
132 * as a driver which may support both 2410 and 2440 may try and use it.
133*/
134
135#ifdef CONFIG_PM
136static struct sleep_save s3c2412_sleep[] = {
137 SAVE_ITEM(S3C2412_DSC0),
138 SAVE_ITEM(S3C2412_DSC1),
139 SAVE_ITEM(S3C2413_GPJDAT),
140 SAVE_ITEM(S3C2413_GPJCON),
141 SAVE_ITEM(S3C2413_GPJUP),
142
143 /* save the sleep configuration anyway, just in case these
144 * get damaged during wakeup */
145
146 SAVE_ITEM(S3C2412_GPBSLPCON),
147 SAVE_ITEM(S3C2412_GPCSLPCON),
148 SAVE_ITEM(S3C2412_GPDSLPCON),
149 SAVE_ITEM(S3C2412_GPESLPCON),
150 SAVE_ITEM(S3C2412_GPFSLPCON),
151 SAVE_ITEM(S3C2412_GPGSLPCON),
152 SAVE_ITEM(S3C2412_GPHSLPCON),
153 SAVE_ITEM(S3C2413_GPJSLPCON),
154};
155
156static int s3c2412_suspend(struct sys_device *dev, pm_message_t state)
157{
158 s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
159 return 0;
160}
161
162static int s3c2412_resume(struct sys_device *dev)
163{
164 s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
165 return 0;
166}
167
168#else
169#define s3c2412_suspend NULL
170#define s3c2412_resume NULL
171#endif
172
173struct sysdev_class s3c2412_sysclass = {
174 set_kset_name("s3c2412-core"),
175 .suspend = s3c2412_suspend,
176 .resume = s3c2412_resume
177};
178
179static int __init s3c2412_core_init(void)
180{
181 return sysdev_class_register(&s3c2412_sysclass);
182}
183
184core_initcall(s3c2412_core_init);
185
186static struct sys_device s3c2412_sysdev = {
187 .cls = &s3c2412_sysclass,
188};
189
190int __init s3c2412_init(void)
191{
192 printk("S3C2412: Initialising architecture\n");
193
194 return sysdev_register(&s3c2412_sysdev);
195}
diff --git a/arch/arm/mach-s3c2410/s3c2412.h b/arch/arm/mach-s3c2410/s3c2412.h
new file mode 100644
index 000000000000..c6e56032a6e7
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412.h
@@ -0,0 +1,29 @@
1/* arch/arm/mach-s3c2410/s3c2412.h
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Header file for s3c2412 cpu 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#ifdef CONFIG_CPU_S3C2412
14
15extern int s3c2412_init(void);
16
17extern void s3c2412_map_io(struct map_desc *mach_desc, int size);
18
19extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
20
21extern void s3c2412_init_clocks(int xtal);
22
23extern int s3c2412_baseclk_add(void);
24#else
25#define s3c2412_init_clocks NULL
26#define s3c2412_init_uarts NULL
27#define s3c2412_map_io NULL
28#define s3c2412_init NULL
29#endif