/*
 * Copyright 2009-2011 Freescale Semiconductor, Inc.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <command.h>
#include <netdev.h>
#include <asm/mmu.h>
#include <asm/processor.h>
#include <asm/cache.h>
#include <asm/immap_85xx.h>
#include <asm/fsl_law.h>
#include <asm/fsl_ddr_sdram.h>
#include <asm/fsl_serdes.h>
#include <asm/fsl_portals.h>
#include <asm/fsl_liodn.h>
#include <malloc.h>
#include <fm_eth.h>
#include <fsl_mdio.h>
#include <miiphy.h>
#include <phy.h>

#include "../common/ngpixis.h"
#include "../common/fman.h"
#include <asm/fsl_dtsec.h>

#define EMI_NONE	0xffffffff
#define EMI_MASK	0xf0000000
#define EMI1_RGMII	0x0
#define EMI1_SLOT3	0x80000000	/* bank1 EFGH */
#define EMI1_SLOT4	0x40000000	/* bank2 ABCD */
#define EMI1_SLOT5	0xc0000000	/* bank3 ABCD */
#define EMI2_SLOT4	0x10000000	/* bank2 ABCD */
#define EMI2_SLOT5	0x30000000	/* bank3 ABCD */
#define EMI1_MASK	0xc0000000
#define EMI2_MASK	0x30000000

static int mdio_mux[NUM_FM_PORTS];

static char *mdio_names[16] = {
	"P4080DS_MDIO0",
	"P4080DS_MDIO1",
	NULL,
	"P4080DS_MDIO3",
	"P4080DS_MDIO4",
	NULL, NULL, NULL,
	"P4080DS_MDIO8",
	NULL, NULL, NULL,
	"P4080DS_MDIO12",
	NULL, NULL, NULL,
};

/*
 * Mapping of all 18 SERDES lanes to board slots. A value of '0' here means
 * that the mapping must be determined dynamically, or that the lane maps to
 * something other than a board slot.
 */
static u8 lane_to_slot[] = {
	1, 1, 2, 2, 3, 3, 3, 3, 6, 6, 4, 4, 4, 4, 5, 5, 5, 5
};

static char *p4080ds_mdio_name_for_muxval(u32 muxval)
{
	return mdio_names[(muxval & EMI_MASK) >> 28];
}

struct mii_dev *mii_dev_for_muxval(u32 muxval)
{
	struct mii_dev *bus;
	char *name = p4080ds_mdio_name_for_muxval(muxval);

	if (!name) {
		printf("No bus for muxval %x\n", muxval);
		return NULL;
	}

	bus = miiphy_get_dev_by_name(name);

	if (!bus) {
		printf("No bus by name %s\n", name);
		return NULL;
	}

	return bus;
}

#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) && defined(CONFIG_PHY_TERANETICS)
int board_phy_config(struct phy_device *phydev)
{
	if (phydev->drv->config)
		phydev->drv->config(phydev);
	if (phydev->drv->uid == PHY_UID_TN2020) {
		unsigned long timeout = 1 * 1000; /* 1 seconds */
		enum srds_prtcl device;

		/*
		 * Wait for the XAUI to come out of reset.  This is when it
		 * starts transmitting alignment signals.
		 */
		while (--timeout) {
			int reg = phy_read(phydev, MDIO_MMD_PHYXS, MDIO_CTRL1);
			if (reg < 0) {
				printf("TN2020: Error reading from PHY at "
				       "address %u\n", phydev->addr);
				break;
			}
			/*
			 * Note that we've never actually seen
			 * MDIO_CTRL1_RESET set to 1.
			 */
			if ((reg & MDIO_CTRL1_RESET) == 0)
				break;
			udelay(1000);
		}

		if (!timeout) {
			printf("TN2020: Timeout waiting for PHY at address %u "
			       " to reset.\n", phydev->addr);
		}

		switch (phydev->addr) {
		case CONFIG_SYS_FM1_10GEC1_PHY_ADDR:
			device = XAUI_FM1;
			break;
		case CONFIG_SYS_FM2_10GEC1_PHY_ADDR:
			device = XAUI_FM2;
			break;
		default:
			device = NONE;
		}

		serdes_reset_rx(device);
	}

	return 0;
}
#endif

struct p4080ds_mdio {
	u32 muxval;
	struct mii_dev *realbus;
};

static void p4080ds_mux_mdio(u32 muxval)
{
	ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
	uint gpioval = in_be32(&pgpio->gpdat) & ~(EMI_MASK);
	gpioval |= muxval;

	out_be32(&pgpio->gpdat, gpioval);
}

