hrcon: Add support for the DH variant

hrcon DH(dual head) has two video outputs per FPGA.

Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
diff --git a/board/gdsys/common/osd.c b/board/gdsys/common/osd.c
index f11e26f..b288df8 100644
--- a/board/gdsys/common/osd.c
+++ b/board/gdsys/common/osd.c
@@ -28,12 +28,45 @@
 
 #define PIXCLK_640_480_60 25180000
 
+#ifdef CONFIG_SYS_OSD_DH
+#define MAX_OSD_SCREEN 8
+#define OSD_DH_BASE 4
+#else
+#define MAX_OSD_SCREEN 4
+#endif
+
+#ifdef CONFIG_SYS_OSD_DH
+#define OSD_SET_REG(screen, fld, val) \
+	do { \
+		if (screen >= OSD_DH_BASE) \
+			FPGA_SET_REG(screen - OSD_DH_BASE, osd1.fld, val); \
+		else \
+			FPGA_SET_REG(screen, osd0.fld, val); \
+	} while (0)
+#else
+#define OSD_SET_REG(screen, fld, val) \
+		FPGA_SET_REG(screen, osd0.fld, val)
+#endif
+
+#ifdef CONFIG_SYS_OSD_DH
+#define OSD_GET_REG(screen, fld, val) \
+	do {					\
+		if (screen >= OSD_DH_BASE) \
+			FPGA_GET_REG(screen - OSD_DH_BASE, osd1.fld, val); \
+		else \
+			FPGA_GET_REG(screen, osd0.fld, val); \
+	} while (0)
+#else
+#define OSD_GET_REG(screen, fld, val) \
+		FPGA_GET_REG(screen, osd0.fld, val)
+#endif
+
 unsigned int base_width;
 unsigned int base_height;
 size_t bufsize;
 u16 *buf;
 
-unsigned int max_osd_screen = CONFIG_SYS_OSD_SCREENS - 1;
+unsigned int osd_screen_mask = 0;
 
 #ifdef CONFIG_SYS_ICS8N3QV01_I2C
 int ics8n3qv01_i2c[] = CONFIG_SYS_ICS8N3QV01_I2C;
@@ -47,6 +80,9 @@
 int dp501_i2c[] = CONFIG_SYS_DP501_I2C;
 #endif
 
