xref: /openbmc/u-boot/drivers/ddr/fsl/ddr2_dimm_params.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0
25614e71bSYork Sun /*
35614e71bSYork Sun  * Copyright 2008 Freescale Semiconductor, Inc.
45614e71bSYork Sun  */
55614e71bSYork Sun 
65614e71bSYork Sun #include <common.h>
75614e71bSYork Sun #include <fsl_ddr_sdram.h>
85614e71bSYork Sun 
95614e71bSYork Sun #include <fsl_ddr.h>
105614e71bSYork Sun /*
115614e71bSYork Sun  * Calculate the Density of each Physical Rank.
125614e71bSYork Sun  * Returned size is in bytes.
135614e71bSYork Sun  *
145614e71bSYork Sun  * Study these table from Byte 31 of JEDEC SPD Spec.
155614e71bSYork Sun  *
165614e71bSYork Sun  *		DDR I	DDR II
175614e71bSYork Sun  *	Bit	Size	Size
185614e71bSYork Sun  *	---	-----	------
195614e71bSYork Sun  *	7 high	512MB	512MB
205614e71bSYork Sun  *	6	256MB	256MB
215614e71bSYork Sun  *	5	128MB	128MB
225614e71bSYork Sun  *	4	 64MB	 16GB
235614e71bSYork Sun  *	3	 32MB	  8GB
245614e71bSYork Sun  *	2	 16MB	  4GB
255614e71bSYork Sun  *	1	  2GB	  2GB
265614e71bSYork Sun  *	0 low	  1GB	  1GB
275614e71bSYork Sun  *
285614e71bSYork Sun  * Reorder Table to be linear by stripping the bottom
295614e71bSYork Sun  * 2 or 5 bits off and shifting them up to the top.
305614e71bSYork Sun  *
315614e71bSYork Sun  */
325614e71bSYork Sun static unsigned long long
compute_ranksize(unsigned int mem_type,unsigned char row_dens)335614e71bSYork Sun compute_ranksize(unsigned int mem_type, unsigned char row_dens)
345614e71bSYork Sun {
355614e71bSYork Sun 	unsigned long long bsize;
365614e71bSYork Sun 
375614e71bSYork Sun 	/* Bottom 5 bits up to the top. */
385614e71bSYork Sun 	bsize = ((row_dens >> 5) | ((row_dens & 31) << 3));
395614e71bSYork Sun 	bsize <<= 27ULL;
405614e71bSYork Sun 	debug("DDR: DDR II rank density = 0x%16llx\n", bsize);
415614e71bSYork Sun 
425614e71bSYork Sun 	return bsize;
435614e71bSYork Sun }
445614e71bSYork Sun 
455614e71bSYork Sun /*
465614e71bSYork Sun  * Convert a two-nibble BCD value into a cycle time.
475614e71bSYork Sun  * While the spec calls for nano-seconds, picos are returned.
485614e71bSYork Sun  *
495614e71bSYork Sun  * This implements the tables for bytes 9, 23 and 25 for both
505614e71bSYork Sun  * DDR I and II.  No allowance for distinguishing the invalid
515614e71bSYork Sun  * fields absent for DDR I yet present in DDR II is made.
525614e71bSYork Sun  * (That is, cycle times of .25, .33, .66 and .75 ns are
535614e71bSYork Sun  * allowed for both DDR II and I.)
545614e71bSYork Sun  */
555614e71bSYork Sun static unsigned int
convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)565614e71bSYork Sun convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
575614e71bSYork Sun {
585614e71bSYork Sun 	/* Table look up the lower nibble, allow DDR I & II. */
595614e71bSYork Sun 	unsigned int tenths_ps[16] = {
605614e71bSYork Sun 		0,
615614e71bSYork Sun 		100,
625614e71bSYork Sun 		200,
635614e71bSYork Sun 		300,
645614e71bSYork Sun 		400,
655614e71bSYork Sun 		500,
665614e71bSYork Sun 		600,
675614e71bSYork Sun 		700,
685614e71bSYork Sun 		800,
695614e71bSYork Sun 		900,
705614e71bSYork Sun 		250,	/* This and the next 3 entries valid ... */
715614e71bSYork Sun 		330,	/* ...  only for tCK calculations. */
725614e71bSYork Sun 		660,
735614e71bSYork Sun 		750,
745614e71bSYork Sun 		0,	/* undefined */
755614e71bSYork Sun 		0	/* undefined */
765614e71bSYork Sun 	};
775614e71bSYork Sun 
785614e71bSYork Sun 	unsigned int whole_ns = (spd_val & 0xF0) >> 4;
795614e71bSYork Sun 	unsigned int tenth_ns = spd_val & 0x0F;
805614e71bSYork Sun 	unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns];
815614e71bSYork Sun 
825614e71bSYork Sun 	return ps;
835614e71bSYork Sun }
845614e71bSYork Sun 
855614e71bSYork Sun static unsigned int
convert_bcd_hundredths_to_cycle_time_ps(unsigned int spd_val)865614e71bSYork Sun convert_bcd_hundredths_to_cycle_time_ps(unsigned int spd_val)
875614e71bSYork Sun {
885614e71bSYork Sun 	unsigned int tenth_ns = (spd_val & 0xF0) >> 4;
895614e71bSYork Sun 	unsigned int hundredth_ns = spd_val & 0x0F;
905614e71bSYork Sun 	unsigned int ps = tenth_ns * 100 + hundredth_ns * 10;
915614e71bSYork Sun 
925614e71bSYork Sun 	return ps;
935614e71bSYork Sun }
945614e71bSYork Sun 
955614e71bSYork Sun static unsigned int byte40_table_ps[8] = {
965614e71bSYork Sun 	0,
975614e71bSYork Sun 	250,
985614e71bSYork Sun 	330,
995614e71bSYork Sun 	500,
1005614e71bSYork Sun 	660,
1015614e71bSYork Sun 	750,
1025614e71bSYork Sun 	0,	/* supposed to be RFC, but not sure what that means */
1035614e71bSYork Sun 	0	/* Undefined */
1045614e71bSYork Sun };
1055614e71bSYork Sun 
1065614e71bSYork Sun static unsigned int
compute_trfc_ps_from_spd(unsigned char trctrfc_ext,unsigned char trfc)1075614e71bSYork Sun compute_trfc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trfc)
1085614e71bSYork Sun {
109a4ca3799SMasahiro Yamada 	return (((trctrfc_ext & 0x1) * 256) + trfc) * 1000
1105614e71bSYork Sun 		+ byte40_table_ps[(trctrfc_ext >> 1) & 0x7];
1115614e71bSYork Sun }
1125614e71bSYork Sun 
1135614e71bSYork Sun static unsigned int
compute_trc_ps_from_spd(unsigned char trctrfc_ext,unsigned char trc)1145614e71bSYork Sun compute_trc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trc)
1155614e71bSYork Sun {
116a4ca3799SMasahiro Yamada 	return trc * 1000 + byte40_table_ps[(trctrfc_ext >> 4) & 0x7];
1175614e71bSYork Sun }
1185614e71bSYork Sun 
1195614e71bSYork Sun /*
1205614e71bSYork Sun  * Determine Refresh Rate.  Ignore self refresh bit on DDR I.
1215614e71bSYork Sun  * Table from SPD Spec, Byte 12, converted to picoseconds and
1225614e71bSYork Sun  * filled in with "default" normal values.
1235614e71bSYork Sun  */
1245614e71bSYork Sun static unsigned int
determine_refresh_rate_ps(const unsigned int spd_refresh)1255614e71bSYork Sun determine_refresh_rate_ps(const unsigned int spd_refresh)
1265614e71bSYork Sun {
1275614e71bSYork Sun 	unsigned int refresh_time_ps[8] = {
1285614e71bSYork Sun 		15625000,	/* 0 Normal    1.00x */
1295614e71bSYork Sun 		3900000,	/* 1 Reduced    .25x */
1305614e71bSYork Sun 		7800000,	/* 2 Extended   .50x */
1315614e71bSYork Sun 		31300000,	/* 3 Extended  2.00x */
1325614e71bSYork Sun 		62500000,	/* 4 Extended  4.00x */
1335614e71bSYork Sun 		125000000,	/* 5 Extended  8.00x */
1345614e71bSYork Sun 		15625000,	/* 6 Normal    1.00x  filler */
1355614e71bSYork Sun 		15625000,	/* 7 Normal    1.00x  filler */
1365614e71bSYork Sun 	};
1375614e71bSYork Sun 
1385614e71bSYork Sun 	return refresh_time_ps[spd_refresh & 0x7];
1395614e71bSYork Sun }
1405614e71bSYork Sun 
1415614e71bSYork Sun /*
1425614e71bSYork Sun  * The purpose of this function is to compute a suitable
1435614e71bSYork Sun  * CAS latency given the DRAM clock period.  The SPD only
1445614e71bSYork Sun  * defines at most 3 CAS latencies.  Typically the slower in
1455614e71bSYork Sun  * frequency the DIMM runs at, the shorter its CAS latency can.
1465614e71bSYork Sun  * be.  If the DIMM is operating at a sufficiently low frequency,
1475614e71bSYork Sun  * it may be able to run at a CAS latency shorter than the
1485614e71bSYork Sun  * shortest SPD-defined CAS latency.
1495614e71bSYork Sun  *
1505614e71bSYork Sun  * If a CAS latency is not found, 0 is returned.
1515614e71bSYork Sun  *
1525614e71bSYork Sun  * Do this by finding in the standard speed bin table the longest
1535614e71bSYork Sun  * tCKmin that doesn't exceed the value of mclk_ps (tCK).
1545614e71bSYork Sun  *
1555614e71bSYork Sun  * An assumption made is that the SDRAM device allows the
1565614e71bSYork Sun  * CL to be programmed for a value that is lower than those
1575614e71bSYork Sun  * advertised by the SPD.  This is not always the case,
1585614e71bSYork Sun  * as those modes not defined in the SPD are optional.
1595614e71bSYork Sun  *
1605614e71bSYork Sun  * CAS latency de-rating based upon values JEDEC Standard No. 79-2C
1615614e71bSYork Sun  * Table 40, "DDR2 SDRAM stanadard speed bins and tCK, tRCD, tRP, tRAS,
1625614e71bSYork Sun  * and tRC for corresponding bin"
1635614e71bSYork Sun  *
1645614e71bSYork Sun  * ordinal 2, ddr2_speed_bins[1] contains tCK for CL=3
1655614e71bSYork Sun  * Not certain if any good value exists for CL=2
1665614e71bSYork Sun  */
1675614e71bSYork Sun 				 /* CL2   CL3   CL4   CL5   CL6  CL7*/
1685614e71bSYork Sun unsigned short ddr2_speed_bins[] = {   0, 5000, 3750, 3000, 2500, 1875 };
1695614e71bSYork Sun 
1705614e71bSYork Sun unsigned int
compute_derated_DDR2_CAS_latency(unsigned int mclk_ps)1715614e71bSYork Sun compute_derated_DDR2_CAS_latency(unsigned int mclk_ps)
1725614e71bSYork Sun {
1735614e71bSYork Sun 	const unsigned int num_speed_bins = ARRAY_SIZE(ddr2_speed_bins);
1745614e71bSYork Sun 	unsigned int lowest_tCKmin_found = 0;
1755614e71bSYork Sun 	unsigned int lowest_tCKmin_CL = 0;
1765614e71bSYork Sun 	unsigned int i;
1775614e71bSYork Sun 
1785614e71bSYork Sun 	debug("mclk_ps = %u\n", mclk_ps);
1795614e71bSYork Sun 
1805614e71bSYork Sun 	for (i = 0; i < num_speed_bins; i++) {
1815614e71bSYork Sun 		unsigned int x = ddr2_speed_bins[i];
1825614e71bSYork Sun 		debug("i=%u, x = %u, lowest_tCKmin_found = %u\n",
1835614e71bSYork Sun 		      i, x, lowest_tCKmin_found);
1845614e71bSYork Sun 		if (x && x <= mclk_ps && x >= lowest_tCKmin_found ) {
1855614e71bSYork Sun 			lowest_tCKmin_found = x;
1865614e71bSYork Sun 			lowest_tCKmin_CL = i + 2;
1875614e71bSYork Sun 		}
1885614e71bSYork Sun 	}
1895614e71bSYork Sun 
1905614e71bSYork Sun 	debug("lowest_tCKmin_CL = %u\n", lowest_tCKmin_CL);
1915614e71bSYork Sun 
1925614e71bSYork Sun 	return lowest_tCKmin_CL;
1935614e71bSYork Sun }
1945614e71bSYork Sun 
1955614e71bSYork Sun /*
1965614e71bSYork Sun  * ddr_compute_dimm_parameters for DDR2 SPD
1975614e71bSYork Sun  *
1985614e71bSYork Sun  * Compute DIMM parameters based upon the SPD information in spd.
1995614e71bSYork Sun  * Writes the results to the dimm_params_t structure pointed by pdimm.
2005614e71bSYork Sun  *
2015614e71bSYork Sun  * FIXME: use #define for the retvals
2025614e71bSYork Sun  */
ddr_compute_dimm_parameters(const unsigned int ctrl_num,const ddr2_spd_eeprom_t * spd,dimm_params_t * pdimm,unsigned int dimm_number)20303e664d8SYork Sun unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
20403e664d8SYork Sun 					 const ddr2_spd_eeprom_t *spd,
2055614e71bSYork Sun 					 dimm_params_t *pdimm,
2065614e71bSYork Sun 					 unsigned int dimm_number)
2075614e71bSYork Sun {
2085614e71bSYork Sun 	unsigned int retval;
2095614e71bSYork Sun 
2105614e71bSYork Sun 	if (spd->mem_type) {
2115614e71bSYork Sun 		if (spd->mem_type != SPD_MEMTYPE_DDR2) {
2125614e71bSYork Sun 			printf("DIMM %u: is not a DDR2 SPD.\n", dimm_number);
2135614e71bSYork Sun 			return 1;
2145614e71bSYork Sun 		}
2155614e71bSYork Sun 	} else {
2165614e71bSYork Sun 		memset(pdimm, 0, sizeof(dimm_params_t));
2175614e71bSYork Sun 		return 1;
2185614e71bSYork Sun 	}
2195614e71bSYork Sun 
2205614e71bSYork Sun 	retval = ddr2_spd_check(spd);
2215614e71bSYork Sun 	if (retval) {
2225614e71bSYork Sun 		printf("DIMM %u: failed checksum\n", dimm_number);
2235614e71bSYork Sun 		return 2;
2245614e71bSYork Sun 	}
2255614e71bSYork Sun 
2265614e71bSYork Sun 	/*
2275614e71bSYork Sun 	 * The part name in ASCII in the SPD EEPROM is not null terminated.
2285614e71bSYork Sun 	 * Guarantee null termination here by presetting all bytes to 0
2295614e71bSYork Sun 	 * and copying the part name in ASCII from the SPD onto it
2305614e71bSYork Sun 	 */
2315614e71bSYork Sun 	memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
2325614e71bSYork Sun 	memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1);
2335614e71bSYork Sun 
2345614e71bSYork Sun 	/* DIMM organization parameters */
2355614e71bSYork Sun 	pdimm->n_ranks = (spd->mod_ranks & 0x7) + 1;
2365614e71bSYork Sun 	pdimm->rank_density = compute_ranksize(spd->mem_type, spd->rank_dens);
2375614e71bSYork Sun 	pdimm->capacity = pdimm->n_ranks * pdimm->rank_density;
2385614e71bSYork Sun 	pdimm->data_width = spd->dataw;
2395614e71bSYork Sun 	pdimm->primary_sdram_width = spd->primw;
2405614e71bSYork Sun 	pdimm->ec_sdram_width = spd->ecw;
2415614e71bSYork Sun 
2425614e71bSYork Sun 	/* These are all the types defined by the JEDEC DDR2 SPD 1.3 spec */
2435614e71bSYork Sun 	switch (spd->dimm_type) {
2445614e71bSYork Sun 	case DDR2_SPD_DIMMTYPE_RDIMM:
2455614e71bSYork Sun 	case DDR2_SPD_DIMMTYPE_72B_SO_RDIMM:
2465614e71bSYork Sun 	case DDR2_SPD_DIMMTYPE_MINI_RDIMM:
2475614e71bSYork Sun 		/* Registered/buffered DIMMs */
2485614e71bSYork Sun 		pdimm->registered_dimm = 1;
2495614e71bSYork Sun 		break;
2505614e71bSYork Sun 
2515614e71bSYork Sun 	case DDR2_SPD_DIMMTYPE_UDIMM:
2525614e71bSYork Sun 	case DDR2_SPD_DIMMTYPE_SO_DIMM:
2535614e71bSYork Sun 	case DDR2_SPD_DIMMTYPE_MICRO_DIMM:
2545614e71bSYork Sun 	case DDR2_SPD_DIMMTYPE_MINI_UDIMM:
2555614e71bSYork Sun 		/* Unbuffered DIMMs */
2565614e71bSYork Sun 		pdimm->registered_dimm = 0;
2575614e71bSYork Sun 		break;
2585614e71bSYork Sun 
2595614e71bSYork Sun 	case DDR2_SPD_DIMMTYPE_72B_SO_CDIMM:
2605614e71bSYork Sun 	default:
2615614e71bSYork Sun 		printf("unknown dimm_type 0x%02X\n", spd->dimm_type);
2625614e71bSYork Sun 		return 1;
2635614e71bSYork Sun 	}
2645614e71bSYork Sun 
2655614e71bSYork Sun 	/* SDRAM device parameters */
2665614e71bSYork Sun 	pdimm->n_row_addr = spd->nrow_addr;
2675614e71bSYork Sun 	pdimm->n_col_addr = spd->ncol_addr;
2685614e71bSYork Sun 	pdimm->n_banks_per_sdram_device = spd->nbanks;
2695614e71bSYork Sun 	pdimm->edc_config = spd->config;
2705614e71bSYork Sun 	pdimm->burst_lengths_bitmask = spd->burstl;
2715614e71bSYork Sun 
2725614e71bSYork Sun 	/*
2735614e71bSYork Sun 	 * Calculate the Maximum Data Rate based on the Minimum Cycle time.
2745614e71bSYork Sun 	 * The SPD clk_cycle field (tCKmin) is measured in tenths of
2755614e71bSYork Sun 	 * nanoseconds and represented as BCD.
2765614e71bSYork Sun 	 */
2775614e71bSYork Sun 	pdimm->tckmin_x_ps
2785614e71bSYork Sun 		= convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle);
2795614e71bSYork Sun 	pdimm->tckmin_x_minus_1_ps
2805614e71bSYork Sun 		= convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle2);
2815614e71bSYork Sun 	pdimm->tckmin_x_minus_2_ps
2825614e71bSYork Sun 		= convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle3);
2835614e71bSYork Sun 
2845614e71bSYork Sun 	pdimm->tckmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd->tckmax);
2855614e71bSYork Sun 
2865614e71bSYork Sun 	/*
2875614e71bSYork Sun 	 * Compute CAS latencies defined by SPD
2885614e71bSYork Sun 	 * The SPD caslat_x should have at least 1 and at most 3 bits set.
2895614e71bSYork Sun 	 *
2905614e71bSYork Sun 	 * If cas_lat after masking is 0, the __ilog2 function returns
2915614e71bSYork Sun 	 * 255 into the variable.   This behavior is abused once.
2925614e71bSYork Sun 	 */
2935614e71bSYork Sun 	pdimm->caslat_x  = __ilog2(spd->cas_lat);
2945614e71bSYork Sun 	pdimm->caslat_x_minus_1 = __ilog2(spd->cas_lat
2955614e71bSYork Sun 					  & ~(1 << pdimm->caslat_x));
2965614e71bSYork Sun 	pdimm->caslat_x_minus_2 = __ilog2(spd->cas_lat
2975614e71bSYork Sun 					  & ~(1 << pdimm->caslat_x)
2985614e71bSYork Sun 					  & ~(1 << pdimm->caslat_x_minus_1));
2995614e71bSYork Sun 
3005614e71bSYork Sun 	/* Compute CAS latencies below that defined by SPD */
30103e664d8SYork Sun 	pdimm->caslat_lowest_derated = compute_derated_DDR2_CAS_latency(
30203e664d8SYork Sun 					get_memory_clk_period_ps(ctrl_num));
3035614e71bSYork Sun 
3045614e71bSYork Sun 	/* Compute timing parameters */
3055614e71bSYork Sun 	pdimm->trcd_ps = spd->trcd * 250;
3065614e71bSYork Sun 	pdimm->trp_ps = spd->trp * 250;
3075614e71bSYork Sun 	pdimm->tras_ps = spd->tras * 1000;
3085614e71bSYork Sun 
3095614e71bSYork Sun 	pdimm->twr_ps = spd->twr * 250;
3105614e71bSYork Sun 	pdimm->twtr_ps = spd->twtr * 250;
3115614e71bSYork Sun 	pdimm->trfc_ps = compute_trfc_ps_from_spd(spd->trctrfc_ext, spd->trfc);
3125614e71bSYork Sun 
3135614e71bSYork Sun 	pdimm->trrd_ps = spd->trrd * 250;
3145614e71bSYork Sun 	pdimm->trc_ps = compute_trc_ps_from_spd(spd->trctrfc_ext, spd->trc);
3155614e71bSYork Sun 
3165614e71bSYork Sun 	pdimm->refresh_rate_ps = determine_refresh_rate_ps(spd->refresh);
3175614e71bSYork Sun 
3185614e71bSYork Sun 	pdimm->tis_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_setup);
3195614e71bSYork Sun 	pdimm->tih_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_hold);
3205614e71bSYork Sun 	pdimm->tds_ps
3215614e71bSYork Sun 		= convert_bcd_hundredths_to_cycle_time_ps(spd->data_setup);
3225614e71bSYork Sun 	pdimm->tdh_ps
3235614e71bSYork Sun 		= convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold);
3245614e71bSYork Sun 
3255614e71bSYork Sun 	pdimm->trtp_ps = spd->trtp * 250;
3265614e71bSYork Sun 	pdimm->tdqsq_max_ps = spd->tdqsq * 10;
3275614e71bSYork Sun 	pdimm->tqhs_ps = spd->tqhs * 10;
3285614e71bSYork Sun 
3295614e71bSYork Sun 	return 0;
3305614e71bSYork Sun }
331