/*
 * (C) Copyright 2007
 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * AMBA Plug&Play information list command
 *
 */
#include <common.h>
#include <command.h>
#include <ambapp.h>

DECLARE_GLOBAL_DATA_PTR;

/* We put these variables into .data section so that they are zero
 * when entering the AMBA Plug & Play routines (in cpu/cpu/ambapp.c)
 * the first time. BSS is not garantueed to be zero since BSS
 * hasn't been cleared the first times entering the CPU AMBA functions.
 *
 * The AMBA PnP routines call these functions if ambapp_???_print is set.
 *
 */
int ambapp_apb_print __attribute__ ((section(".data"))) = 0;
int ambapp_ahb_print __attribute__ ((section(".data"))) = 0;

typedef struct {
	int device_id;
	char *name;
} ambapp_device_name;

static ambapp_device_name gaisler_devices[] = {
	{GAISLER_LEON3, "GAISLER_LEON3"},
	{GAISLER_LEON3DSU, "GAISLER_LEON3DSU"},
	{GAISLER_ETHAHB, "GAISLER_ETHAHB"},
	{GAISLER_ETHMAC, "GAISLER_ETHMAC"},
	{GAISLER_APBMST, "GAISLER_APBMST"},
	{GAISLER_AHBUART, "GAISLER_AHBUART"},
	{GAISLER_SRCTRL, "GAISLER_SRCTRL"},
	{GAISLER_SDCTRL, "GAISLER_SDCTRL"},
	{GAISLER_APBUART, "GAISLER_APBUART"},
	{GAISLER_IRQMP, "GAISLER_IRQMP"},
	{GAISLER_AHBRAM, "GAISLER_AHBRAM"},
	{GAISLER_GPTIMER, "GAISLER_GPTIMER"},
	{GAISLER_PCITRG, "GAISLER_PCITRG"},
	{GAISLER_PCISBRG, "GAISLER_PCISBRG"},
	{GAISLER_PCIFBRG, "GAISLER_PCIFBRG"},
	{GAISLER_PCITRACE, "GAISLER_PCITRACE"},
	{GAISLER_AHBTRACE, "GAISLER_AHBTRACE"},
	{GAISLER_ETHDSU, "GAISLER_ETHDSU"},
	{GAISLER_PIOPORT, "GAISLER_PIOPORT"},
	{GAISLER_AHBJTAG, "GAISLER_AHBJTAG"},
	{GAISLER_ATACTRL, "GAISLER_ATACTRL"},
	{GAISLER_VGA, "GAISLER_VGA"},
	{GAISLER_KBD, "GAISLER_KBD"},
	{GAISLER_L2TIME, "GAISLER_L2TIME"},
	{GAISLER_L2C, "GAISLER_L2C"},
	{GAISLER_PLUGPLAY, "GAISLER_PLUGPLAY"},
	{GAISLER_SPW, "GAISLER_SPW"},
	{GAISLER_SPW2, "GAISLER_SPW2"},
	{GAISLER_EHCI, "GAISLER_EHCI"},
	{GAISLER_UHCI, "GAISLER_UHCI"},
	{GAISLER_AHBSTAT, "GAISLER_AHBSTAT"},
	{GAISLER_DDR2SPA, "GAISLER_DDR2SPA"},
	{GAISLER_DDRSPA, "GAISLER_DDRSPA"},
	{0, NULL}
};

static ambapp_device_name esa_devices[] = {
	{ESA_LEON2, "ESA_LEON2"},
	{ESA_MCTRL, "ESA_MCTRL"},
	{0, NULL}
};

static ambapp_device_name opencores_devices[] = {
	{OPENCORES_PCIBR, "OPENCORES_PCIBR"},
	{OPENCORES_ETHMAC, "OPENCORES_ETHMAC"},
	{0, NULL}
};

typedef struct {
	unsigned int vendor_id;
	char *name;
	ambapp_device_name *devices;
} ambapp_vendor_devnames;

static ambapp_vendor_devnames vendors[] = {
	{VENDOR_GAISLER, "VENDOR_GAISLER", gaisler_devices},
	{VENDOR_ESA, "VENDOR_ESA", esa_devices},
	{VENDOR_OPENCORES, "VENDOR_OPENCORES", opencores_devices},
	{0, NULL, 0}
};

static char *ambapp_get_devname(ambapp_device_name * devs, int id)
{
	if (!devs)
		return NULL;

	while (devs->device_id > 0) {
		if (devs->device_id == id)
			return devs->name;
		devs++;
	}
	return NULL;
}

char *ambapp_device_id2str(int vendor, int id)
{
	ambapp_vendor_devnames *ven = &vendors[0];

	while (ven->vendor_id > 0) {
		if (ven->vendor_id == vendor) {
			return ambapp_get_devname(ven->devices, id);
		}
		ven++;
	}
	return NULL;
}

