diff options
| author | Hongtao Jia <hongtao.jia@freescale.com> | 2015-02-26 02:23:08 -0500 |
|---|---|---|
| committer | Scott Wood <scottwood@freescale.com> | 2015-03-23 20:51:18 -0400 |
| commit | ff015659b631621fc9d60403a5dfbdf72c1cd058 (patch) | |
| tree | 493c005e167a3a531c8e3363a423139c93ba58be /arch/powerpc/sysdev | |
| parent | 807d38b73b63bbbaa8e1baacf76f7874992f91e8 (diff) | |
powerpc/85xx: workaround for chips with MSI hardware errata
The MPIC version 2.0 has a MSI errata (errata PIC1 of mpc8544), It causes
that neither MSI nor MSI-X can work fine. This is a workaround to allow
MSI-X to function properly.
Signed-off-by: Liu Shuo <soniccat.liu@gmail.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Jia Hongtao <hongtao.jia@freescale.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'arch/powerpc/sysdev')
| -rw-r--r-- | arch/powerpc/sysdev/fsl_msi.c | 29 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/fsl_msi.h | 2 |
2 files changed, 28 insertions, 3 deletions
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 4bbb4b8dfd09..f086c6f22dc9 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
| @@ -162,7 +162,17 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, | |||
| 162 | msg->address_lo = lower_32_bits(address); | 162 | msg->address_lo = lower_32_bits(address); |
| 163 | msg->address_hi = upper_32_bits(address); | 163 | msg->address_hi = upper_32_bits(address); |
| 164 | 164 | ||
| 165 | msg->data = hwirq; | 165 | /* |
| 166 | * MPIC version 2.0 has erratum PIC1. It causes | ||
| 167 | * that neither MSI nor MSI-X can work fine. | ||
| 168 | * This is a workaround to allow MSI-X to function | ||
| 169 | * properly. It only works for MSI-X, we prevent | ||
| 170 | * MSI on buggy chips in fsl_setup_msi_irqs(). | ||
| 171 | */ | ||
| 172 | if (msi_data->feature & MSI_HW_ERRATA_ENDIAN) | ||
| 173 | msg->data = __swab32(hwirq); | ||
| 174 | else | ||
| 175 | msg->data = hwirq; | ||
| 166 | 176 | ||
| 167 | pr_debug("%s: allocated srs: %d, ibs: %d\n", __func__, | 177 | pr_debug("%s: allocated srs: %d, ibs: %d\n", __func__, |
| 168 | (hwirq >> msi_data->srs_shift) & MSI_SRS_MASK, | 178 | (hwirq >> msi_data->srs_shift) & MSI_SRS_MASK, |
| @@ -180,8 +190,16 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
| 180 | struct msi_msg msg; | 190 | struct msi_msg msg; |
| 181 | struct fsl_msi *msi_data; | 191 | struct fsl_msi *msi_data; |
| 182 | 192 | ||
| 183 | if (type == PCI_CAP_ID_MSIX) | 193 | if (type == PCI_CAP_ID_MSI) { |
| 184 | pr_debug("fslmsi: MSI-X untested, trying anyway.\n"); | 194 | /* |
| 195 | * MPIC version 2.0 has erratum PIC1. For now MSI | ||
| 196 | * could not work. So check to prevent MSI from | ||
| 197 | * being used on the board with this erratum. | ||
| 198 | */ | ||
| 199 | list_for_each_entry(msi_data, &msi_head, list) | ||
| 200 | if (msi_data->feature & MSI_HW_ERRATA_ENDIAN) | ||
| 201 | return -EINVAL; | ||
| 202 | } | ||
| 185 | 203 | ||
| 186 | /* | 204 | /* |
| 187 | * If the PCI node has an fsl,msi property, then we need to use it | 205 | * If the PCI node has an fsl,msi property, then we need to use it |
| @@ -446,6 +464,11 @@ static int fsl_of_msi_probe(struct platform_device *dev) | |||
| 446 | 464 | ||
| 447 | msi->feature = features->fsl_pic_ip; | 465 | msi->feature = features->fsl_pic_ip; |
| 448 | 466 | ||
| 467 | /* For erratum PIC1 on MPIC version 2.0*/ | ||
| 468 | if ((features->fsl_pic_ip & FSL_PIC_IP_MASK) == FSL_PIC_IP_MPIC | ||
| 469 | && (fsl_mpic_primary_get_version() == 0x0200)) | ||
| 470 | msi->feature |= MSI_HW_ERRATA_ENDIAN; | ||
| 471 | |||
| 449 | /* | 472 | /* |
| 450 | * Remember the phandle, so that we can match with any PCI nodes | 473 | * Remember the phandle, so that we can match with any PCI nodes |
| 451 | * that have an "fsl,msi" property. | 474 | * that have an "fsl,msi" property. |
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h index 420cfcbdac01..a67359d993e5 100644 --- a/arch/powerpc/sysdev/fsl_msi.h +++ b/arch/powerpc/sysdev/fsl_msi.h | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #define FSL_PIC_IP_IPIC 0x00000002 | 27 | #define FSL_PIC_IP_IPIC 0x00000002 |
| 28 | #define FSL_PIC_IP_VMPIC 0x00000003 | 28 | #define FSL_PIC_IP_VMPIC 0x00000003 |
| 29 | 29 | ||
| 30 | #define MSI_HW_ERRATA_ENDIAN 0x00000010 | ||
| 31 | |||
| 30 | struct fsl_msi_cascade_data; | 32 | struct fsl_msi_cascade_data; |
| 31 | 33 | ||
| 32 | struct fsl_msi { | 34 | struct fsl_msi { |
