1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "hw/arm/omap.h"
22
23
24struct omap_sdrc_s {
25 MemoryRegion iomem;
26 uint8_t config;
27};
28
29void omap_sdrc_reset(struct omap_sdrc_s *s)
30{
31 s->config = 0x10;
32}
33
34static uint64_t omap_sdrc_read(void *opaque, hwaddr addr,
35 unsigned size)
36{
37 struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
38
39 if (size != 4) {
40 return omap_badwidth_read32(opaque, addr);
41 }
42
43 switch (addr) {
44 case 0x00:
45 return 0x20;
46
47 case 0x10:
48 return s->config;
49
50 case 0x14:
51 return 1;
52
53 case 0x40:
54 case 0x44:
55 case 0x48:
56 case 0x4c:
57 case 0x60:
58 case 0x64:
59 case 0x68:
60 case 0x6c:
61 case 0x70:
62 case 0x80:
63 case 0x84:
64 case 0x88:
65 case 0x8c:
66 case 0x90:
67 case 0x94:
68 case 0x98:
69 case 0x9c:
70 case 0xa0:
71 case 0xa4:
72 case 0xa8:
73 case 0xb0:
74 case 0xb4:
75 case 0xb8:
76 case 0xbc:
77 case 0xc0:
78 case 0xc4:
79 case 0xc8:
80 case 0xd4:
81 case 0xd8:
82 return 0x00;
83 }
84
85 OMAP_BAD_REG(addr);
86 return 0;
87}
88
89static void omap_sdrc_write(void *opaque, hwaddr addr,
90 uint64_t value, unsigned size)
91{
92 struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
93
94 if (size != 4) {
95 omap_badwidth_write32(opaque, addr, value);
96 return;
97 }
98
99 switch (addr) {
100 case 0x00:
101 case 0x14:
102 case 0x48:
103 case 0x64:
104 case 0x6c:
105 OMAP_RO_REG(addr);
106 return;
107
108 case 0x10:
109 if ((value >> 3) != 0x2)
110 fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
111 __func__, (unsigned)value >> 3);
112 if (value & 2)
113 omap_sdrc_reset(s);
114 s->config = value & 0x18;
115 break;
116
117 case 0x40:
118 case 0x44:
119 case 0x4c:
120 case 0x60:
121 case 0x68:
122 case 0x70:
123 case 0x80:
124 case 0x84:
125 case 0x88:
126 case 0x8c:
127 case 0x90:
128 case 0x94:
129 case 0x98:
130 case 0x9c:
131 case 0xa0:
132 case 0xa4:
133 case 0xa8:
134 case 0xb0:
135 case 0xb4:
136 case 0xb8:
137 case 0xbc:
138 case 0xc0:
139 case 0xc4:
140 case 0xc8:
141 case 0xd4:
142 case 0xd8:
143 break;
144
145 default:
146 OMAP_BAD_REG(addr);
147 return;
148 }
149}
150
151static const MemoryRegionOps omap_sdrc_ops = {
152 .read = omap_sdrc_read,
153 .write = omap_sdrc_write,
154 .endianness = DEVICE_NATIVE_ENDIAN,
155};
156
157struct omap_sdrc_s *omap_sdrc_init(MemoryRegion *sysmem,
158 hwaddr base)
159{
160 struct omap_sdrc_s *s = g_new0(struct omap_sdrc_s, 1);
161
162 omap_sdrc_reset(s);
163
164 memory_region_init_io(&s->iomem, NULL, &omap_sdrc_ops, s, "omap.sdrc", 0x1000);
165 memory_region_add_subregion(sysmem, base, &s->iomem);
166
167 return s;
168}
169