aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.14/701-dpaa2-dpio-support-layerscape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.14/701-dpaa2-dpio-support-layerscape.patch')
-rw-r--r--target/linux/layerscape/patches-4.14/701-dpaa2-dpio-support-layerscape.patch789
1 files changed, 683 insertions, 106 deletions
diff --git a/target/linux/layerscape/patches-4.14/701-dpaa2-dpio-support-layerscape.patch b/target/linux/layerscape/patches-4.14/701-dpaa2-dpio-support-layerscape.patch
index 34514caa0c..ce5dfdbe86 100644
--- a/target/linux/layerscape/patches-4.14/701-dpaa2-dpio-support-layerscape.patch
+++ b/target/linux/layerscape/patches-4.14/701-dpaa2-dpio-support-layerscape.patch
@@ -1,20 +1,27 @@
-From ede8d823f0e1b2c5e14cbac13839b818ed1c18cf Mon Sep 17 00:00:00 2001
+From 80df9e62536d7cac5c03a4fcb494c6ddf0723633 Mon Sep 17 00:00:00 2001
From: Biwen Li <biwen.li@nxp.com>
-Date: Tue, 30 Oct 2018 18:26:10 +0800
-Subject: [PATCH 07/40] apaa2-dpio:support layerscape
+Date: Wed, 17 Apr 2019 18:58:27 +0800
+Subject: [PATCH] dpaa2-dpio: support layerscape
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
This is an integrated patch of dpaa2-dpio for layerscape
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
+Signed-off-by: Biwen Li <biwen.li@nxp.com>
Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Guanhua Gao <guanhua.gao@nxp.com>
Signed-off-by: Haiying Wang <Haiying.Wang@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
+Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Roy Pledge <roy.pledge@nxp.com>
-Signed-off-by: Biwen Li <biwen.li@nxp.com>
+Signed-off-by: Youri Querry <youri.querry_1@nxp.com>
---
drivers/staging/fsl-mc/Kconfig | 1 +
drivers/staging/fsl-mc/Makefile | 1 +
@@ -26,12 +33,12 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
drivers/staging/fsl-mc/bus/dpcon.c | 32 +-
drivers/staging/fsl-mc/bus/dpio/Makefile | 3 +-
drivers/staging/fsl-mc/bus/dpio/dpio-cmd.h | 29 +-
- drivers/staging/fsl-mc/bus/dpio/dpio-driver.c | 53 ++--
- .../staging/fsl-mc/bus/dpio/dpio-service.c | 258 +++++++++++++---
- drivers/staging/fsl-mc/bus/dpio/dpio.c | 51 ++--
+ drivers/staging/fsl-mc/bus/dpio/dpio-driver.c | 99 ++--
+ .../staging/fsl-mc/bus/dpio/dpio-service.c | 295 +++++++++---
+ drivers/staging/fsl-mc/bus/dpio/dpio.c | 51 +--
drivers/staging/fsl-mc/bus/dpio/dpio.h | 32 +-
- .../staging/fsl-mc/bus/dpio/qbman-portal.c | 217 ++++++++++---
- .../staging/fsl-mc/bus/dpio/qbman-portal.h | 112 ++++---
+ .../staging/fsl-mc/bus/dpio/qbman-portal.c | 421 ++++++++++++++----
+ .../staging/fsl-mc/bus/dpio/qbman-portal.h | 134 ++++--
drivers/staging/fsl-mc/bus/dpmcp.c | 28 +-
drivers/staging/fsl-mc/bus/dprc-driver.c | 4 +-
drivers/staging/fsl-mc/bus/dprc.c | 28 +-
@@ -42,14 +49,14 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
.../fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 4 +-
drivers/staging/fsl-mc/bus/mc-io.c | 28 +-
drivers/staging/fsl-mc/bus/mc-sys.c | 28 +-
- drivers/staging/fsl-mc/include/dpaa2-fd.h | 288 ++++++++++++++++--
+ drivers/staging/fsl-mc/include/dpaa2-fd.h | 288 ++++++++++--
drivers/staging/fsl-mc/include/dpaa2-global.h | 27 +-
- drivers/staging/fsl-mc/include/dpaa2-io.h | 97 ++++--
+ drivers/staging/fsl-mc/include/dpaa2-io.h | 110 +++--
drivers/staging/fsl-mc/include/dpbp.h | 29 +-
drivers/staging/fsl-mc/include/dpcon.h | 32 +-
- drivers/staging/fsl-mc/include/dpopr.h | 110 +++++++
+ drivers/staging/fsl-mc/include/dpopr.h | 110 +++++
drivers/staging/fsl-mc/include/mc.h | 4 +-
- 33 files changed, 970 insertions(+), 634 deletions(-)
+ 33 files changed, 1233 insertions(+), 693 deletions(-)
create mode 100644 drivers/staging/fsl-mc/include/dpopr.h
--- a/drivers/staging/fsl-mc/Kconfig
@@ -347,15 +354,33 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
*/
#include <linux/types.h>
-@@ -114,6 +89,7 @@ static int dpaa2_dpio_probe(struct fsl_m
+@@ -38,6 +13,7 @@
+ #include <linux/msi.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/delay.h>
++#include <linux/io.h>
+
+ #include "../../include/mc.h"
+ #include "../../include/dpaa2-io.h"
+@@ -54,6 +30,8 @@ struct dpio_priv {
+ struct dpaa2_io *io;
+ };
+
++static cpumask_var_t cpus_unused_mask;
++
+ static irqreturn_t dpio_irq_handler(int irq_num, void *arg)
+ {
+ struct device *dev = (struct device *)arg;
+@@ -113,7 +91,7 @@ static int dpaa2_dpio_probe(struct fsl_m
+ struct dpio_priv *priv;
int err = -ENOMEM;
struct device *dev = &dpio_dev->dev;
- static int next_cpu = -1;
+- static int next_cpu = -1;
+ int possible_next_cpu;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
-@@ -135,6 +111,12 @@ static int dpaa2_dpio_probe(struct fsl_m
+@@ -135,6 +113,12 @@ static int dpaa2_dpio_probe(struct fsl_m
goto err_open;
}
@@ -368,39 +393,75 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
err = dpio_get_attributes(dpio_dev->mc_io, 0, dpio_dev->mc_handle,
&dpio_attrs);
if (err) {
-@@ -156,23 +138,23 @@ static int dpaa2_dpio_probe(struct fsl_m
+@@ -155,26 +139,35 @@ static int dpaa2_dpio_probe(struct fsl_m
+ desc.dpio_id = dpio_dev->obj_desc.id;
/* get the cpu to use for the affinity hint */
- if (next_cpu == -1)
+- if (next_cpu == -1)
- next_cpu = cpumask_first(cpu_online_mask);
-+ possible_next_cpu = cpumask_first(cpu_online_mask);
- else
+- else
- next_cpu = cpumask_next(next_cpu, cpu_online_mask);
-+ possible_next_cpu = cpumask_next(next_cpu, cpu_online_mask);
-
+-
- if (!cpu_possible(next_cpu)) {
++ possible_next_cpu = cpumask_first(cpus_unused_mask);
+ if (possible_next_cpu >= nr_cpu_ids) {
dev_err(dev, "probe failed. Number of DPIOs exceeds NR_CPUS.\n");
err = -ERANGE;
goto err_allocate_irqs;
}
- desc.cpu = next_cpu;
-+ desc.cpu = next_cpu = possible_next_cpu;
++ desc.cpu = possible_next_cpu;
++ cpumask_clear_cpu(possible_next_cpu, cpus_unused_mask);
- /*
+- /*
- * Set the CENA regs to be the cache inhibited area of the portal to
- * avoid coherency issues if a user migrates to another core.
-+ * Set the CENA regs to be the cache enabled area of the portal to
-+ * achieve the best performance.
- */
+- */
- desc.regs_cena = ioremap_wc(dpio_dev->regions[1].start,
- resource_size(&dpio_dev->regions[1]));
-+ desc.regs_cena = ioremap_cache_ns(dpio_dev->regions[0].start,
-+ resource_size(&dpio_dev->regions[0]));
- desc.regs_cinh = ioremap(dpio_dev->regions[1].start,
- resource_size(&dpio_dev->regions[1]));
+- desc.regs_cinh = ioremap(dpio_dev->regions[1].start,
+- resource_size(&dpio_dev->regions[1]));
++ if (dpio_dev->obj_desc.region_count < 3) {
++ /* No support for DDR backed portals, use classic mapping */
++ desc.regs_cena = ioremap_cache_ns(dpio_dev->regions[0].start,
++ resource_size(&dpio_dev->regions[0]));
++ } else {
++ desc.regs_cena = memremap(dpio_dev->regions[2].start,
++ resource_size(&dpio_dev->regions[2]),
++ MEMREMAP_WB);
++ }
++ if (IS_ERR(desc.regs_cena)) {
++ dev_err(dev, "ioremap_cache_ns failed\n");
++ goto err_allocate_irqs;
++ }
++
++ desc.regs_cinh = devm_ioremap(dev, dpio_dev->regions[1].start,
++ resource_size(&dpio_dev->regions[1]));
++ if (!desc.regs_cinh) {
++ dev_err(dev, "devm_ioremap failed\n");
++ goto err_allocate_irqs;
++ }
+
+ err = fsl_mc_allocate_irqs(dpio_dev);
+ if (err) {
+@@ -186,7 +179,7 @@ static int dpaa2_dpio_probe(struct fsl_m
+ if (err)
+ goto err_register_dpio_irq;
+
+- priv->io = dpaa2_io_create(&desc);
++ priv->io = dpaa2_io_create(&desc, dev);
+ if (!priv->io) {
+ dev_err(dev, "dpaa2_io_create failed\n");
+ goto err_dpaa2_io_create;
+@@ -196,7 +189,6 @@ static int dpaa2_dpio_probe(struct fsl_m
+ dev_dbg(dev, " receives_notifications = %d\n",
+ desc.receives_notifications);
+ dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
+- fsl_mc_portal_free(dpio_dev->mc_io);
-@@ -207,6 +189,7 @@ err_register_dpio_irq:
+ return 0;
+
+@@ -207,6 +199,7 @@ err_register_dpio_irq:
err_allocate_irqs:
dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
err_get_attr:
@@ -408,6 +469,55 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
err_open:
fsl_mc_portal_free(dpio_dev->mc_io);
+@@ -227,7 +220,7 @@ static int dpaa2_dpio_remove(struct fsl_
+ {
+ struct device *dev;
+ struct dpio_priv *priv;
+- int err;
++ int err = 0, cpu;
+
+ dev = &dpio_dev->dev;
+ priv = dev_get_drvdata(dev);
+@@ -236,11 +229,8 @@ static int dpaa2_dpio_remove(struct fsl_
+
+ dpio_teardown_irqs(dpio_dev);
+
+- err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io);
+- if (err) {
+- dev_err(dev, "MC portal allocation failed\n");
+- goto err_mcportal;
+- }
++ cpu = dpaa2_io_get_cpu(priv->io);
++ cpumask_set_cpu(cpu, cpus_unused_mask);
+
+ err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id,
+ &dpio_dev->mc_handle);
+@@ -261,7 +251,7 @@ static int dpaa2_dpio_remove(struct fsl_
+
+ err_open:
+ fsl_mc_portal_free(dpio_dev->mc_io);
+-err_mcportal:
++
+ return err;
+ }
+
+@@ -285,11 +275,16 @@ static struct fsl_mc_driver dpaa2_dpio_d
+
+ static int dpio_driver_init(void)
+ {
++ if (!zalloc_cpumask_var(&cpus_unused_mask, GFP_KERNEL))
++ return -ENOMEM;
++ cpumask_copy(cpus_unused_mask, cpu_online_mask);
++
+ return fsl_mc_driver_register(&dpaa2_dpio_driver);
+ }
+
+ static void dpio_driver_exit(void)
+ {
++ free_cpumask_var(cpus_unused_mask);
+ fsl_mc_driver_unregister(&dpaa2_dpio_driver);
+ }
+ module_init(dpio_driver_init);
--- a/drivers/staging/fsl-mc/bus/dpio/dpio-service.c
+++ b/drivers/staging/fsl-mc/bus/dpio/dpio-service.c
@@ -1,33 +1,8 @@
@@ -453,7 +563,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpaa2_io_desc dpio_desc;
struct qbman_swp_desc swp_desc;
struct qbman_swp *swp;
-@@ -83,7 +57,7 @@ static inline struct dpaa2_io *service_s
+@@ -53,6 +27,7 @@ struct dpaa2_io {
+ /* protect notifications list */
+ spinlock_t lock_notifications;
+ struct list_head notifications;
++ struct device *dev;
+ };
+
+ struct dpaa2_io_store {
+@@ -83,7 +58,7 @@ static inline struct dpaa2_io *service_s
* If cpu == -1, choose the current cpu, with no guarantees about
* potentially being migrated away.
*/
@@ -462,7 +580,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
cpu = smp_processor_id();
/* If a specific cpu was requested, pick it up immediately */
-@@ -95,6 +69,10 @@ static inline struct dpaa2_io *service_s
+@@ -95,6 +70,10 @@ static inline struct dpaa2_io *service_s
if (d)
return d;
@@ -473,7 +591,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
spin_lock(&dpio_list_lock);
d = list_entry(dpio_list.next, struct dpaa2_io, node);
list_del(&d->node);
-@@ -105,6 +83,23 @@ static inline struct dpaa2_io *service_s
+@@ -105,15 +84,34 @@ static inline struct dpaa2_io *service_s
}
/**
@@ -496,8 +614,20 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+/**
* dpaa2_io_create() - create a dpaa2_io object.
* @desc: the dpaa2_io descriptor
++ * @dev: the actual DPIO device
+ *
+ * Activates a "struct dpaa2_io" corresponding to the given config of an actual
+ * DPIO object.
*
-@@ -126,7 +121,6 @@ struct dpaa2_io *dpaa2_io_create(const s
+ * Return a valid dpaa2_io object for success, or NULL for failure.
+ */
+-struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc)
++struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc,
++ struct device *dev)
+ {
+ struct dpaa2_io *obj = kmalloc(sizeof(*obj), GFP_KERNEL);
+
+@@ -126,7 +124,6 @@ struct dpaa2_io *dpaa2_io_create(const s
return NULL;
}
@@ -505,15 +635,19 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
obj->dpio_desc = *desc;
obj->swp_desc.cena_bar = obj->dpio_desc.regs_cena;
obj->swp_desc.cinh_bar = obj->dpio_desc.regs_cinh;
-@@ -158,7 +152,6 @@ struct dpaa2_io *dpaa2_io_create(const s
+@@ -156,9 +153,10 @@ struct dpaa2_io *dpaa2_io_create(const s
+ dpio_by_cpu[desc->cpu] = obj;
+ spin_unlock(&dpio_list_lock);
++ obj->dev = dev;
++
return obj;
}
-EXPORT_SYMBOL(dpaa2_io_create);
/**
* dpaa2_io_down() - release the dpaa2_io object.
-@@ -171,11 +164,8 @@ EXPORT_SYMBOL(dpaa2_io_create);
+@@ -171,11 +169,8 @@ EXPORT_SYMBOL(dpaa2_io_create);
*/
void dpaa2_io_down(struct dpaa2_io *d)
{
@@ -525,7 +659,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
#define DPAA_POLL_MAX 32
-@@ -206,7 +196,7 @@ irqreturn_t dpaa2_io_irq(struct dpaa2_io
+@@ -206,7 +201,7 @@ irqreturn_t dpaa2_io_irq(struct dpaa2_io
u64 q64;
q64 = qbman_result_SCN_ctx(dq);
@@ -534,25 +668,54 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
ctx->cb(ctx);
} else {
pr_crit("fsl-mc-dpio: Unrecognised/ignored DQRR entry\n");
-@@ -222,7 +212,6 @@ done:
+@@ -222,13 +217,19 @@ done:
qbman_swp_interrupt_set_inhibit(swp, 0);
return IRQ_HANDLED;
}
-EXPORT_SYMBOL(dpaa2_io_irq);
++
++int dpaa2_io_get_cpu(struct dpaa2_io *d)
++{
++ return d->dpio_desc.cpu;
++}
++EXPORT_SYMBOL(dpaa2_io_get_cpu);
/**
* dpaa2_io_service_register() - Prepare for servicing of FQDAN or CDAN
-@@ -252,7 +241,7 @@ int dpaa2_io_service_register(struct dpa
+ * notifications on the given DPIO service.
+ * @d: the given DPIO service.
+ * @ctx: the notification context.
++ * @dev: the device that requests the register
+ *
+ * The caller should make the MC command to attach a DPAA2 object to
+ * a DPIO after this function completes successfully. In that way:
+@@ -243,7 +244,8 @@ EXPORT_SYMBOL(dpaa2_io_irq);
+ * Return 0 for success, or -ENODEV for failure.
+ */
+ int dpaa2_io_service_register(struct dpaa2_io *d,
+- struct dpaa2_io_notification_ctx *ctx)
++ struct dpaa2_io_notification_ctx *ctx,
++ struct device *dev)
+ {
+ unsigned long irqflags;
+
+@@ -251,8 +253,10 @@ int dpaa2_io_service_register(struct dpa
+ if (!d)
return -ENODEV;
++ device_link_add(dev, d->dev, DL_FLAG_AUTOREMOVE_SUPPLIER);
++
ctx->dpio_id = d->dpio_desc.dpio_id;
- ctx->qman64 = (u64)ctx;
+ ctx->qman64 = (u64)(uintptr_t)ctx;
ctx->dpio_private = d;
spin_lock_irqsave(&d->lock_notifications, irqflags);
list_add(&ctx->node, &d->notifications);
-@@ -265,7 +254,7 @@ int dpaa2_io_service_register(struct dpa
+@@ -263,20 +267,23 @@ int dpaa2_io_service_register(struct dpa
+ return qbman_swp_CDAN_set_context_enable(d->swp,
+ (u16)ctx->id,
ctx->qman64);
++
return 0;
}
-EXPORT_SYMBOL(dpaa2_io_service_register);
@@ -560,16 +723,33 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* dpaa2_io_service_deregister - The opposite of 'register'.
-@@ -288,7 +277,7 @@ void dpaa2_io_service_deregister(struct
+ * @service: the given DPIO service.
+ * @ctx: the notification context.
++ * @dev: the device that requests to be deregistered
+ *
+ * This function should be called only after sending the MC command to
+ * to detach the notification-producing device from the DPIO.
+ */
+ void dpaa2_io_service_deregister(struct dpaa2_io *service,
+- struct dpaa2_io_notification_ctx *ctx)
++ struct dpaa2_io_notification_ctx *ctx,
++ struct device *dev)
+ {
+ struct dpaa2_io *d = ctx->dpio_private;
+ unsigned long irqflags;
+@@ -287,8 +294,10 @@ void dpaa2_io_service_deregister(struct
+ spin_lock_irqsave(&d->lock_notifications, irqflags);
list_del(&ctx->node);
spin_unlock_irqrestore(&d->lock_notifications, irqflags);
++
++ device_link_remove(dev, d->dev);
}
-EXPORT_SYMBOL(dpaa2_io_service_deregister);
+EXPORT_SYMBOL_GPL(dpaa2_io_service_deregister);
/**
* dpaa2_io_service_rearm() - Rearm the notification for the given DPIO service.
-@@ -322,7 +311,7 @@ int dpaa2_io_service_rearm(struct dpaa2_
+@@ -322,7 +331,7 @@ int dpaa2_io_service_rearm(struct dpaa2_
return err;
}
@@ -578,7 +758,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* dpaa2_io_service_pull_fq() - pull dequeue functions from a fq.
-@@ -385,7 +374,7 @@ int dpaa2_io_service_pull_channel(struct
+@@ -385,7 +394,7 @@ int dpaa2_io_service_pull_channel(struct
return err;
}
@@ -587,7 +767,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* dpaa2_io_service_enqueue_fq() - Enqueue a frame to a frame queue.
-@@ -441,7 +430,7 @@ int dpaa2_io_service_enqueue_qd(struct d
+@@ -441,7 +450,7 @@ int dpaa2_io_service_enqueue_qd(struct d
return qbman_swp_enqueue(d->swp, &ed, fd);
}
@@ -596,7 +776,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* dpaa2_io_service_release() - Release buffers to a buffer pool.
-@@ -453,7 +442,7 @@ EXPORT_SYMBOL(dpaa2_io_service_enqueue_q
+@@ -453,7 +462,7 @@ EXPORT_SYMBOL(dpaa2_io_service_enqueue_q
* Return 0 for success, and negative error code for failure.
*/
int dpaa2_io_service_release(struct dpaa2_io *d,
@@ -605,7 +785,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
const u64 *buffers,
unsigned int num_buffers)
{
-@@ -468,7 +457,7 @@ int dpaa2_io_service_release(struct dpaa
+@@ -468,7 +477,7 @@ int dpaa2_io_service_release(struct dpaa
return qbman_swp_release(d->swp, &rd, buffers, num_buffers);
}
@@ -614,7 +794,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* dpaa2_io_service_acquire() - Acquire buffers from a buffer pool.
-@@ -482,7 +471,7 @@ EXPORT_SYMBOL(dpaa2_io_service_release);
+@@ -482,7 +491,7 @@ EXPORT_SYMBOL(dpaa2_io_service_release);
* Eg. if the buffer pool is empty, this will return zero.
*/
int dpaa2_io_service_acquire(struct dpaa2_io *d,
@@ -623,7 +803,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
u64 *buffers,
unsigned int num_buffers)
{
-@@ -499,7 +488,7 @@ int dpaa2_io_service_acquire(struct dpaa
+@@ -499,7 +508,7 @@ int dpaa2_io_service_acquire(struct dpaa
return err;
}
@@ -632,7 +812,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/*
* 'Stores' are reusable memory blocks for holding dequeue results, and to
-@@ -553,7 +542,7 @@ struct dpaa2_io_store *dpaa2_io_store_cr
+@@ -553,7 +562,7 @@ struct dpaa2_io_store *dpaa2_io_store_cr
return ret;
}
@@ -641,7 +821,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* dpaa2_io_store_destroy() - Frees the dma memory storage for dequeue
-@@ -567,7 +556,7 @@ void dpaa2_io_store_destroy(struct dpaa2
+@@ -567,7 +576,7 @@ void dpaa2_io_store_destroy(struct dpaa2
kfree(s->alloced_addr);
kfree(s);
}
@@ -650,7 +830,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* dpaa2_io_store_next() - Determine when the next dequeue result is available.
-@@ -615,4 +604,177 @@ struct dpaa2_dq *dpaa2_io_store_next(str
+@@ -610,9 +619,193 @@ struct dpaa2_dq *dpaa2_io_store_next(str
+ if (!(dpaa2_dq_flags(ret) & DPAA2_DQ_STAT_VALIDFRAME))
+ ret = NULL;
+ } else {
++ prefetch(&s->vaddr[s->idx]);
+ *is_last = 0;
+ }
return ret;
}
@@ -820,10 +1006,20 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+{
+ struct qbman_eq_desc ed;
+ struct dpaa2_fd fd;
++ unsigned long irqflags;
++ int ret;
+
+ d = service_select(d);
+ if (!d)
+ return -ENODEV;
++
++ if ((d->swp->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) {
++ spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags);
++ ret = qbman_orp_drop(d->swp, orpid, seqnum);
++ spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags);
++ return ret;
++ }
++
+ qbman_eq_desc_clear(&ed);
+ qbman_eq_desc_set_orp_hole(&ed, orpid, seqnum);
+ return qbman_swp_enqueue(d->swp, &ed, &fd);
@@ -978,7 +1174,53 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
*/
#include <asm/cacheflush.h>
-@@ -99,6 +74,14 @@ enum qbman_sdqcr_fc {
+@@ -37,23 +12,26 @@
+
+ #include "qbman-portal.h"
+
+-#define QMAN_REV_4000 0x04000000
+-#define QMAN_REV_4100 0x04010000
+-#define QMAN_REV_4101 0x04010001
+-#define QMAN_REV_MASK 0xffff0000
+-
+ /* All QBMan command and result structures use this "valid bit" encoding */
+ #define QB_VALID_BIT ((u32)0x80)
+
+ /* QBMan portal management command codes */
+ #define QBMAN_MC_ACQUIRE 0x30
+ #define QBMAN_WQCHAN_CONFIGURE 0x46
++#define QBMAN_MC_ORP 0x63
+
+ /* CINH register offsets */
++#define QBMAN_CINH_SWP_EQCR_PI 0x800
+ #define QBMAN_CINH_SWP_EQAR 0x8c0
++#define QBMAN_CINH_SWP_CR_RT 0x900
++#define QBMAN_CINH_SWP_VDQCR_RT 0x940
++#define QBMAN_CINH_SWP_EQCR_AM_RT 0x980
++#define QBMAN_CINH_SWP_RCR_AM_RT 0x9c0
+ #define QBMAN_CINH_SWP_DQPI 0xa00
+ #define QBMAN_CINH_SWP_DCAP 0xac0
+ #define QBMAN_CINH_SWP_SDQCR 0xb00
++#define QBMAN_CINH_SWP_EQCR_AM_RT2 0xb40
++#define QBMAN_CINH_SWP_RCR_PI 0xc00
+ #define QBMAN_CINH_SWP_RAR 0xcc0
+ #define QBMAN_CINH_SWP_ISR 0xe00
+ #define QBMAN_CINH_SWP_IER 0xe40
+@@ -68,6 +46,13 @@
+ #define QBMAN_CENA_SWP_RR(vb) (0x700 + ((u32)(vb) >> 1))
+ #define QBMAN_CENA_SWP_VDQCR 0x780
+
++/* CENA register offsets in memory-backed mode */
++#define QBMAN_CENA_SWP_DQRR_MEM(n) (0x800 + ((u32)(n) << 6))
++#define QBMAN_CENA_SWP_RCR_MEM(n) (0x1400 + ((u32)(n) << 6))
++#define QBMAN_CENA_SWP_CR_MEM 0x1600
++#define QBMAN_CENA_SWP_RR_MEM 0x1680
++#define QBMAN_CENA_SWP_VDQCR_MEM 0x1780
++
+ /* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
+ #define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)(p) & 0x1ff) >> 6)
+
+@@ -99,6 +84,14 @@ enum qbman_sdqcr_fc {
qbman_sdqcr_fc_up_to_3 = 1
};
@@ -993,32 +1235,139 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Portal Access */
static inline u32 qbman_read_register(struct qbman_swp *p, u32 offset)
-@@ -189,7 +172,7 @@ struct qbman_swp *qbman_swp_init(const s
+@@ -121,10 +114,13 @@ static inline void *qbman_get_cmd(struct
+
+ #define SWP_CFG_DQRR_MF_SHIFT 20
+ #define SWP_CFG_EST_SHIFT 16
++#define SWP_CFG_CPBS_SHIFT 15
+ #define SWP_CFG_WN_SHIFT 14
+ #define SWP_CFG_RPM_SHIFT 12
+ #define SWP_CFG_DCM_SHIFT 10
+ #define SWP_CFG_EPM_SHIFT 8
++#define SWP_CFG_VPM_SHIFT 7
++#define SWP_CFG_CPM_SHIFT 6
+ #define SWP_CFG_SD_SHIFT 5
+ #define SWP_CFG_SP_SHIFT 4
+ #define SWP_CFG_SE_SHIFT 3
+@@ -150,6 +146,8 @@ static inline u32 qbman_set_swp_cfg(u8 m
+ ep << SWP_CFG_EP_SHIFT);
+ }
+
++#define QMAN_RT_MODE 0x00000100
++
+ /**
+ * qbman_swp_init() - Create a functional object representing the given
+ * QBMan portal descriptor.
+@@ -171,6 +169,8 @@ struct qbman_swp *qbman_swp_init(const s
+ p->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT;
+ p->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT;
+ p->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT;
++ if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000)
++ p->mr.valid_bit = QB_VALID_BIT;
+
+ atomic_set(&p->vdq.available, 1);
+ p->vdq.valid_bit = QB_VALID_BIT;
+@@ -188,8 +188,11 @@ struct qbman_swp *qbman_swp_init(const s
+ p->addr_cena = d->cena_bar;
p->addr_cinh = d->cinh_bar;
++ if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000)
++ memset(p->addr_cena, 0, 64 * 1024);
++
reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
- 1, /* Writes Non-cacheable */
+ 0, /* Writes cacheable */
0, /* EQCR_CI stashing threshold */
3, /* RPM: Valid bit mode, RCR in array mode */
2, /* DCM: Discrete consumption ack mode */
-@@ -315,6 +298,7 @@ void qbman_swp_mc_submit(struct qbman_sw
+@@ -200,6 +203,10 @@ struct qbman_swp *qbman_swp_init(const s
+ 1, /* dequeue stashing priority == TRUE */
+ 0, /* dequeue stashing enable == FALSE */
+ 0); /* EQCR_CI stashing priority == FALSE */
++ if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000)
++ reg |= 1 << SWP_CFG_CPBS_SHIFT | /* memory-backed mode */
++ 1 << SWP_CFG_VPM_SHIFT | /* VDQCR read triggered mode */
++ 1 << SWP_CFG_CPM_SHIFT; /* CR read triggered mode */
+
+ qbman_write_register(p, QBMAN_CINH_SWP_CFG, reg);
+ reg = qbman_read_register(p, QBMAN_CINH_SWP_CFG);
+@@ -208,6 +215,10 @@ struct qbman_swp *qbman_swp_init(const s
+ return NULL;
+ }
- dma_wmb();
- *v = cmd_verb | p->mc.valid_bit;
-+ dccvac(cmd);
++ if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) {
++ qbman_write_register(p, QBMAN_CINH_SWP_EQCR_PI, QMAN_RT_MODE);
++ qbman_write_register(p, QBMAN_CINH_SWP_RCR_PI, QMAN_RT_MODE);
++ }
+ /*
+ * SDQCR needs to be initialized to 0 when no channels are
+ * being dequeued from or else the QMan HW will indicate an
+@@ -302,7 +313,10 @@ void qbman_swp_interrupt_set_inhibit(str
+ */
+ void *qbman_swp_mc_start(struct qbman_swp *p)
+ {
+- return qbman_get_cmd(p, QBMAN_CENA_SWP_CR);
++ if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
++ return qbman_get_cmd(p, QBMAN_CENA_SWP_CR);
++ else
++ return qbman_get_cmd(p, QBMAN_CENA_SWP_CR_MEM);
+ }
+
+ /*
+@@ -313,8 +327,15 @@ void qbman_swp_mc_submit(struct qbman_sw
+ {
+ u8 *v = cmd;
+
+- dma_wmb();
+- *v = cmd_verb | p->mc.valid_bit;
++ if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
++ dma_wmb();
++ *v = cmd_verb | p->mc.valid_bit;
++ dccvac(cmd);
++ } else {
++ *v = cmd_verb | p->mc.valid_bit;
++ dma_wmb();
++ qbman_write_register(p, QBMAN_CINH_SWP_CR_RT, QMAN_RT_MODE);
++ }
}
/*
-@@ -325,6 +309,7 @@ void *qbman_swp_mc_result(struct qbman_s
+@@ -325,13 +346,28 @@ void *qbman_swp_mc_result(struct qbman_s
{
u32 *ret, verb;
-+ qbman_inval_prefetch(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
- ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+- ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
++ if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
++ qbman_inval_prefetch(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
++ ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
++ /* Remove the valid-bit - command completed if the rest
++ * is non-zero.
++ */
++ verb = ret[0] & ~QB_VALID_BIT;
++ if (!verb)
++ return NULL;
++ p->mc.valid_bit ^= QB_VALID_BIT;
++ } else {
++ ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR_MEM);
++ /* Command completed if the valid bit is toggled */
++ if (p->mr.valid_bit != (ret[0] & QB_VALID_BIT))
++ return NULL;
++ /* Command completed if the rest is non-zero */
++ verb = ret[0] & ~QB_VALID_BIT;
++ if (!verb)
++ return NULL;
++ p->mr.valid_bit ^= QB_VALID_BIT;
++ }
- /* Remove the valid-bit - command completed if the rest is non-zero */
-@@ -370,6 +355,43 @@ void qbman_eq_desc_set_no_orp(struct qbm
+- /* Remove the valid-bit - command completed if the rest is non-zero */
+- verb = ret[0] & ~QB_VALID_BIT;
+- if (!verb)
+- return NULL;
+- p->mc.valid_bit ^= QB_VALID_BIT;
+ return ret;
+ }
+
+@@ -370,6 +406,43 @@ void qbman_eq_desc_set_no_orp(struct qbm
d->verb |= enqueue_rejects_to_fq;
}
@@ -1062,7 +1411,26 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/*
* Exactly one of the following descriptor "targets" should be set. (Calling any
* one of these will replace the effect of any prior call to one of these.)
-@@ -429,12 +451,23 @@ int qbman_swp_enqueue(struct qbman_swp *
+@@ -408,6 +481,18 @@ void qbman_eq_desc_set_qd(struct qbman_e
+ #define EQAR_VB(eqar) ((eqar) & 0x80)
+ #define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
+
++static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p,
++ u8 idx)
++{
++ if (idx < 16)
++ qbman_write_register(p, QBMAN_CINH_SWP_EQCR_AM_RT + idx * 4,
++ QMAN_RT_MODE);
++ else
++ qbman_write_register(p, QBMAN_CINH_SWP_EQCR_AM_RT2 +
++ (idx - 16) * 4,
++ QMAN_RT_MODE);
++}
++
+ /**
+ * qbman_swp_enqueue() - Issue an enqueue command
+ * @s: the software portal used for enqueue
+@@ -429,12 +514,29 @@ int qbman_swp_enqueue(struct qbman_swp *
return -EBUSY;
p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
@@ -1080,14 +1448,23 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ memcpy(&p->tgtid, &d->tgtid, 24);
memcpy(&p->fd, fd, sizeof(*fd));
- /* Set the verb byte, have to substitute in the valid-bit */
- dma_wmb();
- p->verb = d->verb | EQAR_VB(eqar);
-+ dccvac(p);
+- /* Set the verb byte, have to substitute in the valid-bit */
+- dma_wmb();
+- p->verb = d->verb | EQAR_VB(eqar);
++ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
++ /* Set the verb byte, have to substitute in the valid-bit */
++ dma_wmb();
++ p->verb = d->verb | EQAR_VB(eqar);
++ dccvac(p);
++ } else {
++ p->verb = d->verb | EQAR_VB(eqar);
++ dma_wmb();
++ qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar));
++ }
return 0;
}
-@@ -522,7 +555,7 @@ void qbman_pull_desc_set_storage(struct
+@@ -522,7 +624,7 @@ void qbman_pull_desc_set_storage(struct
int stash)
{
/* save the virtual address */
@@ -1096,24 +1473,43 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
if (!storage) {
d->verb &= ~(1 << QB_VDQCR_VERB_RLS_SHIFT);
-@@ -615,7 +648,7 @@ int qbman_swp_pull(struct qbman_swp *s,
+@@ -615,18 +717,28 @@ int qbman_swp_pull(struct qbman_swp *s,
atomic_inc(&s->vdq.available);
return -EBUSY;
}
- s->vdq.storage = (void *)d->rsp_addr_virt;
+- p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR);
+ s->vdq.storage = (void *)(uintptr_t)d->rsp_addr_virt;
- p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR);
++ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
++ p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR);
++ else
++ p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR_MEM);
p->numf = d->numf;
p->tok = QMAN_DQ_TOKEN_VALID;
-@@ -627,6 +660,7 @@ int qbman_swp_pull(struct qbman_swp *s,
- /* Set the verb byte, have to substitute in the valid-bit */
- p->verb = d->verb | s->vdq.valid_bit;
- s->vdq.valid_bit ^= QB_VALID_BIT;
-+ dccvac(p);
+ p->dq_src = d->dq_src;
+ p->rsp_addr = d->rsp_addr;
+ p->rsp_addr_virt = d->rsp_addr_virt;
+- dma_wmb();
+-
+- /* Set the verb byte, have to substitute in the valid-bit */
+- p->verb = d->verb | s->vdq.valid_bit;
+- s->vdq.valid_bit ^= QB_VALID_BIT;
++ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
++ dma_wmb();
++ /* Set the verb byte, have to substitute in the valid-bit */
++ p->verb = d->verb | s->vdq.valid_bit;
++ s->vdq.valid_bit ^= QB_VALID_BIT;
++ dccvac(p);
++ } else {
++ p->verb = d->verb | s->vdq.valid_bit;
++ s->vdq.valid_bit ^= QB_VALID_BIT;
++ dma_wmb();
++ qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE);
++ }
return 0;
}
-@@ -680,8 +714,7 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne
+@@ -680,11 +792,13 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne
s->dqrr.next_idx, pi);
s->dqrr.reset_bug = 0;
}
@@ -1122,8 +1518,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
}
- p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
-@@ -696,8 +729,7 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne
+- p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
++ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
++ p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
++ else
++ p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx));
+ verb = p->dq.verb;
+
+ /*
+@@ -696,8 +810,7 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne
* knew from reading PI.
*/
if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
@@ -1133,7 +1536,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return NULL;
}
/*
-@@ -720,7 +752,7 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne
+@@ -720,7 +833,7 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne
(flags & DPAA2_DQ_STAT_EXPIRED))
atomic_inc(&s->vdq.available);
@@ -1142,15 +1545,44 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return p;
}
-@@ -848,6 +880,7 @@ int qbman_swp_release(struct qbman_swp *
- */
- dma_wmb();
- p->verb = d->verb | RAR_VB(rar) | num_buffers;
-+ dccvac(p);
+@@ -836,18 +949,29 @@ int qbman_swp_release(struct qbman_swp *
+ return -EBUSY;
+
+ /* Start the release command */
+- p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
++ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
++ p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
++ else
++ p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar)));
+ /* Copy the caller's buffer pointers to the command */
+ for (i = 0; i < num_buffers; i++)
+ p->buf[i] = cpu_to_le64(buffers[i]);
+ p->bpid = d->bpid;
+
+- /*
+- * Set the verb byte, have to substitute in the valid-bit and the number
+- * of buffers.
+- */
+- dma_wmb();
+- p->verb = d->verb | RAR_VB(rar) | num_buffers;
++ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
++ /*
++ * Set the verb byte, have to substitute in the valid-bit
++ * and the number of buffers.
++ */
++ dma_wmb();
++ p->verb = d->verb | RAR_VB(rar) | num_buffers;
++ dccvac(p);
++ } else {
++ p->verb = d->verb | RAR_VB(rar) | num_buffers;
++ dma_wmb();
++ qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT +
++ RAR_IDX(rar) * 4, QMAN_RT_MODE);
++ }
return 0;
}
-@@ -855,7 +888,7 @@ int qbman_swp_release(struct qbman_swp *
+@@ -855,7 +979,7 @@ int qbman_swp_release(struct qbman_swp *
struct qbman_acquire_desc {
u8 verb;
u8 reserved;
@@ -1159,7 +1591,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
u8 num;
u8 reserved2[59];
};
-@@ -863,10 +896,10 @@ struct qbman_acquire_desc {
+@@ -863,10 +987,10 @@ struct qbman_acquire_desc {
struct qbman_acquire_rslt {
u8 verb;
u8 rslt;
@@ -1172,7 +1604,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
};
/**
-@@ -929,7 +962,7 @@ int qbman_swp_acquire(struct qbman_swp *
+@@ -929,7 +1053,7 @@ int qbman_swp_acquire(struct qbman_swp *
struct qbman_alt_fq_state_desc {
u8 verb;
u8 reserved[3];
@@ -1181,7 +1613,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
u8 reserved2[56];
};
-@@ -952,7 +985,7 @@ int qbman_swp_alt_fq_state(struct qbman_
+@@ -952,7 +1076,7 @@ int qbman_swp_alt_fq_state(struct qbman_
if (!p)
return -EBUSY;
@@ -1190,7 +1622,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Complete the management command */
r = qbman_swp_mc_complete(s, p, alt_fq_verb);
-@@ -978,11 +1011,11 @@ int qbman_swp_alt_fq_state(struct qbman_
+@@ -978,11 +1102,11 @@ int qbman_swp_alt_fq_state(struct qbman_
struct qbman_cdan_ctrl_desc {
u8 verb;
u8 reserved;
@@ -1205,7 +1637,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
u8 reserved3[48];
};
-@@ -990,7 +1023,7 @@ struct qbman_cdan_ctrl_desc {
+@@ -990,7 +1114,7 @@ struct qbman_cdan_ctrl_desc {
struct qbman_cdan_ctrl_rslt {
u8 verb;
u8 rslt;
@@ -1214,10 +1646,12 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
u8 reserved[60];
};
-@@ -1033,3 +1066,99 @@ int qbman_swp_CDAN_set(struct qbman_swp
+@@ -1031,5 +1155,152 @@ int qbman_swp_CDAN_set(struct qbman_swp
+ return -EIO;
+ }
- return 0;
- }
++ return 0;
++}
+
+#define QBMAN_RESPONSE_VERB_MASK 0x7f
+#define QBMAN_FQ_QUERY_NP 0x45
@@ -1314,13 +1748,65 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+{
+ return le32_to_cpu(a->fill);
+}
++
++struct qbman_orp_cmd_desc {
++ u8 verb;
++ u8 reserved;
++ u8 cid;
++ u8 reserved2;
++ u16 orpid;
++ u16 seqnum;
++ u8 reserved3[56];
++};
++
++struct qbman_orp_cmd_rslt {
++ u8 verb;
++ u8 rslt;
++ u8 cid;
++ u8 reserved1[61];
++};
++
++int qbman_orp_drop(struct qbman_swp *s, u16 orpid, u16 seqnum)
++{
++ struct qbman_orp_cmd_desc *p;
++ struct qbman_orp_cmd_rslt *r;
++ void *resp;
++
++ p = (struct qbman_orp_cmd_desc *)qbman_swp_mc_start(s);
++ if (!p)
++ return -EBUSY;
++
++ p->cid = 0x7;
++ p->orpid = cpu_to_le16(orpid);
++ p->seqnum = cpu_to_le16(seqnum);
++
++ resp = qbman_swp_mc_complete(s, p, QBMAN_MC_ORP);
++ if (!resp) {
++ pr_err("qbman: Drop sequence num %d orpid 0x%x failed, no response\n",
++ seqnum, orpid);
++ return -EIO;
++ }
++ r = (struct qbman_orp_cmd_rslt *)resp;
++ /* Decode the outcome */
++ WARN_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ORP);
++
++ /* Determine success or failure */
++ if (r->rslt != QBMAN_MC_RSLT_OK) {
++ pr_err("Drop seqnum %d of prpid 0x%x failed, code=0x%02x\n",
++ seqnum, orpid, r->rslt);
++ return -EIO;
++ }
++
+ return 0;
+ }
--- a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.h
+++ b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.h
-@@ -1,33 +1,8 @@
+@@ -1,46 +1,28 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/*
* Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- * Copyright 2016 NXP
+- * Copyright 2016 NXP
++ * Copyright 2016-2019 NXP
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
@@ -1351,7 +1837,28 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
*/
#ifndef __FSL_QBMAN_PORTAL_H
#define __FSL_QBMAN_PORTAL_H
-@@ -57,8 +32,8 @@ struct qbman_pull_desc {
+
+ #include "../../include/dpaa2-fd.h"
+
++#define QMAN_REV_4000 0x04000000
++#define QMAN_REV_4100 0x04010000
++#define QMAN_REV_4101 0x04010001
++#define QMAN_REV_5000 0x05000000
++
++#define QMAN_REV_MASK 0xffff0000
++
+ struct dpaa2_dq;
+ struct qbman_swp;
+
+ /* qbman software portal descriptor structure */
+ struct qbman_swp_desc {
+ void *cena_bar; /* Cache-enabled portal base address */
+- void *cinh_bar; /* Cache-inhibited portal base address */
++ void __iomem *cinh_bar; /* Cache-inhibited portal base address */
+ u32 qman_version;
+ };
+
+@@ -57,8 +39,8 @@ struct qbman_pull_desc {
u8 numf;
u8 tok;
u8 reserved;
@@ -1362,7 +1869,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
u64 rsp_addr_virt;
u8 padding[40];
};
-@@ -95,17 +70,17 @@ enum qbman_pull_type_e {
+@@ -95,17 +77,17 @@ enum qbman_pull_type_e {
struct qbman_eq_desc {
u8 verb;
u8 dca;
@@ -1387,7 +1894,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
u8 fd[32];
};
-@@ -113,9 +88,9 @@ struct qbman_eq_desc {
+@@ -113,9 +95,9 @@ struct qbman_eq_desc {
struct qbman_release_desc {
u8 verb;
u8 reserved;
@@ -1400,7 +1907,28 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
};
/* Management command result codes */
-@@ -187,6 +162,9 @@ int qbman_result_has_new_result(struct q
+@@ -127,7 +109,7 @@ struct qbman_release_desc {
+ /* portal data structure */
+ struct qbman_swp {
+ const struct qbman_swp_desc *desc;
+- void __iomem *addr_cena;
++ void *addr_cena;
+ void __iomem *addr_cinh;
+
+ /* Management commands */
+@@ -135,6 +117,11 @@ struct qbman_swp {
+ u32 valid_bit; /* 0x00 or 0x80 */
+ } mc;
+
++ /* Management response */
++ struct {
++ u32 valid_bit; /* 0x00 or 0x80 */
++ } mr;
++
+ /* Push dequeues */
+ u32 sdq;
+
+@@ -187,6 +174,9 @@ int qbman_result_has_new_result(struct q
void qbman_eq_desc_clear(struct qbman_eq_desc *d);
void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
@@ -1410,7 +1938,25 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
void qbman_eq_desc_set_token(struct qbman_eq_desc *d, u8 token);
void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid);
void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
-@@ -466,4 +444,62 @@ static inline void *qbman_swp_mc_complet
+@@ -195,6 +185,8 @@ void qbman_eq_desc_set_qd(struct qbman_e
+ int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd);
+
++int qbman_orp_drop(struct qbman_swp *s, u16 orpid, u16 seqnum);
++
+ void qbman_release_desc_clear(struct qbman_release_desc *d);
+ void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid);
+ void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
+@@ -453,7 +445,7 @@ static inline int qbman_swp_CDAN_set_con
+ static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
+ u8 cmd_verb)
+ {
+- int loopvar = 1000;
++ int loopvar = 2000;
+
+ qbman_swp_mc_submit(swp, cmd, cmd_verb);
+
+@@ -466,4 +458,62 @@ static inline void *qbman_swp_mc_complet
return cmd;
}
@@ -2112,7 +2658,21 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
*/
#ifndef __FSL_DPAA2_IO_H
#define __FSL_DPAA2_IO_H
-@@ -88,6 +63,8 @@ void dpaa2_io_down(struct dpaa2_io *d);
+@@ -77,17 +52,20 @@ struct dpaa2_io_desc {
+ int has_8prio;
+ int cpu;
+ void *regs_cena;
+- void *regs_cinh;
++ void __iomem *regs_cinh;
+ int dpio_id;
+ u32 qman_version;
+ };
+
+-struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc);
++struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc,
++ struct device *dev);
+
+ void dpaa2_io_down(struct dpaa2_io *d);
irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj);
@@ -2121,7 +2681,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* struct dpaa2_io_notification_ctx - The DPIO notification context structure
* @cb: The callback to be invoked when the notification arrives
-@@ -103,7 +80,7 @@ irqreturn_t dpaa2_io_irq(struct dpaa2_io
+@@ -103,7 +81,7 @@ irqreturn_t dpaa2_io_irq(struct dpaa2_io
* Used when a FQDAN/CDAN registration is made by drivers.
*/
struct dpaa2_io_notification_ctx {
@@ -2130,7 +2690,24 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
int is_cdan;
u32 id;
int desired_cpu;
-@@ -129,9 +106,9 @@ int dpaa2_io_service_enqueue_fq(struct d
+@@ -113,10 +91,14 @@ struct dpaa2_io_notification_ctx {
+ void *dpio_private;
+ };
+
++int dpaa2_io_get_cpu(struct dpaa2_io *d);
++
+ int dpaa2_io_service_register(struct dpaa2_io *service,
+- struct dpaa2_io_notification_ctx *ctx);
++ struct dpaa2_io_notification_ctx *ctx,
++ struct device *dev);
+ void dpaa2_io_service_deregister(struct dpaa2_io *service,
+- struct dpaa2_io_notification_ctx *ctx);
++ struct dpaa2_io_notification_ctx *ctx,
++ struct device *dev);
+ int dpaa2_io_service_rearm(struct dpaa2_io *service,
+ struct dpaa2_io_notification_ctx *ctx);
+
+@@ -129,9 +111,9 @@ int dpaa2_io_service_enqueue_fq(struct d
const struct dpaa2_fd *fd);
int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio,
u16 qdbin, const struct dpaa2_fd *fd);
@@ -2142,7 +2719,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
u64 *buffers, unsigned int num_buffers);
struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
-@@ -139,4 +116,64 @@ struct dpaa2_io_store *dpaa2_io_store_cr
+@@ -139,4 +121,64 @@ struct dpaa2_io_store *dpaa2_io_store_cr
void dpaa2_io_store_destroy(struct dpaa2_io_store *s);
struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last);