summaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2019-03-25 10:39:45 +0100
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2019-05-01 16:50:13 +0200
commit6b7330303a8186fb211357e6d379237fe9d2ece1 (patch)
treeb036a0b061ffd2179375cf549a2aa608a9bc9691 /drivers/pci/controller
parentPCI: designware-ep: Configure Resizable BAR cap to advertise the smallest size (diff)
downloadlinux-6b7330303a8186fb211357e6d379237fe9d2ece1.tar.xz
linux-6b7330303a8186fb211357e6d379237fe9d2ece1.zip
PCI: designware-ep: Use aligned ATU window for raising MSI interrupts
Certain platforms like K2G reguires the outbound ATU window to be aligned. The alignment size is already present in mem->page_size. Use the alignment size present in mem->page_size to configure an aligned ATU window. In order to raise an interrupt, CPU has to write to address offset from the start of the window unlike before where writes were always to the beginning of the ATU window. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Diffstat (limited to 'drivers/pci/controller')
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-ep.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 0c208b9bda43..2bf5a35c0570 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -397,6 +397,7 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct pci_epc *epc = ep->epc;
+ unsigned int aligned_offset;
u16 msg_ctrl, msg_data;
u32 msg_addr_lower, msg_addr_upper, reg;
u64 msg_addr;
@@ -422,13 +423,15 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
reg = ep->msi_cap + PCI_MSI_DATA_32;
msg_data = dw_pcie_readw_dbi(pci, reg);
}
- msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
+ aligned_offset = msg_addr_lower & (epc->mem->page_size - 1);
+ msg_addr = ((u64)msg_addr_upper) << 32 |
+ (msg_addr_lower & ~aligned_offset);
ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
epc->mem->page_size);
if (ret)
return ret;
- writel(msg_data | (interrupt_num - 1), ep->msi_mem);
+ writel(msg_data | (interrupt_num - 1), ep->msi_mem + aligned_offset);
dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);