aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powernv/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/powernv/pci.c')
-rw-r--r--arch/powerpc/platforms/powernv/pci.c139
1 files changed, 103 insertions, 36 deletions
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 277343cc6a3d..a28d3b5e6393 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -20,6 +20,7 @@
20#include <linux/irq.h> 20#include <linux/irq.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/msi.h> 22#include <linux/msi.h>
23#include <linux/iommu.h>
23 24
24#include <asm/sections.h> 25#include <asm/sections.h>
25#include <asm/io.h> 26#include <asm/io.h>
@@ -32,6 +33,8 @@
32#include <asm/iommu.h> 33#include <asm/iommu.h>
33#include <asm/tce.h> 34#include <asm/tce.h>
34#include <asm/firmware.h> 35#include <asm/firmware.h>
36#include <asm/eeh_event.h>
37#include <asm/eeh.h>
35 38
36#include "powernv.h" 39#include "powernv.h"
37#include "pci.h" 40#include "pci.h"
@@ -202,7 +205,8 @@ static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no)
202 205
203 spin_lock_irqsave(&phb->lock, flags); 206 spin_lock_irqsave(&phb->lock, flags);
204 207
205 rc = opal_pci_get_phb_diag_data(phb->opal_id, phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE); 208 rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob,
209 PNV_PCI_DIAG_BUF_SIZE);
206 has_diag = (rc == OPAL_SUCCESS); 210 has_diag = (rc == OPAL_SUCCESS);
207 211
208 rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, 212 rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
@@ -227,43 +231,50 @@ static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no)
227 spin_unlock_irqrestore(&phb->lock, flags); 231 spin_unlock_irqrestore(&phb->lock, flags);
228} 232}
229 233
230static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, 234static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
231 u32 bdfn) 235 struct device_node *dn)
232{ 236{
233 s64 rc; 237 s64 rc;
234 u8 fstate; 238 u8 fstate;
235 u16 pcierr; 239 u16 pcierr;
236 u32 pe_no; 240 u32 pe_no;
237 241
238 /* Get PE# if we support IODA */ 242 /*
239 pe_no = phb->bdfn_to_pe ? phb->bdfn_to_pe(phb, bus, bdfn & 0xff) : 0; 243 * Get the PE#. During the PCI probe stage, we might not
244 * setup that yet. So all ER errors should be mapped to
245 * PE#0
246 */
247 pe_no = PCI_DN(dn)->pe_number;
248 if (pe_no == IODA_INVALID_PE)
249 pe_no = 0;
240 250
241 /* Read freeze status */ 251 /* Read freeze status */
242 rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr, 252 rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr,
243 NULL); 253 NULL);
244 if (rc) { 254 if (rc) {
245 pr_warning("PCI %d: Failed to read EEH status for PE#%d," 255 pr_warning("%s: Can't read EEH status (PE#%d) for "
246 " err %lld\n", phb->hose->global_number, pe_no, rc); 256 "%s, err %lld\n",
257 __func__, pe_no, dn->full_name, rc);
247 return; 258 return;
248 } 259 }
249 cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n", 260 cfg_dbg(" -> EEH check, bdfn=%04x PE#%d fstate=%x\n",
250 bdfn, pe_no, fstate); 261 (PCI_DN(dn)->busno << 8) | (PCI_DN(dn)->devfn),
262 pe_no, fstate);
251 if (fstate != 0) 263 if (fstate != 0)
252 pnv_pci_handle_eeh_config(phb, pe_no); 264 pnv_pci_handle_eeh_config(phb, pe_no);
253} 265}
254 266
255static int pnv_pci_read_config(struct pci_bus *bus, 267int pnv_pci_cfg_read(struct device_node *dn,
256 unsigned int devfn, 268 int where, int size, u32 *val)
257 int where, int size, u32 *val)
258{ 269{
259 struct pci_controller *hose = pci_bus_to_host(bus); 270 struct pci_dn *pdn = PCI_DN(dn);
260 struct pnv_phb *phb = hose->private_data; 271 struct pnv_phb *phb = pdn->phb->private_data;
261 u32 bdfn = (((uint64_t)bus->number) << 8) | devfn; 272 u32 bdfn = (pdn->busno << 8) | pdn->devfn;
273#ifdef CONFIG_EEH
274 struct eeh_pe *phb_pe = NULL;
275#endif
262 s64 rc; 276 s64 rc;
263 277
264 if (hose == NULL)
265 return PCIBIOS_DEVICE_NOT_FOUND;
266
267 switch (size) { 278 switch (size) {
268 case 1: { 279 case 1: {
269 u8 v8; 280 u8 v8;
@@ -287,28 +298,43 @@ static int pnv_pci_read_config(struct pci_bus *bus,
287 default: 298 default:
288 return PCIBIOS_FUNC_NOT_SUPPORTED; 299 return PCIBIOS_FUNC_NOT_SUPPORTED;
289 } 300 }
290 cfg_dbg("pnv_pci_read_config bus: %x devfn: %x +%x/%x -> %08x\n", 301 cfg_dbg("%s: bus: %x devfn: %x +%x/%x -> %08x\n",
291 bus->number, devfn, where, size, *val); 302 __func__, pdn->busno, pdn->devfn, where, size, *val);
292 303
293 /* Check if the PHB got frozen due to an error (no response) */ 304 /*
294 pnv_pci_config_check_eeh(phb, bus, bdfn); 305 * Check if the specified PE has been put into frozen
306 * state. On the other hand, we needn't do that while
307 * the PHB has been put into frozen state because of
308 * PHB-fatal errors.
309 */
310#ifdef CONFIG_EEH
311 phb_pe = eeh_phb_pe_get(pdn->phb);
312 if (phb_pe && (phb_pe->state & EEH_PE_ISOLATED))
313 return PCIBIOS_SUCCESSFUL;
314
315 if (phb->eeh_state & PNV_EEH_STATE_ENABLED) {
316 if (*val == EEH_IO_ERROR_VALUE(size) &&
317 eeh_dev_check_failure(of_node_to_eeh_dev(dn)))
318 return PCIBIOS_DEVICE_NOT_FOUND;
319 } else {
320 pnv_pci_config_check_eeh(phb, dn);
321 }
322#else
323 pnv_pci_config_check_eeh(phb, dn);
324#endif
295 325
296 return PCIBIOS_SUCCESSFUL; 326 return PCIBIOS_SUCCESSFUL;
297} 327}
298 328
299static int pnv_pci_write_config(struct pci_bus *bus, 329int pnv_pci_cfg_write(struct device_node *dn,
300 unsigned int devfn, 330 int where, int size, u32 val)
301 int where, int size, u32 val)
302{ 331{
303 struct pci_controller *hose = pci_bus_to_host(bus); 332 struct pci_dn *pdn = PCI_DN(dn);
304 struct pnv_phb *phb = hose->private_data; 333 struct pnv_phb *phb = pdn->phb->private_data;
305 u32 bdfn = (((uint64_t)bus->number) << 8) | devfn; 334 u32 bdfn = (pdn->busno << 8) | pdn->devfn;
306
307 if (hose == NULL)
308 return PCIBIOS_DEVICE_NOT_FOUND;
309 335
310 cfg_dbg("pnv_pci_write_config bus: %x devfn: %x +%x/%x -> %08x\n", 336 cfg_dbg("%s: bus: %x devfn: %x +%x/%x -> %08x\n",
311 bus->number, devfn, where, size, val); 337 pdn->busno, pdn->devfn, where, size, val);
312 switch (size) { 338 switch (size) {
313 case 1: 339 case 1:
314 opal_pci_config_write_byte(phb->opal_id, bdfn, where, val); 340 opal_pci_config_write_byte(phb->opal_id, bdfn, where, val);
@@ -322,14 +348,54 @@ static int pnv_pci_write_config(struct pci_bus *bus,
322 default: 348 default:
323 return PCIBIOS_FUNC_NOT_SUPPORTED; 349 return PCIBIOS_FUNC_NOT_SUPPORTED;
324 } 350 }
351
325 /* Check if the PHB got frozen due to an error (no response) */ 352 /* Check if the PHB got frozen due to an error (no response) */
326 pnv_pci_config_check_eeh(phb, bus, bdfn); 353#ifdef CONFIG_EEH
354 if (!(phb->eeh_state & PNV_EEH_STATE_ENABLED))
355 pnv_pci_config_check_eeh(phb, dn);
356#else
357 pnv_pci_config_check_eeh(phb, dn);
358#endif
327 359
328 return PCIBIOS_SUCCESSFUL; 360 return PCIBIOS_SUCCESSFUL;
329} 361}
330 362
363static int pnv_pci_read_config(struct pci_bus *bus,
364 unsigned int devfn,
365 int where, int size, u32 *val)
366{
367 struct device_node *dn, *busdn = pci_bus_to_OF_node(bus);
368 struct pci_dn *pdn;
369
370 for (dn = busdn->child; dn; dn = dn->sibling) {
371 pdn = PCI_DN(dn);
372 if (pdn && pdn->devfn == devfn)
373 return pnv_pci_cfg_read(dn, where, size, val);
374 }
375
376 *val = 0xFFFFFFFF;
377 return PCIBIOS_DEVICE_NOT_FOUND;
378
379}
380
381static int pnv_pci_write_config(struct pci_bus *bus,
382 unsigned int devfn,
383 int where, int size, u32 val)
384{
385 struct device_node *dn, *busdn = pci_bus_to_OF_node(bus);
386 struct pci_dn *pdn;
387
388 for (dn = busdn->child; dn; dn = dn->sibling) {
389 pdn = PCI_DN(dn);
390 if (pdn && pdn->devfn == devfn)
391 return pnv_pci_cfg_write(dn, where, size, val);
392 }
393
394 return PCIBIOS_DEVICE_NOT_FOUND;
395}
396
331struct pci_ops pnv_pci_ops = { 397struct pci_ops pnv_pci_ops = {
332 .read = pnv_pci_read_config, 398 .read = pnv_pci_read_config,
333 .write = pnv_pci_write_config, 399 .write = pnv_pci_write_config,
334}; 400};
335 401
@@ -412,6 +478,7 @@ static struct iommu_table *pnv_pci_setup_bml_iommu(struct pci_controller *hose)
412 pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)), 478 pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)),
413 be32_to_cpup(sizep), 0); 479 be32_to_cpup(sizep), 0);
414 iommu_init_table(tbl, hose->node); 480 iommu_init_table(tbl, hose->node);
481 iommu_register_group(tbl, pci_domain_nr(hose->bus), 0);
415 482
416 /* Deal with SW invalidated TCEs when needed (BML way) */ 483 /* Deal with SW invalidated TCEs when needed (BML way) */
417 swinvp = of_get_property(hose->dn, "linux,tce-sw-invalidate-info", 484 swinvp = of_get_property(hose->dn, "linux,tce-sw-invalidate-info",