Skip to contentSkip to conversation

sunxi: display: add support for eDP panels connected via an anx9804 bridge chip

PATCH New Hans de Goede 4 participants 17 messages Aug 8, 2015 – Aug 12, 2015

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover sunxi: display: add support for eDP panels connected via an anx9804 bridge chip

Hi Ian and Anatolij,

Here is a patch series adding support for eDP panels connected via an anx9804 bridge chip.

Most of this series touches sunxi only files, except for the commit adding the anx9804 bridge driver, which is a generic driver which should hopefully be useful elsewhere too.

Anatolij, can we have your ack for merging this new video bridge chip driver via the sunxi tree ?

Regards,

Hans

#1 lore raw

PATCH 1/5 sunxi: clock: Add clock_get_pll3() helper function

Add a helper function to get the pll3 clock rate.

---
 arch/arm/cpu/armv7/sunxi/clock_sun4i.c        |  9 +++++++++
 arch/arm/cpu/armv7/sunxi/clock_sun6i.c        | 12 ++++++++++++
 arch/arm/include/asm/arch-sunxi/clock_sun4i.h |  3 +++
 arch/arm/include/asm/arch-sunxi/clock_sun6i.h |  5 +++++
 4 files changed, 29 insertions(+)
arch/arm/cpu/armv7/sunxi/clock_sun4i.c +9 -0
index c3e04af..7c8eff9 100644
@@ -198,6 +198,15 @@ void clock_set_pll3(unsigned int clk)
 	       CCM_PLL3_CTRL_M(clk / 3000000), &ccm->pll3_cfg);
 }
 
+unsigned int clock_get_pll3(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	uint32_t rval = readl(&ccm->pll3_cfg);
+	int m = ((rval & CCM_PLL3_CTRL_M_MASK) >> CCM_PLL3_CTRL_M_SHIFT);
+	return 3000000 * m;
+}
+
 unsigned int clock_get_pll5p(void)
 {
 	struct sunxi_ccm_reg *const ccm =
arch/arm/cpu/armv7/sunxi/clock_sun6i.c +12 -0
index 3bfa122..1d6f839 100644
@@ -188,6 +188,18 @@ void clock_set_pll11(unsigned int clk, bool sigma_delta_enable)
 }
 #endif
 
