[U-Boot] [PATCH 1/2] sunxi: video: Fix lvds panel support for sun6i+

Hans de Goede hdegoede at redhat.com
Thu May 14 19:04:00 CEST 2015


We've never tested the lvds panel support on sun6i+ SoCs until now, and
unsurprisingly the lvds code needed some fixes to work on my ga10h A33
tablet with lvds panel. This makes the panel on that tablet actually work.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/include/asm/arch-sunxi/clock_sun6i.h |  3 +++
 arch/arm/include/asm/arch-sunxi/display.h     | 12 ++++++++++++
 drivers/video/sunxi_display.c                 | 18 +++++++++++++++++-
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index bacd70a..6465f21 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -331,6 +331,9 @@ struct sunxi_ccm_reg {
 #define AHB_RESET_OFFSET_LCD1		5
 #define AHB_RESET_OFFSET_LCD0		4
 
+/* ahb_reset2 offsets */
+#define AHB_RESET_OFFSET_LVDS		0
+
 /* apb2 reset */
 #define APB2_RESET_UART_SHIFT		(16)
 #define APB2_RESET_UART_MASK		(0xff << APB2_RESET_UART_SHIFT)
diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h
index 5e94253..ae95417 100644
--- a/arch/arm/include/asm/arch-sunxi/display.h
+++ b/arch/arm/include/asm/arch-sunxi/display.h
@@ -363,6 +363,11 @@ struct sunxi_tve_reg {
 #define SUNXI_LCDC_TCON0_TIMING_H_TOTAL(n)	(((n) - 1) << 16)
 #define SUNXI_LCDC_TCON0_TIMING_V_BP(n)		(((n) - 1) << 0)
 #define SUNXI_LCDC_TCON0_TIMING_V_TOTAL(n)	(((n) * 2) << 16)
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+#define SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0	(1 << 20)
+#else
+#define SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0	0 /* NA */
+#endif
 #define SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(n)	((n) << 26)
 #define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE	(1 << 31)
 #define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(x)	((x) << 28)
@@ -372,8 +377,15 @@ struct sunxi_tve_reg {
 #define SUNXI_LCDC_TCON1_TIMING_H_TOTAL(n)	(((n) - 1) << 16)
 #define SUNXI_LCDC_TCON1_TIMING_V_BP(n)		(((n) - 1) << 0)
 #define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n)	(((n) * 2) << 16)
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+#define SUNXI_LCDC_LVDS_ANA0			0x40040320
+#define SUNXI_LCDC_LVDS_ANA0_EN_MB		(1 << 31)
+#define SUNXI_LCDC_LVDS_ANA0_DRVC		(1 << 24)
+#define SUNXI_LCDC_LVDS_ANA0_DRVD(x)		((x) << 20)
+#else
 #define SUNXI_LCDC_LVDS_ANA0			0x3f310000
 #define SUNXI_LCDC_LVDS_ANA0_UPDATE		(1 << 22)
+#endif
 #define SUNXI_LCDC_LVDS_ANA1_INIT1		(0x1f << 26 | 0x1f << 10)
 #define SUNXI_LCDC_LVDS_ANA1_INIT2		(0x1f << 16 | 0x1f << 00)
 
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 48dbdf5..269083b 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -558,8 +558,12 @@ static void sunxi_lcdc_init(void)
 	/* Clock on */
 	setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0);
 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+	setbits_le32(&ccm->ahb_reset2_cfg, 1 << AHB_RESET_OFFSET_LVDS);
+#else
 	setbits_le32(&ccm->lvds_clk_cfg, CCM_LVDS_CTRL_RST);
 #endif
+#endif
 
 	/* Init lcdc */
 	writel(0, &lcdc->ctrl); /* Disable tcon */
@@ -582,6 +586,16 @@ static void sunxi_lcdc_enable(void)
 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
 	setbits_le32(&lcdc->tcon0_lvds_intf, SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE);
 	setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0);
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+	udelay(2); /* delay at least 1200 ns */
+	setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_EN_MB);
+	udelay(2); /* delay at least 1200 ns */
+	setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVC);
+	if (sunxi_display.depth == 18)
+		setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0x7));
+	else
+		setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0xf));
+#else
 	setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
 	udelay(2); /* delay at least 1200 ns */
 	setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT1);
@@ -589,6 +603,7 @@ static void sunxi_lcdc_enable(void)
 	setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT2);
 	setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
 #endif
+#endif
 }
 
 static void sunxi_lcdc_panel_enable(void)
@@ -706,7 +721,8 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
 #endif
 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
 	val = (sunxi_display.depth == 18) ? 1 : 0;
-	writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val), &lcdc->tcon0_lvds_intf);
+	writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val) |
+	       SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0, &lcdc->tcon0_lvds_intf);
 #endif
 
 	if (sunxi_display.depth == 18 || sunxi_display.depth == 16) {
-- 
2.3.6



More information about the U-Boot mailing list