1 /* 2 * Copyright 2008-2012 Freescale Semiconductor, Inc. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * Version 2 as published by the Free Software Foundation. 7 */ 8 9 #include <common.h> 10 #include <asm/fsl_law.h> 11 #include <div64.h> 12 13 #include <fsl_ddr.h> 14 #include <asm/io.h> 15 16 /* To avoid 64-bit full-divides, we factor this here */ 17 #define ULL_2E12 2000000000000ULL 18 #define UL_5POW12 244140625UL 19 #define UL_2POW13 (1UL << 13) 20 21 #define ULL_8FS 0xFFFFFFFFULL 22 23 /* 24 * Round up mclk_ps to nearest 1 ps in memory controller code 25 * if the error is 0.5ps or more. 26 * 27 * If an imprecise data rate is too high due to rounding error 28 * propagation, compute a suitably rounded mclk_ps to compute 29 * a working memory controller configuration. 30 */ 31 unsigned int get_memory_clk_period_ps(void) 32 { 33 unsigned int data_rate = get_ddr_freq(0); 34 unsigned int result; 35 36 /* Round to nearest 10ps, being careful about 64-bit multiply/divide */ 37 unsigned long long rem, mclk_ps = ULL_2E12; 38 39 /* Now perform the big divide, the result fits in 32-bits */ 40 rem = do_div(mclk_ps, data_rate); 41 result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps; 42 43 return result; 44 } 45 46 /* Convert picoseconds into DRAM clock cycles (rounding up if needed). */ 47 unsigned int picos_to_mclk(unsigned int picos) 48 { 49 unsigned long long clks, clks_rem; 50 unsigned long data_rate = get_ddr_freq(0); 51 52 /* Short circuit for zero picos */ 53 if (!picos) 54 return 0; 55 56 /* First multiply the time by the data rate (32x32 => 64) */ 57 clks = picos * (unsigned long long)data_rate; 58 /* 59 * Now divide by 5^12 and track the 32-bit remainder, then divide 60 * by 2*(2^12) using shifts (and updating the remainder). 61 */ 62 clks_rem = do_div(clks, UL_5POW12); 63 clks_rem += (clks & (UL_2POW13-1)) * UL_5POW12; 64 clks >>= 13; 65 66 /* If we had a remainder greater than the 1ps error, then round up */ 67 if (clks_rem > data_rate) 68 clks++; 69 70 /* Clamp to the maximum representable value */ 71 if (clks > ULL_8FS) 72 clks = ULL_8FS; 73 return (unsigned int) clks; 74 } 75 76 unsigned int mclk_to_picos(unsigned int mclk) 77 { 78 return get_memory_clk_period_ps() * mclk; 79 } 80 81 void 82 __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, 83 unsigned int law_memctl, 84 unsigned int ctrl_num) 85 { 86 unsigned long long base = memctl_common_params->base_address; 87 unsigned long long size = memctl_common_params->total_mem; 88 89 /* 90 * If no DIMMs on this controller, do not proceed any further. 91 */ 92 if (!memctl_common_params->ndimms_present) { 93 return; 94 } 95 96 #if !defined(CONFIG_PHYS_64BIT) 97 if (base >= CONFIG_MAX_MEM_MAPPED) 98 return; 99 if ((base + size) >= CONFIG_MAX_MEM_MAPPED) 100 size = CONFIG_MAX_MEM_MAPPED - base; 101 #endif 102 if (set_ddr_laws(base, size, law_memctl) < 0) { 103 printf("%s: ERROR (ctrl #%d, TRGT ID=%x)\n", __func__, ctrl_num, 104 law_memctl); 105 return ; 106 } 107 debug("setup ddr law base = 0x%llx, size 0x%llx, TRGT_ID 0x%x\n", 108 base, size, law_memctl); 109 } 110 111 __attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void 112 fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, 113 unsigned int memctl_interleaved, 114 unsigned int ctrl_num); 115 116 void fsl_ddr_set_intl3r(const unsigned int granule_size) 117 { 118 #ifdef CONFIG_E6500 119 u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); 120 *mcintl3r = 0x80000000 | (granule_size & 0x1f); 121 debug("Enable MCINTL3R with granule size 0x%x\n", granule_size); 122 #endif 123 } 124 125 u32 fsl_ddr_get_intl3r(void) 126 { 127 u32 val = 0; 128 #ifdef CONFIG_E6500 129 u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); 130 val = *mcintl3r; 131 #endif 132 return val; 133 } 134 135 void board_add_ram_info(int use_default) 136 { 137 ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_FSL_DDR_ADDR); 138 139 #if defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3) 140 u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); 141 #endif 142 #if (CONFIG_NUM_DDR_CONTROLLERS > 1) 143 uint32_t cs0_config = in_be32(&ddr->cs0_config); 144 #endif 145 uint32_t sdram_cfg = in_be32(&ddr->sdram_cfg); 146 int cas_lat; 147 148 #if CONFIG_NUM_DDR_CONTROLLERS >= 2 149 if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) { 150 ddr = (void __iomem *)CONFIG_SYS_FSL_DDR2_ADDR; 151 sdram_cfg = in_be32(&ddr->sdram_cfg); 152 } 153 #endif 154 #if CONFIG_NUM_DDR_CONTROLLERS >= 3 155 if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) { 156 ddr = (void __iomem *)CONFIG_SYS_FSL_DDR3_ADDR; 157 sdram_cfg = in_be32(&ddr->sdram_cfg); 158 } 159 #endif 160 puts(" (DDR"); 161 switch ((sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >> 162 SDRAM_CFG_SDRAM_TYPE_SHIFT) { 163 case SDRAM_TYPE_DDR1: 164 puts("1"); 165 break; 166 case SDRAM_TYPE_DDR2: 167 puts("2"); 168 break; 169 case SDRAM_TYPE_DDR3: 170 puts("3"); 171 break; 172 default: 173 puts("?"); 174 break; 175 } 176 177 if (sdram_cfg & SDRAM_CFG_32_BE) 178 puts(", 32-bit"); 179 else if (sdram_cfg & SDRAM_CFG_16_BE) 180 puts(", 16-bit"); 181 else 182 puts(", 64-bit"); 183 184 /* Calculate CAS latency based on timing cfg values */ 185 cas_lat = ((in_be32(&ddr->timing_cfg_1) >> 16) & 0xf) + 1; 186 if ((in_be32(&ddr->timing_cfg_3) >> 12) & 1) 187 cas_lat += (8 << 1); 188 printf(", CL=%d", cas_lat >> 1); 189 if (cas_lat & 0x1) 190 puts(".5"); 191 192 if (sdram_cfg & SDRAM_CFG_ECC_EN) 193 puts(", ECC on)"); 194 else 195 puts(", ECC off)"); 196 197 #if (CONFIG_NUM_DDR_CONTROLLERS == 3) 198 #ifdef CONFIG_E6500 199 if (*mcintl3r & 0x80000000) { 200 puts("\n"); 201 puts(" DDR Controller Interleaving Mode: "); 202 switch (*mcintl3r & 0x1f) { 203 case FSL_DDR_3WAY_1KB_INTERLEAVING: 204 puts("3-way 1KB"); 205 break; 206 case FSL_DDR_3WAY_4KB_INTERLEAVING: 207 puts("3-way 4KB"); 208 break; 209 case FSL_DDR_3WAY_8KB_INTERLEAVING: 210 puts("3-way 8KB"); 211 break; 212 default: 213 puts("3-way UNKNOWN"); 214 break; 215 } 216 } 217 #endif 218 #endif 219 #if (CONFIG_NUM_DDR_CONTROLLERS >= 2) 220 if (cs0_config & 0x20000000) { 221 puts("\n"); 222 puts(" DDR Controller Interleaving Mode: "); 223 224 switch ((cs0_config >> 24) & 0xf) { 225 case FSL_DDR_CACHE_LINE_INTERLEAVING: 226 puts("cache line"); 227 break; 228 case FSL_DDR_PAGE_INTERLEAVING: 229 puts("page"); 230 break; 231 case FSL_DDR_BANK_INTERLEAVING: 232 puts("bank"); 233 break; 234 case FSL_DDR_SUPERBANK_INTERLEAVING: 235 puts("super-bank"); 236 break; 237 default: 238 puts("invalid"); 239 break; 240 } 241 } 242 #endif 243 244 if ((sdram_cfg >> 8) & 0x7f) { 245 puts("\n"); 246 puts(" DDR Chip-Select Interleaving Mode: "); 247 switch(sdram_cfg >> 8 & 0x7f) { 248 case FSL_DDR_CS0_CS1_CS2_CS3: 249 puts("CS0+CS1+CS2+CS3"); 250 break; 251 case FSL_DDR_CS0_CS1: 252 puts("CS0+CS1"); 253 break; 254 case FSL_DDR_CS2_CS3: 255 puts("CS2+CS3"); 256 break; 257 case FSL_DDR_CS0_CS1_AND_CS2_CS3: 258 puts("CS0+CS1 and CS2+CS3"); 259 break; 260 default: 261 puts("invalid"); 262 break; 263 } 264 } 265 } 266