blob: ad6736f24618884a8a5db0285dc33ab6371d5281 [file] [log] [blame]
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*!@file: DWC_ETH_QOS_rgmii_io_macro.c
* @brief: RGMII IO MACRO functions.
*/
#include "DWC_ETH_QOS_yheader.h"
#include "DWC_ETH_QOS_yrgmii_io_macro_regacc.h"
/* RGMII IO MACRO power on reset values */
#define RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX 0
#define SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX 1
#define SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX 2
#define SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX 3
#define SDCC_USR_CTL_POR_ARR_INDEX 4
#define RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX 5
#define RGMII_IO_MACRO_DLL_POR_NUM_OF_REGS 6
#define RGMII_IO_MACRO_DLL_POR_REG_OFFSET_INDEX 0
#define RGMII_IO_MACRO_DLL_POR_REG_DATA_INDEX 1
ULONG rgmii_io_macro_dll_por_values
[EMAC_HW_vMAX][RGMII_IO_MACRO_DLL_POR_NUM_OF_REGS][2] = {
[EMAC_HW_None] = {
[RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET, 0x0 },
[SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_RGOFFADDR_OFFSET, 0x0 },
[SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DDR_CONFIG_RGOFFADDR_OFFSET, 0x0 },
[SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR_OFFSET, 0x0 },
[SDCC_USR_CTL_POR_ARR_INDEX] = { SDCC_USR_CTL_RGOFFADDR_OFFSET, 0x0 },
[RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_2_RGOFFADDR_OFFSET, 0x0 },
},
[EMAC_HW_v2_0_0] = {
[RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET, 0x40C01343 },
[SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_RGOFFADDR_OFFSET, 0x2004642C },
[SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DDR_CONFIG_RGOFFADDR_OFFSET, 0x00000000 },
[SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR_OFFSET, 0x00200000 },
[SDCC_USR_CTL_POR_ARR_INDEX] = { SDCC_USR_CTL_RGOFFADDR_OFFSET, 0x00000000 },
[RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_2_RGOFFADDR_OFFSET, 0x00002060 },
},
[EMAC_HW_v2_1_0] = {
[RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET, 0x40C01343 },
[SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_RGOFFADDR_OFFSET, 0x2004642C },
[SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DDR_CONFIG_RGOFFADDR_OFFSET, 0x00000000 },
[SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR_OFFSET, 0x00200000 },
[SDCC_USR_CTL_POR_ARR_INDEX] = { SDCC_USR_CTL_RGOFFADDR_OFFSET, 0x00010800 },
[RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_2_RGOFFADDR_OFFSET, 0x00002060 },
},
[EMAC_HW_v2_1_1] = {
[RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET, 0x40C01343 },
[SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_RGOFFADDR_OFFSET, 0x2004642C },
[SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DDR_CONFIG_RGOFFADDR_OFFSET, 0x00000000 },
[SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR_OFFSET, 0x00200000 },
[SDCC_USR_CTL_POR_ARR_INDEX] = { SDCC_USR_CTL_RGOFFADDR_OFFSET, 0x00000000 },
[RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_2_RGOFFADDR_OFFSET, 0x00002060 },
},
[EMAC_HW_v2_1_2] = {
[RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET, 0x40C01343 },
[SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_RGOFFADDR_OFFSET, 0x2004642C },
[SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DDR_CONFIG_RGOFFADDR_OFFSET, 0x00000000 },
[SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR_OFFSET, 0x00200000 },
[SDCC_USR_CTL_POR_ARR_INDEX] = { SDCC_USR_CTL_RGOFFADDR_OFFSET, 0x00000000 },
[RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_2_RGOFFADDR_OFFSET, 0x00002060 },
},
[EMAC_HW_v2_2_0] = {
[RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET, 0x00C01343 },
[SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_RGOFFADDR_OFFSET, 0x6004642C },
[SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DDR_CONFIG_RGOFFADDR_OFFSET, 0x00000000 },
[SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR_OFFSET, 0x00200000 },
[SDCC_USR_CTL_POR_ARR_INDEX] = { SDCC_USR_CTL_RGOFFADDR_OFFSET, 0x00010800 },
[RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_2_RGOFFADDR_OFFSET, 0x00002060 },
},
[EMAC_HW_v2_3_0] = {
[RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET, 0x00C01343 },
[SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_RGOFFADDR_OFFSET, 0x2004642C },
[SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DDR_CONFIG_RGOFFADDR_OFFSET, 0x00000000 },
[SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR_OFFSET, 0x00200000 },
[SDCC_USR_CTL_POR_ARR_INDEX] = { SDCC_USR_CTL_RGOFFADDR_OFFSET, 0x00010800 },
[RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_2_RGOFFADDR_OFFSET, 0x00002060 },
},
[EMAC_HW_v2_3_1] = {
[RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET, 0x40C01343 },
[SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_RGOFFADDR_OFFSET, 0x2004642C },
[SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DDR_CONFIG_RGOFFADDR_OFFSET, 0x00000000 },
[SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR_OFFSET, 0x00200000 },
[SDCC_USR_CTL_POR_ARR_INDEX] = { SDCC_USR_CTL_RGOFFADDR_OFFSET, 0x00000000 },
[RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_2_RGOFFADDR_OFFSET, 0x00002060 },
},
[EMAC_HW_v2_3_2] = {
[RGMII_IO_MACRO_CONFIG_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_RGOFFADDR_OFFSET, 0x40C01343 },
[SDCC_HC_REG_DLL_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_RGOFFADDR_OFFSET, 0x2004642C },
[SDCC_HC_REG_DDR_CONFIG_POR_ARR_INDEX] = { SDCC_HC_REG_DDR_CONFIG_RGOFFADDR_OFFSET, 0x00000000 },
[SDCC_HC_REG_DLL_CONFIG_2_POR_ARR_INDEX] = { SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR_OFFSET, 0x00200000 },
[SDCC_USR_CTL_POR_ARR_INDEX] = { SDCC_USR_CTL_RGOFFADDR_OFFSET, 0x00000000 },
[RGMII_IO_MACRO_CONFIG_2_POR_ARR_INDEX] = { RGMII_IO_MACRO_CONFIG_2_RGOFFADDR_OFFSET, 0x00002060 },
},
};
/* SDCDC DLL initialization */
/*!
* \brief Initialize the SDCDC
*
* \details This function will write to the various fields in
* SDCC_HC_REG_DLL_CONFIG register for the DLL
* initialization
*\return Y_SUCCESS
*/
int DWC_ETH_QOS_rgmii_io_macro_sdcdc_init(struct DWC_ETH_QOS_prv_data *pdata)
{
int reg_val = 0;
ULONG RETRYCOUNT = 1000;
ULONG current_cnt = 0;
volatile ULONG VARDLL_LOCK;
EMACDBG("Enter\n");
/* Write 1 to DLL_RST bit of SDCC_HC_REG_DLL_CONFIG register */
SDCC_HC_DLL_RST_UDFWR(0x1);
/* Write 1 to PDN bit of SDCC_HC_REG_DLL_CONFIG register */
SDCC_HC_PDN_UDFWR(0x1);
/* Write 0 to DLL_RST bit of SDCC_HC_REG_DLL_CONFIG register */
SDCC_HC_DLL_RST_UDFWR(0x0);
/* Write 0 to PDN bit of SDCC_HC_REG_DLL_CONFIG register */
SDCC_HC_PDN_UDFWR(0x0);
/* DLL RST=0 and PDN=0 are sufficient for RGMII_ID 10/100 Mbps mode */
if (pdata->speed == SPEED_100 || pdata->speed == SPEED_10) {
EMACDBG("Bail out\n");
return Y_SUCCESS;
}
/* Write 1 to DLL_EN */
SDCC_HC_DLL_EN_UDFWR(0x1);
/* Write 1 to CK_OUT_EN */
SDCC_HC_CK_OUT_EN_UDFWR(0x1);
SDCC_USR_CTL_RGRD(reg_val);
reg_val &= ~(0x7UL<<24);
reg_val |= (0x4UL<<24);
SDCC_USR_CTL_RGWR(reg_val);
/* Wait until DLL_LOCK bit of SDC4_STATUS register is 1 */
while (1) {
if (current_cnt > RETRYCOUNT)
return -Y_FAILURE;
SDC4_STATUS_DLL_LOCK_STS_UDFRD(VARDLL_LOCK);
if (VARDLL_LOCK == 1) {
EMACDBG("DLL lock status bit set. DLL init successful\n");
break;
}
current_cnt++;
mdelay(1);
}
EMACDBG("Exit\n");
return Y_SUCCESS;
}
/* SDCDC low power mode */
/*!
* \brief Put SDCDC in the lowest power consumption mode
*
* \details This function will write to the PDN field in
* SDCC_HC_REG_DLL_CONFIG register to enable low power mode
*
*\return 0 on success and -ve on failure.
*/
int DWC_ETH_QOS_rgmii_io_macro_sdcdc_enable_lp_mode(void)
{
EMACDBG("Enter\n");
/* Write 1 to PDN bit of SDCC_HC_REG_DLL_CONFIG register */
SDCC_HC_PDN_UDFWR(0x1);
EMACDBG("Exit\n");
return Y_SUCCESS;
}
/* SDCDC DLL configuration */
/*!
* \brief Configure SDCDC DLL config
*
* \details This function will write to the various fields in
* SDCC_HC_REG_DLL_CONFIG and SDCC_HC_REG_DLL_CONFIG_2
* registers for DLL configuration
*
*\return 0 on success and -1 on failure.
*/
int DWC_ETH_QOS_rgmii_io_macro_sdcdc_config(struct DWC_ETH_QOS_prv_data *pdata)
{
ULONG RETRYCOUNT = 1000;
ULONG current_cnt = 0;
volatile ULONG VARCK_OUT_EN;
EMACDBG("Enter\n");
if (pdata->emac_hw_version_type == EMAC_HW_v2_3_0) {
/* Set CDR_EN bit to 1 */
SDCC_HC_CDR_EN_UDFWR(0x1);
} else {
/* Set CDR_EN bit to 0 */
SDCC_HC_CDR_EN_UDFWR(0x0);
}
/* Set CDR_EXT_EN bit to 1 */
SDCC_HC_CDR_EXT_EN_UDFWR(0x1);
/* Set CK_OUT_EN bit to 0 */
SDCC_HC_CK_OUT_EN_UDFWR(0x0);
/* Set DLL_EN bit to 1 */
SDCC_HC_DLL_EN_UDFWR(0x1);
if (pdata->emac_hw_version_type == EMAC_HW_v2_3_0) {
/* Set MCLK_GATING_ENABLE bit to 0 */
SDCC_HC_MCLK_GATING_ENABLE_UDFWR(0x0);
/* Set CDR_FINE_PHASE bit to 0 */
SDCC_HC_CDR_FINE_PHASE_UDFWR(0x0);
}
/* Wait until CK_OUT_EN bit of SDCC_HC_REG_DLL_CONFIG register
* is 0
*/
while (1) {
if (current_cnt > RETRYCOUNT)
return -Y_FAILURE;
SDCC_HC_CK_OUT_EN_UDFRD(VARCK_OUT_EN);
if (VARCK_OUT_EN == 0)
break;
current_cnt++;
mdelay(1);
}
/* Set CK_OUT_EN bit to 1 */
SDCC_HC_CK_OUT_EN_UDFWR(0x1);
/* Wait until CK_OUT_EN bit of SDCC_HC_REG_DLL_CONFIG register
* is 1
*/
current_cnt = 0;
while (1) {
if (current_cnt > RETRYCOUNT)
return -Y_FAILURE;
SDCC_HC_CK_OUT_EN_UDFRD(VARCK_OUT_EN);
if (VARCK_OUT_EN == 1)
break;
current_cnt++;
mdelay(1);
}
/* Write 1 to DDR_CAL_EN bit of SDCC_HC_REG_DLL_CONFIG_2
* register
*/
SDCC_HC_CFG_2_DDR_CAL_EN_UDFWR(0x1);
if (pdata->emac_hw_version_type == EMAC_HW_v2_3_0) {
/* Set DLL_CLOCK_DISABLE bit to 0 */
SDCC_HC_CFG_2_DLL_CLOCK_DISABLE_UDFWR(0x0);
/* Set MCLK_FREQ_CALC bit to 26 */
SDCC_HC_CFG_2_MCLK_FREQ_CALC_UDFWR(0x1A);
/* Set DDR_TRAFFIC_INIT_SEL bit to 0 */
SDCC_HC_CFG_2_DDR_TRAFFIC_INIT_SEL_UDFWR(0x1);
/* Set DDR_TRAFFIC_INIT_SW bit to 0 */
SDCC_HC_CFG_2_DDR_TRAFFIC_INIT_SW_UDFWR(0x1);
}
EMACDBG("Exit\n");
return Y_SUCCESS;
}
/* SDCC DLL Bypass mode programming */
/*!
* \brief Enable SDCC DLL Bypass mode programming
*
* \details This function will write to the PDN field in
* SDCC_HC_REG_DLL_CONFIG register and bypass bit in
* SDCC_DLL_TEST_CTL register
*
*\return 0 on success
*/
int DWC_ETH_QOS_sdcc_set_bypass_mode(void)
{
EMACDBG("Enter\n");
/* Write 1 to PDN bit of SDCC_HC_REG_DLL_CONFIG register */
SDCC_HC_PDN_UDFWR(0x1);
/* Write 1 to bypass bit of SDCC_USR_CTL register */
SDCC_USR_CTL_BYPASS_MODE_UDFWR(0x1);
EMACDBG("Exit\n");
return Y_SUCCESS;
}
/* Programming rgmii_io_macro register for loopback mode */
/*!
* \brief Initialize the rgmii io macro block
*
* \details This function will write to the loopback
* fields in RGMII_IO_MACRO_CONFIG RGMII_IO_MACRO_CONFIG_2
* registers to set the RGMII loopback mode
*
*\return 0 on success
*/
static int DWC_ETH_QOS_set_rgmii_loopback_mode(UINT lb_mode)
{
EMACDBG("Enter\n");
RGMII_CONFIG_2_TX_TO_RX_LOOPBACK_EN_UDFWR(lb_mode);
EMACDBG("RGMII loopback mode set to = %d\n", lb_mode);
EMACDBG("Exit\n");
return Y_SUCCESS;
}
/* Programming rgmii_io_macro register for func_clk_en */
/*!
* \brief Initialize the rgmii io macro block
*
* \details This function will write to the func_clk_en
* fields in RGMII_IO_MACRO_CONFIG
*
*\return 0 on success
*/
int DWC_ETH_QOS_set_rgmii_func_clk_en(void)
{
EMACDBG("Enter\n");
RGMII_FUNC_CLK_EN_UDFWR(1);
EMACDBG("Exit\n");
return Y_SUCCESS;
}
/* Programming rgmii_io_macro register initialization */
/*!
* \brief Initialize the rgmii io macro block
*
* \details This function will write to the various
* fields in RGMII_IO_MACRO_CONFIG register to set the RGMII mode
*
*\return 0 on success
*/
int DWC_ETH_QOS_rgmii_io_macro_init(struct DWC_ETH_QOS_prv_data *pdata)
{
uint loopback_mode = 0;
uint loopback_mode_en = 0;
uint rgmii_data_divide_clk;
ULONG data;
if (pdata->emac_hw_version_type == EMAC_HW_v2_3_0 || (pdata->emac_hw_version_type == EMAC_HW_v2_3_1)) {
if(pdata->io_macro_phy_intf == RGMII_MODE)
loopback_mode_en = 0x1;
rgmii_data_divide_clk = 0x0;
} else {
loopback_mode_en = 0x0;
rgmii_data_divide_clk = 0x1;
}
EMACDBG("Enter\n");
/* Loopback is disabled */
DWC_ETH_QOS_set_rgmii_loopback_mode(loopback_mode);
switch (pdata->io_macro_phy_intf) {
case RGMII_MODE:
/* Select RGMII interface */
RGMII_INTF_SEL_UDFWR(0x0);
switch (pdata->speed) {
case SPEED_1000:
EMACDBG("Set RGMII registers for speed = %d\n", pdata->speed);
if (pdata->io_macro_tx_mode_non_id){
EMACDBG(
"Set registers for Bypass mode = %d\n",
pdata->io_macro_tx_mode_non_id);
/* Enable DDR mode*/
RGMII_DDR_MODE_UDFWR(0x1);
RGMII_BYPASS_TX_ID_EN_UDFWR(0x1);
RGMII_POS_NEG_DATA_SEL_UDFWR(0x0);
RGMII_PROG_SWAP_UDFWR(0x0);
RGMII_CONFIG_2_DATA_DIVIDE_CLK_SEL_UDFWR(rgmii_data_divide_clk);
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x0);
RGMII_CONFIG_2_RERVED_CONFIG_16_EN_UDFWR(0x0);
/* Rx Path */
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x1);
RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en);
if (pdata->emac_hw_version_type == EMAC_HW_v2_1_0 ||
pdata->emac_hw_version_type == EMAC_HW_v2_1_2 ||
(pdata->emac_hw_version_type == EMAC_HW_v2_3_1))
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1);
} else {
/* Enable DDR mode*/
RGMII_DDR_MODE_UDFWR(0x1);
RGMII_BYPASS_TX_ID_EN_UDFWR(0x0);
RGMII_POS_NEG_DATA_SEL_UDFWR(0x1);
/* RGMII_TX_POS and RGMII_TX_NEG input pins are swapped
* based on the programmable swap control bit
*/
RGMII_PROG_SWAP_UDFWR(0x1);
RGMII_CONFIG_2_DATA_DIVIDE_CLK_SEL_UDFWR(rgmii_data_divide_clk);
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1);
RGMII_CONFIG_2_RERVED_CONFIG_16_EN_UDFWR(0x0);
/* If data arrives at positive edge or if data is
* delayed by 1.5ns/ 2ns then write 1 to RX_PROG_SWAP
* bit of register EMAC_RGMII_IO_MACRO_CONFIG_2
*/
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x1);
/* Program PRG_RCLK_DLY to 52 ns for a required delay of 2 ns on HANA AU */
if (pdata->emac_hw_version_type == EMAC_HW_v2_1_0 ||
pdata->emac_hw_version_type == EMAC_HW_v2_1_2)
SDCC_HC_PRG_RCLK_DLY_UDFWR(52);
else if (pdata->emac_hw_version_type == EMAC_HW_v2_3_1)
SDCC_HC_PRG_RCLK_DLY_UDFWR(104);
else { /* Program PRG_RCLK_DLY to 57 for a required delay of 1.8 ns */
SDCC_HC_PRG_RCLK_DLY_UDFWR(57);
}
SDCC_HC_REG_DDR_CONFIG_RGRD(data);
data |= (1 << 31);
SDCC_HC_REG_DDR_CONFIG_RGWR(data);
RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en);
}
break;
case SPEED_100:
EMACDBG("Set RGMII registers for speed = %d\n", pdata->speed);
if (pdata->io_macro_tx_mode_non_id) {
EMACDBG("Set registers for Bypass mode = %d\n",
pdata->io_macro_tx_mode_non_id);
RGMII_DDR_MODE_UDFWR(0x0);
RGMII_BYPASS_TX_ID_EN_UDFWR(0x1);
RGMII_POS_NEG_DATA_SEL_UDFWR(0x0);
RGMII_PROG_SWAP_UDFWR(0x0);
RGMII_CONFIG_2_DATA_DIVIDE_CLK_SEL_UDFWR(rgmii_data_divide_clk);
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x0);
RGMII_MAX_SPD_PRG_2_UDFWR(0x1);
RGMII_CONFIG_2_RERVED_CONFIG_16_EN_UDFWR(0x1);
/* Rx Path */
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x0);
RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en);
if (pdata->emac_hw_version_type == EMAC_HW_v2_1_0 ||
pdata->emac_hw_version_type == EMAC_HW_v2_1_2 ||
(pdata->emac_hw_version_type == EMAC_HW_v2_3_1))
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x1);
if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2)
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1);
} else{
RGMII_DDR_MODE_UDFWR(0x1);
RGMII_BYPASS_TX_ID_EN_UDFWR(0x1);
RGMII_POS_NEG_DATA_SEL_UDFWR(0x0);
RGMII_PROG_SWAP_UDFWR(0x0);
RGMII_CONFIG_2_DATA_DIVIDE_CLK_SEL_UDFWR(rgmii_data_divide_clk);
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1);
RGMII_MAX_SPD_PRG_2_UDFWR(0x1);
RGMII_CONFIG_2_RERVED_CONFIG_16_EN_UDFWR(0x0);
/* Rx Path */
if (pdata->emac_hw_version_type == EMAC_HW_v2_3_0)
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x0);
else
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x1);
SDCC_HC_EXT_PRG_RCLK_DLY_CODE_UDFWR(0x5);
SDCC_HC_EXT_PRG_RCLK_DLY_UDFWR(0x3f);
SDCC_HC_EXT_PRG_RCLK_DLY_EN_UDFWR(0x1);
RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en);
}
break;
case SPEED_10:
EMACDBG("Set RGMII registers for speed = %d\n", pdata->speed);
if (pdata->io_macro_tx_mode_non_id) {
EMACDBG("Set registers for Bypass mode = %d\n",
pdata->io_macro_tx_mode_non_id);
RGMII_DDR_MODE_UDFWR(0x0);
RGMII_BYPASS_TX_ID_EN_UDFWR(0x1);
RGMII_POS_NEG_DATA_SEL_UDFWR(0x0);
RGMII_PROG_SWAP_UDFWR(0x0);
RGMII_CONFIG_2_DATA_DIVIDE_CLK_SEL_UDFWR(rgmii_data_divide_clk);
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x0);
RGMII_MAX_SPD_PRG_9_UDFWR(0x13);
RGMII_CONFIG_2_RERVED_CONFIG_16_EN_UDFWR(0x1);
/* Rx Path */
if (pdata->emac_hw_version_type == EMAC_HW_v2_3_1)
RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en);
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x0);
RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en);
if (pdata->emac_hw_version_type == EMAC_HW_v2_1_0 ||
pdata->emac_hw_version_type == EMAC_HW_v2_1_2 ||
(pdata->emac_hw_version_type == EMAC_HW_v2_3_1))
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x1);
if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2)
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1);
} else{
RGMII_DDR_MODE_UDFWR(0x1);
RGMII_BYPASS_TX_ID_EN_UDFWR(0x1);
RGMII_POS_NEG_DATA_SEL_UDFWR(0x0);
RGMII_PROG_SWAP_UDFWR(0x0);
RGMII_CONFIG_2_DATA_DIVIDE_CLK_SEL_UDFWR(rgmii_data_divide_clk);
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1);
RGMII_MAX_SPD_PRG_9_UDFWR(0x13);
RGMII_CONFIG_2_RERVED_CONFIG_16_EN_UDFWR(0x0);
/* Rx Path */
if (pdata->emac_hw_version_type == EMAC_HW_v2_3_0)
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x0);
else
RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x1);
SDCC_HC_EXT_PRG_RCLK_DLY_CODE_UDFWR(0x5);
SDCC_HC_EXT_PRG_RCLK_DLY_UDFWR(0x3f);
SDCC_HC_EXT_PRG_RCLK_DLY_EN_UDFWR(0x1);
RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en);
}
break;
default:
EMACDBG(
"No RGMII register settings for link speed = %d\n",
pdata->speed);
break;
}
break;
case RMII_MODE:
EMACDBG("Set registers for RMII mode and speed = %d\n", pdata->speed);
RGMII_INTF_SEL_UDFWR(0x01);
RGMII_DDR_MODE_UDFWR(0x0);
RGMII_BYPASS_TX_ID_EN_UDFWR(0x1);
RGMII_POS_NEG_DATA_SEL_UDFWR(0x0);
RGMII_PROG_SWAP_UDFWR(0x1);
RGMII_CONFIG_2_DATA_DIVIDE_CLK_SEL_UDFWR(0x1);
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x0);
RGMII_CONFIG_2_CLK_DIVIDE_SEL_UDFWR(0x1);
RGMII_MAX_SPD_PRG_2_UDFWR(0x1);
RGMII_MAX_SPD_PRG_9_UDFWR(0x13);
RGMII_CONFIG_2_RERVED_CONFIG_16_EN_UDFWR(0x0);
if (pdata->emac_hw_version_type == EMAC_HW_v2_3_0 || (pdata->emac_hw_version_type == EMAC_HW_v2_3_1))
RGMII_LOOPBACK_EN_UDFWR(0x0);
else
RGMII_LOOPBACK_EN_UDFWR(0x1);
break;
case MII_MODE:
EMACDBG("Set registers for MII mode and speed = %d\n", pdata->speed);
RGMII_INTF_SEL_UDFWR(0x2);
RGMII_DDR_MODE_UDFWR(0x0);
RGMII_BYPASS_TX_ID_EN_UDFWR(0x1);
RGMII_POS_NEG_DATA_SEL_UDFWR(0x0);
RGMII_PROG_SWAP_UDFWR(0x0);
RGMII_CONFIG_2_DATA_DIVIDE_CLK_SEL_UDFWR(0x1);
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x0);
RGMII_CONFIG_2_RERVED_CONFIG_16_EN_UDFWR(0x1);
if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2)
RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1);
if (pdata->emac_hw_version_type == EMAC_HW_v2_3_1)
RGMII_LOOPBACK_EN_UDFWR(0x1);
break;
}
EMACDBG("Exit\n");
return Y_SUCCESS;
}
/* Programming IO macro and DLL registers with POR values */
/*!
* \brief Reset the IO MACRO and DLL blocks
*
* \details This function will write POR values to RGMII and
* DLL registers.
*
*\return Y_SUCCESS
*/
int DWC_ETH_QOS_rgmii_io_macro_dll_reset(struct DWC_ETH_QOS_prv_data *pdata)
{
int index_of_reg;
ULONG data, address;
EMACDBG("Enter\n");
for (index_of_reg = 0 ; index_of_reg < RGMII_IO_MACRO_DLL_POR_NUM_OF_REGS; index_of_reg++) {
address = RGMII_IO_BASE_ADDRESS
+ rgmii_io_macro_dll_por_values
[pdata->emac_hw_version_type]
[index_of_reg]
[RGMII_IO_MACRO_DLL_POR_REG_OFFSET_INDEX];
data = rgmii_io_macro_dll_por_values
[pdata->emac_hw_version_type]
[index_of_reg]
[RGMII_IO_MACRO_DLL_POR_REG_DATA_INDEX];
iowrite32(data, (void *)address);
}
DWC_ETH_QOS_set_rgmii_func_clk_en();
EMACDBG("Exit\n");
return Y_SUCCESS;
}
void dump_rgmii_io_macro_registers(void)
{
int reg_val;
pr_alert(
"\n************* RGMII IO Macro Reg dump *************************\n");
RGMII_IO_MACRO_CONFIG_RGRD(reg_val);
pr_alert(
"RGMII_IO_MACRO_CONFIG (0x%p) = %#x\n",
RGMII_IO_MACRO_CONFIG_RGOFFADDR, reg_val);
SDCC_HC_REG_DLL_CONFIG_RGRD(reg_val);
pr_alert(
"SDCC_HC_REG_DLL_CONFIG (0x%p) = %#x\n",
SDCC_HC_REG_DLL_CONFIG_RGOFFADDR, reg_val);
SDCC_HC_REG_DDR_CONFIG_RGRD(reg_val);
pr_alert(
"SDCC_HC_REG_DDR_CONFIG (0x%p) = %#x\n",
SDCC_HC_REG_DDR_CONFIG_RGOFFADDR, reg_val);
SDCC_HC_REG_DLL_CONFIG_2_RGRD(reg_val);
pr_alert(
"SDCC_HC_REG_DLL_CONFIG_2 (0x%p) = %#x\n",
SDCC_HC_REG_DLL_CONFIG_2_RGOFFADDR, reg_val);
RGMII_IO_MACRO_CONFIG_2_RGRD(reg_val);
pr_alert(
"RGMII_IO_MACRO_CONFIG_2 (0x%p) = %#x\n",
RGMII_IO_MACRO_CONFIG_2_RGOFFADDR, reg_val);
RGMII_IO_MACRO_DEBUG_1_RGRD(reg_val);
pr_alert(
"RGMII_IO_MACRO_DEBUG_1 (0x%p) = %#x\n",
RGMII_IO_MACRO_DEBUG_1_RGOFFADDR, reg_val);
SDC4_STATUS_RGRD(reg_val);
pr_alert(
"SDC4_STATUS_RGRD (0x%p) = %#x\n",
SDC4_STATUS_RGOFFADDR, reg_val);
SDCC_USR_CTL_RGRD(reg_val);
pr_alert(
"SDCC_USR_CTL_RGRD (0x%p) = %#x\n",
SDCC_USR_CTL_RGOFFADDR, reg_val);
EMAC_SYSTEM_LOW_POWER_DEBUG_RGRD(reg_val);
pr_alert(
"EMAC_SYSTEM_LOW_POWER_DEBUG_RGRD (0x%p) = %#x\n",
EMAC_SYSTEM_LOW_POWER_DEBUG_RGOFFADDR, reg_val);
pr_alert("\n****************************************************\n");
}