1 // SPDX-License-Identifier: GPL-2.0+
11 #include <gdsys_fpga.h>
13 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
19 #include "../../../drivers/misc/gdsys_soc.h"
20 #include "../../../drivers/misc/gdsys_ioep.h"
21 #include "../../../drivers/misc/ihs_fpga.h"
23 const int HEADER_WORDS = sizeof(struct io_generic_packet) / 2;
24 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
26 enum status_print_type {
31 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
33 STATE_TX_PACKET_BUILDING = BIT(0),
34 STATE_TX_TRANSMITTING = BIT(1),
35 STATE_TX_BUFFER_FULL = BIT(2),
36 STATE_TX_ERR = BIT(3),
37 STATE_RECEIVE_TIMEOUT = BIT(4),
38 STATE_PROC_RX_STORE_TIMEOUT = BIT(5),
39 STATE_PROC_RX_RECEIVE_TIMEOUT = BIT(6),
40 STATE_RX_DIST_ERR = BIT(7),
41 STATE_RX_LENGTH_ERR = BIT(8),
42 STATE_RX_FRAME_CTR_ERR = BIT(9),
43 STATE_RX_FCS_ERR = BIT(10),
44 STATE_RX_PACKET_DROPPED = BIT(11),
45 STATE_RX_DATA_LAST = BIT(12),
46 STATE_RX_DATA_FIRST = BIT(13),
47 STATE_RX_DATA_AVAILABLE = BIT(15),
51 IRQ_CPU_TRANSMITBUFFER_FREE_STATUS = BIT(5),
52 IRQ_CPU_PACKET_TRANSMITTED_EVENT = BIT(6),
53 IRQ_NEW_CPU_PACKET_RECEIVED_EVENT = BIT(7),
54 IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS = BIT(8),
58 CTRL_PROC_RECEIVE_ENABLE = BIT(12),
59 CTRL_FLUSH_TRANSMIT_BUFFER = BIT(15),
62 struct io_generic_packet {
68 } __attribute__((__packed__));
69 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
71 unsigned long long rx_ctr;
72 unsigned long long tx_ctr;
73 unsigned long long err_ctr;
74 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
76 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
78 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
79 static void io_check_status(uint fpga, u16 status, enum status_print_type type)
81 u16 mask = STATE_RX_DIST_ERR | STATE_RX_LENGTH_ERR |
82 STATE_RX_FRAME_CTR_ERR | STATE_RX_FCS_ERR |
83 STATE_RX_PACKET_DROPPED | STATE_TX_ERR;
85 if (!(status & mask)) {
86 FPGA_SET_REG(fpga, ep.rx_tx_status, status);
91 FPGA_SET_REG(fpga, ep.rx_tx_status, status);
93 if (type == STATUS_SILENT)
96 if (status & STATE_RX_PACKET_DROPPED)
97 printf("RX_PACKET_DROPPED, status %04x\n", status);
99 if (status & STATE_RX_DIST_ERR)
100 printf("RX_DIST_ERR\n");
101 if (status & STATE_RX_LENGTH_ERR)
102 printf("RX_LENGTH_ERR\n");
103 if (status & STATE_RX_FRAME_CTR_ERR)
104 printf("RX_FRAME_CTR_ERR\n");
105 if (status & STATE_RX_FCS_ERR)
106 printf("RX_FCS_ERR\n");
108 if (status & STATE_TX_ERR)
112 static void io_check_status(struct udevice *dev, enum status_print_type type)
117 ret = misc_call(dev, 0, NULL, 0, &status, 0);
123 if (type != STATUS_LOUD)
126 if (status & STATE_RX_PACKET_DROPPED)
127 printf("RX_PACKET_DROPPED, status %04x\n", status);
129 if (status & STATE_RX_DIST_ERR)
130 printf("RX_DIST_ERR\n");
131 if (status & STATE_RX_LENGTH_ERR)
132 printf("RX_LENGTH_ERR\n");
133 if (status & STATE_RX_FRAME_CTR_ERR)
134 printf("RX_FRAME_CTR_ERR\n");
135 if (status & STATE_RX_FCS_ERR)
136 printf("RX_FCS_ERR\n");
138 if (status & STATE_TX_ERR)
141 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
143 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
144 static void io_send(uint fpga, uint size)
147 struct io_generic_packet packet = {
150 .packet_length = size,
152 u16 *p = (u16 *)&packet;
154 for (k = 0; k < sizeof(packet) / 2; ++k)
155 FPGA_SET_REG(fpga, ep.transmit_data, *p++);
157 for (k = 0; k < (size + 1) / 2; ++k)
158 FPGA_SET_REG(fpga, ep.transmit_data, k);
160 FPGA_SET_REG(fpga, ep.rx_tx_control,
161 CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
166 static void io_send(struct udevice *dev, uint size)
169 u16 buffer[HEADER_WORDS + 128];
170 struct io_generic_packet header = {
173 .packet_length = size,
175 const uint words = (size + 1) / 2;
177 memcpy(buffer, &header, 2 * HEADER_WORDS);
178 for (k = 0; k < words; ++k)
179 buffer[k + HEADER_WORDS] = (2 * k + 1) + ((2 * k) << 8);
181 misc_write(dev, 0, buffer, HEADER_WORDS + words);
185 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
187 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
188 static void io_receive(uint fpga)
192 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
194 while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
197 if (rx_tx_status & STATE_RX_DATA_LAST)
200 FPGA_GET_REG(fpga, ep.receive_data, &rx);
202 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
206 static void io_receive(struct udevice *dev)
208 u16 buffer[HEADER_WORDS + 128];
210 if (!misc_read(dev, 0, buffer, 0))
213 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
215 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
216 static void io_reflect(uint fpga)
224 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
226 while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
227 FPGA_GET_REG(fpga, ep.receive_data, &buffer[k++]);
228 if (rx_tx_status & STATE_RX_DATA_LAST)
231 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
237 for (n = 0; n < k; ++n)
238 FPGA_SET_REG(fpga, ep.transmit_data, buffer[n]);
240 FPGA_SET_REG(fpga, ep.rx_tx_control,
241 CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
246 static void io_reflect(struct udevice *dev)
248 u16 buffer[HEADER_WORDS + 128];
249 struct io_generic_packet *header;
251 if (misc_read(dev, 0, buffer, 0))
254 header = (struct io_generic_packet *)&buffer;
256 misc_write(dev, 0, buffer, HEADER_WORDS + header->packet_length);
258 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
260 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
262 * FPGA io-endpoint reflector
265 * ioreflect {fpga} {reportrate}
267 int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
271 unsigned long long last_seen = 0;
274 return CMD_RET_USAGE;
276 fpga = simple_strtoul(argv[1], NULL, 10);
279 * If another parameter, it is the report rate in packets.
282 rate = simple_strtoul(argv[2], NULL, 10);
284 /* Enable receive path */
285 FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
287 /* Set device address to dummy 1*/
288 FPGA_SET_REG(fpga, ep.device_address, 1);
290 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
296 FPGA_GET_REG(fpga, top_interrupt, &top_int);
297 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
299 io_check_status(fpga, rx_tx_status, STATUS_SILENT);
300 if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) &&
301 (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS))
305 if (!(tx_ctr % rate) && (tx_ctr != last_seen))
306 printf("refl %llu, err %llu\n", tx_ctr,
319 * FPGA io-endpoint reflector
322 * ioreflect {reportrate}
324 int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
326 struct udevice *fpga;
329 unsigned long long last_seen = 0;
332 printf("No device selected\n");
336 gdsys_soc_get_fpga(dev, &fpga);
337 regmap_init_mem(dev_ofnode(dev), &map);
339 /* Enable receive path */
340 misc_set_enabled(dev, true);
342 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
347 ihs_fpga_get(map, top_interrupt, &top_int);
348 io_check_status(dev, STATUS_SILENT);
349 if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) &&
350 (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS))
354 if (!(tx_ctr % rate) && (tx_ctr != last_seen))
355 printf("refl %llu, err %llu\n", tx_ctr,
366 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
368 #define DISP_LINE_LEN 16
370 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
372 * FPGA io-endpoint looptest
375 * ioloop {fpga} {size} {rate}
377 int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
384 return CMD_RET_USAGE;
387 * FPGA is specified since argc > 2
389 fpga = simple_strtoul(argv[1], NULL, 10);
392 * packet size is specified since argc > 2
394 size = simple_strtoul(argv[2], NULL, 10);
397 * If another parameter, it is the test rate in packets per second.
400 rate = simple_strtoul(argv[3], NULL, 10);
402 /* enable receive path */
403 FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
405 /* set device address to dummy 1*/
406 FPGA_SET_REG(fpga, ep.device_address, 1);
408 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
414 FPGA_GET_REG(fpga, top_interrupt, &top_int);
415 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
417 io_check_status(fpga, rx_tx_status, STATUS_LOUD);
418 if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
420 if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
426 udelay(1000000 / rate);
427 if (!(tx_ctr % rate))
428 printf("d %llu, tx %llu, rx %llu, err %llu\n",
429 tx_ctr - rx_ctr, tx_ctr, rx_ctr,
438 * FPGA io-endpoint looptest
441 * ioloop {size} {rate}
443 int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
447 struct udevice *fpga;
451 printf("No device selected\n");
455 gdsys_soc_get_fpga(dev, &fpga);
456 regmap_init_mem(dev_ofnode(dev), &map);
459 return CMD_RET_USAGE;
462 * packet size is specified since argc > 1
464 size = simple_strtoul(argv[2], NULL, 10);
467 * If another parameter, it is the test rate in packets per second.
470 rate = simple_strtoul(argv[3], NULL, 10);
472 /* Enable receive path */
473 misc_set_enabled(dev, true);
475 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
483 ihs_fpga_get(map, top_interrupt, &top_int);
485 io_check_status(dev, STATUS_LOUD);
486 if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
488 if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
492 udelay(1000000 / rate);
493 if (!(tx_ctr % rate))
494 printf("d %llu, tx %llu, rx %llu, err %llu\n",
495 tx_ctr - rx_ctr, tx_ctr, rx_ctr,
501 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
503 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
504 int do_iodev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
506 struct udevice *ioep = NULL;
507 struct udevice *board;
511 if (board_get(&board))
512 return CMD_RET_FAILURE;
515 int i = simple_strtoul(argv[1], NULL, 10);
517 snprintf(name, sizeof(name), "ioep%d", i);
519 ret = uclass_get_device_by_phandle(UCLASS_MISC, board, name, &ioep);
522 printf("Invalid IOEP %d\n", i);
523 return CMD_RET_FAILURE;
531 snprintf(name, sizeof(name), "ioep%d", i);
533 ret = uclass_get_device_by_phandle(UCLASS_MISC, board, name, &ioep);
538 printf("IOEP %d:\t%s\n", i++, ioep->name);
542 printf("\nSelected IOEP: %s\n", dev->name);
544 puts("\nNo IOEP selected.\n");
549 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
551 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
553 ioloop, 4, 0, do_ioloop,
554 "fpga io-endpoint looptest",
555 "fpga packetsize [packets/sec]"
559 ioreflect, 3, 0, do_ioreflect,
560 "fpga io-endpoint reflector",
565 ioloop, 3, 0, do_ioloop,
566 "fpga io-endpoint looptest",
567 "packetsize [packets/sec]"
571 ioreflect, 2, 0, do_ioreflect,
572 "fpga io-endpoint reflector",
577 iodev, 2, 0, do_iodev,
578 "fpga io-endpoint listing/selection",
579 "[ioep device to select]"
581 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */