/*
 * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <linux/io.h>
#include <mach/ddrphy-regs.h>

/* Select either decimal or hexadecimal */
#if 1
#define PRINTF_FORMAT "%2d"
#else
#define PRINTF_FORMAT "%02x"
#endif
/* field separator */
#define FS "   "

static u32 read_bdl(struct ddrphy_datx8 __iomem *dx, int index)
{
	return (readl(&dx->bdlr[index / 5]) >> (index % 5 * 6)) & 0x3f;
}

static void dump_loop(void (*callback)(struct ddrphy_datx8 __iomem *))
{
	int ch, p, dx;
	struct ddrphy __iomem *phy;

	for (ch = 0; ch < NR_DDRCH; ch++) {
		for (p = 0; p < NR_DDRPHY_PER_CH; p++) {
			phy = (struct ddrphy __iomem *)DDRPHY_BASE(ch, p);

			for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) {
				printf("CH%dP%dDX%d:", ch, p, dx);
				(*callback)(&phy->dx[dx]);
				printf("\n");
			}
		}
	}
}

static void __wbdl_dump(struct ddrphy_datx8 __iomem *dx)
{
	int i;

	for (i = 0; i < 10; i++)
		printf(FS PRINTF_FORMAT, read_bdl(dx, i));

	printf(FS "(+" PRINTF_FORMAT ")", readl(&dx->lcdlr[1]) & 0xff);
}

static void wbdl_dump(void)
{
	printf("\n--- Write Bit Delay Line ---\n");
	printf("           DQ0  DQ1  DQ2  DQ3  DQ4  DQ5  DQ6  DQ7   DM  DQS  (WDQD)\n");

	dump_loop(&__wbdl_dump);
}

static void __rbdl_dump(struct ddrphy_datx8 __iomem *dx)
{
	int i;

	for (i = 15; i < 24; i++)
		printf(FS PRINTF_FORMAT, read_bdl(dx, i));

	printf(FS "(+" PRINTF_FORMAT ")", (readl(&dx->lcdlr[1]) >> 8) & 0xff);
}

static void rbdl_dump(void)
{
	printf("\n--- Read Bit Delay Line ---\n");
	printf("           DQ0  DQ1  DQ2  DQ3  DQ4  DQ5  DQ6  DQ7   DM  (RDQSD)\n");

	dump_loop(&__rbdl_dump);
}

static void __wld_dump(struct ddrphy_datx8 __iomem *dx)
{
	int rank;
	u32 lcdlr0 = readl(&dx->lcdlr[0]);
	u32 gtr = readl(&dx->gtr);

	for (rank = 0; rank < 4; rank++) {
		u32 wld = (lcdlr0 >> (8 * rank)) & 0xff; /* Delay */
		u32 wlsl = (gtr >> (12 + 2 * rank)) & 0x3; /* System Latency */

		printf(FS PRINTF_FORMAT "%sT", wld,
		       wlsl == 0 ? "-1" : wlsl == 1 ? "+0" : "+1");
	}
}

static void wld_dump(void)
{
	printf("\n--- Write Leveling Delay ---\n");
	printf("            Rank0   Rank1   Rank2   Rank3\n");

	dump_loop(&__wld_dump);
}

static void __dqsgd_dump(struct ddrphy_datx8 __iomem *dx)
{
	int rank;
	u32 lcdlr2 = readl(&dx->lcdlr[2]);
	u32 gtr = readl(&dx->gtr);

	for (rank = 0; rank < 4; rank++) {
		u32 dqsgd = (lcdlr2 >> (8 * rank)) & 0xff; /* Delay */
		u32 dgsl = (gtr >> (3 * rank)) & 0x7; /* System Latency */

		printf(FS PRINTF_FORMAT "+%dT", dqsgd, dgsl);
	}
}

static void dqsgd_dump(void)
{
	printf("\n--- DQS Gating Delay ---\n");
	printf("            Rank0   Rank1   Rank2   Rank3\n");

	dump_loop(&__dqsgd_dump);
}

static void __mdl_dump(struct ddrphy_datx8 __iomem *dx)
{
	int i;
	u32 mdl = readl(&dx->mdlr);
	for (i = 0; i < 3; i++)
		printf(FS PRINTF_FORMAT, (mdl >> (8 * i)) & 0xff);
}

static void mdl_dump(void)
{
	printf("\n--- Master Delay Line ---\n");
	printf("          IPRD TPRD MDLD\n");

	dump_loop(&__mdl_dump);
}

#define REG_DUMP(x) \
	{ u32 __iomem *p = &phy->x; printf("%3d: %-10s: %p : %08x\n", \
					p - (u32 *)phy, #x, p, readl(p)); }

static void reg_dump(void)
{
	int ch, p;
	struct ddrphy __iomem *phy;

	printf("\n--- DDR PHY registers ---\n");

	for (ch = 0; ch < NR_DDRCH; ch++) {
		for (p = 0; p < NR_DDRPHY_PER_CH; p++) {
			printf("== Ch%d, PHY%d ==\n", ch, p);
			printf(" No: Name      : Address  : Data\n");

			phy = (struct ddrphy __iomem *)DDRPHY_BASE(ch, p);

			REG_DUMP(ridr);
			REG_DUMP(pir);
			REG_DUMP(pgcr[0]);
			REG_DUMP(pgcr[1]);
			REG_DUMP(pgsr[0]);
			REG_DUMP(pgsr[1]);
			REG_DUMP(pllcr);
			REG_DUMP(ptr[0]);
			REG_DUMP(ptr[1]);
			REG_DUMP(ptr[2]);
			REG_DUMP(ptr[3]);
			REG_DUMP(ptr[4]);
			REG_DUMP(acmdlr);
			REG_DUMP(acbdlr);
			REG_DUMP(dxccr);
			REG_DUMP(dsgcr);
			REG_DUMP(dcr);
			REG_DUMP(dtpr[0]);
			REG_DUMP(dtpr[1]);
			REG_DUMP(dtpr[2]);
			REG_DUMP(mr0);
			REG_DUMP(mr1);
			REG_DUMP(mr2);
			REG_DUMP(mr3);
			REG_DUMP(dx[0].gcr);
			REG_DUMP(dx[0].gtr);
			REG_DUMP(dx[1].gcr);
			REG_DUMP(dx[1].gtr);
		}
	}
}

static int do_ddr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char *cmd = argv[1];

	if (argc == 1)
		cmd = "all";

	if (!strcmp(cmd, "wbdl") || !strcmp(cmd, "all"))
		wbdl_dump();

	if (!strcmp(cmd, "rbdl") || !strcmp(cmd, "all"))
		rbdl_dump();

	if (!strcmp(cmd, "wld") || !strcmp(cmd, "all"))
		wld_dump();

	if (!strcmp(cmd, "dqsgd") || !strcmp(cmd, "all"))
		dqsgd_dump();

	if (!strcmp(cmd, "mdl") || !strcmp(cmd, "all"))
		mdl_dump();

	if (!strcmp(cmd, "reg") || !strcmp(cmd, "all"))
		reg_dump();

	return 0;
}

U_BOOT_CMD(
	ddr,	2,	1,	do_ddr,
	"UniPhier DDR PHY parameters dumper",
	"- dump all of the followings\n"
	"ddr wbdl - dump Write Bit Delay\n"
	"ddr rbdl - dump Read Bit Delay\n"
	"ddr wld - dump Write Leveling\n"
	"ddr dqsgd - dump DQS Gating Delay\n"
	"ddr mdl - dump Master Delay Line\n"
	"ddr reg - dump registers\n"
);
