mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 01:04:19 +08:00
PCI: dwc: Set INCREASE_REGION_SIZE flag based on limit address
We program the 64-bit ATU limit address (in PCIE_ATU_LIMIT/ PCIE_ATU_UPPER_LIMIT or PCIE_ATU_UNR_LOWER_LIMIT/PCIE_ATU_UNR_UPPER_LIMIT), but in addition, the PCIE_ATU_INCREASE_REGION_SIZE bit must be set if the upper 32 bits of the limit address differ from the upper 32 bits of the base address (see [1,2]).5b4cf0f653
("PCI: dwc: Add upper limit address for outbound iATU") set PCIE_ATU_INCREASE_REGION_SIZE, but only when the *size* was greater than 4GB. It did not set it when a smaller region crossed a 4GB boundary, e.g., [mem 0x0_f0000000-0x1_0fffffff]. Set PCIE_ATU_INCREASE_REGION_SIZE whenever PCIE_ATU_UPPER_LIMIT is greater than PCIE_ATU_UPPER_BASE. [1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, v5.40a, March 2019, fig.3-36, p.175 [2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, v5.40a, March 2019, fig.3-37, p.176 [bhelgaas: commit log] Fixes:5b4cf0f653
("PCI: dwc: Add upper limit address for outbound iATU") Link: https://lore.kernel.org/r/20220624143428.8334-5-Sergey.Semin@baikalelectronics.ru Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Rob Herring <robh@kernel.org>
This commit is contained in:
parent
d60a2e281e
commit
777e7c3ab7
@ -287,8 +287,8 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,
|
||||
dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
|
||||
upper_32_bits(pci_addr));
|
||||
val = type | PCIE_ATU_FUNC_NUM(func_no);
|
||||
val = upper_32_bits(size - 1) ?
|
||||
val | PCIE_ATU_INCREASE_REGION_SIZE : val;
|
||||
if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr))
|
||||
val |= PCIE_ATU_INCREASE_REGION_SIZE;
|
||||
if (pci->version == 0x490A)
|
||||
val = dw_pcie_enable_ecrc(val);
|
||||
dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, val);
|
||||
@ -315,6 +315,7 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
|
||||
u64 pci_addr, u64 size)
|
||||
{
|
||||
u32 retries, val;
|
||||
u64 limit_addr;
|
||||
|
||||
if (pci->ops && pci->ops->cpu_addr_fixup)
|
||||
cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
|
||||
@ -325,6 +326,8 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
|
||||
return;
|
||||
}
|
||||
|
||||
limit_addr = cpu_addr + size - 1;
|
||||
|
||||
dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT,
|
||||
PCIE_ATU_REGION_OUTBOUND | index);
|
||||
dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE,
|
||||
@ -332,17 +335,18 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
|
||||
dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE,
|
||||
upper_32_bits(cpu_addr));
|
||||
dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT,
|
||||
lower_32_bits(cpu_addr + size - 1));
|
||||
lower_32_bits(limit_addr));
|
||||
if (pci->version >= 0x460A)
|
||||
dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_LIMIT,
|
||||
upper_32_bits(cpu_addr + size - 1));
|
||||
upper_32_bits(limit_addr));
|
||||
dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET,
|
||||
lower_32_bits(pci_addr));
|
||||
dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
|
||||
upper_32_bits(pci_addr));
|
||||
val = type | PCIE_ATU_FUNC_NUM(func_no);
|
||||
val = ((upper_32_bits(size - 1)) && (pci->version >= 0x460A)) ?
|
||||
val | PCIE_ATU_INCREASE_REGION_SIZE : val;
|
||||
if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr) &&
|
||||
pci->version >= 0x460A)
|
||||
val |= PCIE_ATU_INCREASE_REGION_SIZE;
|
||||
if (pci->version == 0x490A)
|
||||
val = dw_pcie_enable_ecrc(val);
|
||||
dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, val);
|
||||
|
Loading…
Reference in New Issue
Block a user