/*
 * Copyright (C) 2004-2008 Freescale Semiconductor, Inc.
 * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <config.h>
#include <net.h>
#include <netdev.h>

#ifdef CONFIG_MCF547x_8x
#include <asm/fsl_mcdmafec.h>
#else
#include <asm/fec.h>
#endif
#include <asm/immap.h>

DECLARE_GLOBAL_DATA_PTR;

#if defined(CONFIG_CMD_NET)
#undef MII_DEBUG
#undef ET_DEBUG

/*extern int fecpin_setclear(struct eth_device *dev, int setclear);*/

#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_CMD_MII)
#include <miiphy.h>

/* Make MII read/write commands for the FEC. */
#define mk_mii_read(ADDR, REG)		(0x60020000 | ((ADDR << 23) | \
					 (REG & 0x1f) << 18))
#define mk_mii_write(ADDR, REG, VAL)	(0x50020000 | ((ADDR << 23) | \
					 (REG & 0x1f) << 18) | (VAL & 0xffff))

#ifndef CONFIG_SYS_UNSPEC_PHYID
#	define CONFIG_SYS_UNSPEC_PHYID		0
#endif
#ifndef CONFIG_SYS_UNSPEC_STRID
#	define CONFIG_SYS_UNSPEC_STRID		0
#endif

#ifdef CONFIG_MCF547x_8x
typedef struct fec_info_dma FEC_INFO_T;
#define FEC_T fecdma_t
#else
typedef struct fec_info_s FEC_INFO_T;
#define FEC_T fec_t
#endif

typedef struct phy_info_struct {
	u32 phyid;
	char *strid;
} phy_info_t;

phy_info_t phyinfo[] = {
	{0x0022561B, "AMD79C784VC"},	/* AMD 79C784VC */
	{0x00406322, "BCM5222"},	/* Broadcom 5222 */
	{0x02a80150, "Intel82555"},	/* Intel 82555 */
	{0x0016f870, "LSI80225"},	/* LSI 80225 */
	{0x0016f880, "LSI80225/B"},	/* LSI 80225/B */
	{0x78100000, "LXT970"},		/* LXT970 */
	{0x001378e0, "LXT971"},		/* LXT971 and 972 */
	{0x00221619, "KS8721BL"},	/* Micrel KS8721BL/SL */
	{0x00221512, "KSZ8041NL"},	/* Micrel KSZ8041NL */
	{0x20005CE1, "N83640"},		/* National 83640 */
	{0x20005C90, "N83848"},		/* National 83848 */
	{0x20005CA2, "N83849"},		/* National 83849 */
	{0x01814400, "QS6612"},		/* QS6612 */
#if defined(CONFIG_SYS_UNSPEC_PHYID) && defined(CONFIG_SYS_UNSPEC_STRID)
	{CONFIG_SYS_UNSPEC_PHYID, CONFIG_SYS_UNSPEC_STRID},
#endif
	{0, 0}
};

/*
 * mii_init -- Initialize the MII for MII command without ethernet
 * This function is a subset of eth_init
 */
void mii_reset(FEC_INFO_T *info)
{
	volatile FEC_T *fecp = (FEC_T *) (info->miibase);
	int i;

	fecp->ecr = FEC_ECR_RESET;

	for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) {
		udelay(1);
	}
	if (i == FEC_RESET_DELAY)
		printf("FEC_RESET_DELAY timeout\n");
}

/* send command to phy using mii, wait for result */
uint mii_send(uint mii_cmd)
{
	FEC_INFO_T *info;
	volatile FEC_T *ep;
	struct eth_device *dev;
	uint mii_reply;
	int j = 0;

	/* retrieve from register structure */
	dev = eth_get_dev();
	info = dev->priv;

	ep = (FEC_T *) info->miibase;

	ep->mmfr = mii_cmd;	/* command to phy */

	/* wait for mii complete */
	while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) {
		udelay(1);
		j++;
	}
	if (j >= MCFFEC_TOUT_LOOP) {
		printf("MII not complete\n");
		return -1;
	}

	mii_reply = ep->mmfr;	/* result from phy */
	ep->eir = FEC_EIR_MII;	/* clear MII complete */
#ifdef ET_DEBUG
	printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
	       __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply);
#endif

	return (mii_reply & 0xffff);	/* data read from phy */
}
#endif				/* CONFIG_SYS_DISCOVER_PHY || (CONFIG_MII) */