char *ambapp_vendor_id2str(int vendor)
{
	ambapp_vendor_devnames *ven = &vendors[0];

	while (ven->vendor_id > 0) {
		if (ven->vendor_id == vendor) {
			return ven->name;
		}
		ven++;
	}
	return NULL;
}

static char *unknown = "unknown";

/* Print one APB device */
void ambapp_print_apb(apbctrl_pp_dev * apb, ambapp_ahbdev * apbmst, int index)
{
	char *dev_str, *ven_str;
	int irq, ver, vendor, deviceid;
	unsigned int address, apbmst_base, mask;

	vendor = amba_vendor(apb->conf);
	deviceid = amba_device(apb->conf);
	irq = amba_irq(apb->conf);
	ver = amba_ver(apb->conf);
	apbmst_base = apbmst->address[0] & LEON3_IO_AREA;
	address = (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) &
	    (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);

	mask = amba_membar_mask(apb->bar) << 8;
	mask = ((~mask) & 0x000fffff) + 1;

	ven_str = ambapp_vendor_id2str(vendor);
	if (!ven_str) {
		ven_str = unknown;
		dev_str = unknown;
	} else {
		dev_str = ambapp_device_id2str(vendor, deviceid);
		if (!dev_str)
			dev_str = unknown;
	}

	printf("0x%02x:0x%02x:0x%02x: %s  %s\n"
	       "   apb: 0x%08x - 0x%08x\n"
	       "   irq: %-2d (ver: %-2d)\n",
	       index, vendor, deviceid, ven_str, dev_str, address,
	       address + mask, irq, ver);
}

void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index)
{
	char *dev_str, *ven_str;
	int irq, ver, vendor, deviceid;
	unsigned int addr, mask;
	int j;

	vendor = amba_vendor(ahb->conf);
	deviceid = amba_device(ahb->conf);
	irq = amba_irq(ahb->conf);
	ver = amba_ver(ahb->conf);

	ven_str = ambapp_vendor_id2str(vendor);
	if (!ven_str) {
		ven_str = unknown;
		dev_str = unknown;
	} else {
		dev_str = ambapp_device_id2str(vendor, deviceid);
		if (!dev_str)
			dev_str = unknown;
	}

	printf("0x%02x:0x%02x:0x%02x: %s  %s\n",
	       index, vendor, deviceid, ven_str, dev_str);

	for (j = 0; j < 4; j++) {
		addr = amba_membar_start(ahb->bars[j]);
		if (amba_membar_type(ahb->bars[j]) == 0)
			continue;
		if (amba_membar_type(ahb->bars[j]) == AMBA_TYPE_AHBIO)
			addr = AMBA_TYPE_AHBIO_ADDR(addr);
		mask = amba_membar_mask(ahb->bars[j]) << 20;
		printf("   mem: 0x%08x - 0x%08x\n", addr, addr + ((~mask) + 1));
	}

	printf("   irq: %-2d (ver: %d)\n", irq, ver);
}

int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{

	/* Print AHB Masters */
	puts("--------- AHB Masters ---------\n");
	ambapp_apb_print = 0;
	ambapp_ahb_print = 1;
	ambapp_ahbmst_count(99, 99);	/* Get vendor&device 99 = nonexistent... */

	/* Print AHB Slaves */
	puts("--------- AHB Slaves  ---------\n");
	ambapp_ahbslv_count(99, 99);	/* Get vendor&device 99 = nonexistent... */

	/* Print APB Slaves */
	puts("--------- APB Slaves  ---------\n");
	ambapp_apb_print = 1;
	ambapp_ahb_print = 0;
	ambapp_apb_count(99, 99);	/* Get vendor&device 99 = nonexistent... */

	/* Reset, no futher printing */
	ambapp_apb_print = 0;
	ambapp_ahb_print = 0;
	puts("\n");
	return 0;
}

int ambapp_init_reloc(void)
{
	ambapp_vendor_devnames *vend = vendors;
	ambapp_device_name *dev;

	while (vend->vendor_id && vend->name) {
		vend->name = (char *)((unsigned int)vend->name + gd->reloc_off);
		vend->devices =
		    (ambapp_device_name *) ((unsigned int)vend->devices +
					    gd->reloc_off);;
		dev = vend->devices;
		vend++;
		if (!dev)
			continue;
		while (dev->device_id && dev->name) {
			dev->name =
			    (char *)((unsigned int)dev->name + gd->reloc_off);;
			dev++;
		}
	}
	return 0;
}

U_BOOT_CMD(
	ambapp, 1, 1, do_ambapp_print,
	"list AMBA Plug&Play information",
	"ambapp\n"
	"    - lists AMBA (AHB & APB) Plug&Play devices present on the system"
);
