/*
 * 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 <asm/fsl_dtsec.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[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;

	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:
			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;
		}
	}

	cpu_eth_init(bis);
#endif

	return pci_eth_init(bis);
}
