]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * TI OMAP SDRAM controller emulation. | |
3 | * | |
4 | * Copyright (C) 2007-2008 Nokia Corporation | |
5 | * Written by Andrzej Zaborowski <andrew@openedhand.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License as | |
9 | * published by the Free Software Foundation; either version 2 or | |
10 | * (at your option) any later version of the License. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License along | |
18 | * with this program; if not, see <http://www.gnu.org/licenses/>. | |
19 | */ | |
20 | #include "hw.h" | |
21 | #include "omap.h" | |
22 | ||
23 | /* SDRAM Controller Subsystem */ | |
24 | struct omap_sdrc_s { | |
25 | uint8_t config; | |
26 | }; | |
27 | ||
28 | void omap_sdrc_reset(struct omap_sdrc_s *s) | |
29 | { | |
30 | s->config = 0x10; | |
31 | } | |
32 | ||
33 | static uint32_t omap_sdrc_read(void *opaque, target_phys_addr_t addr) | |
34 | { | |
35 | struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque; | |
36 | ||
37 | switch (addr) { | |
38 | case 0x00: /* SDRC_REVISION */ | |
39 | return 0x20; | |
40 | ||
41 | case 0x10: /* SDRC_SYSCONFIG */ | |
42 | return s->config; | |
43 | ||
44 | case 0x14: /* SDRC_SYSSTATUS */ | |
45 | return 1; /* RESETDONE */ | |
46 | ||
47 | case 0x40: /* SDRC_CS_CFG */ | |
48 | case 0x44: /* SDRC_SHARING */ | |
49 | case 0x48: /* SDRC_ERR_ADDR */ | |
50 | case 0x4c: /* SDRC_ERR_TYPE */ | |
51 | case 0x60: /* SDRC_DLLA_SCTRL */ | |
52 | case 0x64: /* SDRC_DLLA_STATUS */ | |
53 | case 0x68: /* SDRC_DLLB_CTRL */ | |
54 | case 0x6c: /* SDRC_DLLB_STATUS */ | |
55 | case 0x70: /* SDRC_POWER */ | |
56 | case 0x80: /* SDRC_MCFG_0 */ | |
57 | case 0x84: /* SDRC_MR_0 */ | |
58 | case 0x88: /* SDRC_EMR1_0 */ | |
59 | case 0x8c: /* SDRC_EMR2_0 */ | |
60 | case 0x90: /* SDRC_EMR3_0 */ | |
61 | case 0x94: /* SDRC_DCDL1_CTRL */ | |
62 | case 0x98: /* SDRC_DCDL2_CTRL */ | |
63 | case 0x9c: /* SDRC_ACTIM_CTRLA_0 */ | |
64 | case 0xa0: /* SDRC_ACTIM_CTRLB_0 */ | |
65 | case 0xa4: /* SDRC_RFR_CTRL_0 */ | |
66 | case 0xa8: /* SDRC_MANUAL_0 */ | |
67 | case 0xb0: /* SDRC_MCFG_1 */ | |
68 | case 0xb4: /* SDRC_MR_1 */ | |
69 | case 0xb8: /* SDRC_EMR1_1 */ | |
70 | case 0xbc: /* SDRC_EMR2_1 */ | |
71 | case 0xc0: /* SDRC_EMR3_1 */ | |
72 | case 0xc4: /* SDRC_ACTIM_CTRLA_1 */ | |
73 | case 0xc8: /* SDRC_ACTIM_CTRLB_1 */ | |
74 | case 0xd4: /* SDRC_RFR_CTRL_1 */ | |
75 | case 0xd8: /* SDRC_MANUAL_1 */ | |
76 | return 0x00; | |
77 | } | |
78 | ||
79 | OMAP_BAD_REG(addr); | |
80 | return 0; | |
81 | } | |
82 | ||
83 | static void omap_sdrc_write(void *opaque, target_phys_addr_t addr, | |
84 | uint32_t value) | |
85 | { | |
86 | struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque; | |
87 | ||
88 | switch (addr) { | |
89 | case 0x00: /* SDRC_REVISION */ | |
90 | case 0x14: /* SDRC_SYSSTATUS */ | |
91 | case 0x48: /* SDRC_ERR_ADDR */ | |
92 | case 0x64: /* SDRC_DLLA_STATUS */ | |
93 | case 0x6c: /* SDRC_DLLB_STATUS */ | |
94 | OMAP_RO_REG(addr); | |
95 | return; | |
96 | ||
97 | case 0x10: /* SDRC_SYSCONFIG */ | |
98 | if ((value >> 3) != 0x2) | |
99 | fprintf(stderr, "%s: bad SDRAM idle mode %i\n", | |
100 | __FUNCTION__, value >> 3); | |
101 | if (value & 2) | |
102 | omap_sdrc_reset(s); | |
103 | s->config = value & 0x18; | |
104 | break; | |
105 | ||
106 | case 0x40: /* SDRC_CS_CFG */ | |
107 | case 0x44: /* SDRC_SHARING */ | |
108 | case 0x4c: /* SDRC_ERR_TYPE */ | |
109 | case 0x60: /* SDRC_DLLA_SCTRL */ | |
110 | case 0x68: /* SDRC_DLLB_CTRL */ | |
111 | case 0x70: /* SDRC_POWER */ | |
112 | case 0x80: /* SDRC_MCFG_0 */ | |
113 | case 0x84: /* SDRC_MR_0 */ | |
114 | case 0x88: /* SDRC_EMR1_0 */ | |
115 | case 0x8c: /* SDRC_EMR2_0 */ | |
116 | case 0x90: /* SDRC_EMR3_0 */ | |
117 | case 0x94: /* SDRC_DCDL1_CTRL */ | |
118 | case 0x98: /* SDRC_DCDL2_CTRL */ | |
119 | case 0x9c: /* SDRC_ACTIM_CTRLA_0 */ | |
120 | case 0xa0: /* SDRC_ACTIM_CTRLB_0 */ | |
121 | case 0xa4: /* SDRC_RFR_CTRL_0 */ | |
122 | case 0xa8: /* SDRC_MANUAL_0 */ | |
123 | case 0xb0: /* SDRC_MCFG_1 */ | |
124 | case 0xb4: /* SDRC_MR_1 */ | |
125 | case 0xb8: /* SDRC_EMR1_1 */ | |
126 | case 0xbc: /* SDRC_EMR2_1 */ | |
127 | case 0xc0: /* SDRC_EMR3_1 */ | |
128 | case 0xc4: /* SDRC_ACTIM_CTRLA_1 */ | |
129 | case 0xc8: /* SDRC_ACTIM_CTRLB_1 */ | |
130 | case 0xd4: /* SDRC_RFR_CTRL_1 */ | |
131 | case 0xd8: /* SDRC_MANUAL_1 */ | |
132 | break; | |
133 | ||
134 | default: | |
135 | OMAP_BAD_REG(addr); | |
136 | return; | |
137 | } | |
138 | } | |
139 | ||
140 | static CPUReadMemoryFunc * const omap_sdrc_readfn[] = { | |
141 | omap_badwidth_read32, | |
142 | omap_badwidth_read32, | |
143 | omap_sdrc_read, | |
144 | }; | |
145 | ||
146 | static CPUWriteMemoryFunc * const omap_sdrc_writefn[] = { | |
147 | omap_badwidth_write32, | |
148 | omap_badwidth_write32, | |
149 | omap_sdrc_write, | |
150 | }; | |
151 | ||
152 | struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base) | |
153 | { | |
154 | int iomemtype; | |
155 | struct omap_sdrc_s *s = (struct omap_sdrc_s *) | |
156 | qemu_mallocz(sizeof(struct omap_sdrc_s)); | |
157 | ||
158 | omap_sdrc_reset(s); | |
159 | ||
160 | iomemtype = cpu_register_io_memory(omap_sdrc_readfn, | |
161 | omap_sdrc_writefn, s, DEVICE_NATIVE_ENDIAN); | |
162 | cpu_register_physical_memory(base, 0x1000, iomemtype); | |
163 | ||
164 | return s; | |
165 | } |