+#ifdef CONFIG_SYS_DP501_BASE
+int dp501_base[] = CONFIG_SYS_DP501_BASE;
+#endif
 
 #ifdef CONFIG_SYS_MPC92469AC
 static void mpc92469ac_calc_parameters(unsigned int fout,
@@ -216,7 +252,15 @@
 	for (k = 0; k < charcount; ++k) {
 		if (offset + k >= bufsize)
 			return -1;
-		FPGA_SET_REG(screen, videomem[offset + k], data[k]);
+#ifdef CONFIG_SYS_OSD_DH
+		if (screen >= OSD_DH_BASE)
+			FPGA_SET_REG(screen - OSD_DH_BASE,
+				     videomem1[offset + k], data[k]);
+		else
+			FPGA_SET_REG(screen, videomem0[offset + k], data[k]);
+#else
+		FPGA_SET_REG(screen, videomem0[offset + k], data[k]);
+#endif
 	}
 
 	return charcount;
@@ -226,7 +270,12 @@
 {
 	unsigned screen;
 
-	for (screen = 0; screen <= max_osd_screen; ++screen) {
+	if (argc < 5) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
 		unsigned x;
 		unsigned y;
 		unsigned charcount;
@@ -236,10 +285,8 @@
 		char *text;
 		int res;
 
-		if (argc < 5) {
-			cmd_usage(cmdtp);
-			return 1;
-		}
+		if (!(osd_screen_mask & (1 << screen)))
+			continue;
 
 		x = simple_strtoul(argv[1], NULL, 16);
 		y = simple_strtoul(argv[2], NULL, 16);
@@ -266,9 +313,16 @@
 	int old_bus = i2c_get_bus_num();
 	bool pixclock_present = false;
 	bool output_driver_present = false;
+#ifdef CONFIG_SYS_DP501_I2C
+#ifdef CONFIG_SYS_DP501_BASE
+	uint8_t dp501_addr = dp501_base[screen];
+#else
+	uint8_t dp501_addr = DP501_I2C_ADDR;
+#endif
+#endif
 
-	FPGA_GET_REG(0, osd.version, &version);
-	FPGA_GET_REG(0, osd.features, &features);
+	OSD_GET_REG(0, version, &version);
+	OSD_GET_REG(0, features, &features);
 
 	base_width = ((features & 0x3f00) >> 8) + 1;
 	base_height = (features & 0x001f) + 1;
@@ -277,9 +331,15 @@
 	if (!buf)
 		return -1;
 
+#ifdef CONFIG_SYS_OSD_DH
+	printf("OSD%d-%d: Digital-OSD version %01d.%02d, %d" "x%d characters\n",
+	       (screen >= OSD_DH_BASE) ? (screen - OSD_DH_BASE) : screen,
+	       (screen > 3) ? 1 : 0, version/100, version%100, base_width,
+	       base_height);
+#else
 	printf("OSD%d:  Digital-OSD version %01d.%02d, %d" "x%d characters\n",
-		screen, version/100, version%100, base_width, base_height);
-
+	       screen, version/100, version%100, base_width, base_height);
+#endif
 	/* setup pixclock */
 
 #ifdef CONFIG_SYS_MPC92469AC
@@ -330,8 +390,8 @@
 
 #ifdef CONFIG_SYS_DP501_I2C
 	i2c_set_bus_num(dp501_i2c[screen]);
-	if (!i2c_probe(DP501_I2C_ADDR)) {
-		dp501_powerup(DP501_I2C_ADDR);
+	if (!i2c_probe(dp501_addr)) {
+		dp501_powerup(dp501_addr);
 		output_driver_present = true;
 	}
 #endif
@@ -339,14 +399,14 @@
 	if (!output_driver_present)
 		printf("       no output driver found\n");
 
-	FPGA_SET_REG(screen, osd.control, 0x0049);
+	OSD_SET_REG(screen, control, 0x0049);
 
-	FPGA_SET_REG(screen, osd.xy_size, ((32 - 1) << 8) | (16 - 1));
-	FPGA_SET_REG(screen, osd.x_pos, 0x007f);
-	FPGA_SET_REG(screen, osd.y_pos, 0x005f);
+	OSD_SET_REG(screen, xy_size, ((32 - 1) << 8) | (16 - 1));
+	OSD_SET_REG(screen, x_pos, 0x007f);
+	OSD_SET_REG(screen, y_pos, 0x005f);
 
-	if (screen > max_osd_screen)
-		max_osd_screen = screen;
+	if (pixclock_present && output_driver_present)
+		osd_screen_mask |= 1 << screen;
 
 	i2c_set_bus_num(old_bus);
 
@@ -357,7 +417,12 @@
 {
 	unsigned screen;
 
+	if ((argc < 4) || (strlen(argv[3]) % 4)) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
-	for (screen = 0; screen <= max_osd_screen; ++screen) {
+	for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
 		unsigned x;
 		unsigned y;
 		unsigned k;
@@ -367,10 +432,8 @@
 		unsigned count = (argc > 4) ?
 			simple_strtoul(argv[4], NULL, 16) : 1;
 
-		if ((argc < 4) || (strlen(argv[3]) % 4)) {
-			cmd_usage(cmdtp);
-			return 1;
-		}
+		if (!(osd_screen_mask & (1 << screen)))
+			continue;
 
 		x = simple_strtoul(argv[1], NULL, 16);
 		y = simple_strtoul(argv[2], NULL, 16);