[v2,06/10] clk: imx6: Add imx6ul clock tree support

Message ID 20190402112843.992-7-jagan@amarulasolutions.com
State New
Headers show
Series
  • clk: imx: Add i.MX6 CLK support
Related show

Commit Message

Jagan Teki April 2, 2019, 11:28 a.m. UTC
i.MX6 clock control module comprise of parent clocks, gates, multiplexers,
dividers, PODF, PLL, fixed rate and etc.

So, the U-Boot implementation of ccm has divided into gates and tree.

1) gate clocks are generic clock configuration of enable/disable bit management
   which can be handle via imx6_clock_gate.
2) tree clocks are handle via tree clock management where it link the clocks
   based on the parent clock which usually required to get and set the
   clock rates.

This patch add tree clock management for imx6ul USDHC clocks, so the mmc driver
from imx6 can eventually use this so getting the USDHC clock rates.

Unlike Linux, U-Boot implementation may not require to maintain exact clock tree
due to various constrains and use cases. So here is how the clock tree differs
between them.

usdhc clock tree in Linux:
-------------------------
USDHC1 => USDHC1_PODF => USDHC1_SEL => PLL2_PFD2 => PLL2_BUS => PLL2_BYPASS => PLL2 => OSC

usdhc clock tree in U-Boot:
---------------------------
USDHC1 => USDHC1_PODF => USDHC1_SEL => PLL2_PFD2 => PLL2_BUS => OSC

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
 drivers/clk/imx/clk-imx6ul.c | 48 ++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

Patch

diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index f5250e8b72..8528176eec 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -10,6 +10,53 @@ 
 #include <asm/arch/clock.h>
 #include <dt-bindings/clock/imx6ul-clock.h>
 
+static const unsigned long pll2_bus[] = {
+	IMX6UL_CLK_OSC,
+};
+
+static const unsigned long pfd_352m[] = {
+	IMX6UL_CLK_PLL2_BUS,
+};
+
+static const unsigned long usdhc_sel[] = {
+	IMX6UL_CLK_PLL2_PFD2,
+	IMX6UL_CLK_PLL2_PFD0,
+};
+
+static const unsigned long usdhc1_podf[] = {
+	IMX6UL_CLK_USDHC1_SEL,
+};
+
+static const unsigned long usdhc2_podf[] = {
+	IMX6UL_CLK_USDHC2_SEL,
+};
+
+static const unsigned long usdhc1[] = {
+	IMX6UL_CLK_USDHC1_PODF,
+};
+
+static const unsigned long usdhc2[] = {
+	IMX6UL_CLK_USDHC2_PODF,
+};
+
+static const struct imx6_clk_tree imx6ul_tree[] = {
+	[IMX6UL_CLK_OSC]		= FIXED(OSC_24M_ULL),
+
+	[IMX6UL_CLK_PLL2_BUS]		= PLL_DIV(pll2_bus, 0x30, 13, 1),
+
+	[IMX6UL_CLK_PLL2_PFD0]		= PLL_PFD(pfd_352m, 0x100, 6, 0),
+	[IMX6UL_CLK_PLL2_PFD2]		= PLL_PFD(pfd_352m, 0x100, 6, 2),
+
+	[IMX6UL_CLK_USDHC2_SEL]		= MUX(usdhc_sel, 0x01c, 17, 1),
+	[IMX6UL_CLK_USDHC1_SEL]		= MUX(usdhc_sel, 0x01c, 16, 1),
+
+	[IMX6UL_CLK_USDHC2_PODF]	= DIV(usdhc2_podf, 0x024, 16, 3),
+	[IMX6UL_CLK_USDHC1_PODF]	= DIV(usdhc1_podf, 0x024, 11, 3),
+
+	[IMX6UL_CLK_USDHC2]		= SIMPLE(usdhc2),
+	[IMX6UL_CLK_USDHC1]		= SIMPLE(usdhc1),
+};
+
 static const struct imx6_clk_gate imx6ul_gates[] = {
 	[IMX6UL_CLK_USDHC1]		= GATE(0x080, GENMASK(3, 2)),
 	[IMX6UL_CLK_USDHC2]		= GATE(0x080, GENMASK(5, 4)),
@@ -17,6 +64,7 @@  static const struct imx6_clk_gate imx6ul_gates[] = {
 
 static const struct imx6_clk_desc imx6ul_clk_desc = {
 	.gates = imx6ul_gates,
+	.tree = imx6ul_tree,
 };
 
 static const struct udevice_id clk_imx6ul_ids[] = {