sunxi: video: Force h/vsync active high when using ext. vga dac on some boards
Subsystems (2)
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
@@ -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
@@ -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
@@ -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
@@ -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 definedCONFIG_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
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->lowedge 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.
Signed-off-by Hans de Goede <[email protected]>
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@@ -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_LCDconfigs/A13-OLinuXinoM_defconfig +1
-0@@ -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@@ -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@@ -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 definedCONFIG_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 ();
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->lowedge 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.
Signed-off-by Hans de Goede <[email protected]>Acked-by Ian Campbell <[email protected]>
Thanks.
Quoted 4 lines
Although I might have been tempted to adjust
mode->syncin 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
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->syncin 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.