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