Commit a4c66509f1b95884e5753d5a30cf2cf884adb821

Authored by York Sun
Committed by Andy Fleming
1 parent fcea30688f

powerpc/mpc8xxx: Enable 3-way and 4-way DDR interleaving

Restructure DDR interleaving option to support 3 and 4 DDR controllers
for 2-, 3- and 4-way interleaving.

Signed-off-by: York Sun <yorksun@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>

Showing 10 changed files with 489 additions and 320 deletions Side-by-side Diff

arch/powerpc/cpu/mpc85xx/cpu.c
... ... @@ -430,9 +430,19 @@
430 430 case 0:
431 431 ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
432 432 break;
433   -#ifdef CONFIG_SYS_MPC85xx_DDR2_ADDR
  433 +#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
434 434 case 1:
435 435 ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
  436 + break;
  437 +#endif
  438 +#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
  439 + case 2:
  440 + ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
  441 + break;
  442 +#endif
  443 +#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
  444 + case 3:
  445 + ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR;
436 446 break;
437 447 #endif
438 448 default:
arch/powerpc/cpu/mpc85xx/ddr-gen3.c
... ... @@ -32,9 +32,21 @@
32 32 case 0:
33 33 ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
34 34 break;
  35 +#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
35 36 case 1:
36 37 ddr = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
37 38 break;
  39 +#endif
  40 +#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
  41 + case 2:
  42 + ddr = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
  43 + break;
  44 +#endif
  45 +#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
  46 + case 3:
  47 + ddr = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR;
  48 + break;
  49 +#endif
38 50 default:
39 51 printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
40 52 return;
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
... ... @@ -151,8 +151,19 @@
151 151 if (dimm_params[dimm_number].n_ranks > 0) {
152 152 go_config = 1;
153 153 /* These fields only available in CS0_CONFIG */
154   - intlv_en = popts->memctl_interleaving;
155   - intlv_ctl = popts->memctl_interleaving_mode;
  154 + if (!popts->memctl_interleaving)
  155 + break;
  156 + switch (popts->memctl_interleaving_mode) {
  157 + case FSL_DDR_CACHE_LINE_INTERLEAVING:
  158 + case FSL_DDR_PAGE_INTERLEAVING:
  159 + case FSL_DDR_BANK_INTERLEAVING:
  160 + case FSL_DDR_SUPERBANK_INTERLEAVING:
  161 + intlv_en = popts->memctl_interleaving;
  162 + intlv_ctl = popts->memctl_interleaving_mode;
  163 + break;
  164 + default:
  165 + break;
  166 + }
156 167 }
157 168 break;
158 169 case 1:
159 170  
160 171  
161 172  
162 173  
163 174  
164 175  
165 176  
166 177  
... ... @@ -1413,73 +1424,37 @@
1413 1424  
1414 1425 /* Chip Select Memory Bounds (CSn_BNDS) */
1415 1426 for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
1416   - unsigned long long ea = 0, sa = 0;
  1427 + unsigned long long ea, sa;
1417 1428 unsigned int cs_per_dimm
1418 1429 = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR;
1419 1430 unsigned int dimm_number
1420 1431 = i / cs_per_dimm;
1421 1432 unsigned long long rank_density
1422   - = dimm_params[dimm_number].rank_density;
  1433 + = dimm_params[dimm_number].rank_density >> dbw_cap_adj;
1423 1434  
1424   - if (((i == 1) && (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1)) ||
1425   - ((i == 2) && (popts->ba_intlv_ctl & 0x04)) ||
1426   - ((i == 3) && (popts->ba_intlv_ctl & FSL_DDR_CS2_CS3))) {
1427   - /*
1428   - * Don't set up boundaries for unused CS
1429   - * cs1 for cs0_cs1, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3
1430   - * cs2 for cs0_cs1_cs2_cs3
1431   - * cs3 for cs2_cs3, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3
1432   - * But we need to set the ODT_RD_CFG and
1433   - * ODT_WR_CFG for CS1_CONFIG here.
1434   - */
1435   - set_csn_config(dimm_number, i, ddr, popts, dimm_params);
1436   - continue;
1437   - }
1438 1435 if (dimm_params[dimm_number].n_ranks == 0) {
1439 1436 debug("Skipping setup of CS%u "
1440 1437 "because n_ranks on DIMM %u is 0\n", i, dimm_number);
1441 1438 continue;
1442 1439 }
1443   - if (popts->memctl_interleaving && popts->ba_intlv_ctl) {
1444   - /*
1445   - * This works superbank 2CS
1446   - * There are 2 or more memory controllers configured
1447   - * identically, memory is interleaved between them,
1448   - * and each controller uses rank interleaving within
1449   - * itself. Therefore the starting and ending address
1450   - * on each controller is twice the amount present on
1451   - * each controller. If any CS is not included in the
1452   - * interleaving, the memory on that CS is not accssible
1453   - * and the total memory size is reduced. The CS is also
1454   - * disabled.
1455   - */
1456   - unsigned long long ctlr_density = 0;
  1440 + if (popts->memctl_interleaving) {
1457 1441 switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
  1442 + case FSL_DDR_CS0_CS1_CS2_CS3:
  1443 + break;
1458 1444 case FSL_DDR_CS0_CS1:
1459 1445 case FSL_DDR_CS0_CS1_AND_CS2_CS3:
1460   - ctlr_density = dimm_params[0].rank_density * 2;
1461 1446 if (i > 1)
1462 1447 cs_en = 0;
1463 1448 break;
1464 1449 case FSL_DDR_CS2_CS3:
1465   - ctlr_density = dimm_params[0].rank_density;
  1450 + default:
1466 1451 if (i > 0)
1467 1452 cs_en = 0;
1468 1453 break;
1469   - case FSL_DDR_CS0_CS1_CS2_CS3:
1470   - /*
1471   - * The four CS interleaving should have been verified by
1472   - * populate_memctl_options()
1473   - */
1474   - ctlr_density = dimm_params[0].rank_density * 4;
1475   - break;
1476   - default:
1477   - break;
1478 1454 }
1479   - ea = (CONFIG_NUM_DDR_CONTROLLERS *
1480   - (ctlr_density >> dbw_cap_adj)) - 1;
1481   - }
1482   - else if (!popts->memctl_interleaving && popts->ba_intlv_ctl) {
  1455 + sa = common_dimm->base_address;
  1456 + ea = common_dimm->total_mem - 1;
  1457 + } else if (!popts->memctl_interleaving) {
1483 1458 /*
1484 1459 * If memory interleaving between controllers is NOT
1485 1460 * enabled, the starting address for each memory
1486 1461  
1487 1462  
1488 1463  
1489 1464  
1490 1465  
1491 1466  
1492 1467  
1493 1468  
1494 1469  
... ... @@ -1491,49 +1466,40 @@
1491 1466 */
1492 1467 switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
1493 1468 case FSL_DDR_CS0_CS1_CS2_CS3:
1494   - /* CS0+CS1+CS2+CS3 interleaving, only CS0_CNDS
1495   - * needs to be set.
1496   - */
1497 1469 sa = common_dimm->base_address;
1498   - ea = sa + (4 * (rank_density >> dbw_cap_adj))-1;
  1470 + ea = common_dimm->total_mem - 1;
1499 1471 break;
1500 1472 case FSL_DDR_CS0_CS1_AND_CS2_CS3:
1501   - /* CS0+CS1 and CS2+CS3 interleaving, CS0_CNDS
1502   - * and CS2_CNDS need to be set.
1503   - */
1504   - if ((i == 2) && (dimm_number == 0)) {
  1473 + if ((i >= 2) && (dimm_number == 0)) {
1505 1474 sa = dimm_params[dimm_number].base_address +
1506   - 2 * (rank_density >> dbw_cap_adj);
1507   - ea = sa + 2 * (rank_density >> dbw_cap_adj) - 1;
  1475 + 2 * rank_density;
  1476 + ea = sa + 2 * rank_density - 1;
1508 1477 } else {
1509 1478 sa = dimm_params[dimm_number].base_address;
1510   - ea = sa + (2 * (rank_density >>
1511   - dbw_cap_adj)) - 1;
  1479 + ea = sa + 2 * rank_density - 1;
1512 1480 }
1513 1481 break;
1514 1482 case FSL_DDR_CS0_CS1:
1515   - /* CS0+CS1 interleaving, CS0_CNDS needs
1516   - * to be set
1517   - */
1518 1483 if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
1519 1484 sa = dimm_params[dimm_number].base_address;
1520   - ea = sa + (rank_density >> dbw_cap_adj) - 1;
1521   - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj);
1522   - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj);
  1485 + ea = sa + rank_density - 1;
  1486 + if (i != 1)
  1487 + sa += (i % cs_per_dimm) * rank_density;
  1488 + ea += (i % cs_per_dimm) * rank_density;
