diff --git a/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch b/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch index dcdbb8f967..e9631335de 100644 --- a/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch +++ b/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch @@ -72,7 +72,7 @@ Signed-off-by: Hauke Mehrtens +obj-$(CONFIG_PCI_BCM5301X) += pci-host-bcm5301x.o --- /dev/null +++ b/drivers/pci/host/pci-host-bcm5301x.c -@@ -0,0 +1,428 @@ +@@ -0,0 +1,459 @@ +/* + * Northstar PCI-Express driver + * Only supports Root-Complex (RC) mode @@ -94,13 +94,16 @@ Signed-off-by: Hauke Mehrtens +#include +#include +#include -+#include +#include +#include -+#include + +#define SOC_PCIE_HDR_OFF 0x400 /* 256 bytes per function */ + ++#define PCI_LINK_STATUS_CTRL_2_OFFSET 0xDC ++#define PCI_TARGET_LINK_SPEED_MASK 0xF ++#define PCI_TARGET_LINK_SPEED_GEN2 0x2 ++#define PCI_TARGET_LINK_SPEED_GEN1 0x1 ++ +static int bcma_pcie2_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +{ + struct pci_sys_data *sys = pdev->sysdata; @@ -222,31 +225,59 @@ Signed-off-by: Hauke Mehrtens + * Check link status, return 0 if link is up in RC mode, + * otherwise return non-zero + */ -+static int bcma_pcie2_check_link(struct bcma_device *bdev, bool allow_gen2) ++static int bcma_pcie2_check_link(struct bcma_device *bdev, struct pci_sys_data *sys) +{ -+ u32 devfn = 0; + u32 tmp32; -+ u8 tmp8; -+ -+ tmp32 = bcma_pcie2_read_config(bdev, 0, devfn, 0xdc, 4); -+ tmp32 &= ~0xf; -+ if (allow_gen2) -+ tmp32 |= 2; -+ else { -+ /* force PCIE GEN1 */ -+ tmp32 |= 1; -+ } -+ bcma_pcie2_write_config(bdev, 0, devfn, 0xdc, 4, tmp32); -+ -+ /* See if the port is in EP mode, indicated by header type 00 */ -+ tmp8 = bcma_pcie2_read_config(bdev, 0, devfn, PCI_HEADER_TYPE, 1); -+ if (tmp8 != PCI_HEADER_TYPE_BRIDGE) { -+ dev_info(&bdev->dev, "Port %d in End-Point mode - ignored\n", -+ bdev->core_unit); -+ return -ENODEV; ++ u16 tmp16; ++ u16 pos; ++ u8 nlw; ++ /* ++ * Setup callback (bcma_pcie2_setup) is called in pcibios_init_hw before ++ * creating bus root, so we don't have it here yet. On the other hand ++ * we really want to use pci_bus_find_capability helper to check NLW. ++ * Let's fake simple pci_bus just to query for capabilities. ++ */ ++ struct pci_bus bus = { ++ .number = 0, ++ .ops = &bcma_pcie2_ops, ++ .sysdata = sys, ++ }; ++ ++ tmp32 = bcma_read32(bdev, BCMA_CORE_PCIE2_LINK_STATUS); ++ dev_dbg(&bdev->dev, "link status: 0x%08x\n", tmp32); ++ ++ tmp32 = bcma_read32(bdev, BCMA_CORE_PCIE2_STRAP_STATUS); ++ dev_dbg(&bdev->dev, "strap status: 0x%08x\n", tmp32); ++ ++ /* check link status to see if link is active */ ++ pos = pci_bus_find_capability(&bus, 0, PCI_CAP_ID_EXP); ++ pci_bus_read_config_word(&bus, 0, pos + PCI_EXP_LNKSTA, &tmp16); ++ nlw = (tmp16 & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; ++ ++ if (nlw == 0) { ++ /* try GEN 1 link speed */ ++ tmp32 = bcma_pcie2_read_config(bdev, 0, 0, ++ PCI_LINK_STATUS_CTRL_2_OFFSET, 4); ++ if ((tmp32 & PCI_TARGET_LINK_SPEED_MASK) == ++ PCI_TARGET_LINK_SPEED_GEN2) { ++ tmp32 &= ~PCI_TARGET_LINK_SPEED_MASK; ++ tmp32 |= PCI_TARGET_LINK_SPEED_GEN1; ++ bcma_pcie2_write_config(bdev, 0, 0, ++ PCI_LINK_STATUS_CTRL_2_OFFSET, 4, tmp32); ++ tmp32 = bcma_pcie2_read_config(bdev, 0, 0, ++ PCI_LINK_STATUS_CTRL_2_OFFSET, 4); ++ msleep(100); ++ ++ pos = pci_bus_find_capability(&bus, 0, PCI_CAP_ID_EXP); ++ pci_bus_read_config_word(&bus, 0, pos + PCI_EXP_LNKSTA, ++ &tmp16); ++ nlw = (tmp16 & PCI_EXP_LNKSTA_NLW) >> ++ PCI_EXP_LNKSTA_NLW_SHIFT; ++ } + } + -+ return 0; ++ dev_info(&bdev->dev, "link: %s\n", nlw ? "UP" : "DOWN"); ++ return nlw ? 0 : -ENODEV; +} + +/* @@ -438,7 +469,7 @@ Signed-off-by: Hauke Mehrtens + * Skip inactive ports - + * will need to change this for hot-plugging + */ -+ ret = bcma_pcie2_check_link(bdev, true); ++ ret = bcma_pcie2_check_link(bdev, sys); + if (ret) + return ret; + diff --git a/target/linux/bcm53xx/patches-3.18/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch b/target/linux/bcm53xx/patches-3.18/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch index fc616d7cd3..1a8460490f 100644 --- a/target/linux/bcm53xx/patches-3.18/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch +++ b/target/linux/bcm53xx/patches-3.18/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch @@ -72,7 +72,7 @@ Signed-off-by: Hauke Mehrtens +obj-$(CONFIG_PCI_BCM5301X) += pci-host-bcm5301x.o --- /dev/null +++ b/drivers/pci/host/pci-host-bcm5301x.c -@@ -0,0 +1,428 @@ +@@ -0,0 +1,459 @@ +/* + * Northstar PCI-Express driver + * Only supports Root-Complex (RC) mode @@ -94,13 +94,16 @@ Signed-off-by: Hauke Mehrtens +#include +#include +#include -+#include +#include +#include -+#include + +#define SOC_PCIE_HDR_OFF 0x400 /* 256 bytes per function */ + ++#define PCI_LINK_STATUS_CTRL_2_OFFSET 0xDC ++#define PCI_TARGET_LINK_SPEED_MASK 0xF ++#define PCI_TARGET_LINK_SPEED_GEN2 0x2 ++#define PCI_TARGET_LINK_SPEED_GEN1 0x1 ++ +static int bcma_pcie2_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +{ + struct pci_sys_data *sys = pdev->sysdata; @@ -222,31 +225,59 @@ Signed-off-by: Hauke Mehrtens + * Check link status, return 0 if link is up in RC mode, + * otherwise return non-zero + */ -+static int bcma_pcie2_check_link(struct bcma_device *bdev, bool allow_gen2) ++static int bcma_pcie2_check_link(struct bcma_device *bdev, struct pci_sys_data *sys) +{ -+ u32 devfn = 0; + u32 tmp32; -+ u8 tmp8; -+ -+ tmp32 = bcma_pcie2_read_config(bdev, 0, devfn, 0xdc, 4); -+ tmp32 &= ~0xf; -+ if (allow_gen2) -+ tmp32 |= 2; -+ else { -+ /* force PCIE GEN1 */ -+ tmp32 |= 1; -+ } -+ bcma_pcie2_write_config(bdev, 0, devfn, 0xdc, 4, tmp32); -+ -+ /* See if the port is in EP mode, indicated by header type 00 */ -+ tmp8 = bcma_pcie2_read_config(bdev, 0, devfn, PCI_HEADER_TYPE, 1); -+ if (tmp8 != PCI_HEADER_TYPE_BRIDGE) { -+ dev_info(&bdev->dev, "Port %d in End-Point mode - ignored\n", -+ bdev->core_unit); -+ return -ENODEV; ++ u16 tmp16; ++ u16 pos; ++ u8 nlw; ++ /* ++ * Setup callback (bcma_pcie2_setup) is called in pcibios_init_hw before ++ * creating bus root, so we don't have it here yet. On the other hand ++ * we really want to use pci_bus_find_capability helper to check NLW. ++ * Let's fake simple pci_bus just to query for capabilities. ++ */ ++ struct pci_bus bus = { ++ .number = 0, ++ .ops = &bcma_pcie2_ops, ++ .sysdata = sys, ++ }; ++ ++ tmp32 = bcma_read32(bdev, BCMA_CORE_PCIE2_LINK_STATUS); ++ dev_dbg(&bdev->dev, "link status: 0x%08x\n", tmp32); ++ ++ tmp32 = bcma_read32(bdev, BCMA_CORE_PCIE2_STRAP_STATUS); ++ dev_dbg(&bdev->dev, "strap status: 0x%08x\n", tmp32); ++ ++ /* check link status to see if link is active */ ++ pos = pci_bus_find_capability(&bus, 0, PCI_CAP_ID_EXP); ++ pci_bus_read_config_word(&bus, 0, pos + PCI_EXP_LNKSTA, &tmp16); ++ nlw = (tmp16 & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; ++ ++ if (nlw == 0) { ++ /* try GEN 1 link speed */ ++ tmp32 = bcma_pcie2_read_config(bdev, 0, 0, ++ PCI_LINK_STATUS_CTRL_2_OFFSET, 4); ++ if ((tmp32 & PCI_TARGET_LINK_SPEED_MASK) == ++ PCI_TARGET_LINK_SPEED_GEN2) { ++ tmp32 &= ~PCI_TARGET_LINK_SPEED_MASK; ++ tmp32 |= PCI_TARGET_LINK_SPEED_GEN1; ++ bcma_pcie2_write_config(bdev, 0, 0, ++ PCI_LINK_STATUS_CTRL_2_OFFSET, 4, tmp32); ++ tmp32 = bcma_pcie2_read_config(bdev, 0, 0, ++ PCI_LINK_STATUS_CTRL_2_OFFSET, 4); ++ msleep(100); ++ ++ pos = pci_bus_find_capability(&bus, 0, PCI_CAP_ID_EXP); ++ pci_bus_read_config_word(&bus, 0, pos + PCI_EXP_LNKSTA, ++ &tmp16); ++ nlw = (tmp16 & PCI_EXP_LNKSTA_NLW) >> ++ PCI_EXP_LNKSTA_NLW_SHIFT; ++ } + } + -+ return 0; ++ dev_info(&bdev->dev, "link: %s\n", nlw ? "UP" : "DOWN"); ++ return nlw ? 0 : -ENODEV; +} + +/* @@ -438,7 +469,7 @@ Signed-off-by: Hauke Mehrtens + * Skip inactive ports - + * will need to change this for hot-plugging + */ -+ ret = bcma_pcie2_check_link(bdev, true); ++ ret = bcma_pcie2_check_link(bdev, sys); + if (ret) + return ret; +