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

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

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

#define EMI_NONE	0xFF
#define EMI1_RGMII1	0
#define EMI1_RGMII2	1
#define EMI1_SLOT1	2
#define EMI1_SLOT2	3
#define EMI1_SLOT3	4
#define EMI1_SLOT4	5
#define EMI2		6

static int mdio_mux[NUM_FM_PORTS];

static const char * const mdio_names[] = {
	"LS1043AQDS_MDIO_RGMII1",
	"LS1043AQDS_MDIO_RGMII2",
	"LS1043AQDS_MDIO_SLOT1",
	"LS1043AQDS_MDIO_SLOT2",
	"LS1043AQDS_MDIO_SLOT3",
	"LS1043AQDS_MDIO_SLOT4",
	"NULL",
};

/* Map SerDes1 4 lanes to default slot, will be initialized dynamically */
static u8 lane_to_slot[] = {1, 2, 3, 4};

static const char *ls1043aqds_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;

	if (muxval > EMI2)
		return NULL;

	name = ls1043aqds_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;
}

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

static void ls1043aqds_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 ls1043aqds_mdio_read(struct mii_dev *bus, int addr, int devad,
			      int regnum)
{
	struct ls1043aqds_mdio *priv = bus->priv;

	ls1043aqds_mux_mdio(priv->muxval);

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

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

	ls1043aqds_mux_mdio(priv->muxval);

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

static int ls1043aqds_mdio_reset(struct mii_dev *bus)
{
	struct ls1043aqds_mdio *priv = bus->priv;

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

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

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

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

	bus->read = ls1043aqds_mdio_read;
	bus->write = ls1043aqds_mdio_write;
	bus->reset = ls1043aqds_mdio_reset;
	strcpy(bus->name, ls1043aqds_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 *fdt, char *compat, phys_addr_t addr,
			      enum fm_port port, int offset)
{
	struct fixed_link f_link;

	if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
		if (port == FM1_DTSEC9) {
			fdt_set_phy_handle(fdt, compat, addr,
					   "sgmii_riser_s1_p1");
		} else if (port == FM1_DTSEC2) {
			fdt_set_phy_handle(fdt, compat, addr,
					   "sgmii_riser_s2_p1");
		} else if (port == FM1_DTSEC5) {
			fdt_set_phy_handle(fdt, compat, addr,
					   "sgmii_riser_s3_p1");
		} else if (port == FM1_DTSEC6) {
			fdt_set_phy_handle(fdt, compat, addr,
					   "sgmii_riser_s4_p1");
		}
	} else if (fm_info_get_enet_if(port) ==
		   PHY_INTERFACE_MODE_SGMII_2500) {
		/* 2.5G SGMII interface */
		f_link.phy_id = port;
		f_link.duplex = 1;
		f_link.link_speed = 1000;
		f_link.pause = 0;
		f_link.asym_pause = 0;
		/* no PHY for 2.5G SGMII */
		fdt_delprop(fdt, offset, "phy-handle");
		fdt_setprop(fdt, offset, "fixed-link", &f_link, sizeof(f_link));
		fdt_setprop_string(fdt, offset, "phy-connection-type",
				   "sgmii-2500");
	} else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_QSGMII) {
		switch (mdio_mux[port]) {
		case EMI1_SLOT1:
			switch (port) {
			case FM1_DTSEC1:
				fdt_set_phy_handle(fdt, compat, addr,
						   "qsgmii_s1_p1");
				break;
			case FM1_DTSEC2:
				fdt_set_phy_handle(fdt, compat, addr,
						   "qsgmii_s1_p2");
				break;
			case FM1_DTSEC5:
				fdt_set_phy_handle(fdt, compat, addr,
						   "qsgmii_s1_p3");
				break;
			case FM1_DTSEC6:
				fdt_set_phy_handle(fdt, compat, addr,
						   "qsgmii_s1_p4");
				break;
			default:
				break;
			}
			break;
		case EMI1_SLOT2:
			switch (port) {
			case FM1_DTSEC1:
				fdt_set_phy_handle(fdt, compat, addr,
						   "qsgmii_s2_p1");
				break;
			case FM1_DTSEC2:
				fdt_set_phy_handle(fdt, compat, addr,
						   "qsgmii_s2_p2");
				break;
			case FM1_DTSEC5:
				fdt_set_phy_handle(fdt, compat, addr,
						   "qsgmii_s2_p3");
				break;
			case FM1_DTSEC6:
				fdt_set_phy_handle(fdt, compat, addr,
						   "qsgmii_s2_p4");
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		fdt_delprop(fdt, offset, "phy-connection-type");
		fdt_setprop_string(fdt, offset, "phy-connection-type",
				   "qsgmii");
	} else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII &&
		   port == FM1_10GEC1) {
		/* XFI interface */
		f_link.phy_id = port;
		f_link.duplex = 1;
		f_link.link_speed = 10000;
		f_link.pause = 0;
		f_link.asym_pause = 0;
		/* no PHY for XFI */
		fdt_delprop(fdt, offset, "phy-handle");
		fdt_setprop(fdt, offset, "fixed-link", &f_link, sizeof(f_link));
		fdt_setprop_string(fdt, offset, "phy-connection-type", "xgmii");
	}
}

void fdt_fixup_board_enet(void *fdt)
{
	int i;
	struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
	u32 srds_s1;

	srds_s1 = in_be32(&gur->rcwsr[4]) &
			FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
	srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;

	for (i = FM1_DTSEC1; i < NUM_FM_PORTS; i++) {
		switch (fm_info_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_SGMII:
		case PHY_INTERFACE_MODE_QSGMII:
			switch (mdio_mux[i]) {
			case EMI1_SLOT1:
				fdt_status_okay_by_alias(fdt, "emi1_slot1");
				break;
			case EMI1_SLOT2:
				fdt_status_okay_by_alias(fdt, "emi1_slot2");
				break;
			case EMI1_SLOT3:
				fdt_status_okay_by_alias(fdt, "emi1_slot3");
				break;
			case EMI1_SLOT4:
				fdt_status_okay_by_alias(fdt, "emi1_slot4");
				break;
			default:
				break;
			}
			break;
		case PHY_INTERFACE_MODE_XGMII:
			break;
		default:
			break;
		}
	}
}

int board_eth_init(bd_t *bis)
{
#ifdef CONFIG_FMAN_ENET
	int i, idx, lane, slot, interface;
	struct memac_mdio_info dtsec_mdio_info;
	struct memac_mdio_info tgec_mdio_info;
	struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
	u32 srds_s1;

	srds_s1 = in_be32(&gur->rcwsr[4]) &
			FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
	srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;

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

	dtsec_mdio_info.regs =
		(struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;

	dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;

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

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

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

	/* Register the muxing front-ends to the MDIO buses */
	ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
	ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2);
	ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
	ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2);
	ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
	ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
	ls1043aqds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2);

	/* Set the two on-board RGMII PHY address */
	fm_info_set_phy_address(FM1_DTSEC3, RGMII_PHY1_ADDR);
	fm_info_set_phy_address(FM1_DTSEC4, RGMII_PHY2_ADDR);

	switch (srds_s1) {
	case 0x2555:
		/* 2.5G SGMII on lane A, MAC 9 */
		fm_info_set_phy_address(FM1_DTSEC9, 9);
		break;
	case 0x4555:
	case 0x4558:
		/* QSGMII on lane A, MAC 1/2/5/6 */
		fm_info_set_phy_address(FM1_DTSEC1,
					QSGMII_CARD_PORT1_PHY_ADDR_S1);
		fm_info_set_phy_address(FM1_DTSEC2,
					QSGMII_CARD_PORT2_PHY_ADDR_S1);
		fm_info_set_phy_address(FM1_DTSEC5,
					QSGMII_CARD_PORT3_PHY_ADDR_S1);
		fm_info_set_phy_address(FM1_DTSEC6,
					QSGMII_CARD_PORT4_PHY_ADDR_S1);
		break;
	case 0x1355:
		/* SGMII on lane B, MAC 2*/
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
		break;
	case 0x2355:
		/* 2.5G SGMII on lane A, MAC 9 */
		fm_info_set_phy_address(FM1_DTSEC9, 9);
		/* SGMII on lane B, MAC 2*/
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
		break;
	case 0x3335:
		/* SGMII on lane C, MAC 5 */
		fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT1_PHY_ADDR);
	case 0x3355:
	case 0x3358:
		/* SGMII on lane B, MAC 2 */
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
	case 0x3555:
	case 0x3558:
		/* SGMII on lane A, MAC 9 */
		fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
		break;
	case 0x1455:
		/* QSGMII on lane B, MAC 1/2/5/6 */
		fm_info_set_phy_address(FM1_DTSEC1,
					QSGMII_CARD_PORT1_PHY_ADDR_S2);
		fm_info_set_phy_address(FM1_DTSEC2,
					QSGMII_CARD_PORT2_PHY_ADDR_S2);
		fm_info_set_phy_address(FM1_DTSEC5,
					QSGMII_CARD_PORT3_PHY_ADDR_S2);
		fm_info_set_phy_address(FM1_DTSEC6,
					QSGMII_CARD_PORT4_PHY_ADDR_S2);
		break;
	case 0x2455:
		/* 2.5G SGMII on lane A, MAC 9 */
		fm_info_set_phy_address(FM1_DTSEC9, 9);
		/* QSGMII on lane B, MAC 1/2/5/6 */
		fm_info_set_phy_address(FM1_DTSEC1,
					QSGMII_CARD_PORT1_PHY_ADDR_S2);
		fm_info_set_phy_address(FM1_DTSEC2,
					QSGMII_CARD_PORT2_PHY_ADDR_S2);
		fm_info_set_phy_address(FM1_DTSEC5,
					QSGMII_CARD_PORT3_PHY_ADDR_S2);
		fm_info_set_phy_address(FM1_DTSEC6,
					QSGMII_CARD_PORT4_PHY_ADDR_S2);
		break;
	case 0x2255:
		/* 2.5G SGMII on lane A, MAC 9 */
		fm_info_set_phy_address(FM1_DTSEC9, 9);
		/* 2.5G SGMII on lane B, MAC 2 */
		fm_info_set_phy_address(FM1_DTSEC2, 2);
		break;
	case 0x3333:
		/* SGMII on lane A/B/C/D, MAC 9/2/5/6 */
		fm_info_set_phy_address(FM1_DTSEC9,
					SGMII_CARD_PORT1_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC2,
					SGMII_CARD_PORT1_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC5,
					SGMII_CARD_PORT1_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC6,
					SGMII_CARD_PORT1_PHY_ADDR);
		break;
	default:
		printf("Invalid SerDes protocol 0x%x for LS1043AQDS\n",
		       srds_s1);
		break;
	}

	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
		idx = i - FM1_DTSEC1;
		interface = fm_info_get_enet_if(i);
		switch (interface) {
		case PHY_INTERFACE_MODE_SGMII:
		case PHY_INTERFACE_MODE_SGMII_2500:
		case PHY_INTERFACE_MODE_QSGMII:
			if (interface == PHY_INTERFACE_MODE_SGMII) {
				lane = serdes_get_first_lane(FSL_SRDS_1,
						SGMII_FM1_DTSEC1 + idx);
			} else if (interface == PHY_INTERFACE_MODE_SGMII_2500) {
				lane = serdes_get_first_lane(FSL_SRDS_1,
						SGMII_2500_FM1_DTSEC1 + idx);
			} else {
				lane = serdes_get_first_lane(FSL_SRDS_1,
						QSGMII_FM1_A);
			}

			if (lane < 0)
				break;

			slot = lane_to_slot[lane];
			debug("FM1@DTSEC%u expects SGMII in slot %u\n",
			      idx + 1, slot);
			if (QIXIS_READ(present2) & (1 << (slot - 1)))
				fm_disable_port(i);

			switch (slot) {
			case 1:
				mdio_mux[i] = EMI1_SLOT1;
				fm_info_set_mdio(i, mii_dev_for_muxval(
						 mdio_mux[i]));
				break;
			case 2:
				mdio_mux[i] = EMI1_SLOT2;
				fm_info_set_mdio(i, mii_dev_for_muxval(
						 mdio_mux[i]));
				break;
			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;
			default:
				break;
			}
			break;
		case PHY_INTERFACE_MODE_RGMII:
			if (i == FM1_DTSEC3)
				mdio_mux[i] = EMI1_RGMII1;
			else if (i == FM1_DTSEC4)
				mdio_mux[i] = EMI1_RGMII2;
			fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
			break;
		default:
			break;
		}
	}

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

	return pci_eth_init(bis);
}
