
Make the ioloop command DM compatible, while keeping the old functionality for not-yet-converted boards.
Signed-off-by: Mario Six mario.six@gdsys.cc ---
board/gdsys/common/cmd_ioloop.c | 241 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 234 insertions(+), 7 deletions(-)
diff --git a/board/gdsys/common/cmd_ioloop.c b/board/gdsys/common/cmd_ioloop.c index 2ea8bc8670..b767c4d174 100644 --- a/board/gdsys/common/cmd_ioloop.c +++ b/board/gdsys/common/cmd_ioloop.c @@ -11,12 +11,27 @@
#include <gdsys_fpga.h>
+#ifndef CONFIG_GDSYS_LEGACY_DRIVERS +#include <dm.h> +#include <gdsys_ioep.h> +#include <gdsys_soc.h> +#include <ihs_fpga.h> +#endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */ + enum status_print_type { STATUS_LOUD = 0, STATUS_SILENT = 1, };
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), +}; + +#ifdef CONFIG_GDSYS_LEGACY_DRIVERS +enum { STATE_TX_PACKET_BUILDING = BIT(0), STATE_TX_TRANSMITTING = BIT(1), STATE_TX_BUFFER_FULL = BIT(2), @@ -39,13 +54,6 @@ enum { CTRL_FLUSH_TRANSMIT_BUFFER = 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), -}; - struct io_generic_packet { u16 target_address; u16 source_address; @@ -53,11 +61,16 @@ struct io_generic_packet { 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 | @@ -90,7 +103,15 @@ static void io_check_status(uint fpga, u16 status, enum status_print_type type) if (status & STATE_TX_ERR) printf("TX_ERR\n"); } +#else +static void io_check_status(struct udevice *dev, enum status_print_type type) +{ + if (ioep_reset_status(dev, type == STATUS_LOUD)) + err_ctr++; +} +#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS static void io_send(uint fpga, uint size) { uint k; @@ -112,7 +133,27 @@ static void io_send(uint fpga, uint size)
tx_ctr++; } +#else +static void io_send(struct udevice *dev, uint size) +{ + uint k; + u16 buffer[128]; + struct io_generic_packet header = { + .source_address = 1, + .packet_type = 1, + .packet_length = size, + }; + + for (k = 0; k < size; ++k) + buffer[k] = k; + + ioep_send(dev, &header, buffer); + + tx_ctr++; +} +#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS static void io_receive(uint fpga) { u16 rx_tx_status; @@ -130,7 +171,18 @@ static void io_receive(uint fpga) FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status); } } +#else +static void io_receive(struct udevice *dev) +{ + u16 buffer[128]; + struct io_generic_packet header;
+ if (!ioep_receive(dev, &header, buffer)) + rx_ctr++; +} +#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */ + +#ifdef CONFIG_GDSYS_LEGACY_DRIVERS static void io_reflect(uint fpga) { u16 buffer[128]; @@ -160,7 +212,20 @@ static void io_reflect(uint fpga)
tx_ctr++; } +#else +static void io_reflect(struct udevice *dev) +{ + u16 buffer[128]; + struct io_generic_packet header; + + if (ioep_receive(dev, &header, buffer)) + return; + + ioep_send(dev, &header, buffer); +} +#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS /* * FPGA io-endpoint reflector * @@ -217,9 +282,54 @@ int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 0; } +#else +/* + * FPGA io-endpoint reflector + * + * Syntax: + * ioreflect {reportrate} + */ +int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev); + uint rate = 0; + unsigned long long last_seen = 0; + + /* Enable receive path */ + ioep_enable_receive(dev); + + /* Set device address to dummy 1*/ + ioep_set_address(dev, 1); + + rx_ctr = 0; tx_ctr = 0; err_ctr = 0; + + while (1) { + uint top_int; + + fpga_get_reg(pplat->fpga, "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 * @@ -285,7 +395,105 @@ int do_ioloop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 0; } +#else +/* + * FPGA io-endpoint looptest + * + * Syntax: + * ioloop {size} {rate} + */ +int do_ioloop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + uint size; + uint rate = 0; + struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev); + + 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 */ + ioep_enable_receive(dev); + + /* Set device address to dummy 1*/ + ioep_set_address(dev, 1); + + rx_ctr = 0; tx_ctr = 0; err_ctr = 0; + + while (1) { + uint top_int; + + fpga_get_reg(pplat->fpga, "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) { + 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; +} +#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */ + +#ifndef CONFIG_GDSYS_LEGACY_DRIVERS +int do_iodev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct udevice *ioep; + + if (argc > 1) { + int i = simple_strtoul(argv[1], NULL, 10); + int ret; + + ret = uclass_get_device_by_seq(UCLASS_IOEP, i, &ioep); + if (ret) { + printf("Invalid IOEP %d: err=%d\n", i, ret); + return CMD_RET_FAILURE; + } + + dev = ioep; + } else { + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_IOEP, &uc); + if (ret) + return CMD_RET_FAILURE; + + uclass_foreach_dev(ioep, uc) { + printf("IOEP %d:\t%s\n", ioep->seq, ioep->name); + } + + if (dev) + printf("\nSelected IOEP: %d\n", dev->seq); + 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", @@ -297,3 +505,22 @@ U_BOOT_CMD( "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 */