2020-07-21 22:39:09

by Suman Anna

[permalink] [raw]
Subject: [PATCH v5 0/6] TI K3 DSP remoteproc driver for C66x DSPs

Hi All,

The following is v5 of the K3 DSP remoteproc driver supporting the C66x DSPs
on the TI K3 J721E SoCs. The patches apply cleanly both on v5.8-rc1 as well
as on latest HEAD of rproc-next branch. The C71x v3 still applies cleanly on
top of this series.

The main changes are on the bindings. The previously added common
ti,k3-sci-rproc.yaml remoteproc binding (v4 patch#3) is replaced by an
equivalent generic ti,k3-sci-common.yaml binding (patch #1) that can scale
to other TI SCI controller nodes. As such, I have relocated the file to
Documentation/devicetree/bindings/arm/keystone folder instead of the
remoteproc folder. Driver patches are unchanged.

Please see the v4 cover-letter and individual patches for further delta
differences.

v4: https://patchwork.kernel.org/cover/11671459/
v3: https://patchwork.kernel.org/cover/11602331/
v2: https://patchwork.kernel.org/cover/11561787/
v1: https://patchwork.kernel.org/cover/11458573/

C71x v3: https://patchwork.kernel.org/cover/11602345/

regards
Suman

Suman Anna (6):
dt-bindings: arm: keystone: Add common TI SCI bindings
remoteproc: Introduce rproc_of_parse_firmware() helper
remoteproc: k3: Add TI-SCI processor control helper functions
dt-bindings: remoteproc: Add bindings for C66x DSPs on TI K3 SoCs
remoteproc: k3-dsp: Add a remoteproc driver of K3 C66x DSPs
remoteproc: k3-dsp: Add support for L2RAM loading on C66x DSPs

.../arm/keystone/ti,k3-sci-common.yaml | 44 +
.../bindings/remoteproc/ti,k3-dsp-rproc.yaml | 142 ++++
MAINTAINERS | 1 +
drivers/remoteproc/Kconfig | 13 +
drivers/remoteproc/Makefile | 1 +
drivers/remoteproc/remoteproc_core.c | 23 +
drivers/remoteproc/remoteproc_internal.h | 2 +
drivers/remoteproc/ti_k3_dsp_remoteproc.c | 771 ++++++++++++++++++
drivers/remoteproc/ti_sci_proc.h | 104 +++
9 files changed, 1101 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/keystone/ti,k3-sci-common.yaml
create mode 100644 Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml
create mode 100644 drivers/remoteproc/ti_k3_dsp_remoteproc.c
create mode 100644 drivers/remoteproc/ti_sci_proc.h

--
2.26.0


2020-07-21 22:39:45

by Suman Anna

[permalink] [raw]
Subject: [PATCH v5 6/6] remoteproc: k3-dsp: Add support for L2RAM loading on C66x DSPs

The resets for the DSP processors on K3 SoCs are managed through the
Power and Sleep Controller (PSC) module. Each DSP typically has two
resets - a global module reset for powering on the device, and a local
reset that affects only the CPU while allowing access to the other
sub-modules within the DSP processor sub-systems.

The C66x DSPs have two levels of internal RAMs that can be used to
boot from, and the firmware loading into these RAMs require the
local reset to be asserted with the device powered on/enabled using
the module reset. Enhance the K3 DSP remoteproc driver to add support
for loading into the internal RAMs. The local reset is deasserted on
SoC power-on-reset, so logic has to be added in probe in remoteproc
mode to balance the remoteproc state-machine.

Note that the local resets are a no-op on C71x cores, and the hardware
does not supporting loading into its internal RAMs.

Signed-off-by: Suman Anna <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
Reviewed-by: Mathieu Poirier <[email protected]>
---
v4, v5: No changes
v3: https://patchwork.kernel.org/patch/11602323/

drivers/remoteproc/ti_k3_dsp_remoteproc.c | 72 +++++++++++++++++++++++
1 file changed, 72 insertions(+)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 18f714b012df..43566ead7a1d 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -174,6 +174,9 @@ static int k3_dsp_rproc_reset(struct k3_dsp_rproc *kproc)
return ret;
}

+ if (kproc->data->uses_lreset)
+ return ret;
+
ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
kproc->ti_sci_id);
if (ret) {
@@ -191,6 +194,9 @@ static int k3_dsp_rproc_release(struct k3_dsp_rproc *kproc)
struct device *dev = kproc->dev;
int ret;

+ if (kproc->data->uses_lreset)
+ goto lreset;
+
ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,
kproc->ti_sci_id);
if (ret) {
@@ -198,6 +204,7 @@ static int k3_dsp_rproc_release(struct k3_dsp_rproc *kproc)
return ret;
}

+lreset:
ret = reset_control_deassert(kproc->reset);
if (ret) {
dev_err(dev, "local-reset deassert failed, ret = %d\n", ret);
@@ -209,6 +216,53 @@ static int k3_dsp_rproc_release(struct k3_dsp_rproc *kproc)
return ret;
}

+/*
+ * The C66x DSP cores have a local reset that affects only the CPU, and a
+ * generic module reset that powers on the device and allows the DSP internal
+ * memories to be accessed while the local reset is asserted. This function is
+ * used to release the global reset on C66x DSPs to allow loading into the DSP
+ * internal RAMs. The .prepare() ops is invoked by remoteproc core before any
+ * firmware loading, and is followed by the .start() ops after loading to
+ * actually let the C66x DSP cores run.
+ */
+static int k3_dsp_rproc_prepare(struct rproc *rproc)
+{
+ struct k3_dsp_rproc *kproc = rproc->priv;
+ struct device *dev = kproc->dev;
+ int ret;
+
+ ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,
+ kproc->ti_sci_id);
+ if (ret)
+ dev_err(dev, "module-reset deassert failed, cannot enable internal RAM loading, ret = %d\n",
+ ret);
+
+ return ret;
+}
+
+/*
+ * This function implements the .unprepare() ops and performs the complimentary
+ * operations to that of the .prepare() ops. The function is used to assert the
+ * global reset on applicable C66x cores. This completes the second portion of
+ * powering down the C66x DSP cores. The cores themselves are only halted in the
+ * .stop() callback through the local reset, and the .unprepare() ops is invoked
+ * by the remoteproc core after the remoteproc is stopped to balance the global
+ * reset.
+ */
+static int k3_dsp_rproc_unprepare(struct rproc *rproc)
+{
+ struct k3_dsp_rproc *kproc = rproc->priv;
+ struct device *dev = kproc->dev;
+ int ret;
+
+ ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
+ kproc->ti_sci_id);
+ if (ret)
+ dev_err(dev, "module-reset assert failed, ret = %d\n", ret);
+
+ return ret;
+}
+
/*
* Power up the DSP remote processor.
*
@@ -352,6 +406,8 @@ static void *k3_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len)
}

static const struct rproc_ops k3_dsp_rproc_ops = {
+ .prepare = k3_dsp_rproc_prepare,
+ .unprepare = k3_dsp_rproc_unprepare,
.start = k3_dsp_rproc_start,
.stop = k3_dsp_rproc_stop,
.kick = k3_dsp_rproc_kick,
@@ -612,6 +668,22 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
goto release_tsp;
}

+ /*
+ * ensure the DSP local reset is asserted to ensure the DSP doesn't
+ * execute bogus code in .prepare() when the module reset is released.
+ */
+ if (data->uses_lreset) {
+ ret = reset_control_status(kproc->reset);
+ if (ret < 0) {
+ dev_err(dev, "failed to get reset status, status = %d\n",
+ ret);
+ goto release_mem;
+ } else if (ret == 0) {
+ dev_warn(dev, "local reset is deasserted for device\n");
+ k3_dsp_rproc_reset(kproc);
+ }
+ }
+
ret = rproc_add(rproc);
if (ret) {
dev_err(dev, "failed to add register device with remoteproc core, status = %d\n",
--
2.26.0