[U-Boot] [PATCH 05/17] sunxi: video: Improve monitor video-mode option handling

Hans de Goede hdegoede at redhat.com
Wed Dec 24 20:06:17 CET 2014


Add a sunxi_monitor enum and parse the monitor option string into this enum
once, rather then doing strcmp-s on it in various places. This also adds
checking for it being a valid value.

This also adds new "none" and "lcd" values in preparation for lcd support.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 drivers/video/sunxi_display.c | 51 +++++++++++++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index ced5ce5..83ee360 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -21,9 +21,18 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+enum sunxi_monitor {
+	sunxi_monitor_none,
+	sunxi_monitor_dvi,
+	sunxi_monitor_hdmi,
+	sunxi_monitor_lcd,
+	sunxi_monitor_vga,
+};
+
 struct sunxi_display {
 	GraphicDevice graphic_device;
 	bool enabled;
+	enum sunxi_monitor monitor;
 } sunxi_display;
 
 /*
@@ -159,7 +168,7 @@ static int sunxi_hdmi_edid_get_block(int block, u8 *buf)
 	return r;
 }
 
-static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode, char *monitor)
+static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode)
 {
 	struct edid1_info edid1;
 	struct edid_cea861_info cea681[4];
@@ -241,14 +250,14 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode, char *monitor)
 	}
 
 	/* Check for basic audio support, if found enable hdmi output */
-	strcpy(monitor, "dvi");
+	sunxi_display.monitor = sunxi_monitor_dvi;
 	for (i = 0; i < ext_blocks; i++) {
 		if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG ||
 		    cea681[i].revision < 2)
 			continue;
 
 		if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i]))
-			strcpy(monitor, "hdmi");
+			sunxi_display.monitor = sunxi_monitor_hdmi;
 	}
 
 	return 0;
@@ -489,7 +498,7 @@ static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode)
 }
 
 static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
-				bool hdmi_mode, int clk_div, int clk_double)
+				int clk_div, int clk_double)
 {
 	struct sunxi_hdmi_reg * const hdmi =
 		(struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
@@ -498,7 +507,7 @@ static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
 	/* Write clear interrupt status bits */
 	writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq);
 
-	if (hdmi_mode)
+	if (sunxi_display.monitor == sunxi_monitor_hdmi)
 		sunxi_hdmi_setup_info_frames(mode);
 
 	/* Set input sync enable */
@@ -549,7 +558,7 @@ static void sunxi_engines_init(void)
 #endif
 }
 
-static void sunxi_mode_set(const struct ctfb_res_modes *mode, char *monitor,
+static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 			   unsigned int address)
 {
 	struct sunxi_de_be_reg * const de_be =
@@ -559,11 +568,10 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode, char *monitor,
 	struct sunxi_hdmi_reg * const hdmi =
 		(struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
 	int clk_div, clk_double;
-	bool hdmi_mode = strcmp(monitor, "hdmi") == 0;
 
 	sunxi_composer_mode_set(mode, address);
 	sunxi_lcdc_mode_set(mode, &clk_div, &clk_double);
-	sunxi_hdmi_mode_set(mode, hdmi_mode, clk_div, clk_double);
+	sunxi_hdmi_mode_set(mode, clk_div, clk_double);
 
 	setbits_le32(&de_be->reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS);
 	setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START);
@@ -581,8 +589,9 @@ void *video_hw_init(void)
 	struct ctfb_res_modes edid_mode;
 	const char *options;
 	unsigned int depth;
-	int ret, hpd, edid;
-	char monitor[16];
+	int i, ret, hpd, edid;
+	char mon[16];
+	const char *mon_desc[] = { "none", "dvi", "hdmi", "lcd", "vga" };
 
 	memset(&sunxi_display, 0, sizeof(struct sunxi_display));
 
@@ -593,8 +602,18 @@ void *video_hw_init(void)
 	video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, &depth, &options);
 	hpd = video_get_option_int(options, "hpd", 1);
 	edid = video_get_option_int(options, "edid", 1);
-	video_get_option_string(options, "monitor", monitor, sizeof(monitor),
-				"dvi");
+	sunxi_display.monitor = sunxi_monitor_dvi;
+	video_get_option_string(options, "monitor", mon, sizeof(mon),
+				mon_desc[sunxi_display.monitor]);
+	for (i = 0; i < ARRAY_SIZE(mon_desc); i++) {
+		if (strcmp(mon, mon_desc[i]) == 0) {
+			sunxi_display.monitor = i;
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(mon_desc))
+		printf("Unknown monitor: '%s', falling back to '%s'\n",
+		       mon, mon_desc[sunxi_display.monitor]);
 
 	/* Always call hdp_detect, as it also enables various clocks, etc. */
 	ret = sunxi_hdmi_hpd_detect();
@@ -607,7 +626,7 @@ void *video_hw_init(void)
 
 	/* Check edid if requested and we've a cable plugged in */
 	if (edid && ret) {
-		if (sunxi_hdmi_edid_get_mode(&edid_mode, monitor) == 0)
+		if (sunxi_hdmi_edid_get_mode(&edid_mode) == 0)
 			mode = &edid_mode;
 	}
 
@@ -615,13 +634,13 @@ void *video_hw_init(void)
 		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, monitor);
+		printf("Setting up a %dx%d %s console\n", mode->xres,
+		       mode->yres, mon_desc[sunxi_display.monitor]);
 	}
 
 	sunxi_display.enabled = true;
 	sunxi_engines_init();
-	sunxi_mode_set(mode, monitor, gd->fb_base - CONFIG_SYS_SDRAM_BASE);
+	sunxi_mode_set(mode, gd->fb_base - CONFIG_SYS_SDRAM_BASE);
 
 	/*
 	 * These are the only members of this structure that are used. All the
-- 
2.1.0



More information about the U-Boot mailing list