All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 00/11] clk: imx: add imx8qxp clock support
@ 2018-09-25 16:43 ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

This patch series adds i.MX8QXP clock support which is based
on the clock service provided by SCU firmware.
It depends on SCU driver.

Dong Aisheng (11):
  clk: imx: add configuration option for mmio clks
  clk: imx: scu: add scu clock common part
  clk: imx: scu: add scu clock divider
  clk: imx: scu: add scu clock gpr divider
  clk: imx: scu: add scu clock gate
  clk: imx: scu: add scu clock gpr gate
  clk: imx: scu: add scu clock mux
  clk: imx: scu: add scu clock gpr mux
  clk: imx: add common imx_clk_hw_fixed functions
  clk: imx: add imx_check_clk_hws helper function
  clk: imx: add imx8qxp clk driver

 arch/arm/mach-imx/Kconfig                 |  11 +
 drivers/clk/Kconfig                       |   1 +
 drivers/clk/imx/Kconfig                   |   7 +
 drivers/clk/imx/Makefile                  |   4 +-
 drivers/clk/imx/clk-common.h              |  27 ++
 drivers/clk/imx/scu/Kconfig               |   5 +
 drivers/clk/imx/scu/Makefile              |  12 +
 drivers/clk/imx/scu/clk-divider-gpr-scu.c | 131 +++++++++
 drivers/clk/imx/scu/clk-divider-scu.c     | 190 +++++++++++++
 drivers/clk/imx/scu/clk-gate-gpr-scu.c    |  84 ++++++
 drivers/clk/imx/scu/clk-gate-scu.c        | 230 ++++++++++++++++
 drivers/clk/imx/scu/clk-imx8qxp.c         | 426 ++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-mux-gpr-scu.c     |  90 +++++++
 drivers/clk/imx/scu/clk-mux-scu.c         | 142 ++++++++++
 drivers/clk/imx/scu/clk-scu.c             |  17 ++
 drivers/clk/imx/scu/clk-scu.h             |  97 +++++++
 include/soc/imx/imx8qxp/lpcg.h            | 186 +++++++++++++
 17 files changed, 1659 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/Kconfig
 create mode 100644 drivers/clk/imx/clk-common.h
 create mode 100644 drivers/clk/imx/scu/Kconfig
 create mode 100644 drivers/clk/imx/scu/Makefile
 create mode 100644 drivers/clk/imx/scu/clk-divider-gpr-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-divider-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-gate-gpr-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-gate-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-imx8qxp.c
 create mode 100644 drivers/clk/imx/scu/clk-mux-gpr-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-mux-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-scu.h
 create mode 100644 include/soc/imx/imx8qxp/lpcg.h

-- 
2.7.4

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

* [PATCH V2 00/11] clk: imx: add imx8qxp clock support
@ 2018-09-25 16:43 ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series adds i.MX8QXP clock support which is based
on the clock service provided by SCU firmware.
It depends on SCU driver.

Dong Aisheng (11):
  clk: imx: add configuration option for mmio clks
  clk: imx: scu: add scu clock common part
  clk: imx: scu: add scu clock divider
  clk: imx: scu: add scu clock gpr divider
  clk: imx: scu: add scu clock gate
  clk: imx: scu: add scu clock gpr gate
  clk: imx: scu: add scu clock mux
  clk: imx: scu: add scu clock gpr mux
  clk: imx: add common imx_clk_hw_fixed functions
  clk: imx: add imx_check_clk_hws helper function
  clk: imx: add imx8qxp clk driver

 arch/arm/mach-imx/Kconfig                 |  11 +
 drivers/clk/Kconfig                       |   1 +
 drivers/clk/imx/Kconfig                   |   7 +
 drivers/clk/imx/Makefile                  |   4 +-
 drivers/clk/imx/clk-common.h              |  27 ++
 drivers/clk/imx/scu/Kconfig               |   5 +
 drivers/clk/imx/scu/Makefile              |  12 +
 drivers/clk/imx/scu/clk-divider-gpr-scu.c | 131 +++++++++
 drivers/clk/imx/scu/clk-divider-scu.c     | 190 +++++++++++++
 drivers/clk/imx/scu/clk-gate-gpr-scu.c    |  84 ++++++
 drivers/clk/imx/scu/clk-gate-scu.c        | 230 ++++++++++++++++
 drivers/clk/imx/scu/clk-imx8qxp.c         | 426 ++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-mux-gpr-scu.c     |  90 +++++++
 drivers/clk/imx/scu/clk-mux-scu.c         | 142 ++++++++++
 drivers/clk/imx/scu/clk-scu.c             |  17 ++
 drivers/clk/imx/scu/clk-scu.h             |  97 +++++++
 include/soc/imx/imx8qxp/lpcg.h            | 186 +++++++++++++
 17 files changed, 1659 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/Kconfig
 create mode 100644 drivers/clk/imx/clk-common.h
 create mode 100644 drivers/clk/imx/scu/Kconfig
 create mode 100644 drivers/clk/imx/scu/Makefile
 create mode 100644 drivers/clk/imx/scu/clk-divider-gpr-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-divider-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-gate-gpr-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-gate-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-imx8qxp.c
 create mode 100644 drivers/clk/imx/scu/clk-mux-gpr-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-mux-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-scu.h
 create mode 100644 include/soc/imx/imx8qxp/lpcg.h

-- 
2.7.4

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

* [PATCH V2 01/11] clk: imx: add configuration option for mmio clks
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

The patch introduces CONFIG_MXC_CLK option for legacy MMIO clocks,
this is required to compile legacy MMIO clock conditionally when adding
SCU based clocks for MX8 platforms later.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 arch/arm/mach-imx/Kconfig | 11 +++++++++++
 drivers/clk/Kconfig       |  1 +
 drivers/clk/imx/Kconfig   |  5 +++++
 drivers/clk/imx/Makefile  |  2 +-
 4 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/Kconfig

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index abc3371..11a9661 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -57,23 +57,27 @@ config SOC_IMX21
 	select CPU_ARM926T
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
+	select MXC_CLK
 
 config SOC_IMX27
 	bool
 	select CPU_ARM926T
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
+	select MXC_CLK
 	select PINCTRL_IMX27
 
 config SOC_IMX31
 	bool
 	select CPU_V6
 	select MXC_AVIC
+	select MXC_CLK
 
 config SOC_IMX35
 	bool
 	select ARCH_MXC_IOMUX_V3
 	select MXC_AVIC
+	select MXC_CLK
 	select PINCTRL_IMX35
 
 if ARCH_MULTI_V5
@@ -417,6 +421,7 @@ config SOC_IMX1
 	bool "i.MX1 support"
 	select CPU_ARM920T
 	select MXC_AVIC
+	select MXC_CLK
 	select PINCTRL_IMX1
 	help
 	  This enables support for Freescale i.MX1 processor
@@ -430,6 +435,7 @@ config SOC_IMX25
 	select ARCH_MXC_IOMUX_V3
 	select CPU_ARM926T
 	select MXC_AVIC
+	select MXC_CLK
 	select PINCTRL_IMX25
 	help
 	  This enables support for Freescale i.MX25 processor
@@ -442,6 +448,7 @@ comment "Cortex-A platforms"
 config SOC_IMX5
 	bool
 	select HAVE_IMX_SRC
+	select MXC_CLK
 	select MXC_TZIC
 
 config	SOC_IMX50
@@ -478,6 +485,7 @@ config SOC_IMX6
 	select HAVE_IMX_MMDC
 	select HAVE_IMX_SRC
 	select MFD_SYSCON
+	select MXC_CLK
 	select PL310_ERRATA_769419 if CACHE_L2X0
 
 config SOC_IMX6Q
@@ -545,10 +553,12 @@ config SOC_IMX7D_CA7
 	select HAVE_IMX_MMDC
 	select HAVE_IMX_SRC
 	select IMX_GPCV2
+	select MXC_CLK
 
 config SOC_IMX7D_CM4
 	bool
 	select ARMV7M_SYSTICK
+	select MXC_CLK
 
 config SOC_IMX7D
 	bool "i.MX7 Dual support"
@@ -561,6 +571,7 @@ config SOC_IMX7D
 config SOC_VF610
 	bool "Vybrid Family VF610 support"
 	select ARM_GIC if ARCH_MULTI_V7
+	select MXC_CLK
 	select PINCTRL_VF610
 
 	help
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 721572a..c4886be 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -281,6 +281,7 @@ source "drivers/clk/actions/Kconfig"
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/imgtec/Kconfig"
+source "drivers/clk/imx/Kconfig"
 source "drivers/clk/keystone/Kconfig"
 source "drivers/clk/mediatek/Kconfig"
 source "drivers/clk/meson/Kconfig"
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
new file mode 100644
index 0000000..43a3ecc
--- /dev/null
+++ b/drivers/clk/imx/Kconfig
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+# common clock support for NXP i.MX SoC family.
+config MXC_CLK
+	bool
+	depends on ARCH_MXC
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 8c3baa7..d447f8c 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-y += \
+obj-$(CONFIG_MXC_CLK) += \
 	clk.o \
 	clk-busy.o \
 	clk-cpu.o \
-- 
2.7.4

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

* [PATCH V2 01/11] clk: imx: add configuration option for mmio clks
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

The patch introduces CONFIG_MXC_CLK option for legacy MMIO clocks,
this is required to compile legacy MMIO clock conditionally when adding
SCU based clocks for MX8 platforms later.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 arch/arm/mach-imx/Kconfig | 11 +++++++++++
 drivers/clk/Kconfig       |  1 +
 drivers/clk/imx/Kconfig   |  5 +++++
 drivers/clk/imx/Makefile  |  2 +-
 4 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/Kconfig

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index abc3371..11a9661 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -57,23 +57,27 @@ config SOC_IMX21
 	select CPU_ARM926T
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
+	select MXC_CLK
 
 config SOC_IMX27
 	bool
 	select CPU_ARM926T
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
+	select MXC_CLK
 	select PINCTRL_IMX27
 
 config SOC_IMX31
 	bool
 	select CPU_V6
 	select MXC_AVIC
+	select MXC_CLK
 
 config SOC_IMX35
 	bool
 	select ARCH_MXC_IOMUX_V3
 	select MXC_AVIC
+	select MXC_CLK
 	select PINCTRL_IMX35
 
 if ARCH_MULTI_V5
@@ -417,6 +421,7 @@ config SOC_IMX1
 	bool "i.MX1 support"
 	select CPU_ARM920T
 	select MXC_AVIC
+	select MXC_CLK
 	select PINCTRL_IMX1
 	help
 	  This enables support for Freescale i.MX1 processor
@@ -430,6 +435,7 @@ config SOC_IMX25
 	select ARCH_MXC_IOMUX_V3
 	select CPU_ARM926T
 	select MXC_AVIC
+	select MXC_CLK
 	select PINCTRL_IMX25
 	help
 	  This enables support for Freescale i.MX25 processor
@@ -442,6 +448,7 @@ comment "Cortex-A platforms"
 config SOC_IMX5
 	bool
 	select HAVE_IMX_SRC
+	select MXC_CLK
 	select MXC_TZIC
 
 config	SOC_IMX50
@@ -478,6 +485,7 @@ config SOC_IMX6
 	select HAVE_IMX_MMDC
 	select HAVE_IMX_SRC
 	select MFD_SYSCON
+	select MXC_CLK
 	select PL310_ERRATA_769419 if CACHE_L2X0
 
 config SOC_IMX6Q
@@ -545,10 +553,12 @@ config SOC_IMX7D_CA7
 	select HAVE_IMX_MMDC
 	select HAVE_IMX_SRC
 	select IMX_GPCV2
+	select MXC_CLK
 
 config SOC_IMX7D_CM4
 	bool
 	select ARMV7M_SYSTICK
+	select MXC_CLK
 
 config SOC_IMX7D
 	bool "i.MX7 Dual support"
@@ -561,6 +571,7 @@ config SOC_IMX7D
 config SOC_VF610
 	bool "Vybrid Family VF610 support"
 	select ARM_GIC if ARCH_MULTI_V7
+	select MXC_CLK
 	select PINCTRL_VF610
 
 	help
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 721572a..c4886be 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -281,6 +281,7 @@ source "drivers/clk/actions/Kconfig"
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/imgtec/Kconfig"
+source "drivers/clk/imx/Kconfig"
 source "drivers/clk/keystone/Kconfig"
 source "drivers/clk/mediatek/Kconfig"
 source "drivers/clk/meson/Kconfig"
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
new file mode 100644
index 0000000..43a3ecc
--- /dev/null
+++ b/drivers/clk/imx/Kconfig
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+# common clock support for NXP i.MX SoC family.
+config MXC_CLK
+	bool
+	depends on ARCH_MXC
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 8c3baa7..d447f8c 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-y += \
+obj-$(CONFIG_MXC_CLK) += \
 	clk.o \
 	clk-busy.o \
 	clk-cpu.o \
-- 
2.7.4

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

* [PATCH V2 02/11] clk: imx: scu: add scu clock common part
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add scu clock common part which will be used by client clock drivers.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2:
 * update function call name
---
 drivers/clk/imx/Kconfig       |  2 ++
 drivers/clk/imx/Makefile      |  2 ++
 drivers/clk/imx/scu/Kconfig   |  5 +++++
 drivers/clk/imx/scu/Makefile  |  4 ++++
 drivers/clk/imx/scu/clk-scu.c | 17 +++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h | 18 ++++++++++++++++++
 6 files changed, 48 insertions(+)
 create mode 100644 drivers/clk/imx/scu/Kconfig
 create mode 100644 drivers/clk/imx/scu/Makefile
 create mode 100644 drivers/clk/imx/scu/clk-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-scu.h

diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 43a3ecc..b1599bf 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -3,3 +3,5 @@
 config MXC_CLK
 	bool
 	depends on ARCH_MXC
+
+source drivers/clk/imx/scu/Kconfig
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index d447f8c..79b641a 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_MXC_CLK) += \
 	clk-pllv3.o \
 	clk-pfd.o
 
+obj-y += scu/
+
 obj-$(CONFIG_SOC_IMX1)   += clk-imx1.o
 obj-$(CONFIG_SOC_IMX21)  += clk-imx21.o
 obj-$(CONFIG_SOC_IMX25)  += clk-imx25.o
diff --git a/drivers/clk/imx/scu/Kconfig b/drivers/clk/imx/scu/Kconfig
new file mode 100644
index 0000000..4d018fd
--- /dev/null
+++ b/drivers/clk/imx/scu/Kconfig
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+# SCU based common clock support for NXP i.MX SoC family.
+config MXC_CLK_SCU
+	bool
+	depends on ARCH_MXC && ARM64
diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
new file mode 100644
index 0000000..7dead13
--- /dev/null
+++ b/drivers/clk/imx/scu/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_MXC_CLK_SCU) += \
+	clk-scu.o
diff --git a/drivers/clk/imx/scu/clk-scu.c b/drivers/clk/imx/scu/clk-scu.c
new file mode 100644
index 0000000..4c253a5
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-scu.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/errno.h>
+#include "clk-scu.h"
+
+DEFINE_SPINLOCK(imx_ccm_lock);
+struct sc_ipc *ccm_ipc_handle;
+
+int imx_clk_scu_init(void)
+{
+	return imx_scu_get_handle(&ccm_ipc_handle);
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
new file mode 100644
index 0000000..c503a52
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ */
+
+#ifndef __IMX_CLK_SCU_H
+#define __IMX_CLK_SCU_H
+
+#include <linux/spinlock.h>
+#include <soc/imx/scu/sci.h>
+
+extern spinlock_t imx_ccm_lock;
+extern struct sc_ipc *ccm_ipc_handle;
+
+int imx_clk_scu_init(void);
+
+#endif
-- 
2.7.4

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

* [PATCH V2 02/11] clk: imx: scu: add scu clock common part
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Add scu clock common part which will be used by client clock drivers.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2:
 * update function call name
---
 drivers/clk/imx/Kconfig       |  2 ++
 drivers/clk/imx/Makefile      |  2 ++
 drivers/clk/imx/scu/Kconfig   |  5 +++++
 drivers/clk/imx/scu/Makefile  |  4 ++++
 drivers/clk/imx/scu/clk-scu.c | 17 +++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h | 18 ++++++++++++++++++
 6 files changed, 48 insertions(+)
 create mode 100644 drivers/clk/imx/scu/Kconfig
 create mode 100644 drivers/clk/imx/scu/Makefile
 create mode 100644 drivers/clk/imx/scu/clk-scu.c
 create mode 100644 drivers/clk/imx/scu/clk-scu.h

diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 43a3ecc..b1599bf 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -3,3 +3,5 @@
 config MXC_CLK
 	bool
 	depends on ARCH_MXC
+
+source drivers/clk/imx/scu/Kconfig
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index d447f8c..79b641a 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_MXC_CLK) += \
 	clk-pllv3.o \
 	clk-pfd.o
 
+obj-y += scu/
+
 obj-$(CONFIG_SOC_IMX1)   += clk-imx1.o
 obj-$(CONFIG_SOC_IMX21)  += clk-imx21.o
 obj-$(CONFIG_SOC_IMX25)  += clk-imx25.o
diff --git a/drivers/clk/imx/scu/Kconfig b/drivers/clk/imx/scu/Kconfig
new file mode 100644
index 0000000..4d018fd
--- /dev/null
+++ b/drivers/clk/imx/scu/Kconfig
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+# SCU based common clock support for NXP i.MX SoC family.
+config MXC_CLK_SCU
+	bool
+	depends on ARCH_MXC && ARM64
diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
new file mode 100644
index 0000000..7dead13
--- /dev/null
+++ b/drivers/clk/imx/scu/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_MXC_CLK_SCU) += \
+	clk-scu.o
diff --git a/drivers/clk/imx/scu/clk-scu.c b/drivers/clk/imx/scu/clk-scu.c
new file mode 100644
index 0000000..4c253a5
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-scu.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/errno.h>
+#include "clk-scu.h"
+
+DEFINE_SPINLOCK(imx_ccm_lock);
+struct sc_ipc *ccm_ipc_handle;
+
+int imx_clk_scu_init(void)
+{
+	return imx_scu_get_handle(&ccm_ipc_handle);
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
new file mode 100644
index 0000000..c503a52
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ */
+
+#ifndef __IMX_CLK_SCU_H
+#define __IMX_CLK_SCU_H
+
+#include <linux/spinlock.h>
+#include <soc/imx/scu/sci.h>
+
+extern spinlock_t imx_ccm_lock;
+extern struct sc_ipc *ccm_ipc_handle;
+
+int imx_clk_scu_init(void);
+
+#endif
-- 
2.7.4

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

* [PATCH V2 03/11] clk: imx: scu: add scu clock divider
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add scu based clock divider.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2:
 * move SCU clock API implementation into driver
---
 drivers/clk/imx/scu/Makefile          |   3 +-
 drivers/clk/imx/scu/clk-divider-scu.c | 190 ++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h         |  18 ++++
 3 files changed, 210 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-divider-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 7dead13..7e360e2 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_MXC_CLK_SCU) += \
