/*
 * (C) Copyright 2012
 * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA
 */

#include <common.h>
#include <miiphy.h>
#include <asm/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"
	);