static int p4080ds_mdio_read(struct mii_dev *bus, int addr, int devad,
				int regnum)
{
	struct p4080ds_mdio *priv = bus->priv;

	p4080ds_mux_mdio(priv->muxval);

	return priv->realbus->read(priv->realbus, addr, devad, regnum);
}

static int p4080ds_mdio_write(struct mii_dev *bus, int addr, int devad,
				int regnum, u16 value)
{
	struct p4080ds_mdio *priv = bus->priv;

	p4080ds_mux_mdio(priv->muxval);

	return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
}

static int p4080ds_mdio_reset(struct mii_dev *bus)
{
	struct p4080ds_mdio *priv = bus->priv;

	return priv->realbus->reset(priv->realbus);
}

static int p4080ds_mdio_init(char *realbusname, u32 muxval)
{
	struct p4080ds_mdio *pmdio;
	struct mii_dev *bus = mdio_alloc();

	if (!bus) {
		printf("Failed to allocate P4080DS MDIO bus\n");
		return -1;
	}

	pmdio = malloc(sizeof(*pmdio));
	if (!pmdio) {
		printf("Failed to allocate P4080DS private data\n");
		free(bus);
		return -1;
	}

	bus->read = p4080ds_mdio_read;
	bus->write = p4080ds_mdio_write;
	bus->reset = p4080ds_mdio_reset;
	sprintf(bus->name, p4080ds_mdio_name_for_muxval(muxval));

	pmdio->realbus = miiphy_get_dev_by_name(realbusname);

	if (!pmdio->realbus) {
		printf("No bus with name %s\n", realbusname);
		free(bus);
		free(pmdio);
		return -1;
	}

	pmdio->muxval = muxval;
	bus->priv = pmdio;

	return mdio_register(bus);
}

void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa,
				enum fm_port port, int offset)
{
	if (mdio_mux[port] == EMI1_RGMII)
		fdt_set_phy_handle(blob, prop, pa, "phy_rgmii");

	if (mdio_mux[port] == EMI1_SLOT3) {
		int idx = port - FM2_DTSEC1 + 5;
		char phy[16];

		sprintf(phy, "phy%d_slot3", idx);

		fdt_set_phy_handle(blob, prop, pa, phy);
	}
}

void fdt_fixup_board_enet(void *fdt)
{
	int i;

	/*
	 * P4080DS can be configured in many different ways, supporting a number
	 * of combinations of ethernet devices and phy types.  In order to
	 * have just one device tree for all of those configurations, we fix up
	 * the tree here.  By default, the device tree configures FM1 and FM2
	 * for SGMII, and configures XAUI on both 10G interfaces.  So we have
	 * a number of different variables to track:
	 *
	 * 1) Whether the device is configured at all.  Whichever devices are
	 *    not enabled should be disabled by setting the "status" property
	 *    to "disabled".
	 * 2) What the PHY interface is.  If this is an RGMII connection,
	 *    we should change the "phy-connection-type" property to
	 *    "rgmii"
	 * 3) Which PHY is being used.  Because the MDIO buses are muxed,
	 *    we need to redirect the "phy-handle" property to point at the
	 *    PHY on the right slot/bus.
	 */

	/* We've got six MDIO nodes that may or may not need to exist */
	fdt_status_disabled_by_alias(fdt, "emi1_slot3");
	fdt_status_disabled_by_alias(fdt, "emi1_slot4");
	fdt_status_disabled_by_alias(fdt, "emi1_slot5");
	fdt_status_disabled_by_alias(fdt, "emi2_slot4");
	fdt_status_disabled_by_alias(fdt, "emi2_slot5");

	for (i = 0; i < NUM_FM_PORTS; i++) {
		switch (mdio_mux[i]) {
		case EMI1_SLOT3:
			fdt_status_okay_by_alias(fdt, "emi1_slot3");
			break;
		case EMI1_SLOT4:
			fdt_status_okay_by_alias(fdt, "emi1_slot4");
			break;
		case EMI1_SLOT5:
			fdt_status_okay_by_alias(fdt, "emi1_slot5");
			break;
		case EMI2_SLOT4:
			fdt_status_okay_by_alias(fdt, "emi2_slot4");
			break;
		case EMI2_SLOT5:
			fdt_status_okay_by_alias(fdt, "emi2_slot5");
			break;
		}
	}
}

