Skip to contentSkip to conversation

sunxi: video: Force h/vsync active high when using ext. vga dac on some boards

PATCH Superseded Hans de Goede 2 participants 4 messages Jan 28, 2015

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

PATCH v2 1/1 sunxi: video: Force h/vsync active high when using ext. vga dac on some boards

On both my A13-OLinuxIno and my A13-OLinuxIno-Micro, the vga output gives an unstable image when active low v or hsync is used.

The problem seems to be specific to the OLinuxIno A13 (normal & micro) boards. I've just looked up the schematics and they use an opendrain driver for the vga sync lines, and with sync pulses it is the logical high->low edge of the pulse which counts for the timing, which with an active low sync is being driven by the pull-up, and that simply seems to not drive it hard enough to get a stable image.

So force v and hsync active high on these boards. independent of what the modeline says. This fixes the unstable image.

---
 board/sunxi/Kconfig              | 10 ++++++++++
 configs/A13-OLinuXinoM_defconfig |  1 +
 configs/A13-OLinuXino_defconfig  |  1 +
 drivers/video/sunxi_display.c    | 12 +++++++++---
 4 files changed, 21 insertions(+), 3 deletions(-)
board/sunxi/Kconfig +10 -0
index 8b94311..ab884dc 100644
@@ -190,6 +190,16 @@ config VIDEO_VGA_VIA_LCD
 	LCD interface driving a VGA connector, such as found on the
 	Olimex A13 boards.
 
+config VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH
+	boolean "Force sync active high for VGA via LCD controller support"
+	depends on VIDEO_VGA_VIA_LCD
+	default n
+	---help---
+	Say Y here if you've a board which uses opendrain drivers for the vga
+	hsync and vsync signals. Opendrain drivers cannot generate steep enough
+	positive edges for a stable video output, so on boards with opendrain
+	drivers the sync signals must always be active high.
+
 config VIDEO_VGA_EXTERNAL_DAC_EN
 	string "LCD panel power enable pin"
 	depends on VIDEO_VGA_VIA_LCD
configs/A13-OLinuXinoM_defconfig +1 -0
index 1c3fc3a..a04f2b3 100644
@@ -4,6 +4,7 @@ CONFIG_FDTFILE="sun5i-a13-olinuxino-micro.dtb"
 CONFIG_USB1_VBUS_PIN="PG11"
 CONFIG_VIDEO_HDMI=n
 CONFIG_VIDEO_VGA_VIA_LCD=y
+CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
 # For use with the Olimex 7" LCD module, adjust timings for other displays
 # Set video-mode=sunxi:800x600-24 at 60,monitor=lcd in the env. to enable
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
configs/A13-OLinuXino_defconfig +1 -0
index 0daaaae..806d5b7 100644
@@ -4,6 +4,7 @@ CONFIG_FDTFILE="sun5i-a13-olinuxino.dtb"
 CONFIG_USB1_VBUS_PIN="PG11"
 CONFIG_VIDEO_HDMI=n
 CONFIG_VIDEO_VGA_VIA_LCD=y
+CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
 # For use with the Olimex 7" LCD module, adjust timings for other displays
 # Set video-mode=sunxi:800x600-24 at 60,monitor=lcd in the env. to enable
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
drivers/video/sunxi_display.c +9 -3
index af728b5..f5f24fc 100644
@@ -645,7 +645,8 @@ static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode)
 	return (delay > 30) ? 30 : delay;
 }
 
-static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode)
+static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
+				      bool for_ext_vga_dac)
 {
 	struct sunxi_lcdc_reg * const lcdc =
 		(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
@@ -719,6 +720,11 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode)
 		val |= SUNXI_LCDC_TCON_HSYNC_MASK;
 	if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
 		val |= SUNXI_LCDC_TCON_VSYNC_MASK;
+
+#ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH
+	if (for_ext_vga_dac)
+		val = 0;
+#endif
 	writel(val, &lcdc->tcon0_io_polarity);
 
 	writel(0, &lcdc->tcon0_io_tristate);
@@ -1015,7 +1021,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 			hitachi_tx18d42vm_init();
 		}
 		sunxi_composer_mode_set(mode, address);
