From 57f065fee2a421085621a34097ccbc45fc18aad5 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 18 Mar 2019 23:29:31 +0100 Subject: video: ipuv3: add DM_VIDEO support 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 --- 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 812e6f8..d1a14ad 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 953fe53..22a371a 100644 --- a/arch/arm/mach-imx/video.c +++ b/arch/arm/mach-imx/video.c @@ -4,6 +4,17 @@ #include #include +#ifdef CONFIG_IMX_HDMI +#include +#include + +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 -#include -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 2eac4b6..73a2402 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 23cd55d..5b3ba7b 100644 --- a/drivers/video/mxc_ipuv3_fb.c +++ b/drivers/video/mxc_ipuv3_fb.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include "videomodes.h" @@ -24,6 +25,9 @@ #include "mxcfb.h" #include "ipu_regs.h" +#include +#include + 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 */ -- cgit v1.1