From: Elad Nachman <enachman@xxxxxxxxxxx> Support atu/vendor registers regions start according to DT rather than using inflexible offset arithmetics. Signed-off-by: Elad Nachman <enachman@xxxxxxxxxxx> --- v4: Split from previous patch in series drivers/pci/controller/dwc/pcie-armada8k.c | 30 ++++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c index 2b94e32853ad..145434c7a9fb 100644 --- a/drivers/pci/controller/dwc/pcie-armada8k.c +++ b/drivers/pci/controller/dwc/pcie-armada8k.c @@ -46,7 +46,7 @@ struct armada8k_pcie_of_data { const struct dw_pcie_ops *pcie_ops; }; -#define PCIE_VENDOR_REGS_OFFSET 0x8000 /* in ac5 is 0x10000 */ +#define PCIE_VENDOR_REGS_OFFSET 0x8000 /* in ac5 is in another region */ #define PCIE_GLOBAL_CONTROL_REG (PCIE_VENDOR_REGS_OFFSET + 0x0) #define PCIE_APP_LTSSM_EN BIT(2) @@ -314,24 +314,29 @@ static int armada8k_add_pcie_port(struct armada8k_pcie *pcie, return 0; } -static u32 ac5_xlate_dbi_reg(u32 reg) +static void __iomem *ac5_xlate_dbi_reg(struct dw_pcie *pci, + void __iomem *base, + u32 reg) { /* Handle AC5 ATU access */ if ((reg & ~0xfffff) == PCIE_ATU_ACCESS_MASK_AC5) { reg &= 0xfffff; - /* ATU registers offset is 0xC00 + 0x200 * n, + /* ATU registers offset is 0xC000 + 0x200 * n, * from RFU registers. */ - reg = 0xc000 | (0x200 * (reg >> 9)) | (reg & 0xff); + reg = (0x200 * (reg >> 9)) | (reg & 0xff); + return pci->atu_base + reg; } else if ((reg & 0xfffff000) == PCIE_VENDOR_REGS_OFFSET) { /* PCIe RFU registers in A8K are at offset 0x8000 from base * (0xf2600000) while in AC5 offset is 0x10000 from base - * (0x800a0000) therefore need the addition of 0x8000. + * (0x800a0000) therefore need to be reduced by 0x8000 + * and rebased from dbi2 base, which is set to the PCIe rfu + * base in the AC5 dts: */ - reg += PCIE_VENDOR_REGS_OFFSET; + reg -= PCIE_VENDOR_REGS_OFFSET; + return pci->dbi_base2 + reg; } - - return reg; + return base + reg; } static u32 ac5_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, @@ -339,14 +344,14 @@ static u32 ac5_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, { u32 val; - dw_pcie_read(base + ac5_xlate_dbi_reg(reg), size, &val); + dw_pcie_read(ac5_xlate_dbi_reg(pci, base, reg), size, &val); return val; } static void ac5_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg, size_t size, u32 val) { - dw_pcie_write(base + ac5_xlate_dbi_reg(reg), size, val); + dw_pcie_write(ac5_xlate_dbi_reg(pci, base, reg), size, val); } static const struct dw_pcie_ops armada8k_dw_pcie_ops = { @@ -425,7 +430,6 @@ static int armada8k_pcie_probe(struct platform_device *pdev) ret = PTR_ERR(pci->dbi_base); goto fail_clkreg; } - ret = armada8k_pcie_setup_phys(pcie); if (ret) goto fail_clkreg; @@ -436,6 +440,10 @@ static int armada8k_pcie_probe(struct platform_device *pdev) if (ret) goto disable_phy; + /* backwards compatibility with older dts files: */ + if (!pci->dbi_base2) + pci->dbi_base2 = pci->dbi_base; + return 0; disable_phy: -- 2.17.1