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
int ipu_set_ldb_clock(int rate);
int ipu_displays_init(void);
#endif

View File

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

View File

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

View File

@ -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 */