/*
 * Xilinx PCS/PMA Core phy driver
 *
 * Copyright (C) 2015 - 2016 Xilinx, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <config.h>
#include <common.h>
#include <phy.h>
#include <dm.h>

DECLARE_GLOBAL_DATA_PTR;

#define MII_PHY_STATUS_SPD_MASK		0x0C00
#define MII_PHY_STATUS_FULLDUPLEX	0x1000
#define MII_PHY_STATUS_1000		0x0800
#define MII_PHY_STATUS_100		0x0400
#define XPCSPMA_PHY_CTRL_ISOLATE_DISABLE 0xFBFF

/* Mask used for ID comparisons */
#define XILINX_PHY_ID_MASK		0xfffffff0

/* Known PHY IDs */
#define XILINX_PHY_ID			0x01740c00

/* struct phy_device dev_flags definitions */
#define XAE_PHY_TYPE_MII		0
#define XAE_PHY_TYPE_GMII		1
#define XAE_PHY_TYPE_RGMII_1_3		2
#define XAE_PHY_TYPE_RGMII_2_0		3
#define XAE_PHY_TYPE_SGMII		4
#define XAE_PHY_TYPE_1000BASE_X		5

static int xilinxphy_startup(struct phy_device *phydev)
{
	int err;
	int status = 0;

	debug("%s\n", __func__);
	/* Update the link, but return if there
	 * was an error
	 */
	err = genphy_update_link(phydev);
	if (err)
		return err;

	if (AUTONEG_ENABLE == phydev->autoneg) {
		status = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
		status = status & MII_PHY_STATUS_SPD_MASK;

		if (status & MII_PHY_STATUS_FULLDUPLEX)
			phydev->duplex = DUPLEX_FULL;
		else
			phydev->duplex = DUPLEX_HALF;

		switch (status) {
		case MII_PHY_STATUS_1000:
			phydev->speed = SPEED_1000;
			break;

		case MII_PHY_STATUS_100:
			phydev->speed = SPEED_100;
			break;

		default:
			phydev->speed = SPEED_10;
			break;
		}
	} else {
		int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);

		if (bmcr < 0)
			return bmcr;

		if (bmcr & BMCR_FULLDPLX)
			phydev->duplex = DUPLEX_FULL;
		else
			phydev->duplex = DUPLEX_HALF;

		if (bmcr & BMCR_SPEED1000)
			phydev->speed = SPEED_1000;
		else if (bmcr & BMCR_SPEED100)
			phydev->speed = SPEED_100;
		else
			phydev->speed = SPEED_10;
	}

	/*
	 * For 1000BASE-X Phy Mode the speed/duplex will always be
	 * 1000Mbps/fullduplex
	 */
	if (phydev->flags == XAE_PHY_TYPE_1000BASE_X) {
		phydev->duplex = DUPLEX_FULL;
		phydev->speed = SPEED_1000;
	}

	return 0;
}

static int xilinxphy_of_init(struct phy_device *phydev)
{
	u32 phytype;

	debug("%s\n", __func__);
	phytype = fdtdec_get_int(gd->fdt_blob, dev_of_offset(phydev->dev),
				 "xlnx,phy-type", -1);
	if (phytype == XAE_PHY_TYPE_1000BASE_X)
		phydev->flags |= XAE_PHY_TYPE_1000BASE_X;

	return 0;
}

static int xilinxphy_config(struct phy_device *phydev)
{
	int temp;

	debug("%s\n", __func__);
	xilinxphy_of_init(phydev);
	temp = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
	temp &= XPCSPMA_PHY_CTRL_ISOLATE_DISABLE;
	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, temp);

	return 0;
}

static struct phy_driver xilinxphy_driver = {
	.uid = XILINX_PHY_ID,
	.mask = XILINX_PHY_ID_MASK,
	.name = "Xilinx PCS/PMA PHY",
	.features = PHY_GBIT_FEATURES,
	.config = &xilinxphy_config,
	.startup = &xilinxphy_startup,
	.shutdown = &genphy_shutdown,
};

int phy_xilinx_init(void)
{
	debug("%s\n", __func__);
	phy_register(&xilinxphy_driver);

	return 0;
}
