// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2012
 * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
 */

#include <common.h>
#include <miiphy.h>
#include <linux/errno.h>
#include <mv88e6352.h>

#define SMI_HDR		((0x8 | 0x1) << 12)
#define SMI_BUSY_MASK	(0x8000)
#define SMIRD_OP	(0x2 << 10)
#define SMIWR_OP	(0x1 << 10)
#define SMI_MASK	0x1f
#define PORT_SHIFT	5

#define COMMAND_REG	0
#define DATA_REG	1

/* global registers */
#define GLOBAL		0x1b

#define GLOBAL_STATUS	0x00
#define PPU_STATE	0x8000

#define GLOBAL_CTRL	0x04
#define SW_RESET	0x8000
#define PPU_ENABLE	0x4000

static int sw_wait_rdy(const char *devname, u8 phy_addr)
{
	u16 command;
	u32 timeout = 100;
	int ret;

	/* wait till the SMI is not busy */
	do {
		/* read command register */
		ret = miiphy_read(devname, phy_addr, COMMAND_REG, &command);
		if (ret < 0) {
			printf("%s: Error reading command register\n",
				__func__);
			return ret;
		}
		if (timeout-- == 0) {
			printf("Err..(%s) SMI busy timeout\n", __func__);
			return -EFAULT;
		}
	} while (command & SMI_BUSY_MASK);

	return 0;
}

static int sw_reg_read(const char *devname, u8 phy_addr, u8 port,
	u8 reg, u16 *data)
{
	int ret;
	u16 command;

	ret = sw_wait_rdy(devname, phy_addr);
	if (ret)
		return ret;

	command = SMI_HDR | SMIRD_OP | ((port&SMI_MASK) << PORT_SHIFT) |
			(reg & SMI_MASK);
	debug("%s: write to command: %#x\n", __func__, command);
	ret = miiphy_write(devname, phy_addr, COMMAND_REG, command);
	if (ret)
		return ret;

	ret = sw_wait_rdy(devname, phy_addr);
	if (ret)
		return ret;

	ret = miiphy_read(devname, phy_addr, DATA_REG, data);

	return ret;
}

static int sw_reg_write(const char *devname, u8 phy_addr, u8 port,
	u8 reg, u16 data)
{
	int ret;
	u16 value;

	ret = sw_wait_rdy(devname, phy_addr);
	if (ret)
		return ret;

	debug("%s: write to data: %#x\n", __func__, data);
	ret = miiphy_write(devname, phy_addr, DATA_REG, data);
	if (ret)
		return ret;

	value = SMI_HDR | SMIWR_OP | ((port & SMI_MASK) << PORT_SHIFT) |
			(reg & SMI_MASK);
	debug("%s: write to command: %#x\n", __func__, value);
	ret = miiphy_write(devname, phy_addr, COMMAND_REG, value);
	if (ret)
		return ret;

	ret = sw_wait_rdy(devname, phy_addr);
	if (ret)
		return ret;

	return 0;
}

static int ppu_enable(const char *devname, u8 phy_addr)
{
	int i, ret = 0;
	u16 reg;

	ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, &reg);
	if (ret) {
		printf("%s: Error reading global ctrl reg\n", __func__);
		return ret;
	}

	reg |= PPU_ENABLE;

	ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg);
	if (ret) {
		printf("%s: Error writing global ctrl reg\n", __func__);
		return ret;
	}

	for (i = 0; i < 1000; i++) {
		sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS,
			&reg);
		if ((reg & 0xc000) == 0xc000)
			return 0;
		udelay(1000);
	}

	return -ETIMEDOUT;
}

static int ppu_disable(const char *devname, u8 phy_addr)
{
	int i, ret = 0;
	u16 reg;

	ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, &reg);
	if (ret) {
		printf("%s: Error reading global ctrl reg\n", __func__);
		return ret;
	}

	reg &= ~PPU_ENABLE;

	ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg);
	if (ret) {
		printf("%s: Error writing global ctrl reg\n", __func__);
		return ret;
	}

	for (i = 0; i < 1000; i++) {
		sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS,
			&reg);
		if ((reg & 0xc000) != 0xc000)
			return 0;
		udelay(1000);
	}

	return -ETIMEDOUT;
}

int mv88e_sw_program(const char *devname, u8 phy_addr,
	struct mv88e_sw_reg *regs, int regs_nb)
{
	int i, ret = 0;

	/* first we need to disable the PPU */
	ret = ppu_disable(devname, phy_addr);
	if (ret) {
		printf("%s: Error disabling PPU\n", __func__);
		return ret;
	}

	for (i = 0; i < regs_nb; i++) {
		ret = sw_reg_write(devname, phy_addr, regs[i].port,
			regs[i].reg, regs[i].value);
		if (ret) {
			printf("%s: Error configuring switch\n", __func__);
			ppu_enable(devname, phy_addr);
			return ret;
		}
	}

	/* re-enable the PPU */
	ret = ppu_enable(devname, phy_addr);
	if (ret) {
		printf("%s: Error enabling PPU\n", __func__);
		return ret;
	}

	return 0;
}

int mv88e_sw_reset(const char *devname, u8 phy_addr)
{
	int i, ret = 0;
	u16 reg;

	ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, &reg);
	if (ret) {
		printf("%s: Error reading global ctrl reg\n", __func__);
		return ret;
	}

	reg = SW_RESET | PPU_ENABLE | 0x0400;

	ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg);
	if (ret) {
		printf("%s: Error writing global ctrl reg\n", __func__);
		return ret;
	}

	for (i = 0; i < 1000; i++) {
		sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS,
			&reg);
		if ((reg & 0xc800) != 0xc800)
			return 0;
		udelay(1000);
	}

	return -ETIMEDOUT;
}

int do_mvsw_reg_read(const char *name, int argc, char * const argv[])
{
	u16 value = 0, phyaddr, reg, port;
	int ret;

	phyaddr = simple_strtoul(argv[1], NULL, 10);
	port = simple_strtoul(argv[2], NULL, 10);
	reg = simple_strtoul(argv[3], NULL, 10);

	ret = sw_reg_read(name, phyaddr, port, reg, &value);
	printf("%#x\n", value);

	return ret;
}

int do_mvsw_reg_write(const char *name, int argc, char * const argv[])
{
	u16 value = 0, phyaddr, reg, port;
	int ret;

	phyaddr = simple_strtoul(argv[1], NULL, 10);
	port = simple_strtoul(argv[2], NULL, 10);
	reg = simple_strtoul(argv[3], NULL, 10);
	value = simple_strtoul(argv[4], NULL, 16);

	ret = sw_reg_write(name, phyaddr, port, reg, value);

	return ret;
}


int do_mvsw_reg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int ret;
	const char *cmd, *ethname;

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

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

	if (strcmp(cmd, "read") == 0) {
		if (argc < 5)
			return cmd_usage(cmdtp);
		ethname = argv[1];
		--argc;
		++argv;
		ret = do_mvsw_reg_read(ethname, argc, argv);
	} else if (strcmp(cmd, "write") == 0) {
		if (argc < 6)
			return cmd_usage(cmdtp);
		ethname = argv[1];
		--argc;
		++argv;
		ret = do_mvsw_reg_write(ethname, argc, argv);
	} else
		return cmd_usage(cmdtp);

	return ret;
}

U_BOOT_CMD(
	mvsw_reg,	7,	1,	do_mvsw_reg,
	"marvell 88e6352 switch register access",
	"write ethname phyaddr port reg value\n"
	"mvsw_reg read  ethname phyaddr port reg\n"
	);
