All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions
@ 2015-08-03 21:54 Hans de Goede
  2015-08-03 21:54 ` [U-Boot] [PATCH 2/5] sunxi: display: Correct clk_delay calculations for lcd displays Hans de Goede
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Hans de Goede @ 2015-08-03 21:54 UTC (permalink / raw)
  To: u-boot

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 <hdegoede@redhat.com>
---
 drivers/video/sunxi_display.c | 90 +++++++++++++++++++++++++++----------------
 1 file changed, 56 insertions(+), 34 deletions(-)

diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 269083b..3942d2f 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -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 defined CONFIG_VIDEO_VGA || defined CONFIG_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 defined CONFIG_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 defined CONFIG_VIDEO_VGA_VIA_LCD || defined CONFIG_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 defined CONFIG_VIDEO_VGA_VIA_LCD || defined CONFIG_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) {
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 2/5] sunxi: display: Correct clk_delay calculations for lcd displays
  2015-08-03 21:54 [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions Hans de Goede
@ 2015-08-03 21:54 ` Hans de Goede
  2015-08-05  7:54   ` Ian Campbell
  2015-08-03 21:54 ` [U-Boot] [PATCH 3/5] sunxi: display: Add a few extra register and constant defines Hans de Goede
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Hans de Goede @ 2015-08-03 21:54 UTC (permalink / raw)
  To: u-boot

