diff options
author | Tom Rini | 2017-06-10 09:48:09 -0400 |
---|---|---|
committer | Tom Rini | 2017-06-10 09:48:09 -0400 |
commit | d2e1ee686ab16c022d1a3049a35b4ce89a25d34e (patch) | |
tree | 8cacb796cda155844349ebd6ff68935dcc8e2042 | |
parent | 75fd49c836d9a1750c9b6d86c0511b990fbe9fa8 (diff) | |
parent | 76a5e1b7156d16fec3dfa17c5135b28d4d657f0e (diff) |
Merge branch 'master' of git://git.denx.de/u-boot-video
-rw-r--r-- | arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 10 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-sunxi/display2.h | 17 | ||||
-rw-r--r-- | common/edid.c | 2 | ||||
-rw-r--r-- | drivers/video/atmel_hlcdfb.c | 8 | ||||
-rw-r--r-- | drivers/video/rockchip/rk_hdmi.h | 44 | ||||
-rw-r--r-- | drivers/video/rockchip/rk_vop.h | 34 | ||||
-rw-r--r-- | drivers/video/sunxi/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/sunxi/sunxi_de2.c | 60 | ||||
-rw-r--r-- | drivers/video/sunxi/tve_common.c (renamed from drivers/video/sunxi/tve.c) | 0 |
9 files changed, 161 insertions, 16 deletions
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 6aa5e91adae..2419062d45d 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -34,7 +34,9 @@ #define SUNXI_MS_BASE 0x01c07000 #define SUNXI_TVD_BASE 0x01c08000 #define SUNXI_CSI0_BASE 0x01c09000 +#ifndef CONFIG_MACH_SUNXI_H3_H5 #define SUNXI_TVE0_BASE 0x01c0a000 +#endif #define SUNXI_EMAC_BASE 0x01c0b000 #define SUNXI_LCD0_BASE 0x01c0C000 #define SUNXI_LCD1_BASE 0x01c0d000 @@ -161,10 +163,18 @@ defined(CONFIG_MACH_SUN50I) /* module sram */ #define SUNXI_SRAM_C_BASE 0x01d00000 +#ifndef CONFIG_MACH_SUN8I_H3 #define SUNXI_DE_FE0_BASE 0x01e00000 +#else +#define SUNXI_TVE0_BASE 0x01e00000 +#endif #define SUNXI_DE_FE1_BASE 0x01e20000 #define SUNXI_DE_BE0_BASE 0x01e60000 +#ifndef CONFIG_MACH_SUN50I_H5 #define SUNXI_DE_BE1_BASE 0x01e40000 +#else +#define SUNXI_TVE0_BASE 0x01e40000 +#endif #define SUNXI_MP_BASE 0x01e80000 #define SUNXI_AVG_BASE 0x01ea0000 diff --git a/arch/arm/include/asm/arch-sunxi/display2.h b/arch/arm/include/asm/arch-sunxi/display2.h index b5875f96050..359cacd90bc 100644 --- a/arch/arm/include/asm/arch-sunxi/display2.h +++ b/arch/arm/include/asm/arch-sunxi/display2.h @@ -90,6 +90,23 @@ struct de_ui { u32 ovl_size; }; +struct de_csc { + u32 csc_ctl; + u8 res[0xc]; + u32 coef11; + u32 coef12; + u32 coef13; + u32 coef14; + u32 coef21; + u32 coef22; + u32 coef23; + u32 coef24; + u32 coef31; + u32 coef32; + u32 coef33; + u32 coef34; +}; + /* * DE register constants. */ diff --git a/common/edid.c b/common/edid.c index 19410aa4fcc..854d40c8f8b 100644 --- a/common/edid.c +++ b/common/edid.c @@ -295,7 +295,7 @@ static void edid_print_dtd(struct edid_monitor_descriptor *monitor, h_total = h_active + h_blanking; v_total = v_active + v_blanking; - if (v_total * h_total) + if (v_total > 0 && h_total > 0) vfreq = pixclock / (v_total * h_total); else vfreq = 1; /* Error case */ diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c index 47078fdaaed..f77da2ec979 100644 --- a/drivers/video/atmel_hlcdfb.c +++ b/drivers/video/atmel_hlcdfb.c @@ -426,7 +426,9 @@ static void atmel_hlcdc_init(struct udevice *dev) writel(~0UL, ®s->lcdc_baseidr); /* Setup the DMA descriptor, this descriptor will loop to itself */ - desc = (struct lcd_dma_desc *)(uc_plat->base - 16); + desc = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*desc)); + if (!desc) + return; desc->address = (u32)uc_plat->base; @@ -436,7 +438,9 @@ static void atmel_hlcdc_init(struct udevice *dev) desc->next = (u32)desc; /* Flush the DMA descriptor if we enabled dcache */ - flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc)); + flush_dcache_range((u32)desc, + ALIGN(((u32)desc + sizeof(*desc)), + CONFIG_SYS_CACHELINE_SIZE)); writel(desc->address, ®s->lcdc_baseaddr); writel(desc->control, ®s->lcdc_basectrl); diff --git a/drivers/video/rockchip/rk_hdmi.h b/drivers/video/rockchip/rk_hdmi.h index 501ed3ada82..ec396682f10 100644 --- a/drivers/video/rockchip/rk_hdmi.h +++ b/drivers/video/rockchip/rk_hdmi.h @@ -23,10 +23,54 @@ struct rk_hdmi_priv { void *grf; }; +/** + * rk_hdmi_read_edid() - read the attached HDMI/DVI monitor's EDID + * + * N.B.: The buffer should be large enough to hold 2 EDID blocks, as + * this function calls dw_hdmi_read_edid, which ignores buf_size + * argument and assumes that there's always enough space for 2 + * EDID blocks. + * + * @dev: device + * @buf: output buffer for the EDID + * @buf_size: number of bytes in the buffer + * @return number of bytes read if OK, -ve if something went wrong + */ int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size); + +/** + * rk_hdmi_probe_regulators() - probe (autoset + enable) regulators + * + * Probes a list of regulators by performing autoset and enable + * operations on them. The list of regulators is an array of string + * pointers and any individual regulator-probe may fail without + * counting as an error. + * + * @dev: device + * @names: array of string-pointers to regulator names to probe + * @cnt: number of elements in the 'names' array + */ void rk_hdmi_probe_regulators(struct udevice *dev, const char * const *names, int cnt); +/** + * rk_hdmi_ofdata_to_platdata() - common ofdata_to_platdata implementation + * + * @dev: device + * @return 0 if OK, -ve if something went wrong + */ int rk_hdmi_ofdata_to_platdata(struct udevice *dev); + +/** + * rk_hdmi_probe() - common probe implementation + * + * Performs the following, common initialisation steps: + * 1. checks for HPD (i.e. a HDMI monitor being attached) + * 2. initialises the Designware HDMI core + * 3. initialises the Designware HDMI PHY + * + * @dev: device + * @return 0 if OK, -ve if something went wrong + */ int rk_hdmi_probe(struct udevice *dev); #endif diff --git a/drivers/video/rockchip/rk_vop.h b/drivers/video/rockchip/rk_vop.h index 9bda51410d9..b2b29c452a2 100644 --- a/drivers/video/rockchip/rk_vop.h +++ b/drivers/video/rockchip/rk_vop.h @@ -25,8 +25,42 @@ struct rkvop_driverdata { void (*set_pin_polarity)(struct udevice *, enum vop_modes, u32); }; +/** + * rk_vop_probe() - common probe implementation + * + * Performs the rk_display_init on each port-subnode until finding a + * working port (or returning an error if none of the ports could be + * successfully initialised). + * + * @dev: device + * @return 0 if OK, -ve if something went wrong + */ int rk_vop_probe(struct udevice *dev); + +/** + * rk_vop_bind() - common bind implementation + * + * Sets the plat->size field to the amount of memory to be reserved for + * the framebuffer: this is always + * (32 BPP) x VIDEO_ROCKCHIP_MAX_XRES x VIDEO_ROCKCHIP_MAX_YRES + * + * @dev: device + * @return 0 (always OK) + */ int rk_vop_bind(struct udevice *dev); + +/** + * rk_vop_probe_regulators() - probe (autoset + enable) regulators + * + * Probes a list of regulators by performing autoset and enable + * operations on them. The list of regulators is an array of string + * pointers and any individual regulator-probe may fail without + * counting as an error. + * + * @dev: device + * @names: array of string-pointers to regulator names to probe + * @cnt: number of elements in the 'names' array + */ void rk_vop_probe_regulators(struct udevice *dev, const char * const *names, int cnt); diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile index dbaab61b59c..0d64c2021f8 100644 --- a/drivers/video/sunxi/Makefile +++ b/drivers/video/sunxi/Makefile @@ -5,5 +5,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o tve.o ../videomodes.o +obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o tve_common.o ../videomodes.o obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o lcdc.o ../dw_hdmi.o diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c index 9a32c3a0209..ee67764ac5c 100644 --- a/drivers/video/sunxi/sunxi_de2.c +++ b/drivers/video/sunxi/sunxi_de2.c @@ -56,7 +56,7 @@ static void sunxi_de2_composer_init(void) } static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, - int bpp, ulong address) + int bpp, ulong address, bool is_composite) { ulong de_mux_base = (mux == 0) ? SUNXI_DE2_MUX0_BASE : SUNXI_DE2_MUX1_BASE; @@ -72,6 +72,9 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, (struct de_ui *)(de_mux_base + SUNXI_DE2_MUX_CHAN_REGS + SUNXI_DE2_MUX_CHAN_SZ * 1); + struct de_csc * const de_csc_regs = + (struct de_csc *)(de_mux_base + + SUNXI_DE2_MUX_DCSC_REGS); u32 size = SUNXI_DE2_WH(mode->hactive.typ, mode->vactive.typ); int channel; u32 format; @@ -128,7 +131,27 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, writel(0, de_mux_base + SUNXI_DE2_MUX_PEAK_REGS); writel(0, de_mux_base + SUNXI_DE2_MUX_ASE_REGS); writel(0, de_mux_base + SUNXI_DE2_MUX_FCC_REGS); - writel(0, de_mux_base + SUNXI_DE2_MUX_DCSC_REGS); + + if (is_composite) { + /* set CSC coefficients */ + writel(0x107, &de_csc_regs->coef11); + writel(0x204, &de_csc_regs->coef12); + writel(0x64, &de_csc_regs->coef13); + writel(0x4200, &de_csc_regs->coef14); + writel(0x1f68, &de_csc_regs->coef21); + writel(0x1ed6, &de_csc_regs->coef22); + writel(0x1c2, &de_csc_regs->coef23); + writel(0x20200, &de_csc_regs->coef24); + writel(0x1c2, &de_csc_regs->coef31); + writel(0x1e87, &de_csc_regs->coef32); + writel(0x1fb7, &de_csc_regs->coef33); + writel(0x20200, &de_csc_regs->coef34); + + /* enable CSC unit */ + writel(1, &de_csc_regs->csc_ctl); + } else { + writel(0, &de_csc_regs->csc_ctl); + } switch (bpp) { case 16: @@ -153,7 +176,7 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, static int sunxi_de2_init(struct udevice *dev, ulong fbbase, enum video_log2_bpp l2bpp, - struct udevice *disp, int mux) + struct udevice *disp, int mux, bool is_composite) { struct video_priv *uc_priv = dev_get_uclass_priv(dev); struct display_timing timing; @@ -183,7 +206,7 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase, } sunxi_de2_composer_init(); - sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase); + sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase, is_composite); ret = display_enable(disp, 1 << l2bpp, &timing); if (ret) { @@ -204,7 +227,6 @@ static int sunxi_de2_probe(struct udevice *dev) struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); struct udevice *disp; int ret; - int mux; /* Before relocation we don't need to do anything */ if (!(gd->flags & GD_FLG_RELOC)) @@ -212,17 +234,31 @@ static int sunxi_de2_probe(struct udevice *dev) ret = uclass_find_device_by_name(UCLASS_DISPLAY, "sunxi_dw_hdmi", &disp); + if (!ret) { + int mux; + if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5)) + mux = 0; + else + mux = 1; + + ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux, + false); + if (!ret) { + video_set_flush_dcache(dev, 1); + return 0; + } + } + + debug("%s: hdmi display not found (ret=%d)\n", __func__, ret); + + ret = uclass_find_device_by_name(UCLASS_DISPLAY, + "sunxi_tve", &disp); if (ret) { - debug("%s: hdmi display not found (ret=%d)\n", __func__, ret); + debug("%s: tv not found (ret=%d)\n", __func__, ret); return ret; } - if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5)) - mux = 0; - else - mux = 1; - - ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux); + ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, 1, true); if (ret) return ret; diff --git a/drivers/video/sunxi/tve.c b/drivers/video/sunxi/tve_common.c index adea78a69aa..adea78a69aa 100644 --- a/drivers/video/sunxi/tve.c +++ b/drivers/video/sunxi/tve_common.c |