/*
 * 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[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]);
	brdcfg9 |= (1 << 5);
	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]);

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