driver/ddr/fsl: Add DDR4 support to Freescale DDR driver
Mostly reusing DDR3 driver, this patch adds DDR4 SPD handling, register calculation and programming. Signed-off-by: York Sun <yorksun@freescale.com>
This commit is contained in:
		
							parent
							
								
									8d451a7129
								
							
						
					
					
						commit
						34e026f9b1
					
				
							
								
								
									
										13
									
								
								README
								
								
								
								
							
							
						
						
									
										13
									
								
								README
								
								
								
								
							|  | @ -458,6 +458,9 @@ The following options need to be configured: | ||||||
| 		CONFIG_SYS_FSL_DDRC_GEN3 | 		CONFIG_SYS_FSL_DDRC_GEN3 | ||||||
| 		Freescale DDR3 controller. | 		Freescale DDR3 controller. | ||||||
| 
 | 
 | ||||||
|  | 		CONFIG_SYS_FSL_DDRC_GEN4 | ||||||
|  | 		Freescale DDR4 controller. | ||||||
|  | 
 | ||||||
| 		CONFIG_SYS_FSL_DDRC_ARM_GEN3 | 		CONFIG_SYS_FSL_DDRC_ARM_GEN3 | ||||||
| 		Freescale DDR3 controller for ARM-based SoCs. | 		Freescale DDR3 controller for ARM-based SoCs. | ||||||
| 
 | 
 | ||||||
|  | @ -473,7 +476,15 @@ The following options need to be configured: | ||||||
| 
 | 
 | ||||||
| 		CONFIG_SYS_FSL_DDR3 | 		CONFIG_SYS_FSL_DDR3 | ||||||
| 		Board config to use DDR3. It can be enabled for SoCs with | 		Board config to use DDR3. It can be enabled for SoCs with | ||||||
| 		Freescale DDR3 controllers. | 		Freescale DDR3 or DDR3L controllers. | ||||||
|  | 
 | ||||||
|  | 		CONFIG_SYS_FSL_DDR3L | ||||||
|  | 		Board config to use DDR3L. It can be enabled for SoCs with | ||||||
|  | 		DDR3L controllers. | ||||||
|  | 
 | ||||||
|  | 		CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		Board config to use DDR4. It can be enabled for SoCs with | ||||||
|  | 		DDR4 controllers. | ||||||
| 
 | 
 | ||||||
| 		CONFIG_SYS_FSL_IFC_BE | 		CONFIG_SYS_FSL_IFC_BE | ||||||
| 		Defines the IFC controller register space as Big Endian | 		Defines the IFC controller register space as Big Endian | ||||||
|  |  | ||||||
|  | @ -19,8 +19,8 @@ | ||||||
|  */ |  */ | ||||||
| #define CONFIG_PPC_SPINTABLE_COMPATIBLE | #define CONFIG_PPC_SPINTABLE_COMPATIBLE | ||||||
| 
 | 
 | ||||||
| #define FSL_DDR_VER_4_7	47 | #include <fsl_ddrc_version.h> | ||||||
| #define FSL_DDR_VER_5_0	50 | #define CONFIG_SYS_FSL_DDR_BE | ||||||
| 
 | 
 | ||||||
| /* IP endianness */ | /* IP endianness */ | ||||||
| #define CONFIG_SYS_FSL_IFC_BE | #define CONFIG_SYS_FSL_IFC_BE | ||||||
|  | @ -401,6 +401,7 @@ | ||||||
| #define CONFIG_SYS_NUM_FM1_DTSEC	5 | #define CONFIG_SYS_NUM_FM1_DTSEC	5 | ||||||
| #define CONFIG_SYS_NUM_FM1_10GEC	1 | #define CONFIG_SYS_NUM_FM1_10GEC	1 | ||||||
| #define CONFIG_NUM_DDR_CONTROLLERS	1 | #define CONFIG_NUM_DDR_CONTROLLERS	1 | ||||||
|  | #define CONFIG_SYS_FSL_DDR_VER		FSL_DDR_VER_4_5 | ||||||
| #define CONFIG_SYS_FM_MURAM_SIZE	0x28000 | #define CONFIG_SYS_FM_MURAM_SIZE	0x28000 | ||||||
| #define CONFIG_SYS_FSL_TBCLK_DIV	32 | #define CONFIG_SYS_FSL_TBCLK_DIV	32 | ||||||
| #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.2" | #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.2" | ||||||
|  | @ -442,6 +443,7 @@ | ||||||
| #define CONFIG_SYS_NUM_FM1_10GEC	1 | #define CONFIG_SYS_NUM_FM1_10GEC	1 | ||||||
| #define CONFIG_SYS_NUM_FM2_10GEC	1 | #define CONFIG_SYS_NUM_FM2_10GEC	1 | ||||||
| #define CONFIG_NUM_DDR_CONTROLLERS	2 | #define CONFIG_NUM_DDR_CONTROLLERS	2 | ||||||
|  | #define CONFIG_SYS_FSL_DDR_VER		FSL_DDR_VER_4_4 | ||||||
| #define CONFIG_USB_MAX_CONTROLLER_COUNT	2 | #define CONFIG_USB_MAX_CONTROLLER_COUNT	2 | ||||||
| #define CONFIG_SYS_FM_MURAM_SIZE	0x28000 | #define CONFIG_SYS_FM_MURAM_SIZE	0x28000 | ||||||
| #define CONFIG_SYS_FSL_TBCLK_DIV	16 | #define CONFIG_SYS_FSL_TBCLK_DIV	16 | ||||||
|  | @ -490,6 +492,7 @@ | ||||||
| #define CONFIG_SYS_NUM_FM1_DTSEC	5 | #define CONFIG_SYS_NUM_FM1_DTSEC	5 | ||||||
| #define CONFIG_SYS_NUM_FM1_10GEC	1 | #define CONFIG_SYS_NUM_FM1_10GEC	1 | ||||||
| #define CONFIG_NUM_DDR_CONTROLLERS	2 | #define CONFIG_NUM_DDR_CONTROLLERS	2 | ||||||
|  | #define CONFIG_SYS_FSL_DDR_VER		FSL_DDR_VER_4_4 | ||||||
| #define CONFIG_USB_MAX_CONTROLLER_COUNT	2 | #define CONFIG_USB_MAX_CONTROLLER_COUNT	2 | ||||||
| #define CONFIG_SYS_FM_MURAM_SIZE	0x28000 | #define CONFIG_SYS_FM_MURAM_SIZE	0x28000 | ||||||
| #define CONFIG_SYS_FSL_TBCLK_DIV	32 | #define CONFIG_SYS_FSL_TBCLK_DIV	32 | ||||||
|  | @ -527,6 +530,7 @@ | ||||||
| #define CONFIG_SYS_NUM_FM2_DTSEC	5 | #define CONFIG_SYS_NUM_FM2_DTSEC	5 | ||||||
| #define CONFIG_SYS_NUM_FM2_10GEC	1 | #define CONFIG_SYS_NUM_FM2_10GEC	1 | ||||||
| #define CONFIG_NUM_DDR_CONTROLLERS	2 | #define CONFIG_NUM_DDR_CONTROLLERS	2 | ||||||
|  | #define CONFIG_SYS_FSL_DDR_VER		FSL_DDR_VER_4_4 | ||||||
| #define CONFIG_USB_MAX_CONTROLLER_COUNT	2 | #define CONFIG_USB_MAX_CONTROLLER_COUNT	2 | ||||||
| #define CONFIG_SYS_FM_MURAM_SIZE	0x28000 | #define CONFIG_SYS_FM_MURAM_SIZE	0x28000 | ||||||
| #define CONFIG_SYS_FSL_TBCLK_DIV	16 | #define CONFIG_SYS_FSL_TBCLK_DIV	16 | ||||||
|  | @ -553,6 +557,7 @@ | ||||||
| #define CONFIG_TSECV2 | #define CONFIG_TSECV2 | ||||||
| #define CONFIG_SYS_FSL_SEC_COMPAT	4 | #define CONFIG_SYS_FSL_SEC_COMPAT	4 | ||||||
| #define CONFIG_NUM_DDR_CONTROLLERS	1 | #define CONFIG_NUM_DDR_CONTROLLERS	1 | ||||||
|  | #define CONFIG_SYS_FSL_DDR_VER		FSL_DDR_VER_4_4 | ||||||
| #define CONFIG_USB_MAX_CONTROLLER_COUNT	1 | #define CONFIG_USB_MAX_CONTROLLER_COUNT	1 | ||||||
| #define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR	0xb0000000 | #define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR	0xb0000000 | ||||||
| #define CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT	0xff600000 | #define CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT	0xff600000 | ||||||
|  | @ -571,6 +576,7 @@ | ||||||
| #define CONFIG_TSECV2 | #define CONFIG_TSECV2 | ||||||
| #define CONFIG_SYS_FSL_SEC_COMPAT	4 | #define CONFIG_SYS_FSL_SEC_COMPAT	4 | ||||||
| #define CONFIG_NUM_DDR_CONTROLLERS	2 | #define CONFIG_NUM_DDR_CONTROLLERS	2 | ||||||
|  | #define CONFIG_SYS_FSL_DDR_VER		FSL_DDR_VER_4_6 | ||||||
| #define CONFIG_USB_MAX_CONTROLLER_COUNT	1 | #define CONFIG_USB_MAX_CONTROLLER_COUNT	1 | ||||||
| #define CONFIG_SYS_FSL_DSP_DDR_ADDR	0x40000000 | #define CONFIG_SYS_FSL_DSP_DDR_ADDR	0x40000000 | ||||||
| #define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR	0xb0000000 | #define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR	0xb0000000 | ||||||
|  | @ -704,6 +710,9 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) | ||||||
| #define CONFIG_SYS_FSL_QORIQ_CHASSIS2	/* Freescale Chassis generation 2 */ | #define CONFIG_SYS_FSL_QORIQ_CHASSIS2	/* Freescale Chassis generation 2 */ | ||||||
| #define CONFIG_SYS_FSL_CORES_PER_CLUSTER 1 | #define CONFIG_SYS_FSL_CORES_PER_CLUSTER 1 | ||||||
| #define CONFIG_SYS_FSL_QMAN_V3		/* QMAN version 3 */ | #define CONFIG_SYS_FSL_QMAN_V3		/* QMAN version 3 */ | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | #define CONFIG_SYS_FSL_DDRC_GEN4 | ||||||
|  | #endif | ||||||
| #if defined(CONFIG_PPC_T1040) || defined(CONFIG_PPC_T1042) | #if defined(CONFIG_PPC_T1040) || defined(CONFIG_PPC_T1042) | ||||||
| #define CONFIG_MAX_CPUS			4 | #define CONFIG_MAX_CPUS			4 | ||||||
| #elif defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) | #elif defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) | ||||||
|  | @ -796,6 +805,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) | ||||||
| #define CONFIG_SYS_FSL_SEC_COMPAT	6 | #define CONFIG_SYS_FSL_SEC_COMPAT	6 | ||||||
| #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 | #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 | ||||||
| #define CONFIG_NUM_DDR_CONTROLLERS	1 | #define CONFIG_NUM_DDR_CONTROLLERS	1 | ||||||
|  | #define CONFIG_SYS_FSL_DDR_VER		FSL_DDR_VER_4_6 | ||||||
| #define CONFIG_SYS_FSL_IFC_BANK_COUNT	8 | #define CONFIG_SYS_FSL_IFC_BANK_COUNT	8 | ||||||
| #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000 | #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000 | ||||||
| #define CONFIG_SYS_FSL_ERRATUM_A005125 | #define CONFIG_SYS_FSL_ERRATUM_A005125 | ||||||
|  | @ -820,7 +830,8 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) | ||||||
| 
 | 
 | ||||||
| #if !defined(CONFIG_SYS_FSL_DDRC_GEN1) && \ | #if !defined(CONFIG_SYS_FSL_DDRC_GEN1) && \ | ||||||
| 	!defined(CONFIG_SYS_FSL_DDRC_GEN2) && \ | 	!defined(CONFIG_SYS_FSL_DDRC_GEN2) && \ | ||||||
| 	!defined(CONFIG_SYS_FSL_DDRC_GEN3) | 	!defined(CONFIG_SYS_FSL_DDRC_GEN3) && \ | ||||||
|  | 	!defined(CONFIG_SYS_FSL_DDRC_GEN4) | ||||||
| #define CONFIG_SYS_FSL_DDRC_GEN3 | #define CONFIG_SYS_FSL_DDRC_GEN3 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008 Freescale Semiconductor, Inc. |  * Copyright 2008-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or |  * This program is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU General Public License |  * modify it under the terms of the GNU General Public License | ||||||
|  | @ -116,3 +116,46 @@ ddr3_spd_check(const ddr3_spd_eeprom_t *spd) | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s *spd) | ||||||
|  | { | ||||||
|  | 	char *p = (char *)spd; | ||||||
|  | 	int csum16; | ||||||
|  | 	int len; | ||||||
|  | 	char crc_lsb;	/* byte 126 */ | ||||||
|  | 	char crc_msb;	/* byte 127 */ | ||||||
|  | 
 | ||||||
|  | 	len = 126; | ||||||
|  | 	csum16 = crc16(p, len); | ||||||
|  | 
 | ||||||
|  | 	crc_lsb = (char) (csum16 & 0xff); | ||||||
|  | 	crc_msb = (char) (csum16 >> 8); | ||||||
|  | 
 | ||||||
|  | 	if (spd->crc[0] != crc_lsb || spd->crc[1] != crc_msb) { | ||||||
|  | 		printf("SPD checksum unexpected.\n" | ||||||
|  | 			"Checksum lsb in SPD = %02X, computed SPD = %02X\n" | ||||||
|  | 			"Checksum msb in SPD = %02X, computed SPD = %02X\n", | ||||||
|  | 			spd->crc[0], crc_lsb, spd->crc[1], crc_msb); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	p = (char *)((ulong)spd + 128); | ||||||
|  | 	len = 126; | ||||||
|  | 	csum16 = crc16(p, len); | ||||||
|  | 
 | ||||||
|  | 	crc_lsb = (char) (csum16 & 0xff); | ||||||
|  | 	crc_msb = (char) (csum16 >> 8); | ||||||
|  | 
 | ||||||
|  | 	if (spd->mod_section.uc[126] != crc_lsb || | ||||||
|  | 	    spd->mod_section.uc[127] != crc_msb) { | ||||||
|  | 		printf("SPD checksum unexpected.\n" | ||||||
|  | 			"Checksum lsb in SPD = %02X, computed SPD = %02X\n" | ||||||
|  | 			"Checksum msb in SPD = %02X, computed SPD = %02X\n", | ||||||
|  | 			spd->mod_section.uc[126], | ||||||
|  | 			crc_lsb, spd->mod_section.uc[127], | ||||||
|  | 			crc_msb); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| #
 | #
 | ||||||
| # Copyright 2008-2011 Freescale Semiconductor, Inc.
 | # Copyright 2008-2014 Freescale Semiconductor, Inc.
 | ||||||
| #
 | #
 | ||||||
| # This program is free software; you can redistribute it and/or
 | # This program is free software; you can redistribute it and/or
 | ||||||
| # modify it under the terms of the GNU General Public License
 | # modify it under the terms of the GNU General Public License
 | ||||||
|  | @ -8,12 +8,13 @@ | ||||||
| 
 | 
 | ||||||
| obj-$(CONFIG_SYS_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \
 | obj-$(CONFIG_SYS_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \
 | ||||||
| 				lc_common_dimm_params.o | 				lc_common_dimm_params.o | ||||||
| 
 |  | ||||||
| obj-$(CONFIG_SYS_FSL_DDR2) += main.o util.o ctrl_regs.o options.o \
 | obj-$(CONFIG_SYS_FSL_DDR2) += main.o util.o ctrl_regs.o options.o \
 | ||||||
| 				lc_common_dimm_params.o | 				lc_common_dimm_params.o | ||||||
| 
 |  | ||||||
| obj-$(CONFIG_SYS_FSL_DDR3) += main.o util.o ctrl_regs.o options.o \
 | obj-$(CONFIG_SYS_FSL_DDR3) += main.o util.o ctrl_regs.o options.o \
 | ||||||
| 				lc_common_dimm_params.o | 				lc_common_dimm_params.o | ||||||
|  | obj-$(CONFIG_SYS_FSL_DDR4) += main.o util.o ctrl_regs.o options.o \
 | ||||||
|  | 				lc_common_dimm_params.o | ||||||
|  | 
 | ||||||
| ifdef CONFIG_DDR_SPD | ifdef CONFIG_DDR_SPD | ||||||
| SPD := y | SPD := y | ||||||
| endif | endif | ||||||
|  | @ -24,6 +25,7 @@ ifdef SPD | ||||||
| obj-$(CONFIG_SYS_FSL_DDR1)	+= ddr1_dimm_params.o | obj-$(CONFIG_SYS_FSL_DDR1)	+= ddr1_dimm_params.o | ||||||
| obj-$(CONFIG_SYS_FSL_DDR2)	+= ddr2_dimm_params.o | obj-$(CONFIG_SYS_FSL_DDR2)	+= ddr2_dimm_params.o | ||||||
| obj-$(CONFIG_SYS_FSL_DDR3)	+= ddr3_dimm_params.o | obj-$(CONFIG_SYS_FSL_DDR3)	+= ddr3_dimm_params.o | ||||||
|  | obj-$(CONFIG_SYS_FSL_DDR4)	+= ddr4_dimm_params.o | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| obj-$(CONFIG_FSL_DDR_INTERACTIVE)	+= interactive.o | obj-$(CONFIG_FSL_DDR_INTERACTIVE)	+= interactive.o | ||||||
|  | @ -32,3 +34,4 @@ obj-$(CONFIG_SYS_FSL_DDRC_GEN2)	+= mpc85xx_ddr_gen2.o | ||||||
| obj-$(CONFIG_SYS_FSL_DDRC_GEN3)	+= mpc85xx_ddr_gen3.o | obj-$(CONFIG_SYS_FSL_DDRC_GEN3)	+= mpc85xx_ddr_gen3.o | ||||||
| obj-$(CONFIG_SYS_FSL_DDR_86XX)		+= mpc86xx_ddr.o | obj-$(CONFIG_SYS_FSL_DDR_86XX)		+= mpc86xx_ddr.o | ||||||
| obj-$(CONFIG_SYS_FSL_DDRC_ARM_GEN3)	+= arm_ddr_gen3.o | obj-$(CONFIG_SYS_FSL_DDRC_ARM_GEN3)	+= arm_ddr_gen3.o | ||||||
|  | obj-$(CONFIG_SYS_FSL_DDRC_GEN4) += fsl_ddr_gen4.o | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,300 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2014 Freescale Semiconductor, Inc. | ||||||
|  |  * | ||||||
|  |  * calculate the organization and timing parameter | ||||||
|  |  * from ddr3 spd, please refer to the spec | ||||||
|  |  * JEDEC standard No.21-C 4_01_02_12R23A.pdf | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <fsl_ddr_sdram.h> | ||||||
|  | 
 | ||||||
|  | #include <fsl_ddr.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Calculate the Density of each Physical Rank. | ||||||
|  |  * Returned size is in bytes. | ||||||
|  |  * | ||||||
|  |  * Total DIMM size = | ||||||
|  |  * sdram capacity(bit) / 8 * primary bus width / sdram width | ||||||
|  |  *                     * Logical Ranks per DIMM | ||||||
|  |  * | ||||||
|  |  * where: sdram capacity  = spd byte4[3:0] | ||||||
|  |  *        primary bus width = spd byte13[2:0] | ||||||
|  |  *        sdram width = spd byte12[2:0] | ||||||
|  |  *        Logical Ranks per DIMM = spd byte12[5:3] for SDP, DDP, QDP | ||||||
|  |  *                                 spd byte12{5:3] * spd byte6[6:4] for 3DS | ||||||
|  |  * | ||||||
|  |  * To simplify each rank size = total DIMM size / Number of Package Ranks | ||||||
|  |  * where Number of Package Ranks = spd byte12[5:3] | ||||||
|  |  * | ||||||
|  |  * SPD byte4 - sdram density and banks | ||||||
|  |  *	bit[3:0]	size(bit)	size(byte) | ||||||
|  |  *	0000		256Mb		32MB | ||||||
|  |  *	0001		512Mb		64MB | ||||||
|  |  *	0010		1Gb		128MB | ||||||
|  |  *	0011		2Gb		256MB | ||||||
|  |  *	0100		4Gb		512MB | ||||||
|  |  *	0101		8Gb		1GB | ||||||
|  |  *	0110		16Gb		2GB | ||||||
|  |  *      0111		32Gb		4GB | ||||||
|  |  * | ||||||
|  |  * SPD byte13 - module memory bus width | ||||||
|  |  *	bit[2:0]	primary bus width | ||||||
|  |  *	000		8bits | ||||||
|  |  *	001		16bits | ||||||
|  |  *	010		32bits | ||||||
|  |  *	011		64bits | ||||||
|  |  * | ||||||
|  |  * SPD byte12 - module organization | ||||||
|  |  *	bit[2:0]	sdram device width | ||||||
|  |  *	000		4bits | ||||||
|  |  *	001		8bits | ||||||
|  |  *	010		16bits | ||||||
|  |  *	011		32bits | ||||||
|  |  * | ||||||
|  |  * SPD byte12 - module organization | ||||||
|  |  *	bit[5:3]	number of package ranks per DIMM | ||||||
|  |  *	000		1 | ||||||
|  |  *	001		2 | ||||||
|  |  *	010		3 | ||||||
|  |  *	011		4 | ||||||
|  |  * | ||||||
|  |  * SPD byte6 - SDRAM package type | ||||||
|  |  *	bit[6:4]	Die count | ||||||
|  |  *	000		1 | ||||||
|  |  *	001		2 | ||||||
|  |  *	010		3 | ||||||
|  |  *	011		4 | ||||||
|  |  *	100		5 | ||||||
|  |  *	101		6 | ||||||
|  |  *	110		7 | ||||||
|  |  *	111		8 | ||||||
|  |  * | ||||||
|  |  * SPD byte6 - SRAM package type | ||||||
|  |  *	bit[1:0]	Signal loading | ||||||
|  |  *	00		Not specified | ||||||
|  |  *	01		Multi load stack | ||||||
|  |  *	10		Sigle load stack (3DS) | ||||||
|  |  *	11		Reserved | ||||||
|  |  */ | ||||||
|  | static unsigned long long | ||||||
|  | compute_ranksize(const struct ddr4_spd_eeprom_s *spd) | ||||||
|  | { | ||||||
|  | 	unsigned long long bsize; | ||||||
|  | 
 | ||||||
|  | 	int nbit_sdram_cap_bsize = 0; | ||||||
|  | 	int nbit_primary_bus_width = 0; | ||||||
|  | 	int nbit_sdram_width = 0; | ||||||
|  | 	int die_count = 0; | ||||||
|  | 	bool package_3ds; | ||||||
|  | 
 | ||||||
|  | 	if ((spd->density_banks & 0xf) <= 7) | ||||||
|  | 		nbit_sdram_cap_bsize = (spd->density_banks & 0xf) + 28; | ||||||
|  | 	if ((spd->bus_width & 0x7) < 4) | ||||||
|  | 		nbit_primary_bus_width = (spd->bus_width & 0x7) + 3; | ||||||
|  | 	if ((spd->organization & 0x7) < 4) | ||||||
|  | 		nbit_sdram_width = (spd->organization & 0x7) + 2; | ||||||
|  | 	package_3ds = (spd->package_type & 0x3) == 0x2; | ||||||
|  | 	if (package_3ds) | ||||||
|  | 		die_count = (spd->package_type >> 4) & 0x7; | ||||||
|  | 
 | ||||||
|  | 	bsize = 1ULL << (nbit_sdram_cap_bsize - 3 + | ||||||
|  | 			 nbit_primary_bus_width - nbit_sdram_width + | ||||||
|  | 			 die_count); | ||||||
|  | 
 | ||||||
|  | 	debug("DDR: DDR III rank density = 0x%16llx\n", bsize); | ||||||
|  | 
 | ||||||
|  | 	return bsize; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define spd_to_ps(mtb, ftb)	\ | ||||||
|  | 	(mtb * pdimm->mtb_ps + (ftb * pdimm->ftb_10th_ps) / 10) | ||||||
|  | /*
 | ||||||
|  |  * ddr_compute_dimm_parameters for DDR3 SPD | ||||||
|  |  * | ||||||
|  |  * Compute DIMM parameters based upon the SPD information in spd. | ||||||
|  |  * Writes the results to the dimm_params_t structure pointed by pdimm. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | unsigned int | ||||||
|  | ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd, | ||||||
|  | 			    dimm_params_t *pdimm, | ||||||
|  | 			    unsigned int dimm_number) | ||||||
|  | { | ||||||
|  | 	unsigned int retval; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	if (spd->mem_type) { | ||||||
|  | 		if (spd->mem_type != SPD_MEMTYPE_DDR4) { | ||||||
|  | 			printf("DIMM %u: is not a DDR4 SPD.\n", dimm_number); | ||||||
|  | 			return 1; | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		memset(pdimm, 0, sizeof(dimm_params_t)); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	retval = ddr4_spd_check(spd); | ||||||
|  | 	if (retval) { | ||||||
|  | 		printf("DIMM %u: failed checksum\n", dimm_number); | ||||||
|  | 		return 2; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * The part name in ASCII in the SPD EEPROM is not null terminated. | ||||||
|  | 	 * Guarantee null termination here by presetting all bytes to 0 | ||||||
|  | 	 * and copying the part name in ASCII from the SPD onto it | ||||||
|  | 	 */ | ||||||
|  | 	memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); | ||||||
|  | 	if ((spd->info_size_crc & 0xF) > 2) | ||||||
|  | 		memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1); | ||||||
|  | 
 | ||||||
|  | 	/* DIMM organization parameters */ | ||||||
|  | 	pdimm->n_ranks = ((spd->organization >> 3) & 0x7) + 1; | ||||||
|  | 	pdimm->rank_density = compute_ranksize(spd); | ||||||
|  | 	pdimm->capacity = pdimm->n_ranks * pdimm->rank_density; | ||||||
|  | 	pdimm->primary_sdram_width = 1 << (3 + (spd->bus_width & 0x7)); | ||||||
|  | 	if ((spd->bus_width >> 3) & 0x3) | ||||||
|  | 		pdimm->ec_sdram_width = 8; | ||||||
|  | 	else | ||||||
|  | 		pdimm->ec_sdram_width = 0; | ||||||
|  | 	pdimm->data_width = pdimm->primary_sdram_width | ||||||
|  | 			  + pdimm->ec_sdram_width; | ||||||
|  | 	pdimm->device_width = 1 << ((spd->organization & 0x7) + 2); | ||||||
|  | 
 | ||||||
|  | 	/* These are the types defined by the JEDEC DDR3 SPD spec */ | ||||||
|  | 	pdimm->mirrored_dimm = 0; | ||||||
|  | 	pdimm->registered_dimm = 0; | ||||||
|  | 	switch (spd->module_type & DDR3_SPD_MODULETYPE_MASK) { | ||||||
|  | 	case DDR3_SPD_MODULETYPE_RDIMM: | ||||||
|  | 		/* Registered/buffered DIMMs */ | ||||||
|  | 		pdimm->registered_dimm = 1; | ||||||
|  | 		break; | ||||||
|  | 
 | ||||||
|  | 	case DDR3_SPD_MODULETYPE_UDIMM: | ||||||
|  | 	case DDR3_SPD_MODULETYPE_SO_DIMM: | ||||||
|  | 		/* Unbuffered DIMMs */ | ||||||
|  | 		if (spd->mod_section.unbuffered.addr_mapping & 0x1) | ||||||
|  | 			pdimm->mirrored_dimm = 1; | ||||||
|  | 		break; | ||||||
|  | 
 | ||||||
|  | 	default: | ||||||
|  | 		printf("unknown module_type 0x%02X\n", spd->module_type); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* SDRAM device parameters */ | ||||||
|  | 	pdimm->n_row_addr = ((spd->addressing >> 3) & 0x7) + 12; | ||||||
|  | 	pdimm->n_col_addr = (spd->addressing & 0x7) + 9; | ||||||
|  | 	pdimm->bank_addr_bits = (spd->density_banks >> 4) & 0x3; | ||||||
|  | 	pdimm->bank_group_bits = (spd->density_banks >> 6) & 0x3; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * The SPD spec has not the ECC bit, | ||||||
|  | 	 * We consider the DIMM as ECC capability | ||||||
|  | 	 * when the extension bus exist | ||||||
|  | 	 */ | ||||||
|  | 	if (pdimm->ec_sdram_width) | ||||||
|  | 		pdimm->edc_config = 0x02; | ||||||
|  | 	else | ||||||
|  | 		pdimm->edc_config = 0x00; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * The SPD spec has not the burst length byte | ||||||
|  | 	 * but DDR4 spec has nature BL8 and BC4, | ||||||
|  | 	 * BL8 -bit3, BC4 -bit2 | ||||||
|  | 	 */ | ||||||
|  | 	pdimm->burst_lengths_bitmask = 0x0c; | ||||||
|  | 	pdimm->row_density = __ilog2(pdimm->rank_density); | ||||||
|  | 
 | ||||||
|  | 	/* MTB - medium timebase
 | ||||||
|  | 	 * The MTB in the SPD spec is 125ps, | ||||||
|  | 	 * | ||||||
|  | 	 * FTB - fine timebase | ||||||
|  | 	 * use 1/10th of ps as our unit to avoid floating point | ||||||
|  | 	 * eg, 10 for 1ps, 25 for 2.5ps, 50 for 5ps | ||||||
|  | 	 */ | ||||||
|  | 	if ((spd->timebases & 0xf) == 0x0) { | ||||||
|  | 		pdimm->mtb_ps = 125; | ||||||
|  | 		pdimm->ftb_10th_ps = 10; | ||||||
|  | 
 | ||||||
|  | 	} else { | ||||||
|  | 		printf("Unknown Timebases\n"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* sdram minimum cycle time */ | ||||||
|  | 	pdimm->tckmin_x_ps = spd_to_ps(spd->tck_min, spd->fine_tck_min); | ||||||
|  | 
 | ||||||
|  | 	/* sdram max cycle time */ | ||||||
|  | 	pdimm->tckmax_ps = spd_to_ps(spd->tck_max, spd->fine_tck_max); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * CAS latency supported | ||||||
|  | 	 * bit0 - CL7 | ||||||
|  | 	 * bit4 - CL11 | ||||||
|  | 	 * bit8 - CL15 | ||||||
|  | 	 * bit12- CL19 | ||||||
|  | 	 * bit16- CL23 | ||||||
|  | 	 */ | ||||||
|  | 	pdimm->caslat_x  = (spd->caslat_b1 << 7)	| | ||||||
|  | 			   (spd->caslat_b2 << 15)	| | ||||||
|  | 			   (spd->caslat_b3 << 23); | ||||||
|  | 
 | ||||||
|  | 	BUG_ON(spd->caslat_b4 != 0); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * min CAS latency time | ||||||
|  | 	 */ | ||||||
|  | 	pdimm->taa_ps = spd_to_ps(spd->taa_min, spd->fine_taa_min); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * min RAS to CAS delay time | ||||||
|  | 	 */ | ||||||
|  | 	pdimm->trcd_ps = spd_to_ps(spd->trcd_min, spd->fine_trcd_min); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Min Row Precharge Delay Time | ||||||
|  | 	 */ | ||||||
|  | 	pdimm->trp_ps = spd_to_ps(spd->trp_min, spd->fine_trp_min); | ||||||
|  | 
 | ||||||
|  | 	/* min active to precharge delay time */ | ||||||
|  | 	pdimm->tras_ps = (((spd->tras_trc_ext & 0xf) << 8) + | ||||||
|  | 			  spd->tras_min_lsb) * pdimm->mtb_ps; | ||||||
|  | 
 | ||||||
|  | 	/* min active to actice/refresh delay time */ | ||||||
|  | 	pdimm->trc_ps = spd_to_ps((((spd->tras_trc_ext & 0xf0) << 4) + | ||||||
|  | 				   spd->trc_min_lsb), spd->fine_trc_min); | ||||||
|  | 	/* Min Refresh Recovery Delay Time */ | ||||||
|  | 	pdimm->trfc1_ps = ((spd->trfc1_min_msb << 8) | (spd->trfc1_min_lsb)) * | ||||||
|  | 		       pdimm->mtb_ps; | ||||||
|  | 	pdimm->trfc2_ps = ((spd->trfc2_min_msb << 8) | (spd->trfc2_min_lsb)) * | ||||||
|  | 		       pdimm->mtb_ps; | ||||||
|  | 	pdimm->trfc4_ps = ((spd->trfc4_min_msb << 8) | (spd->trfc4_min_lsb)) * | ||||||
|  | 			pdimm->mtb_ps; | ||||||
|  | 	/* min four active window delay time */ | ||||||
|  | 	pdimm->tfaw_ps = (((spd->tfaw_msb & 0xf) << 8) | spd->tfaw_min) * | ||||||
|  | 			pdimm->mtb_ps; | ||||||
|  | 
 | ||||||
|  | 	/* min row active to row active delay time, different bank group */ | ||||||
|  | 	pdimm->trrds_ps = spd_to_ps(spd->trrds_min, spd->fine_trrds_min); | ||||||
|  | 	/* min row active to row active delay time, same bank group */ | ||||||
|  | 	pdimm->trrdl_ps = spd_to_ps(spd->trrdl_min, spd->fine_trrdl_min); | ||||||
|  | 	/* min CAS to CAS Delay Time (tCCD_Lmin), same bank group */ | ||||||
|  | 	pdimm->tccdl_ps = spd_to_ps(spd->tccdl_min, spd->fine_tccdl_min); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Average periodic refresh interval | ||||||
|  | 	 * tREFI = 7.8 us at normal temperature range | ||||||
|  | 	 */ | ||||||
|  | 	pdimm->refresh_rate_ps = 7800000; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 18; i++) | ||||||
|  | 		pdimm->dq_mapping[i] = spd->mapping[i]; | ||||||
|  | 
 | ||||||
|  | 	pdimm->dq_mapping_ors = ((spd->mapping[0] >> 6) & 0x3) == 0 ? 1 : 0; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,234 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2014 Freescale Semiconductor, Inc. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier:	GPL-2.0+ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <asm/io.h> | ||||||
|  | #include <fsl_ddr_sdram.h> | ||||||
|  | #include <asm/processor.h> | ||||||
|  | #include <fsl_ddr.h> | ||||||
|  | 
 | ||||||
|  | #if (CONFIG_CHIP_SELECTS_PER_CTRL > 4) | ||||||
|  | #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * regs has the to-be-set values for DDR controller registers | ||||||
|  |  * ctrl_num is the DDR controller number | ||||||
|  |  * step: 0 goes through the initialization in one pass | ||||||
|  |  *       1 sets registers and returns before enabling controller | ||||||
|  |  *       2 resumes from step 1 and continues to initialize | ||||||
|  |  * Dividing the initialization to two steps to deassert DDR reset signal | ||||||
|  |  * to comply with JEDEC specs for RDIMMs. | ||||||
|  |  */ | ||||||
|  | void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, | ||||||
|  | 			     unsigned int ctrl_num, int step) | ||||||
|  | { | ||||||
|  | 	unsigned int i, bus_width; | ||||||
|  | 	struct ccsr_ddr __iomem *ddr; | ||||||
|  | 	u32 temp_sdram_cfg; | ||||||
|  | 	u32 total_gb_size_per_controller; | ||||||
|  | 	int timeout; | ||||||
|  | 
 | ||||||
|  | 	switch (ctrl_num) { | ||||||
|  | 	case 0: | ||||||
|  | 		ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; | ||||||
|  | 		break; | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) | ||||||
|  | 	case 1: | ||||||
|  | 		ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; | ||||||
|  | 		break; | ||||||
|  | #endif | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) | ||||||
|  | 	case 2: | ||||||
|  | 		ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; | ||||||
|  | 		break; | ||||||
|  | #endif | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) | ||||||
|  | 	case 3: | ||||||
|  | 		ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; | ||||||
|  | 		break; | ||||||
|  | #endif | ||||||
|  | 	default: | ||||||
|  | 		printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (step == 2) | ||||||
|  | 		goto step2; | ||||||
|  | 
 | ||||||
|  | 	if (regs->ddr_eor) | ||||||
|  | 		ddr_out32(&ddr->eor, regs->ddr_eor); | ||||||
|  | 
 | ||||||
|  | 	ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { | ||||||
|  | 		if (i == 0) { | ||||||
|  | 			ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds); | ||||||
|  | 			ddr_out32(&ddr->cs0_config, regs->cs[i].config); | ||||||
|  | 			ddr_out32(&ddr->cs0_config_2, regs->cs[i].config_2); | ||||||
|  | 
 | ||||||
|  | 		} else if (i == 1) { | ||||||
|  | 			ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds); | ||||||
|  | 			ddr_out32(&ddr->cs1_config, regs->cs[i].config); | ||||||
|  | 			ddr_out32(&ddr->cs1_config_2, regs->cs[i].config_2); | ||||||
|  | 
 | ||||||
|  | 		} else if (i == 2) { | ||||||
|  | 			ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds); | ||||||
|  | 			ddr_out32(&ddr->cs2_config, regs->cs[i].config); | ||||||
|  | 			ddr_out32(&ddr->cs2_config_2, regs->cs[i].config_2); | ||||||
|  | 
 | ||||||
|  | 		} else if (i == 3) { | ||||||
|  | 			ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds); | ||||||
|  | 			ddr_out32(&ddr->cs3_config, regs->cs[i].config); | ||||||
|  | 			ddr_out32(&ddr->cs3_config_2, regs->cs[i].config_2); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_3, regs->timing_cfg_3); | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0); | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1); | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2); | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4); | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5); | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_6, regs->timing_cfg_6); | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_7, regs->timing_cfg_7); | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_8, regs->timing_cfg_8); | ||||||
|  | 	ddr_out32(&ddr->timing_cfg_9, regs->timing_cfg_9); | ||||||
|  | 	ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl); | ||||||
|  | 	ddr_out32(&ddr->dq_map_0, regs->dq_map_0); | ||||||
|  | 	ddr_out32(&ddr->dq_map_1, regs->dq_map_1); | ||||||
|  | 	ddr_out32(&ddr->dq_map_2, regs->dq_map_2); | ||||||
|  | 	ddr_out32(&ddr->dq_map_3, regs->dq_map_3); | ||||||
|  | 	ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); | ||||||
|  | 	ddr_out32(&ddr->sdram_cfg_3, regs->ddr_sdram_cfg_3); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_9, regs->ddr_sdram_mode_9); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_10, regs->ddr_sdram_mode_10); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_11, regs->ddr_sdram_mode_11); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_12, regs->ddr_sdram_mode_12); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_13, regs->ddr_sdram_mode_13); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_14, regs->ddr_sdram_mode_14); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_15, regs->ddr_sdram_mode_15); | ||||||
|  | 	ddr_out32(&ddr->sdram_mode_16, regs->ddr_sdram_mode_16); | ||||||
|  | 	ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl); | ||||||
|  | 	ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval); | ||||||
|  | 	ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init); | ||||||
|  | 	ddr_out32(&ddr->init_addr, regs->ddr_init_addr); | ||||||
|  | 	ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); | ||||||
|  | 	ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl); | ||||||
|  | #ifndef CONFIG_SYS_FSL_DDR_EMU | ||||||
|  | 	/*
 | ||||||
|  | 	 * Skip these two registers if running on emulator | ||||||
|  | 	 * because emulator doesn't have skew between bytes. | ||||||
|  | 	 */ | ||||||
|  | 
 | ||||||
|  | 	if (regs->ddr_wrlvl_cntl_2) | ||||||
|  | 		ddr_out32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2); | ||||||
|  | 	if (regs->ddr_wrlvl_cntl_3) | ||||||
|  | 		ddr_out32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 	ddr_out32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr); | ||||||
|  | 	ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1); | ||||||
|  | 	ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2); | ||||||
|  | 	ddr_out32(&ddr->ddr_sdram_rcw_3, regs->ddr_sdram_rcw_3); | ||||||
|  | 	ddr_out32(&ddr->ddr_sdram_rcw_4, regs->ddr_sdram_rcw_4); | ||||||
|  | 	ddr_out32(&ddr->ddr_sdram_rcw_5, regs->ddr_sdram_rcw_5); | ||||||
|  | 	ddr_out32(&ddr->ddr_sdram_rcw_6, regs->ddr_sdram_rcw_6); | ||||||
|  | 	ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1); | ||||||
|  | 	ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2); | ||||||
|  | 	ddr_out32(&ddr->err_disable, regs->err_disable); | ||||||
|  | 	ddr_out32(&ddr->err_int_en, regs->err_int_en); | ||||||
|  | 	for (i = 0; i < 32; i++) { | ||||||
|  | 		if (regs->debug[i]) { | ||||||
|  | 			debug("Write to debug_%d as %08x\n", | ||||||
|  | 			      i+1, regs->debug[i]); | ||||||
|  | 			ddr_out32(&ddr->debug[i], regs->debug[i]); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * For RDIMMs, JEDEC spec requires clocks to be stable before reset is | ||||||
|  | 	 * deasserted. Clocks start when any chip select is enabled and clock | ||||||
|  | 	 * control register is set. Because all DDR components are connected to | ||||||
|  | 	 * one reset signal, this needs to be done in two steps. Step 1 is to | ||||||
|  | 	 * get the clocks started. Step 2 resumes after reset signal is | ||||||
|  | 	 * deasserted. | ||||||
|  | 	 */ | ||||||
|  | 	if (step == 1) { | ||||||
|  | 		udelay(200); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | step2: | ||||||
|  | 	/* Set, but do not enable the memory */ | ||||||
|  | 	temp_sdram_cfg = regs->ddr_sdram_cfg; | ||||||
|  | 	temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN); | ||||||
|  | 	ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * 500 painful micro-seconds must elapse between | ||||||
|  | 	 * the DDR clock setup and the DDR config enable. | ||||||
|  | 	 * DDR2 need 200 us, and DDR3 need 500 us from spec, | ||||||
|  | 	 * we choose the max, that is 500 us for all of case. | ||||||
|  | 	 */ | ||||||
|  | 	udelay(500); | ||||||
|  | 	asm volatile("sync;isync"); | ||||||
|  | 
 | ||||||
|  | 	/* Let the controller go */ | ||||||
|  | 	temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; | ||||||
|  | 	ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); | ||||||
|  | 	asm volatile("sync;isync"); | ||||||
|  | 
 | ||||||
|  | 	total_gb_size_per_controller = 0; | ||||||
|  | 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { | ||||||
|  | 		if (!(regs->cs[i].config & 0x80000000)) | ||||||
|  | 			continue; | ||||||
|  | 		total_gb_size_per_controller += 1 << ( | ||||||
|  | 			((regs->cs[i].config >> 14) & 0x3) + 2 + | ||||||
|  | 			((regs->cs[i].config >> 8) & 0x7) + 12 + | ||||||
|  | 			((regs->cs[i].config >> 4) & 0x3) + 0 + | ||||||
|  | 			((regs->cs[i].config >> 0) & 0x7) + 8 + | ||||||
|  | 			3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) - | ||||||
|  | 			26);			/* minus 26 (count of 64M) */ | ||||||
|  | 	} | ||||||
|  | 	if (fsl_ddr_get_intl3r() & 0x80000000)	/* 3-way interleaving */ | ||||||
|  | 		total_gb_size_per_controller *= 3; | ||||||
|  | 	else if (regs->cs[0].config & 0x20000000) /* 2-way interleaving */ | ||||||
|  | 		total_gb_size_per_controller <<= 1; | ||||||
|  | 	/*
 | ||||||
|  | 	 * total memory / bus width = transactions needed | ||||||
|  | 	 * transactions needed / data rate = seconds | ||||||
|  | 	 * to add plenty of buffer, double the time | ||||||
|  | 	 * For example, 2GB on 666MT/s 64-bit bus takes about 402ms | ||||||
|  | 	 * Let's wait for 800ms | ||||||
|  | 	 */ | ||||||
|  | 	bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK) | ||||||
|  | 			>> SDRAM_CFG_DBW_SHIFT); | ||||||
|  | 	timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 / | ||||||
|  | 		(get_ddr_freq(0) >> 20)) << 2; | ||||||
|  | 	total_gb_size_per_controller >>= 4;	/* shift down to gb size */ | ||||||
|  | 	debug("total %d GB\n", total_gb_size_per_controller); | ||||||
|  | 	debug("Need to wait up to %d * 10ms\n", timeout); | ||||||
|  | 
 | ||||||