#if defined(CONFIG_SYS_DISCOVER_PHY)
int mii_discover_phy(struct eth_device *dev)
{
#define MAX_PHY_PASSES 11
	FEC_INFO_T *info = dev->priv;
	int phyaddr, pass;
	uint phyno, phytype;
	int i, found = 0;

	if (info->phyname_init)
		return info->phy_addr;

	phyaddr = -1;		/* didn't find a PHY yet */
	for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
		if (pass > 1) {
			/* PHY may need more time to recover from reset.
			 * The LXT970 needs 50ms typical, no maximum is
			 * specified, so wait 10ms before try again.
			 * With 11 passes this gives it 100ms to wake up.
			 */
			udelay(10000);	/* wait 10ms */
		}

		for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {

			phytype = mii_send(mk_mii_read(phyno, MII_PHYSID1));
#ifdef ET_DEBUG
			printf("PHY type 0x%x pass %d type\n", phytype, pass);
#endif
			if (phytype == 0xffff)
				continue;
			phyaddr = phyno;
			phytype <<= 16;
			phytype |=
			    mii_send(mk_mii_read(phyno, MII_PHYSID2));

#ifdef ET_DEBUG
			printf("PHY @ 0x%x pass %d\n", phyno, pass);
#endif

			for (i = 0; (i < (sizeof(phyinfo) / sizeof(phy_info_t)))
				&& (phyinfo[i].phyid != 0); i++) {
				if (phyinfo[i].phyid == phytype) {
#ifdef ET_DEBUG
					printf("phyid %x - %s\n",
					       phyinfo[i].phyid,
					       phyinfo[i].strid);
#endif
					strcpy(info->phy_name, phyinfo[i].strid);
					info->phyname_init = 1;
					found = 1;
					break;
				}
			}

			if (!found) {
#ifdef ET_DEBUG
				printf("0x%08x\n", phytype);
#endif
				strcpy(info->phy_name, "unknown");
				info->phyname_init = 1;
				break;
			}
		}
	}

	if (phyaddr < 0)
		printf("No PHY device found.\n");

	return phyaddr;
}
#endif				/* CONFIG_SYS_DISCOVER_PHY */

void mii_init(void) __attribute__((weak,alias("__mii_init")));

void __mii_init(void)
{
	FEC_INFO_T *info;
	volatile FEC_T *fecp;
	struct eth_device *dev;
	int miispd = 0, i = 0;
	u16 status = 0;
	u16 linkgood = 0;

	/* retrieve from register structure */
	dev = eth_get_dev();
	info = dev->priv;

	fecp = (FEC_T *) info->miibase;

	fecpin_setclear(dev, 1);

	mii_reset(info);

	/* We use strictly polling mode only */
	fecp->eimr = 0;

	/* Clear any pending interrupt */
	fecp->eir = 0xffffffff;

	/* Set MII speed */
	miispd = (gd->bus_clk / 1000000) / 5;
	fecp->mscr = miispd << 1;

	info->phy_addr = mii_discover_phy(dev);

	while (i < MCFFEC_TOUT_LOOP) {
		status = 0;
		i++;
		/* Read PHY control register */
		miiphy_read(dev->name, info->phy_addr, MII_BMCR, &status);

		/* If phy set to autonegotiate, wait for autonegotiation done,
		 * if phy is not autonegotiating, just wait for link up.
		 */
		if ((status & BMCR_ANENABLE) == BMCR_ANENABLE) {
			linkgood = (BMSR_ANEGCOMPLETE | BMSR_LSTATUS);
		} else {
			linkgood = BMSR_LSTATUS;
		}
		/* Read PHY status register */
		miiphy_read(dev->name, info->phy_addr, MII_BMSR, &status);
		if ((status & linkgood) == linkgood)
			break;

		udelay(1);
	}
	if (i >= MCFFEC_TOUT_LOOP) {
		printf("Link UP timeout\n");
	}

	/* adapt to the duplex and speed settings of the phy */
	info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16;
	info->dup_spd |= miiphy_speed(dev->name, info->phy_addr);
}

/*
 * Read and write a MII PHY register, routines used by MII Utilities
 *
 * FIXME: These routines are expected to return 0 on success, but mii_send
 *	  does _not_ return an error code. Maybe 0xFFFF means error, i.e.
 *	  no PHY connected...
 *	  For now always return 0.
 * FIXME: These routines only work after calling eth_init() at least once!
 *	  Otherwise they hang in mii_send() !!! Sorry!
 */

int mcffec_miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
		       unsigned short *value)
{
	short rdreg;		/* register working value */

#ifdef MII_DEBUG
	printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
#endif
	rdreg = mii_send(mk_mii_read(addr, reg));

	*value = rdreg;

#ifdef MII_DEBUG
	printf("0x%04x\n", *value);
#endif

	return 0;
}

int mcffec_miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
			unsigned short value)
{
#ifdef MII_DEBUG
	printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr);
#endif

	mii_send(mk_mii_write(addr, reg, value));

#ifdef MII_DEBUG
	printf("0x%04x\n", value);
#endif

	return 0;
}

#endif				/* CONFIG_CMD_NET */
