]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
b9e745bb SL |
2 | /* |
3 | * Copyright 2016 Freescale Semiconductor, Inc. | |
b9e745bb SL |
4 | */ |
5 | ||
6 | /* | |
7 | * Generic driver for Freescale MMDC(Multi Mode DDR Controller). | |
8 | */ | |
9 | ||
10 | #include <common.h> | |
11 | #include <fsl_mmdc.h> | |
12 | #include <asm/io.h> | |
13 | ||
14 | static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits) | |
15 | { | |
16 | int timeout = 1000; | |
17 | ||
18 | out_be32(ptr, value); | |
19 | ||
20 | while (in_be32(ptr) & bits) { | |
21 | udelay(100); | |
22 | timeout--; | |
23 | } | |
24 | if (timeout <= 0) | |
25 | printf("Error: %p wait for clear timeout.\n", ptr); | |
26 | } | |
27 | ||
1fdcc8df | 28 | void mmdc_init(const struct fsl_mmdc_info *priv) |
b9e745bb SL |
29 | { |
30 | struct mmdc_regs *mmdc = (struct mmdc_regs *)CONFIG_SYS_FSL_DDR_ADDR; | |
31 | unsigned int tmp; | |
32 | ||
33 | /* 1. set configuration request */ | |
34 | out_be32(&mmdc->mdscr, MDSCR_ENABLE_CON_REQ); | |
35 | ||
36 | /* 2. configure the desired timing parameters */ | |
1fdcc8df YS |
37 | out_be32(&mmdc->mdotc, priv->mdotc); |
38 | out_be32(&mmdc->mdcfg0, priv->mdcfg0); | |
39 | out_be32(&mmdc->mdcfg1, priv->mdcfg1); | |
40 | out_be32(&mmdc->mdcfg2, priv->mdcfg2); | |
b9e745bb SL |
41 | |
42 | /* 3. configure DDR type and other miscellaneous parameters */ | |
1fdcc8df | 43 | out_be32(&mmdc->mdmisc, priv->mdmisc); |
b9e745bb | 44 | out_be32(&mmdc->mpmur0, MMDC_MPMUR0_FRC_MSR); |
1fdcc8df YS |
45 | out_be32(&mmdc->mdrwd, priv->mdrwd); |
46 | out_be32(&mmdc->mpodtctrl, priv->mpodtctrl); | |
b9e745bb SL |
47 | |
48 | /* 4. configure the required delay while leaving reset */ | |
1fdcc8df | 49 | out_be32(&mmdc->mdor, priv->mdor); |
b9e745bb SL |
50 | |
51 | /* 5. configure DDR physical parameters */ | |
52 | /* set row/column address width, burst length, data bus width */ | |
1fdcc8df | 53 | tmp = priv->mdctl & ~(MDCTL_SDE0 | MDCTL_SDE1); |
b9e745bb SL |
54 | out_be32(&mmdc->mdctl, tmp); |
55 | /* configure address space partition */ | |
1fdcc8df | 56 | out_be32(&mmdc->mdasp, priv->mdasp); |
b9e745bb SL |
57 | |
58 | /* 6. perform a ZQ calibration - not needed here, doing in #8b */ | |
59 | ||
60 | /* 7. enable MMDC with the desired chip select */ | |
61 | #if (CONFIG_CHIP_SELECTS_PER_CTRL == 1) | |
62 | out_be32(&mmdc->mdctl, tmp | MDCTL_SDE0); | |
63 | #elif (CONFIG_CHIP_SELECTS_PER_CTRL == 2) | |
64 | out_be32(&mmdc->mdctl, tmp | MDCTL_SDE0 | MDCTL_SDE1); | |
65 | #endif | |
66 | ||
67 | /* 8a. dram init sequence: update MRs for ZQ, ODT, PRE, etc */ | |
68 | out_be32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(8) | MDSCR_ENABLE_CON_REQ | | |
69 | CMD_LOAD_MODE_REG | CMD_BANK_ADDR_2); | |
70 | ||
71 | out_be32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(0) | MDSCR_ENABLE_CON_REQ | | |
72 | CMD_LOAD_MODE_REG | CMD_BANK_ADDR_3); | |
73 | ||
74 | out_be32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(4) | MDSCR_ENABLE_CON_REQ | | |
75 | CMD_LOAD_MODE_REG | CMD_BANK_ADDR_1); | |
76 | ||
77 | out_be32(&mmdc->mdscr, CMD_ADDR_MSB_MR_OP(0x19) | | |
78 | CMD_ADDR_LSB_MR_ADDR(0x30) | | |
79 | MDSCR_ENABLE_CON_REQ | | |
80 | CMD_LOAD_MODE_REG | CMD_BANK_ADDR_0); | |
81 | ||
82 | /* 8b. ZQ calibration */ | |
83 | out_be32(&mmdc->mdscr, CMD_ADDR_MSB_MR_OP(0x4) | MDSCR_ENABLE_CON_REQ | | |
84 | CMD_ZQ_CALIBRATION | CMD_BANK_ADDR_0); | |
85 | ||
1fdcc8df | 86 | set_wait_for_bits_clear(&mmdc->mpzqhwctrl, priv->mpzqhwctrl, |
b9e745bb SL |
87 | MPZQHWCTRL_ZQ_HW_FORCE); |
88 | ||
89 | /* 9a. calibrations now, wr lvl */ | |
90 | out_be32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(0x84) | | |
91 | MDSCR_ENABLE_CON_REQ | | |
92 | CMD_LOAD_MODE_REG | CMD_BANK_ADDR_1); | |
93 | ||
94 | out_be32(&mmdc->mdscr, MDSCR_ENABLE_CON_REQ | MDSCR_WL_EN | | |
95 | CMD_NORMAL); | |
96 | ||
97 | set_wait_for_bits_clear(&mmdc->mpwlgcr, MPWLGCR_HW_WL_EN, | |
98 | MPWLGCR_HW_WL_EN); | |
99 | ||
100 | mdelay(1); | |
101 | ||
102 | out_be32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(4) | MDSCR_ENABLE_CON_REQ | | |
103 | CMD_LOAD_MODE_REG | CMD_BANK_ADDR_1); | |
104 | out_be32(&mmdc->mdscr, MDSCR_ENABLE_CON_REQ); | |
105 | ||
106 | mdelay(1); | |
107 | ||
108 | /* 9b. read DQS gating calibration */ | |
109 | out_be32(&mmdc->mdscr, CMD_ADDR_MSB_MR_OP(4) | MDSCR_ENABLE_CON_REQ | | |
110 | CMD_PRECHARGE_BANK_OPEN | CMD_BANK_ADDR_0); | |
111 | ||
112 | out_be32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(4) | MDSCR_ENABLE_CON_REQ | | |
113 | CMD_LOAD_MODE_REG | CMD_BANK_ADDR_3); | |
114 | ||
115 | out_be32(&mmdc->mppdcmpr2, MPPDCMPR2_MPR_COMPARE_EN); | |
116 | ||
117 | /* set absolute read delay offset */ | |
1fdcc8df YS |
118 | if (priv->mprddlctl) |
119 | out_be32(&mmdc->mprddlctl, priv->mprddlctl); | |
120 | else | |
121 | out_be32(&mmdc->mprddlctl, MMDC_MPRDDLCTL_DEFAULT_DELAY); | |
122 | ||
b9e745bb SL |
123 | set_wait_for_bits_clear(&mmdc->mpdgctrl0, |
124 | AUTO_RD_DQS_GATING_CALIBRATION_EN, | |
125 | AUTO_RD_DQS_GATING_CALIBRATION_EN); | |
126 | ||
127 | out_be32(&mmdc->mdscr, MDSCR_ENABLE_CON_REQ | CMD_LOAD_MODE_REG | | |
128 | CMD_BANK_ADDR_3); | |
129 | ||
130 | /* 9c. read calibration */ | |
131 | out_be32(&mmdc->mdscr, CMD_ADDR_MSB_MR_OP(4) | MDSCR_ENABLE_CON_REQ | | |
132 | CMD_PRECHARGE_BANK_OPEN | CMD_BANK_ADDR_0); | |
133 | out_be32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(4) | MDSCR_ENABLE_CON_REQ | | |
134 | CMD_LOAD_MODE_REG | CMD_BANK_ADDR_3); | |
135 | out_be32(&mmdc->mppdcmpr2, MPPDCMPR2_MPR_COMPARE_EN); | |
136 | set_wait_for_bits_clear(&mmdc->mprddlhwctl, | |
137 | MPRDDLHWCTL_AUTO_RD_CALIBRATION_EN, | |
138 | MPRDDLHWCTL_AUTO_RD_CALIBRATION_EN); | |
139 | ||
140 | out_be32(&mmdc->mdscr, MDSCR_ENABLE_CON_REQ | CMD_LOAD_MODE_REG | | |
141 | CMD_BANK_ADDR_3); | |
142 | ||
143 | /* 10. configure power-down, self-refresh entry, exit parameters */ | |
1fdcc8df | 144 | out_be32(&mmdc->mdpdc, priv->mdpdc); |
b9e745bb SL |
145 | out_be32(&mmdc->mapsr, MMDC_MAPSR_PWR_SAV_CTRL_STAT); |
146 | ||
147 | /* 11. ZQ config again? do nothing here */ | |
148 | ||
149 | /* 12. refresh scheme */ | |
1fdcc8df | 150 | set_wait_for_bits_clear(&mmdc->mdref, priv->mdref, |
b9e745bb SL |
151 | MDREF_START_REFRESH); |
152 | ||
153 | /* 13. disable CON_REQ */ | |
154 | out_be32(&mmdc->mdscr, MDSCR_DISABLE_CFG_REQ); | |
155 | } |