clk: rockchip: rv1126: Add support for gmac
Change-Id: I10ade6acbbfe5dd23e33a250ef601948606bc57e Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
This commit is contained in:
parent
b0c9708366
commit
2438a166f4
|
|
@ -337,11 +337,43 @@ enum {
|
|||
CLK_NANDC_DIV_SHIFT = 0,
|
||||
CLK_NANDC_DIV_MASK = 0xff,
|
||||
|
||||
/* CRU_CLK_SEL61_CON */
|
||||
CLK_GMAC_OUT_SEL_SHIFT = 15,
|
||||
CLK_GMAC_OUT_SEL_MASK = 0x1 << CLK_GMAC_OUT_SEL_SHIFT,
|
||||
CLK_GMAC_OUT_SEL_CPLL = 0,
|
||||
CLK_GMAC_OUT_SEL_GPLL,
|
||||
CLK_GMAC_OUT_DIV_SHIFT = 8,
|
||||
CLK_GMAC_OUT_DIV_MASK = 0x1f << CLK_GMAC_OUT_DIV_SHIFT,
|
||||
|
||||
/* CRU_CLK_SEL63_CON */
|
||||
PCLK_GMAC_DIV_SHIFT = 8,
|
||||
PCLK_GMAC_DIV_MASK = 0x1f << PCLK_GMAC_DIV_SHIFT,
|
||||
CLK_GMAC_SRC_SEL_SHIFT = 7,
|
||||
CLK_GMAC_SRC_SEL_MASK = 0x1 << CLK_GMAC_SRC_SEL_SHIFT,
|
||||
CLK_GMAC_SRC_SEL_CPLL = 0,
|
||||
CLK_GMAC_SRC_SEL_GPLL,
|
||||
CLK_GMAC_SRC_DIV_SHIFT = 0,
|
||||
CLK_GMAC_SRC_DIV_MASK = 0x1f << CLK_GMAC_SRC_DIV_SHIFT,
|
||||
|
||||
/* CRU_GMAC_CON */
|
||||
GMAC_SRC_M1_SEL_SHIFT = 5,
|
||||
GMAC_SRC_M1_SEL_MASK = 0x1 << GMAC_SRC_M1_SEL_SHIFT,
|
||||
GMAC_SRC_M1_SEL_INT = 0,
|
||||
GMAC_SRC_M1_SEL_EXT,
|
||||
GMAC_MODE_SEL_SHIFT = 4,
|
||||
GMAC_MODE_SEL_MASK = 0x1 << GMAC_MODE_SEL_SHIFT,
|
||||
GMAC_RGMII_MODE = 0,
|
||||
GMAC_RMII_MODE,
|
||||
RGMII_CLK_SEL_SHIFT = 2,
|
||||
RGMII_CLK_SEL_MASK = 0x3 << RGMII_CLK_SEL_SHIFT,
|
||||
RGMII_CLK_DIV0 = 0,
|
||||
RGMII_CLK_DIV1,
|
||||
RGMII_CLK_DIV50,
|
||||
RGMII_CLK_DIV5,
|
||||
RMII_CLK_SEL_SHIFT = 1,
|
||||
RMII_CLK_SEL_MASK = 0x1 << RMII_CLK_SEL_SHIFT,
|
||||
RMII_CLK_DIV20 = 0,
|
||||
RMII_CLK_DIV2,
|
||||
GMAC_SRC_M0_SEL_SHIFT = 0,
|
||||
GMAC_SRC_M0_SEL_MASK = 0x1,
|
||||
GMAC_SRC_M0_SEL_INT = 0,
|
||||
|
|
|
|||
|
|
@ -1288,6 +1288,114 @@ static ulong rv1126_scr1_set_clk(struct rv1126_clk_priv *priv, ulong rate)
|
|||
return rv1126_scr1_get_clk(priv);
|
||||
}
|
||||
|
||||
static ulong rv1126_gmac_src_get_clk(struct rv1126_clk_priv *priv)
|
||||
{
|
||||
struct rv1126_cru *cru = priv->cru;
|
||||
u32 div, sel, con, parent;
|
||||
|
||||
con = readl(&cru->clksel_con[63]);
|
||||
div = (con & CLK_GMAC_SRC_DIV_MASK) >> CLK_GMAC_SRC_DIV_SHIFT;
|
||||
sel = (con & CLK_GMAC_SRC_SEL_MASK) >> CLK_GMAC_SRC_SEL_SHIFT;
|
||||
if (sel == CLK_GMAC_SRC_SEL_CPLL)
|
||||
parent = priv->cpll_hz;
|
||||
else if (sel == CLK_GMAC_SRC_SEL_GPLL)
|
||||
parent = priv->gpll_hz;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
||||
return DIV_TO_RATE(parent, div);
|
||||
}
|
||||
|
||||
static ulong rv1126_gmac_src_set_clk(struct rv1126_clk_priv *priv, ulong rate)
|
||||
{
|
||||
struct rv1126_cru *cru = priv->cru;
|
||||
int src_clk_div;
|
||||
|
||||
src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
|
||||
assert(src_clk_div - 1 <= 31);
|
||||
rk_clrsetreg(&cru->clksel_con[63],
|
||||
CLK_GMAC_SRC_SEL_MASK | CLK_GMAC_SRC_DIV_MASK,
|
||||
CLK_GMAC_SRC_SEL_CPLL << CLK_GMAC_SRC_SEL_SHIFT |
|
||||
(src_clk_div - 1) << CLK_GMAC_SRC_DIV_SHIFT);
|
||||
|
||||
return rv1126_gmac_src_get_clk(priv);
|
||||
}
|
||||
|
||||
static ulong rv1126_gmac_out_get_clk(struct rv1126_clk_priv *priv)
|
||||
{
|
||||
struct rv1126_cru *cru = priv->cru;
|
||||
u32 div, sel, con, parent;
|
||||
|
||||
con = readl(&cru->clksel_con[61]);
|
||||
div = (con & CLK_GMAC_OUT_DIV_MASK) >> CLK_GMAC_OUT_DIV_SHIFT;
|
||||
sel = (con & CLK_GMAC_OUT_SEL_MASK) >> CLK_GMAC_OUT_SEL_SHIFT;
|
||||
if (sel == CLK_GMAC_OUT_SEL_CPLL)
|
||||
parent = priv->cpll_hz;
|
||||
else if (sel == CLK_GMAC_OUT_SEL_GPLL)
|
||||
parent = priv->gpll_hz;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
||||
return DIV_TO_RATE(parent, div);
|
||||
}
|
||||
|
||||
static ulong rv1126_gmac_out_set_clk(struct rv1126_clk_priv *priv, ulong rate)
|
||||
{
|
||||
struct rv1126_cru *cru = priv->cru;
|
||||
int src_clk_div;
|
||||
|
||||
src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
|
||||
assert(src_clk_div - 1 <= 31);
|
||||
rk_clrsetreg(&cru->clksel_con[61],
|
||||
CLK_GMAC_OUT_SEL_MASK | CLK_GMAC_OUT_DIV_MASK,
|
||||
CLK_GMAC_OUT_SEL_CPLL << CLK_GMAC_OUT_SEL_SHIFT |
|
||||
(src_clk_div - 1) << CLK_GMAC_OUT_DIV_SHIFT);
|
||||
|
||||
return rv1126_gmac_out_get_clk(priv);
|
||||
}
|
||||
|
||||
static ulong rv1126_gmac_tx_rx_set_clk(struct rv1126_clk_priv *priv, ulong rate)
|
||||
{
|
||||
struct rv1126_cru *cru = priv->cru;
|
||||
u32 con, sel, div_sel;
|
||||
|
||||
con = readl(&cru->gmac_con);
|
||||
sel = (con & GMAC_MODE_SEL_MASK) >> GMAC_MODE_SEL_SHIFT;
|
||||
|
||||
if (sel == GMAC_RGMII_MODE) {
|
||||
if (rate == 2500000)
|
||||
div_sel = RGMII_CLK_DIV50;
|
||||
else if (rate == 25000000)
|
||||
div_sel = RGMII_CLK_DIV5;
|
||||
else
|
||||
div_sel = RGMII_CLK_DIV0;
|
||||
rk_clrsetreg(&cru->gmac_con, RGMII_CLK_SEL_MASK,
|
||||
div_sel << RGMII_CLK_SEL_SHIFT);
|
||||
} else if (sel == GMAC_RMII_MODE) {
|
||||
if (rate == 2500000)
|
||||
div_sel = RMII_CLK_DIV20;
|
||||
else
|
||||
div_sel = RMII_CLK_DIV2;
|
||||
rk_clrsetreg(&cru->gmac_con, RMII_CLK_SEL_MASK,
|
||||
div_sel << RMII_CLK_SEL_SHIFT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong rv1126_pclk_gmac_get_clk(struct rv1126_clk_priv *priv)
|
||||
{
|
||||
struct rv1126_cru *cru = priv->cru;
|
||||
u32 div, con, parent;
|
||||
|
||||
parent = rv1126_pdphp_get_clk(priv, ACLK_PDPHP);
|
||||
|
||||
con = readl(&cru->clksel_con[63]);
|
||||
div = (con & PCLK_GMAC_DIV_MASK) >> PCLK_GMAC_DIV_SHIFT;
|
||||
|
||||
return DIV_TO_RATE(parent, div);
|
||||
}
|
||||
|
||||
static ulong rv1126_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
|
|
@ -1372,6 +1480,15 @@ static ulong rv1126_clk_get_rate(struct clk *clk)
|
|||
case CLK_SCR1_CORE:
|
||||
rate = rv1126_scr1_get_clk(priv);
|
||||
break;
|
||||
case CLK_GMAC_SRC:
|
||||
rate = rv1126_gmac_src_get_clk(priv);
|
||||
break;
|
||||
case CLK_GMAC_ETHERNET_OUT:
|
||||
rate = rv1126_gmac_out_get_clk(priv);
|
||||
break;
|
||||
case PCLK_GMAC:
|
||||
rate = rv1126_pclk_gmac_get_clk(priv);
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
|
@ -1463,6 +1580,15 @@ static ulong rv1126_clk_set_rate(struct clk *clk, ulong rate)
|
|||
case CLK_SCR1_CORE:
|
||||
ret = rv1126_scr1_set_clk(priv, rate);
|
||||
break;
|
||||
case CLK_GMAC_SRC:
|
||||
ret = rv1126_gmac_src_set_clk(priv, rate);
|
||||
break;
|
||||
case CLK_GMAC_ETHERNET_OUT:
|
||||
ret = rv1126_gmac_out_set_clk(priv, rate);
|
||||
break;
|
||||
case CLK_GMAC_TX_RX:
|
||||
ret = rv1126_gmac_tx_rx_set_clk(priv, rate);
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
|
@ -1643,6 +1769,21 @@ static int rv1126_gmac_src_m1_set_parent(struct clk *clk, struct clk *parent)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rv1126_gmac_tx_rx_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
struct rv1126_cru *cru = priv->cru;
|
||||
|
||||
if (parent->id == RGMII_MODE_CLK)
|
||||
rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
|
||||
GMAC_RGMII_MODE << GMAC_MODE_SEL_SHIFT);
|
||||
else
|
||||
rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
|
||||
GMAC_RMII_MODE << GMAC_MODE_SEL_SHIFT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rv1126_clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
switch (clk->id) {
|
||||
|
|
@ -1652,6 +1793,8 @@ static int rv1126_clk_set_parent(struct clk *clk, struct clk *parent)
|
|||
return rv1126_gmac_src_m0_set_parent(clk, parent);
|
||||
case CLK_GMAC_SRC_M1:
|
||||
return rv1126_gmac_src_m1_set_parent(clk, parent);
|
||||
case CLK_GMAC_TX_RX:
|
||||
return rv1126_gmac_tx_rx_set_parent(clk, parent);
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue