in microchip/lan966x_serdes.c [169:281]
static int lan966x_sd6g40_reg_cfg(struct serdes_macro *macro,
struct lan966x_sd6g40_setup *res_struct,
u32 idx)
{
u32 value;
/* Note: SerDes HSIO is configured in 1G_LAN mode */
lan_rmw(HSIO_SD_CFG_LANE_10BIT_SEL_SET(res_struct->lane_10bit_sel) |
HSIO_SD_CFG_RX_RATE_SET(res_struct->rx_rate) |
HSIO_SD_CFG_TX_RATE_SET(res_struct->tx_rate) |
HSIO_SD_CFG_TX_INVERT_SET(res_struct->tx_invert) |
HSIO_SD_CFG_RX_INVERT_SET(res_struct->rx_invert) |
HSIO_SD_CFG_LANE_LOOPBK_EN_SET(res_struct->lane_loopbk_en) |
HSIO_SD_CFG_RX_RESET_SET(0) |
HSIO_SD_CFG_TX_RESET_SET(0),
HSIO_SD_CFG_LANE_10BIT_SEL |
HSIO_SD_CFG_RX_RATE |
HSIO_SD_CFG_TX_RATE |
HSIO_SD_CFG_TX_INVERT |
HSIO_SD_CFG_RX_INVERT |
HSIO_SD_CFG_LANE_LOOPBK_EN |
HSIO_SD_CFG_RX_RESET |
HSIO_SD_CFG_TX_RESET,
macro->ctrl->regs, HSIO_SD_CFG(idx));
lan_rmw(HSIO_MPLL_CFG_MPLL_MULTIPLIER_SET(res_struct->mpll_multiplier) |
HSIO_MPLL_CFG_REF_CLKDIV2_SET(res_struct->ref_clkdiv2),
HSIO_MPLL_CFG_MPLL_MULTIPLIER |
HSIO_MPLL_CFG_REF_CLKDIV2,
macro->ctrl->regs, HSIO_MPLL_CFG(idx));
lan_rmw(HSIO_SD_CFG_RX_TERM_EN_SET(res_struct->rx_term_en),
HSIO_SD_CFG_RX_TERM_EN,
macro->ctrl->regs, HSIO_SD_CFG(idx));
lan_rmw(HSIO_MPLL_CFG_REF_SSP_EN_SET(1),
HSIO_MPLL_CFG_REF_SSP_EN,
macro->ctrl->regs, HSIO_MPLL_CFG(idx));
usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
lan_rmw(HSIO_SD_CFG_PHY_RESET_SET(0),
HSIO_SD_CFG_PHY_RESET,
macro->ctrl->regs, HSIO_SD_CFG(idx));
usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
lan_rmw(HSIO_MPLL_CFG_MPLL_EN_SET(1),
HSIO_MPLL_CFG_MPLL_EN,
macro->ctrl->regs, HSIO_MPLL_CFG(idx));
usleep_range(7 * USEC_PER_MSEC, 8 * USEC_PER_MSEC);
value = readl(macro->ctrl->regs + lan_offset(HSIO_SD_STAT(idx)));
value = HSIO_SD_STAT_MPLL_STATE_GET(value);
if (value != 0x1) {
dev_err(macro->ctrl->dev,
"Unexpected sd_sd_stat[%u] mpll_state was 0x1 but is 0x%x\n",
idx, value);
return -EIO;
}
lan_rmw(HSIO_SD_CFG_TX_CM_EN_SET(1),
HSIO_SD_CFG_TX_CM_EN,
macro->ctrl->regs, HSIO_SD_CFG(idx));
usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
value = readl(macro->ctrl->regs + lan_offset(HSIO_SD_STAT(idx)));
value = HSIO_SD_STAT_TX_CM_STATE_GET(value);
if (value != 0x1) {
dev_err(macro->ctrl->dev,
"Unexpected sd_sd_stat[%u] tx_cm_state was 0x1 but is 0x%x\n",
idx, value);
return -EIO;
}
lan_rmw(HSIO_SD_CFG_RX_PLL_EN_SET(1) |
HSIO_SD_CFG_TX_EN_SET(1),
HSIO_SD_CFG_RX_PLL_EN |
HSIO_SD_CFG_TX_EN,
macro->ctrl->regs, HSIO_SD_CFG(idx));
usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
/* Waiting for serdes 0 rx DPLL to lock... */
value = readl(macro->ctrl->regs + lan_offset(HSIO_SD_STAT(idx)));
value = HSIO_SD_STAT_RX_PLL_STATE_GET(value);
if (value != 0x1) {
dev_err(macro->ctrl->dev,
"Unexpected sd_sd_stat[%u] rx_pll_state was 0x1 but is 0x%x\n",
idx, value);
return -EIO;
}
/* Waiting for serdes 0 tx operational... */
value = readl(macro->ctrl->regs + lan_offset(HSIO_SD_STAT(idx)));
value = HSIO_SD_STAT_TX_STATE_GET(value);
if (value != 0x1) {
dev_err(macro->ctrl->dev,
"Unexpected sd_sd_stat[%u] tx_state was 0x1 but is 0x%x\n",
idx, value);
return -EIO;
}
lan_rmw(HSIO_SD_CFG_TX_DATA_EN_SET(1) |
HSIO_SD_CFG_RX_DATA_EN_SET(1),
HSIO_SD_CFG_TX_DATA_EN |
HSIO_SD_CFG_RX_DATA_EN,
macro->ctrl->regs, HSIO_SD_CFG(idx));
return 0;
}