1523 1489 } else {
1524 1490 sa = 0;
1525 1491 ea = 0;
1526 1492 }
1527 1493 if (i == 0)
1528   - ea += (rank_density >> dbw_cap_adj);
  1494 + ea += rank_density;
1529 1495 break;
1530 1496 case FSL_DDR_CS2_CS3:
1531   - /* CS2+CS3 interleaving*/
1532 1497 if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
1533 1498 sa = dimm_params[dimm_number].base_address;
1534   - ea = sa + (rank_density >> dbw_cap_adj) - 1;
1535   - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj);
1536   - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj);
  1499 + ea = sa + rank_density - 1;
  1500 + if (i != 3)
  1501 + sa += (i % cs_per_dimm) * rank_density;
  1502 + ea += (i % cs_per_dimm) * rank_density;
1537 1503 } else {
1538 1504 sa = 0;
1539 1505 ea = 0;
1540 1506  
... ... @@ -1542,36 +1508,16 @@
1542 1508 ea += (rank_density >> dbw_cap_adj);
1543 1509 break;
1544 1510 default: /* No bank(chip-select) interleaving */
  1511 + sa = dimm_params[dimm_number].base_address;
  1512 + ea = sa + rank_density - 1;
  1513 + if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
  1514 + sa += (i % cs_per_dimm) * rank_density;
  1515 + ea += (i % cs_per_dimm) * rank_density;
  1516 + } else {
  1517 + sa = 0;
  1518 + ea = 0;
  1519 + }
