]> git.sur5r.net Git - u-boot/blobdiff - drivers/video/sunxi_display.c
dm: video: Add a 'normal' text console driver
[u-boot] / drivers / video / sunxi_display.c
index f5deca35abc5bff90b9a11c3bdccd83ac3e91f04..9fee66a2a450b84645e855e0a0c9fc7f4593112a 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/global_data.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <axp_pmic.h>
 #include <errno.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
@@ -22,6 +23,7 @@
 #include <malloc.h>
 #include <video_fb.h>
 #include "videomodes.h"
+#include "anx9804.h"
 #include "hitachi_tx18d42vm_lcd.h"
 #include "ssd2828.h"
 
@@ -521,6 +523,7 @@ static void sunxi_lcdc_pll_set(int tcon, int dotclock,
        int value, n, m, min_m, max_m, diff;
        int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF;
        int best_double = 0;
+       bool use_mipi_pll = false;
 
        if (tcon == 0) {
 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
@@ -571,16 +574,42 @@ static void sunxi_lcdc_pll_set(int tcon, int dotclock,
                }
        }
 
-       debug("dotclock: %dkHz = %dkHz: (%d * 3MHz * %d) / %d\n",
-             dotclock, (best_double + 1) * 3000 * best_n / best_m,
-             best_double + 1, best_n, best_m);
+#ifdef CONFIG_MACH_SUN6I
+       /*
+        * Use the MIPI pll if we've been unable to find any matching setting
+        * for PLL3, this happens with high dotclocks because of min_m = 6.
+        */
+       if (tcon == 0 && best_n == 0) {
+               use_mipi_pll = true;
+               best_m = 6;  /* Minimum m for tcon0 */
+       }
 
-       clock_set_pll3(best_n * 3000000);
+       if (use_mipi_pll) {
+               clock_set_pll3(297000000); /* Fix the video pll at 297 MHz */
+               clock_set_mipi_pll(best_m * dotclock * 1000);
+               debug("dotclock: %dkHz = %dkHz via mipi pll\n",
+                     dotclock, clock_get_mipi_pll() / best_m / 1000);
+       } else
+#endif
+       {
+               clock_set_pll3(best_n * 3000000);
+               debug("dotclock: %dkHz = %dkHz: (%d * 3MHz * %d) / %d\n",
+                     dotclock,
+                     (best_double + 1) * clock_get_pll3() / best_m / 1000,
+                     best_double + 1, best_n, best_m);
+       }
 
        if (tcon == 0) {
-               writel(CCM_LCD_CH0_CTRL_GATE | CCM_LCD_CH0_CTRL_RST |
-                      (best_double ? CCM_LCD_CH0_CTRL_PLL3_2X :
-                                     CCM_LCD_CH0_CTRL_PLL3),
+               u32 pll;
+
+               if (use_mipi_pll)
+                       pll = CCM_LCD_CH0_CTRL_MIPI_PLL;
+               else if (best_double)
+                       pll = CCM_LCD_CH0_CTRL_PLL3_2X;
+               else
+                       pll = CCM_LCD_CH0_CTRL_PLL3;
+
+               writel(CCM_LCD_CH0_CTRL_GATE | CCM_LCD_CH0_CTRL_RST | pll,
                       &ccm->lcd0_ch0_clk_cfg);
        } else {
                writel(CCM_LCD_CH1_CTRL_GATE |
@@ -738,13 +767,17 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
                (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
        int bp, clk_delay, clk_div, clk_double, pin, total, val;
 
-       for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++)
+       for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++) {
 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
                sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0);
 #endif
 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
                sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0);
 #endif
+#ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
+               sunxi_gpio_set_drv(pin, 3);
+#endif
+       }
 
        sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double);
 
@@ -1181,6 +1214,17 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
                break;
        case sunxi_monitor_lcd:
                sunxi_lcdc_panel_enable();
+               if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804)) {
+                       /*
+                        * The anx9804 needs 1.8V from eldo3, we do this here
+                        * and not via CONFIG_AXP_ELDO3_VOLT from board_init()
+                        * to avoid turning this on when using hdmi output.
+                        */
+                       axp_set_eldo(3, 1800);
+                       anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4,
+                                    ANX9804_DATA_RATE_1620M,
+                                    sunxi_display.depth);
+               }
                if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
                        mdelay(50); /* Wait for lcd controller power on */
                        hitachi_tx18d42vm_init();