Commit 57f065fee2a421085621a34097ccbc45fc18aad5
Committed by
Stefano Babic
1 parent
01b7e8f6d4
Exists in
smarc_8mq_lf_v2020.04
and in
9 other branches
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>
Showing 4 changed files with 113 additions and 14 deletions Side-by-side Diff
arch/arm/include/asm/mach-imx/video.h
arch/arm/mach-imx/video.c
... | ... | @@ -4,6 +4,17 @@ |
4 | 4 | #include <linux/errno.h> |
5 | 5 | #include <asm/mach-imx/video.h> |
6 | 6 | |
7 | +#ifdef CONFIG_IMX_HDMI | |
8 | +#include <asm/arch/mxc_hdmi.h> | |
9 | +#include <asm/io.h> | |
10 | + | |
11 | +int detect_hdmi(struct display_info_t const *dev) | |
12 | +{ | |
13 | + struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; | |
14 | + return readb(&hdmi->phy_stat0) & HDMI_DVI_STAT; | |
15 | +} | |
16 | +#endif | |
17 | + | |
7 | 18 | int board_video_skip(void) |
8 | 19 | { |
9 | 20 | int i; |
... | ... | @@ -42,6 +53,11 @@ |
42 | 53 | displays[i].mode.name, |
43 | 54 | displays[i].mode.xres, |
44 | 55 | displays[i].mode.yres); |
56 | + | |
57 | +#ifdef CONFIG_IMX_HDMI | |
58 | + if (!strcmp(displays[i].mode.name, "HDMI")) | |
59 | + imx_enable_hdmi_phy(); | |
60 | +#endif | |
45 | 61 | } else |
46 | 62 | printf("LCD %s cannot be configured: %d\n", |
47 | 63 | displays[i].mode.name, ret); |
48 | 64 | |
49 | 65 | |
... | ... | @@ -53,13 +69,8 @@ |
53 | 69 | return ret; |
54 | 70 | } |
55 | 71 | |
56 | -#ifdef CONFIG_IMX_HDMI | |
57 | -#include <asm/arch/mxc_hdmi.h> | |
58 | -#include <asm/io.h> | |
59 | -int detect_hdmi(struct display_info_t const *dev) | |
72 | +int ipu_displays_init(void) | |
60 | 73 | { |
61 | - struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; | |
62 | - return readb(&hdmi->phy_stat0) & HDMI_DVI_STAT; | |
74 | + return board_video_skip(); | |
63 | 75 | } |
64 | -#endif |
drivers/video/Kconfig
... | ... | @@ -538,6 +538,13 @@ |
538 | 538 | |
539 | 539 | source "drivers/video/bridge/Kconfig" |
540 | 540 | |
541 | +config VIDEO_IPUV3 | |
542 | + bool "i.MX IPUv3 Core video support" | |
543 | + depends on (VIDEO || DM_VIDEO) && (MX5 || MX6) | |
544 | + help | |
545 | + This enables framebuffer driver for i.MX processors working | |
546 | + on the IPUv3(Image Processing Unit) internal graphic processor. | |
547 | + | |
541 | 548 | config VIDEO |
542 | 549 | bool "Enable legacy video support" |
543 | 550 | depends on !DM_VIDEO |
... | ... | @@ -546,13 +553,6 @@ |
546 | 553 | drivers use this because they are not yet converted to driver |
547 | 554 | model. Video drivers typically provide a colour text console and |
548 | 555 | cursor. |
549 | - | |
550 | -config VIDEO_IPUV3 | |
551 | - bool "i.MX IPUv3 Core video support" | |
552 | - depends on VIDEO && MX6 | |
553 | - help | |
554 | - This enables framebuffer driver for i.MX processors working | |
555 | - on the IPUv3(Image Processing Unit) internal graphic processor. | |
556 | 556 | |
557 | 557 | config CFB_CONSOLE |
558 | 558 | bool "Enable colour frame buffer console" |
drivers/video/mxc_ipuv3_fb.c
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | #include <linux/list.h> |
18 | 18 | #include <linux/fb.h> |
19 | 19 | #include <asm/io.h> |
20 | +#include <asm/mach-imx/video.h> | |
20 | 21 | #include <malloc.h> |
21 | 22 | #include <video_fb.h> |
22 | 23 | #include "videomodes.h" |
... | ... | @@ -24,6 +25,9 @@ |
24 | 25 | #include "mxcfb.h" |
25 | 26 | #include "ipu_regs.h" |
26 | 27 | |
28 | +#include <dm.h> | |
29 | +#include <video.h> | |
30 | + | |
27 | 31 | DECLARE_GLOBAL_DATA_PTR; |
28 | 32 | |
29 | 33 | static int mxcfb_map_video_memory(struct fb_info *fbi); |
30 | 34 | |
... | ... | @@ -401,8 +405,14 @@ |
401 | 405 | fbi->fix.line_length; |
402 | 406 | } |
403 | 407 | fbi->fix.smem_len = roundup(fbi->fix.smem_len, ARCH_DMA_MINALIGN); |
408 | + | |
409 | +#if CONFIG_IS_ENABLED(DM_VIDEO) | |
410 | + fbi->screen_base = (char *)gd->video_bottom; | |
411 | +#else | |
404 | 412 | fbi->screen_base = (char *)memalign(ARCH_DMA_MINALIGN, |
405 | 413 | fbi->fix.smem_len); |
414 | +#endif | |
415 | + | |
406 | 416 | fbi->fix.smem_start = (unsigned long)fbi->screen_base; |
407 | 417 | if (fbi->screen_base == 0) { |
408 | 418 | puts("Unable to allocate framebuffer memory\n"); |
409 | 419 | |
... | ... | @@ -416,7 +426,9 @@ |
416 | 426 | |
417 | 427 | fbi->screen_size = fbi->fix.smem_len; |
418 | 428 | |
429 | +#if CONFIG_IS_ENABLED(VIDEO) | |
419 | 430 | gd->fb_base = fbi->fix.smem_start; |
431 | +#endif | |
420 | 432 | |
421 | 433 | /* Clear the screen */ |
422 | 434 | memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); |
... | ... | @@ -611,4 +623,79 @@ |
611 | 623 | |
612 | 624 | return 0; |
613 | 625 | } |
626 | + | |
627 | +#if CONFIG_IS_ENABLED(DM_VIDEO) | |
628 | +enum { | |
629 | + /* Maximum display size we support */ | |
630 | + LCD_MAX_WIDTH = 1920, | |
631 | + LCD_MAX_HEIGHT = 1080, | |
632 | + LCD_MAX_LOG2_BPP = VIDEO_BPP16, | |
633 | +}; | |
634 | + | |
635 | +static int ipuv3_video_probe(struct udevice *dev) | |
636 | +{ | |
637 | + struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); | |
638 | + struct video_priv *uc_priv = dev_get_uclass_priv(dev); | |
639 | + u32 fb_start, fb_end; | |
640 | + int ret; | |
641 | + | |
642 | + debug("%s() plat: base 0x%lx, size 0x%x\n", | |
643 | + __func__, plat->base, plat->size); | |
644 | + | |
645 | + ret = ipu_probe(); | |
646 | + if (ret) | |
647 | + return ret; | |
648 | + | |
649 | + ret = ipu_displays_init(); | |
650 | + if (ret < 0) | |
651 | + return ret; | |
652 | + | |
653 | + ret = mxcfb_probe(gpixfmt, gdisp, gmode); | |
654 | + if (ret < 0) | |
655 | + return ret; | |
656 | + | |
657 | + uc_priv->xsize = gmode->xres; | |
658 | + uc_priv->ysize = gmode->yres; | |
659 | + uc_priv->bpix = LCD_MAX_LOG2_BPP; | |
660 | + | |
661 | + /* Enable dcache for the frame buffer */ | |
662 | + fb_start = plat->base & ~(MMU_SECTION_SIZE - 1); | |
663 | + fb_end = plat->base + plat->size; | |
664 | + fb_end = ALIGN(fb_end, 1 << MMU_SECTION_SHIFT); | |
665 | + mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start, | |
666 | + DCACHE_WRITEBACK); | |
667 | + video_set_flush_dcache(dev, true); | |
668 | + | |
669 | + return 0; | |
670 | +} | |
671 | + | |
672 | +struct ipuv3_video_priv { | |
673 | + ulong regs; | |
674 | +}; | |
675 | + | |
676 | +static int ipuv3_video_bind(struct udevice *dev) | |
677 | +{ | |
678 | + struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); | |
679 | + | |
680 | + plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT * | |
681 | + (1 << LCD_MAX_LOG2_BPP) / 8; | |
682 | + | |
683 | + return 0; | |
684 | +} | |
685 | + | |
686 | +static const struct udevice_id ipuv3_video_ids[] = { | |
687 | + { .compatible = "fsl,imx6q-ipu" }, | |
688 | + { } | |
689 | +}; | |
690 | + | |
691 | +U_BOOT_DRIVER(ipuv3_video) = { | |
692 | + .name = "ipuv3_video", | |
693 | + .id = UCLASS_VIDEO, | |
694 | + .of_match = ipuv3_video_ids, | |
695 | + .bind = ipuv3_video_bind, | |
696 | + .probe = ipuv3_video_probe, | |
697 | + .priv_auto_alloc_size = sizeof(struct ipuv3_video_priv), | |
698 | + .flags = DM_FLAG_PRE_RELOC, | |
699 | +}; | |
700 | +#endif /* CONFIG_DM_VIDEO */ |