Message ID | 1424935388-49100-1-git-send-email-hongtao.jia@freescale.com (mailing list archive) |
---|---|
State | Accepted |
Commit | ff015659b631621fc9d60403a5dfbdf72c1cd058 |
Delegated to: | Scott Wood |
Headers | show |
Hi Scott, I sent V3 of this patch a few days ago. Comments are welcome. Thanks. -Hongtao > -----Original Message----- > From: Jia Hongtao [mailto:hongtao.jia@freescale.com] > Sent: Thursday, February 26, 2015 3:23 PM > To: linuxppc-dev@lists.ozlabs.org; Wood Scott-B07421; asolokha@kb.kras.ru > Cc: galak@kernel.crashing.org; Li Yang-Leo-R58472; Jia Hongtao-B38951 > Subject: [PATCH V3] powerpc/85xx: workaround for chips with MSI hardware > errata > > From: Hongtao Jia <hongtao.jia@freescale.com> > > 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> > --- > Changes for V3: > * remove mpic_has_erratum_pic1() function. Test erratum directly. > * rebase on latest kernel update. > > Changes for V2: > * change the name of function mpic_has_errata() to > mpic_has_erratum_pic1(). > * move MSI_HW_ERRATA_ENDIAN define to fsl_msi.h with all other defines. > > arch/powerpc/sysdev/fsl_msi.c | 29 ++++++++++++++++++++++++++--- > 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 4bbb4b8..f086c6f 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, > msg->address_lo = lower_32_bits(address); > msg->address_hi = upper_32_bits(address); > > - msg->data = hwirq; > + /* > + * MPIC version 2.0 has erratum PIC1. It causes > + * that neither MSI nor MSI-X can work fine. > + * This is a workaround to allow MSI-X to function > + * properly. It only works for MSI-X, we prevent > + * MSI on buggy chips in fsl_setup_msi_irqs(). > + */ > + if (msi_data->feature & MSI_HW_ERRATA_ENDIAN) > + msg->data = __swab32(hwirq); > + else > + msg->data = hwirq; > > pr_debug("%s: allocated srs: %d, ibs: %d\n", __func__, > (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) > struct msi_msg msg; > struct fsl_msi *msi_data; > > - if (type == PCI_CAP_ID_MSIX) > - pr_debug("fslmsi: MSI-X untested, trying anyway.\n"); > + if (type == PCI_CAP_ID_MSI) { > + /* > + * MPIC version 2.0 has erratum PIC1. For now MSI > + * could not work. So check to prevent MSI from > + * being used on the board with this erratum. > + */ > + list_for_each_entry(msi_data, &msi_head, list) > + if (msi_data->feature & MSI_HW_ERRATA_ENDIAN) > + return -EINVAL; > + } > > /* > * 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) > > msi->feature = features->fsl_pic_ip; > > + /* For erratum PIC1 on MPIC version 2.0*/ > + if ((features->fsl_pic_ip & FSL_PIC_IP_MASK) == FSL_PIC_IP_MPIC > + && (fsl_mpic_primary_get_version() == 0x0200)) > + msi->feature |= MSI_HW_ERRATA_ENDIAN; > + > /* > * Remember the phandle, so that we can match with any PCI nodes > * that have an "fsl,msi" property. > diff --git a/arch/powerpc/sysdev/fsl_msi.h > b/arch/powerpc/sysdev/fsl_msi.h > index 420cfcb..a67359d 100644 > --- a/arch/powerpc/sysdev/fsl_msi.h > +++ b/arch/powerpc/sysdev/fsl_msi.h > @@ -27,6 +27,8 @@ > #define FSL_PIC_IP_IPIC 0x00000002 > #define FSL_PIC_IP_VMPIC 0x00000003 > > +#define MSI_HW_ERRATA_ENDIAN 0x00000010 > + > struct fsl_msi_cascade_data; > > struct fsl_msi { > -- > 2.1.0.27.g96db324
On Wed, 2015-03-04 at 00:44 -0600, Jia Hongtao-B38951 wrote: > Hi Scott, > > I sent V3 of this patch a few days ago. > Comments are welcome. Patience is welcome. :-) -Scott
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 4bbb4b8..f086c6f 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, msg->address_lo = lower_32_bits(address); msg->address_hi = upper_32_bits(address); - msg->data = hwirq; + /* + * MPIC version 2.0 has erratum PIC1. It causes + * that neither MSI nor MSI-X can work fine. + * This is a workaround to allow MSI-X to function + * properly. It only works for MSI-X, we prevent + * MSI on buggy chips in fsl_setup_msi_irqs(). + */ + if (msi_data->feature & MSI_HW_ERRATA_ENDIAN) + msg->data = __swab32(hwirq); + else + msg->data = hwirq; pr_debug("%s: allocated srs: %d, ibs: %d\n", __func__, (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) struct msi_msg msg; struct fsl_msi *msi_data; - if (type == PCI_CAP_ID_MSIX) - pr_debug("fslmsi: MSI-X untested, trying anyway.\n"); + if (type == PCI_CAP_ID_MSI) { + /* + * MPIC version 2.0 has erratum PIC1. For now MSI + * could not work. So check to prevent MSI from + * being used on the board with this erratum. + */ + list_for_each_entry(msi_data, &msi_head, list) + if (msi_data->feature & MSI_HW_ERRATA_ENDIAN) + return -EINVAL; + } /* * 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) msi->feature = features->fsl_pic_ip; + /* For erratum PIC1 on MPIC version 2.0*/ + if ((features->fsl_pic_ip & FSL_PIC_IP_MASK) == FSL_PIC_IP_MPIC + && (fsl_mpic_primary_get_version() == 0x0200)) + msi->feature |= MSI_HW_ERRATA_ENDIAN; + /* * Remember the phandle, so that we can match with any PCI nodes * that have an "fsl,msi" property. diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h index 420cfcb..a67359d 100644 --- a/arch/powerpc/sysdev/fsl_msi.h +++ b/arch/powerpc/sysdev/fsl_msi.h @@ -27,6 +27,8 @@ #define FSL_PIC_IP_IPIC 0x00000002 #define FSL_PIC_IP_VMPIC 0x00000003 +#define MSI_HW_ERRATA_ENDIAN 0x00000010 + struct fsl_msi_cascade_data; struct fsl_msi {