Skip to content

Commit 9415743

Browse files
Abhishek-brcmLorenzo Pieralisi
authored andcommitted
PCI: iproc: Invalidate PAXB address mapping before programming it
Invalidate PAXB inbound/outbound address mapping on probe before programming it. Kernel relies on outbound/inbound windows VALID bit in OARR registers to detect if a window was programmed and if it is set it does not overwrite it. This causes issues on soft reboot (eg kexec) since the host controller does not go through a HW reset on softboot so the kernel detects valid outbound/inbound windows configuration and is not able to reprogramme it as expected. Therefore, in order to make sure outbound/inbound windows are reprogrammed on soft reboot (eg kexec), invalidate memory windows on each probe to fix the issue. Signed-off-by: Abhishek Shah <[email protected]> Signed-off-by: Lorenzo Pieralisi <[email protected]> Reviewed-by: Ray Jui <[email protected]> Reviewed-by: Andrew Murray <[email protected]>
1 parent 54ecb8f commit 9415743

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

drivers/pci/controller/pcie-iproc.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,32 @@ static int iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie)
12451245
return ret;
12461246
}
12471247

1248+
static void iproc_pcie_invalidate_mapping(struct iproc_pcie *pcie)
1249+
{
1250+
struct iproc_pcie_ib *ib = &pcie->ib;
1251+
struct iproc_pcie_ob *ob = &pcie->ob;
1252+
int idx;
1253+
1254+
if (pcie->ep_is_internal)
1255+
return;
1256+
1257+
if (pcie->need_ob_cfg) {
1258+
/* iterate through all OARR mapping regions */
1259+
for (idx = ob->nr_windows - 1; idx >= 0; idx--) {
1260+
iproc_pcie_write_reg(pcie,
1261+
MAP_REG(IPROC_PCIE_OARR0, idx), 0);
1262+
}
1263+
}
1264+
1265+
if (pcie->need_ib_cfg) {
1266+
/* iterate through all IARR mapping regions */
1267+
for (idx = 0; idx < ib->nr_regions; idx++) {
1268+
iproc_pcie_write_reg(pcie,
1269+
MAP_REG(IPROC_PCIE_IARR0, idx), 0);
1270+
}
1271+
}
1272+
}
1273+
12481274
static int iproce_pcie_get_msi(struct iproc_pcie *pcie,
12491275
struct device_node *msi_node,
12501276
u64 *msi_addr)
@@ -1517,6 +1543,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
15171543
iproc_pcie_perst_ctrl(pcie, true);
15181544
iproc_pcie_perst_ctrl(pcie, false);
15191545

1546+
iproc_pcie_invalidate_mapping(pcie);
1547+
15201548
if (pcie->need_ob_cfg) {
15211549
ret = iproc_pcie_map_ranges(pcie, res);
15221550
if (ret) {

0 commit comments

Comments
 (0)