Files
xiuos/Ubiquitous/XiZi_AIoT/services/drivers/rk-3568/ethernet/gmac_3568.c
T
2024-06-03 16:45:09 +08:00

200 lines
6.0 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Copyright (c) 2021 Rockchip Electronics Co., Ltd.
*/
#include "hal_base.h"
#include "hal_gmac.h"
#include "hal_debug.h"
#include "hal_cru.h"
/** @addtogroup RK_HAL_Driver
* @{
*/
/** @addtogroup GMAC
* @{
*/
/** @defgroup GMAC_Private_Definition Private Definition
* @{
*/
/********************* Private MACRO Definition ******************************/
#define HIWORD_UPDATE(val, mask, shift) \
((val) << (shift) | (mask) << ((shift) + 16))
#define GRF_BIT(nr) (1 << (nr) | 1 << (nr+16))
#define GRF_CLR_BIT(nr) (1 << (nr+16))
#define DELAY_ENABLE(soc, tx, rx) \
(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
#define RK3568_GRF_GMAC0_CON0 0X0380
#define RK3568_GRF_GMAC0_CON1 0X0384
#define RK3568_GRF_GMAC1_CON0 0X0388
#define RK3568_GRF_GMAC1_CON1 0X038c
/* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
#define RK3568_GMAC_GMII_MODE GRF_BIT(7)
#define RK3568_GMAC_PHY_INTF_SEL_RGMII \
(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
#define RK3568_GMAC_PHY_INTF_SEL_RMII \
(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
#define RK3568_GMAC_FLOW_CTRL GRF_BIT(3)
#define RK3568_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3)
#define RK3568_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1)
#define RK3568_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1)
#define RK3568_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0)
#define RK3568_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0)
/* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
#define RK3568_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
#define RK3568_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
/********************* Private Structure Definition **************************/
/********************* Private Variable Definition ***************************/
/********************* Private Function Definition ***************************/
/** @} */
/********************* Public Function Definition ****************************/
/** @defgroup GMAC_Exported_Functions_Group5 Other Functions
* @{
*/
/**
* @brief Set RGMII Mode.
* @param pGMAC: pointer to a GMAC_HANDLE structure that contains
* the information for GMAC module.
* @param txDelay: RGMII tx delayline
* @param rxDelay: RGMII rx delayline
*/
void HAL_GMAC_SetToRGMII(struct GMAC_HANDLE *pGMAC,
int32_t txDelay, int32_t rxDelay)
{
uint32_t *con0, *con1;
con0 = (uint32_t *)((pGMAC->pReg == GMAC1) ? &(GRF->MAC1_CON0) :
&(GRF->MAC0_CON0));
con1 = (uint32_t *)((pGMAC->pReg == GMAC1) ? &(GRF->MAC1_CON1) :
&(GRF->MAC0_CON1));
WRITE_REG(*con1,
RK3568_GMAC_PHY_INTF_SEL_RGMII |
RK3568_GMAC_RXCLK_DLY_ENABLE |
RK3568_GMAC_TXCLK_DLY_ENABLE);
WRITE_REG(*con0,
RK3568_GMAC_CLK_RX_DL_CFG(rxDelay) |
RK3568_GMAC_CLK_TX_DL_CFG(txDelay));
}
/**
* @brief Set RMII Mode.
* @param pGMAC: pointer to a GMAC_HANDLE structure that contains
* the information for GMAC module.
*/
void HAL_GMAC_SetToRMII(struct GMAC_HANDLE *pGMAC)
{
uint32_t *con1, *cruCon, val;
con1 = (uint32_t *)((pGMAC->pReg == GMAC1) ? &(GRF->MAC1_CON1) :
&(GRF->MAC0_CON1));
WRITE_REG(*con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
cruCon = (uint32_t *)((pGMAC->pReg == GMAC1) ? &(CRU->CRU_CLKSEL_CON[33]) :
&(CRU->CRU_CLKSEL_CON[31]));
/* RMII mode */
val = HIWORD_UPDATE(0x1, 0x3, 0);
/* clock from io if it was */
/* val |= HIWORD_UPDATE(0x1, 0x1, 2); */
/* ref clock sel 50M */
val |= HIWORD_UPDATE(0x1, 0x3, 8);
/* clock speed 25M */
val |= HIWORD_UPDATE(0x1, 0x1, 3);
WRITE_REG(*cruCon, val);
}
/**
* @brief Set external clock source select.
* @param pGMAC: pointer to a GMAC_HANDLE structure that contains
* the information for GMAC module.
* @param extClk: 0: select clk_mac as the clock of mac
* 1: select external phy clock as the clock of mac
*/
void HAL_GMAC_SetExtclkSrc(struct GMAC_HANDLE *pGMAC, bool extClk)
{
uint32_t *cruCon, val;
uint32_t clksel = 0;
cruCon = (uint32_t *)((pGMAC->pReg == GMAC1) ? &(CRU->CRU_CLKSEL_CON[33]) :
&(CRU->CRU_CLKSEL_CON[31]));
if (extClk) {
clksel = 1;
}
val = HIWORD_UPDATE(clksel, 0x1, 2);
WRITE_REG(*cruCon, val);
}
/**
* @brief Set RGMII speed.
* @param pGMAC: pointer to a GMAC_HANDLE structure that contains
* the information for GMAC module.
* @param speed: RGMII speed 10/100/1000
*/
void HAL_GMAC_SetRGMIISpeed(struct GMAC_HANDLE *pGMAC, int32_t speed)
{
eCLOCK_Name clkID;
uint32_t rate;
int32_t ret;
switch (speed) {
case 10:
rate = 2500000;
break;
case 100:
rate = 25000000;
break;
case 1000:
rate = 125000000;
break;
default:
HAL_DBG_ERR("unknown speed value for GMAC speed=%ld", speed);
return;
}
if (pGMAC->phyStatus.interface == PHY_INTERFACE_MODE_RMII) {
clkID = (pGMAC->pReg == GMAC1) ? SCLK_GMAC1_RMII_SPEED :
SCLK_GMAC0_RMII_SPEED;
} else {
clkID = (pGMAC->pReg == GMAC1) ? SCLK_GMAC1_RGMII_SPEED :
SCLK_GMAC0_RGMII_SPEED;
}
ret = HAL_CRU_ClkSetFreq(clkID, rate);
if (ret) {
HAL_DBG_ERR("%s: set clk_mac_speed rate %ld failed %ld\n",
__func__, rate, ret);
}
}
/**
* @brief Set RGMII speed.
* @param pGMAC: pointer to a GMAC_HANDLE structure that contains
* the information for GMAC module.
* @param speed: RGMII speed 10/100
*/
void HAL_GMAC_SetRMIISpeed(struct GMAC_HANDLE *pGMAC, int32_t speed)
{
HAL_GMAC_SetRGMIISpeed(pGMAC, speed);
}