1545 1520 break;
1546   - }
1547   - }
1548   - else if (popts->memctl_interleaving && !popts->ba_intlv_ctl) {
1549   - /*
1550   - * Only the rank on CS0 of each memory controller may
1551   - * be used if memory controller interleaving is used
1552   - * without rank interleaving within each memory
1553   - * controller. However, the ending address programmed
1554   - * into each CS0 must be the sum of the amount of
1555   - * memory in the two CS0 ranks.
1556   - */
1557   - if (i == 0) {
1558   - ea = (2 * (rank_density >> dbw_cap_adj)) - 1;
1559   - }
1560   -
1561   - }
1562   - else if (!popts->memctl_interleaving && !popts->ba_intlv_ctl) {
1563   - /*
1564   - * No rank interleaving and no memory controller
1565   - * interleaving.
1566   - */
1567   - sa = dimm_params[dimm_number].base_address;
1568   - ea = sa + (rank_density >> dbw_cap_adj) - 1;
1569   - if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
1570   - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj);
1571   - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj);
1572   - } else {
1573   - sa = 0;
1574   - ea = 0;
1575 1521 }
1576 1522 }
1577 1523  
arch/powerpc/cpu/mpc8xxx/ddr/main.c
1 1 /*
2   - * Copyright 2008-2011 Freescale Semiconductor, Inc.
  2 + * Copyright 2008-2012 Freescale Semiconductor, Inc.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
6 6  
7 7  
... ... @@ -15,13 +15,15 @@
15 15 #include <common.h>
16 16 #include <i2c.h>
17 17 #include <asm/fsl_ddr_sdram.h>
  18 +#include <asm/fsl_law.h>
18 19  
19 20 #include "ddr.h"
20 21  
21   -extern void fsl_ddr_set_lawbar(
  22 +void fsl_ddr_set_lawbar(
22 23 const common_timing_params_t *memctl_common_params,
23 24 unsigned int memctl_interleaved,
24 25 unsigned int ctrl_num);
  26 +void fsl_ddr_set_intl3r(const unsigned int granule_size);
25 27  
26 28 /* processor specific function */
27 29 extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
... ... @@ -51,6 +53,22 @@
51 53 [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */
52 54 [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */
53 55 };
  56 +#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
  57 +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
  58 + [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */
  59 + [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */
  60 + [2][0] = SPD_EEPROM_ADDRESS3, /* controller 3 */
  61 +};
  62 +#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
  63 +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
  64 + [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */
  65 + [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */
  66 + [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */
  67 + [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */
  68 + [2][0] = SPD_EEPROM_ADDRESS5, /* controller 3 */
  69 + [2][1] = SPD_EEPROM_ADDRESS6, /* controller 3 */
  70 +};
  71 +
54 72 #endif
55 73  
56 74 static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
57 75  
... ... @@ -156,12 +174,12 @@
156 174 return step_string_tbl[s];
157 175 }
158 176  
159   -int step_assign_addresses(fsl_ddr_info_t *pinfo,
160   - unsigned int dbw_cap_adj[],
161   - unsigned int *all_memctl_interleaving,
162   - unsigned int *all_ctlr_rank_interleaving)
  177 +unsigned long long step_assign_addresses(fsl_ddr_info_t *pinfo,
  178 + unsigned int dbw_cap_adj[])
163 179 {
164 180 int i, j;
  181 + unsigned long long total_mem, current_mem_base, total_ctlr_mem;
  182 + unsigned long long rank_density, ctlr_density = 0;
165 183  
166 184 /*
167 185 * If a reduced data width is requested, but the SPD
168 186  
169 187  
170 188  
171 189  
172 190  
173 191  
174 192  
175 193  
176 194  
177 195  
178 196  
179 197  
... ... @@ -220,86 +238,108 @@
220 238 "specified controller %u\n", i);
221 239 return 1;
222 240 }
  241 + debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]);
223 242 }
224 243  
225   - j = 0;
226   - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
227   - if (pinfo->memctl_opts[i].memctl_interleaving)
228   - j++;
229   - /*
230   - * Not support less than all memory controllers interleaving
231   - * if more than two controllers
232   - */
233   - if (j == CONFIG_NUM_DDR_CONTROLLERS)
234   - *all_memctl_interleaving = 1;
235   -
236   - /* Check that all controllers are rank interleaving. */
237   - j = 0;
238   - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
239   - if (pinfo->memctl_opts[i].ba_intlv_ctl)
240   - j++;
241   - /*
242   - * All memory controllers must be populated to qualify for
243   - * all controller rank interleaving
244   - */
245   - if (j == CONFIG_NUM_DDR_CONTROLLERS)
246   - *all_ctlr_rank_interleaving = 1;
247   -
248   - if (*all_memctl_interleaving) {
249   - unsigned long long addr, total_mem_per_ctlr = 0;
250   - /*
251   - * If interleaving between memory controllers,
252   - * make each controller start at a base address
253   - * of 0.
254   - *
255   - * Also, if bank interleaving (chip select
256   - * interleaving) is enabled on each memory
257   - * controller, CS0 needs to be programmed to
258   - * cover the entire memory range on that memory
259   - * controller
260   - *
261   - * Bank interleaving also implies that each
262   - * addressed chip select is identical in size.
263   - */
264   -
  244 + current_mem_base = 0ull;
  245 + total_mem = 0;
  246 + if (pinfo->memctl_opts[0].memctl_interleaving) {
  247 + rank_density = pinfo->dimm_params[0][0].rank_density >>
  248 + dbw_cap_adj[0];
  249 + switch (pinfo->memctl_opts[0].ba_intlv_ctl &
  250 + FSL_DDR_CS0_CS1_CS2_CS3) {
  251 + case FSL_DDR_CS0_CS1_CS2_CS3:
  252 + ctlr_density = 4 * rank_density;
  253 + break;
  254 + case FSL_DDR_CS0_CS1:
  255 + case FSL_DDR_CS0_CS1_AND_CS2_CS3:
  256 + ctlr_density = 2 * rank_density;
  257 + break;
  258 + case FSL_DDR_CS2_CS3:
  259 + default:
  260 + ctlr_density = rank_density;
  261 + break;
  262 + }
  263 + debug("rank density is 0x%llx, ctlr density is 0x%llx\n",
  264 + rank_density, ctlr_density);
265 265 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
266   - addr = 0;
267   - pinfo->common_timing_params[i].base_address = 0ull;
268   - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
269   - unsigned long long cap
270   - = pinfo->dimm_params[i][j].capacity;
271   -
272   - pinfo->dimm_params[i][j].base_address = addr;
273   - addr += cap >> dbw_cap_adj[i];
274   - total_mem_per_ctlr += cap >> dbw_cap_adj[i];
  266 + if (pinfo->memctl_opts[i].memctl_interleaving) {
  267 + switch (pinfo->memctl_opts[i].memctl_interleaving_mode) {
  268 + case FSL_DDR_CACHE_LINE_INTERLEAVING:
  269 + case FSL_DDR_PAGE_INTERLEAVING:
  270 + case FSL_DDR_BANK_INTERLEAVING:
  271 + case FSL_DDR_SUPERBANK_INTERLEAVING:
  272 + total_ctlr_mem = 2 * ctlr_density;
  273 + break;
  274 + case FSL_DDR_3WAY_1KB_INTERLEAVING:
  275 + case FSL_DDR_3WAY_4KB_INTERLEAVING:
  276 + case FSL_DDR_3WAY_8KB_INTERLEAVING:
  277 + total_ctlr_mem = 3 * ctlr_density;
  278 + break;
  279 + case FSL_DDR_4WAY_1KB_INTERLEAVING:
  280 + case FSL_DDR_4WAY_4KB_INTERLEAVING:
  281 + case FSL_DDR_4WAY_8KB_INTERLEAVING:
  282 + total_ctlr_mem = 4 * ctlr_density;
  283 + break;
  284 + default:
  285 + panic("Unknown interleaving mode");
  286 + }
  287 + pinfo->common_timing_params[i].base_address =
  288 + current_mem_base;
  289 + pinfo->common_timing_params[i].total_mem =
  290 + total_ctlr_mem;
  291 + total_mem = current_mem_base + total_ctlr_mem;
  292 + debug("ctrl %d base 0x%llx\n", i, current_mem_base);
  293 + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem);
  294 + } else {
  295 + /* when 3rd controller not interleaved */
  296 + current_mem_base = total_mem;
  297 + total_ctlr_mem = 0;
  298 + pinfo->common_timing_params[i].base_address =
  299 + current_mem_base;
  300 + for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
  301 + unsigned long long cap =
  302 + pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i];
  303 + pinfo->dimm_params[i][j].base_address =
  304 + current_mem_base;
  305 + debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base);
  306 + current_mem_base += cap;
  307 + total_ctlr_mem += cap;
  308 + }
  309 + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem);
  310 + pinfo->common_timing_params[i].total_mem =
  311 + total_ctlr_mem;
  312 + total_mem += total_ctlr_mem;
275 313 }
276 314 }
277   - pinfo->common_timing_params[0].total_mem = total_mem_per_ctlr;
278 315 } else {
279 316 /*
280 317 * Simple linear assignment if memory
281 318 * controllers are not interleaved.
282 319 */
283   - unsigned long long cur_memsize = 0;
284 320 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
285   - u64 total_mem_per_ctlr = 0;
  321 + total_ctlr_mem = 0;
286 322 pinfo->common_timing_params[i].base_address =
287   - cur_memsize;
  323 + current_mem_base;
288 324 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
289 325 /* Compute DIMM base addresses. */
290 326 unsigned long long cap =
291   - pinfo->dimm_params[i][j].capacity;
  327 + pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i];
