/*
 * Copyright 2009-2011 Freescale Semiconductor, Inc.
 * Author: Timur Tabi <timur@freescale.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * This file handles the board muxing between the Fman Ethernet MACs and
 * the RGMII/SGMII/XGMII PHYs on a Freescale P3041/P5020 "Hydra" reference
 * board. The RGMII PHYs are the two on-board 1Gb ports.  The SGMII PHYs are
 * provided by the standard Freescale four-port SGMII riser card.  The 10Gb
 * XGMII PHY is provided via the XAUI riser card.  Since there is only one
 * Fman device on a P3041 and P5020, we only support one SGMII card and one
 * RGMII card.
 *
 * Muxing is handled via the PIXIS BRDCFG1 register.  The EMI1 bits control
 * muxing among the RGMII PHYs and the SGMII PHYs.  The value for RGMII is
 * always the same (0).  The value for SGMII depends on which slot the riser is
 * inserted in.  The EMI2 bits control muxing for the the XGMII.  Like SGMII,
 * the value is based on which slot the XAUI is inserted in.
 *
 * The SERDES configuration is used to determine where the SGMII and XAUI cards
 * exist, and also which Fman MACs are routed to which PHYs.  So for a given
 * Fman MAC, there is one and only PHY it connects to.  MACs cannot be routed
 * to PHYs dynamically.
 *
 *
 * This file also updates the device tree in three ways:
 *
 * 1) The status of each virtual MDIO node that is referenced by an Ethernet
 *    node is set to "okay".
 *
 * 2) The phy-handle property of each active Ethernet MAC node is set to the
 *    appropriate PHY node.
 *
 * 3) The "mux value" for each virtual MDIO node is set to the correct value,
 *    if necessary.  Some virtual MDIO nodes do not have configurable mux
 *    values, so those values are hard-coded in the DTS.  On the HYDRA board,
 *    the virtual MDIO node for the SGMII card needs to be updated.
 *
 * For all this to work, the device tree needs to have the following:
 *
 * 1) An alias for each PHY node that an Ethernet node could be routed to.
 *
 * 2) An alias for each real and virtual MDIO node that is disabled by default
 * and might need to be enabled, and also might need to have its mux-value
 * updated.
 */

#include <common.h>
#include <netdev.h>
#include <asm/fsl_serdes.h>
#include <fm_eth.h>
#include <fsl_mdio.h>
#include <malloc.h>
#include <fdt_support.h>
#include <fsl_dtsec.h>

#include "../common/ngpixis.h"
#include "../common/fman.h"

#ifdef CONFIG_FMAN_ENET

#define BRDCFG1_EMI1_SEL_MASK	0x78
#define BRDCFG1_EMI1_SEL_SLOT1	0x10
#define BRDCFG1_EMI1_SEL_SLOT2	0x20
#define BRDCFG1_EMI1_SEL_SLOT5	0x30
#define BRDCFG1_EMI1_SEL_SLOT6	0x40
#define BRDCFG1_EMI1_SEL_SLOT7	0x50
#define BRDCFG1_EMI1_SEL_RGMII	0x00
#define BRDCFG1_EMI1_EN		0x08
#define BRDCFG1_EMI2_SEL_MASK	0x06
#define BRDCFG1_EMI2_SEL_SLOT1	0x00
#define BRDCFG1_EMI2_SEL_SLOT2	0x02

#define BRDCFG2_REG_GPIO_SEL	0x20

#define PHY_BASE_ADDR		0x00

/*
 * BRDCFG1 mask and value for each MAC
 *
 * This array contains the BRDCFG1 values (in mask/val format) that route the
 * MDIO bus to a particular RGMII or SGMII PHY.
 */
struct {
	u8 mask;
	u8 val;
} mdio_mux[NUM_FM_PORTS];

/*
 * 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[] = {
	7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0
};

/*
 * Set the board muxing for a given MAC
 *
 * The MDIO layer calls this function every time it wants to talk to a PHY.
 */
void hydra_mux_mdio(u8 mask, u8 val)
{
	clrsetbits_8(&pixis->brdcfg1, mask, val);
}

struct hydra_mdio {
	u8 mask;
	u8 val;
	struct mii_dev *realbus;
};

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

	hydra_mux_mdio(priv->mask, priv->val);

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

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

	hydra_mux_mdio(priv->mask, priv->val);

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

static int hydra_mdio_reset(struct mii_dev *bus)
{
	struct hydra_mdio *priv = bus->priv;

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

static void hydra_mdio_set_mux(char *name, u8 mask, u8 val)
{
	struct mii_dev *bus = miiphy_get_dev_by_name(name);
	struct hydra_mdio *priv = bus->priv;

	priv->mask = mask;
	priv->val = val;
}

static int hydra_mdio_init(char *realbusname, char *fakebusname)
{
	struct hydra_mdio *hmdio;
	struct mii_dev *bus = mdio_alloc();

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

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

	bus->read = hydra_mdio_read;
	bus->write = hydra_mdio_write;
	bus->reset = hydra_mdio_reset;
	sprintf(bus->name, fakebusname);

	hmdio->realbus = miiphy_get_dev_by_name(realbusname);

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

	bus->priv = hmdio;

	return mdio_register(bus);
}

/*
 * Given an alias or a path for a node, set the mux value of that node.
 *
 * If 'alias' is not a valid alias, then it is treated as a full path to the
 * node.  No error checking is performed.
 *
 * This function is normally called to set the fsl,hydra-mdio-muxval property
 * of a virtual MDIO node.
 */
static void fdt_set_mdio_mux(void *fdt, const char *alias, u32 mux)
{
	const char *path = fdt_get_alias(fdt, alias);

	if (!path)
		path = alias;

	do_fixup_by_path(fdt, path, "reg",
			 &mux, sizeof(mux), 1);
	do_fixup_by_path(fdt, path, "fsl,hydra-mdio-muxval",
			 &mux, sizeof(mux), 1);
}

/*
 * Given the following ...
 *
 * 1) A pointer to an Fman Ethernet node (as identified by the 'compat'
 * compatible string and 'addr' physical address)
 *
 * 2) An Fman port
 *
 * ... update the phy-handle property of the Ethernet node to point to the
 * right PHY.  This assumes that we already know the PHY for each port.  That
 * information is stored in mdio_mux[].
 *
 * The offset of the Fman Ethernet node is also passed in for convenience, but
 * it is not used, and we recalculate the offset anyway.
 *
 * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC.
 * Inside the Fman, "ports" are things that connect to MACs.  We only call them
 * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs
 * and ports are the same thing.
 *
 * Note that this code would be cleaner if had a function called
 * fm_info_get_phy_address(), which returns a value from the fm1_dtsec_info[]
 * array.  That's because all we're doing is figuring out the PHY address for
 * a given Fman MAC and writing it to the device tree.  Well, we already did
 * the hard work to figure that out in board_eth_init(), so it's silly to
 * repeat that here.
 */
void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
			      enum fm_port port, int offset)
{
	unsigned int mux = mdio_mux[port].val & mdio_mux[port].mask;
	char phy[16];

	if (port == FM1_10GEC1) {
		/* XAUI */
		int lane = serdes_get_first_lane(XAUI_FM1);
		if (lane >= 0) {
			/* The XAUI PHY is identified by the slot */
			sprintf(phy, "phy_xgmii_%u", lane_to_slot[lane]);
			fdt_set_phy_handle(fdt, compat, addr, phy);
		}
		return;
	}

	if (mux == (BRDCFG1_EMI1_SEL_RGMII | BRDCFG1_EMI1_EN)) {
		/* RGMII */
		/* The RGMII PHY is identified by the MAC connected to it */
		sprintf(phy, "phy_rgmii_%u", port == FM1_DTSEC4 ? 0 : 1);
		fdt_set_phy_handle(fdt, compat, addr, phy);
		return;
	}

	/* If it's not RGMII or XGMII, it must be SGMII */
	if (mux) {
		/* The SGMII PHY is identified by the MAC connected to it */
		sprintf(phy, "phy_sgmii_%x",
			CONFIG_SYS_FM1_DTSEC1_PHY_ADDR + (port - FM1_DTSEC1));
		fdt_set_phy_handle(fdt, compat, addr, phy);
	}
}

#define PIXIS_SW2_LANE_23_SEL		0x80
#define PIXIS_SW2_LANE_45_SEL		0x40
#define PIXIS_SW2_LANE_67_SEL_MASK	0x30
#define PIXIS_SW2_LANE_67_SEL_5		0x00
#define PIXIS_SW2_LANE_67_SEL_6		0x20
#define PIXIS_SW2_LANE_67_SEL_7		0x10
#define PIXIS_SW2_LANE_8_SEL		0x08
#define PIXIS_SW2_LANE_1617_SEL		0x04

/*
 * Initialize the lane_to_slot[] array.
 *
 * On the P4080DS "Expedition" board, the mapping of SERDES lanes to board
 * slots is hard-coded.  On the Hydra board, however, the mapping is controlled
 * by board switch SW2, so the lane_to_slot[] array needs to be dynamically
 * initialized.
 */
static void initialize_lane_to_slot(void)
{
	u8 sw2 = in_8(&PIXIS_SW(2));

	lane_to_slot[2] = (sw2 & PIXIS_SW2_LANE_23_SEL) ? 7 : 4;
	lane_to_slot[3] = lane_to_slot[2];

	lane_to_slot[4] = (sw2 & PIXIS_SW2_LANE_45_SEL) ? 7 : 6;
	lane_to_slot[5] = lane_to_slot[4];

	switch (sw2 & PIXIS_SW2_LANE_67_SEL_MASK) {
	case PIXIS_SW2_LANE_67_SEL_5:
		lane_to_slot[6] = 5;
		break;
	case PIXIS_SW2_LANE_67_SEL_6:
		lane_to_slot[6] = 6;
		break;
	case PIXIS_SW2_LANE_67_SEL_7:
		lane_to_slot[6] = 7;
		break;
	}
	lane_to_slot[7] = lane_to_slot[6];

	lane_to_slot[8] = (sw2 & PIXIS_SW2_LANE_8_SEL) ? 3 : 0;

	lane_to_slot[16] = (sw2 & PIXIS_SW2_LANE_1617_SEL) ? 1 : 0;
	lane_to_slot[17] = lane_to_slot[16];
}

#endif /* #ifdef CONFIG_FMAN_ENET */

/*
 * Configure the status for the virtual MDIO nodes
 *
 * Rather than create the virtual MDIO nodes from scratch for each active
 * virtual MDIO, we expect the DTS to have the nodes defined already, and we
 * only enable the ones that are actually active.
 *
 * We assume that the DTS already hard-codes the status for all the
 * virtual MDIO nodes to "disabled", so all we need to do is enable the
 * active ones.
 *
 * For SGMII, we also need to set the mux value in the node.
 */
void fdt_fixup_board_enet(void *fdt)
{
#ifdef CONFIG_FMAN_ENET
	unsigned int i;
	int lane;

	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
		int idx = i - FM1_DTSEC1;

		switch (fm_info_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_SGMII:
			lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
			if (lane >= 0) {
				fdt_status_okay_by_alias(fdt, "emi1_sgmii");
				/* Also set the MUX value */
				fdt_set_mdio_mux(fdt, "emi1_sgmii",
						 mdio_mux[i].val);
			}
			break;
		case PHY_INTERFACE_MODE_RGMII:
			fdt_status_okay_by_alias(fdt, "emi1_rgmii");
			break;
		default:
			break;
		}
	}

	lane = serdes_get_first_lane(XAUI_FM1);
	if (lane >= 0)
		fdt_status_okay_by_alias(fdt, "emi2_xgmii");
#endif
}

