PCI: EPF: dma-test: Add outbound ATU test function

PCIe endpoint controller supports 8 outbound channels to map Root port
address and access it as memory mapped IO. Add test function to verify
this feature.

Bug 4705051

Change-Id: I126e94619c581ed15f1d6db54845de209742af0e
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3163953
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com>
This commit is contained in:
Manikanta Maddireddy
2024-06-25 14:12:07 +00:00
committed by mobile promotions
parent fb5a616f92
commit 49bb1dec11
3 changed files with 62 additions and 0 deletions

View File

@@ -240,6 +240,8 @@ static int ep_test_dma_probe(struct pci_dev *pdev, const struct pci_device_id *i
/* Update RP DMA system memory base address allocated with EP pci_dev in BAR0 */ /* Update RP DMA system memory base address allocated with EP pci_dev in BAR0 */
epf_bar = (__force struct pcie_epf_bar *)ep->bar_virt; epf_bar = (__force struct pcie_epf_bar *)ep->bar_virt;
epf_bar->rp_phy_addr = ep->ep_dma_phy; epf_bar->rp_phy_addr = ep->ep_dma_phy;
/* Assign OB magic number */
*((u64 *)((u8 *)ep->ep_dma_virt + PCIE_EP_OB_OFFSET)) = PCIE_EP_OB_MAGIC;
pci_read_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, &val_16); pci_read_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, &val_16);
if (val_16 & PCI_MSI_FLAGS_64BIT) { if (val_16 & PCI_MSI_FLAGS_64BIT) {

View File

@@ -114,11 +114,67 @@ static int edmalib_read_test(struct seq_file *s, void *data)
return edmalib_common_test(&epfnv->edma); return edmalib_common_test(&epfnv->edma);
} }
/* debugfs to perform EP outbound access */
static int edmalib_test_ob(struct seq_file *s, void *data)
{
struct pcie_epf_dma *epfnv = (struct pcie_epf_dma *)dev_get_drvdata(s->private);
struct pcie_epf_bar *epf_bar = (struct pcie_epf_bar *)epfnv->bar_virt;
struct pci_epc *epc = epfnv->epc;
void __iomem *dst_va[10] = { 0 };
phys_addr_t dst_pci_addr[10] = { 0 };
int i, ret;
if (!epf_bar->rp_phy_addr) {
dev_err(epfnv->fdev, "RP DMA address is null\n");
return -1;
}
for (i = 0; i < 10; i++) {
dst_va[i] = pci_epc_mem_alloc_addr(epc, &dst_pci_addr[i], SZ_64K);
if (!dst_va[i]) {
dev_err(epfnv->fdev, "failed to allocate dst PCIe address, ob ch: %u\n", i);
break;
}
dev_dbg(epfnv->fdev, "Mapping %llx(EP) to %llx(RP) for size SZ_64K, ob ch: %d\n",
dst_pci_addr[i], epf_bar->rp_phy_addr, i);
if (lpci_epc_map_addr(epc, 0, dst_pci_addr[i], epf_bar->rp_phy_addr, SZ_64K) < 0) {
dev_err(epfnv->fdev, "failed to map rp_phy_addr, ob ch: %d\n", i);
break;
}
if (*((u64 *) ((u8 *)dst_va[i] + PCIE_EP_OB_OFFSET)) != PCIE_EP_OB_MAGIC) {
dev_err(epfnv->fdev, "magic number: %llx is not matching, ob ch: %d\n",
*((u64 *) ((u8 *)dst_va[i] + PCIE_EP_OB_OFFSET)), i);
break;
}
}
if (i == 8) {
dev_info(epfnv->fdev, "Eight outbound channel mapping success\n");
ret = 0;
} else {
dev_info(epfnv->fdev, "Outbound channel mapping failed at ch: %d\n", i);
ret = -1;
}
while (i >= 0) {
if (dst_pci_addr[i])
lpci_epc_unmap_addr(epc, 0, dst_pci_addr[i]);
if (dst_va[i])
pci_epc_mem_free_addr(epc, dst_pci_addr[i], dst_va[i], SZ_64K);
i--;
}
return ret;
}
static void init_debugfs(struct pcie_epf_dma *epfnv) static void init_debugfs(struct pcie_epf_dma *epfnv)
{ {
debugfs_create_devm_seqfile(epfnv->fdev, "edmalib_test", epfnv->debugfs, edmalib_test); debugfs_create_devm_seqfile(epfnv->fdev, "edmalib_test", epfnv->debugfs, edmalib_test);
debugfs_create_devm_seqfile(epfnv->fdev, "edmalib_read_test", epfnv->debugfs, debugfs_create_devm_seqfile(epfnv->fdev, "edmalib_read_test", epfnv->debugfs,
edmalib_read_test); edmalib_read_test);
debugfs_create_devm_seqfile(epfnv->fdev, "edmalib_test_ob", epfnv->debugfs,
edmalib_test_ob);
debugfs_create_u32("dma_size", 0644, epfnv->debugfs, &epfnv->dma_size); debugfs_create_u32("dma_size", 0644, epfnv->debugfs, &epfnv->dma_size);
epfnv->dma_size = SZ_1M; epfnv->dma_size = SZ_1M;

View File

@@ -64,6 +64,10 @@ static inline void dma_common_wr(void __iomem *p, u32 val, u32 offset)
/* DMA base offset starts at 0x20000 from ATU_DMA base */ /* DMA base offset starts at 0x20000 from ATU_DMA base */
#define DMA_OFFSET 0x20000 #define DMA_OFFSET 0x20000
/* Outbound magic number */
#define PCIE_EP_OB_MAGIC 0xA5A519885A5A1984LU
#define PCIE_EP_OB_OFFSET SZ_16K
struct sanity_data { struct sanity_data {
u32 size; u32 size;
u32 src_offset; u32 src_offset;