Skip to content

Commit e73ea1c

Browse files
damien-lemoalkwilczynski
authored andcommitted
PCI: dwc: endpoint: Implement the pci_epc_ops::align_addr() operation
The function dw_pcie_prog_outbound_atu() used to program outbound ATU entries for mapping RC PCI addresses to local CPU addresses does not allow PCI addresses that are not aligned to the value of region_align of struct dw_pcie. This value is determined from the iATU hardware registers during probing of the iATU (done by dw_pcie_iatu_detect()). This value is thus valid for all DWC PCIe controllers, and valid regardless of the hardware configuration used when synthesizing the DWC PCIe controller. Implement the ->align_addr() endpoint controller operation to allow this mapping alignment to be transparently handled by endpoint function drivers through the function pci_epc_mem_map(). Link: https://lore.kernel.org/linux-pci/[email protected] Link: https://lore.kernel.org/linux-pci/[email protected] Link: https://lore.kernel.org/linux-pci/[email protected] Co-developed-by: Niklas Cassel <[email protected]> Signed-off-by: Damien Le Moal <[email protected]> [mani: squashed the patch that changed phy_addr_t to u64] Signed-off-by: Manivannan Sadhasivam <[email protected]> [kwilczynski: squashed patch that updated the pci_size variable] Signed-off-by: Krzysztof Wilczyński <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]>
1 parent 08cac10 commit e73ea1c

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

drivers/pci/controller/dwc/pcie-designware-ep.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,20 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
268268
return -EINVAL;
269269
}
270270

271+
static u64 dw_pcie_ep_align_addr(struct pci_epc *epc, u64 pci_addr,
272+
size_t *pci_size, size_t *offset)
273+
{
274+
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
275+
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
276+
u64 mask = pci->region_align - 1;
277+
size_t ofst = pci_addr & mask;
278+
279+
*pci_size = ALIGN(ofst + *pci_size, epc->mem->window.page_size);
280+
*offset = ofst;
281+
282+
return pci_addr & ~mask;
283+
}
284+
271285
static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
272286
phys_addr_t addr)
273287
{
@@ -444,6 +458,7 @@ static const struct pci_epc_ops epc_ops = {
444458
.write_header = dw_pcie_ep_write_header,
445459
.set_bar = dw_pcie_ep_set_bar,
446460
.clear_bar = dw_pcie_ep_clear_bar,
461+
.align_addr = dw_pcie_ep_align_addr,
447462
.map_addr = dw_pcie_ep_map_addr,
448463
.unmap_addr = dw_pcie_ep_unmap_addr,
449464
.set_msi = dw_pcie_ep_set_msi,

0 commit comments

Comments
 (0)