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)
This commit is contained in:
Bjorn Helgaas 2019-11-28 08:54:48 -06:00
commit 21cea0c0ea

View File

@ -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;
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;
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);
mask = roundup_pow_of_two(size) - 1;
mask &= ~0xf;
/*
* 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);
}