|  | 	/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done.  */ | ||||||
|  | 	while ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) && | ||||||
|  | 		(timeout >= 0)) { | ||||||
|  | 		udelay(10000);		/* throttle polling rate */ | ||||||
|  | 		timeout--; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (timeout <= 0) | ||||||
|  | 		printf("Waiting for D_INIT timeout. Memory may not work.\n"); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2010-2012 Freescale Semiconductor, Inc. |  * Copyright 2010-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier:	GPL-2.0+ |  * SPDX-License-Identifier:	GPL-2.0+ | ||||||
|  */ |  */ | ||||||
|  | @ -153,25 +153,38 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo, | ||||||
| 	static const struct options_string options[] = { | 	static const struct options_string options[] = { | ||||||
| 		COMMON_TIMING(tckmin_x_ps), | 		COMMON_TIMING(tckmin_x_ps), | ||||||
| 		COMMON_TIMING(tckmax_ps), | 		COMMON_TIMING(tckmax_ps), | ||||||
| 		COMMON_TIMING(tckmax_max_ps), | 		COMMON_TIMING(taamin_ps), | ||||||
| 		COMMON_TIMING(trcd_ps), | 		COMMON_TIMING(trcd_ps), | ||||||
| 		COMMON_TIMING(trp_ps), | 		COMMON_TIMING(trp_ps), | ||||||
| 		COMMON_TIMING(tras_ps), | 		COMMON_TIMING(tras_ps), | ||||||
| 		COMMON_TIMING(twr_ps), | 
 | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		COMMON_TIMING(trfc1_ps), | ||||||
|  | 		COMMON_TIMING(trfc2_ps), | ||||||
|  | 		COMMON_TIMING(trfc4_ps), | ||||||
|  | 		COMMON_TIMING(trrds_ps), | ||||||
|  | 		COMMON_TIMING(trrdl_ps), | ||||||
|  | 		COMMON_TIMING(tccdl_ps), | ||||||
|  | #else | ||||||
| 		COMMON_TIMING(twtr_ps), | 		COMMON_TIMING(twtr_ps), | ||||||
| 		COMMON_TIMING(trfc_ps), | 		COMMON_TIMING(trfc_ps), | ||||||
| 		COMMON_TIMING(trrd_ps), | 		COMMON_TIMING(trrd_ps), | ||||||
|  | 		COMMON_TIMING(trtp_ps), | ||||||
|  | #endif | ||||||
|  | 		COMMON_TIMING(twr_ps), | ||||||
| 		COMMON_TIMING(trc_ps), | 		COMMON_TIMING(trc_ps), | ||||||
| 		COMMON_TIMING(refresh_rate_ps), | 		COMMON_TIMING(refresh_rate_ps), | ||||||
|  | 		COMMON_TIMING(extended_op_srt), | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 		COMMON_TIMING(tis_ps), | 		COMMON_TIMING(tis_ps), | ||||||
| 		COMMON_TIMING(tih_ps), | 		COMMON_TIMING(tih_ps), | ||||||
| 		COMMON_TIMING(tds_ps), | 		COMMON_TIMING(tds_ps), | ||||||
| 		COMMON_TIMING(tdh_ps), | 		COMMON_TIMING(tdh_ps), | ||||||
| 		COMMON_TIMING(trtp_ps), |  | ||||||
| 		COMMON_TIMING(tdqsq_max_ps), | 		COMMON_TIMING(tdqsq_max_ps), | ||||||
| 		COMMON_TIMING(tqhs_ps), | 		COMMON_TIMING(tqhs_ps), | ||||||
|  | #endif | ||||||
| 		COMMON_TIMING(ndimms_present), | 		COMMON_TIMING(ndimms_present), | ||||||
| 		COMMON_TIMING(lowest_common_SPD_caslat), | 		COMMON_TIMING(lowest_common_spd_caslat), | ||||||
| 		COMMON_TIMING(highest_common_derated_caslat), | 		COMMON_TIMING(highest_common_derated_caslat), | ||||||
| 		COMMON_TIMING(additive_latency), | 		COMMON_TIMING(additive_latency), | ||||||
| 		COMMON_TIMING(all_dimms_burst_lengths_bitmask), | 		COMMON_TIMING(all_dimms_burst_lengths_bitmask), | ||||||
|  | @ -211,7 +224,12 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, | ||||||
| 		DIMM_PARM(n_row_addr), | 		DIMM_PARM(n_row_addr), | ||||||
| 		DIMM_PARM(n_col_addr), | 		DIMM_PARM(n_col_addr), | ||||||
| 		DIMM_PARM(edc_config), | 		DIMM_PARM(edc_config), | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		DIMM_PARM(bank_addr_bits), | ||||||
|  | 		DIMM_PARM(bank_group_bits), | ||||||
|  | #else | ||||||
| 		DIMM_PARM(n_banks_per_sdram_device), | 		DIMM_PARM(n_banks_per_sdram_device), | ||||||
|  | #endif | ||||||
| 		DIMM_PARM(burst_lengths_bitmask), | 		DIMM_PARM(burst_lengths_bitmask), | ||||||
| 		DIMM_PARM(row_density), | 		DIMM_PARM(row_density), | ||||||
| 
 | 
 | ||||||
|  | @ -229,20 +247,32 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, | ||||||
| 		DIMM_PARM(trcd_ps), | 		DIMM_PARM(trcd_ps), | ||||||
| 		DIMM_PARM(trp_ps), | 		DIMM_PARM(trp_ps), | ||||||
| 		DIMM_PARM(tras_ps), | 		DIMM_PARM(tras_ps), | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		DIMM_PARM(trfc1_ps), | ||||||
|  | 		DIMM_PARM(trfc2_ps), | ||||||
|  | 		DIMM_PARM(trfc4_ps), | ||||||
|  | 		DIMM_PARM(trrds_ps), | ||||||
|  | 		DIMM_PARM(trrdl_ps), | ||||||
|  | 		DIMM_PARM(tccdl_ps), | ||||||
|  | #else | ||||||
| 		DIMM_PARM(twr_ps), | 		DIMM_PARM(twr_ps), | ||||||
| 		DIMM_PARM(twtr_ps), | 		DIMM_PARM(twtr_ps), | ||||||
| 		DIMM_PARM(trfc_ps), | 		DIMM_PARM(trfc_ps), | ||||||
| 		DIMM_PARM(trrd_ps), | 		DIMM_PARM(trrd_ps), | ||||||
|  | 		DIMM_PARM(trtp_ps), | ||||||
|  | #endif | ||||||
| 		DIMM_PARM(trc_ps), | 		DIMM_PARM(trc_ps), | ||||||
| 		DIMM_PARM(refresh_rate_ps), | 		DIMM_PARM(refresh_rate_ps), | ||||||
|  | 		DIMM_PARM(extended_op_srt), | ||||||
| 
 | 
 | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 		DIMM_PARM(tis_ps), | 		DIMM_PARM(tis_ps), | ||||||
| 		DIMM_PARM(tih_ps), | 		DIMM_PARM(tih_ps), | ||||||
| 		DIMM_PARM(tds_ps), | 		DIMM_PARM(tds_ps), | ||||||
| 		DIMM_PARM(tdh_ps), | 		DIMM_PARM(tdh_ps), | ||||||
| 		DIMM_PARM(trtp_ps), |  | ||||||
| 		DIMM_PARM(tdqsq_max_ps), | 		DIMM_PARM(tdqsq_max_ps), | ||||||
| 		DIMM_PARM(tqhs_ps), | 		DIMM_PARM(tqhs_ps), | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 		DIMM_PARM(rank_density), | 		DIMM_PARM(rank_density), | ||||||
| 		DIMM_PARM(capacity), | 		DIMM_PARM(capacity), | ||||||
|  | @ -270,7 +300,12 @@ static void print_dimm_parameters(const dimm_params_t *pdimm) | ||||||
| 		DIMM_PARM(n_row_addr), | 		DIMM_PARM(n_row_addr), | ||||||
| 		DIMM_PARM(n_col_addr), | 		DIMM_PARM(n_col_addr), | ||||||
| 		DIMM_PARM(edc_config), | 		DIMM_PARM(edc_config), | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		DIMM_PARM(bank_addr_bits), | ||||||
|  | 		DIMM_PARM(bank_group_bits), | ||||||
|  | #else | ||||||
| 		DIMM_PARM(n_banks_per_sdram_device), | 		DIMM_PARM(n_banks_per_sdram_device), | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 		DIMM_PARM(tckmin_x_ps), | 		DIMM_PARM(tckmin_x_ps), | ||||||
| 		DIMM_PARM(tckmin_x_minus_1_ps), | 		DIMM_PARM(tckmin_x_minus_1_ps), | ||||||
|  | @ -286,20 +321,31 @@ static void print_dimm_parameters(const dimm_params_t *pdimm) | ||||||
| 		DIMM_PARM(trcd_ps), | 		DIMM_PARM(trcd_ps), | ||||||
| 		DIMM_PARM(trp_ps), | 		DIMM_PARM(trp_ps), | ||||||
| 		DIMM_PARM(tras_ps), | 		DIMM_PARM(tras_ps), | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		DIMM_PARM(trfc1_ps), | ||||||
|  | 		DIMM_PARM(trfc2_ps), | ||||||
|  | 		DIMM_PARM(trfc4_ps), | ||||||
|  | 		DIMM_PARM(trrds_ps), | ||||||
|  | 		DIMM_PARM(trrdl_ps), | ||||||
|  | 		DIMM_PARM(tccdl_ps), | ||||||
|  | #else | ||||||
| 		DIMM_PARM(twr_ps), | 		DIMM_PARM(twr_ps), | ||||||
| 		DIMM_PARM(twtr_ps), | 		DIMM_PARM(twtr_ps), | ||||||
| 		DIMM_PARM(trfc_ps), | 		DIMM_PARM(trfc_ps), | ||||||
| 		DIMM_PARM(trrd_ps), | 		DIMM_PARM(trrd_ps), | ||||||
|  | 		DIMM_PARM(trtp_ps), | ||||||
|  | #endif | ||||||
| 		DIMM_PARM(trc_ps), | 		DIMM_PARM(trc_ps), | ||||||
| 		DIMM_PARM(refresh_rate_ps), | 		DIMM_PARM(refresh_rate_ps), | ||||||
| 
 | 
 | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 		DIMM_PARM(tis_ps), | 		DIMM_PARM(tis_ps), | ||||||
| 		DIMM_PARM(tih_ps), | 		DIMM_PARM(tih_ps), | ||||||
| 		DIMM_PARM(tds_ps), | 		DIMM_PARM(tds_ps), | ||||||
| 		DIMM_PARM(tdh_ps), | 		DIMM_PARM(tdh_ps), | ||||||
| 		DIMM_PARM(trtp_ps), |  | ||||||
| 		DIMM_PARM(tdqsq_max_ps), | 		DIMM_PARM(tdqsq_max_ps), | ||||||
| 		DIMM_PARM(tqhs_ps), | 		DIMM_PARM(tqhs_ps), | ||||||
|  | #endif | ||||||
| 	}; | 	}; | ||||||
| 	static const unsigned int n_opts = ARRAY_SIZE(options); | 	static const unsigned int n_opts = ARRAY_SIZE(options); | ||||||
| 
 | 
 | ||||||
|  | @ -326,23 +372,36 @@ static void print_lowest_common_dimm_parameters( | ||||||
| 		const common_timing_params_t *plcd_dimm_params) | 		const common_timing_params_t *plcd_dimm_params) | ||||||
| { | { | ||||||
| 	static const struct options_string options[] = { | 	static const struct options_string options[] = { | ||||||
| 		COMMON_TIMING(tckmax_max_ps), | 		COMMON_TIMING(taamin_ps), | ||||||
| 		COMMON_TIMING(trcd_ps), | 		COMMON_TIMING(trcd_ps), | ||||||
| 		COMMON_TIMING(trp_ps), | 		COMMON_TIMING(trp_ps), | ||||||
| 		COMMON_TIMING(tras_ps), | 		COMMON_TIMING(tras_ps), | ||||||
| 		COMMON_TIMING(twr_ps), | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		COMMON_TIMING(trfc1_ps), | ||||||
|  | 		COMMON_TIMING(trfc2_ps), | ||||||
|  | 		COMMON_TIMING(trfc4_ps), | ||||||
|  | 		COMMON_TIMING(trrds_ps), | ||||||
|  | 		COMMON_TIMING(trrdl_ps), | ||||||
|  | 		COMMON_TIMING(tccdl_ps), | ||||||
|  | #else | ||||||
| 		COMMON_TIMING(twtr_ps), | 		COMMON_TIMING(twtr_ps), | ||||||
| 		COMMON_TIMING(trfc_ps), | 		COMMON_TIMING(trfc_ps), | ||||||
| 		COMMON_TIMING(trrd_ps), | 		COMMON_TIMING(trrd_ps), | ||||||
|  | 		COMMON_TIMING(trtp_ps), | ||||||
|  | #endif | ||||||
|  | 		COMMON_TIMING(twr_ps), | ||||||
| 		COMMON_TIMING(trc_ps), | 		COMMON_TIMING(trc_ps), | ||||||
| 		COMMON_TIMING(refresh_rate_ps), | 		COMMON_TIMING(refresh_rate_ps), | ||||||
|  | 		COMMON_TIMING(extended_op_srt), | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 		COMMON_TIMING(tis_ps), | 		COMMON_TIMING(tis_ps), | ||||||
|  | 		COMMON_TIMING(tih_ps), | ||||||
| 		COMMON_TIMING(tds_ps), | 		COMMON_TIMING(tds_ps), | ||||||
| 		COMMON_TIMING(tdh_ps), | 		COMMON_TIMING(tdh_ps), | ||||||
| 		COMMON_TIMING(trtp_ps), |  | ||||||
| 		COMMON_TIMING(tdqsq_max_ps), | 		COMMON_TIMING(tdqsq_max_ps), | ||||||
| 		COMMON_TIMING(tqhs_ps), | 		COMMON_TIMING(tqhs_ps), | ||||||
| 		COMMON_TIMING(lowest_common_SPD_caslat), | #endif | ||||||
|  | 		COMMON_TIMING(lowest_common_spd_caslat), | ||||||
| 		COMMON_TIMING(highest_common_derated_caslat), | 		COMMON_TIMING(highest_common_derated_caslat), | ||||||
| 		COMMON_TIMING(additive_latency), | 		COMMON_TIMING(additive_latency), | ||||||
| 		COMMON_TIMING(ndimms_present), | 		COMMON_TIMING(ndimms_present), | ||||||
|  | @ -460,6 +519,9 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo, | ||||||
| 		CTRL_OPTIONS(tfaw_window_four_activates_ps), | 		CTRL_OPTIONS(tfaw_window_four_activates_ps), | ||||||
| 		CTRL_OPTIONS(trwt_override), | 		CTRL_OPTIONS(trwt_override), | ||||||
| 		CTRL_OPTIONS(trwt), | 		CTRL_OPTIONS(trwt), | ||||||
|  | 		CTRL_OPTIONS(rtt_override), | ||||||
|  | 		CTRL_OPTIONS(rtt_override_value), | ||||||
|  | 		CTRL_OPTIONS(rtt_wr_override_value), | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	static const unsigned int n_opts = ARRAY_SIZE(options); | 	static const unsigned int n_opts = ARRAY_SIZE(options); | ||||||
|  | @ -505,6 +567,7 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) | ||||||
| 		CFG_REGS(timing_cfg_2), | 		CFG_REGS(timing_cfg_2), | ||||||
| 		CFG_REGS(ddr_sdram_cfg), | 		CFG_REGS(ddr_sdram_cfg), | ||||||
| 		CFG_REGS(ddr_sdram_cfg_2), | 		CFG_REGS(ddr_sdram_cfg_2), | ||||||
|  | 		CFG_REGS(ddr_sdram_cfg_3), | ||||||
| 		CFG_REGS(ddr_sdram_mode), | 		CFG_REGS(ddr_sdram_mode), | ||||||
| 		CFG_REGS(ddr_sdram_mode_2), | 		CFG_REGS(ddr_sdram_mode_2), | ||||||
| 		CFG_REGS(ddr_sdram_mode_3), | 		CFG_REGS(ddr_sdram_mode_3), | ||||||
|  | @ -513,6 +576,16 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) | ||||||
| 		CFG_REGS(ddr_sdram_mode_6), | 		CFG_REGS(ddr_sdram_mode_6), | ||||||
| 		CFG_REGS(ddr_sdram_mode_7), | 		CFG_REGS(ddr_sdram_mode_7), | ||||||
| 		CFG_REGS(ddr_sdram_mode_8), | 		CFG_REGS(ddr_sdram_mode_8), | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_9), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_10), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_11), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_12), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_13), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_14), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_15), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_16), | ||||||
|  | #endif | ||||||
| 		CFG_REGS(ddr_sdram_interval), | 		CFG_REGS(ddr_sdram_interval), | ||||||
| 		CFG_REGS(ddr_data_init), | 		CFG_REGS(ddr_data_init), | ||||||
| 		CFG_REGS(ddr_sdram_clk_cntl), | 		CFG_REGS(ddr_sdram_clk_cntl), | ||||||
|  | @ -520,6 +593,12 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) | ||||||
| 		CFG_REGS(ddr_init_ext_addr), | 		CFG_REGS(ddr_init_ext_addr), | ||||||
| 		CFG_REGS(timing_cfg_4), | 		CFG_REGS(timing_cfg_4), | ||||||
| 		CFG_REGS(timing_cfg_5), | 		CFG_REGS(timing_cfg_5), | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		CFG_REGS(timing_cfg_6), | ||||||
|  | 		CFG_REGS(timing_cfg_7), | ||||||
|  | 		CFG_REGS(timing_cfg_8), | ||||||
|  | 		CFG_REGS(timing_cfg_9), | ||||||
|  | #endif | ||||||
| 		CFG_REGS(ddr_zq_cntl), | 		CFG_REGS(ddr_zq_cntl), | ||||||
| 		CFG_REGS(ddr_wrlvl_cntl), | 		CFG_REGS(ddr_wrlvl_cntl), | ||||||
| 		CFG_REGS(ddr_wrlvl_cntl_2), | 		CFG_REGS(ddr_wrlvl_cntl_2), | ||||||
|  | @ -529,6 +608,10 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) | ||||||
| 		CFG_REGS(ddr_sdram_rcw_2), | 		CFG_REGS(ddr_sdram_rcw_2), | ||||||
| 		CFG_REGS(ddr_cdr1), | 		CFG_REGS(ddr_cdr1), | ||||||
| 		CFG_REGS(ddr_cdr2), | 		CFG_REGS(ddr_cdr2), | ||||||
|  | 		CFG_REGS(dq_map_0), | ||||||
|  | 		CFG_REGS(dq_map_1), | ||||||
|  | 		CFG_REGS(dq_map_2), | ||||||
|  | 		CFG_REGS(dq_map_3), | ||||||
| 		CFG_REGS(err_disable), | 		CFG_REGS(err_disable), | ||||||
| 		CFG_REGS(err_int_en), | 		CFG_REGS(err_int_en), | ||||||
| 		CFG_REGS(ddr_eor), | 		CFG_REGS(ddr_eor), | ||||||
|  | @ -574,6 +657,7 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, | ||||||
| 		CFG_REGS(timing_cfg_2), | 		CFG_REGS(timing_cfg_2), | ||||||
| 		CFG_REGS(ddr_sdram_cfg), | 		CFG_REGS(ddr_sdram_cfg), | ||||||
| 		CFG_REGS(ddr_sdram_cfg_2), | 		CFG_REGS(ddr_sdram_cfg_2), | ||||||
|  | 		CFG_REGS(ddr_sdram_cfg_3), | ||||||
| 		CFG_REGS(ddr_sdram_mode), | 		CFG_REGS(ddr_sdram_mode), | ||||||
| 		CFG_REGS(ddr_sdram_mode_2), | 		CFG_REGS(ddr_sdram_mode_2), | ||||||
| 		CFG_REGS(ddr_sdram_mode_3), | 		CFG_REGS(ddr_sdram_mode_3), | ||||||
|  | @ -582,6 +666,16 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, | ||||||
| 		CFG_REGS(ddr_sdram_mode_6), | 		CFG_REGS(ddr_sdram_mode_6), | ||||||
| 		CFG_REGS(ddr_sdram_mode_7), | 		CFG_REGS(ddr_sdram_mode_7), | ||||||
| 		CFG_REGS(ddr_sdram_mode_8), | 		CFG_REGS(ddr_sdram_mode_8), | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_9), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_10), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_11), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_12), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_13), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_14), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_15), | ||||||
|  | 		CFG_REGS(ddr_sdram_mode_16), | ||||||
|  | #endif | ||||||
| 		CFG_REGS(ddr_sdram_interval), | 		CFG_REGS(ddr_sdram_interval), | ||||||
| 		CFG_REGS(ddr_data_init), | 		CFG_REGS(ddr_data_init), | ||||||
| 		CFG_REGS(ddr_sdram_clk_cntl), | 		CFG_REGS(ddr_sdram_clk_cntl), | ||||||
|  | @ -589,6 +683,12 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, | ||||||
| 		CFG_REGS(ddr_init_ext_addr), | 		CFG_REGS(ddr_init_ext_addr), | ||||||
| 		CFG_REGS(timing_cfg_4), | 		CFG_REGS(timing_cfg_4), | ||||||
| 		CFG_REGS(timing_cfg_5), | 		CFG_REGS(timing_cfg_5), | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		CFG_REGS(timing_cfg_6), | ||||||
|  | 		CFG_REGS(timing_cfg_7), | ||||||
|  | 		CFG_REGS(timing_cfg_8), | ||||||
|  | 		CFG_REGS(timing_cfg_9), | ||||||
|  | #endif | ||||||
| 		CFG_REGS(ddr_zq_cntl), | 		CFG_REGS(ddr_zq_cntl), | ||||||
| 		CFG_REGS(ddr_wrlvl_cntl), | 		CFG_REGS(ddr_wrlvl_cntl), | ||||||
| 		CFG_REGS(ddr_wrlvl_cntl_2), | 		CFG_REGS(ddr_wrlvl_cntl_2), | ||||||
|  | @ -598,6 +698,10 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, | ||||||
| 		CFG_REGS(ddr_sdram_rcw_2), | 		CFG_REGS(ddr_sdram_rcw_2), | ||||||
| 		CFG_REGS(ddr_cdr1), | 		CFG_REGS(ddr_cdr1), | ||||||
| 		CFG_REGS(ddr_cdr2), | 		CFG_REGS(ddr_cdr2), | ||||||
|  | 		CFG_REGS(dq_map_0), | ||||||
|  | 		CFG_REGS(dq_map_1), | ||||||
|  | 		CFG_REGS(dq_map_2), | ||||||
|  | 		CFG_REGS(dq_map_3), | ||||||
| 		CFG_REGS(err_disable), | 		CFG_REGS(err_disable), | ||||||
| 		CFG_REGS(err_int_en), | 		CFG_REGS(err_int_en), | ||||||
| 		CFG_REGS(ddr_sdram_rcw_2), | 		CFG_REGS(ddr_sdram_rcw_2), | ||||||
|  | @ -705,6 +809,9 @@ static void print_memctl_options(const memctl_options_t *popts) | ||||||
| 		CTRL_OPTIONS(tfaw_window_four_activates_ps), | 		CTRL_OPTIONS(tfaw_window_four_activates_ps), | ||||||
| 		CTRL_OPTIONS(trwt_override), | 		CTRL_OPTIONS(trwt_override), | ||||||
| 		CTRL_OPTIONS(trwt), | 		CTRL_OPTIONS(trwt), | ||||||
|  | 		CTRL_OPTIONS(rtt_override), | ||||||
|  | 		CTRL_OPTIONS(rtt_override_value), | ||||||
|  | 		CTRL_OPTIONS(rtt_wr_override_value), | ||||||
| 	}; | 	}; | ||||||
| 	static const unsigned int n_opts = ARRAY_SIZE(options); | 	static const unsigned int n_opts = ARRAY_SIZE(options); | ||||||
| 
 | 
 | ||||||
|  | @ -1245,6 +1352,266 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | void ddr4_spd_dump(const struct ddr4_spd_eeprom_s *spd) | ||||||
|  | { | ||||||
|  | 	unsigned int i; | ||||||
|  | 
 | ||||||
|  | 	/* General Section: Bytes 0-127 */ | ||||||
|  | 
 | ||||||
|  | #define PRINT_NXS(x, y, z...) printf("%-3d    : %02x " z "\n", x, (u8)y); | ||||||
|  | #define PRINT_NNXXS(n0, n1, x0, x1, s) \ | ||||||
|  | 	printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1); | ||||||
|  | 
 | ||||||
|  | 	PRINT_NXS(0, spd->info_size_crc, | ||||||
|  | 		  "info_size_crc  bytes written into serial memory, CRC coverage"); | ||||||
|  | 	PRINT_NXS(1, spd->spd_rev, | ||||||
|  | 		  "spd_rev        SPD Revision"); | ||||||
|  | 	PRINT_NXS(2, spd->mem_type, | ||||||
|  | 		  "mem_type       Key Byte / DRAM Device Type"); | ||||||
|  | 	PRINT_NXS(3, spd->module_type, | ||||||
|  | 		  "module_type    Key Byte / Module Type"); | ||||||
|  | 	PRINT_NXS(4, spd->density_banks, | ||||||
|  | 		  "density_banks  SDRAM Density and Banks"); | ||||||
|  | 	PRINT_NXS(5, spd->addressing, | ||||||
|  | 		  "addressing     SDRAM Addressing"); | ||||||
|  | 	PRINT_NXS(6, spd->package_type, | ||||||
|  | 		  "package_type   Package type"); | ||||||
|  | 	PRINT_NXS(7, spd->opt_feature, | ||||||
|  | 		  "opt_feature    Optional features"); | ||||||
|  | 	PRINT_NXS(8, spd->thermal_ref, | ||||||
|  | 		  "thermal_ref    Thermal and Refresh options"); | ||||||
|  | 	PRINT_NXS(9, spd->oth_opt_features, | ||||||
|  | 		  "oth_opt_features Other SDRAM optional features"); | ||||||
|  | 	PRINT_NXS(10, spd->res_10, | ||||||
|  | 		  "res_10         Reserved"); | ||||||
|  | 	PRINT_NXS(11, spd->module_vdd, | ||||||
|  | 		  "module_vdd     Module Nominal Voltage, VDD"); | ||||||
|  | 	PRINT_NXS(12, spd->organization, | ||||||
|  | 		  "organization Module Organization"); | ||||||
|  | 	PRINT_NXS(13, spd->bus_width, | ||||||
|  | 		  "bus_width      Module Memory Bus Width"); | ||||||
|  | 	PRINT_NXS(14, spd->therm_sensor, | ||||||
|  | 		  "therm_sensor   Module Thermal Sensor"); | ||||||
|  | 	PRINT_NXS(15, spd->ext_type, | ||||||
|  | 		  "ext_type       Extended module type"); | ||||||
|  | 	PRINT_NXS(16, spd->res_16, | ||||||
|  | 		  "res_16       Reserved"); | ||||||
|  | 	PRINT_NXS(17, spd->timebases, | ||||||
|  | 		  "timebases    MTb and FTB"); | ||||||
|  | 	PRINT_NXS(18, spd->tck_min, | ||||||
|  | 		  "tck_min      tCKAVGmin"); | ||||||
|  | 	PRINT_NXS(19, spd->tck_max, | ||||||
|  | 		  "tck_max      TCKAVGmax"); | ||||||
|  | 	PRINT_NXS(20, spd->caslat_b1, | ||||||
|  | 		  "caslat_b1    CAS latencies, 1st byte"); | ||||||
|  | 	PRINT_NXS(21, spd->caslat_b2, | ||||||
|  | 		  "caslat_b2    CAS latencies, 2nd byte"); | ||||||
|  | 	PRINT_NXS(22, spd->caslat_b3, | ||||||
|  | 		  "caslat_b3    CAS latencies, 3rd byte "); | ||||||
|  | 	PRINT_NXS(23, spd->caslat_b4, | ||||||
|  | 		  "caslat_b4    CAS latencies, 4th byte"); | ||||||
|  | 	PRINT_NXS(24, spd->taa_min, | ||||||
|  | 		  "taa_min      Min CAS Latency Time"); | ||||||
|  | 	PRINT_NXS(25, spd->trcd_min, | ||||||
|  | 		  "trcd_min     Min RAS# to CAS# Delay Time"); | ||||||
|  | 	PRINT_NXS(26, spd->trp_min, | ||||||
|  | 		  "trp_min      Min Row Precharge Delay Time"); | ||||||
|  | 	PRINT_NXS(27, spd->tras_trc_ext, | ||||||
|  | 		  "tras_trc_ext Upper Nibbles for tRAS and tRC"); | ||||||
|  | 	PRINT_NXS(28, spd->tras_min_lsb, | ||||||
|  | 		  "tras_min_lsb tRASmin, lsb"); | ||||||
|  | 	PRINT_NXS(29, spd->trc_min_lsb, | ||||||
|  | 		  "trc_min_lsb  tRCmin, lsb"); | ||||||
|  | 	PRINT_NXS(30, spd->trfc1_min_lsb, | ||||||
|  | 		  "trfc1_min_lsb  Min Refresh Recovery Delay Time, LSB"); | ||||||
|  | 	PRINT_NXS(31, spd->trfc1_min_msb, | ||||||
|  | 		  "trfc1_min_msb  Min Refresh Recovery Delay Time, MSB "); | ||||||
|  | 	PRINT_NXS(32, spd->trfc2_min_lsb, | ||||||
|  | 		  "trfc2_min_lsb  Min Refresh Recovery Delay Time, LSB"); | ||||||
|  | 	PRINT_NXS(33, spd->trfc2_min_msb, | ||||||
|  | 		  "trfc2_min_msb  Min Refresh Recovery Delay Time, MSB"); | ||||||
|  | 	PRINT_NXS(34, spd->trfc4_min_lsb, | ||||||
|  | 		  "trfc4_min_lsb Min Refresh Recovery Delay Time, LSB"); | ||||||
|  | 	PRINT_NXS(35, spd->trfc4_min_msb, | ||||||
|  | 		  "trfc4_min_msb Min Refresh Recovery Delay Time, MSB"); | ||||||
|  | 	PRINT_NXS(36, spd->tfaw_msb, | ||||||
|  | 		  "tfaw_msb      Upper Nibble for tFAW"); | ||||||
|  | 	PRINT_NXS(37, spd->tfaw_min, | ||||||
|  | 		  "tfaw_min      tFAW, lsb"); | ||||||
|  | 	PRINT_NXS(38, spd->trrds_min, | ||||||
|  | 		  "trrds_min     tRRD_Smin, MTB"); | ||||||
|  | 	PRINT_NXS(39, spd->trrdl_min, | ||||||
|  | 		  "trrdl_min     tRRD_Lmin, MTB"); | ||||||
|  | 	PRINT_NXS(40, spd->tccdl_min, | ||||||
|  | 		  "tccdl_min     tCCS_Lmin, MTB"); | ||||||
|  | 
 | ||||||
|  | 	printf("%-3d-%3d: ", 41, 59);  /* Reserved, General Section */ | ||||||
|  | 	for (i = 41; i <= 59; i++) | ||||||
|  | 		printf("%02x ", spd->res_41[i - 41]); | ||||||
|  | 
 | ||||||
|  | 	puts("\n"); | ||||||
|  | 	printf("%-3d-%3d: ", 60, 77); | ||||||
|  | 	for (i = 60; i <= 77; i++) | ||||||
|  | 		printf("%02x ", spd->mapping[i - 60]); | ||||||
|  | 	puts("   mapping[] Connector to SDRAM bit map\n"); | ||||||
|  | 
 | ||||||
|  | 	PRINT_NXS(117, spd->fine_tccdl_min, | ||||||
|  | 		  "fine_tccdl_min Fine offset for tCCD_Lmin"); | ||||||
|  | 	PRINT_NXS(118, spd->fine_trrdl_min, | ||||||
|  | 		  "fine_trrdl_min Fine offset for tRRD_Lmin"); | ||||||
|  | 	PRINT_NXS(119, spd->fine_trrds_min, | ||||||
|  | 		  "fine_trrds_min Fine offset for tRRD_Smin"); | ||||||
|  | 	PRINT_NXS(120, spd->fine_trc_min, | ||||||
|  | 		  "fine_trc_min   Fine offset for tRCmin"); | ||||||
|  | 	PRINT_NXS(121, spd->fine_trp_min, | ||||||
|  | 		  "fine_trp_min   Fine offset for tRPmin"); | ||||||
|  | 	PRINT_NXS(122, spd->fine_trcd_min, | ||||||
|  | 		  "fine_trcd_min  Fine offset for tRCDmin"); | ||||||
|  | 	PRINT_NXS(123, spd->fine_taa_min, | ||||||
|  | 		  "fine_taa_min   Fine offset for tAAmin"); | ||||||
|  | 	PRINT_NXS(124, spd->fine_tck_max, | ||||||
|  | 		  "fine_tck_max   Fine offset for tCKAVGmax"); | ||||||
|  | 	PRINT_NXS(125, spd->fine_tck_min, | ||||||
|  | 		  "fine_tck_min   Fine offset for tCKAVGmin"); | ||||||
|  | 
 | ||||||
|  | 	/* CRC: Bytes 126-127 */ | ||||||
|  | 	PRINT_NNXXS(126, 127, spd->crc[0], spd->crc[1], "  SPD CRC"); | ||||||
|  | 
 | ||||||
|  | 	switch (spd->module_type) { | ||||||
|  | 	case 0x02:  /* UDIMM */ | ||||||
|  | 	case 0x03:  /* SO-DIMM */ | ||||||
|  | 		PRINT_NXS(128, spd->mod_section.unbuffered.mod_height, | ||||||
|  | 			  "mod_height    (Unbuffered) Module Nominal Height"); | ||||||
|  | 		PRINT_NXS(129, spd->mod_section.unbuffered.mod_thickness, | ||||||
|  | 			  "mod_thickness (Unbuffered) Module Maximum Thickness"); | ||||||
|  | 		PRINT_NXS(130, spd->mod_section.unbuffered.ref_raw_card, | ||||||
|  | 			  "ref_raw_card  (Unbuffered) Reference Raw Card Used"); | ||||||
|  | 		PRINT_NXS(131, spd->mod_section.unbuffered.addr_mapping, | ||||||
|  | 			  "addr_mapping  (Unbuffered) Address mapping from Edge Connector to DRAM"); | ||||||
|  | 		PRINT_NNXXS(254, 255, spd->mod_section.unbuffered.crc[0], | ||||||
|  | 			    spd->mod_section.unbuffered.crc[1], "  Module CRC"); | ||||||
|  | 		break; | ||||||
|  | 	case 0x01:  /* RDIMM */ | ||||||
|  | 		PRINT_NXS(128, spd->mod_section.registered.mod_height, | ||||||
|  | 			  "mod_height    (Registered) Module Nominal Height"); | ||||||
|  | 		PRINT_NXS(129, spd->mod_section.registered.mod_thickness, | ||||||
|  | 			  "mod_thickness (Registered) Module Maximum Thickness"); | ||||||
|  | 		PRINT_NXS(130, spd->mod_section.registered.ref_raw_card, | ||||||
|  | 			  "ref_raw_card  (Registered) Reference Raw Card Used"); | ||||||
|  | 		PRINT_NXS(131, spd->mod_section.registered.modu_attr, | ||||||
|  | 			  "modu_attr     (Registered) DIMM Module Attributes"); | ||||||
|  | 		PRINT_NXS(132, spd->mod_section.registered.thermal, | ||||||
|  | 			  "thermal       (Registered) Thermal Heat Spreader Solution"); | ||||||
|  | 		PRINT_NXS(133, spd->mod_section.registered.reg_id_lo, | ||||||
|  | 			  "reg_id_lo     (Registered) Register Manufacturer ID Code, LSB"); | ||||||
|  | 		PRINT_NXS(134, spd->mod_section.registered.reg_id_hi, | ||||||
|  | 			  "reg_id_hi     (Registered) Register Manufacturer ID Code, MSB"); | ||||||
|  | 		PRINT_NXS(135, spd->mod_section.registered.reg_rev, | ||||||
|  | 			  "reg_rev       (Registered) Register Revision Number"); | ||||||
|  | 		PRINT_NXS(136, spd->mod_section.registered.reg_map, | ||||||
|  | 			  "reg_map       (Registered) Address mapping"); | ||||||
|  | 		PRINT_NNXXS(254, 255, spd->mod_section.registered.crc[0], | ||||||
|  | 			    spd->mod_section.registered.crc[1], "  Module CRC"); | ||||||
|  | 		break; | ||||||
|  | 	case 0x04:  /* LRDIMM */ | ||||||
|  | 		PRINT_NXS(128, spd->mod_section.loadreduced.mod_height, | ||||||
|  | 			  "mod_height    (Loadreduced) Module Nominal Height"); | ||||||
|  | 		PRINT_NXS(129, spd->mod_section.loadreduced.mod_thickness, | ||||||
|  | 			  "mod_thickness (Loadreduced) Module Maximum Thickness"); | ||||||
|  | 		PRINT_NXS(130, spd->mod_section.loadreduced.ref_raw_card, | ||||||
|  | 			  "ref_raw_card  (Loadreduced) Reference Raw Card Used"); | ||||||
|  | 		PRINT_NXS(131, spd->mod_section.loadreduced.modu_attr, | ||||||
|  | 			  "modu_attr     (Loadreduced) DIMM Module Attributes"); | ||||||
|  | 		PRINT_NXS(132, spd->mod_section.loadreduced.thermal, | ||||||
|  | 			  "thermal       (Loadreduced) Thermal Heat Spreader Solution"); | ||||||
|  | 		PRINT_NXS(133, spd->mod_section.loadreduced.reg_id_lo, | ||||||
|  | 			  "reg_id_lo     (Loadreduced) Register Manufacturer ID Code, LSB"); | ||||||
|  | 		PRINT_NXS(134, spd->mod_section.loadreduced.reg_id_hi, | ||||||
|  | 			  "reg_id_hi     (Loadreduced) Register Manufacturer ID Code, MSB"); | ||||||
|  | 		PRINT_NXS(135, spd->mod_section.loadreduced.reg_rev, | ||||||
|  | 			  "reg_rev       (Loadreduced) Register Revision Number"); | ||||||
|  | 		PRINT_NXS(136, spd->mod_section.loadreduced.reg_map, | ||||||
|  | 			  "reg_map       (Loadreduced) Address mapping"); | ||||||
|  | 		PRINT_NXS(137, spd->mod_section.loadreduced.reg_drv, | ||||||
|  | 			  "reg_drv       (Loadreduced) Reg output drive strength"); | ||||||
|  | 		PRINT_NXS(138, spd->mod_section.loadreduced.reg_drv_ck, | ||||||
|  | 			  "reg_drv_ck    (Loadreduced) Reg output drive strength for CK"); | ||||||
|  | 		PRINT_NXS(139, spd->mod_section.loadreduced.data_buf_rev, | ||||||
|  | 			  "data_buf_rev  (Loadreduced) Data Buffer Revision Numbe"); | ||||||
|  | 		PRINT_NXS(140, spd->mod_section.loadreduced.vrefqe_r0, | ||||||
|  | 			  "vrefqe_r0     (Loadreduced) DRAM VrefDQ for Package Rank 0"); | ||||||
|  | 		PRINT_NXS(141, spd->mod_section.loadreduced.vrefqe_r1, | ||||||
|  | 			  "vrefqe_r1     (Loadreduced) DRAM VrefDQ for Package Rank 1"); | ||||||
|  | 		PRINT_NXS(142, spd->mod_section.loadreduced.vrefqe_r2, | ||||||
|  | 			  "vrefqe_r2     (Loadreduced) DRAM VrefDQ for Package Rank 2"); | ||||||
|  | 		PRINT_NXS(143, spd->mod_section.loadreduced.vrefqe_r3, | ||||||
|  | 			  "vrefqe_r3     (Loadreduced) DRAM VrefDQ for Package Rank 3"); | ||||||
|  | 		PRINT_NXS(144, spd->mod_section.loadreduced.data_intf, | ||||||
|  | 			  "data_intf     (Loadreduced) Data Buffer VrefDQ for DRAM Interface"); | ||||||
|  | 		PRINT_NXS(145, spd->mod_section.loadreduced.data_drv_1866, | ||||||
|  | 			  "data_drv_1866 (Loadreduced) Data Buffer MDQ Drive Strength and RTT"); | ||||||
|  | 		PRINT_NXS(146, spd->mod_section.loadreduced.data_drv_2400, | ||||||
|  | 			  "data_drv_2400 (Loadreduced) Data Buffer MDQ Drive Strength and RTT"); | ||||||
|  | 		PRINT_NXS(147, spd->mod_section.loadreduced.data_drv_3200, | ||||||
|  | 			  "data_drv_3200 (Loadreduced) Data Buffer MDQ Drive Strength and RTT"); | ||||||
|  | 		PRINT_NXS(148, spd->mod_section.loadreduced.dram_drv, | ||||||
|  | 			  "dram_drv      (Loadreduced) DRAM Drive Strength"); | ||||||
|  | 		PRINT_NXS(149, spd->mod_section.loadreduced.dram_odt_1866, | ||||||
|  | 			  "dram_odt_1866 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)"); | ||||||
|  | 		PRINT_NXS(150, spd->mod_section.loadreduced.dram_odt_2400, | ||||||
|  | 			  "dram_odt_2400 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)"); | ||||||
|  | 		PRINT_NXS(151, spd->mod_section.loadreduced.dram_odt_3200, | ||||||
|  | 			  "dram_odt_3200 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)"); | ||||||
|  | 		PRINT_NXS(152, spd->mod_section.loadreduced.dram_odt_park_1866, | ||||||
|  | 			  "dram_odt_park_1866 (Loadreduced) DRAM ODT (RTT_PARK)"); | ||||||
|  | 		PRINT_NXS(153, spd->mod_section.loadreduced.dram_odt_park_2400, | ||||||
|  | 			  "dram_odt_park_2400 (Loadreduced) DRAM ODT (RTT_PARK)"); | ||||||
|  | 		PRINT_NXS(154, spd->mod_section.loadreduced.dram_odt_park_3200, | ||||||
|  | 			  "dram_odt_park_3200 (Loadreduced) DRAM ODT (RTT_PARK)"); | ||||||
|  | 		PRINT_NNXXS(254, 255, spd->mod_section.loadreduced.crc[0], | ||||||
|  | 			    spd->mod_section.loadreduced.crc[1], | ||||||
|  | 			    "  Module CRC"); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		/* Module-specific Section, Unsupported Module Type */ | ||||||
|  | 		printf("%-3d-%3d: ", 128, 255); | ||||||
|  | 
 | ||||||
|  | 		for (i = 128; i <= 255; i++) | ||||||
|  | 			printf("%02x", spd->mod_section.uc[i - 60]); | ||||||
|  | 
 | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Unique Module ID: Bytes 320-383 */ | ||||||
|  | 	PRINT_NXS(320, spd->mmid_lsb, "Module MfgID Code LSB - JEP-106"); | ||||||
|  | 	PRINT_NXS(321, spd->mmid_msb, "Module MfgID Code MSB - JEP-106"); | ||||||
|  | 	PRINT_NXS(322, spd->mloc,     "Mfg Location"); | ||||||
|  | 	PRINT_NNXXS(323, 324, spd->mdate[0], spd->mdate[1], "Mfg Date"); | ||||||
|  | 
 | ||||||
|  | 	printf("%-3d-%3d: ", 325, 328); | ||||||
|  | 
 | ||||||
|  | 	for (i = 325; i <= 328; i++) | ||||||
|  | 		printf("%02x ", spd->sernum[i - 325]); | ||||||
|  | 	printf("   Module Serial Number\n"); | ||||||
|  | 
 | ||||||
|  | 	printf("%-3d-%3d: ", 329, 348); | ||||||
|  | 	for (i = 329; i <= 348; i++) | ||||||
|  | 		printf("%02x ", spd->mpart[i - 329]); | ||||||
|  | 	printf("   Mfg's Module Part Number\n"); | ||||||
|  | 
 | ||||||
|  | 	PRINT_NXS(349, spd->mrev, "Module Revision code"); | ||||||
|  | 	PRINT_NXS(350, spd->dmid_lsb, "DRAM MfgID Code LSB - JEP-106"); | ||||||
|  | 	PRINT_NXS(351, spd->dmid_msb, "DRAM MfgID Code MSB - JEP-106"); | ||||||
|  | 	PRINT_NXS(352, spd->stepping, "DRAM stepping"); | ||||||
|  | 
 | ||||||
|  | 	printf("%-3d-%3d: ", 353, 381); | ||||||
|  | 	for (i = 353; i <= 381; i++) | ||||||
|  | 		printf("%02x ", spd->msd[i - 353]); | ||||||
|  | 	printf("   Mfg's Specific Data\n"); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| static inline void generic_spd_dump(const generic_spd_eeprom_t *spd) | static inline void generic_spd_dump(const generic_spd_eeprom_t *spd) | ||||||
| { | { | ||||||
| #if defined(CONFIG_SYS_FSL_DDR1) | #if defined(CONFIG_SYS_FSL_DDR1) | ||||||
|  | @ -1253,6 +1620,8 @@ static inline void generic_spd_dump(const generic_spd_eeprom_t *spd) | ||||||
| 	ddr2_spd_dump(spd); | 	ddr2_spd_dump(spd); | ||||||
| #elif defined(CONFIG_SYS_FSL_DDR3) | #elif defined(CONFIG_SYS_FSL_DDR3) | ||||||
| 	ddr3_spd_dump(spd); | 	ddr3_spd_dump(spd); | ||||||
|  | #elif defined(CONFIG_SYS_FSL_DDR4) | ||||||
|  | 	ddr4_spd_dump(spd); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008-2012 Freescale Semiconductor, Inc. |  * Copyright 2008-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or |  * This program is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU General Public License |  * modify it under the terms of the GNU General Public License | ||||||
|  | @ -11,20 +11,23 @@ | ||||||
| 
 | 
 | ||||||
| #include <fsl_ddr.h> | #include <fsl_ddr.h> | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_SYS_FSL_DDR3) | #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) | ||||||
| static unsigned int | static unsigned int | ||||||
| compute_cas_latency_ddr3(const dimm_params_t *dimm_params, | compute_cas_latency(const dimm_params_t *dimm_params, | ||||||
| 		    common_timing_params_t *outpdimm, | 		    common_timing_params_t *outpdimm, | ||||||
| 		    unsigned int number_of_dimms) | 		    unsigned int number_of_dimms) | ||||||
| { | { | ||||||
| 	unsigned int i; | 	unsigned int i; | ||||||
| 	unsigned int taamin_ps = 0; |  | ||||||
| 	unsigned int tckmin_x_ps = 0; |  | ||||||
| 	unsigned int common_caslat; | 	unsigned int common_caslat; | ||||||
| 	unsigned int caslat_actual; | 	unsigned int caslat_actual; | ||||||
| 	unsigned int retry = 16; | 	unsigned int retry = 16; | ||||||
| 	unsigned int tmp; | 	unsigned int tmp; | ||||||
| 	const unsigned int mclk_ps = get_memory_clk_period_ps(); | 	const unsigned int mclk_ps = get_memory_clk_period_ps(); | ||||||
|  | #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 */ | 	/* compute the common CAS latency supported between slots */ | ||||||
| 	tmp = dimm_params[0].caslat_x; | 	tmp = dimm_params[0].caslat_x; | ||||||
|  | @ -34,19 +37,20 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params, | ||||||
| 	} | 	} | ||||||
| 	common_caslat = tmp; | 	common_caslat = tmp; | ||||||
| 
 | 
 | ||||||
| 	/* compute the max tAAmin tCKmin between slots */ |  | ||||||
| 	for (i = 0; i < number_of_dimms; i++) { |  | ||||||
| 		taamin_ps = max(taamin_ps, dimm_params[i].taa_ps); |  | ||||||
| 		tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps); |  | ||||||
| 	} |  | ||||||
| 	/* validate if the memory clk is in the range of dimms */ | 	/* validate if the memory clk is in the range of dimms */ | ||||||
| 	if (mclk_ps < tckmin_x_ps) { | 	if (mclk_ps < outpdimm->tckmin_x_ps) { | ||||||
| 		printf("DDR clock (MCLK cycle %u ps) is faster than " | 		printf("DDR clock (MCLK cycle %u ps) is faster than " | ||||||
| 			"the slowest DIMM(s) (tCKmin %u ps) can support.\n", | 			"the slowest DIMM(s) (tCKmin %u ps) can support.\n", | ||||||
| 			mclk_ps, tckmin_x_ps); | 			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 */ | 	/* determine the acutal cas latency */ | ||||||
| 	caslat_actual = (taamin_ps + mclk_ps - 1) / mclk_ps; | 	caslat_actual = (outpdimm->taamin_ps + mclk_ps - 1) / mclk_ps; | ||||||
| 	/* check if the dimms support the CAS latency */ | 	/* check if the dimms support the CAS latency */ | ||||||
| 	while (!(common_caslat & (1 << caslat_actual)) && retry > 0) { | 	while (!(common_caslat & (1 << caslat_actual)) && retry > 0) { | ||||||
| 		caslat_actual++; | 		caslat_actual++; | ||||||
|  | @ -54,13 +58,147 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params, | ||||||
| 	} | 	} | ||||||
| 	/* once the caculation of caslat_actual is completed
 | 	/* once the caculation of caslat_actual is completed
 | ||||||
| 	 * we must verify that this CAS latency value does not | 	 * we must verify that this CAS latency value does not | ||||||
| 	 * exceed tAAmax, which is 20 ns for all DDR3 speed grades | 	 * exceed tAAmax, which is 20 ns for all DDR3 speed grades, | ||||||
|  | 	 * 18ns for all DDR4 speed grades. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (caslat_actual * mclk_ps > 20000) { | 	if (caslat_actual * mclk_ps > taamax) { | ||||||
| 		printf("The choosen cas latency %d is too large\n", | 		printf("The choosen cas latency %d is too large\n", | ||||||
| 			caslat_actual); | 			caslat_actual); | ||||||
| 	} | 	} | ||||||
| 	outpdimm->lowest_common_SPD_caslat = 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 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(); | ||||||
|  | 	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; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -82,34 +220,40 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, | ||||||
| 
 | 
 | ||||||
| 	unsigned int tckmin_x_ps = 0; | 	unsigned int tckmin_x_ps = 0; | ||||||
| 	unsigned int tckmax_ps = 0xFFFFFFFF; | 	unsigned int tckmax_ps = 0xFFFFFFFF; | ||||||
| 	unsigned int tckmax_max_ps = 0; |  | ||||||
| 	unsigned int trcd_ps = 0; | 	unsigned int trcd_ps = 0; | ||||||
| 	unsigned int trp_ps = 0; | 	unsigned int trp_ps = 0; | ||||||
| 	unsigned int tras_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; | ||||||
|  | #else | ||||||
| 	unsigned int twr_ps = 0; | 	unsigned int twr_ps = 0; | ||||||
| 	unsigned int twtr_ps = 0; | 	unsigned int twtr_ps = 0; | ||||||
| 	unsigned int trfc_ps = 0; | 	unsigned int trfc_ps = 0; | ||||||
| 	unsigned int trrd_ps = 0; | 	unsigned int trrd_ps = 0; | ||||||
|  | 	unsigned int trtp_ps = 0; | ||||||
|  | #endif | ||||||
| 	unsigned int trc_ps = 0; | 	unsigned int trc_ps = 0; | ||||||
| 	unsigned int refresh_rate_ps = 0; | 	unsigned int refresh_rate_ps = 0; | ||||||
| 	unsigned int extended_op_srt = 1; | 	unsigned int extended_op_srt = 1; | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 	unsigned int tis_ps = 0; | 	unsigned int tis_ps = 0; | ||||||
| 	unsigned int tih_ps = 0; | 	unsigned int tih_ps = 0; | ||||||
| 	unsigned int tds_ps = 0; | 	unsigned int tds_ps = 0; | ||||||
| 	unsigned int tdh_ps = 0; | 	unsigned int tdh_ps = 0; | ||||||
| 	unsigned int trtp_ps = 0; |  | ||||||
| 	unsigned int tdqsq_max_ps = 0; | 	unsigned int tdqsq_max_ps = 0; | ||||||
| 	unsigned int tqhs_ps = 0; | 	unsigned int tqhs_ps = 0; | ||||||
| 
 | #endif | ||||||
| 	unsigned int temp1, temp2; | 	unsigned int temp1, temp2; | ||||||
| 	unsigned int additive_latency = 0; | 	unsigned int additive_latency = 0; | ||||||
| #if !defined(CONFIG_SYS_FSL_DDR3) |  | ||||||
| 	const unsigned int mclk_ps = get_memory_clk_period_ps(); |  | ||||||
| 	unsigned int lowest_good_caslat; |  | ||||||
| 	unsigned int not_ok; |  | ||||||
| 
 |  | ||||||
| 	debug("using mclk_ps = %u\n", mclk_ps); |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 	temp1 = 0; | 	temp1 = 0; | ||||||
| 	for (i = 0; i < number_of_dimms; i++) { | 	for (i = 0; i < number_of_dimms; i++) { | ||||||
|  | @ -146,31 +290,34 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, | ||||||
| 		 * i.e., this is the slowest the whole system can go. | 		 * i.e., this is the slowest the whole system can go. | ||||||
| 		 */ | 		 */ | ||||||
| 		tckmax_ps = min(tckmax_ps, dimm_params[i].tckmax_ps); | 		tckmax_ps = min(tckmax_ps, dimm_params[i].tckmax_ps); | ||||||
| 
 | #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) | ||||||
| 		/* Either find maximum value to determine slowest
 | 		taamin_ps = max(taamin_ps, dimm_params[i].taa_ps); | ||||||
| 		 * speed, delay, time, period, etc */ | #endif | ||||||
| 		tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps); | 		tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps); | ||||||
| 		tckmax_max_ps = max(tckmax_max_ps, dimm_params[i].tckmax_ps); |  | ||||||
| 		trcd_ps = max(trcd_ps, dimm_params[i].trcd_ps); | 		trcd_ps = max(trcd_ps, dimm_params[i].trcd_ps); | ||||||
| 		trp_ps = max(trp_ps, dimm_params[i].trp_ps); | 		trp_ps = max(trp_ps, dimm_params[i].trp_ps); | ||||||
| 		tras_ps = max(tras_ps, dimm_params[i].tras_ps); | 		tras_ps = max(tras_ps, dimm_params[i].tras_ps); | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 		trfc1_ps = max(trfc1_ps, dimm_params[i].trfc1_ps); | ||||||
|  | 		trfc2_ps = max(trfc2_ps, dimm_params[i].trfc2_ps); | ||||||
|  | 		trfc4_ps = max(trfc4_ps, dimm_params[i].trfc4_ps); | ||||||
|  | 		trrds_ps = max(trrds_ps, dimm_params[i].trrds_ps); | ||||||
|  | 		trrdl_ps = max(trrdl_ps, dimm_params[i].trrdl_ps); | ||||||
|  | 		tccdl_ps = max(tccdl_ps, dimm_params[i].tccdl_ps); | ||||||
|  | #else | ||||||
| 		twr_ps = max(twr_ps, dimm_params[i].twr_ps); | 		twr_ps = max(twr_ps, dimm_params[i].twr_ps); | ||||||
| 		twtr_ps = max(twtr_ps, dimm_params[i].twtr_ps); | 		twtr_ps = max(twtr_ps, dimm_params[i].twtr_ps); | ||||||
| 		trfc_ps = max(trfc_ps, dimm_params[i].trfc_ps); | 		trfc_ps = max(trfc_ps, dimm_params[i].trfc_ps); | ||||||
| 		trrd_ps = max(trrd_ps, dimm_params[i].trrd_ps); | 		trrd_ps = max(trrd_ps, dimm_params[i].trrd_ps); | ||||||
|  | 		trtp_ps = max(trtp_ps, dimm_params[i].trtp_ps); | ||||||
|  | #endif | ||||||
| 		trc_ps = max(trc_ps, dimm_params[i].trc_ps); | 		trc_ps = max(trc_ps, dimm_params[i].trc_ps); | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 		tis_ps = max(tis_ps, dimm_params[i].tis_ps); | 		tis_ps = max(tis_ps, dimm_params[i].tis_ps); | ||||||
| 		tih_ps = max(tih_ps, dimm_params[i].tih_ps); | 		tih_ps = max(tih_ps, dimm_params[i].tih_ps); | ||||||
| 		tds_ps = max(tds_ps, dimm_params[i].tds_ps); | 		tds_ps = max(tds_ps, dimm_params[i].tds_ps); | ||||||
| 		tdh_ps = max(tdh_ps, dimm_params[i].tdh_ps); | 		tdh_ps = max(tdh_ps, dimm_params[i].tdh_ps); | ||||||
| 		trtp_ps = max(trtp_ps, dimm_params[i].trtp_ps); |  | ||||||
| 		tqhs_ps = max(tqhs_ps, dimm_params[i].tqhs_ps); | 		tqhs_ps = max(tqhs_ps, dimm_params[i].tqhs_ps); | ||||||
| 		refresh_rate_ps = max(refresh_rate_ps, |  | ||||||
| 				      dimm_params[i].refresh_rate_ps); |  | ||||||
| 		/* extended_op_srt is either 0 or 1, 0 having priority */ |  | ||||||
| 		extended_op_srt = min(extended_op_srt, |  | ||||||
| 				      dimm_params[i].extended_op_srt); |  | ||||||
| 
 |  | ||||||
| 		/*
 | 		/*
 | ||||||
| 		 * Find maximum tdqsq_max_ps to find slowest. | 		 * Find maximum tdqsq_max_ps to find slowest. | ||||||
| 		 * | 		 * | ||||||
|  | @ -178,6 +325,12 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, | ||||||
| 		 * strategy for this parameter? | 		 * strategy for this parameter? | ||||||
| 		 */ | 		 */ | ||||||
| 		tdqsq_max_ps = max(tdqsq_max_ps, dimm_params[i].tdqsq_max_ps); | 		tdqsq_max_ps = max(tdqsq_max_ps, dimm_params[i].tdqsq_max_ps); | ||||||
|  | #endif | ||||||
|  | 		refresh_rate_ps = max(refresh_rate_ps, | ||||||
|  | 				      dimm_params[i].refresh_rate_ps); | ||||||
|  | 		/* extended_op_srt is either 0 or 1, 0 having priority */ | ||||||
|  | 		extended_op_srt = min(extended_op_srt, | ||||||
|  | 				      dimm_params[i].extended_op_srt); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	outpdimm->ndimms_present = number_of_dimms - temp1; | 	outpdimm->ndimms_present = number_of_dimms - temp1; | ||||||
|  | @ -189,24 +342,37 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, | ||||||
| 
 | 
 | ||||||
| 	outpdimm->tckmin_x_ps = tckmin_x_ps; | 	outpdimm->tckmin_x_ps = tckmin_x_ps; | ||||||
| 	outpdimm->tckmax_ps = tckmax_ps; | 	outpdimm->tckmax_ps = tckmax_ps; | ||||||
| 	outpdimm->tckmax_max_ps = tckmax_max_ps; | #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) | ||||||
|  | 	outpdimm->taamin_ps = taamin_ps; | ||||||
|  | #endif | ||||||
| 	outpdimm->trcd_ps = trcd_ps; | 	outpdimm->trcd_ps = trcd_ps; | ||||||
| 	outpdimm->trp_ps = trp_ps; | 	outpdimm->trp_ps = trp_ps; | ||||||
| 	outpdimm->tras_ps = tras_ps; | 	outpdimm->tras_ps = tras_ps; | ||||||
| 	outpdimm->twr_ps = twr_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; | ||||||
|  | #else | ||||||
| 	outpdimm->twtr_ps = twtr_ps; | 	outpdimm->twtr_ps = twtr_ps; | ||||||
| 	outpdimm->trfc_ps = trfc_ps; | 	outpdimm->trfc_ps = trfc_ps; | ||||||
| 	outpdimm->trrd_ps = trrd_ps; | 	outpdimm->trrd_ps = trrd_ps; | ||||||
|  | 	outpdimm->trtp_ps = trtp_ps; | ||||||
|  | #endif | ||||||
|  | 	outpdimm->twr_ps = twr_ps; | ||||||
| 	outpdimm->trc_ps = trc_ps; | 	outpdimm->trc_ps = trc_ps; | ||||||
| 	outpdimm->refresh_rate_ps = refresh_rate_ps; | 	outpdimm->refresh_rate_ps = refresh_rate_ps; | ||||||
| 	outpdimm->extended_op_srt = extended_op_srt; | 	outpdimm->extended_op_srt = extended_op_srt; | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 	outpdimm->tis_ps = tis_ps; | 	outpdimm->tis_ps = tis_ps; | ||||||
| 	outpdimm->tih_ps = tih_ps; | 	outpdimm->tih_ps = tih_ps; | ||||||
| 	outpdimm->tds_ps = tds_ps; | 	outpdimm->tds_ps = tds_ps; | ||||||
| 	outpdimm->tdh_ps = tdh_ps; | 	outpdimm->tdh_ps = tdh_ps; | ||||||
| 	outpdimm->trtp_ps = trtp_ps; |  | ||||||
| 	outpdimm->tdqsq_max_ps = tdqsq_max_ps; | 	outpdimm->tdqsq_max_ps = tdqsq_max_ps; | ||||||
| 	outpdimm->tqhs_ps = tqhs_ps; | 	outpdimm->tqhs_ps = tqhs_ps; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	/* Determine common burst length for all DIMMs. */ | 	/* Determine common burst length for all DIMMs. */ | ||||||
| 	temp1 = 0xff; | 	temp1 = 0xff; | ||||||
|  | @ -265,128 +431,9 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, | ||||||
| 	if (temp1 != 0) | 	if (temp1 != 0) | ||||||
| 		printf("ERROR: Mix different RDIMM detected!\n"); | 		printf("ERROR: Mix different RDIMM detected!\n"); | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_SYS_FSL_DDR3) | 	/* calculate cas latency for all DDR types */ | ||||||
| 	if (compute_cas_latency_ddr3(dimm_params, outpdimm, number_of_dimms)) | 	if (compute_cas_latency(dimm_params, outpdimm, number_of_dimms)) | ||||||
| 		return 1; | 		return 1; | ||||||
| #else |  | ||||||
| 	/*
 |  | ||||||
| 	 * 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; |  | ||||||
| 			/*
 |  | ||||||
| 			 * FIXME: 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 its 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 its " |  | ||||||
| 						"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 its " |  | ||||||
| 						"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); |  | ||||||
| #endif /* #if defined(CONFIG_SYS_FSL_DDR3) */ |  | ||||||
| 
 | 
 | ||||||
| 	/* Determine if all DIMMs ECC capable. */ | 	/* Determine if all DIMMs ECC capable. */ | ||||||
| 	temp1 = 1; | 	temp1 = 1; | ||||||
|  | @ -404,14 +451,6 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, | ||||||
| 	} | 	} | ||||||
| 	outpdimm->all_dimms_ecc_capable = temp1; | 	outpdimm->all_dimms_ecc_capable = temp1; | ||||||
| 
 | 
 | ||||||
