]>
Commit | Line | Data |
---|---|---|
8159df72 | 1 | /* |
93e2b95c | 2 | * Copyright 2008-2011 DENX Software Engineering GmbH |
8159df72 HS |
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> | |
60063497 | 31 | #include <linux/atomic.h> |
8159df72 HS |
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 | */ | |
93e2b95c | 52 | static void __init mpc83xx_km_setup_arch(void) |
8159df72 HS |
53 | { |
54 | struct device_node *np; | |
55 | ||
56 | if (ppc_md.progress) | |
93e2b95c | 57 | ppc_md.progress("kmpbec83xx_setup_arch()", 0); |
8159df72 HS |
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 | ||
93e2b95c HB |
72 | for_each_node_by_name(np, "spi") |
73 | par_io_of_config(np); | |
74 | ||
8159df72 HS |
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 | } | |
28f65c11 | 104 | base = ioremap(res.start, resource_size(&res)); |
8159df72 HS |
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 | ||
93e2b95c | 125 | static struct of_device_id kmpbec83xx_ids[] = { |
8159df72 HS |
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 */ | |
93e2b95c | 137 | of_platform_bus_probe(NULL, kmpbec83xx_ids, NULL); |
8159df72 HS |
138 | |
139 | return 0; | |
140 | } | |
93e2b95c | 141 | machine_device_initcall(mpc83xx_km, kmeter_declare_of_platform_devices); |
8159df72 | 142 | |
93e2b95c | 143 | static void __init mpc83xx_km_init_IRQ(void) |
8159df72 HS |
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 | ||
93e2b95c HB |
174 | /* list of the supported boards */ |
175 | static char *board[] __initdata = { | |
176 | "Keymile,KMETER1", | |
177 | "Keymile,kmpbec8321", | |
178 | NULL | |
179 | }; | |
180 | ||
8159df72 HS |
181 | /* |
182 | * Called very early, MMU is off, device-tree isn't unflattened | |
183 | */ | |
93e2b95c | 184 | static int __init mpc83xx_km_probe(void) |
8159df72 | 185 | { |
93e2b95c HB |
186 | unsigned long node = of_get_flat_dt_root(); |
187 | int i = 0; | |
8159df72 | 188 | |
93e2b95c HB |
189 | while (board[i]) { |
190 | if (of_flat_dt_is_compatible(node, board[i])) | |
191 | break; | |
192 | i++; | |
193 | } | |
194 | return (board[i] != NULL); | |
8159df72 HS |
195 | } |
196 | ||
93e2b95c HB |
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, | |
8159df72 HS |
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 | }; |