/*
 * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.

 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.

 * 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.
*/

#include <common.h>
#include <miiphy.h>
#include <phy.h>
#include <asm/io.h>
#include <errno.h>
#include "ipq40xx_mdio.h"

struct ipq40xx_mdio_data {
	struct mii_bus *bus;
	int phy_irq[PHY_MAX_ADDR];
};

static int ipq40xx_mdio_wait_busy(void)
{
	int i;
	u32 busy;
	for (i = 0; i < IPQ40XX_MDIO_RETRY; i++) {
		udelay(IPQ40XX_MDIO_DELAY);
		busy = readl(IPQ40XX_MDIO_BASE +
			MDIO_CTRL_4_REG) &
			MDIO_CTRL_4_ACCESS_BUSY;

		if (!busy)
			return 0;
		udelay(IPQ40XX_MDIO_DELAY);
	}
	printf("%s: MDIO operation timed out\n",
			__func__);
	return -ETIMEDOUT;
}

int ipq40xx_mdio_write(int mii_id, int regnum, u16 value)
{
	if (ipq40xx_mdio_wait_busy())
		return -ETIMEDOUT;
	/* Issue the phy addreass and reg */
	writel((mii_id << 8 | regnum),
		IPQ40XX_MDIO_BASE + MDIO_CTRL_1_REG);

	/* Issue a write data */
	writel(value, IPQ40XX_MDIO_BASE + MDIO_CTRL_2_REG);

	/* Issue write command */
	writel((MDIO_CTRL_4_ACCESS_START |
		MDIO_CTRL_4_ACCESS_CODE_WRITE),
		(IPQ40XX_MDIO_BASE + MDIO_CTRL_4_REG));

	/* Wait for write complete */

	if (ipq40xx_mdio_wait_busy())
		return -ETIMEDOUT;

	return 0;
}

int ipq40xx_mdio_read(int mii_id, int regnum, ushort *data)
{
	u32 val;
	if (ipq40xx_mdio_wait_busy())
		return -ETIMEDOUT;

	/* Issue the phy address and reg */
	writel((mii_id << 8) | regnum,
		IPQ40XX_MDIO_BASE + MDIO_CTRL_1_REG);

	/* issue read command */
	writel((MDIO_CTRL_4_ACCESS_START |
		MDIO_CTRL_4_ACCESS_CODE_READ),
		(IPQ40XX_MDIO_BASE + MDIO_CTRL_4_REG));

	if (ipq40xx_mdio_wait_busy())
		return -ETIMEDOUT;

	/* Read data */
	val = readl(IPQ40XX_MDIO_BASE + MDIO_CTRL_3_REG);

	if (data != NULL)
		*data = val;

	return val;
}

int ipq40xx_phy_write(struct mii_dev *bus,
		int addr, int dev_addr,
		int regnum, ushort value)
{
	return ipq40xx_mdio_write(
		addr, regnum, value);
}

int ipq40xx_phy_read(struct mii_dev *bus,
		int addr, int dev_addr, int regnum)
{
	return ipq40xx_mdio_read(
		addr, regnum, NULL);
}

int ipq40xx_sw_mdio_init(const char *name)
{
	struct mii_dev *bus = mdio_alloc();
	if(!bus) {
		printf("Failed to allocate IPQ MDIO bus\n");
		return -1;
	}
	bus->read = ipq40xx_phy_read;
	bus->write = ipq40xx_phy_write;
	bus->reset = NULL;
	snprintf(bus->name, MDIO_NAME_LEN, name);
	return mdio_register(bus);
}

