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