---
 linux/drivers/soc/fsl/qbman/qman_ccsr.c   | 66 ++++++++++++++++++++---
 linux/drivers/soc/fsl/qbman/qman_portal.c | 89 ++++++++++++++++++++-----------
 2 files changed, 116 insertions(+), 39 deletions(-)

diff --git a/linux/drivers/soc/fsl/qbman/qman_ccsr.c 
b/linux/drivers/soc/fsl/qbman/qman_ccsr.c
index 817bb5041..5377c30f0 100644
--- a/linux/drivers/soc/fsl/qbman/qman_ccsr.c
+++ b/linux/drivers/soc/fsl/qbman/qman_ccsr.c
@@ -49,6 +49,7 @@ EXPORT_SYMBOL(qm_channel_pool1);
 u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
 EXPORT_SYMBOL(qm_channel_caam);
 
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
 /* Register offsets */
 #define REG_QCSP_LIO_CFG(n)    (0x0000 + ((n) * 0x10))
 #define REG_QCSP_IO_CFG(n)     (0x0004 + ((n) * 0x10))
@@ -283,9 +284,11 @@ static const struct qman_error_info_mdata error_mdata[] = {
 
 /* Pointer to the start of the QMan's CCSR space */
 static u32 __iomem *qm_ccsr_start;
+#endif /* !QORIQ_IS_HYPERVISOR_GUEST */
 /* A SDQCR mask comprising all the available/visible pool channels */
 static u32 qm_pools_sdqcr;
 
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
 static inline u32 qm_ccsr_in(u32 offset)
 {
        return ioread32be(qm_ccsr_start + offset/4);
@@ -295,12 +298,14 @@ static inline void qm_ccsr_out(u32 offset, u32 val)
 {
        iowrite32be(val, qm_ccsr_start + offset/4);
 }
+#endif /* !QORIQ_IS_HYPERVISOR_GUEST */
 
 u32 qm_get_pools_sdqcr(void)
 {
        return qm_pools_sdqcr;
 }
 
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
 enum qm_dc_portal {
        qm_dc_portal_fman0 = 0,
        qm_dc_portal_fman1 = 1
@@ -661,6 +666,20 @@ void qman_set_sdest(u16 channel, unsigned int cpu_idx)
                qm_ccsr_out(REG_QCSP_IO_CFG(idx), after);
        }
 }
+#else /* QORIQ_IS_HYPERVISOR_GUEST */
+static unsigned int qm_get_fqid_maxcnt(void)
+{
+       return 1U << 16;
+}
+
+void qman_liodn_fixup(u16 channel)
+{
+}
+
+void qman_set_sdest(u16 channel, unsigned int cpu_idx)
+{
+}
+#endif /* !QORIQ_IS_HYPERVISOR_GUEST */
 
 static int qman_resource_init(struct device *dev)
 {
@@ -711,6 +730,7 @@ static int qman_resource_init(struct device *dev)
        return 0;
 }
 
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
 static int fsl_qman_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -829,6 +849,7 @@ static int fsl_qman_probe(struct platform_device *pdev)
 
        return 0;
 }
