clk: Add support for I2C clocks on NXP's imx6q SoC which use CCF
authorLukasz Majewski <lukma@denx.de>
Tue, 15 Oct 2019 10:44:57 +0000 (12:44 +0200)
committerLukasz Majewski <lukma@denx.de>
Tue, 22 Oct 2019 14:14:05 +0000 (16:14 +0200)
This change adds support for I2C clock modeled in CCF. This code intention
is to only enable those clocks in the I2C driver with default settings.
For that reason the "busy" versions of clocks reuse the generic approach
and would need to be updated when one wants to adjust the I2C clock
frequency in U-Boot.

Signed-off-by: Lukasz Majewski <lukma@denx.de>
drivers/clk/imx/clk-imx6q.c
drivers/clk/imx/clk.h

index 92e9337d4464b1b00f420a5d875d8d1fe1f32fda..5ae4781d11d768ee2027db8969f655ec3af72427 100644 (file)
@@ -89,6 +89,9 @@ static struct clk_ops imx6q_clk_ops = {
 };
 
 static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *const periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *const periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m",
+                                              "pll2_pfd0_352m", "pll2_198m", };
 
 static int imx6q_clk_probe(struct udevice *dev)
 {
@@ -161,6 +164,24 @@ static int imx6q_clk_probe(struct udevice *dev)
        clk_dm(IMX6QDL_CLK_USDHC4,
               imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8));
 
+       clk_dm(IMX6QDL_CLK_PERIPH_PRE,
+              imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels,
+                          ARRAY_SIZE(periph_pre_sels)));
+       clk_dm(IMX6QDL_CLK_PERIPH,
+              imx_clk_busy_mux("periph",  base + 0x14, 25, 1, base + 0x48,
+                               5, periph_sels,  ARRAY_SIZE(periph_sels)));
+       clk_dm(IMX6QDL_CLK_AHB,
+              imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3,
+                                   base + 0x48, 1));
+       clk_dm(IMX6QDL_CLK_IPG,
+              imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2));
+       clk_dm(IMX6QDL_CLK_IPG_PER,
+              imx_clk_divider("ipg_per", "ipg", base + 0x1c, 0, 6));
+       clk_dm(IMX6QDL_CLK_I2C1,
+              imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6));
+       clk_dm(IMX6QDL_CLK_I2C2,
+              imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8));
+
        return 0;
 }
 
index 4956e04a9253076175ed6c7c564fd19e80384382..07dcf94ea58668a4bded25a114ec6a2924120b56 100644 (file)
@@ -92,6 +92,14 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent,
                        reg, shift, width, 0);
 }
 
+static inline struct clk *
+imx_clk_busy_divider(const char *name, const char *parent, void __iomem *reg,
+                    u8 shift, u8 width, void __iomem *busy_reg, u8 busy_shift)
+{
+       return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+                       reg, shift, width, 0);
+}
+
 static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
                void __iomem *reg, u8 shift, u8 width)
 {
@@ -126,6 +134,16 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
                        width, 0);
 }
 
+static inline struct clk *
+imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, u8 width,
+                void __iomem *busy_reg, u8 busy_shift,
+                const char * const *parents, int num_parents)
+{
+       return clk_register_mux(NULL, name, parents, num_parents,
+                       CLK_SET_RATE_NO_REPARENT, reg, shift,
+                       width, 0);
+}
+
 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
                        u8 shift, u8 width, const char * const *parents,
                        int num_parents)