/*******************************************************************************
Copyright (C) Marvell International Ltd. and its affiliates

This software file (the "File") is owned and distributed by Marvell
International Ltd. and/or its affiliates ("Marvell") under the following
alternative licensing terms.  Once you have made an election to distribute the
File under one of the following license alternatives, please (i) delete this
introductory statement regarding license alternatives, (ii) delete the two
license alternatives that you have not elected to use and (iii) preserve the
Marvell copyright notice above.

********************************************************************************
Marvell Commercial License Option

If you received this File from Marvell and you have entered into a commercial
license agreement (a "Commercial License") with Marvell, the File is licensed
to you under the terms of the applicable Commercial License.

********************************************************************************
Marvell GPL License Option

If you received this File from Marvell, you may opt to use, redistribute and/or
modify this File in accordance with the terms and conditions of the General
Public License Version 2, June 1991 (the "GPL License"), a copy of which is
available along with the File in the license.txt file or by writing to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
on the worldwide web at http://www.gnu.org/licenses/gpl.txt.

THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
DISCLAIMED.  The GPL License provides additional details about this warranty
disclaimer.
********************************************************************************
Marvell BSD License Option

If you received this File from Marvell, you may opt to use, redistribute and/or
modify this File under the following licensing terms.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * 	Redistributions of source code must retain the above copyright notice,
	this list of conditions and the following disclaimer.

    *	Redistributions in binary form must reproduce the above copyright
	notice, this list of conditions and the following disclaimer in the
	documentation and/or other materials provided with the distribution.

    *	Neither the name of Marvell nor the names of its contributors may be
	used to endorse or promote products derived from this software without
	specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*******************************************************************************/

#include <mvCommon.h>
#include <mvOs.h>
#include "ctrlEnv/mvCtrlEnvSpec.h"
#include "mvCtrlEthCompLib.h"
#include "ctrlEnv/mvCtrlEnvLib.h"
#include "boardEnv/mvBoardEnvLib.h"
#include "pp2/gmac/mvEthGmacRegs.h"
#include "pp2/gbe/mvPp2Gbe.h"

static void mvEthComplexPortInBandAnEnable(MV_U32 port, MV_BOOL enable)
{
	MV_U32 reg;
	reg = MV_REG_READ(ETH_GMAC_AN_CTRL_REG(port));

	/* Enable AnBandAnEn */
	reg &= ~MV_ETH_IN_BAND_AN_EN_MASK;
	reg |= (0x1 << MV_ETH_IN_BAND_AN_EN_OFFSET);

	/* Disable AnDuplex, AnSpeedEn, AnFcEn */
	if (enable == MV_FALSE) {
		reg &= ~MV_ETH_SPEED_AUTO_NEG_MASK;
		reg |= (0x0 << MV_ETH_SPEED_AUTO_NEG_OFFSET);
		reg &= ~MV_ETH_FLOW_CTRL_AUTO_NEG_MASK;
		reg |= (0x0 << MV_ETH_FLOW_CTRL_AUTO_NEG_OFFSET);
		reg &= ~MV_ETH_DUPLEX_AUTO_NEG_MASK;
		reg |= (0x0 << MV_ETH_DUPLEX_AUTO_NEG_OFFSET);
	}
	MV_REG_WRITE(ETH_GMAC_AN_CTRL_REG(port), reg);
}

static void mvEthComplexGponPhySrcSet(MV_U32 src)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_GPON_PHY_CTRL1_REG);
	reg &= ~GPON_PHY_CTRL1_MASK;

	src <<= GPON_PHY_CTRL1_OFFSET;
	src &= GPON_PHY_CTRL1_MASK;

	reg |= src;

	MV_REG_WRITE(MV_GPON_PHY_CTRL1_REG, reg);
}

void mvEthComplexGphyPortSmiSrcSet(MV_U32 phy, MV_U32 src)
{
	MV_U32 reg;
	/* In A0 added Phy Smi source configuration for ports 0 and 3.
	** In Zx, only Phy Smi source for 1,2 are configurable, but no
	** need to modify the default values. */
	if (mvCtrlRevGet() <= MV_88F66X0_Z3_ID)
		return;

	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG);
	reg &= ~ETHCC_GBE_PHY_PORT_SMI_SRC_MASK(phy);

	src <<= ETHCC_GBE_PHY_PORT_SMI_SRC_OFFSET(phy);
	src &= ETHCC_GBE_PHY_PORT_SMI_SRC_MASK(phy);

	reg |= src;

	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG, reg);
}

static void mvEthComplexGbeClockControlSet(void)
{
	MV_U32 reg;
	/* Thus fields are not exists in ZX revision */
	if (mvCtrlRevGet() <= MV_88F66X0_Z3_ID)
		return;

	/* Change default value of Bit 23, and 28 to NegEdge(0) */
	reg = MV_REG_READ(MV_ETHCOMP_GBE_PHY_CLOCK_CTRL_REG);
	/* Field - Switch Port4 To MPP Data Sample */
	reg &= ~(ETHCC_GBE_PHY_P4_SW_TO_MPP_EDGE_MASK);
	/* Field - GbE Port 0 To MPP Data Sample */
	reg &= ~(ETHCC_GBE_PHY_GBE_P0_TO_MPP_EDGE_MASK);

	MV_REG_WRITE(MV_ETHCOMP_GBE_PHY_CLOCK_CTRL_REG, reg);
}

static void mvEthComplexGbePhySrcSet(MV_U32 phy, MV_U32 src)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG);
	reg &= ~ETHCC_GBE_PHY_PORT_SRC_MASK(phy);

	src <<= ETHCC_GBE_PHY_PORT_SRC_OFFSET(phy);
	src &= ETHCC_GBE_PHY_PORT_SRC_MASK(phy);

	reg |= src;

	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG, reg);
}

static MV_U32 mvEthComplexSwPortSrcCalc(MV_U32 swPort, enum mvSwPortSrc src)
{
	MV_U32 val = 0x0;

	if (swPort != 0 && swPort != 3 && swPort != 4 && swPort != 6) {
		mvOsPrintf("%s: Wrong switch port (%d)\n",
			   __func__, swPort);
		return 0x0;
	}

	switch (swPort) {
	case 0:
	case 3:
		if (src == ETHC_SW_PORT_SRC_GBE_PHY)
			val = 0x1;
		else if (src == ETHC_SW_PORT_SRC_NC)
			val = 0x0;
		else {
			mvOsPrintf("%s: Wrong src (%d) for switch port (%d)\n",
				   __func__, src, swPort);
		}
		break;
	case 4:
		if (src == ETHC_SW_PORT_SRC_MPP)
			val = 0x1;
		else if (src == ETHC_SW_PORT_SRC_GBE_MAC)
			val = 0x0;
		else {
			mvOsPrintf("%s: Wrong src (%d) for switch port (%d)\n",
				   __func__, src, swPort);
		}
		break;
	case 6:
		if (src == ETHC_SW_PORT_SRC_GBE_MAC)
			val = 0x1;
		else if (src == ETHC_SW_PORT_SRC_NC)
			val = 0x0;
		else {
			mvOsPrintf("%s: Wrong src (%d) for switch port (%d)\n",
				   __func__, src, swPort);
		}
		break;
	}

	return val;
}

static void mvEthComplexSwPortSrcSet(MV_U32 swPort, MV_U32 src)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG);
	reg &= ~ETHCC_SW_PORT_SRC_MASK(swPort);

	src <<= ETHCC_SW_PORT_SRC_OFFSET(swPort);
	src &= ETHCC_SW_PORT_SRC_MASK(swPort);

	reg |= src;

	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG, reg);
}

static void mvEthComplexGbePortSrcSet(MV_U32 port, MV_U32 src)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG);
	reg &= ~ETHCC_GBE_MAC_SRC_MASK(port);

	src <<= ETHCC_GBE_MAC_SRC_OFFSET(port);
	src &= ETHCC_GBE_MAC_SRC_MASK(port);

	reg |= src;

	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG, reg);
}

/*
 * Set speed Gbe Port 0 when it is connected to switch port 6
 */
static void mvEthComplexGbeToSwitchSpeedSet(MV_BOARD_MAC_SPEED speed)
{
	MV_U32 reg;

	if (speed != BOARD_MAC_SPEED_1000M && speed != BOARD_MAC_SPEED_2000M) {
		mvOsPrintf("%s: wrong speed (%d)\n", __func__, speed);
		return;
	}

	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG);
	reg &= ~ETHCC_GE_MAC0_SW_PORT_6_SPEED_MASK;

	if (speed == BOARD_MAC_SPEED_2000M)
		reg |= (0x1 << ETHCC_GE_MAC0_SW_PORT_6_SPEED_OFFSET);

	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG, reg);

	if (speed == BOARD_MAC_SPEED_2000M) {
		reg = MV_REG_READ(MV_ETHCOMP_SW_CONFIG_RESET_CTRL);
		reg &= ~ETHSCRC_PORT_2G_SELECT_MASK;
		reg |= (0x1 << ETHSCRC_PORT_2G_SELECT_OFFSET);
		MV_REG_WRITE(MV_ETHCOMP_SW_CONFIG_RESET_CTRL, reg);
	}
}

static void mvEthComplexPortDpClkSrcSet(MV_U32 port, MV_U32 src)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_GOP_CTRL_STAT_REG);
	reg &= ~ETHCGCS_PORT_DP_CLK_SRC_MASK(port);

	src <<= ETHCGCS_PORT_DP_CLK_SRC_OFFSET(port);
	src &= ETHCGCS_PORT_DP_CLK_SRC_MASK(port);

	reg |= src;

	MV_REG_WRITE(MV_ETHCOMP_GOP_CTRL_STAT_REG, reg);
}

static void mvEthComplexGopDevEnable(void)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_GOP_CTRL_STAT_REG);
	reg &= ~ETHCGCS_GOP_ENABLE_DEV_MASK;
	reg |= (0x1 << ETHCGCS_GOP_ENABLE_DEV_OFFSET);

	MV_REG_WRITE(MV_ETHCOMP_GOP_CTRL_STAT_REG, reg);
}

static void mvEthComplexSwResetSet(MV_BOOL setReset)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_SW_CONFIG_RESET_CTRL);
	reg &= ~ETHSCRC_SWITCH_RESET_MASK;

	if (setReset == MV_TRUE)
		reg |= (0x0 << ETHSCRC_SWITCH_RESET_OFFSET);
	else
		reg |= (0x1 << ETHSCRC_SWITCH_RESET_OFFSET);

	MV_REG_WRITE(MV_ETHCOMP_SW_CONFIG_RESET_CTRL, reg);
}

static void mvEthComplexGbePhyPowerSet(MV_U32 phy, MV_BOOL setPowerUp)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_GBE_PHY_CTRL1_REG(phy));
	reg &= ~ETHCGPC1_PHY_POWER_DOWN_MASK;

	if (setPowerUp == MV_TRUE)
		reg |= (0x0 << ETHCGPC1_PHY_POWER_DOWN_OFFSET);
	else
		reg |= (0x3 << ETHCGPC1_PHY_POWER_DOWN_OFFSET);

	MV_REG_WRITE(MV_ETHCOMP_GBE_PHY_CTRL1_REG(phy), reg);
}

static void mvEthComplexGbePhyPowerCycle(MV_U32 phy)
{
	mvEthComplexGbePhyPowerSet(phy, MV_FALSE);
	mvOsDelay(100);
	mvEthComplexGbePhyPowerSet(phy, MV_TRUE);
}

static void mvEthComplexGbePhyPdConfigEdetASet(MV_U32 phy, MV_U32 val)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_GBE_PHY_CTRL1_REG(phy));
	reg &= ~ETHCGPC1_PD_CFG_EDED_A_MASK;

	val <<= ETHCGPC1_PD_CFG_EDED_A_OFFSET;
	val &= ETHCGPC1_PD_CFG_EDED_A_MASK;

	reg |= val;

	MV_REG_WRITE(MV_ETHCOMP_GBE_PHY_CTRL1_REG(phy), reg);
}

