1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (C) 2016 Freescale Semiconductor, Inc. |
4 | * Copyright 2017~2018 NXP |
5 | * |
6 | * Author: Dong Aisheng <aisheng.dong@nxp.com> |
7 | * |
8 | */ |
9 | |
10 | #include <dt-bindings/clock/imx7ulp-clock.h> |
11 | #include <linux/clk-provider.h> |
12 | #include <linux/err.h> |
13 | #include <linux/init.h> |
14 | #include <linux/io.h> |
15 | #include <linux/of.h> |
16 | #include <linux/of_address.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/slab.h> |
19 | |
20 | #include "clk.h" |
21 | |
22 | static const char * const pll_pre_sels[] = { "sosc" , "firc" , }; |
23 | static const char * const spll_pfd_sels[] = { "spll_pfd0" , "spll_pfd1" , "spll_pfd2" , "spll_pfd3" , }; |
24 | static const char * const spll_sels[] = { "spll" , "spll_pfd_sel" , }; |
25 | static const char * const apll_pfd_sels[] = { "apll_pfd0" , "apll_pfd1" , "apll_pfd2" , "apll_pfd3" , }; |
26 | static const char * const apll_sels[] = { "apll" , "apll_pfd_sel" , }; |
27 | static const char * const scs_sels[] = { "dummy" , "sosc" , "sirc" , "firc" , "dummy" , "apll_sel" , "spll_sel" , "dummy" , }; |
28 | static const char * const ddr_sels[] = { "apll_pfd_sel" , "dummy" , "dummy" , "dummy" , }; |
29 | static const char * const nic_sels[] = { "firc" , "ddr_clk" , }; |
30 | static const char * const periph_plat_sels[] = { "dummy" , "nic1_bus_clk" , "nic1_clk" , "ddr_clk" , "apll_pfd2" , "apll_pfd1" , "apll_pfd0" , "upll" , }; |
31 | static const char * const periph_bus_sels[] = { "dummy" , "sosc_bus_clk" , "dummy" , "firc_bus_clk" , "rosc" , "nic1_bus_clk" , "nic1_clk" , "spll_bus_clk" , }; |
32 | static const char * const arm_sels[] = { "core" , "dummy" , "dummy" , "hsrun_core" , }; |
33 | |
34 | /* used by sosc/sirc/firc/ddr/spll/apll dividers */ |
35 | static const struct clk_div_table ulp_div_table[] = { |
36 | { .val = 1, .div = 1, }, |
37 | { .val = 2, .div = 2, }, |
38 | { .val = 3, .div = 4, }, |
39 | { .val = 4, .div = 8, }, |
40 | { .val = 5, .div = 16, }, |
41 | { .val = 6, .div = 32, }, |
42 | { .val = 7, .div = 64, }, |
43 | { /* sentinel */ }, |
44 | }; |
45 | |
46 | static void __init imx7ulp_clk_scg1_init(struct device_node *np) |
47 | { |
48 | struct clk_hw_onecell_data *clk_data; |
49 | struct clk_hw **hws; |
50 | void __iomem *base; |
51 | |
52 | clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SCG1_END), |
53 | GFP_KERNEL); |
54 | if (!clk_data) |
55 | return; |
56 | |
57 | clk_data->num = IMX7ULP_CLK_SCG1_END; |
58 | hws = clk_data->hws; |
59 | |
60 | hws[IMX7ULP_CLK_DUMMY] = imx_clk_hw_fixed(name: "dummy" , rate: 0); |
61 | |
62 | hws[IMX7ULP_CLK_ROSC] = imx_get_clk_hw_by_name(np, name: "rosc" ); |
63 | hws[IMX7ULP_CLK_SOSC] = imx_get_clk_hw_by_name(np, name: "sosc" ); |
64 | hws[IMX7ULP_CLK_SIRC] = imx_get_clk_hw_by_name(np, name: "sirc" ); |
65 | hws[IMX7ULP_CLK_FIRC] = imx_get_clk_hw_by_name(np, name: "firc" ); |
66 | hws[IMX7ULP_CLK_UPLL] = imx_get_clk_hw_by_name(np, name: "upll" ); |
67 | |
68 | /* SCG1 */ |
69 | base = of_iomap(node: np, index: 0); |
70 | WARN_ON(!base); |
71 | |
72 | /* NOTE: xPLL config can't be changed when xPLL is enabled */ |
73 | hws[IMX7ULP_CLK_APLL_PRE_SEL] = imx_clk_hw_mux_flags("apll_pre_sel" , base + 0x508, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); |
74 | hws[IMX7ULP_CLK_SPLL_PRE_SEL] = imx_clk_hw_mux_flags("spll_pre_sel" , base + 0x608, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); |
75 | |
76 | /* name parent_name reg shift width flags */ |
77 | hws[IMX7ULP_CLK_APLL_PRE_DIV] = imx_clk_hw_divider_flags("apll_pre_div" , "apll_pre_sel" , base + 0x508, 8, 3, CLK_SET_RATE_GATE); |
78 | hws[IMX7ULP_CLK_SPLL_PRE_DIV] = imx_clk_hw_divider_flags("spll_pre_div" , "spll_pre_sel" , base + 0x608, 8, 3, CLK_SET_RATE_GATE); |
79 | |
80 | /* name parent_name base */ |
81 | hws[IMX7ULP_CLK_APLL] = imx_clk_hw_pllv4(type: IMX_PLLV4_IMX7ULP, name: "apll" , parent_name: "apll_pre_div" , base: base + 0x500); |
82 | hws[IMX7ULP_CLK_SPLL] = imx_clk_hw_pllv4(type: IMX_PLLV4_IMX7ULP, name: "spll" , parent_name: "spll_pre_div" , base: base + 0x600); |
83 | |
84 | /* APLL PFDs */ |
85 | hws[IMX7ULP_CLK_APLL_PFD0] = imx_clk_hw_pfdv2(type: IMX_PFDV2_IMX7ULP, name: "apll_pfd0" , parent_name: "apll" , reg: base + 0x50c, idx: 0); |
86 | hws[IMX7ULP_CLK_APLL_PFD1] = imx_clk_hw_pfdv2(type: IMX_PFDV2_IMX7ULP, name: "apll_pfd1" , parent_name: "apll" , reg: base + 0x50c, idx: 1); |
87 | hws[IMX7ULP_CLK_APLL_PFD2] = imx_clk_hw_pfdv2(type: IMX_PFDV2_IMX7ULP, name: "apll_pfd2" , parent_name: "apll" , reg: base + 0x50c, idx: 2); |
88 | hws[IMX7ULP_CLK_APLL_PFD3] = imx_clk_hw_pfdv2(type: IMX_PFDV2_IMX7ULP, name: "apll_pfd3" , parent_name: "apll" , reg: base + 0x50c, idx: 3); |
89 | |
90 | /* SPLL PFDs */ |
91 | hws[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_hw_pfdv2(type: IMX_PFDV2_IMX7ULP, name: "spll_pfd0" , parent_name: "spll" , reg: base + 0x60C, idx: 0); |
92 | hws[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_hw_pfdv2(type: IMX_PFDV2_IMX7ULP, name: "spll_pfd1" , parent_name: "spll" , reg: base + 0x60C, idx: 1); |
93 | hws[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_hw_pfdv2(type: IMX_PFDV2_IMX7ULP, name: "spll_pfd2" , parent_name: "spll" , reg: base + 0x60C, idx: 2); |
94 | hws[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_hw_pfdv2(type: IMX_PFDV2_IMX7ULP, name: "spll_pfd3" , parent_name: "spll" , reg: base + 0x60C, idx: 3); |
95 | |
96 | /* PLL Mux */ |
97 | hws[IMX7ULP_CLK_APLL_PFD_SEL] = imx_clk_hw_mux_flags("apll_pfd_sel" , base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); |
98 | hws[IMX7ULP_CLK_SPLL_PFD_SEL] = imx_clk_hw_mux_flags("spll_pfd_sel" , base + 0x608, 14, 2, spll_pfd_sels, ARRAY_SIZE(spll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); |
99 | hws[IMX7ULP_CLK_APLL_SEL] = imx_clk_hw_mux_flags("apll_sel" , base + 0x508, 1, 1, apll_sels, ARRAY_SIZE(apll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); |
100 | hws[IMX7ULP_CLK_SPLL_SEL] = imx_clk_hw_mux_flags("spll_sel" , base + 0x608, 1, 1, spll_sels, ARRAY_SIZE(spll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); |
101 | |
102 | hws[IMX7ULP_CLK_SPLL_BUS_CLK] = imx_clk_hw_divider_gate(name: "spll_bus_clk" , parent_name: "spll_sel" , CLK_SET_RATE_GATE, reg: base + 0x604, shift: 8, width: 3, clk_divider_flags: 0, table: ulp_div_table, lock: &imx_ccm_lock); |
103 | |
104 | /* scs/ddr/nic select different clock source requires that clock to be enabled first */ |
105 | hws[IMX7ULP_CLK_SYS_SEL] = imx_clk_hw_mux2("scs_sel" , base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); |
106 | hws[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_hw_mux2("hsrun_scs_sel" , base + 0x1c, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); |
107 | hws[IMX7ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel" , base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels)); |
108 | hws[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel" , base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); |
109 | |
110 | hws[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore" , "scs_sel" , base + 0x14, 16, 4, CLK_SET_RATE_PARENT); |
111 | hws[IMX7ULP_CLK_CORE] = imx_clk_hw_cpu(name: "core" , parent_name: "divcore" , div: hws[IMX7ULP_CLK_CORE_DIV]->clk, mux: hws[IMX7ULP_CLK_SYS_SEL]->clk, pll: hws[IMX7ULP_CLK_SPLL_SEL]->clk, step: hws[IMX7ULP_CLK_FIRC]->clk); |
112 | hws[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore" , "hsrun_scs_sel" , base + 0x1c, 16, 4, CLK_SET_RATE_PARENT); |
113 | hws[IMX7ULP_CLK_HSRUN_CORE] = imx_clk_hw_cpu(name: "hsrun_core" , parent_name: "hsrun_divcore" , div: hws[IMX7ULP_CLK_HSRUN_CORE_DIV]->clk, mux: hws[IMX7ULP_CLK_HSRUN_SYS_SEL]->clk, pll: hws[IMX7ULP_CLK_SPLL_SEL]->clk, step: hws[IMX7ULP_CLK_FIRC]->clk); |
114 | |
115 | hws[IMX7ULP_CLK_DDR_DIV] = imx_clk_hw_divider_gate(name: "ddr_clk" , parent_name: "ddr_sel" , CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, reg: base + 0x30, shift: 0, width: 3, |
116 | clk_divider_flags: 0, table: ulp_div_table, lock: &imx_ccm_lock); |
117 | |
118 | hws[IMX7ULP_CLK_NIC0_DIV] = imx_clk_hw_divider_flags("nic0_clk" , "nic_sel" , base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); |
119 | hws[IMX7ULP_CLK_NIC1_DIV] = imx_clk_hw_divider_flags("nic1_clk" , "nic0_clk" , base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); |
120 | hws[IMX7ULP_CLK_NIC1_BUS_DIV] = imx_clk_hw_divider_flags("nic1_bus_clk" , "nic0_clk" , base + 0x40, 4, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); |
121 | |
122 | hws[IMX7ULP_CLK_GPU_DIV] = imx_clk_hw_divider("gpu_clk" , "nic0_clk" , base + 0x40, 20, 4); |
123 | |
124 | hws[IMX7ULP_CLK_SOSC_BUS_CLK] = imx_clk_hw_divider_gate(name: "sosc_bus_clk" , parent_name: "sosc" , flags: 0, reg: base + 0x104, shift: 8, width: 3, |
125 | CLK_DIVIDER_READ_ONLY, table: ulp_div_table, lock: &imx_ccm_lock); |
126 | hws[IMX7ULP_CLK_FIRC_BUS_CLK] = imx_clk_hw_divider_gate(name: "firc_bus_clk" , parent_name: "firc" , flags: 0, reg: base + 0x304, shift: 8, width: 3, |
127 | CLK_DIVIDER_READ_ONLY, table: ulp_div_table, lock: &imx_ccm_lock); |
128 | |
129 | imx_check_clk_hws(clks: hws, count: clk_data->num); |
130 | |
131 | of_clk_add_hw_provider(np, get: of_clk_hw_onecell_get, data: clk_data); |
132 | } |
133 | CLK_OF_DECLARE(imx7ulp_clk_scg1, "fsl,imx7ulp-scg1" , imx7ulp_clk_scg1_init); |
134 | |
135 | static void __init imx7ulp_clk_pcc2_init(struct device_node *np) |
136 | { |
137 | struct clk_hw_onecell_data *clk_data; |
138 | struct clk_hw **hws; |
139 | void __iomem *base; |
140 | |
141 | clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC2_END), |
142 | GFP_KERNEL); |
143 | if (!clk_data) |
144 | return; |
145 | |
146 | clk_data->num = IMX7ULP_CLK_PCC2_END; |
147 | hws = clk_data->hws; |
148 | |
149 | /* PCC2 */ |
150 | base = of_iomap(node: np, index: 0); |
151 | WARN_ON(!base); |
152 | |
153 | hws[IMX7ULP_CLK_DMA1] = imx_clk_hw_gate("dma1" , "nic1_clk" , base + 0x20, 30); |
154 | hws[IMX7ULP_CLK_RGPIO2P1] = imx_clk_hw_gate("rgpio2p1" , "nic1_bus_clk" , base + 0x3c, 30); |
155 | hws[IMX7ULP_CLK_DMA_MUX1] = imx_clk_hw_gate("dma_mux1" , "nic1_bus_clk" , base + 0x84, 30); |
156 | hws[IMX7ULP_CLK_CAAM] = imx_clk_hw_gate("caam" , "nic1_clk" , base + 0x90, 30); |
157 | hws[IMX7ULP_CLK_LPTPM4] = imx7ulp_clk_hw_composite(name: "lptpm4" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x94); |
158 | hws[IMX7ULP_CLK_LPTPM5] = imx7ulp_clk_hw_composite(name: "lptpm5" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x98); |
159 | hws[IMX7ULP_CLK_LPIT1] = imx7ulp_clk_hw_composite(name: "lpit1" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x9c); |
160 | hws[IMX7ULP_CLK_LPSPI2] = imx7ulp_clk_hw_composite(name: "lpspi2" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0xa4); |
161 | hws[IMX7ULP_CLK_LPSPI3] = imx7ulp_clk_hw_composite(name: "lpspi3" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0xa8); |
162 | hws[IMX7ULP_CLK_LPI2C4] = imx7ulp_clk_hw_composite(name: "lpi2c4" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0xac); |
163 | hws[IMX7ULP_CLK_LPI2C5] = imx7ulp_clk_hw_composite(name: "lpi2c5" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0xb0); |
164 | hws[IMX7ULP_CLK_LPUART4] = imx7ulp_clk_hw_composite(name: "lpuart4" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0xb4); |
165 | hws[IMX7ULP_CLK_LPUART5] = imx7ulp_clk_hw_composite(name: "lpuart5" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0xb8); |
166 | hws[IMX7ULP_CLK_FLEXIO1] = imx7ulp_clk_hw_composite(name: "flexio1" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0xc4); |
167 | hws[IMX7ULP_CLK_USB0] = imx7ulp_clk_hw_composite(name: "usb0" , parent_names: periph_plat_sels, ARRAY_SIZE(periph_plat_sels), mux_present: true, rate_present: true, gate_present: true, reg: base + 0xcc); |
168 | hws[IMX7ULP_CLK_USB1] = imx7ulp_clk_hw_composite(name: "usb1" , parent_names: periph_plat_sels, ARRAY_SIZE(periph_plat_sels), mux_present: true, rate_present: true, gate_present: true, reg: base + 0xd0); |
169 | hws[IMX7ULP_CLK_USB_PHY] = imx_clk_hw_gate("usb_phy" , "nic1_bus_clk" , base + 0xd4, 30); |
170 | hws[IMX7ULP_CLK_USDHC0] = imx7ulp_clk_hw_composite(name: "usdhc0" , parent_names: periph_plat_sels, ARRAY_SIZE(periph_plat_sels), mux_present: true, rate_present: true, gate_present: true, reg: base + 0xdc); |
171 | hws[IMX7ULP_CLK_USDHC1] = imx7ulp_clk_hw_composite(name: "usdhc1" , parent_names: periph_plat_sels, ARRAY_SIZE(periph_plat_sels), mux_present: true, rate_present: true, gate_present: true, reg: base + 0xe0); |
172 | hws[IMX7ULP_CLK_WDG1] = imx7ulp_clk_hw_composite(name: "wdg1" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: true, gate_present: true, reg: base + 0xf4); |
173 | hws[IMX7ULP_CLK_WDG2] = imx7ulp_clk_hw_composite(name: "wdg2" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: true, gate_present: true, reg: base + 0x10c); |
174 | |
175 | imx_check_clk_hws(clks: hws, count: clk_data->num); |
176 | |
177 | of_clk_add_hw_provider(np, get: of_clk_hw_onecell_get, data: clk_data); |
178 | |
179 | imx_register_uart_clocks(); |
180 | } |
181 | CLK_OF_DECLARE(imx7ulp_clk_pcc2, "fsl,imx7ulp-pcc2" , imx7ulp_clk_pcc2_init); |
182 | |
183 | static void __init imx7ulp_clk_pcc3_init(struct device_node *np) |
184 | { |
185 | struct clk_hw_onecell_data *clk_data; |
186 | struct clk_hw **hws; |
187 | void __iomem *base; |
188 | |
189 | clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC3_END), |
190 | GFP_KERNEL); |
191 | if (!clk_data) |
192 | return; |
193 | |
194 | clk_data->num = IMX7ULP_CLK_PCC3_END; |
195 | hws = clk_data->hws; |
196 | |
197 | /* PCC3 */ |
198 | base = of_iomap(node: np, index: 0); |
199 | WARN_ON(!base); |
200 | |
201 | hws[IMX7ULP_CLK_LPTPM6] = imx7ulp_clk_hw_composite(name: "lptpm6" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x84); |
202 | hws[IMX7ULP_CLK_LPTPM7] = imx7ulp_clk_hw_composite(name: "lptpm7" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x88); |
203 | |
204 | hws[IMX7ULP_CLK_MMDC] = clk_hw_register_gate(NULL, "mmdc" , "nic1_clk" , CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, |
205 | base + 0xac, 30, 0, &imx_ccm_lock); |
206 | hws[IMX7ULP_CLK_LPI2C6] = imx7ulp_clk_hw_composite(name: "lpi2c6" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x90); |
207 | hws[IMX7ULP_CLK_LPI2C7] = imx7ulp_clk_hw_composite(name: "lpi2c7" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x94); |
208 | hws[IMX7ULP_CLK_LPUART6] = imx7ulp_clk_hw_composite(name: "lpuart6" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x98); |
209 | hws[IMX7ULP_CLK_LPUART7] = imx7ulp_clk_hw_composite(name: "lpuart7" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x9c); |
210 | hws[IMX7ULP_CLK_DSI] = imx7ulp_clk_hw_composite(name: "dsi" , parent_names: periph_bus_sels, ARRAY_SIZE(periph_bus_sels), mux_present: true, rate_present: true, gate_present: true, reg: base + 0xa4); |
211 | hws[IMX7ULP_CLK_LCDIF] = imx7ulp_clk_hw_composite(name: "lcdif" , parent_names: periph_plat_sels, ARRAY_SIZE(periph_plat_sels), mux_present: true, rate_present: true, gate_present: true, reg: base + 0xa8); |
212 | |
213 | hws[IMX7ULP_CLK_VIU] = imx_clk_hw_gate("viu" , "nic1_clk" , base + 0xa0, 30); |
214 | hws[IMX7ULP_CLK_PCTLC] = imx_clk_hw_gate("pctlc" , "nic1_bus_clk" , base + 0xb8, 30); |
215 | hws[IMX7ULP_CLK_PCTLD] = imx_clk_hw_gate("pctld" , "nic1_bus_clk" , base + 0xbc, 30); |
216 | hws[IMX7ULP_CLK_PCTLE] = imx_clk_hw_gate("pctle" , "nic1_bus_clk" , base + 0xc0, 30); |
217 | hws[IMX7ULP_CLK_PCTLF] = imx_clk_hw_gate("pctlf" , "nic1_bus_clk" , base + 0xc4, 30); |
218 | |
219 | hws[IMX7ULP_CLK_GPU3D] = imx7ulp_clk_hw_composite(name: "gpu3d" , parent_names: periph_plat_sels, ARRAY_SIZE(periph_plat_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x140); |
220 | hws[IMX7ULP_CLK_GPU2D] = imx7ulp_clk_hw_composite(name: "gpu2d" , parent_names: periph_plat_sels, ARRAY_SIZE(periph_plat_sels), mux_present: true, rate_present: false, gate_present: true, reg: base + 0x144); |
221 | |
222 | imx_check_clk_hws(clks: hws, count: clk_data->num); |
223 | |
224 | of_clk_add_hw_provider(np, get: of_clk_hw_onecell_get, data: clk_data); |
225 | |
226 | imx_register_uart_clocks(); |
227 | } |
228 | CLK_OF_DECLARE(imx7ulp_clk_pcc3, "fsl,imx7ulp-pcc3" , imx7ulp_clk_pcc3_init); |
229 | |
230 | static void __init imx7ulp_clk_smc1_init(struct device_node *np) |
231 | { |
232 | struct clk_hw_onecell_data *clk_data; |
233 | struct clk_hw **hws; |
234 | void __iomem *base; |
235 | |
236 | clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SMC1_END), |
237 | GFP_KERNEL); |
238 | if (!clk_data) |
239 | return; |
240 | |
241 | clk_data->num = IMX7ULP_CLK_SMC1_END; |
242 | hws = clk_data->hws; |
243 | |
244 | /* SMC1 */ |
245 | base = of_iomap(node: np, index: 0); |
246 | WARN_ON(!base); |
247 | |
248 | hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm" , base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_SET_RATE_PARENT); |
249 | |
250 | imx_check_clk_hws(clks: hws, count: clk_data->num); |
251 | |
252 | of_clk_add_hw_provider(np, get: of_clk_hw_onecell_get, data: clk_data); |
253 | } |
254 | CLK_OF_DECLARE(imx7ulp_clk_smc1, "fsl,imx7ulp-smc1" , imx7ulp_clk_smc1_init); |
255 | |