| #ifndef CONFIG_SYS_FSL_DDR3 |  | ||||||
| 	/* FIXME: move to somewhere else to validate. */ |  | ||||||
| 	if (mclk_ps > tckmax_max_ps) { |  | ||||||
| 		printf("Warning: some of the installed DIMMs " |  | ||||||
| 				"can not operate this slowly.\n"); |  | ||||||
| 		return 1; |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Compute additive latency. | 	 * Compute additive latency. | ||||||
| 	 * | 	 * | ||||||
|  | @ -468,27 +507,20 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, | ||||||
| 	additive_latency = 0; | 	additive_latency = 0; | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_SYS_FSL_DDR2) | #if defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 	if (lowest_good_caslat < 4) { | 	if ((outpdimm->lowest_common_spd_caslat < 4) && | ||||||
| 		additive_latency = (picos_to_mclk(trcd_ps) > lowest_good_caslat) | 	    (picos_to_mclk(trcd_ps) > outpdimm->lowest_common_spd_caslat)) { | ||||||
| 			? picos_to_mclk(trcd_ps) - lowest_good_caslat : 0; | 		additive_latency = picos_to_mclk(trcd_ps) - | ||||||
|  | 				   outpdimm->lowest_common_spd_caslat; | ||||||
| 		if (mclk_to_picos(additive_latency) > trcd_ps) { | 		if (mclk_to_picos(additive_latency) > trcd_ps) { | ||||||
| 			additive_latency = picos_to_mclk(trcd_ps); | 			additive_latency = picos_to_mclk(trcd_ps); | ||||||
| 			debug("setting additive_latency to %u because it was " | 			debug("setting additive_latency to %u because it was " | ||||||
| 				" greater than tRCD_ps\n", additive_latency); | 				" greater than tRCD_ps\n", additive_latency); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| #elif defined(CONFIG_SYS_FSL_DDR3) |  | ||||||
| 	/*
 |  | ||||||
| 	 * The system will not use the global auto-precharge mode. |  | ||||||
| 	 * However, it uses the page mode, so we set AL=0 |  | ||||||
| 	 */ |  | ||||||
| 	additive_latency = 0; |  | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Validate additive latency | 	 * Validate additive latency | ||||||
| 	 * FIXME: move to somewhere else to validate |  | ||||||
| 	 * | 	 * | ||||||
| 	 * AL <= tRCD(min) | 	 * AL <= tRCD(min) | ||||||
| 	 */ | 	 */ | ||||||
|  | @ -516,10 +548,19 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, | ||||||
| 	debug("trcd_ps   = %u\n", outpdimm->trcd_ps); | 	debug("trcd_ps   = %u\n", outpdimm->trcd_ps); | ||||||
| 	debug("trp_ps    = %u\n", outpdimm->trp_ps); | 	debug("trp_ps    = %u\n", outpdimm->trp_ps); | ||||||
| 	debug("tras_ps   = %u\n", outpdimm->tras_ps); | 	debug("tras_ps   = %u\n", outpdimm->tras_ps); | ||||||
| 	debug("twr_ps    = %u\n", outpdimm->twr_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); | ||||||
|  | #else | ||||||
| 	debug("twtr_ps   = %u\n", outpdimm->twtr_ps); | 	debug("twtr_ps   = %u\n", outpdimm->twtr_ps); | ||||||
| 	debug("trfc_ps   = %u\n", outpdimm->trfc_ps); | 	debug("trfc_ps   = %u\n", outpdimm->trfc_ps); | ||||||
| 	debug("trrd_ps   = %u\n", outpdimm->trrd_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); | 	debug("trc_ps    = %u\n", outpdimm->trc_ps); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008-2012 Freescale Semiconductor, Inc. |  * Copyright 2008-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or |  * This program is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU General Public License |  * modify it under the terms of the GNU General Public License | ||||||
|  | @ -81,14 +81,37 @@ u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #define SPD_SPA0_ADDRESS	0x36 | ||||||
|  | #define SPD_SPA1_ADDRESS	0x37 | ||||||
|  | 
 | ||||||
| static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) | static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) | ||||||
| { | { | ||||||
| 	int ret; | 	int ret; | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 	uint8_t dummy = 0; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM); | 	i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM); | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 	/*
 | ||||||
|  | 	 * DDR4 SPD has 384 to 512 bytes | ||||||
|  | 	 * To access the lower 256 bytes, we need to set EE page address to 0 | ||||||
|  | 	 * To access the upper 256 bytes, we need to set EE page address to 1 | ||||||
|  | 	 * See Jedec standar No. 21-C for detail | ||||||
|  | 	 */ | ||||||
|  | 	i2c_write(SPD_SPA0_ADDRESS, 0, 1, &dummy, 1); | ||||||
|  | 	ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, 256); | ||||||
|  | 	if (!ret) { | ||||||
|  | 		i2c_write(SPD_SPA1_ADDRESS, 0, 1, &dummy, 1); | ||||||
|  | 		ret = i2c_read(i2c_address, 0, 1, | ||||||
|  | 			       (uchar *)((ulong)spd + 256), | ||||||
|  | 			       min(256, sizeof(generic_spd_eeprom_t) - 256)); | ||||||
|  | 	} | ||||||
|  | #else | ||||||
| 	ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, | 	ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, | ||||||
| 				sizeof(generic_spd_eeprom_t)); | 				sizeof(generic_spd_eeprom_t)); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	if (ret) { | 	if (ret) { | ||||||
| 		if (i2c_address == | 		if (i2c_address == | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008, 2010-2012 Freescale Semiconductor, Inc. |  * Copyright 2008, 2010-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier:	GPL-2.0+ |  * SPDX-License-Identifier:	GPL-2.0+ | ||||||
|  */ |  */ | ||||||
|  | @ -29,7 +29,7 @@ struct dynamic_odt { | ||||||
| 	unsigned int odt_rtt_wr; | 	unsigned int odt_rtt_wr; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_SYS_FSL_DDR3 | #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) | ||||||
| static const struct dynamic_odt single_Q[4] = { | static const struct dynamic_odt single_Q[4] = { | ||||||
| 	{	/* cs0 */ | 	{	/* cs0 */ | ||||||
| 		FSL_DDR_ODT_NEVER, | 		FSL_DDR_ODT_NEVER, | ||||||
|  | @ -259,7 +259,7 @@ static const struct dynamic_odt odt_unknown[4] = { | ||||||
| 		DDR3_RTT_OFF | 		DDR3_RTT_OFF | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| #else	/* CONFIG_SYS_FSL_DDR3 */ | #else	/* CONFIG_SYS_FSL_DDR3 || CONFIG_SYS_FSL_DDR4 */ | ||||||
| static const struct dynamic_odt single_Q[4] = { | static const struct dynamic_odt single_Q[4] = { | ||||||
| 	{0, 0, 0, 0}, | 	{0, 0, 0, 0}, | ||||||
| 	{0, 0, 0, 0}, | 	{0, 0, 0, 0}, | ||||||
|  | @ -507,7 +507,9 @@ unsigned int populate_memctl_options(int all_dimms_registered, | ||||||
| 	unsigned int i; | 	unsigned int i; | ||||||
| 	char buffer[HWCONFIG_BUFFER_SIZE]; | 	char buffer[HWCONFIG_BUFFER_SIZE]; | ||||||
| 	char *buf = NULL; | 	char *buf = NULL; | ||||||
| #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR2) | #if defined(CONFIG_SYS_FSL_DDR3) || \ | ||||||
|  | 	defined(CONFIG_SYS_FSL_DDR2) || \ | ||||||
|  | 	defined(CONFIG_SYS_FSL_DDR4) | ||||||
| 	const struct dynamic_odt *pdodt = odt_unknown; | 	const struct dynamic_odt *pdodt = odt_unknown; | ||||||
| #endif | #endif | ||||||
| 	ulong ddr_freq; | 	ulong ddr_freq; | ||||||
|  | @ -519,7 +521,9 @@ unsigned int populate_memctl_options(int all_dimms_registered, | ||||||
| 	if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0) | 	if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0) | ||||||
| 		buf = buffer; | 		buf = buffer; | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR2) | #if defined(CONFIG_SYS_FSL_DDR3) || \ | ||||||
|  | 	defined(CONFIG_SYS_FSL_DDR2) || \ | ||||||
|  | 	defined(CONFIG_SYS_FSL_DDR4) | ||||||
| 	/* Chip select options. */ | 	/* Chip select options. */ | ||||||
| 	if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) { | 	if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) { | ||||||
| 		switch (pdimm[0].n_ranks) { | 		switch (pdimm[0].n_ranks) { | ||||||
|  | @ -585,7 +589,9 @@ unsigned int populate_memctl_options(int all_dimms_registered, | ||||||
| 
 | 
 | ||||||
| 	/* Pick chip-select local options. */ | 	/* Pick chip-select local options. */ | ||||||
| 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { | 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { | ||||||
| #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR2) | #if defined(CONFIG_SYS_FSL_DDR3) || \ | ||||||
|  | 	defined(CONFIG_SYS_FSL_DDR2) || \ | ||||||
|  | 	defined(CONFIG_SYS_FSL_DDR4) | ||||||
| 		popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg; | 		popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg; | ||||||
| 		popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg; | 		popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg; | ||||||
| 		popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm; | 		popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm; | ||||||
|  | @ -703,7 +709,7 @@ unsigned int populate_memctl_options(int all_dimms_registered, | ||||||
| 	popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0; | 	popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0; | ||||||
| 
 | 
 | ||||||
| 	/* Choose burst length. */ | 	/* Choose burst length. */ | ||||||
| #if defined(CONFIG_SYS_FSL_DDR3) | #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) | ||||||
| #if defined(CONFIG_E500MC) | #if defined(CONFIG_E500MC) | ||||||
| 	popts->otf_burst_chop_en = 0;	/* on-the-fly burst chop disable */ | 	popts->otf_burst_chop_en = 0;	/* on-the-fly burst chop disable */ | ||||||
| 	popts->burst_length = DDR_BL8;	/* Fixed 8-beat burst len */ | 	popts->burst_length = DDR_BL8;	/* Fixed 8-beat burst len */ | ||||||
|  | @ -722,7 +728,7 @@ unsigned int populate_memctl_options(int all_dimms_registered, | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	/* Choose ddr controller address mirror mode */ | 	/* Choose ddr controller address mirror mode */ | ||||||
| #if defined(CONFIG_SYS_FSL_DDR3) | #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) | ||||||
| 	popts->mirrored_dimm = pdimm[0].mirrored_dimm; | 	popts->mirrored_dimm = pdimm[0].mirrored_dimm; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | @ -766,11 +772,9 @@ unsigned int populate_memctl_options(int all_dimms_registered, | ||||||
| 	 * BSTTOPRE precharge interval | 	 * BSTTOPRE precharge interval | ||||||
| 	 * | 	 * | ||||||
| 	 * Set this to 0 for global auto precharge | 	 * Set this to 0 for global auto precharge | ||||||
| 	 * | 	 * The value of 0x100 has been used for DDR1, DDR2, DDR3. | ||||||
| 	 * FIXME: Should this be configured in picoseconds? | 	 * It is not wrong. Any value should be OK. The performance depends on | ||||||
| 	 * Why it should be in ps:  better understanding of this | 	 * applications. There is no one good value for all. | ||||||
| 	 * relative to actual DRAM timing parameters such as tRAS. |  | ||||||
| 	 * e.g. tRAS(min) = 40 ns |  | ||||||
| 	 */ | 	 */ | ||||||
| 	popts->bstopre = 0x100; | 	popts->bstopre = 0x100; | ||||||
| 
 | 
 | ||||||
|  | @ -795,12 +799,12 @@ unsigned int populate_memctl_options(int all_dimms_registered, | ||||||
| 	 */ | 	 */ | ||||||
| 	popts->tfaw_window_four_activates_ps = 37500; | 	popts->tfaw_window_four_activates_ps = 37500; | ||||||
| 
 | 
 | ||||||
| #elif defined(CONFIG_SYS_FSL_DDR3) | #else | ||||||
| 	popts->tfaw_window_four_activates_ps = pdimm[0].tfaw_ps; | 	popts->tfaw_window_four_activates_ps = pdimm[0].tfaw_ps; | ||||||
| #endif | #endif | ||||||
| 	popts->zq_en = 0; | 	popts->zq_en = 0; | ||||||
| 	popts->wrlvl_en = 0; | 	popts->wrlvl_en = 0; | ||||||
| #if defined(CONFIG_SYS_FSL_DDR3) | #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * due to ddr3 dimm is fly-by topology | 	 * due to ddr3 dimm is fly-by topology | ||||||
| 	 * we suggest to enable write leveling to | 	 * we suggest to enable write leveling to | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008-2012 Freescale Semiconductor, Inc. |  * Copyright 2008-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or |  * This program is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU General Public License |  * modify it under the terms of the GNU General Public License | ||||||
|  | @ -23,6 +23,18 @@ | ||||||
| 
 | 
 | ||||||
| #define ULL_8FS 0xFFFFFFFFULL | #define ULL_8FS 0xFFFFFFFFULL | ||||||
| 
 | 
 | ||||||
|  | u32 fsl_ddr_get_version(void) | ||||||
|  | { | ||||||
|  | 	struct ccsr_ddr __iomem *ddr; | ||||||
|  | 	u32 ver_major_minor_errata; | ||||||
|  | 
 | ||||||
|  | 	ddr = (void *)_DDR_ADDR; | ||||||
|  | 	ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8; | ||||||
|  | 	ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8; | ||||||
|  | 
 | ||||||
|  | 	return ver_major_minor_errata; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Round up mclk_ps to nearest 1 ps in memory controller code |  * Round up mclk_ps to nearest 1 ps in memory controller code | ||||||
|  * if the error is 0.5ps or more. |  * if the error is 0.5ps or more. | ||||||
|  | @ -175,6 +187,9 @@ void board_add_ram_info(int use_default) | ||||||
| 	case SDRAM_TYPE_DDR3: | 	case SDRAM_TYPE_DDR3: | ||||||
| 		puts("3"); | 		puts("3"); | ||||||
| 		break; | 		break; | ||||||
|  | 	case SDRAM_TYPE_DDR4: | ||||||
|  | 		puts("4"); | ||||||
|  | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		puts("?"); | 		puts("?"); | ||||||
| 		break; | 		break; | ||||||
|  | @ -188,9 +203,12 @@ void board_add_ram_info(int use_default) | ||||||
| 		puts(", 64-bit"); | 		puts(", 64-bit"); | ||||||
| 
 | 
 | ||||||
| 	/* Calculate CAS latency based on timing cfg values */ | 	/* Calculate CAS latency based on timing cfg values */ | ||||||
| 	cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf) + 1; | 	cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf); | ||||||
| 	if ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 1) | 	if (fsl_ddr_get_version() <= 0x40400) | ||||||
| 		cas_lat += (8 << 1); | 		cas_lat += 1; | ||||||
|  | 	else | ||||||
|  | 		cas_lat += 2; | ||||||
|  | 	cas_lat += ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 3) << 4; | ||||||
| 	printf(", CL=%d", cas_lat >> 1); | 	printf(", CL=%d", cas_lat >> 1); | ||||||
| 	if (cas_lat & 0x1) | 	if (cas_lat & 0x1) | ||||||
| 		puts(".5"); | 		puts(".5"); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008 Freescale Semiconductor, Inc. |  * Copyright 2008-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or |  * This program is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU General Public License |  * modify it under the terms of the GNU General Public License | ||||||
|  | @ -14,32 +14,45 @@ typedef struct { | ||||||
| 
 | 
 | ||||||
| 	unsigned int tckmin_x_ps; | 	unsigned int tckmin_x_ps; | ||||||
| 	unsigned int tckmax_ps; | 	unsigned int tckmax_ps; | ||||||
| 	unsigned int tckmax_max_ps; |  | ||||||
| 	unsigned int trcd_ps; | 	unsigned int trcd_ps; | ||||||
| 	unsigned int trp_ps; | 	unsigned int trp_ps; | ||||||
| 	unsigned int tras_ps; | 	unsigned int tras_ps; | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) | ||||||
|  | 	unsigned int taamin_ps; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	unsigned int twr_ps;	/* maximum = 63750 ps */ | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 	unsigned int trfc1_ps; | ||||||
|  | 	unsigned int trfc2_ps; | ||||||
|  | 	unsigned int trfc4_ps; | ||||||
|  | 	unsigned int trrds_ps; | ||||||
|  | 	unsigned int trrdl_ps; | ||||||
|  | 	unsigned int tccdl_ps; | ||||||
|  | #else | ||||||
| 	unsigned int twtr_ps;	/* maximum = 63750 ps */ | 	unsigned int twtr_ps;	/* maximum = 63750 ps */ | ||||||
| 	unsigned int trfc_ps;	/* maximum = 255 ns + 256 ns + .75 ns
 | 	unsigned int trfc_ps;	/* maximum = 255 ns + 256 ns + .75 ns
 | ||||||
| 					   = 511750 ps */ | 					   = 511750 ps */ | ||||||
| 
 | 
 | ||||||
| 	unsigned int trrd_ps;	/* maximum = 63750 ps */ | 	unsigned int trrd_ps;	/* maximum = 63750 ps */ | ||||||
|  | 	unsigned int trtp_ps;	/* byte 38, spd->trtp */ | ||||||
|  | #endif | ||||||
|  | 	unsigned int twr_ps;	/* maximum = 63750 ps */ | ||||||
| 	unsigned int trc_ps;	/* maximum = 254 ns + .75 ns = 254750 ps */ | 	unsigned int trc_ps;	/* maximum = 254 ns + .75 ns = 254750 ps */ | ||||||
| 
 | 
 | ||||||
| 	unsigned int refresh_rate_ps; | 	unsigned int refresh_rate_ps; | ||||||
| 	unsigned int extended_op_srt; | 	unsigned int extended_op_srt; | ||||||
| 
 | 
 | ||||||
|  | #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 	unsigned int tis_ps;	/* byte 32, spd->ca_setup */ | 	unsigned int tis_ps;	/* byte 32, spd->ca_setup */ | ||||||
| 	unsigned int tih_ps;	/* byte 33, spd->ca_hold */ | 	unsigned int tih_ps;	/* byte 33, spd->ca_hold */ | ||||||
| 	unsigned int tds_ps;	/* byte 34, spd->data_setup */ | 	unsigned int tds_ps;	/* byte 34, spd->data_setup */ | ||||||
| 	unsigned int tdh_ps;	/* byte 35, spd->data_hold */ | 	unsigned int tdh_ps;	/* byte 35, spd->data_hold */ | ||||||
| 	unsigned int trtp_ps;	/* byte 38, spd->trtp */ |  | ||||||
| 	unsigned int tdqsq_max_ps;	/* byte 44, spd->tdqsq */ | 	unsigned int tdqsq_max_ps;	/* byte 44, spd->tdqsq */ | ||||||
| 	unsigned int tqhs_ps;	/* byte 45, spd->tqhs */ | 	unsigned int tqhs_ps;	/* byte 45, spd->tqhs */ | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	unsigned int ndimms_present; | 	unsigned int ndimms_present; | ||||||
| 	unsigned int lowest_common_SPD_caslat; | 	unsigned int lowest_common_spd_caslat; | ||||||
| 	unsigned int highest_common_derated_caslat; | 	unsigned int highest_common_derated_caslat; | ||||||
| 	unsigned int additive_latency; | 	unsigned int additive_latency; | ||||||
| 	unsigned int all_dimms_burst_lengths_bitmask; | 	unsigned int all_dimms_burst_lengths_bitmask; | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008 Freescale Semiconductor, Inc. |  * Copyright 2008-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or |  * This program is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU General Public License |  * modify it under the terms of the GNU General Public License | ||||||
|  | @ -290,11 +290,220 @@ typedef struct ddr3_spd_eeprom_s { | ||||||
| 
 | 
 | ||||||
| } ddr3_spd_eeprom_t; | } ddr3_spd_eeprom_t; | ||||||
| 
 | 
 | ||||||
|  | /* From JEEC Standard No. 21-C release 23A */ | ||||||
|  | struct ddr4_spd_eeprom_s { | ||||||
|  | 	/* General Section: Bytes 0-127 */ | ||||||
|  | 	uint8_t info_size_crc;		/*  0 # bytes */ | ||||||
|  | 	uint8_t spd_rev;		/*  1 Total # bytes of SPD */ | ||||||
|  | 	uint8_t mem_type;		/*  2 Key Byte / mem type */ | ||||||
|  | 	uint8_t module_type;		/*  3 Key Byte / Module Type */ | ||||||
|  | 	uint8_t density_banks;		/*  4 Density and Banks	*/ | ||||||
|  | 	uint8_t addressing;		/*  5 Addressing */ | ||||||
|  | 	uint8_t package_type;		/*  6 Package type */ | ||||||
|  | 	uint8_t opt_feature;		/*  7 Optional features */ | ||||||
|  | 	uint8_t thermal_ref;		/*  8 Thermal and refresh */ | ||||||
|  | 	uint8_t oth_opt_features;	/*  9 Other optional features */ | ||||||
|  | 	uint8_t res_10;			/* 10 Reserved */ | ||||||
|  | 	uint8_t module_vdd;		/* 11 Module nominal voltage */ | ||||||
|  | 	uint8_t organization;		/* 12 Module Organization */ | ||||||
|  | 	uint8_t bus_width;		/* 13 Module Memory Bus Width */ | ||||||
|  | 	uint8_t therm_sensor;		/* 14 Module Thermal Sensor */ | ||||||
|  | 	uint8_t ext_type;		/* 15 Extended module type */ | ||||||
|  | 	uint8_t res_16; | ||||||
|  | 	uint8_t timebases;		/* 17 MTb and FTB */ | ||||||
|  | 	uint8_t tck_min;		/* 18 tCKAVGmin */ | ||||||
|  | 	uint8_t tck_max;		/* 19 TCKAVGmax */ | ||||||
|  | 	uint8_t caslat_b1;		/* 20 CAS latencies, 1st byte */ | ||||||
|  | 	uint8_t caslat_b2;		/* 21 CAS latencies, 2nd byte */ | ||||||
|  | 	uint8_t caslat_b3;		/* 22 CAS latencies, 3rd byte */ | ||||||
|  | 	uint8_t caslat_b4;		/* 23 CAS latencies, 4th byte */ | ||||||
|  | 	uint8_t taa_min;		/* 24 Min CAS Latency Time */ | ||||||
|  | 	uint8_t trcd_min;		/* 25 Min RAS# to CAS# Delay Time */ | ||||||
|  | 	uint8_t trp_min;		/* 26 Min Row Precharge Delay Time */ | ||||||
|  | 	uint8_t tras_trc_ext;		/* 27 Upper Nibbles for tRAS and tRC */ | ||||||
|  | 	uint8_t tras_min_lsb;		/* 28 tRASmin, lsb */ | ||||||
|  | 	uint8_t trc_min_lsb;		/* 29 tRCmin, lsb */ | ||||||
|  | 	uint8_t trfc1_min_lsb;		/* 30 Min Refresh Recovery Delay Time */ | ||||||
|  | 	uint8_t trfc1_min_msb;		/* 31 Min Refresh Recovery Delay Time */ | ||||||
|  | 	uint8_t trfc2_min_lsb;		/* 32 Min Refresh Recovery Delay Time */ | ||||||
|  | 	uint8_t trfc2_min_msb;		/* 33 Min Refresh Recovery Delay Time */ | ||||||
|  | 	uint8_t trfc4_min_lsb;		/* 34 Min Refresh Recovery Delay Time */ | ||||||
|  | 	uint8_t trfc4_min_msb;		/* 35 Min Refresh Recovery Delay Time */ | ||||||
|  | 	uint8_t tfaw_msb;		/* 36 Upper Nibble for tFAW */ | ||||||
|  | 	uint8_t tfaw_min;		/* 37 tFAW, lsb */ | ||||||
|  | 	uint8_t trrds_min;		/* 38 tRRD_Smin, MTB */ | ||||||
|  | 	uint8_t trrdl_min;		/* 39 tRRD_Lmin, MTB */ | ||||||
|  | 	uint8_t tccdl_min;		/* 40 tCCS_Lmin, MTB */ | ||||||
|  | 	uint8_t res_41[60-41];		/* 41 Rserved */ | ||||||
|  | 	uint8_t mapping[78-60];		/* 60~77 Connector to SDRAM bit map */ | ||||||
|  | 	uint8_t res_78[117-78];		/* 78~116, Reserved */ | ||||||
|  | 	int8_t fine_tccdl_min;		/* 117 Fine offset for tCCD_Lmin */ | ||||||
|  | 	int8_t fine_trrdl_min;		/* 118 Fine offset for tRRD_Lmin */ | ||||||
|  | 	int8_t fine_trrds_min;		/* 119 Fine offset for tRRD_Smin */ | ||||||
|  | 	int8_t fine_trc_min;		/* 120 Fine offset for tRCmin */ | ||||||
|  | 	int8_t fine_trp_min;		/* 121 Fine offset for tRPmin */ | ||||||
|  | 	int8_t fine_trcd_min;		/* 122 Fine offset for tRCDmin */ | ||||||
|  | 	int8_t fine_taa_min;		/* 123 Fine offset for tAAmin */ | ||||||
|  | 	int8_t fine_tck_max;		/* 124 Fine offset for tCKAVGmax */ | ||||||
|  | 	int8_t fine_tck_min;		/* 125 Fine offset for tCKAVGmin */ | ||||||
|  | 	/* CRC: Bytes 126-127 */ | ||||||
|  | 	uint8_t crc[2];			/* 126-127 SPD CRC */ | ||||||
|  | 
 | ||||||
|  | 	/* Module-Specific Section: Bytes 128-255 */ | ||||||
|  | 	union { | ||||||
|  | 		struct { | ||||||
|  | 			/* 128 (Unbuffered) Module Nominal Height */ | ||||||
|  | 			uint8_t mod_height; | ||||||
|  | 			/* 129 (Unbuffered) Module Maximum Thickness */ | ||||||
|  | 			uint8_t mod_thickness; | ||||||
|  | 			/* 130 (Unbuffered) Reference Raw Card Used */ | ||||||
|  | 			uint8_t ref_raw_card; | ||||||
|  | 			/* 131 (Unbuffered) Address Mapping from
 | ||||||
|  | 			      Edge Connector to DRAM */ | ||||||
|  | 			uint8_t addr_mapping; | ||||||
|  | 			/* 132~253 (Unbuffered) Reserved */ | ||||||
|  | 			uint8_t res_132[254-132]; | ||||||
|  | 			/* 254~255 CRC */ | ||||||
|  | 			uint8_t crc[2]; | ||||||
|  | 		} unbuffered; | ||||||
|  | 		struct { | ||||||
|  | 			/* 128 (Registered) Module Nominal Height */ | ||||||
|  | 			uint8_t mod_height; | ||||||
|  | 			/* 129 (Registered) Module Maximum Thickness */ | ||||||
|  | 			uint8_t mod_thickness; | ||||||
|  | 			/* 130 (Registered) Reference Raw Card Used */ | ||||||
|  | 			uint8_t ref_raw_card; | ||||||
|  | 			/* 131 DIMM Module Attributes */ | ||||||
|  | 			uint8_t modu_attr; | ||||||
|  | 			/* 132 RDIMM Thermal Heat Spreader Solution */ | ||||||
|  | 			uint8_t thermal; | ||||||
|  | 			/* 133 Register Manufacturer ID Code, LSB */ | ||||||
|  | 			uint8_t reg_id_lo; | ||||||
|  | 			/* 134 Register Manufacturer ID Code, MSB */ | ||||||
|  | 			uint8_t reg_id_hi; | ||||||
|  | 			/* 135 Register Revision Number */ | ||||||
|  | 			uint8_t reg_rev; | ||||||
|  | 			/* 136 Address mapping from register to DRAM */ | ||||||
|  | 			uint8_t reg_map; | ||||||
|  | 			/* 137~253 Reserved */ | ||||||
|  | 			uint8_t res_137[254-137]; | ||||||
|  | 			/* 254~255 CRC */ | ||||||
|  | 			uint8_t crc[2]; | ||||||
|  | 		} registered; | ||||||
|  | 		struct { | ||||||
|  | 			/* 128 (Loadreduced) Module Nominal Height */ | ||||||
|  | 			uint8_t mod_height; | ||||||
|  | 			/* 129 (Loadreduced) Module Maximum Thickness */ | ||||||
|  | 			uint8_t mod_thickness; | ||||||
|  | 			/* 130 (Loadreduced) Reference Raw Card Used */ | ||||||
|  | 			uint8_t ref_raw_card; | ||||||
|  | 			/* 131 DIMM Module Attributes */ | ||||||
|  | 			uint8_t modu_attr; | ||||||
|  | 			/* 132 RDIMM Thermal Heat Spreader Solution */ | ||||||
|  | 			uint8_t thermal; | ||||||
|  | 			/* 133 Register Manufacturer ID Code, LSB */ | ||||||
|  | 			uint8_t reg_id_lo; | ||||||
|  | 			/* 134 Register Manufacturer ID Code, MSB */ | ||||||
|  | 			uint8_t reg_id_hi; | ||||||
|  | 			/* 135 Register Revision Number */ | ||||||
|  | 			uint8_t reg_rev; | ||||||
|  | 			/* 136 Address mapping from register to DRAM */ | ||||||
|  | 			uint8_t reg_map; | ||||||
|  | 			/* 137 Register Output Drive Strength for CMD/Add*/ | ||||||
|  | 			uint8_t reg_drv; | ||||||
|  | 			/* 138 Register Output Drive Strength for CK */ | ||||||
|  | 			uint8_t reg_drv_ck; | ||||||
|  | 			/* 139 Data Buffer Revision Number */ | ||||||
|  | 			uint8_t data_buf_rev; | ||||||
|  | 			/* 140 DRAM VrefDQ for Package Rank 0 */ | ||||||
|  | 			uint8_t vrefqe_r0; | ||||||
|  | 			/* 141 DRAM VrefDQ for Package Rank 1 */ | ||||||
|  | 			uint8_t vrefqe_r1; | ||||||
|  | 			/* 142 DRAM VrefDQ for Package Rank 2 */ | ||||||
|  | 			uint8_t vrefqe_r2; | ||||||
|  | 			/* 143 DRAM VrefDQ for Package Rank 3 */ | ||||||
|  | 			uint8_t vrefqe_r3; | ||||||
|  | 			/* 144 Data Buffer VrefDQ for DRAM Interface */ | ||||||
|  | 			uint8_t data_intf; | ||||||
|  | 			/*
 | ||||||
|  | 			 * 145 Data Buffer MDQ Drive Strength and RTT | ||||||
|  | 			 * for data rate <= 1866 | ||||||
|  | 			 */ | ||||||
|  | 			uint8_t data_drv_1866; | ||||||
|  | 			/*
 | ||||||
|  | 			 * 146 Data Buffer MDQ Drive Strength and RTT | ||||||
|  | 			 * for 1866 < data rate <= 2400 | ||||||
|  | 			 */ | ||||||
|  | 			uint8_t data_drv_2400; | ||||||
|  | 			/*
 | ||||||
|  | 			 * 147 Data Buffer MDQ Drive Strength and RTT | ||||||
|  | 			 * for 2400 < data rate <= 3200 | ||||||
|  | 			 */ | ||||||
|  | 			uint8_t data_drv_3200; | ||||||
|  | 			/* 148 DRAM Drive Strength */ | ||||||
|  | 			uint8_t dram_drv; | ||||||
|  | 			/*
 | ||||||
|  | 			 * 149 DRAM ODT (RTT_WR, RTT_NOM) | ||||||
|  | 			 * for data rate <= 1866 | ||||||
|  | 			 */ | ||||||
|  | 			uint8_t dram_odt_1866; | ||||||
|  | 			/*
 | ||||||
|  | 			 * 150 DRAM ODT (RTT_WR, RTT_NOM) | ||||||
|  | 			 * for 1866 < data rate <= 2400 | ||||||
|  | 			 */ | ||||||
|  | 			uint8_t dram_odt_2400; | ||||||
|  | 			/*
 | ||||||
|  | 			 * 151 DRAM ODT (RTT_WR, RTT_NOM) | ||||||
|  | 			 * for 2400 < data rate <= 3200 | ||||||
|  | 			 */ | ||||||
|  | 			uint8_t dram_odt_3200; | ||||||
|  | 			/*
 | ||||||
|  | 			 * 152 DRAM ODT (RTT_PARK) | ||||||
|  | 			 * for data rate <= 1866 | ||||||
|  | 			 */ | ||||||
|  | 			uint8_t dram_odt_park_1866; | ||||||
|  | 			/*
 | ||||||
|  | 			 * 153 DRAM ODT (RTT_PARK) | ||||||
|  | 			 * for 1866 < data rate <= 2400 | ||||||
|  | 			 */ | ||||||
|  | 			uint8_t dram_odt_park_2400; | ||||||
|  | 			/*
 | ||||||
|  | 			 * 154 DRAM ODT (RTT_PARK) | ||||||
|  | 			 * for 2400 < data rate <= 3200 | ||||||
|  | 			 */ | ||||||
|  | 			uint8_t dram_odt_park_3200; | ||||||
|  | 			uint8_t res_155[254-155];	/* Reserved */ | ||||||
|  | 			/* 254~255 CRC */ | ||||||
|  | 			uint8_t crc[2]; | ||||||
|  | 		} loadreduced; | ||||||
|  | 		uint8_t uc[128]; /* 128-255 Module-Specific Section */ | ||||||
|  | 	} mod_section; | ||||||
|  | 
 | ||||||
|  | 	uint8_t res_256[320-256];	/* 256~319 Reserved */ | ||||||
|  | 
 | ||||||
|  | 	/* Module supplier's data: Byte 320~383 */ | ||||||
|  | 	uint8_t mmid_lsb;		/* 320 Module MfgID Code LSB */ | ||||||
|  | 	uint8_t mmid_msb;		/* 321 Module MfgID Code MSB */ | ||||||
|  | 	uint8_t mloc;			/* 322 Mfg Location */ | ||||||
|  | 	uint8_t mdate[2];		/* 323~324 Mfg Date */ | ||||||
|  | 	uint8_t sernum[4];		/* 325~328 Module Serial Number */ | ||||||
|  | 	uint8_t mpart[20];		/* 329~348 Mfg's Module Part Number */ | ||||||
|  | 	uint8_t mrev;			/* 349 Module Revision Code */ | ||||||
|  | 	uint8_t dmid_lsb;		/* 350 DRAM MfgID Code LSB */ | ||||||
|  | 	uint8_t dmid_msb;		/* 351 DRAM MfgID Code MSB */ | ||||||
|  | 	uint8_t stepping;		/* 352 DRAM stepping */ | ||||||
|  | 	uint8_t msd[29];		/* 353~381 Mfg's Specific Data */ | ||||||
|  | 	uint8_t res_382[2];		/* 382~383 Reserved */ | ||||||
|  | 
 | ||||||
|  | 	uint8_t user[512-384];		/* 384~511 End User Programmable */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| extern unsigned int ddr1_spd_check(const ddr1_spd_eeprom_t *spd); | extern unsigned int ddr1_spd_check(const ddr1_spd_eeprom_t *spd); | ||||||
| extern void ddr1_spd_dump(const ddr1_spd_eeprom_t *spd); | extern void ddr1_spd_dump(const ddr1_spd_eeprom_t *spd); | ||||||
| extern unsigned int ddr2_spd_check(const ddr2_spd_eeprom_t *spd); | extern unsigned int ddr2_spd_check(const ddr2_spd_eeprom_t *spd); | ||||||
| extern void ddr2_spd_dump(const ddr2_spd_eeprom_t *spd); | extern void ddr2_spd_dump(const ddr2_spd_eeprom_t *spd); | ||||||
| extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd); | extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd); | ||||||
|  | unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s *spd); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Byte 2 Fundamental Memory Types. |  * Byte 2 Fundamental Memory Types. | ||||||
|  | @ -310,6 +519,7 @@ extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd); | ||||||
| #define SPD_MEMTYPE_DDR2_FBDIMM	(0x09) | #define SPD_MEMTYPE_DDR2_FBDIMM	(0x09) | ||||||
| #define SPD_MEMTYPE_DDR2_FBDIMM_PROBE	(0x0A) | #define SPD_MEMTYPE_DDR2_FBDIMM_PROBE	(0x0A) | ||||||
| #define SPD_MEMTYPE_DDR3	(0x0B) | #define SPD_MEMTYPE_DDR3	(0x0B) | ||||||
|  | #define SPD_MEMTYPE_DDR4	(0x0C) | ||||||
| 
 | 
 | ||||||
| /* DIMM Type for DDR2 SPD (according to v1.3) */ | /* DIMM Type for DDR2 SPD (according to v1.3) */ | ||||||
| #define DDR2_SPD_DIMMTYPE_UNDEFINED	(0x00) | #define DDR2_SPD_DIMMTYPE_UNDEFINED	(0x00) | ||||||
|  | @ -338,4 +548,18 @@ extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd); | ||||||
| #define DDR3_SPD_MODULETYPE_16B_SO_DIMM	(0x0C) | #define DDR3_SPD_MODULETYPE_16B_SO_DIMM	(0x0C) | ||||||
| #define DDR3_SPD_MODULETYPE_32B_SO_DIMM	(0x0D) | #define DDR3_SPD_MODULETYPE_32B_SO_DIMM	(0x0D) | ||||||
| 
 | 
 | ||||||
|  | /* DIMM Type for DDR4 SPD */ | ||||||
|  | #define DDR4_SPD_MODULETYPE_MASK	(0x0f) | ||||||
|  | #define DDR4_SPD_MODULETYPE_EXT		(0x00) | ||||||
|  | #define DDR4_SPD_MODULETYPE_RDIMM	(0x01) | ||||||
|  | #define DDR4_SPD_MODULETYPE_UDIMM	(0x02) | ||||||
|  | #define DDR4_SPD_MODULETYPE_SO_DIMM	(0x03) | ||||||
|  | #define DDR4_SPD_MODULETYPE_LRDIMM	(0x04) | ||||||
|  | #define DDR4_SPD_MODULETYPE_MINI_RDIMM	(0x05) | ||||||
|  | #define DDR4_SPD_MODULETYPE_MINI_UDIMM	(0x06) | ||||||
|  | #define DDR4_SPD_MODULETYPE_72B_SO_UDIMM	(0x08) | ||||||
|  | #define DDR4_SPD_MODULETYPE_72B_SO_RDIMM	(0x09) | ||||||
|  | #define DDR4_SPD_MODULETYPE_16B_SO_DIMM	(0x0C) | ||||||
|  | #define DDR4_SPD_MODULETYPE_32B_SO_DIMM	(0x0D) | ||||||
|  | 
 | ||||||
| #endif /* _DDR_SPD_H_ */ | #endif /* _DDR_SPD_H_ */ | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008-2011 Freescale Semiconductor, Inc. |  * Copyright 2008-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or |  * This program is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU General Public License |  * modify it under the terms of the GNU General Public License | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| #ifndef FSL_DDR_MAIN_H | #ifndef FSL_DDR_MAIN_H | ||||||
| #define FSL_DDR_MAIN_H | #define FSL_DDR_MAIN_H | ||||||
| 
 | 
 | ||||||
|  | #include <fsl_ddrc_version.h> | ||||||
| #include <fsl_ddr_sdram.h> | #include <fsl_ddr_sdram.h> | ||||||
| #include <fsl_ddr_dimm_params.h> | #include <fsl_ddr_dimm_params.h> | ||||||
| 
 | 
 | ||||||
|  | @ -22,6 +23,10 @@ | ||||||
| #define ddr_out32(a, v)	out_be32(a, v) | #define ddr_out32(a, v)	out_be32(a, v) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #define _DDR_ADDR CONFIG_SYS_FSL_DDR_ADDR | ||||||
|  | 
 | ||||||
|  | u32 fsl_ddr_get_version(void); | ||||||
|  | 
 | ||||||
| #if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM) | #if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM) | ||||||
| /*
 | /*
 | ||||||
|  * Bind the main DDR setup driver's generic names |  * Bind the main DDR setup driver's generic names | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008 Freescale Semiconductor, Inc. |  * Copyright 2008-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or |  * This program is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU General Public License |  * modify it under the terms of the GNU General Public License | ||||||
|  | @ -13,7 +13,7 @@ | ||||||
| #define EDC_ECC		2 | #define EDC_ECC		2 | ||||||
| #define EDC_AC_PARITY	4 | #define EDC_AC_PARITY	4 | ||||||
| 
 | 
 | ||||||
| /* Parameters for a DDR2 dimm computed from the SPD */ | /* Parameters for a DDR dimm computed from the SPD */ | ||||||
| typedef struct dimm_params_s { | typedef struct dimm_params_s { | ||||||
| 
 | 
 | ||||||
| 	/* DIMM organization parameters */ | 	/* DIMM organization parameters */ | ||||||
|  | @ -32,7 +32,12 @@ typedef struct dimm_params_s { | ||||||
| 	unsigned int n_row_addr; | 	unsigned int n_row_addr; | ||||||
| 	unsigned int n_col_addr; | 	unsigned int n_col_addr; | ||||||
| 	unsigned int edc_config;	/* 0 = none, 1 = parity, 2 = ECC */ | 	unsigned int edc_config;	/* 0 = none, 1 = parity, 2 = ECC */ | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 	unsigned int bank_addr_bits; | ||||||
|  | 	unsigned int bank_group_bits; | ||||||
|  | #else | ||||||
| 	unsigned int n_banks_per_sdram_device; | 	unsigned int n_banks_per_sdram_device; | ||||||
|  | #endif | ||||||
| 	unsigned int burst_lengths_bitmask;	/* BL=4 bit 2, BL=8 = bit 3 */ | 	unsigned int burst_lengths_bitmask;	/* BL=4 bit 2, BL=8 = bit 3 */ | ||||||
| 	unsigned int row_density; | 	unsigned int row_density; | ||||||
| 
 | 
 | ||||||
|  | @ -43,19 +48,19 @@ typedef struct dimm_params_s { | ||||||
| 
 | 
 | ||||||
| 	/* DIMM timing parameters */ | 	/* DIMM timing parameters */ | ||||||
| 
 | 
 | ||||||
| 	unsigned int mtb_ps;	/* medium timebase ps, only for ddr3 */ | 	int mtb_ps;	/* medium timebase ps */ | ||||||
| 	unsigned int ftb_10th_ps; /* fine timebase, in 1/10 ps, only for ddr3 */ | 	int ftb_10th_ps; /* fine timebase, in 1/10 ps */ | ||||||
| 	unsigned int taa_ps;	/* minimum CAS latency time, only for ddr3 */ | 	int taa_ps;	/* minimum CAS latency time */ | ||||||
| 	unsigned int tfaw_ps;	/* four active window delay, only for ddr3 */ | 	int tfaw_ps;	/* four active window delay */ | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * SDRAM clock periods | 	 * SDRAM clock periods | ||||||
| 	 * The range for these are 1000-10000 so a short should be sufficient | 	 * The range for these are 1000-10000 so a short should be sufficient | ||||||
| 	 */ | 	 */ | ||||||
| 	unsigned int tckmin_x_ps; | 	int tckmin_x_ps; | ||||||
| 	unsigned int tckmin_x_minus_1_ps; | 	int tckmin_x_minus_1_ps; | ||||||
| 	unsigned int tckmin_x_minus_2_ps; | 	int tckmin_x_minus_2_ps; | ||||||
| 	unsigned int tckmax_ps; | 	int tckmax_ps; | ||||||
| 
 | 
 | ||||||
| 	/* SPD-defined CAS latencies */ | 	/* SPD-defined CAS latencies */ | ||||||
| 	unsigned int caslat_x; | 	unsigned int caslat_x; | ||||||
|  | @ -65,32 +70,46 @@ typedef struct dimm_params_s { | ||||||
| 	unsigned int caslat_lowest_derated;	/* Derated CAS latency */ | 	unsigned int caslat_lowest_derated;	/* Derated CAS latency */ | ||||||
| 
 | 
 | ||||||
| 	/* basic timing parameters */ | 	/* basic timing parameters */ | ||||||
| 	unsigned int trcd_ps; | 	int trcd_ps; | ||||||
| 	unsigned int trp_ps; | 	int trp_ps; | ||||||
| 	unsigned int tras_ps; | 	int tras_ps; | ||||||
| 
 | 
 | ||||||
| 	unsigned int twr_ps;	/* maximum = 63750 ps */ | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
| 	unsigned int twtr_ps;	/* maximum = 63750 ps */ | 	int trfc1_ps; | ||||||
| 	unsigned int trfc_ps;   /* max = 255 ns + 256 ns + .75 ns
 | 	int trfc2_ps; | ||||||
|  | 	int trfc4_ps; | ||||||
|  | 	int trrds_ps; | ||||||
|  | 	int trrdl_ps; | ||||||
|  | 	int tccdl_ps; | ||||||
|  | #else | ||||||
|  | 	int twr_ps;	/* maximum = 63750 ps */ | ||||||
|  | 	int trfc_ps;	/* max = 255 ns + 256 ns + .75 ns
 | ||||||
| 				       = 511750 ps */ | 				       = 511750 ps */ | ||||||
|  | 	int trrd_ps;	/* maximum = 63750 ps */ | ||||||
|  | 	int twtr_ps;	/* maximum = 63750 ps */ | ||||||
|  | 	int trtp_ps;	/* byte 38, spd->trtp */ | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	unsigned int trrd_ps;	/* maximum = 63750 ps */ | 	int trc_ps;	/* maximum = 254 ns + .75 ns = 254750 ps */ | ||||||
| 	unsigned int trc_ps;	/* maximum = 254 ns + .75 ns = 254750 ps */ |  | ||||||
| 
 | 
 | ||||||
| 	unsigned int refresh_rate_ps; | 	int refresh_rate_ps; | ||||||
| 	unsigned int extended_op_srt; | 	int extended_op_srt; | ||||||
| 
 | 
 | ||||||
| 	/* DDR3 doesn't need these as below */ | #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) | ||||||
| 	unsigned int tis_ps;	/* byte 32, spd->ca_setup */ | 	int tis_ps;	/* byte 32, spd->ca_setup */ | ||||||
| 	unsigned int tih_ps;	/* byte 33, spd->ca_hold */ | 	int tih_ps;	/* byte 33, spd->ca_hold */ | ||||||
| 	unsigned int tds_ps;	/* byte 34, spd->data_setup */ | 	int tds_ps;	/* byte 34, spd->data_setup */ | ||||||
| 	unsigned int tdh_ps;	/* byte 35, spd->data_hold */ | 	int tdh_ps;	/* byte 35, spd->data_hold */ | ||||||
| 	unsigned int trtp_ps;	/* byte 38, spd->trtp */ | 	int tdqsq_max_ps;	/* byte 44, spd->tdqsq */ | ||||||
| 	unsigned int tdqsq_max_ps;	/* byte 44, spd->tdqsq */ | 	int tqhs_ps;	/* byte 45, spd->tqhs */ | ||||||
| 	unsigned int tqhs_ps;	/* byte 45, spd->tqhs */ | #endif | ||||||
| 
 | 
 | ||||||
| 	/* DDR3 RDIMM */ | 	/* DDR3 RDIMM */ | ||||||
| 	unsigned char rcw[16];	/* Register Control Word 0-15 */ | 	unsigned char rcw[16];	/* Register Control Word 0-15 */ | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR4 | ||||||
|  | 	unsigned int dq_mapping[18]; | ||||||
|  | 	unsigned int dq_mapping_ors; | ||||||
|  | #endif | ||||||
| } dimm_params_t; | } dimm_params_t; | ||||||
| 
 | 
 | ||||||
| extern unsigned int ddr_compute_dimm_parameters( | extern unsigned int ddr_compute_dimm_parameters( | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2008-2011 Freescale Semiconductor, Inc. |  * Copyright 2008-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or |  * This program is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU General Public License |  * modify it under the terms of the GNU General Public License | ||||||
|  | @ -13,11 +13,13 @@ | ||||||
|  * Pick a basic DDR Technology. |  * Pick a basic DDR Technology. | ||||||
|  */ |  */ | ||||||
| #include <ddr_spd.h> | #include <ddr_spd.h> | ||||||
|  | #include <fsl_ddrc_version.h> | ||||||
| 
 | 
 | ||||||
| #define SDRAM_TYPE_DDR1		2 | #define SDRAM_TYPE_DDR1		2 | ||||||
| #define SDRAM_TYPE_DDR2		3 | #define SDRAM_TYPE_DDR2		3 | ||||||
| #define SDRAM_TYPE_LPDDR1	6 | #define SDRAM_TYPE_LPDDR1	6 | ||||||
| #define SDRAM_TYPE_DDR3		7 | #define SDRAM_TYPE_DDR3		7 | ||||||
|  | #define SDRAM_TYPE_DDR4		5 | ||||||
| 
 | 
 | ||||||
| #define DDR_BL4		4	/* burst length 4 */ | #define DDR_BL4		4	/* burst length 4 */ | ||||||
| #define DDR_BC4		DDR_BL4	/* burst chop for ddr3 */ | #define DDR_BC4		DDR_BL4	/* burst chop for ddr3 */ | ||||||
|  | @ -54,6 +56,12 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; | ||||||
| #ifndef CONFIG_FSL_SDRAM_TYPE | #ifndef CONFIG_FSL_SDRAM_TYPE | ||||||
| #define CONFIG_FSL_SDRAM_TYPE	SDRAM_TYPE_DDR3 | #define CONFIG_FSL_SDRAM_TYPE	SDRAM_TYPE_DDR3 | ||||||
| #endif | #endif | ||||||
|  | #elif defined(CONFIG_SYS_FSL_DDR4) | ||||||
|  | #define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR	(3)	/* FIXME */ | ||||||
|  | typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t; | ||||||
|  | #ifndef CONFIG_FSL_SDRAM_TYPE | ||||||
|  | #define CONFIG_FSL_SDRAM_TYPE	SDRAM_TYPE_DDR4 | ||||||
|  | #endif | ||||||
| #endif	/* #if defined(CONFIG_SYS_FSL_DDR1) */ | #endif	/* #if defined(CONFIG_SYS_FSL_DDR1) */ | ||||||
| 
 | 
 | ||||||
| #define FSL_DDR_ODT_NEVER		0x0 | #define FSL_DDR_ODT_NEVER		0x0 | ||||||
|  | @ -116,7 +124,8 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; | ||||||
| 
 | 
 | ||||||
| #define TIMING_CFG_2_CPO_MASK	0x0F800000 | #define TIMING_CFG_2_CPO_MASK	0x0F800000 | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_P4080) | #if defined(CONFIG_SYS_FSL_DDR_VER) && \ | ||||||
|  | 	(CONFIG_SYS_FSL_DDR_VER > FSL_DDR_VER_4_4) | ||||||
| #define RD_TO_PRE_MASK		0xf | #define RD_TO_PRE_MASK		0xf | ||||||
| #define RD_TO_PRE_SHIFT		13 | #define RD_TO_PRE_SHIFT		13 | ||||||
| #define WR_DATA_DELAY_MASK	0xf | #define WR_DATA_DELAY_MASK	0xf | ||||||
|  | @ -154,9 +163,27 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; | ||||||
| #define DDR_CDR2_ODT_MASK	0x1 | #define DDR_CDR2_ODT_MASK	0x1 | ||||||
| #define DDR_CDR1_ODT(x) ((x & DDR_CDR1_ODT_MASK) << DDR_CDR1_ODT_SHIFT) | #define DDR_CDR1_ODT(x) ((x & DDR_CDR1_ODT_MASK) << DDR_CDR1_ODT_SHIFT) | ||||||
| #define DDR_CDR2_ODT(x) (x & DDR_CDR2_ODT_MASK) | #define DDR_CDR2_ODT(x) (x & DDR_CDR2_ODT_MASK) | ||||||
|  | #define DDR_CDR2_VREF_OVRD(x)	(0x00008080 | ((((x) - 37) & 0x3F) << 8)) | ||||||
| 
 | 
 | ||||||
| #if (defined(CONFIG_SYS_FSL_DDR_VER) && \ | #if (defined(CONFIG_SYS_FSL_DDR_VER) && \ | ||||||
| 	(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)) | 	(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)) | ||||||
|  | #ifdef CONFIG_SYS_FSL_DDR3L | ||||||
|  | #define DDR_CDR_ODT_OFF		0x0 | ||||||
|  | #define DDR_CDR_ODT_120ohm	0x1 | ||||||
|  | #define DDR_CDR_ODT_200ohm	0x2 | ||||||
|  | #define DDR_CDR_ODT_75ohm	0x3 | ||||||
|  | #define DDR_CDR_ODT_60ohm	0x5 | ||||||
|  | #define DDR_CDR_ODT_46ohm	0x7 | ||||||
|  | #elif defined(CONFIG_SYS_FSL_DDR4) | ||||||
|  | #define DDR_CDR_ODT_OFF		0x0 | ||||||
|  | #define DDR_CDR_ODT_100ohm	0x1 | ||||||
|  | #define DDR_CDR_ODT_120OHM	0x2 | ||||||
|  | #define DDR_CDR_ODT_80ohm	0x3 | ||||||
|  | #define DDR_CDR_ODT_60ohm	0x4 | ||||||
|  | #define DDR_CDR_ODT_40ohm	0x5 | ||||||
|  | #define DDR_CDR_ODT_50ohm	0x6 | ||||||
|  | #define DDR_CDR_ODT_30ohm	0x7 | ||||||
|  | #else | ||||||
| #define DDR_CDR_ODT_OFF		0x0 | #define DDR_CDR_ODT_OFF		0x0 | ||||||
| #define DDR_CDR_ODT_120ohm	0x1 | #define DDR_CDR_ODT_120ohm	0x1 | ||||||
| #define DDR_CDR_ODT_180ohm	0x2 | #define DDR_CDR_ODT_180ohm	0x2 | ||||||
|  | @ -165,6 +192,7 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; | ||||||
| #define DDR_CDR_ODT_60hm	0x5 | #define DDR_CDR_ODT_60hm	0x5 | ||||||
| #define DDR_CDR_ODT_70ohm	0x6 | #define DDR_CDR_ODT_70ohm	0x6 | ||||||
| #define DDR_CDR_ODT_47ohm	0x7 | #define DDR_CDR_ODT_47ohm	0x7 | ||||||
|  | #endif /* DDR3L */ | ||||||
| #else | #else | ||||||
| #define DDR_CDR_ODT_75ohm	0x0 | #define DDR_CDR_ODT_75ohm	0x0 | ||||||
| #define DDR_CDR_ODT_55ohm	0x1 | #define DDR_CDR_ODT_55ohm	0x1 | ||||||
|  | @ -188,6 +216,7 @@ typedef struct fsl_ddr_cfg_regs_s { | ||||||
| 	unsigned int timing_cfg_2; | 	unsigned int timing_cfg_2; | ||||||
| 	unsigned int ddr_sdram_cfg; | 	unsigned int ddr_sdram_cfg; | ||||||
| 	unsigned int ddr_sdram_cfg_2; | 	unsigned int ddr_sdram_cfg_2; | ||||||
|  | 	unsigned int ddr_sdram_cfg_3; | ||||||
| 	unsigned int ddr_sdram_mode; | 	unsigned int ddr_sdram_mode; | ||||||
| 	unsigned int ddr_sdram_mode_2; | 	unsigned int ddr_sdram_mode_2; | ||||||
| 	unsigned int ddr_sdram_mode_3; | 	unsigned int ddr_sdram_mode_3; | ||||||
|  | @ -196,6 +225,14 @@ typedef struct fsl_ddr_cfg_regs_s { | ||||||
| 	unsigned int ddr_sdram_mode_6; | 	unsigned int ddr_sdram_mode_6; | ||||||
| 	unsigned int ddr_sdram_mode_7; | 	unsigned int ddr_sdram_mode_7; | ||||||
| 	unsigned int ddr_sdram_mode_8; | 	unsigned int ddr_sdram_mode_8; | ||||||
|  | 	unsigned int ddr_sdram_mode_9; | ||||||
|  | 	unsigned int ddr_sdram_mode_10; | ||||||
|  | 	unsigned int ddr_sdram_mode_11; | ||||||
|  | 	unsigned int ddr_sdram_mode_12; | ||||||
|  | 	unsigned int ddr_sdram_mode_13; | ||||||
|  | 	unsigned int ddr_sdram_mode_14; | ||||||
|  | 	unsigned int ddr_sdram_mode_15; | ||||||
|  | 	unsigned int ddr_sdram_mode_16; | ||||||
| 	unsigned int ddr_sdram_md_cntl; | 	unsigned int ddr_sdram_md_cntl; | ||||||
| 	unsigned int ddr_sdram_interval; | 	unsigned int ddr_sdram_interval; | ||||||
| 	unsigned int ddr_data_init; | 	unsigned int ddr_data_init; | ||||||
|  | @ -204,6 +241,10 @@ typedef struct fsl_ddr_cfg_regs_s { | ||||||
| 	unsigned int ddr_init_ext_addr; | 	unsigned int ddr_init_ext_addr; | ||||||
| 	unsigned int timing_cfg_4; | 	unsigned int timing_cfg_4; | ||||||
| 	unsigned int timing_cfg_5; | 	unsigned int timing_cfg_5; | ||||||
|  | 	unsigned int timing_cfg_6; | ||||||
|  | 	unsigned int timing_cfg_7; | ||||||
|  | 	unsigned int timing_cfg_8; | ||||||
|  | 	unsigned int timing_cfg_9; | ||||||
| 	unsigned int ddr_zq_cntl; | 	unsigned int ddr_zq_cntl; | ||||||
| 	unsigned int ddr_wrlvl_cntl; | 	unsigned int ddr_wrlvl_cntl; | ||||||
| 	unsigned int ddr_wrlvl_cntl_2; | 	unsigned int ddr_wrlvl_cntl_2; | ||||||
|  | @ -211,6 +252,14 @@ typedef struct fsl_ddr_cfg_regs_s { | ||||||
| 	unsigned int ddr_sr_cntr; | 	unsigned int ddr_sr_cntr; | ||||||
| 	unsigned int ddr_sdram_rcw_1; | 	unsigned int ddr_sdram_rcw_1; | ||||||
| 	unsigned int ddr_sdram_rcw_2; | 	unsigned int ddr_sdram_rcw_2; | ||||||
|  | 	unsigned int ddr_sdram_rcw_3; | ||||||
|  | 	unsigned int ddr_sdram_rcw_4; | ||||||
|  | 	unsigned int ddr_sdram_rcw_5; | ||||||
|  | 	unsigned int ddr_sdram_rcw_6; | ||||||
|  | 	unsigned int dq_map_0; | ||||||
|  | 	unsigned int dq_map_1; | ||||||
|  | 	unsigned int dq_map_2; | ||||||
|  | 	unsigned int dq_map_3; | ||||||
| 	unsigned int ddr_eor; | 	unsigned int ddr_eor; | ||||||
| 	unsigned int ddr_cdr1; | 	unsigned int ddr_cdr1; | ||||||
| 	unsigned int ddr_cdr2; | 	unsigned int ddr_cdr2; | ||||||
|  | @ -225,7 +274,7 @@ typedef struct memctl_options_partial_s { | ||||||
| 	unsigned int all_dimms_burst_lengths_bitmask; | 	unsigned int all_dimms_burst_lengths_bitmask; | ||||||
| 	unsigned int all_dimms_registered; | 	unsigned int all_dimms_registered; | ||||||
| 	unsigned int all_dimms_unbuffered; | 	unsigned int all_dimms_unbuffered; | ||||||
| 	/*	unsigned int lowest_common_SPD_caslat; */ | 	/*	unsigned int lowest_common_spd_caslat; */ | ||||||
| 	unsigned int all_dimms_minimum_trcd_ps; | 	unsigned int all_dimms_minimum_trcd_ps; | ||||||
| } memctl_options_partial_t; | } memctl_options_partial_t; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,18 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2014 Freescale Semiconductor, Inc. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier:	GPL-2.0+ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __FSL_DDRC_VER_H | ||||||
|  | #define __FSL_DDRC_VER_H | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Only the versions with distinct features or registers are listed here. | ||||||
|  |  */ | ||||||
|  | #define FSL_DDR_VER_4_4 44 | ||||||
|  | #define FSL_DDR_VER_4_6 46 | ||||||
|  | #define FSL_DDR_VER_4_7	47 | ||||||
|  | #define FSL_DDR_VER_5_0	50 | ||||||
|  | 
 | ||||||
|  | #endif /* __FSL_DDRC_VER_H */ | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Common internal memory map for some Freescale SoCs |  * Common internal memory map for some Freescale SoCs | ||||||
|  * |  * | ||||||
|  * Copyright 2013 Freescale Semiconductor, Inc. |  * Copyright 2013-2014 Freescale Semiconductor, Inc. | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier:	GPL-2.0+ |  * SPDX-License-Identifier:	GPL-2.0+ | ||||||
|  */ |  */ | ||||||
|  | @ -50,7 +50,8 @@ struct ccsr_ddr { | ||||||
| 	u8	res_150[16]; | 	u8	res_150[16]; | ||||||
| 	u32	timing_cfg_4;		/* SDRAM Timing Configuration 4 */ | 	u32	timing_cfg_4;		/* SDRAM Timing Configuration 4 */ | ||||||
| 	u32	timing_cfg_5;		/* SDRAM Timing Configuration 5 */ | 	u32	timing_cfg_5;		/* SDRAM Timing Configuration 5 */ | ||||||
| 	u8	reg_168[8]; | 	u32	timing_cfg_6;		/* SDRAM Timing Configuration 6 */ | ||||||
|  | 	u32	timing_cfg_7;		/* SDRAM Timing Configuration 7 */ | ||||||
| 	u32	ddr_zq_cntl;		/* ZQ calibration control*/ | 	u32	ddr_zq_cntl;		/* ZQ calibration control*/ | ||||||
| 	u32	ddr_wrlvl_cntl;		/* write leveling control*/ | 	u32	ddr_wrlvl_cntl;		/* write leveling control*/ | ||||||
| 	u8	reg_178[4]; | 	u8	reg_178[4]; | ||||||
|  | @ -60,14 +61,40 @@ struct ccsr_ddr { | ||||||
| 	u8	reg_188[8]; | 	u8	reg_188[8]; | ||||||
| 	u32	ddr_wrlvl_cntl_2;	/* write leveling control 2 */ | 	u32	ddr_wrlvl_cntl_2;	/* write leveling control 2 */ | ||||||
| 	u32	ddr_wrlvl_cntl_3;	/* write leveling control 3 */ | 	u32	ddr_wrlvl_cntl_3;	/* write leveling control 3 */ | ||||||
| 	u8	res_198[104]; | 	u8	res_198[0x1a0-0x198]; | ||||||
|  | 	u32	ddr_sdram_rcw_3; | ||||||
|  | 	u32	ddr_sdram_rcw_4; | ||||||
|  | 	u32	ddr_sdram_rcw_5; | ||||||
|  | 	u32	ddr_sdram_rcw_6; | ||||||
|  | 	u8	res_1b0[0x200-0x1b0]; | ||||||
| 	u32	sdram_mode_3;		/* SDRAM Mode Configuration 3 */ | 	u32	sdram_mode_3;		/* SDRAM Mode Configuration 3 */ | ||||||
| 	u32	sdram_mode_4;		/* SDRAM Mode Configuration 4 */ | 	u32	sdram_mode_4;		/* SDRAM Mode Configuration 4 */ | ||||||
| 	u32	sdram_mode_5;		/* SDRAM Mode Configuration 5 */ | 	u32	sdram_mode_5;		/* SDRAM Mode Configuration 5 */ | ||||||
| 	u32	sdram_mode_6;		/* SDRAM Mode Configuration 6 */ | 	u32	sdram_mode_6;		/* SDRAM Mode Configuration 6 */ | ||||||
| 	u32	sdram_mode_7;		/* SDRAM Mode Configuration 7 */ | 	u32	sdram_mode_7;		/* SDRAM Mode Configuration 7 */ | ||||||
| 	u32	sdram_mode_8;		/* SDRAM Mode Configuration 8 */ | 	u32	sdram_mode_8;		/* SDRAM Mode Configuration 8 */ | ||||||
| 	u8	res_218[0x908]; | 	u8	res_218[0x220-0x218]; | ||||||
|  | 	u32	sdram_mode_9;		/* SDRAM Mode Configuration 9 */ | ||||||
|  | 	u32	sdram_mode_10;		/* SDRAM Mode Configuration 10 */ | ||||||
|  | 	u32	sdram_mode_11;		/* SDRAM Mode Configuration 11 */ | ||||||
|  | 	u32	sdram_mode_12;		/* SDRAM Mode Configuration 12 */ | ||||||
|  | 	u32	sdram_mode_13;		/* SDRAM Mode Configuration 13 */ | ||||||
|  | 	u32	sdram_mode_14;		/* SDRAM Mode Configuration 14 */ | ||||||
|  | 	u32	sdram_mode_15;		/* SDRAM Mode Configuration 15 */ | ||||||
|  | 	u32	sdram_mode_16;		/* SDRAM Mode Configuration 16 */ | ||||||
|  | 	u8	res_240[0x250-0x240]; | ||||||
|  | 	u32	timing_cfg_8;		/* SDRAM Timing Configuration 8 */ | ||||||
|  | 	u32	timing_cfg_9;		/* SDRAM Timing Configuration 9 */ | ||||||
|  | 	u8	res_258[0x260-0x258]; | ||||||
|  | 	u32	sdram_cfg_3; | ||||||
|  | 	u8	res_264[0x2a0-0x264]; | ||||||
|  | 	u32	deskew_cntl; | ||||||
|  | 	u8	res_2a4[0x400-0x2a4]; | ||||||
|  | 	u32	dq_map_0; | ||||||
|  | 	u32	dq_map_1; | ||||||
|  | 	u32	dq_map_2; | ||||||
|  | 	u32	dq_map_3; | ||||||
|  | 	u8	res_410[0xb20-0x410]; | ||||||
| 	u32	ddr_dsr1;		/* Debug Status 1 */ | 	u32	ddr_dsr1;		/* Debug Status 1 */ | ||||||
| 	u32	ddr_dsr2;		/* Debug Status 2 */ | 	u32	ddr_dsr2;		/* Debug Status 2 */ | ||||||
| 	u32	ddr_cdr1;		/* Control Driver 1 */ | 	u32	ddr_cdr1;		/* Control Driver 1 */ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue