Merge branch 'master' of git://git.denx.de/u-boot
[oweals/u-boot.git] / drivers / clk / rockchip / clk_rk3399.c
index 93a652e5ff4d0c9fe48425c4290dc6ffcfb01370..d822acace14be9ba955c96f1c484e14ee0e8137f 100644 (file)
@@ -9,12 +9,13 @@
 #include <dm.h>
 #include <dt-structs.h>
 #include <errno.h>
+#include <malloc.h>
 #include <mapmem.h>
 #include <syscon.h>
 #include <bitfield.h>
 #include <asm/io.h>
 #include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/cru_rk3399.h>
+#include <asm/arch-rockchip/cru.h>
 #include <asm/arch-rockchip/hardware.h>
 #include <dm/lists.h>
 #include <dt-bindings/clock/rk3399-cru.h>
@@ -38,8 +39,8 @@ struct pll_div {
 };
 
 #define RATE_TO_DIV(input_rate, output_rate) \
-       ((input_rate) / (output_rate) - 1);
-#define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
+       ((input_rate) / (output_rate) - 1)
+#define DIV_TO_RATE(input_rate, div)           ((input_rate) / ((div) + 1))
 
 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
        .refdiv = _refdiv,\
@@ -53,15 +54,15 @@ static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2, 2);
 static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1);
 #endif
 
-static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600*MHz, 3, 1, 1);
-static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
+static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600 * MHz, 3, 1, 1);
+static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600 * MHz, 1, 2, 1);
 
 static const struct pll_div *apll_l_cfgs[] = {
        [APLL_L_1600_MHZ] = &apll_l_1600_cfg,
        [APLL_L_600_MHZ] = &apll_l_600_cfg,
 };
 
-static const struct pll_div apll_b_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
+static const struct pll_div apll_b_600_cfg = PLL_DIVISORS(600 * MHz, 1, 2, 1);
 static const struct pll_div *apll_b_cfgs[] = {
        [APLL_B_600_MHZ] = &apll_b_600_cfg,
 };
@@ -393,7 +394,7 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div)
                fref_khz = ref_khz / refdiv;
 
                fbdiv = vco_khz / fref_khz;
-               if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv))
+               if (fbdiv >= max_fbdiv || fbdiv <= min_fbdiv)
                        continue;
                diff_khz = vco_khz - fbdiv * fref_khz;
                if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
@@ -409,7 +410,7 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div)
                div->fbdiv = fbdiv;
        }
 
-       if (best_diff_khz > 4 * (MHz/KHz)) {
+       if (best_diff_khz > 4 * (MHz / KHz)) {
                printf("%s: Failed to match output frequency %u, "
                       "difference is %u Hz,exceed 4MHZ\n", __func__, freq_hz,
                       best_diff_khz * KHz);
@@ -418,7 +419,7 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div)
        return 0;
 }
 
