summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
blob: 1c4d313eb4862945da870001fc99a7a011a7ddbe (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
/*
 * Header file for the Atmel DDR/SDR SDRAM Controller
 *
 * Copyright (C) 2010 Atmel Corporation
 *	Nicolas Ferre <nicolas.ferre@atmel.com>
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 */
#ifndef AT91SAM9_DDRSDR_H
#define AT91SAM9_DDRSDR_H

#define AT91_DDRSDRC_MR		0x00	/* Mode Register */
#define		AT91_DDRSDRC_MODE	(0x7 << 0)		/* Command Mode */
#define			AT91_DDRSDRC_MODE_NORMAL	0
#define			AT91_DDRSDRC_MODE_NOP		1
#define			AT91_DDRSDRC_MODE_PRECHARGE	2
#define			AT91_DDRSDRC_MODE_LMR		3
#define			AT91_DDRSDRC_MODE_REFRESH	4
#define			AT91_DDRSDRC_MODE_EXT_LMR	5
#define			AT91_DDRSDRC_MODE_DEEP		6

#define AT91_DDRSDRC_RTR	0x04	/* Refresh Timer Register */
#define		AT91_DDRSDRC_COUNT	(0xfff << 0)		/* Refresh Timer Counter */

#define AT91_DDRSDRC_CR		0x08	/* Configuration Register */
#define		AT91_DDRSDRC_NC		(3 << 0)		/* Number of Column Bits */
#define			AT91_DDRSDRC_NC_SDR8	(0 << 0)
#define			AT91_DDRSDRC_NC_SDR9	(1 << 0)
#define			AT91_DDRSDRC_NC_SDR10	(2 << 0)
#define			AT91_DDRSDRC_NC_SDR11	(3 << 0)
#define			AT91_DDRSDRC_NC_DDR9	(0 << 0)
#define			AT91_DDRSDRC_NC_DDR10	(1 << 0)
#define			AT91_DDRSDRC_NC_DDR11	(2 << 0)
#define			AT91_DDRSDRC_NC_DDR12	(3 << 0)
#define		AT91_DDRSDRC_NR		(3 << 2)		/* Number of Row Bits */
#define			AT91_DDRSDRC_NR_11	(0 << 2)
#define			AT91_DDRSDRC_NR_12	(1 << 2)
#define			AT91_DDRSDRC_NR_13	(2 << 2)
#define			AT91_DDRSDRC_NR_14	(3 << 2)
#define		AT91_DDRSDRC_CAS	(7 << 4)		/* CAS Latency */
#define			AT91_DDRSDRC_CAS_2	(2 << 4)
#define			AT91_DDRSDRC_CAS_3	(3 << 4)
#define			AT91_DDRSDRC_CAS_25	(6 << 4)
#define		AT91_DDRSDRC_RST_DLL	(1 << 7)		/* Reset DLL */
#define		AT91_DDRSDRC_DICDS	(1 << 8)		/* Output impedance control */
#define		AT91_DDRSDRC_DIS_DLL	(1 << 9)		/* Disable DLL [SAM9 Only] */
#define		AT91_DDRSDRC_OCD	(1 << 12)		/* Off-Chip Driver [SAM9 Only] */
#define		AT91_DDRSDRC_DQMS	(1 << 16)		/* Mask Data is Shared [SAM9 Only] */
#define		AT91_DDRSDRC_ACTBST	(1 << 18)		/* Active Bank X to Burst Stop Read Access Bank Y [SAM9 Only] */
#define		AT91_DDRSDRC_NB		(1 << 20)		/* Number of
Banks [not SAM9G45] */
#define			AT91_SDRAMC_NB_4	(0 << 20)
#define			AT91_SDRAMC_NB_8	(1 << 20)

#define AT91_DDRSDRC_T0PR	0x0C	/* Timing 0 Register */
#define		AT91_DDRSDRC_TRAS	(0xf <<  0)		/* Active to Precharge delay */
#define		AT91_DDRSDRC_TRCD	(0xf <<  4)		/* Row to Column delay */
#define		AT91_DDRSDRC_TWR	(0xf <<  8)		/* Write recovery delay */
#define		AT91_DDRSDRC_TRC	(0xf << 12)		/* Row cycle delay */
#define		AT91_DDRSDRC_TRP	(0xf << 16)		/* Row precharge delay */
#define		AT91_DDRSDRC_TRRD	(0xf << 20)		/* Active BankA to BankB */
#define		AT91_DDRSDRC_TWTR	(0x7 << 24)		/* Internal Write to Read delay */
#define		AT91CAP9_DDRSDRC_TWTR	(1   << 24)		/* Internal Write to Read delay */
#define		AT91_DDRSDRC_RED_WRRD	(0x1 << 27)		/* Reduce Write to Read Delay [SAM9 Only] */
#define		AT91_DDRSDRC_TMRD	(0xf << 28)		/* Load mode to active/refresh delay */

#define AT91_DDRSDRC_T1PR	0x10	/* Timing 1 Register */
#define		AT91_DDRSDRC_TRFC	(0x1f << 0)		/* Row Cycle Delay */
#define		AT91_DDRSDRC_TXSNR	(0xff << 8)		/* Exit self-refresh to non-read */
#define		AT91_DDRSDRC_TXSRD	(0xff << 16)		/* Exit self-refresh to read */
#define		AT91_DDRSDRC_TXP	(0xf  << 24)		/* Exit power-down delay */

#define AT91_DDRSDRC_T2PR	0x14	/* Timing 2 Register [SAM9 Only] */
#define		AT91_DDRSDRC_TXARD	(0xf  << 0)		/* Exit active power down delay to read command in mode "Fast Exit" */
#define		AT91_DDRSDRC_TXARDS	(0xf  << 4)		/* Exit active power down delay to read command in mode "Slow Exit" */
#define		AT91_DDRSDRC_TRPA	(0xf  << 8)		/* Row Precharge All delay */
#define		AT91_DDRSDRC_TRTP	(0x7  << 12)		/* Read to Precharge delay */

#define AT91_DDRSDRC_LPR	0x1C	/* Low Power Register */
#define AT91CAP9_DDRSDRC_LPR	0x18	/* Low Power Register */
#define		AT91_DDRSDRC_LPCB	(3 << 0)		/* Low-power Configurations */
#define			AT91_DDRSDRC_LPCB_DISABLE		0
#define			AT91_DDRSDRC_LPCB_SELF_REFRESH		1
#define			AT91_DDRSDRC_LPCB_POWER_DOWN		2
#define			AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN	3
#define		AT91_DDRSDRC_CLKFR	(1 << 2)	/* Clock Frozen */
#define		AT91_DDRSDRC_PASR	(7 << 4)	/* Partial Array Self Refresh */
#define		AT91_DDRSDRC_TCSR	(3 << 8)	/* Temperature Compensated Self Refresh */
#define		AT91_DDRSDRC_DS		(3 << 10)	/* Drive Strength */
#define		AT91_DDRSDRC_TIMEOUT	(3 << 12)	/* Time to define when Low Power Mode is enabled */
#define			AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES	(0 << 12)
#define			AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES	(1 << 12)
#define			AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES	(2 << 12)
#define		AT91_DDRSDRC_APDE	(1 << 16)	 /* Active power down exit time */
#define		AT91_DDRSDRC_UPD_MR	(3 << 20)	 /* Update load mode register and extended mode register */

#define AT91_DDRSDRC_MDR	0x20	/* Memory Device Register */
#define AT91CAP9_DDRSDRC_MDR	0x1C	/* Memory Device Register */
#define		AT91_DDRSDRC_MD		(3 << 0)		/* Memory Device Type */
#define			AT91_DDRSDRC_MD_SDR		0
#define			AT91_DDRSDRC_MD_LOW_POWER_SDR	1
#define			AT91CAP9_DDRSDRC_MD_DDR		2
#define			AT91_DDRSDRC_MD_LOW_POWER_DDR	3
#define			AT91_DDRSDRC_MD_DDR2		6	/* [SAM9 Only] */
#define		AT91_DDRSDRC_DBW	(1 << 4)		/* Data Bus Width */
#define			AT91_DDRSDRC_DBW_32BITS		(0 <<  4)
#define			AT91_DDRSDRC_DBW_16BITS		(1 <<  4)

#define AT91_DDRSDRC_DLL	0x24	/* DLL Information Register */
#define AT91CAP9_DDRSDRC_DLL	0x20	/* DLL Information Register */
#define		AT91_DDRSDRC_MDINC	(1 << 0)		/* Master Delay increment */
#define		AT91_DDRSDRC_MDDEC	(1 << 1)		/* Master Delay decrement */
#define		AT91_DDRSDRC_MDOVF	(1 << 2)		/* Master Delay Overflow */
#define		AT91CAP9_DDRSDRC_SDCOVF	(1 << 3)		/* Slave Delay Correction Overflow */
#define		AT91CAP9_DDRSDRC_SDCUDF	(1 << 4)		/* Slave Delay Correction Underflow */
#define		AT91CAP9_DDRSDRC_SDERF	(1 << 5)		/* Slave Delay Correction error */
#define		AT91_DDRSDRC_MDVAL	(0xff <<  8)		/* Master Delay value */
#define		AT91CAP9_DDRSDRC_SDVAL	(0xff << 16)		/* Slave Delay value */
#define		AT91CAP9_DDRSDRC_SDCVAL	(0xff << 24)		/* Slave Delay Correction value */

#define AT91_DDRSDRC_HS		0x2C	/* High Speed Register [SAM9 Only] */
#define		AT91_DDRSDRC_DIS_ATCP_RD	(1 << 2)	/* Anticip read access is disabled */

#define AT91_DDRSDRC_DELAY(n)	(0x30 + (0x4 * (n)))	/* Delay I/O Register n */

#define AT91_DDRSDRC_WPMR	0xE4	/* Write Protect Mode Register [SAM9 Only] */
#define		AT91_DDRSDRC_WP		(1 << 0)		/* Write protect enable */
#define		AT91_DDRSDRC_WPKEY	(0xffffff << 8)		/* Write protect key */
#define		AT91_DDRSDRC_KEY	(0x444452 << 8)		/* Write protect key = "DDR" */

#define AT91_DDRSDRC_WPSR	0xE8	/* Write Protect Status Register [SAM9 Only] */
#define		AT91_DDRSDRC_WPVS	(1 << 0)		/* Write protect violation status */
#define		AT91_DDRSDRC_WPVSRC	(0xffff << 8)		/* Write protect violation source */

#ifndef __ASSEMBLY__
#include <io.h>

static inline u32 at91_get_ddram_size(void * __iomem base, bool is_nb)
{
	u32 cr;
	u32 mdr;
	u32 size;
	bool is_sdram;

	cr = __raw_readl(base + AT91_DDRSDRC_CR);
	mdr = __raw_readl(base + AT91_DDRSDRC_MDR);

	is_sdram = (mdr & AT91_DDRSDRC_MD) <= AT91_DDRSDRC_MD_LOW_POWER_SDR;

	/* Formula:
	 * size = bank << (col + row + 1);
	 * if (bandwidth == 32 bits)
	 *	size <<= 1;
	 */
	size = 1;
	/* COL */
	size += (cr & AT91_DDRSDRC_NC) + 8;
	if (!is_sdram)
		size ++;
	/* ROW */
	size += ((cr & AT91_DDRSDRC_NR) >> 2) + 11;
	/* BANK */
	if (is_nb)
		size = ((cr & AT91_DDRSDRC_NB) ? 8 : 4) << size;
	else
		size = 4 << size;

	/* bandwidth */
	if (!(mdr & AT91_DDRSDRC_DBW))
		size <<= 1;

	return size;
}

#ifdef CONFIG_SOC_AT91SAM9G45
#include <mach/at91sam9g45.h>
static inline u32 at91sam9g45_get_ddram_size(int bank)
{
	switch (bank) {
	case 0:
		return at91_get_ddram_size(IOMEM(AT91SAM9G45_BASE_DDRSDRC0), false);
	case 1:
		return at91_get_ddram_size(IOMEM(AT91SAM9G45_BASE_DDRSDRC1), false);
	default:
		return 0;
	}
}
#else
static inline u32 at91sam9g45_get_ddram_size(int bank)
{
	return 0;
}
#endif

#ifdef CONFIG_SOC_AT91SAM9X5
#include <mach/at91sam9x5.h>
static inline u32 at91sam9x5_get_ddram_size(void)
{
	return at91_get_ddram_size(IOMEM(AT91SAM9X5_BASE_DDRSDRC0), true);
}
#else
static inline u32 at91sam9x5_get_ddram_size(void)
{
	return 0;
}
#endif

#ifdef CONFIG_SOC_AT91SAM9N12
#include <mach/at91sam9n12.h>
static inline u32 at91sam9n12_get_ddram_size(void)
{
	return at91_get_ddram_size(IOMEM(AT91SAM9N12_BASE_DDRSDRC0), true);
}
#else
static inline u32 at91sam9n12_get_ddram_size(void)
{
	return 0;
}
#endif

#ifdef CONFIG_SOC_SAMA5
#include <mach/sama5d3.h>
static inline u32 at91sama5_get_ddram_size(void)
{
	u32 cr;
	u32 mdr;
	u32 size;
	void * __iomem base = IOMEM(SAMA5D3_BASE_MPDDRC);

	cr = __raw_readl(base + AT91_DDRSDRC_CR);
	mdr = __raw_readl(base + AT91_DDRSDRC_MDR);

	/* Formula:
	 * size = bank << (col + row + 1);
	 * if (bandwidth == 32 bits)
	 *	size <<= 1;
	 */
	size = 1;
	/* COL */
	size += (cr & AT91_DDRSDRC_NC) + 9;
	/* ROW */
	size += ((cr & AT91_DDRSDRC_NR) >> 2) + 11;
	/* BANK */
	size = ((cr & AT91_DDRSDRC_NB) ? 8 : 4) << size;

	/* bandwidth */
	if (!(mdr & AT91_DDRSDRC_DBW))
		size <<= 1;

	return size;
}
#else
static inline u32 at91sama5_get_ddram_size(void)
{
	return 0;
}
#endif

#endif

#endif