aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h
blob: f757fd89687d5d0b560b2c39544a50ba57d5505e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * This file is part of the coreboot project.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef _SOC_CANNONLAKE_MEMCFG_INIT_H_
#define _SOC_CANNONLAKE_MEMCFG_INIT_H_

#include <stddef.h>
#include <stdint.h>
#include <fsp/soc_binding.h>

/* Number of dq bits controlled per dqs */
#define DQ_BITS_PER_DQS 8

/* Number of memory DIMM slots available on Cannonlake board */
#define NUM_DIMM_SLOT 4

/*
 * Number of memory packages, where a "package" represents a 64-bit solution.
 */
#define DDR_NUM_PACKAGES 2

/* 64-bit Channel identification */
enum {
	DDR_CH0,
	DDR_CH1,
	DDR_NUM_CHANNELS
};

struct spd_by_pointer {
	size_t spd_data_len;
	uintptr_t spd_data_ptr;
};

enum mem_info_read_type {
	NOT_EXISTING,	/* No memory in this slot */
	READ_SMBUS,	/* Read on-module spd by SMBUS. */
	READ_SPD_CBFS,	/* Find spd file in CBFS. */
	READ_SPD_MEMPTR /* Find spd data from pointer. */
};

struct spd_info {
	enum mem_info_read_type read_type;
	union spd_data_by {
		/* To read on-module spd when read_type is READ_SMBUS. */
		uint8_t spd_smbus_address;

		/* To identify spd file when read_type is READ_SPD_CBFS. */
		int spd_index;

		/* To find spd data when read_type is READ_SPD_MEMPTR. */
		struct spd_by_pointer spd_data_ptr_info;
	} spd_spec;
};

/* Board-specific memory dq mapping information */
struct cnl_mb_cfg {
	/* Parameters required to access SPD for CH0D0/CH0D1/CH1D0/CH1D1. */
	struct spd_info spd[NUM_DIMM_SLOT];

	/*
	 * For each channel, there are 6 sets of DQ byte mappings,
	 * where each set has a package 0 and a package 1 value (package 0
	 * represents the first 64-bit lpddr4 chip combination, and package 1
	 * represents the second 64-bit lpddr4 chip combination).
	 * The first three sets are for CLK, CMD, and CTL.
	 * The fsp package actually expects 6 sets, even though the last 3 sets
	 * are not used in CNL.
	 * We let the meminit_lpddr4() routine take care of clearing the
	 * unused fields for the caller.
	 * Note that dq_map is only used by LPDDR; it does not need to be
	 * initialized for designs using DDR4.
	 */
	uint8_t dq_map[DDR_NUM_CHANNELS][6][DDR_NUM_PACKAGES];

	/*
	 * DQS CPU<>DRAM map Ch0 and Ch1.  Each array entry represents a
	 * mapping of a dq bit on the CPU to the bit it's connected to on
	 * the memory part.  The array index represents the dqs bit number
	 * on the memory part, and the values in the array represent which
	 * pin on the CPU that DRAM pin connects to.
	 * dqs_map is only used by LPDDR; same comments apply as for dq_map
	 * above.
	 */
	uint8_t dqs_map[DDR_NUM_CHANNELS][DQ_BITS_PER_DQS];

	/*
	 * Rcomp resistor values.  These values represent the resistance in
	 * ohms of the three rcomp resistors attached to the DDR_COMP_0,
	 * DDR_COMP_1, and DDR_COMP_2 pins on the DRAM.
	 */
	uint16_t rcomp_resistor[3];

	/*
	 * Rcomp target values.  These will typically be the following
	 * values for Cannon Lake : { 80, 40, 40, 40, 30 }
	 */
	uint16_t rcomp_targets[5];

	/*
	 * Indicates whether memory is interleaved.
	 * Set to 1 for an interleaved design,
	 * set to 0 for non-interleaved design.
	 */
	uint8_t dq_pins_interleaved;

	/*
	 * VREF_CA configuration.
	 * Set to 0 VREF_CA goes to both CH_A and CH_B,
	 * set to 1 VREF_CA goes to CH_A and VREF_DQ_A goes to CH_B,
	 * set to 2 VREF_CA goes to CH_A and VREF_DQ_B goes to CH_B.
	 */
	uint8_t vref_ca_config;

	/* Early Command Training Enabled */
	uint8_t ect;
};

/*
 * Initialize default memory configurations for CannonLake.
 */
void cannonlake_memcfg_init(FSP_M_CONFIG *mem_cfg,
			    const struct cnl_mb_cfg *cnl_cfg);

#endif /* _SOC_CANNONLAKE_MEMCFG_INIT_H_ */