Browse Source

remoteproc/k3-dsp: add support for IPC-only mode for all K3 DSPs

Add support to the K3 DSP remoteproc driver to configure all the C66x
and C71x cores on J721E SoCs to be either in IPC-only mode or the
traditional remoteproc mode. The IPC-only mode expects that the remote
processors are already booted by the bootloader, and only perform the
minimum steps required to initialize and deinitialize the virtio IPC
transports. The remoteproc mode allows the kernel remoteproc driver to
do the regular load and boot and other device management operations for
a DSP.

The IPC-only mode for a DSP is detected and configured at driver probe
time by querying the System Firmware for the DSP power and reset state
and/or status and making sure that the DSP is indeed started by the
bootloaders, otherwise the device is configured for remoteproc mode.

Support for IPC-only mode is achieved through various flags in both
remoteproc core and the DSP remoteproc driver. The support in remoteproc
core for this is added in commit 20afed1b45bf ("remoteproc: add
infrastructure support to allow pre-loaded remoteprocs"). The support
requires that the firmware still be requested to process the resource
table for retrieving the virtio device and trace resource entries.

NOTE:
 - The driver cannot configure a DSP for remoteproc mode by any
   means without rebooting the kernel if that DSP has been started
   by a bootloader.
 - The resource table address retrieval logic can actually be done by
   providing the data through device tree (thereby bypassing the need to
   request the firmware), with the bootloader adding and/or updating the
   necessary DT properties. Another option is to use a design-by-contract
   approach of having the resource table located at a specific offset
   within one of the memory regions. This will be optimized for in
   the future.

Signed-off-by: Suman Anna <s-anna@ti.com>
Suman Anna 6 years ago
parent
commit
7e3cb7682d
1 changed files with 39 additions and 0 deletions
  1. 39 0
      drivers/remoteproc/ti_k3_dsp_remoteproc.c

+ 39 - 0
drivers/remoteproc/ti_k3_dsp_remoteproc.c

@@ -51,6 +51,7 @@ struct k3_dsp_rproc_mem {
  * @ti_sci_id: TI-SCI device identifier
  * @mbox: mailbox channel handle
  * @client: mailbox client to request the mailbox channel
+ * @ipc_only: flag to indicate IPC-only mode
  */
 struct k3_dsp_rproc {
 	struct device *dev;
@@ -65,6 +66,7 @@ struct k3_dsp_rproc {
 	u32 ti_sci_id;
 	struct mbox_chan *mbox;
 	struct mbox_client client;
+	unsigned int ipc_only : 1;
 };
 
 /**
@@ -241,6 +243,15 @@ static int k3_dsp_rproc_start(struct rproc *rproc)
 		goto put_mbox;
 	}
 
+	/*
+	 * no need to issue TI-SCI commands to configure and boot the DSP cores
+	 * in IPC-only mode.
+	 */
+	if (kproc->ipc_only) {
+		dev_err(dev, "DSP initialized in IPC-only mode\n");
+		return 0;
+	}
+
 	boot_addr = rproc->bootaddr;
 	if (boot_addr & (SZ_1K - 1)) {
 		dev_err(dev, "invalid boot address 0x%x, must be aligned on a 1KB boundary\n",
@@ -277,6 +288,15 @@ static int k3_dsp_rproc_stop(struct rproc *rproc)
 
 	mbox_free_channel(kproc->mbox);
 
+	/*
+	 * no need to issue TI-SCI commands to stop the DSP core
+	 * in IPC-only mode.
+	 */
+	if (kproc->ipc_only) {
+		dev_err(kproc->dev, "DSP deinitialized in IPC-only mode\n");
+		return 0;
+	}
+
 	k3_dsp_rproc_reset(kproc);
 
 	return 0;
@@ -550,6 +570,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
 	struct k3_dsp_rproc *kproc;
 	struct rproc *rproc;
 	const char *fw_name;
+	bool r_state = false;
+	bool p_state = false;
 	int ret = 0;
 	int ret1;
 
@@ -636,6 +658,23 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
 		goto disable_clk;
 	}
 
+	ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
+					       &r_state, &p_state);
+	if (ret) {
+		dev_err(dev, "failed to get initial state, mode cannot be determined, ret = %d\n",
+			ret);
+		goto release_mem;
+	}
+
+	/* configure J721E devices for either remoteproc or IPC-only mode */
+	if (p_state) {
+		dev_err(dev, "configured DSP for IPC-only mode\n");
+		rproc->skip_load = 1;
+		kproc->ipc_only = 1;
+	} else {
+		dev_err(dev, "configured DSP for remoteproc mode\n");
+	}
+
 	ret = rproc_add(rproc);
 	if (ret) {
 		dev_err(dev, "failed to add register device with remoteproc core, status = %d\n",