diff options
author | Tom Rini <trini@konsulko.com> | 2021-08-06 20:46:40 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-08-06 20:46:40 +0300 |
commit | 8f07f5376a21a57ce191e5548b1a30c9709994d3 (patch) | |
tree | 09d66e4a19c260207511265e0f27ede198a6b24d /drivers/video | |
parent | abc784185475ad0d61a8d38f451f2fb8842e7f88 (diff) | |
parent | 845d71ce999936ab5ae2cef4542b221851cde199 (diff) | |
download | u-boot-8f07f5376a21a57ce191e5548b1a30c9709994d3.tar.xz |
Merge tag 'video-2021-08-05' of https://source.denx.de/u-boot/custodians/u-boot-video
- add display driver for ST-Ericsson MCDE
- drop legacy CONFIG_VIDEO dependency for Hitachi tx18d42vm
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/Kconfig | 13 | ||||
-rw-r--r-- | drivers/video/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/mcde_simple.c | 141 |
3 files changed, 154 insertions, 1 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index b69ffcae4b..8b940d70eb 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -470,7 +470,6 @@ config VIDEO_LCD_TDO_TL070WSH30 config VIDEO_LCD_HITACHI_TX18D42VM bool "Hitachi tx18d42vm LVDS LCD panel support" - depends on VIDEO default n ---help--- Support for Hitachi tx18d42vm LVDS LCD panels, these panels have a @@ -854,6 +853,18 @@ config VIDEO_DT_SIMPLEFB The video output is initialized by U-Boot, and kept by the kernel. +config VIDEO_MCDE_SIMPLE + bool "Simple driver for ST-Ericsson MCDE with preconfigured display" + depends on DM_VIDEO + help + Enables a simple display driver for ST-Ericsson MCDE + (Multichannel Display Engine), which reads the configuration from + the MCDE registers. + + This driver assumes that the display hardware has been initialized + before u-boot starts, and u-boot will simply render to the pre- + allocated frame buffer surface. + config OSD bool "Enable OSD support" depends on DM diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 1c534a6f9a..7ae0ab2b35 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_VIDEO_LCD_ORISETECH_OTM8009A) += orisetech_otm8009a.o obj-$(CONFIG_VIDEO_LCD_RAYDIUM_RM68200) += raydium-rm68200.o obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o obj-$(CONFIG_VIDEO_LCD_TDO_TL070WSH30) += tdo-tl070wsh30.o +obj-$(CONFIG_VIDEO_MCDE_SIMPLE) += mcde_simple.o obj-${CONFIG_VIDEO_MESON} += meson/ obj-${CONFIG_VIDEO_MIPI_DSI} += mipi_dsi.o obj-$(CONFIG_VIDEO_MVEBU) += mvebu_lcd.o diff --git a/drivers/video/mcde_simple.c b/drivers/video/mcde_simple.c new file mode 100644 index 0000000000..0924ceee30 --- /dev/null +++ b/drivers/video/mcde_simple.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2019 Stephan Gerhold */ + +#include <common.h> +#include <dm.h> +#include <log.h> +#include <video.h> +#include <asm/io.h> +#include <linux/bitfield.h> +#include <linux/iopoll.h> + +#define MCDE_EXTSRC0A0 0x200 +#define MCDE_EXTSRC0CONF 0x20C +#define MCDE_EXTSRC0CONF_BPP GENMASK(11, 8) +#define MCDE_OVL0CONF 0x404 +#define MCDE_OVL0CONF_PPL GENMASK(10, 0) +#define MCDE_OVL0CONF_LPF GENMASK(26, 16) +#define MCDE_CHNL0SYNCHMOD 0x608 +#define MCDE_CHNL0SYNCHMOD_SRC_SYNCH GENMASK(1, 0) +#define MCDE_CHNL0SYNCHSW 0x60C +#define MCDE_CHNL0SYNCHSW_SW_TRIG BIT(0) +#define MCDE_CRA0 0x800 +#define MCDE_CRA0_FLOEN BIT(0) + +#define MCDE_FLOW_COMPLETION_TIMEOUT 200000 /* us */ + +enum mcde_bpp { + MCDE_EXTSRC0CONF_BPP_1BPP_PAL, + MCDE_EXTSRC0CONF_BPP_2BPP_PAL, + MCDE_EXTSRC0CONF_BPP_4BPP_PAL, + MCDE_EXTSRC0CONF_BPP_8BPP_PAL, + MCDE_EXTSRC0CONF_BPP_RGB444, + MCDE_EXTSRC0CONF_BPP_ARGB4444, + MCDE_EXTSRC0CONF_BPP_IRGB1555, + MCDE_EXTSRC0CONF_BPP_RGB565, + MCDE_EXTSRC0CONF_BPP_RGB888, + MCDE_EXTSRC0CONF_BPP_XRGB8888, + MCDE_EXTSRC0CONF_BPP_ARGB8888, + MCDE_EXTSRC0CONF_BPP_YCBCR422, +}; + +enum mcde_src_synch { + MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE, + MCDE_CHNL0SYNCHMOD_SRC_SYNCH_NO_SYNCH, + MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE, +}; + +struct mcde_simple_priv { + fdt_addr_t base; + enum mcde_src_synch src_synch; +}; + +static int mcde_simple_probe(struct udevice *dev) +{ + struct mcde_simple_priv *priv = dev_get_priv(dev); + struct video_uc_plat *plat = dev_get_uclass_plat(dev); + struct video_priv *uc_priv = dev_get_uclass_priv(dev); + u32 val; + + priv->base = dev_read_addr(dev); + if (priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + plat->base = readl(priv->base + MCDE_EXTSRC0A0); + if (!plat->base) + return -ENODEV; + + val = readl(priv->base + MCDE_OVL0CONF); + uc_priv->xsize = FIELD_GET(MCDE_OVL0CONF_PPL, val); + uc_priv->ysize = FIELD_GET(MCDE_OVL0CONF_LPF, val); + uc_priv->rot = 0; + + val = readl(priv->base + MCDE_EXTSRC0CONF); + switch (FIELD_GET(MCDE_EXTSRC0CONF_BPP, val)) { + case MCDE_EXTSRC0CONF_BPP_RGB565: + uc_priv->bpix = VIDEO_BPP16; + break; + case MCDE_EXTSRC0CONF_BPP_XRGB8888: + case MCDE_EXTSRC0CONF_BPP_ARGB8888: + uc_priv->bpix = VIDEO_BPP32; + break; + default: + printf("unsupported format: %#x\n", val); + return -EINVAL; + } + + val = readl(priv->base + MCDE_CHNL0SYNCHMOD); + priv->src_synch = FIELD_GET(MCDE_CHNL0SYNCHMOD_SRC_SYNCH, val); + + plat->size = uc_priv->xsize * uc_priv->ysize * VNBYTES(uc_priv->bpix); + debug("MCDE base: %#lx, xsize: %d, ysize: %d, bpp: %d\n", + plat->base, uc_priv->xsize, uc_priv->ysize, VNBITS(uc_priv->bpix)); + + video_set_flush_dcache(dev, true); + return 0; +} + +static int mcde_simple_video_sync(struct udevice *dev) +{ + struct mcde_simple_priv *priv = dev_get_priv(dev); + unsigned int val; + + if (priv->src_synch != MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE) + return 0; + + /* Enable flow */ + val = readl(priv->base + MCDE_CRA0); + val |= MCDE_CRA0_FLOEN; + writel(val, priv->base + MCDE_CRA0); + + /* Trigger a software sync */ + writel(MCDE_CHNL0SYNCHSW_SW_TRIG, priv->base + MCDE_CHNL0SYNCHSW); + + /* Disable flow */ + val = readl(priv->base + MCDE_CRA0); + val &= ~MCDE_CRA0_FLOEN; + writel(val, priv->base + MCDE_CRA0); + + /* Wait for completion */ + return readl_poll_timeout(priv->base + MCDE_CRA0, val, + !(val & MCDE_CRA0_FLOEN), + MCDE_FLOW_COMPLETION_TIMEOUT); +} + +static struct video_ops mcde_simple_ops = { + .video_sync = mcde_simple_video_sync, +}; + +static const struct udevice_id mcde_simple_ids[] = { + { .compatible = "ste,mcde" }, + { } +}; + +U_BOOT_DRIVER(mcde_simple) = { + .name = "mcde_simple", + .id = UCLASS_VIDEO, + .ops = &mcde_simple_ops, + .of_match = mcde_simple_ids, + .probe = mcde_simple_probe, + .priv_auto = sizeof(struct mcde_simple_priv), +}; |