dram.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. /*
  2. * Copyright 2021-2024 NXP
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <stdbool.h>
  8. #include <arch_helpers.h>
  9. #include <bl31/interrupt_mgmt.h>
  10. #include <common/runtime_svc.h>
  11. #include <lib/mmio.h>
  12. #include <lib/spinlock.h>
  13. #include <plat/common/platform.h>
  14. #include <platform_def.h>
  15. #include <dram.h>
  16. #include <upower_api.h>
  17. #define PHY_FREQ_SEL_INDEX(x) ((x) << 16)
  18. #define PHY_FREQ_MULTICAST_EN(x) ((x) << 8)
  19. #define DENALI_PHY_1537 U(0x5804)
  20. #define IMX_DDRC_BASE U(0x2E060000)
  21. #define SAVED_DRAM_DATA_BASE U(0x20055000)
  22. #define DENALI_CTL_143 U(0x23C)
  23. #define DENALI_CTL_144 U(0x240)
  24. #define DENALI_CTL_146 U(0x248)
  25. #define LP_STATE_CS_IDLE U(0x404000)
  26. #define LP_STATE_CS_PD_CG U(0x4F4F00)
  27. #define LPI_WAKEUP_EN_SHIFT U(8)
  28. #define IMX_LPAV_SIM_BASE 0x2DA50000
  29. #define LPDDR_CTRL 0x14
  30. #define LPDDR_AUTO_LP_MODE_DISABLE BIT(24)
  31. #define SOC_LP_CMD_SHIFT U(15)
  32. #define LPDDR_CTRL2 0x18
  33. #define LPDDR_EN_CLKGATE (0x1<<17)
  34. #define LPDDR_MAX_CLKDIV_EN (0x1 << 16)
  35. #define LP_AUTO_ENTRY_EN 0x4
  36. #define LP_AUTO_EXIT_EN 0xF
  37. #define DENALI_CTL_00 U(0x0)
  38. #define DENALI_CTL_23 U(0x5c)
  39. #define DFIBUS_FREQ_INIT_SHIFT U(24)
  40. #define TSREF2PHYMSTR_SHIFT U(8)
  41. #define TSREF2PHYMSTR_MASK GENMASK(13, 8)
  42. #define DENALI_CTL_24 U(0x60)
  43. #define DENALI_CTL_25 U(0x64)
  44. #define DENALI_CTL_93 U(0x174)
  45. #define PWRUP_SREFRESH_EXIT BIT(0)
  46. #define DENALI_CTL_127 U(0x1fc)
  47. #define PHYMSTR_TRAIN_AFTER_INIT_COMPLETE BIT(16)
  48. #define DENALI_CTL_147 U(0x24c)
  49. #define DENALI_CTL_153 U(0x264)
  50. #define PCPCS_PD_EN BIT(8)
  51. #define DENALI_CTL_249 U(0x3E4)
  52. #define DENALI_CTL_266 U(0x428)
  53. #define DENALI_PHY_1547 U(0x582c)
  54. #define PHY_LP4_BOOT_DISABLE BIT(8)
  55. #define DENALI_PHY_1559 U(0x585c)
  56. #define DENALI_PHY_1590 U(0x58D8)
  57. #define DENALI_PI_00 U(0x2000)
  58. #define DENALI_PI_04 U(0x2010)
  59. #define DENALI_PI_52 U(0x20D0)
  60. #define DENALI_PI_26 U(0x2068)
  61. #define DENALI_PI_33 U(0x2084)
  62. #define DENALI_PI_65 U(0x2104)
  63. #define DENALI_PI_77 U(0x2134)
  64. #define DENALI_PI_134 U(0x2218)
  65. #define DENALI_PI_131 U(0x220C)
  66. #define DENALI_PI_132 U(0x2210)
  67. #define DENALI_PI_134 U(0x2218)
  68. #define DENALI_PI_137 U(0x2224)
  69. #define DENALI_PI_174 U(0x22B8)
  70. #define DENALI_PI_175 U(0x22BC)
  71. #define DENALI_PI_181 U(0x22D4)
  72. #define DENALI_PI_182 U(0x22D8)
  73. #define DENALI_PI_191 U(0x22FC)
  74. #define DENALI_PI_192 U(0x2300)
  75. #define DENALI_PI_212 U(0x2350)
  76. #define DENALI_PI_214 U(0x2358)
  77. #define DENALI_PI_217 U(0x2364)
  78. #define LPDDR3_TYPE U(0x7)
  79. #define LPDDR4_TYPE U(0xB)
  80. extern void upower_wait_resp(void);
  81. struct dram_cfg_param {
  82. uint32_t reg;
  83. uint32_t val;
  84. };
  85. struct dram_timing_info {
  86. /* ddr controller config */
  87. struct dram_cfg_param *ctl_cfg;
  88. unsigned int ctl_cfg_num;
  89. /* pi config */
  90. struct dram_cfg_param *pi_cfg;
  91. unsigned int pi_cfg_num;
  92. /* phy freq1 config */
  93. struct dram_cfg_param *phy_f1_cfg;
  94. unsigned int phy_f1_cfg_num;
  95. /* phy freq2 config */
  96. struct dram_cfg_param *phy_f2_cfg;
  97. unsigned int phy_f2_cfg_num;
  98. /* automatic low power config */
  99. struct dram_cfg_param *auto_lp_cfg;
  100. unsigned int auto_lp_cfg_num;
  101. /* initialized drate table */
  102. unsigned int fsp_table[3];
  103. };
  104. #define CTL_NUM U(680)
  105. #define PI_NUM U(298)
  106. #define PHY_NUM U(1654)
  107. #define PHY_DIFF_NUM U(49)
  108. #define AUTO_LP_NUM U(3)
  109. struct dram_cfg {
  110. uint32_t ctl_cfg[CTL_NUM];
  111. uint32_t pi_cfg[PI_NUM];
  112. uint32_t phy_full[PHY_NUM];
  113. uint32_t phy_diff[PHY_DIFF_NUM];
  114. uint32_t auto_lp_cfg[AUTO_LP_NUM];
  115. };
  116. struct dram_timing_info *info;
  117. struct dram_cfg *dram_timing_cfg;
  118. /* mark if dram cfg is already saved */
  119. static bool dram_cfg_saved;
  120. static bool dram_auto_lp_true;
  121. static uint32_t dram_class, dram_ctl_143;
  122. /* PHY register index for frequency diff */
  123. uint32_t freq_specific_reg_array[PHY_DIFF_NUM] = {
  124. 90, 92, 93, 96, 97, 100, 101, 102, 103, 104, 114,
  125. 346, 348, 349, 352, 353, 356, 357, 358, 359, 360,
  126. 370, 602, 604, 605, 608, 609, 612, 613, 614, 615,
  127. 616, 626, 858, 860, 861, 864, 865, 868, 869, 870,
  128. 871, 872, 882, 1063, 1319, 1566, 1624, 1625
  129. };
  130. /* lock used for DDR DVFS */
  131. spinlock_t dfs_lock;
  132. static volatile uint32_t core_count;
  133. static volatile bool in_progress;
  134. static volatile bool sys_dvfs;
  135. static int num_fsp;
  136. static void ddr_init(void)
  137. {
  138. unsigned int i;
  139. /* restore the ddr ctl config */
  140. for (i = 0U; i < CTL_NUM; i++) {
  141. mmio_write_32(IMX_DDRC_BASE + i * 4, dram_timing_cfg->ctl_cfg[i]);
  142. }
  143. /* load the PI registers */
  144. for (i = 0U; i < PI_NUM; i++) {
  145. mmio_write_32(IMX_DDRC_BASE + 0x2000 + i * 4, dram_timing_cfg->pi_cfg[i]);
  146. }
  147. /* restore all PHY registers for all the fsp. */
  148. mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x100);
  149. /* restore all the phy configs */
  150. for (i = 0U; i < PHY_NUM; i++) {
  151. /* skip the reserved registers space */
  152. if (i >= 121U && i <= 255U) {
  153. continue;
  154. }
  155. if (i >= 377U && i <= 511U) {
  156. continue;
  157. }
  158. if (i >= 633U && i <= 767U) {
  159. continue;
  160. }
  161. if (i >= 889U && i <= 1023U) {
  162. continue;
  163. }
  164. if (i >= 1065U && i <= 1279U) {
  165. continue;
  166. }
  167. if (i >= 1321U && i <= 1535U) {
  168. continue;
  169. }
  170. mmio_write_32(IMX_DDRC_BASE + 0x4000 + i * 4, dram_timing_cfg->phy_full[i]);
  171. }
  172. if (dram_class == LPDDR4_TYPE) {
  173. /* restore only the diff. */
  174. mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x0);
  175. for (i = 0U; i < PHY_DIFF_NUM; i++) {
  176. mmio_write_32(IMX_DDRC_BASE + 0x4000 + freq_specific_reg_array[i] * 4,
  177. dram_timing_cfg->phy_diff[i]);
  178. }
  179. }
  180. /* Re-enable MULTICAST mode */
  181. mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, PHY_FREQ_MULTICAST_EN(1));
  182. }
  183. void dram_lp_auto_disable(void)
  184. {
  185. uint32_t lp_auto_en;
  186. dram_timing_cfg = (struct dram_cfg *)(SAVED_DRAM_DATA_BASE +
  187. sizeof(struct dram_timing_info));
  188. lp_auto_en = (mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) & (LP_AUTO_ENTRY_EN << 24));
  189. /* Save initial config */
  190. dram_ctl_143 = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_143);
  191. if (lp_auto_en && !dram_auto_lp_true) {
  192. /* 0.a Save DDRC auto low-power mode parameter */
  193. dram_timing_cfg->auto_lp_cfg[0] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
  194. dram_timing_cfg->auto_lp_cfg[1] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_147);
  195. dram_timing_cfg->auto_lp_cfg[2] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146);
  196. /* Set LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2 to Maximum */
  197. mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_143, 0xF << 24);
  198. /* 0.b Disable DDRC auto low-power mode interface */
  199. mmio_clrbits_32(IMX_DDRC_BASE + DENALI_CTL_146, LP_AUTO_ENTRY_EN << 24);
  200. /* 0.c Read any location to get DRAM out of Self-refresh */
  201. mmio_read_32(DEVICE2_BASE);
  202. /* 0.d Confirm DRAM is out of Self-refresh */
  203. while ((mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) &
  204. LP_STATE_CS_PD_CG) != LP_STATE_CS_IDLE) {
  205. ;
  206. }
  207. /* 0.e Disable DDRC auto low-power exit */
  208. mmio_clrbits_32(IMX_DDRC_BASE + DENALI_CTL_147, LP_AUTO_EXIT_EN);
  209. /* dram low power mode flag */
  210. dram_auto_lp_true = true;
  211. }
  212. }
  213. void dram_lp_auto_enable(void)
  214. {
  215. /* Switch back to Auto Low-power mode */
  216. if (dram_auto_lp_true) {
  217. /* 12.a Confirm DRAM is out of Self-refresh */
  218. while ((mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) &
  219. LP_STATE_CS_PD_CG) != LP_STATE_CS_IDLE) {
  220. ;
  221. }
  222. /* 12.b Enable DDRC auto low-power exit */
  223. /*
  224. * 12.c TBC! : Set DENALI_CTL_144 [LPI_CTRL_REQ_EN[24]] and
  225. * [DFI_LP_VERSION[16]] back to default settings = 1b'1.
  226. */
  227. /*
  228. * 12.d Reconfigure DENALI_CTL_144 [LPI_WAKEUP_EN[5:0]] bit
  229. * LPI_WAKEUP_EN[3] = 1b'1.
  230. */
  231. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, dram_timing_cfg->auto_lp_cfg[0]);
  232. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_147, dram_timing_cfg->auto_lp_cfg[1]);
  233. /* 12.e Re-enable DDRC auto low-power mode interface */
  234. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_146, dram_timing_cfg->auto_lp_cfg[2]);
  235. /* restore ctl config */
  236. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_143, dram_ctl_143);
  237. /* dram low power mode flag */
  238. dram_auto_lp_true = false;
  239. }
  240. }
  241. void dram_enter_self_refresh(void)
  242. {
  243. /* disable auto low power interface */
  244. dram_lp_auto_disable();
  245. /* 1. config the PCC_LPDDR4[SSADO] to 2b'11 for ACK domain 0/1's STOP */
  246. mmio_setbits_32(IMX_PCC5_BASE + 0x108, 0x2 << 22);
  247. /* 1.a Clock gate PCC_LPDDR4[CGC] and no software reset PCC_LPDDR4[SWRST] */
  248. mmio_setbits_32(IMX_PCC5_BASE + 0x108, (BIT(30) | BIT(28)));
  249. /*
  250. * 2. Make sure the DENALI_CTL_144[LPI_WAKEUP_EN[5:0]] has the bit
  251. * LPI_WAKEUP_EN[3] = 1b'1. This enables the option 'self-refresh
  252. * long with mem and ctlr clk gating or self-refresh power-down long
  253. * with mem and ctlr clk gating'
  254. */
  255. mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(3) << LPI_WAKEUP_EN_SHIFT);
  256. /* TODO: Needed ? 2.a DENALI_CTL_144[LPI_TIMER_WAKEUP_F2] */
  257. //mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(0));
  258. /*
  259. * 3a. Config SIM_LPAV LPDDR_CTRL[LPDDR_AUTO_LP_MODE_DISABLE] to 1b'0(enable
  260. * the logic to automatic handles low power entry/exit. This is the recommended
  261. * option over handling through software.
  262. * 3b. Config the SIM_LPAV LPDDR_CTRL[SOC_LP_CMD] to 6b'101001(encoding for
  263. * self_refresh with both DDR controller and DRAM clock gate. THis is mandatory
  264. * since LPPDR logic will be power gated).
  265. */
  266. mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL, LPDDR_AUTO_LP_MODE_DISABLE);
  267. mmio_clrsetbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL,
  268. 0x3f << SOC_LP_CMD_SHIFT, 0x29 << SOC_LP_CMD_SHIFT);
  269. /* 3.c clock gate ddr controller */
  270. mmio_setbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL2, LPDDR_EN_CLKGATE);
  271. /* 3.d lpddr max clk div en */
  272. mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL2, LPDDR_MAX_CLKDIV_EN);
  273. }
  274. void dram_exit_self_refresh(void)
  275. {
  276. dram_lp_auto_enable();
  277. }
  278. void dram_enter_retention(void)
  279. {
  280. unsigned int i;
  281. dram_lp_auto_disable();
  282. /* 1. config the PCC_LPDDR4[SSADO] to 2b'11 for ACK domain 0/1's STOP */
  283. mmio_setbits_32(IMX_PCC5_BASE + 0x108, 0x2 << 22);
  284. /*
  285. * 2. Make sure the DENALI_CTL_144[LPI_WAKEUP_EN[5:0]] has the bit
  286. * LPI_WAKEUP_EN[3] = 1b'1. This enables the option 'self-refresh
  287. * long with mem and ctlr clk gating or self-refresh power-down
  288. * long with mem and ctlr clk gating'
  289. */
  290. mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(3) << LPI_WAKEUP_EN_SHIFT);
  291. /*
  292. * 3a. Config SIM_LPAV LPDDR_CTRL[LPDDR_AUTO_LP_MODE_DISABLE] to 1b'0(enable
  293. * the logic to automatic handles low power entry/exit. This is the recommended
  294. * option over handling through software.
  295. * 3b. Config the SIM_LPAV LPDDR_CTRL[SOC_LP_CMD] to 6b'101001(encoding for
  296. * self_refresh with both DDR controller and DRAM clock gate. THis is mandatory
  297. * since LPPDR logic will be power gated).
  298. */
  299. mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL, LPDDR_AUTO_LP_MODE_DISABLE);
  300. mmio_clrsetbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL,
  301. 0x3f << SOC_LP_CMD_SHIFT, 0x29 << SOC_LP_CMD_SHIFT);
  302. /* Save DDR Controller & PHY config.
  303. * Set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=1. Read and store all
  304. * the PHY registers for F2 into phy_f1_cfg, then read/store the diff between
  305. * F1 & F2 into phy_f2_cfg.
  306. */
  307. if (!dram_cfg_saved) {
  308. info = (struct dram_timing_info *)SAVED_DRAM_DATA_BASE;
  309. dram_timing_cfg = (struct dram_cfg *)(SAVED_DRAM_DATA_BASE +
  310. sizeof(struct dram_timing_info));
  311. /* get the dram type */
  312. dram_class = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_00);
  313. dram_class = (dram_class >> 8) & 0xf;
  314. /* save the ctl registers */
  315. for (i = 0U; i < CTL_NUM; i++) {
  316. dram_timing_cfg->ctl_cfg[i] = mmio_read_32(IMX_DDRC_BASE + i * 4);
  317. }
  318. dram_timing_cfg->ctl_cfg[0] = dram_timing_cfg->ctl_cfg[0] & 0xFFFFFFFE;
  319. /* save the PI registers */
  320. for (i = 0U; i < PI_NUM; i++) {
  321. dram_timing_cfg->pi_cfg[i] = mmio_read_32(IMX_DDRC_BASE + 0x2000 + i * 4);
  322. }
  323. dram_timing_cfg->pi_cfg[0] = dram_timing_cfg->pi_cfg[0] & 0xFFFFFFFE;
  324. /*
  325. * Read and store all PHY registers. full array is a full
  326. * copy for all the setpoint
  327. */
  328. if (dram_class == LPDDR4_TYPE) {
  329. mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x10000);
  330. for (i = 0U; i < PHY_NUM; i++) {
  331. /* Make sure MULTICASE is enabled */
  332. if (i == 1537U) {
  333. dram_timing_cfg->phy_full[i] = 0x100;
  334. } else {
  335. dram_timing_cfg->phy_full[i] = mmio_read_32(IMX_DDRC_BASE + 0x4000 + i * 4);
  336. }
  337. }
  338. /*
  339. * set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=0.
  340. * Read and store only the diff.
  341. */
  342. mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x0);
  343. /* save only the frequency based diff config to save memory */
  344. for (i = 0U; i < PHY_DIFF_NUM; i++) {
  345. dram_timing_cfg->phy_diff[i] = mmio_read_32(IMX_DDRC_BASE + 0x4000 +
  346. freq_specific_reg_array[i] * 4);
  347. }
  348. } else {
  349. /* LPDDR3, only f1 need to save */
  350. for (i = 0U; i < info->phy_f1_cfg_num; i++) {
  351. info->phy_f1_cfg[i].val = mmio_read_32(info->phy_f1_cfg[i].reg);
  352. }
  353. }
  354. dram_cfg_saved = true;
  355. }
  356. }
  357. void dram_exit_retention(void)
  358. {
  359. uint32_t val;
  360. /* 1. Config the LPAV PLL4 and DDR clock for the desired LPDDR operating frequency. */
  361. mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
  362. /* 2. Write PCC5.PCC_LPDDR4[SWRST] to 1b'1 to release LPDDR from reset. */
  363. mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(28));
  364. /* 3. Reload the LPDDR CTL/PI/PHY register */
  365. ddr_init();
  366. if (dram_class == LPDDR4_TYPE) {
  367. /* 4a. FIXME Set PHY_SET_DFI_INPUT_N parameters to 4'h1. LPDDR4 only */
  368. mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1559, 0x01010101);
  369. /*
  370. * 4b. CTL PWRUP_SREFRESH_EXIT=1'b0 for disabling self refresh exit
  371. * from controller.
  372. */
  373. /*
  374. * 4c. PI_PWRUP_SELF_REF_EXIT=1, PI_MC_PWRUP_SELF_REF_EXIT=0 for enabling
  375. * self refresh exit from PI
  376. */
  377. /* 4c. PI_INT_LVL_EN=0 to skip Initialization trainings. */
  378. /*
  379. * 4d. PI_WRLVL_EN_F0/1/2= PI_CALVL_EN_F0/1/2= PI_RDLVL_EN_F0/1/2=
  380. * PI_RDLVL_GATE_EN_F0/1/2= PI_WDQLVL_EN_F0/1/2=0x2.
  381. * Enable non initialization trainings.
  382. */
  383. /* 4e. PI_PWRUP_SREFRESH_EXIT_CS=0xF */
  384. /* 4f. PI_DLL_RESET=0x1 */
  385. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_137, 0x1);
  386. /* PI_PWRUP_SELF_REF_EXIT = 1 */
  387. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_132, 0x01000000);
  388. /* PI_MC_PWRUP_SELF_REF_EXIT = 0 */
  389. mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_132, BIT(16));
  390. /* PI_INT_LVL_EN = 0 */
  391. mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_04, BIT(0));
  392. /* PI_WRLVL_EN_F0 = 3, PI_WRLVL_EN_F1 = 3 */
  393. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_174, 0x03030000);
  394. /* PI_WRLVL_EN_F2 = 3 */
  395. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_175, 0x03);
  396. /* PI_CALVL_EN_F0 = 3, PI_CALVL_EN_F1 = 3 */
  397. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_191, 0x03030000);
  398. /* PI_CALVL_EN_F2 = 3 */
  399. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_192, 0x03);
  400. /* PI_WDQLVL_EN_F0 = 3 */
  401. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_212, 0x300);
  402. /* PI_WDQLVL_EN_F1 = 3 */
  403. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_214, 0x03000000);
  404. /* PI_WDQLVL_EN_F2 = 3 */
  405. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_217, 0x300);
  406. /* PI_EDLVL_EN_F0 = 3, PI_EDLVL_GATE_EN_F0 = 3 */
  407. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_181, 0x03030000);
  408. /*
  409. * PI_RDLVL_EN_F1 = 3, PI_RDLVL_GATE_EN_F1 = 3,
  410. * PI_RDLVL_EN_F2 = 3, PI_RDLVL_GATE_EN_F2 = 3
  411. */
  412. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_182, 0x03030303);
  413. /* PI_PWRUP_SREFRESH_EXIT_CS = 0xF */
  414. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_134, 0x000F0000);
  415. } else {
  416. /* PI_DLL_RESET=1 */
  417. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_137, 0x1);
  418. /* PI_PWRUP_SELF_REF_EXIT=1 */
  419. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_132, 0x01000000);
  420. /* PI_MC_PWRUP_SELF_REF_EXIT=0 */
  421. mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_132, BIT(16));
  422. /* PI_INT_LVL_EN=0 */
  423. mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_04, BIT(0));
  424. /* PI_WRLVL_EN_F0=3 */
  425. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_174, 0x00030000);
  426. /* PI_CALVL_EN_F0=3 */
  427. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_191, 0x00030000);
  428. /* PI_RDLVL_EN_F0=3,PI_RDLVL_GATE_EN_F0=3 */
  429. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_181, 0x03030000);
  430. /* PI_PWRUP_SREFRESH_EXIT_CS=0xF */
  431. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_134, 0x000F0000);
  432. }
  433. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, 0x00002D00);
  434. /* Force in-order AXI read data */
  435. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, 0x1);
  436. /*
  437. * Disable special R/W group switches so that R/W group placement
  438. * is always at END of R/W group.
  439. */
  440. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_249, 0x0);
  441. /* Reduce time for IO pad calibration */
  442. mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1590, 0x01000000);
  443. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_25, 0x00020100);
  444. /* PD disable */
  445. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_153, 0x04040000);
  446. /*
  447. * 5. Disable automatic LP entry and PCPCS modes LP_AUTO_ENTRY_EN
  448. * to 1b'0, PCPCS_PD_EN to 1b'0
  449. */
  450. upwr_xcp_set_ddr_retention(APD_DOMAIN, 0, NULL);
  451. upower_wait_resp();
  452. if (dram_class == LPDDR4_TYPE) {
  453. /* 7. Write PI START parameter to 1'b1 */
  454. mmio_write_32(IMX_DDRC_BASE + DENALI_PI_00, 0x00000b01);
  455. /* 8. Write CTL START parameter to 1'b1 */
  456. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_00, 0x00000b01);
  457. } else {
  458. /* 7. Write PI START parameter to 1'b1 */
  459. mmio_write_32(IMX_DDRC_BASE + DENALI_PI_00, 0x00000701);
  460. /* 8. Write CTL START parameter to 1'b1 */
  461. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_00, 0x00000701);
  462. }
  463. /* 9. DENALI_CTL_266: Wait for INT_STATUS_INIT=0x2 */
  464. do {
  465. val = (mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_266) >> 8) & 0xFF;
  466. } while (val != 0x2);
  467. /*
  468. * 10. Run SW trainings by setting PI_CALVL_REQ,PI_WRLVL_REQ,PI_RDLVL_GATE_REQ,
  469. * PI_RDLVL_REQ,PI_WDQLVL_REQ(NA for LPDDR3) in same order.
  470. */
  471. if (dram_class == LPDDR4_TYPE) {
  472. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_52, 0x10000); /* CALVL */
  473. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_26, 0x100); /* WRLVL */
  474. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
  475. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
  476. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_65, 0x10000); /* WDQLVL */
  477. /* 11. Wait for trainings to get complete by polling PI_INT_STATUS */
  478. while ((mmio_read_32(IMX_DDRC_BASE + DENALI_PI_77) & 0x07E00000) != 0x07E00000) {
  479. ;
  480. }
  481. } else {
  482. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_52, 0x10000); /* CALVL */
  483. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_26, 0x100); /* WRLVL */
  484. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
  485. mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
  486. while ((mmio_read_32(IMX_DDRC_BASE + DENALI_PI_77) & 0x05E00000) != 0x05E00000) {
  487. ;
  488. }
  489. }
  490. dram_lp_auto_enable();
  491. }
  492. #define LPDDR_DONE (0x1<<4)
  493. #define SOC_FREQ_CHG_ACK (0x1<<6)
  494. #define SOC_FREQ_CHG_REQ (0x1<<7)
  495. #define LPI_WAKEUP_EN (0x4<<8)
  496. #define SOC_FREQ_REQ (0x1<<11)
  497. static void set_cgc2_ddrclk(uint8_t src, uint8_t div)
  498. {
  499. /* Wait until the reg is unlocked for writing */
  500. while (mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(31))
  501. ;
  502. mmio_write_32(IMX_CGC2_BASE + 0x40, (src << 28) | (div << 21));
  503. /* Wait for the clock switching done */
  504. while (!(mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(27)))
  505. ;
  506. }
  507. static void set_ddr_clk(uint32_t ddr_freq)
  508. {
  509. /* Disable DDR clock */
  510. mmio_clrbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
  511. switch (ddr_freq) {
  512. /* boot frequency ? */
  513. case 48:
  514. set_cgc2_ddrclk(2, 0);
  515. break;
  516. /* default bypass frequency for fsp 1 */
  517. case 192:
  518. set_cgc2_ddrclk(0, 1);
  519. break;
  520. case 384:
  521. set_cgc2_ddrclk(0, 0);
  522. break;
  523. case 264:
  524. set_cgc2_ddrclk(4, 3);
  525. break;
  526. case 528:
  527. set_cgc2_ddrclk(4, 1);
  528. break;
  529. default:
  530. break;
  531. }
  532. /* Enable DDR clock */
  533. mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
  534. /* Wait until the reg is unlocked for writing */
  535. while (mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(31)) {
  536. ;
  537. }
  538. }
  539. #define AVD_SIM_LPDDR_CTRL (IMX_LPAV_SIM_BASE + 0x14)
  540. #define AVD_SIM_LPDDR_CTRL2 (IMX_LPAV_SIM_BASE + 0x18)
  541. #define MAX_FSP_NUM U(3)
  542. #define DDR_DFS_GET_FSP_COUNT 0x10
  543. #define DDR_BYPASS_DRATE U(400)
  544. extern int upower_pmic_i2c_write(uint32_t reg_addr, uint32_t reg_val);
  545. /* Normally, we only switch frequency between 1(bypass) and 2(highest) */
  546. int lpddr4_dfs(uint32_t freq_index)
  547. {
  548. uint32_t lpddr_ctrl, lpddr_ctrl2;
  549. uint32_t ddr_ctl_144;
  550. /*
  551. * Valid index: 0 to 2
  552. * index 0: boot frequency
  553. * index 1: bypass frequency
  554. * index 2: highest frequency
  555. */
  556. if (freq_index > 2U) {
  557. return -1;
  558. }
  559. /*
  560. * increase the voltage to 1.1V firstly before increase frequency
  561. * and APD enter OD mode
  562. */
  563. if (freq_index == 2U && sys_dvfs) {
  564. upower_pmic_i2c_write(0x22, 0x28);
  565. }
  566. /* Enable LPI_WAKEUP_EN */
  567. ddr_ctl_144 = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
  568. mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, LPI_WAKEUP_EN);
  569. /* put DRAM into long self-refresh & clock gating */
  570. lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL);
  571. lpddr_ctrl = (lpddr_ctrl & ~((0x3f << 15) | (0x3 << 9))) | (0x28 << 15) | (freq_index << 9);
  572. mmio_write_32(AVD_SIM_LPDDR_CTRL, lpddr_ctrl);
  573. /* Gating the clock */
  574. lpddr_ctrl2 = mmio_read_32(AVD_SIM_LPDDR_CTRL2);
  575. mmio_setbits_32(AVD_SIM_LPDDR_CTRL2, LPDDR_EN_CLKGATE);
  576. /* Request frequency change */
  577. mmio_setbits_32(AVD_SIM_LPDDR_CTRL, SOC_FREQ_REQ);
  578. do {
  579. lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL);
  580. if (lpddr_ctrl & SOC_FREQ_CHG_REQ) {
  581. /* Bypass mode */
  582. if (info->fsp_table[freq_index] < DDR_BYPASS_DRATE) {
  583. /* Change to PLL bypass mode */
  584. mmio_write_32(IMX_LPAV_SIM_BASE, 0x1);
  585. /* change the ddr clock source & frequency */
  586. set_ddr_clk(info->fsp_table[freq_index]);
  587. } else {
  588. /* Change to PLL unbypass mode */
  589. mmio_write_32(IMX_LPAV_SIM_BASE, 0x0);
  590. /* change the ddr clock source & frequency */
  591. set_ddr_clk(info->fsp_table[freq_index] >> 1);
  592. }
  593. mmio_clrsetbits_32(AVD_SIM_LPDDR_CTRL, SOC_FREQ_CHG_REQ, SOC_FREQ_CHG_ACK);
  594. continue;
  595. }
  596. } while ((lpddr_ctrl & LPDDR_DONE) != 0); /* several try? */
  597. /* restore the original setting */
  598. mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, ddr_ctl_144);
  599. mmio_write_32(AVD_SIM_LPDDR_CTRL2, lpddr_ctrl2);
  600. /* Check the DFS result */
  601. lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL) & 0xF;
  602. if (lpddr_ctrl != 0U) {
  603. /* Must be something wrong, return failure */
  604. return -1;
  605. }
  606. /* decrease the BUCK3 voltage after frequency changed to lower
  607. * and APD in ND_MODE
  608. */
  609. if (freq_index == 1U && sys_dvfs) {
  610. upower_pmic_i2c_write(0x22, 0x20);
  611. }
  612. /* DFS done successfully */
  613. return 0;
  614. }
  615. /* for the non-primary core, waiting for DFS done */
  616. static uint64_t waiting_dvfs(uint32_t id, uint32_t flags,
  617. void *handle, void *cookie)
  618. {
  619. uint32_t irq;
  620. irq = plat_ic_acknowledge_interrupt();
  621. if (irq < 1022U) {
  622. plat_ic_end_of_interrupt(irq);
  623. }
  624. /* set the WFE done status */
  625. spin_lock(&dfs_lock);
  626. core_count++;
  627. dsb();
  628. spin_unlock(&dfs_lock);
  629. while (in_progress) {
  630. wfe();
  631. }
  632. return 0;
  633. }
  634. int dram_dvfs_handler(uint32_t smc_fid, void *handle,
  635. u_register_t x1, u_register_t x2, u_register_t x3)
  636. {
  637. unsigned int fsp_index = x1;
  638. uint32_t online_cpus = x2 - 1;
  639. uint64_t mpidr = read_mpidr_el1();
  640. unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
  641. /* Get the number of FSPs */
  642. if (x1 == DDR_DFS_GET_FSP_COUNT) {
  643. SMC_RET2(handle, num_fsp, info->fsp_table[1]);
  644. }
  645. /* start lpddr frequency scaling */
  646. in_progress = true;
  647. sys_dvfs = x3 ? true : false;
  648. dsb();
  649. /* notify other core wait for scaling done */
  650. for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++)
  651. /* Skip raise SGI for current CPU */
  652. if (i != cpu_id) {
  653. plat_ic_raise_el3_sgi(0x8, i);
  654. }
  655. /* Make sure all the cpu in WFE */
  656. while (online_cpus != core_count) {
  657. ;
  658. }
  659. /* Flush the L1/L2 cache */
  660. dcsw_op_all(DCCSW);
  661. lpddr4_dfs(fsp_index);
  662. in_progress = false;
  663. core_count = 0;
  664. dsb();
  665. sev();
  666. isb();
  667. SMC_RET1(handle, 0);
  668. }
  669. void dram_init(void)
  670. {
  671. uint32_t flags = 0;
  672. uint32_t rc;
  673. unsigned int i;
  674. /* Register the EL3 handler for DDR DVFS */
  675. set_interrupt_rm_flag(flags, NON_SECURE);
  676. rc = register_interrupt_type_handler(INTR_TYPE_EL3, waiting_dvfs, flags);
  677. if (rc) {
  678. panic();
  679. }
  680. info = (struct dram_timing_info *)SAVED_DRAM_DATA_BASE;
  681. /* Get the num of the supported Fsp */
  682. for (i = 0; i < MAX_FSP_NUM; i++) {
  683. if (!info->fsp_table[i]) {
  684. break;
  685. }
  686. }
  687. num_fsp = (i > MAX_FSP_NUM) ? MAX_FSP_NUM : i;
  688. }