| /* |
| * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. All Rights Reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #include <linux/linkage.h> |
| #include "hardware.h" |
| |
| #define DDRC_MSTR 0x0 |
| #define DDRC_STAT 0x4 |
| #define DDRC_MRCTRL0 0x10 |
| #define DDRC_MRCTRL1 0x14 |
| #define DDRC_MRSTAT 0x18 |
| #define DDRC_PWRCTL 0x30 |
| #define DDRC_RFSHCTL3 0x60 |
| #define DDRC_RFSHTMG 0x64 |
| #define DDRC_DBG1 0x304 |
| #define DDRC_SWCTL 0x320 |
| #define DDRC_SWSTAT 0x324 |
| #define DDRC_PSTAT 0x3fc |
| #define DDRC_PCTRL_0 0x490 |
| #define DDRC_ZQCTL0 0x180 |
| #define DDRC_DFIMISC 0x1b0 |
| #define DDRC_DBGCAM 0x308 |
| #define DDRPHY_LP_CON0 0x18 |
| #define IOMUXC_GPR8 0x20 |
| #define DDRPHY_MDLL_CON0 0xb0 |
| #define DDRPHY_MDLL_CON1 0xb4 |
| #define DDRPHY_OFFSETD_CON0 0x50 |
| #define DDRPHY_OFFSETR_CON0 0x20 |
| #define DDRPHY_OFFSETR_CON1 0x24 |
| #define DDRPHY_OFFSETR_CON2 0x28 |
| #define DDRPHY_OFFSETW_CON0 0x30 |
| #define DDRPHY_OFFSETW_CON1 0x34 |
| #define DDRPHY_OFFSETW_CON2 0x38 |
| #define DDRPHY_CA_WLDSKEW_CON0 0x6c |
| #define DDRPHY_CA_DSKEW_CON0 0x7c |
| #define DDRPHY_CA_DSKEW_CON1 0x80 |
| #define DDRPHY_CA_DSKEW_CON2 0x84 |
| |
| #define ANADIG_DIGPROG 0x800 |
| |
| .align 3 |
| |
| .macro switch_to_below_100m |
| |
| ldr r7, =0x2 |
| str r7, [r4, #DDRC_DBG1] |
| |
| ldr r6, =0x36000000 |
| 1: |
| ldr r7, [r4, #DDRC_DBGCAM] |
| and r7, r7, r6 |
| cmp r7, r6 |
| bne 1b |
| |
| ldr r6, =0x1 |
| 2: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 2b |
| |
| ldr r7, =0x10f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x0 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800010f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r6, =0x1 |
| 3: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 3b |
| |
| ldr r7, =0x20f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x8 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800020f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r6, =0x1 |
| 4: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 4b |
| |
| ldr r7, =0x10f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x1 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800010f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r7, =0x20 |
| str r7, [r4, #DDRC_PWRCTL] |
| |
| ldr r6, =0x23 |
| 5: |
| ldr r7, [r4, #DDRC_STAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| bne 5b |
| |
| ldr r7, =0x0 |
| str r7, [r4, #DDRC_SWCTL] |
| |
| ldr r7, =0x03048001 |
| str r7, [r4, #DDRC_MSTR] |
| |
| ldr r7, =0x1 |
| str r7, [r4, #DDRC_SWCTL] |
| |
| ldr r6, =0x1 |
| 6: |
| ldr r7, [r4, #DDRC_SWSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| bne 6b |
| |
| ldr r7, =0x10010100 |
| str r7, [r5, #0x4] |
| |
| ldr r6, =24000000 |
| cmp r0, r6 |
| beq 25f |
| |
| ldr r7, =0x000B000D |
| str r7,[r4, #DDRC_RFSHTMG] |
| b 7f |
| |
| 25: |
| ldr r7, =0x00030004 |
| str r7,[r4, #DDRC_RFSHTMG] |
| |
| /* dram alt sel set to OSC */ |
| ldr r7, =0x10000000 |
| ldr r8, =0xa080 |
| str r7, [r2, r8] |
| /* dram root set to from dram alt, div by 1 */ |
| ldr r7, =0x11000000 |
| ldr r8, =0x9880 |
| str r7, [r2, r8] |
| b 8f |
| 7: |
| /* dram alt sel set to pfd0_392m */ |
| ldr r7, =0x15000000 |
| ldr r8, =0xa080 |
| str r7, [r2, r8] |
| /* dram root set to from dram alt, div by 4 */ |
| ldr r7, =0x11000003 |
| ldr r8, =0x9880 |
| str r7, [r2, r8] |
| 8: |
| ldr r7, =0x202ffd0 |
| str r7, [r5, #DDRPHY_MDLL_CON0] |
| |
| ldr r7, =0x1000007f |
| str r7, [r5, #DDRPHY_OFFSETD_CON0] |
| |
| ldr r7, =0x7f7f7f7f |
| str r7, [r5, #DDRPHY_OFFSETR_CON0] |
| str r7, [r5, #DDRPHY_OFFSETR_CON1] |
| ldr r7, =0x7f |
| str r7, [r5, #DDRPHY_OFFSETR_CON2] |
| |
| ldr r7, =0x7f7f7f7f |
| str r7, [r5, #DDRPHY_OFFSETW_CON0] |
| str r7, [r5, #DDRPHY_OFFSETW_CON1] |
| ldr r7, =0x7f |
| str r7, [r5, #DDRPHY_OFFSETW_CON2] |
| |
| ldr r7, [r9, #ANADIG_DIGPROG] |
| and r7, r7, #0x11 |
| cmp r7, #0x11 |
| bne 20f |
| |
| ldr r7, =0x0 |
| str r7, [r5, #DDRPHY_CA_WLDSKEW_CON0] |
| ldr r7, =0x60606060 |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON0] |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON1] |
| ldr r7, =0x00006060 |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON2] |
| b 21f |
| 20: |
| ldr r7, =0x0 |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON0] |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON1] |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON2] |
| 21: |
| ldr r7, =0x1100007f |
| str r7, [r5, #DDRPHY_OFFSETD_CON0] |
| ldr r7, =0x1000007f |
| str r7, [r5, #DDRPHY_OFFSETD_CON0] |
| |
| ldr r7, =0x0 |
| str r7, [r4, #DDRC_PWRCTL] |
| |
| ldr r6, =0x1 |
| 9: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 9b |
| |
| ldr r7, =0xf0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x820 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800000f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r6, =0x1 |
| 10: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 10b |
| |
| ldr r7, =0x800020 |
| str r7, [r4, #DDRC_ZQCTL0] |
| |
| ldr r7, =0x0 |
| str r7, [r4, #DDRC_DBG1] |
| |
| /* enable auto self-refresh */ |
| ldr r7, [r4, #DDRC_PWRCTL] |
| orr r7, r7, #(1 << 0) |
| str r7, [r4, #DDRC_PWRCTL] |
| |
| .endm |
| |
| .macro switch_to_533m |
| |
| ldr r7, =0x2 |
| str r7, [r4, #DDRC_DBG1] |
| |
| ldr r7, =0x78 |
| str r7, [r3, #IOMUXC_GPR8] |
| orr r7, r7, #0x100 |
| str r7, [r3, #IOMUXC_GPR8] |
| |
| ldr r6, =0x30000000 |
| 11: |
| ldr r7, [r4, #DDRC_DBGCAM] |
| and r7, r7, r6 |
| cmp r7, r6 |
| bne 11b |
| |
| ldr r6, =0x1 |
| 12: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 12b |
| |
| ldr r7, =0x10f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x1 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800010f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r7, =0x20 |
| str r7, [r4, #DDRC_PWRCTL] |
| |
| ldr r6, =0x23 |
| 13: |
| ldr r7, [r4, #DDRC_STAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| bne 13b |
| |
| ldr r7, =0x03040001 |
| str r7, [r4, #DDRC_MSTR] |
| |
| ldr r7, =0x40800020 |
| str r7, [r4, #DDRC_ZQCTL0] |
| |
| |
| ldr r7, =0x10210100 |
| str r7, [r5, #0x4] |
| |
| ldr r7, =0x00040046 |
| str r7, [r4, #DDRC_RFSHTMG] |
| |
| /* dram root set to from dram main, div by 2 */ |
| ldr r7, =0x10000001 |
| ldr r8, =0x9880 |
| str r7, [r2, r8] |
| |
| ldr r7, =0x1010007e |
| str r7, [r5, #DDRPHY_MDLL_CON0] |
| |
| ldr r7, =0x10000008 |
| str r7, [r5, #DDRPHY_OFFSETD_CON0] |
| |
| ldr r7, =0x08080808 |
| str r7, [r5, #DDRPHY_OFFSETR_CON0] |
| str r7, [r5, #DDRPHY_OFFSETR_CON1] |
| ldr r7, =0x8 |
| str r7, [r5, #DDRPHY_OFFSETR_CON2] |
| |
| ldr r7, =0x08080808 |
| str r7, [r5, #DDRPHY_OFFSETW_CON0] |
| str r7, [r5, #DDRPHY_OFFSETW_CON1] |
| ldr r7, =0x8 |
| str r7, [r5, #DDRPHY_OFFSETW_CON2] |
| |
| ldr r7, [r9, #ANADIG_DIGPROG] |
| and r7, r7, #0x11 |
| cmp r7, #0x11 |
| bne 22f |
| |
| ldr r7, =0x40404040 |
| str r7, [r5, #DDRPHY_CA_WLDSKEW_CON0] |
| ldr r7, =0x18181818 |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON0] |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON1] |
| ldr r7, =0x40401818 |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON2] |
| b 23f |
| 22: |
| ldr r7, =0x0 |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON0] |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON1] |
| str r7, [r5, #DDRPHY_CA_DSKEW_CON2] |
| 23: |
| ldr r7, =0x11000008 |
| str r7, [r5, #DDRPHY_OFFSETD_CON0] |
| ldr r7, =0x10000008 |
| str r7, [r5, #DDRPHY_OFFSETD_CON0] |
| |
| ldr r6, =0x4 |
| 14: |
| ldr r7, [r5, #DDRPHY_MDLL_CON1] |
| and r7, r7, r6 |
| cmp r7, r6 |
| bne 14b |
| |
| ldr r7, =0x1 |
| str r7, [r4, #DDRC_RFSHCTL3] |
| ldr r7, =0x3 |
| str r7, [r4, #DDRC_RFSHCTL3] |
| |
| ldr r7, =0x0 |
| str r7, [r4, #DDRC_PWRCTL] |
| |
| ldr r6, =0x1 |
| 15: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 15b |
| |
| ldr r7, =0x10f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x0 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800010f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r6, =0x1 |
| 16: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 16b |
| |
| ldr r7, =0xf0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x930 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800000f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r7, =0x0 |
| str r7, [r4, #DDRC_RFSHCTL3] |
| ldr r7, =0x2 |
| str r7, [r4, #DDRC_RFSHCTL3] |
| |
| ldr r6, =0x1 |
| 17: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 17b |
| |
| ldr r7, =0xf0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x930 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800000f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r6, =0x1 |
| 18: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 18b |
| |
| ldr r7, =0x20f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x408 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800020f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r6, =0x1 |
| 19: |
| ldr r7, [r4, #DDRC_MRSTAT] |
| and r7, r7, r6 |
| cmp r7, r6 |
| beq 19b |
| |
| ldr r7, =0x10f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| ldr r7, =0x4 |
| str r7, [r4, #DDRC_MRCTRL1] |
| ldr r7, =0x800010f0 |
| str r7, [r4, #DDRC_MRCTRL0] |
| |
| ldr r7, =0x0 |
| str r7, [r4, #DDRC_DBG1] |
| |
| /* enable auto self-refresh */ |
| ldr r7, [r4, #DDRC_PWRCTL] |
| orr r7, r7, #(1 << 0) |
| str r7, [r4, #DDRC_PWRCTL] |
| |
| .endm |
| |
| ENTRY(imx7d_ddr3_freq_change) |
| push {r2 - r9} |
| |
| /* |
| * To ensure no page table walks occur in DDR, we |
| * have a another page table stored in IRAM that only |
| * contains entries pointing to IRAM, AIPS1 and AIPS2. |
| * We need to set the TTBR1 to the new IRAM TLB. |
| * Do the following steps: |
| * 1. Flush the Branch Target Address Cache (BTAC) |
| * 2. Set TTBR1 to point to IRAM page table. |
| * 3. Disable page table walks in TTBR0 (PD0 = 1) |
| * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0 |
| * and 2-4G is translated by TTBR1. |
| */ |
| ldr r6, =0x0 |
| mcr p15, 0, r6, c8, c3, 0 |
| |
| ldr r6, =iram_tlb_phys_addr |
| ldr r7, [r6] |
| |
| /* Disable Branch Prediction, Z bit in SCTLR. */ |
| mrc p15, 0, r6, c1, c0, 0 |
| bic r6, r6, #0x800 |
| mcr p15, 0, r6, c1, c0, 0 |
| |
| /* Flush the Branch Target Address Cache (BTAC) */ |
| ldr r6, =0x0 |
| mcr p15, 0, r6, c7, c1, 6 |
| |
| dsb |
| isb |
| /* Store the IRAM table in TTBR1 */ |
| mcr p15, 0, r7, c2, c0, 1 |
| |
| /* Read TTBCR and set PD0=1, N = 1 */ |
| mrc p15, 0, r6, c2, c0, 2 |
| orr r6, r6, #0x11 |
| mcr p15, 0, r6, c2, c0, 2 |
| |
| dsb |
| isb |
| |
| /* flush the TLB */ |
| ldr r6, =0x0 |
| mcr p15, 0, r6, c8, c3, 0 |
| |
| dsb |
| isb |
| |
| ldr r2, =IMX_IO_P2V(MX7D_CCM_BASE_ADDR) |
| ldr r3, =IMX_IO_P2V(MX7D_IOMUXC_GPR_BASE_ADDR) |
| ldr r4, =IMX_IO_P2V(MX7D_DDRC_BASE_ADDR) |
| ldr r5, =IMX_IO_P2V(MX7D_DDRC_PHY_BASE_ADDR) |
| ldr r9, =IMX_IO_P2V(MX7D_ANATOP_BASE_ADDR) |
| |
| ldr r6, =100000000 |
| cmp r0, r6 |
| bgt set_to_533m |
| |
| set_to_below_100m: |
| switch_to_below_100m |
| b done |
| |
| set_to_533m: |
| switch_to_533m |
| b done |
| |
| done: |
| /* Enable L1 data cache. */ |
| mrc p15, 0, r6, c1, c0, 0 |
| orr r6, r6, #0x4 |
| mcr p15, 0, r6, c1, c0, 0 |
| |
| /* Restore the TTBCR */ |
| dsb |
| isb |
| |
| /* Read TTBCR and set PD0=0, N = 0 */ |
| mrc p15, 0, r6, c2, c0, 2 |
| bic r6, r6, #0x11 |
| mcr p15, 0, r6, c2, c0, 2 |
| dsb |
| isb |
| |
| /* flush the TLB */ |
| ldr r6, =0x0 |
| mcr p15, 0, r6, c8, c3, 0 |
| |
| dsb |
| isb |
| |
| /* Enable Branch Prediction, Z bit in SCTLR. */ |
| mrc p15, 0, r6, c1, c0, 0 |
| orr r6, r6, #0x800 |
| mcr p15, 0, r6, c1, c0, 0 |
| |
| /* Flush the Branch Target Address Cache (BTAC) */ |
| ldr r6, =0x0 |
| mcr p15, 0, r6, c7, c1, 6 |
| |
| dsb |
| isb |
| |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| /* Restore registers */ |
| pop {r2 - r9} |
| mov pc, lr |
| .ltorg |
| ENDPROC(imx7d_ddr3_freq_change) |