xref: /rk3399_ARM-atf/plat/imx/imx8m/ddr/ddr4_dvfs.c (revision 093888caaf54cbfe38d4b68406d98fbcf5c7d81f)
19c336f61SJacky Bai /*
2*093888caSJacky Bai  * Copyright 2018-2023 NXP
39c336f61SJacky Bai  *
49c336f61SJacky Bai  * SPDX-License-Identifier: BSD-3-Clause
59c336f61SJacky Bai  */
69c336f61SJacky Bai 
79c336f61SJacky Bai #include <drivers/delay_timer.h>
89c336f61SJacky Bai #include <lib/mmio.h>
99c336f61SJacky Bai 
109c336f61SJacky Bai #include <dram.h>
119c336f61SJacky Bai 
129c336f61SJacky Bai void ddr4_mr_write(uint32_t mr, uint32_t data, uint32_t mr_type, uint32_t rank)
139c336f61SJacky Bai {
149c336f61SJacky Bai 	uint32_t val, mr_mirror, data_mirror;
159c336f61SJacky Bai 
169c336f61SJacky Bai 	/*
179c336f61SJacky Bai 	 * 1. Poll MRSTAT.mr_wr_busy until it is 0 to make sure
189c336f61SJacky Bai 	 * that there is no outstanding MR transAction.
199c336f61SJacky Bai 	 */
209c336f61SJacky Bai 	while (mmio_read_32(DDRC_MRSTAT(0)) & 0x1) {
219c336f61SJacky Bai 		;
229c336f61SJacky Bai 	}
239c336f61SJacky Bai 
249c336f61SJacky Bai 	/*
259c336f61SJacky Bai 	 * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank
269c336f61SJacky Bai 	 * and (for MRWs) MRCTRL1.mr_data to define the MR transaction.
279c336f61SJacky Bai 	 */
289c336f61SJacky Bai 	val = mmio_read_32(DDRC_DIMMCTL(0));
299c336f61SJacky Bai 	if ((val & 0x2) && (rank == 0x2)) {
309c336f61SJacky Bai 		mr_mirror = (mr & 0x4) | ((mr & 0x1) << 1) | ((mr & 0x2) >> 1); /* BA0, BA1 swap */
319c336f61SJacky Bai 		data_mirror = (data & 0x1607) | ((data & 0x8) << 1) | ((data & 0x10) >> 1) |
329c336f61SJacky Bai 				((data & 0x20) << 1) | ((data & 0x40) >> 1) | ((data & 0x80) << 1) |
339c336f61SJacky Bai 				 ((data & 0x100) >> 1) | ((data & 0x800) << 2) | ((data & 0x2000) >> 2) ;
349c336f61SJacky Bai 	} else {
359c336f61SJacky Bai 		mr_mirror = mr;
369c336f61SJacky Bai 		data_mirror = data;
379c336f61SJacky Bai 	}
389c336f61SJacky Bai 
399c336f61SJacky Bai 	mmio_write_32(DDRC_MRCTRL0(0), mr_type | (mr_mirror << 12) | (rank << 4));
409c336f61SJacky Bai 	mmio_write_32(DDRC_MRCTRL1(0), data_mirror);
419c336f61SJacky Bai 
429c336f61SJacky Bai 	/*
439c336f61SJacky Bai 	 * 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1.
449c336f61SJacky Bai 	 * This bit is self-clearing, and triggers the MR transaction.
459c336f61SJacky Bai 	 * The uMCTL2 then asserts the MRSTAT.mr_wr_busy while it performs
469c336f61SJacky Bai 	 * the MR transaction to SDRAM, and no further accesses can be
479c336f61SJacky Bai 	 * initiated until it is deasserted.
489c336f61SJacky Bai 	 */
499c336f61SJacky Bai 	mmio_setbits_32(DDRC_MRCTRL0(0), BIT(31));
509c336f61SJacky Bai 
519c336f61SJacky Bai 	while (mmio_read_32(DDRC_MRSTAT(0))) {
529c336f61SJacky Bai 		;
539c336f61SJacky Bai 	}
549c336f61SJacky Bai }
559c336f61SJacky Bai 
569c336f61SJacky Bai void dram_cfg_all_mr(struct dram_info *info, uint32_t pstate)
579c336f61SJacky Bai {
589c336f61SJacky Bai 	uint32_t num_rank = info->num_rank;
599c336f61SJacky Bai 	/*
609c336f61SJacky Bai 	 * 15. Perform MRS commands as required to re-program
619c336f61SJacky Bai 	 * timing registers in the SDRAM for the new frequency
629c336f61SJacky Bai 	 * (in particular, CL, CWL and WR may need to be changed).
639c336f61SJacky Bai 	 */
649c336f61SJacky Bai 
659c336f61SJacky Bai 	for (int i = 1; i <= num_rank; i++) {
669c336f61SJacky Bai 		for (int j = 0; j < 6; j++) {
679c336f61SJacky Bai 			ddr4_mr_write(j, info->mr_table[pstate][j], 0, i);
689c336f61SJacky Bai 		}
699c336f61SJacky Bai 		ddr4_mr_write(6, info->mr_table[pstate][7], 0, i);
709c336f61SJacky Bai 	}
719c336f61SJacky Bai }
729c336f61SJacky Bai 
739c336f61SJacky Bai void sw_pstate(uint32_t pstate, uint32_t drate)
749c336f61SJacky Bai {
759c336f61SJacky Bai 	uint32_t val;
769c336f61SJacky Bai 
779c336f61SJacky Bai 	mmio_write_32(DDRC_SWCTL(0), 0x0);
789c336f61SJacky Bai 
799c336f61SJacky Bai 	/*
809c336f61SJacky Bai 	 * Update any registers which may be required to
819c336f61SJacky Bai 	 * change for the new frequency.
829c336f61SJacky Bai 	 */
839c336f61SJacky Bai 	mmio_write_32(DDRC_MSTR2(0), pstate);
849c336f61SJacky Bai 	mmio_setbits_32(DDRC_MSTR(0), (0x1 << 29));
859c336f61SJacky Bai 
869c336f61SJacky Bai 	/*
879c336f61SJacky Bai 	 * Toggle RFSHCTL3.refresh_update_level to allow the
889c336f61SJacky Bai 	 * new refresh-related register values to propagate
899c336f61SJacky Bai 	 * to the refresh logic.
909c336f61SJacky Bai 	 */
919c336f61SJacky Bai 	val = mmio_read_32(DDRC_RFSHCTL3(0));
929c336f61SJacky Bai 	if (val & 0x2) {
939c336f61SJacky Bai 		mmio_write_32(DDRC_RFSHCTL3(0), val & 0xFFFFFFFD);
949c336f61SJacky Bai 	} else {
959c336f61SJacky Bai 		mmio_write_32(DDRC_RFSHCTL3(0), val | 0x2);
969c336f61SJacky Bai 	}
979c336f61SJacky Bai 
989c336f61SJacky Bai 	/*
999c336f61SJacky Bai 	 * 19. If required, trigger the initialization in the PHY.
1009c336f61SJacky Bai 	 * If using the gen2 multiPHY, PLL initialization should
1019c336f61SJacky Bai 	 * be triggered at this point. See the PHY databook for
1029c336f61SJacky Bai 	 * details about the frequency change procedure.
1039c336f61SJacky Bai 	 */
1049c336f61SJacky Bai 	mmio_write_32(DDRC_DFIMISC(0), 0x00000000 | (pstate << 8));
1059c336f61SJacky Bai 	mmio_write_32(DDRC_DFIMISC(0), 0x00000020 | (pstate << 8));
1069c336f61SJacky Bai 
1079c336f61SJacky Bai 	/* wait DFISTAT.dfi_init_complete to 0 */
1089c336f61SJacky Bai 	while (mmio_read_32(DDRC_DFISTAT(0)) & 0x1) {
1099c336f61SJacky Bai 		;
1109c336f61SJacky Bai 	}
1119c336f61SJacky Bai 
1129c336f61SJacky Bai 	/* change the clock to the target frequency */
1139c336f61SJacky Bai 	dram_clock_switch(drate, false);
1149c336f61SJacky Bai 
1159c336f61SJacky Bai 	mmio_write_32(DDRC_DFIMISC(0), 0x00000000 | (pstate << 8));
1169c336f61SJacky Bai 
1179c336f61SJacky Bai 	/* wait DFISTAT.dfi_init_complete to 1 */
1189c336f61SJacky Bai 	while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
1199c336f61SJacky Bai 		;
1209c336f61SJacky Bai 	}
1219c336f61SJacky Bai 
1229c336f61SJacky Bai 	/*
1239c336f61SJacky Bai 	 * When changing frequencies the controller may violate the JEDEC
1249c336f61SJacky Bai 	 * requirement that no more than 16 refreshes should be issued within
1259c336f61SJacky Bai 	 * 2*tREFI. These extra refreshes are not expected to cause a problem
1269c336f61SJacky Bai 	 * in the SDRAM. This issue can be avoided by waiting for at least 2*tREFI
1279c336f61SJacky Bai 	 * before exiting self-refresh in step 19.
1289c336f61SJacky Bai 	 */
1299c336f61SJacky Bai 	udelay(14);
1309c336f61SJacky Bai 
1319c336f61SJacky Bai 	/* 14. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
1329c336f61SJacky Bai 	mmio_clrbits_32(DDRC_PWRCTL(0), (1 << 5));
1339c336f61SJacky Bai 
1349c336f61SJacky Bai 	while ((mmio_read_32(DDRC_STAT(0)) & 0x3f) == 0x23) {
1359c336f61SJacky Bai 		;
1369c336f61SJacky Bai 	}
1379c336f61SJacky Bai }
1389c336f61SJacky Bai 
1399c336f61SJacky Bai void ddr4_swffc(struct dram_info *info, unsigned int pstate)
1409c336f61SJacky Bai {
1419c336f61SJacky Bai 	uint32_t drate = info->timing_info->fsp_table[pstate];
1429c336f61SJacky Bai 
1439c336f61SJacky Bai 	/*
1449c336f61SJacky Bai 	 * 1. set SWCTL.sw_done to disable quasi-dynamic register
1459c336f61SJacky Bai 	 * programming outside reset.
1469c336f61SJacky Bai 	 */
1479c336f61SJacky Bai 	mmio_write_32(DDRC_SWCTL(0), 0x0);
1489c336f61SJacky Bai 
1499c336f61SJacky Bai 	/*
1509c336f61SJacky Bai 	 * 2. Write 0 to PCTRL_n.port_en. This blocks AXI port(s)
1519c336f61SJacky Bai 	 * from taking any transaction (blocks traffic on AXI ports).
1529c336f61SJacky Bai 	 */
1539c336f61SJacky Bai 	mmio_write_32(DDRC_PCTRL_0(0), 0x0);
1549c336f61SJacky Bai 
1559c336f61SJacky Bai 	/*
1569c336f61SJacky Bai 	 * 3. Poll PSTAT.rd_port_busy_n=0 and PSTAT.wr_port_busy_n=0.
1579c336f61SJacky Bai 	 * Wait until all AXI ports are idle (the uMCTL2 core has to
1589c336f61SJacky Bai 	 * be idle).
1599c336f61SJacky Bai 	 */
1609c336f61SJacky Bai 	while (mmio_read_32(DDRC_PSTAT(0)) & 0x10001) {
1619c336f61SJacky Bai 		;
1629c336f61SJacky Bai 	}
1639c336f61SJacky Bai 
1649c336f61SJacky Bai 	/*
1659c336f61SJacky Bai 	 * 4. Write 0 to SBRCTL.scrub_en. Disable SBR, required only if
1669c336f61SJacky Bai 	 * SBR instantiated.
1679c336f61SJacky Bai 	 * 5. Poll SBRSTAT.scrub_busy=0.
1689c336f61SJacky Bai 	 * 6. Set DERATEEN.derate_enable = 0, if DERATEEN.derate_eanble = 1
1699c336f61SJacky Bai 	 * and the read latency (RL) value needs to change after the frequency
1709c336f61SJacky Bai 	 * change (LPDDR2/3/4 only).
1719c336f61SJacky Bai 	 * 7. Set DBG1.dis_hif=1 so that no new commands will be accepted by the uMCTL2.
1729c336f61SJacky Bai 	 */
1739c336f61SJacky Bai 	mmio_setbits_32(DDRC_DBG1(0), (0x1 << 1));
1749c336f61SJacky Bai 
1759c336f61SJacky Bai 	/*
1769c336f61SJacky Bai 	 * 8. Poll DBGCAM.dbg_wr_q_empty and DBGCAM.dbg_rd_q_empty to ensure
1779c336f61SJacky Bai 	 * that write and read data buffers are empty.
1789c336f61SJacky Bai 	 */
1799c336f61SJacky Bai 	while ((mmio_read_32(DDRC_DBGCAM(0)) & 0x06000000) != 0x06000000) {
1809c336f61SJacky Bai 		;
1819c336f61SJacky Bai 	}
1829c336f61SJacky Bai 
1839c336f61SJacky Bai 	/*
1849c336f61SJacky Bai 	 * 9. For DDR4, update MR6 with the new tDLLK value via the Mode
1859c336f61SJacky Bai 	 * Register Write signals
1869c336f61SJacky Bai 	 * 10. Set DFILPCFG0.dfi_lp_en_sr = 0, if DFILPCFG0.dfi_lp_en_sr = 1,
1879c336f61SJacky Bai 	 * and wait until DFISTAT.dfi_lp_ack
1889c336f61SJacky Bai 	 * 11. If DFI PHY Master interface is active in uMCTL2, then disable it
1899c336f61SJacky Bai 	 * 12. Wait until STAT.operating_mode[1:0]!=11 indicating that the
1909c336f61SJacky Bai 	 * controller is not in self-refresh mode.
1919c336f61SJacky Bai 	 */
192*093888caSJacky Bai 	if ((mmio_read_32(DDRC_STAT(0)) & 0x3) == 0x3) {
193*093888caSJacky Bai 		VERBOSE("DRAM is in Self Refresh\n");
1949c336f61SJacky Bai 	}
1959c336f61SJacky Bai 
1969c336f61SJacky Bai 	/*
1979c336f61SJacky Bai 	 * 13. Assert PWRCTL.selfref_sw for the DWC_ddr_umctl2 core to enter
1989c336f61SJacky Bai 	 * the self-refresh mode.
1999c336f61SJacky Bai 	 */
2009c336f61SJacky Bai 	mmio_setbits_32(DDRC_PWRCTL(0), (1 << 5));
2019c336f61SJacky Bai 
2029c336f61SJacky Bai 	/*
2039c336f61SJacky Bai 	 * 14. Wait until STAT.operating_mode[1:0]==11 indicating that the
2049c336f61SJacky Bai 	 * controller core is in self-refresh mode.
2059c336f61SJacky Bai 	 */
2069c336f61SJacky Bai 	while ((mmio_read_32(DDRC_STAT(0)) & 0x3f) != 0x23) {
2079c336f61SJacky Bai 		;
2089c336f61SJacky Bai 	}
2099c336f61SJacky Bai 
2109c336f61SJacky Bai 	sw_pstate(pstate, drate);
2119c336f61SJacky Bai 	dram_cfg_all_mr(info, pstate);
2129c336f61SJacky Bai 
2139c336f61SJacky Bai 	/* 23. Enable HIF commands by setting DBG1.dis_hif=0. */
2149c336f61SJacky Bai 	mmio_clrbits_32(DDRC_DBG1(0), (0x1 << 1));
2159c336f61SJacky Bai 
2169c336f61SJacky Bai 	/*
2179c336f61SJacky Bai 	 * 24. Reset DERATEEN.derate_enable = 1 if DERATEEN.derate_enable
2189c336f61SJacky Bai 	 * has been set to 0 in step 6.
2199c336f61SJacky Bai 	 * 25. If DFI PHY Master interface was active before step 11 then
2209c336f61SJacky Bai 	 * enable it back by programming DFIPHYMSTR.phymstr_en = 1'b1.
2219c336f61SJacky Bai 	 * 26. Write 1 to PCTRL_n.port_en. AXI port(s) are no longer blocked
2229c336f61SJacky Bai 	 * from taking transactions (Re-enable traffic on AXI ports)
2239c336f61SJacky Bai 	 */
2249c336f61SJacky Bai 	mmio_write_32(DDRC_PCTRL_0(0), 0x1);
2259c336f61SJacky Bai 
2269c336f61SJacky Bai 	/*
2279c336f61SJacky Bai 	 * 27. Write 1 to SBRCTL.scrub_en. Enable SBR if desired, only
2289c336f61SJacky Bai 	 * required if SBR instantiated.
2299c336f61SJacky Bai 	 */
2309c336f61SJacky Bai 
2319c336f61SJacky Bai 	/*
2329c336f61SJacky Bai 	 * set SWCTL.sw_done to enable quasi-dynamic register programming
2339c336f61SJacky Bai 	 * outside reset.
2349c336f61SJacky Bai 	 */
2359c336f61SJacky Bai 	mmio_write_32(DDRC_SWCTL(0), 0x1);
2369c336f61SJacky Bai 
2379c336f61SJacky Bai 	/* wait SWSTAT.sw_done_ack to 1 */
2389c336f61SJacky Bai 	while (!(mmio_read_32(DDRC_SWSTAT(0)) & 0x1)) {
2399c336f61SJacky Bai 		;
2409c336f61SJacky Bai 	}
2419c336f61SJacky Bai }
242