From fb75d972eaf5c887ada28e73d3e84d52931d4cb0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 25 Jan 2015 15:33:07 +0100 Subject: [PATCH] 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. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- 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(-) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 4b31dcca20..adbd2b5716 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -185,6 +185,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 diff --git a/configs/A13-OLinuXinoM_defconfig b/configs/A13-OLinuXinoM_defconfig index 1c3fc3a3e9..a04f2b3362 100644 --- a/configs/A13-OLinuXinoM_defconfig +++ b/configs/A13-OLinuXinoM_defconfig @@ -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@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" diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig index 0daaaae5b4..806d5b7bd5 100644 --- a/configs/A13-OLinuXino_defconfig +++ b/configs/A13-OLinuXino_defconfig @@ -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@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" diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index af728b51c7..f5f24fc020 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -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.39.2