TEMP: remoteproc/omap: add "late attach" support
authorRobert Tivy <rtivy@ti.com>
Thu, 12 Sep 2019 17:45:10 +0000 (17:45 +0000)
committerSuman Anna <s-anna@ti.com>
Mon, 23 Sep 2019 01:47:33 +0000 (20:47 -0500)
Add the necessary support in the OMAP remoteproc driver to enable the
"late attach" functionality. The 'late attach' functionality has the
processors already loaded and running by the time the kernel has booted.

The 'late attach' support in OMAP remoteproc driver is added through
minimal changes like skipping the releasing of the processor reset.
The processor reset is skipped as this relies on the omap_hwmod /
omap_device API which perform a module disable/enable sequence in
addition to the reset programming. Other required functionality is
achieved through the late attach support in the remoteproc driver core.

During late attach, we use non-zeroing dma ops to prevent the kernel
from overwriting already loaded code and data segments. When shutting
down the processor, we restore the normal zeroing dma ops.  This allows
the kernel to clear memory when loading a new remoteproc binary or
during error recovery with the current remoteproc binary.

The 'late attach' capability is determined through a .device_is_enabled
pdata ops. The rproc nodes along with the corresponding IOMMU and timer
nodes should all have the "ti,no-idle-on-init" and "ti,no-reset-on-init"
properties set to prevent omap_hwmod from resetting and idling these
devices on boot.

The .late_attach field in the rproc data structure is used to denote
the mode and differentiate a normal boot from a late-attach boot. The
late_attach functionality is relevant only for the first time boot of
the kernel, and will be reset for subsequent probes of the remoteproc
node. The flag is also reset during the stopping of the remoteproc,
so that any error recovery results in a regular boot.

TODO:
Move away from modifying the dma_ops for the device completely.

Signed-off-by: Robert Tivy <rtivy@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Venkateswara Rao Mandela <venkat.mandela@ti.com>
Signed-off-by: Angela Stegmaier <angelabaker@ti.com>
Signed-off-by: Shravan Karthik <shravan.karthik@ti.com>
Signed-off-by: Keerthy <j-keerthy@ti.com>
drivers/remoteproc/omap_remoteproc.c

index aa325c8c5fae83d7b066ef933a2f190191d7d2ee..731986d026c40840ed71447a7bd5a880a353b04f 100644 (file)
@@ -573,6 +573,10 @@ static int omap_rproc_start(struct rproc *rproc)
        int ret;
        struct mbox_client *client = &oproc->client;
 
        int ret;
        struct mbox_client *client = &oproc->client;
 
+       /*
+        * We set boot address irrespective of the value of the late attach flag
+        * as boot address takes effect only on a deassert of remoteproc reset.
+        */
        if (oproc->boot_data) {
                ret = omap_rproc_write_dsp_boot_addr(rproc);
                if (ret)
        if (oproc->boot_data) {
                ret = omap_rproc_write_dsp_boot_addr(rproc);
                if (ret)
@@ -612,10 +616,12 @@ static int omap_rproc_start(struct rproc *rproc)
                goto put_mbox;
        }
 
                goto put_mbox;
        }
 
-       ret = pdata->device_enable(pdev);
-       if (ret) {
-               dev_err(dev, "omap_device_enable failed: %d\n", ret);
-               goto reset_timers;
+       if (!rproc->late_attach) {
+               ret = pdata->device_enable(pdev);
+               if (ret) {
+                       dev_err(dev, "omap_device_enable failed: %d\n", ret);
+                       goto reset_timers;
+               }
        }
 
        /*
        }
 
        /*
@@ -671,6 +677,16 @@ static int omap_rproc_stop(struct rproc *rproc)
        if (ret)
                goto enable_device;
 
        if (ret)
                goto enable_device;
 
+       /*
+        * During late attach, we use non-zeroing dma ops to prevent the kernel
+        * from overwriting already loaded code and data segments. When
+        * shutting down the processor, we restore the normal zeroing dma ops.
+        * This allows the kernel to clear memory when loading a new remoteproc
+        * binary or during error recovery with the current remoteproc binary.
+        */
+       if (rproc->late_attach)
+               set_dma_ops(dev, &arm_dma_ops);
+
        mbox_free_channel(oproc->mbox);
 
        /*
        mbox_free_channel(oproc->mbox);
 
        /*
@@ -1310,6 +1326,11 @@ static int omap_rproc_probe(struct platform_device *pdev)
        if (!rproc)
                return -ENOMEM;
 
        if (!rproc)
                return -ENOMEM;
 
+       if (pdata->device_is_enabled && pdata->device_is_enabled(pdev)) {
+               rproc->late_attach = 1;
+               set_dma_ops(&pdev->dev, &arm_dma_m_ops);
+       }
+
        oproc = rproc->priv;
        oproc->rproc = rproc;
        /* All existing OMAP IPU and DSP processors have an MMU */
        oproc = rproc->priv;
        oproc->rproc = rproc;
        /* All existing OMAP IPU and DSP processors have an MMU */
@@ -1398,6 +1419,8 @@ static int omap_rproc_probe(struct platform_device *pdev)
 release_mem:
        of_reserved_mem_device_release(&pdev->dev);
 free_rproc:
 release_mem:
        of_reserved_mem_device_release(&pdev->dev);
 free_rproc:
+       if (rproc->late_attach)
+               set_dma_ops(&pdev->dev, &arm_dma_ops);
        rproc_free(rproc);
        return ret;
 }
        rproc_free(rproc);
        return ret;
 }