/*
 * Copyright 2013 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * The RGMII PHYs are provided by the two on-board PHY connected to
 * dTSEC instances 4 and 5. The SGMII PHYs are provided by one on-board
 * PHY or by the standard four-port SGMII riser card (VSC).
 */

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

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

#include "t1040qds_qixis.h"

#ifdef CONFIG_FMAN_ENET
 /* - In T1040 there are only 8 SERDES lanes, spread across 2 SERDES banks.
 *   Bank 1 -> Lanes A, B, C, D
 *   Bank 2 -> Lanes E, F, G, H
 */

 /* Mapping of 8 SERDES lanes to T1040 QDS 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[] = {
	0, 0, 0, 0, 0, 0, 0, 0
};

/* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
 * housed.
 */
static int riser_phy_addr[] = {
	CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR,
	CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR,
	CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR,
	CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR,
};

/* Slot2 does not have EMI connections */
#define EMI_NONE	0xFFFFFFFF
#define EMI1_RGMII0	0
#define EMI1_RGMII1	1
#define EMI1_SLOT1	2
#define EMI1_SLOT3	3
#define EMI1_SLOT4	4
#define EMI1_SLOT5	5
#define EMI1_SLOT6	6
#define EMI1_SLOT7	7
#define EMI2		8

static int mdio_mux[NUM_FM_PORTS];

static const char * const mdio_names[] = {
	"T1040_QDS_MDIO0",
	"T1040_QDS_MDIO1",
	"T1040_QDS_MDIO2",
	"T1040_QDS_MDIO3",
	"T1040_QDS_MDIO4",
	"T1040_QDS_MDIO5",
	"T1040_QDS_MDIO6",
	"T1040_QDS_MDIO7",
};

struct t1040_qds_mdio {
	u8 muxval;
	struct mii_dev *realbus;
};

static const char *t1040_qds_mdio_name_for_muxval(u8 muxval)
{
	return mdio_names[muxval];
}

struct mii_dev *mii_dev_for_muxval(u8 muxval)
{
	struct mii_dev *bus;
	const char *name = t1040_qds_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;
}

static void t1040_qds_mux_mdio(u8 muxval)
{
	u8 brdcfg4;
	if (muxval <= 7) {
		brdcfg4 = QIXIS_READ(brdcfg[4]);
		brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
		brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
		QIXIS_WRITE(brdcfg[4], brdcfg4);
	}
}

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

	t1040_qds_mux_mdio(priv->muxval);

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

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

	t1040_qds_mux_mdio(priv->muxval);

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

static int t1040_qds_mdio_reset(struct mii_dev *bus)
{
	struct t1040_qds_mdio *priv = bus->priv;

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

static int t1040_qds_mdio_init(char *realbusname, u8 muxval)
{
	struct t1040_qds_mdio *pmdio;
	struct mii_dev *bus = mdio_alloc();

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

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

	bus->read = t1040_qds_mdio_read;
	bus->write = t1040_qds_mdio_write;
	bus->reset = t1040_qds_mdio_reset;
	sprintf(bus->name, t1040_qds_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);
}

/*
 * Initialize the lane_to_slot[] array.
 *
 * On the T1040QDS board the mapping is controlled by ?? register.
 */
static void initialize_lane_to_slot(void)
{
	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
	int serdes1_prtcl = (in_be32(&gur->rcwsr[4]) &
				FSL_CORENET2_RCWSR4_SRDS1_PRTCL)
		>> FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;

	QIXIS_WRITE(cms[0], 0x07);

	switch (serdes1_prtcl) {
	case 0x60:
	case 0x66:
	case 0x67:
	case 0x69:
		lane_to_slot[1] = 7;
		lane_to_slot[2] = 6;
		lane_to_slot[3] = 5;
		break;
	case 0x86:
		lane_to_slot[1] = 7;
		lane_to_slot[2] = 7;
		lane_to_slot[3] = 7;
		break;
	case 0x87:
		lane_to_slot[1] = 7;
		lane_to_slot[2] = 7;
		lane_to_slot[3] = 7;
		lane_to_slot[7] = 7;
		break;
	case 0x89:
		lane_to_slot[1] = 7;
		lane_to_slot[2] = 7;
		lane_to_slot[3] = 7;
		lane_to_slot[6] = 7;
		lane_to_slot[7] = 7;
		break;
	case 0x8d:
		lane_to_slot[1] = 7;
		lane_to_slot[2] = 7;
		lane_to_slot[3] = 7;
		lane_to_slot[5] = 3;
		lane_to_slot[6] = 3;
		lane_to_slot[7] = 3;
		break;
	case 0x8F:
	case 0x85:
		lane_to_slot[1] = 7;
		lane_to_slot[2] = 6;
		lane_to_slot[3] = 5;
		lane_to_slot[6] = 3;
		lane_to_slot[7] = 3;
		break;
	case 0xA5:
		lane_to_slot[1] = 7;
		lane_to_slot[6] = 3;
		lane_to_slot[7] = 3;
		break;
	case 0xA7:
		lane_to_slot[1] = 7;
		lane_to_slot[2] = 6;
		lane_to_slot[3] = 5;
		lane_to_slot[7] = 7;
		break;
	case 0xAA:
		lane_to_slot[1] = 7;
		lane_to_slot[6] = 7;
		lane_to_slot[7] = 7;
		break;
	case 0x40:
		lane_to_slot[2] = 7;
		lane_to_slot[3] = 7;
		break;
	default:
		printf("qds: Fman: Unsupported SerDes Protocol 0x%02x\n",
		       serdes1_prtcl);
		break;
	}
}

/*
 * 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.
 *
 * 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.
 *
 */
void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
			      enum fm_port port, int offset)
{
	phy_interface_t intf = fm_info_get_enet_if(port);
	char phy[16];

	/* The RGMII PHY is identified by the MAC connected to it */
	if (intf == PHY_INTERFACE_MODE_RGMII) {
		sprintf(phy, "rgmii_phy%u", port == FM1_DTSEC4 ? 1 : 2);
		fdt_set_phy_handle(fdt, compat, addr, phy);
	}

	/* The SGMII PHY is identified by the MAC connected to it */
	if (intf == PHY_INTERFACE_MODE_SGMII) {
		int lane = serdes_get_first_lane(FSL_SRDS_1, SGMII_FM1_DTSEC1
						 + port);
		u8 slot;
		if (lane < 0)
			return;
		slot = lane_to_slot[lane];
		if (slot) {
			/* Slot housing a SGMII riser card */
			sprintf(phy, "phy_s%x_%02x", slot,
				(fm_info_get_phy_address(port - FM1_DTSEC1)-
				CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR + 1));
			fdt_set_phy_handle(fdt, compat, addr, phy);
		}
	}
}

void fdt_fixup_board_enet(void *fdt)
{
	int i, lane, idx;

	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
		idx = i - FM1_DTSEC1;
		switch (fm_info_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_SGMII:
			lane = serdes_get_first_lane(FSL_SRDS_1,
						     SGMII_FM1_DTSEC1 + idx);
			if (lane < 0)
				break;

			switch (mdio_mux[i]) {
			case EMI1_SLOT3:
				fdt_status_okay_by_alias(fdt, "emi1_slot3");
				break;
			case EMI1_SLOT5:
				fdt_status_okay_by_alias(fdt, "emi1_slot5");
				break;
			case EMI1_SLOT6:
				fdt_status_okay_by_alias(fdt, "emi1_slot6");
				break;
			case EMI1_SLOT7:
				fdt_status_okay_by_alias(fdt, "emi1_slot7");
				break;
			}
		break;
		case PHY_INTERFACE_MODE_RGMII:
			if (i == FM1_DTSEC4)
				fdt_status_okay_by_alias(fdt, "emi1_rgmii0");

			if (i == FM1_DTSEC5)
				fdt_status_okay_by_alias(fdt, "emi1_rgmii1");
			break;
		default:
			break;
		}
	}
}
#endif /* #ifdef CONFIG_FMAN_ENET */

static void set_brdcfg9_for_gtx_clk(void)
{
	u8 brdcfg9;
	brdcfg9 = QIXIS_READ(brdcfg[9]);
/* Initializing EPHY2 clock to RGMII mode */
	brdcfg9 &= ~(BRDCFG9_EPHY2_MASK);
	brdcfg9 |= (BRDCFG9_EPHY2_VAL);
	QIXIS_WRITE(brdcfg[9], brdcfg9);
}

