aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/include/mach/emif.h
blob: 8a3ea34c6c6aa5e0431726ce9f85b43ee71e4178 (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/*
 * OMAP44xx EMIF header
 *
 * Copyright (C) 2009-2010 Texas Instruments, Inc.
 *
 * Aneesh V <aneesh@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef _EMIF_H
#define _EMIF_H

#include <mach/emif-44xx.h>
#include <mach/lpddr2-jedec.h>

#define EMIF_NUM_INSTANCES 2
#define EMIF1	0
#define EMIF2	1

/* The maximum frequency at which the LPDDR2 interface can operate in Hz*/
#define MAX_LPDDR2_FREQ	400000000	/* 400 MHz */

/* 19.2 MHz to be used for finding initialization values */
#define EMIF_FREQ_19_2_MHZ 19200000	/* 19.2 MHz */
/*
 * The period of DDR clk is represented as numerator and denominator for
 * better accuracy in integer based calculations. However, if the numerator
 * and denominator are very huge there may be chances of overflow in
 * calculations. So, as a trade-off keep denominator(and consequently
 * numerator) within a limit sacrificing some accuracy - but not much
 * If denominator and numerator are already small (such as at 400 MHz)
 * no adjustment is needed
 */
#define EMIF_PERIOD_DEN_LIMIT	1000
/*
 * Maximum number of different frequencies supported by EMIF driver
 * Determines the number of entries in the pointer array for register
 * cache
 */
#define EMIF_MAX_NUM_FREQUENCIES	6
/*
 * Indices into the Addressing Table array.
 * One entry each for all the different types of devices with different
 * addressing schemes
 */
#define ADDR_TABLE_INDEX64M	0
#define ADDR_TABLE_INDEX128M	1
#define ADDR_TABLE_INDEX256M	2
#define ADDR_TABLE_INDEX512M	3
#define ADDR_TABLE_INDEX1GS4	4
#define ADDR_TABLE_INDEX2GS4	5
#define ADDR_TABLE_INDEX4G	6
#define ADDR_TABLE_INDEX8G	7
#define ADDR_TABLE_INDEX1GS2	8
#define ADDR_TABLE_INDEX2GS2	9
#define ADDR_TABLE_INDEXMAX	10

/* Number of Row bits */
#define ROW_9  0
#define ROW_10 1
#define ROW_11 2
#define ROW_12 3
#define ROW_13 4
#define ROW_14 5
#define ROW_15 6
#define ROW_16 7

/* Number of Column bits */
#define COL_8   0
#define COL_9   1
#define COL_10  2
#define COL_11  3
#define COL_7   4 /*Not supported by OMAP included for completeness */

/* Number of Banks*/
#define BANKS1 0
#define BANKS2 1
#define BANKS4 2
#define BANKS8 3

/* Refresh rate in micro seconds x 10 */
#define T_REFI_15_6	156
#define T_REFI_7_8	78
#define T_REFI_3_9	39

#define EBANK_CS1_DIS	0
#define EBANK_CS1_EN	1

/* Read Latency at the base frequency - 19.2 MHz on bootup */
#define RL_19_2_MHZ	3
/* Interleaving policies at EMIF level- between banks and Chip Selects */
#define EMIF_INTERLEAVING_POLICY_MAX_INTERLEAVING	0
#define EMIF_INTERLEAVING_POLICY_NO_BANK_INTERLEAVING	3

/*
 * Interleaving policy to be used
 * Currently set to MAX interleaving for better performance
 */
#define EMIF_INTERLEAVING_POLICY EMIF_INTERLEAVING_POLICY_MAX_INTERLEAVING

/* State of the core voltage:
 * This is important for some parameters such as read idle control and
 * ZQ calibration timings. Timings are much stricter when voltage ramp
 * is happening compared to when the voltage is stable.
 * We need to calculate two sets of values for these parameters and use
 * them accordingly
 */
#define LPDDR2_VOLTAGE_STABLE	0
#define LPDDR2_VOLTAGE_RAMPING	1

/* Length of the forced read idle period in terms of cycles */
#define EMIF_REG_READ_IDLE_LEN_VAL	5

/* Interval between forced 'read idles' */
/* To be used when voltage is changed for DPS/DVFS - 1us */
#define READ_IDLE_INTERVAL_DVFS		(1*1000)
/*
 * To be used when voltage is not scaled except by Smart Reflex
 * 50us - or maximum value will do
 */
#define READ_IDLE_INTERVAL_NORMAL	(50*1000)


/*
 * Unless voltage is changing due to DVFS one ZQCS command every 50ms should
 * be enough. This shoule be enough also in the case when voltage is changing
 * due to smart-reflex.
 */
#define EMIF_ZQCS_INTERVAL_NORMAL_IN_US	(50*1000)
/*
 * If voltage is changing due to DVFS ZQCS should be performed more
 * often(every 50us)
 */
#define EMIF_ZQCS_INTERVAL_DVFS_IN_US	50

/* The interval between ZQCL commands as a multiple of ZQCS interval */
#define REG_ZQ_ZQCL_MULT		4
/* The interval between ZQINIT commands as a multiple of ZQCL interval */
#define REG_ZQ_ZQINIT_MULT		3
/* Enable ZQ Calibration on exiting Self-refresh */
#define REG_ZQ_SFEXITEN_ENABLE		1
/*
 * ZQ Calibration simultaneously on both chip-selects:
 * Needs one calibration resistor per CS
 * None of the boards that we know of have this capability
 * So disabled by default
 */
#define REG_ZQ_DUALCALEN_DISABLE	0
/*
 * Enable ZQ Calibration by default on CS0. If we are asked to program
 * the EMIF there will be something connected to CS0 for sure
 */
#define REG_ZQ_CS0EN_ENABLE		1

/* EMIF_PWR_MGMT_CTRL register */
/* Low power modes */
#define LP_MODE_DISABLE		0
#define LP_MODE_CLOCK_STOP	1
#define LP_MODE_SELF_REFRESH	2
#define LP_MODE_PWR_DN		3

/* REG_DPD_EN */
#define DPD_DISABLE	0
#define DPD_ENABLE	1

/*
 * Value of bits 12:31 of DDR_PHY_CTRL_1 register:
 * All these fields have magic values dependent on frequency and
 * determined by PHY and DLL integration with EMIF. Setting the magic
 * values suggested by hw team.
 */
#define EMIF_DDR_PHY_CTRL_1_BASE_VAL			0x049FF
#define EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ			0x41
#define EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ			0x80
#define EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS	0xFF

/*
* MR1 value:
* Burst length	: 8
* Burst type	: sequential
* Wrap		: enabled
* nWR		: 3(default). EMIF does not do pre-charge.
*		: So nWR is don't care
*/
#define MR1_VAL	0x23

/* MR10: ZQ calibration codes */
#define MR10_ZQ_ZQCS		0x56
#define MR10_ZQ_ZQCL		0xAB
#define MR10_ZQ_ZQINIT		0xFF
#define MR10_ZQ_ZQRESET		0xC3

/* TEMP_ALERT_CONFIG */
#define TEMP_ALERT_POLL_INTERVAL_MS	360 /* for temp gradient - 5 C/s */
#define TEMP_ALERT_CONFIG_DEVCT_1	0
#define TEMP_ALERT_CONFIG_DEVWDT_32	2

/* MR16 value: refresh full array(no partial array self refresh) */
#define MR16_VAL	0

#if defined(DEBUG)
#define emif_assert(c)	BUG_ON(!(c))
#else
#define emif_assert(c)	({ if (0) BUG_ON(!(c)); 0; })
#endif

/* Details of the devices connected to each chip-select of an EMIF instance */
struct emif_device_details {
	const struct lpddr2_device_info *cs0_device;
	const struct lpddr2_device_info *cs1_device;
};

/*
 * LPDDR2 interface clock frequency:
 * Period (represented as numerator and denominator for better accuracy in
 * calculations) should be <= the real value. Period is used for calculating
 * all timings except refresh rate.
 * freq_mhz_floor - freq in mhz truncated to the lower integer is used for
 * calculating refresh rate
 * freq_mhz_ceil - frequency in mhz rounded up is used for identifying the
 * right speed bin and the corresponding timings table for the LPDDR2 device
 */
struct freq_info {
	u16 period_num;
	u16 period_den;
	u16 freq_mhz_floor;
	u16 freq_mhz_ceil;
};

/*
 * Structure containing shadow of important registers in EMIF
 * The calculation function fills in this structure to be later used for
 * initialization and DVFS
 */
struct emif_regs {
	u32 freq;
	u8 RL_final;
	u32 sdram_config_init;
	u32 sdram_config_final;
	u32 ref_ctrl;
	u32 ref_ctrl_derated;
	u32 sdram_tim1;
	u32 sdram_tim1_derated;
	u32 sdram_tim2;
	u32 sdram_tim3;
	u32 read_idle_ctrl_normal;
	u32 read_idle_ctrl_volt_ramp;
	u32 zq_config_normal;
	u32 zq_config_volt_ramp;
	u32 temp_alert_config;
	u32 temp_alert_config_derated;
	u32 emif_ddr_phy_ctlr_1_init;
	u32 emif_ddr_phy_ctlr_1_final;
};

int omap_emif_setup_registers(u32 freq,
			      u32 volt_state);
void omap_emif_frequency_pre_notify(void);
void omap_emif_frequency_post_notify(void);
int omap_emif_setup_device_details(
			const struct emif_device_details *emif1_devices,
			const struct emif_device_details *emif2_devices);

void emif_clear_irq(int emif_id);
#endif