From be8ff354c6bad34c73512ed9f60fea6529b848d7 Mon Sep 17 00:00:00 2001 From: Minghuan Lian Date: Thu, 17 Oct 2013 15:35:44 +0800 Subject: fsl_pci_ep: initialize PF and VF ATMU The first PCI controller of T4 has two physical functions(PF). Each physical functions supports 64 virtual functions(VF). There may be multiple functions to share PCI memory resource. The patch first disables all the inbound/outbound windows then, divides the PCI memory resource equally among all functions and enable a PF/VF outbound window to cover assigned memory. Signed-off-by: Minghuan Lian Change-Id: I84f2211438f1dae32a32d22c4ac60f3f53993159 Reviewed-on: http://git.am.freescale.net:8181/9603 Tested-by: Review Code-CDREVIEW Reviewed-by: Tiefei Zang Reviewed-by: Jose Rivera diff --git a/drivers/vfio/fsl_pci_ep/fsl_pci_ep.c b/drivers/vfio/fsl_pci_ep/fsl_pci_ep.c index 2f614b7..a29d97c 100644 --- a/drivers/vfio/fsl_pci_ep/fsl_pci_ep.c +++ b/drivers/vfio/fsl_pci_ep/fsl_pci_ep.c @@ -727,6 +727,57 @@ static int fsl_pci_pf_iov_init(struct pci_pf_dev *pf) return pf->vf_num; } +static int fsl_pci_pf_atmu_init(struct pci_pf_dev *pf) +{ + struct pci_ep_dev *ep = pf->pdev->sysdata; + struct pci_ep_win win; + int i, bits; + int win_idx = 3, start_idx = 1, end_idx = 4; + u64 sz; + + if (in_be32(&pf->regs->block_rev1) >= PCIE_IP_REV_2_2) { + win_idx = 2; + start_idx = 0; + end_idx = 3; + } + + sz = resource_size(&pf->mem_resources[0]) / (pf->vf_total + 1); + bits = ilog2(sz); + sz = 1ull << bits; + + if (pf->vf_regs) { + /* Disable all VF windows */ + for (i = 0; i < pf->vf_ow_num; i++) + out_be32(&pf->vf_regs->vfow[i].powar, 0); + for (i = 0; i < pf->vf_iw_num - 1; i++) + out_be32(&pf->vf_regs->vfiw[i].piwar, 0); + + /* Setup VF outbound windows*/ + win.cpu_addr = pf->mem_resources[0].start; + win.pci_addr = win.cpu_addr - pf->pci_mem_offset; + win.size = sz; + win.attr = 0; + win.idx = 0; + fsl_pci_ep_set_vfobwin(ep, &win); + } + + /* Disable all PF windows (except powar0 since it's ignored) */ + for (i = 1; i < pf->ow_num; i++) + out_be32(&pf->regs->pow[i].powar, 0); + for (i = start_idx; i < end_idx; i++) + out_be32(&pf->regs->piw[i].piwar, 0); + + /* Setup PF outbound windows */ + win.cpu_addr = pf->mem_resources[0].start + pf->vf_total * sz; + win.pci_addr = win.cpu_addr - pf->pci_mem_offset; + win.size = sz; + win.attr = 0; + win.idx = 1; + fsl_pci_ep_set_obwin(ep, &win); + + return 0; +} + struct pci_pf_dev *fsl_pci_pf_alloc(struct pci_dev *pdev, struct list_head *pf_list) { @@ -870,6 +921,7 @@ int fsl_pci_pf_setup(struct pci_bus *bus, int pf_num) fsl_pci_pf_cfg_ready(pf); fsl_pci_pf_iov_init(pf); + fsl_pci_pf_atmu_init(pf); for (i = 1; i <= pf->vf_num; i++) fsl_pci_ep_alloc(pf, i); -- cgit v0.10.2