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 | ||
9724b86f | 12 | #include <linux/init.h> |
273b281f | 13 | #include <generated/utsrelease.h> |
9724b86f | 14 | #include <linux/pci.h> |
9fe2e796 | 15 | #include <linux/of.h> |
308c09f1 | 16 | #include <asm/dma.h> |
9724b86f SM |
17 | #include <asm/prom.h> |
18 | #include <asm/time.h> | |
19 | #include <asm/machdep.h> | |
20 | #include <asm/rtas.h> | |
9724b86f SM |
21 | #include <asm/mpc52xx.h> |
22 | ||
9724b86f SM |
23 | #define EFIKA_PLATFORM_NAME "Efika" |
24 | ||
25 | ||
26 | /* ------------------------------------------------------------------------ */ | |
27 | /* PCI accesses thru RTAS */ | |
28 | /* ------------------------------------------------------------------------ */ | |
29 | ||
30 | #ifdef CONFIG_PCI | |
31 | ||
32 | /* | |
33 | * Access functions for PCI config space using RTAS calls. | |
34 | */ | |
35 | static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | |
36 | int len, u32 * val) | |
37 | { | |
5b21fb8e | 38 | struct pci_controller *hose = pci_bus_to_host(bus); |
9724b86f SM |
39 | unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) |
40 | | (((bus->number - hose->first_busno) & 0xff) << 16) | |
5516b540 | 41 | | (hose->global_number << 24); |
9724b86f SM |
42 | int ret = -1; |
43 | int rval; | |
44 | ||
45 | rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len); | |
46 | *val = ret; | |
47 | return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | |
48 | } | |
49 | ||
50 | static int rtas_write_config(struct pci_bus *bus, unsigned int devfn, | |
51 | int offset, int len, u32 val) | |
52 | { | |
5b21fb8e | 53 | struct pci_controller *hose = pci_bus_to_host(bus); |
9724b86f SM |
54 | unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) |
55 | | (((bus->number - hose->first_busno) & 0xff) << 16) | |
5516b540 | 56 | | (hose->global_number << 24); |
9724b86f SM |
57 | int rval; |
58 | ||
59 | rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, | |
60 | addr, len, val); | |
61 | return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | |
62 | } | |
63 | ||
64 | static struct pci_ops rtas_pci_ops = { | |
21d8f6c7 NL |
65 | .read = rtas_read_config, |
66 | .write = rtas_write_config, | |
9724b86f SM |
67 | }; |
68 | ||
69 | ||
d3e0e028 | 70 | static void __init efika_pcisetup(void) |
9724b86f SM |
71 | { |
72 | const int *bus_range; | |
73 | int len; | |
74 | struct pci_controller *hose; | |
75 | struct device_node *root; | |
76 | struct device_node *pcictrl; | |
77 | ||
78 | root = of_find_node_by_path("/"); | |
79 | if (root == NULL) { | |
80 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | |
81 | ": Unable to find the root node\n"); | |
82 | return; | |
83 | } | |
84 | ||
85 | for (pcictrl = NULL;;) { | |
86 | pcictrl = of_get_next_child(root, pcictrl); | |
87 | if ((pcictrl == NULL) || (strcmp(pcictrl->name, "pci") == 0)) | |
88 | break; | |
89 | } | |
90 | ||
91 | of_node_put(root); | |
92 | ||
93 | if (pcictrl == NULL) { | |
94 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | |
95 | ": Unable to find the PCI bridge node\n"); | |
96 | return; | |
97 | } | |
98 | ||
e2eb6392 | 99 | bus_range = of_get_property(pcictrl, "bus-range", &len); |
9724b86f SM |
100 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
101 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | |
102 | ": Can't get bus-range for %s\n", pcictrl->full_name); | |
915b9619 | 103 | goto out_put; |
9724b86f SM |
104 | } |
105 | ||
106 | if (bus_range[1] == bus_range[0]) | |
107 | printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d", | |
108 | bus_range[0]); | |
109 | else | |
110 | printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d", | |
111 | bus_range[0], bus_range[1]); | |
112 | printk(" controlled by %s\n", pcictrl->full_name); | |
113 | printk("\n"); | |
114 | ||
915b9619 | 115 | hose = pcibios_alloc_controller(pcictrl); |
9724b86f SM |
116 | if (!hose) { |
117 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | |
118 | ": Can't allocate PCI controller structure for %s\n", | |
119 | pcictrl->full_name); | |
915b9619 | 120 | goto out_put; |
9724b86f SM |
121 | } |
122 | ||
9724b86f SM |
123 | hose->first_busno = bus_range[0]; |
124 | hose->last_busno = bus_range[1]; | |
125 | hose->ops = &rtas_pci_ops; | |
126 | ||
127 | pci_process_bridge_OF_ranges(hose, pcictrl, 0); | |
915b9619 JL |
128 | return; |
129 | out_put: | |
130 | of_node_put(pcictrl); | |
9724b86f SM |
131 | } |
132 | ||
133 | #else | |
d3e0e028 | 134 | static void __init efika_pcisetup(void) |
9724b86f SM |
135 | {} |
136 | #endif | |
137 | ||
138 | ||
139 | ||
140 | /* ------------------------------------------------------------------------ */ | |
141 | /* Platform setup */ | |
142 | /* ------------------------------------------------------------------------ */ | |
143 | ||
144 | static void efika_show_cpuinfo(struct seq_file *m) | |
145 | { | |
146 | struct device_node *root; | |
e2eb6392 SR |
147 | const char *revision; |
148 | const char *codegendescription; | |
149 | const char *codegenvendor; | |
9724b86f SM |
150 | |
151 | root = of_find_node_by_path("/"); | |
152 | if (!root) | |
153 | return; | |
154 | ||
e2eb6392 SR |
155 | revision = of_get_property(root, "revision", NULL); |
156 | codegendescription = of_get_property(root, "CODEGEN,description", NULL); | |
157 | codegenvendor = of_get_property(root, "CODEGEN,vendor", NULL); | |
9724b86f SM |
158 | |
159 | if (codegendescription) | |
160 | seq_printf(m, "machine\t\t: %s\n", codegendescription); | |
161 | else | |
162 | seq_printf(m, "machine\t\t: Efika\n"); | |
163 | ||
164 | if (revision) | |
165 | seq_printf(m, "revision\t: %s\n", revision); | |
166 | ||
167 | if (codegenvendor) | |
168 | seq_printf(m, "vendor\t\t: %s\n", codegenvendor); | |
169 | ||
170 | of_node_put(root); | |
171 | } | |
172 | ||
2e1ee1f7 DP |
173 | #ifdef CONFIG_PM |
174 | static void efika_suspend_prepare(void __iomem *mbar) | |
175 | { | |
176 | u8 pin = 4; /* GPIO_WKUP_4 (GPIO_PSC6_0 - IRDA_RX) */ | |
177 | u8 level = 1; /* wakeup on high level */ | |
178 | /* IOW. to wake it up, short pins 1 and 3 on IRDA connector */ | |
179 | mpc52xx_set_wakeup_gpio(pin, level); | |
180 | } | |
181 | #endif | |
182 | ||
9724b86f SM |
183 | static void __init efika_setup_arch(void) |
184 | { | |
185 | rtas_initialize(); | |
186 | ||
c8004a28 GL |
187 | /* Map important registers from the internal memory map */ |
188 | mpc52xx_map_common_devices(); | |
189 | ||
9724b86f SM |
190 | efika_pcisetup(); |
191 | ||
2e1ee1f7 DP |
192 | #ifdef CONFIG_PM |
193 | mpc52xx_suspend.board_suspend_prepare = efika_suspend_prepare; | |
194 | mpc52xx_pm_init(); | |
195 | #endif | |
196 | ||
9724b86f SM |
197 | if (ppc_md.progress) |
198 | ppc_md.progress("Linux/PPC " UTS_RELEASE " running on Efika ;-)\n", 0x0); | |
199 | } | |
200 | ||
201 | static int __init efika_probe(void) | |
202 | { | |
9d0c4dfe RH |
203 | const char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), |
204 | "model", NULL); | |
9724b86f SM |
205 | |
206 | if (model == NULL) | |
207 | return 0; | |
208 | if (strcmp(model, "EFIKA5K2")) | |
209 | return 0; | |
210 | ||
211 | ISA_DMA_THRESHOLD = ~0L; | |
212 | DMA_MODE_READ = 0x44; | |
213 | DMA_MODE_WRITE = 0x48; | |
214 | ||
9178ba29 AG |
215 | pm_power_off = rtas_power_off; |
216 | ||
9724b86f SM |
217 | return 1; |
218 | } | |
219 | ||
220 | define_machine(efika) | |
221 | { | |
222 | .name = EFIKA_PLATFORM_NAME, | |
223 | .probe = efika_probe, | |
224 | .setup_arch = efika_setup_arch, | |
225 | .init = mpc52xx_declare_of_platform_devices, | |
226 | .show_cpuinfo = efika_show_cpuinfo, | |
227 | .init_IRQ = mpc52xx_init_irq, | |
228 | .get_irq = mpc52xx_get_irq, | |
229 | .restart = rtas_restart, | |
9724b86f SM |
230 | .halt = rtas_halt, |
231 | .set_rtc_time = rtas_set_rtc_time, | |
232 | .get_rtc_time = rtas_get_rtc_time, | |
233 | .progress = rtas_progress, | |
234 | .get_boot_time = rtas_get_boot_time, | |
235 | .calibrate_decr = generic_calibrate_decr, | |
d6658408 | 236 | #ifdef CONFIG_PCI |
9724b86f | 237 | .phys_mem_access_prot = pci_phys_mem_access_prot, |
d6658408 | 238 | #endif |
9724b86f SM |
239 | }; |
240 |