/*
 * (C) Copyright 2000-2003
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * MPC8xx Internal Memory Map Functions
 */

#include <common.h>
#include <command.h>

#include <asm/8xx_immap.h>
#include <commproc.h>
#include <asm/iopin_8xx.h>
#include <asm/io.h>

DECLARE_GLOBAL_DATA_PTR;

static int do_siuinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	sysconf8xx_t __iomem *sc = &immap->im_siu_conf;

	printf("SIUMCR= %08x SYPCR = %08x\n",
	       in_be32(&sc->sc_siumcr), in_be32(&sc->sc_sypcr));
	printf("SWT   = %08x\n", in_be32(&sc->sc_swt));
	printf("SIPEND= %08x SIMASK= %08x\n",
	       in_be32(&sc->sc_sipend), in_be32(&sc->sc_simask));
	printf("SIEL  = %08x SIVEC = %08x\n",
	       in_be32(&sc->sc_siel), in_be32(&sc->sc_sivec));
	printf("TESR  = %08x SDCR  = %08x\n",
	       in_be32(&sc->sc_tesr), in_be32(&sc->sc_sdcr));
	return 0;
}

static int do_memcinfo(cmd_tbl_t *cmdtp, int flag, int argc,
		       char * const argv[])
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	memctl8xx_t __iomem *memctl = &immap->im_memctl;
	int nbanks = 8;
	uint __iomem *p = &memctl->memc_br0;
	int i;

	for (i = 0; i < nbanks; i++, p += 2)
		printf("BR%-2d  = %08x OR%-2d  = %08x\n",
		       i, in_be32(p), i, in_be32(p + 1));

	printf("MAR   = %08x", in_be32(&memctl->memc_mar));
	printf(" MCR   = %08x\n", in_be32(&memctl->memc_mcr));
	printf("MAMR  = %08x MBMR  = %08x",
	       in_be32(&memctl->memc_mamr), in_be32(&memctl->memc_mbmr));
	printf("\nMSTAT =     %04x\n", in_be16(&memctl->memc_mstat));
	printf("MPTPR =     %04x MDR   = %08x\n",
	       in_be16(&memctl->memc_mptpr), in_be32(&memctl->memc_mdr));
	return 0;
}

static int do_carinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	car8xx_t __iomem *car = &immap->im_clkrst;

	printf("SCCR  = %08x\n", in_be32(&car->car_sccr));
	printf("PLPRCR= %08x\n", in_be32(&car->car_plprcr));
	printf("RSR   = %08x\n", in_be32(&car->car_rsr));
	return 0;
}

static int counter;

static void header(void)
{
	char *data = "\
       --------------------------------        --------------------------------\
       00000000001111111111222222222233        00000000001111111111222222222233\
       01234567890123456789012345678901        01234567890123456789012345678901\
       --------------------------------        --------------------------------\
    ";
	int i;

	if (counter % 2)
		putc('\n');
	counter = 0;

	for (i = 0; i < 4; i++, data += 79)
		printf("%.79s\n", data);
}

static void binary(char *label, uint value, int nbits)
{
	uint mask = 1 << (nbits - 1);
	int i, second = (counter++ % 2);

	if (second)
		putc(' ');
	puts(label);
	for (i = 32 + 1; i != nbits; i--)
		putc(' ');

	while (mask != 0) {
		if (value & mask)
			putc('1');
		else
			putc('0');
		mask >>= 1;
	}

	if (second)
		putc('\n');
}

#define PA_NBITS	16
#define PA_NB_ODR	 8
#define PB_NBITS	18
#define PB_NB_ODR	16
#define PC_NBITS	12
#define PD_NBITS	13

static int do_iopinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	iop8xx_t __iomem *iop = &immap->im_ioport;
	ushort __iomem *l, *r;
	uint __iomem *R;

	counter = 0;
	header();

	/*
	 * Ports A & B
	 */

	l = &iop->iop_padir;
	R = &immap->im_cpm.cp_pbdir;
	binary("PA_DIR", in_be16(l++), PA_NBITS);
	binary("PB_DIR", in_be32(R++), PB_NBITS);
	binary("PA_PAR", in_be16(l++), PA_NBITS);
	binary("PB_PAR", in_be32(R++), PB_NBITS);
	binary("PA_ODR", in_be16(l++), PA_NB_ODR);
	binary("PB_ODR", in_be32(R++), PB_NB_ODR);
	binary("PA_DAT", in_be16(l++), PA_NBITS);
	binary("PB_DAT", in_be32(R++), PB_NBITS);

	header();

	/*
	 * Ports C & D
	 */

	l = &iop->iop_pcdir;
	r = &iop->iop_pddir;
	binary("PC_DIR", in_be16(l++), PC_NBITS);
	binary("PD_DIR", in_be16(r++), PD_NBITS);
	binary("PC_PAR", in_be16(l++), PC_NBITS);
	binary("PD_PAR", in_be16(r++), PD_NBITS);
	binary("PC_SO ", in_be16(l++), PC_NBITS);
	binary("      ", 0, 0);
	r++;
	binary("PC_DAT", in_be16(l++), PC_NBITS);
	binary("PD_DAT", in_be16(r++), PD_NBITS);
	binary("PC_INT", in_be16(l++), PC_NBITS);

	header();
	return 0;
}

