From af072edb83555e768d2b30c6a31629d3eb3e0527 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 5 Sep 2019 16:05:28 +0100 Subject: PCI: rcar: Remove unnecessary header include (../pci.h) Remove unnecessary header include (../pci.h) since it doesn't provide any needed symbols. Signed-off-by: Andrew Murray Signed-off-by: Lorenzo Pieralisi Reviewed-by: Simon Horman Reviewed-by: Kieran Bingham Reviewed-by: Geert Uytterhoeven --- drivers/pci/controller/pcie-rcar.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/pci') diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c index f6a669a9af41..ee1c38c2fac9 100644 --- a/drivers/pci/controller/pcie-rcar.c +++ b/drivers/pci/controller/pcie-rcar.c @@ -30,8 +30,6 @@ #include #include -#include "../pci.h" - #define PCIECAR 0x000010 #define PCIECCTLR 0x000018 #define CONFIG_SEND_ENABLE BIT(31) -- cgit v1.2.3 From 85bff4c3d320bffceab0c96ee2be4d5f55a3a4e7 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 26 Oct 2019 20:26:58 +0200 Subject: PCI: rcar: Move the inbound index check Since the 'idx' variable value is stored across multiple calls to rcar_pcie_inbound_ranges() function, and the 'idx' value is used to index registers which are written, subsequent calls might cause the 'idx' value to be high enough to trigger writes into nonexistent registers. Fix this by moving the 'idx' value check to the beginning of the loop. Signed-off-by: Marek Vasut Signed-off-by: Lorenzo Pieralisi Reviewed-by: Andrew Murray Reviewed-by: Yoshihiro Shimoda Cc: Geert Uytterhoeven Cc: Lorenzo Pieralisi Cc: Wolfram Sang Cc: linux-renesas-soc@vger.kernel.org --- drivers/pci/controller/pcie-rcar.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/pci') diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c index ee1c38c2fac9..04ff6c4baa70 100644 --- a/drivers/pci/controller/pcie-rcar.c +++ b/drivers/pci/controller/pcie-rcar.c @@ -1046,6 +1046,10 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie, 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; + } /* * Set up 64-bit inbound regions as the range parser doesn't * distinguish between 32 and 64-bit types. @@ -1065,11 +1069,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; -- cgit v1.2.3 From 767c7846419cc562c9dd4f14cc617c2b9b1b96cd Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 26 Oct 2019 20:26:59 +0200 Subject: PCI: rcar: Recalculate inbound range alignment for each controller entry Due to hardware constraints, the size of each inbound range entry populated into the controller cannot be larger than the alignment of the entry's start address. Currently, the alignment for each "dma-ranges" inbound range is calculated only once for each range and the increment for programming the controller is also derived from it only once. Thus, a "dma-ranges" entry describing a memory at 0x48000000 and size 0x38000000 would lead to multiple controller entries, each 0x08000000 long. This is inefficient, especially considering that by adding the size to the start address, the alignment increases. This patch moves the alignment calculation into the loop populating the controller entries, thus updating the alignment for each controller entry. Tested-by: Yoshihiro Shimoda Signed-off-by: Marek Vasut Signed-off-by: Lorenzo Pieralisi Reviewed-by: Andrew Murray Reviewed-by: Simon Horman Reviewed-by: Yoshihiro Shimoda Cc: Geert Uytterhoeven Cc: Lorenzo Pieralisi Cc: Wolfram Sang Cc: linux-renesas-soc@vger.kernel.org --- drivers/pci/controller/pcie-rcar.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers/pci') diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c index 04ff6c4baa70..40d8c54a17d1 100644 --- a/drivers/pci/controller/pcie-rcar.c +++ b/drivers/pci/controller/pcie-rcar.c @@ -1027,29 +1027,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. -- cgit v1.2.3 From 7c7e53e1c93df14690bd12c1f84730fef927a6f1 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 5 Nov 2019 19:51:29 +0900 Subject: PCI: rcar: Fix missing MACCTLR register setting in initialization sequence The R-Car Gen2/3 manual - available at: https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/rz/rzg/rzg1m.html#documents "RZ/G Series User's Manual: Hardware" section strictly enforces the MACCTLR inizialization value - 39.3.1 - "Initial Setting of PCI Express": "Be sure to write the initial value (= H'80FF 0000) to MACCTLR before enabling PCIETCTLR.CFINIT". To avoid unexpected behavior and to match the SW initialization sequence guidelines, this patch programs the MACCTLR with the correct value. Note that the MACCTLR.SPCHG bit in the MACCTLR register description reports that "Only writing 1 is valid and writing 0 is invalid" but this "invalid" has to be interpreted as a write-ignore aka "ignored", not "prohibited". Reported-by: Eugeniu Rosca Fixes: c25da4778803 ("PCI: rcar: Add Renesas R-Car PCIe driver") Fixes: be20bbcb0a8c ("PCI: rcar: Add the initialization of PCIe link in resume_noirq()") Signed-off-by: Yoshihiro Shimoda Signed-off-by: Lorenzo Pieralisi Reviewed-by: Geert Uytterhoeven Cc: # v5.2+ --- drivers/pci/controller/pcie-rcar.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/pci') diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c index 40d8c54a17d1..94ba4fe21923 100644 --- a/drivers/pci/controller/pcie-rcar.c +++ b/drivers/pci/controller/pcie-rcar.c @@ -91,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 @@ -613,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); @@ -1235,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); } -- cgit v1.2.3