aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2019-03-18 23:29:31 +0100
committerStefano Babic <sbabic@denx.de>2019-04-13 20:30:09 +0200
commit57f065fee2a421085621a34097ccbc45fc18aad5 (patch)
treea92b9a942cc122c187571435655cd622dec8a141
parent01b7e8f6d4878c1b095627a70f1f10afb4db8078 (diff)
downloadu-boot-57f065fee2a421085621a34097ccbc45fc18aad5.zip
u-boot-57f065fee2a421085621a34097ccbc45fc18aad5.tar.gz
u-boot-57f065fee2a421085621a34097ccbc45fc18aad5.tar.bz2
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 <agust@denx.de>
-rw-r--r--arch/arm/include/asm/mach-imx/video.h1
-rw-r--r--arch/arm/mach-imx/video.c25
-rw-r--r--drivers/video/Kconfig14
-rw-r--r--drivers/video/mxc_ipuv3_fb.c87
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 <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 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 <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 */