// SPDX-License-Identifier: GPL-2.0+
/*
 * Commands to deal with Synology specifics.
 *
 * Copyright (C) 2015  Phil Sutter <phil@nwl.cc>
 */

#include <command.h>
#include <div64.h>
#include <env.h>
#include <net.h>
#include <spi.h>
#include <spi_flash.h>
#include <linux/mtd/mtd.h>

#include <asm/io.h>
#include "../drivers/ddr/marvell/axp/ddr3_init.h"

#include "cmd_syno.h"

int do_syno_populate(int argc, char *const argv[])
{
	unsigned int bus = CONFIG_SF_DEFAULT_BUS;
	unsigned int cs = CONFIG_SF_DEFAULT_CS;
	unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
	unsigned int mode = CONFIG_SF_DEFAULT_MODE;
	struct spi_flash *flash;
	unsigned long addr = 0x80000; /* XXX: parameterize this? */
	loff_t offset = 0x007d0000;
	loff_t len = 0x00010000;
	char *buf, *bufp;
	char var[128];
	char val[128];
	int ret, n;

	/* XXX: arg parsing to select flash here? */

	flash = spi_flash_probe(bus, cs, speed, mode);
	if (!flash) {
		printf("Failed to initialize SPI flash at %u:%u\n", bus, cs);
		return 1;
	}

	buf = map_physmem(addr, len, MAP_WRBACK);
	if (!buf) {
		puts("Failed to map physical memory\n");
		return 1;
	}

	ret = spi_flash_read(flash, offset, len, buf);
	if (ret) {
		puts("Failed to read from SPI flash\n");
		goto out_unmap;
	}

	for (n = 0; n < SYNO_ETHADDR_MAX; n++) {
		char ethaddr[ETH_ALEN];
		int i, sum = 0;
		unsigned char csum = 0;

		for (i = 0, bufp = buf + n * 7; i < ETH_ALEN; i++) {
			sum += bufp[i];
			csum += bufp[i];
			ethaddr[i] = bufp[i];
		}
		if (!sum)		/* MAC address empty */
			continue;
		if (csum != bufp[i]) {	/* seventh byte is checksum value */
			printf("Invalid MAC address for interface %d!\n", n);
			continue;
		}
		if (n == 0)
			sprintf(var, "ethaddr");
		else
			sprintf(var, "eth%daddr", n);
		snprintf(val, sizeof(val) - 1,
		         "%02x:%02x:%02x:%02x:%02x:%02x",
		         ethaddr[0], ethaddr[1], ethaddr[2],
			 ethaddr[3], ethaddr[4], ethaddr[5]);
		printf("parsed %s = %s\n", var, val);
		env_set(var, val);
	}
	if (!strncmp(buf + 32, SYNO_SN_TAG, strlen(SYNO_SN_TAG))) {
		char *snp, *csump;
		int csum = 0;
		unsigned long c;

		snp = bufp = buf + 32 + strlen(SYNO_SN_TAG);
		for (n = 0; bufp[n] && bufp[n] != ','; n++)
			csum += bufp[n];
		bufp[n] = '\0';

		/* should come right after, but you never know */
		bufp = strstr(bufp + n + 1, SYNO_CHKSUM_TAG);
		if (!bufp) {
			printf("Serial number checksum tag missing!\n");
			goto out_unmap;
		}

		csump = bufp += strlen(SYNO_CHKSUM_TAG);
		for (n = 0; bufp[n] && bufp[n] != ','; n++)
			;
		bufp[n] = '\0';

		if (strict_strtoul(csump, 10, &c) || c != csum) {
			puts("Invalid serial number found!\n");
			ret = 1;
			goto out_unmap;
		}
		printf("parsed SN = %s\n", snp);
		env_set("SN", snp);
	} else {	/* old style format */
		unsigned char csum = 0;

		for (n = 0, bufp = buf + 32; n < 10; n++)
			csum += bufp[n];

		if (csum != bufp[n]) {
			puts("Invalid serial number found!\n");
			ret = 1;
			goto out_unmap;
		}
		bufp[n] = '\0';
		printf("parsed SN = %s\n", buf + 32);
		env_set("SN", buf + 32);
	}
out_unmap:
	unmap_physmem(buf, len);
	return ret;
}

/* map bit position to function in POWER_MNG_CTRL_REG */
static const char * const pwr_mng_bit_func[] = {
	"audio",
	"ge3", "ge2", "ge1", "ge0",
	"pcie00", "pcie01", "pcie02", "pcie03",
	"pcie10", "pcie11", "pcie12", "pcie13",
	"bp",
	"sata0_link", "sata0_core",
	"lcd",
	"sdio",
	"usb0", "usb1", "usb2",
	"idma", "xor0", "crypto",
	NULL,
	"tdm",
	"pcie20", "pcie30",
	"xor1",
	"sata1_link", "sata1_core",
	NULL,
};

static int do_syno_clk_gate(int argc, char *const argv[])
{
	u32 pwr_mng_ctrl_reg = reg_read(POWER_MNG_CTRL_REG);
	const char *func, *state;
	int i, val;

	if (argc < 2)
		return -1;

	if (!strcmp(argv[1], "get")) {
		puts("Clock Gating:\n");
		for (i = 0; i < 32; i++) {
			func = pwr_mng_bit_func[i];
			if (!func)
				continue;
			state = pwr_mng_ctrl_reg & (1 << i) ?  "ON" : "OFF";
			printf("%s:\t\t%s\n", func, state);
		}
		return 0;
	}
	if (argc < 4)
		return -1;
	if (!strcmp(argv[1], "set")) {
		func = argv[2];
		state = argv[3];
		for (i = 0; i < 32; i++) {
			if (!pwr_mng_bit_func[i])
				continue;
			if (!strcmp(func, pwr_mng_bit_func[i]))
				break;
		}
		if (i == 32) {
			printf("Error: name '%s' not known\n", func);
			return -1;
		}
		val = state[0] != '0';
		pwr_mng_ctrl_reg |= (val << i);
		pwr_mng_ctrl_reg &= ~(!val << i);
		reg_write(POWER_MNG_CTRL_REG, pwr_mng_ctrl_reg);
	}
	return 0;
}

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

	if (argc < 2)
		goto usage;

	cmd = argv[1];
	--argc;
	++argv;

	if (!strcmp(cmd, "populate_env"))
		ret = do_syno_populate(argc, argv);
	else if (!strcmp(cmd, "clk_gate"))
		ret = do_syno_clk_gate(argc, argv);

	if (ret != -1)
		return ret;
usage:
	return CMD_RET_USAGE;
}

U_BOOT_CMD(
	syno, 5, 1, do_syno,
	"Synology specific commands",
	"populate_env                 - Read vendor data from SPI flash into environment\n"
	"clk_gate (get|set name 1|0)  - Manage clock gating\n"
);