We should only substract 2 from the vblank time when using tcon1.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/sunxi_display.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 3942d2f..fa4241e 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -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);
 
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 3/5] sunxi: display: Add a few extra register and constant defines
  2015-08-03 21:54 [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions Hans de Goede
  2015-08-03 21:54 ` [U-Boot] [PATCH 2/5] sunxi: display: Correct clk_delay calculations for lcd displays Hans de Goede
@ 2015-08-03 21:54 ` Hans de Goede
  2015-08-05  7:57   ` Ian Campbell
  2015-08-03 21:54 ` [U-Boot] [PATCH 4/5] sunxi: display: Add support for interlaced modes Hans de Goede
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Hans de Goede @ 2015-08-03 21:54 UTC (permalink / raw)
  To: u-boot

Add a few extra sunxi display registers and constant defines.
This is a preparation patch for adding composite video out support.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 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(-)

diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
index 01d3e28..a7e25f4 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
@@ -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)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index 8a26b9f..06c6feb 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -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)
diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h
index ae95417..830ec42 100644
--- a/arch/arm/include/asm/arch-sunxi/display.h
+++ b/arch/arm/include/asm/arch-sunxi/display.h
@@ -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)
@@ -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))
@@ -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		0x00000000
 
 int sunxi_simplefb_setup(void *blob);
 
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index fa4241e..74a4280 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -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)
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 4/5] sunxi: display: Add support for interlaced modes
  2015-08-03 21:54 [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions Hans de Goede
  2015-08-03 21:54 ` [U-Boot] [PATCH 2/5] sunxi: display: Correct clk_delay calculations for lcd displays Hans de Goede
  2015-08-03 21:54 ` [U-Boot] [PATCH 3/5] sunxi: display: Add a few extra register and constant defines Hans de Goede
@ 2015-08-03 21:54 ` Hans de Goede
  2015-08-05  8:05   ` Ian Campbell
  2015-08-03 21:54 ` [U-Boot] [PATCH 5/5] sunxi: display: Add composite video out support Hans de Goede
  2015-08-05  7:53 ` [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions Ian Campbell
  4 siblings, 1 reply; 12+ messages in thread
From: Hans de Goede @ 2015-08-03 21:54 UTC (permalink / raw)
  To: u-boot

Add support for interlaced modes, this is a preparation patch for adding
composite out support.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/sunxi_display.c | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 74a4280..bed8a3e 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -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();
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 5/5] sunxi: display: Add composite video out support
  2015-08-03 21:54 [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions Hans de Goede
                   ` (2 preceding siblings ...)
  2015-08-03 21:54 ` [U-Boot] [PATCH 4/5] sunxi: display: Add support for interlaced modes Hans de Goede
@ 2015-08-03 21:54 ` Hans de Goede
  2015-08-05  8:07   ` Ian Campbell
  2015-08-05  7:53 ` [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions Ian Campbell
  4 siblings, 1 reply; 12+ messages in thread
From: Hans de Goede @ 2015-08-03 21:54 UTC (permalink / raw)
  To: u-boot

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 <hdegoede@redhat.com>
---
 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(-)

diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index b156701..7b4a23b 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -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
diff --git a/configs/Mele_M3_defconfig b/configs/Mele_M3_defconfig
index d498269..5c9796a 100644
--- a/configs/Mele_M3_defconfig
+++ b/configs/Mele_M3_defconfig
@@ -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
diff --git a/doc/README.video b/doc/README.video
index d0a3ad6..4f7a4b5 100644
--- a/doc/README.video
+++ b/doc/README.video
@@ -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
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index bed8a3e..75190db 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -2,7 +2,7 @@
  * Display driver for Allwinner SoCs.
  *
  * (C) Copyright 2013-2014 Luc Verhaegen <libv@skynet.be>
- * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ * (C) Copyright 2014-2015 Hans de Goede <hdegoede@redhat.com>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -40,8 +40,12 @@ enum sunxi_monitor {
 	sunxi_monitor_hdmi,
 	sunxi_monitor_lcd,
 	sunxi_monitor_vga,
+	sunxi_monitor_composite_pal,
+	sunxi_monitor_composite_ntsc,
+	sunxi_monitor_composite_pal_m,
+	sunxi_monitor_composite_pal_nc,
 };
-#define SUNXI_MONITOR_LAST sunxi_monitor_vga
+#define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc
 
 struct sunxi_display {
 	GraphicDevice graphic_device;
@@ -50,6 +54,12 @@ struct sunxi_display {
 	unsigned int fb_size;
 } sunxi_display;
 
+const struct ctfb_res_modes composite_video_modes[2] = {
+	/*  x     y  hz  pixclk ps/kHz   le   ri  up  lo   hs vs  s  vmode */
+	{ 720,  576, 50, 37037,  27000, 137,   5, 20, 27,   2, 2, 0, FB_VMODE_INTERLACED },
+	{ 720,  480, 60, 37037,  27000, 116,  20, 16, 27,   2, 2, 0, FB_VMODE_INTERLACED },
+};
+
 #ifdef CONFIG_VIDEO_HDMI
 
 /*
@@ -390,6 +400,25 @@ static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
 static void sunxi_frontend_enable(void) {}
 #endif
 
+static bool sunxi_is_composite(void)
+{
+	switch (sunxi_display.monitor) {
+	case sunxi_monitor_none:
+	case sunxi_monitor_dvi:
+	case sunxi_monitor_hdmi:
+	case sunxi_monitor_lcd:
+	case sunxi_monitor_vga:
+		return false;
+	case sunxi_monitor_composite_pal:
+	case sunxi_monitor_composite_ntsc:
+	case sunxi_monitor_composite_pal_m:
+	case sunxi_monitor_composite_pal_nc:
+		return true;
+	}
+
+	return false; /* Never reached */
+}
+
 /*
  * This is the entity that mixes and matches the different layers and inputs.
  * Allwinner calls it the back-end, but i like composer better.
@@ -423,11 +452,18 @@ static void sunxi_composer_init(void)
 	setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_ENABLE);
 }
 
+static u32 sunxi_rgb2yuv_coef[12] = {
+	0x00000107, 0x00000204, 0x00000064, 0x00000108,
+	0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808,
+	0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
+};
+
 static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
 				    unsigned int address)
 {
 	struct sunxi_de_be_reg * const de_be =
 		(struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
+	int i;
 
 	sunxi_frontend_mode_set(mode, address);
 
@@ -449,6 +485,14 @@ static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
 		setbits_le32(&de_be->mode,
 			     SUNXI_DE_BE_MODE_DEFLICKER_ENABLE |
 			     SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
+
+	if (sunxi_is_composite()) {
+		writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE,
+		       &de_be->output_color_ctrl);
+		for (i = 0; i < 12; i++)
+			writel(sunxi_rgb2yuv_coef[i],
+			       &de_be->output_color_coef[i]);
+	}
 }
 
 static void sunxi_composer_enable(void)
@@ -539,6 +583,9 @@ static void sunxi_lcdc_pll_set(int tcon, int dotclock,
 		       (best_double ? CCM_LCD_CH1_CTRL_PLL3_2X :
 				      CCM_LCD_CH1_CTRL_PLL3) |
 		       CCM_LCD_CH1_CTRL_M(best_m), &ccm->lcd0_ch1_clk_cfg);
+		if (sunxi_is_composite())
+			setbits_le32(&ccm->lcd0_ch1_clk_cfg,
+				     CCM_LCD_CH1_CTRL_HALF_SCLK1);
 	}
 
 	*clk_div = best_m;
@@ -766,7 +813,7 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
 	writel(0, &lcdc->tcon0_io_tristate);
 }
 
-#if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA
+#if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
 static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 				      int *clk_div, int *clk_double,
 				      bool use_portd_hvsync)
@@ -827,7 +874,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 	}
 	sunxi_lcdc_pll_set(1, mode->pixclock_khz, clk_div, clk_double);
 }
-#endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA */
+#endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
 
 #ifdef CONFIG_VIDEO_HDMI
 
@@ -941,9 +988,9 @@ static void sunxi_hdmi_enable(void)
 
 #endif /* CONFIG_VIDEO_HDMI */
 
-#ifdef CONFIG_VIDEO_VGA
+#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
 
-static void sunxi_vga_mode_set(void)
+static void sunxi_tvencoder_mode_set(void)
 {
 	struct sunxi_ccm_reg * const ccm =
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
@@ -953,16 +1000,75 @@ static void sunxi_vga_mode_set(void)
 	/* Clock on */
 	setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
 
-	/* Set TVE in VGA mode */
-	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_CFG0_VGA, &tve->cfg0);
-	writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0);
-	writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
+	switch (sunxi_display.monitor) {
+	case sunxi_monitor_vga:
+		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_CFG0_VGA, &tve->cfg0);
+		writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0);
+		writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
+		break;
+	case sunxi_monitor_composite_pal_nc:
+		writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq);
+		/* Fall through */
+	case sunxi_monitor_composite_pal:
+		writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
+		writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0);
+		writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
+		writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
+		writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num);
+		writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num);
+		writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level);
+		writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
+		writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level);
+		writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
+		writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2);
+		writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
+		writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
+		writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
+		writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num);
+		writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
+		break;
+	case sunxi_monitor_composite_pal_m:
+		writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq);
+		writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst);
+		/* Fall through */
+	case sunxi_monitor_composite_ntsc:
+		writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
+		writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0);
+		writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
+		writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
+		writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num);
+		writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num);
+		writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level);
+		writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
+		writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level);
+		writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase);
+		writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
+		writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2);
+		writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level);
+		writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
+		writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
+		writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
+		writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num);
+		writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
+		break;
+	case sunxi_monitor_none:
+	case sunxi_monitor_dvi:
+	case sunxi_monitor_hdmi:
+	case sunxi_monitor_lcd:
+		break;
+	}
 }
 
-static void sunxi_vga_enable(void)
+static void sunxi_tvencoder_enable(void)
 {
 	struct sunxi_tve_reg * const tve =
 		(struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
@@ -970,7 +1076,7 @@ static void sunxi_vga_enable(void)
 	setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE);
 }
 
-#endif /* CONFIG_VIDEO_VGA */
+#endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */
 
 static void sunxi_drc_init(void)
 {
@@ -1085,10 +1191,10 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 #ifdef CONFIG_VIDEO_VGA
 		sunxi_composer_mode_set(mode, address);
 		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
-		sunxi_vga_mode_set();
+		sunxi_tvencoder_mode_set();
 		sunxi_composer_enable();
 		sunxi_lcdc_enable();
-		sunxi_vga_enable();
+		sunxi_tvencoder_enable();
 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
 		sunxi_composer_mode_set(mode, address);
 		sunxi_lcdc_tcon0_mode_set(mode, true);
@@ -1097,17 +1203,34 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 		sunxi_vga_external_dac_enable();
 #endif
 		break;
+	case sunxi_monitor_composite_pal:
+	case sunxi_monitor_composite_ntsc:
+	case sunxi_monitor_composite_pal_m:
+	case sunxi_monitor_composite_pal_nc:
+#ifdef CONFIG_VIDEO_COMPOSITE
+		sunxi_composer_mode_set(mode, address);
+		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
+		sunxi_tvencoder_mode_set();
+		sunxi_composer_enable();
+		sunxi_lcdc_enable();
+		sunxi_tvencoder_enable();
+#endif
+		break;
 	}
 }
 
 static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
 {
 	switch (monitor) {
-	case sunxi_monitor_none:	return "none";
-	case sunxi_monitor_dvi:		return "dvi";
-	case sunxi_monitor_hdmi:	return "hdmi";
-	case sunxi_monitor_lcd:		return "lcd";
-	case sunxi_monitor_vga:		return "vga";
+	case sunxi_monitor_none:		return "none";
+	case sunxi_monitor_dvi:			return "dvi";
+	case sunxi_monitor_hdmi:		return "hdmi";
+	case sunxi_monitor_lcd:			return "lcd";
+	case sunxi_monitor_vga:			return "vga";
+	case sunxi_monitor_composite_pal:	return "composite-pal";
+	case sunxi_monitor_composite_ntsc:	return "composite-ntsc";
+	case sunxi_monitor_composite_pal_m:	return "composite-pal-m";
+	case sunxi_monitor_composite_pal_nc:	return "composite-pal-nc";
 	}
 	return NULL; /* never reached */
 }
@@ -1142,6 +1265,15 @@ static bool sunxi_has_vga(void)
 #endif
 }
 
+static bool sunxi_has_composite(void)
+{
+#ifdef CONFIG_VIDEO_COMPOSITE
+	return true;
+#else
+	return false;
+#endif
+}
+
 static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
 {
 	if (allow_hdmi && sunxi_has_hdmi())
@@ -1150,6 +1282,8 @@ static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
 		return sunxi_monitor_lcd;
 	else if (sunxi_has_vga())
 		return sunxi_monitor_vga;
+	else if (sunxi_has_composite())
+		return sunxi_monitor_composite_pal;
 	else
 		return sunxi_monitor_none;
 }
@@ -1234,6 +1368,22 @@ void *video_hw_init(void)
 		}
 		sunxi_display.depth = 18;
 		break;
+	case sunxi_monitor_composite_pal:
+	case sunxi_monitor_composite_ntsc:
+	case sunxi_monitor_composite_pal_m:
+	case sunxi_monitor_composite_pal_nc:
+		if (!sunxi_has_composite()) {
+			printf("Composite video not supported on this board\n");
+			sunxi_display.monitor = sunxi_monitor_none;
+			return NULL;
+		}
+		if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
+		    sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
+			mode = &composite_video_modes[0];
+		else
+			mode = &composite_video_modes[1];
+		sunxi_display.depth = 24;
+		break;
 	}
 
 	sunxi_display.fb_size =
@@ -1301,6 +1451,12 @@ int sunxi_simplefb_setup(void *blob)
 		pipeline = PIPELINE_PREFIX "de_be0-lcd0";
 #endif
 		break;
+	case sunxi_monitor_composite_pal:
+	case sunxi_monitor_composite_ntsc:
+	case sunxi_monitor_composite_pal_m:
+	case sunxi_monitor_composite_pal_nc:
+		pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
+		break;
 	}
 
 	/* Find a prefilled simpefb node, matching out pipeline config */
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions
  2015-08-03 21:54 [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions Hans de Goede
                   ` (3 preceding siblings ...)
  2015-08-03 21:54 ` [U-Boot] [PATCH 5/5] sunxi: display: Add composite video out support Hans de Goede
@ 2015-08-05  7:53 ` Ian Campbell
  4 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2015-08-05  7:53 UTC (permalink / raw)
  To: u-boot

On Mon, 2015-08-03 at 23:54 +0200, Hans de Goede wrote:
> 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 <hdegoede@redhat.com>

I couldn't quite convince myself there was "no semantic change" here,
but either way it's an improvement so:

Acked-by: Ian Campbell <ijc@hellion.org.uk>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 2/5] sunxi: display: Correct clk_delay calculations for lcd displays
  2015-08-03 21:54 ` [U-Boot] [PATCH 2/5] sunxi: display: Correct clk_delay calculations for lcd displays Hans de Goede
@ 2015-08-05  7:54   ` Ian Campbell
  0 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2015-08-05  7:54 UTC (permalink / raw)
  To: u-boot

On Mon, 2015-08-03 at 23:54 +0200, Hans de Goede wrote:
> We should only substract 2 from the vblank time when using tcon1.

"subtract"

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

Acked-by: Ian Campbell <ijc@hellion.org.uk>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 3/5] sunxi: display: Add a few extra register and constant defines
  2015-08-03 21:54 ` [U-Boot] [PATCH 3/5] sunxi: display: Add a few extra register and constant defines Hans de Goede
@ 2015-08-05  7:57   ` Ian Campbell
  2015-08-05 15:09     ` Hans de Goede
  0 siblings, 1 reply; 12+ messages in thread
From: Ian Campbell @ 2015-08-05  7:57 UTC (permalink / raw)
  To: u-boot

On Mon, 2015-08-03 at 23:54 +0200, Hans de Goede wrote:
> 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)."

> This is a preparation patch for adding composite video out support.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

Acked-by: Ian Campbell <ijc@hellion.org.uk>

> ---
>  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(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h 
> b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
> index 01d3e28..a7e25f4 100644
> --- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
> @@ -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)
> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h 
> b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
> index 8a26b9f..06c6feb 100644
> --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
> @@ -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)
> diff --git a/arch/arm/include/asm/arch-sunxi/display.h 
> b/arch/arm/include/asm/arch-sunxi/display.h
> index ae95417..830ec42 100644
> --- a/arch/arm/include/asm/arch-sunxi/display.h
> +++ b/arch/arm/include/asm/arch-sunxi/display.h
> @@ -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)
> @@ -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))
> @@ -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		0x00000000
>  
>  int sunxi_simplefb_setup(void *blob);
>  
> diff --git a/drivers/video/sunxi_display.c 
> b/drivers/video/sunxi_display.c
> index fa4241e..74a4280 100644
> --- a/drivers/video/sunxi_display.c
> +++ b/drivers/video/sunxi_display.c
> @@ -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)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 4/5] sunxi: display: Add support for interlaced modes
  2015-08-03 21:54 ` [U-Boot] [PATCH 4/5] sunxi: display: Add support for interlaced modes Hans de Goede
@ 2015-08-05  8:05   ` Ian Campbell
  2015-08-05 15:13     ` Hans de Goede
  0 siblings, 1 reply; 12+ messages in thread
From: Ian Campbell @ 2015-08-05  8:05 UTC (permalink / raw)
  To: u-boot

On Mon, 2015-08-03 at 23:54 +0200, Hans de Goede wrote:
> @@ -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) |

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:

Acked-by: Ian Campbell <ijc@hellion.org.uk>

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)
>  		return 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.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 5/5] sunxi: display: Add composite video out support
  2015-08-03 21:54 ` [U-Boot] [PATCH 5/5] sunxi: display: Add composite video out support Hans de Goede
@ 2015-08-05  8:07   ` Ian Campbell
  0 siblings, 0 replies; 12+ messages in thread
From: Ian Campbell @ 2015-08-05  8:07 UTC (permalink / raw)
  To: u-boot

On Mon, 2015-08-03 at 23:54 +0200, Hans de Goede wrote:
> 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 <hdegoede@redhat.com>

Acked-by: Ian Campbell <ijc@hellion.org.uk>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 3/5] sunxi: display: Add a few extra register and constant defines
  2015-08-05  7:57   ` Ian Campbell
@ 2015-08-05 15:09     ` Hans de Goede
  0 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2015-08-05 15:09 UTC (permalink / raw)
  To: u-boot

Hi,

On 05-08-15 09:57, Ian Campbell wrote:
> On Mon, 2015-08-03 at 23:54 +0200, Hans de Goede wrote:
>> 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)."

Added to the commit msg, thanks for the reviews.

Regards,

Hans


>
>> This is a preparation patch for adding composite video out support.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>
> Acked-by: Ian Campbell <ijc@hellion.org.uk>
>
>> ---
>>   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(-)
>>
>> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
>> b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
>> index 01d3e28..a7e25f4 100644
>> --- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
>> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
>> @@ -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)
>> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
>> b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
>> index 8a26b9f..06c6feb 100644
>> --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
>> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
>> @@ -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)
>> diff --git a/arch/arm/include/asm/arch-sunxi/display.h
>> b/arch/arm/include/asm/arch-sunxi/display.h
>> index ae95417..830ec42 100644
>> --- a/arch/arm/include/asm/arch-sunxi/display.h
>> +++ b/arch/arm/include/asm/arch-sunxi/display.h
>> @@ -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)
>> @@ -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))
>> @@ -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		0x00000000
>>
>>   int sunxi_simplefb_setup(void *blob);
>>
>> diff --git a/drivers/video/sunxi_display.c
>> b/drivers/video/sunxi_display.c
>> index fa4241e..74a4280 100644
>> --- a/drivers/video/sunxi_display.c
>> +++ b/drivers/video/sunxi_display.c
>> @@ -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)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 4/5] sunxi: display: Add support for interlaced modes
  2015-08-05  8:05   ` Ian Campbell
@ 2015-08-05 15:13     ` Hans de Goede
  0 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2015-08-05 15:13 UTC (permalink / raw)
  To: u-boot

Hi,

On 05-08-15 10:05, Ian Campbell wrote:
> On Mon, 2015-08-03 at 23:54 +0200, Hans de Goede wrote:
>> @@ -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) |
>
> 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.

Agreed, fixed.

>
> But ultimately the code is correct as you have it so either way as you
> prefer:
>
> Acked-by: Ian Campbell <ijc@hellion.org.uk>
>
> 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)
>>   		return 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)

Also fixed.

Thanks,

Hans

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-08-05 15:13 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-03 21:54 [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions Hans de Goede
2015-08-03 21:54 ` [U-Boot] [PATCH 2/5] sunxi: display: Correct clk_delay calculations for lcd displays Hans de Goede
2015-08-05  7:54   ` Ian Campbell
2015-08-03 21:54 ` [U-Boot] [PATCH 3/5] sunxi: display: Add a few extra register and constant defines Hans de Goede
2015-08-05  7:57   ` Ian Campbell
2015-08-05 15:09     ` Hans de Goede
2015-08-03 21:54 ` [U-Boot] [PATCH 4/5] sunxi: display: Add support for interlaced modes Hans de Goede
2015-08-05  8:05   ` Ian Campbell
2015-08-05 15:13     ` Hans de Goede
2015-08-03 21:54 ` [U-Boot] [PATCH 5/5] sunxi: display: Add composite video out support Hans de Goede
2015-08-05  8:07   ` Ian Campbell
2015-08-05  7:53 ` [U-Boot] [PATCH 1/5] sunxi: display: Replace #ifdef-ery with helper functions Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.