+unsigned int clock_get_pll3(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	uint32_t rval = readl(&ccm->pll3_cfg);
+	int n = ((rval & CCM_PLL3_CTRL_N_MASK) >> CCM_PLL3_CTRL_N_SHIFT) + 1;
+	int m = ((rval & CCM_PLL3_CTRL_M_MASK) >> CCM_PLL3_CTRL_M_SHIFT) + 1;
+
+	/* Multiply by 1000 after dividing by m to avoid integer overflows */
+	return (24000 * n / m) * 1000;
+}
+
 unsigned int clock_get_pll6(void)
 {
 	struct sunxi_ccm_reg *const ccm =
arch/arm/include/asm/arch-sunxi/clock_sun4i.h +3 -0
index b397809..1a0b525 100644
@@ -208,6 +208,8 @@ struct sunxi_ccm_reg {
 #define CCM_AHB_GATE_DLL (0x1 << 15)
 #define CCM_AHB_GATE_ACE (0x1 << 16)
 
+#define CCM_PLL3_CTRL_M_SHIFT		0
+#define CCM_PLL3_CTRL_M_MASK		(0x7f << CCM_PLL3_CTRL_M_SHIFT)
 #define CCM_PLL3_CTRL_M(n)		(((n) & 0x7f) << 0)
 #define CCM_PLL3_CTRL_INTEGER_MODE	(0x1 << 15)
 #define CCM_PLL3_CTRL_EN		(0x1 << 31)
@@ -347,6 +349,7 @@ struct sunxi_ccm_reg {
 #ifndef __ASSEMBLY__
 void clock_set_pll1(unsigned int hz);
 void clock_set_pll3(unsigned int hz);
+unsigned int clock_get_pll3(void);
 unsigned int clock_get_pll5p(void);
 unsigned int clock_get_pll6(void);
 #endif
arch/arm/include/asm/arch-sunxi/clock_sun6i.h +5 -0
index 06c6feb..a197345 100644
@@ -179,7 +179,11 @@ struct sunxi_ccm_reg {
 #define CCM_PLL1_CTRL_P(n)		(((n) & 0x3) << 16)
 #define CCM_PLL1_CTRL_EN		(0x1 << 31)
 
+#define CCM_PLL3_CTRL_M_SHIFT		0
+#define CCM_PLL3_CTRL_M_MASK		(0xf << CCM_PLL3_CTRL_M_SHIFT)
 #define CCM_PLL3_CTRL_M(n)		((((n) - 1) & 0xf) << 0)
+#define CCM_PLL3_CTRL_N_SHIFT		8
+#define CCM_PLL3_CTRL_N_MASK		(0x7f << CCM_PLL3_CTRL_N_SHIFT)
 #define CCM_PLL3_CTRL_N(n)		((((n) - 1) & 0x7f) << 8)
 #define CCM_PLL3_CTRL_INTEGER_MODE	(0x1 << 24)
 #define CCM_PLL3_CTRL_EN		(0x1 << 31)
@@ -360,6 +364,7 @@ void clock_set_pll1(unsigned int hz);
 void clock_set_pll3(unsigned int hz);
 void clock_set_pll5(unsigned int clk, bool sigma_delta_enable);
 void clock_set_pll11(unsigned int clk, bool sigma_delta_enable);
+unsigned int clock_get_pll3(void);
 unsigned int clock_get_pll6(void);
 #endif
 
Signature · 1 line
2.4.3
#3 lore raw

PATCH 2/5 sun6i: clock: Add support for the mipi pll

In reply to Hans de Goede

Add support for the mipi pll, this is necessary for getting higher dotclocks with lcd panels.

---
 arch/arm/cpu/armv7/sunxi/clock_sun6i.c        | 55 +++++++++++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/clock_sun4i.h |  1 +
 arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 14 +++++++
 3 files changed, 70 insertions(+)
arch/arm/cpu/armv7/sunxi/clock_sun6i.c +55 -0
index 1d6f839..3ab3b31 100644
@@ -170,6 +170,47 @@ void clock_set_pll5(unsigned int clk, bool sigma_delta_enable)
 	udelay(5500);
 }
 
+#ifdef CONFIG_MACH_SUN6I
+void clock_set_mipi_pll(unsigned int clk)
+{
+	struct sunxi_ccm_reg * const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	unsigned int k, m, n, value, diff;
+	unsigned best_k = 0, best_m = 0, best_n = 0, best_diff = 0xffffffff;
+	unsigned int src = clock_get_pll3();
+
+	/* All calculations are in KHz to avoid overflows */
+	clk /= 1000;
+	src /= 1000;
+
+	/* Pick the closest lower clock */
+	for (k = 1; k <= 4; k++) {
+		for (m = 1; m <= 16; m++) {
+			for (n = 1; n <= 16; n++) {
+				value = src * n * k / m;
+				if (value > clk)
+					continue;
+
+				diff = clk - value;
+				if (diff < best_diff) {
+					best_diff = diff;
+					best_k = k;
+					best_m = m;
+					best_n = n;
+				}
+				if (diff == 0)
+					goto done;
+			}
+		}
+	}
+
+done:
+	writel(CCM_MIPI_PLL_CTRL_EN | CCM_MIPI_PLL_CTRL_LDO_EN |
+	       CCM_MIPI_PLL_CTRL_N(best_n) | CCM_MIPI_PLL_CTRL_K(best_k) |
+	       CCM_MIPI_PLL_CTRL_M(best_m), &ccm->mipi_pll_cfg);
+}
+#endif
+
 #ifdef CONFIG_MACH_SUN8I_A33
 void clock_set_pll11(unsigned int clk, bool sigma_delta_enable)
 {
@@ -210,6 +251,20 @@ unsigned int clock_get_pll6(void)
 	return 24000000 * n * k / 2;
 }
 
+unsigned int clock_get_mipi_pll(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	uint32_t rval = readl(&ccm->mipi_pll_cfg);
+	unsigned int n = ((rval & CCM_MIPI_PLL_CTRL_N_MASK) >> CCM_MIPI_PLL_CTRL_N_SHIFT) + 1;
+	unsigned int k = ((rval & CCM_MIPI_PLL_CTRL_K_MASK) >> CCM_MIPI_PLL_CTRL_K_SHIFT) + 1;
+	unsigned int m = ((rval & CCM_MIPI_PLL_CTRL_M_MASK) >> CCM_MIPI_PLL_CTRL_M_SHIFT) + 1;
+	unsigned int src = clock_get_pll3();
+
+	/* Multiply by 1000 after dividing by m to avoid integer overflows */
+	return ((src / 1000) * n * k / m) * 1000;
+}
+
 void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz)
 {
 	int pll = clock_get_pll6() * 2;
arch/arm/include/asm/arch-sunxi/clock_sun4i.h +1 -0
index 1a0b525..0088bb9 100644
@@ -289,6 +289,7 @@ struct sunxi_ccm_reg {
 #define CCM_LCD_CH0_CTRL_PLL7		(1 << 24)
 #define CCM_LCD_CH0_CTRL_PLL3_2X	(2 << 24)
 #define CCM_LCD_CH0_CTRL_PLL7_2X	(3 << 24)
+#define CCM_LCD_CH0_CTRL_MIPI_PLL	0 /* No mipi pll on sun4i/5i/7i */
 #ifdef CONFIG_MACH_SUN5I
 #define CCM_LCD_CH0_CTRL_TVE_RST	(0x1 << 29)
 #else
arch/arm/include/asm/arch-sunxi/clock_sun6i.h +14 -0
index a197345..9b7b90c 100644
@@ -202,6 +202,18 @@ struct sunxi_ccm_reg {
 #define CCM_PLL6_CTRL_K_SHIFT		4
 #define CCM_PLL6_CTRL_K_MASK		(0x3 << CCM_PLL6_CTRL_K_SHIFT)
 
+#define CCM_MIPI_PLL_CTRL_M_SHIFT	0
+#define CCM_MIPI_PLL_CTRL_M_MASK	(0xf << CCM_MIPI_PLL_CTRL_M_SHIFT)
+#define CCM_MIPI_PLL_CTRL_M(n)		((((n) - 1) & 0xf) << 0)
+#define CCM_MIPI_PLL_CTRL_K_SHIFT	4
+#define CCM_MIPI_PLL_CTRL_K_MASK	(0x3 << CCM_MIPI_PLL_CTRL_K_SHIFT)
+#define CCM_MIPI_PLL_CTRL_K(n)		((((n) - 1) & 0x3) << 4)
+#define CCM_MIPI_PLL_CTRL_N_SHIFT	8
+#define CCM_MIPI_PLL_CTRL_N_MASK	(0xf << CCM_MIPI_PLL_CTRL_N_SHIFT)
+#define CCM_MIPI_PLL_CTRL_N(n)		((((n) - 1) & 0xf) << 8)
+#define CCM_MIPI_PLL_CTRL_LDO_EN	(0x3 << 22)
+#define CCM_MIPI_PLL_CTRL_EN		(0x1 << 31)
+
 #define CCM_PLL11_CTRL_N(n)		((((n) - 1) & 0x3f) << 8)
 #define CCM_PLL11_CTRL_SIGMA_DELTA_EN	(0x1 << 24)
 #define CCM_PLL11_CTRL_UPD		(0x1 << 30)
@@ -364,8 +376,10 @@ void clock_set_pll1(unsigned int hz);
 void clock_set_pll3(unsigned int hz);
 void clock_set_pll5(unsigned int clk, bool sigma_delta_enable);
 void clock_set_pll11(unsigned int clk, bool sigma_delta_enable);
+void clock_set_mipi_pll(unsigned int hz);
 unsigned int clock_get_pll3(void);
 unsigned int clock_get_pll6(void);
+unsigned int clock_get_mipi_pll(void);
 #endif
 
 #endif /* _SUNXI_CLOCK_SUN6I_H */
Signature · 1 line
2.4.3
#5 lore raw

PATCH 2/5 sun6i: clock: Add support for the mipi pll

In reply to Hans de Goede
Quoted 2 lines · Hans de Goede

Add support for the mipi pll, this is necessary for getting higher dotclocks with lcd panels.

Do you plan on adding this to the kernel (both the clock driver and reference in the simplefb node) as well?

ChenYu

Quoted 6 lines
---
 arch/arm/cpu/armv7/sunxi/clock_sun6i.c        | 55 +++++++++++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/clock_sun4i.h |  1 +
 arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 14 +++++++
 3 files changed, 70 insertions(+)
#6 lore raw

PATCH 2/5 sun6i: clock: Add support for the mipi pll

Hi,

Quoted 6 lines · Chen-Yu Tsai
Quoted 2 lines · Hans de Goede

Add support for the mipi pll, this is necessary for getting higher dotclocks with lcd panels.

Do you plan on adding this to the kernel (both the clock driver and reference in the simplefb node) as well?

Not at this time, once we have a kms driver in the kernel, and figured out how to add support for bridge chips like these, we are going to need support for this to support high res lcd panels though.

Regards,

Hans

#7 lore raw

PATCH 3/5 sun6i: display: Add support for using the mipi pll as lcd clock source

In reply to Hans de Goede

Add support for using the mipi pll as lcd clock source, this is necessary for getting higher dotclocks with lcd panels.

---
 drivers/video/sunxi_display.c | 41 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 7 deletions(-)
drivers/video/sunxi_display.c +34 -7
index 75acf84..aad870e 100644
@@ -521,6 +521,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 +572,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 |
Signature · 1 line
2.4.3
#10 lore raw

PATCH 4/5 video: Add support for the ANX9804 parallel lcd to dp bridge chip

In reply to Hans de Goede

Add support for the ANX9804 bridge chip, which can take pixel data coming from a parallel LCD interface and translate it on the flight into a DP interface for driving eDP TFT displays. It uses I2C for configuration.

---
 drivers/video/Kconfig   |   8 +++
 drivers/video/Makefile  |   1 +
 drivers/video/anx9804.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/video/anx9804.h |  25 +++++++
 4 files changed, 222 insertions(+)
 create mode 100755 drivers/video/anx9804.c
 create mode 100644 drivers/video/anx9804.h
drivers/video/Kconfig +8 -0
index 9ae23e8..71cbff9 100644
@@ -145,6 +145,14 @@ config FRAMEBUFFER_VESA_MODE
 	default 0x11B if FRAMEBUFFER_VESA_MODE_11B
 	default 0x117 if FRAMEBUFFER_VESA_MODE_USER
 
+config VIDEO_LCD_ANX9804
+	bool "ANX9804 bridge chip"
+	default n
+	---help---
+	Support for the ANX9804 bridge chip, which can take pixel data coming
+	from a parallel LCD interface and translate it on the flight into a DP
+	interface for driving eDP TFT displays. It uses I2C for configuration.
+
 config VIDEO_LCD_SSD2828
 	bool "SSD2828 bridge chip"
 	default n
drivers/video/Makefile +1 -0
index 2ead7f1..e414e8c 100644
@@ -33,6 +33,7 @@ obj-$(CONFIG_VIDEO_COREBOOT) += coreboot_fb.o
 obj-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o
 obj-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o
 obj-$(CONFIG_VIDEO_IMX25LCDC) += imx25lcdc.o videomodes.o
+obj-$(CONFIG_VIDEO_LCD_ANX9804) += anx9804.o
 obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o
 obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o
 obj-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o
drivers/video/anx9804.c new file +188 -0

188 lines not on this page · raw message

drivers/video/anx9804.h new file +25 -0
new file mode 100644
index 0000000..6c5daf9
@@ -0,0 +1,25 @@
+/*
+ * (C) 2015 Hans de Goede <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Support for the ANX9804 bridge chip, which can take pixel data coming
+ * from a parallel LCD interface and translate it on the flight into a DP
+ * interface for driving eDP TFT displays.
+ */
+
+#ifndef _ANX9804_H
+#define _ANX9804_H
+
+#define ANX9804_DATA_RATE_1620M				0x06
+#define ANX9804_DATA_RATE_2700M				0x0a
+
+#ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
+void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate, int bpp);
+#else
+static inline void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate,
+				int bpp) {}
+#endif
+#endif
Signature · 1 line
2.4.3
#11 lore raw

PATCH 4/5 video: Add support for the ANX9804 parallel lcd to dp bridge chip

Quoted 2 lines · Hans de Goede

Add support for the ANX9804 bridge chip, which can take pixel data coming from a parallel LCD interface and translate it on the flight into a DP

I think you meant "on the fly" (in the Kconfig too).

The driver itself looks pretty straight forward to me, but I'll leave it to Anatolij to formally ack.

#12 lore raw

PATCH 4/5 video: Add support for the ANX9804 parallel lcd to dp bridge chip

Hi,

Quoted 5 lines · Ian Campbell
Quoted 2 lines · Hans de Goede

Add support for the ANX9804 bridge chip, which can take pixel data coming from a parallel LCD interface and translate it on the flight into a DP

I think you meant "on the fly" (in the Kconfig too).

Thanks, fixed in my personal tree.

Regards,

Hans

#13 lore raw

PATCH 4/5 video: Add support for the ANX9804 parallel lcd to dp bridge chip

In reply to Hans de Goede
Quoted 5 lines · On Sat, 8 Aug 2015 16:25:03 +0200 Hans de Goede <[email protected]> wrote:

Add support for the ANX9804 bridge chip, which can take pixel data coming from a parallel LCD interface and translate it on the flight into a DP interface for driving eDP TFT displays. It uses I2C for configuration.

#14 lore raw

PATCH 5/5 sunxi: Display: Add support for eDP panels connected via an anx9804 bridge

In reply to Hans de Goede

Add support for 4 1.62G lane eDP panels connected via an anx9804 bridge, such as found on the Colombus devkit.

While at it also fix the wrong indentation of the SSD2828 Kconfig help text in board/sunxi/Kconfig.

---
 board/sunxi/Kconfig            | 11 ++++++++++-
 configs/Colombus_defconfig     | 11 +++++++++++
 drivers/video/sunxi_display.c  | 19 ++++++++++++++++++-
 include/configs/sunxi-common.h |  4 ++++
 4 files changed, 43 insertions(+), 2 deletions(-)
board/sunxi/Kconfig +10 -1
index 13f4537..fd6668f 100644
@@ -526,7 +526,16 @@ config VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828
 	select VIDEO_LCD_SSD2828
 	select VIDEO_LCD_IF_PARALLEL
 	---help---
-	 7.85" 768x1024 LCD panels, such as LG LP079X01 or AUO B079XAN01.0
+	7.85" 768x1024 LCD panels, such as LG LP079X01 or AUO B079XAN01.0
+
+config VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
+	bool "eDP 4-lane, 1.62G LCD panel via ANX9804 bridge chip"
+	select VIDEO_LCD_ANX9804
+	select VIDEO_LCD_IF_PARALLEL
+	select VIDEO_LCD_PANEL_I2C
+	---help---
+	Select this for eDP LCD panels with 4 lanes running at 1.62G,
+	connected via an ANX9804 bridge chip.
 
 config VIDEO_LCD_PANEL_HITACHI_TX18D42VM
 	bool "Hitachi tx18d42vm LCD panel"
configs/Colombus_defconfig +11 -0
index 7fa9ef1..35f644a 100644
@@ -4,6 +4,16 @@ CONFIG_MACH_SUN6I=y
 CONFIG_DRAM_CLK=240
 CONFIG_DRAM_ZQ=251
 CONFIG_USB1_VBUS_PIN=""
+CONFIG_I2C0_ENABLE=y
+CONFIG_AXP_GPIO=y
+CONFIG_VIDEO_LCD_MODE="x:2048,y:1536,depth:24,pclk_khz:208000,le:5,ri:150,up:9,lo:24,hs:5,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=0
+CONFIG_VIDEO_LCD_POWER="PH27"
+CONFIG_VIDEO_LCD_BL_EN="PM1"
+CONFIG_VIDEO_LCD_BL_PWM="PH13"
+CONFIG_VIDEO_LCD_PANEL_I2C_SDA="PA23"
+CONFIG_VIDEO_LCD_PANEL_I2C_SCL="PA24"
+CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804=y
 CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-colombus"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL=y
@@ -13,4 +23,5 @@ CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII"
 # CONFIG_CMD_FPGA is not set
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_AXP221_ALDO1_VOLT=3300
+CONFIG_AXP221_ELDO3_VOLT=1800
 CONFIG_USB_EHCI_HCD=y
drivers/video/sunxi_display.c +18 -1
index aad870e..62cef87 100644
@@ -15,6 +15,7 @@
 #include <asm/global_data.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <axp221.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"
 
@@ -765,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);
 
@@ -1208,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_AXP221_ELDO3 from board_init()
+			 * to avoid turning this on when using hdmi output.
+			 */
+			axp221_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();
include/configs/sunxi-common.h +4 -0
index 83b6556..436c249 100644
@@ -290,7 +290,11 @@ extern int soft_i2c_gpio_scl;
  * The amount of RAM to keep free at the top of RAM when relocating u-boot,
  * to use as framebuffer. This must be a multiple of 4096.
  */
+#ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
+#define CONFIG_SUNXI_MAX_FB_SIZE (12 << 20)
+#else
 #define CONFIG_SUNXI_MAX_FB_SIZE (9 << 20)
+#endif
 
 /* Do we want to initialize a simple FB? */
 #define CONFIG_VIDEO_DT_SIMPLEFB
Signature · 1 line
2.4.3
#15 lore raw

PATCH 5/5 sunxi: Display: Add support for eDP panels connected via an anx9804 bridge

Quoted 9 lines · Hans de Goede

Add support for 4 1.62G lane eDP panels connected via an anx9804 bridge,
such as found on the Colombus devkit.

While at it also fix the wrong indentation of the SSD2828 Kconfig help text
in board/sunxi/Kconfig.

#16 lore raw

cover sunxi: display: add support for eDP panels connected via an anx9804 bridge chip

In reply to Hans de Goede

Hi Hans,

On Sat, 8 Aug 2015 16:24:59 +0200
Hans de Goede <[email protected]> wrote:
...

Quoted 2 lines

Anatolij, can we have your ack for merging this new video bridge chip driver via the sunxi tree ?

just replied with ack, please merge.

Thanks,

Anatolij