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

/*
 * ehnus: change pll frequency.
 * Wed Sep  5 11:45:17 CST 2007
 * hsun@udtech.com.cn
 */


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

#ifdef CONFIG_CMD_EEPROM

#define EEPROM_CONF_OFFSET		0
#define EEPROM_TEST_OFFSET		16
#define EEPROM_SDSTP_PARAM		16

#define PLL_NAME_MAX			12
#define BUF_STEP			8

/* eeprom_wirtes 8Byte per op. */
#define EEPROM_ALTER_FREQ(freq)						\
	do {								\
		int __i;						\
		for (__i = 0; __i < 2; __i++)				\
			eeprom_write (CONFIG_SYS_I2C_EEPROM_ADDR,		\
				      EEPROM_CONF_OFFSET + __i*BUF_STEP, \
				      pll_select[freq],			\
				      BUF_STEP + __i*BUF_STEP);		\
	} while (0)

#define PDEBUG
#ifdef	PDEBUG
#define PLL_DEBUG	pll_debug(EEPROM_CONF_OFFSET)
#else
#define PLL_DEBUG
#endif

typedef enum {
	PLL_ebc20,
	PLL_333,
	PLL_4001,
	PLL_4002,
	PLL_533,
	PLL_600,
	PLL_666,	/* For now, kilauea can't support */
	RCONF,
	WTEST,
	PLL_TOTAL
} pll_freq_t;

static const char
pll_name[][PLL_NAME_MAX] = {
	"PLL_ebc20",
	"PLL_333",
	"PLL_400@1",
	"PLL_400@2",
	"PLL_533",
	"PLL_600",
	"PLL_666",
	"RCONF",
	"WTEST",
	""
};

/*
 * ehnus:
 */
static uchar
pll_select[][EEPROM_SDSTP_PARAM] = {
	/* 0: CPU 333MHz EBC 20MHz, for test only */
	{
		0x8c, 0x12, 0xec, 0x12, 0x88, 0x00, 0x0a, 0x00,
		0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00
	},

	/* 0: 333 */
	{
		0x8c, 0x12, 0xec, 0x12, 0x98, 0x00, 0x0a, 0x00,
		0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00
	},

	/* 1: 400_266 */
	{
		0x8e, 0x0e, 0xe8, 0x13, 0x98, 0x00, 0x0a, 0x00,
		0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00
	},

	/* 2: 400 */
	{
		0x8e, 0x0e, 0xe8, 0x12, 0x98, 0x00, 0x0a, 0x00,
		0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00
	},

	/* 3: 533 */
	{
		0x8e, 0x43, 0x60, 0x13, 0x98, 0x00, 0x0a, 0x00,
		0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00
	},

	/* 4: 600 */
	{
		0x8d, 0x02, 0x34, 0x13, 0x98, 0x00, 0x0a, 0x00,
		0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00
	},

	/* 5: 666 */
	{
		0x8d, 0x03, 0x78, 0x13, 0x98, 0x00, 0x0a, 0x00,
		0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00
	},

	{}
};

static uchar
testbuf[EEPROM_SDSTP_PARAM] = {
	0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
	0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
};

static void
pll_debug(int off)
{
	int i;
	uchar buffer[EEPROM_SDSTP_PARAM];

	memset(buffer, 0, sizeof(buffer));
	eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR, off,
		    buffer, EEPROM_SDSTP_PARAM);

	printf("Debug: SDSTP[0-3] at offset \"0x%02x\" lists as follows: \n", off);
	for (i = 0; i < EEPROM_SDSTP_PARAM; i++)
		printf("%02x ", buffer[i]);
	printf("\n");
}

static void
test_write(void)
{
	printf("Debug: test eeprom_write ... ");

	/*
	 * Write twice, 8 bytes per write
	 */
	eeprom_write (CONFIG_SYS_I2C_EEPROM_ADDR, EEPROM_TEST_OFFSET,
		      testbuf, 8);
	eeprom_write (CONFIG_SYS_I2C_EEPROM_ADDR, EEPROM_TEST_OFFSET+8,
		      testbuf, 16);
	printf("done\n");

	pll_debug(EEPROM_TEST_OFFSET);
}

