forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-02-20 e636c8d336489bf3eed5878299e6cc045bbad077
kernel/drivers/soc/imx/gpcv2.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * Copyright 2017 Impinj, Inc
34 * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
....@@ -5,39 +6,72 @@
56 * Based on the code of analogus driver:
67 *
78 * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
8
- *
9
- * The code contained herein is licensed under the GNU General Public
10
- * License. You may obtain a copy of the GNU General Public License
11
- * Version 2 or later at the following locations:
12
- *
13
- * http://www.opensource.org/licenses/gpl-license.html
14
- * http://www.gnu.org/copyleft/gpl.html
159 */
1610
11
+#include <linux/clk.h>
12
+#include <linux/of_device.h>
1713 #include <linux/platform_device.h>
1814 #include <linux/pm_domain.h>
1915 #include <linux/regmap.h>
2016 #include <linux/regulator/consumer.h>
17
+#include <linux/sizes.h>
2118 #include <dt-bindings/power/imx7-power.h>
19
+#include <dt-bindings/power/imx8mq-power.h>
2220
23
-#define GPC_LPCR_A7_BSC 0x000
21
+#define GPC_LPCR_A_CORE_BSC 0x000
2422
2523 #define GPC_PGC_CPU_MAPPING 0x0ec
26
-#define USB_HSIC_PHY_A7_DOMAIN BIT(6)
27
-#define USB_OTG2_PHY_A7_DOMAIN BIT(5)
28
-#define USB_OTG1_PHY_A7_DOMAIN BIT(4)
29
-#define PCIE_PHY_A7_DOMAIN BIT(3)
30
-#define MIPI_PHY_A7_DOMAIN BIT(2)
24
+
25
+#define IMX7_USB_HSIC_PHY_A_CORE_DOMAIN BIT(6)
26
+#define IMX7_USB_OTG2_PHY_A_CORE_DOMAIN BIT(5)
27
+#define IMX7_USB_OTG1_PHY_A_CORE_DOMAIN BIT(4)
28
+#define IMX7_PCIE_PHY_A_CORE_DOMAIN BIT(3)
29
+#define IMX7_MIPI_PHY_A_CORE_DOMAIN BIT(2)
30
+
31
+#define IMX8M_PCIE2_A53_DOMAIN BIT(15)
32
+#define IMX8M_MIPI_CSI2_A53_DOMAIN BIT(14)
33
+#define IMX8M_MIPI_CSI1_A53_DOMAIN BIT(13)
34
+#define IMX8M_DISP_A53_DOMAIN BIT(12)
35
+#define IMX8M_HDMI_A53_DOMAIN BIT(11)
36
+#define IMX8M_VPU_A53_DOMAIN BIT(10)
37
+#define IMX8M_GPU_A53_DOMAIN BIT(9)
38
+#define IMX8M_DDR2_A53_DOMAIN BIT(8)
39
+#define IMX8M_DDR1_A53_DOMAIN BIT(7)
40
+#define IMX8M_OTG2_A53_DOMAIN BIT(5)
41
+#define IMX8M_OTG1_A53_DOMAIN BIT(4)
42
+#define IMX8M_PCIE1_A53_DOMAIN BIT(3)
43
+#define IMX8M_MIPI_A53_DOMAIN BIT(2)
3144
3245 #define GPC_PU_PGC_SW_PUP_REQ 0x0f8
3346 #define GPC_PU_PGC_SW_PDN_REQ 0x104
34
-#define USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
35
-#define USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
36
-#define USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
37
-#define PCIE_PHY_SW_Pxx_REQ BIT(1)
38
-#define MIPI_PHY_SW_Pxx_REQ BIT(0)
47
+
48
+#define IMX7_USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
49
+#define IMX7_USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
50
+#define IMX7_USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
51
+#define IMX7_PCIE_PHY_SW_Pxx_REQ BIT(1)
52
+#define IMX7_MIPI_PHY_SW_Pxx_REQ BIT(0)
53
+
54
+#define IMX8M_PCIE2_SW_Pxx_REQ BIT(13)
55
+#define IMX8M_MIPI_CSI2_SW_Pxx_REQ BIT(12)
56
+#define IMX8M_MIPI_CSI1_SW_Pxx_REQ BIT(11)
57
+#define IMX8M_DISP_SW_Pxx_REQ BIT(10)
58
+#define IMX8M_HDMI_SW_Pxx_REQ BIT(9)
59
+#define IMX8M_VPU_SW_Pxx_REQ BIT(8)
60
+#define IMX8M_GPU_SW_Pxx_REQ BIT(7)
61
+#define IMX8M_DDR2_SW_Pxx_REQ BIT(6)
62
+#define IMX8M_DDR1_SW_Pxx_REQ BIT(5)
63
+#define IMX8M_OTG2_SW_Pxx_REQ BIT(3)
64
+#define IMX8M_OTG1_SW_Pxx_REQ BIT(2)
65
+#define IMX8M_PCIE1_SW_Pxx_REQ BIT(1)
66
+#define IMX8M_MIPI_SW_Pxx_REQ BIT(0)
3967
4068 #define GPC_M4_PU_PDN_FLG 0x1bc
69
+
70
+#define GPC_PU_PWRHSK 0x1fc
71
+
72
+#define IMX8M_GPU_HSK_PWRDNREQN BIT(6)
73
+#define IMX8M_VPU_HSK_PWRDNREQN BIT(5)
74
+#define IMX8M_DISP_HSK_PWRDNREQN BIT(4)
4175
4276 /*
4377 * The PGC offset values in Reference Manual
....@@ -45,42 +79,66 @@
4579 * GPC_PGC memory map are incorrect, below offset
4680 * values are from design RTL.
4781 */
48
-#define PGC_MIPI 16
49
-#define PGC_PCIE 17
50
-#define PGC_USB_HSIC 20
82
+#define IMX7_PGC_MIPI 16
83
+#define IMX7_PGC_PCIE 17
84
+#define IMX7_PGC_USB_HSIC 20
85
+
86
+#define IMX8M_PGC_MIPI 16
87
+#define IMX8M_PGC_PCIE1 17
88
+#define IMX8M_PGC_OTG1 18
89
+#define IMX8M_PGC_OTG2 19
90
+#define IMX8M_PGC_DDR1 21
91
+#define IMX8M_PGC_GPU 23
92
+#define IMX8M_PGC_VPU 24
93
+#define IMX8M_PGC_DISP 26
94
+#define IMX8M_PGC_MIPI_CSI1 27
95
+#define IMX8M_PGC_MIPI_CSI2 28
96
+#define IMX8M_PGC_PCIE2 29
97
+
5198 #define GPC_PGC_CTRL(n) (0x800 + (n) * 0x40)
5299 #define GPC_PGC_SR(n) (GPC_PGC_CTRL(n) + 0xc)
53100
54101 #define GPC_PGC_CTRL_PCR BIT(0)
55102
56
-struct imx7_pgc_domain {
103
+#define GPC_CLK_MAX 6
104
+
105
+struct imx_pgc_domain {
57106 struct generic_pm_domain genpd;
58107 struct regmap *regmap;
59108 struct regulator *regulator;
109
+ struct clk *clk[GPC_CLK_MAX];
110
+ int num_clks;
60111
61112 unsigned int pgc;
62113
63114 const struct {
64115 u32 pxx;
65116 u32 map;
117
+ u32 hsk;
66118 } bits;
67119
68120 const int voltage;
69121 struct device *dev;
70122 };
71123
72
-static int imx7_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
124
+struct imx_pgc_domain_data {
125
+ const struct imx_pgc_domain *domains;
126
+ size_t domains_num;
127
+ const struct regmap_access_table *reg_access_table;
128
+};
129
+
130
+static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
73131 bool on)
74132 {
75
- struct imx7_pgc_domain *domain = container_of(genpd,
76
- struct imx7_pgc_domain,
133
+ struct imx_pgc_domain *domain = container_of(genpd,
134
+ struct imx_pgc_domain,
77135 genpd);
78136 unsigned int offset = on ?
79137 GPC_PU_PGC_SW_PUP_REQ : GPC_PU_PGC_SW_PDN_REQ;
80138 const bool enable_power_control = !on;
81139 const bool has_regulator = !IS_ERR(domain->regulator);
82
- unsigned long deadline;
83
- int ret = 0;
140
+ int i, ret = 0;
141
+ u32 pxx_req;
84142
85143 regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
86144 domain->bits.map, domain->bits.map);
....@@ -93,9 +151,17 @@
93151 }
94152 }
95153
154
+ /* Enable reset clocks for all devices in the domain */
155
+ for (i = 0; i < domain->num_clks; i++)
156
+ clk_prepare_enable(domain->clk[i]);
157
+
96158 if (enable_power_control)
97159 regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
98160 GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
161
+
162
+ if (domain->bits.hsk)
163
+ regmap_update_bits(domain->regmap, GPC_PU_PWRHSK,
164
+ domain->bits.hsk, on ? domain->bits.hsk : 0);
99165
100166 regmap_update_bits(domain->regmap, offset,
101167 domain->bits.pxx, domain->bits.pxx);
....@@ -104,35 +170,28 @@
104170 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
105171 * for PUP_REQ/PDN_REQ bit to be cleared
106172 */
107
- deadline = jiffies + msecs_to_jiffies(1);
108
- while (true) {
109
- u32 pxx_req;
110
-
111
- regmap_read(domain->regmap, offset, &pxx_req);
112
-
113
- if (!(pxx_req & domain->bits.pxx))
114
- break;
115
-
116
- if (time_after(jiffies, deadline)) {
117
- dev_err(domain->dev, "falied to command PGC\n");
118
- ret = -ETIMEDOUT;
119
- /*
120
- * If we were in a process of enabling a
121
- * domain and failed we might as well disable
122
- * the regulator we just enabled. And if it
123
- * was the opposite situation and we failed to
124
- * power down -- keep the regulator on
125
- */
126
- on = !on;
127
- break;
128
- }
129
-
130
- cpu_relax();
173
+ ret = regmap_read_poll_timeout(domain->regmap, offset, pxx_req,
174
+ !(pxx_req & domain->bits.pxx),
175
+ 0, USEC_PER_MSEC);
176
+ if (ret) {
177
+ dev_err(domain->dev, "failed to command PGC\n");
178
+ /*
179
+ * If we were in a process of enabling a
180
+ * domain and failed we might as well disable
181
+ * the regulator we just enabled. And if it
182
+ * was the opposite situation and we failed to
183
+ * power down -- keep the regulator on
184
+ */
185
+ on = !on;
131186 }
132187
133188 if (enable_power_control)
134189 regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
135190 GPC_PGC_CTRL_PCR, 0);
191
+
192
+ /* Disable reset clocks for all devices in the domain */
193
+ for (i = 0; i < domain->num_clks; i++)
194
+ clk_disable_unprepare(domain->clk[i]);
136195
137196 if (has_regulator && !on) {
138197 int err;
....@@ -140,7 +199,7 @@
140199 err = regulator_disable(domain->regulator);
141200 if (err)
142201 dev_err(domain->dev,
143
- "failed to disable regulator: %d\n", ret);
202
+ "failed to disable regulator: %d\n", err);
144203 /* Preserve earlier error code */
145204 ret = ret ?: err;
146205 }
....@@ -150,27 +209,27 @@
150209 return ret;
151210 }
152211
153
-static int imx7_gpc_pu_pgc_sw_pup_req(struct generic_pm_domain *genpd)
212
+static int imx_gpc_pu_pgc_sw_pup_req(struct generic_pm_domain *genpd)
154213 {
155
- return imx7_gpc_pu_pgc_sw_pxx_req(genpd, true);
214
+ return imx_gpc_pu_pgc_sw_pxx_req(genpd, true);
156215 }
157216
158
-static int imx7_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd)
217
+static int imx_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd)
159218 {
160
- return imx7_gpc_pu_pgc_sw_pxx_req(genpd, false);
219
+ return imx_gpc_pu_pgc_sw_pxx_req(genpd, false);
161220 }
162221
163
-static const struct imx7_pgc_domain imx7_pgc_domains[] = {
222
+static const struct imx_pgc_domain imx7_pgc_domains[] = {
164223 [IMX7_POWER_DOMAIN_MIPI_PHY] = {
165224 .genpd = {
166225 .name = "mipi-phy",
167226 },
168227 .bits = {
169
- .pxx = MIPI_PHY_SW_Pxx_REQ,
170
- .map = MIPI_PHY_A7_DOMAIN,
228
+ .pxx = IMX7_MIPI_PHY_SW_Pxx_REQ,
229
+ .map = IMX7_MIPI_PHY_A_CORE_DOMAIN,
171230 },
172231 .voltage = 1000000,
173
- .pgc = PGC_MIPI,
232
+ .pgc = IMX7_PGC_MIPI,
174233 },
175234
176235 [IMX7_POWER_DOMAIN_PCIE_PHY] = {
....@@ -178,11 +237,11 @@
178237 .name = "pcie-phy",
179238 },
180239 .bits = {
181
- .pxx = PCIE_PHY_SW_Pxx_REQ,
182
- .map = PCIE_PHY_A7_DOMAIN,
240
+ .pxx = IMX7_PCIE_PHY_SW_Pxx_REQ,
241
+ .map = IMX7_PCIE_PHY_A_CORE_DOMAIN,
183242 },
184243 .voltage = 1000000,
185
- .pgc = PGC_PCIE,
244
+ .pgc = IMX7_PGC_PCIE,
186245 },
187246
188247 [IMX7_POWER_DOMAIN_USB_HSIC_PHY] = {
....@@ -190,36 +249,260 @@
190249 .name = "usb-hsic-phy",
191250 },
192251 .bits = {
193
- .pxx = USB_HSIC_PHY_SW_Pxx_REQ,
194
- .map = USB_HSIC_PHY_A7_DOMAIN,
252
+ .pxx = IMX7_USB_HSIC_PHY_SW_Pxx_REQ,
253
+ .map = IMX7_USB_HSIC_PHY_A_CORE_DOMAIN,
195254 },
196255 .voltage = 1200000,
197
- .pgc = PGC_USB_HSIC,
256
+ .pgc = IMX7_PGC_USB_HSIC,
198257 },
199258 };
200259
201
-static int imx7_pgc_domain_probe(struct platform_device *pdev)
260
+static const struct regmap_range imx7_yes_ranges[] = {
261
+ regmap_reg_range(GPC_LPCR_A_CORE_BSC,
262
+ GPC_M4_PU_PDN_FLG),
263
+ regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_MIPI),
264
+ GPC_PGC_SR(IMX7_PGC_MIPI)),
265
+ regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_PCIE),
266
+ GPC_PGC_SR(IMX7_PGC_PCIE)),
267
+ regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_USB_HSIC),
268
+ GPC_PGC_SR(IMX7_PGC_USB_HSIC)),
269
+};
270
+
271
+static const struct regmap_access_table imx7_access_table = {
272
+ .yes_ranges = imx7_yes_ranges,
273
+ .n_yes_ranges = ARRAY_SIZE(imx7_yes_ranges),
274
+};
275
+
276
+static const struct imx_pgc_domain_data imx7_pgc_domain_data = {
277
+ .domains = imx7_pgc_domains,
278
+ .domains_num = ARRAY_SIZE(imx7_pgc_domains),
279
+ .reg_access_table = &imx7_access_table,
280
+};
281
+
282
+static const struct imx_pgc_domain imx8m_pgc_domains[] = {
283
+ [IMX8M_POWER_DOMAIN_MIPI] = {
284
+ .genpd = {
285
+ .name = "mipi",
286
+ },
287
+ .bits = {
288
+ .pxx = IMX8M_MIPI_SW_Pxx_REQ,
289
+ .map = IMX8M_MIPI_A53_DOMAIN,
290
+ },
291
+ .pgc = IMX8M_PGC_MIPI,
292
+ },
293
+
294
+ [IMX8M_POWER_DOMAIN_PCIE1] = {
295
+ .genpd = {
296
+ .name = "pcie1",
297
+ },
298
+ .bits = {
299
+ .pxx = IMX8M_PCIE1_SW_Pxx_REQ,
300
+ .map = IMX8M_PCIE1_A53_DOMAIN,
301
+ },
302
+ .pgc = IMX8M_PGC_PCIE1,
303
+ },
304
+
305
+ [IMX8M_POWER_DOMAIN_USB_OTG1] = {
306
+ .genpd = {
307
+ .name = "usb-otg1",
308
+ },
309
+ .bits = {
310
+ .pxx = IMX8M_OTG1_SW_Pxx_REQ,
311
+ .map = IMX8M_OTG1_A53_DOMAIN,
312
+ },
313
+ .pgc = IMX8M_PGC_OTG1,
314
+ },
315
+
316
+ [IMX8M_POWER_DOMAIN_USB_OTG2] = {
317
+ .genpd = {
318
+ .name = "usb-otg2",
319
+ },
320
+ .bits = {
321
+ .pxx = IMX8M_OTG2_SW_Pxx_REQ,
322
+ .map = IMX8M_OTG2_A53_DOMAIN,
323
+ },
324
+ .pgc = IMX8M_PGC_OTG2,
325
+ },
326
+
327
+ [IMX8M_POWER_DOMAIN_DDR1] = {
328
+ .genpd = {
329
+ .name = "ddr1",
330
+ },
331
+ .bits = {
332
+ .pxx = IMX8M_DDR1_SW_Pxx_REQ,
333
+ .map = IMX8M_DDR2_A53_DOMAIN,
334
+ },
335
+ .pgc = IMX8M_PGC_DDR1,
336
+ },
337
+
338
+ [IMX8M_POWER_DOMAIN_GPU] = {
339
+ .genpd = {
340
+ .name = "gpu",
341
+ },
342
+ .bits = {
343
+ .pxx = IMX8M_GPU_SW_Pxx_REQ,
344
+ .map = IMX8M_GPU_A53_DOMAIN,
345
+ .hsk = IMX8M_GPU_HSK_PWRDNREQN,
346
+ },
347
+ .pgc = IMX8M_PGC_GPU,
348
+ },
349
+
350
+ [IMX8M_POWER_DOMAIN_VPU] = {
351
+ .genpd = {
352
+ .name = "vpu",
353
+ },
354
+ .bits = {
355
+ .pxx = IMX8M_VPU_SW_Pxx_REQ,
356
+ .map = IMX8M_VPU_A53_DOMAIN,
357
+ .hsk = IMX8M_VPU_HSK_PWRDNREQN,
358
+ },
359
+ .pgc = IMX8M_PGC_VPU,
360
+ },
361
+
362
+ [IMX8M_POWER_DOMAIN_DISP] = {
363
+ .genpd = {
364
+ .name = "disp",
365
+ },
366
+ .bits = {
367
+ .pxx = IMX8M_DISP_SW_Pxx_REQ,
368
+ .map = IMX8M_DISP_A53_DOMAIN,
369
+ .hsk = IMX8M_DISP_HSK_PWRDNREQN,
370
+ },
371
+ .pgc = IMX8M_PGC_DISP,
372
+ },
373
+
374
+ [IMX8M_POWER_DOMAIN_MIPI_CSI1] = {
375
+ .genpd = {
376
+ .name = "mipi-csi1",
377
+ },
378
+ .bits = {
379
+ .pxx = IMX8M_MIPI_CSI1_SW_Pxx_REQ,
380
+ .map = IMX8M_MIPI_CSI1_A53_DOMAIN,
381
+ },
382
+ .pgc = IMX8M_PGC_MIPI_CSI1,
383
+ },
384
+
385
+ [IMX8M_POWER_DOMAIN_MIPI_CSI2] = {
386
+ .genpd = {
387
+ .name = "mipi-csi2",
388
+ },
389
+ .bits = {
390
+ .pxx = IMX8M_MIPI_CSI2_SW_Pxx_REQ,
391
+ .map = IMX8M_MIPI_CSI2_A53_DOMAIN,
392
+ },
393
+ .pgc = IMX8M_PGC_MIPI_CSI2,
394
+ },
395
+
396
+ [IMX8M_POWER_DOMAIN_PCIE2] = {
397
+ .genpd = {
398
+ .name = "pcie2",
399
+ },
400
+ .bits = {
401
+ .pxx = IMX8M_PCIE2_SW_Pxx_REQ,
402
+ .map = IMX8M_PCIE2_A53_DOMAIN,
403
+ },
404
+ .pgc = IMX8M_PGC_PCIE2,
405
+ },
406
+};
407
+
408
+static const struct regmap_range imx8m_yes_ranges[] = {
409
+ regmap_reg_range(GPC_LPCR_A_CORE_BSC,
410
+ GPC_PU_PWRHSK),
411
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI),
412
+ GPC_PGC_SR(IMX8M_PGC_MIPI)),
413
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE1),
414
+ GPC_PGC_SR(IMX8M_PGC_PCIE1)),
415
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG1),
416
+ GPC_PGC_SR(IMX8M_PGC_OTG1)),
417
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG2),
418
+ GPC_PGC_SR(IMX8M_PGC_OTG2)),
419
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DDR1),
420
+ GPC_PGC_SR(IMX8M_PGC_DDR1)),
421
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_GPU),
422
+ GPC_PGC_SR(IMX8M_PGC_GPU)),
423
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_VPU),
424
+ GPC_PGC_SR(IMX8M_PGC_VPU)),
425
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DISP),
426
+ GPC_PGC_SR(IMX8M_PGC_DISP)),
427
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI1),
428
+ GPC_PGC_SR(IMX8M_PGC_MIPI_CSI1)),
429
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI2),
430
+ GPC_PGC_SR(IMX8M_PGC_MIPI_CSI2)),
431
+ regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE2),
432
+ GPC_PGC_SR(IMX8M_PGC_PCIE2)),
433
+};
434
+
435
+static const struct regmap_access_table imx8m_access_table = {
436
+ .yes_ranges = imx8m_yes_ranges,
437
+ .n_yes_ranges = ARRAY_SIZE(imx8m_yes_ranges),
438
+};
439
+
440
+static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
441
+ .domains = imx8m_pgc_domains,
442
+ .domains_num = ARRAY_SIZE(imx8m_pgc_domains),
443
+ .reg_access_table = &imx8m_access_table,
444
+};
445
+
446
+static int imx_pgc_get_clocks(struct imx_pgc_domain *domain)
202447 {
203
- struct imx7_pgc_domain *domain = pdev->dev.platform_data;
448
+ int i, ret;
449
+
450
+ for (i = 0; ; i++) {
451
+ struct clk *clk = of_clk_get(domain->dev->of_node, i);
452
+ if (IS_ERR(clk))
453
+ break;
454
+ if (i >= GPC_CLK_MAX) {
455
+ dev_err(domain->dev, "more than %d clocks\n",
456
+ GPC_CLK_MAX);
457
+ ret = -EINVAL;
458
+ goto clk_err;
459
+ }
460
+ domain->clk[i] = clk;
461
+ }
462
+ domain->num_clks = i;
463
+
464
+ return 0;
465
+
466
+clk_err:
467
+ while (i--)
468
+ clk_put(domain->clk[i]);
469
+
470
+ return ret;
471
+}
472
+
473
+static void imx_pgc_put_clocks(struct imx_pgc_domain *domain)
474
+{
475
+ int i;
476
+
477
+ for (i = domain->num_clks - 1; i >= 0; i--)
478
+ clk_put(domain->clk[i]);
479
+}
480
+
481
+static int imx_pgc_domain_probe(struct platform_device *pdev)
482
+{
483
+ struct imx_pgc_domain *domain = pdev->dev.platform_data;
204484 int ret;
205485
206486 domain->dev = &pdev->dev;
207487
208488 domain->regulator = devm_regulator_get_optional(domain->dev, "power");
209489 if (IS_ERR(domain->regulator)) {
210
- if (PTR_ERR(domain->regulator) != -ENODEV) {
211
- if (PTR_ERR(domain->regulator) != -EPROBE_DEFER)
212
- dev_err(domain->dev, "Failed to get domain's regulator\n");
213
- return PTR_ERR(domain->regulator);
214
- }
215
- } else {
490
+ if (PTR_ERR(domain->regulator) != -ENODEV)
491
+ return dev_err_probe(domain->dev, PTR_ERR(domain->regulator),
492
+ "Failed to get domain's regulator\n");
493
+ } else if (domain->voltage) {
216494 regulator_set_voltage(domain->regulator,
217495 domain->voltage, domain->voltage);
218496 }
219497
498
+ ret = imx_pgc_get_clocks(domain);
499
+ if (ret)
500
+ return dev_err_probe(domain->dev, ret, "Failed to get domain's clocks\n");
501
+
220502 ret = pm_genpd_init(&domain->genpd, NULL, true);
221503 if (ret) {
222504 dev_err(domain->dev, "Failed to init power domain\n");
505
+ imx_pgc_put_clocks(domain);
223506 return ret;
224507 }
225508
....@@ -228,64 +511,54 @@
228511 if (ret) {
229512 dev_err(domain->dev, "Failed to add genpd provider\n");
230513 pm_genpd_remove(&domain->genpd);
514
+ imx_pgc_put_clocks(domain);
231515 }
232516
233517 return ret;
234518 }
235519
236
-static int imx7_pgc_domain_remove(struct platform_device *pdev)
520
+static int imx_pgc_domain_remove(struct platform_device *pdev)
237521 {
238
- struct imx7_pgc_domain *domain = pdev->dev.platform_data;
522
+ struct imx_pgc_domain *domain = pdev->dev.platform_data;
239523
240524 of_genpd_del_provider(domain->dev->of_node);
241525 pm_genpd_remove(&domain->genpd);
526
+ imx_pgc_put_clocks(domain);
242527
243528 return 0;
244529 }
245530
246
-static const struct platform_device_id imx7_pgc_domain_id[] = {
247
- { "imx7-pgc-domain", },
531
+static const struct platform_device_id imx_pgc_domain_id[] = {
532
+ { "imx-pgc-domain", },
248533 { },
249534 };
250535
251
-static struct platform_driver imx7_pgc_domain_driver = {
536
+static struct platform_driver imx_pgc_domain_driver = {
252537 .driver = {
253
- .name = "imx7-pgc",
538
+ .name = "imx-pgc",
254539 },
255
- .probe = imx7_pgc_domain_probe,
256
- .remove = imx7_pgc_domain_remove,
257
- .id_table = imx7_pgc_domain_id,
540
+ .probe = imx_pgc_domain_probe,
541
+ .remove = imx_pgc_domain_remove,
542
+ .id_table = imx_pgc_domain_id,
258543 };
259
-builtin_platform_driver(imx7_pgc_domain_driver)
544
+builtin_platform_driver(imx_pgc_domain_driver)
260545
261546 static int imx_gpcv2_probe(struct platform_device *pdev)
262547 {
263
- static const struct regmap_range yes_ranges[] = {
264
- regmap_reg_range(GPC_LPCR_A7_BSC,
265
- GPC_M4_PU_PDN_FLG),
266
- regmap_reg_range(GPC_PGC_CTRL(PGC_MIPI),
267
- GPC_PGC_SR(PGC_MIPI)),
268
- regmap_reg_range(GPC_PGC_CTRL(PGC_PCIE),
269
- GPC_PGC_SR(PGC_PCIE)),
270
- regmap_reg_range(GPC_PGC_CTRL(PGC_USB_HSIC),
271
- GPC_PGC_SR(PGC_USB_HSIC)),
272
- };
273
- static const struct regmap_access_table access_table = {
274
- .yes_ranges = yes_ranges,
275
- .n_yes_ranges = ARRAY_SIZE(yes_ranges),
276
- };
277
- static const struct regmap_config regmap_config = {
548
+ const struct imx_pgc_domain_data *domain_data =
549
+ of_device_get_match_data(&pdev->dev);
550
+
551
+ struct regmap_config regmap_config = {
278552 .reg_bits = 32,
279553 .val_bits = 32,
280554 .reg_stride = 4,
281
- .rd_table = &access_table,
282
- .wr_table = &access_table,
555
+ .rd_table = domain_data->reg_access_table,
556
+ .wr_table = domain_data->reg_access_table,
283557 .max_register = SZ_4K,
284558 };
285559 struct device *dev = &pdev->dev;
286560 struct device_node *pgc_np, *np;
287561 struct regmap *regmap;
288
- struct resource *res;
289562 void __iomem *base;
290563 int ret;
291564
....@@ -295,8 +568,7 @@
295568 return -EINVAL;
296569 }
297570
298
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
299
- base = devm_ioremap_resource(dev, res);
571
+ base = devm_platform_ioremap_resource(pdev, 0);
300572 if (IS_ERR(base))
301573 return PTR_ERR(base);
302574
....@@ -309,7 +581,7 @@
309581
310582 for_each_child_of_node(pgc_np, np) {
311583 struct platform_device *pd_pdev;
312
- struct imx7_pgc_domain *domain;
584
+ struct imx_pgc_domain *domain;
313585 u32 domain_index;
314586
315587 ret = of_property_read_u32(np, "reg", &domain_index);
....@@ -319,14 +591,14 @@
319591 return ret;
320592 }
321593
322
- if (domain_index >= ARRAY_SIZE(imx7_pgc_domains)) {
594
+ if (domain_index >= domain_data->domains_num) {
323595 dev_warn(dev,
324596 "Domain index %d is out of bounds\n",
325597 domain_index);
326598 continue;
327599 }
328600
329
- pd_pdev = platform_device_alloc("imx7-pgc-domain",
601
+ pd_pdev = platform_device_alloc("imx-pgc-domain",
330602 domain_index);
331603 if (!pd_pdev) {
332604 dev_err(dev, "Failed to allocate platform device\n");
....@@ -335,8 +607,8 @@
335607 }
336608
337609 ret = platform_device_add_data(pd_pdev,
338
- &imx7_pgc_domains[domain_index],
339
- sizeof(imx7_pgc_domains[domain_index]));
610
+ &domain_data->domains[domain_index],
611
+ sizeof(domain_data->domains[domain_index]));
340612 if (ret) {
341613 platform_device_put(pd_pdev);
342614 of_node_put(np);
....@@ -345,8 +617,8 @@
345617
346618 domain = pd_pdev->dev.platform_data;
347619 domain->regmap = regmap;
348
- domain->genpd.power_on = imx7_gpc_pu_pgc_sw_pup_req;
349
- domain->genpd.power_off = imx7_gpc_pu_pgc_sw_pdn_req;
620
+ domain->genpd.power_on = imx_gpc_pu_pgc_sw_pup_req;
621
+ domain->genpd.power_off = imx_gpc_pu_pgc_sw_pdn_req;
350622
351623 pd_pdev->dev.parent = dev;
352624 pd_pdev->dev.of_node = np;
....@@ -363,7 +635,8 @@
363635 }
364636
365637 static const struct of_device_id imx_gpcv2_dt_ids[] = {
366
- { .compatible = "fsl,imx7d-gpc" },
638
+ { .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
639
+ { .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, },
367640 { }
368641 };
369642