// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2016
 * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
 *
 * (C) Copyright 2017, 2018
 * Mario Six,  Guntermann & Drunck GmbH, mario.six@gdsys.cc
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <axi.h>
#include <command.h>
#include <console.h>
#include <display_options.h>
#include <dm.h>
#include <log.h>

/* Currently selected AXI bus device */
static struct udevice *axi_cur_bus;
/* Transmission size from last command */
static uint dp_last_size;
/* Address from last command */
static uint dp_last_addr;
/* Number of bytes to display from last command; default = 64 */
static uint dp_last_length = 0x40;

/**
 * show_bus() - Show devices on a single AXI bus
 * @bus: The AXI bus device to printt information for
 */
static void show_bus(struct udevice *bus)
{
	struct udevice *dev;

	printf("Bus %d:\t%s", dev_seq(bus), bus->name);
	if (device_active(bus))
		printf("  (active)");
	printf("\n");
	for (device_find_first_child(bus, &dev);
	     dev;
	     device_find_next_child(&dev))
		printf("  %s\n", dev->name);
}

/**
 * axi_set_cur_bus() - Set the currently active AXI bus
 * @busnum: The number of the bus (i.e. its sequence number) that should be
 *	    made active
 *
 * The operations supplied by this command operate only on the currently active
 * bus.
 *
 * Return: 0 if OK, -ve on error
 */
static int axi_set_cur_bus(unsigned int busnum)
{
	struct udevice *bus;
	struct udevice *dummy;
	int ret;

	/* Make sure that all sequence numbers are initialized */
	for (uclass_first_device(UCLASS_AXI, &dummy);
	     dummy;
	     uclass_next_device(&dummy))
		;

	ret = uclass_get_device_by_seq(UCLASS_AXI, busnum, &bus);
	if (ret) {
		debug("%s: No bus %d\n", __func__, busnum);
		return ret;
	}
	axi_cur_bus = bus;

	return 0;
}

/**
 * axi_get_cur_bus() - Retrieve the currently active AXI bus device
 * @busp: Pointer to a struct udevice that receives the currently active bus
 *	  device
 *
 * Return: 0 if OK, -ve on error
 */
static int axi_get_cur_bus(struct udevice **busp)
{
	if (!axi_cur_bus) {
		puts("No AXI bus selected\n");
		return -ENODEV;
	}
	*busp = axi_cur_bus;

	return 0;
}

/*
 * Command handlers
 */

static int do_axi_show_bus(struct cmd_tbl *cmdtp, int flag, int argc,
			   char *const argv[])
{
	struct udevice *dummy;

	/* Make sure that all sequence numbers are initialized */
	for (uclass_first_device(UCLASS_AXI, &dummy);
	     dummy;
	     uclass_next_device(&dummy))
		;

	if (argc == 1) {
		/* show all busses */
		struct udevice *bus;

		for (uclass_first_device(UCLASS_AXI, &bus);
		     bus;
		     uclass_next_device(&bus))
			show_bus(bus);
	} else {
		int i;

		/* show specific bus */
		i = dectoul(argv[1], NULL);

		struct udevice *bus;
		int ret;

		ret = uclass_get_device_by_seq(UCLASS_AXI, i, &bus);
		if (ret) {
			printf("Invalid bus %d: err=%d\n", i, ret);
			return CMD_RET_FAILURE;
		}
		show_bus(bus);
	}

	return 0;
}

static int do_axi_bus_num(struct cmd_tbl *cmdtp, int flag, int argc,
			  char *const argv[])
{
	int ret = 0;
	int bus_no;

	if (argc == 1) {
		/* querying current setting */
		struct udevice *bus;

		if (!axi_get_cur_bus(&bus))
			bus_no = dev_seq(bus);
		else
			bus_no = -1;

		printf("Current bus is %d\n", bus_no);
	} else {
		bus_no = dectoul(argv[1], NULL);
		printf("Setting bus to %d\n", bus_no);

		ret = axi_set_cur_bus(bus_no);
		if (ret)
			printf("Failure changing bus number (%d)\n", ret);
	}

	return ret ? CMD_RET_FAILURE : 0;
}