-		sunxi_lcdc_tcon0_mode_set(mode);
+		sunxi_lcdc_tcon0_mode_set(mode, false);
 		sunxi_composer_enable();
 		sunxi_lcdc_enable();
 #ifdef CONFIG_VIDEO_LCD_SSD2828
@@ -1033,7 +1039,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 		sunxi_vga_enable();
 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
 		sunxi_composer_mode_set(mode, address);
-		sunxi_lcdc_tcon0_mode_set(mode);
+		sunxi_lcdc_tcon0_mode_set(mode, true);
 		sunxi_composer_enable();
 		sunxi_lcdc_enable();
 		sunxi_vga_external_dac_enable();
Signature · 1 line
2.1.0
#1 lore raw

PATCH v2 1/1 sunxi: video: Force h/vsync active high when using ext. vga dac on some boards

Quoted 10 lines · Hans de Goede

On both my A13-OLinuxIno and my A13-OLinuxIno-Micro, the vga output gives an unstable image when active low v or hsync is used.

The problem seems to be specific to the OLinuxIno A13 (normal & micro) boards. I've just looked up the schematics and they use an opendrain driver for the vga sync lines, and with sync pulses it is the logical high->low edge of the pulse which counts for the timing, which with an active low sync is being driven by the pull-up, and that simply seems to not drive it hard enough to get a stable image.

Quoted 4 lines

So force v and hsync active high on these boards. independent of what the modeline says. This fixes the unstable image.

Although I might have been tempted to adjust mode->sync in the caller or the place which populates it in the first place, just due to a general dislike of boolean params to functions (which are opaque at the caller) and to keep mode in sync with reality (if that matters).

Ian.

Quoted 96 lines
---
 board/sunxi/Kconfig              | 10 ++++++++++
 configs/A13-OLinuXinoM_defconfig |  1 +
 configs/A13-OLinuXino_defconfig  |  1 +
 drivers/video/sunxi_display.c    | 12 +++++++++---
 4 files changed, 21 insertions(+), 3 deletions(-)
board/sunxi/Kconfig +10 -0
index 8b94311..ab884dc 100644
@@ -190,6 +190,16 @@ config VIDEO_VGA_VIA_LCD
 	LCD interface driving a VGA connector, such as found on the
 	Olimex A13 boards.
 
+config VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH
+	boolean "Force sync active high for VGA via LCD controller support"
+	depends on VIDEO_VGA_VIA_LCD
+	default n
+	---help---
+	Say Y here if you've a board which uses opendrain drivers for the vga
+	hsync and vsync signals. Opendrain drivers cannot generate steep enough
+	positive edges for a stable video output, so on boards with opendrain
+	drivers the sync signals must always be active high.
+
 config VIDEO_VGA_EXTERNAL_DAC_EN
 	string "LCD panel power enable pin"
 	depends on VIDEO_VGA_VIA_LCD
configs/A13-OLinuXinoM_defconfig +1 -0
index 1c3fc3a..a04f2b3 100644
@@ -4,6 +4,7 @@ CONFIG_FDTFILE="sun5i-a13-olinuxino-micro.dtb"
 CONFIG_USB1_VBUS_PIN="PG11"
 CONFIG_VIDEO_HDMI=n
 CONFIG_VIDEO_VGA_VIA_LCD=y
+CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
 # For use with the Olimex 7" LCD module, adjust timings for other displays
 # Set video-mode=sunxi:800x600-24 at 60,monitor=lcd in the env. to enable
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
configs/A13-OLinuXino_defconfig +1 -0
index 0daaaae..806d5b7 100644
@@ -4,6 +4,7 @@ CONFIG_FDTFILE="sun5i-a13-olinuxino.dtb"
 CONFIG_USB1_VBUS_PIN="PG11"
 CONFIG_VIDEO_HDMI=n
 CONFIG_VIDEO_VGA_VIA_LCD=y
+CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
 # For use with the Olimex 7" LCD module, adjust timings for other displays
 # Set video-mode=sunxi:800x600-24 at 60,monitor=lcd in the env. to enable
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
drivers/video/sunxi_display.c +9 -3
index af728b5..f5f24fc 100644
@@ -645,7 +645,8 @@ static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode)
 	return (delay > 30) ? 30 : delay;
 }
 
-static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode)
+static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
+				      bool for_ext_vga_dac)
 {
 	struct sunxi_lcdc_reg * const lcdc =
 		(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
@@ -719,6 +720,11 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode)
 		val |= SUNXI_LCDC_TCON_HSYNC_MASK;
 	if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
 		val |= SUNXI_LCDC_TCON_VSYNC_MASK;
+
+#ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH
+	if (for_ext_vga_dac)
+		val = 0;
+#endif
 	writel(val, &lcdc->tcon0_io_polarity);
 
 	writel(0, &lcdc->tcon0_io_tristate);
@@ -1015,7 +1021,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 			hitachi_tx18d42vm_init();
 		}
 		sunxi_composer_mode_set(mode, address);
-		sunxi_lcdc_tcon0_mode_set(mode);
+		sunxi_lcdc_tcon0_mode_set(mode, false);
 		sunxi_composer_enable();
 		sunxi_lcdc_enable();
 #ifdef CONFIG_VIDEO_LCD_SSD2828
@@ -1033,7 +1039,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 		sunxi_vga_enable();
 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
 		sunxi_composer_mode_set(mode, address);
-		sunxi_lcdc_tcon0_mode_set(mode);
+		sunxi_lcdc_tcon0_mode_set(mode, true);
 		sunxi_composer_enable();
 		sunxi_lcdc_enable();
 		sunxi_vga_external_dac_enable();
#2 lore raw

PATCH v2 1/1 sunxi: video: Force h/vsync active high when using ext. vga dac on some boards

Hi,

Quoted 11 lines · Ian Campbell
Quoted 10 lines · Hans de Goede

On both my A13-OLinuxIno and my A13-OLinuxIno-Micro, the vga output gives an unstable image when active low v or hsync is used.

The problem seems to be specific to the OLinuxIno A13 (normal & micro) boards. I've just looked up the schematics and they use an opendrain driver for the vga sync lines, and with sync pulses it is the logical high->low edge of the pulse which counts for the timing, which with an active low sync is being driven by the pull-up, and that simply seems to not drive it hard enough to get a stable image.

Quoted 6 lines
Quoted 4 lines

So force v and hsync active high on these boards. independent of what the modeline says. This fixes the unstable image.

Thanks.

Quoted 4 lines

Although I might have been tempted to adjust mode->sync in the caller or the place which populates it in the first place, just due to a general dislike of boolean params to functions (which are opaque at the caller) and to keep mode in sync with reality (if that matters).

I had the same idea, but mode can point to the global fixed mode list, so it is: "const struct ctfb_res_modes *mode" and we cannot change what a const pointer points too.

Regards,

Hans

#3 lore raw

PATCH v2 1/1 sunxi: video: Force h/vsync active high when using ext. vga dac on some boards

Quoted 8 lines · Hans de Goede
Quoted 4 lines

Although I might have been tempted to adjust mode->sync in the caller or the place which populates it in the first place, just due to a general dislike of boolean params to functions (which are opaque at the caller) and to keep mode in sync with reality (if that matters).

I had the same idea, but mode can point to the global fixed mode list, so it is: "const struct ctfb_res_modes *mode" and we cannot change what a const pointer points too.

Ah, then no, that won't work will it ;-).

Ian.