aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c')
-rw-r--r--target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c394
1 files changed, 394 insertions, 0 deletions
diff --git a/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c b/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c
new file mode 100644
index 0000000000..fb4db113a9
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2013 Realtek Semiconductor Corp.
+ * All Rights Reserved.
+ *
+ * Unless you and Realtek execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2,
+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+ *
+ * $Revision: 76306 $
+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $
+ *
+ * Purpose : RTL8367C switch high-level API for RTL8367C
+ * Feature : PHY related functions
+ *
+ */
+#include <rtl8367c_asicdrv_phy.h>
+
+#if defined(MDC_MDIO_OPERATION)
+/* Function Name:
+ * rtl8367c_setAsicPHYOCPReg
+ * Description:
+ * Set PHY OCP registers
+ * Input:
+ * phyNo - Physical port number (0~7)
+ * ocpAddr - OCP address
+ * ocpData - Writing data
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PHY_REG_ID - invalid PHY address
+ * RT_ERR_PHY_ID - invalid PHY no
+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
+ * Note:
+ * None
+ */
+ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData )
+{
+ ret_t retVal;
+ rtk_uint32 regAddr;
+ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1;
+
+ /* OCP prefix */
+ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10);
+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK)
+ return retVal;
+
+ /*prepare access address*/
+ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F);
+ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F);
+ regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1;
+ if((retVal = rtl8367c_setAsicReg(regAddr, ocpData)) != RT_ERR_OK)
+ return retVal;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtl8367c_getAsicPHYOCPReg
+ * Description:
+ * Get PHY OCP registers
+ * Input:
+ * phyNo - Physical port number (0~7)
+ * ocpAddr - PHY address
+ * pRegData - read data
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PHY_REG_ID - invalid PHY address
+ * RT_ERR_PHY_ID - invalid PHY no
+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
+ * Note:
+ * None
+ */
+ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData )
+{
+ ret_t retVal;
+ rtk_uint32 regAddr;
+ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1;
+ /* OCP prefix */
+ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10);
+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK)
+ return retVal;
+
+ /*prepare access address*/
+ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F);
+ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F);
+ regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1;
+ if((retVal = rtl8367c_getAsicReg(regAddr, pRegData)) != RT_ERR_OK)
+ return retVal;
+
+ return RT_ERR_OK;
+}
+
+#else
+
+/* Function Name:
+ * rtl8367c_setAsicPHYOCPReg
+ * Description:
+ * Set PHY OCP registers
+ * Input:
+ * phyNo - Physical port number (0~7)
+ * ocpAddr - OCP address
+ * ocpData - Writing data
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PHY_REG_ID - invalid PHY address
+ * RT_ERR_PHY_ID - invalid PHY no
+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
+ * Note:
+ * None
+ */
+ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData )
+{
+ ret_t retVal;
+ rtk_uint32 regData;
+ rtk_uint32 busyFlag, checkCounter;
+ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1;
+
+ /*Check internal phy access busy or not*/
+ /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/
+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag);
+ if(retVal != RT_ERR_OK)
+ return retVal;
+
+ if(busyFlag)
+ return RT_ERR_BUSYWAIT_TIMEOUT;
+
+ /* OCP prefix */
+ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10);
+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK)
+ return retVal;
+
+ /*prepare access data*/
+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA, ocpData);
+ if(retVal != RT_ERR_OK)
+ return retVal;
+
+ /*prepare access address*/
+ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F);
+ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F);
+ regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1;
+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData);
+ if(retVal != RT_ERR_OK)
+ return retVal;
+
+ /*Set WRITE Command*/
+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK | RTL8367C_RW_MASK);
+
+ checkCounter = 100;
+ while(checkCounter)
+ {
+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag);
+ if((retVal != RT_ERR_OK) || busyFlag)
+ {
+ checkCounter --;
+ if(0 == checkCounter)
+ return RT_ERR_BUSYWAIT_TIMEOUT;
+ }
+ else
+ {
+ checkCounter = 0;
+ }
+ }
+
+ return retVal;
+}
+/* Function Name:
+ * rtl8367c_getAsicPHYOCPReg
+ * Description:
+ * Get PHY OCP registers
+ * Input:
+ * phyNo - Physical port number (0~7)
+ * ocpAddr - PHY address
+ * pRegData - read data
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PHY_REG_ID - invalid PHY address
+ * RT_ERR_PHY_ID - invalid PHY no
+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
+ * Note:
+ * None
+ */
+ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData )
+{
+ ret_t retVal;
+ rtk_uint32 regData;
+ rtk_uint32 busyFlag,checkCounter;
+ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1;
+ /*Check internal phy access busy or not*/
+ /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/
+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag);
+ if(retVal != RT_ERR_OK)
+ return retVal;
+
+ if(busyFlag)
+ return RT_ERR_BUSYWAIT_TIMEOUT;
+
+ /* OCP prefix */
+ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10);
+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK)
+ return retVal;
+
+ /*prepare access address*/
+ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F);
+ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F);
+ regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1;
+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData);
+ if(retVal != RT_ERR_OK)
+ return retVal;
+
+ /*Set READ Command*/
+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK );
+ if(retVal != RT_ERR_OK)
+ return retVal;
+
+ checkCounter = 100;
+ while(checkCounter)
+ {
+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag);
+ if((retVal != RT_ERR_OK) || busyFlag)
+ {
+ checkCounter --;
+ if(0 == checkCounter)
+ return RT_ERR_FAILED;
+ }
+ else
+ {
+ checkCounter = 0;
+ }
+ }
+
+ /*get PHY register*/
+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_READ_DATA, &regData);
+ if(retVal != RT_ERR_OK)
+ return retVal;
+
+ *pRegData = regData;
+
+ return RT_ERR_OK;
+}
+
+#endif
+
+/* Function Name:
+ * rtl8367c_setAsicPHYReg
+ * Description:
+ * Set PHY registers
+ * Input:
+ * phyNo - Physical port number (0~7)
+ * phyAddr - PHY address (0~31)
+ * phyData - Writing data
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PHY_REG_ID - invalid PHY address
+ * RT_ERR_PHY_ID - invalid PHY no
+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
+ * Note:
+ * None
+ */
+ret_t rtl8367c_setAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 phyData )
+{
+ rtk_uint32 ocp_addr;
+
+ if(phyAddr > RTL8367C_PHY_REGNOMAX)
+ return RT_ERR_PHY_REG_ID;
+
+ ocp_addr = 0xa400 + phyAddr*2;
+
+ return rtl8367c_setAsicPHYOCPReg(phyNo, ocp_addr, phyData);
+}
+/* Function Name:
+ * rtl8367c_getAsicPHYReg
+ * Description:
+ * Get PHY registers
+ * Input:
+ * phyNo - Physical port number (0~7)
+ * phyAddr - PHY address (0~31)
+ * pRegData - Writing data
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PHY_REG_ID - invalid PHY address
+ * RT_ERR_PHY_ID - invalid PHY no
+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
+ * Note:
+ * None
+ */
+ret_t rtl8367c_getAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 *pRegData )
+{
+ rtk_uint32 ocp_addr;
+
+ if(phyAddr > RTL8367C_PHY_REGNOMAX)
+ return RT_ERR_PHY_REG_ID;
+
+ ocp_addr = 0xa400 + phyAddr*2;
+
+ return rtl8367c_getAsicPHYOCPReg(phyNo, ocp_addr, pRegData);
+}
+
+
+/* Function Name:
+ * rtl8367c_setAsicSdsReg
+ * Description:
+ * Set Serdes registers
+ * Input:
+ * sdsId - sdsid (0~1)
+ * sdsReg - reg address (0~31)
+ * sdsPage - Writing data
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+
+ * Note:
+ * None
+ */
+
+ret_t rtl8367c_setAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 value)
+{
+ rtk_uint32 retVal;
+
+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value)) != RT_ERR_OK)
+ return retVal;
+
+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK)
+ return retVal;
+
+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0|sdsId)) != RT_ERR_OK)
+ return retVal;
+
+ return RT_ERR_OK;
+
+}
+
+/* Function Name:
+ * rtl8367c_getAiscSdsReg
+ * Description:
+ * Get Serdes registers
+ * Input:
+ * sdsId - sdsid (0~1)
+ * sdsReg - reg address (0~31)
+ * sdsPage - Writing data
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+
+ * Note:
+ * None
+ */
+ret_t rtl8367c_getAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 *value)
+{
+ rtk_uint32 retVal, busy;
+
+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK)
+ return retVal;
+
+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080|sdsId)) != RT_ERR_OK)
+ return retVal;
+
+ while(1)
+ {
+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_CMD, &busy))!=RT_ERR_OK)
+ return retVal;
+
+ if ((busy & 0x100) == 0)
+ break;
+ }
+
+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value))!=RT_ERR_OK)
+ return retVal;
+
+ return RT_ERR_OK;
+}
+
+
+
+