-	clk-scu.o
+	clk-scu.o \
+	clk-divider-scu.o
diff --git a/drivers/clk/imx/scu/clk-divider-scu.c b/drivers/clk/imx/scu/clk-divider-scu.c
new file mode 100644
index 0000000..9da75ae
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-divider-scu.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ *
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_divider_scu {
+	struct clk_hw	hw;
+	sc_rsrc_t	rsrc_id;
+	uint8_t	clk_type;
+};
+
+/* SCU Clock Protocol definitions */
+struct imx_sc_msg_req_set_clock_rate {
+	struct sc_rpc_msg hdr;
+	u32 rate;
+	u16 resource;
+	u8 clk;
+} __packed;
+
+struct imx_sc_msg_req_get_clock_rate {
+	struct sc_rpc_msg hdr;
+	u16 resource;
+	u8 clk;
+} __packed;
+
+struct imx_sc_msg_resp_get_clock_rate {
+	struct sc_rpc_msg hdr;
+	u32 rate;
+} __packed;
+
+
+static inline struct clk_divider_scu *to_clk_divider_scu(struct clk_hw *hw)
+{
+	return container_of(hw, struct clk_divider_scu, hw);
+}
+
+/*
+ * clk_divider_scu_recalc_rate - Get clock rate for a SCU clock
+ * @hw: clock to get rate for
+ * @parent_rate: parent rate provided by common clock framework, not used
+ *
+ * Gets the current clock rate of a SCU clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static unsigned long clk_divider_scu_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct clk_divider_scu *div = to_clk_divider_scu(hw);
+	struct imx_sc_msg_req_get_clock_rate msg;
+	struct imx_sc_msg_resp_get_clock_rate *resp;
+	struct sc_rpc_msg *hdr = &msg.hdr;
+	sc_err_t sci_err;
+	int ret;
+
+	hdr->ver = SC_RPC_VERSION;
+	hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+	hdr->func = (uint8_t)PM_FUNC_GET_CLOCK_RATE;
+	hdr->size = 2;
+
+	msg.resource = div->rsrc_id;
+	msg.clk = div->clk_type;
+
+	ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+	if (ret)
+		return ret;
+
+	resp = (struct imx_sc_msg_resp_get_clock_rate *)&msg;
+	sci_err = (sc_err_t)resp->hdr.func;
+	if (sci_err) {
+		pr_err("%s: failed to get clock rate %d\n",
+			clk_hw_get_name(hw), ret);
+		return 0;
+	}
+
+	return resp->rate;
+}
+
+/*
+ * clk_divider_scu_round_rate - Round clock rate for a SCU clock
+ * @hw: clock to round rate for
+ * @rate: rate to round
+ * @parent_rate: parent rate provided by common clock framework, not used
+ *
+ * Gets the current clock rate of a SCU clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static long clk_divider_scu_round_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long *parent_rate)
+{
+	/*
+	 * Assume we support all the requested rate and let the SCU firmware
+	 * to handle the left work
+	 */
+	return rate;
+}
+
+/*
+ * clk_divider_scu_set_rate - Set rate for a SCU clock
+ * @hw: clock to change rate for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the clock parent, not used for SCU clocks
+ *
+ * Sets a clock frequency for a SCU clock. Returns the SCU
+ * protocol status.
+ */
+static int clk_divider_scu_set_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long parent_rate)
+{
+	struct clk_divider_scu *div = to_clk_divider_scu(hw);
+	struct imx_sc_msg_req_set_clock_rate msg;
+	struct imx_sc_msg_resp_get_clock_rate *resp;
+	struct sc_rpc_msg *hdr = &msg.hdr;
+	sc_err_t sci_err;
+	int ret;
+
+	hdr->ver = SC_RPC_VERSION;
+	hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+	hdr->func = (uint8_t)PM_FUNC_SET_CLOCK_RATE;
+	hdr->size = 3;
+
+	msg.rate = rate;
+	msg.resource = div->rsrc_id;
+	msg.clk = div->clk_type;
+
+	ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+	if (ret)
+		return ret;
+
+	resp = (struct imx_sc_msg_resp_get_clock_rate *)&msg;
+	sci_err = (sc_err_t)resp->hdr.func;
+	if (sci_err) {
+		pr_err("%s: failed to set clock rate %ld : ret %d\n",
+			clk_hw_get_name(hw), rate, sci_err);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct clk_ops clk_divider_scu_ops = {
+	.recalc_rate = clk_divider_scu_recalc_rate,
+	.round_rate = clk_divider_scu_round_rate,
+	.set_rate = clk_divider_scu_set_rate,
+};
+
+struct clk_hw *imx_clk_register_divider_scu(const char *name,
+					    const char *parent_name,
+					    sc_rsrc_t rsrc_id,
+					    uint8_t clk_type)
+{
+	struct clk_divider_scu *div;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	div->rsrc_id = rsrc_id;
+	div->clk_type = clk_type;
+
+	init.name = name;
+	init.ops = &clk_divider_scu_ops;
+	init.flags = CLK_GET_RATE_NOCACHE;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+	div->hw.init = &init;
+
+	hw = &div->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(div);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index c503a52..c433cd4 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -7,6 +7,7 @@
 #ifndef __IMX_CLK_SCU_H
 #define __IMX_CLK_SCU_H
 
+#include <linux/clk-provider.h>
 #include <linux/spinlock.h>
 #include <soc/imx/scu/sci.h>
 
@@ -15,4 +16,21 @@ extern struct sc_ipc *ccm_ipc_handle;
 
 int imx_clk_scu_init(void);
 
+struct clk_hw *imx_clk_register_divider_scu(const char *name,
+				const char *parent_name, sc_rsrc_t rsrc_id,
+				uint8_t clk_type);
+
+static inline struct clk_hw *imx_clk_divider_scu(const char *name,
+				sc_rsrc_t rsrc_id, uint8_t clk_type)
+{
+	return imx_clk_register_divider_scu(name, NULL, rsrc_id, clk_type);
+}
+
+static inline struct clk_hw *imx_clk_divider2_scu(const char *name,
+				const char *parent_name,
+				sc_rsrc_t rsrc_id, uint8_t clk_type)
+{
+	return imx_clk_register_divider_scu(name, parent_name, rsrc_id, clk_type);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 03/11] clk: imx: scu: add scu clock divider
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Add scu based clock divider.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2:
 * move SCU clock API implementation into driver
---
 drivers/clk/imx/scu/Makefile          |   3 +-
 drivers/clk/imx/scu/clk-divider-scu.c | 190 ++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h         |  18 ++++
 3 files changed, 210 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-divider-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 7dead13..7e360e2 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_MXC_CLK_SCU) += \
-	clk-scu.o
+	clk-scu.o \
+	clk-divider-scu.o
diff --git a/drivers/clk/imx/scu/clk-divider-scu.c b/drivers/clk/imx/scu/clk-divider-scu.c
new file mode 100644
index 0000000..9da75ae
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-divider-scu.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ *
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_divider_scu {
+	struct clk_hw	hw;
+	sc_rsrc_t	rsrc_id;
+	uint8_t	clk_type;
+};
+
+/* SCU Clock Protocol definitions */
+struct imx_sc_msg_req_set_clock_rate {
+	struct sc_rpc_msg hdr;
+	u32 rate;
+	u16 resource;
+	u8 clk;
+} __packed;
+
+struct imx_sc_msg_req_get_clock_rate {
+	struct sc_rpc_msg hdr;
+	u16 resource;
+	u8 clk;
+} __packed;
+
+struct imx_sc_msg_resp_get_clock_rate {
+	struct sc_rpc_msg hdr;
+	u32 rate;
+} __packed;
+
+
+static inline struct clk_divider_scu *to_clk_divider_scu(struct clk_hw *hw)
+{
+	return container_of(hw, struct clk_divider_scu, hw);
+}
+
+/*
+ * clk_divider_scu_recalc_rate - Get clock rate for a SCU clock
+ * @hw: clock to get rate for
+ * @parent_rate: parent rate provided by common clock framework, not used
+ *
+ * Gets the current clock rate of a SCU clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static unsigned long clk_divider_scu_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct clk_divider_scu *div = to_clk_divider_scu(hw);
+	struct imx_sc_msg_req_get_clock_rate msg;
+	struct imx_sc_msg_resp_get_clock_rate *resp;
+	struct sc_rpc_msg *hdr = &msg.hdr;
+	sc_err_t sci_err;
+	int ret;
+
+	hdr->ver = SC_RPC_VERSION;
+	hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+	hdr->func = (uint8_t)PM_FUNC_GET_CLOCK_RATE;
+	hdr->size = 2;
+
+	msg.resource = div->rsrc_id;
+	msg.clk = div->clk_type;
+
+	ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+	if (ret)
+		return ret;
+
+	resp = (struct imx_sc_msg_resp_get_clock_rate *)&msg;
+	sci_err = (sc_err_t)resp->hdr.func;
+	if (sci_err) {
+		pr_err("%s: failed to get clock rate %d\n",
+			clk_hw_get_name(hw), ret);
+		return 0;
+	}
+
+	return resp->rate;
+}
+
+/*
+ * clk_divider_scu_round_rate - Round clock rate for a SCU clock
+ * @hw: clock to round rate for
+ * @rate: rate to round
+ * @parent_rate: parent rate provided by common clock framework, not used
+ *
+ * Gets the current clock rate of a SCU clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static long clk_divider_scu_round_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long *parent_rate)
+{
+	/*
+	 * Assume we support all the requested rate and let the SCU firmware
+	 * to handle the left work
+	 */
+	return rate;
+}
+
+/*
+ * clk_divider_scu_set_rate - Set rate for a SCU clock
+ * @hw: clock to change rate for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the clock parent, not used for SCU clocks
+ *
+ * Sets a clock frequency for a SCU clock. Returns the SCU
+ * protocol status.
+ */
+static int clk_divider_scu_set_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long parent_rate)
+{
+	struct clk_divider_scu *div = to_clk_divider_scu(hw);
+	struct imx_sc_msg_req_set_clock_rate msg;
+	struct imx_sc_msg_resp_get_clock_rate *resp;
+	struct sc_rpc_msg *hdr = &msg.hdr;
+	sc_err_t sci_err;
+	int ret;
+
+	hdr->ver = SC_RPC_VERSION;
+	hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+	hdr->func = (uint8_t)PM_FUNC_SET_CLOCK_RATE;
+	hdr->size = 3;
+
+	msg.rate = rate;
+	msg.resource = div->rsrc_id;
+	msg.clk = div->clk_type;
+
+	ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+	if (ret)
+		return ret;
+
+	resp = (struct imx_sc_msg_resp_get_clock_rate *)&msg;
+	sci_err = (sc_err_t)resp->hdr.func;
+	if (sci_err) {
+		pr_err("%s: failed to set clock rate %ld : ret %d\n",
+			clk_hw_get_name(hw), rate, sci_err);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct clk_ops clk_divider_scu_ops = {
+	.recalc_rate = clk_divider_scu_recalc_rate,
+	.round_rate = clk_divider_scu_round_rate,
+	.set_rate = clk_divider_scu_set_rate,
+};
+
+struct clk_hw *imx_clk_register_divider_scu(const char *name,
+					    const char *parent_name,
+					    sc_rsrc_t rsrc_id,
+					    uint8_t clk_type)
+{
+	struct clk_divider_scu *div;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	div->rsrc_id = rsrc_id;
+	div->clk_type = clk_type;
+
+	init.name = name;
+	init.ops = &clk_divider_scu_ops;
+	init.flags = CLK_GET_RATE_NOCACHE;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+	div->hw.init = &init;
+
+	hw = &div->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(div);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index c503a52..c433cd4 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -7,6 +7,7 @@
 #ifndef __IMX_CLK_SCU_H
 #define __IMX_CLK_SCU_H
 
+#include <linux/clk-provider.h>
 #include <linux/spinlock.h>
 #include <soc/imx/scu/sci.h>
 
@@ -15,4 +16,21 @@ extern struct sc_ipc *ccm_ipc_handle;
 
 int imx_clk_scu_init(void);
 
+struct clk_hw *imx_clk_register_divider_scu(const char *name,
+				const char *parent_name, sc_rsrc_t rsrc_id,
+				uint8_t clk_type);
+
+static inline struct clk_hw *imx_clk_divider_scu(const char *name,
+				sc_rsrc_t rsrc_id, uint8_t clk_type)
+{
+	return imx_clk_register_divider_scu(name, NULL, rsrc_id, clk_type);
+}
+
+static inline struct clk_hw *imx_clk_divider2_scu(const char *name,
+				const char *parent_name,
+				sc_rsrc_t rsrc_id, uint8_t clk_type)
+{
+	return imx_clk_register_divider_scu(name, parent_name, rsrc_id, clk_type);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 04/11] clk: imx: scu: add scu clock gpr divider
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add scu based clock gpr divider. Unlike the normal scu divider, such
dividers are controlled by GPR bits through SCU sc_misc_set_control
API.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2: no changes except update headfile name
---
 drivers/clk/imx/scu/Makefile              |   3 +-
 drivers/clk/imx/scu/clk-divider-gpr-scu.c | 131 ++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h             |   3 +
 3 files changed, 136 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-divider-gpr-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 7e360e2..9e7f4aa 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -2,4 +2,5 @@
 
 obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-scu.o \
-	clk-divider-scu.o
+	clk-divider-scu.o \
+	clk-divider-gpr-scu.o
diff --git a/drivers/clk/imx/scu/clk-divider-gpr-scu.c b/drivers/clk/imx/scu/clk-divider-gpr-scu.c
new file mode 100644
index 0000000..14deb7a
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-divider-gpr-scu.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_divider_gpr_scu {
+	struct clk_hw	hw;
+	sc_rsrc_t	rsrc_id;
+	sc_ctrl_t	gpr_id;
+};
+
+static inline struct clk_divider_gpr_scu *to_clk_divider_gpr_scu(struct clk_hw *hw)
+{
+	return container_of(hw, struct clk_divider_gpr_scu, hw);
+}
+
+/*
+ * clk_divider_scu_recalc_rate - Get clock rate for a SCU clock
+ * @hw: clock to get rate for
+ * @parent_rate: parent rate provided by common clock framework
+ *
+ * Gets the current clock rate of a SCU clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static unsigned long clk_divider_gpr_scu_recalc_rate(struct clk_hw *hw,
+						     unsigned long parent_rate)
+{
+	struct clk_divider_gpr_scu *clk = to_clk_divider_gpr_scu(hw);
+	uint32_t rate = 0;
+	sc_err_t sci_err;
+	uint32_t val;
+
+	sci_err = sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id,
+				      clk->gpr_id, &val);
+
+	rate  = val ? parent_rate / 2 : parent_rate;
+
+	return sci_err ? 0 : rate;
+}
+
+/*
+ * clk_divider_scu_round_rate - Round clock rate for a SCU clock
+ * @hw: clock to round rate for
+ * @rate: rate to round
+ * @parent_rate: parent rate provided by common clock framework
+ *
+ * Gets the current clock rate of a SCU clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static long clk_divider_gpr_scu_round_rate(struct clk_hw *hw, unsigned long rate,
+					   unsigned long *prate)
+{
+	if (rate < *prate)
+		rate = *prate / 2;
+	else
+		rate = *prate;
+
+	return rate;
+}
+
+/*
+ * clk_divider_scu_set_rate - Set rate for a SCU clock
+ * @hw: clock to change rate for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the clock parent
+ *
+ * Sets a clock frequency for a SCU clock. Returns the SCU
+ * protocol status.
+ */
+static int clk_divider_gpr_scu_set_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct clk_divider_gpr_scu *clk = to_clk_divider_gpr_scu(hw);
+	uint32_t val;
+	sc_err_t sci_err;
+
+	val = (rate < parent_rate) ? 1 : 0;
+	sci_err = sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id,
+		clk->gpr_id, val);
+
+	return sci_err ? -EINVAL : 0;
+}
+
+static struct clk_ops clk_divider_gpr_scu_ops = {
+	.recalc_rate = clk_divider_gpr_scu_recalc_rate,
+	.round_rate = clk_divider_gpr_scu_round_rate,
+	.set_rate = clk_divider_gpr_scu_set_rate,
+};
+
+struct clk_hw *imx_clk_divider_gpr_scu(const char *name, const char *parent_name,
+				       sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id)
+{
+	struct clk_divider_gpr_scu *div;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	div->rsrc_id = rsrc_id;
+	div->gpr_id = gpr_id;
+
+	init.name = name;
+	init.ops = &clk_divider_gpr_scu_ops;
+	init.flags = CLK_GET_RATE_NOCACHE;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	div->hw.init = &init;
+
+	hw = &div->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(div);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index c433cd4..97d8bdc 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -33,4 +33,7 @@ static inline struct clk_hw *imx_clk_divider2_scu(const char *name,
 	return imx_clk_register_divider_scu(name, parent_name, rsrc_id, clk_type);
 }
 
+struct clk_hw *imx_clk_divider_gpr_scu(const char *name, const char *parent_name,
+				sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id);
+
 #endif
-- 
2.7.4

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

* [PATCH V2 04/11] clk: imx: scu: add scu clock gpr divider
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Add scu based clock gpr divider. Unlike the normal scu divider, such
dividers are controlled by GPR bits through SCU sc_misc_set_control
API.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2: no changes except update headfile name
---
 drivers/clk/imx/scu/Makefile              |   3 +-
 drivers/clk/imx/scu/clk-divider-gpr-scu.c | 131 ++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h             |   3 +
 3 files changed, 136 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-divider-gpr-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 7e360e2..9e7f4aa 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -2,4 +2,5 @@
 
 obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-scu.o \
-	clk-divider-scu.o
+	clk-divider-scu.o \
+	clk-divider-gpr-scu.o
diff --git a/drivers/clk/imx/scu/clk-divider-gpr-scu.c b/drivers/clk/imx/scu/clk-divider-gpr-scu.c
new file mode 100644
index 0000000..14deb7a
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-divider-gpr-scu.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_divider_gpr_scu {
+	struct clk_hw	hw;
+	sc_rsrc_t	rsrc_id;
+	sc_ctrl_t	gpr_id;
+};
+
+static inline struct clk_divider_gpr_scu *to_clk_divider_gpr_scu(struct clk_hw *hw)
+{
+	return container_of(hw, struct clk_divider_gpr_scu, hw);
+}
+
+/*
+ * clk_divider_scu_recalc_rate - Get clock rate for a SCU clock
+ * @hw: clock to get rate for
+ * @parent_rate: parent rate provided by common clock framework
+ *
+ * Gets the current clock rate of a SCU clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static unsigned long clk_divider_gpr_scu_recalc_rate(struct clk_hw *hw,
+						     unsigned long parent_rate)
+{
+	struct clk_divider_gpr_scu *clk = to_clk_divider_gpr_scu(hw);
+	uint32_t rate = 0;
+	sc_err_t sci_err;
+	uint32_t val;
+
+	sci_err = sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id,
+				      clk->gpr_id, &val);
+
+	rate  = val ? parent_rate / 2 : parent_rate;
+
+	return sci_err ? 0 : rate;
+}
+
+/*
+ * clk_divider_scu_round_rate - Round clock rate for a SCU clock
+ * @hw: clock to round rate for
+ * @rate: rate to round
+ * @parent_rate: parent rate provided by common clock framework
+ *
+ * Gets the current clock rate of a SCU clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static long clk_divider_gpr_scu_round_rate(struct clk_hw *hw, unsigned long rate,
+					   unsigned long *prate)
+{
+	if (rate < *prate)
+		rate = *prate / 2;
+	else
+		rate = *prate;
+
+	return rate;
+}
+
+/*
+ * clk_divider_scu_set_rate - Set rate for a SCU clock
+ * @hw: clock to change rate for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the clock parent
+ *
+ * Sets a clock frequency for a SCU clock. Returns the SCU
+ * protocol status.
+ */
+static int clk_divider_gpr_scu_set_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct clk_divider_gpr_scu *clk = to_clk_divider_gpr_scu(hw);
+	uint32_t val;
+	sc_err_t sci_err;
+
+	val = (rate < parent_rate) ? 1 : 0;
+	sci_err = sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id,
+		clk->gpr_id, val);
+
+	return sci_err ? -EINVAL : 0;
+}
+
+static struct clk_ops clk_divider_gpr_scu_ops = {
+	.recalc_rate = clk_divider_gpr_scu_recalc_rate,
+	.round_rate = clk_divider_gpr_scu_round_rate,
+	.set_rate = clk_divider_gpr_scu_set_rate,
+};
+
+struct clk_hw *imx_clk_divider_gpr_scu(const char *name, const char *parent_name,
+				       sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id)
+{
+	struct clk_divider_gpr_scu *div;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	div->rsrc_id = rsrc_id;
+	div->gpr_id = gpr_id;
+
+	init.name = name;
+	init.ops = &clk_divider_gpr_scu_ops;
+	init.flags = CLK_GET_RATE_NOCACHE;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	div->hw.init = &init;
+
+	hw = &div->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(div);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index c433cd4..97d8bdc 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -33,4 +33,7 @@ static inline struct clk_hw *imx_clk_divider2_scu(const char *name,
 	return imx_clk_register_divider_scu(name, parent_name, rsrc_id, clk_type);
 }
 
+struct clk_hw *imx_clk_divider_gpr_scu(const char *name, const char *parent_name,
+				sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id);
+
 #endif
-- 
2.7.4

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

* [PATCH V2 05/11] clk: imx: scu: add scu clock gate
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add scu based clock gate.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
    v1->v2:
     * move SCU clock API implementation into driver
---
 drivers/clk/imx/scu/Makefile       |   3 +-
 drivers/clk/imx/scu/clk-gate-scu.c | 230 +++++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h      |  23 ++++
 3 files changed, 255 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-gate-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 9e7f4aa..2abed17 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -3,4 +3,5 @@
 obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-scu.o \
 	clk-divider-scu.o \
-	clk-divider-gpr-scu.o
+	clk-divider-gpr-scu.o \
+	clk-gate-scu.o
diff --git a/drivers/clk/imx/scu/clk-gate-scu.c b/drivers/clk/imx/scu/clk-gate-scu.c
new file mode 100644
index 0000000..6edcf29
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-gate-scu.c
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+/*
+ * basic gatable clock which can gate and ungate it's output
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional & control gating
+ * rate - inherits rate from parent.  No clk_set_rate support
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define CLK_GATE_SCU_LPCG_MASK		0x3
+#define CLK_GATE_SCU_LPCG_HW_SEL	BIT(0)
+#define CLK_GATE_SCU_LPCG_SW_SEL	BIT(1)
+
+struct clk_gate_scu {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	u8		bit_idx;
+	bool		hw_gate;
+	sc_rsrc_t	rsrc_id;
+	uint8_t		clk_type;
+};
+
+#define to_clk_gate_scu(_hw) container_of(_hw, struct clk_gate_scu, hw)
+
+/* SCU Clock Protocol definitions */
+struct imx_sc_msg_req_clock_enable {
+	struct sc_rpc_msg hdr;
+	u16 resource;
+	u8 clk;
+	u8 enable;
+	u8 autog;
+} __packed;
+
+/* Write to the LPCG bits. */
+static int clk_gate_scu_enable(struct clk_hw *hw)
+{
+	struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+	u32 reg;
+
+	if (gate->reg) {
+		reg = readl(gate->reg);
+		reg &= ~(CLK_GATE_SCU_LPCG_MASK << gate->bit_idx);
+		if (gate->hw_gate)
+			reg |= (CLK_GATE_SCU_LPCG_HW_SEL |
+				CLK_GATE_SCU_LPCG_SW_SEL) << gate->bit_idx;
+		else
+			reg |= (CLK_GATE_SCU_LPCG_SW_SEL << gate->bit_idx);
+		writel(reg, gate->reg);
+	}
+
+	return 0;
+}
+
+static void clk_gate_scu_disable(struct clk_hw *hw)
+{
+	struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+	u32 reg;
+
+	if (gate->reg) {
+		reg = readl(gate->reg);
+		reg &= ~(CLK_GATE_SCU_LPCG_MASK << gate->bit_idx);
+		writel(reg, gate->reg);
+	}
+}
+
+static sc_err_t sc_pm_clock_enable(struct sc_ipc *ipc, sc_rsrc_t resource,
+				   uint8_t clk, bool enable, bool autog)
+{
+       struct imx_sc_msg_req_clock_enable msg;
+       struct sc_rpc_msg *hdr = &msg.hdr;
+       int ret;
+
+       hdr->ver = SC_RPC_VERSION;
+       hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+       hdr->func = (uint8_t)PM_FUNC_CLOCK_ENABLE;
+       hdr->size = 3;
+
+       msg.resource = resource;
+       msg.clk = clk;
+       msg.enable = (uint8_t)enable;
+       msg.autog = (uint8_t)autog;
+
+       ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+       if (ret)
+               return ret;
+
+       return (sc_err_t)hdr->func;
+}
+
+static int clk_gate_scu_prepare(struct clk_hw *hw)
+{
+	struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+	sc_err_t sci_err;
+
+	/* Enable the clock at the DSC slice level */
+	sci_err = sc_pm_clock_enable(ccm_ipc_handle, gate->rsrc_id,
+				     gate->clk_type, true, gate->hw_gate);
+
+	if (sci_err)
+		pr_err("%s: %s: clk prepare failed %d\n",
+			__func__, clk_hw_get_name(hw), sci_err);
+
+	return sci_err;
+}
+
+static void clk_gate_scu_unprepare(struct clk_hw *hw)
+{
+	struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+	sc_err_t sci_err;
+
+	sci_err = sc_pm_clock_enable(ccm_ipc_handle, gate->rsrc_id,
+				     gate->clk_type, false, false);
+	if (sci_err)
+		pr_err("%s: %s: clk unprepare failed %d\n",
+			__func__, clk_hw_get_name(hw), sci_err);
+}
+
+static const struct clk_ops clk_gate_scu_ops = {
+	.prepare = clk_gate_scu_prepare,
+	.unprepare = clk_gate_scu_unprepare,
+	.enable = clk_gate_scu_enable,
+	.disable = clk_gate_scu_disable,
+};
+
+struct clk_hw *clk_register_gate_scu(const char *name, const char *parent_name,
+				     unsigned long flags, sc_rsrc_t rsrc_id,
+				     uint8_t clk_type, void __iomem *reg,
+				     u8 bit_idx, bool hw_gate)
+{
+	struct clk_gate_scu *gate;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->rsrc_id = rsrc_id;
+	gate->clk_type = clk_type;
+	if (reg) {
+		gate->reg = ioremap((phys_addr_t)reg, SZ_64K);
+		if (!gate->reg) {
+			kfree(gate);
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	gate->bit_idx = bit_idx;
+	gate->hw_gate = hw_gate;
+
+	init.name = name;
+	init.ops = &clk_gate_scu_ops;
+	init.flags = flags;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	gate->hw.init = &init;
+
+	hw = &gate->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		iounmap(gate->reg);
+		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
+
+static const struct clk_ops clk_gate2_scu_ops = {
+	.enable = clk_gate_scu_enable,
+	.disable = clk_gate_scu_disable,
+};
+
+struct clk_hw *clk_register_gate2_scu(const char *name, const char *parent_name,
+				      unsigned long flags, void __iomem *reg,
+				      u8 bit_idx, bool hw_gate)
+{
+	struct clk_gate_scu *gate;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->reg = ioremap((phys_addr_t)reg, SZ_64K);
+	if (!gate->reg) {
+		kfree(gate);
+		return ERR_PTR(-ENOMEM);
+	}
+	gate->bit_idx = bit_idx;
+	gate->hw_gate = hw_gate;
+
+	init.name = name;
+	init.ops = &clk_gate2_scu_ops;
+	init.flags = flags;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	gate->hw.init = &init;
+
+	hw = &gate->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		iounmap(gate->reg);
+		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 97d8bdc..99e45ae 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -36,4 +36,27 @@ static inline struct clk_hw *imx_clk_divider2_scu(const char *name,
 struct clk_hw *imx_clk_divider_gpr_scu(const char *name, const char *parent_name,
 				sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id);
 
+struct clk_hw *clk_register_gate_scu(const char *name, const char *parent_name,
+				unsigned long flags, sc_rsrc_t rsrc_id,
+				uint8_t clk_type, void __iomem *reg,
+				u8 bit_idx, bool hw_gate);
+
+struct clk_hw *clk_register_gate2_scu(const char *name, const char *parent_name,
+				unsigned long flags, void __iomem *reg,
+				u8 bit_idx, bool hw_gate);
+
+static inline struct clk_hw *imx_clk_gate_scu(const char *name, const char *parent,
+				sc_rsrc_t rsrc_id, uint8_t clk_type,
+				void __iomem *reg, u8 bit_idx, bool hw_gate)
+{
+	return clk_register_gate_scu(name, parent, CLK_SET_RATE_PARENT,
+				     rsrc_id, clk_type, reg, bit_idx, hw_gate);
+}
+
+static inline struct clk_hw *imx_clk_gate2_scu(const char *name, const char *parent,
+				void __iomem *reg, u8 bit_idx, bool hw_gate)
+{
+	return clk_register_gate2_scu(name, parent, 0, reg, bit_idx, hw_gate);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 05/11] clk: imx: scu: add scu clock gate
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Add scu based clock gate.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
    v1->v2:
     * move SCU clock API implementation into driver
---
 drivers/clk/imx/scu/Makefile       |   3 +-
 drivers/clk/imx/scu/clk-gate-scu.c | 230 +++++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h      |  23 ++++
 3 files changed, 255 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-gate-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 9e7f4aa..2abed17 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -3,4 +3,5 @@
 obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-scu.o \
 	clk-divider-scu.o \
-	clk-divider-gpr-scu.o
+	clk-divider-gpr-scu.o \
+	clk-gate-scu.o
diff --git a/drivers/clk/imx/scu/clk-gate-scu.c b/drivers/clk/imx/scu/clk-gate-scu.c
new file mode 100644
index 0000000..6edcf29
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-gate-scu.c
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+/*
+ * basic gatable clock which can gate and ungate it's output
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional & control gating
+ * rate - inherits rate from parent.  No clk_set_rate support
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define CLK_GATE_SCU_LPCG_MASK		0x3
+#define CLK_GATE_SCU_LPCG_HW_SEL	BIT(0)
+#define CLK_GATE_SCU_LPCG_SW_SEL	BIT(1)
+
+struct clk_gate_scu {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	u8		bit_idx;
+	bool		hw_gate;
+	sc_rsrc_t	rsrc_id;
+	uint8_t		clk_type;
+};
+
+#define to_clk_gate_scu(_hw) container_of(_hw, struct clk_gate_scu, hw)
+
+/* SCU Clock Protocol definitions */
+struct imx_sc_msg_req_clock_enable {
+	struct sc_rpc_msg hdr;
+	u16 resource;
+	u8 clk;
+	u8 enable;
+	u8 autog;
+} __packed;
+
+/* Write to the LPCG bits. */
+static int clk_gate_scu_enable(struct clk_hw *hw)
+{
+	struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+	u32 reg;
+
+	if (gate->reg) {
+		reg = readl(gate->reg);
+		reg &= ~(CLK_GATE_SCU_LPCG_MASK << gate->bit_idx);
+		if (gate->hw_gate)
+			reg |= (CLK_GATE_SCU_LPCG_HW_SEL |
+				CLK_GATE_SCU_LPCG_SW_SEL) << gate->bit_idx;
+		else
+			reg |= (CLK_GATE_SCU_LPCG_SW_SEL << gate->bit_idx);
+		writel(reg, gate->reg);
+	}
+
+	return 0;
+}
+
+static void clk_gate_scu_disable(struct clk_hw *hw)
+{
+	struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+	u32 reg;
+
+	if (gate->reg) {
+		reg = readl(gate->reg);
+		reg &= ~(CLK_GATE_SCU_LPCG_MASK << gate->bit_idx);
+		writel(reg, gate->reg);
+	}
+}
+
+static sc_err_t sc_pm_clock_enable(struct sc_ipc *ipc, sc_rsrc_t resource,
+				   uint8_t clk, bool enable, bool autog)
+{
+       struct imx_sc_msg_req_clock_enable msg;
+       struct sc_rpc_msg *hdr = &msg.hdr;
+       int ret;
+
+       hdr->ver = SC_RPC_VERSION;
+       hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+       hdr->func = (uint8_t)PM_FUNC_CLOCK_ENABLE;
+       hdr->size = 3;
+
+       msg.resource = resource;
+       msg.clk = clk;
+       msg.enable = (uint8_t)enable;
+       msg.autog = (uint8_t)autog;
+
+       ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+       if (ret)
+               return ret;
+
+       return (sc_err_t)hdr->func;
+}
+
+static int clk_gate_scu_prepare(struct clk_hw *hw)
+{
+	struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+	sc_err_t sci_err;
+
+	/* Enable the clock at the DSC slice level */
+	sci_err = sc_pm_clock_enable(ccm_ipc_handle, gate->rsrc_id,
+				     gate->clk_type, true, gate->hw_gate);
+
+	if (sci_err)
+		pr_err("%s: %s: clk prepare failed %d\n",
+			__func__, clk_hw_get_name(hw), sci_err);
+
+	return sci_err;
+}
+
+static void clk_gate_scu_unprepare(struct clk_hw *hw)
+{
+	struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+	sc_err_t sci_err;
+
+	sci_err = sc_pm_clock_enable(ccm_ipc_handle, gate->rsrc_id,
+				     gate->clk_type, false, false);
+	if (sci_err)
+		pr_err("%s: %s: clk unprepare failed %d\n",
+			__func__, clk_hw_get_name(hw), sci_err);
+}
+
+static const struct clk_ops clk_gate_scu_ops = {
+	.prepare = clk_gate_scu_prepare,
+	.unprepare = clk_gate_scu_unprepare,
+	.enable = clk_gate_scu_enable,
+	.disable = clk_gate_scu_disable,
+};
+
+struct clk_hw *clk_register_gate_scu(const char *name, const char *parent_name,
+				     unsigned long flags, sc_rsrc_t rsrc_id,
+				     uint8_t clk_type, void __iomem *reg,
+				     u8 bit_idx, bool hw_gate)
+{
+	struct clk_gate_scu *gate;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->rsrc_id = rsrc_id;
+	gate->clk_type = clk_type;
+	if (reg) {
+		gate->reg = ioremap((phys_addr_t)reg, SZ_64K);
+		if (!gate->reg) {
+			kfree(gate);
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	gate->bit_idx = bit_idx;
+	gate->hw_gate = hw_gate;
+
+	init.name = name;
+	init.ops = &clk_gate_scu_ops;
+	init.flags = flags;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	gate->hw.init = &init;
+
+	hw = &gate->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		iounmap(gate->reg);
+		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
+
+static const struct clk_ops clk_gate2_scu_ops = {
+	.enable = clk_gate_scu_enable,
+	.disable = clk_gate_scu_disable,
+};
+
+struct clk_hw *clk_register_gate2_scu(const char *name, const char *parent_name,
+				      unsigned long flags, void __iomem *reg,
+				      u8 bit_idx, bool hw_gate)
+{
+	struct clk_gate_scu *gate;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->reg = ioremap((phys_addr_t)reg, SZ_64K);
+	if (!gate->reg) {
+		kfree(gate);
+		return ERR_PTR(-ENOMEM);
+	}
+	gate->bit_idx = bit_idx;
+	gate->hw_gate = hw_gate;
+
+	init.name = name;
+	init.ops = &clk_gate2_scu_ops;
+	init.flags = flags;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	gate->hw.init = &init;
+
+	hw = &gate->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		iounmap(gate->reg);
+		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 97d8bdc..99e45ae 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -36,4 +36,27 @@ static inline struct clk_hw *imx_clk_divider2_scu(const char *name,
 struct clk_hw *imx_clk_divider_gpr_scu(const char *name, const char *parent_name,
 				sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id);
 
+struct clk_hw *clk_register_gate_scu(const char *name, const char *parent_name,
+				unsigned long flags, sc_rsrc_t rsrc_id,
+				uint8_t clk_type, void __iomem *reg,
+				u8 bit_idx, bool hw_gate);
+
+struct clk_hw *clk_register_gate2_scu(const char *name, const char *parent_name,
+				unsigned long flags, void __iomem *reg,
+				u8 bit_idx, bool hw_gate);
+
+static inline struct clk_hw *imx_clk_gate_scu(const char *name, const char *parent,
+				sc_rsrc_t rsrc_id, uint8_t clk_type,
+				void __iomem *reg, u8 bit_idx, bool hw_gate)
+{
+	return clk_register_gate_scu(name, parent, CLK_SET_RATE_PARENT,
+				     rsrc_id, clk_type, reg, bit_idx, hw_gate);
+}
+
+static inline struct clk_hw *imx_clk_gate2_scu(const char *name, const char *parent,
+				void __iomem *reg, u8 bit_idx, bool hw_gate)
+{
+	return clk_register_gate2_scu(name, parent, 0, reg, bit_idx, hw_gate);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 06/11] clk: imx: scu: add scu clock gpr gate
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add scu based clock gpr gate. Unlike the normal scu gate, such
gates are controlled by GPR bits through SCU sc_misc_set_control
API.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
    v1->v2: no changes except update headfile name
---
 drivers/clk/imx/scu/Makefile           |  3 +-
 drivers/clk/imx/scu/clk-gate-gpr-scu.c | 84 ++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h          |  9 ++++
 3 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-gate-gpr-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 2abed17..25d3511 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-scu.o \
 	clk-divider-scu.o \
 	clk-divider-gpr-scu.o \
-	clk-gate-scu.o
+	clk-gate-scu.o \
+	clk-gate-gpr-scu.o
diff --git a/drivers/clk/imx/scu/clk-gate-gpr-scu.c b/drivers/clk/imx/scu/clk-gate-gpr-scu.c
new file mode 100644
index 0000000..ea3d4fb
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-gate-gpr-scu.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_gate_gpr_scu {
+	struct clk_hw hw;
+	sc_rsrc_t	rsrc_id;
+	sc_ctrl_t	gpr_id;
+
+	/* default: enable 1 disable 0 */
+	bool	invert;
+};
+
+#define to_clk_gate_gpr_scu(_hw) container_of(_hw, struct clk_gate_gpr_scu, hw)
+
+static int clk_gate_gpr_scu_enable(struct clk_hw *hw)
+{
+	struct clk_gate_gpr_scu *gate = to_clk_gate_gpr_scu(hw);
+
+	return sc_misc_set_control(ccm_ipc_handle, gate->rsrc_id,
+				   gate->gpr_id, !gate->invert);
+}
+
+static void clk_gate_gpr_scu_disable(struct clk_hw *hw)
+{
+	struct clk_gate_gpr_scu *gate = to_clk_gate_gpr_scu(hw);
+	sc_err_t sci_err;
+
+	sci_err = sc_misc_set_control(ccm_ipc_handle, gate->rsrc_id,
+				      gate->gpr_id, gate->invert);
+	if (sci_err)
+		pr_warn("%s: %s: clk disable failed %d\n",
+			__func__, clk_hw_get_name(hw), sci_err);
+}
+
+static const struct clk_ops clk_gate_gpr_scu_ops = {
+	.enable = clk_gate_gpr_scu_enable,
+	.disable = clk_gate_gpr_scu_disable,
+};
+
+struct clk_hw *clk_register_gate_gpr_scu(const char *name, const char *parent_name,
+					 sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id,
+					 bool invert_flag)
+{
+	struct clk_gate_gpr_scu *gate;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->rsrc_id = rsrc_id;
+	gate->gpr_id = gpr_id;
+	gate->invert = invert_flag;
+
+	init.name = name;
+	init.ops = &clk_gate_gpr_scu_ops;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	gate->hw.init = &init;
+
+	hw = &gate->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 99e45ae..13af045 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -59,4 +59,13 @@ static inline struct clk_hw *imx_clk_gate2_scu(const char *name, const char *par
 	return clk_register_gate2_scu(name, parent, 0, reg, bit_idx, hw_gate);
 }
 
+struct clk_hw *clk_register_gate_gpr_scu(const char *name, const char *parent_name,
+				sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag);
+
+static inline struct clk_hw *imx_clk_gate_gpr_scu(const char *name, const char *parent,
+				sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag)
+{
+	return clk_register_gate_gpr_scu(name, parent, rsrc_id, gpr_id, invert_flag);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 06/11] clk: imx: scu: add scu clock gpr gate
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Add scu based clock gpr gate. Unlike the normal scu gate, such
gates are controlled by GPR bits through SCU sc_misc_set_control
API.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
    v1->v2: no changes except update headfile name
---
 drivers/clk/imx/scu/Makefile           |  3 +-
 drivers/clk/imx/scu/clk-gate-gpr-scu.c | 84 ++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h          |  9 ++++
 3 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-gate-gpr-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 2abed17..25d3511 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-scu.o \
 	clk-divider-scu.o \
 	clk-divider-gpr-scu.o \
-	clk-gate-scu.o
+	clk-gate-scu.o \
+	clk-gate-gpr-scu.o
diff --git a/drivers/clk/imx/scu/clk-gate-gpr-scu.c b/drivers/clk/imx/scu/clk-gate-gpr-scu.c
new file mode 100644
index 0000000..ea3d4fb
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-gate-gpr-scu.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_gate_gpr_scu {
+	struct clk_hw hw;
+	sc_rsrc_t	rsrc_id;
+	sc_ctrl_t	gpr_id;
+
+	/* default: enable 1 disable 0 */
+	bool	invert;
+};
+
+#define to_clk_gate_gpr_scu(_hw) container_of(_hw, struct clk_gate_gpr_scu, hw)
+
+static int clk_gate_gpr_scu_enable(struct clk_hw *hw)
+{
+	struct clk_gate_gpr_scu *gate = to_clk_gate_gpr_scu(hw);
+
+	return sc_misc_set_control(ccm_ipc_handle, gate->rsrc_id,
+				   gate->gpr_id, !gate->invert);
+}
+
+static void clk_gate_gpr_scu_disable(struct clk_hw *hw)
+{
+	struct clk_gate_gpr_scu *gate = to_clk_gate_gpr_scu(hw);
+	sc_err_t sci_err;
+
+	sci_err = sc_misc_set_control(ccm_ipc_handle, gate->rsrc_id,
+				      gate->gpr_id, gate->invert);
+	if (sci_err)
+		pr_warn("%s: %s: clk disable failed %d\n",
+			__func__, clk_hw_get_name(hw), sci_err);
+}
+
+static const struct clk_ops clk_gate_gpr_scu_ops = {
+	.enable = clk_gate_gpr_scu_enable,
+	.disable = clk_gate_gpr_scu_disable,
+};
+
+struct clk_hw *clk_register_gate_gpr_scu(const char *name, const char *parent_name,
+					 sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id,
+					 bool invert_flag)
+{
+	struct clk_gate_gpr_scu *gate;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->rsrc_id = rsrc_id;
+	gate->gpr_id = gpr_id;
+	gate->invert = invert_flag;
+
+	init.name = name;
+	init.ops = &clk_gate_gpr_scu_ops;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	gate->hw.init = &init;
+
+	hw = &gate->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 99e45ae..13af045 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -59,4 +59,13 @@ static inline struct clk_hw *imx_clk_gate2_scu(const char *name, const char *par
 	return clk_register_gate2_scu(name, parent, 0, reg, bit_idx, hw_gate);
 }
 
+struct clk_hw *clk_register_gate_gpr_scu(const char *name, const char *parent_name,
+				sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag);
+
+static inline struct clk_hw *imx_clk_gate_gpr_scu(const char *name, const char *parent,
+				sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag)
+{
+	return clk_register_gate_gpr_scu(name, parent, rsrc_id, gpr_id, invert_flag);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 07/11] clk: imx: scu: add scu clock mux
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add scu based clock mux.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2:
 * move SCU clock API implementation into driver
---
 drivers/clk/imx/scu/Makefile      |   3 +-
 drivers/clk/imx/scu/clk-mux-scu.c | 142 ++++++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h     |  13 ++++
 3 files changed, 157 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-mux-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 25d3511..aee56bf 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-divider-scu.o \
 	clk-divider-gpr-scu.o \
 	clk-gate-scu.o \
-	clk-gate-gpr-scu.o
+	clk-gate-gpr-scu.o \
+	clk-mux-scu.o
diff --git a/drivers/clk/imx/scu/clk-mux-scu.c b/drivers/clk/imx/scu/clk-mux-scu.c
new file mode 100644
index 0000000..bd6f51b
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-mux-scu.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_mux_scu {
+	struct clk_hw	hw;
+	sc_rsrc_t	rsrc_id;
+	uint8_t	clk_type;
+};
+
+#define to_clk_mux_scu(_hw) container_of(_hw, struct clk_mux_scu, hw)
+
+
+/* SCU Clock Protocol definitions */
+struct imx_sc_msg_req_set_clock_parent {
+	struct sc_rpc_msg hdr;
+	u16 resource;
+	u8 clk;
+	u8 parent;
+} __packed;
+
+struct imx_sc_msg_req_get_clock_parent {
+	struct sc_rpc_msg hdr;
+	u16 resource;
+	u8 clk;
+} __packed;
+
+struct imx_sc_msg_resp_get_clock_parent {
+	struct sc_rpc_msg hdr;
+	u8 parent;
+} __packed;
+
+static u8 clk_mux_scu_get_parent(struct clk_hw *hw)
+{
+	struct clk_mux_scu *mux = to_clk_mux_scu(hw);
+	struct imx_sc_msg_req_get_clock_parent msg;
+	struct imx_sc_msg_resp_get_clock_parent *resp;
+	struct sc_rpc_msg *hdr = &msg.hdr;
+	sc_err_t sci_err;
+	int ret;
+
+	hdr->ver = SC_RPC_VERSION;
+	hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+	hdr->func = (uint8_t)PM_FUNC_GET_CLOCK_PARENT;
+	hdr->size = 2;
+
+	msg.resource = mux->rsrc_id;
+	msg.clk = mux->clk_type;
+
+	ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+	if (ret)
+		return ret;
+
+	resp = (struct imx_sc_msg_resp_get_clock_parent *)&msg;
+	sci_err = (sc_err_t)resp->hdr.func;
+	if (sci_err) {
+		pr_err("%s: failed to get clock parent %d\n",
+			clk_hw_get_name(hw), sci_err);
+		return -EINVAL;
+	}
+
+	return resp->parent;
+}
+
+static int clk_mux_scu_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_mux_scu *mux = to_clk_mux_scu(hw);
+	struct imx_sc_msg_req_set_clock_parent msg;
+	struct sc_rpc_msg *hdr = &msg.hdr;
+	sc_err_t sci_err;
+	int ret;
+
+	hdr->ver = SC_RPC_VERSION;
+	hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+	hdr->func = (uint8_t)PM_FUNC_SET_CLOCK_PARENT;
+	hdr->size = 2;
+
+	msg.resource = mux->rsrc_id;
+	msg.clk = mux->clk_type;
+	msg.parent = index;
+
+	ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+	if (ret)
+		return ret;
+
+	sci_err = (sc_err_t)hdr->func;
+	if (sci_err) {
+		pr_err("%s: failed to set clock parent %d : ret %d\n",
+			clk_hw_get_name(hw), index, sci_err);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct clk_ops clk_mux_scu_ops = {
+	.get_parent = clk_mux_scu_get_parent,
+	.set_parent = clk_mux_scu_set_parent,
+};
+
+struct clk_hw *clk_register_mux_scu(const char *name, const char * const *parents,
+				    int num_parents, unsigned long flags,
+				    sc_rsrc_t rsrc_id, uint8_t clk_type)
+{
+	struct clk_init_data init;
+	struct clk_mux_scu *mux;
+	struct clk_hw *hw;
+	int ret;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_mux_scu_ops;
+	init.parent_names = parents;
+	init.num_parents = num_parents;
+
+	mux->hw.init = &init;
+	mux->rsrc_id = rsrc_id;
+	mux->clk_type = clk_type;
+
+	hw = &mux->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(mux);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 13af045..43009c4 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -68,4 +68,17 @@ static inline struct clk_hw *imx_clk_gate_gpr_scu(const char *name, const char *
 	return clk_register_gate_gpr_scu(name, parent, rsrc_id, gpr_id, invert_flag);
 }
 
+struct clk_hw *clk_register_mux_scu(const char *name, const char * const *parents,
+			int num_parents, unsigned long flags,
+			sc_rsrc_t rsrc_id, uint8_t clk_type);
+
+static inline struct clk_hw *imx_clk_mux_scu(const char *name,
+			const char * const *parents, int num_parents,
+			sc_rsrc_t rsrc_id, uint8_t clk_type)
+{
+	return clk_register_mux_scu(name, parents, num_parents,
+			CLK_SET_RATE_NO_REPARENT, rsrc_id,
+			clk_type);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 07/11] clk: imx: scu: add scu clock mux
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Add scu based clock mux.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2:
 * move SCU clock API implementation into driver
---
 drivers/clk/imx/scu/Makefile      |   3 +-
 drivers/clk/imx/scu/clk-mux-scu.c | 142 ++++++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h     |  13 ++++
 3 files changed, 157 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-mux-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index 25d3511..aee56bf 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-divider-scu.o \
 	clk-divider-gpr-scu.o \
 	clk-gate-scu.o \
-	clk-gate-gpr-scu.o
+	clk-gate-gpr-scu.o \
+	clk-mux-scu.o
diff --git a/drivers/clk/imx/scu/clk-mux-scu.c b/drivers/clk/imx/scu/clk-mux-scu.c
new file mode 100644
index 0000000..bd6f51b
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-mux-scu.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_mux_scu {
+	struct clk_hw	hw;
+	sc_rsrc_t	rsrc_id;
+	uint8_t	clk_type;
+};
+
+#define to_clk_mux_scu(_hw) container_of(_hw, struct clk_mux_scu, hw)
+
+
+/* SCU Clock Protocol definitions */
+struct imx_sc_msg_req_set_clock_parent {
+	struct sc_rpc_msg hdr;
+	u16 resource;
+	u8 clk;
+	u8 parent;
+} __packed;
+
+struct imx_sc_msg_req_get_clock_parent {
+	struct sc_rpc_msg hdr;
+	u16 resource;
+	u8 clk;
+} __packed;
+
+struct imx_sc_msg_resp_get_clock_parent {
+	struct sc_rpc_msg hdr;
+	u8 parent;
+} __packed;
+
+static u8 clk_mux_scu_get_parent(struct clk_hw *hw)
+{
+	struct clk_mux_scu *mux = to_clk_mux_scu(hw);
+	struct imx_sc_msg_req_get_clock_parent msg;
+	struct imx_sc_msg_resp_get_clock_parent *resp;
+	struct sc_rpc_msg *hdr = &msg.hdr;
+	sc_err_t sci_err;
+	int ret;
+
+	hdr->ver = SC_RPC_VERSION;
+	hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+	hdr->func = (uint8_t)PM_FUNC_GET_CLOCK_PARENT;
+	hdr->size = 2;
+
+	msg.resource = mux->rsrc_id;
+	msg.clk = mux->clk_type;
+
+	ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+	if (ret)
+		return ret;
+
+	resp = (struct imx_sc_msg_resp_get_clock_parent *)&msg;
+	sci_err = (sc_err_t)resp->hdr.func;
+	if (sci_err) {
+		pr_err("%s: failed to get clock parent %d\n",
+			clk_hw_get_name(hw), sci_err);
+		return -EINVAL;
+	}
+
+	return resp->parent;
+}
+
+static int clk_mux_scu_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_mux_scu *mux = to_clk_mux_scu(hw);
+	struct imx_sc_msg_req_set_clock_parent msg;
+	struct sc_rpc_msg *hdr = &msg.hdr;
+	sc_err_t sci_err;
+	int ret;
+
+	hdr->ver = SC_RPC_VERSION;
+	hdr->svc = (uint8_t)SC_RPC_SVC_PM;
+	hdr->func = (uint8_t)PM_FUNC_SET_CLOCK_PARENT;
+	hdr->size = 2;
+
+	msg.resource = mux->rsrc_id;
+	msg.clk = mux->clk_type;
+	msg.parent = index;
+
+	ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
+	if (ret)
+		return ret;
+
+	sci_err = (sc_err_t)hdr->func;
+	if (sci_err) {
+		pr_err("%s: failed to set clock parent %d : ret %d\n",
+			clk_hw_get_name(hw), index, sci_err);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct clk_ops clk_mux_scu_ops = {
+	.get_parent = clk_mux_scu_get_parent,
+	.set_parent = clk_mux_scu_set_parent,
+};
+
+struct clk_hw *clk_register_mux_scu(const char *name, const char * const *parents,
+				    int num_parents, unsigned long flags,
+				    sc_rsrc_t rsrc_id, uint8_t clk_type)
+{
+	struct clk_init_data init;
+	struct clk_mux_scu *mux;
+	struct clk_hw *hw;
+	int ret;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_mux_scu_ops;
+	init.parent_names = parents;
+	init.num_parents = num_parents;
+
+	mux->hw.init = &init;
+	mux->rsrc_id = rsrc_id;
+	mux->clk_type = clk_type;
+
+	hw = &mux->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(mux);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 13af045..43009c4 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -68,4 +68,17 @@ static inline struct clk_hw *imx_clk_gate_gpr_scu(const char *name, const char *
 	return clk_register_gate_gpr_scu(name, parent, rsrc_id, gpr_id, invert_flag);
 }
 
+struct clk_hw *clk_register_mux_scu(const char *name, const char * const *parents,
+			int num_parents, unsigned long flags,
+			sc_rsrc_t rsrc_id, uint8_t clk_type);
+
+static inline struct clk_hw *imx_clk_mux_scu(const char *name,
+			const char * const *parents, int num_parents,
+			sc_rsrc_t rsrc_id, uint8_t clk_type)
+{
+	return clk_register_mux_scu(name, parents, num_parents,
+			CLK_SET_RATE_NO_REPARENT, rsrc_id,
+			clk_type);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 08/11] clk: imx: scu: add scu clock gpr mux
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add scu based clock gpr mux. Unlike the normal scu mux, such
muxes are controlled by GPR bits through SCU sc_misc_set_control
API.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
 v1->v2:
  * no changes except headfile name updated
---
 drivers/clk/imx/scu/Makefile          |  3 +-
 drivers/clk/imx/scu/clk-mux-gpr-scu.c | 90 +++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h         | 11 +++++
 3 files changed, 103 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-mux-gpr-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index aee56bf..a76ed78 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-divider-gpr-scu.o \
 	clk-gate-scu.o \
 	clk-gate-gpr-scu.o \
-	clk-mux-scu.o
+	clk-mux-scu.o \
+	clk-mux-gpr-scu.o
diff --git a/drivers/clk/imx/scu/clk-mux-gpr-scu.c b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
new file mode 100644
index 0000000..c4b5687
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_mux_gpr_scu {
+	struct clk_hw hw;
+	sc_rsrc_t	rsrc_id;
+	sc_ctrl_t	gpr_id;
+};
+
+#define to_clk_mux_gpr_scu(_hw) container_of(_hw, struct clk_mux_gpr_scu, hw)
+
+static u8 clk_mux_gpr_scu_get_parent(struct clk_hw *hw)
+{
+	struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
+	sc_err_t ret;
+	u32 val = 0;
+
+	ret = sc_misc_get_control(ccm_ipc_handle, gpr_mux->rsrc_id,
+				  gpr_mux->gpr_id, &val);
+	if (ret != SC_ERR_NONE) {
+		pr_warn("%s: failed to get clock parent %d\n",
+			clk_hw_get_name(hw), ret);
+		return 0;
+	}
+
+	return (u8)val;
+}
+
+static int clk_mux_gpr_scu_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
+	sc_err_t ret;
+
+	ret = sc_misc_set_control(ccm_ipc_handle, gpr_mux->rsrc_id,
+				  gpr_mux->gpr_id, index);
+	if (ret != SC_ERR_NONE)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const struct clk_ops clk_mux_gpr_scu_ops = {
+	.get_parent = clk_mux_gpr_scu_get_parent,
+	.set_parent = clk_mux_gpr_scu_set_parent,
+};
+
+struct clk_hw *clk_register_mux_gpr_scu(const char *name, const char * const *parents,
+					int num_parents, unsigned long flags,
+					sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id)
+{
+	struct clk_mux_gpr_scu *mux;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_mux_gpr_scu_ops;
+	init.parent_names = parents;
+	init.num_parents = num_parents;
+	init.flags = flags;
+
+	mux->hw.init = &init;
+	mux->rsrc_id = rsrc_id;
+	mux->gpr_id = gpr_id;
+
+	hw = &mux->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(mux);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 43009c4..828700d 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -81,4 +81,15 @@ static inline struct clk_hw *imx_clk_mux_scu(const char *name,
 			clk_type);
 }
 
+struct clk_hw *clk_register_mux_gpr_scu(const char *name, const char * const *parents,
+			int num_parents, unsigned long flags,
+			sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id);
+
+static inline struct clk_hw *imx_clk_mux_gpr_scu(const char *name, const char * const *parents,
+			int num_parents, sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id)
+{
+	return clk_register_mux_gpr_scu(name, parents, num_parents,
+			CLK_SET_RATE_NO_REPARENT, rsrc_id, gpr_id);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 08/11] clk: imx: scu: add scu clock gpr mux
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Add scu based clock gpr mux. Unlike the normal scu mux, such
muxes are controlled by GPR bits through SCU sc_misc_set_control
API.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
 v1->v2:
  * no changes except headfile name updated
---
 drivers/clk/imx/scu/Makefile          |  3 +-
 drivers/clk/imx/scu/clk-mux-gpr-scu.c | 90 +++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h         | 11 +++++
 3 files changed, 103 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-mux-gpr-scu.c

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index aee56bf..a76ed78 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-divider-gpr-scu.o \
 	clk-gate-scu.o \
 	clk-gate-gpr-scu.o \
-	clk-mux-scu.o
+	clk-mux-scu.o \
+	clk-mux-gpr-scu.o
diff --git a/drivers/clk/imx/scu/clk-mux-gpr-scu.c b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
new file mode 100644
index 0000000..c4b5687
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+struct clk_mux_gpr_scu {
+	struct clk_hw hw;
+	sc_rsrc_t	rsrc_id;
+	sc_ctrl_t	gpr_id;
+};
+
+#define to_clk_mux_gpr_scu(_hw) container_of(_hw, struct clk_mux_gpr_scu, hw)
+
+static u8 clk_mux_gpr_scu_get_parent(struct clk_hw *hw)
+{
+	struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
+	sc_err_t ret;
+	u32 val = 0;
+
+	ret = sc_misc_get_control(ccm_ipc_handle, gpr_mux->rsrc_id,
+				  gpr_mux->gpr_id, &val);
+	if (ret != SC_ERR_NONE) {
+		pr_warn("%s: failed to get clock parent %d\n",
+			clk_hw_get_name(hw), ret);
+		return 0;
+	}
+
+	return (u8)val;
+}
+
+static int clk_mux_gpr_scu_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
+	sc_err_t ret;
+
+	ret = sc_misc_set_control(ccm_ipc_handle, gpr_mux->rsrc_id,
+				  gpr_mux->gpr_id, index);
+	if (ret != SC_ERR_NONE)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const struct clk_ops clk_mux_gpr_scu_ops = {
+	.get_parent = clk_mux_gpr_scu_get_parent,
+	.set_parent = clk_mux_gpr_scu_set_parent,
+};
+
+struct clk_hw *clk_register_mux_gpr_scu(const char *name, const char * const *parents,
+					int num_parents, unsigned long flags,
+					sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id)
+{
+	struct clk_mux_gpr_scu *mux;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_mux_gpr_scu_ops;
+	init.parent_names = parents;
+	init.num_parents = num_parents;
+	init.flags = flags;
+
+	mux->hw.init = &init;
+	mux->rsrc_id = rsrc_id;
+	mux->gpr_id = gpr_id;
+
+	hw = &mux->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(mux);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 43009c4..828700d 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -81,4 +81,15 @@ static inline struct clk_hw *imx_clk_mux_scu(const char *name,
 			clk_type);
 }
 
+struct clk_hw *clk_register_mux_gpr_scu(const char *name, const char * const *parents,
+			int num_parents, unsigned long flags,
+			sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id);
+
+static inline struct clk_hw *imx_clk_mux_gpr_scu(const char *name, const char * const *parents,
+			int num_parents, sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id)
+{
+	return clk_register_mux_gpr_scu(name, parents, num_parents,
+			CLK_SET_RATE_NO_REPARENT, rsrc_id, gpr_id);
+}
+
 #endif
-- 
2.7.4

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

* [PATCH V2 09/11] clk: imx: add common imx_clk_hw_fixed functions
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

This may be used by both mmio and scu clks. So let's put it
into a common file.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 drivers/clk/imx/clk-common.h  | 16 ++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h |  2 ++
 2 files changed, 18 insertions(+)
 create mode 100644 drivers/clk/imx/clk-common.h

diff --git a/drivers/clk/imx/clk-common.h b/drivers/clk/imx/clk-common.h
new file mode 100644
index 0000000..e3634a5
--- /dev/null
+++ b/drivers/clk/imx/clk-common.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef __IMX_CLK_COMMON_H
+#define __IMX_CLK_COMMON_H
+
+#include <linux/clk-provider.h>
+
+static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
+{
+	return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
+}
+
+#endif /* __IMX_CLK_COMMON_H */
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 828700d..60c476b 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -11,6 +11,8 @@
 #include <linux/spinlock.h>
 #include <soc/imx/scu/sci.h>
 
+#include "../clk-common.h"
+
 extern spinlock_t imx_ccm_lock;
 extern struct sc_ipc *ccm_ipc_handle;
 
-- 
2.7.4

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

* [PATCH V2 09/11] clk: imx: add common imx_clk_hw_fixed functions
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

This may be used by both mmio and scu clks. So let's put it
into a common file.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 drivers/clk/imx/clk-common.h  | 16 ++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h |  2 ++
 2 files changed, 18 insertions(+)
 create mode 100644 drivers/clk/imx/clk-common.h

diff --git a/drivers/clk/imx/clk-common.h b/drivers/clk/imx/clk-common.h
new file mode 100644
index 0000000..e3634a5
--- /dev/null
+++ b/drivers/clk/imx/clk-common.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef __IMX_CLK_COMMON_H
+#define __IMX_CLK_COMMON_H
+
+#include <linux/clk-provider.h>
+
+static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
+{
+	return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
+}
+
+#endif /* __IMX_CLK_COMMON_H */
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index 828700d..60c476b 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -11,6 +11,8 @@
 #include <linux/spinlock.h>
 #include <soc/imx/scu/sci.h>
 
+#include "../clk-common.h"
+
 extern spinlock_t imx_ccm_lock;
 extern struct sc_ipc *ccm_ipc_handle;
 
-- 
2.7.4

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

* [PATCH V2 10/11] clk: imx: add imx_check_clk_hws helper function
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add imx_check_clk_hws helper function

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 drivers/clk/imx/clk-common.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/clk/imx/clk-common.h b/drivers/clk/imx/clk-common.h
index e3634a5..01550fd 100644
--- a/drivers/clk/imx/clk-common.h
+++ b/drivers/clk/imx/clk-common.h
@@ -13,4 +13,15 @@ static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
 	return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
 }
 
+static inline void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count)
+{
+	unsigned int 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]));
+	}
+}
+
 #endif /* __IMX_CLK_COMMON_H */
-- 
2.7.4

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

* [PATCH V2 10/11] clk: imx: add imx_check_clk_hws helper function
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Add imx_check_clk_hws helper function

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 drivers/clk/imx/clk-common.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/clk/imx/clk-common.h b/drivers/clk/imx/clk-common.h
index e3634a5..01550fd 100644
--- a/drivers/clk/imx/clk-common.h
+++ b/drivers/clk/imx/clk-common.h
@@ -13,4 +13,15 @@ static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
 	return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
 }
 
+static inline void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count)
+{
+	unsigned int 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]));
+	}
+}
+
 #endif /* __IMX_CLK_COMMON_H */
-- 
2.7.4

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

* [PATCH V2 11/11] clk: imx: add imx8qxp clk driver
  2018-09-25 16:43 ` Dong Aisheng
@ 2018-09-25 16:43   ` Dong Aisheng
  -1 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add imx8qxp clk driver which is based on SCU firmware clock service.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2:
 * no changes except headfile name updated
---
 drivers/clk/imx/scu/Makefile      |   2 +
 drivers/clk/imx/scu/clk-imx8qxp.c | 426 ++++++++++++++++++++++++++++++++++++++
 include/soc/imx/imx8qxp/lpcg.h    | 186 +++++++++++++++++
 3 files changed, 614 insertions(+)
 create mode 100644 drivers/clk/imx/scu/clk-imx8qxp.c
 create mode 100644 include/soc/imx/imx8qxp/lpcg.h

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index a76ed78..68e2d7f 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -8,3 +8,5 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-gate-gpr-scu.o \
 	clk-mux-scu.o \
 	clk-mux-gpr-scu.o
+
+obj-$(CONFIG_SOC_IMX8QXP)	+= clk-imx8qxp.o
diff --git a/drivers/clk/imx/scu/clk-imx8qxp.c b/drivers/clk/imx/scu/clk-imx8qxp.c
new file mode 100644
index 0000000..1a55757
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-imx8qxp.c
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <dt-bindings/clock/imx8qxp-clock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <soc/imx/imx8qxp/lpcg.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+static struct clk_hw_onecell_data *clk_data;
+
+static const char * const enet_sels[] = { "enet_25MHz", "enet_125MHz", };
+static const char * const enet0_rmii_tx_sels[] = { "enet0_ref_div", "dummy", };
+static const char * const enet1_rmii_tx_sels[] = { "enet1_ref_div", "dummy", };
+
+static int imx8qxp_clk_probe(struct platform_device *pdev)
+{
+	struct device_node *ccm_node = pdev->dev.of_node;
+	struct clk_hw **clks;
+	int ret;
+
+	ret = imx_clk_scu_init();
+	if (ret)
+		return ret;
+
+	clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data) +
+				sizeof(*clk_data->hws) * IMX8QXP_CLK_END,
+				GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	clk_data->num = IMX8QXP_CLK_END;
+	clks = clk_data->hws;
+
+	/* Fixed clocks */
+	clks[IMX8QXP_CLK_DUMMY]		= imx_clk_hw_fixed("dummy", 0);
+	clks[IMX8QXP_24MHZ]		= imx_clk_hw_fixed("xtal_24MHz", 24000000);
+	clks[IMX8QXP_GPT_3M]		= imx_clk_hw_fixed("gpt_3m", 3000000);
+	clks[IMX8QXP_32KHZ]		= imx_clk_hw_fixed("xtal_32KHz", 32768);
+
+	/* ARM core */
+	clks[IMX8QXP_A35_DIV]		= imx_clk_divider_scu("a35_div", SC_R_A35, SC_PM_CLK_CPU);
+
+	clks[IMX8QXP_IPG_DMA_CLK_ROOT]	= imx_clk_hw_fixed("ipg_dma_clk_root", 120000000);
+	clks[IMX8QXP_AXI_CONN_CLK_ROOT] = imx_clk_hw_fixed("axi_conn_clk_root", 333333333);
+	clks[IMX8QXP_AHB_CONN_CLK_ROOT] = imx_clk_hw_fixed("ahb_conn_clk_root", 166666666);
+	clks[IMX8QXP_IPG_CONN_CLK_ROOT] = imx_clk_hw_fixed("ipg_conn_clk_root", 83333333);
+	clks[IMX8QXP_DC_AXI_EXT_CLK]	= imx_clk_hw_fixed("axi_ext_dc_clk_root", 800000000);
+	clks[IMX8QXP_DC_AXI_INT_CLK]	= imx_clk_hw_fixed("axi_int_dc_clk_root", 400000000);
+	clks[IMX8QXP_DC_CFG_CLK]	= imx_clk_hw_fixed("cfg_dc_clk_root", 100000000);
+	clks[IMX8QXP_MIPI_IPG_CLK]	= imx_clk_hw_fixed("ipg_mipi_clk_root", 120000000);
+	clks[IMX8QXP_IMG_AXI_CLK]	= imx_clk_hw_fixed("axi_img_clk_root", 400000000);
+	clks[IMX8QXP_IMG_IPG_CLK]	= imx_clk_hw_fixed("ipg_img_clk_root", 200000000);
+	clks[IMX8QXP_IMG_PXL_CLK]	= imx_clk_hw_fixed("pxl_img_clk_root", 600000000);
+	clks[IMX8QXP_HSIO_AXI_CLK]	= imx_clk_hw_fixed("axi_hsio_clk_root", 400000000);
+	clks[IMX8QXP_HSIO_PER_CLK]	= imx_clk_hw_fixed("per_hsio_clk_root", 133333333);
+
+	clks[IMX8QXP_UART0_DIV]		= imx_clk_divider_scu("uart0_div", SC_R_UART_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_UART0_IPG_CLK]	= imx_clk_gate2_scu("uart0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_0_LPCG), 16, 0);
+	clks[IMX8QXP_UART0_CLK]		= imx_clk_gate_scu("uart0_clk", "uart0_div", SC_R_UART_0, SC_PM_CLK_PER, (void __iomem *)(LPUART_0_LPCG), 0, 0);
+
+	clks[IMX8QXP_GPU0_CORE_DIV]	= imx_clk_divider_scu("gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER);
+	clks[IMX8QXP_GPU0_SHADER_DIV]	= imx_clk_divider_scu("gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC);
+	clks[IMX8QXP_GPU0_CORE_CLK]	= imx_clk_gate_scu("gpu_core0_clk", "gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER, NULL, 0, 0);
+	clks[IMX8QXP_GPU0_SHADER_CLK]	= imx_clk_gate_scu("gpu_shader0_clk", "gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC, NULL, 0, 0);
+
+	/* LSIO SS */
+	clks[IMX8QXP_LSIO_MEM_CLK]	= imx_clk_hw_fixed("lsio_mem_clk_root", 100000000);
+	clks[IMX8QXP_LSIO_BUS_CLK]	= imx_clk_hw_fixed("lsio_bus_clk_root", 200000000);
+
+	clks[IMX8QXP_LSIO_PWM0_DIV]		= imx_clk_divider_scu("pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM0_IPG_S_CLK]	= imx_clk_gate_scu("pwm_0_ipg_s_clk", "pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM0_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_0_ipg_slv_clk", "pwm_0_ipg_s_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM0_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_0_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_0_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM0_HF_CLK]		= imx_clk_gate_scu("pwm_0_hf_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM0_CLK]		= imx_clk_gate_scu("pwm_0_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM1_DIV]		= imx_clk_divider_scu("pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM1_IPG_S_CLK]	= imx_clk_gate_scu("pwm_1_ipg_s_clk", "pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM1_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_1_ipg_slv_clk", "pwm_1_ipg_s_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM1_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_1_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_1_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM1_HF_CLK]		= imx_clk_gate_scu("pwm_1_hf_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM1_CLK]		= imx_clk_gate_scu("pwm_1_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM2_DIV]		= imx_clk_divider_scu("pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM2_IPG_S_CLK]	= imx_clk_gate_scu("pwm_2_ipg_s_clk", "pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM2_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_2_ipg_slv_clk", "pwm_2_ipg_s_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM2_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_2_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_2_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM2_HF_CLK]		= imx_clk_gate_scu("pwm_2_hf_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM2_CLK]		= imx_clk_gate_scu("pwm_2_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM3_DIV]		= imx_clk_divider_scu("pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM3_IPG_S_CLK]	= imx_clk_gate_scu("pwm_3_ipg_s_clk", "pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM3_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_3_ipg_slv_clk", "pwm_3_ipg_s_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM3_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_3_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_3_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM3_HF_CLK]		= imx_clk_gate_scu("pwm_3_hf_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM3_CLK]		= imx_clk_gate_scu("pwm_3_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM4_DIV]		= imx_clk_divider_scu("pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM4_IPG_S_CLK]	= imx_clk_gate_scu("pwm_4_ipg_s_clk", "pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM4_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_4_ipg_slv_clk", "pwm_4_ipg_s_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM4_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_4_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_4_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM4_HF_CLK]		= imx_clk_gate_scu("pwm_4_hf_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM4_CLK]		= imx_clk_gate_scu("pwm_4_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM5_DIV]		= imx_clk_divider_scu("pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM5_IPG_S_CLK]	= imx_clk_gate_scu("pwm_5_ipg_s_clk", "pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM5_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_5_ipg_slv_clk", "pwm_5_ipg_s_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM5_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_5_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_5_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM5_HF_CLK]		= imx_clk_gate_scu("pwm_5_hf_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM5_CLK]		= imx_clk_gate_scu("pwm_5_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM6_DIV]		= imx_clk_divider_scu("pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM6_IPG_S_CLK]	= imx_clk_gate_scu("pwm_6_ipg_s_clk", "pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM6_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_6_ipg_slv_clk", "pwm_6_ipg_s_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM6_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_6_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_6_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM6_HF_CLK]		= imx_clk_gate_scu("pwm_6_hf_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM6_CLK]		= imx_clk_gate_scu("pwm_6_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM7_DIV]		= imx_clk_divider_scu("pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM7_IPG_S_CLK]	= imx_clk_gate_scu("pwm_7_ipg_s_clk", "pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM7_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_7_ipg_slv_clk", "pwm_7_ipg_s_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM7_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_7_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_7_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM7_HF_CLK]		= imx_clk_gate_scu("pwm_7_hf_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM7_CLK]		= imx_clk_gate_scu("pwm_7_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT0_DIV]		= imx_clk_divider_scu("gpt_0_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT0_IPG_S_CLK]	= imx_clk_gate_scu("gpt_0_ipg_s_clk", "gpt_0_div", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT0_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_0_ipg_slv_clk", "gpt_0_ipg_s_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT0_CLK]		= imx_clk_gate_scu("gpt_0_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT0_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_0_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_0_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_GPT0_HF_CLK]		= imx_clk_gate_scu("gpt_0_hf_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT1_DIV]		= imx_clk_divider_scu("gpt_1_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT1_IPG_S_CLK]	= imx_clk_gate_scu("gpt_1_ipg_s_clk", "gpt_1_div", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT1_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_1_ipg_slv_clk", "gpt_1_ipg_s_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT1_CLK]		= imx_clk_gate_scu("gpt_1_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT1_HF_CLK]		= imx_clk_gate_scu("gpt_1_hf_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT1_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_1_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_1_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_GPT2_DIV]		= imx_clk_divider_scu("gpt_2_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT2_IPG_S_CLK]	= imx_clk_gate_scu("gpt_2_ipg_s_clk", "gpt_2_div", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT2_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_2_ipg_slv_clk", "gpt_2_ipg_s_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT2_CLK]		= imx_clk_gate_scu("gpt_2_clk", "gpt_2_ipg_slv_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT2_HF_CLK]		= imx_clk_gate_scu("gpt_2_hf_clk", "gpt_2_div", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT2_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_2_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_2_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_GPT3_DIV]		= imx_clk_divider_scu("gpt_3_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT3_IPG_S_CLK]	= imx_clk_gate_scu("gpt_3_ipg_s_clk", "gpt_3_div", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT3_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_3_ipg_slv_clk", "gpt_3_ipg_s_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT3_CLK]		= imx_clk_gate_scu("gpt_3_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT3_HF_CLK]		= imx_clk_gate_scu("gpt_3_hf_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT3_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_3_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_3_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_GPT4_DIV]		= imx_clk_divider_scu("gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT4_IPG_S_CLK]	= imx_clk_gate_scu("gpt_4_ipg_s_clk", "gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT4_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_4_ipg_slv_clk", "gpt_4_ipg_s_clk", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT4_CLK]		= imx_clk_gate_scu("gpt_4_clk", "gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT4_HF_CLK]		= imx_clk_gate_scu("gpt_4_hf_clk", "gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT4_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_4_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_4_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_FSPI0_DIV]		= imx_clk_divider_scu("fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_FSPI0_HCLK]		= imx_clk_gate2_scu("fspi0_hclk_clk", "lsio_mem_clk_root", (void __iomem *)(FSPI_0_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_FSPI0_IPG_S_CLK]	= imx_clk_gate2_scu("fspi0_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(FSPI_0_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_FSPI0_IPG_CLK]	= imx_clk_gate2_scu("fspi0_ipg_clk", "fspi0_ipg_s_clk", (void __iomem *)(FSPI_0_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_FSPI0_CLK]		= imx_clk_gate_scu("fspi_0_clk", "fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER, (void __iomem *)(FSPI_0_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_FSPI1_DIV]		= imx_clk_divider_scu("fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_FSPI1_HCLK]		= imx_clk_gate2_scu("fspi1_hclk_clk", "lsio_mem_clk_root", (void __iomem *)(FSPI_1_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_FSPI1_IPG_S_CLK]	= imx_clk_gate2_scu("fspi1_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(FSPI_1_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_FSPI1_IPG_CLK]	= imx_clk_gate2_scu("fspi1_ipg_clk", "fspi1_ipg_s_clk", (void __iomem *)(FSPI_1_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_FSPI1_CLK]		= imx_clk_gate_scu("fspi_1_clk", "fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER, (void __iomem *)(FSPI_1_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPIO0_IPG_S_CLK]	= imx_clk_gate2_scu("gpio0_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_0_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO1_IPG_S_CLK]	= imx_clk_gate2_scu("gpio1_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_1_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO2_IPG_S_CLK]	= imx_clk_gate2_scu("gpio2_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_2_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO3_IPG_S_CLK]	= imx_clk_gate2_scu("gpio3_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_3_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO4_IPG_S_CLK]	= imx_clk_gate2_scu("gpio4_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_4_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO5_IPG_S_CLK]	= imx_clk_gate2_scu("gpio5_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_5_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO6_IPG_S_CLK]	= imx_clk_gate2_scu("gpio6_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_6_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO7_IPG_S_CLK]	= imx_clk_gate2_scu("gpio7_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_7_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_ROMCP_REG_CLK]	= imx_clk_gate2_scu("romcp_reg_clk", "lsio_bus_clk_root", (void __iomem *)(ROMCP_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_ROMCP_CLK]		= imx_clk_gate2_scu("romcp_clk", "lsio_mem_clk_root", (void __iomem *)(ROMCP_LPCG), 0x0, 0);
+	clks[IMX8QXP_LSIO_96KROM_CLK]		= imx_clk_gate2_scu("96krom_clk", "lsio_mem_clk_root", (void __iomem *)(ROMCP_LPCG), 0x4, 0);
+	clks[IMX8QXP_LSIO_OCRAM_MEM_CLK]	= imx_clk_gate2_scu("ocram_lk", "lsio_mem_clk_root", (void __iomem *)(OCRAM_LPCG), 0x4, 0);
+	clks[IMX8QXP_LSIO_OCRAM_CTRL_CLK]	= imx_clk_gate2_scu("ocram_ctrl_clk", "lsio_mem_clk_root", (void __iomem *)(OCRAM_LPCG), 0x0, 0);
+
+	/* ADMA SS */
+	clks[IMX8QXP_UART1_IPG_CLK]	= imx_clk_gate2_scu("uart1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_1_LPCG), 16, 0);
+	clks[IMX8QXP_UART2_IPG_CLK]	= imx_clk_gate2_scu("uart2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_2_LPCG), 16, 0);
+	clks[IMX8QXP_UART3_IPG_CLK]	= imx_clk_gate2_scu("uart3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_3_LPCG), 16, 0);
+	clks[IMX8QXP_UART1_DIV]		= imx_clk_divider_scu("uart1_div", SC_R_UART_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_UART2_DIV]		= imx_clk_divider_scu("uart2_div", SC_R_UART_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_UART3_DIV]		= imx_clk_divider_scu("uart3_div", SC_R_UART_3, SC_PM_CLK_PER);
+	clks[IMX8QXP_UART1_CLK]		= imx_clk_gate_scu("uart1_clk", "uart1_div", SC_R_UART_1, SC_PM_CLK_PER, (void __iomem *)(LPUART_1_LPCG), 0, 0);
+	clks[IMX8QXP_UART2_CLK]		= imx_clk_gate_scu("uart2_clk", "uart2_div", SC_R_UART_2, SC_PM_CLK_PER, (void __iomem *)(LPUART_2_LPCG), 0, 0);
+	clks[IMX8QXP_UART3_CLK]		= imx_clk_gate_scu("uart3_clk", "uart3_div", SC_R_UART_3, SC_PM_CLK_PER, (void __iomem *)(LPUART_3_LPCG), 0, 0);
+	clks[IMX8QXP_SPI0_IPG_CLK]	= imx_clk_gate2_scu("spi0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_0_LPCG), 16, 0);
+	clks[IMX8QXP_SPI1_IPG_CLK]	= imx_clk_gate2_scu("spi1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_1_LPCG), 16, 0);
+	clks[IMX8QXP_SPI2_IPG_CLK]	= imx_clk_gate2_scu("spi2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_2_LPCG), 16, 0);
+	clks[IMX8QXP_SPI3_IPG_CLK]	= imx_clk_gate2_scu("spi3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_3_LPCG), 16, 0);
+	clks[IMX8QXP_SPI0_DIV]		= imx_clk_divider_scu("spi0_div", SC_R_SPI_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_SPI1_DIV]		= imx_clk_divider_scu("spi1_div", SC_R_SPI_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_SPI2_DIV]		= imx_clk_divider_scu("spi2_div", SC_R_SPI_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_SPI3_DIV]		= imx_clk_divider_scu("spi3_div", SC_R_SPI_3, SC_PM_CLK_PER);
+	clks[IMX8QXP_SPI0_CLK]		= imx_clk_gate_scu("spi0_clk", "spi0_div", SC_R_SPI_0, SC_PM_CLK_PER, (void __iomem *)(LPSPI_0_LPCG), 0, 0);
+	clks[IMX8QXP_SPI1_CLK]		= imx_clk_gate_scu("spi1_clk", "spi1_div", SC_R_SPI_2, SC_PM_CLK_PER, (void __iomem *)(LPSPI_1_LPCG), 0, 0);
+	clks[IMX8QXP_SPI2_CLK]		= imx_clk_gate_scu("spi2_clk", "spi2_div", SC_R_SPI_2, SC_PM_CLK_PER, (void __iomem *)(LPSPI_2_LPCG), 0, 0);
+	clks[IMX8QXP_SPI3_CLK]		= imx_clk_gate_scu("spi3_clk", "spi3_div", SC_R_SPI_3, SC_PM_CLK_PER, (void __iomem *)(LPSPI_3_LPCG), 0, 0);
+	clks[IMX8QXP_CAN0_IPG_CHI_CLK]	= imx_clk_gate2_scu("can0_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_0_LPCG), 20, 0);
+	clks[IMX8QXP_CAN0_IPG_CLK]	= imx_clk_gate2_scu("can0_ipg_clk", "can0_ipg_chi_clk", (void __iomem *)(FLEX_CAN_0_LPCG), 16, 0);
+	clks[IMX8QXP_CAN1_IPG_CHI_CLK]	= imx_clk_gate2_scu("can1_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_1_LPCG), 20, 0);
+	clks[IMX8QXP_CAN1_IPG_CLK]	= imx_clk_gate2_scu("can1_ipg_clk", "can1_ipg_chi_clk", (void __iomem *)(FLEX_CAN_1_LPCG), 16, 0);
+	clks[IMX8QXP_CAN2_IPG_CHI_CLK]	= imx_clk_gate2_scu("can2_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_2_LPCG), 20, 0);
+	clks[IMX8QXP_CAN2_IPG_CLK]	= imx_clk_gate2_scu("can2_ipg_clk", "can2_ipg_chi_clk", (void __iomem *)(FLEX_CAN_2_LPCG), 16, 0);
+	clks[IMX8QXP_CAN0_DIV]		= imx_clk_divider_scu("can0_div", SC_R_CAN_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_CAN1_DIV]		= imx_clk_divider_scu("can1_div", SC_R_CAN_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_CAN2_DIV]		= imx_clk_divider_scu("can2_div", SC_R_CAN_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_CAN0_CLK]		= imx_clk_gate_scu("can0_clk", "can0_div", SC_R_CAN_0, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_0_LPCG), 0, 0);
+	clks[IMX8QXP_CAN1_CLK]		= imx_clk_gate_scu("can1_clk", "can1_div", SC_R_CAN_1, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_1_LPCG), 0, 0);
+	clks[IMX8QXP_CAN2_CLK]		= imx_clk_gate_scu("can2_clk", "can2_div", SC_R_CAN_2, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_2_LPCG), 0, 0);
+	clks[IMX8QXP_I2C0_IPG_CLK]	= imx_clk_gate2_scu("i2c0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_0_LPCG), 16, 0);
+	clks[IMX8QXP_I2C1_IPG_CLK]	= imx_clk_gate2_scu("i2c1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_1_LPCG), 16, 0);
+	clks[IMX8QXP_I2C2_IPG_CLK]	= imx_clk_gate2_scu("i2c2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_2_LPCG), 16, 0);
+	clks[IMX8QXP_I2C3_IPG_CLK]	= imx_clk_gate2_scu("i2c3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_3_LPCG), 16, 0);
+	clks[IMX8QXP_I2C0_DIV]		= imx_clk_divider_scu("i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_I2C1_DIV]		= imx_clk_divider_scu("i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_I2C2_DIV]		= imx_clk_divider_scu("i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_I2C3_DIV]		= imx_clk_divider_scu("i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER);
+	clks[IMX8QXP_I2C0_CLK]		= imx_clk_gate_scu("i2c0_clk", "i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER, (void __iomem *)(LPI2C_0_LPCG), 0, 0);
+	clks[IMX8QXP_I2C1_CLK]		= imx_clk_gate_scu("i2c1_clk", "i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER, (void __iomem *)(LPI2C_1_LPCG), 0, 0);
+	clks[IMX8QXP_I2C2_CLK]		= imx_clk_gate_scu("i2c2_clk", "i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER, (void __iomem *)(LPI2C_2_LPCG), 0, 0);
+	clks[IMX8QXP_I2C3_CLK]		= imx_clk_gate_scu("i2c3_clk", "i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER, (void __iomem *)(LPI2C_3_LPCG), 0, 0);
+	clks[IMX8QXP_FTM0_IPG_CLK]	= imx_clk_gate2_scu("ftm0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(FTM_0_LPCG), 16, 0);
+	clks[IMX8QXP_FTM1_IPG_CLK]	= imx_clk_gate2_scu("ftm1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(FTM_1_LPCG), 16, 0);
+	clks[IMX8QXP_FTM0_DIV]		= imx_clk_divider_scu("ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_FTM1_DIV]		= imx_clk_divider_scu("ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_FTM0_CLK]		= imx_clk_gate_scu("ftm0_clk", "ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER, (void __iomem *)(FTM_0_LPCG), 0, 0);
+	clks[IMX8QXP_FTM1_CLK]		= imx_clk_gate_scu("ftm1_clk", "ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER, (void __iomem *)(FTM_1_LPCG), 0, 0);
+	clks[IMX8QXP_ADC0_IPG_CLK]	= imx_clk_gate2_scu("adc0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(ADC_0_LPCG), 16, 0);
+	clks[IMX8QXP_ADC0_DIV]		= imx_clk_divider_scu("adc0_div", SC_R_ADC_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_ADC0_CLK]		= imx_clk_gate_scu("adc0_clk", "adc0_div", SC_R_ADC_0, SC_PM_CLK_PER, (void __iomem *)(ADC_0_LPCG), 0, 0);
+	clks[IMX8QXP_PWM_IPG_CLK]	= imx_clk_gate2_scu("pwm_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(PWM_LPCG), 16, 0);
+	clks[IMX8QXP_PWM_DIV]		= imx_clk_divider_scu("pwm_div", SC_R_LCD_0_PWM_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_PWM_CLK]		= imx_clk_gate_scu("pwm_clk", "pwm_div", SC_R_LCD_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_LPCG), 0, 0);
+	clks[IMX8QXP_LCD_IPG_CLK]	= imx_clk_gate2_scu("lcd_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LCD_LPCG), 16, 0);
+	clks[IMX8QXP_LCD_DIV]		= imx_clk_divider_scu("lcd_div", SC_R_LCD_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_LCD_CLK]		= imx_clk_gate_scu("lcd_clk", "lcd_div", SC_R_LCD_0, SC_PM_CLK_PER, (void __iomem *)(LCD_LPCG), 0, 0);
+
+	/* Connectivity */
+	clks[IMX8QXP_SDHC0_IPG_CLK]	= imx_clk_gate2_scu("sdhc0_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_0_LPCG), 16, 0);
+	clks[IMX8QXP_SDHC1_IPG_CLK]	= imx_clk_gate2_scu("sdhc1_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_1_LPCG), 16, 0);
+	clks[IMX8QXP_SDHC2_IPG_CLK]	= imx_clk_gate2_scu("sdhc2_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_2_LPCG), 16, 0);
+	clks[IMX8QXP_SDHC0_DIV]		= imx_clk_divider_scu("sdhc0_div", SC_R_SDHC_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_SDHC1_DIV]		= imx_clk_divider_scu("sdhc1_div", SC_R_SDHC_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_SDHC2_DIV]		= imx_clk_divider_scu("sdhc2_div", SC_R_SDHC_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_SDHC0_CLK]		= imx_clk_gate_scu("sdhc0_clk", "sdhc0_div", SC_R_SDHC_0, SC_PM_CLK_PER, (void __iomem *)(USDHC_0_LPCG), 0, 0);
+	clks[IMX8QXP_SDHC1_CLK]		= imx_clk_gate_scu("sdhc1_clk", "sdhc1_div", SC_R_SDHC_1, SC_PM_CLK_PER, (void __iomem *)(USDHC_1_LPCG), 0, 0);
+	clks[IMX8QXP_SDHC2_CLK]		= imx_clk_gate_scu("sdhc2_clk", "sdhc1_div", SC_R_SDHC_2, SC_PM_CLK_PER, (void __iomem *)(USDHC_2_LPCG), 0, 0);
+	clks[IMX8QXP_ENET0_ROOT_DIV]	= imx_clk_divider_scu("enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_ENET0_REF_DIV]	= imx_clk_divider_gpr_scu("enet0_ref_div", "enet0_root_clk", SC_R_ENET_0, SC_C_CLKDIV);
+	clks[IMX8QXP_ENET1_REF_DIV]	= imx_clk_divider_gpr_scu("enet1_ref_div", "enet1_root_clk", SC_R_ENET_1, SC_C_CLKDIV);
+	clks[IMX8QXP_ENET0_BYPASS_DIV]	= imx_clk_divider_scu("enet0_bypass_div", SC_R_ENET_0, SC_PM_CLK_BYPASS);
+	clks[IMX8QXP_ENET0_RGMII_DIV]	= imx_clk_divider_scu("enet0_rgmii_div", SC_R_ENET_0, SC_PM_CLK_MISC0);
+	clks[IMX8QXP_ENET1_ROOT_DIV]	= imx_clk_divider_scu("enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_ENET1_BYPASS_DIV]	= imx_clk_divider_scu("enet1_bypass_div", SC_R_ENET_1, SC_PM_CLK_BYPASS);
+	clks[IMX8QXP_ENET1_RGMII_DIV]	= imx_clk_divider_scu("enet1_rgmii_div", SC_R_ENET_1, SC_PM_CLK_MISC0);
+	clks[IMX8QXP_ENET0_AHB_CLK]	= imx_clk_gate2_scu("enet0_ahb_clk", "axi_conn_clk_root", (void __iomem *)(ENET_0_LPCG), 8, 0);
+	clks[IMX8QXP_ENET0_IPG_S_CLK]	= imx_clk_gate2_scu("enet0_ipg_s_clk", "ipg_conn_clk_root", (void __iomem *)(ENET_0_LPCG), 20, 0);
+	clks[IMX8QXP_ENET0_IPG_CLK]	= imx_clk_gate2_scu("enet0_ipg_clk", "enet0_ipg_s_clk", (void __iomem *)(ENET_0_LPCG), 16, 0);
+	clks[IMX8QXP_ENET1_AHB_CLK]	= imx_clk_gate2_scu("enet1_ahb_clk", "axi_conn_clk_root", (void __iomem *)(ENET_1_LPCG), 8, 0);
+	clks[IMX8QXP_ENET1_IPG_S_CLK]	= imx_clk_gate2_scu("enet1_ipg_s_clk", "ipg_conn_clk_root", (void __iomem *)(ENET_1_LPCG), 20, 0);
+	clks[IMX8QXP_ENET1_IPG_CLK]	= imx_clk_gate2_scu("enet1_ipg_clk", "enet1_ipg_s_clk", (void __iomem *)(ENET_1_LPCG), 16, 0);
+	clks[IMX8QXP_ENET0_ROOT_CLK]	= imx_clk_gate_scu("enet0_root_clk", "enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER, NULL, 0, 0);
+	clks[IMX8QXP_ENET1_ROOT_CLK]	= imx_clk_gate_scu("enet1_root_clk", "enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER, NULL, 0, 0);
+	clks[IMX8QXP_ENET0_TX_CLK]	= imx_clk_gate2_scu("enet0_tx_2x_clk", "enet0_root_div", (void __iomem *)(ENET_0_LPCG), 4, 0);
+	clks[IMX8QXP_ENET1_TX_CLK]	= imx_clk_gate2_scu("enet1_tx_2x_clk", "enet1_root_div", (void __iomem *)(ENET_1_LPCG), 4, 0);
+	clks[IMX8QXP_ENET0_PTP_CLK]	= imx_clk_gate2_scu("enet0_ptp_clk", "enet0_ref_div", (void __iomem *)(ENET_0_LPCG), 0, 0);
+	clks[IMX8QXP_ENET1_PTP_CLK]	= imx_clk_gate2_scu("enet1_ptp_clk", "enet1_ref_div", (void __iomem *)(ENET_1_LPCG), 0, 0);
+	clks[IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet0_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_0, SC_C_SEL_125);
+	clks[IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet1_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_1, SC_C_SEL_125);
+	clks[IMX8QXP_ENET0_RMII_TX_SEL]	= imx_clk_mux_gpr_scu("enet0_rmii_tx_sel", enet0_rmii_tx_sels, ARRAY_SIZE(enet0_rmii_tx_sels), SC_R_ENET_0, SC_C_TXCLK);
+	clks[IMX8QXP_ENET1_RMII_TX_SEL]	= imx_clk_mux_gpr_scu("enet1_rmii_tx_sel", enet1_rmii_tx_sels, ARRAY_SIZE(enet1_rmii_tx_sels), SC_R_ENET_1, SC_C_TXCLK);
+	clks[IMX8QXP_ENET0_RGMII_TX_CLK] = imx_clk_gate2_scu("enet0_rgmii_tx_clk", "enet0_rmii_tx_sel", (void __iomem *)(ENET_0_LPCG), 12, 0);
+	clks[IMX8QXP_ENET1_RGMII_TX_CLK] = imx_clk_gate2_scu("enet1_rgmii_tx_clk", "enet1_rmii_tx_sel", (void __iomem *)(ENET_1_LPCG), 12, 0);
+	clks[IMX8QXP_ENET0_RMII_RX_CLK]	= imx_clk_gate2_scu("enet0_rgmii_rx_clk", "enet0_rgmii_div", (void __iomem *)(ENET_0_LPCG + 0x4), 0, 0);
+	clks[IMX8QXP_ENET1_RMII_RX_CLK]	= imx_clk_gate2_scu("enet1_rgmii_rx_clk", "enet1_rgmii_div", (void __iomem *)(ENET_1_LPCG + 0x4), 0, 0);
+	clks[IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK] = imx_clk_gate_gpr_scu("enet0_ref_25_125_clk", "enet0_ref_25_125_sel", SC_R_ENET_0, SC_C_DISABLE_125, true);
+	clks[IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK] = imx_clk_gate_gpr_scu("enet1_ref_25_125_clk", "enet1_ref_25_125_sel", SC_R_ENET_1, SC_C_DISABLE_125, true);
+	clks[IMX8QXP_ENET0_REF_50MHZ_CLK] = imx_clk_gate_gpr_scu("enet0_ref_50_clk", NULL, SC_R_ENET_0, SC_C_DISABLE_50, true);
+	clks[IMX8QXP_ENET1_REF_50MHZ_CLK] = imx_clk_gate_gpr_scu("enet1_ref_50_clk", NULL, SC_R_ENET_1, SC_C_DISABLE_50, true);
+	clks[IMX8QXP_GPMI_BCH_IO_DIV]	= imx_clk_divider_scu("gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS);
+	clks[IMX8QXP_GPMI_BCH_DIV]	= imx_clk_divider_scu("gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER);
+	clks[IMX8QXP_GPMI_APB_CLK]	= imx_clk_gate2_scu("gpmi_apb_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG), 16, 0);
+	clks[IMX8QXP_GPMI_APB_BCH_CLK]	= imx_clk_gate2_scu("gpmi_apb_bch_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG), 20, 0);
+	clks[IMX8QXP_GPMI_BCH_IO_CLK]	= imx_clk_gate_scu("gpmi_io_clk", "gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS, (void __iomem *)(NAND_LPCG), 4, 0);
+	clks[IMX8QXP_GPMI_BCH_CLK]	= imx_clk_gate_scu("gpmi_bch_clk", "gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER, (void __iomem *)(NAND_LPCG), 0, 0);
+	clks[IMX8QXP_APBHDMA_CLK]	= imx_clk_gate2_scu("gpmi_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG + 0x4), 16, 0);
+	clks[IMX8QXP_USB3_ACLK_DIV]	= imx_clk_divider_scu("usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_USB3_BUS_DIV]	= imx_clk_divider_scu("usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS);
+	clks[IMX8QXP_USB3_LPM_DIV]	= imx_clk_divider_scu("usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC);
+	clks[IMX8QXP_USB2_OH_AHB_CLK]	= imx_clk_gate2_scu("usboh3", "ahb_conn_clk_root", (void __iomem *)(USB_2_LPCG), 24, 0);
+	clks[IMX8QXP_USB2_OH_IPG_S_CLK]	= imx_clk_gate2_scu("usboh3_ipg_s", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 16, 0);
+	clks[IMX8QXP_USB2_OH_IPG_S_PL301_CLK] = imx_clk_gate2_scu("usboh3_ipg_pl301_s", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 20, 0);
+	clks[IMX8QXP_USB2_PHY_IPG_CLK]	= imx_clk_gate2_scu("usboh3_phy_clk", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 28, 0);
+	clks[IMX8QXP_USB3_IPG_CLK]	= imx_clk_gate2_scu("usb3_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USB_3_LPCG), 16, 0);
+	clks[IMX8QXP_USB3_CORE_PCLK]	= imx_clk_gate2_scu("usb3_core_clk", "ipg_conn_clk_root", (void __iomem *)(USB_3_LPCG), 20, 0);
+	clks[IMX8QXP_USB3_PHY_CLK]	= imx_clk_gate2_scu("usb3_phy_clk", "usb3_ipg_clk", (void __iomem *)(USB_3_LPCG), 24, 0);
+	clks[IMX8QXP_USB3_ACLK]		= imx_clk_gate_scu("usb3_aclk", "usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER, (void __iomem *)(USB_3_LPCG), 28, 0);
+	clks[IMX8QXP_USB3_BUS_CLK]	= imx_clk_gate_scu("usb3_bus_clk", "usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS, (void __iomem *)(USB_3_LPCG), 0, 0);
+	clks[IMX8QXP_USB3_LPM_CLK]	= imx_clk_gate_scu("usb3_lpm_clk", "usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC, (void __iomem *)(USB_3_LPCG), 4, 0);
+	clks[IMX8QXP_EDMA_CLK]		= imx_clk_gate2_scu("edma_clk", "axi_conn_clk_root", (void __iomem *)(EDMA_LPCG), 0, 0);
+	clks[IMX8QXP_EDMA_IPG_CLK]	= imx_clk_gate2_scu("edma_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(EDMA_LPCG), 16, 0);
+	clks[IMX8QXP_MLB_HCLK]		= imx_clk_gate2_scu("mlb_hclk", "axi_conn_clk_root", (void __iomem *)(MLB_LPCG), 20, 0);
+	clks[IMX8QXP_MLB_CLK]		= imx_clk_gate2_scu("mlb_clk", "mlb_hclk", (void __iomem *)(MLB_LPCG), 0, 0);
+	clks[IMX8QXP_MLB_IPG_CLK]	= imx_clk_gate2_scu("mlb_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(MLB_LPCG), 16, 0);
+
+	/* Display controller - DC0 SS */
+	clks[IMX8QXP_DC0_DISP0_CLK]	= imx_clk_gate_scu("dc0_disp0_clk", "dc0_disp0_div", SC_R_DC_0, SC_PM_CLK_MISC0, (void __iomem *)(DC_0_LPCG), 0, 0);
+	clks[IMX8QXP_DC0_DISP1_CLK]	= imx_clk_gate_scu("dc0_disp1_clk", "dc0_disp1_div", SC_R_DC_0, SC_PM_CLK_MISC1, (void __iomem *)(DC_0_LPCG), 4, 0);
+	clks[IMX8QXP_DC0_PRG0_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg0_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x20), 0, 0);
+	clks[IMX8QXP_DC0_PRG0_APB_CLK]	= imx_clk_gate2_scu("dc0_prg0_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x20), 16, 0);
+	clks[IMX8QXP_DC0_PRG1_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg1_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x24), 0, 0);
+	clks[IMX8QXP_DC0_PRG1_APB_CLK]	= imx_clk_gate2_scu("dc0_prg1_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x24), 16, 0);
+	clks[IMX8QXP_DC0_PRG2_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg2_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x28), 0, 0);
+	clks[IMX8QXP_DC0_PRG2_APB_CLK]	= imx_clk_gate2_scu("dc0_prg2_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x28), 16, 0);
+	clks[IMX8QXP_DC0_PRG3_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg3_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x34), 0, 0);
+	clks[IMX8QXP_DC0_PRG3_APB_CLK]	= imx_clk_gate2_scu("dc0_prg3_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x34), 16, 0);
+	clks[IMX8QXP_DC0_PRG4_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg4_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x38), 0, 0);
+	clks[IMX8QXP_DC0_PRG4_APB_CLK]	= imx_clk_gate2_scu("dc0_prg4_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x38), 16, 0);
+	clks[IMX8QXP_DC0_PRG5_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg5_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x3c), 0, 0);
+	clks[IMX8QXP_DC0_PRG5_APB_CLK]	= imx_clk_gate2_scu("dc0_prg5_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x3c), 16, 0);
+	clks[IMX8QXP_DC0_PRG6_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg6_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x40), 0, 0);
+	clks[IMX8QXP_DC0_PRG6_APB_CLK]	= imx_clk_gate2_scu("dc0_prg6_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x40), 16, 0);
+	clks[IMX8QXP_DC0_PRG7_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg7_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x44), 0, 0);
+	clks[IMX8QXP_DC0_PRG7_APB_CLK]	= imx_clk_gate2_scu("dc0_prg7_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x44), 16, 0);
+	clks[IMX8QXP_DC0_PRG8_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg8_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x48), 0, 0);
+	clks[IMX8QXP_DC0_PRG8_APB_CLK]	= imx_clk_gate2_scu("dc0_prg8_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x48), 16, 0);
+	clks[IMX8QXP_DC0_DPR0_APB_CLK]	= imx_clk_gate2_scu("dc0_dpr0_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x18), 16, 0);
+	clks[IMX8QXP_DC0_DPR0_B_CLK]	= imx_clk_gate2_scu("dc0_dpr0_b_clk", "axi_ext_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x18), 20, 0);
+	clks[IMX8QXP_DC0_RTRAM0_CLK]	= imx_clk_gate2_scu("dc0_rtrm0_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x1C), 0, 0);
+	clks[IMX8QXP_DC0_RTRAM1_CLK]	= imx_clk_gate2_scu("dc0_rtrm1_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x30), 0, 0);
+
+	/* Display interface - MIPI-LVDS SS */
+	clks[IMX8QXP_MIPI0_I2C0_DIV]	= imx_clk_divider_scu("mipi_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2);
+	clks[IMX8QXP_MIPI0_I2C1_DIV]	= imx_clk_divider_scu("mipi_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2);
+	clks[IMX8QXP_MIPI0_I2C0_CLK]	= imx_clk_gate_scu("mipi_i2c0_clk", "mipi_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI0_LPCG + 0x14), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C1_CLK]	= imx_clk_gate_scu("mipi_i2c1_clk", "mipi_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI0_LPCG + 0x14), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C0_IPG_S_CLK] = imx_clk_gate2_scu("mipi_i2c0_ipg_s", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x10), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C0_IPG_CLK]	= imx_clk_gate2_scu("mipi_i2c0_ipg_clk", "mipi_i2c0_ipg_s", (void __iomem *)(DI_MIPI0_LPCG), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C1_IPG_S_CLK] = imx_clk_gate2_scu("mipi_i2c1_ipg_s", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x14), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C1_IPG_CLK]	= imx_clk_gate2_scu("mipi_i2c1_ipg_clk", "mipi_i2c1_ipg_s", (void __iomem *)(DI_MIPI0_LPCG), 0, 0);
+	clks[IMX8QXP_MIPI0_PWM_IPG_S_CLK] = imx_clk_gate2_scu("mipi_pwm_ipg_s", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 0, 0);
+	clks[IMX8QXP_MIPI0_PWM_IPG_CLK]	= imx_clk_gate2_scu("mipi_pwm_ipg_clk", "mipi_pwm_ipg_s", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 0, 0);
+	clks[IMX8QXP_MIPI0_PWM_32K_CLK]	= imx_clk_gate2_scu("mipi_pwm_32K_clk", "xtal_32KHz", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 0, 0);
+	clks[IMX8QXP_MIPI0_GPIO_IPG_CLK]	= imx_clk_gate2_scu("mipi_gpio_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x8), 0, 0);
+
+	/* Imaging SS */
+	clks[IMX8QXP_IMG_JPEG_ENC_IPG_CLK]	= imx_clk_gate2_scu("img_jpeg_enc_ipg_clk", "ipg_img_clk_root", (void __iomem *)(IMG_JPEG_ENC_LPCG), 16, 0);
+	clks[IMX8QXP_IMG_JPEG_ENC_CLK]		= imx_clk_gate2_scu("img_jpeg_enc_clk", "img_jpeg_enc_ipg_clk", (void __iomem *)(IMG_JPEG_ENC_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_JPEG_DEC_IPG_CLK]	= imx_clk_gate2_scu("img_jpeg_dec_ipg_clk", "ipg_img_clk_root", (void __iomem *)(IMG_JPEG_DEC_LPCG), 16, 0);
+	clks[IMX8QXP_IMG_JPEG_DEC_CLK]		= imx_clk_gate2_scu("img_jpeg_dec_clk", "img_jpeg_dec_ipg_clk", (void __iomem *)(IMG_JPEG_DEC_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_DC0_CLK]	= imx_clk_gate2_scu("img_pxl_link_dc0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_DC0_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_DC1_CLK]	= imx_clk_gate2_scu("img_pxl_link_dc1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_DC1_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_CSI0_CLK]	= imx_clk_gate2_scu("img_pxl_link_csi0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_CSI0_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_CSI1_CLK]	= imx_clk_gate2_scu("img_pxl_link_csi1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_CSI1_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_HDMI_IN_CLK]	= imx_clk_gate2_scu("img_pxl_link_hdmi_in_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_HDMI_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_0_CLK]		= imx_clk_gate2_scu("img_pdma0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_0_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_1_CLK]		= imx_clk_gate2_scu("img_pdma1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_1_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_2_CLK]		= imx_clk_gate2_scu("img_pdma2_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_2_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_3_CLK]		= imx_clk_gate2_scu("img_pdma3_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_3_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_4_CLK]		= imx_clk_gate2_scu("img_pdma4_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_4_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_5_CLK]		= imx_clk_gate2_scu("img_pdma5_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_5_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_6_CLK]		= imx_clk_gate2_scu("img_pdma6_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_6_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_7_CLK]		= imx_clk_gate2_scu("img_pdma7_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_7_LPCG), 0, 0);
+
+	/* MIPI CSI SS */
+	clks[IMX8QXP_CSI0_I2C0_DIV]	= imx_clk_divider_scu("mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_CSI0_PWM0_DIV]	= imx_clk_divider_scu("mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_CSI0_CORE_DIV]	= imx_clk_divider_scu("mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_CSI0_ESC_DIV]	= imx_clk_divider_scu("mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC);
+	clks[IMX8QXP_CSI0_IPG_CLK_S]	= imx_clk_gate2_scu("mipi_csi0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x8), 16, 0);
+	clks[IMX8QXP_CSI0_IPG_CLK]	= imx_clk_gate2_scu("mipi_csi0_ipg", "mipi_csi0_ipg_s", (void __iomem *)(MIPI_CSI_0_LPCG), 16, 0);
+	clks[IMX8QXP_CSI0_APB_CLK]	= imx_clk_gate2_scu("mipi_csi0_apb_clk", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x4), 16,  0);
+	clks[IMX8QXP_CSI0_I2C0_IPG_CLK]	= imx_clk_gate2_scu("mipi_csi0_i2c0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x14), 16, 0);
+	clks[IMX8QXP_CSI0_I2C0_CLK]	= imx_clk_gate_scu("mipi_csi0_i2c0_clk", "mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x14), 0, 0);
+	clks[IMX8QXP_CSI0_PWM0_IPG_CLK]	= imx_clk_gate2_scu("mipi_csi0_pwm0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x10), 16, 0);
+	clks[IMX8QXP_CSI0_PWM0_CLK]	= imx_clk_gate_scu("mipi_csi0_pwm0_clk", "mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x10), 0, 0);
+	clks[IMX8QXP_CSI0_CORE_CLK]	= imx_clk_gate_scu("mipi_csi0_core_clk", "mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x18), 16, 0);
+	clks[IMX8QXP_CSI0_ESC_CLK]	= imx_clk_gate_scu("mipi_csi0_esc_clk", "mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC, (void __iomem *)(MIPI_CSI_0_LPCG + 0x1C), 16, 0);
+
+	/* HSIO SS */
+	clks[IMX8QXP_HSIO_PCIE_MSTR_AXI_CLK]	= imx_clk_gate2_scu("hsio_pcie_mstr_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_PCIE_SLV_AXI_CLK]	= imx_clk_gate2_scu("hsio_pcie_slv_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 20, 0);
+	clks[IMX8QXP_HSIO_PCIE_DBI_AXI_CLK]	= imx_clk_gate2_scu("hsio_pcie_dbi_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 24, 0);
+	clks[IMX8QXP_HSIO_PCIE_X1_PER_CLK]	= imx_clk_gate2_scu("hsio_pcie_x1_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_CRR3_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_PHY_X1_PER_CLK]	= imx_clk_gate2_scu("hsio_phy_x1_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PHY_X1_CRR1_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_MISC_PER_CLK]		= imx_clk_gate2_scu("hsio_misc_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_MISC_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_PHY_X1_APB_CLK]	= imx_clk_gate2_scu("hsio_phy_x1_apb_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PHY_X1_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_GPIO_CLK]		= imx_clk_gate2_scu("hsio_gpio_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_GPIO_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_PHY_X1_PCLK]		= imx_clk_gate2_scu("hsio_phy_x1_pclk", "dummy", (void __iomem *)(HSIO_PHY_X1_LPCG), 0, 0);
+
+	imx_check_clk_hws(clks, clk_data->num);
+
+	of_clk_add_hw_provider(ccm_node, of_clk_hw_onecell_get, clk_data);
+
+	pr_info("i.MX8QXP clock tree init done.\n");
+
+	return 0;
+}
+
+static const struct of_device_id imx8qxp_match[] = {
+	{ .compatible = "fsl,imx8qxp-clk", },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver imx8qxp_clk_driver = {
+	.driver = {
+		.name = "imx8qxp-clk",
+		.of_match_table = imx8qxp_match,
+	},
+	.probe = imx8qxp_clk_probe,
+};
+
+static int __init imx8qxp_clk_init(void)
+{
+	return platform_driver_register(&imx8qxp_clk_driver);
+}
+core_initcall(imx8qxp_clk_init);
diff --git a/include/soc/imx/imx8qxp/lpcg.h b/include/soc/imx/imx8qxp/lpcg.h
new file mode 100644
index 0000000..afbb5da
--- /dev/null
+++ b/include/soc/imx/imx8qxp/lpcg.h
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *
+ */
+
+#ifndef _SC_LPCG_H
+#define _SC_LPCG_H
+
+/*LSIO SS */
+#define		PWM_0_LPCG		0x5D400000
+#define		PWM_1_LPCG		0x5D410000
+#define		PWM_2_LPCG		0x5D420000
+#define		PWM_3_LPCG		0x5D430000
+#define		PWM_4_LPCG		0x5D440000
+#define		PWM_5_LPCG		0x5D450000
+#define		PWM_6_LPCG		0x5D460000
+#define		PWM_7_LPCG		0x5D470000
+#define		GPIO_0_LPCG		0x5D480000
+#define		GPIO_1_LPCG		0x5D490000
+#define		GPIO_2_LPCG		0x5D4A0000
+#define		GPIO_3_LPCG		0x5D4B0000
+#define		GPIO_4_LPCG		0x5D4C0000
+#define		GPIO_5_LPCG		0x5D4D0000
+#define		GPIO_6_LPCG		0x5D4E0000
+#define		GPIO_7_LPCG		0x5D4F0000
+#define		FSPI_0_LPCG		0x5D520000
+#define		FSPI_1_LPCG		0x5D530000
+#define		GPT_0_LPCG		0x5D540000
+#define		GPT_1_LPCG		0x5D550000
+#define		GPT_2_LPCG		0x5D560000
+#define		GPT_3_LPCG		0x5D570000
+#define		GPT_4_LPCG		0x5D580000
+#define		OCRAM_LPCG		0x5D590000
+#define		KPP_LPCG		0x5D5A0000
+#define		ROMCP_LPCG		0x5D500000
+
+/* HSIO SS */
+#define		CRR_5_LPCG		0x5F0F0000
+#define		CRR_4_LPCG		0x5F0E0000
+#define		CRR_3_LPCG		0x5F0D0000
+#define		CRR_2_LPCG		0x5F0C0000
+#define		CRR_1_LPCG		0x5F0B0000
+#define		CRR_0_LPCG		0x5F0A0000
+#define		PHY_1_LPCG		0x5F090000
+#define		PHY_2_LPCG		0x5F080000
+#define		SATA_0_LPCG		0x5F070000
+#define		PCIE_B_LPCG		0x5F060000
+#define		PCIE_A_LPCG		0x5F050000
+
+/* DMA SS */
+#define		FLEX_CAN_2_LPCG		0x5ACF0000
+#define		FLEX_CAN_1_LPCG		0x5ACE0000
+#define		FLEX_CAN_0_LPCG		0x5ACD0000
+#define		FTM_1_LPCG		0x5ACB0000
+#define		FTM_0_LPCG		0x5ACA0000
+#define		ADC_0_LPCG		0x5AC80000
+#define		LPI2C_3_LPCG		0x5AC30000
+#define		LPI2C_2_LPCG		0x5AC20000
+#define		LPI2C_1_LPCG		0x5AC10000
+#define		LPI2C_0_LPCG		0x5AC00000
+#define		PWM_LPCG		0x5A590000
+#define		LCD_LPCG		0x5A580000
+#define		LPUART_3_LPCG		0x5A490000
+#define		LPUART_2_LPCG		0x5A480000
+#define		LPUART_1_LPCG		0x5A470000
+#define		LPUART_0_LPCG		0x5A460000
+#define		LPSPI_3_LPCG		0x5A430000
+#define		LPSPI_2_LPCG		0x5A420000
+#define		LPSPI_1_LPCG		0x5A410000
+#define		LPSPI_0_LPCG		0x5A400000
+
+/* Display SS */
+#define		DC_0_LPCG		0x56010000
+#define		DC_1_LPCG		0x57010000
+
+/* LVDS */
+#define		DI_LVDS_0_LPCG		0x56243000
+#define		DI_LVDS_1_LPCG		0x57243000
+
+/* DI HDMI */
+#define		DI_HDMI_LPCG		0x56263000
+
+/* RX-HDMI */
+#define		RX_HDMI_LPCG		0x58263000
+
+/* MIPI CSI SS */
+#define		MIPI_CSI_0_LPCG		0x58223000
+#define		MIPI_CSI_1_LPCG		0x58243000
+
+/* PARALLEL CSI SS */
+#define		PARALLEL_CSI_LPCG	0x58263000
+
+/* Display MIPI SS */
+#define		DI_MIPI0_LPCG		0x56223000
+#define		DI_MIPI1_LPCG		0x56243000
+
+/* Imaging SS */
+#define		IMG_JPEG_ENC_LPCG	0x585F0000
+#define		IMG_JPEG_DEC_LPCG	0x585D0000
+#define		IMG_PXL_LINK_DC1_LPCG	0x585C0000
+#define		IMG_PXL_LINK_DC0_LPCG	0x585B0000
+#define		IMG_PXL_LINK_HDMI_LPCG	0x585A0000
+#define		IMG_PXL_LINK_CSI1_LPCG	0x58590000
+#define		IMG_PXL_LINK_CSI0_LPCG	0x58580000
+#define		IMG_PDMA_7_LPCG		0x58570000
+#define		IMG_PDMA_6_LPCG		0x58560000
+#define		IMG_PDMA_5_LPCG		0x58550000
+#define		IMG_PDMA_4_LPCG		0x58540000
+#define		IMG_PDMA_3_LPCG		0x58530000
+#define		IMG_PDMA_2_LPCG		0x58520000
+#define		IMG_PDMA_1_LPCG		0x58510000
+#define		IMG_PDMA_0_LPCG		0x58500000
+
+/* HSIO SS */
+#define		HSIO_GPIO_LPCG		0x5F100000
+#define		HSIO_MISC_LPCG		0x5F0F0000
+#define		HSIO_SATA_CRR4_LPCG	0x5F0E0000
+#define		HSIO_PCIE_X1_CRR3_LPCG	0x5F0D0000
+#define		HSIO_PCIE_X2_CRR2_LPCG	0x5F0C0000
+#define		HSIO_PHY_X1_CRR1_LPCG	0x5F0B0000
+#define		HSIO_PHY_X2_CRR0_LPCG	0x5F0A0000
+#define		HSIO_PHY_X1_LPCG	0x5F090000
+#define		HSIO_PHY_X2_LPCG	0x5F080000
+#define		HSIO_SATA_LPCG		0x5F070000
+#define		HSIO_PCIE_X1_LPCG	0x5F060000
+#define		HSIO_PCIE_X2_LPCG	0x5F050000
+
+/* M4 SS */
+#define		M4_0_I2C_LPCG		0x37630000
+#define		M4_0_LPUART_LPCG	0x37620000
+#define		M4_0_LPIT_LPCG		0x37610000
+#define		M4_1_I2C_LPCG		0x3B630000
+#define		M4_1_LPUART_LPCG	0x3B620000
+#define		M4_1_LPIT_LPCG		0x3B610000
+
+/* Audio SS */
+#define		AUD_ASRC_0_LPCG		0x59400000
+#define		AUD_ESAI_0_LPCG		0x59410000
+#define		AUD_SPDIF_0_LPCG	0x59420000
+#define		AUD_SAI_0_LPCG		0x59440000
+#define		AUD_SAI_1_LPCG		0x59450000
+#define		AUD_SAI_2_LPCG		0x59460000
+#define		AUD_SAI_3_LPCG		0x59470000
+#define		AUD_GPT_5_LPCG		0x594B0000
+#define		AUD_GPT_6_LPCG		0x594C0000
+#define		AUD_GPT_7_LPCG		0x594D0000
+#define		AUD_GPT_8_LPCG		0x594E0000
+#define		AUD_GPT_9_LPCG		0x594F0000
+#define		AUD_GPT_10_LPCG		0x59500000
+#define		AUD_HIFI_LPCG		0x59580000
+#define		AUD_OCRAM_LPCG		0x59590000
+#define		AUD_EDMA_0_LPCG		0x595f0000
+#define		AUD_ASRC_1_LPCG		0x59c00000
+#define		AUD_SAI_4_LPCG		0x59c20000
+#define		AUD_SAI_5_LPCG		0x59c30000
+#define		AUD_AMIX_LPCG		0x59c40000
+#define		AUD_MQS_LPCG		0x59c50000
+#define		AUD_ACM_LPCG		0x59c60000
+#define		AUD_REC_CLK0_LPCG	0x59d00000
+#define		AUD_REC_CLK1_LPCG	0x59d10000
+#define		AUD_PLL_CLK0_LPCG	0x59d20000
+#define		AUD_PLL_CLK1_LPCG	0x59d30000
+#define		AUD_MCLKOUT0_LPCG	0x59d50000
+#define		AUD_MCLKOUT1_LPCG	0x59d60000
+#define		AUD_EDMA_1_LPCG		0x59df0000
+
+
+/* Connectivity SS */
+#define		USDHC_0_LPCG		0x5B200000
+#define		USDHC_1_LPCG		0x5B210000
+#define		USDHC_2_LPCG		0x5B220000
+#define		ENET_0_LPCG		0x5B230000
+#define		ENET_1_LPCG		0x5B240000
+#define		DTCP_LPCG		0x5B250000
+#define		MLB_LPCG		0x5B260000
+#define		USB_2_LPCG		0x5B270000
+#define		USB_3_LPCG		0x5B280000
+#define		NAND_LPCG		0x5B290000
+#define		EDMA_LPCG		0x5B2A0000
+
+/* CM40 SS */
+#define		CM40_I2C_LPCG		0x37630000
+
+#endif
-- 
2.7.4

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

* [PATCH V2 11/11] clk: imx: add imx8qxp clk driver
@ 2018-09-25 16:43   ` Dong Aisheng
  0 siblings, 0 replies; 24+ messages in thread
From: Dong Aisheng @ 2018-09-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Add imx8qxp clk driver which is based on SCU firmware clock service.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v1->v2:
 * no changes except headfile name updated
---
 drivers/clk/imx/scu/Makefile      |   2 +
 drivers/clk/imx/scu/clk-imx8qxp.c | 426 ++++++++++++++++++++++++++++++++++++++
 include/soc/imx/imx8qxp/lpcg.h    | 186 +++++++++++++++++
 3 files changed, 614 insertions(+)
 create mode 100644 drivers/clk/imx/scu/clk-imx8qxp.c
 create mode 100644 include/soc/imx/imx8qxp/lpcg.h

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index a76ed78..68e2d7f 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -8,3 +8,5 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-gate-gpr-scu.o \
 	clk-mux-scu.o \
 	clk-mux-gpr-scu.o
+
+obj-$(CONFIG_SOC_IMX8QXP)	+= clk-imx8qxp.o
diff --git a/drivers/clk/imx/scu/clk-imx8qxp.c b/drivers/clk/imx/scu/clk-imx8qxp.c
new file mode 100644
index 0000000..1a55757
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-imx8qxp.c
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <dt-bindings/clock/imx8qxp-clock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <soc/imx/imx8qxp/lpcg.h>
+#include <soc/imx/scu/sci.h>
+
+#include "clk-scu.h"
+
+static struct clk_hw_onecell_data *clk_data;
+
+static const char * const enet_sels[] = { "enet_25MHz", "enet_125MHz", };
+static const char * const enet0_rmii_tx_sels[] = { "enet0_ref_div", "dummy", };
+static const char * const enet1_rmii_tx_sels[] = { "enet1_ref_div", "dummy", };
+
+static int imx8qxp_clk_probe(struct platform_device *pdev)
+{
+	struct device_node *ccm_node = pdev->dev.of_node;
+	struct clk_hw **clks;
+	int ret;
+
+	ret = imx_clk_scu_init();
+	if (ret)
+		return ret;
+
+	clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data) +
+				sizeof(*clk_data->hws) * IMX8QXP_CLK_END,
+				GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	clk_data->num = IMX8QXP_CLK_END;
+	clks = clk_data->hws;
+
+	/* Fixed clocks */
+	clks[IMX8QXP_CLK_DUMMY]		= imx_clk_hw_fixed("dummy", 0);
+	clks[IMX8QXP_24MHZ]		= imx_clk_hw_fixed("xtal_24MHz", 24000000);
+	clks[IMX8QXP_GPT_3M]		= imx_clk_hw_fixed("gpt_3m", 3000000);
+	clks[IMX8QXP_32KHZ]		= imx_clk_hw_fixed("xtal_32KHz", 32768);
+
+	/* ARM core */
+	clks[IMX8QXP_A35_DIV]		= imx_clk_divider_scu("a35_div", SC_R_A35, SC_PM_CLK_CPU);
+
+	clks[IMX8QXP_IPG_DMA_CLK_ROOT]	= imx_clk_hw_fixed("ipg_dma_clk_root", 120000000);
+	clks[IMX8QXP_AXI_CONN_CLK_ROOT] = imx_clk_hw_fixed("axi_conn_clk_root", 333333333);
+	clks[IMX8QXP_AHB_CONN_CLK_ROOT] = imx_clk_hw_fixed("ahb_conn_clk_root", 166666666);
+	clks[IMX8QXP_IPG_CONN_CLK_ROOT] = imx_clk_hw_fixed("ipg_conn_clk_root", 83333333);
+	clks[IMX8QXP_DC_AXI_EXT_CLK]	= imx_clk_hw_fixed("axi_ext_dc_clk_root", 800000000);
+	clks[IMX8QXP_DC_AXI_INT_CLK]	= imx_clk_hw_fixed("axi_int_dc_clk_root", 400000000);
+	clks[IMX8QXP_DC_CFG_CLK]	= imx_clk_hw_fixed("cfg_dc_clk_root", 100000000);
+	clks[IMX8QXP_MIPI_IPG_CLK]	= imx_clk_hw_fixed("ipg_mipi_clk_root", 120000000);
+	clks[IMX8QXP_IMG_AXI_CLK]	= imx_clk_hw_fixed("axi_img_clk_root", 400000000);
+	clks[IMX8QXP_IMG_IPG_CLK]	= imx_clk_hw_fixed("ipg_img_clk_root", 200000000);
+	clks[IMX8QXP_IMG_PXL_CLK]	= imx_clk_hw_fixed("pxl_img_clk_root", 600000000);
+	clks[IMX8QXP_HSIO_AXI_CLK]	= imx_clk_hw_fixed("axi_hsio_clk_root", 400000000);
+	clks[IMX8QXP_HSIO_PER_CLK]	= imx_clk_hw_fixed("per_hsio_clk_root", 133333333);
+
+	clks[IMX8QXP_UART0_DIV]		= imx_clk_divider_scu("uart0_div", SC_R_UART_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_UART0_IPG_CLK]	= imx_clk_gate2_scu("uart0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_0_LPCG), 16, 0);
+	clks[IMX8QXP_UART0_CLK]		= imx_clk_gate_scu("uart0_clk", "uart0_div", SC_R_UART_0, SC_PM_CLK_PER, (void __iomem *)(LPUART_0_LPCG), 0, 0);
+
+	clks[IMX8QXP_GPU0_CORE_DIV]	= imx_clk_divider_scu("gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER);
+	clks[IMX8QXP_GPU0_SHADER_DIV]	= imx_clk_divider_scu("gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC);
+	clks[IMX8QXP_GPU0_CORE_CLK]	= imx_clk_gate_scu("gpu_core0_clk", "gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER, NULL, 0, 0);
+	clks[IMX8QXP_GPU0_SHADER_CLK]	= imx_clk_gate_scu("gpu_shader0_clk", "gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC, NULL, 0, 0);
+
+	/* LSIO SS */
+	clks[IMX8QXP_LSIO_MEM_CLK]	= imx_clk_hw_fixed("lsio_mem_clk_root", 100000000);
+	clks[IMX8QXP_LSIO_BUS_CLK]	= imx_clk_hw_fixed("lsio_bus_clk_root", 200000000);
+
+	clks[IMX8QXP_LSIO_PWM0_DIV]		= imx_clk_divider_scu("pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM0_IPG_S_CLK]	= imx_clk_gate_scu("pwm_0_ipg_s_clk", "pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM0_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_0_ipg_slv_clk", "pwm_0_ipg_s_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM0_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_0_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_0_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM0_HF_CLK]		= imx_clk_gate_scu("pwm_0_hf_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM0_CLK]		= imx_clk_gate_scu("pwm_0_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM1_DIV]		= imx_clk_divider_scu("pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM1_IPG_S_CLK]	= imx_clk_gate_scu("pwm_1_ipg_s_clk", "pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM1_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_1_ipg_slv_clk", "pwm_1_ipg_s_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM1_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_1_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_1_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM1_HF_CLK]		= imx_clk_gate_scu("pwm_1_hf_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM1_CLK]		= imx_clk_gate_scu("pwm_1_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM2_DIV]		= imx_clk_divider_scu("pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM2_IPG_S_CLK]	= imx_clk_gate_scu("pwm_2_ipg_s_clk", "pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM2_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_2_ipg_slv_clk", "pwm_2_ipg_s_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM2_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_2_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_2_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM2_HF_CLK]		= imx_clk_gate_scu("pwm_2_hf_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM2_CLK]		= imx_clk_gate_scu("pwm_2_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM3_DIV]		= imx_clk_divider_scu("pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM3_IPG_S_CLK]	= imx_clk_gate_scu("pwm_3_ipg_s_clk", "pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM3_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_3_ipg_slv_clk", "pwm_3_ipg_s_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM3_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_3_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_3_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM3_HF_CLK]		= imx_clk_gate_scu("pwm_3_hf_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM3_CLK]		= imx_clk_gate_scu("pwm_3_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM4_DIV]		= imx_clk_divider_scu("pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM4_IPG_S_CLK]	= imx_clk_gate_scu("pwm_4_ipg_s_clk", "pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM4_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_4_ipg_slv_clk", "pwm_4_ipg_s_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM4_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_4_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_4_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM4_HF_CLK]		= imx_clk_gate_scu("pwm_4_hf_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM4_CLK]		= imx_clk_gate_scu("pwm_4_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM5_DIV]		= imx_clk_divider_scu("pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM5_IPG_S_CLK]	= imx_clk_gate_scu("pwm_5_ipg_s_clk", "pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM5_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_5_ipg_slv_clk", "pwm_5_ipg_s_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM5_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_5_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_5_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM5_HF_CLK]		= imx_clk_gate_scu("pwm_5_hf_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM5_CLK]		= imx_clk_gate_scu("pwm_5_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM6_DIV]		= imx_clk_divider_scu("pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM6_IPG_S_CLK]	= imx_clk_gate_scu("pwm_6_ipg_s_clk", "pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM6_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_6_ipg_slv_clk", "pwm_6_ipg_s_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM6_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_6_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_6_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM6_HF_CLK]		= imx_clk_gate_scu("pwm_6_hf_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM6_CLK]		= imx_clk_gate_scu("pwm_6_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_PWM7_DIV]		= imx_clk_divider_scu("pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_PWM7_IPG_S_CLK]	= imx_clk_gate_scu("pwm_7_ipg_s_clk", "pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_PWM7_IPG_SLV_CLK]	= imx_clk_gate_scu("pwm_7_ipg_slv_clk", "pwm_7_ipg_s_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_PWM7_IPG_MSTR_CLK]	= imx_clk_gate2_scu("pwm_7_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_7_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_PWM7_HF_CLK]		= imx_clk_gate_scu("pwm_7_hf_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_PWM7_CLK]		= imx_clk_gate_scu("pwm_7_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT0_DIV]		= imx_clk_divider_scu("gpt_0_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT0_IPG_S_CLK]	= imx_clk_gate_scu("gpt_0_ipg_s_clk", "gpt_0_div", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT0_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_0_ipg_slv_clk", "gpt_0_ipg_s_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT0_CLK]		= imx_clk_gate_scu("gpt_0_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT0_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_0_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_0_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_GPT0_HF_CLK]		= imx_clk_gate_scu("gpt_0_hf_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT1_DIV]		= imx_clk_divider_scu("gpt_1_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT1_IPG_S_CLK]	= imx_clk_gate_scu("gpt_1_ipg_s_clk", "gpt_1_div", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT1_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_1_ipg_slv_clk", "gpt_1_ipg_s_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT1_CLK]		= imx_clk_gate_scu("gpt_1_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT1_HF_CLK]		= imx_clk_gate_scu("gpt_1_hf_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT1_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_1_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_1_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_GPT2_DIV]		= imx_clk_divider_scu("gpt_2_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT2_IPG_S_CLK]	= imx_clk_gate_scu("gpt_2_ipg_s_clk", "gpt_2_div", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT2_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_2_ipg_slv_clk", "gpt_2_ipg_s_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT2_CLK]		= imx_clk_gate_scu("gpt_2_clk", "gpt_2_ipg_slv_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT2_HF_CLK]		= imx_clk_gate_scu("gpt_2_hf_clk", "gpt_2_div", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT2_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_2_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_2_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_GPT3_DIV]		= imx_clk_divider_scu("gpt_3_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT3_IPG_S_CLK]	= imx_clk_gate_scu("gpt_3_ipg_s_clk", "gpt_3_div", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT3_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_3_ipg_slv_clk", "gpt_3_ipg_s_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT3_CLK]		= imx_clk_gate_scu("gpt_3_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT3_HF_CLK]		= imx_clk_gate_scu("gpt_3_hf_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT3_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_3_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_3_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_GPT4_DIV]		= imx_clk_divider_scu("gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_GPT4_IPG_S_CLK]	= imx_clk_gate_scu("gpt_4_ipg_s_clk", "gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPT4_IPG_SLV_CLK]	= imx_clk_gate_scu("gpt_4_ipg_slv_clk", "gpt_4_ipg_s_clk", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_GPT4_CLK]		= imx_clk_gate_scu("gpt_4_clk", "gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPT4_HF_CLK]		= imx_clk_gate_scu("gpt_4_hf_clk", "gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 4, 0);
+	clks[IMX8QXP_LSIO_GPT4_IPG_MSTR_CLK]	= imx_clk_gate2_scu("gpt_4_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_4_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_FSPI0_DIV]		= imx_clk_divider_scu("fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_FSPI0_HCLK]		= imx_clk_gate2_scu("fspi0_hclk_clk", "lsio_mem_clk_root", (void __iomem *)(FSPI_0_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_FSPI0_IPG_S_CLK]	= imx_clk_gate2_scu("fspi0_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(FSPI_0_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_FSPI0_IPG_CLK]	= imx_clk_gate2_scu("fspi0_ipg_clk", "fspi0_ipg_s_clk", (void __iomem *)(FSPI_0_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_FSPI0_CLK]		= imx_clk_gate_scu("fspi_0_clk", "fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER, (void __iomem *)(FSPI_0_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_FSPI1_DIV]		= imx_clk_divider_scu("fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_LSIO_FSPI1_HCLK]		= imx_clk_gate2_scu("fspi1_hclk_clk", "lsio_mem_clk_root", (void __iomem *)(FSPI_1_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_FSPI1_IPG_S_CLK]	= imx_clk_gate2_scu("fspi1_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(FSPI_1_LPCG), 0x18, 0);
+	clks[IMX8QXP_LSIO_FSPI1_IPG_CLK]	= imx_clk_gate2_scu("fspi1_ipg_clk", "fspi1_ipg_s_clk", (void __iomem *)(FSPI_1_LPCG), 0x14, 0);
+	clks[IMX8QXP_LSIO_FSPI1_CLK]		= imx_clk_gate_scu("fspi_1_clk", "fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER, (void __iomem *)(FSPI_1_LPCG), 0, 0);
+	clks[IMX8QXP_LSIO_GPIO0_IPG_S_CLK]	= imx_clk_gate2_scu("gpio0_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_0_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO1_IPG_S_CLK]	= imx_clk_gate2_scu("gpio1_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_1_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO2_IPG_S_CLK]	= imx_clk_gate2_scu("gpio2_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_2_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO3_IPG_S_CLK]	= imx_clk_gate2_scu("gpio3_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_3_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO4_IPG_S_CLK]	= imx_clk_gate2_scu("gpio4_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_4_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO5_IPG_S_CLK]	= imx_clk_gate2_scu("gpio5_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_5_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO6_IPG_S_CLK]	= imx_clk_gate2_scu("gpio6_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_6_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_GPIO7_IPG_S_CLK]	= imx_clk_gate2_scu("gpio7_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(GPIO_7_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_ROMCP_REG_CLK]	= imx_clk_gate2_scu("romcp_reg_clk", "lsio_bus_clk_root", (void __iomem *)(ROMCP_LPCG), 0x10, 0);
+	clks[IMX8QXP_LSIO_ROMCP_CLK]		= imx_clk_gate2_scu("romcp_clk", "lsio_mem_clk_root", (void __iomem *)(ROMCP_LPCG), 0x0, 0);
+	clks[IMX8QXP_LSIO_96KROM_CLK]		= imx_clk_gate2_scu("96krom_clk", "lsio_mem_clk_root", (void __iomem *)(ROMCP_LPCG), 0x4, 0);
+	clks[IMX8QXP_LSIO_OCRAM_MEM_CLK]	= imx_clk_gate2_scu("ocram_lk", "lsio_mem_clk_root", (void __iomem *)(OCRAM_LPCG), 0x4, 0);
+	clks[IMX8QXP_LSIO_OCRAM_CTRL_CLK]	= imx_clk_gate2_scu("ocram_ctrl_clk", "lsio_mem_clk_root", (void __iomem *)(OCRAM_LPCG), 0x0, 0);
+
+	/* ADMA SS */
+	clks[IMX8QXP_UART1_IPG_CLK]	= imx_clk_gate2_scu("uart1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_1_LPCG), 16, 0);
+	clks[IMX8QXP_UART2_IPG_CLK]	= imx_clk_gate2_scu("uart2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_2_LPCG), 16, 0);
+	clks[IMX8QXP_UART3_IPG_CLK]	= imx_clk_gate2_scu("uart3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_3_LPCG), 16, 0);
+	clks[IMX8QXP_UART1_DIV]		= imx_clk_divider_scu("uart1_div", SC_R_UART_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_UART2_DIV]		= imx_clk_divider_scu("uart2_div", SC_R_UART_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_UART3_DIV]		= imx_clk_divider_scu("uart3_div", SC_R_UART_3, SC_PM_CLK_PER);
+	clks[IMX8QXP_UART1_CLK]		= imx_clk_gate_scu("uart1_clk", "uart1_div", SC_R_UART_1, SC_PM_CLK_PER, (void __iomem *)(LPUART_1_LPCG), 0, 0);
+	clks[IMX8QXP_UART2_CLK]		= imx_clk_gate_scu("uart2_clk", "uart2_div", SC_R_UART_2, SC_PM_CLK_PER, (void __iomem *)(LPUART_2_LPCG), 0, 0);
+	clks[IMX8QXP_UART3_CLK]		= imx_clk_gate_scu("uart3_clk", "uart3_div", SC_R_UART_3, SC_PM_CLK_PER, (void __iomem *)(LPUART_3_LPCG), 0, 0);
+	clks[IMX8QXP_SPI0_IPG_CLK]	= imx_clk_gate2_scu("spi0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_0_LPCG), 16, 0);
+	clks[IMX8QXP_SPI1_IPG_CLK]	= imx_clk_gate2_scu("spi1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_1_LPCG), 16, 0);
+	clks[IMX8QXP_SPI2_IPG_CLK]	= imx_clk_gate2_scu("spi2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_2_LPCG), 16, 0);
+	clks[IMX8QXP_SPI3_IPG_CLK]	= imx_clk_gate2_scu("spi3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_3_LPCG), 16, 0);
+	clks[IMX8QXP_SPI0_DIV]		= imx_clk_divider_scu("spi0_div", SC_R_SPI_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_SPI1_DIV]		= imx_clk_divider_scu("spi1_div", SC_R_SPI_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_SPI2_DIV]		= imx_clk_divider_scu("spi2_div", SC_R_SPI_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_SPI3_DIV]		= imx_clk_divider_scu("spi3_div", SC_R_SPI_3, SC_PM_CLK_PER);
+	clks[IMX8QXP_SPI0_CLK]		= imx_clk_gate_scu("spi0_clk", "spi0_div", SC_R_SPI_0, SC_PM_CLK_PER, (void __iomem *)(LPSPI_0_LPCG), 0, 0);
+	clks[IMX8QXP_SPI1_CLK]		= imx_clk_gate_scu("spi1_clk", "spi1_div", SC_R_SPI_2, SC_PM_CLK_PER, (void __iomem *)(LPSPI_1_LPCG), 0, 0);
+	clks[IMX8QXP_SPI2_CLK]		= imx_clk_gate_scu("spi2_clk", "spi2_div", SC_R_SPI_2, SC_PM_CLK_PER, (void __iomem *)(LPSPI_2_LPCG), 0, 0);
+	clks[IMX8QXP_SPI3_CLK]		= imx_clk_gate_scu("spi3_clk", "spi3_div", SC_R_SPI_3, SC_PM_CLK_PER, (void __iomem *)(LPSPI_3_LPCG), 0, 0);
+	clks[IMX8QXP_CAN0_IPG_CHI_CLK]	= imx_clk_gate2_scu("can0_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_0_LPCG), 20, 0);
+	clks[IMX8QXP_CAN0_IPG_CLK]	= imx_clk_gate2_scu("can0_ipg_clk", "can0_ipg_chi_clk", (void __iomem *)(FLEX_CAN_0_LPCG), 16, 0);
+	clks[IMX8QXP_CAN1_IPG_CHI_CLK]	= imx_clk_gate2_scu("can1_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_1_LPCG), 20, 0);
+	clks[IMX8QXP_CAN1_IPG_CLK]	= imx_clk_gate2_scu("can1_ipg_clk", "can1_ipg_chi_clk", (void __iomem *)(FLEX_CAN_1_LPCG), 16, 0);
+	clks[IMX8QXP_CAN2_IPG_CHI_CLK]	= imx_clk_gate2_scu("can2_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_2_LPCG), 20, 0);
+	clks[IMX8QXP_CAN2_IPG_CLK]	= imx_clk_gate2_scu("can2_ipg_clk", "can2_ipg_chi_clk", (void __iomem *)(FLEX_CAN_2_LPCG), 16, 0);
+	clks[IMX8QXP_CAN0_DIV]		= imx_clk_divider_scu("can0_div", SC_R_CAN_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_CAN1_DIV]		= imx_clk_divider_scu("can1_div", SC_R_CAN_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_CAN2_DIV]		= imx_clk_divider_scu("can2_div", SC_R_CAN_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_CAN0_CLK]		= imx_clk_gate_scu("can0_clk", "can0_div", SC_R_CAN_0, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_0_LPCG), 0, 0);
+	clks[IMX8QXP_CAN1_CLK]		= imx_clk_gate_scu("can1_clk", "can1_div", SC_R_CAN_1, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_1_LPCG), 0, 0);
+	clks[IMX8QXP_CAN2_CLK]		= imx_clk_gate_scu("can2_clk", "can2_div", SC_R_CAN_2, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_2_LPCG), 0, 0);
+	clks[IMX8QXP_I2C0_IPG_CLK]	= imx_clk_gate2_scu("i2c0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_0_LPCG), 16, 0);
+	clks[IMX8QXP_I2C1_IPG_CLK]	= imx_clk_gate2_scu("i2c1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_1_LPCG), 16, 0);
+	clks[IMX8QXP_I2C2_IPG_CLK]	= imx_clk_gate2_scu("i2c2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_2_LPCG), 16, 0);
+	clks[IMX8QXP_I2C3_IPG_CLK]	= imx_clk_gate2_scu("i2c3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_3_LPCG), 16, 0);
+	clks[IMX8QXP_I2C0_DIV]		= imx_clk_divider_scu("i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_I2C1_DIV]		= imx_clk_divider_scu("i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_I2C2_DIV]		= imx_clk_divider_scu("i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_I2C3_DIV]		= imx_clk_divider_scu("i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER);
+	clks[IMX8QXP_I2C0_CLK]		= imx_clk_gate_scu("i2c0_clk", "i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER, (void __iomem *)(LPI2C_0_LPCG), 0, 0);
+	clks[IMX8QXP_I2C1_CLK]		= imx_clk_gate_scu("i2c1_clk", "i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER, (void __iomem *)(LPI2C_1_LPCG), 0, 0);
+	clks[IMX8QXP_I2C2_CLK]		= imx_clk_gate_scu("i2c2_clk", "i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER, (void __iomem *)(LPI2C_2_LPCG), 0, 0);
+	clks[IMX8QXP_I2C3_CLK]		= imx_clk_gate_scu("i2c3_clk", "i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER, (void __iomem *)(LPI2C_3_LPCG), 0, 0);
+	clks[IMX8QXP_FTM0_IPG_CLK]	= imx_clk_gate2_scu("ftm0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(FTM_0_LPCG), 16, 0);
+	clks[IMX8QXP_FTM1_IPG_CLK]	= imx_clk_gate2_scu("ftm1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(FTM_1_LPCG), 16, 0);
+	clks[IMX8QXP_FTM0_DIV]		= imx_clk_divider_scu("ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_FTM1_DIV]		= imx_clk_divider_scu("ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_FTM0_CLK]		= imx_clk_gate_scu("ftm0_clk", "ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER, (void __iomem *)(FTM_0_LPCG), 0, 0);
+	clks[IMX8QXP_FTM1_CLK]		= imx_clk_gate_scu("ftm1_clk", "ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER, (void __iomem *)(FTM_1_LPCG), 0, 0);
+	clks[IMX8QXP_ADC0_IPG_CLK]	= imx_clk_gate2_scu("adc0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(ADC_0_LPCG), 16, 0);
+	clks[IMX8QXP_ADC0_DIV]		= imx_clk_divider_scu("adc0_div", SC_R_ADC_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_ADC0_CLK]		= imx_clk_gate_scu("adc0_clk", "adc0_div", SC_R_ADC_0, SC_PM_CLK_PER, (void __iomem *)(ADC_0_LPCG), 0, 0);
+	clks[IMX8QXP_PWM_IPG_CLK]	= imx_clk_gate2_scu("pwm_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(PWM_LPCG), 16, 0);
+	clks[IMX8QXP_PWM_DIV]		= imx_clk_divider_scu("pwm_div", SC_R_LCD_0_PWM_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_PWM_CLK]		= imx_clk_gate_scu("pwm_clk", "pwm_div", SC_R_LCD_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_LPCG), 0, 0);
+	clks[IMX8QXP_LCD_IPG_CLK]	= imx_clk_gate2_scu("lcd_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LCD_LPCG), 16, 0);
+	clks[IMX8QXP_LCD_DIV]		= imx_clk_divider_scu("lcd_div", SC_R_LCD_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_LCD_CLK]		= imx_clk_gate_scu("lcd_clk", "lcd_div", SC_R_LCD_0, SC_PM_CLK_PER, (void __iomem *)(LCD_LPCG), 0, 0);
+
+	/* Connectivity */
+	clks[IMX8QXP_SDHC0_IPG_CLK]	= imx_clk_gate2_scu("sdhc0_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_0_LPCG), 16, 0);
+	clks[IMX8QXP_SDHC1_IPG_CLK]	= imx_clk_gate2_scu("sdhc1_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_1_LPCG), 16, 0);
+	clks[IMX8QXP_SDHC2_IPG_CLK]	= imx_clk_gate2_scu("sdhc2_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_2_LPCG), 16, 0);
+	clks[IMX8QXP_SDHC0_DIV]		= imx_clk_divider_scu("sdhc0_div", SC_R_SDHC_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_SDHC1_DIV]		= imx_clk_divider_scu("sdhc1_div", SC_R_SDHC_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_SDHC2_DIV]		= imx_clk_divider_scu("sdhc2_div", SC_R_SDHC_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_SDHC0_CLK]		= imx_clk_gate_scu("sdhc0_clk", "sdhc0_div", SC_R_SDHC_0, SC_PM_CLK_PER, (void __iomem *)(USDHC_0_LPCG), 0, 0);
+	clks[IMX8QXP_SDHC1_CLK]		= imx_clk_gate_scu("sdhc1_clk", "sdhc1_div", SC_R_SDHC_1, SC_PM_CLK_PER, (void __iomem *)(USDHC_1_LPCG), 0, 0);
+	clks[IMX8QXP_SDHC2_CLK]		= imx_clk_gate_scu("sdhc2_clk", "sdhc1_div", SC_R_SDHC_2, SC_PM_CLK_PER, (void __iomem *)(USDHC_2_LPCG), 0, 0);
+	clks[IMX8QXP_ENET0_ROOT_DIV]	= imx_clk_divider_scu("enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_ENET0_REF_DIV]	= imx_clk_divider_gpr_scu("enet0_ref_div", "enet0_root_clk", SC_R_ENET_0, SC_C_CLKDIV);
+	clks[IMX8QXP_ENET1_REF_DIV]	= imx_clk_divider_gpr_scu("enet1_ref_div", "enet1_root_clk", SC_R_ENET_1, SC_C_CLKDIV);
+	clks[IMX8QXP_ENET0_BYPASS_DIV]	= imx_clk_divider_scu("enet0_bypass_div", SC_R_ENET_0, SC_PM_CLK_BYPASS);
+	clks[IMX8QXP_ENET0_RGMII_DIV]	= imx_clk_divider_scu("enet0_rgmii_div", SC_R_ENET_0, SC_PM_CLK_MISC0);
+	clks[IMX8QXP_ENET1_ROOT_DIV]	= imx_clk_divider_scu("enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER);
+	clks[IMX8QXP_ENET1_BYPASS_DIV]	= imx_clk_divider_scu("enet1_bypass_div", SC_R_ENET_1, SC_PM_CLK_BYPASS);
+	clks[IMX8QXP_ENET1_RGMII_DIV]	= imx_clk_divider_scu("enet1_rgmii_div", SC_R_ENET_1, SC_PM_CLK_MISC0);
+	clks[IMX8QXP_ENET0_AHB_CLK]	= imx_clk_gate2_scu("enet0_ahb_clk", "axi_conn_clk_root", (void __iomem *)(ENET_0_LPCG), 8, 0);
+	clks[IMX8QXP_ENET0_IPG_S_CLK]	= imx_clk_gate2_scu("enet0_ipg_s_clk", "ipg_conn_clk_root", (void __iomem *)(ENET_0_LPCG), 20, 0);
+	clks[IMX8QXP_ENET0_IPG_CLK]	= imx_clk_gate2_scu("enet0_ipg_clk", "enet0_ipg_s_clk", (void __iomem *)(ENET_0_LPCG), 16, 0);
+	clks[IMX8QXP_ENET1_AHB_CLK]	= imx_clk_gate2_scu("enet1_ahb_clk", "axi_conn_clk_root", (void __iomem *)(ENET_1_LPCG), 8, 0);
+	clks[IMX8QXP_ENET1_IPG_S_CLK]	= imx_clk_gate2_scu("enet1_ipg_s_clk", "ipg_conn_clk_root", (void __iomem *)(ENET_1_LPCG), 20, 0);
+	clks[IMX8QXP_ENET1_IPG_CLK]	= imx_clk_gate2_scu("enet1_ipg_clk", "enet1_ipg_s_clk", (void __iomem *)(ENET_1_LPCG), 16, 0);
+	clks[IMX8QXP_ENET0_ROOT_CLK]	= imx_clk_gate_scu("enet0_root_clk", "enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER, NULL, 0, 0);
+	clks[IMX8QXP_ENET1_ROOT_CLK]	= imx_clk_gate_scu("enet1_root_clk", "enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER, NULL, 0, 0);
+	clks[IMX8QXP_ENET0_TX_CLK]	= imx_clk_gate2_scu("enet0_tx_2x_clk", "enet0_root_div", (void __iomem *)(ENET_0_LPCG), 4, 0);
+	clks[IMX8QXP_ENET1_TX_CLK]	= imx_clk_gate2_scu("enet1_tx_2x_clk", "enet1_root_div", (void __iomem *)(ENET_1_LPCG), 4, 0);
+	clks[IMX8QXP_ENET0_PTP_CLK]	= imx_clk_gate2_scu("enet0_ptp_clk", "enet0_ref_div", (void __iomem *)(ENET_0_LPCG), 0, 0);
+	clks[IMX8QXP_ENET1_PTP_CLK]	= imx_clk_gate2_scu("enet1_ptp_clk", "enet1_ref_div", (void __iomem *)(ENET_1_LPCG), 0, 0);
+	clks[IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet0_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_0, SC_C_SEL_125);
+	clks[IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet1_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_1, SC_C_SEL_125);
+	clks[IMX8QXP_ENET0_RMII_TX_SEL]	= imx_clk_mux_gpr_scu("enet0_rmii_tx_sel", enet0_rmii_tx_sels, ARRAY_SIZE(enet0_rmii_tx_sels), SC_R_ENET_0, SC_C_TXCLK);
+	clks[IMX8QXP_ENET1_RMII_TX_SEL]	= imx_clk_mux_gpr_scu("enet1_rmii_tx_sel", enet1_rmii_tx_sels, ARRAY_SIZE(enet1_rmii_tx_sels), SC_R_ENET_1, SC_C_TXCLK);
+	clks[IMX8QXP_ENET0_RGMII_TX_CLK] = imx_clk_gate2_scu("enet0_rgmii_tx_clk", "enet0_rmii_tx_sel", (void __iomem *)(ENET_0_LPCG), 12, 0);
+	clks[IMX8QXP_ENET1_RGMII_TX_CLK] = imx_clk_gate2_scu("enet1_rgmii_tx_clk", "enet1_rmii_tx_sel", (void __iomem *)(ENET_1_LPCG), 12, 0);
+	clks[IMX8QXP_ENET0_RMII_RX_CLK]	= imx_clk_gate2_scu("enet0_rgmii_rx_clk", "enet0_rgmii_div", (void __iomem *)(ENET_0_LPCG + 0x4), 0, 0);
+	clks[IMX8QXP_ENET1_RMII_RX_CLK]	= imx_clk_gate2_scu("enet1_rgmii_rx_clk", "enet1_rgmii_div", (void __iomem *)(ENET_1_LPCG + 0x4), 0, 0);
+	clks[IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK] = imx_clk_gate_gpr_scu("enet0_ref_25_125_clk", "enet0_ref_25_125_sel", SC_R_ENET_0, SC_C_DISABLE_125, true);
+	clks[IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK] = imx_clk_gate_gpr_scu("enet1_ref_25_125_clk", "enet1_ref_25_125_sel", SC_R_ENET_1, SC_C_DISABLE_125, true);
+	clks[IMX8QXP_ENET0_REF_50MHZ_CLK] = imx_clk_gate_gpr_scu("enet0_ref_50_clk", NULL, SC_R_ENET_0, SC_C_DISABLE_50, true);
+	clks[IMX8QXP_ENET1_REF_50MHZ_CLK] = imx_clk_gate_gpr_scu("enet1_ref_50_clk", NULL, SC_R_ENET_1, SC_C_DISABLE_50, true);
+	clks[IMX8QXP_GPMI_BCH_IO_DIV]	= imx_clk_divider_scu("gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS);
+	clks[IMX8QXP_GPMI_BCH_DIV]	= imx_clk_divider_scu("gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER);
+	clks[IMX8QXP_GPMI_APB_CLK]	= imx_clk_gate2_scu("gpmi_apb_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG), 16, 0);
+	clks[IMX8QXP_GPMI_APB_BCH_CLK]	= imx_clk_gate2_scu("gpmi_apb_bch_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG), 20, 0);
+	clks[IMX8QXP_GPMI_BCH_IO_CLK]	= imx_clk_gate_scu("gpmi_io_clk", "gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS, (void __iomem *)(NAND_LPCG), 4, 0);
+	clks[IMX8QXP_GPMI_BCH_CLK]	= imx_clk_gate_scu("gpmi_bch_clk", "gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER, (void __iomem *)(NAND_LPCG), 0, 0);
+	clks[IMX8QXP_APBHDMA_CLK]	= imx_clk_gate2_scu("gpmi_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG + 0x4), 16, 0);
+	clks[IMX8QXP_USB3_ACLK_DIV]	= imx_clk_divider_scu("usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER);
+	clks[IMX8QXP_USB3_BUS_DIV]	= imx_clk_divider_scu("usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS);
+	clks[IMX8QXP_USB3_LPM_DIV]	= imx_clk_divider_scu("usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC);
+	clks[IMX8QXP_USB2_OH_AHB_CLK]	= imx_clk_gate2_scu("usboh3", "ahb_conn_clk_root", (void __iomem *)(USB_2_LPCG), 24, 0);
+	clks[IMX8QXP_USB2_OH_IPG_S_CLK]	= imx_clk_gate2_scu("usboh3_ipg_s", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 16, 0);
+	clks[IMX8QXP_USB2_OH_IPG_S_PL301_CLK] = imx_clk_gate2_scu("usboh3_ipg_pl301_s", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 20, 0);
+	clks[IMX8QXP_USB2_PHY_IPG_CLK]	= imx_clk_gate2_scu("usboh3_phy_clk", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 28, 0);
+	clks[IMX8QXP_USB3_IPG_CLK]	= imx_clk_gate2_scu("usb3_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USB_3_LPCG), 16, 0);
+	clks[IMX8QXP_USB3_CORE_PCLK]	= imx_clk_gate2_scu("usb3_core_clk", "ipg_conn_clk_root", (void __iomem *)(USB_3_LPCG), 20, 0);
+	clks[IMX8QXP_USB3_PHY_CLK]	= imx_clk_gate2_scu("usb3_phy_clk", "usb3_ipg_clk", (void __iomem *)(USB_3_LPCG), 24, 0);
+	clks[IMX8QXP_USB3_ACLK]		= imx_clk_gate_scu("usb3_aclk", "usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER, (void __iomem *)(USB_3_LPCG), 28, 0);
+	clks[IMX8QXP_USB3_BUS_CLK]	= imx_clk_gate_scu("usb3_bus_clk", "usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS, (void __iomem *)(USB_3_LPCG), 0, 0);
+	clks[IMX8QXP_USB3_LPM_CLK]	= imx_clk_gate_scu("usb3_lpm_clk", "usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC, (void __iomem *)(USB_3_LPCG), 4, 0);
+	clks[IMX8QXP_EDMA_CLK]		= imx_clk_gate2_scu("edma_clk", "axi_conn_clk_root", (void __iomem *)(EDMA_LPCG), 0, 0);
+	clks[IMX8QXP_EDMA_IPG_CLK]	= imx_clk_gate2_scu("edma_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(EDMA_LPCG), 16, 0);
+	clks[IMX8QXP_MLB_HCLK]		= imx_clk_gate2_scu("mlb_hclk", "axi_conn_clk_root", (void __iomem *)(MLB_LPCG), 20, 0);
+	clks[IMX8QXP_MLB_CLK]		= imx_clk_gate2_scu("mlb_clk", "mlb_hclk", (void __iomem *)(MLB_LPCG), 0, 0);
+	clks[IMX8QXP_MLB_IPG_CLK]	= imx_clk_gate2_scu("mlb_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(MLB_LPCG), 16, 0);
+
+	/* Display controller - DC0 SS */
+	clks[IMX8QXP_DC0_DISP0_CLK]	= imx_clk_gate_scu("dc0_disp0_clk", "dc0_disp0_div", SC_R_DC_0, SC_PM_CLK_MISC0, (void __iomem *)(DC_0_LPCG), 0, 0);
+	clks[IMX8QXP_DC0_DISP1_CLK]	= imx_clk_gate_scu("dc0_disp1_clk", "dc0_disp1_div", SC_R_DC_0, SC_PM_CLK_MISC1, (void __iomem *)(DC_0_LPCG), 4, 0);
+	clks[IMX8QXP_DC0_PRG0_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg0_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x20), 0, 0);
+	clks[IMX8QXP_DC0_PRG0_APB_CLK]	= imx_clk_gate2_scu("dc0_prg0_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x20), 16, 0);
+	clks[IMX8QXP_DC0_PRG1_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg1_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x24), 0, 0);
+	clks[IMX8QXP_DC0_PRG1_APB_CLK]	= imx_clk_gate2_scu("dc0_prg1_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x24), 16, 0);
+	clks[IMX8QXP_DC0_PRG2_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg2_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x28), 0, 0);
+	clks[IMX8QXP_DC0_PRG2_APB_CLK]	= imx_clk_gate2_scu("dc0_prg2_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x28), 16, 0);
+	clks[IMX8QXP_DC0_PRG3_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg3_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x34), 0, 0);
+	clks[IMX8QXP_DC0_PRG3_APB_CLK]	= imx_clk_gate2_scu("dc0_prg3_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x34), 16, 0);
+	clks[IMX8QXP_DC0_PRG4_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg4_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x38), 0, 0);
+	clks[IMX8QXP_DC0_PRG4_APB_CLK]	= imx_clk_gate2_scu("dc0_prg4_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x38), 16, 0);
+	clks[IMX8QXP_DC0_PRG5_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg5_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x3c), 0, 0);
+	clks[IMX8QXP_DC0_PRG5_APB_CLK]	= imx_clk_gate2_scu("dc0_prg5_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x3c), 16, 0);
+	clks[IMX8QXP_DC0_PRG6_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg6_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x40), 0, 0);
+	clks[IMX8QXP_DC0_PRG6_APB_CLK]	= imx_clk_gate2_scu("dc0_prg6_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x40), 16, 0);
+	clks[IMX8QXP_DC0_PRG7_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg7_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x44), 0, 0);
+	clks[IMX8QXP_DC0_PRG7_APB_CLK]	= imx_clk_gate2_scu("dc0_prg7_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x44), 16, 0);
+	clks[IMX8QXP_DC0_PRG8_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg8_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x48), 0, 0);
+	clks[IMX8QXP_DC0_PRG8_APB_CLK]	= imx_clk_gate2_scu("dc0_prg8_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x48), 16, 0);
+	clks[IMX8QXP_DC0_DPR0_APB_CLK]	= imx_clk_gate2_scu("dc0_dpr0_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x18), 16, 0);
+	clks[IMX8QXP_DC0_DPR0_B_CLK]	= imx_clk_gate2_scu("dc0_dpr0_b_clk", "axi_ext_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x18), 20, 0);
+	clks[IMX8QXP_DC0_RTRAM0_CLK]	= imx_clk_gate2_scu("dc0_rtrm0_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x1C), 0, 0);
+	clks[IMX8QXP_DC0_RTRAM1_CLK]	= imx_clk_gate2_scu("dc0_rtrm1_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x30), 0, 0);
+
+	/* Display interface - MIPI-LVDS SS */
+	clks[IMX8QXP_MIPI0_I2C0_DIV]	= imx_clk_divider_scu("mipi_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2);
+	clks[IMX8QXP_MIPI0_I2C1_DIV]	= imx_clk_divider_scu("mipi_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2);
+	clks[IMX8QXP_MIPI0_I2C0_CLK]	= imx_clk_gate_scu("mipi_i2c0_clk", "mipi_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI0_LPCG + 0x14), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C1_CLK]	= imx_clk_gate_scu("mipi_i2c1_clk", "mipi_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI0_LPCG + 0x14), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C0_IPG_S_CLK] = imx_clk_gate2_scu("mipi_i2c0_ipg_s", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x10), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C0_IPG_CLK]	= imx_clk_gate2_scu("mipi_i2c0_ipg_clk", "mipi_i2c0_ipg_s", (void __iomem *)(DI_MIPI0_LPCG), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C1_IPG_S_CLK] = imx_clk_gate2_scu("mipi_i2c1_ipg_s", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x14), 0, 0);
+	clks[IMX8QXP_MIPI0_I2C1_IPG_CLK]	= imx_clk_gate2_scu("mipi_i2c1_ipg_clk", "mipi_i2c1_ipg_s", (void __iomem *)(DI_MIPI0_LPCG), 0, 0);
+	clks[IMX8QXP_MIPI0_PWM_IPG_S_CLK] = imx_clk_gate2_scu("mipi_pwm_ipg_s", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 0, 0);
+	clks[IMX8QXP_MIPI0_PWM_IPG_CLK]	= imx_clk_gate2_scu("mipi_pwm_ipg_clk", "mipi_pwm_ipg_s", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 0, 0);
+	clks[IMX8QXP_MIPI0_PWM_32K_CLK]	= imx_clk_gate2_scu("mipi_pwm_32K_clk", "xtal_32KHz", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 0, 0);
+	clks[IMX8QXP_MIPI0_GPIO_IPG_CLK]	= imx_clk_gate2_scu("mipi_gpio_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x8), 0, 0);
+
+	/* Imaging SS */
+	clks[IMX8QXP_IMG_JPEG_ENC_IPG_CLK]	= imx_clk_gate2_scu("img_jpeg_enc_ipg_clk", "ipg_img_clk_root", (void __iomem *)(IMG_JPEG_ENC_LPCG), 16, 0);
+	clks[IMX8QXP_IMG_JPEG_ENC_CLK]		= imx_clk_gate2_scu("img_jpeg_enc_clk", "img_jpeg_enc_ipg_clk", (void __iomem *)(IMG_JPEG_ENC_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_JPEG_DEC_IPG_CLK]	= imx_clk_gate2_scu("img_jpeg_dec_ipg_clk", "ipg_img_clk_root", (void __iomem *)(IMG_JPEG_DEC_LPCG), 16, 0);
+	clks[IMX8QXP_IMG_JPEG_DEC_CLK]		= imx_clk_gate2_scu("img_jpeg_dec_clk", "img_jpeg_dec_ipg_clk", (void __iomem *)(IMG_JPEG_DEC_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_DC0_CLK]	= imx_clk_gate2_scu("img_pxl_link_dc0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_DC0_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_DC1_CLK]	= imx_clk_gate2_scu("img_pxl_link_dc1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_DC1_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_CSI0_CLK]	= imx_clk_gate2_scu("img_pxl_link_csi0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_CSI0_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_CSI1_CLK]	= imx_clk_gate2_scu("img_pxl_link_csi1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_CSI1_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PXL_LINK_HDMI_IN_CLK]	= imx_clk_gate2_scu("img_pxl_link_hdmi_in_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_HDMI_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_0_CLK]		= imx_clk_gate2_scu("img_pdma0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_0_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_1_CLK]		= imx_clk_gate2_scu("img_pdma1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_1_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_2_CLK]		= imx_clk_gate2_scu("img_pdma2_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_2_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_3_CLK]		= imx_clk_gate2_scu("img_pdma3_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_3_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_4_CLK]		= imx_clk_gate2_scu("img_pdma4_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_4_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_5_CLK]		= imx_clk_gate2_scu("img_pdma5_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_5_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_6_CLK]		= imx_clk_gate2_scu("img_pdma6_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_6_LPCG), 0, 0);
+	clks[IMX8QXP_IMG_PDMA_7_CLK]		= imx_clk_gate2_scu("img_pdma7_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_7_LPCG), 0, 0);
+
+	/* MIPI CSI SS */
+	clks[IMX8QXP_CSI0_I2C0_DIV]	= imx_clk_divider_scu("mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_CSI0_PWM0_DIV]	= imx_clk_divider_scu("mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_CSI0_CORE_DIV]	= imx_clk_divider_scu("mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER);
+	clks[IMX8QXP_CSI0_ESC_DIV]	= imx_clk_divider_scu("mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC);
+	clks[IMX8QXP_CSI0_IPG_CLK_S]	= imx_clk_gate2_scu("mipi_csi0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x8), 16, 0);
+	clks[IMX8QXP_CSI0_IPG_CLK]	= imx_clk_gate2_scu("mipi_csi0_ipg", "mipi_csi0_ipg_s", (void __iomem *)(MIPI_CSI_0_LPCG), 16, 0);
+	clks[IMX8QXP_CSI0_APB_CLK]	= imx_clk_gate2_scu("mipi_csi0_apb_clk", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x4), 16,  0);
+	clks[IMX8QXP_CSI0_I2C0_IPG_CLK]	= imx_clk_gate2_scu("mipi_csi0_i2c0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x14), 16, 0);
+	clks[IMX8QXP_CSI0_I2C0_CLK]	= imx_clk_gate_scu("mipi_csi0_i2c0_clk", "mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x14), 0, 0);
+	clks[IMX8QXP_CSI0_PWM0_IPG_CLK]	= imx_clk_gate2_scu("mipi_csi0_pwm0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x10), 16, 0);
+	clks[IMX8QXP_CSI0_PWM0_CLK]	= imx_clk_gate_scu("mipi_csi0_pwm0_clk", "mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x10), 0, 0);
+	clks[IMX8QXP_CSI0_CORE_CLK]	= imx_clk_gate_scu("mipi_csi0_core_clk", "mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x18), 16, 0);
+	clks[IMX8QXP_CSI0_ESC_CLK]	= imx_clk_gate_scu("mipi_csi0_esc_clk", "mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC, (void __iomem *)(MIPI_CSI_0_LPCG + 0x1C), 16, 0);
+
+	/* HSIO SS */
+	clks[IMX8QXP_HSIO_PCIE_MSTR_AXI_CLK]	= imx_clk_gate2_scu("hsio_pcie_mstr_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_PCIE_SLV_AXI_CLK]	= imx_clk_gate2_scu("hsio_pcie_slv_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 20, 0);
+	clks[IMX8QXP_HSIO_PCIE_DBI_AXI_CLK]	= imx_clk_gate2_scu("hsio_pcie_dbi_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 24, 0);
+	clks[IMX8QXP_HSIO_PCIE_X1_PER_CLK]	= imx_clk_gate2_scu("hsio_pcie_x1_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_CRR3_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_PHY_X1_PER_CLK]	= imx_clk_gate2_scu("hsio_phy_x1_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PHY_X1_CRR1_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_MISC_PER_CLK]		= imx_clk_gate2_scu("hsio_misc_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_MISC_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_PHY_X1_APB_CLK]	= imx_clk_gate2_scu("hsio_phy_x1_apb_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PHY_X1_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_GPIO_CLK]		= imx_clk_gate2_scu("hsio_gpio_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_GPIO_LPCG), 16, 0);
+	clks[IMX8QXP_HSIO_PHY_X1_PCLK]		= imx_clk_gate2_scu("hsio_phy_x1_pclk", "dummy", (void __iomem *)(HSIO_PHY_X1_LPCG), 0, 0);
+
+	imx_check_clk_hws(clks, clk_data->num);
+
+	of_clk_add_hw_provider(ccm_node, of_clk_hw_onecell_get, clk_data);
+
+	pr_info("i.MX8QXP clock tree init done.\n");
+
+	return 0;
+}
+
+static const struct of_device_id imx8qxp_match[] = {
+	{ .compatible = "fsl,imx8qxp-clk", },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver imx8qxp_clk_driver = {
+	.driver = {
+		.name = "imx8qxp-clk",
+		.of_match_table = imx8qxp_match,
+	},
+	.probe = imx8qxp_clk_probe,
+};
+
+static int __init imx8qxp_clk_init(void)
+{
+	return platform_driver_register(&imx8qxp_clk_driver);
+}
+core_initcall(imx8qxp_clk_init);
diff --git a/include/soc/imx/imx8qxp/lpcg.h b/include/soc/imx/imx8qxp/lpcg.h
new file mode 100644
index 0000000..afbb5da
--- /dev/null
+++ b/include/soc/imx/imx8qxp/lpcg.h
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *
+ */
+
+#ifndef _SC_LPCG_H
+#define _SC_LPCG_H
+
+/*LSIO SS */
+#define		PWM_0_LPCG		0x5D400000
+#define		PWM_1_LPCG		0x5D410000
+#define		PWM_2_LPCG		0x5D420000
+#define		PWM_3_LPCG		0x5D430000
+#define		PWM_4_LPCG		0x5D440000
+#define		PWM_5_LPCG		0x5D450000
+#define		PWM_6_LPCG		0x5D460000
+#define		PWM_7_LPCG		0x5D470000
+#define		GPIO_0_LPCG		0x5D480000
+#define		GPIO_1_LPCG		0x5D490000
+#define		GPIO_2_LPCG		0x5D4A0000
+#define		GPIO_3_LPCG		0x5D4B0000
+#define		GPIO_4_LPCG		0x5D4C0000
+#define		GPIO_5_LPCG		0x5D4D0000
+#define		GPIO_6_LPCG		0x5D4E0000
+#define		GPIO_7_LPCG		0x5D4F0000
+#define		FSPI_0_LPCG		0x5D520000
+#define		FSPI_1_LPCG		0x5D530000
+#define		GPT_0_LPCG		0x5D540000
+#define		GPT_1_LPCG		0x5D550000
+#define		GPT_2_LPCG		0x5D560000
+#define		GPT_3_LPCG		0x5D570000
+#define		GPT_4_LPCG		0x5D580000
+#define		OCRAM_LPCG		0x5D590000
+#define		KPP_LPCG		0x5D5A0000
+#define		ROMCP_LPCG		0x5D500000
+
+/* HSIO SS */
+#define		CRR_5_LPCG		0x5F0F0000
+#define		CRR_4_LPCG		0x5F0E0000
+#define		CRR_3_LPCG		0x5F0D0000
+#define		CRR_2_LPCG		0x5F0C0000
+#define		CRR_1_LPCG		0x5F0B0000
+#define		CRR_0_LPCG		0x5F0A0000
+#define		PHY_1_LPCG		0x5F090000
+#define		PHY_2_LPCG		0x5F080000
+#define		SATA_0_LPCG		0x5F070000
+#define		PCIE_B_LPCG		0x5F060000
+#define		PCIE_A_LPCG		0x5F050000
+
+/* DMA SS */
+#define		FLEX_CAN_2_LPCG		0x5ACF0000
+#define		FLEX_CAN_1_LPCG		0x5ACE0000
+#define		FLEX_CAN_0_LPCG		0x5ACD0000
+#define		FTM_1_LPCG		0x5ACB0000
+#define		FTM_0_LPCG		0x5ACA0000
+#define		ADC_0_LPCG		0x5AC80000
+#define		LPI2C_3_LPCG		0x5AC30000
+#define		LPI2C_2_LPCG		0x5AC20000
+#define		LPI2C_1_LPCG		0x5AC10000
+#define		LPI2C_0_LPCG		0x5AC00000
+#define		PWM_LPCG		0x5A590000
+#define		LCD_LPCG		0x5A580000
+#define		LPUART_3_LPCG		0x5A490000
+#define		LPUART_2_LPCG		0x5A480000
+#define		LPUART_1_LPCG		0x5A470000
+#define		LPUART_0_LPCG		0x5A460000
+#define		LPSPI_3_LPCG		0x5A430000
+#define		LPSPI_2_LPCG		0x5A420000
+#define		LPSPI_1_LPCG		0x5A410000
+#define		LPSPI_0_LPCG		0x5A400000
+
+/* Display SS */
+#define		DC_0_LPCG		0x56010000
+#define		DC_1_LPCG		0x57010000
+
+/* LVDS */
+#define		DI_LVDS_0_LPCG		0x56243000
+#define		DI_LVDS_1_LPCG		0x57243000
+
+/* DI HDMI */
+#define		DI_HDMI_LPCG		0x56263000
+
+/* RX-HDMI */
+#define		RX_HDMI_LPCG		0x58263000
+
+/* MIPI CSI SS */
+#define		MIPI_CSI_0_LPCG		0x58223000
+#define		MIPI_CSI_1_LPCG		0x58243000
+
+/* PARALLEL CSI SS */
+#define		PARALLEL_CSI_LPCG	0x58263000
+
+/* Display MIPI SS */
+#define		DI_MIPI0_LPCG		0x56223000
+#define		DI_MIPI1_LPCG		0x56243000
+
+/* Imaging SS */
+#define		IMG_JPEG_ENC_LPCG	0x585F0000
+#define		IMG_JPEG_DEC_LPCG	0x585D0000
+#define		IMG_PXL_LINK_DC1_LPCG	0x585C0000
+#define		IMG_PXL_LINK_DC0_LPCG	0x585B0000
+#define		IMG_PXL_LINK_HDMI_LPCG	0x585A0000
+#define		IMG_PXL_LINK_CSI1_LPCG	0x58590000
+#define		IMG_PXL_LINK_CSI0_LPCG	0x58580000
+#define		IMG_PDMA_7_LPCG		0x58570000
+#define		IMG_PDMA_6_LPCG		0x58560000
+#define		IMG_PDMA_5_LPCG		0x58550000
+#define		IMG_PDMA_4_LPCG		0x58540000
+#define		IMG_PDMA_3_LPCG		0x58530000
+#define		IMG_PDMA_2_LPCG		0x58520000
+#define		IMG_PDMA_1_LPCG		0x58510000
+#define		IMG_PDMA_0_LPCG		0x58500000
+
+/* HSIO SS */
+#define		HSIO_GPIO_LPCG		0x5F100000
+#define		HSIO_MISC_LPCG		0x5F0F0000
+#define		HSIO_SATA_CRR4_LPCG	0x5F0E0000
+#define		HSIO_PCIE_X1_CRR3_LPCG	0x5F0D0000
+#define		HSIO_PCIE_X2_CRR2_LPCG	0x5F0C0000
+#define		HSIO_PHY_X1_CRR1_LPCG	0x5F0B0000
+#define		HSIO_PHY_X2_CRR0_LPCG	0x5F0A0000
+#define		HSIO_PHY_X1_LPCG	0x5F090000
+#define		HSIO_PHY_X2_LPCG	0x5F080000
+#define		HSIO_SATA_LPCG		0x5F070000
+#define		HSIO_PCIE_X1_LPCG	0x5F060000
+#define		HSIO_PCIE_X2_LPCG	0x5F050000
+
+/* M4 SS */
+#define		M4_0_I2C_LPCG		0x37630000
+#define		M4_0_LPUART_LPCG	0x37620000
+#define		M4_0_LPIT_LPCG		0x37610000
+#define		M4_1_I2C_LPCG		0x3B630000
+#define		M4_1_LPUART_LPCG	0x3B620000
+#define		M4_1_LPIT_LPCG		0x3B610000
+
+/* Audio SS */
+#define		AUD_ASRC_0_LPCG		0x59400000
+#define		AUD_ESAI_0_LPCG		0x59410000
+#define		AUD_SPDIF_0_LPCG	0x59420000
+#define		AUD_SAI_0_LPCG		0x59440000
+#define		AUD_SAI_1_LPCG		0x59450000
+#define		AUD_SAI_2_LPCG		0x59460000
+#define		AUD_SAI_3_LPCG		0x59470000
+#define		AUD_GPT_5_LPCG		0x594B0000
+#define		AUD_GPT_6_LPCG		0x594C0000
+#define		AUD_GPT_7_LPCG		0x594D0000
+#define		AUD_GPT_8_LPCG		0x594E0000
+#define		AUD_GPT_9_LPCG		0x594F0000
+#define		AUD_GPT_10_LPCG		0x59500000
+#define		AUD_HIFI_LPCG		0x59580000
+#define		AUD_OCRAM_LPCG		0x59590000
+#define		AUD_EDMA_0_LPCG		0x595f0000
+#define		AUD_ASRC_1_LPCG		0x59c00000
+#define		AUD_SAI_4_LPCG		0x59c20000
+#define		AUD_SAI_5_LPCG		0x59c30000
+#define		AUD_AMIX_LPCG		0x59c40000
+#define		AUD_MQS_LPCG		0x59c50000
+#define		AUD_ACM_LPCG		0x59c60000
+#define		AUD_REC_CLK0_LPCG	0x59d00000
+#define		AUD_REC_CLK1_LPCG	0x59d10000
+#define		AUD_PLL_CLK0_LPCG	0x59d20000
+#define		AUD_PLL_CLK1_LPCG	0x59d30000
+#define		AUD_MCLKOUT0_LPCG	0x59d50000
+#define		AUD_MCLKOUT1_LPCG	0x59d60000
+#define		AUD_EDMA_1_LPCG		0x59df0000
+
+
+/* Connectivity SS */
+#define		USDHC_0_LPCG		0x5B200000
+#define		USDHC_1_LPCG		0x5B210000
+#define		USDHC_2_LPCG		0x5B220000
+#define		ENET_0_LPCG		0x5B230000
+#define		ENET_1_LPCG		0x5B240000
+#define		DTCP_LPCG		0x5B250000
+#define		MLB_LPCG		0x5B260000
+#define		USB_2_LPCG		0x5B270000
+#define		USB_3_LPCG		0x5B280000
+#define		NAND_LPCG		0x5B290000
+#define		EDMA_LPCG		0x5B2A0000
+
+/* CM40 SS */
+#define		CM40_I2C_LPCG		0x37630000
+
+#endif
-- 
2.7.4

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

end of thread, other threads:[~2018-09-25 16:43 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-25 16:43 [PATCH V2 00/11] clk: imx: add imx8qxp clock support Dong Aisheng
2018-09-25 16:43 ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 01/11] clk: imx: add configuration option for mmio clks Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 02/11] clk: imx: scu: add scu clock common part Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 03/11] clk: imx: scu: add scu clock divider Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 04/11] clk: imx: scu: add scu clock gpr divider Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 05/11] clk: imx: scu: add scu clock gate Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 06/11] clk: imx: scu: add scu clock gpr gate Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 07/11] clk: imx: scu: add scu clock mux Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 08/11] clk: imx: scu: add scu clock gpr mux Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 09/11] clk: imx: add common imx_clk_hw_fixed functions Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 10/11] clk: imx: add imx_check_clk_hws helper function Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng
2018-09-25 16:43 ` [PATCH V2 11/11] clk: imx: add imx8qxp clk driver Dong Aisheng
2018-09-25 16:43   ` Dong Aisheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.