1 /* 2 * Copyright 2021-2022 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #include <errno.h> 9 #include <stdint.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 13 #include <common/debug.h> 14 #include <ddr.h> 15 #include <immap.h> 16 #include <lib/mmio.h> 17 18 #define UL_5POW12 244140625UL 19 #define ULL_2E12 2000000000000ULL 20 #define UL_2POW13 (1UL << 13) 21 #define ULL_8FS 0xFFFFFFFFULL 22 23 #define do_div(n, base) ({ \ 24 unsigned int __base = (base); \ 25 unsigned int __rem; \ 26 __rem = ((unsigned long long)(n)) % __base; \ 27 (n) = ((unsigned long long)(n)) / __base; \ 28 __rem; \ 29 }) 30 31 #define CCN_HN_F_SAM_NODEID_MASK 0x7f 32 #ifdef NXP_HAS_CCN504 33 #define CCN_HN_F_SAM_NODEID_DDR0 0x4 34 #define CCN_HN_F_SAM_NODEID_DDR1 0xe 35 #elif defined(NXP_HAS_CCN508) 36 #define CCN_HN_F_SAM_NODEID_DDR0_0 0x3 37 #define CCN_HN_F_SAM_NODEID_DDR0_1 0x8 38 #define CCN_HN_F_SAM_NODEID_DDR1_0 0x13 39 #define CCN_HN_F_SAM_NODEID_DDR1_1 0x18 40 #endif 41 42 unsigned long get_ddr_freq(struct sysinfo *sys, int ctrl_num) 43 { 44 if (sys->freq_ddr_pll0 == 0) { 45 get_clocks(sys); 46 } 47 48 switch (ctrl_num) { 49 case 0: 50 return sys->freq_ddr_pll0; 51 case 1: 52 return sys->freq_ddr_pll0; 53 case 2: 54 return sys->freq_ddr_pll1; 55 } 56 57 return 0; 58 } 59 60 unsigned int get_memory_clk_ps(const unsigned long data_rate) 61 { 62 unsigned int result; 63 /* Round to nearest 10ps, being careful about 64-bit multiply/divide */ 64 unsigned long long rem, mclk_ps = ULL_2E12; 65 66 /* Now perform the big divide, the result fits in 32-bits */ 67 rem = do_div(mclk_ps, data_rate); 68 result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps; 69 70 return result; 71 } 72 73 unsigned int picos_to_mclk(unsigned long data_rate, unsigned int picos) 74 { 75 unsigned long long clks, clks_rem; 76 77 /* Short circuit for zero picos */ 78 if ((picos == 0U) || (data_rate == 0UL)) { 79 return 0U; 80 } 81 82 /* First multiply the time by the data rate (32x32 => 64) */ 83 clks = picos * (unsigned long long)data_rate; 84 /* 85 * Now divide by 5^12 and track the 32-bit remainder, then divide 86 * by 2*(2^12) using shifts (and updating the remainder). 87 */ 88 clks_rem = do_div(clks, UL_5POW12); 89 clks_rem += (clks & (UL_2POW13-1)) * UL_5POW12; 90 clks >>= 13U; 91 92 /* If we had a remainder greater than the 1ps error, then round up */ 93 if (clks_rem > data_rate) { 94 clks++; 95 } 96 97 /* Clamp to the maximum representable value */ 98 if (clks > ULL_8FS) { 99 clks = ULL_8FS; 100 } 101 return (unsigned int) clks; 102 } 103 104 /* valid_spd_mask has been checked by parse_spd */ 105 int disable_unused_ddrc(struct ddr_info *priv, 106 int valid_spd_mask, uintptr_t nxp_ccn_hn_f0_addr) 107 { 108 #if defined(NXP_HAS_CCN504) || defined(NXP_HAS_CCN508) 109 void *hnf_sam_ctrl = (void *)(nxp_ccn_hn_f0_addr + CCN_HN_F_SAM_CTL); 110 uint32_t val, nodeid; 111 #ifdef NXP_HAS_CCN504 112 uint32_t num_hnf_nodes = 4U; 113 #else 114 uint32_t num_hnf_nodes = 8U; 115 #endif 116 int disable_ddrc = 0; 117 int i; 118 119 if (priv->num_ctlrs < 2) { 120 debug("%s: nothing to do.\n", __func__); 121 } 122 123 switch (priv->dimm_on_ctlr) { 124 case 1: 125 disable_ddrc = ((valid_spd_mask &0x2) == 0) ? 2 : 0; 126 disable_ddrc = ((valid_spd_mask &0x1) == 0) ? 1 : disable_ddrc; 127 break; 128 case 2: 129 disable_ddrc = ((valid_spd_mask &0x4) == 0) ? 2 : 0; 130 disable_ddrc = ((valid_spd_mask &0x1) == 0) ? 1 : disable_ddrc; 131 break; 132 default: 133 ERROR("Invalid number of DIMMs %d\n", priv->dimm_on_ctlr); 134 return -EINVAL; 135 } 136 137 if (disable_ddrc != 0) { 138 debug("valid_spd_mask = 0x%x\n", valid_spd_mask); 139 } 140 141 switch (disable_ddrc) { 142 case 1: 143 priv->num_ctlrs = 1; 144 priv->spd_addr = &priv->spd_addr[priv->dimm_on_ctlr]; 145 priv->ddr[0] = priv->ddr[1]; 146 priv->ddr[1] = NULL; 147 priv->phy[0] = priv->phy[0]; 148 priv->phy[1] = NULL; 149 debug("Disable first DDR controller\n"); 150 break; 151 case 2: 152 priv->num_ctlrs = 1; 153 priv->ddr[1] = NULL; 154 priv->phy[1] = NULL; 155 debug("Disable second DDR controller\n"); 156 /* fallthrough */ 157 case 0: 158 break; 159 default: 160 ERROR("Program error.\n"); 161 return -EINVAL; 162 } 163 164 if (disable_ddrc == 0) { 165 debug("Both controllers in use.\n"); 166 return 0; 167 } 168 169 for (i = 0; i < num_hnf_nodes; i++) { 170 val = mmio_read_64((uintptr_t)hnf_sam_ctrl); 171 #ifdef NXP_HAS_CCN504 172 nodeid = disable_ddrc == 1 ? CCN_HN_F_SAM_NODEID_DDR1 : 173 (disable_ddrc == 2 ? CCN_HN_F_SAM_NODEID_DDR0 : 174 0x0); /*Failure condition. never hit */ 175 #elif defined(NXP_HAS_CCN508) 176 if (disable_ddrc == 1) { 177 nodeid = (i < 2 || i >= 6) ? CCN_HN_F_SAM_NODEID_DDR1_1 : 178 CCN_HN_F_SAM_NODEID_DDR1_0; 179 } else if (disable_ddrc == 2) { 180 nodeid = (i < 2 || i >= 6) ? CCN_HN_F_SAM_NODEID_DDR0_0 : 181 CCN_HN_F_SAM_NODEID_DDR0_1; 182 } else { 183 nodeid = 0; /* Failure condition. never hit */ 184 } 185 #endif 186 if (nodeid != (val & CCN_HN_F_SAM_NODEID_MASK)) { 187 debug("Setting HN-F node %d\n", i); 188 debug("nodeid = 0x%x\n", nodeid); 189 val &= ~CCN_HN_F_SAM_NODEID_MASK; 190 val |= nodeid; 191 mmio_write_64((uintptr_t)hnf_sam_ctrl, val); 192 } 193 hnf_sam_ctrl += CCN_HN_F_REGION_SIZE; 194 } 195 #endif 196 return 0; 197 } 198 199 unsigned int get_ddrc_version(const struct ccsr_ddr *ddr) 200 { 201 unsigned int ver; 202 203 ver = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8U; 204 ver |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8U; 205 206 return ver; 207 } 208 209 void print_ddr_info(struct ccsr_ddr *ddr) 210 { 211 unsigned int cs0_config = ddr_in32(&ddr->csn_cfg[0]); 212 unsigned int sdram_cfg = ddr_in32(&ddr->sdram_cfg); 213 int cas_lat; 214 215 if ((sdram_cfg & SDRAM_CFG_MEM_EN) == 0U) { 216 printf(" (DDR not enabled)\n"); 217 return; 218 } 219 220 printf("DDR"); 221 switch ((sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >> 222 SDRAM_CFG_SDRAM_TYPE_SHIFT) { 223 case SDRAM_TYPE_DDR4: 224 printf("4"); 225 break; 226 default: 227 printf("?"); 228 break; 229 } 230 231 switch (sdram_cfg & SDRAM_CFG_DBW_MASK) { 232 case SDRAM_CFG_32_BW: 233 printf(", 32-bit"); 234 break; 235 case SDRAM_CFG_16_BW: 236 printf(", 16-bit"); 237 break; 238 case SDRAM_CFG_8_BW: 239 printf(", 8-bit"); 240 break; 241 default: 242 printf(", 64-bit"); 243 break; 244 } 245 246 /* Calculate CAS latency based on timing cfg values */ 247 cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf); 248 cas_lat += 2; /* for DDRC newer than 4.4 */ 249 cas_lat += ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 3) << 4; 250 printf(", CL=%d", cas_lat >> 1); 251 if ((cas_lat & 0x1) != 0) { 252 printf(".5"); 253 } 254 255 if ((sdram_cfg & SDRAM_CFG_ECC_EN) != 0) { 256 printf(", ECC on"); 257 } else { 258 printf(", ECC off"); 259 } 260 261 if ((cs0_config & 0x20000000) != 0) { 262 printf(", "); 263 switch ((cs0_config >> 24) & 0xf) { 264 case DDR_256B_INTLV: 265 printf("256B"); 266 break; 267 default: 268 printf("invalid"); 269 break; 270 } 271 } 272 273 if (((sdram_cfg >> 8) & 0x7f) != 0) { 274 printf(", "); 275 switch (sdram_cfg >> 8 & 0x7f) { 276 case DDR_BA_INTLV_CS0123: 277 printf("CS0+CS1+CS2+CS3"); 278 break; 279 case DDR_BA_INTLV_CS01: 280 printf("CS0+CS1"); 281 break; 282 default: 283 printf("invalid"); 284 break; 285 } 286 } 287 printf("\n"); 288 } 289