sunxi: display: Replace #ifdef-ery with helper functions
Subsystems (3)
PATCH 1/5 sunxi: display: Replace #ifdef-ery with helper functions
All the #ifdef-ery in selecting the default and fallback monitor type is becoming unyielding and makes the code hard to read, replace it with a few helper functions.
This will also be useful with the upcoming CHIP board which has display adapter daughterboards which should be runtime detectable.
--- drivers/video/sunxi_display.c | 90 +++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 34 deletions(-)
drivers/video/sunxi_display.c +56 -34
@@ -1101,6 +1101,43 @@ ulong board_get_usable_ram_top(ulong total_size)return gd->ram_top -CONFIG_SUNXI_MAX_FB_SIZE ; } +static bool sunxi_has_hdmi (void ) +{ +#ifdef CONFIG_VIDEO_HDMI +return true; +#else +return false; +#endif +} + +static bool sunxi_has_lcd (void ) +{ +char *lcd_mode =CONFIG_VIDEO_LCD_MODE ; + +return lcd_mode[0 ] !=0 ; +} + +static bool sunxi_has_vga (void ) +{ +#if definedCONFIG_VIDEO_VGA || definedCONFIG_VIDEO_VGA_VIA_LCD +return true; +#else +return false; +#endif +} + +static enum sunxi_monitor sunxi_get_default_mon (bool allow_hdmi) +{ +if (allow_hdmi &&sunxi_has_hdmi ()) +return sunxi_monitor_dvi; +else if (sunxi_has_lcd ()) +return sunxi_monitor_lcd; +else if (sunxi_has_vga ()) +return sunxi_monitor_vga; +else +return sunxi_monitor_none; +} +void *video_hw_init (void ) {static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
@@ -1122,12 +1159,8 @@ void *video_hw_init(void) hpd =video_get_option_int (options,"hpd" ,1 ); hpd_delay =video_get_option_int (options,"hpd_delay" ,500 ); edid =video_get_option_int (options,"edid" ,1 ); - sunxi_display.monitor = sunxi_monitor_dvi; -#elif definedCONFIG_VIDEO_VGA_VIA_LCD - sunxi_display.monitor = sunxi_monitor_vga; -#else - sunxi_display.monitor = sunxi_monitor_lcd;#endif + sunxi_display.monitor =sunxi_get_default_mon (true);video_get_option_string (options,"monitor" , mon,sizeof (mon),sunxi_get_mon_desc (sunxi_display.monitor));for (i =0 ; i <=SUNXI_MONITOR_LAST ; i++) {
@@ -1152,16 +1185,7 @@ void *video_hw_init(void) mode = &custom; }else if (hpd) {sunxi_hdmi_shutdown (); -/* Fallback to lcd / vga / none */ -if (lcd_mode[0 ]) { - sunxi_display.monitor = sunxi_monitor_lcd; - }else { -#if definedCONFIG_VIDEO_VGA_VIA_LCD || definedCONFIG_VIDEO_VGA - sunxi_display.monitor = sunxi_monitor_vga; -#else - sunxi_display.monitor = sunxi_monitor_none; -#endif - } + sunxi_display.monitor =sunxi_get_default_mon (false); }/* else continue with hdmi/dvi without a cable connected */ }#endif
@@ -1171,31 +1195,29 @@ void *video_hw_init(void)return NULL ;case sunxi_monitor_dvi:case sunxi_monitor_hdmi: -#ifdef CONFIG_VIDEO_HDMI +if (!sunxi_has_hdmi ()) { +printf ("HDMI/DVI not supported on this board\n" ); + sunxi_display.monitor = sunxi_monitor_none; +return NULL ; + }break ; -#else -printf ("HDMI/DVI not supported on this board\n" ); - sunxi_display.monitor = sunxi_monitor_none; -return NULL ; -#endif case sunxi_monitor_lcd: -if (lcd_mode[0 ]) { - sunxi_display.depth =video_get_params (&custom, lcd_mode); - mode = &custom; -break ; +if (!sunxi_has_lcd ()) { +printf ("LCD not supported on this board\n" ); + sunxi_display.monitor = sunxi_monitor_none; +return NULL ; } -printf ("LCD not supported on this board\n" ); - sunxi_display.monitor = sunxi_monitor_none; -return NULL ; + sunxi_display.depth =video_get_params (&custom, lcd_mode); + mode = &custom; +break ;case sunxi_monitor_vga: -#if definedCONFIG_VIDEO_VGA_VIA_LCD || definedCONFIG_VIDEO_VGA +if (!sunxi_has_vga ()) { +printf ("VGA not supported on this board\n" ); + sunxi_display.monitor = sunxi_monitor_none; +return NULL ; + } sunxi_display.depth =18 ;break ; -#else -printf ("VGA not supported on this board\n" ); - sunxi_display.monitor = sunxi_monitor_none; -return NULL ; -#endif }if (mode->vmode !=FB_VMODE_NONINTERLACED ) {
Signature · 1 line
2.4.3
PATCH 2/5 sunxi: display: Correct clk_delay calculations for lcd displays
We should only substract 2 from the vblank time when using tcon1.
--- drivers/video/sunxi_display.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/video/sunxi_display.c +7 -4
@@ -663,11 +663,14 @@ static void sunxi_lcdc_backlight_enable(void)gpio_direction_output (pin,PWM_ON ); } -static int sunxi_lcdc_get_clk_delay (const struct ctfb_res_modes *mode) +static int sunxi_lcdc_get_clk_delay (const struct ctfb_res_modes *mode,int tcon) {int delay; - delay = mode->lower_margin + mode->vsync_len + mode->upper_margin -2 ; + delay = mode->lower_margin + mode->vsync_len + mode->upper_margin; +if (tcon ==1 ) + delay -=2 ; +return (delay >30 ) ?30 : delay; }
@@ -692,7 +695,7 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,clrsetbits_le32 (&lcdc->ctrl,SUNXI_LCDC_CTRL_IO_MAP_MASK ,SUNXI_LCDC_CTRL_IO_MAP_TCON0 ); - clk_delay =sunxi_lcdc_get_clk_delay (mode); + clk_delay =sunxi_lcdc_get_clk_delay (mode,0 );writel (SUNXI_LCDC_TCON0_CTRL_ENABLE |SUNXI_LCDC_TCON0_CTRL_CLK_DELAY (clk_delay), &lcdc->tcon0_ctrl);
@@ -770,7 +773,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,clrsetbits_le32 (&lcdc->ctrl,SUNXI_LCDC_CTRL_IO_MAP_MASK ,SUNXI_LCDC_CTRL_IO_MAP_TCON1 ); - clk_delay =sunxi_lcdc_get_clk_delay (mode); + clk_delay =sunxi_lcdc_get_clk_delay (mode,1 );writel (SUNXI_LCDC_TCON1_CTRL_ENABLE |SUNXI_LCDC_TCON1_CTRL_CLK_DELAY (clk_delay), &lcdc->tcon1_ctrl);
Signature · 1 line
2.4.3
PATCH 2/5 sunxi: display: Correct clk_delay calculations for lcd displays
Quoted 1 line · Hans de Goede
We should only substract 2 from the vblank time when using tcon1.
"subtract"
Quoted 1 line
Signed-off-by Hans de Goede <[email protected]>
PATCH 3/5 sunxi: display: Add a few extra register and constant defines
In reply to Hans de GoedeAdd a few extra sunxi display registers and constant defines. This is a preparation patch for adding composite video out support.
--- arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 2 +- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 1 + arch/arm/include/asm/arch-sunxi/display.h | 45 ++++++++++++++++++++++++--- drivers/video/sunxi_display.c | 8 ++--- 4 files changed, 46 insertions(+), 10 deletions(-)
arch/arm/include/asm/arch-sunxi/clock_sun4i.h +1 -1
@@ -291,7 +291,7 @@ struct sunxi_ccm_reg {#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)#define CCM_LCD_CH1_CTRL_M (n) ((((n) - 1) & 0xf) << 0) -/* We leave bit 11 set to 0, so sclk1 == sclk2 */ +#define CCM_LCD_CH1_CTRL_HALF_SCLK1 (1 << 11)#define CCM_LCD_CH1_CTRL_PLL3 (0 << 24)#define CCM_LCD_CH1_CTRL_PLL7 (1 << 24)#define CCM_LCD_CH1_CTRL_PLL3_2X (2 << 24)
arch/arm/include/asm/arch-sunxi/clock_sun6i.h +1 -0
@@ -290,6 +290,7 @@ struct sunxi_ccm_reg {#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)#define CCM_LCD_CH1_CTRL_M (n) ((((n) - 1) & 0xf) << 0) +#define CCM_LCD_CH1_CTRL_HALF_SCLK1 0/* no seperate sclk1 & 2 on sun6i */ #define CCM_LCD_CH1_CTRL_PLL3 (0 << 24)#define CCM_LCD_CH1_CTRL_PLL7 (1 << 24)#define CCM_LCD_CH1_CTRL_PLL3_2X (2 << 24)
arch/arm/include/asm/arch-sunxi/display.h +40 -5
90 lines not on this page · raw message
drivers/video/sunxi_display.c +4 -4
@@ -791,7 +791,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode, bp = mode->vsync_len + mode->upper_margin; total = mode->yres + mode->lower_margin + bp; -writel (SUNXI_LCDC_TCON1_TIMING_V_TOTAL (total) | +writel (SUNXI_LCDC_TCON1_TIMING_V_TOTAL (2 * total) |SUNXI_LCDC_TCON1_TIMING_V_BP (bp), &lcdc->tcon1_timing_v); writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
@@ -944,9 +944,9 @@ static void sunxi_vga_mode_set(void)writel (SUNXI_TVE_GCTRL_DAC_INPUT (0 ,1 ) |SUNXI_TVE_GCTRL_DAC_INPUT (1 ,2 ) |SUNXI_TVE_GCTRL_DAC_INPUT (2 ,3 ), &tve->gctrl); -writel (SUNXI_TVE_GCTRL_CFG0_VGA , &tve->cfg0); -writel (SUNXI_TVE_GCTRL_DAC_CFG0_VGA , &tve->dac_cfg0); -writel (SUNXI_TVE_GCTRL_UNKNOWN1_VGA , &tve->unknown1); +writel (SUNXI_TVE_CFG0_VGA , &tve->cfg0); +writel (SUNXI_TVE_DAC_CFG0_VGA , &tve->dac_cfg0); +writel (SUNXI_TVE_UNKNOWN1_VGA , &tve->unknown1); }static void sunxi_vga_enable (void )
Signature · 1 line
2.4.3
PATCH 3/5 sunxi: display: Add a few extra register and constant defines
Quoted 1 line · Hans de Goede
Add a few extra sunxi display registers and constant defines.
+ "Also rename some existing defines (e.g. dropping _GCTRL) and make some more generic (e.g. dropping the 2x scaling from SUNXI_LCDC_TCON1_TIMING_V_TOTAL)."
Quoted 3 lines
This is a preparation patch for adding composite video out support.
Signed-off-by Hans de Goede <[email protected]>
Quoted 171 lines
--- arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 2 +- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 1 + arch/arm/include/asm/arch-sunxi/display.h | 45 ++++++++++++++++++++++++--- drivers/video/sunxi_display.c | 8 ++--- 4 files changed, 46 insertions(+), 10 deletions(-)arch/arm/include/asm/arch-sunxi/clock_sun4i.h +1
-1@@ -291,7 +291,7 @@ struct sunxi_ccm_reg {#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)#define CCM_LCD_CH1_CTRL_M (n) ((((n) - 1) & 0xf) << 0) -/* We leave bit 11 set to 0, so sclk1 == sclk2 */ +#define CCM_LCD_CH1_CTRL_HALF_SCLK1 (1 << 11)#define CCM_LCD_CH1_CTRL_PLL3 (0 << 24)#define CCM_LCD_CH1_CTRL_PLL7 (1 << 24)#define CCM_LCD_CH1_CTRL_PLL3_2X (2 << 24)arch/arm/include/asm/arch-sunxi/clock_sun6i.h +1
-0@@ -290,6 +290,7 @@ struct sunxi_ccm_reg {#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)#define CCM_LCD_CH1_CTRL_M (n) ((((n) - 1) & 0xf) << 0) +#define CCM_LCD_CH1_CTRL_HALF_SCLK1 0/* no seperate sclk1 & 2 on sun6i */
#defineCCM_LCD_CH1_CTRL_PLL3(0 << 24)
#defineCCM_LCD_CH1_CTRL_PLL7(1 << 24)
#defineCCM_LCD_CH1_CTRL_PLL3_2X(2 << 24)arch/arm/include/asm/arch-sunxi/display.h +10
-2@@ -151,6 +151,10 @@ struct sunxi_de_be_reg {u32 layer1_attr1_ctrl;/* 0x8a4 */ u32 layer2_attr1_ctrl;/* 0x8a8 */ u32 layer3_attr1_ctrl;/* 0x8ac */ +u8 res5[0x110 ];/* 0x8b0 */ +u32 output_color_ctrl;/* 0x9c0 */ +u8 res6[0xc ];/* 0x9c4 */ +u32 output_color_coef[12 ];/* 0x9d0 */ };struct sunxi_lcdc_reg {@@ -298,7 +302,7 @@ struct sunxi_tve_reg {u32 cbr_level;/* 0x10c */ u32 burst_phase;/* 0x110 */ u32 burst_width;/* 0x114 */ -u8 res2[0x04 ];/* 0x118 */ +u32 unknown2;/* 0x118 */ u32 sync_vbi_level;/* 0x11c */ u32 white_level;/* 0x120 */ u32 active_num;/* 0x124 */ @@ -331,11 +335,14 @@ struct sunxi_tve_reg {#define SUNXI_DE_BE_HEIGHT (y) (((y) - 1) << 16)#define SUNXI_DE_BE_MODE_ENABLE (1 << 0)#define SUNXI_DE_BE_MODE_START (1 << 1) +#define SUNXI_DE_BE_MODE_DEFLICKER_ENABLE (1 << 4)#define SUNXI_DE_BE_MODE_LAYER0_ENABLE (1 << 8) +#define SUNXI_DE_BE_MODE_INTERLACE_ENABLE (1 << 28)#define SUNXI_DE_BE_LAYER_STRIDE (x) ((x) << 5)#define SUNXI_DE_BE_REG_CTRL_LOAD_REGS (1 << 0)#define SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0 0x00000002#define SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888 (0x09 << 8) +#define SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE 1/* * LCDC register constants. @@ -372,11 +379,12 @@ struct sunxi_tve_reg {#define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE (1 << 31)#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE (x) ((x) << 28)#define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY (n) (((n) & 0x1f) << 4) +#define SUNXI_LCDC_TCON1_CTRL_INTERLACE (n) ((n) << 20)#define SUNXI_LCDC_TCON1_CTRL_ENABLE (1 << 31)#define SUNXI_LCDC_TCON1_TIMING_H_BP (n) (((n) - 1) << 0)#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) +#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL (n) ((n) << 16)#ifdef CONFIG_SUNXI_GEN_SUN6I #define
SUNXI_LCDC_LVDS_ANA00x40040320
#defineSUNXI_LCDC_LVDS_ANA0_EN_MB(1 << 31)arch/arm/include/asm/arch-sunxi/display.h +16
-3@@ -494,9 +502,22 @@ struct sunxi_tve_reg {*/ #define SUNXI_TVE_GCTRL_DAC_INPUT_MASK (dac) (0xf << (((dac) + 1) * 4))#define SUNXI_TVE_GCTRL_DAC_INPUT (dac, sel) ((sel) << (((dac) + 1) * 4)) -#define SUNXI_TVE_GCTRL_CFG0_VGA 0x20000000 -#define SUNXI_TVE_GCTRL_DAC_CFG0_VGA 0x403e1ac7 -#define SUNXI_TVE_GCTRL_UNKNOWN1_VGA 0x00000000 +#define SUNXI_TVE_CFG0_VGA 0x20000000 +#define SUNXI_TVE_CFG0_PAL 0x07030001 +#define SUNXI_TVE_CFG0_NTSC 0x07030000 +#define SUNXI_TVE_DAC_CFG0_VGA 0x403e1ac7 +#define SUNXI_TVE_DAC_CFG0_COMPOSITE 0x403f0008 +#define SUNXI_TVE_FILTER_COMPOSITE 0x00000120 +#define SUNXI_TVE_CHROMA_FREQ_PAL_M 0x21e6efe3 +#define SUNXI_TVE_CHROMA_FREQ_PAL_NC 0x21f69446 +#define SUNXI_TVE_PORCH_NUM_PAL 0x008a0018 +#define SUNXI_TVE_PORCH_NUM_NTSC 0x00760020 +#define SUNXI_TVE_LINE_NUM_PAL 0x00160271 +#define SUNXI_TVE_LINE_NUM_NTSC 0x0016020d +#define SUNXI_TVE_BLANK_BLACK_LEVEL_PAL 0x00fc00fc +#define SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC 0x00f0011a +#define SUNXI_TVE_UNKNOWN1_VGA 0x00000000 +#define SUNXI_TVE_UNKNOWN1_COMPOSITE 0x18181818#define SUNXI_TVE_AUTO_DETECT_EN_DET_EN (dac) (1 << ((dac) + 0))#define
SUNXI_TVE_AUTO_DETECT_EN_INT_EN(dac)(1 << ((dac) + 16))
#defineSUNXI_TVE_AUTO_DETECT_INT_STATUS(dac)(1 << ((dac) + 0))arch/arm/include/asm/arch-sunxi/display.h +14
-0@@ -512,6 +533,20 @@ struct sunxi_tve_reg {#define SUNXI_TVE_CSC_REG1 0x3b6dace1#define SUNXI_TVE_CSC_REG2 0x0e1d13dc#define SUNXI_TVE_CSC_REG3 0x00108080 +#define SUNXI_TVE_COLOR_BURST_PAL_M 0x00000000 +#define SUNXI_TVE_CBR_LEVEL_PAL 0x00002828 +#define SUNXI_TVE_CBR_LEVEL_NTSC 0x0000004f +#define SUNXI_TVE_BURST_PHASE_NTSC 0x00000000 +#define SUNXI_TVE_BURST_WIDTH_COMPOSITE 0x0016447e +#define SUNXI_TVE_UNKNOWN2_PAL 0x0000e0e0 +#define SUNXI_TVE_UNKNOWN2_NTSC 0x0000a0a0 +#define SUNXI_TVE_SYNC_VBI_LEVEL_NTSC 0x001000f0 +#define SUNXI_TVE_ACTIVE_NUM_COMPOSITE 0x000005a0 +#define SUNXI_TVE_CHROMA_BW_GAIN_COMP 0x00000002 +#define SUNXI_TVE_NOTCH_WIDTH_COMPOSITE 0x00000101 +#define SUNXI_TVE_RESYNC_NUM_PAL 0x800d000c +#define SUNXI_TVE_RESYNC_NUM_NTSC 0x000e000c +#define SUNXI_TVE_SLAVE_PARA_COMPOSITE 0x00000000int sunxi_simplefb_setup (void *blob);drivers/video/sunxi_display.c +4
-6@@ -791,7 +791,7 @@ static void sunxi_lcdc_tcon1_mode_set(conststruct ctfb_res_modes *mode, bp = mode->vsync_len + mode->upper_margin; total = mode->yres + mode->lower_margin + bp; -writel (SUNXI_LCDC_TCON1_TIMING_V_TOTAL (total) | + writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(2 * total) | SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc ->tcon1_timing_v); writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode ->vsync_len),@@ -944,9 +944,9 @@ static void sunxi_vga_mode_set(void)writel (SUNXI_TVE_GCTRL_DAC_INPUT (0 ,1 ) |SUNXI_TVE_GCTRL_DAC_INPUT (1 ,2 ) |SUNXI_TVE_GCTRL_DAC_INPUT (2 ,3 ), &tve->gctrl); -writel (SUNXI_TVE_GCTRL_CFG0_VGA , &tve->cfg0); -writel (SUNXI_TVE_GCTRL_DAC_CFG0_VGA , &tve->dac_cfg0); -writel (SUNXI_TVE_GCTRL_UNKNOWN1_VGA , &tve->unknown1); +writel (SUNXI_TVE_CFG0_VGA , &tve->cfg0); +writel (SUNXI_TVE_DAC_CFG0_VGA , &tve->dac_cfg0); +writel (SUNXI_TVE_UNKNOWN1_VGA , &tve->unknown1); }static void sunxi_vga_enable (void )
PATCH 3/5 sunxi: display: Add a few extra register and constant defines
Hi,
Quoted 6 lines · Ian Campbell
Quoted 1 line · Hans de Goede
Add a few extra sunxi display registers and constant defines.
+ "Also rename some existing defines (e.g. dropping
_GCTRL) and make some more generic (e.g. dropping the 2x scaling fromSUNXI_LCDC_TCON1_TIMING_V_TOTAL)."
Added to the commit msg, thanks for the reviews.
Regards,
Hans
Quoted 178 lines
Quoted 4 lines
This is a preparation patch for adding composite video out support.
Signed-off-by Hans de Goede <[email protected]>Acked-by Ian Campbell <[email protected]>Quoted 171 lines
--- arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 2 +- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 1 + arch/arm/include/asm/arch-sunxi/display.h | 45 ++++++++++++++++++++++++--- drivers/video/sunxi_display.c | 8 ++--- 4 files changed, 46 insertions(+), 10 deletions(-)arch/arm/include/asm/arch-sunxi/clock_sun4i.h +1
-1@@ -291,7 +291,7 @@ struct sunxi_ccm_reg {#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)#define CCM_LCD_CH1_CTRL_M (n) ((((n) - 1) & 0xf) << 0) -/* We leave bit 11 set to 0, so sclk1 == sclk2 */ +#define CCM_LCD_CH1_CTRL_HALF_SCLK1 (1 << 11)#define CCM_LCD_CH1_CTRL_PLL3 (0 << 24)#define CCM_LCD_CH1_CTRL_PLL7 (1 << 24)#define CCM_LCD_CH1_CTRL_PLL3_2X (2 << 24)arch/arm/include/asm/arch-sunxi/clock_sun6i.h +1
-0@@ -290,6 +290,7 @@ struct sunxi_ccm_reg {#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31)#define CCM_LCD_CH1_CTRL_M (n) ((((n) - 1) & 0xf) << 0) +#define CCM_LCD_CH1_CTRL_HALF_SCLK1 0/* no seperate sclk1 & 2 on sun6i */
#defineCCM_LCD_CH1_CTRL_PLL3(0 << 24)
#defineCCM_LCD_CH1_CTRL_PLL7(1 << 24)
#defineCCM_LCD_CH1_CTRL_PLL3_2X(2 << 24)arch/arm/include/asm/arch-sunxi/display.h +10
-2@@ -151,6 +151,10 @@ struct sunxi_de_be_reg {u32 layer1_attr1_ctrl;/* 0x8a4 */ u32 layer2_attr1_ctrl;/* 0x8a8 */ u32 layer3_attr1_ctrl;/* 0x8ac */ +u8 res5[0x110 ];/* 0x8b0 */ +u32 output_color_ctrl;/* 0x9c0 */ +u8 res6[0xc ];/* 0x9c4 */ +u32 output_color_coef[12 ];/* 0x9d0 */ };struct sunxi_lcdc_reg {@@ -298,7 +302,7 @@ struct sunxi_tve_reg {u32 cbr_level;/* 0x10c */ u32 burst_phase;/* 0x110 */ u32 burst_width;/* 0x114 */ -u8 res2[0x04 ];/* 0x118 */ +u32 unknown2;/* 0x118 */ u32 sync_vbi_level;/* 0x11c */ u32 white_level;/* 0x120 */ u32 active_num;/* 0x124 */ @@ -331,11 +335,14 @@ struct sunxi_tve_reg {#define SUNXI_DE_BE_HEIGHT (y) (((y) - 1) << 16)#define SUNXI_DE_BE_MODE_ENABLE (1 << 0)#define SUNXI_DE_BE_MODE_START (1 << 1) +#define SUNXI_DE_BE_MODE_DEFLICKER_ENABLE (1 << 4)#define SUNXI_DE_BE_MODE_LAYER0_ENABLE (1 << 8) +#define SUNXI_DE_BE_MODE_INTERLACE_ENABLE (1 << 28)#define SUNXI_DE_BE_LAYER_STRIDE (x) ((x) << 5)#define SUNXI_DE_BE_REG_CTRL_LOAD_REGS (1 << 0)#define SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0 0x00000002#define SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888 (0x09 << 8) +#define SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE 1/* * LCDC register constants. @@ -372,11 +379,12 @@ struct sunxi_tve_reg {#define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE (1 << 31)#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE (x) ((x) << 28)#define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY (n) (((n) & 0x1f) << 4) +#define SUNXI_LCDC_TCON1_CTRL_INTERLACE (n) ((n) << 20)#define SUNXI_LCDC_TCON1_CTRL_ENABLE (1 << 31)#define SUNXI_LCDC_TCON1_TIMING_H_BP (n) (((n) - 1) << 0)#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) +#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL (n) ((n) << 16)#ifdef CONFIG_SUNXI_GEN_SUN6I #define SUNXI_LCDC_LVDS_ANA0 0x40040320 #define SUNXI_LCDC_LVDS_ANA0_EN_MB (1 << 31)arch/arm/include/asm/arch-sunxi/display.h +16
-3@@ -494,9 +502,22 @@ struct sunxi_tve_reg {*/ #define SUNXI_TVE_GCTRL_DAC_INPUT_MASK (dac) (0xf << (((dac) + 1) * 4))#define SUNXI_TVE_GCTRL_DAC_INPUT (dac, sel) ((sel) << (((dac) + 1) * 4)) -#define SUNXI_TVE_GCTRL_CFG0_VGA 0x20000000 -#define SUNXI_TVE_GCTRL_DAC_CFG0_VGA 0x403e1ac7 -#define SUNXI_TVE_GCTRL_UNKNOWN1_VGA 0x00000000 +#define SUNXI_TVE_CFG0_VGA 0x20000000 +#define SUNXI_TVE_CFG0_PAL 0x07030001 +#define SUNXI_TVE_CFG0_NTSC 0x07030000 +#define SUNXI_TVE_DAC_CFG0_VGA 0x403e1ac7 +#define SUNXI_TVE_DAC_CFG0_COMPOSITE 0x403f0008 +#define SUNXI_TVE_FILTER_COMPOSITE 0x00000120 +#define SUNXI_TVE_CHROMA_FREQ_PAL_M 0x21e6efe3 +#define SUNXI_TVE_CHROMA_FREQ_PAL_NC 0x21f69446 +#define SUNXI_TVE_PORCH_NUM_PAL 0x008a0018 +#define SUNXI_TVE_PORCH_NUM_NTSC 0x00760020 +#define SUNXI_TVE_LINE_NUM_PAL 0x00160271 +#define SUNXI_TVE_LINE_NUM_NTSC 0x0016020d +#define SUNXI_TVE_BLANK_BLACK_LEVEL_PAL 0x00fc00fc +#define SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC 0x00f0011a +#define SUNXI_TVE_UNKNOWN1_VGA 0x00000000 +#define SUNXI_TVE_UNKNOWN1_COMPOSITE 0x18181818#define SUNXI_TVE_AUTO_DETECT_EN_DET_EN (dac) (1 << ((dac) + 0))#define SUNXI_TVE_AUTO_DETECT_EN_INT_EN(dac) (1 << ((dac) + 16)) #define SUNXI_TVE_AUTO_DETECT_INT_STATUS(dac) (1 << ((dac) + 0))arch/arm/include/asm/arch-sunxi/display.h +14
-0@@ -512,6 +533,20 @@ struct sunxi_tve_reg {#define SUNXI_TVE_CSC_REG1 0x3b6dace1#define SUNXI_TVE_CSC_REG2 0x0e1d13dc#define SUNXI_TVE_CSC_REG3 0x00108080 +#define SUNXI_TVE_COLOR_BURST_PAL_M 0x00000000 +#define SUNXI_TVE_CBR_LEVEL_PAL 0x00002828 +#define SUNXI_TVE_CBR_LEVEL_NTSC 0x0000004f +#define SUNXI_TVE_BURST_PHASE_NTSC 0x00000000 +#define SUNXI_TVE_BURST_WIDTH_COMPOSITE 0x0016447e +#define SUNXI_TVE_UNKNOWN2_PAL 0x0000e0e0 +#define SUNXI_TVE_UNKNOWN2_NTSC 0x0000a0a0 +#define SUNXI_TVE_SYNC_VBI_LEVEL_NTSC 0x001000f0 +#define SUNXI_TVE_ACTIVE_NUM_COMPOSITE 0x000005a0 +#define SUNXI_TVE_CHROMA_BW_GAIN_COMP 0x00000002 +#define SUNXI_TVE_NOTCH_WIDTH_COMPOSITE 0x00000101 +#define SUNXI_TVE_RESYNC_NUM_PAL 0x800d000c +#define SUNXI_TVE_RESYNC_NUM_NTSC 0x000e000c +#define SUNXI_TVE_SLAVE_PARA_COMPOSITE 0x00000000int sunxi_simplefb_setup (void *blob);drivers/video/sunxi_display.c +4
-6@@ -791,7 +791,7 @@ static void sunxi_lcdc_tcon1_mode_set(conststruct ctfb_res_modes *mode, bp = mode->vsync_len + mode->upper_margin; total = mode->yres + mode->lower_margin + bp; -writel (SUNXI_LCDC_TCON1_TIMING_V_TOTAL (total) | + writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(2 * total) | SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc ->tcon1_timing_v); writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode ->vsync_len),@@ -944,9 +944,9 @@ static void sunxi_vga_mode_set(void)writel (SUNXI_TVE_GCTRL_DAC_INPUT (0 ,1 ) |SUNXI_TVE_GCTRL_DAC_INPUT (1 ,2 ) |SUNXI_TVE_GCTRL_DAC_INPUT (2 ,3 ), &tve->gctrl); -writel (SUNXI_TVE_GCTRL_CFG0_VGA , &tve->cfg0); -writel (SUNXI_TVE_GCTRL_DAC_CFG0_VGA , &tve->dac_cfg0); -writel (SUNXI_TVE_GCTRL_UNKNOWN1_VGA , &tve->unknown1); +writel (SUNXI_TVE_CFG0_VGA , &tve->cfg0); +writel (SUNXI_TVE_DAC_CFG0_VGA , &tve->dac_cfg0); +writel (SUNXI_TVE_UNKNOWN1_VGA , &tve->unknown1); }static void sunxi_vga_enable (void )
PATCH 4/5 sunxi: display: Add support for interlaced modes
In reply to Hans de GoedeAdd support for interlaced modes, this is a preparation patch for adding composite out support.
--- drivers/video/sunxi_display.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-)
drivers/video/sunxi_display.c +21 -13
@@ -445,6 +445,10 @@ static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,writel (SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888 , &de_be->layer0_attr1_ctrl);setbits_le32 (&de_be->mode,SUNXI_DE_BE_MODE_LAYER0_ENABLE ); +if (mode->vmode ==FB_VMODE_INTERLACED ) +setbits_le32 (&de_be->mode, +SUNXI_DE_BE_MODE_DEFLICKER_ENABLE | +SUNXI_DE_BE_MODE_INTERLACE_ENABLE ); }static void sunxi_composer_enable (void )
@@ -668,6 +672,8 @@ static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon)int delay; delay = mode->lower_margin + mode->vsync_len + mode->upper_margin; +if (mode->vmode ==FB_VMODE_INTERLACED ) + delay /=2 ;if (tcon ==1 ) delay -=2 ;
@@ -767,7 +773,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode, {struct sunxi_lcdc_reg *const lcdc = (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE ; -int bp, clk_delay, total, val; +int bp, clk_delay, total, val, yres;/* Use tcon1 */ clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
@@ -775,13 +781,18 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode, clk_delay =sunxi_lcdc_get_clk_delay (mode,1 );writel (SUNXI_LCDC_TCON1_CTRL_ENABLE | +SUNXI_LCDC_TCON1_CTRL_INTERLACE ( + mode->vmode ==FB_VMODE_INTERLACED ) |SUNXI_LCDC_TCON1_CTRL_CLK_DELAY (clk_delay), &lcdc->tcon1_ctrl); -writel (SUNXI_LCDC_X (mode->xres) |SUNXI_LCDC_Y (mode->yres), + yres = mode->yres; +if (mode->vmode ==FB_VMODE_INTERLACED ) + yres /=2 ; +writel (SUNXI_LCDC_X (mode->xres) |SUNXI_LCDC_Y (yres), &lcdc->tcon1_timing_source); -writel (SUNXI_LCDC_X (mode->xres) |SUNXI_LCDC_Y (mode->yres), +writel (SUNXI_LCDC_X (mode->xres) |SUNXI_LCDC_Y (yres), &lcdc->tcon1_timing_scale); -writel (SUNXI_LCDC_X (mode->xres) |SUNXI_LCDC_Y (mode->yres), +writel (SUNXI_LCDC_X (mode->xres) |SUNXI_LCDC_Y (yres), &lcdc->tcon1_timing_out); bp = mode->hsync_len + mode->left_margin;
@@ -791,7 +802,9 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode, bp = mode->vsync_len + mode->upper_margin; total = mode->yres + mode->lower_margin + bp; -writel (SUNXI_LCDC_TCON1_TIMING_V_TOTAL (2 * total) | +if (mode->vmode ==FB_VMODE_NONINTERLACED ) + total *=2 ; +writel (SUNXI_LCDC_TCON1_TIMING_V_TOTAL (total) |SUNXI_LCDC_TCON1_TIMING_V_BP (bp), &lcdc->tcon1_timing_v); writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
@@ -1223,14 +1236,6 @@ void *video_hw_init(void)break ; } -if (mode->vmode !=FB_VMODE_NONINTERLACED ) { -printf ("Only non-interlaced modes supported, falling back to 1024x768\n" ); - mode = &res_mode_init[RES_MODE_1024x768]; - }else { -printf ("Setting up a %dx%d %s console\n" , mode->xres, - mode->yres,sunxi_get_mon_desc (sunxi_display.monitor)); - } - sunxi_display.fb_size = (mode->xres * mode->yres *4 +0xfff ) & ~0xfff ;if (sunxi_display.fb_size >CONFIG_SUNXI_MAX_FB_SIZE ) {
@@ -1240,6 +1245,9 @@ void *video_hw_init(void)return NULL ; } +printf ("Setting up a %dx%d %s console\n" , mode->xres, + mode->yres,sunxi_get_mon_desc (sunxi_display.monitor)); + gd->fb_base = gd->bd->bi_dram[0 ].start + gd->bd->bi_dram[0 ].size - sunxi_display.fb_size;sunxi_engines_init ();
Signature · 1 line
2.4.3
PATCH 4/5 sunxi: display: Add support for interlaced modes
drivers/video/sunxi_display.c static void sunxi_lcdc_tcon1_mode_set(const · line 786
Quoted 7 lines · Hans de Goede
drivers/video/sunxi_display.c +2
-0@@ -775,13 +781,18 @@ static void sunxi_lcdc_tcon1_mode_set(conststruct ctfb_res_modes *mode, clk_delay =sunxi_lcdc_get_clk_delay (mode,1 ); writel(SUNXI_LCDC_TCON1_CTRL_ENABLE | + SUNXI_LCDC_TCON1_CTRL_INTERLACE( + mode->vmode == FB_VMODE_INTERLACED) |
I think this would be clearer if SUNXI_LCDC_TCON1_CTRL_INTERLACE was actually the enable bit (perhaps with _ENABLE on the name), rather than a macro which takes a boolean and returns 0 or the single bit, so you could just write
mode->vmode == FB_VMODE_INTERLACED ? SUNXI_LCDC_TCON1_CTRL_INTERLACE : 0
(in whichever wrapping style you prefer).
I think the macro is the bit style is more common in this code for boolean options too, we mainly use the macro-with-argument style for fields with more than 1 bit to them.
But ultimately the code is correct as you have it so either way as you prefer:
Although if you want to keep it the way it is then perhaps the macro sh ould have !!n instead of just n, to prevent surprises if someone uses a bitop rather than a full boolean op as an argument?
@@ -1240,6 +1245,9 @@ void *video_hw_init(void)
drivers/video/sunxi_display.c void *video_hw_init(void)
Quoted 5 lines
drivers/video/sunxi_display.c +2
-0return NULL ; } +> > printf("Setting up a %dx%d %s console\n", mode->xres, +> > mode->yres, sunxi_get_mon_desc(sunxi_display.monitor));
Is it worth including the string "interlaced" here when appropriate? (Ack stands either way)
Ian.
PATCH 4/5 sunxi: display: Add support for interlaced modes
Hi,
Quoted 13 lines · Ian Campbell
drivers/video/sunxi_display.c static void sunxi_lcdc_tcon1_mode_set(const · line 786
Quoted 7 lines · Hans de Goede
drivers/video/sunxi_display.c +2
-0@@ -775,13 +781,18 @@ static void sunxi_lcdc_tcon1_mode_set(conststruct ctfb_res_modes *mode, clk_delay =sunxi_lcdc_get_clk_delay (mode,1 ); writel(SUNXI_LCDC_TCON1_CTRL_ENABLE | + SUNXI_LCDC_TCON1_CTRL_INTERLACE( + mode->vmode == FB_VMODE_INTERLACED) |I think this would be clearer if
SUNXI_LCDC_TCON1_CTRL_INTERLACEwas actually the enable bit (perhaps with_ENABLEon the name), rather than a macro which takes a boolean and returns 0 or the single bit, so you could just write
Quoted 7 lines
mode->vmode == FB_VMODE_INTERLACED ? SUNXI_LCDC_TCON1_CTRL_INTERLACE : 0(in whichever wrapping style you prefer).
I think the macro is the bit style is more common in this code for boolean options too, we mainly use the macro-with-argument style for fields with more than 1 bit to them.
Agreed, fixed.
Quoted 14 lines
But ultimately the code is correct as you have it so either way as you prefer:
Acked-by Ian Campbell <[email protected]>Although if you want to keep it the way it is then perhaps the macro sh ould have !!n instead of just n, to prevent surprises if someone uses a bitop rather than a full boolean op as an argument?
(quoted diff) +0
-0@@ -1240,6 +1245,9 @@ void *video_hw_init(void) > return NULL; > }Quoted 1 line
Quoted 5 lines
Quoted 2 lines
+> > printf("Setting up a %dx%d %s console\n",
mode->xres,
+> >mode->yres,sunxi_get_mon_desc(sunxi_display.monitor));Is it worth including the string "interlaced" here when appropriate? (Ack stands either way)
Also fixed.
Thanks,
Hans
PATCH 5/5 sunxi: display: Add composite video out support
In reply to Hans de GoedeAdd composite video out support.
This only gets enabled on the Mele M3 for now, since that is were it was tested. It will be enabled on more boards after testing.
--- board/sunxi/Kconfig | 7 ++ configs/Mele_M3_defconfig | 1 + doc/README.video | 7 +- drivers/video/sunxi_display.c | 200 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 191 insertions(+), 24 deletions(-)
board/sunxi/Kconfig +7 -0
@@ -410,6 +410,13 @@ config VIDEO_VGA_EXTERNAL_DAC_EN Set the enable pin for the external VGA DAC. This takes a string in the format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H. +config VIDEO_COMPOSITE + boolean "Composite video output support" + depends on VIDEO && (MACH_SUN4I || MACH_SUN5I || MACH_SUN7I) + default n + ---help--- + Say Y here to add support for outputting composite video. + config VIDEO_LCD_MODE string "LCD panel timing details" depends on VIDEO
configs/Mele_M3_defconfig +1 -0
@@ -5,6 +5,7 @@ CONFIG_DRAM_CLK=384 CONFIG_MMC0_CD_PIN="PH1" CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_VIDEO_VGA=y +CONFIG_VIDEO_COMPOSITE=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-m3" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL=y
doc/README.video +5 -2
@@ -40,12 +40,15 @@ requires the CONFIG_VIDEO_LCD_MODE Kconfig value to be set. The sunxi u-boot driver supports the following video-mode options: -- monitor=[none|dvi|hdmi|lcd] - Select the video output to use +- monitor=[none|dvi|hdmi|lcd|vga|composite-*] - Select the video output to use none: Disable video output. dvi/hdmi: Selects output over the hdmi connector with dvi resp. hdmi output format, if edid is used the format is automatically selected. lcd: Selects video output to a LCD screen. - vga: Selects bideo output over the VGA connector. + vga: Selects video output over the VGA connector. + composite-pal/composite-ntsc/composite-pal-m/composite-pal-nc: + Selects composite video output, note the specified resolution is + ignored with composite video output. Defaults to monitor=dvi. - hpd=[0|1] - Enable use of the hdmi HotPlug Detect feature
drivers/video/sunxi_display.c +178 -22
325 lines not on this page · raw message
Signature · 1 line
2.4.3
PATCH 5/5 sunxi: display: Add composite video out support
Quoted 6 lines · Hans de Goede
Add composite video out support.
This only gets enabled on the Mele M3 for now, since that is were it was tested. It will be enabled on more boards after testing.
Signed-off-by Hans de Goede <[email protected]>
PATCH 1/5 sunxi: display: Replace #ifdef-ery with helper functions
In reply to Hans de GoedeQuoted 11 lines · Hans de Goede
All the #ifdef-ery in selecting the default and fallback monitor type is
becoming unyielding and makes the code hard to read, replace it with a few
helper functions.This will also be useful with the upcoming CHIP board which has display
adapter daughterboards which should be runtime detectable.Signed-off-by Hans de Goede <[email protected]>
I couldn't quite convince myself there was "no semantic change" here, but either way it's an improvement so: