All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support
@ 2014-12-31 12:07 Hans de Goede
  2014-12-31 12:07 ` [U-Boot] [PATCH v2 2/2] sunxi: video: Enable video on sun8i, which supports LCD but not HDMI Hans de Goede
  2015-01-01 20:21 ` [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support Siarhei Siamashka
  0 siblings, 2 replies; 6+ messages in thread
From: Hans de Goede @ 2014-12-31 12:07 UTC (permalink / raw)
  To: u-boot

Add lcd output support, see the new Kconfig entries and doc/README.video for
how to enable / configure this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-Do not request backlight gpio twices
-Fix some spelling errors in comments
-Fix some no longer accurate comments
---
 arch/arm/include/asm/arch-sunxi/display.h |  25 ++++-
 arch/arm/include/asm/arch-sunxi/gpio.h    |   2 +
 board/sunxi/Kconfig                       |  43 ++++++-
 doc/README.video                          |  50 +++++++--
 drivers/video/sunxi_display.c             | 179 ++++++++++++++++++++++++++++--
 5 files changed, 272 insertions(+), 27 deletions(-)

diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h
index 00e3466..dcb2fe4 100644
--- a/arch/arm/include/asm/arch-sunxi/display.h
+++ b/arch/arm/include/asm/arch-sunxi/display.h
@@ -57,14 +57,13 @@ struct sunxi_lcdc_reg {
 	u32 int0;			/* 0x04 */
 	u32 int1;			/* 0x08 */
 	u8 res0[0x04];			/* 0x0c */
-	u32 frame_ctrl;			/* 0x10 */
-	u8 res1[0x2c];			/* 0x14 */
+	u32 frame_ctrl[12];		/* 0x10 */
 	u32 tcon0_ctrl;			/* 0x40 */
 	u32 tcon0_dclk;			/* 0x44 */
-	u32 tcon0_basic_timing0;	/* 0x48 */
-	u32 tcon0_basic_timing1;	/* 0x4c */
-	u32 tcon0_basic_timing2;	/* 0x50 */
-	u32 tcon0_basic_timing3;	/* 0x54 */
+	u32 tcon0_timing_active;	/* 0x48 */
+	u32 tcon0_timing_h;		/* 0x4c */
+	u32 tcon0_timing_v;		/* 0x50 */
+	u32 tcon0_timing_sync;		/* 0x54 */
 	u32 tcon0_hv_intf;		/* 0x58 */
 	u8 res2[0x04];			/* 0x5c */
 	u32 tcon0_cpu_intf;		/* 0x60 */
@@ -179,7 +178,21 @@ struct sunxi_hdmi_reg {
 #define SUNXI_LCDC_CTRL_IO_MAP_TCON0		(0 << 0)
 #define SUNXI_LCDC_CTRL_IO_MAP_TCON1		(1 << 0)
 #define SUNXI_LCDC_CTRL_TCON_ENABLE		(1 << 31)
+#define SUNXI_LCDC_FRAME_CTRL0_RGB666		((1 << 31) | (0 << 4))
+#define SUNXI_LCDC_FRAME_CTRL0_RGB656		((1 << 31) | (5 << 4))
+#define SUNXI_LCDC_FRAME_CTRL_DITHER0		0x11111111
+#define SUNXI_LCDC_FRAME_CTRL_DITHER1		0x01010000
+#define SUNXI_LCDC_FRAME_CTRL_DITHER2		0x15151111
+#define SUNXI_LCDC_FRAME_CTRL_DITHER3		0x57575555
+#define SUNXI_LCDC_FRAME_CTRL_DITHER4		0x7f7f7777
+#define SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(n)	(((n) & 0x1f) << 4)
+#define SUNXI_LCDC_TCON0_CTRL_ENABLE		(1 << 31)
+#define SUNXI_LCDC_TCON0_DCLK_DIV(n)		((n) << 0)
 #define SUNXI_LCDC_TCON0_DCLK_ENABLE		(0xf << 28)
+#define SUNXI_LCDC_TCON0_TIMING_H_BP(n)		(((n) - 1) << 0)
+#define SUNXI_LCDC_TCON0_TIMING_H_TOTAL(n)	(((n) - 1) << 16)
+#define SUNXI_LCDC_TCON0_TIMING_V_BP(n)		(((n) - 1) << 0)
+#define SUNXI_LCDC_TCON0_TIMING_V_TOTAL(n)	(((n) * 2) << 16)
 #define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(n)	(((n) & 0x1f) << 4)
 #define SUNXI_LCDC_TCON1_CTRL_ENABLE		(1 << 31)
 #define SUNXI_LCDC_TCON1_TIMING_H_BP(n)		(((n) - 1) << 0)
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 32941cb..9438f5a 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -150,6 +150,8 @@ enum sunxi_gpio_number {
 
 #define SUNXI_GPC6_SDC2		3
 
+#define SUNXI_GPD0_LCD0		2
+
 #define SUNXI_GPF0_SDC0		2
 
 #define SUNXI_GPF2_SDC0		2
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 72c0165..6f2377d 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -281,17 +281,52 @@ config USB2_VBUS_PIN
 	See USB1_VBUS_PIN help text.
 
 config VIDEO
-	boolean "Enable graphical uboot console on HDMI"
+	boolean "Enable graphical uboot console on HDMI, LCD or VGA"
 	default y
 	---help---
-	Say Y here to add support for using a cfb console on the HDMI output
-	found on most sunxi devices.
+	Say Y here to add support for using a cfb console on the HDMI, LCD
+	or VGA output found on most sunxi devices. See doc/README.video for
+	info on how to select the video output and mode.
+
+config VIDEO_LCD_MODE
+	string "LCD panel timing details"
+	depends on VIDEO
+	default ""
+	---help---
+	LCD panel timing details string, leave empty if there is no LCD panel.
+	This is in drivers/video/videomodes.c: video_get_params() format, e.g.
+	x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:0,vmode:0
+
+config VIDEO_LCD_POWER
+	string "LCD panel power enable pin"
+	depends on VIDEO
+	default ""
+	---help---
+	Set the power enable pin for the LCD panel. This takes a string in the
+	format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
+
+config VIDEO_LCD_BL_EN
+	string "LCD panel backlight enable pin"
+	depends on VIDEO
+	default ""
+	---help---
+	Set the backlight enable pin for the LCD panel. This takes a string in the
+	the format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of
+	port H.
+
+config VIDEO_LCD_BL_PWM
+	string "LCD panel backlight pwm pin"
+	depends on VIDEO
+	default ""
+	---help---
+	Set the backlight pwm pin for the LCD panel. This takes a string in the
+	format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
 
 config USB_KEYBOARD
 	boolean "Enable USB keyboard support"
 	default y
 	---help---
 	Say Y here to add support for using a USB keyboard (typically used
-	in combination with a graphical console on HDMI).
+	in combination with a graphical console).
 
 endif
diff --git a/doc/README.video b/doc/README.video
index dadbfcd..cfe6318 100644
--- a/doc/README.video
+++ b/doc/README.video
@@ -5,15 +5,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-U-Boot MPC8xx video controller driver
-======================================
-
-The driver has been tested with the following configurations:
-
-- MPC823FADS with AD7176 on a PAL TV (YCbYCr)	- arsenio@tin.it
-
 "video-mode" environment variable
-===============================
+=================================
 
 The 'video-mode' environment variable can be used to enable and configure
 some video drivers.  The format matches the video= command-line option used
@@ -28,4 +21,45 @@ for Linux:
 	<freq>		The frequency (in Hz) to use.
 	<options>	A comma-separated list of device-specific options
 
+
+U-Boot MPC8xx video controller driver
+=====================================
+
+The driver has been tested with the following configurations:
+
+- MPC823FADS with AD7176 on a PAL TV (YCbYCr)	- arsenio at tin.it
+
 Example: video-mode=fslfb:1280x1024-32 at 60,monitor=dvi
+
+
+U-boot sunxi video controller driver
+====================================
+
+U-boot supports hdmi and lcd output on Allwinner sunxi SoCs, lcd output
+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
+ 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.
+ Defaults to monitor=dvi.
+
+- hpd=[0|1] - Enable use of the hdmi HotPlug Detect feature
+ 0: Disabled. Configure dvi/hdmi output even if no cable is detected
+ 1: Enabled. If a LCD has been configured fallback to the LCD when no cable is
+    detected, if no LCD is configured, disable video ouput.
+ Defaults to hpd=1.
+
+- edid=[0|1] - Enable use of DDC + EDID to get monitor info
+ 0: Disabled.
+ 1: Enabled. If valid EDID info was read from the monitor the EDID info will
+    overrides the xres, yres and refresh from the video-mode env. variable.
+ Defaults to edid=1.
+
+For example to always use the hdmi connector, even if no cable is inserted,
+using edid info when available and otherwise initalizing it at 1024x768 at 60Hz,
+use: video-mode=sunxi:1024x768-24 at 60,monitor=dvi,hpd=0,edid=1 .
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index ad38f16..fee1474 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -11,7 +11,9 @@
 
 #include <asm/arch/clock.h>
 #include <asm/arch/display.h>
+#include <asm/arch/gpio.h>
 #include <asm/global_data.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
 #include <errno.h>
 #include <fdtdec.h>
@@ -34,6 +36,7 @@ struct sunxi_display {
 	GraphicDevice graphic_device;
 	bool enabled;
 	enum sunxi_monitor monitor;
+	unsigned int depth;
 } sunxi_display;
 
 /*
@@ -435,6 +438,133 @@ static void sunxi_lcdc_enable(void)
 	setbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE);
 }
 
+static void sunxi_lcdc_panel_enable(void)
+{
+	int pin;
+
+	/*
+	 * Start with backlight disabled to avoid the screen flashing to
+	 * white while the lcd inits.
+	 */
+	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
+	if (pin != -1) {
+		gpio_request(pin, "lcd_backlight_enable");
+		gpio_direction_output(pin, 0);
+	}
+
+	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
+	if (pin != -1) {
+		gpio_request(pin, "lcd_backlight_pwm");
+		/* backlight pwm is inverted, set to 1 to disable backlight */
+		gpio_direction_output(pin, 1);
+	}
+
+	/* Give the backlight some time to turn off and power up the panel. */
+	mdelay(40);
+	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER);
+	if (pin != -1) {
+		gpio_request(pin, "lcd_power");
+		gpio_direction_output(pin, 1);
+	}
+}
+
+static void sunxi_lcdc_backlight_enable(void)
+{
+	int pin;
+
+	/*
+	 * We want to have scanned out at least one frame before enabling the
+	 * backlight to avoid the screen flashing to white when we enable it.
+	 */
+	mdelay(40);
+
+	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
+	if (pin != -1)
+		gpio_direction_output(pin, 1);
+
+	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
+	if (pin != -1) {
+		/* backlight pwm is inverted, set to 0 to enable backlight */
+		gpio_direction_output(pin, 0);
+	}
+}
+
+static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode)
+{
+	int delay;
+
+	delay = mode->lower_margin + mode->vsync_len + mode->upper_margin - 2;
+	return (delay > 30) ? 30 : delay;
+}
+
+static void sunxi_lcdc_tcon0_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, clk_div, clk_double, pin, total;
+
+	for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++)
+		sunxi_gpio_set_cfgpin(pin, SUNXI_GPD0_LCD0);
+
+	sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double);
+
+	/* Use tcon0 */
+	clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
+			SUNXI_LCDC_CTRL_IO_MAP_TCON0);
+
+	clk_delay = sunxi_lcdc_get_clk_delay(mode);
+	writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
+	       SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);
+
+	writel(SUNXI_LCDC_TCON0_DCLK_ENABLE |
+	       SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk);
+
+	writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
+	       &lcdc->tcon0_timing_active);
+
+	bp = mode->hsync_len + mode->left_margin;
+	total = mode->xres + mode->right_margin + bp;
+	writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) |
+	       SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h);
+
+	bp = mode->vsync_len + mode->upper_margin;
+	total = mode->yres + mode->lower_margin + bp;
+	writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) |
+	       SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v);
+
+	writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
+	       &lcdc->tcon0_timing_sync);
+
+	/* We only support hv-sync parallel lcd-s for now */
+	writel(0, &lcdc->tcon0_hv_intf);
+	writel(0, &lcdc->tcon0_cpu_intf);
+
+	if (sunxi_display.depth == 18 || sunxi_display.depth == 17) {
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[1]);
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[2]);
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[3]);
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[4]);
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[5]);
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[6]);
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER1, &lcdc->frame_ctrl[7]);
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER2, &lcdc->frame_ctrl[8]);
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER3, &lcdc->frame_ctrl[9]);
+		writel(SUNXI_LCDC_FRAME_CTRL_DITHER4, &lcdc->frame_ctrl[10]);
+		writel(((sunxi_display.depth == 18) ?
+			SUNXI_LCDC_FRAME_CTRL0_RGB666 :
+			SUNXI_LCDC_FRAME_CTRL0_RGB656),
+		       &lcdc->frame_ctrl[0]);
+	}
+
+	/*
+	 * Bit 24 and 25 of tcon0_io_polarity can be used to invert hsync /
+	 * vsync polarity, but this leads to noise problems, so we always
+	 * keep the polarity positive.
+	 */
+	writel(0, &lcdc->tcon0_io_polarity);
+	writel(0, &lcdc->tcon0_io_tristate);
+}
+
 static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 				      int *clk_div, int *clk_double)
 {
@@ -618,7 +748,12 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 		}
 		break;
 	case sunxi_monitor_lcd:
-		/* TODO */
+		sunxi_lcdc_panel_enable();
+		sunxi_composer_mode_set(mode, address);
+		sunxi_lcdc_tcon0_mode_set(mode);
+		sunxi_composer_enable();
+		sunxi_lcdc_enable();
+		sunxi_lcdc_backlight_enable();
 		break;
 	case sunxi_monitor_vga:
 		break;
@@ -641,11 +776,11 @@ void *video_hw_init(void)
 {
 	static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
 	const struct ctfb_res_modes *mode;
-	struct ctfb_res_modes edid_mode;
+	struct ctfb_res_modes custom;
 	const char *options;
-	unsigned int depth;
 	int i, ret, hpd, edid;
 	char mon[16];
+	char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
 
 	memset(&sunxi_display, 0, sizeof(struct sunxi_display));
 
@@ -653,7 +788,8 @@ void *video_hw_init(void)
 	       CONFIG_SUNXI_FB_SIZE >> 10);
 	gd->fb_base = gd->ram_top;
 
-	video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, &depth, &options);
+	video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
+				 &sunxi_display.depth, &options);
 	hpd = video_get_option_int(options, "hpd", 1);
 	edid = video_get_option_int(options, "edid", 1);
 	sunxi_display.monitor = sunxi_monitor_dvi;
@@ -678,16 +814,26 @@ void *video_hw_init(void)
 		ret = sunxi_hdmi_hpd_detect();
 		if (ret) {
 			printf("HDMI connected: ");
-			if (edid && sunxi_hdmi_edid_get_mode(&edid_mode) == 0)
-				mode = &edid_mode;
+			if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0)
+				mode = &custom;
 			break;
 		}
 		if (!hpd)
 			break; /* User has requested to ignore hpd */
 
 		sunxi_hdmi_shutdown();
-		return NULL;
+
+		if (lcd_mode[0] == 0)
+			return NULL; /* No LCD, bail */
+
+		/* Fall back / through to LCD */
+		sunxi_display.monitor = sunxi_monitor_lcd;
 	case sunxi_monitor_lcd:
+		if (lcd_mode[0]) {
+			sunxi_display.depth = video_get_params(&custom, lcd_mode);
+			mode = &custom;
+			break;
+		}
 		printf("LCD not supported on this board\n");
 		return NULL;
 	case sunxi_monitor_vga:
@@ -729,16 +875,31 @@ int sunxi_simplefb_setup(void *blob)
 {
 	static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
 	int offset, ret;
+	const char *pipeline = NULL;
 
 	if (!sunxi_display.enabled)
 		return 0;
 
-	/* Find a framebuffer node, with pipeline == "de_be0-lcd0-hdmi" */
+	switch (sunxi_display.monitor) {
+	case sunxi_monitor_none:
+		return 0;
+	case sunxi_monitor_dvi:
+	case sunxi_monitor_hdmi:
+		pipeline = "de_be0-lcd0-hdmi";
+		break;
+	case sunxi_monitor_lcd:
+		pipeline = "de_be0-lcd0";
+		break;
+	case sunxi_monitor_vga:
+		break;
+	}
+
+	/* Find a prefilled simpefb node, matching out pipeline config */
 	offset = fdt_node_offset_by_compatible(blob, -1,
 					       "allwinner,simple-framebuffer");
 	while (offset >= 0) {
 		ret = fdt_find_string(blob, offset, "allwinner,pipeline",
-				      "de_be0-lcd0-hdmi");
+				      pipeline);
 		if (ret == 0)
 			break;
 		offset = fdt_node_offset_by_compatible(blob, offset,
-- 
2.1.0

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

* [U-Boot] [PATCH v2 2/2] sunxi: video: Enable video on sun8i, which supports LCD but not HDMI
  2014-12-31 12:07 [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support Hans de Goede
@ 2014-12-31 12:07 ` Hans de Goede
  2015-01-07 18:51   ` Ian Campbell
  2015-01-01 20:21 ` [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support Siarhei Siamashka
  1 sibling, 1 reply; 6+ messages in thread
From: Hans de Goede @ 2014-12-31 12:07 UTC (permalink / raw)
  To: u-boot

The A23 (sun8i) only has lcd output support, so allow building the video code
without HDMI support for use with the A23.

Also the A23 has the same reset bits (and necessity to enable the DRC block)
as the sun6i, so enable those bits for sun8i too.

Note building without HDMI support is useful for the A13 (sun5i variant) too,
as that one does not have HDMI either.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-Improve commit message to better reflect what the patch does
---
 board/sunxi/Kconfig           |  7 +++++++
 drivers/video/sunxi_display.c | 30 ++++++++++++++++++++++++++----
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 6f2377d..ff4fbb4 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -288,6 +288,13 @@ config VIDEO
 	or VGA output found on most sunxi devices. See doc/README.video for
 	info on how to select the video output and mode.
 
+config VIDEO_HDMI
+	boolean "HDMI output support"
+	depends on VIDEO && !MACH_SUN8I
+	default y
+	---help---
+	Say Y here to add support for outputting video over HDMI.
+
 config VIDEO_LCD_MODE
 	string "LCD panel timing details"
 	depends on VIDEO
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index fee1474..9481b95 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -39,6 +39,8 @@ struct sunxi_display {
 	unsigned int depth;
 } sunxi_display;
 
+#ifdef CONFIG_VIDEO_HDMI
+
 /*
  * Wait up to 200ms for value to be set in given part of reg.
  */
@@ -267,6 +269,8 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode)
 	return 0;
 }
 
+#endif /* CONFIG_VIDEO_HDMI */
+
 /*
  * This is the entity that mixes and matches the different layers and inputs.
  * Allwinner calls it the back-end, but i like composer better.
@@ -279,7 +283,7 @@ static void sunxi_composer_init(void)
 		(struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
 	int i;
 
-#ifdef CONFIG_MACH_SUN6I
+#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
 	/* Reset off */
 	setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE_BE0);
 #endif
@@ -409,7 +413,7 @@ static void sunxi_lcdc_init(void)
 		(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
 
 	/* Reset off */
-#ifdef CONFIG_MACH_SUN6I
+#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
 	setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0);
 #else
 	setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_RST);
@@ -565,6 +569,8 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode)
 	writel(0, &lcdc->tcon0_io_tristate);
 }
 
+#ifdef CONFIG_VIDEO_HDMI
+
 static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 				      int *clk_div, int *clk_double)
 {
@@ -711,9 +717,11 @@ static void sunxi_hdmi_enable(void)
 	setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE);
 }
 
+#endif /* CONFIG_VIDEO_HDMI */
+
 static void sunxi_drc_init(void)
 {
-#ifdef CONFIG_MACH_SUN6I
+#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
 	struct sunxi_ccm_reg * const ccm =
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 
@@ -738,6 +746,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 		break;
 	case sunxi_monitor_dvi:
 	case sunxi_monitor_hdmi: {
+#ifdef CONFIG_VIDEO_HDMI
 		int clk_div, clk_double;
 		sunxi_composer_mode_set(mode, address);
 		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double);
@@ -745,6 +754,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 		sunxi_composer_enable();
 		sunxi_lcdc_enable();
 		sunxi_hdmi_enable();
+#endif
 		}
 		break;
 	case sunxi_monitor_lcd:
@@ -778,9 +788,12 @@ void *video_hw_init(void)
 	const struct ctfb_res_modes *mode;
 	struct ctfb_res_modes custom;
 	const char *options;
-	int i, ret, hpd, edid;
+#ifdef CONFIG_VIDEO_HDMI
+	int ret, hpd, edid;
+#endif
 	char mon[16];
 	char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
+	int i;
 
 	memset(&sunxi_display, 0, sizeof(struct sunxi_display));
 
@@ -790,9 +803,13 @@ void *video_hw_init(void)
 
 	video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
 				 &sunxi_display.depth, &options);
+#ifdef CONFIG_VIDEO_HDMI
 	hpd = video_get_option_int(options, "hpd", 1);
 	edid = video_get_option_int(options, "edid", 1);
 	sunxi_display.monitor = sunxi_monitor_dvi;
+#else
+	sunxi_display.monitor = sunxi_monitor_lcd;
+#endif
 	video_get_option_string(options, "monitor", mon, sizeof(mon),
 				sunxi_get_mon_desc(sunxi_display.monitor));
 	for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
@@ -810,6 +827,10 @@ void *video_hw_init(void)
 		return NULL;
 	case sunxi_monitor_dvi:
 	case sunxi_monitor_hdmi:
+#ifndef CONFIG_VIDEO_HDMI
+		printf("HDMI/DVI not supported on this board\n");
+		return NULL;
+#else
 		/* Always call hdp_detect, as it also enables clocks, etc. */
 		ret = sunxi_hdmi_hpd_detect();
 		if (ret) {
@@ -828,6 +849,7 @@ void *video_hw_init(void)
 
 		/* Fall back / through to LCD */
 		sunxi_display.monitor = sunxi_monitor_lcd;
+#endif
 	case sunxi_monitor_lcd:
 		if (lcd_mode[0]) {
 			sunxi_display.depth = video_get_params(&custom, lcd_mode);
-- 
2.1.0

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

* [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support
  2014-12-31 12:07 [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support Hans de Goede
  2014-12-31 12:07 ` [U-Boot] [PATCH v2 2/2] sunxi: video: Enable video on sun8i, which supports LCD but not HDMI Hans de Goede
@ 2015-01-01 20:21 ` Siarhei Siamashka
  2015-01-05 16:21   ` Hans de Goede
  1 sibling, 1 reply; 6+ messages in thread
From: Siarhei Siamashka @ 2015-01-01 20:21 UTC (permalink / raw)
  To: u-boot

On Wed, 31 Dec 2014 13:07:20 +0100
Hans de Goede <hdegoede@redhat.com> wrote:

> Add lcd output support, see the new Kconfig entries and doc/README.video for
> how to enable / configure this.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> Changes in v2:
> -Do not request backlight gpio twices
> -Fix some spelling errors in comments
> -Fix some no longer accurate comments
> ---
>  arch/arm/include/asm/arch-sunxi/display.h |  25 ++++-
>  arch/arm/include/asm/arch-sunxi/gpio.h    |   2 +
>  board/sunxi/Kconfig                       |  43 ++++++-
>  doc/README.video                          |  50 +++++++--
>  drivers/video/sunxi_display.c             | 179 ++++++++++++++++++++++++++++--
>  5 files changed, 272 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h
> index 00e3466..dcb2fe4 100644
> --- a/arch/arm/include/asm/arch-sunxi/display.h
> +++ b/arch/arm/include/asm/arch-sunxi/display.h
> @@ -57,14 +57,13 @@ struct sunxi_lcdc_reg {
>  	u32 int0;			/* 0x04 */
>  	u32 int1;			/* 0x08 */
>  	u8 res0[0x04];			/* 0x0c */
> -	u32 frame_ctrl;			/* 0x10 */
> -	u8 res1[0x2c];			/* 0x14 */
> +	u32 frame_ctrl[12];		/* 0x10 */
>  	u32 tcon0_ctrl;			/* 0x40 */
>  	u32 tcon0_dclk;			/* 0x44 */
> -	u32 tcon0_basic_timing0;	/* 0x48 */
> -	u32 tcon0_basic_timing1;	/* 0x4c */
> -	u32 tcon0_basic_timing2;	/* 0x50 */
> -	u32 tcon0_basic_timing3;	/* 0x54 */
> +	u32 tcon0_timing_active;	/* 0x48 */
> +	u32 tcon0_timing_h;		/* 0x4c */
> +	u32 tcon0_timing_v;		/* 0x50 */
> +	u32 tcon0_timing_sync;		/* 0x54 */
>  	u32 tcon0_hv_intf;		/* 0x58 */
>  	u8 res2[0x04];			/* 0x5c */
>  	u32 tcon0_cpu_intf;		/* 0x60 */
> @@ -179,7 +178,21 @@ struct sunxi_hdmi_reg {
>  #define SUNXI_LCDC_CTRL_IO_MAP_TCON0		(0 << 0)
>  #define SUNXI_LCDC_CTRL_IO_MAP_TCON1		(1 << 0)
>  #define SUNXI_LCDC_CTRL_TCON_ENABLE		(1 << 31)
> +#define SUNXI_LCDC_FRAME_CTRL0_RGB666		((1 << 31) | (0 << 4))
> +#define SUNXI_LCDC_FRAME_CTRL0_RGB656		((1 << 31) | (5 << 4))

This would be probably SUNXI_LCDC_FRAME_CTRL0_RGB565 according to
the Allwinner documentation of the TCON0_FRM_CTL_REG register:

 0: 6bit frm output
 1: 5bit frm output

Since we have 5 there (101 bit pattern), it simply means RGB565.

> +#define SUNXI_LCDC_FRAME_CTRL_DITHER0		0x11111111
> +#define SUNXI_LCDC_FRAME_CTRL_DITHER1		0x01010000
> +#define SUNXI_LCDC_FRAME_CTRL_DITHER2		0x15151111
> +#define SUNXI_LCDC_FRAME_CTRL_DITHER3		0x57575555
> +#define SUNXI_LCDC_FRAME_CTRL_DITHER4		0x7f7f7777
> +#define SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(n)	(((n) & 0x1f) << 4)
> +#define SUNXI_LCDC_TCON0_CTRL_ENABLE		(1 << 31)
> +#define SUNXI_LCDC_TCON0_DCLK_DIV(n)		((n) << 0)
>  #define SUNXI_LCDC_TCON0_DCLK_ENABLE		(0xf << 28)
> +#define SUNXI_LCDC_TCON0_TIMING_H_BP(n)		(((n) - 1) << 0)
> +#define SUNXI_LCDC_TCON0_TIMING_H_TOTAL(n)	(((n) - 1) << 16)
> +#define SUNXI_LCDC_TCON0_TIMING_V_BP(n)		(((n) - 1) << 0)
> +#define SUNXI_LCDC_TCON0_TIMING_V_TOTAL(n)	(((n) * 2) << 16)
>  #define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(n)	(((n) & 0x1f) << 4)
>  #define SUNXI_LCDC_TCON1_CTRL_ENABLE		(1 << 31)
>  #define SUNXI_LCDC_TCON1_TIMING_H_BP(n)		(((n) - 1) << 0)
> diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
> index 32941cb..9438f5a 100644
> --- a/arch/arm/include/asm/arch-sunxi/gpio.h
> +++ b/arch/arm/include/asm/arch-sunxi/gpio.h
> @@ -150,6 +150,8 @@ enum sunxi_gpio_number {
>  
>  #define SUNXI_GPC6_SDC2		3
>  
> +#define SUNXI_GPD0_LCD0		2
> +
>  #define SUNXI_GPF0_SDC0		2
>  
>  #define SUNXI_GPF2_SDC0		2
> diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
> index 72c0165..6f2377d 100644
> --- a/board/sunxi/Kconfig
> +++ b/board/sunxi/Kconfig
> @@ -281,17 +281,52 @@ config USB2_VBUS_PIN
>  	See USB1_VBUS_PIN help text.
>  
>  config VIDEO
> -	boolean "Enable graphical uboot console on HDMI"
> +	boolean "Enable graphical uboot console on HDMI, LCD or VGA"
>  	default y
>  	---help---
> -	Say Y here to add support for using a cfb console on the HDMI output
> -	found on most sunxi devices.
> +	Say Y here to add support for using a cfb console on the HDMI, LCD
> +	or VGA output found on most sunxi devices. See doc/README.video for
> +	info on how to select the video output and mode.
> +
> +config VIDEO_LCD_MODE
> +	string "LCD panel timing details"
> +	depends on VIDEO
> +	default ""
> +	---help---
> +	LCD panel timing details string, leave empty if there is no LCD panel.
> +	This is in drivers/video/videomodes.c: video_get_params() format, e.g.
> +	x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:0,vmode:0
> +
> +config VIDEO_LCD_POWER
> +	string "LCD panel power enable pin"
> +	depends on VIDEO
> +	default ""
> +	---help---
> +	Set the power enable pin for the LCD panel. This takes a string in the
> +	format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
> +
> +config VIDEO_LCD_BL_EN
> +	string "LCD panel backlight enable pin"
> +	depends on VIDEO
> +	default ""
> +	---help---
> +	Set the backlight enable pin for the LCD panel. This takes a string in the
> +	the format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of
> +	port H.
> +
> +config VIDEO_LCD_BL_PWM
> +	string "LCD panel backlight pwm pin"
> +	depends on VIDEO
> +	default ""
> +	---help---
> +	Set the backlight pwm pin for the LCD panel. This takes a string in the
> +	format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
>  
>  config USB_KEYBOARD
>  	boolean "Enable USB keyboard support"
>  	default y
>  	---help---
>  	Say Y here to add support for using a USB keyboard (typically used
> -	in combination with a graphical console on HDMI).
> +	in combination with a graphical console).
>  
>  endif
> diff --git a/doc/README.video b/doc/README.video
> index dadbfcd..cfe6318 100644
> --- a/doc/README.video
> +++ b/doc/README.video
> @@ -5,15 +5,8 @@
>   * SPDX-License-Identifier:	GPL-2.0+
>   */
>  
> -U-Boot MPC8xx video controller driver
> -======================================
> -
> -The driver has been tested with the following configurations:
> -
> -- MPC823FADS with AD7176 on a PAL TV (YCbYCr)	- arsenio at tin.it
> -
>  "video-mode" environment variable
> -===============================
> +=================================
>  
>  The 'video-mode' environment variable can be used to enable and configure
>  some video drivers.  The format matches the video= command-line option used
> @@ -28,4 +21,45 @@ for Linux:
>  	<freq>		The frequency (in Hz) to use.
>  	<options>	A comma-separated list of device-specific options
>  
> +
> +U-Boot MPC8xx video controller driver
> +=====================================
> +
> +The driver has been tested with the following configurations:
> +
> +- MPC823FADS with AD7176 on a PAL TV (YCbYCr)	- arsenio at tin.it
> +
>  Example: video-mode=fslfb:1280x1024-32 at 60,monitor=dvi
> +
> +
> +U-boot sunxi video controller driver
> +====================================
> +
> +U-boot supports hdmi and lcd output on Allwinner sunxi SoCs, lcd output
> +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
> + 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.
> + Defaults to monitor=dvi.
> +
> +- hpd=[0|1] - Enable use of the hdmi HotPlug Detect feature
> + 0: Disabled. Configure dvi/hdmi output even if no cable is detected
> + 1: Enabled. If a LCD has been configured fallback to the LCD when no cable is
> +    detected, if no LCD is configured, disable video ouput.
> + Defaults to hpd=1.
> +
> +- edid=[0|1] - Enable use of DDC + EDID to get monitor info
> + 0: Disabled.
> + 1: Enabled. If valid EDID info was read from the monitor the EDID info will
> +    overrides the xres, yres and refresh from the video-mode env. variable.
> + Defaults to edid=1.
> +
> +For example to always use the hdmi connector, even if no cable is inserted,
> +using edid info when available and otherwise initalizing it at 1024x768 at 60Hz,
> +use: video-mode=sunxi:1024x768-24 at 60,monitor=dvi,hpd=0,edid=1 .
> diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
> index ad38f16..fee1474 100644
> --- a/drivers/video/sunxi_display.c
> +++ b/drivers/video/sunxi_display.c
> @@ -11,7 +11,9 @@
>  
>  #include <asm/arch/clock.h>
>  #include <asm/arch/display.h>
> +#include <asm/arch/gpio.h>
>  #include <asm/global_data.h>
> +#include <asm/gpio.h>
>  #include <asm/io.h>
>  #include <errno.h>
>  #include <fdtdec.h>
> @@ -34,6 +36,7 @@ struct sunxi_display {
>  	GraphicDevice graphic_device;
>  	bool enabled;
>  	enum sunxi_monitor monitor;
> +	unsigned int depth;
>  } sunxi_display;
>  
>  /*
> @@ -435,6 +438,133 @@ static void sunxi_lcdc_enable(void)
>  	setbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE);
>  }
>  
> +static void sunxi_lcdc_panel_enable(void)
> +{
> +	int pin;
> +
> +	/*
> +	 * Start with backlight disabled to avoid the screen flashing to
> +	 * white while the lcd inits.
> +	 */
> +	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
> +	if (pin != -1) {
> +		gpio_request(pin, "lcd_backlight_enable");
> +		gpio_direction_output(pin, 0);
> +	}
> +
> +	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
> +	if (pin != -1) {
> +		gpio_request(pin, "lcd_backlight_pwm");
> +		/* backlight pwm is inverted, set to 1 to disable backlight */
> +		gpio_direction_output(pin, 1);
> +	}
> +
> +	/* Give the backlight some time to turn off and power up the panel. */
> +	mdelay(40);
> +	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER);
> +	if (pin != -1) {
> +		gpio_request(pin, "lcd_power");
> +		gpio_direction_output(pin, 1);
> +	}
> +}
> +
> +static void sunxi_lcdc_backlight_enable(void)
> +{
> +	int pin;
> +
> +	/*
> +	 * We want to have scanned out at least one frame before enabling the
> +	 * backlight to avoid the screen flashing to white when we enable it.
> +	 */
> +	mdelay(40);
> +
> +	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
> +	if (pin != -1)
> +		gpio_direction_output(pin, 1);
> +
> +	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
> +	if (pin != -1) {
> +		/* backlight pwm is inverted, set to 0 to enable backlight */
> +		gpio_direction_output(pin, 0);
> +	}
> +}
> +
> +static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode)
> +{
> +	int delay;
> +
> +	delay = mode->lower_margin + mode->vsync_len + mode->upper_margin - 2;
> +	return (delay > 30) ? 30 : delay;
> +}
> +
> +static void sunxi_lcdc_tcon0_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, clk_div, clk_double, pin, total;
> +
> +	for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++)
> +		sunxi_gpio_set_cfgpin(pin, SUNXI_GPD0_LCD0);
> +
> +	sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double);
> +
> +	/* Use tcon0 */
> +	clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
> +			SUNXI_LCDC_CTRL_IO_MAP_TCON0);
> +
> +	clk_delay = sunxi_lcdc_get_clk_delay(mode);
> +	writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
> +	       SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);
> +
> +	writel(SUNXI_LCDC_TCON0_DCLK_ENABLE |
> +	       SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk);
> +
> +	writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
> +	       &lcdc->tcon0_timing_active);
> +
> +	bp = mode->hsync_len + mode->left_margin;
> +	total = mode->xres + mode->right_margin + bp;
> +	writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) |
> +	       SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h);
> +
> +	bp = mode->vsync_len + mode->upper_margin;
> +	total = mode->yres + mode->lower_margin + bp;
> +	writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) |
> +	       SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v);
> +
> +	writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
> +	       &lcdc->tcon0_timing_sync);
> +
> +	/* We only support hv-sync parallel lcd-s for now */
> +	writel(0, &lcdc->tcon0_hv_intf);
> +	writel(0, &lcdc->tcon0_cpu_intf);
> +
> +	if (sunxi_display.depth == 18 || sunxi_display.depth == 17) {

Here 17 is not quite correct for RGB565.

Also these are dithering settings, and this code just unconditionally
enables the right dithering for 16-bit LCD displays (this seems to
be never used in any real device from the sunxi-boards repository) or
18-bit LCD displays, which are very common.

Because 32-bit framebuffers support more colors than the 18-bit LCD
hardware can show, dithering is needed and used:
    http://en.wikipedia.org/wiki/Frame_rate_control

Do we want to have a separate option to enable/disable dithering? Or
just keep it always enabled until somebody complains?

A simple program for testing dithering effects/usefulness can be found
here:
    http://lists.denx.de/pipermail/u-boot/2015-January/200031.html

> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[1]);
> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[2]);
> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[3]);
> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[4]);
> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[5]);
> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER0, &lcdc->frame_ctrl[6]);
> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER1, &lcdc->frame_ctrl[7]);
> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER2, &lcdc->frame_ctrl[8]);
> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER3, &lcdc->frame_ctrl[9]);
> +		writel(SUNXI_LCDC_FRAME_CTRL_DITHER4, &lcdc->frame_ctrl[10]);
> +		writel(((sunxi_display.depth == 18) ?
> +			SUNXI_LCDC_FRAME_CTRL0_RGB666 :
> +			SUNXI_LCDC_FRAME_CTRL0_RGB656),
> +		       &lcdc->frame_ctrl[0]);
> +	}
> +
> +	/*
> +	 * Bit 24 and 25 of tcon0_io_polarity can be used to invert hsync /
> +	 * vsync polarity, but this leads to noise problems, so we always
> +	 * keep the polarity positive.
> +	 */
> +	writel(0, &lcdc->tcon0_io_polarity);
> +	writel(0, &lcdc->tcon0_io_tristate);
> +}
> +
>  static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
>  				      int *clk_div, int *clk_double)
>  {
> @@ -618,7 +748,12 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
>  		}
>  		break;
>  	case sunxi_monitor_lcd:
> -		/* TODO */
> +		sunxi_lcdc_panel_enable();
> +		sunxi_composer_mode_set(mode, address);
> +		sunxi_lcdc_tcon0_mode_set(mode);
> +		sunxi_composer_enable();
> +		sunxi_lcdc_enable();
> +		sunxi_lcdc_backlight_enable();
>  		break;
>  	case sunxi_monitor_vga:
>  		break;
> @@ -641,11 +776,11 @@ void *video_hw_init(void)
>  {
>  	static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
>  	const struct ctfb_res_modes *mode;
> -	struct ctfb_res_modes edid_mode;
> +	struct ctfb_res_modes custom;
>  	const char *options;
> -	unsigned int depth;
>  	int i, ret, hpd, edid;
>  	char mon[16];
> +	char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
>  
>  	memset(&sunxi_display, 0, sizeof(struct sunxi_display));
>  
> @@ -653,7 +788,8 @@ void *video_hw_init(void)
>  	       CONFIG_SUNXI_FB_SIZE >> 10);
>  	gd->fb_base = gd->ram_top;
>  
> -	video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, &depth, &options);
> +	video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
> +				 &sunxi_display.depth, &options);
>  	hpd = video_get_option_int(options, "hpd", 1);
>  	edid = video_get_option_int(options, "edid", 1);
>  	sunxi_display.monitor = sunxi_monitor_dvi;
> @@ -678,16 +814,26 @@ void *video_hw_init(void)
>  		ret = sunxi_hdmi_hpd_detect();
>  		if (ret) {
>  			printf("HDMI connected: ");
> -			if (edid && sunxi_hdmi_edid_get_mode(&edid_mode) == 0)
> -				mode = &edid_mode;
> +			if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0)
> +				mode = &custom;
>  			break;
>  		}
>  		if (!hpd)
>  			break; /* User has requested to ignore hpd */
>  
>  		sunxi_hdmi_shutdown();
> -		return NULL;
> +
> +		if (lcd_mode[0] == 0)
> +			return NULL; /* No LCD, bail */
> +
> +		/* Fall back / through to LCD */
> +		sunxi_display.monitor = sunxi_monitor_lcd;
>  	case sunxi_monitor_lcd:
> +		if (lcd_mode[0]) {
> +			sunxi_display.depth = video_get_params(&custom, lcd_mode);
> +			mode = &custom;
> +			break;
> +		}
>  		printf("LCD not supported on this board\n");
>  		return NULL;
>  	case sunxi_monitor_vga:
> @@ -729,16 +875,31 @@ int sunxi_simplefb_setup(void *blob)
>  {
>  	static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
>  	int offset, ret;
> +	const char *pipeline = NULL;
>  
>  	if (!sunxi_display.enabled)
>  		return 0;
>  
> -	/* Find a framebuffer node, with pipeline == "de_be0-lcd0-hdmi" */
> +	switch (sunxi_display.monitor) {
> +	case sunxi_monitor_none:
> +		return 0;
> +	case sunxi_monitor_dvi:
> +	case sunxi_monitor_hdmi:
> +		pipeline = "de_be0-lcd0-hdmi";
> +		break;
> +	case sunxi_monitor_lcd:
> +		pipeline = "de_be0-lcd0";
> +		break;
> +	case sunxi_monitor_vga:
> +		break;
> +	}
> +
> +	/* Find a prefilled simpefb node, matching out pipeline config */
>  	offset = fdt_node_offset_by_compatible(blob, -1,
>  					       "allwinner,simple-framebuffer");
>  	while (offset >= 0) {
>  		ret = fdt_find_string(blob, offset, "allwinner,pipeline",
> -				      "de_be0-lcd0-hdmi");
> +				      pipeline);
>  		if (ret == 0)
>  			break;
>  		offset = fdt_node_offset_by_compatible(blob, offset,



-- 
Best regards,
Siarhei Siamashka

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

* [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support
  2015-01-01 20:21 ` [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support Siarhei Siamashka
@ 2015-01-05 16:21   ` Hans de Goede
  0 siblings, 0 replies; 6+ messages in thread
From: Hans de Goede @ 2015-01-05 16:21 UTC (permalink / raw)
  To: u-boot

Hi,

On 01-01-15 21:21, Siarhei Siamashka wrote:
> On Wed, 31 Dec 2014 13:07:20 +0100
> Hans de Goede <hdegoede@redhat.com> wrote:
>
>> Add lcd output support, see the new Kconfig entries and doc/README.video for
>> how to enable / configure this.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

<snip>

>> @@ -179,7 +178,21 @@ struct sunxi_hdmi_reg {
>>   #define SUNXI_LCDC_CTRL_IO_MAP_TCON0		(0 << 0)
>>   #define SUNXI_LCDC_CTRL_IO_MAP_TCON1		(1 << 0)
>>   #define SUNXI_LCDC_CTRL_TCON_ENABLE		(1 << 31)
>> +#define SUNXI_LCDC_FRAME_CTRL0_RGB666		((1 << 31) | (0 << 4))
>> +#define SUNXI_LCDC_FRAME_CTRL0_RGB656		((1 << 31) | (5 << 4))
>
> This would be probably SUNXI_LCDC_FRAME_CTRL0_RGB565 according to
> the Allwinner documentation of the TCON0_FRM_CTL_REG register:
>
>   0: 6bit frm output
>   1: 5bit frm output
>
> Since we have 5 there (101 bit pattern), it simply means RGB565.

You're completely right, I took over the weird RGB656 naming from the
allwinner kernel code without thinking things through properly.


<snip>

>> +	bp = mode->vsync_len + mode->upper_margin;
>> +	total = mode->yres + mode->lower_margin + bp;
>> +	writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) |
>> +	       SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v);
>> +
>> +	writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
>> +	       &lcdc->tcon0_timing_sync);
>> +
>> +	/* We only support hv-sync parallel lcd-s for now */
>> +	writel(0, &lcdc->tcon0_hv_intf);
>> +	writel(0, &lcdc->tcon0_cpu_intf);
>> +
>> +	if (sunxi_display.depth == 18 || sunxi_display.depth == 17) {
>
> Here 17 is not quite correct for RGB565.

Right, this should be 16 meaning plain old RGB565, I've fixed both in
my personal tree. Thanks for pointing this out!



>
> Also these are dithering settings, and this code just unconditionally
> enables the right dithering for 16-bit LCD displays (this seems to
> be never used in any real device from the sunxi-boards repository) or
> 18-bit LCD displays, which are very common.
>
> Because 32-bit framebuffers support more colors than the 18-bit LCD
> hardware can show, dithering is needed and used:
>      http://en.wikipedia.org/wiki/Frame_rate_control
>
> Do we want to have a separate option to enable/disable dithering? Or
> just keep it always enabled until somebody complains?
>
> A simple program for testing dithering effects/usefulness can be found
> here:
>      http://lists.denx.de/pipermail/u-boot/2015-January/200031.html

<snip>

Regards,

Hans

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

* [U-Boot] [PATCH v2 2/2] sunxi: video: Enable video on sun8i, which supports LCD but not HDMI
  2014-12-31 12:07 ` [U-Boot] [PATCH v2 2/2] sunxi: video: Enable video on sun8i, which supports LCD but not HDMI Hans de Goede
@ 2015-01-07 18:51   ` Ian Campbell
  2015-01-07 19:54     ` Hans de Goede
  0 siblings, 1 reply; 6+ messages in thread
From: Ian Campbell @ 2015-01-07 18:51 UTC (permalink / raw)
  To: u-boot

On Wed, 2014-12-31 at 13:07 +0100, Hans de Goede wrote:
> The A23 (sun8i) only has lcd output support, so allow building the video code
> without HDMI support for use with the A23.
> 
> Also the A23 has the same reset bits (and necessity to enable the DRC block)
> as the sun6i, so enable those bits for sun8i too.
> 
> Note building without HDMI support is useful for the A13 (sun5i variant) too,
> as that one does not have HDMI either.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> Changes in v2:
> -Improve commit message to better reflect what the patch does

Much better, thanks. Acked-by: Ian Campbell <ijc@hellion.org.uk>

I think a v3 is still pending on #1/2 based on Siahei's feedback, or did
I miss it?

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

* [U-Boot] [PATCH v2 2/2] sunxi: video: Enable video on sun8i, which supports LCD but not HDMI
  2015-01-07 18:51   ` Ian Campbell
@ 2015-01-07 19:54     ` Hans de Goede
  0 siblings, 0 replies; 6+ messages in thread
From: Hans de Goede @ 2015-01-07 19:54 UTC (permalink / raw)
  To: u-boot

Hi,

On 07-01-15 19:51, Ian Campbell wrote:
> On Wed, 2014-12-31 at 13:07 +0100, Hans de Goede wrote:
>> The A23 (sun8i) only has lcd output support, so allow building the video code
>> without HDMI support for use with the A23.
>>
>> Also the A23 has the same reset bits (and necessity to enable the DRC block)
>> as the sun6i, so enable those bits for sun8i too.
>>
>> Note building without HDMI support is useful for the A13 (sun5i variant) too,
>> as that one does not have HDMI either.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>> Changes in v2:
>> -Improve commit message to better reflect what the patch does
>
> Much better, thanks. Acked-by: Ian Campbell <ijc@hellion.org.uk>
>
> I think a v3 is still pending on #1/2 based on Siahei's feedback, or did
> I miss it?

Fixing the RGB656 vs RGB565 thing was such a simple fix that I've simply
squashed it into v2 in my personal tree, without sending a v3, but I can send
a v3 if you want one ...

Regards,

Hans

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

end of thread, other threads:[~2015-01-07 19:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-31 12:07 [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support Hans de Goede
2014-12-31 12:07 ` [U-Boot] [PATCH v2 2/2] sunxi: video: Enable video on sun8i, which supports LCD but not HDMI Hans de Goede
2015-01-07 18:51   ` Ian Campbell
2015-01-07 19:54     ` Hans de Goede
2015-01-01 20:21 ` [U-Boot] [PATCH v2 1/2] sunxi: video: Add lcd output support Siarhei Siamashka
2015-01-05 16:21   ` Hans de Goede

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.