-void rk3399_configure_cpu_l(struct rk3399_cru *cru,
+void rk3399_configure_cpu_l(struct rockchip_cru *cru,
                            enum apll_l_frequencies apll_l_freq)
 {
        u32 aclkm_div;
@@ -453,7 +454,7 @@ void rk3399_configure_cpu_l(struct rk3399_cru *cru,
                     atclk_div << ATCLK_CORE_L_DIV_SHIFT);
 }
 
-void rk3399_configure_cpu_b(struct rk3399_cru *cru,
+void rk3399_configure_cpu_b(struct rockchip_cru *cru,
                            enum apll_b_frequencies apll_b_freq)
 {
        u32 aclkm_div;
@@ -489,30 +490,23 @@ void rk3399_configure_cpu_b(struct rk3399_cru *cru,
 }
 
 #define I2C_CLK_REG_MASK(bus) \
-                       (I2C_DIV_CON_MASK << \
-                       CLK_I2C ##bus## _DIV_CON_SHIFT | \
-                       CLK_I2C_PLL_SEL_MASK << \
-                       CLK_I2C ##bus## _PLL_SEL_SHIFT)
+       (I2C_DIV_CON_MASK << CLK_I2C ##bus## _DIV_CON_SHIFT | \
+        CLK_I2C_PLL_SEL_MASK << CLK_I2C ##bus## _PLL_SEL_SHIFT)
 
 #define I2C_CLK_REG_VALUE(bus, clk_div) \
-                             ((clk_div - 1) << \
-                                       CLK_I2C ##bus## _DIV_CON_SHIFT | \
-                             CLK_I2C_PLL_SEL_GPLL << \
-                                       CLK_I2C ##bus## _PLL_SEL_SHIFT)
+       ((clk_div - 1) << CLK_I2C ##bus## _DIV_CON_SHIFT | \
+        CLK_I2C_PLL_SEL_GPLL << CLK_I2C ##bus## _PLL_SEL_SHIFT)
 
 #define I2C_CLK_DIV_VALUE(con, bus) \
-                       (con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & \
-                               I2C_DIV_CON_MASK;
+       ((con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & I2C_DIV_CON_MASK)
 
 #define I2C_PMUCLK_REG_MASK(bus) \
-                       (I2C_DIV_CON_MASK << \
-                        CLK_I2C ##bus## _DIV_CON_SHIFT)
+       (I2C_DIV_CON_MASK << CLK_I2C ##bus## _DIV_CON_SHIFT)
 
 #define I2C_PMUCLK_REG_VALUE(bus, clk_div) \
-                               ((clk_div - 1) << \
-                               CLK_I2C ##bus## _DIV_CON_SHIFT)
+       ((clk_div - 1) << CLK_I2C ##bus## _DIV_CON_SHIFT)
 
-static ulong rk3399_i2c_get_clk(struct rk3399_cru *cru, ulong clk_id)
+static ulong rk3399_i2c_get_clk(struct rockchip_cru *cru, ulong clk_id)
 {
        u32 div, con;
 
@@ -549,7 +543,7 @@ static ulong rk3399_i2c_get_clk(struct rk3399_cru *cru, ulong clk_id)
        return DIV_TO_RATE(GPLL_HZ, div);
 }
 
-static ulong rk3399_i2c_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
+static ulong rk3399_i2c_set_clk(struct rockchip_cru *cru, ulong clk_id, uint hz)
 {
        int src_clk_div;
 
@@ -597,9 +591,9 @@ static ulong rk3399_i2c_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
  */
 
 struct spi_clkreg {
-       uint8_t reg;  /* CLKSEL_CON[reg] register in CRU */
-       uint8_t div_shift;
-       uint8_t sel_shift;
+       u8 reg;  /* CLKSEL_CON[reg] register in CRU */
+       u8 div_shift;
+       u8 sel_shift;
 };
 
 /*
@@ -626,7 +620,7 @@ static const struct spi_clkreg spi_clkregs[] = {
                .sel_shift = CLK_SPI5_PLL_SEL_SHIFT, },
 };
 
-static ulong rk3399_spi_get_clk(struct rk3399_cru *cru, ulong clk_id)
+static ulong rk3399_spi_get_clk(struct rockchip_cru *cru, ulong clk_id)
 {
        const struct spi_clkreg *spiclk = NULL;
        u32 div, val;
@@ -648,7 +642,7 @@ static ulong rk3399_spi_get_clk(struct rk3399_cru *cru, ulong clk_id)
        return DIV_TO_RATE(GPLL_HZ, div);
 }
 
-static ulong rk3399_spi_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
+static ulong rk3399_spi_set_clk(struct rockchip_cru *cru, ulong clk_id, uint hz)
 {
        const struct spi_clkreg *spiclk = NULL;
        int src_clk_div;
@@ -675,10 +669,10 @@ static ulong rk3399_spi_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
        return rk3399_spi_get_clk(cru, clk_id);
 }
 
-static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz)
+static ulong rk3399_vop_set_clk(struct rockchip_cru *cru, ulong clk_id, u32 hz)
 {
        struct pll_div vpll_config = {0};
-       int aclk_vop = 198*MHz;
+       int aclk_vop = 198 * MHz;
        void *aclkreg_addr, *dclkreg_addr;
        u32 div;
 
@@ -710,7 +704,7 @@ static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz)
        rkclk_set_pll(&cru->vpll_con[0], &vpll_config);
 
        rk_clrsetreg(dclkreg_addr,
-                    DCLK_VOP_DCLK_SEL_MASK | DCLK_VOP_PLL_SEL_MASK|
+                    DCLK_VOP_DCLK_SEL_MASK | DCLK_VOP_PLL_SEL_MASK |
                     DCLK_VOP_DIV_CON_MASK,
                     DCLK_VOP_DCLK_SEL_DIVOUT << DCLK_VOP_DCLK_SEL_SHIFT |
                     DCLK_VOP_PLL_SEL_VPLL << DCLK_VOP_PLL_SEL_SHIFT |
@@ -719,7 +713,7 @@ static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz)
        return hz;
 }
 
-static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id)
+static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id)
 {
        u32 div, con;
 
@@ -746,11 +740,11 @@ static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id)
                return DIV_TO_RATE(GPLL_HZ, div);
 }
 
-static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
+static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru,
                                ulong clk_id, ulong set_rate)
 {
        int src_clk_div;
-       int aclk_emmc = 198*MHz;
+       int aclk_emmc = 198 * MHz;
 
        switch (clk_id) {
        case HCLK_SDMMC:
@@ -776,7 +770,7 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
                break;
        case SCLK_EMMC:
                /* Select aclk_emmc source from GPLL */
-               src_clk_div = DIV_ROUND_UP(GPLL_HZ , aclk_emmc);
+               src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc);
                assert(src_clk_div - 1 < 32);
 
                rk_clrsetreg(&cru->clksel_con[21],
@@ -799,7 +793,7 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
        return rk3399_mmc_get_clk(cru, clk_id);
 }
 
-static ulong rk3399_gmac_set_clk(struct rk3399_cru *cru, ulong rate)
+static ulong rk3399_gmac_set_clk(struct rockchip_cru *cru, ulong rate)
 {
        ulong ret;
 
@@ -824,7 +818,7 @@ static ulong rk3399_gmac_set_clk(struct rk3399_cru *cru, ulong rate)
 }
 
 #define PMUSGRF_DDR_RGN_CON16 0xff330040
-static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
+static ulong rk3399_ddr_set_clk(struct rockchip_cru *cru,
                                ulong set_rate)
 {
        struct pll_div dpll_cfg;
@@ -834,23 +828,31 @@ static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
 
        /*  clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */
        switch (set_rate) {
-       case 200*MHz:
+       case 50 * MHz:
+               dpll_cfg = (struct pll_div)
+               {.refdiv = 1, .fbdiv = 12, .postdiv1 = 3, .postdiv2 = 2};
+               break;
+       case 200 * MHz:
                dpll_cfg = (struct pll_div)
                {.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
                break;
-       case 300*MHz:
+       case 300 * MHz:
                dpll_cfg = (struct pll_div)
                {.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
                break;
-       case 666*MHz:
+       case 400 * MHz:
+               dpll_cfg = (struct pll_div)
+               {.refdiv = 1, .fbdiv = 50, .postdiv1 = 3, .postdiv2 = 1};
+               break;
+       case 666 * MHz:
                dpll_cfg = (struct pll_div)
                {.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
                break;
-       case 800*MHz:
+       case 800 * MHz:
                dpll_cfg = (struct pll_div)
                {.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
                break;
-       case 933*MHz:
+       case 933 * MHz:
                dpll_cfg = (struct pll_div)
                {.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
                break;
@@ -862,7 +864,7 @@ static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
        return set_rate;
 }
 
-static ulong rk3399_saradc_get_clk(struct rk3399_cru *cru)
+static ulong rk3399_saradc_get_clk(struct rockchip_cru *cru)
 {
        u32 div, val;
 
@@ -873,7 +875,7 @@ static ulong rk3399_saradc_get_clk(struct rk3399_cru *cru)
        return DIV_TO_RATE(OSC_HZ, div);
 }
 
-static ulong rk3399_saradc_set_clk(struct rk3399_cru *cru, uint hz)
+static ulong rk3399_saradc_set_clk(struct rockchip_cru *cru, uint hz)
 {
        int src_clk_div;
 
@@ -912,9 +914,10 @@ static ulong rk3399_clk_get_rate(struct clk *clk)
                rate = rk3399_spi_get_clk(priv->cru, clk->id);
                break;
        case SCLK_UART0:
+       case SCLK_UART1:
        case SCLK_UART2:
+       case SCLK_UART3:
                return 24000000;
-               break;
        case PCLK_HDMI_CTRL:
                break;
        case DCLK_VOP0:
@@ -991,6 +994,14 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
        case DCLK_VOP1:
                ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
                break;
+       case ACLK_VOP1:
+       case HCLK_VOP1:
+       case HCLK_SD:
+               /**
+                * assigned-clocks handling won't require for vopl, so
+                * return 0 to satisfy clk_set_defaults during device probe.
+                */
+               return 0;
        case SCLK_DDRCLK:
                ret = rk3399_ddr_set_clk(priv->cru, rate);
                break;
@@ -1012,7 +1023,8 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
        return ret;
 }
 
-static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk, struct clk *parent)
+static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk,
+                                                struct clk *parent)
 {
        struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
        const char *clock_output_name;
@@ -1022,7 +1034,7 @@ static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk, struct clk *pa
         * If the requested parent is in the same clock-controller and
         * the id is SCLK_MAC ("clk_gmac"), switch to the internal clock.
         */
-       if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC)) {
+       if (parent->dev == clk->dev && parent->id == SCLK_MAC) {
                debug("%s: switching RGMII to SCLK_MAC\n", __func__);
                rk_clrreg(&priv->cru->clksel_con[19], BIT(4));
                return 0;
@@ -1047,7 +1059,8 @@ static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk, struct clk *pa
        return -EINVAL;
 }
 
-static int __maybe_unused rk3399_clk_set_parent(struct clk *clk, struct clk *parent)
+static int __maybe_unused rk3399_clk_set_parent(struct clk *clk,
+                                               struct clk *parent)
 {
        switch (clk->id) {
        case SCLK_RMII_SRC:
@@ -1058,41 +1071,16 @@ static int __maybe_unused rk3399_clk_set_parent(struct clk *clk, struct clk *par
        return -ENOENT;
 }
 
-static int rk3399_clk_enable(struct clk *clk)
-{
-       switch (clk->id) {
-       case HCLK_HOST0:
-       case HCLK_HOST0_ARB:
-       case HCLK_HOST1:
-       case HCLK_HOST1_ARB:
-               return 0;
-
-       case SCLK_MAC:
-       case SCLK_MAC_RX:
-       case SCLK_MAC_TX:
-       case SCLK_MACREF:
-       case SCLK_MACREF_OUT:
-       case ACLK_GMAC:
-       case PCLK_GMAC:
-               /* Required to successfully probe the Designware GMAC driver */
-               return 0;
-       }
-
-       debug("%s: unsupported clk %ld\n", __func__, clk->id);
-       return -ENOENT;
-}
-
 static struct clk_ops rk3399_clk_ops = {
        .get_rate = rk3399_clk_get_rate,
        .set_rate = rk3399_clk_set_rate,
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
        .set_parent = rk3399_clk_set_parent,
 #endif
-       .enable = rk3399_clk_enable,
 };
 
 #ifdef CONFIG_SPL_BUILD
-static void rkclk_init(struct rk3399_cru *cru)
+static void rkclk_init(struct rockchip_cru *cru)
 {
        u32 aclk_div;
        u32 hclk_div;
@@ -1209,15 +1197,15 @@ static int rk3399_clk_bind(struct udevice *dev)
                debug("Warning: No sysreset driver: ret=%d\n", ret);
        } else {
                priv = malloc(sizeof(struct sysreset_reg));
-               priv->glb_srst_fst_value = offsetof(struct rk3399_cru,
+               priv->glb_srst_fst_value = offsetof(struct rockchip_cru,
                                                    glb_srst_fst_value);
-               priv->glb_srst_snd_value = offsetof(struct rk3399_cru,
+               priv->glb_srst_snd_value = offsetof(struct rockchip_cru,
                                                    glb_srst_snd_value);
                sys_child->priv = priv;
        }
 
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
-       ret = offsetof(struct rk3399_cru, softrst_con[0]);
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+       ret = offsetof(struct rockchip_cru, softrst_con[0]);
        ret = rockchip_reset_bind(dev, ret, 21);
        if (ret)
                debug("Warning: software reset driver bind faile\n");