lc_common_dimm_params.c 16.9 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
/*
 * Copyright 2008-2016 Freescale Semiconductor, Inc.
 * Copyright 2017-2018 NXP Semiconductor
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#include <fsl_ddr_sdram.h>

#include <fsl_ddr.h>

#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
static unsigned int
compute_cas_latency(const unsigned int ctrl_num,
		    const dimm_params_t *dimm_params,
		    common_timing_params_t *outpdimm,
		    unsigned int number_of_dimms)
{
	unsigned int i;
	unsigned int common_caslat;
	unsigned int caslat_actual;
	unsigned int retry = 16;
	unsigned int tmp = ~0;
	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#ifdef CONFIG_SYS_FSL_DDR3
	const unsigned int taamax = 20000;
#else
	const unsigned int taamax = 18000;
#endif

	/* compute the common CAS latency supported between slots */
	for (i = 0; i < number_of_dimms; i++) {
		if (dimm_params[i].n_ranks)
			tmp &= dimm_params[i].caslat_x;
	}
	common_caslat = tmp;

	/* validate if the memory clk is in the range of dimms */
	if (mclk_ps < outpdimm->tckmin_x_ps) {
		printf("DDR clock (MCLK cycle %u ps) is faster than "
			"the slowest DIMM(s) (tCKmin %u ps) can support.\n",
			mclk_ps, outpdimm->tckmin_x_ps);
	}
#ifdef CONFIG_SYS_FSL_DDR4
	if (mclk_ps > outpdimm->tckmax_ps) {
		printf("DDR clock (MCLK cycle %u ps) is slower than DIMM(s) (tCKmax %u ps) can support.\n",
		       mclk_ps, outpdimm->tckmax_ps);
	}
#endif
	/* determine the acutal cas latency */
	caslat_actual = (outpdimm->taamin_ps + mclk_ps - 1) / mclk_ps;
	/* check if the dimms support the CAS latency */
	while (!(common_caslat & (1 << caslat_actual)) && retry > 0) {
		caslat_actual++;
		retry--;
	}
	/* once the caculation of caslat_actual is completed
	 * we must verify that this CAS latency value does not
	 * exceed tAAmax, which is 20 ns for all DDR3 speed grades,
	 * 18ns for all DDR4 speed grades.
	 */
	if (caslat_actual * mclk_ps > taamax) {
		printf("The chosen cas latency %d is too large\n",
		       caslat_actual);
	}
	outpdimm->lowest_common_spd_caslat = caslat_actual;
	debug("lowest_common_spd_caslat is 0x%x\n", caslat_actual);

	return 0;
}
#else	/* for DDR1 and DDR2 */
static unsigned int
compute_cas_latency(const unsigned int ctrl_num,
		    const dimm_params_t *dimm_params,
		    common_timing_params_t *outpdimm,
		    unsigned int number_of_dimms)
{
	int i;
	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
	unsigned int lowest_good_caslat;
	unsigned int not_ok;
	unsigned int temp1, temp2;

	debug("using mclk_ps = %u\n", mclk_ps);
	if (mclk_ps > outpdimm->tckmax_ps) {
		printf("Warning: DDR clock (%u ps) is slower than DIMM(s) (tCKmax %u ps)\n",
		       mclk_ps, outpdimm->tckmax_ps);
	}

	/*
	 * Compute a CAS latency suitable for all DIMMs
	 *
	 * Strategy for SPD-defined latencies: compute only
	 * CAS latency defined by all DIMMs.
	 */

	/*
	 * Step 1: find CAS latency common to all DIMMs using bitwise
	 * operation.
	 */
	temp1 = 0xFF;
	for (i = 0; i < number_of_dimms; i++) {
		if (dimm_params[i].n_ranks) {
			temp2 = 0;
			temp2 |= 1 << dimm_params[i].caslat_x;
			temp2 |= 1 << dimm_params[i].caslat_x_minus_1;
			temp2 |= 1 << dimm_params[i].caslat_x_minus_2;
			/*
			 * If there was no entry for X-2 (X-1) in
			 * the SPD, then caslat_x_minus_2
			 * (caslat_x_minus_1) contains either 255 or
			 * 0xFFFFFFFF because that's what the glorious
			 * __ilog2 function returns for an input of 0.
			 * On 32-bit PowerPC, left shift counts with bit
			 * 26 set (that the value of 255 or 0xFFFFFFFF
			 * will have), cause the destination register to
			 * be 0.  That is why this works.
			 */
			temp1 &= temp2;
		}
	}

	/*
	 * Step 2: check each common CAS latency against tCK of each
	 * DIMM's SPD.
	 */
	lowest_good_caslat = 0;
	temp2 = 0;
	while (temp1) {
		not_ok = 0;
		temp2 =  __ilog2(temp1);
		debug("checking common caslat = %u\n", temp2);

		/* Check if this CAS latency will work on all DIMMs at tCK. */
		for (i = 0; i < number_of_dimms; i++) {
			if (!dimm_params[i].n_ranks)
				continue;

			if (dimm_params[i].caslat_x == temp2) {
				if (mclk_ps >= dimm_params[i].tckmin_x_ps) {
					debug("CL = %u ok on DIMM %u at tCK=%u ps with tCKmin_X_ps of %u\n",
					      temp2, i, mclk_ps,
					      dimm_params[i].tckmin_x_ps);
					continue;
				} else {
					not_ok++;
				}
			}

			if (dimm_params[i].caslat_x_minus_1 == temp2) {
				unsigned int tckmin_x_minus_1_ps
					= dimm_params[i].tckmin_x_minus_1_ps;
				if (mclk_ps >= tckmin_x_minus_1_ps) {
					debug("CL = %u ok on DIMM %u at tCK=%u ps with tckmin_x_minus_1_ps of %u\n",
					      temp2, i, mclk_ps,
					      tckmin_x_minus_1_ps);
					continue;
				} else {
					not_ok++;
				}
			}

			if (dimm_params[i].caslat_x_minus_2 == temp2) {
				unsigned int tckmin_x_minus_2_ps
					= dimm_params[i].tckmin_x_minus_2_ps;
				if (mclk_ps >= tckmin_x_minus_2_ps) {
					debug("CL = %u ok on DIMM %u at tCK=%u ps with tckmin_x_minus_2_ps of %u\n",
					      temp2, i, mclk_ps,
					      tckmin_x_minus_2_ps);
					continue;
				} else {
					not_ok++;
				}
			}
		}

		if (!not_ok)
			lowest_good_caslat = temp2;

		temp1 &= ~(1 << temp2);
	}

	debug("lowest common SPD-defined CAS latency = %u\n",
	      lowest_good_caslat);
	outpdimm->lowest_common_spd_caslat = lowest_good_caslat;


	/*
	 * Compute a common 'de-rated' CAS latency.
	 *
	 * The strategy here is to find the *highest* dereated cas latency
	 * with the assumption that all of the DIMMs will support a dereated
	 * CAS latency higher than or equal to their lowest dereated value.
	 */
	temp1 = 0;
	for (i = 0; i < number_of_dimms; i++)
		temp1 = max(temp1, dimm_params[i].caslat_lowest_derated);

	outpdimm->highest_common_derated_caslat = temp1;
	debug("highest common dereated CAS latency = %u\n", temp1);

	return 0;
}
#endif

