mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 00/28] Vybrid support in Barebox
@ 2016-11-09 16:13 Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 01/28] i.MX: Add primitive functions for VF610 family Andrey Smirnov
                   ` (28 more replies)
  0 siblings, 29 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Hi everyone,

It took me a bit more than a month, but I finally put together a
second version (for v1 see [1]) of the Vybrid support patchset.

Some highlights of this version:

     - Various code/commit arrangement feedback for v1 is addressed
     - Added commit to move all of the i.MX clock code to drivers/clk
       (Sascha, we'd probably have to coordinate with your i.MX6ul
       patches on this one)
     - I2C commit split in two
     - clock tree is reconciled with Linux code, since having a custom
       version of it proved to be difficult to compare agains Linux's
       implementation
     - GPIO driver (tested on a custom Vybrid board)
     - FEC support (tested on a custom Vybrid board)

Any feedback is, as always, very much appreciated.

Thank you,
Andrey Smirnov

[1] http://lists.infradead.org/pipermail/barebox/2016-October/028225.html

Andrey Smirnov (28):
  i.MX: Add primitive functions for VF610 family
  i.MX: Add register definitions for VF610 SoC
  i.MX: Add DEBUG_LL hooks for VF610
  i.MX: scripts: Add "vf610" soc to imx-image
  i.MX: Add support for VF610 Tower board
  pinctrl: Add provisions to control GPIO pin direction
  i.MX: Add pinctrl driver for VF610
  clk: Port clock dependency resolution code
  clk: Port of_clk_set_defaults()
  i.MX: Move clk code from 'mach-imx' to 'drivers'
  i.MX: clk: Port imx_clk_gate2_cgr()
  i.MX: clk: Add IMX_PLLV3_USB_VF610 support
  i.MX: clk: Port imx_check_clocks()
  i.MX: clk: Port imx_clk_mux_flags from Linux
  i.MX: Add VF610 clock tree initialization code
  vf610: Give enet_osc explicit "enet_ext" name
  i.MX: Add 'lpuart' serial driver
  i.MX: i2c: Use read/write adapter functions
  i.MX: i2c: Add Vybrid support
  i.MX: esdhc: Do not rely on CPU type for quirks
  i.MX: esdhc: Request "per" clock explicitly
  i.MX: Kconfig: Enable OCOTP on Vybrid
  i.MX: ocotp: Remove unused #define
  i.MX: ocotp: Account for shadow memory gaps
  i.MX: ocotp: Add Vybrid support
  i.MX: fec: Enable all clocks specified for FEC
  i.MX: fec: Add support for Vybrid variant
  gpio: Add GPIO driver for Vybrid

 arch/arm/boards/Makefile                           |   1 +
 arch/arm/boards/freescale-vf610-twr/Makefile       |   3 +
 .../flash-header-vf610-twr.imxcfg                  | 278 +++++++++++
 arch/arm/boards/freescale-vf610-twr/lowlevel.c     |  45 ++
 arch/arm/dts/Makefile                              |   1 +
 arch/arm/dts/vf610-twr.dts                         |  18 +
 arch/arm/mach-imx/Kconfig                          |  16 +-
 arch/arm/mach-imx/Makefile                         |  23 +-
 arch/arm/mach-imx/clk-gate-exclusive.c             | 103 ----
 arch/arm/mach-imx/clk-gate2.c                      | 145 ------
 arch/arm/mach-imx/clk-imx1.c                       | 121 -----
 arch/arm/mach-imx/clk-imx21.c                      | 196 --------
 arch/arm/mach-imx/clk-imx25.c                      | 200 --------
 arch/arm/mach-imx/clk-imx27.c                      | 270 ----------
 arch/arm/mach-imx/clk-imx31.c                      | 146 ------
 arch/arm/mach-imx/clk-imx35.c                      | 219 ---------
 arch/arm/mach-imx/clk-imx5.c                       | 533 --------------------
 arch/arm/mach-imx/clk-imx6.c                       | 541 ---------------------
 arch/arm/mach-imx/clk-imx6sx.c                     | 483 ------------------
 arch/arm/mach-imx/clk-pfd.c                        | 148 ------
 arch/arm/mach-imx/clk-pllv1.c                      |  95 ----
 arch/arm/mach-imx/clk-pllv2.c                      | 230 ---------
 arch/arm/mach-imx/clk-pllv3.c                      | 326 -------------
 arch/arm/mach-imx/clk.h                            | 104 ----
 arch/arm/mach-imx/cpu_init.c                       |   5 +
 arch/arm/mach-imx/imx.c                            |   4 +
 arch/arm/mach-imx/include/mach/clock-vf610.h       | 171 +++++++
 arch/arm/mach-imx/include/mach/debug_ll.h          |  27 +-
 arch/arm/mach-imx/include/mach/generic.h           |  13 +
 arch/arm/mach-imx/include/mach/imx_cpu_types.h     |   1 +
 arch/arm/mach-imx/include/mach/iomux-vf610.h       | 226 +++++++++
 arch/arm/mach-imx/include/mach/vf610-regs.h        | 110 +++++
 arch/arm/mach-imx/ocotp.c                          |  51 +-
 common/Kconfig                                     |  10 +-
 drivers/clk/Makefile                               |   3 +-
 drivers/clk/clk-conf.c                             | 144 ++++++
 drivers/clk/clk.c                                  |  91 +++-
 drivers/clk/imx/Makefile                           |  21 +
 drivers/clk/imx/clk-gate-exclusive.c               | 103 ++++
 drivers/clk/imx/clk-gate2.c                        | 147 ++++++
 drivers/clk/imx/clk-imx1.c                         | 121 +++++
 drivers/clk/imx/clk-imx21.c                        | 196 ++++++++
 drivers/clk/imx/clk-imx25.c                        | 200 ++++++++
 drivers/clk/imx/clk-imx27.c                        | 270 ++++++++++
 drivers/clk/imx/clk-imx31.c                        | 146 ++++++
 drivers/clk/imx/clk-imx35.c                        | 219 +++++++++
 drivers/clk/imx/clk-imx5.c                         | 533 ++++++++++++++++++++
 drivers/clk/imx/clk-imx6.c                         | 541 +++++++++++++++++++++
 drivers/clk/imx/clk-imx6sx.c                       | 483 ++++++++++++++++++
 drivers/clk/imx/clk-pfd.c                          | 148 ++++++
 drivers/clk/imx/clk-pllv1.c                        |  95 ++++
 drivers/clk/imx/clk-pllv2.c                        | 230 +++++++++
 drivers/clk/imx/clk-pllv3.c                        | 329 +++++++++++++
 drivers/clk/imx/clk-vf610.c                        | 443 +++++++++++++++++
 drivers/clk/imx/clk.c                              |  21 +
 drivers/clk/imx/clk.h                              | 123 +++++
 drivers/gpio/Kconfig                               |   3 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-vf610.c                          | 181 +++++++
 drivers/i2c/busses/i2c-imx.c                       | 225 ++++++---
 drivers/mci/imx-esdhc.c                            | 123 ++++-
 drivers/net/fec_imx.c                              |  74 ++-
 drivers/net/fec_imx.h                              |  10 +-
 drivers/pinctrl/Kconfig                            |   5 +
 drivers/pinctrl/Makefile                           |   1 +
 drivers/pinctrl/pinctrl-vf610.c                    | 167 +++++++
 drivers/pinctrl/pinctrl.c                          |  45 ++
 drivers/serial/Kconfig                             |   5 +
 drivers/serial/Makefile                            |   1 +
 drivers/serial/serial_lpuart.c                     | 217 +++++++++
 images/Makefile.imx                                |   5 +
 include/linux/clk/clk-conf.h                       |  14 +
 include/pinctrl.h                                  |  21 +
 include/serial/lpuart.h                            | 281 +++++++++++
 scripts/imx/imx.c                                  |   1 +
 75 files changed, 6870 insertions(+), 3980 deletions(-)
 create mode 100644 arch/arm/boards/freescale-vf610-twr/Makefile
 create mode 100644 arch/arm/boards/freescale-vf610-twr/flash-header-vf610-twr.imxcfg
 create mode 100644 arch/arm/boards/freescale-vf610-twr/lowlevel.c
 create mode 100644 arch/arm/dts/vf610-twr.dts
 delete mode 100644 arch/arm/mach-imx/clk-gate-exclusive.c
 delete mode 100644 arch/arm/mach-imx/clk-gate2.c
 delete mode 100644 arch/arm/mach-imx/clk-imx1.c
 delete mode 100644 arch/arm/mach-imx/clk-imx21.c
 delete mode 100644 arch/arm/mach-imx/clk-imx25.c
 delete mode 100644 arch/arm/mach-imx/clk-imx27.c
 delete mode 100644 arch/arm/mach-imx/clk-imx31.c
 delete mode 100644 arch/arm/mach-imx/clk-imx35.c
 delete mode 100644 arch/arm/mach-imx/clk-imx5.c
 delete mode 100644 arch/arm/mach-imx/clk-imx6.c
 delete mode 100644 arch/arm/mach-imx/clk-imx6sx.c
 delete mode 100644 arch/arm/mach-imx/clk-pfd.c
 delete mode 100644 arch/arm/mach-imx/clk-pllv1.c
 delete mode 100644 arch/arm/mach-imx/clk-pllv2.c
 delete mode 100644 arch/arm/mach-imx/clk-pllv3.c
 delete mode 100644 arch/arm/mach-imx/clk.h
 create mode 100644 arch/arm/mach-imx/include/mach/clock-vf610.h
 create mode 100644 arch/arm/mach-imx/include/mach/iomux-vf610.h
 create mode 100644 arch/arm/mach-imx/include/mach/vf610-regs.h
 create mode 100644 drivers/clk/clk-conf.c
 create mode 100644 drivers/clk/imx/Makefile
 create mode 100644 drivers/clk/imx/clk-gate-exclusive.c
 create mode 100644 drivers/clk/imx/clk-gate2.c
 create mode 100644 drivers/clk/imx/clk-imx1.c
 create mode 100644 drivers/clk/imx/clk-imx21.c
 create mode 100644 drivers/clk/imx/clk-imx25.c
 create mode 100644 drivers/clk/imx/clk-imx27.c
 create mode 100644 drivers/clk/imx/clk-imx31.c
 create mode 100644 drivers/clk/imx/clk-imx35.c
 create mode 100644 drivers/clk/imx/clk-imx5.c
 create mode 100644 drivers/clk/imx/clk-imx6.c
 create mode 100644 drivers/clk/imx/clk-imx6sx.c
 create mode 100644 drivers/clk/imx/clk-pfd.c
 create mode 100644 drivers/clk/imx/clk-pllv1.c
 create mode 100644 drivers/clk/imx/clk-pllv2.c
 create mode 100644 drivers/clk/imx/clk-pllv3.c
 create mode 100644 drivers/clk/imx/clk-vf610.c
 create mode 100644 drivers/clk/imx/clk.c
 create mode 100644 drivers/clk/imx/clk.h
 create mode 100644 drivers/gpio/gpio-vf610.c
 create mode 100644 drivers/pinctrl/pinctrl-vf610.c
 create mode 100644 drivers/serial/serial_lpuart.c
 create mode 100644 include/linux/clk/clk-conf.h
 create mode 100644 include/serial/lpuart.h

-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 01/28] i.MX: Add primitive functions for VF610 family
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 02/28] i.MX: Add register definitions for VF610 SoC Andrey Smirnov
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Add very basic functions to support VF610 family.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/Kconfig                      | 10 ++++++++++
 arch/arm/mach-imx/cpu_init.c                   |  5 +++++
 arch/arm/mach-imx/imx.c                        |  4 ++++
 arch/arm/mach-imx/include/mach/generic.h       | 13 +++++++++++++
 arch/arm/mach-imx/include/mach/imx_cpu_types.h |  1 +
 5 files changed, 33 insertions(+)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index f23af99..cfbaaa2 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -149,6 +149,16 @@ config ARCH_IMX6SX
 	select OFTREE
 	select COMMON_CLK_OF_PROVIDER
 
+config ARCH_VF610
+	bool
+	select ARCH_HAS_L2X0
+	select ARCH_HAS_FEC_IMX
+	select CPU_V7
+	select PINCTRL
+	select OFTREE
+	select COMMON_CLK
+	select COMMON_CLK_OF_PROVIDER
+
 config IMX_MULTI_BOARDS
 	bool "Allow multiple boards to be selected"
 	select HAVE_PBL_MULTI_IMAGES
diff --git a/arch/arm/mach-imx/cpu_init.c b/arch/arm/mach-imx/cpu_init.c
index 7603883..6971d89 100644
--- a/arch/arm/mach-imx/cpu_init.c
+++ b/arch/arm/mach-imx/cpu_init.c
@@ -33,3 +33,8 @@ void imx6_cpu_lowlevel_init(void)
 	enable_arm_errata_794072_war();
 	enable_arm_errata_845369_war();
 }
+
+void vf610_cpu_lowlevel_init(void)
+{
+	arm_cpu_lowlevel_init();
+}
diff --git a/arch/arm/mach-imx/imx.c b/arch/arm/mach-imx/imx.c
index 5ab6afc..eb2adcd 100644
--- a/arch/arm/mach-imx/imx.c
+++ b/arch/arm/mach-imx/imx.c
@@ -63,6 +63,8 @@ static int imx_soc_from_dt(void)
 		return IMX_CPU_IMX6;
 	if (of_machine_is_compatible("fsl,imx6qp"))
 		return IMX_CPU_IMX6;
+	if (of_machine_is_compatible("fsl,vf610"))
+		return IMX_CPU_VF610;
 
 	return 0;
 }
@@ -99,6 +101,8 @@ static int imx_init(void)
 		ret = imx53_init();
 	else if (cpu_is_mx6())
 		ret = imx6_init();
+	else if (cpu_is_vf610())
+		ret = 0;
 	else
 		return -EINVAL;
 
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 7c275df..3419450 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -45,6 +45,7 @@ int imx6_devices_init(void);
 
 void imx5_cpu_lowlevel_init(void);
 void imx6_cpu_lowlevel_init(void);
+void vf610_cpu_lowlevel_init(void);
 
 /* There's a off-by-one betweem the gpio bank number and the gpiochip */
 /* range e.g. GPIO_1_5 is gpio 5 under linux */
@@ -173,6 +174,18 @@ extern unsigned int __imx_cpu_type;
 # define cpu_is_mx6()		(0)
 #endif
 
+#ifdef CONFIG_ARCH_VF610
+# ifdef imx_cpu_type
+#  undef imx_cpu_type
+#  define imx_cpu_type __imx_cpu_type
+# else
+#  define imx_cpu_type IMX_CPU_VF610
+# endif
+# define cpu_is_vf610()		(imx_cpu_type == IMX_CPU_VF610)
+#else
+# define cpu_is_vf610()		(0)
+#endif
+
 #define cpu_is_mx23()	(0)
 #define cpu_is_mx28()	(0)
 
diff --git a/arch/arm/mach-imx/include/mach/imx_cpu_types.h b/arch/arm/mach-imx/include/mach/imx_cpu_types.h
index 8472488..50be0b6 100644
--- a/arch/arm/mach-imx/include/mach/imx_cpu_types.h
+++ b/arch/arm/mach-imx/include/mach/imx_cpu_types.h
@@ -11,5 +11,6 @@
 #define IMX_CPU_IMX51	51
 #define IMX_CPU_IMX53	53
 #define IMX_CPU_IMX6	6
+#define IMX_CPU_VF610	610
 
 #endif /* __MACH_IMX_CPU_TYPES_H */
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 02/28] i.MX: Add register definitions for VF610 SoC
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 01/28] i.MX: Add primitive functions for VF610 family Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 03/28] i.MX: Add DEBUG_LL hooks for VF610 Andrey Smirnov
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/include/mach/clock-vf610.h | 171 ++++++++++++++++++++
 arch/arm/mach-imx/include/mach/iomux-vf610.h | 226 +++++++++++++++++++++++++++
 arch/arm/mach-imx/include/mach/vf610-regs.h  | 110 +++++++++++++
 3 files changed, 507 insertions(+)
 create mode 100644 arch/arm/mach-imx/include/mach/clock-vf610.h
 create mode 100644 arch/arm/mach-imx/include/mach/iomux-vf610.h
 create mode 100644 arch/arm/mach-imx/include/mach/vf610-regs.h

diff --git a/arch/arm/mach-imx/include/mach/clock-vf610.h b/arch/arm/mach-imx/include/mach/clock-vf610.h
new file mode 100644
index 0000000..0fa70a4
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/clock-vf610.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __MACH_CLOCK_VF610_H__
+#define __MACH_CLOCK_VF610_H__
+
+#define VF610_CCM_CCR				(VF610_CCM_BASE_ADDR + 0x00)
+#define VF610_CCM_CSR				(VF610_CCM_BASE_ADDR + 0x04)
+#define VF610_CCM_CCSR				(VF610_CCM_BASE_ADDR + 0x08)
+#define VF610_CCM_CACRR				(VF610_CCM_BASE_ADDR + 0x0c)
+#define VF610_CCM_CSCMR1			(VF610_CCM_BASE_ADDR + 0x10)
+#define VF610_CCM_CSCDR1			(VF610_CCM_BASE_ADDR + 0x14)
+#define VF610_CCM_CSCDR2			(VF610_CCM_BASE_ADDR + 0x18)
+#define VF610_CCM_CSCDR3			(VF610_CCM_BASE_ADDR + 0x1c)
+#define VF610_CCM_CSCMR2			(VF610_CCM_BASE_ADDR + 0x20)
+#define VF610_CCM_CTOR				(VF610_CCM_BASE_ADDR + 0x28)
+#define VF610_CCM_CLPCR				(VF610_CCM_BASE_ADDR + 0x80)
+#define VF610_CCM_CMEOR5			(VF610_CCM_BASE_ADDR + 0x84)
+#define VF610_CCM_CPPDSR			(VF610_CCM_BASE_ADDR + 0x88)
+#define VF610_CCM_CCOWR				(VF610_CCM_BASE_ADDR + 0x8c)
+#define VF610_CCM_CCPGR0			(VF610_CCM_BASE_ADDR + 0x90)
+#define VF610_CCM_CCPGR1			(VF610_CCM_BASE_ADDR + 0x94)
+#define VF610_CCM_CCPGR2			(VF610_CCM_BASE_ADDR + 0x98)
+#define VF610_CCM_CCPGR3			(VF610_CCM_BASE_ADDR + 0x9c)
+
+#define VF610_CCM_CCGRx_CGn(n)	((n) * 2)
+
+#define VF610_ANADIG_PLL1_CTRL			(VF610_ANADIG_BASE_ADDR + 0x270)
+#define VF610_ANADIG_PLL1_NUM			(VF610_ANADIG_BASE_ADDR + 0x290)
+#define VF610_ANADIG_PLL1_DENOM			(VF610_ANADIG_BASE_ADDR + 0x2A0)
+#define VF610_ANADIG_PLL2_CTRL			(VF610_ANADIG_BASE_ADDR + 0x30)
+#define VF610_ANADIG_PLL2_NUM			(VF610_ANADIG_BASE_ADDR + 0x50)
+#define VF610_ANADIG_PLL3_CTRL			(VF610_ANADIG_BASE_ADDR + 0x10)
+#define VF610_ANADIG_PLL4_CTRL			(VF610_ANADIG_BASE_ADDR + 0x70)
+#define VF610_ANADIG_PLL5_CTRL			(VF610_ANADIG_BASE_ADDR + 0xe0)
+#define VF610_ANADIG_PLL6_CTRL			(VF610_ANADIG_BASE_ADDR + 0xa0)
+#define VF610_ANADIG_PLL7_CTRL			(VF610_ANADIG_BASE_ADDR + 0x20)
+#define VF610_ANADIG_ANA_MISC1			(VF610_ANADIG_BASE_ADDR + 0x160)
+#define VF610_ANADIG_LOCK			(VF610_ANADIG_BASE_ADDR + 0x2C0)
+
+#define CCM_CCR_FIRC_EN				(1 << 16)
+#define CCM_CCR_OSCNT_MASK			0xff
+#define CCM_CCR_OSCNT(v)			((v) & 0xff)
+
+#define CCM_CCSR_PLL2_PFD_CLK_SEL_OFFSET	19
+#define CCM_CCSR_PLL2_PFD_CLK_SEL_MASK		(0x7 << 19)
+#define CCM_CCSR_PLL2_PFD_CLK_SEL(v)		(((v) & 0x7) << 19)
+
+#define CCM_CCSR_PLL1_PFD_CLK_SEL_OFFSET	16
+#define CCM_CCSR_PLL1_PFD_CLK_SEL_MASK		(0x7 << 16)
+#define CCM_CCSR_PLL1_PFD_CLK_SEL(v)		(((v) & 0x7) << 16)
+
+#define CCM_CCSR_PLL2_PFD4_EN			(1 << 15)
+#define CCM_CCSR_PLL2_PFD3_EN			(1 << 14)
+#define CCM_CCSR_PLL2_PFD2_EN			(1 << 13)
+#define CCM_CCSR_PLL2_PFD1_EN			(1 << 12)
+#define CCM_CCSR_PLL1_PFD4_EN			(1 << 11)
+#define CCM_CCSR_PLL1_PFD3_EN			(1 << 10)
+#define CCM_CCSR_PLL1_PFD2_EN			(1 << 9)
+#define CCM_CCSR_PLL1_PFD1_EN			(1 << 8)
+
+#define CCM_CCSR_DDRC_CLK_SEL(v)		((v) << 6)
+#define CCM_CCSR_FAST_CLK_SEL(v)		((v) << 5)
+
+#define CCM_CCSR_SYS_CLK_SEL_OFFSET		0
+#define CCM_CCSR_SYS_CLK_SEL_MASK		0x7
+#define CCM_CCSR_SYS_CLK_SEL(v)			((v) & 0x7)
+
+#define CCM_CACRR_IPG_CLK_DIV_OFFSET		11
+#define CCM_CACRR_IPG_CLK_DIV_MASK		(0x3 << 11)
+#define CCM_CACRR_IPG_CLK_DIV(v)		(((v) & 0x3) << 11)
+#define CCM_CACRR_BUS_CLK_DIV_OFFSET		3
+#define CCM_CACRR_BUS_CLK_DIV_MASK		(0x7 << 3)
+#define CCM_CACRR_BUS_CLK_DIV(v)		(((v) & 0x7) << 3)
+#define CCM_CACRR_ARM_CLK_DIV_OFFSET		0
+#define CCM_CACRR_ARM_CLK_DIV_MASK		0x7
+#define CCM_CACRR_ARM_CLK_DIV(v)		((v) & 0x7)
+
+#define CCM_CSCMR1_QSPI0_CLK_SEL_OFFSET		22
+#define CCM_CSCMR1_QSPI0_CLK_SEL_MASK		(0x3 << 22)
+#define CCM_CSCMR1_QSPI0_CLK_SEL(v)		(((v) & 0x3) << 22)
+#define CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET	18
+#define CCM_CSCMR1_ESDHC1_CLK_SEL_MASK		(0x3 << 18)
+#define CCM_CSCMR1_ESDHC1_CLK_SEL(v)		(((v) & 0x3) << 18)
+#define CCM_CSCMR1_NFC_CLK_SEL_OFFSET		12
+#define CCM_CSCMR1_NFC_CLK_SEL_MASK		(0x3 << 12)
+#define CCM_CSCMR1_NFC_CLK_SEL(v)		(((v) & 0x3) << 12)
+
+#define CCM_CSCDR1_RMII_CLK_EN			(1 << 24)
+
+#define CCM_CSCDR2_NFC_EN			(1 << 9)
+#define CCM_CSCDR2_NFC_FRAC_DIV_EN		(1 << 13)
+#define CCM_CSCDR2_NFC_CLK_INV			(1 << 14)
+#define CCM_CSCDR2_NFC_FRAC_DIV_OFFSET		4
+#define CCM_CSCDR2_NFC_FRAC_DIV_MASK		(0xf << 4)
+#define CCM_CSCDR2_NFC_FRAC_DIV(v)		(((v) & 0xf) << 4)
+
+#define CCM_CSCDR2_ESDHC1_EN			(1 << 29)
+#define CCM_CSCDR2_ESDHC1_CLK_DIV_OFFSET	20
+#define CCM_CSCDR2_ESDHC1_CLK_DIV_MASK		(0xf << 20)
+#define CCM_CSCDR2_ESDHC1_CLK_DIV(v)		(((v) & 0xf) << 20)
+
+#define CCM_CSCDR3_NFC_PRE_DIV_OFFSET		13
+#define CCM_CSCDR3_NFC_PRE_DIV_MASK		(0x7 << 13)
+#define CCM_CSCDR3_NFC_PRE_DIV(v)		(((v) & 0x7) << 13)
+#define CCM_CSCDR3_QSPI0_EN			(1 << 4)
+#define CCM_CSCDR3_QSPI0_DIV(v)			((v) << 3)
+#define CCM_CSCDR3_QSPI0_X2_DIV(v)		((v) << 2)
+#define CCM_CSCDR3_QSPI0_X4_DIV(v)		((v) & 0x3)
+
+#define CCM_CSCMR2_RMII_CLK_SEL_OFFSET		4
+#define CCM_CSCMR2_RMII_CLK_SEL_MASK		(0x3 << 4)
+#define CCM_CSCMR2_RMII_CLK_SEL(v)		(((v) & 0x3) << 4)
+
+#define CCM_REG_CTRL_MASK			0xffffffff
+#define CCM_CCGR0_UART0_CTRL_MASK               (0x3 << 14)
+#define CCM_CCGR0_UART1_CTRL_MASK		(0x3 << 16)
+#define CCM_CCGR0_DSPI0_CTRL_MASK		(0x3 << 24)
+#define CCM_CCGR0_DSPI1_CTRL_MASK		(0x3 << 26)
+#define CCM_CCGR1_USBC0_CTRL_MASK		(0x3 << 8)
+#define CCM_CCGR1_PIT_CTRL_MASK			(0x3 << 14)
+#define CCM_CCGR1_WDOGA5_CTRL_MASK		(0x3 << 28)
+#define CCM_CCGR2_QSPI0_CTRL_MASK		(0x3 << 8)
+#define CCM_CCGR2_IOMUXC_CTRL_MASK		(0x3 << 16)
+#define CCM_CCGR2_PORTA_CTRL_MASK		(0x3 << 18)
+#define CCM_CCGR2_PORTB_CTRL_MASK		(0x3 << 20)
+#define CCM_CCGR2_PORTC_CTRL_MASK		(0x3 << 22)
+#define CCM_CCGR2_PORTD_CTRL_MASK		(0x3 << 24)
+#define CCM_CCGR2_PORTE_CTRL_MASK		(0x3 << 26)
+#define CCM_CCGR3_ANADIG_CTRL_MASK		0x3
+#define CCM_CCGR3_SCSC_CTRL_MASK		(0x3 << 4)
+#define CCM_CCGR4_WKUP_CTRL_MASK		(0x3 << 20)
+#define CCM_CCGR4_CCM_CTRL_MASK			(0x3 << 22)
+#define CCM_CCGR4_GPC_CTRL_MASK			(0x3 << 24)
+#define CCM_CCGR4_I2C0_CTRL_MASK		(0x3 << 12)
+#define CCM_CCGR4_I2C1_CTRL_MASK		(0x3 << 14)
+#define CCM_CCGR6_OCOTP_CTRL_MASK		(0x3 << 10)
+#define CCM_CCGR6_DSPI2_CTRL_MASK		(0x3 << 24)
+#define CCM_CCGR6_DSPI3_CTRL_MASK		(0x3 << 26)
+#define CCM_CCGR6_DDRMC_CTRL_MASK		(0x3 << 28)
+#define CCM_CCGR7_SDHC1_CTRL_MASK		(0x3 << 4)
+#define CCM_CCGR7_USBC1_CTRL_MASK		(0x3 << 8)
+#define CCM_CCGR9_FEC0_CTRL_MASK		0x3
+#define CCM_CCGR9_FEC1_CTRL_MASK		(0x3 << 2)
+#define CCM_CCGR10_NFC_CTRL_MASK		0x3
+#define CCM_CCGR10_I2C2_CTRL_MASK		(0x3 << 12)
+#define CCM_CCGR10_I2C3_CTRL_MASK		(0x3 << 14)
+
+#define ANADIG_PLL7_CTRL_BYPASS			(1 << 16)
+#define ANADIG_PLL7_CTRL_ENABLE			(1 << 13)
+#define ANADIG_PLL7_CTRL_POWERDOWN		(1 << 12)
+#define ANADIG_PLL7_CTRL_DIV_SELECT		(1 << 1)
+#define ANADIG_PLL5_CTRL_BYPASS			(1 << 16)
+#define ANADIG_PLL5_CTRL_ENABLE			(1 << 13)
+#define ANADIG_PLL5_CTRL_POWERDOWN		(1 << 12)
+#define ANADIG_PLL5_CTRL_DIV_SELECT		1
+#define ANADIG_PLL3_CTRL_BYPASS			(1 << 16)
+#define ANADIG_PLL3_CTRL_ENABLE			(1 << 13)
+#define ANADIG_PLL3_CTRL_POWERDOWN		(1 << 12)
+#define ANADIG_PLL3_CTRL_DIV_SELECT		(1 << 1)
+#define ANADIG_PLL2_CTRL_ENABLE			(1 << 13)
+#define ANADIG_PLL2_CTRL_POWERDOWN		(1 << 12)
+#define ANADIG_PLL2_CTRL_DIV_SELECT		1
+#define ANADIG_PLL1_CTRL_ENABLE			(1 << 13)
+#define ANADIG_PLL1_CTRL_POWERDOWN		(1 << 12)
+#define ANADIG_PLL1_CTRL_DIV_SELECT		1
+
+#endif
diff --git a/arch/arm/mach-imx/include/mach/iomux-vf610.h b/arch/arm/mach-imx/include/mach/iomux-vf610.h
new file mode 100644
index 0000000..1535628
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/iomux-vf610.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __MACH_IOMUX_VF610_H__
+#define __MACH_IOMUX_VF610_H__
+
+#include <mach/iomux-v3.h>
+
+#undef PAD_CTL_ODE
+#undef PAD_CTL_PKE
+#undef PAD_CTL_PUE
+
+enum {
+	PAD_MUX_MODE_SHIFT		= 20,
+	PAD_CTL_INPUT_DIFFERENTIAL	= 1 << 16,
+	PAD_CTL_SPEED_MED		= 1 << 12,
+	PAD_CTL_SPEED_HIGH		= 3 << 12,
+	PAD_CTL_SRE			= 1 << 11,
+	PAD_CTL_ODE			= 1 << 10,
+	PAD_CTL_DSE_150ohm		= 1 << 6,
+	PAD_CTL_DSE_50ohm		= 3 << 6,
+	PAD_CTL_DSE_25ohm		= 6 << 6,
+	PAD_CTL_DSE_20ohm		= 7 << 6,
+	PAD_CTL_PKE			= 1 << 3,
+	PAD_CTL_PUE			= 1 << 2 | PAD_CTL_PKE,
+	PAD_CTL_OBE_IBE_ENABLE		= 3 << 0,
+	PAD_CTL_OBE_ENABLE		= 1 << 1,
+	PAD_CTL_IBE_ENABLE		= 1 << 0,
+};
+
+/* These 2 defines are for pins that may not have a mux register, but could
+ * have a pad setting register, and vice-versa. */
+#define __NA_	0x00
+
+/* Pad control groupings */
+enum {
+
+	VF610_UART_PAD_CTRL	= PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_25ohm | PAD_CTL_OBE_IBE_ENABLE,
+	VF610_SDHC_PAD_CTRL	= PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_20ohm | PAD_CTL_OBE_IBE_ENABLE,
+	VF610_ENET_PAD_CTRL	= PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_50ohm | PAD_CTL_OBE_IBE_ENABLE,
+	VF610_DDR_PAD_CTRL	= PAD_CTL_DSE_25ohm,
+	VF610_DDR_PAD_CTRL_1	= PAD_CTL_DSE_25ohm | PAD_CTL_INPUT_DIFFERENTIAL,
+	VF610_I2C_PAD_CTRL	= PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_50ohm | PAD_CTL_SPEED_HIGH | PAD_CTL_ODE | PAD_CTL_OBE_IBE_ENABLE,
+	VF610_NFC_IO_PAD_CTRL	= PAD_CTL_SPEED_MED | PAD_CTL_SRE | PAD_CTL_DSE_50ohm | PAD_CTL_PUS_47K_UP | PAD_CTL_OBE_IBE_ENABLE,
+	VF610_NFC_CN_PAD_CTRL	= PAD_CTL_SPEED_MED | PAD_CTL_SRE | PAD_CTL_DSE_25ohm | PAD_CTL_OBE_ENABLE,
+	VF610_NFC_RB_PAD_CTRL	= PAD_CTL_SPEED_MED | PAD_CTL_SRE | PAD_CTL_PUS_22K_UP | PAD_CTL_IBE_ENABLE,
+	VF610_QSPI_PAD_CTRL	= PAD_CTL_SPEED_HIGH | PAD_CTL_DSE_150ohm | PAD_CTL_PUS_22K_UP | PAD_CTL_OBE_IBE_ENABLE,
+	VF610_GPIO_PAD_CTRL	= PAD_CTL_SPEED_MED | PAD_CTL_DSE_50ohm | PAD_CTL_IBE_ENABLE,
+	VF610_DSPI_PAD_CTRL	= PAD_CTL_OBE_ENABLE | PAD_CTL_DSE_20ohm | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_HIGH,
+	VF610_DSPI_SIN_PAD_CTRL	= PAD_CTL_IBE_ENABLE | PAD_CTL_DSE_20ohm | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_HIGH,
+};
+
+enum {
+	VF610_PAD_PTA6__RMII0_CLKIN	= IOMUX_PAD(0x0000, 0x0000, 2, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTA6__RMII0_CLKOUT	= IOMUX_PAD(0x0000, 0x0000, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTA7__GPIO_134	= IOMUX_PAD(0x0218, 0x0218, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTA17__GPIO_7		= IOMUX_PAD(0x001c, 0x001c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTA20__GPIO_10	= IOMUX_PAD(0x0028, 0x0028, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTA21__GPIO_11	= IOMUX_PAD(0x002c, 0x002c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTA30__GPIO_20	= IOMUX_PAD(0x0050, 0x0050, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTA31__GPIO_21	= IOMUX_PAD(0x0054, 0x0054, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB0__GPIO_22		= IOMUX_PAD(0x0058, 0x0058, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB1__GPIO_23		= IOMUX_PAD(0x005C, 0x005C, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB4__UART1_TX	= IOMUX_PAD(0x0068, 0x0068, 2, 0x0380, 0, VF610_UART_PAD_CTRL),
+	VF610_PAD_PTB5__UART1_RX	= IOMUX_PAD(0x006c, 0x006c, 2, 0x037c, 0, VF610_UART_PAD_CTRL),
+	VF610_PAD_PTB6__GPIO_28		= IOMUX_PAD(0x0070, 0x0070, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB7__GPIO_29		= IOMUX_PAD(0x0074, 0x0074, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB8__GPIO_30		= IOMUX_PAD(0x0078, 0x0078, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB9__GPIO_31		= IOMUX_PAD(0x007C, 0x007C, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB10__UART0_TX	= IOMUX_PAD(0x0080, 0x0080, 1, __NA_, 0, VF610_UART_PAD_CTRL),
+	VF610_PAD_PTB11__UART0_RX	= IOMUX_PAD(0x0084, 0x0084, 1, __NA_, 0, VF610_UART_PAD_CTRL),
+	VF610_PAD_PTB12__GPIO_34	= IOMUX_PAD(0x0088, 0x0088, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB13__GPIO_35	= IOMUX_PAD(0x008c, 0x008c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB16__GPIO_38	= IOMUX_PAD(0x0098, 0x0098, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB17__GPIO_39	= IOMUX_PAD(0x009c, 0x009c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB18__GPIO_40	= IOMUX_PAD(0x00a0, 0x00a0, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB21__GPIO_43	= IOMUX_PAD(0x00ac, 0x00ac, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB22__GPIO_44	= IOMUX_PAD(0x00b0, 0x00b0, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB23__GPIO_93	= IOMUX_PAD(0x0174, 0x0174, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB26__GPIO_96	= IOMUX_PAD(0x0180, 0x0180, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTB28__GPIO_98	= IOMUX_PAD(0x0188, 0x0188, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC1__GPIO_46		= IOMUX_PAD(0x00b8, 0x00b8, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC1__RMII0_MDIO	= IOMUX_PAD(0x00b8, 0x00b8, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC0__GPIO_45		= IOMUX_PAD(0x00b4, 0x00b4, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC0__RMII0_MDC	= IOMUX_PAD(0x00b4, 0x00b4, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC2__RMII0_CRS_DV	= IOMUX_PAD(0x00bc, 0x00bc, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC2__GPIO_47		= IOMUX_PAD(0x00bc, 0x00bc, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC3__RMII0_RD1	= IOMUX_PAD(0x00c0, 0x00c0, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC3__GPIO_48		= IOMUX_PAD(0x00c0, 0x00c0, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC4__RMII0_RD0	= IOMUX_PAD(0x00c4, 0x00c4, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC4__GPIO_49		= IOMUX_PAD(0x00c4, 0x00c4, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC5__RMII0_RXER	= IOMUX_PAD(0x00c8, 0x00c8, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC5__GPIO_50		= IOMUX_PAD(0x00c8, 0x00c8, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC6__RMII0_TD1	= IOMUX_PAD(0x00cc, 0x00cc, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC6__GPIO_51		= IOMUX_PAD(0x00cc, 0x00cc, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC7__RMII0_TD0	= IOMUX_PAD(0x00D0, 0x00D0, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC7__GPIO_52		= IOMUX_PAD(0x00D0, 0x00D0, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC8__RMII0_TXEN	= IOMUX_PAD(0x00D4, 0x00D4, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC8__GPIO_53		= IOMUX_PAD(0x00D4, 0x00D4, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC10__RMII1_MDIO	= IOMUX_PAD(0x00dc, 0x00dc, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC9__RMII1_MDC	= IOMUX_PAD(0x00d8, 0x00d8, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC11__RMII1_CRS_DV	= IOMUX_PAD(0x00e0, 0x00e0, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC12__RMII1_RD1	= IOMUX_PAD(0x00e4, 0x00e4, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC13__RMII1_RD0	= IOMUX_PAD(0x00e8, 0x00e8, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC14__RMII1_RXER	= IOMUX_PAD(0x00ec, 0x00ec, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC15__RMII1_TD1	= IOMUX_PAD(0x00f0, 0x00f0, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC16__RMII1_TD0	= IOMUX_PAD(0x00f4, 0x00f4, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTC17__RMII1_TXEN	= IOMUX_PAD(0x00f8, 0x00f8, 1, __NA_, 0, VF610_ENET_PAD_CTRL),
+	VF610_PAD_PTD5__DSPI1_CS0	= IOMUX_PAD(0x0150, 0x0150, 3, 0x300, 1, VF610_DSPI_PAD_CTRL),
+	VF610_PAD_PTD6__DSPI1_SIN	= IOMUX_PAD(0x0154, 0x0154, 3, 0x2fc, 1, VF610_DSPI_SIN_PAD_CTRL),
+	VF610_PAD_PTD7__DSPI1_SOUT	= IOMUX_PAD(0x0158, 0x0158, 3, __NA_, 0, VF610_DSPI_PAD_CTRL),
+	VF610_PAD_PTD8__DSPI1_SCK	= IOMUX_PAD(0x015c, 0x015c, 3, 0x2f8, 1, VF610_DSPI_PAD_CTRL),
+	VF610_PAD_PTC29__GPIO_102	= IOMUX_PAD(0x0198, 0x0198, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTC30__GPIO_103	= IOMUX_PAD(0x019c, 0x019c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTA24__ESDHC1_CLK	= IOMUX_PAD(0x0038, 0x0038, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
+	VF610_PAD_PTA25__ESDHC1_CMD	= IOMUX_PAD(0x003c, 0x003c, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
+	VF610_PAD_PTA26__ESDHC1_DAT0	= IOMUX_PAD(0x0040, 0x0040, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
+	VF610_PAD_PTA27__ESDHC1_DAT1	= IOMUX_PAD(0x0044, 0x0044, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
+	VF610_PAD_PTA28__ESDHC1_DAT2	= IOMUX_PAD(0x0048, 0x0048, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
+	VF610_PAD_PTA29__ESDHC1_DAT3	= IOMUX_PAD(0x004c, 0x004c, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
+	VF610_PAD_PTB14__I2C0_SCL	= IOMUX_PAD(0x0090, 0x0090, 2, 0x033c, 1, VF610_I2C_PAD_CTRL),
+	VF610_PAD_PTB15__I2C0_SDA	= IOMUX_PAD(0x0094, 0x0094, 2, 0x0340, 1, VF610_I2C_PAD_CTRL),
+	VF610_PAD_PTA22__I2C2_SCL	= IOMUX_PAD(0x0030, 0x0030, 6, 0x034c, 0, VF610_I2C_PAD_CTRL),
+	VF610_PAD_PTA23__I2C2_SDA	= IOMUX_PAD(0x0034, 0x0034, 6, 0x0350, 0, VF610_I2C_PAD_CTRL),
+	VF610_PAD_PTD31__NF_IO15	= IOMUX_PAD(0x00fc, 0x00fc, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD31__GPIO_63	= IOMUX_PAD(0x00fc, 0x00fc, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD30__NF_IO14	= IOMUX_PAD(0x0100, 0x0100, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD30__GPIO_64	= IOMUX_PAD(0x0100, 0x0100, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD29__NF_IO13	= IOMUX_PAD(0x0104, 0x0104, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD29__GPIO_65	= IOMUX_PAD(0x0104, 0x0104, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD28__NF_IO12	= IOMUX_PAD(0x0108, 0x0108, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD28__GPIO_66	= IOMUX_PAD(0x0108, 0x0108, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD27__NF_IO11	= IOMUX_PAD(0x010c, 0x010c, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD27__GPIO_67	= IOMUX_PAD(0x010c, 0x010c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD26__NF_IO10	= IOMUX_PAD(0x0110, 0x0110, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD26__GPIO_68	= IOMUX_PAD(0x0110, 0x0110, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD25__NF_IO9		= IOMUX_PAD(0x0114, 0x0114, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD25__GPIO_69	= IOMUX_PAD(0x0114, 0x0114, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD24__NF_IO8		= IOMUX_PAD(0x0118, 0x0118, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD24__GPIO_70	= IOMUX_PAD(0x0118, 0x0118, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD23__NF_IO7		= IOMUX_PAD(0x011c, 0x011c, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD0__QSPI0_A_QSCK	= IOMUX_PAD(0x013c, 0x013c, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD1__QSPI0_A_CS0	= IOMUX_PAD(0x0140, 0x0140, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD2__QSPI0_A_DATA3	= IOMUX_PAD(0x0144, 0x0144, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD3__QSPI0_A_DATA2	= IOMUX_PAD(0x0148, 0x0148, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD4__GPIO_83		= IOMUX_PAD(0x014C, 0x014C, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD4__QSPI0_A_DATA1	= IOMUX_PAD(0x014c, 0x014c, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD5__QSPI0_A_DATA0	= IOMUX_PAD(0x0150, 0x0150, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD7__QSPI0_B_QSCK	= IOMUX_PAD(0x0158, 0x0158, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD8__QSPI0_B_CS0	= IOMUX_PAD(0x015c, 0x015c, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD9__QSPI0_B_DATA3	= IOMUX_PAD(0x0160, 0x0160, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD9__GPIO_88		= IOMUX_PAD(0x0160, 0x0160, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD10__QSPI0_B_DATA2	= IOMUX_PAD(0x0164, 0x0164, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD10__GPIO_89	= IOMUX_PAD(0x0164, 0x0164, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD11__QSPI0_B_DATA1	= IOMUX_PAD(0x0168, 0x0168, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD11__GPIO_90	= IOMUX_PAD(0x0168, 0x0168, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD12__QSPI0_B_DATA0	= IOMUX_PAD(0x016c, 0x016c, 1, __NA_, 0, VF610_QSPI_PAD_CTRL),
+	VF610_PAD_PTD12__GPIO_91	= IOMUX_PAD(0x016c, 0x016c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD13__GPIO_92	= IOMUX_PAD(0x0170, 0x0170, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
+	VF610_PAD_PTD22__NF_IO6		= IOMUX_PAD(0x0120, 0x0120, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD21__NF_IO5		= IOMUX_PAD(0x0124, 0x0124, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD20__NF_IO4		= IOMUX_PAD(0x0128, 0x0128, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD19__NF_IO3		= IOMUX_PAD(0x012c, 0x012c, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD18__NF_IO2		= IOMUX_PAD(0x0130, 0x0130, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD17__NF_IO1		= IOMUX_PAD(0x0134, 0x0134, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTD16__NF_IO0		= IOMUX_PAD(0x0138, 0x0138, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+	VF610_PAD_PTB24__NF_WE_B	= IOMUX_PAD(0x0178, 0x0178, 5, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
+	VF610_PAD_PTB25__NF_CE0_B	= IOMUX_PAD(0x017c, 0x017c, 5, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
+	VF610_PAD_PTB27__NF_RE_B 	= IOMUX_PAD(0x0184, 0x0184, 6, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
+	VF610_PAD_PTC26__NF_RB_B 	= IOMUX_PAD(0x018C, 0x018C, 5, __NA_, 0, VF610_NFC_RB_PAD_CTRL),
+	VF610_PAD_PTC27__NF_ALE  	= IOMUX_PAD(0x0190, 0x0190, 6, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
+	VF610_PAD_PTC28__NF_CLE  	= IOMUX_PAD(0x0194, 0x0194, 6, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
+	VF610_PAD_DDR_RESETB		= IOMUX_PAD(0x021c, 0x021c, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A15__DDR_A_15	= IOMUX_PAD(0x0220, 0x0220, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A14__DDR_A_14	= IOMUX_PAD(0x0224, 0x0224, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A13__DDR_A_13	= IOMUX_PAD(0x0228, 0x0228, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A12__DDR_A_12	= IOMUX_PAD(0x022c, 0x022c, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A11__DDR_A_11	= IOMUX_PAD(0x0230, 0x0230, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A10__DDR_A_10	= IOMUX_PAD(0x0234, 0x0234, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A9__DDR_A_9	= IOMUX_PAD(0x0238, 0x0238, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A8__DDR_A_8	= IOMUX_PAD(0x023c, 0x023c, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A7__DDR_A_7	= IOMUX_PAD(0x0240, 0x0240, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A6__DDR_A_6	= IOMUX_PAD(0x0244, 0x0244, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A5__DDR_A_5	= IOMUX_PAD(0x0248, 0x0248, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A4__DDR_A_4	= IOMUX_PAD(0x024c, 0x024c, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A3__DDR_A_3	= IOMUX_PAD(0x0250, 0x0250, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A2__DDR_A_2	= IOMUX_PAD(0x0254, 0x0254, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A1__DDR_A_1	= IOMUX_PAD(0x0258, 0x0258, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_A0__DDR_A_0	= IOMUX_PAD(0x025c, 0x025c, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_BA2__DDR_BA_2	= IOMUX_PAD(0x0260, 0x0260, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_BA1__DDR_BA_1	= IOMUX_PAD(0x0264, 0x0264, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_BA0__DDR_BA_0	= IOMUX_PAD(0x0268, 0x0268, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_CAS__DDR_CAS_B	= IOMUX_PAD(0x026c, 0x026c, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_CKE__DDR_CKE_0	= IOMUX_PAD(0x0270, 0x0270, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_CLK__DDR_CLK_0	= IOMUX_PAD(0x0274, 0x0274, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_CS__DDR_CS_B_0	= IOMUX_PAD(0x0278, 0x0278, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_D15__DDR_D_15	= IOMUX_PAD(0x027c, 0x027c, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D14__DDR_D_14	= IOMUX_PAD(0x0280, 0x0280, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D13__DDR_D_13	= IOMUX_PAD(0x0284, 0x0284, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D12__DDR_D_12	= IOMUX_PAD(0x0288, 0x0288, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D11__DDR_D_11	= IOMUX_PAD(0x028c, 0x028c, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D10__DDR_D_10	= IOMUX_PAD(0x0290, 0x0290, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D9__DDR_D_9	= IOMUX_PAD(0x0294, 0x0294, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D8__DDR_D_8	= IOMUX_PAD(0x0298, 0x0298, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D7__DDR_D_7	= IOMUX_PAD(0x029c, 0x029c, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D6__DDR_D_6	= IOMUX_PAD(0x02a0, 0x02a0, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D5__DDR_D_5	= IOMUX_PAD(0x02a4, 0x02a4, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D4__DDR_D_4	= IOMUX_PAD(0x02a8, 0x02a8, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D3__DDR_D_3	= IOMUX_PAD(0x02ac, 0x02ac, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D2__DDR_D_2	= IOMUX_PAD(0x02b0, 0x02b0, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D1__DDR_D_1	= IOMUX_PAD(0x02b4, 0x02b4, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_D0__DDR_D_0	= IOMUX_PAD(0x02b8, 0x02b8, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_DQM1__DDR_DQM_1	= IOMUX_PAD(0x02bc, 0x02bc, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_DQM0__DDR_DQM_0	= IOMUX_PAD(0x02c0, 0x02c0, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_DQS1__DDR_DQS_1	= IOMUX_PAD(0x02c4, 0x02c4, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_DQS0__DDR_DQS_0	= IOMUX_PAD(0x02c8, 0x02c8, 0, __NA_, 0, VF610_DDR_PAD_CTRL_1),
+	VF610_PAD_DDR_RAS__DDR_RAS_B	= IOMUX_PAD(0x02cc, 0x02cc, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_WE__DDR_WE_B	= IOMUX_PAD(0x02d0, 0x02d0, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_ODT1__DDR_ODT_0	= IOMUX_PAD(0x02d4, 0x02d4, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+	VF610_PAD_DDR_ODT0__DDR_ODT_1	= IOMUX_PAD(0x02d8, 0x02d8, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
+};
+
+#endif	/* __IOMUX_VF610_H__ */
diff --git a/arch/arm/mach-imx/include/mach/vf610-regs.h b/arch/arm/mach-imx/include/mach/vf610-regs.h
new file mode 100644
index 0000000..8be220b
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/vf610-regs.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __MACH_VF610_REGS_H__
+#define __MACH_VF610_REGS_H__
+
+#define VF610_IRAM_BASE_ADDR		0x3F000000	/* internal ram */
+#define VF610_IRAM_SIZE			0x00080000	/* 512 KB */
+
+#define VF610_AIPS0_BASE_ADDR		0x40000000
+#define VF610_AIPS1_BASE_ADDR		0x40080000
+
+/* AIPS 0 */
+#define VF610_MSCM_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00001000)
+#define VF610_MSCM_IR_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00001800)
+#define VF610_CA5SCU_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00002000)
+#define VF610_CA5_INTD_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00003000)
+#define VF610_CA5_L2C_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00006000)
+#define VF610_NIC0_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00008000)
+#define VF610_NIC1_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00009000)
+#define VF610_NIC2_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0000A000)
+#define VF610_NIC3_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0000B000)
+#define VF610_NIC4_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0000C000)
+#define VF610_NIC5_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0000D000)
+#define VF610_NIC6_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0000E000)
+#define VF610_NIC7_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0000F000)
+#define VF610_AHBTZASC_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00010000)
+#define VF610_TZASC_SYS0_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00011000)
+#define VF610_TZASC_SYS1_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00012000)
+#define VF610_TZASC_GFX_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00013000)
+#define VF610_TZASC_DDR0_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00014000)
+#define VF610_TZASC_DDR1_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00015000)
+#define VF610_CSU_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00017000)
+#define VF610_DMA0_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00018000)
+#define VF610_DMA0_TCD_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00019000)
+#define VF610_SEMA4_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0001D000)
+#define VF610_FB_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0001E000)
+#define VF610_DMA_MUX0_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00024000)
+#define VF610_UART1_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00027000)
+#define VF610_UART2_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00028000)
+#define VF610_UART3_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00029000)
+#define VF610_UART4_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0002A000)
+#define VF610_SPI0_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0002C000)
+#define VF610_SPI1_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0002D000)
+#define VF610_SAI0_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0002F000)
+#define VF610_SAI1_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00030000)
+#define VF610_SAI2_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00031000)
+#define VF610_SAI3_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00032000)
+#define VF610_CRC_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00033000)
+#define VF610_USBC0_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00034000)
+#define VF610_PDB_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00036000)
+#define VF610_PIT_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00037000)
+#define VF610_FTM0_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00038000)
+#define VF610_FTM1_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00039000)
+#define VF610_ADC_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0003B000)
+#define VF610_TCON0_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0003D000)
+#define VF610_WDOG1_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0003E000)
+#define VF610_LPTMR_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00040000)
+#define VF610_RLE_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00042000)
+#define VF610_MLB_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00043000)
+#define VF610_QSPI0_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00044000)
+#define VF610_IOMUXC_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00048000)
+#define VF610_ANADIG_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00050000)
+#define VF610_USB_PHY0_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00050800)
+#define VF610_USB_PHY1_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00050C00)
+#define VF610_SCSC_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00052000)
+#define VF610_ASRC_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00060000)
+#define VF610_SPDIF_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00061000)
+#define VF610_ESAI_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00062000)
+#define VF610_ESAI_FIFO_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x00063000)
+#define VF610_WDOG_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00065000)
+#define VF610_I2C1_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00066000)
+#define VF610_I2C2_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x00067000)
+#define VF610_I2C3_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x000E6000)
+#define VF610_I2C4_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x000E7000)
+#define VF610_WKUP_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0006A000)
+#define VF610_CCM_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0006B000)
+#define VF610_GPC_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0006C000)
+#define VF610_VREG_DIG_BASE_ADDR	(VF610_AIPS0_BASE_ADDR + 0x0006D000)
+#define VF610_SRC_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0006E000)
+#define VF610_CMU_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x0006F000)
+#define VF610_GPIO0_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x000FF000)
+#define VF610_GPIO1_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x000FF040)
+#define VF610_GPIO2_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x000FF080)
+#define VF610_GPIO3_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x000FF0C0)
+#define VF610_GPIO4_BASE_ADDR		(VF610_AIPS0_BASE_ADDR + 0x000FF100)
+
+/* AIPS 1 */
+#define VF610_OCOTP_BASE_ADDR		(VF610_AIPS1_BASE_ADDR + 0x00025000)
+#define VF610_DDR_BASE_ADDR		(VF610_AIPS1_BASE_ADDR + 0x0002E000)
+#define VF610_ESDHC0_BASE_ADDR		(VF610_AIPS1_BASE_ADDR + 0x00031000)
+#define VF610_ESDHC1_BASE_ADDR		(VF610_AIPS1_BASE_ADDR + 0x00032000)
+#define VF610_USBC1_BASE_ADDR		(VF610_AIPS1_BASE_ADDR + 0x00034000)
+#define VF610_ENET_BASE_ADDR		(VF610_AIPS1_BASE_ADDR + 0x00050000)
+#define VF610_ENET1_BASE_ADDR		(VF610_AIPS1_BASE_ADDR + 0x00051000)
+#define VF610_NFC_BASE_ADDR		(VF610_AIPS1_BASE_ADDR + 0x00060000)
+
+#define VF610_QSPI0_AMBA_BASE		0x20000000
+
+
+/* MSCM interrupt rounter */
+#define VF610_MSCM_IRSPRC(n)		(0x880 + 2 * (n))
+#define VF610_MSCM_CPxTYPE		0
+#define VF610_MSCM_IRSPRC_CP0_EN	1
+#define VF610_MSCM_IRSPRC_NUM		112
+
+#endif
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 03/28] i.MX: Add DEBUG_LL hooks for VF610
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 01/28] i.MX: Add primitive functions for VF610 family Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 02/28] i.MX: Add register definitions for VF610 SoC Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 04/28] i.MX: scripts: Add "vf610" soc to imx-image Andrey Smirnov
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Add code to support DEBUG_LL functionality on VF610/Vybrid platform.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/include/mach/debug_ll.h |  27 ++-
 common/Kconfig                            |  10 +-
 include/serial/lpuart.h                   | 281 ++++++++++++++++++++++++++++++
 3 files changed, 316 insertions(+), 2 deletions(-)
 create mode 100644 include/serial/lpuart.h

diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index 5c2db6c..a132f3c 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -14,8 +14,10 @@
 #include <mach/imx51-regs.h>
 #include <mach/imx53-regs.h>
 #include <mach/imx6-regs.h>
+#include <mach/vf610-regs.h>
 
 #include <serial/imx-uart.h>
+#include <serial/lpuart.h>
 
 #ifdef CONFIG_DEBUG_LL
 
@@ -42,6 +44,8 @@
 #define IMX_DEBUG_SOC MX53
 #elif defined CONFIG_DEBUG_IMX6Q_UART
 #define IMX_DEBUG_SOC MX6
+#elif defined CONFIG_DEBUG_VF610_UART
+#define IMX_DEBUG_SOC VF610
 #else
 #error "unknown i.MX debug uart soc type"
 #endif
@@ -74,6 +78,13 @@ static inline void imx6_uart_setup_ll(void)
 	imx6_uart_setup(base);
 }
 
+static inline void vf610_uart_setup_ll(void)
+{
+	void *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, CONFIG_DEBUG_IMX_UART_PORT));
+
+	lpuart_setup(base, 66000000);
+}
+
 static inline void PUTC_LL(int c)
 {
 	void __iomem *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC,
@@ -82,14 +93,19 @@ static inline void PUTC_LL(int c)
 	if (!base)
 		return;
 
-	imx_uart_putc(base, c);
+	if (IS_ENABLED(CONFIG_DEBUG_VF610_UART))
+		lpuart_putc(base, c);
+	else
+		imx_uart_putc(base, c);
 }
+
 #else
 
 static inline void imx50_uart_setup_ll(void) {}
 static inline void imx51_uart_setup_ll(void) {}
 static inline void imx53_uart_setup_ll(void) {}
 static inline void imx6_uart_setup_ll(void)  {}
+static inline void vf610_uart_setup_ll(void) {}
 
 #endif /* CONFIG_DEBUG_LL */
 
@@ -115,4 +131,13 @@ static inline void imx53_ungate_all_peripherals(void)
 	imx_ungate_all_peripherals(IOMEM(MX53_CCM_BASE_ADDR));
 }
 
+static inline void vf610_ungate_all_peripherals(void)
+{
+	void __iomem *ccmbase = IOMEM(VF610_CCM_BASE_ADDR);
+	int i;
+
+	for (i = 0x40; i <= 0x6c; i += 4)
+		writel(0xffffffff, ccmbase + i);
+}
+
 #endif /* __MACH_DEBUG_LL_H__ */
diff --git a/common/Kconfig b/common/Kconfig
index efd1949..ed472a0 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1071,6 +1071,13 @@ config DEBUG_IMX6Q_UART
 	  Say Y here if you want kernel low-level debugging support
 	  on i.MX6Q.
 
+config DEBUG_VF610_UART
+	bool "VF610 Debug UART"
+	depends on ARCH_VF610
+	help
+	  Say Y here if you want kernel low-level debugging support
+	  on VF610.
+
 config DEBUG_OMAP3_UART
 	bool "OMAP3 Debug UART"
 	depends on ARCH_OMAP3
@@ -1111,7 +1118,8 @@ config DEBUG_IMX_UART_PORT
 						DEBUG_IMX51_UART || \
 						DEBUG_IMX53_UART || \
 						DEBUG_IMX6Q_UART || \
-						DEBUG_IMX6SL_UART
+						DEBUG_IMX6SL_UART || \
+						DEBUG_VF610_UART
 	default 1
 	depends on ARCH_IMX
 	help
diff --git a/include/serial/lpuart.h b/include/serial/lpuart.h
new file mode 100644
index 0000000..917f644
--- /dev/null
+++ b/include/serial/lpuart.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2016 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * Based on code found in Linux kernel and U-Boot.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __LPUART_H__
+#define __LPUART_H__
+
+
+/* All registers are 8-bit width */
+#define UARTBDH			0x00
+#define UARTBDL			0x01
+#define UARTCR1			0x02
+#define UARTCR2			0x03
+#define UARTSR1			0x04
+#define UARTCR3			0x06
+#define UARTDR			0x07
+#define UARTCR4			0x0a
+#define UARTCR5			0x0b
+#define UARTMODEM		0x0d
+#define UARTPFIFO		0x10
+#define UARTCFIFO		0x11
+#define UARTSFIFO		0x12
+#define UARTTWFIFO		0x13
+#define UARTTCFIFO		0x14
+#define UARTRWFIFO		0x15
+#define UARTRCFIFO		0x16
+
+#define UARTBDH_LBKDIE		0x80
+#define UARTBDH_RXEDGIE		0x40
+#define UARTBDH_SBR_MASK	0x1f
+
+#define UARTCR1_LOOPS		0x80
+#define UARTCR1_RSRC		0x20
+#define UARTCR1_M		0x10
+#define UARTCR1_WAKE		0x08
+#define UARTCR1_ILT		0x04
+#define UARTCR1_PE		0x02
+#define UARTCR1_PT		0x01
+
+#define UARTCR2_TIE		0x80
+#define UARTCR2_TCIE		0x40
+#define UARTCR2_RIE		0x20
+#define UARTCR2_ILIE		0x10
+#define UARTCR2_TE		0x08
+#define UARTCR2_RE		0x04
+#define UARTCR2_RWU		0x02
+#define UARTCR2_SBK		0x01
+
+#define UARTSR1_TDRE		0x80
+#define UARTSR1_TC		0x40
+#define UARTSR1_RDRF		0x20
+#define UARTSR1_IDLE		0x10
+#define UARTSR1_OR		0x08
+#define UARTSR1_NF		0x04
+#define UARTSR1_FE		0x02
+#define UARTSR1_PE		0x01
+
+#define UARTCR3_R8		0x80
+#define UARTCR3_T8		0x40
+#define UARTCR3_TXDIR		0x20
+#define UARTCR3_TXINV		0x10
+#define UARTCR3_ORIE		0x08
+#define UARTCR3_NEIE		0x04
+#define UARTCR3_FEIE		0x02
+#define UARTCR3_PEIE		0x01
+
+#define UARTCR4_MAEN1		0x80
+#define UARTCR4_MAEN2		0x40
+#define UARTCR4_M10		0x20
+#define UARTCR4_BRFA_MASK	0x1f
+#define UARTCR4_BRFA_OFF	0
+
+#define UARTCR5_TDMAS		0x80
+#define UARTCR5_RDMAS		0x20
+
+#define UARTMODEM_RXRTSE	0x08
+#define UARTMODEM_TXRTSPOL	0x04
+#define UARTMODEM_TXRTSE	0x02
+#define UARTMODEM_TXCTSE	0x01
+
+#define UARTPFIFO_TXFE		0x80
+#define UARTPFIFO_FIFOSIZE_MASK	0x7
+#define UARTPFIFO_TXSIZE_OFF	4
+#define UARTPFIFO_RXFE		0x08
+#define UARTPFIFO_RXSIZE_OFF	0
+
+#define UARTCFIFO_TXFLUSH	0x80
+#define UARTCFIFO_RXFLUSH	0x40
+#define UARTCFIFO_RXOFE		0x04
+#define UARTCFIFO_TXOFE		0x02
+#define UARTCFIFO_RXUFE		0x01
+
+#define UARTSFIFO_TXEMPT	0x80
+#define UARTSFIFO_RXEMPT	0x40
+#define UARTSFIFO_RXOF		0x04
+#define UARTSFIFO_TXOF		0x02
+#define UARTSFIFO_RXUF		0x01
+
+/* 32-bit register defination */
+#define UARTBAUD		0x00
+#define UARTSTAT		0x04
+#define UARTCTRL		0x08
+#define UARTDATA		0x0C
+#define UARTMATCH		0x10
+#define UARTMODIR		0x14
+#define UARTFIFO		0x18
+#define UARTWATER		0x1c
+
+#define UARTBAUD_MAEN1		0x80000000
+#define UARTBAUD_MAEN2		0x40000000
+#define UARTBAUD_M10		0x20000000
+#define UARTBAUD_TDMAE		0x00800000
+#define UARTBAUD_RDMAE		0x00200000
+#define UARTBAUD_MATCFG		0x00400000
+#define UARTBAUD_BOTHEDGE	0x00020000
+#define UARTBAUD_RESYNCDIS	0x00010000
+#define UARTBAUD_LBKDIE		0x00008000
+#define UARTBAUD_RXEDGIE	0x00004000
+#define UARTBAUD_SBNS		0x00002000
+#define UARTBAUD_SBR		0x00000000
+#define UARTBAUD_SBR_MASK	0x1fff
+
+#define UARTSTAT_LBKDIF		0x80000000
+#define UARTSTAT_RXEDGIF	0x40000000
+#define UARTSTAT_MSBF		0x20000000
+#define UARTSTAT_RXINV		0x10000000
+#define UARTSTAT_RWUID		0x08000000
+#define UARTSTAT_BRK13		0x04000000
+#define UARTSTAT_LBKDE		0x02000000
+#define UARTSTAT_RAF		0x01000000
+#define UARTSTAT_TDRE		0x00800000
+#define UARTSTAT_TC		0x00400000
+#define UARTSTAT_RDRF		0x00200000
+#define UARTSTAT_IDLE		0x00100000
+#define UARTSTAT_OR		0x00080000
+#define UARTSTAT_NF		0x00040000
+#define UARTSTAT_FE		0x00020000
+#define UARTSTAT_PE		0x00010000
+#define UARTSTAT_MA1F		0x00008000
+#define UARTSTAT_M21F		0x00004000
+
+#define UARTCTRL_R8T9		0x80000000
+#define UARTCTRL_R9T8		0x40000000
+#define UARTCTRL_TXDIR		0x20000000
+#define UARTCTRL_TXINV		0x10000000
+#define UARTCTRL_ORIE		0x08000000
+#define UARTCTRL_NEIE		0x04000000
+#define UARTCTRL_FEIE		0x02000000
+#define UARTCTRL_PEIE		0x01000000
+#define UARTCTRL_TIE		0x00800000
+#define UARTCTRL_TCIE		0x00400000
+#define UARTCTRL_RIE		0x00200000
+#define UARTCTRL_ILIE		0x00100000
+#define UARTCTRL_TE		0x00080000
+#define UARTCTRL_RE		0x00040000
+#define UARTCTRL_RWU		0x00020000
+#define UARTCTRL_SBK		0x00010000
+#define UARTCTRL_MA1IE		0x00008000
+#define UARTCTRL_MA2IE		0x00004000
+#define UARTCTRL_IDLECFG	0x00000100
+#define UARTCTRL_LOOPS		0x00000080
+#define UARTCTRL_DOZEEN		0x00000040
+#define UARTCTRL_RSRC		0x00000020
+#define UARTCTRL_M		0x00000010
+#define UARTCTRL_WAKE		0x00000008
+#define UARTCTRL_ILT		0x00000004
+#define UARTCTRL_PE		0x00000002
+#define UARTCTRL_PT		0x00000001
+
+#define UARTDATA_NOISY		0x00008000
+#define UARTDATA_PARITYE	0x00004000
+#define UARTDATA_FRETSC		0x00002000
+#define UARTDATA_RXEMPT		0x00001000
+#define UARTDATA_IDLINE		0x00000800
+#define UARTDATA_MASK		0x3ff
+
+#define UARTMODIR_IREN		0x00020000
+#define UARTMODIR_TXCTSSRC	0x00000020
+#define UARTMODIR_TXCTSC	0x00000010
+#define UARTMODIR_RXRTSE	0x00000008
+#define UARTMODIR_TXRTSPOL	0x00000004
+#define UARTMODIR_TXRTSE	0x00000002
+#define UARTMODIR_TXCTSE	0x00000001
+
+#define UARTFIFO_TXEMPT		0x00800000
+#define UARTFIFO_RXEMPT		0x00400000
+#define UARTFIFO_TXOF		0x00020000
+#define UARTFIFO_RXUF		0x00010000
+#define UARTFIFO_TXFLUSH	0x00008000
+#define UARTFIFO_RXFLUSH	0x00004000
+#define UARTFIFO_TXOFE		0x00000200
+#define UARTFIFO_RXUFE		0x00000100
+#define UARTFIFO_TXFE		0x00000080
+#define UARTFIFO_FIFOSIZE_MASK	0x7
+#define UARTFIFO_TXSIZE_OFF	4
+#define UARTFIFO_RXFE		0x00000008
+#define UARTFIFO_RXSIZE_OFF	0
+
+#define UARTWATER_COUNT_MASK	0xff
+#define UARTWATER_TXCNT_OFF	8
+#define UARTWATER_RXCNT_OFF	24
+#define UARTWATER_WATER_MASK	0xff
+#define UARTWATER_TXWATER_OFF	0
+#define UARTWATER_RXWATER_OFF	16
+
+#define FSL_UART_RX_DMA_BUFFER_SIZE	64
+
+static inline void lpuart_setbrg(void __iomem *base,
+				 unsigned int refclock,
+				 unsigned int baudrate)
+{
+	unsigned int bfra;
+	u16 sbr;
+
+	sbr = (u16) (refclock / (16 * baudrate));
+
+	writeb(sbr >> 8,   base + UARTBDH);
+	writeb(sbr & 0xff, base + UARTBDL);
+
+	bfra  = DIV_ROUND_UP(2 * refclock, baudrate) - 32 * sbr;
+	bfra &= UARTCR4_BRFA_MASK;
+	writeb(bfra, base + UARTCR4);
+}
+
+static inline void lpuart_setup_with_fifo(void __iomem *base,
+					  unsigned int refclock,
+					  unsigned int twfifo)
+{
+	/* Disable UART */
+	writeb(0, base + UARTCR2);
+	writeb(0, base + UARTMODEM);
+	writeb(0, base + UARTCR1);
+
+	if (twfifo) {
+		writeb(UARTPFIFO_TXFE | UARTPFIFO_RXFE, base + UARTPFIFO);
+		writeb((u8)twfifo, base + UARTTWFIFO);
+	} else {
+		writeb(0, base + UARTPFIFO);
+		writeb(0, base + UARTTWFIFO);
+	}
+	writeb(1, base + UARTRWFIFO);
+	writeb(UARTCFIFO_RXFLUSH | UARTCFIFO_TXFLUSH, base + UARTCFIFO);
+
+	lpuart_setbrg(base, refclock, CONFIG_BAUDRATE);
+
+	writeb(UARTCR2_TE | UARTCR2_RE, base + UARTCR2);
+}
+
+static inline void lpuart_setup(void __iomem *base,
+				unsigned int refclock)
+{
+	lpuart_setup_with_fifo(base, refclock, 0x00);
+}
+
+static inline void lpuart_putc(void __iomem *base, int c)
+{
+	if (!(readb(base + UARTCR2) & UARTCR2_TE))
+		return;
+
+	while (!(readb(base + UARTSR1) & UARTSR1_TDRE));
+
+	writeb(c, base + UARTDR);
+}
+
+#endif
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 04/28] i.MX: scripts: Add "vf610" soc to imx-image
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (2 preceding siblings ...)
  2016-11-09 16:13 ` [PATCH v2 03/28] i.MX: Add DEBUG_LL hooks for VF610 Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 05/28] i.MX: Add support for VF610 Tower board Andrey Smirnov
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Needed in order to support Vybrid SoCs.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 scripts/imx/imx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c
index c8ee309..bd48321 100644
--- a/scripts/imx/imx.c
+++ b/scripts/imx/imx.c
@@ -223,6 +223,7 @@ static struct soc_type socs[] = {
 	{ .name = "imx51", .header_version = 1, .cpu_type = IMX_CPU_IMX51 },
 	{ .name = "imx53", .header_version = 2, .cpu_type = IMX_CPU_IMX53 },
 	{ .name = "imx6", .header_version = 2, .cpu_type = IMX_CPU_IMX6 },
+	{ .name = "vf610", .header_version = 2, .cpu_type = IMX_CPU_VF610 },
 };
 
 static int do_soc(struct config_data *data, int argc, char *argv[])
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 05/28] i.MX: Add support for VF610 Tower board
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (3 preceding siblings ...)
  2016-11-09 16:13 ` [PATCH v2 04/28] i.MX: scripts: Add "vf610" soc to imx-image Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 06/28] pinctrl: Add provisions to control GPIO pin direction Andrey Smirnov
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Add support for VF610 Tower board.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/boards/Makefile                           |   1 +
 arch/arm/boards/freescale-vf610-twr/Makefile       |   3 +
 .../flash-header-vf610-twr.imxcfg                  | 278 +++++++++++++++++++++
 arch/arm/boards/freescale-vf610-twr/lowlevel.c     |  45 ++++
 arch/arm/dts/Makefile                              |   1 +
 arch/arm/dts/vf610-twr.dts                         |  14 ++
 arch/arm/mach-imx/Kconfig                          |   4 +
 images/Makefile.imx                                |   5 +
 8 files changed, 351 insertions(+)
 create mode 100644 arch/arm/boards/freescale-vf610-twr/Makefile
 create mode 100644 arch/arm/boards/freescale-vf610-twr/flash-header-vf610-twr.imxcfg
 create mode 100644 arch/arm/boards/freescale-vf610-twr/lowlevel.c
 create mode 100644 arch/arm/dts/vf610-twr.dts

diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index 1a0f63f..ff0a86f 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -140,3 +140,4 @@ obj-$(CONFIG_MACH_ZYLONITE)			+= zylonite/
 obj-$(CONFIG_MACH_VARISCITE_MX6)		+= variscite-mx6/
 obj-$(CONFIG_MACH_VSCOM_BALTOS)			+= vscom-baltos/
 obj-$(CONFIG_MACH_QEMU_VIRT64)			+= qemu-virt64/
+obj-$(CONFIG_MACH_VF610_TWR)			+= freescale-vf610-twr/
diff --git a/arch/arm/boards/freescale-vf610-twr/Makefile b/arch/arm/boards/freescale-vf610-twr/Makefile
new file mode 100644
index 0000000..6b029ce
--- /dev/null
+++ b/arch/arm/boards/freescale-vf610-twr/Makefile
@@ -0,0 +1,3 @@
+obj-y += flash-header-vf610-twr.dcd.o
+extra-y += flash-header-vf610-twr.dcd.S flash-header-vf610-twr.dcd
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/freescale-vf610-twr/flash-header-vf610-twr.imxcfg b/arch/arm/boards/freescale-vf610-twr/flash-header-vf610-twr.imxcfg
new file mode 100644
index 0000000..01ffc69
--- /dev/null
+++ b/arch/arm/boards/freescale-vf610-twr/flash-header-vf610-twr.imxcfg
@@ -0,0 +1,278 @@
+soc vf610
+loadaddr 0x80000000
+dcdofs 0x400
+
+#define VF610_DDR_PAD_CTRL	0x00000180 /* 25 Ohm drive strength */
+#define VF610_DDR_PAD_CTRL_1	0x00010180 /* 25 Ohm drive strength + differential input */
+
+#define DDRMC_PHY_DQ_TIMING	0x00002613
+#define DDRMC_PHY_DQS_TIMING	0x00002615
+#define DDRMC_PHY_CTRL		0x00210000
+#define DDRMC_PHY_MASTER_CTRL	0x0001012a
+#define DDRMC_PHY_SLAVE_CTRL	0x00002000
+#define DDRMC_PHY_OFF		0x00000000
+#define DDRMC_PHY_PROC_PAD_ODT	0x00010101
+
+#ifdef DEBUG
+#define CHECKPOINT(n) wm 32 0x3f040000 n
+#else
+#define CHECKPOINT(n)
+#endif
+
+CHECKPOINT(1)
+
+/* ======================= Clock initialization =======================*/
+
+/*
+ * Ungate all IP block clocks
+ */
+wm 32 0x4006b040 0xffffffff
+wm 32 0x4006b044 0xffffffff
+wm 32 0x4006b048 0xffffffff
+wm 32 0x4006b04c 0xffffffff
+wm 32 0x4006b050 0xffffffff
+wm 32 0x4006b058 0xffffffff
+wm 32 0x4006b05c 0xffffffff
+wm 32 0x4006b060 0xffffffff
+wm 32 0x4006b064 0xffffffff
+wm 32 0x4006b068 0xffffffff
+wm 32 0x4006b06c 0xffffffff
+
+
+/*
+ * We have to options to clock DDR controller:
+ *
+ *  - Use Core-A5 clock
+ *  - Use PLL2 PFD2 clock
+ *
+
+ * Using first option without changing PLL settings doesn't seem to be
+ * possible given that DDRMC requires minimum of 300Mhz and MaskROM
+ * configures it to be clocked at 264Mhz. Changing PLL1 settings
+ * proved to be challenging becuase MaskROM code executing this DCD
+ * will also be fetching the rest of the bootloader via some
+ * peripheral interface whose clock is derived from Cortex-A5 clock.
+ *
+ * As a result this DCD configuration code uses the second option of
+ * clocking DDR wiht PLL2 PFD2 clock output
+ *
+ * Turn PLL2 on
+ */
+wm 32 0x40050030 0x00002001 /* Fout = Fin * 22 */
+
+CHECKPOINT(2)
+
+/*
+ * Wait for PLLs to lock
+ */
+check 32 while_any_bit_clear 0x40050030 0x80000000
+
+
+CHECKPOINT(3)
+
+/*
+ * Switch DDRMC to be clocked with PLL2 PFD2 and enable PFD2 output
+ */
+clear_bits 32 0x4006b008 0x00000040
+set_bits   32 0x4006b008 0x00002000
+
+
+
+/* ======================= DDR IOMUX ======================= */
+
+CHECKPOINT(4)
+
+wm 32 0x40048220 VF610_DDR_PAD_CTRL
+wm 32 0x40048224 VF610_DDR_PAD_CTRL
+wm 32 0x40048228 VF610_DDR_PAD_CTRL
+wm 32 0x4004822c VF610_DDR_PAD_CTRL
+wm 32 0x40048230 VF610_DDR_PAD_CTRL
+wm 32 0x40048234 VF610_DDR_PAD_CTRL
+wm 32 0x40048238 VF610_DDR_PAD_CTRL
+wm 32 0x4004823c VF610_DDR_PAD_CTRL
+wm 32 0x40048240 VF610_DDR_PAD_CTRL
+wm 32 0x40048244 VF610_DDR_PAD_CTRL
+wm 32 0x40048248 VF610_DDR_PAD_CTRL
+wm 32 0x4004824c VF610_DDR_PAD_CTRL
+wm 32 0x40048250 VF610_DDR_PAD_CTRL
+wm 32 0x40048254 VF610_DDR_PAD_CTRL
+wm 32 0x40048258 VF610_DDR_PAD_CTRL
+wm 32 0x4004825c VF610_DDR_PAD_CTRL
+wm 32 0x40048260 VF610_DDR_PAD_CTRL
+wm 32 0x40048264 VF610_DDR_PAD_CTRL
+wm 32 0x40048268 VF610_DDR_PAD_CTRL
+wm 32 0x4004826c VF610_DDR_PAD_CTRL
+wm 32 0x40048270 VF610_DDR_PAD_CTRL
+wm 32 0x40048274 VF610_DDR_PAD_CTRL
+wm 32 0x40048278 VF610_DDR_PAD_CTRL
+wm 32 0x4004827c VF610_DDR_PAD_CTRL_1
+wm 32 0x40048280 VF610_DDR_PAD_CTRL_1
+wm 32 0x40048284 VF610_DDR_PAD_CTRL_1
+wm 32 0x40048288 VF610_DDR_PAD_CTRL_1
+wm 32 0x4004828c VF610_DDR_PAD_CTRL_1
+wm 32 0x40048290 VF610_DDR_PAD_CTRL_1
+wm 32 0x40048294 VF610_DDR_PAD_CTRL_1
+wm 32 0x40048298 VF610_DDR_PAD_CTRL_1
+wm 32 0x4004829c VF610_DDR_PAD_CTRL_1
+wm 32 0x400482a0 VF610_DDR_PAD_CTRL_1
+wm 32 0x400482a4 VF610_DDR_PAD_CTRL_1
+wm 32 0x400482a8 VF610_DDR_PAD_CTRL_1
+wm 32 0x400482ac VF610_DDR_PAD_CTRL_1
+wm 32 0x400482b0 VF610_DDR_PAD_CTRL_1
+wm 32 0x400482b4 VF610_DDR_PAD_CTRL_1
+wm 32 0x400482b8 VF610_DDR_PAD_CTRL_1
+wm 32 0x400482bc VF610_DDR_PAD_CTRL_1
+wm 32 0x400482c0 VF610_DDR_PAD_CTRL_1
+wm 32 0x400482c4 VF610_DDR_PAD_CTRL_1
+wm 32 0x400482c8 VF610_DDR_PAD_CTRL_1
+wm 32 0x400482cc VF610_DDR_PAD_CTRL
+wm 32 0x400482d0 VF610_DDR_PAD_CTRL
+wm 32 0x400482d4 VF610_DDR_PAD_CTRL
+wm 32 0x400482d8 VF610_DDR_PAD_CTRL
+wm 32 0x4004821c VF610_DDR_PAD_CTRL
+
+/* ======================= DDR Controller =======================*/
+
+CHECKPOINT(5)
+
+wm 32 0x400ae000 0x00000600
+wm 32 0x400ae008 0x00000020
+wm 32 0x400ae028 0x00013880
+wm 32 0x400ae02c 0x00030d40
+wm 32 0x400ae030 0x0000050c
+wm 32 0x400ae034 0x15040400
+wm 32 0x400ae038 0x1406040f
+wm 32 0x400ae040 0x04040000
+wm 32 0x400ae044 0x006db00c
+wm 32 0x400ae048 0x00000403
+wm 32 0x400ae050 0x01000000
+wm 32 0x400ae054 0x00060001
+wm 32 0x400ae058 0x000c0000
+wm 32 0x400ae05c 0x03000200
+wm 32 0x400ae060 0x00000006
+wm 32 0x400ae064 0x00010000
+wm 32 0x400ae068 0x0c30002c
+wm 32 0x400ae070 0x00000000
+wm 32 0x400ae074 0x00000003
+wm 32 0x400ae078 0x0000000a
+wm 32 0x400ae07c 0x003001d4
+wm 32 0x400ae084 0x00010000
+wm 32 0x400ae088 0x00050500
+wm 32 0x400ae098 0x00000000
+wm 32 0x400ae09c 0x04001002
+wm 32 0x400ae0a4 0x00000001
+wm 32 0x400ae0c0 0x00460420
+wm 32 0x400ae108 0x01000200
+wm 32 0x400ae10c 0x00000040
+wm 32 0x400ae114 0x00000200
+wm 32 0x400ae118 0x00000040
+wm 32 0x400ae120 0x00000000
+wm 32 0x400ae124 0x0a010300
+wm 32 0x400ae128 0x01014040
+wm 32 0x400ae12c 0x01010101
+wm 32 0x400ae130 0x03030100
+wm 32 0x400ae134 0x01000101
+wm 32 0x400ae138 0x0700000c
+wm 32 0x400ae13c 0x00000000
+wm 32 0x400ae148 0x10000000
+wm 32 0x400ae15c 0x01000000
+wm 32 0x400ae160 0x00040000
+wm 32 0x400ae164 0x00000002
+wm 32 0x400ae16c 0x00020000
+wm 32 0x400ae180 0x00002819
+wm 32 0x400ae184 0x01000000
+wm 32 0x400ae188 0x00000000
+wm 32 0x400ae18c 0x00000000
+wm 32 0x400ae198 0x00010100
+wm 32 0x400ae1a4 0x00000000
+wm 32 0x400ae1a8 0x00000004
+wm 32 0x400ae1b8 0x00040000
+wm 32 0x400ae1c8 0x00000000
+wm 32 0x400ae1cc 0x00000000
+wm 32 0x400ae1d4 0x00000000
+wm 32 0x400ae1d8 0x01010000
+wm 32 0x400ae1e0 0x02020000
+wm 32 0x400ae1e4 0x00000202
+wm 32 0x400ae1e8 0x01010064
+wm 32 0x400ae1ec 0x00010101
+wm 32 0x400ae1f0 0x00000064
+wm 32 0x400ae1f8 0x00000800
+wm 32 0x400ae210 0x00000506
+wm 32 0x400ae224 0x00020000
+wm 32 0x400ae228 0x01000000
+wm 32 0x400ae22c 0x04070303
+wm 32 0x400ae230 0x00000040
+wm 32 0x400ae23c 0x06000080
+wm 32 0x400ae240 0x04070303
+wm 32 0x400ae244 0x00000040
+wm 32 0x400ae248 0x00000040
+wm 32 0x400ae24c 0x000f0000
+wm 32 0x400ae250 0x000f0000
+wm 32 0x400ae25c 0x00000101
+wm 32 0x400ae268 0x682c4000
+wm 32 0x400ae26c 0x00000012
+wm 32 0x400ae278 0x00000006
+wm 32 0x400ae284 0x00010202
+
+/* ======================= DDR PHY =======================*/
+
+CHECKPOINT(6)
+
+wm 32 0x400ae400 DDRMC_PHY_DQ_TIMING
+wm 32 0x400ae440 DDRMC_PHY_DQ_TIMING
+wm 32 0x400ae480 DDRMC_PHY_DQ_TIMING
+wm 32 0x400ae404 DDRMC_PHY_DQS_TIMING
+wm 32 0x400ae444 DDRMC_PHY_DQS_TIMING
+wm 32 0x400ae408 DDRMC_PHY_CTRL
+wm 32 0x400ae448 DDRMC_PHY_CTRL
+wm 32 0x400ae488 DDRMC_PHY_CTRL
+wm 32 0x400ae40c DDRMC_PHY_MASTER_CTRL
+wm 32 0x400ae44c DDRMC_PHY_MASTER_CTRL
+wm 32 0x400ae48c DDRMC_PHY_MASTER_CTRL
+wm 32 0x400ae410 DDRMC_PHY_SLAVE_CTRL
+wm 32 0x400ae450 DDRMC_PHY_SLAVE_CTRL
+wm 32 0x400ae490 DDRMC_PHY_SLAVE_CTRL
+wm 32 0x400ae4c4 DDRMC_PHY_OFF
+wm 32 0x400ae4c8 0x00001100
+wm 32 0x400ae4d0 DDRMC_PHY_PROC_PAD_ODT
+
+wm 32 0x400ae000 0x00000601
+
+CHECKPOINT(7)
+
+check 32 while_any_bit_clear 0x400ae140 0x100
+
+CHECKPOINT(8)
+
+/*
+ * Cargo cult DDR controller initialization here we come!
+ *
+ * Experemintation with VF610 Tower Board shows that without the
+ * following code the board would not boot off of SD card when
+ * power-cycled. It will however happily boot when reset via SW3/Reset
+ * button. For whatever reason the following actions appear to be
+ * necessary:
+ *
+ *          - Initialize DDRMC as usual
+ *	    - Issue a read to location in DDR address space
+ *	    - Disable DDRMC
+ *	    - Enable DDRMC and wait for it to finish initializing
+ *
+ * I am sure this is all going to be extrememly embarrassing to read
+ * if/when the real problem and real solution is found.
+ */
+
+/*
+ * Because there's no standalone read command what we do here instead
+ * is write a pattern to memory and then checking that memory address
+ * against that pattern
+ */
+wm 32 0x80000000 0xa5a5a5a5
+check 32 while_any_bit_clear 0x80000000 0xa5a5a5a5
+
+wm 32 0x400ae000 0x00000600
+wm 32 0x400ae000 0x00000601
+
+check 32 while_any_bit_clear 0x400ae140 0x100
+
+CHECKPOINT(9)
\ No newline at end of file
diff --git a/arch/arm/boards/freescale-vf610-twr/lowlevel.c b/arch/arm/boards/freescale-vf610-twr/lowlevel.c
new file mode 100644
index 0000000..6504273
--- /dev/null
+++ b/arch/arm/boards/freescale-vf610-twr/lowlevel.c
@@ -0,0 +1,45 @@
+#include <common.h>
+#include <linux/sizes.h>
+#include <mach/generic.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <mach/vf610-regs.h>
+#include <mach/clock-vf610.h>
+#include <mach/iomux-vf610.h>
+#include <debug_ll.h>
+
+static inline void setup_uart(void)
+{
+	void __iomem *iomuxbase = IOMEM(VF610_IOMUXC_BASE_ADDR);
+
+	vf610_ungate_all_peripherals();
+
+	/*
+	 * VF610_PAD_PTB4__UART1_TX
+	 */
+	writel(VF610_UART_PAD_CTRL | (2 << 20), iomuxbase + 0x0068);
+	writel(0, iomuxbase + 0x0380);
+
+	vf610_uart_setup_ll();
+}
+
+extern char __dtb_vf610_twr_start[];
+
+ENTRY_FUNCTION(start_vf610_twr, r0, r1, r2)
+{
+	int i;
+	void *fdt;
+	void __iomem *mscm = IOMEM(VF610_MSCM_BASE_ADDR);
+
+	vf610_cpu_lowlevel_init();
+
+	for (i = 0; i < VF610_MSCM_IRSPRC_NUM; i++)
+		writew(VF610_MSCM_IRSPRC_CP0_EN,
+		       mscm + VF610_MSCM_IRSPRC(i));
+
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		setup_uart();
+
+	fdt = __dtb_vf610_twr_start - get_runtime_offset();
+	barebox_arm_entry(0x80000000, SZ_128M, fdt);
+}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 8d8d1fb..607c620 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -78,5 +78,6 @@ pbl-dtb-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o
 pbl-dtb-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o
 pbl-dtb-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o
 pbl-dtb-$(CONFIG_MACH_VSCOM_BALTOS) += am335x-baltos-minimal.dtb.o
+pbl-dtb-$(CONFIG_MACH_VF610_TWR) += vf610-twr.dtb.o
 
 clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts *.dtb.lzo
diff --git a/arch/arm/dts/vf610-twr.dts b/arch/arm/dts/vf610-twr.dts
new file mode 100644
index 0000000..54b4435
--- /dev/null
+++ b/arch/arm/dts/vf610-twr.dts
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <arm/vf610-twr.dts>
+
+&usbdev0 {
+	status = "disabled";
+};
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index cfbaaa2..5f4fdc6 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -337,6 +337,10 @@ config MACH_CM_FX6
 	bool "CM FX6"
 	select ARCH_IMX6
 
+config MACH_VF610_TWR
+	bool "Freescale VF610 Tower Board"
+	select ARCH_VF610
+
 endif
 
 # ----------------------------------------------------------
diff --git a/images/Makefile.imx b/images/Makefile.imx
index 8db9c75..983d896 100644
--- a/images/Makefile.imx
+++ b/images/Makefile.imx
@@ -403,3 +403,8 @@ pblx-$(CONFIG_MACH_ELTEC_HIPERCAM) += start_imx6dl_eltec_hipercam
 CFG_start_imx6dl_eltec_hipercam.pblx.imximg = $(board)/eltec-hipercam/flash-header-eltec-hipercam.imxcfg
 FILE_barebox-eltec-hipercam.img = start_imx6dl_eltec_hipercam.pblx.imximg
 image-$(CONFIG_MACH_ELTEC_HIPERCAM) += barebox-eltec-hipercam.img
+
+pblx-$(CONFIG_MACH_VF610_TWR) += start_vf610_twr
+CFG_start_vf610_twr.pblx.imximg = $(board)/freescale-vf610-twr/flash-header-vf610-twr.imxcfg
+FILE_barebox-vf610-twr.img = start_vf610_twr.pblx.imximg
+image-$(CONFIG_MACH_VF610_TWR) += barebox-vf610-twr.img
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 06/28] pinctrl: Add provisions to control GPIO pin direction
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (4 preceding siblings ...)
  2016-11-09 16:13 ` [PATCH v2 05/28] i.MX: Add support for VF610 Tower board Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 07/28] i.MX: Add pinctrl driver for VF610 Andrey Smirnov
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Some SoC (of which Vybrid is a one example) relegate GPIO direction
control to their pinmux IP block, instead of having that functionality
within GPIO IP. Add provisions to control that aspect of pinmux to
support such SoCs.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/pinctrl/pinctrl.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 include/pinctrl.h         | 21 +++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/drivers/pinctrl/pinctrl.c b/drivers/pinctrl/pinctrl.c
index e7b08a2..bef4fcd 100644
--- a/drivers/pinctrl/pinctrl.c
+++ b/drivers/pinctrl/pinctrl.c
@@ -24,6 +24,51 @@
 
 static LIST_HEAD(pinctrl_list);
 
+static struct pinctrl_device *pin_to_pinctrl(unsigned int pin)
+{
+	struct pinctrl_device *pinctrl;
+
+	list_for_each_entry(pinctrl, &pinctrl_list, list)
+		if (pin > pinctrl->base &&
+		    pin < pinctrl->base + pinctrl->npins)
+			return pinctrl;
+	return NULL;
+}
+
+static int pinctrl_gpio_direction(unsigned pin, bool input)
+{
+	struct pinctrl_device *pinctrl = pin_to_pinctrl(pin);
+
+	if (!pinctrl)
+		return -EINVAL;
+
+	BUG_ON(!pinctrl->ops->set_direction);
+
+	return pinctrl->ops->set_direction(pinctrl, pin, input);
+}
+
+int pinctrl_gpio_direction_input(unsigned int pin)
+{
+	return pinctrl_gpio_direction(pin, true);
+}
+
+int pinctrl_gpio_direction_output(unsigned int pin)
+{
+	return pinctrl_gpio_direction(pin, false);
+}
+
+int pinctrl_gpio_get_direction(unsigned pin)
+{
+	struct pinctrl_device *pinctrl = pin_to_pinctrl(pin);
+
+	if (!pinctrl)
+		return -EINVAL;
+
+	BUG_ON(!pinctrl->ops->get_direction);
+
+	return pinctrl->ops->get_direction(pinctrl, pin);
+}
+
 static struct pinctrl_device *find_pinctrl(struct device_node *node)
 {
 	struct pinctrl_device *pdev;
diff --git a/include/pinctrl.h b/include/pinctrl.h
index 0f03b10..0fde3f9 100644
--- a/include/pinctrl.h
+++ b/include/pinctrl.h
@@ -5,6 +5,8 @@ struct pinctrl_device;
 
 struct pinctrl_ops {
 	int (*set_state)(struct pinctrl_device *, struct device_node *);
+	int (*set_direction)(struct pinctrl_device *, unsigned int, bool);
+	int (*get_direction)(struct pinctrl_device *, unsigned int);
 };
 
 struct pinctrl_device {
@@ -12,6 +14,7 @@ struct pinctrl_device {
 	struct pinctrl_ops *ops;
 	struct list_head list;
 	struct device_node *node;
+	unsigned int base, npins;
 };
 
 int pinctrl_register(struct pinctrl_device *pdev);
@@ -22,6 +25,9 @@ int pinctrl_select_state(struct device_d *dev, const char *state);
 int pinctrl_select_state_default(struct device_d *dev);
 int of_pinctrl_select_state(struct device_node *np, const char *state);
 int of_pinctrl_select_state_default(struct device_node *np);
+int pinctrl_gpio_direction_input(unsigned pin);
+int pinctrl_gpio_direction_output(unsigned int pin);
+int pinctrl_gpio_get_direction(unsigned pin);
 #else
 static inline int pinctrl_select_state(struct device_d *dev, const char *state)
 {
@@ -42,6 +48,21 @@ static inline int of_pinctrl_select_state_default(struct device_node *np)
 {
 	return -ENODEV;
 }
+
+static inline int pinctrl_gpio_direction_input(unsigend pin)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pinctrl_gpio_direction_output(unsigned int pin)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pinctrl_gpio_get_direction(unsigned pin)
+{
+	return -ENOTSUPP;
+}
 #endif
 
 #endif /* PINCTRL_H */
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 07/28] i.MX: Add pinctrl driver for VF610
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (5 preceding siblings ...)
  2016-11-09 16:13 ` [PATCH v2 06/28] pinctrl: Add provisions to control GPIO pin direction Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 08/28] clk: Port clock dependency resolution code Andrey Smirnov
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/pinctrl/Kconfig         |   5 ++
 drivers/pinctrl/Makefile        |   1 +
 drivers/pinctrl/pinctrl-vf610.c | 167 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 173 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-vf610.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 5c69928..12fff4f 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -77,4 +77,9 @@ config PINCTRL_TEGRA_XUSB
 
 source drivers/pinctrl/mvebu/Kconfig
 
+config PINCTRL_VF610
+	bool
+	default y if ARCH_VF610
+	help
+	  Pinmux controller found on Vybrid VF610 family of SoCs
 endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index af9b30d..9450dbb 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -9,5 +9,6 @@ obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
 obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
 obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
 obj-$(CONFIG_PINCTRL_TEGRA_XUSB) += pinctrl-tegra-xusb.o
+obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o
 
 obj-$(CONFIG_ARCH_MVEBU) += mvebu/
diff --git a/drivers/pinctrl/pinctrl-vf610.c b/drivers/pinctrl/pinctrl-vf610.c
new file mode 100644
index 0000000..b479bf2
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-vf610.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2016 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <of.h>
+#include <pinctrl.h>
+#include <malloc.h>
+#include <gpio.h>
+
+enum {
+	PINCTRL_VF610_MUX_LINE_SIZE = 20,
+	PINCTRL_VF610_MUX_SHIFT = 20,
+
+	PINCTRL_VF610_IBE = 1 << 0,
+	PINCTRL_VF610_OBE = 1 << 1,
+	PINCTRL_VF610_xBE = 0b11,
+};
+
+struct pinctrl_vf610 {
+	void __iomem *base;
+	struct pinctrl_device pinctrl;
+};
+
+static int pinctrl_vf610_set_state(struct pinctrl_device *pdev,
+				   struct device_node *np)
+{
+	const __be32 *list;
+	int npins, size, i;
+
+	struct pinctrl_vf610 *iomux =
+		container_of(pdev, struct pinctrl_vf610, pinctrl);
+
+	list = of_get_property(np, "fsl,pins", &size);
+	if (!list)
+		return -EINVAL;
+
+	if (!size || size % PINCTRL_VF610_MUX_LINE_SIZE) {
+		dev_err(pdev->dev, "Invalid fsl,pins property in %s\n",
+			np->full_name);
+		return -EINVAL;
+	}
+
+	npins = size / PINCTRL_VF610_MUX_LINE_SIZE;
+
+	for (i = 0; i < npins; i++) {
+		u32 mux_reg   = be32_to_cpu(*list++);
+		u32 input_reg = be32_to_cpu(*list++);
+		u32 mux_val   = be32_to_cpu(*list++);
+		u32 input_val = be32_to_cpu(*list++);
+		u32 conf_val  = be32_to_cpu(*list++);
+
+		writel(mux_val << PINCTRL_VF610_MUX_SHIFT | conf_val,
+		       iomux->base + mux_reg);
+
+		if (input_reg)
+			writel(input_val, iomux->base + input_reg);
+	}
+
+	return 0;
+}
+
+static int pinctrl_vf610_set_direction(struct pinctrl_device *pdev,
+				       unsigned int pin, bool input)
+{
+	u32 pad_cr;
+	const u32 off = pin * sizeof(u32);
+	struct pinctrl_vf610 *iomux =
+		container_of(pdev, struct pinctrl_vf610, pinctrl);
+
+	pad_cr = readl(iomux->base + off);
+
+	if (input) {
+		pad_cr |= PINCTRL_VF610_IBE;
+		pad_cr &= ~PINCTRL_VF610_OBE;
+	} else {
+		pad_cr &= ~PINCTRL_VF610_IBE;
+		pad_cr |= PINCTRL_VF610_OBE;
+	}
+
+	writel(pad_cr, iomux->base + off);
+
+	return 0;
+}
+
+static int pinctrl_vf610_get_direction(struct pinctrl_device *pdev,
+				       unsigned int pin)
+{
+	const u32 off = pin * sizeof(u32);
+	struct pinctrl_vf610 *iomux =
+		container_of(pdev, struct pinctrl_vf610, pinctrl);
+
+	const u32 pad_cr = readl(iomux->base + off);
+
+	switch (pad_cr & PINCTRL_VF610_xBE) {
+	case PINCTRL_VF610_IBE:
+		return GPIOF_DIR_IN;
+	case PINCTRL_VF610_OBE:
+		return GPIOF_DIR_OUT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct pinctrl_ops pinctrl_vf610_ops = {
+	.set_state = pinctrl_vf610_set_state,
+	.set_direction = pinctrl_vf610_set_direction,
+	.get_direction = pinctrl_vf610_get_direction,
+};
+
+static int pinctrl_vf610_probe(struct device_d *dev)
+{
+	int ret;
+	struct resource *io;
+	struct pinctrl_vf610 *iomux;
+
+	iomux = xzalloc(sizeof(*iomux));
+
+	io = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(io))
+		return PTR_ERR(io);
+
+	iomux->base = IOMEM(io->start);
+	iomux->pinctrl.dev = dev;
+	iomux->pinctrl.ops = &pinctrl_vf610_ops;
+	iomux->pinctrl.base = 0;
+	iomux->pinctrl.npins = ARCH_NR_GPIOS;
+
+	ret = pinctrl_register(&iomux->pinctrl);
+	if (ret)
+		free(iomux);
+
+	return ret;
+}
+
+static __maybe_unused struct of_device_id pinctrl_vf610_dt_ids[] = {
+	{ .compatible = "fsl,vf610-iomuxc", },
+	{ /* sentinel */ }
+};
+
+static struct driver_d pinctrl_vf610_driver = {
+	.name		= "vf610-pinctrl",
+	.probe		= pinctrl_vf610_probe,
+	.of_compatible	= DRV_OF_COMPAT(pinctrl_vf610_dt_ids),
+};
+
+static int pinctrl_vf610_init(void)
+{
+	return platform_driver_register(&pinctrl_vf610_driver);
+}
+postcore_initcall(pinctrl_vf610_init);
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 08/28] clk: Port clock dependency resolution code
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (6 preceding siblings ...)
  2016-11-09 16:13 ` [PATCH v2 07/28] i.MX: Add pinctrl driver for VF610 Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 09/28] clk: Port of_clk_set_defaults() Andrey Smirnov
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Port the clock dependency resolution algorithm utilized by Linux
kernel's version of of_clk_init(), to allow for SoCs whose DT clock
configuration reqires such behaviour for correct initialization (Vybrid
is one such example).

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/clk/clk.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 82 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 630a84d..a38f339 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -404,7 +404,7 @@ EXPORT_SYMBOL_GPL(of_clk_del_provider);
 struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
 {
 	struct of_clk_provider *provider;
-	struct clk *clk = ERR_PTR(-ENOENT);
+	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
 
 	/* Check if we have such a provider in our array */
 	list_for_each_entry(provider, &of_clk_providers, link) {
@@ -437,6 +437,47 @@ char *of_clk_get_parent_name(struct device_node *np, unsigned int index)
 }
 EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
 
+struct clock_provider {
+	of_clk_init_cb_t clk_init_cb;
+	struct device_node *np;
+	struct list_head node;
+};
+
+/*
+ * This function looks for a parent clock. If there is one, then it
+ * checks that the provider for this parent clock was initialized, in
+ * this case the parent clock will be ready.
+ */
+static int parent_ready(struct device_node *np)
+{
+	int i = 0;
+
+	while (true) {
+		struct clk *clk = of_clk_get(np, i);
+
+		/* this parent is ready we can check the next one */
+		if (!IS_ERR(clk)) {
+			clk_put(clk);
+			i++;
+			continue;
+		}
+
+		/* at least one parent is not ready, we exit now */
+		if (PTR_ERR(clk) == -EPROBE_DEFER)
+			return 0;
+
+		/*
+		 * Here we make assumption that the device tree is
+		 * written correctly. So an error means that there is
+		 * no more parent. As we didn't exit yet, then the
+		 * previous parent are ready. If there is no clock
+		 * parent, no need to wait for them, then we can
+		 * consider their absence as being ready
+		 */
+		return 1;
+	}
+}
+
 /**
  * of_clk_init() - Scan and init clock providers from the DT
  * @root: parent of the first level to probe or NULL for the root of the tree
@@ -449,8 +490,11 @@ EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
  */
 int of_clk_init(struct device_node *root, const struct of_device_id *matches)
 {
+	struct clock_provider *clk_provider, *next;
+	bool is_init_done;
+	bool force = false;
+	LIST_HEAD(clk_provider_list);
 	const struct of_device_id *match;
-	int rc;
 
 	if (!root)
 		root = of_find_node_by_path("/");
@@ -459,12 +503,43 @@ int of_clk_init(struct device_node *root, const struct of_device_id *matches)
 	if (!matches)
 		matches = __clk_of_table_start;
 
+	/* First prepare the list of the clocks providers */
 	for_each_matching_node_and_match(root, matches, &match) {
-		of_clk_init_cb_t clk_init_cb = (of_clk_init_cb_t)match->data;
-		rc = clk_init_cb(root);
-		if (rc)
-			pr_err("%s: failed to init clock for %s: %d\n",
-			       __func__, root->full_name, rc);
+		struct clock_provider *parent;
+
+		if (!of_device_is_available(root))
+			continue;
+
+		parent = xzalloc(sizeof(*parent));
+
+		parent->clk_init_cb = match->data;
+		parent->np = root;
+		list_add_tail(&parent->node, &clk_provider_list);
+	}
+
+	while (!list_empty(&clk_provider_list)) {
+		is_init_done = false;
+		list_for_each_entry_safe(clk_provider, next,
+					 &clk_provider_list, node) {
+
+			if (force || parent_ready(clk_provider->np)) {
+
+				clk_provider->clk_init_cb(clk_provider->np);
+
+				list_del(&clk_provider->node);
+				free(clk_provider);
+				is_init_done = true;
+			}
+		}
+
+		/*
+		 * We didn't manage to initialize any of the
+		 * remaining providers during the last loop, so now we
+		 * initialize all the remaining ones unconditionally
+		 * in case the clock parent was not mandatory
+		 */
+		if (!is_init_done)
+			force = true;
 	}
 
 	return 0;
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 09/28] clk: Port of_clk_set_defaults()
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (7 preceding siblings ...)
  2016-11-09 16:13 ` [PATCH v2 08/28] clk: Port clock dependency resolution code Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-15  7:53   ` Sascha Hauer
  2016-11-09 16:13 ` [PATCH v2 10/28] i.MX: Move clk code from 'mach-imx' to 'drivers' Andrey Smirnov
                   ` (19 subsequent siblings)
  28 siblings, 1 reply; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Port of_clk_set_defautls() from Linux kernel in order to support DT
configurations that require it (e. g. Vybrid).

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/clk/Makefile         |   2 +-
 drivers/clk/clk-conf.c       | 144 +++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/clk.c            |   2 +
 include/linux/clk/clk-conf.h |  14 +++++
 4 files changed, 161 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/clk-conf.c
 create mode 100644 include/linux/clk/clk-conf.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 47ed7b1..0fe8f1e 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,6 +1,6 @@
 obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-fixed.o clk-divider.o clk-fixed-factor.o \
 				clk-mux.o clk-gate.o clk-composite.o \
-				clk-fractional-divider.o
+				clk-fractional-divider.o clk-conf.o
 obj-$(CONFIG_CLKDEV_LOOKUP)	+= clkdev.o
 
 obj-$(CONFIG_ARCH_MVEBU)	+= mvebu/
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
new file mode 100644
index 0000000..961fad8
--- /dev/null
+++ b/drivers/clk/clk-conf.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <io.h>
+#include <malloc.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/clk/clk-conf.h>
+
+static int __set_clk_parents(struct device_node *node, bool clk_supplier)
+{
+	struct of_phandle_args clkspec;
+	int index, rc, num_parents;
+	struct clk *clk, *pclk;
+
+	num_parents = of_count_phandle_with_args(node, "assigned-clock-parents",
+						 "#clock-cells");
+	if (num_parents == -EINVAL)
+		pr_err("clk: invalid value of clock-parents property at %s\n",
+		       node->full_name);
+
+	for (index = 0; index < num_parents; index++) {
+		rc = of_parse_phandle_with_args(node, "assigned-clock-parents",
+					"#clock-cells",	index, &clkspec);
+		if (rc < 0) {
+			/* skip empty (null) phandles */
+			if (rc == -ENOENT)
+				continue;
+			else
+				return rc;
+		}
+		if (clkspec.np == node && !clk_supplier)
+			return 0;
+		pclk = of_clk_get_from_provider(&clkspec);
+		if (IS_ERR(pclk)) {
+			pr_warn("clk: couldn't get parent clock %d for %s\n",
+				index, node->full_name);
+			return PTR_ERR(pclk);
+		}
+
+		rc = of_parse_phandle_with_args(node, "assigned-clocks",
+					"#clock-cells", index, &clkspec);
+		if (rc < 0)
+			goto err;
+		if (clkspec.np == node && !clk_supplier) {
+			rc = 0;
+			goto err;
+		}
+		clk = of_clk_get_from_provider(&clkspec);
+		if (IS_ERR(clk)) {
+			pr_warn("clk: couldn't get parent clock %d for %s\n",
+				index, node->full_name);
+			rc = PTR_ERR(clk);
+			goto err;
+		}
+
+		rc = clk_set_parent(clk, pclk);
+		if (rc < 0)
+			pr_err("clk: failed to reparent %s to %s: %d\n",
+			       __clk_get_name(clk), __clk_get_name(pclk), rc);
+		clk_put(clk);
+		clk_put(pclk);
+	}
+	return 0;
+err:
+	clk_put(pclk);
+	return rc;
+}
+
+static int __set_clk_rates(struct device_node *node, bool clk_supplier)
+{
+	struct of_phandle_args clkspec;
+	struct property	*prop;
+	const __be32 *cur;
+	int rc, index = 0;
+	struct clk *clk;
+	u32 rate;
+
+	of_property_for_each_u32(node, "assigned-clock-rates", prop, cur, rate) {
+		if (rate) {
+			rc = of_parse_phandle_with_args(node, "assigned-clocks",
+					"#clock-cells",	index, &clkspec);
+			if (rc < 0) {
+				/* skip empty (null) phandles */
+				if (rc == -ENOENT)
+					continue;
+				else
+					return rc;
+			}
+			if (clkspec.np == node && !clk_supplier)
+				return 0;
+
+			clk = of_clk_get_from_provider(&clkspec);
+			if (IS_ERR(clk)) {
+				pr_warn("clk: couldn't get clock %d for %s\n",
+					index, node->full_name);
+				return PTR_ERR(clk);
+			}
+
+			rc = clk_set_rate(clk, rate);
+			if (rc < 0)
+				pr_err("clk: couldn't set %s clk rate to %d (%d), current rate: %ld\n",
+				       __clk_get_name(clk), rate, rc,
+				       clk_get_rate(clk));
+			clk_put(clk);
+		}
+		index++;
+	}
+	return 0;
+}
+
+/**
+ * of_clk_set_defaults() - parse and set assigned clocks configuration
+ * @node: device node to apply clock settings for
+ * @clk_supplier: true if clocks supplied by @node should also be considered
+ *
+ * This function parses 'assigned-{clocks/clock-parents/clock-rates}' properties
+ * and sets any specified clock parents and rates. The @clk_supplier argument
+ * should be set to true if @node may be also a clock supplier of any clock
+ * listed in its 'assigned-clocks' or 'assigned-clock-parents' properties.
+ * If @clk_supplier is false the function exits returning 0 as soon as it
+ * determines the @node is also a supplier of any of the clocks.
+ */
+int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
+{
+	int rc;
+
+	if (!node)
+		return 0;
+
+	rc = __set_clk_parents(node, clk_supplier);
+	if (rc < 0)
+		return rc;
+
+	return __set_clk_rates(node, clk_supplier);
+}
+EXPORT_SYMBOL_GPL(of_clk_set_defaults);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index a38f339..28a1be5 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -19,6 +19,7 @@
 #include <malloc.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/clk/clk-conf.h>
 
 static LIST_HEAD(clks);
 
@@ -525,6 +526,7 @@ int of_clk_init(struct device_node *root, const struct of_device_id *matches)
 			if (force || parent_ready(clk_provider->np)) {
 
 				clk_provider->clk_init_cb(clk_provider->np);
+				of_clk_set_defaults(clk_provider->np, true);
 
 				list_del(&clk_provider->node);
 				free(clk_provider);
diff --git a/include/linux/clk/clk-conf.h b/include/linux/clk/clk-conf.h
new file mode 100644
index 0000000..0b8a973
--- /dev/null
+++ b/include/linux/clk/clk-conf.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+
+struct device_node;
+int of_clk_set_defaults(struct device_node *node, bool clk_supplier);
+
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 10/28] i.MX: Move clk code from 'mach-imx' to 'drivers'
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (8 preceding siblings ...)
  2016-11-09 16:13 ` [PATCH v2 09/28] clk: Port of_clk_set_defaults() Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:13 ` [PATCH v2 11/28] i.MX: clk: Port imx_clk_gate2_cgr() Andrey Smirnov
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Move clk code from 'mach-imx' to 'drivers' to keep the code tree
structure closer to that of analogous one from Linux kernel and,
arguably although subjective, to keep 'mach-imx' less cluttered.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/Makefile             |  23 +-
 arch/arm/mach-imx/clk-gate-exclusive.c | 103 -------
 arch/arm/mach-imx/clk-gate2.c          | 145 ---------
 arch/arm/mach-imx/clk-imx1.c           | 121 --------
 arch/arm/mach-imx/clk-imx21.c          | 196 ------------
 arch/arm/mach-imx/clk-imx25.c          | 200 ------------
 arch/arm/mach-imx/clk-imx27.c          | 270 ----------------
 arch/arm/mach-imx/clk-imx31.c          | 146 ---------
 arch/arm/mach-imx/clk-imx35.c          | 219 -------------
 arch/arm/mach-imx/clk-imx5.c           | 533 --------------------------------
 arch/arm/mach-imx/clk-imx6.c           | 541 ---------------------------------
 arch/arm/mach-imx/clk-imx6sx.c         | 483 -----------------------------
 arch/arm/mach-imx/clk-pfd.c            | 148 ---------
 arch/arm/mach-imx/clk-pllv1.c          |  95 ------
 arch/arm/mach-imx/clk-pllv2.c          | 230 --------------
 arch/arm/mach-imx/clk-pllv3.c          | 326 --------------------
 arch/arm/mach-imx/clk.h                | 104 -------
 drivers/clk/Makefile                   |   1 +
 drivers/clk/imx/Makefile               |  21 ++
 drivers/clk/imx/clk-gate-exclusive.c   | 103 +++++++
 drivers/clk/imx/clk-gate2.c            | 145 +++++++++
 drivers/clk/imx/clk-imx1.c             | 121 ++++++++
 drivers/clk/imx/clk-imx21.c            | 196 ++++++++++++
 drivers/clk/imx/clk-imx25.c            | 200 ++++++++++++
 drivers/clk/imx/clk-imx27.c            | 270 ++++++++++++++++
 drivers/clk/imx/clk-imx31.c            | 146 +++++++++
 drivers/clk/imx/clk-imx35.c            | 219 +++++++++++++
 drivers/clk/imx/clk-imx5.c             | 533 ++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk-imx6.c             | 541 +++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk-imx6sx.c           | 483 +++++++++++++++++++++++++++++
 drivers/clk/imx/clk-pfd.c              | 148 +++++++++
 drivers/clk/imx/clk-pllv1.c            |  95 ++++++
 drivers/clk/imx/clk-pllv2.c            | 230 ++++++++++++++
 drivers/clk/imx/clk-pllv3.c            | 326 ++++++++++++++++++++
 drivers/clk/imx/clk.h                  | 104 +++++++
 35 files changed, 3893 insertions(+), 3872 deletions(-)
 delete mode 100644 arch/arm/mach-imx/clk-gate-exclusive.c
 delete mode 100644 arch/arm/mach-imx/clk-gate2.c
 delete mode 100644 arch/arm/mach-imx/clk-imx1.c
 delete mode 100644 arch/arm/mach-imx/clk-imx21.c
 delete mode 100644 arch/arm/mach-imx/clk-imx25.c
 delete mode 100644 arch/arm/mach-imx/clk-imx27.c
 delete mode 100644 arch/arm/mach-imx/clk-imx31.c
 delete mode 100644 arch/arm/mach-imx/clk-imx35.c
 delete mode 100644 arch/arm/mach-imx/clk-imx5.c
 delete mode 100644 arch/arm/mach-imx/clk-imx6.c
 delete mode 100644 arch/arm/mach-imx/clk-imx6sx.c
 delete mode 100644 arch/arm/mach-imx/clk-pfd.c
 delete mode 100644 arch/arm/mach-imx/clk-pllv1.c
 delete mode 100644 arch/arm/mach-imx/clk-pllv2.c
 delete mode 100644 arch/arm/mach-imx/clk-pllv3.c
 delete mode 100644 arch/arm/mach-imx/clk.h
 create mode 100644 drivers/clk/imx/Makefile
 create mode 100644 drivers/clk/imx/clk-gate-exclusive.c
 create mode 100644 drivers/clk/imx/clk-gate2.c
 create mode 100644 drivers/clk/imx/clk-imx1.c
 create mode 100644 drivers/clk/imx/clk-imx21.c
 create mode 100644 drivers/clk/imx/clk-imx25.c
 create mode 100644 drivers/clk/imx/clk-imx27.c
 create mode 100644 drivers/clk/imx/clk-imx31.c
 create mode 100644 drivers/clk/imx/clk-imx35.c
 create mode 100644 drivers/clk/imx/clk-imx5.c
 create mode 100644 drivers/clk/imx/clk-imx6.c
 create mode 100644 drivers/clk/imx/clk-imx6sx.c
 create mode 100644 drivers/clk/imx/clk-pfd.c
 create mode 100644 drivers/clk/imx/clk-pllv1.c
 create mode 100644 drivers/clk/imx/clk-pllv2.c
 create mode 100644 drivers/clk/imx/clk-pllv3.c
 create mode 100644 drivers/clk/imx/clk.h

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index a216c9b..e426f2c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,25 +1,24 @@
 obj-y += clocksource.o
-obj-$(CONFIG_ARCH_IMX1)  += imx1.o clk-imx1.o
-obj-$(CONFIG_ARCH_IMX25) += imx25.o clk-imx25.o
-obj-$(CONFIG_ARCH_IMX21) += imx21.o clk-imx21.o
-obj-$(CONFIG_ARCH_IMX27) += imx27.o clk-imx27.o
-obj-$(CONFIG_ARCH_IMX31) += imx31.o clk-imx31.o
-obj-$(CONFIG_ARCH_IMX35) += imx35.o clk-imx35.o
-obj-$(CONFIG_ARCH_IMX50) += imx50.o imx5.o clk-imx5.o
+obj-$(CONFIG_ARCH_IMX1)  += imx1.o
+obj-$(CONFIG_ARCH_IMX25) += imx25.o
+obj-$(CONFIG_ARCH_IMX21) += imx21.o
+obj-$(CONFIG_ARCH_IMX27) += imx27.o
+obj-$(CONFIG_ARCH_IMX31) += imx31.o
+obj-$(CONFIG_ARCH_IMX35) += imx35.o
+obj-$(CONFIG_ARCH_IMX50) += imx50.o imx5.o
 pbl-$(CONFIG_ARCH_IMX50) += imx50.o imx5.o
-obj-$(CONFIG_ARCH_IMX51) += imx51.o imx5.o clk-imx5.o
+obj-$(CONFIG_ARCH_IMX51) += imx51.o imx5.o
 pbl-$(CONFIG_ARCH_IMX51) += imx51.o imx5.o
-obj-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o clk-imx5.o esdctl-v4.o
+obj-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
 pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
-obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o clk-imx6.o
+obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o
 lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
-obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
 obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
 obj-$(CONFIG_IMX_IIM)	+= iim.o
 obj-$(CONFIG_IMX_OCOTP)	+= ocotp.o
 obj-$(CONFIG_NAND_IMX) += nand.o
 lwl-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o
-obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-pfd.o clk-gate2.o clk-gate-exclusive.o
+
 obj-y += devices.o imx.o
 obj-pbl-y += esdctl.o boot.o
 obj-$(CONFIG_BAREBOX_UPDATE) += imx-bbu-internal.o
diff --git a/arch/arm/mach-imx/clk-gate-exclusive.c b/arch/arm/mach-imx/clk-gate-exclusive.c
deleted file mode 100644
index db88db0..0000000
--- a/arch/arm/mach-imx/clk-gate-exclusive.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2014 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <common.h>
-#include <io.h>
-#include <malloc.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include "clk.h"
-
-/**
- * struct clk_gate_exclusive - i.MX specific gate clock which is mutually
- * exclusive with other gate clocks
- *
- * @gate: the parent class
- * @exclusive_mask: mask of gate bits which are mutually exclusive to this
- *	gate clock
- *
- * The imx exclusive gate clock is a subclass of basic clk_gate
- * with an addtional mask to indicate which other gate bits in the same
- * register is mutually exclusive to this gate clock.
- */
-struct clk_gate_exclusive {
-	struct clk clk;
-	void __iomem *reg;
-	int shift;
-	const char *parent;
-	u32 exclusive_mask;
-};
-
-static int clk_gate_exclusive_enable(struct clk *clk)
-{
-	struct clk_gate_exclusive *exgate = container_of(clk,
-					struct clk_gate_exclusive, clk);
-	u32 val = readl(exgate->reg);
-
-	if (val & exgate->exclusive_mask)
-		return -EBUSY;
-
-	val |= 1 << exgate->shift;
-
-	writel(val, exgate->reg);
-
-	return 0;
-}
-
-static void clk_gate_exclusive_disable(struct clk *clk)
-{
-	struct clk_gate_exclusive *exgate = container_of(clk,
-					struct clk_gate_exclusive, clk);
-	u32 val = readl(exgate->reg);
-
-	val &= ~(1 << exgate->shift);
-
-	writel(val, exgate->reg);
-}
-
-static int clk_gate_exclusive_is_enabled(struct clk *clk)
-{
-	struct clk_gate_exclusive *exgate = container_of(clk,
-					struct clk_gate_exclusive, clk);
-
-	return readl(exgate->reg) & (1 << exgate->shift);
-}
-
-static const struct clk_ops clk_gate_exclusive_ops = {
-	.enable = clk_gate_exclusive_enable,
-	.disable = clk_gate_exclusive_disable,
-	.is_enabled = clk_gate_exclusive_is_enabled,
-};
-
-struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
-	 void __iomem *reg, u8 shift, u32 exclusive_mask)
-{
-	struct clk_gate_exclusive *exgate;
-	int ret;
-
-	exgate = xzalloc(sizeof(*exgate));
-	exgate->parent = parent;
-	exgate->clk.name = name;
-	exgate->clk.ops = &clk_gate_exclusive_ops;
-	exgate->clk.flags = CLK_SET_RATE_PARENT;
-	exgate->clk.parent_names = &exgate->parent;
-	exgate->clk.num_parents = 1;
-
-	exgate->reg = reg;
-	exgate->shift = shift;
-	exgate->exclusive_mask = exclusive_mask;
-
-	ret = clk_register(&exgate->clk);
-	if (ret) {
-		free(exgate);
-		return ERR_PTR(ret);
-	}
-
-	return &exgate->clk;
-}
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
deleted file mode 100644
index faed631..0000000
--- a/arch/arm/mach-imx/clk-gate2.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * clk-gate2.c - barebox 2-bit clock support. Based on Linux clk support
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <common.h>
-#include <io.h>
-#include <malloc.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include "clk.h"
-
-
-struct clk_gate2 {
-	struct clk clk;
-	void __iomem *reg;
-	int shift;
-	const char *parent;
-#define CLK_GATE_INVERTED	(1 << 0)
-	unsigned flags;
-};
-
-#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
-
-static int clk_gate2_enable(struct clk *clk)
-{
-	struct clk_gate2 *g = to_clk_gate2(clk);
-	u32 val;
-
-	val = readl(g->reg);
-
-	if (g->flags & CLK_GATE_INVERTED)
-		val &= ~(3 << g->shift);
-	else
-		val |= 3 << g->shift;
-
-	writel(val, g->reg);
-
-	return 0;
-}
-
-static void clk_gate2_disable(struct clk *clk)
-{
-	struct clk_gate2 *g = to_clk_gate2(clk);
-	u32 val;
-
-	val = readl(g->reg);
-
-	if (g->flags & CLK_GATE_INVERTED)
-		val |= 3 << g->shift;
-	else
-		val &= ~(3 << g->shift);
-
-	writel(val, g->reg);
-}
-
-static int clk_gate2_is_enabled(struct clk *clk)
-{
-	struct clk_gate2 *g = to_clk_gate2(clk);
-	u32 val;
-
-	val = readl(g->reg);
-
-	if (val & (1 << g->shift))
-		return g->flags & CLK_GATE_INVERTED ? 0 : 1;
-	else
-		return g->flags & CLK_GATE_INVERTED ? 1 : 0;
-}
-
-static struct clk_ops clk_gate2_ops = {
-	.set_rate = clk_parent_set_rate,
-	.round_rate = clk_parent_round_rate,
-	.enable = clk_gate2_enable,
-	.disable = clk_gate2_disable,
-	.is_enabled = clk_gate2_is_enabled,
-};
-
-struct clk *clk_gate2_alloc(const char *name, const char *parent,
-		void __iomem *reg, u8 shift)
-{
-	struct clk_gate2 *g = xzalloc(sizeof(*g));
-
-	g->parent = parent;
-	g->reg = reg;
-	g->shift = shift;
-	g->clk.ops = &clk_gate2_ops;
-	g->clk.name = name;
-	g->clk.parent_names = &g->parent;
-	g->clk.num_parents = 1;
-	g->clk.flags = CLK_SET_RATE_PARENT;
-
-	return &g->clk;
-}
-
-void clk_gate2_free(struct clk *clk)
-{
-	struct clk_gate2 *g = to_clk_gate2(clk);
-
-	free(g);
-}
-
-struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
-		u8 shift)
-{
-	struct clk *g;
-	int ret;
-
-	g = clk_gate2_alloc(name , parent, reg, shift);
-
-	ret = clk_register(g);
-	if (ret) {
-		free(to_clk_gate2(g));
-		return ERR_PTR(ret);
-	}
-
-	return g;
-}
-
-struct clk *clk_gate2_inverted(const char *name, const char *parent,
-		void __iomem *reg, u8 shift)
-{
-	struct clk *clk;
-	struct clk_gate2 *g;
-
-	clk = clk_gate2(name, parent, reg, shift);
-	if (IS_ERR(clk))
-		return clk;
-
-	g = to_clk_gate2(clk);
-
-	g->flags = CLK_GATE_INVERTED;
-
-	return clk;
-}
diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
deleted file mode 100644
index 5f600a9..0000000
--- a/arch/arm/mach-imx/clk-imx1.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *  Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx1-regs.h>
-
-#include "clk.h"
-
-#define CCM_CSCR	0x0
-#define CCM_MPCTL0	0x4
-#define CCM_SPCTL0	0xc
-#define CCM_PCDR	0x20
-
-enum imx1_clks {
-	dummy, clk32, clk16m, clk32_premult, prem, mpll, spll, mcu,
-	fclk, hclk, clk48m, per1, per2, per3, clko, dma_gate, csi_gate,
-	mma_gate, usbd_gate, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *prem_sel_clks[] = {
-	"clk32_premult",
-	"clk16m",
-};
-
-static const char *clko_sel_clks[] = {
-	"per1",
-	"hclk",
-	"clk48m",
-	"clk16m",
-	"prem",
-	"fclk",
-};
-
-int __init mx1_clocks_init(void __iomem *regs, unsigned long fref)
-{
-	clks[dummy] = clk_fixed("dummy", 0);
-	clks[clk32] = clk_fixed("clk32", fref);
-	clks[clk16m] = clk_fixed("clk16m", 16000000);
-	clks[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
-	clks[prem] = imx_clk_mux("prem", regs + CCM_CSCR, 16, 1, prem_sel_clks,
-			ARRAY_SIZE(prem_sel_clks));
-	clks[mpll] = imx_clk_pllv1("mpll", "clk32_premult", regs + CCM_MPCTL0);
-	clks[spll] = imx_clk_pllv1("spll", "prem", regs + CCM_SPCTL0);
-	clks[mcu] = imx_clk_divider("mcu", "clk32_premult", regs + CCM_CSCR, 15, 1);
-	clks[fclk] = imx_clk_divider("fclk", "mpll", regs + CCM_CSCR, 15, 1);
-	clks[hclk] = imx_clk_divider("hclk", "spll", regs + CCM_CSCR, 10, 4);
-	clks[clk48m] = imx_clk_divider("clk48m", "spll", regs + CCM_CSCR, 26, 3);
-	clks[per1] = imx_clk_divider("per1", "spll", regs + CCM_PCDR, 0, 4);
-	clks[per2] = imx_clk_divider("per2", "spll", regs + CCM_PCDR, 4, 4);
-	clks[per3] = imx_clk_divider("per3", "spll", regs + CCM_PCDR, 16, 7);
-	clks[clko] = imx_clk_mux("clko", regs + CCM_CSCR, 29, 3, clko_sel_clks,
-			ARRAY_SIZE(clko_sel_clks));
-
-	clkdev_add_physbase(clks[per1], MX1_TIM1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1], MX1_TIM2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per2], MX1_LCDC_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1], MX1_UART1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1], MX1_UART2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per2], MX1_CSPI1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per2], MX1_CSPI2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[hclk], MX1_I2C_BASE_ADDR, NULL);
-
-	return 0;
-}
-
-static int imx1_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *regs;
-
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	regs = IOMEM(iores->start);
-
-	mx1_clocks_init(regs, 32000);
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx1_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx1-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx1_ccm_driver = {
-	.probe	= imx1_ccm_probe,
-	.name	= "imx1-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx1_ccm_dt_ids),
-};
-
-static int imx1_ccm_init(void)
-{
-	return platform_driver_register(&imx1_ccm_driver);
-}
-core_initcall(imx1_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c
deleted file mode 100644
index 546461b..0000000
--- a/arch/arm/mach-imx/clk-imx21.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx21-regs.h>
-
-#include "clk.h"
-
-/* Register offsets */
-#define CCM_CSCR		0x0
-#define CCM_MPCTL0		0x4
-#define CCM_MPCTL1		0x8
-#define CCM_SPCTL0		0xc
-#define CCM_SPCTL1		0x10
-#define CCM_OSC26MCTL		0x14
-#define CCM_PCDR0		0x18
-#define CCM_PCDR1		0x1c
-#define CCM_PCCR0		0x20
-#define CCM_PCCR1		0x24
-#define CCM_CCSR		0x28
-#define CCM_PMCTL		0x2c
-#define CCM_PMCOUNT		0x30
-#define CCM_WKGDCTL		0x34
-
-#define PCCR0_UART1_EN		(1 << 0)
-#define PCCR0_UART2_EN		(1 << 1)
-#define PCCR0_UART3_EN		(1 << 2)
-#define PCCR0_UART4_EN		(1 << 3)
-#define PCCR0_CSPI1_EN		(1 << 4)
-#define PCCR0_CSPI2_EN		(1 << 5)
-#define PCCR0_SSI1_EN		(1 << 6)
-#define PCCR0_SSI2_EN		(1 << 7)
-#define PCCR0_FIRI_EN		(1 << 8)
-#define PCCR0_SDHC1_EN		(1 << 9)
-#define PCCR0_SDHC2_EN		(1 << 10)
-#define PCCR0_GPIO_EN		(1 << 11)
-#define PCCR0_I2C_EN		(1 << 12)
-#define PCCR0_DMA_EN		(1 << 13)
-#define PCCR0_USBOTG_EN		(1 << 14)
-#define PCCR0_EMMA_EN		(1 << 15)
-#define PCCR0_SSI2_BAUD_EN	(1 << 16)
-#define PCCR0_SSI1_BAUD_EN	(1 << 17)
-#define PCCR0_PERCLK3_EN	(1 << 18)
-#define PCCR0_NFC_EN		(1 << 19)
-#define PCCR0_FRI_BAUD_EN	(1 << 20)
-#define PCCR0_SLDC_EN		(1 << 21)
-#define PCCR0_PERCLK4_EN	(1 << 22)
-#define PCCR0_HCLK_BMI_EN	(1 << 23)
-#define PCCR0_HCLK_USBOTG_EN	(1 << 24)
-#define PCCR0_HCLK_SLCDC_EN	(1 << 25)
-#define PCCR0_HCLK_LCDC_EN	(1 << 26)
-#define PCCR0_HCLK_EMMA_EN	(1 << 27)
-#define PCCR0_HCLK_BROM_EN	(1 << 28)
-#define PCCR0_HCLK_DMA_EN	(1 << 30)
-#define PCCR0_HCLK_CSI_EN	(1 << 31)
-
-#define PCCR1_CSPI3_EN	(1 << 23)
-#define PCCR1_WDT_EN	(1 << 24)
-#define PCCR1_GPT1_EN	(1 << 25)
-#define PCCR1_GPT2_EN	(1 << 26)
-#define PCCR1_GPT3_EN	(1 << 27)
-#define PCCR1_PWM_EN	(1 << 28)
-#define PCCR1_RTC_EN	(1 << 29)
-#define PCCR1_KPP_EN	(1 << 30)
-#define PCCR1_OWIRE_EN	(1 << 31)
-
-enum imx21_clks {
-	ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1,
-	per2, per3, per4, usb_div, nfc_div, lcdc_per_gate, lcdc_ahb_gate,
-	lcdc_ipg_gate, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *mpll_sel_clks[] = {
-	"fpm",
-	"ckih",
-};
-
-static const char *spll_sel_clks[] = {
-	"fpm",
-	"ckih",
-};
-
-static int imx21_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *base;
-	unsigned long lref = 32768;
-	unsigned long href = 26000000;
-
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	base = IOMEM(iores->start);
-
-	writel(PCCR0_UART1_EN | PCCR0_UART2_EN | PCCR0_UART3_EN | PCCR0_UART4_EN |
-			PCCR0_CSPI1_EN | PCCR0_CSPI2_EN | PCCR0_SDHC1_EN |
-			PCCR0_SDHC2_EN | PCCR0_GPIO_EN | PCCR0_I2C_EN | PCCR0_DMA_EN |
-			PCCR0_USBOTG_EN | PCCR0_NFC_EN | PCCR0_PERCLK4_EN |
-			PCCR0_HCLK_USBOTG_EN | PCCR0_HCLK_DMA_EN,
-			base + CCM_PCCR0);
-
-	writel(PCCR1_CSPI3_EN | PCCR1_WDT_EN | PCCR1_GPT1_EN | PCCR1_GPT2_EN |
-			PCCR1_GPT3_EN | PCCR1_PWM_EN | PCCR1_RTC_EN | PCCR1_KPP_EN |
-			PCCR1_OWIRE_EN,
-			base + CCM_PCCR1);
-
-	clks[ckil] = clk_fixed("ckil", lref);
-	clks[ckih] = clk_fixed("ckih", href);
-	clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
-	clks[mpll_sel] = imx_clk_mux("mpll_sel", base + CCM_CSCR, 16, 1, mpll_sel_clks,
-			ARRAY_SIZE(mpll_sel_clks));
-	clks[spll_sel] = imx_clk_mux("spll_sel", base + CCM_CSCR, 17, 1, spll_sel_clks,
-			ARRAY_SIZE(spll_sel_clks));
-	clks[mpll] = imx_clk_pllv1("mpll", "mpll_sel", base + CCM_MPCTL0);
-	clks[spll] = imx_clk_pllv1("spll", "spll_sel", base + CCM_SPCTL0);
-	clks[fclk] = imx_clk_divider("fclk", "mpll", base + CCM_CSCR, 29, 3);
-	clks[hclk] = imx_clk_divider("hclk", "fclk", base + CCM_CSCR, 10, 4);
-	clks[ipg] = imx_clk_divider("ipg", "hclk", base + CCM_CSCR, 9, 1);
-	clks[per1] = imx_clk_divider("per1", "mpll", base + CCM_PCDR1, 0, 6);
-	clks[per2] = imx_clk_divider("per2", "mpll", base + CCM_PCDR1, 8, 6);
-	clks[per3] = imx_clk_divider("per3", "mpll", base + CCM_PCDR1, 16, 6);
-	clks[per4] = imx_clk_divider("per4", "mpll", base + CCM_PCDR1, 24, 6);
-	clks[usb_div] = imx_clk_divider("usb_div", "spll", base + CCM_CSCR, 26, 3);
-	clks[nfc_div] = imx_clk_divider("nfc_div", "ipg", base + CCM_PCDR0, 12, 4);
-	clks[lcdc_per_gate] = imx_clk_gate("lcdc_per_gate", "per3", base + CCM_PCCR0, 18);
-	clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR0, 26);
-	/*
-	 * i.MX21 doesn't have an IPG clock for the LCD. To avoid even more conditionals
-	 * in the framebuffer code, provide a dummy clock.
-	 */
-	clks[lcdc_ipg_gate] = clk_fixed("dummy", 0);
-
-	clkdev_add_physbase(clks[per1], MX21_GPT1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1], MX21_GPT2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1], MX21_GPT3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1], MX21_UART1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1], MX21_UART2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1], MX21_UART3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1], MX21_UART4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per2], MX21_CSPI1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per2], MX21_CSPI2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per2], MX21_CSPI3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX21_I2C_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX21_SDHC1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX21_SDHC2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[lcdc_per_gate], MX21_LCDC_BASE_ADDR, "per");
-	clkdev_add_physbase(clks[lcdc_ahb_gate], MX21_LCDC_BASE_ADDR, "ahb");
-	clkdev_add_physbase(clks[lcdc_ipg_gate], MX21_LCDC_BASE_ADDR, "ipg");
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx21_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx21-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx21_ccm_driver = {
-	.probe	= imx21_ccm_probe,
-	.name	= "imx21-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx21_ccm_dt_ids),
-};
-
-static int imx21_ccm_init(void)
-{
-	return platform_driver_register(&imx21_ccm_driver);
-}
-core_initcall(imx21_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
deleted file mode 100644
index 864d06e..0000000
--- a/arch/arm/mach-imx/clk-imx25.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2009 by Sascha Hauer, Pengutronix
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx25-regs.h>
-
-#include "clk.h"
-
-#define CCM_MPCTL	0x00
-#define CCM_UPCTL	0x04
-#define CCM_CCTL	0x08
-#define CCM_CGCR0	0x0C
-#define CCM_CGCR1	0x10
-#define CCM_CGCR2	0x14
-#define CCM_PCDR0	0x18
-#define CCM_PCDR1	0x1C
-#define CCM_PCDR2	0x20
-#define CCM_PCDR3	0x24
-#define CCM_RCSR	0x28
-#define CCM_CRDR	0x2C
-#define CCM_DCVR0	0x30
-#define CCM_DCVR1	0x34
-#define CCM_DCVR2	0x38
-#define CCM_DCVR3	0x3c
-#define CCM_LTR0	0x40
-#define CCM_LTR1	0x44
-#define CCM_LTR2	0x48
-#define CCM_LTR3	0x4c
-#define CCM_MCR		0x64
-
-enum mx25_clks {
-	dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg,
-	per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel,
-	per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
-	per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
-	per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
-	csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per,
-	gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per,
-	pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per,
-	uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb,
-	esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb,
-	reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg, csi_ipg,
-	cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg,
-	reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9,
-	gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12,
-	iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg,
-	pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg,
-	sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg,
-	uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17,
-	wdt_ipg, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *cpu_sel_clks[] = {
-	"mpll",
-	"mpll_cpu_3_4",
-};
-
-static const char *per_sel_clks[] = {
-	"ahb",
-	"upll",
-};
-
-static int imx25_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *base;
-
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	base = IOMEM(iores->start);
-
-	writel((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 8) | (1 << 9) |
-			(1 << 10) | (1 << 15) |	(1 << 19) | (1 << 21) | (1 << 22) |
-			(1 << 23) | (1 << 24) | (1 << 28),
-			base + CCM_CGCR0);
-
-	writel((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 13) | (1 << 14) |
-			(1 << 15) | (1 << 19) | (1 << 20) | (1 << 21) | (1 << 22) |
-			(1 << 26) | (1 << 31),
-			base + CCM_CGCR1);
-
-	writel((1 << 0) | (1 << 1) | (1 << 2) | (1 << 10) | (1 << 13) | (1 << 14) |
-			(1 << 15) | (1 << 16) | (1 << 17) | (1 << 18),
-			base + CCM_CGCR2);
-
-	clks[dummy] = clk_fixed("dummy", 0);
-	clks[osc] = clk_fixed("osc", 24000000);
-	clks[mpll] = imx_clk_pllv1("mpll", "osc", base + CCM_MPCTL);
-	clks[upll] = imx_clk_pllv1("upll", "osc", base + CCM_UPCTL);
-	clks[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
-	clks[cpu_sel] = imx_clk_mux("cpu_sel", base + CCM_CCTL, 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
-	clks[cpu] = imx_clk_divider("cpu", "cpu_sel", base + CCM_CCTL, 30, 2);
-	clks[ahb] = imx_clk_divider("ahb", "cpu", base + CCM_CCTL, 28, 2);
-	clks[usb_div] = imx_clk_divider("usb_div", "upll", base + CCM_CCTL, 16, 6);
-	clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
-	clks[per0_sel] = imx_clk_mux("per0_sel", base + CCM_MCR, 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per1_sel] = imx_clk_mux("per1_sel", base + CCM_MCR, 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per2_sel] = imx_clk_mux("per2_sel", base + CCM_MCR, 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per3_sel] = imx_clk_mux("per3_sel", base + CCM_MCR, 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per4_sel] = imx_clk_mux("per4_sel", base + CCM_MCR, 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per5_sel] = imx_clk_mux("per5_sel", base + CCM_MCR, 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per6_sel] = imx_clk_mux("per6_sel", base + CCM_MCR, 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per7_sel] = imx_clk_mux("per7_sel", base + CCM_MCR, 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per8_sel] = imx_clk_mux("per8_sel", base + CCM_MCR, 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per9_sel] = imx_clk_mux("per9_sel", base + CCM_MCR, 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per10_sel] = imx_clk_mux("per10_sel", base + CCM_MCR, 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per11_sel] = imx_clk_mux("per11_sel", base + CCM_MCR, 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per12_sel] = imx_clk_mux("per12_sel", base + CCM_MCR, 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per13_sel] = imx_clk_mux("per13_sel", base + CCM_MCR, 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per14_sel] = imx_clk_mux("per14_sel", base + CCM_MCR, 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per15_sel] = imx_clk_mux("per15_sel", base + CCM_MCR, 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
-	clks[per0] = imx_clk_divider("per0", "per0_sel", base + CCM_PCDR0, 0, 6);
-	clks[per1] = imx_clk_divider("per1", "per1_sel", base + CCM_PCDR0, 8, 6);
-	clks[per2] = imx_clk_divider("per2", "per2_sel", base + CCM_PCDR0, 16, 6);
-	clks[per3] = imx_clk_divider("per3", "per3_sel", base + CCM_PCDR0, 24, 6);
-	clks[per4] = imx_clk_divider("per4", "per4_sel", base + CCM_PCDR1, 0, 6);
-	clks[per5] = imx_clk_divider("per5", "per5_sel", base + CCM_PCDR1, 8, 6);
-	clks[per6] = imx_clk_divider("per6", "per6_sel", base + CCM_PCDR1, 16, 6);
-	clks[per7] = imx_clk_divider("per7", "per7_sel", base + CCM_PCDR1, 24, 6);
-	clks[per8] = imx_clk_divider("per8", "per8_sel", base + CCM_PCDR2, 0, 6);
-	clks[per9] = imx_clk_divider("per9", "per9_sel", base + CCM_PCDR2, 8, 6);
-	clks[per10] = imx_clk_divider("per10", "per10_sel", base + CCM_PCDR2, 16, 6);
-	clks[per11] = imx_clk_divider("per11", "per11_sel", base + CCM_PCDR2, 24, 6);
-	clks[per12] = imx_clk_divider("per12", "per12_sel", base + CCM_PCDR3, 0, 6);
-	clks[per13] = imx_clk_divider("per13", "per13_sel", base + CCM_PCDR3, 8, 6);
-	clks[per14] = imx_clk_divider("per14", "per14_sel", base + CCM_PCDR3, 16, 6);
-	clks[per15] = imx_clk_divider("per15", "per15_sel", base + CCM_PCDR3, 24, 6);
-	clks[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", base + CCM_CGCR0, 24);
-	clks[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", base + CCM_CGCR1, 29);
-	clks[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", base + CCM_CGCR0, 7);
-
-	clkdev_add_physbase(clks[per15], MX25_UART1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per15], MX25_UART2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per15], MX25_UART3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per15], MX25_UART4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per15], MX25_UART5_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per5], MX25_GPT1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per5], MX25_GPT2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per5], MX25_GPT3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per5], MX25_GPT4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX25_FEC_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX25_I2C1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX25_I2C2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX25_I2C3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX25_CSPI1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX25_CSPI2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX25_CSPI3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per3], MX25_ESDHC1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per4], MX25_ESDHC2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per8], MX25_NFC_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[lcdc_ipg_per], MX25_LCDC_BASE_ADDR, "per");
-	clkdev_add_physbase(clks[lcdc_ipg], MX25_LCDC_BASE_ADDR, "ipg");
-	clkdev_add_physbase(clks[lcdc_ahb], MX25_LCDC_BASE_ADDR, "ahb");
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx25_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx25-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx25_ccm_driver = {
-	.probe	= imx25_ccm_probe,
-	.name	= "imx25-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx25_ccm_dt_ids),
-};
-
-static int imx25_ccm_init(void)
-{
-	return platform_driver_register(&imx25_ccm_driver);
-}
-core_initcall(imx25_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
deleted file mode 100644
index 4b63244..0000000
--- a/arch/arm/mach-imx/clk-imx27.c
+++ /dev/null
@@ -1,270 +0,0 @@
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx27-regs.h>
-#include <mach/generic.h>
-#include <mach/revision.h>
-
-#include "clk.h"
-
-/* Register offsets */
-#define CCM_CSCR		0x0
-#define CCM_MPCTL0		0x4
-#define CCM_MPCTL1		0x8
-#define CCM_SPCTL0		0xc
-#define CCM_SPCTL1		0x10
-#define CCM_OSC26MCTL		0x14
-#define CCM_PCDR0		0x18
-#define CCM_PCDR1		0x1c
-#define CCM_PCCR0		0x20
-#define CCM_PCCR1		0x24
-#define CCM_CCSR		0x28
-#define CCM_PMCTL		0x2c
-#define CCM_PMCOUNT		0x30
-#define CCM_WKGDCTL		0x34
-
-#define PCCR0_SSI2_EN	(1 << 0)
-#define PCCR0_SSI1_EN	(1 << 1)
-#define PCCR0_SLCDC_EN	(1 << 2)
-#define PCCR0_SDHC3_EN	(1 << 3)
-#define PCCR0_SDHC2_EN	(1 << 4)
-#define PCCR0_SDHC1_EN	(1 << 5)
-#define PCCR0_SDC_EN	(1 << 6)
-#define PCCR0_SAHARA_EN	(1 << 7)
-#define PCCR0_RTIC_EN	(1 << 8)
-#define PCCR0_RTC_EN	(1 << 9)
-#define PCCR0_PWM_EN	(1 << 11)
-#define PCCR0_OWIRE_EN	(1 << 12)
-#define PCCR0_MSHC_EN	(1 << 13)
-#define PCCR0_LCDC_EN	(1 << 14)
-#define PCCR0_KPP_EN	(1 << 15)
-#define PCCR0_IIM_EN	(1 << 16)
-#define PCCR0_I2C2_EN	(1 << 17)
-#define PCCR0_I2C1_EN	(1 << 18)
-#define PCCR0_GPT6_EN	(1 << 19)
-#define PCCR0_GPT5_EN	(1 << 20)
-#define PCCR0_GPT4_EN	(1 << 21)
-#define PCCR0_GPT3_EN	(1 << 22)
-#define PCCR0_GPT2_EN	(1 << 23)
-#define PCCR0_GPT1_EN	(1 << 24)
-#define PCCR0_GPIO_EN	(1 << 25)
-#define PCCR0_FEC_EN	(1 << 26)
-#define PCCR0_EMMA_EN	(1 << 27)
-#define PCCR0_DMA_EN	(1 << 28)
-#define PCCR0_CSPI3_EN	(1 << 29)
-#define PCCR0_CSPI2_EN	(1 << 30)
-#define PCCR0_CSPI1_EN	(1 << 31)
-
-#define PCCR1_MSHC_BAUDEN	(1 << 2)
-#define PCCR1_NFC_BAUDEN	(1 << 3)
-#define PCCR1_SSI2_BAUDEN	(1 << 4)
-#define PCCR1_SSI1_BAUDEN	(1 << 5)
-#define PCCR1_H264_BAUDEN	(1 << 6)
-#define PCCR1_PERCLK4_EN	(1 << 7)
-#define PCCR1_PERCLK3_EN	(1 << 8)
-#define PCCR1_PERCLK2_EN	(1 << 9)
-#define PCCR1_PERCLK1_EN	(1 << 10)
-#define PCCR1_HCLK_USB		(1 << 11)
-#define PCCR1_HCLK_SLCDC	(1 << 12)
-#define PCCR1_HCLK_SAHARA	(1 << 13)
-#define PCCR1_HCLK_RTIC		(1 << 14)
-#define PCCR1_HCLK_LCDC		(1 << 15)
-#define PCCR1_HCLK_H264		(1 << 16)
-#define PCCR1_HCLK_FEC		(1 << 17)
-#define PCCR1_HCLK_EMMA		(1 << 18)
-#define PCCR1_HCLK_EMI		(1 << 19)
-#define PCCR1_HCLK_DMA		(1 << 20)
-#define PCCR1_HCLK_CSI		(1 << 21)
-#define PCCR1_HCLK_BROM		(1 << 22)
-#define PCCR1_HCLK_ATA		(1 << 23)
-#define PCCR1_WDT_EN		(1 << 24)
-#define PCCR1_USB_EN		(1 << 25)
-#define PCCR1_UART6_EN		(1 << 26)
-#define PCCR1_UART5_EN		(1 << 27)
-#define PCCR1_UART4_EN		(1 << 28)
-#define PCCR1_UART3_EN		(1 << 29)
-#define PCCR1_UART2_EN		(1 << 30)
-#define PCCR1_UART1_EN		(1 << 31)
-
-enum mx27_clks {
-	dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div,
-	per2_div, per3_div, per4_div, vpu_sel, vpu_div, usb_div, cpu_sel,
-	clko_sel, cpu_div, clko_div, ssi1_sel, ssi2_sel, ssi1_div, ssi2_div,
-	clko_en, ssi2_ipg_gate, ssi1_ipg_gate, slcdc_ipg_gate, sdhc3_ipg_gate,
-	sdhc2_ipg_gate, sdhc1_ipg_gate, scc_ipg_gate, sahara_ipg_gate,
-	rtc_ipg_gate, pwm_ipg_gate, owire_ipg_gate, lcdc_ipg_gate,
-	kpp_ipg_gate, iim_ipg_gate, i2c2_ipg_gate, i2c1_ipg_gate,
-	gpt6_ipg_gate, gpt5_ipg_gate, gpt4_ipg_gate, gpt3_ipg_gate,
-	gpt2_ipg_gate, gpt1_ipg_gate, gpio_ipg_gate, fec_ipg_gate,
-	emma_ipg_gate, dma_ipg_gate, cspi3_ipg_gate, cspi2_ipg_gate,
-	cspi1_ipg_gate, nfc_baud_gate, ssi2_baud_gate, ssi1_baud_gate,
-	vpu_baud_gate, per4_gate, per3_gate, per2_gate, per1_gate,
-	usb_ahb_gate, slcdc_ahb_gate, sahara_ahb_gate, lcdc_ahb_gate,
-	vpu_ahb_gate, fec_ahb_gate, emma_ahb_gate, emi_ahb_gate, dma_ahb_gate,
-	csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
-	uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
-	uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel,
-	mpll_sel, spll_gate, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *cpu_sel_clks[] = {
-	"mpll_main2",
-	"mpll",
-};
-
-static const char *mpll_sel_clks[] = {
-	"fpm",
-	"mpll_osc_sel",
-};
-
-static const char *mpll_osc_sel_clks[] = {
-	"ckih",
-	"ckih_div1p5",
-};
-
-static const char *clko_sel_clks[] = {
-	"ckil",
-	NULL,
-	"ckih",
-	"ckih",
-	"ckih",
-	"mpll",
-	"spll",
-	"cpu_div",
-	"ahb",
-	"ipg",
-	"per1_div",
-	"per2_div",
-	"per3_div",
-	"per4_div",
-	NULL,
-	NULL,
-	"nfc_div",
-	NULL,
-	NULL,
-	NULL,
-	"ckil",
-	"usb_div",
-	NULL,
-};
-
-static int imx27_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *base;
-
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	base = IOMEM(iores->start);
-
-	writel(PCCR0_SDHC3_EN | PCCR0_SDHC2_EN | PCCR0_SDHC1_EN |
-			PCCR0_PWM_EN | PCCR0_KPP_EN | PCCR0_IIM_EN |
-			PCCR0_I2C2_EN | PCCR0_I2C1_EN | PCCR0_GPT6_EN | PCCR0_GPT5_EN |
-			PCCR0_GPT4_EN | PCCR0_GPT3_EN | PCCR0_GPT2_EN | PCCR0_GPT1_EN |
-			PCCR0_GPIO_EN | PCCR0_FEC_EN | PCCR0_CSPI3_EN | PCCR0_CSPI2_EN |
-			PCCR0_CSPI1_EN,
-			base + CCM_PCCR0);
-
-	writel(PCCR1_NFC_BAUDEN | PCCR1_PERCLK4_EN | PCCR1_PERCLK2_EN | PCCR1_PERCLK1_EN |
-			PCCR1_HCLK_USB | PCCR1_HCLK_FEC | PCCR1_HCLK_EMI | PCCR1_WDT_EN |
-			PCCR1_USB_EN | PCCR1_UART6_EN | PCCR1_UART5_EN | PCCR1_UART4_EN |
-			PCCR1_UART3_EN | PCCR1_UART2_EN | PCCR1_UART1_EN,
-			base + CCM_PCCR1);
-
-	clks[dummy] = clk_fixed("dummy", 0);
-	clks[ckih] = clk_fixed("ckih", 26000000);
-	clks[ckil] = clk_fixed("ckil", 32768);
-	clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 1024, 1);
-	clks[ckih_div1p5] = imx_clk_fixed_factor("ckih_div1p5", "ckih", 2, 3);
-
-	clks[mpll_osc_sel] = imx_clk_mux("mpll_osc_sel", base + CCM_CSCR, 4, 1,
-			mpll_osc_sel_clks,
-			ARRAY_SIZE(mpll_osc_sel_clks));
-	clks[mpll_sel] = imx_clk_mux("mpll_sel", base + CCM_CSCR, 16, 1, mpll_sel_clks,
-			ARRAY_SIZE(mpll_sel_clks));
-
-	clks[mpll] = imx_clk_pllv1("mpll", "mpll_sel", base + CCM_MPCTL0);
-	clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SPCTL0);
-	clks[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
-
-	if (imx_silicon_revision() >= IMX_CHIP_REV_2_0) {
-		clks[ahb] = imx_clk_divider("ahb", "mpll_main2", base + CCM_CSCR, 8, 2);
-		clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
-	} else {
-		clks[ahb] = imx_clk_divider("ahb", "mpll_main2", base + CCM_CSCR, 9, 4);
-		clks[ipg] = imx_clk_divider("ipg", "ahb", base + CCM_CSCR, 8, 1);
-	}
-
-	clks[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + CCM_PCDR0, 6, 4);
-	clks[per1_div] = imx_clk_divider("per1_div", "mpll_main2", base + CCM_PCDR1, 0, 6);
-	clks[per2_div] = imx_clk_divider("per2_div", "mpll_main2", base + CCM_PCDR1, 8, 6);
-	clks[per3_div] = imx_clk_divider("per3_div", "mpll_main2", base + CCM_PCDR1, 16, 6);
-	clks[per4_div] = imx_clk_divider("per4_div", "mpll_main2", base + CCM_PCDR1, 24, 6);
-	clks[usb_div] = imx_clk_divider("usb_div", "spll", base + CCM_CSCR, 28, 3);
-	clks[cpu_sel] = imx_clk_mux("cpu_sel", base + CCM_CSCR, 15, 1, cpu_sel_clks,
-			ARRAY_SIZE(cpu_sel_clks));
-	clks[clko_sel] = imx_clk_mux("clko_sel", base + CCM_CCSR, 0, 5, clko_sel_clks,
-			ARRAY_SIZE(clko_sel_clks));
-	if (imx_silicon_revision() >= IMX_CHIP_REV_2_0)
-		clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 12, 2);
-	else
-		clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 13, 3);
-	clks[clko_div] = imx_clk_divider("clko_div", "clko_sel", base + CCM_PCDR0, 22, 3);
-	clks[per3_gate] = imx_clk_gate("per3_gate", "per3_div", base + CCM_PCCR1, 8);
-	clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR1, 15);
-	clks[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", base + CCM_PCCR0, 14);
-
-	clkdev_add_physbase(clks[per1_div], MX27_GPT1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_GPT2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_GPT3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_GPT4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_GPT5_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_GPT6_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_UART1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_UART2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_UART3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_UART4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_UART5_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per1_div], MX27_UART6_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX27_CSPI1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX27_CSPI2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX27_CSPI3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX27_I2C1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX27_I2C2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per2_div], MX27_SDHC1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per2_div], MX27_SDHC2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per2_div], MX27_SDHC3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per3_gate], MX27_LCDC_BASE_ADDR, "per");
-	clkdev_add_physbase(clks[lcdc_ahb_gate], MX27_LCDC_BASE_ADDR, "ahb");
-	clkdev_add_physbase(clks[lcdc_ipg_gate], MX27_LCDC_BASE_ADDR, "ipg");
-	clkdev_add_physbase(clks[ipg], MX27_FEC_BASE_ADDR, NULL);
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx27_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx27-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx27_ccm_driver = {
-	.probe	= imx27_ccm_probe,
-	.name	= "imx27-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx27_ccm_dt_ids),
-};
-
-static int imx27_ccm_init(void)
-{
-	return platform_driver_register(&imx27_ccm_driver);
-}
-core_initcall(imx27_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
deleted file mode 100644
index 8d135c9..0000000
--- a/arch/arm/mach-imx/clk-imx31.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation.
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx31-regs.h>
-
-#include "clk.h"
-
-/* Register addresses */
-#define CCM_CCMR		0x00
-#define CCM_PDR0		0x04
-#define CCM_PDR1		0x08
-//#define CCM_RCSR		0x0C
-#define CCM_MPCTL		0x10
-#define CCM_UPCTL		0x14
-#define CCM_SRPCTL		0x18
-#define CCM_COSR		0x1C
-#define CCM_CGR0		0x20
-#define CCM_CGR1		0x24
-#define CCM_CGR2		0x28
-#define CCM_WIMR		0x2C
-#define CCM_LDC		0x30
-#define CCM_DCVR0		0x34
-#define CCM_DCVR1		0x38
-#define CCM_DCVR2		0x3C
-#define CCM_DCVR3		0x40
-#define CCM_LTR0		0x44
-#define CCM_LTR1		0x48
-#define CCM_LTR2		0x4C
-#define CCM_LTR3		0x50
-#define CCM_LTBR0		0x54
-#define CCM_LTBR1		0x58
-#define CCM_PMCR0		0x5C
-#define CCM_PMCR1		0x60
-#define CCM_PDR2		0x64
-
-enum mx31_clks {
-	ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div,
-	per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
-	fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
-	iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
-	uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
-	mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
-	sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
-	uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
-	gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *mcu_main_sel[] = {
-	"spll",
-	"mpll",
-};
-
-static const char *per_sel[] = {
-	"per_div",
-	"ipg",
-};
-
-static int imx31_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *base;
-
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	base = IOMEM(iores->start);
-
-	writel(0xffffffff, base + CCM_CGR0);
-	writel(0xffffffff, base + CCM_CGR1);
-	writel(0xffffffff, base + CCM_CGR2);
-
-	clks[ckih] = clk_fixed("ckih", 26000000);
-	clks[ckil] = clk_fixed("ckil", 32768);
-	clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL);
-	clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SRPCTL);
-	clks[upll] = imx_clk_pllv1("upll", "ckih", base + CCM_UPCTL);
-	clks[mcu_main] = imx_clk_mux("mcu_main", base + CCM_PMCR0, 31, 1,
-			mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
-	clks[hsp] = imx_clk_divider("hsp", "mcu_main", base + CCM_PDR0, 11, 3);
-	clks[ahb] = imx_clk_divider("ahb", "mcu_main", base + CCM_PDR0, 3, 3);
-	clks[nfc] = imx_clk_divider("nfc", "ahb", base + CCM_PDR0, 8, 3);
-	clks[ipg] = imx_clk_divider("ipg", "ahb", base + CCM_PDR0, 6, 2);
-	clks[per_div] = imx_clk_divider("per_div", "upll", base + CCM_PDR0, 16, 5);
-	clks[per] = imx_clk_mux("per", base + CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
-
-	clkdev_add_physbase(clks[per], MX31_UART1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_UART2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_UART3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_UART4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_UART5_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_I2C1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_I2C2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_I2C3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX31_CSPI1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX31_CSPI2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX31_CSPI3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_SDHC1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_SDHC2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[per], MX31_GPT1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[hsp], MX31_IPU_CTRL_BASE_ADDR, NULL);
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx31_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx31-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx31_ccm_driver = {
-	.probe	= imx31_ccm_probe,
-	.name	= "imx31-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx31_ccm_dt_ids),
-};
-
-static int imx31_ccm_init(void)
-{
-	return platform_driver_register(&imx31_ccm_driver);
-}
-core_initcall(imx31_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
deleted file mode 100644
index af6c405..0000000
--- a/arch/arm/mach-imx/clk-imx35.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx35-regs.h>
-#include <reset_source.h>
-
-#include "clk.h"
-
-#define CCM_CCMR	0x00
-#define CCM_PDR0	0x04
-#define CCM_PDR1	0x08
-#define CCM_PDR2	0x0C
-#define CCM_PDR3	0x10
-#define CCM_PDR4	0x14
-#define CCM_RCSR	0x18
-#define CCM_MPCTL	0x1C
-#define CCM_PPCTL	0x20
-#define CCM_ACMR	0x24
-#define CCM_COSR	0x28
-#define CCM_CGR0	0x2C
-#define CCM_CGR1	0x30
-#define CCM_CGR2	0x34
-#define CCM_CGR3	0x38
-
-struct arm_ahb_div {
-	unsigned char arm, ahb, sel;
-};
-
-static struct arm_ahb_div clk_consumer[] = {
-	{ .arm = 1, .ahb = 4, .sel = 0},
-	{ .arm = 1, .ahb = 3, .sel = 1},
-	{ .arm = 2, .ahb = 2, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 4, .ahb = 1, .sel = 0},
-	{ .arm = 1, .ahb = 5, .sel = 0},
-	{ .arm = 1, .ahb = 8, .sel = 0},
-	{ .arm = 1, .ahb = 6, .sel = 1},
-	{ .arm = 2, .ahb = 4, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 4, .ahb = 2, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-};
-
-static char hsp_div_532[] = { 4, 8, 3, 0 };
-static char hsp_div_400[] = { 3, 6, 3, 0 };
-
-enum mx35_clks {
-	ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
-	arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
-	esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
-	spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
-	ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate,
-	audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate,
-	edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
-	esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate,
-	gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate,
-	kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
-	rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
-	ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
-	wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate,
-	clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *std_sel[] = {
-	"ppll",
-	"arm",
-};
-
-static const char *ipg_per_sel[] = {
-	"ahb_per_div",
-	"arm_per_div",
-};
-
-static int imx35_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	u32 pdr0, consumer_sel, hsp_sel;
-	struct arm_ahb_div *aad;
-	unsigned char *hsp_div;
-	void __iomem *base;
-	u32 reg;
-
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	base = IOMEM(iores->start);
-
-	/* Check reset source */
-	reg = readl(base + CCM_RCSR);
-
-	switch (reg & 0x0F) {
-	case 0x00:
-		reset_source_set_priority(RESET_POR, 200);
-		break;
-	case 0x02:
-		reset_source_set_priority(RESET_JTAG, 200);
-		break;
-	case 0x04:
-		reset_source_set_priority(RESET_RST, 200);
-		break;
-	case 0x08:
-		reset_source_set_priority(RESET_WDG, 200);
-		break;
-	}
-
-	writel(0xffffffff, base + CCM_CGR0);
-	writel(0xffffffff, base + CCM_CGR1);
-	writel(0xfbffffff, base + CCM_CGR2);
-	writel(0xffffffff, base + CCM_CGR3);
-
-	pdr0 = __raw_readl(base + CCM_PDR0);
-	consumer_sel = (pdr0 >> 16) & 0xf;
-	aad = &clk_consumer[consumer_sel];
-	if (!aad->arm) {
-		pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
-		/*
-		 * We are basically stuck. Continue with a default entry and hope we
-		 * get far enough to actually show the above message
-		 */
-		aad = &clk_consumer[0];
-	}
-
-	clks[ckih] = clk_fixed("ckih", 24000000);
-	clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL);
-	clks[ppll] = imx_clk_pllv1("ppll", "ckih", base + CCM_PPCTL);
-
-	clks[mpll_075] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
-
-	if (aad->sel)
-		clks[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
-	else
-		clks[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
-
-	if (clk_get_rate(clks[arm]) > 400000000)
-		hsp_div = hsp_div_532;
-	else
-		hsp_div = hsp_div_400;
-
-	hsp_sel = (pdr0 >> 20) & 0x3;
-	if (!hsp_div[hsp_sel]) {
-		pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
-		hsp_sel = 0;
-	}
-
-	clks[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
-
-	clks[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
-	clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
-
-	clks[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + CCM_PDR4, 16, 6);
-	clks[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + CCM_PDR0, 12, 3);
-	clks[ipg_per] = imx_clk_mux("ipg_per", base + CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
-
-	clks[uart_sel] = imx_clk_mux("uart_sel", base + CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
-	clks[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + CCM_PDR4, 10, 6);
-
-	clks[esdhc_sel] = imx_clk_mux("esdhc_sel", base + CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
-	clks[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + CCM_PDR3, 0, 6);
-	clks[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + CCM_PDR3, 8, 6);
-	clks[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + CCM_PDR3, 16, 6);
-
-	clks[usb_sel] = imx_clk_mux("usb_sel", base + CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
-	clks[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + CCM_PDR4, 22, 6);
-
-	clkdev_add_physbase(clks[uart_div], MX35_UART1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[uart_div], MX35_UART2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[uart_div], MX35_UART3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg_per], MX35_I2C1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg_per], MX35_I2C2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg_per], MX35_I2C3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX35_CSPI1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX35_CSPI2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX35_FEC_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[ipg], MX35_GPT1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[esdhc1_div], MX35_ESDHC1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[esdhc2_div], MX35_ESDHC2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[esdhc3_div], MX35_ESDHC3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[hsp], MX35_IPU_CTRL_BASE_ADDR, NULL);
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx35_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx35-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx35_ccm_driver = {
-	.probe	= imx35_ccm_probe,
-	.name	= "imx35-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx35_ccm_dt_ids),
-};
-
-static int imx35_ccm_init(void)
-{
-	return platform_driver_register(&imx35_ccm_driver);
-}
-core_initcall(imx35_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx5.c b/arch/arm/mach-imx/clk-imx5.c
deleted file mode 100644
index c4c47a6..0000000
--- a/arch/arm/mach-imx/clk-imx5.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <of.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx50-regs.h>
-#include <mach/imx51-regs.h>
-#include <mach/imx53-regs.h>
-#include <dt-bindings/clock/imx5-clock.h>
-
-#include "clk.h"
-
-/* Register addresses of CCM*/
-#define CCM_CCR		0x00
-#define CCM_CCDR	0x04
-#define CCM_CSR		0x08
-#define CCM_CCSR	0x0C
-#define CCM_CACRR	0x10
-#define CCM_CBCDR	0x14
-#define CCM_CBCMR	0x18
-#define CCM_CSCMR1	0x1C
-#define CCM_CSCMR2	0x20
-#define CCM_CSCDR1	0x24
-#define CCM_CS1CDR	0x28
-#define CCM_CS2CDR	0x2C
-#define CCM_CDCDR	0x30
-#define CCM_CHSCDR	0x34
-#define CCM_CSCDR2	0x38
-#define CCM_CSCDR3	0x3C
-#define CCM_CSCDR4	0x40
-#define CCM_CWDR	0x44
-#define CCM_CDHIPR	0x48
-#define CCM_CDCR	0x4C
-#define CCM_CTOR	0x50
-#define CCM_CLPCR	0x54
-#define CCM_CISR	0x58
-#define CCM_CIMR	0x5C
-#define CCM_CCOSR	0x60
-#define CCM_CGPR	0x64
-#define CCM_CCGR0	0x68
-#define CCM_CCGR1	0x6C
-#define CCM_CCGR2	0x70
-#define CCM_CCGR3	0x74
-#define CCM_CCGR4	0x78
-#define CCM_CCGR5	0x7C
-#define CCM_CCGR6	0x80
-#define CCM_CCGR7	0x84
-
-#define CCM_CMEOR	0x84
-
-static struct clk *clks[IMX5_CLK_END];
-
-/* This is used multiple times */
-static const char *standard_pll_sel[] = {
-	"pll1_sw",
-	"pll2_sw",
-	"pll3_sw",
-	"lp_apm",
-};
-
-static const char *mx50_3bit_clk_sel[] = {
-	"pll1_sw",
-	"pll2_sw",
-	"pll3_sw",
-	"lp_apm",
-	"pfd0",
-	"pfd1",
-	"pfd4",
-	"osc",
-};
-
-static const char *lp_apm_sel[] = {
-	"osc",
-};
-
-static const char *periph_apm_sel[] = {
-	"pll1_sw",
-	"pll3_sw",
-	"lp_apm",
-};
-
-static const char *main_bus_sel[] = {
-	"pll2_sw",
-	"periph_apm",
-};
-
-static const char *mx50_periph_clk_sel[] = {
-	"pll1_sw",
-	"pll2_sw",
-	"pll3_sw",
-	"lp_apm",
-};
-
-static const char *per_lp_apm_sel[] = {
-	"main_bus",
-	"lp_apm",
-};
-
-static const char *per_root_sel[] = {
-	"per_podf",
-	"ipg",
-};
-
-static const char *esdhc_c_sel[] = {
-	"esdhc_a_podf",
-	"esdhc_b_podf",
-};
-
-static const char *esdhc_d_sel[] = {
-	"esdhc_a_podf",
-	"esdhc_b_podf",
-};
-
-static const char *emi_slow_sel[] = {
-	"main_bus",
-	"ahb",
-};
-
-static const char *usb_phy_sel_str[] = {
-	"osc",
-	"usb_phy_podf",
-};
-
-static const char *mx51_ipu_di0_sel[] = {
-	"di_pred",
-	"osc",
-	"ckih1",
-	"tve_di",
-};
-
-static const char *mx53_ipu_di0_sel[] = {
-	"di_pred",
-	"osc",
-	"ckih1",
-	"di_pll4_podf",
-	"dummy",
-	"ldb_di0_div",
-};
-
-static const char *mx53_ldb_di0_sel[] = {
-	"pll3_sw",
-	"pll4_sw",
-};
-
-static const char *mx51_ipu_di1_sel[] = {
-	"di_pred",
-	"osc",
-	"ckih1",
-	"tve_di",
-	"ipp_di1",
-};
-
-static const char *mx53_ipu_di1_sel[] = {
-	"di_pred",
-	"osc",
-	"ckih1",
-	"tve_di",
-	"ipp_di1",
-	"ldb_di1_div",
-};
-
-static const char *mx53_ldb_di1_sel[] = {
-	"pll3_sw",
-	"pll4_sw",
-};
-
-static const char *mx51_tve_ext_sel[] = {
-	"osc",
-	"ckih1",
-};
-
-static const char *mx53_tve_ext_sel[] = {
-	"pll4_sw",
-	"ckih1",
-};
-
-static const char *mx51_tve_sel[] = {
-	"tve_pred",
-	"tve_ext_sel",
-};
-
-static const char *ipu_sel[] = {
-	"axi_a",
-	"axi_b",
-	"emi_slow_gate",
-	"ahb",
-};
-
-static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *base)
-{
-	writel(0xffffffff, base + CCM_CCGR0);
-	writel(0xffffffff, base + CCM_CCGR1);
-	writel(0xffffffff, base + CCM_CCGR2);
-	writel(0xffffffff, base + CCM_CCGR3);
-	writel(0xffffffff, base + CCM_CCGR4);
-	writel(0xffffffff, base + CCM_CCGR5);
-	writel(0xffffffff, base + CCM_CCGR6);
-	writel(0xffffffff, base + CCM_CCGR7);
-
-	if (!IS_ENABLED(CONFIG_COMMON_CLK_OF_PROVIDER) || !dev->device_node) {
-		clks[IMX5_CLK_CKIL] = clk_fixed("ckil", 32768);
-		clks[IMX5_CLK_OSC] = clk_fixed("osc", 24000000);
-	}
-
-	clks[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", base + CCM_CBCMR, 1, 1,
-				per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
-	clks[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", base + CCM_CBCDR, 6, 2);
-	clks[IMX5_CLK_PER_PRED2] = imx_clk_divider("per_pred2", "per_pred1", base + CCM_CBCDR, 3, 3);
-	clks[IMX5_CLK_PER_PODF] = imx_clk_divider("per_podf", "per_pred2", base + CCM_CBCDR, 0, 3);
-	clks[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", base + CCM_CBCMR, 0, 1,
-				per_root_sel, ARRAY_SIZE(per_root_sel));
-	clks[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", base + CCM_CBCDR, 10, 3);
-	clks[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + CCM_CBCDR, 8, 2);
-	clks[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", base + CCM_CBCDR, 16, 3);
-	clks[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", base + CCM_CBCDR, 19, 3);
-	clks[IMX5_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + CCM_CSCMR1, 24, 2,
-				standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-	clks[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", base + CCM_CSCDR1, 3, 3);
-	clks[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", base + CCM_CSCDR1, 0, 3);
-	clks[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred",
-		"esdhc_a_sel", base + CCM_CSCDR1, 16, 3);
-	clks[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf",
-		"esdhc_a_pred", base + CCM_CSCDR1, 11, 3);
-	clks[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred",
-		"esdhc_b_sel", base + CCM_CSCDR1, 22, 3);
-	clks[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf",
-		"esdhc_b_pred", base + CCM_CSCDR1, 19, 3);
-	clks[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + CCM_CSCMR1,
-		4, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-	clks[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred",
-		"ecspi_sel", base + CCM_CSCDR2, 25, 3);
-	clks[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf",
-		"ecspi_pred", base + CCM_CSCDR2, 19, 6);
-	clks[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf",
-		"pll1_sw", base + CCM_CACRR, 0, 3);
-}
-
-static void mx5_clocks_mx51_mx53_init(void __iomem *base)
-{
-	clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", base + CCM_CCSR, 9, 1,
-				lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
-	clks[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", base + CCM_CBCMR, 12, 2,
-				periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
-	clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", base + CCM_CBCDR, 25, 1,
-				main_bus_sel, ARRAY_SIZE(main_bus_sel));
-	clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", base + CCM_CSCMR1, 20, 2,
-				standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-	clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", base + CCM_CSCMR1, 16, 2,
-				standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-	clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", base + CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
-	clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", base + CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
-	clks[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", base + CCM_CBCDR, 26, 1,
-				emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
-	clks[IMX5_CLK_EMI_SLOW_PODF] = imx_clk_divider("emi_slow_podf", "emi_sel", base + CCM_CBCDR, 22, 3);
-	clks[IMX5_CLK_NFC_PODF] = imx_clk_divider("nfc_podf", "emi_slow_podf", base + CCM_CBCDR, 13, 3);
-	clks[IMX5_CLK_USBOH3_SEL] = imx_clk_mux("usboh3_sel", base + CCM_CSCMR1, 22, 2,
-				standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-	clks[IMX5_CLK_USBOH3_PRED] = imx_clk_divider("usboh3_pred", "usboh3_sel", base + CCM_CSCDR1, 8, 3);
-	clks[IMX5_CLK_USBOH3_PODF] = imx_clk_divider("usboh3_podf", "usboh3_pred", base + CCM_CSCDR1, 6, 2);
-	clks[IMX5_CLK_USB_PHY_PRED] = imx_clk_divider("usb_phy_pred", "pll3_sw", base + CCM_CDCDR, 3, 3);
-	clks[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", base + CCM_CDCDR, 0, 3);
-	clks[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", base + CCM_CSCMR1, 26, 1,
-				usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
-}
-
-static void mx5_clocks_ipu_init(void __iomem *regs)
-{
-	clks[IMX5_CLK_IPU_SEL]		= imx_clk_mux("ipu_sel", regs + CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
-}
-
-int __init mx50_clocks_init(struct device_d *dev, void __iomem *regs)
-{
-	clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc",
-					       (void *)MX50_PLL1_BASE_ADDR);
-	clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc",
-					       (void *)MX50_PLL2_BASE_ADDR);
-	clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc",
-					       (void *)MX50_PLL3_BASE_ADDR);
-
-	mx5_clocks_common_init(dev, regs);
-
-	clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", regs + CCM_CCSR, 10, 1, lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
-	clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", regs + CCM_CBCDR, 25, 2, mx50_periph_clk_sel, ARRAY_SIZE(mx50_periph_clk_sel));
-	clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", regs + CCM_CSCMR1, 21, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-	clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", regs + CCM_CSCMR1, 16, 3, mx50_3bit_clk_sel, ARRAY_SIZE(mx50_3bit_clk_sel));
-	clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", regs + CCM_CSCMR1, 20, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
-	clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", regs + CCM_CSCMR1, 19, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_GPT1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_CSPI_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_FEC_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX50_ESDHC1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX50_ESDHC2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX50_ESDHC3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX50_ESDHC4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM1_BASE_ADDR, "per");
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM2_BASE_ADDR, "per");
-
-	return 0;
-}
-
-static int imx50_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *regs;
-
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	regs = IOMEM(iores->start);
-
-	mx50_clocks_init(dev, regs);
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx50_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx50-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx50_ccm_driver = {
-	.probe	= imx50_ccm_probe,
-	.name	= "imx50-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx50_ccm_dt_ids),
-};
-
-static void mx51_clocks_ipu_init(void __iomem *regs)
-{
-	clks[IMX5_CLK_IPU_DI0_SEL]	= imx_clk_mux_p("ipu_di0_sel", regs + CCM_CSCMR2, 26, 3,
-						mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
-	clks[IMX5_CLK_IPU_DI1_SEL]	= imx_clk_mux_p("ipu_di1_sel", regs + CCM_CSCMR2, 29, 3,
-						mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
-	clks[IMX5_CLK_TVE_EXT_SEL]	= imx_clk_mux_p("tve_ext_sel", regs + CCM_CSCMR1, 6, 1,
-						mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel));
-	clks[IMX5_CLK_TVE_SEL]		= imx_clk_mux("tve_sel", regs + CCM_CSCMR1, 7, 1,
-						mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
-	clks[IMX5_CLK_TVE_PRED]		= imx_clk_divider("tve_pred", "pll3_sw", regs + CCM_CDCDR, 28, 3);
-
-	mx5_clocks_ipu_init(regs);
-
-	clkdev_add_physbase(clks[IMX5_CLK_IPU_SEL], MX51_IPU_BASE_ADDR, "bus");
-	clkdev_add_physbase(clks[IMX5_CLK_IPU_DI0_SEL], MX51_IPU_BASE_ADDR, "di0");
-	clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX51_IPU_BASE_ADDR, "di1");
-}
-
-int __init mx51_clocks_init(struct device_d *dev, void __iomem *regs)
-{
-	clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX51_PLL1_BASE_ADDR);
-	clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX51_PLL2_BASE_ADDR);
-	clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", (void *)MX51_PLL3_BASE_ADDR);
-
-	mx5_clocks_common_init(dev, regs);
-	mx5_clocks_mx51_mx53_init(regs);
-
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_I2C1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_I2C2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_GPT1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_CSPI_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX51_ECSPI1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX51_ECSPI2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_MXC_FEC_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX51_MMC_SDHC1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX51_MMC_SDHC2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX51_MMC_SDHC3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX51_MMC_SDHC4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_ATA_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM1_BASE_ADDR, "per");
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM2_BASE_ADDR, "per");
-
-	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
-		mx51_clocks_ipu_init(regs);
-
-	return 0;
-}
-
-static int imx51_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *regs;
-
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	regs = IOMEM(iores->start);
-
-	mx51_clocks_init(dev, regs);
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx51_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx51-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx51_ccm_driver = {
-	.probe	= imx51_ccm_probe,
-	.name	= "imx51-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx51_ccm_dt_ids),
-};
-
-static void mx53_clocks_ipu_init(void __iomem *regs)
-{
-	clks[IMX5_CLK_LDB_DI1_DIV_3_5]	= imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
-	clks[IMX5_CLK_LDB_DI1_DIV]	= imx_clk_divider_np("ldb_di1_div", "ldb_di1_div_3_5", regs + CCM_CSCMR2, 11, 1);
-	clks[IMX5_CLK_LDB_DI1_SEL]	= imx_clk_mux_p("ldb_di1_sel", regs + CCM_CSCMR2, 9, 1,
-						mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
-	clks[IMX5_CLK_DI_PLL4_PODF]	= imx_clk_divider("di_pll4_podf", "pll4_sw", regs + CCM_CDCDR, 16, 3);
-	clks[IMX5_CLK_LDB_DI0_DIV_3_5]	= imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
-	clks[IMX5_CLK_LDB_DI0_DIV]	= imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", regs + CCM_CSCMR2, 10, 1);
-	clks[IMX5_CLK_LDB_DI0_SEL]	= imx_clk_mux_p("ldb_di0_sel", regs + CCM_CSCMR2, 8, 1,
-						mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
-	clks[IMX5_CLK_IPU_DI0_SEL]	= imx_clk_mux_p("ipu_di0_sel", regs + CCM_CSCMR2, 26, 3,
-						mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
-	clks[IMX5_CLK_IPU_DI1_SEL]	= imx_clk_mux_p("ipu_di1_sel", regs + CCM_CSCMR2, 29, 3,
-						mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
-	clks[IMX5_CLK_TVE_EXT_SEL]	= imx_clk_mux_p("tve_ext_sel", regs + CCM_CSCMR1, 6, 1,
-						mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel));
-	clks[IMX5_CLK_TVE_PRED]		= imx_clk_divider("tve_pred", "tve_ext_sel", regs + CCM_CDCDR, 28, 3);
-
-	mx5_clocks_ipu_init(regs);
-
-	clkdev_add_physbase(clks[IMX5_CLK_IPU_SEL], MX53_IPU_BASE_ADDR, "bus");
-	clkdev_add_physbase(clks[IMX5_CLK_IPU_DI0_SEL], MX53_IPU_BASE_ADDR, "di0");
-	clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX53_IPU_BASE_ADDR, "di1");
-}
-
-int __init mx53_clocks_init(struct device_d *dev, void __iomem *regs)
-{
-	clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX53_PLL1_BASE_ADDR);
-	clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX53_PLL2_BASE_ADDR);
-	clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", (void *)MX53_PLL3_BASE_ADDR);
-	clks[IMX5_CLK_PLL4_SW] = imx_clk_pllv2("pll4_sw", "osc", (void *)MX53_PLL4_BASE_ADDR);
-
-	mx5_clocks_common_init(dev, regs);
-	mx5_clocks_mx51_mx53_init(regs);
-
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART5_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_GPT1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX53_CSPI_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX53_ECSPI1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX53_ECSPI2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX53_FEC_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX53_ESDHC1_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX53_ESDHC2_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX53_ESDHC3_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX53_ESDHC4_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_AHB], MX53_SATA_BASE_ADDR, NULL);
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM1_BASE_ADDR, "per");
-	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM2_BASE_ADDR, "per");
-
-	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
-		mx53_clocks_ipu_init(regs);
-
-	return 0;
-}
-
-static int imx53_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *regs;
-
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	regs = IOMEM(iores->start);
-
-	mx53_clocks_init(dev, regs);
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx53_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx53-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx53_ccm_driver = {
-	.probe	= imx53_ccm_probe,
-	.name	= "imx53-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx53_ccm_dt_ids),
-};
-
-static int imx5_ccm_init(void)
-{
-	if (IS_ENABLED(CONFIG_ARCH_IMX50))
-		platform_driver_register(&imx50_ccm_driver);
-	if (IS_ENABLED(CONFIG_ARCH_IMX51))
-		platform_driver_register(&imx51_ccm_driver);
-	if (IS_ENABLED(CONFIG_ARCH_IMX53))
-		platform_driver_register(&imx53_ccm_driver);
-
-	return 0;
-}
-core_initcall(imx5_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx6.c b/arch/arm/mach-imx/clk-imx6.c
deleted file mode 100644
index 8ac43be..0000000
--- a/arch/arm/mach-imx/clk-imx6.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc.
- * Copyright 2011 Linaro Ltd.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <of.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx6-regs.h>
-#include <mach/revision.h>
-#include <mach/imx6.h>
-#include <dt-bindings/clock/imx6qdl-clock.h>
-
-#include "clk.h"
-
-#define CCGR0				0x68
-#define CCGR1				0x6c
-#define CCGR2				0x70
-#define CCGR3				0x74
-#define CCGR4				0x78
-#define CCGR5				0x7c
-#define CCGR6				0x80
-#define CCGR7				0x84
-
-#define CLPCR				0x54
-#define BP_CLPCR_LPM			0
-#define BM_CLPCR_LPM			(0x3 << 0)
-#define BM_CLPCR_BYPASS_PMIC_READY	(0x1 << 2)
-#define BM_CLPCR_ARM_CLK_DIS_ON_LPM	(0x1 << 5)
-#define BM_CLPCR_SBYOS			(0x1 << 6)
-#define BM_CLPCR_DIS_REF_OSC		(0x1 << 7)
-#define BM_CLPCR_VSTBY			(0x1 << 8)
-#define BP_CLPCR_STBY_COUNT		9
-#define BM_CLPCR_STBY_COUNT		(0x3 << 9)
-#define BM_CLPCR_COSC_PWRDOWN		(0x1 << 11)
-#define BM_CLPCR_WB_PER_AT_LPM		(0x1 << 16)
-#define BM_CLPCR_WB_CORE_AT_LPM		(0x1 << 17)
-#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS	(0x1 << 19)
-#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS	(0x1 << 21)
-#define BM_CLPCR_MASK_CORE0_WFI		(0x1 << 22)
-#define BM_CLPCR_MASK_CORE1_WFI		(0x1 << 23)
-#define BM_CLPCR_MASK_CORE2_WFI		(0x1 << 24)
-#define BM_CLPCR_MASK_CORE3_WFI		(0x1 << 25)
-#define BM_CLPCR_MASK_SCU_IDLE		(0x1 << 26)
-#define BM_CLPCR_MASK_L2CC_IDLE		(0x1 << 27)
-
-static struct clk *clks[IMX6QDL_CLK_END];
-static struct clk_onecell_data clk_data;
-
-static const char *step_sels[] = {
-	"osc",
-	"pll2_pfd2_396m",
-};
-
-static const char *pll1_sw_sels[] = {
-	"pll1_sys",
-	"step",
-};
-
-static const char *periph_pre_sels[] = {
-	"pll2_bus",
-	"pll2_pfd2_396m",
-	"pll2_pfd0_352m",
-	"pll2_198m",
-};
-
-static const char *periph_clk2_sels[] = {
-	"pll3_usb_otg",
-	"osc",
-};
-
-static const char *periph_sels[] = {
-	"periph_pre",
-	"periph_clk2",
-};
-
-static const char *periph2_sels[] = {
-	"periph2_pre",
-	"periph2_clk2",
-};
-
-static const char *axi_sels[] = {
-	"periph",
-	"pll2_pfd2_396m",
-	"pll3_pfd1_540m",
-};
-
-static const char *usdhc_sels[] = {
-	"pll2_pfd2_396m",
-	"pll2_pfd0_352m",
-};
-
-static const char *enfc_sels[]	= {
-	"pll2_pfd0_352m",
-	"pll2_bus",
-	"pll3_usb_otg",
-	"pll2_pfd2_396m",
-};
-
-static const char *eim_sels[] = {
-	"axi",
-	"pll3_usb_otg",
-	"pll2_pfd2_396m",
-	"pll2_pfd0_352m",
-};
-
-static const char *vdo_axi_sels[] = {
-	"axi",
-	"ahb",
-};
-
-static const char *cko_sels[] = {
-	"cko1",
-	"cko2",
-};
-
-static const char *cko1_sels[] = {
-	"pll3_usb_otg",
-	"pll2_bus",
-	"pll1_sys",
-	"pll5_video",
-	"dummy",
-	"axi",
-	"enfc",
-	"ipu1_di0",
-	"ipu1_di1",
-	"ipu2_di0",
-	"ipu2_di1",
-	"ahb",
-	"ipg",
-	"ipg_per",
-	"ckil",
-	"pll4_audio",
-};
-
-static const char *cko2_sels[] = {
-	"mmdc_ch0_axi",
-	"mmdc_ch1_axi",
-	"usdhc4",
-	"usdhc1",
-	"gpu2d_axi",
-	"dummy",
-	"ecspi_root",
-	"gpu3d_axi",
-	"usdhc3",
-	"dummy",
-	"arm",
-	"ipu1",
-	"ipu2",
-	"vdo_axi",
-	"osc",
-	"gpu2d_core",
-	"gpu3d_core",
-	"usdhc2",
-	"ssi1",
-	"ssi2",
-	"ssi3",
-	"gpu3d_shader",
-	"vpu_axi",
-	"can_root",
-	"ldb_di0",
-	"ldb_di1",
-	"esai",
-	"eim_slow",
-	"uart_serial",
-	"spdif",
-	"asrc",
-	"hsi_tx",
-};
-
-static const char *ipu_sels[] = {
-	"mmdc_ch0_axi_podf",
-	"pll2_pfd2_396m",
-	"pll3_120m",
-	"pll3_pfd1_540m",
-};
-
-static const char *ldb_di_sels[] = {
-	"pll5_video_div",
-	"pll2_pfd0_352m",
-	"pll2_pfd2_396m",
-	"mmdc_ch1_axi_podf",
-	"pll3_usb_otg",
-};
-
-static const char *ipu_di_pre_sels[] = {
-	"mmdc_ch0_axi",
-	"pll3_usb_otg",
-	"pll5_video_div",
-	"pll2_pfd0_352m",
-	"pll2_pfd2_396m",
-	"pll3_pfd1_540m",
-};
-
-static const char *ipu1_di0_sels[] = {
-	"ipu1_di0_pre",
-	"dummy",
-	"dummy",
-	"ldb_di0_podf",
-	"ldb_di1_podf",
-};
-
-static const char *ipu1_di1_sels[] = {
-	"ipu1_di1_pre",
-	"dummy",
-	"dummy",
-	"ldb_di0_podf",
-	"ldb_di1_podf",
-};
-
-static const char *ipu2_di0_sels[] = {
-	"ipu2_di0_pre",
-	"dummy",
-	"dummy",
-	"ldb_di0_podf",
-	"ldb_di1_podf",
-};
-
-static const char *ipu2_di1_sels[] = {
-	"ipu2_di1_pre",
-	"dummy",
-	"dummy",
-	"ldb_di0_podf",
-	"ldb_di1_podf",
-};
-
-static const char *lvds_sels[] = {
-	"dummy",
-	"dummy",
-	"dummy",
-	"dummy",
-	"dummy",
-	"dummy",
-	"pll4_audio",
-	"pll5_video",
-	"pll8_mlb",
-	"enet_ref",
-	"pcie_ref_125m",
-	"sata_ref_100m",
-};
-
-static const char *pcie_axi_sels[] = {
-	"axi",
-	"ahb",
-};
-
-static struct clk_div_table clk_enet_ref_table[] = {
-	{ .val = 0, .div = 20, },
-	{ .val = 1, .div = 10, },
-	{ .val = 2, .div = 5, },
-	{ .val = 3, .div = 4, },
-	{ },
-};
-
-static struct clk_div_table post_div_table[] = {
-	{ .val = 2, .div = 1, },
-	{ .val = 1, .div = 2, },
-	{ .val = 0, .div = 4, },
-	{ /* sentinel */ }
-};
-
-static struct clk_div_table video_div_table[] = {
-	{ .val = 0, .div = 1, },
-	{ .val = 1, .div = 2, },
-	{ .val = 2, .div = 1, },
-	{ .val = 3, .div = 4, },
-	{ /* sentinel */ }
-};
-
-static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb)
-{
-	clks[IMX6QDL_CLK_PLL5_POST_DIV] = imx_clk_divider_table("pll5_post_div", "pll5_video", anab + 0xa0, 19, 2, post_div_table);
-	clks[IMX6QDL_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div", anab + 0x170, 30, 2, video_div_table);
-
-	clks[IMX6QDL_CLK_IPU1_SEL]         = imx_clk_mux("ipu1_sel",         cb + 0x3c, 9,  2, ipu_sels,          ARRAY_SIZE(ipu_sels));
-	clks[IMX6QDL_CLK_IPU2_SEL]         = imx_clk_mux("ipu2_sel",         cb + 0x3c, 14, 2, ipu_sels,          ARRAY_SIZE(ipu_sels));
-	clks[IMX6QDL_CLK_LDB_DI0_SEL]      = imx_clk_mux_p("ldb_di0_sel",      cb + 0x2c, 9,  3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
-	clks[IMX6QDL_CLK_LDB_DI1_SEL]      = imx_clk_mux_p("ldb_di1_sel",      cb + 0x2c, 12, 3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
-	clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_p("ipu1_di0_pre_sel", cb + 0x34, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
-	clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_p("ipu1_di1_pre_sel", cb + 0x34, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
-	clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_p("ipu2_di0_pre_sel", cb + 0x38, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
-	clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_p("ipu2_di1_pre_sel", cb + 0x38, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
-	clks[IMX6QDL_CLK_IPU1_DI0_SEL]     = imx_clk_mux_p("ipu1_di0_sel",     cb + 0x34, 0,  3, ipu1_di0_sels,     ARRAY_SIZE(ipu1_di0_sels));
-	clks[IMX6QDL_CLK_IPU1_DI1_SEL]     = imx_clk_mux_p("ipu1_di1_sel",     cb + 0x34, 9,  3, ipu1_di1_sels,     ARRAY_SIZE(ipu1_di1_sels));
-	clks[IMX6QDL_CLK_IPU2_DI0_SEL]     = imx_clk_mux_p("ipu2_di0_sel",     cb + 0x38, 0,  3, ipu2_di0_sels,     ARRAY_SIZE(ipu2_di0_sels));
-	clks[IMX6QDL_CLK_IPU2_DI1_SEL]     = imx_clk_mux_p("ipu2_di1_sel",     cb + 0x38, 9,  3, ipu2_di1_sels,     ARRAY_SIZE(ipu2_di1_sels));
-
-	clks[IMX6QDL_CLK_IPU1_PODF]        = imx_clk_divider("ipu1_podf",        "ipu1_sel",          cb + 0x3c, 11, 3);
-	clks[IMX6QDL_CLK_IPU2_PODF]        = imx_clk_divider("ipu2_podf",        "ipu2_sel",          cb + 0x3c, 16, 3);
-	clks[IMX6QDL_CLK_LDB_DI0_DIV_3_5]  = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
-	clks[IMX6QDL_CLK_LDB_DI0_PODF]     = imx_clk_divider_np("ldb_di0_podf", "ldb_di0_div_3_5", cb + 0x20, 10, 1);
-	clks[IMX6QDL_CLK_LDB_DI1_DIV_3_5]  = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
-	clks[IMX6QDL_CLK_LDB_DI1_PODF]     = imx_clk_divider_np("ldb_di1_podf", "ldb_di1_div_3_5", cb + 0x20, 11, 1);
-	clks[IMX6QDL_CLK_IPU1_DI0_PRE]     = imx_clk_divider("ipu1_di0_pre",     "ipu1_di0_pre_sel",  cb + 0x34, 3,  3);
-	clks[IMX6QDL_CLK_IPU1_DI1_PRE]     = imx_clk_divider("ipu1_di1_pre",     "ipu1_di1_pre_sel",  cb + 0x34, 12, 3);
-	clks[IMX6QDL_CLK_IPU2_DI0_PRE]     = imx_clk_divider("ipu2_di0_pre",     "ipu2_di0_pre_sel",  cb + 0x38, 3,  3);
-	clks[IMX6QDL_CLK_IPU2_DI1_PRE]     = imx_clk_divider("ipu2_di1_pre",     "ipu2_di1_pre_sel",  cb + 0x38, 12, 3);
-
-	clks[IMX6QDL_CLK_IPU1]         = imx_clk_gate2("ipu1",          "ipu1_podf",         cb + 0x74, 0);
-	clks[IMX6QDL_CLK_IPU1_DI0]     = imx_clk_gate2("ipu1_di0",      "ipu1_di0_sel",      cb + 0x74, 2);
-	clks[IMX6QDL_CLK_IPU1_DI1]     = imx_clk_gate2("ipu1_di1",      "ipu1_di1_sel",      cb + 0x74, 4);
-	clks[IMX6QDL_CLK_IPU2]         = imx_clk_gate2("ipu2",          "ipu2_podf",         cb + 0x74, 6);
-	clks[IMX6QDL_CLK_IPU2_DI0]     = imx_clk_gate2("ipu2_di0",      "ipu2_di0_sel",      cb + 0x74, 8);
-	clks[IMX6QDL_CLK_LDB_DI0]      = imx_clk_gate2("ldb_di0",       "ldb_di0_podf",      cb + 0x74, 12);
-	clks[IMX6QDL_CLK_LDB_DI1]      = imx_clk_gate2("ldb_di1",       "ldb_di1_podf",      cb + 0x74, 14);
-	clks[IMX6QDL_CLK_IPU2_DI1]     = imx_clk_gate2("ipu2_di1",      "ipu2_di1_sel",      cb + 0x74, 10);
-
-	clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_SEL], clks[IMX6QDL_CLK_IPU1_DI0_PRE]);
-	clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_SEL], clks[IMX6QDL_CLK_IPU1_DI1_PRE]);
-	clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_SEL], clks[IMX6QDL_CLK_IPU2_DI0_PRE]);
-	clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_SEL], clks[IMX6QDL_CLK_IPU2_DI1_PRE]);
-
-	clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
-	clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
-	clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
-	clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
-
-	if ((imx_silicon_revision() != IMX_CHIP_REV_1_0) ||
-	    cpu_is_mx6dl()) {
-		clk_set_parent(clks[IMX6QDL_CLK_LDB_DI0_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
-		clk_set_parent(clks[IMX6QDL_CLK_LDB_DI1_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
-	}
-
-}
-
-static int imx6_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *base, *anatop_base, *ccm_base;
-
-	anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	ccm_base = IOMEM(iores->start);
-
-	base = anatop_base;
-
-	/*                   type                               name            parent_name base   div_mask */
-	clks[IMX6QDL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x7f);
-	clks[IMX6QDL_CLK_PLL2_BUS]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x1);
-	clks[IMX6QDL_CLK_PLL3_USB_OTG]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x3);
-	clks[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x7f);
-	clks[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
-	clks[IMX6QDL_CLK_PLL8_MLB]      = imx_clk_pllv3(IMX_PLLV3_MLB,	"pll8_mlb",	"osc", base + 0xd0, 0x0);
-	clks[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
-	clks[IMX6QDL_CLK_PLL6_ENET]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
-
-	clks[IMX6QDL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6);
-	clks[IMX6QDL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6);
-
-	clks[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
-	clks[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
-	clks[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
-	clks[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
-
-	clks[IMX6QDL_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet", base + 0xe0, 0, 2, clk_enet_ref_table);
-
-	clks[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
-	clks[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
-
-	clks[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12));
-	clks[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13));
-
-	/*                                name               parent_name         reg          idx */
-	clks[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
-	clks[IMX6QDL_CLK_PLL2_PFD1_594M] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",     base + 0x100, 1);
-	clks[IMX6QDL_CLK_PLL2_PFD2_396M] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus",     base + 0x100, 2);
-	clks[IMX6QDL_CLK_PLL3_PFD0_720M] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0,  0);
-	clks[IMX6QDL_CLK_PLL3_PFD1_540M] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0,  1);
-	clks[IMX6QDL_CLK_PLL3_PFD2_508M] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0,  2);
-	clks[IMX6QDL_CLK_PLL3_PFD3_454M] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0,  3);
-
-	/*                                    name          parent_name          mult div */
-	clks[IMX6QDL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
-	clks[IMX6QDL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg",   1, 4);
-	clks[IMX6QDL_CLK_PLL3_80M]  = imx_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1, 6);
-	clks[IMX6QDL_CLK_PLL3_60M]  = imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 8);
-	clks[IMX6QDL_CLK_TWD]       = imx_clk_fixed_factor("twd",       "arm",            1, 2);
-
-	base = ccm_base;
-
-	/*                                  name                 reg       shift width parent_names     num_parents */
-	clks[IMX6QDL_CLK_STEP]             = imx_clk_mux("step",	         base + 0xc,  8,  1, step_sels,	        ARRAY_SIZE(step_sels));
-	clks[IMX6QDL_CLK_PLL1_SW]          = imx_clk_mux("pll1_sw",	         base + 0xc,  2,  1, pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
-	clks[IMX6QDL_CLK_PERIPH_PRE]       = imx_clk_mux("periph_pre",       base + 0x18, 18, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
-	clks[IMX6QDL_CLK_PERIPH2_PRE]      = imx_clk_mux("periph2_pre",      base + 0x18, 21, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
-	clks[IMX6QDL_CLK_PERIPH_CLK2_SEL]  = imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
-	clks[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
-	clks[IMX6QDL_CLK_AXI_SEL]          = imx_clk_mux("axi_sel",          base + 0x14, 6,  2, axi_sels,          ARRAY_SIZE(axi_sels));
-	clks[IMX6QDL_CLK_USDHC1_SEL]       = imx_clk_mux("usdhc1_sel",       base + 0x1c, 16, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-	clks[IMX6QDL_CLK_USDHC2_SEL]       = imx_clk_mux("usdhc2_sel",       base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-	clks[IMX6QDL_CLK_USDHC3_SEL]       = imx_clk_mux("usdhc3_sel",       base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-	clks[IMX6QDL_CLK_USDHC4_SEL]       = imx_clk_mux("usdhc4_sel",       base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-	clks[IMX6QDL_CLK_ENFC_SEL]         = imx_clk_mux("enfc_sel",         base + 0x2c, 16, 2, enfc_sels,         ARRAY_SIZE(enfc_sels));
-	clks[IMX6QDL_CLK_EIM_SEL]          = imx_clk_mux("eim_sel",          base + 0x1c, 27, 2, eim_sels,          ARRAY_SIZE(eim_sels));
-	clks[IMX6QDL_CLK_EIM_SLOW_SEL]     = imx_clk_mux("eim_slow_sel",     base + 0x1c, 29, 2, eim_sels,          ARRAY_SIZE(eim_sels));
-	clks[IMX6QDL_CLK_VDO_AXI_SEL]      = imx_clk_mux("vdo_axi_sel",      base + 0x18, 11, 1, vdo_axi_sels,      ARRAY_SIZE(vdo_axi_sels));
-	clks[IMX6QDL_CLK_CKO1_SEL]         = imx_clk_mux("cko1_sel",         base + 0x60, 0,  4, cko1_sels,         ARRAY_SIZE(cko1_sels));
-	clks[IMX6QDL_CLK_CKO2_SEL]         = imx_clk_mux("cko2_sel",         base + 0x60, 16, 5, cko2_sels,         ARRAY_SIZE(cko2_sels));
-	clks[IMX6QDL_CLK_CKO]              = imx_clk_mux("cko",              base + 0x60, 8,  1, cko_sels,          ARRAY_SIZE(cko_sels));
-	clks[IMX6QDL_CLK_PCIE_AXI_SEL]     = imx_clk_mux("pcie_axi_sel",     base + 0x18, 10, 1, pcie_axi_sels,     ARRAY_SIZE(pcie_axi_sels));
-
-	/*                              name         reg       shift width busy: reg, shift parent_names  num_parents */
-	clks[IMX6QDL_CLK_PERIPH]  = imx_clk_busy_mux("periph",  base + 0x14, 25,  1,   base + 0x48, 5,  periph_sels,  ARRAY_SIZE(periph_sels));
-	clks[IMX6QDL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26,  1,   base + 0x48, 3,  periph2_sels, ARRAY_SIZE(periph2_sels));
-
-	/*                                      name                 parent_name               reg       shift width */
-	clks[IMX6QDL_CLK_PERIPH_CLK2]      = imx_clk_divider("periph_clk2",      "periph_clk2_sel",   base + 0x14, 27, 3);
-	clks[IMX6QDL_CLK_PERIPH2_CLK2]     = imx_clk_divider("periph2_clk2",     "periph2_clk2_sel",  base + 0x14, 0,  3);
-	clks[IMX6QDL_CLK_IPG]              = imx_clk_divider("ipg",              "ahb",               base + 0x14, 8,  2);
-	clks[IMX6QDL_CLK_IPG_PER]          = imx_clk_divider("ipg_per",          "ipg",               base + 0x1c, 0,  6);
-	clks[IMX6QDL_CLK_CAN_ROOT]         = imx_clk_divider("can_root",         "pll3_usb_otg",      base + 0x20, 2,  6);
-	clks[IMX6QDL_CLK_ECSPI_ROOT]       = imx_clk_divider("ecspi_root",       "pll3_60m",          base + 0x38, 19, 6);
-	clks[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m",          base + 0x24, 0,  6);
-	clks[IMX6QDL_CLK_USDHC1_PODF]      = imx_clk_divider("usdhc1_podf",      "usdhc1_sel",        base + 0x24, 11, 3);
-	clks[IMX6QDL_CLK_USDHC2_PODF]      = imx_clk_divider("usdhc2_podf",      "usdhc2_sel",        base + 0x24, 16, 3);
-	clks[IMX6QDL_CLK_USDHC3_PODF]      = imx_clk_divider("usdhc3_podf",      "usdhc3_sel",        base + 0x24, 19, 3);
-	clks[IMX6QDL_CLK_USDHC4_PODF]      = imx_clk_divider("usdhc4_podf",      "usdhc4_sel",        base + 0x24, 22, 3);
-	clks[IMX6QDL_CLK_ENFC_PRED]        = imx_clk_divider("enfc_pred",        "enfc_sel",          base + 0x2c, 18, 3);
-	clks[IMX6QDL_CLK_ENFC_PODF]        = imx_clk_divider("enfc_podf",        "enfc_pred",         base + 0x2c, 21, 6);
-	clks[IMX6QDL_CLK_EIM_PODF]         = imx_clk_divider("eim_podf",         "eim_sel",           base + 0x1c, 20, 3);
-	clks[IMX6QDL_CLK_EIM_SLOW_PODF]    = imx_clk_divider("eim_slow_podf",    "eim_slow_sel",      base + 0x1c, 23, 3);
-	clks[IMX6QDL_CLK_CKO1_PODF]        = imx_clk_divider("cko1_podf",        "cko1_sel",          base + 0x60, 4,  3);
-	clks[IMX6QDL_CLK_CKO2_PODF]        = imx_clk_divider("cko2_podf",        "cko2_sel",          base + 0x60, 21, 3);
-
-	/*                                            name                  parent_name         reg        shift width busy: reg, shift */
-	clks[IMX6QDL_CLK_AXI]               = imx_clk_busy_divider("axi",               "axi_sel",     base + 0x14, 16,  3,   base + 0x48, 0);
-	clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph",      base + 0x14, 19,  3,   base + 0x48, 4);
-	clks[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2",     base + 0x14, 3,   3,   base + 0x48, 2);
-	clks[IMX6QDL_CLK_ARM]               = imx_clk_busy_divider("arm",               "pll1_sw",     base + 0x10, 0,   3,   base + 0x48, 16);
-	clks[IMX6QDL_CLK_AHB]               = imx_clk_busy_divider("ahb",               "periph",      base + 0x14, 10,  3,   base + 0x48, 1);
-
-	/*                                            name             parent_name          reg         shift */
-	clks[IMX6QDL_CLK_APBH_DMA]     = imx_clk_gate2("apbh_dma",      "usdhc3",            base + 0x68, 4);
-	clks[IMX6QDL_CLK_CAAM_MEM]     = imx_clk_gate2("caam_mem",      "ahb",               base + 0x68, 8);
-	clks[IMX6QDL_CLK_CAAM_ACLK]    = imx_clk_gate2("caam_aclk",     "ahb",               base + 0x68, 10);
-	clks[IMX6QDL_CLK_CAAM_IPG]     = imx_clk_gate2("caam_ipg",      "ipg",               base + 0x68, 12);
-	clks[IMX6QDL_CLK_ECSPI1]       = imx_clk_gate2("ecspi1",        "ecspi_root",        base + 0x6c, 0);
-	clks[IMX6QDL_CLK_ECSPI2]       = imx_clk_gate2("ecspi2",        "ecspi_root",        base + 0x6c, 2);
-	clks[IMX6QDL_CLK_ECSPI3]       = imx_clk_gate2("ecspi3",        "ecspi_root",        base + 0x6c, 4);
-	clks[IMX6QDL_CLK_ECSPI4]       = imx_clk_gate2("ecspi4",        "ecspi_root",        base + 0x6c, 6);
-	if (cpu_is_mx6dl())
-		clks[IMX6DL_CLK_I2C4]  = imx_clk_gate2("i2c4",          "ipg_per",           base + 0x6c, 8);
-	else
-		clks[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5",        "ecspi_root",        base + 0x6c, 8);
-	clks[IMX6QDL_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x6c, 10);
-	clks[IMX6QDL_CLK_GPT_IPG]      = imx_clk_gate2("gpt_ipg",       "ipg",               base + 0x6c, 20);
-	clks[IMX6QDL_CLK_GPT_IPG_PER]  = imx_clk_gate2("gpt_ipg_per",   "ipg_per",           base + 0x6c, 22);
-	clks[IMX6QDL_CLK_I2C1]         = imx_clk_gate2("i2c1",          "ipg_per",           base + 0x70, 6);
-	clks[IMX6QDL_CLK_I2C2]         = imx_clk_gate2("i2c2",          "ipg_per",           base + 0x70, 8);
-	clks[IMX6QDL_CLK_I2C3]         = imx_clk_gate2("i2c3",          "ipg_per",           base + 0x70, 10);
-	clks[IMX6QDL_CLK_IIM]          = imx_clk_gate2("iim",           "ipg",               base + 0x70, 12);
-	clks[IMX6QDL_CLK_ENFC]         = imx_clk_gate2("enfc",          "enfc_podf",         base + 0x70, 14);
-	clks[IMX6QDL_CLK_PCIE_AXI]     = imx_clk_gate2("pcie_axi",      "pcie_axi_sel",      base + 0x78, 0);
-	clks[IMX6QDL_CLK_PER1_BCH]     = imx_clk_gate2("per1_bch",      "usdhc3",            base + 0x78, 12);
-	clks[IMX6QDL_CLK_PWM1]         = imx_clk_gate2("pwm1",          "ipg_per",           base + 0x78, 16);
-	clks[IMX6QDL_CLK_PWM2]         = imx_clk_gate2("pwm2",          "ipg_per",           base + 0x78, 18);
-	clks[IMX6QDL_CLK_PWM3]         = imx_clk_gate2("pwm3",          "ipg_per",           base + 0x78, 20);
-	clks[IMX6QDL_CLK_PWM4]         = imx_clk_gate2("pwm4",          "ipg_per",           base + 0x78, 22);
-	clks[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
-	clks[IMX6QDL_CLK_GPMI_BCH]     = imx_clk_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
-	clks[IMX6QDL_CLK_GPMI_IO]      = imx_clk_gate2("gpmi_io",       "enfc",              base + 0x78, 28);
-	clks[IMX6QDL_CLK_GPMI_APB]     = imx_clk_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
-	clks[IMX6QDL_CLK_SATA]         = imx_clk_gate2("sata",          "ipg",               base + 0x7c, 4);
-	clks[IMX6QDL_CLK_UART_IPG]     = imx_clk_gate2("uart_ipg",      "ipg",               base + 0x7c, 24);
-	clks[IMX6QDL_CLK_UART_SERIAL]  = imx_clk_gate2("uart_serial",   "uart_serial_podf",  base + 0x7c, 26);
-	clks[IMX6QDL_CLK_USBOH3]       = imx_clk_gate2("usboh3",        "ipg",               base + 0x80, 0);
-	clks[IMX6QDL_CLK_USDHC1]       = imx_clk_gate2("usdhc1",        "usdhc1_podf",       base + 0x80, 2);
-	clks[IMX6QDL_CLK_USDHC2]       = imx_clk_gate2("usdhc2",        "usdhc2_podf",       base + 0x80, 4);
-	clks[IMX6QDL_CLK_USDHC3]       = imx_clk_gate2("usdhc3",        "usdhc3_podf",       base + 0x80, 6);
-	clks[IMX6QDL_CLK_USDHC4]       = imx_clk_gate2("usdhc4",        "usdhc4_podf",       base + 0x80, 8);
-	clks[IMX6QDL_CLK_EIM_SLOW]     = imx_clk_gate2("eim_slow",      "eim_slow_podf",     base + 0x80, 10);
-	clks[IMX6QDL_CLK_CKO1]         = imx_clk_gate("cko1",           "cko1_podf",         base + 0x60, 7);
-	clks[IMX6QDL_CLK_CKO2]         = imx_clk_gate("cko2",           "cko2_podf",         base + 0x60, 24);
-
-	clkdev_add_physbase(clks[IMX6QDL_CLK_IPG], MX6_OCOTP_BASE_ADDR, NULL);
-
-	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
-		imx6_add_video_clks(anatop_base, ccm_base);
-
-	writel(0xffffffff, ccm_base + CCGR0);
-	writel(0xf0ffffff, ccm_base + CCGR1); /* gate GPU3D, GPU2D */
-	writel(0xffffffff, ccm_base + CCGR2);
-	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
-		writel(0x3fffffff, ccm_base + CCGR3); /* gate OpenVG */
-	else
-		writel(0x3fff0000, ccm_base + CCGR3); /* gate OpenVG, LDB, IPU1, IPU2 */
-	if (IS_ENABLED(CONFIG_PCI_IMX6))
-		writel(0xffffffff, ccm_base + CCGR4);
-	else
-		writel(0xfffffffc, ccm_base + CCGR4); /* gate PCIe */
-	writel(0xffffffff, ccm_base + CCGR5);
-	writel(0xffff3fff, ccm_base + CCGR6); /* gate VPU */
-	writel(0xffffffff, ccm_base + CCGR7);
-
-	clk_data.clks = clks;
-	clk_data.clk_num = IMX6QDL_CLK_END;
-	of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data);
-
-	clk_enable(clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF]);
-	clk_enable(clks[IMX6QDL_CLK_PLL6_ENET]);
-	clk_enable(clks[IMX6QDL_CLK_SATA_REF_100M]);
-	clk_enable(clks[IMX6QDL_CLK_ENFC_PODF]);
-
-	clk_set_parent(clks[IMX6QDL_CLK_LVDS1_SEL], clks[IMX6QDL_CLK_SATA_REF_100M]);
-
-	return 0;
-}
-
-static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx6q-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx6_ccm_driver = {
-	.probe	= imx6_ccm_probe,
-	.name	= "imx6-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx6_ccm_dt_ids),
-};
-
-static int imx6_ccm_init(void)
-{
-	return platform_driver_register(&imx6_ccm_driver);
-}
-core_initcall(imx6_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c
deleted file mode 100644
index d758957..0000000
--- a/arch/arm/mach-imx/clk-imx6sx.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <dt-bindings/clock/imx6sx-clock.h>
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <of.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <mach/imx6-regs.h>
-#include <mach/revision.h>
-#include <mach/imx6.h>
-
-#include "clk.h"
-#include "common.h"
-
-#define CCDR    0x4
-#define BM_CCM_CCDR_MMDC_CH0_MASK       (0x2 << 16)
-
-static const char *step_sels[]		= { "osc", "pll2_pfd2_396m", };
-static const char *pll1_sw_sels[]	= { "pll1_sys", "step", };
-static const char *periph_pre_sels[]	= { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
-static const char *periph2_pre_sels[]	= { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
-static const char *periph_clk2_sels[]	= { "pll3_usb_otg", "osc", "osc", };
-static const char *periph2_clk2_sels[]	= { "pll3_usb_otg", "osc", };
-static const char *periph_sels[]	= { "periph_pre", "periph_clk2", };
-static const char *periph2_sels[]	= { "periph2_pre", "periph2_clk2", };
-static const char *ocram_sels[]		= { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
-static const char *gpu_axi_sels[]	= { "pll2_pfd2_396m", "pll3_pfd0_720m", "pll3_pfd1_540m", "pll2_bus", };
-static const char *gpu_core_sels[]	= { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", };
-static const char *ldb_di0_div_sels[]	= { "ldb_di0_div_3_5", "ldb_di0_div_7", };
-static const char *ldb_di1_div_sels[]	= { "ldb_di1_div_3_5", "ldb_di1_div_7", };
-static const char *ldb_di0_sels[]	= { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
-static const char *ldb_di1_sels[]	= { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
-static const char *pcie_axi_sels[]	= { "axi", "ahb", };
-static const char *qspi1_sels[]		= { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
-static const char *perclk_sels[]	= { "ipg", "osc", };
-static const char *usdhc_sels[]		= { "pll2_pfd2_396m", "pll2_pfd0_352m", };
-static const char *vid_sels[]		= { "pll3_pfd1_540m", "pll3_usb_otg", "pll3_pfd3_454m", "pll4_audio_div", "pll5_video_div", };
-static const char *uart_sels[]		= { "pll3_80m", "osc", };
-static const char *qspi2_sels[]		= { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", "dummy", "dummy", };
-static const char *enet_pre_sels[]	= { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
-static const char *enet_sels[]		= { "enet_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
-static const char *m4_pre_sels[]	= { "pll2_bus", "pll3_usb_otg", "osc", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd3_454m", };
-static const char *m4_sels[]		= { "m4_pre_sel", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
-static const char *eim_slow_sels[]	= { "ocram", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
-static const char *ecspi_sels[]		= { "pll3_60m", "osc", };
-static const char *lcdif1_pre_sels[]	= { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
-static const char *lcdif1_sels[]	= { "lcdif1_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
-static const char *lcdif2_pre_sels[]	= { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd3_594m", "pll3_pfd1_540m", };
-static const char *lcdif2_sels[]	= { "lcdif2_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
-static const char *display_sels[]	= { "pll2_bus", "pll2_pfd2_396m", "pll3_usb_otg", "pll3_pfd1_540m", };
-static const char *csi_sels[]		= { "osc", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
-static const char *cko1_sels[]		= {
-	"pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
-	"dummy", "ocram", "dummy", "pxp_axi", "epdc_axi", "lcdif_pix",
-	"epdc_pix", "ahb", "ipg", "perclk", "ckil", "pll4_audio_div",
-};
-static const char *cko2_sels[]		= {
-	"dummy", "mmdc_p0_fast", "usdhc4", "usdhc1", "dummy", "wrck",
-	"ecspi_root", "dummy", "usdhc3", "pcie", "arm", "csi_core",
-	"lcdif_axi", "dummy", "osc", "dummy", "gpu2d_ovg_core",
-	"usdhc2", "ssi1", "ssi2", "ssi3", "gpu2d_core", "dummy",
-	"dummy", "dummy", "dummy", "esai_extal", "eim_slow", "uart_serial",
-	"spdif", "asrc", "dummy",
-};
-static const char *cko_sels[] = { "cko1", "cko2", };
-static const char *lvds_sels[]	= {
-	"arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div",
-	"dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2",
-};
-static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
-static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
-static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
-static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
-static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
-static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
-static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
-static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
-
-static struct clk *clks[IMX6SX_CLK_CLK_END];
-static struct clk_onecell_data clk_data;
-
-static struct clk_div_table clk_enet_ref_table[] = {
-	{ .val = 0, .div = 20, },
-	{ .val = 1, .div = 10, },
-	{ .val = 2, .div = 5, },
-	{ .val = 3, .div = 4, },
-	{ }
-};
-
-static struct clk_div_table post_div_table[] = {
-	{ .val = 2, .div = 1, },
-	{ .val = 1, .div = 2, },
-	{ .val = 0, .div = 4, },
-	{ }
-};
-
-static struct clk_div_table video_div_table[] = {
-	{ .val = 0, .div = 1, },
-	{ .val = 1, .div = 2, },
-	{ .val = 2, .div = 1, },
-	{ .val = 3, .div = 4, },
-	{ }
-};
-
-static int imx6sx_ccm_probe(struct device_d *dev)
-{
-	struct resource *iores;
-	void __iomem *base, *anatop_base, *ccm_base;
-	struct device_node *ccm_node = dev->device_node;
-
-	clks[IMX6SX_CLK_DUMMY] = clk_fixed("dummy", 0);
-
-	anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
-	iores = dev_request_mem_resource(dev, 0);
-	if (IS_ERR(iores))
-		return PTR_ERR(iores);
-	ccm_base = IOMEM(iores->start);
-
-	base = anatop_base;
-
-	clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
-	clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
-	clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
-	clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
-	clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
-	clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
-	clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
-
-	/*                                    type               name    parent_name        base         div_mask */
-	clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS,     "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
-	clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
-	clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB,     "pll3", "pll3_bypass_src", base + 0x10, 0x3);
-	clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV,      "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
-	clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV,      "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
-	clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET,    "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
-	clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB,     "pll7", "pll7_bypass_src", base + 0x20, 0x3);
-
-	clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_p("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels));
-	clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_p("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels));
-	clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_p("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels));
-	clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_p("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels));
-	clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_p("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels));
-	clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_p("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels));
-	clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_p("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels));
-
-	/* Do not bypass PLLs initially */
-	clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
-	clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
-	clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
-	clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
-	clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
-	clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
-	clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
-
-	clks[IMX6SX_CLK_PLL1_SYS]      = imx_clk_gate("pll1_sys",      "pll1_bypass", base + 0x00, 13);
-	clks[IMX6SX_CLK_PLL2_BUS]      = imx_clk_gate("pll2_bus",      "pll2_bypass", base + 0x30, 13);
-	clks[IMX6SX_CLK_PLL3_USB_OTG]  = imx_clk_gate("pll3_usb_otg",  "pll3_bypass", base + 0x10, 13);
-	clks[IMX6SX_CLK_PLL4_AUDIO]    = imx_clk_gate("pll4_audio",    "pll4_bypass", base + 0x70, 13);
-	clks[IMX6SX_CLK_PLL5_VIDEO]    = imx_clk_gate("pll5_video",    "pll5_bypass", base + 0xa0, 13);
-	clks[IMX6SX_CLK_PLL6_ENET]     = imx_clk_gate("pll6_enet",     "pll6_bypass", base + 0xe0, 13);
-	clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
-
-	/*
-	 * Bit 20 is the reserved and read-only bit, we do this only for:
-	 * - Do nothing for usbphy clk_enable/disable
-	 * - Keep refcount when do usbphy clk_enable/disable, in that case,
-	 * the clk framework may need to enable/disable usbphy's parent
-	 */
-	clks[IMX6SX_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg",  base + 0x10, 20);
-	clks[IMX6SX_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
-
-	/*
-	 * usbphy*_gate needs to be on after system boots up, and software
-	 * never needs to control it anymore.
-	 */
-	clks[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
-	clks[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
-
-	/* FIXME 100Mhz is used for pcie ref for all imx6 pcie, excepted imx6q */
-	clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5);
-	clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
-
-	clks[IMX6SX_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet",
-			base + 0xe0, 0, 2, clk_enet_ref_table);
-	clks[IMX6SX_CLK_ENET2_REF] = imx_clk_divider_table("enet2_ref", "pll6_enet",
-			base + 0xe0, 2, 2, clk_enet_ref_table);
-	clks[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20);
-
-	clks[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
-	clks[IMX6SX_CLK_ENET_PTP] = imx_clk_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21);
-
-	/*                                       name              parent_name     reg           idx */
-	clks[IMX6SX_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
-	clks[IMX6SX_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",     base + 0x100, 1);
-	clks[IMX6SX_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus",     base + 0x100, 2);
-	clks[IMX6SX_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus",     base + 0x100, 3);
-	clks[IMX6SX_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0,  0);
-	clks[IMX6SX_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0,  1);
-	clks[IMX6SX_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0,  2);
-	clks[IMX6SX_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0,  3);
-
-	/*                                                name         parent_name       mult div */
-	clks[IMX6SX_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1,   2);
-	clks[IMX6SX_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg",   1,   4);
-	clks[IMX6SX_CLK_PLL3_80M]  = imx_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1,   6);
-	clks[IMX6SX_CLK_PLL3_60M]  = imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1,   8);
-	clks[IMX6SX_CLK_TWD]       = imx_clk_fixed_factor("twd",       "arm",            1,   2);
-	clks[IMX6SX_CLK_GPT_3M]    = imx_clk_fixed_factor("gpt_3m",    "osc",            1,   8);
-
-	clks[IMX6SX_CLK_PLL4_POST_DIV]  = imx_clk_divider_table("pll4_post_div", "pll4_audio",
-				base + 0x70, 19, 2, post_div_table);
-	clks[IMX6SX_CLK_PLL4_AUDIO_DIV] = imx_clk_divider("pll4_audio_div", "pll4_post_div",
-				base + 0x170, 15, 1);
-	clks[IMX6SX_CLK_PLL5_POST_DIV]  = imx_clk_divider_table("pll5_post_div", "pll5_video",
-				base + 0xa0, 19, 2, post_div_table);
-	clks[IMX6SX_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div",
-				base + 0x170, 30, 2, video_div_table);
-
-	/*                                                name                reg           shift   width   parent_names       num_parents */
-	clks[IMX6SX_CLK_LVDS1_SEL]          = imx_clk_mux("lvds1_sel",        base + 0x160, 0,      5,      lvds_sels,         ARRAY_SIZE(lvds_sels));
-
-	base = ccm_base;
-
-	/*                                                name                reg           shift   width   parent_names       num_parents */
-	clks[IMX6SX_CLK_STEP]               = imx_clk_mux("step",             base + 0xc,   8,      1,      step_sels,         ARRAY_SIZE(step_sels));
-	clks[IMX6SX_CLK_PLL1_SW]            = imx_clk_mux("pll1_sw",          base + 0xc,   2,      1,      pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
-	clks[IMX6SX_CLK_OCRAM_SEL]          = imx_clk_mux("ocram_sel",        base + 0x14,  6,      2,      ocram_sels,        ARRAY_SIZE(ocram_sels));
-	clks[IMX6SX_CLK_PERIPH_PRE]         = imx_clk_mux("periph_pre",       base + 0x18,  18,     2,      periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
-	clks[IMX6SX_CLK_PERIPH2_PRE]        = imx_clk_mux("periph2_pre",      base + 0x18,  21,     2,      periph2_pre_sels,   ARRAY_SIZE(periph2_pre_sels));
-	clks[IMX6SX_CLK_PERIPH_CLK2_SEL]    = imx_clk_mux("periph_clk2_sel",  base + 0x18,  12,     2,      periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
-	clks[IMX6SX_CLK_PERIPH2_CLK2_SEL]   = imx_clk_mux("periph2_clk2_sel", base + 0x18,  20,     1,      periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
-	clks[IMX6SX_CLK_PCIE_AXI_SEL]       = imx_clk_mux("pcie_axi_sel",     base + 0x18,  10,     1,      pcie_axi_sels,     ARRAY_SIZE(pcie_axi_sels));
-	clks[IMX6SX_CLK_GPU_AXI_SEL]        = imx_clk_mux("gpu_axi_sel",      base + 0x18,  8,      2,      gpu_axi_sels,      ARRAY_SIZE(gpu_axi_sels));
-	clks[IMX6SX_CLK_GPU_CORE_SEL]       = imx_clk_mux("gpu_core_sel",     base + 0x18,  4,      2,      gpu_core_sels,     ARRAY_SIZE(gpu_core_sels));
-	clks[IMX6SX_CLK_EIM_SLOW_SEL]       = imx_clk_mux("eim_slow_sel",     base + 0x1c,  29,     2,      eim_slow_sels,     ARRAY_SIZE(eim_slow_sels));
-	clks[IMX6SX_CLK_USDHC1_SEL]         = imx_clk_mux("usdhc1_sel",       base + 0x1c,  16,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-	clks[IMX6SX_CLK_USDHC2_SEL]         = imx_clk_mux("usdhc2_sel",       base + 0x1c,  17,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-	clks[IMX6SX_CLK_USDHC3_SEL]         = imx_clk_mux("usdhc3_sel",       base + 0x1c,  18,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-	clks[IMX6SX_CLK_USDHC4_SEL]         = imx_clk_mux("usdhc4_sel",       base + 0x1c,  19,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-	clks[IMX6SX_CLK_QSPI1_SEL]          = imx_clk_mux_p("qspi1_sel", base + 0x1c,  7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
-	clks[IMX6SX_CLK_PERCLK_SEL]         = imx_clk_mux("perclk_sel",       base + 0x1c,  6,      1,      perclk_sels,       ARRAY_SIZE(perclk_sels));
-	clks[IMX6SX_CLK_VID_SEL]            = imx_clk_mux("vid_sel",          base + 0x20,  21,     3,      vid_sels,          ARRAY_SIZE(vid_sels));
-	clks[IMX6SX_CLK_UART_SEL]           = imx_clk_mux("uart_sel",         base + 0x24,  6,      1,      uart_sels,         ARRAY_SIZE(uart_sels));
-	clks[IMX6SX_CLK_QSPI2_SEL]          = imx_clk_mux_p("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels));
-	clks[IMX6SX_CLK_ENET_PRE_SEL]       = imx_clk_mux("enet_pre_sel",     base + 0x34,  15,     3,      enet_pre_sels,     ARRAY_SIZE(enet_pre_sels));
-	clks[IMX6SX_CLK_ENET_SEL]           = imx_clk_mux("enet_sel",         base + 0x34,  9,      3,      enet_sels,         ARRAY_SIZE(enet_sels));
-	clks[IMX6SX_CLK_M4_PRE_SEL]         = imx_clk_mux("m4_pre_sel",       base + 0x34,  6,      3,      m4_pre_sels,       ARRAY_SIZE(m4_pre_sels));
-	clks[IMX6SX_CLK_M4_SEL]             = imx_clk_mux("m4_sel",           base + 0x34,  0,      3,      m4_sels,           ARRAY_SIZE(m4_sels));
-	clks[IMX6SX_CLK_ECSPI_SEL]          = imx_clk_mux("ecspi_sel",        base + 0x38,  18,     1,      ecspi_sels,        ARRAY_SIZE(ecspi_sels));
-	clks[IMX6SX_CLK_LCDIF2_PRE_SEL]     = imx_clk_mux("lcdif2_pre_sel",   base + 0x38,  6,      3,      lcdif2_pre_sels,   ARRAY_SIZE(lcdif2_pre_sels));
-	clks[IMX6SX_CLK_LCDIF2_SEL]         = imx_clk_mux("lcdif2_sel",       base + 0x38,  0,      3,      lcdif2_sels,       ARRAY_SIZE(lcdif2_sels));
-	clks[IMX6SX_CLK_DISPLAY_SEL]        = imx_clk_mux("display_sel",      base + 0x3c,  14,     2,      display_sels,      ARRAY_SIZE(display_sels));
-	clks[IMX6SX_CLK_CSI_SEL]            = imx_clk_mux("csi_sel",          base + 0x3c,  9,      2,      csi_sels,          ARRAY_SIZE(csi_sels));
-	clks[IMX6SX_CLK_CKO1_SEL]           = imx_clk_mux("cko1_sel",         base + 0x60,  0,      4,      cko1_sels,         ARRAY_SIZE(cko1_sels));
-	clks[IMX6SX_CLK_CKO2_SEL]           = imx_clk_mux("cko2_sel",         base + 0x60,  16,     5,      cko2_sels,         ARRAY_SIZE(cko2_sels));
-	clks[IMX6SX_CLK_CKO]                = imx_clk_mux("cko",              base + 0x60,  8,      1,      cko_sels,          ARRAY_SIZE(cko_sels));
-
-	clks[IMX6SX_CLK_LDB_DI1_DIV_SEL]    = imx_clk_mux_p("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
-	clks[IMX6SX_CLK_LDB_DI0_DIV_SEL]    = imx_clk_mux_p("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
-	clks[IMX6SX_CLK_LDB_DI1_SEL]        = imx_clk_mux_p("ldb_di1_sel",     base + 0x2c, 12, 3, ldb_di1_sels,      ARRAY_SIZE(ldb_di1_sels));
-	clks[IMX6SX_CLK_LDB_DI0_SEL]        = imx_clk_mux_p("ldb_di0_sel",     base + 0x2c, 9,  3, ldb_di0_sels,      ARRAY_SIZE(ldb_di0_sels));
-	clks[IMX6SX_CLK_LCDIF1_PRE_SEL]     = imx_clk_mux_p("lcdif1_pre_sel",  base + 0x38, 15, 3, lcdif1_pre_sels,   ARRAY_SIZE(lcdif1_pre_sels));
-	clks[IMX6SX_CLK_LCDIF1_SEL]         = imx_clk_mux_p("lcdif1_sel",      base + 0x38, 9,  3, lcdif1_sels,       ARRAY_SIZE(lcdif1_sels));
-
-	/*                                                    name              parent_name          reg          shift width */
-	clks[IMX6SX_CLK_PERIPH_CLK2]        = imx_clk_divider("periph_clk2",    "periph_clk2_sel",   base + 0x14, 27,   3);
-	clks[IMX6SX_CLK_PERIPH2_CLK2]       = imx_clk_divider("periph2_clk2",   "periph2_clk2_sel",  base + 0x14, 0,    3);
-	clks[IMX6SX_CLK_IPG]                = imx_clk_divider("ipg",            "ahb",               base + 0x14, 8,    2);
-	clks[IMX6SX_CLK_GPU_CORE_PODF]      = imx_clk_divider("gpu_core_podf",  "gpu_core_sel",      base + 0x18, 29,   3);
-	clks[IMX6SX_CLK_GPU_AXI_PODF]       = imx_clk_divider("gpu_axi_podf",   "gpu_axi_sel",       base + 0x18, 26,   3);
-	clks[IMX6SX_CLK_LCDIF1_PODF]        = imx_clk_divider("lcdif1_podf",    "lcdif1_pred",       base + 0x18, 23,   3);
-	clks[IMX6SX_CLK_QSPI1_PODF]         = imx_clk_divider("qspi1_podf",     "qspi1_sel",         base + 0x1c, 26,   3);
-	clks[IMX6SX_CLK_EIM_SLOW_PODF]      = imx_clk_divider("eim_slow_podf",  "eim_slow_sel",      base + 0x1c, 23,   3);
-	clks[IMX6SX_CLK_LCDIF2_PODF]        = imx_clk_divider("lcdif2_podf",    "lcdif2_pred",       base + 0x1c, 20,   3);
-	clks[IMX6SX_CLK_PERCLK]             = imx_clk_divider("perclk",         "perclk_sel",        base + 0x1c, 0,    6);
-	clks[IMX6SX_CLK_VID_PODF]           = imx_clk_divider("vid_podf",       "vid_sel",           base + 0x20, 24,   2);
-	clks[IMX6SX_CLK_USDHC4_PODF]        = imx_clk_divider("usdhc4_podf",    "usdhc4_sel",        base + 0x24, 22,   3);
-	clks[IMX6SX_CLK_USDHC3_PODF]        = imx_clk_divider("usdhc3_podf",    "usdhc3_sel",        base + 0x24, 19,   3);
-	clks[IMX6SX_CLK_USDHC2_PODF]        = imx_clk_divider("usdhc2_podf",    "usdhc2_sel",        base + 0x24, 16,   3);
-	clks[IMX6SX_CLK_USDHC1_PODF]        = imx_clk_divider("usdhc1_podf",    "usdhc1_sel",        base + 0x24, 11,   3);
-	clks[IMX6SX_CLK_UART_PODF]          = imx_clk_divider("uart_podf",      "uart_sel",          base + 0x24, 0,    6);
-	clks[IMX6SX_CLK_QSPI2_PRED]         = imx_clk_divider("qspi2_pred",     "qspi2_sel",         base + 0x2c, 18,   3);
-	clks[IMX6SX_CLK_QSPI2_PODF]         = imx_clk_divider("qspi2_podf",     "qspi2_pred",        base + 0x2c, 21,   6);
-	clks[IMX6SX_CLK_ENET_PODF]          = imx_clk_divider("enet_podf",      "enet_pre_sel",      base + 0x34, 12,   3);
-	clks[IMX6SX_CLK_M4_PODF]            = imx_clk_divider("m4_podf",        "m4_sel",            base + 0x34, 3,    3);
-	clks[IMX6SX_CLK_ECSPI_PODF]         = imx_clk_divider("ecspi_podf",     "ecspi_sel",         base + 0x38, 19,   6);
-	clks[IMX6SX_CLK_LCDIF1_PRED]        = imx_clk_divider("lcdif1_pred",    "lcdif1_pre_sel",    base + 0x38, 12,   3);
-	clks[IMX6SX_CLK_LCDIF2_PRED]        = imx_clk_divider("lcdif2_pred",    "lcdif2_pre_sel",    base + 0x38, 3,    3);
-	clks[IMX6SX_CLK_DISPLAY_PODF]       = imx_clk_divider("display_podf",   "display_sel",       base + 0x3c, 16,   3);
-	clks[IMX6SX_CLK_CSI_PODF]           = imx_clk_divider("csi_podf",       "csi_sel",           base + 0x3c, 11,   3);
-	clks[IMX6SX_CLK_CKO1_PODF]          = imx_clk_divider("cko1_podf",      "cko1_sel",          base + 0x60, 4,    3);
-	clks[IMX6SX_CLK_CKO2_PODF]          = imx_clk_divider("cko2_podf",      "cko2_sel",          base + 0x60, 21,   3);
-
-	clks[IMX6SX_CLK_LDB_DI0_DIV_3_5]    = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
-	clks[IMX6SX_CLK_LDB_DI0_DIV_7]      = imx_clk_fixed_factor("ldb_di0_div_7",   "ldb_di0_sel", 1, 7);
-	clks[IMX6SX_CLK_LDB_DI1_DIV_3_5]    = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
-	clks[IMX6SX_CLK_LDB_DI1_DIV_7]      = imx_clk_fixed_factor("ldb_di1_div_7",   "ldb_di1_sel", 1, 7);
-
-	/*                                               name        reg          shift width busy: reg,   shift parent_names       num_parents */
-	clks[IMX6SX_CLK_PERIPH]       = imx_clk_busy_mux("periph",   base + 0x14, 25,   1,    base + 0x48, 5,    periph_sels,       ARRAY_SIZE(periph_sels));
-	clks[IMX6SX_CLK_PERIPH2]      = imx_clk_busy_mux("periph2",  base + 0x14, 26,   1,    base + 0x48, 3,    periph2_sels,      ARRAY_SIZE(periph2_sels));
-	/*                                                   name             parent_name    reg          shift width busy: reg,   shift */
-	clks[IMX6SX_CLK_OCRAM_PODF]   = imx_clk_busy_divider("ocram_podf",    "ocram_sel",   base + 0x14, 16,   3,    base + 0x48, 0);
-	clks[IMX6SX_CLK_AHB]          = imx_clk_busy_divider("ahb",           "periph",      base + 0x14, 10,   3,    base + 0x48, 1);
-	clks[IMX6SX_CLK_MMDC_PODF]    = imx_clk_busy_divider("mmdc_podf",     "periph2",     base + 0x14, 3,    3,    base + 0x48, 2);
-	clks[IMX6SX_CLK_ARM]          = imx_clk_busy_divider("arm",           "pll1_sw",     base + 0x10, 0,    3,    base + 0x48, 16);
-
-	/*                                            name             parent_name          reg         shift */
-	/* CCGR0 */
-	clks[IMX6SX_CLK_AIPS_TZ1]     = imx_clk_gate2("aips_tz1",      "ahb",               base + 0x68, 0);
-	clks[IMX6SX_CLK_AIPS_TZ2]     = imx_clk_gate2("aips_tz2",      "ahb",               base + 0x68, 2);
-	clks[IMX6SX_CLK_APBH_DMA]     = imx_clk_gate2("apbh_dma",      "usdhc3",            base + 0x68, 4);
-	clks[IMX6SX_CLK_CAAM_MEM]     = imx_clk_gate2("caam_mem",      "ahb",               base + 0x68, 8);
-	clks[IMX6SX_CLK_CAAM_ACLK]    = imx_clk_gate2("caam_aclk",     "ahb",               base + 0x68, 10);
-	clks[IMX6SX_CLK_CAAM_IPG]     = imx_clk_gate2("caam_ipg",      "ipg",               base + 0x68, 12);
-	clks[IMX6SX_CLK_DCIC1]        = imx_clk_gate2("dcic1",         "display_podf",      base + 0x68, 24);
-	clks[IMX6SX_CLK_DCIC2]        = imx_clk_gate2("dcic2",         "display_podf",      base + 0x68, 26);
-	clks[IMX6SX_CLK_AIPS_TZ3]     = imx_clk_gate2("aips_tz3",      "ahb",               base + 0x68, 30);
-
-	/* CCGR1 */
-	clks[IMX6SX_CLK_ECSPI1]       = imx_clk_gate2("ecspi1",        "ecspi_podf",        base + 0x6c, 0);
-	clks[IMX6SX_CLK_ECSPI2]       = imx_clk_gate2("ecspi2",        "ecspi_podf",        base + 0x6c, 2);
-	clks[IMX6SX_CLK_ECSPI3]       = imx_clk_gate2("ecspi3",        "ecspi_podf",        base + 0x6c, 4);
-	clks[IMX6SX_CLK_ECSPI4]       = imx_clk_gate2("ecspi4",        "ecspi_podf",        base + 0x6c, 6);
-	clks[IMX6SX_CLK_ECSPI5]       = imx_clk_gate2("ecspi5",        "ecspi_podf",        base + 0x6c, 8);
-	clks[IMX6SX_CLK_EPIT1]        = imx_clk_gate2("epit1",         "perclk",            base + 0x6c, 12);
-	clks[IMX6SX_CLK_EPIT2]        = imx_clk_gate2("epit2",         "perclk",            base + 0x6c, 14);
-	clks[IMX6SX_CLK_WAKEUP]       = imx_clk_gate2("wakeup",        "ipg",               base + 0x6c, 18);
-	clks[IMX6SX_CLK_GPT_BUS]      = imx_clk_gate2("gpt_bus",       "perclk",            base + 0x6c, 20);
-	clks[IMX6SX_CLK_GPT_SERIAL]   = imx_clk_gate2("gpt_serial",    "perclk",            base + 0x6c, 22);
-	clks[IMX6SX_CLK_GPU]          = imx_clk_gate2("gpu",           "gpu_core_podf",     base + 0x6c, 26);
-
-	/* CCGR2 */
-	clks[IMX6SX_CLK_CSI]          = imx_clk_gate2("csi",           "csi_podf",          base + 0x70, 2);
-	clks[IMX6SX_CLK_I2C1]         = imx_clk_gate2("i2c1",          "perclk",            base + 0x70, 6);
-	clks[IMX6SX_CLK_I2C2]         = imx_clk_gate2("i2c2",          "perclk",            base + 0x70, 8);
-	clks[IMX6SX_CLK_I2C3]         = imx_clk_gate2("i2c3",          "perclk",            base + 0x70, 10);
-	clks[IMX6SX_CLK_OCOTP]        = imx_clk_gate2("ocotp",         "ipg",               base + 0x70, 12);
-	clks[IMX6SX_CLK_IOMUXC]       = imx_clk_gate2("iomuxc",        "lcdif1_podf",       base + 0x70, 14);
-	clks[IMX6SX_CLK_IPMUX1]       = imx_clk_gate2("ipmux1",        "ahb",               base + 0x70, 16);
-	clks[IMX6SX_CLK_IPMUX2]       = imx_clk_gate2("ipmux2",        "ahb",               base + 0x70, 18);
-	clks[IMX6SX_CLK_IPMUX3]       = imx_clk_gate2("ipmux3",        "ahb",               base + 0x70, 20);
-	clks[IMX6SX_CLK_TZASC1]       = imx_clk_gate2("tzasc1",        "mmdc_podf",         base + 0x70, 22);
-	clks[IMX6SX_CLK_LCDIF_APB]    = imx_clk_gate2("lcdif_apb",     "display_podf",      base + 0x70, 28);
-	clks[IMX6SX_CLK_PXP_AXI]      = imx_clk_gate2("pxp_axi",       "display_podf",      base + 0x70, 30);
-
-	/* CCGR3 */
-	clks[IMX6SX_CLK_M4]           = imx_clk_gate2("m4",            "m4_podf",           base + 0x74, 2);
-	clks[IMX6SX_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x74, 4);
-	clks[IMX6SX_CLK_ENET_AHB]     = imx_clk_gate2("enet_ahb",      "enet_sel",          base + 0x74, 4);
-	clks[IMX6SX_CLK_DISPLAY_AXI]  = imx_clk_gate2("display_axi",   "display_podf",      base + 0x74, 6);
-	clks[IMX6SX_CLK_LCDIF2_PIX]   = imx_clk_gate2("lcdif2_pix",    "lcdif2_sel",        base + 0x74, 8);
-	clks[IMX6SX_CLK_LCDIF1_PIX]   = imx_clk_gate2("lcdif1_pix",    "lcdif1_sel",        base + 0x74, 10);
-	clks[IMX6SX_CLK_LDB_DI0]      = imx_clk_gate2("ldb_di0",       "ldb_di0_div_sel",   base + 0x74, 12);
-	clks[IMX6SX_CLK_QSPI1]        = imx_clk_gate2("qspi1",         "qspi1_podf",        base + 0x74, 14);
-	clks[IMX6SX_CLK_MLB]          = imx_clk_gate2("mlb",           "ahb",               base + 0x74, 18);
-	clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast",  "mmdc_podf",         base + 0x74, 20);
-	clks[IMX6SX_CLK_MMDC_P0_IPG]  = imx_clk_gate2("mmdc_p0_ipg",   "ipg",               base + 0x74, 24);
-	clks[IMX6SX_CLK_OCRAM]        = imx_clk_gate2("ocram",         "ocram_podf",        base + 0x74, 28);
-
-	/* CCGR4 */
-	clks[IMX6SX_CLK_PCIE_AXI]     = imx_clk_gate2("pcie_axi",      "display_podf",      base + 0x78, 0);
-	clks[IMX6SX_CLK_QSPI2]        = imx_clk_gate2("qspi2",         "qspi2_podf",        base + 0x78, 10);
-	clks[IMX6SX_CLK_PER1_BCH]     = imx_clk_gate2("per1_bch",      "usdhc3",            base + 0x78, 12);
-	clks[IMX6SX_CLK_PER2_MAIN]    = imx_clk_gate2("per2_main",     "ahb",               base + 0x78, 14);
-	clks[IMX6SX_CLK_PWM1]         = imx_clk_gate2("pwm1",          "perclk",            base + 0x78, 16);
-	clks[IMX6SX_CLK_PWM2]         = imx_clk_gate2("pwm2",          "perclk",            base + 0x78, 18);
-	clks[IMX6SX_CLK_PWM3]         = imx_clk_gate2("pwm3",          "perclk",            base + 0x78, 20);
-	clks[IMX6SX_CLK_PWM4]         = imx_clk_gate2("pwm4",          "perclk",            base + 0x78, 22);
-	clks[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
-	clks[IMX6SX_CLK_GPMI_BCH]     = imx_clk_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
-	clks[IMX6SX_CLK_GPMI_IO]      = imx_clk_gate2("gpmi_io",       "qspi2_podf",        base + 0x78, 28);
-	clks[IMX6SX_CLK_GPMI_APB]     = imx_clk_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
-
-	/* CCGR5 */
-	clks[IMX6SX_CLK_ROM]          = imx_clk_gate2("rom",           "ahb",               base + 0x7c, 0);
-	clks[IMX6SX_CLK_SDMA]         = imx_clk_gate2("sdma",          "ahb",               base + 0x7c, 6);
-	clks[IMX6SX_CLK_SPBA]         = imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
-	clks[IMX6SX_CLK_UART_IPG]     = imx_clk_gate2("uart_ipg",      "ipg",               base + 0x7c, 24);
-	clks[IMX6SX_CLK_UART_SERIAL]  = imx_clk_gate2("uart_serial",   "uart_podf",         base + 0x7c, 26);
-	clks[IMX6SX_CLK_SAI1_IPG]     = imx_clk_gate2("sai1_ipg",      "ipg",               base + 0x7c, 28);
-	clks[IMX6SX_CLK_SAI2_IPG]     = imx_clk_gate2("sai2_ipg",      "ipg",               base + 0x7c, 30);
-
-	/* CCGR6 */
-	clks[IMX6SX_CLK_USBOH3]       = imx_clk_gate2("usboh3",        "ipg",               base + 0x80, 0);
-	clks[IMX6SX_CLK_USDHC1]       = imx_clk_gate2("usdhc1",        "usdhc1_podf",       base + 0x80, 2);
-	clks[IMX6SX_CLK_USDHC2]       = imx_clk_gate2("usdhc2",        "usdhc2_podf",       base + 0x80, 4);
-	clks[IMX6SX_CLK_USDHC3]       = imx_clk_gate2("usdhc3",        "usdhc3_podf",       base + 0x80, 6);
-	clks[IMX6SX_CLK_USDHC4]       = imx_clk_gate2("usdhc4",        "usdhc4_podf",       base + 0x80, 8);
-	clks[IMX6SX_CLK_EIM_SLOW]     = imx_clk_gate2("eim_slow",      "eim_slow_podf",     base + 0x80, 10);
-	clks[IMX6SX_CLK_PWM8]         = imx_clk_gate2("pwm8",          "perclk",            base + 0x80, 16);
-	clks[IMX6SX_CLK_VADC]         = imx_clk_gate2("vadc",          "vid_podf",          base + 0x80, 20);
-	clks[IMX6SX_CLK_GIS]          = imx_clk_gate2("gis",           "display_podf",      base + 0x80, 22);
-	clks[IMX6SX_CLK_I2C4]         = imx_clk_gate2("i2c4",          "perclk",            base + 0x80, 24);
-	clks[IMX6SX_CLK_PWM5]         = imx_clk_gate2("pwm5",          "perclk",            base + 0x80, 26);
-	clks[IMX6SX_CLK_PWM6]         = imx_clk_gate2("pwm6",          "perclk",            base + 0x80, 28);
-	clks[IMX6SX_CLK_PWM7]         = imx_clk_gate2("pwm7",          "perclk",            base + 0x80, 30);
-
-	clks[IMX6SX_CLK_CKO1]         = imx_clk_gate("cko1",           "cko1_podf",         base + 0x60, 7);
-	clks[IMX6SX_CLK_CKO2]         = imx_clk_gate("cko2",           "cko2_podf",         base + 0x60, 24);
-
-	/* mask handshake of mmdc */
-	writel(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
-
-	clk_data.clks = clks;
-	clk_data.clk_num = ARRAY_SIZE(clks);
-	of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
-
-	if (IS_ENABLED(CONFIG_USB_IMX_PHY)) {
-		clk_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
-		clk_enable(clks[IMX6SX_CLK_USBPHY2_GATE]);
-	}
-
-	return 0;
-};
-
-static int imx6sx_clocks_init(void)
-{
-	if (!of_machine_is_compatible("fsl,imx6sx"))
-		return 0;
-
-	/* Set the default 132MHz for EIM module */
-	clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
-	clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000);
-
-	/* set parent clock for LCDIF1 pixel clock */
-	clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]);
-	clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]);
-
-	/*
-	 * Init enet system AHB clock, set to 200Mhz
-	 * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
-	 */
-	clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
-	clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]);
-	clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000);
-	clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000);
-	clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000);
-
-	/* Set parent clock for vadc */
-	clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
-
-	/* Update gpu clock from default 528M to 720M */
-	clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
-	clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
-
-	return 0;
-}
-coredevice_initcall(imx6sx_clocks_init);
-
-static __maybe_unused struct of_device_id imx6sx_ccm_dt_ids[] = {
-	{
-		.compatible = "fsl,imx6sx-ccm",
-	}, {
-		/* sentinel */
-	}
-};
-
-static struct driver_d imx6sx_ccm_driver = {
-	.probe	= imx6sx_ccm_probe,
-	.name	= "imx6-ccm",
-	.of_compatible = DRV_OF_COMPAT(imx6sx_ccm_dt_ids),
-};
-
-static int imx6sx_ccm_init(void)
-{
-	return platform_driver_register(&imx6sx_ccm_driver);
-}
-core_initcall(imx6sx_ccm_init);
diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c
deleted file mode 100644
index 8f6d5ad..0000000
--- a/arch/arm/mach-imx/clk-pfd.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Copyright 2012 Linaro Ltd.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <malloc.h>
-#include <asm-generic/div64.h>
-
-#include "clk.h"
-
-/**
- * struct clk_pfd - IMX PFD clock
- * @clk_hw:	clock source
- * @reg:	PFD register address
- * @idx:	the index of PFD encoded in the register
- *
- * PFD clock found on i.MX6 series.  Each register for PFD has 4 clk_pfd
- * data encoded, and member idx is used to specify the one.  And each
- * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
- */
-struct clk_pfd {
-	struct clk	clk;
-	void __iomem	*reg;
-	u8		idx;
-	const char	*parent;
-};
-
-#define to_clk_pfd(_clk) container_of(_clk, struct clk_pfd, clk)
-
-#define SET	0x4
-#define CLR	0x8
-#define OTG	0xc
-
-static int clk_pfd_enable(struct clk *clk)
-{
-	struct clk_pfd *pfd = to_clk_pfd(clk);
-	writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
-
-	return 0;
-}
-
-static void clk_pfd_disable(struct clk *clk)
-{
-	struct clk_pfd *pfd = to_clk_pfd(clk);
-
-	writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
-}
-
-static unsigned long clk_pfd_recalc_rate(struct clk *clk,
-					 unsigned long parent_rate)
-{
-	struct clk_pfd *pfd = to_clk_pfd(clk);
-	u64 tmp = parent_rate;
-	u8 frac = (readl(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
-
-	tmp *= 18;
-	do_div(tmp, frac);
-
-	return tmp;
-}
-
-static long clk_pfd_round_rate(struct clk *clk, unsigned long rate,
-			       unsigned long *prate)
-{
-	u64 tmp = *prate;
-	u8 frac;
-
-	tmp = tmp * 18 + rate / 2;
-	do_div(tmp, rate);
-	frac = tmp;
-	if (frac < 12)
-		frac = 12;
-	else if (frac > 35)
-		frac = 35;
-	tmp = *prate;
-	tmp *= 18;
-	do_div(tmp, frac);
-
-	return tmp;
-}
-
-static int clk_pfd_set_rate(struct clk *clk, unsigned long rate,
-		unsigned long parent_rate)
-{
-	struct clk_pfd *pfd = to_clk_pfd(clk);
-	u64 tmp = parent_rate;
-	u8 frac;
-
-	tmp = tmp * 18 + rate / 2;
-	do_div(tmp, rate);
-	frac = tmp;
-	if (frac < 12)
-		frac = 12;
-	else if (frac > 35)
-		frac = 35;
-
-	writel(0x3f << (pfd->idx * 8), pfd->reg + CLR);
-	writel(frac << (pfd->idx * 8), pfd->reg + SET);
-
-	return 0;
-}
-
-static const struct clk_ops clk_pfd_ops = {
-	.enable		= clk_pfd_enable,
-	.disable	= clk_pfd_disable,
-	.recalc_rate	= clk_pfd_recalc_rate,
-	.round_rate	= clk_pfd_round_rate,
-	.set_rate	= clk_pfd_set_rate,
-};
-
-struct clk *imx_clk_pfd(const char *name, const char *parent,
-			void __iomem *reg, u8 idx)
-{
-	struct clk_pfd *pfd;
-	int ret;
-
-	pfd = xzalloc(sizeof(*pfd));
-
-	pfd->reg = reg;
-	pfd->idx = idx;
-	pfd->parent = parent;
-	pfd->clk.name = name;
-	pfd->clk.ops = &clk_pfd_ops;
-	pfd->clk.parent_names = &pfd->parent;
-	pfd->clk.num_parents = 1;
-
-	ret = clk_register(&pfd->clk);
-	if (ret) {
-		free(pfd);
-		return ERR_PTR(ret);
-	}
-
-	return &pfd->clk;
-}
diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c
deleted file mode 100644
index f992134..0000000
--- a/arch/arm/mach-imx/clk-pllv1.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <malloc.h>
-#include <asm-generic/div64.h>
-
-#include "clk.h"
-
-struct clk_pllv1 {
-	struct clk clk;
-	void __iomem *reg;
-	const char *parent;
-};
-
-static unsigned long clk_pllv1_recalc_rate(struct clk *clk,
-		unsigned long parent_rate)
-{
-	struct clk_pllv1 *pll = container_of(clk, struct clk_pllv1, clk);
-	unsigned long long ll;
-	int mfn_abs;
-	unsigned int mfi, mfn, mfd, pd;
-	u32 reg_val = readl(pll->reg);
-	unsigned long freq = parent_rate;
-
-	mfi = (reg_val >> 10) & 0xf;
-	mfn = reg_val & 0x3ff;
-	mfd = (reg_val >> 16) & 0x3ff;
-	pd =  (reg_val >> 26) & 0xf;
-
-	mfi = mfi <= 5 ? 5 : mfi;
-
-	mfn_abs = mfn;
-
-#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21
-	if (mfn >= 0x200) {
-		mfn |= 0xFFFFFE00;
-		mfn_abs = -mfn;
-	}
-#endif
-
-	freq *= 2;
-	freq /= pd + 1;
-
-	ll = (unsigned long long)freq * mfn_abs;
-
-	do_div(ll, mfd + 1);
-	if (mfn < 0)
-		ll = (freq * mfi) - ll;
-	else
-		ll = (freq * mfi) + ll;
-
-	return ll;
-}
-
-struct clk_ops clk_pllv1_ops = {
-	.recalc_rate = clk_pllv1_recalc_rate,
-};
-
-struct clk *imx_clk_pllv1(const char *name, const char *parent,
-		void __iomem *base)
-{
-	struct clk_pllv1 *pll = xzalloc(sizeof(*pll));
-	int ret;
-
-	pll->parent = parent;
-	pll->reg = base;
-	pll->clk.ops = &clk_pllv1_ops;
-	pll->clk.name = name;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
-
-	ret = clk_register(&pll->clk);
-	if (ret) {
-		free(pll);
-		return ERR_PTR(ret);
-	}
-
-	return &pll->clk;
-}
diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c
deleted file mode 100644
index 5ba07fa..0000000
--- a/arch/arm/mach-imx/clk-pllv2.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <malloc.h>
-#include <asm-generic/div64.h>
-
-#include "clk.h"
-
-/* PLL Register Offsets */
-#define MXC_PLL_DP_CTL			0x00
-#define MXC_PLL_DP_CONFIG		0x04
-#define MXC_PLL_DP_OP			0x08
-#define MXC_PLL_DP_MFD			0x0C
-#define MXC_PLL_DP_MFN			0x10
-#define MXC_PLL_DP_MFNMINUS		0x14
-#define MXC_PLL_DP_MFNPLUS		0x18
-#define MXC_PLL_DP_HFS_OP		0x1C
-#define MXC_PLL_DP_HFS_MFD		0x20
-#define MXC_PLL_DP_HFS_MFN		0x24
-#define MXC_PLL_DP_MFN_TOGC		0x28
-#define MXC_PLL_DP_DESTAT		0x2c
-
-/* PLL Register Bit definitions */
-#define MXC_PLL_DP_CTL_MUL_CTRL		0x2000
-#define MXC_PLL_DP_CTL_DPDCK0_2_EN	0x1000
-#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET	12
-#define MXC_PLL_DP_CTL_ADE		0x800
-#define MXC_PLL_DP_CTL_REF_CLK_DIV	0x400
-#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK	(3 << 8)
-#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET	8
-#define MXC_PLL_DP_CTL_HFSM		0x80
-#define MXC_PLL_DP_CTL_PRE		0x40
-#define MXC_PLL_DP_CTL_UPEN		0x20
-#define MXC_PLL_DP_CTL_RST		0x10
-#define MXC_PLL_DP_CTL_RCP		0x8
-#define MXC_PLL_DP_CTL_PLM		0x4
-#define MXC_PLL_DP_CTL_BRM0		0x2
-#define MXC_PLL_DP_CTL_LRF		0x1
-
-#define MXC_PLL_DP_CONFIG_BIST		0x8
-#define MXC_PLL_DP_CONFIG_SJC_CE	0x4
-#define MXC_PLL_DP_CONFIG_AREN		0x2
-#define MXC_PLL_DP_CONFIG_LDREQ		0x1
-
-#define MXC_PLL_DP_OP_MFI_OFFSET	4
-#define MXC_PLL_DP_OP_MFI_MASK		(0xF << 4)
-#define MXC_PLL_DP_OP_PDF_OFFSET	0
-#define MXC_PLL_DP_OP_PDF_MASK		0xF
-
-#define MXC_PLL_DP_MFD_OFFSET		0
-#define MXC_PLL_DP_MFD_MASK		0x07FFFFFF
-
-#define MXC_PLL_DP_MFN_OFFSET		0x0
-#define MXC_PLL_DP_MFN_MASK		0x07FFFFFF
-
-#define MXC_PLL_DP_MFN_TOGC_TOG_DIS	(1 << 17)
-#define MXC_PLL_DP_MFN_TOGC_TOG_EN	(1 << 16)
-#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET	0x0
-#define MXC_PLL_DP_MFN_TOGC_CNT_MASK	0xFFFF
-
-#define MXC_PLL_DP_DESTAT_TOG_SEL	(1 << 31)
-#define MXC_PLL_DP_DESTAT_MFN		0x07FFFFFF
-
-#define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
-
-struct clk_pllv2 {
-	struct clk clk;
-	void __iomem *reg;
-	const char *parent;
-};
-
-static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
-		u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn)
-{
-	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
-	unsigned long dbl;
-	uint64_t temp;
-
-	dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
-
-	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
-	mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
-	mfi = (mfi <= 5) ? 5 : mfi;
-	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
-	mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
-	/* Sign extend to 32-bits */
-	if (mfn >= 0x04000000) {
-		mfn |= 0xFC000000;
-		mfn_abs = -mfn;
-	}
-
-	ref_clk = 2 * parent_rate;
-	if (dbl != 0)
-		ref_clk *= 2;
-
-	ref_clk /= (pdf + 1);
-	temp = (u64) ref_clk * mfn_abs;
-	do_div(temp, mfd + 1);
-	if (mfn < 0)
-		temp = (ref_clk * mfi) - temp;
-	else
-		temp = (ref_clk * mfi) + temp;
-
-	return temp;
-}
-
-static unsigned long clk_pllv2_recalc_rate(struct clk *clk,
-		unsigned long parent_rate)
-{
-	u32 dp_op, dp_mfd, dp_mfn, dp_ctl;
-	void __iomem *pllbase;
-	struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
-
-	pllbase = pll->reg;
-
-	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
-	dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
-	dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
-	dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
-
-	return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn);
-}
-
-static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate,
-		u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn)
-{
-	u32 reg;
-	long mfi, pdf, mfn, mfd = 999999;
-	u64 temp64;
-	unsigned long quad_parent_rate;
-
-	quad_parent_rate = 4 * parent_rate;
-	pdf = mfi = -1;
-	while (++pdf < 16 && mfi < 5)
-		mfi = rate * (pdf+1) / quad_parent_rate;
-	if (mfi > 15)
-		return -EINVAL;
-	pdf--;
-
-	temp64 = rate * (pdf + 1) - quad_parent_rate * mfi;
-	do_div(temp64, quad_parent_rate / 1000000);
-	mfn = (long)temp64;
-
-	reg = mfi << 4 | pdf;
-
-	*dp_op = reg;
-	*dp_mfd = mfd;
-	*dp_mfn = mfn;
-
-	return 0;
-}
-
-static int clk_pllv2_set_rate(struct clk *clk, unsigned long rate,
-		unsigned long parent_rate)
-{
-	struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
-	void __iomem *pllbase;
-	u32 dp_ctl, dp_op, dp_mfd, dp_mfn;
-	int ret;
-
-	pllbase = pll->reg;
-
-	ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn);
-	if (ret)
-		return ret;
-
-	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
-	/* use dpdck0_2 */
-	__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
-
-	__raw_writel(dp_op, pllbase + MXC_PLL_DP_OP);
-	__raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD);
-	__raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN);
-
-	return 0;
-}
-
-static long clk_pllv2_round_rate(struct clk *clk, unsigned long rate,
-		unsigned long *prate)
-{
-	u32 dp_op, dp_mfd, dp_mfn;
-
-	__clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn);
-	return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN,
-			dp_op, dp_mfd, dp_mfn);
-}
-
-struct clk_ops clk_pllv2_ops = {
-	.recalc_rate = clk_pllv2_recalc_rate,
-	.round_rate = clk_pllv2_round_rate,
-	.set_rate = clk_pllv2_set_rate,
-};
-
-struct clk *imx_clk_pllv2(const char *name, const char *parent,
-		void __iomem *base)
-{
-	struct clk_pllv2 *pll = xzalloc(sizeof(*pll));
-	int ret;
-
-	pll->parent = parent;
-	pll->reg = base;
-	pll->clk.ops = &clk_pllv2_ops;
-	pll->clk.name = name;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
-
-	ret = clk_register(&pll->clk);
-	if (ret) {
-		free(pll);
-		return ERR_PTR(ret);
-	}
-
-	return &pll->clk;
-}
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
deleted file mode 100644
index e38dcdf..0000000
--- a/arch/arm/mach-imx/clk-pllv3.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <malloc.h>
-#include <clock.h>
-#include <asm-generic/div64.h>
-
-#include "clk.h"
-
-#define PLL_NUM_OFFSET		0x10
-#define PLL_DENOM_OFFSET	0x20
-
-#define BM_PLL_POWER		(0x1 << 12)
-#define BM_PLL_ENABLE		(0x1 << 13)
-#define BM_PLL_BYPASS		(0x1 << 16)
-#define BM_PLL_LOCK		(0x1 << 31)
-
-struct clk_pllv3 {
-	struct clk	clk;
-	void __iomem	*base;
-	bool		powerup_set;
-	u32		div_mask;
-	const char	*parent;
-};
-
-#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
-
-static int clk_pllv3_enable(struct clk *clk)
-{
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
-	u32 val;
-	int timeout = 10000;
-
-	val = readl(pll->base);
-	val &= ~BM_PLL_BYPASS;
-	if (pll->powerup_set)
-		val |= BM_PLL_POWER;
-	else
-		val &= ~BM_PLL_POWER;
-	writel(val, pll->base);
-
-	/* Wait for PLL to lock */
-	while (timeout--) {
-		if (readl(pll->base) & BM_PLL_LOCK)
-			break;
-	}
-
-	if (!timeout)
-		return -ETIMEDOUT;
-
-	val = readl(pll->base);
-	val |= BM_PLL_ENABLE;
-	writel(val, pll->base);
-
-	return 0;
-}
-
-static void clk_pllv3_disable(struct clk *clk)
-{
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
-	u32 val;
-
-	val = readl(pll->base);
-	val &= ~BM_PLL_ENABLE;
-	writel(val, pll->base);
-
-	val |= BM_PLL_BYPASS;
-	if (pll->powerup_set)
-		val &= ~BM_PLL_POWER;
-	else
-		val |= BM_PLL_POWER;
-	writel(val, pll->base);
-}
-
-static unsigned long clk_pllv3_recalc_rate(struct clk *clk,
-					   unsigned long parent_rate)
-{
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
-	u32 div = readl(pll->base)  & pll->div_mask;
-
-	return (div == 1) ? parent_rate * 22 : parent_rate * 20;
-}
-
-static long clk_pllv3_round_rate(struct clk *clk, unsigned long rate,
-				 unsigned long *prate)
-{
-	unsigned long parent_rate = *prate;
-
-	return (rate >= parent_rate * 22) ? parent_rate * 22 :
-					    parent_rate * 20;
-}
-
-static int clk_pllv3_set_rate(struct clk *clk, unsigned long rate,
-		unsigned long parent_rate)
-{
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
-	u32 val, div;
-
-	if (rate == parent_rate * 22)
-		div = 1;
-	else if (rate == parent_rate * 20)
-		div = 0;
-	else
-		return -EINVAL;
-
-	val = readl(pll->base);
-	val &= ~pll->div_mask;
-	val |= div;
-	writel(val, pll->base);
-
-	return 0;
-}
-
-static const struct clk_ops clk_pllv3_ops = {
-	.enable		= clk_pllv3_enable,
-	.disable	= clk_pllv3_disable,
-	.recalc_rate	= clk_pllv3_recalc_rate,
-	.round_rate	= clk_pllv3_round_rate,
-	.set_rate	= clk_pllv3_set_rate,
-};
-
-static unsigned long clk_pllv3_sys_recalc_rate(struct clk *clk,
-					       unsigned long parent_rate)
-{
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
-	u32 div = readl(pll->base) & pll->div_mask;
-
-	return parent_rate * div / 2;
-}
-
-static long clk_pllv3_sys_round_rate(struct clk *clk, unsigned long rate,
-				     unsigned long *prate)
-{
-	unsigned long parent_rate = *prate;
-	unsigned long min_rate = parent_rate * 54 / 2;
-	unsigned long max_rate = parent_rate * 108 / 2;
-	u32 div;
-
-	if (rate > max_rate)
-		rate = max_rate;
-	else if (rate < min_rate)
-		rate = min_rate;
-	div = rate * 2 / parent_rate;
-
-	return parent_rate * div / 2;
-}
-
-static int clk_pllv3_sys_set_rate(struct clk *clk, unsigned long rate,
-		unsigned long parent_rate)
-{
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
-	unsigned long min_rate = parent_rate * 54 / 2;
-	unsigned long max_rate = parent_rate * 108 / 2;
-	u32 val, div;
-
-	if (rate < min_rate || rate > max_rate)
-		return -EINVAL;
-
-	div = rate * 2 / parent_rate;
-	val = readl(pll->base);
-	val &= ~pll->div_mask;
-	val |= div;
-	writel(val, pll->base);
-
-	return 0;
-}
-
-static const struct clk_ops clk_pllv3_sys_ops = {
-	.enable		= clk_pllv3_enable,
-	.disable	= clk_pllv3_disable,
-	.recalc_rate	= clk_pllv3_sys_recalc_rate,
-	.round_rate	= clk_pllv3_sys_round_rate,
-	.set_rate	= clk_pllv3_sys_set_rate,
-};
-
-static unsigned long clk_pllv3_av_recalc_rate(struct clk *clk,
-					      unsigned long parent_rate)
-{
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
-	u32 mfn = readl(pll->base + PLL_NUM_OFFSET);
-	u32 mfd = readl(pll->base + PLL_DENOM_OFFSET);
-	u32 div = readl(pll->base) & pll->div_mask;
-
-	return (parent_rate * div) + ((parent_rate / mfd) * mfn);
-}
-
-static long clk_pllv3_av_round_rate(struct clk *clk, unsigned long rate,
-				    unsigned long *prate)
-{
-	unsigned long parent_rate = *prate;
-	unsigned long min_rate = parent_rate * 27;
-	unsigned long max_rate = parent_rate * 54;
-	u32 div;
-	u32 mfn, mfd = 1000000;
-	u64 temp64;
-
-	if (rate > max_rate)
-		rate = max_rate;
-	else if (rate < min_rate)
-		rate = min_rate;
-
-	div = rate / parent_rate;
-	temp64 = (u64) (rate - div * parent_rate);
-	temp64 *= mfd;
-	do_div(temp64, parent_rate);
-	mfn = temp64;
-
-	return parent_rate * div + parent_rate / mfd * mfn;
-}
-
-static int clk_pllv3_av_set_rate(struct clk *clk, unsigned long rate,
-		unsigned long parent_rate)
-{
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
-	unsigned long min_rate = parent_rate * 27;
-	unsigned long max_rate = parent_rate * 54;
-	u32 val, div;
-	u32 mfn, mfd = 1000000;
-	u64 temp64;
-
-	if (rate < min_rate || rate > max_rate)
-		return -EINVAL;
-
-	div = rate / parent_rate;
-	temp64 = (u64) (rate - div * parent_rate);
-	temp64 *= mfd;
-	do_div(temp64, parent_rate);
-	mfn = temp64;
-
-	val = readl(pll->base);
-	val &= ~pll->div_mask;
-	val |= div;
-	writel(val, pll->base);
-	writel(mfn, pll->base + PLL_NUM_OFFSET);
-	writel(mfd, pll->base + PLL_DENOM_OFFSET);
-
-	return 0;
-}
-
-static const struct clk_ops clk_pllv3_av_ops = {
-	.enable		= clk_pllv3_enable,
-	.disable	= clk_pllv3_disable,
-	.recalc_rate	= clk_pllv3_av_recalc_rate,
-	.round_rate	= clk_pllv3_av_round_rate,
-	.set_rate	= clk_pllv3_av_set_rate,
-};
-
-static unsigned long clk_pllv3_enet_recalc_rate(struct clk *clk,
-						unsigned long parent_rate)
-{
-	return 500000000;
-}
-
-static const struct clk_ops clk_pllv3_enet_ops = {
-	.enable		= clk_pllv3_enable,
-	.disable	= clk_pllv3_disable,
-	.recalc_rate	= clk_pllv3_enet_recalc_rate,
-};
-
-static const struct clk_ops clk_pllv3_mlb_ops = {
-	.enable		= clk_pllv3_enable,
-	.disable	= clk_pllv3_disable,
-};
-
-struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
-			  const char *parent, void __iomem *base,
-			  u32 div_mask)
-{
-	struct clk_pllv3 *pll;
-	const struct clk_ops *ops;
-	int ret;
-
-	pll = xzalloc(sizeof(*pll));
-
-	switch (type) {
-	case IMX_PLLV3_SYS:
-		ops = &clk_pllv3_sys_ops;
-		break;
-	case IMX_PLLV3_USB:
-		ops = &clk_pllv3_ops;
-		pll->powerup_set = true;
-		break;
-	case IMX_PLLV3_AV:
-		ops = &clk_pllv3_av_ops;
-		break;
-	case IMX_PLLV3_ENET:
-		ops = &clk_pllv3_enet_ops;
-		break;
-	case IMX_PLLV3_MLB:
-		ops = &clk_pllv3_mlb_ops;
-		break;
-	default:
-		ops = &clk_pllv3_ops;
-	}
-	pll->base = base;
-	pll->div_mask = div_mask;
-	pll->parent = parent;
-	pll->clk.ops = ops;
-	pll->clk.name = name;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
-
-	ret = clk_register(&pll->clk);
-	if (ret) {
-		free(pll);
-		return ERR_PTR(ret);
-	}
-
-	return &pll->clk;
-}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
deleted file mode 100644
index c5913e1..0000000
--- a/arch/arm/mach-imx/clk.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef __IMX_CLK_H
-#define __IMX_CLK_H
-
-struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
-		u8 shift);
-
-static inline struct clk *imx_clk_divider(const char *name, const char *parent,
-		void __iomem *reg, u8 shift, u8 width)
-{
-	return clk_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT);
-}
-
-static inline struct clk *imx_clk_divider_np(const char *name, const char *parent,
-		void __iomem *reg, u8 shift, u8 width)
-{
-	return clk_divider(name, parent, reg, shift, width, 0);
-}
-
-static inline struct clk *imx_clk_divider_table(const char *name,
-		const char *parent, void __iomem *reg, u8 shift, u8 width,
-		const struct clk_div_table *table)
-{
-	return clk_divider_table(name, parent, reg, shift, width, table,
-			CLK_SET_RATE_PARENT);
-}
-
-static inline struct clk *imx_clk_fixed_factor(const char *name,
-		const char *parent, unsigned int mult, unsigned int div)
-{
-	return clk_fixed_factor(name, parent, mult, div, CLK_SET_RATE_PARENT);
-}
-
-static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
-		u8 shift, u8 width, const char **parents, u8 num_parents)
-{
-	return clk_mux(name, reg, shift, width, parents, num_parents, 0);
-}
-
-static inline struct clk *imx_clk_mux_p(const char *name, void __iomem *reg,
-		u8 shift, u8 width, const char **parents, u8 num_parents)
-{
-	return clk_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT);
-}
-
-static inline struct clk *imx_clk_gate(const char *name, const char *parent,
-		void __iomem *reg, u8 shift)
-{
-	return clk_gate(name, parent, reg, shift, CLK_SET_RATE_PARENT, 0);
-}
-
-static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
-		void __iomem *reg, u8 shift)
-{
-	return clk_gate2(name, parent, reg, shift);
-}
-
-struct clk *imx_clk_pllv1(const char *name, const char *parent,
-		void __iomem *base);
-
-struct clk *imx_clk_pllv2(const char *name, const char *parent,
-		void __iomem *base);
-
-enum imx_pllv3_type {
-	IMX_PLLV3_GENERIC,
-	IMX_PLLV3_SYS,
-	IMX_PLLV3_USB,
-	IMX_PLLV3_AV,
-	IMX_PLLV3_ENET,
-	IMX_PLLV3_MLB,
-};
-
-struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
-			  const char *parent, void __iomem *base,
-			  u32 div_mask);
-
-struct clk *imx_clk_pfd(const char *name, const char *parent,
-			void __iomem *reg, u8 idx);
-
-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)
-{
-	/*
-	 * For now we do not support rate setting, so just fall back to
-	 * regular divider.
-	 */
-	return imx_clk_divider(name, parent, reg, shift, width);
-}
-
-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 **parents, int num_parents)
-{
-	/*
-	 * For now we do not support mux switching, so just fall back to
-	 * regular mux.
-	 */
-	return imx_clk_mux(name, reg, shift, width, parents, num_parents);
-}
-
-struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
-		void __iomem *reg, u8 shift, u32 exclusive_mask);
-
-#endif /* __IMX_CLK_H */
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 0fe8f1e..a4e4ed0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_ARCH_ROCKCHIP)	+= rockchip/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_CLK_SOCFPGA)	+= socfpga.o
 obj-$(CONFIG_MACH_MIPS_ATH79)	+= clk-ar933x.o
+obj-$(CONFIG_ARCH_IMX)		+= imx/
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
new file mode 100644
index 0000000..893a1a5
--- /dev/null
+++ b/drivers/clk/imx/Makefile
@@ -0,0 +1,21 @@
+obj-$(CONFIG_COMMON_CLK) +=	\
+	clk-pllv1.o		\
+	clk-pllv2.o		\
+	clk-pllv3.o		\
+	clk-pfd.o		\
+	clk-gate2.o		\
+	clk-gate-exclusive.o
+
+obj-$(CONFIG_ARCH_IMX1)   += clk-imx1.o
+obj-$(CONFIG_ARCH_IMX25)  += clk-imx25.o
+obj-$(CONFIG_ARCH_IMX21)  += clk-imx21.o
+obj-$(CONFIG_ARCH_IMX27)  += clk-imx27.o
+obj-$(CONFIG_ARCH_IMX31)  += clk-imx31.o
+obj-$(CONFIG_ARCH_IMX35)  += clk-imx35.o
+obj-$(CONFIG_ARCH_IMX50)  += clk-imx5.o
+obj-$(CONFIG_ARCH_IMX51)  += clk-imx5.o
+obj-$(CONFIG_ARCH_IMX53)  += clk-imx5.o
+obj-$(CONFIG_ARCH_IMX6)   += clk-imx6.o
+obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
+
+
diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c
new file mode 100644
index 0000000..db88db0
--- /dev/null
+++ b/drivers/clk/imx/clk-gate-exclusive.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <io.h>
+#include <malloc.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include "clk.h"
+
+/**
+ * struct clk_gate_exclusive - i.MX specific gate clock which is mutually
+ * exclusive with other gate clocks
+ *
+ * @gate: the parent class
+ * @exclusive_mask: mask of gate bits which are mutually exclusive to this
+ *	gate clock
+ *
+ * The imx exclusive gate clock is a subclass of basic clk_gate
+ * with an addtional mask to indicate which other gate bits in the same
+ * register is mutually exclusive to this gate clock.
+ */
+struct clk_gate_exclusive {
+	struct clk clk;
+	void __iomem *reg;
+	int shift;
+	const char *parent;
+	u32 exclusive_mask;
+};
+
+static int clk_gate_exclusive_enable(struct clk *clk)
+{
+	struct clk_gate_exclusive *exgate = container_of(clk,
+					struct clk_gate_exclusive, clk);
+	u32 val = readl(exgate->reg);
+
+	if (val & exgate->exclusive_mask)
+		return -EBUSY;
+
+	val |= 1 << exgate->shift;
+
+	writel(val, exgate->reg);
+
+	return 0;
+}
+
+static void clk_gate_exclusive_disable(struct clk *clk)
+{
+	struct clk_gate_exclusive *exgate = container_of(clk,
+					struct clk_gate_exclusive, clk);
+	u32 val = readl(exgate->reg);
+
+	val &= ~(1 << exgate->shift);
+
+	writel(val, exgate->reg);
+}
+
+static int clk_gate_exclusive_is_enabled(struct clk *clk)
+{
+	struct clk_gate_exclusive *exgate = container_of(clk,
+					struct clk_gate_exclusive, clk);
+
+	return readl(exgate->reg) & (1 << exgate->shift);
+}
+
+static const struct clk_ops clk_gate_exclusive_ops = {
+	.enable = clk_gate_exclusive_enable,
+	.disable = clk_gate_exclusive_disable,
+	.is_enabled = clk_gate_exclusive_is_enabled,
+};
+
+struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
+	 void __iomem *reg, u8 shift, u32 exclusive_mask)
+{
+	struct clk_gate_exclusive *exgate;
+	int ret;
+
+	exgate = xzalloc(sizeof(*exgate));
+	exgate->parent = parent;
+	exgate->clk.name = name;
+	exgate->clk.ops = &clk_gate_exclusive_ops;
+	exgate->clk.flags = CLK_SET_RATE_PARENT;
+	exgate->clk.parent_names = &exgate->parent;
+	exgate->clk.num_parents = 1;
+
+	exgate->reg = reg;
+	exgate->shift = shift;
+	exgate->exclusive_mask = exclusive_mask;
+
+	ret = clk_register(&exgate->clk);
+	if (ret) {
+		free(exgate);
+		return ERR_PTR(ret);
+	}
+
+	return &exgate->clk;
+}
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
new file mode 100644
index 0000000..faed631
--- /dev/null
+++ b/drivers/clk/imx/clk-gate2.c
@@ -0,0 +1,145 @@
+/*
+ * clk-gate2.c - barebox 2-bit clock support. Based on Linux clk support
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <io.h>
+#include <malloc.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include "clk.h"
+
+
+struct clk_gate2 {
+	struct clk clk;
+	void __iomem *reg;
+	int shift;
+	const char *parent;
+#define CLK_GATE_INVERTED	(1 << 0)
+	unsigned flags;
+};
+
+#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
+
+static int clk_gate2_enable(struct clk *clk)
+{
+	struct clk_gate2 *g = to_clk_gate2(clk);
+	u32 val;
+
+	val = readl(g->reg);
+
+	if (g->flags & CLK_GATE_INVERTED)
+		val &= ~(3 << g->shift);
+	else
+		val |= 3 << g->shift;
+
+	writel(val, g->reg);
+
+	return 0;
+}
+
+static void clk_gate2_disable(struct clk *clk)
+{
+	struct clk_gate2 *g = to_clk_gate2(clk);
+	u32 val;
+
+	val = readl(g->reg);
+
+	if (g->flags & CLK_GATE_INVERTED)
+		val |= 3 << g->shift;
+	else
+		val &= ~(3 << g->shift);
+
+	writel(val, g->reg);
+}
+
+static int clk_gate2_is_enabled(struct clk *clk)
+{
+	struct clk_gate2 *g = to_clk_gate2(clk);
+	u32 val;
+
+	val = readl(g->reg);
+
+	if (val & (1 << g->shift))
+		return g->flags & CLK_GATE_INVERTED ? 0 : 1;
+	else
+		return g->flags & CLK_GATE_INVERTED ? 1 : 0;
+}
+
+static struct clk_ops clk_gate2_ops = {
+	.set_rate = clk_parent_set_rate,
+	.round_rate = clk_parent_round_rate,
+	.enable = clk_gate2_enable,
+	.disable = clk_gate2_disable,
+	.is_enabled = clk_gate2_is_enabled,
+};
+
+struct clk *clk_gate2_alloc(const char *name, const char *parent,
+		void __iomem *reg, u8 shift)
+{
+	struct clk_gate2 *g = xzalloc(sizeof(*g));
+
+	g->parent = parent;
+	g->reg = reg;
+	g->shift = shift;
+	g->clk.ops = &clk_gate2_ops;
+	g->clk.name = name;
+	g->clk.parent_names = &g->parent;
+	g->clk.num_parents = 1;
+	g->clk.flags = CLK_SET_RATE_PARENT;
+
+	return &g->clk;
+}
+
+void clk_gate2_free(struct clk *clk)
+{
+	struct clk_gate2 *g = to_clk_gate2(clk);
+
+	free(g);
+}
+
+struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
+		u8 shift)
+{
+	struct clk *g;
+	int ret;
+
+	g = clk_gate2_alloc(name , parent, reg, shift);
+
+	ret = clk_register(g);
+	if (ret) {
+		free(to_clk_gate2(g));
+		return ERR_PTR(ret);
+	}
+
+	return g;
+}
+
+struct clk *clk_gate2_inverted(const char *name, const char *parent,
+		void __iomem *reg, u8 shift)
+{
+	struct clk *clk;
+	struct clk_gate2 *g;
+
+	clk = clk_gate2(name, parent, reg, shift);
+	if (IS_ERR(clk))
+		return clk;
+
+	g = to_clk_gate2(clk);
+
+	g->flags = CLK_GATE_INVERTED;
+
+	return clk;
+}
diff --git a/drivers/clk/imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c
new file mode 100644
index 0000000..5f600a9
--- /dev/null
+++ b/drivers/clk/imx/clk-imx1.c
@@ -0,0 +1,121 @@
+/*
+ *  Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx1-regs.h>
+
+#include "clk.h"
+
+#define CCM_CSCR	0x0
+#define CCM_MPCTL0	0x4
+#define CCM_SPCTL0	0xc
+#define CCM_PCDR	0x20
+
+enum imx1_clks {
+	dummy, clk32, clk16m, clk32_premult, prem, mpll, spll, mcu,
+	fclk, hclk, clk48m, per1, per2, per3, clko, dma_gate, csi_gate,
+	mma_gate, usbd_gate, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *prem_sel_clks[] = {
+	"clk32_premult",
+	"clk16m",
+};
+
+static const char *clko_sel_clks[] = {
+	"per1",
+	"hclk",
+	"clk48m",
+	"clk16m",
+	"prem",
+	"fclk",
+};
+
+int __init mx1_clocks_init(void __iomem *regs, unsigned long fref)
+{
+	clks[dummy] = clk_fixed("dummy", 0);
+	clks[clk32] = clk_fixed("clk32", fref);
+	clks[clk16m] = clk_fixed("clk16m", 16000000);
+	clks[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
+	clks[prem] = imx_clk_mux("prem", regs + CCM_CSCR, 16, 1, prem_sel_clks,
+			ARRAY_SIZE(prem_sel_clks));
+	clks[mpll] = imx_clk_pllv1("mpll", "clk32_premult", regs + CCM_MPCTL0);
+	clks[spll] = imx_clk_pllv1("spll", "prem", regs + CCM_SPCTL0);
+	clks[mcu] = imx_clk_divider("mcu", "clk32_premult", regs + CCM_CSCR, 15, 1);
+	clks[fclk] = imx_clk_divider("fclk", "mpll", regs + CCM_CSCR, 15, 1);
+	clks[hclk] = imx_clk_divider("hclk", "spll", regs + CCM_CSCR, 10, 4);
+	clks[clk48m] = imx_clk_divider("clk48m", "spll", regs + CCM_CSCR, 26, 3);
+	clks[per1] = imx_clk_divider("per1", "spll", regs + CCM_PCDR, 0, 4);
+	clks[per2] = imx_clk_divider("per2", "spll", regs + CCM_PCDR, 4, 4);
+	clks[per3] = imx_clk_divider("per3", "spll", regs + CCM_PCDR, 16, 7);
+	clks[clko] = imx_clk_mux("clko", regs + CCM_CSCR, 29, 3, clko_sel_clks,
+			ARRAY_SIZE(clko_sel_clks));
+
+	clkdev_add_physbase(clks[per1], MX1_TIM1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1], MX1_TIM2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per2], MX1_LCDC_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1], MX1_UART1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1], MX1_UART2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per2], MX1_CSPI1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per2], MX1_CSPI2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[hclk], MX1_I2C_BASE_ADDR, NULL);
+
+	return 0;
+}
+
+static int imx1_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *regs;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	regs = IOMEM(iores->start);
+
+	mx1_clocks_init(regs, 32000);
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx1_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx1-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx1_ccm_driver = {
+	.probe	= imx1_ccm_probe,
+	.name	= "imx1-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx1_ccm_dt_ids),
+};
+
+static int imx1_ccm_init(void)
+{
+	return platform_driver_register(&imx1_ccm_driver);
+}
+core_initcall(imx1_ccm_init);
diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c
new file mode 100644
index 0000000..546461b
--- /dev/null
+++ b/drivers/clk/imx/clk-imx21.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx21-regs.h>
+
+#include "clk.h"
+
+/* Register offsets */
+#define CCM_CSCR		0x0
+#define CCM_MPCTL0		0x4
+#define CCM_MPCTL1		0x8
+#define CCM_SPCTL0		0xc
+#define CCM_SPCTL1		0x10
+#define CCM_OSC26MCTL		0x14
+#define CCM_PCDR0		0x18
+#define CCM_PCDR1		0x1c
+#define CCM_PCCR0		0x20
+#define CCM_PCCR1		0x24
+#define CCM_CCSR		0x28
+#define CCM_PMCTL		0x2c
+#define CCM_PMCOUNT		0x30
+#define CCM_WKGDCTL		0x34
+
+#define PCCR0_UART1_EN		(1 << 0)
+#define PCCR0_UART2_EN		(1 << 1)
+#define PCCR0_UART3_EN		(1 << 2)
+#define PCCR0_UART4_EN		(1 << 3)
+#define PCCR0_CSPI1_EN		(1 << 4)
+#define PCCR0_CSPI2_EN		(1 << 5)
+#define PCCR0_SSI1_EN		(1 << 6)
+#define PCCR0_SSI2_EN		(1 << 7)
+#define PCCR0_FIRI_EN		(1 << 8)
+#define PCCR0_SDHC1_EN		(1 << 9)
+#define PCCR0_SDHC2_EN		(1 << 10)
+#define PCCR0_GPIO_EN		(1 << 11)
+#define PCCR0_I2C_EN		(1 << 12)
+#define PCCR0_DMA_EN		(1 << 13)
+#define PCCR0_USBOTG_EN		(1 << 14)
+#define PCCR0_EMMA_EN		(1 << 15)
+#define PCCR0_SSI2_BAUD_EN	(1 << 16)
+#define PCCR0_SSI1_BAUD_EN	(1 << 17)
+#define PCCR0_PERCLK3_EN	(1 << 18)
+#define PCCR0_NFC_EN		(1 << 19)
+#define PCCR0_FRI_BAUD_EN	(1 << 20)
+#define PCCR0_SLDC_EN		(1 << 21)
+#define PCCR0_PERCLK4_EN	(1 << 22)
+#define PCCR0_HCLK_BMI_EN	(1 << 23)
+#define PCCR0_HCLK_USBOTG_EN	(1 << 24)
+#define PCCR0_HCLK_SLCDC_EN	(1 << 25)
+#define PCCR0_HCLK_LCDC_EN	(1 << 26)
+#define PCCR0_HCLK_EMMA_EN	(1 << 27)
+#define PCCR0_HCLK_BROM_EN	(1 << 28)
+#define PCCR0_HCLK_DMA_EN	(1 << 30)
+#define PCCR0_HCLK_CSI_EN	(1 << 31)
+
+#define PCCR1_CSPI3_EN	(1 << 23)
+#define PCCR1_WDT_EN	(1 << 24)
+#define PCCR1_GPT1_EN	(1 << 25)
+#define PCCR1_GPT2_EN	(1 << 26)
+#define PCCR1_GPT3_EN	(1 << 27)
+#define PCCR1_PWM_EN	(1 << 28)
+#define PCCR1_RTC_EN	(1 << 29)
+#define PCCR1_KPP_EN	(1 << 30)
+#define PCCR1_OWIRE_EN	(1 << 31)
+
+enum imx21_clks {
+	ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1,
+	per2, per3, per4, usb_div, nfc_div, lcdc_per_gate, lcdc_ahb_gate,
+	lcdc_ipg_gate, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *mpll_sel_clks[] = {
+	"fpm",
+	"ckih",
+};
+
+static const char *spll_sel_clks[] = {
+	"fpm",
+	"ckih",
+};
+
+static int imx21_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *base;
+	unsigned long lref = 32768;
+	unsigned long href = 26000000;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	base = IOMEM(iores->start);
+
+	writel(PCCR0_UART1_EN | PCCR0_UART2_EN | PCCR0_UART3_EN | PCCR0_UART4_EN |
+			PCCR0_CSPI1_EN | PCCR0_CSPI2_EN | PCCR0_SDHC1_EN |
+			PCCR0_SDHC2_EN | PCCR0_GPIO_EN | PCCR0_I2C_EN | PCCR0_DMA_EN |
+			PCCR0_USBOTG_EN | PCCR0_NFC_EN | PCCR0_PERCLK4_EN |
+			PCCR0_HCLK_USBOTG_EN | PCCR0_HCLK_DMA_EN,
+			base + CCM_PCCR0);
+
+	writel(PCCR1_CSPI3_EN | PCCR1_WDT_EN | PCCR1_GPT1_EN | PCCR1_GPT2_EN |
+			PCCR1_GPT3_EN | PCCR1_PWM_EN | PCCR1_RTC_EN | PCCR1_KPP_EN |
+			PCCR1_OWIRE_EN,
+			base + CCM_PCCR1);
+
+	clks[ckil] = clk_fixed("ckil", lref);
+	clks[ckih] = clk_fixed("ckih", href);
+	clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
+	clks[mpll_sel] = imx_clk_mux("mpll_sel", base + CCM_CSCR, 16, 1, mpll_sel_clks,
+			ARRAY_SIZE(mpll_sel_clks));
+	clks[spll_sel] = imx_clk_mux("spll_sel", base + CCM_CSCR, 17, 1, spll_sel_clks,
+			ARRAY_SIZE(spll_sel_clks));
+	clks[mpll] = imx_clk_pllv1("mpll", "mpll_sel", base + CCM_MPCTL0);
+	clks[spll] = imx_clk_pllv1("spll", "spll_sel", base + CCM_SPCTL0);
+	clks[fclk] = imx_clk_divider("fclk", "mpll", base + CCM_CSCR, 29, 3);
+	clks[hclk] = imx_clk_divider("hclk", "fclk", base + CCM_CSCR, 10, 4);
+	clks[ipg] = imx_clk_divider("ipg", "hclk", base + CCM_CSCR, 9, 1);
+	clks[per1] = imx_clk_divider("per1", "mpll", base + CCM_PCDR1, 0, 6);
+	clks[per2] = imx_clk_divider("per2", "mpll", base + CCM_PCDR1, 8, 6);
+	clks[per3] = imx_clk_divider("per3", "mpll", base + CCM_PCDR1, 16, 6);
+	clks[per4] = imx_clk_divider("per4", "mpll", base + CCM_PCDR1, 24, 6);
+	clks[usb_div] = imx_clk_divider("usb_div", "spll", base + CCM_CSCR, 26, 3);
+	clks[nfc_div] = imx_clk_divider("nfc_div", "ipg", base + CCM_PCDR0, 12, 4);
+	clks[lcdc_per_gate] = imx_clk_gate("lcdc_per_gate", "per3", base + CCM_PCCR0, 18);
+	clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR0, 26);
+	/*
+	 * i.MX21 doesn't have an IPG clock for the LCD. To avoid even more conditionals
+	 * in the framebuffer code, provide a dummy clock.
+	 */
+	clks[lcdc_ipg_gate] = clk_fixed("dummy", 0);
+
+	clkdev_add_physbase(clks[per1], MX21_GPT1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1], MX21_GPT2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1], MX21_GPT3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1], MX21_UART1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1], MX21_UART2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1], MX21_UART3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1], MX21_UART4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per2], MX21_CSPI1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per2], MX21_CSPI2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per2], MX21_CSPI3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX21_I2C_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX21_SDHC1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX21_SDHC2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[lcdc_per_gate], MX21_LCDC_BASE_ADDR, "per");
+	clkdev_add_physbase(clks[lcdc_ahb_gate], MX21_LCDC_BASE_ADDR, "ahb");
+	clkdev_add_physbase(clks[lcdc_ipg_gate], MX21_LCDC_BASE_ADDR, "ipg");
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx21_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx21-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx21_ccm_driver = {
+	.probe	= imx21_ccm_probe,
+	.name	= "imx21-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx21_ccm_dt_ids),
+};
+
+static int imx21_ccm_init(void)
+{
+	return platform_driver_register(&imx21_ccm_driver);
+}
+core_initcall(imx21_ccm_init);
diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c
new file mode 100644
index 0000000..864d06e
--- /dev/null
+++ b/drivers/clk/imx/clk-imx25.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx25-regs.h>
+
+#include "clk.h"
+
+#define CCM_MPCTL	0x00
+#define CCM_UPCTL	0x04
+#define CCM_CCTL	0x08
+#define CCM_CGCR0	0x0C
+#define CCM_CGCR1	0x10
+#define CCM_CGCR2	0x14
+#define CCM_PCDR0	0x18
+#define CCM_PCDR1	0x1C
+#define CCM_PCDR2	0x20
+#define CCM_PCDR3	0x24
+#define CCM_RCSR	0x28
+#define CCM_CRDR	0x2C
+#define CCM_DCVR0	0x30
+#define CCM_DCVR1	0x34
+#define CCM_DCVR2	0x38
+#define CCM_DCVR3	0x3c
+#define CCM_LTR0	0x40
+#define CCM_LTR1	0x44
+#define CCM_LTR2	0x48
+#define CCM_LTR3	0x4c
+#define CCM_MCR		0x64
+
+enum mx25_clks {
+	dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg,
+	per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel,
+	per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
+	per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
+	per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
+	csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per,
+	gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per,
+	pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per,
+	uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb,
+	esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb,
+	reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg, csi_ipg,
+	cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg,
+	reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9,
+	gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12,
+	iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg,
+	pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg,
+	sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg,
+	uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17,
+	wdt_ipg, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *cpu_sel_clks[] = {
+	"mpll",
+	"mpll_cpu_3_4",
+};
+
+static const char *per_sel_clks[] = {
+	"ahb",
+	"upll",
+};
+
+static int imx25_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *base;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	base = IOMEM(iores->start);
+
+	writel((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 8) | (1 << 9) |
+			(1 << 10) | (1 << 15) |	(1 << 19) | (1 << 21) | (1 << 22) |
+			(1 << 23) | (1 << 24) | (1 << 28),
+			base + CCM_CGCR0);
+
+	writel((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 13) | (1 << 14) |
+			(1 << 15) | (1 << 19) | (1 << 20) | (1 << 21) | (1 << 22) |
+			(1 << 26) | (1 << 31),
+			base + CCM_CGCR1);
+
+	writel((1 << 0) | (1 << 1) | (1 << 2) | (1 << 10) | (1 << 13) | (1 << 14) |
+			(1 << 15) | (1 << 16) | (1 << 17) | (1 << 18),
+			base + CCM_CGCR2);
+
+	clks[dummy] = clk_fixed("dummy", 0);
+	clks[osc] = clk_fixed("osc", 24000000);
+	clks[mpll] = imx_clk_pllv1("mpll", "osc", base + CCM_MPCTL);
+	clks[upll] = imx_clk_pllv1("upll", "osc", base + CCM_UPCTL);
+	clks[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
+	clks[cpu_sel] = imx_clk_mux("cpu_sel", base + CCM_CCTL, 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
+	clks[cpu] = imx_clk_divider("cpu", "cpu_sel", base + CCM_CCTL, 30, 2);
+	clks[ahb] = imx_clk_divider("ahb", "cpu", base + CCM_CCTL, 28, 2);
+	clks[usb_div] = imx_clk_divider("usb_div", "upll", base + CCM_CCTL, 16, 6);
+	clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+	clks[per0_sel] = imx_clk_mux("per0_sel", base + CCM_MCR, 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per1_sel] = imx_clk_mux("per1_sel", base + CCM_MCR, 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per2_sel] = imx_clk_mux("per2_sel", base + CCM_MCR, 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per3_sel] = imx_clk_mux("per3_sel", base + CCM_MCR, 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per4_sel] = imx_clk_mux("per4_sel", base + CCM_MCR, 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per5_sel] = imx_clk_mux("per5_sel", base + CCM_MCR, 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per6_sel] = imx_clk_mux("per6_sel", base + CCM_MCR, 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per7_sel] = imx_clk_mux("per7_sel", base + CCM_MCR, 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per8_sel] = imx_clk_mux("per8_sel", base + CCM_MCR, 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per9_sel] = imx_clk_mux("per9_sel", base + CCM_MCR, 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per10_sel] = imx_clk_mux("per10_sel", base + CCM_MCR, 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per11_sel] = imx_clk_mux("per11_sel", base + CCM_MCR, 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per12_sel] = imx_clk_mux("per12_sel", base + CCM_MCR, 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per13_sel] = imx_clk_mux("per13_sel", base + CCM_MCR, 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per14_sel] = imx_clk_mux("per14_sel", base + CCM_MCR, 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per15_sel] = imx_clk_mux("per15_sel", base + CCM_MCR, 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	clks[per0] = imx_clk_divider("per0", "per0_sel", base + CCM_PCDR0, 0, 6);
+	clks[per1] = imx_clk_divider("per1", "per1_sel", base + CCM_PCDR0, 8, 6);
+	clks[per2] = imx_clk_divider("per2", "per2_sel", base + CCM_PCDR0, 16, 6);
+	clks[per3] = imx_clk_divider("per3", "per3_sel", base + CCM_PCDR0, 24, 6);
+	clks[per4] = imx_clk_divider("per4", "per4_sel", base + CCM_PCDR1, 0, 6);
+	clks[per5] = imx_clk_divider("per5", "per5_sel", base + CCM_PCDR1, 8, 6);
+	clks[per6] = imx_clk_divider("per6", "per6_sel", base + CCM_PCDR1, 16, 6);
+	clks[per7] = imx_clk_divider("per7", "per7_sel", base + CCM_PCDR1, 24, 6);
+	clks[per8] = imx_clk_divider("per8", "per8_sel", base + CCM_PCDR2, 0, 6);
+	clks[per9] = imx_clk_divider("per9", "per9_sel", base + CCM_PCDR2, 8, 6);
+	clks[per10] = imx_clk_divider("per10", "per10_sel", base + CCM_PCDR2, 16, 6);
+	clks[per11] = imx_clk_divider("per11", "per11_sel", base + CCM_PCDR2, 24, 6);
+	clks[per12] = imx_clk_divider("per12", "per12_sel", base + CCM_PCDR3, 0, 6);
+	clks[per13] = imx_clk_divider("per13", "per13_sel", base + CCM_PCDR3, 8, 6);
+	clks[per14] = imx_clk_divider("per14", "per14_sel", base + CCM_PCDR3, 16, 6);
+	clks[per15] = imx_clk_divider("per15", "per15_sel", base + CCM_PCDR3, 24, 6);
+	clks[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", base + CCM_CGCR0, 24);
+	clks[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", base + CCM_CGCR1, 29);
+	clks[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", base + CCM_CGCR0, 7);
+
+	clkdev_add_physbase(clks[per15], MX25_UART1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per15], MX25_UART2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per15], MX25_UART3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per15], MX25_UART4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per15], MX25_UART5_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per5], MX25_GPT1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per5], MX25_GPT2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per5], MX25_GPT3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per5], MX25_GPT4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX25_FEC_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX25_I2C1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX25_I2C2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX25_I2C3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX25_CSPI1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX25_CSPI2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX25_CSPI3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per3], MX25_ESDHC1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per4], MX25_ESDHC2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per8], MX25_NFC_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[lcdc_ipg_per], MX25_LCDC_BASE_ADDR, "per");
+	clkdev_add_physbase(clks[lcdc_ipg], MX25_LCDC_BASE_ADDR, "ipg");
+	clkdev_add_physbase(clks[lcdc_ahb], MX25_LCDC_BASE_ADDR, "ahb");
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx25_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx25-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx25_ccm_driver = {
+	.probe	= imx25_ccm_probe,
+	.name	= "imx25-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx25_ccm_dt_ids),
+};
+
+static int imx25_ccm_init(void)
+{
+	return platform_driver_register(&imx25_ccm_driver);
+}
+core_initcall(imx25_ccm_init);
diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
new file mode 100644
index 0000000..4b63244
--- /dev/null
+++ b/drivers/clk/imx/clk-imx27.c
@@ -0,0 +1,270 @@
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx27-regs.h>
+#include <mach/generic.h>
+#include <mach/revision.h>
+
+#include "clk.h"
+
+/* Register offsets */
+#define CCM_CSCR		0x0
+#define CCM_MPCTL0		0x4
+#define CCM_MPCTL1		0x8
+#define CCM_SPCTL0		0xc
+#define CCM_SPCTL1		0x10
+#define CCM_OSC26MCTL		0x14
+#define CCM_PCDR0		0x18
+#define CCM_PCDR1		0x1c
+#define CCM_PCCR0		0x20
+#define CCM_PCCR1		0x24
+#define CCM_CCSR		0x28
+#define CCM_PMCTL		0x2c
+#define CCM_PMCOUNT		0x30
+#define CCM_WKGDCTL		0x34
+
+#define PCCR0_SSI2_EN	(1 << 0)
+#define PCCR0_SSI1_EN	(1 << 1)
+#define PCCR0_SLCDC_EN	(1 << 2)
+#define PCCR0_SDHC3_EN	(1 << 3)
+#define PCCR0_SDHC2_EN	(1 << 4)
+#define PCCR0_SDHC1_EN	(1 << 5)
+#define PCCR0_SDC_EN	(1 << 6)
+#define PCCR0_SAHARA_EN	(1 << 7)
+#define PCCR0_RTIC_EN	(1 << 8)
+#define PCCR0_RTC_EN	(1 << 9)
+#define PCCR0_PWM_EN	(1 << 11)
+#define PCCR0_OWIRE_EN	(1 << 12)
+#define PCCR0_MSHC_EN	(1 << 13)
+#define PCCR0_LCDC_EN	(1 << 14)
+#define PCCR0_KPP_EN	(1 << 15)
+#define PCCR0_IIM_EN	(1 << 16)
+#define PCCR0_I2C2_EN	(1 << 17)
+#define PCCR0_I2C1_EN	(1 << 18)
+#define PCCR0_GPT6_EN	(1 << 19)
+#define PCCR0_GPT5_EN	(1 << 20)
+#define PCCR0_GPT4_EN	(1 << 21)
+#define PCCR0_GPT3_EN	(1 << 22)
+#define PCCR0_GPT2_EN	(1 << 23)
+#define PCCR0_GPT1_EN	(1 << 24)
+#define PCCR0_GPIO_EN	(1 << 25)
+#define PCCR0_FEC_EN	(1 << 26)
+#define PCCR0_EMMA_EN	(1 << 27)
+#define PCCR0_DMA_EN	(1 << 28)
+#define PCCR0_CSPI3_EN	(1 << 29)
+#define PCCR0_CSPI2_EN	(1 << 30)
+#define PCCR0_CSPI1_EN	(1 << 31)
+
+#define PCCR1_MSHC_BAUDEN	(1 << 2)
+#define PCCR1_NFC_BAUDEN	(1 << 3)
+#define PCCR1_SSI2_BAUDEN	(1 << 4)
+#define PCCR1_SSI1_BAUDEN	(1 << 5)
+#define PCCR1_H264_BAUDEN	(1 << 6)
+#define PCCR1_PERCLK4_EN	(1 << 7)
+#define PCCR1_PERCLK3_EN	(1 << 8)
+#define PCCR1_PERCLK2_EN	(1 << 9)
+#define PCCR1_PERCLK1_EN	(1 << 10)
+#define PCCR1_HCLK_USB		(1 << 11)
+#define PCCR1_HCLK_SLCDC	(1 << 12)
+#define PCCR1_HCLK_SAHARA	(1 << 13)
+#define PCCR1_HCLK_RTIC		(1 << 14)
+#define PCCR1_HCLK_LCDC		(1 << 15)
+#define PCCR1_HCLK_H264		(1 << 16)
+#define PCCR1_HCLK_FEC		(1 << 17)
+#define PCCR1_HCLK_EMMA		(1 << 18)
+#define PCCR1_HCLK_EMI		(1 << 19)
+#define PCCR1_HCLK_DMA		(1 << 20)
+#define PCCR1_HCLK_CSI		(1 << 21)
+#define PCCR1_HCLK_BROM		(1 << 22)
+#define PCCR1_HCLK_ATA		(1 << 23)
+#define PCCR1_WDT_EN		(1 << 24)
+#define PCCR1_USB_EN		(1 << 25)
+#define PCCR1_UART6_EN		(1 << 26)
+#define PCCR1_UART5_EN		(1 << 27)
+#define PCCR1_UART4_EN		(1 << 28)
+#define PCCR1_UART3_EN		(1 << 29)
+#define PCCR1_UART2_EN		(1 << 30)
+#define PCCR1_UART1_EN		(1 << 31)
+
+enum mx27_clks {
+	dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div,
+	per2_div, per3_div, per4_div, vpu_sel, vpu_div, usb_div, cpu_sel,
+	clko_sel, cpu_div, clko_div, ssi1_sel, ssi2_sel, ssi1_div, ssi2_div,
+	clko_en, ssi2_ipg_gate, ssi1_ipg_gate, slcdc_ipg_gate, sdhc3_ipg_gate,
+	sdhc2_ipg_gate, sdhc1_ipg_gate, scc_ipg_gate, sahara_ipg_gate,
+	rtc_ipg_gate, pwm_ipg_gate, owire_ipg_gate, lcdc_ipg_gate,
+	kpp_ipg_gate, iim_ipg_gate, i2c2_ipg_gate, i2c1_ipg_gate,
+	gpt6_ipg_gate, gpt5_ipg_gate, gpt4_ipg_gate, gpt3_ipg_gate,
+	gpt2_ipg_gate, gpt1_ipg_gate, gpio_ipg_gate, fec_ipg_gate,
+	emma_ipg_gate, dma_ipg_gate, cspi3_ipg_gate, cspi2_ipg_gate,
+	cspi1_ipg_gate, nfc_baud_gate, ssi2_baud_gate, ssi1_baud_gate,
+	vpu_baud_gate, per4_gate, per3_gate, per2_gate, per1_gate,
+	usb_ahb_gate, slcdc_ahb_gate, sahara_ahb_gate, lcdc_ahb_gate,
+	vpu_ahb_gate, fec_ahb_gate, emma_ahb_gate, emi_ahb_gate, dma_ahb_gate,
+	csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
+	uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
+	uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel,
+	mpll_sel, spll_gate, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *cpu_sel_clks[] = {
+	"mpll_main2",
+	"mpll",
+};
+
+static const char *mpll_sel_clks[] = {
+	"fpm",
+	"mpll_osc_sel",
+};
+
+static const char *mpll_osc_sel_clks[] = {
+	"ckih",
+	"ckih_div1p5",
+};
+
+static const char *clko_sel_clks[] = {
+	"ckil",
+	NULL,
+	"ckih",
+	"ckih",
+	"ckih",
+	"mpll",
+	"spll",
+	"cpu_div",
+	"ahb",
+	"ipg",
+	"per1_div",
+	"per2_div",
+	"per3_div",
+	"per4_div",
+	NULL,
+	NULL,
+	"nfc_div",
+	NULL,
+	NULL,
+	NULL,
+	"ckil",
+	"usb_div",
+	NULL,
+};
+
+static int imx27_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *base;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	base = IOMEM(iores->start);
+
+	writel(PCCR0_SDHC3_EN | PCCR0_SDHC2_EN | PCCR0_SDHC1_EN |
+			PCCR0_PWM_EN | PCCR0_KPP_EN | PCCR0_IIM_EN |
+			PCCR0_I2C2_EN | PCCR0_I2C1_EN | PCCR0_GPT6_EN | PCCR0_GPT5_EN |
+			PCCR0_GPT4_EN | PCCR0_GPT3_EN | PCCR0_GPT2_EN | PCCR0_GPT1_EN |
+			PCCR0_GPIO_EN | PCCR0_FEC_EN | PCCR0_CSPI3_EN | PCCR0_CSPI2_EN |
+			PCCR0_CSPI1_EN,
+			base + CCM_PCCR0);
+
+	writel(PCCR1_NFC_BAUDEN | PCCR1_PERCLK4_EN | PCCR1_PERCLK2_EN | PCCR1_PERCLK1_EN |
+			PCCR1_HCLK_USB | PCCR1_HCLK_FEC | PCCR1_HCLK_EMI | PCCR1_WDT_EN |
+			PCCR1_USB_EN | PCCR1_UART6_EN | PCCR1_UART5_EN | PCCR1_UART4_EN |
+			PCCR1_UART3_EN | PCCR1_UART2_EN | PCCR1_UART1_EN,
+			base + CCM_PCCR1);
+
+	clks[dummy] = clk_fixed("dummy", 0);
+	clks[ckih] = clk_fixed("ckih", 26000000);
+	clks[ckil] = clk_fixed("ckil", 32768);
+	clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 1024, 1);
+	clks[ckih_div1p5] = imx_clk_fixed_factor("ckih_div1p5", "ckih", 2, 3);
+
+	clks[mpll_osc_sel] = imx_clk_mux("mpll_osc_sel", base + CCM_CSCR, 4, 1,
+			mpll_osc_sel_clks,
+			ARRAY_SIZE(mpll_osc_sel_clks));
+	clks[mpll_sel] = imx_clk_mux("mpll_sel", base + CCM_CSCR, 16, 1, mpll_sel_clks,
+			ARRAY_SIZE(mpll_sel_clks));
+
+	clks[mpll] = imx_clk_pllv1("mpll", "mpll_sel", base + CCM_MPCTL0);
+	clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SPCTL0);
+	clks[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
+
+	if (imx_silicon_revision() >= IMX_CHIP_REV_2_0) {
+		clks[ahb] = imx_clk_divider("ahb", "mpll_main2", base + CCM_CSCR, 8, 2);
+		clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+	} else {
+		clks[ahb] = imx_clk_divider("ahb", "mpll_main2", base + CCM_CSCR, 9, 4);
+		clks[ipg] = imx_clk_divider("ipg", "ahb", base + CCM_CSCR, 8, 1);
+	}
+
+	clks[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + CCM_PCDR0, 6, 4);
+	clks[per1_div] = imx_clk_divider("per1_div", "mpll_main2", base + CCM_PCDR1, 0, 6);
+	clks[per2_div] = imx_clk_divider("per2_div", "mpll_main2", base + CCM_PCDR1, 8, 6);
+	clks[per3_div] = imx_clk_divider("per3_div", "mpll_main2", base + CCM_PCDR1, 16, 6);
+	clks[per4_div] = imx_clk_divider("per4_div", "mpll_main2", base + CCM_PCDR1, 24, 6);
+	clks[usb_div] = imx_clk_divider("usb_div", "spll", base + CCM_CSCR, 28, 3);
+	clks[cpu_sel] = imx_clk_mux("cpu_sel", base + CCM_CSCR, 15, 1, cpu_sel_clks,
+			ARRAY_SIZE(cpu_sel_clks));
+	clks[clko_sel] = imx_clk_mux("clko_sel", base + CCM_CCSR, 0, 5, clko_sel_clks,
+			ARRAY_SIZE(clko_sel_clks));
+	if (imx_silicon_revision() >= IMX_CHIP_REV_2_0)
+		clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 12, 2);
+	else
+		clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 13, 3);
+	clks[clko_div] = imx_clk_divider("clko_div", "clko_sel", base + CCM_PCDR0, 22, 3);
+	clks[per3_gate] = imx_clk_gate("per3_gate", "per3_div", base + CCM_PCCR1, 8);
+	clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR1, 15);
+	clks[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", base + CCM_PCCR0, 14);
+
+	clkdev_add_physbase(clks[per1_div], MX27_GPT1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_GPT2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_GPT3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_GPT4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_GPT5_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_GPT6_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_UART1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_UART2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_UART3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_UART4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_UART5_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per1_div], MX27_UART6_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX27_CSPI1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX27_CSPI2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX27_CSPI3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX27_I2C1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX27_I2C2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per2_div], MX27_SDHC1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per2_div], MX27_SDHC2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per2_div], MX27_SDHC3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per3_gate], MX27_LCDC_BASE_ADDR, "per");
+	clkdev_add_physbase(clks[lcdc_ahb_gate], MX27_LCDC_BASE_ADDR, "ahb");
+	clkdev_add_physbase(clks[lcdc_ipg_gate], MX27_LCDC_BASE_ADDR, "ipg");
+	clkdev_add_physbase(clks[ipg], MX27_FEC_BASE_ADDR, NULL);
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx27_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx27-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx27_ccm_driver = {
+	.probe	= imx27_ccm_probe,
+	.name	= "imx27-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx27_ccm_dt_ids),
+};
+
+static int imx27_ccm_init(void)
+{
+	return platform_driver_register(&imx27_ccm_driver);
+}
+core_initcall(imx27_ccm_init);
diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
new file mode 100644
index 0000000..8d135c9
--- /dev/null
+++ b/drivers/clk/imx/clk-imx31.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx31-regs.h>
+
+#include "clk.h"
+
+/* Register addresses */
+#define CCM_CCMR		0x00
+#define CCM_PDR0		0x04
+#define CCM_PDR1		0x08
+//#define CCM_RCSR		0x0C
+#define CCM_MPCTL		0x10
+#define CCM_UPCTL		0x14
+#define CCM_SRPCTL		0x18
+#define CCM_COSR		0x1C
+#define CCM_CGR0		0x20
+#define CCM_CGR1		0x24
+#define CCM_CGR2		0x28
+#define CCM_WIMR		0x2C
+#define CCM_LDC		0x30
+#define CCM_DCVR0		0x34
+#define CCM_DCVR1		0x38
+#define CCM_DCVR2		0x3C
+#define CCM_DCVR3		0x40
+#define CCM_LTR0		0x44
+#define CCM_LTR1		0x48
+#define CCM_LTR2		0x4C
+#define CCM_LTR3		0x50
+#define CCM_LTBR0		0x54
+#define CCM_LTBR1		0x58
+#define CCM_PMCR0		0x5C
+#define CCM_PMCR1		0x60
+#define CCM_PDR2		0x64
+
+enum mx31_clks {
+	ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div,
+	per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
+	fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
+	iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
+	uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
+	mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
+	sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
+	uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
+	gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *mcu_main_sel[] = {
+	"spll",
+	"mpll",
+};
+
+static const char *per_sel[] = {
+	"per_div",
+	"ipg",
+};
+
+static int imx31_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *base;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	base = IOMEM(iores->start);
+
+	writel(0xffffffff, base + CCM_CGR0);
+	writel(0xffffffff, base + CCM_CGR1);
+	writel(0xffffffff, base + CCM_CGR2);
+
+	clks[ckih] = clk_fixed("ckih", 26000000);
+	clks[ckil] = clk_fixed("ckil", 32768);
+	clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL);
+	clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SRPCTL);
+	clks[upll] = imx_clk_pllv1("upll", "ckih", base + CCM_UPCTL);
+	clks[mcu_main] = imx_clk_mux("mcu_main", base + CCM_PMCR0, 31, 1,
+			mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
+	clks[hsp] = imx_clk_divider("hsp", "mcu_main", base + CCM_PDR0, 11, 3);
+	clks[ahb] = imx_clk_divider("ahb", "mcu_main", base + CCM_PDR0, 3, 3);
+	clks[nfc] = imx_clk_divider("nfc", "ahb", base + CCM_PDR0, 8, 3);
+	clks[ipg] = imx_clk_divider("ipg", "ahb", base + CCM_PDR0, 6, 2);
+	clks[per_div] = imx_clk_divider("per_div", "upll", base + CCM_PDR0, 16, 5);
+	clks[per] = imx_clk_mux("per", base + CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
+
+	clkdev_add_physbase(clks[per], MX31_UART1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_UART2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_UART3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_UART4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_UART5_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_I2C1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_I2C2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_I2C3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX31_CSPI1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX31_CSPI2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX31_CSPI3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_SDHC1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_SDHC2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[per], MX31_GPT1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[hsp], MX31_IPU_CTRL_BASE_ADDR, NULL);
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx31_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx31-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx31_ccm_driver = {
+	.probe	= imx31_ccm_probe,
+	.name	= "imx31-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx31_ccm_dt_ids),
+};
+
+static int imx31_ccm_init(void)
+{
+	return platform_driver_register(&imx31_ccm_driver);
+}
+core_initcall(imx31_ccm_init);
diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
new file mode 100644
index 0000000..af6c405
--- /dev/null
+++ b/drivers/clk/imx/clk-imx35.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx35-regs.h>
+#include <reset_source.h>
+
+#include "clk.h"
+
+#define CCM_CCMR	0x00
+#define CCM_PDR0	0x04
+#define CCM_PDR1	0x08
+#define CCM_PDR2	0x0C
+#define CCM_PDR3	0x10
+#define CCM_PDR4	0x14
+#define CCM_RCSR	0x18
+#define CCM_MPCTL	0x1C
+#define CCM_PPCTL	0x20
+#define CCM_ACMR	0x24
+#define CCM_COSR	0x28
+#define CCM_CGR0	0x2C
+#define CCM_CGR1	0x30
+#define CCM_CGR2	0x34
+#define CCM_CGR3	0x38
+
+struct arm_ahb_div {
+	unsigned char arm, ahb, sel;
+};
+
+static struct arm_ahb_div clk_consumer[] = {
+	{ .arm = 1, .ahb = 4, .sel = 0},
+	{ .arm = 1, .ahb = 3, .sel = 1},
+	{ .arm = 2, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 1, .sel = 0},
+	{ .arm = 1, .ahb = 5, .sel = 0},
+	{ .arm = 1, .ahb = 8, .sel = 0},
+	{ .arm = 1, .ahb = 6, .sel = 1},
+	{ .arm = 2, .ahb = 4, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static char hsp_div_532[] = { 4, 8, 3, 0 };
+static char hsp_div_400[] = { 3, 6, 3, 0 };
+
+enum mx35_clks {
+	ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
+	arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
+	esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
+	spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
+	ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate,
+	audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate,
+	edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
+	esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate,
+	gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate,
+	kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
+	rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
+	ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
+	wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate,
+	clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *std_sel[] = {
+	"ppll",
+	"arm",
+};
+
+static const char *ipg_per_sel[] = {
+	"ahb_per_div",
+	"arm_per_div",
+};
+
+static int imx35_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	u32 pdr0, consumer_sel, hsp_sel;
+	struct arm_ahb_div *aad;
+	unsigned char *hsp_div;
+	void __iomem *base;
+	u32 reg;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	base = IOMEM(iores->start);
+
+	/* Check reset source */
+	reg = readl(base + CCM_RCSR);
+
+	switch (reg & 0x0F) {
+	case 0x00:
+		reset_source_set_priority(RESET_POR, 200);
+		break;
+	case 0x02:
+		reset_source_set_priority(RESET_JTAG, 200);
+		break;
+	case 0x04:
+		reset_source_set_priority(RESET_RST, 200);
+		break;
+	case 0x08:
+		reset_source_set_priority(RESET_WDG, 200);
+		break;
+	}
+
+	writel(0xffffffff, base + CCM_CGR0);
+	writel(0xffffffff, base + CCM_CGR1);
+	writel(0xfbffffff, base + CCM_CGR2);
+	writel(0xffffffff, base + CCM_CGR3);
+
+	pdr0 = __raw_readl(base + CCM_PDR0);
+	consumer_sel = (pdr0 >> 16) & 0xf;
+	aad = &clk_consumer[consumer_sel];
+	if (!aad->arm) {
+		pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
+		/*
+		 * We are basically stuck. Continue with a default entry and hope we
+		 * get far enough to actually show the above message
+		 */
+		aad = &clk_consumer[0];
+	}
+
+	clks[ckih] = clk_fixed("ckih", 24000000);
+	clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL);
+	clks[ppll] = imx_clk_pllv1("ppll", "ckih", base + CCM_PPCTL);
+
+	clks[mpll_075] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
+
+	if (aad->sel)
+		clks[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
+	else
+		clks[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
+
+	if (clk_get_rate(clks[arm]) > 400000000)
+		hsp_div = hsp_div_532;
+	else
+		hsp_div = hsp_div_400;
+
+	hsp_sel = (pdr0 >> 20) & 0x3;
+	if (!hsp_div[hsp_sel]) {
+		pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
+		hsp_sel = 0;
+	}
+
+	clks[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
+
+	clks[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
+	clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+
+	clks[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + CCM_PDR4, 16, 6);
+	clks[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + CCM_PDR0, 12, 3);
+	clks[ipg_per] = imx_clk_mux("ipg_per", base + CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
+
+	clks[uart_sel] = imx_clk_mux("uart_sel", base + CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
+	clks[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + CCM_PDR4, 10, 6);
+
+	clks[esdhc_sel] = imx_clk_mux("esdhc_sel", base + CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+	clks[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + CCM_PDR3, 0, 6);
+	clks[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + CCM_PDR3, 8, 6);
+	clks[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + CCM_PDR3, 16, 6);
+
+	clks[usb_sel] = imx_clk_mux("usb_sel", base + CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+	clks[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + CCM_PDR4, 22, 6);
+
+	clkdev_add_physbase(clks[uart_div], MX35_UART1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[uart_div], MX35_UART2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[uart_div], MX35_UART3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg_per], MX35_I2C1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg_per], MX35_I2C2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg_per], MX35_I2C3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX35_CSPI1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX35_CSPI2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX35_FEC_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[ipg], MX35_GPT1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[esdhc1_div], MX35_ESDHC1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[esdhc2_div], MX35_ESDHC2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[esdhc3_div], MX35_ESDHC3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[hsp], MX35_IPU_CTRL_BASE_ADDR, NULL);
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx35_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx35-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx35_ccm_driver = {
+	.probe	= imx35_ccm_probe,
+	.name	= "imx35-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx35_ccm_dt_ids),
+};
+
+static int imx35_ccm_init(void)
+{
+	return platform_driver_register(&imx35_ccm_driver);
+}
+core_initcall(imx35_ccm_init);
diff --git a/drivers/clk/imx/clk-imx5.c b/drivers/clk/imx/clk-imx5.c
new file mode 100644
index 0000000..c4c47a6
--- /dev/null
+++ b/drivers/clk/imx/clk-imx5.c
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx50-regs.h>
+#include <mach/imx51-regs.h>
+#include <mach/imx53-regs.h>
+#include <dt-bindings/clock/imx5-clock.h>
+
+#include "clk.h"
+
+/* Register addresses of CCM*/
+#define CCM_CCR		0x00
+#define CCM_CCDR	0x04
+#define CCM_CSR		0x08
+#define CCM_CCSR	0x0C
+#define CCM_CACRR	0x10
+#define CCM_CBCDR	0x14
+#define CCM_CBCMR	0x18
+#define CCM_CSCMR1	0x1C
+#define CCM_CSCMR2	0x20
+#define CCM_CSCDR1	0x24
+#define CCM_CS1CDR	0x28
+#define CCM_CS2CDR	0x2C
+#define CCM_CDCDR	0x30
+#define CCM_CHSCDR	0x34
+#define CCM_CSCDR2	0x38
+#define CCM_CSCDR3	0x3C
+#define CCM_CSCDR4	0x40
+#define CCM_CWDR	0x44
+#define CCM_CDHIPR	0x48
+#define CCM_CDCR	0x4C
+#define CCM_CTOR	0x50
+#define CCM_CLPCR	0x54
+#define CCM_CISR	0x58
+#define CCM_CIMR	0x5C
+#define CCM_CCOSR	0x60
+#define CCM_CGPR	0x64
+#define CCM_CCGR0	0x68
+#define CCM_CCGR1	0x6C
+#define CCM_CCGR2	0x70
+#define CCM_CCGR3	0x74
+#define CCM_CCGR4	0x78
+#define CCM_CCGR5	0x7C
+#define CCM_CCGR6	0x80
+#define CCM_CCGR7	0x84
+
+#define CCM_CMEOR	0x84
+
+static struct clk *clks[IMX5_CLK_END];
+
+/* This is used multiple times */
+static const char *standard_pll_sel[] = {
+	"pll1_sw",
+	"pll2_sw",
+	"pll3_sw",
+	"lp_apm",
+};
+
+static const char *mx50_3bit_clk_sel[] = {
+	"pll1_sw",
+	"pll2_sw",
+	"pll3_sw",
+	"lp_apm",
+	"pfd0",
+	"pfd1",
+	"pfd4",
+	"osc",
+};
+
+static const char *lp_apm_sel[] = {
+	"osc",
+};
+
+static const char *periph_apm_sel[] = {
+	"pll1_sw",
+	"pll3_sw",
+	"lp_apm",
+};
+
+static const char *main_bus_sel[] = {
+	"pll2_sw",
+	"periph_apm",
+};
+
+static const char *mx50_periph_clk_sel[] = {
+	"pll1_sw",
+	"pll2_sw",
+	"pll3_sw",
+	"lp_apm",
+};
+
+static const char *per_lp_apm_sel[] = {
+	"main_bus",
+	"lp_apm",
+};
+
+static const char *per_root_sel[] = {
+	"per_podf",
+	"ipg",
+};
+
+static const char *esdhc_c_sel[] = {
+	"esdhc_a_podf",
+	"esdhc_b_podf",
+};
+
+static const char *esdhc_d_sel[] = {
+	"esdhc_a_podf",
+	"esdhc_b_podf",
+};
+
+static const char *emi_slow_sel[] = {
+	"main_bus",
+	"ahb",
+};
+
+static const char *usb_phy_sel_str[] = {
+	"osc",
+	"usb_phy_podf",
+};
+
+static const char *mx51_ipu_di0_sel[] = {
+	"di_pred",
+	"osc",
+	"ckih1",
+	"tve_di",
+};
+
+static const char *mx53_ipu_di0_sel[] = {
+	"di_pred",
+	"osc",
+	"ckih1",
+	"di_pll4_podf",
+	"dummy",
+	"ldb_di0_div",
+};
+
+static const char *mx53_ldb_di0_sel[] = {
+	"pll3_sw",
+	"pll4_sw",
+};
+
+static const char *mx51_ipu_di1_sel[] = {
+	"di_pred",
+	"osc",
+	"ckih1",
+	"tve_di",
+	"ipp_di1",
+};
+
+static const char *mx53_ipu_di1_sel[] = {
+	"di_pred",
+	"osc",
+	"ckih1",
+	"tve_di",
+	"ipp_di1",
+	"ldb_di1_div",
+};
+
+static const char *mx53_ldb_di1_sel[] = {
+	"pll3_sw",
+	"pll4_sw",
+};
+
+static const char *mx51_tve_ext_sel[] = {
+	"osc",
+	"ckih1",
+};
+
+static const char *mx53_tve_ext_sel[] = {
+	"pll4_sw",
+	"ckih1",
+};
+
+static const char *mx51_tve_sel[] = {
+	"tve_pred",
+	"tve_ext_sel",
+};
+
+static const char *ipu_sel[] = {
+	"axi_a",
+	"axi_b",
+	"emi_slow_gate",
+	"ahb",
+};
+
+static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *base)
+{
+	writel(0xffffffff, base + CCM_CCGR0);
+	writel(0xffffffff, base + CCM_CCGR1);
+	writel(0xffffffff, base + CCM_CCGR2);
+	writel(0xffffffff, base + CCM_CCGR3);
+	writel(0xffffffff, base + CCM_CCGR4);
+	writel(0xffffffff, base + CCM_CCGR5);
+	writel(0xffffffff, base + CCM_CCGR6);
+	writel(0xffffffff, base + CCM_CCGR7);
+
+	if (!IS_ENABLED(CONFIG_COMMON_CLK_OF_PROVIDER) || !dev->device_node) {
+		clks[IMX5_CLK_CKIL] = clk_fixed("ckil", 32768);
+		clks[IMX5_CLK_OSC] = clk_fixed("osc", 24000000);
+	}
+
+	clks[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", base + CCM_CBCMR, 1, 1,
+				per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
+	clks[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", base + CCM_CBCDR, 6, 2);
+	clks[IMX5_CLK_PER_PRED2] = imx_clk_divider("per_pred2", "per_pred1", base + CCM_CBCDR, 3, 3);
+	clks[IMX5_CLK_PER_PODF] = imx_clk_divider("per_podf", "per_pred2", base + CCM_CBCDR, 0, 3);
+	clks[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", base + CCM_CBCMR, 0, 1,
+				per_root_sel, ARRAY_SIZE(per_root_sel));
+	clks[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", base + CCM_CBCDR, 10, 3);
+	clks[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + CCM_CBCDR, 8, 2);
+	clks[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", base + CCM_CBCDR, 16, 3);
+	clks[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", base + CCM_CBCDR, 19, 3);
+	clks[IMX5_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + CCM_CSCMR1, 24, 2,
+				standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+	clks[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", base + CCM_CSCDR1, 3, 3);
+	clks[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", base + CCM_CSCDR1, 0, 3);
+	clks[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred",
+		"esdhc_a_sel", base + CCM_CSCDR1, 16, 3);
+	clks[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf",
+		"esdhc_a_pred", base + CCM_CSCDR1, 11, 3);
+	clks[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred",
+		"esdhc_b_sel", base + CCM_CSCDR1, 22, 3);
+	clks[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf",
+		"esdhc_b_pred", base + CCM_CSCDR1, 19, 3);
+	clks[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + CCM_CSCMR1,
+		4, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+	clks[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred",
+		"ecspi_sel", base + CCM_CSCDR2, 25, 3);
+	clks[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf",
+		"ecspi_pred", base + CCM_CSCDR2, 19, 6);
+	clks[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf",
+		"pll1_sw", base + CCM_CACRR, 0, 3);
+}
+
+static void mx5_clocks_mx51_mx53_init(void __iomem *base)
+{
+	clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", base + CCM_CCSR, 9, 1,
+				lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+	clks[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", base + CCM_CBCMR, 12, 2,
+				periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
+	clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", base + CCM_CBCDR, 25, 1,
+				main_bus_sel, ARRAY_SIZE(main_bus_sel));
+	clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", base + CCM_CSCMR1, 20, 2,
+				standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+	clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", base + CCM_CSCMR1, 16, 2,
+				standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+	clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", base + CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
+	clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", base + CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
+	clks[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", base + CCM_CBCDR, 26, 1,
+				emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
+	clks[IMX5_CLK_EMI_SLOW_PODF] = imx_clk_divider("emi_slow_podf", "emi_sel", base + CCM_CBCDR, 22, 3);
+	clks[IMX5_CLK_NFC_PODF] = imx_clk_divider("nfc_podf", "emi_slow_podf", base + CCM_CBCDR, 13, 3);
+	clks[IMX5_CLK_USBOH3_SEL] = imx_clk_mux("usboh3_sel", base + CCM_CSCMR1, 22, 2,
+				standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+	clks[IMX5_CLK_USBOH3_PRED] = imx_clk_divider("usboh3_pred", "usboh3_sel", base + CCM_CSCDR1, 8, 3);
+	clks[IMX5_CLK_USBOH3_PODF] = imx_clk_divider("usboh3_podf", "usboh3_pred", base + CCM_CSCDR1, 6, 2);
+	clks[IMX5_CLK_USB_PHY_PRED] = imx_clk_divider("usb_phy_pred", "pll3_sw", base + CCM_CDCDR, 3, 3);
+	clks[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", base + CCM_CDCDR, 0, 3);
+	clks[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", base + CCM_CSCMR1, 26, 1,
+				usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
+}
+
+static void mx5_clocks_ipu_init(void __iomem *regs)
+{
+	clks[IMX5_CLK_IPU_SEL]		= imx_clk_mux("ipu_sel", regs + CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
+}
+
+int __init mx50_clocks_init(struct device_d *dev, void __iomem *regs)
+{
+	clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc",
+					       (void *)MX50_PLL1_BASE_ADDR);
+	clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc",
+					       (void *)MX50_PLL2_BASE_ADDR);
+	clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc",
+					       (void *)MX50_PLL3_BASE_ADDR);
+
+	mx5_clocks_common_init(dev, regs);
+
+	clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", regs + CCM_CCSR, 10, 1, lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+	clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", regs + CCM_CBCDR, 25, 2, mx50_periph_clk_sel, ARRAY_SIZE(mx50_periph_clk_sel));
+	clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", regs + CCM_CSCMR1, 21, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+	clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", regs + CCM_CSCMR1, 16, 3, mx50_3bit_clk_sel, ARRAY_SIZE(mx50_3bit_clk_sel));
+	clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", regs + CCM_CSCMR1, 20, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
+	clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", regs + CCM_CSCMR1, 19, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_GPT1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_CSPI_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_FEC_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX50_ESDHC1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX50_ESDHC2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX50_ESDHC3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX50_ESDHC4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM1_BASE_ADDR, "per");
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM2_BASE_ADDR, "per");
+
+	return 0;
+}
+
+static int imx50_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *regs;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	regs = IOMEM(iores->start);
+
+	mx50_clocks_init(dev, regs);
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx50_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx50-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx50_ccm_driver = {
+	.probe	= imx50_ccm_probe,
+	.name	= "imx50-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx50_ccm_dt_ids),
+};
+
+static void mx51_clocks_ipu_init(void __iomem *regs)
+{
+	clks[IMX5_CLK_IPU_DI0_SEL]	= imx_clk_mux_p("ipu_di0_sel", regs + CCM_CSCMR2, 26, 3,
+						mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
+	clks[IMX5_CLK_IPU_DI1_SEL]	= imx_clk_mux_p("ipu_di1_sel", regs + CCM_CSCMR2, 29, 3,
+						mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
+	clks[IMX5_CLK_TVE_EXT_SEL]	= imx_clk_mux_p("tve_ext_sel", regs + CCM_CSCMR1, 6, 1,
+						mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel));
+	clks[IMX5_CLK_TVE_SEL]		= imx_clk_mux("tve_sel", regs + CCM_CSCMR1, 7, 1,
+						mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
+	clks[IMX5_CLK_TVE_PRED]		= imx_clk_divider("tve_pred", "pll3_sw", regs + CCM_CDCDR, 28, 3);
+
+	mx5_clocks_ipu_init(regs);
+
+	clkdev_add_physbase(clks[IMX5_CLK_IPU_SEL], MX51_IPU_BASE_ADDR, "bus");
+	clkdev_add_physbase(clks[IMX5_CLK_IPU_DI0_SEL], MX51_IPU_BASE_ADDR, "di0");
+	clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX51_IPU_BASE_ADDR, "di1");
+}
+
+int __init mx51_clocks_init(struct device_d *dev, void __iomem *regs)
+{
+	clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX51_PLL1_BASE_ADDR);
+	clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX51_PLL2_BASE_ADDR);
+	clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", (void *)MX51_PLL3_BASE_ADDR);
+
+	mx5_clocks_common_init(dev, regs);
+	mx5_clocks_mx51_mx53_init(regs);
+
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_I2C1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_I2C2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_GPT1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_CSPI_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX51_ECSPI1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX51_ECSPI2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_MXC_FEC_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX51_MMC_SDHC1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX51_MMC_SDHC2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX51_MMC_SDHC3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX51_MMC_SDHC4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_ATA_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM1_BASE_ADDR, "per");
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM2_BASE_ADDR, "per");
+
+	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+		mx51_clocks_ipu_init(regs);
+
+	return 0;
+}
+
+static int imx51_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *regs;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	regs = IOMEM(iores->start);
+
+	mx51_clocks_init(dev, regs);
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx51_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx51-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx51_ccm_driver = {
+	.probe	= imx51_ccm_probe,
+	.name	= "imx51-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx51_ccm_dt_ids),
+};
+
+static void mx53_clocks_ipu_init(void __iomem *regs)
+{
+	clks[IMX5_CLK_LDB_DI1_DIV_3_5]	= imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+	clks[IMX5_CLK_LDB_DI1_DIV]	= imx_clk_divider_np("ldb_di1_div", "ldb_di1_div_3_5", regs + CCM_CSCMR2, 11, 1);
+	clks[IMX5_CLK_LDB_DI1_SEL]	= imx_clk_mux_p("ldb_di1_sel", regs + CCM_CSCMR2, 9, 1,
+						mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
+	clks[IMX5_CLK_DI_PLL4_PODF]	= imx_clk_divider("di_pll4_podf", "pll4_sw", regs + CCM_CDCDR, 16, 3);
+	clks[IMX5_CLK_LDB_DI0_DIV_3_5]	= imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+	clks[IMX5_CLK_LDB_DI0_DIV]	= imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", regs + CCM_CSCMR2, 10, 1);
+	clks[IMX5_CLK_LDB_DI0_SEL]	= imx_clk_mux_p("ldb_di0_sel", regs + CCM_CSCMR2, 8, 1,
+						mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
+	clks[IMX5_CLK_IPU_DI0_SEL]	= imx_clk_mux_p("ipu_di0_sel", regs + CCM_CSCMR2, 26, 3,
+						mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
+	clks[IMX5_CLK_IPU_DI1_SEL]	= imx_clk_mux_p("ipu_di1_sel", regs + CCM_CSCMR2, 29, 3,
+						mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
+	clks[IMX5_CLK_TVE_EXT_SEL]	= imx_clk_mux_p("tve_ext_sel", regs + CCM_CSCMR1, 6, 1,
+						mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel));
+	clks[IMX5_CLK_TVE_PRED]		= imx_clk_divider("tve_pred", "tve_ext_sel", regs + CCM_CDCDR, 28, 3);
+
+	mx5_clocks_ipu_init(regs);
+
+	clkdev_add_physbase(clks[IMX5_CLK_IPU_SEL], MX53_IPU_BASE_ADDR, "bus");
+	clkdev_add_physbase(clks[IMX5_CLK_IPU_DI0_SEL], MX53_IPU_BASE_ADDR, "di0");
+	clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX53_IPU_BASE_ADDR, "di1");
+}
+
+int __init mx53_clocks_init(struct device_d *dev, void __iomem *regs)
+{
+	clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX53_PLL1_BASE_ADDR);
+	clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX53_PLL2_BASE_ADDR);
+	clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", (void *)MX53_PLL3_BASE_ADDR);
+	clks[IMX5_CLK_PLL4_SW] = imx_clk_pllv2("pll4_sw", "osc", (void *)MX53_PLL4_BASE_ADDR);
+
+	mx5_clocks_common_init(dev, regs);
+	mx5_clocks_mx51_mx53_init(regs);
+
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART5_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_GPT1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX53_CSPI_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX53_ECSPI1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX53_ECSPI2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_IPG], MX53_FEC_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX53_ESDHC1_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX53_ESDHC2_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX53_ESDHC3_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX53_ESDHC4_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_AHB], MX53_SATA_BASE_ADDR, NULL);
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM1_BASE_ADDR, "per");
+	clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM2_BASE_ADDR, "per");
+
+	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+		mx53_clocks_ipu_init(regs);
+
+	return 0;
+}
+
+static int imx53_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *regs;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	regs = IOMEM(iores->start);
+
+	mx53_clocks_init(dev, regs);
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx53_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx53-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx53_ccm_driver = {
+	.probe	= imx53_ccm_probe,
+	.name	= "imx53-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx53_ccm_dt_ids),
+};
+
+static int imx5_ccm_init(void)
+{
+	if (IS_ENABLED(CONFIG_ARCH_IMX50))
+		platform_driver_register(&imx50_ccm_driver);
+	if (IS_ENABLED(CONFIG_ARCH_IMX51))
+		platform_driver_register(&imx51_ccm_driver);
+	if (IS_ENABLED(CONFIG_ARCH_IMX53))
+		platform_driver_register(&imx53_ccm_driver);
+
+	return 0;
+}
+core_initcall(imx5_ccm_init);
diff --git a/drivers/clk/imx/clk-imx6.c b/drivers/clk/imx/clk-imx6.c
new file mode 100644
index 0000000..8ac43be
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6.c
@@ -0,0 +1,541 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx6-regs.h>
+#include <mach/revision.h>
+#include <mach/imx6.h>
+#include <dt-bindings/clock/imx6qdl-clock.h>
+
+#include "clk.h"
+
+#define CCGR0				0x68
+#define CCGR1				0x6c
+#define CCGR2				0x70
+#define CCGR3				0x74
+#define CCGR4				0x78
+#define CCGR5				0x7c
+#define CCGR6				0x80
+#define CCGR7				0x84
+
+#define CLPCR				0x54
+#define BP_CLPCR_LPM			0
+#define BM_CLPCR_LPM			(0x3 << 0)
+#define BM_CLPCR_BYPASS_PMIC_READY	(0x1 << 2)
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM	(0x1 << 5)
+#define BM_CLPCR_SBYOS			(0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC		(0x1 << 7)
+#define BM_CLPCR_VSTBY			(0x1 << 8)
+#define BP_CLPCR_STBY_COUNT		9
+#define BM_CLPCR_STBY_COUNT		(0x3 << 9)
+#define BM_CLPCR_COSC_PWRDOWN		(0x1 << 11)
+#define BM_CLPCR_WB_PER_AT_LPM		(0x1 << 16)
+#define BM_CLPCR_WB_CORE_AT_LPM		(0x1 << 17)
+#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS	(0x1 << 19)
+#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS	(0x1 << 21)
+#define BM_CLPCR_MASK_CORE0_WFI		(0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI		(0x1 << 23)
+#define BM_CLPCR_MASK_CORE2_WFI		(0x1 << 24)
+#define BM_CLPCR_MASK_CORE3_WFI		(0x1 << 25)
+#define BM_CLPCR_MASK_SCU_IDLE		(0x1 << 26)
+#define BM_CLPCR_MASK_L2CC_IDLE		(0x1 << 27)
+
+static struct clk *clks[IMX6QDL_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static const char *step_sels[] = {
+	"osc",
+	"pll2_pfd2_396m",
+};
+
+static const char *pll1_sw_sels[] = {
+	"pll1_sys",
+	"step",
+};
+
+static const char *periph_pre_sels[] = {
+	"pll2_bus",
+	"pll2_pfd2_396m",
+	"pll2_pfd0_352m",
+	"pll2_198m",
+};
+
+static const char *periph_clk2_sels[] = {
+	"pll3_usb_otg",
+	"osc",
+};
+
+static const char *periph_sels[] = {
+	"periph_pre",
+	"periph_clk2",
+};
+
+static const char *periph2_sels[] = {
+	"periph2_pre",
+	"periph2_clk2",
+};
+
+static const char *axi_sels[] = {
+	"periph",
+	"pll2_pfd2_396m",
+	"pll3_pfd1_540m",
+};
+
+static const char *usdhc_sels[] = {
+	"pll2_pfd2_396m",
+	"pll2_pfd0_352m",
+};
+
+static const char *enfc_sels[]	= {
+	"pll2_pfd0_352m",
+	"pll2_bus",
+	"pll3_usb_otg",
+	"pll2_pfd2_396m",
+};
+
+static const char *eim_sels[] = {
+	"axi",
+	"pll3_usb_otg",
+	"pll2_pfd2_396m",
+	"pll2_pfd0_352m",
+};
+
+static const char *vdo_axi_sels[] = {
+	"axi",
+	"ahb",
+};
+
+static const char *cko_sels[] = {
+	"cko1",
+	"cko2",
+};
+
+static const char *cko1_sels[] = {
+	"pll3_usb_otg",
+	"pll2_bus",
+	"pll1_sys",
+	"pll5_video",
+	"dummy",
+	"axi",
+	"enfc",
+	"ipu1_di0",
+	"ipu1_di1",
+	"ipu2_di0",
+	"ipu2_di1",
+	"ahb",
+	"ipg",
+	"ipg_per",
+	"ckil",
+	"pll4_audio",
+};
+
+static const char *cko2_sels[] = {
+	"mmdc_ch0_axi",
+	"mmdc_ch1_axi",
+	"usdhc4",
+	"usdhc1",
+	"gpu2d_axi",
+	"dummy",
+	"ecspi_root",
+	"gpu3d_axi",
+	"usdhc3",
+	"dummy",
+	"arm",
+	"ipu1",
+	"ipu2",
+	"vdo_axi",
+	"osc",
+	"gpu2d_core",
+	"gpu3d_core",
+	"usdhc2",
+	"ssi1",
+	"ssi2",
+	"ssi3",
+	"gpu3d_shader",
+	"vpu_axi",
+	"can_root",
+	"ldb_di0",
+	"ldb_di1",
+	"esai",
+	"eim_slow",
+	"uart_serial",
+	"spdif",
+	"asrc",
+	"hsi_tx",
+};
+
+static const char *ipu_sels[] = {
+	"mmdc_ch0_axi_podf",
+	"pll2_pfd2_396m",
+	"pll3_120m",
+	"pll3_pfd1_540m",
+};
+
+static const char *ldb_di_sels[] = {
+	"pll5_video_div",
+	"pll2_pfd0_352m",
+	"pll2_pfd2_396m",
+	"mmdc_ch1_axi_podf",
+	"pll3_usb_otg",
+};
+
+static const char *ipu_di_pre_sels[] = {
+	"mmdc_ch0_axi",
+	"pll3_usb_otg",
+	"pll5_video_div",
+	"pll2_pfd0_352m",
+	"pll2_pfd2_396m",
+	"pll3_pfd1_540m",
+};
+
+static const char *ipu1_di0_sels[] = {
+	"ipu1_di0_pre",
+	"dummy",
+	"dummy",
+	"ldb_di0_podf",
+	"ldb_di1_podf",
+};
+
+static const char *ipu1_di1_sels[] = {
+	"ipu1_di1_pre",
+	"dummy",
+	"dummy",
+	"ldb_di0_podf",
+	"ldb_di1_podf",
+};
+
+static const char *ipu2_di0_sels[] = {
+	"ipu2_di0_pre",
+	"dummy",
+	"dummy",
+	"ldb_di0_podf",
+	"ldb_di1_podf",
+};
+
+static const char *ipu2_di1_sels[] = {
+	"ipu2_di1_pre",
+	"dummy",
+	"dummy",
+	"ldb_di0_podf",
+	"ldb_di1_podf",
+};
+
+static const char *lvds_sels[] = {
+	"dummy",
+	"dummy",
+	"dummy",
+	"dummy",
+	"dummy",
+	"dummy",
+	"pll4_audio",
+	"pll5_video",
+	"pll8_mlb",
+	"enet_ref",
+	"pcie_ref_125m",
+	"sata_ref_100m",
+};
+
+static const char *pcie_axi_sels[] = {
+	"axi",
+	"ahb",
+};
+
+static struct clk_div_table clk_enet_ref_table[] = {
+	{ .val = 0, .div = 20, },
+	{ .val = 1, .div = 10, },
+	{ .val = 2, .div = 5, },
+	{ .val = 3, .div = 4, },
+	{ },
+};
+
+static struct clk_div_table post_div_table[] = {
+	{ .val = 2, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 0, .div = 4, },
+	{ /* sentinel */ }
+};
+
+static struct clk_div_table video_div_table[] = {
+	{ .val = 0, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 2, .div = 1, },
+	{ .val = 3, .div = 4, },
+	{ /* sentinel */ }
+};
+
+static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb)
+{
+	clks[IMX6QDL_CLK_PLL5_POST_DIV] = imx_clk_divider_table("pll5_post_div", "pll5_video", anab + 0xa0, 19, 2, post_div_table);
+	clks[IMX6QDL_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div", anab + 0x170, 30, 2, video_div_table);
+
+	clks[IMX6QDL_CLK_IPU1_SEL]         = imx_clk_mux("ipu1_sel",         cb + 0x3c, 9,  2, ipu_sels,          ARRAY_SIZE(ipu_sels));
+	clks[IMX6QDL_CLK_IPU2_SEL]         = imx_clk_mux("ipu2_sel",         cb + 0x3c, 14, 2, ipu_sels,          ARRAY_SIZE(ipu_sels));
+	clks[IMX6QDL_CLK_LDB_DI0_SEL]      = imx_clk_mux_p("ldb_di0_sel",      cb + 0x2c, 9,  3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
+	clks[IMX6QDL_CLK_LDB_DI1_SEL]      = imx_clk_mux_p("ldb_di1_sel",      cb + 0x2c, 12, 3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
+	clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_p("ipu1_di0_pre_sel", cb + 0x34, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_p("ipu1_di1_pre_sel", cb + 0x34, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_p("ipu2_di0_pre_sel", cb + 0x38, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_p("ipu2_di1_pre_sel", cb + 0x38, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	clks[IMX6QDL_CLK_IPU1_DI0_SEL]     = imx_clk_mux_p("ipu1_di0_sel",     cb + 0x34, 0,  3, ipu1_di0_sels,     ARRAY_SIZE(ipu1_di0_sels));
+	clks[IMX6QDL_CLK_IPU1_DI1_SEL]     = imx_clk_mux_p("ipu1_di1_sel",     cb + 0x34, 9,  3, ipu1_di1_sels,     ARRAY_SIZE(ipu1_di1_sels));
+	clks[IMX6QDL_CLK_IPU2_DI0_SEL]     = imx_clk_mux_p("ipu2_di0_sel",     cb + 0x38, 0,  3, ipu2_di0_sels,     ARRAY_SIZE(ipu2_di0_sels));
+	clks[IMX6QDL_CLK_IPU2_DI1_SEL]     = imx_clk_mux_p("ipu2_di1_sel",     cb + 0x38, 9,  3, ipu2_di1_sels,     ARRAY_SIZE(ipu2_di1_sels));
+
+	clks[IMX6QDL_CLK_IPU1_PODF]        = imx_clk_divider("ipu1_podf",        "ipu1_sel",          cb + 0x3c, 11, 3);
+	clks[IMX6QDL_CLK_IPU2_PODF]        = imx_clk_divider("ipu2_podf",        "ipu2_sel",          cb + 0x3c, 16, 3);
+	clks[IMX6QDL_CLK_LDB_DI0_DIV_3_5]  = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+	clks[IMX6QDL_CLK_LDB_DI0_PODF]     = imx_clk_divider_np("ldb_di0_podf", "ldb_di0_div_3_5", cb + 0x20, 10, 1);
+	clks[IMX6QDL_CLK_LDB_DI1_DIV_3_5]  = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+	clks[IMX6QDL_CLK_LDB_DI1_PODF]     = imx_clk_divider_np("ldb_di1_podf", "ldb_di1_div_3_5", cb + 0x20, 11, 1);
+	clks[IMX6QDL_CLK_IPU1_DI0_PRE]     = imx_clk_divider("ipu1_di0_pre",     "ipu1_di0_pre_sel",  cb + 0x34, 3,  3);
+	clks[IMX6QDL_CLK_IPU1_DI1_PRE]     = imx_clk_divider("ipu1_di1_pre",     "ipu1_di1_pre_sel",  cb + 0x34, 12, 3);
+	clks[IMX6QDL_CLK_IPU2_DI0_PRE]     = imx_clk_divider("ipu2_di0_pre",     "ipu2_di0_pre_sel",  cb + 0x38, 3,  3);
+	clks[IMX6QDL_CLK_IPU2_DI1_PRE]     = imx_clk_divider("ipu2_di1_pre",     "ipu2_di1_pre_sel",  cb + 0x38, 12, 3);
+
+	clks[IMX6QDL_CLK_IPU1]         = imx_clk_gate2("ipu1",          "ipu1_podf",         cb + 0x74, 0);
+	clks[IMX6QDL_CLK_IPU1_DI0]     = imx_clk_gate2("ipu1_di0",      "ipu1_di0_sel",      cb + 0x74, 2);
+	clks[IMX6QDL_CLK_IPU1_DI1]     = imx_clk_gate2("ipu1_di1",      "ipu1_di1_sel",      cb + 0x74, 4);
+	clks[IMX6QDL_CLK_IPU2]         = imx_clk_gate2("ipu2",          "ipu2_podf",         cb + 0x74, 6);
+	clks[IMX6QDL_CLK_IPU2_DI0]     = imx_clk_gate2("ipu2_di0",      "ipu2_di0_sel",      cb + 0x74, 8);
+	clks[IMX6QDL_CLK_LDB_DI0]      = imx_clk_gate2("ldb_di0",       "ldb_di0_podf",      cb + 0x74, 12);
+	clks[IMX6QDL_CLK_LDB_DI1]      = imx_clk_gate2("ldb_di1",       "ldb_di1_podf",      cb + 0x74, 14);
+	clks[IMX6QDL_CLK_IPU2_DI1]     = imx_clk_gate2("ipu2_di1",      "ipu2_di1_sel",      cb + 0x74, 10);
+
+	clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_SEL], clks[IMX6QDL_CLK_IPU1_DI0_PRE]);
+	clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_SEL], clks[IMX6QDL_CLK_IPU1_DI1_PRE]);
+	clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_SEL], clks[IMX6QDL_CLK_IPU2_DI0_PRE]);
+	clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_SEL], clks[IMX6QDL_CLK_IPU2_DI1_PRE]);
+
+	clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+	clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+	clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+	clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+
+	if ((imx_silicon_revision() != IMX_CHIP_REV_1_0) ||
+	    cpu_is_mx6dl()) {
+		clk_set_parent(clks[IMX6QDL_CLK_LDB_DI0_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+		clk_set_parent(clks[IMX6QDL_CLK_LDB_DI1_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+	}
+
+}
+
+static int imx6_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *base, *anatop_base, *ccm_base;
+
+	anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	ccm_base = IOMEM(iores->start);
+
+	base = anatop_base;
+
+	/*                   type                               name            parent_name base   div_mask */
+	clks[IMX6QDL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x7f);
+	clks[IMX6QDL_CLK_PLL2_BUS]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x1);
+	clks[IMX6QDL_CLK_PLL3_USB_OTG]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x3);
+	clks[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x7f);
+	clks[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
+	clks[IMX6QDL_CLK_PLL8_MLB]      = imx_clk_pllv3(IMX_PLLV3_MLB,	"pll8_mlb",	"osc", base + 0xd0, 0x0);
+	clks[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
+	clks[IMX6QDL_CLK_PLL6_ENET]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
+
+	clks[IMX6QDL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6);
+	clks[IMX6QDL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6);
+
+	clks[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
+	clks[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
+	clks[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
+	clks[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+	clks[IMX6QDL_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet", base + 0xe0, 0, 2, clk_enet_ref_table);
+
+	clks[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+	clks[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+
+	clks[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12));
+	clks[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13));
+
+	/*                                name               parent_name         reg          idx */
+	clks[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
+	clks[IMX6QDL_CLK_PLL2_PFD1_594M] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",     base + 0x100, 1);
+	clks[IMX6QDL_CLK_PLL2_PFD2_396M] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus",     base + 0x100, 2);
+	clks[IMX6QDL_CLK_PLL3_PFD0_720M] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0,  0);
+	clks[IMX6QDL_CLK_PLL3_PFD1_540M] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0,  1);
+	clks[IMX6QDL_CLK_PLL3_PFD2_508M] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0,  2);
+	clks[IMX6QDL_CLK_PLL3_PFD3_454M] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0,  3);
+
+	/*                                    name          parent_name          mult div */
+	clks[IMX6QDL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+	clks[IMX6QDL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg",   1, 4);
+	clks[IMX6QDL_CLK_PLL3_80M]  = imx_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1, 6);
+	clks[IMX6QDL_CLK_PLL3_60M]  = imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 8);
+	clks[IMX6QDL_CLK_TWD]       = imx_clk_fixed_factor("twd",       "arm",            1, 2);
+
+	base = ccm_base;
+
+	/*                                  name                 reg       shift width parent_names     num_parents */
+	clks[IMX6QDL_CLK_STEP]             = imx_clk_mux("step",	         base + 0xc,  8,  1, step_sels,	        ARRAY_SIZE(step_sels));
+	clks[IMX6QDL_CLK_PLL1_SW]          = imx_clk_mux("pll1_sw",	         base + 0xc,  2,  1, pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
+	clks[IMX6QDL_CLK_PERIPH_PRE]       = imx_clk_mux("periph_pre",       base + 0x18, 18, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
+	clks[IMX6QDL_CLK_PERIPH2_PRE]      = imx_clk_mux("periph2_pre",      base + 0x18, 21, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
+	clks[IMX6QDL_CLK_PERIPH_CLK2_SEL]  = imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
+	clks[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
+	clks[IMX6QDL_CLK_AXI_SEL]          = imx_clk_mux("axi_sel",          base + 0x14, 6,  2, axi_sels,          ARRAY_SIZE(axi_sels));
+	clks[IMX6QDL_CLK_USDHC1_SEL]       = imx_clk_mux("usdhc1_sel",       base + 0x1c, 16, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6QDL_CLK_USDHC2_SEL]       = imx_clk_mux("usdhc2_sel",       base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6QDL_CLK_USDHC3_SEL]       = imx_clk_mux("usdhc3_sel",       base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6QDL_CLK_USDHC4_SEL]       = imx_clk_mux("usdhc4_sel",       base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6QDL_CLK_ENFC_SEL]         = imx_clk_mux("enfc_sel",         base + 0x2c, 16, 2, enfc_sels,         ARRAY_SIZE(enfc_sels));
+	clks[IMX6QDL_CLK_EIM_SEL]          = imx_clk_mux("eim_sel",          base + 0x1c, 27, 2, eim_sels,          ARRAY_SIZE(eim_sels));
+	clks[IMX6QDL_CLK_EIM_SLOW_SEL]     = imx_clk_mux("eim_slow_sel",     base + 0x1c, 29, 2, eim_sels,          ARRAY_SIZE(eim_sels));
+	clks[IMX6QDL_CLK_VDO_AXI_SEL]      = imx_clk_mux("vdo_axi_sel",      base + 0x18, 11, 1, vdo_axi_sels,      ARRAY_SIZE(vdo_axi_sels));
+	clks[IMX6QDL_CLK_CKO1_SEL]         = imx_clk_mux("cko1_sel",         base + 0x60, 0,  4, cko1_sels,         ARRAY_SIZE(cko1_sels));
+	clks[IMX6QDL_CLK_CKO2_SEL]         = imx_clk_mux("cko2_sel",         base + 0x60, 16, 5, cko2_sels,         ARRAY_SIZE(cko2_sels));
+	clks[IMX6QDL_CLK_CKO]              = imx_clk_mux("cko",              base + 0x60, 8,  1, cko_sels,          ARRAY_SIZE(cko_sels));
+	clks[IMX6QDL_CLK_PCIE_AXI_SEL]     = imx_clk_mux("pcie_axi_sel",     base + 0x18, 10, 1, pcie_axi_sels,     ARRAY_SIZE(pcie_axi_sels));
+
+	/*                              name         reg       shift width busy: reg, shift parent_names  num_parents */
+	clks[IMX6QDL_CLK_PERIPH]  = imx_clk_busy_mux("periph",  base + 0x14, 25,  1,   base + 0x48, 5,  periph_sels,  ARRAY_SIZE(periph_sels));
+	clks[IMX6QDL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26,  1,   base + 0x48, 3,  periph2_sels, ARRAY_SIZE(periph2_sels));
+
+	/*                                      name                 parent_name               reg       shift width */
+	clks[IMX6QDL_CLK_PERIPH_CLK2]      = imx_clk_divider("periph_clk2",      "periph_clk2_sel",   base + 0x14, 27, 3);
+	clks[IMX6QDL_CLK_PERIPH2_CLK2]     = imx_clk_divider("periph2_clk2",     "periph2_clk2_sel",  base + 0x14, 0,  3);
+	clks[IMX6QDL_CLK_IPG]              = imx_clk_divider("ipg",              "ahb",               base + 0x14, 8,  2);
+	clks[IMX6QDL_CLK_IPG_PER]          = imx_clk_divider("ipg_per",          "ipg",               base + 0x1c, 0,  6);
+	clks[IMX6QDL_CLK_CAN_ROOT]         = imx_clk_divider("can_root",         "pll3_usb_otg",      base + 0x20, 2,  6);
+	clks[IMX6QDL_CLK_ECSPI_ROOT]       = imx_clk_divider("ecspi_root",       "pll3_60m",          base + 0x38, 19, 6);
+	clks[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m",          base + 0x24, 0,  6);
+	clks[IMX6QDL_CLK_USDHC1_PODF]      = imx_clk_divider("usdhc1_podf",      "usdhc1_sel",        base + 0x24, 11, 3);
+	clks[IMX6QDL_CLK_USDHC2_PODF]      = imx_clk_divider("usdhc2_podf",      "usdhc2_sel",        base + 0x24, 16, 3);
+	clks[IMX6QDL_CLK_USDHC3_PODF]      = imx_clk_divider("usdhc3_podf",      "usdhc3_sel",        base + 0x24, 19, 3);
+	clks[IMX6QDL_CLK_USDHC4_PODF]      = imx_clk_divider("usdhc4_podf",      "usdhc4_sel",        base + 0x24, 22, 3);
+	clks[IMX6QDL_CLK_ENFC_PRED]        = imx_clk_divider("enfc_pred",        "enfc_sel",          base + 0x2c, 18, 3);
+	clks[IMX6QDL_CLK_ENFC_PODF]        = imx_clk_divider("enfc_podf",        "enfc_pred",         base + 0x2c, 21, 6);
+	clks[IMX6QDL_CLK_EIM_PODF]         = imx_clk_divider("eim_podf",         "eim_sel",           base + 0x1c, 20, 3);
+	clks[IMX6QDL_CLK_EIM_SLOW_PODF]    = imx_clk_divider("eim_slow_podf",    "eim_slow_sel",      base + 0x1c, 23, 3);
+	clks[IMX6QDL_CLK_CKO1_PODF]        = imx_clk_divider("cko1_podf",        "cko1_sel",          base + 0x60, 4,  3);
+	clks[IMX6QDL_CLK_CKO2_PODF]        = imx_clk_divider("cko2_podf",        "cko2_sel",          base + 0x60, 21, 3);
+
+	/*                                            name                  parent_name         reg        shift width busy: reg, shift */
+	clks[IMX6QDL_CLK_AXI]               = imx_clk_busy_divider("axi",               "axi_sel",     base + 0x14, 16,  3,   base + 0x48, 0);
+	clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph",      base + 0x14, 19,  3,   base + 0x48, 4);
+	clks[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2",     base + 0x14, 3,   3,   base + 0x48, 2);
+	clks[IMX6QDL_CLK_ARM]               = imx_clk_busy_divider("arm",               "pll1_sw",     base + 0x10, 0,   3,   base + 0x48, 16);
+	clks[IMX6QDL_CLK_AHB]               = imx_clk_busy_divider("ahb",               "periph",      base + 0x14, 10,  3,   base + 0x48, 1);
+
+	/*                                            name             parent_name          reg         shift */
+	clks[IMX6QDL_CLK_APBH_DMA]     = imx_clk_gate2("apbh_dma",      "usdhc3",            base + 0x68, 4);
+	clks[IMX6QDL_CLK_CAAM_MEM]     = imx_clk_gate2("caam_mem",      "ahb",               base + 0x68, 8);
+	clks[IMX6QDL_CLK_CAAM_ACLK]    = imx_clk_gate2("caam_aclk",     "ahb",               base + 0x68, 10);
+	clks[IMX6QDL_CLK_CAAM_IPG]     = imx_clk_gate2("caam_ipg",      "ipg",               base + 0x68, 12);
+	clks[IMX6QDL_CLK_ECSPI1]       = imx_clk_gate2("ecspi1",        "ecspi_root",        base + 0x6c, 0);
+	clks[IMX6QDL_CLK_ECSPI2]       = imx_clk_gate2("ecspi2",        "ecspi_root",        base + 0x6c, 2);
+	clks[IMX6QDL_CLK_ECSPI3]       = imx_clk_gate2("ecspi3",        "ecspi_root",        base + 0x6c, 4);
+	clks[IMX6QDL_CLK_ECSPI4]       = imx_clk_gate2("ecspi4",        "ecspi_root",        base + 0x6c, 6);
+	if (cpu_is_mx6dl())
+		clks[IMX6DL_CLK_I2C4]  = imx_clk_gate2("i2c4",          "ipg_per",           base + 0x6c, 8);
+	else
+		clks[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5",        "ecspi_root",        base + 0x6c, 8);
+	clks[IMX6QDL_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x6c, 10);
+	clks[IMX6QDL_CLK_GPT_IPG]      = imx_clk_gate2("gpt_ipg",       "ipg",               base + 0x6c, 20);
+	clks[IMX6QDL_CLK_GPT_IPG_PER]  = imx_clk_gate2("gpt_ipg_per",   "ipg_per",           base + 0x6c, 22);
+	clks[IMX6QDL_CLK_I2C1]         = imx_clk_gate2("i2c1",          "ipg_per",           base + 0x70, 6);
+	clks[IMX6QDL_CLK_I2C2]         = imx_clk_gate2("i2c2",          "ipg_per",           base + 0x70, 8);
+	clks[IMX6QDL_CLK_I2C3]         = imx_clk_gate2("i2c3",          "ipg_per",           base + 0x70, 10);
+	clks[IMX6QDL_CLK_IIM]          = imx_clk_gate2("iim",           "ipg",               base + 0x70, 12);
+	clks[IMX6QDL_CLK_ENFC]         = imx_clk_gate2("enfc",          "enfc_podf",         base + 0x70, 14);
+	clks[IMX6QDL_CLK_PCIE_AXI]     = imx_clk_gate2("pcie_axi",      "pcie_axi_sel",      base + 0x78, 0);
+	clks[IMX6QDL_CLK_PER1_BCH]     = imx_clk_gate2("per1_bch",      "usdhc3",            base + 0x78, 12);
+	clks[IMX6QDL_CLK_PWM1]         = imx_clk_gate2("pwm1",          "ipg_per",           base + 0x78, 16);
+	clks[IMX6QDL_CLK_PWM2]         = imx_clk_gate2("pwm2",          "ipg_per",           base + 0x78, 18);
+	clks[IMX6QDL_CLK_PWM3]         = imx_clk_gate2("pwm3",          "ipg_per",           base + 0x78, 20);
+	clks[IMX6QDL_CLK_PWM4]         = imx_clk_gate2("pwm4",          "ipg_per",           base + 0x78, 22);
+	clks[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
+	clks[IMX6QDL_CLK_GPMI_BCH]     = imx_clk_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
+	clks[IMX6QDL_CLK_GPMI_IO]      = imx_clk_gate2("gpmi_io",       "enfc",              base + 0x78, 28);
+	clks[IMX6QDL_CLK_GPMI_APB]     = imx_clk_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
+	clks[IMX6QDL_CLK_SATA]         = imx_clk_gate2("sata",          "ipg",               base + 0x7c, 4);
+	clks[IMX6QDL_CLK_UART_IPG]     = imx_clk_gate2("uart_ipg",      "ipg",               base + 0x7c, 24);
+	clks[IMX6QDL_CLK_UART_SERIAL]  = imx_clk_gate2("uart_serial",   "uart_serial_podf",  base + 0x7c, 26);
+	clks[IMX6QDL_CLK_USBOH3]       = imx_clk_gate2("usboh3",        "ipg",               base + 0x80, 0);
+	clks[IMX6QDL_CLK_USDHC1]       = imx_clk_gate2("usdhc1",        "usdhc1_podf",       base + 0x80, 2);
+	clks[IMX6QDL_CLK_USDHC2]       = imx_clk_gate2("usdhc2",        "usdhc2_podf",       base + 0x80, 4);
+	clks[IMX6QDL_CLK_USDHC3]       = imx_clk_gate2("usdhc3",        "usdhc3_podf",       base + 0x80, 6);
+	clks[IMX6QDL_CLK_USDHC4]       = imx_clk_gate2("usdhc4",        "usdhc4_podf",       base + 0x80, 8);
+	clks[IMX6QDL_CLK_EIM_SLOW]     = imx_clk_gate2("eim_slow",      "eim_slow_podf",     base + 0x80, 10);
+	clks[IMX6QDL_CLK_CKO1]         = imx_clk_gate("cko1",           "cko1_podf",         base + 0x60, 7);
+	clks[IMX6QDL_CLK_CKO2]         = imx_clk_gate("cko2",           "cko2_podf",         base + 0x60, 24);
+
+	clkdev_add_physbase(clks[IMX6QDL_CLK_IPG], MX6_OCOTP_BASE_ADDR, NULL);
+
+	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+		imx6_add_video_clks(anatop_base, ccm_base);
+
+	writel(0xffffffff, ccm_base + CCGR0);
+	writel(0xf0ffffff, ccm_base + CCGR1); /* gate GPU3D, GPU2D */
+	writel(0xffffffff, ccm_base + CCGR2);
+	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+		writel(0x3fffffff, ccm_base + CCGR3); /* gate OpenVG */
+	else
+		writel(0x3fff0000, ccm_base + CCGR3); /* gate OpenVG, LDB, IPU1, IPU2 */
+	if (IS_ENABLED(CONFIG_PCI_IMX6))
+		writel(0xffffffff, ccm_base + CCGR4);
+	else
+		writel(0xfffffffc, ccm_base + CCGR4); /* gate PCIe */
+	writel(0xffffffff, ccm_base + CCGR5);
+	writel(0xffff3fff, ccm_base + CCGR6); /* gate VPU */
+	writel(0xffffffff, ccm_base + CCGR7);
+
+	clk_data.clks = clks;
+	clk_data.clk_num = IMX6QDL_CLK_END;
+	of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data);
+
+	clk_enable(clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF]);
+	clk_enable(clks[IMX6QDL_CLK_PLL6_ENET]);
+	clk_enable(clks[IMX6QDL_CLK_SATA_REF_100M]);
+	clk_enable(clks[IMX6QDL_CLK_ENFC_PODF]);
+
+	clk_set_parent(clks[IMX6QDL_CLK_LVDS1_SEL], clks[IMX6QDL_CLK_SATA_REF_100M]);
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx6q-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx6_ccm_driver = {
+	.probe	= imx6_ccm_probe,
+	.name	= "imx6-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx6_ccm_dt_ids),
+};
+
+static int imx6_ccm_init(void)
+{
+	return platform_driver_register(&imx6_ccm_driver);
+}
+core_initcall(imx6_ccm_init);
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
new file mode 100644
index 0000000..d758957
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <dt-bindings/clock/imx6sx-clock.h>
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <mach/imx6-regs.h>
+#include <mach/revision.h>
+#include <mach/imx6.h>
+
+#include "clk.h"
+#include "common.h"
+
+#define CCDR    0x4
+#define BM_CCM_CCDR_MMDC_CH0_MASK       (0x2 << 16)
+
+static const char *step_sels[]		= { "osc", "pll2_pfd2_396m", };
+static const char *pll1_sw_sels[]	= { "pll1_sys", "step", };
+static const char *periph_pre_sels[]	= { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static const char *periph2_pre_sels[]	= { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
+static const char *periph_clk2_sels[]	= { "pll3_usb_otg", "osc", "osc", };
+static const char *periph2_clk2_sels[]	= { "pll3_usb_otg", "osc", };
+static const char *periph_sels[]	= { "periph_pre", "periph_clk2", };
+static const char *periph2_sels[]	= { "periph2_pre", "periph2_clk2", };
+static const char *ocram_sels[]		= { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
+static const char *gpu_axi_sels[]	= { "pll2_pfd2_396m", "pll3_pfd0_720m", "pll3_pfd1_540m", "pll2_bus", };
+static const char *gpu_core_sels[]	= { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", };
+static const char *ldb_di0_div_sels[]	= { "ldb_di0_div_3_5", "ldb_di0_div_7", };
+static const char *ldb_di1_div_sels[]	= { "ldb_di1_div_3_5", "ldb_di1_div_7", };
+static const char *ldb_di0_sels[]	= { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
+static const char *ldb_di1_sels[]	= { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *pcie_axi_sels[]	= { "axi", "ahb", };
+static const char *qspi1_sels[]		= { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *perclk_sels[]	= { "ipg", "osc", };
+static const char *usdhc_sels[]		= { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *vid_sels[]		= { "pll3_pfd1_540m", "pll3_usb_otg", "pll3_pfd3_454m", "pll4_audio_div", "pll5_video_div", };
+static const char *uart_sels[]		= { "pll3_80m", "osc", };
+static const char *qspi2_sels[]		= { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", "dummy", "dummy", };
+static const char *enet_pre_sels[]	= { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
+static const char *enet_sels[]		= { "enet_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *m4_pre_sels[]	= { "pll2_bus", "pll3_usb_otg", "osc", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd3_454m", };
+static const char *m4_sels[]		= { "m4_pre_sel", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *eim_slow_sels[]	= { "ocram", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *ecspi_sels[]		= { "pll3_60m", "osc", };
+static const char *lcdif1_pre_sels[]	= { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
+static const char *lcdif1_sels[]	= { "lcdif1_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *lcdif2_pre_sels[]	= { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd3_594m", "pll3_pfd1_540m", };
+static const char *lcdif2_sels[]	= { "lcdif2_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *display_sels[]	= { "pll2_bus", "pll2_pfd2_396m", "pll3_usb_otg", "pll3_pfd1_540m", };
+static const char *csi_sels[]		= { "osc", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
+static const char *cko1_sels[]		= {
+	"pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
+	"dummy", "ocram", "dummy", "pxp_axi", "epdc_axi", "lcdif_pix",
+	"epdc_pix", "ahb", "ipg", "perclk", "ckil", "pll4_audio_div",
+};
+static const char *cko2_sels[]		= {
+	"dummy", "mmdc_p0_fast", "usdhc4", "usdhc1", "dummy", "wrck",
+	"ecspi_root", "dummy", "usdhc3", "pcie", "arm", "csi_core",
+	"lcdif_axi", "dummy", "osc", "dummy", "gpu2d_ovg_core",
+	"usdhc2", "ssi1", "ssi2", "ssi3", "gpu2d_core", "dummy",
+	"dummy", "dummy", "dummy", "esai_extal", "eim_slow", "uart_serial",
+	"spdif", "asrc", "dummy",
+};
+static const char *cko_sels[] = { "cko1", "cko2", };
+static const char *lvds_sels[]	= {
+	"arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div",
+	"dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2",
+};
+static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+
+static struct clk *clks[IMX6SX_CLK_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static struct clk_div_table clk_enet_ref_table[] = {
+	{ .val = 0, .div = 20, },
+	{ .val = 1, .div = 10, },
+	{ .val = 2, .div = 5, },
+	{ .val = 3, .div = 4, },
+	{ }
+};
+
+static struct clk_div_table post_div_table[] = {
+	{ .val = 2, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 0, .div = 4, },
+	{ }
+};
+
+static struct clk_div_table video_div_table[] = {
+	{ .val = 0, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 2, .div = 1, },
+	{ .val = 3, .div = 4, },
+	{ }
+};
+
+static int imx6sx_ccm_probe(struct device_d *dev)
+{
+	struct resource *iores;
+	void __iomem *base, *anatop_base, *ccm_base;
+	struct device_node *ccm_node = dev->device_node;
+
+	clks[IMX6SX_CLK_DUMMY] = clk_fixed("dummy", 0);
+
+	anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	ccm_base = IOMEM(iores->start);
+
+	base = anatop_base;
+
+	clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+	/*                                    type               name    parent_name        base         div_mask */
+	clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS,     "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
+	clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
+	clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB,     "pll3", "pll3_bypass_src", base + 0x10, 0x3);
+	clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV,      "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
+	clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV,      "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
+	clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET,    "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
+	clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB,     "pll7", "pll7_bypass_src", base + 0x20, 0x3);
+
+	clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_p("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels));
+	clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_p("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels));
+	clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_p("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels));
+	clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_p("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels));
+	clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_p("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels));
+	clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_p("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels));
+	clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_p("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels));
+
+	/* Do not bypass PLLs initially */
+	clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
+	clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
+	clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
+	clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
+	clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
+	clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
+	clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
+
+	clks[IMX6SX_CLK_PLL1_SYS]      = imx_clk_gate("pll1_sys",      "pll1_bypass", base + 0x00, 13);
+	clks[IMX6SX_CLK_PLL2_BUS]      = imx_clk_gate("pll2_bus",      "pll2_bypass", base + 0x30, 13);
+	clks[IMX6SX_CLK_PLL3_USB_OTG]  = imx_clk_gate("pll3_usb_otg",  "pll3_bypass", base + 0x10, 13);
+	clks[IMX6SX_CLK_PLL4_AUDIO]    = imx_clk_gate("pll4_audio",    "pll4_bypass", base + 0x70, 13);
+	clks[IMX6SX_CLK_PLL5_VIDEO]    = imx_clk_gate("pll5_video",    "pll5_bypass", base + 0xa0, 13);
+	clks[IMX6SX_CLK_PLL6_ENET]     = imx_clk_gate("pll6_enet",     "pll6_bypass", base + 0xe0, 13);
+	clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
+
+	/*
+	 * Bit 20 is the reserved and read-only bit, we do this only for:
+	 * - Do nothing for usbphy clk_enable/disable
+	 * - Keep refcount when do usbphy clk_enable/disable, in that case,
+	 * the clk framework may need to enable/disable usbphy's parent
+	 */
+	clks[IMX6SX_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg",  base + 0x10, 20);
+	clks[IMX6SX_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
+
+	/*
+	 * usbphy*_gate needs to be on after system boots up, and software
+	 * never needs to control it anymore.
+	 */
+	clks[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+	clks[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+	/* FIXME 100Mhz is used for pcie ref for all imx6 pcie, excepted imx6q */
+	clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5);
+	clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+	clks[IMX6SX_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet",
+			base + 0xe0, 0, 2, clk_enet_ref_table);
+	clks[IMX6SX_CLK_ENET2_REF] = imx_clk_divider_table("enet2_ref", "pll6_enet",
+			base + 0xe0, 2, 2, clk_enet_ref_table);
+	clks[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20);
+
+	clks[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
+	clks[IMX6SX_CLK_ENET_PTP] = imx_clk_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21);
+
+	/*                                       name              parent_name     reg           idx */
+	clks[IMX6SX_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
+	clks[IMX6SX_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",     base + 0x100, 1);
+	clks[IMX6SX_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus",     base + 0x100, 2);
+	clks[IMX6SX_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus",     base + 0x100, 3);
+	clks[IMX6SX_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0,  0);
+	clks[IMX6SX_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0,  1);
+	clks[IMX6SX_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0,  2);
+	clks[IMX6SX_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0,  3);
+
+	/*                                                name         parent_name       mult div */
+	clks[IMX6SX_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1,   2);
+	clks[IMX6SX_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg",   1,   4);
+	clks[IMX6SX_CLK_PLL3_80M]  = imx_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1,   6);
+	clks[IMX6SX_CLK_PLL3_60M]  = imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1,   8);
+	clks[IMX6SX_CLK_TWD]       = imx_clk_fixed_factor("twd",       "arm",            1,   2);
+	clks[IMX6SX_CLK_GPT_3M]    = imx_clk_fixed_factor("gpt_3m",    "osc",            1,   8);
+
+	clks[IMX6SX_CLK_PLL4_POST_DIV]  = imx_clk_divider_table("pll4_post_div", "pll4_audio",
+				base + 0x70, 19, 2, post_div_table);
+	clks[IMX6SX_CLK_PLL4_AUDIO_DIV] = imx_clk_divider("pll4_audio_div", "pll4_post_div",
+				base + 0x170, 15, 1);
+	clks[IMX6SX_CLK_PLL5_POST_DIV]  = imx_clk_divider_table("pll5_post_div", "pll5_video",
+				base + 0xa0, 19, 2, post_div_table);
+	clks[IMX6SX_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div",
+				base + 0x170, 30, 2, video_div_table);
+
+	/*                                                name                reg           shift   width   parent_names       num_parents */
+	clks[IMX6SX_CLK_LVDS1_SEL]          = imx_clk_mux("lvds1_sel",        base + 0x160, 0,      5,      lvds_sels,         ARRAY_SIZE(lvds_sels));
+
+	base = ccm_base;
+
+	/*                                                name                reg           shift   width   parent_names       num_parents */
+	clks[IMX6SX_CLK_STEP]               = imx_clk_mux("step",             base + 0xc,   8,      1,      step_sels,         ARRAY_SIZE(step_sels));
+	clks[IMX6SX_CLK_PLL1_SW]            = imx_clk_mux("pll1_sw",          base + 0xc,   2,      1,      pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
+	clks[IMX6SX_CLK_OCRAM_SEL]          = imx_clk_mux("ocram_sel",        base + 0x14,  6,      2,      ocram_sels,        ARRAY_SIZE(ocram_sels));
+	clks[IMX6SX_CLK_PERIPH_PRE]         = imx_clk_mux("periph_pre",       base + 0x18,  18,     2,      periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
+	clks[IMX6SX_CLK_PERIPH2_PRE]        = imx_clk_mux("periph2_pre",      base + 0x18,  21,     2,      periph2_pre_sels,   ARRAY_SIZE(periph2_pre_sels));
+	clks[IMX6SX_CLK_PERIPH_CLK2_SEL]    = imx_clk_mux("periph_clk2_sel",  base + 0x18,  12,     2,      periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
+	clks[IMX6SX_CLK_PERIPH2_CLK2_SEL]   = imx_clk_mux("periph2_clk2_sel", base + 0x18,  20,     1,      periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+	clks[IMX6SX_CLK_PCIE_AXI_SEL]       = imx_clk_mux("pcie_axi_sel",     base + 0x18,  10,     1,      pcie_axi_sels,     ARRAY_SIZE(pcie_axi_sels));
+	clks[IMX6SX_CLK_GPU_AXI_SEL]        = imx_clk_mux("gpu_axi_sel",      base + 0x18,  8,      2,      gpu_axi_sels,      ARRAY_SIZE(gpu_axi_sels));
+	clks[IMX6SX_CLK_GPU_CORE_SEL]       = imx_clk_mux("gpu_core_sel",     base + 0x18,  4,      2,      gpu_core_sels,     ARRAY_SIZE(gpu_core_sels));
+	clks[IMX6SX_CLK_EIM_SLOW_SEL]       = imx_clk_mux("eim_slow_sel",     base + 0x1c,  29,     2,      eim_slow_sels,     ARRAY_SIZE(eim_slow_sels));
+	clks[IMX6SX_CLK_USDHC1_SEL]         = imx_clk_mux("usdhc1_sel",       base + 0x1c,  16,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SX_CLK_USDHC2_SEL]         = imx_clk_mux("usdhc2_sel",       base + 0x1c,  17,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SX_CLK_USDHC3_SEL]         = imx_clk_mux("usdhc3_sel",       base + 0x1c,  18,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SX_CLK_USDHC4_SEL]         = imx_clk_mux("usdhc4_sel",       base + 0x1c,  19,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SX_CLK_QSPI1_SEL]          = imx_clk_mux_p("qspi1_sel", base + 0x1c,  7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
+	clks[IMX6SX_CLK_PERCLK_SEL]         = imx_clk_mux("perclk_sel",       base + 0x1c,  6,      1,      perclk_sels,       ARRAY_SIZE(perclk_sels));
+	clks[IMX6SX_CLK_VID_SEL]            = imx_clk_mux("vid_sel",          base + 0x20,  21,     3,      vid_sels,          ARRAY_SIZE(vid_sels));
+	clks[IMX6SX_CLK_UART_SEL]           = imx_clk_mux("uart_sel",         base + 0x24,  6,      1,      uart_sels,         ARRAY_SIZE(uart_sels));
+	clks[IMX6SX_CLK_QSPI2_SEL]          = imx_clk_mux_p("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels));
+	clks[IMX6SX_CLK_ENET_PRE_SEL]       = imx_clk_mux("enet_pre_sel",     base + 0x34,  15,     3,      enet_pre_sels,     ARRAY_SIZE(enet_pre_sels));
+	clks[IMX6SX_CLK_ENET_SEL]           = imx_clk_mux("enet_sel",         base + 0x34,  9,      3,      enet_sels,         ARRAY_SIZE(enet_sels));
+	clks[IMX6SX_CLK_M4_PRE_SEL]         = imx_clk_mux("m4_pre_sel",       base + 0x34,  6,      3,      m4_pre_sels,       ARRAY_SIZE(m4_pre_sels));
+	clks[IMX6SX_CLK_M4_SEL]             = imx_clk_mux("m4_sel",           base + 0x34,  0,      3,      m4_sels,           ARRAY_SIZE(m4_sels));
+	clks[IMX6SX_CLK_ECSPI_SEL]          = imx_clk_mux("ecspi_sel",        base + 0x38,  18,     1,      ecspi_sels,        ARRAY_SIZE(ecspi_sels));
+	clks[IMX6SX_CLK_LCDIF2_PRE_SEL]     = imx_clk_mux("lcdif2_pre_sel",   base + 0x38,  6,      3,      lcdif2_pre_sels,   ARRAY_SIZE(lcdif2_pre_sels));
+	clks[IMX6SX_CLK_LCDIF2_SEL]         = imx_clk_mux("lcdif2_sel",       base + 0x38,  0,      3,      lcdif2_sels,       ARRAY_SIZE(lcdif2_sels));
+	clks[IMX6SX_CLK_DISPLAY_SEL]        = imx_clk_mux("display_sel",      base + 0x3c,  14,     2,      display_sels,      ARRAY_SIZE(display_sels));
+	clks[IMX6SX_CLK_CSI_SEL]            = imx_clk_mux("csi_sel",          base + 0x3c,  9,      2,      csi_sels,          ARRAY_SIZE(csi_sels));
+	clks[IMX6SX_CLK_CKO1_SEL]           = imx_clk_mux("cko1_sel",         base + 0x60,  0,      4,      cko1_sels,         ARRAY_SIZE(cko1_sels));
+	clks[IMX6SX_CLK_CKO2_SEL]           = imx_clk_mux("cko2_sel",         base + 0x60,  16,     5,      cko2_sels,         ARRAY_SIZE(cko2_sels));
+	clks[IMX6SX_CLK_CKO]                = imx_clk_mux("cko",              base + 0x60,  8,      1,      cko_sels,          ARRAY_SIZE(cko_sels));
+
+	clks[IMX6SX_CLK_LDB_DI1_DIV_SEL]    = imx_clk_mux_p("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
+	clks[IMX6SX_CLK_LDB_DI0_DIV_SEL]    = imx_clk_mux_p("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
+	clks[IMX6SX_CLK_LDB_DI1_SEL]        = imx_clk_mux_p("ldb_di1_sel",     base + 0x2c, 12, 3, ldb_di1_sels,      ARRAY_SIZE(ldb_di1_sels));
+	clks[IMX6SX_CLK_LDB_DI0_SEL]        = imx_clk_mux_p("ldb_di0_sel",     base + 0x2c, 9,  3, ldb_di0_sels,      ARRAY_SIZE(ldb_di0_sels));
+	clks[IMX6SX_CLK_LCDIF1_PRE_SEL]     = imx_clk_mux_p("lcdif1_pre_sel",  base + 0x38, 15, 3, lcdif1_pre_sels,   ARRAY_SIZE(lcdif1_pre_sels));
+	clks[IMX6SX_CLK_LCDIF1_SEL]         = imx_clk_mux_p("lcdif1_sel",      base + 0x38, 9,  3, lcdif1_sels,       ARRAY_SIZE(lcdif1_sels));
+
+	/*                                                    name              parent_name          reg          shift width */
+	clks[IMX6SX_CLK_PERIPH_CLK2]        = imx_clk_divider("periph_clk2",    "periph_clk2_sel",   base + 0x14, 27,   3);
+	clks[IMX6SX_CLK_PERIPH2_CLK2]       = imx_clk_divider("periph2_clk2",   "periph2_clk2_sel",  base + 0x14, 0,    3);
+	clks[IMX6SX_CLK_IPG]                = imx_clk_divider("ipg",            "ahb",               base + 0x14, 8,    2);
+	clks[IMX6SX_CLK_GPU_CORE_PODF]      = imx_clk_divider("gpu_core_podf",  "gpu_core_sel",      base + 0x18, 29,   3);
+	clks[IMX6SX_CLK_GPU_AXI_PODF]       = imx_clk_divider("gpu_axi_podf",   "gpu_axi_sel",       base + 0x18, 26,   3);
+	clks[IMX6SX_CLK_LCDIF1_PODF]        = imx_clk_divider("lcdif1_podf",    "lcdif1_pred",       base + 0x18, 23,   3);
+	clks[IMX6SX_CLK_QSPI1_PODF]         = imx_clk_divider("qspi1_podf",     "qspi1_sel",         base + 0x1c, 26,   3);
+	clks[IMX6SX_CLK_EIM_SLOW_PODF]      = imx_clk_divider("eim_slow_podf",  "eim_slow_sel",      base + 0x1c, 23,   3);
+	clks[IMX6SX_CLK_LCDIF2_PODF]        = imx_clk_divider("lcdif2_podf",    "lcdif2_pred",       base + 0x1c, 20,   3);
+	clks[IMX6SX_CLK_PERCLK]             = imx_clk_divider("perclk",         "perclk_sel",        base + 0x1c, 0,    6);
+	clks[IMX6SX_CLK_VID_PODF]           = imx_clk_divider("vid_podf",       "vid_sel",           base + 0x20, 24,   2);
+	clks[IMX6SX_CLK_USDHC4_PODF]        = imx_clk_divider("usdhc4_podf",    "usdhc4_sel",        base + 0x24, 22,   3);
+	clks[IMX6SX_CLK_USDHC3_PODF]        = imx_clk_divider("usdhc3_podf",    "usdhc3_sel",        base + 0x24, 19,   3);
+	clks[IMX6SX_CLK_USDHC2_PODF]        = imx_clk_divider("usdhc2_podf",    "usdhc2_sel",        base + 0x24, 16,   3);
+	clks[IMX6SX_CLK_USDHC1_PODF]        = imx_clk_divider("usdhc1_podf",    "usdhc1_sel",        base + 0x24, 11,   3);
+	clks[IMX6SX_CLK_UART_PODF]          = imx_clk_divider("uart_podf",      "uart_sel",          base + 0x24, 0,    6);
+	clks[IMX6SX_CLK_QSPI2_PRED]         = imx_clk_divider("qspi2_pred",     "qspi2_sel",         base + 0x2c, 18,   3);
+	clks[IMX6SX_CLK_QSPI2_PODF]         = imx_clk_divider("qspi2_podf",     "qspi2_pred",        base + 0x2c, 21,   6);
+	clks[IMX6SX_CLK_ENET_PODF]          = imx_clk_divider("enet_podf",      "enet_pre_sel",      base + 0x34, 12,   3);
+	clks[IMX6SX_CLK_M4_PODF]            = imx_clk_divider("m4_podf",        "m4_sel",            base + 0x34, 3,    3);
+	clks[IMX6SX_CLK_ECSPI_PODF]         = imx_clk_divider("ecspi_podf",     "ecspi_sel",         base + 0x38, 19,   6);
+	clks[IMX6SX_CLK_LCDIF1_PRED]        = imx_clk_divider("lcdif1_pred",    "lcdif1_pre_sel",    base + 0x38, 12,   3);
+	clks[IMX6SX_CLK_LCDIF2_PRED]        = imx_clk_divider("lcdif2_pred",    "lcdif2_pre_sel",    base + 0x38, 3,    3);
+	clks[IMX6SX_CLK_DISPLAY_PODF]       = imx_clk_divider("display_podf",   "display_sel",       base + 0x3c, 16,   3);
+	clks[IMX6SX_CLK_CSI_PODF]           = imx_clk_divider("csi_podf",       "csi_sel",           base + 0x3c, 11,   3);
+	clks[IMX6SX_CLK_CKO1_PODF]          = imx_clk_divider("cko1_podf",      "cko1_sel",          base + 0x60, 4,    3);
+	clks[IMX6SX_CLK_CKO2_PODF]          = imx_clk_divider("cko2_podf",      "cko2_sel",          base + 0x60, 21,   3);
+
+	clks[IMX6SX_CLK_LDB_DI0_DIV_3_5]    = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+	clks[IMX6SX_CLK_LDB_DI0_DIV_7]      = imx_clk_fixed_factor("ldb_di0_div_7",   "ldb_di0_sel", 1, 7);
+	clks[IMX6SX_CLK_LDB_DI1_DIV_3_5]    = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+	clks[IMX6SX_CLK_LDB_DI1_DIV_7]      = imx_clk_fixed_factor("ldb_di1_div_7",   "ldb_di1_sel", 1, 7);
+
+	/*                                               name        reg          shift width busy: reg,   shift parent_names       num_parents */
+	clks[IMX6SX_CLK_PERIPH]       = imx_clk_busy_mux("periph",   base + 0x14, 25,   1,    base + 0x48, 5,    periph_sels,       ARRAY_SIZE(periph_sels));
+	clks[IMX6SX_CLK_PERIPH2]      = imx_clk_busy_mux("periph2",  base + 0x14, 26,   1,    base + 0x48, 3,    periph2_sels,      ARRAY_SIZE(periph2_sels));
+	/*                                                   name             parent_name    reg          shift width busy: reg,   shift */
+	clks[IMX6SX_CLK_OCRAM_PODF]   = imx_clk_busy_divider("ocram_podf",    "ocram_sel",   base + 0x14, 16,   3,    base + 0x48, 0);
+	clks[IMX6SX_CLK_AHB]          = imx_clk_busy_divider("ahb",           "periph",      base + 0x14, 10,   3,    base + 0x48, 1);
+	clks[IMX6SX_CLK_MMDC_PODF]    = imx_clk_busy_divider("mmdc_podf",     "periph2",     base + 0x14, 3,    3,    base + 0x48, 2);
+	clks[IMX6SX_CLK_ARM]          = imx_clk_busy_divider("arm",           "pll1_sw",     base + 0x10, 0,    3,    base + 0x48, 16);
+
+	/*                                            name             parent_name          reg         shift */
+	/* CCGR0 */
+	clks[IMX6SX_CLK_AIPS_TZ1]     = imx_clk_gate2("aips_tz1",      "ahb",               base + 0x68, 0);
+	clks[IMX6SX_CLK_AIPS_TZ2]     = imx_clk_gate2("aips_tz2",      "ahb",               base + 0x68, 2);
+	clks[IMX6SX_CLK_APBH_DMA]     = imx_clk_gate2("apbh_dma",      "usdhc3",            base + 0x68, 4);
+	clks[IMX6SX_CLK_CAAM_MEM]     = imx_clk_gate2("caam_mem",      "ahb",               base + 0x68, 8);
+	clks[IMX6SX_CLK_CAAM_ACLK]    = imx_clk_gate2("caam_aclk",     "ahb",               base + 0x68, 10);
+	clks[IMX6SX_CLK_CAAM_IPG]     = imx_clk_gate2("caam_ipg",      "ipg",               base + 0x68, 12);
+	clks[IMX6SX_CLK_DCIC1]        = imx_clk_gate2("dcic1",         "display_podf",      base + 0x68, 24);
+	clks[IMX6SX_CLK_DCIC2]        = imx_clk_gate2("dcic2",         "display_podf",      base + 0x68, 26);
+	clks[IMX6SX_CLK_AIPS_TZ3]     = imx_clk_gate2("aips_tz3",      "ahb",               base + 0x68, 30);
+
+	/* CCGR1 */
+	clks[IMX6SX_CLK_ECSPI1]       = imx_clk_gate2("ecspi1",        "ecspi_podf",        base + 0x6c, 0);
+	clks[IMX6SX_CLK_ECSPI2]       = imx_clk_gate2("ecspi2",        "ecspi_podf",        base + 0x6c, 2);
+	clks[IMX6SX_CLK_ECSPI3]       = imx_clk_gate2("ecspi3",        "ecspi_podf",        base + 0x6c, 4);
+	clks[IMX6SX_CLK_ECSPI4]       = imx_clk_gate2("ecspi4",        "ecspi_podf",        base + 0x6c, 6);
+	clks[IMX6SX_CLK_ECSPI5]       = imx_clk_gate2("ecspi5",        "ecspi_podf",        base + 0x6c, 8);
+	clks[IMX6SX_CLK_EPIT1]        = imx_clk_gate2("epit1",         "perclk",            base + 0x6c, 12);
+	clks[IMX6SX_CLK_EPIT2]        = imx_clk_gate2("epit2",         "perclk",            base + 0x6c, 14);
+	clks[IMX6SX_CLK_WAKEUP]       = imx_clk_gate2("wakeup",        "ipg",               base + 0x6c, 18);
+	clks[IMX6SX_CLK_GPT_BUS]      = imx_clk_gate2("gpt_bus",       "perclk",            base + 0x6c, 20);
+	clks[IMX6SX_CLK_GPT_SERIAL]   = imx_clk_gate2("gpt_serial",    "perclk",            base + 0x6c, 22);
+	clks[IMX6SX_CLK_GPU]          = imx_clk_gate2("gpu",           "gpu_core_podf",     base + 0x6c, 26);
+
+	/* CCGR2 */
+	clks[IMX6SX_CLK_CSI]          = imx_clk_gate2("csi",           "csi_podf",          base + 0x70, 2);
+	clks[IMX6SX_CLK_I2C1]         = imx_clk_gate2("i2c1",          "perclk",            base + 0x70, 6);
+	clks[IMX6SX_CLK_I2C2]         = imx_clk_gate2("i2c2",          "perclk",            base + 0x70, 8);
+	clks[IMX6SX_CLK_I2C3]         = imx_clk_gate2("i2c3",          "perclk",            base + 0x70, 10);
+	clks[IMX6SX_CLK_OCOTP]        = imx_clk_gate2("ocotp",         "ipg",               base + 0x70, 12);
+	clks[IMX6SX_CLK_IOMUXC]       = imx_clk_gate2("iomuxc",        "lcdif1_podf",       base + 0x70, 14);
+	clks[IMX6SX_CLK_IPMUX1]       = imx_clk_gate2("ipmux1",        "ahb",               base + 0x70, 16);
+	clks[IMX6SX_CLK_IPMUX2]       = imx_clk_gate2("ipmux2",        "ahb",               base + 0x70, 18);
+	clks[IMX6SX_CLK_IPMUX3]       = imx_clk_gate2("ipmux3",        "ahb",               base + 0x70, 20);
+	clks[IMX6SX_CLK_TZASC1]       = imx_clk_gate2("tzasc1",        "mmdc_podf",         base + 0x70, 22);
+	clks[IMX6SX_CLK_LCDIF_APB]    = imx_clk_gate2("lcdif_apb",     "display_podf",      base + 0x70, 28);
+	clks[IMX6SX_CLK_PXP_AXI]      = imx_clk_gate2("pxp_axi",       "display_podf",      base + 0x70, 30);
+
+	/* CCGR3 */
+	clks[IMX6SX_CLK_M4]           = imx_clk_gate2("m4",            "m4_podf",           base + 0x74, 2);
+	clks[IMX6SX_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x74, 4);
+	clks[IMX6SX_CLK_ENET_AHB]     = imx_clk_gate2("enet_ahb",      "enet_sel",          base + 0x74, 4);
+	clks[IMX6SX_CLK_DISPLAY_AXI]  = imx_clk_gate2("display_axi",   "display_podf",      base + 0x74, 6);
+	clks[IMX6SX_CLK_LCDIF2_PIX]   = imx_clk_gate2("lcdif2_pix",    "lcdif2_sel",        base + 0x74, 8);
+	clks[IMX6SX_CLK_LCDIF1_PIX]   = imx_clk_gate2("lcdif1_pix",    "lcdif1_sel",        base + 0x74, 10);
+	clks[IMX6SX_CLK_LDB_DI0]      = imx_clk_gate2("ldb_di0",       "ldb_di0_div_sel",   base + 0x74, 12);
+	clks[IMX6SX_CLK_QSPI1]        = imx_clk_gate2("qspi1",         "qspi1_podf",        base + 0x74, 14);
+	clks[IMX6SX_CLK_MLB]          = imx_clk_gate2("mlb",           "ahb",               base + 0x74, 18);
+	clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast",  "mmdc_podf",         base + 0x74, 20);
+	clks[IMX6SX_CLK_MMDC_P0_IPG]  = imx_clk_gate2("mmdc_p0_ipg",   "ipg",               base + 0x74, 24);
+	clks[IMX6SX_CLK_OCRAM]        = imx_clk_gate2("ocram",         "ocram_podf",        base + 0x74, 28);
+
+	/* CCGR4 */
+	clks[IMX6SX_CLK_PCIE_AXI]     = imx_clk_gate2("pcie_axi",      "display_podf",      base + 0x78, 0);
+	clks[IMX6SX_CLK_QSPI2]        = imx_clk_gate2("qspi2",         "qspi2_podf",        base + 0x78, 10);
+	clks[IMX6SX_CLK_PER1_BCH]     = imx_clk_gate2("per1_bch",      "usdhc3",            base + 0x78, 12);
+	clks[IMX6SX_CLK_PER2_MAIN]    = imx_clk_gate2("per2_main",     "ahb",               base + 0x78, 14);
+	clks[IMX6SX_CLK_PWM1]         = imx_clk_gate2("pwm1",          "perclk",            base + 0x78, 16);
+	clks[IMX6SX_CLK_PWM2]         = imx_clk_gate2("pwm2",          "perclk",            base + 0x78, 18);
+	clks[IMX6SX_CLK_PWM3]         = imx_clk_gate2("pwm3",          "perclk",            base + 0x78, 20);
+	clks[IMX6SX_CLK_PWM4]         = imx_clk_gate2("pwm4",          "perclk",            base + 0x78, 22);
+	clks[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
+	clks[IMX6SX_CLK_GPMI_BCH]     = imx_clk_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
+	clks[IMX6SX_CLK_GPMI_IO]      = imx_clk_gate2("gpmi_io",       "qspi2_podf",        base + 0x78, 28);
+	clks[IMX6SX_CLK_GPMI_APB]     = imx_clk_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
+
+	/* CCGR5 */
+	clks[IMX6SX_CLK_ROM]          = imx_clk_gate2("rom",           "ahb",               base + 0x7c, 0);
+	clks[IMX6SX_CLK_SDMA]         = imx_clk_gate2("sdma",          "ahb",               base + 0x7c, 6);
+	clks[IMX6SX_CLK_SPBA]         = imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
+	clks[IMX6SX_CLK_UART_IPG]     = imx_clk_gate2("uart_ipg",      "ipg",               base + 0x7c, 24);
+	clks[IMX6SX_CLK_UART_SERIAL]  = imx_clk_gate2("uart_serial",   "uart_podf",         base + 0x7c, 26);
+	clks[IMX6SX_CLK_SAI1_IPG]     = imx_clk_gate2("sai1_ipg",      "ipg",               base + 0x7c, 28);
+	clks[IMX6SX_CLK_SAI2_IPG]     = imx_clk_gate2("sai2_ipg",      "ipg",               base + 0x7c, 30);
+
+	/* CCGR6 */
+	clks[IMX6SX_CLK_USBOH3]       = imx_clk_gate2("usboh3",        "ipg",               base + 0x80, 0);
+	clks[IMX6SX_CLK_USDHC1]       = imx_clk_gate2("usdhc1",        "usdhc1_podf",       base + 0x80, 2);
+	clks[IMX6SX_CLK_USDHC2]       = imx_clk_gate2("usdhc2",        "usdhc2_podf",       base + 0x80, 4);
+	clks[IMX6SX_CLK_USDHC3]       = imx_clk_gate2("usdhc3",        "usdhc3_podf",       base + 0x80, 6);
+	clks[IMX6SX_CLK_USDHC4]       = imx_clk_gate2("usdhc4",        "usdhc4_podf",       base + 0x80, 8);
+	clks[IMX6SX_CLK_EIM_SLOW]     = imx_clk_gate2("eim_slow",      "eim_slow_podf",     base + 0x80, 10);
+	clks[IMX6SX_CLK_PWM8]         = imx_clk_gate2("pwm8",          "perclk",            base + 0x80, 16);
+	clks[IMX6SX_CLK_VADC]         = imx_clk_gate2("vadc",          "vid_podf",          base + 0x80, 20);
+	clks[IMX6SX_CLK_GIS]          = imx_clk_gate2("gis",           "display_podf",      base + 0x80, 22);
+	clks[IMX6SX_CLK_I2C4]         = imx_clk_gate2("i2c4",          "perclk",            base + 0x80, 24);
+	clks[IMX6SX_CLK_PWM5]         = imx_clk_gate2("pwm5",          "perclk",            base + 0x80, 26);
+	clks[IMX6SX_CLK_PWM6]         = imx_clk_gate2("pwm6",          "perclk",            base + 0x80, 28);
+	clks[IMX6SX_CLK_PWM7]         = imx_clk_gate2("pwm7",          "perclk",            base + 0x80, 30);
+
+	clks[IMX6SX_CLK_CKO1]         = imx_clk_gate("cko1",           "cko1_podf",         base + 0x60, 7);
+	clks[IMX6SX_CLK_CKO2]         = imx_clk_gate("cko2",           "cko2_podf",         base + 0x60, 24);
+
+	/* mask handshake of mmdc */
+	writel(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
+
+	if (IS_ENABLED(CONFIG_USB_IMX_PHY)) {
+		clk_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
+		clk_enable(clks[IMX6SX_CLK_USBPHY2_GATE]);
+	}
+
+	return 0;
+};
+
+static int imx6sx_clocks_init(void)
+{
+	if (!of_machine_is_compatible("fsl,imx6sx"))
+		return 0;
+
+	/* Set the default 132MHz for EIM module */
+	clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+	clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000);
+
+	/* set parent clock for LCDIF1 pixel clock */
+	clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]);
+	clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]);
+
+	/*
+	 * Init enet system AHB clock, set to 200Mhz
+	 * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
+	 */
+	clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+	clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]);
+	clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000);
+	clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000);
+	clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000);
+
+	/* Set parent clock for vadc */
+	clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
+
+	/* Update gpu clock from default 528M to 720M */
+	clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+	clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+
+	return 0;
+}
+coredevice_initcall(imx6sx_clocks_init);
+
+static __maybe_unused struct of_device_id imx6sx_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx6sx-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx6sx_ccm_driver = {
+	.probe	= imx6sx_ccm_probe,
+	.name	= "imx6-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx6sx_ccm_dt_ids),
+};
+
+static int imx6sx_ccm_init(void)
+{
+	return platform_driver_register(&imx6sx_ccm_driver);
+}
+core_initcall(imx6sx_ccm_init);
diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c
new file mode 100644
index 0000000..8f6d5ad
--- /dev/null
+++ b/drivers/clk/imx/clk-pfd.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+/**
+ * struct clk_pfd - IMX PFD clock
+ * @clk_hw:	clock source
+ * @reg:	PFD register address
+ * @idx:	the index of PFD encoded in the register
+ *
+ * PFD clock found on i.MX6 series.  Each register for PFD has 4 clk_pfd
+ * data encoded, and member idx is used to specify the one.  And each
+ * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
+ */
+struct clk_pfd {
+	struct clk	clk;
+	void __iomem	*reg;
+	u8		idx;
+	const char	*parent;
+};
+
+#define to_clk_pfd(_clk) container_of(_clk, struct clk_pfd, clk)
+
+#define SET	0x4
+#define CLR	0x8
+#define OTG	0xc
+
+static int clk_pfd_enable(struct clk *clk)
+{
+	struct clk_pfd *pfd = to_clk_pfd(clk);
+	writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
+
+	return 0;
+}
+
+static void clk_pfd_disable(struct clk *clk)
+{
+	struct clk_pfd *pfd = to_clk_pfd(clk);
+
+	writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
+}
+
+static unsigned long clk_pfd_recalc_rate(struct clk *clk,
+					 unsigned long parent_rate)
+{
+	struct clk_pfd *pfd = to_clk_pfd(clk);
+	u64 tmp = parent_rate;
+	u8 frac = (readl(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
+
+	tmp *= 18;
+	do_div(tmp, frac);
+
+	return tmp;
+}
+
+static long clk_pfd_round_rate(struct clk *clk, unsigned long rate,
+			       unsigned long *prate)
+{
+	u64 tmp = *prate;
+	u8 frac;
+
+	tmp = tmp * 18 + rate / 2;
+	do_div(tmp, rate);
+	frac = tmp;
+	if (frac < 12)
+		frac = 12;
+	else if (frac > 35)
+		frac = 35;
+	tmp = *prate;
+	tmp *= 18;
+	do_div(tmp, frac);
+
+	return tmp;
+}
+
+static int clk_pfd_set_rate(struct clk *clk, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct clk_pfd *pfd = to_clk_pfd(clk);
+	u64 tmp = parent_rate;
+	u8 frac;
+
+	tmp = tmp * 18 + rate / 2;
+	do_div(tmp, rate);
+	frac = tmp;
+	if (frac < 12)
+		frac = 12;
+	else if (frac > 35)
+		frac = 35;
+
+	writel(0x3f << (pfd->idx * 8), pfd->reg + CLR);
+	writel(frac << (pfd->idx * 8), pfd->reg + SET);
+
+	return 0;
+}
+
+static const struct clk_ops clk_pfd_ops = {
+	.enable		= clk_pfd_enable,
+	.disable	= clk_pfd_disable,
+	.recalc_rate	= clk_pfd_recalc_rate,
+	.round_rate	= clk_pfd_round_rate,
+	.set_rate	= clk_pfd_set_rate,
+};
+
+struct clk *imx_clk_pfd(const char *name, const char *parent,
+			void __iomem *reg, u8 idx)
+{
+	struct clk_pfd *pfd;
+	int ret;
+
+	pfd = xzalloc(sizeof(*pfd));
+
+	pfd->reg = reg;
+	pfd->idx = idx;
+	pfd->parent = parent;
+	pfd->clk.name = name;
+	pfd->clk.ops = &clk_pfd_ops;
+	pfd->clk.parent_names = &pfd->parent;
+	pfd->clk.num_parents = 1;
+
+	ret = clk_register(&pfd->clk);
+	if (ret) {
+		free(pfd);
+		return ERR_PTR(ret);
+	}
+
+	return &pfd->clk;
+}
diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c
new file mode 100644
index 0000000..f992134
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv1.c
@@ -0,0 +1,95 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+struct clk_pllv1 {
+	struct clk clk;
+	void __iomem *reg;
+	const char *parent;
+};
+
+static unsigned long clk_pllv1_recalc_rate(struct clk *clk,
+		unsigned long parent_rate)
+{
+	struct clk_pllv1 *pll = container_of(clk, struct clk_pllv1, clk);
+	unsigned long long ll;
+	int mfn_abs;
+	unsigned int mfi, mfn, mfd, pd;
+	u32 reg_val = readl(pll->reg);
+	unsigned long freq = parent_rate;
+
+	mfi = (reg_val >> 10) & 0xf;
+	mfn = reg_val & 0x3ff;
+	mfd = (reg_val >> 16) & 0x3ff;
+	pd =  (reg_val >> 26) & 0xf;
+
+	mfi = mfi <= 5 ? 5 : mfi;
+
+	mfn_abs = mfn;
+
+#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21
+	if (mfn >= 0x200) {
+		mfn |= 0xFFFFFE00;
+		mfn_abs = -mfn;
+	}
+#endif
+
+	freq *= 2;
+	freq /= pd + 1;
+
+	ll = (unsigned long long)freq * mfn_abs;
+
+	do_div(ll, mfd + 1);
+	if (mfn < 0)
+		ll = (freq * mfi) - ll;
+	else
+		ll = (freq * mfi) + ll;
+
+	return ll;
+}
+
+struct clk_ops clk_pllv1_ops = {
+	.recalc_rate = clk_pllv1_recalc_rate,
+};
+
+struct clk *imx_clk_pllv1(const char *name, const char *parent,
+		void __iomem *base)
+{
+	struct clk_pllv1 *pll = xzalloc(sizeof(*pll));
+	int ret;
+
+	pll->parent = parent;
+	pll->reg = base;
+	pll->clk.ops = &clk_pllv1_ops;
+	pll->clk.name = name;
+	pll->clk.parent_names = &pll->parent;
+	pll->clk.num_parents = 1;
+
+	ret = clk_register(&pll->clk);
+	if (ret) {
+		free(pll);
+		return ERR_PTR(ret);
+	}
+
+	return &pll->clk;
+}
diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c
new file mode 100644
index 0000000..5ba07fa
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv2.c
@@ -0,0 +1,230 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL			0x00
+#define MXC_PLL_DP_CONFIG		0x04
+#define MXC_PLL_DP_OP			0x08
+#define MXC_PLL_DP_MFD			0x0C
+#define MXC_PLL_DP_MFN			0x10
+#define MXC_PLL_DP_MFNMINUS		0x14
+#define MXC_PLL_DP_MFNPLUS		0x18
+#define MXC_PLL_DP_HFS_OP		0x1C
+#define MXC_PLL_DP_HFS_MFD		0x20
+#define MXC_PLL_DP_HFS_MFN		0x24
+#define MXC_PLL_DP_MFN_TOGC		0x28
+#define MXC_PLL_DP_DESTAT		0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL		0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN	0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET	12
+#define MXC_PLL_DP_CTL_ADE		0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV	0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK	(3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET	8
+#define MXC_PLL_DP_CTL_HFSM		0x80
+#define MXC_PLL_DP_CTL_PRE		0x40
+#define MXC_PLL_DP_CTL_UPEN		0x20
+#define MXC_PLL_DP_CTL_RST		0x10
+#define MXC_PLL_DP_CTL_RCP		0x8
+#define MXC_PLL_DP_CTL_PLM		0x4
+#define MXC_PLL_DP_CTL_BRM0		0x2
+#define MXC_PLL_DP_CTL_LRF		0x1
+
+#define MXC_PLL_DP_CONFIG_BIST		0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE	0x4
+#define MXC_PLL_DP_CONFIG_AREN		0x2
+#define MXC_PLL_DP_CONFIG_LDREQ		0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET	4
+#define MXC_PLL_DP_OP_MFI_MASK		(0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET	0
+#define MXC_PLL_DP_OP_PDF_MASK		0xF
+
+#define MXC_PLL_DP_MFD_OFFSET		0
+#define MXC_PLL_DP_MFD_MASK		0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET		0x0
+#define MXC_PLL_DP_MFN_MASK		0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS	(1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN	(1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET	0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK	0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL	(1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN		0x07FFFFFF
+
+#define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
+
+struct clk_pllv2 {
+	struct clk clk;
+	void __iomem *reg;
+	const char *parent;
+};
+
+static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
+		u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn)
+{
+	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+	unsigned long dbl;
+	uint64_t temp;
+
+	dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+	mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+	mfi = (mfi <= 5) ? 5 : mfi;
+	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+	mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+	/* Sign extend to 32-bits */
+	if (mfn >= 0x04000000) {
+		mfn |= 0xFC000000;
+		mfn_abs = -mfn;
+	}
+
+	ref_clk = 2 * parent_rate;
+	if (dbl != 0)
+		ref_clk *= 2;
+
+	ref_clk /= (pdf + 1);
+	temp = (u64) ref_clk * mfn_abs;
+	do_div(temp, mfd + 1);
+	if (mfn < 0)
+		temp = (ref_clk * mfi) - temp;
+	else
+		temp = (ref_clk * mfi) + temp;
+
+	return temp;
+}
+
+static unsigned long clk_pllv2_recalc_rate(struct clk *clk,
+		unsigned long parent_rate)
+{
+	u32 dp_op, dp_mfd, dp_mfn, dp_ctl;
+	void __iomem *pllbase;
+	struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
+
+	pllbase = pll->reg;
+
+	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+	dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+	dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+	dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+
+	return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn);
+}
+
+static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate,
+		u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn)
+{
+	u32 reg;
+	long mfi, pdf, mfn, mfd = 999999;
+	u64 temp64;
+	unsigned long quad_parent_rate;
+
+	quad_parent_rate = 4 * parent_rate;
+	pdf = mfi = -1;
+	while (++pdf < 16 && mfi < 5)
+		mfi = rate * (pdf+1) / quad_parent_rate;
+	if (mfi > 15)
+		return -EINVAL;
+	pdf--;
+
+	temp64 = rate * (pdf + 1) - quad_parent_rate * mfi;
+	do_div(temp64, quad_parent_rate / 1000000);
+	mfn = (long)temp64;
+
+	reg = mfi << 4 | pdf;
+
+	*dp_op = reg;
+	*dp_mfd = mfd;
+	*dp_mfn = mfn;
+
+	return 0;
+}
+
+static int clk_pllv2_set_rate(struct clk *clk, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
+	void __iomem *pllbase;
+	u32 dp_ctl, dp_op, dp_mfd, dp_mfn;
+	int ret;
+
+	pllbase = pll->reg;
+
+	ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn);
+	if (ret)
+		return ret;
+
+	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+	/* use dpdck0_2 */
+	__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+
+	__raw_writel(dp_op, pllbase + MXC_PLL_DP_OP);
+	__raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD);
+	__raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN);
+
+	return 0;
+}
+
+static long clk_pllv2_round_rate(struct clk *clk, unsigned long rate,
+		unsigned long *prate)
+{
+	u32 dp_op, dp_mfd, dp_mfn;
+
+	__clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn);
+	return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN,
+			dp_op, dp_mfd, dp_mfn);
+}
+
+struct clk_ops clk_pllv2_ops = {
+	.recalc_rate = clk_pllv2_recalc_rate,
+	.round_rate = clk_pllv2_round_rate,
+	.set_rate = clk_pllv2_set_rate,
+};
+
+struct clk *imx_clk_pllv2(const char *name, const char *parent,
+		void __iomem *base)
+{
+	struct clk_pllv2 *pll = xzalloc(sizeof(*pll));
+	int ret;
+
+	pll->parent = parent;
+	pll->reg = base;
+	pll->clk.ops = &clk_pllv2_ops;
+	pll->clk.name = name;
+	pll->clk.parent_names = &pll->parent;
+	pll->clk.num_parents = 1;
+
+	ret = clk_register(&pll->clk);
+	if (ret) {
+		free(pll);
+		return ERR_PTR(ret);
+	}
+
+	return &pll->clk;
+}
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
new file mode 100644
index 0000000..e38dcdf
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -0,0 +1,326 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <clock.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+#define PLL_NUM_OFFSET		0x10
+#define PLL_DENOM_OFFSET	0x20
+
+#define BM_PLL_POWER		(0x1 << 12)
+#define BM_PLL_ENABLE		(0x1 << 13)
+#define BM_PLL_BYPASS		(0x1 << 16)
+#define BM_PLL_LOCK		(0x1 << 31)
+
+struct clk_pllv3 {
+	struct clk	clk;
+	void __iomem	*base;
+	bool		powerup_set;
+	u32		div_mask;
+	const char	*parent;
+};
+
+#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
+
+static int clk_pllv3_enable(struct clk *clk)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	u32 val;
+	int timeout = 10000;
+
+	val = readl(pll->base);
+	val &= ~BM_PLL_BYPASS;
+	if (pll->powerup_set)
+		val |= BM_PLL_POWER;
+	else
+		val &= ~BM_PLL_POWER;
+	writel(val, pll->base);
+
+	/* Wait for PLL to lock */
+	while (timeout--) {
+		if (readl(pll->base) & BM_PLL_LOCK)
+			break;
+	}
+
+	if (!timeout)
+		return -ETIMEDOUT;
+
+	val = readl(pll->base);
+	val |= BM_PLL_ENABLE;
+	writel(val, pll->base);
+
+	return 0;
+}
+
+static void clk_pllv3_disable(struct clk *clk)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	u32 val;
+
+	val = readl(pll->base);
+	val &= ~BM_PLL_ENABLE;
+	writel(val, pll->base);
+
+	val |= BM_PLL_BYPASS;
+	if (pll->powerup_set)
+		val &= ~BM_PLL_POWER;
+	else
+		val |= BM_PLL_POWER;
+	writel(val, pll->base);
+}
+
+static unsigned long clk_pllv3_recalc_rate(struct clk *clk,
+					   unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	u32 div = readl(pll->base)  & pll->div_mask;
+
+	return (div == 1) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static long clk_pllv3_round_rate(struct clk *clk, unsigned long rate,
+				 unsigned long *prate)
+{
+	unsigned long parent_rate = *prate;
+
+	return (rate >= parent_rate * 22) ? parent_rate * 22 :
+					    parent_rate * 20;
+}
+
+static int clk_pllv3_set_rate(struct clk *clk, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	u32 val, div;
+
+	if (rate == parent_rate * 22)
+		div = 1;
+	else if (rate == parent_rate * 20)
+		div = 0;
+	else
+		return -EINVAL;
+
+	val = readl(pll->base);
+	val &= ~pll->div_mask;
+	val |= div;
+	writel(val, pll->base);
+
+	return 0;
+}
+
+static const struct clk_ops clk_pllv3_ops = {
+	.enable		= clk_pllv3_enable,
+	.disable	= clk_pllv3_disable,
+	.recalc_rate	= clk_pllv3_recalc_rate,
+	.round_rate	= clk_pllv3_round_rate,
+	.set_rate	= clk_pllv3_set_rate,
+};
+
+static unsigned long clk_pllv3_sys_recalc_rate(struct clk *clk,
+					       unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	u32 div = readl(pll->base) & pll->div_mask;
+
+	return parent_rate * div / 2;
+}
+
+static long clk_pllv3_sys_round_rate(struct clk *clk, unsigned long rate,
+				     unsigned long *prate)
+{
+	unsigned long parent_rate = *prate;
+	unsigned long min_rate = parent_rate * 54 / 2;
+	unsigned long max_rate = parent_rate * 108 / 2;
+	u32 div;
+
+	if (rate > max_rate)
+		rate = max_rate;
+	else if (rate < min_rate)
+		rate = min_rate;
+	div = rate * 2 / parent_rate;
+
+	return parent_rate * div / 2;
+}
+
+static int clk_pllv3_sys_set_rate(struct clk *clk, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	unsigned long min_rate = parent_rate * 54 / 2;
+	unsigned long max_rate = parent_rate * 108 / 2;
+	u32 val, div;
+
+	if (rate < min_rate || rate > max_rate)
+		return -EINVAL;
+
+	div = rate * 2 / parent_rate;
+	val = readl(pll->base);
+	val &= ~pll->div_mask;
+	val |= div;
+	writel(val, pll->base);
+
+	return 0;
+}
+
+static const struct clk_ops clk_pllv3_sys_ops = {
+	.enable		= clk_pllv3_enable,
+	.disable	= clk_pllv3_disable,
+	.recalc_rate	= clk_pllv3_sys_recalc_rate,
+	.round_rate	= clk_pllv3_sys_round_rate,
+	.set_rate	= clk_pllv3_sys_set_rate,
+};
+
+static unsigned long clk_pllv3_av_recalc_rate(struct clk *clk,
+					      unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	u32 mfn = readl(pll->base + PLL_NUM_OFFSET);
+	u32 mfd = readl(pll->base + PLL_DENOM_OFFSET);
+	u32 div = readl(pll->base) & pll->div_mask;
+
+	return (parent_rate * div) + ((parent_rate / mfd) * mfn);
+}
+
+static long clk_pllv3_av_round_rate(struct clk *clk, unsigned long rate,
+				    unsigned long *prate)
+{
+	unsigned long parent_rate = *prate;
+	unsigned long min_rate = parent_rate * 27;
+	unsigned long max_rate = parent_rate * 54;
+	u32 div;
+	u32 mfn, mfd = 1000000;
+	u64 temp64;
+
+	if (rate > max_rate)
+		rate = max_rate;
+	else if (rate < min_rate)
+		rate = min_rate;
+
+	div = rate / parent_rate;
+	temp64 = (u64) (rate - div * parent_rate);
+	temp64 *= mfd;
+	do_div(temp64, parent_rate);
+	mfn = temp64;
+
+	return parent_rate * div + parent_rate / mfd * mfn;
+}
+
+static int clk_pllv3_av_set_rate(struct clk *clk, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	unsigned long min_rate = parent_rate * 27;
+	unsigned long max_rate = parent_rate * 54;
+	u32 val, div;
+	u32 mfn, mfd = 1000000;
+	u64 temp64;
+
+	if (rate < min_rate || rate > max_rate)
+		return -EINVAL;
+
+	div = rate / parent_rate;
+	temp64 = (u64) (rate - div * parent_rate);
+	temp64 *= mfd;
+	do_div(temp64, parent_rate);
+	mfn = temp64;
+
+	val = readl(pll->base);
+	val &= ~pll->div_mask;
+	val |= div;
+	writel(val, pll->base);
+	writel(mfn, pll->base + PLL_NUM_OFFSET);
+	writel(mfd, pll->base + PLL_DENOM_OFFSET);
+
+	return 0;
+}
+
+static const struct clk_ops clk_pllv3_av_ops = {
+	.enable		= clk_pllv3_enable,
+	.disable	= clk_pllv3_disable,
+	.recalc_rate	= clk_pllv3_av_recalc_rate,
+	.round_rate	= clk_pllv3_av_round_rate,
+	.set_rate	= clk_pllv3_av_set_rate,
+};
+
+static unsigned long clk_pllv3_enet_recalc_rate(struct clk *clk,
+						unsigned long parent_rate)
+{
+	return 500000000;
+}
+
+static const struct clk_ops clk_pllv3_enet_ops = {
+	.enable		= clk_pllv3_enable,
+	.disable	= clk_pllv3_disable,
+	.recalc_rate	= clk_pllv3_enet_recalc_rate,
+};
+
+static const struct clk_ops clk_pllv3_mlb_ops = {
+	.enable		= clk_pllv3_enable,
+	.disable	= clk_pllv3_disable,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+			  const char *parent, void __iomem *base,
+			  u32 div_mask)
+{
+	struct clk_pllv3 *pll;
+	const struct clk_ops *ops;
+	int ret;
+
+	pll = xzalloc(sizeof(*pll));
+
+	switch (type) {
+	case IMX_PLLV3_SYS:
+		ops = &clk_pllv3_sys_ops;
+		break;
+	case IMX_PLLV3_USB:
+		ops = &clk_pllv3_ops;
+		pll->powerup_set = true;
+		break;
+	case IMX_PLLV3_AV:
+		ops = &clk_pllv3_av_ops;
+		break;
+	case IMX_PLLV3_ENET:
+		ops = &clk_pllv3_enet_ops;
+		break;
+	case IMX_PLLV3_MLB:
+		ops = &clk_pllv3_mlb_ops;
+		break;
+	default:
+		ops = &clk_pllv3_ops;
+	}
+	pll->base = base;
+	pll->div_mask = div_mask;
+	pll->parent = parent;
+	pll->clk.ops = ops;
+	pll->clk.name = name;
+	pll->clk.parent_names = &pll->parent;
+	pll->clk.num_parents = 1;
+
+	ret = clk_register(&pll->clk);
+	if (ret) {
+		free(pll);
+		return ERR_PTR(ret);
+	}
+
+	return &pll->clk;
+}
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
new file mode 100644
index 0000000..c5913e1
--- /dev/null
+++ b/drivers/clk/imx/clk.h
@@ -0,0 +1,104 @@
+#ifndef __IMX_CLK_H
+#define __IMX_CLK_H
+
+struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
+		u8 shift);
+
+static inline struct clk *imx_clk_divider(const char *name, const char *parent,
+		void __iomem *reg, u8 shift, u8 width)
+{
+	return clk_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *imx_clk_divider_np(const char *name, const char *parent,
+		void __iomem *reg, u8 shift, u8 width)
+{
+	return clk_divider(name, parent, reg, shift, width, 0);
+}
+
+static inline struct clk *imx_clk_divider_table(const char *name,
+		const char *parent, void __iomem *reg, u8 shift, u8 width,
+		const struct clk_div_table *table)
+{
+	return clk_divider_table(name, parent, reg, shift, width, table,
+			CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *imx_clk_fixed_factor(const char *name,
+		const char *parent, unsigned int mult, unsigned int div)
+{
+	return clk_fixed_factor(name, parent, mult, div, CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
+		u8 shift, u8 width, const char **parents, u8 num_parents)
+{
+	return clk_mux(name, reg, shift, width, parents, num_parents, 0);
+}
+
+static inline struct clk *imx_clk_mux_p(const char *name, void __iomem *reg,
+		u8 shift, u8 width, const char **parents, u8 num_parents)
+{
+	return clk_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *imx_clk_gate(const char *name, const char *parent,
+		void __iomem *reg, u8 shift)
+{
+	return clk_gate(name, parent, reg, shift, CLK_SET_RATE_PARENT, 0);
+}
+
+static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
+		void __iomem *reg, u8 shift)
+{
+	return clk_gate2(name, parent, reg, shift);
+}
+
+struct clk *imx_clk_pllv1(const char *name, const char *parent,
+		void __iomem *base);
+
+struct clk *imx_clk_pllv2(const char *name, const char *parent,
+		void __iomem *base);
+
+enum imx_pllv3_type {
+	IMX_PLLV3_GENERIC,
+	IMX_PLLV3_SYS,
+	IMX_PLLV3_USB,
+	IMX_PLLV3_AV,
+	IMX_PLLV3_ENET,
+	IMX_PLLV3_MLB,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+			  const char *parent, void __iomem *base,
+			  u32 div_mask);
+
+struct clk *imx_clk_pfd(const char *name, const char *parent,
+			void __iomem *reg, u8 idx);
+
+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)
+{
+	/*
+	 * For now we do not support rate setting, so just fall back to
+	 * regular divider.
+	 */
+	return imx_clk_divider(name, parent, reg, shift, width);
+}
+
+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 **parents, int num_parents)
+{
+	/*
+	 * For now we do not support mux switching, so just fall back to
+	 * regular mux.
+	 */
+	return imx_clk_mux(name, reg, shift, width, parents, num_parents);
+}
+
+struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
+		void __iomem *reg, u8 shift, u32 exclusive_mask);
+
+#endif /* __IMX_CLK_H */
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 11/28] i.MX: clk: Port imx_clk_gate2_cgr()
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (9 preceding siblings ...)
  2016-11-09 16:13 ` [PATCH v2 10/28] i.MX: Move clk code from 'mach-imx' to 'drivers' Andrey Smirnov
@ 2016-11-09 16:13 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 12/28] i.MX: clk: Add IMX_PLLV3_USB_VF610 support Andrey Smirnov
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Update clk-gate2 code to be able to accept arbitrary 'cgr' value and
introduce imx_clk_gate2_cgr() (Used by Vybrid clock tree)

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/clk/imx/clk-gate2.c | 12 +++++++-----
 drivers/clk/imx/clk.h       | 11 +++++++++--
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index faed631..f952f3e 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -26,6 +26,7 @@ struct clk_gate2 {
 	struct clk clk;
 	void __iomem *reg;
 	int shift;
+	u8 cgr_val;
 	const char *parent;
 #define CLK_GATE_INVERTED	(1 << 0)
 	unsigned flags;
@@ -43,7 +44,7 @@ static int clk_gate2_enable(struct clk *clk)
 	if (g->flags & CLK_GATE_INVERTED)
 		val &= ~(3 << g->shift);
 	else
-		val |= 3 << g->shift;
+		val |= g->cgr_val << g->shift;
 
 	writel(val, g->reg);
 
@@ -87,12 +88,13 @@ static struct clk_ops clk_gate2_ops = {
 };
 
 struct clk *clk_gate2_alloc(const char *name, const char *parent,
-		void __iomem *reg, u8 shift)
+			    void __iomem *reg, u8 shift, u8 cgr_val)
 {
 	struct clk_gate2 *g = xzalloc(sizeof(*g));
 
 	g->parent = parent;
 	g->reg = reg;
+	g->cgr_val = cgr_val;
 	g->shift = shift;
 	g->clk.ops = &clk_gate2_ops;
 	g->clk.name = name;
@@ -111,12 +113,12 @@ void clk_gate2_free(struct clk *clk)
 }
 
 struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
-		u8 shift)
+		      u8 shift, u8 cgr_val)
 {
 	struct clk *g;
 	int ret;
 
-	g = clk_gate2_alloc(name , parent, reg, shift);
+	g = clk_gate2_alloc(name , parent, reg, shift, cgr_val);
 
 	ret = clk_register(g);
 	if (ret) {
@@ -133,7 +135,7 @@ struct clk *clk_gate2_inverted(const char *name, const char *parent,
 	struct clk *clk;
 	struct clk_gate2 *g;
 
-	clk = clk_gate2(name, parent, reg, shift);
+	clk = clk_gate2(name, parent, reg, shift, 0x3);
 	if (IS_ERR(clk))
 		return clk;
 
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index c5913e1..2aeb356 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -2,7 +2,7 @@
 #define __IMX_CLK_H
 
 struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
-		u8 shift);
+		      u8 shift, u8 cgr_val);
 
 static inline struct clk *imx_clk_divider(const char *name, const char *parent,
 		void __iomem *reg, u8 shift, u8 width)
@@ -51,9 +51,16 @@ static inline struct clk *imx_clk_gate(const char *name, const char *parent,
 static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
 		void __iomem *reg, u8 shift)
 {
-	return clk_gate2(name, parent, reg, shift);
+	return clk_gate2(name, parent, reg, shift, 0x3);
 }
 
+static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent,
+					    void __iomem *reg, u8 shift, u8 cgr_val)
+{
+	return clk_gate2(name, parent, reg, shift, cgr_val);
+}
+
+
 struct clk *imx_clk_pllv1(const char *name, const char *parent,
 		void __iomem *base);
 
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 12/28] i.MX: clk: Add IMX_PLLV3_USB_VF610 support
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (10 preceding siblings ...)
  2016-11-09 16:13 ` [PATCH v2 11/28] i.MX: clk: Port imx_clk_gate2_cgr() Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 13/28] i.MX: clk: Port imx_check_clocks() Andrey Smirnov
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Add IMX_PLLV3_USB_VF610 PLLv3 types support clk-pllv3.c

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/clk/imx/clk-pllv3.c | 9 ++++++---
 drivers/clk/imx/clk.h       | 1 +
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index e38dcdf..29c0f1c 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -36,6 +36,7 @@ struct clk_pllv3 {
 	void __iomem	*base;
 	bool		powerup_set;
 	u32		div_mask;
+	u32		div_shift;
 	const char	*parent;
 };
 
@@ -92,7 +93,7 @@ static unsigned long clk_pllv3_recalc_rate(struct clk *clk,
 					   unsigned long parent_rate)
 {
 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
-	u32 div = readl(pll->base)  & pll->div_mask;
+	u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
 
 	return (div == 1) ? parent_rate * 22 : parent_rate * 20;
 }
@@ -120,8 +121,8 @@ static int clk_pllv3_set_rate(struct clk *clk, unsigned long rate,
 		return -EINVAL;
 
 	val = readl(pll->base);
-	val &= ~pll->div_mask;
-	val |= div;
+	val &= ~(pll->div_mask << pll->div_shift);
+	val |= div << pll->div_shift;
 	writel(val, pll->base);
 
 	return 0;
@@ -292,6 +293,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 	case IMX_PLLV3_SYS:
 		ops = &clk_pllv3_sys_ops;
 		break;
+	case IMX_PLLV3_USB_VF610:
+		pll->div_shift = 1;
 	case IMX_PLLV3_USB:
 		ops = &clk_pllv3_ops;
 		pll->powerup_set = true;
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 2aeb356..35e480f 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -71,6 +71,7 @@ enum imx_pllv3_type {
 	IMX_PLLV3_GENERIC,
 	IMX_PLLV3_SYS,
 	IMX_PLLV3_USB,
+	IMX_PLLV3_USB_VF610,
 	IMX_PLLV3_AV,
 	IMX_PLLV3_ENET,
 	IMX_PLLV3_MLB,
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 13/28] i.MX: clk: Port imx_check_clocks()
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (11 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 12/28] i.MX: clk: Add IMX_PLLV3_USB_VF610 support Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 14/28] i.MX: clk: Port imx_clk_mux_flags from Linux Andrey Smirnov
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Port imx_check_clocks() from Linux kernel.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/clk/imx/Makefile |  3 ++-
 drivers/clk/imx/clk.c    | 21 +++++++++++++++++++++
 drivers/clk/imx/clk.h    |  3 +++
 3 files changed, 26 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/clk.c

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 893a1a5..06af530 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -4,7 +4,8 @@ obj-$(CONFIG_COMMON_CLK) +=	\
 	clk-pllv3.o		\
 	clk-pfd.o		\
 	clk-gate2.o		\
-	clk-gate-exclusive.o
+	clk-gate-exclusive.o	\
+	clk.o
 
 obj-$(CONFIG_ARCH_IMX1)   += clk-imx1.o
 obj-$(CONFIG_ARCH_IMX25)  += clk-imx25.o
diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
new file mode 100644
index 0000000..7488dfc
--- /dev/null
+++ b/drivers/clk/imx/clk.c
@@ -0,0 +1,21 @@
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+
+#include "clk.h"
+
+void __init imx_check_clocks(struct clk *clks[], unsigned int count)
+{
+	unsigned i;
+
+	for (i = 0; i < count; i++)
+		if (IS_ERR(clks[i]))
+			pr_err("i.MX clk %u: register failed with %ld\n",
+			       i, PTR_ERR(clks[i]));
+}
+
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 35e480f..fd43fc2 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -109,4 +109,7 @@ static inline struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg,
 struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
 		void __iomem *reg, u8 shift, u32 exclusive_mask);
 
+void imx_check_clocks(struct clk *clks[], unsigned int count);
+
+
 #endif /* __IMX_CLK_H */
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 14/28] i.MX: clk: Port imx_clk_mux_flags from Linux
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (12 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 13/28] i.MX: clk: Port imx_check_clocks() Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 15/28] i.MX: Add VF610 clock tree initialization code Andrey Smirnov
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Port imx_clk_mux_flags from Linux, to simplify clock code porting.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/clk/imx/clk.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index fd43fc2..970f65c 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -30,6 +30,14 @@ static inline struct clk *imx_clk_fixed_factor(const char *name,
 	return clk_fixed_factor(name, parent, mult, div, CLK_SET_RATE_PARENT);
 }
 
+static inline struct clk *imx_clk_mux_flags(const char *name, void __iomem *reg,
+					    u8 shift, u8 width,
+					    const char **parents, u8 num_parents,
+					    unsigned long flags)
+{
+	return clk_mux(name, reg, shift, width, parents, num_parents, flags);
+}
+
 static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
 		u8 shift, u8 width, const char **parents, u8 num_parents)
 {
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 15/28] i.MX: Add VF610 clock tree initialization code
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (13 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 14/28] i.MX: clk: Port imx_clk_mux_flags from Linux Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 16/28] vf610: Give enet_osc explicit "enet_ext" name Andrey Smirnov
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Based on analogous code from Linux kernel

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/clk/imx/Makefile    |   3 +-
 drivers/clk/imx/clk-vf610.c | 443 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 444 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/imx/clk-vf610.c

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 06af530..ffaff1c 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -18,5 +18,4 @@ obj-$(CONFIG_ARCH_IMX51)  += clk-imx5.o
 obj-$(CONFIG_ARCH_IMX53)  += clk-imx5.o
 obj-$(CONFIG_ARCH_IMX6)   += clk-imx6.o
 obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
-
-
+obj-$(CONFIG_ARCH_VF610) += clk-vf610.o
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
new file mode 100644
index 0000000..04cb02f
--- /dev/null
+++ b/drivers/clk/imx/clk-vf610.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2012-2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <io.h>
+#include <of.h>
+#include <of_address.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <dt-bindings/clock/vf610-clock.h>
+
+#include "clk.h"
+
+#define CCM_CCR			(ccm_base + 0x00)
+#define CCM_CSR			(ccm_base + 0x04)
+#define CCM_CCSR		(ccm_base + 0x08)
+#define CCSR_PLL1_PFDn_EN(n)	BIT((n) + 7)
+#define CCSR_PLL2_PFDn_EN(n)	BIT((n) + 11)
+#define CCSR_PLL3_PFDn_EN(n)	BIT((n) + 27)
+#define CCM_CACRR		(ccm_base + 0x0c)
+#define CCM_CSCMR1		(ccm_base + 0x10)
+#define CCM_CSCDR1		(ccm_base + 0x14)
+#define CCM_CSCDR2		(ccm_base + 0x18)
+#define CCM_CSCDR3		(ccm_base + 0x1c)
+#define CCM_CSCMR2		(ccm_base + 0x20)
+#define CCM_CSCDR4		(ccm_base + 0x24)
+#define CCM_CLPCR		(ccm_base + 0x2c)
+#define CCM_CISR		(ccm_base + 0x30)
+#define CCM_CIMR		(ccm_base + 0x34)
+#define CCM_CGPR		(ccm_base + 0x3c)
+#define CCM_CCGR0		(ccm_base + 0x40)
+#define CCM_CCGR1		(ccm_base + 0x44)
+#define CCM_CCGR2		(ccm_base + 0x48)
+#define CCM_CCGR3		(ccm_base + 0x4c)
+#define CCM_CCGR4		(ccm_base + 0x50)
+#define CCM_CCGR5		(ccm_base + 0x54)
+#define CCM_CCGR6		(ccm_base + 0x58)
+#define CCM_CCGR7		(ccm_base + 0x5c)
+#define CCM_CCGR8		(ccm_base + 0x60)
+#define CCM_CCGR9		(ccm_base + 0x64)
+#define CCM_CCGR10		(ccm_base + 0x68)
+#define CCM_CCGR11		(ccm_base + 0x6c)
+#define CCM_CCGRx(x)		(CCM_CCGR0 + (x) * 4)
+#define CCM_CMEOR0		(ccm_base + 0x70)
+#define CCM_CMEOR1		(ccm_base + 0x74)
+#define CCM_CMEOR2		(ccm_base + 0x78)
+#define CCM_CMEOR3		(ccm_base + 0x7c)
+#define CCM_CMEOR4		(ccm_base + 0x80)
+#define CCM_CMEOR5		(ccm_base + 0x84)
+#define CCM_CPPDSR		(ccm_base + 0x88)
+#define CCM_CCOWR		(ccm_base + 0x8c)
+#define CCM_CCPGR0		(ccm_base + 0x90)
+#define CCM_CCPGR1		(ccm_base + 0x94)
+#define CCM_CCPGR2		(ccm_base + 0x98)
+#define CCM_CCPGR3		(ccm_base + 0x9c)
+
+#define CCM_CCGRx_CGn(n)	((n) * 2)
+
+#define PFD_PLL1_BASE		(anatop_base + 0x2b0)
+#define PFD_PLL2_BASE		(anatop_base + 0x100)
+#define PFD_PLL3_BASE		(anatop_base + 0xf0)
+#define PLL1_CTRL		(anatop_base + 0x270)
+#define PLL2_CTRL		(anatop_base + 0x30)
+#define PLL3_CTRL		(anatop_base + 0x10)
+#define PLL4_CTRL		(anatop_base + 0x70)
+#define PLL5_CTRL		(anatop_base + 0xe0)
+#define PLL6_CTRL		(anatop_base + 0xa0)
+#define PLL7_CTRL		(anatop_base + 0x20)
+#define ANA_MISC1		(anatop_base + 0x160)
+
+static void __iomem *anatop_base;
+static void __iomem *ccm_base;
+
+/* sources for multiplexer clocks, this is used multiple times */
+static const char *fast_sels[]	= { "firc", "fxosc", };
+static const char *slow_sels[]	= { "sirc_32k", "sxosc", };
+static const char *pll1_sels[]	= { "pll1_sys", "pll1_pfd1", "pll1_pfd2", "pll1_pfd3", "pll1_pfd4", };
+static const char *pll2_sels[]	= { "pll2_bus", "pll2_pfd1", "pll2_pfd2", "pll2_pfd3", "pll2_pfd4", };
+static const char *pll_bypass_src_sels[] = { "fast_clk_sel", "lvds1_in", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+static const char *sys_sels[]	= { "fast_clk_sel", "slow_clk_sel", "pll2_pfd_sel", "pll2_bus", "pll1_pfd_sel", "pll3_usb_otg", };
+static const char *ddr_sels[]	= { "pll2_pfd2", "sys_sel", };
+static const char *rmii_sels[]	= { "enet_ext", "audio_ext", "enet_50m", "enet_25m", };
+static const char *enet_ts_sels[]	= { "enet_ext", "fxosc", "audio_ext", "usb", "enet_ts", "enet_25m", "enet_50m", };
+static const char *esai_sels[]	= { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", };
+static const char *sai_sels[]	= { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", };
+static const char *nfc_sels[]	= { "platform_bus", "pll1_pfd1", "pll3_pfd1", "pll3_pfd3", };
+static const char *qspi_sels[]	= { "pll3_usb_otg", "pll3_pfd4", "pll2_pfd4", "pll1_pfd4", };
+static const char *esdhc_sels[]	= { "pll3_usb_otg", "pll3_pfd3", "pll1_pfd3", "platform_bus", };
+static const char *dcu_sels[]	= { "pll1_pfd2", "pll3_usb_otg", };
+static const char *gpu_sels[]	= { "pll2_pfd2", "pll3_pfd2", };
+static const char *vadc_sels[]	= { "pll6_video_div", "pll3_usb_otg_div", "pll3_usb_otg", };
+/* FTM counter clock source, not module clock */
+static const char *ftm_ext_sels[]	= {"sirc_128k", "sxosc", "fxosc_half", "audio_ext", };
+static const char *ftm_fix_sels[]	= { "sxosc", "ipg_bus", };
+
+
+static struct clk_div_table pll4_audio_div_table[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 6 },
+	{ .val = 3, .div = 8 },
+	{ .val = 4, .div = 10 },
+	{ .val = 5, .div = 12 },
+	{ .val = 6, .div = 14 },
+	{ .val = 7, .div = 16 },
+	{ }
+};
+
+static struct clk *clk[VF610_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static unsigned int const clks_init_on[] __initconst = {
+	VF610_CLK_SYS_BUS,
+	VF610_CLK_DDR_SEL,
+	VF610_CLK_DAP,
+	VF610_CLK_DDRMC,
+	VF610_CLK_WKPU,
+};
+
+static void __init vf610_clocks_init(struct device_node *ccm_node)
+{
+	u32 ccsr;
+	struct device_node *np;
+	int i;
+
+	clk[VF610_CLK_DUMMY] = clk_fixed("dummy", 0);
+	clk[VF610_CLK_SIRC_128K] = clk_fixed("sirc_128k", 128000);
+	clk[VF610_CLK_SIRC_32K] = clk_fixed("sirc_32k", 32000);
+	clk[VF610_CLK_FIRC] = clk_fixed("firc", 24000000);
+
+	clk[VF610_CLK_SXOSC] = of_clk_get_by_name(ccm_node, "sxosc");
+	clk[VF610_CLK_FXOSC] = of_clk_get_by_name(ccm_node, "fxosc");
+	clk[VF610_CLK_AUDIO_EXT] = of_clk_get_by_name(ccm_node, "audio_ext");
+	clk[VF610_CLK_ENET_EXT] = of_clk_get_by_name(ccm_node, "enet_ext");
+
+	/* Clock source from external clock via LVDs PAD */
+	clk[VF610_CLK_ANACLK1] = of_clk_get_by_name(ccm_node, "anaclk1");
+
+	clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2);
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,vf610-anatop");
+	anatop_base = of_iomap(np, 0);
+	BUG_ON(!anatop_base);
+
+	np = ccm_node;
+	ccm_base = of_iomap(np, 0);
+	BUG_ON(!ccm_base);
+
+	ccsr = readl(CCM_CCSR);
+	ccsr |= CCSR_PLL3_PFDn_EN(1) |
+		CCSR_PLL3_PFDn_EN(2) |
+		CCSR_PLL3_PFDn_EN(3) |
+		CCSR_PLL3_PFDn_EN(4) |
+		CCSR_PLL2_PFDn_EN(1) |
+		CCSR_PLL2_PFDn_EN(2) |
+		CCSR_PLL2_PFDn_EN(3) |
+		CCSR_PLL2_PFDn_EN(4) |
+		CCSR_PLL1_PFDn_EN(1) |
+		CCSR_PLL1_PFDn_EN(2) |
+		CCSR_PLL1_PFDn_EN(3) |
+		CCSR_PLL1_PFDn_EN(4);
+	writel(ccsr, CCM_CCSR);
+
+	clk[VF610_CLK_SLOW_CLK_SEL] = imx_clk_mux("slow_clk_sel", CCM_CCSR, 4, 1, slow_sels, ARRAY_SIZE(slow_sels));
+	clk[VF610_CLK_FASK_CLK_SEL] = imx_clk_mux("fast_clk_sel", CCM_CCSR, 5, 1, fast_sels, ARRAY_SIZE(fast_sels));
+
+	clk[VF610_CLK_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", PLL1_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clk[VF610_CLK_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", PLL2_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clk[VF610_CLK_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", PLL3_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clk[VF610_CLK_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", PLL4_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clk[VF610_CLK_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", PLL5_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clk[VF610_CLK_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", PLL6_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clk[VF610_CLK_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", PLL7_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+	clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1);
+	clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1);
+	clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610,     "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2);
+	clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV,      "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f);
+	clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET,    "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3);
+	clk[VF610_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_AV,      "pll6", "pll6_bypass_src", PLL6_CTRL, 0x7f);
+	clk[VF610_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB_VF610,     "pll7", "pll7_bypass_src", PLL7_CTRL, 0x2);
+
+	clk[VF610_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", PLL1_CTRL, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	clk[VF610_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", PLL2_CTRL, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+	clk[VF610_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", PLL3_CTRL, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+	clk[VF610_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", PLL4_CTRL, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
+	clk[VF610_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", PLL5_CTRL, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+	clk[VF610_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", PLL6_CTRL, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
+	clk[VF610_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", PLL7_CTRL, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
+
+	/* Do not bypass PLLs initially */
+	clk_set_parent(clk[VF610_PLL1_BYPASS], clk[VF610_CLK_PLL1]);
+	clk_set_parent(clk[VF610_PLL2_BYPASS], clk[VF610_CLK_PLL2]);
+	clk_set_parent(clk[VF610_PLL3_BYPASS], clk[VF610_CLK_PLL3]);
+	clk_set_parent(clk[VF610_PLL4_BYPASS], clk[VF610_CLK_PLL4]);
+	clk_set_parent(clk[VF610_PLL5_BYPASS], clk[VF610_CLK_PLL5]);
+	clk_set_parent(clk[VF610_PLL6_BYPASS], clk[VF610_CLK_PLL6]);
+	clk_set_parent(clk[VF610_PLL7_BYPASS], clk[VF610_CLK_PLL7]);
+
+	clk[VF610_CLK_PLL1_SYS]      = imx_clk_gate("pll1_sys",      "pll1_bypass", PLL1_CTRL, 13);
+	clk[VF610_CLK_PLL2_BUS]      = imx_clk_gate("pll2_bus",      "pll2_bypass", PLL2_CTRL, 13);
+	clk[VF610_CLK_PLL3_USB_OTG]  = imx_clk_gate("pll3_usb_otg",  "pll3_bypass", PLL3_CTRL, 13);
+	clk[VF610_CLK_PLL4_AUDIO]    = imx_clk_gate("pll4_audio",    "pll4_bypass", PLL4_CTRL, 13);
+	clk[VF610_CLK_PLL5_ENET]     = imx_clk_gate("pll5_enet",     "pll5_bypass", PLL5_CTRL, 13);
+	clk[VF610_CLK_PLL6_VIDEO]    = imx_clk_gate("pll6_video",    "pll6_bypass", PLL6_CTRL, 13);
+	clk[VF610_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", PLL7_CTRL, 13);
+
+	clk[VF610_CLK_LVDS1_IN]  = imx_clk_gate_exclusive("lvds1_in", "anaclk1", ANA_MISC1, 12, BIT(10));
+
+	clk[VF610_CLK_PLL1_PFD1] = imx_clk_pfd("pll1_pfd1", "pll1_sys", PFD_PLL1_BASE, 0);
+	clk[VF610_CLK_PLL1_PFD2] = imx_clk_pfd("pll1_pfd2", "pll1_sys", PFD_PLL1_BASE, 1);
+	clk[VF610_CLK_PLL1_PFD3] = imx_clk_pfd("pll1_pfd3", "pll1_sys", PFD_PLL1_BASE, 2);
+	clk[VF610_CLK_PLL1_PFD4] = imx_clk_pfd("pll1_pfd4", "pll1_sys", PFD_PLL1_BASE, 3);
+
+	clk[VF610_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", PFD_PLL2_BASE, 0);
+	clk[VF610_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", PFD_PLL2_BASE, 1);
+	clk[VF610_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3", "pll2_bus", PFD_PLL2_BASE, 2);
+	clk[VF610_CLK_PLL2_PFD4] = imx_clk_pfd("pll2_pfd4", "pll2_bus", PFD_PLL2_BASE, 3);
+
+	clk[VF610_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", PFD_PLL3_BASE, 0);
+	clk[VF610_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", PFD_PLL3_BASE, 1);
+	clk[VF610_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", PFD_PLL3_BASE, 2);
+	clk[VF610_CLK_PLL3_PFD4] = imx_clk_pfd("pll3_pfd4", "pll3_usb_otg", PFD_PLL3_BASE, 3);
+
+	clk[VF610_CLK_PLL1_PFD_SEL] = imx_clk_mux("pll1_pfd_sel", CCM_CCSR, 16, 3, pll1_sels, 5);
+	clk[VF610_CLK_PLL2_PFD_SEL] = imx_clk_mux("pll2_pfd_sel", CCM_CCSR, 19, 3, pll2_sels, 5);
+	clk[VF610_CLK_SYS_SEL] = imx_clk_mux("sys_sel", CCM_CCSR, 0, 3, sys_sels, ARRAY_SIZE(sys_sels));
+	clk[VF610_CLK_DDR_SEL] = imx_clk_mux("ddr_sel", CCM_CCSR, 6, 1, ddr_sels, ARRAY_SIZE(ddr_sels));
+	clk[VF610_CLK_SYS_BUS] = imx_clk_divider("sys_bus", "sys_sel", CCM_CACRR, 0, 3);
+	clk[VF610_CLK_PLATFORM_BUS] = imx_clk_divider("platform_bus", "sys_bus", CCM_CACRR, 3, 3);
+	clk[VF610_CLK_IPG_BUS] = imx_clk_divider("ipg_bus", "platform_bus", CCM_CACRR, 11, 2);
+
+	clk[VF610_CLK_PLL3_MAIN_DIV] = imx_clk_divider("pll3_usb_otg_div", "pll3_usb_otg", CCM_CACRR, 20, 1);
+	clk[VF610_CLK_PLL4_MAIN_DIV] = clk_divider_table("pll4_audio_div", "pll4_audio", CCM_CACRR, 6, 3, pll4_audio_div_table, 0);
+	clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1);
+
+	clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
+	clk[VF610_CLK_WKPU] = imx_clk_gate2_cgr("wkpu", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(10), 0x2);
+
+	clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6);
+	clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6);
+
+	clk[VF610_CLK_USBC0] = imx_clk_gate2("usbc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(4));
+	clk[VF610_CLK_USBC1] = imx_clk_gate2("usbc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(4));
+
+	clk[VF610_CLK_QSPI0_SEL] = imx_clk_mux("qspi0_sel", CCM_CSCMR1, 22, 2, qspi_sels, 4);
+	clk[VF610_CLK_QSPI0_EN] = imx_clk_gate("qspi0_en", "qspi0_sel", CCM_CSCDR3, 4);
+	clk[VF610_CLK_QSPI0_X4_DIV] = imx_clk_divider("qspi0_x4", "qspi0_en", CCM_CSCDR3, 0, 2);
+	clk[VF610_CLK_QSPI0_X2_DIV] = imx_clk_divider("qspi0_x2", "qspi0_x4", CCM_CSCDR3, 2, 1);
+	clk[VF610_CLK_QSPI0_X1_DIV] = imx_clk_divider("qspi0_x1", "qspi0_x2", CCM_CSCDR3, 3, 1);
+	clk[VF610_CLK_QSPI0] = imx_clk_gate2("qspi0", "qspi0_x1", CCM_CCGR2, CCM_CCGRx_CGn(4));
+
+	clk[VF610_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", CCM_CSCMR1, 24, 2, qspi_sels, 4);
+	clk[VF610_CLK_QSPI1_EN] = imx_clk_gate("qspi1_en", "qspi1_sel", CCM_CSCDR3, 12);
+	clk[VF610_CLK_QSPI1_X4_DIV] = imx_clk_divider("qspi1_x4", "qspi1_en", CCM_CSCDR3, 8, 2);
+	clk[VF610_CLK_QSPI1_X2_DIV] = imx_clk_divider("qspi1_x2", "qspi1_x4", CCM_CSCDR3, 10, 1);
+	clk[VF610_CLK_QSPI1_X1_DIV] = imx_clk_divider("qspi1_x1", "qspi1_x2", CCM_CSCDR3, 11, 1);
+	clk[VF610_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_x1", CCM_CCGR8, CCM_CCGRx_CGn(4));
+
+	clk[VF610_CLK_ENET_50M] = imx_clk_fixed_factor("enet_50m", "pll5_enet", 1, 10);
+	clk[VF610_CLK_ENET_25M] = imx_clk_fixed_factor("enet_25m", "pll5_enet", 1, 20);
+	clk[VF610_CLK_ENET_SEL] = imx_clk_mux("enet_sel", CCM_CSCMR2, 4, 2, rmii_sels, 4);
+	clk[VF610_CLK_ENET_TS_SEL] = imx_clk_mux("enet_ts_sel", CCM_CSCMR2, 0, 3, enet_ts_sels, 7);
+	clk[VF610_CLK_ENET] = imx_clk_gate("enet", "enet_sel", CCM_CSCDR1, 24);
+	clk[VF610_CLK_ENET_TS] = imx_clk_gate("enet_ts", "enet_ts_sel", CCM_CSCDR1, 23);
+	clk[VF610_CLK_ENET0] = imx_clk_gate2("enet0", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(0));
+	clk[VF610_CLK_ENET1] = imx_clk_gate2("enet1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(1));
+
+	clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7));
+
+	clk[VF610_CLK_UART0] = imx_clk_gate2_cgr("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7), 0x2);
+	clk[VF610_CLK_UART1] = imx_clk_gate2_cgr("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8), 0x2);
+	clk[VF610_CLK_UART2] = imx_clk_gate2_cgr("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9), 0x2);
+	clk[VF610_CLK_UART3] = imx_clk_gate2_cgr("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10), 0x2);
+	clk[VF610_CLK_UART4] = imx_clk_gate2_cgr("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9), 0x2);
+	clk[VF610_CLK_UART5] = imx_clk_gate2_cgr("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10), 0x2);
+
+	clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6));
+	clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7));
+	clk[VF610_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(6));
+	clk[VF610_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(7));
+
+	clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12));
+	clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13));
+	clk[VF610_CLK_DSPI2] = imx_clk_gate2("dspi2", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(12));
+	clk[VF610_CLK_DSPI3] = imx_clk_gate2("dspi3", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(13));
+
+	clk[VF610_CLK_WDT] = imx_clk_gate2("wdt", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(14));
+
+	clk[VF610_CLK_ESDHC0_SEL] = imx_clk_mux("esdhc0_sel", CCM_CSCMR1, 16, 2, esdhc_sels, 4);
+	clk[VF610_CLK_ESDHC0_EN] = imx_clk_gate("esdhc0_en", "esdhc0_sel", CCM_CSCDR2, 28);
+	clk[VF610_CLK_ESDHC0_DIV] = imx_clk_divider("esdhc0_div", "esdhc0_en", CCM_CSCDR2, 16, 4);
+	clk[VF610_CLK_ESDHC0] = imx_clk_gate2("eshc0", "esdhc0_div", CCM_CCGR7, CCM_CCGRx_CGn(1));
+
+	clk[VF610_CLK_ESDHC1_SEL] = imx_clk_mux("esdhc1_sel", CCM_CSCMR1, 18, 2, esdhc_sels, 4);
+	clk[VF610_CLK_ESDHC1_EN] = imx_clk_gate("esdhc1_en", "esdhc1_sel", CCM_CSCDR2, 29);
+	clk[VF610_CLK_ESDHC1_DIV] = imx_clk_divider("esdhc1_div", "esdhc1_en", CCM_CSCDR2, 20, 4);
+	clk[VF610_CLK_ESDHC1] = imx_clk_gate2("eshc1", "esdhc1_div", CCM_CCGR7, CCM_CCGRx_CGn(2));
+
+	/*
+	 * ftm_ext_clk and ftm_fix_clk are FTM timer counter's
+	 * selectable clock sources, both use a common enable bit
+	 * in CCM_CSCDR1, selecting "dummy" clock as parent of
+	 * "ftm0_ext_fix" make it serve only for enable/disable.
+	 */
+	clk[VF610_CLK_FTM0_EXT_SEL] = imx_clk_mux("ftm0_ext_sel", CCM_CSCMR2, 6, 2, ftm_ext_sels, 4);
+	clk[VF610_CLK_FTM0_FIX_SEL] = imx_clk_mux("ftm0_fix_sel", CCM_CSCMR2, 14, 1, ftm_fix_sels, 2);
+	clk[VF610_CLK_FTM0_EXT_FIX_EN] = imx_clk_gate("ftm0_ext_fix_en", "dummy", CCM_CSCDR1, 25);
+	clk[VF610_CLK_FTM1_EXT_SEL] = imx_clk_mux("ftm1_ext_sel", CCM_CSCMR2, 8, 2, ftm_ext_sels, 4);
+	clk[VF610_CLK_FTM1_FIX_SEL] = imx_clk_mux("ftm1_fix_sel", CCM_CSCMR2, 15, 1, ftm_fix_sels, 2);
+	clk[VF610_CLK_FTM1_EXT_FIX_EN] = imx_clk_gate("ftm1_ext_fix_en", "dummy", CCM_CSCDR1, 26);
+	clk[VF610_CLK_FTM2_EXT_SEL] = imx_clk_mux("ftm2_ext_sel", CCM_CSCMR2, 10, 2, ftm_ext_sels, 4);
+	clk[VF610_CLK_FTM2_FIX_SEL] = imx_clk_mux("ftm2_fix_sel", CCM_CSCMR2, 16, 1, ftm_fix_sels, 2);
+	clk[VF610_CLK_FTM2_EXT_FIX_EN] = imx_clk_gate("ftm2_ext_fix_en", "dummy", CCM_CSCDR1, 27);
+	clk[VF610_CLK_FTM3_EXT_SEL] = imx_clk_mux("ftm3_ext_sel", CCM_CSCMR2, 12, 2, ftm_ext_sels, 4);
+	clk[VF610_CLK_FTM3_FIX_SEL] = imx_clk_mux("ftm3_fix_sel", CCM_CSCMR2, 17, 1, ftm_fix_sels, 2);
+	clk[VF610_CLK_FTM3_EXT_FIX_EN] = imx_clk_gate("ftm3_ext_fix_en", "dummy", CCM_CSCDR1, 28);
+
+	/* ftm(n)_clk are FTM module operation clock */
+	clk[VF610_CLK_FTM0] = imx_clk_gate2("ftm0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(8));
+	clk[VF610_CLK_FTM1] = imx_clk_gate2("ftm1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(9));
+	clk[VF610_CLK_FTM2] = imx_clk_gate2("ftm2", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(8));
+	clk[VF610_CLK_FTM3] = imx_clk_gate2("ftm3", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(9));
+
+	clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2);
+	clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19);
+	clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3);
+	clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "ipg_bus", CCM_CCGR3, CCM_CCGRx_CGn(8));
+	clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2);
+	clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23);
+	clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3);
+	clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(8));
+
+	clk[VF610_CLK_TCON0] = imx_clk_gate2("tcon0", "platform_bus", CCM_CCGR1, CCM_CCGRx_CGn(13));
+	clk[VF610_CLK_TCON1] = imx_clk_gate2("tcon1", "platform_bus", CCM_CCGR7, CCM_CCGRx_CGn(13));
+
+	clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4);
+	clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30);
+	clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", CCM_CSCDR2, 24, 4);
+	clk[VF610_CLK_ESAI] = imx_clk_gate2("esai", "esai_div", CCM_CCGR4, CCM_CCGRx_CGn(2));
+
+	clk[VF610_CLK_SAI0_SEL] = imx_clk_mux("sai0_sel", CCM_CSCMR1, 0, 2, sai_sels, 4);
+	clk[VF610_CLK_SAI0_EN] = imx_clk_gate("sai0_en", "sai0_sel", CCM_CSCDR1, 16);
+	clk[VF610_CLK_SAI0_DIV] = imx_clk_divider("sai0_div", "sai0_en", CCM_CSCDR1, 0, 4);
+	clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(15));
+
+	clk[VF610_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", CCM_CSCMR1, 2, 2, sai_sels, 4);
+	clk[VF610_CLK_SAI1_EN] = imx_clk_gate("sai1_en", "sai1_sel", CCM_CSCDR1, 17);
+	clk[VF610_CLK_SAI1_DIV] = imx_clk_divider("sai1_div", "sai1_en", CCM_CSCDR1, 4, 4);
+	clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(0));
+
+	clk[VF610_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", CCM_CSCMR1, 4, 2, sai_sels, 4);
+	clk[VF610_CLK_SAI2_EN] = imx_clk_gate("sai2_en", "sai2_sel", CCM_CSCDR1, 18);
+	clk[VF610_CLK_SAI2_DIV] = imx_clk_divider("sai2_div", "sai2_en", CCM_CSCDR1, 8, 4);
+	clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(1));
+
+	clk[VF610_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", CCM_CSCMR1, 6, 2, sai_sels, 4);
+	clk[VF610_CLK_SAI3_EN] = imx_clk_gate("sai3_en", "sai3_sel", CCM_CSCDR1, 19);
+	clk[VF610_CLK_SAI3_DIV] = imx_clk_divider("sai3_div", "sai3_en", CCM_CSCDR1, 12, 4);
+	clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(2));
+
+	clk[VF610_CLK_NFC_SEL] = imx_clk_mux("nfc_sel", CCM_CSCMR1, 12, 2, nfc_sels, 4);
+	clk[VF610_CLK_NFC_EN] = imx_clk_gate("nfc_en", "nfc_sel", CCM_CSCDR2, 9);
+	clk[VF610_CLK_NFC_PRE_DIV] = imx_clk_divider("nfc_pre_div", "nfc_en", CCM_CSCDR3, 13, 3);
+	clk[VF610_CLK_NFC_FRAC_DIV] = imx_clk_divider("nfc_frac_div", "nfc_pre_div", CCM_CSCDR2, 4, 4);
+	clk[VF610_CLK_NFC] = imx_clk_gate2("nfc", "nfc_frac_div", CCM_CCGR10, CCM_CCGRx_CGn(0));
+
+	clk[VF610_CLK_GPU_SEL] = imx_clk_mux("gpu_sel", CCM_CSCMR1, 14, 1, gpu_sels, 2);
+	clk[VF610_CLK_GPU_EN] = imx_clk_gate("gpu_en", "gpu_sel", CCM_CSCDR2, 10);
+	clk[VF610_CLK_GPU2D] = imx_clk_gate2("gpu", "gpu_en", CCM_CCGR8, CCM_CCGRx_CGn(15));
+
+	clk[VF610_CLK_VADC_SEL] = imx_clk_mux("vadc_sel", CCM_CSCMR1, 8, 2, vadc_sels, 3);
+	clk[VF610_CLK_VADC_EN] = imx_clk_gate("vadc_en", "vadc_sel", CCM_CSCDR1, 22);
+	clk[VF610_CLK_VADC_DIV] = imx_clk_divider("vadc_div", "vadc_en", CCM_CSCDR1, 20, 2);
+	clk[VF610_CLK_VADC_DIV_HALF] = imx_clk_fixed_factor("vadc_div_half", "vadc_div", 1, 2);
+	clk[VF610_CLK_VADC] = imx_clk_gate2("vadc", "vadc_div", CCM_CCGR8, CCM_CCGRx_CGn(7));
+
+	clk[VF610_CLK_ADC0] = imx_clk_gate2("adc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(11));
+	clk[VF610_CLK_ADC1] = imx_clk_gate2("adc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(11));
+	clk[VF610_CLK_DAC0] = imx_clk_gate2("dac0", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(12));
+	clk[VF610_CLK_DAC1] = imx_clk_gate2("dac1", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(13));
+
+	clk[VF610_CLK_ASRC] = imx_clk_gate2("asrc", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(1));
+
+	clk[VF610_CLK_FLEXCAN0_EN] = imx_clk_gate("flexcan0_en", "ipg_bus", CCM_CSCDR2, 11);
+	clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "flexcan0_en", CCM_CCGR0, CCM_CCGRx_CGn(0));
+	clk[VF610_CLK_FLEXCAN1_EN] = imx_clk_gate("flexcan1_en", "ipg_bus", CCM_CSCDR2, 12);
+	clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "flexcan1_en", CCM_CCGR9, CCM_CCGRx_CGn(4));
+
+	clk[VF610_CLK_DMAMUX0] = imx_clk_gate2("dmamux0", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(4));
+	clk[VF610_CLK_DMAMUX1] = imx_clk_gate2("dmamux1", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(5));
+	clk[VF610_CLK_DMAMUX2] = imx_clk_gate2("dmamux2", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(1));
+	clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2));
+
+	clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
+	clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
+	clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5));
+
+	imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+	clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]);
+	clk_set_rate(clk[VF610_CLK_QSPI0_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_SEL]) / 2);
+	clk_set_rate(clk[VF610_CLK_QSPI0_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X4_DIV]) / 2);
+	clk_set_rate(clk[VF610_CLK_QSPI0_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X2_DIV]) / 2);
+
+	clk_set_parent(clk[VF610_CLK_QSPI1_SEL], clk[VF610_CLK_PLL1_PFD4]);
+	clk_set_rate(clk[VF610_CLK_QSPI1_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_SEL]) / 2);
+	clk_set_rate(clk[VF610_CLK_QSPI1_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X4_DIV]) / 2);
+	clk_set_rate(clk[VF610_CLK_QSPI1_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X2_DIV]) / 2);
+
+	clk_set_parent(clk[VF610_CLK_ESDHC1_SEL], clk[VF610_CLK_PLL1_PFD3]);
+	clk_set_rate(clk[VF610_CLK_ESDHC1_DIV], clk_get_rate(clk[VF610_CLK_PLL1_PFD3]) / 9);
+
+	clk_set_parent(clk[VF610_CLK_SAI0_SEL], clk[VF610_CLK_AUDIO_EXT]);
+	clk_set_parent(clk[VF610_CLK_SAI1_SEL], clk[VF610_CLK_AUDIO_EXT]);
+	clk_set_parent(clk[VF610_CLK_SAI2_SEL], clk[VF610_CLK_AUDIO_EXT]);
+	clk_set_parent(clk[VF610_CLK_SAI3_SEL], clk[VF610_CLK_AUDIO_EXT]);
+
+	for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+		clk_enable(clk[clks_init_on[i]]);
+
+	/* Add the clocks to provider list */
+	clk_data.clks = clk;
+	clk_data.clk_num = ARRAY_SIZE(clk);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+CLK_OF_DECLARE(vf610, "fsl,vf610-ccm", vf610_clocks_init);
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 16/28] vf610: Give enet_osc explicit "enet_ext" name
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (14 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 15/28] i.MX: Add VF610 clock tree initialization code Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 17/28] i.MX: Add 'lpuart' serial driver Andrey Smirnov
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Give enet_osc explicit "enet_ext" name, since without it, Barebox
version of clk_set_parent fails when trying to re-parent "enet_sel".

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/dts/vf610-twr.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/dts/vf610-twr.dts b/arch/arm/dts/vf610-twr.dts
index 54b4435..5947fdb 100644
--- a/arch/arm/dts/vf610-twr.dts
+++ b/arch/arm/dts/vf610-twr.dts
@@ -12,3 +12,7 @@
 &usbdev0 {
 	status = "disabled";
 };
+
+&enet_ext {
+	clock-output-names = "enet_ext";
+};
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 17/28] i.MX: Add 'lpuart' serial driver
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (15 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 16/28] vf610: Give enet_osc explicit "enet_ext" name Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 18/28] i.MX: i2c: Use read/write adapter functions Andrey Smirnov
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Add 'lpuart' serial driver, based on analogous driver from U-Boot

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/serial/Kconfig         |   5 +
 drivers/serial/Makefile        |   1 +
 drivers/serial/serial_lpuart.c | 217 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 223 insertions(+)
 create mode 100644 drivers/serial/serial_lpuart.c

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b112d7e..4eab437 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -137,4 +137,9 @@ config DRIVER_SERIAL_DIGIC
 	bool "Canon DIGIC serial driver"
 	depends on ARCH_DIGIC
 
+config DRIVER_SERIAL_LPUART
+	depends on ARCH_VF610
+	default y
+	bool "LPUART serial driver"
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 189e777..7d1bae1 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_DRIVER_SERIAL_AUART)		+= serial_auart.o
 obj-$(CONFIG_DRIVER_SERIAL_CADENCE)		+= serial_cadence.o
 obj-$(CONFIG_DRIVER_SERIAL_EFI_STDIO)		+= efi-stdio.o
 obj-$(CONFIG_DRIVER_SERIAL_DIGIC)		+= serial_digic.o
+obj-$(CONFIG_DRIVER_SERIAL_LPUART)		+= serial_lpuart.o
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
new file mode 100644
index 0000000..52fb6d3
--- /dev/null
+++ b/drivers/serial/serial_lpuart.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2016 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * Based on analogous driver from U-Boot
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <malloc.h>
+#include <notifier.h>
+#include <io.h>
+#include <of.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <serial/lpuart.h>
+
+struct lpuart {
+	struct console_device cdev;
+	int baudrate;
+	int dte_mode;
+	struct notifier_block notify;
+	struct resource *io;
+	void __iomem *base;
+	struct clk *clk;
+};
+
+static struct lpuart *cdev_to_lpuart(struct console_device *cdev)
+{
+	return container_of(cdev, struct lpuart, cdev);
+}
+
+static struct lpuart *nb_to_lpuart(struct notifier_block *nb)
+{
+	return container_of(nb, struct lpuart, notify);
+}
+
+static void lpuart_enable(struct lpuart *lpuart, bool on)
+{
+	u8 ctrl;
+
+	ctrl = readb(lpuart->base + UARTCR2);
+	if (on)
+		ctrl |= UARTCR2_TE | UARTCR2_RE;
+	else
+		ctrl &= ~(UARTCR2_TE | UARTCR2_RE);
+	writeb(ctrl, lpuart->base + UARTCR2);
+}
+
+static int lpuart_serial_setbaudrate(struct console_device *cdev,
+				     int baudrate)
+{
+	struct lpuart *lpuart = cdev_to_lpuart(cdev);
+
+	lpuart_enable(lpuart, false);
+
+	lpuart_setbrg(lpuart->base,
+		      clk_get_rate(lpuart->clk),
+		      baudrate);
+
+	lpuart_enable(lpuart, true);
+
+	lpuart->baudrate = baudrate;
+
+	return 0;
+}
+
+static int lpuart_serial_getc(struct console_device *cdev)
+{
+	bool ready;
+	struct lpuart *lpuart = cdev_to_lpuart(cdev);
+
+	do {
+		const u8 sr1 = readb(lpuart->base + UARTSR1);
+		ready = !!(sr1 & (UARTSR1_OR | UARTSR1_RDRF));
+	} while (!ready);
+
+	return readb(lpuart->base + UARTDR);
+}
+
+static void lpuart_serial_putc(struct console_device *cdev, char c)
+{
+	lpuart_putc(cdev_to_lpuart(cdev)->base, c);
+}
+
+/* Test whether a character is in the RX buffer */
+static int lpuart_serial_tstc(struct console_device *cdev)
+{
+	return !!readb(cdev_to_lpuart(cdev)->base + UARTRCFIFO);
+}
+
+static void lpuart_serial_flush(struct console_device *cdev)
+{
+	bool tx_empty;
+	struct lpuart *lpuart = cdev_to_lpuart(cdev);
+
+	do {
+		const u8 sr1 = readb(lpuart->base + UARTSR1);
+		tx_empty = !!(sr1 & UARTSR1_TDRE);
+	} while (!tx_empty);
+}
+
+static int lpuart_clocksource_clock_change(struct notifier_block *nb,
+					   unsigned long event, void *data)
+{
+	struct lpuart *lpuart = nb_to_lpuart(nb);
+
+	return lpuart_serial_setbaudrate(&lpuart->cdev, lpuart->baudrate);
+}
+
+static int lpuart_serial_probe(struct device_d *dev)
+{
+	int ret;
+	struct console_device *cdev;
+	struct lpuart *lpuart;
+	const char *devname;
+
+	lpuart    = xzalloc(sizeof(*lpuart));
+	cdev      = &lpuart->cdev;
+	dev->priv = lpuart;
+
+	lpuart->io = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(lpuart->io)) {
+		ret = PTR_ERR(lpuart->io);
+		goto err_free;
+	}
+	lpuart->base = IOMEM(lpuart->io->start);
+
+	lpuart->clk = clk_get(dev, NULL);
+	if (IS_ERR(lpuart->clk)) {
+		ret = PTR_ERR(lpuart->clk);
+		dev_err(dev, "Failed to get UART clock %d\n", ret);
+		goto io_release;
+	}
+
+	ret = clk_enable(lpuart->clk);
+	if (ret) {
+		dev_err(dev, "Failed to enable UART clock %d\n", ret);
+		goto io_release;
+	}
+
+	cdev->dev    = dev;
+	cdev->tstc   = lpuart_serial_tstc;
+	cdev->putc   = lpuart_serial_putc;
+	cdev->getc   = lpuart_serial_getc;
+	cdev->flush  = lpuart_serial_flush;
+	cdev->setbrg = lpuart_serial_setbaudrate;
+
+	if (dev->device_node) {
+		devname = of_alias_get(dev->device_node);
+		if (devname) {
+			cdev->devname = xstrdup(devname);
+			cdev->devid   = DEVICE_ID_SINGLE;
+		}
+	}
+
+	cdev->linux_console_name = "ttyLP";
+
+	lpuart_setup_with_fifo(lpuart->base,
+			       clk_get_rate(lpuart->clk),
+			       15);
+
+	ret = console_register(cdev);
+	if (!ret) {
+		lpuart->notify.notifier_call = lpuart_clocksource_clock_change;
+		clock_register_client(&lpuart->notify);
+
+		return 0;
+	}
+
+	clk_put(lpuart->clk);
+io_release:
+	release_region(lpuart->io);
+err_free:
+	free(lpuart);
+
+	return ret;
+}
+
+static void lpuart_serial_remove(struct device_d *dev)
+{
+	struct lpuart *lpuart = dev->priv;
+
+	lpuart_serial_flush(&lpuart->cdev);
+	console_unregister(&lpuart->cdev);
+	release_region(lpuart->io);
+	clk_put(lpuart->clk);
+
+	free(lpuart);
+}
+
+static struct of_device_id lpuart_serial_dt_ids[] = {
+	{ .compatible = "fsl,vf610-lpuart" },
+	{}
+};
+
+static struct driver_d lpuart_serial_driver = {
+	.name   = "lpuart-serial",
+	.probe  = lpuart_serial_probe,
+	.remove = lpuart_serial_remove,
+	.of_compatible = DRV_OF_COMPAT(lpuart_serial_dt_ids),
+};
+console_platform_driver(lpuart_serial_driver);
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 18/28] i.MX: i2c: Use read/write adapter functions
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (16 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 17/28] i.MX: Add 'lpuart' serial driver Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 19/28] i.MX: i2c: Add Vybrid support Andrey Smirnov
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Use read/write adapter functions instead of directly calling to
readb/writeb. This is needed to prepare driver code to support Vybrid
SoC's variant of this block.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/i2c/busses/i2c-imx.c | 88 +++++++++++++++++++++++---------------------
 1 file changed, 46 insertions(+), 42 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index e407896..ec40475 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -115,14 +115,27 @@ struct fsl_i2c_struct {
 };
 #define to_fsl_i2c_struct(a)	container_of(a, struct fsl_i2c_struct, adapter)
 
+static inline void fsl_i2c_write_reg(unsigned int val,
+				     struct fsl_i2c_struct *i2c_fsl,
+				     unsigned int reg)
+{
+	writeb(val, i2c_fsl->base + reg);
+}
+
+static inline unsigned char fsl_i2c_read_reg(struct fsl_i2c_struct *i2c_fsl,
+					     unsigned int reg)
+{
+	return readb(i2c_fsl->base + reg);
+}
+
 #ifdef CONFIG_I2C_DEBUG
 static void i2c_fsl_dump_reg(struct i2c_adapter *adapter)
 {
 	struct fsl_i2c_struct *i2c_fsl = to_fsl_i2c_struct(adapter);
 	u32 reg_cr, reg_sr;
 
-	reg_cr = readb(i2c_fsl->base + FSL_I2C_I2CR);
-	reg_sr = readb(i2c_fsl->base + FSL_I2C_I2SR);
+	reg_cr = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
+	reg_sr = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2SR);
 
 	dev_dbg(adapter->dev, "CONTROL:\t"
 		"IEN =%d, IIEN=%d, MSTA=%d, MTX =%d, TXAK=%d, RSTA=%d\n",
@@ -144,16 +157,16 @@ static inline void i2c_fsl_dump_reg(struct i2c_adapter *adapter)
 }
 #endif
 
+
 static int i2c_fsl_bus_busy(struct i2c_adapter *adapter, int for_busy)
 {
 	struct fsl_i2c_struct *i2c_fsl = to_fsl_i2c_struct(adapter);
-	void __iomem *base = i2c_fsl->base;
 	uint64_t start;
 	unsigned int temp;
 
 	start = get_time_ns();
 	while (1) {
-		temp = readb(base + FSL_I2C_I2SR);
+		temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2SR);
 		if (for_busy && (temp & I2SR_IBB))
 			break;
 		if (!for_busy && !(temp & I2SR_IBB))
@@ -172,12 +185,11 @@ static int i2c_fsl_bus_busy(struct i2c_adapter *adapter, int for_busy)
 static int i2c_fsl_trx_complete(struct i2c_adapter *adapter)
 {
 	struct fsl_i2c_struct *i2c_fsl = to_fsl_i2c_struct(adapter);
-	void __iomem *base = i2c_fsl->base;
 	uint64_t start;
 
 	start = get_time_ns();
 	while (1) {
-		unsigned int reg = readb(base + FSL_I2C_I2SR);
+		unsigned int reg = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2SR);
 		if (reg & I2SR_IIF)
 			break;
 
@@ -186,7 +198,7 @@ static int i2c_fsl_trx_complete(struct i2c_adapter *adapter)
 			return -EIO;
 		}
 	}
-	writeb(0, base + FSL_I2C_I2SR);
+	fsl_i2c_write_reg(0, i2c_fsl, FSL_I2C_I2SR);
 
 	return 0;
 }
@@ -194,12 +206,11 @@ static int i2c_fsl_trx_complete(struct i2c_adapter *adapter)
 static int i2c_fsl_acked(struct i2c_adapter *adapter)
 {
 	struct fsl_i2c_struct *i2c_fsl = to_fsl_i2c_struct(adapter);
-	void __iomem *base = i2c_fsl->base;
 	uint64_t start;
 
 	start = get_time_ns();
 	while (1) {
-		unsigned int reg = readb(base + FSL_I2C_I2SR);
+		unsigned int reg = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2SR);
 		if (!(reg & I2SR_RXAK))
 			break;
 
@@ -215,25 +226,24 @@ static int i2c_fsl_acked(struct i2c_adapter *adapter)
 static int i2c_fsl_start(struct i2c_adapter *adapter)
 {
 	struct fsl_i2c_struct *i2c_fsl = to_fsl_i2c_struct(adapter);
-	void __iomem *base = i2c_fsl->base;
 	unsigned int temp = 0;
 	int result;
 
-	writeb(i2c_fsl->ifdr, base + FSL_I2C_IFDR);
+	fsl_i2c_write_reg(i2c_fsl->ifdr, fsl_i2c, FSL_I2C_IFDR);
 	if (i2c_fsl->dfsrr != -1)
-		writeb(i2c_fsl->dfsrr, base + FSL_I2C_DFSRR);
+		fsl_i2c_write_reg(i2c_fsl->dfsrr, fsl_i2c, FSL_I2C_DFSRR);
 
 	/* Enable I2C controller */
-	writeb(0, base + FSL_I2C_I2SR);
-	writeb(I2CR_IEN, base + FSL_I2C_I2CR);
+	fsl_i2c_write_reg(0, fsl_i2c, FSL_I2C_I2SR);
+	fsl_i2c_write_reg(I2CR_IEN, fsl_i2c, FSL_I2C_I2CR);
 
 	/* Wait controller to be stable */
 	udelay(100);
 
 	/* Start I2C transaction */
-	temp = readb(base + FSL_I2C_I2CR);
+	temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 	temp |= I2CR_MSTA;
-	writeb(temp, base + FSL_I2C_I2CR);
+	fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
 
 	result = i2c_fsl_bus_busy(adapter, 1);
 	if (result) {
@@ -246,7 +256,7 @@ static int i2c_fsl_start(struct i2c_adapter *adapter)
 	i2c_fsl->stopped = 0;
 
 	temp |= I2CR_MTX | I2CR_TXAK;
-	writeb(temp, base + FSL_I2C_I2CR);
+	fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
 
 	return result;
 }
@@ -254,14 +264,13 @@ static int i2c_fsl_start(struct i2c_adapter *adapter)
 static void i2c_fsl_stop(struct i2c_adapter *adapter)
 {
 	struct fsl_i2c_struct *i2c_fsl = to_fsl_i2c_struct(adapter);
-	void __iomem *base = i2c_fsl->base;
 	unsigned int temp = 0;
 
 	if (!i2c_fsl->stopped) {
 		/* Stop I2C transaction */
-		temp = readb(base + FSL_I2C_I2CR);
+		temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 		temp &= ~(I2CR_MSTA | I2CR_MTX);
-		writeb(temp, base + FSL_I2C_I2CR);
+		fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
 		/* wait for the stop condition to be send, otherwise the i2c
 		 * controller is disabled before the STOP is sent completely */
 		i2c_fsl->stopped = i2c_fsl_bus_busy(adapter, 0) ? 0 : 1;
@@ -273,14 +282,13 @@ static void i2c_fsl_stop(struct i2c_adapter *adapter)
 	}
 
 	/* Disable I2C controller, and force our state to stopped */
-	writeb(0, base + FSL_I2C_I2CR);
+	fsl_i2c_write_reg(0, fsl_i2c, FSL_I2C_I2CR);
 }
 
 #ifdef CONFIG_PPC
 static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl,
 				    unsigned int rate)
 {
-	void __iomem *base;
 	unsigned int i2c_clk;
 	unsigned short divider;
 	/*
@@ -295,7 +303,6 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl,
 	unsigned long c_div, est_div;
 
 	fdr = 0x31; /* Default if no FDR found */
-	base = i2c_fsl->base;
 	i2c_clk = fsl_get_i2c_freq();
 	divider = min((unsigned short)(i2c_clk / rate), (unsigned short) -1);
 
@@ -387,7 +394,6 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl,
 static int i2c_fsl_write(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 {
 	struct fsl_i2c_struct *i2c_fsl = to_fsl_i2c_struct(adapter);
-	void __iomem *base = i2c_fsl->base;
 	int i, result;
 
 	if ( !(msgs->flags & I2C_M_DATA_ONLY) ) {
@@ -396,7 +402,7 @@ static int i2c_fsl_write(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 			__func__, msgs->addr << 1);
 
 		/* write slave address */
-		writeb(msgs->addr << 1, base + FSL_I2C_I2DR);
+		fsl_i2c_write_reg(msgs->addr << 1, fsl_i2c, FSL_I2C_I2DR);
 
 		result = i2c_fsl_trx_complete(adapter);
 		if (result)
@@ -411,7 +417,7 @@ static int i2c_fsl_write(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 		dev_dbg(&adapter->dev,
 			"<%s> write byte: B%d=0x%02X\n",
 			__func__, i, msgs->buf[i]);
-		writeb(msgs->buf[i], base + FSL_I2C_I2DR);
+		fsl_i2c_write_reg(msgs->buf[i], fsl_i2c, FSL_I2C_I2DR);
 
 		result = i2c_fsl_trx_complete(adapter);
 		if (result)
@@ -426,12 +432,11 @@ static int i2c_fsl_write(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 {
 	struct fsl_i2c_struct *i2c_fsl = to_fsl_i2c_struct(adapter);
-	void __iomem *base = i2c_fsl->base;
 	int i, result;
 	unsigned int temp;
 
 	/* clear IIF */
-	writeb(0x0, base + FSL_I2C_I2SR);
+	fsl_i2c_write_reg(0x0, fsl_i2c, FSL_I2C_I2SR);
 
 	if ( !(msgs->flags & I2C_M_DATA_ONLY) ) {
 		dev_dbg(&adapter->dev,
@@ -439,7 +444,7 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 			__func__, (msgs->addr << 1) | 0x01);
 
 		/* write slave address */
-		writeb((msgs->addr << 1) | 0x01, base + FSL_I2C_I2DR);
+		fsl_i2c_write_reg((msgs->addr << 1) | 0x01, fsl_i2c, FSL_I2C_I2DR);
 
 		result = i2c_fsl_trx_complete(adapter);
 		if (result)
@@ -450,13 +455,13 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 	}
 
 	/* setup bus to read data */
-	temp = readb(base + FSL_I2C_I2CR);
+	temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 	temp &= ~I2CR_MTX;
 	if (msgs->len - 1)
 		temp &= ~I2CR_TXAK;
-	writeb(temp, base + FSL_I2C_I2CR);
+	fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
 
-	readb(base + FSL_I2C_I2DR);	/* dummy read */
+	fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2DR);	/* dummy read */
 
 	/* read data */
 	for (i = 0; i < msgs->len; i++) {
@@ -469,9 +474,9 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 			 * It must generate STOP before read I2DR to prevent
 			 * controller from generating another clock cycle
 			 */
-			temp = readb(base + FSL_I2C_I2CR);
+			temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 			temp &= ~(I2CR_MSTA | I2CR_MTX);
-			writeb(temp, base + FSL_I2C_I2CR);
+			fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
 
 			/*
 			 * adding this delay helps on low bitrates
@@ -481,11 +486,11 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 			i2c_fsl_bus_busy(adapter, 0);
 			i2c_fsl->stopped = 1;
 		} else if (i == (msgs->len - 2)) {
-			temp = readb(base + FSL_I2C_I2CR);
+			temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 			temp |= I2CR_TXAK;
-			writeb(temp, base + FSL_I2C_I2CR);
+			fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
 		}
-		msgs->buf[i] = readb(base + FSL_I2C_I2DR);
+		msgs->buf[i] = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2DR);
 
 		dev_dbg(&adapter->dev, "<%s> read byte: B%d=0x%02X\n",
 			__func__, i, msgs->buf[i]);
@@ -497,7 +502,6 @@ static int i2c_fsl_xfer(struct i2c_adapter *adapter,
 			struct i2c_msg *msgs, int num)
 {
 	struct fsl_i2c_struct *i2c_fsl = to_fsl_i2c_struct(adapter);
-	void __iomem *base = i2c_fsl->base;
 	unsigned int i, temp;
 	int result;
 
@@ -514,9 +518,9 @@ static int i2c_fsl_xfer(struct i2c_adapter *adapter,
 	/* read/write data */
 	for (i = 0; i < num; i++) {
 		if (i && !(msgs[i].flags & I2C_M_DATA_ONLY)) {
-			temp = readb(base + FSL_I2C_I2CR);
+			temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 			temp |= I2CR_RSTA;
-			writeb(temp, base + FSL_I2C_I2CR);
+			fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
 
 			result = i2c_fsl_bus_busy(adapter, 1);
 			if (result)
@@ -623,8 +627,8 @@ static int __init i2c_fsl_probe(struct device_d *pdev)
 		i2c_fsl_set_clk(i2c_fsl, FSL_I2C_BIT_RATE);
 
 	/* Set up chip registers to defaults */
-	writeb(0, i2c_fsl->base + FSL_I2C_I2CR);
-	writeb(0, i2c_fsl->base + FSL_I2C_I2SR);
+	fsl_i2c_write_reg(0, i2c_fsl, FSL_I2C_I2CR);
+	fsl_i2c_write_reg(0, i2c_fsl, FSL_I2C_I2SR);
 
 	/* Add I2C adapter */
 	ret = i2c_add_numbered_adapter(&i2c_fsl->adapter);
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 19/28] i.MX: i2c: Add Vybrid support
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (17 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 18/28] i.MX: i2c: Use read/write adapter functions Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 20/28] i.MX: esdhc: Do not rely on CPU type for quirks Andrey Smirnov
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/i2c/busses/i2c-imx.c | 175 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 138 insertions(+), 37 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index ec40475..ee0cfcc 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -43,6 +43,7 @@
 #include <linux/err.h>
 #include <pinctrl.h>
 #include <of_gpio.h>
+#include <of_device.h>
 
 #include <io.h>
 #include <i2c/i2c.h>
@@ -54,14 +55,25 @@
 /* Default value */
 #define FSL_I2C_BIT_RATE	100000	/* 100kHz */
 
-/* FSL I2C registers */
+/* IMX I2C registers:
+ * the I2C register offset is different between SoCs,
+ * to provid support for all these chips, split the
+ * register offset into a fixed base address and a
+ * variable shift value, then the full register offset
+ * will be calculated by
+ * reg_off = ( reg_base_addr << reg_shift)
+ */
 #define FSL_I2C_IADR	0x00	/* i2c slave address */
-#define FSL_I2C_IFDR	0x04	/* i2c frequency divider */
-#define FSL_I2C_I2CR	0x08	/* i2c control */
-#define FSL_I2C_I2SR	0x0C	/* i2c status */
-#define FSL_I2C_I2DR	0x10	/* i2c transfer data */
+#define FSL_I2C_IFDR	0x01	/* i2c frequency divider */
+#define FSL_I2C_I2CR	0x02	/* i2c control */
+#define FSL_I2C_I2SR	0x03	/* i2c status */
+#define FSL_I2C_I2DR	0x04	/* i2c transfer data */
 #define FSL_I2C_DFSRR	0x14	/* i2c digital filter sampling rate */
 
+#define IMX_I2C_REGSHIFT	2
+#define VF610_I2C_REGSHIFT	0
+
+
 /* Bits of FSL I2C registers */
 #define I2SR_RXAK	0x01
 #define I2SR_IIF	0x02
@@ -77,6 +89,22 @@
 #define I2CR_IIEN	0x40
 #define I2CR_IEN	0x80
 
+/* register bits different operating codes definition:
+ * 1) I2SR: Interrupt flags clear operation differ between SoCs:
+ * - write zero to clear(w0c) INT flag on i.MX,
+ * - but write one to clear(w1c) INT flag on Vybrid.
+ * 2) I2CR: I2C module enable operation also differ between SoCs:
+ * - set I2CR_IEN bit enable the module on i.MX,
+ * - but clear I2CR_IEN bit enable the module on Vybrid.
+ */
+#define I2SR_CLR_OPCODE_W0C	0x0
+#define I2SR_CLR_OPCODE_W1C	(I2SR_IAL | I2SR_IIF)
+#define I2CR_IEN_OPCODE_0	0x0
+#define I2CR_IEN_OPCODE_1	I2CR_IEN
+
+#define I2C_PM_TIMEOUT		10 /* ms */
+
+
 /*
  * sorted list of clock divider, register value pairs
  * taken from table 26-5, p.26-9, Freescale i.MX
@@ -85,8 +113,14 @@
  *
  * Duplicated divider values removed from list
  */
+struct fsl_i2c_clk_pair {
+	u16	div;
+	u16	val;
+};
+
 #ifndef CONFIG_PPC
-static u16 i2c_clk_div[50][2] = {
+
+static struct fsl_i2c_clk_pair imx_i2c_clk_div[] = {
 	{ 22,	0x20 }, { 24,	0x21 }, { 26,	0x22 }, { 28,	0x23 },
 	{ 30,	0x00 },	{ 32,	0x24 }, { 36,	0x25 }, { 40,	0x26 },
 	{ 42,	0x03 }, { 44,	0x27 },	{ 48,	0x28 }, { 52,	0x05 },
@@ -101,8 +135,36 @@ static u16 i2c_clk_div[50][2] = {
 	{ 1920,	0x1B },	{ 2048,	0x3F }, { 2304,	0x1C }, { 2560,	0x1D },
 	{ 3072,	0x1E }, { 3840,	0x1F }
 };
+
+/* Vybrid VF610 clock divider, register value pairs */
+static struct fsl_i2c_clk_pair vf610_i2c_clk_div[] = {
+	{ 20,   0x00 }, { 22,   0x01 }, { 24,   0x02 }, { 26,   0x03 },
+	{ 28,   0x04 }, { 30,   0x05 }, { 32,   0x09 }, { 34,   0x06 },
+	{ 36,   0x0A }, { 40,   0x07 }, { 44,   0x0C }, { 48,   0x0D },
+	{ 52,   0x43 }, { 56,   0x0E }, { 60,   0x45 }, { 64,   0x12 },
+	{ 68,   0x0F }, { 72,   0x13 }, { 80,   0x14 }, { 88,   0x15 },
+	{ 96,   0x19 }, { 104,  0x16 }, { 112,  0x1A }, { 128,  0x17 },
+	{ 136,  0x4F }, { 144,  0x1C }, { 160,  0x1D }, { 176,  0x55 },
+	{ 192,  0x1E }, { 208,  0x56 }, { 224,  0x22 }, { 228,  0x24 },
+	{ 240,  0x1F }, { 256,  0x23 }, { 288,  0x5C }, { 320,  0x25 },
+	{ 384,  0x26 }, { 448,  0x2A }, { 480,  0x27 }, { 512,  0x2B },
+	{ 576,  0x2C }, { 640,  0x2D }, { 768,  0x31 }, { 896,  0x32 },
+	{ 960,  0x2F }, { 1024, 0x33 }, { 1152, 0x34 }, { 1280, 0x35 },
+	{ 1536, 0x36 }, { 1792, 0x3A }, { 1920, 0x37 }, { 2048, 0x3B },
+	{ 2304, 0x3C }, { 2560, 0x3D }, { 3072, 0x3E }, { 3584, 0x7A },
+	{ 3840, 0x3F }, { 4096, 0x7B }, { 5120, 0x7D }, { 6144, 0x7E },
+};
+
 #endif
 
+struct fsl_i2c_hwdata {
+	unsigned		regshift;
+	struct fsl_i2c_clk_pair	*clk_div;
+	unsigned		ndivs;
+	unsigned		i2sr_clr_opcode;
+	unsigned		i2cr_ien_opcode;
+};
+
 struct fsl_i2c_struct {
 	void __iomem		*base;
 	struct clk		*clk;
@@ -112,6 +174,7 @@ struct fsl_i2c_struct {
 	unsigned int		ifdr;	/* FSL_I2C_IFDR */
 	unsigned int		dfsrr;  /* FSL_I2C_DFSRR */
 	struct i2c_bus_recovery_info rinfo;
+	const struct fsl_i2c_hwdata *hwdata;
 };
 #define to_fsl_i2c_struct(a)	container_of(a, struct fsl_i2c_struct, adapter)
 
@@ -119,12 +182,14 @@ static inline void fsl_i2c_write_reg(unsigned int val,
 				     struct fsl_i2c_struct *i2c_fsl,
 				     unsigned int reg)
 {
+	reg <<= i2c_fsl->hwdata->regshift;
 	writeb(val, i2c_fsl->base + reg);
 }
 
 static inline unsigned char fsl_i2c_read_reg(struct fsl_i2c_struct *i2c_fsl,
 					     unsigned int reg)
 {
+	reg <<= i2c_fsl->hwdata->regshift;
 	return readb(i2c_fsl->base + reg);
 }
 
@@ -198,7 +263,9 @@ static int i2c_fsl_trx_complete(struct i2c_adapter *adapter)
 			return -EIO;
 		}
 	}
-	fsl_i2c_write_reg(0, i2c_fsl, FSL_I2C_I2SR);
+
+	fsl_i2c_write_reg(i2c_fsl->hwdata->i2sr_clr_opcode,
+			  i2c_fsl, FSL_I2C_I2SR);
 
 	return 0;
 }
@@ -229,13 +296,17 @@ static int i2c_fsl_start(struct i2c_adapter *adapter)
 	unsigned int temp = 0;
 	int result;
 
-	fsl_i2c_write_reg(i2c_fsl->ifdr, fsl_i2c, FSL_I2C_IFDR);
+	fsl_i2c_write_reg(i2c_fsl->ifdr, i2c_fsl, FSL_I2C_IFDR);
+#ifdef CONFIG_PPC
 	if (i2c_fsl->dfsrr != -1)
 		fsl_i2c_write_reg(i2c_fsl->dfsrr, fsl_i2c, FSL_I2C_DFSRR);
+#endif
 
 	/* Enable I2C controller */
-	fsl_i2c_write_reg(0, fsl_i2c, FSL_I2C_I2SR);
-	fsl_i2c_write_reg(I2CR_IEN, fsl_i2c, FSL_I2C_I2CR);
+	fsl_i2c_write_reg(i2c_fsl->hwdata->i2sr_clr_opcode,
+			  i2c_fsl, FSL_I2C_I2SR);
+	fsl_i2c_write_reg(i2c_fsl->hwdata->i2cr_ien_opcode,
+			  i2c_fsl, FSL_I2C_I2CR);
 
 	/* Wait controller to be stable */
 	udelay(100);
@@ -243,7 +314,7 @@ static int i2c_fsl_start(struct i2c_adapter *adapter)
 	/* Start I2C transaction */
 	temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 	temp |= I2CR_MSTA;
-	fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
+	fsl_i2c_write_reg(temp, i2c_fsl, FSL_I2C_I2CR);
 
 	result = i2c_fsl_bus_busy(adapter, 1);
 	if (result) {
@@ -256,7 +327,7 @@ static int i2c_fsl_start(struct i2c_adapter *adapter)
 	i2c_fsl->stopped = 0;
 
 	temp |= I2CR_MTX | I2CR_TXAK;
-	fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
+	fsl_i2c_write_reg(temp, i2c_fsl, FSL_I2C_I2CR);
 
 	return result;
 }
@@ -270,7 +341,7 @@ static void i2c_fsl_stop(struct i2c_adapter *adapter)
 		/* Stop I2C transaction */
 		temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 		temp &= ~(I2CR_MSTA | I2CR_MTX);
-		fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
+		fsl_i2c_write_reg(temp, i2c_fsl, FSL_I2C_I2CR);
 		/* wait for the stop condition to be send, otherwise the i2c
 		 * controller is disabled before the STOP is sent completely */
 		i2c_fsl->stopped = i2c_fsl_bus_busy(adapter, 0) ? 0 : 1;
@@ -282,7 +353,8 @@ static void i2c_fsl_stop(struct i2c_adapter *adapter)
 	}
 
 	/* Disable I2C controller, and force our state to stopped */
-	fsl_i2c_write_reg(0, fsl_i2c, FSL_I2C_I2CR);
+	temp = i2c_fsl->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
+	fsl_i2c_write_reg(temp, i2c_fsl, FSL_I2C_I2CR);
 }
 
 #ifdef CONFIG_PPC
@@ -356,6 +428,7 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl,
 static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl,
 			    unsigned int rate)
 {
+	struct fsl_i2c_clk_pair *i2c_clk_div = i2c_fsl->hwdata->clk_div;
 	unsigned int i2c_clk_rate;
 	unsigned int div;
 	int i;
@@ -363,16 +436,16 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl,
 	/* Divider value calculation */
 	i2c_clk_rate = clk_get_rate(i2c_fsl->clk);
 	div = (i2c_clk_rate + rate - 1) / rate;
-	if (div < i2c_clk_div[0][0])
+	if (div < i2c_clk_div[0].div)
 		i = 0;
-	else if (div > i2c_clk_div[ARRAY_SIZE(i2c_clk_div) - 1][0])
-		i = ARRAY_SIZE(i2c_clk_div) - 1;
+	else if (div > i2c_clk_div[i2c_fsl->hwdata->ndivs - 1].div)
+		i = i2c_clk_div[i2c_fsl->hwdata->ndivs - 1].div - 1;
 	else
-		for (i = 0; i2c_clk_div[i][0] < div; i++)
+		for (i = 0; i2c_clk_div[i].div < div; i++)
 			;
 
 	/* Store divider value */
-	i2c_fsl->ifdr = i2c_clk_div[i][1];
+	i2c_fsl->ifdr = i2c_clk_div[i].val;
 
 	/*
 	 * There dummy delay is calculated.
@@ -381,13 +454,13 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl,
 	 * to fix chip hardware bug.
 	 */
 	i2c_fsl->disable_delay =
-		(500000U * i2c_clk_div[i][0] + (i2c_clk_rate / 2) - 1) /
+		(500000U * i2c_clk_div[i].div + (i2c_clk_rate / 2) - 1) /
 		(i2c_clk_rate / 2);
 
 	dev_dbg(&i2c_fsl->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
 		__func__, i2c_clk_rate, div);
 	dev_dbg(&i2c_fsl->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
-		__func__, i2c_clk_div[i][1], i2c_clk_div[i][0]);
+		__func__, i2c_clk_div[i].val, i2c_clk_div[i].div);
 }
 #endif
 
@@ -402,7 +475,8 @@ static int i2c_fsl_write(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 			__func__, msgs->addr << 1);
 
 		/* write slave address */
-		fsl_i2c_write_reg(msgs->addr << 1, fsl_i2c, FSL_I2C_I2DR);
+		fsl_i2c_write_reg(msgs->addr << 1, i2c_fsl,
+				  FSL_I2C_I2DR);
 
 		result = i2c_fsl_trx_complete(adapter);
 		if (result)
@@ -417,7 +491,8 @@ static int i2c_fsl_write(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 		dev_dbg(&adapter->dev,
 			"<%s> write byte: B%d=0x%02X\n",
 			__func__, i, msgs->buf[i]);
-		fsl_i2c_write_reg(msgs->buf[i], fsl_i2c, FSL_I2C_I2DR);
+		fsl_i2c_write_reg(msgs->buf[i], i2c_fsl,
+				  FSL_I2C_I2DR);
 
 		result = i2c_fsl_trx_complete(adapter);
 		if (result)
@@ -436,7 +511,8 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 	unsigned int temp;
 
 	/* clear IIF */
-	fsl_i2c_write_reg(0x0, fsl_i2c, FSL_I2C_I2SR);
+	fsl_i2c_write_reg(i2c_fsl->hwdata->i2sr_clr_opcode,
+			  i2c_fsl, FSL_I2C_I2SR);
 
 	if ( !(msgs->flags & I2C_M_DATA_ONLY) ) {
 		dev_dbg(&adapter->dev,
@@ -444,7 +520,8 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 			__func__, (msgs->addr << 1) | 0x01);
 
 		/* write slave address */
-		fsl_i2c_write_reg((msgs->addr << 1) | 0x01, fsl_i2c, FSL_I2C_I2DR);
+		fsl_i2c_write_reg((msgs->addr << 1) | 0x01, i2c_fsl,
+				  FSL_I2C_I2DR);
 
 		result = i2c_fsl_trx_complete(adapter);
 		if (result)
@@ -459,9 +536,9 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 	temp &= ~I2CR_MTX;
 	if (msgs->len - 1)
 		temp &= ~I2CR_TXAK;
-	fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
+	fsl_i2c_write_reg(temp, i2c_fsl, FSL_I2C_I2CR);
 
-	fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2DR);	/* dummy read */
+	fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2DR); /* dummy read */
 
 	/* read data */
 	for (i = 0; i < msgs->len; i++) {
@@ -476,7 +553,7 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 			 */
 			temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 			temp &= ~(I2CR_MSTA | I2CR_MTX);
-			fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
+			fsl_i2c_write_reg(temp, i2c_fsl, FSL_I2C_I2CR);
 
 			/*
 			 * adding this delay helps on low bitrates
@@ -488,7 +565,7 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
 		} else if (i == (msgs->len - 2)) {
 			temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 			temp |= I2CR_TXAK;
-			fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
+			fsl_i2c_write_reg(temp, i2c_fsl, FSL_I2C_I2CR);
 		}
 		msgs->buf[i] = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2DR);
 
@@ -520,7 +597,7 @@ static int i2c_fsl_xfer(struct i2c_adapter *adapter,
 		if (i && !(msgs[i].flags & I2C_M_DATA_ONLY)) {
 			temp = fsl_i2c_read_reg(i2c_fsl, FSL_I2C_I2CR);
 			temp |= I2CR_RSTA;
-			fsl_i2c_write_reg(temp, fsl_i2c, FSL_I2C_I2CR);
+			fsl_i2c_write_reg(temp, i2c_fsl, FSL_I2C_I2CR);
 
 			result = i2c_fsl_bus_busy(adapter, 1);
 			if (result)
@@ -604,6 +681,13 @@ static int __init i2c_fsl_probe(struct device_d *pdev)
 		goto fail;
 	}
 #endif
+
+	i2c_fsl->hwdata = of_device_get_match_data(pdev);
+	if (!i2c_fsl->hwdata) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
 	/* Setup i2c_fsl driver structure */
 	i2c_fsl->adapter.master_xfer = i2c_fsl_xfer;
 	i2c_fsl->adapter.nr = pdev->id;
@@ -627,8 +711,9 @@ static int __init i2c_fsl_probe(struct device_d *pdev)
 		i2c_fsl_set_clk(i2c_fsl, FSL_I2C_BIT_RATE);
 
 	/* Set up chip registers to defaults */
-	fsl_i2c_write_reg(0, i2c_fsl, FSL_I2C_I2CR);
-	fsl_i2c_write_reg(0, i2c_fsl, FSL_I2C_I2SR);
+	fsl_i2c_write_reg(i2c_fsl->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
+			  i2c_fsl, FSL_I2C_I2CR);
+	fsl_i2c_write_reg(i2c_fsl->hwdata->i2sr_clr_opcode, i2c_fsl, FSL_I2C_I2SR);
 
 	/* Add I2C adapter */
 	ret = i2c_add_numbered_adapter(&i2c_fsl->adapter);
@@ -644,12 +729,28 @@ fail:
 	return ret;
 }
 
+static const struct fsl_i2c_hwdata imx21_i2c_hwdata = {
+	.regshift		= IMX_I2C_REGSHIFT,
+	.clk_div		= imx_i2c_clk_div,
+	.ndivs			= ARRAY_SIZE(imx_i2c_clk_div),
+	.i2sr_clr_opcode	= I2SR_CLR_OPCODE_W0C,
+	.i2cr_ien_opcode	= I2CR_IEN_OPCODE_1,
+
+};
+
+static const struct fsl_i2c_hwdata vf610_i2c_hwdata = {
+	.regshift		= VF610_I2C_REGSHIFT,
+	.clk_div		= vf610_i2c_clk_div,
+	.ndivs			= ARRAY_SIZE(vf610_i2c_clk_div),
+	.i2sr_clr_opcode	= I2SR_CLR_OPCODE_W1C,
+	.i2cr_ien_opcode	= I2CR_IEN_OPCODE_0,
+
+};
+
 static __maybe_unused struct of_device_id imx_i2c_dt_ids[] = {
-	{
-		.compatible = "fsl,imx21-i2c",
-	}, {
-		/* sentinel */
-	}
+	{ .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, },
+	{ .compatible = "fsl,vf610-i2c", .data = &vf610_i2c_hwdata, },
+	{ /* sentinel */ }
 };
 
 static struct driver_d i2c_fsl_driver = {
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 20/28] i.MX: esdhc: Do not rely on CPU type for quirks
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (18 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 19/28] i.MX: i2c: Add Vybrid support Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 21/28] i.MX: esdhc: Request "per" clock explicitly Andrey Smirnov
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

CPU type is not a reliable indicator of the underlying type of IP core
used, since there's no 1:1 mapping between the two. As example of one
such violation consider Vybrid SoC which contains IP block from i.MX53.

Instead port feature flags from corresponding Linux kernel driver and
use the ones that are relevant.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/mci/imx-esdhc.c | 121 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 100 insertions(+), 21 deletions(-)

diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 262a904..764a106 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -35,28 +35,81 @@
 #include <mach/generic.h>
 #include <mach/esdhc.h>
 #include <gpio.h>
+#include <of_device.h>
 
 #include "sdhci.h"
 #include "imx-esdhc.h"
 
+/*
+ * The CMDTYPE of the CMD register (offset 0xE) should be set to
+ * "11" when the STOP CMD12 is issued on imx53 to abort one
+ * open ended multi-blk IO. Otherwise the TC INT wouldn't
+ * be generated.
+ * In exact block transfer, the controller doesn't complete the
+ * operations automatically as required at the end of the
+ * transfer and remains on hold if the abort command is not sent.
+ * As a result, the TC flag is not asserted and SW  received timeout
+ * exeception. Bit1 of Vendor Spec registor is used to fix it.
+ */
+#define ESDHC_FLAG_MULTIBLK_NO_INT	BIT(1)
+/*
+ * The flag enables the workaround for ESDHC errata ENGcm07207 which
+ * affects i.MX25 and i.MX35.
+ */
+#define ESDHC_FLAG_ENGCM07207		BIT(2)
+/*
+ * The flag tells that the ESDHC controller is an USDHC block that is
+ * integrated on the i.MX6 series.
+ */
+#define ESDHC_FLAG_USDHC		BIT(3)
+/* The IP supports manual tuning process */
+#define ESDHC_FLAG_MAN_TUNING		BIT(4)
+/* The IP supports standard tuning process */
+#define ESDHC_FLAG_STD_TUNING		BIT(5)
+/* The IP has SDHCI_CAPABILITIES_1 register */
+#define ESDHC_FLAG_HAVE_CAP1		BIT(6)
+/*
+ * The IP has errata ERR004536
+ * uSDHC: ADMA Length Mismatch Error occurs if the AHB read access is slow,
+ * when reading data from the card
+ */
+#define ESDHC_FLAG_ERR004536		BIT(7)
+/* The IP supports HS200 mode */
+#define ESDHC_FLAG_HS200		BIT(8)
+/* The IP supports HS400 mode */
+#define ESDHC_FLAG_HS400		BIT(9)
+
+
 #define IMX_SDHCI_WML		0x44
 #define IMX_SDHCI_MIXCTRL	0x48
 #define IMX_SDHCI_DLL_CTRL	0x60
 #define IMX_SDHCI_MIX_CTRL_FBCLK_SEL	(BIT(25))
 
+struct esdhc_soc_data {
+	u32 flags;
+};
+
 struct fsl_esdhc_host {
 	struct mci_host		mci;
 	void __iomem		*regs;
 	struct device_d		*dev;
 	struct clk		*clk;
+	const struct esdhc_soc_data *socdata;
 };
 
 #define to_fsl_esdhc(mci)	container_of(mci, struct fsl_esdhc_host, mci)
 
 #define  SDHCI_CMD_ABORTCMD (0xC0 << 16)
 
+static inline int esdhc_is_usdhc(struct fsl_esdhc_host *data)
+{
+	return !!(data->socdata->flags & ESDHC_FLAG_USDHC);
+}
+
+
 /* Return the XFERTYP flags for a given command and data packet */
-static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
+static u32 esdhc_xfertyp(struct fsl_esdhc_host *host,
+			 struct mci_cmd *cmd, struct mci_data *data)
 {
 	u32 xfertyp = 0;
 
@@ -85,8 +138,8 @@ static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
 		xfertyp |= COMMAND_RSPTYP_48_BUSY;
 	else if (cmd->resp_type & MMC_RSP_PRESENT)
 		xfertyp |= COMMAND_RSPTYP_48;
-	if ((cpu_is_mx50() || cpu_is_mx51() || cpu_is_mx53()) &&
-			cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+	if ((host->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) &&
+	    (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION))
 		xfertyp |= SDHCI_CMD_ABORTCMD;
 
 	return COMMAND_CMD(cmd->cmdidx) | xfertyp;
@@ -273,12 +326,12 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
 	}
 
 	/* Figure out the transfer arguments */
-	xfertyp = esdhc_xfertyp(cmd, data);
+	xfertyp = esdhc_xfertyp(host, cmd, data);
 
 	/* Send the command */
 	esdhc_write32(regs + SDHCI_ARGUMENT, cmd->cmdarg);
 
-	if (cpu_is_mx6()) {
+	if (esdhc_is_usdhc(host)) {
 		/* write lower-half of xfertyp to mixctrl */
 		mixctrl = xfertyp & 0xFFFF;
 		/* Keep the bits 22-25 of the register as is */
@@ -525,7 +578,7 @@ static int esdhc_reset(struct fsl_esdhc_host *host)
 			SYSCTL_RSTA);
 
 	/* extra register reset for i.MX6 Solo/DualLite */
-	if (cpu_is_mx6()) {
+	if (esdhc_is_usdhc(host)) {
 		/* reset bit FBCLK_SEL */
 		val = esdhc_read32(regs + IMX_SDHCI_MIXCTRL);
 		val &= ~IMX_SDHCI_MIX_CTRL_FBCLK_SEL;
@@ -570,6 +623,10 @@ static int fsl_esdhc_probe(struct device_d *dev)
 	host = xzalloc(sizeof(*host));
 	mci = &host->mci;
 
+	host->socdata = of_device_get_match_data(dev);
+	if (!host->socdata)
+		return -EINVAL;
+
 	host->clk = clk_get(dev, NULL);
 	if (IS_ERR(host->clk))
 		return PTR_ERR(host->clk);
@@ -634,22 +691,44 @@ static int fsl_esdhc_probe(struct device_d *dev)
 	return mci_register(&host->mci);
 }
 
+static struct esdhc_soc_data esdhc_imx25_data = {
+	.flags = ESDHC_FLAG_ENGCM07207,
+};
+
+static struct esdhc_soc_data esdhc_imx50_data = {
+	.flags = ESDHC_FLAG_MULTIBLK_NO_INT,
+	/* .flags = 0, */
+};
+
+static struct esdhc_soc_data esdhc_imx51_data = {
+	.flags = ESDHC_FLAG_MULTIBLK_NO_INT,
+	/* .flags = 0, */
+};
+
+static struct esdhc_soc_data esdhc_imx53_data = {
+	.flags = ESDHC_FLAG_MULTIBLK_NO_INT,
+};
+
+static struct esdhc_soc_data usdhc_imx6q_data = {
+	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING,
+};
+
+static struct esdhc_soc_data usdhc_imx6sl_data = {
+	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+	       | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_ERR004536
+	       | ESDHC_FLAG_HS200,
+};
+
+
 static __maybe_unused struct of_device_id fsl_esdhc_compatible[] = {
-	{
-		.compatible = "fsl,imx25-esdhc",
-	}, {
-		.compatible = "fsl,imx50-esdhc",
-	}, {
-		.compatible = "fsl,imx51-esdhc",
-	}, {
-		.compatible = "fsl,imx53-esdhc",
-	}, {
-		.compatible = "fsl,imx6q-usdhc",
-	}, {
-		.compatible = "fsl,imx6sl-usdhc",
-	}, {
-		/* sentinel */
-	}
+
+	{ .compatible = "fsl,imx25-esdhc",  .data = &esdhc_imx25_data  },
+	{ .compatible = "fsl,imx50-esdhc",  .data = &esdhc_imx50_data  },
+	{ .compatible = "fsl,imx51-esdhc",  .data = &esdhc_imx51_data  },
+	{ .compatible = "fsl,imx53-esdhc",  .data = &esdhc_imx53_data  },
+	{ .compatible = "fsl,imx6q-usdhc",  .data = &usdhc_imx6q_data  },
+	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data },
+	{ /* sentinel */ }
 };
 
 static struct driver_d fsl_esdhc_driver = {
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 21/28] i.MX: esdhc: Request "per" clock explicitly
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (19 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 20/28] i.MX: esdhc: Do not rely on CPU type for quirks Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 22/28] i.MX: Kconfig: Enable OCOTP on Vybrid Andrey Smirnov
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Calling clk_get() with NULL as the second argument will give us "ipg"
clock as a result. The actual clock feeding into the peripheral is "per"
and, depending on the SoC, "ipg" and "per" may be separated by a clock
divider, so querying "ipg"'s rate may not result in rate that does not
represent the actual peripheral clock rate.

Change the code to request "per" as our peripheral clock to avoid
aforementioned problem.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/mci/imx-esdhc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 764a106..d72e3f8 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -627,7 +627,7 @@ static int fsl_esdhc_probe(struct device_d *dev)
 	if (!host->socdata)
 		return -EINVAL;
 
-	host->clk = clk_get(dev, NULL);
+	host->clk = clk_get(dev, "per");
 	if (IS_ERR(host->clk))
 		return PTR_ERR(host->clk);
 
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 22/28] i.MX: Kconfig: Enable OCOTP on Vybrid
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (20 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 21/28] i.MX: esdhc: Request "per" clock explicitly Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 23/28] i.MX: ocotp: Remove unused #define Andrey Smirnov
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Enable OCOTP driver on Vybrid as well as i.MX6

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 5f4fdc6..24a123a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -659,7 +659,7 @@ config IMX_IIM_FUSE_BLOW
 
 config IMX_OCOTP
 	tristate "i.MX6 On Chip OTP controller"
-	depends on ARCH_IMX6
+	depends on ARCH_IMX6 || ARCH_VF610
 	depends on OFDEVICE
 	help
 	  This adds support for the i.MX6 On-Chip OTP controller. Currently the
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 23/28] i.MX: ocotp: Remove unused #define
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (21 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 22/28] i.MX: Kconfig: Enable OCOTP on Vybrid Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 24/28] i.MX: ocotp: Account for shadow memory gaps Andrey Smirnov
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/ocotp.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 17b944b..44ee0b7 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -66,7 +66,6 @@
 #define BF(value, field)		(((value) << field) & field##_MASK)
 
 /* Other definitions */
-#define FUSE_REGS_COUNT			(16 * 8)
 #define IMX6_OTP_DATA_ERROR_VAL		0xBADABADA
 #define DEF_RELAX			20
 #define MAC_OFFSET			(0x22 * 4)
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 24/28] i.MX: ocotp: Account for shadow memory gaps
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (22 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 23/28] i.MX: ocotp: Remove unused #define Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 25/28] i.MX: ocotp: Add Vybrid support Andrey Smirnov
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Shadow memory does not have a true 1:1 mapping to fuse address
space. All i.MX6 devices, with exception of i.MX6SL have a 0x100 byte
gap between banks 5 and 6 (or addresses 0x2f and 0x30), so we need to
account for that when reading data from shadow memory.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/ocotp.c | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 44ee0b7..b978508 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -73,6 +73,7 @@
 
 struct imx_ocotp_data {
 	int num_regs;
+	u32 (*addr_to_offset)(u32 addr);
 };
 
 struct ocotp_priv {
@@ -84,6 +85,7 @@ struct ocotp_priv {
 	int sense_enable;
 	char ethaddr[6];
 	struct regmap_config map_config;
+	const struct imx_ocotp_data *data;
 };
 
 static int imx6_ocotp_set_timing(struct ocotp_priv *priv)
@@ -192,7 +194,8 @@ static int imx_ocotp_reg_read(void *ctx, unsigned int reg, unsigned int *val)
 		if (ret)
 			return ret;
 	} else {
-		*(u32 *)val = readl(priv->base + 0x400 + index * 0x10);
+		*(u32 *)val = readl(priv->base +
+				    priv->data->addr_to_offset(index));
 	}
 
 	return 0;
@@ -272,7 +275,8 @@ static int imx_ocotp_reg_write(void *ctx, unsigned int reg, unsigned int val)
 		if (ret < 0)
 			return ret;
 	} else {
-		writel(val, priv->base + 0x400 + index * 0x10);
+		writel(val, priv->base +
+		       priv->data->addr_to_offset(index));
 	}
 
 	if (priv->permanent_write_enable)
@@ -374,7 +378,7 @@ static int imx_ocotp_probe(struct device_d *dev)
 	void __iomem *base;
 	struct ocotp_priv *priv;
 	int ret = 0;
-	struct imx_ocotp_data *data;
+	const struct imx_ocotp_data *data;
 
 	ret = dev_get_drvdata(dev, (const void **)&data);
 	if (ret)
@@ -389,6 +393,7 @@ static int imx_ocotp_probe(struct device_d *dev)
 
 	priv = xzalloc(sizeof(*priv));
 
+	priv->data      = data;
 	priv->base	= base;
 	priv->clk	= clk_get(dev, NULL);
 	if (IS_ERR(priv->clk))
@@ -425,12 +430,35 @@ static int imx_ocotp_probe(struct device_d *dev)
 	return 0;
 }
 
+static u32 imx6sl_addr_to_offset(u32 addr)
+{
+	return 0x400 + addr * 0x10;
+}
+
+static u32 imx6q_addr_to_offset(u32 addr)
+{
+	u32 addendum = 0;
+
+	if (addr > 0x2F) {
+		/*
+		 * If we are reading past Bank 5, take into account a
+		 * 0x100 bytes wide gap between Bank 5 and Bank 6
+		 */
+		addendum += 0x100;
+	}
+
+
+	return imx6sl_addr_to_offset(addr) + addendum;
+}
+
 static struct imx_ocotp_data imx6q_ocotp_data = {
 	.num_regs = 512,
+	.addr_to_offset = imx6q_addr_to_offset,
 };
 
 static struct imx_ocotp_data imx6sl_ocotp_data = {
 	.num_regs = 256,
+	.addr_to_offset = imx6sl_addr_to_offset,
 };
 
 static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 25/28] i.MX: ocotp: Add Vybrid support
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (23 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 24/28] i.MX: ocotp: Account for shadow memory gaps Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 26/28] i.MX: fec: Enable all clocks specified for FEC Andrey Smirnov
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/ocotp.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index b978508..989a3cc 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -451,6 +451,14 @@ static u32 imx6q_addr_to_offset(u32 addr)
 	return imx6sl_addr_to_offset(addr) + addendum;
 }
 
+static u32 vf610_addr_to_offset(u32 addr)
+{
+	if (addr == 0x04)
+		return 0x450;
+	else
+		return imx6q_addr_to_offset(addr);
+}
+
 static struct imx_ocotp_data imx6q_ocotp_data = {
 	.num_regs = 512,
 	.addr_to_offset = imx6q_addr_to_offset,
@@ -461,6 +469,11 @@ static struct imx_ocotp_data imx6sl_ocotp_data = {
 	.addr_to_offset = imx6sl_addr_to_offset,
 };
 
+static struct imx_ocotp_data vf610_ocotp_data = {
+	.num_regs = 512,
+	.addr_to_offset = vf610_addr_to_offset,
+};
+
 static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
 	{
 		.compatible = "fsl,imx6q-ocotp",
@@ -472,6 +485,9 @@ static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
 		.compatible = "fsl,imx6sl-ocotp",
 		.data = &imx6sl_ocotp_data,
 	}, {
+		.compatible = "fsl,vf610-ocotp",
+		.data = &vf610_ocotp_data,
+	}, {
 		/* sentinel */
 	}
 };
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 26/28] i.MX: fec: Enable all clocks specified for FEC
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (24 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 25/28] i.MX: ocotp: Add Vybrid support Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 27/28] i.MX: fec: Add support for Vybrid variant Andrey Smirnov
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

For some i.MX variants more than just "ipg" clock need to be enabled for
Ethernet to function, so change the code to enable all of the clock
defined for FEC node (this is what analogous Linux driver does as well).

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/net/fec_imx.c | 71 +++++++++++++++++++++++++++++++++++++++++++--------
 drivers/net/fec_imx.h | 10 +++++++-
 2 files changed, 70 insertions(+), 11 deletions(-)

diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 8bc7c29..1be5b9d 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -51,7 +51,7 @@ static int fec_miibus_read(struct mii_bus *bus, int phyAddr, int regAddr)
 	uint32_t phy;		/* convenient holder for the PHY */
 	uint64_t start;
 
-	writel(((clk_get_rate(fec->clk) >> 20) / 5) << 1,
+	writel(((clk_get_rate(fec->clk[FEC_CLK_IPG]) >> 20) / 5) << 1,
 			fec->regs + FEC_MII_SPEED);
 	/*
 	 * reading from any PHY's register is done by properly
@@ -94,7 +94,7 @@ static int fec_miibus_write(struct mii_bus *bus, int phyAddr,
 	uint32_t phy;		/* convenient holder for the PHY */
 	uint64_t start;
 
-	writel(((clk_get_rate(fec->clk) >> 20) / 5) << 1,
+	writel(((clk_get_rate(fec->clk[FEC_CLK_IPG]) >> 20) / 5) << 1,
 			fec->regs + FEC_MII_SPEED);
 
 	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
@@ -287,7 +287,7 @@ static int fec_init(struct eth_device *dev)
 	 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
 	 * and do not drop the Preamble.
 	 */
-	writel(((clk_get_rate(fec->clk) >> 20) / 5) << 1,
+	writel(((clk_get_rate(fec->clk[FEC_CLK_IPG]) >> 20) / 5) << 1,
 			fec->regs + FEC_MII_SPEED);
 
 	if (fec->interface == PHY_INTERFACE_MODE_RMII) {
@@ -651,6 +651,59 @@ static int fec_probe_dt(struct device_d *dev, struct fec_priv *fec)
 	return -ENODEV;
 }
 #endif
+
+static int fec_clk_enable(struct fec_priv *fec)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(fec->clk); i++) {
+		const int err = clk_enable(fec->clk[i]);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static void fec_clk_disable(struct fec_priv *fec)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(fec->clk); i++) {
+		if (!IS_ERR_OR_NULL(fec->clk[i]))
+			clk_disable(fec->clk[i]);
+	}
+}
+
+static void fec_clk_put(struct fec_priv *fec)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(fec->clk); i++) {
+		if (!IS_ERR_OR_NULL(fec->clk[i]))
+			clk_put(fec->clk[i]);
+	}
+}
+
+static int fec_clk_get(struct fec_priv *fec)
+{
+	int i, err = 0;
+	static const char *clk_names[ARRAY_SIZE(fec->clk)] = {
+		"ipg", "ahb", "ptp"
+	};
+
+	for (i = 0; i < ARRAY_SIZE(fec->clk); i++) {
+		fec->clk[i] = clk_get(fec->edev.parent, clk_names[i]);
+		if (IS_ERR(fec->clk[i])) {
+			err = PTR_ERR(fec->clk[i]);
+			fec_clk_put(fec);
+			break;
+		}
+	}
+
+	return err;
+}
+
 static int fec_probe(struct device_d *dev)
 {
 	struct resource *iores;
@@ -681,13 +734,11 @@ static int fec_probe(struct device_d *dev)
 	edev->set_ethaddr = fec_set_hwaddr;
 	edev->parent = dev;
 
-	fec->clk = clk_get(dev, NULL);
-	if (IS_ERR(fec->clk)) {
-		ret = PTR_ERR(fec->clk);
+	ret = fec_clk_get(fec);
+	if (ret < 0)
 		goto err_free;
-	}
 
-	ret = clk_enable(fec->clk);
+	ret = fec_clk_enable(fec);
 	if (ret < 0)
 		goto put_clk;
 
@@ -787,9 +838,9 @@ free_gpio:
 release_res:
 	release_region(iores);
 disable_clk:
-	clk_disable(fec->clk);
+	fec_clk_disable(fec);
 put_clk:
-	clk_put(fec->clk);
+	fec_clk_put(fec);
 err_free:
 	free(fec);
 	return ret;
diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h
index 1947e60..85d51ba 100644
--- a/drivers/net/fec_imx.h
+++ b/drivers/net/fec_imx.h
@@ -129,6 +129,14 @@ enum fec_type {
 	FEC_TYPE_IMX6,
 };
 
+enum fec_clock {
+	FEC_CLK_IPG,
+	FEC_CLK_AHB,
+	FEC_CLK_PTP,
+
+	FEC_CLK_NUM
+};
+
 /**
  * @brief i.MX27-FEC private structure
  */
@@ -144,7 +152,7 @@ struct fec_priv {
 	u32 phy_flags;
 	struct mii_bus miibus;
 	void (*phy_init)(struct phy_device *dev);
-	struct clk *clk;
+	struct clk *clk[FEC_CLK_NUM];
 	enum fec_type type;
 };
 
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 27/28] i.MX: fec: Add support for Vybrid variant
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (25 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 26/28] i.MX: fec: Enable all clocks specified for FEC Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-09 16:14 ` [PATCH v2 28/28] gpio: Add GPIO driver for Vybrid Andrey Smirnov
  2016-11-11  8:21 ` [PATCH v2 00/28] Vybrid support in Barebox Sascha Hauer
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Add support for Vybrid variant of this IP block

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/net/fec_imx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 1be5b9d..e2b25fe 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -870,6 +870,9 @@ static __maybe_unused struct of_device_id imx_fec_dt_ids[] = {
 		.compatible = "fsl,imx6sx-fec",
 		.data = (void *)FEC_TYPE_IMX6,
 	}, {
+		.compatible = "fsl,mvf600-fec",
+		.data = (void *)FEC_TYPE_IMX6,
+	}, {
 		/* sentinel */
 	}
 };
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 28/28] gpio: Add GPIO driver for Vybrid
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (26 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 27/28] i.MX: fec: Add support for Vybrid variant Andrey Smirnov
@ 2016-11-09 16:14 ` Andrey Smirnov
  2016-11-11  8:21 ` [PATCH v2 00/28] Vybrid support in Barebox Sascha Hauer
  28 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Add GPIO driver for VF610 Family of SoCs (based on analogous driver from
Linux kernel)

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/gpio/Kconfig      |   3 +
 drivers/gpio/Makefile     |   1 +
 drivers/gpio/gpio-vf610.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 185 insertions(+)
 create mode 100644 drivers/gpio/gpio-vf610.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ab919c9..fe62778 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -49,6 +49,9 @@ config GPIO_GENERIC_PLATFORM
 config GPIO_IMX
 	def_bool ARCH_IMX
 
+config GPIO_VF610
+	def_bool ARCH_VF610
+
 config GPIO_MXS
 	def_bool ARCH_MXS
 
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 8767eed..248100f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_GPIO_PL061)	+= gpio-pl061.o
 obj-$(CONFIG_GPIO_STMPE)	+= gpio-stmpe.o
 obj-$(CONFIG_GPIO_TEGRA)	+= gpio-tegra.o
 obj-$(CONFIG_GPIO_DESIGNWARE)	+= gpio-dw.o
+obj-$(CONFIG_GPIO_VF610)	+= gpio-vf610.o
diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
new file mode 100644
index 0000000..c82723f
--- /dev/null
+++ b/drivers/gpio/gpio-vf610.c
@@ -0,0 +1,181 @@
+/*
+ * vf610 GPIO support through PORT and GPIO module
+ *
+ * Copyright (c) 2014 Toradex AG.
+ *
+ * Author: Stefan Agner <stefan@agner.ch>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <io.h>
+#include <of.h>
+#include <gpio.h>
+#include <init.h>
+#include <pinctrl.h>
+
+#define VF610_GPIO_PER_PORT	32
+#define PINCTRL_BASE		2
+#define COUNT 3
+
+struct vf610_gpio_port {
+	struct gpio_chip chip;
+	void __iomem *gpio_base;
+	unsigned int pinctrl_base;
+};
+
+#define GPIO_PDOR		0x00
+#define GPIO_PSOR		0x04
+#define GPIO_PCOR		0x08
+#define GPIO_PTOR		0x0c
+#define GPIO_PDIR		0x10
+
+#define PORT_PCR(n)		((n) * 0x4)
+#define PORT_PCR_IRQC_OFFSET	16
+
+#define PORT_ISFR		0xa0
+#define PORT_DFER		0xc0
+#define PORT_DFCR		0xc4
+#define PORT_DFWR		0xc8
+
+#define PORT_INT_OFF		0x0
+#define PORT_INT_LOGIC_ZERO	0x8
+#define PORT_INT_RISING_EDGE	0x9
+#define PORT_INT_FALLING_EDGE	0xa
+#define PORT_INT_EITHER_EDGE	0xb
+#define PORT_INT_LOGIC_ONE	0xc
+
+static const struct of_device_id vf610_gpio_dt_ids[] = {
+	{ .compatible = "fsl,vf610-gpio" },
+	{ /* sentinel */ }
+};
+
+
+static int vf610_gpio_get_value(struct gpio_chip *chip, unsigned int gpio)
+{
+	struct vf610_gpio_port *port =
+		container_of(chip, struct vf610_gpio_port, chip);
+
+	return !!(readl(port->gpio_base + GPIO_PDIR) & BIT(gpio));
+}
+
+static void vf610_gpio_set_value(struct gpio_chip *chip,
+				  unsigned int gpio, int val)
+{
+	struct vf610_gpio_port *port =
+		container_of(chip, struct vf610_gpio_port, chip);
+	unsigned long mask = BIT(gpio);
+
+	writel(mask, port->gpio_base + ((val) ? GPIO_PSOR : GPIO_PCOR));
+}
+
+static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	struct vf610_gpio_port *port =
+		container_of(chip, struct vf610_gpio_port, chip);
+
+	return pinctrl_gpio_direction_input(port->pinctrl_base + gpio);
+}
+
+static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
+				       int value)
+{
+	struct vf610_gpio_port *port =
+		container_of(chip, struct vf610_gpio_port, chip);
+
+	vf610_gpio_set_value(chip, gpio, value);
+
+	return pinctrl_gpio_direction_output(port->pinctrl_base + gpio);
+}
+
+static int vf610_gpio_get_direction(struct gpio_chip *chip, unsigned gpio)
+{
+	struct vf610_gpio_port *port =
+		container_of(chip, struct vf610_gpio_port, chip);
+
+	return pinctrl_gpio_get_direction(port->pinctrl_base + gpio);
+}
+
+static struct gpio_ops vf610_gpio_ops = {
+	.direction_input = vf610_gpio_direction_input,
+	.direction_output = vf610_gpio_direction_output,
+	.get = vf610_gpio_get_value,
+	.set = vf610_gpio_set_value,
+	.get_direction = vf610_gpio_get_direction,
+};
+
+static int vf610_gpio_probe(struct device_d *dev)
+{
+	int ret, size;
+	struct resource *iores;
+	struct vf610_gpio_port *port;
+	const __be32 *gpio_ranges;
+
+	port = xzalloc(sizeof(*port));
+	if (!port)
+		return -ENOMEM;
+
+	gpio_ranges = of_get_property(dev->device_node, "gpio-ranges", &size);
+	if (!gpio_ranges) {
+		dev_err(dev, "Couldn't read 'gpio-ranges' propery of %s\n",
+			dev->device_node->full_name);
+		ret = -EINVAL;
+		goto free_port;
+	}
+
+	port->pinctrl_base = be32_to_cpu(gpio_ranges[PINCTRL_BASE]);
+	port->chip.ngpio   = be32_to_cpu(gpio_ranges[COUNT]);
+
+	iores = dev_request_mem_resource(dev, 1);
+	if (IS_ERR(iores)) {
+		ret = PTR_ERR(iores);
+		dev_dbg(dev, "Failed to request memory resource\n");
+		goto free_port;
+	}
+
+	port->gpio_base = IOMEM(iores->start);
+
+	port->chip.ops  = &vf610_gpio_ops;
+	if (dev->id < 0) {
+		port->chip.base = of_alias_get_id(dev->device_node, "gpio");
+		if (port->chip.base < 0) {
+			ret = port->chip.base;
+			dev_dbg(dev, "Failed to get GPIO alias\n");
+			goto free_port;
+		}
+	} else {
+		port->chip.base = dev->id;
+	}
+
+
+	port->chip.base *= VF610_GPIO_PER_PORT;
+	port->chip.dev = dev;
+	gpiochip_add(&port->chip);
+
+	return 0;
+
+free_port:
+	free(port);
+	return ret;
+}
+
+static struct driver_d vf610_gpio_driver = {
+	.name	= "gpio-vf610",
+	.probe  = vf610_gpio_probe,
+	.of_compatible = DRV_OF_COMPAT(vf610_gpio_dt_ids),
+};
+
+static int __init gpio_vf610_init(void)
+{
+	return platform_driver_register(&vf610_gpio_driver);
+}
+core_initcall(gpio_vf610_init);
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 00/28] Vybrid support in Barebox
  2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
                   ` (27 preceding siblings ...)
  2016-11-09 16:14 ` [PATCH v2 28/28] gpio: Add GPIO driver for Vybrid Andrey Smirnov
@ 2016-11-11  8:21 ` Sascha Hauer
  28 siblings, 0 replies; 31+ messages in thread
From: Sascha Hauer @ 2016-11-11  8:21 UTC (permalink / raw)
  To: Andrey Smirnov; +Cc: barebox

Hi Andrey,

On Wed, Nov 09, 2016 at 08:13:48AM -0800, Andrey Smirnov wrote:
> Hi everyone,
> 
> It took me a bit more than a month, but I finally put together a
> second version (for v1 see [1]) of the Vybrid support patchset.
> 
> Some highlights of this version:
> 
>      - Various code/commit arrangement feedback for v1 is addressed
>      - Added commit to move all of the i.MX clock code to drivers/clk
>        (Sascha, we'd probably have to coordinate with your i.MX6ul
>        patches on this one)
>      - I2C commit split in two
>      - clock tree is reconciled with Linux code, since having a custom
>        version of it proved to be difficult to compare agains Linux's
>        implementation
>      - GPIO driver (tested on a custom Vybrid board)
>      - FEC support (tested on a custom Vybrid board)
> 
> Any feedback is, as always, very much appreciated.

The series looks mostly good, but I won't find the time for a deeper
review anytime soon, so I decided to just give it a try in -next.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 09/28] clk: Port of_clk_set_defaults()
  2016-11-09 16:13 ` [PATCH v2 09/28] clk: Port of_clk_set_defaults() Andrey Smirnov
@ 2016-11-15  7:53   ` Sascha Hauer
  0 siblings, 0 replies; 31+ messages in thread
From: Sascha Hauer @ 2016-11-15  7:53 UTC (permalink / raw)
  To: Andrey Smirnov; +Cc: barebox

On Wed, Nov 09, 2016 at 08:13:57AM -0800, Andrey Smirnov wrote:
> Port of_clk_set_defautls() from Linux kernel in order to support DT
> configurations that require it (e. g. Vybrid).
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> ---
>  drivers/clk/Makefile         |   2 +-
>  drivers/clk/clk-conf.c       | 144 +++++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/clk.c            |   2 +
>  include/linux/clk/clk-conf.h |  14 +++++
>  4 files changed, 161 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/clk-conf.c
>  create mode 100644 include/linux/clk/clk-conf.h

This patch breaks compilation on platforms using common clk but no
device tree, for example cupid_defconfig:

drivers/clk/clk-conf.c: In function '__set_clk_parents':
drivers/clk/clk-conf.c:41:3: error: implicit declaration of function 'of_clk_get_from_provider' [-Werror=implicit-function-declaration]

As this is not trivial to fix I dropped the rest of this series for now.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2016-11-15  7:54 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-09 16:13 [PATCH v2 00/28] Vybrid support in Barebox Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 01/28] i.MX: Add primitive functions for VF610 family Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 02/28] i.MX: Add register definitions for VF610 SoC Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 03/28] i.MX: Add DEBUG_LL hooks for VF610 Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 04/28] i.MX: scripts: Add "vf610" soc to imx-image Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 05/28] i.MX: Add support for VF610 Tower board Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 06/28] pinctrl: Add provisions to control GPIO pin direction Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 07/28] i.MX: Add pinctrl driver for VF610 Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 08/28] clk: Port clock dependency resolution code Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 09/28] clk: Port of_clk_set_defaults() Andrey Smirnov
2016-11-15  7:53   ` Sascha Hauer
2016-11-09 16:13 ` [PATCH v2 10/28] i.MX: Move clk code from 'mach-imx' to 'drivers' Andrey Smirnov
2016-11-09 16:13 ` [PATCH v2 11/28] i.MX: clk: Port imx_clk_gate2_cgr() Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 12/28] i.MX: clk: Add IMX_PLLV3_USB_VF610 support Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 13/28] i.MX: clk: Port imx_check_clocks() Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 14/28] i.MX: clk: Port imx_clk_mux_flags from Linux Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 15/28] i.MX: Add VF610 clock tree initialization code Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 16/28] vf610: Give enet_osc explicit "enet_ext" name Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 17/28] i.MX: Add 'lpuart' serial driver Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 18/28] i.MX: i2c: Use read/write adapter functions Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 19/28] i.MX: i2c: Add Vybrid support Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 20/28] i.MX: esdhc: Do not rely on CPU type for quirks Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 21/28] i.MX: esdhc: Request "per" clock explicitly Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 22/28] i.MX: Kconfig: Enable OCOTP on Vybrid Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 23/28] i.MX: ocotp: Remove unused #define Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 24/28] i.MX: ocotp: Account for shadow memory gaps Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 25/28] i.MX: ocotp: Add Vybrid support Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 26/28] i.MX: fec: Enable all clocks specified for FEC Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 27/28] i.MX: fec: Add support for Vybrid variant Andrey Smirnov
2016-11-09 16:14 ` [PATCH v2 28/28] gpio: Add GPIO driver for Vybrid Andrey Smirnov
2016-11-11  8:21 ` [PATCH v2 00/28] Vybrid support in Barebox Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox