This source file includes following definitions.
- imx6_set_int_mem_clk_lpm
- imx6_enable_rbc
- imx6q_enable_wb
- imx6_set_lpm
- imx6q_suspend_finish
- imx6q_pm_enter
- imx6q_pm_valid
- imx6_pm_get_base
- imx6q_suspend_init
- imx6_pm_common_init
- imx6_pm_stby_poweroff
- imx6_pm_stby_poweroff_probe
- imx6_pm_ccm_init
- imx6q_pm_init
- imx6dl_pm_init
- imx6sl_pm_init
- imx6sx_pm_init
- imx6ul_pm_init
1
2
3
4
5
6
7 #include <linux/delay.h>
8 #include <linux/init.h>
9 #include <linux/io.h>
10 #include <linux/irq.h>
11 #include <linux/genalloc.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
14 #include <linux/of.h>
15 #include <linux/of_address.h>
16 #include <linux/of_platform.h>
17 #include <linux/regmap.h>
18 #include <linux/suspend.h>
19 #include <asm/cacheflush.h>
20 #include <asm/fncpy.h>
21 #include <asm/proc-fns.h>
22 #include <asm/suspend.h>
23 #include <asm/tlb.h>
24
25 #include "common.h"
26 #include "hardware.h"
27
28 #define CCR 0x0
29 #define BM_CCR_WB_COUNT (0x7 << 16)
30 #define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
31 #define BM_CCR_RBC_EN (0x1 << 27)
32
33 #define CLPCR 0x54
34 #define BP_CLPCR_LPM 0
35 #define BM_CLPCR_LPM (0x3 << 0)
36 #define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
37 #define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
38 #define BM_CLPCR_SBYOS (0x1 << 6)
39 #define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
40 #define BM_CLPCR_VSTBY (0x1 << 8)
41 #define BP_CLPCR_STBY_COUNT 9
42 #define BM_CLPCR_STBY_COUNT (0x3 << 9)
43 #define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
44 #define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
45 #define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
46 #define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
47 #define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
48 #define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
49 #define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
50 #define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
51 #define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
52 #define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
53 #define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
54
55 #define CGPR 0x64
56 #define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17)
57
58 #define MX6Q_SUSPEND_OCRAM_SIZE 0x1000
59 #define MX6_MAX_MMDC_IO_NUM 33
60
61 static void __iomem *ccm_base;
62 static void __iomem *suspend_ocram_base;
63 static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 struct imx6_pm_base {
80 phys_addr_t pbase;
81 void __iomem *vbase;
82 };
83
84 struct imx6_pm_socdata {
85 u32 ddr_type;
86 const char *mmdc_compat;
87 const char *src_compat;
88 const char *iomuxc_compat;
89 const char *gpc_compat;
90 const char *pl310_compat;
91 const u32 mmdc_io_num;
92 const u32 *mmdc_io_offset;
93 };
94
95 static const u32 imx6q_mmdc_io_offset[] __initconst = {
96 0x5ac, 0x5b4, 0x528, 0x520,
97 0x514, 0x510, 0x5bc, 0x5c4,
98 0x56c, 0x578, 0x588, 0x594,
99 0x5a8, 0x5b0, 0x524, 0x51c,
100 0x518, 0x50c, 0x5b8, 0x5c0,
101 0x784, 0x788, 0x794, 0x79c,
102 0x7a0, 0x7a4, 0x7a8, 0x748,
103 0x59c, 0x5a0, 0x750, 0x774,
104 0x74c,
105 };
106
107 static const u32 imx6dl_mmdc_io_offset[] __initconst = {
108 0x470, 0x474, 0x478, 0x47c,
109 0x480, 0x484, 0x488, 0x48c,
110 0x464, 0x490, 0x4ac, 0x4b0,
111 0x4bc, 0x4c0, 0x4c4, 0x4c8,
112 0x4cc, 0x4d0, 0x4d4, 0x4d8,
113 0x764, 0x770, 0x778, 0x77c,
114 0x780, 0x784, 0x78c, 0x748,
115 0x4b4, 0x4b8, 0x750, 0x760,
116 0x74c,
117 };
118
119 static const u32 imx6sl_mmdc_io_offset[] __initconst = {
120 0x30c, 0x310, 0x314, 0x318,
121 0x5c4, 0x5cc, 0x5d4, 0x5d8,
122 0x300, 0x31c, 0x338, 0x5ac,
123 0x33c, 0x340, 0x5b0, 0x5c0,
124 0x330, 0x334, 0x320,
125 };
126
127 static const u32 imx6sll_mmdc_io_offset[] __initconst = {
128 0x294, 0x298, 0x29c, 0x2a0,
129 0x544, 0x54c, 0x554, 0x558,
130 0x530, 0x540, 0x2ac, 0x52c,
131 0x2a4, 0x2a8,
132 };
133
134 static const u32 imx6sx_mmdc_io_offset[] __initconst = {
135 0x2ec, 0x2f0, 0x2f4, 0x2f8,
136 0x60c, 0x610, 0x61c, 0x620,
137 0x300, 0x2fc, 0x32c, 0x5f4,
138 0x310, 0x314, 0x5f8, 0x608,
139 0x330, 0x334, 0x338, 0x33c,
140 };
141
142 static const u32 imx6ul_mmdc_io_offset[] __initconst = {
143 0x244, 0x248, 0x24c, 0x250,
144 0x27c, 0x498, 0x4a4, 0x490,
145 0x280, 0x284, 0x260, 0x264,
146 0x494, 0x4b0,
147 };
148
149 static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
150 .mmdc_compat = "fsl,imx6q-mmdc",
151 .src_compat = "fsl,imx6q-src",
152 .iomuxc_compat = "fsl,imx6q-iomuxc",
153 .gpc_compat = "fsl,imx6q-gpc",
154 .pl310_compat = "arm,pl310-cache",
155 .mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
156 .mmdc_io_offset = imx6q_mmdc_io_offset,
157 };
158
159 static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
160 .mmdc_compat = "fsl,imx6q-mmdc",
161 .src_compat = "fsl,imx6q-src",
162 .iomuxc_compat = "fsl,imx6dl-iomuxc",
163 .gpc_compat = "fsl,imx6q-gpc",
164 .pl310_compat = "arm,pl310-cache",
165 .mmdc_io_num = ARRAY_SIZE(imx6dl_mmdc_io_offset),
166 .mmdc_io_offset = imx6dl_mmdc_io_offset,
167 };
168
169 static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
170 .mmdc_compat = "fsl,imx6sl-mmdc",
171 .src_compat = "fsl,imx6sl-src",
172 .iomuxc_compat = "fsl,imx6sl-iomuxc",
173 .gpc_compat = "fsl,imx6sl-gpc",
174 .pl310_compat = "arm,pl310-cache",
175 .mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset),
176 .mmdc_io_offset = imx6sl_mmdc_io_offset,
177 };
178
179 static const struct imx6_pm_socdata imx6sll_pm_data __initconst = {
180 .mmdc_compat = "fsl,imx6sll-mmdc",
181 .src_compat = "fsl,imx6sll-src",
182 .iomuxc_compat = "fsl,imx6sll-iomuxc",
183 .gpc_compat = "fsl,imx6sll-gpc",
184 .pl310_compat = "arm,pl310-cache",
185 .mmdc_io_num = ARRAY_SIZE(imx6sll_mmdc_io_offset),
186 .mmdc_io_offset = imx6sll_mmdc_io_offset,
187 };
188
189 static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
190 .mmdc_compat = "fsl,imx6sx-mmdc",
191 .src_compat = "fsl,imx6sx-src",
192 .iomuxc_compat = "fsl,imx6sx-iomuxc",
193 .gpc_compat = "fsl,imx6sx-gpc",
194 .pl310_compat = "arm,pl310-cache",
195 .mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_offset),
196 .mmdc_io_offset = imx6sx_mmdc_io_offset,
197 };
198
199 static const struct imx6_pm_socdata imx6ul_pm_data __initconst = {
200 .mmdc_compat = "fsl,imx6ul-mmdc",
201 .src_compat = "fsl,imx6ul-src",
202 .iomuxc_compat = "fsl,imx6ul-iomuxc",
203 .gpc_compat = "fsl,imx6ul-gpc",
204 .pl310_compat = NULL,
205 .mmdc_io_num = ARRAY_SIZE(imx6ul_mmdc_io_offset),
206 .mmdc_io_offset = imx6ul_mmdc_io_offset,
207 };
208
209
210
211
212
213
214
215
216 struct imx6_cpu_pm_info {
217 phys_addr_t pbase;
218 phys_addr_t resume_addr;
219 u32 ddr_type;
220 u32 pm_info_size;
221 struct imx6_pm_base mmdc_base;
222 struct imx6_pm_base src_base;
223 struct imx6_pm_base iomuxc_base;
224 struct imx6_pm_base ccm_base;
225 struct imx6_pm_base gpc_base;
226 struct imx6_pm_base l2_base;
227 u32 mmdc_io_num;
228 u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2];
229 } __aligned(8);
230
231 void imx6_set_int_mem_clk_lpm(bool enable)
232 {
233 u32 val = readl_relaxed(ccm_base + CGPR);
234
235 val &= ~BM_CGPR_INT_MEM_CLK_LPM;
236 if (enable)
237 val |= BM_CGPR_INT_MEM_CLK_LPM;
238 writel_relaxed(val, ccm_base + CGPR);
239 }
240
241 void imx6_enable_rbc(bool enable)
242 {
243 u32 val;
244
245
246
247
248
249 imx_gpc_mask_all();
250
251
252 val = readl_relaxed(ccm_base + CCR);
253 val &= ~BM_CCR_RBC_EN;
254 val |= enable ? BM_CCR_RBC_EN : 0;
255 writel_relaxed(val, ccm_base + CCR);
256
257
258 val = readl_relaxed(ccm_base + CCR);
259 val &= ~BM_CCR_RBC_BYPASS_COUNT;
260 val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
261 writel(val, ccm_base + CCR);
262
263
264
265
266
267
268 udelay(65);
269
270
271 imx_gpc_restore_all();
272 }
273
274 static void imx6q_enable_wb(bool enable)
275 {
276 u32 val;
277
278
279 val = readl_relaxed(ccm_base + CLPCR);
280 val &= ~BM_CLPCR_WB_PER_AT_LPM;
281 val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
282 writel_relaxed(val, ccm_base + CLPCR);
283
284
285 val = readl_relaxed(ccm_base + CCR);
286 val &= ~BM_CCR_WB_COUNT;
287 val |= enable ? BM_CCR_WB_COUNT : 0;
288 writel_relaxed(val, ccm_base + CCR);
289 }
290
291 int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
292 {
293 u32 val = readl_relaxed(ccm_base + CLPCR);
294
295 val &= ~BM_CLPCR_LPM;
296 switch (mode) {
297 case WAIT_CLOCKED:
298 break;
299 case WAIT_UNCLOCKED:
300 val |= 0x1 << BP_CLPCR_LPM;
301 val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
302 break;
303 case STOP_POWER_ON:
304 val |= 0x2 << BP_CLPCR_LPM;
305 val &= ~BM_CLPCR_VSTBY;
306 val &= ~BM_CLPCR_SBYOS;
307 if (cpu_is_imx6sl())
308 val |= BM_CLPCR_BYPASS_PMIC_READY;
309 if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
310 cpu_is_imx6ull() || cpu_is_imx6sll() || cpu_is_imx6ulz())
311 val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
312 else
313 val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
314 break;
315 case WAIT_UNCLOCKED_POWER_OFF:
316 val |= 0x1 << BP_CLPCR_LPM;
317 val &= ~BM_CLPCR_VSTBY;
318 val &= ~BM_CLPCR_SBYOS;
319 break;
320 case STOP_POWER_OFF:
321 val |= 0x2 << BP_CLPCR_LPM;
322 val |= 0x3 << BP_CLPCR_STBY_COUNT;
323 val |= BM_CLPCR_VSTBY;
324 val |= BM_CLPCR_SBYOS;
325 if (cpu_is_imx6sl() || cpu_is_imx6sx())
326 val |= BM_CLPCR_BYPASS_PMIC_READY;
327 if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
328 cpu_is_imx6ull() || cpu_is_imx6sll() || cpu_is_imx6ulz())
329 val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
330 else
331 val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
332 break;
333 default:
334 return -EINVAL;
335 }
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351 if (mode != WAIT_CLOCKED)
352 imx_gpc_hwirq_unmask(0);
353 writel_relaxed(val, ccm_base + CLPCR);
354 if (mode != WAIT_CLOCKED)
355 imx_gpc_hwirq_mask(0);
356
357 return 0;
358 }
359
360 static int imx6q_suspend_finish(unsigned long val)
361 {
362 if (!imx6_suspend_in_ocram_fn) {
363 cpu_do_idle();
364 } else {
365
366
367
368
369 local_flush_tlb_all();
370
371 if (!((struct imx6_cpu_pm_info *)
372 suspend_ocram_base)->l2_base.vbase)
373 flush_cache_all();
374 imx6_suspend_in_ocram_fn(suspend_ocram_base);
375 }
376
377 return 0;
378 }
379
380 static int imx6q_pm_enter(suspend_state_t state)
381 {
382 switch (state) {
383 case PM_SUSPEND_STANDBY:
384 imx6_set_lpm(STOP_POWER_ON);
385 imx6_set_int_mem_clk_lpm(true);
386 imx_gpc_pre_suspend(false);
387 if (cpu_is_imx6sl())
388 imx6sl_set_wait_clk(true);
389
390 cpu_do_idle();
391 if (cpu_is_imx6sl())
392 imx6sl_set_wait_clk(false);
393 imx_gpc_post_resume();
394 imx6_set_lpm(WAIT_CLOCKED);
395 break;
396 case PM_SUSPEND_MEM:
397 imx6_set_lpm(STOP_POWER_OFF);
398 imx6_set_int_mem_clk_lpm(false);
399 imx6q_enable_wb(true);
400
401
402
403
404 if (!imx6_suspend_in_ocram_fn)
405 imx6_enable_rbc(true);
406 imx_gpc_pre_suspend(true);
407 imx_anatop_pre_suspend();
408
409 cpu_suspend(0, imx6q_suspend_finish);
410 if (cpu_is_imx6q() || cpu_is_imx6dl())
411 imx_smp_prepare();
412 imx_anatop_post_resume();
413 imx_gpc_post_resume();
414 imx6_enable_rbc(false);
415 imx6q_enable_wb(false);
416 imx6_set_int_mem_clk_lpm(true);
417 imx6_set_lpm(WAIT_CLOCKED);
418 break;
419 default:
420 return -EINVAL;
421 }
422
423 return 0;
424 }
425
426 static int imx6q_pm_valid(suspend_state_t state)
427 {
428 return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
429 }
430
431 static const struct platform_suspend_ops imx6q_pm_ops = {
432 .enter = imx6q_pm_enter,
433 .valid = imx6q_pm_valid,
434 };
435
436 static int __init imx6_pm_get_base(struct imx6_pm_base *base,
437 const char *compat)
438 {
439 struct device_node *node;
440 struct resource res;
441 int ret = 0;
442
443 node = of_find_compatible_node(NULL, NULL, compat);
444 if (!node)
445 return -ENODEV;
446
447 ret = of_address_to_resource(node, 0, &res);
448 if (ret)
449 goto put_node;
450
451 base->pbase = res.start;
452 base->vbase = ioremap(res.start, resource_size(&res));
453 if (!base->vbase)
454 ret = -ENOMEM;
455
456 put_node:
457 of_node_put(node);
458 return ret;
459 }
460
461 static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
462 {
463 phys_addr_t ocram_pbase;
464 struct device_node *node;
465 struct platform_device *pdev;
466 struct imx6_cpu_pm_info *pm_info;
467 struct gen_pool *ocram_pool;
468 unsigned long ocram_base;
469 int i, ret = 0;
470 const u32 *mmdc_offset_array;
471
472 suspend_set_ops(&imx6q_pm_ops);
473
474 if (!socdata) {
475 pr_warn("%s: invalid argument!\n", __func__);
476 return -EINVAL;
477 }
478
479 node = of_find_compatible_node(NULL, NULL, "mmio-sram");
480 if (!node) {
481 pr_warn("%s: failed to find ocram node!\n", __func__);
482 return -ENODEV;
483 }
484
485 pdev = of_find_device_by_node(node);
486 if (!pdev) {
487 pr_warn("%s: failed to find ocram device!\n", __func__);
488 ret = -ENODEV;
489 goto put_node;
490 }
491
492 ocram_pool = gen_pool_get(&pdev->dev, NULL);
493 if (!ocram_pool) {
494 pr_warn("%s: ocram pool unavailable!\n", __func__);
495 ret = -ENODEV;
496 goto put_node;
497 }
498
499 ocram_base = gen_pool_alloc(ocram_pool, MX6Q_SUSPEND_OCRAM_SIZE);
500 if (!ocram_base) {
501 pr_warn("%s: unable to alloc ocram!\n", __func__);
502 ret = -ENOMEM;
503 goto put_node;
504 }
505
506 ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
507
508 suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
509 MX6Q_SUSPEND_OCRAM_SIZE, false);
510
511 memset(suspend_ocram_base, 0, sizeof(*pm_info));
512 pm_info = suspend_ocram_base;
513 pm_info->pbase = ocram_pbase;
514 pm_info->resume_addr = __pa_symbol(v7_cpu_resume);
515 pm_info->pm_info_size = sizeof(*pm_info);
516
517
518
519
520
521 pm_info->ccm_base.vbase = ccm_base;
522
523 ret = imx6_pm_get_base(&pm_info->mmdc_base, socdata->mmdc_compat);
524 if (ret) {
525 pr_warn("%s: failed to get mmdc base %d!\n", __func__, ret);
526 goto put_node;
527 }
528
529 ret = imx6_pm_get_base(&pm_info->src_base, socdata->src_compat);
530 if (ret) {
531 pr_warn("%s: failed to get src base %d!\n", __func__, ret);
532 goto src_map_failed;
533 }
534
535 ret = imx6_pm_get_base(&pm_info->iomuxc_base, socdata->iomuxc_compat);
536 if (ret) {
537 pr_warn("%s: failed to get iomuxc base %d!\n", __func__, ret);
538 goto iomuxc_map_failed;
539 }
540
541 ret = imx6_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
542 if (ret) {
543 pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
544 goto gpc_map_failed;
545 }
546
547 if (socdata->pl310_compat) {
548 ret = imx6_pm_get_base(&pm_info->l2_base, socdata->pl310_compat);
549 if (ret) {
550 pr_warn("%s: failed to get pl310-cache base %d!\n",
551 __func__, ret);
552 goto pl310_cache_map_failed;
553 }
554 }
555
556 pm_info->ddr_type = imx_mmdc_get_ddr_type();
557 pm_info->mmdc_io_num = socdata->mmdc_io_num;
558 mmdc_offset_array = socdata->mmdc_io_offset;
559
560 for (i = 0; i < pm_info->mmdc_io_num; i++) {
561 pm_info->mmdc_io_val[i][0] =
562 mmdc_offset_array[i];
563 pm_info->mmdc_io_val[i][1] =
564 readl_relaxed(pm_info->iomuxc_base.vbase +
565 mmdc_offset_array[i]);
566 }
567
568 imx6_suspend_in_ocram_fn = fncpy(
569 suspend_ocram_base + sizeof(*pm_info),
570 &imx6_suspend,
571 MX6Q_SUSPEND_OCRAM_SIZE - sizeof(*pm_info));
572
573 goto put_node;
574
575 pl310_cache_map_failed:
576 iounmap(pm_info->gpc_base.vbase);
577 gpc_map_failed:
578 iounmap(pm_info->iomuxc_base.vbase);
579 iomuxc_map_failed:
580 iounmap(pm_info->src_base.vbase);
581 src_map_failed:
582 iounmap(pm_info->mmdc_base.vbase);
583 put_node:
584 of_node_put(node);
585
586 return ret;
587 }
588
589 static void __init imx6_pm_common_init(const struct imx6_pm_socdata
590 *socdata)
591 {
592 struct regmap *gpr;
593 int ret;
594
595 WARN_ON(!ccm_base);
596
597 if (IS_ENABLED(CONFIG_SUSPEND)) {
598 ret = imx6q_suspend_init(socdata);
599 if (ret)
600 pr_warn("%s: No DDR LPM support with suspend %d!\n",
601 __func__, ret);
602 }
603
604
605
606
607
608
609
610
611 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
612 if (!IS_ERR(gpr))
613 regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
614 IMX6Q_GPR1_GINT);
615 }
616
617 static void imx6_pm_stby_poweroff(void)
618 {
619 imx6_set_lpm(STOP_POWER_OFF);
620 imx6q_suspend_finish(0);
621
622 mdelay(1000);
623
624 pr_emerg("Unable to poweroff system\n");
625 }
626
627 static int imx6_pm_stby_poweroff_probe(void)
628 {
629 if (pm_power_off) {
630 pr_warn("%s: pm_power_off already claimed %p %ps!\n",
631 __func__, pm_power_off, pm_power_off);
632 return -EBUSY;
633 }
634
635 pm_power_off = imx6_pm_stby_poweroff;
636 return 0;
637 }
638
639 void __init imx6_pm_ccm_init(const char *ccm_compat)
640 {
641 struct device_node *np;
642 u32 val;
643
644 np = of_find_compatible_node(NULL, NULL, ccm_compat);
645 ccm_base = of_iomap(np, 0);
646 BUG_ON(!ccm_base);
647
648
649
650
651
652 val = readl_relaxed(ccm_base + CLPCR);
653 val &= ~BM_CLPCR_LPM;
654 writel_relaxed(val, ccm_base + CLPCR);
655
656 if (of_property_read_bool(np, "fsl,pmic-stby-poweroff"))
657 imx6_pm_stby_poweroff_probe();
658 }
659
660 void __init imx6q_pm_init(void)
661 {
662 imx6_pm_common_init(&imx6q_pm_data);
663 }
664
665 void __init imx6dl_pm_init(void)
666 {
667 imx6_pm_common_init(&imx6dl_pm_data);
668 }
669
670 void __init imx6sl_pm_init(void)
671 {
672 struct regmap *gpr;
673
674 if (cpu_is_imx6sl()) {
675 imx6_pm_common_init(&imx6sl_pm_data);
676 } else {
677 imx6_pm_common_init(&imx6sll_pm_data);
678 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
679 if (!IS_ERR(gpr))
680 regmap_update_bits(gpr, IOMUXC_GPR5,
681 IMX6SLL_GPR5_AFCG_X_BYPASS_MASK, 0);
682 }
683 }
684
685 void __init imx6sx_pm_init(void)
686 {
687 imx6_pm_common_init(&imx6sx_pm_data);
688 }
689
690 void __init imx6ul_pm_init(void)
691 {
692 imx6_pm_common_init(&imx6ul_pm_data);
693 }