All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP
@ 2019-07-03  5:40 Ye Li
  2019-07-03  5:40 ` [U-Boot] [PATCH 2/5] misc: scu_api: Add new APIs for clk-imx8 driver Ye Li
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Ye Li @ 2019-07-03  5:40 UTC (permalink / raw)
  To: u-boot

Each module may have one or more lpcg registers for SW/HW enabling its
clocks. Add lpcg register address and its driver for accessing lpcg.

Signed-off-by: Ye Li <ye.li@nxp.com>
---
 arch/arm/include/asm/arch-imx8/imx8qm_lpcg.h  | 200 ++++++++++++++++++++++++++
 arch/arm/include/asm/arch-imx8/imx8qxp_lpcg.h | 195 +++++++++++++++++++++++++
 arch/arm/include/asm/arch-imx8/lpcg.h         |  26 ++++
 arch/arm/mach-imx/imx8/Makefile               |   2 +-
 arch/arm/mach-imx/imx8/lpcg.c                 | 115 +++++++++++++++
 5 files changed, 537 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/arch-imx8/imx8qm_lpcg.h
 create mode 100644 arch/arm/include/asm/arch-imx8/imx8qxp_lpcg.h
 create mode 100644 arch/arm/include/asm/arch-imx8/lpcg.h
 create mode 100644 arch/arm/mach-imx/imx8/lpcg.c

diff --git a/arch/arm/include/asm/arch-imx8/imx8qm_lpcg.h b/arch/arm/include/asm/arch-imx8/imx8qm_lpcg.h
new file mode 100644
index 0000000..692c27f
--- /dev/null
+++ b/arch/arm/include/asm/arch-imx8/imx8qm_lpcg.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#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		MU_5A_LPCG		0x5D600000
+#define		MU_6A_LPCG		0x5D610000
+#define		MU_7A_LPCG		0x5D620000
+#define		MU_8A_LPCG		0x5D630000
+#define		MU_9A_LPCG		0x5D640000
+#define		MU_10A_LPCG		0x5D650000
+#define		MU_11A_LPCG		0x5D660000
+#define		MU_12A_LPCG		0x5D670000
+#define		MU_13A_LPCG		0x5D680000
+
+/* 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_1_LPCG		0x5AC90000
+#define		ADC_0_LPCG		0x5AC80000
+#define		LPI2C_4_LPCG		0x5AC40000
+#define		LPI2C_3_LPCG		0x5AC30000
+#define		LPI2C_2_LPCG		0x5AC20000
+#define		LPI2C_1_LPCG		0x5AC10000
+#define		LPI2C_0_LPCG		0x5AC00000
+#define		EMVSIM_1_LPCG		0x5A4E0000
+#define		EMVSIM_0_LPCG		0x5A4D0000
+#define		LPUART_4_LPCG		0x5A4A0000
+#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
+
+/* MIPI DSI SS */
+#define		MIPI_DSI_0_LPCG		0x56223000
+#define		MIPI_DSI_1_LPCG		0x57223000
+
+/* 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_SPDIF_1_LPCG        0x59430000
+#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_HDMI_RX_SAI_0_LPCG  0x59480000
+#define     AUD_HDMI_TX_SAI_0_LPCG  0x59490000
+#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_DSP_LPCG            0x59580000
+#define     AUD_OCRAM_LPCG          0x59590000
+#define     AUD_EDMA_0_LPCG         0x595f0000
+#define     AUD_ASRC_1_LPCG         0x59c00000
+#define     AUD_ESAI_1_LPCG         0x59c10000
+#define     AUD_SAI_6_LPCG          0x59c20000
+#define     AUD_SAI_7_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
+
+/* CM41 SS */
+#define	CM41_I2C_LPCG		0x3B630000
+
+#endif
diff --git a/arch/arm/include/asm/arch-imx8/imx8qxp_lpcg.h b/arch/arm/include/asm/arch-imx8/imx8qxp_lpcg.h
new file mode 100644
index 0000000..5fed514
--- /dev/null
+++ b/arch/arm/include/asm/arch-imx8/imx8qxp_lpcg.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#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
+#define		MU_5A_LPCG		0x5D600000
+#define		MU_6A_LPCG		0x5D610000
+#define		MU_7A_LPCG		0x5D620000
+#define		MU_8A_LPCG		0x5D630000
+#define		MU_9A_LPCG		0x5D640000
+#define		MU_10A_LPCG		0x5D650000
+#define		MU_11A_LPCG		0x5D660000
+#define		MU_12A_LPCG		0x5D670000
+#define		MU_13A_LPCG		0x5D680000
+
+/* 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_DSP_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
diff --git a/arch/arm/include/asm/arch-imx8/lpcg.h b/arch/arm/include/asm/arch-imx8/lpcg.h
new file mode 100644
index 0000000..b3a4545
--- /dev/null
+++ b/arch/arm/include/asm/arch-imx8/lpcg.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_IMX8_LPCG_H__
+#define __ASM_ARCH_IMX8_LPCG_H__
+
+#if defined(CONFIG_IMX8QM)
+#include "imx8qm_lpcg.h"
+#elif defined(CONFIG_IMX8QXP)
+#include "imx8qxp_lpcg.h"
+#else
+#error "No lpcg header"
+#endif
+
+void lpcg_clock_off(u32 lpcg_addr, u8 clk);
+void lpcg_clock_on(u32 lpcg_addr, u8 clk);
+void lpcg_clock_autogate(u32 lpcg_addr, u8 clk);
+bool lpcg_is_clock_on(u32 lpcg_addr, u8 clk);
+void lpcg_all_clock_off(u32 lpcg_addr);
+void lpcg_all_clock_on(u32 lpcg_addr);
+void lpcg_all_clock_autogate(u32 lpcg_addr);
+
+#endif	/* __ASM_ARCH_IMX8_LPCG_H__ */
diff --git a/arch/arm/mach-imx/imx8/Makefile b/arch/arm/mach-imx/imx8/Makefile
index 31ad169..e23f84f 100644
--- a/arch/arm/mach-imx/imx8/Makefile
+++ b/arch/arm/mach-imx/imx8/Makefile
@@ -4,4 +4,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += cpu.o iomux.o
+obj-y += cpu.o iomux.o lpcg.o
diff --git a/arch/arm/mach-imx/imx8/lpcg.c b/arch/arm/mach-imx/imx8/lpcg.c
new file mode 100644
index 0000000..5f5d770
--- /dev/null
+++ b/arch/arm/mach-imx/imx8/lpcg.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/lpcg.h>
+
+#define LPCG_CLOCK_MASK         0x3U
+#define LPCG_CLOCK_OFF          0x0U
+#define LPCG_CLOCK_ON           0x2U
+#define LPCG_CLOCK_AUTO         0x3U
+#define LPCG_CLOCK_STOP         0x8U
+
+#define LPCG_ALL_CLOCK_OFF      0x00000000U
+#define LPCG_ALL_CLOCK_ON       0x22222222U
+#define LPCG_ALL_CLOCK_AUTO     0x33333333U
+#define LPCG_ALL_CLOCK_STOP     0x88888888U
+
+static inline void lpcg_write(u32 lpcgVal, ulong lpcg_addr)
+{
+	/*
+	* Write twice with 4x DSC clock cycles (40x IPS clock cycles) interval
+	* to work around LPCG issue
+	*/
+	writel(lpcgVal, lpcg_addr);
+	udelay(10); /* 10us is enough. Worst case is 40x IPS cycle (200Mhz) */
+	writel(lpcgVal, lpcg_addr);
+	udelay(10);
+}
+
+void lpcg_clock_off(u32 lpcg_addr, u8 clk)
+{
+	u32 lpcgVal;
+
+	/* Read from LPCG */
+	lpcgVal = readl((ulong)lpcg_addr);
+
+	/* Modify */
+	lpcgVal &= ~((u32)(LPCG_CLOCK_MASK) << (clk * 4U));
+	lpcgVal |= ((u32)(LPCG_CLOCK_OFF) << (clk * 4U));
+
+	/* Write to LPCG */
+	lpcg_write(lpcgVal, (ulong)lpcg_addr);
+}
+
+void lpcg_clock_on(u32 lpcg_addr, u8 clk)
+{
+	u32 lpcgVal;
+
+	/* Read from LPCG */
+	lpcgVal = readl((ulong)lpcg_addr);
+
+	/* Modify */
+	lpcgVal &= ~((u32)(LPCG_CLOCK_MASK) << (clk * 4U));
+	lpcgVal |= ((u32)(LPCG_CLOCK_ON) << (clk * 4U));
+
+	/* Write to LPCG */
+	lpcg_write(lpcgVal, (ulong)lpcg_addr);
+}
+
+bool lpcg_is_clock_on(u32 lpcg_addr, u8 clk)
+{
+	u32 lpcgVal;
+
+	/* Read from LPCG */
+	lpcgVal = readl((ulong)lpcg_addr);
+	lpcgVal = (lpcgVal >> (clk * 4U)) & (u32)(LPCG_CLOCK_MASK);
+
+	if (lpcgVal == LPCG_CLOCK_ON)
+		return true;
+
+	return false;
+}
+
+void lpcg_clock_autogate(u32 lpcg_addr, u8 clk)
+{
+	u32 lpcgVal;
+
+	/* Read from LPCG */
+	lpcgVal = readl((ulong)lpcg_addr);
+
+	/* Modify */
+	lpcgVal &= ~((u32)(LPCG_CLOCK_MASK) << (clk * 4U));
+	lpcgVal |= ((u32)(LPCG_CLOCK_AUTO) << (clk * 4U));
+
+	/* Write to LPCG */
+	lpcg_write(lpcgVal, (ulong)lpcg_addr);
+}
+
+void lpcg_all_clock_off(u32 lpcg_addr)
+{
+	/* Write to LPCG */
+	lpcg_write(LPCG_ALL_CLOCK_OFF, (ulong)lpcg_addr);
+}
+
+void lpcg_all_clock_on(u32 lpcg_addr)
+{
+	/* Write to LPCG */
+	lpcg_write(LPCG_ALL_CLOCK_ON, (ulong)lpcg_addr);
+
+	/* Wait for clocks to start */
+	while ((readl((ulong)lpcg_addr) & LPCG_ALL_CLOCK_STOP) != 0U)
+	{
+	}
+}
+
+void lpcg_all_clock_autogate(u32 lpcg_addr)
+{
+	/* Write to LPCG */
+	lpcg_write(LPCG_ALL_CLOCK_AUTO, (ulong)lpcg_addr);
+}
-- 
2.7.4

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

* [U-Boot] [PATCH 2/5] misc: scu_api: Add new APIs for clk-imx8 driver
  2019-07-03  5:40 [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP Ye Li
@ 2019-07-03  5:40 ` Ye Li
  2019-07-03  6:04   ` Peng Fan
  2019-07-03  5:40 ` [U-Boot] [PATCH 3/5] clk: imx8: Update imx8 clock driver Ye Li
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Ye Li @ 2019-07-03  5:40 UTC (permalink / raw)
  To: u-boot

Add sc_misc_set_control to write the subsystem's DSC GPR registers,
and sc_pm_set_clock_parent to select parent clock source.

Signed-off-by: Ye Li <ye.li@nxp.com>
---
 arch/arm/include/asm/arch-imx8/sci/sci.h        |  4 ++
 arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h |  7 ++++
 arch/arm/include/asm/arch-imx8/sci/types.h      | 13 ++++++-
 drivers/misc/imx8/scu_api.c                     | 52 +++++++++++++++++++++++++
 include/dt-bindings/soc/imx_rsrc.h              |  2 +
 5 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/arch-imx8/sci/sci.h b/arch/arm/include/asm/arch-imx8/sci/sci.h
index 9737769..52a3ac8 100644
--- a/arch/arm/include/asm/arch-imx8/sci/sci.h
+++ b/arch/arm/include/asm/arch-imx8/sci/sci.h
@@ -64,8 +64,12 @@ int sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
 			 sc_pm_clock_rate_t *rate);
 int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
 		       sc_bool_t enable, sc_bool_t autog);
+int sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
+			sc_pm_clk_parent_t parent);
 
 /* MISC API */
+int sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			sc_ctrl_t ctrl, u32 val);
 int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
 			u32 *val);
 void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev);
diff --git a/arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h b/arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h
index 9008b85..109ec27 100644
--- a/arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h
+++ b/arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h
@@ -35,6 +35,13 @@
 #define SC_PM_CLK_MODE_AUTOGATE_HW	4U /* Clock is in HW autogate mode */
 #define SC_PM_CLK_MODE_AUTOGATE_SW_HW	5U /* Clock is in SW-HW autogate mode */
 
+/* Defines for sc_pm_clk_parent_t */
+#define SC_PM_PARENT_XTAL              0U    /*!< Parent is XTAL. */
+#define SC_PM_PARENT_PLL0              1U    /*!< Parent is PLL0 */
+#define SC_PM_PARENT_PLL1              2U    /*!< Parent is PLL1 or PLL0/2 */
+#define SC_PM_PARENT_PLL2              3U    /*!< Parent in PLL2 or PLL0/4 */
+#define SC_PM_PARENT_BYPS              4U    /*!< Parent is a bypass clock. */
+
 typedef u8 sc_pm_power_mode_t;
 typedef u8 sc_pm_clk_t;
 typedef u8 sc_pm_clk_mode_t;
diff --git a/arch/arm/include/asm/arch-imx8/sci/types.h b/arch/arm/include/asm/arch-imx8/sci/types.h
index 9eadc88..2d5912e 100644
--- a/arch/arm/include/asm/arch-imx8/sci/types.h
+++ b/arch/arm/include/asm/arch-imx8/sci/types.h
@@ -185,7 +185,18 @@ typedef u64 sc_ipc_t;
 #define SC_C_RST0                       43U
 #define SC_C_RST1                       44U
 #define SC_C_SEL0                       45U
-#define SC_C_LAST                       46U
+#define SC_C_CALIB0                     46U
+#define SC_C_CALIB1                     47U
+#define SC_C_CALIB2                     48U
+#define SC_C_IPG_DEBUG                  49U
+#define SC_C_IPG_DOZE                   50U
+#define SC_C_IPG_WAIT                   51U
+#define SC_C_IPG_STOP                   52U
+#define SC_C_IPG_STOP_MODE              53U
+#define SC_C_IPG_STOP_ACK               54U
+#define SC_C_SYNC_CTRL                  55U
+#define SC_C_LAST                       56U
+
 
 #define SC_P_ALL        ((sc_pad_t)UINT16_MAX)   /* All pads */
 
diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c
index d9c4d5d..cab8995 100644
--- a/drivers/misc/imx8/scu_api.c
+++ b/drivers/misc/imx8/scu_api.c
@@ -93,6 +93,31 @@ int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
 	return ret;
 }
 
+int sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
+    sc_pm_clk_t clk, sc_pm_clk_parent_t parent)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)(SC_RPC_SVC_PM);
+	RPC_FUNC(&msg) = (u8)(PM_FUNC_SET_CLOCK_PARENT);
+	RPC_U16(&msg, 0U) = (u16)(resource);
+	RPC_U8(&msg, 2U) = (u8)(clk);
+	RPC_U8(&msg, 3U) = (u8)(parent);
+	RPC_SIZE(&msg) = 2U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: resource:%d clk:%d: parent clk: %d, res:%d\n",
+		       __func__, resource, clk, parent, RPC_R8(&msg));
+
+	return ret;
+}
+
+
 int sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
 				  sc_pm_power_mode_t mode)
 {
@@ -146,6 +171,33 @@ int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val)
 }
 
 /* MISC */
+int sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			sc_ctrl_t ctrl, u32 val)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)(SC_RPC_SVC_MISC);
+	RPC_FUNC(&msg) = (u8)(MISC_FUNC_SET_CONTROL);
+	RPC_U32(&msg, 0U) = (u32)(ctrl);
+	RPC_U32(&msg, 4U) = (u32)(val);
+	RPC_U16(&msg, 8U) = (u16)(resource);
+	RPC_SIZE(&msg) = 4U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: ctrl:%d resource:%d: res:%d\n",
+		       __func__, ctrl, resource, RPC_R8(&msg));
+
+	return ret;
+}
+
 int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
 			u32 *val)
 {
diff --git a/include/dt-bindings/soc/imx_rsrc.h b/include/dt-bindings/soc/imx_rsrc.h
index 4870eb9..a1c3b1f 100644
--- a/include/dt-bindings/soc/imx_rsrc.h
+++ b/include/dt-bindings/soc/imx_rsrc.h
@@ -554,4 +554,6 @@
 #define SC_R_VPU                        540
 #define SC_R_LAST                       541
 
+#define SC_R_NONE                       0xFFF0
+
 #endif /* DT_BINDINGS_RSCRC_IMX_H */
-- 
2.7.4

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

* [U-Boot] [PATCH 3/5] clk: imx8: Update imx8 clock driver
  2019-07-03  5:40 [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP Ye Li
  2019-07-03  5:40 ` [U-Boot] [PATCH 2/5] misc: scu_api: Add new APIs for clk-imx8 driver Ye Li
@ 2019-07-03  5:40 ` Ye Li
  2019-07-06 23:07   ` Lukasz Majewski
  2019-07-03  5:40 ` [U-Boot] [PATCH 4/5] imx8qm_mek: increase the size of early malloc pool Ye Li
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Ye Li @ 2019-07-03  5:40 UTC (permalink / raw)
  To: u-boot

Update imx8 clock driver to support LPCG and full clocks tree for some
modules aligned with kernel.

We classify the clock into serveral types: slice, fixed, lpcg, gpr and mux.
Generally slice and fixed clocks are the sources. lpcg, gpr and mux are
the downstream of those sources and are used for gating, muxing or dividing
functions.

This patch replaces the functions defined in imx8qm and imx8qxp with the clock
tables of different clock types. clk-imx8 use unified functions to process these
clock tables.

Note: since the clock depends on the power domain of its resource, must power
on the resource firstly, then we can get the clock. Otherwise, we can't access lpcg.
Thus, the clock dump only works for the slice clock.

Signed-off-by: Ye Li <ye.li@nxp.com>
---
 drivers/clk/imx/clk-imx8.c    | 304 +++++++++++++++++++++++++--
 drivers/clk/imx/clk-imx8.h    |  83 +++++++-
 drivers/clk/imx/clk-imx8qm.c  | 479 ++++++++++++++++--------------------------
 drivers/clk/imx/clk-imx8qxp.c | 432 +++++++++++++------------------------
 4 files changed, 689 insertions(+), 609 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c
index a755e26..afdb6ea 100644
--- a/drivers/clk/imx/clk-imx8.c
+++ b/drivers/clk/imx/clk-imx8.c
@@ -12,32 +12,294 @@
 #include <dt-bindings/clock/imx8qxp-clock.h>
 #include <dt-bindings/soc/imx_rsrc.h>
 #include <misc.h>
+#include <asm/arch/lpcg.h>
 
 #include "clk-imx8.h"
 
-__weak ulong imx8_clk_get_rate(struct clk *clk)
+struct imx8_clks_collect *soc_data[] = {
+#ifdef CONFIG_IMX8QXP
+	&imx8qxp_clk_collect,
+#endif
+#ifdef CONFIG_IMX8QM
+	&imx8qm_clk_collect,
+#endif
+};
+
+static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id);
+static int __imx8_clk_enable(struct udevice *dev, ulong id, bool enable);
+static ulong __imx8_clk_set_rate(struct udevice *dev, ulong id, unsigned long rate);
+
+static struct imx8_clks_collect * find_clks_collect(struct udevice *dev)
+{
+	ulong data = (ulong)dev_get_driver_data(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(soc_data); i++) {
+		if (soc_data[i]->match_flag == data)
+			return soc_data[i];
+	}
+
+	return NULL;
+}
+
+static void * check_imx8_clk(struct udevice *dev, enum imx8_clk_type type, ulong id, u32 size_of_clk)
+{
+	u32 i, size;
+	struct imx8_clks_collect *clks_col = find_clks_collect(dev);
+	struct imx8_clk_header *hdr;
+	ulong clks;
+
+	if (!clks_col || !(clks_col->clks[type].type_clks)) {
+		printf("%s fails to get clks for type %d\n",
+		       __func__, type);
+		return NULL;
+	}
+
+	clks = (ulong)(clks_col->clks[type].type_clks);
+	size = clks_col->clks[type].num;
+
+	for (i = 0; i < size; i++) {
+		hdr = (struct imx8_clk_header *)clks;
+		if (id == hdr->id)
+			return (void *)hdr;
+
+		clks += size_of_clk;
+	}
+
+	return NULL;
+}
+
+static ulong imx8_get_rate_lpcg(struct udevice *dev, struct imx8_lpcg_clks *lpcg_clk)
+{
+	if (lpcg_clk->parent_id != 0) {
+		if (lpcg_is_clock_on(lpcg_clk->lpcg, lpcg_clk->bit_idx >> 2)) {
+			return __imx8_clk_get_rate(dev, lpcg_clk->parent_id);
+		} else {
+			return 0;
+		}
+	} else {
+		return -ENOSYS;
+	}
+}
+
+static ulong imx8_get_rate_slice(struct udevice *dev, struct imx8_clks *slice_clk)
+{
+	int ret;
+	u32 rate;
+
+	ret = sc_pm_get_clock_rate(-1, slice_clk->rsrc, slice_clk->pm_clk,
+				   (sc_pm_clock_rate_t *)&rate);
+	if (ret) {
+		printf("%s err %d\n", __func__, ret);
+		return ret;
+	}
+
+	return rate;
+}
+
+static ulong imx8_get_rate_fixed(struct udevice *dev, struct imx8_fixed_clks *fixed_clk)
+{
+	return fixed_clk->rate;
+}
+
+static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id)
+{
+	void* clkdata;
+
+	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id, sizeof(struct imx8_lpcg_clks));
+	if (clkdata) {
+		return imx8_get_rate_lpcg(dev, (struct imx8_lpcg_clks *)clkdata);
+	}
+
+	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id, sizeof(struct imx8_clks));
+	if (clkdata) {
+		return imx8_get_rate_slice(dev, (struct imx8_clks *)clkdata);
+	}
+
+	clkdata = check_imx8_clk(dev, IMX8_CLK_FIXED, id, sizeof(struct imx8_fixed_clks));
+	if (clkdata) {
+		return imx8_get_rate_fixed(dev, (struct imx8_fixed_clks *)clkdata);
+	}
+
+	return -ENOSYS;
+}
+
+static ulong imx8_clk_get_rate(struct clk *clk)
+{
+	return __imx8_clk_get_rate(clk->dev, clk->id);
+}
+
+static ulong imx8_set_rate_lpcg(struct udevice *dev, struct imx8_lpcg_clks *lpcg_clk, unsigned long rate)
+{
+	if (lpcg_clk->parent_id != 0) {
+		return __imx8_clk_set_rate(dev, lpcg_clk->parent_id, rate);
+	} else {
+		return -ENOSYS;
+	}
+}
+
+static ulong imx8_set_rate_slice(struct udevice *dev, struct imx8_clks *slice_clk, unsigned long rate)
+{
+	int ret;
+	u32 new_rate = rate;
+
+	ret = sc_pm_set_clock_rate(-1, slice_clk->rsrc, slice_clk->pm_clk, &new_rate);
+	if (ret) {
+		printf("%s err %d\n", __func__, ret);
+		return ret;
+	}
+
+	return new_rate;
+}
+
+static ulong imx8_set_rate_gpr(struct udevice *dev, struct imx8_gpr_clks *gpr_clk, unsigned long rate)
 {
+	ulong parent_rate;
+	u32 val;
+	int ret;
+
+	if (gpr_clk->parent_id == 0)
+		return -ENOSYS;
+
+	parent_rate = __imx8_clk_get_rate(dev, gpr_clk->parent_id);
+	if (parent_rate > 0) {
+		val = (rate < parent_rate) ? 1 : 0;
+
+		ret = sc_misc_set_control(-1, gpr_clk->rsrc,
+			gpr_clk->gpr_id, val);
+		if (ret) {
+			printf("%s err %d\n", __func__, ret);
+			return ret;
+		}
+
+		return rate;
+	}
+
+	return -ENOSYS;
+}
+
+static ulong __imx8_clk_set_rate(struct udevice *dev, ulong id, unsigned long rate)
+{
+	void* clkdata;
+
+	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id, sizeof(struct imx8_clks));
+	if (clkdata) {
+		return imx8_set_rate_slice(dev, (struct imx8_clks *)clkdata, rate);
+	}
+
+	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id, sizeof(struct imx8_lpcg_clks));
+	if (clkdata) {
+		return imx8_set_rate_lpcg(dev, (struct imx8_lpcg_clks *)clkdata, rate);
+	}
+
+	clkdata = check_imx8_clk(dev, IMX8_CLK_GPR, id, sizeof(struct imx8_gpr_clks));
+	if (clkdata) {
+		return imx8_set_rate_gpr(dev, (struct imx8_gpr_clks *)clkdata, rate);
+	}
+
+	return -ENOSYS;
+}
+
+static ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	return __imx8_clk_set_rate(clk->dev, clk->id, rate);
+
+}
+
+static int imx8_enable_slice(struct udevice *dev, struct imx8_clks *slice_clk, bool enable)
+{
+	int ret;
+
+	ret = sc_pm_clock_enable(-1, slice_clk->rsrc, slice_clk->pm_clk, enable, 0);
+	if (ret) {
+		printf("%s err %d\n", __func__, ret);
+		return ret;
+	}
+
 	return 0;
 }
 
-__weak ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
+static int imx8_enable_lpcg(struct udevice *dev, struct imx8_lpcg_clks *lpcg_clk, bool enable)
 {
+	if (enable) {
+		if (lpcg_clk->parent_id != 0) {
+			__imx8_clk_enable(dev, lpcg_clk->parent_id, enable);
+		}
+
+		lpcg_clock_on(lpcg_clk->lpcg, lpcg_clk->bit_idx >> 2);
+	} else {
+		lpcg_clock_off(lpcg_clk->lpcg, lpcg_clk->bit_idx >> 2);
+
+		if (lpcg_clk->parent_id != 0) {
+			__imx8_clk_enable(dev, lpcg_clk->parent_id, enable);
+		}
+	}
+
 	return 0;
 }
 
-__weak int __imx8_clk_enable(struct clk *clk, bool enable)
+static int __imx8_clk_enable(struct udevice *dev, ulong id, bool enable)
 {
-	return -ENOTSUPP;
+	void* clkdata;
+
+	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id, sizeof(struct imx8_lpcg_clks));
+	if (clkdata) {
+		return imx8_enable_lpcg(dev, (struct imx8_lpcg_clks *)clkdata, enable);
+	}
+
+	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id, sizeof(struct imx8_clks));
+	if (clkdata) {
+		return imx8_enable_slice(dev, (struct imx8_clks *)clkdata, enable);
+	}
+
+	return -ENOSYS;
 }
 
 static int imx8_clk_disable(struct clk *clk)
 {
-	return __imx8_clk_enable(clk, 0);
+	return __imx8_clk_enable(clk->dev, clk->id, 0);
 }
 
 static int imx8_clk_enable(struct clk *clk)
 {
-	return __imx8_clk_enable(clk, 1);
+	return __imx8_clk_enable(clk->dev, clk->id, 1);
+}
+
+static int imx8_set_parent_mux(struct udevice *dev, struct imx8_mux_clks *mux_clk, ulong pid)
+{
+	u32 i;
+	int ret;
+	struct imx8_clks *slice_clkdata;
+
+	slice_clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, mux_clk->slice_clk_id, sizeof(struct imx8_clks));
+	if (!slice_clkdata) {
+		printf("Error: fail to find slice clk %lu for this mux %lu\n", mux_clk->slice_clk_id, mux_clk->hdr.id);
+		return -EINVAL;
+	}
+
+	for (i = 0; i< CLK_IMX8_MAX_MUX_SEL; i++) {
+		if (pid == mux_clk->parent_clks[i]) {
+			ret = sc_pm_set_clock_parent(-1, slice_clkdata->rsrc,  slice_clkdata->pm_clk, i);
+			if (ret)
+				printf("Error: fail to set clock parent rsrc %d, pm_clk %d, parent clk %d\n",
+					slice_clkdata->rsrc,  slice_clkdata->pm_clk, i);
+			return ret;
+		}
+	}
+
+	return -ENOSYS;
+}
+
+static int imx8_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	void* clkdata;
+
+	clkdata = check_imx8_clk(clk->dev, IMX8_CLK_MUX, clk->id, sizeof(struct imx8_mux_clks));
+	if (clkdata) {
+		return imx8_set_parent_mux(clk->dev, (struct imx8_mux_clks *)clkdata, parent->id);
+	}
+
+	return -ENOSYS;
 }
 
 #if CONFIG_IS_ENABLED(CMD_CLK)
@@ -47,6 +309,9 @@ int soc_clk_dump(void)
 	struct clk clk;
 	unsigned long rate;
 	int i, ret;
+	u32 size;
+	struct imx8_clks *clks;
+	struct imx8_clks_collect *clks_col;
 
 	ret = uclass_get_device_by_driver(UCLASS_CLK,
 					  DM_GET_DRIVER(imx8_clk), &dev);
@@ -55,8 +320,19 @@ int soc_clk_dump(void)
 
 	printf("Clk\t\tHz\n");
 
-	for (i = 0; i < num_clks; i++) {
-		clk.id = imx8_clk_names[i].id;
+	clks_col = find_clks_collect(dev);
+
+	if (!clks_col || !(clks_col->clks[IMX8_CLK_SLICE].type_clks)) {
+		printf("%s fails to get clks for type %d\n",
+		       __func__, IMX8_CLK_SLICE);
+		return -ENODEV;
+	}
+
+	clks = (struct imx8_clks *)(clks_col->clks[IMX8_CLK_SLICE].type_clks);
+	size = clks_col->clks[IMX8_CLK_SLICE].num;
+
+	for (i = 0; i < size; i++) {
+		clk.id = clks[i].hdr.id;
 		ret = clk_request(dev, &clk);
 		if (ret < 0) {
 			debug("%s clk_request() failed: %d\n", __func__, ret);
@@ -70,21 +346,22 @@ int soc_clk_dump(void)
 
 		if (ret == -ENOTSUPP) {
 			printf("clk ID %lu not supported yet\n",
-			       imx8_clk_names[i].id);
+			       clks[i].hdr.id);
 			continue;
 		}
 		if (ret < 0) {
 			printf("%s %lu: get_rate err: %d\n",
-			       __func__, imx8_clk_names[i].id, ret);
+			       __func__, clks[i].hdr.id, ret);
 			continue;
 		}
 
 		printf("%s(%3lu):\t%lu\n",
-		       imx8_clk_names[i].name, imx8_clk_names[i].id, rate);
+		       clks[i].hdr.name, clks[i].hdr.id, rate);
 	}
 
 	return 0;
 }
+
 #endif
 
 static struct clk_ops imx8_clk_ops = {
@@ -92,6 +369,7 @@ static struct clk_ops imx8_clk_ops = {
 	.get_rate = imx8_clk_get_rate,
 	.enable = imx8_clk_enable,
 	.disable = imx8_clk_disable,
+	.set_parent = imx8_clk_set_parent,
 };
 
 static int imx8_clk_probe(struct udevice *dev)
@@ -100,8 +378,8 @@ static int imx8_clk_probe(struct udevice *dev)
 }
 
 static const struct udevice_id imx8_clk_ids[] = {
-	{ .compatible = "fsl,imx8qxp-clk" },
-	{ .compatible = "fsl,imx8qm-clk" },
+	{ .compatible = "fsl,imx8qxp-clk", .data = FLAG_CLK_IMX8_IMX8QXP, },
+	{ .compatible = "fsl,imx8qm-clk", .data = FLAG_CLK_IMX8_IMX8QM, },
 	{ },
 };
 
diff --git a/drivers/clk/imx/clk-imx8.h b/drivers/clk/imx/clk-imx8.h
index 68ad675..c0566f8 100644
--- a/drivers/clk/imx/clk-imx8.h
+++ b/drivers/clk/imx/clk-imx8.h
@@ -4,16 +4,87 @@
  * Peng Fan <peng.fan@nxp.com>
  */
 
-struct imx8_clks {
+#define CLK_IMX8_MAX_MUX_SEL 5
+
+#define FLAG_CLK_IMX8_IMX8QM	BIT(0)
+#define FLAG_CLK_IMX8_IMX8QXP	BIT(1)
+
+struct imx8_clk_header {
 	ulong id;
+#if CONFIG_IS_ENABLED(CMD_CLK)
 	const char *name;
+#endif
+};
+
+struct imx8_clks {
+	struct imx8_clk_header hdr;
+	u16 rsrc;
+	sc_pm_clk_t pm_clk;
+};
+
+struct imx8_fixed_clks {
+	struct imx8_clk_header hdr;
+	ulong rate;
+};
+
+struct imx8_gpr_clks {
+	struct imx8_clk_header hdr;
+	u16 rsrc;
+	sc_ctrl_t gpr_id;
+	ulong parent_id;
+};
+
+struct imx8_lpcg_clks {
+	struct imx8_clk_header hdr;
+	u8 bit_idx;
+	u32 lpcg;
+	ulong parent_id;
+};
+
+struct imx8_mux_clks {
+	struct imx8_clk_header hdr;
+	ulong slice_clk_id;
+	ulong parent_clks[CLK_IMX8_MAX_MUX_SEL];
+};
+
+enum imx8_clk_type {
+	IMX8_CLK_SLICE 		= 0,
+	IMX8_CLK_FIXED 	= 1,
+	IMX8_CLK_GPR 		= 2,
+	IMX8_CLK_LPCG 		= 3,
+	IMX8_CLK_MUX 		= 4,
+	IMX8_CLK_END		= 5,
+};
+
+struct imx8_clk_pair {
+	void *type_clks;
+	u32 num;
+};
+
+struct imx8_clks_collect {
+	struct imx8_clk_pair clks[IMX8_CLK_END];
+	ulong match_flag;
 };
 
 #if CONFIG_IS_ENABLED(CMD_CLK)
-extern struct imx8_clks imx8_clk_names[];
-extern int num_clks;
+#define CLK_3(ID, NAME, MEM2) \
+	{ { ID, NAME, }, MEM2, }
+#define CLK_4(ID, NAME, MEM2, MEM3) \
+	{ { ID, NAME, }, MEM2, MEM3, }
+#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
+	{ { ID, NAME, }, MEM2, MEM3, MEM4, }
+#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
+	{ { ID, NAME, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
+#else
+#define CLK_3(ID, NAME, MEM2) \
+	{ { ID, }, MEM2, }
+#define CLK_4(ID, NAME, MEM2, MEM3) \
+	{ { ID, }, MEM2, MEM3, }
+#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
+	{ { ID, }, MEM2, MEM3, MEM4, }
+#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
+	{ { ID, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
 #endif
 
-ulong imx8_clk_get_rate(struct clk *clk);
-ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate);
-int __imx8_clk_enable(struct clk *clk, bool enable);
+extern struct imx8_clks_collect imx8qxp_clk_collect;
+extern struct imx8_clks_collect imx8qm_clk_collect;
diff --git a/drivers/clk/imx/clk-imx8qm.c b/drivers/clk/imx/clk-imx8qm.c
index a6b09d2..f4ee007 100644
--- a/drivers/clk/imx/clk-imx8qm.c
+++ b/drivers/clk/imx/clk-imx8qm.c
@@ -12,314 +12,189 @@
 #include <dt-bindings/clock/imx8qm-clock.h>
 #include <dt-bindings/soc/imx_rsrc.h>
 #include <misc.h>
+#include <asm/arch/lpcg.h>
 
 #include "clk-imx8.h"
 
-#if CONFIG_IS_ENABLED(CMD_CLK)
-struct imx8_clks imx8_clk_names[] = {
-	{ IMX8QM_A53_DIV, "A53_DIV" },
-	{ IMX8QM_UART0_CLK, "UART0" },
-	{ IMX8QM_UART1_CLK, "UART1" },
-	{ IMX8QM_UART2_CLK, "UART2" },
-	{ IMX8QM_UART3_CLK, "UART3" },
-	{ IMX8QM_SDHC0_CLK, "SDHC0" },
-	{ IMX8QM_SDHC1_CLK, "SDHC1" },
-	{ IMX8QM_SDHC2_CLK, "SDHC2" },
-	{ IMX8QM_ENET0_AHB_CLK, "ENET0_AHB" },
-	{ IMX8QM_ENET0_IPG_CLK, "ENET0_IPG" },
-	{ IMX8QM_ENET0_REF_DIV, "ENET0_REF" },
-	{ IMX8QM_ENET0_PTP_CLK, "ENET0_PTP" },
-	{ IMX8QM_ENET1_AHB_CLK, "ENET1_AHB" },
-	{ IMX8QM_ENET1_IPG_CLK, "ENET1_IPG" },
-	{ IMX8QM_ENET1_REF_DIV, "ENET1_REF" },
-	{ IMX8QM_ENET1_PTP_CLK, "ENET1_PTP" },
+static struct imx8_clks imx8qm_clks[] = {
+	CLK_4( IMX8QM_A53_DIV, "A53_DIV", SC_R_A53, SC_PM_CLK_CPU ),
+	CLK_4( IMX8QM_A72_DIV, "A72_DIV", SC_R_A72, SC_PM_CLK_CPU ),
+	CLK_4( IMX8QM_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_LVDS0_I2C0_DIV, "LVDS0 I2C0 DIV", SC_R_LVDS_0_I2C_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_LVDS0_I2C1_DIV, "LVDS0 I2C1 DIV", SC_R_LVDS_0_I2C_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_LVDS1_I2C0_DIV, "LVDS1 I2C0 DIV", SC_R_LVDS_1_I2C_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_LVDS1_I2C1_DIV, "LVDS1 I2C1 DIV", SC_R_LVDS_1_I2C_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QM_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QM_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV", SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QM_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV", SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QM_CSI0_I2C0_DIV, "CSI0 I2C0_DIV", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_CSI1_I2C0_DIV, "CSI1 I2C0_DIV", SC_R_CSI_1_I2C_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_HDMI_I2C0_DIV, "HDMI I2C0_DIV", SC_R_HDMI_I2C_0, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QM_HDMI_IPG_CLK, "HDMI IPG_CLK", SC_R_HDMI, SC_PM_CLK_MISC ),
+	CLK_4( IMX8QM_HDMI_RX_I2C0_DIV, "HDMI RX I2C_DIV", SC_R_HDMI_RX_I2C_0, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QM_UART0_DIV, "UART0_DIV", SC_R_UART_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_UART1_DIV, "UART1_DIV", SC_R_UART_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_UART2_DIV, "UART2_DIV", SC_R_UART_2, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_UART3_DIV, "UART3_DIV", SC_R_UART_3, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_ENET0_ROOT_DIV, "ENET0_ROOT_DIV", SC_R_ENET_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_ENET0_RGMII_DIV, "ENET0_RGMII_DIV", SC_R_ENET_0, SC_PM_CLK_MISC0 ),
+	CLK_4( IMX8QM_ENET1_ROOT_DIV, "ENET1_ROOT_DIV", SC_R_ENET_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_ENET1_RGMII_DIV, "ENET1_RGMII_DIV", SC_R_ENET_1, SC_PM_CLK_MISC0 ),
+
+	CLK_4( IMX8QM_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2, SC_PM_CLK_PER ),
+	CLK_4( IMX8QM_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2, SC_PM_CLK_MST_BUS ),
+	CLK_4( IMX8QM_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2, SC_PM_CLK_MISC ),
+
+	CLK_4( IMX8QM_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0, SC_PM_CLK_PER ),
+
+	CLK_4( IMX8QM_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND, SC_PM_CLK_MST_BUS ),
+	CLK_4( IMX8QM_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND, SC_PM_CLK_PER ),
 };
 
-int num_clks = ARRAY_SIZE(imx8_clk_names);
-#endif
-
-ulong imx8_clk_get_rate(struct clk *clk)
-{
-	sc_pm_clk_t pm_clk;
-	ulong rate;
-	u16 resource;
-	int ret;
-
-	debug("%s(#%lu)\n", __func__, clk->id);
-
-	switch (clk->id) {
-	case IMX8QM_A53_DIV:
-		resource = SC_R_A53;
-		pm_clk = SC_PM_CLK_CPU;
-		break;
-	case IMX8QM_I2C0_CLK:
-		resource = SC_R_I2C_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_I2C1_CLK:
-		resource = SC_R_I2C_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_I2C2_CLK:
-		resource = SC_R_I2C_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_I2C3_CLK:
-		resource = SC_R_I2C_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_SDHC0_IPG_CLK:
-	case IMX8QM_SDHC0_CLK:
-	case IMX8QM_SDHC0_DIV:
-		resource = SC_R_SDHC_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_SDHC1_IPG_CLK:
-	case IMX8QM_SDHC1_CLK:
-	case IMX8QM_SDHC1_DIV:
-		resource = SC_R_SDHC_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_SDHC2_IPG_CLK:
-	case IMX8QM_SDHC2_CLK:
-	case IMX8QM_SDHC2_DIV:
-		resource = SC_R_SDHC_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART0_IPG_CLK:
-	case IMX8QM_UART0_CLK:
-		resource = SC_R_UART_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART1_CLK:
-		resource = SC_R_UART_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART2_CLK:
-		resource = SC_R_UART_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART3_CLK:
-		resource = SC_R_UART_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_ENET0_IPG_CLK:
-	case IMX8QM_ENET0_AHB_CLK:
-	case IMX8QM_ENET0_REF_DIV:
-	case IMX8QM_ENET0_PTP_CLK:
-		resource = SC_R_ENET_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_ENET1_IPG_CLK:
-	case IMX8QM_ENET1_AHB_CLK:
-	case IMX8QM_ENET1_REF_DIV:
-	case IMX8QM_ENET1_PTP_CLK:
-		resource = SC_R_ENET_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	default:
-		if (clk->id < IMX8QM_UART0_IPG_CLK ||
-		    clk->id >= IMX8QM_CLK_END) {
-			printf("%s(Invalid clk ID #%lu)\n",
-			       __func__, clk->id);
-			return -EINVAL;
-		}
-		return -ENOTSUPP;
-	};
-
-	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
-				   (sc_pm_clock_rate_t *)&rate);
-	if (ret) {
-		printf("%s err %d\n", __func__, ret);
-		return ret;
-	}
-
-	return rate;
-}
-
-ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	sc_pm_clk_t pm_clk;
-	u32 new_rate = rate;
-	u16 resource;
-	int ret;
-
-	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
-
-	switch (clk->id) {
-	case IMX8QM_I2C0_CLK:
-		resource = SC_R_I2C_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_I2C1_CLK:
-		resource = SC_R_I2C_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_I2C2_CLK:
-		resource = SC_R_I2C_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_I2C3_CLK:
-		resource = SC_R_I2C_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART0_CLK:
-		resource = SC_R_UART_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART1_CLK:
-		resource = SC_R_UART_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART2_CLK:
-		resource = SC_R_UART_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART3_CLK:
-		resource = SC_R_UART_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_SDHC0_IPG_CLK:
-	case IMX8QM_SDHC0_CLK:
-	case IMX8QM_SDHC0_DIV:
-		resource = SC_R_SDHC_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_SDHC1_IPG_CLK:
-	case IMX8QM_SDHC1_CLK:
-	case IMX8QM_SDHC1_DIV:
-		resource = SC_R_SDHC_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_SDHC2_IPG_CLK:
-	case IMX8QM_SDHC2_CLK:
-	case IMX8QM_SDHC2_DIV:
-		resource = SC_R_SDHC_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_ENET0_IPG_CLK:
-	case IMX8QM_ENET0_AHB_CLK:
-	case IMX8QM_ENET0_REF_DIV:
-	case IMX8QM_ENET0_PTP_CLK:
-	case IMX8QM_ENET0_ROOT_DIV:
-		resource = SC_R_ENET_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_ENET1_IPG_CLK:
-	case IMX8QM_ENET1_AHB_CLK:
-	case IMX8QM_ENET1_REF_DIV:
-	case IMX8QM_ENET1_PTP_CLK:
-	case IMX8QM_ENET1_ROOT_DIV:
-		resource = SC_R_ENET_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	default:
-		if (clk->id < IMX8QM_UART0_IPG_CLK ||
-		    clk->id >= IMX8QM_CLK_END) {
-			printf("%s(Invalid clk ID #%lu)\n",
-			       __func__, clk->id);
-			return -EINVAL;
-		}
-		return -ENOTSUPP;
-	};
-
-	ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
-	if (ret) {
-		printf("%s err %d\n", __func__, ret);
-		return ret;
-	}
-
-	return new_rate;
-}
-
-int __imx8_clk_enable(struct clk *clk, bool enable)
-{
-	sc_pm_clk_t pm_clk;
-	u16 resource;
-	int ret;
+static struct imx8_fixed_clks imx8qm_fixed_clks[] = {
+	CLK_3( IMX8QM_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", SC_83MHZ ),
+	CLK_3( IMX8QM_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK", SC_166MHZ ),
+	CLK_3( IMX8QM_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK", SC_333MHZ ),
+	CLK_3( IMX8QM_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ ),
+	CLK_3( IMX8QM_IPG_MIPI_CSI_CLK_ROOT, "IPG_MIPI_CLK", SC_120MHZ ),
+	CLK_3( IMX8QM_LVDS_IPG_CLK, "IPG_LVDS_CLK", SC_24MHZ ),
+	CLK_3( IMX8QM_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
+	CLK_3( IMX8QM_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
+	CLK_3( IMX8QM_MIPI0_CLK_ROOT, "MIPI0_CLK", SC_120MHZ ),
+	CLK_3( IMX8QM_MIPI1_CLK_ROOT, "MIPI1_CLK", SC_120MHZ ),
+	CLK_3( IMX8QM_HDMI_RX_IPG_CLK, "HDMI_RX_IPG_CLK", SC_200MHZ ),
+};
 
-	debug("%s(#%lu)\n", __func__, clk->id);
+static struct imx8_gpr_clks imx8qm_gpr_clks[] = {
+	CLK_5( IMX8QM_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0, SC_C_CLKDIV, IMX8QM_ENET0_ROOT_DIV ),
+	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL, "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
+	CLK_4( IMX8QM_ENET0_RMII_TX_SEL, "ENET0_RMII_TX", SC_R_ENET_0, SC_C_TXCLK ),
+	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK, "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
+	CLK_4( IMX8QM_ENET0_REF_50MHZ_CLK, "ENET0_REF_50", SC_R_ENET_0, SC_C_DISABLE_50 ),
+
+	CLK_5( IMX8QM_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1, SC_C_CLKDIV, IMX8QM_ENET1_ROOT_DIV ),
+	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL, "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
+	CLK_4( IMX8QM_ENET1_RMII_TX_SEL, "ENET1_RMII_TX", SC_R_ENET_1, SC_C_TXCLK ),
+	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK, "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
+	CLK_4( IMX8QM_ENET1_REF_50MHZ_CLK, "ENET1_REF_50", SC_R_ENET_1, SC_C_DISABLE_50 ),
+};
 
-	switch (clk->id) {
-	case IMX8QM_I2C0_CLK:
-		resource = SC_R_I2C_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_I2C1_CLK:
-		resource = SC_R_I2C_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_I2C2_CLK:
-		resource = SC_R_I2C_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_I2C3_CLK:
-		resource = SC_R_I2C_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART0_CLK:
-		resource = SC_R_UART_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART1_CLK:
-		resource = SC_R_UART_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART2_CLK:
-		resource = SC_R_UART_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_UART3_CLK:
-		resource = SC_R_UART_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_SDHC0_IPG_CLK:
-	case IMX8QM_SDHC0_CLK:
-	case IMX8QM_SDHC0_DIV:
-		resource = SC_R_SDHC_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_SDHC1_IPG_CLK:
-	case IMX8QM_SDHC1_CLK:
-	case IMX8QM_SDHC1_DIV:
-		resource = SC_R_SDHC_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_SDHC2_IPG_CLK:
-	case IMX8QM_SDHC2_CLK:
-	case IMX8QM_SDHC2_DIV:
-		resource = SC_R_SDHC_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_ENET0_IPG_CLK:
-	case IMX8QM_ENET0_AHB_CLK:
-	case IMX8QM_ENET0_REF_DIV:
-	case IMX8QM_ENET0_PTP_CLK:
-		resource = SC_R_ENET_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QM_ENET1_IPG_CLK:
-	case IMX8QM_ENET1_AHB_CLK:
-	case IMX8QM_ENET1_REF_DIV:
-	case IMX8QM_ENET1_PTP_CLK:
-		resource = SC_R_ENET_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	default:
-		if (clk->id < IMX8QM_UART0_IPG_CLK ||
-		    clk->id >= IMX8QM_CLK_END) {
-			printf("%s(Invalid clk ID #%lu)\n",
-			       __func__, clk->id);
-			return -EINVAL;
-		}
-		return -ENOTSUPP;
-	}
+static struct imx8_lpcg_clks imx8qm_lpcg_clks[] = {
+	CLK_5( IMX8QM_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG, IMX8QM_I2C0_DIV ),
+	CLK_5( IMX8QM_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QM_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG, IMX8QM_I2C1_DIV ),
+	CLK_5( IMX8QM_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QM_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG, IMX8QM_I2C2_DIV ),
+	CLK_5( IMX8QM_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QM_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG, IMX8QM_I2C3_DIV ),
+	CLK_5( IMX8QM_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
+
+	CLK_5( IMX8QM_LVDS0_I2C0_CLK, "LVDS0_I2C0_CLK", 0, DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS0_I2C0_DIV ),
+	CLK_5( IMX8QM_LVDS0_I2C0_IPG_CLK, "LVDS0_I2C0_IPG", 16, DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
+	CLK_5( IMX8QM_LVDS0_I2C1_CLK, "LVDS0_I2C1_CLK", 0, DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS0_I2C1_DIV ),
+	CLK_5( IMX8QM_LVDS0_I2C1_IPG_CLK, "LVDS0_I2C1_IPG", 16, DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ),
+	CLK_5( IMX8QM_LVDS1_I2C0_CLK, "LVDS1_I2C0_CLK", 0, DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS1_I2C0_DIV ),
+	CLK_5( IMX8QM_LVDS1_I2C0_IPG_CLK, "LVDS1_I2C0_IPG", 16, DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
+	CLK_5( IMX8QM_LVDS1_I2C1_CLK, "LVDS1_I2C1_CLK", 0, DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS1_I2C1_DIV ),
+	CLK_5( IMX8QM_LVDS1_I2C1_IPG_CLK, "LVDS1_I2C1_IPG", 16, DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ),
+
+	CLK_5( IMX8QM_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0, MIPI_DSI_0_LPCG + 0x1c, IMX8QM_MIPI0_I2C0_DIV ),
+	CLK_5( IMX8QM_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 0, MIPI_DSI_0_LPCG + 0x14,  IMX8QM_MIPI0_I2C0_IPG_S_CLK),
+	CLK_5( IMX8QM_MIPI0_I2C0_IPG_S_CLK, "MIPI0_I2C0_IPG_S", 0, MIPI_DSI_0_LPCG + 0x18, IMX8QM_MIPI0_CLK_ROOT ),
+	CLK_5( IMX8QM_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0, MIPI_DSI_0_LPCG + 0x2c, IMX8QM_MIPI0_I2C1_DIV ),
+	CLK_5( IMX8QM_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 0, MIPI_DSI_0_LPCG + 0x24,  IMX8QM_MIPI0_I2C1_IPG_S_CLK),
+	CLK_5( IMX8QM_MIPI0_I2C1_IPG_S_CLK, "MIPI0_I2C1_IPG_S", 0, MIPI_DSI_0_LPCG + 0x28, IMX8QM_MIPI0_CLK_ROOT ),
+	CLK_5( IMX8QM_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0, MIPI_DSI_1_LPCG + 0x1c, IMX8QM_MIPI1_I2C0_DIV ),
+	CLK_5( IMX8QM_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 0, MIPI_DSI_1_LPCG + 0x14, IMX8QM_MIPI1_I2C0_IPG_S_CLK),
+	CLK_5( IMX8QM_MIPI1_I2C0_IPG_S_CLK, "MIPI1_I2C0_IPG_S", 0, MIPI_DSI_1_LPCG + 0x18, IMX8QM_MIPI1_CLK_ROOT ),
+	CLK_5( IMX8QM_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0, MIPI_DSI_1_LPCG + 0x2c, IMX8QM_MIPI1_I2C1_DIV ),
+	CLK_5( IMX8QM_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 0, MIPI_DSI_1_LPCG + 0x24, IMX8QM_MIPI1_I2C1_IPG_S_CLK),
+	CLK_5( IMX8QM_MIPI1_I2C1_IPG_S_CLK, "MIPI1_I2C1_IPG_S", 0, MIPI_DSI_1_LPCG + 0x28, IMX8QM_MIPI1_CLK_ROOT ),
+
+	CLK_5( IMX8QM_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0, MIPI_CSI_0_LPCG + 0x14, IMX8QM_CSI0_I2C0_DIV ),
+	CLK_5( IMX8QM_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16, MIPI_CSI_0_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
+	CLK_5( IMX8QM_CSI1_I2C0_CLK, "CSI1_I2C0_CLK", 0, MIPI_CSI_1_LPCG + 0x14, IMX8QM_CSI1_I2C0_DIV ),
+	CLK_5( IMX8QM_CSI1_I2C0_IPG_CLK, "CSI1_I2C0_IPG", 16, MIPI_CSI_1_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
+	CLK_5( IMX8QM_HDMI_I2C0_CLK, "HDMI_I2C0_CLK", 0, DI_HDMI_LPCG, IMX8QM_HDMI_I2C0_DIV ),
+	CLK_5( IMX8QM_HDMI_I2C_IPG_CLK, "HDMI_I2C0_IPG", 16, DI_HDMI_LPCG, IMX8QM_HDMI_IPG_CLK ),
+	CLK_5( IMX8QM_HDMI_RX_I2C_DIV_CLK, "HDMI RX_I2C_DIV_CLK", 0, MIPI_DSI_0_LPCG + 0x14, IMX8QM_MIPI0_I2C0_DIV ),
+	CLK_5( IMX8QM_HDMI_RX_I2C0_CLK, "HDMI RX_I2C_CLK", 0, MIPI_DSI_0_LPCG + 0x10, IMX8QM_HDMI_RX_I2C_DIV_CLK ),
+	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_CLK, "HDMI_RX_I2C_IPG", 0, RX_HDMI_LPCG + 0x18,  IMX8QM_HDMI_RX_I2C_IPG_S_CLK),
+	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_S_CLK, "HDMI_I2C_IPG_S", 0, RX_HDMI_LPCG + 0x1c, IMX8QM_HDMI_RX_IPG_CLK ),
+
+	CLK_5( IMX8QM_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG, IMX8QM_UART0_DIV ),
+	CLK_5( IMX8QM_UART0_IPG_CLK, "UART0_IPG", 16, LPUART_0_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QM_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG, IMX8QM_UART1_DIV ),
+	CLK_5( IMX8QM_UART1_IPG_CLK, "UART1_IPG", 16, LPUART_1_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QM_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG, IMX8QM_UART2_DIV ),
+	CLK_5( IMX8QM_UART2_IPG_CLK, "UART2_IPG", 16, LPUART_2_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QM_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG, IMX8QM_UART3_DIV ),
+	CLK_5( IMX8QM_UART3_IPG_CLK, "UART3_IPG", 16, LPUART_3_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
+
+	CLK_5( IMX8QM_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG, IMX8QM_SDHC0_DIV ),
+	CLK_5( IMX8QM_SDHC0_IPG_CLK, "SDHC0_IPG", 16, USDHC_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG, IMX8QM_SDHC1_DIV ),
+	CLK_5( IMX8QM_SDHC1_IPG_CLK, "SDHC1_IPG", 16, USDHC_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG, IMX8QM_SDHC2_DIV ),
+	CLK_5( IMX8QM_SDHC2_IPG_CLK, "SDHC2_IPG", 16, USDHC_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+
+	CLK_5( IMX8QM_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20, ENET_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG, IMX8QM_ENET0_IPG_S_CLK ),
+	CLK_5( IMX8QM_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG, IMX8QM_ENET0_ROOT_DIV ),
+	CLK_5( IMX8QM_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG, IMX8QM_ENET0_ROOT_DIV  ),
+	CLK_5( IMX8QM_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12, ENET_0_LPCG, IMX8QM_ENET0_RMII_TX_SEL  ),
+	CLK_5( IMX8QM_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0, ENET_0_LPCG + 0x4, IMX8QM_ENET0_RGMII_DIV  ),
+
+	CLK_5( IMX8QM_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20, ENET_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG, IMX8QM_ENET1_IPG_S_CLK ),
+	CLK_5( IMX8QM_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG, IMX8QM_ENET1_ROOT_DIV ),
+	CLK_5( IMX8QM_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG, IMX8QM_ENET1_ROOT_DIV  ),
+	CLK_5( IMX8QM_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12, ENET_1_LPCG, IMX8QM_ENET1_RMII_TX_SEL  ),
+	CLK_5( IMX8QM_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0, ENET_1_LPCG + 0x4, IMX8QM_ENET1_RGMII_DIV  ),
+
+	CLK_5( IMX8QM_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18, FSPI_0_LPCG, IMX8QM_LSIO_BUS_CLK ),
+	CLK_5( IMX8QM_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14, FSPI_0_LPCG, IMX8QM_FSPI0_IPG_S_CLK ),
+	CLK_5( IMX8QM_FSPI0_HCLK, "FSPI0_HCLK", 0x10, FSPI_0_LPCG, IMX8QM_LSIO_MEM_CLK ),
+	CLK_5( IMX8QM_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG, IMX8QM_FSPI0_DIV ),
+
+	CLK_5( IMX8QM_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24, USB_2_LPCG, IMX8QM_AHB_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16, USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_USB2_OH_IPG_S_PL301_CLK, "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28, USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+
+	CLK_5( IMX8QM_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG, IMX8QM_USB3_IPG_CLK ),
+	CLK_5( IMX8QM_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG, IMX8QM_USB3_ACLK_DIV ),
+	CLK_5( IMX8QM_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG, IMX8QM_USB3_BUS_DIV ),
+	CLK_5( IMX8QM_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG, IMX8QM_USB3_LPM_DIV ),
+
+	CLK_5( IMX8QM_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20, NAND_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
+	CLK_5( IMX8QM_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4, NAND_LPCG, IMX8QM_GPMI_BCH_IO_DIV ),
+	CLK_5( IMX8QM_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG, IMX8QM_GPMI_BCH_DIV ),
+	CLK_5( IMX8QM_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG + 0x4, IMX8QM_AXI_CONN_CLK_ROOT ),
+};
 
-	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
-	if (ret) {
-		printf("%s err %d\n", __func__, ret);
-		return ret;
-	}
+struct imx8_mux_clks imx8qm_mux_clks[] = {
+};
 
-	return 0;
-}
+struct imx8_clks_collect imx8qm_clk_collect = {
+	{
+		{&imx8qm_clks, ARRAY_SIZE(imx8qm_clks)},
+		{&imx8qm_fixed_clks, ARRAY_SIZE(imx8qm_fixed_clks)},
+		{&imx8qm_gpr_clks, ARRAY_SIZE(imx8qm_gpr_clks)},
+		{&imx8qm_lpcg_clks, ARRAY_SIZE(imx8qm_lpcg_clks)},
+		{&imx8qm_mux_clks, ARRAY_SIZE(imx8qm_mux_clks)},
+	},
+	FLAG_CLK_IMX8_IMX8QM,
+};
diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
index 1fca36a..8181a97 100644
--- a/drivers/clk/imx/clk-imx8qxp.c
+++ b/drivers/clk/imx/clk-imx8qxp.c
@@ -12,300 +12,156 @@
 #include <dt-bindings/clock/imx8qxp-clock.h>
 #include <dt-bindings/soc/imx_rsrc.h>
 #include <misc.h>
+#include <asm/arch/lpcg.h>
 
 #include "clk-imx8.h"
 
-#if CONFIG_IS_ENABLED(CMD_CLK)
-struct imx8_clks imx8_clk_names[] = {
-	{ IMX8QXP_A35_DIV, "A35_DIV" },
-	{ IMX8QXP_I2C0_CLK, "I2C0" },
-	{ IMX8QXP_I2C1_CLK, "I2C1" },
-	{ IMX8QXP_I2C2_CLK, "I2C2" },
-	{ IMX8QXP_I2C3_CLK, "I2C3" },
-	{ IMX8QXP_UART0_CLK, "UART0" },
-	{ IMX8QXP_UART1_CLK, "UART1" },
-	{ IMX8QXP_UART2_CLK, "UART2" },
-	{ IMX8QXP_UART3_CLK, "UART3" },
-	{ IMX8QXP_SDHC0_CLK, "SDHC0" },
-	{ IMX8QXP_SDHC1_CLK, "SDHC1" },
-	{ IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" },
-	{ IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" },
-	{ IMX8QXP_ENET0_REF_DIV, "ENET0_REF" },
-	{ IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" },
-	{ IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" },
-	{ IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" },
-	{ IMX8QXP_ENET1_REF_DIV, "ENET1_REF" },
-	{ IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" },
+static struct imx8_clks imx8qxp_clks[] = {
+	CLK_4( IMX8QXP_A35_DIV, "A35_DIV", SC_R_A35, SC_PM_CLK_CPU ),
+	CLK_4( IMX8QXP_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QXP_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QXP_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV", SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QXP_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV", SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
+	CLK_4( IMX8QXP_CSI0_I2C0_DIV, "CSI0 I2C0_DIV", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_UART0_DIV, "UART0_DIV", SC_R_UART_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_UART1_DIV, "UART1_DIV", SC_R_UART_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_UART2_DIV, "UART2_DIV", SC_R_UART_2, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_UART3_DIV, "UART3_DIV", SC_R_UART_3, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_ENET0_ROOT_DIV, "ENET0_ROOT_DIV", SC_R_ENET_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_ENET0_RGMII_DIV, "ENET0_RGMII_DIV", SC_R_ENET_0, SC_PM_CLK_MISC0 ),
+	CLK_4( IMX8QXP_ENET1_ROOT_DIV, "ENET1_ROOT_DIV", SC_R_ENET_1, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_ENET1_RGMII_DIV, "ENET1_RGMII_DIV", SC_R_ENET_1, SC_PM_CLK_MISC0 ),
+	CLK_4( IMX8QXP_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2, SC_PM_CLK_MST_BUS ),
+	CLK_4( IMX8QXP_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2, SC_PM_CLK_MISC ),
+	CLK_4( IMX8QXP_LSIO_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0, SC_PM_CLK_PER ),
+	CLK_4( IMX8QXP_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND, SC_PM_CLK_MST_BUS ),
+	CLK_4( IMX8QXP_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND, SC_PM_CLK_PER ),
 };
 
-int num_clks = ARRAY_SIZE(imx8_clk_names);
-#endif
-
-ulong imx8_clk_get_rate(struct clk *clk)
-{
-	sc_pm_clk_t pm_clk;
-	ulong rate;
-	u16 resource;
-	int ret;
-
-	debug("%s(#%lu)\n", __func__, clk->id);
-
-	switch (clk->id) {
-	case IMX8QXP_A35_DIV:
-		resource = SC_R_A35;
-		pm_clk = SC_PM_CLK_CPU;
-		break;
-	case IMX8QXP_I2C0_CLK:
-		resource = SC_R_I2C_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_I2C1_CLK:
-		resource = SC_R_I2C_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_I2C2_CLK:
-		resource = SC_R_I2C_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_I2C3_CLK:
-		resource = SC_R_I2C_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_SDHC0_IPG_CLK:
-	case IMX8QXP_SDHC0_CLK:
-	case IMX8QXP_SDHC0_DIV:
-		resource = SC_R_SDHC_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_SDHC1_IPG_CLK:
-	case IMX8QXP_SDHC1_CLK:
-	case IMX8QXP_SDHC1_DIV:
-		resource = SC_R_SDHC_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART0_IPG_CLK:
-	case IMX8QXP_UART0_CLK:
-		resource = SC_R_UART_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART1_CLK:
-		resource = SC_R_UART_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART2_CLK:
-		resource = SC_R_UART_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART3_CLK:
-		resource = SC_R_UART_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_ENET0_IPG_CLK:
-	case IMX8QXP_ENET0_AHB_CLK:
-	case IMX8QXP_ENET0_REF_DIV:
-	case IMX8QXP_ENET0_PTP_CLK:
-		resource = SC_R_ENET_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_ENET1_IPG_CLK:
-	case IMX8QXP_ENET1_AHB_CLK:
-	case IMX8QXP_ENET1_REF_DIV:
-	case IMX8QXP_ENET1_PTP_CLK:
-		resource = SC_R_ENET_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	default:
-		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
-		    clk->id >= IMX8QXP_CLK_END) {
-			printf("%s(Invalid clk ID #%lu)\n",
-			       __func__, clk->id);
-			return -EINVAL;
-		}
-		return -ENOTSUPP;
-	};
-
-	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
-				   (sc_pm_clock_rate_t *)&rate);
-	if (ret) {
-		printf("%s err %d\n", __func__, ret);
-		return ret;
-	}
-
-	return rate;
-}
-
-ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	sc_pm_clk_t pm_clk;
-	u32 new_rate = rate;
-	u16 resource;
-	int ret;
-
-	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
-
-	switch (clk->id) {
-	case IMX8QXP_I2C0_CLK:
-		resource = SC_R_I2C_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_I2C1_CLK:
-		resource = SC_R_I2C_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_I2C2_CLK:
-		resource = SC_R_I2C_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_I2C3_CLK:
-		resource = SC_R_I2C_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART0_CLK:
-		resource = SC_R_UART_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART1_CLK:
-		resource = SC_R_UART_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART2_CLK:
-		resource = SC_R_UART_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART3_CLK:
-		resource = SC_R_UART_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_SDHC0_IPG_CLK:
-	case IMX8QXP_SDHC0_CLK:
-	case IMX8QXP_SDHC0_DIV:
-		resource = SC_R_SDHC_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_SDHC1_SEL:
-	case IMX8QXP_SDHC0_SEL:
-		return 0;
-	case IMX8QXP_SDHC1_IPG_CLK:
-	case IMX8QXP_SDHC1_CLK:
-	case IMX8QXP_SDHC1_DIV:
-		resource = SC_R_SDHC_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_ENET0_IPG_CLK:
-	case IMX8QXP_ENET0_AHB_CLK:
-	case IMX8QXP_ENET0_REF_DIV:
-	case IMX8QXP_ENET0_PTP_CLK:
-		resource = SC_R_ENET_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_ENET1_IPG_CLK:
-	case IMX8QXP_ENET1_AHB_CLK:
-	case IMX8QXP_ENET1_REF_DIV:
-	case IMX8QXP_ENET1_PTP_CLK:
-		resource = SC_R_ENET_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	default:
-		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
-		    clk->id >= IMX8QXP_CLK_END) {
-			printf("%s(Invalid clk ID #%lu)\n",
-			       __func__, clk->id);
-			return -EINVAL;
-		}
-		return -ENOTSUPP;
-	};
-
-	ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
-	if (ret) {
-		printf("%s err %d\n", __func__, ret);
-		return ret;
-	}
-
-	return new_rate;
-}
-
-int __imx8_clk_enable(struct clk *clk, bool enable)
-{
-	sc_pm_clk_t pm_clk;
-	u16 resource;
-	int ret;
+static struct imx8_fixed_clks imx8qxp_fixed_clks[] = {
+	CLK_3( IMX8QXP_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", SC_83MHZ ),
+	CLK_3( IMX8QXP_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK", SC_166MHZ ),
+	CLK_3( IMX8QXP_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK", SC_333MHZ ),
+	CLK_3( IMX8QXP_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ ),
+	CLK_3( IMX8QXP_MIPI_IPG_CLK, "IPG_MIPI_CLK", SC_120MHZ ),
+	CLK_3( IMX8QXP_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
+	CLK_3( IMX8QXP_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
+};
 
-	debug("%s(#%lu)\n", __func__, clk->id);
+static struct imx8_gpr_clks imx8qxp_gpr_clks[] = {
+	CLK_5( IMX8QXP_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0, SC_C_CLKDIV, IMX8QXP_ENET0_ROOT_DIV ),
+	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL, "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
+	CLK_4( IMX8QXP_ENET0_RMII_TX_SEL, "ENET0_RMII_TX", SC_R_ENET_0, SC_C_TXCLK ),
+	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK, "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
+	CLK_4( IMX8QXP_ENET0_REF_50MHZ_CLK, "ENET0_REF_50", SC_R_ENET_0, SC_C_DISABLE_50 ),
+
+	CLK_5( IMX8QXP_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1, SC_C_CLKDIV, IMX8QXP_ENET1_ROOT_DIV ),
+	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL, "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
+	CLK_4( IMX8QXP_ENET1_RMII_TX_SEL, "ENET1_RMII_TX", SC_R_ENET_1, SC_C_TXCLK ),
+	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK, "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
+	CLK_4( IMX8QXP_ENET1_REF_50MHZ_CLK, "ENET1_REF_50", SC_R_ENET_1, SC_C_DISABLE_50 ),
+};
 
-	switch (clk->id) {
-	case IMX8QXP_I2C0_CLK:
-		resource = SC_R_I2C_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_I2C1_CLK:
-		resource = SC_R_I2C_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_I2C2_CLK:
-		resource = SC_R_I2C_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_I2C3_CLK:
-		resource = SC_R_I2C_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART0_CLK:
-		resource = SC_R_UART_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART1_CLK:
-		resource = SC_R_UART_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART2_CLK:
-		resource = SC_R_UART_2;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_UART3_CLK:
-		resource = SC_R_UART_3;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_SDHC0_IPG_CLK:
-	case IMX8QXP_SDHC0_CLK:
-	case IMX8QXP_SDHC0_DIV:
-		resource = SC_R_SDHC_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_SDHC1_IPG_CLK:
-	case IMX8QXP_SDHC1_CLK:
-	case IMX8QXP_SDHC1_DIV:
-		resource = SC_R_SDHC_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_ENET0_IPG_CLK:
-	case IMX8QXP_ENET0_AHB_CLK:
-	case IMX8QXP_ENET0_REF_DIV:
-	case IMX8QXP_ENET0_PTP_CLK:
-		resource = SC_R_ENET_0;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	case IMX8QXP_ENET1_IPG_CLK:
-	case IMX8QXP_ENET1_AHB_CLK:
-	case IMX8QXP_ENET1_REF_DIV:
-	case IMX8QXP_ENET1_PTP_CLK:
-		resource = SC_R_ENET_1;
-		pm_clk = SC_PM_CLK_PER;
-		break;
-	default:
-		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
-		    clk->id >= IMX8QXP_CLK_END) {
-			printf("%s(Invalid clk ID #%lu)\n",
-			       __func__, clk->id);
-			return -EINVAL;
-		}
-		return -ENOTSUPP;
-	}
+static struct imx8_lpcg_clks imx8qxp_lpcg_clks[] = {
+	CLK_5( IMX8QXP_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG, IMX8QXP_I2C0_DIV ),
+	CLK_5( IMX8QXP_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QXP_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG, IMX8QXP_I2C1_DIV ),
+	CLK_5( IMX8QXP_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QXP_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG, IMX8QXP_I2C2_DIV ),
+	CLK_5( IMX8QXP_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QXP_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG, IMX8QXP_I2C3_DIV ),
+	CLK_5( IMX8QXP_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QXP_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0, DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI0_I2C0_DIV ),
+	CLK_5( IMX8QXP_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 16, DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
+	CLK_5( IMX8QXP_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0, DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI0_I2C1_DIV ),
+	CLK_5( IMX8QXP_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 16, DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
+	CLK_5( IMX8QXP_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0, DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI1_I2C0_DIV ),
+	CLK_5( IMX8QXP_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 16, DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
+	CLK_5( IMX8QXP_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0, DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI1_I2C1_DIV ),
+	CLK_5( IMX8QXP_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 16, DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
+	CLK_5( IMX8QXP_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0, MIPI_CSI_0_LPCG + 0x14, IMX8QXP_CSI0_I2C0_DIV ),
+	CLK_5( IMX8QXP_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16, MIPI_CSI_0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
+
+	CLK_5( IMX8QXP_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG, IMX8QXP_UART0_DIV ),
+	CLK_5( IMX8QXP_UART0_IPG_CLK, "UART0_IPG", 16, LPUART_0_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QXP_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG, IMX8QXP_UART1_DIV ),
+	CLK_5( IMX8QXP_UART1_IPG_CLK, "UART1_IPG", 16, LPUART_1_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QXP_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG, IMX8QXP_UART2_DIV ),
+	CLK_5( IMX8QXP_UART2_IPG_CLK, "UART2_IPG", 16, LPUART_2_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
+	CLK_5( IMX8QXP_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG, IMX8QXP_UART3_DIV ),
+	CLK_5( IMX8QXP_UART3_IPG_CLK, "UART3_IPG", 16, LPUART_3_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
+
+	CLK_5( IMX8QXP_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG, IMX8QXP_SDHC0_DIV ),
+	CLK_5( IMX8QXP_SDHC0_IPG_CLK, "SDHC0_IPG", 16, USDHC_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG, IMX8QXP_SDHC1_DIV ),
+	CLK_5( IMX8QXP_SDHC1_IPG_CLK, "SDHC1_IPG", 16, USDHC_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG, IMX8QXP_SDHC2_DIV ),
+	CLK_5( IMX8QXP_SDHC2_IPG_CLK, "SDHC2_IPG", 16, USDHC_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+
+	CLK_5( IMX8QXP_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20, ENET_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG, IMX8QXP_ENET0_IPG_S_CLK ),
+	CLK_5( IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG, IMX8QXP_ENET0_ROOT_DIV ),
+	CLK_5( IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG, IMX8QXP_ENET0_ROOT_DIV  ),
+	CLK_5( IMX8QXP_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12, ENET_0_LPCG, IMX8QXP_ENET0_RMII_TX_SEL  ),
+	CLK_5( IMX8QXP_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0, ENET_0_LPCG + 0x4, IMX8QXP_ENET0_RGMII_DIV  ),
+
+	CLK_5( IMX8QXP_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20, ENET_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG, IMX8QXP_ENET1_IPG_S_CLK ),
+	CLK_5( IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG, IMX8QXP_ENET1_ROOT_DIV ),
+	CLK_5( IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG, IMX8QXP_ENET1_ROOT_DIV  ),
+	CLK_5( IMX8QXP_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12, ENET_1_LPCG, IMX8QXP_ENET1_RMII_TX_SEL  ),
+	CLK_5( IMX8QXP_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0, ENET_1_LPCG + 0x4, IMX8QXP_ENET1_RGMII_DIV  ),
+
+	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18, FSPI_0_LPCG, IMX8QXP_LSIO_BUS_CLK ),
+	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14, FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_IPG_S_CLK ),
+	CLK_5( IMX8QXP_LSIO_FSPI0_HCLK, "FSPI0_HCLK", 0x10, FSPI_0_LPCG, IMX8QXP_LSIO_MEM_CLK ),
+	CLK_5( IMX8QXP_LSIO_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_DIV ),
+
+	CLK_5( IMX8QXP_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24, USB_2_LPCG, IMX8QXP_AHB_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16, USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_USB2_OH_IPG_S_PL301_CLK, "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28, USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+
+	CLK_5( IMX8QXP_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG, IMX8QXP_USB3_IPG_CLK ),
+	CLK_5( IMX8QXP_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG, IMX8QXP_USB3_ACLK_DIV ),
+	CLK_5( IMX8QXP_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG, IMX8QXP_USB3_BUS_DIV ),
+	CLK_5( IMX8QXP_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG, IMX8QXP_USB3_LPM_DIV ),
+
+	CLK_5( IMX8QXP_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20, NAND_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
+	CLK_5( IMX8QXP_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4, NAND_LPCG, IMX8QXP_GPMI_BCH_IO_DIV ),
+	CLK_5( IMX8QXP_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG, IMX8QXP_GPMI_BCH_DIV ),
+	CLK_5( IMX8QXP_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG + 0x4, IMX8QXP_AXI_CONN_CLK_ROOT ),
+};
 
-	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
-	if (ret) {
-		printf("%s err %d\n", __func__, ret);
-		return ret;
-	}
+struct imx8_mux_clks imx8qxp_mux_clks[] = {
+	CLK_MUX( IMX8QXP_SDHC0_SEL, "SDHC0_SEL", IMX8QXP_SDHC0_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
+		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY, IMX8QXP_CLK_DUMMY ),
+	CLK_MUX( IMX8QXP_SDHC1_SEL, "SDHC1_SEL", IMX8QXP_SDHC1_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
+		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY, IMX8QXP_CLK_DUMMY ),
+	CLK_MUX( IMX8QXP_SDHC2_SEL, "SDHC2_SEL", IMX8QXP_SDHC2_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
+		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY, IMX8QXP_CLK_DUMMY ),
+};
 
-	return 0;
-}
+struct imx8_clks_collect imx8qxp_clk_collect = {
+	{
+		{&imx8qxp_clks, ARRAY_SIZE(imx8qxp_clks)},
+		{&imx8qxp_fixed_clks, ARRAY_SIZE(imx8qxp_fixed_clks)},
+		{&imx8qxp_gpr_clks, ARRAY_SIZE(imx8qxp_gpr_clks)},
+		{&imx8qxp_lpcg_clks, ARRAY_SIZE(imx8qxp_lpcg_clks)},
+		{&imx8qxp_mux_clks, ARRAY_SIZE(imx8qxp_mux_clks)},
+	},
+	FLAG_CLK_IMX8_IMX8QXP,
+};
-- 
2.7.4

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

* [U-Boot] [PATCH 4/5] imx8qm_mek: increase the size of early malloc pool
  2019-07-03  5:40 [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP Ye Li
  2019-07-03  5:40 ` [U-Boot] [PATCH 2/5] misc: scu_api: Add new APIs for clk-imx8 driver Ye Li
  2019-07-03  5:40 ` [U-Boot] [PATCH 3/5] clk: imx8: Update imx8 clock driver Ye Li
@ 2019-07-03  5:40 ` Ye Li
  2019-07-03  5:40 ` [U-Boot] [PATCH 5/5] net: fec_mxc: Update driver to use full clks for iMX8 Ye Li
  2019-07-03  6:02 ` [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP Peng Fan
  4 siblings, 0 replies; 14+ messages in thread
From: Ye Li @ 2019-07-03  5:40 UTC (permalink / raw)
  To: u-boot

Encounter malloc failure in arch_cpu_init_dm when binding "fsl,imx8-mu" node
with imx8_scu driver. So increase the early malloc pool to fix the issue.

Signed-off-by: Ye Li <ye.li@nxp.com>
---
 configs/imx8qm_mek_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configs/imx8qm_mek_defconfig b/configs/imx8qm_mek_defconfig
index 1c67b98..a4d2619 100644
--- a/configs/imx8qm_mek_defconfig
+++ b/configs/imx8qm_mek_defconfig
@@ -6,7 +6,7 @@ CONFIG_SYS_TEXT_BASE=0x80020000
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
 CONFIG_TARGET_IMX8QM_MEK=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
-- 
2.7.4

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

* [U-Boot] [PATCH 5/5] net: fec_mxc: Update driver to use full clks for iMX8
  2019-07-03  5:40 [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP Ye Li
                   ` (2 preceding siblings ...)
  2019-07-03  5:40 ` [U-Boot] [PATCH 4/5] imx8qm_mek: increase the size of early malloc pool Ye Li
@ 2019-07-03  5:40 ` Ye Li
  2019-07-06 23:09   ` Lukasz Majewski
  2019-07-03  6:02 ` [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP Peng Fan
  4 siblings, 1 reply; 14+ messages in thread
From: Ye Li @ 2019-07-03  5:40 UTC (permalink / raw)
  To: u-boot

Add support for more clocks used by iMX8 from DTB:
ref_clock, tx_2x_clock, ahb_clock
And update get clock rate interface to support multiple fec ports.

Signed-off-by: Ye Li <ye.li@nxp.com>
---
 drivers/net/fec_mxc.c | 47 ++++++++++++++++++++++++++++++++++++++---------
 drivers/net/fec_mxc.h |  1 +
 2 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index d7c0809..6d485f1 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -6,7 +6,6 @@
  * (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
  * (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de>
  */
-
 #include <common.h>
 #include <dm.h>
 #include <environment.h>
@@ -132,9 +131,9 @@ static int fec_get_clk_rate(void *udev, int idx)
 
 	dev = udev;
 	if (!dev) {
-		ret = uclass_get_device(UCLASS_ETH, idx, &dev);
+		ret = uclass_get_device_by_seq(UCLASS_ETH, idx, &dev);
 		if (ret < 0) {
-			debug("Can't get FEC udev: %d\n", ret);
+			debug("Can't get FEC udev%d: %d\n", idx, ret);
 			return ret;
 		}
 	}
@@ -149,7 +148,7 @@ static int fec_get_clk_rate(void *udev, int idx)
 #endif
 }
 
-static void fec_mii_setspeed(struct ethernet_regs *eth)
+static void fec_mii_setspeed(struct ethernet_regs *eth, int idx)
 {
 	/*
 	 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
@@ -171,7 +170,7 @@ static void fec_mii_setspeed(struct ethernet_regs *eth)
 	u32 hold;
 	int ret;
 
-	ret = fec_get_clk_rate(NULL, 0);
+	ret = fec_get_clk_rate(NULL, idx);
 	if (ret < 0) {
 		printf("Can't find FEC0 clk rate: %d\n", ret);
 		return;
@@ -593,7 +592,7 @@ static int fec_init(struct eth_device *dev, bd_t *bd)
 	fec_reg_setup(fec);
 
 	if (fec->xcv_type != SEVENWIRE)
-		fec_mii_setspeed(fec->bus->priv);
+		fec_mii_setspeed(fec->bus->priv, fec->dev_id);
 
 	/* Set Opcode/Pause Duration Register */
 	writel(0x00010020, &fec->eth->op_pause);	/* FIXME 0xffff0020; */
@@ -1073,7 +1072,7 @@ struct mii_dev *fec_get_miibus(ulong base_addr, int dev_id)
 		free(bus);
 		return NULL;
 	}
-	fec_mii_setspeed(eth);
+	fec_mii_setspeed(eth, dev_id);
 	return bus;
 }
 
@@ -1142,7 +1141,7 @@ static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
 	fec_set_dev_name(edev->name, dev_id);
 	fec->dev_id = (dev_id == -1) ? 0 : dev_id;
 	fec->bus = bus;
-	fec_mii_setspeed(bus->priv);
+	fec_mii_setspeed(bus->priv, fec->dev_id);
 #ifdef CONFIG_PHYLIB
 	fec->phydev = phydev;
 	phy_connect_dev(phydev, edev);
@@ -1324,6 +1323,7 @@ static int fecmxc_probe(struct udevice *dev)
 	int ret;
 
 	if (IS_ENABLED(CONFIG_IMX8)) {
+		struct clk ref_clk, clk_2x_txclk;
 		ret = clk_get_by_name(dev, "ipg", &priv->ipg_clk);
 		if (ret < 0) {
 			debug("Can't get FEC ipg clk: %d\n", ret);
@@ -1335,6 +1335,35 @@ static int fecmxc_probe(struct udevice *dev)
 			return ret;
 		}
 
+		ret = clk_get_by_name(dev, "ahb", &priv->ahb_clk);
+		if (ret < 0) {
+			debug("Can't get FEC ahb clk: %d\n", ret);
+			return ret;
+		}
+		ret = clk_enable(&priv->ahb_clk);
+		if (ret < 0) {
+			debug("Can't enable FEC ahb clk: %d\n", ret);
+			return ret;
+		}
+
+		ret = clk_get_by_name(dev, "enet_clk_ref", &ref_clk);
+		if (ret >= 0) {
+			ret = clk_enable(&ref_clk);
+			if (ret < 0) {
+				debug("Can't enable FEC ref clk: %d\n", ret);
+				return ret;
+			}
+		}
+
+		ret = clk_get_by_name(dev, "enet_2x_txclk", &clk_2x_txclk);
+		if (ret >= 0) {
+			ret = clk_enable(&clk_2x_txclk);
+			if (ret < 0) {
+				debug("Can't enable FEC 2x_tx clk: %d\n", ret);
+				return ret;
+			}
+		}
+
 		priv->clk_rate = clk_get_rate(&priv->ipg_clk);
 	}
 
@@ -1368,7 +1397,6 @@ static int fecmxc_probe(struct udevice *dev)
 	}
 
 	fec_reg_setup(priv);
-
 	priv->dev_id = dev->seq;
 #ifdef CONFIG_FEC_MXC_MDIO_BASE
 	bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE, dev->seq);
@@ -1492,6 +1520,7 @@ static const struct udevice_id fecmxc_ids[] = {
 	{ .compatible = "fsl,imx53-fec" },
 	{ .compatible = "fsl,imx7d-fec" },
 	{ .compatible = "fsl,mvf600-fec" },
+	{ .compatible = "fsl,imx8qm-fec" },
 	{ }
 };
 
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h
index e5f2dd7..23180a6 100644
--- a/drivers/net/fec_mxc.h
+++ b/drivers/net/fec_mxc.h
@@ -264,6 +264,7 @@ struct fec_priv {
 	u32 interface;
 #endif
 	struct clk ipg_clk;
+	struct clk ahb_clk;
 	u32 clk_rate;
 };
 
-- 
2.7.4

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

* [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP
  2019-07-03  5:40 [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP Ye Li
                   ` (3 preceding siblings ...)
  2019-07-03  5:40 ` [U-Boot] [PATCH 5/5] net: fec_mxc: Update driver to use full clks for iMX8 Ye Li
@ 2019-07-03  6:02 ` Peng Fan
  4 siblings, 0 replies; 14+ messages in thread
From: Peng Fan @ 2019-07-03  6:02 UTC (permalink / raw)
  To: u-boot


> Subject: [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP
> 
[...]
> 
> diff --git a/arch/arm/include/asm/arch-imx8/imx8qm_lpcg.h
> b/arch/arm/include/asm/arch-imx8/imx8qm_lpcg.h
> new file mode 100644
> index 0000000..692c27f
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-imx8/imx8qm_lpcg.h
> @@ -0,0 +1,200 @@
> +/*
> + * Copyright 2018 NXP
> + *
> + * SPDX-License-Identifier:     GPL-2.0+

Please fix license and time.

> + */
> +
> +#ifndef _SC_LPCG_H
> +#define _SC_LPCG_H
> +
[...]

> +#endif
> diff --git a/arch/arm/include/asm/arch-imx8/imx8qxp_lpcg.h
> b/arch/arm/include/asm/arch-imx8/imx8qxp_lpcg.h
> new file mode 100644
> index 0000000..5fed514
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-imx8/imx8qxp_lpcg.h
> @@ -0,0 +1,195 @@
> +/*
> + * Copyright 2018 NXP
> + *
> + * SPDX-License-Identifier:     GPL-2.0+

Ditto

> + */
> +
> +#ifndef _SC_LPCG_H
> +#define _SC_LPCG_H
> +
[...]
> +#define     AUD_EDMA_1_LPCG         0x59df0000
> +

Blank line.

> +
> +/* 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
> +
> +

Ditto

> +#endif
> diff --git a/arch/arm/include/asm/arch-imx8/lpcg.h
> b/arch/arm/include/asm/arch-imx8/lpcg.h
> new file mode 100644
> index 0000000..b3a4545
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-imx8/lpcg.h
> @@ -0,0 +1,26 @@
> +/*
> + * Copyright 2018 NXP
> + *
> + * SPDX-License-Identifier:	GPL-2.0+

Please fix copyright and license.

> + */
> +
> +#ifndef __ASM_ARCH_IMX8_LPCG_H__
> +#define __ASM_ARCH_IMX8_LPCG_H__
> +
> +#if defined(CONFIG_IMX8QM)
> +#include "imx8qm_lpcg.h"
> +#elif defined(CONFIG_IMX8QXP)
> +#include "imx8qxp_lpcg.h"
> +#else
> +#error "No lpcg header"
> +#endif
> +
> +void lpcg_clock_off(u32 lpcg_addr, u8 clk); void lpcg_clock_on(u32
> +lpcg_addr, u8 clk); void lpcg_clock_autogate(u32 lpcg_addr, u8 clk);
> +bool lpcg_is_clock_on(u32 lpcg_addr, u8 clk); void
> +lpcg_all_clock_off(u32 lpcg_addr); void lpcg_all_clock_on(u32
> +lpcg_addr); void lpcg_all_clock_autogate(u32 lpcg_addr);
> +
> +#endif	/* __ASM_ARCH_IMX8_LPCG_H__ */
> diff --git a/arch/arm/mach-imx/imx8/Makefile
> b/arch/arm/mach-imx/imx8/Makefile index 31ad169..e23f84f 100644
> --- a/arch/arm/mach-imx/imx8/Makefile
> +++ b/arch/arm/mach-imx/imx8/Makefile
> @@ -4,4 +4,4 @@
>  # SPDX-License-Identifier:	GPL-2.0+
>  #
> 
> -obj-y += cpu.o iomux.o
> +obj-y += cpu.o iomux.o lpcg.o
> diff --git a/arch/arm/mach-imx/imx8/lpcg.c
> b/arch/arm/mach-imx/imx8/lpcg.c new file mode 100644 index
> 0000000..5f5d770
> --- /dev/null
> +++ b/arch/arm/mach-imx/imx8/lpcg.c
> @@ -0,0 +1,115 @@
> +/*
> + * Copyright 2017-2019 NXP
> + *
> + * SPDX-License-Identifier:	GPL-2.0+

Ditto.

Regards,
Peng.

> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <linux/errno.h>
> +#include <asm/arch/lpcg.h>
> +
> +#define LPCG_CLOCK_MASK         0x3U
> +#define LPCG_CLOCK_OFF          0x0U
> +#define LPCG_CLOCK_ON           0x2U
> +#define LPCG_CLOCK_AUTO         0x3U
> +#define LPCG_CLOCK_STOP         0x8U
> +
> +#define LPCG_ALL_CLOCK_OFF      0x00000000U
> +#define LPCG_ALL_CLOCK_ON       0x22222222U
> +#define LPCG_ALL_CLOCK_AUTO     0x33333333U
> +#define LPCG_ALL_CLOCK_STOP     0x88888888U
> +
> +static inline void lpcg_write(u32 lpcgVal, ulong lpcg_addr) {
> +	/*
> +	* Write twice with 4x DSC clock cycles (40x IPS clock cycles) interval
> +	* to work around LPCG issue
> +	*/
> +	writel(lpcgVal, lpcg_addr);
> +	udelay(10); /* 10us is enough. Worst case is 40x IPS cycle (200Mhz) */
> +	writel(lpcgVal, lpcg_addr);
> +	udelay(10);
> +}
> +
> +void lpcg_clock_off(u32 lpcg_addr, u8 clk) {
> +	u32 lpcgVal;
> +
> +	/* Read from LPCG */
> +	lpcgVal = readl((ulong)lpcg_addr);
> +
> +	/* Modify */
> +	lpcgVal &= ~((u32)(LPCG_CLOCK_MASK) << (clk * 4U));
> +	lpcgVal |= ((u32)(LPCG_CLOCK_OFF) << (clk * 4U));
> +
> +	/* Write to LPCG */
> +	lpcg_write(lpcgVal, (ulong)lpcg_addr); }
> +
> +void lpcg_clock_on(u32 lpcg_addr, u8 clk) {
> +	u32 lpcgVal;
> +
> +	/* Read from LPCG */
> +	lpcgVal = readl((ulong)lpcg_addr);
> +
> +	/* Modify */
> +	lpcgVal &= ~((u32)(LPCG_CLOCK_MASK) << (clk * 4U));
> +	lpcgVal |= ((u32)(LPCG_CLOCK_ON) << (clk * 4U));
> +
> +	/* Write to LPCG */
> +	lpcg_write(lpcgVal, (ulong)lpcg_addr); }
> +
> +bool lpcg_is_clock_on(u32 lpcg_addr, u8 clk) {
> +	u32 lpcgVal;
> +
> +	/* Read from LPCG */
> +	lpcgVal = readl((ulong)lpcg_addr);
> +	lpcgVal = (lpcgVal >> (clk * 4U)) & (u32)(LPCG_CLOCK_MASK);
> +
> +	if (lpcgVal == LPCG_CLOCK_ON)
> +		return true;
> +
> +	return false;
> +}
> +
> +void lpcg_clock_autogate(u32 lpcg_addr, u8 clk) {
> +	u32 lpcgVal;
> +
> +	/* Read from LPCG */
> +	lpcgVal = readl((ulong)lpcg_addr);
> +
> +	/* Modify */
> +	lpcgVal &= ~((u32)(LPCG_CLOCK_MASK) << (clk * 4U));
> +	lpcgVal |= ((u32)(LPCG_CLOCK_AUTO) << (clk * 4U));
> +
> +	/* Write to LPCG */
> +	lpcg_write(lpcgVal, (ulong)lpcg_addr); }
> +
> +void lpcg_all_clock_off(u32 lpcg_addr)
> +{
> +	/* Write to LPCG */
> +	lpcg_write(LPCG_ALL_CLOCK_OFF, (ulong)lpcg_addr); }
> +
> +void lpcg_all_clock_on(u32 lpcg_addr)
> +{
> +	/* Write to LPCG */
> +	lpcg_write(LPCG_ALL_CLOCK_ON, (ulong)lpcg_addr);
> +
> +	/* Wait for clocks to start */
> +	while ((readl((ulong)lpcg_addr) & LPCG_ALL_CLOCK_STOP) != 0U)
> +	{
> +	}
> +}
> +
> +void lpcg_all_clock_autogate(u32 lpcg_addr) {
> +	/* Write to LPCG */
> +	lpcg_write(LPCG_ALL_CLOCK_AUTO, (ulong)lpcg_addr); }
> --
> 2.7.4

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

* [U-Boot] [PATCH 2/5] misc: scu_api: Add new APIs for clk-imx8 driver
  2019-07-03  5:40 ` [U-Boot] [PATCH 2/5] misc: scu_api: Add new APIs for clk-imx8 driver Ye Li
@ 2019-07-03  6:04   ` Peng Fan
  0 siblings, 0 replies; 14+ messages in thread
From: Peng Fan @ 2019-07-03  6:04 UTC (permalink / raw)
  To: u-boot

> Subject: [PATCH 2/5] misc: scu_api: Add new APIs for clk-imx8 driver
> 
> Add sc_misc_set_control to write the subsystem's DSC GPR registers, and
> sc_pm_set_clock_parent to select parent clock source.
> 
> Signed-off-by: Ye Li <ye.li@nxp.com>
> ---
>  arch/arm/include/asm/arch-imx8/sci/sci.h        |  4 ++
>  arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h |  7 ++++
>  arch/arm/include/asm/arch-imx8/sci/types.h      | 13 ++++++-
>  drivers/misc/imx8/scu_api.c                     | 52
> +++++++++++++++++++++++++
>  include/dt-bindings/soc/imx_rsrc.h              |  2 +
>  5 files changed, 77 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/asm/arch-imx8/sci/sci.h
> b/arch/arm/include/asm/arch-imx8/sci/sci.h
> index 9737769..52a3ac8 100644
> --- a/arch/arm/include/asm/arch-imx8/sci/sci.h
> +++ b/arch/arm/include/asm/arch-imx8/sci/sci.h
> @@ -64,8 +64,12 @@ int sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t
> resource, sc_pm_clk_t clk,
>  			 sc_pm_clock_rate_t *rate);
>  int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
>  		       sc_bool_t enable, sc_bool_t autog);
> +int sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t
> clk,
> +			sc_pm_clk_parent_t parent);
> 
>  /* MISC API */
> +int sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
> +			sc_ctrl_t ctrl, u32 val);
>  int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
>  			u32 *val);
>  void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev); diff --git
> a/arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h
> b/arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h
> index 9008b85..109ec27 100644
> --- a/arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h
> +++ b/arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h
> @@ -35,6 +35,13 @@
>  #define SC_PM_CLK_MODE_AUTOGATE_HW	4U /* Clock is in HW
> autogate mode */
>  #define SC_PM_CLK_MODE_AUTOGATE_SW_HW	5U /* Clock is in
> SW-HW autogate mode */
> 
> +/* Defines for sc_pm_clk_parent_t */
> +#define SC_PM_PARENT_XTAL              0U    /*!< Parent is XTAL.
> */
> +#define SC_PM_PARENT_PLL0              1U    /*!< Parent is PLL0
> */
> +#define SC_PM_PARENT_PLL1              2U    /*!< Parent is PLL1
> or PLL0/2 */
> +#define SC_PM_PARENT_PLL2              3U    /*!< Parent in PLL2
> or PLL0/4 */
> +#define SC_PM_PARENT_BYPS              4U    /*!< Parent is a
> bypass clock. */
> +
>  typedef u8 sc_pm_power_mode_t;
>  typedef u8 sc_pm_clk_t;
>  typedef u8 sc_pm_clk_mode_t;
> diff --git a/arch/arm/include/asm/arch-imx8/sci/types.h
> b/arch/arm/include/asm/arch-imx8/sci/types.h
> index 9eadc88..2d5912e 100644
> --- a/arch/arm/include/asm/arch-imx8/sci/types.h
> +++ b/arch/arm/include/asm/arch-imx8/sci/types.h
> @@ -185,7 +185,18 @@ typedef u64 sc_ipc_t;
>  #define SC_C_RST0                       43U
>  #define SC_C_RST1                       44U
>  #define SC_C_SEL0                       45U
> -#define SC_C_LAST                       46U
> +#define SC_C_CALIB0                     46U
> +#define SC_C_CALIB1                     47U
> +#define SC_C_CALIB2                     48U
> +#define SC_C_IPG_DEBUG                  49U
> +#define SC_C_IPG_DOZE                   50U
> +#define SC_C_IPG_WAIT                   51U
> +#define SC_C_IPG_STOP                   52U
> +#define SC_C_IPG_STOP_MODE              53U
> +#define SC_C_IPG_STOP_ACK               54U
> +#define SC_C_SYNC_CTRL                  55U
> +#define SC_C_LAST                       56U
> +
> 
>  #define SC_P_ALL        ((sc_pad_t)UINT16_MAX)   /* All pads */
> 
> diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c index
> d9c4d5d..cab8995 100644
> --- a/drivers/misc/imx8/scu_api.c
> +++ b/drivers/misc/imx8/scu_api.c
> @@ -93,6 +93,31 @@ int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t
> resource, sc_pm_clk_t clk,
>  	return ret;
>  }
> 
> +int sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
> +    sc_pm_clk_t clk, sc_pm_clk_parent_t parent) {
> +	struct udevice *dev = gd->arch.scu_dev;
> +	int size = sizeof(struct sc_rpc_msg_s);
> +	struct sc_rpc_msg_s msg;
> +	int ret;
> +
> +	RPC_VER(&msg) = SC_RPC_VERSION;
> +	RPC_SVC(&msg) = (u8)(SC_RPC_SVC_PM);
> +	RPC_FUNC(&msg) = (u8)(PM_FUNC_SET_CLOCK_PARENT);
> +	RPC_U16(&msg, 0U) = (u16)(resource);
> +	RPC_U8(&msg, 2U) = (u8)(clk);
> +	RPC_U8(&msg, 3U) = (u8)(parent);
> +	RPC_SIZE(&msg) = 2U;
> +
> +	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
> +	if (ret)
> +		printf("%s: resource:%d clk:%d: parent clk: %d, res:%d\n",
> +		       __func__, resource, clk, parent, RPC_R8(&msg));
> +
> +	return ret;
> +}
> +
> +
>  int sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
>  				  sc_pm_power_mode_t mode)
>  {
> @@ -146,6 +171,33 @@ int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32
> val)  }
> 
>  /* MISC */
> +int sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
> +			sc_ctrl_t ctrl, u32 val)
> +{
> +	struct udevice *dev = gd->arch.scu_dev;
> +	int size = sizeof(struct sc_rpc_msg_s);
> +	struct sc_rpc_msg_s msg;
> +	int ret;
> +
> +	if (!dev)
> +		hang();
> +
> +	RPC_VER(&msg) = SC_RPC_VERSION;
> +	RPC_SVC(&msg) = (u8)(SC_RPC_SVC_MISC);
> +	RPC_FUNC(&msg) = (u8)(MISC_FUNC_SET_CONTROL);
> +	RPC_U32(&msg, 0U) = (u32)(ctrl);
> +	RPC_U32(&msg, 4U) = (u32)(val);
> +	RPC_U16(&msg, 8U) = (u16)(resource);
> +	RPC_SIZE(&msg) = 4U;
> +
> +	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
> +	if (ret)
> +		printf("%s: ctrl:%d resource:%d: res:%d\n",
> +		       __func__, ctrl, resource, RPC_R8(&msg));
> +
> +	return ret;
> +}
> +
>  int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
>  			u32 *val)
>  {
> diff --git a/include/dt-bindings/soc/imx_rsrc.h
> b/include/dt-bindings/soc/imx_rsrc.h
> index 4870eb9..a1c3b1f 100644
> --- a/include/dt-bindings/soc/imx_rsrc.h
> +++ b/include/dt-bindings/soc/imx_rsrc.h
> @@ -554,4 +554,6 @@
>  #define SC_R_VPU                        540
>  #define SC_R_LAST                       541
> 
> +#define SC_R_NONE                       0xFFF0
> +

Reviewed-by: Peng Fan <peng.fan@nxp.com>

>  #endif /* DT_BINDINGS_RSCRC_IMX_H */
> --
> 2.7.4

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

* [U-Boot] [PATCH 3/5] clk: imx8: Update imx8 clock driver
  2019-07-03  5:40 ` [U-Boot] [PATCH 3/5] clk: imx8: Update imx8 clock driver Ye Li
@ 2019-07-06 23:07   ` Lukasz Majewski
  2019-07-10  7:14     ` [U-Boot] [EXT] " Ye Li
  0 siblings, 1 reply; 14+ messages in thread
From: Lukasz Majewski @ 2019-07-06 23:07 UTC (permalink / raw)
  To: u-boot

Hi Ye,

> Update imx8 clock driver to support LPCG and full clocks tree for some
> modules aligned with kernel.
> 
> We classify the clock into serveral types: slice, fixed, lpcg, gpr
> and mux.

Is this code in sync with Linux kernel? Does the imx8 (in Linux kernel)
use the Common Clock Framework?

> Generally slice and fixed clocks are the sources. lpcg, gpr
> and mux are the downstream of those sources and are used for gating,
> muxing or dividing functions.
> 
> This patch replaces the functions defined in imx8qm and imx8qxp with
> the clock tables of different clock types. clk-imx8 use unified
> functions to process these clock tables.


I've posted the Common Clock Framework v5 to the mailing list recently:
https://patchwork.ozlabs.org/cover/1121348/


So maybe this code could benefit from those patches and use this
infrastructure ?

> 
> Note: since the clock depends on the power domain of its resource,
> must power on the resource firstly, then we can get the clock.
> Otherwise, we can't access lpcg. Thus, the clock dump only works for
> the slice clock.
> 
> Signed-off-by: Ye Li <ye.li@nxp.com>
> ---
>  drivers/clk/imx/clk-imx8.c    | 304 +++++++++++++++++++++++++--
>  drivers/clk/imx/clk-imx8.h    |  83 +++++++-
>  drivers/clk/imx/clk-imx8qm.c  | 479
> ++++++++++++++++--------------------------
> drivers/clk/imx/clk-imx8qxp.c | 432
> +++++++++++++------------------------ 4 files changed, 689
> insertions(+), 609 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c
> index a755e26..afdb6ea 100644
> --- a/drivers/clk/imx/clk-imx8.c
> +++ b/drivers/clk/imx/clk-imx8.c
> @@ -12,32 +12,294 @@
>  #include <dt-bindings/clock/imx8qxp-clock.h>
>  #include <dt-bindings/soc/imx_rsrc.h>
>  #include <misc.h>
> +#include <asm/arch/lpcg.h>
>  
>  #include "clk-imx8.h"
>  
> -__weak ulong imx8_clk_get_rate(struct clk *clk)
> +struct imx8_clks_collect *soc_data[] = {
> +#ifdef CONFIG_IMX8QXP
> +	&imx8qxp_clk_collect,
> +#endif
> +#ifdef CONFIG_IMX8QM
> +	&imx8qm_clk_collect,
> +#endif
> +};
> +
> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id);
> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
> enable); +static ulong __imx8_clk_set_rate(struct udevice *dev, ulong
> id, unsigned long rate); +
> +static struct imx8_clks_collect * find_clks_collect(struct udevice
> *dev) +{
> +	ulong data = (ulong)dev_get_driver_data(dev);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(soc_data); i++) {
> +		if (soc_data[i]->match_flag == data)
> +			return soc_data[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +static void * check_imx8_clk(struct udevice *dev, enum imx8_clk_type
> type, ulong id, u32 size_of_clk) +{
> +	u32 i, size;
> +	struct imx8_clks_collect *clks_col = find_clks_collect(dev);
> +	struct imx8_clk_header *hdr;
> +	ulong clks;
> +
> +	if (!clks_col || !(clks_col->clks[type].type_clks)) {
> +		printf("%s fails to get clks for type %d\n",
> +		       __func__, type);
> +		return NULL;
> +	}
> +
> +	clks = (ulong)(clks_col->clks[type].type_clks);
> +	size = clks_col->clks[type].num;
> +
> +	for (i = 0; i < size; i++) {
> +		hdr = (struct imx8_clk_header *)clks;
> +		if (id == hdr->id)
> +			return (void *)hdr;
> +
> +		clks += size_of_clk;
> +	}
> +
> +	return NULL;
> +}
> +
> +static ulong imx8_get_rate_lpcg(struct udevice *dev, struct
> imx8_lpcg_clks *lpcg_clk) +{
> +	if (lpcg_clk->parent_id != 0) {
> +		if (lpcg_is_clock_on(lpcg_clk->lpcg,
> lpcg_clk->bit_idx >> 2)) {
> +			return __imx8_clk_get_rate(dev,
> lpcg_clk->parent_id);
> +		} else {
> +			return 0;
> +		}
> +	} else {
> +		return -ENOSYS;
> +	}
> +}
> +
> +static ulong imx8_get_rate_slice(struct udevice *dev, struct
> imx8_clks *slice_clk) +{
> +	int ret;
> +	u32 rate;
> +
> +	ret = sc_pm_get_clock_rate(-1, slice_clk->rsrc,
> slice_clk->pm_clk,
> +				   (sc_pm_clock_rate_t *)&rate);
> +	if (ret) {
> +		printf("%s err %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	return rate;
> +}
> +
> +static ulong imx8_get_rate_fixed(struct udevice *dev, struct
> imx8_fixed_clks *fixed_clk) +{
> +	return fixed_clk->rate;
> +}
> +
> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id)
> +{
> +	void* clkdata;
> +
> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
> sizeof(struct imx8_lpcg_clks));
> +	if (clkdata) {
> +		return imx8_get_rate_lpcg(dev, (struct
> imx8_lpcg_clks *)clkdata);
> +	}
> +
> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
> sizeof(struct imx8_clks));
> +	if (clkdata) {
> +		return imx8_get_rate_slice(dev, (struct imx8_clks
> *)clkdata);
> +	}
> +
> +	clkdata = check_imx8_clk(dev, IMX8_CLK_FIXED, id,
> sizeof(struct imx8_fixed_clks));
> +	if (clkdata) {
> +		return imx8_get_rate_fixed(dev, (struct
> imx8_fixed_clks *)clkdata);
> +	}
> +
> +	return -ENOSYS;
> +}
> +
> +static ulong imx8_clk_get_rate(struct clk *clk)
> +{
> +	return __imx8_clk_get_rate(clk->dev, clk->id);
> +}
> +
> +static ulong imx8_set_rate_lpcg(struct udevice *dev, struct
> imx8_lpcg_clks *lpcg_clk, unsigned long rate) +{
> +	if (lpcg_clk->parent_id != 0) {
> +		return __imx8_clk_set_rate(dev, lpcg_clk->parent_id,
> rate);
> +	} else {
> +		return -ENOSYS;
> +	}
> +}
> +
> +static ulong imx8_set_rate_slice(struct udevice *dev, struct
> imx8_clks *slice_clk, unsigned long rate) +{
> +	int ret;
> +	u32 new_rate = rate;
> +
> +	ret = sc_pm_set_clock_rate(-1, slice_clk->rsrc,
> slice_clk->pm_clk, &new_rate);
> +	if (ret) {
> +		printf("%s err %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	return new_rate;
> +}
> +
> +static ulong imx8_set_rate_gpr(struct udevice *dev, struct
> imx8_gpr_clks *gpr_clk, unsigned long rate) {
> +	ulong parent_rate;
> +	u32 val;
> +	int ret;
> +
> +	if (gpr_clk->parent_id == 0)
> +		return -ENOSYS;
> +
> +	parent_rate = __imx8_clk_get_rate(dev, gpr_clk->parent_id);
> +	if (parent_rate > 0) {
> +		val = (rate < parent_rate) ? 1 : 0;
> +
> +		ret = sc_misc_set_control(-1, gpr_clk->rsrc,
> +			gpr_clk->gpr_id, val);
> +		if (ret) {
> +			printf("%s err %d\n", __func__, ret);
> +			return ret;
> +		}
> +
> +		return rate;
> +	}
> +
> +	return -ENOSYS;
> +}
> +
> +static ulong __imx8_clk_set_rate(struct udevice *dev, ulong id,
> unsigned long rate) +{
> +	void* clkdata;
> +
> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
> sizeof(struct imx8_clks));
> +	if (clkdata) {
> +		return imx8_set_rate_slice(dev, (struct imx8_clks
> *)clkdata, rate);
> +	}
> +
> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
> sizeof(struct imx8_lpcg_clks));
> +	if (clkdata) {
> +		return imx8_set_rate_lpcg(dev, (struct
> imx8_lpcg_clks *)clkdata, rate);
> +	}
> +
> +	clkdata = check_imx8_clk(dev, IMX8_CLK_GPR, id,
> sizeof(struct imx8_gpr_clks));
> +	if (clkdata) {
> +		return imx8_set_rate_gpr(dev, (struct imx8_gpr_clks
> *)clkdata, rate);
> +	}
> +
> +	return -ENOSYS;
> +}
> +
> +static ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
> +{
> +	return __imx8_clk_set_rate(clk->dev, clk->id, rate);
> +
> +}
> +
> +static int imx8_enable_slice(struct udevice *dev, struct imx8_clks
> *slice_clk, bool enable) +{
> +	int ret;
> +
> +	ret = sc_pm_clock_enable(-1, slice_clk->rsrc,
> slice_clk->pm_clk, enable, 0);
> +	if (ret) {
> +		printf("%s err %d\n", __func__, ret);
> +		return ret;
> +	}
> +
>  	return 0;
>  }
>  
> -__weak ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
> +static int imx8_enable_lpcg(struct udevice *dev, struct
> imx8_lpcg_clks *lpcg_clk, bool enable) {
> +	if (enable) {
> +		if (lpcg_clk->parent_id != 0) {
> +			__imx8_clk_enable(dev, lpcg_clk->parent_id,
> enable);
> +		}
> +
> +		lpcg_clock_on(lpcg_clk->lpcg, lpcg_clk->bit_idx >>
> 2);
> +	} else {
> +		lpcg_clock_off(lpcg_clk->lpcg, lpcg_clk->bit_idx >>
> 2); +
> +		if (lpcg_clk->parent_id != 0) {
> +			__imx8_clk_enable(dev, lpcg_clk->parent_id,
> enable);
> +		}
> +	}
> +
>  	return 0;
>  }
>  
> -__weak int __imx8_clk_enable(struct clk *clk, bool enable)
> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
> enable) {
> -	return -ENOTSUPP;
> +	void* clkdata;
> +
> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
> sizeof(struct imx8_lpcg_clks));
> +	if (clkdata) {
> +		return imx8_enable_lpcg(dev, (struct imx8_lpcg_clks
> *)clkdata, enable);
> +	}
> +
> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
> sizeof(struct imx8_clks));
> +	if (clkdata) {
> +		return imx8_enable_slice(dev, (struct imx8_clks
> *)clkdata, enable);
> +	}
> +
> +	return -ENOSYS;
>  }
>  
>  static int imx8_clk_disable(struct clk *clk)
>  {
> -	return __imx8_clk_enable(clk, 0);
> +	return __imx8_clk_enable(clk->dev, clk->id, 0);
>  }
>  
>  static int imx8_clk_enable(struct clk *clk)
>  {
> -	return __imx8_clk_enable(clk, 1);
> +	return __imx8_clk_enable(clk->dev, clk->id, 1);
> +}
> +
> +static int imx8_set_parent_mux(struct udevice *dev, struct
> imx8_mux_clks *mux_clk, ulong pid) +{
> +	u32 i;
> +	int ret;
> +	struct imx8_clks *slice_clkdata;
> +
> +	slice_clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE,
> mux_clk->slice_clk_id, sizeof(struct imx8_clks));
> +	if (!slice_clkdata) {
> +		printf("Error: fail to find slice clk %lu for this
> mux %lu\n", mux_clk->slice_clk_id, mux_clk->hdr.id);
> +		return -EINVAL;
> +	}
> +
> +	for (i = 0; i< CLK_IMX8_MAX_MUX_SEL; i++) {
> +		if (pid == mux_clk->parent_clks[i]) {
> +			ret = sc_pm_set_clock_parent(-1,
> slice_clkdata->rsrc,  slice_clkdata->pm_clk, i);
> +			if (ret)
> +				printf("Error: fail to set clock
> parent rsrc %d, pm_clk %d, parent clk %d\n",
> +					slice_clkdata->rsrc,
> slice_clkdata->pm_clk, i);
> +			return ret;
> +		}
> +	}
> +
> +	return -ENOSYS;
> +}
> +
> +static int imx8_clk_set_parent(struct clk *clk, struct clk *parent)
> +{
> +	void* clkdata;
> +
> +	clkdata = check_imx8_clk(clk->dev, IMX8_CLK_MUX, clk->id,
> sizeof(struct imx8_mux_clks));
> +	if (clkdata) {
> +		return imx8_set_parent_mux(clk->dev, (struct
> imx8_mux_clks *)clkdata, parent->id);
> +	}
> +
> +	return -ENOSYS;
>  }
>  
>  #if CONFIG_IS_ENABLED(CMD_CLK)
> @@ -47,6 +309,9 @@ int soc_clk_dump(void)
>  	struct clk clk;
>  	unsigned long rate;
>  	int i, ret;
> +	u32 size;
> +	struct imx8_clks *clks;
> +	struct imx8_clks_collect *clks_col;
>  
>  	ret = uclass_get_device_by_driver(UCLASS_CLK,
>  					  DM_GET_DRIVER(imx8_clk),
> &dev); @@ -55,8 +320,19 @@ int soc_clk_dump(void)
>  
>  	printf("Clk\t\tHz\n");
>  
> -	for (i = 0; i < num_clks; i++) {
> -		clk.id = imx8_clk_names[i].id;
> +	clks_col = find_clks_collect(dev);
> +
> +	if (!clks_col
> || !(clks_col->clks[IMX8_CLK_SLICE].type_clks)) {
> +		printf("%s fails to get clks for type %d\n",
> +		       __func__, IMX8_CLK_SLICE);
> +		return -ENODEV;
> +	}
> +
> +	clks = (struct imx8_clks
> *)(clks_col->clks[IMX8_CLK_SLICE].type_clks);
> +	size = clks_col->clks[IMX8_CLK_SLICE].num;
> +
> +	for (i = 0; i < size; i++) {
> +		clk.id = clks[i].hdr.id;
>  		ret = clk_request(dev, &clk);
>  		if (ret < 0) {
>  			debug("%s clk_request() failed: %d\n",
> __func__, ret); @@ -70,21 +346,22 @@ int soc_clk_dump(void)
>  
>  		if (ret == -ENOTSUPP) {
>  			printf("clk ID %lu not supported yet\n",
> -			       imx8_clk_names[i].id);
> +			       clks[i].hdr.id);
>  			continue;
>  		}
>  		if (ret < 0) {
>  			printf("%s %lu: get_rate err: %d\n",
> -			       __func__, imx8_clk_names[i].id, ret);
> +			       __func__, clks[i].hdr.id, ret);
>  			continue;
>  		}
>  
>  		printf("%s(%3lu):\t%lu\n",
> -		       imx8_clk_names[i].name, imx8_clk_names[i].id,
> rate);
> +		       clks[i].hdr.name, clks[i].hdr.id, rate);
>  	}
>  
>  	return 0;
>  }
> +
>  #endif
>  
>  static struct clk_ops imx8_clk_ops = {
> @@ -92,6 +369,7 @@ static struct clk_ops imx8_clk_ops = {
>  	.get_rate = imx8_clk_get_rate,
>  	.enable = imx8_clk_enable,
>  	.disable = imx8_clk_disable,
> +	.set_parent = imx8_clk_set_parent,
>  };
>  
>  static int imx8_clk_probe(struct udevice *dev)
> @@ -100,8 +378,8 @@ static int imx8_clk_probe(struct udevice *dev)
>  }
>  
>  static const struct udevice_id imx8_clk_ids[] = {
> -	{ .compatible = "fsl,imx8qxp-clk" },
> -	{ .compatible = "fsl,imx8qm-clk" },
> +	{ .compatible = "fsl,imx8qxp-clk", .data =
> FLAG_CLK_IMX8_IMX8QXP, },
> +	{ .compatible = "fsl,imx8qm-clk", .data =
> FLAG_CLK_IMX8_IMX8QM, }, { },
>  };
>  
> diff --git a/drivers/clk/imx/clk-imx8.h b/drivers/clk/imx/clk-imx8.h
> index 68ad675..c0566f8 100644
> --- a/drivers/clk/imx/clk-imx8.h
> +++ b/drivers/clk/imx/clk-imx8.h
> @@ -4,16 +4,87 @@
>   * Peng Fan <peng.fan@nxp.com>
>   */
>  
> -struct imx8_clks {
> +#define CLK_IMX8_MAX_MUX_SEL 5
> +
> +#define FLAG_CLK_IMX8_IMX8QM	BIT(0)
> +#define FLAG_CLK_IMX8_IMX8QXP	BIT(1)
> +
> +struct imx8_clk_header {
>  	ulong id;
> +#if CONFIG_IS_ENABLED(CMD_CLK)
>  	const char *name;
> +#endif
> +};
> +
> +struct imx8_clks {
> +	struct imx8_clk_header hdr;
> +	u16 rsrc;
> +	sc_pm_clk_t pm_clk;
> +};
> +
> +struct imx8_fixed_clks {
> +	struct imx8_clk_header hdr;
> +	ulong rate;
> +};
> +
> +struct imx8_gpr_clks {
> +	struct imx8_clk_header hdr;
> +	u16 rsrc;
> +	sc_ctrl_t gpr_id;
> +	ulong parent_id;
> +};
> +
> +struct imx8_lpcg_clks {
> +	struct imx8_clk_header hdr;
> +	u8 bit_idx;
> +	u32 lpcg;
> +	ulong parent_id;
> +};
> +
> +struct imx8_mux_clks {
> +	struct imx8_clk_header hdr;
> +	ulong slice_clk_id;
> +	ulong parent_clks[CLK_IMX8_MAX_MUX_SEL];
> +};
> +
> +enum imx8_clk_type {
> +	IMX8_CLK_SLICE 		= 0,
> +	IMX8_CLK_FIXED 	= 1,
> +	IMX8_CLK_GPR 		= 2,
> +	IMX8_CLK_LPCG 		= 3,
> +	IMX8_CLK_MUX 		= 4,
> +	IMX8_CLK_END		= 5,
> +};
> +
> +struct imx8_clk_pair {
> +	void *type_clks;
> +	u32 num;
> +};
> +
> +struct imx8_clks_collect {
> +	struct imx8_clk_pair clks[IMX8_CLK_END];
> +	ulong match_flag;
>  };
>  
>  #if CONFIG_IS_ENABLED(CMD_CLK)
> -extern struct imx8_clks imx8_clk_names[];
> -extern int num_clks;
> +#define CLK_3(ID, NAME, MEM2) \
> +	{ { ID, NAME, }, MEM2, }
> +#define CLK_4(ID, NAME, MEM2, MEM3) \
> +	{ { ID, NAME, }, MEM2, MEM3, }
> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
> +	{ { ID, NAME, }, MEM2, MEM3, MEM4, }
> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
> +	{ { ID, NAME, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
> +#else
> +#define CLK_3(ID, NAME, MEM2) \
> +	{ { ID, }, MEM2, }
> +#define CLK_4(ID, NAME, MEM2, MEM3) \
> +	{ { ID, }, MEM2, MEM3, }
> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
> +	{ { ID, }, MEM2, MEM3, MEM4, }
> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
> +	{ { ID, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
>  #endif
>  
> -ulong imx8_clk_get_rate(struct clk *clk);
> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate);
> -int __imx8_clk_enable(struct clk *clk, bool enable);
> +extern struct imx8_clks_collect imx8qxp_clk_collect;
> +extern struct imx8_clks_collect imx8qm_clk_collect;
> diff --git a/drivers/clk/imx/clk-imx8qm.c
> b/drivers/clk/imx/clk-imx8qm.c index a6b09d2..f4ee007 100644
> --- a/drivers/clk/imx/clk-imx8qm.c
> +++ b/drivers/clk/imx/clk-imx8qm.c
> @@ -12,314 +12,189 @@
>  #include <dt-bindings/clock/imx8qm-clock.h>
>  #include <dt-bindings/soc/imx_rsrc.h>
>  #include <misc.h>
> +#include <asm/arch/lpcg.h>
>  
>  #include "clk-imx8.h"
>  
> -#if CONFIG_IS_ENABLED(CMD_CLK)
> -struct imx8_clks imx8_clk_names[] = {
> -	{ IMX8QM_A53_DIV, "A53_DIV" },
> -	{ IMX8QM_UART0_CLK, "UART0" },
> -	{ IMX8QM_UART1_CLK, "UART1" },
> -	{ IMX8QM_UART2_CLK, "UART2" },
> -	{ IMX8QM_UART3_CLK, "UART3" },
> -	{ IMX8QM_SDHC0_CLK, "SDHC0" },
> -	{ IMX8QM_SDHC1_CLK, "SDHC1" },
> -	{ IMX8QM_SDHC2_CLK, "SDHC2" },
> -	{ IMX8QM_ENET0_AHB_CLK, "ENET0_AHB" },
> -	{ IMX8QM_ENET0_IPG_CLK, "ENET0_IPG" },
> -	{ IMX8QM_ENET0_REF_DIV, "ENET0_REF" },
> -	{ IMX8QM_ENET0_PTP_CLK, "ENET0_PTP" },
> -	{ IMX8QM_ENET1_AHB_CLK, "ENET1_AHB" },
> -	{ IMX8QM_ENET1_IPG_CLK, "ENET1_IPG" },
> -	{ IMX8QM_ENET1_REF_DIV, "ENET1_REF" },
> -	{ IMX8QM_ENET1_PTP_CLK, "ENET1_PTP" },
> +static struct imx8_clks imx8qm_clks[] = {
> +	CLK_4( IMX8QM_A53_DIV, "A53_DIV", SC_R_A53, SC_PM_CLK_CPU ),
> +	CLK_4( IMX8QM_A72_DIV, "A72_DIV", SC_R_A72, SC_PM_CLK_CPU ),
> +	CLK_4( IMX8QM_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_LVDS0_I2C0_DIV, "LVDS0 I2C0 DIV",
> SC_R_LVDS_0_I2C_0, SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_LVDS0_I2C1_DIV, "LVDS0 I2C1 DIV",
> SC_R_LVDS_0_I2C_1, SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_LVDS1_I2C0_DIV, "LVDS1 I2C0 DIV",
> SC_R_LVDS_1_I2C_0, SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_LVDS1_I2C1_DIV, "LVDS1 I2C1 DIV",
> SC_R_LVDS_1_I2C_1, SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QM_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QM_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QM_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QM_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_CSI1_I2C0_DIV, "CSI1 I2C0_DIV",
> SC_R_CSI_1_I2C_0, SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_HDMI_I2C0_DIV, "HDMI I2C0_DIV",
> SC_R_HDMI_I2C_0, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QM_HDMI_IPG_CLK, "HDMI IPG_CLK", SC_R_HDMI,
> SC_PM_CLK_MISC ),
> +	CLK_4( IMX8QM_HDMI_RX_I2C0_DIV, "HDMI RX I2C_DIV",
> SC_R_HDMI_RX_I2C_0, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QM_UART0_DIV, "UART0_DIV", SC_R_UART_0,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_UART1_DIV, "UART1_DIV", SC_R_UART_1,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_UART2_DIV, "UART2_DIV", SC_R_UART_2,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_UART3_DIV, "UART3_DIV", SC_R_UART_3,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_ENET0_ROOT_DIV, "ENET0_ROOT_DIV", SC_R_ENET_0,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
> +	CLK_4( IMX8QM_ENET1_ROOT_DIV, "ENET1_ROOT_DIV", SC_R_ENET_1,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
> SC_R_ENET_1, SC_PM_CLK_MISC0 ), +
> +	CLK_4( IMX8QM_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QM_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
> SC_PM_CLK_MST_BUS ),
> +	CLK_4( IMX8QM_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
> SC_PM_CLK_MISC ), +
> +	CLK_4( IMX8QM_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
> SC_PM_CLK_PER ), +
> +	CLK_4( IMX8QM_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND,
> SC_PM_CLK_MST_BUS ),
> +	CLK_4( IMX8QM_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
> SC_PM_CLK_PER ), };
>  
> -int num_clks = ARRAY_SIZE(imx8_clk_names);
> -#endif
> -
> -ulong imx8_clk_get_rate(struct clk *clk)
> -{
> -	sc_pm_clk_t pm_clk;
> -	ulong rate;
> -	u16 resource;
> -	int ret;
> -
> -	debug("%s(#%lu)\n", __func__, clk->id);
> -
> -	switch (clk->id) {
> -	case IMX8QM_A53_DIV:
> -		resource = SC_R_A53;
> -		pm_clk = SC_PM_CLK_CPU;
> -		break;
> -	case IMX8QM_I2C0_CLK:
> -		resource = SC_R_I2C_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_I2C1_CLK:
> -		resource = SC_R_I2C_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_I2C2_CLK:
> -		resource = SC_R_I2C_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_I2C3_CLK:
> -		resource = SC_R_I2C_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_SDHC0_IPG_CLK:
> -	case IMX8QM_SDHC0_CLK:
> -	case IMX8QM_SDHC0_DIV:
> -		resource = SC_R_SDHC_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_SDHC1_IPG_CLK:
> -	case IMX8QM_SDHC1_CLK:
> -	case IMX8QM_SDHC1_DIV:
> -		resource = SC_R_SDHC_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_SDHC2_IPG_CLK:
> -	case IMX8QM_SDHC2_CLK:
> -	case IMX8QM_SDHC2_DIV:
> -		resource = SC_R_SDHC_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART0_IPG_CLK:
> -	case IMX8QM_UART0_CLK:
> -		resource = SC_R_UART_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART1_CLK:
> -		resource = SC_R_UART_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART2_CLK:
> -		resource = SC_R_UART_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART3_CLK:
> -		resource = SC_R_UART_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_ENET0_IPG_CLK:
> -	case IMX8QM_ENET0_AHB_CLK:
> -	case IMX8QM_ENET0_REF_DIV:
> -	case IMX8QM_ENET0_PTP_CLK:
> -		resource = SC_R_ENET_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_ENET1_IPG_CLK:
> -	case IMX8QM_ENET1_AHB_CLK:
> -	case IMX8QM_ENET1_REF_DIV:
> -	case IMX8QM_ENET1_PTP_CLK:
> -		resource = SC_R_ENET_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	default:
> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
> -		    clk->id >= IMX8QM_CLK_END) {
> -			printf("%s(Invalid clk ID #%lu)\n",
> -			       __func__, clk->id);
> -			return -EINVAL;
> -		}
> -		return -ENOTSUPP;
> -	};
> -
> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
> -				   (sc_pm_clock_rate_t *)&rate);
> -	if (ret) {
> -		printf("%s err %d\n", __func__, ret);
> -		return ret;
> -	}
> -
> -	return rate;
> -}
> -
> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
> -{
> -	sc_pm_clk_t pm_clk;
> -	u32 new_rate = rate;
> -	u16 resource;
> -	int ret;
> -
> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
> -
> -	switch (clk->id) {
> -	case IMX8QM_I2C0_CLK:
> -		resource = SC_R_I2C_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_I2C1_CLK:
> -		resource = SC_R_I2C_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_I2C2_CLK:
> -		resource = SC_R_I2C_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_I2C3_CLK:
> -		resource = SC_R_I2C_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART0_CLK:
> -		resource = SC_R_UART_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART1_CLK:
> -		resource = SC_R_UART_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART2_CLK:
> -		resource = SC_R_UART_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART3_CLK:
> -		resource = SC_R_UART_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_SDHC0_IPG_CLK:
> -	case IMX8QM_SDHC0_CLK:
> -	case IMX8QM_SDHC0_DIV:
> -		resource = SC_R_SDHC_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_SDHC1_IPG_CLK:
> -	case IMX8QM_SDHC1_CLK:
> -	case IMX8QM_SDHC1_DIV:
> -		resource = SC_R_SDHC_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_SDHC2_IPG_CLK:
> -	case IMX8QM_SDHC2_CLK:
> -	case IMX8QM_SDHC2_DIV:
> -		resource = SC_R_SDHC_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_ENET0_IPG_CLK:
> -	case IMX8QM_ENET0_AHB_CLK:
> -	case IMX8QM_ENET0_REF_DIV:
> -	case IMX8QM_ENET0_PTP_CLK:
> -	case IMX8QM_ENET0_ROOT_DIV:
> -		resource = SC_R_ENET_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_ENET1_IPG_CLK:
> -	case IMX8QM_ENET1_AHB_CLK:
> -	case IMX8QM_ENET1_REF_DIV:
> -	case IMX8QM_ENET1_PTP_CLK:
> -	case IMX8QM_ENET1_ROOT_DIV:
> -		resource = SC_R_ENET_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	default:
> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
> -		    clk->id >= IMX8QM_CLK_END) {
> -			printf("%s(Invalid clk ID #%lu)\n",
> -			       __func__, clk->id);
> -			return -EINVAL;
> -		}
> -		return -ENOTSUPP;
> -	};
> -
> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
> -	if (ret) {
> -		printf("%s err %d\n", __func__, ret);
> -		return ret;
> -	}
> -
> -	return new_rate;
> -}
> -
> -int __imx8_clk_enable(struct clk *clk, bool enable)
> -{
> -	sc_pm_clk_t pm_clk;
> -	u16 resource;
> -	int ret;
> +static struct imx8_fixed_clks imx8qm_fixed_clks[] = {
> +	CLK_3( IMX8QM_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", SC_83MHZ ),
> +	CLK_3( IMX8QM_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK", SC_166MHZ ),
> +	CLK_3( IMX8QM_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK", SC_333MHZ ),
> +	CLK_3( IMX8QM_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ ),
> +	CLK_3( IMX8QM_IPG_MIPI_CSI_CLK_ROOT, "IPG_MIPI_CLK",
> SC_120MHZ ),
> +	CLK_3( IMX8QM_LVDS_IPG_CLK, "IPG_LVDS_CLK", SC_24MHZ ),
> +	CLK_3( IMX8QM_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
> +	CLK_3( IMX8QM_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
> +	CLK_3( IMX8QM_MIPI0_CLK_ROOT, "MIPI0_CLK", SC_120MHZ ),
> +	CLK_3( IMX8QM_MIPI1_CLK_ROOT, "MIPI1_CLK", SC_120MHZ ),
> +	CLK_3( IMX8QM_HDMI_RX_IPG_CLK, "HDMI_RX_IPG_CLK", SC_200MHZ
> ), +};
>  
> -	debug("%s(#%lu)\n", __func__, clk->id);
> +static struct imx8_gpr_clks imx8qm_gpr_clks[] = {
> +	CLK_5( IMX8QM_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0,
> SC_C_CLKDIV, IMX8QM_ENET0_ROOT_DIV ),
> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL,
> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
> +	CLK_4( IMX8QM_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
> SC_R_ENET_0, SC_C_TXCLK ),
> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK,
> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
> +	CLK_4( IMX8QM_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
> SC_R_ENET_0, SC_C_DISABLE_50 ), +
> +	CLK_5( IMX8QM_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1,
> SC_C_CLKDIV, IMX8QM_ENET1_ROOT_DIV ),
> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL,
> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
> +	CLK_4( IMX8QM_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
> SC_R_ENET_1, SC_C_TXCLK ),
> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK,
> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
> +	CLK_4( IMX8QM_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
>  
> -	switch (clk->id) {
> -	case IMX8QM_I2C0_CLK:
> -		resource = SC_R_I2C_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_I2C1_CLK:
> -		resource = SC_R_I2C_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_I2C2_CLK:
> -		resource = SC_R_I2C_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_I2C3_CLK:
> -		resource = SC_R_I2C_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART0_CLK:
> -		resource = SC_R_UART_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART1_CLK:
> -		resource = SC_R_UART_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART2_CLK:
> -		resource = SC_R_UART_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_UART3_CLK:
> -		resource = SC_R_UART_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_SDHC0_IPG_CLK:
> -	case IMX8QM_SDHC0_CLK:
> -	case IMX8QM_SDHC0_DIV:
> -		resource = SC_R_SDHC_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_SDHC1_IPG_CLK:
> -	case IMX8QM_SDHC1_CLK:
> -	case IMX8QM_SDHC1_DIV:
> -		resource = SC_R_SDHC_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_SDHC2_IPG_CLK:
> -	case IMX8QM_SDHC2_CLK:
> -	case IMX8QM_SDHC2_DIV:
> -		resource = SC_R_SDHC_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_ENET0_IPG_CLK:
> -	case IMX8QM_ENET0_AHB_CLK:
> -	case IMX8QM_ENET0_REF_DIV:
> -	case IMX8QM_ENET0_PTP_CLK:
> -		resource = SC_R_ENET_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QM_ENET1_IPG_CLK:
> -	case IMX8QM_ENET1_AHB_CLK:
> -	case IMX8QM_ENET1_REF_DIV:
> -	case IMX8QM_ENET1_PTP_CLK:
> -		resource = SC_R_ENET_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	default:
> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
> -		    clk->id >= IMX8QM_CLK_END) {
> -			printf("%s(Invalid clk ID #%lu)\n",
> -			       __func__, clk->id);
> -			return -EINVAL;
> -		}
> -		return -ENOTSUPP;
> -	}
> +static struct imx8_lpcg_clks imx8qm_lpcg_clks[] = {
> +	CLK_5( IMX8QM_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
> IMX8QM_I2C0_DIV ),
> +	CLK_5( IMX8QM_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG,
> IMX8QM_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QM_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
> IMX8QM_I2C1_DIV ),
> +	CLK_5( IMX8QM_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG,
> IMX8QM_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QM_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
> IMX8QM_I2C2_DIV ),
> +	CLK_5( IMX8QM_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG,
> IMX8QM_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QM_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
> IMX8QM_I2C3_DIV ),
> +	CLK_5( IMX8QM_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG,
> IMX8QM_IPG_DMA_CLK_ROOT ), +
> +	CLK_5( IMX8QM_LVDS0_I2C0_CLK, "LVDS0_I2C0_CLK", 0,
> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS0_I2C0_DIV ),
> +	CLK_5( IMX8QM_LVDS0_I2C0_IPG_CLK, "LVDS0_I2C0_IPG", 16,
> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
> +	CLK_5( IMX8QM_LVDS0_I2C1_CLK, "LVDS0_I2C1_CLK", 0,
> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS0_I2C1_DIV ),
> +	CLK_5( IMX8QM_LVDS0_I2C1_IPG_CLK, "LVDS0_I2C1_IPG", 16,
> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ),
> +	CLK_5( IMX8QM_LVDS1_I2C0_CLK, "LVDS1_I2C0_CLK", 0,
> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS1_I2C0_DIV ),
> +	CLK_5( IMX8QM_LVDS1_I2C0_IPG_CLK, "LVDS1_I2C0_IPG", 16,
> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
> +	CLK_5( IMX8QM_LVDS1_I2C1_CLK, "LVDS1_I2C1_CLK", 0,
> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS1_I2C1_DIV ),
> +	CLK_5( IMX8QM_LVDS1_I2C1_IPG_CLK, "LVDS1_I2C1_IPG", 16,
> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ), +
> +	CLK_5( IMX8QM_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
> MIPI_DSI_0_LPCG + 0x1c, IMX8QM_MIPI0_I2C0_DIV ),
> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 0,
> MIPI_DSI_0_LPCG + 0x14,  IMX8QM_MIPI0_I2C0_IPG_S_CLK),
> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_S_CLK, "MIPI0_I2C0_IPG_S", 0,
> MIPI_DSI_0_LPCG + 0x18, IMX8QM_MIPI0_CLK_ROOT ),
> +	CLK_5( IMX8QM_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
> MIPI_DSI_0_LPCG + 0x2c, IMX8QM_MIPI0_I2C1_DIV ),
> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 0,
> MIPI_DSI_0_LPCG + 0x24,  IMX8QM_MIPI0_I2C1_IPG_S_CLK),
> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_S_CLK, "MIPI0_I2C1_IPG_S", 0,
> MIPI_DSI_0_LPCG + 0x28, IMX8QM_MIPI0_CLK_ROOT ),
> +	CLK_5( IMX8QM_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
> MIPI_DSI_1_LPCG + 0x1c, IMX8QM_MIPI1_I2C0_DIV ),
> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 0,
> MIPI_DSI_1_LPCG + 0x14, IMX8QM_MIPI1_I2C0_IPG_S_CLK),
> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_S_CLK, "MIPI1_I2C0_IPG_S", 0,
> MIPI_DSI_1_LPCG + 0x18, IMX8QM_MIPI1_CLK_ROOT ),
> +	CLK_5( IMX8QM_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
> MIPI_DSI_1_LPCG + 0x2c, IMX8QM_MIPI1_I2C1_DIV ),
> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 0,
> MIPI_DSI_1_LPCG + 0x24, IMX8QM_MIPI1_I2C1_IPG_S_CLK),
> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_S_CLK, "MIPI1_I2C1_IPG_S", 0,
> MIPI_DSI_1_LPCG + 0x28, IMX8QM_MIPI1_CLK_ROOT ), +
> +	CLK_5( IMX8QM_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
> MIPI_CSI_0_LPCG + 0x14, IMX8QM_CSI0_I2C0_DIV ),
> +	CLK_5( IMX8QM_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
> MIPI_CSI_0_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
> +	CLK_5( IMX8QM_CSI1_I2C0_CLK, "CSI1_I2C0_CLK", 0,
> MIPI_CSI_1_LPCG + 0x14, IMX8QM_CSI1_I2C0_DIV ),
> +	CLK_5( IMX8QM_CSI1_I2C0_IPG_CLK, "CSI1_I2C0_IPG", 16,
> MIPI_CSI_1_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
> +	CLK_5( IMX8QM_HDMI_I2C0_CLK, "HDMI_I2C0_CLK", 0,
> DI_HDMI_LPCG, IMX8QM_HDMI_I2C0_DIV ),
> +	CLK_5( IMX8QM_HDMI_I2C_IPG_CLK, "HDMI_I2C0_IPG", 16,
> DI_HDMI_LPCG, IMX8QM_HDMI_IPG_CLK ),
> +	CLK_5( IMX8QM_HDMI_RX_I2C_DIV_CLK, "HDMI RX_I2C_DIV_CLK", 0,
> MIPI_DSI_0_LPCG + 0x14, IMX8QM_MIPI0_I2C0_DIV ),
> +	CLK_5( IMX8QM_HDMI_RX_I2C0_CLK, "HDMI RX_I2C_CLK", 0,
> MIPI_DSI_0_LPCG + 0x10, IMX8QM_HDMI_RX_I2C_DIV_CLK ),
> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_CLK, "HDMI_RX_I2C_IPG", 0,
> RX_HDMI_LPCG + 0x18,  IMX8QM_HDMI_RX_I2C_IPG_S_CLK),
> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_S_CLK, "HDMI_I2C_IPG_S", 0,
> RX_HDMI_LPCG + 0x1c, IMX8QM_HDMI_RX_IPG_CLK ), +
> +	CLK_5( IMX8QM_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
> IMX8QM_UART0_DIV ),
> +	CLK_5( IMX8QM_UART0_IPG_CLK, "UART0_IPG", 16, LPUART_0_LPCG,
> IMX8QM_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QM_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
> IMX8QM_UART1_DIV ),
> +	CLK_5( IMX8QM_UART1_IPG_CLK, "UART1_IPG", 16, LPUART_1_LPCG,
> IMX8QM_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QM_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
> IMX8QM_UART2_DIV ),
> +	CLK_5( IMX8QM_UART2_IPG_CLK, "UART2_IPG", 16, LPUART_2_LPCG,
> IMX8QM_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QM_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
> IMX8QM_UART3_DIV ),
> +	CLK_5( IMX8QM_UART3_IPG_CLK, "UART3_IPG", 16, LPUART_3_LPCG,
> IMX8QM_IPG_DMA_CLK_ROOT ), +
> +	CLK_5( IMX8QM_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
> IMX8QM_SDHC0_DIV ),
> +	CLK_5( IMX8QM_SDHC0_IPG_CLK, "SDHC0_IPG", 16, USDHC_0_LPCG,
> IMX8QM_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
> IMX8QM_SDHC1_DIV ),
> +	CLK_5( IMX8QM_SDHC1_IPG_CLK, "SDHC1_IPG", 16, USDHC_1_LPCG,
> IMX8QM_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
> IMX8QM_SDHC2_DIV ),
> +	CLK_5( IMX8QM_SDHC2_IPG_CLK, "SDHC2_IPG", 16, USDHC_2_LPCG,
> IMX8QM_IPG_CONN_CLK_ROOT ), +
> +	CLK_5( IMX8QM_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
> ENET_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG,
> IMX8QM_ENET0_IPG_S_CLK ),
> +	CLK_5( IMX8QM_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG,
> IMX8QM_AXI_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
> IMX8QM_ENET0_ROOT_DIV ),
> +	CLK_5( IMX8QM_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG,
> IMX8QM_ENET0_ROOT_DIV  ),
> +	CLK_5( IMX8QM_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
> ENET_0_LPCG, IMX8QM_ENET0_RMII_TX_SEL  ),
> +	CLK_5( IMX8QM_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
> ENET_0_LPCG + 0x4, IMX8QM_ENET0_RGMII_DIV  ), +
> +	CLK_5( IMX8QM_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
> ENET_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG,
> IMX8QM_ENET1_IPG_S_CLK ),
> +	CLK_5( IMX8QM_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG,
> IMX8QM_AXI_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
> IMX8QM_ENET1_ROOT_DIV ),
> +	CLK_5( IMX8QM_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG,
> IMX8QM_ENET1_ROOT_DIV  ),
> +	CLK_5( IMX8QM_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
> ENET_1_LPCG, IMX8QM_ENET1_RMII_TX_SEL  ),
> +	CLK_5( IMX8QM_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
> ENET_1_LPCG + 0x4, IMX8QM_ENET1_RGMII_DIV  ), +
> +	CLK_5( IMX8QM_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18,
> FSPI_0_LPCG, IMX8QM_LSIO_BUS_CLK ),
> +	CLK_5( IMX8QM_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14, FSPI_0_LPCG,
> IMX8QM_FSPI0_IPG_S_CLK ),
> +	CLK_5( IMX8QM_FSPI0_HCLK, "FSPI0_HCLK", 0x10, FSPI_0_LPCG,
> IMX8QM_LSIO_MEM_CLK ),
> +	CLK_5( IMX8QM_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG,
> IMX8QM_FSPI0_DIV ), +
> +	CLK_5( IMX8QM_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
> USB_2_LPCG, IMX8QM_AHB_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_USB2_OH_IPG_S_PL301_CLK,
> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), +
> +	CLK_5( IMX8QM_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
> IMX8QM_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG,
> IMX8QM_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
> IMX8QM_USB3_IPG_CLK ),
> +	CLK_5( IMX8QM_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
> IMX8QM_USB3_ACLK_DIV ),
> +	CLK_5( IMX8QM_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
> IMX8QM_USB3_BUS_DIV ),
> +	CLK_5( IMX8QM_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
> IMX8QM_USB3_LPM_DIV ), +
> +	CLK_5( IMX8QM_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
> IMX8QM_AXI_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
> NAND_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QM_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4, NAND_LPCG,
> IMX8QM_GPMI_BCH_IO_DIV ),
> +	CLK_5( IMX8QM_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG,
> IMX8QM_GPMI_BCH_DIV ),
> +	CLK_5( IMX8QM_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG + 0x4,
> IMX8QM_AXI_CONN_CLK_ROOT ), +};
>  
> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
> -	if (ret) {
> -		printf("%s err %d\n", __func__, ret);
> -		return ret;
> -	}
> +struct imx8_mux_clks imx8qm_mux_clks[] = {
> +};
>  
> -	return 0;
> -}
> +struct imx8_clks_collect imx8qm_clk_collect = {
> +	{
> +		{&imx8qm_clks, ARRAY_SIZE(imx8qm_clks)},
> +		{&imx8qm_fixed_clks, ARRAY_SIZE(imx8qm_fixed_clks)},
> +		{&imx8qm_gpr_clks, ARRAY_SIZE(imx8qm_gpr_clks)},
> +		{&imx8qm_lpcg_clks, ARRAY_SIZE(imx8qm_lpcg_clks)},
> +		{&imx8qm_mux_clks, ARRAY_SIZE(imx8qm_mux_clks)},
> +	},
> +	FLAG_CLK_IMX8_IMX8QM,
> +};
> diff --git a/drivers/clk/imx/clk-imx8qxp.c
> b/drivers/clk/imx/clk-imx8qxp.c index 1fca36a..8181a97 100644
> --- a/drivers/clk/imx/clk-imx8qxp.c
> +++ b/drivers/clk/imx/clk-imx8qxp.c
> @@ -12,300 +12,156 @@
>  #include <dt-bindings/clock/imx8qxp-clock.h>
>  #include <dt-bindings/soc/imx_rsrc.h>
>  #include <misc.h>
> +#include <asm/arch/lpcg.h>
>  
>  #include "clk-imx8.h"
>  
> -#if CONFIG_IS_ENABLED(CMD_CLK)
> -struct imx8_clks imx8_clk_names[] = {
> -	{ IMX8QXP_A35_DIV, "A35_DIV" },
> -	{ IMX8QXP_I2C0_CLK, "I2C0" },
> -	{ IMX8QXP_I2C1_CLK, "I2C1" },
> -	{ IMX8QXP_I2C2_CLK, "I2C2" },
> -	{ IMX8QXP_I2C3_CLK, "I2C3" },
> -	{ IMX8QXP_UART0_CLK, "UART0" },
> -	{ IMX8QXP_UART1_CLK, "UART1" },
> -	{ IMX8QXP_UART2_CLK, "UART2" },
> -	{ IMX8QXP_UART3_CLK, "UART3" },
> -	{ IMX8QXP_SDHC0_CLK, "SDHC0" },
> -	{ IMX8QXP_SDHC1_CLK, "SDHC1" },
> -	{ IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" },
> -	{ IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" },
> -	{ IMX8QXP_ENET0_REF_DIV, "ENET0_REF" },
> -	{ IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" },
> -	{ IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" },
> -	{ IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" },
> -	{ IMX8QXP_ENET1_REF_DIV, "ENET1_REF" },
> -	{ IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" },
> +static struct imx8_clks imx8qxp_clks[] = {
> +	CLK_4( IMX8QXP_A35_DIV, "A35_DIV", SC_R_A35, SC_PM_CLK_CPU ),
> +	CLK_4( IMX8QXP_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QXP_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QXP_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QXP_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
> +	CLK_4( IMX8QXP_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_UART0_DIV, "UART0_DIV", SC_R_UART_0,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_UART1_DIV, "UART1_DIV", SC_R_UART_1,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_UART2_DIV, "UART2_DIV", SC_R_UART_2,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_UART3_DIV, "UART3_DIV", SC_R_UART_3,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_ENET0_ROOT_DIV, "ENET0_ROOT_DIV",
> SC_R_ENET_0, SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
> +	CLK_4( IMX8QXP_ENET1_ROOT_DIV, "ENET1_ROOT_DIV",
> SC_R_ENET_1, SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
> SC_R_ENET_1, SC_PM_CLK_MISC0 ),
> +	CLK_4( IMX8QXP_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
> SC_PM_CLK_MST_BUS ),
> +	CLK_4( IMX8QXP_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
> SC_PM_CLK_MISC ),
> +	CLK_4( IMX8QXP_LSIO_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
> SC_PM_CLK_PER ),
> +	CLK_4( IMX8QXP_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND,
> SC_PM_CLK_MST_BUS ),
> +	CLK_4( IMX8QXP_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
> SC_PM_CLK_PER ), };
>  
> -int num_clks = ARRAY_SIZE(imx8_clk_names);
> -#endif
> -
> -ulong imx8_clk_get_rate(struct clk *clk)
> -{
> -	sc_pm_clk_t pm_clk;
> -	ulong rate;
> -	u16 resource;
> -	int ret;
> -
> -	debug("%s(#%lu)\n", __func__, clk->id);
> -
> -	switch (clk->id) {
> -	case IMX8QXP_A35_DIV:
> -		resource = SC_R_A35;
> -		pm_clk = SC_PM_CLK_CPU;
> -		break;
> -	case IMX8QXP_I2C0_CLK:
> -		resource = SC_R_I2C_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_I2C1_CLK:
> -		resource = SC_R_I2C_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_I2C2_CLK:
> -		resource = SC_R_I2C_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_I2C3_CLK:
> -		resource = SC_R_I2C_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_SDHC0_IPG_CLK:
> -	case IMX8QXP_SDHC0_CLK:
> -	case IMX8QXP_SDHC0_DIV:
> -		resource = SC_R_SDHC_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_SDHC1_IPG_CLK:
> -	case IMX8QXP_SDHC1_CLK:
> -	case IMX8QXP_SDHC1_DIV:
> -		resource = SC_R_SDHC_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART0_IPG_CLK:
> -	case IMX8QXP_UART0_CLK:
> -		resource = SC_R_UART_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART1_CLK:
> -		resource = SC_R_UART_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART2_CLK:
> -		resource = SC_R_UART_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART3_CLK:
> -		resource = SC_R_UART_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_ENET0_IPG_CLK:
> -	case IMX8QXP_ENET0_AHB_CLK:
> -	case IMX8QXP_ENET0_REF_DIV:
> -	case IMX8QXP_ENET0_PTP_CLK:
> -		resource = SC_R_ENET_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_ENET1_IPG_CLK:
> -	case IMX8QXP_ENET1_AHB_CLK:
> -	case IMX8QXP_ENET1_REF_DIV:
> -	case IMX8QXP_ENET1_PTP_CLK:
> -		resource = SC_R_ENET_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	default:
> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
> -		    clk->id >= IMX8QXP_CLK_END) {
> -			printf("%s(Invalid clk ID #%lu)\n",
> -			       __func__, clk->id);
> -			return -EINVAL;
> -		}
> -		return -ENOTSUPP;
> -	};
> -
> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
> -				   (sc_pm_clock_rate_t *)&rate);
> -	if (ret) {
> -		printf("%s err %d\n", __func__, ret);
> -		return ret;
> -	}
> -
> -	return rate;
> -}
> -
> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
> -{
> -	sc_pm_clk_t pm_clk;
> -	u32 new_rate = rate;
> -	u16 resource;
> -	int ret;
> -
> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
> -
> -	switch (clk->id) {
> -	case IMX8QXP_I2C0_CLK:
> -		resource = SC_R_I2C_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_I2C1_CLK:
> -		resource = SC_R_I2C_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_I2C2_CLK:
> -		resource = SC_R_I2C_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_I2C3_CLK:
> -		resource = SC_R_I2C_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART0_CLK:
> -		resource = SC_R_UART_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART1_CLK:
> -		resource = SC_R_UART_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART2_CLK:
> -		resource = SC_R_UART_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART3_CLK:
> -		resource = SC_R_UART_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_SDHC0_IPG_CLK:
> -	case IMX8QXP_SDHC0_CLK:
> -	case IMX8QXP_SDHC0_DIV:
> -		resource = SC_R_SDHC_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_SDHC1_SEL:
> -	case IMX8QXP_SDHC0_SEL:
> -		return 0;
> -	case IMX8QXP_SDHC1_IPG_CLK:
> -	case IMX8QXP_SDHC1_CLK:
> -	case IMX8QXP_SDHC1_DIV:
> -		resource = SC_R_SDHC_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_ENET0_IPG_CLK:
> -	case IMX8QXP_ENET0_AHB_CLK:
> -	case IMX8QXP_ENET0_REF_DIV:
> -	case IMX8QXP_ENET0_PTP_CLK:
> -		resource = SC_R_ENET_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_ENET1_IPG_CLK:
> -	case IMX8QXP_ENET1_AHB_CLK:
> -	case IMX8QXP_ENET1_REF_DIV:
> -	case IMX8QXP_ENET1_PTP_CLK:
> -		resource = SC_R_ENET_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	default:
> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
> -		    clk->id >= IMX8QXP_CLK_END) {
> -			printf("%s(Invalid clk ID #%lu)\n",
> -			       __func__, clk->id);
> -			return -EINVAL;
> -		}
> -		return -ENOTSUPP;
> -	};
> -
> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
> -	if (ret) {
> -		printf("%s err %d\n", __func__, ret);
> -		return ret;
> -	}
> -
> -	return new_rate;
> -}
> -
> -int __imx8_clk_enable(struct clk *clk, bool enable)
> -{
> -	sc_pm_clk_t pm_clk;
> -	u16 resource;
> -	int ret;
> +static struct imx8_fixed_clks imx8qxp_fixed_clks[] = {
> +	CLK_3( IMX8QXP_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", SC_83MHZ ),
> +	CLK_3( IMX8QXP_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK", SC_166MHZ
> ),
> +	CLK_3( IMX8QXP_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK", SC_333MHZ
> ),
> +	CLK_3( IMX8QXP_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ ),
> +	CLK_3( IMX8QXP_MIPI_IPG_CLK, "IPG_MIPI_CLK", SC_120MHZ ),
> +	CLK_3( IMX8QXP_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
> +	CLK_3( IMX8QXP_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
> +};
>  
> -	debug("%s(#%lu)\n", __func__, clk->id);
> +static struct imx8_gpr_clks imx8qxp_gpr_clks[] = {
> +	CLK_5( IMX8QXP_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0,
> SC_C_CLKDIV, IMX8QXP_ENET0_ROOT_DIV ),
> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL,
> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
> +	CLK_4( IMX8QXP_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
> SC_R_ENET_0, SC_C_TXCLK ),
> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK,
> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
> +	CLK_4( IMX8QXP_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
> SC_R_ENET_0, SC_C_DISABLE_50 ), +
> +	CLK_5( IMX8QXP_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1,
> SC_C_CLKDIV, IMX8QXP_ENET1_ROOT_DIV ),
> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL,
> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
> +	CLK_4( IMX8QXP_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
> SC_R_ENET_1, SC_C_TXCLK ),
> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK,
> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
> +	CLK_4( IMX8QXP_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
>  
> -	switch (clk->id) {
> -	case IMX8QXP_I2C0_CLK:
> -		resource = SC_R_I2C_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_I2C1_CLK:
> -		resource = SC_R_I2C_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_I2C2_CLK:
> -		resource = SC_R_I2C_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_I2C3_CLK:
> -		resource = SC_R_I2C_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART0_CLK:
> -		resource = SC_R_UART_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART1_CLK:
> -		resource = SC_R_UART_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART2_CLK:
> -		resource = SC_R_UART_2;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_UART3_CLK:
> -		resource = SC_R_UART_3;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_SDHC0_IPG_CLK:
> -	case IMX8QXP_SDHC0_CLK:
> -	case IMX8QXP_SDHC0_DIV:
> -		resource = SC_R_SDHC_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_SDHC1_IPG_CLK:
> -	case IMX8QXP_SDHC1_CLK:
> -	case IMX8QXP_SDHC1_DIV:
> -		resource = SC_R_SDHC_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_ENET0_IPG_CLK:
> -	case IMX8QXP_ENET0_AHB_CLK:
> -	case IMX8QXP_ENET0_REF_DIV:
> -	case IMX8QXP_ENET0_PTP_CLK:
> -		resource = SC_R_ENET_0;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	case IMX8QXP_ENET1_IPG_CLK:
> -	case IMX8QXP_ENET1_AHB_CLK:
> -	case IMX8QXP_ENET1_REF_DIV:
> -	case IMX8QXP_ENET1_PTP_CLK:
> -		resource = SC_R_ENET_1;
> -		pm_clk = SC_PM_CLK_PER;
> -		break;
> -	default:
> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
> -		    clk->id >= IMX8QXP_CLK_END) {
> -			printf("%s(Invalid clk ID #%lu)\n",
> -			       __func__, clk->id);
> -			return -EINVAL;
> -		}
> -		return -ENOTSUPP;
> -	}
> +static struct imx8_lpcg_clks imx8qxp_lpcg_clks[] = {
> +	CLK_5( IMX8QXP_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
> IMX8QXP_I2C0_DIV ),
> +	CLK_5( IMX8QXP_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG,
> IMX8QXP_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QXP_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
> IMX8QXP_I2C1_DIV ),
> +	CLK_5( IMX8QXP_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG,
> IMX8QXP_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QXP_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
> IMX8QXP_I2C2_DIV ),
> +	CLK_5( IMX8QXP_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG,
> IMX8QXP_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QXP_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
> IMX8QXP_I2C3_DIV ),
> +	CLK_5( IMX8QXP_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG,
> IMX8QXP_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QXP_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI0_I2C0_DIV ),
> +	CLK_5( IMX8QXP_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 16,
> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
> +	CLK_5( IMX8QXP_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI0_I2C1_DIV ),
> +	CLK_5( IMX8QXP_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 16,
> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
> +	CLK_5( IMX8QXP_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI1_I2C0_DIV ),
> +	CLK_5( IMX8QXP_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 16,
> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
> +	CLK_5( IMX8QXP_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI1_I2C1_DIV ),
> +	CLK_5( IMX8QXP_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 16,
> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
> +	CLK_5( IMX8QXP_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_CSI0_I2C0_DIV ),
> +	CLK_5( IMX8QXP_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ), +
> +	CLK_5( IMX8QXP_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
> IMX8QXP_UART0_DIV ),
> +	CLK_5( IMX8QXP_UART0_IPG_CLK, "UART0_IPG", 16,
> LPUART_0_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QXP_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
> IMX8QXP_UART1_DIV ),
> +	CLK_5( IMX8QXP_UART1_IPG_CLK, "UART1_IPG", 16,
> LPUART_1_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QXP_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
> IMX8QXP_UART2_DIV ),
> +	CLK_5( IMX8QXP_UART2_IPG_CLK, "UART2_IPG", 16,
> LPUART_2_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> +	CLK_5( IMX8QXP_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
> IMX8QXP_UART3_DIV ),
> +	CLK_5( IMX8QXP_UART3_IPG_CLK, "UART3_IPG", 16,
> LPUART_3_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ), +
> +	CLK_5( IMX8QXP_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
> IMX8QXP_SDHC0_DIV ),
> +	CLK_5( IMX8QXP_SDHC0_IPG_CLK, "SDHC0_IPG", 16, USDHC_0_LPCG,
> IMX8QXP_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
> IMX8QXP_SDHC1_DIV ),
> +	CLK_5( IMX8QXP_SDHC1_IPG_CLK, "SDHC1_IPG", 16, USDHC_1_LPCG,
> IMX8QXP_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
> IMX8QXP_SDHC2_DIV ),
> +	CLK_5( IMX8QXP_SDHC2_IPG_CLK, "SDHC2_IPG", 16, USDHC_2_LPCG,
> IMX8QXP_IPG_CONN_CLK_ROOT ), +
> +	CLK_5( IMX8QXP_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
> ENET_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG,
> IMX8QXP_ENET0_IPG_S_CLK ),
> +	CLK_5( IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG,
> IMX8QXP_AXI_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
> IMX8QXP_ENET0_ROOT_DIV ),
> +	CLK_5( IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG,
> IMX8QXP_ENET0_ROOT_DIV  ),
> +	CLK_5( IMX8QXP_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
> ENET_0_LPCG, IMX8QXP_ENET0_RMII_TX_SEL  ),
> +	CLK_5( IMX8QXP_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
> ENET_0_LPCG + 0x4, IMX8QXP_ENET0_RGMII_DIV  ), +
> +	CLK_5( IMX8QXP_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
> ENET_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG,
> IMX8QXP_ENET1_IPG_S_CLK ),
> +	CLK_5( IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG,
> IMX8QXP_AXI_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
> IMX8QXP_ENET1_ROOT_DIV ),
> +	CLK_5( IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG,
> IMX8QXP_ENET1_ROOT_DIV  ),
> +	CLK_5( IMX8QXP_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
> ENET_1_LPCG, IMX8QXP_ENET1_RMII_TX_SEL  ),
> +	CLK_5( IMX8QXP_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
> ENET_1_LPCG + 0x4, IMX8QXP_ENET1_RGMII_DIV  ), +
> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18,
> FSPI_0_LPCG, IMX8QXP_LSIO_BUS_CLK ),
> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14,
> FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_IPG_S_CLK ),
> +	CLK_5( IMX8QXP_LSIO_FSPI0_HCLK, "FSPI0_HCLK", 0x10,
> FSPI_0_LPCG, IMX8QXP_LSIO_MEM_CLK ),
> +	CLK_5( IMX8QXP_LSIO_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG,
> IMX8QXP_LSIO_FSPI0_DIV ), +
> +	CLK_5( IMX8QXP_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
> USB_2_LPCG, IMX8QXP_AHB_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_PL301_CLK,
> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), +
> +	CLK_5( IMX8QXP_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
> IMX8QXP_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG,
> IMX8QXP_IPG_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
> IMX8QXP_USB3_IPG_CLK ),
> +	CLK_5( IMX8QXP_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
> IMX8QXP_USB3_ACLK_DIV ),
> +	CLK_5( IMX8QXP_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
> IMX8QXP_USB3_BUS_DIV ),
> +	CLK_5( IMX8QXP_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
> IMX8QXP_USB3_LPM_DIV ), +
> +	CLK_5( IMX8QXP_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
> IMX8QXP_AXI_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
> NAND_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
> +	CLK_5( IMX8QXP_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4, NAND_LPCG,
> IMX8QXP_GPMI_BCH_IO_DIV ),
> +	CLK_5( IMX8QXP_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG,
> IMX8QXP_GPMI_BCH_DIV ),
> +	CLK_5( IMX8QXP_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG + 0x4,
> IMX8QXP_AXI_CONN_CLK_ROOT ), +};
>  
> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
> -	if (ret) {
> -		printf("%s err %d\n", __func__, ret);
> -		return ret;
> -	}
> +struct imx8_mux_clks imx8qxp_mux_clks[] = {
> +	CLK_MUX( IMX8QXP_SDHC0_SEL, "SDHC0_SEL", IMX8QXP_SDHC0_DIV,
> IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
> IMX8QXP_CLK_DUMMY ),
> +	CLK_MUX( IMX8QXP_SDHC1_SEL, "SDHC1_SEL", IMX8QXP_SDHC1_DIV,
> IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
> IMX8QXP_CLK_DUMMY ),
> +	CLK_MUX( IMX8QXP_SDHC2_SEL, "SDHC2_SEL", IMX8QXP_SDHC2_DIV,
> IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
> IMX8QXP_CLK_DUMMY ), +};
>  
> -	return 0;
> -}
> +struct imx8_clks_collect imx8qxp_clk_collect = {
> +	{
> +		{&imx8qxp_clks, ARRAY_SIZE(imx8qxp_clks)},
> +		{&imx8qxp_fixed_clks,
> ARRAY_SIZE(imx8qxp_fixed_clks)},
> +		{&imx8qxp_gpr_clks, ARRAY_SIZE(imx8qxp_gpr_clks)},
> +		{&imx8qxp_lpcg_clks, ARRAY_SIZE(imx8qxp_lpcg_clks)},
> +		{&imx8qxp_mux_clks, ARRAY_SIZE(imx8qxp_mux_clks)},
> +	},
> +	FLAG_CLK_IMX8_IMX8QXP,
> +};




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190707/c78701fd/attachment.sig>

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

* [U-Boot] [PATCH 5/5] net: fec_mxc: Update driver to use full clks for iMX8
  2019-07-03  5:40 ` [U-Boot] [PATCH 5/5] net: fec_mxc: Update driver to use full clks for iMX8 Ye Li
@ 2019-07-06 23:09   ` Lukasz Majewski
  2019-07-10  5:45     ` [U-Boot] [EXT] " Ye Li
  0 siblings, 1 reply; 14+ messages in thread
From: Lukasz Majewski @ 2019-07-06 23:09 UTC (permalink / raw)
  To: u-boot

Hi Ye,

> Add support for more clocks used by iMX8 from DTB:
> ref_clock, tx_2x_clock, ahb_clock
> And update get clock rate interface to support multiple fec ports.
> 
> Signed-off-by: Ye Li <ye.li@nxp.com>
> ---
>  drivers/net/fec_mxc.c | 47
> ++++++++++++++++++++++++++++++++++++++--------- drivers/net/fec_mxc.h
> |  1 + 2 files changed, 39 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
> index d7c0809..6d485f1 100644
> --- a/drivers/net/fec_mxc.c
> +++ b/drivers/net/fec_mxc.c
> @@ -6,7 +6,6 @@
>   * (C) Copyright 2007 Pengutronix, Sascha Hauer
> <s.hauer@pengutronix.de>
>   * (C) Copyright 2007 Pengutronix, Juergen Beisert
> <j.beisert@pengutronix.de> */
> -
>  #include <common.h>
>  #include <dm.h>
>  #include <environment.h>
> @@ -132,9 +131,9 @@ static int fec_get_clk_rate(void *udev, int idx)
>  
>  	dev = udev;
>  	if (!dev) {
> -		ret = uclass_get_device(UCLASS_ETH, idx, &dev);
> +		ret = uclass_get_device_by_seq(UCLASS_ETH, idx,
> &dev); if (ret < 0) {
> -			debug("Can't get FEC udev: %d\n", ret);
> +			debug("Can't get FEC udev%d: %d\n", idx,
> ret); return ret;
>  		}
>  	}
> @@ -149,7 +148,7 @@ static int fec_get_clk_rate(void *udev, int idx)
>  #endif
>  }
>  
> -static void fec_mii_setspeed(struct ethernet_regs *eth)
> +static void fec_mii_setspeed(struct ethernet_regs *eth, int idx)
>  {
>  	/*
>  	 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
> @@ -171,7 +170,7 @@ static void fec_mii_setspeed(struct ethernet_regs
> *eth) u32 hold;
>  	int ret;
>  
> -	ret = fec_get_clk_rate(NULL, 0);
> +	ret = fec_get_clk_rate(NULL, idx);
>  	if (ret < 0) {
>  		printf("Can't find FEC0 clk rate: %d\n", ret);
>  		return;
> @@ -593,7 +592,7 @@ static int fec_init(struct eth_device *dev, bd_t
> *bd) fec_reg_setup(fec);
>  
>  	if (fec->xcv_type != SEVENWIRE)
> -		fec_mii_setspeed(fec->bus->priv);
> +		fec_mii_setspeed(fec->bus->priv, fec->dev_id);
>  
>  	/* Set Opcode/Pause Duration Register */
>  	writel(0x00010020, &fec->eth->op_pause);	/* FIXME
> 0xffff0020; */ @@ -1073,7 +1072,7 @@ struct mii_dev
> *fec_get_miibus(ulong base_addr, int dev_id) free(bus);
>  		return NULL;
>  	}
> -	fec_mii_setspeed(eth);
> +	fec_mii_setspeed(eth, dev_id);
>  	return bus;
>  }
>  
> @@ -1142,7 +1141,7 @@ static int fec_probe(bd_t *bd, int dev_id,
> uint32_t base_addr, fec_set_dev_name(edev->name, dev_id);
>  	fec->dev_id = (dev_id == -1) ? 0 : dev_id;
>  	fec->bus = bus;
> -	fec_mii_setspeed(bus->priv);
> +	fec_mii_setspeed(bus->priv, fec->dev_id);
>  #ifdef CONFIG_PHYLIB
>  	fec->phydev = phydev;
>  	phy_connect_dev(phydev, edev);
> @@ -1324,6 +1323,7 @@ static int fecmxc_probe(struct udevice *dev)
>  	int ret;
>  
>  	if (IS_ENABLED(CONFIG_IMX8)) {
> +		struct clk ref_clk, clk_2x_txclk;
>  		ret = clk_get_by_name(dev, "ipg", &priv->ipg_clk);
>  		if (ret < 0) {
>  			debug("Can't get FEC ipg clk: %d\n", ret);
> @@ -1335,6 +1335,35 @@ static int fecmxc_probe(struct udevice *dev)
>  			return ret;
>  		}
>  
> +		ret = clk_get_by_name(dev, "ahb", &priv->ahb_clk);
> +		if (ret < 0) {
> +			debug("Can't get FEC ahb clk: %d\n", ret);
> +			return ret;
> +		}
> +		ret = clk_enable(&priv->ahb_clk);
> +		if (ret < 0) {
> +			debug("Can't enable FEC ahb clk: %d\n", ret);
> +			return ret;
> +		}
> +
> +		ret = clk_get_by_name(dev, "enet_clk_ref", &ref_clk);

The enet clock is not only IMX8 specific.

> +		if (ret >= 0) {
> +			ret = clk_enable(&ref_clk);
> +			if (ret < 0) {
> +				debug("Can't enable FEC ref clk:
> %d\n", ret);
> +				return ret;
> +			}
> +		}
> +
> +		ret = clk_get_by_name(dev, "enet_2x_txclk",
> &clk_2x_txclk);
> +		if (ret >= 0) {
> +			ret = clk_enable(&clk_2x_txclk);
> +			if (ret < 0) {
> +				debug("Can't enable FEC 2x_tx clk:
> %d\n", ret);
> +				return ret;
> +			}
> +		}
> +
>  		priv->clk_rate = clk_get_rate(&priv->ipg_clk);
>  	}
>  
> @@ -1368,7 +1397,6 @@ static int fecmxc_probe(struct udevice *dev)
>  	}
>  
>  	fec_reg_setup(priv);
> -
>  	priv->dev_id = dev->seq;
>  #ifdef CONFIG_FEC_MXC_MDIO_BASE
>  	bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE,
> dev->seq); @@ -1492,6 +1520,7 @@ static const struct udevice_id
> fecmxc_ids[] = { { .compatible = "fsl,imx53-fec" },
>  	{ .compatible = "fsl,imx7d-fec" },
>  	{ .compatible = "fsl,mvf600-fec" },
> +	{ .compatible = "fsl,imx8qm-fec" },

Could you check if this patch doesn't break existing i.MX53, i.MX6q
(mx53, mx6, mx7) by using buildman ?

https://github.com/dsd/u-boot/tree/master/tools/buildman

>  	{ }
>  };
>  
> diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h
> index e5f2dd7..23180a6 100644
> --- a/drivers/net/fec_mxc.h
> +++ b/drivers/net/fec_mxc.h
> @@ -264,6 +264,7 @@ struct fec_priv {
>  	u32 interface;
>  #endif
>  	struct clk ipg_clk;
> +	struct clk ahb_clk;
>  	u32 clk_rate;
>  };
>  




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190707/539fa63f/attachment.sig>

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

* [U-Boot] [EXT] Re: [PATCH 5/5] net: fec_mxc: Update driver to use full clks for iMX8
  2019-07-06 23:09   ` Lukasz Majewski
@ 2019-07-10  5:45     ` Ye Li
  0 siblings, 0 replies; 14+ messages in thread
From: Ye Li @ 2019-07-10  5:45 UTC (permalink / raw)
  To: u-boot

在 2019/7/7 7:10, Lukasz Majewski 写道:
> Hi Ye,
> 
>> Add support for more clocks used by iMX8 from DTB:
>> ref_clock, tx_2x_clock, ahb_clock
>> And update get clock rate interface to support multiple fec ports.
>>
>> Signed-off-by: Ye Li <ye.li@nxp.com>
>> ---
>>  drivers/net/fec_mxc.c | 47
>> ++++++++++++++++++++++++++++++++++++++--------- drivers/net/fec_mxc.h
>> |  1 + 2 files changed, 39 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
>> index d7c0809..6d485f1 100644
>> --- a/drivers/net/fec_mxc.c
>> +++ b/drivers/net/fec_mxc.c
>> @@ -6,7 +6,6 @@
>>   * (C) Copyright 2007 Pengutronix, Sascha Hauer
>> <s.hauer@pengutronix.de>
>>   * (C) Copyright 2007 Pengutronix, Juergen Beisert
>> <j.beisert@pengutronix.de> */
>> -
>>  #include <common.h>
>>  #include <dm.h>
>>  #include <environment.h>
>> @@ -132,9 +131,9 @@ static int fec_get_clk_rate(void *udev, int idx)
>>  
>>  	dev = udev;
>>  	if (!dev) {
>> -		ret = uclass_get_device(UCLASS_ETH, idx, &dev);
>> +		ret = uclass_get_device_by_seq(UCLASS_ETH, idx,
>> &dev); if (ret < 0) {
>> -			debug("Can't get FEC udev: %d\n", ret);
>> +			debug("Can't get FEC udev%d: %d\n", idx,
>> ret); return ret;
>>  		}
>>  	}
>> @@ -149,7 +148,7 @@ static int fec_get_clk_rate(void *udev, int idx)
>>  #endif
>>  }
>>  
>> -static void fec_mii_setspeed(struct ethernet_regs *eth)
>> +static void fec_mii_setspeed(struct ethernet_regs *eth, int idx)
>>  {
>>  	/*
>>  	 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
>> @@ -171,7 +170,7 @@ static void fec_mii_setspeed(struct ethernet_regs
>> *eth) u32 hold;
>>  	int ret;
>>  
>> -	ret = fec_get_clk_rate(NULL, 0);
>> +	ret = fec_get_clk_rate(NULL, idx);
>>  	if (ret < 0) {
>>  		printf("Can't find FEC0 clk rate: %d\n", ret);
>>  		return;
>> @@ -593,7 +592,7 @@ static int fec_init(struct eth_device *dev, bd_t
>> *bd) fec_reg_setup(fec);
>>  
>>  	if (fec->xcv_type != SEVENWIRE)
>> -		fec_mii_setspeed(fec->bus->priv);
>> +		fec_mii_setspeed(fec->bus->priv, fec->dev_id);
>>  
>>  	/* Set Opcode/Pause Duration Register */
>>  	writel(0x00010020, &fec->eth->op_pause);	/* FIXME
>> 0xffff0020; */ @@ -1073,7 +1072,7 @@ struct mii_dev
>> *fec_get_miibus(ulong base_addr, int dev_id) free(bus);
>>  		return NULL;
>>  	}
>> -	fec_mii_setspeed(eth);
>> +	fec_mii_setspeed(eth, dev_id);
>>  	return bus;
>>  }
>>  
>> @@ -1142,7 +1141,7 @@ static int fec_probe(bd_t *bd, int dev_id,
>> uint32_t base_addr, fec_set_dev_name(edev->name, dev_id);
>>  	fec->dev_id = (dev_id == -1) ? 0 : dev_id;
>>  	fec->bus = bus;
>> -	fec_mii_setspeed(bus->priv);
>> +	fec_mii_setspeed(bus->priv, fec->dev_id);
>>  #ifdef CONFIG_PHYLIB
>>  	fec->phydev = phydev;
>>  	phy_connect_dev(phydev, edev);
>> @@ -1324,6 +1323,7 @@ static int fecmxc_probe(struct udevice *dev)
>>  	int ret;
>>  
>>  	if (IS_ENABLED(CONFIG_IMX8)) {
>> +		struct clk ref_clk, clk_2x_txclk;
>>  		ret = clk_get_by_name(dev, "ipg", &priv->ipg_clk);
>>  		if (ret < 0) {
>>  			debug("Can't get FEC ipg clk: %d\n", ret);
>> @@ -1335,6 +1335,35 @@ static int fecmxc_probe(struct udevice *dev)
>>  			return ret;
>>  		}
>>  
>> +		ret = clk_get_by_name(dev, "ahb", &priv->ahb_clk);
>> +		if (ret < 0) {
>> +			debug("Can't get FEC ahb clk: %d\n", ret);
>> +			return ret;
>> +		}
>> +		ret = clk_enable(&priv->ahb_clk);
>> +		if (ret < 0) {
>> +			debug("Can't enable FEC ahb clk: %d\n", ret);
>> +			return ret;
>> +		}
>> +
>> +		ret = clk_get_by_name(dev, "enet_clk_ref", &ref_clk);
> 
> The enet clock is not only IMX8 specific.
Yes. But so far only IMX8 enables the clk-uclass. Others still use old way.
You can see IS_ENABLED(CONFIG_IMX8) is checked above the codes.


> 
>> +		if (ret >= 0) {
>> +			ret = clk_enable(&ref_clk);
>> +			if (ret < 0) {
>> +				debug("Can't enable FEC ref clk:
>> %d\n", ret);
>> +				return ret;
>> +			}
>> +		}
>> +
>> +		ret = clk_get_by_name(dev, "enet_2x_txclk",
>> &clk_2x_txclk);
>> +		if (ret >= 0) {
>> +			ret = clk_enable(&clk_2x_txclk);
>> +			if (ret < 0) {
>> +				debug("Can't enable FEC 2x_tx clk:
>> %d\n", ret);
>> +				return ret;
>> +			}
>> +		}
>> +
>>  		priv->clk_rate = clk_get_rate(&priv->ipg_clk);
>>  	}
>>  
>> @@ -1368,7 +1397,6 @@ static int fecmxc_probe(struct udevice *dev)
>>  	}
>>  
>>  	fec_reg_setup(priv);
>> -
>>  	priv->dev_id = dev->seq;
>>  #ifdef CONFIG_FEC_MXC_MDIO_BASE
>>  	bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE,
>> dev->seq); @@ -1492,6 +1520,7 @@ static const struct udevice_id
>> fecmxc_ids[] = { { .compatible = "fsl,imx53-fec" },
>>  	{ .compatible = "fsl,imx7d-fec" },
>>  	{ .compatible = "fsl,mvf600-fec" },
>> +	{ .compatible = "fsl,imx8qm-fec" },
> 
> Could you check if this patch doesn't break existing i.MX53, i.MX6q
> (mx53, mx6, mx7) by using buildman ?
> 
> https://github.com/dsd/u-boot/tree/master/tools/buildman
> 

I have run the buildman for mx53, mx6, mx7. No build break.

Best regards,
Ye Li
>>  	{ }
>>  };
>>  
>> diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h
>> index e5f2dd7..23180a6 100644
>> --- a/drivers/net/fec_mxc.h
>> +++ b/drivers/net/fec_mxc.h
>> @@ -264,6 +264,7 @@ struct fec_priv {
>>  	u32 interface;
>>  #endif
>>  	struct clk ipg_clk;
>> +	struct clk ahb_clk;
>>  	u32 clk_rate;
>>  };
>>  
> 
> 
> 
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
> 

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

* [U-Boot] [EXT] Re: [PATCH 3/5] clk: imx8: Update imx8 clock driver
  2019-07-06 23:07   ` Lukasz Majewski
@ 2019-07-10  7:14     ` Ye Li
  2019-07-10  7:34       ` Lukasz Majewski
  0 siblings, 1 reply; 14+ messages in thread
From: Ye Li @ 2019-07-10  7:14 UTC (permalink / raw)
  To: u-boot

Hi Lukasz,

> Hi Ye,
> 
>> Update imx8 clock driver to support LPCG and full clocks tree for some
>> modules aligned with kernel.
>>
>> We classify the clock into serveral types: slice, fixed, lpcg, gpr
>> and mux.
> 
> Is this code in sync with Linux kernel? Does the imx8 (in Linux kernel)
> use the Common Clock Framework?
This patch syncs the tree architecture with kernel but not the codes. imx8 kernel clock
driver uses common clock framework.

> 
>> Generally slice and fixed clocks are the sources. lpcg, gpr
>> and mux are the downstream of those sources and are used for gating,
>> muxing or dividing functions.
>>
>> This patch replaces the functions defined in imx8qm and imx8qxp with
>> the clock tables of different clock types. clk-imx8 use unified
>> functions to process these clock tables.
> 
> 
> I've posted the Common Clock Framework v5 to the mailing list recently:
> https://patchwork.ozlabs.org/cover/1121348/
> 
> 
> So maybe this code could benefit from those patches and use this
> infrastructure ?
> 
I think so. We will look into the CCF in u-boot and migrate it later. 
But now we prefer upstream this update first. This one has been tested in downstream. 
And we have some driver patches going for upstream depending on it, while 
a new driver using CCF may need more time to get ready.

Best regards,
Ye Li
>>
>> Note: since the clock depends on the power domain of its resource,
>> must power on the resource firstly, then we can get the clock.
>> Otherwise, we can't access lpcg. Thus, the clock dump only works for
>> the slice clock.
>>
>> Signed-off-by: Ye Li <ye.li@nxp.com>
>> ---
>>  drivers/clk/imx/clk-imx8.c    | 304 +++++++++++++++++++++++++--
>>  drivers/clk/imx/clk-imx8.h    |  83 +++++++-
>>  drivers/clk/imx/clk-imx8qm.c  | 479
>> ++++++++++++++++--------------------------
>> drivers/clk/imx/clk-imx8qxp.c | 432
>> +++++++++++++------------------------ 4 files changed, 689
>> insertions(+), 609 deletions(-)
>>
>> diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c
>> index a755e26..afdb6ea 100644
>> --- a/drivers/clk/imx/clk-imx8.c
>> +++ b/drivers/clk/imx/clk-imx8.c
>> @@ -12,32 +12,294 @@
>>  #include <dt-bindings/clock/imx8qxp-clock.h>
>>  #include <dt-bindings/soc/imx_rsrc.h>
>>  #include <misc.h>
>> +#include <asm/arch/lpcg.h>
>>  
>>  #include "clk-imx8.h"
>>  
>> -__weak ulong imx8_clk_get_rate(struct clk *clk)
>> +struct imx8_clks_collect *soc_data[] = {
>> +#ifdef CONFIG_IMX8QXP
>> +	&imx8qxp_clk_collect,
>> +#endif
>> +#ifdef CONFIG_IMX8QM
>> +	&imx8qm_clk_collect,
>> +#endif
>> +};
>> +
>> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id);
>> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
>> enable); +static ulong __imx8_clk_set_rate(struct udevice *dev, ulong
>> id, unsigned long rate); +
>> +static struct imx8_clks_collect * find_clks_collect(struct udevice
>> *dev) +{
>> +	ulong data = (ulong)dev_get_driver_data(dev);
>> +	int i;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(soc_data); i++) {
>> +		if (soc_data[i]->match_flag == data)
>> +			return soc_data[i];
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +static void * check_imx8_clk(struct udevice *dev, enum imx8_clk_type
>> type, ulong id, u32 size_of_clk) +{
>> +	u32 i, size;
>> +	struct imx8_clks_collect *clks_col = find_clks_collect(dev);
>> +	struct imx8_clk_header *hdr;
>> +	ulong clks;
>> +
>> +	if (!clks_col || !(clks_col->clks[type].type_clks)) {
>> +		printf("%s fails to get clks for type %d\n",
>> +		       __func__, type);
>> +		return NULL;
>> +	}
>> +
>> +	clks = (ulong)(clks_col->clks[type].type_clks);
>> +	size = clks_col->clks[type].num;
>> +
>> +	for (i = 0; i < size; i++) {
>> +		hdr = (struct imx8_clk_header *)clks;
>> +		if (id == hdr->id)
>> +			return (void *)hdr;
>> +
>> +		clks += size_of_clk;
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +static ulong imx8_get_rate_lpcg(struct udevice *dev, struct
>> imx8_lpcg_clks *lpcg_clk) +{
>> +	if (lpcg_clk->parent_id != 0) {
>> +		if (lpcg_is_clock_on(lpcg_clk->lpcg,
>> lpcg_clk->bit_idx >> 2)) {
>> +			return __imx8_clk_get_rate(dev,
>> lpcg_clk->parent_id);
>> +		} else {
>> +			return 0;
>> +		}
>> +	} else {
>> +		return -ENOSYS;
>> +	}
>> +}
>> +
>> +static ulong imx8_get_rate_slice(struct udevice *dev, struct
>> imx8_clks *slice_clk) +{
>> +	int ret;
>> +	u32 rate;
>> +
>> +	ret = sc_pm_get_clock_rate(-1, slice_clk->rsrc,
>> slice_clk->pm_clk,
>> +				   (sc_pm_clock_rate_t *)&rate);
>> +	if (ret) {
>> +		printf("%s err %d\n", __func__, ret);
>> +		return ret;
>> +	}
>> +
>> +	return rate;
>> +}
>> +
>> +static ulong imx8_get_rate_fixed(struct udevice *dev, struct
>> imx8_fixed_clks *fixed_clk) +{
>> +	return fixed_clk->rate;
>> +}
>> +
>> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id)
>> +{
>> +	void* clkdata;
>> +
>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
>> sizeof(struct imx8_lpcg_clks));
>> +	if (clkdata) {
>> +		return imx8_get_rate_lpcg(dev, (struct
>> imx8_lpcg_clks *)clkdata);
>> +	}
>> +
>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
>> sizeof(struct imx8_clks));
>> +	if (clkdata) {
>> +		return imx8_get_rate_slice(dev, (struct imx8_clks
>> *)clkdata);
>> +	}
>> +
>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_FIXED, id,
>> sizeof(struct imx8_fixed_clks));
>> +	if (clkdata) {
>> +		return imx8_get_rate_fixed(dev, (struct
>> imx8_fixed_clks *)clkdata);
>> +	}
>> +
>> +	return -ENOSYS;
>> +}
>> +
>> +static ulong imx8_clk_get_rate(struct clk *clk)
>> +{
>> +	return __imx8_clk_get_rate(clk->dev, clk->id);
>> +}
>> +
>> +static ulong imx8_set_rate_lpcg(struct udevice *dev, struct
>> imx8_lpcg_clks *lpcg_clk, unsigned long rate) +{
>> +	if (lpcg_clk->parent_id != 0) {
>> +		return __imx8_clk_set_rate(dev, lpcg_clk->parent_id,
>> rate);
>> +	} else {
>> +		return -ENOSYS;
>> +	}
>> +}
>> +
>> +static ulong imx8_set_rate_slice(struct udevice *dev, struct
>> imx8_clks *slice_clk, unsigned long rate) +{
>> +	int ret;
>> +	u32 new_rate = rate;
>> +
>> +	ret = sc_pm_set_clock_rate(-1, slice_clk->rsrc,
>> slice_clk->pm_clk, &new_rate);
>> +	if (ret) {
>> +		printf("%s err %d\n", __func__, ret);
>> +		return ret;
>> +	}
>> +
>> +	return new_rate;
>> +}
>> +
>> +static ulong imx8_set_rate_gpr(struct udevice *dev, struct
>> imx8_gpr_clks *gpr_clk, unsigned long rate) {
>> +	ulong parent_rate;
>> +	u32 val;
>> +	int ret;
>> +
>> +	if (gpr_clk->parent_id == 0)
>> +		return -ENOSYS;
>> +
>> +	parent_rate = __imx8_clk_get_rate(dev, gpr_clk->parent_id);
>> +	if (parent_rate > 0) {
>> +		val = (rate < parent_rate) ? 1 : 0;
>> +
>> +		ret = sc_misc_set_control(-1, gpr_clk->rsrc,
>> +			gpr_clk->gpr_id, val);
>> +		if (ret) {
>> +			printf("%s err %d\n", __func__, ret);
>> +			return ret;
>> +		}
>> +
>> +		return rate;
>> +	}
>> +
>> +	return -ENOSYS;
>> +}
>> +
>> +static ulong __imx8_clk_set_rate(struct udevice *dev, ulong id,
>> unsigned long rate) +{
>> +	void* clkdata;
>> +
>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
>> sizeof(struct imx8_clks));
>> +	if (clkdata) {
>> +		return imx8_set_rate_slice(dev, (struct imx8_clks
>> *)clkdata, rate);
>> +	}
>> +
>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
>> sizeof(struct imx8_lpcg_clks));
>> +	if (clkdata) {
>> +		return imx8_set_rate_lpcg(dev, (struct
>> imx8_lpcg_clks *)clkdata, rate);
>> +	}
>> +
>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_GPR, id,
>> sizeof(struct imx8_gpr_clks));
>> +	if (clkdata) {
>> +		return imx8_set_rate_gpr(dev, (struct imx8_gpr_clks
>> *)clkdata, rate);
>> +	}
>> +
>> +	return -ENOSYS;
>> +}
>> +
>> +static ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
>> +{
>> +	return __imx8_clk_set_rate(clk->dev, clk->id, rate);
>> +
>> +}
>> +
>> +static int imx8_enable_slice(struct udevice *dev, struct imx8_clks
>> *slice_clk, bool enable) +{
>> +	int ret;
>> +
>> +	ret = sc_pm_clock_enable(-1, slice_clk->rsrc,
>> slice_clk->pm_clk, enable, 0);
>> +	if (ret) {
>> +		printf("%s err %d\n", __func__, ret);
>> +		return ret;
>> +	}
>> +
>>  	return 0;
>>  }
>>  
>> -__weak ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
>> +static int imx8_enable_lpcg(struct udevice *dev, struct
>> imx8_lpcg_clks *lpcg_clk, bool enable) {
>> +	if (enable) {
>> +		if (lpcg_clk->parent_id != 0) {
>> +			__imx8_clk_enable(dev, lpcg_clk->parent_id,
>> enable);
>> +		}
>> +
>> +		lpcg_clock_on(lpcg_clk->lpcg, lpcg_clk->bit_idx >>
>> 2);
>> +	} else {
>> +		lpcg_clock_off(lpcg_clk->lpcg, lpcg_clk->bit_idx >>
>> 2); +
>> +		if (lpcg_clk->parent_id != 0) {
>> +			__imx8_clk_enable(dev, lpcg_clk->parent_id,
>> enable);
>> +		}
>> +	}
>> +
>>  	return 0;
>>  }
>>  
>> -__weak int __imx8_clk_enable(struct clk *clk, bool enable)
>> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
>> enable) {
>> -	return -ENOTSUPP;
>> +	void* clkdata;
>> +
>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
>> sizeof(struct imx8_lpcg_clks));
>> +	if (clkdata) {
>> +		return imx8_enable_lpcg(dev, (struct imx8_lpcg_clks
>> *)clkdata, enable);
>> +	}
>> +
>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
>> sizeof(struct imx8_clks));
>> +	if (clkdata) {
>> +		return imx8_enable_slice(dev, (struct imx8_clks
>> *)clkdata, enable);
>> +	}
>> +
>> +	return -ENOSYS;
>>  }
>>  
>>  static int imx8_clk_disable(struct clk *clk)
>>  {
>> -	return __imx8_clk_enable(clk, 0);
>> +	return __imx8_clk_enable(clk->dev, clk->id, 0);
>>  }
>>  
>>  static int imx8_clk_enable(struct clk *clk)
>>  {
>> -	return __imx8_clk_enable(clk, 1);
>> +	return __imx8_clk_enable(clk->dev, clk->id, 1);
>> +}
>> +
>> +static int imx8_set_parent_mux(struct udevice *dev, struct
>> imx8_mux_clks *mux_clk, ulong pid) +{
>> +	u32 i;
>> +	int ret;
>> +	struct imx8_clks *slice_clkdata;
>> +
>> +	slice_clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE,
>> mux_clk->slice_clk_id, sizeof(struct imx8_clks));
>> +	if (!slice_clkdata) {
>> +		printf("Error: fail to find slice clk %lu for this
>> mux %lu\n", mux_clk->slice_clk_id, mux_clk->hdr.id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	for (i = 0; i< CLK_IMX8_MAX_MUX_SEL; i++) {
>> +		if (pid == mux_clk->parent_clks[i]) {
>> +			ret = sc_pm_set_clock_parent(-1,
>> slice_clkdata->rsrc,  slice_clkdata->pm_clk, i);
>> +			if (ret)
>> +				printf("Error: fail to set clock
>> parent rsrc %d, pm_clk %d, parent clk %d\n",
>> +					slice_clkdata->rsrc,
>> slice_clkdata->pm_clk, i);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	return -ENOSYS;
>> +}
>> +
>> +static int imx8_clk_set_parent(struct clk *clk, struct clk *parent)
>> +{
>> +	void* clkdata;
>> +
>> +	clkdata = check_imx8_clk(clk->dev, IMX8_CLK_MUX, clk->id,
>> sizeof(struct imx8_mux_clks));
>> +	if (clkdata) {
>> +		return imx8_set_parent_mux(clk->dev, (struct
>> imx8_mux_clks *)clkdata, parent->id);
>> +	}
>> +
>> +	return -ENOSYS;
>>  }
>>  
>>  #if CONFIG_IS_ENABLED(CMD_CLK)
>> @@ -47,6 +309,9 @@ int soc_clk_dump(void)
>>  	struct clk clk;
>>  	unsigned long rate;
>>  	int i, ret;
>> +	u32 size;
>> +	struct imx8_clks *clks;
>> +	struct imx8_clks_collect *clks_col;
>>  
>>  	ret = uclass_get_device_by_driver(UCLASS_CLK,
>>  					  DM_GET_DRIVER(imx8_clk),
>> &dev); @@ -55,8 +320,19 @@ int soc_clk_dump(void)
>>  
>>  	printf("Clk\t\tHz\n");
>>  
>> -	for (i = 0; i < num_clks; i++) {
>> -		clk.id = imx8_clk_names[i].id;
>> +	clks_col = find_clks_collect(dev);
>> +
>> +	if (!clks_col
>> || !(clks_col->clks[IMX8_CLK_SLICE].type_clks)) {
>> +		printf("%s fails to get clks for type %d\n",
>> +		       __func__, IMX8_CLK_SLICE);
>> +		return -ENODEV;
>> +	}
>> +
>> +	clks = (struct imx8_clks
>> *)(clks_col->clks[IMX8_CLK_SLICE].type_clks);
>> +	size = clks_col->clks[IMX8_CLK_SLICE].num;
>> +
>> +	for (i = 0; i < size; i++) {
>> +		clk.id = clks[i].hdr.id;
>>  		ret = clk_request(dev, &clk);
>>  		if (ret < 0) {
>>  			debug("%s clk_request() failed: %d\n",
>> __func__, ret); @@ -70,21 +346,22 @@ int soc_clk_dump(void)
>>  
>>  		if (ret == -ENOTSUPP) {
>>  			printf("clk ID %lu not supported yet\n",
>> -			       imx8_clk_names[i].id);
>> +			       clks[i].hdr.id);
>>  			continue;
>>  		}
>>  		if (ret < 0) {
>>  			printf("%s %lu: get_rate err: %d\n",
>> -			       __func__, imx8_clk_names[i].id, ret);
>> +			       __func__, clks[i].hdr.id, ret);
>>  			continue;
>>  		}
>>  
>>  		printf("%s(%3lu):\t%lu\n",
>> -		       imx8_clk_names[i].name, imx8_clk_names[i].id,
>> rate);
>> +		       clks[i].hdr.name, clks[i].hdr.id, rate);
>>  	}
>>  
>>  	return 0;
>>  }
>> +
>>  #endif
>>  
>>  static struct clk_ops imx8_clk_ops = {
>> @@ -92,6 +369,7 @@ static struct clk_ops imx8_clk_ops = {
>>  	.get_rate = imx8_clk_get_rate,
>>  	.enable = imx8_clk_enable,
>>  	.disable = imx8_clk_disable,
>> +	.set_parent = imx8_clk_set_parent,
>>  };
>>  
>>  static int imx8_clk_probe(struct udevice *dev)
>> @@ -100,8 +378,8 @@ static int imx8_clk_probe(struct udevice *dev)
>>  }
>>  
>>  static const struct udevice_id imx8_clk_ids[] = {
>> -	{ .compatible = "fsl,imx8qxp-clk" },
>> -	{ .compatible = "fsl,imx8qm-clk" },
>> +	{ .compatible = "fsl,imx8qxp-clk", .data =
>> FLAG_CLK_IMX8_IMX8QXP, },
>> +	{ .compatible = "fsl,imx8qm-clk", .data =
>> FLAG_CLK_IMX8_IMX8QM, }, { },
>>  };
>>  
>> diff --git a/drivers/clk/imx/clk-imx8.h b/drivers/clk/imx/clk-imx8.h
>> index 68ad675..c0566f8 100644
>> --- a/drivers/clk/imx/clk-imx8.h
>> +++ b/drivers/clk/imx/clk-imx8.h
>> @@ -4,16 +4,87 @@
>>   * Peng Fan <peng.fan@nxp.com>
>>   */
>>  
>> -struct imx8_clks {
>> +#define CLK_IMX8_MAX_MUX_SEL 5
>> +
>> +#define FLAG_CLK_IMX8_IMX8QM	BIT(0)
>> +#define FLAG_CLK_IMX8_IMX8QXP	BIT(1)
>> +
>> +struct imx8_clk_header {
>>  	ulong id;
>> +#if CONFIG_IS_ENABLED(CMD_CLK)
>>  	const char *name;
>> +#endif
>> +};
>> +
>> +struct imx8_clks {
>> +	struct imx8_clk_header hdr;
>> +	u16 rsrc;
>> +	sc_pm_clk_t pm_clk;
>> +};
>> +
>> +struct imx8_fixed_clks {
>> +	struct imx8_clk_header hdr;
>> +	ulong rate;
>> +};
>> +
>> +struct imx8_gpr_clks {
>> +	struct imx8_clk_header hdr;
>> +	u16 rsrc;
>> +	sc_ctrl_t gpr_id;
>> +	ulong parent_id;
>> +};
>> +
>> +struct imx8_lpcg_clks {
>> +	struct imx8_clk_header hdr;
>> +	u8 bit_idx;
>> +	u32 lpcg;
>> +	ulong parent_id;
>> +};
>> +
>> +struct imx8_mux_clks {
>> +	struct imx8_clk_header hdr;
>> +	ulong slice_clk_id;
>> +	ulong parent_clks[CLK_IMX8_MAX_MUX_SEL];
>> +};
>> +
>> +enum imx8_clk_type {
>> +	IMX8_CLK_SLICE 		= 0,
>> +	IMX8_CLK_FIXED 	= 1,
>> +	IMX8_CLK_GPR 		= 2,
>> +	IMX8_CLK_LPCG 		= 3,
>> +	IMX8_CLK_MUX 		= 4,
>> +	IMX8_CLK_END		= 5,
>> +};
>> +
>> +struct imx8_clk_pair {
>> +	void *type_clks;
>> +	u32 num;
>> +};
>> +
>> +struct imx8_clks_collect {
>> +	struct imx8_clk_pair clks[IMX8_CLK_END];
>> +	ulong match_flag;
>>  };
>>  
>>  #if CONFIG_IS_ENABLED(CMD_CLK)
>> -extern struct imx8_clks imx8_clk_names[];
>> -extern int num_clks;
>> +#define CLK_3(ID, NAME, MEM2) \
>> +	{ { ID, NAME, }, MEM2, }
>> +#define CLK_4(ID, NAME, MEM2, MEM3) \
>> +	{ { ID, NAME, }, MEM2, MEM3, }
>> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
>> +	{ { ID, NAME, }, MEM2, MEM3, MEM4, }
>> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
>> +	{ { ID, NAME, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
>> +#else
>> +#define CLK_3(ID, NAME, MEM2) \
>> +	{ { ID, }, MEM2, }
>> +#define CLK_4(ID, NAME, MEM2, MEM3) \
>> +	{ { ID, }, MEM2, MEM3, }
>> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
>> +	{ { ID, }, MEM2, MEM3, MEM4, }
>> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
>> +	{ { ID, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
>>  #endif
>>  
>> -ulong imx8_clk_get_rate(struct clk *clk);
>> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate);
>> -int __imx8_clk_enable(struct clk *clk, bool enable);
>> +extern struct imx8_clks_collect imx8qxp_clk_collect;
>> +extern struct imx8_clks_collect imx8qm_clk_collect;
>> diff --git a/drivers/clk/imx/clk-imx8qm.c
>> b/drivers/clk/imx/clk-imx8qm.c index a6b09d2..f4ee007 100644
>> --- a/drivers/clk/imx/clk-imx8qm.c
>> +++ b/drivers/clk/imx/clk-imx8qm.c
>> @@ -12,314 +12,189 @@
>>  #include <dt-bindings/clock/imx8qm-clock.h>
>>  #include <dt-bindings/soc/imx_rsrc.h>
>>  #include <misc.h>
>> +#include <asm/arch/lpcg.h>
>>  
>>  #include "clk-imx8.h"
>>  
>> -#if CONFIG_IS_ENABLED(CMD_CLK)
>> -struct imx8_clks imx8_clk_names[] = {
>> -	{ IMX8QM_A53_DIV, "A53_DIV" },
>> -	{ IMX8QM_UART0_CLK, "UART0" },
>> -	{ IMX8QM_UART1_CLK, "UART1" },
>> -	{ IMX8QM_UART2_CLK, "UART2" },
>> -	{ IMX8QM_UART3_CLK, "UART3" },
>> -	{ IMX8QM_SDHC0_CLK, "SDHC0" },
>> -	{ IMX8QM_SDHC1_CLK, "SDHC1" },
>> -	{ IMX8QM_SDHC2_CLK, "SDHC2" },
>> -	{ IMX8QM_ENET0_AHB_CLK, "ENET0_AHB" },
>> -	{ IMX8QM_ENET0_IPG_CLK, "ENET0_IPG" },
>> -	{ IMX8QM_ENET0_REF_DIV, "ENET0_REF" },
>> -	{ IMX8QM_ENET0_PTP_CLK, "ENET0_PTP" },
>> -	{ IMX8QM_ENET1_AHB_CLK, "ENET1_AHB" },
>> -	{ IMX8QM_ENET1_IPG_CLK, "ENET1_IPG" },
>> -	{ IMX8QM_ENET1_REF_DIV, "ENET1_REF" },
>> -	{ IMX8QM_ENET1_PTP_CLK, "ENET1_PTP" },
>> +static struct imx8_clks imx8qm_clks[] = {
>> +	CLK_4( IMX8QM_A53_DIV, "A53_DIV", SC_R_A53, SC_PM_CLK_CPU ),
>> +	CLK_4( IMX8QM_A72_DIV, "A72_DIV", SC_R_A72, SC_PM_CLK_CPU ),
>> +	CLK_4( IMX8QM_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_LVDS0_I2C0_DIV, "LVDS0 I2C0 DIV",
>> SC_R_LVDS_0_I2C_0, SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_LVDS0_I2C1_DIV, "LVDS0 I2C1 DIV",
>> SC_R_LVDS_0_I2C_1, SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_LVDS1_I2C0_DIV, "LVDS1 I2C0 DIV",
>> SC_R_LVDS_1_I2C_0, SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_LVDS1_I2C1_DIV, "LVDS1 I2C1 DIV",
>> SC_R_LVDS_1_I2C_1, SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
>> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QM_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
>> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QM_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
>> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QM_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
>> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QM_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
>> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_CSI1_I2C0_DIV, "CSI1 I2C0_DIV",
>> SC_R_CSI_1_I2C_0, SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_HDMI_I2C0_DIV, "HDMI I2C0_DIV",
>> SC_R_HDMI_I2C_0, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QM_HDMI_IPG_CLK, "HDMI IPG_CLK", SC_R_HDMI,
>> SC_PM_CLK_MISC ),
>> +	CLK_4( IMX8QM_HDMI_RX_I2C0_DIV, "HDMI RX I2C_DIV",
>> SC_R_HDMI_RX_I2C_0, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QM_UART0_DIV, "UART0_DIV", SC_R_UART_0,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_UART1_DIV, "UART1_DIV", SC_R_UART_1,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_UART2_DIV, "UART2_DIV", SC_R_UART_2,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_UART3_DIV, "UART3_DIV", SC_R_UART_3,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_ENET0_ROOT_DIV, "ENET0_ROOT_DIV", SC_R_ENET_0,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
>> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
>> +	CLK_4( IMX8QM_ENET1_ROOT_DIV, "ENET1_ROOT_DIV", SC_R_ENET_1,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
>> SC_R_ENET_1, SC_PM_CLK_MISC0 ), +
>> +	CLK_4( IMX8QM_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QM_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
>> SC_PM_CLK_MST_BUS ),
>> +	CLK_4( IMX8QM_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
>> SC_PM_CLK_MISC ), +
>> +	CLK_4( IMX8QM_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
>> SC_PM_CLK_PER ), +
>> +	CLK_4( IMX8QM_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND,
>> SC_PM_CLK_MST_BUS ),
>> +	CLK_4( IMX8QM_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
>> SC_PM_CLK_PER ), };
>>  
>> -int num_clks = ARRAY_SIZE(imx8_clk_names);
>> -#endif
>> -
>> -ulong imx8_clk_get_rate(struct clk *clk)
>> -{
>> -	sc_pm_clk_t pm_clk;
>> -	ulong rate;
>> -	u16 resource;
>> -	int ret;
>> -
>> -	debug("%s(#%lu)\n", __func__, clk->id);
>> -
>> -	switch (clk->id) {
>> -	case IMX8QM_A53_DIV:
>> -		resource = SC_R_A53;
>> -		pm_clk = SC_PM_CLK_CPU;
>> -		break;
>> -	case IMX8QM_I2C0_CLK:
>> -		resource = SC_R_I2C_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_I2C1_CLK:
>> -		resource = SC_R_I2C_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_I2C2_CLK:
>> -		resource = SC_R_I2C_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_I2C3_CLK:
>> -		resource = SC_R_I2C_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_SDHC0_IPG_CLK:
>> -	case IMX8QM_SDHC0_CLK:
>> -	case IMX8QM_SDHC0_DIV:
>> -		resource = SC_R_SDHC_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_SDHC1_IPG_CLK:
>> -	case IMX8QM_SDHC1_CLK:
>> -	case IMX8QM_SDHC1_DIV:
>> -		resource = SC_R_SDHC_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_SDHC2_IPG_CLK:
>> -	case IMX8QM_SDHC2_CLK:
>> -	case IMX8QM_SDHC2_DIV:
>> -		resource = SC_R_SDHC_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART0_IPG_CLK:
>> -	case IMX8QM_UART0_CLK:
>> -		resource = SC_R_UART_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART1_CLK:
>> -		resource = SC_R_UART_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART2_CLK:
>> -		resource = SC_R_UART_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART3_CLK:
>> -		resource = SC_R_UART_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_ENET0_IPG_CLK:
>> -	case IMX8QM_ENET0_AHB_CLK:
>> -	case IMX8QM_ENET0_REF_DIV:
>> -	case IMX8QM_ENET0_PTP_CLK:
>> -		resource = SC_R_ENET_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_ENET1_IPG_CLK:
>> -	case IMX8QM_ENET1_AHB_CLK:
>> -	case IMX8QM_ENET1_REF_DIV:
>> -	case IMX8QM_ENET1_PTP_CLK:
>> -		resource = SC_R_ENET_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	default:
>> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
>> -		    clk->id >= IMX8QM_CLK_END) {
>> -			printf("%s(Invalid clk ID #%lu)\n",
>> -			       __func__, clk->id);
>> -			return -EINVAL;
>> -		}
>> -		return -ENOTSUPP;
>> -	};
>> -
>> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
>> -				   (sc_pm_clock_rate_t *)&rate);
>> -	if (ret) {
>> -		printf("%s err %d\n", __func__, ret);
>> -		return ret;
>> -	}
>> -
>> -	return rate;
>> -}
>> -
>> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
>> -{
>> -	sc_pm_clk_t pm_clk;
>> -	u32 new_rate = rate;
>> -	u16 resource;
>> -	int ret;
>> -
>> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
>> -
>> -	switch (clk->id) {
>> -	case IMX8QM_I2C0_CLK:
>> -		resource = SC_R_I2C_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_I2C1_CLK:
>> -		resource = SC_R_I2C_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_I2C2_CLK:
>> -		resource = SC_R_I2C_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_I2C3_CLK:
>> -		resource = SC_R_I2C_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART0_CLK:
>> -		resource = SC_R_UART_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART1_CLK:
>> -		resource = SC_R_UART_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART2_CLK:
>> -		resource = SC_R_UART_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART3_CLK:
>> -		resource = SC_R_UART_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_SDHC0_IPG_CLK:
>> -	case IMX8QM_SDHC0_CLK:
>> -	case IMX8QM_SDHC0_DIV:
>> -		resource = SC_R_SDHC_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_SDHC1_IPG_CLK:
>> -	case IMX8QM_SDHC1_CLK:
>> -	case IMX8QM_SDHC1_DIV:
>> -		resource = SC_R_SDHC_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_SDHC2_IPG_CLK:
>> -	case IMX8QM_SDHC2_CLK:
>> -	case IMX8QM_SDHC2_DIV:
>> -		resource = SC_R_SDHC_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_ENET0_IPG_CLK:
>> -	case IMX8QM_ENET0_AHB_CLK:
>> -	case IMX8QM_ENET0_REF_DIV:
>> -	case IMX8QM_ENET0_PTP_CLK:
>> -	case IMX8QM_ENET0_ROOT_DIV:
>> -		resource = SC_R_ENET_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_ENET1_IPG_CLK:
>> -	case IMX8QM_ENET1_AHB_CLK:
>> -	case IMX8QM_ENET1_REF_DIV:
>> -	case IMX8QM_ENET1_PTP_CLK:
>> -	case IMX8QM_ENET1_ROOT_DIV:
>> -		resource = SC_R_ENET_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	default:
>> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
>> -		    clk->id >= IMX8QM_CLK_END) {
>> -			printf("%s(Invalid clk ID #%lu)\n",
>> -			       __func__, clk->id);
>> -			return -EINVAL;
>> -		}
>> -		return -ENOTSUPP;
>> -	};
>> -
>> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
>> -	if (ret) {
>> -		printf("%s err %d\n", __func__, ret);
>> -		return ret;
>> -	}
>> -
>> -	return new_rate;
>> -}
>> -
>> -int __imx8_clk_enable(struct clk *clk, bool enable)
>> -{
>> -	sc_pm_clk_t pm_clk;
>> -	u16 resource;
>> -	int ret;
>> +static struct imx8_fixed_clks imx8qm_fixed_clks[] = {
>> +	CLK_3( IMX8QM_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", SC_83MHZ ),
>> +	CLK_3( IMX8QM_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK", SC_166MHZ ),
>> +	CLK_3( IMX8QM_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK", SC_333MHZ ),
>> +	CLK_3( IMX8QM_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ ),
>> +	CLK_3( IMX8QM_IPG_MIPI_CSI_CLK_ROOT, "IPG_MIPI_CLK",
>> SC_120MHZ ),
>> +	CLK_3( IMX8QM_LVDS_IPG_CLK, "IPG_LVDS_CLK", SC_24MHZ ),
>> +	CLK_3( IMX8QM_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
>> +	CLK_3( IMX8QM_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
>> +	CLK_3( IMX8QM_MIPI0_CLK_ROOT, "MIPI0_CLK", SC_120MHZ ),
>> +	CLK_3( IMX8QM_MIPI1_CLK_ROOT, "MIPI1_CLK", SC_120MHZ ),
>> +	CLK_3( IMX8QM_HDMI_RX_IPG_CLK, "HDMI_RX_IPG_CLK", SC_200MHZ
>> ), +};
>>  
>> -	debug("%s(#%lu)\n", __func__, clk->id);
>> +static struct imx8_gpr_clks imx8qm_gpr_clks[] = {
>> +	CLK_5( IMX8QM_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0,
>> SC_C_CLKDIV, IMX8QM_ENET0_ROOT_DIV ),
>> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL,
>> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
>> +	CLK_4( IMX8QM_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
>> SC_R_ENET_0, SC_C_TXCLK ),
>> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK,
>> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
>> +	CLK_4( IMX8QM_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
>> SC_R_ENET_0, SC_C_DISABLE_50 ), +
>> +	CLK_5( IMX8QM_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1,
>> SC_C_CLKDIV, IMX8QM_ENET1_ROOT_DIV ),
>> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL,
>> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
>> +	CLK_4( IMX8QM_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
>> SC_R_ENET_1, SC_C_TXCLK ),
>> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK,
>> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
>> +	CLK_4( IMX8QM_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
>> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
>>  
>> -	switch (clk->id) {
>> -	case IMX8QM_I2C0_CLK:
>> -		resource = SC_R_I2C_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_I2C1_CLK:
>> -		resource = SC_R_I2C_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_I2C2_CLK:
>> -		resource = SC_R_I2C_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_I2C3_CLK:
>> -		resource = SC_R_I2C_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART0_CLK:
>> -		resource = SC_R_UART_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART1_CLK:
>> -		resource = SC_R_UART_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART2_CLK:
>> -		resource = SC_R_UART_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_UART3_CLK:
>> -		resource = SC_R_UART_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_SDHC0_IPG_CLK:
>> -	case IMX8QM_SDHC0_CLK:
>> -	case IMX8QM_SDHC0_DIV:
>> -		resource = SC_R_SDHC_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_SDHC1_IPG_CLK:
>> -	case IMX8QM_SDHC1_CLK:
>> -	case IMX8QM_SDHC1_DIV:
>> -		resource = SC_R_SDHC_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_SDHC2_IPG_CLK:
>> -	case IMX8QM_SDHC2_CLK:
>> -	case IMX8QM_SDHC2_DIV:
>> -		resource = SC_R_SDHC_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_ENET0_IPG_CLK:
>> -	case IMX8QM_ENET0_AHB_CLK:
>> -	case IMX8QM_ENET0_REF_DIV:
>> -	case IMX8QM_ENET0_PTP_CLK:
>> -		resource = SC_R_ENET_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QM_ENET1_IPG_CLK:
>> -	case IMX8QM_ENET1_AHB_CLK:
>> -	case IMX8QM_ENET1_REF_DIV:
>> -	case IMX8QM_ENET1_PTP_CLK:
>> -		resource = SC_R_ENET_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	default:
>> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
>> -		    clk->id >= IMX8QM_CLK_END) {
>> -			printf("%s(Invalid clk ID #%lu)\n",
>> -			       __func__, clk->id);
>> -			return -EINVAL;
>> -		}
>> -		return -ENOTSUPP;
>> -	}
>> +static struct imx8_lpcg_clks imx8qm_lpcg_clks[] = {
>> +	CLK_5( IMX8QM_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
>> IMX8QM_I2C0_DIV ),
>> +	CLK_5( IMX8QM_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG,
>> IMX8QM_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QM_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
>> IMX8QM_I2C1_DIV ),
>> +	CLK_5( IMX8QM_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG,
>> IMX8QM_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QM_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
>> IMX8QM_I2C2_DIV ),
>> +	CLK_5( IMX8QM_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG,
>> IMX8QM_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QM_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
>> IMX8QM_I2C3_DIV ),
>> +	CLK_5( IMX8QM_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG,
>> IMX8QM_IPG_DMA_CLK_ROOT ), +
>> +	CLK_5( IMX8QM_LVDS0_I2C0_CLK, "LVDS0_I2C0_CLK", 0,
>> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS0_I2C0_DIV ),
>> +	CLK_5( IMX8QM_LVDS0_I2C0_IPG_CLK, "LVDS0_I2C0_IPG", 16,
>> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
>> +	CLK_5( IMX8QM_LVDS0_I2C1_CLK, "LVDS0_I2C1_CLK", 0,
>> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS0_I2C1_DIV ),
>> +	CLK_5( IMX8QM_LVDS0_I2C1_IPG_CLK, "LVDS0_I2C1_IPG", 16,
>> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ),
>> +	CLK_5( IMX8QM_LVDS1_I2C0_CLK, "LVDS1_I2C0_CLK", 0,
>> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS1_I2C0_DIV ),
>> +	CLK_5( IMX8QM_LVDS1_I2C0_IPG_CLK, "LVDS1_I2C0_IPG", 16,
>> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
>> +	CLK_5( IMX8QM_LVDS1_I2C1_CLK, "LVDS1_I2C1_CLK", 0,
>> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS1_I2C1_DIV ),
>> +	CLK_5( IMX8QM_LVDS1_I2C1_IPG_CLK, "LVDS1_I2C1_IPG", 16,
>> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ), +
>> +	CLK_5( IMX8QM_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
>> MIPI_DSI_0_LPCG + 0x1c, IMX8QM_MIPI0_I2C0_DIV ),
>> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 0,
>> MIPI_DSI_0_LPCG + 0x14,  IMX8QM_MIPI0_I2C0_IPG_S_CLK),
>> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_S_CLK, "MIPI0_I2C0_IPG_S", 0,
>> MIPI_DSI_0_LPCG + 0x18, IMX8QM_MIPI0_CLK_ROOT ),
>> +	CLK_5( IMX8QM_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
>> MIPI_DSI_0_LPCG + 0x2c, IMX8QM_MIPI0_I2C1_DIV ),
>> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 0,
>> MIPI_DSI_0_LPCG + 0x24,  IMX8QM_MIPI0_I2C1_IPG_S_CLK),
>> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_S_CLK, "MIPI0_I2C1_IPG_S", 0,
>> MIPI_DSI_0_LPCG + 0x28, IMX8QM_MIPI0_CLK_ROOT ),
>> +	CLK_5( IMX8QM_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
>> MIPI_DSI_1_LPCG + 0x1c, IMX8QM_MIPI1_I2C0_DIV ),
>> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 0,
>> MIPI_DSI_1_LPCG + 0x14, IMX8QM_MIPI1_I2C0_IPG_S_CLK),
>> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_S_CLK, "MIPI1_I2C0_IPG_S", 0,
>> MIPI_DSI_1_LPCG + 0x18, IMX8QM_MIPI1_CLK_ROOT ),
>> +	CLK_5( IMX8QM_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
>> MIPI_DSI_1_LPCG + 0x2c, IMX8QM_MIPI1_I2C1_DIV ),
>> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 0,
>> MIPI_DSI_1_LPCG + 0x24, IMX8QM_MIPI1_I2C1_IPG_S_CLK),
>> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_S_CLK, "MIPI1_I2C1_IPG_S", 0,
>> MIPI_DSI_1_LPCG + 0x28, IMX8QM_MIPI1_CLK_ROOT ), +
>> +	CLK_5( IMX8QM_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
>> MIPI_CSI_0_LPCG + 0x14, IMX8QM_CSI0_I2C0_DIV ),
>> +	CLK_5( IMX8QM_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
>> MIPI_CSI_0_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
>> +	CLK_5( IMX8QM_CSI1_I2C0_CLK, "CSI1_I2C0_CLK", 0,
>> MIPI_CSI_1_LPCG + 0x14, IMX8QM_CSI1_I2C0_DIV ),
>> +	CLK_5( IMX8QM_CSI1_I2C0_IPG_CLK, "CSI1_I2C0_IPG", 16,
>> MIPI_CSI_1_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
>> +	CLK_5( IMX8QM_HDMI_I2C0_CLK, "HDMI_I2C0_CLK", 0,
>> DI_HDMI_LPCG, IMX8QM_HDMI_I2C0_DIV ),
>> +	CLK_5( IMX8QM_HDMI_I2C_IPG_CLK, "HDMI_I2C0_IPG", 16,
>> DI_HDMI_LPCG, IMX8QM_HDMI_IPG_CLK ),
>> +	CLK_5( IMX8QM_HDMI_RX_I2C_DIV_CLK, "HDMI RX_I2C_DIV_CLK", 0,
>> MIPI_DSI_0_LPCG + 0x14, IMX8QM_MIPI0_I2C0_DIV ),
>> +	CLK_5( IMX8QM_HDMI_RX_I2C0_CLK, "HDMI RX_I2C_CLK", 0,
>> MIPI_DSI_0_LPCG + 0x10, IMX8QM_HDMI_RX_I2C_DIV_CLK ),
>> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_CLK, "HDMI_RX_I2C_IPG", 0,
>> RX_HDMI_LPCG + 0x18,  IMX8QM_HDMI_RX_I2C_IPG_S_CLK),
>> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_S_CLK, "HDMI_I2C_IPG_S", 0,
>> RX_HDMI_LPCG + 0x1c, IMX8QM_HDMI_RX_IPG_CLK ), +
>> +	CLK_5( IMX8QM_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
>> IMX8QM_UART0_DIV ),
>> +	CLK_5( IMX8QM_UART0_IPG_CLK, "UART0_IPG", 16, LPUART_0_LPCG,
>> IMX8QM_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QM_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
>> IMX8QM_UART1_DIV ),
>> +	CLK_5( IMX8QM_UART1_IPG_CLK, "UART1_IPG", 16, LPUART_1_LPCG,
>> IMX8QM_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QM_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
>> IMX8QM_UART2_DIV ),
>> +	CLK_5( IMX8QM_UART2_IPG_CLK, "UART2_IPG", 16, LPUART_2_LPCG,
>> IMX8QM_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QM_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
>> IMX8QM_UART3_DIV ),
>> +	CLK_5( IMX8QM_UART3_IPG_CLK, "UART3_IPG", 16, LPUART_3_LPCG,
>> IMX8QM_IPG_DMA_CLK_ROOT ), +
>> +	CLK_5( IMX8QM_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
>> IMX8QM_SDHC0_DIV ),
>> +	CLK_5( IMX8QM_SDHC0_IPG_CLK, "SDHC0_IPG", 16, USDHC_0_LPCG,
>> IMX8QM_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
>> IMX8QM_SDHC1_DIV ),
>> +	CLK_5( IMX8QM_SDHC1_IPG_CLK, "SDHC1_IPG", 16, USDHC_1_LPCG,
>> IMX8QM_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
>> IMX8QM_SDHC2_DIV ),
>> +	CLK_5( IMX8QM_SDHC2_IPG_CLK, "SDHC2_IPG", 16, USDHC_2_LPCG,
>> IMX8QM_IPG_CONN_CLK_ROOT ), +
>> +	CLK_5( IMX8QM_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
>> ENET_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG,
>> IMX8QM_ENET0_IPG_S_CLK ),
>> +	CLK_5( IMX8QM_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG,
>> IMX8QM_AXI_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
>> IMX8QM_ENET0_ROOT_DIV ),
>> +	CLK_5( IMX8QM_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG,
>> IMX8QM_ENET0_ROOT_DIV  ),
>> +	CLK_5( IMX8QM_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
>> ENET_0_LPCG, IMX8QM_ENET0_RMII_TX_SEL  ),
>> +	CLK_5( IMX8QM_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
>> ENET_0_LPCG + 0x4, IMX8QM_ENET0_RGMII_DIV  ), +
>> +	CLK_5( IMX8QM_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
>> ENET_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG,
>> IMX8QM_ENET1_IPG_S_CLK ),
>> +	CLK_5( IMX8QM_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG,
>> IMX8QM_AXI_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
>> IMX8QM_ENET1_ROOT_DIV ),
>> +	CLK_5( IMX8QM_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG,
>> IMX8QM_ENET1_ROOT_DIV  ),
>> +	CLK_5( IMX8QM_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
>> ENET_1_LPCG, IMX8QM_ENET1_RMII_TX_SEL  ),
>> +	CLK_5( IMX8QM_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
>> ENET_1_LPCG + 0x4, IMX8QM_ENET1_RGMII_DIV  ), +
>> +	CLK_5( IMX8QM_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18,
>> FSPI_0_LPCG, IMX8QM_LSIO_BUS_CLK ),
>> +	CLK_5( IMX8QM_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14, FSPI_0_LPCG,
>> IMX8QM_FSPI0_IPG_S_CLK ),
>> +	CLK_5( IMX8QM_FSPI0_HCLK, "FSPI0_HCLK", 0x10, FSPI_0_LPCG,
>> IMX8QM_LSIO_MEM_CLK ),
>> +	CLK_5( IMX8QM_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG,
>> IMX8QM_FSPI0_DIV ), +
>> +	CLK_5( IMX8QM_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
>> USB_2_LPCG, IMX8QM_AHB_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
>> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_USB2_OH_IPG_S_PL301_CLK,
>> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
>> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), +
>> +	CLK_5( IMX8QM_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
>> IMX8QM_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG,
>> IMX8QM_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
>> IMX8QM_USB3_IPG_CLK ),
>> +	CLK_5( IMX8QM_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
>> IMX8QM_USB3_ACLK_DIV ),
>> +	CLK_5( IMX8QM_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
>> IMX8QM_USB3_BUS_DIV ),
>> +	CLK_5( IMX8QM_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
>> IMX8QM_USB3_LPM_DIV ), +
>> +	CLK_5( IMX8QM_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
>> IMX8QM_AXI_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
>> NAND_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QM_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4, NAND_LPCG,
>> IMX8QM_GPMI_BCH_IO_DIV ),
>> +	CLK_5( IMX8QM_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG,
>> IMX8QM_GPMI_BCH_DIV ),
>> +	CLK_5( IMX8QM_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG + 0x4,
>> IMX8QM_AXI_CONN_CLK_ROOT ), +};
>>  
>> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
>> -	if (ret) {
>> -		printf("%s err %d\n", __func__, ret);
>> -		return ret;
>> -	}
>> +struct imx8_mux_clks imx8qm_mux_clks[] = {
>> +};
>>  
>> -	return 0;
>> -}
>> +struct imx8_clks_collect imx8qm_clk_collect = {
>> +	{
>> +		{&imx8qm_clks, ARRAY_SIZE(imx8qm_clks)},
>> +		{&imx8qm_fixed_clks, ARRAY_SIZE(imx8qm_fixed_clks)},
>> +		{&imx8qm_gpr_clks, ARRAY_SIZE(imx8qm_gpr_clks)},
>> +		{&imx8qm_lpcg_clks, ARRAY_SIZE(imx8qm_lpcg_clks)},
>> +		{&imx8qm_mux_clks, ARRAY_SIZE(imx8qm_mux_clks)},
>> +	},
>> +	FLAG_CLK_IMX8_IMX8QM,
>> +};
>> diff --git a/drivers/clk/imx/clk-imx8qxp.c
>> b/drivers/clk/imx/clk-imx8qxp.c index 1fca36a..8181a97 100644
>> --- a/drivers/clk/imx/clk-imx8qxp.c
>> +++ b/drivers/clk/imx/clk-imx8qxp.c
>> @@ -12,300 +12,156 @@
>>  #include <dt-bindings/clock/imx8qxp-clock.h>
>>  #include <dt-bindings/soc/imx_rsrc.h>
>>  #include <misc.h>
>> +#include <asm/arch/lpcg.h>
>>  
>>  #include "clk-imx8.h"
>>  
>> -#if CONFIG_IS_ENABLED(CMD_CLK)
>> -struct imx8_clks imx8_clk_names[] = {
>> -	{ IMX8QXP_A35_DIV, "A35_DIV" },
>> -	{ IMX8QXP_I2C0_CLK, "I2C0" },
>> -	{ IMX8QXP_I2C1_CLK, "I2C1" },
>> -	{ IMX8QXP_I2C2_CLK, "I2C2" },
>> -	{ IMX8QXP_I2C3_CLK, "I2C3" },
>> -	{ IMX8QXP_UART0_CLK, "UART0" },
>> -	{ IMX8QXP_UART1_CLK, "UART1" },
>> -	{ IMX8QXP_UART2_CLK, "UART2" },
>> -	{ IMX8QXP_UART3_CLK, "UART3" },
>> -	{ IMX8QXP_SDHC0_CLK, "SDHC0" },
>> -	{ IMX8QXP_SDHC1_CLK, "SDHC1" },
>> -	{ IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" },
>> -	{ IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" },
>> -	{ IMX8QXP_ENET0_REF_DIV, "ENET0_REF" },
>> -	{ IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" },
>> -	{ IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" },
>> -	{ IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" },
>> -	{ IMX8QXP_ENET1_REF_DIV, "ENET1_REF" },
>> -	{ IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" },
>> +static struct imx8_clks imx8qxp_clks[] = {
>> +	CLK_4( IMX8QXP_A35_DIV, "A35_DIV", SC_R_A35, SC_PM_CLK_CPU ),
>> +	CLK_4( IMX8QXP_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
>> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QXP_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
>> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QXP_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
>> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QXP_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
>> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
>> +	CLK_4( IMX8QXP_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
>> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_UART0_DIV, "UART0_DIV", SC_R_UART_0,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_UART1_DIV, "UART1_DIV", SC_R_UART_1,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_UART2_DIV, "UART2_DIV", SC_R_UART_2,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_UART3_DIV, "UART3_DIV", SC_R_UART_3,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_ENET0_ROOT_DIV, "ENET0_ROOT_DIV",
>> SC_R_ENET_0, SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
>> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
>> +	CLK_4( IMX8QXP_ENET1_ROOT_DIV, "ENET1_ROOT_DIV",
>> SC_R_ENET_1, SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
>> SC_R_ENET_1, SC_PM_CLK_MISC0 ),
>> +	CLK_4( IMX8QXP_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
>> SC_PM_CLK_MST_BUS ),
>> +	CLK_4( IMX8QXP_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
>> SC_PM_CLK_MISC ),
>> +	CLK_4( IMX8QXP_LSIO_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
>> SC_PM_CLK_PER ),
>> +	CLK_4( IMX8QXP_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND,
>> SC_PM_CLK_MST_BUS ),
>> +	CLK_4( IMX8QXP_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
>> SC_PM_CLK_PER ), };
>>  
>> -int num_clks = ARRAY_SIZE(imx8_clk_names);
>> -#endif
>> -
>> -ulong imx8_clk_get_rate(struct clk *clk)
>> -{
>> -	sc_pm_clk_t pm_clk;
>> -	ulong rate;
>> -	u16 resource;
>> -	int ret;
>> -
>> -	debug("%s(#%lu)\n", __func__, clk->id);
>> -
>> -	switch (clk->id) {
>> -	case IMX8QXP_A35_DIV:
>> -		resource = SC_R_A35;
>> -		pm_clk = SC_PM_CLK_CPU;
>> -		break;
>> -	case IMX8QXP_I2C0_CLK:
>> -		resource = SC_R_I2C_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_I2C1_CLK:
>> -		resource = SC_R_I2C_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_I2C2_CLK:
>> -		resource = SC_R_I2C_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_I2C3_CLK:
>> -		resource = SC_R_I2C_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_SDHC0_IPG_CLK:
>> -	case IMX8QXP_SDHC0_CLK:
>> -	case IMX8QXP_SDHC0_DIV:
>> -		resource = SC_R_SDHC_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_SDHC1_IPG_CLK:
>> -	case IMX8QXP_SDHC1_CLK:
>> -	case IMX8QXP_SDHC1_DIV:
>> -		resource = SC_R_SDHC_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART0_IPG_CLK:
>> -	case IMX8QXP_UART0_CLK:
>> -		resource = SC_R_UART_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART1_CLK:
>> -		resource = SC_R_UART_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART2_CLK:
>> -		resource = SC_R_UART_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART3_CLK:
>> -		resource = SC_R_UART_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_ENET0_IPG_CLK:
>> -	case IMX8QXP_ENET0_AHB_CLK:
>> -	case IMX8QXP_ENET0_REF_DIV:
>> -	case IMX8QXP_ENET0_PTP_CLK:
>> -		resource = SC_R_ENET_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_ENET1_IPG_CLK:
>> -	case IMX8QXP_ENET1_AHB_CLK:
>> -	case IMX8QXP_ENET1_REF_DIV:
>> -	case IMX8QXP_ENET1_PTP_CLK:
>> -		resource = SC_R_ENET_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	default:
>> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
>> -		    clk->id >= IMX8QXP_CLK_END) {
>> -			printf("%s(Invalid clk ID #%lu)\n",
>> -			       __func__, clk->id);
>> -			return -EINVAL;
>> -		}
>> -		return -ENOTSUPP;
>> -	};
>> -
>> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
>> -				   (sc_pm_clock_rate_t *)&rate);
>> -	if (ret) {
>> -		printf("%s err %d\n", __func__, ret);
>> -		return ret;
>> -	}
>> -
>> -	return rate;
>> -}
>> -
>> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
>> -{
>> -	sc_pm_clk_t pm_clk;
>> -	u32 new_rate = rate;
>> -	u16 resource;
>> -	int ret;
>> -
>> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
>> -
>> -	switch (clk->id) {
>> -	case IMX8QXP_I2C0_CLK:
>> -		resource = SC_R_I2C_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_I2C1_CLK:
>> -		resource = SC_R_I2C_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_I2C2_CLK:
>> -		resource = SC_R_I2C_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_I2C3_CLK:
>> -		resource = SC_R_I2C_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART0_CLK:
>> -		resource = SC_R_UART_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART1_CLK:
>> -		resource = SC_R_UART_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART2_CLK:
>> -		resource = SC_R_UART_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART3_CLK:
>> -		resource = SC_R_UART_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_SDHC0_IPG_CLK:
>> -	case IMX8QXP_SDHC0_CLK:
>> -	case IMX8QXP_SDHC0_DIV:
>> -		resource = SC_R_SDHC_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_SDHC1_SEL:
>> -	case IMX8QXP_SDHC0_SEL:
>> -		return 0;
>> -	case IMX8QXP_SDHC1_IPG_CLK:
>> -	case IMX8QXP_SDHC1_CLK:
>> -	case IMX8QXP_SDHC1_DIV:
>> -		resource = SC_R_SDHC_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_ENET0_IPG_CLK:
>> -	case IMX8QXP_ENET0_AHB_CLK:
>> -	case IMX8QXP_ENET0_REF_DIV:
>> -	case IMX8QXP_ENET0_PTP_CLK:
>> -		resource = SC_R_ENET_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_ENET1_IPG_CLK:
>> -	case IMX8QXP_ENET1_AHB_CLK:
>> -	case IMX8QXP_ENET1_REF_DIV:
>> -	case IMX8QXP_ENET1_PTP_CLK:
>> -		resource = SC_R_ENET_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	default:
>> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
>> -		    clk->id >= IMX8QXP_CLK_END) {
>> -			printf("%s(Invalid clk ID #%lu)\n",
>> -			       __func__, clk->id);
>> -			return -EINVAL;
>> -		}
>> -		return -ENOTSUPP;
>> -	};
>> -
>> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
>> -	if (ret) {
>> -		printf("%s err %d\n", __func__, ret);
>> -		return ret;
>> -	}
>> -
>> -	return new_rate;
>> -}
>> -
>> -int __imx8_clk_enable(struct clk *clk, bool enable)
>> -{
>> -	sc_pm_clk_t pm_clk;
>> -	u16 resource;
>> -	int ret;
>> +static struct imx8_fixed_clks imx8qxp_fixed_clks[] = {
>> +	CLK_3( IMX8QXP_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", SC_83MHZ ),
>> +	CLK_3( IMX8QXP_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK", SC_166MHZ
>> ),
>> +	CLK_3( IMX8QXP_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK", SC_333MHZ
>> ),
>> +	CLK_3( IMX8QXP_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ ),
>> +	CLK_3( IMX8QXP_MIPI_IPG_CLK, "IPG_MIPI_CLK", SC_120MHZ ),
>> +	CLK_3( IMX8QXP_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
>> +	CLK_3( IMX8QXP_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
>> +};
>>  
>> -	debug("%s(#%lu)\n", __func__, clk->id);
>> +static struct imx8_gpr_clks imx8qxp_gpr_clks[] = {
>> +	CLK_5( IMX8QXP_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0,
>> SC_C_CLKDIV, IMX8QXP_ENET0_ROOT_DIV ),
>> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL,
>> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
>> +	CLK_4( IMX8QXP_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
>> SC_R_ENET_0, SC_C_TXCLK ),
>> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK,
>> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
>> +	CLK_4( IMX8QXP_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
>> SC_R_ENET_0, SC_C_DISABLE_50 ), +
>> +	CLK_5( IMX8QXP_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1,
>> SC_C_CLKDIV, IMX8QXP_ENET1_ROOT_DIV ),
>> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL,
>> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
>> +	CLK_4( IMX8QXP_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
>> SC_R_ENET_1, SC_C_TXCLK ),
>> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK,
>> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
>> +	CLK_4( IMX8QXP_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
>> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
>>  
>> -	switch (clk->id) {
>> -	case IMX8QXP_I2C0_CLK:
>> -		resource = SC_R_I2C_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_I2C1_CLK:
>> -		resource = SC_R_I2C_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_I2C2_CLK:
>> -		resource = SC_R_I2C_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_I2C3_CLK:
>> -		resource = SC_R_I2C_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART0_CLK:
>> -		resource = SC_R_UART_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART1_CLK:
>> -		resource = SC_R_UART_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART2_CLK:
>> -		resource = SC_R_UART_2;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_UART3_CLK:
>> -		resource = SC_R_UART_3;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_SDHC0_IPG_CLK:
>> -	case IMX8QXP_SDHC0_CLK:
>> -	case IMX8QXP_SDHC0_DIV:
>> -		resource = SC_R_SDHC_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_SDHC1_IPG_CLK:
>> -	case IMX8QXP_SDHC1_CLK:
>> -	case IMX8QXP_SDHC1_DIV:
>> -		resource = SC_R_SDHC_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_ENET0_IPG_CLK:
>> -	case IMX8QXP_ENET0_AHB_CLK:
>> -	case IMX8QXP_ENET0_REF_DIV:
>> -	case IMX8QXP_ENET0_PTP_CLK:
>> -		resource = SC_R_ENET_0;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	case IMX8QXP_ENET1_IPG_CLK:
>> -	case IMX8QXP_ENET1_AHB_CLK:
>> -	case IMX8QXP_ENET1_REF_DIV:
>> -	case IMX8QXP_ENET1_PTP_CLK:
>> -		resource = SC_R_ENET_1;
>> -		pm_clk = SC_PM_CLK_PER;
>> -		break;
>> -	default:
>> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
>> -		    clk->id >= IMX8QXP_CLK_END) {
>> -			printf("%s(Invalid clk ID #%lu)\n",
>> -			       __func__, clk->id);
>> -			return -EINVAL;
>> -		}
>> -		return -ENOTSUPP;
>> -	}
>> +static struct imx8_lpcg_clks imx8qxp_lpcg_clks[] = {
>> +	CLK_5( IMX8QXP_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
>> IMX8QXP_I2C0_DIV ),
>> +	CLK_5( IMX8QXP_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG,
>> IMX8QXP_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
>> IMX8QXP_I2C1_DIV ),
>> +	CLK_5( IMX8QXP_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG,
>> IMX8QXP_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
>> IMX8QXP_I2C2_DIV ),
>> +	CLK_5( IMX8QXP_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG,
>> IMX8QXP_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
>> IMX8QXP_I2C3_DIV ),
>> +	CLK_5( IMX8QXP_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG,
>> IMX8QXP_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
>> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI0_I2C0_DIV ),
>> +	CLK_5( IMX8QXP_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 16,
>> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
>> +	CLK_5( IMX8QXP_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
>> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI0_I2C1_DIV ),
>> +	CLK_5( IMX8QXP_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 16,
>> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
>> +	CLK_5( IMX8QXP_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
>> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI1_I2C0_DIV ),
>> +	CLK_5( IMX8QXP_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 16,
>> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
>> +	CLK_5( IMX8QXP_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
>> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI1_I2C1_DIV ),
>> +	CLK_5( IMX8QXP_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 16,
>> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
>> +	CLK_5( IMX8QXP_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
>> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_CSI0_I2C0_DIV ),
>> +	CLK_5( IMX8QXP_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
>> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ), +
>> +	CLK_5( IMX8QXP_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
>> IMX8QXP_UART0_DIV ),
>> +	CLK_5( IMX8QXP_UART0_IPG_CLK, "UART0_IPG", 16,
>> LPUART_0_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
>> IMX8QXP_UART1_DIV ),
>> +	CLK_5( IMX8QXP_UART1_IPG_CLK, "UART1_IPG", 16,
>> LPUART_1_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
>> IMX8QXP_UART2_DIV ),
>> +	CLK_5( IMX8QXP_UART2_IPG_CLK, "UART2_IPG", 16,
>> LPUART_2_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
>> IMX8QXP_UART3_DIV ),
>> +	CLK_5( IMX8QXP_UART3_IPG_CLK, "UART3_IPG", 16,
>> LPUART_3_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ), +
>> +	CLK_5( IMX8QXP_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
>> IMX8QXP_SDHC0_DIV ),
>> +	CLK_5( IMX8QXP_SDHC0_IPG_CLK, "SDHC0_IPG", 16, USDHC_0_LPCG,
>> IMX8QXP_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
>> IMX8QXP_SDHC1_DIV ),
>> +	CLK_5( IMX8QXP_SDHC1_IPG_CLK, "SDHC1_IPG", 16, USDHC_1_LPCG,
>> IMX8QXP_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
>> IMX8QXP_SDHC2_DIV ),
>> +	CLK_5( IMX8QXP_SDHC2_IPG_CLK, "SDHC2_IPG", 16, USDHC_2_LPCG,
>> IMX8QXP_IPG_CONN_CLK_ROOT ), +
>> +	CLK_5( IMX8QXP_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
>> ENET_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG,
>> IMX8QXP_ENET0_IPG_S_CLK ),
>> +	CLK_5( IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG,
>> IMX8QXP_AXI_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
>> IMX8QXP_ENET0_ROOT_DIV ),
>> +	CLK_5( IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG,
>> IMX8QXP_ENET0_ROOT_DIV  ),
>> +	CLK_5( IMX8QXP_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
>> ENET_0_LPCG, IMX8QXP_ENET0_RMII_TX_SEL  ),
>> +	CLK_5( IMX8QXP_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
>> ENET_0_LPCG + 0x4, IMX8QXP_ENET0_RGMII_DIV  ), +
>> +	CLK_5( IMX8QXP_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
>> ENET_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG,
>> IMX8QXP_ENET1_IPG_S_CLK ),
>> +	CLK_5( IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG,
>> IMX8QXP_AXI_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
>> IMX8QXP_ENET1_ROOT_DIV ),
>> +	CLK_5( IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG,
>> IMX8QXP_ENET1_ROOT_DIV  ),
>> +	CLK_5( IMX8QXP_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
>> ENET_1_LPCG, IMX8QXP_ENET1_RMII_TX_SEL  ),
>> +	CLK_5( IMX8QXP_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
>> ENET_1_LPCG + 0x4, IMX8QXP_ENET1_RGMII_DIV  ), +
>> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18,
>> FSPI_0_LPCG, IMX8QXP_LSIO_BUS_CLK ),
>> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14,
>> FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_IPG_S_CLK ),
>> +	CLK_5( IMX8QXP_LSIO_FSPI0_HCLK, "FSPI0_HCLK", 0x10,
>> FSPI_0_LPCG, IMX8QXP_LSIO_MEM_CLK ),
>> +	CLK_5( IMX8QXP_LSIO_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG,
>> IMX8QXP_LSIO_FSPI0_DIV ), +
>> +	CLK_5( IMX8QXP_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
>> USB_2_LPCG, IMX8QXP_AHB_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
>> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_PL301_CLK,
>> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
>> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), +
>> +	CLK_5( IMX8QXP_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
>> IMX8QXP_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG,
>> IMX8QXP_IPG_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
>> IMX8QXP_USB3_IPG_CLK ),
>> +	CLK_5( IMX8QXP_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
>> IMX8QXP_USB3_ACLK_DIV ),
>> +	CLK_5( IMX8QXP_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
>> IMX8QXP_USB3_BUS_DIV ),
>> +	CLK_5( IMX8QXP_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
>> IMX8QXP_USB3_LPM_DIV ), +
>> +	CLK_5( IMX8QXP_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
>> IMX8QXP_AXI_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
>> NAND_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
>> +	CLK_5( IMX8QXP_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4, NAND_LPCG,
>> IMX8QXP_GPMI_BCH_IO_DIV ),
>> +	CLK_5( IMX8QXP_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG,
>> IMX8QXP_GPMI_BCH_DIV ),
>> +	CLK_5( IMX8QXP_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG + 0x4,
>> IMX8QXP_AXI_CONN_CLK_ROOT ), +};
>>  
>> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
>> -	if (ret) {
>> -		printf("%s err %d\n", __func__, ret);
>> -		return ret;
>> -	}
>> +struct imx8_mux_clks imx8qxp_mux_clks[] = {
>> +	CLK_MUX( IMX8QXP_SDHC0_SEL, "SDHC0_SEL", IMX8QXP_SDHC0_DIV,
>> IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
>> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
>> IMX8QXP_CLK_DUMMY ),
>> +	CLK_MUX( IMX8QXP_SDHC1_SEL, "SDHC1_SEL", IMX8QXP_SDHC1_DIV,
>> IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
>> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
>> IMX8QXP_CLK_DUMMY ),
>> +	CLK_MUX( IMX8QXP_SDHC2_SEL, "SDHC2_SEL", IMX8QXP_SDHC2_DIV,
>> IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
>> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
>> IMX8QXP_CLK_DUMMY ), +};
>>  
>> -	return 0;
>> -}
>> +struct imx8_clks_collect imx8qxp_clk_collect = {
>> +	{
>> +		{&imx8qxp_clks, ARRAY_SIZE(imx8qxp_clks)},
>> +		{&imx8qxp_fixed_clks,
>> ARRAY_SIZE(imx8qxp_fixed_clks)},
>> +		{&imx8qxp_gpr_clks, ARRAY_SIZE(imx8qxp_gpr_clks)},
>> +		{&imx8qxp_lpcg_clks, ARRAY_SIZE(imx8qxp_lpcg_clks)},
>> +		{&imx8qxp_mux_clks, ARRAY_SIZE(imx8qxp_mux_clks)},
>> +	},
>> +	FLAG_CLK_IMX8_IMX8QXP,
>> +};
> 
> 
> 
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
> 

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

* [U-Boot] [EXT] Re: [PATCH 3/5] clk: imx8: Update imx8 clock driver
  2019-07-10  7:14     ` [U-Boot] [EXT] " Ye Li
@ 2019-07-10  7:34       ` Lukasz Majewski
  2019-07-10  8:25         ` Ye Li
  0 siblings, 1 reply; 14+ messages in thread
From: Lukasz Majewski @ 2019-07-10  7:34 UTC (permalink / raw)
  To: u-boot

Hi Ye,

> Hi Lukasz,
> 
> > Hi Ye,
> >   
> >> Update imx8 clock driver to support LPCG and full clocks tree for
> >> some modules aligned with kernel.
> >>
> >> We classify the clock into serveral types: slice, fixed, lpcg, gpr
> >> and mux.  
> > 
> > Is this code in sync with Linux kernel? Does the imx8 (in Linux
> > kernel) use the Common Clock Framework?  
> This patch syncs the tree architecture with kernel but not the codes.
> imx8 kernel clock driver uses common clock framework.
> 
> >   
> >> Generally slice and fixed clocks are the sources. lpcg, gpr
> >> and mux are the downstream of those sources and are used for
> >> gating, muxing or dividing functions.
> >>
> >> This patch replaces the functions defined in imx8qm and imx8qxp
> >> with the clock tables of different clock types. clk-imx8 use
> >> unified functions to process these clock tables.  
> > 
> > 
> > I've posted the Common Clock Framework v5 to the mailing list
> > recently: https://patchwork.ozlabs.org/cover/1121348/
> > 
> > 
> > So maybe this code could benefit from those patches and use this
> > infrastructure ?
> >   
> I think so. We will look into the CCF in u-boot and migrate it later. 

Sorry, but I'm involved in the open source U-Boot developement for too
long to believe in such statements.

If the feature is not added from the outset, then it will not be
changed.

> But now we prefer upstream this update first. This one has been
> tested in downstream. And we have some driver patches going for
> upstream depending on it, while a new driver using CCF may need more
> time to get ready.
> 
> Best regards,
> Ye Li
> >>
> >> Note: since the clock depends on the power domain of its resource,
> >> must power on the resource firstly, then we can get the clock.
> >> Otherwise, we can't access lpcg. Thus, the clock dump only works
> >> for the slice clock.
> >>
> >> Signed-off-by: Ye Li <ye.li@nxp.com>
> >> ---
> >>  drivers/clk/imx/clk-imx8.c    | 304 +++++++++++++++++++++++++--
> >>  drivers/clk/imx/clk-imx8.h    |  83 +++++++-
> >>  drivers/clk/imx/clk-imx8qm.c  | 479
> >> ++++++++++++++++--------------------------
> >> drivers/clk/imx/clk-imx8qxp.c | 432
> >> +++++++++++++------------------------ 4 files changed, 689
> >> insertions(+), 609 deletions(-)
> >>
> >> diff --git a/drivers/clk/imx/clk-imx8.c
> >> b/drivers/clk/imx/clk-imx8.c index a755e26..afdb6ea 100644
> >> --- a/drivers/clk/imx/clk-imx8.c
> >> +++ b/drivers/clk/imx/clk-imx8.c
> >> @@ -12,32 +12,294 @@
> >>  #include <dt-bindings/clock/imx8qxp-clock.h>
> >>  #include <dt-bindings/soc/imx_rsrc.h>
> >>  #include <misc.h>
> >> +#include <asm/arch/lpcg.h>
> >>  
> >>  #include "clk-imx8.h"
> >>  
> >> -__weak ulong imx8_clk_get_rate(struct clk *clk)
> >> +struct imx8_clks_collect *soc_data[] = {
> >> +#ifdef CONFIG_IMX8QXP
> >> +	&imx8qxp_clk_collect,
> >> +#endif
> >> +#ifdef CONFIG_IMX8QM
> >> +	&imx8qm_clk_collect,
> >> +#endif
> >> +};
> >> +
> >> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id);
> >> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
> >> enable); +static ulong __imx8_clk_set_rate(struct udevice *dev,
> >> ulong id, unsigned long rate); +
> >> +static struct imx8_clks_collect * find_clks_collect(struct udevice
> >> *dev) +{
> >> +	ulong data = (ulong)dev_get_driver_data(dev);
> >> +	int i;
> >> +
> >> +	for (i = 0; i < ARRAY_SIZE(soc_data); i++) {
> >> +		if (soc_data[i]->match_flag == data)
> >> +			return soc_data[i];
> >> +	}
> >> +
> >> +	return NULL;
> >> +}
> >> +
> >> +static void * check_imx8_clk(struct udevice *dev, enum
> >> imx8_clk_type type, ulong id, u32 size_of_clk) +{
> >> +	u32 i, size;
> >> +	struct imx8_clks_collect *clks_col =
> >> find_clks_collect(dev);
> >> +	struct imx8_clk_header *hdr;
> >> +	ulong clks;
> >> +
> >> +	if (!clks_col || !(clks_col->clks[type].type_clks)) {
> >> +		printf("%s fails to get clks for type %d\n",
> >> +		       __func__, type);
> >> +		return NULL;
> >> +	}
> >> +
> >> +	clks = (ulong)(clks_col->clks[type].type_clks);
> >> +	size = clks_col->clks[type].num;
> >> +
> >> +	for (i = 0; i < size; i++) {
> >> +		hdr = (struct imx8_clk_header *)clks;
> >> +		if (id == hdr->id)
> >> +			return (void *)hdr;
> >> +
> >> +		clks += size_of_clk;
> >> +	}
> >> +
> >> +	return NULL;
> >> +}
> >> +
> >> +static ulong imx8_get_rate_lpcg(struct udevice *dev, struct
> >> imx8_lpcg_clks *lpcg_clk) +{
> >> +	if (lpcg_clk->parent_id != 0) {
> >> +		if (lpcg_is_clock_on(lpcg_clk->lpcg,
> >> lpcg_clk->bit_idx >> 2)) {
> >> +			return __imx8_clk_get_rate(dev,
> >> lpcg_clk->parent_id);
> >> +		} else {
> >> +			return 0;
> >> +		}
> >> +	} else {
> >> +		return -ENOSYS;
> >> +	}
> >> +}
> >> +
> >> +static ulong imx8_get_rate_slice(struct udevice *dev, struct
> >> imx8_clks *slice_clk) +{
> >> +	int ret;
> >> +	u32 rate;
> >> +
> >> +	ret = sc_pm_get_clock_rate(-1, slice_clk->rsrc,
> >> slice_clk->pm_clk,
> >> +				   (sc_pm_clock_rate_t *)&rate);
> >> +	if (ret) {
> >> +		printf("%s err %d\n", __func__, ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	return rate;
> >> +}
> >> +
> >> +static ulong imx8_get_rate_fixed(struct udevice *dev, struct
> >> imx8_fixed_clks *fixed_clk) +{
> >> +	return fixed_clk->rate;
> >> +}
> >> +
> >> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id)
> >> +{
> >> +	void* clkdata;
> >> +
> >> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
> >> sizeof(struct imx8_lpcg_clks));
> >> +	if (clkdata) {
> >> +		return imx8_get_rate_lpcg(dev, (struct
> >> imx8_lpcg_clks *)clkdata);
> >> +	}
> >> +
> >> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
> >> sizeof(struct imx8_clks));
> >> +	if (clkdata) {
> >> +		return imx8_get_rate_slice(dev, (struct imx8_clks
> >> *)clkdata);
> >> +	}
> >> +
> >> +	clkdata = check_imx8_clk(dev, IMX8_CLK_FIXED, id,
> >> sizeof(struct imx8_fixed_clks));
> >> +	if (clkdata) {
> >> +		return imx8_get_rate_fixed(dev, (struct
> >> imx8_fixed_clks *)clkdata);
> >> +	}
> >> +
> >> +	return -ENOSYS;
> >> +}
> >> +
> >> +static ulong imx8_clk_get_rate(struct clk *clk)
> >> +{
> >> +	return __imx8_clk_get_rate(clk->dev, clk->id);
> >> +}
> >> +
> >> +static ulong imx8_set_rate_lpcg(struct udevice *dev, struct
> >> imx8_lpcg_clks *lpcg_clk, unsigned long rate) +{
> >> +	if (lpcg_clk->parent_id != 0) {
> >> +		return __imx8_clk_set_rate(dev,
> >> lpcg_clk->parent_id, rate);
> >> +	} else {
> >> +		return -ENOSYS;
> >> +	}
> >> +}
> >> +
> >> +static ulong imx8_set_rate_slice(struct udevice *dev, struct
> >> imx8_clks *slice_clk, unsigned long rate) +{
> >> +	int ret;
> >> +	u32 new_rate = rate;
> >> +
> >> +	ret = sc_pm_set_clock_rate(-1, slice_clk->rsrc,
> >> slice_clk->pm_clk, &new_rate);
> >> +	if (ret) {
> >> +		printf("%s err %d\n", __func__, ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	return new_rate;
> >> +}
> >> +
> >> +static ulong imx8_set_rate_gpr(struct udevice *dev, struct
> >> imx8_gpr_clks *gpr_clk, unsigned long rate) {
> >> +	ulong parent_rate;
> >> +	u32 val;
> >> +	int ret;
> >> +
> >> +	if (gpr_clk->parent_id == 0)
> >> +		return -ENOSYS;
> >> +
> >> +	parent_rate = __imx8_clk_get_rate(dev,
> >> gpr_clk->parent_id);
> >> +	if (parent_rate > 0) {
> >> +		val = (rate < parent_rate) ? 1 : 0;
> >> +
> >> +		ret = sc_misc_set_control(-1, gpr_clk->rsrc,
> >> +			gpr_clk->gpr_id, val);
> >> +		if (ret) {
> >> +			printf("%s err %d\n", __func__, ret);
> >> +			return ret;
> >> +		}
> >> +
> >> +		return rate;
> >> +	}
> >> +
> >> +	return -ENOSYS;
> >> +}
> >> +
> >> +static ulong __imx8_clk_set_rate(struct udevice *dev, ulong id,
> >> unsigned long rate) +{
> >> +	void* clkdata;
> >> +
> >> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
> >> sizeof(struct imx8_clks));
> >> +	if (clkdata) {
> >> +		return imx8_set_rate_slice(dev, (struct imx8_clks
> >> *)clkdata, rate);
> >> +	}
> >> +
> >> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
> >> sizeof(struct imx8_lpcg_clks));
> >> +	if (clkdata) {
> >> +		return imx8_set_rate_lpcg(dev, (struct
> >> imx8_lpcg_clks *)clkdata, rate);
> >> +	}
> >> +
> >> +	clkdata = check_imx8_clk(dev, IMX8_CLK_GPR, id,
> >> sizeof(struct imx8_gpr_clks));
> >> +	if (clkdata) {
> >> +		return imx8_set_rate_gpr(dev, (struct
> >> imx8_gpr_clks *)clkdata, rate);
> >> +	}
> >> +
> >> +	return -ENOSYS;
> >> +}
> >> +
> >> +static ulong imx8_clk_set_rate(struct clk *clk, unsigned long
> >> rate) +{
> >> +	return __imx8_clk_set_rate(clk->dev, clk->id, rate);
> >> +
> >> +}
> >> +
> >> +static int imx8_enable_slice(struct udevice *dev, struct imx8_clks
> >> *slice_clk, bool enable) +{
> >> +	int ret;
> >> +
> >> +	ret = sc_pm_clock_enable(-1, slice_clk->rsrc,
> >> slice_clk->pm_clk, enable, 0);
> >> +	if (ret) {
> >> +		printf("%s err %d\n", __func__, ret);
> >> +		return ret;
> >> +	}
> >> +
> >>  	return 0;
> >>  }
> >>  
> >> -__weak ulong imx8_clk_set_rate(struct clk *clk, unsigned long
> >> rate) +static int imx8_enable_lpcg(struct udevice *dev, struct
> >> imx8_lpcg_clks *lpcg_clk, bool enable) {
> >> +	if (enable) {
> >> +		if (lpcg_clk->parent_id != 0) {
> >> +			__imx8_clk_enable(dev,
> >> lpcg_clk->parent_id, enable);
> >> +		}
> >> +
> >> +		lpcg_clock_on(lpcg_clk->lpcg, lpcg_clk->bit_idx >>
> >> 2);
> >> +	} else {
> >> +		lpcg_clock_off(lpcg_clk->lpcg, lpcg_clk->bit_idx
> >> >> 2); +
> >> +		if (lpcg_clk->parent_id != 0) {
> >> +			__imx8_clk_enable(dev,
> >> lpcg_clk->parent_id, enable);
> >> +		}
> >> +	}
> >> +
> >>  	return 0;
> >>  }
> >>  
> >> -__weak int __imx8_clk_enable(struct clk *clk, bool enable)
> >> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
> >> enable) {
> >> -	return -ENOTSUPP;
> >> +	void* clkdata;
> >> +
> >> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
> >> sizeof(struct imx8_lpcg_clks));
> >> +	if (clkdata) {
> >> +		return imx8_enable_lpcg(dev, (struct
> >> imx8_lpcg_clks *)clkdata, enable);
> >> +	}
> >> +
> >> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
> >> sizeof(struct imx8_clks));
> >> +	if (clkdata) {
> >> +		return imx8_enable_slice(dev, (struct imx8_clks
> >> *)clkdata, enable);
> >> +	}
> >> +
> >> +	return -ENOSYS;
> >>  }
> >>  
> >>  static int imx8_clk_disable(struct clk *clk)
> >>  {
> >> -	return __imx8_clk_enable(clk, 0);
> >> +	return __imx8_clk_enable(clk->dev, clk->id, 0);
> >>  }
> >>  
> >>  static int imx8_clk_enable(struct clk *clk)
> >>  {
> >> -	return __imx8_clk_enable(clk, 1);
> >> +	return __imx8_clk_enable(clk->dev, clk->id, 1);
> >> +}
> >> +
> >> +static int imx8_set_parent_mux(struct udevice *dev, struct
> >> imx8_mux_clks *mux_clk, ulong pid) +{
> >> +	u32 i;
> >> +	int ret;
> >> +	struct imx8_clks *slice_clkdata;
> >> +
> >> +	slice_clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE,
> >> mux_clk->slice_clk_id, sizeof(struct imx8_clks));
> >> +	if (!slice_clkdata) {
> >> +		printf("Error: fail to find slice clk %lu for this
> >> mux %lu\n", mux_clk->slice_clk_id, mux_clk->hdr.id);
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	for (i = 0; i< CLK_IMX8_MAX_MUX_SEL; i++) {
> >> +		if (pid == mux_clk->parent_clks[i]) {
> >> +			ret = sc_pm_set_clock_parent(-1,
> >> slice_clkdata->rsrc,  slice_clkdata->pm_clk, i);
> >> +			if (ret)
> >> +				printf("Error: fail to set clock
> >> parent rsrc %d, pm_clk %d, parent clk %d\n",
> >> +					slice_clkdata->rsrc,
> >> slice_clkdata->pm_clk, i);
> >> +			return ret;
> >> +		}
> >> +	}
> >> +
> >> +	return -ENOSYS;
> >> +}
> >> +
> >> +static int imx8_clk_set_parent(struct clk *clk, struct clk
> >> *parent) +{
> >> +	void* clkdata;
> >> +
> >> +	clkdata = check_imx8_clk(clk->dev, IMX8_CLK_MUX, clk->id,
> >> sizeof(struct imx8_mux_clks));
> >> +	if (clkdata) {
> >> +		return imx8_set_parent_mux(clk->dev, (struct
> >> imx8_mux_clks *)clkdata, parent->id);
> >> +	}
> >> +
> >> +	return -ENOSYS;
> >>  }
> >>  
> >>  #if CONFIG_IS_ENABLED(CMD_CLK)
> >> @@ -47,6 +309,9 @@ int soc_clk_dump(void)
> >>  	struct clk clk;
> >>  	unsigned long rate;
> >>  	int i, ret;
> >> +	u32 size;
> >> +	struct imx8_clks *clks;
> >> +	struct imx8_clks_collect *clks_col;
> >>  
> >>  	ret = uclass_get_device_by_driver(UCLASS_CLK,
> >>  					  DM_GET_DRIVER(imx8_clk),
> >> &dev); @@ -55,8 +320,19 @@ int soc_clk_dump(void)
> >>  
> >>  	printf("Clk\t\tHz\n");
> >>  
> >> -	for (i = 0; i < num_clks; i++) {
> >> -		clk.id = imx8_clk_names[i].id;
> >> +	clks_col = find_clks_collect(dev);
> >> +
> >> +	if (!clks_col
> >> || !(clks_col->clks[IMX8_CLK_SLICE].type_clks)) {
> >> +		printf("%s fails to get clks for type %d\n",
> >> +		       __func__, IMX8_CLK_SLICE);
> >> +		return -ENODEV;
> >> +	}
> >> +
> >> +	clks = (struct imx8_clks
> >> *)(clks_col->clks[IMX8_CLK_SLICE].type_clks);
> >> +	size = clks_col->clks[IMX8_CLK_SLICE].num;
> >> +
> >> +	for (i = 0; i < size; i++) {
> >> +		clk.id = clks[i].hdr.id;
> >>  		ret = clk_request(dev, &clk);
> >>  		if (ret < 0) {
> >>  			debug("%s clk_request() failed: %d\n",
> >> __func__, ret); @@ -70,21 +346,22 @@ int soc_clk_dump(void)
> >>  
> >>  		if (ret == -ENOTSUPP) {
> >>  			printf("clk ID %lu not supported yet\n",
> >> -			       imx8_clk_names[i].id);
> >> +			       clks[i].hdr.id);
> >>  			continue;
> >>  		}
> >>  		if (ret < 0) {
> >>  			printf("%s %lu: get_rate err: %d\n",
> >> -			       __func__, imx8_clk_names[i].id,
> >> ret);
> >> +			       __func__, clks[i].hdr.id, ret);
> >>  			continue;
> >>  		}
> >>  
> >>  		printf("%s(%3lu):\t%lu\n",
> >> -		       imx8_clk_names[i].name,
> >> imx8_clk_names[i].id, rate);
> >> +		       clks[i].hdr.name, clks[i].hdr.id, rate);
> >>  	}
> >>  
> >>  	return 0;
> >>  }
> >> +
> >>  #endif
> >>  
> >>  static struct clk_ops imx8_clk_ops = {
> >> @@ -92,6 +369,7 @@ static struct clk_ops imx8_clk_ops = {
> >>  	.get_rate = imx8_clk_get_rate,
> >>  	.enable = imx8_clk_enable,
> >>  	.disable = imx8_clk_disable,
> >> +	.set_parent = imx8_clk_set_parent,
> >>  };
> >>  
> >>  static int imx8_clk_probe(struct udevice *dev)
> >> @@ -100,8 +378,8 @@ static int imx8_clk_probe(struct udevice *dev)
> >>  }
> >>  
> >>  static const struct udevice_id imx8_clk_ids[] = {
> >> -	{ .compatible = "fsl,imx8qxp-clk" },
> >> -	{ .compatible = "fsl,imx8qm-clk" },
> >> +	{ .compatible = "fsl,imx8qxp-clk", .data =
> >> FLAG_CLK_IMX8_IMX8QXP, },
> >> +	{ .compatible = "fsl,imx8qm-clk", .data =
> >> FLAG_CLK_IMX8_IMX8QM, }, { },
> >>  };
> >>  
> >> diff --git a/drivers/clk/imx/clk-imx8.h
> >> b/drivers/clk/imx/clk-imx8.h index 68ad675..c0566f8 100644
> >> --- a/drivers/clk/imx/clk-imx8.h
> >> +++ b/drivers/clk/imx/clk-imx8.h
> >> @@ -4,16 +4,87 @@
> >>   * Peng Fan <peng.fan@nxp.com>
> >>   */
> >>  
> >> -struct imx8_clks {
> >> +#define CLK_IMX8_MAX_MUX_SEL 5
> >> +
> >> +#define FLAG_CLK_IMX8_IMX8QM	BIT(0)
> >> +#define FLAG_CLK_IMX8_IMX8QXP	BIT(1)
> >> +
> >> +struct imx8_clk_header {
> >>  	ulong id;
> >> +#if CONFIG_IS_ENABLED(CMD_CLK)
> >>  	const char *name;
> >> +#endif
> >> +};
> >> +
> >> +struct imx8_clks {
> >> +	struct imx8_clk_header hdr;
> >> +	u16 rsrc;
> >> +	sc_pm_clk_t pm_clk;
> >> +};
> >> +
> >> +struct imx8_fixed_clks {
> >> +	struct imx8_clk_header hdr;
> >> +	ulong rate;
> >> +};
> >> +
> >> +struct imx8_gpr_clks {
> >> +	struct imx8_clk_header hdr;
> >> +	u16 rsrc;
> >> +	sc_ctrl_t gpr_id;
> >> +	ulong parent_id;
> >> +};
> >> +
> >> +struct imx8_lpcg_clks {
> >> +	struct imx8_clk_header hdr;
> >> +	u8 bit_idx;
> >> +	u32 lpcg;
> >> +	ulong parent_id;
> >> +};
> >> +
> >> +struct imx8_mux_clks {
> >> +	struct imx8_clk_header hdr;
> >> +	ulong slice_clk_id;
> >> +	ulong parent_clks[CLK_IMX8_MAX_MUX_SEL];
> >> +};
> >> +
> >> +enum imx8_clk_type {
> >> +	IMX8_CLK_SLICE 		= 0,
> >> +	IMX8_CLK_FIXED 	= 1,
> >> +	IMX8_CLK_GPR 		= 2,
> >> +	IMX8_CLK_LPCG 		= 3,
> >> +	IMX8_CLK_MUX 		= 4,
> >> +	IMX8_CLK_END		= 5,
> >> +};
> >> +
> >> +struct imx8_clk_pair {
> >> +	void *type_clks;
> >> +	u32 num;
> >> +};
> >> +
> >> +struct imx8_clks_collect {
> >> +	struct imx8_clk_pair clks[IMX8_CLK_END];
> >> +	ulong match_flag;
> >>  };
> >>  
> >>  #if CONFIG_IS_ENABLED(CMD_CLK)
> >> -extern struct imx8_clks imx8_clk_names[];
> >> -extern int num_clks;
> >> +#define CLK_3(ID, NAME, MEM2) \
> >> +	{ { ID, NAME, }, MEM2, }
> >> +#define CLK_4(ID, NAME, MEM2, MEM3) \
> >> +	{ { ID, NAME, }, MEM2, MEM3, }
> >> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
> >> +	{ { ID, NAME, }, MEM2, MEM3, MEM4, }
> >> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
> >> +	{ { ID, NAME, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
> >> +#else
> >> +#define CLK_3(ID, NAME, MEM2) \
> >> +	{ { ID, }, MEM2, }
> >> +#define CLK_4(ID, NAME, MEM2, MEM3) \
> >> +	{ { ID, }, MEM2, MEM3, }
> >> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
> >> +	{ { ID, }, MEM2, MEM3, MEM4, }
> >> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
> >> +	{ { ID, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
> >>  #endif
> >>  
> >> -ulong imx8_clk_get_rate(struct clk *clk);
> >> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate);
> >> -int __imx8_clk_enable(struct clk *clk, bool enable);
> >> +extern struct imx8_clks_collect imx8qxp_clk_collect;
> >> +extern struct imx8_clks_collect imx8qm_clk_collect;
> >> diff --git a/drivers/clk/imx/clk-imx8qm.c
> >> b/drivers/clk/imx/clk-imx8qm.c index a6b09d2..f4ee007 100644
> >> --- a/drivers/clk/imx/clk-imx8qm.c
> >> +++ b/drivers/clk/imx/clk-imx8qm.c
> >> @@ -12,314 +12,189 @@
> >>  #include <dt-bindings/clock/imx8qm-clock.h>
> >>  #include <dt-bindings/soc/imx_rsrc.h>
> >>  #include <misc.h>
> >> +#include <asm/arch/lpcg.h>
> >>  
> >>  #include "clk-imx8.h"
> >>  
> >> -#if CONFIG_IS_ENABLED(CMD_CLK)
> >> -struct imx8_clks imx8_clk_names[] = {
> >> -	{ IMX8QM_A53_DIV, "A53_DIV" },
> >> -	{ IMX8QM_UART0_CLK, "UART0" },
> >> -	{ IMX8QM_UART1_CLK, "UART1" },
> >> -	{ IMX8QM_UART2_CLK, "UART2" },
> >> -	{ IMX8QM_UART3_CLK, "UART3" },
> >> -	{ IMX8QM_SDHC0_CLK, "SDHC0" },
> >> -	{ IMX8QM_SDHC1_CLK, "SDHC1" },
> >> -	{ IMX8QM_SDHC2_CLK, "SDHC2" },
> >> -	{ IMX8QM_ENET0_AHB_CLK, "ENET0_AHB" },
> >> -	{ IMX8QM_ENET0_IPG_CLK, "ENET0_IPG" },
> >> -	{ IMX8QM_ENET0_REF_DIV, "ENET0_REF" },
> >> -	{ IMX8QM_ENET0_PTP_CLK, "ENET0_PTP" },
> >> -	{ IMX8QM_ENET1_AHB_CLK, "ENET1_AHB" },
> >> -	{ IMX8QM_ENET1_IPG_CLK, "ENET1_IPG" },
> >> -	{ IMX8QM_ENET1_REF_DIV, "ENET1_REF" },
> >> -	{ IMX8QM_ENET1_PTP_CLK, "ENET1_PTP" },
> >> +static struct imx8_clks imx8qm_clks[] = {
> >> +	CLK_4( IMX8QM_A53_DIV, "A53_DIV", SC_R_A53, SC_PM_CLK_CPU
> >> ),
> >> +	CLK_4( IMX8QM_A72_DIV, "A72_DIV", SC_R_A72, SC_PM_CLK_CPU
> >> ),
> >> +	CLK_4( IMX8QM_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_LVDS0_I2C0_DIV, "LVDS0 I2C0 DIV",
> >> SC_R_LVDS_0_I2C_0, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_LVDS0_I2C1_DIV, "LVDS0 I2C1 DIV",
> >> SC_R_LVDS_0_I2C_1, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_LVDS1_I2C0_DIV, "LVDS1 I2C0 DIV",
> >> SC_R_LVDS_1_I2C_0, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_LVDS1_I2C1_DIV, "LVDS1 I2C1 DIV",
> >> SC_R_LVDS_1_I2C_1, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
> >> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QM_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
> >> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QM_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
> >> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QM_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
> >> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QM_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
> >> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_CSI1_I2C0_DIV, "CSI1 I2C0_DIV",
> >> SC_R_CSI_1_I2C_0, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_HDMI_I2C0_DIV, "HDMI I2C0_DIV",
> >> SC_R_HDMI_I2C_0, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QM_HDMI_IPG_CLK, "HDMI IPG_CLK", SC_R_HDMI,
> >> SC_PM_CLK_MISC ),
> >> +	CLK_4( IMX8QM_HDMI_RX_I2C0_DIV, "HDMI RX I2C_DIV",
> >> SC_R_HDMI_RX_I2C_0, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QM_UART0_DIV, "UART0_DIV", SC_R_UART_0,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_UART1_DIV, "UART1_DIV", SC_R_UART_1,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_UART2_DIV, "UART2_DIV", SC_R_UART_2,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_UART3_DIV, "UART3_DIV", SC_R_UART_3,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_ENET0_ROOT_DIV, "ENET0_ROOT_DIV",
> >> SC_R_ENET_0, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
> >> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
> >> +	CLK_4( IMX8QM_ENET1_ROOT_DIV, "ENET1_ROOT_DIV",
> >> SC_R_ENET_1, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
> >> SC_R_ENET_1, SC_PM_CLK_MISC0 ), +
> >> +	CLK_4( IMX8QM_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QM_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
> >> SC_PM_CLK_MST_BUS ),
> >> +	CLK_4( IMX8QM_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
> >> SC_PM_CLK_MISC ), +
> >> +	CLK_4( IMX8QM_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
> >> SC_PM_CLK_PER ), +
> >> +	CLK_4( IMX8QM_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND,
> >> SC_PM_CLK_MST_BUS ),
> >> +	CLK_4( IMX8QM_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
> >> SC_PM_CLK_PER ), };
> >>  
> >> -int num_clks = ARRAY_SIZE(imx8_clk_names);
> >> -#endif
> >> -
> >> -ulong imx8_clk_get_rate(struct clk *clk)
> >> -{
> >> -	sc_pm_clk_t pm_clk;
> >> -	ulong rate;
> >> -	u16 resource;
> >> -	int ret;
> >> -
> >> -	debug("%s(#%lu)\n", __func__, clk->id);
> >> -
> >> -	switch (clk->id) {
> >> -	case IMX8QM_A53_DIV:
> >> -		resource = SC_R_A53;
> >> -		pm_clk = SC_PM_CLK_CPU;
> >> -		break;
> >> -	case IMX8QM_I2C0_CLK:
> >> -		resource = SC_R_I2C_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_I2C1_CLK:
> >> -		resource = SC_R_I2C_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_I2C2_CLK:
> >> -		resource = SC_R_I2C_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_I2C3_CLK:
> >> -		resource = SC_R_I2C_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_SDHC0_IPG_CLK:
> >> -	case IMX8QM_SDHC0_CLK:
> >> -	case IMX8QM_SDHC0_DIV:
> >> -		resource = SC_R_SDHC_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_SDHC1_IPG_CLK:
> >> -	case IMX8QM_SDHC1_CLK:
> >> -	case IMX8QM_SDHC1_DIV:
> >> -		resource = SC_R_SDHC_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_SDHC2_IPG_CLK:
> >> -	case IMX8QM_SDHC2_CLK:
> >> -	case IMX8QM_SDHC2_DIV:
> >> -		resource = SC_R_SDHC_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART0_IPG_CLK:
> >> -	case IMX8QM_UART0_CLK:
> >> -		resource = SC_R_UART_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART1_CLK:
> >> -		resource = SC_R_UART_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART2_CLK:
> >> -		resource = SC_R_UART_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART3_CLK:
> >> -		resource = SC_R_UART_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_ENET0_IPG_CLK:
> >> -	case IMX8QM_ENET0_AHB_CLK:
> >> -	case IMX8QM_ENET0_REF_DIV:
> >> -	case IMX8QM_ENET0_PTP_CLK:
> >> -		resource = SC_R_ENET_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_ENET1_IPG_CLK:
> >> -	case IMX8QM_ENET1_AHB_CLK:
> >> -	case IMX8QM_ENET1_REF_DIV:
> >> -	case IMX8QM_ENET1_PTP_CLK:
> >> -		resource = SC_R_ENET_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	default:
> >> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
> >> -		    clk->id >= IMX8QM_CLK_END) {
> >> -			printf("%s(Invalid clk ID #%lu)\n",
> >> -			       __func__, clk->id);
> >> -			return -EINVAL;
> >> -		}
> >> -		return -ENOTSUPP;
> >> -	};
> >> -
> >> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
> >> -				   (sc_pm_clock_rate_t *)&rate);
> >> -	if (ret) {
> >> -		printf("%s err %d\n", __func__, ret);
> >> -		return ret;
> >> -	}
> >> -
> >> -	return rate;
> >> -}
> >> -
> >> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
> >> -{
> >> -	sc_pm_clk_t pm_clk;
> >> -	u32 new_rate = rate;
> >> -	u16 resource;
> >> -	int ret;
> >> -
> >> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
> >> -
> >> -	switch (clk->id) {
> >> -	case IMX8QM_I2C0_CLK:
> >> -		resource = SC_R_I2C_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_I2C1_CLK:
> >> -		resource = SC_R_I2C_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_I2C2_CLK:
> >> -		resource = SC_R_I2C_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_I2C3_CLK:
> >> -		resource = SC_R_I2C_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART0_CLK:
> >> -		resource = SC_R_UART_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART1_CLK:
> >> -		resource = SC_R_UART_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART2_CLK:
> >> -		resource = SC_R_UART_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART3_CLK:
> >> -		resource = SC_R_UART_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_SDHC0_IPG_CLK:
> >> -	case IMX8QM_SDHC0_CLK:
> >> -	case IMX8QM_SDHC0_DIV:
> >> -		resource = SC_R_SDHC_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_SDHC1_IPG_CLK:
> >> -	case IMX8QM_SDHC1_CLK:
> >> -	case IMX8QM_SDHC1_DIV:
> >> -		resource = SC_R_SDHC_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_SDHC2_IPG_CLK:
> >> -	case IMX8QM_SDHC2_CLK:
> >> -	case IMX8QM_SDHC2_DIV:
> >> -		resource = SC_R_SDHC_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_ENET0_IPG_CLK:
> >> -	case IMX8QM_ENET0_AHB_CLK:
> >> -	case IMX8QM_ENET0_REF_DIV:
> >> -	case IMX8QM_ENET0_PTP_CLK:
> >> -	case IMX8QM_ENET0_ROOT_DIV:
> >> -		resource = SC_R_ENET_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_ENET1_IPG_CLK:
> >> -	case IMX8QM_ENET1_AHB_CLK:
> >> -	case IMX8QM_ENET1_REF_DIV:
> >> -	case IMX8QM_ENET1_PTP_CLK:
> >> -	case IMX8QM_ENET1_ROOT_DIV:
> >> -		resource = SC_R_ENET_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	default:
> >> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
> >> -		    clk->id >= IMX8QM_CLK_END) {
> >> -			printf("%s(Invalid clk ID #%lu)\n",
> >> -			       __func__, clk->id);
> >> -			return -EINVAL;
> >> -		}
> >> -		return -ENOTSUPP;
> >> -	};
> >> -
> >> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk,
> >> &new_rate);
> >> -	if (ret) {
> >> -		printf("%s err %d\n", __func__, ret);
> >> -		return ret;
> >> -	}
> >> -
> >> -	return new_rate;
> >> -}
> >> -
> >> -int __imx8_clk_enable(struct clk *clk, bool enable)
> >> -{
> >> -	sc_pm_clk_t pm_clk;
> >> -	u16 resource;
> >> -	int ret;
> >> +static struct imx8_fixed_clks imx8qm_fixed_clks[] = {
> >> +	CLK_3( IMX8QM_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", SC_83MHZ
> >> ),
> >> +	CLK_3( IMX8QM_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK",
> >> SC_166MHZ ),
> >> +	CLK_3( IMX8QM_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK",
> >> SC_333MHZ ),
> >> +	CLK_3( IMX8QM_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ
> >> ),
> >> +	CLK_3( IMX8QM_IPG_MIPI_CSI_CLK_ROOT, "IPG_MIPI_CLK",
> >> SC_120MHZ ),
> >> +	CLK_3( IMX8QM_LVDS_IPG_CLK, "IPG_LVDS_CLK", SC_24MHZ ),
> >> +	CLK_3( IMX8QM_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
> >> +	CLK_3( IMX8QM_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
> >> +	CLK_3( IMX8QM_MIPI0_CLK_ROOT, "MIPI0_CLK", SC_120MHZ ),
> >> +	CLK_3( IMX8QM_MIPI1_CLK_ROOT, "MIPI1_CLK", SC_120MHZ ),
> >> +	CLK_3( IMX8QM_HDMI_RX_IPG_CLK, "HDMI_RX_IPG_CLK",
> >> SC_200MHZ ), +};
> >>  
> >> -	debug("%s(#%lu)\n", __func__, clk->id);
> >> +static struct imx8_gpr_clks imx8qm_gpr_clks[] = {
> >> +	CLK_5( IMX8QM_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0,
> >> SC_C_CLKDIV, IMX8QM_ENET0_ROOT_DIV ),
> >> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL,
> >> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
> >> +	CLK_4( IMX8QM_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
> >> SC_R_ENET_0, SC_C_TXCLK ),
> >> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK,
> >> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
> >> +	CLK_4( IMX8QM_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
> >> SC_R_ENET_0, SC_C_DISABLE_50 ), +
> >> +	CLK_5( IMX8QM_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1,
> >> SC_C_CLKDIV, IMX8QM_ENET1_ROOT_DIV ),
> >> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL,
> >> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
> >> +	CLK_4( IMX8QM_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
> >> SC_R_ENET_1, SC_C_TXCLK ),
> >> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK,
> >> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
> >> +	CLK_4( IMX8QM_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
> >> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
> >>  
> >> -	switch (clk->id) {
> >> -	case IMX8QM_I2C0_CLK:
> >> -		resource = SC_R_I2C_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_I2C1_CLK:
> >> -		resource = SC_R_I2C_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_I2C2_CLK:
> >> -		resource = SC_R_I2C_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_I2C3_CLK:
> >> -		resource = SC_R_I2C_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART0_CLK:
> >> -		resource = SC_R_UART_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART1_CLK:
> >> -		resource = SC_R_UART_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART2_CLK:
> >> -		resource = SC_R_UART_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_UART3_CLK:
> >> -		resource = SC_R_UART_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_SDHC0_IPG_CLK:
> >> -	case IMX8QM_SDHC0_CLK:
> >> -	case IMX8QM_SDHC0_DIV:
> >> -		resource = SC_R_SDHC_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_SDHC1_IPG_CLK:
> >> -	case IMX8QM_SDHC1_CLK:
> >> -	case IMX8QM_SDHC1_DIV:
> >> -		resource = SC_R_SDHC_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_SDHC2_IPG_CLK:
> >> -	case IMX8QM_SDHC2_CLK:
> >> -	case IMX8QM_SDHC2_DIV:
> >> -		resource = SC_R_SDHC_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_ENET0_IPG_CLK:
> >> -	case IMX8QM_ENET0_AHB_CLK:
> >> -	case IMX8QM_ENET0_REF_DIV:
> >> -	case IMX8QM_ENET0_PTP_CLK:
> >> -		resource = SC_R_ENET_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QM_ENET1_IPG_CLK:
> >> -	case IMX8QM_ENET1_AHB_CLK:
> >> -	case IMX8QM_ENET1_REF_DIV:
> >> -	case IMX8QM_ENET1_PTP_CLK:
> >> -		resource = SC_R_ENET_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	default:
> >> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
> >> -		    clk->id >= IMX8QM_CLK_END) {
> >> -			printf("%s(Invalid clk ID #%lu)\n",
> >> -			       __func__, clk->id);
> >> -			return -EINVAL;
> >> -		}
> >> -		return -ENOTSUPP;
> >> -	}
> >> +static struct imx8_lpcg_clks imx8qm_lpcg_clks[] = {
> >> +	CLK_5( IMX8QM_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
> >> IMX8QM_I2C0_DIV ),
> >> +	CLK_5( IMX8QM_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG,
> >> IMX8QM_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
> >> IMX8QM_I2C1_DIV ),
> >> +	CLK_5( IMX8QM_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG,
> >> IMX8QM_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
> >> IMX8QM_I2C2_DIV ),
> >> +	CLK_5( IMX8QM_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG,
> >> IMX8QM_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
> >> IMX8QM_I2C3_DIV ),
> >> +	CLK_5( IMX8QM_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG,
> >> IMX8QM_IPG_DMA_CLK_ROOT ), +
> >> +	CLK_5( IMX8QM_LVDS0_I2C0_CLK, "LVDS0_I2C0_CLK", 0,
> >> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS0_I2C0_DIV ),
> >> +	CLK_5( IMX8QM_LVDS0_I2C0_IPG_CLK, "LVDS0_I2C0_IPG", 16,
> >> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
> >> +	CLK_5( IMX8QM_LVDS0_I2C1_CLK, "LVDS0_I2C1_CLK", 0,
> >> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS0_I2C1_DIV ),
> >> +	CLK_5( IMX8QM_LVDS0_I2C1_IPG_CLK, "LVDS0_I2C1_IPG", 16,
> >> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ),
> >> +	CLK_5( IMX8QM_LVDS1_I2C0_CLK, "LVDS1_I2C0_CLK", 0,
> >> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS1_I2C0_DIV ),
> >> +	CLK_5( IMX8QM_LVDS1_I2C0_IPG_CLK, "LVDS1_I2C0_IPG", 16,
> >> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
> >> +	CLK_5( IMX8QM_LVDS1_I2C1_CLK, "LVDS1_I2C1_CLK", 0,
> >> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS1_I2C1_DIV ),
> >> +	CLK_5( IMX8QM_LVDS1_I2C1_IPG_CLK, "LVDS1_I2C1_IPG", 16,
> >> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ), +
> >> +	CLK_5( IMX8QM_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
> >> MIPI_DSI_0_LPCG + 0x1c, IMX8QM_MIPI0_I2C0_DIV ),
> >> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 0,
> >> MIPI_DSI_0_LPCG + 0x14,  IMX8QM_MIPI0_I2C0_IPG_S_CLK),
> >> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_S_CLK, "MIPI0_I2C0_IPG_S", 0,
> >> MIPI_DSI_0_LPCG + 0x18, IMX8QM_MIPI0_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
> >> MIPI_DSI_0_LPCG + 0x2c, IMX8QM_MIPI0_I2C1_DIV ),
> >> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 0,
> >> MIPI_DSI_0_LPCG + 0x24,  IMX8QM_MIPI0_I2C1_IPG_S_CLK),
> >> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_S_CLK, "MIPI0_I2C1_IPG_S", 0,
> >> MIPI_DSI_0_LPCG + 0x28, IMX8QM_MIPI0_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
> >> MIPI_DSI_1_LPCG + 0x1c, IMX8QM_MIPI1_I2C0_DIV ),
> >> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 0,
> >> MIPI_DSI_1_LPCG + 0x14, IMX8QM_MIPI1_I2C0_IPG_S_CLK),
> >> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_S_CLK, "MIPI1_I2C0_IPG_S", 0,
> >> MIPI_DSI_1_LPCG + 0x18, IMX8QM_MIPI1_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
> >> MIPI_DSI_1_LPCG + 0x2c, IMX8QM_MIPI1_I2C1_DIV ),
> >> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 0,
> >> MIPI_DSI_1_LPCG + 0x24, IMX8QM_MIPI1_I2C1_IPG_S_CLK),
> >> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_S_CLK, "MIPI1_I2C1_IPG_S", 0,
> >> MIPI_DSI_1_LPCG + 0x28, IMX8QM_MIPI1_CLK_ROOT ), +
> >> +	CLK_5( IMX8QM_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
> >> MIPI_CSI_0_LPCG + 0x14, IMX8QM_CSI0_I2C0_DIV ),
> >> +	CLK_5( IMX8QM_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
> >> MIPI_CSI_0_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_CSI1_I2C0_CLK, "CSI1_I2C0_CLK", 0,
> >> MIPI_CSI_1_LPCG + 0x14, IMX8QM_CSI1_I2C0_DIV ),
> >> +	CLK_5( IMX8QM_CSI1_I2C0_IPG_CLK, "CSI1_I2C0_IPG", 16,
> >> MIPI_CSI_1_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_HDMI_I2C0_CLK, "HDMI_I2C0_CLK", 0,
> >> DI_HDMI_LPCG, IMX8QM_HDMI_I2C0_DIV ),
> >> +	CLK_5( IMX8QM_HDMI_I2C_IPG_CLK, "HDMI_I2C0_IPG", 16,
> >> DI_HDMI_LPCG, IMX8QM_HDMI_IPG_CLK ),
> >> +	CLK_5( IMX8QM_HDMI_RX_I2C_DIV_CLK, "HDMI RX_I2C_DIV_CLK",
> >> 0, MIPI_DSI_0_LPCG + 0x14, IMX8QM_MIPI0_I2C0_DIV ),
> >> +	CLK_5( IMX8QM_HDMI_RX_I2C0_CLK, "HDMI RX_I2C_CLK", 0,
> >> MIPI_DSI_0_LPCG + 0x10, IMX8QM_HDMI_RX_I2C_DIV_CLK ),
> >> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_CLK, "HDMI_RX_I2C_IPG", 0,
> >> RX_HDMI_LPCG + 0x18,  IMX8QM_HDMI_RX_I2C_IPG_S_CLK),
> >> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_S_CLK, "HDMI_I2C_IPG_S", 0,
> >> RX_HDMI_LPCG + 0x1c, IMX8QM_HDMI_RX_IPG_CLK ), +
> >> +	CLK_5( IMX8QM_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
> >> IMX8QM_UART0_DIV ),
> >> +	CLK_5( IMX8QM_UART0_IPG_CLK, "UART0_IPG", 16,
> >> LPUART_0_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
> >> IMX8QM_UART1_DIV ),
> >> +	CLK_5( IMX8QM_UART1_IPG_CLK, "UART1_IPG", 16,
> >> LPUART_1_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
> >> IMX8QM_UART2_DIV ),
> >> +	CLK_5( IMX8QM_UART2_IPG_CLK, "UART2_IPG", 16,
> >> LPUART_2_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
> >> IMX8QM_UART3_DIV ),
> >> +	CLK_5( IMX8QM_UART3_IPG_CLK, "UART3_IPG", 16,
> >> LPUART_3_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ), +
> >> +	CLK_5( IMX8QM_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
> >> IMX8QM_SDHC0_DIV ),
> >> +	CLK_5( IMX8QM_SDHC0_IPG_CLK, "SDHC0_IPG", 16,
> >> USDHC_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
> >> IMX8QM_SDHC1_DIV ),
> >> +	CLK_5( IMX8QM_SDHC1_IPG_CLK, "SDHC1_IPG", 16,
> >> USDHC_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
> >> IMX8QM_SDHC2_DIV ),
> >> +	CLK_5( IMX8QM_SDHC2_IPG_CLK, "SDHC2_IPG", 16,
> >> USDHC_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), +
> >> +	CLK_5( IMX8QM_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
> >> ENET_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG,
> >> IMX8QM_ENET0_IPG_S_CLK ),
> >> +	CLK_5( IMX8QM_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG,
> >> IMX8QM_AXI_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
> >> IMX8QM_ENET0_ROOT_DIV ),
> >> +	CLK_5( IMX8QM_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG,
> >> IMX8QM_ENET0_ROOT_DIV  ),
> >> +	CLK_5( IMX8QM_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
> >> ENET_0_LPCG, IMX8QM_ENET0_RMII_TX_SEL  ),
> >> +	CLK_5( IMX8QM_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
> >> ENET_0_LPCG + 0x4, IMX8QM_ENET0_RGMII_DIV  ), +
> >> +	CLK_5( IMX8QM_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
> >> ENET_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG,
> >> IMX8QM_ENET1_IPG_S_CLK ),
> >> +	CLK_5( IMX8QM_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG,
> >> IMX8QM_AXI_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
> >> IMX8QM_ENET1_ROOT_DIV ),
> >> +	CLK_5( IMX8QM_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG,
> >> IMX8QM_ENET1_ROOT_DIV  ),
> >> +	CLK_5( IMX8QM_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
> >> ENET_1_LPCG, IMX8QM_ENET1_RMII_TX_SEL  ),
> >> +	CLK_5( IMX8QM_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
> >> ENET_1_LPCG + 0x4, IMX8QM_ENET1_RGMII_DIV  ), +
> >> +	CLK_5( IMX8QM_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18,
> >> FSPI_0_LPCG, IMX8QM_LSIO_BUS_CLK ),
> >> +	CLK_5( IMX8QM_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14,
> >> FSPI_0_LPCG, IMX8QM_FSPI0_IPG_S_CLK ),
> >> +	CLK_5( IMX8QM_FSPI0_HCLK, "FSPI0_HCLK", 0x10, FSPI_0_LPCG,
> >> IMX8QM_LSIO_MEM_CLK ),
> >> +	CLK_5( IMX8QM_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG,
> >> IMX8QM_FSPI0_DIV ), +
> >> +	CLK_5( IMX8QM_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
> >> USB_2_LPCG, IMX8QM_AHB_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
> >> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_USB2_OH_IPG_S_PL301_CLK,
> >> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
> >> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), +
> >> +	CLK_5( IMX8QM_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
> >> IMX8QM_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG,
> >> IMX8QM_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
> >> IMX8QM_USB3_IPG_CLK ),
> >> +	CLK_5( IMX8QM_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
> >> IMX8QM_USB3_ACLK_DIV ),
> >> +	CLK_5( IMX8QM_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
> >> IMX8QM_USB3_BUS_DIV ),
> >> +	CLK_5( IMX8QM_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
> >> IMX8QM_USB3_LPM_DIV ), +
> >> +	CLK_5( IMX8QM_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
> >> IMX8QM_AXI_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
> >> NAND_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QM_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4,
> >> NAND_LPCG, IMX8QM_GPMI_BCH_IO_DIV ),
> >> +	CLK_5( IMX8QM_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG,
> >> IMX8QM_GPMI_BCH_DIV ),
> >> +	CLK_5( IMX8QM_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG +
> >> 0x4, IMX8QM_AXI_CONN_CLK_ROOT ), +};
> >>  
> >> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
> >> -	if (ret) {
> >> -		printf("%s err %d\n", __func__, ret);
> >> -		return ret;
> >> -	}
> >> +struct imx8_mux_clks imx8qm_mux_clks[] = {
> >> +};
> >>  
> >> -	return 0;
> >> -}
> >> +struct imx8_clks_collect imx8qm_clk_collect = {
> >> +	{
> >> +		{&imx8qm_clks, ARRAY_SIZE(imx8qm_clks)},
> >> +		{&imx8qm_fixed_clks,
> >> ARRAY_SIZE(imx8qm_fixed_clks)},
> >> +		{&imx8qm_gpr_clks, ARRAY_SIZE(imx8qm_gpr_clks)},
> >> +		{&imx8qm_lpcg_clks, ARRAY_SIZE(imx8qm_lpcg_clks)},
> >> +		{&imx8qm_mux_clks, ARRAY_SIZE(imx8qm_mux_clks)},
> >> +	},
> >> +	FLAG_CLK_IMX8_IMX8QM,
> >> +};
> >> diff --git a/drivers/clk/imx/clk-imx8qxp.c
> >> b/drivers/clk/imx/clk-imx8qxp.c index 1fca36a..8181a97 100644
> >> --- a/drivers/clk/imx/clk-imx8qxp.c
> >> +++ b/drivers/clk/imx/clk-imx8qxp.c
> >> @@ -12,300 +12,156 @@
> >>  #include <dt-bindings/clock/imx8qxp-clock.h>
> >>  #include <dt-bindings/soc/imx_rsrc.h>
> >>  #include <misc.h>
> >> +#include <asm/arch/lpcg.h>
> >>  
> >>  #include "clk-imx8.h"
> >>  
> >> -#if CONFIG_IS_ENABLED(CMD_CLK)
> >> -struct imx8_clks imx8_clk_names[] = {
> >> -	{ IMX8QXP_A35_DIV, "A35_DIV" },
> >> -	{ IMX8QXP_I2C0_CLK, "I2C0" },
> >> -	{ IMX8QXP_I2C1_CLK, "I2C1" },
> >> -	{ IMX8QXP_I2C2_CLK, "I2C2" },
> >> -	{ IMX8QXP_I2C3_CLK, "I2C3" },
> >> -	{ IMX8QXP_UART0_CLK, "UART0" },
> >> -	{ IMX8QXP_UART1_CLK, "UART1" },
> >> -	{ IMX8QXP_UART2_CLK, "UART2" },
> >> -	{ IMX8QXP_UART3_CLK, "UART3" },
> >> -	{ IMX8QXP_SDHC0_CLK, "SDHC0" },
> >> -	{ IMX8QXP_SDHC1_CLK, "SDHC1" },
> >> -	{ IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" },
> >> -	{ IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" },
> >> -	{ IMX8QXP_ENET0_REF_DIV, "ENET0_REF" },
> >> -	{ IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" },
> >> -	{ IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" },
> >> -	{ IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" },
> >> -	{ IMX8QXP_ENET1_REF_DIV, "ENET1_REF" },
> >> -	{ IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" },
> >> +static struct imx8_clks imx8qxp_clks[] = {
> >> +	CLK_4( IMX8QXP_A35_DIV, "A35_DIV", SC_R_A35,
> >> SC_PM_CLK_CPU ),
> >> +	CLK_4( IMX8QXP_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
> >> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QXP_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
> >> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QXP_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
> >> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QXP_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
> >> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
> >> +	CLK_4( IMX8QXP_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
> >> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_UART0_DIV, "UART0_DIV", SC_R_UART_0,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_UART1_DIV, "UART1_DIV", SC_R_UART_1,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_UART2_DIV, "UART2_DIV", SC_R_UART_2,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_UART3_DIV, "UART3_DIV", SC_R_UART_3,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_ENET0_ROOT_DIV, "ENET0_ROOT_DIV",
> >> SC_R_ENET_0, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
> >> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
> >> +	CLK_4( IMX8QXP_ENET1_ROOT_DIV, "ENET1_ROOT_DIV",
> >> SC_R_ENET_1, SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
> >> SC_R_ENET_1, SC_PM_CLK_MISC0 ),
> >> +	CLK_4( IMX8QXP_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
> >> SC_PM_CLK_MST_BUS ),
> >> +	CLK_4( IMX8QXP_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
> >> SC_PM_CLK_MISC ),
> >> +	CLK_4( IMX8QXP_LSIO_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
> >> SC_PM_CLK_PER ),
> >> +	CLK_4( IMX8QXP_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND,
> >> SC_PM_CLK_MST_BUS ),
> >> +	CLK_4( IMX8QXP_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
> >> SC_PM_CLK_PER ), };
> >>  
> >> -int num_clks = ARRAY_SIZE(imx8_clk_names);
> >> -#endif
> >> -
> >> -ulong imx8_clk_get_rate(struct clk *clk)
> >> -{
> >> -	sc_pm_clk_t pm_clk;
> >> -	ulong rate;
> >> -	u16 resource;
> >> -	int ret;
> >> -
> >> -	debug("%s(#%lu)\n", __func__, clk->id);
> >> -
> >> -	switch (clk->id) {
> >> -	case IMX8QXP_A35_DIV:
> >> -		resource = SC_R_A35;
> >> -		pm_clk = SC_PM_CLK_CPU;
> >> -		break;
> >> -	case IMX8QXP_I2C0_CLK:
> >> -		resource = SC_R_I2C_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_I2C1_CLK:
> >> -		resource = SC_R_I2C_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_I2C2_CLK:
> >> -		resource = SC_R_I2C_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_I2C3_CLK:
> >> -		resource = SC_R_I2C_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_SDHC0_IPG_CLK:
> >> -	case IMX8QXP_SDHC0_CLK:
> >> -	case IMX8QXP_SDHC0_DIV:
> >> -		resource = SC_R_SDHC_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_SDHC1_IPG_CLK:
> >> -	case IMX8QXP_SDHC1_CLK:
> >> -	case IMX8QXP_SDHC1_DIV:
> >> -		resource = SC_R_SDHC_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART0_IPG_CLK:
> >> -	case IMX8QXP_UART0_CLK:
> >> -		resource = SC_R_UART_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART1_CLK:
> >> -		resource = SC_R_UART_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART2_CLK:
> >> -		resource = SC_R_UART_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART3_CLK:
> >> -		resource = SC_R_UART_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_ENET0_IPG_CLK:
> >> -	case IMX8QXP_ENET0_AHB_CLK:
> >> -	case IMX8QXP_ENET0_REF_DIV:
> >> -	case IMX8QXP_ENET0_PTP_CLK:
> >> -		resource = SC_R_ENET_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_ENET1_IPG_CLK:
> >> -	case IMX8QXP_ENET1_AHB_CLK:
> >> -	case IMX8QXP_ENET1_REF_DIV:
> >> -	case IMX8QXP_ENET1_PTP_CLK:
> >> -		resource = SC_R_ENET_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	default:
> >> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
> >> -		    clk->id >= IMX8QXP_CLK_END) {
> >> -			printf("%s(Invalid clk ID #%lu)\n",
> >> -			       __func__, clk->id);
> >> -			return -EINVAL;
> >> -		}
> >> -		return -ENOTSUPP;
> >> -	};
> >> -
> >> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
> >> -				   (sc_pm_clock_rate_t *)&rate);
> >> -	if (ret) {
> >> -		printf("%s err %d\n", __func__, ret);
> >> -		return ret;
> >> -	}
> >> -
> >> -	return rate;
> >> -}
> >> -
> >> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
> >> -{
> >> -	sc_pm_clk_t pm_clk;
> >> -	u32 new_rate = rate;
> >> -	u16 resource;
> >> -	int ret;
> >> -
> >> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
> >> -
> >> -	switch (clk->id) {
> >> -	case IMX8QXP_I2C0_CLK:
> >> -		resource = SC_R_I2C_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_I2C1_CLK:
> >> -		resource = SC_R_I2C_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_I2C2_CLK:
> >> -		resource = SC_R_I2C_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_I2C3_CLK:
> >> -		resource = SC_R_I2C_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART0_CLK:
> >> -		resource = SC_R_UART_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART1_CLK:
> >> -		resource = SC_R_UART_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART2_CLK:
> >> -		resource = SC_R_UART_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART3_CLK:
> >> -		resource = SC_R_UART_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_SDHC0_IPG_CLK:
> >> -	case IMX8QXP_SDHC0_CLK:
> >> -	case IMX8QXP_SDHC0_DIV:
> >> -		resource = SC_R_SDHC_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_SDHC1_SEL:
> >> -	case IMX8QXP_SDHC0_SEL:
> >> -		return 0;
> >> -	case IMX8QXP_SDHC1_IPG_CLK:
> >> -	case IMX8QXP_SDHC1_CLK:
> >> -	case IMX8QXP_SDHC1_DIV:
> >> -		resource = SC_R_SDHC_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_ENET0_IPG_CLK:
> >> -	case IMX8QXP_ENET0_AHB_CLK:
> >> -	case IMX8QXP_ENET0_REF_DIV:
> >> -	case IMX8QXP_ENET0_PTP_CLK:
> >> -		resource = SC_R_ENET_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_ENET1_IPG_CLK:
> >> -	case IMX8QXP_ENET1_AHB_CLK:
> >> -	case IMX8QXP_ENET1_REF_DIV:
> >> -	case IMX8QXP_ENET1_PTP_CLK:
> >> -		resource = SC_R_ENET_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	default:
> >> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
> >> -		    clk->id >= IMX8QXP_CLK_END) {
> >> -			printf("%s(Invalid clk ID #%lu)\n",
> >> -			       __func__, clk->id);
> >> -			return -EINVAL;
> >> -		}
> >> -		return -ENOTSUPP;
> >> -	};
> >> -
> >> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk,
> >> &new_rate);
> >> -	if (ret) {
> >> -		printf("%s err %d\n", __func__, ret);
> >> -		return ret;
> >> -	}
> >> -
> >> -	return new_rate;
> >> -}
> >> -
> >> -int __imx8_clk_enable(struct clk *clk, bool enable)
> >> -{
> >> -	sc_pm_clk_t pm_clk;
> >> -	u16 resource;
> >> -	int ret;
> >> +static struct imx8_fixed_clks imx8qxp_fixed_clks[] = {
> >> +	CLK_3( IMX8QXP_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK",
> >> SC_83MHZ ),
> >> +	CLK_3( IMX8QXP_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK",
> >> SC_166MHZ ),
> >> +	CLK_3( IMX8QXP_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK",
> >> SC_333MHZ ),
> >> +	CLK_3( IMX8QXP_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ
> >> ),
> >> +	CLK_3( IMX8QXP_MIPI_IPG_CLK, "IPG_MIPI_CLK", SC_120MHZ ),
> >> +	CLK_3( IMX8QXP_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
> >> +	CLK_3( IMX8QXP_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
> >> +};
> >>  
> >> -	debug("%s(#%lu)\n", __func__, clk->id);
> >> +static struct imx8_gpr_clks imx8qxp_gpr_clks[] = {
> >> +	CLK_5( IMX8QXP_ENET0_REF_DIV, "ENET0_REF_DIV",
> >> SC_R_ENET_0, SC_C_CLKDIV, IMX8QXP_ENET0_ROOT_DIV ),
> >> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL,
> >> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
> >> +	CLK_4( IMX8QXP_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
> >> SC_R_ENET_0, SC_C_TXCLK ),
> >> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK,
> >> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
> >> +	CLK_4( IMX8QXP_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
> >> SC_R_ENET_0, SC_C_DISABLE_50 ), +
> >> +	CLK_5( IMX8QXP_ENET1_REF_DIV, "ENET1_REF_DIV",
> >> SC_R_ENET_1, SC_C_CLKDIV, IMX8QXP_ENET1_ROOT_DIV ),
> >> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL,
> >> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
> >> +	CLK_4( IMX8QXP_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
> >> SC_R_ENET_1, SC_C_TXCLK ),
> >> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK,
> >> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
> >> +	CLK_4( IMX8QXP_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
> >> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
> >>  
> >> -	switch (clk->id) {
> >> -	case IMX8QXP_I2C0_CLK:
> >> -		resource = SC_R_I2C_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_I2C1_CLK:
> >> -		resource = SC_R_I2C_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_I2C2_CLK:
> >> -		resource = SC_R_I2C_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_I2C3_CLK:
> >> -		resource = SC_R_I2C_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART0_CLK:
> >> -		resource = SC_R_UART_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART1_CLK:
> >> -		resource = SC_R_UART_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART2_CLK:
> >> -		resource = SC_R_UART_2;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_UART3_CLK:
> >> -		resource = SC_R_UART_3;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_SDHC0_IPG_CLK:
> >> -	case IMX8QXP_SDHC0_CLK:
> >> -	case IMX8QXP_SDHC0_DIV:
> >> -		resource = SC_R_SDHC_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_SDHC1_IPG_CLK:
> >> -	case IMX8QXP_SDHC1_CLK:
> >> -	case IMX8QXP_SDHC1_DIV:
> >> -		resource = SC_R_SDHC_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_ENET0_IPG_CLK:
> >> -	case IMX8QXP_ENET0_AHB_CLK:
> >> -	case IMX8QXP_ENET0_REF_DIV:
> >> -	case IMX8QXP_ENET0_PTP_CLK:
> >> -		resource = SC_R_ENET_0;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	case IMX8QXP_ENET1_IPG_CLK:
> >> -	case IMX8QXP_ENET1_AHB_CLK:
> >> -	case IMX8QXP_ENET1_REF_DIV:
> >> -	case IMX8QXP_ENET1_PTP_CLK:
> >> -		resource = SC_R_ENET_1;
> >> -		pm_clk = SC_PM_CLK_PER;
> >> -		break;
> >> -	default:
> >> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
> >> -		    clk->id >= IMX8QXP_CLK_END) {
> >> -			printf("%s(Invalid clk ID #%lu)\n",
> >> -			       __func__, clk->id);
> >> -			return -EINVAL;
> >> -		}
> >> -		return -ENOTSUPP;
> >> -	}
> >> +static struct imx8_lpcg_clks imx8qxp_lpcg_clks[] = {
> >> +	CLK_5( IMX8QXP_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
> >> IMX8QXP_I2C0_DIV ),
> >> +	CLK_5( IMX8QXP_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG,
> >> IMX8QXP_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
> >> IMX8QXP_I2C1_DIV ),
> >> +	CLK_5( IMX8QXP_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG,
> >> IMX8QXP_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
> >> IMX8QXP_I2C2_DIV ),
> >> +	CLK_5( IMX8QXP_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG,
> >> IMX8QXP_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
> >> IMX8QXP_I2C3_DIV ),
> >> +	CLK_5( IMX8QXP_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG,
> >> IMX8QXP_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
> >> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI0_I2C0_DIV ),
> >> +	CLK_5( IMX8QXP_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 16,
> >> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
> >> +	CLK_5( IMX8QXP_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
> >> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI0_I2C1_DIV ),
> >> +	CLK_5( IMX8QXP_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 16,
> >> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
> >> +	CLK_5( IMX8QXP_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
> >> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI1_I2C0_DIV ),
> >> +	CLK_5( IMX8QXP_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 16,
> >> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
> >> +	CLK_5( IMX8QXP_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
> >> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI1_I2C1_DIV ),
> >> +	CLK_5( IMX8QXP_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 16,
> >> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
> >> +	CLK_5( IMX8QXP_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
> >> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_CSI0_I2C0_DIV ),
> >> +	CLK_5( IMX8QXP_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
> >> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ), +
> >> +	CLK_5( IMX8QXP_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
> >> IMX8QXP_UART0_DIV ),
> >> +	CLK_5( IMX8QXP_UART0_IPG_CLK, "UART0_IPG", 16,
> >> LPUART_0_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
> >> IMX8QXP_UART1_DIV ),
> >> +	CLK_5( IMX8QXP_UART1_IPG_CLK, "UART1_IPG", 16,
> >> LPUART_1_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
> >> IMX8QXP_UART2_DIV ),
> >> +	CLK_5( IMX8QXP_UART2_IPG_CLK, "UART2_IPG", 16,
> >> LPUART_2_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
> >> IMX8QXP_UART3_DIV ),
> >> +	CLK_5( IMX8QXP_UART3_IPG_CLK, "UART3_IPG", 16,
> >> LPUART_3_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ), +
> >> +	CLK_5( IMX8QXP_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
> >> IMX8QXP_SDHC0_DIV ),
> >> +	CLK_5( IMX8QXP_SDHC0_IPG_CLK, "SDHC0_IPG", 16,
> >> USDHC_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
> >> IMX8QXP_SDHC1_DIV ),
> >> +	CLK_5( IMX8QXP_SDHC1_IPG_CLK, "SDHC1_IPG", 16,
> >> USDHC_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
> >> IMX8QXP_SDHC2_DIV ),
> >> +	CLK_5( IMX8QXP_SDHC2_IPG_CLK, "SDHC2_IPG", 16,
> >> USDHC_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), +
> >> +	CLK_5( IMX8QXP_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
> >> ENET_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG", 16,
> >> ENET_0_LPCG, IMX8QXP_ENET0_IPG_S_CLK ),
> >> +	CLK_5( IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG,
> >> IMX8QXP_AXI_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
> >> IMX8QXP_ENET0_ROOT_DIV ),
> >> +	CLK_5( IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG,
> >> IMX8QXP_ENET0_ROOT_DIV  ),
> >> +	CLK_5( IMX8QXP_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
> >> ENET_0_LPCG, IMX8QXP_ENET0_RMII_TX_SEL  ),
> >> +	CLK_5( IMX8QXP_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
> >> ENET_0_LPCG + 0x4, IMX8QXP_ENET0_RGMII_DIV  ), +
> >> +	CLK_5( IMX8QXP_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
> >> ENET_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG", 16,
> >> ENET_1_LPCG, IMX8QXP_ENET1_IPG_S_CLK ),
> >> +	CLK_5( IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG,
> >> IMX8QXP_AXI_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
> >> IMX8QXP_ENET1_ROOT_DIV ),
> >> +	CLK_5( IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG,
> >> IMX8QXP_ENET1_ROOT_DIV  ),
> >> +	CLK_5( IMX8QXP_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
> >> ENET_1_LPCG, IMX8QXP_ENET1_RMII_TX_SEL  ),
> >> +	CLK_5( IMX8QXP_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
> >> ENET_1_LPCG + 0x4, IMX8QXP_ENET1_RGMII_DIV  ), +
> >> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18,
> >> FSPI_0_LPCG, IMX8QXP_LSIO_BUS_CLK ),
> >> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14,
> >> FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_IPG_S_CLK ),
> >> +	CLK_5( IMX8QXP_LSIO_FSPI0_HCLK, "FSPI0_HCLK", 0x10,
> >> FSPI_0_LPCG, IMX8QXP_LSIO_MEM_CLK ),
> >> +	CLK_5( IMX8QXP_LSIO_FSPI0_CLK, "FSPI0_CLK", 0,
> >> FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_DIV ), +
> >> +	CLK_5( IMX8QXP_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
> >> USB_2_LPCG, IMX8QXP_AHB_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
> >> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_PL301_CLK,
> >> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
> >> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), +
> >> +	CLK_5( IMX8QXP_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
> >> IMX8QXP_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_USB3_CORE_PCLK, "USB3_CORE", 20,
> >> USB_3_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
> >> IMX8QXP_USB3_IPG_CLK ),
> >> +	CLK_5( IMX8QXP_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
> >> IMX8QXP_USB3_ACLK_DIV ),
> >> +	CLK_5( IMX8QXP_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
> >> IMX8QXP_USB3_BUS_DIV ),
> >> +	CLK_5( IMX8QXP_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
> >> IMX8QXP_USB3_LPM_DIV ), +
> >> +	CLK_5( IMX8QXP_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
> >> IMX8QXP_AXI_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
> >> NAND_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
> >> +	CLK_5( IMX8QXP_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4,
> >> NAND_LPCG, IMX8QXP_GPMI_BCH_IO_DIV ),
> >> +	CLK_5( IMX8QXP_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG,
> >> IMX8QXP_GPMI_BCH_DIV ),
> >> +	CLK_5( IMX8QXP_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG +
> >> 0x4, IMX8QXP_AXI_CONN_CLK_ROOT ), +};
> >>  
> >> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
> >> -	if (ret) {
> >> -		printf("%s err %d\n", __func__, ret);
> >> -		return ret;
> >> -	}
> >> +struct imx8_mux_clks imx8qxp_mux_clks[] = {
> >> +	CLK_MUX( IMX8QXP_SDHC0_SEL, "SDHC0_SEL",
> >> IMX8QXP_SDHC0_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
> >> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
> >> IMX8QXP_CLK_DUMMY ),
> >> +	CLK_MUX( IMX8QXP_SDHC1_SEL, "SDHC1_SEL",
> >> IMX8QXP_SDHC1_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
> >> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
> >> IMX8QXP_CLK_DUMMY ),
> >> +	CLK_MUX( IMX8QXP_SDHC2_SEL, "SDHC2_SEL",
> >> IMX8QXP_SDHC2_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
> >> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
> >> IMX8QXP_CLK_DUMMY ), +};
> >>  
> >> -	return 0;
> >> -}
> >> +struct imx8_clks_collect imx8qxp_clk_collect = {
> >> +	{
> >> +		{&imx8qxp_clks, ARRAY_SIZE(imx8qxp_clks)},
> >> +		{&imx8qxp_fixed_clks,
> >> ARRAY_SIZE(imx8qxp_fixed_clks)},
> >> +		{&imx8qxp_gpr_clks, ARRAY_SIZE(imx8qxp_gpr_clks)},
> >> +		{&imx8qxp_lpcg_clks,
> >> ARRAY_SIZE(imx8qxp_lpcg_clks)},
> >> +		{&imx8qxp_mux_clks, ARRAY_SIZE(imx8qxp_mux_clks)},
> >> +	},
> >> +	FLAG_CLK_IMX8_IMX8QXP,
> >> +};  
> > 
> > 
> > 
> > 
> > Best regards,
> > 
> > Lukasz Majewski
> > 
> > --
> > 
> > DENX Software Engineering GmbH,      Managing Director: Wolfgang
> > Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell,
> > Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
> > lukma at denx.de 
> 




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190710/2a34f3f5/attachment.sig>

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

* [U-Boot] [EXT] Re: [PATCH 3/5] clk: imx8: Update imx8 clock driver
  2019-07-10  7:34       ` Lukasz Majewski
@ 2019-07-10  8:25         ` Ye Li
  2019-07-10  8:46           ` Lukasz Majewski
  0 siblings, 1 reply; 14+ messages in thread
From: Ye Li @ 2019-07-10  8:25 UTC (permalink / raw)
  To: u-boot

Hi Lukasz,

> Hi Ye,
> 
>> Hi Lukasz,
>>
>>> Hi Ye,
>>>   
>>>> Update imx8 clock driver to support LPCG and full clocks tree for
>>>> some modules aligned with kernel.
>>>>
>>>> We classify the clock into serveral types: slice, fixed, lpcg, gpr
>>>> and mux.  
>>>
>>> Is this code in sync with Linux kernel? Does the imx8 (in Linux
>>> kernel) use the Common Clock Framework?  
>> This patch syncs the tree architecture with kernel but not the codes.
>> imx8 kernel clock driver uses common clock framework.
>>
>>>   
>>>> Generally slice and fixed clocks are the sources. lpcg, gpr
>>>> and mux are the downstream of those sources and are used for
>>>> gating, muxing or dividing functions.
>>>>
>>>> This patch replaces the functions defined in imx8qm and imx8qxp
>>>> with the clock tables of different clock types. clk-imx8 use
>>>> unified functions to process these clock tables.  
>>>
>>>
>>> I've posted the Common Clock Framework v5 to the mailing list
>>> recently: https://patchwork.ozlabs.org/cover/1121348/
>>>
>>>
>>> So maybe this code could benefit from those patches and use this
>>> infrastructure ?
>>>   
>> I think so. We will look into the CCF in u-boot and migrate it later. 
> 
> Sorry, but I'm involved in the open source U-Boot developement for too
> long to believe in such statements.
> 
> If the feature is not added from the outset, then it will not be
> changed.
> 
So when will CCF be pushed? 

Best regards,
Ye Li
>> But now we prefer upstream this update first. This one has been
>> tested in downstream. And we have some driver patches going for
>> upstream depending on it, while a new driver using CCF may need more
>> time to get ready.
>>
>> Best regards,
>> Ye Li
>>>>
>>>> Note: since the clock depends on the power domain of its resource,
>>>> must power on the resource firstly, then we can get the clock.
>>>> Otherwise, we can't access lpcg. Thus, the clock dump only works
>>>> for the slice clock.
>>>>
>>>> Signed-off-by: Ye Li <ye.li@nxp.com>
>>>> ---
>>>>  drivers/clk/imx/clk-imx8.c    | 304 +++++++++++++++++++++++++--
>>>>  drivers/clk/imx/clk-imx8.h    |  83 +++++++-
>>>>  drivers/clk/imx/clk-imx8qm.c  | 479
>>>> ++++++++++++++++--------------------------
>>>> drivers/clk/imx/clk-imx8qxp.c | 432
>>>> +++++++++++++------------------------ 4 files changed, 689
>>>> insertions(+), 609 deletions(-)
>>>>
>>>> diff --git a/drivers/clk/imx/clk-imx8.c
>>>> b/drivers/clk/imx/clk-imx8.c index a755e26..afdb6ea 100644
>>>> --- a/drivers/clk/imx/clk-imx8.c
>>>> +++ b/drivers/clk/imx/clk-imx8.c
>>>> @@ -12,32 +12,294 @@
>>>>  #include <dt-bindings/clock/imx8qxp-clock.h>
>>>>  #include <dt-bindings/soc/imx_rsrc.h>
>>>>  #include <misc.h>
>>>> +#include <asm/arch/lpcg.h>
>>>>  
>>>>  #include "clk-imx8.h"
>>>>  
>>>> -__weak ulong imx8_clk_get_rate(struct clk *clk)
>>>> +struct imx8_clks_collect *soc_data[] = {
>>>> +#ifdef CONFIG_IMX8QXP
>>>> +	&imx8qxp_clk_collect,
>>>> +#endif
>>>> +#ifdef CONFIG_IMX8QM
>>>> +	&imx8qm_clk_collect,
>>>> +#endif
>>>> +};
>>>> +
>>>> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id);
>>>> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
>>>> enable); +static ulong __imx8_clk_set_rate(struct udevice *dev,
>>>> ulong id, unsigned long rate); +
>>>> +static struct imx8_clks_collect * find_clks_collect(struct udevice
>>>> *dev) +{
>>>> +	ulong data = (ulong)dev_get_driver_data(dev);
>>>> +	int i;
>>>> +
>>>> +	for (i = 0; i < ARRAY_SIZE(soc_data); i++) {
>>>> +		if (soc_data[i]->match_flag == data)
>>>> +			return soc_data[i];
>>>> +	}
>>>> +
>>>> +	return NULL;
>>>> +}
>>>> +
>>>> +static void * check_imx8_clk(struct udevice *dev, enum
>>>> imx8_clk_type type, ulong id, u32 size_of_clk) +{
>>>> +	u32 i, size;
>>>> +	struct imx8_clks_collect *clks_col =
>>>> find_clks_collect(dev);
>>>> +	struct imx8_clk_header *hdr;
>>>> +	ulong clks;
>>>> +
>>>> +	if (!clks_col || !(clks_col->clks[type].type_clks)) {
>>>> +		printf("%s fails to get clks for type %d\n",
>>>> +		       __func__, type);
>>>> +		return NULL;
>>>> +	}
>>>> +
>>>> +	clks = (ulong)(clks_col->clks[type].type_clks);
>>>> +	size = clks_col->clks[type].num;
>>>> +
>>>> +	for (i = 0; i < size; i++) {
>>>> +		hdr = (struct imx8_clk_header *)clks;
>>>> +		if (id == hdr->id)
>>>> +			return (void *)hdr;
>>>> +
>>>> +		clks += size_of_clk;
>>>> +	}
>>>> +
>>>> +	return NULL;
>>>> +}
>>>> +
>>>> +static ulong imx8_get_rate_lpcg(struct udevice *dev, struct
>>>> imx8_lpcg_clks *lpcg_clk) +{
>>>> +	if (lpcg_clk->parent_id != 0) {
>>>> +		if (lpcg_is_clock_on(lpcg_clk->lpcg,
>>>> lpcg_clk->bit_idx >> 2)) {
>>>> +			return __imx8_clk_get_rate(dev,
>>>> lpcg_clk->parent_id);
>>>> +		} else {
>>>> +			return 0;
>>>> +		}
>>>> +	} else {
>>>> +		return -ENOSYS;
>>>> +	}
>>>> +}
>>>> +
>>>> +static ulong imx8_get_rate_slice(struct udevice *dev, struct
>>>> imx8_clks *slice_clk) +{
>>>> +	int ret;
>>>> +	u32 rate;
>>>> +
>>>> +	ret = sc_pm_get_clock_rate(-1, slice_clk->rsrc,
>>>> slice_clk->pm_clk,
>>>> +				   (sc_pm_clock_rate_t *)&rate);
>>>> +	if (ret) {
>>>> +		printf("%s err %d\n", __func__, ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	return rate;
>>>> +}
>>>> +
>>>> +static ulong imx8_get_rate_fixed(struct udevice *dev, struct
>>>> imx8_fixed_clks *fixed_clk) +{
>>>> +	return fixed_clk->rate;
>>>> +}
>>>> +
>>>> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id)
>>>> +{
>>>> +	void* clkdata;
>>>> +
>>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
>>>> sizeof(struct imx8_lpcg_clks));
>>>> +	if (clkdata) {
>>>> +		return imx8_get_rate_lpcg(dev, (struct
>>>> imx8_lpcg_clks *)clkdata);
>>>> +	}
>>>> +
>>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
>>>> sizeof(struct imx8_clks));
>>>> +	if (clkdata) {
>>>> +		return imx8_get_rate_slice(dev, (struct imx8_clks
>>>> *)clkdata);
>>>> +	}
>>>> +
>>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_FIXED, id,
>>>> sizeof(struct imx8_fixed_clks));
>>>> +	if (clkdata) {
>>>> +		return imx8_get_rate_fixed(dev, (struct
>>>> imx8_fixed_clks *)clkdata);
>>>> +	}
>>>> +
>>>> +	return -ENOSYS;
>>>> +}
>>>> +
>>>> +static ulong imx8_clk_get_rate(struct clk *clk)
>>>> +{
>>>> +	return __imx8_clk_get_rate(clk->dev, clk->id);
>>>> +}
>>>> +
>>>> +static ulong imx8_set_rate_lpcg(struct udevice *dev, struct
>>>> imx8_lpcg_clks *lpcg_clk, unsigned long rate) +{
>>>> +	if (lpcg_clk->parent_id != 0) {
>>>> +		return __imx8_clk_set_rate(dev,
>>>> lpcg_clk->parent_id, rate);
>>>> +	} else {
>>>> +		return -ENOSYS;
>>>> +	}
>>>> +}
>>>> +
>>>> +static ulong imx8_set_rate_slice(struct udevice *dev, struct
>>>> imx8_clks *slice_clk, unsigned long rate) +{
>>>> +	int ret;
>>>> +	u32 new_rate = rate;
>>>> +
>>>> +	ret = sc_pm_set_clock_rate(-1, slice_clk->rsrc,
>>>> slice_clk->pm_clk, &new_rate);
>>>> +	if (ret) {
>>>> +		printf("%s err %d\n", __func__, ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	return new_rate;
>>>> +}
>>>> +
>>>> +static ulong imx8_set_rate_gpr(struct udevice *dev, struct
>>>> imx8_gpr_clks *gpr_clk, unsigned long rate) {
>>>> +	ulong parent_rate;
>>>> +	u32 val;
>>>> +	int ret;
>>>> +
>>>> +	if (gpr_clk->parent_id == 0)
>>>> +		return -ENOSYS;
>>>> +
>>>> +	parent_rate = __imx8_clk_get_rate(dev,
>>>> gpr_clk->parent_id);
>>>> +	if (parent_rate > 0) {
>>>> +		val = (rate < parent_rate) ? 1 : 0;
>>>> +
>>>> +		ret = sc_misc_set_control(-1, gpr_clk->rsrc,
>>>> +			gpr_clk->gpr_id, val);
>>>> +		if (ret) {
>>>> +			printf("%s err %d\n", __func__, ret);
>>>> +			return ret;
>>>> +		}
>>>> +
>>>> +		return rate;
>>>> +	}
>>>> +
>>>> +	return -ENOSYS;
>>>> +}
>>>> +
>>>> +static ulong __imx8_clk_set_rate(struct udevice *dev, ulong id,
>>>> unsigned long rate) +{
>>>> +	void* clkdata;
>>>> +
>>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
>>>> sizeof(struct imx8_clks));
>>>> +	if (clkdata) {
>>>> +		return imx8_set_rate_slice(dev, (struct imx8_clks
>>>> *)clkdata, rate);
>>>> +	}
>>>> +
>>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
>>>> sizeof(struct imx8_lpcg_clks));
>>>> +	if (clkdata) {
>>>> +		return imx8_set_rate_lpcg(dev, (struct
>>>> imx8_lpcg_clks *)clkdata, rate);
>>>> +	}
>>>> +
>>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_GPR, id,
>>>> sizeof(struct imx8_gpr_clks));
>>>> +	if (clkdata) {
>>>> +		return imx8_set_rate_gpr(dev, (struct
>>>> imx8_gpr_clks *)clkdata, rate);
>>>> +	}
>>>> +
>>>> +	return -ENOSYS;
>>>> +}
>>>> +
>>>> +static ulong imx8_clk_set_rate(struct clk *clk, unsigned long
>>>> rate) +{
>>>> +	return __imx8_clk_set_rate(clk->dev, clk->id, rate);
>>>> +
>>>> +}
>>>> +
>>>> +static int imx8_enable_slice(struct udevice *dev, struct imx8_clks
>>>> *slice_clk, bool enable) +{
>>>> +	int ret;
>>>> +
>>>> +	ret = sc_pm_clock_enable(-1, slice_clk->rsrc,
>>>> slice_clk->pm_clk, enable, 0);
>>>> +	if (ret) {
>>>> +		printf("%s err %d\n", __func__, ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>>  	return 0;
>>>>  }
>>>>  
>>>> -__weak ulong imx8_clk_set_rate(struct clk *clk, unsigned long
>>>> rate) +static int imx8_enable_lpcg(struct udevice *dev, struct
>>>> imx8_lpcg_clks *lpcg_clk, bool enable) {
>>>> +	if (enable) {
>>>> +		if (lpcg_clk->parent_id != 0) {
>>>> +			__imx8_clk_enable(dev,
>>>> lpcg_clk->parent_id, enable);
>>>> +		}
>>>> +
>>>> +		lpcg_clock_on(lpcg_clk->lpcg, lpcg_clk->bit_idx >>
>>>> 2);
>>>> +	} else {
>>>> +		lpcg_clock_off(lpcg_clk->lpcg, lpcg_clk->bit_idx
>>>>>> 2); +
>>>> +		if (lpcg_clk->parent_id != 0) {
>>>> +			__imx8_clk_enable(dev,
>>>> lpcg_clk->parent_id, enable);
>>>> +		}
>>>> +	}
>>>> +
>>>>  	return 0;
>>>>  }
>>>>  
>>>> -__weak int __imx8_clk_enable(struct clk *clk, bool enable)
>>>> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
>>>> enable) {
>>>> -	return -ENOTSUPP;
>>>> +	void* clkdata;
>>>> +
>>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
>>>> sizeof(struct imx8_lpcg_clks));
>>>> +	if (clkdata) {
>>>> +		return imx8_enable_lpcg(dev, (struct
>>>> imx8_lpcg_clks *)clkdata, enable);
>>>> +	}
>>>> +
>>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
>>>> sizeof(struct imx8_clks));
>>>> +	if (clkdata) {
>>>> +		return imx8_enable_slice(dev, (struct imx8_clks
>>>> *)clkdata, enable);
>>>> +	}
>>>> +
>>>> +	return -ENOSYS;
>>>>  }
>>>>  
>>>>  static int imx8_clk_disable(struct clk *clk)
>>>>  {
>>>> -	return __imx8_clk_enable(clk, 0);
>>>> +	return __imx8_clk_enable(clk->dev, clk->id, 0);
>>>>  }
>>>>  
>>>>  static int imx8_clk_enable(struct clk *clk)
>>>>  {
>>>> -	return __imx8_clk_enable(clk, 1);
>>>> +	return __imx8_clk_enable(clk->dev, clk->id, 1);
>>>> +}
>>>> +
>>>> +static int imx8_set_parent_mux(struct udevice *dev, struct
>>>> imx8_mux_clks *mux_clk, ulong pid) +{
>>>> +	u32 i;
>>>> +	int ret;
>>>> +	struct imx8_clks *slice_clkdata;
>>>> +
>>>> +	slice_clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE,
>>>> mux_clk->slice_clk_id, sizeof(struct imx8_clks));
>>>> +	if (!slice_clkdata) {
>>>> +		printf("Error: fail to find slice clk %lu for this
>>>> mux %lu\n", mux_clk->slice_clk_id, mux_clk->hdr.id);
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	for (i = 0; i< CLK_IMX8_MAX_MUX_SEL; i++) {
>>>> +		if (pid == mux_clk->parent_clks[i]) {
>>>> +			ret = sc_pm_set_clock_parent(-1,
>>>> slice_clkdata->rsrc,  slice_clkdata->pm_clk, i);
>>>> +			if (ret)
>>>> +				printf("Error: fail to set clock
>>>> parent rsrc %d, pm_clk %d, parent clk %d\n",
>>>> +					slice_clkdata->rsrc,
>>>> slice_clkdata->pm_clk, i);
>>>> +			return ret;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	return -ENOSYS;
>>>> +}
>>>> +
>>>> +static int imx8_clk_set_parent(struct clk *clk, struct clk
>>>> *parent) +{
>>>> +	void* clkdata;
>>>> +
>>>> +	clkdata = check_imx8_clk(clk->dev, IMX8_CLK_MUX, clk->id,
>>>> sizeof(struct imx8_mux_clks));
>>>> +	if (clkdata) {
>>>> +		return imx8_set_parent_mux(clk->dev, (struct
>>>> imx8_mux_clks *)clkdata, parent->id);
>>>> +	}
>>>> +
>>>> +	return -ENOSYS;
>>>>  }
>>>>  
>>>>  #if CONFIG_IS_ENABLED(CMD_CLK)
>>>> @@ -47,6 +309,9 @@ int soc_clk_dump(void)
>>>>  	struct clk clk;
>>>>  	unsigned long rate;
>>>>  	int i, ret;
>>>> +	u32 size;
>>>> +	struct imx8_clks *clks;
>>>> +	struct imx8_clks_collect *clks_col;
>>>>  
>>>>  	ret = uclass_get_device_by_driver(UCLASS_CLK,
>>>>  					  DM_GET_DRIVER(imx8_clk),
>>>> &dev); @@ -55,8 +320,19 @@ int soc_clk_dump(void)
>>>>  
>>>>  	printf("Clk\t\tHz\n");
>>>>  
>>>> -	for (i = 0; i < num_clks; i++) {
>>>> -		clk.id = imx8_clk_names[i].id;
>>>> +	clks_col = find_clks_collect(dev);
>>>> +
>>>> +	if (!clks_col
>>>> || !(clks_col->clks[IMX8_CLK_SLICE].type_clks)) {
>>>> +		printf("%s fails to get clks for type %d\n",
>>>> +		       __func__, IMX8_CLK_SLICE);
>>>> +		return -ENODEV;
>>>> +	}
>>>> +
>>>> +	clks = (struct imx8_clks
>>>> *)(clks_col->clks[IMX8_CLK_SLICE].type_clks);
>>>> +	size = clks_col->clks[IMX8_CLK_SLICE].num;
>>>> +
>>>> +	for (i = 0; i < size; i++) {
>>>> +		clk.id = clks[i].hdr.id;
>>>>  		ret = clk_request(dev, &clk);
>>>>  		if (ret < 0) {
>>>>  			debug("%s clk_request() failed: %d\n",
>>>> __func__, ret); @@ -70,21 +346,22 @@ int soc_clk_dump(void)
>>>>  
>>>>  		if (ret == -ENOTSUPP) {
>>>>  			printf("clk ID %lu not supported yet\n",
>>>> -			       imx8_clk_names[i].id);
>>>> +			       clks[i].hdr.id);
>>>>  			continue;
>>>>  		}
>>>>  		if (ret < 0) {
>>>>  			printf("%s %lu: get_rate err: %d\n",
>>>> -			       __func__, imx8_clk_names[i].id,
>>>> ret);
>>>> +			       __func__, clks[i].hdr.id, ret);
>>>>  			continue;
>>>>  		}
>>>>  
>>>>  		printf("%s(%3lu):\t%lu\n",
>>>> -		       imx8_clk_names[i].name,
>>>> imx8_clk_names[i].id, rate);
>>>> +		       clks[i].hdr.name, clks[i].hdr.id, rate);
>>>>  	}
>>>>  
>>>>  	return 0;
>>>>  }
>>>> +
>>>>  #endif
>>>>  
>>>>  static struct clk_ops imx8_clk_ops = {
>>>> @@ -92,6 +369,7 @@ static struct clk_ops imx8_clk_ops = {
>>>>  	.get_rate = imx8_clk_get_rate,
>>>>  	.enable = imx8_clk_enable,
>>>>  	.disable = imx8_clk_disable,
>>>> +	.set_parent = imx8_clk_set_parent,
>>>>  };
>>>>  
>>>>  static int imx8_clk_probe(struct udevice *dev)
>>>> @@ -100,8 +378,8 @@ static int imx8_clk_probe(struct udevice *dev)
>>>>  }
>>>>  
>>>>  static const struct udevice_id imx8_clk_ids[] = {
>>>> -	{ .compatible = "fsl,imx8qxp-clk" },
>>>> -	{ .compatible = "fsl,imx8qm-clk" },
>>>> +	{ .compatible = "fsl,imx8qxp-clk", .data =
>>>> FLAG_CLK_IMX8_IMX8QXP, },
>>>> +	{ .compatible = "fsl,imx8qm-clk", .data =
>>>> FLAG_CLK_IMX8_IMX8QM, }, { },
>>>>  };
>>>>  
>>>> diff --git a/drivers/clk/imx/clk-imx8.h
>>>> b/drivers/clk/imx/clk-imx8.h index 68ad675..c0566f8 100644
>>>> --- a/drivers/clk/imx/clk-imx8.h
>>>> +++ b/drivers/clk/imx/clk-imx8.h
>>>> @@ -4,16 +4,87 @@
>>>>   * Peng Fan <peng.fan@nxp.com>
>>>>   */
>>>>  
>>>> -struct imx8_clks {
>>>> +#define CLK_IMX8_MAX_MUX_SEL 5
>>>> +
>>>> +#define FLAG_CLK_IMX8_IMX8QM	BIT(0)
>>>> +#define FLAG_CLK_IMX8_IMX8QXP	BIT(1)
>>>> +
>>>> +struct imx8_clk_header {
>>>>  	ulong id;
>>>> +#if CONFIG_IS_ENABLED(CMD_CLK)
>>>>  	const char *name;
>>>> +#endif
>>>> +};
>>>> +
>>>> +struct imx8_clks {
>>>> +	struct imx8_clk_header hdr;
>>>> +	u16 rsrc;
>>>> +	sc_pm_clk_t pm_clk;
>>>> +};
>>>> +
>>>> +struct imx8_fixed_clks {
>>>> +	struct imx8_clk_header hdr;
>>>> +	ulong rate;
>>>> +};
>>>> +
>>>> +struct imx8_gpr_clks {
>>>> +	struct imx8_clk_header hdr;
>>>> +	u16 rsrc;
>>>> +	sc_ctrl_t gpr_id;
>>>> +	ulong parent_id;
>>>> +};
>>>> +
>>>> +struct imx8_lpcg_clks {
>>>> +	struct imx8_clk_header hdr;
>>>> +	u8 bit_idx;
>>>> +	u32 lpcg;
>>>> +	ulong parent_id;
>>>> +};
>>>> +
>>>> +struct imx8_mux_clks {
>>>> +	struct imx8_clk_header hdr;
>>>> +	ulong slice_clk_id;
>>>> +	ulong parent_clks[CLK_IMX8_MAX_MUX_SEL];
>>>> +};
>>>> +
>>>> +enum imx8_clk_type {
>>>> +	IMX8_CLK_SLICE 		= 0,
>>>> +	IMX8_CLK_FIXED 	= 1,
>>>> +	IMX8_CLK_GPR 		= 2,
>>>> +	IMX8_CLK_LPCG 		= 3,
>>>> +	IMX8_CLK_MUX 		= 4,
>>>> +	IMX8_CLK_END		= 5,
>>>> +};
>>>> +
>>>> +struct imx8_clk_pair {
>>>> +	void *type_clks;
>>>> +	u32 num;
>>>> +};
>>>> +
>>>> +struct imx8_clks_collect {
>>>> +	struct imx8_clk_pair clks[IMX8_CLK_END];
>>>> +	ulong match_flag;
>>>>  };
>>>>  
>>>>  #if CONFIG_IS_ENABLED(CMD_CLK)
>>>> -extern struct imx8_clks imx8_clk_names[];
>>>> -extern int num_clks;
>>>> +#define CLK_3(ID, NAME, MEM2) \
>>>> +	{ { ID, NAME, }, MEM2, }
>>>> +#define CLK_4(ID, NAME, MEM2, MEM3) \
>>>> +	{ { ID, NAME, }, MEM2, MEM3, }
>>>> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
>>>> +	{ { ID, NAME, }, MEM2, MEM3, MEM4, }
>>>> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
>>>> +	{ { ID, NAME, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
>>>> +#else
>>>> +#define CLK_3(ID, NAME, MEM2) \
>>>> +	{ { ID, }, MEM2, }
>>>> +#define CLK_4(ID, NAME, MEM2, MEM3) \
>>>> +	{ { ID, }, MEM2, MEM3, }
>>>> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
>>>> +	{ { ID, }, MEM2, MEM3, MEM4, }
>>>> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
>>>> +	{ { ID, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
>>>>  #endif
>>>>  
>>>> -ulong imx8_clk_get_rate(struct clk *clk);
>>>> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate);
>>>> -int __imx8_clk_enable(struct clk *clk, bool enable);
>>>> +extern struct imx8_clks_collect imx8qxp_clk_collect;
>>>> +extern struct imx8_clks_collect imx8qm_clk_collect;
>>>> diff --git a/drivers/clk/imx/clk-imx8qm.c
>>>> b/drivers/clk/imx/clk-imx8qm.c index a6b09d2..f4ee007 100644
>>>> --- a/drivers/clk/imx/clk-imx8qm.c
>>>> +++ b/drivers/clk/imx/clk-imx8qm.c
>>>> @@ -12,314 +12,189 @@
>>>>  #include <dt-bindings/clock/imx8qm-clock.h>
>>>>  #include <dt-bindings/soc/imx_rsrc.h>
>>>>  #include <misc.h>
>>>> +#include <asm/arch/lpcg.h>
>>>>  
>>>>  #include "clk-imx8.h"
>>>>  
>>>> -#if CONFIG_IS_ENABLED(CMD_CLK)
>>>> -struct imx8_clks imx8_clk_names[] = {
>>>> -	{ IMX8QM_A53_DIV, "A53_DIV" },
>>>> -	{ IMX8QM_UART0_CLK, "UART0" },
>>>> -	{ IMX8QM_UART1_CLK, "UART1" },
>>>> -	{ IMX8QM_UART2_CLK, "UART2" },
>>>> -	{ IMX8QM_UART3_CLK, "UART3" },
>>>> -	{ IMX8QM_SDHC0_CLK, "SDHC0" },
>>>> -	{ IMX8QM_SDHC1_CLK, "SDHC1" },
>>>> -	{ IMX8QM_SDHC2_CLK, "SDHC2" },
>>>> -	{ IMX8QM_ENET0_AHB_CLK, "ENET0_AHB" },
>>>> -	{ IMX8QM_ENET0_IPG_CLK, "ENET0_IPG" },
>>>> -	{ IMX8QM_ENET0_REF_DIV, "ENET0_REF" },
>>>> -	{ IMX8QM_ENET0_PTP_CLK, "ENET0_PTP" },
>>>> -	{ IMX8QM_ENET1_AHB_CLK, "ENET1_AHB" },
>>>> -	{ IMX8QM_ENET1_IPG_CLK, "ENET1_IPG" },
>>>> -	{ IMX8QM_ENET1_REF_DIV, "ENET1_REF" },
>>>> -	{ IMX8QM_ENET1_PTP_CLK, "ENET1_PTP" },
>>>> +static struct imx8_clks imx8qm_clks[] = {
>>>> +	CLK_4( IMX8QM_A53_DIV, "A53_DIV", SC_R_A53, SC_PM_CLK_CPU
>>>> ),
>>>> +	CLK_4( IMX8QM_A72_DIV, "A72_DIV", SC_R_A72, SC_PM_CLK_CPU
>>>> ),
>>>> +	CLK_4( IMX8QM_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_LVDS0_I2C0_DIV, "LVDS0 I2C0 DIV",
>>>> SC_R_LVDS_0_I2C_0, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_LVDS0_I2C1_DIV, "LVDS0 I2C1 DIV",
>>>> SC_R_LVDS_0_I2C_1, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_LVDS1_I2C0_DIV, "LVDS1 I2C0 DIV",
>>>> SC_R_LVDS_1_I2C_0, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_LVDS1_I2C1_DIV, "LVDS1 I2C1 DIV",
>>>> SC_R_LVDS_1_I2C_1, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
>>>> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QM_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
>>>> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QM_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
>>>> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QM_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
>>>> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QM_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
>>>> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_CSI1_I2C0_DIV, "CSI1 I2C0_DIV",
>>>> SC_R_CSI_1_I2C_0, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_HDMI_I2C0_DIV, "HDMI I2C0_DIV",
>>>> SC_R_HDMI_I2C_0, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QM_HDMI_IPG_CLK, "HDMI IPG_CLK", SC_R_HDMI,
>>>> SC_PM_CLK_MISC ),
>>>> +	CLK_4( IMX8QM_HDMI_RX_I2C0_DIV, "HDMI RX I2C_DIV",
>>>> SC_R_HDMI_RX_I2C_0, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QM_UART0_DIV, "UART0_DIV", SC_R_UART_0,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_UART1_DIV, "UART1_DIV", SC_R_UART_1,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_UART2_DIV, "UART2_DIV", SC_R_UART_2,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_UART3_DIV, "UART3_DIV", SC_R_UART_3,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_ENET0_ROOT_DIV, "ENET0_ROOT_DIV",
>>>> SC_R_ENET_0, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
>>>> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
>>>> +	CLK_4( IMX8QM_ENET1_ROOT_DIV, "ENET1_ROOT_DIV",
>>>> SC_R_ENET_1, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
>>>> SC_R_ENET_1, SC_PM_CLK_MISC0 ), +
>>>> +	CLK_4( IMX8QM_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QM_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
>>>> SC_PM_CLK_MST_BUS ),
>>>> +	CLK_4( IMX8QM_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
>>>> SC_PM_CLK_MISC ), +
>>>> +	CLK_4( IMX8QM_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
>>>> SC_PM_CLK_PER ), +
>>>> +	CLK_4( IMX8QM_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND,
>>>> SC_PM_CLK_MST_BUS ),
>>>> +	CLK_4( IMX8QM_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
>>>> SC_PM_CLK_PER ), };
>>>>  
>>>> -int num_clks = ARRAY_SIZE(imx8_clk_names);
>>>> -#endif
>>>> -
>>>> -ulong imx8_clk_get_rate(struct clk *clk)
>>>> -{
>>>> -	sc_pm_clk_t pm_clk;
>>>> -	ulong rate;
>>>> -	u16 resource;
>>>> -	int ret;
>>>> -
>>>> -	debug("%s(#%lu)\n", __func__, clk->id);
>>>> -
>>>> -	switch (clk->id) {
>>>> -	case IMX8QM_A53_DIV:
>>>> -		resource = SC_R_A53;
>>>> -		pm_clk = SC_PM_CLK_CPU;
>>>> -		break;
>>>> -	case IMX8QM_I2C0_CLK:
>>>> -		resource = SC_R_I2C_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_I2C1_CLK:
>>>> -		resource = SC_R_I2C_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_I2C2_CLK:
>>>> -		resource = SC_R_I2C_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_I2C3_CLK:
>>>> -		resource = SC_R_I2C_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_SDHC0_IPG_CLK:
>>>> -	case IMX8QM_SDHC0_CLK:
>>>> -	case IMX8QM_SDHC0_DIV:
>>>> -		resource = SC_R_SDHC_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_SDHC1_IPG_CLK:
>>>> -	case IMX8QM_SDHC1_CLK:
>>>> -	case IMX8QM_SDHC1_DIV:
>>>> -		resource = SC_R_SDHC_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_SDHC2_IPG_CLK:
>>>> -	case IMX8QM_SDHC2_CLK:
>>>> -	case IMX8QM_SDHC2_DIV:
>>>> -		resource = SC_R_SDHC_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART0_IPG_CLK:
>>>> -	case IMX8QM_UART0_CLK:
>>>> -		resource = SC_R_UART_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART1_CLK:
>>>> -		resource = SC_R_UART_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART2_CLK:
>>>> -		resource = SC_R_UART_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART3_CLK:
>>>> -		resource = SC_R_UART_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_ENET0_IPG_CLK:
>>>> -	case IMX8QM_ENET0_AHB_CLK:
>>>> -	case IMX8QM_ENET0_REF_DIV:
>>>> -	case IMX8QM_ENET0_PTP_CLK:
>>>> -		resource = SC_R_ENET_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_ENET1_IPG_CLK:
>>>> -	case IMX8QM_ENET1_AHB_CLK:
>>>> -	case IMX8QM_ENET1_REF_DIV:
>>>> -	case IMX8QM_ENET1_PTP_CLK:
>>>> -		resource = SC_R_ENET_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	default:
>>>> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
>>>> -		    clk->id >= IMX8QM_CLK_END) {
>>>> -			printf("%s(Invalid clk ID #%lu)\n",
>>>> -			       __func__, clk->id);
>>>> -			return -EINVAL;
>>>> -		}
>>>> -		return -ENOTSUPP;
>>>> -	};
>>>> -
>>>> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
>>>> -				   (sc_pm_clock_rate_t *)&rate);
>>>> -	if (ret) {
>>>> -		printf("%s err %d\n", __func__, ret);
>>>> -		return ret;
>>>> -	}
>>>> -
>>>> -	return rate;
>>>> -}
>>>> -
>>>> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
>>>> -{
>>>> -	sc_pm_clk_t pm_clk;
>>>> -	u32 new_rate = rate;
>>>> -	u16 resource;
>>>> -	int ret;
>>>> -
>>>> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
>>>> -
>>>> -	switch (clk->id) {
>>>> -	case IMX8QM_I2C0_CLK:
>>>> -		resource = SC_R_I2C_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_I2C1_CLK:
>>>> -		resource = SC_R_I2C_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_I2C2_CLK:
>>>> -		resource = SC_R_I2C_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_I2C3_CLK:
>>>> -		resource = SC_R_I2C_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART0_CLK:
>>>> -		resource = SC_R_UART_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART1_CLK:
>>>> -		resource = SC_R_UART_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART2_CLK:
>>>> -		resource = SC_R_UART_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART3_CLK:
>>>> -		resource = SC_R_UART_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_SDHC0_IPG_CLK:
>>>> -	case IMX8QM_SDHC0_CLK:
>>>> -	case IMX8QM_SDHC0_DIV:
>>>> -		resource = SC_R_SDHC_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_SDHC1_IPG_CLK:
>>>> -	case IMX8QM_SDHC1_CLK:
>>>> -	case IMX8QM_SDHC1_DIV:
>>>> -		resource = SC_R_SDHC_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_SDHC2_IPG_CLK:
>>>> -	case IMX8QM_SDHC2_CLK:
>>>> -	case IMX8QM_SDHC2_DIV:
>>>> -		resource = SC_R_SDHC_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_ENET0_IPG_CLK:
>>>> -	case IMX8QM_ENET0_AHB_CLK:
>>>> -	case IMX8QM_ENET0_REF_DIV:
>>>> -	case IMX8QM_ENET0_PTP_CLK:
>>>> -	case IMX8QM_ENET0_ROOT_DIV:
>>>> -		resource = SC_R_ENET_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_ENET1_IPG_CLK:
>>>> -	case IMX8QM_ENET1_AHB_CLK:
>>>> -	case IMX8QM_ENET1_REF_DIV:
>>>> -	case IMX8QM_ENET1_PTP_CLK:
>>>> -	case IMX8QM_ENET1_ROOT_DIV:
>>>> -		resource = SC_R_ENET_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	default:
>>>> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
>>>> -		    clk->id >= IMX8QM_CLK_END) {
>>>> -			printf("%s(Invalid clk ID #%lu)\n",
>>>> -			       __func__, clk->id);
>>>> -			return -EINVAL;
>>>> -		}
>>>> -		return -ENOTSUPP;
>>>> -	};
>>>> -
>>>> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk,
>>>> &new_rate);
>>>> -	if (ret) {
>>>> -		printf("%s err %d\n", __func__, ret);
>>>> -		return ret;
>>>> -	}
>>>> -
>>>> -	return new_rate;
>>>> -}
>>>> -
>>>> -int __imx8_clk_enable(struct clk *clk, bool enable)
>>>> -{
>>>> -	sc_pm_clk_t pm_clk;
>>>> -	u16 resource;
>>>> -	int ret;
>>>> +static struct imx8_fixed_clks imx8qm_fixed_clks[] = {
>>>> +	CLK_3( IMX8QM_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", SC_83MHZ
>>>> ),
>>>> +	CLK_3( IMX8QM_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK",
>>>> SC_166MHZ ),
>>>> +	CLK_3( IMX8QM_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK",
>>>> SC_333MHZ ),
>>>> +	CLK_3( IMX8QM_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ
>>>> ),
>>>> +	CLK_3( IMX8QM_IPG_MIPI_CSI_CLK_ROOT, "IPG_MIPI_CLK",
>>>> SC_120MHZ ),
>>>> +	CLK_3( IMX8QM_LVDS_IPG_CLK, "IPG_LVDS_CLK", SC_24MHZ ),
>>>> +	CLK_3( IMX8QM_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
>>>> +	CLK_3( IMX8QM_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
>>>> +	CLK_3( IMX8QM_MIPI0_CLK_ROOT, "MIPI0_CLK", SC_120MHZ ),
>>>> +	CLK_3( IMX8QM_MIPI1_CLK_ROOT, "MIPI1_CLK", SC_120MHZ ),
>>>> +	CLK_3( IMX8QM_HDMI_RX_IPG_CLK, "HDMI_RX_IPG_CLK",
>>>> SC_200MHZ ), +};
>>>>  
>>>> -	debug("%s(#%lu)\n", __func__, clk->id);
>>>> +static struct imx8_gpr_clks imx8qm_gpr_clks[] = {
>>>> +	CLK_5( IMX8QM_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0,
>>>> SC_C_CLKDIV, IMX8QM_ENET0_ROOT_DIV ),
>>>> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL,
>>>> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
>>>> +	CLK_4( IMX8QM_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
>>>> SC_R_ENET_0, SC_C_TXCLK ),
>>>> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK,
>>>> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
>>>> +	CLK_4( IMX8QM_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
>>>> SC_R_ENET_0, SC_C_DISABLE_50 ), +
>>>> +	CLK_5( IMX8QM_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1,
>>>> SC_C_CLKDIV, IMX8QM_ENET1_ROOT_DIV ),
>>>> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL,
>>>> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
>>>> +	CLK_4( IMX8QM_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
>>>> SC_R_ENET_1, SC_C_TXCLK ),
>>>> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK,
>>>> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
>>>> +	CLK_4( IMX8QM_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
>>>> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
>>>>  
>>>> -	switch (clk->id) {
>>>> -	case IMX8QM_I2C0_CLK:
>>>> -		resource = SC_R_I2C_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_I2C1_CLK:
>>>> -		resource = SC_R_I2C_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_I2C2_CLK:
>>>> -		resource = SC_R_I2C_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_I2C3_CLK:
>>>> -		resource = SC_R_I2C_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART0_CLK:
>>>> -		resource = SC_R_UART_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART1_CLK:
>>>> -		resource = SC_R_UART_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART2_CLK:
>>>> -		resource = SC_R_UART_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_UART3_CLK:
>>>> -		resource = SC_R_UART_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_SDHC0_IPG_CLK:
>>>> -	case IMX8QM_SDHC0_CLK:
>>>> -	case IMX8QM_SDHC0_DIV:
>>>> -		resource = SC_R_SDHC_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_SDHC1_IPG_CLK:
>>>> -	case IMX8QM_SDHC1_CLK:
>>>> -	case IMX8QM_SDHC1_DIV:
>>>> -		resource = SC_R_SDHC_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_SDHC2_IPG_CLK:
>>>> -	case IMX8QM_SDHC2_CLK:
>>>> -	case IMX8QM_SDHC2_DIV:
>>>> -		resource = SC_R_SDHC_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_ENET0_IPG_CLK:
>>>> -	case IMX8QM_ENET0_AHB_CLK:
>>>> -	case IMX8QM_ENET0_REF_DIV:
>>>> -	case IMX8QM_ENET0_PTP_CLK:
>>>> -		resource = SC_R_ENET_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QM_ENET1_IPG_CLK:
>>>> -	case IMX8QM_ENET1_AHB_CLK:
>>>> -	case IMX8QM_ENET1_REF_DIV:
>>>> -	case IMX8QM_ENET1_PTP_CLK:
>>>> -		resource = SC_R_ENET_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	default:
>>>> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
>>>> -		    clk->id >= IMX8QM_CLK_END) {
>>>> -			printf("%s(Invalid clk ID #%lu)\n",
>>>> -			       __func__, clk->id);
>>>> -			return -EINVAL;
>>>> -		}
>>>> -		return -ENOTSUPP;
>>>> -	}
>>>> +static struct imx8_lpcg_clks imx8qm_lpcg_clks[] = {
>>>> +	CLK_5( IMX8QM_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
>>>> IMX8QM_I2C0_DIV ),
>>>> +	CLK_5( IMX8QM_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG,
>>>> IMX8QM_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
>>>> IMX8QM_I2C1_DIV ),
>>>> +	CLK_5( IMX8QM_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG,
>>>> IMX8QM_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
>>>> IMX8QM_I2C2_DIV ),
>>>> +	CLK_5( IMX8QM_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG,
>>>> IMX8QM_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
>>>> IMX8QM_I2C3_DIV ),
>>>> +	CLK_5( IMX8QM_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG,
>>>> IMX8QM_IPG_DMA_CLK_ROOT ), +
>>>> +	CLK_5( IMX8QM_LVDS0_I2C0_CLK, "LVDS0_I2C0_CLK", 0,
>>>> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS0_I2C0_DIV ),
>>>> +	CLK_5( IMX8QM_LVDS0_I2C0_IPG_CLK, "LVDS0_I2C0_IPG", 16,
>>>> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
>>>> +	CLK_5( IMX8QM_LVDS0_I2C1_CLK, "LVDS0_I2C1_CLK", 0,
>>>> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS0_I2C1_DIV ),
>>>> +	CLK_5( IMX8QM_LVDS0_I2C1_IPG_CLK, "LVDS0_I2C1_IPG", 16,
>>>> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ),
>>>> +	CLK_5( IMX8QM_LVDS1_I2C0_CLK, "LVDS1_I2C0_CLK", 0,
>>>> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS1_I2C0_DIV ),
>>>> +	CLK_5( IMX8QM_LVDS1_I2C0_IPG_CLK, "LVDS1_I2C0_IPG", 16,
>>>> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
>>>> +	CLK_5( IMX8QM_LVDS1_I2C1_CLK, "LVDS1_I2C1_CLK", 0,
>>>> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS1_I2C1_DIV ),
>>>> +	CLK_5( IMX8QM_LVDS1_I2C1_IPG_CLK, "LVDS1_I2C1_IPG", 16,
>>>> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ), +
>>>> +	CLK_5( IMX8QM_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
>>>> MIPI_DSI_0_LPCG + 0x1c, IMX8QM_MIPI0_I2C0_DIV ),
>>>> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 0,
>>>> MIPI_DSI_0_LPCG + 0x14,  IMX8QM_MIPI0_I2C0_IPG_S_CLK),
>>>> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_S_CLK, "MIPI0_I2C0_IPG_S", 0,
>>>> MIPI_DSI_0_LPCG + 0x18, IMX8QM_MIPI0_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
>>>> MIPI_DSI_0_LPCG + 0x2c, IMX8QM_MIPI0_I2C1_DIV ),
>>>> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 0,
>>>> MIPI_DSI_0_LPCG + 0x24,  IMX8QM_MIPI0_I2C1_IPG_S_CLK),
>>>> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_S_CLK, "MIPI0_I2C1_IPG_S", 0,
>>>> MIPI_DSI_0_LPCG + 0x28, IMX8QM_MIPI0_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
>>>> MIPI_DSI_1_LPCG + 0x1c, IMX8QM_MIPI1_I2C0_DIV ),
>>>> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 0,
>>>> MIPI_DSI_1_LPCG + 0x14, IMX8QM_MIPI1_I2C0_IPG_S_CLK),
>>>> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_S_CLK, "MIPI1_I2C0_IPG_S", 0,
>>>> MIPI_DSI_1_LPCG + 0x18, IMX8QM_MIPI1_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
>>>> MIPI_DSI_1_LPCG + 0x2c, IMX8QM_MIPI1_I2C1_DIV ),
>>>> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 0,
>>>> MIPI_DSI_1_LPCG + 0x24, IMX8QM_MIPI1_I2C1_IPG_S_CLK),
>>>> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_S_CLK, "MIPI1_I2C1_IPG_S", 0,
>>>> MIPI_DSI_1_LPCG + 0x28, IMX8QM_MIPI1_CLK_ROOT ), +
>>>> +	CLK_5( IMX8QM_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
>>>> MIPI_CSI_0_LPCG + 0x14, IMX8QM_CSI0_I2C0_DIV ),
>>>> +	CLK_5( IMX8QM_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
>>>> MIPI_CSI_0_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_CSI1_I2C0_CLK, "CSI1_I2C0_CLK", 0,
>>>> MIPI_CSI_1_LPCG + 0x14, IMX8QM_CSI1_I2C0_DIV ),
>>>> +	CLK_5( IMX8QM_CSI1_I2C0_IPG_CLK, "CSI1_I2C0_IPG", 16,
>>>> MIPI_CSI_1_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_HDMI_I2C0_CLK, "HDMI_I2C0_CLK", 0,
>>>> DI_HDMI_LPCG, IMX8QM_HDMI_I2C0_DIV ),
>>>> +	CLK_5( IMX8QM_HDMI_I2C_IPG_CLK, "HDMI_I2C0_IPG", 16,
>>>> DI_HDMI_LPCG, IMX8QM_HDMI_IPG_CLK ),
>>>> +	CLK_5( IMX8QM_HDMI_RX_I2C_DIV_CLK, "HDMI RX_I2C_DIV_CLK",
>>>> 0, MIPI_DSI_0_LPCG + 0x14, IMX8QM_MIPI0_I2C0_DIV ),
>>>> +	CLK_5( IMX8QM_HDMI_RX_I2C0_CLK, "HDMI RX_I2C_CLK", 0,
>>>> MIPI_DSI_0_LPCG + 0x10, IMX8QM_HDMI_RX_I2C_DIV_CLK ),
>>>> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_CLK, "HDMI_RX_I2C_IPG", 0,
>>>> RX_HDMI_LPCG + 0x18,  IMX8QM_HDMI_RX_I2C_IPG_S_CLK),
>>>> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_S_CLK, "HDMI_I2C_IPG_S", 0,
>>>> RX_HDMI_LPCG + 0x1c, IMX8QM_HDMI_RX_IPG_CLK ), +
>>>> +	CLK_5( IMX8QM_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
>>>> IMX8QM_UART0_DIV ),
>>>> +	CLK_5( IMX8QM_UART0_IPG_CLK, "UART0_IPG", 16,
>>>> LPUART_0_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
>>>> IMX8QM_UART1_DIV ),
>>>> +	CLK_5( IMX8QM_UART1_IPG_CLK, "UART1_IPG", 16,
>>>> LPUART_1_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
>>>> IMX8QM_UART2_DIV ),
>>>> +	CLK_5( IMX8QM_UART2_IPG_CLK, "UART2_IPG", 16,
>>>> LPUART_2_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
>>>> IMX8QM_UART3_DIV ),
>>>> +	CLK_5( IMX8QM_UART3_IPG_CLK, "UART3_IPG", 16,
>>>> LPUART_3_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ), +
>>>> +	CLK_5( IMX8QM_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
>>>> IMX8QM_SDHC0_DIV ),
>>>> +	CLK_5( IMX8QM_SDHC0_IPG_CLK, "SDHC0_IPG", 16,
>>>> USDHC_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
>>>> IMX8QM_SDHC1_DIV ),
>>>> +	CLK_5( IMX8QM_SDHC1_IPG_CLK, "SDHC1_IPG", 16,
>>>> USDHC_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
>>>> IMX8QM_SDHC2_DIV ),
>>>> +	CLK_5( IMX8QM_SDHC2_IPG_CLK, "SDHC2_IPG", 16,
>>>> USDHC_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), +
>>>> +	CLK_5( IMX8QM_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
>>>> ENET_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG,
>>>> IMX8QM_ENET0_IPG_S_CLK ),
>>>> +	CLK_5( IMX8QM_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG,
>>>> IMX8QM_AXI_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
>>>> IMX8QM_ENET0_ROOT_DIV ),
>>>> +	CLK_5( IMX8QM_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG,
>>>> IMX8QM_ENET0_ROOT_DIV  ),
>>>> +	CLK_5( IMX8QM_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
>>>> ENET_0_LPCG, IMX8QM_ENET0_RMII_TX_SEL  ),
>>>> +	CLK_5( IMX8QM_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
>>>> ENET_0_LPCG + 0x4, IMX8QM_ENET0_RGMII_DIV  ), +
>>>> +	CLK_5( IMX8QM_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
>>>> ENET_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG,
>>>> IMX8QM_ENET1_IPG_S_CLK ),
>>>> +	CLK_5( IMX8QM_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG,
>>>> IMX8QM_AXI_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
>>>> IMX8QM_ENET1_ROOT_DIV ),
>>>> +	CLK_5( IMX8QM_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG,
>>>> IMX8QM_ENET1_ROOT_DIV  ),
>>>> +	CLK_5( IMX8QM_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
>>>> ENET_1_LPCG, IMX8QM_ENET1_RMII_TX_SEL  ),
>>>> +	CLK_5( IMX8QM_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
>>>> ENET_1_LPCG + 0x4, IMX8QM_ENET1_RGMII_DIV  ), +
>>>> +	CLK_5( IMX8QM_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18,
>>>> FSPI_0_LPCG, IMX8QM_LSIO_BUS_CLK ),
>>>> +	CLK_5( IMX8QM_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14,
>>>> FSPI_0_LPCG, IMX8QM_FSPI0_IPG_S_CLK ),
>>>> +	CLK_5( IMX8QM_FSPI0_HCLK, "FSPI0_HCLK", 0x10, FSPI_0_LPCG,
>>>> IMX8QM_LSIO_MEM_CLK ),
>>>> +	CLK_5( IMX8QM_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG,
>>>> IMX8QM_FSPI0_DIV ), +
>>>> +	CLK_5( IMX8QM_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
>>>> USB_2_LPCG, IMX8QM_AHB_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
>>>> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_USB2_OH_IPG_S_PL301_CLK,
>>>> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
>>>> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), +
>>>> +	CLK_5( IMX8QM_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
>>>> IMX8QM_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG,
>>>> IMX8QM_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
>>>> IMX8QM_USB3_IPG_CLK ),
>>>> +	CLK_5( IMX8QM_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
>>>> IMX8QM_USB3_ACLK_DIV ),
>>>> +	CLK_5( IMX8QM_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
>>>> IMX8QM_USB3_BUS_DIV ),
>>>> +	CLK_5( IMX8QM_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
>>>> IMX8QM_USB3_LPM_DIV ), +
>>>> +	CLK_5( IMX8QM_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
>>>> IMX8QM_AXI_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
>>>> NAND_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QM_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4,
>>>> NAND_LPCG, IMX8QM_GPMI_BCH_IO_DIV ),
>>>> +	CLK_5( IMX8QM_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG,
>>>> IMX8QM_GPMI_BCH_DIV ),
>>>> +	CLK_5( IMX8QM_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG +
>>>> 0x4, IMX8QM_AXI_CONN_CLK_ROOT ), +};
>>>>  
>>>> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
>>>> -	if (ret) {
>>>> -		printf("%s err %d\n", __func__, ret);
>>>> -		return ret;
>>>> -	}
>>>> +struct imx8_mux_clks imx8qm_mux_clks[] = {
>>>> +};
>>>>  
>>>> -	return 0;
>>>> -}
>>>> +struct imx8_clks_collect imx8qm_clk_collect = {
>>>> +	{
>>>> +		{&imx8qm_clks, ARRAY_SIZE(imx8qm_clks)},
>>>> +		{&imx8qm_fixed_clks,
>>>> ARRAY_SIZE(imx8qm_fixed_clks)},
>>>> +		{&imx8qm_gpr_clks, ARRAY_SIZE(imx8qm_gpr_clks)},
>>>> +		{&imx8qm_lpcg_clks, ARRAY_SIZE(imx8qm_lpcg_clks)},
>>>> +		{&imx8qm_mux_clks, ARRAY_SIZE(imx8qm_mux_clks)},
>>>> +	},
>>>> +	FLAG_CLK_IMX8_IMX8QM,
>>>> +};
>>>> diff --git a/drivers/clk/imx/clk-imx8qxp.c
>>>> b/drivers/clk/imx/clk-imx8qxp.c index 1fca36a..8181a97 100644
>>>> --- a/drivers/clk/imx/clk-imx8qxp.c
>>>> +++ b/drivers/clk/imx/clk-imx8qxp.c
>>>> @@ -12,300 +12,156 @@
>>>>  #include <dt-bindings/clock/imx8qxp-clock.h>
>>>>  #include <dt-bindings/soc/imx_rsrc.h>
>>>>  #include <misc.h>
>>>> +#include <asm/arch/lpcg.h>
>>>>  
>>>>  #include "clk-imx8.h"
>>>>  
>>>> -#if CONFIG_IS_ENABLED(CMD_CLK)
>>>> -struct imx8_clks imx8_clk_names[] = {
>>>> -	{ IMX8QXP_A35_DIV, "A35_DIV" },
>>>> -	{ IMX8QXP_I2C0_CLK, "I2C0" },
>>>> -	{ IMX8QXP_I2C1_CLK, "I2C1" },
>>>> -	{ IMX8QXP_I2C2_CLK, "I2C2" },
>>>> -	{ IMX8QXP_I2C3_CLK, "I2C3" },
>>>> -	{ IMX8QXP_UART0_CLK, "UART0" },
>>>> -	{ IMX8QXP_UART1_CLK, "UART1" },
>>>> -	{ IMX8QXP_UART2_CLK, "UART2" },
>>>> -	{ IMX8QXP_UART3_CLK, "UART3" },
>>>> -	{ IMX8QXP_SDHC0_CLK, "SDHC0" },
>>>> -	{ IMX8QXP_SDHC1_CLK, "SDHC1" },
>>>> -	{ IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" },
>>>> -	{ IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" },
>>>> -	{ IMX8QXP_ENET0_REF_DIV, "ENET0_REF" },
>>>> -	{ IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" },
>>>> -	{ IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" },
>>>> -	{ IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" },
>>>> -	{ IMX8QXP_ENET1_REF_DIV, "ENET1_REF" },
>>>> -	{ IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" },
>>>> +static struct imx8_clks imx8qxp_clks[] = {
>>>> +	CLK_4( IMX8QXP_A35_DIV, "A35_DIV", SC_R_A35,
>>>> SC_PM_CLK_CPU ),
>>>> +	CLK_4( IMX8QXP_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
>>>> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QXP_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
>>>> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QXP_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
>>>> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QXP_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
>>>> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
>>>> +	CLK_4( IMX8QXP_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
>>>> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_UART0_DIV, "UART0_DIV", SC_R_UART_0,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_UART1_DIV, "UART1_DIV", SC_R_UART_1,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_UART2_DIV, "UART2_DIV", SC_R_UART_2,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_UART3_DIV, "UART3_DIV", SC_R_UART_3,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_ENET0_ROOT_DIV, "ENET0_ROOT_DIV",
>>>> SC_R_ENET_0, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
>>>> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
>>>> +	CLK_4( IMX8QXP_ENET1_ROOT_DIV, "ENET1_ROOT_DIV",
>>>> SC_R_ENET_1, SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
>>>> SC_R_ENET_1, SC_PM_CLK_MISC0 ),
>>>> +	CLK_4( IMX8QXP_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
>>>> SC_PM_CLK_MST_BUS ),
>>>> +	CLK_4( IMX8QXP_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
>>>> SC_PM_CLK_MISC ),
>>>> +	CLK_4( IMX8QXP_LSIO_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
>>>> SC_PM_CLK_PER ),
>>>> +	CLK_4( IMX8QXP_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND,
>>>> SC_PM_CLK_MST_BUS ),
>>>> +	CLK_4( IMX8QXP_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
>>>> SC_PM_CLK_PER ), };
>>>>  
>>>> -int num_clks = ARRAY_SIZE(imx8_clk_names);
>>>> -#endif
>>>> -
>>>> -ulong imx8_clk_get_rate(struct clk *clk)
>>>> -{
>>>> -	sc_pm_clk_t pm_clk;
>>>> -	ulong rate;
>>>> -	u16 resource;
>>>> -	int ret;
>>>> -
>>>> -	debug("%s(#%lu)\n", __func__, clk->id);
>>>> -
>>>> -	switch (clk->id) {
>>>> -	case IMX8QXP_A35_DIV:
>>>> -		resource = SC_R_A35;
>>>> -		pm_clk = SC_PM_CLK_CPU;
>>>> -		break;
>>>> -	case IMX8QXP_I2C0_CLK:
>>>> -		resource = SC_R_I2C_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_I2C1_CLK:
>>>> -		resource = SC_R_I2C_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_I2C2_CLK:
>>>> -		resource = SC_R_I2C_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_I2C3_CLK:
>>>> -		resource = SC_R_I2C_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_SDHC0_IPG_CLK:
>>>> -	case IMX8QXP_SDHC0_CLK:
>>>> -	case IMX8QXP_SDHC0_DIV:
>>>> -		resource = SC_R_SDHC_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_SDHC1_IPG_CLK:
>>>> -	case IMX8QXP_SDHC1_CLK:
>>>> -	case IMX8QXP_SDHC1_DIV:
>>>> -		resource = SC_R_SDHC_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART0_IPG_CLK:
>>>> -	case IMX8QXP_UART0_CLK:
>>>> -		resource = SC_R_UART_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART1_CLK:
>>>> -		resource = SC_R_UART_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART2_CLK:
>>>> -		resource = SC_R_UART_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART3_CLK:
>>>> -		resource = SC_R_UART_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_ENET0_IPG_CLK:
>>>> -	case IMX8QXP_ENET0_AHB_CLK:
>>>> -	case IMX8QXP_ENET0_REF_DIV:
>>>> -	case IMX8QXP_ENET0_PTP_CLK:
>>>> -		resource = SC_R_ENET_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_ENET1_IPG_CLK:
>>>> -	case IMX8QXP_ENET1_AHB_CLK:
>>>> -	case IMX8QXP_ENET1_REF_DIV:
>>>> -	case IMX8QXP_ENET1_PTP_CLK:
>>>> -		resource = SC_R_ENET_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	default:
>>>> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
>>>> -		    clk->id >= IMX8QXP_CLK_END) {
>>>> -			printf("%s(Invalid clk ID #%lu)\n",
>>>> -			       __func__, clk->id);
>>>> -			return -EINVAL;
>>>> -		}
>>>> -		return -ENOTSUPP;
>>>> -	};
>>>> -
>>>> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
>>>> -				   (sc_pm_clock_rate_t *)&rate);
>>>> -	if (ret) {
>>>> -		printf("%s err %d\n", __func__, ret);
>>>> -		return ret;
>>>> -	}
>>>> -
>>>> -	return rate;
>>>> -}
>>>> -
>>>> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
>>>> -{
>>>> -	sc_pm_clk_t pm_clk;
>>>> -	u32 new_rate = rate;
>>>> -	u16 resource;
>>>> -	int ret;
>>>> -
>>>> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
>>>> -
>>>> -	switch (clk->id) {
>>>> -	case IMX8QXP_I2C0_CLK:
>>>> -		resource = SC_R_I2C_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_I2C1_CLK:
>>>> -		resource = SC_R_I2C_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_I2C2_CLK:
>>>> -		resource = SC_R_I2C_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_I2C3_CLK:
>>>> -		resource = SC_R_I2C_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART0_CLK:
>>>> -		resource = SC_R_UART_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART1_CLK:
>>>> -		resource = SC_R_UART_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART2_CLK:
>>>> -		resource = SC_R_UART_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART3_CLK:
>>>> -		resource = SC_R_UART_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_SDHC0_IPG_CLK:
>>>> -	case IMX8QXP_SDHC0_CLK:
>>>> -	case IMX8QXP_SDHC0_DIV:
>>>> -		resource = SC_R_SDHC_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_SDHC1_SEL:
>>>> -	case IMX8QXP_SDHC0_SEL:
>>>> -		return 0;
>>>> -	case IMX8QXP_SDHC1_IPG_CLK:
>>>> -	case IMX8QXP_SDHC1_CLK:
>>>> -	case IMX8QXP_SDHC1_DIV:
>>>> -		resource = SC_R_SDHC_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_ENET0_IPG_CLK:
>>>> -	case IMX8QXP_ENET0_AHB_CLK:
>>>> -	case IMX8QXP_ENET0_REF_DIV:
>>>> -	case IMX8QXP_ENET0_PTP_CLK:
>>>> -		resource = SC_R_ENET_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_ENET1_IPG_CLK:
>>>> -	case IMX8QXP_ENET1_AHB_CLK:
>>>> -	case IMX8QXP_ENET1_REF_DIV:
>>>> -	case IMX8QXP_ENET1_PTP_CLK:
>>>> -		resource = SC_R_ENET_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	default:
>>>> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
>>>> -		    clk->id >= IMX8QXP_CLK_END) {
>>>> -			printf("%s(Invalid clk ID #%lu)\n",
>>>> -			       __func__, clk->id);
>>>> -			return -EINVAL;
>>>> -		}
>>>> -		return -ENOTSUPP;
>>>> -	};
>>>> -
>>>> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk,
>>>> &new_rate);
>>>> -	if (ret) {
>>>> -		printf("%s err %d\n", __func__, ret);
>>>> -		return ret;
>>>> -	}
>>>> -
>>>> -	return new_rate;
>>>> -}
>>>> -
>>>> -int __imx8_clk_enable(struct clk *clk, bool enable)
>>>> -{
>>>> -	sc_pm_clk_t pm_clk;
>>>> -	u16 resource;
>>>> -	int ret;
>>>> +static struct imx8_fixed_clks imx8qxp_fixed_clks[] = {
>>>> +	CLK_3( IMX8QXP_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK",
>>>> SC_83MHZ ),
>>>> +	CLK_3( IMX8QXP_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK",
>>>> SC_166MHZ ),
>>>> +	CLK_3( IMX8QXP_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK",
>>>> SC_333MHZ ),
>>>> +	CLK_3( IMX8QXP_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ
>>>> ),
>>>> +	CLK_3( IMX8QXP_MIPI_IPG_CLK, "IPG_MIPI_CLK", SC_120MHZ ),
>>>> +	CLK_3( IMX8QXP_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
>>>> +	CLK_3( IMX8QXP_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
>>>> +};
>>>>  
>>>> -	debug("%s(#%lu)\n", __func__, clk->id);
>>>> +static struct imx8_gpr_clks imx8qxp_gpr_clks[] = {
>>>> +	CLK_5( IMX8QXP_ENET0_REF_DIV, "ENET0_REF_DIV",
>>>> SC_R_ENET_0, SC_C_CLKDIV, IMX8QXP_ENET0_ROOT_DIV ),
>>>> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL,
>>>> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
>>>> +	CLK_4( IMX8QXP_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
>>>> SC_R_ENET_0, SC_C_TXCLK ),
>>>> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK,
>>>> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
>>>> +	CLK_4( IMX8QXP_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
>>>> SC_R_ENET_0, SC_C_DISABLE_50 ), +
>>>> +	CLK_5( IMX8QXP_ENET1_REF_DIV, "ENET1_REF_DIV",
>>>> SC_R_ENET_1, SC_C_CLKDIV, IMX8QXP_ENET1_ROOT_DIV ),
>>>> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL,
>>>> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
>>>> +	CLK_4( IMX8QXP_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
>>>> SC_R_ENET_1, SC_C_TXCLK ),
>>>> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK,
>>>> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
>>>> +	CLK_4( IMX8QXP_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
>>>> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
>>>>  
>>>> -	switch (clk->id) {
>>>> -	case IMX8QXP_I2C0_CLK:
>>>> -		resource = SC_R_I2C_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_I2C1_CLK:
>>>> -		resource = SC_R_I2C_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_I2C2_CLK:
>>>> -		resource = SC_R_I2C_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_I2C3_CLK:
>>>> -		resource = SC_R_I2C_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART0_CLK:
>>>> -		resource = SC_R_UART_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART1_CLK:
>>>> -		resource = SC_R_UART_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART2_CLK:
>>>> -		resource = SC_R_UART_2;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_UART3_CLK:
>>>> -		resource = SC_R_UART_3;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_SDHC0_IPG_CLK:
>>>> -	case IMX8QXP_SDHC0_CLK:
>>>> -	case IMX8QXP_SDHC0_DIV:
>>>> -		resource = SC_R_SDHC_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_SDHC1_IPG_CLK:
>>>> -	case IMX8QXP_SDHC1_CLK:
>>>> -	case IMX8QXP_SDHC1_DIV:
>>>> -		resource = SC_R_SDHC_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_ENET0_IPG_CLK:
>>>> -	case IMX8QXP_ENET0_AHB_CLK:
>>>> -	case IMX8QXP_ENET0_REF_DIV:
>>>> -	case IMX8QXP_ENET0_PTP_CLK:
>>>> -		resource = SC_R_ENET_0;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	case IMX8QXP_ENET1_IPG_CLK:
>>>> -	case IMX8QXP_ENET1_AHB_CLK:
>>>> -	case IMX8QXP_ENET1_REF_DIV:
>>>> -	case IMX8QXP_ENET1_PTP_CLK:
>>>> -		resource = SC_R_ENET_1;
>>>> -		pm_clk = SC_PM_CLK_PER;
>>>> -		break;
>>>> -	default:
>>>> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
>>>> -		    clk->id >= IMX8QXP_CLK_END) {
>>>> -			printf("%s(Invalid clk ID #%lu)\n",
>>>> -			       __func__, clk->id);
>>>> -			return -EINVAL;
>>>> -		}
>>>> -		return -ENOTSUPP;
>>>> -	}
>>>> +static struct imx8_lpcg_clks imx8qxp_lpcg_clks[] = {
>>>> +	CLK_5( IMX8QXP_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
>>>> IMX8QXP_I2C0_DIV ),
>>>> +	CLK_5( IMX8QXP_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG,
>>>> IMX8QXP_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
>>>> IMX8QXP_I2C1_DIV ),
>>>> +	CLK_5( IMX8QXP_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG,
>>>> IMX8QXP_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
>>>> IMX8QXP_I2C2_DIV ),
>>>> +	CLK_5( IMX8QXP_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG,
>>>> IMX8QXP_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
>>>> IMX8QXP_I2C3_DIV ),
>>>> +	CLK_5( IMX8QXP_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG,
>>>> IMX8QXP_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
>>>> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI0_I2C0_DIV ),
>>>> +	CLK_5( IMX8QXP_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 16,
>>>> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
>>>> +	CLK_5( IMX8QXP_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
>>>> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI0_I2C1_DIV ),
>>>> +	CLK_5( IMX8QXP_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 16,
>>>> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
>>>> +	CLK_5( IMX8QXP_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
>>>> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI1_I2C0_DIV ),
>>>> +	CLK_5( IMX8QXP_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 16,
>>>> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
>>>> +	CLK_5( IMX8QXP_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
>>>> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI1_I2C1_DIV ),
>>>> +	CLK_5( IMX8QXP_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 16,
>>>> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
>>>> +	CLK_5( IMX8QXP_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
>>>> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_CSI0_I2C0_DIV ),
>>>> +	CLK_5( IMX8QXP_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
>>>> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ), +
>>>> +	CLK_5( IMX8QXP_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
>>>> IMX8QXP_UART0_DIV ),
>>>> +	CLK_5( IMX8QXP_UART0_IPG_CLK, "UART0_IPG", 16,
>>>> LPUART_0_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
>>>> IMX8QXP_UART1_DIV ),
>>>> +	CLK_5( IMX8QXP_UART1_IPG_CLK, "UART1_IPG", 16,
>>>> LPUART_1_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
>>>> IMX8QXP_UART2_DIV ),
>>>> +	CLK_5( IMX8QXP_UART2_IPG_CLK, "UART2_IPG", 16,
>>>> LPUART_2_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
>>>> IMX8QXP_UART3_DIV ),
>>>> +	CLK_5( IMX8QXP_UART3_IPG_CLK, "UART3_IPG", 16,
>>>> LPUART_3_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ), +
>>>> +	CLK_5( IMX8QXP_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
>>>> IMX8QXP_SDHC0_DIV ),
>>>> +	CLK_5( IMX8QXP_SDHC0_IPG_CLK, "SDHC0_IPG", 16,
>>>> USDHC_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
>>>> IMX8QXP_SDHC1_DIV ),
>>>> +	CLK_5( IMX8QXP_SDHC1_IPG_CLK, "SDHC1_IPG", 16,
>>>> USDHC_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
>>>> IMX8QXP_SDHC2_DIV ),
>>>> +	CLK_5( IMX8QXP_SDHC2_IPG_CLK, "SDHC2_IPG", 16,
>>>> USDHC_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), +
>>>> +	CLK_5( IMX8QXP_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
>>>> ENET_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG", 16,
>>>> ENET_0_LPCG, IMX8QXP_ENET0_IPG_S_CLK ),
>>>> +	CLK_5( IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG,
>>>> IMX8QXP_AXI_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
>>>> IMX8QXP_ENET0_ROOT_DIV ),
>>>> +	CLK_5( IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG,
>>>> IMX8QXP_ENET0_ROOT_DIV  ),
>>>> +	CLK_5( IMX8QXP_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
>>>> ENET_0_LPCG, IMX8QXP_ENET0_RMII_TX_SEL  ),
>>>> +	CLK_5( IMX8QXP_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
>>>> ENET_0_LPCG + 0x4, IMX8QXP_ENET0_RGMII_DIV  ), +
>>>> +	CLK_5( IMX8QXP_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
>>>> ENET_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG", 16,
>>>> ENET_1_LPCG, IMX8QXP_ENET1_IPG_S_CLK ),
>>>> +	CLK_5( IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG,
>>>> IMX8QXP_AXI_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
>>>> IMX8QXP_ENET1_ROOT_DIV ),
>>>> +	CLK_5( IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG,
>>>> IMX8QXP_ENET1_ROOT_DIV  ),
>>>> +	CLK_5( IMX8QXP_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
>>>> ENET_1_LPCG, IMX8QXP_ENET1_RMII_TX_SEL  ),
>>>> +	CLK_5( IMX8QXP_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
>>>> ENET_1_LPCG + 0x4, IMX8QXP_ENET1_RGMII_DIV  ), +
>>>> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18,
>>>> FSPI_0_LPCG, IMX8QXP_LSIO_BUS_CLK ),
>>>> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14,
>>>> FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_IPG_S_CLK ),
>>>> +	CLK_5( IMX8QXP_LSIO_FSPI0_HCLK, "FSPI0_HCLK", 0x10,
>>>> FSPI_0_LPCG, IMX8QXP_LSIO_MEM_CLK ),
>>>> +	CLK_5( IMX8QXP_LSIO_FSPI0_CLK, "FSPI0_CLK", 0,
>>>> FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_DIV ), +
>>>> +	CLK_5( IMX8QXP_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
>>>> USB_2_LPCG, IMX8QXP_AHB_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
>>>> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_PL301_CLK,
>>>> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
>>>> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), +
>>>> +	CLK_5( IMX8QXP_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
>>>> IMX8QXP_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_USB3_CORE_PCLK, "USB3_CORE", 20,
>>>> USB_3_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
>>>> IMX8QXP_USB3_IPG_CLK ),
>>>> +	CLK_5( IMX8QXP_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
>>>> IMX8QXP_USB3_ACLK_DIV ),
>>>> +	CLK_5( IMX8QXP_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
>>>> IMX8QXP_USB3_BUS_DIV ),
>>>> +	CLK_5( IMX8QXP_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
>>>> IMX8QXP_USB3_LPM_DIV ), +
>>>> +	CLK_5( IMX8QXP_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
>>>> IMX8QXP_AXI_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
>>>> NAND_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
>>>> +	CLK_5( IMX8QXP_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4,
>>>> NAND_LPCG, IMX8QXP_GPMI_BCH_IO_DIV ),
>>>> +	CLK_5( IMX8QXP_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG,
>>>> IMX8QXP_GPMI_BCH_DIV ),
>>>> +	CLK_5( IMX8QXP_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG +
>>>> 0x4, IMX8QXP_AXI_CONN_CLK_ROOT ), +};
>>>>  
>>>> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
>>>> -	if (ret) {
>>>> -		printf("%s err %d\n", __func__, ret);
>>>> -		return ret;
>>>> -	}
>>>> +struct imx8_mux_clks imx8qxp_mux_clks[] = {
>>>> +	CLK_MUX( IMX8QXP_SDHC0_SEL, "SDHC0_SEL",
>>>> IMX8QXP_SDHC0_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
>>>> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
>>>> IMX8QXP_CLK_DUMMY ),
>>>> +	CLK_MUX( IMX8QXP_SDHC1_SEL, "SDHC1_SEL",
>>>> IMX8QXP_SDHC1_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
>>>> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
>>>> IMX8QXP_CLK_DUMMY ),
>>>> +	CLK_MUX( IMX8QXP_SDHC2_SEL, "SDHC2_SEL",
>>>> IMX8QXP_SDHC2_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
>>>> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
>>>> IMX8QXP_CLK_DUMMY ), +};
>>>>  
>>>> -	return 0;
>>>> -}
>>>> +struct imx8_clks_collect imx8qxp_clk_collect = {
>>>> +	{
>>>> +		{&imx8qxp_clks, ARRAY_SIZE(imx8qxp_clks)},
>>>> +		{&imx8qxp_fixed_clks,
>>>> ARRAY_SIZE(imx8qxp_fixed_clks)},
>>>> +		{&imx8qxp_gpr_clks, ARRAY_SIZE(imx8qxp_gpr_clks)},
>>>> +		{&imx8qxp_lpcg_clks,
>>>> ARRAY_SIZE(imx8qxp_lpcg_clks)},
>>>> +		{&imx8qxp_mux_clks, ARRAY_SIZE(imx8qxp_mux_clks)},
>>>> +	},
>>>> +	FLAG_CLK_IMX8_IMX8QXP,
>>>> +};  
>>>
>>>
>>>
>>>
>>> Best regards,
>>>
>>> Lukasz Majewski
>>>
>>> --
>>>
>>> DENX Software Engineering GmbH,      Managing Director: Wolfgang
>>> Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell,
>>> Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
>>> lukma at denx.de 
>>
> 
> 
> 
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
> 

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

* [U-Boot] [EXT] Re: [PATCH 3/5] clk: imx8: Update imx8 clock driver
  2019-07-10  8:25         ` Ye Li
@ 2019-07-10  8:46           ` Lukasz Majewski
  0 siblings, 0 replies; 14+ messages in thread
From: Lukasz Majewski @ 2019-07-10  8:46 UTC (permalink / raw)
  To: u-boot

On Wed, 10 Jul 2019 08:25:13 +0000
Ye Li <ye.li@nxp.com> wrote:

> Hi Lukasz,
> 
> > Hi Ye,
> >   
> >> Hi Lukasz,
> >>  
> >>> Hi Ye,
> >>>     
> >>>> Update imx8 clock driver to support LPCG and full clocks tree for
> >>>> some modules aligned with kernel.
> >>>>
> >>>> We classify the clock into serveral types: slice, fixed, lpcg,
> >>>> gpr and mux.    
> >>>
> >>> Is this code in sync with Linux kernel? Does the imx8 (in Linux
> >>> kernel) use the Common Clock Framework?    
> >> This patch syncs the tree architecture with kernel but not the
> >> codes. imx8 kernel clock driver uses common clock framework.
> >>  
> >>>     
> >>>> Generally slice and fixed clocks are the sources. lpcg, gpr
> >>>> and mux are the downstream of those sources and are used for
> >>>> gating, muxing or dividing functions.
> >>>>
> >>>> This patch replaces the functions defined in imx8qm and imx8qxp
> >>>> with the clock tables of different clock types. clk-imx8 use
> >>>> unified functions to process these clock tables.    
> >>>
> >>>
> >>> I've posted the Common Clock Framework v5 to the mailing list
> >>> recently: https://patchwork.ozlabs.org/cover/1121348/
> >>>
> >>>
> >>> So maybe this code could benefit from those patches and use this
> >>> infrastructure ?
> >>>     
> >> I think so. We will look into the CCF in u-boot and migrate it
> >> later.   
> > 
> > Sorry, but I'm involved in the open source U-Boot developement for
> > too long to believe in such statements.
> > 
> > If the feature is not added from the outset, then it will not be
> > changed.
> >   
> So when will CCF be pushed? 

It will be pulled when Simon ACKs it. It also may happen (and often
happens) that somebody from the community will lately jump in and we
would need to discuss it again.

> 
> Best regards,
> Ye Li
> >> But now we prefer upstream this update first. This one has been
> >> tested in downstream. And we have some driver patches going for
> >> upstream depending on it, while a new driver using CCF may need
> >> more time to get ready.
> >>
> >> Best regards,
> >> Ye Li  
> >>>>
> >>>> Note: since the clock depends on the power domain of its
> >>>> resource, must power on the resource firstly, then we can get
> >>>> the clock. Otherwise, we can't access lpcg. Thus, the clock dump
> >>>> only works for the slice clock.
> >>>>
> >>>> Signed-off-by: Ye Li <ye.li@nxp.com>
> >>>> ---
> >>>>  drivers/clk/imx/clk-imx8.c    | 304 +++++++++++++++++++++++++--
> >>>>  drivers/clk/imx/clk-imx8.h    |  83 +++++++-
> >>>>  drivers/clk/imx/clk-imx8qm.c  | 479
> >>>> ++++++++++++++++--------------------------
> >>>> drivers/clk/imx/clk-imx8qxp.c | 432
> >>>> +++++++++++++------------------------ 4 files changed, 689
> >>>> insertions(+), 609 deletions(-)
> >>>>
> >>>> diff --git a/drivers/clk/imx/clk-imx8.c
> >>>> b/drivers/clk/imx/clk-imx8.c index a755e26..afdb6ea 100644
> >>>> --- a/drivers/clk/imx/clk-imx8.c
> >>>> +++ b/drivers/clk/imx/clk-imx8.c
> >>>> @@ -12,32 +12,294 @@
> >>>>  #include <dt-bindings/clock/imx8qxp-clock.h>
> >>>>  #include <dt-bindings/soc/imx_rsrc.h>
> >>>>  #include <misc.h>
> >>>> +#include <asm/arch/lpcg.h>
> >>>>  
> >>>>  #include "clk-imx8.h"
> >>>>  
> >>>> -__weak ulong imx8_clk_get_rate(struct clk *clk)
> >>>> +struct imx8_clks_collect *soc_data[] = {
> >>>> +#ifdef CONFIG_IMX8QXP
> >>>> +	&imx8qxp_clk_collect,
> >>>> +#endif
> >>>> +#ifdef CONFIG_IMX8QM
> >>>> +	&imx8qm_clk_collect,
> >>>> +#endif
> >>>> +};
> >>>> +
> >>>> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id);
> >>>> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
> >>>> enable); +static ulong __imx8_clk_set_rate(struct udevice *dev,
> >>>> ulong id, unsigned long rate); +
> >>>> +static struct imx8_clks_collect * find_clks_collect(struct
> >>>> udevice *dev) +{
> >>>> +	ulong data = (ulong)dev_get_driver_data(dev);
> >>>> +	int i;
> >>>> +
> >>>> +	for (i = 0; i < ARRAY_SIZE(soc_data); i++) {
> >>>> +		if (soc_data[i]->match_flag == data)
> >>>> +			return soc_data[i];
> >>>> +	}
> >>>> +
> >>>> +	return NULL;
> >>>> +}
> >>>> +
> >>>> +static void * check_imx8_clk(struct udevice *dev, enum
> >>>> imx8_clk_type type, ulong id, u32 size_of_clk) +{
> >>>> +	u32 i, size;
> >>>> +	struct imx8_clks_collect *clks_col =
> >>>> find_clks_collect(dev);
> >>>> +	struct imx8_clk_header *hdr;
> >>>> +	ulong clks;
> >>>> +
> >>>> +	if (!clks_col || !(clks_col->clks[type].type_clks)) {
> >>>> +		printf("%s fails to get clks for type %d\n",
> >>>> +		       __func__, type);
> >>>> +		return NULL;
> >>>> +	}
> >>>> +
> >>>> +	clks = (ulong)(clks_col->clks[type].type_clks);
> >>>> +	size = clks_col->clks[type].num;
> >>>> +
> >>>> +	for (i = 0; i < size; i++) {
> >>>> +		hdr = (struct imx8_clk_header *)clks;
> >>>> +		if (id == hdr->id)
> >>>> +			return (void *)hdr;
> >>>> +
> >>>> +		clks += size_of_clk;
> >>>> +	}
> >>>> +
> >>>> +	return NULL;
> >>>> +}
> >>>> +
> >>>> +static ulong imx8_get_rate_lpcg(struct udevice *dev, struct
> >>>> imx8_lpcg_clks *lpcg_clk) +{
> >>>> +	if (lpcg_clk->parent_id != 0) {
> >>>> +		if (lpcg_is_clock_on(lpcg_clk->lpcg,
> >>>> lpcg_clk->bit_idx >> 2)) {
> >>>> +			return __imx8_clk_get_rate(dev,
> >>>> lpcg_clk->parent_id);
> >>>> +		} else {
> >>>> +			return 0;
> >>>> +		}
> >>>> +	} else {
> >>>> +		return -ENOSYS;
> >>>> +	}
> >>>> +}
> >>>> +
> >>>> +static ulong imx8_get_rate_slice(struct udevice *dev, struct
> >>>> imx8_clks *slice_clk) +{
> >>>> +	int ret;
> >>>> +	u32 rate;
> >>>> +
> >>>> +	ret = sc_pm_get_clock_rate(-1, slice_clk->rsrc,
> >>>> slice_clk->pm_clk,
> >>>> +				   (sc_pm_clock_rate_t *)&rate);
> >>>> +	if (ret) {
> >>>> +		printf("%s err %d\n", __func__, ret);
> >>>> +		return ret;
> >>>> +	}
> >>>> +
> >>>> +	return rate;
> >>>> +}
> >>>> +
> >>>> +static ulong imx8_get_rate_fixed(struct udevice *dev, struct
> >>>> imx8_fixed_clks *fixed_clk) +{
> >>>> +	return fixed_clk->rate;
> >>>> +}
> >>>> +
> >>>> +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id)
> >>>> +{
> >>>> +	void* clkdata;
> >>>> +
> >>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
> >>>> sizeof(struct imx8_lpcg_clks));
> >>>> +	if (clkdata) {
> >>>> +		return imx8_get_rate_lpcg(dev, (struct
> >>>> imx8_lpcg_clks *)clkdata);
> >>>> +	}
> >>>> +
> >>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
> >>>> sizeof(struct imx8_clks));
> >>>> +	if (clkdata) {
> >>>> +		return imx8_get_rate_slice(dev, (struct
> >>>> imx8_clks *)clkdata);
> >>>> +	}
> >>>> +
> >>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_FIXED, id,
> >>>> sizeof(struct imx8_fixed_clks));
> >>>> +	if (clkdata) {
> >>>> +		return imx8_get_rate_fixed(dev, (struct
> >>>> imx8_fixed_clks *)clkdata);
> >>>> +	}
> >>>> +
> >>>> +	return -ENOSYS;
> >>>> +}
> >>>> +
> >>>> +static ulong imx8_clk_get_rate(struct clk *clk)
> >>>> +{
> >>>> +	return __imx8_clk_get_rate(clk->dev, clk->id);
> >>>> +}
> >>>> +
> >>>> +static ulong imx8_set_rate_lpcg(struct udevice *dev, struct
> >>>> imx8_lpcg_clks *lpcg_clk, unsigned long rate) +{
> >>>> +	if (lpcg_clk->parent_id != 0) {
> >>>> +		return __imx8_clk_set_rate(dev,
> >>>> lpcg_clk->parent_id, rate);
> >>>> +	} else {
> >>>> +		return -ENOSYS;
> >>>> +	}
> >>>> +}
> >>>> +
> >>>> +static ulong imx8_set_rate_slice(struct udevice *dev, struct
> >>>> imx8_clks *slice_clk, unsigned long rate) +{
> >>>> +	int ret;
> >>>> +	u32 new_rate = rate;
> >>>> +
> >>>> +	ret = sc_pm_set_clock_rate(-1, slice_clk->rsrc,
> >>>> slice_clk->pm_clk, &new_rate);
> >>>> +	if (ret) {
> >>>> +		printf("%s err %d\n", __func__, ret);
> >>>> +		return ret;
> >>>> +	}
> >>>> +
> >>>> +	return new_rate;
> >>>> +}
> >>>> +
> >>>> +static ulong imx8_set_rate_gpr(struct udevice *dev, struct
> >>>> imx8_gpr_clks *gpr_clk, unsigned long rate) {
> >>>> +	ulong parent_rate;
> >>>> +	u32 val;
> >>>> +	int ret;
> >>>> +
> >>>> +	if (gpr_clk->parent_id == 0)
> >>>> +		return -ENOSYS;
> >>>> +
> >>>> +	parent_rate = __imx8_clk_get_rate(dev,
> >>>> gpr_clk->parent_id);
> >>>> +	if (parent_rate > 0) {
> >>>> +		val = (rate < parent_rate) ? 1 : 0;
> >>>> +
> >>>> +		ret = sc_misc_set_control(-1, gpr_clk->rsrc,
> >>>> +			gpr_clk->gpr_id, val);
> >>>> +		if (ret) {
> >>>> +			printf("%s err %d\n", __func__, ret);
> >>>> +			return ret;
> >>>> +		}
> >>>> +
> >>>> +		return rate;
> >>>> +	}
> >>>> +
> >>>> +	return -ENOSYS;
> >>>> +}
> >>>> +
> >>>> +static ulong __imx8_clk_set_rate(struct udevice *dev, ulong id,
> >>>> unsigned long rate) +{
> >>>> +	void* clkdata;
> >>>> +
> >>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
> >>>> sizeof(struct imx8_clks));
> >>>> +	if (clkdata) {
> >>>> +		return imx8_set_rate_slice(dev, (struct
> >>>> imx8_clks *)clkdata, rate);
> >>>> +	}
> >>>> +
> >>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
> >>>> sizeof(struct imx8_lpcg_clks));
> >>>> +	if (clkdata) {
> >>>> +		return imx8_set_rate_lpcg(dev, (struct
> >>>> imx8_lpcg_clks *)clkdata, rate);
> >>>> +	}
> >>>> +
> >>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_GPR, id,
> >>>> sizeof(struct imx8_gpr_clks));
> >>>> +	if (clkdata) {
> >>>> +		return imx8_set_rate_gpr(dev, (struct
> >>>> imx8_gpr_clks *)clkdata, rate);
> >>>> +	}
> >>>> +
> >>>> +	return -ENOSYS;
> >>>> +}
> >>>> +
> >>>> +static ulong imx8_clk_set_rate(struct clk *clk, unsigned long
> >>>> rate) +{
> >>>> +	return __imx8_clk_set_rate(clk->dev, clk->id, rate);
> >>>> +
> >>>> +}
> >>>> +
> >>>> +static int imx8_enable_slice(struct udevice *dev, struct
> >>>> imx8_clks *slice_clk, bool enable) +{
> >>>> +	int ret;
> >>>> +
> >>>> +	ret = sc_pm_clock_enable(-1, slice_clk->rsrc,
> >>>> slice_clk->pm_clk, enable, 0);
> >>>> +	if (ret) {
> >>>> +		printf("%s err %d\n", __func__, ret);
> >>>> +		return ret;
> >>>> +	}
> >>>> +
> >>>>  	return 0;
> >>>>  }
> >>>>  
> >>>> -__weak ulong imx8_clk_set_rate(struct clk *clk, unsigned long
> >>>> rate) +static int imx8_enable_lpcg(struct udevice *dev, struct
> >>>> imx8_lpcg_clks *lpcg_clk, bool enable) {
> >>>> +	if (enable) {
> >>>> +		if (lpcg_clk->parent_id != 0) {
> >>>> +			__imx8_clk_enable(dev,
> >>>> lpcg_clk->parent_id, enable);
> >>>> +		}
> >>>> +
> >>>> +		lpcg_clock_on(lpcg_clk->lpcg, lpcg_clk->bit_idx
> >>>> >> 2);
> >>>> +	} else {
> >>>> +		lpcg_clock_off(lpcg_clk->lpcg,
> >>>> lpcg_clk->bit_idx  
> >>>>>> 2); +  
> >>>> +		if (lpcg_clk->parent_id != 0) {
> >>>> +			__imx8_clk_enable(dev,
> >>>> lpcg_clk->parent_id, enable);
> >>>> +		}
> >>>> +	}
> >>>> +
> >>>>  	return 0;
> >>>>  }
> >>>>  
> >>>> -__weak int __imx8_clk_enable(struct clk *clk, bool enable)
> >>>> +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool
> >>>> enable) {
> >>>> -	return -ENOTSUPP;
> >>>> +	void* clkdata;
> >>>> +
> >>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id,
> >>>> sizeof(struct imx8_lpcg_clks));
> >>>> +	if (clkdata) {
> >>>> +		return imx8_enable_lpcg(dev, (struct
> >>>> imx8_lpcg_clks *)clkdata, enable);
> >>>> +	}
> >>>> +
> >>>> +	clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id,
> >>>> sizeof(struct imx8_clks));
> >>>> +	if (clkdata) {
> >>>> +		return imx8_enable_slice(dev, (struct imx8_clks
> >>>> *)clkdata, enable);
> >>>> +	}
> >>>> +
> >>>> +	return -ENOSYS;
> >>>>  }
> >>>>  
> >>>>  static int imx8_clk_disable(struct clk *clk)
> >>>>  {
> >>>> -	return __imx8_clk_enable(clk, 0);
> >>>> +	return __imx8_clk_enable(clk->dev, clk->id, 0);
> >>>>  }
> >>>>  
> >>>>  static int imx8_clk_enable(struct clk *clk)
> >>>>  {
> >>>> -	return __imx8_clk_enable(clk, 1);
> >>>> +	return __imx8_clk_enable(clk->dev, clk->id, 1);
> >>>> +}
> >>>> +
> >>>> +static int imx8_set_parent_mux(struct udevice *dev, struct
> >>>> imx8_mux_clks *mux_clk, ulong pid) +{
> >>>> +	u32 i;
> >>>> +	int ret;
> >>>> +	struct imx8_clks *slice_clkdata;
> >>>> +
> >>>> +	slice_clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE,
> >>>> mux_clk->slice_clk_id, sizeof(struct imx8_clks));
> >>>> +	if (!slice_clkdata) {
> >>>> +		printf("Error: fail to find slice clk %lu for
> >>>> this mux %lu\n", mux_clk->slice_clk_id, mux_clk->hdr.id);
> >>>> +		return -EINVAL;
> >>>> +	}
> >>>> +
> >>>> +	for (i = 0; i< CLK_IMX8_MAX_MUX_SEL; i++) {
> >>>> +		if (pid == mux_clk->parent_clks[i]) {
> >>>> +			ret = sc_pm_set_clock_parent(-1,
> >>>> slice_clkdata->rsrc,  slice_clkdata->pm_clk, i);
> >>>> +			if (ret)
> >>>> +				printf("Error: fail to set clock
> >>>> parent rsrc %d, pm_clk %d, parent clk %d\n",
> >>>> +					slice_clkdata->rsrc,
> >>>> slice_clkdata->pm_clk, i);
> >>>> +			return ret;
> >>>> +		}
> >>>> +	}
> >>>> +
> >>>> +	return -ENOSYS;
> >>>> +}
> >>>> +
> >>>> +static int imx8_clk_set_parent(struct clk *clk, struct clk
> >>>> *parent) +{
> >>>> +	void* clkdata;
> >>>> +
> >>>> +	clkdata = check_imx8_clk(clk->dev, IMX8_CLK_MUX,
> >>>> clk->id, sizeof(struct imx8_mux_clks));
> >>>> +	if (clkdata) {
> >>>> +		return imx8_set_parent_mux(clk->dev, (struct
> >>>> imx8_mux_clks *)clkdata, parent->id);
> >>>> +	}
> >>>> +
> >>>> +	return -ENOSYS;
> >>>>  }
> >>>>  
> >>>>  #if CONFIG_IS_ENABLED(CMD_CLK)
> >>>> @@ -47,6 +309,9 @@ int soc_clk_dump(void)
> >>>>  	struct clk clk;
> >>>>  	unsigned long rate;
> >>>>  	int i, ret;
> >>>> +	u32 size;
> >>>> +	struct imx8_clks *clks;
> >>>> +	struct imx8_clks_collect *clks_col;
> >>>>  
> >>>>  	ret = uclass_get_device_by_driver(UCLASS_CLK,
> >>>>  					  DM_GET_DRIVER(imx8_clk),
> >>>> &dev); @@ -55,8 +320,19 @@ int soc_clk_dump(void)
> >>>>  
> >>>>  	printf("Clk\t\tHz\n");
> >>>>  
> >>>> -	for (i = 0; i < num_clks; i++) {
> >>>> -		clk.id = imx8_clk_names[i].id;
> >>>> +	clks_col = find_clks_collect(dev);
> >>>> +
> >>>> +	if (!clks_col
> >>>> || !(clks_col->clks[IMX8_CLK_SLICE].type_clks)) {
> >>>> +		printf("%s fails to get clks for type %d\n",
> >>>> +		       __func__, IMX8_CLK_SLICE);
> >>>> +		return -ENODEV;
> >>>> +	}
> >>>> +
> >>>> +	clks = (struct imx8_clks
> >>>> *)(clks_col->clks[IMX8_CLK_SLICE].type_clks);
> >>>> +	size = clks_col->clks[IMX8_CLK_SLICE].num;
> >>>> +
> >>>> +	for (i = 0; i < size; i++) {
> >>>> +		clk.id = clks[i].hdr.id;
> >>>>  		ret = clk_request(dev, &clk);
> >>>>  		if (ret < 0) {
> >>>>  			debug("%s clk_request() failed: %d\n",
> >>>> __func__, ret); @@ -70,21 +346,22 @@ int soc_clk_dump(void)
> >>>>  
> >>>>  		if (ret == -ENOTSUPP) {
> >>>>  			printf("clk ID %lu not supported yet\n",
> >>>> -			       imx8_clk_names[i].id);
> >>>> +			       clks[i].hdr.id);
> >>>>  			continue;
> >>>>  		}
> >>>>  		if (ret < 0) {
> >>>>  			printf("%s %lu: get_rate err: %d\n",
> >>>> -			       __func__, imx8_clk_names[i].id,
> >>>> ret);
> >>>> +			       __func__, clks[i].hdr.id, ret);
> >>>>  			continue;
> >>>>  		}
> >>>>  
> >>>>  		printf("%s(%3lu):\t%lu\n",
> >>>> -		       imx8_clk_names[i].name,
> >>>> imx8_clk_names[i].id, rate);
> >>>> +		       clks[i].hdr.name, clks[i].hdr.id, rate);
> >>>>  	}
> >>>>  
> >>>>  	return 0;
> >>>>  }
> >>>> +
> >>>>  #endif
> >>>>  
> >>>>  static struct clk_ops imx8_clk_ops = {
> >>>> @@ -92,6 +369,7 @@ static struct clk_ops imx8_clk_ops = {
> >>>>  	.get_rate = imx8_clk_get_rate,
> >>>>  	.enable = imx8_clk_enable,
> >>>>  	.disable = imx8_clk_disable,
> >>>> +	.set_parent = imx8_clk_set_parent,
> >>>>  };
> >>>>  
> >>>>  static int imx8_clk_probe(struct udevice *dev)
> >>>> @@ -100,8 +378,8 @@ static int imx8_clk_probe(struct udevice
> >>>> *dev) }
> >>>>  
> >>>>  static const struct udevice_id imx8_clk_ids[] = {
> >>>> -	{ .compatible = "fsl,imx8qxp-clk" },
> >>>> -	{ .compatible = "fsl,imx8qm-clk" },
> >>>> +	{ .compatible = "fsl,imx8qxp-clk", .data =
> >>>> FLAG_CLK_IMX8_IMX8QXP, },
> >>>> +	{ .compatible = "fsl,imx8qm-clk", .data =
> >>>> FLAG_CLK_IMX8_IMX8QM, }, { },
> >>>>  };
> >>>>  
> >>>> diff --git a/drivers/clk/imx/clk-imx8.h
> >>>> b/drivers/clk/imx/clk-imx8.h index 68ad675..c0566f8 100644
> >>>> --- a/drivers/clk/imx/clk-imx8.h
> >>>> +++ b/drivers/clk/imx/clk-imx8.h
> >>>> @@ -4,16 +4,87 @@
> >>>>   * Peng Fan <peng.fan@nxp.com>
> >>>>   */
> >>>>  
> >>>> -struct imx8_clks {
> >>>> +#define CLK_IMX8_MAX_MUX_SEL 5
> >>>> +
> >>>> +#define FLAG_CLK_IMX8_IMX8QM	BIT(0)
> >>>> +#define FLAG_CLK_IMX8_IMX8QXP	BIT(1)
> >>>> +
> >>>> +struct imx8_clk_header {
> >>>>  	ulong id;
> >>>> +#if CONFIG_IS_ENABLED(CMD_CLK)
> >>>>  	const char *name;
> >>>> +#endif
> >>>> +};
> >>>> +
> >>>> +struct imx8_clks {
> >>>> +	struct imx8_clk_header hdr;
> >>>> +	u16 rsrc;
> >>>> +	sc_pm_clk_t pm_clk;
> >>>> +};
> >>>> +
> >>>> +struct imx8_fixed_clks {
> >>>> +	struct imx8_clk_header hdr;
> >>>> +	ulong rate;
> >>>> +};
> >>>> +
> >>>> +struct imx8_gpr_clks {
> >>>> +	struct imx8_clk_header hdr;
> >>>> +	u16 rsrc;
> >>>> +	sc_ctrl_t gpr_id;
> >>>> +	ulong parent_id;
> >>>> +};
> >>>> +
> >>>> +struct imx8_lpcg_clks {
> >>>> +	struct imx8_clk_header hdr;
> >>>> +	u8 bit_idx;
> >>>> +	u32 lpcg;
> >>>> +	ulong parent_id;
> >>>> +};
> >>>> +
> >>>> +struct imx8_mux_clks {
> >>>> +	struct imx8_clk_header hdr;
> >>>> +	ulong slice_clk_id;
> >>>> +	ulong parent_clks[CLK_IMX8_MAX_MUX_SEL];
> >>>> +};
> >>>> +
> >>>> +enum imx8_clk_type {
> >>>> +	IMX8_CLK_SLICE 		= 0,
> >>>> +	IMX8_CLK_FIXED 	= 1,
> >>>> +	IMX8_CLK_GPR 		= 2,
> >>>> +	IMX8_CLK_LPCG 		= 3,
> >>>> +	IMX8_CLK_MUX 		= 4,
> >>>> +	IMX8_CLK_END		= 5,
> >>>> +};
> >>>> +
> >>>> +struct imx8_clk_pair {
> >>>> +	void *type_clks;
> >>>> +	u32 num;
> >>>> +};
> >>>> +
> >>>> +struct imx8_clks_collect {
> >>>> +	struct imx8_clk_pair clks[IMX8_CLK_END];
> >>>> +	ulong match_flag;
> >>>>  };
> >>>>  
> >>>>  #if CONFIG_IS_ENABLED(CMD_CLK)
> >>>> -extern struct imx8_clks imx8_clk_names[];
> >>>> -extern int num_clks;
> >>>> +#define CLK_3(ID, NAME, MEM2) \
> >>>> +	{ { ID, NAME, }, MEM2, }
> >>>> +#define CLK_4(ID, NAME, MEM2, MEM3) \
> >>>> +	{ { ID, NAME, }, MEM2, MEM3, }
> >>>> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
> >>>> +	{ { ID, NAME, }, MEM2, MEM3, MEM4, }
> >>>> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
> >>>> +	{ { ID, NAME, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
> >>>> +#else
> >>>> +#define CLK_3(ID, NAME, MEM2) \
> >>>> +	{ { ID, }, MEM2, }
> >>>> +#define CLK_4(ID, NAME, MEM2, MEM3) \
> >>>> +	{ { ID, }, MEM2, MEM3, }
> >>>> +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \
> >>>> +	{ { ID, }, MEM2, MEM3, MEM4, }
> >>>> +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \
> >>>> +	{ { ID, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} }
> >>>>  #endif
> >>>>  
> >>>> -ulong imx8_clk_get_rate(struct clk *clk);
> >>>> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate);
> >>>> -int __imx8_clk_enable(struct clk *clk, bool enable);
> >>>> +extern struct imx8_clks_collect imx8qxp_clk_collect;
> >>>> +extern struct imx8_clks_collect imx8qm_clk_collect;
> >>>> diff --git a/drivers/clk/imx/clk-imx8qm.c
> >>>> b/drivers/clk/imx/clk-imx8qm.c index a6b09d2..f4ee007 100644
> >>>> --- a/drivers/clk/imx/clk-imx8qm.c
> >>>> +++ b/drivers/clk/imx/clk-imx8qm.c
> >>>> @@ -12,314 +12,189 @@
> >>>>  #include <dt-bindings/clock/imx8qm-clock.h>
> >>>>  #include <dt-bindings/soc/imx_rsrc.h>
> >>>>  #include <misc.h>
> >>>> +#include <asm/arch/lpcg.h>
> >>>>  
> >>>>  #include "clk-imx8.h"
> >>>>  
> >>>> -#if CONFIG_IS_ENABLED(CMD_CLK)
> >>>> -struct imx8_clks imx8_clk_names[] = {
> >>>> -	{ IMX8QM_A53_DIV, "A53_DIV" },
> >>>> -	{ IMX8QM_UART0_CLK, "UART0" },
> >>>> -	{ IMX8QM_UART1_CLK, "UART1" },
> >>>> -	{ IMX8QM_UART2_CLK, "UART2" },
> >>>> -	{ IMX8QM_UART3_CLK, "UART3" },
> >>>> -	{ IMX8QM_SDHC0_CLK, "SDHC0" },
> >>>> -	{ IMX8QM_SDHC1_CLK, "SDHC1" },
> >>>> -	{ IMX8QM_SDHC2_CLK, "SDHC2" },
> >>>> -	{ IMX8QM_ENET0_AHB_CLK, "ENET0_AHB" },
> >>>> -	{ IMX8QM_ENET0_IPG_CLK, "ENET0_IPG" },
> >>>> -	{ IMX8QM_ENET0_REF_DIV, "ENET0_REF" },
> >>>> -	{ IMX8QM_ENET0_PTP_CLK, "ENET0_PTP" },
> >>>> -	{ IMX8QM_ENET1_AHB_CLK, "ENET1_AHB" },
> >>>> -	{ IMX8QM_ENET1_IPG_CLK, "ENET1_IPG" },
> >>>> -	{ IMX8QM_ENET1_REF_DIV, "ENET1_REF" },
> >>>> -	{ IMX8QM_ENET1_PTP_CLK, "ENET1_PTP" },
> >>>> +static struct imx8_clks imx8qm_clks[] = {
> >>>> +	CLK_4( IMX8QM_A53_DIV, "A53_DIV", SC_R_A53,
> >>>> SC_PM_CLK_CPU ),
> >>>> +	CLK_4( IMX8QM_A72_DIV, "A72_DIV", SC_R_A72,
> >>>> SC_PM_CLK_CPU ),
> >>>> +	CLK_4( IMX8QM_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_LVDS0_I2C0_DIV, "LVDS0 I2C0 DIV",
> >>>> SC_R_LVDS_0_I2C_0, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_LVDS0_I2C1_DIV, "LVDS0 I2C1 DIV",
> >>>> SC_R_LVDS_0_I2C_1, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_LVDS1_I2C0_DIV, "LVDS1 I2C0 DIV",
> >>>> SC_R_LVDS_1_I2C_0, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_LVDS1_I2C1_DIV, "LVDS1 I2C1 DIV",
> >>>> SC_R_LVDS_1_I2C_1, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
> >>>> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QM_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
> >>>> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QM_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
> >>>> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QM_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
> >>>> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QM_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
> >>>> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_CSI1_I2C0_DIV, "CSI1 I2C0_DIV",
> >>>> SC_R_CSI_1_I2C_0, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_HDMI_I2C0_DIV, "HDMI I2C0_DIV",
> >>>> SC_R_HDMI_I2C_0, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QM_HDMI_IPG_CLK, "HDMI IPG_CLK", SC_R_HDMI,
> >>>> SC_PM_CLK_MISC ),
> >>>> +	CLK_4( IMX8QM_HDMI_RX_I2C0_DIV, "HDMI RX I2C_DIV",
> >>>> SC_R_HDMI_RX_I2C_0, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QM_UART0_DIV, "UART0_DIV", SC_R_UART_0,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_UART1_DIV, "UART1_DIV", SC_R_UART_1,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_UART2_DIV, "UART2_DIV", SC_R_UART_2,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_UART3_DIV, "UART3_DIV", SC_R_UART_3,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_ENET0_ROOT_DIV, "ENET0_ROOT_DIV",
> >>>> SC_R_ENET_0, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
> >>>> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
> >>>> +	CLK_4( IMX8QM_ENET1_ROOT_DIV, "ENET1_ROOT_DIV",
> >>>> SC_R_ENET_1, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
> >>>> SC_R_ENET_1, SC_PM_CLK_MISC0 ), +
> >>>> +	CLK_4( IMX8QM_USB3_ACLK_DIV, "USB3_ACLK_DIV",
> >>>> SC_R_USB_2, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QM_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
> >>>> SC_PM_CLK_MST_BUS ),
> >>>> +	CLK_4( IMX8QM_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
> >>>> SC_PM_CLK_MISC ), +
> >>>> +	CLK_4( IMX8QM_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
> >>>> SC_PM_CLK_PER ), +
> >>>> +	CLK_4( IMX8QM_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND,
> >>>> SC_PM_CLK_MST_BUS ),
> >>>> +	CLK_4( IMX8QM_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
> >>>> SC_PM_CLK_PER ), };
> >>>>  
> >>>> -int num_clks = ARRAY_SIZE(imx8_clk_names);
> >>>> -#endif
> >>>> -
> >>>> -ulong imx8_clk_get_rate(struct clk *clk)
> >>>> -{
> >>>> -	sc_pm_clk_t pm_clk;
> >>>> -	ulong rate;
> >>>> -	u16 resource;
> >>>> -	int ret;
> >>>> -
> >>>> -	debug("%s(#%lu)\n", __func__, clk->id);
> >>>> -
> >>>> -	switch (clk->id) {
> >>>> -	case IMX8QM_A53_DIV:
> >>>> -		resource = SC_R_A53;
> >>>> -		pm_clk = SC_PM_CLK_CPU;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C0_CLK:
> >>>> -		resource = SC_R_I2C_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C1_CLK:
> >>>> -		resource = SC_R_I2C_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C2_CLK:
> >>>> -		resource = SC_R_I2C_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C3_CLK:
> >>>> -		resource = SC_R_I2C_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_SDHC0_IPG_CLK:
> >>>> -	case IMX8QM_SDHC0_CLK:
> >>>> -	case IMX8QM_SDHC0_DIV:
> >>>> -		resource = SC_R_SDHC_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_SDHC1_IPG_CLK:
> >>>> -	case IMX8QM_SDHC1_CLK:
> >>>> -	case IMX8QM_SDHC1_DIV:
> >>>> -		resource = SC_R_SDHC_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_SDHC2_IPG_CLK:
> >>>> -	case IMX8QM_SDHC2_CLK:
> >>>> -	case IMX8QM_SDHC2_DIV:
> >>>> -		resource = SC_R_SDHC_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART0_IPG_CLK:
> >>>> -	case IMX8QM_UART0_CLK:
> >>>> -		resource = SC_R_UART_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART1_CLK:
> >>>> -		resource = SC_R_UART_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART2_CLK:
> >>>> -		resource = SC_R_UART_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART3_CLK:
> >>>> -		resource = SC_R_UART_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_ENET0_IPG_CLK:
> >>>> -	case IMX8QM_ENET0_AHB_CLK:
> >>>> -	case IMX8QM_ENET0_REF_DIV:
> >>>> -	case IMX8QM_ENET0_PTP_CLK:
> >>>> -		resource = SC_R_ENET_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_ENET1_IPG_CLK:
> >>>> -	case IMX8QM_ENET1_AHB_CLK:
> >>>> -	case IMX8QM_ENET1_REF_DIV:
> >>>> -	case IMX8QM_ENET1_PTP_CLK:
> >>>> -		resource = SC_R_ENET_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	default:
> >>>> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
> >>>> -		    clk->id >= IMX8QM_CLK_END) {
> >>>> -			printf("%s(Invalid clk ID #%lu)\n",
> >>>> -			       __func__, clk->id);
> >>>> -			return -EINVAL;
> >>>> -		}
> >>>> -		return -ENOTSUPP;
> >>>> -	};
> >>>> -
> >>>> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
> >>>> -				   (sc_pm_clock_rate_t *)&rate);
> >>>> -	if (ret) {
> >>>> -		printf("%s err %d\n", __func__, ret);
> >>>> -		return ret;
> >>>> -	}
> >>>> -
> >>>> -	return rate;
> >>>> -}
> >>>> -
> >>>> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
> >>>> -{
> >>>> -	sc_pm_clk_t pm_clk;
> >>>> -	u32 new_rate = rate;
> >>>> -	u16 resource;
> >>>> -	int ret;
> >>>> -
> >>>> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
> >>>> -
> >>>> -	switch (clk->id) {
> >>>> -	case IMX8QM_I2C0_CLK:
> >>>> -		resource = SC_R_I2C_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C1_CLK:
> >>>> -		resource = SC_R_I2C_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C2_CLK:
> >>>> -		resource = SC_R_I2C_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C3_CLK:
> >>>> -		resource = SC_R_I2C_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART0_CLK:
> >>>> -		resource = SC_R_UART_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART1_CLK:
> >>>> -		resource = SC_R_UART_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART2_CLK:
> >>>> -		resource = SC_R_UART_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART3_CLK:
> >>>> -		resource = SC_R_UART_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_SDHC0_IPG_CLK:
> >>>> -	case IMX8QM_SDHC0_CLK:
> >>>> -	case IMX8QM_SDHC0_DIV:
> >>>> -		resource = SC_R_SDHC_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_SDHC1_IPG_CLK:
> >>>> -	case IMX8QM_SDHC1_CLK:
> >>>> -	case IMX8QM_SDHC1_DIV:
> >>>> -		resource = SC_R_SDHC_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_SDHC2_IPG_CLK:
> >>>> -	case IMX8QM_SDHC2_CLK:
> >>>> -	case IMX8QM_SDHC2_DIV:
> >>>> -		resource = SC_R_SDHC_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_ENET0_IPG_CLK:
> >>>> -	case IMX8QM_ENET0_AHB_CLK:
> >>>> -	case IMX8QM_ENET0_REF_DIV:
> >>>> -	case IMX8QM_ENET0_PTP_CLK:
> >>>> -	case IMX8QM_ENET0_ROOT_DIV:
> >>>> -		resource = SC_R_ENET_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_ENET1_IPG_CLK:
> >>>> -	case IMX8QM_ENET1_AHB_CLK:
> >>>> -	case IMX8QM_ENET1_REF_DIV:
> >>>> -	case IMX8QM_ENET1_PTP_CLK:
> >>>> -	case IMX8QM_ENET1_ROOT_DIV:
> >>>> -		resource = SC_R_ENET_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	default:
> >>>> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
> >>>> -		    clk->id >= IMX8QM_CLK_END) {
> >>>> -			printf("%s(Invalid clk ID #%lu)\n",
> >>>> -			       __func__, clk->id);
> >>>> -			return -EINVAL;
> >>>> -		}
> >>>> -		return -ENOTSUPP;
> >>>> -	};
> >>>> -
> >>>> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk,
> >>>> &new_rate);
> >>>> -	if (ret) {
> >>>> -		printf("%s err %d\n", __func__, ret);
> >>>> -		return ret;
> >>>> -	}
> >>>> -
> >>>> -	return new_rate;
> >>>> -}
> >>>> -
> >>>> -int __imx8_clk_enable(struct clk *clk, bool enable)
> >>>> -{
> >>>> -	sc_pm_clk_t pm_clk;
> >>>> -	u16 resource;
> >>>> -	int ret;
> >>>> +static struct imx8_fixed_clks imx8qm_fixed_clks[] = {
> >>>> +	CLK_3( IMX8QM_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK",
> >>>> SC_83MHZ ),
> >>>> +	CLK_3( IMX8QM_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK",
> >>>> SC_166MHZ ),
> >>>> +	CLK_3( IMX8QM_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK",
> >>>> SC_333MHZ ),
> >>>> +	CLK_3( IMX8QM_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ
> >>>> ),
> >>>> +	CLK_3( IMX8QM_IPG_MIPI_CSI_CLK_ROOT, "IPG_MIPI_CLK",
> >>>> SC_120MHZ ),
> >>>> +	CLK_3( IMX8QM_LVDS_IPG_CLK, "IPG_LVDS_CLK", SC_24MHZ ),
> >>>> +	CLK_3( IMX8QM_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ),
> >>>> +	CLK_3( IMX8QM_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ),
> >>>> +	CLK_3( IMX8QM_MIPI0_CLK_ROOT, "MIPI0_CLK", SC_120MHZ ),
> >>>> +	CLK_3( IMX8QM_MIPI1_CLK_ROOT, "MIPI1_CLK", SC_120MHZ ),
> >>>> +	CLK_3( IMX8QM_HDMI_RX_IPG_CLK, "HDMI_RX_IPG_CLK",
> >>>> SC_200MHZ ), +};
> >>>>  
> >>>> -	debug("%s(#%lu)\n", __func__, clk->id);
> >>>> +static struct imx8_gpr_clks imx8qm_gpr_clks[] = {
> >>>> +	CLK_5( IMX8QM_ENET0_REF_DIV, "ENET0_REF_DIV",
> >>>> SC_R_ENET_0, SC_C_CLKDIV, IMX8QM_ENET0_ROOT_DIV ),
> >>>> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL,
> >>>> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
> >>>> +	CLK_4( IMX8QM_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
> >>>> SC_R_ENET_0, SC_C_TXCLK ),
> >>>> +	CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK,
> >>>> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
> >>>> +	CLK_4( IMX8QM_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
> >>>> SC_R_ENET_0, SC_C_DISABLE_50 ), +
> >>>> +	CLK_5( IMX8QM_ENET1_REF_DIV, "ENET1_REF_DIV",
> >>>> SC_R_ENET_1, SC_C_CLKDIV, IMX8QM_ENET1_ROOT_DIV ),
> >>>> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL,
> >>>> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
> >>>> +	CLK_4( IMX8QM_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
> >>>> SC_R_ENET_1, SC_C_TXCLK ),
> >>>> +	CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK,
> >>>> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
> >>>> +	CLK_4( IMX8QM_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
> >>>> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
> >>>>  
> >>>> -	switch (clk->id) {
> >>>> -	case IMX8QM_I2C0_CLK:
> >>>> -		resource = SC_R_I2C_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C1_CLK:
> >>>> -		resource = SC_R_I2C_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C2_CLK:
> >>>> -		resource = SC_R_I2C_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_I2C3_CLK:
> >>>> -		resource = SC_R_I2C_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART0_CLK:
> >>>> -		resource = SC_R_UART_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART1_CLK:
> >>>> -		resource = SC_R_UART_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART2_CLK:
> >>>> -		resource = SC_R_UART_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_UART3_CLK:
> >>>> -		resource = SC_R_UART_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_SDHC0_IPG_CLK:
> >>>> -	case IMX8QM_SDHC0_CLK:
> >>>> -	case IMX8QM_SDHC0_DIV:
> >>>> -		resource = SC_R_SDHC_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_SDHC1_IPG_CLK:
> >>>> -	case IMX8QM_SDHC1_CLK:
> >>>> -	case IMX8QM_SDHC1_DIV:
> >>>> -		resource = SC_R_SDHC_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_SDHC2_IPG_CLK:
> >>>> -	case IMX8QM_SDHC2_CLK:
> >>>> -	case IMX8QM_SDHC2_DIV:
> >>>> -		resource = SC_R_SDHC_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_ENET0_IPG_CLK:
> >>>> -	case IMX8QM_ENET0_AHB_CLK:
> >>>> -	case IMX8QM_ENET0_REF_DIV:
> >>>> -	case IMX8QM_ENET0_PTP_CLK:
> >>>> -		resource = SC_R_ENET_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QM_ENET1_IPG_CLK:
> >>>> -	case IMX8QM_ENET1_AHB_CLK:
> >>>> -	case IMX8QM_ENET1_REF_DIV:
> >>>> -	case IMX8QM_ENET1_PTP_CLK:
> >>>> -		resource = SC_R_ENET_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	default:
> >>>> -		if (clk->id < IMX8QM_UART0_IPG_CLK ||
> >>>> -		    clk->id >= IMX8QM_CLK_END) {
> >>>> -			printf("%s(Invalid clk ID #%lu)\n",
> >>>> -			       __func__, clk->id);
> >>>> -			return -EINVAL;
> >>>> -		}
> >>>> -		return -ENOTSUPP;
> >>>> -	}
> >>>> +static struct imx8_lpcg_clks imx8qm_lpcg_clks[] = {
> >>>> +	CLK_5( IMX8QM_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
> >>>> IMX8QM_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QM_I2C0_IPG_CLK, "I2C0_IPG", 16,
> >>>> LPI2C_0_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
> >>>> IMX8QM_I2C1_DIV ),
> >>>> +	CLK_5( IMX8QM_I2C1_IPG_CLK, "I2C1_IPG", 16,
> >>>> LPI2C_1_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
> >>>> IMX8QM_I2C2_DIV ),
> >>>> +	CLK_5( IMX8QM_I2C2_IPG_CLK, "I2C2_IPG", 16,
> >>>> LPI2C_2_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
> >>>> IMX8QM_I2C3_DIV ),
> >>>> +	CLK_5( IMX8QM_I2C3_IPG_CLK, "I2C3_IPG", 16,
> >>>> LPI2C_3_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ), +
> >>>> +	CLK_5( IMX8QM_LVDS0_I2C0_CLK, "LVDS0_I2C0_CLK", 0,
> >>>> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS0_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QM_LVDS0_I2C0_IPG_CLK, "LVDS0_I2C0_IPG", 16,
> >>>> DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
> >>>> +	CLK_5( IMX8QM_LVDS0_I2C1_CLK, "LVDS0_I2C1_CLK", 0,
> >>>> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS0_I2C1_DIV ),
> >>>> +	CLK_5( IMX8QM_LVDS0_I2C1_IPG_CLK, "LVDS0_I2C1_IPG", 16,
> >>>> DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ),
> >>>> +	CLK_5( IMX8QM_LVDS1_I2C0_CLK, "LVDS1_I2C0_CLK", 0,
> >>>> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS1_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QM_LVDS1_I2C0_IPG_CLK, "LVDS1_I2C0_IPG", 16,
> >>>> DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ),
> >>>> +	CLK_5( IMX8QM_LVDS1_I2C1_CLK, "LVDS1_I2C1_CLK", 0,
> >>>> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS1_I2C1_DIV ),
> >>>> +	CLK_5( IMX8QM_LVDS1_I2C1_IPG_CLK, "LVDS1_I2C1_IPG", 16,
> >>>> DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ), +
> >>>> +	CLK_5( IMX8QM_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
> >>>> MIPI_DSI_0_LPCG + 0x1c, IMX8QM_MIPI0_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 0,
> >>>> MIPI_DSI_0_LPCG + 0x14,  IMX8QM_MIPI0_I2C0_IPG_S_CLK),
> >>>> +	CLK_5( IMX8QM_MIPI0_I2C0_IPG_S_CLK, "MIPI0_I2C0_IPG_S",
> >>>> 0, MIPI_DSI_0_LPCG + 0x18, IMX8QM_MIPI0_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
> >>>> MIPI_DSI_0_LPCG + 0x2c, IMX8QM_MIPI0_I2C1_DIV ),
> >>>> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 0,
> >>>> MIPI_DSI_0_LPCG + 0x24,  IMX8QM_MIPI0_I2C1_IPG_S_CLK),
> >>>> +	CLK_5( IMX8QM_MIPI0_I2C1_IPG_S_CLK, "MIPI0_I2C1_IPG_S",
> >>>> 0, MIPI_DSI_0_LPCG + 0x28, IMX8QM_MIPI0_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
> >>>> MIPI_DSI_1_LPCG + 0x1c, IMX8QM_MIPI1_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 0,
> >>>> MIPI_DSI_1_LPCG + 0x14, IMX8QM_MIPI1_I2C0_IPG_S_CLK),
> >>>> +	CLK_5( IMX8QM_MIPI1_I2C0_IPG_S_CLK, "MIPI1_I2C0_IPG_S",
> >>>> 0, MIPI_DSI_1_LPCG + 0x18, IMX8QM_MIPI1_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
> >>>> MIPI_DSI_1_LPCG + 0x2c, IMX8QM_MIPI1_I2C1_DIV ),
> >>>> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 0,
> >>>> MIPI_DSI_1_LPCG + 0x24, IMX8QM_MIPI1_I2C1_IPG_S_CLK),
> >>>> +	CLK_5( IMX8QM_MIPI1_I2C1_IPG_S_CLK, "MIPI1_I2C1_IPG_S",
> >>>> 0, MIPI_DSI_1_LPCG + 0x28, IMX8QM_MIPI1_CLK_ROOT ), +
> >>>> +	CLK_5( IMX8QM_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
> >>>> MIPI_CSI_0_LPCG + 0x14, IMX8QM_CSI0_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QM_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
> >>>> MIPI_CSI_0_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_CSI1_I2C0_CLK, "CSI1_I2C0_CLK", 0,
> >>>> MIPI_CSI_1_LPCG + 0x14, IMX8QM_CSI1_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QM_CSI1_I2C0_IPG_CLK, "CSI1_I2C0_IPG", 16,
> >>>> MIPI_CSI_1_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_HDMI_I2C0_CLK, "HDMI_I2C0_CLK", 0,
> >>>> DI_HDMI_LPCG, IMX8QM_HDMI_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QM_HDMI_I2C_IPG_CLK, "HDMI_I2C0_IPG", 16,
> >>>> DI_HDMI_LPCG, IMX8QM_HDMI_IPG_CLK ),
> >>>> +	CLK_5( IMX8QM_HDMI_RX_I2C_DIV_CLK, "HDMI
> >>>> RX_I2C_DIV_CLK", 0, MIPI_DSI_0_LPCG + 0x14,
> >>>> IMX8QM_MIPI0_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QM_HDMI_RX_I2C0_CLK, "HDMI RX_I2C_CLK", 0,
> >>>> MIPI_DSI_0_LPCG + 0x10, IMX8QM_HDMI_RX_I2C_DIV_CLK ),
> >>>> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_CLK, "HDMI_RX_I2C_IPG", 0,
> >>>> RX_HDMI_LPCG + 0x18,  IMX8QM_HDMI_RX_I2C_IPG_S_CLK),
> >>>> +	CLK_5( IMX8QM_HDMI_RX_I2C_IPG_S_CLK, "HDMI_I2C_IPG_S",
> >>>> 0, RX_HDMI_LPCG + 0x1c, IMX8QM_HDMI_RX_IPG_CLK ), +
> >>>> +	CLK_5( IMX8QM_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
> >>>> IMX8QM_UART0_DIV ),
> >>>> +	CLK_5( IMX8QM_UART0_IPG_CLK, "UART0_IPG", 16,
> >>>> LPUART_0_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
> >>>> IMX8QM_UART1_DIV ),
> >>>> +	CLK_5( IMX8QM_UART1_IPG_CLK, "UART1_IPG", 16,
> >>>> LPUART_1_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
> >>>> IMX8QM_UART2_DIV ),
> >>>> +	CLK_5( IMX8QM_UART2_IPG_CLK, "UART2_IPG", 16,
> >>>> LPUART_2_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
> >>>> IMX8QM_UART3_DIV ),
> >>>> +	CLK_5( IMX8QM_UART3_IPG_CLK, "UART3_IPG", 16,
> >>>> LPUART_3_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ), +
> >>>> +	CLK_5( IMX8QM_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
> >>>> IMX8QM_SDHC0_DIV ),
> >>>> +	CLK_5( IMX8QM_SDHC0_IPG_CLK, "SDHC0_IPG", 16,
> >>>> USDHC_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
> >>>> IMX8QM_SDHC1_DIV ),
> >>>> +	CLK_5( IMX8QM_SDHC1_IPG_CLK, "SDHC1_IPG", 16,
> >>>> USDHC_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
> >>>> IMX8QM_SDHC2_DIV ),
> >>>> +	CLK_5( IMX8QM_SDHC2_IPG_CLK, "SDHC2_IPG", 16,
> >>>> USDHC_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), +
> >>>> +	CLK_5( IMX8QM_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
> >>>> ENET_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_ENET0_IPG_CLK, "ENET0_IPG", 16,
> >>>> ENET_0_LPCG, IMX8QM_ENET0_IPG_S_CLK ),
> >>>> +	CLK_5( IMX8QM_ENET0_AHB_CLK, "ENET0_AHB", 8,
> >>>> ENET_0_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
> >>>> IMX8QM_ENET0_ROOT_DIV ),
> >>>> +	CLK_5( IMX8QM_ENET0_PTP_CLK, "ENET0_PTP", 0,
> >>>> ENET_0_LPCG, IMX8QM_ENET0_ROOT_DIV  ),
> >>>> +	CLK_5( IMX8QM_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
> >>>> ENET_0_LPCG, IMX8QM_ENET0_RMII_TX_SEL  ),
> >>>> +	CLK_5( IMX8QM_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
> >>>> ENET_0_LPCG + 0x4, IMX8QM_ENET0_RGMII_DIV  ), +
> >>>> +	CLK_5( IMX8QM_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
> >>>> ENET_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_ENET1_IPG_CLK, "ENET1_IPG", 16,
> >>>> ENET_1_LPCG, IMX8QM_ENET1_IPG_S_CLK ),
> >>>> +	CLK_5( IMX8QM_ENET1_AHB_CLK, "ENET1_AHB", 8,
> >>>> ENET_1_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
> >>>> IMX8QM_ENET1_ROOT_DIV ),
> >>>> +	CLK_5( IMX8QM_ENET1_PTP_CLK, "ENET1_PTP", 0,
> >>>> ENET_1_LPCG, IMX8QM_ENET1_ROOT_DIV  ),
> >>>> +	CLK_5( IMX8QM_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
> >>>> ENET_1_LPCG, IMX8QM_ENET1_RMII_TX_SEL  ),
> >>>> +	CLK_5( IMX8QM_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
> >>>> ENET_1_LPCG + 0x4, IMX8QM_ENET1_RGMII_DIV  ), +
> >>>> +	CLK_5( IMX8QM_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18,
> >>>> FSPI_0_LPCG, IMX8QM_LSIO_BUS_CLK ),
> >>>> +	CLK_5( IMX8QM_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14,
> >>>> FSPI_0_LPCG, IMX8QM_FSPI0_IPG_S_CLK ),
> >>>> +	CLK_5( IMX8QM_FSPI0_HCLK, "FSPI0_HCLK", 0x10,
> >>>> FSPI_0_LPCG, IMX8QM_LSIO_MEM_CLK ),
> >>>> +	CLK_5( IMX8QM_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG,
> >>>> IMX8QM_FSPI0_DIV ), +
> >>>> +	CLK_5( IMX8QM_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
> >>>> USB_2_LPCG, IMX8QM_AHB_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
> >>>> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_USB2_OH_IPG_S_PL301_CLK,
> >>>> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT
> >>>> ),
> >>>> +	CLK_5( IMX8QM_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
> >>>> USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), +
> >>>> +	CLK_5( IMX8QM_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
> >>>> IMX8QM_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_USB3_CORE_PCLK, "USB3_CORE", 20,
> >>>> USB_3_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
> >>>> IMX8QM_USB3_IPG_CLK ),
> >>>> +	CLK_5( IMX8QM_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
> >>>> IMX8QM_USB3_ACLK_DIV ),
> >>>> +	CLK_5( IMX8QM_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
> >>>> IMX8QM_USB3_BUS_DIV ),
> >>>> +	CLK_5( IMX8QM_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
> >>>> IMX8QM_USB3_LPM_DIV ), +
> >>>> +	CLK_5( IMX8QM_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
> >>>> IMX8QM_AXI_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
> >>>> NAND_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QM_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4,
> >>>> NAND_LPCG, IMX8QM_GPMI_BCH_IO_DIV ),
> >>>> +	CLK_5( IMX8QM_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0,
> >>>> NAND_LPCG, IMX8QM_GPMI_BCH_DIV ),
> >>>> +	CLK_5( IMX8QM_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG +
> >>>> 0x4, IMX8QM_AXI_CONN_CLK_ROOT ), +};
> >>>>  
> >>>> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable,
> >>>> 0);
> >>>> -	if (ret) {
> >>>> -		printf("%s err %d\n", __func__, ret);
> >>>> -		return ret;
> >>>> -	}
> >>>> +struct imx8_mux_clks imx8qm_mux_clks[] = {
> >>>> +};
> >>>>  
> >>>> -	return 0;
> >>>> -}
> >>>> +struct imx8_clks_collect imx8qm_clk_collect = {
> >>>> +	{
> >>>> +		{&imx8qm_clks, ARRAY_SIZE(imx8qm_clks)},
> >>>> +		{&imx8qm_fixed_clks,
> >>>> ARRAY_SIZE(imx8qm_fixed_clks)},
> >>>> +		{&imx8qm_gpr_clks, ARRAY_SIZE(imx8qm_gpr_clks)},
> >>>> +		{&imx8qm_lpcg_clks,
> >>>> ARRAY_SIZE(imx8qm_lpcg_clks)},
> >>>> +		{&imx8qm_mux_clks, ARRAY_SIZE(imx8qm_mux_clks)},
> >>>> +	},
> >>>> +	FLAG_CLK_IMX8_IMX8QM,
> >>>> +};
> >>>> diff --git a/drivers/clk/imx/clk-imx8qxp.c
> >>>> b/drivers/clk/imx/clk-imx8qxp.c index 1fca36a..8181a97 100644
> >>>> --- a/drivers/clk/imx/clk-imx8qxp.c
> >>>> +++ b/drivers/clk/imx/clk-imx8qxp.c
> >>>> @@ -12,300 +12,156 @@
> >>>>  #include <dt-bindings/clock/imx8qxp-clock.h>
> >>>>  #include <dt-bindings/soc/imx_rsrc.h>
> >>>>  #include <misc.h>
> >>>> +#include <asm/arch/lpcg.h>
> >>>>  
> >>>>  #include "clk-imx8.h"
> >>>>  
> >>>> -#if CONFIG_IS_ENABLED(CMD_CLK)
> >>>> -struct imx8_clks imx8_clk_names[] = {
> >>>> -	{ IMX8QXP_A35_DIV, "A35_DIV" },
> >>>> -	{ IMX8QXP_I2C0_CLK, "I2C0" },
> >>>> -	{ IMX8QXP_I2C1_CLK, "I2C1" },
> >>>> -	{ IMX8QXP_I2C2_CLK, "I2C2" },
> >>>> -	{ IMX8QXP_I2C3_CLK, "I2C3" },
> >>>> -	{ IMX8QXP_UART0_CLK, "UART0" },
> >>>> -	{ IMX8QXP_UART1_CLK, "UART1" },
> >>>> -	{ IMX8QXP_UART2_CLK, "UART2" },
> >>>> -	{ IMX8QXP_UART3_CLK, "UART3" },
> >>>> -	{ IMX8QXP_SDHC0_CLK, "SDHC0" },
> >>>> -	{ IMX8QXP_SDHC1_CLK, "SDHC1" },
> >>>> -	{ IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" },
> >>>> -	{ IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" },
> >>>> -	{ IMX8QXP_ENET0_REF_DIV, "ENET0_REF" },
> >>>> -	{ IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" },
> >>>> -	{ IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" },
> >>>> -	{ IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" },
> >>>> -	{ IMX8QXP_ENET1_REF_DIV, "ENET1_REF" },
> >>>> -	{ IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" },
> >>>> +static struct imx8_clks imx8qxp_clks[] = {
> >>>> +	CLK_4( IMX8QXP_A35_DIV, "A35_DIV", SC_R_A35,
> >>>> SC_PM_CLK_CPU ),
> >>>> +	CLK_4( IMX8QXP_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV",
> >>>> SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QXP_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV",
> >>>> SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QXP_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV",
> >>>> SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QXP_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV",
> >>>> SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ),
> >>>> +	CLK_4( IMX8QXP_CSI0_I2C0_DIV, "CSI0 I2C0_DIV",
> >>>> SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_UART0_DIV, "UART0_DIV", SC_R_UART_0,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_UART1_DIV, "UART1_DIV", SC_R_UART_1,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_UART2_DIV, "UART2_DIV", SC_R_UART_2,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_UART3_DIV, "UART3_DIV", SC_R_UART_3,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_ENET0_ROOT_DIV, "ENET0_ROOT_DIV",
> >>>> SC_R_ENET_0, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_ENET0_RGMII_DIV, "ENET0_RGMII_DIV",
> >>>> SC_R_ENET_0, SC_PM_CLK_MISC0 ),
> >>>> +	CLK_4( IMX8QXP_ENET1_ROOT_DIV, "ENET1_ROOT_DIV",
> >>>> SC_R_ENET_1, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_ENET1_RGMII_DIV, "ENET1_RGMII_DIV",
> >>>> SC_R_ENET_1, SC_PM_CLK_MISC0 ),
> >>>> +	CLK_4( IMX8QXP_USB3_ACLK_DIV, "USB3_ACLK_DIV",
> >>>> SC_R_USB_2, SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2,
> >>>> SC_PM_CLK_MST_BUS ),
> >>>> +	CLK_4( IMX8QXP_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2,
> >>>> SC_PM_CLK_MISC ),
> >>>> +	CLK_4( IMX8QXP_LSIO_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0,
> >>>> SC_PM_CLK_PER ),
> >>>> +	CLK_4( IMX8QXP_GPMI_BCH_IO_DIV, "GPMI_IO_DIV",
> >>>> SC_R_NAND, SC_PM_CLK_MST_BUS ),
> >>>> +	CLK_4( IMX8QXP_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND,
> >>>> SC_PM_CLK_PER ), };
> >>>>  
> >>>> -int num_clks = ARRAY_SIZE(imx8_clk_names);
> >>>> -#endif
> >>>> -
> >>>> -ulong imx8_clk_get_rate(struct clk *clk)
> >>>> -{
> >>>> -	sc_pm_clk_t pm_clk;
> >>>> -	ulong rate;
> >>>> -	u16 resource;
> >>>> -	int ret;
> >>>> -
> >>>> -	debug("%s(#%lu)\n", __func__, clk->id);
> >>>> -
> >>>> -	switch (clk->id) {
> >>>> -	case IMX8QXP_A35_DIV:
> >>>> -		resource = SC_R_A35;
> >>>> -		pm_clk = SC_PM_CLK_CPU;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C0_CLK:
> >>>> -		resource = SC_R_I2C_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C1_CLK:
> >>>> -		resource = SC_R_I2C_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C2_CLK:
> >>>> -		resource = SC_R_I2C_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C3_CLK:
> >>>> -		resource = SC_R_I2C_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_SDHC0_IPG_CLK:
> >>>> -	case IMX8QXP_SDHC0_CLK:
> >>>> -	case IMX8QXP_SDHC0_DIV:
> >>>> -		resource = SC_R_SDHC_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_SDHC1_IPG_CLK:
> >>>> -	case IMX8QXP_SDHC1_CLK:
> >>>> -	case IMX8QXP_SDHC1_DIV:
> >>>> -		resource = SC_R_SDHC_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART0_IPG_CLK:
> >>>> -	case IMX8QXP_UART0_CLK:
> >>>> -		resource = SC_R_UART_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART1_CLK:
> >>>> -		resource = SC_R_UART_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART2_CLK:
> >>>> -		resource = SC_R_UART_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART3_CLK:
> >>>> -		resource = SC_R_UART_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_ENET0_IPG_CLK:
> >>>> -	case IMX8QXP_ENET0_AHB_CLK:
> >>>> -	case IMX8QXP_ENET0_REF_DIV:
> >>>> -	case IMX8QXP_ENET0_PTP_CLK:
> >>>> -		resource = SC_R_ENET_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_ENET1_IPG_CLK:
> >>>> -	case IMX8QXP_ENET1_AHB_CLK:
> >>>> -	case IMX8QXP_ENET1_REF_DIV:
> >>>> -	case IMX8QXP_ENET1_PTP_CLK:
> >>>> -		resource = SC_R_ENET_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	default:
> >>>> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
> >>>> -		    clk->id >= IMX8QXP_CLK_END) {
> >>>> -			printf("%s(Invalid clk ID #%lu)\n",
> >>>> -			       __func__, clk->id);
> >>>> -			return -EINVAL;
> >>>> -		}
> >>>> -		return -ENOTSUPP;
> >>>> -	};
> >>>> -
> >>>> -	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
> >>>> -				   (sc_pm_clock_rate_t *)&rate);
> >>>> -	if (ret) {
> >>>> -		printf("%s err %d\n", __func__, ret);
> >>>> -		return ret;
> >>>> -	}
> >>>> -
> >>>> -	return rate;
> >>>> -}
> >>>> -
> >>>> -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
> >>>> -{
> >>>> -	sc_pm_clk_t pm_clk;
> >>>> -	u32 new_rate = rate;
> >>>> -	u16 resource;
> >>>> -	int ret;
> >>>> -
> >>>> -	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
> >>>> -
> >>>> -	switch (clk->id) {
> >>>> -	case IMX8QXP_I2C0_CLK:
> >>>> -		resource = SC_R_I2C_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C1_CLK:
> >>>> -		resource = SC_R_I2C_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C2_CLK:
> >>>> -		resource = SC_R_I2C_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C3_CLK:
> >>>> -		resource = SC_R_I2C_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART0_CLK:
> >>>> -		resource = SC_R_UART_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART1_CLK:
> >>>> -		resource = SC_R_UART_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART2_CLK:
> >>>> -		resource = SC_R_UART_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART3_CLK:
> >>>> -		resource = SC_R_UART_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_SDHC0_IPG_CLK:
> >>>> -	case IMX8QXP_SDHC0_CLK:
> >>>> -	case IMX8QXP_SDHC0_DIV:
> >>>> -		resource = SC_R_SDHC_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_SDHC1_SEL:
> >>>> -	case IMX8QXP_SDHC0_SEL:
> >>>> -		return 0;
> >>>> -	case IMX8QXP_SDHC1_IPG_CLK:
> >>>> -	case IMX8QXP_SDHC1_CLK:
> >>>> -	case IMX8QXP_SDHC1_DIV:
> >>>> -		resource = SC_R_SDHC_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_ENET0_IPG_CLK:
> >>>> -	case IMX8QXP_ENET0_AHB_CLK:
> >>>> -	case IMX8QXP_ENET0_REF_DIV:
> >>>> -	case IMX8QXP_ENET0_PTP_CLK:
> >>>> -		resource = SC_R_ENET_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_ENET1_IPG_CLK:
> >>>> -	case IMX8QXP_ENET1_AHB_CLK:
> >>>> -	case IMX8QXP_ENET1_REF_DIV:
> >>>> -	case IMX8QXP_ENET1_PTP_CLK:
> >>>> -		resource = SC_R_ENET_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	default:
> >>>> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
> >>>> -		    clk->id >= IMX8QXP_CLK_END) {
> >>>> -			printf("%s(Invalid clk ID #%lu)\n",
> >>>> -			       __func__, clk->id);
> >>>> -			return -EINVAL;
> >>>> -		}
> >>>> -		return -ENOTSUPP;
> >>>> -	};
> >>>> -
> >>>> -	ret = sc_pm_set_clock_rate(-1, resource, pm_clk,
> >>>> &new_rate);
> >>>> -	if (ret) {
> >>>> -		printf("%s err %d\n", __func__, ret);
> >>>> -		return ret;
> >>>> -	}
> >>>> -
> >>>> -	return new_rate;
> >>>> -}
> >>>> -
> >>>> -int __imx8_clk_enable(struct clk *clk, bool enable)
> >>>> -{
> >>>> -	sc_pm_clk_t pm_clk;
> >>>> -	u16 resource;
> >>>> -	int ret;
> >>>> +static struct imx8_fixed_clks imx8qxp_fixed_clks[] = {
> >>>> +	CLK_3( IMX8QXP_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK",
> >>>> SC_83MHZ ),
> >>>> +	CLK_3( IMX8QXP_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK",
> >>>> SC_166MHZ ),
> >>>> +	CLK_3( IMX8QXP_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK",
> >>>> SC_333MHZ ),
> >>>> +	CLK_3( IMX8QXP_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK",
> >>>> SC_120MHZ ),
> >>>> +	CLK_3( IMX8QXP_MIPI_IPG_CLK, "IPG_MIPI_CLK", SC_120MHZ
> >>>> ),
> >>>> +	CLK_3( IMX8QXP_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ
> >>>> ),
> >>>> +	CLK_3( IMX8QXP_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ
> >>>> ), +};
> >>>>  
> >>>> -	debug("%s(#%lu)\n", __func__, clk->id);
> >>>> +static struct imx8_gpr_clks imx8qxp_gpr_clks[] = {
> >>>> +	CLK_5( IMX8QXP_ENET0_REF_DIV, "ENET0_REF_DIV",
> >>>> SC_R_ENET_0, SC_C_CLKDIV, IMX8QXP_ENET0_ROOT_DIV ),
> >>>> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL,
> >>>> "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ),
> >>>> +	CLK_4( IMX8QXP_ENET0_RMII_TX_SEL, "ENET0_RMII_TX",
> >>>> SC_R_ENET_0, SC_C_TXCLK ),
> >>>> +	CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK,
> >>>> "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ),
> >>>> +	CLK_4( IMX8QXP_ENET0_REF_50MHZ_CLK, "ENET0_REF_50",
> >>>> SC_R_ENET_0, SC_C_DISABLE_50 ), +
> >>>> +	CLK_5( IMX8QXP_ENET1_REF_DIV, "ENET1_REF_DIV",
> >>>> SC_R_ENET_1, SC_C_CLKDIV, IMX8QXP_ENET1_ROOT_DIV ),
> >>>> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL,
> >>>> "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ),
> >>>> +	CLK_4( IMX8QXP_ENET1_RMII_TX_SEL, "ENET1_RMII_TX",
> >>>> SC_R_ENET_1, SC_C_TXCLK ),
> >>>> +	CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK,
> >>>> "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ),
> >>>> +	CLK_4( IMX8QXP_ENET1_REF_50MHZ_CLK, "ENET1_REF_50",
> >>>> SC_R_ENET_1, SC_C_DISABLE_50 ), +};
> >>>>  
> >>>> -	switch (clk->id) {
> >>>> -	case IMX8QXP_I2C0_CLK:
> >>>> -		resource = SC_R_I2C_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C1_CLK:
> >>>> -		resource = SC_R_I2C_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C2_CLK:
> >>>> -		resource = SC_R_I2C_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_I2C3_CLK:
> >>>> -		resource = SC_R_I2C_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART0_CLK:
> >>>> -		resource = SC_R_UART_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART1_CLK:
> >>>> -		resource = SC_R_UART_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART2_CLK:
> >>>> -		resource = SC_R_UART_2;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_UART3_CLK:
> >>>> -		resource = SC_R_UART_3;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_SDHC0_IPG_CLK:
> >>>> -	case IMX8QXP_SDHC0_CLK:
> >>>> -	case IMX8QXP_SDHC0_DIV:
> >>>> -		resource = SC_R_SDHC_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_SDHC1_IPG_CLK:
> >>>> -	case IMX8QXP_SDHC1_CLK:
> >>>> -	case IMX8QXP_SDHC1_DIV:
> >>>> -		resource = SC_R_SDHC_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_ENET0_IPG_CLK:
> >>>> -	case IMX8QXP_ENET0_AHB_CLK:
> >>>> -	case IMX8QXP_ENET0_REF_DIV:
> >>>> -	case IMX8QXP_ENET0_PTP_CLK:
> >>>> -		resource = SC_R_ENET_0;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	case IMX8QXP_ENET1_IPG_CLK:
> >>>> -	case IMX8QXP_ENET1_AHB_CLK:
> >>>> -	case IMX8QXP_ENET1_REF_DIV:
> >>>> -	case IMX8QXP_ENET1_PTP_CLK:
> >>>> -		resource = SC_R_ENET_1;
> >>>> -		pm_clk = SC_PM_CLK_PER;
> >>>> -		break;
> >>>> -	default:
> >>>> -		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
> >>>> -		    clk->id >= IMX8QXP_CLK_END) {
> >>>> -			printf("%s(Invalid clk ID #%lu)\n",
> >>>> -			       __func__, clk->id);
> >>>> -			return -EINVAL;
> >>>> -		}
> >>>> -		return -ENOTSUPP;
> >>>> -	}
> >>>> +static struct imx8_lpcg_clks imx8qxp_lpcg_clks[] = {
> >>>> +	CLK_5( IMX8QXP_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG,
> >>>> IMX8QXP_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QXP_I2C0_IPG_CLK, "I2C0_IPG", 16,
> >>>> LPI2C_0_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG,
> >>>> IMX8QXP_I2C1_DIV ),
> >>>> +	CLK_5( IMX8QXP_I2C1_IPG_CLK, "I2C1_IPG", 16,
> >>>> LPI2C_1_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG,
> >>>> IMX8QXP_I2C2_DIV ),
> >>>> +	CLK_5( IMX8QXP_I2C2_IPG_CLK, "I2C2_IPG", 16,
> >>>> LPI2C_2_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG,
> >>>> IMX8QXP_I2C3_DIV ),
> >>>> +	CLK_5( IMX8QXP_I2C3_IPG_CLK, "I2C3_IPG", 16,
> >>>> LPI2C_3_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0,
> >>>> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI0_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QXP_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 16,
> >>>> DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
> >>>> +	CLK_5( IMX8QXP_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0,
> >>>> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI0_I2C1_DIV ),
> >>>> +	CLK_5( IMX8QXP_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 16,
> >>>> DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
> >>>> +	CLK_5( IMX8QXP_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0,
> >>>> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI1_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QXP_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 16,
> >>>> DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ),
> >>>> +	CLK_5( IMX8QXP_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0,
> >>>> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI1_I2C1_DIV ),
> >>>> +	CLK_5( IMX8QXP_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 16,
> >>>> DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ),
> >>>> +	CLK_5( IMX8QXP_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0,
> >>>> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_CSI0_I2C0_DIV ),
> >>>> +	CLK_5( IMX8QXP_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16,
> >>>> MIPI_CSI_0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ), +
> >>>> +	CLK_5( IMX8QXP_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG,
> >>>> IMX8QXP_UART0_DIV ),
> >>>> +	CLK_5( IMX8QXP_UART0_IPG_CLK, "UART0_IPG", 16,
> >>>> LPUART_0_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG,
> >>>> IMX8QXP_UART1_DIV ),
> >>>> +	CLK_5( IMX8QXP_UART1_IPG_CLK, "UART1_IPG", 16,
> >>>> LPUART_1_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG,
> >>>> IMX8QXP_UART2_DIV ),
> >>>> +	CLK_5( IMX8QXP_UART2_IPG_CLK, "UART2_IPG", 16,
> >>>> LPUART_2_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG,
> >>>> IMX8QXP_UART3_DIV ),
> >>>> +	CLK_5( IMX8QXP_UART3_IPG_CLK, "UART3_IPG", 16,
> >>>> LPUART_3_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ), +
> >>>> +	CLK_5( IMX8QXP_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG,
> >>>> IMX8QXP_SDHC0_DIV ),
> >>>> +	CLK_5( IMX8QXP_SDHC0_IPG_CLK, "SDHC0_IPG", 16,
> >>>> USDHC_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG,
> >>>> IMX8QXP_SDHC1_DIV ),
> >>>> +	CLK_5( IMX8QXP_SDHC1_IPG_CLK, "SDHC1_IPG", 16,
> >>>> USDHC_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG,
> >>>> IMX8QXP_SDHC2_DIV ),
> >>>> +	CLK_5( IMX8QXP_SDHC2_IPG_CLK, "SDHC2_IPG", 16,
> >>>> USDHC_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), +
> >>>> +	CLK_5( IMX8QXP_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20,
> >>>> ENET_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG", 16,
> >>>> ENET_0_LPCG, IMX8QXP_ENET0_IPG_S_CLK ),
> >>>> +	CLK_5( IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB", 8,
> >>>> ENET_0_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG,
> >>>> IMX8QXP_ENET0_ROOT_DIV ),
> >>>> +	CLK_5( IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP", 0,
> >>>> ENET_0_LPCG, IMX8QXP_ENET0_ROOT_DIV  ),
> >>>> +	CLK_5( IMX8QXP_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12,
> >>>> ENET_0_LPCG, IMX8QXP_ENET0_RMII_TX_SEL  ),
> >>>> +	CLK_5( IMX8QXP_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0,
> >>>> ENET_0_LPCG + 0x4, IMX8QXP_ENET0_RGMII_DIV  ), +
> >>>> +	CLK_5( IMX8QXP_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20,
> >>>> ENET_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG", 16,
> >>>> ENET_1_LPCG, IMX8QXP_ENET1_IPG_S_CLK ),
> >>>> +	CLK_5( IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB", 8,
> >>>> ENET_1_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG,
> >>>> IMX8QXP_ENET1_ROOT_DIV ),
> >>>> +	CLK_5( IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP", 0,
> >>>> ENET_1_LPCG, IMX8QXP_ENET1_ROOT_DIV  ),
> >>>> +	CLK_5( IMX8QXP_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12,
> >>>> ENET_1_LPCG, IMX8QXP_ENET1_RMII_TX_SEL  ),
> >>>> +	CLK_5( IMX8QXP_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0,
> >>>> ENET_1_LPCG + 0x4, IMX8QXP_ENET1_RGMII_DIV  ), +
> >>>> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_S_CLK, "FSPI0_IPG_S",
> >>>> 0x18, FSPI_0_LPCG, IMX8QXP_LSIO_BUS_CLK ),
> >>>> +	CLK_5( IMX8QXP_LSIO_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14,
> >>>> FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_IPG_S_CLK ),
> >>>> +	CLK_5( IMX8QXP_LSIO_FSPI0_HCLK, "FSPI0_HCLK", 0x10,
> >>>> FSPI_0_LPCG, IMX8QXP_LSIO_MEM_CLK ),
> >>>> +	CLK_5( IMX8QXP_LSIO_FSPI0_CLK, "FSPI0_CLK", 0,
> >>>> FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_DIV ), +
> >>>> +	CLK_5( IMX8QXP_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24,
> >>>> USB_2_LPCG, IMX8QXP_AHB_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16,
> >>>> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_USB2_OH_IPG_S_PL301_CLK,
> >>>> "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT
> >>>> ),
> >>>> +	CLK_5( IMX8QXP_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28,
> >>>> USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), +
> >>>> +	CLK_5( IMX8QXP_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG,
> >>>> IMX8QXP_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_USB3_CORE_PCLK, "USB3_CORE", 20,
> >>>> USB_3_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG,
> >>>> IMX8QXP_USB3_IPG_CLK ),
> >>>> +	CLK_5( IMX8QXP_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG,
> >>>> IMX8QXP_USB3_ACLK_DIV ),
> >>>> +	CLK_5( IMX8QXP_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG,
> >>>> IMX8QXP_USB3_BUS_DIV ),
> >>>> +	CLK_5( IMX8QXP_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG,
> >>>> IMX8QXP_USB3_LPM_DIV ), +
> >>>> +	CLK_5( IMX8QXP_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG,
> >>>> IMX8QXP_AXI_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20,
> >>>> NAND_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ),
> >>>> +	CLK_5( IMX8QXP_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4,
> >>>> NAND_LPCG, IMX8QXP_GPMI_BCH_IO_DIV ),
> >>>> +	CLK_5( IMX8QXP_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0,
> >>>> NAND_LPCG, IMX8QXP_GPMI_BCH_DIV ),
> >>>> +	CLK_5( IMX8QXP_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG +
> >>>> 0x4, IMX8QXP_AXI_CONN_CLK_ROOT ), +};
> >>>>  
> >>>> -	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable,
> >>>> 0);
> >>>> -	if (ret) {
> >>>> -		printf("%s err %d\n", __func__, ret);
> >>>> -		return ret;
> >>>> -	}
> >>>> +struct imx8_mux_clks imx8qxp_mux_clks[] = {
> >>>> +	CLK_MUX( IMX8QXP_SDHC0_SEL, "SDHC0_SEL",
> >>>> IMX8QXP_SDHC0_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
> >>>> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
> >>>> IMX8QXP_CLK_DUMMY ),
> >>>> +	CLK_MUX( IMX8QXP_SDHC1_SEL, "SDHC1_SEL",
> >>>> IMX8QXP_SDHC1_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
> >>>> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
> >>>> IMX8QXP_CLK_DUMMY ),
> >>>> +	CLK_MUX( IMX8QXP_SDHC2_SEL, "SDHC2_SEL",
> >>>> IMX8QXP_SDHC2_DIV, IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK,
> >>>> +		IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY,
> >>>> IMX8QXP_CLK_DUMMY ), +};
> >>>>  
> >>>> -	return 0;
> >>>> -}
> >>>> +struct imx8_clks_collect imx8qxp_clk_collect = {
> >>>> +	{
> >>>> +		{&imx8qxp_clks, ARRAY_SIZE(imx8qxp_clks)},
> >>>> +		{&imx8qxp_fixed_clks,
> >>>> ARRAY_SIZE(imx8qxp_fixed_clks)},
> >>>> +		{&imx8qxp_gpr_clks,
> >>>> ARRAY_SIZE(imx8qxp_gpr_clks)},
> >>>> +		{&imx8qxp_lpcg_clks,
> >>>> ARRAY_SIZE(imx8qxp_lpcg_clks)},
> >>>> +		{&imx8qxp_mux_clks,
> >>>> ARRAY_SIZE(imx8qxp_mux_clks)},
> >>>> +	},
> >>>> +	FLAG_CLK_IMX8_IMX8QXP,
> >>>> +};    
> >>>
> >>>
> >>>
> >>>
> >>> Best regards,
> >>>
> >>> Lukasz Majewski
> >>>
> >>> --
> >>>
> >>> DENX Software Engineering GmbH,      Managing Director: Wolfgang
> >>> Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell,
> >>> Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
> >>> lukma at denx.de   
> >>  
> > 
> > 
> > 
> > 
> > Best regards,
> > 
> > Lukasz Majewski
> > 
> > --
> > 
> > DENX Software Engineering GmbH,      Managing Director: Wolfgang
> > Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell,
> > Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
> > lukma at denx.de 
> 




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190710/14a2592e/attachment.sig>

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

end of thread, other threads:[~2019-07-10  8:46 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-03  5:40 [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP Ye Li
2019-07-03  5:40 ` [U-Boot] [PATCH 2/5] misc: scu_api: Add new APIs for clk-imx8 driver Ye Li
2019-07-03  6:04   ` Peng Fan
2019-07-03  5:40 ` [U-Boot] [PATCH 3/5] clk: imx8: Update imx8 clock driver Ye Li
2019-07-06 23:07   ` Lukasz Majewski
2019-07-10  7:14     ` [U-Boot] [EXT] " Ye Li
2019-07-10  7:34       ` Lukasz Majewski
2019-07-10  8:25         ` Ye Li
2019-07-10  8:46           ` Lukasz Majewski
2019-07-03  5:40 ` [U-Boot] [PATCH 4/5] imx8qm_mek: increase the size of early malloc pool Ye Li
2019-07-03  5:40 ` [U-Boot] [PATCH 5/5] net: fec_mxc: Update driver to use full clks for iMX8 Ye Li
2019-07-06 23:09   ` Lukasz Majewski
2019-07-10  5:45     ` [U-Boot] [EXT] " Ye Li
2019-07-03  6:02 ` [U-Boot] [PATCH 1/5] imx8: Add lpcg driver for iMX8QM/QXP Peng Fan

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.