88 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Copyright 2018 NXP
 | |
|  *
 | |
|  * SPDX-License-Identifier: GPL-2.0+
 | |
|  */
 | |
| #include <common.h>
 | |
| #include <linux/kernel.h>
 | |
| #include <asm/arch/imx8m_ddr.h>
 | |
| #include <asm/arch/lpddr4_define.h>
 | |
| 
 | |
| void ddr_cfg_phy(struct dram_timing_info *dram_timing)
 | |
| {
 | |
| 	struct dram_cfg_param *dram_cfg;
 | |
| 	struct dram_fsp_msg *fsp_msg;
 | |
| 	unsigned int num;
 | |
| 	int i = 0;
 | |
| 	int j = 0;
 | |
| 
 | |
| 	/* initialize PHY configuration */
 | |
| 	dram_cfg = dram_timing->ddrphy_cfg;
 | |
| 	num  = dram_timing->ddrphy_cfg_num;
 | |
| 	for (i = 0; i < num; i++) {
 | |
| 		/* config phy reg */
 | |
| 		dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val);
 | |
| 		dram_cfg++;
 | |
| 	}
 | |
| 
 | |
| 	/* load the frequency setpoint message block config */
 | |
| 	fsp_msg = dram_timing->fsp_msg;
 | |
| 	for (i = 0; i < dram_timing->fsp_msg_num; i++) {
 | |
| 		printf("DRAM PHY training for %dMTS\n", fsp_msg->drate);
 | |
| 		/* set dram PHY input clocks to desired frequency */
 | |
| 		ddrphy_init_set_dfi_clk(fsp_msg->drate);
 | |
| 
 | |
| 		/* load the dram training firmware image */
 | |
| 		dwc_ddrphy_apb_wr(0xd0000,0x0);
 | |
| 		ddr_load_train_firmware(fsp_msg->fw_type);
 | |
| 
 | |
| 		/* load the frequency set point message block parameter */
 | |
| 		dram_cfg = fsp_msg->fsp_cfg;
 | |
| 		num = fsp_msg->fsp_cfg_num;
 | |
| 		for (j = 0; j < num; j++) {
 | |
| 			dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val);
 | |
| 			dram_cfg++;
 | |
| 		}
 | |
| 
 | |
| 		/*
 | |
| 		 * -------------------- excute the firmware --------------------
 | |
| 		 * Running the firmware is a simply process to taking the
 | |
| 		 * PMU out of reset and stall, then the firwmare will be run
 | |
| 		 * 1. reset the PMU;
 | |
| 		 * 2. begin the excution;
 | |
| 		 * 3. wait for the training done;
 | |
| 		 * 4. read the message block result.
 | |
| 		 * -------------------------------------------------------------
 | |
| 		 */
 | |
| 		dwc_ddrphy_apb_wr(0xd0000, 0x1);
 | |
| 		dwc_ddrphy_apb_wr(0xd0099, 0x9);
 | |
| 		dwc_ddrphy_apb_wr(0xd0099, 0x1);
 | |
| 		dwc_ddrphy_apb_wr(0xd0099, 0x0);
 | |
| 
 | |
| 		/* Wait for the training firmware to complete */
 | |
| 		wait_ddrphy_training_complete();
 | |
| 
 | |
| 		/* Halt the microcontroller. */
 | |
| 		dwc_ddrphy_apb_wr(0xd0099, 0x1);
 | |
| 
 | |
| 		/* Read the Message Block results */
 | |
| 		dwc_ddrphy_apb_wr(0xd0000, 0x0);
 | |
| 		ddrphy_init_read_msg_block(fsp_msg->fw_type);
 | |
| 		dwc_ddrphy_apb_wr(0xd0000, 0x1);
 | |
| 
 | |
| 		fsp_msg++;
 | |
| 	}
 | |
| 
 | |
| 	/* Load PHY Init Engine Image */
 | |
| 	dram_cfg = dram_timing->ddrphy_pie;
 | |
| 	num = dram_timing->ddrphy_pie_num;
 | |
| 	for (i = 0; i < num; i++) {
 | |
| 		dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val);
 | |
| 		dram_cfg++;
 | |
| 	}
 | |
| 
 | |
| 	/* save the ddr PHY trained CSR in memory for low power use */
 | |
| 	ddrphy_trained_csr_save(dram_timing->ddrphy_trained_csr,
 | |
| 				dram_timing->ddrphy_trained_csr_num);
 | |
| }
 |