292 328 pinfo->dimm_params[i][j].base_address =
293   - cur_memsize;
294   - cur_memsize += cap >> dbw_cap_adj[i];
295   - total_mem_per_ctlr += cap >> dbw_cap_adj[i];
  329 + current_mem_base;
  330 + debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base);
  331 + current_mem_base += cap;
  332 + total_ctlr_mem += cap;
296 333 }
  334 + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem);
297 335 pinfo->common_timing_params[i].total_mem =
298   - total_mem_per_ctlr;
  336 + total_ctlr_mem;
  337 + total_mem += total_ctlr_mem;
299 338 }
300 339 }
  340 + debug("Total mem by %s is 0x%llx\n", __func__, total_mem);
301 341  
302   - return 0;
  342 + return total_mem;
303 343 }
304 344  
305 345 unsigned long long
... ... @@ -307,8 +347,6 @@
307 347 unsigned int size_only)
308 348 {
309 349 unsigned int i, j;
310   - unsigned int all_controllers_memctl_interleaving = 0;
311   - unsigned int all_controllers_rank_interleaving = 0;
312 350 unsigned long long total_mem = 0;
313 351  
314 352 fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
... ... @@ -346,8 +384,9 @@
346 384 retval = compute_dimm_parameters(spd, pdimm, i);
347 385 #ifdef CONFIG_SYS_DDR_RAW_TIMING
348 386 if (retval != 0) {
349   - printf("SPD error! Trying fallback to "
350   - "raw timing calculation\n");
  387 + printf("SPD error on controller %d! "
  388 + "Trying fallback to raw timing "
  389 + "calculation\n", i);
351 390 fsl_ddr_get_dimm_params(pdimm, i, j);
352 391 }
353 392 #else
354 393  
355 394  
... ... @@ -407,17 +446,14 @@
407 446 &pinfo->memctl_opts[i],
408 447 pinfo->dimm_params[i], i);
409 448 }
410   - check_interleaving_options(pinfo);
411 449 case STEP_ASSIGN_ADDRESSES:
412 450 /* STEP 5: Assign addresses to chip selects */
413   - step_assign_addresses(pinfo,
414   - dbw_capacity_adjust,
415   - &all_controllers_memctl_interleaving,
416   - &all_controllers_rank_interleaving);
  451 + check_interleaving_options(pinfo);
  452 + total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust);
417 453  
418 454 case STEP_COMPUTE_REGS:
419 455 /* STEP 6: compute controller register values */
420   - debug("FSL Memory ctrl cg register computation\n");
  456 + debug("FSL Memory ctrl register computation\n");
421 457 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
422 458 if (timing_params[i].ndimms_present == 0) {
423 459 memset(&ddr_reg[i], 0,
... ... @@ -437,21 +473,7 @@
437 473 break;
438 474 }
439 475  
440   - /* Compute the total amount of memory. */
441   -
442   - /*
443   - * If bank interleaving but NOT memory controller interleaving
444   - * CS_BNDS describe the quantity of memory on each memory
445   - * controller, so the total is the sum across.
446   - */
447   - if (!all_controllers_memctl_interleaving
448   - && all_controllers_rank_interleaving) {
449   - total_mem = 0;
450   - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
451   - total_mem += timing_params[i].total_mem;
452   - }
453   -
454   - } else {
  476 + {
455 477 /*
456 478 * Compute the amount of memory available just by
457 479 * looking for the highest valid CSn_BNDS value.
... ... @@ -489,7 +511,7 @@
489 511 phys_size_t fsl_ddr_sdram(void)
490 512 {
491 513 unsigned int i;
492   - unsigned int memctl_interleaved;
  514 + unsigned int law_memctl = LAW_TRGT_IF_DDR_1;
493 515 unsigned long long total_memory;
494 516 fsl_ddr_info_t info;
495 517  
... ... @@ -504,34 +526,6 @@
504 526 #endif
505 527 total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0);
506 528  
507   - /* Check for memory controller interleaving. */
508   - memctl_interleaved = 0;
509   - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
510   - memctl_interleaved +=
511   - info.memctl_opts[i].memctl_interleaving;
512   - }
513   -
514   - if (memctl_interleaved) {
515   - if (memctl_interleaved == CONFIG_NUM_DDR_CONTROLLERS) {
516   - debug("memctl interleaving\n");
517   - /*
518   - * Change the meaning of memctl_interleaved
519   - * to be "boolean".
520   - */
521   - memctl_interleaved = 1;
522   - } else {
523   - printf("Warning: memctl interleaving not "
524   - "properly configured on all controllers\n");
525   - memctl_interleaved = 0;
526   - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
527   - info.memctl_opts[i].memctl_interleaving = 0;
528   - debug("Recomputing with memctl_interleaving off.\n");
529   - total_memory = fsl_ddr_compute(&info,
530   - STEP_ASSIGN_ADDRESSES,
531   - 0);
532   - }
533   - }
534   -
535 529 /* Program configuration registers. */
536 530 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
537 531 debug("Programming controller %u\n", i);
538 532  
539 533  
... ... @@ -544,24 +538,69 @@
544 538 fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i);
545 539 }
546 540  
547   - if (memctl_interleaved) {
548   - const unsigned int ctrl_num = 0;
549   -
550   - /* Only set LAWBAR1 if memory controller interleaving is on. */
551   - fsl_ddr_set_lawbar(&info.common_timing_params[0],
552   - memctl_interleaved, ctrl_num);
553   - } else {
554   - /*
555   - * Memory controller interleaving is NOT on;
556   - * set each lawbar individually.
557   - */
558   - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  541 + /* program LAWs */
  542 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  543 + if (info.memctl_opts[i].memctl_interleaving) {
  544 + switch (info.memctl_opts[i].memctl_interleaving_mode) {
  545 + case FSL_DDR_CACHE_LINE_INTERLEAVING:
  546 + case FSL_DDR_PAGE_INTERLEAVING:
  547 + case FSL_DDR_BANK_INTERLEAVING:
  548 + case FSL_DDR_SUPERBANK_INTERLEAVING:
  549 + if (i == 0) {
  550 + law_memctl = LAW_TRGT_IF_DDR_INTRLV;
  551 + fsl_ddr_set_lawbar(&info.common_timing_params[i],
  552 + law_memctl, i);
  553 + } else if (i == 2) {
  554 + law_memctl = LAW_TRGT_IF_DDR_INTLV_34;
  555 + fsl_ddr_set_lawbar(&info.common_timing_params[i],
  556 + law_memctl, i);
  557 + }
  558 + break;
  559 + case FSL_DDR_3WAY_1KB_INTERLEAVING:
  560 + case FSL_DDR_3WAY_4KB_INTERLEAVING:
  561 + case FSL_DDR_3WAY_8KB_INTERLEAVING:
  562 + law_memctl = LAW_TRGT_IF_DDR_INTLV_123;
  563 + if (i == 0) {
  564 + fsl_ddr_set_intl3r(info.memctl_opts[i].memctl_interleaving_mode);
  565 + fsl_ddr_set_lawbar(&info.common_timing_params[i],
  566 + law_memctl, i);
  567 + }
  568 + break;
  569 + case FSL_DDR_4WAY_1KB_INTERLEAVING:
  570 + case FSL_DDR_4WAY_4KB_INTERLEAVING:
  571 + case FSL_DDR_4WAY_8KB_INTERLEAVING:
  572 + law_memctl = LAW_TRGT_IF_DDR_INTLV_1234;
  573 + if (i == 0)
  574 + fsl_ddr_set_lawbar(&info.common_timing_params[i],
  575 + law_memctl, i);
  576 + /* place holder for future 4-way interleaving */
  577 + break;
  578 + default:
  579 + break;
  580 + }
  581 + } else {
  582 + switch (i) {
  583 + case 0:
  584 + law_memctl = LAW_TRGT_IF_DDR_1;
  585 + break;
  586 + case 1:
  587 + law_memctl = LAW_TRGT_IF_DDR_2;
  588 + break;
  589 + case 2:
  590 + law_memctl = LAW_TRGT_IF_DDR_3;
  591 + break;
  592 + case 3:
  593 + law_memctl = LAW_TRGT_IF_DDR_4;
  594 + break;
  595 + default:
  596 + break;
  597 + }
559 598 fsl_ddr_set_lawbar(&info.common_timing_params[i],
560   - 0, i);
  599 + law_memctl, i);
561 600 }
562 601 }
563 602  
564   - debug("total_memory = %llu\n", total_memory);
  603 + debug("total_memory by %s = %llu\n", __func__, total_memory);
565 604  
566 605 #if !defined(CONFIG_PHYS_64BIT)
567 606 /* Check for 4G or more. Bad. */
arch/powerpc/cpu/mpc8xxx/ddr/options.c
1 1 /*
2   - * Copyright 2008, 2010-2011 Freescale Semiconductor, Inc.
  2 + * Copyright 2008, 2010-2012 Freescale Semiconductor, Inc.
3 3 *
4 4 * This program is free software; you can redistribute it and/or modify it
5 5 * under the terms of the GNU General Public License as published by the Free
6 6  
7 7  
... ... @@ -790,47 +790,98 @@
790 790 * should be a subset of the requested configuration.
791 791 */
792 792 #if (CONFIG_NUM_DDR_CONTROLLERS > 1)
793   - if (hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) {
794   - if (pdimm[0].n_ranks == 0) {
795   - printf("There is no rank on CS0 for controller %d. Because only"
796   - " rank on CS0 and ranks chip-select interleaved with CS0"
797   - " are controller interleaved, force non memory "
798   - "controller interleaving\n", ctrl_num);
799   - popts->memctl_interleaving = 0;
800   - } else {
801   - popts->memctl_interleaving = 1;
802   - /*
803   - * test null first. if CONFIG_HWCONFIG is not defined
804   - * hwconfig_arg_cmp returns non-zero
805   - */
806   - if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
807   - "null", buf)) {
808   - popts->memctl_interleaving = 0;
809   - debug("memory controller interleaving disabled.\n");
810   - } else if (hwconfig_subarg_cmp_f("fsl_ddr",
811   - "ctlr_intlv",
812   - "cacheline", buf))
813   - popts->memctl_interleaving_mode =
814   - FSL_DDR_CACHE_LINE_INTERLEAVING;
815   - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
816   - "page", buf))
817   - popts->memctl_interleaving_mode =
818   - FSL_DDR_PAGE_INTERLEAVING;
819   - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
820   - "bank", buf))
821   - popts->memctl_interleaving_mode =
822   - FSL_DDR_BANK_INTERLEAVING;
823   - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
824   - "superbank", buf))
825   - popts->memctl_interleaving_mode =
826   - FSL_DDR_SUPERBANK_INTERLEAVING;
827   - else {
828   - popts->memctl_interleaving = 0;
829   - printf("hwconfig has unrecognized parameter for ctlr_intlv.\n");
830   - }
831   - }
  793 + if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf))
  794 + goto done;
  795 +
  796 + if (pdimm[0].n_ranks == 0) {
  797 + printf("There is no rank on CS0 for controller %d.\n", ctrl_num);
  798 + popts->memctl_interleaving = 0;
  799 + goto done;
832 800 }
  801 + popts->memctl_interleaving = 1;
  802 + /*
  803 + * test null first. if CONFIG_HWCONFIG is not defined
  804 + * hwconfig_arg_cmp returns non-zero
  805 + */
  806 + if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
  807 + "null", buf)) {
  808 + popts->memctl_interleaving = 0;
  809 + debug("memory controller interleaving disabled.\n");
  810 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  811 + "ctlr_intlv",
  812 + "cacheline", buf)) {
  813 + popts->memctl_interleaving_mode =
  814 + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
  815 + 0 : FSL_DDR_CACHE_LINE_INTERLEAVING;
  816 + popts->memctl_interleaving =
  817 + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
  818 + 0 : 1;
  819 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  820 + "ctlr_intlv",
  821 + "page", buf)) {
  822 + popts->memctl_interleaving_mode =
  823 + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
  824 + 0 : FSL_DDR_PAGE_INTERLEAVING;
  825 + popts->memctl_interleaving =
  826 + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
  827 + 0 : 1;
  828 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  829 + "ctlr_intlv",
  830 + "bank", buf)) {
  831 + popts->memctl_interleaving_mode =
  832 + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
  833 + 0 : FSL_DDR_BANK_INTERLEAVING;
  834 + popts->memctl_interleaving =
  835 + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
  836 + 0 : 1;
  837 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  838 + "ctlr_intlv",
  839 + "superbank", buf)) {
  840 + popts->memctl_interleaving_mode =
  841 + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
  842 + 0 : FSL_DDR_SUPERBANK_INTERLEAVING;
  843 + popts->memctl_interleaving =
  844 + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
  845 + 0 : 1;
  846 +#if (CONFIG_NUM_DDR_CONTROLLERS == 3)
  847 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  848 + "ctlr_intlv",
  849 + "3way_1KB", buf)) {
  850 + popts->memctl_interleaving_mode =
  851 + FSL_DDR_3WAY_1KB_INTERLEAVING;
  852 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  853 + "ctlr_intlv",
  854 + "3way_4KB", buf)) {
  855 + popts->memctl_interleaving_mode =
  856 + FSL_DDR_3WAY_4KB_INTERLEAVING;
  857 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  858 + "ctlr_intlv",
  859 + "3way_8KB", buf)) {
  860 + popts->memctl_interleaving_mode =
  861 + FSL_DDR_3WAY_8KB_INTERLEAVING;
  862 +#elif (CONFIG_NUM_DDR_CONTROLLERS == 4)
  863 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  864 + "ctlr_intlv",
  865 + "4way_1KB", buf)) {
  866 + popts->memctl_interleaving_mode =
  867 + FSL_DDR_4WAY_1KB_INTERLEAVING;
  868 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  869 + "ctlr_intlv",
  870 + "4way_4KB", buf)) {
  871 + popts->memctl_interleaving_mode =
  872 + FSL_DDR_4WAY_4KB_INTERLEAVING;
  873 + } else if (hwconfig_subarg_cmp_f("fsl_ddr",
  874 + "ctlr_intlv",
  875 + "4way_8KB", buf)) {
  876 + popts->memctl_interleaving_mode =
  877 + FSL_DDR_4WAY_8KB_INTERLEAVING;
833 878 #endif
  879 + } else {
  880 + popts->memctl_interleaving = 0;
  881 + printf("hwconfig has unrecognized parameter for ctlr_intlv.\n");
  882 + }
  883 +done:
  884 +#endif
