Tony Xie | f6118cc | 2016-01-15 17:17:32 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. |
| 3 | * |
dp-arm | fa3cf0b | 2017-05-03 09:38:09 +0100 | [diff] [blame] | 4 | * SPDX-License-Identifier: BSD-3-Clause |
Tony Xie | f6118cc | 2016-01-15 17:17:32 +0800 | [diff] [blame] | 5 | */ |
| 6 | |
| 7 | #include <mmio.h> |
| 8 | #include <ddr_rk3368.h> |
| 9 | #include <debug.h> |
| 10 | #include <stdint.h> |
| 11 | #include <string.h> |
| 12 | #include <platform_def.h> |
| 13 | #include <pmu.h> |
| 14 | #include <rk3368_def.h> |
| 15 | #include <soc.h> |
| 16 | |
| 17 | /* GRF_SOC_STATUS0 */ |
| 18 | #define DPLL_LOCK (0x1 << 2) |
| 19 | |
| 20 | /* GRF_DDRC0_CON0 */ |
| 21 | #define GRF_DDR_16BIT_EN (((0x1 << 3) << 16) | (0x1 << 3)) |
| 22 | #define GRF_DDR_32BIT_EN (((0x1 << 3) << 16) | (0x0 << 3)) |
| 23 | #define GRF_MOBILE_DDR_EN (((0x1 << 4) << 16) | (0x1 << 4)) |
| 24 | #define GRF_MOBILE_DDR_DISB (((0x1 << 4) << 16) | (0x0 << 4)) |
| 25 | #define GRF_DDR3_EN (((0x1 << 2) << 16) | (0x1 << 2)) |
| 26 | #define GRF_LPDDR2_3_EN (((0x1 << 2) << 16) | (0x0 << 2)) |
| 27 | |
| 28 | /* PMUGRF_SOC_CON0 */ |
| 29 | #define ddrphy_bufferen_io_en(n) ((0x1 << (9 + 16)) | (n << 9)) |
| 30 | #define ddrphy_bufferen_core_en(n) ((0x1 << (8 + 16)) | (n << 8)) |
| 31 | |
| 32 | struct PCTRL_TIMING_TAG { |
| 33 | uint32_t ddrfreq; |
| 34 | uint32_t TOGCNT1U; |
| 35 | uint32_t TINIT; |
| 36 | uint32_t TRSTH; |
| 37 | uint32_t TOGCNT100N; |
| 38 | uint32_t TREFI; |
| 39 | uint32_t TMRD; |
| 40 | uint32_t TRFC; |
| 41 | uint32_t TRP; |
| 42 | uint32_t TRTW; |
| 43 | uint32_t TAL; |
| 44 | uint32_t TCL; |
| 45 | uint32_t TCWL; |
| 46 | uint32_t TRAS; |
| 47 | uint32_t TRC; |
| 48 | uint32_t TRCD; |
| 49 | uint32_t TRRD; |
| 50 | uint32_t TRTP; |
| 51 | uint32_t TWR; |
| 52 | uint32_t TWTR; |
| 53 | uint32_t TEXSR; |
| 54 | uint32_t TXP; |
| 55 | uint32_t TXPDLL; |
| 56 | uint32_t TZQCS; |
| 57 | uint32_t TZQCSI; |
| 58 | uint32_t TDQS; |
| 59 | uint32_t TCKSRE; |
| 60 | uint32_t TCKSRX; |
| 61 | uint32_t TCKE; |
| 62 | uint32_t TMOD; |
| 63 | uint32_t TRSTL; |
| 64 | uint32_t TZQCL; |
| 65 | uint32_t TMRR; |
| 66 | uint32_t TCKESR; |
| 67 | uint32_t TDPD; |
| 68 | uint32_t TREFI_MEM_DDR3; |
| 69 | }; |
| 70 | |
| 71 | struct MSCH_SAVE_REG_TAG { |
| 72 | uint32_t ddrconf; |
| 73 | uint32_t ddrtiming; |
| 74 | uint32_t ddrmode; |
| 75 | uint32_t readlatency; |
| 76 | uint32_t activate; |
| 77 | uint32_t devtodev; |
| 78 | }; |
| 79 | |
| 80 | /* ddr suspend need save reg */ |
| 81 | struct PCTL_SAVE_REG_TAG { |
| 82 | uint32_t SCFG; |
| 83 | uint32_t CMDTSTATEN; |
| 84 | uint32_t MCFG1; |
| 85 | uint32_t MCFG; |
| 86 | uint32_t PPCFG; |
| 87 | struct PCTRL_TIMING_TAG pctl_timing; |
| 88 | /* DFI Control Registers */ |
| 89 | uint32_t DFITCTRLDELAY; |
| 90 | uint32_t DFIODTCFG; |
| 91 | uint32_t DFIODTCFG1; |
| 92 | uint32_t DFIODTRANKMAP; |
| 93 | /* DFI Write Data Registers */ |
| 94 | uint32_t DFITPHYWRDATA; |
| 95 | uint32_t DFITPHYWRLAT; |
| 96 | uint32_t DFITPHYWRDATALAT; |
| 97 | /* DFI Read Data Registers */ |
| 98 | uint32_t DFITRDDATAEN; |
| 99 | uint32_t DFITPHYRDLAT; |
| 100 | /* DFI Update Registers */ |
| 101 | uint32_t DFITPHYUPDTYPE0; |
| 102 | uint32_t DFITPHYUPDTYPE1; |
| 103 | uint32_t DFITPHYUPDTYPE2; |
| 104 | uint32_t DFITPHYUPDTYPE3; |
| 105 | uint32_t DFITCTRLUPDMIN; |
| 106 | uint32_t DFITCTRLUPDMAX; |
| 107 | uint32_t DFITCTRLUPDDLY; |
| 108 | uint32_t DFIUPDCFG; |
| 109 | uint32_t DFITREFMSKI; |
| 110 | uint32_t DFITCTRLUPDI; |
| 111 | /* DFI Status Registers */ |
| 112 | uint32_t DFISTCFG0; |
| 113 | uint32_t DFISTCFG1; |
| 114 | uint32_t DFITDRAMCLKEN; |
| 115 | uint32_t DFITDRAMCLKDIS; |
| 116 | uint32_t DFISTCFG2; |
| 117 | /* DFI Low Power Register */ |
| 118 | uint32_t DFILPCFG0; |
| 119 | }; |
| 120 | |
| 121 | struct DDRPHY_SAVE_REG_TAG { |
| 122 | uint32_t PHY_REG0; |
| 123 | uint32_t PHY_REG1; |
| 124 | uint32_t PHY_REGB; |
| 125 | uint32_t PHY_REGC; |
| 126 | uint32_t PHY_REG11; |
| 127 | uint32_t PHY_REG13; |
| 128 | uint32_t PHY_REG14; |
| 129 | uint32_t PHY_REG16; |
| 130 | uint32_t PHY_REG20; |
| 131 | uint32_t PHY_REG21; |
| 132 | uint32_t PHY_REG26; |
| 133 | uint32_t PHY_REG27; |
| 134 | uint32_t PHY_REG28; |
| 135 | uint32_t PHY_REG30; |
| 136 | uint32_t PHY_REG31; |
| 137 | uint32_t PHY_REG36; |
| 138 | uint32_t PHY_REG37; |
| 139 | uint32_t PHY_REG38; |
| 140 | uint32_t PHY_REG40; |
| 141 | uint32_t PHY_REG41; |
| 142 | uint32_t PHY_REG46; |
| 143 | uint32_t PHY_REG47; |
| 144 | uint32_t PHY_REG48; |
| 145 | uint32_t PHY_REG50; |
| 146 | uint32_t PHY_REG51; |
| 147 | uint32_t PHY_REG56; |
| 148 | uint32_t PHY_REG57; |
| 149 | uint32_t PHY_REG58; |
| 150 | uint32_t PHY_REGDLL; |
| 151 | uint32_t PHY_REGEC; |
| 152 | uint32_t PHY_REGED; |
| 153 | uint32_t PHY_REGEE; |
| 154 | uint32_t PHY_REGEF; |
| 155 | uint32_t PHY_REGFB; |
| 156 | uint32_t PHY_REGFC; |
| 157 | uint32_t PHY_REGFD; |
| 158 | uint32_t PHY_REGFE; |
| 159 | }; |
| 160 | |
| 161 | struct BACKUP_REG_TAG { |
| 162 | uint32_t tag; |
| 163 | uint32_t pctladdr; |
| 164 | struct PCTL_SAVE_REG_TAG pctl; |
| 165 | uint32_t phyaddr; |
| 166 | struct DDRPHY_SAVE_REG_TAG phy; |
| 167 | uint32_t nocaddr; |
| 168 | struct MSCH_SAVE_REG_TAG noc; |
| 169 | uint32_t pllselect; |
| 170 | uint32_t phypllockaddr; |
| 171 | uint32_t phyplllockmask; |
| 172 | uint32_t phyplllockval; |
| 173 | uint32_t pllpdstat; |
| 174 | uint32_t dpllmodeaddr; |
| 175 | uint32_t dpllslowmode; |
| 176 | uint32_t dpllnormalmode; |
| 177 | uint32_t dpllresetaddr; |
| 178 | uint32_t dpllreset; |
| 179 | uint32_t dplldereset; |
| 180 | uint32_t dpllconaddr; |
| 181 | uint32_t dpllcon[4]; |
| 182 | uint32_t dplllockaddr; |
| 183 | uint32_t dplllockmask; |
| 184 | uint32_t dplllockval; |
| 185 | uint32_t ddrpllsrcdivaddr; |
| 186 | uint32_t ddrpllsrcdiv; |
| 187 | uint32_t retendisaddr; |
| 188 | uint32_t retendisval; |
| 189 | uint32_t grfregaddr; |
| 190 | uint32_t grfddrcreg; |
| 191 | uint32_t crupctlphysoftrstaddr; |
| 192 | uint32_t cruresetpctlphy; |
| 193 | uint32_t cruderesetphy; |
| 194 | uint32_t cruderesetpctlphy; |
| 195 | uint32_t physoftrstaddr; |
| 196 | uint32_t endtag; |
| 197 | }; |
| 198 | |
| 199 | static uint32_t ddr_get_phy_pll_freq(void) |
| 200 | { |
| 201 | uint32_t ret = 0; |
| 202 | uint32_t fb_div, pre_div; |
| 203 | |
| 204 | fb_div = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEC); |
| 205 | fb_div |= (mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGED) & 0x1) << 8; |
| 206 | |
| 207 | pre_div = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEE) & 0xff; |
| 208 | ret = 2 * 24 * fb_div / (4 * pre_div); |
| 209 | |
| 210 | return ret; |
| 211 | } |
| 212 | |
| 213 | static void ddr_copy(uint32_t *pdest, uint32_t *psrc, uint32_t words) |
| 214 | { |
| 215 | uint32_t i; |
| 216 | |
| 217 | for (i = 0; i < words; i++) |
| 218 | pdest[i] = psrc[i]; |
| 219 | } |
| 220 | |
| 221 | static void ddr_get_dpll_cfg(uint32_t *p) |
| 222 | { |
| 223 | uint32_t nmhz, NO, NF, NR; |
| 224 | |
| 225 | nmhz = ddr_get_phy_pll_freq(); |
| 226 | if (nmhz <= 150) |
| 227 | NO = 6; |
| 228 | else if (nmhz <= 250) |
| 229 | NO = 4; |
| 230 | else if (nmhz <= 500) |
| 231 | NO = 2; |
| 232 | else |
| 233 | NO = 1; |
| 234 | |
| 235 | NR = 1; |
| 236 | NF = 2 * nmhz * NR * NO / 24; |
| 237 | |
| 238 | p[0] = SET_NR(NR) | SET_NO(NO); |
| 239 | p[1] = SET_NF(NF); |
| 240 | p[2] = SET_NB(NF / 2); |
| 241 | } |
| 242 | |
| 243 | void ddr_reg_save(uint32_t pllpdstat, uint64_t base_addr) |
| 244 | { |
| 245 | struct BACKUP_REG_TAG *p_ddr_reg = (struct BACKUP_REG_TAG *)base_addr; |
| 246 | struct PCTL_SAVE_REG_TAG *pctl_tim = &p_ddr_reg->pctl; |
| 247 | |
| 248 | p_ddr_reg->tag = 0x56313031; |
| 249 | p_ddr_reg->pctladdr = DDR_PCTL_BASE; |
| 250 | p_ddr_reg->phyaddr = DDR_PHY_BASE; |
| 251 | p_ddr_reg->nocaddr = SERVICE_BUS_BASE; |
| 252 | |
| 253 | /* PCTLR */ |
| 254 | ddr_copy((uint32_t *)&pctl_tim->pctl_timing.TOGCNT1U, |
| 255 | (uint32_t *)(DDR_PCTL_BASE + DDR_PCTL_TOGCNT1U), 35); |
| 256 | pctl_tim->pctl_timing.TREFI |= DDR_UPD_REF_ENABLE; |
| 257 | pctl_tim->SCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_SCFG); |
| 258 | pctl_tim->CMDTSTATEN = mmio_read_32(DDR_PCTL_BASE + |
| 259 | DDR_PCTL_CMDTSTATEN); |
| 260 | pctl_tim->MCFG1 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_MCFG1); |
| 261 | pctl_tim->MCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_MCFG); |
| 262 | pctl_tim->PPCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_PPCFG); |
| 263 | pctl_tim->pctl_timing.ddrfreq = mmio_read_32(DDR_PCTL_BASE + |
| 264 | DDR_PCTL_TOGCNT1U * 2); |
| 265 | pctl_tim->DFITCTRLDELAY = mmio_read_32(DDR_PCTL_BASE + |
| 266 | DDR_PCTL_DFITCTRLDELAY); |
| 267 | pctl_tim->DFIODTCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFIODTCFG); |
| 268 | pctl_tim->DFIODTCFG1 = mmio_read_32(DDR_PCTL_BASE + |
| 269 | DDR_PCTL_DFIODTCFG1); |
| 270 | pctl_tim->DFIODTRANKMAP = mmio_read_32(DDR_PCTL_BASE + |
| 271 | DDR_PCTL_DFIODTRANKMAP); |
| 272 | pctl_tim->DFITPHYWRDATA = mmio_read_32(DDR_PCTL_BASE + |
| 273 | DDR_PCTL_DFITPHYWRDATA); |
| 274 | pctl_tim->DFITPHYWRLAT = mmio_read_32(DDR_PCTL_BASE + |
| 275 | DDR_PCTL_DFITPHYWRLAT); |
| 276 | pctl_tim->DFITPHYWRDATALAT = mmio_read_32(DDR_PCTL_BASE + |
| 277 | DDR_PCTL_DFITPHYWRDATALAT); |
| 278 | pctl_tim->DFITRDDATAEN = mmio_read_32(DDR_PCTL_BASE + |
| 279 | DDR_PCTL_DFITRDDATAEN); |
| 280 | pctl_tim->DFITPHYRDLAT = mmio_read_32(DDR_PCTL_BASE + |
| 281 | DDR_PCTL_DFITPHYRDLAT); |
| 282 | pctl_tim->DFITPHYUPDTYPE0 = mmio_read_32(DDR_PCTL_BASE + |
| 283 | DDR_PCTL_DFITPHYUPDTYPE0); |
| 284 | pctl_tim->DFITPHYUPDTYPE1 = mmio_read_32(DDR_PCTL_BASE + |
| 285 | DDR_PCTL_DFITPHYUPDTYPE1); |
| 286 | pctl_tim->DFITPHYUPDTYPE2 = mmio_read_32(DDR_PCTL_BASE + |
| 287 | DDR_PCTL_DFITPHYUPDTYPE2); |
| 288 | pctl_tim->DFITPHYUPDTYPE3 = mmio_read_32(DDR_PCTL_BASE + |
| 289 | DDR_PCTL_DFITPHYUPDTYPE3); |
| 290 | pctl_tim->DFITCTRLUPDMIN = mmio_read_32(DDR_PCTL_BASE + |
| 291 | DDR_PCTL_DFITCTRLUPDMIN); |
| 292 | pctl_tim->DFITCTRLUPDMAX = mmio_read_32(DDR_PCTL_BASE + |
| 293 | DDR_PCTL_DFITCTRLUPDMAX); |
| 294 | pctl_tim->DFITCTRLUPDDLY = mmio_read_32(DDR_PCTL_BASE + |
| 295 | DDR_PCTL_DFITCTRLUPDDLY); |
| 296 | |
| 297 | pctl_tim->DFIUPDCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFIUPDCFG); |
| 298 | pctl_tim->DFITREFMSKI = mmio_read_32(DDR_PCTL_BASE + |
| 299 | DDR_PCTL_DFITREFMSKI); |
| 300 | pctl_tim->DFITCTRLUPDI = mmio_read_32(DDR_PCTL_BASE + |
| 301 | DDR_PCTL_DFITCTRLUPDI); |
| 302 | pctl_tim->DFISTCFG0 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFISTCFG0); |
| 303 | pctl_tim->DFISTCFG1 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFISTCFG1); |
| 304 | pctl_tim->DFITDRAMCLKEN = mmio_read_32(DDR_PCTL_BASE + |
| 305 | DDR_PCTL_DFITDRAMCLKEN); |
| 306 | pctl_tim->DFITDRAMCLKDIS = mmio_read_32(DDR_PCTL_BASE + |
| 307 | DDR_PCTL_DFITDRAMCLKDIS); |
| 308 | pctl_tim->DFISTCFG2 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFISTCFG2); |
| 309 | pctl_tim->DFILPCFG0 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFILPCFG0); |
| 310 | |
| 311 | /* PHY */ |
| 312 | p_ddr_reg->phy.PHY_REG0 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG0); |
| 313 | p_ddr_reg->phy.PHY_REG1 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG1); |
| 314 | p_ddr_reg->phy.PHY_REGB = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGB); |
| 315 | p_ddr_reg->phy.PHY_REGC = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGC); |
| 316 | p_ddr_reg->phy.PHY_REG11 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG11); |
| 317 | p_ddr_reg->phy.PHY_REG13 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG13); |
| 318 | p_ddr_reg->phy.PHY_REG14 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG14); |
| 319 | p_ddr_reg->phy.PHY_REG16 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG16); |
| 320 | p_ddr_reg->phy.PHY_REG20 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG20); |
| 321 | p_ddr_reg->phy.PHY_REG21 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG21); |
| 322 | p_ddr_reg->phy.PHY_REG26 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG26); |
| 323 | p_ddr_reg->phy.PHY_REG27 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG27); |
| 324 | p_ddr_reg->phy.PHY_REG28 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG28); |
| 325 | p_ddr_reg->phy.PHY_REG30 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG30); |
| 326 | p_ddr_reg->phy.PHY_REG31 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG31); |
| 327 | p_ddr_reg->phy.PHY_REG36 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG36); |
| 328 | p_ddr_reg->phy.PHY_REG37 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG37); |
| 329 | p_ddr_reg->phy.PHY_REG38 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG38); |
| 330 | p_ddr_reg->phy.PHY_REG40 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG40); |
| 331 | p_ddr_reg->phy.PHY_REG41 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG41); |
| 332 | p_ddr_reg->phy.PHY_REG46 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG46); |
| 333 | p_ddr_reg->phy.PHY_REG47 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG47); |
| 334 | p_ddr_reg->phy.PHY_REG48 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG48); |
| 335 | p_ddr_reg->phy.PHY_REG50 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG50); |
| 336 | p_ddr_reg->phy.PHY_REG51 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG51); |
| 337 | p_ddr_reg->phy.PHY_REG56 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG56); |
| 338 | p_ddr_reg->phy.PHY_REG57 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG57); |
| 339 | p_ddr_reg->phy.PHY_REG58 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG58); |
| 340 | p_ddr_reg->phy.PHY_REGDLL = mmio_read_32(DDR_PHY_BASE + |
| 341 | DDR_PHY_REGDLL); |
| 342 | p_ddr_reg->phy.PHY_REGEC = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEC); |
| 343 | p_ddr_reg->phy.PHY_REGED = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGED); |
| 344 | p_ddr_reg->phy.PHY_REGEE = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEE); |
| 345 | p_ddr_reg->phy.PHY_REGEF = 0; |
| 346 | |
| 347 | if (mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG2) & 0x2) { |
| 348 | p_ddr_reg->phy.PHY_REGFB = mmio_read_32(DDR_PHY_BASE + |
| 349 | DDR_PHY_REG2C); |
| 350 | p_ddr_reg->phy.PHY_REGFC = mmio_read_32(DDR_PHY_BASE + |
| 351 | DDR_PHY_REG3C); |
| 352 | p_ddr_reg->phy.PHY_REGFD = mmio_read_32(DDR_PHY_BASE + |
| 353 | DDR_PHY_REG4C); |
| 354 | p_ddr_reg->phy.PHY_REGFE = mmio_read_32(DDR_PHY_BASE + |
| 355 | DDR_PHY_REG5C); |
| 356 | } else { |
| 357 | p_ddr_reg->phy.PHY_REGFB = mmio_read_32(DDR_PHY_BASE + |
| 358 | DDR_PHY_REGFB); |
| 359 | p_ddr_reg->phy.PHY_REGFC = mmio_read_32(DDR_PHY_BASE + |
| 360 | DDR_PHY_REGFC); |
| 361 | p_ddr_reg->phy.PHY_REGFD = mmio_read_32(DDR_PHY_BASE + |
| 362 | DDR_PHY_REGFD); |
| 363 | p_ddr_reg->phy.PHY_REGFE = mmio_read_32(DDR_PHY_BASE + |
| 364 | DDR_PHY_REGFE); |
| 365 | } |
| 366 | |
| 367 | /* NOC */ |
| 368 | p_ddr_reg->noc.ddrconf = mmio_read_32(SERVICE_BUS_BASE + MSCH_DDRCONF); |
| 369 | p_ddr_reg->noc.ddrtiming = mmio_read_32(SERVICE_BUS_BASE + |
| 370 | MSCH_DDRTIMING); |
| 371 | p_ddr_reg->noc.ddrmode = mmio_read_32(SERVICE_BUS_BASE + MSCH_DDRMODE); |
| 372 | p_ddr_reg->noc.readlatency = mmio_read_32(SERVICE_BUS_BASE + |
| 373 | MSCH_READLATENCY); |
| 374 | p_ddr_reg->noc.activate = mmio_read_32(SERVICE_BUS_BASE + |
| 375 | MSCH_ACTIVATE); |
| 376 | p_ddr_reg->noc.devtodev = mmio_read_32(SERVICE_BUS_BASE + |
| 377 | MSCH_DEVTODEV); |
| 378 | |
| 379 | p_ddr_reg->pllselect = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEE) * 0x1; |
| 380 | p_ddr_reg->phypllockaddr = GRF_BASE + GRF_SOC_STATUS0; |
| 381 | p_ddr_reg->phyplllockmask = GRF_DDRPHY_LOCK; |
| 382 | p_ddr_reg->phyplllockval = 0; |
| 383 | |
| 384 | /* PLLPD */ |
| 385 | p_ddr_reg->pllpdstat = pllpdstat; |
| 386 | /* DPLL */ |
| 387 | p_ddr_reg->dpllmodeaddr = CRU_BASE + PLL_CONS(DPLL_ID, 3); |
| 388 | /* slow mode and power on */ |
| 389 | p_ddr_reg->dpllslowmode = DPLL_WORK_SLOW_MODE | DPLL_POWER_DOWN; |
| 390 | p_ddr_reg->dpllnormalmode = DPLL_WORK_NORMAL_MODE; |
| 391 | p_ddr_reg->dpllresetaddr = CRU_BASE + PLL_CONS(DPLL_ID, 3); |
| 392 | p_ddr_reg->dpllreset = DPLL_RESET_CONTROL_NORMAL; |
| 393 | p_ddr_reg->dplldereset = DPLL_RESET_CONTROL_RESET; |
| 394 | p_ddr_reg->dpllconaddr = CRU_BASE + PLL_CONS(DPLL_ID, 0); |
| 395 | |
| 396 | if (p_ddr_reg->pllselect == 0) { |
| 397 | p_ddr_reg->dpllcon[0] = (mmio_read_32(CRU_BASE + |
| 398 | PLL_CONS(DPLL_ID, 0)) |
| 399 | & 0xffff) | |
| 400 | (0xFFFF << 16); |
| 401 | p_ddr_reg->dpllcon[1] = (mmio_read_32(CRU_BASE + |
| 402 | PLL_CONS(DPLL_ID, 1)) |
| 403 | & 0xffff); |
| 404 | p_ddr_reg->dpllcon[2] = (mmio_read_32(CRU_BASE + |
| 405 | PLL_CONS(DPLL_ID, 2)) |
| 406 | & 0xffff); |
| 407 | p_ddr_reg->dpllcon[3] = (mmio_read_32(CRU_BASE + |
| 408 | PLL_CONS(DPLL_ID, 3)) |
| 409 | & 0xffff) | |
| 410 | (0xFFFF << 16); |
| 411 | } else { |
| 412 | ddr_get_dpll_cfg(&p_ddr_reg->dpllcon[0]); |
| 413 | } |
| 414 | |
| 415 | p_ddr_reg->pllselect = 0; |
| 416 | p_ddr_reg->dplllockaddr = CRU_BASE + PLL_CONS(DPLL_ID, 1); |
| 417 | p_ddr_reg->dplllockmask = DPLL_STATUS_LOCK; |
| 418 | p_ddr_reg->dplllockval = DPLL_STATUS_LOCK; |
| 419 | |
| 420 | /* SET_DDR_PLL_SRC */ |
| 421 | p_ddr_reg->ddrpllsrcdivaddr = CRU_BASE + CRU_CLKSELS_CON(13); |
| 422 | p_ddr_reg->ddrpllsrcdiv = (mmio_read_32(CRU_BASE + CRU_CLKSELS_CON(13)) |
| 423 | & DDR_PLL_SRC_MASK) |
| 424 | | (DDR_PLL_SRC_MASK << 16); |
| 425 | p_ddr_reg->retendisaddr = PMU_BASE + PMU_PWRMD_COM; |
| 426 | p_ddr_reg->retendisval = PD_PERI_PWRDN_ENABLE; |
| 427 | p_ddr_reg->grfregaddr = GRF_BASE + GRF_DDRC0_CON0; |
| 428 | p_ddr_reg->grfddrcreg = (mmio_read_32(GRF_BASE + GRF_DDRC0_CON0) & |
| 429 | DDR_PLL_SRC_MASK) | |
| 430 | (DDR_PLL_SRC_MASK << 16); |
| 431 | |
| 432 | /* pctl phy soft reset */ |
| 433 | p_ddr_reg->crupctlphysoftrstaddr = CRU_BASE + CRU_SOFTRSTS_CON(10); |
| 434 | p_ddr_reg->cruresetpctlphy = DDRCTRL0_PSRSTN_REQ(1) | |
| 435 | DDRCTRL0_SRSTN_REQ(1) | |
| 436 | DDRPHY0_PSRSTN_REQ(1) | |
| 437 | DDRPHY0_SRSTN_REQ(1); |
| 438 | p_ddr_reg->cruderesetphy = DDRCTRL0_PSRSTN_REQ(1) | |
| 439 | DDRCTRL0_SRSTN_REQ(1) | |
| 440 | DDRPHY0_PSRSTN_REQ(0) | |
| 441 | DDRPHY0_SRSTN_REQ(0); |
| 442 | |
| 443 | p_ddr_reg->cruderesetpctlphy = DDRCTRL0_PSRSTN_REQ(0) | |
| 444 | DDRCTRL0_SRSTN_REQ(0) | |
| 445 | DDRPHY0_PSRSTN_REQ(0) | |
| 446 | DDRPHY0_SRSTN_REQ(0); |
| 447 | |
| 448 | p_ddr_reg->physoftrstaddr = DDR_PHY_BASE + DDR_PHY_REG0; |
| 449 | |
| 450 | p_ddr_reg->endtag = 0xFFFFFFFF; |
| 451 | } |
| 452 | |
| 453 | /* |
| 454 | * "rk3368_ddr_reg_resume_V1.05.bin" is an executable bin which is generated |
| 455 | * by ARM DS5 for resuming ddr controller. If the soc wakes up from system |
| 456 | * suspend, ddr needs to be resumed and the resuming code needs to be run in |
| 457 | * sram. But there is not a way to pointing the resuming code to the PMUSRAM |
| 458 | * when linking .o files of bl31, so we use the |
| 459 | * "rk3368_ddr_reg_resume_V1.05.bin" whose code is position-independent and |
| 460 | * it can be loaded anywhere and run. |
| 461 | */ |
| 462 | static __aligned(4) unsigned int ddr_reg_resume[] = { |
| 463 | #include "rk3368_ddr_reg_resume_V1.05.bin" |
| 464 | }; |
| 465 | |
| 466 | uint32_t ddr_get_resume_code_size(void) |
| 467 | { |
| 468 | return sizeof(ddr_reg_resume); |
| 469 | } |
| 470 | |
| 471 | uint32_t ddr_get_resume_data_size(void) |
| 472 | { |
| 473 | return sizeof(struct BACKUP_REG_TAG); |
| 474 | } |
| 475 | |
| 476 | uint32_t *ddr_get_resume_code_base(void) |
| 477 | { |
| 478 | return (unsigned int *)ddr_reg_resume; |
| 479 | } |