diff options
Diffstat (limited to 'arch/arm/plat-s3c')
36 files changed, 3575 insertions, 12 deletions
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index 31656c33e05e..def0bb457ca3 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig | |||
@@ -6,8 +6,8 @@ | |||
6 | 6 | ||
7 | config PLAT_S3C | 7 | config PLAT_S3C |
8 | bool | 8 | bool |
9 | depends on ARCH_S3C2410 | 9 | depends on ARCH_S3C2410 || ARCH_S3C24A0 || ARCH_S3C64XX |
10 | default y if ARCH_S3C2410 | 10 | default y |
11 | select NO_IOPORT | 11 | select NO_IOPORT |
12 | help | 12 | help |
13 | Base platform code for any Samsung S3C device | 13 | Base platform code for any Samsung S3C device |
@@ -16,24 +16,24 @@ config PLAT_S3C | |||
16 | 16 | ||
17 | config CPU_LLSERIAL_S3C2410_ONLY | 17 | config CPU_LLSERIAL_S3C2410_ONLY |
18 | bool | 18 | bool |
19 | depends on ARCH_S3C2410 | 19 | depends on PLAT_S3C |
20 | default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440 | 20 | default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440 |
21 | 21 | ||
22 | config CPU_LLSERIAL_S3C2440_ONLY | 22 | config CPU_LLSERIAL_S3C2440_ONLY |
23 | bool | 23 | bool |
24 | depends on ARCH_S3C2410 | 24 | depends on PLAT_S3C |
25 | default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410 | 25 | default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410 |
26 | 26 | ||
27 | config CPU_LLSERIAL_S3C2410 | 27 | config CPU_LLSERIAL_S3C2410 |
28 | bool | 28 | bool |
29 | depends on ARCH_S3C2410 | 29 | depends on PLAT_S3C |
30 | help | 30 | help |
31 | Selected if there is an S3C2410 (or register compatible) serial | 31 | Selected if there is an S3C2410 (or register compatible) serial |
32 | low-level implementation needed | 32 | low-level implementation needed |
33 | 33 | ||
34 | config CPU_LLSERIAL_S3C2440 | 34 | config CPU_LLSERIAL_S3C2440 |
35 | bool | 35 | bool |
36 | depends on ARCH_S3C2410 | 36 | depends on PLAT_S3C |
37 | help | 37 | help |
38 | Selected if there is an S3C2440 (or register compatible) serial | 38 | Selected if there is an S3C2440 (or register compatible) serial |
39 | low-level implementation needed | 39 | low-level implementation needed |
@@ -57,6 +57,14 @@ config S3C_BOOT_ERROR_RESET | |||
57 | Say y here to use the watchdog to reset the system if the | 57 | Say y here to use the watchdog to reset the system if the |
58 | kernel decompressor detects an error during decompression. | 58 | kernel decompressor detects an error during decompression. |
59 | 59 | ||
60 | config S3C_BOOT_UART_FORCE_FIFO | ||
61 | bool "Force UART FIFO on during boot process" | ||
62 | depends on PLAT_S3C | ||
63 | default y | ||
64 | help | ||
65 | Say Y here to force the UART FIFOs on during the kernel | ||
66 | uncompressor | ||
67 | |||
60 | comment "Power management" | 68 | comment "Power management" |
61 | 69 | ||
62 | config S3C2410_PM_DEBUG | 70 | config S3C2410_PM_DEBUG |
@@ -102,3 +110,73 @@ config S3C_LOWLEVEL_UART_PORT | |||
102 | such as the `Uncompressing...` at start time. The value of | 110 | such as the `Uncompressing...` at start time. The value of |
103 | this configuration should be between zero and two. The port | 111 | this configuration should be between zero and two. The port |
104 | must have been initialised by the boot-loader before use. | 112 | must have been initialised by the boot-loader before use. |
113 | |||
114 | # options for gpiolib support | ||
115 | |||
116 | config S3C_GPIO_SPACE | ||
117 | int "Space between gpio banks" | ||
118 | default 0 | ||
119 | help | ||
120 | Add a number of spare GPIO entries between each bank for debugging | ||
121 | purposes. This allows any problems where an counter overflows from | ||
122 | one bank to another to be caught, at the expense of using a little | ||
123 | more memory. | ||
124 | |||
125 | config S3C_GPIO_TRACK | ||
126 | bool | ||
127 | help | ||
128 | Internal configuration option to enable the s3c specific gpio | ||
129 | chip tracking if the platform requires it. | ||
130 | |||
131 | config S3C_GPIO_PULL_UPDOWN | ||
132 | bool | ||
133 | help | ||
134 | Internal configuration to enable the correct GPIO pull helper | ||
135 | |||
136 | config S3C_GPIO_PULL_DOWN | ||
137 | bool | ||
138 | help | ||
139 | Internal configuration to enable the correct GPIO pull helper | ||
140 | |||
141 | config S3C_GPIO_PULL_UP | ||
142 | bool | ||
143 | help | ||
144 | Internal configuration to enable the correct GPIO pull helper | ||
145 | |||
146 | config S3C_GPIO_CFG_S3C24XX | ||
147 | bool | ||
148 | help | ||
149 | Internal configuration to enable S3C24XX style GPIO configuration | ||
150 | functions. | ||
151 | |||
152 | config S3C_GPIO_CFG_S3C64XX | ||
153 | bool | ||
154 | help | ||
155 | Internal configuration to enable S3C64XX style GPIO configuration | ||
156 | functions. | ||
157 | |||
158 | # device definitions to compile in | ||
159 | |||
160 | config S3C_DEV_HSMMC | ||
161 | bool | ||
162 | depends on PLAT_S3C | ||
163 | help | ||
164 | Compile in platform device definitions for HSMMC code | ||
165 | |||
166 | config S3C_DEV_HSMMC1 | ||
167 | bool | ||
168 | depends on PLAT_S3C | ||
169 | help | ||
170 | Compile in platform device definitions for HSMMC channel 1 | ||
171 | |||
172 | config S3C_DEV_I2C1 | ||
173 | bool | ||
174 | depends on PLAT_S3C | ||
175 | help | ||
176 | Compile in platform device definitions for I2C channel 1 | ||
177 | |||
178 | config S3C_DEV_FB | ||
179 | bool | ||
180 | depends on PLAT_S3C | ||
181 | help | ||
182 | Compile in platform device definition for framebuffer | ||
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile index f03d7b35ba37..39195f972d5e 100644 --- a/arch/arm/plat-s3c/Makefile +++ b/arch/arm/plat-s3c/Makefile | |||
@@ -1,3 +1,27 @@ | |||
1 | # dummy makefile, currently just including asm/arm/plat-s3c/include/plat | 1 | # arch/arm/plat-s3c/Makefile |
2 | # | ||
3 | # Copyright 2008 Simtec Electronics | ||
4 | # | ||
5 | # Licensed under GPLv2 | ||
2 | 6 | ||
3 | obj-n := dummy.o | 7 | obj-y := |
8 | obj-m := | ||
9 | obj-n := | ||
10 | obj- := | ||
11 | |||
12 | # Core support for all Samsung SoCs | ||
13 | |||
14 | obj-y += init.o | ||
15 | obj-y += time.o | ||
16 | obj-y += clock.o | ||
17 | obj-y += pwm-clock.o | ||
18 | obj-y += gpio.o | ||
19 | obj-y += gpio-config.o | ||
20 | |||
21 | # devices | ||
22 | |||
23 | obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o | ||
24 | obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o | ||
25 | obj-y += dev-i2c0.o | ||
26 | obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o | ||
27 | obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o | ||
diff --git a/arch/arm/plat-s3c/clock.c b/arch/arm/plat-s3c/clock.c new file mode 100644 index 000000000000..b6be76e2fe51 --- /dev/null +++ b/arch/arm/plat-s3c/clock.c | |||
@@ -0,0 +1,368 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/clock.c | ||
2 | * | ||
3 | * Copyright (c) 2004-2005 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * S3C24XX Core clock control support | ||
7 | * | ||
8 | * Based on, and code from linux/arch/arm/mach-versatile/clock.c | ||
9 | ** | ||
10 | ** Copyright (C) 2004 ARM Limited. | ||
11 | ** Written by Deep Blue Solutions Limited. | ||
12 | * | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/list.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/err.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/sysdev.h> | ||
37 | #include <linux/interrupt.h> | ||
38 | #include <linux/ioport.h> | ||
39 | #include <linux/clk.h> | ||
40 | #include <linux/spinlock.h> | ||
41 | #include <linux/io.h> | ||
42 | |||
43 | #include <mach/hardware.h> | ||
44 | #include <asm/irq.h> | ||
45 | |||
46 | #include <plat/cpu-freq.h> | ||
47 | |||
48 | #include <plat/clock.h> | ||
49 | #include <plat/cpu.h> | ||
50 | |||
51 | /* clock information */ | ||
52 | |||
53 | static LIST_HEAD(clocks); | ||
54 | |||
55 | /* We originally used an mutex here, but some contexts (see resume) | ||
56 | * are calling functions such as clk_set_parent() with IRQs disabled | ||
57 | * causing an BUG to be triggered. | ||
58 | */ | ||
59 | DEFINE_SPINLOCK(clocks_lock); | ||
60 | |||
61 | /* enable and disable calls for use with the clk struct */ | ||
62 | |||
63 | static int clk_null_enable(struct clk *clk, int enable) | ||
64 | { | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | /* Clock API calls */ | ||
69 | |||
70 | struct clk *clk_get(struct device *dev, const char *id) | ||
71 | { | ||
72 | struct clk *p; | ||
73 | struct clk *clk = ERR_PTR(-ENOENT); | ||
74 | int idno; | ||
75 | |||
76 | if (dev == NULL || dev->bus != &platform_bus_type) | ||
77 | idno = -1; | ||
78 | else | ||
79 | idno = to_platform_device(dev)->id; | ||
80 | |||
81 | spin_lock(&clocks_lock); | ||
82 | |||
83 | list_for_each_entry(p, &clocks, list) { | ||
84 | if (p->id == idno && | ||
85 | strcmp(id, p->name) == 0 && | ||
86 | try_module_get(p->owner)) { | ||
87 | clk = p; | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | /* check for the case where a device was supplied, but the | ||
93 | * clock that was being searched for is not device specific */ | ||
94 | |||
95 | if (IS_ERR(clk)) { | ||
96 | list_for_each_entry(p, &clocks, list) { | ||
97 | if (p->id == -1 && strcmp(id, p->name) == 0 && | ||
98 | try_module_get(p->owner)) { | ||
99 | clk = p; | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | |||
105 | spin_unlock(&clocks_lock); | ||
106 | return clk; | ||
107 | } | ||
108 | |||
109 | void clk_put(struct clk *clk) | ||
110 | { | ||
111 | module_put(clk->owner); | ||
112 | } | ||
113 | |||
114 | int clk_enable(struct clk *clk) | ||
115 | { | ||
116 | if (IS_ERR(clk) || clk == NULL) | ||
117 | return -EINVAL; | ||
118 | |||
119 | clk_enable(clk->parent); | ||
120 | |||
121 | spin_lock(&clocks_lock); | ||
122 | |||
123 | if ((clk->usage++) == 0) | ||
124 | (clk->enable)(clk, 1); | ||
125 | |||
126 | spin_unlock(&clocks_lock); | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | void clk_disable(struct clk *clk) | ||
131 | { | ||
132 | if (IS_ERR(clk) || clk == NULL) | ||
133 | return; | ||
134 | |||
135 | spin_lock(&clocks_lock); | ||
136 | |||
137 | if ((--clk->usage) == 0) | ||
138 | (clk->enable)(clk, 0); | ||
139 | |||
140 | spin_unlock(&clocks_lock); | ||
141 | clk_disable(clk->parent); | ||
142 | } | ||
143 | |||
144 | |||
145 | unsigned long clk_get_rate(struct clk *clk) | ||
146 | { | ||
147 | if (IS_ERR(clk)) | ||
148 | return 0; | ||
149 | |||
150 | if (clk->rate != 0) | ||
151 | return clk->rate; | ||
152 | |||
153 | if (clk->get_rate != NULL) | ||
154 | return (clk->get_rate)(clk); | ||
155 | |||
156 | if (clk->parent != NULL) | ||
157 | return clk_get_rate(clk->parent); | ||
158 | |||
159 | return clk->rate; | ||
160 | } | ||
161 | |||
162 | long clk_round_rate(struct clk *clk, unsigned long rate) | ||
163 | { | ||
164 | if (!IS_ERR(clk) && clk->round_rate) | ||
165 | return (clk->round_rate)(clk, rate); | ||
166 | |||
167 | return rate; | ||
168 | } | ||
169 | |||
170 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
171 | { | ||
172 | int ret; | ||
173 | |||
174 | if (IS_ERR(clk)) | ||
175 | return -EINVAL; | ||
176 | |||
177 | /* We do not default just do a clk->rate = rate as | ||
178 | * the clock may have been made this way by choice. | ||
179 | */ | ||
180 | |||
181 | WARN_ON(clk->set_rate == NULL); | ||
182 | |||
183 | if (clk->set_rate == NULL) | ||
184 | return -EINVAL; | ||
185 | |||
186 | spin_lock(&clocks_lock); | ||
187 | ret = (clk->set_rate)(clk, rate); | ||
188 | spin_unlock(&clocks_lock); | ||
189 | |||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | struct clk *clk_get_parent(struct clk *clk) | ||
194 | { | ||
195 | return clk->parent; | ||
196 | } | ||
197 | |||
198 | int clk_set_parent(struct clk *clk, struct clk *parent) | ||
199 | { | ||
200 | int ret = 0; | ||
201 | |||
202 | if (IS_ERR(clk)) | ||
203 | return -EINVAL; | ||
204 | |||
205 | spin_lock(&clocks_lock); | ||
206 | |||
207 | if (clk->set_parent) | ||
208 | ret = (clk->set_parent)(clk, parent); | ||
209 | |||
210 | spin_unlock(&clocks_lock); | ||
211 | |||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | EXPORT_SYMBOL(clk_get); | ||
216 | EXPORT_SYMBOL(clk_put); | ||
217 | EXPORT_SYMBOL(clk_enable); | ||
218 | EXPORT_SYMBOL(clk_disable); | ||
219 | EXPORT_SYMBOL(clk_get_rate); | ||
220 | EXPORT_SYMBOL(clk_round_rate); | ||
221 | EXPORT_SYMBOL(clk_set_rate); | ||
222 | EXPORT_SYMBOL(clk_get_parent); | ||
223 | EXPORT_SYMBOL(clk_set_parent); | ||
224 | |||
225 | /* base clocks */ | ||
226 | |||
227 | static int clk_default_setrate(struct clk *clk, unsigned long rate) | ||
228 | { | ||
229 | clk->rate = rate; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | struct clk clk_xtal = { | ||
234 | .name = "xtal", | ||
235 | .id = -1, | ||
236 | .rate = 0, | ||
237 | .parent = NULL, | ||
238 | .ctrlbit = 0, | ||
239 | }; | ||
240 | |||
241 | struct clk clk_ext = { | ||
242 | .name = "ext", | ||
243 | .id = -1, | ||
244 | }; | ||
245 | |||
246 | struct clk clk_epll = { | ||
247 | .name = "epll", | ||
248 | .id = -1, | ||
249 | }; | ||
250 | |||
251 | struct clk clk_mpll = { | ||
252 | .name = "mpll", | ||
253 | .id = -1, | ||
254 | .set_rate = clk_default_setrate, | ||
255 | }; | ||
256 | |||
257 | struct clk clk_upll = { | ||
258 | .name = "upll", | ||
259 | .id = -1, | ||
260 | .parent = NULL, | ||
261 | .ctrlbit = 0, | ||
262 | }; | ||
263 | |||
264 | struct clk clk_f = { | ||
265 | .name = "fclk", | ||
266 | .id = -1, | ||
267 | .rate = 0, | ||
268 | .parent = &clk_mpll, | ||
269 | .ctrlbit = 0, | ||
270 | .set_rate = clk_default_setrate, | ||
271 | }; | ||
272 | |||
273 | struct clk clk_h = { | ||
274 | .name = "hclk", | ||
275 | .id = -1, | ||
276 | .rate = 0, | ||
277 | .parent = NULL, | ||
278 | .ctrlbit = 0, | ||
279 | .set_rate = clk_default_setrate, | ||
280 | }; | ||
281 | |||
282 | struct clk clk_p = { | ||
283 | .name = "pclk", | ||
284 | .id = -1, | ||
285 | .rate = 0, | ||
286 | .parent = NULL, | ||
287 | .ctrlbit = 0, | ||
288 | .set_rate = clk_default_setrate, | ||
289 | }; | ||
290 | |||
291 | struct clk clk_usb_bus = { | ||
292 | .name = "usb-bus", | ||
293 | .id = -1, | ||
294 | .rate = 0, | ||
295 | .parent = &clk_upll, | ||
296 | }; | ||
297 | |||
298 | |||
299 | |||
300 | struct clk s3c24xx_uclk = { | ||
301 | .name = "uclk", | ||
302 | .id = -1, | ||
303 | }; | ||
304 | |||
305 | /* initialise the clock system */ | ||
306 | |||
307 | int s3c24xx_register_clock(struct clk *clk) | ||
308 | { | ||
309 | clk->owner = THIS_MODULE; | ||
310 | |||
311 | if (clk->enable == NULL) | ||
312 | clk->enable = clk_null_enable; | ||
313 | |||
314 | /* add to the list of available clocks */ | ||
315 | |||
316 | /* Quick check to see if this clock has already been registered. */ | ||
317 | BUG_ON(clk->list.prev != clk->list.next); | ||
318 | |||
319 | spin_lock(&clocks_lock); | ||
320 | list_add(&clk->list, &clocks); | ||
321 | spin_unlock(&clocks_lock); | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | int s3c24xx_register_clocks(struct clk **clks, int nr_clks) | ||
327 | { | ||
328 | int fails = 0; | ||
329 | |||
330 | for (; nr_clks > 0; nr_clks--, clks++) { | ||
331 | if (s3c24xx_register_clock(*clks) < 0) | ||
332 | fails++; | ||
333 | } | ||
334 | |||
335 | return fails; | ||
336 | } | ||
337 | |||
338 | /* initalise all the clocks */ | ||
339 | |||
340 | int __init s3c24xx_register_baseclocks(unsigned long xtal) | ||
341 | { | ||
342 | printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n"); | ||
343 | |||
344 | clk_xtal.rate = xtal; | ||
345 | |||
346 | /* register our clocks */ | ||
347 | |||
348 | if (s3c24xx_register_clock(&clk_xtal) < 0) | ||
349 | printk(KERN_ERR "failed to register master xtal\n"); | ||
350 | |||
351 | if (s3c24xx_register_clock(&clk_mpll) < 0) | ||
352 | printk(KERN_ERR "failed to register mpll clock\n"); | ||
353 | |||
354 | if (s3c24xx_register_clock(&clk_upll) < 0) | ||
355 | printk(KERN_ERR "failed to register upll clock\n"); | ||
356 | |||
357 | if (s3c24xx_register_clock(&clk_f) < 0) | ||
358 | printk(KERN_ERR "failed to register cpu fclk\n"); | ||
359 | |||
360 | if (s3c24xx_register_clock(&clk_h) < 0) | ||
361 | printk(KERN_ERR "failed to register cpu hclk\n"); | ||
362 | |||
363 | if (s3c24xx_register_clock(&clk_p) < 0) | ||
364 | printk(KERN_ERR "failed to register cpu pclk\n"); | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
diff --git a/arch/arm/plat-s3c/dev-fb.c b/arch/arm/plat-s3c/dev-fb.c new file mode 100644 index 000000000000..0454b8ec02e2 --- /dev/null +++ b/arch/arm/plat-s3c/dev-fb.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* linux/arch/arm/plat-s3c/dev-fb.c | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * S3C series device definition for framebuffer device | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/fb.h> | ||
18 | |||
19 | #include <mach/map.h> | ||
20 | #include <mach/regs-fb.h> | ||
21 | |||
22 | #include <plat/fb.h> | ||
23 | #include <plat/devs.h> | ||
24 | #include <plat/cpu.h> | ||
25 | |||
26 | static struct resource s3c_fb_resource[] = { | ||
27 | [0] = { | ||
28 | .start = S3C_PA_FB, | ||
29 | .end = S3C_PA_FB + SZ_16K - 1, | ||
30 | .flags = IORESOURCE_MEM, | ||
31 | }, | ||
32 | [1] = { | ||
33 | .start = IRQ_LCD_VSYNC, | ||
34 | .end = IRQ_LCD_VSYNC, | ||
35 | .flags = IORESOURCE_IRQ, | ||
36 | }, | ||
37 | [2] = { | ||
38 | .start = IRQ_LCD_FIFO, | ||
39 | .end = IRQ_LCD_FIFO, | ||
40 | .flags = IORESOURCE_IRQ, | ||
41 | }, | ||
42 | [3] = { | ||
43 | .start = IRQ_LCD_SYSTEM, | ||
44 | .end = IRQ_LCD_SYSTEM, | ||
45 | .flags = IORESOURCE_IRQ, | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | struct platform_device s3c_device_fb = { | ||
50 | .name = "s3c-fb", | ||
51 | .id = -1, | ||
52 | .num_resources = ARRAY_SIZE(s3c_fb_resource), | ||
53 | .resource = s3c_fb_resource, | ||
54 | .dev.dma_mask = &s3c_device_fb.dev.coherent_dma_mask, | ||
55 | .dev.coherent_dma_mask = 0xffffffffUL, | ||
56 | }; | ||
57 | |||
58 | void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd) | ||
59 | { | ||
60 | struct s3c_fb_platdata *npd; | ||
61 | |||
62 | if (!pd) { | ||
63 | printk(KERN_ERR "%s: no platform data\n", __func__); | ||
64 | return; | ||
65 | } | ||
66 | |||
67 | npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL); | ||
68 | if (!npd) | ||
69 | printk(KERN_ERR "%s: no memory for platform data\n", __func__); | ||
70 | |||
71 | s3c_device_fb.dev.platform_data = npd; | ||
72 | } | ||
diff --git a/arch/arm/plat-s3c/dev-hsmmc.c b/arch/arm/plat-s3c/dev-hsmmc.c new file mode 100644 index 000000000000..4c05b39810e2 --- /dev/null +++ b/arch/arm/plat-s3c/dev-hsmmc.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* linux/arch/arm/plat-s3c/dev-hsmmc.c | ||
2 | * | ||
3 | * Copyright (c) 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * S3C series device definition for hsmmc devices | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/mmc/host.h> | ||
17 | |||
18 | #include <mach/map.h> | ||
19 | #include <plat/sdhci.h> | ||
20 | #include <plat/devs.h> | ||
21 | #include <plat/cpu.h> | ||
22 | |||
23 | #define S3C_SZ_HSMMC (0x1000) | ||
24 | |||
25 | static struct resource s3c_hsmmc_resource[] = { | ||
26 | [0] = { | ||
27 | .start = S3C_PA_HSMMC0, | ||
28 | .end = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1, | ||
29 | .flags = IORESOURCE_MEM, | ||
30 | }, | ||
31 | [1] = { | ||
32 | .start = IRQ_HSMMC0, | ||
33 | .end = IRQ_HSMMC0, | ||
34 | .flags = IORESOURCE_IRQ, | ||
35 | } | ||
36 | }; | ||
37 | |||
38 | static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL; | ||
39 | |||
40 | struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = { | ||
41 | .max_width = 4, | ||
42 | .host_caps = (MMC_CAP_4_BIT_DATA | | ||
43 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | ||
44 | }; | ||
45 | |||
46 | struct platform_device s3c_device_hsmmc0 = { | ||
47 | .name = "s3c-sdhci", | ||
48 | .id = 0, | ||
49 | .num_resources = ARRAY_SIZE(s3c_hsmmc_resource), | ||
50 | .resource = s3c_hsmmc_resource, | ||
51 | .dev = { | ||
52 | .dma_mask = &s3c_device_hsmmc_dmamask, | ||
53 | .coherent_dma_mask = 0xffffffffUL, | ||
54 | .platform_data = &s3c_hsmmc0_def_platdata, | ||
55 | }, | ||
56 | }; | ||
57 | |||
58 | void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) | ||
59 | { | ||
60 | struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata; | ||
61 | |||
62 | set->max_width = pd->max_width; | ||
63 | |||
64 | if (pd->cfg_gpio) | ||
65 | set->cfg_gpio = pd->cfg_gpio; | ||
66 | if (pd->cfg_card) | ||
67 | set->cfg_card = pd->cfg_card; | ||
68 | } | ||
diff --git a/arch/arm/plat-s3c/dev-hsmmc1.c b/arch/arm/plat-s3c/dev-hsmmc1.c new file mode 100644 index 000000000000..e49bc4cd0ee6 --- /dev/null +++ b/arch/arm/plat-s3c/dev-hsmmc1.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* linux/arch/arm/plat-s3c/dev-hsmmc1.c | ||
2 | * | ||
3 | * Copyright (c) 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * S3C series device definition for hsmmc device 1 | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/mmc/host.h> | ||
17 | |||
18 | #include <mach/map.h> | ||
19 | #include <plat/sdhci.h> | ||
20 | #include <plat/devs.h> | ||
21 | #include <plat/cpu.h> | ||
22 | |||
23 | #define S3C_SZ_HSMMC (0x1000) | ||
24 | |||
25 | static struct resource s3c_hsmmc1_resource[] = { | ||
26 | [0] = { | ||
27 | .start = S3C_PA_HSMMC1, | ||
28 | .end = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1, | ||
29 | .flags = IORESOURCE_MEM, | ||
30 | }, | ||
31 | [1] = { | ||
32 | .start = IRQ_HSMMC1, | ||
33 | .end = IRQ_HSMMC1, | ||
34 | .flags = IORESOURCE_IRQ, | ||
35 | } | ||
36 | }; | ||
37 | |||
38 | static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL; | ||
39 | |||
40 | struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = { | ||
41 | .max_width = 4, | ||
42 | .host_caps = (MMC_CAP_4_BIT_DATA | | ||
43 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | ||
44 | }; | ||
45 | |||
46 | struct platform_device s3c_device_hsmmc1 = { | ||
47 | .name = "s3c-sdhci", | ||
48 | .id = 1, | ||
49 | .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource), | ||
50 | .resource = s3c_hsmmc1_resource, | ||
51 | .dev = { | ||
52 | .dma_mask = &s3c_device_hsmmc1_dmamask, | ||
53 | .coherent_dma_mask = 0xffffffffUL, | ||
54 | .platform_data = &s3c_hsmmc1_def_platdata, | ||
55 | }, | ||
56 | }; | ||
57 | |||
58 | void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) | ||
59 | { | ||
60 | struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata; | ||
61 | |||
62 | set->max_width = pd->max_width; | ||
63 | |||
64 | if (pd->cfg_gpio) | ||
65 | set->cfg_gpio = pd->cfg_gpio; | ||
66 | if (pd->cfg_card) | ||
67 | set->cfg_card = pd->cfg_card; | ||
68 | } | ||
diff --git a/arch/arm/plat-s3c/dev-i2c0.c b/arch/arm/plat-s3c/dev-i2c0.c new file mode 100644 index 000000000000..2c0128c77c6e --- /dev/null +++ b/arch/arm/plat-s3c/dev-i2c0.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* linux/arch/arm/plat-s3c/dev-i2c0.c | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * S3C series device definition for i2c device 0 | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include <mach/map.h> | ||
19 | |||
20 | #include <plat/regs-iic.h> | ||
21 | #include <plat/iic.h> | ||
22 | #include <plat/devs.h> | ||
23 | #include <plat/cpu.h> | ||
24 | |||
25 | static struct resource s3c_i2c_resource[] = { | ||
26 | [0] = { | ||
27 | .start = S3C_PA_IIC, | ||
28 | .end = S3C_PA_IIC + SZ_4K - 1, | ||
29 | .flags = IORESOURCE_MEM, | ||
30 | }, | ||
31 | [1] = { | ||
32 | .start = IRQ_IIC, | ||
33 | .end = IRQ_IIC, | ||
34 | .flags = IORESOURCE_IRQ, | ||
35 | }, | ||
36 | }; | ||
37 | |||
38 | struct platform_device s3c_device_i2c0 = { | ||
39 | .name = "s3c2410-i2c", | ||
40 | #ifdef CONFIG_S3C_DEV_I2C1 | ||
41 | .id = 0, | ||
42 | #else | ||
43 | .id = -1, | ||
44 | #endif | ||
45 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
46 | .resource = s3c_i2c_resource, | ||
47 | }; | ||
48 | |||
49 | static struct s3c2410_platform_i2c default_i2c_data0 __initdata = { | ||
50 | .flags = 0, | ||
51 | .slave_addr = 0x10, | ||
52 | .bus_freq = 100*1000, | ||
53 | .max_freq = 400*1000, | ||
54 | .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON, | ||
55 | }; | ||
56 | |||
57 | void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) | ||
58 | { | ||
59 | struct s3c2410_platform_i2c *npd; | ||
60 | |||
61 | if (!pd) | ||
62 | pd = &default_i2c_data0; | ||
63 | |||
64 | npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); | ||
65 | if (!npd) | ||
66 | printk(KERN_ERR "%s: no memory for platform data\n", __func__); | ||
67 | else if (!npd->cfg_gpio) | ||
68 | npd->cfg_gpio = s3c_i2c0_cfg_gpio; | ||
69 | |||
70 | s3c_device_i2c0.dev.platform_data = npd; | ||
71 | } | ||
diff --git a/arch/arm/plat-s3c/dev-i2c1.c b/arch/arm/plat-s3c/dev-i2c1.c new file mode 100644 index 000000000000..9658fb0aec95 --- /dev/null +++ b/arch/arm/plat-s3c/dev-i2c1.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* linux/arch/arm/plat-s3c/dev-i2c1.c | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * S3C series device definition for i2c device 1 | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include <mach/map.h> | ||
19 | |||
20 | #include <plat/regs-iic.h> | ||
21 | #include <plat/iic.h> | ||
22 | #include <plat/devs.h> | ||
23 | #include <plat/cpu.h> | ||
24 | |||
25 | static struct resource s3c_i2c_resource[] = { | ||
26 | [0] = { | ||
27 | .start = S3C_PA_IIC1, | ||
28 | .end = S3C_PA_IIC1 + SZ_4K - 1, | ||
29 | .flags = IORESOURCE_MEM, | ||
30 | }, | ||
31 | [1] = { | ||
32 | .start = IRQ_IIC1, | ||
33 | .end = IRQ_IIC1, | ||
34 | .flags = IORESOURCE_IRQ, | ||
35 | }, | ||
36 | }; | ||
37 | |||
38 | struct platform_device s3c_device_i2c1 = { | ||
39 | .name = "s3c2410-i2c", | ||
40 | .id = 1, | ||
41 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
42 | .resource = s3c_i2c_resource, | ||
43 | }; | ||
44 | |||
45 | static struct s3c2410_platform_i2c default_i2c_data1 __initdata = { | ||
46 | .flags = 0, | ||
47 | .bus_num = 1, | ||
48 | .slave_addr = 0x10, | ||
49 | .bus_freq = 100*1000, | ||
50 | .max_freq = 400*1000, | ||
51 | .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON, | ||
52 | }; | ||
53 | |||
54 | void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd) | ||
55 | { | ||
56 | struct s3c2410_platform_i2c *npd; | ||
57 | |||
58 | if (!pd) | ||
59 | pd = &default_i2c_data1; | ||
60 | |||
61 | npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); | ||
62 | if (!npd) | ||
63 | printk(KERN_ERR "%s: no memory for platform data\n", __func__); | ||
64 | else if (!npd->cfg_gpio) | ||
65 | npd->cfg_gpio = s3c_i2c1_cfg_gpio; | ||
66 | |||
67 | s3c_device_i2c1.dev.platform_data = npd; | ||
68 | } | ||
diff --git a/arch/arm/plat-s3c/gpio-config.c b/arch/arm/plat-s3c/gpio-config.c new file mode 100644 index 000000000000..7642b975a998 --- /dev/null +++ b/arch/arm/plat-s3c/gpio-config.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* linux/arch/arm/plat-s3c/gpio-config.c | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * S3C series GPIO configuration core | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <mach/gpio-core.h> | ||
20 | #include <plat/gpio-cfg.h> | ||
21 | #include <plat/gpio-cfg-helpers.h> | ||
22 | |||
23 | int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) | ||
24 | { | ||
25 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
26 | unsigned long flags; | ||
27 | int offset; | ||
28 | int ret; | ||
29 | |||
30 | if (!chip) | ||
31 | return -EINVAL; | ||
32 | |||
33 | offset = pin - chip->chip.base; | ||
34 | |||
35 | local_irq_save(flags); | ||
36 | ret = s3c_gpio_do_setcfg(chip, offset, config); | ||
37 | local_irq_restore(flags); | ||
38 | |||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) | ||
43 | { | ||
44 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
45 | unsigned long flags; | ||
46 | int offset, ret; | ||
47 | |||
48 | if (!chip) | ||
49 | return -EINVAL; | ||
50 | |||
51 | offset = pin - chip->chip.base; | ||
52 | |||
53 | local_irq_save(flags); | ||
54 | ret = s3c_gpio_do_setpull(chip, offset, pull); | ||
55 | local_irq_restore(flags); | ||
56 | |||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX | ||
61 | int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip, | ||
62 | unsigned int off, unsigned int cfg) | ||
63 | { | ||
64 | void __iomem *reg = chip->base; | ||
65 | unsigned int shift = off; | ||
66 | u32 con; | ||
67 | |||
68 | if (s3c_gpio_is_cfg_special(cfg)) { | ||
69 | cfg &= 0xf; | ||
70 | |||
71 | /* Map output to 0, and SFN2 to 1 */ | ||
72 | cfg -= 1; | ||
73 | if (cfg > 1) | ||
74 | return -EINVAL; | ||
75 | |||
76 | cfg <<= shift; | ||
77 | } | ||
78 | |||
79 | con = __raw_readl(reg); | ||
80 | con &= ~(0x1 << shift); | ||
81 | con |= cfg; | ||
82 | __raw_writel(con, reg); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, | ||
88 | unsigned int off, unsigned int cfg) | ||
89 | { | ||
90 | void __iomem *reg = chip->base; | ||
91 | unsigned int shift = off * 2; | ||
92 | u32 con; | ||
93 | |||
94 | if (s3c_gpio_is_cfg_special(cfg)) { | ||
95 | cfg &= 0xf; | ||
96 | if (cfg > 3) | ||
97 | return -EINVAL; | ||
98 | |||
99 | cfg <<= shift; | ||
100 | } | ||
101 | |||
102 | con = __raw_readl(reg); | ||
103 | con &= ~(0x3 << shift); | ||
104 | con |= cfg; | ||
105 | __raw_writel(con, reg); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | #endif | ||
110 | |||
111 | #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX | ||
112 | int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, | ||
113 | unsigned int off, unsigned int cfg) | ||
114 | { | ||
115 | void __iomem *reg = chip->base; | ||
116 | unsigned int shift = (off & 7) * 4; | ||
117 | u32 con; | ||
118 | |||
119 | if (off < 8 && chip->chip.ngpio >= 8) | ||
120 | reg -= 4; | ||
121 | |||
122 | if (s3c_gpio_is_cfg_special(cfg)) { | ||
123 | cfg &= 0xf; | ||
124 | cfg <<= shift; | ||
125 | } | ||
126 | |||
127 | con = __raw_readl(reg); | ||
128 | con &= ~(0xf << shift); | ||
129 | con |= cfg; | ||
130 | __raw_writel(con, reg); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | #endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */ | ||
135 | |||
136 | #ifdef CONFIG_S3C_GPIO_PULL_UPDOWN | ||
137 | int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip, | ||
138 | unsigned int off, s3c_gpio_pull_t pull) | ||
139 | { | ||
140 | void __iomem *reg = chip->base + 0x08; | ||
141 | int shift = off * 2; | ||
142 | u32 pup; | ||
143 | |||
144 | pup = __raw_readl(reg); | ||
145 | pup &= ~(3 << shift); | ||
146 | pup |= pull << shift; | ||
147 | __raw_writel(pup, reg); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, | ||
153 | unsigned int off) | ||
154 | { | ||
155 | void __iomem *reg = chip->base + 0x08; | ||
156 | int shift = off * 2; | ||
157 | u32 pup = __raw_readl(reg); | ||
158 | |||
159 | pup >>= shift; | ||
160 | pup &= 0x3; | ||
161 | return (__force s3c_gpio_pull_t)pup; | ||
162 | } | ||
163 | #endif | ||
diff --git a/arch/arm/plat-s3c/gpio.c b/arch/arm/plat-s3c/gpio.c new file mode 100644 index 000000000000..d71dd6d9ce5c --- /dev/null +++ b/arch/arm/plat-s3c/gpio.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /* linux/arch/arm/plat-s3c/gpio.c | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * S3C series GPIO core | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | #include <plat/gpio-core.h> | ||
20 | |||
21 | #ifdef CONFIG_S3C_GPIO_TRACK | ||
22 | struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; | ||
23 | |||
24 | static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip) | ||
25 | { | ||
26 | unsigned int gpn; | ||
27 | int i; | ||
28 | |||
29 | gpn = chip->chip.base; | ||
30 | for (i = 0; i < chip->chip.ngpio; i++, gpn++) { | ||
31 | BUG_ON(gpn > ARRAY_SIZE(s3c_gpios)); | ||
32 | s3c_gpios[gpn] = chip; | ||
33 | } | ||
34 | } | ||
35 | #endif /* CONFIG_S3C_GPIO_TRACK */ | ||
36 | |||
37 | /* Default routines for controlling GPIO, based on the original S3C24XX | ||
38 | * GPIO functions which deal with the case where each gpio bank of the | ||
39 | * chip is as following: | ||
40 | * | ||
41 | * base + 0x00: Control register, 2 bits per gpio | ||
42 | * gpio n: 2 bits starting at (2*n) | ||
43 | * 00 = input, 01 = output, others mean special-function | ||
44 | * base + 0x04: Data register, 1 bit per gpio | ||
45 | * bit n: data bit n | ||
46 | */ | ||
47 | |||
48 | static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset) | ||
49 | { | ||
50 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
51 | void __iomem *base = ourchip->base; | ||
52 | unsigned long flags; | ||
53 | unsigned long con; | ||
54 | |||
55 | local_irq_save(flags); | ||
56 | |||
57 | con = __raw_readl(base + 0x00); | ||
58 | con &= ~(3 << (offset * 2)); | ||
59 | |||
60 | __raw_writel(con, base + 0x00); | ||
61 | |||
62 | local_irq_restore(flags); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int s3c_gpiolib_output(struct gpio_chip *chip, | ||
67 | unsigned offset, int value) | ||
68 | { | ||
69 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
70 | void __iomem *base = ourchip->base; | ||
71 | unsigned long flags; | ||
72 | unsigned long dat; | ||
73 | unsigned long con; | ||
74 | |||
75 | local_irq_save(flags); | ||
76 | |||
77 | dat = __raw_readl(base + 0x04); | ||
78 | dat &= ~(1 << offset); | ||
79 | if (value) | ||
80 | dat |= 1 << offset; | ||
81 | __raw_writel(dat, base + 0x04); | ||
82 | |||
83 | con = __raw_readl(base + 0x00); | ||
84 | con &= ~(3 << (offset * 2)); | ||
85 | con |= 1 << (offset * 2); | ||
86 | |||
87 | __raw_writel(con, base + 0x00); | ||
88 | __raw_writel(dat, base + 0x04); | ||
89 | |||
90 | local_irq_restore(flags); | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static void s3c_gpiolib_set(struct gpio_chip *chip, | ||
95 | unsigned offset, int value) | ||
96 | { | ||
97 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
98 | void __iomem *base = ourchip->base; | ||
99 | unsigned long flags; | ||
100 | unsigned long dat; | ||
101 | |||
102 | local_irq_save(flags); | ||
103 | |||
104 | dat = __raw_readl(base + 0x04); | ||
105 | dat &= ~(1 << offset); | ||
106 | if (value) | ||
107 | dat |= 1 << offset; | ||
108 | __raw_writel(dat, base + 0x04); | ||
109 | |||
110 | local_irq_restore(flags); | ||
111 | } | ||
112 | |||
113 | static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset) | ||
114 | { | ||
115 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
116 | unsigned long val; | ||
117 | |||
118 | val = __raw_readl(ourchip->base + 0x04); | ||
119 | val >>= offset; | ||
120 | val &= 1; | ||
121 | |||
122 | return val; | ||
123 | } | ||
124 | |||
125 | __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip) | ||
126 | { | ||
127 | struct gpio_chip *gc = &chip->chip; | ||
128 | int ret; | ||
129 | |||
130 | BUG_ON(!chip->base); | ||
131 | BUG_ON(!gc->label); | ||
132 | BUG_ON(!gc->ngpio); | ||
133 | |||
134 | if (!gc->direction_input) | ||
135 | gc->direction_input = s3c_gpiolib_input; | ||
136 | if (!gc->direction_output) | ||
137 | gc->direction_output = s3c_gpiolib_output; | ||
138 | if (!gc->set) | ||
139 | gc->set = s3c_gpiolib_set; | ||
140 | if (!gc->get) | ||
141 | gc->get = s3c_gpiolib_get; | ||
142 | |||
143 | /* gpiochip_add() prints own failure message on error. */ | ||
144 | ret = gpiochip_add(gc); | ||
145 | if (ret >= 0) | ||
146 | s3c_gpiolib_track(chip); | ||
147 | } | ||
diff --git a/arch/arm/plat-s3c/include/mach/io.h b/arch/arm/plat-s3c/include/mach/io.h new file mode 100644 index 000000000000..10d28d66ace3 --- /dev/null +++ b/arch/arm/plat-s3c/include/mach/io.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* arch/arm/plat-s3c/include/mach/io.h | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben-linux@fluff.org> | ||
5 | * | ||
6 | * Default IO routines for plat-s3c based systems, such as S3C24A0 | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASM_ARM_ARCH_IO_H | ||
10 | #define __ASM_ARM_ARCH_IO_H | ||
11 | |||
12 | /* No current ISA/PCI bus support. */ | ||
13 | #define __io(a) ((void __iomem *)(a)) | ||
14 | #define __mem_pci(a) (a) | ||
15 | |||
16 | #define IO_SPACE_LIMIT (0xFFFFFFFF) | ||
17 | |||
18 | #endif | ||
diff --git a/arch/arm/plat-s3c/include/mach/timex.h b/arch/arm/plat-s3c/include/mach/timex.h new file mode 100644 index 000000000000..2a425ed0a7e0 --- /dev/null +++ b/arch/arm/plat-s3c/include/mach/timex.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* arch/arm/mach-s3c2410/include/mach/timex.h | ||
2 | * | ||
3 | * Copyright (c) 2003-2005 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * S3C2410 - time parameters | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_TIMEX_H | ||
14 | #define __ASM_ARCH_TIMEX_H | ||
15 | |||
16 | /* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it | ||
17 | * a variable is useless. It seems as long as we make our timers an | ||
18 | * exact multiple of HZ, any value that makes a 1->1 correspondence | ||
19 | * for the time conversion functions to/from jiffies is acceptable. | ||
20 | */ | ||
21 | |||
22 | |||
23 | #define CLOCK_TICK_RATE 12000000 | ||
24 | |||
25 | |||
26 | #endif /* __ASM_ARCH_TIMEX_H */ | ||
diff --git a/arch/arm/plat-s3c/include/mach/vmalloc.h b/arch/arm/plat-s3c/include/mach/vmalloc.h new file mode 100644 index 000000000000..bfd2ca6e3074 --- /dev/null +++ b/arch/arm/plat-s3c/include/mach/vmalloc.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* arch/arm/plat-s3c/include/mach/vmalloc.h | ||
2 | * | ||
3 | * from arch/arm/mach-iop3xx/include/mach/vmalloc.h | ||
4 | * | ||
5 | * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> | ||
6 | * http://www.simtec.co.uk/products/SWLINUX/ | ||
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 | * S3C2410 vmalloc definition | ||
13 | */ | ||
14 | |||
15 | #ifndef __ASM_ARCH_VMALLOC_H | ||
16 | #define __ASM_ARCH_VMALLOC_H | ||
17 | |||
18 | #define VMALLOC_END (0xE0000000) | ||
19 | |||
20 | #endif /* __ASM_ARCH_VMALLOC_H */ | ||
diff --git a/arch/arm/plat-s3c/include/plat/adc.h b/arch/arm/plat-s3c/include/plat/adc.h new file mode 100644 index 000000000000..43df2a404b0b --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/adc.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* arch/arm/plat-s3c/include/plat/adc.h | ||
2 | * | ||
3 | * Copyright (c) 2008 Simtec Electronics | ||
4 | * http://armlinux.simnte.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C24XX ADC driver information | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #ifndef __ASM_PLAT_ADC_H | ||
15 | #define __ASM_PLAT_ADC_H __FILE__ | ||
16 | |||
17 | struct s3c_adc_client; | ||
18 | |||
19 | extern int s3c_adc_start(struct s3c_adc_client *client, | ||
20 | unsigned int channel, unsigned int nr_samples); | ||
21 | |||
22 | extern struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev, | ||
23 | void (*select)(unsigned selected), | ||
24 | void (*conv)(unsigned d0, unsigned d1), | ||
25 | unsigned int is_ts); | ||
26 | |||
27 | extern void s3c_adc_release(struct s3c_adc_client *client); | ||
28 | |||
29 | #endif /* __ASM_PLAT_ADC_H */ | ||
diff --git a/arch/arm/plat-s3c/include/plat/clock.h b/arch/arm/plat-s3c/include/plat/clock.h new file mode 100644 index 000000000000..a10622eed43a --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/clock.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* linux/arch/arm/plat-s3c/include/plat/clock.h | ||
2 | * | ||
3 | * Copyright (c) 2004-2005 Simtec Electronics | ||
4 | * http://www.simtec.co.uk/products/SWLINUX/ | ||
5 | * Written by Ben Dooks, <ben@simtec.co.uk> | ||
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 | #include <linux/spinlock.h> | ||
13 | |||
14 | struct clk { | ||
15 | struct list_head list; | ||
16 | struct module *owner; | ||
17 | struct clk *parent; | ||
18 | const char *name; | ||
19 | int id; | ||
20 | int usage; | ||
21 | unsigned long rate; | ||
22 | unsigned long ctrlbit; | ||
23 | |||
24 | int (*enable)(struct clk *, int enable); | ||
25 | int (*set_rate)(struct clk *c, unsigned long rate); | ||
26 | unsigned long (*get_rate)(struct clk *c); | ||
27 | unsigned long (*round_rate)(struct clk *c, unsigned long rate); | ||
28 | int (*set_parent)(struct clk *c, struct clk *parent); | ||
29 | }; | ||
30 | |||
31 | /* other clocks which may be registered by board support */ | ||
32 | |||
33 | extern struct clk s3c24xx_dclk0; | ||
34 | extern struct clk s3c24xx_dclk1; | ||
35 | extern struct clk s3c24xx_clkout0; | ||
36 | extern struct clk s3c24xx_clkout1; | ||
37 | extern struct clk s3c24xx_uclk; | ||
38 | |||
39 | extern struct clk clk_usb_bus; | ||
40 | |||
41 | /* core clock support */ | ||
42 | |||
43 | extern struct clk clk_f; | ||
44 | extern struct clk clk_h; | ||
45 | extern struct clk clk_p; | ||
46 | extern struct clk clk_mpll; | ||
47 | extern struct clk clk_upll; | ||
48 | extern struct clk clk_epll; | ||
49 | extern struct clk clk_xtal; | ||
50 | extern struct clk clk_ext; | ||
51 | |||
52 | /* S3C64XX specific clocks */ | ||
53 | extern struct clk clk_27m; | ||
54 | extern struct clk clk_48m; | ||
55 | |||
56 | /* exports for arch/arm/mach-s3c2410 | ||
57 | * | ||
58 | * Please DO NOT use these outside of arch/arm/mach-s3c2410 | ||
59 | */ | ||
60 | |||
61 | extern spinlock_t clocks_lock; | ||
62 | |||
63 | extern int s3c2410_clkcon_enable(struct clk *clk, int enable); | ||
64 | |||
65 | extern int s3c24xx_register_clock(struct clk *clk); | ||
66 | extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks); | ||
67 | |||
68 | extern int s3c24xx_register_baseclocks(unsigned long xtal); | ||
69 | |||
70 | extern void s3c64xx_register_clocks(void); | ||
71 | |||
72 | extern void s3c24xx_setup_clocks(unsigned long fclk, | ||
73 | unsigned long hclk, | ||
74 | unsigned long pclk); | ||
75 | |||
76 | extern void s3c2410_setup_clocks(void); | ||
77 | extern void s3c2412_setup_clocks(void); | ||
78 | extern void s3c244x_setup_clocks(void); | ||
79 | extern void s3c2443_setup_clocks(void); | ||
80 | |||
81 | /* S3C64XX specific functions and clocks */ | ||
82 | |||
83 | extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable); | ||
84 | |||
85 | /* Init for pwm clock code */ | ||
86 | |||
87 | extern void s3c_pwmclk_init(void); | ||
88 | |||
diff --git a/arch/arm/plat-s3c/include/plat/cpu-freq.h b/arch/arm/plat-s3c/include/plat/cpu-freq.h new file mode 100644 index 000000000000..c86a13307e90 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/cpu-freq.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* arch/arm/plat-s3c/include/plat/cpu-freq.h | ||
2 | * | ||
3 | * Copyright (c) 2006,2007 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C CPU frequency scaling support - driver and board | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/cpufreq.h> | ||
15 | |||
16 | struct s3c_cpufreq_info; | ||
17 | struct s3c_cpufreq_board; | ||
18 | struct s3c_iotimings; | ||
19 | |||
20 | struct s3c_freq { | ||
21 | unsigned long fclk; | ||
22 | unsigned long armclk; | ||
23 | unsigned long hclk_tns; /* in 10ths of ns */ | ||
24 | unsigned long hclk; | ||
25 | unsigned long pclk; | ||
26 | }; | ||
27 | |||
28 | /* wrapper 'struct cpufreq_freqs' so that any drivers receiving the | ||
29 | * notification can use this information that is not provided by just | ||
30 | * having the core frequency alone. | ||
31 | */ | ||
32 | |||
33 | struct s3c_cpufreq_freqs { | ||
34 | struct cpufreq_freqs freqs; | ||
35 | struct s3c_freq old; | ||
36 | struct s3c_freq new; | ||
37 | }; | ||
38 | |||
39 | #define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs) | ||
40 | |||
41 | struct s3c_clkdivs { | ||
42 | int p_divisor; /* fclk / pclk */ | ||
43 | int h_divisor; /* fclk / hclk */ | ||
44 | int arm_divisor; /* not all cpus have this. */ | ||
45 | unsigned char dvs; /* using dvs mode to arm. */ | ||
46 | }; | ||
47 | |||
48 | #define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s)) | ||
49 | |||
50 | struct s3c_pllval { | ||
51 | unsigned long freq; | ||
52 | unsigned long pll_reg; | ||
53 | }; | ||
54 | |||
55 | struct s3c_cpufreq_config { | ||
56 | struct s3c_freq freq; | ||
57 | struct s3c_pllval pll; | ||
58 | struct s3c_clkdivs divs; | ||
59 | struct s3c_cpufreq_info *info; /* for core, not drivers */ | ||
60 | struct s3c_cpufreq_board *board; | ||
61 | }; | ||
62 | |||
63 | /* s3c_cpufreq_board | ||
64 | * | ||
65 | * per-board configuraton information, such as memory refresh and | ||
66 | * how to initialise IO timings. | ||
67 | */ | ||
68 | struct s3c_cpufreq_board { | ||
69 | unsigned int refresh; /* refresh period in ns */ | ||
70 | unsigned int auto_io:1; /* automatically init io timings. */ | ||
71 | unsigned int need_io:1; /* set if needs io timing support. */ | ||
72 | |||
73 | /* any non-zero field in here is taken as an upper limit. */ | ||
74 | struct s3c_freq max; /* frequency limits */ | ||
75 | }; | ||
76 | |||
77 | /* Things depending on frequency scaling. */ | ||
78 | #ifdef CONFIG_CPU_FREQ_S3C | ||
79 | #define __init_or_cpufreq | ||
80 | #else | ||
81 | #define __init_or_cpufreq __init | ||
82 | #endif | ||
83 | |||
84 | /* Board functions */ | ||
85 | |||
86 | #ifdef CONFIG_CPU_FREQ_S3C | ||
87 | extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board); | ||
88 | #else | ||
89 | |||
90 | static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board) | ||
91 | { | ||
92 | return 0; | ||
93 | } | ||
94 | #endif /* CONFIG_CPU_FREQ_S3C */ | ||
diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h new file mode 100644 index 000000000000..e62ae0fcfe56 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/cpu.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* linux/arch/arm/plat-s3c/include/plat/cpu.h | ||
2 | * | ||
3 | * Copyright (c) 2004-2005 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Header file for S3C24XX 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 | /* todo - fix when rmk changes iodescs to use `void __iomem *` */ | ||
14 | |||
15 | #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE } | ||
16 | |||
17 | #ifndef MHZ | ||
18 | #define MHZ (1000*1000) | ||
19 | #endif | ||
20 | |||
21 | #define print_mhz(m) ((m) / MHZ), (((m) / 1000) % 1000) | ||
22 | |||
23 | /* forward declaration */ | ||
24 | struct s3c24xx_uart_resources; | ||
25 | struct platform_device; | ||
26 | struct s3c2410_uartcfg; | ||
27 | struct map_desc; | ||
28 | |||
29 | /* per-cpu initialisation function table. */ | ||
30 | |||
31 | struct cpu_table { | ||
32 | unsigned long idcode; | ||
33 | unsigned long idmask; | ||
34 | void (*map_io)(void); | ||
35 | void (*init_uarts)(struct s3c2410_uartcfg *cfg, int no); | ||
36 | void (*init_clocks)(int xtal); | ||
37 | int (*init)(void); | ||
38 | const char *name; | ||
39 | }; | ||
40 | |||
41 | extern void s3c_init_cpu(unsigned long idcode, | ||
42 | struct cpu_table *cpus, unsigned int cputab_size); | ||
43 | |||
44 | /* core initialisation functions */ | ||
45 | |||
46 | extern void s3c24xx_init_irq(void); | ||
47 | extern void s3c64xx_init_irq(u32 vic0, u32 vic1); | ||
48 | |||
49 | extern void s3c24xx_init_io(struct map_desc *mach_desc, int size); | ||
50 | extern void s3c64xx_init_io(struct map_desc *mach_desc, int size); | ||
51 | |||
52 | extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no); | ||
53 | |||
54 | extern void s3c24xx_init_clocks(int xtal); | ||
55 | |||
56 | extern void s3c24xx_init_uartdevs(char *name, | ||
57 | struct s3c24xx_uart_resources *res, | ||
58 | struct s3c2410_uartcfg *cfg, int no); | ||
59 | |||
60 | /* timer for 2410/2440 */ | ||
61 | |||
62 | struct sys_timer; | ||
63 | extern struct sys_timer s3c24xx_timer; | ||
64 | |||
65 | /* system device classes */ | ||
66 | |||
67 | extern struct sysdev_class s3c2410_sysclass; | ||
68 | extern struct sysdev_class s3c2412_sysclass; | ||
69 | extern struct sysdev_class s3c2440_sysclass; | ||
70 | extern struct sysdev_class s3c2442_sysclass; | ||
71 | extern struct sysdev_class s3c2443_sysclass; | ||
diff --git a/arch/arm/plat-s3c/include/plat/debug-macro.S b/arch/arm/plat-s3c/include/plat/debug-macro.S index 4aa7e2e6c001..3634d4e3708b 100644 --- a/arch/arm/plat-s3c/include/plat/debug-macro.S +++ b/arch/arm/plat-s3c/include/plat/debug-macro.S | |||
@@ -20,7 +20,7 @@ | |||
20 | .endm | 20 | .endm |
21 | 21 | ||
22 | #ifndef fifo_level | 22 | #ifndef fifo_level |
23 | #define fifo_level fifo_level_s3c2410 | 23 | #define fifo_level fifo_level_s3c2440 |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | .macro fifo_full_s3c2440 rd, rx | 26 | .macro fifo_full_s3c2440 rd, rx |
diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h new file mode 100644 index 000000000000..6b1b5231511c --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/devs.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* linux/include/asm-arm/plat-s3c24xx/devs.h | ||
2 | * | ||
3 | * Copyright (c) 2004 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Header file for s3c2410 standard platform devices | ||
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 | #include <linux/platform_device.h> | ||
13 | |||
14 | struct s3c24xx_uart_resources { | ||
15 | struct resource *resources; | ||
16 | unsigned long nr_resources; | ||
17 | }; | ||
18 | |||
19 | extern struct s3c24xx_uart_resources s3c2410_uart_resources[]; | ||
20 | extern struct s3c24xx_uart_resources s3c64xx_uart_resources[]; | ||
21 | |||
22 | extern struct platform_device *s3c24xx_uart_devs[]; | ||
23 | extern struct platform_device *s3c24xx_uart_src[]; | ||
24 | |||
25 | extern struct platform_device s3c_device_timer[]; | ||
26 | |||
27 | extern struct platform_device s3c_device_fb; | ||
28 | extern struct platform_device s3c_device_usb; | ||
29 | extern struct platform_device s3c_device_lcd; | ||
30 | extern struct platform_device s3c_device_wdt; | ||
31 | extern struct platform_device s3c_device_i2c0; | ||
32 | extern struct platform_device s3c_device_i2c1; | ||
33 | extern struct platform_device s3c_device_iis; | ||
34 | extern struct platform_device s3c_device_rtc; | ||
35 | extern struct platform_device s3c_device_adc; | ||
36 | extern struct platform_device s3c_device_sdi; | ||
37 | extern struct platform_device s3c_device_hsmmc0; | ||
38 | extern struct platform_device s3c_device_hsmmc1; | ||
39 | extern struct platform_device s3c_device_hsmmc2; | ||
40 | |||
41 | extern struct platform_device s3c_device_spi0; | ||
42 | extern struct platform_device s3c_device_spi1; | ||
43 | |||
44 | extern struct platform_device s3c_device_nand; | ||
45 | |||
46 | extern struct platform_device s3c_device_usbgadget; | ||
47 | |||
48 | /* s3c2440 specific devices */ | ||
49 | |||
50 | #ifdef CONFIG_CPU_S3C2440 | ||
51 | |||
52 | extern struct platform_device s3c_device_camif; | ||
53 | |||
54 | #endif | ||
diff --git a/arch/arm/plat-s3c/include/plat/fb.h b/arch/arm/plat-s3c/include/plat/fb.h new file mode 100644 index 000000000000..214ff561b0dd --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/fb.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* linux/arch/arm/plat-s3c/include/plat/fb.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C - FB platform data definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __PLAT_S3C_FB_H | ||
16 | #define __PLAT_S3C_FB_H __FILE__ | ||
17 | |||
18 | /** | ||
19 | * struct s3c_fb_pd_win - per window setup data | ||
20 | * @win_mode: The display parameters to initialise (not for window 0) | ||
21 | * @virtual_x: The virtual X size. | ||
22 | * @virtual_y: The virtual Y size. | ||
23 | */ | ||
24 | struct s3c_fb_pd_win { | ||
25 | struct fb_videomode win_mode; | ||
26 | |||
27 | unsigned short default_bpp; | ||
28 | unsigned short max_bpp; | ||
29 | unsigned short virtual_x; | ||
30 | unsigned short virtual_y; | ||
31 | }; | ||
32 | |||
33 | /** | ||
34 | * struct s3c_fb_platdata - S3C driver platform specific information | ||
35 | * @setup_gpio: Setup the external GPIO pins to the right state to transfer | ||
36 | * the data from the display system to the connected display | ||
37 | * device. | ||
38 | * @vidcon0: The base vidcon0 values to control the panel data format. | ||
39 | * @vidcon1: The base vidcon1 values to control the panel data output. | ||
40 | * @win: The setup data for each hardware window, or NULL for unused. | ||
41 | * @display_mode: The LCD output display mode. | ||
42 | * | ||
43 | * The platform data supplies the video driver with all the information | ||
44 | * it requires to work with the display(s) attached to the machine. It | ||
45 | * controls the initial mode, the number of display windows (0 is always | ||
46 | * the base framebuffer) that are initialised etc. | ||
47 | * | ||
48 | */ | ||
49 | struct s3c_fb_platdata { | ||
50 | void (*setup_gpio)(void); | ||
51 | |||
52 | struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN]; | ||
53 | |||
54 | u32 vidcon0; | ||
55 | u32 vidcon1; | ||
56 | }; | ||
57 | |||
58 | /** | ||
59 | * s3c_fb_set_platdata() - Setup the FB device with platform data. | ||
60 | * @pd: The platform data to set. The data is copied from the passed structure | ||
61 | * so the machine data can mark the data __initdata so that any unused | ||
62 | * machines will end up dumping their data at runtime. | ||
63 | */ | ||
64 | extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd); | ||
65 | |||
66 | /** | ||
67 | * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD | ||
68 | * | ||
69 | * Initialise the GPIO for an 24bpp LCD display on the RGB interface. | ||
70 | */ | ||
71 | extern void s3c64xx_fb_gpio_setup_24bpp(void); | ||
72 | |||
73 | #endif /* __PLAT_S3C_FB_H */ | ||
diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h new file mode 100644 index 000000000000..652e2bbdaa20 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h | |||
@@ -0,0 +1,176 @@ | |||
1 | /* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C Platform - GPIO pin configuration helper definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | /* This is meant for core cpu support, machine or other driver files | ||
16 | * should not be including this header. | ||
17 | */ | ||
18 | |||
19 | #ifndef __PLAT_GPIO_CFG_HELPERS_H | ||
20 | #define __PLAT_GPIO_CFG_HELPERS_H __FILE__ | ||
21 | |||
22 | /* As a note, all gpio configuration functions are entered exclusively, either | ||
23 | * with the relevant lock held or the system prevented from doing anything else | ||
24 | * by disabling interrupts. | ||
25 | */ | ||
26 | |||
27 | static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip, | ||
28 | unsigned int off, unsigned int config) | ||
29 | { | ||
30 | return (chip->config->set_config)(chip, off, config); | ||
31 | } | ||
32 | |||
33 | static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip, | ||
34 | unsigned int off, s3c_gpio_pull_t pull) | ||
35 | { | ||
36 | return (chip->config->set_pull)(chip, off, pull); | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration. | ||
41 | * @chip: The gpio chip that is being configured. | ||
42 | * @off: The offset for the GPIO being configured. | ||
43 | * @cfg: The configuration value to set. | ||
44 | * | ||
45 | * This helper deal with the GPIO cases where the control register | ||
46 | * has two bits of configuration per gpio, which have the following | ||
47 | * functions: | ||
48 | * 00 = input | ||
49 | * 01 = output | ||
50 | * 1x = special function | ||
51 | */ | ||
52 | extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, | ||
53 | unsigned int off, unsigned int cfg); | ||
54 | |||
55 | /** | ||
56 | * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A) | ||
57 | * @chip: The gpio chip that is being configured. | ||
58 | * @off: The offset for the GPIO being configured. | ||
59 | * @cfg: The configuration value to set. | ||
60 | * | ||
61 | * This helper deal with the GPIO cases where the control register | ||
62 | * has one bit of configuration for the gpio, where setting the bit | ||
63 | * means the pin is in special function mode and unset means output. | ||
64 | */ | ||
65 | extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, | ||
66 | unsigned int off, unsigned int cfg); | ||
67 | |||
68 | /** | ||
69 | * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config. | ||
70 | * @chip: The gpio chip that is being configured. | ||
71 | * @off: The offset for the GPIO being configured. | ||
72 | * @cfg: The configuration value to set. | ||
73 | * | ||
74 | * This helper deal with the GPIO cases where the control register has 4 bits | ||
75 | * of control per GPIO, generally in the form of: | ||
76 | * 0000 = Input | ||
77 | * 0001 = Output | ||
78 | * others = Special functions (dependant on bank) | ||
79 | * | ||
80 | * Note, since the code to deal with the case where there are two control | ||
81 | * registers instead of one, we do not have a seperate set of functions for | ||
82 | * each case. | ||
83 | */ | ||
84 | extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, | ||
85 | unsigned int off, unsigned int cfg); | ||
86 | |||
87 | |||
88 | /* Pull-{up,down} resistor controls. | ||
89 | * | ||
90 | * S3C2410,S3C2440,S3C24A0 = Pull-UP, | ||
91 | * S3C2412,S3C2413 = Pull-Down | ||
92 | * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef] | ||
93 | * S3C2443 = Pull-Both [not same as S3C6400] | ||
94 | */ | ||
95 | |||
96 | /** | ||
97 | * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none. | ||
98 | * @chip: The gpio chip that is being configured. | ||
99 | * @off: The offset for the GPIO being configured. | ||
100 | * @param: pull: The pull mode being requested. | ||
101 | * | ||
102 | * This is a helper function for the case where we have GPIOs with one | ||
103 | * bit configuring the presence of a pull-up resistor. | ||
104 | */ | ||
105 | extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, | ||
106 | unsigned int off, s3c_gpio_pull_t pull); | ||
107 | |||
108 | /** | ||
109 | * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none | ||
110 | * @chip: The gpio chip that is being configured | ||
111 | * @off: The offset for the GPIO being configured | ||
112 | * @param: pull: The pull mode being requested | ||
113 | * | ||
114 | * This is a helper function for the case where we have GPIOs with one | ||
115 | * bit configuring the presence of a pull-down resistor. | ||
116 | */ | ||
117 | extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, | ||
118 | unsigned int off, s3c_gpio_pull_t pull); | ||
119 | |||
120 | /** | ||
121 | * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none | ||
122 | * @chip: The gpio chip that is being configured. | ||
123 | * @off: The offset for the GPIO being configured. | ||
124 | * @param: pull: The pull mode being requested. | ||
125 | * | ||
126 | * This is a helper function for the case where we have GPIOs with two | ||
127 | * bits configuring the presence of a pull resistor, in the following | ||
128 | * order: | ||
129 | * 00 = No pull resistor connected | ||
130 | * 01 = Pull-up resistor connected | ||
131 | * 10 = Pull-down resistor connected | ||
132 | */ | ||
133 | extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip, | ||
134 | unsigned int off, s3c_gpio_pull_t pull); | ||
135 | |||
136 | |||
137 | /** | ||
138 | * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none | ||
139 | * @chip: The gpio chip that the GPIO pin belongs to | ||
140 | * @off: The offset to the pin to get the configuration of. | ||
141 | * | ||
142 | * This helper function reads the state of the pull-{up,down} resistor for the | ||
143 | * given GPIO in the same case as s3c_gpio_setpull_upown. | ||
144 | */ | ||
145 | extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, | ||
146 | unsigned int off); | ||
147 | |||
148 | /** | ||
149 | * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. | ||
150 | * @chip: The gpio chip that is being configured. | ||
151 | * @off: The offset for the GPIO being configured. | ||
152 | * @param: pull: The pull mode being requested. | ||
153 | * | ||
154 | * This is a helper function for the case where we have GPIOs with two | ||
155 | * bits configuring the presence of a pull resistor, in the following | ||
156 | * order: | ||
157 | * 00 = Pull-up resistor connected | ||
158 | * 10 = Pull-down resistor connected | ||
159 | * x1 = No pull up resistor | ||
160 | */ | ||
161 | extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip, | ||
162 | unsigned int off, s3c_gpio_pull_t pull); | ||
163 | |||
164 | /** | ||
165 | * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors | ||
166 | * @chip: The gpio chip that the GPIO pin belongs to. | ||
167 | * @off: The offset to the pin to get the configuration of. | ||
168 | * | ||
169 | * This helper function reads the state of the pull-{up,down} resistor for the | ||
170 | * given GPIO in the same case as s3c_gpio_setpull_upown. | ||
171 | */ | ||
172 | extern s3c_gpio_pull_t s3c_gpio_getpull_s3c24xx(struct s3c_gpio_chip *chip, | ||
173 | unsigned int off); | ||
174 | |||
175 | #endif /* __PLAT_GPIO_CFG_HELPERS_H */ | ||
176 | |||
diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg.h b/arch/arm/plat-s3c/include/plat/gpio-cfg.h new file mode 100644 index 000000000000..29cd6a86cade --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/gpio-cfg.h | |||
@@ -0,0 +1,110 @@ | |||
1 | /* linux/arch/arm/plat-s3c/include/plat/gpio-cfg.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C Platform - GPIO pin configuration | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | /* This file contains the necessary definitions to get the basic gpio | ||
16 | * pin configuration done such as setting a pin to input or output or | ||
17 | * changing the pull-{up,down} configurations. | ||
18 | */ | ||
19 | |||
20 | /* Note, this interface is being added to the s3c64xx arch first and will | ||
21 | * be added to the s3c24xx systems later. | ||
22 | */ | ||
23 | |||
24 | #ifndef __PLAT_GPIO_CFG_H | ||
25 | #define __PLAT_GPIO_CFG_H __FILE__ | ||
26 | |||
27 | typedef unsigned int __bitwise__ s3c_gpio_pull_t; | ||
28 | |||
29 | /* forward declaration if gpio-core.h hasn't been included */ | ||
30 | struct s3c_gpio_chip; | ||
31 | |||
32 | /** | ||
33 | * struct s3c_gpio_cfg GPIO configuration | ||
34 | * @cfg_eint: Configuration setting when used for external interrupt source | ||
35 | * @get_pull: Read the current pull configuration for the GPIO | ||
36 | * @set_pull: Set the current pull configuraiton for the GPIO | ||
37 | * @set_config: Set the current configuration for the GPIO | ||
38 | * @get_config: Read the current configuration for the GPIO | ||
39 | * | ||
40 | * Each chip can have more than one type of GPIO bank available and some | ||
41 | * have different capabilites even when they have the same control register | ||
42 | * layouts. Provide an point to vector control routine and provide any | ||
43 | * per-bank configuration information that other systems such as the | ||
44 | * external interrupt code will need. | ||
45 | */ | ||
46 | struct s3c_gpio_cfg { | ||
47 | unsigned int cfg_eint; | ||
48 | |||
49 | s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs); | ||
50 | int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs, | ||
51 | s3c_gpio_pull_t pull); | ||
52 | |||
53 | unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs); | ||
54 | int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs, | ||
55 | unsigned config); | ||
56 | }; | ||
57 | |||
58 | #define S3C_GPIO_SPECIAL_MARK (0xfffffff0) | ||
59 | #define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x)) | ||
60 | |||
61 | /* Defines for generic pin configurations */ | ||
62 | #define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0)) | ||
63 | #define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1)) | ||
64 | #define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x)) | ||
65 | |||
66 | #define s3c_gpio_is_cfg_special(_cfg) \ | ||
67 | (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK) | ||
68 | |||
69 | /** | ||
70 | * s3c_gpio_cfgpin() - Change the GPIO function of a pin. | ||
71 | * @pin pin The pin number to configure. | ||
72 | * @pin to The configuration for the pin's function. | ||
73 | * | ||
74 | * Configure which function is actually connected to the external | ||
75 | * pin, such as an gpio input, output or some form of special function | ||
76 | * connected to an internal peripheral block. | ||
77 | */ | ||
78 | extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); | ||
79 | |||
80 | /* Define values for the pull-{up,down} available for each gpio pin. | ||
81 | * | ||
82 | * These values control the state of the weak pull-{up,down} resistors | ||
83 | * available on most pins on the S3C series. Not all chips support both | ||
84 | * up or down settings, and it may be dependant on the chip that is being | ||
85 | * used to whether the particular mode is available. | ||
86 | */ | ||
87 | #define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00) | ||
88 | #define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01) | ||
89 | #define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02) | ||
90 | |||
91 | /** | ||
92 | * s3c_gpio_setpull() - set the state of a gpio pin pull resistor | ||
93 | * @pin: The pin number to configure the pull resistor. | ||
94 | * @pull: The configuration for the pull resistor. | ||
95 | * | ||
96 | * This function sets the state of the pull-{up,down} resistor for the | ||
97 | * specified pin. It will return 0 if successfull, or a negative error | ||
98 | * code if the pin cannot support the requested pull setting. | ||
99 | */ | ||
100 | extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); | ||
101 | |||
102 | /** | ||
103 | * s3c_gpio_getpull() - get the pull resistor state of a gpio pin | ||
104 | * @pin: The pin number to get the settings for | ||
105 | * | ||
106 | * Read the pull resistor value for the specified pin. | ||
107 | */ | ||
108 | extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); | ||
109 | |||
110 | #endif /* __PLAT_GPIO_CFG_H */ | ||
diff --git a/arch/arm/plat-s3c/include/plat/gpio-core.h b/arch/arm/plat-s3c/include/plat/gpio-core.h new file mode 100644 index 000000000000..2fc60a580ac8 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/gpio-core.h | |||
@@ -0,0 +1,77 @@ | |||
1 | /* linux/arch/arm/plat-s3c/include/plat/gpio-core.h | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C Platform - GPIO core | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | /* Define the core gpiolib support functions that the s3c platforms may | ||
15 | * need to extend or change depending on the hardware and the s3c chip | ||
16 | * selected at build or found at run time. | ||
17 | * | ||
18 | * These definitions are not intended for driver inclusion, there is | ||
19 | * nothing here that should not live outside the platform and core | ||
20 | * specific code. | ||
21 | */ | ||
22 | |||
23 | struct s3c_gpio_cfg; | ||
24 | |||
25 | /** | ||
26 | * struct s3c_gpio_chip - wrapper for specific implementation of gpio | ||
27 | * @chip: The chip structure to be exported via gpiolib. | ||
28 | * @base: The base pointer to the gpio configuration registers. | ||
29 | * @config: special function and pull-resistor control information. | ||
30 | * | ||
31 | * This wrapper provides the necessary information for the Samsung | ||
32 | * specific gpios being registered with gpiolib. | ||
33 | */ | ||
34 | struct s3c_gpio_chip { | ||
35 | struct gpio_chip chip; | ||
36 | struct s3c_gpio_cfg *config; | ||
37 | void __iomem *base; | ||
38 | }; | ||
39 | |||
40 | static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc) | ||
41 | { | ||
42 | return container_of(gpc, struct s3c_gpio_chip, chip); | ||
43 | } | ||
44 | |||
45 | /** s3c_gpiolib_add() - add the s3c specific version of a gpio_chip. | ||
46 | * @chip: The chip to register | ||
47 | * | ||
48 | * This is a wrapper to gpiochip_add() that takes our specific gpio chip | ||
49 | * information and makes the necessary alterations for the platform and | ||
50 | * notes the information for use with the configuration systems and any | ||
51 | * other parts of the system. | ||
52 | */ | ||
53 | extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip); | ||
54 | |||
55 | /* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios | ||
56 | * for use with the configuration calls, and other parts of the s3c gpiolib | ||
57 | * support code. | ||
58 | * | ||
59 | * Not all s3c support code will need this, as some configurations of cpu | ||
60 | * may only support one or two different configuration options and have an | ||
61 | * easy gpio to s3c_gpio_chip mapping function. If this is the case, then | ||
62 | * the machine support file should provide its own s3c_gpiolib_getchip() | ||
63 | * and any other necessary functions. | ||
64 | */ | ||
65 | |||
66 | #ifdef CONFIG_S3C_GPIO_TRACK | ||
67 | extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; | ||
68 | |||
69 | static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip) | ||
70 | { | ||
71 | return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL; | ||
72 | } | ||
73 | #else | ||
74 | /* machine specific code should provide s3c_gpiolib_getchip */ | ||
75 | |||
76 | static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { } | ||
77 | #endif | ||
diff --git a/arch/arm/plat-s3c/include/plat/iic-core.h b/arch/arm/plat-s3c/include/plat/iic-core.h new file mode 100644 index 000000000000..36397ca20962 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/iic-core.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* arch/arm/mach-s3c2410/include/mach/iic-core.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C - I2C Controller core functions | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #ifndef __ASM_ARCH_IIC_CORE_H | ||
15 | #define __ASM_ARCH_IIC_CORE_H __FILE__ | ||
16 | |||
17 | /* These functions are only for use with the core support code, such as | ||
18 | * the cpu specific initialisation code | ||
19 | */ | ||
20 | |||
21 | /* re-define device name depending on support. */ | ||
22 | static inline void s3c_i2c0_setname(char *name) | ||
23 | { | ||
24 | /* currently this device is always compiled in */ | ||
25 | s3c_device_i2c0.name = name; | ||
26 | } | ||
27 | |||
28 | static inline void s3c_i2c1_setname(char *name) | ||
29 | { | ||
30 | #ifdef CONFIG_S3C_DEV_I2C1 | ||
31 | s3c_device_i2c1.name = name; | ||
32 | #endif | ||
33 | } | ||
34 | |||
35 | #endif /* __ASM_ARCH_IIC_H */ | ||
diff --git a/arch/arm/plat-s3c/include/plat/iic.h b/arch/arm/plat-s3c/include/plat/iic.h index 5106acaa1d0e..dc1dfcb9bc6c 100644 --- a/arch/arm/plat-s3c/include/plat/iic.h +++ b/arch/arm/plat-s3c/include/plat/iic.h | |||
@@ -28,6 +28,30 @@ struct s3c2410_platform_i2c { | |||
28 | unsigned long max_freq; /* max frequency for the bus */ | 28 | unsigned long max_freq; /* max frequency for the bus */ |
29 | unsigned long min_freq; /* min frequency for the bus */ | 29 | unsigned long min_freq; /* min frequency for the bus */ |
30 | unsigned int sda_delay; /* pclks (s3c2440 only) */ | 30 | unsigned int sda_delay; /* pclks (s3c2440 only) */ |
31 | |||
32 | void (*cfg_gpio)(struct platform_device *dev); | ||
31 | }; | 33 | }; |
32 | 34 | ||
35 | /** | ||
36 | * s3c_i2c0_set_platdata - set platform data for i2c0 device | ||
37 | * @i2c: The platform data to set, or NULL for default data. | ||
38 | * | ||
39 | * Register the given platform data for use with the i2c0 device. This | ||
40 | * call copies the platform data, so the caller can use __initdata for | ||
41 | * their copy. | ||
42 | * | ||
43 | * This call will set cfg_gpio if is null to the default platform | ||
44 | * implementation. | ||
45 | * | ||
46 | * Any user of s3c_device_i2c0 should call this, even if it is with | ||
47 | * NULL to ensure that the device is given the default platform data | ||
48 | * as the driver will no longer carry defaults. | ||
49 | */ | ||
50 | extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
51 | extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
52 | |||
53 | /* defined by architecture to configure gpio */ | ||
54 | extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); | ||
55 | extern void s3c_i2c1_cfg_gpio(struct platform_device *dev); | ||
56 | |||
33 | #endif /* __ASM_ARCH_IIC_H */ | 57 | #endif /* __ASM_ARCH_IIC_H */ |
diff --git a/arch/arm/plat-s3c/include/plat/map.h b/arch/arm/plat-s3c/include/plat/map-base.h index b84289d32a54..b84289d32a54 100644 --- a/arch/arm/plat-s3c/include/plat/map.h +++ b/arch/arm/plat-s3c/include/plat/map-base.h | |||
diff --git a/arch/arm/plat-s3c/include/plat/regs-fb.h b/arch/arm/plat-s3c/include/plat/regs-fb.h new file mode 100644 index 000000000000..e9ee599d430e --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/regs-fb.h | |||
@@ -0,0 +1,366 @@ | |||
1 | /* arch/arm/plat-s3c/include/plat/regs-fb.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C Platform - new-style framebuffer register definitions | ||
9 | * | ||
10 | * This is the register set for the new style framebuffer interface | ||
11 | * found from the S3C2443 onwards into the S3C2416, S3C2450 and the | ||
12 | * S3C64XX series such as the S3C6400 and S3C6410. | ||
13 | * | ||
14 | * The file does not contain the cpu specific items which are based on | ||
15 | * whichever architecture is selected, it only contains the core of the | ||
16 | * register set. See <mach/regs-fb.h> to get the specifics. | ||
17 | * | ||
18 | * Note, we changed to using regs-fb.h as it avoids any clashes with | ||
19 | * the original regs-lcd.h so out of the way of regs-lcd.h as well as | ||
20 | * indicating the newer block is much more than just an LCD interface. | ||
21 | * | ||
22 | * This program is free software; you can redistribute it and/or modify | ||
23 | * it under the terms of the GNU General Public License version 2 as | ||
24 | * published by the Free Software Foundation. | ||
25 | */ | ||
26 | |||
27 | /* Please do not include this file directly, use <mach/regs-fb.h> to | ||
28 | * ensure all the localised SoC support is included as necessary. | ||
29 | */ | ||
30 | |||
31 | /* VIDCON0 */ | ||
32 | |||
33 | #define VIDCON0 (0x00) | ||
34 | #define VIDCON0_INTERLACE (1 << 29) | ||
35 | #define VIDCON0_VIDOUT_MASK (0x3 << 26) | ||
36 | #define VIDCON0_VIDOUT_SHIFT (26) | ||
37 | #define VIDCON0_VIDOUT_RGB (0x0 << 26) | ||
38 | #define VIDCON0_VIDOUT_TV (0x1 << 26) | ||
39 | #define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26) | ||
40 | #define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26) | ||
41 | |||
42 | #define VIDCON0_L1_DATA_MASK (0x7 << 23) | ||
43 | #define VIDCON0_L1_DATA_SHIFT (23) | ||
44 | #define VIDCON0_L1_DATA_16BPP (0x0 << 23) | ||
45 | #define VIDCON0_L1_DATA_18BPP16 (0x1 << 23) | ||
46 | #define VIDCON0_L1_DATA_18BPP9 (0x2 << 23) | ||
47 | #define VIDCON0_L1_DATA_24BPP (0x3 << 23) | ||
48 | #define VIDCON0_L1_DATA_18BPP (0x4 << 23) | ||
49 | #define VIDCON0_L1_DATA_16BPP8 (0x5 << 23) | ||
50 | |||
51 | #define VIDCON0_L0_DATA_MASK (0x7 << 20) | ||
52 | #define VIDCON0_L0_DATA_SHIFT (20) | ||
53 | #define VIDCON0_L0_DATA_16BPP (0x0 << 20) | ||
54 | #define VIDCON0_L0_DATA_18BPP16 (0x1 << 20) | ||
55 | #define VIDCON0_L0_DATA_18BPP9 (0x2 << 20) | ||
56 | #define VIDCON0_L0_DATA_24BPP (0x3 << 20) | ||
57 | #define VIDCON0_L0_DATA_18BPP (0x4 << 20) | ||
58 | #define VIDCON0_L0_DATA_16BPP8 (0x5 << 20) | ||
59 | |||
60 | #define VIDCON0_PNRMODE_MASK (0x3 << 17) | ||
61 | #define VIDCON0_PNRMODE_SHIFT (17) | ||
62 | #define VIDCON0_PNRMODE_RGB (0x0 << 17) | ||
63 | #define VIDCON0_PNRMODE_BGR (0x1 << 17) | ||
64 | #define VIDCON0_PNRMODE_SERIAL_RGB (0x2 << 17) | ||
65 | #define VIDCON0_PNRMODE_SERIAL_BGR (0x3 << 17) | ||
66 | |||
67 | #define VIDCON0_CLKVALUP (1 << 16) | ||
68 | #define VIDCON0_CLKVAL_F_MASK (0xff << 6) | ||
69 | #define VIDCON0_CLKVAL_F_SHIFT (6) | ||
70 | #define VIDCON0_CLKVAL_F_LIMIT (0xff) | ||
71 | #define VIDCON0_CLKVAL_F(_x) ((_x) << 6) | ||
72 | #define VIDCON0_VLCKFREE (1 << 5) | ||
73 | #define VIDCON0_CLKDIR (1 << 4) | ||
74 | |||
75 | #define VIDCON0_CLKSEL_MASK (0x3 << 2) | ||
76 | #define VIDCON0_CLKSEL_SHIFT (2) | ||
77 | #define VIDCON0_CLKSEL_HCLK (0x0 << 2) | ||
78 | #define VIDCON0_CLKSEL_LCD (0x1 << 2) | ||
79 | #define VIDCON0_CLKSEL_27M (0x3 << 2) | ||
80 | |||
81 | #define VIDCON0_ENVID (1 << 1) | ||
82 | #define VIDCON0_ENVID_F (1 << 0) | ||
83 | |||
84 | #define VIDCON1 (0x04) | ||
85 | #define VIDCON1_LINECNT_MASK (0x7ff << 16) | ||
86 | #define VIDCON1_LINECNT_SHIFT (16) | ||
87 | #define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff) | ||
88 | #define VIDCON1_VSTATUS_MASK (0x3 << 13) | ||
89 | #define VIDCON1_VSTATUS_SHIFT (13) | ||
90 | #define VIDCON1_VSTATUS_VSYNC (0x0 << 13) | ||
91 | #define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13) | ||
92 | #define VIDCON1_VSTATUS_ACTIVE (0x2 << 13) | ||
93 | #define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13) | ||
94 | |||
95 | #define VIDCON1_INV_VCLK (1 << 7) | ||
96 | #define VIDCON1_INV_HSYNC (1 << 6) | ||
97 | #define VIDCON1_INV_VSYNC (1 << 5) | ||
98 | #define VIDCON1_INV_VDEN (1 << 4) | ||
99 | |||
100 | /* VIDCON2 */ | ||
101 | |||
102 | #define VIDCON2 (0x08) | ||
103 | #define VIDCON2_EN601 (1 << 23) | ||
104 | #define VIDCON2_TVFMTSEL_SW (1 << 14) | ||
105 | |||
106 | #define VIDCON2_TVFMTSEL1_MASK (0x3 << 12) | ||
107 | #define VIDCON2_TVFMTSEL1_SHIFT (12) | ||
108 | #define VIDCON2_TVFMTSEL1_RGB (0x0 << 12) | ||
109 | #define VIDCON2_TVFMTSEL1_YUV422 (0x1 << 12) | ||
110 | #define VIDCON2_TVFMTSEL1_YUV444 (0x2 << 12) | ||
111 | |||
112 | #define VIDCON2_ORGYCbCr (1 << 8) | ||
113 | #define VIDCON2_YUVORDCrCb (1 << 7) | ||
114 | |||
115 | /* VIDTCON0 */ | ||
116 | |||
117 | #define VIDTCON0_VBPDE_MASK (0xff << 24) | ||
118 | #define VIDTCON0_VBPDE_SHIFT (24) | ||
119 | #define VIDTCON0_VBPDE_LIMIT (0xff) | ||
120 | #define VIDTCON0_VBPDE(_x) ((_x) << 24) | ||
121 | |||
122 | #define VIDTCON0_VBPD_MASK (0xff << 16) | ||
123 | #define VIDTCON0_VBPD_SHIFT (16) | ||
124 | #define VIDTCON0_VBPD_LIMIT (0xff) | ||
125 | #define VIDTCON0_VBPD(_x) ((_x) << 16) | ||
126 | |||
127 | #define VIDTCON0_VFPD_MASK (0xff << 8) | ||
128 | #define VIDTCON0_VFPD_SHIFT (8) | ||
129 | #define VIDTCON0_VFPD_LIMIT (0xff) | ||
130 | #define VIDTCON0_VFPD(_x) ((_x) << 8) | ||
131 | |||
132 | #define VIDTCON0_VSPW_MASK (0xff << 0) | ||
133 | #define VIDTCON0_VSPW_SHIFT (0) | ||
134 | #define VIDTCON0_VSPW_LIMIT (0xff) | ||
135 | #define VIDTCON0_VSPW(_x) ((_x) << 0) | ||
136 | |||
137 | /* VIDTCON1 */ | ||
138 | |||
139 | #define VIDTCON1_VFPDE_MASK (0xff << 24) | ||
140 | #define VIDTCON1_VFPDE_SHIFT (24) | ||
141 | #define VIDTCON1_VFPDE_LIMIT (0xff) | ||
142 | #define VIDTCON1_VFPDE(_x) ((_x) << 24) | ||
143 | |||
144 | #define VIDTCON1_HBPD_MASK (0xff << 16) | ||
145 | #define VIDTCON1_HBPD_SHIFT (16) | ||
146 | #define VIDTCON1_HBPD_LIMIT (0xff) | ||
147 | #define VIDTCON1_HBPD(_x) ((_x) << 16) | ||
148 | |||
149 | #define VIDTCON1_HFPD_MASK (0xff << 8) | ||
150 | #define VIDTCON1_HFPD_SHIFT (8) | ||
151 | #define VIDTCON1_HFPD_LIMIT (0xff) | ||
152 | #define VIDTCON1_HFPD(_x) ((_x) << 8) | ||
153 | |||
154 | #define VIDTCON1_HSPW_MASK (0xff << 0) | ||
155 | #define VIDTCON1_HSPW_SHIFT (0) | ||
156 | #define VIDTCON1_HSPW_LIMIT (0xff) | ||
157 | #define VIDTCON1_HSPW(_x) ((_x) << 0) | ||
158 | |||
159 | #define VIDTCON2 (0x18) | ||
160 | #define VIDTCON2_LINEVAL_MASK (0x7ff << 11) | ||
161 | #define VIDTCON2_LINEVAL_SHIFT (11) | ||
162 | #define VIDTCON2_LINEVAL_LIMIT (0x7ff) | ||
163 | #define VIDTCON2_LINEVAL(_x) ((_x) << 11) | ||
164 | |||
165 | #define VIDTCON2_HOZVAL_MASK (0x7ff << 0) | ||
166 | #define VIDTCON2_HOZVAL_SHIFT (0) | ||
167 | #define VIDTCON2_HOZVAL_LIMIT (0x7ff) | ||
168 | #define VIDTCON2_HOZVAL(_x) ((_x) << 0) | ||
169 | |||
170 | /* WINCONx */ | ||
171 | |||
172 | |||
173 | #define WINCONx_BITSWP (1 << 18) | ||
174 | #define WINCONx_BYTSWP (1 << 17) | ||
175 | #define WINCONx_HAWSWP (1 << 16) | ||
176 | #define WINCONx_BURSTLEN_MASK (0x3 << 9) | ||
177 | #define WINCONx_BURSTLEN_SHIFT (9) | ||
178 | #define WINCONx_BURSTLEN_16WORD (0x0 << 9) | ||
179 | #define WINCONx_BURSTLEN_8WORD (0x1 << 9) | ||
180 | #define WINCONx_BURSTLEN_4WORD (0x2 << 9) | ||
181 | |||
182 | #define WINCONx_ENWIN (1 << 0) | ||
183 | #define WINCON0_BPPMODE_MASK (0xf << 2) | ||
184 | #define WINCON0_BPPMODE_SHIFT (2) | ||
185 | #define WINCON0_BPPMODE_1BPP (0x0 << 2) | ||
186 | #define WINCON0_BPPMODE_2BPP (0x1 << 2) | ||
187 | #define WINCON0_BPPMODE_4BPP (0x2 << 2) | ||
188 | #define WINCON0_BPPMODE_8BPP_PALETTE (0x3 << 2) | ||
189 | #define WINCON0_BPPMODE_16BPP_565 (0x5 << 2) | ||
190 | #define WINCON0_BPPMODE_16BPP_1555 (0x7 << 2) | ||
191 | #define WINCON0_BPPMODE_18BPP_666 (0x8 << 2) | ||
192 | #define WINCON0_BPPMODE_24BPP_888 (0xb << 2) | ||
193 | |||
194 | #define WINCON1_BLD_PIX (1 << 6) | ||
195 | |||
196 | #define WINCON1_ALPHA_SEL (1 << 1) | ||
197 | #define WINCON1_BPPMODE_MASK (0xf << 2) | ||
198 | #define WINCON1_BPPMODE_SHIFT (2) | ||
199 | #define WINCON1_BPPMODE_1BPP (0x0 << 2) | ||
200 | #define WINCON1_BPPMODE_2BPP (0x1 << 2) | ||
201 | #define WINCON1_BPPMODE_4BPP (0x2 << 2) | ||
202 | #define WINCON1_BPPMODE_8BPP_PALETTE (0x3 << 2) | ||
203 | #define WINCON1_BPPMODE_8BPP_1232 (0x4 << 2) | ||
204 | #define WINCON1_BPPMODE_16BPP_565 (0x5 << 2) | ||
205 | #define WINCON1_BPPMODE_16BPP_A1555 (0x6 << 2) | ||
206 | #define WINCON1_BPPMODE_16BPP_I1555 (0x7 << 2) | ||
207 | #define WINCON1_BPPMODE_18BPP_666 (0x8 << 2) | ||
208 | #define WINCON1_BPPMODE_18BPP_A1665 (0x9 << 2) | ||
209 | #define WINCON1_BPPMODE_19BPP_A1666 (0xa << 2) | ||
210 | #define WINCON1_BPPMODE_24BPP_888 (0xb << 2) | ||
211 | #define WINCON1_BPPMODE_24BPP_A1887 (0xc << 2) | ||
212 | #define WINCON1_BPPMODE_25BPP_A1888 (0xd << 2) | ||
213 | #define WINCON1_BPPMODE_28BPP_A4888 (0xd << 2) | ||
214 | |||
215 | |||
216 | #define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11) | ||
217 | #define VIDOSDxA_TOPLEFT_X_SHIFT (11) | ||
218 | #define VIDOSDxA_TOPLEFT_X_LIMIT (0x7ff) | ||
219 | #define VIDOSDxA_TOPLEFT_X(_x) ((_x) << 11) | ||
220 | |||
221 | #define VIDOSDxA_TOPLEFT_Y_MASK (0x7ff << 0) | ||
222 | #define VIDOSDxA_TOPLEFT_Y_SHIFT (0) | ||
223 | #define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff) | ||
224 | #define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0) | ||
225 | |||
226 | #define VIDOSDxB_BOTRIGHT_X_MASK (0x7ff << 11) | ||
227 | #define VIDOSDxB_BOTRIGHT_X_SHIFT (11) | ||
228 | #define VIDOSDxB_BOTRIGHT_X_LIMIT (0x7ff) | ||
229 | #define VIDOSDxB_BOTRIGHT_X(_x) ((_x) << 11) | ||
230 | |||
231 | #define VIDOSDxB_BOTRIGHT_Y_MASK (0x7ff << 0) | ||
232 | #define VIDOSDxB_BOTRIGHT_Y_SHIFT (0) | ||
233 | #define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff) | ||
234 | #define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0) | ||
235 | |||
236 | /* For VIDOSD[1..4]C */ | ||
237 | #define VIDISD14C_ALPHA0_R(_x) ((_x) << 20) | ||
238 | #define VIDISD14C_ALPHA0_G_MASK (0xf << 16) | ||
239 | #define VIDISD14C_ALPHA0_G_SHIFT (16) | ||
240 | #define VIDISD14C_ALPHA0_G_LIMIT (0xf) | ||
241 | #define VIDISD14C_ALPHA0_G(_x) ((_x) << 16) | ||
242 | #define VIDISD14C_ALPHA0_B_MASK (0xf << 12) | ||
243 | #define VIDISD14C_ALPHA0_B_SHIFT (12) | ||
244 | #define VIDISD14C_ALPHA0_B_LIMIT (0xf) | ||
245 | #define VIDISD14C_ALPHA0_B(_x) ((_x) << 12) | ||
246 | #define VIDISD14C_ALPHA1_R_MASK (0xf << 8) | ||
247 | #define VIDISD14C_ALPHA1_R_SHIFT (8) | ||
248 | #define VIDISD14C_ALPHA1_R_LIMIT (0xf) | ||
249 | #define VIDISD14C_ALPHA1_R(_x) ((_x) << 8) | ||
250 | #define VIDISD14C_ALPHA1_G_MASK (0xf << 4) | ||
251 | #define VIDISD14C_ALPHA1_G_SHIFT (4) | ||
252 | #define VIDISD14C_ALPHA1_G_LIMIT (0xf) | ||
253 | #define VIDISD14C_ALPHA1_G(_x) ((_x) << 4) | ||
254 | #define VIDISD14C_ALPHA1_B_MASK (0xf << 0) | ||
255 | #define VIDISD14C_ALPHA1_B_SHIFT (0) | ||
256 | #define VIDISD14C_ALPHA1_B_LIMIT (0xf) | ||
257 | #define VIDISD14C_ALPHA1_B(_x) ((_x) << 0) | ||
258 | |||
259 | /* Video buffer addresses */ | ||
260 | #define VIDW_BUF_START(_buff) (0xA0 + ((_buff) * 8)) | ||
261 | #define VIDW_BUF_START1(_buff) (0xA4 + ((_buff) * 8)) | ||
262 | #define VIDW_BUF_END(_buff) (0xD0 + ((_buff) * 8)) | ||
263 | #define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8)) | ||
264 | #define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4)) | ||
265 | |||
266 | #define VIDW_BUF_SIZE_OFFSET_MASK (0x1fff << 13) | ||
267 | #define VIDW_BUF_SIZE_OFFSET_SHIFT (13) | ||
268 | #define VIDW_BUF_SIZE_OFFSET_LIMIT (0x1fff) | ||
269 | #define VIDW_BUF_SIZE_OFFSET(_x) ((_x) << 13) | ||
270 | |||
271 | #define VIDW_BUF_SIZE_PAGEWIDTH_MASK (0x1fff << 0) | ||
272 | #define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT (0) | ||
273 | #define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT (0x1fff) | ||
274 | #define VIDW_BUF_SIZE_PAGEWIDTH(_x) ((_x) << 0) | ||
275 | |||
276 | /* Interrupt controls and status */ | ||
277 | |||
278 | #define VIDINTCON0_FIFOINTERVAL_MASK (0x3f << 20) | ||
279 | #define VIDINTCON0_FIFOINTERVAL_SHIFT (20) | ||
280 | #define VIDINTCON0_FIFOINTERVAL_LIMIT (0x3f) | ||
281 | #define VIDINTCON0_FIFOINTERVAL(_x) ((_x) << 20) | ||
282 | |||
283 | #define VIDINTCON0_INT_SYSMAINCON (1 << 19) | ||
284 | #define VIDINTCON0_INT_SYSSUBCON (1 << 18) | ||
285 | #define VIDINTCON0_INT_I80IFDONE (1 << 17) | ||
286 | |||
287 | #define VIDINTCON0_FRAMESEL0_MASK (0x3 << 15) | ||
288 | #define VIDINTCON0_FRAMESEL0_SHIFT (15) | ||
289 | #define VIDINTCON0_FRAMESEL0_BACKPORCH (0x0 << 15) | ||
290 | #define VIDINTCON0_FRAMESEL0_VSYNC (0x1 << 15) | ||
291 | #define VIDINTCON0_FRAMESEL0_ACTIVE (0x2 << 15) | ||
292 | #define VIDINTCON0_FRAMESEL0_FRONTPORCH (0x3 << 15) | ||
293 | |||
294 | #define VIDINTCON0_FRAMESEL1 (1 << 14) | ||
295 | #define VIDINTCON0_FRAMESEL1_NONE (0x0 << 14) | ||
296 | #define VIDINTCON0_FRAMESEL1_BACKPORCH (0x1 << 14) | ||
297 | #define VIDINTCON0_FRAMESEL1_VSYNC (0x2 << 14) | ||
298 | #define VIDINTCON0_FRAMESEL1_FRONTPORCH (0x3 << 14) | ||
299 | |||
300 | #define VIDINTCON0_INT_FRAME (1 << 12) | ||
301 | #define VIDINTCON0_FIFIOSEL_MASK (0x7f << 5) | ||
302 | #define VIDINTCON0_FIFIOSEL_SHIFT (5) | ||
303 | #define VIDINTCON0_FIFIOSEL_WINDOW0 (0x1 << 5) | ||
304 | #define VIDINTCON0_FIFIOSEL_WINDOW1 (0x2 << 5) | ||
305 | |||
306 | #define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 2) | ||
307 | #define VIDINTCON0_FIFOLEVEL_SHIFT (2) | ||
308 | #define VIDINTCON0_FIFOLEVEL_TO25PC (0x0 << 2) | ||
309 | #define VIDINTCON0_FIFOLEVEL_TO50PC (0x1 << 2) | ||
310 | #define VIDINTCON0_FIFOLEVEL_TO75PC (0x2 << 2) | ||
311 | #define VIDINTCON0_FIFOLEVEL_EMPTY (0x3 << 2) | ||
312 | #define VIDINTCON0_FIFOLEVEL_FULL (0x4 << 2) | ||
313 | |||
314 | #define VIDINTCON0_INT_FIFO_MASK (0x3 << 0) | ||
315 | #define VIDINTCON0_INT_FIFO_SHIFT (0) | ||
316 | #define VIDINTCON0_INT_ENABLE (1 << 0) | ||
317 | |||
318 | #define VIDINTCON1 (0x134) | ||
319 | #define VIDINTCON1_INT_I180 (1 << 2) | ||
320 | #define VIDINTCON1_INT_FRAME (1 << 1) | ||
321 | #define VIDINTCON1_INT_FIFO (1 << 0) | ||
322 | |||
323 | /* Window colour-key control registers */ | ||
324 | |||
325 | #define WxKEYCON0_KEYBL_EN (1 << 26) | ||
326 | #define WxKEYCON0_KEYEN_F (1 << 25) | ||
327 | #define WxKEYCON0_DIRCON (1 << 24) | ||
328 | #define WxKEYCON0_COMPKEY_MASK (0xffffff << 0) | ||
329 | #define WxKEYCON0_COMPKEY_SHIFT (0) | ||
330 | #define WxKEYCON0_COMPKEY_LIMIT (0xffffff) | ||
331 | #define WxKEYCON0_COMPKEY(_x) ((_x) << 0) | ||
332 | #define WxKEYCON1_COLVAL_MASK (0xffffff << 0) | ||
333 | #define WxKEYCON1_COLVAL_SHIFT (0) | ||
334 | #define WxKEYCON1_COLVAL_LIMIT (0xffffff) | ||
335 | #define WxKEYCON1_COLVAL(_x) ((_x) << 0) | ||
336 | |||
337 | |||
338 | /* Window blanking (MAP) */ | ||
339 | |||
340 | #define WINxMAP_MAP (1 << 24) | ||
341 | #define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0) | ||
342 | #define WINxMAP_MAP_COLOUR_SHIFT (0) | ||
343 | #define WINxMAP_MAP_COLOUR_LIMIT (0xffffff) | ||
344 | #define WINxMAP_MAP_COLOUR(_x) ((_x) << 0) | ||
345 | |||
346 | #define WPALCON_PAL_UPDATE (1 << 9) | ||
347 | #define WPALCON_W1PAL_MASK (0x7 << 3) | ||
348 | #define WPALCON_W1PAL_SHIFT (3) | ||
349 | #define WPALCON_W1PAL_25BPP_A888 (0x0 << 3) | ||
350 | #define WPALCON_W1PAL_24BPP (0x1 << 3) | ||
351 | #define WPALCON_W1PAL_19BPP_A666 (0x2 << 3) | ||
352 | #define WPALCON_W1PAL_18BPP_A665 (0x3 << 3) | ||
353 | #define WPALCON_W1PAL_18BPP (0x4 << 3) | ||
354 | #define WPALCON_W1PAL_16BPP_A555 (0x5 << 3) | ||
355 | #define WPALCON_W1PAL_16BPP_565 (0x6 << 3) | ||
356 | |||
357 | #define WPALCON_W0PAL_MASK (0x7 << 0) | ||
358 | #define WPALCON_W0PAL_SHIFT (0) | ||
359 | #define WPALCON_W0PAL_25BPP_A888 (0x0 << 0) | ||
360 | #define WPALCON_W0PAL_24BPP (0x1 << 0) | ||
361 | #define WPALCON_W0PAL_19BPP_A666 (0x2 << 0) | ||
362 | #define WPALCON_W0PAL_18BPP_A665 (0x3 << 0) | ||
363 | #define WPALCON_W0PAL_18BPP (0x4 << 0) | ||
364 | #define WPALCON_W0PAL_16BPP_A555 (0x5 << 0) | ||
365 | #define WPALCON_W0PAL_16BPP_565 (0x6 << 0) | ||
366 | |||
diff --git a/arch/arm/plat-s3c/include/plat/regs-irqtype.h b/arch/arm/plat-s3c/include/plat/regs-irqtype.h new file mode 100644 index 000000000000..c63cd3fc5ad3 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/regs-irqtype.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* arch/arm/plat-s3c/include/plat/regs-irqtype.h | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * S3C - IRQ detection types. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | /* values for S3C2410_EXTINT0/1/2 and other cpus in the series, including | ||
15 | * the S3C64XX | ||
16 | */ | ||
17 | #define S3C2410_EXTINT_LOWLEV (0x00) | ||
18 | #define S3C2410_EXTINT_HILEV (0x01) | ||
19 | #define S3C2410_EXTINT_FALLEDGE (0x02) | ||
20 | #define S3C2410_EXTINT_RISEEDGE (0x04) | ||
21 | #define S3C2410_EXTINT_BOTHEDGE (0x06) | ||
diff --git a/arch/arm/plat-s3c/include/plat/regs-sdhci.h b/arch/arm/plat-s3c/include/plat/regs-sdhci.h new file mode 100644 index 000000000000..e34049ad44cc --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/regs-sdhci.h | |||
@@ -0,0 +1,87 @@ | |||
1 | /* linux/arch/arm/plat-s3c/include/plat/regs-sdhci.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C Platform - SDHCI (HSMMC) register definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __PLAT_S3C_SDHCI_REGS_H | ||
16 | #define __PLAT_S3C_SDHCI_REGS_H __FILE__ | ||
17 | |||
18 | #define S3C_SDHCI_CONTROL2 (0x80) | ||
19 | #define S3C_SDHCI_CONTROL3 (0x84) | ||
20 | #define S3C64XX_SDHCI_CONTROL4 (0x8C) | ||
21 | |||
22 | #define S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR (1 << 31) | ||
23 | #define S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK (1 << 30) | ||
24 | #define S3C_SDHCI_CTRL2_CDINVRXD3 (1 << 29) | ||
25 | #define S3C_SDHCI_CTRL2_SLCARDOUT (1 << 28) | ||
26 | |||
27 | #define S3C_SDHCI_CTRL2_FLTCLKSEL_MASK (0xf << 24) | ||
28 | #define S3C_SDHCI_CTRL2_FLTCLKSEL_SHIFT (24) | ||
29 | #define S3C_SDHCI_CTRL2_FLTCLKSEL(_x) ((_x) << 24) | ||
30 | |||
31 | #define S3C_SDHCI_CTRL2_LVLDAT_MASK (0xff << 16) | ||
32 | #define S3C_SDHCI_CTRL2_LVLDAT_SHIFT (16) | ||
33 | #define S3C_SDHCI_CTRL2_LVLDAT(_x) ((_x) << 16) | ||
34 | |||
35 | #define S3C_SDHCI_CTRL2_ENFBCLKTX (1 << 15) | ||
36 | #define S3C_SDHCI_CTRL2_ENFBCLKRX (1 << 14) | ||
37 | #define S3C_SDHCI_CTRL2_SDCDSEL (1 << 13) | ||
38 | #define S3C_SDHCI_CTRL2_SDSIGPC (1 << 12) | ||
39 | #define S3C_SDHCI_CTRL2_ENBUSYCHKTXSTART (1 << 11) | ||
40 | |||
41 | #define S3C_SDHCI_CTRL2_DFCNT_MASK (0x3 << 9) | ||
42 | #define S3C_SDHCI_CTRL2_DFCNT_SHIFT (9) | ||
43 | #define S3C_SDHCI_CTRL2_DFCNT_NONE (0x0 << 9) | ||
44 | #define S3C_SDHCI_CTRL2_DFCNT_4SDCLK (0x1 << 9) | ||
45 | #define S3C_SDHCI_CTRL2_DFCNT_16SDCLK (0x2 << 9) | ||
46 | #define S3C_SDHCI_CTRL2_DFCNT_64SDCLK (0x3 << 9) | ||
47 | |||
48 | #define S3C_SDHCI_CTRL2_ENCLKOUTHOLD (1 << 8) | ||
49 | #define S3C_SDHCI_CTRL2_RWAITMODE (1 << 7) | ||
50 | #define S3C_SDHCI_CTRL2_DISBUFRD (1 << 6) | ||
51 | #define S3C_SDHCI_CTRL2_SELBASECLK_MASK (0x3 << 4) | ||
52 | #define S3C_SDHCI_CTRL2_SELBASECLK_SHIFT (4) | ||
53 | #define S3C_SDHCI_CTRL2_PWRSYNC (1 << 3) | ||
54 | #define S3C_SDHCI_CTRL2_ENCLKOUTMSKCON (1 << 1) | ||
55 | #define S3C_SDHCI_CTRL2_HWINITFIN (1 << 0) | ||
56 | |||
57 | #define S3C_SDHCI_CTRL3_FCSEL3 (1 << 31) | ||
58 | #define S3C_SDHCI_CTRL3_FCSEL2 (1 << 23) | ||
59 | #define S3C_SDHCI_CTRL3_FCSEL1 (1 << 15) | ||
60 | #define S3C_SDHCI_CTRL3_FCSEL0 (1 << 7) | ||
61 | |||
62 | #define S3C_SDHCI_CTRL3_FIA3_MASK (0x7f << 24) | ||
63 | #define S3C_SDHCI_CTRL3_FIA3_SHIFT (24) | ||
64 | #define S3C_SDHCI_CTRL3_FIA3(_x) ((_x) << 24) | ||
65 | |||
66 | #define S3C_SDHCI_CTRL3_FIA2_MASK (0x7f << 16) | ||
67 | #define S3C_SDHCI_CTRL3_FIA2_SHIFT (16) | ||
68 | #define S3C_SDHCI_CTRL3_FIA2(_x) ((_x) << 16) | ||
69 | |||
70 | #define S3C_SDHCI_CTRL3_FIA1_MASK (0x7f << 8) | ||
71 | #define S3C_SDHCI_CTRL3_FIA1_SHIFT (8) | ||
72 | #define S3C_SDHCI_CTRL3_FIA1(_x) ((_x) << 8) | ||
73 | |||
74 | #define S3C_SDHCI_CTRL3_FIA0_MASK (0x7f << 0) | ||
75 | #define S3C_SDHCI_CTRL3_FIA0_SHIFT (0) | ||
76 | #define S3C_SDHCI_CTRL3_FIA0(_x) ((_x) << 0) | ||
77 | |||
78 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_MASK (0x3 << 16) | ||
79 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_SHIFT (16) | ||
80 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_2mA (0x0 << 16) | ||
81 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_4mA (0x1 << 16) | ||
82 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_7mA (0x2 << 16) | ||
83 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA (0x3 << 16) | ||
84 | |||
85 | #define S3C64XX_SDHCI_CONTROL4_BUSY (1) | ||
86 | |||
87 | #endif /* __PLAT_S3C_SDHCI_REGS_H */ | ||
diff --git a/arch/arm/plat-s3c/include/plat/regs-serial.h b/arch/arm/plat-s3c/include/plat/regs-serial.h index a0daa647b92c..487d7d2a7e1d 100644 --- a/arch/arm/plat-s3c/include/plat/regs-serial.h +++ b/arch/arm/plat-s3c/include/plat/regs-serial.h | |||
@@ -77,6 +77,12 @@ | |||
77 | #define S3C2440_UCON_FCLK (3<<10) | 77 | #define S3C2440_UCON_FCLK (3<<10) |
78 | #define S3C2443_UCON_EPLL (3<<10) | 78 | #define S3C2443_UCON_EPLL (3<<10) |
79 | 79 | ||
80 | #define S3C6400_UCON_CLKMASK (3<<10) | ||
81 | #define S3C6400_UCON_PCLK (0<<10) | ||
82 | #define S3C6400_UCON_PCLK2 (2<<10) | ||
83 | #define S3C6400_UCON_UCLK0 (1<<10) | ||
84 | #define S3C6400_UCON_UCLK1 (3<<10) | ||
85 | |||
80 | #define S3C2440_UCON2_FCLK_EN (1<<15) | 86 | #define S3C2440_UCON2_FCLK_EN (1<<15) |
81 | #define S3C2440_UCON0_DIVMASK (15 << 12) | 87 | #define S3C2440_UCON0_DIVMASK (15 << 12) |
82 | #define S3C2440_UCON1_DIVMASK (15 << 12) | 88 | #define S3C2440_UCON1_DIVMASK (15 << 12) |
@@ -149,6 +155,14 @@ | |||
149 | #define S3C2410_UFSTAT_RXMASK (15<<0) | 155 | #define S3C2410_UFSTAT_RXMASK (15<<0) |
150 | #define S3C2410_UFSTAT_RXSHIFT (0) | 156 | #define S3C2410_UFSTAT_RXSHIFT (0) |
151 | 157 | ||
158 | /* UFSTAT S3C24A0 */ | ||
159 | #define S3C24A0_UFSTAT_TXFULL (1 << 14) | ||
160 | #define S3C24A0_UFSTAT_RXFULL (1 << 6) | ||
161 | #define S3C24A0_UFSTAT_TXMASK (63 << 8) | ||
162 | #define S3C24A0_UFSTAT_TXSHIFT (8) | ||
163 | #define S3C24A0_UFSTAT_RXMASK (63) | ||
164 | #define S3C24A0_UFSTAT_RXSHIFT (0) | ||
165 | |||
152 | /* UFSTAT S3C2443 same as S3C2440 */ | 166 | /* UFSTAT S3C2443 same as S3C2440 */ |
153 | #define S3C2440_UFSTAT_TXFULL (1<<14) | 167 | #define S3C2440_UFSTAT_TXFULL (1<<14) |
154 | #define S3C2440_UFSTAT_RXFULL (1<<6) | 168 | #define S3C2440_UFSTAT_RXFULL (1<<6) |
@@ -224,7 +238,7 @@ struct s3c2410_uartcfg { | |||
224 | * or platform_add_device() before the console_initcall() | 238 | * or platform_add_device() before the console_initcall() |
225 | */ | 239 | */ |
226 | 240 | ||
227 | extern struct platform_device *s3c24xx_uart_devs[3]; | 241 | extern struct platform_device *s3c24xx_uart_devs[4]; |
228 | 242 | ||
229 | #endif /* __ASSEMBLY__ */ | 243 | #endif /* __ASSEMBLY__ */ |
230 | 244 | ||
diff --git a/arch/arm/plat-s3c/include/plat/regs-timer.h b/arch/arm/plat-s3c/include/plat/regs-timer.h index cc0eedd53e38..d097d92f8cc7 100644 --- a/arch/arm/plat-s3c/include/plat/regs-timer.h +++ b/arch/arm/plat-s3c/include/plat/regs-timer.h | |||
@@ -10,7 +10,6 @@ | |||
10 | * S3C2410 Timer configuration | 10 | * S3C2410 Timer configuration |
11 | */ | 11 | */ |
12 | 12 | ||
13 | |||
14 | #ifndef __ASM_ARCH_REGS_TIMER_H | 13 | #ifndef __ASM_ARCH_REGS_TIMER_H |
15 | #define __ASM_ARCH_REGS_TIMER_H | 14 | #define __ASM_ARCH_REGS_TIMER_H |
16 | 15 | ||
@@ -21,6 +20,8 @@ | |||
21 | #define S3C2410_TCFG1 S3C_TIMERREG(0x04) | 20 | #define S3C2410_TCFG1 S3C_TIMERREG(0x04) |
22 | #define S3C2410_TCON S3C_TIMERREG(0x08) | 21 | #define S3C2410_TCON S3C_TIMERREG(0x08) |
23 | 22 | ||
23 | #define S3C64XX_TINT_CSTAT S3C_TIMERREG(0x44) | ||
24 | |||
24 | #define S3C2410_TCFG_PRESCALER0_MASK (255<<0) | 25 | #define S3C2410_TCFG_PRESCALER0_MASK (255<<0) |
25 | #define S3C2410_TCFG_PRESCALER1_MASK (255<<8) | 26 | #define S3C2410_TCFG_PRESCALER1_MASK (255<<8) |
26 | #define S3C2410_TCFG_PRESCALER1_SHIFT (8) | 27 | #define S3C2410_TCFG_PRESCALER1_SHIFT (8) |
@@ -72,6 +73,14 @@ | |||
72 | #define S3C2410_TCFG1_MUX_TCLK (4<<0) | 73 | #define S3C2410_TCFG1_MUX_TCLK (4<<0) |
73 | #define S3C2410_TCFG1_MUX_MASK (15<<0) | 74 | #define S3C2410_TCFG1_MUX_MASK (15<<0) |
74 | 75 | ||
76 | #define S3C64XX_TCFG1_MUX_DIV1 (0<<0) | ||
77 | #define S3C64XX_TCFG1_MUX_DIV2 (1<<0) | ||
78 | #define S3C64XX_TCFG1_MUX_DIV4 (2<<0) | ||
79 | #define S3C64XX_TCFG1_MUX_DIV8 (3<<0) | ||
80 | #define S3C64XX_TCFG1_MUX_DIV16 (4<<0) | ||
81 | #define S3C64XX_TCFG1_MUX_TCLK (5<<0) /* 3 sets of TCLK */ | ||
82 | #define S3C64XX_TCFG1_MUX_MASK (15<<0) | ||
83 | |||
75 | #define S3C2410_TCFG1_SHIFT(x) ((x) * 4) | 84 | #define S3C2410_TCFG1_SHIFT(x) ((x) * 4) |
76 | 85 | ||
77 | /* for each timer, we have an count buffer, an compare buffer and | 86 | /* for each timer, we have an count buffer, an compare buffer and |
diff --git a/arch/arm/plat-s3c/include/plat/sdhci.h b/arch/arm/plat-s3c/include/plat/sdhci.h new file mode 100644 index 000000000000..c4ca3920ca4b --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/sdhci.h | |||
@@ -0,0 +1,108 @@ | |||
1 | /* linux/arch/arm/plat-s3c/include/plat/sdhci.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C Platform - SDHCI (HSMMC) platform data definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __PLAT_S3C_SDHCI_H | ||
16 | #define __PLAT_S3C_SDHCI_H __FILE__ | ||
17 | |||
18 | struct platform_device; | ||
19 | struct mmc_host; | ||
20 | struct mmc_card; | ||
21 | struct mmc_ios; | ||
22 | |||
23 | /** | ||
24 | * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI | ||
25 | * @max_width: The maximum number of data bits supported. | ||
26 | * @host_caps: Standard MMC host capabilities bit field. | ||
27 | * @cfg_gpio: Configure the GPIO for a specific card bit-width | ||
28 | * @cfg_card: Configure the interface for a specific card and speed. This | ||
29 | * is necessary the controllers and/or GPIO blocks require the | ||
30 | * changing of driver-strength and other controls dependant on | ||
31 | * the card and speed of operation. | ||
32 | * | ||
33 | * Initialisation data specific to either the machine or the platform | ||
34 | * for the device driver to use or call-back when configuring gpio or | ||
35 | * card speed information. | ||
36 | */ | ||
37 | struct s3c_sdhci_platdata { | ||
38 | unsigned int max_width; | ||
39 | unsigned int host_caps; | ||
40 | |||
41 | char **clocks; /* set of clock sources */ | ||
42 | |||
43 | void (*cfg_gpio)(struct platform_device *dev, int width); | ||
44 | void (*cfg_card)(struct platform_device *dev, | ||
45 | void __iomem *regbase, | ||
46 | struct mmc_ios *ios, | ||
47 | struct mmc_card *card); | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device. | ||
52 | * @pd: Platform data to register to device. | ||
53 | * | ||
54 | * Register the given platform data for use withe S3C SDHCI device. | ||
55 | * The call will copy the platform data, so the board definitions can | ||
56 | * make the structure itself __initdata. | ||
57 | */ | ||
58 | extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd); | ||
59 | extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd); | ||
60 | |||
61 | /* Default platform data, exported so that per-cpu initialisation can | ||
62 | * set the correct one when there are more than one cpu type selected. | ||
63 | */ | ||
64 | |||
65 | extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata; | ||
66 | extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata; | ||
67 | |||
68 | /* Helper function availablity */ | ||
69 | |||
70 | #ifdef CONFIG_S3C6410_SETUP_SDHCI | ||
71 | extern char *s3c6410_hsmmc_clksrcs[4]; | ||
72 | |||
73 | extern void s3c6410_setup_sdhci0_cfg_gpio(struct platform_device *, int w); | ||
74 | extern void s3c6410_setup_sdhci1_cfg_gpio(struct platform_device *, int w); | ||
75 | |||
76 | extern void s3c6410_setup_sdhci0_cfg_card(struct platform_device *dev, | ||
77 | void __iomem *r, | ||
78 | struct mmc_ios *ios, | ||
79 | struct mmc_card *card); | ||
80 | |||
81 | #ifdef CONFIG_S3C_DEV_HSMMC | ||
82 | static inline void s3c6410_default_sdhci0(void) | ||
83 | { | ||
84 | s3c_hsmmc0_def_platdata.clocks = s3c6410_hsmmc_clksrcs; | ||
85 | s3c_hsmmc0_def_platdata.cfg_gpio = s3c6410_setup_sdhci0_cfg_gpio; | ||
86 | s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card; | ||
87 | } | ||
88 | #else | ||
89 | static inline void s3c6410_default_sdhci0(void) { } | ||
90 | #endif /* CONFIG_S3C_DEV_HSMMC */ | ||
91 | |||
92 | #ifdef CONFIG_S3C_DEV_HSMMC1 | ||
93 | static inline void s3c6410_default_sdhci1(void) | ||
94 | { | ||
95 | s3c_hsmmc1_def_platdata.clocks = s3c6410_hsmmc_clksrcs; | ||
96 | s3c_hsmmc1_def_platdata.cfg_gpio = s3c6410_setup_sdhci1_cfg_gpio; | ||
97 | s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card; | ||
98 | } | ||
99 | #else | ||
100 | static inline void s3c6410_default_sdhci1(void) { } | ||
101 | #endif /* CONFIG_S3C_DEV_HSMMC1 */ | ||
102 | |||
103 | #else | ||
104 | static inline void s3c6410_default_sdhci0(void) { } | ||
105 | static inline void s3c6410_default_sdhci1(void) { } | ||
106 | #endif /* CONFIG_S3C6410_SETUP_SDHCI */ | ||
107 | |||
108 | #endif /* __PLAT_S3C_SDHCI_H */ | ||
diff --git a/arch/arm/plat-s3c/include/plat/uncompress.h b/arch/arm/plat-s3c/include/plat/uncompress.h index 8a8a927292e0..6061de87f225 100644 --- a/arch/arm/plat-s3c/include/plat/uncompress.h +++ b/arch/arm/plat-s3c/include/plat/uncompress.h | |||
@@ -37,7 +37,7 @@ static void arch_detect_cpu(void); | |||
37 | /* how many bytes we allow into the FIFO at a time in FIFO mode */ | 37 | /* how many bytes we allow into the FIFO at a time in FIFO mode */ |
38 | #define FIFO_MAX (14) | 38 | #define FIFO_MAX (14) |
39 | 39 | ||
40 | #define uart_base S3C24XX_PA_UART + (0x4000*CONFIG_S3C_LOWLEVEL_UART_PORT) | 40 | #define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT) |
41 | 41 | ||
42 | static __inline__ void | 42 | static __inline__ void |
43 | uart_wr(unsigned int reg, unsigned int val) | 43 | uart_wr(unsigned int reg, unsigned int val) |
@@ -139,6 +139,28 @@ static void arch_decomp_error(const char *x) | |||
139 | 139 | ||
140 | static void error(char *err); | 140 | static void error(char *err); |
141 | 141 | ||
142 | #ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO | ||
143 | static inline void arch_enable_uart_fifo(void) | ||
144 | { | ||
145 | u32 fifocon = uart_rd(S3C2410_UFCON); | ||
146 | |||
147 | if (!(fifocon & S3C2410_UFCON_FIFOMODE)) { | ||
148 | fifocon |= S3C2410_UFCON_RESETBOTH; | ||
149 | uart_wr(S3C2410_UFCON, fifocon); | ||
150 | |||
151 | /* wait for fifo reset to complete */ | ||
152 | while (1) { | ||
153 | fifocon = uart_rd(S3C2410_UFCON); | ||
154 | if (!(fifocon & S3C2410_UFCON_RESETBOTH)) | ||
155 | break; | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | #else | ||
160 | #define arch_enable_uart_fifo() do { } while(0) | ||
161 | #endif | ||
162 | |||
163 | |||
142 | static void | 164 | static void |
143 | arch_decomp_setup(void) | 165 | arch_decomp_setup(void) |
144 | { | 166 | { |
@@ -149,6 +171,12 @@ arch_decomp_setup(void) | |||
149 | 171 | ||
150 | arch_detect_cpu(); | 172 | arch_detect_cpu(); |
151 | arch_decomp_wdog_start(); | 173 | arch_decomp_wdog_start(); |
174 | |||
175 | /* Enable the UART FIFOs if they where not enabled and our | ||
176 | * configuration says we should turn them on. | ||
177 | */ | ||
178 | |||
179 | arch_enable_uart_fifo(); | ||
152 | } | 180 | } |
153 | 181 | ||
154 | 182 | ||
diff --git a/arch/arm/plat-s3c/init.c b/arch/arm/plat-s3c/init.c new file mode 100644 index 000000000000..6790edfaca6f --- /dev/null +++ b/arch/arm/plat-s3c/init.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* linux/arch/arm/plat-s3c/init.c | ||
2 | * | ||
3 | * Copyright (c) 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * S3C series CPU initialisation | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/ioport.h> | ||
18 | #include <linux/serial_core.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | |||
21 | #include <mach/hardware.h> | ||
22 | |||
23 | #include <asm/mach/arch.h> | ||
24 | #include <asm/mach/map.h> | ||
25 | |||
26 | #include <plat/cpu.h> | ||
27 | #include <plat/devs.h> | ||
28 | #include <plat/clock.h> | ||
29 | |||
30 | #include <plat/regs-serial.h> | ||
31 | |||
32 | static struct cpu_table *cpu; | ||
33 | |||
34 | static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode, | ||
35 | struct cpu_table *tab, | ||
36 | unsigned int count) | ||
37 | { | ||
38 | for (; count != 0; count--, tab++) { | ||
39 | if ((idcode & tab->idmask) == tab->idcode) | ||
40 | return tab; | ||
41 | } | ||
42 | |||
43 | return NULL; | ||
44 | } | ||
45 | |||
46 | void __init s3c_init_cpu(unsigned long idcode, | ||
47 | struct cpu_table *cputab, unsigned int cputab_size) | ||
48 | { | ||
49 | cpu = s3c_lookup_cpu(idcode, cputab, cputab_size); | ||
50 | |||
51 | if (cpu == NULL) { | ||
52 | printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode); | ||
53 | panic("Unknown S3C24XX CPU"); | ||
54 | } | ||
55 | |||
56 | printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode); | ||
57 | |||
58 | if (cpu->map_io == NULL || cpu->init == NULL) { | ||
59 | printk(KERN_ERR "CPU %s support not enabled\n", cpu->name); | ||
60 | panic("Unsupported Samsung CPU"); | ||
61 | } | ||
62 | |||
63 | cpu->map_io(); | ||
64 | } | ||
65 | |||
66 | /* s3c24xx_init_clocks | ||
67 | * | ||
68 | * Initialise the clock subsystem and associated information from the | ||
69 | * given master crystal value. | ||
70 | * | ||
71 | * xtal = 0 -> use default PLL crystal value (normally 12MHz) | ||
72 | * != 0 -> PLL crystal value in Hz | ||
73 | */ | ||
74 | |||
75 | void __init s3c24xx_init_clocks(int xtal) | ||
76 | { | ||
77 | if (xtal == 0) | ||
78 | xtal = 12*1000*1000; | ||
79 | |||
80 | if (cpu == NULL) | ||
81 | panic("s3c24xx_init_clocks: no cpu setup?\n"); | ||
82 | |||
83 | if (cpu->init_clocks == NULL) | ||
84 | panic("s3c24xx_init_clocks: cpu has no clock init\n"); | ||
85 | else | ||
86 | (cpu->init_clocks)(xtal); | ||
87 | } | ||
88 | |||
89 | /* uart management */ | ||
90 | |||
91 | static int nr_uarts __initdata = 0; | ||
92 | |||
93 | static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS]; | ||
94 | |||
95 | /* s3c24xx_init_uartdevs | ||
96 | * | ||
97 | * copy the specified platform data and configuration into our central | ||
98 | * set of devices, before the data is thrown away after the init process. | ||
99 | * | ||
100 | * This also fills in the array passed to the serial driver for the | ||
101 | * early initialisation of the console. | ||
102 | */ | ||
103 | |||
104 | void __init s3c24xx_init_uartdevs(char *name, | ||
105 | struct s3c24xx_uart_resources *res, | ||
106 | struct s3c2410_uartcfg *cfg, int no) | ||
107 | { | ||
108 | struct platform_device *platdev; | ||
109 | struct s3c2410_uartcfg *cfgptr = uart_cfgs; | ||
110 | struct s3c24xx_uart_resources *resp; | ||
111 | int uart; | ||
112 | |||
113 | memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no); | ||
114 | |||
115 | for (uart = 0; uart < no; uart++, cfg++, cfgptr++) { | ||
116 | platdev = s3c24xx_uart_src[cfgptr->hwport]; | ||
117 | |||
118 | resp = res + cfgptr->hwport; | ||
119 | |||
120 | s3c24xx_uart_devs[uart] = platdev; | ||
121 | |||
122 | platdev->name = name; | ||
123 | platdev->resource = resp->resources; | ||
124 | platdev->num_resources = resp->nr_resources; | ||
125 | |||
126 | platdev->dev.platform_data = cfgptr; | ||
127 | } | ||
128 | |||
129 | nr_uarts = no; | ||
130 | } | ||
131 | |||
132 | void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) | ||
133 | { | ||
134 | if (cpu == NULL) | ||
135 | return; | ||
136 | |||
137 | if (cpu->init_uarts == NULL) { | ||
138 | printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n"); | ||
139 | } else | ||
140 | (cpu->init_uarts)(cfg, no); | ||
141 | } | ||
142 | |||
143 | static int __init s3c_arch_init(void) | ||
144 | { | ||
145 | int ret; | ||
146 | |||
147 | // do the correct init for cpu | ||
148 | |||
149 | if (cpu == NULL) | ||
150 | panic("s3c_arch_init: NULL cpu\n"); | ||
151 | |||
152 | ret = (cpu->init)(); | ||
153 | if (ret != 0) | ||
154 | return ret; | ||
155 | |||
156 | ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts); | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | arch_initcall(s3c_arch_init); | ||
diff --git a/arch/arm/plat-s3c/pwm-clock.c b/arch/arm/plat-s3c/pwm-clock.c new file mode 100644 index 000000000000..a318215ab535 --- /dev/null +++ b/arch/arm/plat-s3c/pwm-clock.c | |||
@@ -0,0 +1,463 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/pwm-clock.c | ||
2 | * | ||
3 | * Copyright (c) 2007 Simtec Electronics | ||
4 | * Copyright (c) 2007, 2008 Ben Dooks | ||
5 | * Ben Dooks <ben-linux@fluff.org> | ||
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 as published by | ||
9 | * the Free Software Foundation; either version 2 of the License. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/list.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/log2.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/io.h> | ||
21 | |||
22 | #include <mach/hardware.h> | ||
23 | #include <mach/map.h> | ||
24 | #include <asm/irq.h> | ||
25 | |||
26 | #include <plat/clock.h> | ||
27 | #include <plat/cpu.h> | ||
28 | |||
29 | #include <plat/regs-timer.h> | ||
30 | #include <mach/pwm-clock.h> | ||
31 | |||
32 | /* Each of the timers 0 through 5 go through the following | ||
33 | * clock tree, with the inputs depending on the timers. | ||
34 | * | ||
35 | * pclk ---- [ prescaler 0 ] -+---> timer 0 | ||
36 | * +---> timer 1 | ||
37 | * | ||
38 | * pclk ---- [ prescaler 1 ] -+---> timer 2 | ||
39 | * +---> timer 3 | ||
40 | * \---> timer 4 | ||
41 | * | ||
42 | * Which are fed into the timers as so: | ||
43 | * | ||
44 | * prescaled 0 ---- [ div 2,4,8,16 ] ---\ | ||
45 | * [mux] -> timer 0 | ||
46 | * tclk 0 ------------------------------/ | ||
47 | * | ||
48 | * prescaled 0 ---- [ div 2,4,8,16 ] ---\ | ||
49 | * [mux] -> timer 1 | ||
50 | * tclk 0 ------------------------------/ | ||
51 | * | ||
52 | * | ||
53 | * prescaled 1 ---- [ div 2,4,8,16 ] ---\ | ||
54 | * [mux] -> timer 2 | ||
55 | * tclk 1 ------------------------------/ | ||
56 | * | ||
57 | * prescaled 1 ---- [ div 2,4,8,16 ] ---\ | ||
58 | * [mux] -> timer 3 | ||
59 | * tclk 1 ------------------------------/ | ||
60 | * | ||
61 | * prescaled 1 ---- [ div 2,4,8, 16 ] --\ | ||
62 | * [mux] -> timer 4 | ||
63 | * tclk 1 ------------------------------/ | ||
64 | * | ||
65 | * Since the mux and the divider are tied together in the | ||
66 | * same register space, it is impossible to set the parent | ||
67 | * and the rate at the same time. To avoid this, we add an | ||
68 | * intermediate 'prescaled-and-divided' clock to select | ||
69 | * as the parent for the timer input clock called tdiv. | ||
70 | * | ||
71 | * prescaled clk --> pwm-tdiv ---\ | ||
72 | * [ mux ] --> timer X | ||
73 | * tclk -------------------------/ | ||
74 | */ | ||
75 | |||
76 | static struct clk clk_timer_scaler[]; | ||
77 | |||
78 | static unsigned long clk_pwm_scaler_get_rate(struct clk *clk) | ||
79 | { | ||
80 | unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0); | ||
81 | |||
82 | if (clk == &clk_timer_scaler[1]) { | ||
83 | tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK; | ||
84 | tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT; | ||
85 | } else { | ||
86 | tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK; | ||
87 | } | ||
88 | |||
89 | return clk_get_rate(clk->parent) / (tcfg0 + 1); | ||
90 | } | ||
91 | |||
92 | static unsigned long clk_pwm_scaler_round_rate(struct clk *clk, | ||
93 | unsigned long rate) | ||
94 | { | ||
95 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
96 | unsigned long divisor = parent_rate / rate; | ||
97 | |||
98 | if (divisor > 256) | ||
99 | divisor = 256; | ||
100 | else if (divisor < 2) | ||
101 | divisor = 2; | ||
102 | |||
103 | return parent_rate / divisor; | ||
104 | } | ||
105 | |||
106 | static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate) | ||
107 | { | ||
108 | unsigned long round = clk_pwm_scaler_round_rate(clk, rate); | ||
109 | unsigned long tcfg0; | ||
110 | unsigned long divisor; | ||
111 | unsigned long flags; | ||
112 | |||
113 | divisor = clk_get_rate(clk->parent) / round; | ||
114 | divisor--; | ||
115 | |||
116 | local_irq_save(flags); | ||
117 | tcfg0 = __raw_readl(S3C2410_TCFG0); | ||
118 | |||
119 | if (clk == &clk_timer_scaler[1]) { | ||
120 | tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; | ||
121 | tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT; | ||
122 | } else { | ||
123 | tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK; | ||
124 | tcfg0 |= divisor; | ||
125 | } | ||
126 | |||
127 | __raw_writel(tcfg0, S3C2410_TCFG0); | ||
128 | local_irq_restore(flags); | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static struct clk clk_timer_scaler[] = { | ||
134 | [0] = { | ||
135 | .name = "pwm-scaler0", | ||
136 | .id = -1, | ||
137 | .get_rate = clk_pwm_scaler_get_rate, | ||
138 | .set_rate = clk_pwm_scaler_set_rate, | ||
139 | .round_rate = clk_pwm_scaler_round_rate, | ||
140 | }, | ||
141 | [1] = { | ||
142 | .name = "pwm-scaler1", | ||
143 | .id = -1, | ||
144 | .get_rate = clk_pwm_scaler_get_rate, | ||
145 | .set_rate = clk_pwm_scaler_set_rate, | ||
146 | .round_rate = clk_pwm_scaler_round_rate, | ||
147 | }, | ||
148 | }; | ||
149 | |||
150 | static struct clk clk_timer_tclk[] = { | ||
151 | [0] = { | ||
152 | .name = "pwm-tclk0", | ||
153 | .id = -1, | ||
154 | }, | ||
155 | [1] = { | ||
156 | .name = "pwm-tclk1", | ||
157 | .id = -1, | ||
158 | }, | ||
159 | }; | ||
160 | |||
161 | struct pwm_tdiv_clk { | ||
162 | struct clk clk; | ||
163 | unsigned int divisor; | ||
164 | }; | ||
165 | |||
166 | static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk) | ||
167 | { | ||
168 | return container_of(clk, struct pwm_tdiv_clk, clk); | ||
169 | } | ||
170 | |||
171 | static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk) | ||
172 | { | ||
173 | unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
174 | unsigned int divisor; | ||
175 | |||
176 | tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id); | ||
177 | tcfg1 &= S3C2410_TCFG1_MUX_MASK; | ||
178 | |||
179 | if (pwm_cfg_src_is_tclk(tcfg1)) | ||
180 | divisor = to_tdiv(clk)->divisor; | ||
181 | else | ||
182 | divisor = tcfg_to_divisor(tcfg1); | ||
183 | |||
184 | return clk_get_rate(clk->parent) / divisor; | ||
185 | } | ||
186 | |||
187 | static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk, | ||
188 | unsigned long rate) | ||
189 | { | ||
190 | unsigned long parent_rate; | ||
191 | unsigned long divisor; | ||
192 | |||
193 | parent_rate = clk_get_rate(clk->parent); | ||
194 | divisor = parent_rate / rate; | ||
195 | |||
196 | if (divisor <= 1 && pwm_tdiv_has_div1()) | ||
197 | divisor = 1; | ||
198 | else if (divisor <= 2) | ||
199 | divisor = 2; | ||
200 | else if (divisor <= 4) | ||
201 | divisor = 4; | ||
202 | else if (divisor <= 8) | ||
203 | divisor = 8; | ||
204 | else | ||
205 | divisor = 16; | ||
206 | |||
207 | return parent_rate / divisor; | ||
208 | } | ||
209 | |||
210 | static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk) | ||
211 | { | ||
212 | return pwm_tdiv_div_bits(divclk->divisor); | ||
213 | } | ||
214 | |||
215 | static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk) | ||
216 | { | ||
217 | unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
218 | unsigned long bits = clk_pwm_tdiv_bits(divclk); | ||
219 | unsigned long flags; | ||
220 | unsigned long shift = S3C2410_TCFG1_SHIFT(divclk->clk.id); | ||
221 | |||
222 | local_irq_save(flags); | ||
223 | |||
224 | tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
225 | tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift); | ||
226 | tcfg1 |= bits << shift; | ||
227 | __raw_writel(tcfg1, S3C2410_TCFG1); | ||
228 | |||
229 | local_irq_restore(flags); | ||
230 | } | ||
231 | |||
232 | static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate) | ||
233 | { | ||
234 | struct pwm_tdiv_clk *divclk = to_tdiv(clk); | ||
235 | unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
236 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
237 | unsigned long divisor; | ||
238 | |||
239 | tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id); | ||
240 | tcfg1 &= S3C2410_TCFG1_MUX_MASK; | ||
241 | |||
242 | rate = clk_round_rate(clk, rate); | ||
243 | divisor = parent_rate / rate; | ||
244 | |||
245 | if (divisor > 16) | ||
246 | return -EINVAL; | ||
247 | |||
248 | divclk->divisor = divisor; | ||
249 | |||
250 | /* Update the current MUX settings if we are currently | ||
251 | * selected as the clock source for this clock. */ | ||
252 | |||
253 | if (!pwm_cfg_src_is_tclk(tcfg1)) | ||
254 | clk_pwm_tdiv_update(divclk); | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static struct pwm_tdiv_clk clk_timer_tdiv[] = { | ||
260 | [0] = { | ||
261 | .clk = { | ||
262 | .name = "pwm-tdiv", | ||
263 | .parent = &clk_timer_scaler[0], | ||
264 | .get_rate = clk_pwm_tdiv_get_rate, | ||
265 | .set_rate = clk_pwm_tdiv_set_rate, | ||
266 | .round_rate = clk_pwm_tdiv_round_rate, | ||
267 | }, | ||
268 | }, | ||
269 | [1] = { | ||
270 | .clk = { | ||
271 | .name = "pwm-tdiv", | ||
272 | .parent = &clk_timer_scaler[0], | ||
273 | .get_rate = clk_pwm_tdiv_get_rate, | ||
274 | .set_rate = clk_pwm_tdiv_set_rate, | ||
275 | .round_rate = clk_pwm_tdiv_round_rate, | ||
276 | } | ||
277 | }, | ||
278 | [2] = { | ||
279 | .clk = { | ||
280 | .name = "pwm-tdiv", | ||
281 | .parent = &clk_timer_scaler[1], | ||
282 | .get_rate = clk_pwm_tdiv_get_rate, | ||
283 | .set_rate = clk_pwm_tdiv_set_rate, | ||
284 | .round_rate = clk_pwm_tdiv_round_rate, | ||
285 | }, | ||
286 | }, | ||
287 | [3] = { | ||
288 | .clk = { | ||
289 | .name = "pwm-tdiv", | ||
290 | .parent = &clk_timer_scaler[1], | ||
291 | .get_rate = clk_pwm_tdiv_get_rate, | ||
292 | .set_rate = clk_pwm_tdiv_set_rate, | ||
293 | .round_rate = clk_pwm_tdiv_round_rate, | ||
294 | }, | ||
295 | }, | ||
296 | [4] = { | ||
297 | .clk = { | ||
298 | .name = "pwm-tdiv", | ||
299 | .parent = &clk_timer_scaler[1], | ||
300 | .get_rate = clk_pwm_tdiv_get_rate, | ||
301 | .set_rate = clk_pwm_tdiv_set_rate, | ||
302 | .round_rate = clk_pwm_tdiv_round_rate, | ||
303 | }, | ||
304 | }, | ||
305 | }; | ||
306 | |||
307 | static int __init clk_pwm_tdiv_register(unsigned int id) | ||
308 | { | ||
309 | struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id]; | ||
310 | unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
311 | |||
312 | tcfg1 >>= S3C2410_TCFG1_SHIFT(id); | ||
313 | tcfg1 &= S3C2410_TCFG1_MUX_MASK; | ||
314 | |||
315 | divclk->clk.id = id; | ||
316 | divclk->divisor = tcfg_to_divisor(tcfg1); | ||
317 | |||
318 | return s3c24xx_register_clock(&divclk->clk); | ||
319 | } | ||
320 | |||
321 | static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id) | ||
322 | { | ||
323 | return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0]; | ||
324 | } | ||
325 | |||
326 | static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id) | ||
327 | { | ||
328 | return &clk_timer_tdiv[id].clk; | ||
329 | } | ||
330 | |||
331 | static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent) | ||
332 | { | ||
333 | unsigned int id = clk->id; | ||
334 | unsigned long tcfg1; | ||
335 | unsigned long flags; | ||
336 | unsigned long bits; | ||
337 | unsigned long shift = S3C2410_TCFG1_SHIFT(id); | ||
338 | |||
339 | if (parent == s3c24xx_pwmclk_tclk(id)) | ||
340 | bits = S3C_TCFG1_MUX_TCLK << shift; | ||
341 | else if (parent == s3c24xx_pwmclk_tdiv(id)) | ||
342 | bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift; | ||
343 | else | ||
344 | return -EINVAL; | ||
345 | |||
346 | clk->parent = parent; | ||
347 | |||
348 | local_irq_save(flags); | ||
349 | |||
350 | tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
351 | tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift); | ||
352 | __raw_writel(tcfg1 | bits, S3C2410_TCFG1); | ||
353 | |||
354 | local_irq_restore(flags); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static struct clk clk_tin[] = { | ||
360 | [0] = { | ||
361 | .name = "pwm-tin", | ||
362 | .id = 0, | ||
363 | .set_parent = clk_pwm_tin_set_parent, | ||
364 | }, | ||
365 | [1] = { | ||
366 | .name = "pwm-tin", | ||
367 | .id = 1, | ||
368 | .set_parent = clk_pwm_tin_set_parent, | ||
369 | }, | ||
370 | [2] = { | ||
371 | .name = "pwm-tin", | ||
372 | .id = 2, | ||
373 | .set_parent = clk_pwm_tin_set_parent, | ||
374 | }, | ||
375 | [3] = { | ||
376 | .name = "pwm-tin", | ||
377 | .id = 3, | ||
378 | .set_parent = clk_pwm_tin_set_parent, | ||
379 | }, | ||
380 | [4] = { | ||
381 | .name = "pwm-tin", | ||
382 | .id = 4, | ||
383 | .set_parent = clk_pwm_tin_set_parent, | ||
384 | }, | ||
385 | }; | ||
386 | |||
387 | static __init int clk_pwm_tin_register(struct clk *pwm) | ||
388 | { | ||
389 | unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
390 | unsigned int id = pwm->id; | ||
391 | |||
392 | struct clk *parent; | ||
393 | int ret; | ||
394 | |||
395 | ret = s3c24xx_register_clock(pwm); | ||
396 | if (ret < 0) | ||
397 | return ret; | ||
398 | |||
399 | tcfg1 >>= S3C2410_TCFG1_SHIFT(id); | ||
400 | tcfg1 &= S3C2410_TCFG1_MUX_MASK; | ||
401 | |||
402 | if (pwm_cfg_src_is_tclk(tcfg1)) | ||
403 | parent = s3c24xx_pwmclk_tclk(id); | ||
404 | else | ||
405 | parent = s3c24xx_pwmclk_tdiv(id); | ||
406 | |||
407 | return clk_set_parent(pwm, parent); | ||
408 | } | ||
409 | |||
410 | /** | ||
411 | * s3c_pwmclk_init() - initialise pwm clocks | ||
412 | * | ||
413 | * Initialise and register the clocks which provide the inputs for the | ||
414 | * pwm timer blocks. | ||
415 | * | ||
416 | * Note, this call is required by the time core, so must be called after | ||
417 | * the base clocks are added and before any of the initcalls are run. | ||
418 | */ | ||
419 | __init void s3c_pwmclk_init(void) | ||
420 | { | ||
421 | struct clk *clk_timers; | ||
422 | unsigned int clk; | ||
423 | int ret; | ||
424 | |||
425 | clk_timers = clk_get(NULL, "timers"); | ||
426 | if (IS_ERR(clk_timers)) { | ||
427 | printk(KERN_ERR "%s: no parent clock\n", __func__); | ||
428 | return; | ||
429 | } | ||
430 | |||
431 | for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) { | ||
432 | clk_timer_scaler[clk].parent = clk_timers; | ||
433 | ret = s3c24xx_register_clock(&clk_timer_scaler[clk]); | ||
434 | if (ret < 0) { | ||
435 | printk(KERN_ERR "error adding pwm scaler%d clock\n", clk); | ||
436 | return; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | for (clk = 0; clk < ARRAY_SIZE(clk_timer_tclk); clk++) { | ||
441 | ret = s3c24xx_register_clock(&clk_timer_tclk[clk]); | ||
442 | if (ret < 0) { | ||
443 | printk(KERN_ERR "error adding pww tclk%d\n", clk); | ||
444 | return; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) { | ||
449 | ret = clk_pwm_tdiv_register(clk); | ||
450 | if (ret < 0) { | ||
451 | printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk); | ||
452 | return; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) { | ||
457 | ret = clk_pwm_tin_register(&clk_tin[clk]); | ||
458 | if (ret < 0) { | ||
459 | printk(KERN_ERR "error adding pwm%d tin clock\n", clk); | ||
460 | return; | ||
461 | } | ||
462 | } | ||
463 | } | ||
diff --git a/arch/arm/plat-s3c/time.c b/arch/arm/plat-s3c/time.c new file mode 100644 index 000000000000..3b27b29da478 --- /dev/null +++ b/arch/arm/plat-s3c/time.c | |||
@@ -0,0 +1,285 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/time.c | ||
2 | * | ||
3 | * Copyright (C) 2003-2005 Simtec Electronics | ||
4 | * Ben Dooks, <ben@simtec.co.uk> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/clk.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | |||
31 | #include <asm/system.h> | ||
32 | #include <asm/leds.h> | ||
33 | #include <asm/mach-types.h> | ||
34 | |||
35 | #include <asm/irq.h> | ||
36 | #include <mach/map.h> | ||
37 | #include <plat/regs-timer.h> | ||
38 | #include <mach/regs-irq.h> | ||
39 | #include <asm/mach/time.h> | ||
40 | #include <mach/tick.h> | ||
41 | |||
42 | #include <plat/clock.h> | ||
43 | #include <plat/cpu.h> | ||
44 | |||
45 | static unsigned long timer_startval; | ||
46 | static unsigned long timer_usec_ticks; | ||
47 | |||
48 | #ifndef TICK_MAX | ||
49 | #define TICK_MAX (0xffff) | ||
50 | #endif | ||
51 | |||
52 | #define TIMER_USEC_SHIFT 16 | ||
53 | |||
54 | /* we use the shifted arithmetic to work out the ratio of timer ticks | ||
55 | * to usecs, as often the peripheral clock is not a nice even multiple | ||
56 | * of 1MHz. | ||
57 | * | ||
58 | * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok | ||
59 | * for the current HZ value of 200 without producing overflows. | ||
60 | * | ||
61 | * Original patch by Dimitry Andric, updated by Ben Dooks | ||
62 | */ | ||
63 | |||
64 | |||
65 | /* timer_mask_usec_ticks | ||
66 | * | ||
67 | * given a clock and divisor, make the value to pass into timer_ticks_to_usec | ||
68 | * to scale the ticks into usecs | ||
69 | */ | ||
70 | |||
71 | static inline unsigned long | ||
72 | timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk) | ||
73 | { | ||
74 | unsigned long den = pclk / 1000; | ||
75 | |||
76 | return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den; | ||
77 | } | ||
78 | |||
79 | /* timer_ticks_to_usec | ||
80 | * | ||
81 | * convert timer ticks to usec. | ||
82 | */ | ||
83 | |||
84 | static inline unsigned long timer_ticks_to_usec(unsigned long ticks) | ||
85 | { | ||
86 | unsigned long res; | ||
87 | |||
88 | res = ticks * timer_usec_ticks; | ||
89 | res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */ | ||
90 | |||
91 | return res >> TIMER_USEC_SHIFT; | ||
92 | } | ||
93 | |||
94 | /*** | ||
95 | * Returns microsecond since last clock interrupt. Note that interrupts | ||
96 | * will have been disabled by do_gettimeoffset() | ||
97 | * IRQs are disabled before entering here from do_gettimeofday() | ||
98 | */ | ||
99 | |||
100 | static unsigned long s3c2410_gettimeoffset (void) | ||
101 | { | ||
102 | unsigned long tdone; | ||
103 | unsigned long tval; | ||
104 | |||
105 | /* work out how many ticks have gone since last timer interrupt */ | ||
106 | |||
107 | tval = __raw_readl(S3C2410_TCNTO(4)); | ||
108 | tdone = timer_startval - tval; | ||
109 | |||
110 | /* check to see if there is an interrupt pending */ | ||
111 | |||
112 | if (s3c24xx_ostimer_pending()) { | ||
113 | /* re-read the timer, and try and fix up for the missed | ||
114 | * interrupt. Note, the interrupt may go off before the | ||
115 | * timer has re-loaded from wrapping. | ||
116 | */ | ||
117 | |||
118 | tval = __raw_readl(S3C2410_TCNTO(4)); | ||
119 | tdone = timer_startval - tval; | ||
120 | |||
121 | if (tval != 0) | ||
122 | tdone += timer_startval; | ||
123 | } | ||
124 | |||
125 | return timer_ticks_to_usec(tdone); | ||
126 | } | ||
127 | |||
128 | |||
129 | /* | ||
130 | * IRQ handler for the timer | ||
131 | */ | ||
132 | static irqreturn_t | ||
133 | s3c2410_timer_interrupt(int irq, void *dev_id) | ||
134 | { | ||
135 | timer_tick(); | ||
136 | return IRQ_HANDLED; | ||
137 | } | ||
138 | |||
139 | static struct irqaction s3c2410_timer_irq = { | ||
140 | .name = "S3C2410 Timer Tick", | ||
141 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | ||
142 | .handler = s3c2410_timer_interrupt, | ||
143 | }; | ||
144 | |||
145 | #define use_tclk1_12() ( \ | ||
146 | machine_is_bast() || \ | ||
147 | machine_is_vr1000() || \ | ||
148 | machine_is_anubis() || \ | ||
149 | machine_is_osiris()) | ||
150 | |||
151 | static struct clk *tin; | ||
152 | static struct clk *tdiv; | ||
153 | static struct clk *timerclk; | ||
154 | |||
155 | /* | ||
156 | * Set up timer interrupt, and return the current time in seconds. | ||
157 | * | ||
158 | * Currently we only use timer4, as it is the only timer which has no | ||
159 | * other function that can be exploited externally | ||
160 | */ | ||
161 | static void s3c2410_timer_setup (void) | ||
162 | { | ||
163 | unsigned long tcon; | ||
164 | unsigned long tcnt; | ||
165 | unsigned long tcfg1; | ||
166 | unsigned long tcfg0; | ||
167 | |||
168 | tcnt = TICK_MAX; /* default value for tcnt */ | ||
169 | |||
170 | /* configure the system for whichever machine is in use */ | ||
171 | |||
172 | if (use_tclk1_12()) { | ||
173 | /* timer is at 12MHz, scaler is 1 */ | ||
174 | timer_usec_ticks = timer_mask_usec_ticks(1, 12000000); | ||
175 | tcnt = 12000000 / HZ; | ||
176 | |||
177 | tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
178 | tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; | ||
179 | tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1; | ||
180 | __raw_writel(tcfg1, S3C2410_TCFG1); | ||
181 | } else { | ||
182 | unsigned long pclk; | ||
183 | struct clk *tscaler; | ||
184 | |||
185 | /* for the h1940 (and others), we use the pclk from the core | ||
186 | * to generate the timer values. since values around 50 to | ||
187 | * 70MHz are not values we can directly generate the timer | ||
188 | * value from, we need to pre-scale and divide before using it. | ||
189 | * | ||
190 | * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz | ||
191 | * (8.45 ticks per usec) | ||
192 | */ | ||
193 | |||
194 | pclk = clk_get_rate(timerclk); | ||
195 | |||
196 | /* configure clock tick */ | ||
197 | |||
198 | timer_usec_ticks = timer_mask_usec_ticks(6, pclk); | ||
199 | |||
200 | tscaler = clk_get_parent(tdiv); | ||
201 | |||
202 | clk_set_rate(tscaler, pclk / 3); | ||
203 | clk_set_rate(tdiv, pclk / 6); | ||
204 | clk_set_parent(tin, tdiv); | ||
205 | |||
206 | tcnt = clk_get_rate(tin) / HZ; | ||
207 | } | ||
208 | |||
209 | tcon = __raw_readl(S3C2410_TCON); | ||
210 | tcfg0 = __raw_readl(S3C2410_TCFG0); | ||
211 | tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
212 | |||
213 | /* timers reload after counting zero, so reduce the count by 1 */ | ||
214 | |||
215 | tcnt--; | ||
216 | |||
217 | printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n", | ||
218 | tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks); | ||
219 | |||
220 | /* check to see if timer is within 16bit range... */ | ||
221 | if (tcnt > TICK_MAX) { | ||
222 | panic("setup_timer: HZ is too small, cannot configure timer!"); | ||
223 | return; | ||
224 | } | ||
225 | |||
226 | __raw_writel(tcfg1, S3C2410_TCFG1); | ||
227 | __raw_writel(tcfg0, S3C2410_TCFG0); | ||
228 | |||
229 | timer_startval = tcnt; | ||
230 | __raw_writel(tcnt, S3C2410_TCNTB(4)); | ||
231 | |||
232 | /* ensure timer is stopped... */ | ||
233 | |||
234 | tcon &= ~(7<<20); | ||
235 | tcon |= S3C2410_TCON_T4RELOAD; | ||
236 | tcon |= S3C2410_TCON_T4MANUALUPD; | ||
237 | |||
238 | __raw_writel(tcon, S3C2410_TCON); | ||
239 | __raw_writel(tcnt, S3C2410_TCNTB(4)); | ||
240 | __raw_writel(tcnt, S3C2410_TCMPB(4)); | ||
241 | |||
242 | /* start the timer running */ | ||
243 | tcon |= S3C2410_TCON_T4START; | ||
244 | tcon &= ~S3C2410_TCON_T4MANUALUPD; | ||
245 | __raw_writel(tcon, S3C2410_TCON); | ||
246 | } | ||
247 | |||
248 | static void __init s3c2410_timer_resources(void) | ||
249 | { | ||
250 | struct platform_device tmpdev; | ||
251 | |||
252 | tmpdev.dev.bus = &platform_bus_type; | ||
253 | tmpdev.id = 4; | ||
254 | |||
255 | timerclk = clk_get(NULL, "timers"); | ||
256 | if (IS_ERR(timerclk)) | ||
257 | panic("failed to get clock for system timer"); | ||
258 | |||
259 | clk_enable(timerclk); | ||
260 | |||
261 | if (!use_tclk1_12()) { | ||
262 | tin = clk_get(&tmpdev.dev, "pwm-tin"); | ||
263 | if (IS_ERR(tin)) | ||
264 | panic("failed to get pwm-tin clock for system timer"); | ||
265 | |||
266 | tdiv = clk_get(&tmpdev.dev, "pwm-tdiv"); | ||
267 | if (IS_ERR(tdiv)) | ||
268 | panic("failed to get pwm-tdiv clock for system timer"); | ||
269 | } | ||
270 | |||
271 | clk_enable(tin); | ||
272 | } | ||
273 | |||
274 | static void __init s3c2410_timer_init(void) | ||
275 | { | ||
276 | s3c2410_timer_resources(); | ||
277 | s3c2410_timer_setup(); | ||
278 | setup_irq(IRQ_TIMER4, &s3c2410_timer_irq); | ||
279 | } | ||
280 | |||
281 | struct sys_timer s3c24xx_timer = { | ||
282 | .init = s3c2410_timer_init, | ||
283 | .offset = s3c2410_gettimeoffset, | ||
284 | .resume = s3c2410_timer_setup | ||
285 | }; | ||