834 885 if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) &&
835 886 (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) {
836 887 /* test null first. if CONFIG_HWCONFIG is not defined,
837 888  
838 889  
... ... @@ -859,20 +910,20 @@
859 910 popts->ba_intlv_ctl = 0;
860 911 printf("Not enough bank(chip-select) for "
861 912 "CS0+CS1+CS2+CS3 on controller %d, "
862   - "force non-interleaving!\n", ctrl_num);
  913 + "interleaving disabled!\n", ctrl_num);
863 914 }
864 915 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
865 916 if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) {
866 917 popts->ba_intlv_ctl = 0;
867 918 printf("Not enough bank(chip-select) for "
868 919 "CS0+CS1+CS2+CS3 on controller %d, "
869   - "force non-interleaving!\n", ctrl_num);
  920 + "interleaving disabled!\n", ctrl_num);
870 921 }
871 922 if (pdimm[0].capacity != pdimm[1].capacity) {
872 923 popts->ba_intlv_ctl = 0;
873 924 printf("Not identical DIMM size for "
874 925 "CS0+CS1+CS2+CS3 on controller %d, "
875   - "force non-interleaving!\n", ctrl_num);
  926 + "interleaving disabled!\n", ctrl_num);
876 927 }
877 928 #endif
878 929 break;
... ... @@ -881,7 +932,7 @@
881 932 popts->ba_intlv_ctl = 0;
882 933 printf("Not enough bank(chip-select) for "
883 934 "CS0+CS1 on controller %d, "
884   - "force non-interleaving!\n", ctrl_num);
  935 + "interleaving disabled!\n", ctrl_num);
885 936 }
886 937 break;
887 938 case FSL_DDR_CS2_CS3:
888 939  
... ... @@ -889,13 +940,13 @@
889 940 if (pdimm[0].n_ranks < 4) {
890 941 popts->ba_intlv_ctl = 0;
891 942 printf("Not enough bank(chip-select) for CS2+CS3 "
892   - "on controller %d, force non-interleaving!\n", ctrl_num);
  943 + "on controller %d, interleaving disabled!\n", ctrl_num);
893 944 }
894 945 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
895 946 if (pdimm[1].n_ranks < 2) {
896 947 popts->ba_intlv_ctl = 0;
897 948 printf("Not enough bank(chip-select) for CS2+CS3 "
898   - "on controller %d, force non-interleaving!\n", ctrl_num);
  949 + "on controller %d, interleaving disabled!\n", ctrl_num);
899 950 }
900 951 #endif
901 952 break;
902 953  
... ... @@ -905,14 +956,14 @@
905 956 popts->ba_intlv_ctl = 0;
906 957 printf("Not enough bank(CS) for CS0+CS1 and "
907 958 "CS2+CS3 on controller %d, "
908   - "force non-interleaving!\n", ctrl_num);
  959 + "interleaving disabled!\n", ctrl_num);
909 960 }
910 961 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
911 962 if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) {
912 963 popts->ba_intlv_ctl = 0;
913 964 printf("Not enough bank(CS) for CS0+CS1 and "
914 965 "CS2+CS3 on controller %d, "
915   - "force non-interleaving!\n", ctrl_num);
  966 + "interleaving disabled!\n", ctrl_num);
916 967 }
917 968 #endif
918 969 break;
919 970  
920 971  
921 972  
922 973  
923 974  
924 975  
925 976  
926 977  
927 978  
... ... @@ -954,33 +1005,73 @@
954 1005  
955 1006 void check_interleaving_options(fsl_ddr_info_t *pinfo)
956 1007 {
957   - int i, j, check_n_ranks, intlv_fixed = 0;
  1008 + int i, j, k, check_n_ranks, intlv_invalid = 0;
  1009 + unsigned int check_intlv, check_n_row_addr, check_n_col_addr;
958 1010 unsigned long long check_rank_density;
  1011 + struct dimm_params_s *dimm;
959 1012 /*
960 1013 * Check if all controllers are configured for memory
961 1014 * controller interleaving. Identical dimms are recommended. At least
962   - * the size should be checked.
  1015 + * the size, row and col address should be checked.
963 1016 */
964 1017 j = 0;
965 1018 check_n_ranks = pinfo->dimm_params[0][0].n_ranks;
966 1019 check_rank_density = pinfo->dimm_params[0][0].rank_density;
  1020 + check_n_row_addr = pinfo->dimm_params[0][0].n_row_addr;
  1021 + check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr;
  1022 + check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode;
967 1023 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
968   - if ((pinfo->memctl_opts[i].memctl_interleaving) && \
969   - (check_rank_density == pinfo->dimm_params[i][0].rank_density) && \
970   - (check_n_ranks == pinfo->dimm_params[i][0].n_ranks)) {
  1024 + dimm = &pinfo->dimm_params[i][0];
  1025 + if (!pinfo->memctl_opts[i].memctl_interleaving) {
  1026 + continue;
  1027 + } else if (((check_rank_density != dimm->rank_density) ||
  1028 + (check_n_ranks != dimm->n_ranks) ||
  1029 + (check_n_row_addr != dimm->n_row_addr) ||
  1030 + (check_n_col_addr != dimm->n_col_addr) ||
  1031 + (check_intlv !=
  1032 + pinfo->memctl_opts[i].memctl_interleaving_mode))){
  1033 + intlv_invalid = 1;
  1034 + break;
  1035 + } else {
971 1036 j++;
972 1037 }
  1038 +
973 1039 }
974   - if (j != CONFIG_NUM_DDR_CONTROLLERS) {
  1040 + if (intlv_invalid) {
975 1041 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
976   - if (pinfo->memctl_opts[i].memctl_interleaving) {
  1042 + pinfo->memctl_opts[i].memctl_interleaving = 0;
  1043 + printf("Not all DIMMs are identical. "
  1044 + "Memory controller interleaving disabled.\n");
  1045 + } else {
  1046 + switch (check_intlv) {
  1047 + case FSL_DDR_CACHE_LINE_INTERLEAVING:
  1048 + case FSL_DDR_PAGE_INTERLEAVING:
  1049 + case FSL_DDR_BANK_INTERLEAVING:
  1050 + case FSL_DDR_SUPERBANK_INTERLEAVING:
  1051 + if (3 == CONFIG_NUM_DDR_CONTROLLERS)
  1052 + k = 2;
  1053 + else
  1054 + k = CONFIG_NUM_DDR_CONTROLLERS;
  1055 + break;
  1056 + case FSL_DDR_3WAY_1KB_INTERLEAVING:
  1057 + case FSL_DDR_3WAY_4KB_INTERLEAVING:
  1058 + case FSL_DDR_3WAY_8KB_INTERLEAVING:
  1059 + case FSL_DDR_4WAY_1KB_INTERLEAVING:
  1060 + case FSL_DDR_4WAY_4KB_INTERLEAVING:
  1061 + case FSL_DDR_4WAY_8KB_INTERLEAVING:
  1062 + default:
  1063 + k = CONFIG_NUM_DDR_CONTROLLERS;
  1064 + break;
  1065 + }
  1066 + debug("%d of %d controllers are interleaving.\n", j, k);
  1067 + if (j != k) {
  1068 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
977 1069 pinfo->memctl_opts[i].memctl_interleaving = 0;
978   - intlv_fixed = 1;
979   - }
980   - if (intlv_fixed)
981   - printf("Not all DIMMs are identical in size. "
982   - "Memory controller interleaving disabled.\n");
  1070 + printf("Not all controllers have compatible "
  1071 + "interleaving mode. All disabled.\n");
  1072 + }
983 1073 }
  1074 + debug("Checking interleaving options completed\n");
984 1075 }
985 1076  
986 1077 int fsl_use_spd(void)
arch/powerpc/cpu/mpc8xxx/ddr/util.c
1 1 /*
2   - * Copyright 2008-2011 Freescale Semiconductor, Inc.
  2 + * Copyright 2008-2012 Freescale Semiconductor, Inc.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
... ... @@ -79,7 +79,7 @@
79 79  
80 80 void
81 81 __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
82   - unsigned int memctl_interleaved,
  82 + unsigned int law_memctl,
83 83 unsigned int ctrl_num)
84 84 {
85 85 unsigned long long base = memctl_common_params->base_address;
86 86  
... ... @@ -98,28 +98,13 @@
98 98 if ((base + size) >= CONFIG_MAX_MEM_MAPPED)
99 99 size = CONFIG_MAX_MEM_MAPPED - base;
100 100 #endif
101   -
102   - if (ctrl_num == 0) {
103   - /*
104   - * Set up LAW for DDR controller 1 space.
105   - */
106   - unsigned int lawbar1_target_id = memctl_interleaved
107   - ? LAW_TRGT_IF_DDR_INTRLV : LAW_TRGT_IF_DDR_1;
108   -
109   - if (set_ddr_laws(base, size, lawbar1_target_id) < 0) {
110   - printf("%s: ERROR (ctrl #0, intrlv=%d)\n", __func__,
111   - memctl_interleaved);
112   - return ;
113   - }
114   - } else if (ctrl_num == 1) {
115   - if (set_ddr_laws(base, size, LAW_TRGT_IF_DDR_2) < 0) {
116   - printf("%s: ERROR (ctrl #1)\n", __func__);
117   - return ;
118   - }
119   - } else {
120   - printf("%s: unexpected DDR controller number (%u)\n", __func__,
121   - ctrl_num);
  101 + if (set_ddr_laws(base, size, law_memctl) < 0) {
  102 + printf("%s: ERROR (ctrl #%d, TRGT ID=%x)\n", __func__, ctrl_num,
  103 + law_memctl);
  104 + return ;
122 105 }
  106 + debug("setup ddr law base = 0x%llx, size 0x%llx, TRGT_ID 0x%x\n",
  107 + base, size, law_memctl);
123 108 }
124 109  
125 110 __attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void
... ... @@ -127,6 +112,15 @@
127 112 unsigned int memctl_interleaved,
128 113 unsigned int ctrl_num);
129 114  
  115 +void fsl_ddr_set_intl3r(const unsigned int granule_size)
  116 +{
  117 +#ifdef CONFIG_E6500
  118 + u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
  119 + *mcintl3r = 0x80000000 | (granule_size & 0x1f);
  120 + debug("Enable MCINTL3R with granule size 0x%x\n", granule_size);
  121 +#endif
  122 +}
  123 +
