1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (C) 2001 Dave Engebretsen, IBM Corporation |
4 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM |
5 | * |
6 | * RTAS specific routines for PCI. |
7 | * |
8 | * Based on code from pci.c, chrp_pci.c and pSeries_pci.c |
9 | */ |
10 | |
11 | #include <linux/kernel.h> |
12 | #include <linux/threads.h> |
13 | #include <linux/pci.h> |
14 | #include <linux/string.h> |
15 | #include <linux/init.h> |
16 | #include <linux/pgtable.h> |
17 | #include <linux/of_address.h> |
18 | #include <linux/of_fdt.h> |
19 | |
20 | #include <asm/io.h> |
21 | #include <asm/irq.h> |
22 | #include <asm/machdep.h> |
23 | #include <asm/pci-bridge.h> |
24 | #include <asm/iommu.h> |
25 | #include <asm/rtas.h> |
26 | #include <asm/mpic.h> |
27 | #include <asm/ppc-pci.h> |
28 | #include <asm/eeh.h> |
29 | |
30 | /* RTAS tokens */ |
31 | static int read_pci_config; |
32 | static int write_pci_config; |
33 | static int ibm_read_pci_config; |
34 | static int ibm_write_pci_config; |
35 | |
36 | static inline int config_access_valid(struct pci_dn *dn, int where) |
37 | { |
38 | if (where < 256) |
39 | return 1; |
40 | if (where < 4096 && dn->pci_ext_config_space) |
41 | return 1; |
42 | |
43 | return 0; |
44 | } |
45 | |
46 | int rtas_pci_dn_read_config(struct pci_dn *pdn, int where, int size, u32 *val) |
47 | { |
48 | int returnval = -1; |
49 | unsigned long buid, addr; |
50 | int ret; |
51 | |
52 | if (!pdn) |
53 | return PCIBIOS_DEVICE_NOT_FOUND; |
54 | if (!config_access_valid(dn: pdn, where)) |
55 | return PCIBIOS_BAD_REGISTER_NUMBER; |
56 | #ifdef CONFIG_EEH |
57 | if (pdn->edev && pdn->edev->pe && |
58 | (pdn->edev->pe->state & EEH_PE_CFG_BLOCKED)) |
59 | return PCIBIOS_SET_FAILED; |
60 | #endif |
61 | |
62 | addr = rtas_config_addr(pdn->busno, pdn->devfn, where); |
63 | buid = pdn->phb->buid; |
64 | if (buid) { |
65 | ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, |
66 | addr, BUID_HI(buid), BUID_LO(buid), size); |
67 | } else { |
68 | ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size); |
69 | } |
70 | *val = returnval; |
71 | |
72 | if (ret) |
73 | return PCIBIOS_DEVICE_NOT_FOUND; |
74 | |
75 | return PCIBIOS_SUCCESSFUL; |
76 | } |
77 | |
78 | static int rtas_pci_read_config(struct pci_bus *bus, |
79 | unsigned int devfn, |
80 | int where, int size, u32 *val) |
81 | { |
82 | struct pci_dn *pdn; |
83 | int ret; |
84 | |
85 | *val = 0xFFFFFFFF; |
86 | |
87 | pdn = pci_get_pdn_by_devfn(bus, devfn); |
88 | |
89 | /* Validity of pdn is checked in here */ |
90 | ret = rtas_pci_dn_read_config(pdn, where, size, val); |
91 | if (*val == EEH_IO_ERROR_VALUE(size) && |
92 | eeh_dev_check_failure(pdn_to_eeh_dev(pdn))) |
93 | return PCIBIOS_DEVICE_NOT_FOUND; |
94 | |
95 | return ret; |
96 | } |
97 | |
98 | int rtas_pci_dn_write_config(struct pci_dn *pdn, int where, int size, u32 val) |
99 | { |
100 | unsigned long buid, addr; |
101 | int ret; |
102 | |
103 | if (!pdn) |
104 | return PCIBIOS_DEVICE_NOT_FOUND; |
105 | if (!config_access_valid(dn: pdn, where)) |
106 | return PCIBIOS_BAD_REGISTER_NUMBER; |
107 | #ifdef CONFIG_EEH |
108 | if (pdn->edev && pdn->edev->pe && |
109 | (pdn->edev->pe->state & EEH_PE_CFG_BLOCKED)) |
110 | return PCIBIOS_SET_FAILED; |
111 | #endif |
112 | |
113 | addr = rtas_config_addr(pdn->busno, pdn->devfn, where); |
114 | buid = pdn->phb->buid; |
115 | if (buid) { |
116 | ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, |
117 | BUID_HI(buid), BUID_LO(buid), size, (ulong) val); |
118 | } else { |
119 | ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val); |
120 | } |
121 | |
122 | if (ret) |
123 | return PCIBIOS_DEVICE_NOT_FOUND; |
124 | |
125 | return PCIBIOS_SUCCESSFUL; |
126 | } |
127 | |
128 | static int rtas_pci_write_config(struct pci_bus *bus, |
129 | unsigned int devfn, |
130 | int where, int size, u32 val) |
131 | { |
132 | struct pci_dn *pdn; |
133 | |
134 | pdn = pci_get_pdn_by_devfn(bus, devfn); |
135 | |
136 | /* Validity of pdn is checked in here. */ |
137 | return rtas_pci_dn_write_config(pdn, where, size, val); |
138 | } |
139 | |
140 | static struct pci_ops rtas_pci_ops = { |
141 | .read = rtas_pci_read_config, |
142 | .write = rtas_pci_write_config, |
143 | }; |
144 | |
145 | static int is_python(struct device_node *dev) |
146 | { |
147 | const char *model = of_get_property(node: dev, name: "model" , NULL); |
148 | |
149 | if (model && strstr(model, "Python" )) |
150 | return 1; |
151 | |
152 | return 0; |
153 | } |
154 | |
155 | static void python_countermeasures(struct device_node *dev) |
156 | { |
157 | struct resource registers; |
158 | void __iomem *chip_regs; |
159 | volatile u32 val; |
160 | |
161 | if (of_address_to_resource(dev, index: 0, r: ®isters)) { |
162 | printk(KERN_ERR "Can't get address for Python workarounds !\n" ); |
163 | return; |
164 | } |
165 | |
166 | /* Python's register file is 1 MB in size. */ |
167 | chip_regs = ioremap(offset: registers.start & ~(0xfffffUL), size: 0x100000); |
168 | |
169 | /* |
170 | * Firmware doesn't always clear this bit which is critical |
171 | * for good performance - Anton |
172 | */ |
173 | |
174 | #define PRG_CL_RESET_VALID 0x00010000 |
175 | |
176 | val = in_be32(chip_regs + 0xf6030); |
177 | if (val & PRG_CL_RESET_VALID) { |
178 | printk(KERN_INFO "Python workaround: " ); |
179 | val &= ~PRG_CL_RESET_VALID; |
180 | out_be32(chip_regs + 0xf6030, val); |
181 | /* |
182 | * We must read it back for changes to |
183 | * take effect |
184 | */ |
185 | val = in_be32(chip_regs + 0xf6030); |
186 | printk("reg0: %x\n" , val); |
187 | } |
188 | |
189 | iounmap(addr: chip_regs); |
190 | } |
191 | |
192 | void __init init_pci_config_tokens(void) |
193 | { |
194 | read_pci_config = rtas_function_token(RTAS_FN_READ_PCI_CONFIG); |
195 | write_pci_config = rtas_function_token(RTAS_FN_WRITE_PCI_CONFIG); |
196 | ibm_read_pci_config = rtas_function_token(RTAS_FN_IBM_READ_PCI_CONFIG); |
197 | ibm_write_pci_config = rtas_function_token(RTAS_FN_IBM_WRITE_PCI_CONFIG); |
198 | } |
199 | |
200 | unsigned long get_phb_buid(struct device_node *phb) |
201 | { |
202 | struct resource r; |
203 | |
204 | if (ibm_read_pci_config == -1) |
205 | return 0; |
206 | if (of_address_to_resource(dev: phb, index: 0, r: &r)) |
207 | return 0; |
208 | return r.start; |
209 | } |
210 | |
211 | static int phb_set_bus_ranges(struct device_node *dev, |
212 | struct pci_controller *phb) |
213 | { |
214 | const __be32 *bus_range; |
215 | unsigned int len; |
216 | |
217 | bus_range = of_get_property(node: dev, name: "bus-range" , lenp: &len); |
218 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
219 | return 1; |
220 | } |
221 | |
222 | phb->first_busno = be32_to_cpu(bus_range[0]); |
223 | phb->last_busno = be32_to_cpu(bus_range[1]); |
224 | |
225 | return 0; |
226 | } |
227 | |
228 | int rtas_setup_phb(struct pci_controller *phb) |
229 | { |
230 | struct device_node *dev = phb->dn; |
231 | |
232 | if (is_python(dev)) |
233 | python_countermeasures(dev); |
234 | |
235 | if (phb_set_bus_ranges(dev, phb)) |
236 | return 1; |
237 | |
238 | phb->ops = &rtas_pci_ops; |
239 | phb->buid = get_phb_buid(phb: dev); |
240 | |
241 | return 0; |
242 | } |
243 | |