clk: rk3399: Add enable/disable clks
authorJagan Teki <jagan@amarulasolutions.com>
Sat, 9 May 2020 16:56:19 +0000 (22:26 +0530)
committerKever Yang <kever.yang@rock-chips.com>
Fri, 22 May 2020 12:53:20 +0000 (20:53 +0800)
Yes, most of the high speed peripheral clocks
in rk3399 enabled by default.

But it would be better to handle them via clk
enable/disable API for handling proper reset
conditions like 'usb reset' over command line.

So, enable USB, GMAC clock via enable/disable ops.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
Tested-by: Suniel Mahesh <sunil.m@amarulasolutions.com> # roc-rk3399-pc
Tested-by: Suniel Mahesh <sunil@amarulasolutions.com> #roc-rk3399-pc
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
drivers/clk/rockchip/clk_rk3399.c

index e009f1cf6c13ad9f53e4d2e4b1fcc64b924eea2b..371410d9a91b76b035577f407c43ec73323a14d4 100644 (file)
@@ -1074,12 +1074,160 @@ static int __maybe_unused rk3399_clk_set_parent(struct clk *clk,
        return -ENOENT;
 }
 
+static int rk3399_clk_enable(struct clk *clk)
+{
+       struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
+
+       switch (clk->id) {
+       case SCLK_MAC:
+               rk_clrreg(&priv->cru->clkgate_con[5], BIT(5));
+               break;
+       case SCLK_MAC_RX:
+               rk_clrreg(&priv->cru->clkgate_con[5], BIT(8));
+               break;
+       case SCLK_MAC_TX:
+               rk_clrreg(&priv->cru->clkgate_con[5], BIT(9));
+               break;
+       case SCLK_MACREF:
+               rk_clrreg(&priv->cru->clkgate_con[5], BIT(7));
+               break;
+       case SCLK_MACREF_OUT:
+               rk_clrreg(&priv->cru->clkgate_con[5], BIT(6));
+               break;
+       case ACLK_GMAC:
+               rk_clrreg(&priv->cru->clkgate_con[32], BIT(0));
+               break;
+       case PCLK_GMAC:
+               rk_clrreg(&priv->cru->clkgate_con[32], BIT(2));
+               break;
+       case SCLK_USB3OTG0_REF:
+               rk_clrreg(&priv->cru->clkgate_con[12], BIT(1));
+               break;
+       case SCLK_USB3OTG1_REF:
+               rk_clrreg(&priv->cru->clkgate_con[12], BIT(2));
+               break;
+       case SCLK_USB3OTG0_SUSPEND:
+               rk_clrreg(&priv->cru->clkgate_con[12], BIT(3));
+               break;
+       case SCLK_USB3OTG1_SUSPEND:
+               rk_clrreg(&priv->cru->clkgate_con[12], BIT(4));
+               break;
+       case ACLK_USB3OTG0:
+               rk_clrreg(&priv->cru->clkgate_con[30], BIT(1));
+               break;
+       case ACLK_USB3OTG1:
+               rk_clrreg(&priv->cru->clkgate_con[30], BIT(2));
+               break;
+       case ACLK_USB3_RKSOC_AXI_PERF:
+               rk_clrreg(&priv->cru->clkgate_con[30], BIT(3));
+               break;
+       case ACLK_USB3:
+               rk_clrreg(&priv->cru->clkgate_con[12], BIT(0));
+               break;
+       case ACLK_USB3_GRF:
+               rk_clrreg(&priv->cru->clkgate_con[30], BIT(4));
+               break;
+       case HCLK_HOST0:
+               rk_clrreg(&priv->cru->clksel_con[20], BIT(5));
+               break;
+       case HCLK_HOST0_ARB:
+               rk_clrreg(&priv->cru->clksel_con[20], BIT(6));
+               break;
+       case HCLK_HOST1:
+               rk_clrreg(&priv->cru->clksel_con[20], BIT(7));
+               break;
+       case HCLK_HOST1_ARB:
+               rk_clrreg(&priv->cru->clksel_con[20], BIT(8));
+               break;
+       default:
+               debug("%s: unsupported clk %ld\n", __func__, clk->id);
+               return -ENOENT;
+       }
+
+       return 0;
+}
+
+static int rk3399_clk_disable(struct clk *clk)
+{
+       struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
+
+       switch (clk->id) {
+       case SCLK_MAC:
+               rk_setreg(&priv->cru->clkgate_con[5], BIT(5));
+               break;
+       case SCLK_MAC_RX:
+               rk_setreg(&priv->cru->clkgate_con[5], BIT(8));
+               break;
+       case SCLK_MAC_TX:
+               rk_setreg(&priv->cru->clkgate_con[5], BIT(9));
+               break;
+       case SCLK_MACREF:
+               rk_setreg(&priv->cru->clkgate_con[5], BIT(7));
+               break;
+       case SCLK_MACREF_OUT:
+               rk_setreg(&priv->cru->clkgate_con[5], BIT(6));
+               break;
+       case ACLK_GMAC:
+               rk_setreg(&priv->cru->clkgate_con[32], BIT(0));
+               break;
+       case PCLK_GMAC:
+               rk_setreg(&priv->cru->clkgate_con[32], BIT(2));
+               break;
+       case SCLK_USB3OTG0_REF:
+               rk_setreg(&priv->cru->clkgate_con[12], BIT(1));
+               break;
+       case SCLK_USB3OTG1_REF:
+               rk_setreg(&priv->cru->clkgate_con[12], BIT(2));
+               break;
+       case SCLK_USB3OTG0_SUSPEND:
+               rk_setreg(&priv->cru->clkgate_con[12], BIT(3));
+               break;
+       case SCLK_USB3OTG1_SUSPEND:
+               rk_setreg(&priv->cru->clkgate_con[12], BIT(4));
+               break;
+       case ACLK_USB3OTG0:
+               rk_setreg(&priv->cru->clkgate_con[30], BIT(1));
+               break;
+       case ACLK_USB3OTG1:
+               rk_setreg(&priv->cru->clkgate_con[30], BIT(2));
+               break;
+       case ACLK_USB3_RKSOC_AXI_PERF:
+               rk_setreg(&priv->cru->clkgate_con[30], BIT(3));
+               break;
+       case ACLK_USB3:
+               rk_setreg(&priv->cru->clkgate_con[12], BIT(0));
+               break;
+       case ACLK_USB3_GRF:
+               rk_setreg(&priv->cru->clkgate_con[30], BIT(4));
+               break;
+       case HCLK_HOST0:
+               rk_setreg(&priv->cru->clksel_con[20], BIT(5));
+               break;
+       case HCLK_HOST0_ARB:
+               rk_setreg(&priv->cru->clksel_con[20], BIT(6));
+               break;
+       case HCLK_HOST1:
+               rk_setreg(&priv->cru->clksel_con[20], BIT(7));
+               break;
+       case HCLK_HOST1_ARB:
+               rk_setreg(&priv->cru->clksel_con[20], BIT(8));
+               break;
+       default:
+               debug("%s: unsupported clk %ld\n", __func__, clk->id);
+               return -ENOENT;
+       }
+
+       return 0;
+}
+
 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,
+       .disable = rk3399_clk_disable,
 };
 
 #ifdef CONFIG_SPL_BUILD