From d8a50ba96cbba8982885805c9da4435430011cfb Mon Sep 17 00:00:00 2001 From: Hu Kejun Date: Tue, 30 Apr 2019 09:42:12 +0800 Subject: [PATCH] media: rockchip: isp1: fix get zero data when start stream again use the following sequence, we will get zero data. 1. open video device; 2. start stream; 3. stop stream; 4. start stream again, we will get zero data. Change-Id: I7433f4891f66c2228e840116a5d4632298ab62c4 Signed-off-by: Hu Kejun --- .../media/platform/rockchip/isp1/capture.c | 58 +++++++++---------- .../media/platform/rockchip/isp1/capture.h | 3 + drivers/media/platform/rockchip/isp1/rkisp1.c | 6 ++ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/drivers/media/platform/rockchip/isp1/capture.c b/drivers/media/platform/rockchip/isp1/capture.c index 81fd10bea419..8b8af2a4223d 100644 --- a/drivers/media/platform/rockchip/isp1/capture.c +++ b/drivers/media/platform/rockchip/isp1/capture.c @@ -1711,35 +1711,6 @@ static int rkisp1_set_fmt(struct rkisp1_stream *stream, return 0; } -static int rkisp1_dma_attach_device(struct rkisp1_device *rkisp1_dev) -{ - struct iommu_domain *domain = rkisp1_dev->domain; - struct device *dev = rkisp1_dev->dev; - int ret; - - ret = iommu_attach_device(domain, dev); - if (ret) { - dev_err(dev, "Failed to attach iommu device\n"); - return ret; - } - - if (!common_iommu_setup_dma_ops(dev, 0x10000000, SZ_2G, domain->ops)) { - dev_err(dev, "Failed to set dma_ops\n"); - iommu_detach_device(domain, dev); - ret = -ENODEV; - } - - return ret; -} - -static void rkisp1_dma_detach_device(struct rkisp1_device *rkisp1_dev) -{ - struct iommu_domain *domain = rkisp1_dev->domain; - struct device *dev = rkisp1_dev->dev; - - iommu_detach_device(domain, dev); -} - int rkisp1_fh_open(struct file *filp) { struct rkisp1_stream *stream = video_drvdata(filp); @@ -2132,6 +2103,35 @@ err: return ret; } +int rkisp1_dma_attach_device(struct rkisp1_device *rkisp1_dev) +{ + struct iommu_domain *domain = rkisp1_dev->domain; + struct device *dev = rkisp1_dev->dev; + int ret; + + ret = iommu_attach_device(domain, dev); + if (ret) { + dev_err(dev, "Failed to attach iommu device\n"); + return ret; + } + + if (!common_iommu_setup_dma_ops(dev, 0x10000000, SZ_2G, domain->ops)) { + dev_err(dev, "Failed to set dma_ops\n"); + iommu_detach_device(domain, dev); + ret = -ENODEV; + } + + return ret; +} + +void rkisp1_dma_detach_device(struct rkisp1_device *rkisp1_dev) +{ + struct iommu_domain *domain = rkisp1_dev->domain; + struct device *dev = rkisp1_dev->dev; + + iommu_detach_device(domain, dev); +} + /**************** Interrupter Handler ****************/ void rkisp1_mi_isr(u32 mis_val, struct rkisp1_device *dev) diff --git a/drivers/media/platform/rockchip/isp1/capture.h b/drivers/media/platform/rockchip/isp1/capture.h index 8613618352e9..db81988a5155 100644 --- a/drivers/media/platform/rockchip/isp1/capture.h +++ b/drivers/media/platform/rockchip/isp1/capture.h @@ -216,4 +216,7 @@ void rkisp1_mipi_dmatx0_end(u32 status, struct rkisp1_device *dev); int fcc_xysubs(u32 fcc, u32 *xsubs, u32 *ysubs); int rkisp1_fh_open(struct file *filp); int rkisp1_fop_release(struct file *file); +int rkisp1_dma_attach_device(struct rkisp1_device *rkisp1_dev); +void rkisp1_dma_detach_device(struct rkisp1_device *rkisp1_dev); + #endif /* _RKISP1_PATH_VIDEO_H */ diff --git a/drivers/media/platform/rockchip/isp1/rkisp1.c b/drivers/media/platform/rockchip/isp1/rkisp1.c index eaeb8368a8c0..0b122aea4888 100644 --- a/drivers/media/platform/rockchip/isp1/rkisp1.c +++ b/drivers/media/platform/rockchip/isp1/rkisp1.c @@ -46,6 +46,7 @@ #include "common.h" #include "regs.h" +#include "capture.h" /* * NOTE: MIPI controller and input MUX are also configured in this file, @@ -694,6 +695,11 @@ static int rkisp1_isp_stop(struct rkisp1_device *dev) writel(0, base + CIF_ISP_CSI0_MASK2); writel(0, base + CIF_ISP_CSI0_MASK3); } + + if (!in_interrupt()) { + rkisp1_dma_detach_device(dev); + rkisp1_dma_attach_device(dev); + } dev->isp_state = ISP_STOP; if (dev->emd_vc <= CIF_ISP_ADD_DATA_VC_MAX) {