xref: /openbmc/u-boot/arch/x86/include/asm/arch-quark/mrc.h (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini /* SPDX-License-Identifier: Intel */
20a391b1cSBin Meng /*
30a391b1cSBin Meng  * Copyright (C) 2013, Intel Corporation
40a391b1cSBin Meng  * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
50a391b1cSBin Meng  *
60a391b1cSBin Meng  * Ported from Intel released Quark UEFI BIOS
70a391b1cSBin Meng  * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei
80a391b1cSBin Meng  */
90a391b1cSBin Meng 
100a391b1cSBin Meng #ifndef _MRC_H_
110a391b1cSBin Meng #define _MRC_H_
120a391b1cSBin Meng 
130a391b1cSBin Meng #define MRC_VERSION	0x0111
140a391b1cSBin Meng 
150a391b1cSBin Meng /* architectural definitions */
160a391b1cSBin Meng #define NUM_CHANNELS	1	/* number of channels */
170a391b1cSBin Meng #define NUM_RANKS	2	/* number of ranks per channel */
180a391b1cSBin Meng #define NUM_BYTE_LANES	4	/* number of byte lanes per channel */
190a391b1cSBin Meng 
200a391b1cSBin Meng /* software limitations */
210a391b1cSBin Meng #define MAX_CHANNELS	1
220a391b1cSBin Meng #define MAX_RANKS	2
230a391b1cSBin Meng #define MAX_BYTE_LANES	4
240a391b1cSBin Meng 
250a391b1cSBin Meng #define MAX_SOCKETS	1
260a391b1cSBin Meng #define MAX_SIDES	1
270a391b1cSBin Meng #define MAX_ROWS	(MAX_SIDES * MAX_SOCKETS)
280a391b1cSBin Meng 
290a391b1cSBin Meng /* Specify DRAM and channel width */
300a391b1cSBin Meng enum {
310a391b1cSBin Meng 	X8,	/* DRAM width */
320a391b1cSBin Meng 	X16,	/* DRAM width & Channel Width */
330a391b1cSBin Meng 	X32	/* Channel Width */
340a391b1cSBin Meng };
350a391b1cSBin Meng 
360a391b1cSBin Meng /* Specify DRAM speed */
370a391b1cSBin Meng enum {
380a391b1cSBin Meng 	DDRFREQ_800,
390a391b1cSBin Meng 	DDRFREQ_1066
400a391b1cSBin Meng };
410a391b1cSBin Meng 
420a391b1cSBin Meng /* Specify DRAM type */
430a391b1cSBin Meng enum {
440a391b1cSBin Meng 	DDR3,
450a391b1cSBin Meng 	DDR3L
460a391b1cSBin Meng };
470a391b1cSBin Meng 
480a391b1cSBin Meng /*
490a391b1cSBin Meng  * density: 0=512Mb, 1=Gb, 2=2Gb, 3=4Gb
500a391b1cSBin Meng  * cl: DRAM CAS Latency in clocks
510a391b1cSBin Meng  * ras: ACT to PRE command period
520a391b1cSBin Meng  * wtr: Delay from start of internal write transaction to internal read command
530a391b1cSBin Meng  * rrd: ACT to ACT command period (JESD79 specific to page size 1K/2K)
540a391b1cSBin Meng  * faw: Four activate window (JESD79 specific to page size 1K/2K)
550a391b1cSBin Meng  *
560a391b1cSBin Meng  * ras/wtr/rrd/faw timings are in picoseconds
570a391b1cSBin Meng  *
580a391b1cSBin Meng  * Refer to JEDEC spec (or DRAM datasheet) when changing these values.
590a391b1cSBin Meng  */
600a391b1cSBin Meng struct dram_params {
610a391b1cSBin Meng 	uint8_t density;
620a391b1cSBin Meng 	uint8_t cl;
630a391b1cSBin Meng 	uint32_t ras;
640a391b1cSBin Meng 	uint32_t wtr;
650a391b1cSBin Meng 	uint32_t rrd;
660a391b1cSBin Meng 	uint32_t faw;
670a391b1cSBin Meng };
680a391b1cSBin Meng 
690a391b1cSBin Meng /*
700a391b1cSBin Meng  * Delay configuration for individual signals
710a391b1cSBin Meng  * Vref setting
720a391b1cSBin Meng  * Scrambler seed
730a391b1cSBin Meng  */
740a391b1cSBin Meng struct mrc_timings {
750a391b1cSBin Meng 	uint32_t rcvn[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
760a391b1cSBin Meng 	uint32_t rdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
770a391b1cSBin Meng 	uint32_t wdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
780a391b1cSBin Meng 	uint32_t wdq[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
790a391b1cSBin Meng 	uint32_t vref[NUM_CHANNELS][NUM_BYTE_LANES];
800a391b1cSBin Meng 	uint32_t wctl[NUM_CHANNELS][NUM_RANKS];
810a391b1cSBin Meng 	uint32_t wcmd[NUM_CHANNELS];
820a391b1cSBin Meng 	uint32_t scrambler_seed;
830a391b1cSBin Meng 	/* need to save for the case of frequency change */
840a391b1cSBin Meng 	uint8_t ddr_speed;
850a391b1cSBin Meng };
860a391b1cSBin Meng 
870a391b1cSBin Meng /* Boot mode defined as bit mask (1<<n) */
880a391b1cSBin Meng enum {
890a391b1cSBin Meng 	BM_UNKNOWN,
900a391b1cSBin Meng 	BM_COLD = 1,	/* full training */
910a391b1cSBin Meng 	BM_FAST = 2,	/* restore timing parameters */
920a391b1cSBin Meng 	BM_S3   = 4,	/* resume from S3 */
930a391b1cSBin Meng 	BM_WARM = 8
940a391b1cSBin Meng };
950a391b1cSBin Meng 
960a391b1cSBin Meng /* MRC execution status */
970a391b1cSBin Meng #define MRC_SUCCESS	0	/* initialization ok */
980a391b1cSBin Meng #define MRC_E_MEMTEST	1	/* memtest failed */
990a391b1cSBin Meng 
1000a391b1cSBin Meng /*
1010a391b1cSBin Meng  * Memory Reference Code parameters
1020a391b1cSBin Meng  *
1030a391b1cSBin Meng  * It includes 3 parts:
1040a391b1cSBin Meng  * - input parameters like boot mode and DRAM parameters
1050a391b1cSBin Meng  * - context parameters for MRC internal state
1060a391b1cSBin Meng  * - output parameters like initialization result and memory size
1070a391b1cSBin Meng  */
1080a391b1cSBin Meng struct mrc_params {
1090a391b1cSBin Meng 	/* Input parameters */
1100a391b1cSBin Meng 	uint32_t boot_mode;		/* BM_COLD, BM_FAST, BM_WARM, BM_S3 */
1110a391b1cSBin Meng 	/* DRAM parameters */
1120a391b1cSBin Meng 	uint8_t dram_width;		/* x8, x16 */
1130a391b1cSBin Meng 	uint8_t ddr_speed;		/* DDRFREQ_800, DDRFREQ_1066 */
1140a391b1cSBin Meng 	uint8_t ddr_type;		/* DDR3, DDR3L */
1150a391b1cSBin Meng 	uint8_t ecc_enables;		/* 0, 1 (memory size reduced to 7/8) */
1160a391b1cSBin Meng 	uint8_t scrambling_enables;	/* 0, 1 */
1170a391b1cSBin Meng 	/* 1, 3 (1'st rank has to be populated if 2'nd rank present) */
1180a391b1cSBin Meng 	uint32_t rank_enables;
1190a391b1cSBin Meng 	uint32_t channel_enables;	/* 1 only */
1200a391b1cSBin Meng 	uint32_t channel_width;		/* x16 only */
1210a391b1cSBin Meng 	/* 0, 1, 2 (mode 2 forced if ecc enabled) */
1220a391b1cSBin Meng 	uint32_t address_mode;
1230a391b1cSBin Meng 	/* REFRESH_RATE: 1=1.95us, 2=3.9us, 3=7.8us, others=RESERVED */
1240a391b1cSBin Meng 	uint8_t refresh_rate;
1250a391b1cSBin Meng 	/* SR_TEMP_RANGE: 0=normal, 1=extended, others=RESERVED */
1260a391b1cSBin Meng 	uint8_t sr_temp_range;
1270a391b1cSBin Meng 	/*
1280a391b1cSBin Meng 	 * RON_VALUE: 0=34ohm, 1=40ohm, others=RESERVED
1290a391b1cSBin Meng 	 * (select MRS1.DIC driver impedance control)
1300a391b1cSBin Meng 	 */
1310a391b1cSBin Meng 	uint8_t ron_value;
1320a391b1cSBin Meng 	/* RTT_NOM_VALUE: 0=40ohm, 1=60ohm, 2=120ohm, others=RESERVED */
1330a391b1cSBin Meng 	uint8_t rtt_nom_value;
1340a391b1cSBin Meng 	/* RD_ODT_VALUE: 0=off, 1=60ohm, 2=120ohm, 3=180ohm, others=RESERVED */
1350a391b1cSBin Meng 	uint8_t rd_odt_value;
1360a391b1cSBin Meng 	struct dram_params params;
1370a391b1cSBin Meng 	/* Internally used context parameters */
1380a391b1cSBin Meng 	uint32_t board_id;	/* board layout (use x8 or x16 memory) */
1390a391b1cSBin Meng 	uint32_t hte_setup;	/* when set hte reconfiguration requested */
1400a391b1cSBin Meng 	uint32_t menu_after_mrc;
1410a391b1cSBin Meng 	uint32_t power_down_disable;
1420a391b1cSBin Meng 	uint32_t tune_rcvn;
1430a391b1cSBin Meng 	uint32_t channel_size[NUM_CHANNELS];
1440a391b1cSBin Meng 	uint32_t column_bits[NUM_CHANNELS];
1450a391b1cSBin Meng 	uint32_t row_bits[NUM_CHANNELS];
1460a391b1cSBin Meng 	uint32_t mrs1;		/* register content saved during training */
1470a391b1cSBin Meng 	uint8_t first_run;
1480a391b1cSBin Meng 	/* Output parameters */
1490a391b1cSBin Meng 	/* initialization result (non zero specifies error code) */
1500a391b1cSBin Meng 	uint32_t status;
1510a391b1cSBin Meng 	/* total memory size in bytes (excludes ECC banks) */
1520a391b1cSBin Meng 	uint32_t mem_size;
1530a391b1cSBin Meng 	/* training results (also used on input) */
1540a391b1cSBin Meng 	struct mrc_timings timings;
1550a391b1cSBin Meng };
1560a391b1cSBin Meng 
1570a391b1cSBin Meng /*
1580a391b1cSBin Meng  * MRC memory initialization structure
1590a391b1cSBin Meng  *
1600a391b1cSBin Meng  * post_code: a 16-bit post code of a specific initialization routine
1610a391b1cSBin Meng  * boot_path: bitwise or of BM_COLD, BM_FAST, BM_WARM and BM_S3
1620a391b1cSBin Meng  * init_fn: real memory initialization routine
1630a391b1cSBin Meng  */
1640a391b1cSBin Meng struct mem_init {
1650a391b1cSBin Meng 	uint16_t post_code;
1660a391b1cSBin Meng 	uint16_t boot_path;
1670a391b1cSBin Meng 	void (*init_fn)(struct mrc_params *mrc_params);
1680a391b1cSBin Meng };
1690a391b1cSBin Meng 
1700a391b1cSBin Meng /* MRC platform data flags */
1710a391b1cSBin Meng #define MRC_FLAG_ECC_EN		0x00000001
1720a391b1cSBin Meng #define MRC_FLAG_SCRAMBLE_EN	0x00000002
1730a391b1cSBin Meng #define MRC_FLAG_MEMTEST_EN	0x00000004
1740a391b1cSBin Meng /* 0b DDR "fly-by" topology else 1b DDR "tree" topology */
1750a391b1cSBin Meng #define MRC_FLAG_TOP_TREE_EN	0x00000008
1760a391b1cSBin Meng /* If set ODR signal is asserted to DRAM devices on writes */
1770a391b1cSBin Meng #define MRC_FLAG_WR_ODT_EN	0x00000010
1780a391b1cSBin Meng 
1790a391b1cSBin Meng /**
1800a391b1cSBin Meng  * mrc_init - Memory Reference Code initialization entry routine
1810a391b1cSBin Meng  *
1820a391b1cSBin Meng  * @mrc_params: parameters for MRC
1830a391b1cSBin Meng  */
1840a391b1cSBin Meng void mrc_init(struct mrc_params *mrc_params);
1850a391b1cSBin Meng 
1860a391b1cSBin Meng #endif /* _MRC_H_ */
187