int board_eth_init(bd_t *bis)
{
#ifdef CONFIG_FMAN_ENET
	ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
	int i;
	struct fsl_pq_mdio_info dtsec_mdio_info;
	struct tgec_mdio_info tgec_mdio_info;

	/* Initialize the mdio_mux array so we can recognize empty elements */
	for (i = 0; i < NUM_FM_PORTS; i++)
		mdio_mux[i] = EMI_NONE;

	/* The first 4 GPIOs are outputs to control MDIO bus muxing */
	out_be32(&pgpio->gpdir, EMI_MASK);

	dtsec_mdio_info.regs =
		(struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
	dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;

	/* Register the 1G MDIO bus */
	fsl_pq_mdio_init(bis, &dtsec_mdio_info);

	tgec_mdio_info.regs =
		(struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
	tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;

	/* Register the 10G MDIO bus */
	fm_tgec_mdio_init(bis, &tgec_mdio_info);

	/* Register the 6 muxing front-ends to the MDIO buses */
	p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII);
	p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
	p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
	p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
	p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT4);
	p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT5);

	fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR);
	fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR);
	fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR);
	fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
	fm_info_set_phy_address(FM1_10GEC1, CONFIG_SYS_FM1_10GEC1_PHY_ADDR);

#if (CONFIG_SYS_NUM_FMAN == 2)
	fm_info_set_phy_address(FM2_DTSEC1, CONFIG_SYS_FM2_DTSEC1_PHY_ADDR);
	fm_info_set_phy_address(FM2_DTSEC2, CONFIG_SYS_FM2_DTSEC2_PHY_ADDR);
	fm_info_set_phy_address(FM2_DTSEC3, CONFIG_SYS_FM2_DTSEC3_PHY_ADDR);
	fm_info_set_phy_address(FM2_DTSEC4, CONFIG_SYS_FM2_DTSEC4_PHY_ADDR);
	fm_info_set_phy_address(FM2_10GEC1, CONFIG_SYS_FM2_10GEC1_PHY_ADDR);
#endif

	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
		int idx = i - FM1_DTSEC1, lane, slot;
		switch (fm_info_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_SGMII:
			lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
			if (lane < 0)
				break;
			slot = lane_to_slot[lane];
			switch (slot) {
			case 3:
				mdio_mux[i] = EMI1_SLOT3;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			case 4:
				mdio_mux[i] = EMI1_SLOT4;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			case 5:
				mdio_mux[i] = EMI1_SLOT5;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			};
			break;
		case PHY_INTERFACE_MODE_RGMII:
			fm_info_set_phy_address(i, 0);
			mdio_mux[i] = EMI1_RGMII;
			fm_info_set_mdio(i,
				mii_dev_for_muxval(mdio_mux[i]));
			break;
		default:
			break;
		}
	}

	for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
		int idx = i - FM1_10GEC1, lane, slot;
		switch (fm_info_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_XGMII:
			lane = serdes_get_first_lane(XAUI_FM1 + idx);
			if (lane < 0)
				break;
			slot = lane_to_slot[lane];
			switch (slot) {
			case 4:
				mdio_mux[i] = EMI2_SLOT4;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			case 5:
				mdio_mux[i] = EMI2_SLOT5;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			};
			break;
		default:
			break;
		}
	}

#if (CONFIG_SYS_NUM_FMAN == 2)
	for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
		int idx = i - FM2_DTSEC1, lane, slot;
		switch (fm_info_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_SGMII:
			lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
			if (lane < 0)
				break;
			slot = lane_to_slot[lane];
			switch (slot) {
			case 3:
				mdio_mux[i] = EMI1_SLOT3;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			case 4:
				mdio_mux[i] = EMI1_SLOT4;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			case 5:
				mdio_mux[i] = EMI1_SLOT5;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			};
			break;
		case PHY_INTERFACE_MODE_RGMII:
			fm_info_set_phy_address(i, 0);
			mdio_mux[i] = EMI1_RGMII;
			fm_info_set_mdio(i,
				mii_dev_for_muxval(mdio_mux[i]));
			break;
		default:
			break;
		}
	}

	for (i = FM2_10GEC1; i < FM2_10GEC1 + CONFIG_SYS_NUM_FM2_10GEC; i++) {
		int idx = i - FM2_10GEC1, lane, slot;
		switch (fm_info_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_XGMII:
			lane = serdes_get_first_lane(XAUI_FM2 + idx);
			if (lane < 0)
				break;
			slot = lane_to_slot[lane];
			switch (slot) {
			case 4:
				mdio_mux[i] = EMI2_SLOT4;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			case 5:
				mdio_mux[i] = EMI2_SLOT5;
				fm_info_set_mdio(i,
					mii_dev_for_muxval(mdio_mux[i]));
				break;
			};
			break;
		default:
			break;
		}
	}
#endif

	cpu_eth_init(bis);
#endif /* CONFIG_FMAN_ENET */

	return pci_eth_init(bis);
}