130 124 void board_add_ram_info(int use_default)
131 125 {
132 126 #if defined(CONFIG_MPC83xx)
... ... @@ -137,6 +131,9 @@
137 131 #elif defined(CONFIG_MPC86xx)
138 132 ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR);
139 133 #endif
  134 +#if defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3)
  135 + u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
  136 +#endif
140 137 #if (CONFIG_NUM_DDR_CONTROLLERS > 1)
141 138 uint32_t cs0_config = in_be32(&ddr->cs0_config);
142 139 #endif
... ... @@ -180,7 +177,29 @@
180 177 else
181 178 puts(", ECC off)");
182 179  
183   -#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
  180 +#if (CONFIG_NUM_DDR_CONTROLLERS == 3)
  181 +#ifdef CONFIG_E6500
  182 + if (*mcintl3r & 0x80000000) {
  183 + puts("\n");
  184 + puts(" DDR Controller Interleaving Mode: ");
  185 + switch (*mcintl3r & 0x1f) {
  186 + case FSL_DDR_3WAY_1KB_INTERLEAVING:
  187 + puts("3-way 1KB");
  188 + break;
  189 + case FSL_DDR_3WAY_4KB_INTERLEAVING:
  190 + puts("3-way 4KB");
  191 + break;
  192 + case FSL_DDR_3WAY_8KB_INTERLEAVING:
  193 + puts("3-way 8KB");
  194 + break;
  195 + default:
  196 + puts("3-way UNKNOWN");
  197 + break;
  198 + }
  199 + }
  200 +#endif
  201 +#endif
  202 +#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