int board_eth_init(bd_t *bis)
{
#ifdef CONFIG_FMAN_ENET
	struct fsl_pq_mdio_info dtsec_mdio_info;
	struct tgec_mdio_info tgec_mdio_info;
	unsigned int i, slot;
	int lane;
	struct mii_dev *bus;

	printf("Initializing Fman\n");

	initialize_lane_to_slot();

	/* We want to use the PIXIS to configure MUX routing, not GPIOs. */
	setbits_8(&pixis->brdcfg2, BRDCFG2_REG_GPIO_SEL);

	memset(mdio_mux, 0, sizeof(mdio_mux));

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

	/* Register the real 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 real 10G MDIO bus */
	fm_tgec_mdio_init(bis, &tgec_mdio_info);

	/* Register the three virtual MDIO front-ends */
	hydra_mdio_init(DEFAULT_FM_MDIO_NAME, "HYDRA_RGMII_MDIO");
	hydra_mdio_init(DEFAULT_FM_MDIO_NAME, "HYDRA_SGMII_MDIO");

	/*
	 * Program the DTSEC PHY addresses assuming that they are all SGMII.
	 * For any DTSEC that's RGMII, we'll override its PHY address later.
	 * We assume that DTSEC5 is only used for RGMII.
	 */
	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);

	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
		int idx = i - FM1_DTSEC1;

		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];
			mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
			switch (slot) {
			case 1:
				/* Always DTSEC5 on Bank 3 */
				mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT1 |
						  BRDCFG1_EMI1_EN;
				break;
			case 2:
				mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT2 |
						  BRDCFG1_EMI1_EN;
				break;
			case 5:
				mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT5 |
						  BRDCFG1_EMI1_EN;
				break;
			case 6:
				mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT6 |
						  BRDCFG1_EMI1_EN;
				break;
			case 7:
				mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT7 |
						  BRDCFG1_EMI1_EN;
				break;
			};

			hydra_mdio_set_mux("HYDRA_SGMII_MDIO",
					mdio_mux[i].mask, mdio_mux[i].val);
			fm_info_set_mdio(i,
				miiphy_get_dev_by_name("HYDRA_SGMII_MDIO"));
			break;
		case PHY_INTERFACE_MODE_RGMII:
			/*
			 * If DTSEC4 is RGMII, then it's routed via via EC1 to
			 * the first on-board RGMII port.  If DTSEC5 is RGMII,
			 * then it's routed via via EC2 to the second on-board
			 * RGMII port. The other DTSECs cannot be routed to
			 * RGMII.
			 */
			fm_info_set_phy_address(i, i == FM1_DTSEC4 ? 0 : 1);
			mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
			mdio_mux[i].val  = BRDCFG1_EMI1_SEL_RGMII |
					   BRDCFG1_EMI1_EN;
			hydra_mdio_set_mux("HYDRA_RGMII_MDIO",
					mdio_mux[i].mask, mdio_mux[i].val);
			fm_info_set_mdio(i,
				miiphy_get_dev_by_name("HYDRA_RGMII_MDIO"));
			break;
		case PHY_INTERFACE_MODE_NONE:
			fm_info_set_phy_address(i, 0);
			break;
		default:
			printf("Fman1: DTSEC%u set to unknown interface %i\n",
			       idx + 1, fm_info_get_enet_if(i));
			fm_info_set_phy_address(i, 0);
			break;
		}
	}

	bus = miiphy_get_dev_by_name("HYDRA_SGMII_MDIO");
	set_sgmii_phy(bus, FM1_DTSEC1, CONFIG_SYS_NUM_FM1_DTSEC, PHY_BASE_ADDR);

	/*
	 * For 10G, we only support one XAUI card per Fman.  If present, then we
	 * force its routing and never touch those bits again, which removes the
	 * need for Linux to do any muxing.  This works because of the way
	 * BRDCFG1 is defined, but it's a bit hackish.
	 *
	 * The PHY address for the XAUI card depends on which slot it's in. The
	 * macros we use imply that the PHY address is based on which FM, but
	 * that's not true.  On the P4080DS, FM1 could only use XAUI in slot 5,
	 * and FM2 could only use a XAUI in slot 4.  On the Hydra board, we
	 * check the actual slot and just use the macros as-is, even though
	 * the P3041 and P5020 only have one Fman.
	 */
	lane = serdes_get_first_lane(XAUI_FM1);
	if (lane >= 0) {
		slot = lane_to_slot[lane];
		if (slot == 1) {
			/* XAUI card is in slot 1 */
			clrsetbits_8(&pixis->brdcfg1, BRDCFG1_EMI2_SEL_MASK,
				     BRDCFG1_EMI2_SEL_SLOT1);
			fm_info_set_phy_address(FM1_10GEC1,
						CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
		} else {
			/* XAUI card is in slot 2 */
			clrsetbits_8(&pixis->brdcfg1, BRDCFG1_EMI2_SEL_MASK,
				     BRDCFG1_EMI2_SEL_SLOT2);
			fm_info_set_phy_address(FM1_10GEC1,
						CONFIG_SYS_FM2_10GEC1_PHY_ADDR);
		}
	}

	fm_info_set_mdio(FM1_10GEC1,
			miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME));

	cpu_eth_init(bis);
#endif

	return pci_eth_init(bis);
}
