summaryrefslogtreecommitdiffstats
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/soc/fsl/qbman/qman_ccsr.c65
-rw-r--r--linux/drivers/soc/fsl/qbman/qman_portal.c86
2 files changed, 111 insertions, 40 deletions
diff --git a/linux/drivers/soc/fsl/qbman/qman_ccsr.c b/linux/drivers/soc/fsl/qbman/qman_ccsr.c
index 817bb504..5f5ab8b0 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);
+#ifdef CONFIG_FSL_QMAN_CONFIG
/* 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 /* CONFIG_FSL_QMAN_CONFIG */
/* A SDQCR mask comprising all the available/visible pool channels */
static u32 qm_pools_sdqcr;
+#ifdef CONFIG_FSL_QMAN_CONFIG
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 /* CONFIG_FSL_QMAN_CONFIG */
u32 qm_get_pools_sdqcr(void)
{
return qm_pools_sdqcr;
}
+#ifdef CONFIG_FSL_QMAN_CONFIG
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 /* !CONFIG_FSL_QMAN_CONFIG */
+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 /* CONFIG_FSL_QMAN_CONFIG */
static int qman_resource_init(struct device *dev)
{
@@ -711,6 +730,7 @@ static int qman_resource_init(struct device *dev)
return 0;
}
+#ifdef CONFIG_FSL_QMAN_CONFIG
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 /* CONFIG_FSL_QMAN_CONFIG */
#ifndef __rtems__
static const struct of_device_id fsl_qman_ids[] = {
@@ -857,18 +878,20 @@ static void
qman_sysinit(void)
{
const char *fdt = bsp_fdt_get();
+ const char *name;
+ int node;
+ int ret;
+#ifdef CONFIG_FSL_QMAN_CONFIG
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 CONFIG_FSL_QMAN_CONFIG
+ BSD_ASSERT(node >= 0);
memset(&dev, 0, sizeof(dev));
dev.pdev.dev.of_node = &dev.of_node;
@@ -876,8 +899,34 @@ qman_sysinit(void)
dev.of_node.full_name = name;
ret = fsl_qman_probe(&dev.pdev);
- if (ret != 0)
- panic("qman: init failed");
+ BSD_ASSERT(ret == 0);
+#else /* !CONFIG_FSL_QMAN_CONFIG */
+ 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);
+#endif /* CONFIG_FSL_QMAN_CONFIG */
qman_sysinit_portals();
}
diff --git a/linux/drivers/soc/fsl/qbman/qman_portal.c b/linux/drivers/soc/fsl/qbman/qman_portal.c
index a7295f90..1fbcb5ff 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,9 @@ 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;
+#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 +445,9 @@ 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;
+#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] <
@@ -471,8 +471,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");
+ BSD_ASSERT(portal != NULL);
qman_portal_update_sdest(pcfg, val);
} else {
@@ -490,42 +489,65 @@ 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);
+ BSD_ASSERT(portal != NULL);
+
+ qman_portal_update_sdest(pcfg, i);
+
+ }
+ }
/* all assigned portals are initialized now */
qman_init_cgr_all();