aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/board/gdsys/common
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/board/gdsys/common')
-rw-r--r--roms/u-boot/board/gdsys/common/Makefile13
-rw-r--r--roms/u-boot/board/gdsys/common/cmd_ioloop.c585
-rw-r--r--roms/u-boot/board/gdsys/common/dp501.c161
-rw-r--r--roms/u-boot/board/gdsys/common/dp501.h31
-rw-r--r--roms/u-boot/board/gdsys/common/fpga.c28
-rw-r--r--roms/u-boot/board/gdsys/common/ihs_mdio.c164
-rw-r--r--roms/u-boot/board/gdsys/common/ihs_mdio.h22
-rw-r--r--roms/u-boot/board/gdsys/common/ioep-fpga.c591
-rw-r--r--roms/u-boot/board/gdsys/common/ioep-fpga.h13
-rw-r--r--roms/u-boot/board/gdsys/common/osd.c506
-rw-r--r--roms/u-boot/board/gdsys/common/osd.h13
-rw-r--r--roms/u-boot/board/gdsys/common/osd_cmd.c147
12 files changed, 2274 insertions, 0 deletions
diff --git a/roms/u-boot/board/gdsys/common/Makefile b/roms/u-boot/board/gdsys/common/Makefile
new file mode 100644
index 000000000..dd6d5e69d
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/Makefile
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2007
+# Stefan Roese, DENX Software Engineering, sr@denx.de.
+
+obj-$(CONFIG_SYS_FPGA_COMMON) += fpga.o
+obj-$(CONFIG_CMD_IOLOOP) += cmd_ioloop.o
+obj-$(CONFIG_CONTROLCENTERD) += dp501.o
+obj-$(CONFIG_TARGET_GAZERBEAM) += osd.o ihs_mdio.o ioep-fpga.o
+
+ifdef CONFIG_OSD
+obj-$(CONFIG_GDSYS_LEGACY_OSD_CMDS) += osd_cmd.o
+endif
diff --git a/roms/u-boot/board/gdsys/common/cmd_ioloop.c b/roms/u-boot/board/gdsys/common/cmd_ioloop.c
new file mode 100644
index 000000000..658756d98
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/cmd_ioloop.c
@@ -0,0 +1,585 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ */
+
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+
+#include <gdsys_fpga.h>
+
+#ifndef CONFIG_GDSYS_LEGACY_DRIVERS
+#include <dm.h>
+#include <misc.h>
+#include <regmap.h>
+#include <sysinfo.h>
+
+#include "../../../drivers/misc/gdsys_soc.h"
+#include "../../../drivers/misc/gdsys_ioep.h"
+#include "../../../drivers/misc/ihs_fpga.h"
+
+const int HEADER_WORDS = sizeof(struct io_generic_packet) / 2;
+#endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
+
+enum status_print_type {
+ STATUS_LOUD = 0,
+ STATUS_SILENT = 1,
+};
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+enum {
+ STATE_TX_PACKET_BUILDING = BIT(0),
+ STATE_TX_TRANSMITTING = BIT(1),
+ STATE_TX_BUFFER_FULL = BIT(2),
+ STATE_TX_ERR = BIT(3),
+ STATE_RECEIVE_TIMEOUT = BIT(4),
+ STATE_PROC_RX_STORE_TIMEOUT = BIT(5),
+ STATE_PROC_RX_RECEIVE_TIMEOUT = BIT(6),
+ STATE_RX_DIST_ERR = BIT(7),
+ STATE_RX_LENGTH_ERR = BIT(8),
+ STATE_RX_FRAME_CTR_ERR = BIT(9),
+ STATE_RX_FCS_ERR = BIT(10),
+ STATE_RX_PACKET_DROPPED = BIT(11),
+ STATE_RX_DATA_LAST = BIT(12),
+ STATE_RX_DATA_FIRST = BIT(13),
+ STATE_RX_DATA_AVAILABLE = BIT(15),
+};
+
+enum {
+ IRQ_CPU_TRANSMITBUFFER_FREE_STATUS = BIT(5),
+ IRQ_CPU_PACKET_TRANSMITTED_EVENT = BIT(6),
+ IRQ_NEW_CPU_PACKET_RECEIVED_EVENT = BIT(7),
+ IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS = BIT(8),
+};
+
+enum {
+ CTRL_PROC_RECEIVE_ENABLE = BIT(12),
+ CTRL_FLUSH_TRANSMIT_BUFFER = BIT(15),
+};
+
+struct io_generic_packet {
+ u16 target_address;
+ u16 source_address;
+ u8 packet_type;
+ u8 bc;
+ u16 packet_length;
+} __attribute__((__packed__));
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+
+unsigned long long rx_ctr;
+unsigned long long tx_ctr;
+unsigned long long err_ctr;
+#ifndef CONFIG_GDSYS_LEGACY_DRIVERS
+struct udevice *dev;
+#endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+static void io_check_status(uint fpga, u16 status, enum status_print_type type)
+{
+ u16 mask = STATE_RX_DIST_ERR | STATE_RX_LENGTH_ERR |
+ STATE_RX_FRAME_CTR_ERR | STATE_RX_FCS_ERR |
+ STATE_RX_PACKET_DROPPED | STATE_TX_ERR;
+
+ if (!(status & mask)) {
+ FPGA_SET_REG(fpga, ep.rx_tx_status, status);
+ return;
+ }
+
+ err_ctr++;
+ FPGA_SET_REG(fpga, ep.rx_tx_status, status);
+
+ if (type == STATUS_SILENT)
+ return;
+
+ if (status & STATE_RX_PACKET_DROPPED)
+ printf("RX_PACKET_DROPPED, status %04x\n", status);
+
+ if (status & STATE_RX_DIST_ERR)
+ printf("RX_DIST_ERR\n");
+ if (status & STATE_RX_LENGTH_ERR)
+ printf("RX_LENGTH_ERR\n");
+ if (status & STATE_RX_FRAME_CTR_ERR)
+ printf("RX_FRAME_CTR_ERR\n");
+ if (status & STATE_RX_FCS_ERR)
+ printf("RX_FCS_ERR\n");
+
+ if (status & STATE_TX_ERR)
+ printf("TX_ERR\n");
+}
+#else
+static void io_check_status(struct udevice *dev, enum status_print_type type)
+{
+ u16 status = 0;
+ int ret;
+
+ ret = misc_call(dev, 0, NULL, 0, &status, 0);
+ if (!ret)
+ return;
+
+ err_ctr++;
+
+ if (type != STATUS_LOUD)
+ return;
+
+ if (status & STATE_RX_PACKET_DROPPED)
+ printf("RX_PACKET_DROPPED, status %04x\n", status);
+
+ if (status & STATE_RX_DIST_ERR)
+ printf("RX_DIST_ERR\n");
+ if (status & STATE_RX_LENGTH_ERR)
+ printf("RX_LENGTH_ERR\n");
+ if (status & STATE_RX_FRAME_CTR_ERR)
+ printf("RX_FRAME_CTR_ERR\n");
+ if (status & STATE_RX_FCS_ERR)
+ printf("RX_FCS_ERR\n");
+
+ if (status & STATE_TX_ERR)
+ printf("TX_ERR\n");
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+static void io_send(uint fpga, uint size)
+{
+ uint k;
+ struct io_generic_packet packet = {
+ .source_address = 1,
+ .packet_type = 1,
+ .packet_length = size,
+ };
+ u16 *p = (u16 *)&packet;
+
+ for (k = 0; k < sizeof(packet) / 2; ++k)
+ FPGA_SET_REG(fpga, ep.transmit_data, *p++);
+
+ for (k = 0; k < (size + 1) / 2; ++k)
+ FPGA_SET_REG(fpga, ep.transmit_data, k);
+
+ FPGA_SET_REG(fpga, ep.rx_tx_control,
+ CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
+
+ tx_ctr++;
+}
+#else
+static void io_send(struct udevice *dev, uint size)
+{
+ uint k;
+ u16 buffer[HEADER_WORDS + 128];
+ struct io_generic_packet header = {
+ .source_address = 1,
+ .packet_type = 1,
+ .packet_length = size,
+ };
+ const uint words = (size + 1) / 2;
+
+ memcpy(buffer, &header, 2 * HEADER_WORDS);
+ for (k = 0; k < words; ++k)
+ buffer[k + HEADER_WORDS] = (2 * k + 1) + ((2 * k) << 8);
+
+ misc_write(dev, 0, buffer, HEADER_WORDS + words);
+
+ tx_ctr++;
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+static void io_receive(uint fpga)
+{
+ u16 rx_tx_status;
+
+ FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
+
+ while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
+ u16 rx;
+
+ if (rx_tx_status & STATE_RX_DATA_LAST)
+ rx_ctr++;
+
+ FPGA_GET_REG(fpga, ep.receive_data, &rx);
+
+ FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
+ }
+}
+#else
+static void io_receive(struct udevice *dev)
+{
+ u16 buffer[HEADER_WORDS + 128];
+
+ if (!misc_read(dev, 0, buffer, 0))
+ rx_ctr++;
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+static void io_reflect(uint fpga)
+{
+ u16 buffer[128];
+
+ uint k = 0;
+ uint n;
+ u16 rx_tx_status;
+
+ FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
+
+ while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
+ FPGA_GET_REG(fpga, ep.receive_data, &buffer[k++]);
+ if (rx_tx_status & STATE_RX_DATA_LAST)
+ break;
+
+ FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
+ }
+
+ if (!k)
+ return;
+
+ for (n = 0; n < k; ++n)
+ FPGA_SET_REG(fpga, ep.transmit_data, buffer[n]);
+
+ FPGA_SET_REG(fpga, ep.rx_tx_control,
+ CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
+
+ tx_ctr++;
+}
+#else
+static void io_reflect(struct udevice *dev)
+{
+ u16 buffer[HEADER_WORDS + 128];
+ struct io_generic_packet *header;
+
+ if (misc_read(dev, 0, buffer, 0))
+ return;
+
+ header = (struct io_generic_packet *)&buffer;
+
+ misc_write(dev, 0, buffer, HEADER_WORDS + header->packet_length);
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+/*
+ * FPGA io-endpoint reflector
+ *
+ * Syntax:
+ * ioreflect {fpga} {reportrate}
+ */
+int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ uint fpga;
+ uint rate = 0;
+ unsigned long long last_seen = 0;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ fpga = simple_strtoul(argv[1], NULL, 10);
+
+ /*
+ * If another parameter, it is the report rate in packets.
+ */
+ if (argc > 2)
+ rate = simple_strtoul(argv[2], NULL, 10);
+
+ /* Enable receive path */
+ FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
+
+ /* Set device address to dummy 1*/
+ FPGA_SET_REG(fpga, ep.device_address, 1);
+
+ rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
+
+ while (1) {
+ u16 top_int;
+ u16 rx_tx_status;
+
+ FPGA_GET_REG(fpga, top_interrupt, &top_int);
+ FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
+
+ io_check_status(fpga, rx_tx_status, STATUS_SILENT);
+ if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) &&
+ (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS))
+ io_reflect(fpga);
+
+ if (rate) {
+ if (!(tx_ctr % rate) && (tx_ctr != last_seen))
+ printf("refl %llu, err %llu\n", tx_ctr,
+ err_ctr);
+ last_seen = tx_ctr;
+ }
+
+ if (ctrlc())
+ break;
+ }
+
+ return 0;
+}
+#else
+/*
+ * FPGA io-endpoint reflector
+ *
+ * Syntax:
+ * ioreflect {reportrate}
+ */
+int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ struct udevice *fpga;
+ struct regmap *map;
+ uint rate = 0;
+ unsigned long long last_seen = 0;
+
+ if (!dev) {
+ printf("No device selected\n");
+ return 1;
+ }
+
+ gdsys_soc_get_fpga(dev, &fpga);
+ regmap_init_mem(dev_ofnode(dev), &map);
+
+ /* Enable receive path */
+ misc_set_enabled(dev, true);
+
+ rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
+
+ while (1) {
+ uint top_int;
+
+ ihs_fpga_get(map, top_interrupt, &top_int);
+ io_check_status(dev, STATUS_SILENT);
+ if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) &&
+ (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS))
+ io_reflect(dev);
+
+ if (rate) {
+ if (!(tx_ctr % rate) && (tx_ctr != last_seen))
+ printf("refl %llu, err %llu\n", tx_ctr,
+ err_ctr);
+ last_seen = tx_ctr;
+ }
+
+ if (ctrlc())
+ break;
+ }
+
+ return 0;
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#define DISP_LINE_LEN 16
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+/*
+ * FPGA io-endpoint looptest
+ *
+ * Syntax:
+ * ioloop {fpga} {size} {rate}
+ */
+int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ uint fpga;
+ uint size;
+ uint rate = 0;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ /*
+ * FPGA is specified since argc > 2
+ */
+ fpga = simple_strtoul(argv[1], NULL, 10);
+
+ /*
+ * packet size is specified since argc > 2
+ */
+ size = simple_strtoul(argv[2], NULL, 10);
+
+ /*
+ * If another parameter, it is the test rate in packets per second.
+ */
+ if (argc > 3)
+ rate = simple_strtoul(argv[3], NULL, 10);
+
+ /* enable receive path */
+ FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
+
+ /* set device address to dummy 1*/
+ FPGA_SET_REG(fpga, ep.device_address, 1);
+
+ rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
+
+ while (1) {
+ u16 top_int;
+ u16 rx_tx_status;
+
+ FPGA_GET_REG(fpga, top_interrupt, &top_int);
+ FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
+
+ io_check_status(fpga, rx_tx_status, STATUS_LOUD);
+ if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
+ io_send(fpga, size);
+ if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
+ io_receive(fpga);
+
+ if (rate) {
+ if (ctrlc())
+ break;
+ udelay(1000000 / rate);
+ if (!(tx_ctr % rate))
+ printf("d %llu, tx %llu, rx %llu, err %llu\n",
+ tx_ctr - rx_ctr, tx_ctr, rx_ctr,
+ err_ctr);
+ }
+ }
+
+ return 0;
+}
+#else
+/*
+ * FPGA io-endpoint looptest
+ *
+ * Syntax:
+ * ioloop {size} {rate}
+ */
+int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ uint size;
+ uint rate = 0;
+ struct udevice *fpga;
+ struct regmap *map;
+
+ if (!dev) {
+ printf("No device selected\n");
+ return 1;
+ }
+
+ gdsys_soc_get_fpga(dev, &fpga);
+ regmap_init_mem(dev_ofnode(dev), &map);
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ /*
+ * packet size is specified since argc > 1
+ */
+ size = simple_strtoul(argv[2], NULL, 10);
+
+ /*
+ * If another parameter, it is the test rate in packets per second.
+ */
+ if (argc > 2)
+ rate = simple_strtoul(argv[3], NULL, 10);
+
+ /* Enable receive path */
+ misc_set_enabled(dev, true);
+
+ rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
+
+ while (1) {
+ uint top_int;
+
+ if (ctrlc())
+ break;
+
+ ihs_fpga_get(map, top_interrupt, &top_int);
+
+ io_check_status(dev, STATUS_LOUD);
+ if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
+ io_send(dev, size);
+ if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
+ io_receive(dev);
+
+ if (rate) {
+ udelay(1000000 / rate);
+ if (!(tx_ctr % rate))
+ printf("d %llu, tx %llu, rx %llu, err %llu\n",
+ tx_ctr - rx_ctr, tx_ctr, rx_ctr,
+ err_ctr);
+ }
+ }
+ return 0;
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#ifndef CONFIG_GDSYS_LEGACY_DRIVERS
+int do_iodev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ struct udevice *ioep = NULL;
+ struct udevice *sysinfo;
+ char name[8];
+ int ret;
+
+ if (sysinfo_get(&sysinfo))
+ return CMD_RET_FAILURE;
+
+ if (argc > 1) {
+ int i = simple_strtoul(argv[1], NULL, 10);
+
+ snprintf(name, sizeof(name), "ioep%d", i);
+
+ ret = uclass_get_device_by_phandle(UCLASS_MISC, sysinfo, name,
+ &ioep);
+
+ if (ret || !ioep) {
+ printf("Invalid IOEP %d\n", i);
+ return CMD_RET_FAILURE;
+ }
+
+ dev = ioep;
+ } else {
+ int i = 0;
+
+ while (1) {
+ snprintf(name, sizeof(name), "ioep%d", i);
+
+ ret = uclass_get_device_by_phandle(UCLASS_MISC, sysinfo,
+ name, &ioep);
+
+ if (ret || !ioep)
+ break;
+
+ printf("IOEP %d:\t%s\n", i++, ioep->name);
+ }
+
+ if (dev)
+ printf("\nSelected IOEP: %s\n", dev->name);
+ else
+ puts("\nNo IOEP selected.\n");
+ }
+
+ return 0;
+}
+#endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+U_BOOT_CMD(
+ ioloop, 4, 0, do_ioloop,
+ "fpga io-endpoint looptest",
+ "fpga packetsize [packets/sec]"
+);
+
+U_BOOT_CMD(
+ ioreflect, 3, 0, do_ioreflect,
+ "fpga io-endpoint reflector",
+ "fpga reportrate"
+);
+#else
+U_BOOT_CMD(
+ ioloop, 3, 0, do_ioloop,
+ "fpga io-endpoint looptest",
+ "packetsize [packets/sec]"
+);
+
+U_BOOT_CMD(
+ ioreflect, 2, 0, do_ioreflect,
+ "fpga io-endpoint reflector",
+ "reportrate"
+);
+
+U_BOOT_CMD(
+ iodev, 2, 0, do_iodev,
+ "fpga io-endpoint listing/selection",
+ "[ioep device to select]"
+);
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/roms/u-boot/board/gdsys/common/dp501.c b/roms/u-boot/board/gdsys/common/dp501.c
new file mode 100644
index 000000000..9ca69ebcb
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/dp501.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2012
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ */
+
+/* Parade Technologies Inc. DP501 DisplayPort DVI/HDMI Transmitter */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
+#include <common.h>
+#include <asm/io.h>
+#include <errno.h>
+#include <i2c.h>
+
+#define DP501_I2C_ADDR 0x08
+
+#ifdef CONFIG_SYS_DP501_I2C
+int dp501_i2c[] = CONFIG_SYS_DP501_I2C;
+#endif
+
+#ifdef CONFIG_SYS_DP501_BASE
+int dp501_base[] = CONFIG_SYS_DP501_BASE;
+#endif
+
+static void dp501_setbits(u8 addr, u8 reg, u8 mask)
+{
+ u8 val;
+
+ val = i2c_reg_read(addr, reg);
+ setbits_8(&val, mask);
+ i2c_reg_write(addr, reg, val);
+}
+
+static void dp501_clrbits(u8 addr, u8 reg, u8 mask)
+{
+ u8 val;
+
+ val = i2c_reg_read(addr, reg);
+ clrbits_8(&val, mask);
+ i2c_reg_write(addr, reg, val);
+}
+
+static int dp501_detect_cable_adapter(u8 addr)
+{
+ u8 val = i2c_reg_read(addr, 0x00);
+
+ return !(val & 0x04);
+}
+
+static void dp501_link_training(u8 addr)
+{
+ u8 val;
+ u8 link_bw;
+ u8 max_lane_cnt;
+ u8 lane_cnt;
+
+ val = i2c_reg_read(addr, 0x51);
+ if (val >= 0x0a)
+ link_bw = 0x0a;
+ else
+ link_bw = 0x06;
+ if (link_bw != val)
+ printf("DP sink supports %d Mbps link rate, set to %d Mbps\n",
+ val * 270, link_bw * 270);
+ i2c_reg_write(addr, 0x5d, link_bw); /* set link_bw */
+ val = i2c_reg_read(addr, 0x52);
+ max_lane_cnt = val & 0x1f;
+ if (max_lane_cnt >= 4)
+ lane_cnt = 4;
+ else
+ lane_cnt = max_lane_cnt;
+ if (lane_cnt != max_lane_cnt)
+ printf("DP sink supports %d lanes, set to %d lanes\n",
+ max_lane_cnt, lane_cnt);
+ i2c_reg_write(addr, 0x5e, lane_cnt | (val & 0x80)); /* set lane_cnt */
+ val = i2c_reg_read(addr, 0x53);
+ i2c_reg_write(addr, 0x5c, val); /* set downspread_ctl */
+
+ i2c_reg_write(addr, 0x5f, 0x0d); /* start training */
+}
+
+void dp501_powerup(u8 addr)
+{
+ dp501_clrbits(addr, 0x0a, 0x30); /* power on encoder */
+ dp501_setbits(addr, 0x0a, 0x0e); /* block HDCP and MCCS on I2C bride*/
+ i2c_reg_write(addr, 0x27, 0x30); /* Hardware auto detect DVO timing */
+ dp501_setbits(addr, 0x72, 0x80); /* DPCD read enable */
+ dp501_setbits(addr, 0x30, 0x20); /* RS polynomial select */
+ i2c_reg_write(addr, 0x71, 0x20); /* Enable Aux burst write */
+ dp501_setbits(addr, 0x78, 0x30); /* Disable HPD2 IRQ */
+ dp501_clrbits(addr, 0x2f, 0x40); /* Link FIFO reset selection */
+ dp501_clrbits(addr, 0x60, 0x20); /* Enable scrambling */
+
+#ifdef CONFIG_SYS_DP501_VCAPCTRL0
+ i2c_reg_write(addr, 0x24, CONFIG_SYS_DP501_VCAPCTRL0);
+#else
+ i2c_reg_write(addr, 0x24, 0xc0); /* SDR mode 0, ext. H/VSYNC */
+#endif
+
+#ifdef CONFIG_SYS_DP501_DIFFERENTIAL
+ i2c_reg_write(addr + 2, 0x24, 0x10); /* clock input differential */
+ i2c_reg_write(addr + 2, 0x25, 0x04);
+ i2c_reg_write(addr + 2, 0x26, 0x10);
+#else
+ i2c_reg_write(addr + 2, 0x24, 0x02); /* clock input single ended */
+#endif
+
+ i2c_reg_write(addr + 2, 0x1a, 0x04); /* SPDIF input method TTL */
+
+ i2c_reg_write(addr + 2, 0x00, 0x18); /* driving strength */
+ i2c_reg_write(addr + 2, 0x03, 0x06); /* driving strength */
+ i2c_reg_write(addr, 0x2c, 0x00); /* configure N value */
+ i2c_reg_write(addr, 0x2d, 0x00); /* configure N value */
+ i2c_reg_write(addr, 0x2e, 0x0c); /* configure N value */
+ i2c_reg_write(addr, 0x76, 0xff); /* clear all interrupt */
+ dp501_setbits(addr, 0x78, 0x03); /* clear all interrupt */
+ i2c_reg_write(addr, 0x75, 0xf8); /* aux channel reset */
+ i2c_reg_write(addr, 0x75, 0x00); /* clear aux channel reset */
+ i2c_reg_write(addr, 0x87, 0x7f); /* set retry counter as 7
+ retry interval 400us */
+
+ if (dp501_detect_cable_adapter(addr)) {
+ printf("DVI/HDMI cable adapter detected\n");
+ i2c_reg_write(addr, 0x5e, 0x04); /* enable 4 channel */
+ dp501_clrbits(addr, 0x00, 0x08); /* DVI/HDMI HDCP operation */
+ } else {
+ printf("no DVI/HDMI cable adapter detected\n");
+ dp501_setbits(addr, 0x00, 0x08); /* for DP HDCP operation */
+
+ dp501_link_training(addr);
+ }
+}
+
+void dp501_powerdown(u8 addr)
+{
+ dp501_setbits(addr, 0x0a, 0x30); /* power down encoder, standby mode */
+}
+
+
+int dp501_probe(unsigned screen, bool power)
+{
+#ifdef CONFIG_SYS_DP501_BASE
+ uint8_t dp501_addr = dp501_base[screen];
+#else
+ uint8_t dp501_addr = DP501_I2C_ADDR;
+#endif
+
+#ifdef CONFIG_SYS_DP501_I2C
+ i2c_set_bus_num(dp501_i2c[screen]);
+#endif
+
+ if (i2c_probe(dp501_addr))
+ return -1;
+
+ dp501_powerup(dp501_addr);
+
+ return 0;
+}
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/roms/u-boot/board/gdsys/common/dp501.h b/roms/u-boot/board/gdsys/common/dp501.h
new file mode 100644
index 000000000..b98b54edc
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/dp501.h
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2012
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _DP501_H_
+#define _DP501_H_
+
+void dp501_powerup(u8 addr);
+void dp501_powerdown(u8 addr);
+int dp501_probe(unsigned screen, bool power);
+
+#endif
diff --git a/roms/u-boot/board/gdsys/common/fpga.c b/roms/u-boot/board/gdsys/common/fpga.c
new file mode 100644
index 000000000..5ba6613ed
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/fpga.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2013
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
+#include <common.h>
+#include <gdsys_fpga.h>
+
+#include <asm/io.h>
+
+int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
+{
+ out_le16(reg, data);
+
+ return 0;
+}
+
+int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data)
+{
+ *data = in_le16(reg);
+
+ return 0;
+}
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/roms/u-boot/board/gdsys/common/ihs_mdio.c b/roms/u-boot/board/gdsys/common/ihs_mdio.c
new file mode 100644
index 000000000..5f1215e9e
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/ihs_mdio.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ */
+
+#include <common.h>
+#include <linux/delay.h>
+
+#include <miiphy.h>
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+#include <gdsys_fpga.h>
+#else
+#include <fdtdec.h>
+#include <dm.h>
+#include <regmap.h>
+#endif
+
+#include "ihs_mdio.h"
+
+#ifndef CONFIG_GDSYS_LEGACY_DRIVERS
+enum {
+ REG_MDIO_CONTROL = 0x0,
+ REG_MDIO_ADDR_DATA = 0x2,
+ REG_MDIO_RX_DATA = 0x4,
+};
+
+static inline u16 read_reg(struct udevice *fpga, uint base, uint addr)
+{
+ struct regmap *map;
+ u8 *ptr;
+
+ regmap_init_mem(dev_ofnode(fpga), &map);
+ ptr = regmap_get_range(map, 0);
+
+ return in_le16((u16 *)(ptr + base + addr));
+}
+
+static inline void write_reg(struct udevice *fpga, uint base, uint addr,
+ u16 val)
+{
+ struct regmap *map;
+ u8 *ptr;
+
+ regmap_init_mem(dev_ofnode(fpga), &map);
+ ptr = regmap_get_range(map, 0);
+
+ out_le16((u16 *)(ptr + base + addr), val);
+}
+#endif
+
+static inline u16 read_control(struct ihs_mdio_info *info)
+{
+ u16 val;
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+ FPGA_GET_REG(info->fpga, mdio.control, &val);
+#else
+ val = read_reg(info->fpga, info->base, REG_MDIO_CONTROL);
+#endif
+ return val;
+}
+
+static inline void write_control(struct ihs_mdio_info *info, u16 val)
+{
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+ FPGA_SET_REG(info->fpga, mdio.control, val);
+#else
+ write_reg(info->fpga, info->base, REG_MDIO_CONTROL, val);
+#endif
+}
+
+static inline void write_addr_data(struct ihs_mdio_info *info, u16 val)
+{
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+ FPGA_SET_REG(info->fpga, mdio.address_data, val);
+#else
+ write_reg(info->fpga, info->base, REG_MDIO_ADDR_DATA, val);
+#endif
+}
+
+static inline u16 read_rx_data(struct ihs_mdio_info *info)
+{
+ u16 val;
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+ FPGA_GET_REG(info->fpga, mdio.rx_data, &val);
+#else
+ val = read_reg(info->fpga, info->base, REG_MDIO_RX_DATA);
+#endif
+ return val;
+}
+
+static int ihs_mdio_idle(struct mii_dev *bus)
+{
+ struct ihs_mdio_info *info = bus->priv;
+ u16 val;
+ unsigned int ctr = 0;
+
+ do {
+ val = read_control(info);
+ udelay(100);
+ if (ctr++ > 10)
+ return -1;
+ } while (!(val & (1 << 12)));
+
+ return 0;
+}
+
+static int ihs_mdio_reset(struct mii_dev *bus)
+{
+ ihs_mdio_idle(bus);
+
+ return 0;
+}
+
+static int ihs_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
+ int regnum)
+{
+ struct ihs_mdio_info *info = bus->priv;
+ u16 val;
+
+ ihs_mdio_idle(bus);
+
+ write_control(info,
+ ((addr & 0x1f) << 5) | (regnum & 0x1f) | (2 << 10));
+
+ /* wait for rx data available */
+ udelay(100);
+
+ val = read_rx_data(info);
+
+ return val;
+}
+
+static int ihs_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
+ int regnum, u16 value)
+{
+ struct ihs_mdio_info *info = bus->priv;
+
+ ihs_mdio_idle(bus);
+
+ write_addr_data(info, value);
+ write_control(info, ((addr & 0x1f) << 5) | (regnum & 0x1f) | (1 << 10));
+
+ return 0;
+}
+
+int ihs_mdio_init(struct ihs_mdio_info *info)
+{
+ struct mii_dev *bus = mdio_alloc();
+
+ if (!bus) {
+ printf("Failed to allocate FSL MDIO bus\n");
+ return -1;
+ }
+
+ bus->read = ihs_mdio_read;
+ bus->write = ihs_mdio_write;
+ bus->reset = ihs_mdio_reset;
+ strcpy(bus->name, info->name);
+
+ bus->priv = info;
+
+ return mdio_register(bus);
+}
diff --git a/roms/u-boot/board/gdsys/common/ihs_mdio.h b/roms/u-boot/board/gdsys/common/ihs_mdio.h
new file mode 100644
index 000000000..d0a4b0d7a
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/ihs_mdio.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ */
+
+#ifndef _IHS_MDIO_H_
+#define _IHS_MDIO_H_
+
+struct ihs_mdio_info {
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+ u32 fpga;
+#else
+ struct udevice *fpga;
+ int base;
+#endif
+ char *name;
+};
+
+int ihs_mdio_init(struct ihs_mdio_info *info);
+
+#endif
diff --git a/roms/u-boot/board/gdsys/common/ioep-fpga.c b/roms/u-boot/board/gdsys/common/ioep-fpga.c
new file mode 100644
index 000000000..7292d7ab5
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/ioep-fpga.c
@@ -0,0 +1,591 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
+#include <common.h>
+
+#include <gdsys_fpga.h>
+#include <linux/bitops.h>
+
+enum pcb_video_type {
+ PCB_DVI_SL,
+ PCB_DP_165MPIX,
+ PCB_DP_300MPIX,
+ PCB_HDMI,
+ PCB_DP_1_2,
+ PCB_HDMI_2_0,
+};
+
+enum pcb_transmission_type {
+ PCB_CAT_1G,
+ PCB_FIBER_3G,
+ PCB_CAT_10G,
+ PCB_FIBER_10G,
+};
+
+enum carrier_speed {
+ CARRIER_SPEED_1G,
+ CARRIER_SPEED_3G,
+ CARRIER_SPEED_2_5G = CARRIER_SPEED_3G,
+ CARRIER_SPEED_10G,
+};
+
+enum ram_config {
+ RAM_DDR2_32BIT_295MBPS,
+ RAM_DDR3_32BIT_590MBPS,
+ RAM_DDR3_48BIT_590MBPS,
+ RAM_DDR3_64BIT_1800MBPS,
+ RAM_DDR3_48BIT_1800MBPS,
+};
+
+enum sysclock {
+ SYSCLK_147456,
+};
+
+struct fpga_versions {
+ bool video_channel;
+ bool con_side;
+ enum pcb_video_type pcb_video_type;
+ enum pcb_transmission_type pcb_transmission_type;
+ unsigned int hw_version;
+};
+
+struct fpga_features {
+ u8 video_channels;
+ u8 carriers;
+ enum carrier_speed carrier_speed;
+ enum ram_config ram_config;
+ enum sysclock sysclock;
+
+ bool pcm_tx;
+ bool pcm_rx;
+ bool spdif_tx;
+ bool spdif_rx;
+ bool usb2;
+ bool rs232;
+ bool compression_type1;
+ bool compression_type2;
+ bool compression_type3;
+ bool interlace;
+ bool osd;
+ bool compression_pipes;
+};
+
+#ifdef CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM
+
+static int get_versions(unsigned int fpga, struct fpga_versions *versions)
+{
+ enum {
+ VERSIONS_FPGA_VIDEO_CHANNEL = BIT(12),
+ VERSIONS_FPGA_CON_SIDE = BIT(13),
+ VERSIONS_FPGA_SC = BIT(14),
+ VERSIONS_PCB_CON = BIT(9),
+ VERSIONS_PCB_SC = BIT(8),
+ VERSIONS_PCB_VIDEO_MASK = 0x3 << 6,
+ VERSIONS_PCB_VIDEO_DP_1_2 = 0x0 << 6,
+ VERSIONS_PCB_VIDEO_HDMI_2_0 = 0x1 << 6,
+ VERSIONS_PCB_TRANSMISSION_MASK = 0x3 << 4,
+ VERSIONS_PCB_TRANSMISSION_FIBER_10G = 0x0 << 4,
+ VERSIONS_PCB_TRANSMISSION_CAT_10G = 0x1 << 4,
+ VERSIONS_PCB_TRANSMISSION_FIBER_3G = 0x2 << 4,
+ VERSIONS_PCB_TRANSMISSION_CAT_1G = 0x3 << 4,
+ VERSIONS_HW_VER_MASK = 0xf << 0,
+ };
+ u16 raw_versions;
+
+ memset(versions, 0, sizeof(struct fpga_versions));
+
+ FPGA_GET_REG(fpga, versions, &raw_versions);
+
+ versions->video_channel = raw_versions & VERSIONS_FPGA_VIDEO_CHANNEL;
+ versions->con_side = raw_versions & VERSIONS_FPGA_CON_SIDE;
+
+ switch (raw_versions & VERSIONS_PCB_VIDEO_MASK) {
+ case VERSIONS_PCB_VIDEO_DP_1_2:
+ versions->pcb_video_type = PCB_DP_1_2;
+ break;
+
+ case VERSIONS_PCB_VIDEO_HDMI_2_0:
+ versions->pcb_video_type = PCB_HDMI_2_0;
+ break;
+ }
+
+ switch (raw_versions & VERSIONS_PCB_TRANSMISSION_MASK) {
+ case VERSIONS_PCB_TRANSMISSION_FIBER_10G:
+ versions->pcb_transmission_type = PCB_FIBER_10G;
+ break;
+
+ case VERSIONS_PCB_TRANSMISSION_CAT_10G:
+ versions->pcb_transmission_type = PCB_CAT_10G;
+ break;
+
+ case VERSIONS_PCB_TRANSMISSION_FIBER_3G:
+ versions->pcb_transmission_type = PCB_FIBER_3G;
+ break;
+
+ case VERSIONS_PCB_TRANSMISSION_CAT_1G:
+ versions->pcb_transmission_type = PCB_CAT_1G;
+ break;
+
+ }
+
+ versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
+
+ return 0;
+}
+
+static int get_features(unsigned int fpga, struct fpga_features *features)
+{
+ enum {
+ FEATURE_SPDIF_RX = BIT(15),
+ FEATURE_SPDIF_TX = BIT(14),
+ FEATURE_PCM_RX = BIT(13),
+ FEATURE_PCM_TX = BIT(12),
+ FEATURE_RAM_MASK = GENMASK(11, 8),
+ FEATURE_RAM_DDR2_32BIT_295MBPS = 0x0 << 8,
+ FEATURE_RAM_DDR3_32BIT_590MBPS = 0x1 << 8,
+ FEATURE_RAM_DDR3_48BIT_590MBPS = 0x2 << 8,
+ FEATURE_RAM_DDR3_64BIT_1800MBPS = 0x3 << 8,
+ FEATURE_RAM_DDR3_48BIT_1800MBPS = 0x4 << 8,
+ FEATURE_CARRIER_SPEED_MASK = GENMASK(7, 6),
+ FEATURE_CARRIER_SPEED_1G = 0x0 << 6,
+ FEATURE_CARRIER_SPEED_2_5G = 0x1 << 6,
+ FEATURE_CARRIER_SPEED_10G = 0x2 << 6,
+ FEATURE_CARRIERS_MASK = GENMASK(5, 4),
+ FEATURE_CARRIERS_0 = 0x0 << 4,
+ FEATURE_CARRIERS_1 = 0x1 << 4,
+ FEATURE_CARRIERS_2 = 0x2 << 4,
+ FEATURE_CARRIERS_4 = 0x3 << 4,
+ FEATURE_USB2 = BIT(3),
+ FEATURE_VIDEOCHANNELS_MASK = GENMASK(2, 0),
+ FEATURE_VIDEOCHANNELS_0 = 0x0 << 0,
+ FEATURE_VIDEOCHANNELS_1 = 0x1 << 0,
+ FEATURE_VIDEOCHANNELS_1_1 = 0x2 << 0,
+ FEATURE_VIDEOCHANNELS_2 = 0x3 << 0,
+ };
+
+ enum {
+ EXT_FEATURE_OSD = BIT(15),
+ EXT_FEATURE_ETHERNET = BIT(9),
+ EXT_FEATURE_INTERLACE = BIT(8),
+ EXT_FEATURE_RS232 = BIT(7),
+ EXT_FEATURE_COMPRESSION_PERF_MASK = GENMASK(6, 4),
+ EXT_FEATURE_COMPRESSION_PERF_1X = 0x0 << 4,
+ EXT_FEATURE_COMPRESSION_PERF_2X = 0x1 << 4,
+ EXT_FEATURE_COMPRESSION_PERF_4X = 0x2 << 4,
+ EXT_FEATURE_COMPRESSION_TYPE1 = BIT(0),
+ EXT_FEATURE_COMPRESSION_TYPE2 = BIT(1),
+ EXT_FEATURE_COMPRESSION_TYPE3 = BIT(2),
+ };
+
+ u16 raw_features;
+ u16 raw_extended_features;
+
+ memset(features, 0, sizeof(struct fpga_features));
+
+ FPGA_GET_REG(fpga, fpga_features, &raw_features);
+ FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
+
+ switch (raw_features & FEATURE_VIDEOCHANNELS_MASK) {
+ case FEATURE_VIDEOCHANNELS_0:
+ features->video_channels = 0;
+ break;
+
+ case FEATURE_VIDEOCHANNELS_1:
+ features->video_channels = 1;
+ break;
+
+ case FEATURE_VIDEOCHANNELS_1_1:
+ case FEATURE_VIDEOCHANNELS_2:
+ features->video_channels = 2;
+ break;
+ };
+
+ switch (raw_features & FEATURE_CARRIERS_MASK) {
+ case FEATURE_CARRIERS_0:
+ features->carriers = 0;
+ break;
+
+ case FEATURE_CARRIERS_1:
+ features->carriers = 1;
+ break;
+
+ case FEATURE_CARRIERS_2:
+ features->carriers = 2;
+ break;
+
+ case FEATURE_CARRIERS_4:
+ features->carriers = 4;
+ break;
+ }
+
+ switch (raw_features & FEATURE_CARRIER_SPEED_MASK) {
+ case FEATURE_CARRIER_SPEED_1G:
+ features->carrier_speed = CARRIER_SPEED_1G;
+ break;
+ case FEATURE_CARRIER_SPEED_2_5G:
+ features->carrier_speed = CARRIER_SPEED_2_5G;
+ break;
+ case FEATURE_CARRIER_SPEED_10G:
+ features->carrier_speed = CARRIER_SPEED_10G;
+ break;
+ }
+
+ switch (raw_features & FEATURE_RAM_MASK) {
+ case FEATURE_RAM_DDR2_32BIT_295MBPS:
+ features->ram_config = RAM_DDR2_32BIT_295MBPS;
+ break;
+
+ case FEATURE_RAM_DDR3_32BIT_590MBPS:
+ features->ram_config = RAM_DDR3_32BIT_590MBPS;
+ break;
+
+ case FEATURE_RAM_DDR3_48BIT_590MBPS:
+ features->ram_config = RAM_DDR3_48BIT_590MBPS;
+ break;
+
+ case FEATURE_RAM_DDR3_64BIT_1800MBPS:
+ features->ram_config = RAM_DDR3_64BIT_1800MBPS;
+ break;
+
+ case FEATURE_RAM_DDR3_48BIT_1800MBPS:
+ features->ram_config = RAM_DDR3_48BIT_1800MBPS;
+ break;
+ }
+
+ features->pcm_tx = raw_features & FEATURE_PCM_TX;
+ features->pcm_rx = raw_features & FEATURE_PCM_RX;
+ features->spdif_tx = raw_features & FEATURE_SPDIF_TX;
+ features->spdif_rx = raw_features & FEATURE_SPDIF_RX;
+ features->usb2 = raw_features & FEATURE_USB2;
+ features->rs232 = raw_extended_features & EXT_FEATURE_RS232;
+ features->compression_type1 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE1;
+ features->compression_type2 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE2;
+ features->compression_type3 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE3;
+ features->interlace = raw_extended_features & EXT_FEATURE_INTERLACE;
+ features->osd = raw_extended_features & EXT_FEATURE_OSD;
+ features->compression_pipes = raw_extended_features & EXT_FEATURE_COMPRESSION_PERF_MASK;
+
+ return 0;
+}
+
+#else
+
+static int get_versions(unsigned int fpga, struct fpga_versions *versions)
+{
+ enum {
+ /* HW version encoding is a mess, leave it for the moment */
+ VERSIONS_HW_VER_MASK = 0xf << 0,
+ VERSIONS_PIX_CLOCK_GEN_IDT8N3QV01 = BIT(4),
+ VERSIONS_SFP = BIT(5),
+ VERSIONS_VIDEO_MASK = 0x7 << 6,
+ VERSIONS_VIDEO_DVI = 0x0 << 6,
+ VERSIONS_VIDEO_DP_165 = 0x1 << 6,
+ VERSIONS_VIDEO_DP_300 = 0x2 << 6,
+ VERSIONS_VIDEO_HDMI = 0x3 << 6,
+ VERSIONS_UT_MASK = 0xf << 12,
+ VERSIONS_UT_MAIN_SERVER = 0x0 << 12,
+ VERSIONS_UT_MAIN_USER = 0x1 << 12,
+ VERSIONS_UT_VIDEO_SERVER = 0x2 << 12,
+ VERSIONS_UT_VIDEO_USER = 0x3 << 12,
+ };
+ u16 raw_versions;
+
+ memset(versions, 0, sizeof(struct fpga_versions));
+
+ FPGA_GET_REG(fpga, versions, &raw_versions);
+
+ switch (raw_versions & VERSIONS_UT_MASK) {
+ case VERSIONS_UT_MAIN_SERVER:
+ versions->video_channel = false;
+ versions->con_side = false;
+ break;
+
+ case VERSIONS_UT_MAIN_USER:
+ versions->video_channel = false;
+ versions->con_side = true;
+ break;
+
+ case VERSIONS_UT_VIDEO_SERVER:
+ versions->video_channel = true;
+ versions->con_side = false;
+ break;
+
+ case VERSIONS_UT_VIDEO_USER:
+ versions->video_channel = true;
+ versions->con_side = true;
+ break;
+
+ }
+
+ switch (raw_versions & VERSIONS_VIDEO_MASK) {
+ case VERSIONS_VIDEO_DVI:
+ versions->pcb_video_type = PCB_DVI_SL;
+ break;
+
+ case VERSIONS_VIDEO_DP_165:
+ versions->pcb_video_type = PCB_DP_165MPIX;
+ break;
+
+ case VERSIONS_VIDEO_DP_300:
+ versions->pcb_video_type = PCB_DP_300MPIX;
+ break;
+
+ case VERSIONS_VIDEO_HDMI:
+ versions->pcb_video_type = PCB_HDMI;
+ break;
+ }
+
+ versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
+
+ if (raw_versions & VERSIONS_SFP)
+ versions->pcb_transmission_type = PCB_FIBER_3G;
+ else
+ versions->pcb_transmission_type = PCB_CAT_1G;
+
+ return 0;
+}
+
+static int get_features(unsigned int fpga, struct fpga_features *features)
+{
+ enum {
+ FEATURE_CARRIER_SPEED_2_5 = BIT(4),
+ FEATURE_RAM_MASK = 0x7 << 5,
+ FEATURE_RAM_DDR2_32BIT = 0x0 << 5,
+ FEATURE_RAM_DDR3_32BIT = 0x1 << 5,
+ FEATURE_RAM_DDR3_48BIT = 0x2 << 5,
+ FEATURE_PCM_AUDIO_TX = BIT(9),
+ FEATURE_PCM_AUDIO_RX = BIT(10),
+ FEATURE_OSD = BIT(11),
+ FEATURE_USB20 = BIT(12),
+ FEATURE_COMPRESSION_MASK = 7 << 13,
+ FEATURE_COMPRESSION_TYPE1 = 0x1 << 13,
+ FEATURE_COMPRESSION_TYPE1_TYPE2 = 0x3 << 13,
+ FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3 = 0x7 << 13,
+ };
+
+ enum {
+ EXTENDED_FEATURE_SPDIF_AUDIO_TX = BIT(0),
+ EXTENDED_FEATURE_SPDIF_AUDIO_RX = BIT(1),
+ EXTENDED_FEATURE_RS232 = BIT(2),
+ EXTENDED_FEATURE_COMPRESSION_PIPES = BIT(3),
+ EXTENDED_FEATURE_INTERLACE = BIT(4),
+ };
+
+ u16 raw_features;
+#ifdef GDSYS_LEGACY_DRIVERS
+ u16 raw_extended_features;
+#endif
+
+ memset(features, 0, sizeof(struct fpga_features));
+
+ FPGA_GET_REG(fpga, fpga_features, &raw_features);
+#ifdef GDSYS_LEGACY_DRIVERS
+ FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
+#endif
+
+ features->video_channels = raw_features & 0x3;
+ features->carriers = (raw_features >> 2) & 0x3;
+
+ features->carrier_speed = (raw_features & FEATURE_CARRIER_SPEED_2_5)
+ ? CARRIER_SPEED_2_5G : CARRIER_SPEED_1G;
+
+ switch (raw_features & FEATURE_RAM_MASK) {
+ case FEATURE_RAM_DDR2_32BIT:
+ features->ram_config = RAM_DDR2_32BIT_295MBPS;
+ break;
+
+ case FEATURE_RAM_DDR3_32BIT:
+ features->ram_config = RAM_DDR3_32BIT_590MBPS;
+ break;
+
+ case FEATURE_RAM_DDR3_48BIT:
+ features->ram_config = RAM_DDR3_48BIT_590MBPS;
+ break;
+ }
+
+ features->pcm_tx = raw_features & FEATURE_PCM_AUDIO_TX;
+ features->pcm_rx = raw_features & FEATURE_PCM_AUDIO_RX;
+#ifdef GDSYS_LEGACY_DRIVERS
+ features->spdif_tx = raw_extended_features & EXTENDED_FEATURE_SPDIF_AUDIO_TX;
+ features->spdif_rx = raw_extended_features & EXTENDED_FEATURE_SPDIF_AUDIO_RX;
+#endif
+
+ features->usb2 = raw_features & FEATURE_USB20;
+#ifdef GDSYS_LEGACY_DRIVERS
+ features->rs232 = raw_extended_features & EXTENDED_FEATURE_RS232;
+#endif
+
+ features->compression_type1 = false;
+ features->compression_type2 = false;
+ features->compression_type3 = false;
+ switch (raw_features & FEATURE_COMPRESSION_MASK) {
+ case FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3:
+ features->compression_type3 = true;
+ case FEATURE_COMPRESSION_TYPE1_TYPE2:
+ features->compression_type2 = true;
+ case FEATURE_COMPRESSION_TYPE1:
+ features->compression_type1 = true;
+ break;
+ }
+
+#ifdef GDSYS_LEGACY_DRIVERS
+ features->interlace = raw_extended_features & EXTENDED_FEATURE_INTERLACE;
+#endif
+ features->osd = raw_features & FEATURE_OSD;
+#ifdef GDSYS_LEGACY_DRIVERS
+ features->compression_pipes = raw_extended_features & EXTENDED_FEATURE_COMPRESSION_PIPES;
+#endif
+
+ return 0;
+}
+
+#include <linux/bitops.h>
+#endif
+
+bool ioep_fpga_has_osd(unsigned int fpga)
+{
+ struct fpga_features features;
+
+ get_features(fpga, &features);
+
+ return features.osd;
+}
+
+void ioep_fpga_print_info(unsigned int fpga)
+{
+ u16 fpga_version;
+ struct fpga_versions versions;
+ struct fpga_features features;
+
+ FPGA_GET_REG(fpga, fpga_version, &fpga_version);
+ get_versions(fpga, &versions);
+ get_features(fpga, &features);
+
+ if (versions.video_channel)
+ printf("Videochannel");
+ else
+ printf("Mainchannel");
+
+ if (versions.con_side)
+ printf(" User");
+ else
+ printf(" Server");
+
+// FIXME
+#if 0
+ if (versions & (1<<4))
+ printf(" UC");
+#endif
+
+ switch(versions.pcb_transmission_type) {
+ case PCB_CAT_1G:
+ case PCB_CAT_10G:
+ printf(" CAT");
+ break;
+ case PCB_FIBER_3G:
+ case PCB_FIBER_10G:
+ printf(" Fiber");
+ break;
+ };
+
+ switch (versions.pcb_video_type) {
+ case PCB_DVI_SL:
+ printf(" DVI,");
+ break;
+ case PCB_DP_165MPIX:
+ printf(" DP 165MPix/s,");
+ break;
+ case PCB_DP_300MPIX:
+ printf(" DP 300MPix/s,");
+ break;
+ case PCB_HDMI:
+ printf(" HDMI,");
+ break;
+ case PCB_DP_1_2:
+ printf(" DP 1.2,");
+ break;
+ case PCB_HDMI_2_0:
+ printf(" HDMI 2.0,");
+ break;
+ }
+
+ printf(" FPGA V %d.%02d\n features: ",
+ fpga_version / 100, fpga_version % 100);
+
+ if (!features.compression_type1 &&
+ !features.compression_type2 &&
+ !features.compression_type3)
+ printf("no compression, ");
+
+ if (features.compression_type1)
+ printf("type1, ");
+
+ if (features.compression_type2)
+ printf("type2, ");
+
+ if (features.compression_type3)
+ printf("type3, ");
+
+ printf("%sosd", features.osd ? "" : "no ");
+
+ if (features.pcm_rx && features.pcm_tx)
+ printf(", pcm rx+tx");
+ else if(features.pcm_rx)
+ printf(", pcm rx");
+ else if(features.pcm_tx)
+ printf(", pcm tx");
+
+ if (features.spdif_rx && features.spdif_tx)
+ printf(", spdif rx+tx");
+ else if(features.spdif_rx)
+ printf(", spdif rx");
+ else if(features.spdif_tx)
+ printf(", spdif tx");
+
+ puts(",\n ");
+
+ switch (features.sysclock) {
+ case SYSCLK_147456:
+ printf("clock 147.456 MHz");
+ break;
+ }
+
+ switch (features.ram_config) {
+ case RAM_DDR2_32BIT_295MBPS:
+ printf(", RAM 32 bit DDR2");
+ break;
+ case RAM_DDR3_32BIT_590MBPS:
+ printf(", RAM 32 bit DDR3");
+ break;
+ case RAM_DDR3_48BIT_590MBPS:
+ case RAM_DDR3_48BIT_1800MBPS:
+ printf(", RAM 48 bit DDR3");
+ break;
+ case RAM_DDR3_64BIT_1800MBPS:
+ printf(", RAM 64 bit DDR3");
+ break;
+ }
+
+ printf(", %d carrier(s)", features.carriers);
+
+ switch(features.carrier_speed) {
+ case CARRIER_SPEED_1G:
+ printf(", 1Gbit/s");
+ break;
+ case CARRIER_SPEED_3G:
+ printf(", 3Gbit/s");
+ break;
+ case CARRIER_SPEED_10G:
+ printf(", 10Gbit/s");
+ break;
+ }
+
+ printf(", %d video channel(s)\n", features.video_channels);
+}
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/roms/u-boot/board/gdsys/common/ioep-fpga.h b/roms/u-boot/board/gdsys/common/ioep-fpga.h
new file mode 100644
index 000000000..53570b936
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/ioep-fpga.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ */
+
+#ifndef _IOEP_FPGA_H_
+#define _IOEP_FPGA_H_
+
+void ioep_fpga_print_info(unsigned int fpga);
+bool ioep_fpga_has_osd(unsigned int fpga);
+
+#endif
diff --git a/roms/u-boot/board/gdsys/common/osd.c b/roms/u-boot/board/gdsys/common/osd.c
new file mode 100644
index 000000000..679f8f301
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/osd.c
@@ -0,0 +1,506 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
+#include <common.h>
+#include <command.h>
+#include <i2c.h>
+#include <malloc.h>
+#include <linux/stringify.h>
+
+#include "ch7301.h"
+#include "dp501.h"
+#include <gdsys_fpga.h>
+
+#define ICS8N3QV01_I2C_ADDR 0x6E
+#define ICS8N3QV01_FREF 114285000
+#define ICS8N3QV01_FREF_LL 114285000LL
+#define ICS8N3QV01_F_DEFAULT_0 156250000LL
+#define ICS8N3QV01_F_DEFAULT_1 125000000LL
+#define ICS8N3QV01_F_DEFAULT_2 100000000LL
+#define ICS8N3QV01_F_DEFAULT_3 25175000LL
+
+#define SIL1178_MASTER_I2C_ADDRESS 0x38
+#define SIL1178_SLAVE_I2C_ADDRESS 0x39
+
+#define PIXCLK_640_480_60 25180000
+#define MAX_X_CHARS 53
+#define MAX_Y_CHARS 26
+
+#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 osd_screen_mask = 0;
+
+#ifdef CONFIG_SYS_ICS8N3QV01_I2C
+int ics8n3qv01_i2c[] = CONFIG_SYS_ICS8N3QV01_I2C;
+#endif
+
+#ifdef CONFIG_SYS_SIL1178_I2C
+int sil1178_i2c[] = CONFIG_SYS_SIL1178_I2C;
+#endif
+
+#ifdef CONFIG_SYS_MPC92469AC
+static void mpc92469ac_calc_parameters(unsigned int fout,
+ unsigned int *post_div, unsigned int *feedback_div)
+{
+ unsigned int n = *post_div;
+ unsigned int m = *feedback_div;
+ unsigned int a;
+ unsigned int b = 14745600 / 16;
+
+ if (fout < 50169600)
+ n = 8;
+ else if (fout < 100339199)
+ n = 4;
+ else if (fout < 200678399)
+ n = 2;
+ else
+ n = 1;
+
+ a = fout * n + (b / 2); /* add b/2 for proper rounding */
+
+ m = a / b;
+
+ *post_div = n;
+ *feedback_div = m;
+}
+
+static void mpc92469ac_set(unsigned screen, unsigned int fout)
+{
+ unsigned int n;
+ unsigned int m;
+ unsigned int bitval = 0;
+ mpc92469ac_calc_parameters(fout, &n, &m);
+
+ switch (n) {
+ case 1:
+ bitval = 0x00;
+ break;
+ case 2:
+ bitval = 0x01;
+ break;
+ case 4:
+ bitval = 0x02;
+ break;
+ case 8:
+ bitval = 0x03;
+ break;
+ }
+
+ FPGA_SET_REG(screen, mpc3w_control, (bitval << 9) | m);
+}
+#endif
+
+#ifdef CONFIG_SYS_ICS8N3QV01_I2C
+
+static unsigned int ics8n3qv01_get_fout_calc(unsigned index)
+{
+ unsigned long long n;
+ unsigned long long mint;
+ unsigned long long mfrac;
+ u8 reg_a, reg_b, reg_c, reg_d, reg_f;
+ unsigned long long fout_calc;
+
+ if (index > 3)
+ return 0;
+
+ reg_a = i2c_reg_read(ICS8N3QV01_I2C_ADDR, 0 + index);
+ reg_b = i2c_reg_read(ICS8N3QV01_I2C_ADDR, 4 + index);
+ reg_c = i2c_reg_read(ICS8N3QV01_I2C_ADDR, 8 + index);
+ reg_d = i2c_reg_read(ICS8N3QV01_I2C_ADDR, 12 + index);
+ reg_f = i2c_reg_read(ICS8N3QV01_I2C_ADDR, 20 + index);
+
+ mint = ((reg_a >> 1) & 0x1f) | (reg_f & 0x20);
+ mfrac = ((reg_a & 0x01) << 17) | (reg_b << 9) | (reg_c << 1)
+ | (reg_d >> 7);
+ n = reg_d & 0x7f;
+
+ fout_calc = (mint * ICS8N3QV01_FREF_LL
+ + mfrac * ICS8N3QV01_FREF_LL / 262144LL
+ + ICS8N3QV01_FREF_LL / 524288LL
+ + n / 2)
+ / n
+ * 1000000
+ / (1000000 - 100);
+
+ return fout_calc;
+}
+
+
+static void ics8n3qv01_calc_parameters(unsigned int fout,
+ unsigned int *_mint, unsigned int *_mfrac,
+ unsigned int *_n)
+{
+ unsigned int n;
+ unsigned int foutiic;
+ unsigned int fvcoiic;
+ unsigned int mint;
+ unsigned long long mfrac;
+
+ n = (2215000000U + fout / 2) / fout;
+ if ((n & 1) && (n > 5))
+ n -= 1;
+
+ foutiic = fout - (fout / 10000);
+ fvcoiic = foutiic * n;
+
+ mint = fvcoiic / 114285000;
+ if ((mint < 17) || (mint > 63))
+ printf("ics8n3qv01_calc_parameters: cannot determine mint\n");
+
+ mfrac = ((unsigned long long)fvcoiic % 114285000LL) * 262144LL
+ / 114285000LL;
+
+ *_mint = mint;
+ *_mfrac = mfrac;
+ *_n = n;
+}
+
+static void ics8n3qv01_set(unsigned int fout)
+{
+ unsigned int n;
+ unsigned int mint;
+ unsigned int mfrac;
+ unsigned int fout_calc;
+ unsigned long long fout_prog;
+ long long off_ppm;
+ u8 reg0, reg4, reg8, reg12, reg18, reg20;
+
+ fout_calc = ics8n3qv01_get_fout_calc(1);
+ off_ppm = (fout_calc - ICS8N3QV01_F_DEFAULT_1) * 1000000
+ / ICS8N3QV01_F_DEFAULT_1;
+ printf(" PLL is off by %lld ppm\n", off_ppm);
+ fout_prog = (unsigned long long)fout * (unsigned long long)fout_calc
+ / ICS8N3QV01_F_DEFAULT_1;
+ ics8n3qv01_calc_parameters(fout_prog, &mint, &mfrac, &n);
+
+ reg0 = i2c_reg_read(ICS8N3QV01_I2C_ADDR, 0) & 0xc0;
+ reg0 |= (mint & 0x1f) << 1;
+ reg0 |= (mfrac >> 17) & 0x01;
+ i2c_reg_write(ICS8N3QV01_I2C_ADDR, 0, reg0);
+
+ reg4 = mfrac >> 9;
+ i2c_reg_write(ICS8N3QV01_I2C_ADDR, 4, reg4);
+
+ reg8 = mfrac >> 1;
+ i2c_reg_write(ICS8N3QV01_I2C_ADDR, 8, reg8);
+
+ reg12 = mfrac << 7;
+ reg12 |= n & 0x7f;
+ i2c_reg_write(ICS8N3QV01_I2C_ADDR, 12, reg12);
+
+ reg18 = i2c_reg_read(ICS8N3QV01_I2C_ADDR, 18) & 0x03;
+ reg18 |= 0x20;
+ i2c_reg_write(ICS8N3QV01_I2C_ADDR, 18, reg18);
+
+ reg20 = i2c_reg_read(ICS8N3QV01_I2C_ADDR, 20) & 0x1f;
+ reg20 |= mint & (1 << 5);
+ i2c_reg_write(ICS8N3QV01_I2C_ADDR, 20, reg20);
+}
+#endif
+
+static int osd_write_videomem(unsigned screen, unsigned offset,
+ u16 *data, size_t charcount)
+{
+ unsigned int k;
+
+ for (k = 0; k < charcount; ++k) {
+ if (offset + k >= bufsize)
+ return -1;
+#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;
+}
+
+static int osd_print(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ unsigned screen;
+
+ if (argc < 5) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
+ unsigned x;
+ unsigned y;
+ unsigned charcount;
+ unsigned len;
+ u8 color;
+ unsigned int k;
+ char *text;
+ int res;
+
+ if (!(osd_screen_mask & (1 << screen)))
+ continue;
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+ color = simple_strtoul(argv[3], NULL, 16);
+ text = argv[4];
+ charcount = strlen(text);
+ len = (charcount > bufsize) ? bufsize : charcount;
+
+ for (k = 0; k < len; ++k)
+ buf[k] = (text[k] << 8) | color;
+
+ res = osd_write_videomem(screen, y * base_width + x, buf, len);
+ if (res < 0)
+ return res;
+
+ OSD_SET_REG(screen, control, 0x0049);
+ }
+
+ return 0;
+}
+
+int osd_probe(unsigned screen)
+{
+ u16 version;
+ u16 features;
+ int old_bus = i2c_get_bus_num();
+ bool pixclock_present = false;
+ bool output_driver_present = false;
+
+ OSD_GET_REG(0, version, &version);
+ OSD_GET_REG(0, features, &features);
+
+ base_width = ((features & 0x3f00) >> 8) + 1;
+ base_height = (features & 0x001f) + 1;
+ bufsize = base_width * base_height;
+ buf = malloc(sizeof(u16) * bufsize);
+ 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);
+#endif
+ /* setup pixclock */
+
+#ifdef CONFIG_SYS_MPC92469AC
+ pixclock_present = true;
+ mpc92469ac_set(screen, PIXCLK_640_480_60);
+#endif
+
+#ifdef CONFIG_SYS_ICS8N3QV01_I2C
+ i2c_set_bus_num(ics8n3qv01_i2c[screen]);
+ if (!i2c_probe(ICS8N3QV01_I2C_ADDR)) {
+ ics8n3qv01_set(PIXCLK_640_480_60);
+ pixclock_present = true;
+ }
+#endif
+
+ if (!pixclock_present)
+ printf(" no pixelclock found\n");
+
+ /* setup output driver */
+
+#ifdef CONFIG_SYS_CH7301_I2C
+ if (!ch7301_probe(screen, true))
+ output_driver_present = true;
+#endif
+
+#ifdef CONFIG_SYS_SIL1178_I2C
+ i2c_set_bus_num(sil1178_i2c[screen]);
+ if (!i2c_probe(SIL1178_SLAVE_I2C_ADDRESS)) {
+ if (i2c_reg_read(SIL1178_SLAVE_I2C_ADDRESS, 0x02) == 0x06) {
+ /*
+ * magic initialization sequence,
+ * adapted from datasheet
+ */
+ i2c_reg_write(SIL1178_SLAVE_I2C_ADDRESS, 0x08, 0x36);
+ i2c_reg_write(SIL1178_MASTER_I2C_ADDRESS, 0x0f, 0x44);
+ i2c_reg_write(SIL1178_MASTER_I2C_ADDRESS, 0x0f, 0x4c);
+ i2c_reg_write(SIL1178_MASTER_I2C_ADDRESS, 0x0e, 0x10);
+ i2c_reg_write(SIL1178_MASTER_I2C_ADDRESS, 0x0a, 0x80);
+ i2c_reg_write(SIL1178_MASTER_I2C_ADDRESS, 0x09, 0x30);
+ i2c_reg_write(SIL1178_MASTER_I2C_ADDRESS, 0x0c, 0x89);
+ i2c_reg_write(SIL1178_MASTER_I2C_ADDRESS, 0x0d, 0x60);
+ i2c_reg_write(SIL1178_MASTER_I2C_ADDRESS, 0x08, 0x36);
+ i2c_reg_write(SIL1178_MASTER_I2C_ADDRESS, 0x08, 0x37);
+ output_driver_present = true;
+ }
+ }
+#endif
+
+#ifdef CONFIG_SYS_DP501_I2C
+ if (!dp501_probe(screen, true))
+ output_driver_present = true;
+#endif
+
+ if (!output_driver_present)
+ printf(" no output driver found\n");
+
+ 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 (pixclock_present && output_driver_present)
+ osd_screen_mask |= 1 << screen;
+
+ i2c_set_bus_num(old_bus);
+
+ return 0;
+}
+
+int osd_write(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ unsigned screen;
+
+ if ((argc < 4) || (strlen(argv[3]) % 4)) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
+ unsigned x;
+ unsigned y;
+ unsigned k;
+ u16 buffer[base_width];
+ char *rp;
+ u16 *wp = buffer;
+ unsigned count = (argc > 4) ?
+ simple_strtoul(argv[4], NULL, 16) : 1;
+
+ if (!(osd_screen_mask & (1 << screen)))
+ continue;
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+ rp = argv[3];
+
+
+ while (*rp) {
+ char substr[5];
+
+ memcpy(substr, rp, 4);
+ substr[4] = 0;
+ *wp = simple_strtoul(substr, NULL, 16);
+
+ rp += 4;
+ wp++;
+ if (wp - buffer > base_width)
+ break;
+ }
+
+ for (k = 0; k < count; ++k) {
+ unsigned offset =
+ y * base_width + x + k * (wp - buffer);
+ osd_write_videomem(screen, offset, buffer,
+ wp - buffer);
+ }
+
+ OSD_SET_REG(screen, control, 0x0049);
+ }
+
+ return 0;
+}
+
+int osd_size(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ unsigned screen;
+ unsigned x;
+ unsigned y;
+
+ if (argc < 3) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+
+ if (!x || (x > 64) || (x > MAX_X_CHARS) ||
+ !y || (y > 32) || (y > MAX_Y_CHARS)) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
+ if (!(osd_screen_mask & (1 << screen)))
+ continue;
+
+ OSD_SET_REG(screen, xy_size, ((x - 1) << 8) | (y - 1));
+ OSD_SET_REG(screen, x_pos, 32767 * (640 - 12 * x) / 65535);
+ OSD_SET_REG(screen, y_pos, 32767 * (480 - 18 * y) / 65535);
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ osdw, 5, 0, osd_write,
+ "write 16-bit hex encoded buffer to osd memory",
+ "pos_x pos_y buffer count\n"
+);
+
+U_BOOT_CMD(
+ osdp, 5, 0, osd_print,
+ "write ASCII buffer to osd memory",
+ "pos_x pos_y color text\n"
+);
+
+U_BOOT_CMD(
+ osdsize, 3, 0, osd_size,
+ "set OSD XY size in characters",
+ "size_x(max. " __stringify(MAX_X_CHARS)
+ ") size_y(max. " __stringify(MAX_Y_CHARS) ")\n"
+);
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/roms/u-boot/board/gdsys/common/osd.h b/roms/u-boot/board/gdsys/common/osd.h
new file mode 100644
index 000000000..4e8e53ab4
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/osd.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2010
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ */
+
+#ifndef _OSD_H_
+#define _OSD_H_
+
+int ch7301_probe(unsigned screen, bool power);
+int osd_probe(unsigned screen);
+
+#endif
diff --git a/roms/u-boot/board/gdsys/common/osd_cmd.c b/roms/u-boot/board/gdsys/common/osd_cmd.c
new file mode 100644
index 000000000..fe6249794
--- /dev/null
+++ b/roms/u-boot/board/gdsys/common/osd_cmd.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2017
+ * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
+ *
+ * based on the gdsys osd driver, which is
+ *
+ * (C) Copyright 2010
+ * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <hexdump.h>
+#include <video_osd.h>
+#include <malloc.h>
+
+static int do_osd_write(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+ uint x, y;
+ uint count;
+ char *hexstr;
+ u8 *buffer;
+ size_t buflen;
+ int res;
+
+ if (argc < 4 || (strlen(argv[3])) % 2)
+ return CMD_RET_USAGE;
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+ hexstr = argv[3];
+ count = (argc > 4) ? simple_strtoul(argv[4], NULL, 16) : 1;
+
+ buflen = strlen(hexstr) / 2;
+
+ buffer = malloc(buflen);
+ if (!buffer) {
+ puts("Memory allocation failure\n");
+ return CMD_RET_FAILURE;
+ }
+
+ res = hex2bin(buffer, hexstr, buflen);
+ if (res) {
+ free(buffer);
+ puts("Hexadecimal input contained invalid characters\n");
+ return CMD_RET_FAILURE;
+ }
+
+ for (uclass_first_device(UCLASS_VIDEO_OSD, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ int res;
+
+ res = video_osd_set_mem(dev, x, y, buffer, buflen, count);
+ if (res) {
+ free(buffer);
+ printf("Could not write to video mem on osd %s\n",
+ dev->name);
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ free(buffer);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_osd_print(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+ uint x, y;
+ u8 color;
+ char *text;
+
+ if (argc < 5)
+ return CMD_RET_USAGE;
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+ color = simple_strtoul(argv[3], NULL, 16);
+ text = argv[4];
+
+ for (uclass_first_device(UCLASS_VIDEO_OSD, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ int res;
+
+ res = video_osd_print(dev, x, y, color, text);
+ if (res) {
+ printf("Could not print string to osd %s\n", dev->name);
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_osd_size(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+ uint x, y;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+
+ for (uclass_first_device(UCLASS_VIDEO_OSD, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ int res;
+
+ res = video_osd_set_size(dev, x, y);
+
+ if (res) {
+ printf("Could not set size on osd %s\n", dev->name);
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+ osdw, 5, 0, do_osd_write,
+ "write 16-bit hex encoded buffer to osd memory",
+ "osdw [pos_x] [pos_y] [buffer] [count] - write 8-bit hex encoded buffer to osd memory\n"
+);
+
+U_BOOT_CMD(
+ osdp, 5, 0, do_osd_print,
+ "write ASCII buffer to osd memory",
+ "osdp [pos_x] [pos_y] [color] [text] - write ASCII buffer to osd memory\n"
+);
+
+U_BOOT_CMD(
+ osdsize, 3, 0, do_osd_size,
+ "set OSD XY size in characters",
+ "osdsize [size_x] [size_y] - set OSD XY size in characters\n"
+);