129310e5eSGavin Shan /* 229310e5eSGavin Shan * The file intends to implement the platform dependent EEH operations on 329310e5eSGavin Shan * powernv platform. Actually, the powernv was created in order to fully 429310e5eSGavin Shan * hypervisor support. 529310e5eSGavin Shan * 629310e5eSGavin Shan * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2013. 729310e5eSGavin Shan * 829310e5eSGavin Shan * This program is free software; you can redistribute it and/or modify 929310e5eSGavin Shan * it under the terms of the GNU General Public License as published by 1029310e5eSGavin Shan * the Free Software Foundation; either version 2 of the License, or 1129310e5eSGavin Shan * (at your option) any later version. 1229310e5eSGavin Shan */ 1329310e5eSGavin Shan 1429310e5eSGavin Shan #include <linux/atomic.h> 1529310e5eSGavin Shan #include <linux/delay.h> 1629310e5eSGavin Shan #include <linux/export.h> 1729310e5eSGavin Shan #include <linux/init.h> 1829310e5eSGavin Shan #include <linux/list.h> 1929310e5eSGavin Shan #include <linux/msi.h> 2029310e5eSGavin Shan #include <linux/of.h> 2129310e5eSGavin Shan #include <linux/pci.h> 2229310e5eSGavin Shan #include <linux/proc_fs.h> 2329310e5eSGavin Shan #include <linux/rbtree.h> 2429310e5eSGavin Shan #include <linux/sched.h> 2529310e5eSGavin Shan #include <linux/seq_file.h> 2629310e5eSGavin Shan #include <linux/spinlock.h> 2729310e5eSGavin Shan 2829310e5eSGavin Shan #include <asm/eeh.h> 2929310e5eSGavin Shan #include <asm/eeh_event.h> 3029310e5eSGavin Shan #include <asm/firmware.h> 3129310e5eSGavin Shan #include <asm/io.h> 3229310e5eSGavin Shan #include <asm/iommu.h> 3329310e5eSGavin Shan #include <asm/machdep.h> 3429310e5eSGavin Shan #include <asm/msi_bitmap.h> 3529310e5eSGavin Shan #include <asm/opal.h> 3629310e5eSGavin Shan #include <asm/ppc-pci.h> 3729310e5eSGavin Shan 3829310e5eSGavin Shan #include "powernv.h" 3929310e5eSGavin Shan #include "pci.h" 4029310e5eSGavin Shan 4129310e5eSGavin Shan /** 4229310e5eSGavin Shan * powernv_eeh_init - EEH platform dependent initialization 4329310e5eSGavin Shan * 4429310e5eSGavin Shan * EEH platform dependent initialization on powernv 4529310e5eSGavin Shan */ 4629310e5eSGavin Shan static int powernv_eeh_init(void) 4729310e5eSGavin Shan { 4829310e5eSGavin Shan /* We require OPALv3 */ 4929310e5eSGavin Shan if (!firmware_has_feature(FW_FEATURE_OPALv3)) { 5029310e5eSGavin Shan pr_warning("%s: OPALv3 is required !\n", __func__); 5129310e5eSGavin Shan return -EINVAL; 5229310e5eSGavin Shan } 5329310e5eSGavin Shan 5429310e5eSGavin Shan /* Set EEH probe mode */ 5529310e5eSGavin Shan eeh_probe_mode_set(EEH_PROBE_MODE_DEV); 5629310e5eSGavin Shan 5729310e5eSGavin Shan return 0; 5829310e5eSGavin Shan } 5929310e5eSGavin Shan 6029310e5eSGavin Shan /** 6129310e5eSGavin Shan * powernv_eeh_post_init - EEH platform dependent post initialization 6229310e5eSGavin Shan * 6329310e5eSGavin Shan * EEH platform dependent post initialization on powernv. When 6429310e5eSGavin Shan * the function is called, the EEH PEs and devices should have 6529310e5eSGavin Shan * been built. If the I/O cache staff has been built, EEH is 6629310e5eSGavin Shan * ready to supply service. 6729310e5eSGavin Shan */ 6829310e5eSGavin Shan static int powernv_eeh_post_init(void) 6929310e5eSGavin Shan { 7029310e5eSGavin Shan struct pci_controller *hose; 7129310e5eSGavin Shan struct pnv_phb *phb; 7229310e5eSGavin Shan int ret = 0; 7329310e5eSGavin Shan 7429310e5eSGavin Shan list_for_each_entry(hose, &hose_list, list_node) { 7529310e5eSGavin Shan phb = hose->private_data; 7629310e5eSGavin Shan 7729310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->post_init) { 7829310e5eSGavin Shan ret = phb->eeh_ops->post_init(hose); 7929310e5eSGavin Shan if (ret) 8029310e5eSGavin Shan break; 8129310e5eSGavin Shan } 8229310e5eSGavin Shan } 8329310e5eSGavin Shan 8429310e5eSGavin Shan return ret; 8529310e5eSGavin Shan } 8629310e5eSGavin Shan 8729310e5eSGavin Shan /** 8829310e5eSGavin Shan * powernv_eeh_dev_probe - Do probe on PCI device 8929310e5eSGavin Shan * @dev: PCI device 9029310e5eSGavin Shan * @flag: unused 9129310e5eSGavin Shan * 9229310e5eSGavin Shan * When EEH module is installed during system boot, all PCI devices 9329310e5eSGavin Shan * are checked one by one to see if it supports EEH. The function 9429310e5eSGavin Shan * is introduced for the purpose. By default, EEH has been enabled 9529310e5eSGavin Shan * on all PCI devices. That's to say, we only need do necessary 9629310e5eSGavin Shan * initialization on the corresponding eeh device and create PE 9729310e5eSGavin Shan * accordingly. 9829310e5eSGavin Shan * 9929310e5eSGavin Shan * It's notable that's unsafe to retrieve the EEH device through 10029310e5eSGavin Shan * the corresponding PCI device. During the PCI device hotplug, which 10129310e5eSGavin Shan * was possiblly triggered by EEH core, the binding between EEH device 10229310e5eSGavin Shan * and the PCI device isn't built yet. 10329310e5eSGavin Shan */ 10429310e5eSGavin Shan static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) 10529310e5eSGavin Shan { 10629310e5eSGavin Shan struct pci_controller *hose = pci_bus_to_host(dev->bus); 10729310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 10829310e5eSGavin Shan struct device_node *dn = pci_device_to_OF_node(dev); 10929310e5eSGavin Shan struct eeh_dev *edev = of_node_to_eeh_dev(dn); 11029310e5eSGavin Shan 11129310e5eSGavin Shan /* 11229310e5eSGavin Shan * When probing the root bridge, which doesn't have any 11329310e5eSGavin Shan * subordinate PCI devices. We don't have OF node for 11429310e5eSGavin Shan * the root bridge. So it's not reasonable to continue 11529310e5eSGavin Shan * the probing. 11629310e5eSGavin Shan */ 117f5c57710SGavin Shan if (!dn || !edev || edev->pe) 11829310e5eSGavin Shan return 0; 11929310e5eSGavin Shan 12029310e5eSGavin Shan /* Skip for PCI-ISA bridge */ 12129310e5eSGavin Shan if ((dev->class >> 8) == PCI_CLASS_BRIDGE_ISA) 12229310e5eSGavin Shan return 0; 12329310e5eSGavin Shan 12429310e5eSGavin Shan /* Initialize eeh device */ 12529310e5eSGavin Shan edev->class_code = dev->class; 126ab55d218SGavin Shan edev->mode &= 0xFFFFFF00; 1274b83bd45SGavin Shan if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) 1284b83bd45SGavin Shan edev->mode |= EEH_DEV_BRIDGE; 1294b83bd45SGavin Shan if (pci_is_pcie(dev)) { 1304b83bd45SGavin Shan edev->pcie_cap = pci_pcie_cap(dev); 1314b83bd45SGavin Shan 1324b83bd45SGavin Shan if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) 1334b83bd45SGavin Shan edev->mode |= EEH_DEV_ROOT_PORT; 1344b83bd45SGavin Shan else if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) 1354b83bd45SGavin Shan edev->mode |= EEH_DEV_DS_PORT; 1364b83bd45SGavin Shan } 1374b83bd45SGavin Shan 13829310e5eSGavin Shan edev->config_addr = ((dev->bus->number << 8) | dev->devfn); 13929310e5eSGavin Shan edev->pe_config_addr = phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff); 14029310e5eSGavin Shan 14129310e5eSGavin Shan /* Create PE */ 14229310e5eSGavin Shan eeh_add_to_parent_pe(edev); 14329310e5eSGavin Shan 14429310e5eSGavin Shan /* 14529310e5eSGavin Shan * Enable EEH explicitly so that we will do EEH check 14629310e5eSGavin Shan * while accessing I/O stuff 14729310e5eSGavin Shan */ 14829310e5eSGavin Shan eeh_subsystem_enabled = 1; 14929310e5eSGavin Shan 15029310e5eSGavin Shan /* Save memory bars */ 15129310e5eSGavin Shan eeh_save_bars(edev); 15229310e5eSGavin Shan 15329310e5eSGavin Shan return 0; 15429310e5eSGavin Shan } 15529310e5eSGavin Shan 15629310e5eSGavin Shan /** 15729310e5eSGavin Shan * powernv_eeh_set_option - Initialize EEH or MMIO/DMA reenable 15829310e5eSGavin Shan * @pe: EEH PE 15929310e5eSGavin Shan * @option: operation to be issued 16029310e5eSGavin Shan * 16129310e5eSGavin Shan * The function is used to control the EEH functionality globally. 16229310e5eSGavin Shan * Currently, following options are support according to PAPR: 16329310e5eSGavin Shan * Enable EEH, Disable EEH, Enable MMIO and Enable DMA 16429310e5eSGavin Shan */ 16529310e5eSGavin Shan static int powernv_eeh_set_option(struct eeh_pe *pe, int option) 16629310e5eSGavin Shan { 16729310e5eSGavin Shan struct pci_controller *hose = pe->phb; 16829310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 16929310e5eSGavin Shan int ret = -EEXIST; 17029310e5eSGavin Shan 17129310e5eSGavin Shan /* 17229310e5eSGavin Shan * What we need do is pass it down for hardware 17329310e5eSGavin Shan * implementation to handle it. 17429310e5eSGavin Shan */ 17529310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->set_option) 17629310e5eSGavin Shan ret = phb->eeh_ops->set_option(pe, option); 17729310e5eSGavin Shan 17829310e5eSGavin Shan return ret; 17929310e5eSGavin Shan } 18029310e5eSGavin Shan 18129310e5eSGavin Shan /** 18229310e5eSGavin Shan * powernv_eeh_get_pe_addr - Retrieve PE address 18329310e5eSGavin Shan * @pe: EEH PE 18429310e5eSGavin Shan * 18529310e5eSGavin Shan * Retrieve the PE address according to the given tranditional 18629310e5eSGavin Shan * PCI BDF (Bus/Device/Function) address. 18729310e5eSGavin Shan */ 18829310e5eSGavin Shan static int powernv_eeh_get_pe_addr(struct eeh_pe *pe) 18929310e5eSGavin Shan { 19029310e5eSGavin Shan return pe->addr; 19129310e5eSGavin Shan } 19229310e5eSGavin Shan 19329310e5eSGavin Shan /** 19429310e5eSGavin Shan * powernv_eeh_get_state - Retrieve PE state 19529310e5eSGavin Shan * @pe: EEH PE 19629310e5eSGavin Shan * @delay: delay while PE state is temporarily unavailable 19729310e5eSGavin Shan * 19829310e5eSGavin Shan * Retrieve the state of the specified PE. For IODA-compitable 19929310e5eSGavin Shan * platform, it should be retrieved from IODA table. Therefore, 20029310e5eSGavin Shan * we prefer passing down to hardware implementation to handle 20129310e5eSGavin Shan * it. 20229310e5eSGavin Shan */ 20329310e5eSGavin Shan static int powernv_eeh_get_state(struct eeh_pe *pe, int *delay) 20429310e5eSGavin Shan { 20529310e5eSGavin Shan struct pci_controller *hose = pe->phb; 20629310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 20729310e5eSGavin Shan int ret = EEH_STATE_NOT_SUPPORT; 20829310e5eSGavin Shan 20929310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->get_state) { 21029310e5eSGavin Shan ret = phb->eeh_ops->get_state(pe); 21129310e5eSGavin Shan 21229310e5eSGavin Shan /* 21329310e5eSGavin Shan * If the PE state is temporarily unavailable, 21429310e5eSGavin Shan * to inform the EEH core delay for default 21529310e5eSGavin Shan * period (1 second) 21629310e5eSGavin Shan */ 21729310e5eSGavin Shan if (delay) { 21829310e5eSGavin Shan *delay = 0; 21929310e5eSGavin Shan if (ret & EEH_STATE_UNAVAILABLE) 22029310e5eSGavin Shan *delay = 1000; 22129310e5eSGavin Shan } 22229310e5eSGavin Shan } 22329310e5eSGavin Shan 22429310e5eSGavin Shan return ret; 22529310e5eSGavin Shan } 22629310e5eSGavin Shan 22729310e5eSGavin Shan /** 22829310e5eSGavin Shan * powernv_eeh_reset - Reset the specified PE 22929310e5eSGavin Shan * @pe: EEH PE 23029310e5eSGavin Shan * @option: reset option 23129310e5eSGavin Shan * 23229310e5eSGavin Shan * Reset the specified PE 23329310e5eSGavin Shan */ 23429310e5eSGavin Shan static int powernv_eeh_reset(struct eeh_pe *pe, int option) 23529310e5eSGavin Shan { 23629310e5eSGavin Shan struct pci_controller *hose = pe->phb; 23729310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 23829310e5eSGavin Shan int ret = -EEXIST; 23929310e5eSGavin Shan 24029310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->reset) 24129310e5eSGavin Shan ret = phb->eeh_ops->reset(pe, option); 24229310e5eSGavin Shan 24329310e5eSGavin Shan return ret; 24429310e5eSGavin Shan } 24529310e5eSGavin Shan 24629310e5eSGavin Shan /** 24729310e5eSGavin Shan * powernv_eeh_wait_state - Wait for PE state 24829310e5eSGavin Shan * @pe: EEH PE 24929310e5eSGavin Shan * @max_wait: maximal period in microsecond 25029310e5eSGavin Shan * 25129310e5eSGavin Shan * Wait for the state of associated PE. It might take some time 25229310e5eSGavin Shan * to retrieve the PE's state. 25329310e5eSGavin Shan */ 25429310e5eSGavin Shan static int powernv_eeh_wait_state(struct eeh_pe *pe, int max_wait) 25529310e5eSGavin Shan { 25629310e5eSGavin Shan int ret; 25729310e5eSGavin Shan int mwait; 25829310e5eSGavin Shan 25929310e5eSGavin Shan while (1) { 26029310e5eSGavin Shan ret = powernv_eeh_get_state(pe, &mwait); 26129310e5eSGavin Shan 26229310e5eSGavin Shan /* 26329310e5eSGavin Shan * If the PE's state is temporarily unavailable, 26429310e5eSGavin Shan * we have to wait for the specified time. Otherwise, 26529310e5eSGavin Shan * the PE's state will be returned immediately. 26629310e5eSGavin Shan */ 26729310e5eSGavin Shan if (ret != EEH_STATE_UNAVAILABLE) 26829310e5eSGavin Shan return ret; 26929310e5eSGavin Shan 27029310e5eSGavin Shan max_wait -= mwait; 27129310e5eSGavin Shan if (max_wait <= 0) { 27229310e5eSGavin Shan pr_warning("%s: Timeout getting PE#%x's state (%d)\n", 27329310e5eSGavin Shan __func__, pe->addr, max_wait); 27429310e5eSGavin Shan return EEH_STATE_NOT_SUPPORT; 27529310e5eSGavin Shan } 27629310e5eSGavin Shan 27729310e5eSGavin Shan msleep(mwait); 27829310e5eSGavin Shan } 27929310e5eSGavin Shan 28029310e5eSGavin Shan return EEH_STATE_NOT_SUPPORT; 28129310e5eSGavin Shan } 28229310e5eSGavin Shan 28329310e5eSGavin Shan /** 28429310e5eSGavin Shan * powernv_eeh_get_log - Retrieve error log 28529310e5eSGavin Shan * @pe: EEH PE 28629310e5eSGavin Shan * @severity: temporary or permanent error log 28729310e5eSGavin Shan * @drv_log: driver log to be combined with retrieved error log 28829310e5eSGavin Shan * @len: length of driver log 28929310e5eSGavin Shan * 29029310e5eSGavin Shan * Retrieve the temporary or permanent error from the PE. 29129310e5eSGavin Shan */ 29229310e5eSGavin Shan static int powernv_eeh_get_log(struct eeh_pe *pe, int severity, 29329310e5eSGavin Shan char *drv_log, unsigned long len) 29429310e5eSGavin Shan { 29529310e5eSGavin Shan struct pci_controller *hose = pe->phb; 29629310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 29729310e5eSGavin Shan int ret = -EEXIST; 29829310e5eSGavin Shan 29929310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->get_log) 30029310e5eSGavin Shan ret = phb->eeh_ops->get_log(pe, severity, drv_log, len); 30129310e5eSGavin Shan 30229310e5eSGavin Shan return ret; 30329310e5eSGavin Shan } 30429310e5eSGavin Shan 30529310e5eSGavin Shan /** 30629310e5eSGavin Shan * powernv_eeh_configure_bridge - Configure PCI bridges in the indicated PE 30729310e5eSGavin Shan * @pe: EEH PE 30829310e5eSGavin Shan * 30929310e5eSGavin Shan * The function will be called to reconfigure the bridges included 31029310e5eSGavin Shan * in the specified PE so that the mulfunctional PE would be recovered 31129310e5eSGavin Shan * again. 31229310e5eSGavin Shan */ 31329310e5eSGavin Shan static int powernv_eeh_configure_bridge(struct eeh_pe *pe) 31429310e5eSGavin Shan { 31529310e5eSGavin Shan struct pci_controller *hose = pe->phb; 31629310e5eSGavin Shan struct pnv_phb *phb = hose->private_data; 31729310e5eSGavin Shan int ret = 0; 31829310e5eSGavin Shan 31929310e5eSGavin Shan if (phb->eeh_ops && phb->eeh_ops->configure_bridge) 32029310e5eSGavin Shan ret = phb->eeh_ops->configure_bridge(pe); 32129310e5eSGavin Shan 32229310e5eSGavin Shan return ret; 32329310e5eSGavin Shan } 32429310e5eSGavin Shan 32529310e5eSGavin Shan /** 32629310e5eSGavin Shan * powernv_eeh_next_error - Retrieve next EEH error to handle 32729310e5eSGavin Shan * @pe: Affected PE 32829310e5eSGavin Shan * 32929310e5eSGavin Shan * Using OPAL API, to retrieve next EEH error for EEH core to handle 33029310e5eSGavin Shan */ 33129310e5eSGavin Shan static int powernv_eeh_next_error(struct eeh_pe **pe) 33229310e5eSGavin Shan { 33329310e5eSGavin Shan struct pci_controller *hose; 33429310e5eSGavin Shan struct pnv_phb *phb = NULL; 33529310e5eSGavin Shan 33629310e5eSGavin Shan list_for_each_entry(hose, &hose_list, list_node) { 33729310e5eSGavin Shan phb = hose->private_data; 33829310e5eSGavin Shan break; 33929310e5eSGavin Shan } 34029310e5eSGavin Shan 34129310e5eSGavin Shan if (phb && phb->eeh_ops->next_error) 34229310e5eSGavin Shan return phb->eeh_ops->next_error(pe); 34329310e5eSGavin Shan 34429310e5eSGavin Shan return -EEXIST; 34529310e5eSGavin Shan } 34629310e5eSGavin Shan 3479be3beccSGavin Shan static int powernv_eeh_restore_config(struct device_node *dn) 3489be3beccSGavin Shan { 3499be3beccSGavin Shan struct eeh_dev *edev = of_node_to_eeh_dev(dn); 3509be3beccSGavin Shan struct pnv_phb *phb; 3519be3beccSGavin Shan s64 ret; 3529be3beccSGavin Shan 3539be3beccSGavin Shan if (!edev) 3549be3beccSGavin Shan return -EEXIST; 3559be3beccSGavin Shan 3569be3beccSGavin Shan phb = edev->phb->private_data; 3579be3beccSGavin Shan ret = opal_pci_reinit(phb->opal_id, 3589be3beccSGavin Shan OPAL_REINIT_PCI_DEV, edev->config_addr); 3599be3beccSGavin Shan if (ret) { 3609be3beccSGavin Shan pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n", 3619be3beccSGavin Shan __func__, edev->config_addr, ret); 3629be3beccSGavin Shan return -EIO; 3639be3beccSGavin Shan } 3649be3beccSGavin Shan 3659be3beccSGavin Shan return 0; 3669be3beccSGavin Shan } 3679be3beccSGavin Shan 36829310e5eSGavin Shan static struct eeh_ops powernv_eeh_ops = { 36929310e5eSGavin Shan .name = "powernv", 37029310e5eSGavin Shan .init = powernv_eeh_init, 37129310e5eSGavin Shan .post_init = powernv_eeh_post_init, 37229310e5eSGavin Shan .of_probe = NULL, 37329310e5eSGavin Shan .dev_probe = powernv_eeh_dev_probe, 37429310e5eSGavin Shan .set_option = powernv_eeh_set_option, 37529310e5eSGavin Shan .get_pe_addr = powernv_eeh_get_pe_addr, 37629310e5eSGavin Shan .get_state = powernv_eeh_get_state, 37729310e5eSGavin Shan .reset = powernv_eeh_reset, 37829310e5eSGavin Shan .wait_state = powernv_eeh_wait_state, 37929310e5eSGavin Shan .get_log = powernv_eeh_get_log, 38029310e5eSGavin Shan .configure_bridge = powernv_eeh_configure_bridge, 3819bf41be6SGavin Shan .read_config = pnv_pci_cfg_read, 3829bf41be6SGavin Shan .write_config = pnv_pci_cfg_write, 3831d350544SGavin Shan .next_error = powernv_eeh_next_error, 3849be3beccSGavin Shan .restore_config = powernv_eeh_restore_config 38529310e5eSGavin Shan }; 38629310e5eSGavin Shan 38729310e5eSGavin Shan /** 38829310e5eSGavin Shan * eeh_powernv_init - Register platform dependent EEH operations 38929310e5eSGavin Shan * 39029310e5eSGavin Shan * EEH initialization on powernv platform. This function should be 39129310e5eSGavin Shan * called before any EEH related functions. 39229310e5eSGavin Shan */ 39329310e5eSGavin Shan static int __init eeh_powernv_init(void) 39429310e5eSGavin Shan { 39529310e5eSGavin Shan int ret = -EINVAL; 39629310e5eSGavin Shan 39729310e5eSGavin Shan if (!machine_is(powernv)) 39829310e5eSGavin Shan return ret; 39929310e5eSGavin Shan 40029310e5eSGavin Shan ret = eeh_ops_register(&powernv_eeh_ops); 40129310e5eSGavin Shan if (!ret) 40229310e5eSGavin Shan pr_info("EEH: PowerNV platform initialized\n"); 40329310e5eSGavin Shan else 40429310e5eSGavin Shan pr_info("EEH: Failed to initialize PowerNV platform (%d)\n", ret); 40529310e5eSGavin Shan 40629310e5eSGavin Shan return ret; 40729310e5eSGavin Shan } 40829310e5eSGavin Shan 40929310e5eSGavin Shan early_initcall(eeh_powernv_init); 410