200 lines
6.0 KiB
C
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);
|
|
}
|
|
|