+#endif /* !QORIQ_IS_HYPERVISOR_GUEST */
 
 #ifndef __rtems__
 static const struct of_device_id fsl_qman_ids[] = {
@@ -857,27 +878,56 @@ static void
 qman_sysinit(void)
 {
        const char *fdt = bsp_fdt_get();
+       const char *name;
+       int node;
+       int ret;
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
        struct {
                struct platform_device pdev;
                struct device_node of_node;
        } dev;
-       const char *name;
-       int node;
-       int ret;
+#endif
 
        name = "fsl,qman";
-       node = fdt_node_offset_by_compatible(fdt, 0, name);
-       if (node < 0)
-               panic("qman: no qman in FDT");
+       node = fdt_node_offset_by_compatible(fdt, -1, name);
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+       BSD_ASSERT(node < 0);
+       BSD_ASSERT(fdt_node_offset_by_compatible(fdt, -1,
+           "fsl,qman-portal-3.1.2") >= 0);
+
+       qman_ip_rev = QMAN_REV31;
+       qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
+       qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
+
+       qm_fqalloc = devm_gen_pool_create(NULL, 0, -1, "qman-fqalloc");
+       BSD_ASSERT(!IS_ERR(qm_fqalloc));
+
+       qm_qpalloc = devm_gen_pool_create(NULL, 0, -1, "qman-qpalloc");
+       BSD_ASSERT(!IS_ERR(qm_qpalloc));
+
+       qm_cgralloc = devm_gen_pool_create(NULL, 0, -1, "qman-cgralloc");
+       BSD_ASSERT(!IS_ERR(qm_cgralloc));
+
+       ret = qman_resource_init(NULL);
+       BSD_ASSERT(ret == 0);
+
+       ret = qman_alloc_fq_table(qm_get_fqid_maxcnt());
+       BSD_ASSERT(ret == 0);
+
+       ret = qman_wq_alloc();
+       BSD_ASSERT(ret == 0);
+#else /* !QORIQ_IS_HYPERVISOR_GUEST */
+       BSD_ASSERT(node >= 0);
 
        memset(&dev, 0, sizeof(dev));
+
        dev.pdev.dev.of_node = &dev.of_node;
        dev.of_node.offset = node;
        dev.of_node.full_name = name;
 
        ret = fsl_qman_probe(&dev.pdev);
-       if (ret != 0)
-               panic("qman: init failed");
+       BSD_ASSERT(ret == 0);
+#endif /* QORIQ_IS_HYPERVISOR_GUEST */
 
        qman_sysinit_portals();
 }
diff --git a/linux/drivers/soc/fsl/qbman/qman_portal.c 
b/linux/drivers/soc/fsl/qbman/qman_portal.c
index a7295f904..b4338a282 100644
--- a/linux/drivers/soc/fsl/qbman/qman_portal.c
+++ b/linux/drivers/soc/fsl/qbman/qman_portal.c
@@ -403,7 +403,7 @@ qman_get_dedicated_portal(int cpu)
        if (p == NULL)
                return (NULL);
 
-       list_del(&pcfg->node);
+       list_del_init(&pcfg->node);
 
        irq_sources = QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI | QM_PIRQ_CSCI
            | QM_PIRQ_DQRI;
@@ -433,9 +433,10 @@ do_init_pcfg(struct device_node *dn, struct 
qm_portal_config *pcfg,
        ret = of_address_to_resource(dn, 0, &res);
        if (ret != 0)
                panic("qman: no portal CE address");
-#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
-       pcfg->addr_virt[0] = (__iomem void *)
-           ((uintptr_t)&qoriq_qman_portal[0][0] + (uintptr_t)res.start);
+       pcfg->addr_virt[0] = (__iomem void *)(uintptr_t)res.start;
+       printk("qman[0] %llx\n", res.start);
+#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) && \
+    !defined(QORIQ_IS_HYPERVISOR_GUEST)
        BSD_ASSERT((uintptr_t)pcfg->addr_virt[0] >=
            (uintptr_t)&qoriq_qman_portal[0][0]);
        BSD_ASSERT((uintptr_t)pcfg->addr_virt[0] <
@@ -445,9 +446,10 @@ do_init_pcfg(struct device_node *dn, struct 
qm_portal_config *pcfg,
        ret = of_address_to_resource(dn, 1, &res);
        if (ret != 0)
                panic("qman: no portal CI address");
-#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
-       pcfg->addr_virt[1] = (__iomem void *)
-           ((uintptr_t)&qoriq_qman_portal[0][0] + (uintptr_t)res.start);
+       pcfg->addr_virt[1] = (__iomem void *)(uintptr_t)res.start;
+       printk("qman[1] %llx\n", res.start);
+#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) && \
+    !defined(QORIQ_IS_HYPERVISOR_GUEST)
        BSD_ASSERT((uintptr_t)pcfg->addr_virt[1] >=
            (uintptr_t)&qoriq_qman_portal[1][0]);
        BSD_ASSERT((uintptr_t)pcfg->addr_virt[1] <
@@ -472,7 +474,7 @@ do_init_pcfg(struct device_node *dn, struct 
qm_portal_config *pcfg,
 
                portal = init_pcfg(pcfg);
                if (portal == NULL)
-                       panic("qman: cannot create portal");
+                       panic("qman: cannot create portal (1)");
 
                qman_portal_update_sdest(pcfg, val);
        } else {
@@ -490,42 +492,67 @@ qman_sysinit_portals(void)
        int cpu_count = (int)rtems_get_processor_count();
        int i;
        int node;
-       int parent;
 
-       memset(&dn, 0, sizeof(dn));
-
-       name = "fsl,qman-portal";
-       node = fdt_node_offset_by_compatible(fdt, 0, name);
-       if (node < 0)
-               panic("qman: no portals in FDT");
-       parent = fdt_parent_offset(fdt, node);
-       if (parent < 0)
-               panic("qman: no parent of portals in FDT");
-       node = fdt_first_subnode(fdt, parent);
-
-       dn.full_name = name;
-       dn.offset = node;
-
-#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
+#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) && \
+    !defined(QORIQ_IS_HYPERVISOR_GUEST)
        qoriq_clear_ce_portal(&qoriq_qman_portal[0][0],
            sizeof(qoriq_qman_portal[0]));
        qoriq_clear_ci_portal(&qoriq_qman_portal[1][0],
            sizeof(qoriq_qman_portal[1]));
 #endif
 
+       memset(&dn, 0, sizeof(dn));
+
+       name = "fsl,qman-portal";
+       node = -1;
+       dn.full_name = name;
        i = 0;
-       while (node >= 0 && i < MAX_QMAN_PORTALS) {
-               if (fdt_node_check_compatible(fdt, node, name) == 0) {
-                       do_init_pcfg(&dn, &qman_configs[i], cpu_count);
-                       ++i;
-               }
 
-               node = fdt_next_subnode(fdt, node);
+       while (i < MAX_QMAN_PORTALS) {
+               node = fdt_node_offset_by_compatible(fdt, node, name);
+               if (node < 0)
+                       break;
+
                dn.offset = node;
+               do_init_pcfg(&dn, &qman_configs[i], cpu_count);
+               ++i;
        }
 
        if (i < cpu_count)
-               panic("qman: not enough portals in FDT");
+               panic("qman: not enough affine portals");
+
+       /*
+        * We try to use the "cell-index" for the affine portal processor
+        * index.  This is not always possible, so equip the remaining
+        * processors with portals from the free list.  Ignore the
+        * "libbsd,dequeue" property.
+        */
+       for (i = 0; i < cpu_count; ++i) {
+               struct qman_portal *p;
+
+               p = affine_portals[i];
+               if (p == NULL) {
+                       struct qm_portal_config *pcfg;
+                       struct qman_portal *portal;
+
+                       if (list_empty(&qman_free_portals))
+                               panic("qman: no free affine portal");
+
+                       pcfg = list_first_entry(&qman_free_portals,
+                           struct qm_portal_config, node);
+                       list_del_init(&pcfg->node);
+
+                       pcfg->cpu = i;
+                       pcfg->pools = qm_get_pools_sdqcr();
+
+                       portal = init_pcfg(pcfg);
+                       if (portal == NULL)
+                               panic("qman: cannot create portal (2)");
+
+                       qman_portal_update_sdest(pcfg, i);
+
+               }
+       }
 
        /* all assigned portals are initialized now */
        qman_init_cgr_all();
-- 
2.12.3

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to