[U-Boot] [PATCH 01/17] video: ipuv3: add DM_VIDEO support

Anatolij Gustschin agust at denx.de
Mon Mar 18 22:29:31 UTC 2019


Extend the driver to build with DM_VIDEO enabled. DTS files
must additionally include 'u-boot,dm-pre-reloc' property in
soc and ipu nodes to enable driver binding to ipu device.

Signed-off-by: Anatolij Gustschin <agust at denx.de>
---
 arch/arm/include/asm/mach-imx/video.h |  1 +
 arch/arm/mach-imx/video.c             | 25 +++++---
 drivers/video/Kconfig                 | 14 ++---
 drivers/video/mxc_ipuv3_fb.c          | 87 +++++++++++++++++++++++++++
 4 files changed, 113 insertions(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/mach-imx/video.h b/arch/arm/include/asm/mach-imx/video.h
index 812e6f85e4..d1a14ad7d3 100644
--- a/arch/arm/include/asm/mach-imx/video.h
+++ b/arch/arm/include/asm/mach-imx/video.h
@@ -26,4 +26,5 @@ extern size_t display_count;
 #endif
 
 int ipu_set_ldb_clock(int rate);
+int ipu_displays_init(void);
 #endif
diff --git a/arch/arm/mach-imx/video.c b/arch/arm/mach-imx/video.c
index 953fe53cb4..22a371a212 100644
--- a/arch/arm/mach-imx/video.c
+++ b/arch/arm/mach-imx/video.c
@@ -4,6 +4,17 @@
 #include <linux/errno.h>
 #include <asm/mach-imx/video.h>
 
+#ifdef CONFIG_IMX_HDMI
+#include <asm/arch/mxc_hdmi.h>
+#include <asm/io.h>
+
+int detect_hdmi(struct display_info_t const *dev)
+{
+	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+	return readb(&hdmi->phy_stat0) & HDMI_DVI_STAT;
+}
+#endif
+
 int board_video_skip(void)
 {
 	int i;
@@ -42,6 +53,11 @@ int board_video_skip(void)
 			       displays[i].mode.name,
 			       displays[i].mode.xres,
 			       displays[i].mode.yres);
+
+#ifdef CONFIG_IMX_HDMI
+			if (!strcmp(displays[i].mode.name, "HDMI"))
+				imx_enable_hdmi_phy();
+#endif
 		} else
 			printf("LCD %s cannot be configured: %d\n",
 			       displays[i].mode.name, ret);
@@ -53,12 +69,7 @@ int board_video_skip(void)
 	return ret;
 }
 
-#ifdef CONFIG_IMX_HDMI
-#include <asm/arch/mxc_hdmi.h>
-#include <asm/io.h>
-int detect_hdmi(struct display_info_t const *dev)
+int ipu_displays_init(void)
 {
-	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-	return readb(&hdmi->phy_stat0) & HDMI_DVI_STAT;
+	return board_video_skip();
 }
-#endif
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2eac4b6381..73a2402f41 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -538,6 +538,13 @@ config VIDEO_TEGRA124
 
 source "drivers/video/bridge/Kconfig"
 
+config VIDEO_IPUV3
+	bool "i.MX IPUv3 Core video support"
+	depends on (VIDEO || DM_VIDEO) && (MX5 || MX6)
+	help
+	  This enables framebuffer driver for i.MX processors working
+	  on the IPUv3(Image Processing Unit) internal graphic processor.
+
 config VIDEO
 	bool "Enable legacy video support"
 	depends on !DM_VIDEO
@@ -547,13 +554,6 @@ config VIDEO
 	  model. Video drivers typically provide a colour text console and
 	  cursor.
 
-config VIDEO_IPUV3
-	bool "i.MX IPUv3 Core video support"
-	depends on VIDEO && MX6
-	help
-	  This enables framebuffer driver for i.MX processors working
-	  on the IPUv3(Image Processing Unit) internal graphic processor.
-
 config CFB_CONSOLE
 	bool "Enable colour frame buffer console"
 	depends on VIDEO
