1 // SPDX-License-Identifier: GPL-2.0+
4 * Dong Aisheng <aisheng.dong@nxp.com>
7 #include <linux/clk-provider.h>
10 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/slab.h>
17 #include <dt-bindings/clock/imx8-clock.h>
18 #include <dt-bindings/firmware/imx/rsrc.h>
20 static int imx8qxp_clk_probe(struct platform_device
*pdev
)
22 struct device_node
*ccm_node
= pdev
->dev
.of_node
;
23 struct clk_hw_onecell_data
*clk_data
;
28 ret
= imx_clk_scu_init(ccm_node
);
32 clk_data
= devm_kzalloc(&pdev
->dev
, struct_size(clk_data
, hws
,
33 IMX_SCU_CLK_END
), GFP_KERNEL
);
37 if (of_property_read_u32(ccm_node
, "#clock-cells", &clk_cells
))
40 clk_data
->num
= IMX_SCU_CLK_END
;
44 clks
[IMX_CLK_DUMMY
] = clk_hw_register_fixed_rate(NULL
, "dummy", NULL
, 0, 0);
45 clks
[IMX_ADMA_IPG_CLK_ROOT
] = clk_hw_register_fixed_rate(NULL
, "dma_ipg_clk_root", NULL
, 0, 120000000);
46 clks
[IMX_CONN_AXI_CLK_ROOT
] = clk_hw_register_fixed_rate(NULL
, "conn_axi_clk_root", NULL
, 0, 333333333);
47 clks
[IMX_CONN_AHB_CLK_ROOT
] = clk_hw_register_fixed_rate(NULL
, "conn_ahb_clk_root", NULL
, 0, 166666666);
48 clks
[IMX_CONN_IPG_CLK_ROOT
] = clk_hw_register_fixed_rate(NULL
, "conn_ipg_clk_root", NULL
, 0, 83333333);
49 clks
[IMX_DC_AXI_EXT_CLK
] = clk_hw_register_fixed_rate(NULL
, "dc_axi_ext_clk_root", NULL
, 0, 800000000);
50 clks
[IMX_DC_AXI_INT_CLK
] = clk_hw_register_fixed_rate(NULL
, "dc_axi_int_clk_root", NULL
, 0, 400000000);
51 clks
[IMX_DC_CFG_CLK
] = clk_hw_register_fixed_rate(NULL
, "dc_cfg_clk_root", NULL
, 0, 100000000);
52 clks
[IMX_MIPI_IPG_CLK
] = clk_hw_register_fixed_rate(NULL
, "mipi_ipg_clk_root", NULL
, 0, 120000000);
53 clks
[IMX_IMG_AXI_CLK
] = clk_hw_register_fixed_rate(NULL
, "img_axi_clk_root", NULL
, 0, 400000000);
54 clks
[IMX_IMG_IPG_CLK
] = clk_hw_register_fixed_rate(NULL
, "img_ipg_clk_root", NULL
, 0, 200000000);
55 clks
[IMX_IMG_PXL_CLK
] = clk_hw_register_fixed_rate(NULL
, "img_pxl_clk_root", NULL
, 0, 600000000);
56 clks
[IMX_HSIO_AXI_CLK
] = clk_hw_register_fixed_rate(NULL
, "hsio_axi_clk_root", NULL
, 0, 400000000);
57 clks
[IMX_HSIO_PER_CLK
] = clk_hw_register_fixed_rate(NULL
, "hsio_per_clk_root", NULL
, 0, 133333333);
58 clks
[IMX_LSIO_MEM_CLK
] = clk_hw_register_fixed_rate(NULL
, "lsio_mem_clk_root", NULL
, 0, 200000000);
59 clks
[IMX_LSIO_BUS_CLK
] = clk_hw_register_fixed_rate(NULL
, "lsio_bus_clk_root", NULL
, 0, 100000000);
62 clks
[IMX_A35_CLK
] = imx_clk_scu("a35_clk", IMX_SC_R_A35
, IMX_SC_PM_CLK_CPU
, clk_cells
);
65 clks
[IMX_LSIO_PWM0_CLK
] = imx_clk_scu("pwm0_clk", IMX_SC_R_PWM_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
66 clks
[IMX_LSIO_PWM1_CLK
] = imx_clk_scu("pwm1_clk", IMX_SC_R_PWM_1
, IMX_SC_PM_CLK_PER
, clk_cells
);
67 clks
[IMX_LSIO_PWM2_CLK
] = imx_clk_scu("pwm2_clk", IMX_SC_R_PWM_2
, IMX_SC_PM_CLK_PER
, clk_cells
);
68 clks
[IMX_LSIO_PWM3_CLK
] = imx_clk_scu("pwm3_clk", IMX_SC_R_PWM_3
, IMX_SC_PM_CLK_PER
, clk_cells
);
69 clks
[IMX_LSIO_PWM4_CLK
] = imx_clk_scu("pwm4_clk", IMX_SC_R_PWM_4
, IMX_SC_PM_CLK_PER
, clk_cells
);
70 clks
[IMX_LSIO_PWM5_CLK
] = imx_clk_scu("pwm5_clk", IMX_SC_R_PWM_5
, IMX_SC_PM_CLK_PER
, clk_cells
);
71 clks
[IMX_LSIO_PWM6_CLK
] = imx_clk_scu("pwm6_clk", IMX_SC_R_PWM_6
, IMX_SC_PM_CLK_PER
, clk_cells
);
72 clks
[IMX_LSIO_PWM7_CLK
] = imx_clk_scu("pwm7_clk", IMX_SC_R_PWM_7
, IMX_SC_PM_CLK_PER
, clk_cells
);
73 clks
[IMX_LSIO_GPT0_CLK
] = imx_clk_scu("gpt0_clk", IMX_SC_R_GPT_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
74 clks
[IMX_LSIO_GPT1_CLK
] = imx_clk_scu("gpt1_clk", IMX_SC_R_GPT_1
, IMX_SC_PM_CLK_PER
, clk_cells
);
75 clks
[IMX_LSIO_GPT2_CLK
] = imx_clk_scu("gpt2_clk", IMX_SC_R_GPT_2
, IMX_SC_PM_CLK_PER
, clk_cells
);
76 clks
[IMX_LSIO_GPT3_CLK
] = imx_clk_scu("gpt3_clk", IMX_SC_R_GPT_3
, IMX_SC_PM_CLK_PER
, clk_cells
);
77 clks
[IMX_LSIO_GPT4_CLK
] = imx_clk_scu("gpt4_clk", IMX_SC_R_GPT_4
, IMX_SC_PM_CLK_PER
, clk_cells
);
78 clks
[IMX_LSIO_FSPI0_CLK
] = imx_clk_scu("fspi0_clk", IMX_SC_R_FSPI_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
79 clks
[IMX_LSIO_FSPI1_CLK
] = imx_clk_scu("fspi1_clk", IMX_SC_R_FSPI_1
, IMX_SC_PM_CLK_PER
, clk_cells
);
82 clks
[IMX_ADMA_UART0_CLK
] = imx_clk_scu("uart0_clk", IMX_SC_R_UART_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
83 clks
[IMX_ADMA_UART1_CLK
] = imx_clk_scu("uart1_clk", IMX_SC_R_UART_1
, IMX_SC_PM_CLK_PER
, clk_cells
);
84 clks
[IMX_ADMA_UART2_CLK
] = imx_clk_scu("uart2_clk", IMX_SC_R_UART_2
, IMX_SC_PM_CLK_PER
, clk_cells
);
85 clks
[IMX_ADMA_UART3_CLK
] = imx_clk_scu("uart3_clk", IMX_SC_R_UART_3
, IMX_SC_PM_CLK_PER
, clk_cells
);
86 clks
[IMX_ADMA_SPI0_CLK
] = imx_clk_scu("spi0_clk", IMX_SC_R_SPI_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
87 clks
[IMX_ADMA_SPI1_CLK
] = imx_clk_scu("spi1_clk", IMX_SC_R_SPI_1
, IMX_SC_PM_CLK_PER
, clk_cells
);
88 clks
[IMX_ADMA_SPI2_CLK
] = imx_clk_scu("spi2_clk", IMX_SC_R_SPI_2
, IMX_SC_PM_CLK_PER
, clk_cells
);
89 clks
[IMX_ADMA_SPI3_CLK
] = imx_clk_scu("spi3_clk", IMX_SC_R_SPI_3
, IMX_SC_PM_CLK_PER
, clk_cells
);
90 clks
[IMX_ADMA_CAN0_CLK
] = imx_clk_scu("can0_clk", IMX_SC_R_CAN_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
91 clks
[IMX_ADMA_I2C0_CLK
] = imx_clk_scu("i2c0_clk", IMX_SC_R_I2C_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
92 clks
[IMX_ADMA_I2C1_CLK
] = imx_clk_scu("i2c1_clk", IMX_SC_R_I2C_1
, IMX_SC_PM_CLK_PER
, clk_cells
);
93 clks
[IMX_ADMA_I2C2_CLK
] = imx_clk_scu("i2c2_clk", IMX_SC_R_I2C_2
, IMX_SC_PM_CLK_PER
, clk_cells
);
94 clks
[IMX_ADMA_I2C3_CLK
] = imx_clk_scu("i2c3_clk", IMX_SC_R_I2C_3
, IMX_SC_PM_CLK_PER
, clk_cells
);
95 clks
[IMX_ADMA_FTM0_CLK
] = imx_clk_scu("ftm0_clk", IMX_SC_R_FTM_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
96 clks
[IMX_ADMA_FTM1_CLK
] = imx_clk_scu("ftm1_clk", IMX_SC_R_FTM_1
, IMX_SC_PM_CLK_PER
, clk_cells
);
97 clks
[IMX_ADMA_ADC0_CLK
] = imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
98 clks
[IMX_ADMA_PWM_CLK
] = imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
99 clks
[IMX_ADMA_LCD_CLK
] = imx_clk_scu("lcd_clk", IMX_SC_R_LCD_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
102 clks
[IMX_CONN_SDHC0_CLK
] = imx_clk_scu("sdhc0_clk", IMX_SC_R_SDHC_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
103 clks
[IMX_CONN_SDHC1_CLK
] = imx_clk_scu("sdhc1_clk", IMX_SC_R_SDHC_1
, IMX_SC_PM_CLK_PER
, clk_cells
);
104 clks
[IMX_CONN_SDHC2_CLK
] = imx_clk_scu("sdhc2_clk", IMX_SC_R_SDHC_2
, IMX_SC_PM_CLK_PER
, clk_cells
);
105 clks
[IMX_CONN_ENET0_ROOT_CLK
] = imx_clk_scu("enet0_clk", IMX_SC_R_ENET_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
106 clks
[IMX_CONN_ENET0_BYPASS_CLK
] = imx_clk_scu("enet0_bypass_clk", IMX_SC_R_ENET_0
, IMX_SC_PM_CLK_BYPASS
, clk_cells
);
107 clks
[IMX_CONN_ENET0_RGMII_CLK
] = imx_clk_scu("enet0_rgmii_clk", IMX_SC_R_ENET_0
, IMX_SC_PM_CLK_MISC0
, clk_cells
);
108 clks
[IMX_CONN_ENET1_ROOT_CLK
] = imx_clk_scu("enet1_clk", IMX_SC_R_ENET_1
, IMX_SC_PM_CLK_PER
, clk_cells
);
109 clks
[IMX_CONN_ENET1_BYPASS_CLK
] = imx_clk_scu("enet1_bypass_clk", IMX_SC_R_ENET_1
, IMX_SC_PM_CLK_BYPASS
, clk_cells
);
110 clks
[IMX_CONN_ENET1_RGMII_CLK
] = imx_clk_scu("enet1_rgmii_clk", IMX_SC_R_ENET_1
, IMX_SC_PM_CLK_MISC0
, clk_cells
);
111 clks
[IMX_CONN_GPMI_BCH_IO_CLK
] = imx_clk_scu("gpmi_io_clk", IMX_SC_R_NAND
, IMX_SC_PM_CLK_MST_BUS
, clk_cells
);
112 clks
[IMX_CONN_GPMI_BCH_CLK
] = imx_clk_scu("gpmi_bch_clk", IMX_SC_R_NAND
, IMX_SC_PM_CLK_PER
, clk_cells
);
113 clks
[IMX_CONN_USB2_ACLK
] = imx_clk_scu("usb3_aclk_div", IMX_SC_R_USB_2
, IMX_SC_PM_CLK_PER
, clk_cells
);
114 clks
[IMX_CONN_USB2_BUS_CLK
] = imx_clk_scu("usb3_bus_div", IMX_SC_R_USB_2
, IMX_SC_PM_CLK_MST_BUS
, clk_cells
);
115 clks
[IMX_CONN_USB2_LPM_CLK
] = imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2
, IMX_SC_PM_CLK_MISC
, clk_cells
);
117 /* Display controller SS */
118 clks
[IMX_DC0_DISP0_CLK
] = imx_clk_scu("dc0_disp0_clk", IMX_SC_R_DC_0
, IMX_SC_PM_CLK_MISC0
, clk_cells
);
119 clks
[IMX_DC0_DISP1_CLK
] = imx_clk_scu("dc0_disp1_clk", IMX_SC_R_DC_0
, IMX_SC_PM_CLK_MISC1
, clk_cells
);
122 clks
[IMX_MIPI0_I2C0_CLK
] = imx_clk_scu("mipi0_i2c0_clk", IMX_SC_R_MIPI_0_I2C_0
, IMX_SC_PM_CLK_MISC2
, clk_cells
);
123 clks
[IMX_MIPI0_I2C1_CLK
] = imx_clk_scu("mipi0_i2c1_clk", IMX_SC_R_MIPI_0_I2C_1
, IMX_SC_PM_CLK_MISC2
, clk_cells
);
126 clks
[IMX_CSI0_CORE_CLK
] = imx_clk_scu("mipi_csi0_core_clk", IMX_SC_R_CSI_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
127 clks
[IMX_CSI0_ESC_CLK
] = imx_clk_scu("mipi_csi0_esc_clk", IMX_SC_R_CSI_0
, IMX_SC_PM_CLK_MISC
, clk_cells
);
128 clks
[IMX_CSI0_I2C0_CLK
] = imx_clk_scu("mipi_csi0_i2c0_clk", IMX_SC_R_CSI_0_I2C_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
129 clks
[IMX_CSI0_PWM0_CLK
] = imx_clk_scu("mipi_csi0_pwm0_clk", IMX_SC_R_CSI_0_PWM_0
, IMX_SC_PM_CLK_PER
, clk_cells
);
132 clks
[IMX_GPU0_CORE_CLK
] = imx_clk_scu("gpu_core0_clk", IMX_SC_R_GPU_0_PID0
, IMX_SC_PM_CLK_PER
, clk_cells
);
133 clks
[IMX_GPU0_SHADER_CLK
] = imx_clk_scu("gpu_shader0_clk", IMX_SC_R_GPU_0_PID0
, IMX_SC_PM_CLK_MISC
, clk_cells
);
135 for (i
= 0; i
< clk_data
->num
; i
++) {
137 pr_warn("i.MX clk %u: register failed with %ld\n",
138 i
, PTR_ERR(clks
[i
]));
141 if (clk_cells
== 2) {
142 ret
= of_clk_add_hw_provider(ccm_node
, imx_scu_of_clk_src_get
, imx_scu_clks
);
144 imx_clk_scu_unregister();
147 * legacy binding code path doesn't unregister here because
148 * it will be removed later.
150 ret
= of_clk_add_hw_provider(ccm_node
, of_clk_hw_onecell_get
, clk_data
);
156 static const struct of_device_id imx8qxp_match
[] = {
157 { .compatible
= "fsl,scu-clk", },
158 { .compatible
= "fsl,imx8qxp-clk", },
162 static struct platform_driver imx8qxp_clk_driver
= {
164 .name
= "imx8qxp-clk",
165 .of_match_table
= imx8qxp_match
,
166 .suppress_bind_attrs
= true,
168 .probe
= imx8qxp_clk_probe
,
170 builtin_platform_driver(imx8qxp_clk_driver
);
172 MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
173 MODULE_DESCRIPTION("NXP i.MX8QXP clock driver");
174 MODULE_LICENSE("GPL v2");