/*
 * compute_lowest_common_dimm_parameters()
 *
 * Determine the worst-case DIMM timing parameters from the set of DIMMs
 * whose parameters have been computed into the array pointed to
 * by dimm_params.
 */
unsigned int
compute_lowest_common_dimm_parameters(const unsigned int ctrl_num,
				      const dimm_params_t *dimm_params,
				      common_timing_params_t *outpdimm,
				      const unsigned int number_of_dimms)
{
	unsigned int i, j;

	unsigned int tckmin_x_ps = 0;
	unsigned int tckmax_ps = 0xFFFFFFFF;
	unsigned int trcd_ps = 0;
	unsigned int trp_ps = 0;
	unsigned int tras_ps = 0;
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
	unsigned int taamin_ps = 0;
#endif
#ifdef CONFIG_SYS_FSL_DDR4
	unsigned int twr_ps = 15000;
	unsigned int trfc1_ps = 0;
	unsigned int trfc2_ps = 0;
	unsigned int trfc4_ps = 0;
	unsigned int trrds_ps = 0;
	unsigned int trrdl_ps = 0;
	unsigned int tccdl_ps = 0;
	unsigned int trfc_slr_ps = 0;
#else
	unsigned int twr_ps = 0;
	unsigned int twtr_ps = 0;
	unsigned int trfc_ps = 0;
	unsigned int trrd_ps = 0;
	unsigned int trtp_ps = 0;
#endif
	unsigned int trc_ps = 0;
	unsigned int refresh_rate_ps = 0;
	unsigned int extended_op_srt = 1;
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
	unsigned int tis_ps = 0;
	unsigned int tih_ps = 0;
	unsigned int tds_ps = 0;
	unsigned int tdh_ps = 0;
	unsigned int tdqsq_max_ps = 0;
	unsigned int tqhs_ps = 0;
#endif
	unsigned int temp1, temp2;
	unsigned int additive_latency = 0;

	temp1 = 0;
	for (i = 0; i < number_of_dimms; i++) {
		/*
		 * If there are no ranks on this DIMM,
		 * it probably doesn't exist, so skip it.
		 */
		if (dimm_params[i].n_ranks == 0) {
			temp1++;
			continue;
		}
		if (dimm_params[i].n_ranks == 4 && i != 0) {
			printf("Found Quad-rank DIMM in wrong bank, ignored."
				" Software may not run as expected.\n");
			temp1++;
			continue;
		}

		/*
		 * check if quad-rank DIMM is plugged if
		 * CONFIG_CHIP_SELECT_QUAD_CAPABLE is not defined
		 * Only the board with proper design is capable
		 */
#ifndef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
		if (dimm_params[i].n_ranks == 4 && \
		  CONFIG_CHIP_SELECTS_PER_CTRL/CONFIG_DIMM_SLOTS_PER_CTLR < 4) {
			printf("Found Quad-rank DIMM, not able to support.");
			temp1++;
			continue;
		}
#endif
		/*
		 * Find minimum tckmax_ps to find fastest slow speed,
		 * i.e., this is the slowest the whole system can go.
		 */
		tckmax_ps = min(tckmax_ps,
				(unsigned int)dimm_params[i].tckmax_ps);
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
		taamin_ps = max(taamin_ps,
				(unsigned int)dimm_params[i].taa_ps);
#endif
		tckmin_x_ps = max(tckmin_x_ps,
				  (unsigned int)dimm_params[i].tckmin_x_ps);
		trcd_ps = max(trcd_ps, (unsigned int)dimm_params[i].trcd_ps);
		trp_ps = max(trp_ps, (unsigned int)dimm_params[i].trp_ps);
		tras_ps = max(tras_ps, (unsigned int)dimm_params[i].tras_ps);
#ifdef CONFIG_SYS_FSL_DDR4
		trfc1_ps = max(trfc1_ps,
			       (unsigned int)dimm_params[i].trfc1_ps);
		trfc2_ps = max(trfc2_ps,
			       (unsigned int)dimm_params[i].trfc2_ps);
		trfc4_ps = max(trfc4_ps,
			       (unsigned int)dimm_params[i].trfc4_ps);
		trrds_ps = max(trrds_ps,
			       (unsigned int)dimm_params[i].trrds_ps);
		trrdl_ps = max(trrdl_ps,
			       (unsigned int)dimm_params[i].trrdl_ps);
		tccdl_ps = max(tccdl_ps,
			       (unsigned int)dimm_params[i].tccdl_ps);
		trfc_slr_ps = max(trfc_slr_ps,
				  (unsigned int)dimm_params[i].trfc_slr_ps);
#else
		twr_ps = max(twr_ps, (unsigned int)dimm_params[i].twr_ps);
		twtr_ps = max(twtr_ps, (unsigned int)dimm_params[i].twtr_ps);
		trfc_ps = max(trfc_ps, (unsigned int)dimm_params[i].trfc_ps);
		trrd_ps = max(trrd_ps, (unsigned int)dimm_params[i].trrd_ps);
		trtp_ps = max(trtp_ps, (unsigned int)dimm_params[i].trtp_ps);
#endif
		trc_ps = max(trc_ps, (unsigned int)dimm_params[i].trc_ps);
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
		tis_ps = max(tis_ps, (unsigned int)dimm_params[i].tis_ps);
		tih_ps = max(tih_ps, (unsigned int)dimm_params[i].tih_ps);
		tds_ps = max(tds_ps, (unsigned int)dimm_params[i].tds_ps);
		tdh_ps = max(tdh_ps, (unsigned int)dimm_params[i].tdh_ps);
		tqhs_ps = max(tqhs_ps, (unsigned int)dimm_params[i].tqhs_ps);
		/*
		 * Find maximum tdqsq_max_ps to find slowest.
		 *
		 * FIXME: is finding the slowest value the correct
		 * strategy for this parameter?
		 */
		tdqsq_max_ps = max(tdqsq_max_ps,
				   (unsigned int)dimm_params[i].tdqsq_max_ps);
#endif
		refresh_rate_ps = max(refresh_rate_ps,
				      (unsigned int)dimm_params[i].refresh_rate_ps);
		/* extended_op_srt is either 0 or 1, 0 having priority */
		extended_op_srt = min(extended_op_srt,
				      (unsigned int)dimm_params[i].extended_op_srt);
	}

	outpdimm->ndimms_present = number_of_dimms - temp1;

	if (temp1 == number_of_dimms) {
		debug("no dimms this memory controller\n");
		return 0;
	}

	outpdimm->tckmin_x_ps = tckmin_x_ps;
	outpdimm->tckmax_ps = tckmax_ps;
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
	outpdimm->taamin_ps = taamin_ps;
#endif
	outpdimm->trcd_ps = trcd_ps;
	outpdimm->trp_ps = trp_ps;
	outpdimm->tras_ps = tras_ps;
#ifdef CONFIG_SYS_FSL_DDR4
	outpdimm->trfc1_ps = trfc1_ps;
	outpdimm->trfc2_ps = trfc2_ps;
	outpdimm->trfc4_ps = trfc4_ps;
	outpdimm->trrds_ps = trrds_ps;
	outpdimm->trrdl_ps = trrdl_ps;
	outpdimm->tccdl_ps = tccdl_ps;
	outpdimm->trfc_slr_ps = trfc_slr_ps;
#else
	outpdimm->twtr_ps = twtr_ps;
	outpdimm->trfc_ps = trfc_ps;
	outpdimm->trrd_ps = trrd_ps;
	outpdimm->trtp_ps = trtp_ps;
#endif
	outpdimm->twr_ps = twr_ps;
	outpdimm->trc_ps = trc_ps;
	outpdimm->refresh_rate_ps = refresh_rate_ps;
	outpdimm->extended_op_srt = extended_op_srt;
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
	outpdimm->tis_ps = tis_ps;
	outpdimm->tih_ps = tih_ps;
	outpdimm->tds_ps = tds_ps;
	outpdimm->tdh_ps = tdh_ps;
	outpdimm->tdqsq_max_ps = tdqsq_max_ps;
	outpdimm->tqhs_ps = tqhs_ps;
#endif

	/* Determine common burst length for all DIMMs. */
	temp1 = 0xff;
	for (i = 0; i < number_of_dimms; i++) {
		if (dimm_params[i].n_ranks) {
			temp1 &= dimm_params[i].burst_lengths_bitmask;
		}
	}
	outpdimm->all_dimms_burst_lengths_bitmask = temp1;

	/* Determine if all DIMMs registered buffered. */
	temp1 = temp2 = 0;
	for (i = 0; i < number_of_dimms; i++) {
		if (dimm_params[i].n_ranks) {
			if (dimm_params[i].registered_dimm) {
				temp1 = 1;
#ifndef CONFIG_SPL_BUILD
				printf("Detected RDIMM %s\n",
					dimm_params[i].mpart);
#endif
			} else {
				temp2 = 1;
#ifndef CONFIG_SPL_BUILD
				printf("Detected UDIMM %s\n",
					dimm_params[i].mpart);
#endif
			}
		}
	}

	outpdimm->all_dimms_registered = 0;
	outpdimm->all_dimms_unbuffered = 0;
	if (temp1 && !temp2) {
		outpdimm->all_dimms_registered = 1;
	} else if (!temp1 && temp2) {
		outpdimm->all_dimms_unbuffered = 1;
	} else {
		printf("ERROR:  Mix of registered buffered and unbuffered "
				"DIMMs detected!\n");
	}

	temp1 = 0;
	if (outpdimm->all_dimms_registered)
		for (j = 0; j < 16; j++) {
			outpdimm->rcw[j] = dimm_params[0].rcw[j];
			for (i = 1; i < number_of_dimms; i++) {
				if (!dimm_params[i].n_ranks)
					continue;
				if (dimm_params[i].rcw[j] != dimm_params[0].rcw[j]) {
					temp1 = 1;
					break;
				}
			}
		}

	if (temp1 != 0)
		printf("ERROR: Mix different RDIMM detected!\n");

	/* calculate cas latency for all DDR types */
	if (compute_cas_latency(ctrl_num, dimm_params,
				outpdimm, number_of_dimms))
		return 1;

	/* Determine if all DIMMs ECC capable. */
	temp1 = 1;
	for (i = 0; i < number_of_dimms; i++) {
		if (dimm_params[i].n_ranks &&
			!(dimm_params[i].edc_config & EDC_ECC)) {
			temp1 = 0;
			break;
		}
	}
	if (temp1) {
		debug("all DIMMs ECC capable\n");
	} else {
		debug("Warning: not all DIMMs ECC capable, cant enable ECC\n");
	}
	outpdimm->all_dimms_ecc_capable = temp1;

	/*
	 * Compute additive latency.
	 *
	 * For DDR1, additive latency should be 0.
	 *
	 * For DDR2, with ODT enabled, use "a value" less than ACTTORW,
	 *	which comes from Trcd, and also note that:
	 *	    add_lat + caslat must be >= 4
	 *
	 * For DDR3, we use the AL=0
	 *
	 * When to use additive latency for DDR2:
	 *
	 * I. Because you are using CL=3 and need to do ODT on writes and
	 *    want functionality.
	 *    1. Are you going to use ODT? (Does your board not have
	 *      additional termination circuitry for DQ, DQS, DQS_,
	 *      DM, RDQS, RDQS_ for x4/x8 configs?)
	 *    2. If so, is your lowest supported CL going to be 3?
	 *    3. If so, then you must set AL=1 because
	 *
	 *       WL >= 3 for ODT on writes
	 *       RL = AL + CL
	 *       WL = RL - 1
	 *       ->
	 *       WL = AL + CL - 1
	 *       AL + CL - 1 >= 3
	 *       AL + CL >= 4
	 *  QED
	 *
	 *  RL >= 3 for ODT on reads
	 *  RL = AL + CL
	 *
	 *  Since CL aren't usually less than 2, AL=0 is a minimum,
	 *  so the WL-derived AL should be the  -- FIXME?
	 *
	 * II. Because you are using auto-precharge globally and want to
	 *     use additive latency (posted CAS) to get more bandwidth.
	 *     1. Are you going to use auto-precharge mode globally?
	 *
	 *        Use addtivie latency and compute AL to be 1 cycle less than
	 *        tRCD, i.e. the READ or WRITE command is in the cycle
	 *        immediately following the ACTIVATE command..
	 *
	 * III. Because you feel like it or want to do some sort of
	 *      degraded-performance experiment.
	 *     1.  Do you just want to use additive latency because you feel
	 *         like it?
	 *
	 * Validation:  AL is less than tRCD, and within the other
	 * read-to-precharge constraints.
	 */

	additive_latency = 0;

#if defined(CONFIG_SYS_FSL_DDR2)
	if ((outpdimm->lowest_common_spd_caslat < 4) &&
	    (picos_to_mclk(ctrl_num, trcd_ps) >
	     outpdimm->lowest_common_spd_caslat)) {
		additive_latency = picos_to_mclk(ctrl_num, trcd_ps) -
				   outpdimm->lowest_common_spd_caslat;
		if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
			additive_latency = picos_to_mclk(ctrl_num, trcd_ps);
			debug("setting additive_latency to %u because it was "
				" greater than tRCD_ps\n", additive_latency);
		}
	}
