1 /* 2 * Copyright 2018-2022 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 10 #include <common/debug.h> 11 #include <ddr.h> 12 #include <lib/utils.h> 13 14 #include <errata.h> 15 16 static const struct rc_timing rce[] = { 17 {U(1600), U(8), U(7)}, 18 {U(1867), U(8), U(7)}, 19 {U(2134), U(8), U(9)}, 20 {} 21 }; 22 23 static const struct board_timing udimm[] = { 24 {U(0x04), rce, U(0x01020304), U(0x06070805)}, 25 }; 26 27 int ddr_board_options(struct ddr_info *priv) 28 { 29 int ret; 30 struct memctl_opt *popts = &priv->opt; 31 32 if (popts->rdimm) { 33 debug("RDIMM parameters not set.\n"); 34 return -EINVAL; 35 } 36 37 ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm)); 38 if (ret != 0) { 39 return ret; 40 } 41 42 popts->wrlvl_override = U(1); 43 popts->wrlvl_sample = U(0x0); /* 32 clocks */ 44 popts->ddr_cdr1 = DDR_CDR1_DHC_EN | 45 DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); 46 popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | 47 DDR_CDR2_VREF_TRAIN_EN | 48 DDR_CDR2_VREF_RANGE_2; 49 50 /* optimize cpo for erratum A-009942 */ 51 popts->cpo_sample = U(0x70); 52 53 return 0; 54 } 55 56 long long init_ddr(void) 57 { 58 int spd_addr[] = { NXP_SPD_EEPROM0 }; 59 struct ddr_info info; 60 struct sysinfo sys; 61 long long dram_size; 62 63 zeromem(&sys, sizeof(sys)); 64 if (get_clocks(&sys)) { 65 ERROR("System clocks are not set\n"); 66 assert(0); 67 } 68 debug("platform clock %lu\n", sys.freq_platform); 69 debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0); 70 debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1); 71 72 zeromem(&info, sizeof(struct ddr_info)); 73 info.num_ctlrs = 1; 74 info.dimm_on_ctlr = 1; 75 info.clk = get_ddr_freq(&sys, 0); 76 info.spd_addr = spd_addr; 77 info.ddr[0] = (void *)NXP_DDR_ADDR; 78 79 dram_size = dram_init(&info); 80 81 if (dram_size < 0) { 82 ERROR("DDR init failed.\n"); 83 } 84 85 #ifdef ERRATA_SOC_A008850 86 erratum_a008850_post(); 87 #endif 88 89 return dram_size; 90 } 91