Merge tag 'u-boot-atmel-fixes-2021.01-b' of https://gitlab.denx.de/u-boot/custodians...
[platform/kernel/u-boot.git] / drivers / clk / rockchip / clk_rk3399.c
index 6a78837..3fd863e 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 struct rk3399_clk_plat {
        struct dtd_rockchip_rk3399_cru dtd;
@@ -50,10 +52,9 @@ struct pll_div {
        .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
        .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
 
-#if defined(CONFIG_SPL_BUILD)
 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2, 2);
-#else
+#if !defined(CONFIG_SPL_BUILD)
 static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1);
 #endif
 
@@ -233,6 +234,10 @@ enum {
        DCLK_VOP_DIV_CON_MASK           = 0xff,
        DCLK_VOP_DIV_CON_SHIFT          = 0,
 
+       /* CLKSEL_CON57 */
+       PCLK_ALIVE_DIV_CON_SHIFT        = 0,
+       PCLK_ALIVE_DIV_CON_MASK         = 0x1f << PCLK_ALIVE_DIV_CON_SHIFT,
+
        /* CLKSEL_CON58 */
        CLK_SPI_PLL_SEL_WIDTH = 1,
        CLK_SPI_PLL_SEL_MASK = ((1 < CLK_SPI_PLL_SEL_WIDTH) - 1),
@@ -728,7 +733,7 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id)
                div = 2;
                break;
        case SCLK_EMMC:
-               con = readl(&cru->clksel_con[21]);
+               con = readl(&cru->clksel_con[22]);
                div = 1;
                break;
        default:
@@ -867,6 +872,17 @@ static ulong rk3399_ddr_set_clk(struct rockchip_cru *cru,
        return set_rate;
 }
 
