diff options
Diffstat (limited to 'arch/powerpc/platforms/83xx/km83xx.c')
-rw-r--r-- | arch/powerpc/platforms/83xx/km83xx.c | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c new file mode 100644 index 00000000000..a2b9b9ef124 --- /dev/null +++ b/arch/powerpc/platforms/83xx/km83xx.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2011 DENX Software Engineering GmbH | ||
3 | * Author: Heiko Schocher <hs@denx.de> | ||
4 | * | ||
5 | * Description: | ||
6 | * Keymile KMETER1 board specific routines. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/stddef.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/reboot.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/kdev_t.h> | ||
21 | #include <linux/major.h> | ||
22 | #include <linux/console.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/seq_file.h> | ||
25 | #include <linux/root_dev.h> | ||
26 | #include <linux/initrd.h> | ||
27 | #include <linux/of_platform.h> | ||
28 | #include <linux/of_device.h> | ||
29 | |||
30 | #include <asm/system.h> | ||
31 | #include <asm/atomic.h> | ||
32 | #include <asm/time.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/machdep.h> | ||
35 | #include <asm/ipic.h> | ||
36 | #include <asm/irq.h> | ||
37 | #include <asm/prom.h> | ||
38 | #include <asm/udbg.h> | ||
39 | #include <sysdev/fsl_soc.h> | ||
40 | #include <sysdev/fsl_pci.h> | ||
41 | #include <asm/qe.h> | ||
42 | #include <asm/qe_ic.h> | ||
43 | |||
44 | #include "mpc83xx.h" | ||
45 | |||
46 | #define SVR_REV(svr) (((svr) >> 0) & 0xFFFF) /* Revision field */ | ||
47 | /* ************************************************************************ | ||
48 | * | ||
49 | * Setup the architecture | ||
50 | * | ||
51 | */ | ||
52 | static void __init mpc83xx_km_setup_arch(void) | ||
53 | { | ||
54 | struct device_node *np; | ||
55 | |||
56 | if (ppc_md.progress) | ||
57 | ppc_md.progress("kmpbec83xx_setup_arch()", 0); | ||
58 | |||
59 | #ifdef CONFIG_PCI | ||
60 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
61 | mpc83xx_add_bridge(np); | ||
62 | #endif | ||
63 | |||
64 | #ifdef CONFIG_QUICC_ENGINE | ||
65 | qe_reset(); | ||
66 | |||
67 | np = of_find_node_by_name(NULL, "par_io"); | ||
68 | if (np != NULL) { | ||
69 | par_io_init(np); | ||
70 | of_node_put(np); | ||
71 | |||
72 | for_each_node_by_name(np, "spi") | ||
73 | par_io_of_config(np); | ||
74 | |||
75 | for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;) | ||
76 | par_io_of_config(np); | ||
77 | } | ||
78 | |||
79 | np = of_find_compatible_node(NULL, "network", "ucc_geth"); | ||
80 | if (np != NULL) { | ||
81 | uint svid; | ||
82 | |||
83 | /* handle mpc8360ea rev.2.1 erratum 2: RGMII Timing */ | ||
84 | svid = mfspr(SPRN_SVR); | ||
85 | if (SVR_REV(svid) == 0x0021) { | ||
86 | struct device_node *np_par; | ||
87 | struct resource res; | ||
88 | void __iomem *base; | ||
89 | int ret; | ||
90 | |||
91 | np_par = of_find_node_by_name(NULL, "par_io"); | ||
92 | if (np_par == NULL) { | ||
93 | printk(KERN_WARNING "%s couldn;t find par_io node\n", | ||
94 | __func__); | ||
95 | return; | ||
96 | } | ||
97 | /* Map Parallel I/O ports registers */ | ||
98 | ret = of_address_to_resource(np_par, 0, &res); | ||
99 | if (ret) { | ||
100 | printk(KERN_WARNING "%s couldn;t map par_io registers\n", | ||
101 | __func__); | ||
102 | return; | ||
103 | } | ||
104 | base = ioremap(res.start, res.end - res.start + 1); | ||
105 | |||
106 | /* | ||
107 | * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2) | ||
108 | * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1) | ||
109 | */ | ||
110 | setbits32((base + 0xa8), 0x0c003000); | ||
111 | |||
112 | /* | ||
113 | * IMMR + 0x14AC[20:27] = 10101010 | ||
114 | * (data delay for both UCC's) | ||
115 | */ | ||
116 | clrsetbits_be32((base + 0xac), 0xff0, 0xaa0); | ||
117 | iounmap(base); | ||
118 | of_node_put(np_par); | ||
119 | } | ||
120 | of_node_put(np); | ||
121 | } | ||
122 | #endif /* CONFIG_QUICC_ENGINE */ | ||
123 | } | ||
124 | |||
125 | static struct of_device_id kmpbec83xx_ids[] = { | ||
126 | { .type = "soc", }, | ||
127 | { .compatible = "soc", }, | ||
128 | { .compatible = "simple-bus", }, | ||
129 | { .type = "qe", }, | ||
130 | { .compatible = "fsl,qe", }, | ||
131 | {}, | ||
132 | }; | ||
133 | |||
134 | static int __init kmeter_declare_of_platform_devices(void) | ||
135 | { | ||
136 | /* Publish the QE devices */ | ||
137 | of_platform_bus_probe(NULL, kmpbec83xx_ids, NULL); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | machine_device_initcall(mpc83xx_km, kmeter_declare_of_platform_devices); | ||
142 | |||
143 | static void __init mpc83xx_km_init_IRQ(void) | ||
144 | { | ||
145 | struct device_node *np; | ||
146 | |||
147 | np = of_find_compatible_node(NULL, NULL, "fsl,pq2pro-pic"); | ||
148 | if (!np) { | ||
149 | np = of_find_node_by_type(NULL, "ipic"); | ||
150 | if (!np) | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | ipic_init(np, 0); | ||
155 | |||
156 | /* Initialize the default interrupt mapping priorities, | ||
157 | * in case the boot rom changed something on us. | ||
158 | */ | ||
159 | ipic_set_default_priority(); | ||
160 | of_node_put(np); | ||
161 | |||
162 | #ifdef CONFIG_QUICC_ENGINE | ||
163 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
164 | if (!np) { | ||
165 | np = of_find_node_by_type(NULL, "qeic"); | ||
166 | if (!np) | ||
167 | return; | ||
168 | } | ||
169 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
170 | of_node_put(np); | ||
171 | #endif /* CONFIG_QUICC_ENGINE */ | ||
172 | } | ||
173 | |||
174 | /* list of the supported boards */ | ||
175 | static char *board[] __initdata = { | ||
176 | "Keymile,KMETER1", | ||
177 | "Keymile,kmpbec8321", | ||
178 | NULL | ||
179 | }; | ||
180 | |||
181 | /* | ||
182 | * Called very early, MMU is off, device-tree isn't unflattened | ||
183 | */ | ||
184 | static int __init mpc83xx_km_probe(void) | ||
185 | { | ||
186 | unsigned long node = of_get_flat_dt_root(); | ||
187 | int i = 0; | ||
188 | |||
189 | while (board[i]) { | ||
190 | if (of_flat_dt_is_compatible(node, board[i])) | ||
191 | break; | ||
192 | i++; | ||
193 | } | ||
194 | return (board[i] != NULL); | ||
195 | } | ||
196 | |||
197 | define_machine(mpc83xx_km) { | ||
198 | .name = "mpc83xx-km-platform", | ||
199 | .probe = mpc83xx_km_probe, | ||
200 | .setup_arch = mpc83xx_km_setup_arch, | ||
201 | .init_IRQ = mpc83xx_km_init_IRQ, | ||
202 | .get_irq = ipic_get_irq, | ||
203 | .restart = mpc83xx_restart, | ||
204 | .time_init = mpc83xx_time_init, | ||
205 | .calibrate_decr = generic_calibrate_decr, | ||
206 | .progress = udbg_progress, | ||
207 | }; | ||