int
do_pll_alter (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char c = '\0';
	pll_freq_t pll_freq;

	if (argc < 2)
		return cmd_usage(cmdtp);

	for (pll_freq = PLL_ebc20; pll_freq < PLL_TOTAL; pll_freq++) {
		if (!strcmp(pll_name[pll_freq], argv[1]))
			break;
	}

	switch (pll_freq) {
	case PLL_ebc20:
	case PLL_333:
	case PLL_4001:
	case PLL_4002:
	case PLL_533:
	case PLL_600:
		EEPROM_ALTER_FREQ(pll_freq);
		break;

	case PLL_666:		/* not support */
		printf("Choose this option will result in a boot failure."
		       "\nContinue? (Y/N): ");

		c = getc(); putc('\n');

		if ((c == 'y') || (c == 'Y')) {
			EEPROM_ALTER_FREQ(pll_freq);
			break;
		}
		goto ret;

	case RCONF:
		pll_debug(EEPROM_CONF_OFFSET);
		goto ret;
	case WTEST:
		printf("DEBUG: write test\n");
		test_write();
		goto ret;

	default:
		printf("Invalid options\n\n");
		return cmd_usage(cmdtp);
	}

	printf("PLL set to %s, "
	       "reset the board to take effect\n", pll_name[pll_freq]);

	PLL_DEBUG;
ret:
	return 0;
}

U_BOOT_CMD(
	pllalter, CONFIG_SYS_MAXARGS, 1,        do_pll_alter,
	"change pll frequence",
	"pllalter <selection>      - change pll frequence \n\n\
	** New freq take effect after reset. ** \n\
	----------------------------------------------\n\
	PLL_ebc20: Board: AMCC 405EX(r) Evaluation Board\n\
	\t	Same as PLL_333	\n\
	\t	except          \n\
	\t	EBC: 20 MHz     \n\
	----------------------------------------------\n\
	PLL_333: Board: AMCC 405EX(r) Evaluation Board\n\
	\t	VCO: 666 MHz  \n\
	\t	CPU: 333 MHz  \n\
	\t	PLB: 166 MHz  \n\
	\t	OPB: 83 MHz   \n\
	\t	DDR: 83 MHz   \n\
	------------------------------------------------\n\
	PLL_400@1: Board: AMCC 405EX(r) Evaluation Board\n\
	\t	VCO: 800 MHz  \n\
	\t	CPU: 400 MHz  \n\
	\t	PLB: 133 MHz  \n\
	\t	OPB: 66  MHz  \n\
	\t	DDR: 133 MHz  \n\
	------------------------------------------------\n\
	PLL_400@2: Board: AMCC 405EX(r) Evaluation Board\n\
	\t	VCO: 800 MHz  \n\
	\t	CPU: 400 MHz  \n\
	\t	PLB: 200 MHz  \n\
	\t	OPB: 100 MHz  \n\
	\t	DDR: 200 MHz  \n\
	----------------------------------------------\n\
	PLL_533: Board: AMCC 405EX(r) Evaluation Board\n\
	\t	VCO: 1066 MHz  \n\
	\t	CPU: 533  MHz  \n\
	\t	PLB: 177  MHz  \n\
	\t	OPB: 88   MHz  \n\
	\t	DDR: 177  MHz  \n\
	----------------------------------------------\n\
	PLL_600: Board: AMCC 405EX(r) Evaluation Board\n\
	\t	VCO: 1200 MHz  \n\
	\t	CPU: 600  MHz  \n\
	\t	PLB: 200  MHz  \n\
	\t	OPB: 100  MHz  \n\
	\t	DDR: 200  MHz  \n\
	----------------------------------------------\n\
	PLL_666: Board: AMCC 405EX(r) Evaluation Board\n\
	\t	VCO: 1333 MHz  \n\
	\t	CPU: 666  MHz  \n\
	\t	PLB: 166  MHz  \n\
	\t	OPB: 83   MHz  \n\
	\t	DDR: 166  MHz  \n\
	-----------------------------------------------\n\
	RCONF: Read current eeprom configuration.      \n\
	-----------------------------------------------\n\
	WTEST: Test EEPROM write with predefined values\n\
	-----------------------------------------------"
);

#endif	/* CONFIG_CMD_EEPROM */
