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