/*
 * set the io pins
 * this needs a clean up for smaller tighter code
 * use *uint and set the address based on cmd + port
 */
static int do_iopset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	uint rcode = 0;
	iopin_t iopin;
	static uint port;
	static uint pin;
	static uint value;
	static enum {
		DIR,
		PAR,
		SOR,
		ODR,
		DAT,
		INT
	} cmd = DAT;

	if (argc != 5) {
		puts("iopset PORT PIN CMD VALUE\n");
		return 1;
	}
	port = argv[1][0] - 'A';
	if (port > 3)
		port -= 0x20;
	if (port > 3)
		rcode = 1;
	pin = simple_strtol(argv[2], NULL, 10);
	if (pin > 31)
		rcode = 1;


	switch (argv[3][0]) {
	case 'd':
		if (argv[3][1] == 'a')
			cmd = DAT;
		else if (argv[3][1] == 'i')
			cmd = DIR;
		else
			rcode = 1;
		break;
	case 'p':
		cmd = PAR;
		break;
	case 'o':
		cmd = ODR;
		break;
	case 's':
		cmd = SOR;
		break;
	case 'i':
		cmd = INT;
		break;
	default:
		printf("iopset: unknown command %s\n", argv[3]);
		rcode = 1;
	}
	if (argv[4][0] == '1')
		value = 1;
	else if (argv[4][0] == '0')
		value = 0;
	else
		rcode = 1;
	if (rcode == 0) {
		iopin.port = port;
		iopin.pin = pin;
		iopin.flag = 0;
		switch (cmd) {
		case DIR:
			if (value)
				iopin_set_out(&iopin);
			else
				iopin_set_in(&iopin);
			break;
		case PAR:
			if (value)
				iopin_set_ded(&iopin);
			else
				iopin_set_gen(&iopin);
			break;
		case SOR:
			if (value)
				iopin_set_opt2(&iopin);
			else
				iopin_set_opt1(&iopin);
			break;
		case ODR:
			if (value)
				iopin_set_odr(&iopin);
			else
				iopin_set_act(&iopin);
			break;
		case DAT:
			if (value)
				iopin_set_high(&iopin);
			else
				iopin_set_low(&iopin);
			break;
		case INT:
			if (value)
				iopin_set_falledge(&iopin);
			else
				iopin_set_anyedge(&iopin);
			break;
		}
	}
	return rcode;
}

static void prbrg(int n, uint val)
{
	uint extc = (val >> 14) & 3;
	uint cd = (val & CPM_BRG_CD_MASK) >> 1;
	uint div16 = (val & CPM_BRG_DIV16) != 0;

	ulong clock = gd->cpu_clk;

	printf("BRG%d:", n);

	if (val & CPM_BRG_RST)
		puts(" RESET");
	else
		puts("      ");

	if (val & CPM_BRG_EN)
		puts("  ENABLED");
	else
		puts(" DISABLED");

	printf(" EXTC=%d", extc);

	if (val & CPM_BRG_ATB)
		puts(" ATB");
	else
		puts("    ");

	printf(" DIVIDER=%4d", cd);
	if (extc == 0 && cd != 0) {
		uint baudrate;

		if (div16)
			baudrate = (clock / 16) / (cd + 1);
		else
			baudrate = clock / (cd + 1);

		printf("=%6d bps", baudrate);
	} else {
		puts("           ");
	}

	if (val & CPM_BRG_DIV16)
		puts(" DIV16");
	else
		puts("      ");

	putc('\n');
}

static int do_brginfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	cpm8xx_t __iomem *cp = &immap->im_cpm;
	uint __iomem *p = &cp->cp_brgc1;
	int i = 1;

	while (i <= 4)
		prbrg(i++, in_be32(p++));

	return 0;
}

/***************************************************/

U_BOOT_CMD(
	siuinfo,	1,	1,	do_siuinfo,
	"print System Interface Unit (SIU) registers",
	""
);

U_BOOT_CMD(
	memcinfo,	1,	1,	do_memcinfo,
	"print Memory Controller registers",
	""
);

U_BOOT_CMD(
	carinfo,	1,	1,	do_carinfo,
	"print Clocks and Reset registers",
	""
);

U_BOOT_CMD(
	iopinfo,	1,	1,	do_iopinfo,
	"print I/O Port registers",
	""
);

U_BOOT_CMD(
	iopset,	5,	0,	do_iopset,
	"set I/O Port registers",
	"PORT PIN CMD VALUE\nPORT: A-D, PIN: 0-31, CMD: [dat|dir|odr|sor], VALUE: 0|1"
);

U_BOOT_CMD(
	brginfo,	1,	1,	do_brginfo,
	"print Baud Rate Generator (BRG) registers",
	""
);