static void mvEthComplexGbePhyPsEnaXcSSet(MV_U32 phy, MV_U32 val)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_GBE_PHY_CTRL1_REG(phy));
	reg &= ~ETHCGPC1_PS_ENA_XCS_MASK;

	val <<= ETHCGPC1_PS_ENA_XCS_OFFSET;
	val &= ETHCGPC1_PS_ENA_XCS_MASK;

	reg |= val;

	MV_REG_WRITE(MV_ETHCOMP_GBE_PHY_CTRL1_REG(phy), reg);
}

static void mvEthComplexGbePhyResetSet(MV_BOOL setReset)
{
	MV_U32 reg;

	reg = MV_REG_READ(MV_ETHCOMP_QUAD_GBE_PHY_CTRL_STAT_REG);

	reg &= ~ETHQPCS_DPLL_RESET_MASK;
	reg &= ~ETHQPCS_RESET_MASK;

	if (setReset == MV_TRUE) {
		reg |= (0x0 << ETHQPCS_RESET_OFFSET);
		reg |= (0x0 << ETHQPCS_DPLL_RESET_OFFSET);
	} else {
		reg |= (0x1 << ETHQPCS_RESET_OFFSET);
		reg |= (0x1 << ETHQPCS_DPLL_RESET_OFFSET);
	}

	MV_REG_WRITE(MV_ETHCOMP_QUAD_GBE_PHY_CTRL_STAT_REG, reg);
}

static void mvEthComplexMacToSwPort(MV_U32 port, MV_U32 swPort,
				   MV_BOARD_MAC_SPEED speed)
{
	MV_U32 src;

	mvEthComplexSwResetSet(MV_FALSE);
	mvOsDelay(200);

	src = mvEthComplexSwPortSrcCalc(swPort, ETHC_SW_PORT_SRC_GBE_MAC);
	mvEthComplexSwPortSrcSet(swPort, src);
	mvEthComplexGbePortSrcSet(port, 0x1);

	/* GE MAC #0 - Switch Port6 2G Speed */
	if (port == 0 && swPort == 6 && speed == BOARD_MAC_SPEED_2000M) {
		mvEthComplexGbeToSwitchSpeedSet(speed);
		mvEthComplexPortDpClkSrcSet(port, 0x0);
	} else
		mvEthComplexPortDpClkSrcSet(port, 0x1);
}

static void mvEthComplexSwPortToRgmii(MV_U32 swPort, MV_U32 port)
{
	MV_U32 src;

	src = mvEthComplexSwPortSrcCalc(swPort, ETHC_SW_PORT_SRC_MPP);
	mvEthComplexSwPortSrcSet(swPort, src);
}

static void mvEthComplexXponMacToPonSerdes(void)
{
	/* 0x0 = XPON Mac is source for GponPhy */
	mvEthComplexGponPhySrcSet(0);
}

static void mvEthComplexMacToGbePhy(MV_U32 port, MV_U32 phy, MV_U32 phyAddr)
{
	mvEthComplexGbePhySrcSet(phy, 0x0);
	mvEthComplexGbePortSrcSet(port, 0x2);

	/* Set SMI source for PHY: 0x0 = MAC is smi master, 0x1 = Switch is smi master */
	mvEthComplexGphyPortSmiSrcSet(phy, 0x0);

	if (port == 0)
		mvEthComplexSwPortSrcSet(6, 0x0);

	mvEthComplexPortDpClkSrcSet(port, 0x1);
	mvEthComplexGbePhyPdConfigEdetASet(phy, 0x0);
	mvEthComplexGbePhyPsEnaXcSSet(phy, 0x3);
	mvEthComplexGbePhyResetSet(MV_FALSE);
}

static void mvEthComplexMacToComPhy(MV_U32 port, MV_U32 comPhy, MV_U32 ethComplexOptions)
{
	/* Set port as SGMII Auto-Negotiation */
	mvEthComplexPortInBandAnEnable(port, MV_TRUE);
	/* 0x1 for 1Gbps, 0x0 for 2.5Gbps */
	if (ethComplexOptions & MV_ETHCOMP_GE_MAC0_2_COMPHY_SPEED_2G)
		mvEthComplexPortDpClkSrcSet(port, 0x0);
	else
		mvEthComplexPortDpClkSrcSet(port, 0x1);
}

