diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/host/pci-layerscape-ep-debugfs.c | 51 | ||||
-rw-r--r-- | drivers/pci/host/pci-layerscape-ep.c | 10 | ||||
-rw-r--r-- | drivers/pci/host/pci-layerscape-ep.h | 1 |
3 files changed, 53 insertions, 9 deletions
diff --git a/drivers/pci/host/pci-layerscape-ep-debugfs.c b/drivers/pci/host/pci-layerscape-ep-debugfs.c index 6d5c781..d803864 100644 --- a/drivers/pci/host/pci-layerscape-ep-debugfs.c +++ b/drivers/pci/host/pci-layerscape-ep-debugfs.c @@ -34,8 +34,10 @@ #define PCIE_BAR1_SIZE (8 * 1024) /* 8K for MSIX */ #define PCIE_BAR2_SIZE (4 * 1024) /* 4K */ #define PCIE_BAR4_SIZE (1 * 1024 * 1024) /* 1M */ +#define PCIE_MSI_OB_SIZE (4 * 1024) /* 4K */ -#define PCIE_OB_BAR 0x1400000000ULL +#define PCIE_MSI_MSG_ADDR_OFF 0x54 +#define PCIE_MSI_MSG_DATA_OFF 0x5c enum test_type { TEST_TYPE_DMA, @@ -57,10 +59,14 @@ struct ls_ep_test { void __iomem *cfg; void __iomem *buf; void __iomem *out; + void __iomem *msi; dma_addr_t cfg_addr; dma_addr_t buf_addr; dma_addr_t out_addr; dma_addr_t bus_addr; + dma_addr_t msi_addr; + u64 msi_msg_addr; + u16 msi_msg_data; struct task_struct *thread; spinlock_t lock; struct completion done; @@ -73,6 +79,16 @@ struct ls_ep_test { char cmd[256]; }; +static int ls_pcie_ep_trigger_msi(struct ls_ep_test *test) +{ + if (!test->msi) + return -EINVAL; + + iowrite32(test->msi_msg_data, test->msi); + + return 0; +} + static int ls_pcie_ep_test_try_run(struct ls_ep_test *test) { int ret; @@ -266,6 +282,9 @@ int ls_pcie_ep_test_thread(void *arg) test->cmd, test->result); ls_pcie_ep_test_done(test); + + ls_pcie_ep_trigger_msi(test); + do_exit(0); } @@ -338,7 +357,7 @@ static int ls_pcie_ep_init_test(struct ls_ep_dev *ep, u64 bus_addr) } test->cfg_addr = virt_to_phys(test->cfg); - test->out_addr = PCIE_OB_BAR; + test->out_addr = pcie->out_base; test->out = ioremap(test->out_addr, PCIE_BAR4_SIZE); if (!test->out) { dev_info(&ep->dev, "failed to map out\n"); @@ -348,11 +367,25 @@ static int ls_pcie_ep_init_test(struct ls_ep_dev *ep, u64 bus_addr) test->bus_addr = bus_addr; + test->msi_addr = test->out_addr + PCIE_BAR4_SIZE; + test->msi = ioremap(test->msi_addr, PCIE_MSI_OB_SIZE); + if (!test->msi) + dev_info(&ep->dev, "failed to map MSI outbound region\n"); + + test->msi_msg_addr = ioread32(pcie->dbi + PCIE_MSI_MSG_ADDR_OFF) | + (((u64)ioread32(pcie->dbi + PCIE_MSI_MSG_ADDR_OFF + 4)) << 32); + test->msi_msg_data = ioread16(pcie->dbi + PCIE_MSI_MSG_DATA_OFF); + ls_pcie_ep_dev_cfg_enable(ep); ls_pcie_ep_test_setup_bars(ep); - /* outbound iATU*/ + + /* outbound iATU for memory */ ls_pcie_iatu_outbound_set(pcie, 0, PCIE_ATU_TYPE_MEM, test->out_addr, bus_addr, PCIE_BAR4_SIZE); + /* outbound iATU for MSI */ + ls_pcie_iatu_outbound_set(pcie, 1, PCIE_ATU_TYPE_MEM, + test->msi_addr, test->msi_msg_addr, + PCIE_MSI_OB_SIZE); /* ATU 0 : INBOUND : map BAR0 */ ls_pcie_iatu_inbound_set(pcie, 0, 0, test->cfg_addr); @@ -565,8 +598,8 @@ static ssize_t ls_pcie_ep_dbg_test_read(struct file *filp, { struct ls_ep_dev *ep = filp->private_data; struct ls_ep_test *test = ep->driver_data; - char buf[256]; - int len; + char buf[512]; + int desc = 0, len; if (!test) { dev_info(&ep->dev, " there is NO test\n"); @@ -578,12 +611,14 @@ static ssize_t ls_pcie_ep_dbg_test_read(struct file *filp, return 0; } + desc = sprintf(buf, "MSI ADDR:0x%llx MSI DATA:0x%x\n", + test->msi_msg_addr, test->msi_msg_data); - snprintf(buf, sizeof(buf), "%s throughput:%lluMbps\n", - test->cmd, test->result); + desc += sprintf(buf + desc, "%s throughput:%lluMbps\n", + test->cmd, test->result); len = simple_read_from_buffer(buffer, count, ppos, - buf, strlen(buf)); + buf, desc); return len; } diff --git a/drivers/pci/host/pci-layerscape-ep.c b/drivers/pci/host/pci-layerscape-ep.c index 461151e..4ee6884 100644 --- a/drivers/pci/host/pci-layerscape-ep.c +++ b/drivers/pci/host/pci-layerscape-ep.c @@ -192,7 +192,7 @@ static int ls_pcie_ep_init(struct ls_pcie *pcie) static int ls_pcie_ep_probe(struct platform_device *pdev) { struct ls_pcie *pcie; - struct resource *dbi_base; + struct resource *dbi_base, *cfg_res; int ret; pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL); @@ -216,6 +216,14 @@ static int ls_pcie_ep_probe(struct platform_device *pdev) dev_info(pcie->dev, "in EP mode\n"); + cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); + if (cfg_res) + pcie->out_base = cfg_res->start; + else { + dev_err(&pdev->dev, "missing *config* space\n"); + return -ENODEV; + } + ret = ls_pcie_ep_init(pcie); if (ret) return ret; diff --git a/drivers/pci/host/pci-layerscape-ep.h b/drivers/pci/host/pci-layerscape-ep.h index e518e84..89dd109 100644 --- a/drivers/pci/host/pci-layerscape-ep.h +++ b/drivers/pci/host/pci-layerscape-ep.h @@ -72,6 +72,7 @@ struct ls_pcie { struct dentry *dir; void __iomem *dbi; void __iomem *lut; + phys_addr_t out_base; int sriov; int index; }; |