MLK-19772: ISI: fill ISI out buffer address before enabling ISI channel
authorGuoniu.Zhou <guoniu.zhou@nxp.com>
Sat, 29 Sep 2018 03:54:03 +0000 (11:54 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
1. Before enabling ISI channel, driver need to fill its out buffer
address, so correct this sequence

2. Because ISI use ping-pong buffer and write data to memory with
BUF1->BUF2->BUF1... sequence. If it finish with BUF1 and user start
a new capture process, it will start with BUF2. This will lead the
buffer ready for being read is not equal to buffer written by ISI.So
HW reset ISI, in order to confirm it start with BUF1.

Signed-off-by: Guoniu.Zhou <guoniu.zhou@nxp.com>
(cherry picked from commit 794ce0cb7d7f129fb46f5d6f38e82cc1e7f2a367)

drivers/media/platform/imx8/mxc-isi-hw.c

index b3ed9cd..7e117a9 100644 (file)
@@ -190,7 +190,9 @@ void mxc_isi_channel_hw_reset(struct mxc_isi_dev *mxc_isi)
 {
        sc_ipc_t ipcHndl;
        sc_err_t sciErr;
-       uint32_t mu_id;
+       uint32_t mu_id, ch_id, i;
+       uint8_t chan_mask = 0, temp_mask;
+       struct device_node *parent, *node;
 
        sciErr = sc_ipc_getMuID(&mu_id);
        if (sciErr != SC_ERR_NONE) {
@@ -204,16 +206,40 @@ void mxc_isi_channel_hw_reset(struct mxc_isi_dev *mxc_isi)
                return;
        }
 
-       sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_ISI_CH0, SC_PM_PW_MODE_OFF);
-       if (sciErr != SC_ERR_NONE)
-               pr_err("sc_misc_MIPI reset failed! (sciError = %d)\n", sciErr);
+       parent = of_get_parent(mxc_isi->pdev->dev.of_node);
+       if (!parent) {
+               dev_err(&mxc_isi->pdev->dev, "get parent device fail\n");
+               return;
+       }
 
-       sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_ISI_CH0, SC_PM_PW_MODE_ON);
-       if (sciErr != SC_ERR_NONE)
-               pr_err("sc_misc_MIPI reset failed! (sciError = %d)\n", sciErr);
+       for_each_available_child_of_node(parent, node) {
+               if (!strcmp(node->name, ISI_OF_NODE_NAME)) {
+                       ch_id = of_alias_get_id(node, "isi");
+                       chan_mask |= 1 << ch_id;
+               }
+       }
 
-       udelay(500);
+       temp_mask = chan_mask;
+       for (i = 0; i < 8; i++) {
+               if (chan_mask & 0x1) {
+                       sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_ISI_CH0 + i, SC_PM_PW_MODE_OFF);
+                       if (sciErr != SC_ERR_NONE)
+                               pr_err("power on ISI%d failed! (sciError = %d)\n", i, sciErr);
+               }
+               chan_mask >>= 1;
+       }
 
+       chan_mask = temp_mask;
+       for (i = 0; i < 8; i++) {
+               if (chan_mask & 0x1) {
+                       sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_ISI_CH0 + i, SC_PM_PW_MODE_ON);
+                       if (sciErr != SC_ERR_NONE)
+                               pr_err("power off ISI%d failed! (sciError = %d)\n", i, sciErr);
+               }
+               chan_mask >>= 1;
+       }
+
+       udelay(500);
        sc_ipc_close(mu_id);
 }