diff mbox series

[05/14] media: sun4i-csi: Deal with DRAM offset

Message ID 20191215165924.28314-6-wens@kernel.org
State Mainlined
Headers show
Series media: sun4i-csi: A10/A20 CSI1 and R40 CSI0 support | expand

Commit Message

Chen-Yu Tsai Dec. 15, 2019, 4:59 p.m. UTC
From: Chen-Yu Tsai <wens@csie.org>

On Allwinner SoCs, some high memory bandwidth devices do DMA directly
over the memory bus (called MBUS), instead of the system bus. These
devices include the CSI camera sensor interface, video (codec) engine,
display subsystem, etc.. The memory bus has a different addressing
scheme without the DRAM starting offset.

Deal with this using the "interconnects" property from the device tree,
or if that is not available, set dev->dma_pfn_offset to PHYS_PFN_OFFSET.

Fixes: 577bbf23b758 ("media: sunxi: Add A10 CSI driver")
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 .../platform/sunxi/sun4i-csi/sun4i_csi.c      | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

Comments

Maxime Ripard Dec. 16, 2019, 1:38 p.m. UTC | #1
On Mon, Dec 16, 2019 at 12:59:15AM +0800, Chen-Yu Tsai wrote:
> From: Chen-Yu Tsai <wens@csie.org>
>
> On Allwinner SoCs, some high memory bandwidth devices do DMA directly
> over the memory bus (called MBUS), instead of the system bus. These
> devices include the CSI camera sensor interface, video (codec) engine,
> display subsystem, etc.. The memory bus has a different addressing
> scheme without the DRAM starting offset.
>
> Deal with this using the "interconnects" property from the device tree,
> or if that is not available, set dev->dma_pfn_offset to PHYS_PFN_OFFSET.
>
> Fixes: 577bbf23b758 ("media: sunxi: Add A10 CSI driver")
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>

Acked-by: Maxime Ripard <mripard@kernel.org>

> ---
>  .../platform/sunxi/sun4i-csi/sun4i_csi.c      | 22 +++++++++++++++++++
>  1 file changed, 22 insertions(+)
>
> diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
> index f36dc6258900..b8b07c1de2a8 100644
> --- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
> +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
> @@ -11,6 +11,7 @@
>  #include <linux/module.h>
>  #include <linux/mutex.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/of_graph.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> @@ -155,6 +156,27 @@ static int sun4i_csi_probe(struct platform_device *pdev)
>  	subdev = &csi->subdev;
>  	vdev = &csi->vdev;
>
> +	/*
> +	 * On Allwinner SoCs, some high memory bandwidth devices do DMA
> +	 * directly over the memory bus (called MBUS), instead of the
> +	 * system bus. The memory bus has a different addressing scheme
> +	 * without the DRAM starting offset.
> +	 *
> +	 * In some cases this can be described by an interconnect in
> +	 * the device tree. In other cases where the hardware is not
> +	 * fully understood and the interconnect is left out of the
> +	 * device tree, fall back to a default offset.
> +	 */

Though we should probably mention the DT-backward-compatibility case
here too.

Maxime
diff mbox series

Patch

diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
index f36dc6258900..b8b07c1de2a8 100644
--- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
@@ -11,6 +11,7 @@ 
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -155,6 +156,27 @@  static int sun4i_csi_probe(struct platform_device *pdev)
 	subdev = &csi->subdev;
 	vdev = &csi->vdev;
 
+	/*
+	 * On Allwinner SoCs, some high memory bandwidth devices do DMA
+	 * directly over the memory bus (called MBUS), instead of the
+	 * system bus. The memory bus has a different addressing scheme
+	 * without the DRAM starting offset.
+	 *
+	 * In some cases this can be described by an interconnect in
+	 * the device tree. In other cases where the hardware is not
+	 * fully understood and the interconnect is left out of the
+	 * device tree, fall back to a default offset.
+	 */
+	if (of_find_property(csi->dev->of_node, "interconnects", NULL)) {
+		ret = of_dma_configure(csi->dev, csi->dev->of_node, true);
+		if (ret)
+			return ret;
+	} else {
+#ifdef PHYS_PFN_OFFSET
+		csi->dev->dma_pfn_offset = PHYS_PFN_OFFSET;
+#endif
+	}
+
 	csi->mdev.dev = csi->dev;
 	strscpy(csi->mdev.model, "Allwinner Video Capture Device",
 		sizeof(csi->mdev.model));