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 <ag...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to