1
From 7d7116b52cf4462f11de830f8ca755f22686285e Mon Sep 17 00:00:00 2001
2
From: Riku Voipio <riku.voipio@nokia.com>
3
Date: Mon, 18 Feb 2013 16:58:25 +0000
4
Subject: [PATCH 13/70] hw/omap_sdrc.c: Implement reading and writing of more
7
Content-Type: text/plain; charset=UTF-8
8
Content-Transfer-Encoding: 8bit
10
Implement SDRC registers as able to be written and read back,
11
rather than simply being unwritable and returning 0.
13
TODO: there are a few TODO remarks and we need to check vs the
14
TRM but this is pretty close to upstreamable.
16
Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
17
[Riku Voipio: Fixes and restructuring patchset]
18
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
19
[Peter Maydell: More fixes and cleanups for upstream submission]
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
hw/misc/omap_sdrc.c | 282 ++++++++++++++++++++++++++++++++++++++--------------
23
1 file changed, 209 insertions(+), 73 deletions(-)
25
diff --git a/hw/misc/omap_sdrc.c b/hw/misc/omap_sdrc.c
26
index ed62caf..ad3b716 100644
27
--- a/hw/misc/omap_sdrc.c
28
+++ b/hw/misc/omap_sdrc.c
41
+ uint32_t actim_ctrla;
42
+ uint32_t actim_ctrlb;
48
void omap_sdrc_reset(struct omap_sdrc_s *s)
51
+ /* TODO: ideally we should copy s->sharing, s->cs[*].mcfg
52
+ * from system control module
58
+ s->power_reg = 0x85;
59
+ s->cs[0].mcfg = s->cs[1].mcfg = 0;
60
+ s->cs[0].mr = s->cs[1].mr = 0x0024;
61
+ s->cs[0].emr2 = s->cs[1].emr2 = 0;
62
+ s->cs[0].actim_ctrla = s->cs[1].actim_ctrla = 0;
63
+ s->cs[0].actim_ctrlb = s->cs[1].actim_ctrlb = 0;
64
+ s->cs[0].rfr_ctrl = s->cs[1].rfr_ctrl = 0;
65
+ s->cs[0].manual = s->cs[1].manual = 0;
68
static uint64_t omap_sdrc_read(void *opaque, hwaddr addr,
71
struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
75
return omap_badwidth_read32(opaque, addr);
79
- case 0x00: /* SDRC_REVISION */
80
+ case 0x00: /* SDRC_REVISION */
83
- case 0x10: /* SDRC_SYSCONFIG */
84
+ case 0x10: /* SDRC_SYSCONFIG */
87
- case 0x14: /* SDRC_SYSSTATUS */
88
- return 1; /* RESETDONE */
90
- case 0x40: /* SDRC_CS_CFG */
91
- case 0x44: /* SDRC_SHARING */
92
- case 0x48: /* SDRC_ERR_ADDR */
93
- case 0x4c: /* SDRC_ERR_TYPE */
94
- case 0x60: /* SDRC_DLLA_SCTRL */
95
- case 0x64: /* SDRC_DLLA_STATUS */
96
- case 0x68: /* SDRC_DLLB_CTRL */
97
- case 0x6c: /* SDRC_DLLB_STATUS */
98
- case 0x70: /* SDRC_POWER */
99
- case 0x80: /* SDRC_MCFG_0 */
100
- case 0x84: /* SDRC_MR_0 */
101
- case 0x88: /* SDRC_EMR1_0 */
102
- case 0x8c: /* SDRC_EMR2_0 */
103
- case 0x90: /* SDRC_EMR3_0 */
104
- case 0x94: /* SDRC_DCDL1_CTRL */
105
- case 0x98: /* SDRC_DCDL2_CTRL */
106
- case 0x9c: /* SDRC_ACTIM_CTRLA_0 */
107
- case 0xa0: /* SDRC_ACTIM_CTRLB_0 */
108
- case 0xa4: /* SDRC_RFR_CTRL_0 */
109
- case 0xa8: /* SDRC_MANUAL_0 */
110
- case 0xb0: /* SDRC_MCFG_1 */
111
- case 0xb4: /* SDRC_MR_1 */
112
- case 0xb8: /* SDRC_EMR1_1 */
113
- case 0xbc: /* SDRC_EMR2_1 */
114
- case 0xc0: /* SDRC_EMR3_1 */
115
- case 0xc4: /* SDRC_ACTIM_CTRLA_1 */
116
- case 0xc8: /* SDRC_ACTIM_CTRLB_1 */
117
- case 0xd4: /* SDRC_RFR_CTRL_1 */
118
- case 0xd8: /* SDRC_MANUAL_1 */
119
+ case 0x14: /* SDRC_SYSSTATUS */
120
+ return 1; /* RESETDONE */
122
+ case 0x40: /* SDRC_CS_CFG */
125
+ case 0x44: /* SDRC_SHARING */
128
+ case 0x48: /* SDRC_ERR_ADDR */
131
+ case 0x4c: /* SDRC_ERR_TYPE */
134
+ case 0x60: /* SDRC_DLLA_SCTRL */
135
+ return s->dlla_ctrl;
137
+ case 0x64: /* SDRC_DLLA_STATUS */
138
+ return ~(s->dlla_ctrl & 0x4);
140
+ case 0x68: /* SDRC_DLLB_CTRL */
141
+ case 0x6c: /* SDRC_DLLB_STATUS */
144
+ case 0x70: /* SDRC_POWER */
145
+ return s->power_reg;
147
+ case 0xb0 ... 0xd8:
151
+ case 0x80 ... 0xa8:
152
+ switch (addr & 0x3f) {
153
+ case 0x00: /* SDRC_MCFG_x */
154
+ return s->cs[cs].mcfg;
155
+ case 0x04: /* SDRC_MR_x */
156
+ return s->cs[cs].mr;
157
+ case 0x08: /* SDRC_EMR1_x */
159
+ case 0x0c: /* SDRC_EMR2_x */
160
+ return s->cs[cs].emr2;
161
+ case 0x10: /* SDRC_EMR3_x */
165
+ return s->cs[1].actim_ctrla; /* SDRC_ACTIM_CTRLA_1 */
167
+ return 0x00; /* SDRC_DCDL1_CTRL */
170
+ return s->cs[1].actim_ctrlb; /* SDRC_ACTIM_CTRLB_1 */
172
+ return 0x00; /* SDRC_DCDL2_CTRL */
175
+ return s->cs[0].actim_ctrla; /* SDRC_ACTIM_CTRLA_0 */
180
+ return s->cs[0].actim_ctrlb; /* SDRC_ACTIM_CTRLB_0 */
183
+ case 0x24: /* SDRC_RFR_CTRL_x */
184
+ return s->cs[cs].rfr_ctrl;
185
+ case 0x28: /* SDRC_MANUAL_x */
186
+ return s->cs[cs].manual;
190
+ addr += cs * 0x30; /* restore address to get correct error messages */
198
@@ -90,60 +161,125 @@ static void omap_sdrc_write(void *opaque, hwaddr addr,
199
uint64_t value, unsigned size)
201
struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
205
return omap_badwidth_write32(opaque, addr, value);
209
- case 0x00: /* SDRC_REVISION */
210
- case 0x14: /* SDRC_SYSSTATUS */
211
- case 0x48: /* SDRC_ERR_ADDR */
212
- case 0x64: /* SDRC_DLLA_STATUS */
213
- case 0x6c: /* SDRC_DLLB_STATUS */
214
+ case 0x00: /* SDRC_REVISION */
215
+ case 0x14: /* SDRC_SYSSTATUS */
216
+ case 0x48: /* SDRC_ERR_ADDR */
217
+ case 0x64: /* SDRC_DLLA_STATUS */
218
+ case 0x6c: /* SDRC_DLLB_STATUS */
223
- case 0x10: /* SDRC_SYSCONFIG */
224
- if ((value >> 3) != 0x2)
225
- fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
226
- __FUNCTION__, (unsigned)value >> 3);
228
+ case 0x10: /* SDRC_SYSCONFIG */
232
s->config = value & 0x18;
235
- case 0x40: /* SDRC_CS_CFG */
236
- case 0x44: /* SDRC_SHARING */
237
- case 0x4c: /* SDRC_ERR_TYPE */
238
- case 0x60: /* SDRC_DLLA_SCTRL */
239
- case 0x68: /* SDRC_DLLB_CTRL */
240
- case 0x70: /* SDRC_POWER */
241
- case 0x80: /* SDRC_MCFG_0 */
242
- case 0x84: /* SDRC_MR_0 */
243
- case 0x88: /* SDRC_EMR1_0 */
244
- case 0x8c: /* SDRC_EMR2_0 */
245
- case 0x90: /* SDRC_EMR3_0 */
246
- case 0x94: /* SDRC_DCDL1_CTRL */
247
- case 0x98: /* SDRC_DCDL2_CTRL */
248
- case 0x9c: /* SDRC_ACTIM_CTRLA_0 */
249
- case 0xa0: /* SDRC_ACTIM_CTRLB_0 */
250
- case 0xa4: /* SDRC_RFR_CTRL_0 */
251
- case 0xa8: /* SDRC_MANUAL_0 */
252
- case 0xb0: /* SDRC_MCFG_1 */
253
- case 0xb4: /* SDRC_MR_1 */
254
- case 0xb8: /* SDRC_EMR1_1 */
255
- case 0xbc: /* SDRC_EMR2_1 */
256
- case 0xc0: /* SDRC_EMR3_1 */
257
- case 0xc4: /* SDRC_ACTIM_CTRLA_1 */
258
- case 0xc8: /* SDRC_ACTIM_CTRLB_1 */
259
- case 0xd4: /* SDRC_RFR_CTRL_1 */
260
- case 0xd8: /* SDRC_MANUAL_1 */
261
+ case 0x40: /* SDRC_CS_CFG */
262
+ s->cscfg = value & 0x30f;
265
+ case 0x44: /* SDRC_SHARING */
266
+ if (!(s->sharing & 0x40000000)) { /* LOCK */
267
+ s->sharing = value & 0x40007f00;
271
+ case 0x4c: /* SDRC_ERR_TYPE */
272
+ OMAP_BAD_REG(addr);
275
+ case 0x60: /* SDRC_DLLA_CTRL */
276
+ s->dlla_ctrl = value & 0xffff00fe;
279
+ case 0x68: /* SDRC_DLLB_CTRL */
280
+ /* silently ignore */
281
+ /*OMAP_BAD_REG(addr);*/
284
+ case 0x70: /* SDRC_POWER_REG */
285
+ s->power_reg = value & 0x04fffffd;
288
+ case 0xb0 ... 0xd8:
292
+ case 0x80 ... 0xa8:
293
+ switch (addr & 0x3f) {
294
+ case 0x00: /* SDRC_MCFG_x */
295
+ if (!(s->cs[cs].mcfg & 0x40000000)) { /* LOCKSTATUS */
296
+ if (value & 0x00080000) { /* ADDRMUXLEGACY */
297
+ s->cs[cs].mcfg = value & 0x477bffdf;
299
+ s->cs[cs].mcfg = value & 0x41fbffdf; /* TODO: marked ???? */
303
+ case 0x04: /* SDRC_MR_x */
304
+ s->cs[cs].mr = value & 0xfff;
306
+ case 0x08: /* SDRC_EMR1_x */
308
+ case 0x0c: /* SDRC_EMR2_x */
309
+ s->cs[cs].emr2 = value & 0xfff;
311
+ case 0x10: /* SDRC_EMR3_x */
315
+ /* SDRC_ACTIM_CTRLA_1 */
316
+ s->cs[1].actim_ctrla = value & 0xffffffdf;
318
+ /* otherwise SDRC_DCDL1_CTRL, do nothing */
322
+ /* SDRC_ACTIM_CTRLB_1 */
323
+ s->cs[1].actim_ctrlb = value & 0x000377ff;
325
+ /* otherwise SDRC_DCDL2_CTRL, do nothing */
329
+ /* SDRC_ACTIM_CTRLA_0 */
330
+ s->cs[0].actim_ctrla = value & 0xffffffdf;
332
+ OMAP_BAD_REG(addr + 0x30);
337
+ /* SDRC_ACTIM_CTRLB_0 */
338
+ s->cs[0].actim_ctrlb = value & 0x000377ff;
340
+ OMAP_BAD_REG(addr + 0x30);
343
+ case 0x24: /* SDRC_RFR_CTRL_x */
344
+ s->cs[cs].rfr_ctrl = value & 0x00ffff03;
346
+ case 0x28: /* SDRC_MANUAL_x */
347
+ s->cs[cs].manual = value & 0xffff000f;
350
+ OMAP_BAD_REG(addr + cs * 0x30);