void t1040_handle_phy_interface_sgmii(int i)
{
	int lane, idx, slot;
	idx = i - FM1_DTSEC1;
	lane = serdes_get_first_lane(FSL_SRDS_1,
			SGMII_FM1_DTSEC1 + idx);

	if (lane < 0)
		return;
	slot = lane_to_slot[lane];

	switch (slot) {
	case 1:
		mdio_mux[i] = EMI1_SLOT1;
		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
		break;
	case 3:
		if (FM1_DTSEC4 == i)
			fm_info_set_phy_address(i, riser_phy_addr[0]);
		if (FM1_DTSEC5 == i)
			fm_info_set_phy_address(i, riser_phy_addr[1]);

		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:
		/* Slot housing a SGMII riser card? */
		fm_info_set_phy_address(i, riser_phy_addr[0]);
		mdio_mux[i] = EMI1_SLOT5;
		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
		break;
	case 6:
		/* Slot housing a SGMII riser card? */
		fm_info_set_phy_address(i, riser_phy_addr[0]);
		mdio_mux[i] = EMI1_SLOT6;
		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
		break;
	case 7:
		if (FM1_DTSEC1 == i)
			fm_info_set_phy_address(i, riser_phy_addr[0]);
		if (FM1_DTSEC2 == i)
			fm_info_set_phy_address(i, riser_phy_addr[1]);
		if (FM1_DTSEC3 == i)
			fm_info_set_phy_address(i, riser_phy_addr[2]);
		if (FM1_DTSEC5 == i)
			fm_info_set_phy_address(i, riser_phy_addr[3]);

		mdio_mux[i] = EMI1_SLOT7;
		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
		break;
	default:
		break;
	}
	fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
}
void t1040_handle_phy_interface_rgmii(int i)
{
	fm_info_set_phy_address(i, i == FM1_DTSEC5 ?
			CONFIG_SYS_FM1_DTSEC5_PHY_ADDR :
			CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
	mdio_mux[i] = (i == FM1_DTSEC5) ? EMI1_RGMII1 :
		EMI1_RGMII0;
	fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
}

int board_eth_init(bd_t *bis)
{
#ifdef CONFIG_FMAN_ENET
	struct memac_mdio_info memac_mdio_info;
	unsigned int i;
#ifdef CONFIG_VSC9953
	int lane;
	int phy_addr;
	phy_interface_t phy_int;
	struct mii_dev *bus;
#endif

	printf("Initializing Fman\n");
	set_brdcfg9_for_gtx_clk();

	initialize_lane_to_slot();

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

	memac_mdio_info.regs =
		(struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
	memac_mdio_info.name = DEFAULT_FM_MDIO_NAME;

	/* Register the real 1G MDIO bus */
	fm_memac_mdio_init(bis, &memac_mdio_info);

	/* Register the muxing front-ends to the MDIO buses */
	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII0);
	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT6);
	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT7);

	/*
	 * Program on board RGMII PHY addresses. If the SGMII Riser
	 * card used, we'll override the PHY address later. For any DTSEC that
	 * is RGMII, we'll also override its PHY address later. We assume that
	 * DTSEC4 and DTSEC5 are used for RGMII.
	 */
	fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
	fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);

	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
		switch (fm_info_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_QSGMII:
			fm_info_set_mdio(i, NULL);
			break;
		case PHY_INTERFACE_MODE_SGMII:
			t1040_handle_phy_interface_sgmii(i);
			break;

		case PHY_INTERFACE_MODE_RGMII:
			/* Only DTSEC4 and DTSEC5 can be routed to RGMII */
			t1040_handle_phy_interface_rgmii(i);
			break;
		default:
			break;
		}
	}

#ifdef CONFIG_VSC9953
	for (i = 0; i < VSC9953_MAX_PORTS; i++) {
		lane = -1;
		phy_addr = 0;
		phy_int = PHY_INTERFACE_MODE_NONE;
		switch (i) {
		case 0:
		case 1:
		case 2:
		case 3:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_SW1_A);
			/* PHYs connected over QSGMII */
			if (lane >= 0) {
				phy_addr = CONFIG_SYS_FM1_QSGMII21_PHY_ADDR +
						i;
				phy_int = PHY_INTERFACE_MODE_QSGMII;
				break;
			}
			lane = serdes_get_first_lane(FSL_SRDS_1,
					SGMII_SW1_MAC1 + i);

			if (lane < 0)
				break;

			/* PHYs connected over QSGMII */
			if (i != 3 || lane_to_slot[lane] == 7)
				phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR
					+ i;
			else
				phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR;
			phy_int = PHY_INTERFACE_MODE_SGMII;
			break;
		case 4:
		case 5:
		case 6:
		case 7:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_SW1_B);
			/* PHYs connected over QSGMII */
			if (lane >= 0) {
				phy_addr = CONFIG_SYS_FM1_QSGMII11_PHY_ADDR +
						i - 4;
				phy_int = PHY_INTERFACE_MODE_QSGMII;
				break;
			}
			lane = serdes_get_first_lane(FSL_SRDS_1,
					SGMII_SW1_MAC1 + i);
			/* PHYs connected over SGMII */
			if (lane >= 0) {
				phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR
						+ i - 3;
				phy_int = PHY_INTERFACE_MODE_SGMII;
			}
			break;
		case 8:
			if (serdes_get_first_lane(FSL_SRDS_1,
						  SGMII_FM1_DTSEC1) < 0)
				/* FM1@DTSEC1 is connected to SW1@PORT8 */
				vsc9953_port_enable(i);
			break;
		case 9:
			if (serdes_get_first_lane(FSL_SRDS_1,
						  SGMII_FM1_DTSEC2) < 0) {
				/* Enable L2 On MAC2 using SCFG */
				struct ccsr_scfg *scfg = (struct ccsr_scfg *)
						CONFIG_SYS_MPC85xx_SCFG;

				out_be32(&scfg->esgmiiselcr,
					 in_be32(&scfg->esgmiiselcr) |
					 (0x80000000));
				vsc9953_port_enable(i);
			}
			break;
		}

		if (lane >= 0) {
			bus = mii_dev_for_muxval(lane_to_slot[lane]);
			vsc9953_port_info_set_mdio(i, bus);
			vsc9953_port_enable(i);
		}
		vsc9953_port_info_set_phy_address(i, phy_addr);
		vsc9953_port_info_set_phy_int(i, phy_int);
	}

#endif
	cpu_eth_init(bis);
#endif

	return pci_eth_init(bis);
}
