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