aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/coldfire
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@uclinux.org>2014-08-18 21:39:09 -0400
committerGreg Ungerer <gerg@uclinux.org>2014-09-28 19:18:34 -0400
commitf86b9e03837beafb4b48d53a76ee4b88559226de (patch)
tree53a673c3719aec83c6c55c265ed6e6433d6550ca /arch/m68k/coldfire
parentfe82dcec644244676d55a1384c958d5f67979adb (diff)
m68k: move coldfire platform code
Move the m68k ColdFire platform support code directory to be with the existing m68k platforms. Although the ColdFire is not a platform as such, we have always kept all its support together. No reason to change that as this time. Signed-off-by: Greg Ungerer <gerg@uclinux.org> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'arch/m68k/coldfire')
-rw-r--r--arch/m68k/coldfire/Makefile41
-rw-r--r--arch/m68k/coldfire/cache.c48
-rw-r--r--arch/m68k/coldfire/clk.c124
-rw-r--r--arch/m68k/coldfire/device.c369
-rw-r--r--arch/m68k/coldfire/dma.c42
-rw-r--r--arch/m68k/coldfire/dma_timer.c81
-rw-r--r--arch/m68k/coldfire/entry.S203
-rw-r--r--arch/m68k/coldfire/firebee.c86
-rw-r--r--arch/m68k/coldfire/gpio.c186
-rw-r--r--arch/m68k/coldfire/head.S298
-rw-r--r--arch/m68k/coldfire/intc-2.c212
-rw-r--r--arch/m68k/coldfire/intc-5249.c61
-rw-r--r--arch/m68k/coldfire/intc-525x.c91
-rw-r--r--arch/m68k/coldfire/intc-5272.c185
-rw-r--r--arch/m68k/coldfire/intc-simr.c199
-rw-r--r--arch/m68k/coldfire/intc.c150
-rw-r--r--arch/m68k/coldfire/m5206.c58
-rw-r--r--arch/m68k/coldfire/m520x.c180
-rw-r--r--arch/m68k/coldfire/m523x.c86
-rw-r--r--arch/m68k/coldfire/m5249.c126
-rw-r--r--arch/m68k/coldfire/m525x.c88
-rw-r--r--arch/m68k/coldfire/m5272.c135
-rw-r--r--arch/m68k/coldfire/m527x.c126
-rw-r--r--arch/m68k/coldfire/m528x.c132
-rw-r--r--arch/m68k/coldfire/m5307.c78
-rw-r--r--arch/m68k/coldfire/m53xx.c588
-rw-r--r--arch/m68k/coldfire/m5407.c53
-rw-r--r--arch/m68k/coldfire/m5441x.c261
-rw-r--r--arch/m68k/coldfire/m54xx.c129
-rw-r--r--arch/m68k/coldfire/mcf8390.c38
-rw-r--r--arch/m68k/coldfire/nettel.c153
-rw-r--r--arch/m68k/coldfire/pci.c325
-rw-r--r--arch/m68k/coldfire/pit.c167
-rw-r--r--arch/m68k/coldfire/reset.c50
-rw-r--r--arch/m68k/coldfire/sltimers.c149
-rw-r--r--arch/m68k/coldfire/timers.c195
-rw-r--r--arch/m68k/coldfire/vectors.c70
37 files changed, 5563 insertions, 0 deletions
diff --git a/arch/m68k/coldfire/Makefile b/arch/m68k/coldfire/Makefile
new file mode 100644
index 000000000000..68f0fac60099
--- /dev/null
+++ b/arch/m68k/coldfire/Makefile
@@ -0,0 +1,41 @@
1#
2# Makefile for the m68knommu kernel.
3#
4
5#
6# If you want to play with the HW breakpoints then you will
7# need to add define this, which will give you a stack backtrace
8# on the console port whenever a DBG interrupt occurs. You have to
9# set up you HW breakpoints to trigger a DBG interrupt:
10#
11# ccflags-y := -DTRAP_DBG_INTERRUPT
12# asflags-y := -DTRAP_DBG_INTERRUPT
13#
14
15asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
16
17obj-$(CONFIG_COLDFIRE) += cache.o clk.o device.o dma.o entry.o vectors.o
18obj-$(CONFIG_M5206) += m5206.o timers.o intc.o reset.o
19obj-$(CONFIG_M5206e) += m5206.o timers.o intc.o reset.o
20obj-$(CONFIG_M520x) += m520x.o pit.o intc-simr.o reset.o
21obj-$(CONFIG_M523x) += m523x.o pit.o dma_timer.o intc-2.o reset.o
22obj-$(CONFIG_M5249) += m5249.o timers.o intc.o intc-5249.o reset.o
23obj-$(CONFIG_M525x) += m525x.o timers.o intc.o intc-525x.o reset.o
24obj-$(CONFIG_M527x) += m527x.o pit.o intc-2.o reset.o
25obj-$(CONFIG_M5272) += m5272.o intc-5272.o timers.o
26obj-$(CONFIG_M528x) += m528x.o pit.o intc-2.o reset.o
27obj-$(CONFIG_M5307) += m5307.o timers.o intc.o reset.o
28obj-$(CONFIG_M53xx) += m53xx.o timers.o intc-simr.o reset.o
29obj-$(CONFIG_M5407) += m5407.o timers.o intc.o reset.o
30obj-$(CONFIG_M54xx) += m54xx.o sltimers.o intc-2.o
31obj-$(CONFIG_M5441x) += m5441x.o pit.o intc-simr.o reset.o
32
33obj-$(CONFIG_NETtel) += nettel.o
34obj-$(CONFIG_CLEOPATRA) += nettel.o
35obj-$(CONFIG_FIREBEE) += firebee.o
36obj-$(CONFIG_MCF8390) += mcf8390.o
37
38obj-$(CONFIG_PCI) += pci.o
39
40obj-y += gpio.o
41extra-y := head.o
diff --git a/arch/m68k/coldfire/cache.c b/arch/m68k/coldfire/cache.c
new file mode 100644
index 000000000000..71beeaf0c5c4
--- /dev/null
+++ b/arch/m68k/coldfire/cache.c
@@ -0,0 +1,48 @@
1/***************************************************************************/
2
3/*
4 * cache.c -- general ColdFire Cache maintenance code
5 *
6 * Copyright (C) 2010, Greg Ungerer (gerg@snapgear.com)
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <asm/coldfire.h>
13#include <asm/mcfsim.h>
14
15/***************************************************************************/
16#ifdef CACHE_PUSH
17/***************************************************************************/
18
19/*
20 * Use cpushl to push all dirty cache lines back to memory.
21 * Older versions of GAS don't seem to know how to generate the
22 * ColdFire cpushl instruction... Oh well, bit stuff it for now.
23 */
24
25void mcf_cache_push(void)
26{
27 __asm__ __volatile__ (
28 "clrl %%d0\n\t"
29 "1:\n\t"
30 "movel %%d0,%%a0\n\t"
31 "2:\n\t"
32 ".word 0xf468\n\t"
33 "addl %0,%%a0\n\t"
34 "cmpl %1,%%a0\n\t"
35 "blt 2b\n\t"
36 "addql #1,%%d0\n\t"
37 "cmpil %2,%%d0\n\t"
38 "bne 1b\n\t"
39 : /* No output */
40 : "i" (CACHE_LINE_SIZE),
41 "i" (DCACHE_SIZE / CACHE_WAYS),
42 "i" (CACHE_WAYS)
43 : "d0", "a0" );
44}
45
46/***************************************************************************/
47#endif /* CACHE_PUSH */
48/***************************************************************************/
diff --git a/arch/m68k/coldfire/clk.c b/arch/m68k/coldfire/clk.c
new file mode 100644
index 000000000000..fddfdccae63b
--- /dev/null
+++ b/arch/m68k/coldfire/clk.c
@@ -0,0 +1,124 @@
1/***************************************************************************/
2
3/*
4 * clk.c -- general ColdFire CPU kernel clk handling
5 *
6 * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/mutex.h>
15#include <linux/clk.h>
16#include <linux/io.h>
17#include <linux/err.h>
18#include <asm/coldfire.h>
19#include <asm/mcfsim.h>
20#include <asm/mcfclk.h>
21
22static DEFINE_SPINLOCK(clk_lock);
23
24#ifdef MCFPM_PPMCR0
25/*
26 * For more advanced ColdFire parts that have clocks that can be enabled
27 * we supply enable/disable functions. These must properly define their
28 * clocks in their platform specific code.
29 */
30void __clk_init_enabled(struct clk *clk)
31{
32 clk->enabled = 1;
33 clk->clk_ops->enable(clk);
34}
35
36void __clk_init_disabled(struct clk *clk)
37{
38 clk->enabled = 0;
39 clk->clk_ops->disable(clk);
40}
41
42static void __clk_enable0(struct clk *clk)
43{
44 __raw_writeb(clk->slot, MCFPM_PPMCR0);
45}
46
47static void __clk_disable0(struct clk *clk)
48{
49 __raw_writeb(clk->slot, MCFPM_PPMSR0);
50}
51
52struct clk_ops clk_ops0 = {
53 .enable = __clk_enable0,
54 .disable = __clk_disable0,
55};
56
57#ifdef MCFPM_PPMCR1
58static void __clk_enable1(struct clk *clk)
59{
60 __raw_writeb(clk->slot, MCFPM_PPMCR1);
61}
62
63static void __clk_disable1(struct clk *clk)
64{
65 __raw_writeb(clk->slot, MCFPM_PPMSR1);
66}
67
68struct clk_ops clk_ops1 = {
69 .enable = __clk_enable1,
70 .disable = __clk_disable1,
71};
72#endif /* MCFPM_PPMCR1 */
73#endif /* MCFPM_PPMCR0 */
74
75struct clk *clk_get(struct device *dev, const char *id)
76{
77 const char *clk_name = dev ? dev_name(dev) : id ? id : NULL;
78 struct clk *clk;
79 unsigned i;
80
81 for (i = 0; (clk = mcf_clks[i]) != NULL; ++i)
82 if (!strcmp(clk->name, clk_name))
83 return clk;
84 pr_warn("clk_get: didn't find clock %s\n", clk_name);
85 return ERR_PTR(-ENOENT);
86}
87EXPORT_SYMBOL(clk_get);
88
89int clk_enable(struct clk *clk)
90{
91 unsigned long flags;
92 spin_lock_irqsave(&clk_lock, flags);
93 if ((clk->enabled++ == 0) && clk->clk_ops)
94 clk->clk_ops->enable(clk);
95 spin_unlock_irqrestore(&clk_lock, flags);
96
97 return 0;
98}
99EXPORT_SYMBOL(clk_enable);
100
101void clk_disable(struct clk *clk)
102{
103 unsigned long flags;
104 spin_lock_irqsave(&clk_lock, flags);
105 if ((--clk->enabled == 0) && clk->clk_ops)
106 clk->clk_ops->disable(clk);
107 spin_unlock_irqrestore(&clk_lock, flags);
108}
109EXPORT_SYMBOL(clk_disable);
110
111void clk_put(struct clk *clk)
112{
113 if (clk->enabled != 0)
114 pr_warn("clk_put %s still enabled\n", clk->name);
115}
116EXPORT_SYMBOL(clk_put);
117
118unsigned long clk_get_rate(struct clk *clk)
119{
120 return clk->rate;
121}
122EXPORT_SYMBOL(clk_get_rate);
123
124/***************************************************************************/
diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c
new file mode 100644
index 000000000000..71ea4c02795d
--- /dev/null
+++ b/arch/m68k/coldfire/device.c
@@ -0,0 +1,369 @@
1/*
2 * device.c -- common ColdFire SoC device support
3 *
4 * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/io.h>
14#include <linux/spi/spi.h>
15#include <linux/gpio.h>
16#include <linux/fec.h>
17#include <asm/traps.h>
18#include <asm/coldfire.h>
19#include <asm/mcfsim.h>
20#include <asm/mcfuart.h>
21#include <asm/mcfqspi.h>
22
23/*
24 * All current ColdFire parts contain from 2, 3, 4 or 10 UARTS.
25 */
26static struct mcf_platform_uart mcf_uart_platform_data[] = {
27 {
28 .mapbase = MCFUART_BASE0,
29 .irq = MCF_IRQ_UART0,
30 },
31 {
32 .mapbase = MCFUART_BASE1,
33 .irq = MCF_IRQ_UART1,
34 },
35#ifdef MCFUART_BASE2
36 {
37 .mapbase = MCFUART_BASE2,
38 .irq = MCF_IRQ_UART2,
39 },
40#endif
41#ifdef MCFUART_BASE3
42 {
43 .mapbase = MCFUART_BASE3,
44 .irq = MCF_IRQ_UART3,
45 },
46#endif
47#ifdef MCFUART_BASE4
48 {
49 .mapbase = MCFUART_BASE4,
50 .irq = MCF_IRQ_UART4,
51 },
52#endif
53#ifdef MCFUART_BASE5
54 {
55 .mapbase = MCFUART_BASE5,
56 .irq = MCF_IRQ_UART5,
57 },
58#endif
59#ifdef MCFUART_BASE6
60 {
61 .mapbase = MCFUART_BASE6,
62 .irq = MCF_IRQ_UART6,
63 },
64#endif
65#ifdef MCFUART_BASE7
66 {
67 .mapbase = MCFUART_BASE7,
68 .irq = MCF_IRQ_UART7,
69 },
70#endif
71#ifdef MCFUART_BASE8
72 {
73 .mapbase = MCFUART_BASE8,
74 .irq = MCF_IRQ_UART8,
75 },
76#endif
77#ifdef MCFUART_BASE9
78 {
79 .mapbase = MCFUART_BASE9,
80 .irq = MCF_IRQ_UART9,
81 },
82#endif
83 { },
84};
85
86static struct platform_device mcf_uart = {
87 .name = "mcfuart",
88 .id = 0,
89 .dev.platform_data = mcf_uart_platform_data,
90};
91
92#ifdef CONFIG_FEC
93
94#ifdef CONFIG_M5441x
95#define FEC_NAME "enet-fec"
96static struct fec_platform_data fec_pdata = {
97 .phy = PHY_INTERFACE_MODE_RMII,
98};
99#define FEC_PDATA (&fec_pdata)
100#else
101#define FEC_NAME "fec"
102#define FEC_PDATA NULL
103#endif
104
105/*
106 * Some ColdFire cores contain the Fast Ethernet Controller (FEC)
107 * block. It is Freescale's own hardware block. Some ColdFires
108 * have 2 of these.
109 */
110static struct resource mcf_fec0_resources[] = {
111 {
112 .start = MCFFEC_BASE0,
113 .end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
114 .flags = IORESOURCE_MEM,
115 },
116 {
117 .start = MCF_IRQ_FECRX0,
118 .end = MCF_IRQ_FECRX0,
119 .flags = IORESOURCE_IRQ,
120 },
121 {
122 .start = MCF_IRQ_FECTX0,
123 .end = MCF_IRQ_FECTX0,
124 .flags = IORESOURCE_IRQ,
125 },
126 {
127 .start = MCF_IRQ_FECENTC0,
128 .end = MCF_IRQ_FECENTC0,
129 .flags = IORESOURCE_IRQ,
130 },
131};
132
133static struct platform_device mcf_fec0 = {
134 .name = FEC_NAME,
135 .id = 0,
136 .num_resources = ARRAY_SIZE(mcf_fec0_resources),
137 .resource = mcf_fec0_resources,
138 .dev.platform_data = FEC_PDATA,
139};
140
141#ifdef MCFFEC_BASE1
142static struct resource mcf_fec1_resources[] = {
143 {
144 .start = MCFFEC_BASE1,
145 .end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
146 .flags = IORESOURCE_MEM,
147 },
148 {
149 .start = MCF_IRQ_FECRX1,
150 .end = MCF_IRQ_FECRX1,
151 .flags = IORESOURCE_IRQ,
152 },
153 {
154 .start = MCF_IRQ_FECTX1,
155 .end = MCF_IRQ_FECTX1,
156 .flags = IORESOURCE_IRQ,
157 },
158 {
159 .start = MCF_IRQ_FECENTC1,
160 .end = MCF_IRQ_FECENTC1,
161 .flags = IORESOURCE_IRQ,
162 },
163};
164
165static struct platform_device mcf_fec1 = {
166 .name = FEC_NAME,
167 .id = 1,
168 .num_resources = ARRAY_SIZE(mcf_fec1_resources),
169 .resource = mcf_fec1_resources,
170 .dev.platform_data = FEC_PDATA,
171};
172#endif /* MCFFEC_BASE1 */
173#endif /* CONFIG_FEC */
174
175#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
176/*
177 * The ColdFire QSPI module is an SPI protocol hardware block used
178 * on a number of different ColdFire CPUs.
179 */
180static struct resource mcf_qspi_resources[] = {
181 {
182 .start = MCFQSPI_BASE,
183 .end = MCFQSPI_BASE + MCFQSPI_SIZE - 1,
184 .flags = IORESOURCE_MEM,
185 },
186 {
187 .start = MCF_IRQ_QSPI,
188 .end = MCF_IRQ_QSPI,
189 .flags = IORESOURCE_IRQ,
190 },
191};
192
193static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
194{
195 int status;
196
197 status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
198 if (status) {
199 pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
200 goto fail0;
201 }
202 status = gpio_direction_output(MCFQSPI_CS0, 1);
203 if (status) {
204 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
205 goto fail1;
206 }
207
208 status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
209 if (status) {
210 pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
211 goto fail1;
212 }
213 status = gpio_direction_output(MCFQSPI_CS1, 1);
214 if (status) {
215 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
216 goto fail2;
217 }
218
219 status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
220 if (status) {
221 pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
222 goto fail2;
223 }
224 status = gpio_direction_output(MCFQSPI_CS2, 1);
225 if (status) {
226 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
227 goto fail3;
228 }
229
230#ifdef MCFQSPI_CS3
231 status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
232 if (status) {
233 pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
234 goto fail3;
235 }
236 status = gpio_direction_output(MCFQSPI_CS3, 1);
237 if (status) {
238 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
239 gpio_free(MCFQSPI_CS3);
240 goto fail3;
241 }
242#endif
243
244 return 0;
245
246fail3:
247 gpio_free(MCFQSPI_CS2);
248fail2:
249 gpio_free(MCFQSPI_CS1);
250fail1:
251 gpio_free(MCFQSPI_CS0);
252fail0:
253 return status;
254}
255
256static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
257{
258#ifdef MCFQSPI_CS3
259 gpio_free(MCFQSPI_CS3);
260#endif
261 gpio_free(MCFQSPI_CS2);
262 gpio_free(MCFQSPI_CS1);
263 gpio_free(MCFQSPI_CS0);
264}
265
266static void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
267 u8 chip_select, bool cs_high)
268{
269 switch (chip_select) {
270 case 0:
271 gpio_set_value(MCFQSPI_CS0, cs_high);
272 break;
273 case 1:
274 gpio_set_value(MCFQSPI_CS1, cs_high);
275 break;
276 case 2:
277 gpio_set_value(MCFQSPI_CS2, cs_high);
278 break;
279#ifdef MCFQSPI_CS3
280 case 3:
281 gpio_set_value(MCFQSPI_CS3, cs_high);
282 break;
283#endif
284 }
285}
286
287static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
288 u8 chip_select, bool cs_high)
289{
290 switch (chip_select) {
291 case 0:
292 gpio_set_value(MCFQSPI_CS0, !cs_high);
293 break;
294 case 1:
295 gpio_set_value(MCFQSPI_CS1, !cs_high);
296 break;
297 case 2:
298 gpio_set_value(MCFQSPI_CS2, !cs_high);
299 break;
300#ifdef MCFQSPI_CS3
301 case 3:
302 gpio_set_value(MCFQSPI_CS3, !cs_high);
303 break;
304#endif
305 }
306}
307
308static struct mcfqspi_cs_control mcf_cs_control = {
309 .setup = mcf_cs_setup,
310 .teardown = mcf_cs_teardown,
311 .select = mcf_cs_select,
312 .deselect = mcf_cs_deselect,
313};
314
315static struct mcfqspi_platform_data mcf_qspi_data = {
316 .bus_num = 0,
317 .num_chipselect = 4,
318 .cs_control = &mcf_cs_control,
319};
320
321static struct platform_device mcf_qspi = {
322 .name = "mcfqspi",
323 .id = 0,
324 .num_resources = ARRAY_SIZE(mcf_qspi_resources),
325 .resource = mcf_qspi_resources,
326 .dev.platform_data = &mcf_qspi_data,
327};
328#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
329
330static struct platform_device *mcf_devices[] __initdata = {
331 &mcf_uart,
332#ifdef CONFIG_FEC
333 &mcf_fec0,
334#ifdef MCFFEC_BASE1
335 &mcf_fec1,
336#endif
337#endif
338#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
339 &mcf_qspi,
340#endif
341};
342
343/*
344 * Some ColdFire UARTs let you set the IRQ line to use.
345 */
346static void __init mcf_uart_set_irq(void)
347{
348#ifdef MCFUART_UIVR
349 /* UART0 interrupt setup */
350 writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR);
351 writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
352 mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
353
354 /* UART1 interrupt setup */
355 writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR);
356 writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
357 mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
358#endif
359}
360
361static int __init mcf_init_devices(void)
362{
363 mcf_uart_set_irq();
364 platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
365 return 0;
366}
367
368arch_initcall(mcf_init_devices);
369
diff --git a/arch/m68k/coldfire/dma.c b/arch/m68k/coldfire/dma.c
new file mode 100644
index 000000000000..df5ce20d181c
--- /dev/null
+++ b/arch/m68k/coldfire/dma.c
@@ -0,0 +1,42 @@
1/***************************************************************************/
2
3/*
4 * dma.c -- Freescale ColdFire DMA support
5 *
6 * Copyright (C) 2007, Greg Ungerer (gerg@snapgear.com)
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <asm/dma.h>
14#include <asm/coldfire.h>
15#include <asm/mcfsim.h>
16#include <asm/mcfdma.h>
17
18/***************************************************************************/
19
20/*
21 * DMA channel base address table.
22 */
23unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
24#ifdef MCFDMA_BASE0
25 MCFDMA_BASE0,
26#endif
27#ifdef MCFDMA_BASE1
28 MCFDMA_BASE1,
29#endif
30#ifdef MCFDMA_BASE2
31 MCFDMA_BASE2,
32#endif
33#ifdef MCFDMA_BASE3
34 MCFDMA_BASE3,
35#endif
36};
37EXPORT_SYMBOL(dma_base_addr);
38
39unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
40EXPORT_SYMBOL(dma_device_address);
41
42/***************************************************************************/
diff --git a/arch/m68k/coldfire/dma_timer.c b/arch/m68k/coldfire/dma_timer.c
new file mode 100644
index 000000000000..235ad57c4707
--- /dev/null
+++ b/arch/m68k/coldfire/dma_timer.c
@@ -0,0 +1,81 @@
1/*
2 * dma_timer.c -- Freescale ColdFire DMA Timer.
3 *
4 * Copyright (C) 2007, Benedikt Spranger <b.spranger@linutronix.de>
5 * Copyright (C) 2008. Sebastian Siewior, Linutronix
6 *
7 */
8
9#include <linux/clocksource.h>
10#include <linux/io.h>
11
12#include <asm/machdep.h>
13#include <asm/coldfire.h>
14#include <asm/mcfpit.h>
15#include <asm/mcfsim.h>
16
17#define DMA_TIMER_0 (0x00)
18#define DMA_TIMER_1 (0x40)
19#define DMA_TIMER_2 (0x80)
20#define DMA_TIMER_3 (0xc0)
21
22#define DTMR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x400)
23#define DTXMR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x402)
24#define DTER0 (MCF_IPSBAR + DMA_TIMER_0 + 0x403)
25#define DTRR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x404)
26#define DTCR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x408)
27#define DTCN0 (MCF_IPSBAR + DMA_TIMER_0 + 0x40c)
28
29#define DMA_FREQ ((MCF_CLK / 2) / 16)
30
31/* DTMR */
32#define DMA_DTMR_RESTART (1 << 3)
33#define DMA_DTMR_CLK_DIV_1 (1 << 1)
34#define DMA_DTMR_CLK_DIV_16 (2 << 1)
35#define DMA_DTMR_ENABLE (1 << 0)
36
37static cycle_t cf_dt_get_cycles(struct clocksource *cs)
38{
39 return __raw_readl(DTCN0);
40}
41
42static struct clocksource clocksource_cf_dt = {
43 .name = "coldfire_dma_timer",
44 .rating = 200,
45 .read = cf_dt_get_cycles,
46 .mask = CLOCKSOURCE_MASK(32),
47 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
48};
49
50static int __init init_cf_dt_clocksource(void)
51{
52 /*
53 * We setup DMA timer 0 in free run mode. This incrementing counter is
54 * used as a highly precious clock source. With MCF_CLOCK = 150 MHz we
55 * get a ~213 ns resolution and the 32bit register will overflow almost
56 * every 15 minutes.
57 */
58 __raw_writeb(0x00, DTXMR0);
59 __raw_writeb(0x00, DTER0);
60 __raw_writel(0x00000000, DTRR0);
61 __raw_writew(DMA_DTMR_CLK_DIV_16 | DMA_DTMR_ENABLE, DTMR0);
62 return clocksource_register_hz(&clocksource_cf_dt, DMA_FREQ);
63}
64
65arch_initcall(init_cf_dt_clocksource);
66
67#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
68#define CYC2NS_SCALE ((1000000 << CYC2NS_SCALE_FACTOR) / (DMA_FREQ / 1000))
69
70static unsigned long long cycles2ns(unsigned long cycl)
71{
72 return (unsigned long long) ((unsigned long long)cycl *
73 CYC2NS_SCALE) >> CYC2NS_SCALE_FACTOR;
74}
75
76unsigned long long sched_clock(void)
77{
78 unsigned long cycl = __raw_readl(DTCN0);
79
80 return cycles2ns(cycl);
81}
diff --git a/arch/m68k/coldfire/entry.S b/arch/m68k/coldfire/entry.S
new file mode 100644
index 000000000000..881ab8e379d4
--- /dev/null
+++ b/arch/m68k/coldfire/entry.S
@@ -0,0 +1,203 @@
1/*
2 * linux/arch/m68knommu/platform/5307/entry.S
3 *
4 * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
5 * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
6 * Kenneth Albanowski <kjahds@kjahds.com>,
7 * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
8 * Copyright (C) 2004-2006 Macq Electronique SA. (www.macqel.com)
9 *
10 * Based on:
11 *
12 * linux/arch/m68k/kernel/entry.S
13 *
14 * Copyright (C) 1991, 1992 Linus Torvalds
15 *
16 * This file is subject to the terms and conditions of the GNU General Public
17 * License. See the file README.legal in the main directory of this archive
18 * for more details.
19 *
20 * Linux/m68k support by Hamish Macdonald
21 *
22 * 68060 fixes by Jesper Skov
23 * ColdFire support by Greg Ungerer (gerg@snapgear.com)
24 * 5307 fixes by David W. Miller
25 * linux 2.4 support David McCullough <davidm@snapgear.com>
26 * Bug, speed and maintainability fixes by Philippe De Muyter <phdm@macqel.be>
27 */
28
29#include <linux/linkage.h>
30#include <asm/unistd.h>
31#include <asm/thread_info.h>
32#include <asm/errno.h>
33#include <asm/setup.h>
34#include <asm/segment.h>
35#include <asm/asm-offsets.h>
36#include <asm/entry.h>
37
38#ifdef CONFIG_COLDFIRE_SW_A7
39/*
40 * Define software copies of the supervisor and user stack pointers.
41 */
42.bss
43sw_ksp:
44.long 0
45sw_usp:
46.long 0
47#endif /* CONFIG_COLDFIRE_SW_A7 */
48
49.text
50
51.globl system_call
52.globl resume
53.globl ret_from_exception
54.globl ret_from_signal
55.globl sys_call_table
56.globl inthandler
57
58enosys:
59 mov.l #sys_ni_syscall,%d3
60 bra 1f
61
62ENTRY(system_call)
63 SAVE_ALL_SYS
64 move #0x2000,%sr /* enable intrs again */
65 GET_CURRENT(%d2)
66
67 cmpl #NR_syscalls,%d0
68 jcc enosys
69 lea sys_call_table,%a0
70 lsll #2,%d0 /* movel %a0@(%d0:l:4),%d3 */
71 movel %a0@(%d0),%d3
72 jeq enosys
73
741:
75 movel %sp,%d2 /* get thread_info pointer */
76 andl #-THREAD_SIZE,%d2 /* at start of kernel stack */
77 movel %d2,%a0
78 movel %a0@,%a1 /* save top of frame */
79 movel %sp,%a1@(TASK_THREAD+THREAD_ESP0)
80 btst #(TIF_SYSCALL_TRACE%8),%a0@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
81 bnes 1f
82
83 movel %d3,%a0
84 jbsr %a0@
85 movel %d0,%sp@(PT_OFF_D0) /* save the return value */
86 jra ret_from_exception
871:
88 movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_OFF_D0 */
89 movel %d2,PT_OFF_D0(%sp) /* on syscall entry */
90 subql #4,%sp
91 SAVE_SWITCH_STACK
92 jbsr syscall_trace_enter
93 RESTORE_SWITCH_STACK
94 addql #4,%sp
95 movel %d3,%a0
96 jbsr %a0@
97 movel %d0,%sp@(PT_OFF_D0) /* save the return value */
98 subql #4,%sp /* dummy return address */
99 SAVE_SWITCH_STACK
100 jbsr syscall_trace_leave
101
102ret_from_signal:
103 RESTORE_SWITCH_STACK
104 addql #4,%sp
105
106ret_from_exception:
107 move #0x2700,%sr /* disable intrs */
108 btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel */
109 jeq Luser_return /* if so, skip resched, signals */
110
111#ifdef CONFIG_PREEMPT
112 movel %sp,%d1 /* get thread_info pointer */
113 andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
114 movel %d1,%a0
115 movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
116 andl #(1<<TIF_NEED_RESCHED),%d1
117 jeq Lkernel_return
118
119 movel %a0@(TINFO_PREEMPT),%d1
120 cmpl #0,%d1
121 jne Lkernel_return
122
123 pea Lkernel_return
124 jmp preempt_schedule_irq /* preempt the kernel */
125#endif
126
127Lkernel_return:
128 moveml %sp@,%d1-%d5/%a0-%a2
129 lea %sp@(32),%sp /* space for 8 regs */
130 movel %sp@+,%d0
131 addql #4,%sp /* orig d0 */
132 addl %sp@+,%sp /* stk adj */
133 rte
134
135Luser_return:
136 movel %sp,%d1 /* get thread_info pointer */
137 andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
138 movel %d1,%a0
139 moveb %a0@(TINFO_FLAGS+3),%d1 /* thread_info->flags (low 8 bits) */
140 jne Lwork_to_do /* still work to do */
141
142Lreturn:
143 RESTORE_USER
144
145Lwork_to_do:
146 movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
147 move #0x2000,%sr /* enable intrs again */
148 btst #TIF_NEED_RESCHED,%d1
149 jne reschedule
150
151Lsignal_return:
152 subql #4,%sp /* dummy return address */
153 SAVE_SWITCH_STACK
154 pea %sp@(SWITCH_STACK_SIZE)
155 jsr do_notify_resume
156 addql #4,%sp
157 RESTORE_SWITCH_STACK
158 addql #4,%sp
159 jmp Luser_return
160
161/*
162 * This is the generic interrupt handler (for all hardware interrupt
163 * sources). Calls up to high level code to do all the work.
164 */
165ENTRY(inthandler)
166 SAVE_ALL_INT
167 GET_CURRENT(%d2)
168
169 movew %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */
170 andl #0x03fc,%d0 /* mask out vector only */
171
172 movel %sp,%sp@- /* push regs arg */
173 lsrl #2,%d0 /* calculate real vector # */
174 movel %d0,%sp@- /* push vector number */
175 jbsr do_IRQ /* call high level irq handler */
176 lea %sp@(8),%sp /* pop args off stack */
177
178 bra ret_from_exception
179
180/*
181 * Beware - when entering resume, prev (the current task) is
182 * in a0, next (the new task) is in a1, so don't change these
183 * registers until their contents are no longer needed.
184 */
185ENTRY(resume)
186 movew %sr,%d1 /* save current status */
187 movew %d1,%a0@(TASK_THREAD+THREAD_SR)
188 movel %a0,%d1 /* get prev thread in d1 */
189 SAVE_SWITCH_STACK
190 movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
191 RDUSP /* movel %usp,%a3 */
192 movel %a3,%a0@(TASK_THREAD+THREAD_USP) /* save thread user stack */
193#ifdef CONFIG_MMU
194 movel %a1,%a2 /* set new current */
195#endif
196 movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore thread user stack */
197 WRUSP /* movel %a3,%usp */
198 movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new kernel stack */
199 movew %a1@(TASK_THREAD+THREAD_SR),%d7 /* restore new status */
200 movew %d7,%sr
201 RESTORE_SWITCH_STACK
202 rts
203
diff --git a/arch/m68k/coldfire/firebee.c b/arch/m68k/coldfire/firebee.c
new file mode 100644
index 000000000000..46d50534f981
--- /dev/null
+++ b/arch/m68k/coldfire/firebee.c
@@ -0,0 +1,86 @@
1/***************************************************************************/
2
3/*
4 * firebee.c -- extra startup code support for the FireBee boards
5 *
6 * Copyright (C) 2011, Greg Ungerer (gerg@snapgear.com)
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/io.h>
14#include <linux/platform_device.h>
15#include <linux/mtd/mtd.h>
16#include <linux/mtd/partitions.h>
17#include <linux/mtd/physmap.h>
18#include <asm/coldfire.h>
19#include <asm/mcfsim.h>
20
21/***************************************************************************/
22
23/*
24 * 8MB of NOR flash fitted to the FireBee board.
25 */
26#define FLASH_PHYS_ADDR 0xe0000000 /* Physical address of flash */
27#define FLASH_PHYS_SIZE 0x00800000 /* Size of flash */
28
29#define PART_BOOT_START 0x00000000 /* Start at bottom of flash */
30#define PART_BOOT_SIZE 0x00040000 /* 256k in size */
31#define PART_IMAGE_START 0x00040000 /* Start after boot loader */
32#define PART_IMAGE_SIZE 0x006c0000 /* Most of flash */
33#define PART_FPGA_START 0x00700000 /* Start at offset 7MB */
34#define PART_FPGA_SIZE 0x00100000 /* 1MB in size */
35
36static struct mtd_partition firebee_flash_parts[] = {
37 {
38 .name = "dBUG",
39 .offset = PART_BOOT_START,
40 .size = PART_BOOT_SIZE,
41 },
42 {
43 .name = "FPGA",
44 .offset = PART_FPGA_START,
45 .size = PART_FPGA_SIZE,
46 },
47 {
48 .name = "image",
49 .offset = PART_IMAGE_START,
50 .size = PART_IMAGE_SIZE,
51 },
52};
53
54static struct physmap_flash_data firebee_flash_data = {
55 .width = 2,
56 .nr_parts = ARRAY_SIZE(firebee_flash_parts),
57 .parts = firebee_flash_parts,
58};
59
60static struct resource firebee_flash_resource = {
61 .start = FLASH_PHYS_ADDR,
62 .end = FLASH_PHYS_ADDR + FLASH_PHYS_SIZE,
63 .flags = IORESOURCE_MEM,
64};
65
66static struct platform_device firebee_flash = {
67 .name = "physmap-flash",
68 .id = 0,
69 .dev = {
70 .platform_data = &firebee_flash_data,
71 },
72 .num_resources = 1,
73 .resource = &firebee_flash_resource,
74};
75
76/***************************************************************************/
77
78static int __init init_firebee(void)
79{
80 platform_device_register(&firebee_flash);
81 return 0;
82}
83
84arch_initcall(init_firebee);
85
86/***************************************************************************/
diff --git a/arch/m68k/coldfire/gpio.c b/arch/m68k/coldfire/gpio.c
new file mode 100644
index 000000000000..e7e428681ec5
--- /dev/null
+++ b/arch/m68k/coldfire/gpio.c
@@ -0,0 +1,186 @@
1/*
2 * Coldfire generic GPIO support.
3 *
4 * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/device.h>
20
21#include <linux/io.h>
22#include <asm/coldfire.h>
23#include <asm/mcfsim.h>
24#include <asm/mcfgpio.h>
25
26int __mcfgpio_get_value(unsigned gpio)
27{
28 return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
29}
30EXPORT_SYMBOL(__mcfgpio_get_value);
31
32void __mcfgpio_set_value(unsigned gpio, int value)
33{
34 if (gpio < MCFGPIO_SCR_START) {
35 unsigned long flags;
36 MCFGPIO_PORTTYPE data;
37
38 local_irq_save(flags);
39 data = mcfgpio_read(__mcfgpio_podr(gpio));
40 if (value)
41 data |= mcfgpio_bit(gpio);
42 else
43 data &= ~mcfgpio_bit(gpio);
44 mcfgpio_write(data, __mcfgpio_podr(gpio));
45 local_irq_restore(flags);
46 } else {
47 if (value)
48 mcfgpio_write(mcfgpio_bit(gpio),
49 MCFGPIO_SETR_PORT(gpio));
50 else
51 mcfgpio_write(~mcfgpio_bit(gpio),
52 MCFGPIO_CLRR_PORT(gpio));
53 }
54}
55EXPORT_SYMBOL(__mcfgpio_set_value);
56
57int __mcfgpio_direction_input(unsigned gpio)
58{
59 unsigned long flags;
60 MCFGPIO_PORTTYPE dir;
61
62 local_irq_save(flags);
63 dir = mcfgpio_read(__mcfgpio_pddr(gpio));
64 dir &= ~mcfgpio_bit(gpio);
65 mcfgpio_write(dir, __mcfgpio_pddr(gpio));
66 local_irq_restore(flags);
67
68 return 0;
69}
70EXPORT_SYMBOL(__mcfgpio_direction_input);
71
72int __mcfgpio_direction_output(unsigned gpio, int value)
73{
74 unsigned long flags;
75 MCFGPIO_PORTTYPE data;
76
77 local_irq_save(flags);
78 data = mcfgpio_read(__mcfgpio_pddr(gpio));
79 data |= mcfgpio_bit(gpio);
80 mcfgpio_write(data, __mcfgpio_pddr(gpio));
81
82 /* now set the data to output */
83 if (gpio < MCFGPIO_SCR_START) {
84 data = mcfgpio_read(__mcfgpio_podr(gpio));
85 if (value)
86 data |= mcfgpio_bit(gpio);
87 else
88 data &= ~mcfgpio_bit(gpio);
89 mcfgpio_write(data, __mcfgpio_podr(gpio));
90 } else {
91 if (value)
92 mcfgpio_write(mcfgpio_bit(gpio),
93 MCFGPIO_SETR_PORT(gpio));
94 else
95 mcfgpio_write(~mcfgpio_bit(gpio),
96 MCFGPIO_CLRR_PORT(gpio));
97 }
98 local_irq_restore(flags);
99 return 0;
100}
101EXPORT_SYMBOL(__mcfgpio_direction_output);
102
103int __mcfgpio_request(unsigned gpio)
104{
105 return 0;
106}
107EXPORT_SYMBOL(__mcfgpio_request);
108
109void __mcfgpio_free(unsigned gpio)
110{
111 __mcfgpio_direction_input(gpio);
112}
113EXPORT_SYMBOL(__mcfgpio_free);
114
115#ifdef CONFIG_GPIOLIB
116
117static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
118{
119 return __mcfgpio_direction_input(offset);
120}
121
122static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
123{
124 return __mcfgpio_get_value(offset);
125}
126
127static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
128 int value)
129{
130 return __mcfgpio_direction_output(offset, value);
131}
132
133static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
134 int value)
135{
136 __mcfgpio_set_value(offset, value);
137}
138
139static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
140{
141 return __mcfgpio_request(offset);
142}
143
144static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
145{
146 __mcfgpio_free(offset);
147}
148
149static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
150{
151#if defined(MCFGPIO_IRQ_MIN)
152 if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
153#else
154 if (offset < MCFGPIO_IRQ_MAX)
155#endif
156 return MCFGPIO_IRQ_VECBASE + offset;
157 else
158 return -EINVAL;
159}
160
161static struct bus_type mcfgpio_subsys = {
162 .name = "gpio",
163 .dev_name = "gpio",
164};
165
166static struct gpio_chip mcfgpio_chip = {
167 .label = "mcfgpio",
168 .request = mcfgpio_request,
169 .free = mcfgpio_free,
170 .direction_input = mcfgpio_direction_input,
171 .direction_output = mcfgpio_direction_output,
172 .get = mcfgpio_get_value,
173 .set = mcfgpio_set_value,
174 .to_irq = mcfgpio_to_irq,
175 .base = 0,
176 .ngpio = MCFGPIO_PIN_MAX,
177};
178
179static int __init mcfgpio_sysinit(void)
180{
181 gpiochip_add(&mcfgpio_chip);
182 return subsys_system_register(&mcfgpio_subsys, NULL);
183}
184
185core_initcall(mcfgpio_sysinit);
186#endif
diff --git a/arch/m68k/coldfire/head.S b/arch/m68k/coldfire/head.S
new file mode 100644
index 000000000000..fa31be297b85
--- /dev/null
+++ b/arch/m68k/coldfire/head.S
@@ -0,0 +1,298 @@
1/*****************************************************************************/
2
3/*
4 * head.S -- common startup code for ColdFire CPUs.
5 *
6 * (C) Copyright 1999-2011, Greg Ungerer <gerg@snapgear.com>.
7 */
8
9/*****************************************************************************/
10
11#include <linux/linkage.h>
12#include <linux/init.h>
13#include <asm/asm-offsets.h>
14#include <asm/coldfire.h>
15#include <asm/mcfsim.h>
16#include <asm/mcfmmu.h>
17#include <asm/thread_info.h>
18
19/*****************************************************************************/
20
21/*
22 * If we don't have a fixed memory size, then lets build in code
23 * to auto detect the DRAM size. Obviously this is the preferred
24 * method, and should work for most boards. It won't work for those
25 * that do not have their RAM starting at address 0, and it only
26 * works on SDRAM (not boards fitted with SRAM).
27 */
28#if CONFIG_RAMSIZE != 0
29.macro GET_MEM_SIZE
30 movel #CONFIG_RAMSIZE,%d0 /* hard coded memory size */
31.endm
32
33#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
34 defined(CONFIG_M5249) || defined(CONFIG_M525x) || \
35 defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
36 defined(CONFIG_M5307) || defined(CONFIG_M5407)
37/*
38 * Not all these devices have exactly the same DRAM controller,
39 * but the DCMR register is virtually identical - give or take
40 * a couple of bits. The only exception is the 5272 devices, their
41 * DRAM controller is quite different.
42 */
43.macro GET_MEM_SIZE
44 movel MCFSIM_DMR0,%d0 /* get mask for 1st bank */
45 btst #0,%d0 /* check if region enabled */
46 beq 1f
47 andl #0xfffc0000,%d0
48 beq 1f
49 addl #0x00040000,%d0 /* convert mask to size */
501:
51 movel MCFSIM_DMR1,%d1 /* get mask for 2nd bank */
52 btst #0,%d1 /* check if region enabled */
53 beq 2f
54 andl #0xfffc0000,%d1
55 beq 2f
56 addl #0x00040000,%d1
57 addl %d1,%d0 /* total mem size in d0 */
582:
59.endm
60
61#elif defined(CONFIG_M5272)
62.macro GET_MEM_SIZE
63 movel MCFSIM_CSOR7,%d0 /* get SDRAM address mask */
64 andil #0xfffff000,%d0 /* mask out chip select options */
65 negl %d0 /* negate bits */
66.endm
67
68#elif defined(CONFIG_M520x)
69.macro GET_MEM_SIZE
70 clrl %d0
71 movel MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */
72 andl #0x1f, %d2 /* Get only the chip select size */
73 beq 3f /* Check if it is enabled */
74 addql #1, %d2 /* Form exponent */
75 moveql #1, %d0
76 lsll %d2, %d0 /* 2 ^ exponent */
773:
78 movel MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */
79 andl #0x1f, %d2 /* Get only the chip select size */
80 beq 4f /* Check if it is enabled */
81 addql #1, %d2 /* Form exponent */
82 moveql #1, %d1
83 lsll %d2, %d1 /* 2 ^ exponent */
84 addl %d1, %d0 /* Total size of SDRAM in d0 */
854:
86.endm
87
88#else
89#error "ERROR: I don't know how to probe your boards memory size?"
90#endif
91
92/*****************************************************************************/
93
94/*
95 * Boards and platforms can do specific early hardware setup if
96 * they need to. Most don't need this, define away if not required.
97 */
98#ifndef PLATFORM_SETUP
99#define PLATFORM_SETUP
100#endif
101
102/*****************************************************************************/
103
104.global _start
105.global _rambase
106.global _ramvec
107.global _ramstart
108.global _ramend
109#if defined(CONFIG_UBOOT)
110.global _init_sp
111#endif
112
113/*****************************************************************************/
114
115.data
116
117/*
118 * During startup we store away the RAM setup. These are not in the
119 * bss, since their values are determined and written before the bss
120 * has been cleared.
121 */
122_rambase:
123.long 0
124_ramvec:
125.long 0
126_ramstart:
127.long 0
128_ramend:
129.long 0
130#if defined(CONFIG_UBOOT)
131_init_sp:
132.long 0
133#endif
134
135/*****************************************************************************/
136
137__HEAD
138
139#ifdef CONFIG_MMU
140_start0:
141 jmp _start
142.global kernel_pg_dir
143.equ kernel_pg_dir,_start0
144.equ .,_start0+0x1000
145#endif
146
147/*
148 * This is the codes first entry point. This is where it all
149 * begins...
150 */
151
152_start:
153 nop /* filler */
154 movew #0x2700, %sr /* no interrupts */
155 movel #CACHE_INIT,%d0 /* disable cache */
156 movec %d0,%CACR
157 nop
158#if defined(CONFIG_UBOOT)
159 movel %sp,_init_sp /* save initial stack pointer */
160#endif
161#ifdef CONFIG_MBAR
162 movel #CONFIG_MBAR+1,%d0 /* configured MBAR address */
163 movec %d0,%MBAR /* set it */
164#endif
165
166 /*
167 * Do any platform or board specific setup now. Most boards
168 * don't need anything. Those exceptions are define this in
169 * their board specific includes.
170 */
171 PLATFORM_SETUP
172
173 /*
174 * Create basic memory configuration. Set VBR accordingly,
175 * and size memory.
176 */
177 movel #CONFIG_VECTORBASE,%a7
178 movec %a7,%VBR /* set vectors addr */
179 movel %a7,_ramvec
180
181 movel #CONFIG_RAMBASE,%a7 /* mark the base of RAM */
182 movel %a7,_rambase
183
184 GET_MEM_SIZE /* macro code determines size */
185 addl %a7,%d0
186 movel %d0,_ramend /* set end ram addr */
187
188 /*
189 * Now that we know what the memory is, lets enable cache
190 * and get things moving. This is Coldfire CPU specific. Not
191 * all version cores have identical cache register setup. But
192 * it is very similar. Define the exact settings in the headers
193 * then the code here is the same for all.
194 */
195 movel #ACR0_MODE,%d0 /* set RAM region for caching */
196 movec %d0,%ACR0
197 movel #ACR1_MODE,%d0 /* anything else to cache? */
198 movec %d0,%ACR1
199#ifdef ACR2_MODE
200 movel #ACR2_MODE,%d0
201 movec %d0,%ACR2
202 movel #ACR3_MODE,%d0
203 movec %d0,%ACR3
204#endif
205 movel #CACHE_MODE,%d0 /* enable cache */
206 movec %d0,%CACR
207 nop
208
209#ifdef CONFIG_MMU
210 /*
211 * Identity mapping for the kernel region.
212 */
213 movel #(MMUBASE+1),%d0 /* enable MMUBAR registers */
214 movec %d0,%MMUBAR
215 movel #MMUOR_CA,%d0 /* clear TLB entries */
216 movel %d0,MMUOR
217 movel #0,%d0 /* set ASID to 0 */
218 movec %d0,%asid
219
220 movel #MMUCR_EN,%d0 /* Enable the identity map */
221 movel %d0,MMUCR
222 nop /* sync i-pipeline */
223
224 movel #_vstart,%a0 /* jump to "virtual" space */
225 jmp %a0@
226_vstart:
227#endif /* CONFIG_MMU */
228
229#ifdef CONFIG_ROMFS_FS
230 /*
231 * Move ROM filesystem above bss :-)
232 */
233 lea __bss_start,%a0 /* get start of bss */
234 lea __bss_stop,%a1 /* set up destination */
235 movel %a0,%a2 /* copy of bss start */
236
237 movel 8(%a0),%d0 /* get size of ROMFS */
238 addql #8,%d0 /* allow for rounding */
239 andl #0xfffffffc, %d0 /* whole words */
240
241 addl %d0,%a0 /* copy from end */
242 addl %d0,%a1 /* copy from end */
243 movel %a1,_ramstart /* set start of ram */
244
245_copy_romfs:
246 movel -(%a0),%d0 /* copy dword */
247 movel %d0,-(%a1)
248 cmpl %a0,%a2 /* check if at end */
249 bne _copy_romfs
250
251#else /* CONFIG_ROMFS_FS */
252 lea __bss_stop,%a1
253 movel %a1,_ramstart
254#endif /* CONFIG_ROMFS_FS */
255
256
257 /*
258 * Zero out the bss region.
259 */
260 lea __bss_start,%a0 /* get start of bss */
261 lea __bss_stop,%a1 /* get end of bss */
262 clrl %d0 /* set value */
263_clear_bss:
264 movel %d0,(%a0)+ /* clear each word */
265 cmpl %a0,%a1 /* check if at end */
266 bne _clear_bss
267
268 /*
269 * Load the current task pointer and stack.
270 */
271 lea init_thread_union,%a0
272 lea THREAD_SIZE(%a0),%sp
273
274#ifdef CONFIG_MMU
275.global m68k_cputype
276.global m68k_mmutype
277.global m68k_fputype
278.global m68k_machtype
279 movel #CPU_COLDFIRE,%d0
280 movel %d0,m68k_cputype /* Mark us as a ColdFire */
281 movel #MMU_COLDFIRE,%d0
282 movel %d0,m68k_mmutype
283 movel #FPU_COLDFIRE,%d0
284 movel %d0,m68k_fputype
285 movel #MACH_M54XX,%d0
286 movel %d0,m68k_machtype /* Mark us as a 54xx machine */
287 lea init_task,%a2 /* Set "current" init task */
288#endif
289
290 /*
291 * Assember start up done, start code proper.
292 */
293 jsr start_kernel /* start Linux kernel */
294
295_exit:
296 jmp _exit /* should never get here */
297
298/*****************************************************************************/
diff --git a/arch/m68k/coldfire/intc-2.c b/arch/m68k/coldfire/intc-2.c
new file mode 100644
index 000000000000..995093357c59
--- /dev/null
+++ b/arch/m68k/coldfire/intc-2.c
@@ -0,0 +1,212 @@
1/*
2 * intc-2.c
3 *
4 * General interrupt controller code for the many ColdFire cores that use
5 * interrupt controllers with 63 interrupt sources, organized as 56 fully-
6 * programmable + 7 fixed-level interrupt sources. This includes the 523x
7 * family, the 5270, 5271, 5274, 5275, and the 528x family which have two such
8 * controllers, and the 547x and 548x families which have only one of them.
9 *
10 * The external 7 fixed interrupts are part the the Edge Port unit of these
11 * ColdFire parts. They can be configured as level or edge triggered.
12 *
13 * (C) Copyright 2009-2011, Greg Ungerer <gerg@snapgear.com>
14 *
15 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file COPYING in the main directory of this archive
17 * for more details.
18 */
19
20#include <linux/types.h>
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25#include <linux/io.h>
26#include <asm/coldfire.h>
27#include <asm/mcfsim.h>
28#include <asm/traps.h>
29
30/*
31 * Bit definitions for the ICR family of registers.
32 */
33#define MCFSIM_ICR_LEVEL(l) ((l)<<3) /* Level l intr */
34#define MCFSIM_ICR_PRI(p) (p) /* Priority p intr */
35
36/*
37 * The EDGE Port interrupts are the fixed 7 external interrupts.
38 * They need some special treatment, for example they need to be acked.
39 */
40#define EINT0 64 /* Is not actually used, but spot reserved for it */
41#define EINT1 65 /* EDGE Port interrupt 1 */
42#define EINT7 71 /* EDGE Port interrupt 7 */
43
44#ifdef MCFICM_INTC1
45#define NR_VECS 128
46#else
47#define NR_VECS 64
48#endif
49
50static void intc_irq_mask(struct irq_data *d)
51{
52 unsigned int irq = d->irq - MCFINT_VECBASE;
53 unsigned long imraddr;
54 u32 val, imrbit;
55
56#ifdef MCFICM_INTC1
57 imraddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
58#else
59 imraddr = MCFICM_INTC0;
60#endif
61 imraddr += (irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL;
62 imrbit = 0x1 << (irq & 0x1f);
63
64 val = __raw_readl(imraddr);
65 __raw_writel(val | imrbit, imraddr);
66}
67
68static void intc_irq_unmask(struct irq_data *d)
69{
70 unsigned int irq = d->irq - MCFINT_VECBASE;
71 unsigned long imraddr;
72 u32 val, imrbit;
73
74#ifdef MCFICM_INTC1
75 imraddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
76#else
77 imraddr = MCFICM_INTC0;
78#endif
79 imraddr += ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
80 imrbit = 0x1 << (irq & 0x1f);
81
82 /* Don't set the "maskall" bit! */
83 if ((irq & 0x20) == 0)
84 imrbit |= 0x1;
85
86 val = __raw_readl(imraddr);
87 __raw_writel(val & ~imrbit, imraddr);
88}
89
90/*
91 * Only the external (or EDGE Port) interrupts need to be acknowledged
92 * here, as part of the IRQ handler. They only really need to be ack'ed
93 * if they are in edge triggered mode, but there is no harm in doing it
94 * for all types.
95 */
96static void intc_irq_ack(struct irq_data *d)
97{
98 unsigned int irq = d->irq;
99
100 __raw_writeb(0x1 << (irq - EINT0), MCFEPORT_EPFR);
101}
102
103/*
104 * Each vector needs a unique priority and level associated with it.
105 * We don't really care so much what they are, we don't rely on the
106 * traditional priority interrupt scheme of the m68k/ColdFire. This
107 * only needs to be set once for an interrupt, and we will never change
108 * these values once we have set them.
109 */
110static u8 intc_intpri = MCFSIM_ICR_LEVEL(6) | MCFSIM_ICR_PRI(6);
111
112static unsigned int intc_irq_startup(struct irq_data *d)
113{
114 unsigned int irq = d->irq - MCFINT_VECBASE;
115 unsigned long icraddr;
116
117#ifdef MCFICM_INTC1
118 icraddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
119#else
120 icraddr = MCFICM_INTC0;
121#endif
122 icraddr += MCFINTC_ICR0 + (irq & 0x3f);
123 if (__raw_readb(icraddr) == 0)
124 __raw_writeb(intc_intpri--, icraddr);
125
126 irq = d->irq;
127 if ((irq >= EINT1) && (irq <= EINT7)) {
128 u8 v;
129
130 irq -= EINT0;
131
132 /* Set EPORT line as input */
133 v = __raw_readb(MCFEPORT_EPDDR);
134 __raw_writeb(v & ~(0x1 << irq), MCFEPORT_EPDDR);
135
136 /* Set EPORT line as interrupt source */
137 v = __raw_readb(MCFEPORT_EPIER);
138 __raw_writeb(v | (0x1 << irq), MCFEPORT_EPIER);
139 }
140
141 intc_irq_unmask(d);
142 return 0;
143}
144
145static int intc_irq_set_type(struct irq_data *d, unsigned int type)
146{
147 unsigned int irq = d->irq;
148 u16 pa, tb;
149
150 switch (type) {
151 case IRQ_TYPE_EDGE_RISING:
152 tb = 0x1;
153 break;
154 case IRQ_TYPE_EDGE_FALLING:
155 tb = 0x2;
156 break;
157 case IRQ_TYPE_EDGE_BOTH:
158 tb = 0x3;
159 break;
160 default:
161 /* Level triggered */
162 tb = 0;
163 break;
164 }
165
166 if (tb)
167 irq_set_handler(irq, handle_edge_irq);
168
169 irq -= EINT0;
170 pa = __raw_readw(MCFEPORT_EPPAR);
171 pa = (pa & ~(0x3 << (irq * 2))) | (tb << (irq * 2));
172 __raw_writew(pa, MCFEPORT_EPPAR);
173
174 return 0;
175}
176
177static struct irq_chip intc_irq_chip = {
178 .name = "CF-INTC",
179 .irq_startup = intc_irq_startup,
180 .irq_mask = intc_irq_mask,
181 .irq_unmask = intc_irq_unmask,
182};
183
184static struct irq_chip intc_irq_chip_edge_port = {
185 .name = "CF-INTC-EP",
186 .irq_startup = intc_irq_startup,
187 .irq_mask = intc_irq_mask,
188 .irq_unmask = intc_irq_unmask,
189 .irq_ack = intc_irq_ack,
190 .irq_set_type = intc_irq_set_type,
191};
192
193void __init init_IRQ(void)
194{
195 int irq;
196
197 /* Mask all interrupt sources */
198 __raw_writel(0x1, MCFICM_INTC0 + MCFINTC_IMRL);
199#ifdef MCFICM_INTC1
200 __raw_writel(0x1, MCFICM_INTC1 + MCFINTC_IMRL);
201#endif
202
203 for (irq = MCFINT_VECBASE; (irq < MCFINT_VECBASE + NR_VECS); irq++) {
204 if ((irq >= EINT1) && (irq <=EINT7))
205 irq_set_chip(irq, &intc_irq_chip_edge_port);
206 else
207 irq_set_chip(irq, &intc_irq_chip);
208 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
209 irq_set_handler(irq, handle_level_irq);
210 }
211}
212
diff --git a/arch/m68k/coldfire/intc-5249.c b/arch/m68k/coldfire/intc-5249.c
new file mode 100644
index 000000000000..b0d1641053e4
--- /dev/null
+++ b/arch/m68k/coldfire/intc-5249.c
@@ -0,0 +1,61 @@
1/*
2 * intc2.c -- support for the 2nd INTC controller of the 5249
3 *
4 * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/types.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/io.h>
17#include <asm/coldfire.h>
18#include <asm/mcfsim.h>
19
20static void intc2_irq_gpio_mask(struct irq_data *d)
21{
22 u32 imr;
23 imr = readl(MCFSIM2_GPIOINTENABLE);
24 imr &= ~(0x1 << (d->irq - MCF_IRQ_GPIO0));
25 writel(imr, MCFSIM2_GPIOINTENABLE);
26}
27
28static void intc2_irq_gpio_unmask(struct irq_data *d)
29{
30 u32 imr;
31 imr = readl(MCFSIM2_GPIOINTENABLE);
32 imr |= (0x1 << (d->irq - MCF_IRQ_GPIO0));
33 writel(imr, MCFSIM2_GPIOINTENABLE);
34}
35
36static void intc2_irq_gpio_ack(struct irq_data *d)
37{
38 writel(0x1 << (d->irq - MCF_IRQ_GPIO0), MCFSIM2_GPIOINTCLEAR);
39}
40
41static struct irq_chip intc2_irq_gpio_chip = {
42 .name = "CF-INTC2",
43 .irq_mask = intc2_irq_gpio_mask,
44 .irq_unmask = intc2_irq_gpio_unmask,
45 .irq_ack = intc2_irq_gpio_ack,
46};
47
48static int __init mcf_intc2_init(void)
49{
50 int irq;
51
52 /* GPIO interrupt sources */
53 for (irq = MCF_IRQ_GPIO0; (irq <= MCF_IRQ_GPIO7); irq++) {
54 irq_set_chip(irq, &intc2_irq_gpio_chip);
55 irq_set_handler(irq, handle_edge_irq);
56 }
57
58 return 0;
59}
60
61arch_initcall(mcf_intc2_init);
diff --git a/arch/m68k/coldfire/intc-525x.c b/arch/m68k/coldfire/intc-525x.c
new file mode 100644
index 000000000000..b23204d059ac
--- /dev/null
+++ b/arch/m68k/coldfire/intc-525x.c
@@ -0,0 +1,91 @@
1/*
2 * intc2.c -- support for the 2nd INTC controller of the 525x
3 *
4 * (C) Copyright 2012, Steven King <sfking@fdwdc.com>
5 * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/types.h>
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/io.h>
18#include <asm/coldfire.h>
19#include <asm/mcfsim.h>
20
21static void intc2_irq_gpio_mask(struct irq_data *d)
22{
23 u32 imr = readl(MCFSIM2_GPIOINTENABLE);
24 u32 type = irqd_get_trigger_type(d);
25 int irq = d->irq - MCF_IRQ_GPIO0;
26
27 if (type & IRQ_TYPE_EDGE_RISING)
28 imr &= ~(0x001 << irq);
29 if (type & IRQ_TYPE_EDGE_FALLING)
30 imr &= ~(0x100 << irq);
31 writel(imr, MCFSIM2_GPIOINTENABLE);
32}
33
34static void intc2_irq_gpio_unmask(struct irq_data *d)
35{
36 u32 imr = readl(MCFSIM2_GPIOINTENABLE);
37 u32 type = irqd_get_trigger_type(d);
38 int irq = d->irq - MCF_IRQ_GPIO0;
39
40 if (type & IRQ_TYPE_EDGE_RISING)
41 imr |= (0x001 << irq);
42 if (type & IRQ_TYPE_EDGE_FALLING)
43 imr |= (0x100 << irq);
44 writel(imr, MCFSIM2_GPIOINTENABLE);
45}
46
47static void intc2_irq_gpio_ack(struct irq_data *d)
48{
49 u32 imr = 0;
50 u32 type = irqd_get_trigger_type(d);
51 int irq = d->irq - MCF_IRQ_GPIO0;
52
53 if (type & IRQ_TYPE_EDGE_RISING)
54 imr |= (0x001 << irq);
55 if (type & IRQ_TYPE_EDGE_FALLING)
56 imr |= (0x100 << irq);
57 writel(imr, MCFSIM2_GPIOINTCLEAR);
58}
59
60static int intc2_irq_gpio_set_type(struct irq_data *d, unsigned int f)
61{
62 if (f & ~IRQ_TYPE_EDGE_BOTH)
63 return -EINVAL;
64 return 0;
65}
66
67static struct irq_chip intc2_irq_gpio_chip = {
68 .name = "CF-INTC2",
69 .irq_mask = intc2_irq_gpio_mask,
70 .irq_unmask = intc2_irq_gpio_unmask,
71 .irq_ack = intc2_irq_gpio_ack,
72 .irq_set_type = intc2_irq_gpio_set_type,
73};
74
75static int __init mcf_intc2_init(void)
76{
77 int irq;
78
79 /* set the interrupt base for the second interrupt controller */
80 writel(MCFINTC2_VECBASE, MCFINTC2_INTBASE);
81
82 /* GPIO interrupt sources */
83 for (irq = MCF_IRQ_GPIO0; (irq <= MCF_IRQ_GPIO6); irq++) {
84 irq_set_chip(irq, &intc2_irq_gpio_chip);
85 irq_set_handler(irq, handle_edge_irq);
86 }
87
88 return 0;
89}
90
91arch_initcall(mcf_intc2_init);
diff --git a/arch/m68k/coldfire/intc-5272.c b/arch/m68k/coldfire/intc-5272.c
new file mode 100644
index 000000000000..d7b695629a7e
--- /dev/null
+++ b/arch/m68k/coldfire/intc-5272.c
@@ -0,0 +1,185 @@
1/*
2 * intc.c -- interrupt controller or ColdFire 5272 SoC
3 *
4 * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/types.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/kernel_stat.h>
16#include <linux/irq.h>
17#include <linux/io.h>
18#include <asm/coldfire.h>
19#include <asm/mcfsim.h>
20#include <asm/traps.h>
21
22/*
23 * The 5272 ColdFire interrupt controller is nothing like any other
24 * ColdFire interrupt controller - it truly is completely different.
25 * Given its age it is unlikely to be used on any other ColdFire CPU.
26 */
27
28/*
29 * The masking and priproty setting of interrupts on the 5272 is done
30 * via a set of 4 "Interrupt Controller Registers" (ICR). There is a
31 * loose mapping of vector number to register and internal bits, but
32 * a table is the easiest and quickest way to map them.
33 *
34 * Note that the external interrupts are edge triggered (unlike the
35 * internal interrupt sources which are level triggered). Which means
36 * they also need acknowledging via acknowledge bits.
37 */
38struct irqmap {
39 unsigned char icr;
40 unsigned char index;
41 unsigned char ack;
42};
43
44static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = {
45 /*MCF_IRQ_SPURIOUS*/ { .icr = 0, .index = 0, .ack = 0, },
46 /*MCF_IRQ_EINT1*/ { .icr = MCFSIM_ICR1, .index = 28, .ack = 1, },
47 /*MCF_IRQ_EINT2*/ { .icr = MCFSIM_ICR1, .index = 24, .ack = 1, },
48 /*MCF_IRQ_EINT3*/ { .icr = MCFSIM_ICR1, .index = 20, .ack = 1, },
49 /*MCF_IRQ_EINT4*/ { .icr = MCFSIM_ICR1, .index = 16, .ack = 1, },
50 /*MCF_IRQ_TIMER1*/ { .icr = MCFSIM_ICR1, .index = 12, .ack = 0, },
51 /*MCF_IRQ_TIMER2*/ { .icr = MCFSIM_ICR1, .index = 8, .ack = 0, },
52 /*MCF_IRQ_TIMER3*/ { .icr = MCFSIM_ICR1, .index = 4, .ack = 0, },
53 /*MCF_IRQ_TIMER4*/ { .icr = MCFSIM_ICR1, .index = 0, .ack = 0, },
54 /*MCF_IRQ_UART1*/ { .icr = MCFSIM_ICR2, .index = 28, .ack = 0, },
55 /*MCF_IRQ_UART2*/ { .icr = MCFSIM_ICR2, .index = 24, .ack = 0, },
56 /*MCF_IRQ_PLIP*/ { .icr = MCFSIM_ICR2, .index = 20, .ack = 0, },
57 /*MCF_IRQ_PLIA*/ { .icr = MCFSIM_ICR2, .index = 16, .ack = 0, },
58 /*MCF_IRQ_USB0*/ { .icr = MCFSIM_ICR2, .index = 12, .ack = 0, },
59 /*MCF_IRQ_USB1*/ { .icr = MCFSIM_ICR2, .index = 8, .ack = 0, },
60 /*MCF_IRQ_USB2*/ { .icr = MCFSIM_ICR2, .index = 4, .ack = 0, },
61 /*MCF_IRQ_USB3*/ { .icr = MCFSIM_ICR2, .index = 0, .ack = 0, },
62 /*MCF_IRQ_USB4*/ { .icr = MCFSIM_ICR3, .index = 28, .ack = 0, },
63 /*MCF_IRQ_USB5*/ { .icr = MCFSIM_ICR3, .index = 24, .ack = 0, },
64 /*MCF_IRQ_USB6*/ { .icr = MCFSIM_ICR3, .index = 20, .ack = 0, },
65 /*MCF_IRQ_USB7*/ { .icr = MCFSIM_ICR3, .index = 16, .ack = 0, },
66 /*MCF_IRQ_DMA*/ { .icr = MCFSIM_ICR3, .index = 12, .ack = 0, },
67 /*MCF_IRQ_ERX*/ { .icr = MCFSIM_ICR3, .index = 8, .ack = 0, },
68 /*MCF_IRQ_ETX*/ { .icr = MCFSIM_ICR3, .index = 4, .ack = 0, },
69 /*MCF_IRQ_ENTC*/ { .icr = MCFSIM_ICR3, .index = 0, .ack = 0, },
70 /*MCF_IRQ_QSPI*/ { .icr = MCFSIM_ICR4, .index = 28, .ack = 0, },
71 /*MCF_IRQ_EINT5*/ { .icr = MCFSIM_ICR4, .index = 24, .ack = 1, },
72 /*MCF_IRQ_EINT6*/ { .icr = MCFSIM_ICR4, .index = 20, .ack = 1, },
73 /*MCF_IRQ_SWTO*/ { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, },
74};
75
76/*
77 * The act of masking the interrupt also has a side effect of 'ack'ing
78 * an interrupt on this irq (for the external irqs). So this mask function
79 * is also an ack_mask function.
80 */
81static void intc_irq_mask(struct irq_data *d)
82{
83 unsigned int irq = d->irq;
84
85 if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
86 u32 v;
87 irq -= MCFINT_VECBASE;
88 v = 0x8 << intc_irqmap[irq].index;
89 writel(v, intc_irqmap[irq].icr);
90 }
91}
92
93static void intc_irq_unmask(struct irq_data *d)
94{
95 unsigned int irq = d->irq;
96
97 if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
98 u32 v;
99 irq -= MCFINT_VECBASE;
100 v = 0xd << intc_irqmap[irq].index;
101 writel(v, intc_irqmap[irq].icr);
102 }
103}
104
105static void intc_irq_ack(struct irq_data *d)
106{
107 unsigned int irq = d->irq;
108
109 /* Only external interrupts are acked */
110 if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
111 irq -= MCFINT_VECBASE;
112 if (intc_irqmap[irq].ack) {
113 u32 v;
114 v = readl(intc_irqmap[irq].icr);
115 v &= (0x7 << intc_irqmap[irq].index);
116 v |= (0x8 << intc_irqmap[irq].index);
117 writel(v, intc_irqmap[irq].icr);
118 }
119 }
120}
121
122static int intc_irq_set_type(struct irq_data *d, unsigned int type)
123{
124 unsigned int irq = d->irq;
125
126 if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
127 irq -= MCFINT_VECBASE;
128 if (intc_irqmap[irq].ack) {
129 u32 v;
130 v = readl(MCFSIM_PITR);
131 if (type == IRQ_TYPE_EDGE_FALLING)
132 v &= ~(0x1 << (32 - irq));
133 else
134 v |= (0x1 << (32 - irq));
135 writel(v, MCFSIM_PITR);
136 }
137 }
138 return 0;
139}
140
141/*
142 * Simple flow handler to deal with the external edge triggered interrupts.
143 * We need to be careful with the masking/acking due to the side effects
144 * of masking an interrupt.
145 */
146static void intc_external_irq(unsigned int irq, struct irq_desc *desc)
147{
148 irq_desc_get_chip(desc)->irq_ack(&desc->irq_data);
149 handle_simple_irq(irq, desc);
150}
151
152static struct irq_chip intc_irq_chip = {
153 .name = "CF-INTC",
154 .irq_mask = intc_irq_mask,
155 .irq_unmask = intc_irq_unmask,
156 .irq_mask_ack = intc_irq_mask,
157 .irq_ack = intc_irq_ack,
158 .irq_set_type = intc_irq_set_type,
159};
160
161void __init init_IRQ(void)
162{
163 int irq, edge;
164
165 /* Mask all interrupt sources */
166 writel(0x88888888, MCFSIM_ICR1);
167 writel(0x88888888, MCFSIM_ICR2);
168 writel(0x88888888, MCFSIM_ICR3);
169 writel(0x88888888, MCFSIM_ICR4);
170
171 for (irq = 0; (irq < NR_IRQS); irq++) {
172 irq_set_chip(irq, &intc_irq_chip);
173 edge = 0;
174 if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX))
175 edge = intc_irqmap[irq - MCFINT_VECBASE].ack;
176 if (edge) {
177 irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
178 irq_set_handler(irq, intc_external_irq);
179 } else {
180 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
181 irq_set_handler(irq, handle_level_irq);
182 }
183 }
184}
185
diff --git a/arch/m68k/coldfire/intc-simr.c b/arch/m68k/coldfire/intc-simr.c
new file mode 100644
index 000000000000..7cf2c156f72d
--- /dev/null
+++ b/arch/m68k/coldfire/intc-simr.c
@@ -0,0 +1,199 @@
1/*
2 * intc-simr.c
3 *
4 * Interrupt controller code for the ColdFire 5208, 5207 & 532x parts.
5 *
6 * (C) Copyright 2009-2011, Greg Ungerer <gerg@snapgear.com>
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/types.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/io.h>
19#include <asm/coldfire.h>
20#include <asm/mcfsim.h>
21#include <asm/traps.h>
22
23/*
24 * The EDGE Port interrupts are the fixed 7 external interrupts.
25 * They need some special treatment, for example they need to be acked.
26 */
27#ifdef CONFIG_M520x
28/*
29 * The 520x parts only support a limited range of these external
30 * interrupts, only 1, 4 and 7 (as interrupts 65, 66 and 67).
31 */
32#define EINT0 64 /* Is not actually used, but spot reserved for it */
33#define EINT1 65 /* EDGE Port interrupt 1 */
34#define EINT4 66 /* EDGE Port interrupt 4 */
35#define EINT7 67 /* EDGE Port interrupt 7 */
36
37static unsigned int irqebitmap[] = { 0, 1, 4, 7 };
38static unsigned int inline irq2ebit(unsigned int irq)
39{
40 return irqebitmap[irq - EINT0];
41}
42
43#else
44
45/*
46 * Most of the ColdFire parts with the EDGE Port module just have
47 * a strait direct mapping of the 7 external interrupts. Although
48 * there is a bit reserved for 0, it is not used.
49 */
50#define EINT0 64 /* Is not actually used, but spot reserved for it */
51#define EINT1 65 /* EDGE Port interrupt 1 */
52#define EINT7 71 /* EDGE Port interrupt 7 */
53
54static unsigned int inline irq2ebit(unsigned int irq)
55{
56 return irq - EINT0;
57}
58
59#endif
60
61/*
62 * There maybe one, two or three interrupt control units, each has 64
63 * interrupts. If there is no second or third unit then MCFINTC1_* or
64 * MCFINTC2_* defines will be 0 (and code for them optimized away).
65 */
66
67static void intc_irq_mask(struct irq_data *d)
68{
69 unsigned int irq = d->irq - MCFINT_VECBASE;
70
71 if (MCFINTC2_SIMR && (irq > 128))
72 __raw_writeb(irq - 128, MCFINTC2_SIMR);
73 else if (MCFINTC1_SIMR && (irq > 64))
74 __raw_writeb(irq - 64, MCFINTC1_SIMR);
75 else
76 __raw_writeb(irq, MCFINTC0_SIMR);
77}
78
79static void intc_irq_unmask(struct irq_data *d)
80{
81 unsigned int irq = d->irq - MCFINT_VECBASE;
82
83 if (MCFINTC2_CIMR && (irq > 128))
84 __raw_writeb(irq - 128, MCFINTC2_CIMR);
85 else if (MCFINTC1_CIMR && (irq > 64))
86 __raw_writeb(irq - 64, MCFINTC1_CIMR);
87 else
88 __raw_writeb(irq, MCFINTC0_CIMR);
89}
90
91static void intc_irq_ack(struct irq_data *d)
92{
93 unsigned int ebit = irq2ebit(d->irq);
94
95 __raw_writeb(0x1 << ebit, MCFEPORT_EPFR);
96}
97
98static unsigned int intc_irq_startup(struct irq_data *d)
99{
100 unsigned int irq = d->irq;
101
102 if ((irq >= EINT1) && (irq <= EINT7)) {
103 unsigned int ebit = irq2ebit(irq);
104 u8 v;
105
106#if defined(MCFEPORT_EPDDR)
107 /* Set EPORT line as input */
108 v = __raw_readb(MCFEPORT_EPDDR);
109 __raw_writeb(v & ~(0x1 << ebit), MCFEPORT_EPDDR);
110#endif
111
112 /* Set EPORT line as interrupt source */
113 v = __raw_readb(MCFEPORT_EPIER);
114 __raw_writeb(v | (0x1 << ebit), MCFEPORT_EPIER);
115 }
116
117 irq -= MCFINT_VECBASE;
118 if (MCFINTC2_ICR0 && (irq > 128))
119 __raw_writeb(5, MCFINTC2_ICR0 + irq - 128);
120 else if (MCFINTC1_ICR0 && (irq > 64))
121 __raw_writeb(5, MCFINTC1_ICR0 + irq - 64);
122 else
123 __raw_writeb(5, MCFINTC0_ICR0 + irq);
124
125 intc_irq_unmask(d);
126 return 0;
127}
128
129static int intc_irq_set_type(struct irq_data *d, unsigned int type)
130{
131 unsigned int ebit, irq = d->irq;
132 u16 pa, tb;
133
134 switch (type) {
135 case IRQ_TYPE_EDGE_RISING:
136 tb = 0x1;
137 break;
138 case IRQ_TYPE_EDGE_FALLING:
139 tb = 0x2;
140 break;
141 case IRQ_TYPE_EDGE_BOTH:
142 tb = 0x3;
143 break;
144 default:
145 /* Level triggered */
146 tb = 0;
147 break;
148 }
149
150 if (tb)
151 irq_set_handler(irq, handle_edge_irq);
152
153 ebit = irq2ebit(irq) * 2;
154 pa = __raw_readw(MCFEPORT_EPPAR);
155 pa = (pa & ~(0x3 << ebit)) | (tb << ebit);
156 __raw_writew(pa, MCFEPORT_EPPAR);
157
158 return 0;
159}
160
161static struct irq_chip intc_irq_chip = {
162 .name = "CF-INTC",
163 .irq_startup = intc_irq_startup,
164 .irq_mask = intc_irq_mask,
165 .irq_unmask = intc_irq_unmask,
166};
167
168static struct irq_chip intc_irq_chip_edge_port = {
169 .name = "CF-INTC-EP",
170 .irq_startup = intc_irq_startup,
171 .irq_mask = intc_irq_mask,
172 .irq_unmask = intc_irq_unmask,
173 .irq_ack = intc_irq_ack,
174 .irq_set_type = intc_irq_set_type,
175};
176
177void __init init_IRQ(void)
178{
179 int irq, eirq;
180
181 /* Mask all interrupt sources */
182 __raw_writeb(0xff, MCFINTC0_SIMR);
183 if (MCFINTC1_SIMR)
184 __raw_writeb(0xff, MCFINTC1_SIMR);
185 if (MCFINTC2_SIMR)
186 __raw_writeb(0xff, MCFINTC2_SIMR);
187
188 eirq = MCFINT_VECBASE + 64 + (MCFINTC1_ICR0 ? 64 : 0) +
189 (MCFINTC2_ICR0 ? 64 : 0);
190 for (irq = MCFINT_VECBASE; (irq < eirq); irq++) {
191 if ((irq >= EINT1) && (irq <= EINT7))
192 irq_set_chip(irq, &intc_irq_chip_edge_port);
193 else
194 irq_set_chip(irq, &intc_irq_chip);
195 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
196 irq_set_handler(irq, handle_level_irq);
197 }
198}
199
diff --git a/arch/m68k/coldfire/intc.c b/arch/m68k/coldfire/intc.c
new file mode 100644
index 000000000000..cce257420388
--- /dev/null
+++ b/arch/m68k/coldfire/intc.c
@@ -0,0 +1,150 @@
1/*
2 * intc.c -- support for the old ColdFire interrupt controller
3 *
4 * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/types.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/io.h>
17#include <asm/traps.h>
18#include <asm/coldfire.h>
19#include <asm/mcfsim.h>
20
21/*
22 * The mapping of irq number to a mask register bit is not one-to-one.
23 * The irq numbers are either based on "level" of interrupt or fixed
24 * for an autovector-able interrupt. So we keep a local data structure
25 * that maps from irq to mask register. Not all interrupts will have
26 * an IMR bit.
27 */
28unsigned char mcf_irq2imr[NR_IRQS];
29
30/*
31 * Define the miniumun and maximum external interrupt numbers.
32 * This is also used as the "level" interrupt numbers.
33 */
34#define EIRQ1 25
35#define EIRQ7 31
36
37/*
38 * In the early version 2 core ColdFire parts the IMR register was 16 bits
39 * in size. Version 3 (and later version 2) core parts have a 32 bit
40 * sized IMR register. Provide some size independent methods to access the
41 * IMR register.
42 */
43#ifdef MCFSIM_IMR_IS_16BITS
44
45void mcf_setimr(int index)
46{
47 u16 imr;
48 imr = __raw_readw(MCFSIM_IMR);
49 __raw_writew(imr | (0x1 << index), MCFSIM_IMR);
50}
51
52void mcf_clrimr(int index)
53{
54 u16 imr;
55 imr = __raw_readw(MCFSIM_IMR);
56 __raw_writew(imr & ~(0x1 << index), MCFSIM_IMR);
57}
58
59void mcf_maskimr(unsigned int mask)
60{
61 u16 imr;
62 imr = __raw_readw(MCFSIM_IMR);
63 imr |= mask;
64 __raw_writew(imr, MCFSIM_IMR);
65}
66
67#else
68
69void mcf_setimr(int index)
70{
71 u32 imr;
72 imr = __raw_readl(MCFSIM_IMR);
73 __raw_writel(imr | (0x1 << index), MCFSIM_IMR);
74}
75
76void mcf_clrimr(int index)
77{
78 u32 imr;
79 imr = __raw_readl(MCFSIM_IMR);
80 __raw_writel(imr & ~(0x1 << index), MCFSIM_IMR);
81}
82
83void mcf_maskimr(unsigned int mask)
84{
85 u32 imr;
86 imr = __raw_readl(MCFSIM_IMR);
87 imr |= mask;
88 __raw_writel(imr, MCFSIM_IMR);
89}
90
91#endif
92
93/*
94 * Interrupts can be "vectored" on the ColdFire cores that support this old
95 * interrupt controller. That is, the device raising the interrupt can also
96 * supply the vector number to interrupt through. The AVR register of the
97 * interrupt controller enables or disables this for each external interrupt,
98 * so provide generic support for this. Setting this up is out-of-band for
99 * the interrupt system API's, and needs to be done by the driver that
100 * supports this device. Very few devices actually use this.
101 */
102void mcf_autovector(int irq)
103{
104#ifdef MCFSIM_AVR
105 if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
106 u8 avec;
107 avec = __raw_readb(MCFSIM_AVR);
108 avec |= (0x1 << (irq - EIRQ1 + 1));
109 __raw_writeb(avec, MCFSIM_AVR);
110 }
111#endif
112}
113
114static void intc_irq_mask(struct irq_data *d)
115{
116 if (mcf_irq2imr[d->irq])
117 mcf_setimr(mcf_irq2imr[d->irq]);
118}
119
120static void intc_irq_unmask(struct irq_data *d)
121{
122 if (mcf_irq2imr[d->irq])
123 mcf_clrimr(mcf_irq2imr[d->irq]);
124}
125
126static int intc_irq_set_type(struct irq_data *d, unsigned int type)
127{
128 return 0;
129}
130
131static struct irq_chip intc_irq_chip = {
132 .name = "CF-INTC",
133 .irq_mask = intc_irq_mask,
134 .irq_unmask = intc_irq_unmask,
135 .irq_set_type = intc_irq_set_type,
136};
137
138void __init init_IRQ(void)
139{
140 int irq;
141
142 mcf_maskimr(0xffffffff);
143
144 for (irq = 0; (irq < NR_IRQS); irq++) {
145 irq_set_chip(irq, &intc_irq_chip);
146 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
147 irq_set_handler(irq, handle_level_irq);
148 }
149}
150
diff --git a/arch/m68k/coldfire/m5206.c b/arch/m68k/coldfire/m5206.c
new file mode 100644
index 000000000000..0e55f449a88c
--- /dev/null
+++ b/arch/m68k/coldfire/m5206.c
@@ -0,0 +1,58 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/5206/config.c
5 *
6 * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
7 * Copyright (C) 2000-2001, Lineo Inc. (www.lineo.com)
8 */
9
10/***************************************************************************/
11
12#include <linux/kernel.h>
13#include <linux/param.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <asm/machdep.h>
17#include <asm/coldfire.h>
18#include <asm/mcfsim.h>
19#include <asm/mcfclk.h>
20
21/***************************************************************************/
22
23DEFINE_CLK(pll, "pll.0", MCF_CLK);
24DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
25DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
26DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
27DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
28DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
29
30struct clk *mcf_clks[] = {
31 &clk_pll,
32 &clk_sys,
33 &clk_mcftmr0,
34 &clk_mcftmr1,
35 &clk_mcfuart0,
36 &clk_mcfuart1,
37 NULL
38};
39
40/***************************************************************************/
41
42void __init config_BSP(char *commandp, int size)
43{
44#if defined(CONFIG_NETtel)
45 /* Copy command line from FLASH to local buffer... */
46 memcpy(commandp, (char *) 0xf0004000, size);
47 commandp[size-1] = 0;
48#endif /* CONFIG_NETtel */
49
50 mach_sched_init = hw_timer_init;
51
52 /* Only support the external interrupts on their primary level */
53 mcf_mapirq2imr(25, MCFINTC_EINT1);
54 mcf_mapirq2imr(28, MCFINTC_EINT4);
55 mcf_mapirq2imr(31, MCFINTC_EINT7);
56}
57
58/***************************************************************************/
diff --git a/arch/m68k/coldfire/m520x.c b/arch/m68k/coldfire/m520x.c
new file mode 100644
index 000000000000..4040a3c93733
--- /dev/null
+++ b/arch/m68k/coldfire/m520x.c
@@ -0,0 +1,180 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/520x/config.c
5 *
6 * Copyright (C) 2005, Freescale (www.freescale.com)
7 * Copyright (C) 2005, Intec Automation (mike@steroidmicros.com)
8 * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
9 * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
10 */
11
12/***************************************************************************/
13
14#include <linux/kernel.h>
15#include <linux/param.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <asm/machdep.h>
19#include <asm/coldfire.h>
20#include <asm/mcfsim.h>
21#include <asm/mcfuart.h>
22#include <asm/mcfclk.h>
23
24/***************************************************************************/
25
26DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
27DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
28DEFINE_CLK(0, "edma", 17, MCF_CLK);
29DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
30DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
31DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
32DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
33DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
34DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
35DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
36DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
37DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
38DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
39DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
40
41DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
42DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
43DEFINE_CLK(0, "mcfeport.0", 34, MCF_CLK);
44DEFINE_CLK(0, "mcfwdt.0", 35, MCF_CLK);
45DEFINE_CLK(0, "pll.0", 36, MCF_CLK);
46DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
47DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
48DEFINE_CLK(0, "sdram.0", 42, MCF_CLK);
49
50struct clk *mcf_clks[] = {
51 &__clk_0_2, /* flexbus */
52 &__clk_0_12, /* fec.0 */
53 &__clk_0_17, /* edma */
54 &__clk_0_18, /* intc.0 */
55 &__clk_0_21, /* iack.0 */
56 &__clk_0_22, /* mcfi2c.0 */
57 &__clk_0_23, /* mcfqspi.0 */
58 &__clk_0_24, /* mcfuart.0 */
59 &__clk_0_25, /* mcfuart.1 */
60 &__clk_0_26, /* mcfuart.2 */
61 &__clk_0_28, /* mcftmr.0 */
62 &__clk_0_29, /* mcftmr.1 */
63 &__clk_0_30, /* mcftmr.2 */
64 &__clk_0_31, /* mcftmr.3 */
65
66 &__clk_0_32, /* mcfpit.0 */
67 &__clk_0_33, /* mcfpit.1 */
68 &__clk_0_34, /* mcfeport.0 */
69 &__clk_0_35, /* mcfwdt.0 */
70 &__clk_0_36, /* pll.0 */
71 &__clk_0_40, /* sys.0 */
72 &__clk_0_41, /* gpio.0 */
73 &__clk_0_42, /* sdram.0 */
74NULL,
75};
76
77static struct clk * const enable_clks[] __initconst = {
78 &__clk_0_2, /* flexbus */
79 &__clk_0_18, /* intc.0 */
80 &__clk_0_21, /* iack.0 */
81 &__clk_0_24, /* mcfuart.0 */
82 &__clk_0_25, /* mcfuart.1 */
83 &__clk_0_26, /* mcfuart.2 */
84
85 &__clk_0_32, /* mcfpit.0 */
86 &__clk_0_33, /* mcfpit.1 */
87 &__clk_0_34, /* mcfeport.0 */
88 &__clk_0_36, /* pll.0 */
89 &__clk_0_40, /* sys.0 */
90 &__clk_0_41, /* gpio.0 */
91 &__clk_0_42, /* sdram.0 */
92};
93
94static struct clk * const disable_clks[] __initconst = {
95 &__clk_0_12, /* fec.0 */
96 &__clk_0_17, /* edma */
97 &__clk_0_22, /* mcfi2c.0 */
98 &__clk_0_23, /* mcfqspi.0 */
99 &__clk_0_28, /* mcftmr.0 */
100 &__clk_0_29, /* mcftmr.1 */
101 &__clk_0_30, /* mcftmr.2 */
102 &__clk_0_31, /* mcftmr.3 */
103 &__clk_0_35, /* mcfwdt.0 */
104};
105
106
107static void __init m520x_clk_init(void)
108{
109 unsigned i;
110
111 /* make sure these clocks are enabled */
112 for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
113 __clk_init_enabled(enable_clks[i]);
114 /* make sure these clocks are disabled */
115 for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
116 __clk_init_disabled(disable_clks[i]);
117}
118
119/***************************************************************************/
120
121static void __init m520x_qspi_init(void)
122{
123#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
124 u16 par;
125 /* setup Port QS for QSPI with gpio CS control */
126 writeb(0x3f, MCF_GPIO_PAR_QSPI);
127 /* make U1CTS and U2RTS gpio for cs_control */
128 par = readw(MCF_GPIO_PAR_UART);
129 par &= 0x00ff;
130 writew(par, MCF_GPIO_PAR_UART);
131#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
132}
133
134/***************************************************************************/
135
136static void __init m520x_uarts_init(void)
137{
138 u16 par;
139 u8 par2;
140
141 /* UART0 and UART1 GPIO pin setup */
142 par = readw(MCF_GPIO_PAR_UART);
143 par |= MCF_GPIO_PAR_UART_PAR_UTXD0 | MCF_GPIO_PAR_UART_PAR_URXD0;
144 par |= MCF_GPIO_PAR_UART_PAR_UTXD1 | MCF_GPIO_PAR_UART_PAR_URXD1;
145 writew(par, MCF_GPIO_PAR_UART);
146
147 /* UART1 GPIO pin setup */
148 par2 = readb(MCF_GPIO_PAR_FECI2C);
149 par2 &= ~0x0F;
150 par2 |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 |
151 MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
152 writeb(par2, MCF_GPIO_PAR_FECI2C);
153}
154
155/***************************************************************************/
156
157static void __init m520x_fec_init(void)
158{
159 u8 v;
160
161 /* Set multi-function pins to ethernet mode */
162 v = readb(MCF_GPIO_PAR_FEC);
163 writeb(v | 0xf0, MCF_GPIO_PAR_FEC);
164
165 v = readb(MCF_GPIO_PAR_FECI2C);
166 writeb(v | 0x0f, MCF_GPIO_PAR_FECI2C);
167}
168
169/***************************************************************************/
170
171void __init config_BSP(char *commandp, int size)
172{
173 mach_sched_init = hw_timer_init;
174 m520x_clk_init();
175 m520x_uarts_init();
176 m520x_fec_init();
177 m520x_qspi_init();
178}
179
180/***************************************************************************/
diff --git a/arch/m68k/coldfire/m523x.c b/arch/m68k/coldfire/m523x.c
new file mode 100644
index 000000000000..6b7135e6d5b4
--- /dev/null
+++ b/arch/m68k/coldfire/m523x.c
@@ -0,0 +1,86 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/523x/config.c
5 *
6 * Sub-architcture dependent initialization code for the Freescale
7 * 523x CPUs.
8 *
9 * Copyright (C) 1999-2005, Greg Ungerer (gerg@snapgear.com)
10 * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
11 */
12
13/***************************************************************************/
14
15#include <linux/kernel.h>
16#include <linux/param.h>
17#include <linux/init.h>
18#include <linux/io.h>
19#include <asm/machdep.h>
20#include <asm/coldfire.h>
21#include <asm/mcfsim.h>
22#include <asm/mcfclk.h>
23
24/***************************************************************************/
25
26DEFINE_CLK(pll, "pll.0", MCF_CLK);
27DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
28DEFINE_CLK(mcfpit0, "mcfpit.0", MCF_CLK);
29DEFINE_CLK(mcfpit1, "mcfpit.1", MCF_CLK);
30DEFINE_CLK(mcfpit2, "mcfpit.2", MCF_CLK);
31DEFINE_CLK(mcfpit3, "mcfpit.3", MCF_CLK);
32DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
33DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
34DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK);
35DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
36DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK);
37
38struct clk *mcf_clks[] = {
39 &clk_pll,
40 &clk_sys,
41 &clk_mcfpit0,
42 &clk_mcfpit1,
43 &clk_mcfpit2,
44 &clk_mcfpit3,
45 &clk_mcfuart0,
46 &clk_mcfuart1,
47 &clk_mcfuart2,
48 &clk_mcfqspi0,
49 &clk_fec0,
50 NULL
51};
52
53/***************************************************************************/
54
55static void __init m523x_qspi_init(void)
56{
57#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
58 u16 par;
59
60 /* setup QSPS pins for QSPI with gpio CS control */
61 writeb(0x1f, MCFGPIO_PAR_QSPI);
62 /* and CS2 & CS3 as gpio */
63 par = readw(MCFGPIO_PAR_TIMER);
64 par &= 0x3f3f;
65 writew(par, MCFGPIO_PAR_TIMER);
66#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
67}
68
69/***************************************************************************/
70
71static void __init m523x_fec_init(void)
72{
73 /* Set multi-function pins to ethernet use */
74 writeb(readb(MCFGPIO_PAR_FECI2C) | 0xf0, MCFGPIO_PAR_FECI2C);
75}
76
77/***************************************************************************/
78
79void __init config_BSP(char *commandp, int size)
80{
81 mach_sched_init = hw_timer_init;
82 m523x_fec_init();
83 m523x_qspi_init();
84}
85
86/***************************************************************************/
diff --git a/arch/m68k/coldfire/m5249.c b/arch/m68k/coldfire/m5249.c
new file mode 100644
index 000000000000..f6253a3313b3
--- /dev/null
+++ b/arch/m68k/coldfire/m5249.c
@@ -0,0 +1,126 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/5249/config.c
5 *
6 * Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <linux/param.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <asm/machdep.h>
17#include <asm/coldfire.h>
18#include <asm/mcfsim.h>
19#include <asm/mcfclk.h>
20
21/***************************************************************************/
22
23DEFINE_CLK(pll, "pll.0", MCF_CLK);
24DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
25DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
26DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
27DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
28DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
29DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
30
31struct clk *mcf_clks[] = {
32 &clk_pll,
33 &clk_sys,
34 &clk_mcftmr0,
35 &clk_mcftmr1,
36 &clk_mcfuart0,
37 &clk_mcfuart1,
38 &clk_mcfqspi0,
39 NULL
40};
41
42/***************************************************************************/
43
44#ifdef CONFIG_M5249C3
45
46static struct resource m5249_smc91x_resources[] = {
47 {
48 .start = 0xe0000300,
49 .end = 0xe0000300 + 0x100,
50 .flags = IORESOURCE_MEM,
51 },
52 {
53 .start = MCF_IRQ_GPIO6,
54 .end = MCF_IRQ_GPIO6,
55 .flags = IORESOURCE_IRQ,
56 },
57};
58
59static struct platform_device m5249_smc91x = {
60 .name = "smc91x",
61 .id = 0,
62 .num_resources = ARRAY_SIZE(m5249_smc91x_resources),
63 .resource = m5249_smc91x_resources,
64};
65
66#endif /* CONFIG_M5249C3 */
67
68static struct platform_device *m5249_devices[] __initdata = {
69#ifdef CONFIG_M5249C3
70 &m5249_smc91x,
71#endif
72};
73
74/***************************************************************************/
75
76static void __init m5249_qspi_init(void)
77{
78#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
79 /* QSPI irq setup */
80 writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
81 MCFSIM_QSPIICR);
82 mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
83#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
84}
85
86/***************************************************************************/
87
88#ifdef CONFIG_M5249C3
89
90static void __init m5249_smc91x_init(void)
91{
92 u32 gpio;
93
94 /* Set the GPIO line as interrupt source for smc91x device */
95 gpio = readl(MCFSIM2_GPIOINTENABLE);
96 writel(gpio | 0x40, MCFSIM2_GPIOINTENABLE);
97
98 gpio = readl(MCFINTC2_INTPRI5);
99 writel(gpio | 0x04000000, MCFINTC2_INTPRI5);
100}
101
102#endif /* CONFIG_M5249C3 */
103
104/***************************************************************************/
105
106void __init config_BSP(char *commandp, int size)
107{
108 mach_sched_init = hw_timer_init;
109
110#ifdef CONFIG_M5249C3
111 m5249_smc91x_init();
112#endif
113 m5249_qspi_init();
114}
115
116/***************************************************************************/
117
118static int __init init_BSP(void)
119{
120 platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices));
121 return 0;
122}
123
124arch_initcall(init_BSP);
125
126/***************************************************************************/
diff --git a/arch/m68k/coldfire/m525x.c b/arch/m68k/coldfire/m525x.c
new file mode 100644
index 000000000000..1adba3909035
--- /dev/null
+++ b/arch/m68k/coldfire/m525x.c
@@ -0,0 +1,88 @@
1/***************************************************************************/
2
3/*
4 * 525x.c
5 *
6 * Copyright (C) 2012, Steven King <sfking@fdwdc.com>
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <linux/param.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <asm/machdep.h>
17#include <asm/coldfire.h>
18#include <asm/mcfsim.h>
19#include <asm/mcfclk.h>
20
21/***************************************************************************/
22
23DEFINE_CLK(pll, "pll.0", MCF_CLK);
24DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
25DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
26DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
27DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
28DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
29DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
30
31struct clk *mcf_clks[] = {
32 &clk_pll,
33 &clk_sys,
34 &clk_mcftmr0,
35 &clk_mcftmr1,
36 &clk_mcfuart0,
37 &clk_mcfuart1,
38 &clk_mcfqspi0,
39 NULL
40};
41
42/***************************************************************************/
43
44static void __init m525x_qspi_init(void)
45{
46#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
47 /* set the GPIO function for the qspi cs gpios */
48 /* FIXME: replace with pinmux/pinctl support */
49 u32 f = readl(MCFSIM2_GPIOFUNC);
50 f |= (1 << MCFQSPI_CS2) | (1 << MCFQSPI_CS1) | (1 << MCFQSPI_CS0);
51 writel(f, MCFSIM2_GPIOFUNC);
52
53 /* QSPI irq setup */
54 writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
55 MCFSIM_QSPIICR);
56 mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
57#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
58}
59
60static void __init m525x_i2c_init(void)
61{
62#if IS_ENABLED(CONFIG_I2C_COLDFIRE)
63 u32 r;
64
65 /* first I2C controller uses regular irq setup */
66 writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI0,
67 MCFSIM_I2CICR);
68 mcf_mapirq2imr(MCF_IRQ_I2C0, MCFINTC_I2C);
69
70 /* second I2C controller is completely different */
71 r = readl(MCFINTC2_INTPRI_REG(MCF_IRQ_I2C1));
72 r &= ~MCFINTC2_INTPRI_BITS(0xf, MCF_IRQ_I2C1);
73 r |= MCFINTC2_INTPRI_BITS(0x5, MCF_IRQ_I2C1);
74 writel(r, MCFINTC2_INTPRI_REG(MCF_IRQ_I2C1));
75#endif /* IS_ENABLED(CONFIG_I2C_COLDFIRE) */
76}
77
78/***************************************************************************/
79
80void __init config_BSP(char *commandp, int size)
81{
82 mach_sched_init = hw_timer_init;
83
84 m525x_qspi_init();
85 m525x_i2c_init();
86}
87
88/***************************************************************************/
diff --git a/arch/m68k/coldfire/m5272.c b/arch/m68k/coldfire/m5272.c
new file mode 100644
index 000000000000..8a4d3cc322c6
--- /dev/null
+++ b/arch/m68k/coldfire/m5272.c
@@ -0,0 +1,135 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/5272/config.c
5 *
6 * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
7 * Copyright (C) 2001-2002, SnapGear Inc. (www.snapgear.com)
8 */
9
10/***************************************************************************/
11
12#include <linux/kernel.h>
13#include <linux/param.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/phy.h>
17#include <linux/phy_fixed.h>
18#include <asm/machdep.h>
19#include <asm/coldfire.h>
20#include <asm/mcfsim.h>
21#include <asm/mcfuart.h>
22#include <asm/mcfclk.h>
23
24/***************************************************************************/
25
26/*
27 * Some platforms need software versions of the GPIO data registers.
28 */
29unsigned short ppdata;
30unsigned char ledbank = 0xff;
31
32/***************************************************************************/
33
34DEFINE_CLK(pll, "pll.0", MCF_CLK);
35DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
36DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
37DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
38DEFINE_CLK(mcftmr2, "mcftmr.2", MCF_BUSCLK);
39DEFINE_CLK(mcftmr3, "mcftmr.3", MCF_BUSCLK);
40DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
41DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
42DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
43DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK);
44
45struct clk *mcf_clks[] = {
46 &clk_pll,
47 &clk_sys,
48 &clk_mcftmr0,
49 &clk_mcftmr1,
50 &clk_mcftmr2,
51 &clk_mcftmr3,
52 &clk_mcfuart0,
53 &clk_mcfuart1,
54 &clk_mcfqspi0,
55 &clk_fec0,
56 NULL
57};
58
59/***************************************************************************/
60
61static void __init m5272_uarts_init(void)
62{
63 u32 v;
64
65 /* Enable the output lines for the serial ports */
66 v = readl(MCFSIM_PBCNT);
67 v = (v & ~0x000000ff) | 0x00000055;
68 writel(v, MCFSIM_PBCNT);
69
70 v = readl(MCFSIM_PDCNT);
71 v = (v & ~0x000003fc) | 0x000002a8;
72 writel(v, MCFSIM_PDCNT);
73}
74
75/***************************************************************************/
76
77static void m5272_cpu_reset(void)
78{
79 local_irq_disable();
80 /* Set watchdog to reset, and enabled */
81 __raw_writew(0, MCFSIM_WIRR);
82 __raw_writew(1, MCFSIM_WRRR);
83 __raw_writew(0, MCFSIM_WCR);
84 for (;;)
85 /* wait for watchdog to timeout */;
86}
87
88/***************************************************************************/
89
90void __init config_BSP(char *commandp, int size)
91{
92#if defined (CONFIG_MOD5272)
93 /* Set base of device vectors to be 64 */
94 writeb(0x40, MCFSIM_PIVR);
95#endif
96
97#if defined(CONFIG_NETtel) || defined(CONFIG_SCALES)
98 /* Copy command line from FLASH to local buffer... */
99 memcpy(commandp, (char *) 0xf0004000, size);
100 commandp[size-1] = 0;
101#elif defined(CONFIG_CANCam)
102 /* Copy command line from FLASH to local buffer... */
103 memcpy(commandp, (char *) 0xf0010000, size);
104 commandp[size-1] = 0;
105#endif
106
107 mach_reset = m5272_cpu_reset;
108 mach_sched_init = hw_timer_init;
109}
110
111/***************************************************************************/
112
113/*
114 * Some 5272 based boards have the FEC ethernet diectly connected to
115 * an ethernet switch. In this case we need to use the fixed phy type,
116 * and we need to declare it early in boot.
117 */
118static struct fixed_phy_status nettel_fixed_phy_status __initdata = {
119 .link = 1,
120 .speed = 100,
121 .duplex = 0,
122};
123
124/***************************************************************************/
125
126static int __init init_BSP(void)
127{
128 m5272_uarts_init();
129 fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status);
130 return 0;
131}
132
133arch_initcall(init_BSP);
134
135/***************************************************************************/
diff --git a/arch/m68k/coldfire/m527x.c b/arch/m68k/coldfire/m527x.c
new file mode 100644
index 000000000000..62d81ef016f1
--- /dev/null
+++ b/arch/m68k/coldfire/m527x.c
@@ -0,0 +1,126 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/527x/config.c
5 *
6 * Sub-architcture dependent initialization code for the Freescale
7 * 5270/5271 CPUs.
8 *
9 * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
10 * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
11 */
12
13/***************************************************************************/
14
15#include <linux/kernel.h>
16#include <linux/param.h>
17#include <linux/init.h>
18#include <linux/io.h>
19#include <asm/machdep.h>
20#include <asm/coldfire.h>
21#include <asm/mcfsim.h>
22#include <asm/mcfuart.h>
23#include <asm/mcfclk.h>
24
25/***************************************************************************/
26
27DEFINE_CLK(pll, "pll.0", MCF_CLK);
28DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
29DEFINE_CLK(mcfpit0, "mcfpit.0", MCF_CLK);
30DEFINE_CLK(mcfpit1, "mcfpit.1", MCF_CLK);
31DEFINE_CLK(mcfpit2, "mcfpit.2", MCF_CLK);
32DEFINE_CLK(mcfpit3, "mcfpit.3", MCF_CLK);
33DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
34DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
35DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK);
36DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
37DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK);
38DEFINE_CLK(fec1, "fec.1", MCF_BUSCLK);
39
40struct clk *mcf_clks[] = {
41 &clk_pll,
42 &clk_sys,
43 &clk_mcfpit0,
44 &clk_mcfpit1,
45 &clk_mcfpit2,
46 &clk_mcfpit3,
47 &clk_mcfuart0,
48 &clk_mcfuart1,
49 &clk_mcfuart2,
50 &clk_mcfqspi0,
51 &clk_fec0,
52 &clk_fec1,
53 NULL
54};
55
56/***************************************************************************/
57
58static void __init m527x_qspi_init(void)
59{
60#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
61#if defined(CONFIG_M5271)
62 u16 par;
63
64 /* setup QSPS pins for QSPI with gpio CS control */
65 writeb(0x1f, MCFGPIO_PAR_QSPI);
66 /* and CS2 & CS3 as gpio */
67 par = readw(MCFGPIO_PAR_TIMER);
68 par &= 0x3f3f;
69 writew(par, MCFGPIO_PAR_TIMER);
70#elif defined(CONFIG_M5275)
71 /* setup QSPS pins for QSPI with gpio CS control */
72 writew(0x003e, MCFGPIO_PAR_QSPI);
73#endif
74#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
75}
76
77/***************************************************************************/
78
79static void __init m527x_uarts_init(void)
80{
81 u16 sepmask;
82
83 /*
84 * External Pin Mask Setting & Enable External Pin for Interface
85 */
86 sepmask = readw(MCFGPIO_PAR_UART);
87 sepmask |= UART0_ENABLE_MASK | UART1_ENABLE_MASK | UART2_ENABLE_MASK;
88 writew(sepmask, MCFGPIO_PAR_UART);
89}
90
91/***************************************************************************/
92
93static void __init m527x_fec_init(void)
94{
95 u16 par;
96 u8 v;
97
98 /* Set multi-function pins to ethernet mode for fec0 */
99#if defined(CONFIG_M5271)
100 v = readb(MCFGPIO_PAR_FECI2C);
101 writeb(v | 0xf0, MCFGPIO_PAR_FECI2C);
102#else
103 par = readw(MCFGPIO_PAR_FECI2C);
104 writew(par | 0xf00, MCFGPIO_PAR_FECI2C);
105 v = readb(MCFGPIO_PAR_FEC0HL);
106 writeb(v | 0xc0, MCFGPIO_PAR_FEC0HL);
107
108 /* Set multi-function pins to ethernet mode for fec1 */
109 par = readw(MCFGPIO_PAR_FECI2C);
110 writew(par | 0xa0, MCFGPIO_PAR_FECI2C);
111 v = readb(MCFGPIO_PAR_FEC1HL);
112 writeb(v | 0xc0, MCFGPIO_PAR_FEC1HL);
113#endif
114}
115
116/***************************************************************************/
117
118void __init config_BSP(char *commandp, int size)
119{
120 mach_sched_init = hw_timer_init;
121 m527x_uarts_init();
122 m527x_fec_init();
123 m527x_qspi_init();
124}
125
126/***************************************************************************/
diff --git a/arch/m68k/coldfire/m528x.c b/arch/m68k/coldfire/m528x.c
new file mode 100644
index 000000000000..21cd161d36f1
--- /dev/null
+++ b/arch/m68k/coldfire/m528x.c
@@ -0,0 +1,132 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/528x/config.c
5 *
6 * Sub-architcture dependent initialization code for the Freescale
7 * 5280, 5281 and 5282 CPUs.
8 *
9 * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
10 * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
11 */
12
13/***************************************************************************/
14
15#include <linux/kernel.h>
16#include <linux/param.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/io.h>
20#include <asm/machdep.h>
21#include <asm/coldfire.h>
22#include <asm/mcfsim.h>
23#include <asm/mcfuart.h>
24#include <asm/mcfclk.h>
25
26/***************************************************************************/
27
28DEFINE_CLK(pll, "pll.0", MCF_CLK);
29DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
30DEFINE_CLK(mcfpit0, "mcfpit.0", MCF_CLK);
31DEFINE_CLK(mcfpit1, "mcfpit.1", MCF_CLK);
32DEFINE_CLK(mcfpit2, "mcfpit.2", MCF_CLK);
33DEFINE_CLK(mcfpit3, "mcfpit.3", MCF_CLK);
34DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
35DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
36DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK);
37DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
38DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK);
39
40struct clk *mcf_clks[] = {
41 &clk_pll,
42 &clk_sys,
43 &clk_mcfpit0,
44 &clk_mcfpit1,
45 &clk_mcfpit2,
46 &clk_mcfpit3,
47 &clk_mcfuart0,
48 &clk_mcfuart1,
49 &clk_mcfuart2,
50 &clk_mcfqspi0,
51 &clk_fec0,
52 NULL
53};
54
55/***************************************************************************/
56
57static void __init m528x_qspi_init(void)
58{
59#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
60 /* setup Port QS for QSPI with gpio CS control */
61 __raw_writeb(0x07, MCFGPIO_PQSPAR);
62#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
63}
64
65/***************************************************************************/
66
67static void __init m528x_uarts_init(void)
68{
69 u8 port;
70
71 /* make sure PUAPAR is set for UART0 and UART1 */
72 port = readb(MCFGPIO_PUAPAR);
73 port |= 0x03 | (0x03 << 2);
74 writeb(port, MCFGPIO_PUAPAR);
75}
76
77/***************************************************************************/
78
79static void __init m528x_fec_init(void)
80{
81 u16 v16;
82
83 /* Set multi-function pins to ethernet mode for fec0 */
84 v16 = readw(MCFGPIO_PASPAR);
85 writew(v16 | 0xf00, MCFGPIO_PASPAR);
86 writeb(0xc0, MCFGPIO_PEHLPAR);
87}
88
89/***************************************************************************/
90
91#ifdef CONFIG_WILDFIRE
92void wildfire_halt(void)
93{
94 writeb(0, 0x30000007);
95 writeb(0x2, 0x30000007);
96}
97#endif
98
99#ifdef CONFIG_WILDFIREMOD
100void wildfiremod_halt(void)
101{
102 printk(KERN_INFO "WildFireMod hibernating...\n");
103
104 /* Set portE.5 to Digital IO */
105 MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2));
106
107 /* Make portE.5 an output */
108 MCF5282_GPIO_DDRE |= (1 << 5);
109
110 /* Now toggle portE.5 from low to high */
111 MCF5282_GPIO_PORTE &= ~(1 << 5);
112 MCF5282_GPIO_PORTE |= (1 << 5);
113
114 printk(KERN_EMERG "Failed to hibernate. Halting!\n");
115}
116#endif
117
118void __init config_BSP(char *commandp, int size)
119{
120#ifdef CONFIG_WILDFIRE
121 mach_halt = wildfire_halt;
122#endif
123#ifdef CONFIG_WILDFIREMOD
124 mach_halt = wildfiremod_halt;
125#endif
126 mach_sched_init = hw_timer_init;
127 m528x_uarts_init();
128 m528x_fec_init();
129 m528x_qspi_init();
130}
131
132/***************************************************************************/
diff --git a/arch/m68k/coldfire/m5307.c b/arch/m68k/coldfire/m5307.c
new file mode 100644
index 000000000000..887435361386
--- /dev/null
+++ b/arch/m68k/coldfire/m5307.c
@@ -0,0 +1,78 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/5307/config.c
5 *
6 * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
7 * Copyright (C) 2000, Lineo (www.lineo.com)
8 */
9
10/***************************************************************************/
11
12#include <linux/kernel.h>
13#include <linux/param.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <asm/machdep.h>
17#include <asm/coldfire.h>
18#include <asm/mcfsim.h>
19#include <asm/mcfwdebug.h>
20#include <asm/mcfclk.h>
21
22/***************************************************************************/
23
24/*
25 * Some platforms need software versions of the GPIO data registers.
26 */
27unsigned short ppdata;
28unsigned char ledbank = 0xff;
29
30/***************************************************************************/
31
32DEFINE_CLK(pll, "pll.0", MCF_CLK);
33DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
34DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
35DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
36DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
37DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
38
39struct clk *mcf_clks[] = {
40 &clk_pll,
41 &clk_sys,
42 &clk_mcftmr0,
43 &clk_mcftmr1,
44 &clk_mcfuart0,
45 &clk_mcfuart1,
46 NULL
47};
48
49/***************************************************************************/
50
51void __init config_BSP(char *commandp, int size)
52{
53#if defined(CONFIG_NETtel) || \
54 defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
55 /* Copy command line from FLASH to local buffer... */
56 memcpy(commandp, (char *) 0xf0004000, size);
57 commandp[size-1] = 0;
58#endif
59
60 mach_sched_init = hw_timer_init;
61
62 /* Only support the external interrupts on their primary level */
63 mcf_mapirq2imr(25, MCFINTC_EINT1);
64 mcf_mapirq2imr(27, MCFINTC_EINT3);
65 mcf_mapirq2imr(29, MCFINTC_EINT5);
66 mcf_mapirq2imr(31, MCFINTC_EINT7);
67
68#ifdef CONFIG_BDM_DISABLE
69 /*
70 * Disable the BDM clocking. This also turns off most of the rest of
71 * the BDM device. This is good for EMC reasons. This option is not
72 * incompatible with the memory protection option.
73 */
74 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
75#endif
76}
77
78/***************************************************************************/
diff --git a/arch/m68k/coldfire/m53xx.c b/arch/m68k/coldfire/m53xx.c
new file mode 100644
index 000000000000..80879a7fe3d5
--- /dev/null
+++ b/arch/m68k/coldfire/m53xx.c
@@ -0,0 +1,588 @@
1/***************************************************************************/
2
3/*
4 * m53xx.c -- platform support for ColdFire 53xx based boards
5 *
6 * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
7 * Copyright (C) 2000, Lineo (www.lineo.com)
8 * Yaroslav Vinogradov yaroslav.vinogradov@freescale.com
9 * Copyright Freescale Semiconductor, Inc 2006
10 * Copyright (c) 2006, emlix, Sebastian Hess <shess@hessware.de>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 */
17
18/***************************************************************************/
19
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <asm/machdep.h>
25#include <asm/coldfire.h>
26#include <asm/mcfsim.h>
27#include <asm/mcfuart.h>
28#include <asm/mcfdma.h>
29#include <asm/mcfwdebug.h>
30#include <asm/mcfclk.h>
31
32/***************************************************************************/
33
34DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
35DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
36DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
37DEFINE_CLK(0, "edma", 17, MCF_CLK);
38DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
39DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
40DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
41DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
42DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
43DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
44DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
45DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
46DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
47DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
48DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
49DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
50
51DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
52DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
53DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
54DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
55DEFINE_CLK(0, "mcfpwm.0", 36, MCF_CLK);
56DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
57DEFINE_CLK(0, "mcfwdt.0", 38, MCF_CLK);
58DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
59DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
60DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
61DEFINE_CLK(0, "mcflcd.0", 43, MCF_CLK);
62DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
63DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
64DEFINE_CLK(0, "sdram.0", 46, MCF_CLK);
65DEFINE_CLK(0, "ssi.0", 47, MCF_CLK);
66DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
67
68DEFINE_CLK(1, "mdha.0", 32, MCF_CLK);
69DEFINE_CLK(1, "skha.0", 33, MCF_CLK);
70DEFINE_CLK(1, "rng.0", 34, MCF_CLK);
71
72struct clk *mcf_clks[] = {
73 &__clk_0_2, /* flexbus */
74 &__clk_0_8, /* mcfcan.0 */
75 &__clk_0_12, /* fec.0 */
76 &__clk_0_17, /* edma */
77 &__clk_0_18, /* intc.0 */
78 &__clk_0_19, /* intc.1 */
79 &__clk_0_21, /* iack.0 */
80 &__clk_0_22, /* mcfi2c.0 */
81 &__clk_0_23, /* mcfqspi.0 */
82 &__clk_0_24, /* mcfuart.0 */
83 &__clk_0_25, /* mcfuart.1 */
84 &__clk_0_26, /* mcfuart.2 */
85 &__clk_0_28, /* mcftmr.0 */
86 &__clk_0_29, /* mcftmr.1 */
87 &__clk_0_30, /* mcftmr.2 */
88 &__clk_0_31, /* mcftmr.3 */
89
90 &__clk_0_32, /* mcfpit.0 */
91 &__clk_0_33, /* mcfpit.1 */
92 &__clk_0_34, /* mcfpit.2 */
93 &__clk_0_35, /* mcfpit.3 */
94 &__clk_0_36, /* mcfpwm.0 */
95 &__clk_0_37, /* mcfeport.0 */
96 &__clk_0_38, /* mcfwdt.0 */
97 &__clk_0_40, /* sys.0 */
98 &__clk_0_41, /* gpio.0 */
99 &__clk_0_42, /* mcfrtc.0 */
100 &__clk_0_43, /* mcflcd.0 */
101 &__clk_0_44, /* mcfusb-otg.0 */
102 &__clk_0_45, /* mcfusb-host.0 */
103 &__clk_0_46, /* sdram.0 */
104 &__clk_0_47, /* ssi.0 */
105 &__clk_0_48, /* pll.0 */
106
107 &__clk_1_32, /* mdha.0 */
108 &__clk_1_33, /* skha.0 */
109 &__clk_1_34, /* rng.0 */
110 NULL,
111};
112
113static struct clk * const enable_clks[] __initconst = {
114 &__clk_0_2, /* flexbus */
115 &__clk_0_18, /* intc.0 */
116 &__clk_0_19, /* intc.1 */
117 &__clk_0_21, /* iack.0 */
118 &__clk_0_24, /* mcfuart.0 */
119 &__clk_0_25, /* mcfuart.1 */
120 &__clk_0_26, /* mcfuart.2 */
121 &__clk_0_28, /* mcftmr.0 */
122 &__clk_0_29, /* mcftmr.1 */
123 &__clk_0_32, /* mcfpit.0 */
124 &__clk_0_33, /* mcfpit.1 */
125 &__clk_0_37, /* mcfeport.0 */
126 &__clk_0_40, /* sys.0 */
127 &__clk_0_41, /* gpio.0 */
128 &__clk_0_46, /* sdram.0 */
129 &__clk_0_48, /* pll.0 */
130};
131
132static struct clk * const disable_clks[] __initconst = {
133 &__clk_0_8, /* mcfcan.0 */
134 &__clk_0_12, /* fec.0 */
135 &__clk_0_17, /* edma */
136 &__clk_0_22, /* mcfi2c.0 */
137 &__clk_0_23, /* mcfqspi.0 */
138 &__clk_0_30, /* mcftmr.2 */
139 &__clk_0_31, /* mcftmr.3 */
140 &__clk_0_34, /* mcfpit.2 */
141 &__clk_0_35, /* mcfpit.3 */
142 &__clk_0_36, /* mcfpwm.0 */
143 &__clk_0_38, /* mcfwdt.0 */
144 &__clk_0_42, /* mcfrtc.0 */
145 &__clk_0_43, /* mcflcd.0 */
146 &__clk_0_44, /* mcfusb-otg.0 */
147 &__clk_0_45, /* mcfusb-host.0 */
148 &__clk_0_47, /* ssi.0 */
149 &__clk_1_32, /* mdha.0 */
150 &__clk_1_33, /* skha.0 */
151 &__clk_1_34, /* rng.0 */
152};
153
154
155static void __init m53xx_clk_init(void)
156{
157 unsigned i;
158
159 /* make sure these clocks are enabled */
160 for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
161 __clk_init_enabled(enable_clks[i]);
162 /* make sure these clocks are disabled */
163 for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
164 __clk_init_disabled(disable_clks[i]);
165}
166
167/***************************************************************************/
168
169static void __init m53xx_qspi_init(void)
170{
171#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
172 /* setup QSPS pins for QSPI with gpio CS control */
173 writew(0x01f0, MCFGPIO_PAR_QSPI);
174#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
175}
176
177/***************************************************************************/
178
179static void __init m53xx_uarts_init(void)
180{
181 /* UART GPIO initialization */
182 writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
183}
184
185/***************************************************************************/
186
187static void __init m53xx_fec_init(void)
188{
189 u8 v;
190
191 /* Set multi-function pins to ethernet mode for fec0 */
192 v = readb(MCFGPIO_PAR_FECI2C);
193 v |= MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
194 MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO;
195 writeb(v, MCFGPIO_PAR_FECI2C);
196
197 v = readb(MCFGPIO_PAR_FEC);
198 v = MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC;
199 writeb(v, MCFGPIO_PAR_FEC);
200}
201
202/***************************************************************************/
203
204void __init config_BSP(char *commandp, int size)
205{
206#if !defined(CONFIG_BOOTPARAM)
207 /* Copy command line from FLASH to local buffer... */
208 memcpy(commandp, (char *) 0x4000, 4);
209 if(strncmp(commandp, "kcl ", 4) == 0){
210 memcpy(commandp, (char *) 0x4004, size);
211 commandp[size-1] = 0;
212 } else {
213 memset(commandp, 0, size);
214 }
215#endif
216 mach_sched_init = hw_timer_init;
217 m53xx_clk_init();
218 m53xx_uarts_init();
219 m53xx_fec_init();
220 m53xx_qspi_init();
221
222#ifdef CONFIG_BDM_DISABLE
223 /*
224 * Disable the BDM clocking. This also turns off most of the rest of
225 * the BDM device. This is good for EMC reasons. This option is not
226 * incompatible with the memory protection option.
227 */
228 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
229#endif
230}
231
232/***************************************************************************/
233/* Board initialization */
234/***************************************************************************/
235/*
236 * PLL min/max specifications
237 */
238#define MAX_FVCO 500000 /* KHz */
239#define MAX_FSYS 80000 /* KHz */
240#define MIN_FSYS 58333 /* KHz */
241#define FREF 16000 /* KHz */
242
243
244#define MAX_MFD 135 /* Multiplier */
245#define MIN_MFD 88 /* Multiplier */
246#define BUSDIV 6 /* Divider */
247
248/*
249 * Low Power Divider specifications
250 */
251#define MIN_LPD (1 << 0) /* Divider (not encoded) */
252#define MAX_LPD (1 << 15) /* Divider (not encoded) */
253#define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */
254
255#define SYS_CLK_KHZ 80000
256#define SYSTEM_PERIOD 12.5
257/*
258 * SDRAM Timing Parameters
259 */
260#define SDRAM_BL 8 /* # of beats in a burst */
261#define SDRAM_TWR 2 /* in clocks */
262#define SDRAM_CASL 2.5 /* CASL in clocks */
263#define SDRAM_TRCD 2 /* in clocks */
264#define SDRAM_TRP 2 /* in clocks */
265#define SDRAM_TRFC 7 /* in clocks */
266#define SDRAM_TREFI 7800 /* in ns */
267
268#define EXT_SRAM_ADDRESS (0xC0000000)
269#define FLASH_ADDRESS (0x00000000)
270#define SDRAM_ADDRESS (0x40000000)
271
272#define NAND_FLASH_ADDRESS (0xD0000000)
273
274int sys_clk_khz = 0;
275int sys_clk_mhz = 0;
276
277void wtm_init(void);
278void scm_init(void);
279void gpio_init(void);
280void fbcs_init(void);
281void sdramc_init(void);
282int clock_pll (int fsys, int flags);
283int clock_limp (int);
284int clock_exit_limp (void);
285int get_sys_clock (void);
286
287asmlinkage void __init sysinit(void)
288{
289 sys_clk_khz = clock_pll(0, 0);
290 sys_clk_mhz = sys_clk_khz/1000;
291
292 wtm_init();
293 scm_init();
294 gpio_init();
295 fbcs_init();
296 sdramc_init();
297}
298
299void wtm_init(void)
300{
301 /* Disable watchdog timer */
302 writew(0, MCF_WTM_WCR);
303}
304
305#define MCF_SCM_BCR_GBW (0x00000100)
306#define MCF_SCM_BCR_GBR (0x00000200)
307
308void scm_init(void)
309{
310 /* All masters are trusted */
311 writel(0x77777777, MCF_SCM_MPR);
312
313 /* Allow supervisor/user, read/write, and trusted/untrusted
314 access to all slaves */
315 writel(0, MCF_SCM_PACRA);
316 writel(0, MCF_SCM_PACRB);
317 writel(0, MCF_SCM_PACRC);
318 writel(0, MCF_SCM_PACRD);
319 writel(0, MCF_SCM_PACRE);
320 writel(0, MCF_SCM_PACRF);
321
322 /* Enable bursts */
323 writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
324}
325
326
327void fbcs_init(void)
328{
329 writeb(0x3E, MCFGPIO_PAR_CS);
330
331 /* Latch chip select */
332 writel(0x10080000, MCF_FBCS1_CSAR);
333
334 writel(0x002A3780, MCF_FBCS1_CSCR);
335 writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
336
337 /* Initialize latch to drive signals to inactive states */
338 writew(0xffff, 0x10080000);
339
340 /* External SRAM */
341 writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR);
342 writel(MCF_FBCS_CSCR_PS_16 |
343 MCF_FBCS_CSCR_AA |
344 MCF_FBCS_CSCR_SBM |
345 MCF_FBCS_CSCR_WS(1),
346 MCF_FBCS1_CSCR);
347 writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
348
349 /* Boot Flash connected to FBCS0 */
350 writel(FLASH_ADDRESS, MCF_FBCS0_CSAR);
351 writel(MCF_FBCS_CSCR_PS_16 |
352 MCF_FBCS_CSCR_BEM |
353 MCF_FBCS_CSCR_AA |
354 MCF_FBCS_CSCR_SBM |
355 MCF_FBCS_CSCR_WS(7),
356 MCF_FBCS0_CSCR);
357 writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR);
358}
359
360void sdramc_init(void)
361{
362 /*
363 * Check to see if the SDRAM has already been initialized
364 * by a run control tool
365 */
366 if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
367 /* SDRAM chip select initialization */
368
369 /* Initialize SDRAM chip select */
370 writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
371 MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
372 MCF_SDRAMC_SDCS0);
373
374 /*
375 * Basic configuration and initialization
376 */
377 writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
378 MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) |
379 MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
380 MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
381 MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
382 MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
383 MCF_SDRAMC_SDCFG1_WTLAT(3),
384 MCF_SDRAMC_SDCFG1);
385 writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) |
386 MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) |
387 MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
388 MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1),
389 MCF_SDRAMC_SDCFG2);
390
391
392 /*
393 * Precharge and enable write to SDMR
394 */
395 writel(MCF_SDRAMC_SDCR_MODE_EN |
396 MCF_SDRAMC_SDCR_CKE |
397 MCF_SDRAMC_SDCR_DDR |
398 MCF_SDRAMC_SDCR_MUX(1) |
399 MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
400 MCF_SDRAMC_SDCR_PS_16 |
401 MCF_SDRAMC_SDCR_IPALL,
402 MCF_SDRAMC_SDCR);
403
404 /*
405 * Write extended mode register
406 */
407 writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
408 MCF_SDRAMC_SDMR_AD(0x0) |
409 MCF_SDRAMC_SDMR_CMD,
410 MCF_SDRAMC_SDMR);
411
412 /*
413 * Write mode register and reset DLL
414 */
415 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
416 MCF_SDRAMC_SDMR_AD(0x163) |
417 MCF_SDRAMC_SDMR_CMD,
418 MCF_SDRAMC_SDMR);
419
420 /*
421 * Execute a PALL command
422 */
423 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
424
425 /*
426 * Perform two REF cycles
427 */
428 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
429 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
430
431 /*
432 * Write mode register and clear reset DLL
433 */
434 writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
435 MCF_SDRAMC_SDMR_AD(0x063) |
436 MCF_SDRAMC_SDMR_CMD,
437 MCF_SDRAMC_SDMR);
438
439 /*
440 * Enable auto refresh and lock SDMR
441 */
442 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN,
443 MCF_SDRAMC_SDCR);
444 writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
445 MCF_SDRAMC_SDCR);
446 }
447}
448
449void gpio_init(void)
450{
451 /* Enable UART0 pins */
452 writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
453 MCFGPIO_PAR_UART);
454
455 /*
456 * Initialize TIN3 as a GPIO output to enable the write
457 * half of the latch.
458 */
459 writeb(0x00, MCFGPIO_PAR_TIMER);
460 writeb(0x08, MCFGPIO_PDDR_TIMER);
461 writeb(0x00, MCFGPIO_PCLRR_TIMER);
462}
463
464int clock_pll(int fsys, int flags)
465{
466 int fref, temp, fout, mfd;
467 u32 i;
468
469 fref = FREF;
470
471 if (fsys == 0) {
472 /* Return current PLL output */
473 mfd = readb(MCF_PLL_PFDR);
474
475 return (fref * mfd / (BUSDIV * 4));
476 }
477
478 /* Check bounds of requested system clock */
479 if (fsys > MAX_FSYS)
480 fsys = MAX_FSYS;
481 if (fsys < MIN_FSYS)
482 fsys = MIN_FSYS;
483
484 /* Multiplying by 100 when calculating the temp value,
485 and then dividing by 100 to calculate the mfd allows
486 for exact values without needing to include floating
487 point libraries. */
488 temp = 100 * fsys / fref;
489 mfd = 4 * BUSDIV * temp / 100;
490
491 /* Determine the output frequency for selected values */
492 fout = (fref * mfd / (BUSDIV * 4));
493
494 /*
495 * Check to see if the SDRAM has already been initialized.
496 * If it has then the SDRAM needs to be put into self refresh
497 * mode before reprogramming the PLL.
498 */
499 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
500 /* Put SDRAM into self refresh mode */
501 writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
502 MCF_SDRAMC_SDCR);
503
504 /*
505 * Initialize the PLL to generate the new system clock frequency.
506 * The device must be put into LIMP mode to reprogram the PLL.
507 */
508
509 /* Enter LIMP mode */
510 clock_limp(DEFAULT_LPD);
511
512 /* Reprogram PLL for desired fsys */
513 writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
514 MCF_PLL_PODR);
515
516 writeb(mfd, MCF_PLL_PFDR);
517
518 /* Exit LIMP mode */
519 clock_exit_limp();
520
521 /*
522 * Return the SDRAM to normal operation if it is in use.
523 */
524 if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
525 /* Exit self refresh mode */
526 writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
527 MCF_SDRAMC_SDCR);
528
529 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
530 writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
531
532 /* wait for DQS logic to relock */
533 for (i = 0; i < 0x200; i++)
534 ;
535
536 return fout;
537}
538
539int clock_limp(int div)
540{
541 u32 temp;
542
543 /* Check bounds of divider */
544 if (div < MIN_LPD)
545 div = MIN_LPD;
546 if (div > MAX_LPD)
547 div = MAX_LPD;
548
549 /* Save of the current value of the SSIDIV so we don't
550 overwrite the value*/
551 temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
552
553 /* Apply the divider to the system clock */
554 writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
555
556 writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
557
558 return (FREF/(3*(1 << div)));
559}
560
561int clock_exit_limp(void)
562{
563 int fout;
564
565 /* Exit LIMP mode */
566 writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
567
568 /* Wait for PLL to lock */
569 while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
570 ;
571
572 fout = get_sys_clock();
573
574 return fout;
575}
576
577int get_sys_clock(void)
578{
579 int divider;
580
581 /* Test to see if device is in LIMP mode */
582 if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
583 divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
584 return (FREF/(2 << divider));
585 }
586 else
587 return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
588}
diff --git a/arch/m68k/coldfire/m5407.c b/arch/m68k/coldfire/m5407.c
new file mode 100644
index 000000000000..2fb3cdbfde30
--- /dev/null
+++ b/arch/m68k/coldfire/m5407.c
@@ -0,0 +1,53 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/5407/config.c
5 *
6 * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
7 * Copyright (C) 2000, Lineo (www.lineo.com)
8 */
9
10/***************************************************************************/
11
12#include <linux/kernel.h>
13#include <linux/param.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <asm/machdep.h>
17#include <asm/coldfire.h>
18#include <asm/mcfsim.h>
19#include <asm/mcfclk.h>
20
21/***************************************************************************/
22
23DEFINE_CLK(pll, "pll.0", MCF_CLK);
24DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
25DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
26DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
27DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
28DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
29
30struct clk *mcf_clks[] = {
31 &clk_pll,
32 &clk_sys,
33 &clk_mcftmr0,
34 &clk_mcftmr1,
35 &clk_mcfuart0,
36 &clk_mcfuart1,
37 NULL
38};
39
40/***************************************************************************/
41
42void __init config_BSP(char *commandp, int size)
43{
44 mach_sched_init = hw_timer_init;
45
46 /* Only support the external interrupts on their primary level */
47 mcf_mapirq2imr(25, MCFINTC_EINT1);
48 mcf_mapirq2imr(27, MCFINTC_EINT3);
49 mcf_mapirq2imr(29, MCFINTC_EINT5);
50 mcf_mapirq2imr(31, MCFINTC_EINT7);
51}
52
53/***************************************************************************/
diff --git a/arch/m68k/coldfire/m5441x.c b/arch/m68k/coldfire/m5441x.c
new file mode 100644
index 000000000000..98a13cce93d8
--- /dev/null
+++ b/arch/m68k/coldfire/m5441x.c
@@ -0,0 +1,261 @@
1/*
2 * m5441x.c -- support for Coldfire m5441x processors
3 *
4 * (C) Copyright Steven King <sfking@fdwdc.com>
5 */
6
7#include <linux/kernel.h>
8#include <linux/param.h>
9#include <linux/init.h>
10#include <linux/io.h>
11#include <linux/clk.h>
12#include <asm/machdep.h>
13#include <asm/coldfire.h>
14#include <asm/mcfsim.h>
15#include <asm/mcfuart.h>
16#include <asm/mcfdma.h>
17#include <asm/mcfclk.h>
18
19DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
20DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
21DEFINE_CLK(0, "mcfcan.1", 9, MCF_CLK);
22DEFINE_CLK(0, "mcfi2c.1", 14, MCF_CLK);
23DEFINE_CLK(0, "mcfdspi.1", 15, MCF_CLK);
24DEFINE_CLK(0, "edma", 17, MCF_CLK);
25DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
26DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
27DEFINE_CLK(0, "intc.2", 20, MCF_CLK);
28DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
29DEFINE_CLK(0, "mcfdspi.0", 23, MCF_CLK);
30DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
31DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
32DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
33DEFINE_CLK(0, "mcfuart.3", 27, MCF_BUSCLK);
34DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
35DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
36DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
37DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
38DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
39DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
40DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
41DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
42DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
43DEFINE_CLK(0, "mcfadc.0", 38, MCF_CLK);
44DEFINE_CLK(0, "mcfdac.0", 39, MCF_CLK);
45DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
46DEFINE_CLK(0, "mcfsim.0", 43, MCF_CLK);
47DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
48DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
49DEFINE_CLK(0, "mcfddr-sram.0", 46, MCF_CLK);
50DEFINE_CLK(0, "mcfssi.0", 47, MCF_CLK);
51DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
52DEFINE_CLK(0, "mcfrng.0", 49, MCF_CLK);
53DEFINE_CLK(0, "mcfssi.1", 50, MCF_CLK);
54DEFINE_CLK(0, "mcfsdhc.0", 51, MCF_CLK);
55DEFINE_CLK(0, "enet-fec.0", 53, MCF_CLK);
56DEFINE_CLK(0, "enet-fec.1", 54, MCF_CLK);
57DEFINE_CLK(0, "switch.0", 55, MCF_CLK);
58DEFINE_CLK(0, "switch.1", 56, MCF_CLK);
59DEFINE_CLK(0, "nand.0", 63, MCF_CLK);
60
61DEFINE_CLK(1, "mcfow.0", 2, MCF_CLK);
62DEFINE_CLK(1, "mcfi2c.2", 4, MCF_CLK);
63DEFINE_CLK(1, "mcfi2c.3", 5, MCF_CLK);
64DEFINE_CLK(1, "mcfi2c.4", 6, MCF_CLK);
65DEFINE_CLK(1, "mcfi2c.5", 7, MCF_CLK);
66DEFINE_CLK(1, "mcfuart.4", 24, MCF_BUSCLK);
67DEFINE_CLK(1, "mcfuart.5", 25, MCF_BUSCLK);
68DEFINE_CLK(1, "mcfuart.6", 26, MCF_BUSCLK);
69DEFINE_CLK(1, "mcfuart.7", 27, MCF_BUSCLK);
70DEFINE_CLK(1, "mcfuart.8", 28, MCF_BUSCLK);
71DEFINE_CLK(1, "mcfuart.9", 29, MCF_BUSCLK);
72DEFINE_CLK(1, "mcfpwm.0", 34, MCF_BUSCLK);
73DEFINE_CLK(1, "sys.0", 36, MCF_BUSCLK);
74DEFINE_CLK(1, "gpio.0", 37, MCF_BUSCLK);
75
76struct clk *mcf_clks[] = {
77 &__clk_0_2,
78 &__clk_0_8,
79 &__clk_0_9,
80 &__clk_0_14,
81 &__clk_0_15,
82 &__clk_0_17,
83 &__clk_0_18,
84 &__clk_0_19,
85 &__clk_0_20,
86 &__clk_0_22,
87 &__clk_0_23,
88 &__clk_0_24,
89 &__clk_0_25,
90 &__clk_0_26,
91 &__clk_0_27,
92 &__clk_0_28,
93 &__clk_0_29,
94 &__clk_0_30,
95 &__clk_0_31,
96 &__clk_0_32,
97 &__clk_0_33,
98 &__clk_0_34,
99 &__clk_0_35,
100 &__clk_0_37,
101 &__clk_0_38,
102 &__clk_0_39,
103 &__clk_0_42,
104 &__clk_0_43,
105 &__clk_0_44,
106 &__clk_0_45,
107 &__clk_0_46,
108 &__clk_0_47,
109 &__clk_0_48,
110 &__clk_0_49,
111 &__clk_0_50,
112 &__clk_0_51,
113 &__clk_0_53,
114 &__clk_0_54,
115 &__clk_0_55,
116 &__clk_0_56,
117 &__clk_0_63,
118
119 &__clk_1_2,
120 &__clk_1_4,
121 &__clk_1_5,
122 &__clk_1_6,
123 &__clk_1_7,
124 &__clk_1_24,
125 &__clk_1_25,
126 &__clk_1_26,
127 &__clk_1_27,
128 &__clk_1_28,
129 &__clk_1_29,
130 &__clk_1_34,
131 &__clk_1_36,
132 &__clk_1_37,
133 NULL,
134};
135
136
137static struct clk * const enable_clks[] __initconst = {
138 /* make sure these clocks are enabled */
139 &__clk_0_18, /* intc0 */
140 &__clk_0_19, /* intc0 */
141 &__clk_0_20, /* intc0 */
142 &__clk_0_24, /* uart0 */
143 &__clk_0_25, /* uart1 */
144 &__clk_0_26, /* uart2 */
145 &__clk_0_27, /* uart3 */
146
147 &__clk_0_33, /* pit.1 */
148 &__clk_0_37, /* eport */
149 &__clk_0_48, /* pll */
150
151 &__clk_1_36, /* CCM/reset module/Power management */
152 &__clk_1_37, /* gpio */
153};
154static struct clk * const disable_clks[] __initconst = {
155 &__clk_0_8, /* can.0 */
156 &__clk_0_9, /* can.1 */
157 &__clk_0_14, /* i2c.1 */
158 &__clk_0_15, /* dspi.1 */
159 &__clk_0_17, /* eDMA */
160 &__clk_0_22, /* i2c.0 */
161 &__clk_0_23, /* dspi.0 */
162 &__clk_0_28, /* tmr.1 */
163 &__clk_0_29, /* tmr.2 */
164 &__clk_0_30, /* tmr.2 */
165 &__clk_0_31, /* tmr.3 */
166 &__clk_0_32, /* pit.0 */
167 &__clk_0_34, /* pit.2 */
168 &__clk_0_35, /* pit.3 */
169 &__clk_0_38, /* adc */
170 &__clk_0_39, /* dac */
171 &__clk_0_44, /* usb otg */
172 &__clk_0_45, /* usb host */
173 &__clk_0_47, /* ssi.0 */
174 &__clk_0_49, /* rng */
175 &__clk_0_50, /* ssi.1 */
176 &__clk_0_51, /* eSDHC */
177 &__clk_0_53, /* enet-fec */
178 &__clk_0_54, /* enet-fec */
179 &__clk_0_55, /* switch.0 */
180 &__clk_0_56, /* switch.1 */
181
182 &__clk_1_2, /* 1-wire */
183 &__clk_1_4, /* i2c.2 */
184 &__clk_1_5, /* i2c.3 */
185 &__clk_1_6, /* i2c.4 */
186 &__clk_1_7, /* i2c.5 */
187 &__clk_1_24, /* uart 4 */
188 &__clk_1_25, /* uart 5 */
189 &__clk_1_26, /* uart 6 */
190 &__clk_1_27, /* uart 7 */
191 &__clk_1_28, /* uart 8 */
192 &__clk_1_29, /* uart 9 */
193};
194
195static void __init m5441x_clk_init(void)
196{
197 unsigned i;
198
199 for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
200 __clk_init_enabled(enable_clks[i]);
201 /* make sure these clocks are disabled */
202 for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
203 __clk_init_disabled(disable_clks[i]);
204}
205
206static void __init m5441x_uarts_init(void)
207{
208 __raw_writeb(0x0f, MCFGPIO_PAR_UART0);
209 __raw_writeb(0x00, MCFGPIO_PAR_UART1);
210 __raw_writeb(0x00, MCFGPIO_PAR_UART2);
211}
212
213static void __init m5441x_fec_init(void)
214{
215 __raw_writeb(0x03, MCFGPIO_PAR_FEC);
216}
217
218void __init config_BSP(char *commandp, int size)
219{
220 m5441x_clk_init();
221 mach_sched_init = hw_timer_init;
222 m5441x_uarts_init();
223 m5441x_fec_init();
224}
225
226
227#if IS_ENABLED(CONFIG_RTC_DRV_M5441x)
228static struct resource m5441x_rtc_resources[] = {
229 {
230 .start = MCFRTC_BASE,
231 .end = MCFRTC_BASE + MCFRTC_SIZE - 1,
232 .flags = IORESOURCE_MEM,
233 },
234 {
235 .start = MCF_IRQ_RTC,
236 .end = MCF_IRQ_RTC,
237 .flags = IORESOURCE_IRQ,
238 },
239};
240
241static struct platform_device m5441x_rtc = {
242 .name = "mcfrtc",
243 .id = 0,
244 .resource = m5441x_rtc_resources,
245 .num_resources = ARRAY_SIZE(m5441x_rtc_resources),
246};
247#endif
248
249static struct platform_device *m5441x_devices[] __initdata = {
250#if IS_ENABLED(CONFIG_RTC_DRV_M5441x)
251 &m5441x_rtc,
252#endif
253};
254
255static int __init init_BSP(void)
256{
257 platform_add_devices(m5441x_devices, ARRAY_SIZE(m5441x_devices));
258 return 0;
259}
260
261arch_initcall(init_BSP);
diff --git a/arch/m68k/coldfire/m54xx.c b/arch/m68k/coldfire/m54xx.c
new file mode 100644
index 000000000000..952da53aa0bc
--- /dev/null
+++ b/arch/m68k/coldfire/m54xx.c
@@ -0,0 +1,129 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/54xx/config.c
5 *
6 * Copyright (C) 2010, Philippe De Muyter <phdm@macqel.be>
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <linux/param.h>
13#include <linux/init.h>
14#include <linux/interrupt.h>
15#include <linux/io.h>
16#include <linux/mm.h>
17#include <linux/clk.h>
18#include <linux/bootmem.h>
19#include <asm/pgalloc.h>
20#include <asm/machdep.h>
21#include <asm/coldfire.h>
22#include <asm/m54xxsim.h>
23#include <asm/mcfuart.h>
24#include <asm/mcfclk.h>
25#include <asm/m54xxgpt.h>
26#include <asm/mcfclk.h>
27#ifdef CONFIG_MMU
28#include <asm/mmu_context.h>
29#endif
30
31/***************************************************************************/
32
33DEFINE_CLK(pll, "pll.0", MCF_CLK);
34DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
35DEFINE_CLK(mcfslt0, "mcfslt.0", MCF_BUSCLK);
36DEFINE_CLK(mcfslt1, "mcfslt.1", MCF_BUSCLK);
37DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
38DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
39DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK);
40DEFINE_CLK(mcfuart3, "mcfuart.3", MCF_BUSCLK);
41
42struct clk *mcf_clks[] = {
43 &clk_pll,
44 &clk_sys,
45 &clk_mcfslt0,
46 &clk_mcfslt1,
47 &clk_mcfuart0,
48 &clk_mcfuart1,
49 &clk_mcfuart2,
50 &clk_mcfuart3,
51 NULL
52};
53
54/***************************************************************************/
55
56static void __init m54xx_uarts_init(void)
57{
58 /* enable io pins */
59 __raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD, MCFGPIO_PAR_PSC0);
60 __raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD | MCF_PAR_PSC_RTS_RTS,
61 MCFGPIO_PAR_PSC1);
62 __raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD | MCF_PAR_PSC_RTS_RTS |
63 MCF_PAR_PSC_CTS_CTS, MCFGPIO_PAR_PSC2);
64 __raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD, MCFGPIO_PAR_PSC3);
65}
66
67/***************************************************************************/
68
69static void mcf54xx_reset(void)
70{
71 /* disable interrupts and enable the watchdog */
72 asm("movew #0x2700, %sr\n");
73 __raw_writel(0, MCF_GPT_GMS0);
74 __raw_writel(MCF_GPT_GCIR_CNT(1), MCF_GPT_GCIR0);
75 __raw_writel(MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS(4),
76 MCF_GPT_GMS0);
77}
78
79/***************************************************************************/
80
81#ifdef CONFIG_MMU
82
83unsigned long num_pages;
84
85static void __init mcf54xx_bootmem_alloc(void)
86{
87 unsigned long start_pfn;
88 unsigned long memstart;
89
90 /* _rambase and _ramend will be naturally page aligned */
91 m68k_memory[0].addr = _rambase;
92 m68k_memory[0].size = _ramend - _rambase;
93
94 /* compute total pages in system */
95 num_pages = (_ramend - _rambase) >> PAGE_SHIFT;
96
97 /* page numbers */
98 memstart = PAGE_ALIGN(_ramstart);
99 min_low_pfn = _rambase >> PAGE_SHIFT;
100 start_pfn = memstart >> PAGE_SHIFT;
101 max_low_pfn = _ramend >> PAGE_SHIFT;
102 high_memory = (void *)_ramend;
103
104 m68k_virt_to_node_shift = fls(_ramend - _rambase - 1) - 6;
105 module_fixup(NULL, __start_fixup, __stop_fixup);
106
107 /* setup bootmem data */
108 m68k_setup_node(0);
109 memstart += init_bootmem_node(NODE_DATA(0), start_pfn,
110 min_low_pfn, max_low_pfn);
111 free_bootmem_node(NODE_DATA(0), memstart, _ramend - memstart);
112}
113
114#endif /* CONFIG_MMU */
115
116/***************************************************************************/
117
118void __init config_BSP(char *commandp, int size)
119{
120#ifdef CONFIG_MMU
121 mcf54xx_bootmem_alloc();
122 mmu_context_init();
123#endif
124 mach_reset = mcf54xx_reset;
125 mach_sched_init = hw_timer_init;
126 m54xx_uarts_init();
127}
128
129/***************************************************************************/
diff --git a/arch/m68k/coldfire/mcf8390.c b/arch/m68k/coldfire/mcf8390.c
new file mode 100644
index 000000000000..23a6874a3248
--- /dev/null
+++ b/arch/m68k/coldfire/mcf8390.c
@@ -0,0 +1,38 @@
1/*
2 * mcf8390.c -- platform support for 8390 ethernet on many boards
3 *
4 * (C) Copyright 2012, Greg Ungerer <gerg@uclinux.org>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/resource.h>
15#include <linux/platform_device.h>
16#include <asm/mcf8390.h>
17
18static struct resource mcf8390_resources[] = {
19 {
20 .start = NE2000_ADDR,
21 .end = NE2000_ADDR + NE2000_ADDRSIZE - 1,
22 .flags = IORESOURCE_MEM,
23 },
24 {
25 .start = NE2000_IRQ_VECTOR,
26 .end = NE2000_IRQ_VECTOR,
27 .flags = IORESOURCE_IRQ,
28 },
29};
30
31static int __init mcf8390_platform_init(void)
32{
33 platform_device_register_simple("mcf8390", -1, mcf8390_resources,
34 ARRAY_SIZE(mcf8390_resources));
35 return 0;
36}
37
38arch_initcall(mcf8390_platform_init);
diff --git a/arch/m68k/coldfire/nettel.c b/arch/m68k/coldfire/nettel.c
new file mode 100644
index 000000000000..ddc48ec1b800
--- /dev/null
+++ b/arch/m68k/coldfire/nettel.c
@@ -0,0 +1,153 @@
1/***************************************************************************/
2
3/*
4 * nettel.c -- startup code support for the NETtel boards
5 *
6 * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <linux/param.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <asm/coldfire.h>
17#include <asm/mcfsim.h>
18#include <asm/nettel.h>
19
20/***************************************************************************/
21
22/*
23 * Define the IO and interrupt resources of the 2 SMC9196 interfaces.
24 */
25#define NETTEL_SMC0_ADDR 0x30600300
26#define NETTEL_SMC0_IRQ 29
27
28#define NETTEL_SMC1_ADDR 0x30600000
29#define NETTEL_SMC1_IRQ 27
30
31/*
32 * We need some access into the SMC9196 registers. Define those registers
33 * we will need here (including the smc91x.h doesn't seem to give us these
34 * in a simple form).
35 */
36#define SMC91xx_BANKSELECT 14
37#define SMC91xx_BASEADDR 2
38#define SMC91xx_BASEMAC 4
39
40/***************************************************************************/
41
42static struct resource nettel_smc91x_0_resources[] = {
43 {
44 .start = NETTEL_SMC0_ADDR,
45 .end = NETTEL_SMC0_ADDR + 0x20,
46 .flags = IORESOURCE_MEM,
47 },
48 {
49 .start = NETTEL_SMC0_IRQ,
50 .end = NETTEL_SMC0_IRQ,
51 .flags = IORESOURCE_IRQ,
52 },
53};
54
55static struct resource nettel_smc91x_1_resources[] = {
56 {
57 .start = NETTEL_SMC1_ADDR,
58 .end = NETTEL_SMC1_ADDR + 0x20,
59 .flags = IORESOURCE_MEM,
60 },
61 {
62 .start = NETTEL_SMC1_IRQ,
63 .end = NETTEL_SMC1_IRQ,
64 .flags = IORESOURCE_IRQ,
65 },
66};
67
68static struct platform_device nettel_smc91x[] = {
69 {
70 .name = "smc91x",
71 .id = 0,
72 .num_resources = ARRAY_SIZE(nettel_smc91x_0_resources),
73 .resource = nettel_smc91x_0_resources,
74 },
75 {
76 .name = "smc91x",
77 .id = 1,
78 .num_resources = ARRAY_SIZE(nettel_smc91x_1_resources),
79 .resource = nettel_smc91x_1_resources,
80 },
81};
82
83static struct platform_device *nettel_devices[] __initdata = {
84 &nettel_smc91x[0],
85 &nettel_smc91x[1],
86};
87
88/***************************************************************************/
89
90static u8 nettel_macdefault[] __initdata = {
91 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01,
92};
93
94/*
95 * Set flash contained MAC address into SMC9196 core. Make sure the flash
96 * MAC address is sane, and not an empty flash. If no good use the Moreton
97 * Bay default MAC address instead.
98 */
99
100static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr)
101{
102 u16 *macp;
103
104 macp = (u16 *) flashaddr;
105 if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff))
106 macp = (u16 *) &nettel_macdefault[0];
107
108 writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
109 writew(macp[0], ioaddr + SMC91xx_BASEMAC);
110 writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2);
111 writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4);
112}
113
114/***************************************************************************/
115
116/*
117 * Re-map the address space of at least one of the SMC ethernet
118 * parts. Both parts power up decoding the same address, so we
119 * need to move one of them first, before doing anything else.
120 */
121
122static void __init nettel_smc91x_init(void)
123{
124 writew(0x00ec, MCFSIM_PADDR);
125 mcf_setppdata(0, 0x0080);
126 writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
127 writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR);
128 mcf_setppdata(0x0080, 0);
129
130 /* Set correct chip select timing for SMC9196 accesses */
131 writew(0x1180, MCFSIM_CSCR3);
132
133 /* Set the SMC interrupts to be auto-vectored */
134 mcf_autovector(NETTEL_SMC0_IRQ);
135 mcf_autovector(NETTEL_SMC1_IRQ);
136
137 /* Set MAC addresses from flash for both interfaces */
138 nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000);
139 nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006);
140}
141
142/***************************************************************************/
143
144static int __init init_nettel(void)
145{
146 nettel_smc91x_init();
147 platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices));
148 return 0;
149}
150
151arch_initcall(init_nettel);
152
153/***************************************************************************/
diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c
new file mode 100644
index 000000000000..df9679238b6d
--- /dev/null
+++ b/arch/m68k/coldfire/pci.c
@@ -0,0 +1,325 @@
1/*
2 * pci.c -- PCI bus support for ColdFire processors
3 *
4 * (C) Copyright 2012, Greg Ungerer <gerg@uclinux.com>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/io.h>
18#include <linux/pci.h>
19#include <linux/delay.h>
20#include <asm/coldfire.h>
21#include <asm/mcfsim.h>
22#include <asm/m54xxpci.h>
23
24/*
25 * Memory and IO mappings. We use a 1:1 mapping for local host memory to
26 * PCI bus memory (no reason not to really). IO space doesn't matter, we
27 * always use access functions for that. The device configuration space is
28 * mapped over the IO map space when we enable it in the PCICAR register.
29 */
30#define PCI_MEM_PA 0xf0000000 /* Host physical address */
31#define PCI_MEM_BA 0xf0000000 /* Bus physical address */
32#define PCI_MEM_SIZE 0x08000000 /* 128 MB */
33#define PCI_MEM_MASK (PCI_MEM_SIZE - 1)
34
35#define PCI_IO_PA 0xf8000000 /* Host physical address */
36#define PCI_IO_BA 0x00000000 /* Bus physical address */
37#define PCI_IO_SIZE 0x00010000 /* 64k */
38#define PCI_IO_MASK (PCI_IO_SIZE - 1)
39
40static struct pci_bus *rootbus;
41static unsigned long iospace;
42
43/*
44 * We need to be carefull probing on bus 0 (directly connected to host
45 * bridge). We should only acccess the well defined possible devices in
46 * use, ignore aliases and the like.
47 */
48static unsigned char mcf_host_slot2sid[32] = {
49 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 1, 2, 0, 3, 4, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0,
53};
54
55static unsigned char mcf_host_irq[] = {
56 0, 69, 69, 71, 71,
57};
58
59
60static inline void syncio(void)
61{
62 /* The ColdFire "nop" instruction waits for all bus IO to complete */
63 __asm__ __volatile__ ("nop");
64}
65
66/*
67 * Configuration space access functions. Configuration space access is
68 * through the IO mapping window, enabling it via the PCICAR register.
69 */
70static unsigned long mcf_mk_pcicar(int bus, unsigned int devfn, int where)
71{
72 return (bus << PCICAR_BUSN) | (devfn << PCICAR_DEVFNN) | (where & 0xfc);
73}
74
75static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn,
76 int where, int size, u32 *value)
77{
78 unsigned long addr;
79
80 *value = 0xffffffff;
81
82 if (bus->number == 0) {
83 if (mcf_host_slot2sid[PCI_SLOT(devfn)] == 0)
84 return PCIBIOS_SUCCESSFUL;
85 }
86
87 syncio();
88 addr = mcf_mk_pcicar(bus->number, devfn, where);
89 __raw_writel(PCICAR_E | addr, PCICAR);
90 addr = iospace + (where & 0x3);
91
92 switch (size) {
93 case 1:
94 *value = __raw_readb(addr);
95 break;
96 case 2:
97 *value = le16_to_cpu(__raw_readw(addr));
98 break;
99 default:
100 *value = le32_to_cpu(__raw_readl(addr));
101 break;
102 }
103
104 syncio();
105 __raw_writel(0, PCICAR);
106 return PCIBIOS_SUCCESSFUL;
107}
108
109static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn,
110 int where, int size, u32 value)
111{
112 unsigned long addr;
113
114 if (bus->number == 0) {
115 if (mcf_host_slot2sid[PCI_SLOT(devfn)] == 0)
116 return PCIBIOS_SUCCESSFUL;
117 }
118
119 syncio();
120 addr = mcf_mk_pcicar(bus->number, devfn, where);
121 __raw_writel(PCICAR_E | addr, PCICAR);
122 addr = iospace + (where & 0x3);
123
124 switch (size) {
125 case 1:
126 __raw_writeb(value, addr);
127 break;
128 case 2:
129 __raw_writew(cpu_to_le16(value), addr);
130 break;
131 default:
132 __raw_writel(cpu_to_le32(value), addr);
133 break;
134 }
135
136 syncio();
137 __raw_writel(0, PCICAR);
138 return PCIBIOS_SUCCESSFUL;
139}
140
141static struct pci_ops mcf_pci_ops = {
142 .read = mcf_pci_readconfig,
143 .write = mcf_pci_writeconfig,
144};
145
146/*
147 * IO address space access functions. Pretty strait forward, these are
148 * directly mapped in to the IO mapping window. And that is mapped into
149 * virtual address space.
150 */
151u8 mcf_pci_inb(u32 addr)
152{
153 return __raw_readb(iospace + (addr & PCI_IO_MASK));
154}
155EXPORT_SYMBOL(mcf_pci_inb);
156
157u16 mcf_pci_inw(u32 addr)
158{
159 return le16_to_cpu(__raw_readw(iospace + (addr & PCI_IO_MASK)));
160}
161EXPORT_SYMBOL(mcf_pci_inw);
162
163u32 mcf_pci_inl(u32 addr)
164{
165 return le32_to_cpu(__raw_readl(iospace + (addr & PCI_IO_MASK)));
166}
167EXPORT_SYMBOL(mcf_pci_inl);
168
169void mcf_pci_insb(u32 addr, u8 *buf, u32 len)
170{
171 for (; len; len--)
172 *buf++ = mcf_pci_inb(addr);
173}
174EXPORT_SYMBOL(mcf_pci_insb);
175
176void mcf_pci_insw(u32 addr, u16 *buf, u32 len)
177{
178 for (; len; len--)
179 *buf++ = mcf_pci_inw(addr);
180}
181EXPORT_SYMBOL(mcf_pci_insw);
182
183void mcf_pci_insl(u32 addr, u32 *buf, u32 len)
184{
185 for (; len; len--)
186 *buf++ = mcf_pci_inl(addr);
187}
188EXPORT_SYMBOL(mcf_pci_insl);
189
190void mcf_pci_outb(u8 v, u32 addr)
191{
192 __raw_writeb(v, iospace + (addr & PCI_IO_MASK));
193}
194EXPORT_SYMBOL(mcf_pci_outb);
195
196void mcf_pci_outw(u16 v, u32 addr)
197{
198 __raw_writew(cpu_to_le16(v), iospace + (addr & PCI_IO_MASK));
199}
200EXPORT_SYMBOL(mcf_pci_outw);
201
202void mcf_pci_outl(u32 v, u32 addr)
203{
204 __raw_writel(cpu_to_le32(v), iospace + (addr & PCI_IO_MASK));
205}
206EXPORT_SYMBOL(mcf_pci_outl);
207
208void mcf_pci_outsb(u32 addr, const u8 *buf, u32 len)
209{
210 for (; len; len--)
211 mcf_pci_outb(*buf++, addr);
212}
213EXPORT_SYMBOL(mcf_pci_outsb);
214
215void mcf_pci_outsw(u32 addr, const u16 *buf, u32 len)
216{
217 for (; len; len--)
218 mcf_pci_outw(*buf++, addr);
219}
220EXPORT_SYMBOL(mcf_pci_outsw);
221
222void mcf_pci_outsl(u32 addr, const u32 *buf, u32 len)
223{
224 for (; len; len--)
225 mcf_pci_outl(*buf++, addr);
226}
227EXPORT_SYMBOL(mcf_pci_outsl);
228
229/*
230 * Initialize the PCI bus registers, and scan the bus.
231 */
232static struct resource mcf_pci_mem = {
233 .name = "PCI Memory space",
234 .start = PCI_MEM_PA,
235 .end = PCI_MEM_PA + PCI_MEM_SIZE - 1,
236 .flags = IORESOURCE_MEM,
237};
238
239static struct resource mcf_pci_io = {
240 .name = "PCI IO space",
241 .start = 0x400,
242 .end = 0x10000 - 1,
243 .flags = IORESOURCE_IO,
244};
245
246/*
247 * Interrupt mapping and setting.
248 */
249static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
250{
251 int sid;
252
253 sid = mcf_host_slot2sid[slot];
254 if (sid)
255 return mcf_host_irq[sid];
256 return 0;
257}
258
259static int __init mcf_pci_init(void)
260{
261 pr_info("ColdFire: PCI bus initialization...\n");
262
263 /* Reset the external PCI bus */
264 __raw_writel(PCIGSCR_RESET, PCIGSCR);
265 __raw_writel(0, PCITCR);
266
267 request_resource(&iomem_resource, &mcf_pci_mem);
268 request_resource(&iomem_resource, &mcf_pci_io);
269
270 /* Configure PCI arbiter */
271 __raw_writel(PACR_INTMPRI | PACR_INTMINTE | PACR_EXTMPRI(0x1f) |
272 PACR_EXTMINTE(0x1f), PACR);
273
274 /* Set required multi-function pins for PCI bus use */
275 __raw_writew(0x3ff, MCFGPIO_PAR_PCIBG);
276 __raw_writew(0x3ff, MCFGPIO_PAR_PCIBR);
277
278 /* Set up config space for local host bus controller */
279 __raw_writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
280 PCI_COMMAND_INVALIDATE, PCISCR);
281 __raw_writel(PCICR1_LT(32) | PCICR1_CL(8), PCICR1);
282 __raw_writel(0, PCICR2);
283
284 /*
285 * Set up the initiator windows for memory and IO mapping.
286 * These give the CPU bus access onto the PCI bus. One for each of
287 * PCI memory and IO address spaces.
288 */
289 __raw_writel(WXBTAR(PCI_MEM_PA, PCI_MEM_BA, PCI_MEM_SIZE),
290 PCIIW0BTAR);
291 __raw_writel(WXBTAR(PCI_IO_PA, PCI_IO_BA, PCI_IO_SIZE),
292 PCIIW1BTAR);
293 __raw_writel(PCIIWCR_W0_MEM /*| PCIIWCR_W0_MRDL*/ | PCIIWCR_W0_E |
294 PCIIWCR_W1_IO | PCIIWCR_W1_E, PCIIWCR);
295
296 /*
297 * Set up the target windows for access from the PCI bus back to the
298 * CPU bus. All we need is access to system RAM (for mastering).
299 */
300 __raw_writel(CONFIG_RAMBASE, PCIBAR1);
301 __raw_writel(CONFIG_RAMBASE | PCITBATR1_E, PCITBATR1);
302
303 /* Keep a virtual mapping to IO/config space active */
304 iospace = (unsigned long) ioremap(PCI_IO_PA, PCI_IO_SIZE);
305 if (iospace == 0)
306 return -ENODEV;
307 pr_info("Coldfire: PCI IO/config window mapped to 0x%x\n",
308 (u32) iospace);
309
310 /* Turn of PCI reset, and wait for devices to settle */
311 __raw_writel(0, PCIGSCR);
312 set_current_state(TASK_UNINTERRUPTIBLE);
313 schedule_timeout(msecs_to_jiffies(200));
314
315 rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL);
316 rootbus->resource[0] = &mcf_pci_io;
317 rootbus->resource[1] = &mcf_pci_mem;
318
319 pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq);
320 pci_bus_size_bridges(rootbus);
321 pci_bus_assign_resources(rootbus);
322 return 0;
323}
324
325subsys_initcall(mcf_pci_init);
diff --git a/arch/m68k/coldfire/pit.c b/arch/m68k/coldfire/pit.c
new file mode 100644
index 000000000000..493b3111d4c1
--- /dev/null
+++ b/arch/m68k/coldfire/pit.c
@@ -0,0 +1,167 @@
1/***************************************************************************/
2
3/*
4 * pit.c -- Freescale ColdFire PIT timer. Currently this type of
5 * hardware timer only exists in the Freescale ColdFire
6 * 5270/5271, 5282 and 5208 CPUs. No doubt newer ColdFire
7 * family members will probably use it too.
8 *
9 * Copyright (C) 1999-2008, Greg Ungerer (gerg@snapgear.com)
10 * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
11 */
12
13/***************************************************************************/
14
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <linux/param.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/irq.h>
21#include <linux/clockchips.h>
22#include <asm/machdep.h>
23#include <asm/io.h>
24#include <asm/coldfire.h>
25#include <asm/mcfpit.h>
26#include <asm/mcfsim.h>
27
28/***************************************************************************/
29
30/*
31 * By default use timer1 as the system clock timer.
32 */
33#define FREQ ((MCF_CLK / 2) / 64)
34#define TA(a) (MCFPIT_BASE1 + (a))
35#define PIT_CYCLES_PER_JIFFY (FREQ / HZ)
36
37static u32 pit_cnt;
38
39/*
40 * Initialize the PIT timer.
41 *
42 * This is also called after resume to bring the PIT into operation again.
43 */
44
45static void init_cf_pit_timer(enum clock_event_mode mode,
46 struct clock_event_device *evt)
47{
48 switch (mode) {
49 case CLOCK_EVT_MODE_PERIODIC:
50
51 __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR));
52 __raw_writew(PIT_CYCLES_PER_JIFFY, TA(MCFPIT_PMR));
53 __raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | \
54 MCFPIT_PCSR_OVW | MCFPIT_PCSR_RLD | \
55 MCFPIT_PCSR_CLK64, TA(MCFPIT_PCSR));
56 break;
57
58 case CLOCK_EVT_MODE_SHUTDOWN:
59 case CLOCK_EVT_MODE_UNUSED:
60
61 __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR));
62 break;
63
64 case CLOCK_EVT_MODE_ONESHOT:
65
66 __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR));
67 __raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | \
68 MCFPIT_PCSR_OVW | MCFPIT_PCSR_CLK64, \
69 TA(MCFPIT_PCSR));
70 break;
71
72 case CLOCK_EVT_MODE_RESUME:
73 /* Nothing to do here */
74 break;
75 }
76}
77
78/*
79 * Program the next event in oneshot mode
80 *
81 * Delta is given in PIT ticks
82 */
83static int cf_pit_next_event(unsigned long delta,
84 struct clock_event_device *evt)
85{
86 __raw_writew(delta, TA(MCFPIT_PMR));
87 return 0;
88}
89
90struct clock_event_device cf_pit_clockevent = {
91 .name = "pit",
92 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
93 .set_mode = init_cf_pit_timer,
94 .set_next_event = cf_pit_next_event,
95 .shift = 32,
96 .irq = MCF_IRQ_PIT1,
97};
98
99
100
101/***************************************************************************/
102
103static irqreturn_t pit_tick(int irq, void *dummy)
104{
105 struct clock_event_device *evt = &cf_pit_clockevent;
106 u16 pcsr;
107
108 /* Reset the ColdFire timer */
109 pcsr = __raw_readw(TA(MCFPIT_PCSR));
110 __raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR));
111
112 pit_cnt += PIT_CYCLES_PER_JIFFY;
113 evt->event_handler(evt);
114 return IRQ_HANDLED;
115}
116
117/***************************************************************************/
118
119static struct irqaction pit_irq = {
120 .name = "timer",
121 .flags = IRQF_TIMER,
122 .handler = pit_tick,
123};
124
125/***************************************************************************/
126
127static cycle_t pit_read_clk(struct clocksource *cs)
128{
129 unsigned long flags;
130 u32 cycles;
131 u16 pcntr;
132
133 local_irq_save(flags);
134 pcntr = __raw_readw(TA(MCFPIT_PCNTR));
135 cycles = pit_cnt;
136 local_irq_restore(flags);
137
138 return cycles + PIT_CYCLES_PER_JIFFY - pcntr;
139}
140
141/***************************************************************************/
142
143static struct clocksource pit_clk = {
144 .name = "pit",
145 .rating = 100,
146 .read = pit_read_clk,
147 .mask = CLOCKSOURCE_MASK(32),
148};
149
150/***************************************************************************/
151
152void hw_timer_init(irq_handler_t handler)
153{
154 cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id());
155 cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
156 cf_pit_clockevent.max_delta_ns =
157 clockevent_delta2ns(0xFFFF, &cf_pit_clockevent);
158 cf_pit_clockevent.min_delta_ns =
159 clockevent_delta2ns(0x3f, &cf_pit_clockevent);
160 clockevents_register_device(&cf_pit_clockevent);
161
162 setup_irq(MCF_IRQ_PIT1, &pit_irq);
163
164 clocksource_register_hz(&pit_clk, FREQ);
165}
166
167/***************************************************************************/
diff --git a/arch/m68k/coldfire/reset.c b/arch/m68k/coldfire/reset.c
new file mode 100644
index 000000000000..f30952f0cbe6
--- /dev/null
+++ b/arch/m68k/coldfire/reset.c
@@ -0,0 +1,50 @@
1/*
2 * reset.c -- common ColdFire SoC reset support
3 *
4 * (C) Copyright 2012, Greg Ungerer <gerg@uclinux.org>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/io.h>
14#include <asm/machdep.h>
15#include <asm/coldfire.h>
16#include <asm/mcfsim.h>
17
18/*
19 * There are 2 common methods amongst the ColdFure parts for reseting
20 * the CPU. But there are couple of exceptions, the 5272 and the 547x
21 * have something completely special to them, and we let their specific
22 * subarch code handle them.
23 */
24
25#ifdef MCFSIM_SYPCR
26static void mcf_cpu_reset(void)
27{
28 local_irq_disable();
29 /* Set watchdog to soft reset, and enabled */
30 __raw_writeb(0xc0, MCFSIM_SYPCR);
31 for (;;)
32 /* wait for watchdog to timeout */;
33}
34#endif
35
36#ifdef MCF_RCR
37static void mcf_cpu_reset(void)
38{
39 local_irq_disable();
40 __raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
41}
42#endif
43
44static int __init mcf_setup_reset(void)
45{
46 mach_reset = mcf_cpu_reset;
47 return 0;
48}
49
50arch_initcall(mcf_setup_reset);
diff --git a/arch/m68k/coldfire/sltimers.c b/arch/m68k/coldfire/sltimers.c
new file mode 100644
index 000000000000..831a08cf6f40
--- /dev/null
+++ b/arch/m68k/coldfire/sltimers.c
@@ -0,0 +1,149 @@
1/***************************************************************************/
2
3/*
4 * sltimers.c -- generic ColdFire slice timer support.
5 *
6 * Copyright (C) 2009-2010, Philippe De Muyter <phdm@macqel.be>
7 * based on
8 * timers.c -- generic ColdFire hardware timer support.
9 * Copyright (C) 1999-2008, Greg Ungerer <gerg@snapgear.com>
10 */
11
12/***************************************************************************/
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/sched.h>
17#include <linux/interrupt.h>
18#include <linux/irq.h>
19#include <linux/profile.h>
20#include <linux/clocksource.h>
21#include <asm/io.h>
22#include <asm/traps.h>
23#include <asm/machdep.h>
24#include <asm/coldfire.h>
25#include <asm/mcfslt.h>
26#include <asm/mcfsim.h>
27
28/***************************************************************************/
29
30#ifdef CONFIG_HIGHPROFILE
31
32/*
33 * By default use Slice Timer 1 as the profiler clock timer.
34 */
35#define PA(a) (MCFSLT_TIMER1 + (a))
36
37/*
38 * Choose a reasonably fast profile timer. Make it an odd value to
39 * try and get good coverage of kernel operations.
40 */
41#define PROFILEHZ 1013
42
43irqreturn_t mcfslt_profile_tick(int irq, void *dummy)
44{
45 /* Reset Slice Timer 1 */
46 __raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, PA(MCFSLT_SSR));
47 if (current->pid)
48 profile_tick(CPU_PROFILING);
49 return IRQ_HANDLED;
50}
51
52static struct irqaction mcfslt_profile_irq = {
53 .name = "profile timer",
54 .flags = IRQF_TIMER,
55 .handler = mcfslt_profile_tick,
56};
57
58void mcfslt_profile_init(void)
59{
60 printk(KERN_INFO "PROFILE: lodging TIMER 1 @ %dHz as profile timer\n",
61 PROFILEHZ);
62
63 setup_irq(MCF_IRQ_PROFILER, &mcfslt_profile_irq);
64
65 /* Set up TIMER 2 as high speed profile clock */
66 __raw_writel(MCF_BUSCLK / PROFILEHZ - 1, PA(MCFSLT_STCNT));
67 __raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN,
68 PA(MCFSLT_SCR));
69
70}
71
72#endif /* CONFIG_HIGHPROFILE */
73
74/***************************************************************************/
75
76/*
77 * By default use Slice Timer 0 as the system clock timer.
78 */
79#define TA(a) (MCFSLT_TIMER0 + (a))
80
81static u32 mcfslt_cycles_per_jiffy;
82static u32 mcfslt_cnt;
83
84static irq_handler_t timer_interrupt;
85
86static irqreturn_t mcfslt_tick(int irq, void *dummy)
87{
88 /* Reset Slice Timer 0 */
89 __raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, TA(MCFSLT_SSR));
90 mcfslt_cnt += mcfslt_cycles_per_jiffy;
91 return timer_interrupt(irq, dummy);
92}
93
94static struct irqaction mcfslt_timer_irq = {
95 .name = "timer",
96 .flags = IRQF_TIMER,
97 .handler = mcfslt_tick,
98};
99
100static cycle_t mcfslt_read_clk(struct clocksource *cs)
101{
102 unsigned long flags;
103 u32 cycles, scnt;
104
105 local_irq_save(flags);
106 scnt = __raw_readl(TA(MCFSLT_SCNT));
107 cycles = mcfslt_cnt;
108 if (__raw_readl(TA(MCFSLT_SSR)) & MCFSLT_SSR_TE) {
109 cycles += mcfslt_cycles_per_jiffy;
110 scnt = __raw_readl(TA(MCFSLT_SCNT));
111 }
112 local_irq_restore(flags);
113
114 /* subtract because slice timers count down */
115 return cycles + ((mcfslt_cycles_per_jiffy - 1) - scnt);
116}
117
118static struct clocksource mcfslt_clk = {
119 .name = "slt",
120 .rating = 250,
121 .read = mcfslt_read_clk,
122 .mask = CLOCKSOURCE_MASK(32),
123 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
124};
125
126void hw_timer_init(irq_handler_t handler)
127{
128 mcfslt_cycles_per_jiffy = MCF_BUSCLK / HZ;
129 /*
130 * The coldfire slice timer (SLT) runs from STCNT to 0 included,
131 * then STCNT again and so on. It counts thus actually
132 * STCNT + 1 steps for 1 tick, not STCNT. So if you want
133 * n cycles, initialize STCNT with n - 1.
134 */
135 __raw_writel(mcfslt_cycles_per_jiffy - 1, TA(MCFSLT_STCNT));
136 __raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN,
137 TA(MCFSLT_SCR));
138 /* initialize mcfslt_cnt knowing that slice timers count down */
139 mcfslt_cnt = mcfslt_cycles_per_jiffy;
140
141 timer_interrupt = handler;
142 setup_irq(MCF_IRQ_TIMER, &mcfslt_timer_irq);
143
144 clocksource_register_hz(&mcfslt_clk, MCF_BUSCLK);
145
146#ifdef CONFIG_HIGHPROFILE
147 mcfslt_profile_init();
148#endif
149}
diff --git a/arch/m68k/coldfire/timers.c b/arch/m68k/coldfire/timers.c
new file mode 100644
index 000000000000..cd496a20fcc7
--- /dev/null
+++ b/arch/m68k/coldfire/timers.c
@@ -0,0 +1,195 @@
1/***************************************************************************/
2
3/*
4 * timers.c -- generic ColdFire hardware timer support.
5 *
6 * Copyright (C) 1999-2008, Greg Ungerer <gerg@snapgear.com>
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/sched.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/profile.h>
17#include <linux/clocksource.h>
18#include <asm/io.h>
19#include <asm/traps.h>
20#include <asm/machdep.h>
21#include <asm/coldfire.h>
22#include <asm/mcftimer.h>
23#include <asm/mcfsim.h>
24
25/***************************************************************************/
26
27/*
28 * By default use timer1 as the system clock timer.
29 */
30#define FREQ (MCF_BUSCLK / 16)
31#define TA(a) (MCFTIMER_BASE1 + (a))
32
33/*
34 * These provide the underlying interrupt vector support.
35 * Unfortunately it is a little different on each ColdFire.
36 */
37void coldfire_profile_init(void);
38
39#if defined(CONFIG_M53xx) || defined(CONFIG_M5441x)
40#define __raw_readtrr __raw_readl
41#define __raw_writetrr __raw_writel
42#else
43#define __raw_readtrr __raw_readw
44#define __raw_writetrr __raw_writew
45#endif
46
47static u32 mcftmr_cycles_per_jiffy;
48static u32 mcftmr_cnt;
49
50static irq_handler_t timer_interrupt;
51
52/***************************************************************************/
53
54static void init_timer_irq(void)
55{
56#ifdef MCFSIM_ICR_AUTOVEC
57 /* Timer1 is always used as system timer */
58 writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
59 MCFSIM_TIMER1ICR);
60 mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
61
62#ifdef CONFIG_HIGHPROFILE
63 /* Timer2 is to be used as a high speed profile timer */
64 writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
65 MCFSIM_TIMER2ICR);
66 mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
67#endif
68#endif /* MCFSIM_ICR_AUTOVEC */
69}
70
71/***************************************************************************/
72
73static irqreturn_t mcftmr_tick(int irq, void *dummy)
74{
75 /* Reset the ColdFire timer */
76 __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
77
78 mcftmr_cnt += mcftmr_cycles_per_jiffy;
79 return timer_interrupt(irq, dummy);
80}
81
82/***************************************************************************/
83
84static struct irqaction mcftmr_timer_irq = {
85 .name = "timer",
86 .flags = IRQF_TIMER,
87 .handler = mcftmr_tick,
88};
89
90/***************************************************************************/
91
92static cycle_t mcftmr_read_clk(struct clocksource *cs)
93{
94 unsigned long flags;
95 u32 cycles;
96 u16 tcn;
97
98 local_irq_save(flags);
99 tcn = __raw_readw(TA(MCFTIMER_TCN));
100 cycles = mcftmr_cnt;
101 local_irq_restore(flags);
102
103 return cycles + tcn;
104}
105
106/***************************************************************************/
107
108static struct clocksource mcftmr_clk = {
109 .name = "tmr",
110 .rating = 250,
111 .read = mcftmr_read_clk,
112 .mask = CLOCKSOURCE_MASK(32),
113 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
114};
115
116/***************************************************************************/
117
118void hw_timer_init(irq_handler_t handler)
119{
120 __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
121 mcftmr_cycles_per_jiffy = FREQ / HZ;
122 /*
123 * The coldfire timer runs from 0 to TRR included, then 0
124 * again and so on. It counts thus actually TRR + 1 steps
125 * for 1 tick, not TRR. So if you want n cycles,
126 * initialize TRR with n - 1.
127 */
128 __raw_writetrr(mcftmr_cycles_per_jiffy - 1, TA(MCFTIMER_TRR));
129 __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
130 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR));
131
132 clocksource_register_hz(&mcftmr_clk, FREQ);
133
134 timer_interrupt = handler;
135 init_timer_irq();
136 setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq);
137
138#ifdef CONFIG_HIGHPROFILE
139 coldfire_profile_init();
140#endif
141}
142
143/***************************************************************************/
144#ifdef CONFIG_HIGHPROFILE
145/***************************************************************************/
146
147/*
148 * By default use timer2 as the profiler clock timer.
149 */
150#define PA(a) (MCFTIMER_BASE2 + (a))
151
152/*
153 * Choose a reasonably fast profile timer. Make it an odd value to
154 * try and get good coverage of kernel operations.
155 */
156#define PROFILEHZ 1013
157
158/*
159 * Use the other timer to provide high accuracy profiling info.
160 */
161irqreturn_t coldfire_profile_tick(int irq, void *dummy)
162{
163 /* Reset ColdFire timer2 */
164 __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER));
165 if (current->pid)
166 profile_tick(CPU_PROFILING);
167 return IRQ_HANDLED;
168}
169
170/***************************************************************************/
171
172static struct irqaction coldfire_profile_irq = {
173 .name = "profile timer",
174 .flags = IRQF_TIMER,
175 .handler = coldfire_profile_tick,
176};
177
178void coldfire_profile_init(void)
179{
180 printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n",
181 PROFILEHZ);
182
183 /* Set up TIMER 2 as high speed profile clock */
184 __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
185
186 __raw_writetrr(((MCF_BUSCLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
187 __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
188 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
189
190 setup_irq(MCF_IRQ_PROFILER, &coldfire_profile_irq);
191}
192
193/***************************************************************************/
194#endif /* CONFIG_HIGHPROFILE */
195/***************************************************************************/
diff --git a/arch/m68k/coldfire/vectors.c b/arch/m68k/coldfire/vectors.c
new file mode 100644
index 000000000000..a4dbdecbec7a
--- /dev/null
+++ b/arch/m68k/coldfire/vectors.c
@@ -0,0 +1,70 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/coldfire/vectors.c
5 *
6 * Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com>
7 */
8
9/***************************************************************************/
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/irq.h>
14#include <asm/traps.h>
15#include <asm/machdep.h>
16#include <asm/coldfire.h>
17#include <asm/mcfsim.h>
18#include <asm/mcfwdebug.h>
19
20/***************************************************************************/
21
22#ifdef TRAP_DBG_INTERRUPT
23
24asmlinkage void dbginterrupt_c(struct frame *fp)
25{
26 extern void dump(struct pt_regs *fp);
27 printk(KERN_DEBUG "%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
28 dump((struct pt_regs *) fp);
29 asm("halt");
30}
31
32#endif
33
34/***************************************************************************/
35
36/* Assembler routines */
37asmlinkage void buserr(void);
38asmlinkage void trap(void);
39asmlinkage void system_call(void);
40asmlinkage void inthandler(void);
41
42void __init trap_init(void)
43{
44 int i;
45
46 /*
47 * There is a common trap handler and common interrupt
48 * handler that handle almost every vector. We treat
49 * the system call and bus error special, they get their
50 * own first level handlers.
51 */
52 for (i = 3; (i <= 23); i++)
53 _ramvec[i] = trap;
54 for (i = 33; (i <= 63); i++)
55 _ramvec[i] = trap;
56 for (i = 24; (i <= 31); i++)
57 _ramvec[i] = inthandler;
58 for (i = 64; (i < 255); i++)
59 _ramvec[i] = inthandler;
60 _ramvec[255] = 0;
61
62 _ramvec[2] = buserr;
63 _ramvec[32] = system_call;
64
65#ifdef TRAP_DBG_INTERRUPT
66 _ramvec[12] = dbginterrupt;
67#endif
68}
69
70/***************************************************************************/