#endif

	/*
	 * Validate additive latency
	 *
	 * AL <= tRCD(min)
	 */
	if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
		printf("Error: invalid additive latency exceeds tRCD(min).\n");
		return 1;
	}

	/*
	 * RL = CL + AL;  RL >= 3 for ODT_RD_CFG to be enabled
	 * WL = RL - 1;  WL >= 3 for ODT_WL_CFG to be enabled
	 * ADD_LAT (the register) must be set to a value less
	 * than ACTTORW if WL = 1, then AL must be set to 1
	 * RD_TO_PRE (the register) must be set to a minimum
	 * tRTP + AL if AL is nonzero
	 */

	/*
	 * Additive latency will be applied only if the memctl option to
	 * use it.
	 */
	outpdimm->additive_latency = additive_latency;

	debug("tCKmin_ps = %u\n", outpdimm->tckmin_x_ps);
	debug("trcd_ps   = %u\n", outpdimm->trcd_ps);
	debug("trp_ps    = %u\n", outpdimm->trp_ps);
	debug("tras_ps   = %u\n", outpdimm->tras_ps);
#ifdef CONFIG_SYS_FSL_DDR4
	debug("trfc1_ps = %u\n", trfc1_ps);
	debug("trfc2_ps = %u\n", trfc2_ps);
	debug("trfc4_ps = %u\n", trfc4_ps);
	debug("trrds_ps = %u\n", trrds_ps);
	debug("trrdl_ps = %u\n", trrdl_ps);
	debug("tccdl_ps = %u\n", tccdl_ps);
	debug("trfc_slr_ps = %u\n", trfc_slr_ps);
#else
	debug("twtr_ps   = %u\n", outpdimm->twtr_ps);
	debug("trfc_ps   = %u\n", outpdimm->trfc_ps);
	debug("trrd_ps   = %u\n", outpdimm->trrd_ps);
#endif
	debug("twr_ps    = %u\n", outpdimm->twr_ps);
	debug("trc_ps    = %u\n", outpdimm->trc_ps);

	return 0;
}