1// SPDX-License-Identifier: GPL-2.0+ OR MIT 2/* 3 * Copyright 2021 NXP 4 */ 5#include <common.h> 6#include <asm/io.h> 7#include <asm/arch/clock.h> 8#include <asm/arch/ddr.h> 9#include <asm/arch/imx-regs.h> 10 11#define DENALI_CTL_00 (DDR_CTL_BASE_ADDR + 4 * 0) 12#define CTL_START 0x1 13 14#define DENALI_CTL_03 (DDR_CTL_BASE_ADDR + 4 * 3) 15#define DENALI_CTL_197 (DDR_CTL_BASE_ADDR + 4 * 197) 16#define DENALI_CTL_250 (DDR_CTL_BASE_ADDR + 4 * 250) 17#define DENALI_CTL_251 (DDR_CTL_BASE_ADDR + 4 * 251) 18#define DENALI_CTL_266 (DDR_CTL_BASE_ADDR + 4 * 266) 19#define DFI_INIT_COMPLETE 0x2 20 21#define DENALI_CTL_614 (DDR_CTL_BASE_ADDR + 4 * 614) 22#define DENALI_CTL_615 (DDR_CTL_BASE_ADDR + 4 * 615) 23 24#define DENALI_PI_00 (DDR_PI_BASE_ADDR + 4 * 0) 25#define PI_START 0x1 26 27#define DENALI_PI_04 (DDR_PI_BASE_ADDR + 4 * 4) 28#define DENALI_PI_11 (DDR_PI_BASE_ADDR + 4 * 11) 29#define DENALI_PI_12 (DDR_PI_BASE_ADDR + 4 * 12) 30#define DENALI_CTL_23 (DDR_CTL_BASE_ADDR + 4 * 23) 31#define DENALI_CTL_25 (DDR_CTL_BASE_ADDR + 4 * 25) 32 33#define DENALI_PHY_1624 (DDR_PHY_BASE_ADDR + 4 * 1624) 34#define DENALI_PHY_1625 (DDR_PHY_BASE_ADDR + 4 * 1625) 35#define DENALI_PHY_1537 (DDR_PHY_BASE_ADDR + 4 * 1537) 36#define PHY_FREQ_SEL_MULTICAST_EN(X) ((X) << 8) 37#define PHY_FREQ_SEL_INDEX(X) ((X) << 16) 38 39#define DENALI_PHY_1547 (DDR_PHY_BASE_ADDR + 4 * 1547) 40#define DENALI_PHY_1555 (DDR_PHY_BASE_ADDR + 4 * 1555) 41#define DENALI_PHY_1564 (DDR_PHY_BASE_ADDR + 4 * 1564) 42#define DENALI_PHY_1565 (DDR_PHY_BASE_ADDR + 4 * 1565) 43 44static void ddr_enable_pll_bypass(void) 45{ 46 u32 reg_val; 47 48 /* PI_INIT_LVL_EN=0x0 (DENALI_PI_04) */ 49 reg_val = readl(DENALI_PI_04) & ~0x1; 50 writel(reg_val, DENALI_PI_04); 51 52 /* PI_FREQ_MAP=0x1 (DENALI_PI_12) */ 53 writel(0x1, DENALI_PI_12); 54 55 /* PI_INIT_WORK_FREQ=0x0 (DENALI_PI_11) */ 56 reg_val = readl(DENALI_PI_11) & ~(0x1f << 8); 57 writel(reg_val, DENALI_PI_11); 58 59 /* DFIBUS_FREQ_INIT=0x0 (DENALI_CTL_23) */ 60 reg_val = readl(DENALI_CTL_23) & ~(0x3 << 24); 61 writel(reg_val, DENALI_CTL_23); 62 63 /* PHY_LP4_BOOT_DISABLE=0x0 (DENALI_PHY_1547) */ 64 reg_val = readl(DENALI_PHY_1547) & ~(0x1 << 8); 65 writel(reg_val, DENALI_PHY_1547); 66 67 /* PHY_PLL_BYPASS=0x1 (DENALI_PHY_1624) */ 68 reg_val = readl(DENALI_PHY_1624) | 0x1; 69 writel(reg_val, DENALI_PHY_1624); 70 71 /* PHY_LP4_BOOT_PLL_BYPASS to 0x1 (DENALI_PHY_1555) */ 72 reg_val = readl(DENALI_PHY_1555) | 0x1; 73 writel(reg_val, DENALI_PHY_1555); 74 75 /* FREQ_CHANGE_TYPE_F0 = 0x0/FREQ_CHANGE_TYPE_F1 = 0x1/FREQ_CHANGE_TYPE_F2 = 0x2 */ 76 reg_val = 0x020100; 77 writel(reg_val, DENALI_CTL_25); 78} 79 80int ddr_calibration(unsigned int fsp_table[3]) 81{ 82 u32 reg_val; 83 u32 int_status_init, phy_freq_req, phy_freq_type; 84 u32 lock_0, lock_1, lock_2; 85 u32 freq_chg_pt, freq_chg_cnt; 86 u32 is_lpddr4 = 0; 87 88 if (IS_ENABLED(CONFIG_IMX8ULP_DRAM_PHY_PLL_BYPASS)) { 89 ddr_enable_pll_bypass(); 90 freq_chg_cnt = 0; 91 freq_chg_pt = 0; 92 } else { 93 reg_val = (readl(DENALI_CTL_00)>>8)&0xf; 94 if(reg_val == 0x7) { 95 /* LPDDR3 type */ 96 set_ddr_clk(fsp_table[1] >> 1); 97 freq_chg_cnt = 0; 98 freq_chg_pt = 0; 99 } else if(reg_val == 0xb) { 100 /* LPDDR4/4x type */ 101 is_lpddr4 = 1; 102 reg_val = readl(DENALI_CTL_250); 103 if (((reg_val >> 16) & 0x3) == 1) 104 freq_chg_cnt = 2; 105 else 106 freq_chg_cnt = 3; 107 108 reg_val = readl(DENALI_PI_12); 109 if(reg_val == 0x3) 110 freq_chg_pt = 1; 111 else if(reg_val == 0x7) 112 freq_chg_pt = 2; 113 else { 114 printf("frequency map(0x%x) is wrong, please check!\r\n", reg_val); 115 return -1; 116 } 117 } else { 118 printf("Incorrect DDR type configured!\r\n"); 119 return -1; 120 } 121 } 122 123 /* Assert PI_START parameter and then assert START parameter in Controller. */ 124 reg_val = readl(DENALI_PI_00) | PI_START; 125 writel(reg_val, DENALI_PI_00); 126 127 reg_val = readl(DENALI_CTL_00) | CTL_START; 128 writel(reg_val, DENALI_CTL_00); 129 130 /* Poll for init_done_bit in Controller interrupt status register (INT_STATUS_INIT) */ 131 do { 132 if (!freq_chg_cnt) { 133 int_status_init = (readl(DENALI_CTL_266) >> 8) & 0xff; 134 /* DDR subsystem is ready for traffic. */ 135 if (int_status_init & DFI_INIT_COMPLETE) { 136 debug("complete\n"); 137 break; 138 } 139 } 140 141 /* 142 * During leveling, PHY will request for freq change and SoC clock logic 143 * should provide requested frequency 144 * Polling SIM LPDDR_CTRL2 Bit phy_freq_chg_req until be 1'b1 145 */ 146 reg_val = readl(AVD_SIM_LPDDR_CTRL2); 147 /* DFS interrupt is set */ 148 phy_freq_req = ((reg_val >> 7) & 0x1) && ((reg_val >> 15) & 0x1); 149 if (phy_freq_req) { 150 phy_freq_type = reg_val & 0x1F; 151 if (phy_freq_type == 0x00) { 152 debug("Poll for freq_chg_req on SIM register and change to F0 frequency.\n"); 153 set_ddr_clk(fsp_table[phy_freq_type] >> 1); 154 155 /* Write 1'b1 at LPDDR_CTRL2 bit phy_freq_cfg_ack */ 156 reg_val = readl(AVD_SIM_LPDDR_CTRL2); 157 writel(reg_val | (0x1 << 6), AVD_SIM_LPDDR_CTRL2); 158 } else if (phy_freq_type == 0x01) { 159 debug("Poll for freq_chg_req on SIM register and change to F1 frequency.\n"); 160 set_ddr_clk(fsp_table[phy_freq_type] >> 1); 161 162 /* Write 1'b1 at LPDDR_CTRL2 bit phy_freq_cfg_ack */ 163 reg_val = readl(AVD_SIM_LPDDR_CTRL2); 164 writel(reg_val | (0x1 << 6), AVD_SIM_LPDDR_CTRL2); 165 if (freq_chg_pt == 1) 166 freq_chg_cnt--; 167 } else if (phy_freq_type == 0x02) { 168 debug("Poll for freq_chg_req on SIM register and change to F2 frequency.\n"); 169 set_ddr_clk(fsp_table[phy_freq_type] >> 1); 170 171 /* Write 1'b1 at LPDDR_CTRL2 bit phy_freq_cfg_ack */ 172 reg_val = readl(AVD_SIM_LPDDR_CTRL2); 173 writel(reg_val | (0x1 << 6), AVD_SIM_LPDDR_CTRL2); 174 if (freq_chg_pt == 2) 175 freq_chg_cnt--; 176 } 177 178 /* Hardware clear the ack on falling edge of LPDDR_CTRL2:phy_freq_chg_reg */ 179 /* Ensure the ack is clear before starting to poll request again */ 180 while ((readl(AVD_SIM_LPDDR_CTRL2) & BIT(6))) 181 ; 182 } 183 } while (1); 184 185 /* Check PLL lock status */ 186 lock_0 = readl(DENALI_PHY_1564) & 0xffff; 187 lock_1 = (readl(DENALI_PHY_1564) >> 16) & 0xffff; 188 lock_2 = readl(DENALI_PHY_1565) & 0xffff; 189 190 if ((lock_0 & 0x3) != 0x3 || (lock_1 & 0x3) != 0x3 || (lock_2 & 0x3) != 0x3) { 191 debug("De-Skew PLL failed to lock\n"); 192 debug("lock_0=0x%x, lock_1=0x%x, lock_2=0x%x\n", lock_0, lock_1, lock_2); 193 return -1; 194 } 195 196 debug("De-Skew PLL is locked and ready\n"); 197 198 /* Change LPDDR4 FREQ1 to bypass mode if it is lower than 200MHz */ 199 if(is_lpddr4 && fsp_table[1] < 400) { 200 /* Set FREQ1 to bypass mode */ 201 reg_val = PHY_FREQ_SEL_MULTICAST_EN(0) | PHY_FREQ_SEL_INDEX(0); 202 writel(reg_val, DENALI_PHY_1537); 203 204 /* PHY_PLL_BYPASS=0x1 (DENALI_PHY_1624) */ 205 reg_val =readl(DENALI_PHY_1624) | 0x1; 206 writel(reg_val, DENALI_PHY_1624); 207 208 /* DENALI_PHY_1625: bypass mode in PHY PLL */ 209 reg_val =readl(DENALI_PHY_1625) & ~0xf; 210 writel(reg_val, DENALI_PHY_1625); 211 } 212 213 return 0; 214} 215 216static void save_dram_config(struct dram_timing_info2 *timing_info, unsigned long saved_timing_base) 217{ 218 int i = 0; 219 struct dram_timing_info2 *saved_timing = (struct dram_timing_info2 *)saved_timing_base; 220 struct dram_cfg_param *cfg; 221 222 saved_timing->ctl_cfg_num = timing_info->ctl_cfg_num; 223 saved_timing->phy_f1_cfg_num = timing_info->phy_f1_cfg_num; 224 saved_timing->phy_f2_cfg_num = timing_info->phy_f2_cfg_num; 225 226 /* save the fsp table */ 227 for (i = 0; i < 3; i++) 228 saved_timing->fsp_table[i] = timing_info->fsp_table[i]; 229 230 cfg = (struct dram_cfg_param *)(saved_timing_base + 231 sizeof(*timing_info)); 232 233 /* save ctl config */ 234 saved_timing->ctl_cfg = cfg; 235 for (i = 0; i < timing_info->ctl_cfg_num; i++) { 236 cfg->reg = timing_info->ctl_cfg[i].reg; 237 cfg->val = timing_info->ctl_cfg[i].val; 238 cfg++; 239 } 240 241 /* save phy f1 config */ 242 saved_timing->phy_f1_cfg = cfg; 243 for (i = 0; i < timing_info->phy_f1_cfg_num; i++) { 244 cfg->reg = timing_info->phy_f1_cfg[i].reg; 245 cfg->val = timing_info->phy_f1_cfg[i].val; 246 cfg++; 247 } 248 249 /* save phy f2 config */ 250 saved_timing->phy_f2_cfg = cfg; 251 for (i = 0; i < timing_info->phy_f2_cfg_num; i++) { 252 cfg->reg = timing_info->phy_f2_cfg[i].reg; 253 cfg->val = timing_info->phy_f2_cfg[i].val; 254 cfg++; 255 } 256} 257 258int ddr_init(struct dram_timing_info2 *dram_timing) 259{ 260 int i; 261 262 if (IS_ENABLED(CONFIG_IMX8ULP_DRAM_PHY_PLL_BYPASS)) { 263 /* Use PLL bypass for boot freq */ 264 /* Since PLL can't generate the double freq, Need ddr clock to generate it. */ 265 set_ddr_clk(dram_timing->fsp_table[0]); /* Set to boot freq */ 266 setbits_le32(AVD_SIM_BASE_ADDR, 0x1); /* SIM_DDR_CTRL_DIV2_EN */ 267 } else { 268 set_ddr_clk(dram_timing->fsp_table[0] >> 1); /* Set to boot freq */ 269 clrbits_le32(AVD_SIM_BASE_ADDR, 0x1); /* SIM_DDR_CTRL_DIV2_EN */ 270 } 271 272 /* save the dram config into sram for low power mode */ 273 save_dram_config(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE); 274 275 /* Initialize CTL registers */ 276 for (i = 0; i < dram_timing->ctl_cfg_num; i++) 277 writel(dram_timing->ctl_cfg[i].val, (ulong)dram_timing->ctl_cfg[i].reg); 278 279 /* Initialize PI registers */ 280 for (i = 0; i < dram_timing->pi_cfg_num; i++) 281 writel(dram_timing->pi_cfg[i].val, (ulong)dram_timing->pi_cfg[i].reg); 282 283 /* Write PHY regiters for all 3 frequency points (48Mhz/384Mhz/528Mhz): f1_index=0 */ 284 writel(PHY_FREQ_SEL_MULTICAST_EN(1) | PHY_FREQ_SEL_INDEX(0), DENALI_PHY_1537); 285 for (i = 0; i < dram_timing->phy_f1_cfg_num; i++) 286 writel(dram_timing->phy_f1_cfg[i].val, (ulong)dram_timing->phy_f1_cfg[i].reg); 287 288 /* Write PHY regiters for freqency point 2 (528Mhz): f2_index=1 */ 289 writel(PHY_FREQ_SEL_MULTICAST_EN(0) | PHY_FREQ_SEL_INDEX(1), DENALI_PHY_1537); 290 for (i = 0; i < dram_timing->phy_f2_cfg_num; i++) 291 writel(dram_timing->phy_f2_cfg[i].val, (ulong)dram_timing->phy_f2_cfg[i].reg); 292 293 /* Re-enable MULTICAST mode */ 294 writel(PHY_FREQ_SEL_MULTICAST_EN(1) | PHY_FREQ_SEL_INDEX(0), DENALI_PHY_1537); 295 296 return ddr_calibration(dram_timing->fsp_table); 297} 298