summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPali Rohár <pali@kernel.org>2022-07-06 13:10:43 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-08-25 12:14:56 +0300
commit6007987d46c60a49d7b7d6f40113819087926e1c (patch)
treec8c6139cb8be3c38759c5cc132d0c99f5aefa798
parentea0224643543d34020edb94d04089dc0c46af126 (diff)
downloadlinux-6007987d46c60a49d7b7d6f40113819087926e1c.tar.xz
powerpc/fsl-pci: Fix Class Code of PCIe Root Port
commit 0c551abfa004ce154d487d91777bf221c808a64f upstream. By default old pre-3.0 Freescale PCIe controllers reports invalid PCI Class Code 0x0b20 for PCIe Root Port. It can be seen by lspci -b output on P2020 board which has this pre-3.0 controller: $ lspci -bvnn 00:00.0 Power PC [0b20]: Freescale Semiconductor Inc P2020E [1957:0070] (rev 21) !!! Invalid class 0b20 for header type 01 Capabilities: [4c] Express Root Port (Slot-), MSI 00 Fix this issue by programming correct PCI Class Code 0x0604 for PCIe Root Port to the Freescale specific PCIe register 0x474. With this change lspci -b output is: $ lspci -bvnn 00:00.0 PCI bridge [0604]: Freescale Semiconductor Inc P2020E [1957:0070] (rev 21) (prog-if 00 [Normal decode]) Capabilities: [4c] Express Root Port (Slot-), MSI 00 Without any "Invalid class" error. So class code was properly reflected into standard (read-only) PCI register 0x08. Same fix is already implemented in U-Boot pcie_fsl.c driver in commit: http://source.denx.de/u-boot/u-boot/-/commit/d18d06ac35229345a0af80977a408cfbe1d1015b Fix activated by U-Boot stay active also after booting Linux kernel. But boards which use older U-Boot version without that fix are affected and still require this fix. So implement this class code fix also in kernel fsl_pci.c driver. Cc: stable@vger.kernel.org Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20220706101043.4867-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c8
-rw-r--r--arch/powerpc/sysdev/fsl_pci.h1
2 files changed, 9 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 918be816b097..6d41aa4db05d 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -523,6 +523,7 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary)
struct resource rsrc;
const int *bus_range;
u8 hdr_type, progif;
+ u32 class_code;
struct device_node *dev;
struct ccsr_pci __iomem *pci;
u16 temp;
@@ -596,6 +597,13 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary)
PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
if (fsl_pcie_check_link(hose))
hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ /* Fix Class Code to PCI_CLASS_BRIDGE_PCI_NORMAL for pre-3.0 controller */
+ if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) {
+ early_read_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, &class_code);
+ class_code &= 0xff;
+ class_code |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8;
+ early_write_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, class_code);
+ }
} else {
/*
* Set PBFR(PCI Bus Function Register)[10] = 1 to
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index 151588530b06..caa05c4aa427 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -23,6 +23,7 @@ struct platform_device;
#define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */
#define PCIE_LTSSM_L0 0x16 /* L0 state */
+#define PCIE_FSL_CSR_CLASSCODE 0x474 /* FSL GPEX CSR */
#define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */
#define PCIE_IP_REV_3_0 0x02080300 /* PCIE IP block version Rev3.0 */
#define PIWAR_EN 0x80000000 /* Enable */