static void mvEthComplexMac1ToPonSerdes(MV_U32 port, MV_U32 ethComplexOptions)
{
	if (ethComplexOptions & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP)
		mvEthComplexPortInBandAnEnable(port, MV_TRUE);
	/* 0x1 = Mac#1 is source for GponPhy */
	mvEthComplexGponPhySrcSet(0x1);
}

static void mvEthComplexMacToRgmii(MV_U32 port)
{
	mvEthComplexGbePortSrcSet(port, 0x0);
	mvEthComplexPortDpClkSrcSet(port, 0x1);
	mvEthComplexGopDevEnable();
}

static void mvEthComplexSwPortToGbePhy(MV_U32 swPort, MV_U32 phy)
{
	/* For Phy 1 and 2, Sw port source and phy source are hardcoded */
	if (phy == 0 || phy == 3) {
		mvEthComplexSwPortSrcSet(swPort, 0x1);
		mvEthComplexGbePhySrcSet(phy, 0x1);
	}
	/* Set SMI source for PHY: 0x0 = MAC is smi master, 0x1 = Switch is smi master */
	mvEthComplexGphyPortSmiSrcSet(phy, 0x1);
	mvEthComplexGbePhyResetSet(MV_FALSE);
	mvEthComplexGbePhyPowerCycle(phy);
}

MV_STATUS mvEthComplexInit(MV_U32 ethCompConfig)
{
	MV_U32 c = ethCompConfig;

	mvEthComplexGopDevEnable();

	mvEthComplexGbeClockControlSet();

	if (c & MV_ETHCOMP_GE_MAC0_2_SW_P6)
		mvEthComplexMacToSwPort(0, 6, mvBoardMacSpeedGet(0));

	if (c & MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0)
		mvEthComplexMacToGbePhy(0, 0, mvBoardPhyAddrGet(0));

	if (c & MV_ETHCOMP_GE_MAC0_2_RGMII0)
		mvEthComplexMacToRgmii(0);

	if (c & MV_ETHCOMP_GE_MAC0_2_COMPHY_1)
		mvEthComplexMacToComPhy(0, 1, c);

	if (c & MV_ETHCOMP_GE_MAC0_2_COMPHY_2)
		mvEthComplexMacToComPhy(0, 2, c);

	if (c & MV_ETHCOMP_GE_MAC0_2_COMPHY_3)
		mvEthComplexMacToComPhy(0, 3, c);

	if (c & MV_ETHCOMP_GE_MAC1_2_SW_P4)
		mvEthComplexMacToSwPort(1, 4, mvBoardMacSpeedGet(1));

	if (c & MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3)
		mvEthComplexMacToGbePhy(1, 3, mvBoardPhyAddrGet(1));

	if (c & (MV_ETHCOMP_GE_MAC1_2_RGMII1 | MV_ETHCOMP_GE_MAC1_2_RGMII0))
		mvEthComplexMacToRgmii(1);

	if (c & (MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES | MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP))
		mvEthComplexMac1ToPonSerdes(1, c);

	if (c & MV_ETHCOMP_SW_P0_2_GE_PHY_P0)
		mvEthComplexSwPortToGbePhy(0, 0);

	if (c & MV_ETHCOMP_SW_P1_2_GE_PHY_P1)
		mvEthComplexSwPortToGbePhy(1, 1);
	else
		/* Set SMI sourse of PHY-1 to CPU (and not Switch)
		 to access and shutdown the PHY */
		mvEthComplexGphyPortSmiSrcSet(1, 0);

	if (c & MV_ETHCOMP_SW_P2_2_GE_PHY_P2)
		mvEthComplexSwPortToGbePhy(2, 2);
	else
		/* Set SMI sourse of PHY-1 to CPU (and not Switch)
		 to access and shutdown the PHY */
		mvEthComplexGphyPortSmiSrcSet(2, 0);

	if (c & MV_ETHCOMP_SW_P3_2_GE_PHY_P3)
		mvEthComplexSwPortToGbePhy(3, 3);

	if (c & MV_ETHCOMP_SW_P4_2_RGMII0)
		mvEthComplexSwPortToRgmii(4, 0);

	if (c & MV_ETHCOMP_P2P_MAC_2_PON_ETH_SERDES)
		mvEthComplexXponMacToPonSerdes();

	return MV_OK;
}
