Ryder Lee | 60f633e | 2018-11-15 10:08:03 +0800 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* |
| 3 | * MediaTek DDR3 driver for MT7629 SoC |
| 4 | * |
| 5 | * Copyright (C) 2018 MediaTek Inc. |
| 6 | * Author: Wu Zou <wu.zou@mediatek.com> |
| 7 | * Ryder Lee <ryder.lee@mediatek.com> |
| 8 | */ |
| 9 | |
| 10 | #include <clk.h> |
| 11 | #include <common.h> |
| 12 | #include <dm.h> |
| 13 | #include <ram.h> |
| 14 | #include <asm/io.h> |
Simon Glass | cd93d62 | 2020-05-10 11:40:13 -0600 | [diff] [blame] | 15 | #include <linux/bitops.h> |
Simon Glass | c05ed00 | 2020-05-10 11:40:11 -0600 | [diff] [blame] | 16 | #include <linux/delay.h> |
Ryder Lee | 60f633e | 2018-11-15 10:08:03 +0800 | [diff] [blame] | 17 | |
| 18 | /* EMI */ |
| 19 | #define EMI_CONA 0x000 |
| 20 | #define EMI_CONF 0x028 |
| 21 | #define EMI_CONM 0x060 |
| 22 | |
| 23 | /* DDR PHY */ |
| 24 | #define DDRPHY_PLL1 0x0000 |
| 25 | #define DDRPHY_PLL2 0x0004 |
| 26 | #define DDRPHY_PLL3 0x0008 |
| 27 | #define DDRPHY_PLL4 0x000c |
| 28 | #define DDRPHY_PLL5 0x0010 |
| 29 | #define DDRPHY_PLL7 0x0018 |
| 30 | #define DDRPHY_B0_DLL_ARPI0 0x0080 |
| 31 | #define DDRPHY_B0_DLL_ARPI1 0x0084 |
| 32 | #define DDRPHY_B0_DLL_ARPI2 0x0088 |
| 33 | #define DDRPHY_B0_DLL_ARPI3 0x008c |
| 34 | #define DDRPHY_B0_DLL_ARPI4 0x0090 |
| 35 | #define DDRPHY_B0_DLL_ARPI5 0x0094 |
| 36 | #define DDRPHY_B0_DQ2 0x00a0 |
| 37 | #define DDRPHY_B0_DQ3 0x00a4 |
| 38 | #define DDRPHY_B0_DQ4 0x00a8 |
| 39 | #define DDRPHY_B0_DQ5 0x00ac |
| 40 | #define DDRPHY_B0_DQ6 0x00b0 |
| 41 | #define DDRPHY_B0_DQ7 0x00b4 |
| 42 | #define DDRPHY_B0_DQ8 0x00b8 |
| 43 | #define DDRPHY_B1_DLL_ARPI0 0x0100 |
| 44 | #define DDRPHY_B1_DLL_ARPI1 0x0104 |
| 45 | #define DDRPHY_B1_DLL_ARPI2 0x0108 |
| 46 | #define DDRPHY_B1_DLL_ARPI3 0x010c |
| 47 | #define DDRPHY_B1_DLL_ARPI4 0x0110 |
| 48 | #define DDRPHY_B1_DLL_ARPI5 0x0114 |
| 49 | #define DDRPHY_B1_DQ2 0x0120 |
| 50 | #define DDRPHY_B1_DQ3 0x0124 |
| 51 | #define DDRPHY_B1_DQ4 0x0128 |
| 52 | #define DDRPHY_B1_DQ5 0x012c |
| 53 | #define DDRPHY_B1_DQ6 0x0130 |
| 54 | #define DDRPHY_B1_DQ7 0x0134 |
| 55 | #define DDRPHY_B1_DQ8 0x0138 |
| 56 | #define DDRPHY_CA_DLL_ARPI0 0x0180 |
| 57 | #define DDRPHY_CA_DLL_ARPI1 0x0184 |
| 58 | #define DDRPHY_CA_DLL_ARPI2 0x0188 |
| 59 | #define DDRPHY_CA_DLL_ARPI3 0x018c |
| 60 | #define DDRPHY_CA_DLL_ARPI4 0x0190 |
| 61 | #define DDRPHY_CA_DLL_ARPI5 0x0194 |
| 62 | #define DDRPHY_CA_CMD2 0x01a0 |
| 63 | #define DDRPHY_CA_CMD3 0x01a4 |
| 64 | #define DDRPHY_CA_CMD5 0x01ac |
| 65 | #define DDRPHY_CA_CMD6 0x01b0 |
| 66 | #define DDRPHY_CA_CMD7 0x01b4 |
| 67 | #define DDRPHY_CA_CMD8 0x01b8 |
| 68 | #define DDRPHY_MISC_VREF_CTRL 0x0264 |
| 69 | #define DDRPHY_MISC_IMP_CTRL0 0x0268 |
| 70 | #define DDRPHY_MISC_IMP_CTRL1 0x026c |
| 71 | #define DDRPHY_MISC_SHU_OPT 0x0270 |
| 72 | #define DDRPHY_MISC_SPM_CTRL0 0x0274 |
| 73 | #define DDRPHY_MISC_SPM_CTRL1 0x0278 |
| 74 | #define DDRPHY_MISC_SPM_CTRL2 0x027c |
| 75 | #define DDRPHY_MISC_CG_CTRL0 0x0284 |
| 76 | #define DDRPHY_MISC_CG_CTRL1 0x0288 |
| 77 | #define DDRPHY_MISC_CG_CTRL2 0x028c |
| 78 | #define DDRPHY_MISC_CG_CTRL4 0x0294 |
| 79 | #define DDRPHY_MISC_CTRL0 0x029c |
| 80 | #define DDRPHY_MISC_CTRL1 0x02a0 |
| 81 | #define DDRPHY_MISC_CTRL3 0x02a8 |
| 82 | #define DDRPHY_MISC_RXDVS1 0x05e4 |
| 83 | #define DDRPHY_SHU1_B0_DQ4 0x0c10 |
| 84 | #define DDRPHY_SHU1_B0_DQ5 0x0c14 |
| 85 | #define DDRPHY_SHU1_B0_DQ6 0x0c18 |
| 86 | #define DDRPHY_SHU1_B0_DQ7 0x0c1c |
| 87 | #define DDRPHY_SHU1_B1_DQ4 0x0c90 |
| 88 | #define DDRPHY_SHU1_B1_DQ5 0x0c94 |
| 89 | #define DDRPHY_SHU1_B1_DQ6 0x0c98 |
| 90 | #define DDRPHY_SHU1_B1_DQ7 0x0c9c |
| 91 | #define DDRPHY_SHU1_CA_CMD2 0x0d08 |
| 92 | #define DDRPHY_SHU1_CA_CMD4 0x0d10 |
| 93 | #define DDRPHY_SHU1_CA_CMD5 0x0d14 |
| 94 | #define DDRPHY_SHU1_CA_CMD6 0x0d18 |
| 95 | #define DDRPHY_SHU1_CA_CMD7 0x0d1c |
| 96 | #define DDRPHY_SHU1_PLL0 0x0d80 |
| 97 | #define DDRPHY_SHU1_PLL1 0x0d84 |
| 98 | #define DDRPHY_SHU1_PLL4 0x0d90 |
| 99 | #define DDRPHY_SHU1_PLL5 0x0d94 |
| 100 | #define DDRPHY_SHU1_PLL6 0x0d98 |
| 101 | #define DDRPHY_SHU1_PLL7 0x0d9C |
| 102 | #define DDRPHY_SHU1_PLL8 0x0da0 |
| 103 | #define DDRPHY_SHU1_PLL9 0x0da4 |
| 104 | #define DDRPHY_SHU1_PLL10 0x0da8 |
| 105 | #define DDRPHY_SHU1_PLL11 0x0dac |
| 106 | #define DDRPHY_SHU1_R0_B0_DQ2 0x0e08 |
| 107 | #define DDRPHY_SHU1_R0_B0_DQ3 0x0e0c |
| 108 | #define DDRPHY_SHU1_R0_B0_DQ4 0x0e10 |
| 109 | #define DDRPHY_SHU1_R0_B0_DQ5 0x0e14 |
| 110 | #define DDRPHY_SHU1_R0_B0_DQ6 0x0e18 |
| 111 | #define DDRPHY_SHU1_R0_B0_DQ7 0x0e1c |
| 112 | #define DDRPHY_SHU1_R0_B1_DQ2 0x0e58 |
| 113 | #define DDRPHY_SHU1_R0_B1_DQ3 0x0e5c |
| 114 | #define DDRPHY_SHU1_R0_B1_DQ4 0x0e60 |
| 115 | #define DDRPHY_SHU1_R0_B1_DQ5 0x0e64 |
| 116 | #define DDRPHY_SHU1_R0_B1_DQ6 0x0e68 |
| 117 | #define DDRPHY_SHU1_R0_B1_DQ7 0x0e6c |
| 118 | #define DDRPHY_SHU1_R0_CA_CMD9 0x0ec4 |
| 119 | #define DDRPHY_SHU1_R1_B0_DQ2 0x0f08 |
| 120 | #define DDRPHY_SHU1_R1_B0_DQ3 0x0f0c |
| 121 | #define DDRPHY_SHU1_R1_B0_DQ4 0x0f10 |
| 122 | #define DDRPHY_SHU1_R1_B0_DQ5 0x0f14 |
| 123 | #define DDRPHY_SHU1_R1_B0_DQ6 0x0f18 |
| 124 | #define DDRPHY_SHU1_R1_B0_DQ7 0x0f1c |
| 125 | #define DDRPHY_SHU1_R1_B1_DQ2 0x0f58 |
| 126 | #define DDRPHY_SHU1_R1_B1_DQ3 0x0f5c |
| 127 | #define DDRPHY_SHU1_R1_B1_DQ4 0x0f60 |
| 128 | #define DDRPHY_SHU1_R1_B1_DQ5 0x0f64 |
| 129 | #define DDRPHY_SHU1_R1_B1_DQ6 0x0f68 |
| 130 | #define DDRPHY_SHU1_R1_B1_DQ7 0x0f6c |
| 131 | #define DDRPHY_SHU1_R1_CA_CMD9 0x0fc4 |
| 132 | |
| 133 | /* DRAMC */ |
| 134 | #define DRAMC_DDRCONF0 0x0000 |
| 135 | #define DRAMC_DRAMCTRL 0x0004 |
| 136 | #define DRAMC_MISCTL0 0x0008 |
| 137 | #define DRAMC_PERFCTL0 0x000c |
| 138 | #define DRAMC_ARBCTL 0x0010 |
| 139 | #define DRAMC_RSTMASK 0x001c |
| 140 | #define DRAMC_PADCTRL 0x0020 |
| 141 | #define DRAMC_CKECTRL 0x0024 |
| 142 | #define DRAMC_RKCFG 0x0034 |
| 143 | #define DRAMC_DRAMC_PD_CTRL 0x0038 |
| 144 | #define DRAMC_CLKAR 0x003c |
| 145 | #define DRAMC_CLKCTRL 0x0040 |
| 146 | #define DRAMC_SREFCTRL 0x0048 |
| 147 | #define DRAMC_REFCTRL0 0x004c |
| 148 | #define DRAMC_REFCTRL1 0x0050 |
| 149 | #define DRAMC_REFRATRE_FILTER 0x0054 |
| 150 | #define DRAMC_ZQCS 0x0058 |
| 151 | #define DRAMC_MRS 0x005c |
| 152 | #define DRAMC_SPCMD 0x0060 |
| 153 | #define DRAMC_SPCMDCTRL 0x0064 |
| 154 | #define DRAMC_HW_MRR_FUN 0x0074 |
| 155 | #define DRAMC_TEST2_1 0x0094 |
| 156 | #define DRAMC_TEST2_2 0x0098 |
| 157 | #define DRAMC_TEST2_3 0x009c |
| 158 | #define DRAMC_TEST2_4 0x00a0 |
| 159 | #define DRAMC_CATRAINING1 0x00b0 |
| 160 | #define DRAMC_DUMMY_RD 0x00d0 |
| 161 | #define DRAMC_SHUCTRL 0x00d4 |
| 162 | #define DRAMC_SHUCTRL2 0x00dc |
| 163 | #define DRAMC_STBCAL 0x0200 |
| 164 | #define DRAMC_STBCAL1 0x0204 |
| 165 | #define DRAMC_EYESCAN 0x020c |
| 166 | #define DRAMC_DVFSDLL 0x0210 |
| 167 | #define DRAMC_SHU_ACTIM0 0x0800 |
| 168 | #define DRAMC_SHU_ACTIM1 0x0804 |
| 169 | #define DRAMC_SHU_ACTIM2 0x0808 |
| 170 | #define DRAMC_SHU_ACTIM3 0x080c |
| 171 | #define DRAMC_SHU_ACTIM4 0x0810 |
| 172 | #define DRAMC_SHU_ACTIM5 0x0814 |
| 173 | #define DRAMC_SHU_ACTIM_XRT 0x081c |
| 174 | #define DRAMC_SHU_AC_TIME_05T 0x0820 |
| 175 | #define DRAMC_SHU_CONF0 0x0840 |
| 176 | #define DRAMC_SHU_CONF1 0x0844 |
| 177 | #define DRAMC_SHU_CONF2 0x0848 |
| 178 | #define DRAMC_SHU_CONF3 0x084c |
| 179 | #define DRAMC_SHU_RANKCTL 0x0858 |
| 180 | #define DRAMC_SHU_CKECTRL 0x085c |
| 181 | #define DRAMC_SHU_ODTCTRL 0x0860 |
| 182 | #define DRAMC_SHU_PIPE 0x0878 |
| 183 | #define DRAMC_SHU_SELPH_CA1 0x0880 |
| 184 | #define DRAMC_SHU_SELPH_CA2 0x0884 |
| 185 | #define DRAMC_SHU_SELPH_CA3 0x0888 |
| 186 | #define DRAMC_SHU_SELPH_CA4 0x088c |
| 187 | #define DRAMC_SHU_SELPH_CA5 0x0890 |
| 188 | #define DRAMC_SHU_SELPH_CA6 0x0894 |
| 189 | #define DRAMC_SHU_SELPH_CA7 0x0898 |
| 190 | #define DRAMC_SHU_SELPH_CA8 0x089c |
| 191 | #define DRAMC_SHU_SELPH_DQS0 0x08a0 |
| 192 | #define DRAMC_SHU_SELPH_DQS1 0x08a4 |
| 193 | #define DRAMC_SHU1_DRVING1 0x08a8 |
| 194 | #define DRAMC_SHU1_DRVING2 0x08ac |
| 195 | #define DRAMC_SHU1_WODT 0x08c0 |
| 196 | #define DRAMC_SHU_SCINTV 0x08c8 |
| 197 | #define DRAMC_SHURK0_DQSCTL 0x0a00 |
| 198 | #define DRAMC_SHURK0_DQSIEN 0x0a04 |
| 199 | #define DRAMC_SHURK0_SELPH_ODTEN0 0x0a1c |
| 200 | #define DRAMC_SHURK0_SELPH_ODTEN1 0x0a20 |
| 201 | #define DRAMC_SHURK0_SELPH_DQSG0 0x0a24 |
| 202 | #define DRAMC_SHURK0_SELPH_DQSG1 0x0a28 |
| 203 | #define DRAMC_SHURK0_SELPH_DQ0 0x0a2c |
| 204 | #define DRAMC_SHURK0_SELPH_DQ1 0x0a30 |
| 205 | #define DRAMC_SHURK0_SELPH_DQ2 0x0a34 |
| 206 | #define DRAMC_SHURK0_SELPH_DQ3 0x0a38 |
| 207 | #define DRAMC_SHURK1_DQSCTL 0x0b00 |
| 208 | #define DRAMC_SHURK1_SELPH_ODTEN0 0x0b1c |
| 209 | #define DRAMC_SHURK1_SELPH_ODTEN1 0x0b20 |
| 210 | #define DRAMC_SHURK1_SELPH_DQSG0 0x0b24 |
| 211 | #define DRAMC_SHURK1_SELPH_DQSG1 0x0b28 |
| 212 | #define DRAMC_SHURK1_SELPH_DQ0 0x0b2c |
| 213 | #define DRAMC_SHURK1_SELPH_DQ1 0x0b30 |
| 214 | #define DRAMC_SHURK1_SELPH_DQ2 0x0b34 |
| 215 | #define DRAMC_SHURK1_SELPH_DQ3 0x0b38 |
| 216 | #define DRAMC_SHURK2_SELPH_ODTEN0 0x0c1c |
| 217 | #define DRAMC_SHURK2_SELPH_ODTEN1 0x0c20 |
| 218 | #define DRAMC_SHU_DQSG_RETRY 0x0c54 |
| 219 | |
| 220 | #define EMI_COL_ADDR_MASK GENMASK(13, 12) |
| 221 | #define EMI_COL_ADDR_SHIFT 12 |
| 222 | #define WALKING_PATTERN 0x12345678 |
| 223 | #define WALKING_STEP 0x4000000 |
| 224 | |
| 225 | struct mtk_ddr3_priv { |
| 226 | fdt_addr_t emi; |
| 227 | fdt_addr_t ddrphy; |
| 228 | fdt_addr_t dramc_ao; |
| 229 | struct clk phy; |
| 230 | struct clk phy_mux; |
| 231 | struct clk mem; |
| 232 | struct clk mem_mux; |
| 233 | }; |
| 234 | |
| 235 | #ifdef CONFIG_SPL_BUILD |
| 236 | static int mtk_ddr3_rank_size_detect(struct udevice *dev) |
| 237 | { |
| 238 | struct mtk_ddr3_priv *priv = dev_get_priv(dev); |
| 239 | int step; |
| 240 | u32 start, test; |
| 241 | |
| 242 | /* To detect size, we have to make sure it's single rank |
| 243 | * and it has maximum addressing region |
| 244 | */ |
| 245 | |
| 246 | writel(WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE); |
| 247 | |
| 248 | if (readl(CONFIG_SYS_SDRAM_BASE) != WALKING_PATTERN) |
| 249 | return -EINVAL; |
| 250 | |
| 251 | for (step = 0; step < 5; step++) { |
| 252 | writel(~WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE + |
| 253 | (WALKING_STEP << step)); |
| 254 | |
| 255 | start = readl(CONFIG_SYS_SDRAM_BASE); |
| 256 | test = readl(CONFIG_SYS_SDRAM_BASE + (WALKING_STEP << step)); |
| 257 | if ((test != ~WALKING_PATTERN) || test == start) |
| 258 | break; |
| 259 | } |
| 260 | |
| 261 | step = step ? step - 1 : 3; |
| 262 | clrsetbits_le32(priv->emi + EMI_CONA, EMI_COL_ADDR_MASK, |
| 263 | step << EMI_COL_ADDR_SHIFT); |
| 264 | |
| 265 | return 0; |
| 266 | } |
| 267 | |
| 268 | static int mtk_ddr3_init(struct udevice *dev) |
| 269 | { |
| 270 | struct mtk_ddr3_priv *priv = dev_get_priv(dev); |
| 271 | int ret; |
| 272 | |
| 273 | ret = clk_set_parent(&priv->phy, &priv->phy_mux); |
| 274 | if (ret) |
| 275 | return ret; |
| 276 | |
| 277 | /* EMI Setting */ |
| 278 | writel(0x00003010, priv->emi + EMI_CONA); |
| 279 | writel(0x00000000, priv->emi + EMI_CONF); |
| 280 | writel(0x000006b8, priv->emi + EMI_CONM); |
| 281 | /* DQS */ |
| 282 | writel(0x20c00, priv->dramc_ao + DRAMC_SHU1_DRVING1); |
| 283 | /* Clock */ |
| 284 | writel(0x8320c83, priv->dramc_ao + DRAMC_SHU1_DRVING2); |
| 285 | |
| 286 | /* DDRPHY setting */ |
| 287 | writel(0x2201, priv->dramc_ao + DRAMC_DRAMCTRL); |
| 288 | writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL); |
| 289 | writel(0xe08, priv->ddrphy + DDRPHY_CA_CMD5); |
| 290 | writel(0x60e, priv->ddrphy + DDRPHY_SHU1_CA_CMD5); |
| 291 | writel(0x0, priv->ddrphy + DDRPHY_MISC_SPM_CTRL1); |
| 292 | writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL0); |
| 293 | writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL2); |
| 294 | writel(0x6003bf, priv->ddrphy + DDRPHY_MISC_CG_CTRL2); |
| 295 | writel(0x13300000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4); |
| 296 | |
| 297 | writel(0x1, priv->ddrphy + DDRPHY_SHU1_CA_CMD7); |
| 298 | writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7); |
| 299 | writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7); |
| 300 | writel(0xfff0, priv->ddrphy + DDRPHY_CA_CMD2); |
| 301 | writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2); |
| 302 | writel(0x0, priv->ddrphy + DDRPHY_B1_DQ2); |
| 303 | writel(0x7, priv->ddrphy + DDRPHY_MISC_RXDVS1); |
| 304 | writel(0x10, priv->ddrphy + DDRPHY_PLL3); |
| 305 | writel(0x8e8e0000, priv->ddrphy + DDRPHY_MISC_VREF_CTRL); |
| 306 | writel(0x2e0040, priv->ddrphy + DDRPHY_MISC_IMP_CTRL0); |
| 307 | writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5); |
| 308 | writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5); |
| 309 | udelay(1); |
| 310 | |
| 311 | writel(0x10, priv->ddrphy + DDRPHY_B0_DQ3); |
| 312 | writel(0x10, priv->ddrphy + DDRPHY_B1_DQ3); |
| 313 | writel(0x3f600, priv->ddrphy + DDRPHY_MISC_CG_CTRL1); |
| 314 | writel(0x1010, priv->ddrphy + DDRPHY_B0_DQ4); |
| 315 | writel(0x1110e0e, priv->ddrphy + DDRPHY_B0_DQ5); |
| 316 | writel(0x10c10d0, priv->ddrphy + DDRPHY_B0_DQ6); |
| 317 | writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5); |
| 318 | writel(0x1010, priv->ddrphy + DDRPHY_B1_DQ4); |
| 319 | writel(0x1110e0e, priv->ddrphy + DDRPHY_B1_DQ5); |
| 320 | writel(0x10c10d0, priv->ddrphy + DDRPHY_B1_DQ6); |
| 321 | writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5); |
| 322 | writel(0x7fffffc, priv->ddrphy + DDRPHY_CA_CMD3); |
| 323 | writel(0xc0010, priv->ddrphy + DDRPHY_CA_CMD6); |
| 324 | writel(0x101, priv->ddrphy + DDRPHY_SHU1_CA_CMD2); |
| 325 | writel(0x41e, priv->ddrphy + DDRPHY_B0_DQ3); |
| 326 | writel(0x41e, priv->ddrphy + DDRPHY_B1_DQ3); |
| 327 | writel(0x180101, priv->ddrphy + DDRPHY_CA_CMD8); |
| 328 | writel(0x0, priv->ddrphy + DDRPHY_MISC_IMP_CTRL1); |
| 329 | writel(0x11400000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4); |
| 330 | writel(0xfff0f0f0, priv->ddrphy + DDRPHY_MISC_SHU_OPT); |
| 331 | writel(0x1f, priv->ddrphy + DDRPHY_MISC_CG_CTRL0); |
| 332 | |
| 333 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD6); |
| 334 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ6); |
| 335 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ6); |
| 336 | writel(0x40000, priv->ddrphy + DDRPHY_PLL4); |
| 337 | writel(0x0, priv->ddrphy + DDRPHY_PLL1); |
| 338 | writel(0x0, priv->ddrphy + DDRPHY_PLL2); |
| 339 | writel(0x666008, priv->ddrphy + DDRPHY_CA_DLL_ARPI5); |
| 340 | writel(0x80666008, priv->ddrphy + DDRPHY_B0_DLL_ARPI5); |
| 341 | writel(0x80666008, priv->ddrphy + DDRPHY_B1_DLL_ARPI5); |
| 342 | writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI0); |
| 343 | writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI0); |
| 344 | writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI0); |
| 345 | writel(0x400, priv->ddrphy + DDRPHY_CA_DLL_ARPI2); |
| 346 | writel(0x20400, priv->ddrphy + DDRPHY_B0_DLL_ARPI2); |
| 347 | writel(0x20400, priv->ddrphy + DDRPHY_B1_DLL_ARPI2); |
| 348 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL9); |
| 349 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL11); |
| 350 | writel(0xf7f, priv->ddrphy + DDRPHY_SHU1_PLL0); |
| 351 | writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL8); |
| 352 | writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL10); |
| 353 | writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL4); |
| 354 | writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL6); |
| 355 | |
| 356 | writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL5); |
| 357 | writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL7); |
| 358 | |
| 359 | writel(0x14d0002, priv->ddrphy + DDRPHY_PLL5); |
| 360 | writel(0x14d0002, priv->ddrphy + DDRPHY_PLL7); |
| 361 | writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL8); |
| 362 | writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL10); |
| 363 | writel(0xf, priv->ddrphy + DDRPHY_SHU1_PLL1); |
| 364 | writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0); |
| 365 | writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0); |
| 366 | writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0); |
| 367 | writel(0x698600, priv->ddrphy + DDRPHY_CA_DLL_ARPI5); |
| 368 | writel(0xc0778600, priv->ddrphy + DDRPHY_B0_DLL_ARPI5); |
| 369 | writel(0xc0778600, priv->ddrphy + DDRPHY_B1_DLL_ARPI5); |
| 370 | writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI4); |
| 371 | writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI4); |
| 372 | writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI4); |
| 373 | writel(0x2ba800, priv->ddrphy + DDRPHY_CA_DLL_ARPI1); |
| 374 | writel(0x2ae806, priv->ddrphy + DDRPHY_B0_DLL_ARPI1); |
| 375 | writel(0xae806, priv->ddrphy + DDRPHY_B1_DLL_ARPI1); |
| 376 | writel(0xba000, priv->ddrphy + DDRPHY_CA_DLL_ARPI3); |
| 377 | writel(0x2e800, priv->ddrphy + DDRPHY_B0_DLL_ARPI3); |
| 378 | writel(0x2e800, priv->ddrphy + DDRPHY_B1_DLL_ARPI3); |
| 379 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD4); |
| 380 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ4); |
| 381 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ4); |
| 382 | writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0); |
| 383 | writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0); |
| 384 | writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0); |
| 385 | writel(0x32cf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6); |
| 386 | writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6); |
| 387 | writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6); |
| 388 | writel(0x80010000, priv->ddrphy + DDRPHY_PLL1); |
| 389 | writel(0x80000000, priv->ddrphy + DDRPHY_PLL2); |
| 390 | udelay(100); |
| 391 | |
| 392 | writel(0xc, priv->ddrphy + DDRPHY_CA_DLL_ARPI0); |
| 393 | writel(0x9, priv->ddrphy + DDRPHY_B0_DLL_ARPI0); |
| 394 | writel(0x9, priv->ddrphy + DDRPHY_B1_DLL_ARPI0); |
| 395 | writel(0xd0000, priv->ddrphy + DDRPHY_PLL4); |
| 396 | udelay(1); |
| 397 | |
| 398 | writel(0x82, priv->ddrphy + DDRPHY_MISC_CTRL1); |
| 399 | writel(0x2, priv->dramc_ao + DRAMC_DDRCONF0); |
| 400 | writel(0x3acf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6); |
| 401 | writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6); |
| 402 | writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6); |
| 403 | udelay(1); |
| 404 | |
| 405 | writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI2); |
| 406 | writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI2); |
| 407 | writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI2); |
| 408 | writel(0x80, priv->ddrphy + DDRPHY_MISC_CTRL1); |
| 409 | writel(0x0, priv->dramc_ao + DRAMC_DDRCONF0); |
| 410 | writel(0x80000000, priv->ddrphy + DDRPHY_PLL1); |
| 411 | udelay(1); |
| 412 | |
| 413 | writel(0x698e00, priv->ddrphy + DDRPHY_CA_DLL_ARPI5); |
| 414 | udelay(1); |
| 415 | |
| 416 | writel(0xc0778e00, priv->ddrphy + DDRPHY_B0_DLL_ARPI5); |
| 417 | udelay(1); |
| 418 | |
| 419 | writel(0xc0778e00, priv->ddrphy + DDRPHY_B1_DLL_ARPI5); |
| 420 | udelay(1); |
| 421 | |
| 422 | ret = clk_set_parent(&priv->mem, &priv->mem_mux); |
| 423 | if (ret) |
| 424 | return ret; |
| 425 | |
| 426 | /* DDR PHY PLL setting */ |
| 427 | writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3); |
| 428 | writel(0x51e, priv->ddrphy + DDRPHY_B1_DQ3); |
| 429 | writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1); |
| 430 | writel(0x80101, priv->ddrphy + DDRPHY_CA_CMD8); |
| 431 | writel(0x100, priv->ddrphy + DDRPHY_CA_CMD7); |
| 432 | writel(0x0, priv->ddrphy + DDRPHY_CA_CMD7); |
| 433 | writel(0x0, priv->ddrphy + DDRPHY_B0_DQ7); |
| 434 | writel(0x0, priv->ddrphy + DDRPHY_B1_DQ7); |
| 435 | writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3); |
| 436 | writel(0xff051e, priv->ddrphy + DDRPHY_B1_DQ3); |
| 437 | writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2); |
| 438 | writel(0x1ff, priv->ddrphy + DDRPHY_B1_DQ2); |
| 439 | |
| 440 | /* Update initial setting */ |
| 441 | writel(0x5fc, priv->ddrphy + DDRPHY_B0_DQ3); |
| 442 | writel(0xff05fc, priv->ddrphy + DDRPHY_B1_DQ3); |
| 443 | writel(0x10c12d9, priv->ddrphy + DDRPHY_B0_DQ6); |
| 444 | writel(0x10c12d9, priv->ddrphy + DDRPHY_B1_DQ6); |
| 445 | writel(0xc0259, priv->ddrphy + DDRPHY_CA_CMD6); |
| 446 | writel(0x4000, priv->ddrphy + DDRPHY_B0_DQ2); |
| 447 | writel(0x41ff, priv->ddrphy + DDRPHY_B1_DQ2); |
| 448 | writel(0x0, priv->ddrphy + DDRPHY_B0_DQ8); |
| 449 | writel(0x100, priv->ddrphy + DDRPHY_B1_DQ8); |
| 450 | writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5); |
| 451 | writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5); |
| 452 | writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5); |
| 453 | writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5); |
| 454 | writel(0x39eff6, priv->dramc_ao + DRAMC_SHU_SCINTV); |
| 455 | writel(0x204ffff, priv->dramc_ao + DRAMC_CLKAR); |
| 456 | writel(0x31b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| 457 | writel(0x0, priv->dramc_ao + DRAMC_PERFCTL0); |
| 458 | writel(0x80000, priv->dramc_ao + DRAMC_PERFCTL0); |
| 459 | |
| 460 | /* Dramc setting PC3 */ |
| 461 | writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| 462 | |
| 463 | writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3); |
| 464 | writel(0x200600, priv->dramc_ao + DRAMC_SHU_DQSG_RETRY); |
| 465 | writel(0x101d007, priv->dramc_ao + DRAMC_SHUCTRL2); |
| 466 | writel(0xe090601, priv->dramc_ao + DRAMC_DVFSDLL); |
| 467 | writel(0x20003000, priv->dramc_ao + DRAMC_DDRCONF0); |
| 468 | writel(0x3900020f, priv->ddrphy + DDRPHY_MISC_CTRL0); |
| 469 | writel(0xa20810bf, priv->dramc_ao + DRAMC_SHU_CONF0); |
| 470 | writel(0x30050, priv->dramc_ao + DRAMC_SHU_ODTCTRL); |
| 471 | writel(0x25712000, priv->dramc_ao + DRAMC_REFCTRL0); |
| 472 | writel(0xb0100000, priv->dramc_ao + DRAMC_STBCAL); |
| 473 | writel(0x8000000, priv->dramc_ao + DRAMC_SREFCTRL); |
| 474 | writel(0xc0000000, priv->dramc_ao + DRAMC_SHU_PIPE); |
| 475 | writel(0x731004, priv->dramc_ao + DRAMC_RKCFG); |
| 476 | writel(0x8007320f, priv->dramc_ao + DRAMC_SHU_CONF2); |
| 477 | writel(0x2a7c0, priv->dramc_ao + DRAMC_SHU_SCINTV); |
| 478 | writel(0xc110, priv->dramc_ao + DRAMC_SHUCTRL); |
| 479 | writel(0x30000700, priv->dramc_ao + DRAMC_REFCTRL1); |
| 480 | writel(0x6543b321, priv->dramc_ao + DRAMC_REFRATRE_FILTER); |
| 481 | |
| 482 | /* Update PCDDR3 default setting */ |
| 483 | writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA1); |
| 484 | writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA2); |
| 485 | writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA3); |
| 486 | writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA4); |
| 487 | writel(0x10000111, priv->dramc_ao + DRAMC_SHU_SELPH_CA5); |
| 488 | writel(0x1000000, priv->dramc_ao + DRAMC_SHU_SELPH_CA6); |
| 489 | writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA7); |
| 490 | writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA8); |
| 491 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_CA_CMD9); |
| 492 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_CA_CMD9); |
| 493 | writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0); |
| 494 | writel(0x33331111, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1); |
| 495 | writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0); |
| 496 | writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1); |
| 497 | writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2); |
| 498 | writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3); |
| 499 | writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ0); |
| 500 | writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ1); |
| 501 | writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ2); |
| 502 | writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ3); |
| 503 | writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7); |
| 504 | writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ7); |
| 505 | writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7); |
| 506 | writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ7); |
| 507 | writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN0); |
| 508 | writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN1); |
| 509 | writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN0); |
| 510 | writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN1); |
| 511 | writel(0x0, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN0); |
| 512 | writel(0x66666666, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN1); |
| 513 | writel(0x2c000b0f, priv->dramc_ao + DRAMC_SHU_CONF1); |
| 514 | writel(0x11111111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0); |
| 515 | writel(0x64646464, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1); |
| 516 | writel(0x11111111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG0); |
| 517 | writel(0x64646464, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG1); |
| 518 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2); |
| 519 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3); |
| 520 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4); |
| 521 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5); |
| 522 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ6); |
| 523 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ2); |
| 524 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ3); |
| 525 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ4); |
| 526 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ5); |
| 527 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ6); |
| 528 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2); |
| 529 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3); |
| 530 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4); |
| 531 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5); |
| 532 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ6); |
| 533 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ2); |
| 534 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ3); |
| 535 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ4); |
| 536 | writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ5); |
| 537 | writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ6); |
| 538 | writel(0x20000001, priv->dramc_ao + DRAMC_SHU_RANKCTL); |
| 539 | writel(0x2, priv->dramc_ao + DRAMC_SHURK0_DQSCTL); |
| 540 | writel(0x2, priv->dramc_ao + DRAMC_SHURK1_DQSCTL); |
| 541 | writel(0x4020b07, priv->dramc_ao + DRAMC_SHU_ACTIM0); |
| 542 | writel(0xb060400, priv->dramc_ao + DRAMC_SHU_ACTIM1); |
| 543 | writel(0x8090200, priv->dramc_ao + DRAMC_SHU_ACTIM2); |
| 544 | writel(0x810018, priv->dramc_ao + DRAMC_SHU_ACTIM3); |
| 545 | writel(0x1e9700ff, priv->dramc_ao + DRAMC_SHU_ACTIM4); |
| 546 | writel(0x1000908, priv->dramc_ao + DRAMC_SHU_ACTIM5); |
| 547 | writel(0x801040b, priv->dramc_ao + DRAMC_SHU_ACTIM_XRT); |
| 548 | writel(0x20000D1, priv->dramc_ao + DRAMC_SHU_AC_TIME_05T); |
| 549 | writel(0x80010000, priv->ddrphy + DDRPHY_PLL2); |
| 550 | udelay(500); |
| 551 | |
| 552 | writel(0x81080000, priv->dramc_ao + DRAMC_MISCTL0); |
| 553 | writel(0xacf13, priv->dramc_ao + DRAMC_PERFCTL0); |
| 554 | writel(0xacf12, priv->dramc_ao + DRAMC_PERFCTL0); |
| 555 | writel(0x80, priv->dramc_ao + DRAMC_ARBCTL); |
| 556 | writel(0x9, priv->dramc_ao + DRAMC_PADCTRL); |
| 557 | writel(0x80000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL); |
| 558 | writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL); |
| 559 | writel(0x25714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| 560 | writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| 561 | writel(0x4300000, priv->dramc_ao + DRAMC_CATRAINING1); |
| 562 | writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| 563 | writel(0x731414, priv->dramc_ao + DRAMC_RKCFG); |
| 564 | writel(0x733414, priv->dramc_ao + DRAMC_RKCFG); |
| 565 | udelay(20); |
| 566 | |
| 567 | writel(0x80002050, priv->dramc_ao + DRAMC_CKECTRL); |
| 568 | udelay(100); |
| 569 | |
| 570 | writel(0x400000, priv->dramc_ao + DRAMC_MRS); |
| 571 | writel(0x401800, priv->dramc_ao + DRAMC_MRS); |
| 572 | writel(0x1, priv->dramc_ao + DRAMC_SPCMD); |
| 573 | writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| 574 | udelay(100); |
| 575 | |
| 576 | writel(0x601800, priv->dramc_ao + DRAMC_MRS); |
| 577 | writel(0x600000, priv->dramc_ao + DRAMC_MRS); |
| 578 | writel(0x1, priv->dramc_ao + DRAMC_SPCMD); |
| 579 | writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| 580 | udelay(100); |
| 581 | |
| 582 | writel(0x200000, priv->dramc_ao + DRAMC_MRS); |
| 583 | writel(0x200400, priv->dramc_ao + DRAMC_MRS); |
| 584 | writel(0x1, priv->dramc_ao + DRAMC_SPCMD); |
| 585 | writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| 586 | udelay(100); |
| 587 | |
| 588 | writel(0x400, priv->dramc_ao + DRAMC_MRS); |
| 589 | writel(0x1d7000, priv->dramc_ao + DRAMC_MRS); |
| 590 | writel(0x1, priv->dramc_ao + DRAMC_SPCMD); |
| 591 | writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| 592 | udelay(100); |
| 593 | |
| 594 | writel(0x702201, priv->dramc_ao + DRAMC_DRAMCTRL); |
| 595 | writel(0x10, priv->dramc_ao + DRAMC_SPCMD); |
| 596 | writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| 597 | writel(0x20, priv->dramc_ao + DRAMC_SPCMD); |
| 598 | writel(0x0, priv->dramc_ao + DRAMC_SPCMD); |
| 599 | writel(0x1, priv->dramc_ao + DRAMC_HW_MRR_FUN); |
| 600 | writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL); |
| 601 | writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL); |
| 602 | writel(0xa56, priv->dramc_ao + DRAMC_ZQCS); |
| 603 | writel(0xff0000, priv->dramc_ao + DRAMC_SHU_CONF3); |
| 604 | writel(0x15b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| 605 | writel(0x2cb00b0f, priv->dramc_ao + DRAMC_SHU_CONF1); |
| 606 | writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| 607 | writel(0x48000000, priv->dramc_ao + DRAMC_SREFCTRL); |
| 608 | writel(0xc0000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL); |
| 609 | writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN); |
| 610 | writel(0x15e00, priv->dramc_ao + DRAMC_STBCAL1); |
| 611 | writel(0x100000, priv->dramc_ao + DRAMC_TEST2_1); |
| 612 | writel(0x4000, priv->dramc_ao + DRAMC_TEST2_2); |
| 613 | writel(0x12000480, priv->dramc_ao + DRAMC_TEST2_3); |
| 614 | writel(0x301d007, priv->dramc_ao + DRAMC_SHUCTRL2); |
| 615 | writel(0x4782321, priv->dramc_ao + DRAMC_DRAMCTRL); |
| 616 | writel(0x30210000, priv->dramc_ao + DRAMC_SHU_CKECTRL); |
| 617 | writel(0x20000, priv->dramc_ao + DRAMC_DUMMY_RD); |
| 618 | writel(0x4080110d, priv->dramc_ao + DRAMC_TEST2_4); |
| 619 | writel(0x30000721, priv->dramc_ao + DRAMC_REFCTRL1); |
| 620 | writel(0x0, priv->dramc_ao + DRAMC_RSTMASK); |
| 621 | writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL); |
| 622 | writel(0x80002000, priv->dramc_ao + DRAMC_CKECTRL); |
| 623 | writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| 624 | |
| 625 | /* Apply config before calibration */ |
| 626 | writel(0x120, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL); |
| 627 | writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3); |
| 628 | writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_CG_CTRL0); |
| 629 | writel(0x2a7fe, priv->dramc_ao + DRAMC_SHU_SCINTV); |
| 630 | writel(0xff01ff, priv->dramc_ao + DRAMC_SHU_CONF3); |
| 631 | writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL); |
| 632 | writel(0xa56, priv->dramc_ao + DRAMC_ZQCS); |
| 633 | writel(0x80000000, priv->dramc_ao + DRAMC_SHU1_WODT); |
| 634 | writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7); |
| 635 | writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7); |
| 636 | writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| 637 | writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| 638 | writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL); |
| 639 | writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| 640 | writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| 641 | writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN); |
| 642 | writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1); |
| 643 | writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0); |
| 644 | writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| 645 | writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL); |
| 646 | |
| 647 | /* Write leveling */ |
| 648 | writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7); |
| 649 | writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7); |
| 650 | writel(0x33221100, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1); |
| 651 | writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0); |
| 652 | |
| 653 | /* RX dqs gating cal */ |
| 654 | writel(0x11111010, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0); |
| 655 | writel(0x20201717, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1); |
| 656 | writel(0x1d1f, priv->dramc_ao + DRAMC_SHURK0_DQSIEN); |
| 657 | |
| 658 | /* RX window per-bit cal */ |
| 659 | writel(0x03030404, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2); |
| 660 | writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3); |
| 661 | writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4); |
| 662 | writel(0x01010000, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5); |
| 663 | writel(0x03030606, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2); |
| 664 | writel(0x02020202, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3); |
| 665 | writel(0x04040303, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4); |
| 666 | writel(0x06060101, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5); |
| 667 | |
| 668 | /* RX datlat cal */ |
| 669 | writel(0x28b00a0e, priv->dramc_ao + DRAMC_SHU_CONF1); |
| 670 | |
| 671 | /* TX window per-byte with 2UI cal */ |
| 672 | writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0); |
| 673 | writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2); |
| 674 | writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1); |
| 675 | writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3); |
| 676 | writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7); |
| 677 | writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7); |
| 678 | |
| 679 | return mtk_ddr3_rank_size_detect(dev); |
| 680 | } |
| 681 | #endif |
| 682 | |
| 683 | static int mtk_ddr3_probe(struct udevice *dev) |
| 684 | { |
| 685 | struct mtk_ddr3_priv *priv = dev_get_priv(dev); |
| 686 | |
| 687 | priv->emi = dev_read_addr_index(dev, 0); |
| 688 | if (priv->emi == FDT_ADDR_T_NONE) |
| 689 | return -EINVAL; |
| 690 | |
| 691 | priv->ddrphy = dev_read_addr_index(dev, 1); |
| 692 | if (priv->ddrphy == FDT_ADDR_T_NONE) |
| 693 | return -EINVAL; |
| 694 | |
| 695 | priv->dramc_ao = dev_read_addr_index(dev, 2); |
| 696 | if (priv->dramc_ao == FDT_ADDR_T_NONE) |
| 697 | return -EINVAL; |
| 698 | |
| 699 | #ifdef CONFIG_SPL_BUILD |
| 700 | int ret; |
| 701 | |
| 702 | ret = clk_get_by_index(dev, 0, &priv->phy); |
| 703 | if (ret) |
| 704 | return ret; |
| 705 | |
| 706 | ret = clk_get_by_index(dev, 1, &priv->phy_mux); |
| 707 | if (ret) |
| 708 | return ret; |
| 709 | |
| 710 | ret = clk_get_by_index(dev, 2, &priv->mem); |
| 711 | if (ret) |
| 712 | return ret; |
| 713 | |
| 714 | ret = clk_get_by_index(dev, 3, &priv->mem_mux); |
| 715 | if (ret) |
| 716 | return ret; |
| 717 | |
| 718 | ret = mtk_ddr3_init(dev); |
| 719 | if (ret) |
| 720 | return ret; |
| 721 | #endif |
| 722 | return 0; |
| 723 | } |
| 724 | |
| 725 | static int mtk_ddr3_get_info(struct udevice *dev, struct ram_info *info) |
| 726 | { |
| 727 | struct mtk_ddr3_priv *priv = dev_get_priv(dev); |
| 728 | u32 val = readl(priv->emi + EMI_CONA); |
| 729 | |
| 730 | info->base = CONFIG_SYS_SDRAM_BASE; |
| 731 | |
| 732 | switch ((val & EMI_COL_ADDR_MASK) >> EMI_COL_ADDR_SHIFT) { |
| 733 | case 0: |
| 734 | info->size = SZ_128M; |
| 735 | break; |
| 736 | case 1: |
| 737 | info->size = SZ_256M; |
| 738 | break; |
| 739 | case 2: |
| 740 | info->size = SZ_512M; |
| 741 | break; |
| 742 | case 3: |
| 743 | info->size = SZ_1G; |
| 744 | break; |
| 745 | default: |
| 746 | return -EINVAL; |
| 747 | } |
| 748 | |
| 749 | return 0; |
| 750 | } |
| 751 | |
| 752 | static struct ram_ops mtk_ddr3_ops = { |
| 753 | .get_info = mtk_ddr3_get_info, |
| 754 | }; |
| 755 | |
| 756 | static const struct udevice_id mtk_ddr3_ids[] = { |
| 757 | { .compatible = "mediatek,mt7629-dramc" }, |
| 758 | { } |
| 759 | }; |
| 760 | |
| 761 | U_BOOT_DRIVER(mediatek_ddr3) = { |
| 762 | .name = "mediatek_ddr3", |
| 763 | .id = UCLASS_RAM, |
| 764 | .of_match = mtk_ddr3_ids, |
| 765 | .ops = &mtk_ddr3_ops, |
| 766 | .probe = mtk_ddr3_probe, |
| 767 | .priv_auto_alloc_size = sizeof(struct mtk_ddr3_priv), |
| 768 | }; |