184 203 if (cs0_config & 0x20000000) {
185 204 puts("\n");
186 205 puts(" DDR Controller Interleaving Mode: ");
arch/powerpc/include/asm/fsl_ddr_sdram.h
... ... @@ -76,6 +76,13 @@
76 76 #define FSL_DDR_PAGE_INTERLEAVING 0x1
77 77 #define FSL_DDR_BANK_INTERLEAVING 0x2
78 78 #define FSL_DDR_SUPERBANK_INTERLEAVING 0x3
  79 +#define FSL_DDR_3WAY_1KB_INTERLEAVING 0xA
  80 +#define FSL_DDR_3WAY_4KB_INTERLEAVING 0xC
  81 +#define FSL_DDR_3WAY_8KB_INTERLEAVING 0xD
  82 +/* placeholder for 4-way interleaving */
  83 +#define FSL_DDR_4WAY_1KB_INTERLEAVING 0x1A
  84 +#define FSL_DDR_4WAY_4KB_INTERLEAVING 0x1C
  85 +#define FSL_DDR_4WAY_8KB_INTERLEAVING 0x1D
79 86  
80 87 /* DDR_SDRAM_CFG - DDR SDRAM Control Configuration
81 88 */
arch/powerpc/include/asm/fsl_law.h
... ... @@ -60,8 +60,12 @@
60 60  
61 61 LAW_TRGT_IF_DDR_1 = 0x10,
62 62 LAW_TRGT_IF_DDR_2 = 0x11, /* 2nd controller */
  63 + LAW_TRGT_IF_DDR_3 = 0x12,
  64 + LAW_TRGT_IF_DDR_4 = 0x13,
63 65 LAW_TRGT_IF_DDR_INTRLV = 0x14,
64   -
  66 + LAW_TRGT_IF_DDR_INTLV_34 = 0x15,
  67 + LAW_TRGT_IF_DDR_INTLV_123 = 0x17,
  68 + LAW_TRGT_IF_DDR_INTLV_1234 = 0x16,
65 69 LAW_TRGT_IF_BMAN = 0x18,
66 70 LAW_TRGT_IF_DCSR = 0x1d,
67 71 LAW_TRGT_IF_LBC = 0x1f,
... ... @@ -87,6 +91,12 @@
87 91 LAW_TRGT_IF_DPAA_SWP_SRAM = 0x0e,
88 92 LAW_TRGT_IF_DDR = 0x0f,
89 93 LAW_TRGT_IF_DDR_2 = 0x16, /* 2nd controller */
  94 + /* place holder for 3-way and 4-way interleaving */
  95 + LAW_TRGT_IF_DDR_3,
  96 + LAW_TRGT_IF_DDR_4,
  97 + LAW_TRGT_IF_DDR_INTLV_34,
  98 + LAW_TRGT_IF_DDR_INTLV_123,
  99 + LAW_TRGT_IF_DDR_INTLV_1234,
90 100 };
91 101 #define LAW_TRGT_IF_DDR_1 LAW_TRGT_IF_DDR
92 102 #define LAW_TRGT_IF_PCI_1 LAW_TRGT_IF_PCI
arch/powerpc/include/asm/immap_85xx.h
... ... @@ -2621,6 +2621,7 @@
2621 2621 #define CONFIG_SYS_FSL_CORENET_CCM_OFFSET 0x0000
2622 2622 #define CONFIG_SYS_MPC85xx_DDR_OFFSET 0x8000
2623 2623 #define CONFIG_SYS_MPC85xx_DDR2_OFFSET 0x9000
  2624 +#define CONFIG_SYS_MPC85xx_DDR3_OFFSET 0xA000
2624 2625 #define CONFIG_SYS_FSL_CORENET_CLK_OFFSET 0xE1000
2625 2626 #define CONFIG_SYS_FSL_CORENET_RCPM_OFFSET 0xE2000
2626 2627 #define CONFIG_SYS_FSL_CORENET_SERDES_OFFSET 0xEA000
... ... @@ -2740,6 +2741,8 @@
2740 2741 (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR_OFFSET)
2741 2742 #define CONFIG_SYS_MPC85xx_DDR2_ADDR \
2742 2743 (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR2_OFFSET)
  2744 +#define CONFIG_SYS_MPC85xx_DDR3_ADDR \
  2745 + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR3_OFFSET)
2743 2746 #define CONFIG_SYS_LBC_ADDR \
2744 2747 (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_LBC_OFFSET)
2745 2748 #define CONFIG_SYS_IFC_ADDR \
  1 +Table of interleaving 2-4 controllers
  2 +=====================================
  3 + +--------------+-----------------------------------------------------------+
  4 + |Configuration | Memory Controller |
  5 + | | 1 2 3 4 |
  6 + |--------------+--------------+--------------+-----------------------------+
  7 + | Two memory | Not Intlv'ed | Not Intlv'ed | |
  8 + | complexes +--------------+--------------+ |
  9 + | | 2-way Intlv'ed | |
  10 + |--------------+--------------+--------------+--------------+ |
  11 + | | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | |
  12 + | Three memory +--------------+--------------+--------------+ |
  13 + | complexes | 2-way Intlv'ed | Not Intlv'ed | |
  14 + | +-----------------------------+--------------+ |
  15 + | | 3-way Intlv'ed | |
  16 + +--------------+--------------+--------------+--------------+--------------+
  17 + | | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed |
  18 + | Four memory +--------------+--------------+--------------+--------------+
  19 + | complexes | 2-way Intlv'ed | 2-way Intlv'ed |
  20 + | +-----------------------------+-----------------------------+
  21 + | | 4-way Intlv'ed |
  22 + +--------------+-----------------------------------------------------------+
1 23  
2   -Table of interleaving modes supported in cpu/8xxx/ddr/
  24 +
  25 +Table of 2-way interleaving modes supported in cpu/8xxx/ddr/
3 26 ======================================================
4 27 +-------------+---------------------------------------------------------+
5 28 | | Rank Interleaving |
... ... @@ -55,6 +78,15 @@
55 78  
56 79 # superbank
57 80 setenv hwconfig "fsl_ddr:ctlr_intlv=superbank"
  81 +
  82 + # 1KB 3-way interleaving
  83 + setenv hwconfig "fsl_ddr:ctlr_intlv=3way_1KB"
  84 +
  85 + # 4KB 3-way interleaving
  86 + setenv hwconfig "fsl_ddr:ctlr_intlv=3way_4KB"
  87 +
  88 + # 8KB 3-way interleaving
  89 + setenv hwconfig "fsl_ddr:ctlr_intlv=3way_8KB"
58 90  
59 91 # disable bank (chip-select) interleaving
60 92 setenv hwconfig "fsl_ddr:bank_intlv=null"