1 /* 2 * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch_helpers.h> 8 9 #include <common/debug.h> 10 11 #include <ddrphy_phyinit.h> 12 13 /* 14 * This function implements the flow of PhyInit software to initialize the PHY. 15 * 16 * The execution sequence follows the overview figure provided in the Reference Manual. 17 * 18 * \returns 0 on completion of the sequence, EXIT_FAILURE on error. 19 */ 20 int ddrphy_phyinit_sequence(struct stm32mp_ddr_config *config, bool skip_training, bool reten) 21 { 22 int ret; 23 uint32_t ardptrinitval; /* 24 * Represents the value stored in Step C into the register with the 25 * same name. Defined as a global variable so that implementation 26 * of ddrphy_phyinit_progcsrskiptrain() function does not require 27 * a PHY read register implementation. 28 */ 29 struct pmu_smb_ddr_1d mb_ddr_1d; /* Firmware 1D Message Block structure */ 30 31 /* Check user input pstate number consistency vs. SW capabilities */ 32 if (config->uib.numpstates > 1U) { 33 return -1; 34 } 35 36 /* Initialize structures */ 37 ddrphy_phyinit_initstruct(config, &mb_ddr_1d); 38 39 /* Re-calculate Firmware Message Block input based on final user input */ 40 ret = ddrphy_phyinit_calcmb(config, &mb_ddr_1d); 41 if (ret != 0) { 42 return ret; 43 } 44 45 /* (A) Bring up VDD, VDDQ, and VAA */ 46 /* ddrphy_phyinit_usercustom_a_bringuppower(); */ 47 48 /* (B) Start Clocks and Reset the PHY */ 49 /* ddrphy_phyinit_usercustom_b_startclockresetphy(); */ 50 51 /* (C) Initialize PHY Configuration */ 52 ret = ddrphy_phyinit_c_initphyconfig(config, &mb_ddr_1d, &ardptrinitval); 53 if (ret != 0) { 54 return ret; 55 } 56 /* 57 * Customize any register write desired; This can include any CSR not covered by PhyInit 58 * or user wish to override values calculated in step_C. 59 */ 60 ddrphy_phyinit_usercustom_custompretrain(config); 61 62 /* Stop retention register tracking for training firmware related registers */ 63 ret = ddrphy_phyinit_reginterface(STOPTRACK, 0U, 0U); 64 if (ret != 0) { 65 return ret; 66 } 67 68 if (skip_training) { 69 /* Skip running training firmware entirely */ 70 ddrphy_phyinit_progcsrskiptrain(config, &mb_ddr_1d, ardptrinitval); 71 } else { 72 /* (D) Load the IMEM Memory for 1D training */ 73 ddrphy_phyinit_d_loadimem(); 74 75 /* (E) Set the PHY input clocks to the desired frequency */ 76 /* ddrphy_phyinit_usercustom_e_setdficlk(pstate); */ 77 78 /* (F) Write the Message Block parameters for the training firmware */ 79 ret = ddrphy_phyinit_f_loaddmem(config, &mb_ddr_1d); 80 if (ret != 0) { 81 return ret; 82 } 83 84 /* (G) Execute the Training Firmware */ 85 ret = ddrphy_phyinit_g_execfw(); 86 if (ret != 0) { 87 return ret; 88 } 89 90 /* (H) Read the Message Block results */ 91 /* ddrphy_phyinit_h_readmsgblock(); */ 92 } 93 94 /* Start retention register tracking for training firmware related registers */ 95 ret = ddrphy_phyinit_reginterface(STARTTRACK, 0U, 0U); 96 if (ret != 0) { 97 return ret; 98 } 99 100 /* (I) Load PHY Init Engine Image */ 101 ddrphy_phyinit_i_loadpieimage(config, skip_training); 102 103 /* 104 * Customize any CSR write desired to override values programmed by firmware or 105 * ddrphy_phyinit_i_loadpieimage() 106 */ 107 /* ddrphy_phyinit_usercustom_customposttrain(); */ 108 109 if (reten) { 110 /* Save value of tracked registers for retention restore sequence. */ 111 ret = ddrphy_phyinit_usercustom_saveretregs(config); 112 if (ret != 0) { 113 return ret; 114 } 115 } 116 117 /* (J) Initialize the PHY to Mission Mode through DFI Initialization */ 118 /* ddrphy_phyinit_usercustom_j_entermissionmode(); */ 119 120 return 0; 121 } 122