Commit | Line | Data |
---|---|---|
9724b86f SM |
1 | /* |
2 | * Efika 5K2 platform code | |
3 | * Some code really inspired from the lite5200b platform. | |
4 | * | |
5 | * Copyright (C) 2006 bplan GmbH | |
6 | * | |
7 | * This file is licensed under the terms of the GNU General Public License | |
8 | * version 2. This program is licensed "as is" without any warranty of any | |
9 | * kind, whether express or implied. | |
10 | */ | |
11 | ||
12 | #include <linux/errno.h> | |
13 | #include <linux/kernel.h> | |
14 | #include <linux/slab.h> | |
15 | #include <linux/reboot.h> | |
16 | #include <linux/init.h> | |
17 | #include <linux/utsrelease.h> | |
18 | #include <linux/seq_file.h> | |
19 | #include <linux/string.h> | |
20 | #include <linux/root_dev.h> | |
21 | #include <linux/initrd.h> | |
22 | #include <linux/timer.h> | |
23 | #include <linux/pci.h> | |
9414715a | 24 | #include <linux/console.h> |
9724b86f SM |
25 | |
26 | #include <asm/io.h> | |
27 | #include <asm/irq.h> | |
28 | #include <asm/sections.h> | |
29 | #include <asm/pci-bridge.h> | |
30 | #include <asm/pgtable.h> | |
31 | #include <asm/prom.h> | |
32 | #include <asm/time.h> | |
33 | #include <asm/machdep.h> | |
34 | #include <asm/rtas.h> | |
35 | #include <asm/of_device.h> | |
36 | #include <asm/of_platform.h> | |
37 | #include <asm/mpc52xx.h> | |
38 | ||
39 | ||
40 | #define EFIKA_PLATFORM_NAME "Efika" | |
41 | ||
42 | ||
43 | /* ------------------------------------------------------------------------ */ | |
44 | /* PCI accesses thru RTAS */ | |
45 | /* ------------------------------------------------------------------------ */ | |
46 | ||
47 | #ifdef CONFIG_PCI | |
48 | ||
49 | /* | |
50 | * Access functions for PCI config space using RTAS calls. | |
51 | */ | |
52 | static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | |
53 | int len, u32 * val) | |
54 | { | |
55 | struct pci_controller *hose = bus->sysdata; | |
56 | unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) | |
57 | | (((bus->number - hose->first_busno) & 0xff) << 16) | |
58 | | (hose->index << 24); | |
59 | int ret = -1; | |
60 | int rval; | |
61 | ||
62 | rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len); | |
63 | *val = ret; | |
64 | return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | |
65 | } | |
66 | ||
67 | static int rtas_write_config(struct pci_bus *bus, unsigned int devfn, | |
68 | int offset, int len, u32 val) | |
69 | { | |
70 | struct pci_controller *hose = bus->sysdata; | |
71 | unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) | |
72 | | (((bus->number - hose->first_busno) & 0xff) << 16) | |
73 | | (hose->index << 24); | |
74 | int rval; | |
75 | ||
76 | rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, | |
77 | addr, len, val); | |
78 | return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | |
79 | } | |
80 | ||
81 | static struct pci_ops rtas_pci_ops = { | |
82 | rtas_read_config, | |
83 | rtas_write_config | |
84 | }; | |
85 | ||
86 | ||
87 | void __init efika_pcisetup(void) | |
88 | { | |
89 | const int *bus_range; | |
90 | int len; | |
91 | struct pci_controller *hose; | |
92 | struct device_node *root; | |
93 | struct device_node *pcictrl; | |
94 | ||
95 | root = of_find_node_by_path("/"); | |
96 | if (root == NULL) { | |
97 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | |
98 | ": Unable to find the root node\n"); | |
99 | return; | |
100 | } | |
101 | ||
102 | for (pcictrl = NULL;;) { | |
103 | pcictrl = of_get_next_child(root, pcictrl); | |
104 | if ((pcictrl == NULL) || (strcmp(pcictrl->name, "pci") == 0)) | |
105 | break; | |
106 | } | |
107 | ||
108 | of_node_put(root); | |
109 | ||
110 | if (pcictrl == NULL) { | |
111 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | |
112 | ": Unable to find the PCI bridge node\n"); | |
113 | return; | |
114 | } | |
115 | ||
e2eb6392 | 116 | bus_range = of_get_property(pcictrl, "bus-range", &len); |
9724b86f SM |
117 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
118 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | |
119 | ": Can't get bus-range for %s\n", pcictrl->full_name); | |
120 | return; | |
121 | } | |
122 | ||
123 | if (bus_range[1] == bus_range[0]) | |
124 | printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d", | |
125 | bus_range[0]); | |
126 | else | |
127 | printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d", | |
128 | bus_range[0], bus_range[1]); | |
129 | printk(" controlled by %s\n", pcictrl->full_name); | |
130 | printk("\n"); | |
131 | ||
132 | hose = pcibios_alloc_controller(); | |
133 | if (!hose) { | |
134 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | |
135 | ": Can't allocate PCI controller structure for %s\n", | |
136 | pcictrl->full_name); | |
137 | return; | |
138 | } | |
139 | ||
140 | hose->arch_data = of_node_get(pcictrl); | |
141 | hose->first_busno = bus_range[0]; | |
142 | hose->last_busno = bus_range[1]; | |
143 | hose->ops = &rtas_pci_ops; | |
144 | ||
145 | pci_process_bridge_OF_ranges(hose, pcictrl, 0); | |
146 | } | |
147 | ||
148 | #else | |
149 | void __init efika_pcisetup(void) | |
150 | {} | |
151 | #endif | |
152 | ||
153 | ||
154 | ||
155 | /* ------------------------------------------------------------------------ */ | |
156 | /* Platform setup */ | |
157 | /* ------------------------------------------------------------------------ */ | |
158 | ||
159 | static void efika_show_cpuinfo(struct seq_file *m) | |
160 | { | |
161 | struct device_node *root; | |
e2eb6392 SR |
162 | const char *revision; |
163 | const char *codegendescription; | |
164 | const char *codegenvendor; | |
9724b86f SM |
165 | |
166 | root = of_find_node_by_path("/"); | |
167 | if (!root) | |
168 | return; | |
169 | ||
e2eb6392 SR |
170 | revision = of_get_property(root, "revision", NULL); |
171 | codegendescription = of_get_property(root, "CODEGEN,description", NULL); | |
172 | codegenvendor = of_get_property(root, "CODEGEN,vendor", NULL); | |
9724b86f SM |
173 | |
174 | if (codegendescription) | |
175 | seq_printf(m, "machine\t\t: %s\n", codegendescription); | |
176 | else | |
177 | seq_printf(m, "machine\t\t: Efika\n"); | |
178 | ||
179 | if (revision) | |
180 | seq_printf(m, "revision\t: %s\n", revision); | |
181 | ||
182 | if (codegenvendor) | |
183 | seq_printf(m, "vendor\t\t: %s\n", codegenvendor); | |
184 | ||
185 | of_node_put(root); | |
186 | } | |
187 | ||
188 | static void __init efika_setup_arch(void) | |
189 | { | |
190 | rtas_initialize(); | |
191 | ||
192 | #ifdef CONFIG_BLK_DEV_INITRD | |
193 | initrd_below_start_ok = 1; | |
194 | ||
195 | if (initrd_start) | |
196 | ROOT_DEV = Root_RAM0; | |
197 | else | |
198 | #endif | |
199 | ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */ | |
200 | ||
201 | efika_pcisetup(); | |
202 | ||
203 | if (ppc_md.progress) | |
204 | ppc_md.progress("Linux/PPC " UTS_RELEASE " running on Efika ;-)\n", 0x0); | |
205 | } | |
206 | ||
207 | static int __init efika_probe(void) | |
208 | { | |
209 | char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), | |
210 | "model", NULL); | |
211 | ||
212 | if (model == NULL) | |
213 | return 0; | |
214 | if (strcmp(model, "EFIKA5K2")) | |
215 | return 0; | |
216 | ||
217 | ISA_DMA_THRESHOLD = ~0L; | |
218 | DMA_MODE_READ = 0x44; | |
219 | DMA_MODE_WRITE = 0x48; | |
220 | ||
221 | return 1; | |
222 | } | |
223 | ||
9414715a OH |
224 | static void __init efika_init_early(void) |
225 | { | |
226 | #ifdef CONFIG_SERIAL_MPC52xx | |
227 | struct device_node *stdout_node; | |
228 | const char *device_type; | |
229 | ||
230 | if (strstr(cmd_line, "console=")) | |
231 | return; | |
232 | /* find the boot console from /chosen/stdout */ | |
233 | if (!of_chosen) | |
234 | return; | |
235 | device_type = get_property(of_chosen, "linux,stdout-path", NULL); | |
236 | if (!device_type) | |
237 | return; | |
238 | stdout_node = of_find_node_by_path(device_type); | |
239 | if (stdout_node) { | |
240 | device_type = get_property(stdout_node, "device_type", NULL); | |
241 | if (device_type && strcmp(device_type, "serial") == 0) | |
242 | add_preferred_console("ttyPSC", 0, NULL); | |
243 | of_node_put(stdout_node); | |
244 | } | |
245 | #endif | |
246 | } | |
247 | ||
9724b86f SM |
248 | define_machine(efika) |
249 | { | |
250 | .name = EFIKA_PLATFORM_NAME, | |
251 | .probe = efika_probe, | |
252 | .setup_arch = efika_setup_arch, | |
253 | .init = mpc52xx_declare_of_platform_devices, | |
9414715a | 254 | .init_early = efika_init_early, |
9724b86f SM |
255 | .show_cpuinfo = efika_show_cpuinfo, |
256 | .init_IRQ = mpc52xx_init_irq, | |
257 | .get_irq = mpc52xx_get_irq, | |
258 | .restart = rtas_restart, | |
259 | .power_off = rtas_power_off, | |
260 | .halt = rtas_halt, | |
261 | .set_rtc_time = rtas_set_rtc_time, | |
262 | .get_rtc_time = rtas_get_rtc_time, | |
263 | .progress = rtas_progress, | |
264 | .get_boot_time = rtas_get_boot_time, | |
265 | .calibrate_decr = generic_calibrate_decr, | |
266 | .phys_mem_access_prot = pci_phys_mem_access_prot, | |
267 | }; | |
268 |