+static ulong rk3399_alive_get_clk(struct rockchip_cru *cru)
+{
+        u32 div, val;
+
+        val = readl(&cru->clksel_con[57]);
+        div = (val & PCLK_ALIVE_DIV_CON_MASK) >>
+              PCLK_ALIVE_DIV_CON_SHIFT;
+
+        return DIV_TO_RATE(GPLL_HZ, div);
+}
+
 static ulong rk3399_saradc_get_clk(struct rockchip_cru *cru)
 {
        u32 div, val;
@@ -936,6 +952,10 @@ static ulong rk3399_clk_get_rate(struct clk *clk)
        case ACLK_GIC_PRE:
        case PCLK_DDR:
                break;
+       case PCLK_ALIVE:
+       case PCLK_WDT:
+               rate = rk3399_alive_get_clk(priv->cru);
+               break;
        default:
                log_debug("Unknown clock %lu\n", clk->id);
                return -ENOENT;
@@ -1000,6 +1020,8 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
        case ACLK_VOP1:
        case HCLK_VOP1:
        case HCLK_SD:
+       case SCLK_UPHY0_TCPDCORE:
+       case SCLK_UPHY1_TCPDCORE:
                /**
                 * assigned-clocks handling won't require for vopl, so
                 * return 0 to satisfy clk_set_defaults during device probe.
@@ -1094,6 +1116,12 @@ static int rk3399_clk_enable(struct clk *clk)
        case SCLK_MACREF_OUT:
                rk_clrreg(&priv->cru->clkgate_con[5], BIT(6));
                break;
+       case SCLK_USB2PHY0_REF:
+               rk_clrreg(&priv->cru->clkgate_con[6], BIT(5));
+               break;
+       case SCLK_USB2PHY1_REF:
+               rk_clrreg(&priv->cru->clkgate_con[6], BIT(6));
+               break;
        case ACLK_GMAC:
                rk_clrreg(&priv->cru->clkgate_con[32], BIT(0));
                break;
@@ -1139,6 +1167,18 @@ static int rk3399_clk_enable(struct clk *clk)
        case HCLK_HOST1_ARB:
                rk_clrreg(&priv->cru->clksel_con[20], BIT(8));
                break;
+       case SCLK_UPHY0_TCPDPHY_REF:
+               rk_clrreg(&priv->cru->clkgate_con[13], BIT(4));
+               break;
+       case SCLK_UPHY0_TCPDCORE:
+               rk_clrreg(&priv->cru->clkgate_con[13], BIT(5));
+               break;
+       case SCLK_UPHY1_TCPDPHY_REF:
+               rk_clrreg(&priv->cru->clkgate_con[13], BIT(6));
+               break;
+       case SCLK_UPHY1_TCPDCORE:
+               rk_clrreg(&priv->cru->clkgate_con[13], BIT(7));
+               break;
        case SCLK_PCIEPHY_REF:
                rk_clrreg(&priv->cru->clksel_con[18], BIT(10));
                break;
@@ -1170,6 +1210,12 @@ static int rk3399_clk_disable(struct clk *clk)
        case SCLK_MACREF_OUT:
                rk_setreg(&priv->cru->clkgate_con[5], BIT(6));
                break;
+       case SCLK_USB2PHY0_REF:
+               rk_setreg(&priv->cru->clkgate_con[6], BIT(5));
+               break;
+       case SCLK_USB2PHY1_REF:
+               rk_setreg(&priv->cru->clkgate_con[6], BIT(6));
+               break;
        case ACLK_GMAC:
                rk_setreg(&priv->cru->clkgate_con[32], BIT(0));
                break;
@@ -1215,6 +1261,18 @@ static int rk3399_clk_disable(struct clk *clk)
        case HCLK_HOST1_ARB:
                rk_setreg(&priv->cru->clksel_con[20], BIT(8));
                break;
+       case SCLK_UPHY0_TCPDPHY_REF:
+               rk_setreg(&priv->cru->clkgate_con[13], BIT(4));
+               break;
+       case SCLK_UPHY0_TCPDCORE:
+               rk_setreg(&priv->cru->clkgate_con[13], BIT(5));
+               break;
+       case SCLK_UPHY1_TCPDPHY_REF:
+               rk_setreg(&priv->cru->clkgate_con[13], BIT(6));
+               break;
+       case SCLK_UPHY1_TCPDCORE:
+               rk_setreg(&priv->cru->clkgate_con[13], BIT(7));
+               break;
        case SCLK_PCIEPHY_REF:
                rk_clrreg(&priv->cru->clksel_con[18], BIT(10));
                break;
@@ -1236,7 +1294,6 @@ static struct clk_ops rk3399_clk_ops = {
        .disable = rk3399_clk_disable,
 };
 
-#ifdef CONFIG_SPL_BUILD
 static void rkclk_init(struct rockchip_cru *cru)
 {
        u32 aclk_div;
@@ -1314,20 +1371,30 @@ static void rkclk_init(struct rockchip_cru *cru)
                     hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
                     HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
 }
-#endif
 
 static int rk3399_clk_probe(struct udevice *dev)
 {
-#ifdef CONFIG_SPL_BUILD
        struct rk3399_clk_priv *priv = dev_get_priv(dev);
+       bool init_clocks = false;
 
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
        struct rk3399_clk_plat *plat = dev_get_platdata(dev);
 
        priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
 #endif
-       rkclk_init(priv->cru);
+
+#if defined(CONFIG_SPL_BUILD)
+       init_clocks = true;
+#elif CONFIG_IS_ENABLED(HANDOFF)
+       if (!(gd->flags & GD_FLG_RELOC)) {
+               if (!(gd->spl_handoff))
+                       init_clocks = true;
+       }
 #endif
+
+       if (init_clocks)
+               rkclk_init(priv->cru);
+
        return 0;
 }
 
@@ -1464,6 +1531,7 @@ static ulong rk3399_pmuclk_get_rate(struct clk *clk)
        case PLL_PPLL:
                return PPLL_HZ;
        case PCLK_RKPWM_PMU:
+       case PCLK_WDT_M0_PMU:
                rate = rk3399_pwm_get_clk(priv->pmucru);
                break;
        case SCLK_I2C0_PMU:
@@ -1554,7 +1622,7 @@ static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
 
 static int rk3399_pmuclk_bind(struct udevice *dev)
 {
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
        int ret;
 
        ret = offsetof(struct rk3399_pmucru, pmucru_softrst_con[0]);