diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2019-11-28 17:54:48 +0300 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2019-11-28 17:54:48 +0300 |
commit | 21cea0c0eabae5d8b498b661885396d7186f6b61 (patch) | |
tree | a42b5828f9d15b2e977ea9c7544bc335d23f6377 /drivers/pci | |
parent | 4940330a3696c37d95cb8e16880c412c28748e2d (diff) | |
parent | 7c7e53e1c93df14690bd12c1f84730fef927a6f1 (diff) |
Merge branch 'remotes/lorenzo/pci/rcar'
- Clear bit 0 of MACCTLR before PCIETCTLR.CFINIT per manual (Yoshihiro
Shimoda)
- Remove unnecessary header include from rcar (Andrew Murray)
- Tighten register index checking for rcar inbound range programming
(Marek Vasut)
- Fix rcar inbound range alignment calculation to improve packing of
multiple entries (Marek Vasut)
- Update rcar MACCTLR setting to match documentation (Yoshihiro Shimoda)
* remotes/lorenzo/pci/rcar:
PCI: rcar: Fix missing MACCTLR register setting in initialization sequence
PCI: rcar: Recalculate inbound range alignment for each controller entry
PCI: rcar: Move the inbound index check
PCI: rcar: Remove unnecessary header include (../pci.h)
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/controller/pcie-rcar.c | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c index f6a669a9af41..94ba4fe21923 100644 --- a/drivers/pci/controller/pcie-rcar.c +++ b/drivers/pci/controller/pcie-rcar.c @@ -30,8 +30,6 @@ #include <linux/pm_runtime.h> #include <linux/slab.h> -#include "../pci.h" - #define PCIECAR 0x000010 #define PCIECCTLR 0x000018 #define CONFIG_SEND_ENABLE BIT(31) @@ -93,8 +91,11 @@ #define LINK_SPEED_2_5GTS (1 << 16) #define LINK_SPEED_5_0GTS (2 << 16) #define MACCTLR 0x011058 +#define MACCTLR_NFTS_MASK GENMASK(23, 16) /* The name is from SH7786 */ #define SPEED_CHANGE BIT(24) #define SCRAMBLE_DISABLE BIT(27) +#define LTSMDIS BIT(31) +#define MACCTLR_INIT_VAL (LTSMDIS | MACCTLR_NFTS_MASK) #define PMSR 0x01105c #define MACS2R 0x011078 #define MACCGSPSETR 0x011084 @@ -615,6 +616,8 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie) if (IS_ENABLED(CONFIG_PCI_MSI)) rcar_pci_write_reg(pcie, 0x801f0000, PCIEMSITXR); + rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR); + /* Finish initialization - establish a PCI Express link */ rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); @@ -1029,25 +1032,30 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie, if (restype & IORESOURCE_PREFETCH) flags |= LAM_PREFETCH; - /* - * If the size of the range is larger than the alignment of the start - * address, we have to use multiple entries to perform the mapping. - */ - if (cpu_addr > 0) { - unsigned long nr_zeros = __ffs64(cpu_addr); - u64 alignment = 1ULL << nr_zeros; + while (cpu_addr < cpu_end) { + if (idx >= MAX_NR_INBOUND_MAPS - 1) { + dev_err(pcie->dev, "Failed to map inbound regions!\n"); + return -EINVAL; + } + /* + * If the size of the range is larger than the alignment of + * the start address, we have to use multiple entries to + * perform the mapping. + */ + if (cpu_addr > 0) { + unsigned long nr_zeros = __ffs64(cpu_addr); + u64 alignment = 1ULL << nr_zeros; - size = min(range->size, alignment); - } else { - size = range->size; - } - /* Hardware supports max 4GiB inbound region */ - size = min(size, 1ULL << 32); + size = min(range->size, alignment); + } else { + size = range->size; + } + /* Hardware supports max 4GiB inbound region */ + size = min(size, 1ULL << 32); - mask = roundup_pow_of_two(size) - 1; - mask &= ~0xf; + mask = roundup_pow_of_two(size) - 1; + mask &= ~0xf; - while (cpu_addr < cpu_end) { /* * Set up 64-bit inbound regions as the range parser doesn't * distinguish between 32 and 64-bit types. @@ -1067,11 +1075,6 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie, pci_addr += size; cpu_addr += size; idx += 2; - - if (idx > MAX_NR_INBOUND_MAPS) { - dev_err(pcie->dev, "Failed to map inbound regions!\n"); - return -EINVAL; - } } *index = idx; @@ -1237,6 +1240,7 @@ static int rcar_pcie_resume_noirq(struct device *dev) return 0; /* Re-establish the PCIe link */ + rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR); rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); return rcar_pcie_wait_for_dl(pcie); } |