media: mtk-vpu: dump VPU status when IPI times out
authorIrui Wang <irui.wang@mediatek.com>
Thu, 29 Oct 2020 01:17:21 +0000 (02:17 +0100)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Thu, 3 Dec 2020 06:42:34 +0000 (07:42 +0100)
when IPI time out, dump VPU status to get more debug information

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
Reviewed-by: Alexandre Courbot <acourbot@chromium.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/platform/mtk-vpu/mtk_vpu.c

index 86ab808ba877ecb44df727559023112b8615efb3..043894f7188c80092e9c3c797c3c4ceb81e4e27c 100644 (file)
@@ -61,6 +61,8 @@
 #define VPU_IDLE_REG           0x002C
 #define VPU_INT_STATUS         0x0034
 #define VPU_PC_REG             0x0060
+#define VPU_SP_REG             0x0064
+#define VPU_RA_REG             0x0068
 #define VPU_WDT_REG            0x0084
 
 /* vpu inter-processor communication interrupt */
@@ -268,6 +270,20 @@ static int vpu_clock_enable(struct mtk_vpu *vpu)
        return ret;
 }
 
+static void vpu_dump_status(struct mtk_vpu *vpu)
+{
+       dev_info(vpu->dev,
+                "vpu: run %x, pc = 0x%x, ra = 0x%x, sp = 0x%x, idle = 0x%x\n"
+                "vpu: int %x, hv = 0x%x, vh = 0x%x, wdt = 0x%x\n",
+                vpu_running(vpu), vpu_cfg_readl(vpu, VPU_PC_REG),
+                vpu_cfg_readl(vpu, VPU_RA_REG), vpu_cfg_readl(vpu, VPU_SP_REG),
+                vpu_cfg_readl(vpu, VPU_IDLE_REG),
+                vpu_cfg_readl(vpu, VPU_INT_STATUS),
+                vpu_cfg_readl(vpu, HOST_TO_VPU),
+                vpu_cfg_readl(vpu, VPU_TO_HOST),
+                vpu_cfg_readl(vpu, VPU_WDT_REG));
+}
+
 int vpu_ipi_register(struct platform_device *pdev,
                     enum ipi_id id, ipi_handler_t handler,
                     const char *name, void *priv)
@@ -328,6 +344,7 @@ int vpu_ipi_send(struct platform_device *pdev,
                if (time_after(jiffies, timeout)) {
                        dev_err(vpu->dev, "vpu_ipi_send: IPI timeout!\n");
                        ret = -EIO;
+                       vpu_dump_status(vpu);
                        goto mut_unlock;
                }
        } while (vpu_cfg_readl(vpu, HOST_TO_VPU));
@@ -347,8 +364,9 @@ int vpu_ipi_send(struct platform_device *pdev,
        ret = wait_event_timeout(vpu->ack_wq, vpu->ipi_id_ack[id], timeout);
        vpu->ipi_id_ack[id] = false;
        if (ret == 0) {
-               dev_err(vpu->dev, "vpu ipi %d ack time out !", id);
+               dev_err(vpu->dev, "vpu ipi %d ack time out !\n", id);
                ret = -EIO;
+               vpu_dump_status(vpu);
                goto clock_disable;
        }
        vpu_clock_disable(vpu);
@@ -633,7 +651,7 @@ static ssize_t vpu_debug_read(struct file *file, char __user *user_buf,
 {
        char buf[256];
        unsigned int len;
-       unsigned int running, pc, vpu_to_host, host_to_vpu, wdt;
+       unsigned int running, pc, vpu_to_host, host_to_vpu, wdt, idle, ra, sp;
        int ret;
        struct device *dev = file->private_data;
        struct mtk_vpu *vpu = dev_get_drvdata(dev);
@@ -650,6 +668,10 @@ static ssize_t vpu_debug_read(struct file *file, char __user *user_buf,
        wdt = vpu_cfg_readl(vpu, VPU_WDT_REG);
        host_to_vpu = vpu_cfg_readl(vpu, HOST_TO_VPU);
        vpu_to_host = vpu_cfg_readl(vpu, VPU_TO_HOST);
+       ra = vpu_cfg_readl(vpu, VPU_RA_REG);
+       sp = vpu_cfg_readl(vpu, VPU_SP_REG);
+       idle = vpu_cfg_readl(vpu, VPU_IDLE_REG);
+
        vpu_clock_disable(vpu);
 
        if (running) {
@@ -658,9 +680,12 @@ static ssize_t vpu_debug_read(struct file *file, char __user *user_buf,
                "PC: 0x%x\n"
                "WDT: 0x%x\n"
                "Host to VPU: 0x%x\n"
-               "VPU to Host: 0x%x\n",
+               "VPU to Host: 0x%x\n"
+               "SP: 0x%x\n"
+               "RA: 0x%x\n"
+               "idle: 0x%x\n",
                vpu->run.fw_ver, pc, wdt,
-               host_to_vpu, vpu_to_host);
+               host_to_vpu, vpu_to_host, sp, ra, idle);
        } else {
                len = snprintf(buf, sizeof(buf), "VPU not running\n");
        }