summaryrefslogtreecommitdiff
path: root/drivers/vfio
diff options
context:
space:
mode:
authorMinghuan Lian <Minghuan.Lian@freescale.com>2013-10-17 07:35:44 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-03-17 19:35:56 (GMT)
commitbe8ff354c6bad34c73512ed9f60fea6529b848d7 (patch)
tree908283fdf2d3222d3fe12edfc235729013a9c0df /drivers/vfio
parentb9bfcda3e66e7718c2dc2423e40e61ebc0f8a27d (diff)
downloadlinux-fsl-qoriq-be8ff354c6bad34c73512ed9f60fea6529b848d7.tar.xz
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 <Minghuan.Lian@freescale.com> Change-Id: I84f2211438f1dae32a32d22c4ac60f3f53993159 Reviewed-on: http://git.am.freescale.net:8181/9603 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Tiefei Zang <tie-fei.zang@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/vfio')
-rw-r--r--drivers/vfio/fsl_pci_ep/fsl_pci_ep.c52
1 files changed, 52 insertions, 0 deletions
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);