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>
This commit is contained in:
Anatolij Gustschin 2019-03-18 23:29:31 +01:00 committed by Stefano Babic
parent 01b7e8f6d4
commit 57f065fee2
4 changed files with 113 additions and 14 deletions

View file

@ -26,4 +26,5 @@ extern size_t display_count;
#endif #endif
int ipu_set_ldb_clock(int rate); int ipu_set_ldb_clock(int rate);
int ipu_displays_init(void);
#endif #endif

View file

@ -4,6 +4,17 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <asm/mach-imx/video.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 board_video_skip(void)
{ {
int i; int i;
@ -42,6 +53,11 @@ int board_video_skip(void)
displays[i].mode.name, displays[i].mode.name,
displays[i].mode.xres, displays[i].mode.xres,
displays[i].mode.yres); displays[i].mode.yres);
#ifdef CONFIG_IMX_HDMI
if (!strcmp(displays[i].mode.name, "HDMI"))
imx_enable_hdmi_phy();
#endif
} else } else
printf("LCD %s cannot be configured: %d\n", printf("LCD %s cannot be configured: %d\n",
displays[i].mode.name, ret); displays[i].mode.name, ret);
@ -53,12 +69,7 @@ int board_video_skip(void)
return ret; return ret;
} }
#ifdef CONFIG_IMX_HDMI int ipu_displays_init(void)
#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 board_video_skip();
return readb(&hdmi->phy_stat0) & HDMI_DVI_STAT;
} }
#endif

View file

@ -538,6 +538,13 @@ config VIDEO_TEGRA124
source "drivers/video/bridge/Kconfig" 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 config VIDEO
bool "Enable legacy video support" bool "Enable legacy video support"
depends on !DM_VIDEO depends on !DM_VIDEO
@ -547,13 +554,6 @@ config VIDEO
model. Video drivers typically provide a colour text console and model. Video drivers typically provide a colour text console and
cursor. 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 config CFB_CONSOLE
bool "Enable colour frame buffer console" bool "Enable colour frame buffer console"
depends on VIDEO depends on VIDEO

View file

@ -17,6 +17,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/mach-imx/video.h>
#include <malloc.h> #include <malloc.h>
#include <video_fb.h> #include <video_fb.h>
#include "videomodes.h" #include "videomodes.h"
@ -24,6 +25,9 @@
#include "mxcfb.h" #include "mxcfb.h"
#include "ipu_regs.h" #include "ipu_regs.h"
#include <dm.h>
#include <video.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
static int mxcfb_map_video_memory(struct fb_info *fbi); 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.line_length;
} }
fbi->fix.smem_len = roundup(fbi->fix.smem_len, ARCH_DMA_MINALIGN); 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->screen_base = (char *)memalign(ARCH_DMA_MINALIGN,
fbi->fix.smem_len); fbi->fix.smem_len);
#endif
fbi->fix.smem_start = (unsigned long)fbi->screen_base; fbi->fix.smem_start = (unsigned long)fbi->screen_base;
if (fbi->screen_base == 0) { if (fbi->screen_base == 0) {
puts("Unable to allocate framebuffer memory\n"); 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; fbi->screen_size = fbi->fix.smem_len;
#if CONFIG_IS_ENABLED(VIDEO)
gd->fb_base = fbi->fix.smem_start; gd->fb_base = fbi->fix.smem_start;
#endif
/* Clear the screen */ /* Clear the screen */
memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); 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; 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 */