Merge branch 'master' of git://git.denx.de/u-boot-video
authorTom Rini <trini@konsulko.com>
Sat, 10 Jun 2017 13:48:09 +0000 (09:48 -0400)
committerTom Rini <trini@konsulko.com>
Sat, 10 Jun 2017 13:48:09 +0000 (09:48 -0400)
arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
arch/arm/include/asm/arch-sunxi/display2.h
common/edid.c
drivers/video/atmel_hlcdfb.c
drivers/video/rockchip/rk_hdmi.h
drivers/video/rockchip/rk_vop.h
drivers/video/sunxi/Makefile
drivers/video/sunxi/sunxi_de2.c
drivers/video/sunxi/tve_common.c [moved from drivers/video/sunxi/tve.c with 100% similarity]

index 6aa5e91..2419062 100644 (file)
@@ -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
 
index b5875f9..359cacd 100644 (file)
@@ -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.
  */
index 19410aa..854d40c 100644 (file)
@@ -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 */
index 47078fd..f77da2e 100644 (file)
@@ -426,7 +426,9 @@ static void atmel_hlcdc_init(struct udevice *dev)
        writel(~0UL, &regs->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, &regs->lcdc_baseaddr);
        writel(desc->control, &regs->lcdc_basectrl);
index 501ed3a..ec39668 100644 (file)
@@ -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
index 9bda514..b2b29c4 100644 (file)
@@ -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);
 
index dbaab61..0d64c20 100644 (file)
@@ -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
index 9a32c3a..ee67764 100644 (file)
@@ -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;