Merge tag 'u-boot-atmel-fixes-2021.01-b' of https://gitlab.denx.de/u-boot/custodians...
[platform/kernel/u-boot.git] / drivers / pci / pcie_layerscape_ep.c
index e609607..d7d4a44 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <asm/arch/fsl_serdes.h>
 #include <dm.h>
 #include <dm/devres.h>
 #include <errno.h>
@@ -46,7 +47,7 @@ static int ls_ep_set_bar(struct udevice *dev, uint fn, struct pci_bar *ep_bar)
        else
                type = PCIE_ATU_TYPE_IO;
 
-       ls_pcie_atu_inbound_set(pcie, fn, type, idx, bar, bar_phys);
+       ls_pcie_atu_inbound_set(pcie, fn, 0, type, idx, bar, bar_phys);
 
        dbi_writel(pcie, lower_32_bits(size - 1), reg + PCIE_NO_SRIOV_BAR_BASE);
        dbi_writel(pcie, flags, reg);
@@ -67,27 +68,51 @@ static struct pci_ep_ops ls_pcie_ep_ops = {
 static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep, u32 pf)
 {
        struct ls_pcie *pcie = pcie_ep->pcie;
+       u32 vf_flag = 0;
        u64 phys = 0;
 
        phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + pf * SZ_64M;
 
        phys = ALIGN(phys, PCIE_BAR0_SIZE);
        /* ATU 0 : INBOUND : map BAR0 */
-       ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+       ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
                                0 + pf * BAR_NUM, 0, phys);
        /* ATU 1 : INBOUND : map BAR1 */
        phys = ALIGN(phys + PCIE_BAR0_SIZE, PCIE_BAR1_SIZE);
-       ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+       ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
                                1 + pf * BAR_NUM, 1, phys);
        /* ATU 2 : INBOUND : map BAR2 */
        phys = ALIGN(phys + PCIE_BAR1_SIZE, PCIE_BAR2_SIZE);
-       ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+       ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
                                2 + pf * BAR_NUM, 2, phys);
        /* ATU 3 : INBOUND : map BAR2 */
        phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR4_SIZE);
-       ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
+       ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
                                3 + pf * BAR_NUM, 4, phys);
 
+       if (pcie_ep->sriov_flag) {
+               vf_flag = 1;
+               /* ATU 4 : INBOUND : map BAR0 */
+               phys = ALIGN(phys + PCIE_BAR4_SIZE, PCIE_BAR0_SIZE);
+               ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
+                                       4 + pf * BAR_NUM, 0, phys);
+               /* ATU 5 : INBOUND : map BAR1 */
+               phys = ALIGN(phys + PCIE_BAR0_SIZE * PCIE_VF_NUM,
+                            PCIE_BAR1_SIZE);
+               ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
+                                       5 + pf * BAR_NUM, 1, phys);
+               /* ATU 6 : INBOUND : map BAR2 */
+               phys = ALIGN(phys + PCIE_BAR1_SIZE * PCIE_VF_NUM,
+                            PCIE_BAR2_SIZE);
+               ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
+                                       6 + pf * BAR_NUM, 2, phys);
+               /* ATU 7 : INBOUND : map BAR4 */
+               phys = ALIGN(phys + PCIE_BAR2_SIZE * PCIE_VF_NUM,
+                            PCIE_BAR4_SIZE);
+               ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
+                                       7 + pf * BAR_NUM, 4, phys);
+       }
+
        /* ATU: OUTBOUND : map MEM */
        ls_pcie_atu_outbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
                                 (u64)pcie_ep->addr_res.start +
@@ -164,17 +189,35 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep)
        if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
                pcie_ep->sriov_flag = 1;
                for (pf = 0; pf < PCIE_PF_NUM; pf++) {
+                       /*
+                        * The VF_BARn_REG register's Prefetchable and Type bit
+                        * fields are overwritten by a write to VF's BAR Mask
+                        * register. Before writing to the VF_BARn_MASK_REG
+                        * register, write 0b to the PCIE_MISC_CONTROL_1_OFF
+                        * register.
+                        */
+                       writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF);
+
+                       bar_base = pcie->dbi +
+                                  PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf,
+                                                   pcie_ep->pf1_offset);
+
                        if (pcie_ep->cfg2_flag) {
-                               for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
+                               ctrl_writel(pcie,
+                                           PCIE_LCTRL0_VAL(pf, 0),
+                                           PCIE_PF_VF_CTRL);
+                               ls_pcie_ep_setup_bars(bar_base);
+
+                               for (vf = 1; vf <= PCIE_VF_NUM; vf++) {
                                        ctrl_writel(pcie,
                                                    PCIE_LCTRL0_VAL(pf, vf),
                                                    PCIE_PF_VF_CTRL);
+                                       ls_pcie_ep_setup_vf_bars(bar_base);
                                }
+                       } else {
+                               ls_pcie_ep_setup_bars(bar_base);
+                               ls_pcie_ep_setup_vf_bars(bar_base);
                        }
-                       bar_base = pcie->dbi +
-                                  PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf);
-                       ls_pcie_ep_setup_bars(bar_base);
-                       ls_pcie_ep_setup_vf_bars(bar_base);
 
                        ls_pcie_ep_setup_atu(pcie_ep, pf);
                }
@@ -186,6 +229,9 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep)
                ls_pcie_ep_setup_atu(pcie_ep, 0);
        }
 
+       ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM_SRIOV,
+                        PCIE_ATU_REGION_INBOUND);
+
        ls_pcie_ep_enable_cfg(pcie_ep);
 }
 
@@ -227,6 +273,13 @@ static int ls_pcie_ep_probe(struct udevice *dev)
 
        svr = SVR_SOC_VER(get_svr());
 
+       if (svr == SVR_LX2160A || svr == SVR_LX2162A ||
+           svr == SVR_LX2120A || svr == SVR_LX2080A ||
+           svr == SVR_LX2122A || svr == SVR_LX2082A)
+               pcie_ep->pf1_offset = LX2160_PCIE_PF1_OFFSET;
+       else
+               pcie_ep->pf1_offset = LS_PCIE_PF1_OFFSET;
+
        if (svr == SVR_LS2080A || svr == SVR_LS2085A)
                pcie_ep->cfg2_flag = 1;
        else
@@ -244,7 +297,8 @@ static int ls_pcie_ep_probe(struct udevice *dev)
        pcie_ep->num_ob_wins = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
                                              "num-ob-windows", 8);
 
-       printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
+       printf("PCIe%u: %s %s", PCIE_SRDS_PRTCL(pcie->idx), dev->name,
+              "Endpoint");
        ls_pcie_setup_ep(pcie_ep);
 
        if (!ls_pcie_link_up(pcie)) {