static int do_axi_md(struct cmd_tbl *cmdtp, int flag, int argc,
		     char *const argv[])
{
	/* Print that many bytes per line */
	const uint DISP_LINE_LEN = 16;
	u8 linebuf[DISP_LINE_LEN];
	unsigned int k;
	ulong addr, length, size;
	ulong nbytes;
	enum axi_size_t axisize;
	int unitsize;

	/*
	 * We use the last specified parameters, unless new ones are
	 * entered.
	 */
	size = dp_last_size;
	addr = dp_last_addr;
	length = dp_last_length;

	if (argc < 3)
		return CMD_RET_USAGE;

	if (!axi_cur_bus) {
		puts("No AXI bus selected\n");
		return CMD_RET_FAILURE;
	}

	if ((flag & CMD_FLAG_REPEAT) == 0) {
		size = dectoul(argv[1], NULL);

		/*
		 * Address is specified since argc >= 3
		 */
		addr = hextoul(argv[2], NULL);

		/*
		 * If there's another parameter, it is the length to display;
		 * length is the number of objects, not number of bytes
		 */
		if (argc > 3)
			length = hextoul(argv[3], NULL);
	}

	switch (size) {
	case 8:
		axisize = AXI_SIZE_8;
		unitsize = 1;
		break;
	case 16:
		axisize = AXI_SIZE_16;
		unitsize = 2;
		break;
	case 32:
		axisize = AXI_SIZE_32;
		unitsize = 4;
		break;
	default:
		printf("Unknown read size '%lu'\n", size);
		return CMD_RET_USAGE;
	};

	nbytes = length * unitsize;
	do {
		ulong linebytes = (nbytes > DISP_LINE_LEN) ?
				  DISP_LINE_LEN : nbytes;

		for (k = 0; k < linebytes / unitsize; ++k) {
			int ret = axi_read(axi_cur_bus, addr + k * unitsize,
					   linebuf + k * unitsize, axisize);

			if (!ret) /* Continue if axi_read was successful */
				continue;

			if (ret == -ENOSYS)
				printf("axi_read failed; read size not supported?\n");
			else
				printf("axi_read failed: err = %d\n", ret);

			return CMD_RET_FAILURE;
		}
		print_buffer(addr, (void *)linebuf, unitsize,
			     linebytes / unitsize,
			     DISP_LINE_LEN / unitsize);

		nbytes -= max(linebytes, 1UL);
		addr += linebytes;

		if (ctrlc())
			break;
	} while (nbytes > 0);

	dp_last_size = size;
	dp_last_addr = addr;
	dp_last_length = length;

	return 0;
}

static int do_axi_mw(struct cmd_tbl *cmdtp, int flag, int argc,
		     char *const argv[])
{
	u32 writeval;
	ulong addr, count, size;
	enum axi_size_t axisize;

	if (argc <= 3 || argc >= 6)
		return CMD_RET_USAGE;

	size = dectoul(argv[1], NULL);

	switch (size) {
	case 8:
		axisize = AXI_SIZE_8;
		break;
	case 16:
		axisize = AXI_SIZE_16;
		break;
	case 32:
		axisize = AXI_SIZE_32;
		break;
	default:
		printf("Unknown write size '%lu'\n", size);
		return CMD_RET_USAGE;
	};

	/* Address is specified since argc > 4 */
	addr = hextoul(argv[2], NULL);

	/* Get the value to write */
	writeval = hextoul(argv[3], NULL);

	/* Count ? */
	if (argc == 5)
		count = hextoul(argv[4], NULL);
	else
		count = 1;

	while (count-- > 0) {
		int ret = axi_write(axi_cur_bus, addr + count * sizeof(u32),
				    &writeval, axisize);

		if (ret) {
			printf("axi_write failed: err = %d\n", ret);
			return CMD_RET_FAILURE;
		}
	}

	return 0;
}

static struct cmd_tbl cmd_axi_sub[] = {
	U_BOOT_CMD_MKENT(bus, 1, 1, do_axi_show_bus, "", ""),
	U_BOOT_CMD_MKENT(dev, 1, 1, do_axi_bus_num, "", ""),
	U_BOOT_CMD_MKENT(md, 4, 1, do_axi_md, "", ""),
	U_BOOT_CMD_MKENT(mw, 5, 1, do_axi_mw, "", ""),
};

static int do_ihs_axi(struct cmd_tbl *cmdtp, int flag, int argc,
		      char *const argv[])
{
	struct cmd_tbl *c;

	if (argc < 2)
		return CMD_RET_USAGE;

	/* Strip off leading 'axi' command argument */
	argc--;
	argv++;

	/* Hand off rest of command line to sub-commands */
	c = find_cmd_tbl(argv[0], &cmd_axi_sub[0], ARRAY_SIZE(cmd_axi_sub));

	if (c)
		return c->cmd(cmdtp, flag, argc, argv);
	else
		return CMD_RET_USAGE;
}

U_BOOT_LONGHELP(axi,
	"bus  - show AXI bus info\n"
	"axi dev [bus] - show or set current AXI bus to bus number [bus]\n"
	"axi md size addr [# of objects] - read from AXI device at address [addr] and data width [size] (one of 8, 16, 32)\n"
	"axi mw size addr value [count] - write data [value] to AXI device at address [addr] and data width [size] (one of 8, 16, 32)\n");

U_BOOT_CMD(axi, 7, 1, do_ihs_axi,
	   "AXI sub-system",
	   axi_help_text
);
