2 * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the license, or
7 * (at your option) any later version.
9 * This program is distributed in teh hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/linkage.h>
17 #define PM_INFO_PM_INFO_SIZE_OFFSET 0x0
18 #define PM_INFO_TTBR_OFFSET 0x4
19 #define PM_INFO_MMDC_V_OFFSET 0x8
20 #define PM_INFO_IOMUXC_V_OFFSET 0xc
21 #define PM_INFO_CCM_V_OFFSET 0x10
22 #define PM_INFO_L2_V_OFFSET 0x14
23 #define PM_INFO_ANATOP_V_OFFSET 0x18
24 #define PM_INFO_IO_NUM_OFFSET 0x1c
25 #define PM_INFO_IO_VAL_OFFSET 0x20
27 #define MX6Q_MMDC_MAPSR 0x404
28 #define MX6Q_MMDC_MPDGCTRL0 0x83c
30 .global mx6sl_lpm_wfi_start
31 .global mx6sl_lpm_wfi_end
33 .macro pll_do_wait_lock
51 ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
53 * if in audio_bus_freq_mode, skip to
54 * audio_mode low power setting.
59 * Now set DDR rate to 1MHz.
60 * DDR is from bypassed PLL2 on periph2_clk2 path.
61 * Set the periph2_clk2_podf to divide by 8.
67 /* Now set MMDC PODF to divide by 3. */
75 /* Set the AHB to 3MHz. AXI to 3MHz. */
77 /*r12 stores the origin AHB podf value */
85 /* Now set ARM to 24MHz.
86 * Move ARM to be sourced from step_clk
87 * after setting step_clk to 24MHz.
92 /*Now pll1_sw_clk to step_clk */
97 /* Bypass PLL1 and power it down */
98 ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
104 * Set the ARM PODF to divide by 8.
105 * IPG is at 1.5MHz here, we need ARM to
106 * run at the 12:5 ratio (WAIT mode issue).
108 ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
109 ldr r11, [r10, #0x10]
119 * MMDC is sourced from pll2_200M.
120 * Set the mmdc_podf to div by 8
122 ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
130 * ARM is sourced from pll2_pfd2_400M here.
131 * switch ARM to bypassed PLL1
133 ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
139 * set the arm_podf to divide by 3
140 * as IPG is at 4MHz, we cannot run
141 * arm clk above 9.6MHz when system
144 ldr r11, [r10, #0x10]
157 * If in audio_bus_freq_mode, skip to
158 * audio_mode ccm restore.
161 beq audio_ccm_restore
163 ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
164 /* Power up PLL1 and un-bypass it. */
168 /* Wait for PLL1 to relock */
175 ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
176 /* Set PLL1_sw_clk back to PLL1 */
181 /* Restore AHB/AXI back */
182 str r12, [r10, #0x14]
186 /* restore mmdc back to 24MHz*/
195 /* move arm clk back to pll2_pfd2_400M */
200 /* restore mmdc podf */
201 ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
213 .macro check_pll_state
215 ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
217 * Check whether any PLL is enabled, as only when
218 * there is no PLLs enabled, 2p5 can be off and
219 * only enable the weak one. PLL1 will be powered
220 * down late, so no need to check PLL1 state.
225 ands r6, r6, #(1 << 31)
230 ands r6, r6, #(1 << 31)
235 ands r6, r6, #(1 << 31)
240 ands r6, r6, #(1 << 31)
245 ands r6, r6, #(1 << 31)
250 ands r6, r6, #(1 << 31)
261 .macro anatop_enter_idle
263 ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
265 beq anatop_enter_done
267 /* Disable 1p1 brown out. */
268 ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
269 ldr r6, [r10, #0x110]
271 str r6, [r10, #0x110]
273 * Set the OSC bias current to -37.5%
274 * to drop the power on VDDHIGH.
276 ldr r6, [r10, #0x150]
278 str r6, [r10, #0x150]
281 * if the usb VBUS wakeup is enabled, skip
285 beq anatop_enter_done
287 /* Enable the week 2p5 */
288 ldr r6, [r10, #0x130]
290 str r6, [r10, #0x130]
292 /* Disable main 2p5. */
293 ldr r6, [r10, #0x130]
295 str r6, [r10, #0x130]
298 * Cannot diable regular bandgap
299 * in LDO-enable mode. The bandgap
300 * is required for ARM-LDO to regulate
303 ldr r6, [r10, #0x140]
306 bne anatop_enter_done
308 /* Enable low power bandgap */
309 ldr r6, [r10, #0x260]
311 str r6, [r10, #0x260]
314 * Turn off the bias current
315 * from the regular bandgap.
317 ldr r6, [r10, #0x260]
319 str r6, [r10, #0x260]
322 * Clear the REFTTOP+SELFBIASOFF,
323 * self_bais circuit of the band gap.
324 * Per RM, should be cleared when
325 * band gap is powered down.
327 ldr r6, [r10, #0x150]
329 str r6, [r10, #0x150]
331 /* Power down the regular bandgap */
332 ldr r6, [r10, #0x150]
334 str r6, [r10, #0x150]
339 .macro anatop_exit_idle
341 ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET]
343 beq skip_anatop_restore
346 beq ldo2p5_not_disabled
348 * Regular bandgap will not be disabled
349 * in LDO-enabled mode as it is required
350 * for ARM-LDO to reguulate the voltage.
352 ldr r6, [r10, #0x140]
355 bne skip_bandgap_restore
357 /* Power up the regular bandgap */
358 ldr r6, [r10, #0x150]
360 str r6, [r10, #0x150]
362 /* wait for bandgap stable */
364 ldr r6, [r10, #0x150]
369 /* now disable bandgap self-bias circuit */
370 ldr r6, [r10, #0x150]
372 str r6, [r10, #0x150]
374 /* Turn on the bias current
375 * from the regular bandgap.
377 ldr r6, [r10, #0x260]
379 str r6, [r10, #0x260]
381 /* Disable the low power bandgap */
382 ldr r6, [r10, #0x260]
384 str r6, [r10, #0x260]
386 skip_bandgap_restore:
387 /* Enable main 2p5. */
388 ldr r6, [r10, #0x130]
390 str r6, [r10, #0x130]
392 /* Ensure the 2p5 is up */
394 ldr r6, [r10, #0x130]
399 /* Disable the weak 2p5 */
400 ldr r6, [r10, #0x130]
402 str r6, [r10, #0x130]
406 * Set the OSC bias current to max
407 * value for normal operation.
409 ldr r6, [r10, #0x150]
411 str r6, [r10, #0x150]
413 /* Enable 1p1 brown out, */
414 ldr r6, [r10, #0x110]
416 str r6, [r10, #0x110]
422 .macro disable_l1_dcache
424 /* disable d-cache */
425 mrc p15, 0, r7, c1, c0, 0
426 bic r7, r7, #(1 << 2)
427 mcr p15, 0, r7, c1, c0, 0
434 .macro mmdc_enter_dvfs_mode
436 /* disable automatic power saving. */
437 ldr r7, [r10, #MX6Q_MMDC_MAPSR]
439 str r7, [r10, #MX6Q_MMDC_MAPSR]
441 /* disable power down timer */
446 /* Make the DDR explicitly enter self-refresh. */
447 ldr r7, [r10, #MX6Q_MMDC_MAPSR]
448 orr r7, r7, #(1 << 21)
449 str r7, [r10, #MX6Q_MMDC_MAPSR]
452 ldr r7, [r10, #MX6Q_MMDC_MAPSR]
453 ands r7, r7, #(1 << 25)
456 /* set SBS step-by step mode */
457 ldr r7, [r10, #0x410]
459 str r7, [r10, #0x410]
464 /* restore MMDC IO */
465 ldr r10, [r0, #PM_INFO_IOMUXC_V_OFFSET]
467 ldr r6, [r0, #PM_INFO_IO_NUM_OFFSET]
468 ldr r7, =PM_INFO_IO_VAL_OFFSET
478 * Need to reset the FIFO to avoid MMDC lockup
479 * caused because of floating/changing the
480 * configuration of many DDR IO pads.
482 ldr r10, [r0, #PM_INFO_MMDC_V_OFFSET]
483 /* reset read FIFO, RST_RD_FIFO */
484 ldr r7, =MX6Q_MMDC_MPDGCTRL0
486 orr r6, r6, #(1 << 31)
490 ands r6, r6, #(1 << 31)
493 /* reset FIFO a second time */
494 ldr r7, =MX6Q_MMDC_MPDGCTRL0
496 orr r6, r6, #(1 << 31)
500 ands r6, r6, #(1 <<31)
503 ldr r10, [r0, #PM_INFO_MMDC_V_OFFSET]
504 /* Let DDR out of self-refresh */
505 ldr r7, [r10, #MX6Q_MMDC_MAPSR]
506 bic r7, r7, #(1 << 21)
507 str r7, [r10, #MX6Q_MMDC_MAPSR]
509 ldr r7, [r10, #MX6Q_MMDC_MAPSR]
510 ands r7, r7, #(1 << 25)
513 /* enable power down timer */
518 /* enable DDR auto power saving */
519 ldr r7, [r10, #MX6Q_MMDC_MAPSR]
521 str r7, [r10, #MX6Q_MMDC_MAPSR]
523 /* Clear SBS - unblock DDR accesses */
524 ldr r7, [r10, #0x410]
526 str r7, [r10, #0x410]
530 .macro tlb_set_to_ocram
533 mrc p15, 0, r7, c2, c0, 1
534 str r7, [r0, #PM_INFO_TTBR_OFFSET]
537 * To ensure no page table walks occur in DDR, we
538 * have a another page table stored in IRAM that only
539 * contains entries pointing to IRAM, AIPS1 and AIPS2.
540 * we need to set the TTBR1 to the new IRAM TLB.
541 * Do the following steps:
542 * 1. Flush the Branch Target Address Cache (BTAC)
543 * 2. Set TTBR1 to point to the IRAM page table.
544 * 3. Disable page table walks in TTBR0 (PD0 = 1)
545 * 4. Set TTBR0.N=1, implying 0-2G is transslated by TTBR0
546 * and 2-4G is translated by TTBR1.
549 ldr r6, =iram_tlb_phys_addr
552 /* Disable Branch Prediction, Z bit in SCTLR */
553 mrc p15, 0, r6, c1, c0, 0
555 mcr p15, 0, r6, c1, c0, 0
557 /* Flush the BTAC. */
559 mcr p15, 0, r6, c7, c1, 6
564 /* store the IRAM table in TTBR1 */
565 mcr p15, 0, r7, c2, c0, 1
566 /* Read TTBCR and set PD0=1, N=1 */
567 mrc p15, 0, r6, c2, c0, 2
569 mcr p15, 0, r6, c2, c0, 2
576 mcr p15, 0, r6, c8, c3, 0
580 .macro tlb_back_to_ddr
582 /* Restore the TTBCR */
586 /* Read TTBCR and set PD0=0, N=0 */
587 mrc p15, 0, r6, c2, c0, 2
589 mcr p15, 0, r6, c2, c0, 2
592 mcr p15, 0, r6, c8, c3, 0
597 /* Enable Branch Prediction, Z bit in SCTLR. */
598 mrc p15, 0, r6, c1, c0, 0
600 mcr p15, 0 ,r6, c1, c0, 0
601 /* Flush the Branch Target Address Cache (BTAC) */
603 mcr p15, 0, r6, c7, c1, 6
605 ldr r7, [r0, #PM_INFO_TTBR_OFFSET]
606 mcr p15, 0, r7, c2, c0, 1
610 .extern iram_tlb_phys_addr
613 * imx6sl_low_power_wfi code
614 * r0: wfi code base address
615 * r1: audio_bus_freq mode stat
616 * r2: vbus_ldo status
617 * r4: used for store the PLLs state
618 * r11: used for saving the ARM_PODF origin value
619 * r12: used for saving AHB_PODF origin value
622 ENTRY(imx6sl_low_power_wfi)
631 #ifdef CONFIG_CACHE_L2X0
633 ldr r10, [r0, #PM_INFO_L2_V_OFFSET]
634 /* Wait for background operations to complete. */
636 ldr r6, [r10, #0x730]
641 str r6, [r10, #0x730]
643 str r6, [r10, #0x100]
649 /* make sure MMDC in self-refresh */
650 ldr r10, [r0, #PM_INFO_MMDC_V_OFFSET]
652 /* save DDR IO settings and set to LPM mode*/
653 ldr r10, [r0, #PM_INFO_IOMUXC_V_OFFSET]
655 ldr r7, [r0, #PM_INFO_IO_NUM_OFFSET]
656 ldr r8, =PM_INFO_IO_VAL_OFFSET
659 /* imx6sl's last 3 IOs need special setting */
661 save_and_set_mmdc_io_lpm:
667 bne save_and_set_mmdc_io_lpm
684 /* check the PLLs lock state */
688 /* if in audio low power mode, no
689 * need to do anatop setting.
697 * Add these nops so that the
698 * prefetcher will not try to get
699 * any instrutions from DDR.
700 * The prefetch depth is about 23
701 * on A9, so adding 25 nops.
734 * restore the ARM PODF first to speed
735 * up the restore procedure
737 ldr r10, [r0, #PM_INFO_CCM_V_OFFSET]
738 /* Restore arm_clk_podf */
739 str r11, [r10, #0x10]
743 * if in audio low power mode, skip
744 * restore the anatop setting.
747 beq skip_analog_restore
755 mrc p15, 0, r7, c1, c0, 0
756 orr r7, r7, #(1 << 2)
757 mcr p15, 0, r7, c1, c0, 0
759 #ifdef CONFIG_CACHE_L2X0
760 ldr r10, [r0, #PM_INFO_L2_V_OFFSET]
763 str r7, [r10, #0x100]
767 /* Restore register */
772 * Add ltorg here to ensure that all
773 * literals are stored here and are
774 * within the text space.