/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

/**
 *  \file   mdio.c
 *
 *  \brief  MDIO APIs.
 *
 *   This file contains the device abstraction layer APIs for MDIO.
 */

/*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
*/
/*
*  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 Texas Instruments Incorporated 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.
*
*/

/* HW Macros and Peripheral Defines */
#include <ethdrivers/plat/hw/hw_types.h>
#include <ethdrivers/plat/hw/hw_mdio.h>

/* Driver APIs */
#include <ethdrivers/plat/mdio.h>

/*******************************************************************************
*                       INTERNAL MACRO DEFINITIONS
*******************************************************************************/
#define PHY_REG_MASK                             (0x1Fu)
#define PHY_ADDR_MASK                            (0x1Fu)
#define PHY_DATA_MASK                            (0xFFFFu)
#define PHY_REG_SHIFT                            (21u)
#define PHY_ADDR_SHIFT                           (16u)

/*******************************************************************************
*                        API FUNCTION DEFINITIONS
*******************************************************************************/

/**
 * \brief   Reads a PHY register using MDIO.
 *
 * \param   baseAddr      Base Address of the MDIO Module Registers.
 * \param   phyAddr       PHY Adress.
 * \param   regNum        Register Number to be read.
 * \param   dataPtr       Pointer where the read value shall be written.
 *
 * \return  status of the read \n
 *          TRUE - read is successful.\n
 *          FALSE - read is not acknowledged properly.
 *
 **/
unsigned int MDIOPhyRegRead(unsigned int baseAddr, unsigned int phyAddr,
                            unsigned int regNum, volatile unsigned short *dataPtr)
{
    /* Wait till transaction completion if any */
    while (HWREG(baseAddr + MDIO_USERACCESS0) & MDIO_USERACCESS0_GO);

    HWREG(baseAddr + MDIO_USERACCESS0)
        = (MDIO_USERACCESS0_READ | MDIO_USERACCESS0_GO
           | ((regNum & PHY_REG_MASK) << PHY_REG_SHIFT)
           | ((phyAddr & PHY_ADDR_MASK) << PHY_ADDR_SHIFT));

    /* wait for command completion */
    while (HWREG(baseAddr + MDIO_USERACCESS0) & MDIO_USERACCESS0_GO);

    /* Store the data if the read is acknowledged */
    if ((HWREG(baseAddr + MDIO_USERACCESS0)) & MDIO_USERACCESS0_ACK) {
        *dataPtr = (unsigned short)((HWREG(baseAddr + MDIO_USERACCESS0))
                                    & PHY_DATA_MASK);
        return TRUE;
    }

    return FALSE;
}

/**
 * \brief   Writes a PHY register using MDIO.
 *
 * \param   baseAddr      Base Address of the MDIO Module Registers.
 * \param   phyAddr       PHY Adress.
 * \param   regNum        Register Number to be read.
 * \param   RegVal        Value to be written.
 *
 * \return  None
 *
 **/
void MDIOPhyRegWrite(unsigned int baseAddr, unsigned int phyAddr,
                     unsigned int regNum, unsigned short RegVal)
{
    /* Wait till transaction completion if any */
    while (HWREG(baseAddr + MDIO_USERACCESS0) & MDIO_USERACCESS0_GO);

    HWREG(baseAddr + MDIO_USERACCESS0)
        = (MDIO_USERACCESS0_WRITE | MDIO_USERACCESS0_GO
           | ((regNum & PHY_REG_MASK) << PHY_REG_SHIFT)
           | ((phyAddr & PHY_ADDR_MASK) << PHY_ADDR_SHIFT)
           | RegVal);

    /* wait for command completion*/
    while (HWREG(baseAddr + MDIO_USERACCESS0) & MDIO_USERACCESS0_GO);
}
/**
 * \brief   Reads the alive status of all PHY connected to this MDIO.
 *          The bit correponding to the PHY address will be set if the PHY
 *          is alive.
 *
 * \param   baseAddr      Base Address of the MDIO Module Registers.
 *
 * \return  MDIO alive register state
 *
 **/
unsigned int MDIOPhyAliveStatusGet(unsigned int baseAddr)
{
    return (HWREG(baseAddr + MDIO_ALIVE));
}

/**
 * \brief   Reads the link status of all PHY connected to this MDIO.
 *          The bit correponding to the PHY address will be set if the PHY
 *          link is active.
 *
 * \param   baseAddr      Base Address of the MDIO Module Registers.
 *
 * \return  MDIO link register state
 *
 **/
unsigned int MDIOPhyLinkStatusGet(unsigned int baseAddr)
{
    return (HWREG(baseAddr + MDIO_LINK));
}

/**
 * \brief   Initializes the MDIO peripheral. This enables the MDIO state
 *          machine, uses standard pre-amble and set the clock divider value.
 *
 * \param   baseAddr       Base Address of the MDIO Module Registers.
 * \param   mdioInputFreq  The clock input to the MDIO module
 * \param   mdioOutputFreq The clock output required on the MDIO bus
 * \return  None
 *
 **/
void MDIOInit(unsigned int baseAddr, unsigned int mdioInputFreq,
              unsigned int mdioOutputFreq)
{
    unsigned int clkDiv = (mdioInputFreq / mdioOutputFreq) - 1;

    HWREG(baseAddr + MDIO_CONTROL) = ((clkDiv & MDIO_CONTROL_CLKDIV)
                                      | MDIO_CONTROL_ENABLE
                                      | MDIO_CONTROL_PREAMBLE
                                      | MDIO_CONTROL_FAULTENB);
}

/**
 * \brief   Saves the MDIO register context. Note that only MDIO control
 *          register context is saved here.
 *
 * \param   baseAddr       Base Address of the MDIO Module Registers.
 * \param   contextPtr     Pointer to the structure where MDIO context
 *                         needs to be saved.
 * \return  None
 *
 **/
void MDIOContextSave(unsigned int baseAddr, MDIOCONTEXT *contextPtr)
{
    contextPtr->mdioCtrl = HWREG(baseAddr + MDIO_CONTROL);
}

/**
 * \brief   Restores the MDIO register context. Note that only MDIO control
 *          register context is restored here. Hence enough delay shall be
 *          given after this API
 *
 * \param   baseAddr       Base Address of the MDIO Module Registers.
 * \param   contextPtr     Pointer to the structure where MDIO context
 *                         needs to be restored from
 * \return  None
 *
 **/
void MDIOContextRestore(unsigned int baseAddr, MDIOCONTEXT *contextPtr)
{
    HWREG(baseAddr + MDIO_CONTROL) = contextPtr->mdioCtrl;
}

/***************************** End Of File ***********************************/