diff --git a/drivers/video/mxc_ipuv3_fb.c b/drivers/video/mxc_ipuv3_fb.c
index 23cd55de47..5b3ba7b3a9 100644
--- a/drivers/video/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc_ipuv3_fb.c
@@ -17,6 +17,7 @@
 #include <linux/list.h>
 #include <linux/fb.h>
 #include <asm/io.h>
+#include <asm/mach-imx/video.h>
 #include <malloc.h>
 #include <video_fb.h>
 #include "videomodes.h"
@@ -24,6 +25,9 @@
 #include "mxcfb.h"
 #include "ipu_regs.h"
 
+#include <dm.h>
+#include <video.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static int mxcfb_map_video_memory(struct fb_info *fbi);
@@ -401,8 +405,14 @@ static int mxcfb_map_video_memory(struct fb_info *fbi)
 				    fbi->fix.line_length;
 	}
 	fbi->fix.smem_len = roundup(fbi->fix.smem_len, ARCH_DMA_MINALIGN);
+
+#if CONFIG_IS_ENABLED(DM_VIDEO)
+	fbi->screen_base = (char *)gd->video_bottom;
+#else
 	fbi->screen_base = (char *)memalign(ARCH_DMA_MINALIGN,
 					    fbi->fix.smem_len);
+#endif
+
 	fbi->fix.smem_start = (unsigned long)fbi->screen_base;
 	if (fbi->screen_base == 0) {
 		puts("Unable to allocate framebuffer memory\n");
@@ -416,7 +426,9 @@ static int mxcfb_map_video_memory(struct fb_info *fbi)
 
 	fbi->screen_size = fbi->fix.smem_len;
 
+#if CONFIG_IS_ENABLED(VIDEO)
 	gd->fb_base = fbi->fix.smem_start;
+#endif
 
 	/* Clear the screen */
 	memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
@@ -611,3 +623,78 @@ int ipuv3_fb_init(struct fb_videomode const *mode,
 
 	return 0;
 }
+
+#if CONFIG_IS_ENABLED(DM_VIDEO)
+enum {
+	/* Maximum display size we support */
+	LCD_MAX_WIDTH		= 1920,
+	LCD_MAX_HEIGHT		= 1080,
+	LCD_MAX_LOG2_BPP	= VIDEO_BPP16,
+};
+
+static int ipuv3_video_probe(struct udevice *dev)
+{
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+	u32 fb_start, fb_end;
+	int ret;
+
+	debug("%s() plat: base 0x%lx, size 0x%x\n",
+	      __func__, plat->base, plat->size);
+
+	ret = ipu_probe();
+	if (ret)
+		return ret;
+
+	ret = ipu_displays_init();
+	if (ret < 0)
+		return ret;
+
+	ret = mxcfb_probe(gpixfmt, gdisp, gmode);
+	if (ret < 0)
+		return ret;
+
+	uc_priv->xsize = gmode->xres;
+	uc_priv->ysize = gmode->yres;
+	uc_priv->bpix = LCD_MAX_LOG2_BPP;
+
+	/* Enable dcache for the frame buffer */
+	fb_start = plat->base & ~(MMU_SECTION_SIZE - 1);
+	fb_end = plat->base + plat->size;
+	fb_end = ALIGN(fb_end, 1 << MMU_SECTION_SHIFT);
+	mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start,
+					DCACHE_WRITEBACK);
+	video_set_flush_dcache(dev, true);
+
+	return 0;
+}
+
+struct ipuv3_video_priv {
+	ulong regs;
+};
+
+static int ipuv3_video_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+
+	plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
+		     (1 << LCD_MAX_LOG2_BPP) / 8;
+
+	return 0;
+}
+
+static const struct udevice_id ipuv3_video_ids[] = {
+	{ .compatible = "fsl,imx6q-ipu" },
+	{ }
+};
+
+U_BOOT_DRIVER(ipuv3_video) = {
+	.name	= "ipuv3_video",
+	.id	= UCLASS_VIDEO,
+	.of_match = ipuv3_video_ids,
+	.bind	= ipuv3_video_bind,
+	.probe	= ipuv3_video_probe,
+	.priv_auto_alloc_size = sizeof(struct ipuv3_video_priv),
+	.flags	= DM_FLAG_PRE_RELOC,
+};
+#endif /* CONFIG_DM_VIDEO */
-- 
2.17.1



More information about the U-Boot mailing list